1+ """This compoment calculates the pose of a data tree of point clouds."""
12#! python3
23
34from diffCheck import df_cvt_bindings
45from diffCheck import df_poses
6+ from diffCheck .diffcheck_bindings import dfb_geometry
57
68import Rhino
79from Grasshopper .Kernel import GH_RuntimeMessageLevel as RML
10+ import Grasshopper
11+ import ghpythonlib .treehelpers as th
812
913from ghpythonlib .componentbase import executingcomponent as component
10- import System
1114
1215
1316class DFPoseEstimation (component ):
1417 def RunScript (self ,
15- i_clouds : System . Collections . Generic . List [Rhino .Geometry .PointCloud ],
18+ i_face_clusters : Grasshopper . DataTree [Rhino .Geometry .PointCloud ],
1619 i_assembly ,
17- i_save : bool ,
18- i_reset : bool ):
20+ i_reset : bool ,
21+ i_save : bool ):
1922
23+ clusters_per_beam = th .tree_to_list (i_face_clusters )
2024 # ensure assembly has enough beams
21- if len (i_assembly .beams ) < len (i_clouds ):
25+ if len (i_assembly .beams ) < len (clusters_per_beam ):
2226 ghenv .Component .AddRuntimeMessage (RML .Warning , "Assembly has fewer beams than input clouds" ) # noqa: F821
2327 return None , None
2428
@@ -29,32 +33,31 @@ def RunScript(self,
2933 return None , None
3034
3135 all_poses_this_time = []
32- for i , cloud in enumerate (i_clouds ):
36+ for i , face_clouds in enumerate (clusters_per_beam ):
3337 try :
34- df_cloud = df_cvt_bindings .cvt_rhcloud_2_dfcloud (cloud )
35- if df_cloud is None :
36- return None , None
37- if not df_cloud .has_normals ():
38- ghenv .Component .AddRuntimeMessage (RML .Error , f"Point cloud { i } has no normals. Please compute the normals." ) # noqa: F821
38+ df_cloud = dfb_geometry .DFPointCloud ()
3939
40- df_points = df_cloud .get_axis_aligned_bounding_box ()
41- df_point = (df_points [0 ] + df_points [1 ]) / 2
42- rh_point = Rhino .Geometry .Point3d (df_point [0 ], df_point [1 ], df_point [2 ])
40+ rh_face_normals = []
41+ for face_cloud in face_clouds :
42+ df_face_cloud = df_cvt_bindings .cvt_rhcloud_2_dfcloud (face_cloud )
43+ df_cloud .add_points (df_face_cloud )
44+ plane_normal = df_face_cloud .fit_plane_ransac ()
45+ rh_face_normals .append (Rhino .Geometry .Vector3d (plane_normal [0 ], plane_normal [1 ], plane_normal [2 ]))
4346
44- axes = df_cloud .get_principal_axes (3 )
45- vectors = []
46- for axe in axes :
47- vectors .append (Rhino .Geometry .Vector3d (axe [0 ], axe [1 ], axe [2 ]))
47+ df_bb_points = df_cloud .get_axis_aligned_bounding_box ()
48+ df_bb_centroid = (df_bb_points [0 ] + df_bb_points [1 ]) / 2
49+ rh_bb_centroid = Rhino .Geometry .Point3d (df_bb_centroid [0 ], df_bb_centroid [1 ], df_bb_centroid [2 ])
4850
49- new_xDirection , new_yDirection = df_poses .select_vectors (vectors , i_assembly .beams [i ].plane .XAxis , i_assembly .beams [i ].plane .YAxis )
51+ new_xDirection , new_yDirection = df_poses .select_vectors (rh_face_normals , i_assembly .beams [i ].plane .XAxis , i_assembly .beams [i ].plane .YAxis )
5052
5153 pose = df_poses .DFPose (
52- origin = [rh_point .X , rh_point .Y , rh_point .Z ],
54+ origin = [rh_bb_centroid .X , rh_bb_centroid .Y , rh_bb_centroid .Z ],
5355 xDirection = [new_xDirection .X , new_xDirection .Y , new_xDirection .Z ],
5456 yDirection = [new_yDirection .X , new_yDirection .Y , new_yDirection .Z ])
5557 all_poses_this_time .append (pose )
56- plane = Rhino .Geometry .Plane (origin = rh_point , xDirection = new_xDirection , yDirection = new_yDirection )
58+ plane = Rhino .Geometry .Plane (origin = rh_bb_centroid , xDirection = new_xDirection , yDirection = new_yDirection )
5759 planes .append (plane )
60+
5861 except Exception as e :
5962 # Any unexpected error on this cloud, skip it and keep going
6063 ghenv .Component .AddRuntimeMessage (RML .Error , f"Cloud { i } : processing failed ({ e } ); skipping." ) # noqa: F821
0 commit comments