Skip to content

Commit 773c5fb

Browse files
committed
Explicit methods for geometry and separate methods for doc objects
1 parent ea316f9 commit 773c5fb

File tree

7 files changed

+342
-387
lines changed

7 files changed

+342
-387
lines changed

CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232
* Added `compas.geometry.curves.curve.Curve.from_native`.
3333
* Added `compas_rhino.geometry.curves.curve.Curve.from_native`.
3434
* Added `compas_rhino.geometry.curves.nurbs.NurbsCurve.from_native`.
35+
* Added `compas_rhino.conversions.breps.brep_to_compas_mesh`.
36+
* Added `compas_rhino.conversions.docobjects.brepobject_to_compas`.
37+
* Added `compas_rhino.conversions.docobjects.curveobject_to_compas`.
38+
* Added `compas_rhino.conversions.docobjects.meshobject_to_compas`.
39+
* Added `compas_rhino.conversions.docobjects.pointobject_to_compas`.
40+
* Added `compas_rhino.conversions.docobjects.surfaceobject_to_compas`.
3541

3642
### Changed
3743

@@ -46,7 +52,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4652
* Changed `compas.geometry.curves.nurbs.NurbsCurve.__new__` to prevent instantiation of `NurbsCurve` directly.
4753
* Changed `compas_rhino.geometry.curves.new_nurbscurve_from_...` to `nurbscurve_from_...`.
4854
* Fixed `compas_ghpython` Grasshopper components not included in published pakcage.
49-
* Chnaged `compas.colors.Color.coerce` to take color as is, if it is already aninstance of `compas.colors.Color`.
55+
* Changed `compas.colors.Color.coerce` to take color as is, if it is already aninstance of `compas.colors.Color`.
56+
* Changed `compas_rhino.conversions.surfaces.surface_to_compas` to work only with surface geometry.
57+
* Changed `compas_rhino.conversions.curves.curve_to_compas_line` to work only with geometry.
58+
* Changed `compas_rhino.conversions.curves.curve_to_compas_circle` to work only with geometry.
59+
* Changed `compas_rhino.conversions.curves.curve_to_compas_ellipse` to work only with geometry.
60+
* Changed `compas_rhino.conversions.curves.curve_to_compas_polyline` to work only with geometry.
5061

5162
### Removed
5263

@@ -75,6 +86,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7586
* Removed `compas.geometry.curves.curve.new_nurbscurve`.
7687
* Removed `compas_rhino.geometry.curves.new_curve`.
7788
* Removed `compas_rhino.geometry.curves.new_nurbscurve`.
89+
* Removed `compas_rhino.conversions.surfaces.data_to_rhino_surface`.
90+
* Removed `compas_rhino.conversions.surfaces.surface_to_compas_data`.
91+
* Removed `compas_rhino.conversions.surfaces.surface_to_compas_quadmesh`.
92+
* Removed `compas_rhino.conversions.curves.curve_to_compas_data`.
7893

7994
## [2.2.1] 2024-06-25
8095

src/compas_rhino/conversions/__init__.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,8 @@
4343
)
4444
from .surfaces import (
4545
surface_to_rhino,
46-
data_to_rhino_surface,
47-
surface_to_compas_data,
4846
surface_to_compas,
4947
surface_to_compas_mesh,
50-
surface_to_compas_quadmesh,
5148
)
5249
from .shapes import (
5350
box_to_rhino,
@@ -77,6 +74,7 @@
7774
brep_to_compas_cone,
7875
brep_to_compas_cylinder,
7976
brep_to_compas_sphere,
77+
brep_to_compas_mesh,
8078
)
8179
from .extrusions import (
8280
extrusion_to_compas_box,
@@ -89,6 +87,14 @@
8987
transformation_matrix_to_rhino,
9088
)
9189

90+
from .docobjects import (
91+
brepobject_to_compas,
92+
curveobject_to_compas,
93+
meshobject_to_compas,
94+
pointobject_to_compas,
95+
surfaceobject_to_compas,
96+
)
97+
9298

