|
7 | 7 | import Rhino.Geometry # type: ignore |
8 | 8 |
|
9 | 9 | from compas.geometry import NurbsSurface |
10 | | -from compas.geometry import Point |
11 | 10 | from compas.geometry import knots_and_mults_to_knotvector |
12 | 11 | from compas.itertools import flatten |
| 12 | +from compas_rhino.conversions import cylinder_to_rhino |
| 13 | +from compas_rhino.conversions import frame_to_rhino_plane |
| 14 | +from compas_rhino.conversions import plane_to_rhino |
13 | 15 | from compas_rhino.conversions import point_to_compas |
14 | 16 | from compas_rhino.conversions import point_to_rhino |
| 17 | +from compas_rhino.conversions import sphere_to_rhino |
15 | 18 |
|
16 | 19 | from .surface import RhinoSurface |
17 | 20 |
|
@@ -133,10 +136,6 @@ class RhinoNurbsSurface(RhinoSurface, NurbsSurface): |
133 | 136 |
|
134 | 137 | """ |
135 | 138 |
|
136 | | - def __init__(self, name=None): |
137 | | - super(RhinoNurbsSurface, self).__init__(name=name) |
138 | | - self._points = None |
139 | | - |
140 | 139 | # ============================================================================== |
141 | 140 | # Data |
142 | 141 | # ============================================================================== |
@@ -165,52 +164,14 @@ def __data__(self): |
165 | 164 | "is_periodic_v": self.is_periodic_v, |
166 | 165 | } |
167 | 166 |
|
168 | | - @classmethod |
169 | | - def __from_data__(cls, data): |
170 | | - """Construct a BSpline surface from its data representation. |
171 | | -
|
172 | | - Parameters |
173 | | - ---------- |
174 | | - data : dict |
175 | | - The data dictionary. |
176 | | -
|
177 | | - Returns |
178 | | - ------- |
179 | | - :class:`compas_rhino.geometry.RhinoNurbsSurface` |
180 | | - The constructed surface. |
181 | | -
|
182 | | - """ |
183 | | - points = [[Point.__from_data__(point) for point in row] for row in data["points"]] |
184 | | - weights = data["weights"] |
185 | | - knots_u = data["knots_u"] |
186 | | - knots_v = data["knots_v"] |
187 | | - mults_u = data["mults_u"] |
188 | | - mults_v = data["mults_v"] |
189 | | - degree_u = data["degree_u"] |
190 | | - degree_v = data["degree_v"] |
191 | | - is_periodic_u = data["is_periodic_u"] |
192 | | - is_periodic_v = data["is_periodic_v"] |
193 | | - return cls.from_parameters( |
194 | | - points, |
195 | | - weights, |
196 | | - knots_u, |
197 | | - knots_v, |
198 | | - mults_u, |
199 | | - mults_v, |
200 | | - degree_u, |
201 | | - degree_v, |
202 | | - is_periodic_u, |
203 | | - is_periodic_v, |
204 | | - ) |
205 | | - |
206 | 167 | # ============================================================================== |
207 | 168 | # Properties |
208 | 169 | # ============================================================================== |
209 | 170 |
|
210 | 171 | @property |
211 | 172 | def points(self): |
212 | 173 | if self.rhino_surface: |
213 | | - if not self._points: |
| 174 | + if not hasattr(self, "_points"): |
214 | 175 | self._points = ControlPoints(self.rhino_surface) |
215 | 176 | return self._points |
216 | 177 |
|
@@ -269,6 +230,95 @@ def degree_v(self): |
269 | 230 | # Constructors |
270 | 231 | # ============================================================================== |
271 | 232 |
|
| 233 | + @classmethod |
| 234 | + def from_corners(cls, corners): |
| 235 | + """Creates a NURBS surface using the given 4 corners. |
| 236 | +
|
| 237 | + The order of the given points determins the normal direction of the generated surface. |
| 238 | +
|
| 239 | + Parameters |
| 240 | + ---------- |
| 241 | + corners : list(:class:`compas.geometry.Point`) |
| 242 | + 4 points in 3d space to represent the corners of the planar surface. |
| 243 | +
|
| 244 | + Returns |
| 245 | + ------- |
| 246 | + :class:`compas_rhino.geometry.RhinoNurbsSurface` |
| 247 | +
|
| 248 | + """ |
| 249 | + rhino_points = [Rhino.Geometry.Point3d(corner.x, corner.y, corner.z) for corner in corners] |
| 250 | + return cls.from_native(Rhino.Geometry.NurbsSurface.CreateFromCorners(*rhino_points)) |
| 251 | + |
| 252 | + @classmethod |
| 253 | + def from_cylinder(cls, cylinder): |
| 254 | + """Create a NURBS surface from a cylinder. |
| 255 | +
|
| 256 | + Parameters |
| 257 | + ---------- |
| 258 | + cylinder : :class:`compas.geometry.Cylinder` |
| 259 | + The surface's geometry. |
| 260 | +
|
| 261 | + Returns |
| 262 | + ------- |
| 263 | + :class:`compas_rhino.geometry.RhinoNurbsSurface` |
| 264 | +
|
| 265 | + """ |
| 266 | + cylinder = cylinder_to_rhino(cylinder) |
| 267 | + surface = Rhino.Geometry.NurbsSurface.CreateFromCylinder(cylinder) |
| 268 | + return cls.from_native(surface) |
| 269 | + |
| 270 | + @classmethod |
| 271 | + def from_fill(cls, curve1, curve2): |
| 272 | + """Construct a NURBS surface from the infill between two NURBS curves. |
| 273 | +
|
| 274 | + Parameters |
| 275 | + ---------- |
| 276 | + curve1 : :class:`compas.geometry.NurbsCurve` |
| 277 | + curve2 : :class:`compas.geometry.NurbsCurve` |
| 278 | +
|
| 279 | + Returns |
| 280 | + ------- |
| 281 | + :class:`compas_rhino.geometry.RhinoNurbsSurface` |
| 282 | +
|
| 283 | + """ |
| 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 |
| 288 | + |
| 289 | + @classmethod |
| 290 | + 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): |
| 291 | + """Creates a planar surface from a frame and parametric domain information. |
| 292 | +
|
| 293 | + Parameters |
| 294 | + ---------- |
| 295 | + frame : :class:`compas.geometry.Frame` |
| 296 | + A frame with point at the center of the wanted plannar surface and |
| 297 | + x and y axes the direction of u and v respectively. |
| 298 | + domain_u : tuple[int, int], optional |
| 299 | + The domain of the U parameter. |
| 300 | + domain_v : tuple[int, int], optional |
| 301 | + The domain of the V parameter. |
| 302 | + degree_u : int, optional |
| 303 | + Degree in the U direction. |
| 304 | + degree_v : int, optional |
| 305 | + Degree in the V direction. |
| 306 | + pointcount_u : int, optional |
| 307 | + Number of control points in the U direction. |
| 308 | + pointcount_v : int, optional |
| 309 | + Number of control points in the V direction. |
| 310 | +
|
| 311 | + Returns |
| 312 | + ------- |
| 313 | + :class:`compas_rhino.geometry.RhinoNurbsSurface` |
| 314 | +
|
| 315 | + """ |
| 316 | + plane = frame_to_rhino_plane(frame) |
| 317 | + du = Rhino.Geometry.Interval(*domain_u) |
| 318 | + 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) |
| 321 | + |
272 | 322 | @classmethod |
273 | 323 | def from_parameters( |
274 | 324 | cls, |
@@ -313,6 +363,38 @@ def from_parameters( |
313 | 363 | surface.rhino_surface = rhino_surface_from_parameters(points, weights, knots_u, knots_v, mults_u, mults_v, degree_u, degree_v) |
314 | 364 | return surface |
315 | 365 |
|
| 366 | + @classmethod |
| 367 | + 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): |
| 368 | + """Construct a surface from a plane. |
| 369 | +
|
| 370 | + Parameters |
| 371 | + ---------- |
| 372 | + plane : :class:`compas.geometry.Plane` |
| 373 | + The plane. |
| 374 | + domain_u : tuple[int, int], optional |
| 375 | + The domain of the U parameter. |
| 376 | + domain_v : tuple[int, int], optional |
| 377 | + The domain of the V parameter. |
| 378 | + degree_u : int, optional |
| 379 | + Degree in the U direction. |
| 380 | + degree_v : int, optional |
| 381 | + Degree in the V direction. |
| 382 | + pointcount_u : int, optional |
| 383 | + Number of control points in the U direction. |
| 384 | + pointcount_v : int, optional |
| 385 | + Number of control points in the V direction. |
| 386 | +
|
| 387 | + Returns |
| 388 | + ------- |
| 389 | + :class:`compas_rhino.geometry.RhinoNurbsSurface` |
| 390 | +
|
| 391 | + """ |
| 392 | + plane = plane_to_rhino(plane) |
| 393 | + du = Rhino.Geometry.Interval(*domain_u) |
| 394 | + 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) |
| 397 | + |
316 | 398 | @classmethod |
317 | 399 | def from_points(cls, points, degree_u=3, degree_v=3): |
318 | 400 | """Construct a NURBS surface from control points. |
@@ -343,23 +425,38 @@ def from_points(cls, points, degree_u=3, degree_v=3): |
343 | 425 | return surface |
344 | 426 |
|
345 | 427 | @classmethod |
346 | | - def from_fill(cls, curve1, curve2): |
347 | | - """Construct a NURBS surface from the infill between two NURBS curves. |
| 428 | + def from_sphere(cls, sphere): |
| 429 | + """Creates a NURBS surface from a sphere. |
348 | 430 |
|
349 | 431 | Parameters |
350 | 432 | ---------- |
351 | | - curve1 : :class:`compas.geometry.NurbsCurve` |
352 | | - curve2 : :class:`compas.geometry.NurbsCurve` |
| 433 | + sphere : :class:`compas.geometry.Sphere` |
| 434 | + The surface's geometry. |
353 | 435 |
|
354 | 436 | Returns |
355 | 437 | ------- |
356 | 438 | :class:`compas_rhino.geometry.RhinoNurbsSurface` |
357 | 439 |
|
358 | 440 | """ |
359 | | - surface = cls() |
360 | | - # these curves probably need to be processed first |
361 | | - surface.rhino_surface = Rhino.Geometry.NurbsSurface.CreateRuledSurface(curve1, curve2) |
362 | | - return surface |
| 441 | + sphere = sphere_to_rhino(sphere) |
| 442 | + surface = Rhino.Geometry.NurbsSurface.CreateFromSphere(sphere) |
| 443 | + return cls.from_native(surface) |
| 444 | + |
| 445 | + @classmethod |
| 446 | + def from_torus(cls, torus): |
| 447 | + """Create a NURBS surface from a torus. |
| 448 | +
|
| 449 | + Parameters |
| 450 | + ---------- |
| 451 | + torus : :class:`compas.geometry.Torus` |
| 452 | + The surface's geometry. |
| 453 | +
|
| 454 | + Returns |
| 455 | + ------- |
| 456 | + :class:`compas_rhino.geometry.RhinoNurbsSurface` |
| 457 | +
|
| 458 | + """ |
| 459 | + raise NotImplementedError |
363 | 460 |
|
364 | 461 | # ============================================================================== |
365 | 462 | # Conversions |
|
0 commit comments