11from compas .geometry import BrepFace
22from compas_rhino .geometry import RhinoNurbsSurface
3+ from compas_rhino .conversions import plane_to_compas
4+ from compas_rhino .conversions import sphere_to_compas
5+ from compas_rhino .conversions import cylinder_to_compas
6+ from compas_rhino .conversions import plane_to_rhino
7+ from compas_rhino .conversions import sphere_to_rhino
8+ from compas_rhino .conversions import cylinder_to_rhino
39
410from .loop import RhinoBrepLoop
511
@@ -35,9 +41,7 @@ def __init__(self, rhino_face=None):
3541 def _set_face (self , native_face ):
3642 self ._face = native_face
3743 self ._loops = [RhinoBrepLoop (loop ) for loop in self ._face .Loops ]
38- self ._surface = RhinoNurbsSurface .from_rhino (
39- self ._face .ToNurbsSurface ()
40- ) # surface in Rhino will always be NURBS
44+ self ._surface = self ._face .UnderlyingSurface ()
4145
4246 # ==============================================================================
4347 # Data
@@ -47,26 +51,35 @@ def _set_face(self, native_face):
4751 def data (self ):
4852 boundary = self ._loops [0 ].data
4953 holes = [loop .data for loop in self ._loops [1 :]]
50- surface = {"type" : "nurbs" }
51- surface .update (self .surface .data )
52- return {"boundary" : boundary , "surface" : surface , "holes" : holes }
54+ surface_type , surface = self ._get_surface_geometry (self ._surface )
55+ return {"boundary" : boundary , "holes" : holes , "surface_type" : surface_type , "surface" : surface }
5356
5457 @data .setter
5558 def data (self , value ):
5659 boundary = RhinoBrepLoop .from_data (value ["boundary" ])
5760 holes = [RhinoBrepLoop .from_data (loop ) for loop in value ["holes" ]]
5861 self ._loops = [boundary ] + holes
59- # TODO: should we check surface type here? should we support surfaces other than NURBS?
60- self ._surface = RhinoNurbsSurface .from_data (value ["surface" ])
62+ type_ = value ["surface_type" ]
63+ # TODO: using the new serialization mechanism, surface.to_nurbs() should replace all this branching..
64+ # TODO: given that Plane, Sphere, Cylinder etc. all implement to_nurbs()
65+ surface = value ["surface" ]
66+ if type_ == "plane" :
67+ surface = self ._make_surface_from_plane_loop (surface , boundary )
68+ elif type_ == "sphere" :
69+ surface = RhinoNurbsSurface .from_sphere (surface )
70+ elif type_ == "cylinder" :
71+ surface = RhinoNurbsSurface .from_cylinder (surface )
72+ elif type_ == "torus" :
73+ raise NotImplementedError ("Support for torus surface is not yet implemented!" )
74+ self ._surface = surface .rhino_surface
6175
6276 # ==============================================================================
6377 # Properties
6478 # ==============================================================================
6579
6680 @property
6781 def native_surface (self ):
68- if self ._surface :
69- return self ._surface .rhino_surface
82+ return self ._surface
7083
7184 @property
7285 def loops (self ):
@@ -87,3 +100,39 @@ def holes(self):
87100 @property
88101 def is_plane (self ):
89102 return
103+
104+ @staticmethod
105+ def _get_surface_geometry (surface ):
106+ # success, cast_surface = surface.TryGetPlane()
107+ # if success:
108+ # return "plane", plane_to_compas(cast_surface)
109+ # success, cast_surface = surface.TryGetSphere()
110+ # if success:
111+ # return "sphere", sphere_to_compas(cast_surface)
112+ # success, cast_surface = surface.TryGetCylinder()
113+ # if success:
114+ # return "cylinder", cylinder_to_compas(cast_surface)
115+ # success, cast_surface = surface.TryGetTorus()
116+ # if success:
117+ # raise NotImplementedError("Support for torus surface is not yet implemented!")
118+ return "nurbs" , RhinoNurbsSurface .from_rhino (surface .ToNurbsSurface ())
119+
120+ # @staticmethod
121+ # def _make_surface_from_plane_loop(plane, loop):
122+ # # TODO: replace guesswork here with an actual calculation..
123+ # u_degree, v_degree = 1, 1
124+ # u_p_count, v_p_count = 2, 2
125+ # curve_lengths = [edge.curve.GetLength() for edge in loop.edges]
126+ # max_length = max(curve_lengths)
127+ # u_interval, v_interval = (0.0, max_length), (0.0, max_length)
128+ # return RhinoNurbsSurface.from_plane(plane, u_interval, v_interval, u_degree, v_degree, u_p_count, v_p_count)
129+
130+ @staticmethod
131+ def _make_surface_from_plane_loop (plane , loop ):
132+ # TODO: replace guesswork here with an actual calculation..
133+ c0 = loop .edges [0 ].start_point
134+ c1 = loop .edges [1 ].start_point
135+ c2 = loop .edges [2 ].start_point
136+ c3 = loop .edges [3 ].start_point
137+ surface = RhinoNurbsSurface .from_corners ([c3 , c2 , c1 , c0 ])
138+ return surface
0 commit comments