|
7 | 7 | from diffCheck import df_cvt_bindings as df_cvt |
8 | 8 | import diffCheck.df_util |
9 | 9 |
|
| 10 | +from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML |
10 | 11 | from ghpythonlib.componentbase import executingcomponent as component |
11 | 12 |
|
| 13 | +import typing |
| 14 | + |
12 | 15 | ABSTOL = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance |
13 | 16 |
|
14 | 17 | class DFJointSegmentator(component): |
| 18 | + def __init__(self): |
| 19 | + super(DFJointSegmentator, self).__init__() |
15 | 20 | 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, |
19 | 23 | i_angle_threshold: float, |
20 | 24 | i_distance_threshold: float): |
21 | | - """ |
22 | | - Amongst clusters, associates the clusters to the individual joints, |
23 | | - creates a reference point cloud for each joint, |
24 | | - and returns the joint segments, the reference point clouds, and the ICP transformations from the first to the second. |
25 | | -
|
26 | | - :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. |
29 | | - :param i_angle_threshold: The angle threshold for the association of the clusters to the joints. |
30 | | - :param i_distance_threshold: The distance threshold for the association of the clusters to the joints. |
31 | | - """ |
| 25 | + |
32 | 26 | if i_angle_threshold is None : i_angle_threshold = 0.1 |
33 | 27 | 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.") |
37 | 28 |
|
38 | 29 | if len(i_clusters) == 0: |
39 | 30 | raise ValueError("No clusters given.") |
40 | 31 |
|
41 | 32 | if not isinstance(i_clusters[0], Rhino.Geometry.PointCloud): |
42 | 33 | raise ValueError("The input clusters must be PointClouds.") |
43 | | - |
44 | | - if not isinstance(i_joints[0], Rhino.Geometry.Mesh): |
45 | | - raise ValueError("The input joints must be convertible to Meshes.") |
46 | 34 |
|
| 35 | + # get number of joints |
| 36 | + n_joints = i_assembly.total_number_joints |
47 | 37 |
|
48 | 38 | # 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)) |
55 | | - |
56 | | - joint_clouds = [] |
57 | | - registrations = [] |
58 | | - joint_segments = [] |
59 | | - df_clouds = [df_cvt.cvt_rhcloud_2_dfcloud(cluster) for cluster in i_clusters] |
| 39 | + df_joints = [[] for _ in range(n_joints)] |
| 40 | + for joint in i_assembly.all_joints: |
| 41 | + for face in joint.faces: |
| 42 | + face = face.to_mesh() |
| 43 | + face.Subdivide() |
| 44 | + face.Faces.ConvertQuadsToTriangles() |
| 45 | + df_joints[joint.id].append(df_cvt.cvt_rhmesh_2_dfmesh(face)) |
| 46 | + |
| 47 | + ref_rh_joint_clouds = [] |
| 48 | + transforms = [] |
| 49 | + rh_joint_segments = [] |
| 50 | + df_cloud_clusters = [df_cvt.cvt_rhcloud_2_dfcloud(cluster) for cluster in i_clusters] |
60 | 51 |
|
61 | 52 | # 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 |
62 | | - for joint in joints: |
63 | | - |
| 53 | + for df_joint in df_joints: |
64 | 54 | # create the reference point cloud |
65 | | - joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud() |
| 55 | + ref_df_joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud() |
66 | 56 |
|
67 | | - for face in joint: |
68 | | - face_cloud = face.sample_points_uniformly(1000) |
69 | | - joint_cloud.add_points(face_cloud) |
| 57 | + for face in df_joint: |
| 58 | + ref_face_cloud = face.sample_points_uniformly(1000) |
| 59 | + ref_df_joint_cloud.add_points(ref_face_cloud) |
70 | 60 |
|
71 | | - joint_clouds.append(df_cvt.cvt_dfcloud_2_rhcloud(joint_cloud)) |
| 61 | + ref_rh_joint_clouds.append(df_cvt.cvt_dfcloud_2_rhcloud(ref_df_joint_cloud)) |
72 | 62 |
|
73 | 63 | # find the corresponding clusters and merge them |
74 | | - 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 | | - |
| 64 | + df_joint_segment = diffcheck_bindings.dfb_segmentation.DFSegmentation.associate_clusters(df_joint, df_cloud_clusters, i_angle_threshold, i_distance_threshold) |
| 65 | + diffcheck_bindings.dfb_segmentation.DFSegmentation.clean_unassociated_clusters(df_cloud_clusters, [df_joint_segment], [df_joint], i_angle_threshold, i_distance_threshold) |
| 66 | + |
77 | 67 | # register the merged clusters to the reference point cloud |
78 | | - registration = diffcheck_bindings.dfb_registrations.DFRefinedRegistration.O3DICP(segment, joint_cloud) |
| 68 | + registration = diffcheck_bindings.dfb_registrations.DFRefinedRegistration.O3DICP(df_joint_segment, ref_df_joint_cloud) |
79 | 69 | res = registration.transformation_matrix |
80 | | - |
81 | | - registrations.append(df_cvt.cvt_ndarray_2_rh_transform(res)) |
82 | | - joint_segments.append(df_cvt.cvt_dfcloud_2_rhcloud(segment)) |
83 | | - |
84 | | - return joint_segments, registrations, joint_clouds |
| 70 | + transforms.append(df_cvt.cvt_ndarray_2_rh_transform(res)) |
| 71 | + rh_joint_segments.append(df_cvt.cvt_dfcloud_2_rhcloud(df_joint_segment)) |
| 72 | + |
| 73 | + o_joint_segments = [] |
| 74 | + o_transforms = [] |
| 75 | + o_reference_point_clouds = [] |
| 76 | + for joint_segment, transform, _joint_cloud in zip(rh_joint_segments, transforms, ref_rh_joint_clouds): |
| 77 | + if joint_segment.IsValid: |
| 78 | + o_joint_segments.append(joint_segment) |
| 79 | + o_transforms.append(transform) |
| 80 | + o_reference_point_clouds.append(_joint_cloud) |
| 81 | + else: |
| 82 | + ghenv.Component.AddRuntimeMessage(RML.Warning, "Some joints could not be segmented and were ignored.") |
| 83 | + |
| 84 | + return o_joint_segments, o_transforms, o_reference_point_clouds |
85 | 85 |
|
86 | 86 | # if __name__ == "__main__": |
87 | | -# o_joint_segments, o_reference_point_clouds, o_transforms = main(i_clusters, i_joints, i_joint_ids) |
88 | | - |
| 87 | +# comp = DFJointSegmentator() |
| 88 | +# o_joint_segments, o_transforms, o_reference_point_clouds = comp.RunScript(i_clusters, i_assembly, i_angle_threshold, i_distance_threshold) |
89 | 89 | # for i in range(len(o_joint_segments)): |
90 | 90 | # o_joint_segments[i].Transform(o_transforms[i]) |
0 commit comments