9399
__all__ = [
94100
"ConversionError",
@@ -127,11 +133,8 @@
127133
"curve_to_compas",
128134
# surfaces
129135
"surface_to_rhino",
130-
"surface_to_compas_data",
131-
"data_to_rhino_surface",
132136
"surface_to_compas",
133137
"surface_to_compas_mesh",
134-
"surface_to_compas_quadmesh",
135138
# shapes
136139
"box_to_rhino",
137140
"sphere_to_rhino",
@@ -158,11 +161,18 @@
158161
"brep_to_compas_cone",
159162
"brep_to_compas_cylinder",
160163
"brep_to_compas_sphere",
164+
"brep_to_compas_mesh",
161165
# extrusions
162166
"extrusion_to_compas_box",
163167
"extrusion_to_compas_cylinder",
164168
"extrusion_to_compas_torus",
165169
# transformations
166170
"transformation_to_rhino",
167171
"transformation_matrix_to_rhino",
172+
# docobjects
173+
"brepobject_to_compas",
174+
"curveobject_to_compas",
175+
"meshobject_to_compas",
176+
"pointobject_to_compas",
177+
"surfaceobject_to_compas",
168178
]

src/compas_rhino/conversions/breps.py

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44

55
import scriptcontext as sc # type: ignore
66

7+
from compas.datastructures import Mesh
8+
from compas.geometry import Brep
9+
from compas.tolerance import TOL
10+
711
from .exceptions import ConversionError
12+
from .geometry import point_to_compas
813
from .shapes import cone_to_compas
914
from .shapes import cylinder_to_compas
1015
from .shapes import sphere_to_compas
@@ -15,7 +20,7 @@
1520

1621

1722
def brep_to_rhino(brep):
18-
"""Convert a COMPAS brep to a Rhino brep.
23+
"""Convert a COMPAS Brep to a Rhino Brep.
1924
2025
Parameters
2126
----------
@@ -34,6 +39,26 @@ def brep_to_rhino(brep):
3439
# =============================================================================
3540

3641

