[vtkusers] stenciling problem-- is this code thread safe?
Mark Roden
mmroden at gmail.com
Fri Feb 11 16:33:07 EST 2011
I guess the question is why the 5.6 method doesn't work with 5.9, if
the extrusion/polydatatostencil/stencil pipeline should be good-- ie,
if I have contours drawn along the x plane, I'll need this
non-z-stacking approach to work (and I do have such contours). Our
app allows users to draw their contours on any plane, so the z-aligned
contour assumption isn't entirely useful to me.
It looks like there's a noop happening somewhere, as if the something
in that pipeline just decided that because there are only polys (or
something similar), it's not going to do the work. If polys are still
a valid input, then why should the old code break?
On Fri, Feb 11, 2011 at 1:24 PM, David Gobbi <david.gobbi at gmail.com> wrote:
> Ah, it looks like TestImageTracerWidget.cxx uses slices that
> aren't parallel to the XY plane... so it actually has to use the
> old extrusion method to prepare the data.
>
> - David
>
>
> On Fri, Feb 11, 2011 at 1:57 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>> I was recommending that you visualize the contours as polydata,
>> so telling me that you are still getting blank images doesn't help
>> to move things forward.
>>
>> PolyDataToImageStencil still works on polys. It has two modes:
>> it can be given a closed polyhedral surface (like before) or,
>> in VTK 5.8 and 5.9, it can be given a set of polyline contours.
>> But if its input contains any polys, then it will ignore the polylines.
>> And if given a set of polys that do not form a closed surface, it
>> will usually not work (this depends on the orientation of the polys).
>> Given a single, flat poly it will never work, if given polys the polys
>> must define an enclosed volume.
>>
>> The vtkImageTracer widget has not been updated recently, so
>> it still uses extrusion in order to generate a surface, instead of
>> using the more efficient contour-to-stencil conversion.
>>
>> The contours should be closed and connected, which they should
>> be if they are generated from polygon edges, but vtkCleanPolyData
>> can be used as further insurance. An example of contour use is
>> Hybrid/Testing/Tcl/TestImageStencilWithPolydata.tcl
>>
>> But I've gone ahead and merged a patch for the vtkLinearExtrusion
>> multithreading bug. I'd prefer if you continued to diagnose the
>> contour issue and get it working that way, but that's up to you.
>>
>> - David
>>
>>
>> On Fri, Feb 11, 2011 at 1:34 PM, Mark Roden <mmroden at gmail.com> wrote:
>>> Hi David,
>>>
>>> Yes, I'm feeding these things into a visualizer. It's the same code
>>> path as when I was using 5.6, in that it's going right into a mapper
>>> to an actor to a renderer. I'm getting blank images.
>>>
>>> I'm wondering if it could be easier to avoid this extra filter (that
>>> seems to have some kind of angle threshold?) and just redo the gdcm
>>> poly reader to report both polys and lines, and then blank the polys
>>> if necessary for the stenciling code.
>>>
>>> rtstructs are just a series of points that are supposed to be linearly
>>> connected. right now, the code to feed them into the polys array
>>> looks like:
>>>
>>>
>>> vtkCellArray *polys = vtkCellArray::New();
>>> for(unsigned int i = 0; i < nitems; ++i){//nitems = number of
>>> closed contour polygons
>>> ....
>>> for(unsigned int i = 0; i < npts * 3; i+=3)
>>> {
>>> float x[3];
>>> x[0] = pts[i+0];
>>> x[1] = pts[i+1];
>>> x[2] = pts[i+2];
>>> vtkIdType ptId = newPts->InsertNextPoint( x );
>>> ptIds[i / 3] = ptId;
>>> }
>>> // Each Contour Data is in fact a Cell:
>>> vtkIdType cellId = polys->InsertNextCell( npts , ptIds);
>>> }
>>> Could you point me to some sample code I can use to construct the
>>> lines necessary to make your filter work, as opposed to the polys that
>>> the reader is currently producing?
>>>
>>>
>>>
>>> On Fri, Feb 11, 2011 at 12:14 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>> A better approach would be to visualize the contours to make
>>>> sure there's nothing wrong with them. Just feed them into a
>>>> vtkDataSetMapper, add that mapper to a vtkActor, and add that
>>>> to your renderer. If they don't look right, then do the same for the
>>>> polygons. You need to know what kind of input you are feeding into
>>>> vtkPolyDataToImageStencil before you start worrying about the output.
>>>>
>>>> On Fri, Feb 11, 2011 at 1:01 PM, Mark Roden <mmroden at gmail.com> wrote:
>>>>> whoops. Thanks for that.
>>>>>
>>>>> Now theLines has some information in it, although more than I think it should.
>>>>>
>>>>> Still not showing up in my displays, though, whereas it was in the 5.6 version.
>>>>>
>>>>> Is there a way to quickly walk through the contents of vtkImageData to
>>>>> see if there's anything there produced by the stenciling? I'm
>>>>> wondering if something's broken in the visualization code.
>>>>>
>>>>> On Fri, Feb 11, 2011 at 11:57 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>> I gotta ask... did you call theEdges.Update() before checking the output?
>>>>>>
>>>>>> On Fri, Feb 11, 2011 at 12:49 PM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>> Yeah, that doesn't work.
>>>>>>>
>>>>>>> vtkCellArray thePolys = data.GetPolys();
>>>>>>> vtkCellArray theStrips = data.GetStrips();
>>>>>>> vtkCellArray theLines = data.GetLines();
>>>>>>>
>>>>>>> vtkFeatureEdges theEdges = new vtkFeatureEdges();
>>>>>>> theEdges.BoundaryEdgesOn();
>>>>>>> theEdges.ManifoldEdgesOn();
>>>>>>> theEdges.NonManifoldEdgesOn();
>>>>>>> theEdges.FeatureEdgesOn();
>>>>>>> theEdges.SetInput(data);
>>>>>>> vtkPolyData theEdgeData = theEdges.GetOutput();
>>>>>>>
>>>>>>> thePolys = theEdgeData.GetPolys();
>>>>>>> theStrips = theEdgeData.GetStrips();
>>>>>>> theLines = theEdgeData.GetLines();
>>>>>>>
>>>>>>> thePolys, theStrips, and theLines are all zero-sized once
>>>>>>> theFeatureEdges filter is run, but thePolys has 25 points (for my test
>>>>>>> data) prior to running.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Feb 11, 2011 at 11:37 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>>>> You could try vtkFeatureEdges. There is probably a better filter for
>>>>>>>> the job, but I don't know.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Feb 11, 2011 at 12:25 PM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>>>> OK, so it looks like everything's coming back as polys instead of
>>>>>>>>> lines. What's the best way to proceed then, modify the reader to get
>>>>>>>>> just lines, or is there some way to convert from the polys to lines?
>>>>>>>>>
>>>>>>>>> On Fri, Feb 11, 2011 at 11:12 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>>>>>> Just verify that the vtkGDCMPolyDataReader contains no polygons, i.e.
>>>>>>>>>> get its output and call output.GetPolys() and output.GetStrips().
>>>>>>>>>> Both of these should be null, because a single polygon or strip in the
>>>>>>>>>> polydata will keep the contour code from working. The output of
>>>>>>>>>> GetLines() should, of course, not be null, since that is what
>>>>>>>>>> vtkPolyDataToImageStencil will use to create the stencil.
>>>>>>>>>>
>>>>>>>>>> - David
>>>>>>>>>>
>>>>>>>>>> On Fri, Feb 11, 2011 at 12:05 PM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>>>>>> So in this code, which is using a vtkPolyData 'data' that is a series
>>>>>>>>>>> of xy contours along the z axis, as restored by the
>>>>>>>>>>> vtkGDCMPolyDataReader (and working in 5.6):
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> //vtk 5.9 no longer requires linear extrusion beforehand
>>>>>>>>>>> //vtkLinearExtrusionFilter extruder = new vtkLinearExtrusionFilter();
>>>>>>>>>>> //extruder.SetInput(data);
>>>>>>>>>>> //extruder.SetVector(0, 0, spacing[2]);
>>>>>>>>>>> //extruder.Update();
>>>>>>>>>>> //vtkPolyData extruderOutput = extruder.GetOutput();
>>>>>>>>>>>
>>>>>>>>>>> vtkPolyDataToImageStencil pol2Stenc = new vtkPolyDataToImageStencil();
>>>>>>>>>>> pol2Stenc.SetTolerance(0);
>>>>>>>>>>> //pol2Stenc.SetInput(extruderOutput);
>>>>>>>>>>> pol2Stenc.SetInput(data);
>>>>>>>>>>> pol2Stenc.SetInformationInput(binaryOrgan);
>>>>>>>>>>> pol2Stenc.Update();
>>>>>>>>>>> vtkImageStencilData pol2StencOutput = pol2Stenc.GetOutput();
>>>>>>>>>>>
>>>>>>>>>>> vtkImageStencil stencil = new vtkImageStencil();
>>>>>>>>>>> stencil.SetInput(binaryOrgan);
>>>>>>>>>>> stencil.ReverseStencilOn();
>>>>>>>>>>> stencil.SetStencil(pol2StencOutput);
>>>>>>>>>>> stencil.Update();
>>>>>>>>>>>
>>>>>>>>>>> final vtkImageData stencilOutput = stencil.GetOutput();
>>>>>>>>>>> final vtkImageData imageToKeep = new vtkImageData();
>>>>>>>>>>> imageToKeep.DeepCopy(stencilOutput);
>>>>>>>>>>> stencilOutput.Delete();
>>>>>>>>>>>
>>>>>>>>>>> The result is a blank image. Is there a call I'm missing here?
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Feb 11, 2011 at 11:00 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>>>>>>>> The vtkPolyDataToImageStencil in VTK 5.8 and 5.9 can take a polyline
>>>>>>>>>>>> contour or a stack of contours as input and create a stencil from
>>>>>>>>>>>> that. Each polylines should lie in an XY plane (though they can be at
>>>>>>>>>>>> any Z position). This will not work with a polygon; a polyline is
>>>>>>>>>>>> required.
>>>>>>>>>>>>
>>>>>>>>>>>> - David
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Fri, Feb 11, 2011 at 11:51 AM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>>>>>>>> Hi David,
>>>>>>>>>>>>>
>>>>>>>>>>>>> How should the stenciling be done in vtk 5.9 then? If I remove the
>>>>>>>>>>>>> linear extrusion, no masks are produced.
>>>>>>>>>>>>>
>>>>>>>>>>>>> This is exciting-- I can now use the vtkSmartVolumeMapper, which I've
>>>>>>>>>>>>> been drooling over ever since it was introduced!
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>> Mark
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 10:39 AM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>>>>>>>>> wait, never mind! I had some issues with vtk strings, but it appears
>>>>>>>>>>>>>> that this line:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> outWin.SetInstance(outWin);
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> is now deprecated or something, because having that line active in this snippet:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> vtkFileOutputWindow outWin = new vtkFileOutputWindow();
>>>>>>>>>>>>>> outWin.SetInstance(outWin);
>>>>>>>>>>>>>> outWin.SetFileName("MVSVTKViewer.log");
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> throws this exception:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Exception in thread "main" java.lang.NoSuchFieldError: vtkId
>>>>>>>>>>>>>> at vtk.vtkOutputWindow.SetInstance_3(Native Method)
>>>>>>>>>>>>>> at vtk.vtkOutputWindow.SetInstance(vtkOutputWindow.java:45)
>>>>>>>>>>>>>> at com.mvs.viewer.Application.main(Application.java:63)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> But that's a different issue (bug?)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 10:35 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>>>>>>>>>>> If you are reporting the vtkLinearExtrusionFilter, I already did.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 11:31 AM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>>>>>>>>>>> Hi David,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Unfortunately, the current vtk master branch is seriously broken in
>>>>>>>>>>>>>>>> its java wrappings. I'm putting together a bug report now...
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Mark
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 10:09 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>>>>>>>>>>>>> I should add: with the current VTK master and release branches,
>>>>>>>>>>>>>>>>> vtkPolyDataToImageStencil no longer requires vtkLinearExtrusionFilter
>>>>>>>>>>>>>>>>> to be used beforehand. So you could try that.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - David
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 11:06 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>>>>>>>>>>>>>> I was doubtful about the global memory, but I looked through the
>>>>>>>>>>>>>>>>>> filters just to be sure. And guess what I found... here is some
>>>>>>>>>>>>>>>>>> highly suspect code in vtkLinearExtrusionFilter:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> double *vtkLinearExtrusionFilter::ViaNormal(double x[3], vtkIdType id,
>>>>>>>>>>>>>>>>>> vtkDataArray *n)
>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>> static double xNew[3], normal[3];
>>>>>>>>>>>>>>>>>> int i;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> n->GetTuple(id, normal);
>>>>>>>>>>>>>>>>>> for (i=0; i<3; i++)
>>>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>>> xNew[i] = x[i] + this->ScaleFactor*normal[i];
>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> return xNew;
>>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Code like the above is definitely going to cause thread problems.
>>>>>>>>>>>>>>>>>> And this isn't the only place in that class where code like this appears.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Yikes!
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> - David
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 10:46 AM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>>>>>>>>>>>>>> What I mean is, I have a vtkPolyData that has been DeepCopied and a
>>>>>>>>>>>>>>>>>>> vtkImageData that is binary and distinct from all other data.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> When I call the previously listed code with multiple threads (each
>>>>>>>>>>>>>>>>>>> with their own polydata and binary image to fill in), the result is
>>>>>>>>>>>>>>>>>>> generally a very garbled image. If I call from a single thread in
>>>>>>>>>>>>>>>>>>> series, one for each polydata/image pair, then everything works out
>>>>>>>>>>>>>>>>>>> fine.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> So it seems to me that something in the above series isn't thread
>>>>>>>>>>>>>>>>>>> safe. Each thread is declaring its own local objects, but is there
>>>>>>>>>>>>>>>>>>> some global memory that's being used or accessed here?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 9:23 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>> Hi Mark,
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Explain in more detail what you mean by "call from multiple threads".
>>>>>>>>>>>>>>>>>>>> VTK is, in general, not thread safe and you cannot call Update() on
>>>>>>>>>>>>>>>>>>>> a filter from more than one thread. Each thread needs to have its own
>>>>>>>>>>>>>>>>>>>> set of filters. And in general, you cannot feed a data object into more
>>>>>>>>>>>>>>>>>>>> than one thread, because even simple methods like GetBounds() are
>>>>>>>>>>>>>>>>>>>> not thread safe.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> When using VTK from multiple threads, it is necessary to apply
>>>>>>>>>>>>>>>>>>>> extreme caution.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> - David
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Fri, Feb 11, 2011 at 10:00 AM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>>>>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> This code does not have threads enabled in vtk 5.6.1 (the code is in Java):
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> vtkLinearExtrusionFilter extruder = new vtkLinearExtrusionFilter();
>>>>>>>>>>>>>>>>>>>>> extruder.SetInput(data);
>>>>>>>>>>>>>>>>>>>>> extruder.SetVector(0, 0, spacing[2]);
>>>>>>>>>>>>>>>>>>>>> extruder.Update();
>>>>>>>>>>>>>>>>>>>>> vtkPolyData extruderOutput = extruder.GetOutput();
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> vtkPolyDataToImageStencil pol2Stenc = new vtkPolyDataToImageStencil();
>>>>>>>>>>>>>>>>>>>>> pol2Stenc.SetTolerance(0);
>>>>>>>>>>>>>>>>>>>>> pol2Stenc.SetInput(extruderOutput);
>>>>>>>>>>>>>>>>>>>>> pol2Stenc.SetInformationInput(binaryOrgan);
>>>>>>>>>>>>>>>>>>>>> pol2Stenc.Update();
>>>>>>>>>>>>>>>>>>>>> vtkImageStencilData pol2StencOutput = pol2Stenc.GetOutput();
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> // This is where the memory leak is!!!!
>>>>>>>>>>>>>>>>>>>>> vtkImageStencil stencil = new vtkImageStencil();
>>>>>>>>>>>>>>>>>>>>> stencil.SetInput(binaryOrgan);
>>>>>>>>>>>>>>>>>>>>> stencil.ReverseStencilOn();
>>>>>>>>>>>>>>>>>>>>> stencil.SetStencil(pol2StencOutput);
>>>>>>>>>>>>>>>>>>>>> stencil.Update();
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> // We're doing this because of an email to Mark
>>>>>>>>>>>>>>>>>>>>> // that says this will fix our memory issues
>>>>>>>>>>>>>>>>>>>>> final vtkImageData stencilOutput = stencil.GetOutput();
>>>>>>>>>>>>>>>>>>>>> final vtkImageData imageToKeep = new vtkImageData();
>>>>>>>>>>>>>>>>>>>>> imageToKeep.DeepCopy(stencilOutput);
>>>>>>>>>>>>>>>>>>>>> stencilOutput.Delete();
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> When I try to call this code from multiple threads (ie, to create the
>>>>>>>>>>>>>>>>>>>>> stencils for multiple organs), Bad Things happen, as in, the data are
>>>>>>>>>>>>>>>>>>>>> entirely corrupted. Is this code thread safe?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Mark
>>>>>>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>>>>>>>> Powered by www.kitware.com
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Follow this link to subscribe/unsubscribe:
>>>>>>>>>>>>>>>>>>>>> http://www.vtk.org/mailman/listinfo/vtkusers
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
More information about the vtkusers
mailing list