How to find the upper-direction of mesh data ( idea , task, reference anything )

Operating system: window 10
Slicer version: 5.2.1

I have several mesh data files (.ply), and the orientation of objects in these files is always random.

like this :

With the goal of having all meshes have the same ‘upper-direction’, I tried the following ideas.

  1. calculate mesh’s center point

  2. get ‘inner-mesh’ from kD-tree

  3. Find the point normals of the ‘inner-mesh’ and sum them all.


# make functions that find inner mesh 

# set mesh's center point

mesh_center_pos =[0,0,0]
node_in_scene = slicer.mrmlScene.GetNodesByClass('vtkMRMLModelNode')

for value in node_in_scene:
 node_name = value.GetName()

crown_node = getNode(node_name)
mesh = crown_node.GetMesh()


# make kdtree for mesh data
points = mesh.GetPoints()
k_Dtree = vtk.vtkKdTree()
k_Dtree.SetNumberOfRegionsOrMore(4)
k_Dtree.BuildLocatorFromPoints(points)


# cal mesh's center point 
for value in range(mesh.GetNumberOfPoints()):
 mesh_center_pos[0] += mesh.GetPoint(value)[0] 
 mesh_center_pos[1] += mesh.GetPoint(value)[1] 
 mesh_center_pos[2] += mesh.GetPoint(value)[2] 

mesh_center_pos[0] /= mesh.GetNumberOfPoints()
mesh_center_pos[1] /= mesh.GetNumberOfPoints()
mesh_center_pos[2] /= mesh.GetNumberOfPoints()

# current pos = [28.750410911221405, -4.0782514881915715, 26.817471450103564]
slicer.modules.markups.logic().AddControlPoint(mesh_center_pos[0], mesh_center_pos[1] , mesh_center_pos[2])

inner_mesh_id = vtk.vtkIdList()

k_Dtree.FindClosestNPoints( 3000, mesh_center_pos, inner_mesh_id)

inner_mesh_pos = [] 

# get nearest position's id 
for value in range(inner_mesh_id.GetNumberOfIds()):

 inner_mesh_pos.append( inner_mesh_id.GetId(value))

# draw nearest position via makrupsFiducialNode
for value in inner_mesh_pos:
 closet_pos = mesh.GetPoint(value)
 slicer.modules.markups.logic().AddControlPoint(closet_pos[0], closet_pos[1] , closet_pos[2])

However, the kD_tree.FindClosestNPoints() function has a problem because it requires directly specifying the number of points close to the reference point.

Therefore, I want to unify the case where the direction of the mesh data object is random. Is there a way to find the uppder-direction of the ojbect mesh?

If the shape is always similar to your sketches then the “up” vector is the vector that connects the center of the oriented bounding box to the center of gravity. You can get both these center positions from Segment Statistics module.