11from compas .geometry import Frame
22from compas .geometry import Brep
3- from compas .geometry import BrepInvalidError
43from compas .geometry import BrepTrimmingError
54from compas .geometry import Plane
65
76from compas_rhino .conversions import box_to_rhino
8- from compas_rhino .conversions import point_to_rhino
97from compas_rhino .conversions import xform_to_rhino
108from compas_rhino .conversions import frame_to_rhino
119from compas_rhino .conversions import cylinder_to_rhino
1210
1311import Rhino
1412
13+ from .builder import RhinoBrepBuilder
1514from .face import RhinoBrepFace
1615from .edge import RhinoBrepEdge
1716from .vertex import RhinoBrepVertex
@@ -36,6 +35,8 @@ class RhinoBrep(Brep):
3635 The list of vertex geometries as points in 3D space.
3736 edges : list[:class:`~compas_rhino.geometry.RhinoBrepEdge`], read-only
3837 The list of edges which comprise this brep.
38+ trims : list[:class:`~compas_rhino.geometry.RhinoBrepTrim`], read-only
39+ The list of trims which comprise this brep.
3940 loops : list[:class:`~compas_rhino.geometry.RhinoBrepLoop`], read-only
4041 The list of loops which comprise this brep.
4142 faces : list[:class:`~compas_rhino.geometry.RhinoBrepFace`], read-only
@@ -70,18 +71,22 @@ def __init__(self, brep=None):
7071
7172 @property
7273 def data (self ):
73- faces = []
74- for face in self .faces :
75- faces .append (face .data )
76- return {"faces" : faces }
74+ return {
75+ "vertices" : [v .data for v in self .vertices ],
76+ "edges" : [e .data for e in self .edges ],
77+ "faces" : [f .data for f in self .faces ],
78+ }
7779
7880 @data .setter
7981 def data (self , data ):
80- faces = []
81- for facedata in data ["faces" ]:
82- face = RhinoBrepFace .from_data (facedata )
83- faces .append (face )
84- self ._create_native_brep (faces )
82+ builder = RhinoBrepBuilder ()
83+ for v_data in data ["vertices" ]:
84+ RhinoBrepVertex .from_data (v_data , builder )
85+ for e_data in data ["edges" ]:
86+ RhinoBrepEdge .from_data (e_data , builder )
87+ for f_data in data ["faces" ]:
88+ RhinoBrepFace .from_data (f_data , builder )
89+ self ._brep = builder .result
8590
8691 # ==============================================================================
8792 # Properties
@@ -102,6 +107,11 @@ def points(self):
102107
103108 @property
104109 def edges (self ):
110+ if self ._brep :
111+ return [RhinoBrepEdge (edge ) for edge in self ._brep .Edges ]
112+
113+ @property
114+ def trims (self ):
105115 if self ._brep :
106116 return [RhinoBrepEdge (trim ) for trim in self ._brep .Trims ]
107117
@@ -326,88 +336,3 @@ def split(self, cutter):
326336 """
327337 resulting_breps = self ._brep .Split (cutter .native_brep , TOLERANCE )
328338 return [RhinoBrep .from_native (brep ) for brep in resulting_breps ]
329-
330- # ==============================================================================
331- # Other Methods
332- # ==============================================================================
333-
334- def _create_native_brep (self , faces ):
335- # Source: https://github.com/mcneel/rhino-developer-samples/blob/3179a8386a64602ee670cc832c77c561d1b0944b/rhinocommon/cs/SampleCsCommands/SampleCsTrimmedPlane.cs
336- # Things need to be defined in a valid brep:
337- # 1- Vertices
338- # 2- 3D Curves (geometry)
339- # 3- Edges (topology - reference curve geometry)
340- # 4- Surfaces (geometry)
341- # 5- Faces (topology - reference surface geometry)
342- # 6- Loops (2D parameter space of faces)
343- # 4- Trims and 2D curves (2D parameter space of edges)
344- self ._brep = Rhino .Geometry .Brep ()
345- for face in faces :
346- rhino_face , rhino_surface = self ._create_brep_face (face )
347- for loop in face .loops :
348- rhino_loop = self ._brep .Loops .Add (Rhino .Geometry .BrepLoopType .Outer , rhino_face )
349- for edge in loop .edges :
350- start_vertex , end_vertex = self ._add_edge_vertices (edge )
351- rhino_edge = self ._add_edge (edge , start_vertex , end_vertex )
352- rhino_2d_curve = self ._create_trim_curve (rhino_edge , rhino_surface )
353- self ._add_trim (rhino_2d_curve , rhino_edge , rhino_loop )
354-
355- self ._brep .Repair (TOLERANCE )
356- self ._brep .JoinNakedEdges (
357- TOLERANCE
358- ) # without this, Brep.Trim() led to some weird results on de-serialized Breps
359- self ._validate_brep ()
360-
361- def _validate_brep (self ):
362- if self ._brep .IsValid :
363- return
364-
365- error_message = ""
366- valid_topo , log_topo = self ._brep .IsValidTopology ()
367- valid_tol , log_tol = self ._brep .IsValidTolerancesAndFlags ()
368- valid_geo , log_geo = self ._brep .IsValidGeometry ()
369- if not valid_geo :
370- error_message += "Invalid geometry:\n {}\n " .format (log_geo )
371- if not valid_topo :
372- error_message += "Invalid topology:\n {}\n " .format (log_topo )
373- if not valid_tol :
374- error_message += "Invalid tolerances:\n {}\n " .format (log_tol )
375-
376- raise BrepInvalidError (error_message )
377-
378- def _create_brep_face (self , face ):
379- # Geometry
380- surface_index = self ._brep .AddSurface (face .native_surface )
381- brep_surface = self ._brep .Surfaces .Item [surface_index ]
382- # Topology
383- brep_face = self ._brep .Faces .Add (surface_index )
384- return brep_face , brep_surface
385-
386- def _add_edge_vertices (self , edge ):
387- start_vertex = self ._brep .Vertices .Add (point_to_rhino (edge .start_vertex .point ), TOLERANCE )
388- end_vertex = self ._brep .Vertices .Add (point_to_rhino (edge .end_vertex .point ), TOLERANCE )
389- return start_vertex , end_vertex
390-
391- def _add_edge (self , edge , start_vertex , end_vertex ):
392- # Geometry
393- curve_index = self ._brep .AddEdgeCurve (edge .curve )
394- # Topology
395- rhino_edge = self ._brep .Edges .Add (start_vertex , end_vertex , curve_index , TOLERANCE )
396- return rhino_edge
397-
398- def _add_trim (self , rhino_trim_curve , rhino_edge , rhino_loop ):
399- # Geometry
400- trim_curve_index = self ._brep .AddTrimCurve (rhino_trim_curve )
401- # Topology
402- trim = self ._brep .Trims .Add (rhino_edge , True , rhino_loop , trim_curve_index )
403- trim .IsoStatus = getattr (
404- Rhino .Geometry .IsoStatus , "None"
405- ) # IsoStatus.None makes lint, IDE and even Python angry
406- trim .TrimType = Rhino .Geometry .BrepTrimType .Boundary
407- trim .SetTolerances (TOLERANCE , TOLERANCE )
408-
409- @staticmethod
410- def _create_trim_curve (rhino_edge , rhino_surface ):
411- curve_2d = rhino_surface .Pullback (rhino_edge .EdgeCurve , TOLERANCE )
412- curve_2d .Reverse ()
413- return curve_2d
0 commit comments