42+
def brep_to_compas(brep):
43+
"""Convert a Rhino Brep to a COMPAS Brep.
44+
45+
Parameters
46+
----------
47+
brep : :rhino:`Rhino.Geometry.Brep`
48+
49+
Returns
50+
-------
51+
:class:`compas.geometry.Brep`
52+
53+
"""
54+
return Brep.from_native(brep)
55+
56+
57+
# =============================================================================
58+
# To COMPAS Shapes
59+
# =============================================================================
60+
61+
3762
def brep_to_compas_box(brep):
3863
"""Convert a Rhino brep to a COMPAS box.
3964
@@ -120,3 +145,89 @@ def brep_to_compas_sphere(brep):
120145
result, sphere = face.TryGetSphere()
121146
if result:
122147
return sphere_to_compas(sphere)
148+
149+
150+
# =============================================================================
151+
# To COMPAS Mesh
152+
# =============================================================================
153+
154+
155+
def brep_to_compas_mesh(brep, facefilter=None, cleanup=False, cls=None):
156+
"""Convert the face loops of a Rhino brep to a COMPAS mesh.
157+
158+
Parameters
159+
----------
160+
brep : :class:`Rhino.Geometry.Brep`
161+
A Rhino brep.
162+
facefilter : callable, optional
163+
A filter for selection which Brep faces to include.
164+
If provided, the filter should return True or False per face.
165+
A very simple filter that includes all faces is ``def facefilter(face): return True``.
166+
Default parameter value is None in which case all faces are included.
167+
cleanup : bool, optional
168+
Flag indicating to clean up the result.
169+
Cleaning up means to remove isolated faces and unused vertices.
170+
Default is False.
171+
cls : :class:`compas.datastructures.Mesh`, optional
172+
The type of COMPAS mesh.
173+
174+
Returns
175+
-------
176+
:class:`compas.datastructures.Mesh`
177+
The resulting mesh.
178+
179+
"""
180+
if facefilter and callable(facefilter):
181+
brepfaces = [face for face in brep.Faces if facefilter(face)]
182+
else:
183+
brepfaces = brep.Faces
184+
185+
# vertex maps and face lists
186+
gkey_xyz = {}
187+
faces = []
188+
for face in brepfaces:
189+
loop = face.OuterLoop
190+
curve = loop.To3dCurve()
191+
segments = list(curve.Explode())
192+
a = point_to_compas(segments[0].PointAtStart)
193+
b = point_to_compas(segments[0].PointAtEnd)
194+
a_gkey = TOL.geometric_key(a)
195+
b_gkey = TOL.geometric_key(b)
196+
gkey_xyz[a_gkey] = a
197+
gkey_xyz[b_gkey] = b
198+
face = [a_gkey, b_gkey]
199+
for segment in segments[1:-1]:
200+
b = point_to_compas(segment.PointAtEnd)
201+
b_gkey = TOL.geometric_key(b)
202+
face.append(b_gkey)
203+
gkey_xyz[b_gkey] = b
204+
faces.append(face)
205+
206+
# vertices and faces
207+
gkey_index = {gkey: index for index, gkey in enumerate(gkey_xyz)}
208+
vertices = [list(xyz) for gkey, xyz in gkey_xyz.items()]
209+
faces = [[gkey_index[gkey] for gkey in face] for face in faces]
210+
211+
# remove duplicates from vertexlist
212+
polygons = []
213+
for temp in faces:
214+
face = []
215+
for vertex in temp:
216+
if vertex not in face:
217+
face.append(vertex)
218+
polygons.append(face)
219+
220+
# define mesh type
221+
cls = cls or Mesh
222+
# create mesh
223+
mesh = cls.from_vertices_and_faces(vertices, polygons)
224+
225+
# remove isolated faces
226+
if cleanup:
227+
if mesh.number_of_faces() > 1:
228+
for face in list(mesh.faces()):
229+
if not mesh.face_neighbors(face):
230+
mesh.delete_face(face)
231+
mesh.remove_unused_vertices()
232+
233+
return mesh

src/compas_rhino/conversions/curves.py

Lines changed: 12 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from compas.geometry import Arc
99
from compas.geometry import Circle
10+
from compas.geometry import Curve
1011
from compas.geometry import Ellipse
1112
from compas.geometry import Line
1213
from compas.geometry import NurbsCurve
@@ -25,33 +26,6 @@
2526
# =============================================================================
2627

2728

28-
def data_to_rhino_curve(data):
29-
"""Convert a COMPAS curve to a Rhino curve.
30-
31-
Parameters
32-
----------
33-
data : dict
34-
35-
Returns
36-
-------
37-
:rhino:`Rhino.Geometry.NurbsCurve`
38-
39-
"""
40-
nurbs = Rhino.Geometry.NurbsCurve(data["degree"], len(data["points"]))
41-
42-
for index, xyz in enumerate(data["points"]):
43-
nurbs.Points.SetPoint(index, *xyz)
44-
45-
knotvector = []
46-
for knot, mult in zip(data["knots"], data["multiplicities"]):
47-
for i in range(mult):
48-
knotvector.append(knot)
49-
50-
for index, knot in enumerate(knotvector):
51-
nurbs.Knots.Item[index] = knot
52-
return nurbs
53-
54-
5529
def line_to_rhino(line):
5630
"""Convert a COMPAS line to a Rhino line.
5731
@@ -308,8 +282,6 @@ def curve_to_compas_line(curve):
308282
:class:`compas.geometry.Line`
309283
310284
"""
311-
if isinstance(curve, Rhino.DocObjects.RhinoObject):
312-
curve = curve.Geometry
313285
return Line(point_to_compas(curve.PointAtStart), point_to_compas(curve.PointAtEnd))
314286

315287

@@ -330,8 +302,6 @@ def curve_to_compas_circle(curve):
330302
If the curve cannot be converted to a circle.
331303
332304
"""
333-
if isinstance(curve, Rhino.DocObjects.RhinoObject):
334-
curve = curve.Geometry
335305
result, circle = curve.TryGetCircle()
336306
if not result:
337307
raise ConversionError("The curve cannot be converted to a circle.")
@@ -355,8 +325,6 @@ def curve_to_compas_ellipse(curve):
355325
If the curve cannot be converted to an ellipse.
356326
357327
"""
358-
if isinstance(curve, Rhino.DocObjects.RhinoObject):
359-
curve = curve.Geometry
360328
result, ellipse = curve.TryGetEllipse()
361329
if not result:
362330
raise ConversionError("The curve cannot be converted to an ellipse.")
@@ -380,74 +348,29 @@ def curve_to_compas_polyline(curve):
380348
If the curve cannot be converted to a polyline.
381349
382350
"""
383-
if isinstance(curve, Rhino.DocObjects.RhinoObject):
384-
curve = curve.Geometry
385351
result, polyline = curve.TryGetPolyline()
386352
if not result:
387353
raise ConversionError("The curve cannot be converted to a polyline.")
388354
return polyline_to_compas(polyline)
389355

