Skip to content

Commit 4d5c71b

Browse files
feat-wip: add code to main axis calculation component. OK but reliability will be improved
1 parent ad8e895 commit 4d5c71b

File tree

1 file changed

+89
-0
lines changed
  • src/gh/components/DF_main_pc_axes

1 file changed

+89
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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

Comments
 (0)