Skip to content

Commit 8edb83d

Browse files
committed
last fixes
1 parent ba26ea3 commit 8edb83d

File tree

6 files changed

+114
-84
lines changed

6 files changed

+114
-84
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
* Added `compas.geometry.surfaces.nurbs.NurbsSurface.from_sphere`.
2121
* Added `compas.geometry.surfaces.nurbs.NurbsSurface.from_torus`.
2222
* Added `compas_rhino.geometry.surfaces.surface_from_native`.
23+
* Added `compas_rhino.geometry.surfaces.nurbssurface_from_native`.
2324
* Added `compas_rhino.geometry.surfaces.nurbssurface_from_cylinder`.
2425
* Added `compas_rhino.geometry.surfaces.nurbssurface_from_fill`.
2526
* Added `compas_rhino.geometry.surfaces.nurbssurface_from_torus`.
@@ -33,7 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3334

3435
* Fixed bug in `compas.geometry.curves.curve.Curve.reversed` by adding missing parenthesis.
3536
* Fixed all doctests so we can run `invoke test --doctest`.
36-
* Changed `compas.geometry.surfaces.surface.Surface.__new__` to prevent instantiation of `compas.geometry.surfaces.surface.Surface` only.
37+
* Changed `compas.geometry.surfaces.surface.Surface.__new__` to prevent instantiation of `compas.geometry.surfaces.surface.Surface` directly.
38+
* Changed `compas.geometry.surfaces.nurbs.NurbsSurface.__new__` to prevent instantiation of `compas.geometry.surfaces.nurbs.NurbsSurface` directly.
3739
* Fixed bug in `compas.geometry.surfaces.nurbs.NurbsSurface.__data__`.
3840
* Changed `compas.geometry.surfaces.nurbs.new_nurbssurface_from_...` to `compas.geometry.surfaces.nurbs.nurbssurface_from_...`.
3941

@@ -49,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4951
* Removed `compas.geometry.surfaces.surface.ToroidalSurface.__new__`.
5052
* Removed `compas.geometry.surfaces.nurbs.NurbsSurface.__init__`.
5153
* Removed `compas_rhino.geometry.surfaces.new_surface`.
54+
* Removed `compas_rhino.geometry.surfaces.new_nurbssurface`.
5255
* Removed `compas_rhino.geometry.surfaces.nurbs.NurbsSurface.__from_data__`.
5356
* Removed `compas_rhino.geometry.surfaces.surface.Surface.from_corners`.
5457
* Removed `compas_rhino.geometry.surfaces.surface.Surface.from_cylinder`.

src/compas/geometry/surfaces/nurbs.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@
1111
from .surface import Surface
1212

1313

14-
@pluggable(category="factories")
15-
def new_nurbssurface(cls, *args, **kwargs):
16-
raise PluginNotInstalledError
17-
18-
1914
@pluggable(category="factories")
2015
def nurbssurface_from_cylinder(cls, *args, **kwargs):
2116
raise PluginNotInstalledError
@@ -41,6 +36,11 @@ def nurbssurface_from_interpolation(cls, *args, **kwargs):
4136
raise PluginNotInstalledError
4237

4338

