Is there a convenient way to extract a single of these contour lines (possibly without creating a copy of the data) for rendering? Best would be also as vtkPolyData.
If there is not: I know there is vtkPolyData::GetLines() and vtkCellArray::GetCellAtId(). Unfortunately, the latter only gets me vtkIdList *. How would I get vtkCellArray needed for vtkPolyData::SetLines()?
I want to try again / give more information / elaborate.
Currently, I am using vtkImageViewer2 to both draw an image as well as contour data:
What I want is to render a single contour line in accordance with the currently displayed image slice.
I also played around with AutoAdjustCameraClippingRange of the InteractorStyleImage but that didn’t work.
Is there any functionality in VTK that I could use for this purpose? Thanks
You can add clipping planes to the mapper with the AddClippingPlane() method. Two clipping planes are needed, one on each side of the contour you want to show. Once the clipping planes are added to the mapper, you can adjust the two vtkPlane objects to select different contours.
If you want to adjust the clipping planes for interactive viewing, a good way to do this is by adding an observer method (a callback) for the StartEvent of the renderer. This method would have to figure out what contour should be displayed and then set the clipping planes. By observing the StartEvent, it’s guaranteed that the clipping planes can be set before the mapper actually renders the data.
Using observers like this is an advanced topic, but there are some general observer examples on the VTK examples site (though probably none with StartEvent or clipping planes).
So you’re introspecting the renderer to find the actors? I’d recommend a more direct approach: in your callback class, you can have a list of the mappers that you want to clip (more specifically, you can use an std::vector<vtkSmartPointer<vtkMapper>>).
For setting the planes, I don’t recommend Push(). Use SetOrigin() instead.
The GetClippingRangeExpansion() method isn’t going to give you anything useful for setting the mapper clipping planes. What you need is to get a point (any point) on the image plane, in world coordinates. The “origin” points of your clipping planes will be offset from that image plane point (offset in different directions along the plane normal).
The clipping planes need to have opposite normals, i.e. one (0, 0, -1) and the other (0, 0, +1).
For debugging, I recommend trying just one thing at a time. Start with just one clipping plane. Manually set the Origin and Normal (without using a transform). Play around with both the Normal and Origin. Once you see it clipping in a way that makes sense, you can build up the rest of the code to properly automate the clipping.
Let’s assume I have a clipping plane c at coordinates (x_c,y_c,z_c), clipping in positive z-direction, i.e., its normal is set to (0,0,1). Will primitive p, with z-coordinate z_p = z_c get clipped or not?
Maybe yes and maybe not, it depends on roundoff error. The vtkPlane’s normal and origin are converted into a glClipPlane so that the GPU can do the clipping, which is a different formulation and uses different numerical precision (single-precision float rather than double-precision float).
In any case, most floating-point math is inexact, and questions like “is the point exactly on the plane” cannot, in general, be answered with floating-point math.