|
| 1 | +#! python3 |
| 2 | + |
| 3 | +from diffCheck import diffcheck_bindings |
| 4 | +from diffCheck import df_cvt_bindings |
| 5 | +from diffCheck import df_poses |
| 6 | + |
| 7 | +import Rhino |
| 8 | + |
| 9 | +from ghpythonlib.componentbase import executingcomponent as component |
| 10 | +# from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML |
| 11 | + |
| 12 | +import System |
| 13 | + |
| 14 | +def compute_dot_product(v1, v2): |
| 15 | + """ |
| 16 | + Compute the dot product of two vectors. |
| 17 | + """ |
| 18 | + return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z |
| 19 | + |
| 20 | +class DFMainPCAxes(component): |
| 21 | + def RunScript(self, |
| 22 | + i_clouds: System.Collections.Generic.List[Rhino.Geometry.PointCloud], |
| 23 | + i_file_name: str, |
| 24 | + reset: bool) -> System.Collections.Generic.IList[Rhino.Geometry.Vector3d]: |
| 25 | + |
| 26 | + planes = [] |
| 27 | + all_poses_in_time = df_poses.DFPosesAssembly() |
| 28 | + if reset: |
| 29 | + all_poses_in_time.reset() |
| 30 | + return None, None |
| 31 | + |
| 32 | + previous_poses = all_poses_in_time.get_last_poses() |
| 33 | + all_poses_this_time = [] |
| 34 | + for i, cloud in enumerate(i_clouds): |
| 35 | + df_cloud = df_cvt_bindings.cvt_rhcloud_2_dfcloud(cloud) |
| 36 | + if df_cloud is None: |
| 37 | + return None, None |
| 38 | + df_cloud.estimate_normals(True, 12) |
| 39 | + |
| 40 | + # hint = df_cvt_bindings.cvt_dfcloud_2_rhcloud(df_cloud) |
| 41 | + df_points = df_cloud.get_axis_aligned_bounding_box() |
| 42 | + df_point = (df_points[0] + df_points[1]) / 2 |
| 43 | + rh_point = Rhino.Geometry.Point3d(df_point[0], df_point[1], df_point[2]) |
| 44 | + vectors = [] |
| 45 | + # Get the main axes of the point cloud |
| 46 | + previous_pose = previous_poses[i] if previous_poses else None |
| 47 | + if previous_pose: |
| 48 | + rh_previous_xDirection = Rhino.Geometry.Vector3d(previous_pose.xDirection[0], previous_pose.xDirection[1], previous_pose.xDirection[2]) |
| 49 | + rh_previous_yDirection = Rhino.Geometry.Vector3d(previous_pose.yDirection[0], previous_pose.yDirection[1], previous_pose.yDirection[2]) |
| 50 | + n_faces = len(diffcheck_bindings.dfb_segmentation.DFSegmentation.segment_by_normal(df_cloud, 12, int(len(df_cloud.points)/20), True, int(len(df_cloud.points)/200), 1)) |
| 51 | + axes = df_cloud.get_principal_axes(n_faces) |
| 52 | + for axe in axes: |
| 53 | + vectors.append(Rhino.Geometry.Vector3d(axe[0], axe[1], axe[2])) |
| 54 | + if previous_pose: |
| 55 | + # Sort the vectors by their alignment with the previous xDirection and yDirection |
| 56 | + sorted_vectors_by_alignment = sorted(vectors, key=lambda v: compute_dot_product(v, rh_previous_xDirection), reverse=True) |
| 57 | + sorted_vectors_by_perpendicularity = sorted(vectors, key=lambda v: compute_dot_product(v, rh_previous_yDirection), reverse=True) |
| 58 | + new_xDirection = sorted_vectors_by_alignment[0] |
| 59 | + new_yDirection = sorted_vectors_by_perpendicularity[0] #- compute_dot_product(sorted_vectors_by_perpendicularity[0], new_xDirection) * new_xDirection |
| 60 | + new_yDirection.Unitize() |
| 61 | + else: |
| 62 | + # If no previous pose, just use the first two vectors as x and y directions |
| 63 | + new_xDirection = vectors[0] |
| 64 | + new_yDirection = vectors[1] #- compute_dot_product(vectors[1], new_xDirection) * new_xDirection |
| 65 | + new_yDirection.Unitize() |
| 66 | + |
| 67 | + print(new_xDirection) |
| 68 | + print(new_yDirection) |
| 69 | + |
| 70 | + pose = df_poses.DFPose( |
| 71 | + origin = [rh_point.X, rh_point.Y, rh_point.Z], |
| 72 | + xDirection = [new_xDirection.X, new_xDirection.Y, new_xDirection.Z], |
| 73 | + yDirection = [new_yDirection.X, new_yDirection.Y, new_yDirection.Z]) |
| 74 | + all_poses_this_time.append(pose) |
| 75 | + plane = Rhino.Geometry.Plane(origin = rh_point, xDirection=new_xDirection, yDirection=new_yDirection) |
| 76 | + planes.append(plane) |
| 77 | + |
| 78 | + all_poses_in_time.add_step(all_poses_this_time) |
| 79 | + |
| 80 | + return planes, all_poses_in_time.poses_per_element_dictionary |
| 81 | + |
| 82 | + |
| 83 | +# if __name__ == "__main__": |
| 84 | +# i_file_name = "C:/Users/localuser/test_file_poses.json" |
| 85 | +# component = DFMainPCAxes() |
| 86 | +# if reset == None: # noqa: E711 |
| 87 | +# reset = False |
| 88 | + |
| 89 | +# a, dico = component.RunScript(x, i_file_name, reset) # noqa: F821 |
0 commit comments