[vtkusers] problems with multithreading in VTK with winforms
Neel Patel 0-0-0
siva.yedithi at gmail.com
Tue Jul 4 18:38:35 EDT 2017
Hello all. I have a couple problems trying to do multithreading with VTK
using winforms. Currently I have a form with a pictureBox and a
RenderControlWindow, where the pictureBox is used for streaming data while
the RenderWindow is used to display images on the side. From some previous
reading, I've tried to implement a solution where updates to my image are
done on one thread and the rendering is done on the main form thread. The
problem is that when I try to re-render the window itself doesn't change.
Some code below, at least what I think might be relevant can post more if
need be.
Update Thread:
vtkImageImport imageImport = null;
o = new Thread(() =>
{
byte[] myByteArray = new byte[data.Size];
int idx = 0;
for (int k = 0; k < D; k++)
{
for (int j = 0; j < H; j++)
{
for (int i = 0; i < W; i++)
{
idx = k * W * H + j * W + i;
myByteArray[idx] = (byte)data.Get(idx);
}
}
}
// Copy byte array into VTK
// Based on:
http://stackoverflow.com/questions/31670753/use-c-sharp-byte-image-data-in-vtk
vtkUnsignedCharArray myCharArray =
vtkUnsignedCharArray.New();
GCHandle gPointer = GCHandle.Alloc(myByteArray,
GCHandleType.Pinned);
// Import image data
imageImport = vtkImageImport.New();
imageImport.SetDataSpacing(1, 1, 1);
imageImport.SetDataOrigin(0, 0, 0);
imageImport.SetDataExtent(0, W - 1, 0, H - 1, 0, D - 1);
imageImport.SetWholeExtent(0, W - 1, 0, H - 1, 0, D - 1);
imageImport.SetDataScalarTypeToUnsignedChar();
imageImport.SetNumberOfScalarComponents(1);
imageImport.SetImportVoidPointer(gPointer.AddrOfPinnedObject());
imageImport.Update();
if (InvokeRequired)
{
this.Invoke(new Action(() => renderInMain()));
Thread.Sleep(1000);
}
});
o.Start();
}
Rendering Method called in main thread:
public void renderInMain() {
lock (_lock)
{
vtkRenderer renderer =
renderWindowControl1.RenderWindow.GetRenderers().GetFirstRenderer();
vtkImageActor actor = vtkImageActor.New();
vtkMatrix4x4 resliceAxes = vtkMatrix4x4.New();
vtkImageReslice reslice = vtkImageReslice.New();
vtkLookupTable table = vtkLookupTable.New();
renderer.RemoveAllViewProps();
//renderer.Modified();
//renderer.Render();
// Get extent and calculate the center of the volume
int[] extent = imageImport.GetOutput().GetWholeExtent();
double[] spacing = imageImport.GetOutput().GetSpacing();
double[] origin = imageImport.GetOutput().GetOrigin();
double[] center = new double[3];
center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] +
extent[1]);
center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] +
extent[3]);
center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] +
extent[5]);
// Matrices for axial, coronal, sagittal, oblique view
orientations
double[] axialElements = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
double[] coronalElements = {
1, 0, 0, 0,
0, 0, 1, 0,
0,-1, 0, 0,
0, 0, 0, 1 };
double[] sagittalElements = {
0, 0,-1, 0,
1, 0, 0, 0,
0,-1, 0, 0,
0, 0, 0, 1 };
double[] obliqueElements = {
1, 0, 0, 0,
0, 0.866025, -0.5, 0,
0, 0.5, 0.866025, 0,
0, 0, 0, 1 };
// Set the slice orientation
GCHandle sagittalElements_ptr =
GCHandle.Alloc(coronalElements, GCHandleType.Pinned);
resliceAxes.DeepCopy(sagittalElements_ptr.AddrOfPinnedObject());
Thread.Sleep(1000);
// Set the point through which to slice
resliceAxes.SetElement(0, 3, center[0]);
resliceAxes.SetElement(1, 3, center[1]);
resliceAxes.SetElement(2, 3, center[2]);
resliceAxes.Modified();
Thread.Sleep(1000);
// Extract a slice in the desired orientation
reslice.SetInputConnection(imageImport.GetOutputPort());
reslice.SetOutputDimensionality(2);
reslice.SetResliceAxes(resliceAxes);
reslice.SetInterpolationModeToLinear();
reslice.Modified();
Thread.Sleep(1000);
// Create a greyscale lookup table
table.SetRange(0, 255); // image intensity range
table.SetValueRange(0.0, 1); // from black to white
table.SetSaturationRange(0.0, 0.0); // no color saturation
table.SetRampToLinear();
table.Build();
// Map the image through the lookup table
vtkImageMapToColors color = vtkImageMapToColors.New();
color.SetLookupTable(table);
color.SetInputConnection(reslice.GetOutputPort());
// Display the image
actor.SetInput(color.GetOutput());
actor.Modified();
Console.WriteLine("Exit");
Thread.Sleep(1000);
// Set up renderer
//if (renderFlag == 1)
//{
renderer.ResetCamera();
renderer.AddActor(actor);
renderer.SetBackground(0, 0, 0);
renderer.Modified();
renderer.Render();
}
}
Another curious thing is that if I run this normally the renderWindow
doesn't change, but if I run it while debugging it seems to work fine and
the window changes to what it should be.
Any help or insight would be greatly appreciated. Thanks!
Regards,
Neel
--
View this message in context: http://vtk.1045678.n5.nabble.com/problems-with-multithreading-in-VTK-with-winforms-tp5743896.html
Sent from the VTK - Users mailing list archive at Nabble.com.
More information about the vtkusers
mailing list