390356

391-
def curve_to_compas_data(curve):
392-
"""Convert a Rhino curve to a COMPAS data dict.
357+
def curve_to_compas(curve, try_nurbs=True):
358+
"""Convert a Rhino curve to a COMPAS curve.
393359
394360
Parameters
395361
----------
396362
curve : :rhino:`Rhino.Geometry.Curve`
363+
A Rhino curve.
364+
try_nurbs : bool, optional
365+
Try to convert the curve to a NURBS curve.
397366
398367
Returns
399368
-------
400-
dict
401-
402-
"""
403-
if isinstance(curve, Rhino.DocObjects.RhinoObject):
404-
curve = curve.Geometry
405-
406-
nurbs = curve.ToNurbsCurve()
407-
points = []
408-
weights = []
409-
knots = []
410-
multiplicities = []
411-
degree = nurbs.Degree
412-
is_periodic = nurbs.IsPeriodic
413-
414-
for index in range(nurbs.Points.Count):
415-
point = nurbs.Points.Item[index]
416-
points.append(point_to_compas(point.Location))
417-
weights.append(point.Weight)
418-
419-
for index in range(nurbs.Knots.Count):
420-
knots.append(nurbs.Knots.Item[index])
421-
multiplicities.append(nurbs.Knots.KnotMultiplicity(index))
422-
423-
return {
424-
"points": [point.data for point in points],
425-
"weights": weights,
426-
"knots": knots,
427-
"multiplicities": multiplicities,
428-
"degree": degree,
429-
"is_periodic": is_periodic,
430-
}
431-
432-
433-
def curve_to_compas(curve):
434-
"""Convert a Rhino (Nurbs) curve to a COMPAS curve.
435-
436-
Parameters
437-
----------
438-
curve : :rhino:`Rhino.Geometry.Curve`
439-
440-
Returns
441-
-------
442-
:class:`compas.geometry.NurbsCurve`
443-
444-
Raises
445-
------
446-
ConversionError
447-
If the curve cannot be converted to a COMPAS curve.
369+
:class:`compas.geometry.Curve` | :class:`compas.geometry.NurbsCurve`
370+
If `try_nurbs` is `True`, and the geometry has a NURBS representation, return a NURBS curve.
371+
Otherwise return a general curve.
448372
449373
"""
450-
if isinstance(curve, Rhino.DocObjects.RhinoObject):
451-
curve = curve.Geometry
452-
nurbs = curve.ToNurbsCurve()
453-
return NurbsCurve.from_native(nurbs)
374+
if try_nurbs and curve.HasNurbsForm():
375+
return NurbsCurve.from_native(curve.ToNurbsCurve())
376+
return Curve.from_native(curve)

0 commit comments

Comments
 (0)