39+
@pluggable(category="factories")
40+
def nurbssurface_from_native(cls, *args, **kwargs):
41+
raise PluginNotInstalledError
42+
43+
4444
@pluggable(category="factories")
4545
def nurbssurface_from_parameters(cls, *args, **kwargs):
4646
raise PluginNotInstalledError
@@ -157,7 +157,7 @@ def __from_data__(cls, data):
157157
The constructed surface.
158158
159159
"""
160-
points = [[Point.__from_data__(point) for point in row] for row in data["points"]]
160+
points = data["points"] # conversion is not needed because point data can be provided in their raw form as well
161161
weights = data["weights"]
162162
knots_u = data["knots_u"]
163163
knots_v = data["knots_v"]
@@ -180,9 +180,10 @@ def __from_data__(cls, data):
180180
is_periodic_v,
181181
)
182182

183-
# this may not really be necessary
184183
def __new__(cls, *args, **kwargs):
185-
return new_nurbssurface(cls, *args, **kwargs)
184+
if cls is NurbsSurface:
185+
raise TypeError("Instantiating the base NURBS Surface class directly is not allowed.")
186+
return object.__new__(cls)
186187

187188
def __repr__(self):
188189
return "{0}(points={1!r}, weigths={2}, knots_u={3}, knots_v={4}, mults_u={5}, mults_v={6}, degree_u={7}, degree_v={8}, is_periodic_u={9}, is_periodic_v={10})".format(
@@ -377,6 +378,22 @@ def from_meshgrid(cls, nu=10, nv=10):
377378
points.append(row)
378379
return cls.from_points(points=points)
379380

381+
@classmethod
382+
def from_native(cls, surface):
383+
"""Construct a NURBS surface from a native surface geometry.
384+
385+
Parameters
386+
----------
387+
surface
388+
A CAD native surface object.
389+
390+
Returns
391+
-------
392+
:class:`compas.geometry.NurbsSurface`
393+
394+
"""
395+
raise NotImplementedError
396+
380397
@classmethod
381398
def from_parameters(
382399
cls,

src/compas/geometry/surfaces/surface.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,6 @@ def is_periodic_v(self):
145145
# Constructors
146146
# ==============================================================================
147147

148-
# these probably need to be moved to Nurbs
149-
# i don't think you can store a "general" parametric surface in a file
150-
151148
@classmethod
152149
def from_native(cls, surface):
153150
"""Construct a parametric surface from a native surface geometry.
@@ -163,7 +160,7 @@ def from_native(cls, surface):
163160
A COMPAS surface.
164161
165162
"""
166-
return surface_from_native(cls, surface)
163+
raise NotImplementedError
167164

168165
@classmethod
169166
def from_obj(cls, filepath):

src/compas_rhino/geometry/surfaces/__init__.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from .surface import RhinoSurface # noqa : F401
22
from .nurbs import RhinoNurbsSurface
33

4-
from compas.geometry import NurbsSurface
54
from compas.plugins import plugin
65

76

@@ -10,12 +9,6 @@ def surface_from_native(cls, *args, **kwargs):
109
return RhinoSurface.from_native(*args, **kwargs)
1110

1211

13-
# this may not really be necessary
14-
@plugin(category="factories", requires=["Rhino"])
15-
def new_nurbssurface(cls, *args, **kwargs):
16-
return super(NurbsSurface, cls).__new__(cls)
17-
18-
1912
@plugin(category="factories", requires=["Rhino"])
2013
def nurbssurface_from_cylinder(cls, *args, **kwargs):
2114
return RhinoNurbsSurface.from_cylinder(*args, **kwargs)
@@ -31,6 +24,11 @@ def nurbssurface_from_frame(cls, *args, **kwargs):
3124
return RhinoNurbsSurface.from_frame(*args, **kwargs)
3225

3326

27+
@plugin(category="factories", requires=["Rhino"])
28+
def nurbssurface_from_native(cls, *args, **kwargs):
29+
return RhinoNurbsSurface.from_native(*args, **kwargs)
30+
31+
3432
@plugin(category="factories", requires=["Rhino"])
3533
def nurbssurface_from_parameters(cls, *args, **kwargs):
3634
return RhinoNurbsSurface.from_parameters(*args, **kwargs)

src/compas_rhino/geometry/surfaces/nurbs.py

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121

2222
class ControlPoints(object):
2323
def __init__(self, surface):
24-
self.rhino_surface = surface
24+
self.native_surface = surface
2525

2626
@property
2727
def points(self):
2828
points = []
29-
for i in range(self.rhino_surface.Points.CountU):
29+
for i in range(self.native_surface.Points.CountU):
3030
row = []
31-
for j in range(self.rhino_surface.Points.CountV):
32-
row.append(point_to_compas(self.rhino_surface.Points.GetControlPoint(i, j).Location))
31+
for j in range(self.native_surface.Points.CountV):
32+
row.append(point_to_compas(self.native_surface.Points.GetControlPoint(i, j).Location))
3333
points.append(row)
3434
return points
3535

@@ -39,21 +39,21 @@ def __getitem__(self, index):
3939
except TypeError:
4040
return self.points[index]
4141
else:
42-
point = self.rhino_surface.Points.GetControlPoint(u, v).Location
42+
point = self.native_surface.Points.GetControlPoint(u, v).Location
4343
return point_to_compas(point)
4444

4545
def __setitem__(self, index, point):
4646
u, v = index
47-
self.rhino_surface.Points.SetControlPoint(u, v, Rhino.Geometry.ControlPoint(point_to_rhino(point)))
47+
self.native_surface.Points.SetControlPoint(u, v, Rhino.Geometry.ControlPoint(point_to_rhino(point)))
4848

4949
def __len__(self):
50-
return self.rhino_surface.Points.CountU
50+
return self.native_surface.Points.CountU
5151

5252
def __iter__(self):
5353
return iter(self.points)
5454

5555

56-
def rhino_surface_from_parameters(
56+
def native_surface_from_parameters(
5757
points,
5858
weights,
5959
knots_u,
@@ -72,7 +72,7 @@ def rhino_surface_from_parameters(
7272
is_rational = any(weight != 1.0 for weight in flatten(weights))
7373
dimensions = 3
7474

75-
rhino_surface = Rhino.Geometry.NurbsSurface.Create(
75+
native_surface = Rhino.Geometry.NurbsSurface.Create(
7676
dimensions,
7777
is_rational,
7878
order_u,
@@ -81,7 +81,7 @@ def rhino_surface_from_parameters(
8181
pointcount_v,
8282
)
8383

84-
if not rhino_surface:
84+
if not native_surface:
8585
message = "dimensions: {} is_rational: {} order_u: {} order_v: {} u_points: {} v_points: {}".format(
8686
dimensions,
8787
is_rational,
@@ -102,14 +102,14 @@ def rhino_surface_from_parameters(
102102
knotvector_v[:] = knotvector_v[1:-1]
103103
# add knots
104104
for index, knot in enumerate(knotvector_u):
105-
rhino_surface.KnotsU[index] = knot
105+
native_surface.KnotsU[index] = knot
106106
for index, knot in enumerate(knotvector_v):
107-
rhino_surface.KnotsV[index] = knot
107+
native_surface.KnotsV[index] = knot
108108
# add control points
109109
for i in range(pointcount_u):
110110
for j in range(pointcount_v):
111-
rhino_surface.Points.SetPoint(i, j, point_to_rhino(points[i][j]), weights[i][j])
112-
return rhino_surface
111+
native_surface.Points.SetPoint(i, j, point_to_rhino(points[i][j]), weights[i][j])
112+
return native_surface
113113

114114

115115
class RhinoNurbsSurface(RhinoSurface, NurbsSurface):
@@ -170,61 +170,61 @@ def __data__(self):
170170

171171
@property
172172
def points(self):
173-
if self.rhino_surface:
173+
if self.native_surface:
174174
if not hasattr(self, "_points"):
175-
self._points = ControlPoints(self.rhino_surface)
175+
self._points = ControlPoints(self.native_surface)
176176
return self._points
177177

178178
@property
179179
def weights(self):
180-
if self.rhino_surface:
180+
if self.native_surface:
181181
weights = []
182-
for i in range(self.rhino_surface.Points.CountU):
182+
for i in range(self.native_surface.Points.CountU):
183183
row = []
184-
for j in range(self.rhino_surface.Points.CountV):
185-
row.append(self.rhino_surface.Points.GetWeight(i, j))
184+
for j in range(self.native_surface.Points.CountV):
185+
row.append(self.native_surface.Points.GetWeight(i, j))
186186
weights.append(row)
187187
return weights
188188

189189
@property
190190
def knots_u(self):
191-
if self.rhino_surface:
192-
return [key for key, _ in groupby(self.rhino_surface.KnotsU)]
191+
if self.native_surface:
192+
return [key for key, _ in groupby(self.native_surface.KnotsU)]
193193

194194
@property
195195
def mults_u(self):
196-
if self.rhino_surface:
197-
return [len(list(group)) for _, group in groupby(self.rhino_surface.KnotsU)]
196+
if self.native_surface:
197+
return [len(list(group)) for _, group in groupby(self.native_surface.KnotsU)]
198198

199199
@property
200200
def knotvector_u(self):
201-
if self.rhino_surface:
202-
return list(self.rhino_surface.KnotsU)
201+
if self.native_surface:
202+
return list(self.native_surface.KnotsU)
203203

204204
@property
205205
def knots_v(self):
206-
if self.rhino_surface:
207-
return [key for key, _ in groupby(self.rhino_surface.KnotsV)]
206+
if self.native_surface:
207+
return [key for key, _ in groupby(self.native_surface.KnotsV)]
208208

209209
@property
210210
def mults_v(self):
211-
if self.rhino_surface:
212-
return [len(list(group)) for _, group in groupby(self.rhino_surface.KnotsV)]
211+
if self.native_surface:
212+
return [len(list(group)) for _, group in groupby(self.native_surface.KnotsV)]
213213

214214
@property
215215
def knotvector_v(self):
216-
if self.rhino_surface:
217-
return list(self.rhino_surface.KnotsV)
216+
if self.native_surface:
217+
return list(self.native_surface.KnotsV)
218218

219219
@property
220220
def degree_u(self):
221-
if self.rhino_surface:
222-
return self.rhino_surface.Degree(0)
221+
if self.native_surface:
222+
return self.native_surface.Degree(0)
223223

224224
@property
225225
def degree_v(self):
226-
if self.rhino_surface:
227-
return self.rhino_surface.Degree(1)
226+
if self.native_surface:
227+
return self.native_surface.Degree(1)
228228

229229
# ==============================================================================
230230
# Constructors
@@ -281,10 +281,8 @@ def from_fill(cls, curve1, curve2):
281281
:class:`compas_rhino.geometry.RhinoNurbsSurface`
282282
283283
"""
284-
surface = cls()
285-
# these curves probably need to be processed first
286-
surface.rhino_surface = Rhino.Geometry.NurbsSurface.CreateRuledSurface(curve1, curve2)
287-
return surface
284+
native_surface = Rhino.Geometry.NurbsSurface.CreateRuledSurface(curve1, curve2)
285+
return cls.from_native(native_surface)
288286

