I am trying to register and deform a surgical plate (roughly pre-registered using a few discrete landmarks) to adapt to the surface of the orbit. The plate has a thickness. You can see that some parts of the pre-registered unbended plate is “sinking” into the orbit.
The approach I am testing to adapt the plate to the orbital surface is to 1) sample same points at both the upper and undersurface of the plate, and 2) project the points at the upper surface of the plate to the orbit, and 3) run a registration between the points at the under plate surface to the points projected to the orbit, followed by a thin-plate spline (TPS) transformation (deform the plate at the same type).Though not perfect, it did adapt most of the plate to the surface of the orbit.
Points at the upper surface of the plate. Same points were also sampled at the under surface.
Points projected to the orbital surface from points plated at the upper surface of the plate.
Deformed plate adapt to the orbital surface based on register the points at the undersurface of the plate to the points projected to the orbital surface followed by a thin-plate spline transformation.
However, a small part of the plate was still under the surface. This is because a few points (31, 32, 44) at that region were projected to another side of the orbit due to the presence of a convex area at the medial orbital wall. Thus, a portion of the plate “sank” too deep under that convex area and got too close to under side of the orbital surface.
Is there any way to project points into a designated upper surface of the orbit?
The way I do the projection is by using the the
runPointProjection() function based on the
projectPointsPolydata in the
ALPACA module of the
SlicerMorph extension, which is about casting a ray along the normal of each point and find the intersection with the surface of another model (https://github.com/SlicerMorph/SlicerMorph/blob/8c1419d0a6da86f8009980f8925a238cbd2fa88d/ALPACA/ALPACA.py#L2977C4-L3073C1).
The script I did was:
import ALPACA logic = ALPACA.ALPACALogic() plate_model_node = slicer.util.getNode("preregistered_plate") lm_plate_upper_node = slicer.util.getNode("lm_plate_upper_surface") orbit_model_node = slicer.util.getNode("orbit") projectionFactor = 0.001 #I've been playing with the parameter. lm_projected_to_orbit = logic.runPointProjection(plate_model_node, orbit_model_node, lm_plate_upper_node , projectionFactor) projected_plate_below_to_orbit_lm.SetName("lm_projected_to_orbit")
Orbit and plate and landmark files can be accessed at: orbit_and_plate.zip - Google Drive