77from diffCheck import df_cvt_bindings as df_cvt
88import diffCheck .df_util
99
10+ from Grasshopper .Kernel import GH_RuntimeMessageLevel as RML
1011from ghpythonlib .componentbase import executingcomponent as component
1112
13+ import typing
14+
1215ABSTOL = Rhino .RhinoDoc .ActiveDoc .ModelAbsoluteTolerance
1316
1417class DFJointSegmentator (component ):
18+ # def __init__(self):
19+ # super(DFJointSegmentator, self).__init__()
1520 def RunScript (self ,
16- i_clusters : Rhino .Geometry .PointCloud ,
17- i_joints : Rhino .Geometry .Mesh ,
18- i_joint_ids : int ,
21+ i_clusters : typing .List [Rhino .Geometry .PointCloud ],
22+ i_assembly : diffCheck .df_geometries .DFAssembly ,
1923 i_angle_threshold : float ,
2024 i_distance_threshold : float ):
2125 """
@@ -24,43 +28,42 @@ def RunScript(self,
2428 and returns the joint segments, the reference point clouds, and the ICP transformations from the first to the second.
2529
2630 :param i_clusters: The clusters to be associated to the joints.
27- :param i_joints: The joints to which the clusters will be associated. These are meshes.
28- :param i_joint_ids: The joint ids of the joints.
31+ :param i_assembly: The DFAssembly containing the joints we want to segment.
2932 :param i_angle_threshold: The angle threshold for the association of the clusters to the joints.
3033 :param i_distance_threshold: The distance threshold for the association of the clusters to the joints.
3134 """
3235 if i_angle_threshold is None : i_angle_threshold = 0.1
3336 if i_distance_threshold is None : i_distance_threshold = 0.1
34-
35- if len (i_joints ) != len (i_joint_ids ):
36- raise ValueError ("The number of joints and joint ids must be the same." )
3737
3838 if len (i_clusters ) == 0 :
3939 raise ValueError ("No clusters given." )
4040
4141 if not isinstance (i_clusters [0 ], Rhino .Geometry .PointCloud ):
4242 raise ValueError ("The input clusters must be PointClouds." )
4343
44- if not isinstance (i_joints [0 ], Rhino .Geometry .Mesh ):
44+ all_joints = i_assembly .all_joints
45+ if not isinstance (all_joints [0 ].faces [0 ].to_mesh (), Rhino .Geometry .Mesh ):
4546 raise ValueError ("The input joints must be convertible to Meshes." )
4647
48+ # get number of joints
49+ n_joints = max ([joint .id for joint in all_joints ]) + 1
4750
4851 # prepping the reference meshes
49- n_joints = max (i_joint_ids ) + 1
50- joints = [ [] for i in range (n_joints ) ]
51- for face , id in zip (i_joints , i_joint_ids ):
52- face .Subdivide ()
53- face .Faces .ConvertQuadsToTriangles ()
54- joints [id ].append (df_cvt .cvt_rhmesh_2_dfmesh (face ))
52+ joints = [[] for _ in range (n_joints )]
53+ for joint in all_joints :
54+ for face in joint .faces :
55+ face = face .to_mesh ()
56+ face .Subdivide ()
57+ face .Faces .ConvertQuadsToTriangles ()
58+ joints [joint .id ].append (df_cvt .cvt_rhmesh_2_dfmesh (face ))
5559
5660 joint_clouds = []
57- registrations = []
61+ transforms = []
5862 joint_segments = []
5963 df_clouds = [df_cvt .cvt_rhcloud_2_dfcloud (cluster ) for cluster in i_clusters ]
6064
6165 # for each joint, find the corresponding clusters and merge them, generate a reference point cloud, and register the merged clusters to the reference point cloud
6266 for joint in joints :
63-
6467 # create the reference point cloud
6568 joint_cloud = diffcheck_bindings .dfb_geometry .DFPointCloud ()
6669
@@ -72,19 +75,29 @@ def RunScript(self,
7275
7376 # find the corresponding clusters and merge them
7477 segment = diffcheck_bindings .dfb_segmentation .DFSegmentation .associate_clusters (joint , df_clouds , i_angle_threshold , i_distance_threshold )
75- diffcheck_bindings .dfb_segmentation .DFSegmentation .clean_unassociated_clusters (df_clouds , [segment ], [joint ], i_angle_threshold , i_distance_threshold )
76-
78+ diffcheck_bindings .dfb_segmentation .DFSegmentation .clean_unassociated_clusters (df_clouds , [segment ], [joint ], i_angle_threshold , i_distance_threshold )
79+
7780 # register the merged clusters to the reference point cloud
7881 registration = diffcheck_bindings .dfb_registrations .DFRefinedRegistration .O3DICP (segment , joint_cloud )
7982 res = registration .transformation_matrix
80-
81- registrations .append (df_cvt .cvt_ndarray_2_rh_transform (res ))
83+ transforms .append (df_cvt .cvt_ndarray_2_rh_transform (res ))
8284 joint_segments .append (df_cvt .cvt_dfcloud_2_rhcloud (segment ))
83-
84- return joint_segments , registrations , joint_clouds
85+
86+ o_joint_segments = []
87+ o_transforms = []
88+ o_reference_point_clouds = []
89+ for joint_segment , transform , _joint_cloud in zip (joint_segments , transforms , joint_clouds ):
90+ if joint_segment .IsValid :
91+ o_joint_segments .append (joint_segment )
92+ o_transforms .append (transform )
93+ o_reference_point_clouds .append (_joint_cloud )
94+ else :
95+ ghenv .Component .AddRuntimeMessage (RML .Warning , "Some joints could not be segmented and were ignored." )
96+
97+ return o_joint_segments , o_transforms , o_reference_point_clouds
8598
8699# if __name__ == "__main__":
87- # o_joint_segments, o_reference_point_clouds, o_transforms = main(i_clusters, i_joints, i_joint_ids )
88-
100+ # comp = DFJointSegmentator( )
101+ # o_joint_segments, o_transforms, o_reference_point_clouds = comp.RunScript(i_clusters, i_assembly, i_angle_threshold, i_distance_threshold)
89102# for i in range(len(o_joint_segments)):
90103# o_joint_segments[i].Transform(o_transforms[i])
0 commit comments