Markups fiducials are displayed in 3D views using vtkAbstractPolygonalHandleRepresentation3D. By default, it uses vtkFocalPlanePointPlacer for converting 2D click position to 3D position (this class constrains point positions to a plane parallel to the focal plane), but using SetPointPlacer method of the representation, it should be possible to change the placer. For example, if you set a vtkPolyDataPointPlacer instance as placer then point positions will be constrained to selected polygonal actor. Model displayable manager should be able to provide polygonal actor corresponding to a model node.
Thanks for your reply @lassoan. I’ve looked at the current implementation and would like to clarify how the handles are being used by the markups.
Would it be correct change the point placer of the handle created by vtkMRMLMarkupsFiducialDisplayableManager3D::CreateWidget or the handle of the Nth seed placed by vtkMRMLMarkupsFiducialDisplayableManager3D::SetNthSeed? If I understand correctly both are using vtkOrientedPolygonalHandleRepresentation3D and would be able to use the vtkPolyDataPointPlacer.
I started an experiment in this branch linked below. I didn’t use the vtkPolyDataPointPlacer approach, because we’d also like the method to work well on volume renderings and segmentations, etc. What I have almost works but not perfectly.
Yes, it is, i.e. a markup point is automatically positioned to a location closest to the model surface, kind of like “Shortest distance on surface” for curve setting. However, I do not see this feature for markup points in the latest preview release 2020-08-18. What am I missing?
For me it just happens with no feature setting required. I guess if you don’t want to snap to a surface than you make that model invisible.
If you have a model visible and you click to add a fiducial in the 3D view it should be on the surface, and then stay on the surface when you drag. That’s what happens for me anyway with today’s nightly preview.
Maybe it’s that we mean slightly different things. What I mean is that if you click on the green part when placing the fiducial it will snap to the surface, but if you click on the blue part it will be a an arbitrary distance from the camera. If you drag the fiducial over the green object it should snap to that.
In curves control points behave the same way as fiducials, only the curve points are strictly constrained to the selected surface. I agree that it could be useful to add a hard constraint to the control point themselves. We will implement this if one of the funded projects will require this feature. I’ve added an issue so that you can monitor if there is any progress:
I have encountered the same issue. I was trying to measure a surface of the cross-sections of hummingbird tongue. In order to measure the surface perpendicular to the longitudinal axes to the tongue, I transformed ROI and made measurements directly on my 3D model. However, the fiducials in the blue space is not constrained to the surface of the tongue. I wonder if it’s possible to constrain fiducials to a markup plane so it will be very flexible?
I dont think you have 3D model, all I can see is a volume rendering. If you use curves on volume rendering, you I suspect you will be susceptible to rendering artifacts. You will be better of doing a segmentation of this region, then export it as a model and then repeat the task.
From your screenshot it looks like Slicer works as it is supposed to. In 3D views, points are snapped to visible surfaces, which works for volume rendering, too, and as long as you can clearly see a surface in the view, the placed point positions will be predictable, too.
If you mean that you would like to constrain placement to an image plane then you can move a slice view where you want to annotate (by holding down Shift key while moving the mouse) and place points on that slice.