Skip to content

Commit c575579

Browse files
FIX-CAP: various small fixes after code review
1 parent d2fa4c3 commit c575579

File tree

2 files changed

+94
-60
lines changed

2 files changed

+94
-60
lines changed
Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,90 @@
11
#! python3
22

33
import Rhino
4+
45
import diffCheck
56
from diffCheck import diffcheck_bindings
67
from diffCheck import df_cvt_bindings as df_cvt
78
import diffCheck.df_util
8-
import scriptcontext as sc
99

10-
ABSTOL = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance
10+
from ghpythonlib.componentbase import executingcomponent as component
1111

12-
def main(i_clusters, i_joints, i_joint_ids):
12+
ABSTOL = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance
1313

14-
if len(i_joints) != len(i_joint_ids):
15-
raise ValueError("The number of joints and joint ids must be the same.")
16-
17-
if len(i_clusters) == 0:
18-
raise ValueError("No clusters given.")
14+
class DFJointSegmentator(component):
15+
def RunScript(self,
16+
i_clusters: Rhino.Geometry.PointCloud,
17+
i_joints: Rhino.Geometry.Mesh,
18+
i_joint_ids: int,
19+
i_angle_threshold: float,
20+
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+
"""
32+
if i_angle_threshold is None : i_angle_threshold = 0.1
33+
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+
38+
if len(i_clusters) == 0:
39+
raise ValueError("No clusters given.")
1940

20-
if not isinstance(i_clusters[0], Rhino.Geometry.PointCloud):
21-
raise ValueError("The input clusters must be PointClouds.")
22-
23-
if not isinstance(i_joints[0], Rhino.Geometry.Mesh):
24-
raise ValueError("The input joints must be convertible to Meshes.")
41+
if not isinstance(i_clusters[0], Rhino.Geometry.PointCloud):
42+
raise ValueError("The input clusters must be PointClouds.")
2543

44+
if not isinstance(i_joints[0], Rhino.Geometry.Mesh):
45+
raise ValueError("The input joints must be convertible to Meshes.")
46+
2647

27-
# prepping the reference meshes
28-
n_joints = max(i_joint_ids) + 1
29-
joints = [ [] for i in range(n_joints) ]
30-
for face, id in zip(i_joints, i_joint_ids):
31-
face.Subdivide()
32-
face.Faces.ConvertQuadsToTriangles()
33-
joints[id].append(df_cvt.cvt_rhmesh_2_dfmesh(face))
48+
# 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))
3455

35-
joint_clouds = []
36-
registrations = []
37-
joint_segments = []
38-
df_clouds = [df_cvt.cvt_rhcloud_2_dfcloud(cluster) for cluster in i_clusters]
56+
joint_clouds = []
57+
registrations = []
58+
joint_segments = []
59+
df_clouds = [df_cvt.cvt_rhcloud_2_dfcloud(cluster) for cluster in i_clusters]
3960

40-
# 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
41-
for joint in joints:
61+
# 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:
4263

43-
# create the reference point cloud
44-
joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud()
64+
# create the reference point cloud
65+
joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud()
4566

46-
for face in joint:
47-
face_cloud = face.sample_points_uniformly(1000)
48-
joint_cloud.add_points(face_cloud)
67+
for face in joint:
68+
face_cloud = face.sample_points_uniformly(1000)
69+
joint_cloud.add_points(face_cloud)
4970

50-
joint_clouds.append(df_cvt.cvt_dfcloud_2_rhcloud(joint_cloud))
71+
joint_clouds.append(df_cvt.cvt_dfcloud_2_rhcloud(joint_cloud))
5172

52-
# find the corresponding clusters and merge them
53-
segment = diffcheck_bindings.dfb_segmentation.DFSegmentation.associate_clusters(joint, df_clouds )
54-
diffcheck_bindings.dfb_segmentation.DFSegmentation.clean_unassociated_clusters(df_clouds, [segment], [joint], 0.1, 0.02)
73+
# 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)
5576

56-
# register the merged clusters to the reference point cloud
57-
registration = diffcheck_bindings.dfb_registrations.DFRefinedRegistration.O3DICP(segment, joint_cloud)
58-
res = registration.transformation_matrix
77+
# register the merged clusters to the reference point cloud
78+
registration = diffcheck_bindings.dfb_registrations.DFRefinedRegistration.O3DICP(segment, joint_cloud)
79+
res = registration.transformation_matrix
5980

60-
registrations.append(df_cvt.cvt_ndarray_2_rh_transform(res))
61-
joint_segments.append(df_cvt.cvt_dfcloud_2_rhcloud(segment))
81+
registrations.append(df_cvt.cvt_ndarray_2_rh_transform(res))
82+
joint_segments.append(df_cvt.cvt_dfcloud_2_rhcloud(segment))
6283

63-
return joint_segments, joint_clouds, registrations
84+
return joint_segments, registrations, joint_clouds
6485

65-
if __name__ == "__main__":
66-
o_joint_segments, o_reference_point_clouds, o_transforms = main(i_clusters, i_joints, i_joint_ids)
86+
# if __name__ == "__main__":
87+
# o_joint_segments, o_reference_point_clouds, o_transforms = main(i_clusters, i_joints, i_joint_ids)
6788

68-
for i in range(len(o_joint_segments)):
69-
o_joint_segments[i].Transform(o_transforms[i])
89+
# for i in range(len(o_joint_segments)):
90+
# o_joint_segments[i].Transform(o_transforms[i])

src/gh/components/DF_joint_segmentator/metadata.json

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "Extract Joints",
3-
"nickname": "Extract Joints",
2+
"name": "DFJointSegmentator",
3+
"nickname": "DFJointSegmentator",
44
"category": "diffCheck",
55
"subcategory": "Segmentation",
66
"description": "Extracts the joints from a point cloud.",
@@ -13,18 +13,7 @@
1313
"marshalOutGuids": true,
1414
"iconDisplay": 2,
1515
"inputParameters": [
16-
{
17-
"name": "i_recompute",
18-
"nickname": "i_recompute",
19-
"description": "Connect a button to recompute the registration.",
20-
"optional": true,
21-
"allowListAccess": false,
22-
"showTypeHints": true,
23-
"scriptParamAccess": "item",
24-
"wireDisplay": "default",
25-
"sourceCount": 0,
26-
"typeHintID": "bool"
27-
},
16+
2817
{
2918
"name": "i_clusters",
3019
"nickname": "i_clusters",
@@ -39,7 +28,7 @@
3928
},
4029
{
4130
"name": "i_joint_faces",
42-
"nickname": "i_joints",
31+
"nickname": "i_joint_faces",
4332
"description": "The joints to extract and analyze",
4433
"optional": false,
4534
"allowTreeAccess": false,
@@ -60,6 +49,30 @@
6049
"wireDisplay": "default",
6150
"sourceCount": 0,
6251
"typeHintID": "int"
52+
},
53+
{
54+
"name": "i_angle_threshold",
55+
"nickname": "i_angle_threshold",
56+
"description": "From 0 to 1, it's the sin value. By default 0.1. The closer to 0 the less permissive and viceversa to 1.",
57+
"optional": true,
58+
"allowTreeAccess": true,
59+
"showTypeHints": true,
60+
"scriptParamAccess": "item",
61+
"wireDisplay": "default",
62+
"sourceCount": 0,
63+
"typeHintID": "float"
64+
},
65+
{
66+
"name": "i_association_threshold",
67+
"nickname": "i_association_threshold",
68+
"description": "From 0 to infinite. By default 0.1. The closer to 0 the less permissive your point.",
69+
"optional": true,
70+
"allowTreeAccess": true,
71+
"showTypeHints": true,
72+
"scriptParamAccess": "item",
73+
"wireDisplay": "default",
74+
"sourceCount": 0,
75+
"typeHintID": "float"
6376
}
6477
],
6578
"outputParameters": [

0 commit comments

Comments
 (0)