How to generate path between two specified nodes in treelib tree object in python

Viewed 18

I have been trying to create a function that takes needed parameters and creates and returns a path. But I could not found any solution.

In detail, as you see below I'm using treelib library. I'm reading data from a 3d model than skeletonizing it with skeletor library. It gives me results as ->

     node_id  parent_id         x         y         z radius                                                                                                                                              
0          0         -1 -1.228041 -0.106300  0.001783   None
1          1          0 -1.223447 -0.108507 -0.003192   None
2          2          4 -1.203667 -0.120944 -0.014145   None
3          3          5 -0.332745  0.222496  1.590621   None
4          4          1 -1.217804 -0.115034 -0.011167   None
..       ...        ...       ...       ...       ...    ...
655      655        534  0.179983 -1.285225  0.181451   None
656      656        480 -0.408439 -0.766452  0.132349   None
657      657        545 -0.085553 -0.860636  0.359673   None
658      658        659 -0.079773 -0.854532  0.385282   None
659      659        657 -0.081701 -0.857868  0.373008   None

While storing these values, I use a basic class "MyNode". (I will give the code below)

After that, I'm creating a tree with treelib Tree class according to the taken info from skeleton. Se the tree output here -> ("Note you can also generate the tree by the code I give") zoomed out photo of tree_output.txt

In this tree, nodes are represented with their ID's, and I want to create method that takes (startID, endID) to create path between these two ids. I have tried several methods, but I keep facing with errors or only empty list returns and etc.

About the usage case, I really like to find a path from "8" to "482" or opposite. See here -> desired function's result explained (The red node IDS should be returned as path in a list. Order is not required)

Shortly, the only thing I need is to get a list including the nodes.

The input file used -> ply file used

See the code here,

from collections import defaultdict
from treelib import Tree  
import skeletor as sk
import trimesh as tm

class MyNode :
    def __init__(self, nodeID:int, parentNodeID:int, nodeX:float, nodeY:float, nodeZ:float) -> None:
        self.nodeID, self.parentNodeID, self.nodeX, self.nodeY, self.nodeZ = int(nodeID), int(parentNodeID), float(nodeX), float(nodeY), float(nodeZ)
    def __str__(self) -> str: 
        return (f"MyNode(SelfID:{self.nodeID}, ParentID:{self.parentNodeID}, X:{self.nodeX}, Y:{self.nodeY}, Z:{self.nodeZ})")

inputMeshFile = "question_input.ply"
mesh = tm.load_mesh(inputMeshFile)

skeleton = sk.skeletonize.by_teasar(mesh=mesh, inv_dist=0.27)
skeletonInfo = skeleton.swc

allNodes = []
for i in range(len(skeletonInfo)) :
    allNodes.append(
        MyNode(
            skeletonInfo["node_id"].values[i], 
            skeletonInfo["parent_id"].values[i], 
            skeletonInfo["x"].values[i], 
            skeletonInfo["y"].values[i], 
            skeletonInfo["z"].values[i]
        )
    )

childrenParen_DDict = defaultdict(list) # <-- children-parent ddict, ddict is used for creating tree easier

for currentNode in allNodes :
    childrenParen_DDict[currentNode.parentNodeID].append(currentNode.nodeID)

root = childrenParen_DDict[-1][0]

tree = Tree()
tree.create_node(root, root)

agenda, seen = [root], set([root])
while agenda:
    nxtParent = agenda.pop()
    for child in childrenParen_DDict[nxtParent]:
        tree.create_node(child, child, parent=nxtParent)
        if child not in seen:
            agenda.append(child)
            seen.add(child)

tree.save2file("tree_output.txt")

#Rest of the code I want to make it run.

def findPath(startNode:MyNode, endNode:MyNode, tree:Tree, allNodes:list) -> list :
        path = []
    
        #.
        #.
        #.
    
        return path 
    
    print("Path is :", findPath(allNodes[8], allNodes[482], tree, allNodes))
0 Answers
Related