@@ -2,6 +2,7 @@ from .arc import Arc
|
||||
from .box import Box
|
||||
from .circle import Circle
|
||||
from .control_point import ControlPoint
|
||||
from .curve import Curve
|
||||
from .ellipse import Ellipse
|
||||
from .line import Line
|
||||
from .mesh import Mesh
|
||||
@@ -33,4 +34,5 @@ __all__ = [
|
||||
"Polycurve",
|
||||
"Spiral",
|
||||
"Surface",
|
||||
"Curve",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry.box import Box
|
||||
from specklepy.objects.geometry.polyline import Polyline
|
||||
from specklepy.objects.interfaces import ICurve, IHasArea, IHasUnits
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Curve(
|
||||
Base,
|
||||
ICurve,
|
||||
IHasArea,
|
||||
IHasUnits,
|
||||
speckle_type="Objects.Geometry.Curve",
|
||||
detachable={"points", "weights", "knots", "displayValue"},
|
||||
chunkable={"points": 31250, "weights": 31250, "knots": 31250},
|
||||
):
|
||||
"""
|
||||
a NURBS curve
|
||||
"""
|
||||
|
||||
degree: int
|
||||
periodic: bool
|
||||
rational: bool
|
||||
points: List[float]
|
||||
weights: List[float]
|
||||
knots: List[float]
|
||||
closed: bool
|
||||
displayValue: Polyline
|
||||
bbox: Optional[Box] = None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"{self.__class__.__name__}("
|
||||
f"degree: {self.degree}, "
|
||||
f"periodic: {self.periodic}, "
|
||||
f"rational: {self.rational}, "
|
||||
f"closed: {self.closed}, "
|
||||
f"units: {self.units})"
|
||||
)
|
||||
|
||||
@property
|
||||
def length(self) -> float:
|
||||
return self.__dict__.get("_length", 0.0)
|
||||
|
||||
@length.setter
|
||||
def length(self, value: float) -> None:
|
||||
self.__dict__["_length"] = value
|
||||
|
||||
@property
|
||||
def area(self) -> float:
|
||||
return self.__dict__.get("_area", 0.0)
|
||||
|
||||
@area.setter
|
||||
def area(self, value: float) -> None:
|
||||
self.__dict__["_area"] = value
|
||||
@@ -0,0 +1,158 @@
|
||||
import pytest
|
||||
|
||||
from specklepy.core.api.operations import deserialize, serialize
|
||||
from specklepy.objects.geometry import Curve, Plane, Point, Polyline, Vector
|
||||
from specklepy.objects.models.units import Units
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_polyline():
|
||||
"""
|
||||
sample polyline
|
||||
"""
|
||||
return Polyline(value=[0, 0, 0, 1, 0, 0, 1, 1, 0], units=Units.m)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_plane():
|
||||
"""
|
||||
sample plane for bbox creation
|
||||
"""
|
||||
origin = Point(x=0, y=0, z=0, units=Units.m)
|
||||
normal = Vector(x=0, y=0, z=1, units=Units.m)
|
||||
xdir = Vector(x=1, y=0, z=0, units=Units.m)
|
||||
ydir = Vector(x=0, y=1, z=0, units=Units.m)
|
||||
return Plane(origin=origin, normal=normal, xdir=xdir, ydir=ydir, units=Units.m)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_curve(sample_polyline):
|
||||
"""
|
||||
sample curve for testing
|
||||
"""
|
||||
return Curve(
|
||||
degree=3,
|
||||
periodic=False,
|
||||
rational=False,
|
||||
points=[0, 0, 0, 1, 1, 0, 2, 0, 0, 3, 1, 0],
|
||||
weights=[1, 1, 1, 1],
|
||||
knots=[0, 0, 0, 0, 1, 1, 1, 1],
|
||||
closed=False,
|
||||
displayValue=sample_polyline,
|
||||
units=Units.m,
|
||||
)
|
||||
|
||||
|
||||
def test_curve_creation(sample_polyline):
|
||||
"""
|
||||
test curve initialization
|
||||
"""
|
||||
curve = Curve(
|
||||
degree=3,
|
||||
periodic=False,
|
||||
rational=False,
|
||||
points=[0, 0, 0, 1, 1, 0, 2, 0, 0, 3, 1, 0],
|
||||
weights=[1, 1, 1, 1],
|
||||
knots=[0, 0, 0, 0, 1, 1, 1, 1],
|
||||
closed=False,
|
||||
displayValue=sample_polyline,
|
||||
units=Units.m,
|
||||
)
|
||||
|
||||
assert curve.degree == 3
|
||||
assert curve.periodic is False
|
||||
assert curve.rational is False
|
||||
assert curve.points == [0, 0, 0, 1, 1, 0, 2, 0, 0, 3, 1, 0]
|
||||
assert curve.weights == [1, 1, 1, 1]
|
||||
assert curve.knots == [0, 0, 0, 0, 1, 1, 1, 1]
|
||||
assert curve.closed is False
|
||||
assert curve.units == Units.m.value
|
||||
assert curve.displayValue == sample_polyline
|
||||
|
||||
|
||||
def test_length_property(sample_polyline):
|
||||
"""
|
||||
test the length property setter and getter
|
||||
"""
|
||||
curve = Curve(
|
||||
degree=1,
|
||||
periodic=False,
|
||||
rational=False,
|
||||
points=[0, 0, 0, 1, 0, 0],
|
||||
weights=[1, 1],
|
||||
knots=[0, 0, 1, 1],
|
||||
closed=False,
|
||||
displayValue=sample_polyline,
|
||||
units=Units.m,
|
||||
)
|
||||
|
||||
assert curve.length == 0.0
|
||||
|
||||
curve.length = 1.5
|
||||
assert curve.length == 1.5
|
||||
|
||||
|
||||
def test_area_property(sample_polyline):
|
||||
"""
|
||||
test the area property setter and getter
|
||||
"""
|
||||
polyline = Polyline(
|
||||
value=[0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0], units=Units.m
|
||||
)
|
||||
|
||||
curve = Curve(
|
||||
degree=1,
|
||||
periodic=False,
|
||||
rational=False,
|
||||
points=[0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0],
|
||||
weights=[1, 1, 1, 1, 1],
|
||||
knots=[0, 0, 1, 2, 3, 4, 4],
|
||||
closed=True,
|
||||
displayValue=polyline,
|
||||
units=Units.m,
|
||||
)
|
||||
|
||||
assert curve.area == 0.0
|
||||
|
||||
curve.area = 1.0
|
||||
assert curve.area == 1.0
|
||||
|
||||
|
||||
def test_curve_serialization(sample_curve):
|
||||
"""
|
||||
test serialization and deserialization of the curve
|
||||
"""
|
||||
serialized = serialize(sample_curve)
|
||||
deserialized = deserialize(serialized)
|
||||
|
||||
assert deserialized.degree == sample_curve.degree
|
||||
assert deserialized.periodic == sample_curve.periodic
|
||||
assert deserialized.rational == sample_curve.rational
|
||||
assert deserialized.points == sample_curve.points
|
||||
assert deserialized.weights == sample_curve.weights
|
||||
assert deserialized.knots == sample_curve.knots
|
||||
assert deserialized.closed == sample_curve.closed
|
||||
assert deserialized.units == sample_curve.units
|
||||
|
||||
|
||||
@pytest.mark.parametrize("new_units", ["mm", "cm", "in"])
|
||||
def test_curve_units(sample_polyline, new_units):
|
||||
"""
|
||||
test changing units of a curve
|
||||
"""
|
||||
curve = Curve(
|
||||
degree=3,
|
||||
periodic=False,
|
||||
rational=False,
|
||||
points=[0, 0, 0, 1, 1, 0, 2, 0, 0, 3, 1, 0],
|
||||
weights=[1, 1, 1, 1],
|
||||
knots=[0, 0, 0, 0, 1, 1, 1, 1],
|
||||
closed=False,
|
||||
displayValue=sample_polyline,
|
||||
units=Units.m,
|
||||
)
|
||||
|
||||
assert curve.units == Units.m.value
|
||||
|
||||
curve.units = new_units
|
||||
assert curve.units == new_units
|
||||
Reference in New Issue
Block a user