vtkStripper get wrong loop contour when inputdata is vtkcutter

hi guys
I use vtkcutter cut mesh by planes and get 200 contours. And, use vtkStripper to detect closed contour. finally, I use vtkCleanPolyData to sort the points of contours
code is as follows:
vtkSmartPointer cutter = vtkSmartPointer::New();
cutter->SetCutFunction(plane);
cutter->SetInputData(poissonpolydata);

			int slicecount = fabsf(zmax - origin[2]) / zhigh + 1;
			cutter->GenerateValues(slicecount, 0.0, zmax - zmin);
			cutter->Update();

			auto numONcountorsq1 = cutter->GetNumberOfContours();


			vtkSmartPointer<vtkStripper> stripper = vtkSmartPointer<vtkStripper>::New();

			stripper->SetInputData(cutter->GetOutput());
			stripper->SetMaximumLength(99999);
			stripper->JoinContiguousSegmentsOn();
			stripper->Update();

			vtkSmartPointer<vtkCleanPolyData> cleanPolyData = vtkSmartPointer<vtkCleanPolyData>::New();
			cleanPolyData->SetInputConnection(stripper->GetOutputPort());
			cleanPolyData->Update();

I get Incomplete contours like this
1636270675127_1A1BBE8F-21FC-4063-8457-B5C728C44B33

1636270718788_10743660-65D9-410f-B04B-19D31A757AC2
the two pictures above showed be one .But then I get two different pictures.

Using vtkStripper for creating polygons from a cut surface was just a workaround. The proper filter for this task is vtkContourTriangulator. It is not just more robust but it also has essential features that vtkStripper lacks. For example, if you slice a 3D shape that has some concavities then those may appear in slices as holes, which vktContourTriangulator will correctly render as holes (does not fill them).

very appreciated! I will try it.

I’ve tried this filter like this


but I get zero lines but the points number is maybe right, but the cells number is close to the point number. Is there any problem using it like above? thanks.

the contour of the topic is a 3d contour but z is the same value.

You get polygon or triangle cells, so your numbers sound good.

How to get the contours? I will resort to the points of contour clockwise with vtkCleanPolyData.

I’m not sure if you are on the right track. Could you describe your overall goal?

I have a 3d mesh surface like bellow


I want to cut it with equal steps belong z axes, so I use vtkcutter to cut the surface and get 200 layers of contours. Then I will get the contours closed polylines, so I use vtkstripper. but stripper gets the wrong segment, like the topic problem.

How do you plan to use the slice intersections? Visualization (show in a slice view, …), quantification (compute surface area, curvature, …), modling (cap the cut surface, …), 3D printing, laser cutting, …?

I will use it to generate clockwise point lists and write them to dicom file.

Would you like to write an RT structure set?

lQLPDhrayA6s-8LNAbHNAjWwCeHZe_eKPzcBk7HCBEBrAA_565_433
yes like this, the green close polyline and Purple polyline are got from the surface cutter. some are normal but others are wrong like a topic problem.

Stay away from DICOM RT structure sets. Until very recently, the only option to specify concavities (holes in the intersection) was to use the keyhole technique. Since many faulty, non-DICOM compliant software implementations started to appear in the last few years (which did not use the keyhole technique but used traditional computer graphics method of combining contours with XOR operation), vendors stepped in and added a supplement that allows imaging vendors to explicitly state that they used keyhole technique and a separate contour type for software that cannot generate keyholes. (Note that neither the keyhole, nor the XOR technique relies on polygon winding direction, so you would not need to worry about clockwise direction.) Of course most software developers are still not aware that they were not standard compliant and that they would need to specify a different contour type if they use XOR technique. Another issue is that contours can only be generated reliably for simple shapes (typically hand drawn by clinicians), and not for arbitrarily complex intersections generated by reslicing images. What is even worse, reconstructing of 3D surfaces from parallel contours is not a well defined operation either. Therefore, RTSTRUCTs are really problematic: it is practically impossible to implement an accurate reader and writer that works well with multiple software applications. There is significant difference between even how clinical radiation therapy systems generate and interpret the parallel contours (see this recent paper).

In case you are forced to use RT structure sets (because for example you need to inject segmentation into a radiation treatment planning software) then don’t even think about implementing yet another limited, broken exporter, but choose one of the many existing implementations. We got a big grant about a decade ago to implement RT support in 3D Slicer: we spent 5 years implementing an importer, which has become quite good in the end (tested on tens of thousands of images by many users, which probably brought out most of the limitations and they are all quite reasonable); and integrated the DICOM exporter of Plastimatch library, which we don’t get too many complaints for either. So, one option is to use these algorithms in 3D Slicer/SlicerRT. If you don’t need a solution that works for a wide variety of contours (or you can manually verify all imports and exports and can correct them manually as needed), then you can do a google search and choose one of the many simplified implementations (mostly in Python). Although these implementations often have many serious limitations and not thoroughly validated, but they might work for your specific use case.

If you you just need a way to store segmentations (binary masks) in DICOM then the best information object for that is DICOM Segmentation Object. It allows lossless, unambiguous storage of segmentations. Reading/writing this information object is not trivial either because unfortunately the file format uses a complicated bit packing algorithm. But the difference compared to RT structure set is that there is a consensus among software developers of various packages of how to handle Segmentation Objects and there are a few well-tested implementations (for example in DCMQI library, which is very widely used in the research community).

1 Like