289287
@classmethod
290288
def from_frame(cls, frame, domain_u=(0, 1), domain_v=(0, 1), degree_u=1, degree_v=1, pointcount_u=2, pointcount_v=2):
@@ -316,8 +314,24 @@ def from_frame(cls, frame, domain_u=(0, 1), domain_v=(0, 1), degree_u=1, degree_
316314
plane = frame_to_rhino_plane(frame)
317315
du = Rhino.Geometry.Interval(*domain_u)
318316
dv = Rhino.Geometry.Interval(*domain_v)
319-
rhino_surface = Rhino.Geometry.NurbsSurface.CreateFromPlane(plane, du, dv, degree_u, degree_v, pointcount_u, pointcount_v)
320-
return cls.from_native(rhino_surface)
317+
native_surface = Rhino.Geometry.NurbsSurface.CreateFromPlane(plane, du, dv, degree_u, degree_v, pointcount_u, pointcount_v)
318+
return cls.from_native(native_surface)
319+
320+
@classmethod
321+
def from_native(cls, native_surface):
322+
"""Construct a NURBS surface from an existing Rhino surface.
323+
324+
Parameters
325+
----------
326+
native_surface : :rhino:`Rhino.Geometry.Surface`
327+
A Rhino surface.
328+
329+
Returns
330+
-------
331+
:class:`compas_rhino.geometry.RhinoNurbsSurface`
332+
333+
"""
334+
return cls(native_surface)
321335

322336
@classmethod
323337
def from_parameters(
@@ -359,9 +373,8 @@ def from_parameters(
359373
:class:`compas_rhino.geometry.RhinoNurbsSurface`
360374
361375
"""
362-
surface = cls()
363-
surface.rhino_surface = rhino_surface_from_parameters(points, weights, knots_u, knots_v, mults_u, mults_v, degree_u, degree_v)
364-
return surface
376+
native_surface = native_surface_from_parameters(points, weights, knots_u, knots_v, mults_u, mults_v, degree_u, degree_v)
377+
return cls.from_native(native_surface)
365378

366379
@classmethod
367380
def from_plane(cls, plane, domain_u=(0, 1), domain_v=(0, 1), degree_u=1, degree_v=1, pointcount_u=2, pointcount_v=2):
@@ -392,8 +405,8 @@ def from_plane(cls, plane, domain_u=(0, 1), domain_v=(0, 1), degree_u=1, degree_
392405
plane = plane_to_rhino(plane)
393406
du = Rhino.Geometry.Interval(*domain_u)
394407
dv = Rhino.Geometry.Interval(*domain_v)
395-
rhino_surface = Rhino.Geometry.NurbsSurface.CreateFromPlane(plane, du, dv, degree_u, degree_v, pointcount_u, pointcount_v)
396-
return cls.from_native(rhino_surface)
408+
native_surface = Rhino.Geometry.NurbsSurface.CreateFromPlane(plane, du, dv, degree_u, degree_v, pointcount_u, pointcount_v)
409+
return cls.from_native(native_surface)
397410

398411
@classmethod
399412
def from_points(cls, points, degree_u=3, degree_v=3):
@@ -420,9 +433,8 @@ def from_points(cls, points, degree_u=3, degree_v=3):
420433
pointcount_u = len(points)
421434
pointcount_v = len(points[0])
422435
points[:] = [point_to_rhino(point) for row in points for point in row]
423-
surface = cls()
424-
surface.rhino_surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(points, pointcount_u, pointcount_v, degree_u, degree_v)
425-
return surface
436+
native_surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(points, pointcount_u, pointcount_v, degree_u, degree_v)
437+
return cls.from_native(native_surface)
426438

427439
@classmethod
428440
def from_sphere(cls, sphere):

0 commit comments

Comments
 (0)