|
| 1 | +#! python3 |
| 2 | + |
| 3 | +from diffCheck import df_cvt_bindings |
| 4 | +from diffCheck import df_poses |
| 5 | + |
| 6 | +import Rhino |
| 7 | +from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML |
| 8 | + |
| 9 | +from ghpythonlib.componentbase import executingcomponent as component |
| 10 | +import System |
| 11 | + |
| 12 | + |
| 13 | +class DFPoseEstimation(component): |
| 14 | + def RunScript(self, |
| 15 | + i_clouds: System.Collections.Generic.List[Rhino.Geometry.PointCloud], |
| 16 | + i_assembly, |
| 17 | + i_save: bool, |
| 18 | + i_reset: bool): |
| 19 | + |
| 20 | + # ensure assembly has enough beams |
| 21 | + if len(i_assembly.beams) < len(i_clouds): |
| 22 | + ghenv.Component.AddRuntimeMessage(RML.Warning, "Assembly has fewer beams than input clouds") # noqa: F821 |
| 23 | + return None, None |
| 24 | + |
| 25 | + planes = [] |
| 26 | + all_poses_in_time = df_poses.DFPosesAssembly() |
| 27 | + if i_reset: |
| 28 | + all_poses_in_time.reset() |
| 29 | + return None, None |
| 30 | + |
| 31 | + all_poses_this_time = [] |
| 32 | + for i, cloud in enumerate(i_clouds): |
| 33 | + try: |
| 34 | + df_cloud = df_cvt_bindings.cvt_rhcloud_2_dfcloud(cloud) |
| 35 | + if df_cloud is None: |
| 36 | + return None, None |
| 37 | + if not df_cloud.has_normals(): |
| 38 | + ghenv.Component.AddRuntimeMessage(RML.Error, f"Point cloud {i} has no normals. Please compute the normals.") # noqa: F821 |
| 39 | + |
| 40 | + df_points = df_cloud.get_axis_aligned_bounding_box() |
| 41 | + df_point = (df_points[0] + df_points[1]) / 2 |
| 42 | + rh_point = Rhino.Geometry.Point3d(df_point[0], df_point[1], df_point[2]) |
| 43 | + |
| 44 | + axes = df_cloud.get_principal_axes(3) |
| 45 | + vectors = [] |
| 46 | + for axe in axes: |
| 47 | + vectors.append(Rhino.Geometry.Vector3d(axe[0], axe[1], axe[2])) |
| 48 | + |
| 49 | + new_xDirection, new_yDirection = df_poses.select_vectors(vectors, i_assembly.beams[i].plane.XAxis, i_assembly.beams[i].plane.YAxis) |
| 50 | + |
| 51 | + pose = df_poses.DFPose( |
| 52 | + origin = [rh_point.X, rh_point.Y, rh_point.Z], |
| 53 | + xDirection = [new_xDirection.X, new_xDirection.Y, new_xDirection.Z], |
| 54 | + yDirection = [new_yDirection.X, new_yDirection.Y, new_yDirection.Z]) |
| 55 | + all_poses_this_time.append(pose) |
| 56 | + plane = Rhino.Geometry.Plane(origin = rh_point, xDirection=new_xDirection, yDirection=new_yDirection) |
| 57 | + planes.append(plane) |
| 58 | + except Exception as e: |
| 59 | + # Any unexpected error on this cloud, skip it and keep going |
| 60 | + ghenv.Component.AddRuntimeMessage(RML.Error, f"Cloud {i}: processing failed ({e}); skipping.") # noqa: F821 |
| 61 | + planes.append(None) |
| 62 | + all_poses_this_time.append(None) |
| 63 | + continue |
| 64 | + |
| 65 | + if i_save: |
| 66 | + all_poses_in_time.add_step(all_poses_this_time) |
| 67 | + |
| 68 | + return [planes, all_poses_in_time.to_gh_tree()] |
0 commit comments