Skip to content

Commit 8ba24c1

Browse files
authored
Merge pull request #61 from diffCheckOrg/substractive_segmentation_with_DFAssembly
refactoring segmentations with DFAsssembly
2 parents f462abe + c01955f commit 8ba24c1

File tree

4 files changed

+74
-76
lines changed

4 files changed

+74
-76
lines changed

src/gh/components/DF_CAD_segmentator/code.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def RunScript(self,
3838
o_clusters = []
3939
# the df cloud clusters
4040
df_clusters = []
41-
# we make a deepcopy of the input clouds because
41+
# we make a deepcopy of the input clouds
4242
df_clouds = [df_cvt_bindings.cvt_rhcloud_2_dfcloud(cloud.Duplicate()) for cloud in i_clouds]
4343

4444
df_beams = i_assembly.beams
@@ -73,11 +73,11 @@ def RunScript(self,
7373

7474
return o_clusters, rh_beams_meshes
7575

76-
if __name__ == "__main__":
77-
com = DFCADSegmentator()
78-
o_clusters, rh_beams_meshes = com.RunScript(
79-
i_clouds,
80-
i_assembly,
81-
i_angle_threshold,
82-
i_association_threshold
83-
)
76+
# if __name__ == "__main__":
77+
# com = DFCADSegmentator()
78+
# o_clusters, rh_beams_meshes = com.RunScript(
79+
# i_clouds,
80+
# i_assembly,
81+
# i_angle_threshold,
82+
# i_association_threshold
83+
# )

src/gh/components/DF_joint_segmentator/code.py

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,84 +7,84 @@
77
from diffCheck import df_cvt_bindings as df_cvt
88
import diffCheck.df_util
99

10+
from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML
1011
from ghpythonlib.componentbase import executingcomponent as component
1112

13+
import typing
14+
1215
ABSTOL = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance
1316

1417
class 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):
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+
3226
if i_angle_threshold is None : i_angle_threshold = 0.1
3327
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.")
3728

3829
if len(i_clusters) == 0:
3930
raise ValueError("No clusters given.")
4031

4132
if not isinstance(i_clusters[0], Rhino.Geometry.PointCloud):
4233
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.")
4634

35+
# get number of joints
36+
n_joints = i_assembly.total_number_joints
4737

4838
# 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]
6051

6152
# 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:
6454
# create the reference point cloud
65-
joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud()
55+
ref_df_joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud()
6656

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)
7060

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))
7262

7363
# 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+
7767
# 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)
7969
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
8585

8686
# 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)
8989
# for i in range(len(o_joint_segments)):
9090
# o_joint_segments[i].Transform(o_transforms[i])

src/gh/components/DF_joint_segmentator/metadata.json

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"marshalOutGuids": true,
1414
"iconDisplay": 2,
1515
"inputParameters": [
16-
1716
{
1817
"name": "i_clusters",
1918
"nickname": "i_clusters",
@@ -27,28 +26,16 @@
2726
"typeHintID": "pointcloud"
2827
},
2928
{
30-
"name": "i_joint_faces",
31-
"nickname": "i_joint_faces",
32-
"description": "The joints to extract and analyze",
29+
"name": "i_assembly",
30+
"nickname": "i_assembly",
31+
"description": "The assembly to extract the joints from",
3332
"optional": false,
3433
"allowTreeAccess": false,
3534
"showTypeHints": true,
36-
"scriptParamAccess": "list",
37-
"wireDisplay": "default",
38-
"sourceCount": 0,
39-
"typeHintID": "mesh"
40-
},
41-
{
42-
"name": "i_joint_ids",
43-
"nickname": "i_joint_ids",
44-
"description": "The joint ids of the assembly",
45-
"optional": false,
46-
"allowTreeAccess": true,
47-
"showTypeHints": true,
48-
"scriptParamAccess": "list",
35+
"scriptParamAccess": "item",
4936
"wireDisplay": "default",
5037
"sourceCount": 0,
51-
"typeHintID": "int"
38+
"typeHintID": "ghdoc"
5239
},
5340
{
5441
"name": "i_angle_threshold",

src/gh/diffCheck/diffCheck/df_geometries.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,10 @@ def __repr__(self):
313313
def id(self):
314314
return self.__id
315315

316+
@property
317+
def number_joints(self):
318+
return max([joint.id for joint in self.joints]) + 1
319+
316320
@property
317321
def joint_faces(self):
318322
return [face for face in self.faces if face.is_joint]
@@ -420,20 +424,27 @@ def dump_xml(self, pretty_xml: str, dir: str):
420424
with open(file_path, "w") as f:
421425
f.write(pretty_xml)
422426

427+
@property
428+
def total_number_joints(self):
429+
return max([joint.id for joint in self.all_joints]) + 1
430+
423431
@property
424432
def all_joint_faces(self):
433+
self._all_jointfaces = []
425434
for beam in self.beams:
426435
self._all_jointfaces.extend(beam.joint_faces)
427436
return self._all_jointfaces
428437

429438
@property
430439
def all_side_faces(self):
440+
self._all_sidefaces = []
431441
for beam in self.beams:
432442
self._all_sidefaces.extend(beam.side_faces)
433443
return self._all_sidefaces
434444

435445
@property
436446
def all_joints(self):
447+
self._all_joints = []
437448
for beam in self.beams:
438449
self._all_joints.extend(beam.joints)
439450
return self._all_joints

0 commit comments

Comments
 (0)