Issue with vtkClipClosedSurface on a bone stl file

Hey everyone,

I’m quite new in using vtk, but I manage to write some code in C++ that allows a user to cut a bone thanks to mouse click.
I’ll explain: user select three points on the STL file he wants to cut, a plane is created thanks to those three points and then I want to clip the stl according to this plane. This part pertfectly works using vtkClipDataSet and the related mapper and actor.
You can see the result on the next image:


The left part of the renderer is where the original STL file is displayed and the user can choose points to define the cutting plane. The right renderer is the result, thus the cutted bone.

As you can see, the top surface is not “closed”. I thought I could do that quite simply by using vtkClipClosedSurface instead of vtkClipDatSet, but it doesn’t seems to work (as you can see on the capture below).

Here is the code related to this part:

vtkSmartPointer planes = vtkSmartPointer::New();
planes->AddItem(plane);

		vtkSmartPointer<vtkClipClosedSurface> clipper =
			vtkSmartPointer<vtkClipClosedSurface>::New();
		clipper->SetInputData(STLreader->GetOutput());
		clipper->SetClippingPlanes(planes);
		clipper->SetScalarModeToColors();
		clipper->SetClipColor(0.8900, 0.8100, 0.3400); // banana
		clipper->SetBaseColor(1.0000, 0.3882, 0.2784); // tomato
		
		vtkSmartPointer<vtkDataSetMapper> clipMapper = 	vtkSmartPointer<vtkDataSetMapper>::New();
		clipMapper->SetInputConnection(clipper->GetOutputPort());

		vtkSmartPointer<vtkActor> clipActor = vtkSmartPointer<vtkActor>::New();
		clipActor->SetMapper(clipMapper);
		clipActor->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);
		clipActor->GetProperty()->SetInterpolationToFlat();

		rightRenderer->AddActor(clipActor);  //add the cutted actor
		rightRenderer->RemoveActor(actor);  //remove the STL original file

Am I forgotting something? I tried to follow the exemple given by vtk
[https://lorensen.github.io/VTKExamples/site/Cxx/Meshes/ClipClosedSurface/](http://vtk example) and just adapt it to work with the rest of my code…

Maybe vtkClipClosedSurface don’t work with “empty” volume? (I tried to figure it out with the doc but didn’t success…)

Thank you for your time and help :slight_smile:
Don’t hesitate if I wasn’t clear, it’s my first post here so I’m not used to explain issue that I encouter… :slight_smile:

We use vtkClipClosedSurface in 3D Slicer’s EasyClip extension for clipping polydata and the clipped cross-sections are nicely covered with a triangulated plane. The module is implemented in Python and you can have a look at its source code here, maybe you’ll notice some differences compared to how you have set up your filter. You can also see if there is something special in your data that makes the filter fail, by trying clipping your data in 3D Slicer with Easy Clip.

Thank you for this answer, I will try what you suggest!

I’m the author of vtkClipClosedSurface. The only obvious thing that might make it fail with your data is if the triangles aren’t correctly oriented. You could try passing your data through vtkPolyDataNormals with ConsistencyOn(), and try it with or without vtkReverseSense.

2 Likes

This works perfectly with the vtkReverseSense, my triangle were indeed wrongly oriented! Thank you so much for your time and advice!

1 Like

Hi David,
I have a question here, is there any way to automatically detect whether vtkReverseSense needs to be used on a model?

I don’t know of a simple way to do it in VTK. But mathematically, there are two methods that can be used:

  1. Calculate the enclosed volume using the polyhedron volume formula. If the volume is negative, the surface needs to be reversed. This is a fairly expensive check.

  2. Compute the normal of any point on the convex hull of the model. If the normal points inwards, the surface needs to be reversed. This is easier than it sounds: any extreme point of the mesh is on the hull, so you can e.g. find the point with the largest x coordinate. Compute the normal of this point, using the weighted sum of the normals of the adjacent faces. If the x component of this normal is negative, then the surface needs to be reversed.

1 Like

Thanks! I’ll try your suggestion.