Skip to content

Commit e0e314c

Browse files
feat-fix: pose comparison takes (or converts to) data tree as input and detects if list or history is passed
1 parent 6660ecb commit e0e314c

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

src/gh/components/DF_pose_comparison/code.py

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,35 @@
22
#! python3
33

44
import Rhino
5+
import Grasshopper
56
from ghpythonlib.componentbase import executingcomponent as component
6-
7-
import System
7+
import ghpythonlib.treehelpers as th
88

99
import diffCheck.df_geometries
1010
import numpy
1111

12+
def compute_comparison(measured_pose, cad_pose):
13+
cad_origin = cad_pose.Origin
14+
measured_origin = measured_pose.Origin
15+
distance = cad_origin.DistanceTo(measured_origin)
16+
17+
# Compare the orientations using the formula: $$ \theta = \arccos\left(\frac{\text{trace}(R_{\text{pred}}^T R_{\text{meas}}) - 1}{2}\right) $$
18+
transform_o_to_cad = Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY, cad_pose)
19+
transform_o_to_measured = Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY, measured_pose)
20+
np_transform_o_to_cad = numpy.array(transform_o_to_cad.ToDoubleArray(rowDominant=True)).reshape((4, 4))
21+
np_transform_o_to_measured = numpy.array(transform_o_to_measured.ToDoubleArray(rowDominant=True)).reshape((4, 4))
22+
23+
R_cad = np_transform_o_to_cad[:3, :3]
24+
R_measured = np_transform_o_to_measured[:3, :3]
25+
R_rel = numpy.dot(R_cad.T, R_measured)
26+
theta = numpy.arccos(numpy.clip((numpy.trace(R_rel) - 1) / 2, -1.0, 1.0))
27+
28+
# Compute the transformation matrix between the CAD pose and the measured pose
29+
transform_cad_to_measured = Rhino.Geometry.Transform.PlaneToPlane(cad_pose, measured_pose)
30+
return distance, theta, transform_cad_to_measured
1231

1332
class DFPoseComparison(component):
14-
def RunScript(self,
15-
i_assembly: diffCheck.df_geometries.DFAssembly,
16-
i_measured_planes: System.Collections.Generic.List[object]):
33+
def RunScript(self, i_assembly: diffCheck.df_geometries.DFAssembly, i_measured_planes: Grasshopper.DataTree[object]):
1734

1835
CAD_poses = [beam.plane for beam in i_assembly.beams]
1936

@@ -22,31 +39,35 @@ def RunScript(self,
2239
o_transforms_cad_to_measured = []
2340
# Compare the origins
2441
# measure the distance between the origins of the CAD pose and the measured pose and output this in the component
25-
for i in range(len(i_measured_planes)):
26-
if not i_measured_planes[i]:
27-
o_distances.append(None)
28-
o_angles.append(None)
29-
o_transforms_cad_to_measured.append(None)
30-
continue
31-
cad_origin = CAD_poses[i].Origin
32-
measured_origin = i_measured_planes[i].Origin
33-
distance = cad_origin.DistanceTo(measured_origin)
34-
o_distances.append(distance)
35-
36-
# Compare the orientations using the formula: $$ \theta = \arccos\left(\frac{\text{trace}(R_{\text{pred}}^T R_{\text{meas}}) - 1}{2}\right) $$
37-
transform_o_to_cad = Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY, CAD_poses[i])
38-
transform_o_to_measured = Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY, i_measured_planes[i])
39-
np_transform_o_to_cad = numpy.array(transform_o_to_cad.ToDoubleArray(rowDominant=True)).reshape((4, 4))
40-
np_transform_o_to_measured = numpy.array(transform_o_to_measured.ToDoubleArray(rowDominant=True)).reshape((4, 4))
41-
42-
R_cad = np_transform_o_to_cad[:3, :3]
43-
R_measured = np_transform_o_to_measured[:3, :3]
44-
R_rel = numpy.dot(R_cad.T, R_measured)
45-
theta = numpy.arccos(numpy.clip((numpy.trace(R_rel) - 1) / 2, -1.0, 1.0))
46-
o_angles.append(theta)
47-
48-
# Compute the transformation matrix between the CAD pose and the measured pose
49-
transform_cad_to_measured = Rhino.Geometry.Transform.PlaneToPlane(CAD_poses[i], i_measured_planes[i])
50-
o_transforms_cad_to_measured.append(transform_cad_to_measured)
51-
52-
return [o_distances, o_angles, o_transforms_cad_to_measured]
42+
43+
bc = i_measured_planes.BranchCount
44+
if bc > 1:
45+
poses_per_beam = i_measured_planes.Branches
46+
for beam_id, poses in enumerate(poses_per_beam):
47+
o_distances.append(bc * [])
48+
o_angles.append(bc * [])
49+
o_transforms_cad_to_measured.append(bc * [])
50+
for pose in poses:
51+
if not pose:
52+
o_distances[beam_id].append(None)
53+
o_angles[beam_id].append(None)
54+
o_transforms_cad_to_measured[beam_id].append(None)
55+
else:
56+
dist, angle, transform_cad_to_measured = compute_comparison(pose, CAD_poses[beam_id])
57+
o_distances[beam_id].append(dist)
58+
o_angles[beam_id].append(angle)
59+
o_transforms_cad_to_measured[beam_id].append(transform_cad_to_measured)
60+
else:
61+
i_measured_planes.Flatten()
62+
measured_plane_list = th.tree_to_list(i_measured_planes)
63+
print(measured_plane_list)
64+
for i, plane in enumerate(measured_plane_list):
65+
dist, angle, transform_cad_to_measured = compute_comparison(plane, CAD_poses[i])
66+
o_distances.append(dist)
67+
o_angles.append(angle)
68+
o_transforms_cad_to_measured.append(transform_cad_to_measured)
69+
70+
if bc == 1:
71+
return o_distances, o_angles, o_transforms_cad_to_measured
72+
else:
73+
return th.list_to_tree(o_distances), th.list_to_tree(o_angles), th.list_to_tree(o_transforms_cad_to_measured)

src/gh/components/DF_pose_comparison/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"optional": false,
3333
"allowTreeAccess": true,
3434
"showTypeHints": true,
35-
"scriptParamAccess": "list",
35+
"scriptParamAccess": "tree",
3636
"wireDisplay": "default",
3737
"sourceCount": 0
3838
}

0 commit comments

Comments
 (0)