Display the shortest surface to surface distance using python

Hello,

I have two segmentations. I want to measure and display the shortest distance between the surfaces (just like the picture below)

I can measure the distance between the two surfaces using slicer.modules.modeltomodeldistance but I can’t get the two points that achieve this smallest distance.

Does anyone knows how to get the points achieving the smallest distance given by slicer.modules.modeltomodeldistance

I just discovered this module and AFAIU, the following should solve your problem, at least if your models do not intersect.

If you use absolute_closest_point, you can get one point coordinate from the Absolute array of the output model (the one(s) with the minimum absolute distance). With this coordinate, the polydata of the Target Model can give the second coordinate using FindPoint() and GetPoint().

I managed to get this using the following code

    # Step 2: Compute distance from inside to outside
    distance_model = findModelToModelDistance(outside_model, inside_model)  # Distance from outside to inside
    VTKFieldData = distance_model.GetMesh().GetAttributesAsFieldData(0)
    created_nodes.append(distance_model)

    # Step 3: Extract signed distances and find min
    signedVals = []
    for i in range(VTKFieldData.GetArray("Signed").GetNumberOfTuples()):
        val = VTKFieldData.GetArray("Signed").GetValue(i)
        signedVals.append(-val)  # Negate to get correct direction

    min_index = np.argmin(signedVals)
    min_distance = signedVals[min_index]

    # Step 4: Get closest point on inside
    closest_inside_point = inside_model.GetPolyData().GetPoint(min_index)

    # Step 5: Get corresponding closest point on outside
    locator = vtk.vtkPointLocator()
    locator.SetDataSet(outside_model.GetPolyData())
    locator.BuildLocator()
    closest_outside_point_id = locator.FindClosestPoint(closest_inside_point)
    closest_outside_point = outside_model.GetPolyData().GetPoint(closest_outside_point_id)

def findModelToModelDistance(modelNode1,modelNode2):
    vtkOutput = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLModelNode")
    vtkOutput.SetName("m2md")

    parameters = {}
    parameters["vtkFile1"] = modelNode2
    parameters["vtkFile2"] = modelNode1
    parameters['distanceType'] = "signed_closest_point"
    parameters["vtkOutput"] = vtkOutput

    cliNode = slicer.cli.runSync(slicer.modules.modeltomodeldistance, None, parameters)
    return vtkOutput