Skip to content

Commit 039d6d0

Browse files
DF_Joint_segmentator refactored with DF_Assembly
1 parent b379924 commit 039d6d0

File tree

3 files changed

+52
-49
lines changed

3 files changed

+52
-49
lines changed

src/gh/components/DF_joint_segmentator/code.py

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@
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):
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])

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: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -422,18 +422,21 @@ def dump_xml(self, pretty_xml: str, dir: str):
422422

423423
@property
424424
def all_joint_faces(self):
425-
for beam in self.beams:
426-
self._all_jointfaces.extend(beam.joint_faces)
425+
if len(self._all_jointfaces) == 0:
426+
for beam in self.beams:
427+
self._all_jointfaces.extend(beam.joint_faces)
427428
return self._all_jointfaces
428429

429430
@property
430431
def all_side_faces(self):
431-
for beam in self.beams:
432-
self._all_sidefaces.extend(beam.side_faces)
432+
if len(self._all_sidefaces) == 0:
433+
for beam in self.beams:
434+
self._all_sidefaces.extend(beam.side_faces)
433435
return self._all_sidefaces
434436

435437
@property
436438
def all_joints(self):
437-
for beam in self.beams:
438-
self._all_joints.extend(beam.joints)
439+
if len(self._all_joints) == 0:
440+
for beam in self.beams:
441+
self._all_joints.extend(beam.joints)
439442
return self._all_joints

0 commit comments

Comments
 (0)