<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">'''
This script uses a registration XML to read bone and cartilage STLs to delete the inner surface of the cartilage

Inputs:
Registration xml with the appropriate locations of the segmented STLs

USAGE:
python STLspliter.py &lt;Registration.xml&gt;

Outputs:
New STls without inner surface

Written By:
Rodrigo Lopez-Navarro
Department of Biomedical Engineering, Cleveland Clinic
'''
import numpy as np
import vtk
import xml.etree.ElementTree as ET
import os
import sys

def splitSTL(bone_stl, cart_stl, name):
    reader1 = vtk.vtkSTLReader()
    reader1.SetFileName(bone_stl)
    reader1.Update()

    reader2 = vtk.vtkSTLReader()
    reader2.SetFileName(cart_stl)
    reader2.Update()

    implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance()
    bone_data = reader1.GetOutput()
    implicitPolyDataDistance.SetInput(bone_data)
    cart_data = reader2.GetOutput()

    points = vtk.vtkPoints()
    a = np.zeros(3)
    for i in range(cart_data.GetNumberOfPoints()):
        cart_data.GetPoint(i, a)
        points.InsertNextPoint(a[0], a[1], a[2])

    # Add distances to each point
    signedDistances = vtk.vtkFloatArray()
    signedDistances.SetNumberOfComponents(1)
    signedDistances.SetName("SignedDistances")
    dist = []
    proximity_nodes = []
    np.asarray(proximity_nodes)
    # Evaluate the signed distance function at all of the grid points
    for pointId in range(points.GetNumberOfPoints()):
        p = points.GetPoint(pointId)
        signedDistance = implicitPolyDataDistance.EvaluateFunction(p)
        signedDistances.InsertNextValue(signedDistance)
        dist.append(signedDistance)
    np.asarray(dist)
    ave = np.average(dist)

    b = np.zeros(3)
    newpoints = vtk.vtkPoints()

    for ind, len in enumerate(dist):
        if len &gt; (1.05*ave) or len &gt; (0.95*ave):
            points.GetPoint(ind,b)
            newpoints.InsertNextPoint(b)

    polyData = vtk.vtkPolyData()
    polyData.SetPoints(newpoints)
    delaunay = vtk.vtkDelaunay2D()
    delaunay.SetInputData(polyData)
    delaunay.Update()

    delaunay = vtk.vtkDelaunay2D()
    delaunay.SetInputData(polyData)
    delaunay.Update()

    stlWriter = vtk.vtkSTLWriter()
    stlWriter.SetFileName(name)
    stlWriter.SetInputConnection(delaunay.GetOutputPort())
    stlWriter.Write()

def main(args):

    input_xml = ET.parse(args[-1])
    root = input_xml.getroot()

    knee_dir = root.find("Knee_directory").text
    knee_id = os.path.split(knee_dir)[1]

    FMC_stl_name = root.find("Cartilages").find("Fem-cart").find("file").text
    TBB_L_stl_name = root.find("Cartilages").find("Tibia-L").find("file").text
    TBB_M_stl_name = root.find("Cartilages").find("Tibia-M").find("file").text
    PTC_stl_name = root.find("Cartilages").find("Pat-cart").find("file").text
    cartilage_stls = [os.path.join(knee_dir, 'mri-' + knee_id, FMC_stl_name),
                      os.path.join(knee_dir, 'mri-' + knee_id, TBB_L_stl_name),
                      os.path.join(knee_dir, 'mri-' + knee_id, TBB_M_stl_name),
                      os.path.join(knee_dir, 'mri-' + knee_id, PTC_stl_name)]
    femur_stl_name = root.find("Bones").find("Femur").find("file").text
    tibia_stl_name = root.find("Bones").find("Tibia").find("file").text
    fibula_stl_name = root.find("Bones").find("Fibula").find("file").text
    patella_stl_name = root.find("Bones").find("Patella").find("file").text
    bone_stls = [os.path.join(knee_dir, 'mri-' + knee_id, femur_stl_name),
                 os.path.join(knee_dir, 'mri-' + knee_id, tibia_stl_name),
                 os.path.join(knee_dir, 'mri-' + knee_id, patella_stl_name),
                 os.path.join(knee_dir, 'mri-' + knee_id, fibula_stl_name)]

    splitSTL(bone_stls[0], cartilage_stls[0], 'fem_cart_split.stl')
    splitSTL(bone_stls[1], cartilage_stls[1], 'tib_L_cart_split.stl')
    splitSTL(bone_stls[1], cartilage_stls[2], 'tib_M_cart_split.stl')
    splitSTL(bone_stls[2], cartilage_stls[3], 'pat_cart_split.stl')

    reader = vtk.vtkSTLReader()
    reader.SetFileName(bone_stls[0])
    reader.Update()

    reader2 = vtk.vtkSTLReader()
    reader2.SetFileName(cartilage_stls[0])
    reader2.Update()

if __name__ == "__main__":
    main(sys.argv)
    # main(['callfunction', '/home/lopezr3/Documents/CC/Registration/oks003_registration_01.xml'])</pre></body></html>