Skip to content

Commit e8c2670

Browse files
feat: add input parameter i_poses_from_icp to accept poses detected ad CAD segmentation step
1 parent 59a2a33 commit e8c2670

2 files changed

Lines changed: 54 additions & 34 deletions

File tree

src/gh/components/DF_pose_estimation/code.py

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class DFPoseEstimation(component):
1717
def RunScript(self,
1818
i_face_clouds: Grasshopper.DataTree[Rhino.Geometry.PointCloud],
1919
i_assembly,
20+
i_poses_from_icp: list,
2021
i_reset: bool,
2122
i_save: bool):
2223

@@ -35,40 +36,47 @@ def RunScript(self,
3536
all_poses_this_time = []
3637
for i, face_clouds in enumerate(clusters_per_beam):
3738
try:
38-
df_cloud = dfb_geometry.DFPointCloud()
39-
40-
rh_face_normals = []
41-
for face_cloud in face_clouds:
42-
df_face_cloud = df_cvt_bindings.cvt_rhcloud_2_dfcloud(face_cloud)
43-
df_cloud.add_points(df_face_cloud)
44-
plane_normal = df_face_cloud.fit_plane_ransac()
45-
if all(plane_normal) == 0:
46-
ghenv.Component.AddRuntimeMessage(RML.Warning, f"There was a missing face in the cloud of beam {i}: the face was skipped in the pose estimation of that beam") # noqa: F821
47-
continue
48-
rh_face_normals.append(Rhino.Geometry.Vector3d(plane_normal[0], plane_normal[1], plane_normal[2]))
49-
50-
df_bb_points = df_cloud.get_tight_bounding_box()
51-
df_bb_centroid = sum(df_bb_points)/len(df_bb_points)
52-
rh_tentative_bb_centroid = Rhino.Geometry.Point3d(df_bb_centroid[0], df_bb_centroid[1], df_bb_centroid[2])
53-
54-
new_xDirection, new_yDirection = df_poses.select_vectors(rh_face_normals, i_assembly.beams[i].plane.XAxis, i_assembly.beams[i].plane.YAxis)
55-
rh_tentative_plane = Rhino.Geometry.Plane(rh_tentative_bb_centroid, new_xDirection, new_yDirection)
56-
57-
rh_beam_cloud = Rhino.Geometry.PointCloud()
58-
for face_cloud in face_clouds:
59-
rh_beam_cloud.Merge(face_cloud)
60-
61-
rh_bbox = rh_beam_cloud.GetBoundingBox(rh_tentative_plane)
62-
rh_bbox.Transform(Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY, rh_tentative_plane))
63-
rh_bb_centroid = rh_bbox.Center
64-
65-
pose = df_poses.DFPose(
66-
origin = [rh_bb_centroid.X, rh_bb_centroid.Y, rh_bb_centroid.Z],
67-
xDirection = [new_xDirection.X, new_xDirection.Y, new_xDirection.Z],
68-
yDirection = [new_yDirection.X, new_yDirection.Y, new_yDirection.Z])
69-
all_poses_this_time.append(pose)
70-
plane = Rhino.Geometry.Plane(origin = rh_bb_centroid, xDirection=new_xDirection, yDirection=new_yDirection)
71-
planes.append(plane)
39+
if len(i_poses_from_icp) > i and i_poses_from_icp[i] is not None:
40+
# if there is a pose from ICP for this beam, use it directly without processing the cloud
41+
planes.append(i_poses_from_icp[i])
42+
all_poses_this_time.append(df_poses.DFPose.from_rh_plane(i_poses_from_icp[i]))
43+
continue
44+
45+
else:
46+
df_cloud = dfb_geometry.DFPointCloud()
47+
48+
rh_face_normals = []
49+
for face_cloud in face_clouds:
50+
df_face_cloud = df_cvt_bindings.cvt_rhcloud_2_dfcloud(face_cloud)
51+
df_cloud.add_points(df_face_cloud)
52+
plane_normal = df_face_cloud.fit_plane_ransac()
53+
if all(plane_normal) == 0:
54+
ghenv.Component.AddRuntimeMessage(RML.Warning, f"There was a missing face in the cloud of beam {i}: the face was skipped in the pose estimation of that beam") # noqa: F821
55+
continue
56+
rh_face_normals.append(Rhino.Geometry.Vector3d(plane_normal[0], plane_normal[1], plane_normal[2]))
57+
58+
df_bb_points = df_cloud.get_tight_bounding_box()
59+
df_bb_centroid = sum(df_bb_points)/len(df_bb_points)
60+
rh_tentative_bb_centroid = Rhino.Geometry.Point3d(df_bb_centroid[0], df_bb_centroid[1], df_bb_centroid[2])
61+
62+
new_xDirection, new_yDirection = df_poses.select_vectors(rh_face_normals, i_assembly.beams[i].plane.XAxis, i_assembly.beams[i].plane.YAxis)
63+
rh_tentative_plane = Rhino.Geometry.Plane(rh_tentative_bb_centroid, new_xDirection, new_yDirection)
64+
65+
rh_beam_cloud = Rhino.Geometry.PointCloud()
66+
for face_cloud in face_clouds:
67+
rh_beam_cloud.Merge(face_cloud)
68+
69+
rh_bbox = rh_beam_cloud.GetBoundingBox(rh_tentative_plane)
70+
rh_bbox.Transform(Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY, rh_tentative_plane))
71+
rh_bb_centroid = rh_bbox.Center
72+
73+
pose = df_poses.DFPose(
74+
origin = [rh_bb_centroid.X, rh_bb_centroid.Y, rh_bb_centroid.Z],
75+
xDirection = [new_xDirection.X, new_xDirection.Y, new_xDirection.Z],
76+
yDirection = [new_yDirection.X, new_yDirection.Y, new_yDirection.Z])
77+
all_poses_this_time.append(pose)
78+
plane = Rhino.Geometry.Plane(origin = rh_bb_centroid, xDirection=new_xDirection, yDirection=new_yDirection)
79+
planes.append(plane)
7280

7381
except Exception as e:
7482
# Any unexpected error on this cloud, skip it and keep going

src/gh/components/DF_pose_estimation/metadata.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@
3737
"sourceCount": 0,
3838
"typeHintID": "ghdoc"
3939
},
40+
{
41+
"name": "i_poses_from_icp",
42+
"nickname": "i_poses_from_icp",
43+
"description": "The optional poses detected in the CAD segmentation component though ICP. If provided, the pose will not be re-calculated using the faces normals.",
44+
"optional": true,
45+
"allowTreeAccess": true,
46+
"showTypeHints": true,
47+
"scriptParamAccess": "list",
48+
"wireDisplay": "default",
49+
"sourceCount": 0,
50+
"typeHintID": "ghdoc"
51+
},
4052
{
4153
"name": "i_reset",
4254
"nickname": "i_reset",

0 commit comments

Comments
 (0)