diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19259eb..30895fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,9 @@
# Changelog
-## Unreleased
+## 2020-12-18 - 1.0.1
### Added
-
-### Changed
-
-### Removed
-
+* Moved MeasurementPoint from grasshopper document to `compas_mobile_robot_reloc.utils`.
## 2020-12-18 - 1.0.0
diff --git a/grasshopper/robot_localization.ghx b/grasshopper/robot_localization.ghx
index 9c0aa84..bd59c9f 100644
--- a/grasshopper/robot_localization.ghx
+++ b/grasshopper/robot_localization.ghx
@@ -69,10 +69,10 @@
-
- -1504
- -446
+ 247
+ 121
- - 2.35919762
+ - 0.3605495
@@ -132,9 +132,9 @@
- - 142
+ - 140
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
@@ -1203,16 +1203,16 @@
114.9603
-
- 653.6582
+ 653.6581
114.9603
-
- 653.6582
- 210.7123
+ 653.6581
+ 210.7122
-
63.03317
- 210.7123
+ 210.7122
- A quick note
- Microsoft Sans Serif
@@ -1229,7 +1229,7 @@
-
58.03317
109.9603
- 600.6251
+ 600.625
105.752
-
@@ -1255,12 +1255,9 @@
import csv
import os
-from collections import OrderedDict
-
import rhinoscriptsyntax as rs
-import Rhino.Geometry as rg
-from compas.geometry import Point
+from compas_mobile_robot_reloc.utils import MeasurementPoint
if len(prefixes) < 1:
select_all = True
@@ -1268,40 +1265,6 @@ else:
select_all = False
prefixes = [prefix.upper() for prefix in prefixes]
-class MeasurementPt(object):
- def __init__(self, pt_name, xyz, attrs={}):
- self.pt_name = pt_name
- self.xyz = xyz
- self.x, self.y, self.z = xyz
- self.attrs = attrs
-
- self.split_pt_name()
-
- def __repr__(self):
- return "Point ID: {}, Location: {}, {}, {}".format(self.pt_name, *self.xyz)
-
- def as_cgpoint(self):
- return Point(*self.xyz)
-
- def as_rgpoint(self):
- return rg.Point3d(*self.xyz)
-
- def split_pt_name(self):
- idx = ""
-
- for n, elem in enumerate(self.pt_name[::-1]):
- if elem.isdigit():
- idx = elem + idx # add to front of str
- else:
- idx_last_char_idx = len(self.pt_name) - n
- break
-
- self.prefix = self.pt_name[:idx_last_char_idx]
-
- try:
- self.idx = int(idx)
- except ValueError:
- self.idx = 0
if cache_dir is None:
cache_dir = os.path.dirname(rs.DocumentPath())
@@ -1336,11 +1299,11 @@ if os.path.exists(file_to_process):
except ValueError:
continue
- xyz = [c * 1000 for c in xyz]
+ x, y, z = [c * 1000 for c in xyz]
pt_name = pt_data.pop("NAME")
- #print(pt_name)
- measured_pts.append(MeasurementPt(pt_name, xyz, attrs=pt_data))
+
+ measured_pts.append(MeasurementPoint(x, y, z, pt_name, attrs=pt_data))
# raise if no points found
if len(measured_pts) == 0:
@@ -1373,7 +1336,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
958
207
@@ -1384,7 +1347,6 @@ ids = [pt.pt_name for pt in measured_pts]
1061
269
- - true
@@ -1418,7 +1380,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
960
209
@@ -1429,7 +1391,6 @@ ids = [pt.pt_name for pt in measured_pts]
1004.5
219
- - true
@@ -1449,7 +1410,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
960
229
@@ -1460,7 +1421,6 @@ ids = [pt.pt_name for pt in measured_pts]
1004.5
239
- - true
@@ -1481,7 +1441,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
960
249
@@ -1492,7 +1452,6 @@ ids = [pt.pt_name for pt in measured_pts]
1004.5
259
- - true
@@ -1512,7 +1471,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
960
269
@@ -1523,7 +1482,6 @@ ids = [pt.pt_name for pt in measured_pts]
1004.5
279
- - true
@@ -1544,7 +1502,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
960
289
@@ -1555,7 +1513,6 @@ ids = [pt.pt_name for pt in measured_pts]
1004.5
299
- - true
@@ -1577,7 +1534,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
960
309
@@ -1588,7 +1545,6 @@ ids = [pt.pt_name for pt in measured_pts]
1004.5
319
- - true
@@ -1604,7 +1560,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
1076
209
@@ -1615,7 +1571,6 @@ ids = [pt.pt_name for pt in measured_pts]
1089
229
- - true
@@ -1631,7 +1586,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
1076
249
@@ -1642,7 +1597,6 @@ ids = [pt.pt_name for pt in measured_pts]
1089
269
- - true
@@ -1658,7 +1612,7 @@ ids = [pt.pt_name for pt in measured_pts]
-
+
-
1076
289
@@ -1669,7 +1623,6 @@ ids = [pt.pt_name for pt in measured_pts]
1089
309
- - true
@@ -2318,11 +2271,11 @@ ids = [pt.pt_name for pt in measured_pts]
-
3247.588
- 679.0239
+ 679.024
-
2321.27
- 679.0239
+ 679.024
- A quick note
- Microsoft Sans Serif
@@ -2782,11 +2735,11 @@ if localization_origin_frame:
741.1973
-
- 2692.582
+ 2692.581
741.1973
-
- 2692.582
+ 2692.581
835.7286
-
@@ -2808,8 +2761,8 @@ if localization_origin_frame:
-
1958.138
736.1973
- 739.4436
- 104.5314
+ 739.4434
+ 104.5313
-
1963.138
@@ -3652,60 +3605,6 @@ transformation = cgtransformation_to_rgtransform(_transformation)
-
- - 7f5c6c55-f846-4a08-9c9a-cfdc285cc6fe
- - Scribble
-
-
-
-
- - true
- -
- 2099.8
- 1079.629
-
- -
- 2308.736
- 1079.629
-
- -
- 2308.736
- 1131.863
-
- -
- 2099.8
- 1131.863
-
- - A quick note
- - Microsoft Sans Serif
- - 7943ddbb-7631-4d54-ad14-c027df3ea2dc
- - false
- - Scribble
- - Scribble
- - 25
- - conda activate rcf
-rcf proxy
-
-
-
-
- -
- 2094.8
- 1074.629
- 218.9355
- 62.23401
-
- -
- 2099.8
- 1079.629
-
-
-
-
-
-
-
-
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -3741,7 +3640,7 @@ rcf proxy
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -3777,7 +3676,7 @@ rcf proxy
-
+
- 410755b1-224a-4c1e-a407-bf32fb45ea7e
- 00000000-0000-0000-0000-000000000000
@@ -4180,7 +4079,7 @@ else:
-
+
- 410755b1-224a-4c1e-a407-bf32fb45ea7e
- 00000000-0000-0000-0000-000000000000
@@ -4522,7 +4421,7 @@ if sticky["apl_result"] is not None:
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -4557,7 +4456,7 @@ if sticky["apl_result"] is not None:
-
+
- 410755b1-224a-4c1e-a407-bf32fb45ea7e
- 00000000-0000-0000-0000-000000000000
@@ -4567,8 +4466,7 @@ if sticky["apl_result"] is not None:
- from compas import json_load
-from compas_rhino.utilities import unload_modules
-unload_modules("compas_mobile_robot_reloc")
+
from compas_mobile_robot_reloc.utils import cgframe_to_rgplane
import Rhino.Geometry as rg
@@ -4704,7 +4602,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 06953bda-1d37-4d58-9b38-4b3c74e54c8f
- File Path
@@ -4761,7 +4659,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 9ab93e1a-ebdf-4090-9296-b000cff7b202
- Split List
@@ -4903,7 +4801,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 1817fd29-20ae-4503-b542-f0fb651e67d7
- List Length
@@ -4989,7 +4887,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -5024,7 +4922,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 9ab93e1a-ebdf-4090-9296-b000cff7b202
- Split List
@@ -5166,7 +5064,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 1817fd29-20ae-4503-b542-f0fb651e67d7
- List Length
@@ -5252,7 +5150,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -5287,7 +5185,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5312,7 +5210,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -5347,7 +5245,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -5382,7 +5280,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -5417,7 +5315,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5442,7 +5340,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 28f40e48-e739-4211-91bd-f4aefa5965f8
- Transform
@@ -5477,7 +5375,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5502,7 +5400,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5527,7 +5425,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5552,7 +5450,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5577,7 +5475,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5602,7 +5500,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5627,7 +5525,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5652,7 +5550,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5677,84 +5575,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
-
- - 28f40e48-e739-4211-91bd-f4aefa5965f8
- - Transform
-
-
-
-
- - Contains a collection of three-dimensional transformations
- - acdeb4d1-999a-4cd6-9e0d-ea2c0df4ae08
- - Transform
- - Transform
- - false
- - 0
-
-
-
-
- -
- 1824
- 59
- 50
- 24
-
- -
- 1849.049
- 71.82825
-
-
-
-
-
- - 1
-
-
-
-
- - 1
- - {0;0;0}
-
-
-
-
- - 1
-
-
-
-
- - Generic
- - 0.63751297948073338
- - -0.77043276933639726
- - 0.00324791105910414
- - 7315.0846573320905
- - 0.77043830834011318
- - 0.63751399837689271
- - -0.00084552677788633877
- - -25098.384917767537
- - -0.0014191672286269555
- - 0.0030413493974164032
- - 0.99999436806325082
- - -1211.8461418773127
- - 0
- - 0
- - 0
- - 1
-
-
-
-
-
-
-
-
-
-
-
-
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5779,7 +5600,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5804,7 +5625,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5829,7 +5650,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5854,7 +5675,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5879,7 +5700,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 59e0b89a-e487-49f8-bab8-b5bab16be14c
- Panel
@@ -5940,7 +5761,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5965,7 +5786,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -5990,7 +5811,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6015,7 +5836,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6040,7 +5861,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6065,7 +5886,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6090,7 +5911,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6115,7 +5936,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6140,7 +5961,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6165,7 +5986,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6190,7 +6011,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6215,7 +6036,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6240,7 +6061,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6265,7 +6086,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6290,7 +6111,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6315,7 +6136,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6340,7 +6161,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6365,7 +6186,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6390,7 +6211,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6415,7 +6236,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- 28f40e48-e739-4211-91bd-f4aefa5965f8
- Transform
@@ -6450,7 +6271,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6475,7 +6296,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6500,7 +6321,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6525,7 +6346,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6550,7 +6371,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6575,7 +6396,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6600,7 +6421,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6625,7 +6446,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6650,7 +6471,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6675,7 +6496,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6700,7 +6521,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -6839,7 +6660,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -6864,7 +6685,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- fbac3e32-f100-4292-8692-77240a42fd1a
- Point
@@ -7003,7 +6824,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -7028,7 +6849,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -7065,7 +6886,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
+
- c552a431-af5b-46a9-a8a4-0fcbc27ef596
- Group
@@ -7097,7 +6918,7 @@ rcs_planes = [cgframe_to_rgplane(f) for f in frames]
-
- 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
+ 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
diff --git a/src/compas_mobile_robot_reloc/utils.py b/src/compas_mobile_robot_reloc/utils.py
index abb1408..acfb905 100644
--- a/src/compas_mobile_robot_reloc/utils.py
+++ b/src/compas_mobile_robot_reloc/utils.py
@@ -1,6 +1,6 @@
"""
********************************************************************************
-compas_mobile_robot_reloc.utils
+Utilities
********************************************************************************
"""
from __future__ import absolute_import
@@ -8,10 +8,10 @@
from __future__ import print_function
import compas
-import compas.geometry as cg
+import compas.geometry
try:
- import Rhino.Geometry as rg
+ import Rhino.Geometry
except ImportError:
pass
@@ -38,10 +38,12 @@ def _is_type_checking(): # type: () -> bool
if TYPE_CHECKING:
from typing import List
+ from typing import Tuple
+ from typing import Union
def rgpoint_to_cgpoint(pt):
- # type: (rg.Point3d) -> compas.geometry.Point
+ # type: (Rhino.Geometry.Point3d) -> compas.geometry.Point
"""Convert :class:`Rhino.Geometry.Point3d` to :class:`compas.geometry.Point`.
Parameters
@@ -53,32 +55,38 @@ def rgpoint_to_cgpoint(pt):
-------
Resulting point object
"""
- return cg.Point(pt.X, pt.Y, pt.Z)
+ return compas.geometry.Point(pt.X, pt.Y, pt.Z)
-def cgframe_to_rgplane(frame): # type: (compas.geometry.Frame) -> rg.Plane
+def cgpoint_to_rgpoint(pt):
+ # type: (compas.geometry.Point) -> (Rhino.Geometry.Point3d)
+ """Convert :class:`compas.geometry.Point` to :class:`Rhino.Geometry.Point`."""
+ return Rhino.Geometry.Point3d(*list(pt))
+
+
+def cgframe_to_rgplane(frame): # type: (compas.geometry.Frame) -> Rhino.Geometry.Plane
"""Convert :class:`compas.Geometry.Frame` to :class:`Rhino.Geometry.Plane`.""" # noqa: E501
- origin = rg.Point3d(*list(frame.point))
- x_vec = rg.Vector3d(*list(frame.xaxis))
- y_vec = rg.Vector3d(*list(frame.yaxis))
+ origin = Rhino.Geometry.Point3d(*list(frame.point))
+ x_vec = Rhino.Geometry.Vector3d(*list(frame.xaxis))
+ y_vec = Rhino.Geometry.Vector3d(*list(frame.yaxis))
- return rg.Plane(origin, x_vec, y_vec)
+ return Rhino.Geometry.Plane(origin, x_vec, y_vec)
def rgtransform_to_cgtransformation(rgT):
- # type: (rg.Transform) -> cg.Transformation
+ # type: (Rhino.Geometry.Transform) -> compas.geometry.Transformation
"""Convert :class:`Rhino.Geometry.Transform` to :class:`compas.geometry.Transformation`.""" # noqa: E501
M = rgtransform_to_matrix(rgT)
- return cg.Transformation.from_matrix(M)
+ return compas.geometry.Transformation.from_matrix(M)
-def rgtransform_to_matrix(rgT): # type: (rg.Transform) -> List[List[float]]
+def rgtransform_to_matrix(rgT): # type: (Rhino.Geometry.Transform) -> List[List[float]]
"""Convert :class:`Rhino.Geometry.Transform` to transformation matrix."""
return [[rgT.Item[i, j] for j in range(4)] for i in range(4)]
def cgtransformation_to_rgtransform(cgT):
- # type: (compas.geometry.Transformation) -> rg.Transform
+ # type: (compas.geometry.Transformation) -> Rhino.Geometry.Transform
"""Convert :class:`compas.geometry.Transformation` to :class:`Rhino.Geometry.Transform`.""" # noqa: E501
_ensure_rhino()
@@ -87,14 +95,68 @@ def cgtransformation_to_rgtransform(cgT):
return matrix_to_rgtransform(M)
-def matrix_to_rgtransform(M): # type: (List[List[float]]) -> rg.Transform
+def matrix_to_rgtransform(M): # type: (List[List[float]]) -> Rhino.Geometry.Transform
"""Create :class:`Rhino.Geometry.Transform` from a transformation matrix."""
_ensure_rhino()
- rgT = rg.Transform()
+ rgT = Rhino.Geometry.Transform()
for i, row in enumerate(M):
for j, val in enumerate(row):
rgT[i, j] = val
return rgT
+
+
+class MeasurementPoint(compas.geometry.Point):
+ """A :class:`compas.geometry.Point` with some CSV pointlist related methods."""
+
+ def __init__(
+ self,
+ x, # type: float
+ y, # type: float
+ z, # type: float
+ pt_name, # type: str
+ attrs=None, # type: Union[None, dict]
+ ): # type: (...) -> None
+ super(MeasurementPoint, self).__init__(x, y, z)
+ self.pt_name = pt_name
+ self.attrs = attrs or {}
+
+ def __repr__(self): # type: () -> str
+ return "Point ID: {}, Location: {}, {}, {}".format(
+ self.pt_name, self.x, self.y, self.z
+ )
+
+ @property
+ def prefix(self): # type: () -> str
+ """Point prefix from data source."""
+ return self._split_pt_name()[0]
+
+ @property
+ def idx(self): # type: () -> int
+ """Point index from data source."""
+ return self._split_pt_name()[1]
+
+ def as_rgpoint(self): # type: () -> compas.geometry.Point
+ """Get a point representation in Rhino."""
+ return cgpoint_to_rgpoint(self)
+
+ def _split_pt_name(self): # type: () -> Tuple[str, int]
+ idx = ""
+
+ for n, elem in enumerate(self.pt_name[::-1]):
+ if elem.isdigit():
+ idx = elem + idx # add to front of str
+ else:
+ idx_last_char_idx = len(self.pt_name) - n
+ break
+
+ prefix = self.pt_name[:idx_last_char_idx]
+
+ try:
+ _idx = int(idx)
+ except ValueError:
+ _idx = 0
+
+ return prefix, _idx
diff --git a/src/compas_mobile_robot_reloc/xforms.py b/src/compas_mobile_robot_reloc/xforms.py
index c9a140f..84e3a0e 100644
--- a/src/compas_mobile_robot_reloc/xforms.py
+++ b/src/compas_mobile_robot_reloc/xforms.py
@@ -1,6 +1,6 @@
"""
********************************************************************************
-compas_mobile_robot_reloc.utils
+Transformations
********************************************************************************
"""
from __future__ import absolute_import