[vtk-developers] potential speedup for the vtkpolydatatoimagestencil

Mark Roden mmroden at gmail.com
Wed Feb 29 17:04:35 EST 2012


OK, I got it to work.

For people who are following this thread, converting rtstructs from
vtkgdcmpolydata reader into a binary image but wanting to avoid
extrusion, this code will convert the data from polys to lines:


//just want lines returned, nothing else, for fast stenciling.
vtkPolyData* ConvertToLines(vtkPolyData * const data) {
    vtkPolyData* returnedData = vtkPolyData::New();
    returnedData->DeepCopy(data);

    vtkPoints* newPoints = vtkPoints::New();

    int theNumPoints = returnedData->GetNumberOfPoints();

    if (theNumPoints == 1){
        double* pt = data->GetPoint(0);
        newPoints->InsertNextPoint(pt);
        returnedData->SetPoints(newPoints);
    } else {

        int i;
        //borrowed this code from the polydatatostencil code
        //we know that each polygon is coplanar, so do that here.
        //also, closes the polygon, but should check to see if that's necessary.
        vtkMergePoints* theMerge = vtkMergePoints::New();
        double bounds[6];
        data->GetBounds(bounds);
        theMerge->InitPointInsertion(newPoints, bounds);
        vtkCellArray* polys = (data->GetPolys());
        vtkCellArray* lines = vtkCellArray::New();
        returnedData->SetLines(lines);//blank them out, just in case
        //each cell in the poly array is a polyline, I contend.
        int theNumPolys = polys->GetNumberOfCells();
        lines->Allocate(theNumPolys);
        polys->InitTraversal();
        vtkPoints* oldPoints = data->GetPoints();
        for (int j = 0; j < theNumPolys; j++){
            vtkIdType numPoints;
            vtkIdType* ptIds;
            polys->GetNextCell(numPoints, ptIds);
            lines->InsertNextCell(numPoints+1);//close the end of the poly
            int zeroPtId = 0;
            double zeroPt[3];
            for (i = 0; i < numPoints; i++){
              vtkIdType ptId;
              double point[3];
              oldPoints->GetPoint(ptIds[i], point);
              theMerge->InsertUniquePoint(point, ptId);
              lines->InsertCellPoint(ptId);
              newPoints->InsertNextPoint(point);
              if (i == 0){
                zeroPtId = ptId;
                zeroPt[0] = point[0];
                zeroPt[1] = point[1];
                zeroPt[2] = point[2];
              }
            }
            newPoints->InsertNextPoint(zeroPt);
            theMerge->InsertUniquePoint(zeroPt, zeroPtId);
            lines->InsertCellPoint(zeroPtId);//start from the beginning
        }
        returnedData->SetPoints(newPoints);
        returnedData->SetLines(lines);
        vtkCellArray* blank = vtkCellArray::New();
        returnedData->SetPolys(blank);
        blank->Delete();
        lines->Delete();
    }
    newPoints->Delete();

    return returnedData;
}

On Tue, Feb 28, 2012 at 12:08 PM, Mark Roden <mmroden at gmail.com> wrote:
> This crashes.
>
>    vtkExtractEdges* theEdger = vtkExtractEdges::New();
>    theEdger->SetInput(data);
>    theEdger->Update();
>
>    vtkStripper* theStripper = vtkStripper::New();
>    theStripper->SetInputConnection(theEdger->GetOutputPort());
>    theStripper->Update();
>
>    vtkPolyDataToImageStencil* pol2Stenc = vtkPolyDataToImageStencil::New();
>    pol2Stenc->SetTolerance(0);
>    pol2Stenc->SetInputConnection(theStripper->GetOutputPort());
> //    pol2Stenc->SetInputConnection(extruder->GetOutputPort());
>    pol2Stenc->SetInformationInput(flippedImage);
>    pol2Stenc->Update();
>
>    vtkImageStencil* stencil = vtkImageStencil::New();
>    stencil->SetInput(flippedImage);
>    stencil->ReverseStencilOn();
>    stencil->SetStencil(pol2Stenc->GetOutput());
>    stencil->Update();
>
> If I remove the stripper, then there's no crash, but the result is a
> blank image.
>
> On Tue, Feb 28, 2012 at 11:46 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>> The vtkExtractEdges filter should do what you need, and you can
>> follow it with vtkStripper to ensure that the resulting polylines are
>> continuous.
>>
>>  - David
>>
>>
>> On Tue, Feb 28, 2012 at 12:40 PM, Mark Roden <mmroden at gmail.com> wrote:
>>> OK, I think I see the problem here-- the gdcm loader is explicitly
>>> loading the data as a polygon rather than as a polyline.
>>>
>>> Is there a cheap way to convert between the two?  A simple function
>>> call, or a way to iterate through the data to convert it to a line so
>>> as to use the cheaper code path in the stenciling step?
>>>
>>> Thanks,
>>> Mark
>>>
>>> On Mon, Feb 27, 2012 at 1:13 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>> There is a dashboard test that uses the direct path (see the section
>>>> after "#test again with a contour").  It only uses a single contour,
>>>> but I've used vtkPolyDataToImageStencil extensively with a series
>>>> of contours.  The example passes the contours through vtkStripper
>>>> to make each contour into an ordered, contiguous polyline but I don't
>>>> think that step is necessary.
>>>>
>>>> http://vtk.org/gitweb?p=VTK.git;a=blob;f=Hybrid/Testing/Tcl/TestImageStencilWithPolydata.tcl;#l35
>>>>
>>>>  - David
>>>>
>>>> On Mon, Feb 27, 2012 at 2:07 PM, Mark Roden <mmroden at gmail.com> wrote:
>>>>> Hi David,
>>>>>
>>>>> I know where the split in the code is.  My point is that the direct
>>>>> path doesn't work with rtstructs, ie, the result of reading rtstructs
>>>>> via the vtkGDCMPolyDataReader.  It only works if I run the extrusion
>>>>> first.  In addition, I can't find other code that uses the direct
>>>>> path, so I can't see how to fix the polydata (if it's, in fact,
>>>>> broken) to use the direct path.
>>>>>
>>>>> So how can I get the direct path to be chosen?  The output from the
>>>>> reader is a set of lines, and only adds polys once we do the
>>>>> extrusion.  Given that it still takes 10 seconds, _something_ is being
>>>>> done there...
>>>>>
>>>>> Thanks,
>>>>> Mark
>>>>>
>>>>> On Mon, Feb 27, 2012 at 12:58 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>>>>>> On Mon, Feb 27, 2012 at 1:24 PM, Mark Roden <mmroden at gmail.com> wrote:
>>>>>>
>>>>>>> David, if you could please shed some light on how to use the faster code path-- right now, it produces blank binary images.
>>>>>>
>>>>>> See line 320 in the source code.  That's the "if" statement that
>>>>>> chooses the cutter-path (if the input is polys) or the direct path (if
>>>>>> the input is polyline contours that are aligned with the slices).
>>>>>>
>>>>>> http://vtk.org/gitweb?p=VTK.git;a=blob;f=Hybrid/vtkPolyDataToImageStencil.cxx;#l320
>>>>>>
>>>>>> If you want to be sure about what path your data is taking, you can
>>>>>> add print statements to the code, or run your program in a debugger.
>>>>>>
>>>>>>  - David



More information about the vtk-developers mailing list