Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ce1c36a51 | |||
| 6f56ecb0c0 | |||
| ef5a570dd4 | |||
| 424d7d9caf | |||
| 6aa643837a | |||
| 32cbb33e10 |
+2
-5
@@ -6,7 +6,7 @@ services:
|
||||
# Speckle Server dependencies
|
||||
#######
|
||||
postgres:
|
||||
image: "postgres:16-alpine"
|
||||
image: "postgres:16.4-alpine3.20@sha256:d898b0b78a2627cb4ee63464a14efc9d296884f1b28c841b0ab7d7c42f1fffdf"
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_DB: speckle
|
||||
@@ -49,10 +49,6 @@ services:
|
||||
retries: 30
|
||||
start_period: 10s
|
||||
|
||||
####
|
||||
# Speckle Server
|
||||
#######
|
||||
|
||||
speckle-server:
|
||||
image: speckle/speckle-server:latest
|
||||
restart: always
|
||||
@@ -79,6 +75,7 @@ services:
|
||||
# TODO: Change this to the URL of the speckle server, as accessed from the network
|
||||
CANONICAL_URL: "http://127.0.0.1:8080"
|
||||
SPECKLE_AUTOMATE_URL: "http://127.0.0.1:3030"
|
||||
FRONTEND_ORIGIN: "http://127.0.0.1:8081"
|
||||
|
||||
# TODO: Change thvolumes:
|
||||
REDIS_URL: "redis://redis"
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ ignore = ["UP006", "UP007", "UP035"]
|
||||
[[tool.uv.index]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple/"
|
||||
publish-url = "https://pypi.org/legacy/"
|
||||
publish-url = "https://upload.pypi.org/legacy/"
|
||||
|
||||
[[tool.uv.index]]
|
||||
name = "test"
|
||||
|
||||
@@ -49,9 +49,8 @@ class Mesh(
|
||||
|
||||
if len(self.vertices) % 3 != 0:
|
||||
raise ValueError(
|
||||
f"Invalid vertices list: length ({
|
||||
len(self.vertices)
|
||||
}) must be a multiple of 3"
|
||||
f"Invalid vertices list: length {len(self.vertices)} "
|
||||
f"must be a multiple of 3"
|
||||
)
|
||||
return len(self.vertices) // 3
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import List
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry.point import Point
|
||||
from specklepy.objects.interfaces import ICurve, IHasUnits
|
||||
from specklepy.objects.models.units import Units
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
@@ -13,24 +14,28 @@ class Polyline(Base, IHasUnits, ICurve, speckle_type="Objects.Geometry.Polyline"
|
||||
"""
|
||||
|
||||
value: List[float]
|
||||
closed: bool = False
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.__class__.__name__}(value: {self.value}, units: {self.units})"
|
||||
return (
|
||||
f"{self.__class__.__name__}("
|
||||
f"value: {self.value}, "
|
||||
f"closed: {self.closed}, "
|
||||
f"units: {self.units})"
|
||||
)
|
||||
|
||||
def is_closed(self, tolerance: float = 1e-6) -> bool:
|
||||
@staticmethod
|
||||
def is_closed(points: List[float], tolerance: float = 1e-6) -> bool:
|
||||
"""
|
||||
check if the polyline is closed (start point equals end point within tolerance)
|
||||
check if the polyline is closed
|
||||
"""
|
||||
if len(self.value) < 6: # need at least 2 points to be closed
|
||||
if len(points) < 6: # need at least 2 points to be closed
|
||||
return False
|
||||
|
||||
# compare first and last points
|
||||
start = Point(
|
||||
x=self.value[0], y=self.value[1], z=self.value[2], units=self.units
|
||||
)
|
||||
end = Point(
|
||||
x=self.value[-3], y=self.value[-2], z=self.value[-1], units=self.units
|
||||
)
|
||||
start = Point(x=points[0], y=points[1], z=points[2], units=Units.m)
|
||||
end = Point(x=points[-3], y=points[-2], z=points[-1], units=Units.m)
|
||||
|
||||
return start.distance_to(end) <= tolerance
|
||||
|
||||
@property
|
||||
@@ -46,7 +51,7 @@ class Polyline(Base, IHasUnits, ICurve, speckle_type="Objects.Geometry.Polyline"
|
||||
total_length = 0.0
|
||||
for i in range(len(points) - 1):
|
||||
total_length += points[i].distance_to(points[i + 1])
|
||||
if self.is_closed() and points:
|
||||
if self.closed and points:
|
||||
total_length += points[-1].distance_to(points[0])
|
||||
return total_length
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from specklepy.objects.other import RenderMaterial
|
||||
@dataclass(kw_only=True)
|
||||
class ColorProxy(
|
||||
Base,
|
||||
speckle_type="Models.Proxies.ColorProxy",
|
||||
speckle_type="Speckle.Core.Models.Proxies.ColorProxy",
|
||||
detachable={"objects"},
|
||||
):
|
||||
objects: List[str]
|
||||
@@ -20,7 +20,7 @@ class ColorProxy(
|
||||
@dataclass(kw_only=True)
|
||||
class GroupProxy(
|
||||
Base,
|
||||
speckle_type="Models.Proxies.GroupProxy",
|
||||
speckle_type="Speckle.Core.Models.Proxies.GroupProxy",
|
||||
detachable={"objects"},
|
||||
):
|
||||
objects: List[str]
|
||||
@@ -31,7 +31,7 @@ class GroupProxy(
|
||||
class InstanceProxy(
|
||||
Base,
|
||||
IHasUnits,
|
||||
speckle_type="Models.Proxies.InstanceProxy",
|
||||
speckle_type="Speckle.Core.Models.Instances.InstanceProxy",
|
||||
):
|
||||
definition_id: str
|
||||
transform: List[float]
|
||||
@@ -41,7 +41,7 @@ class InstanceProxy(
|
||||
@dataclass(kw_only=True)
|
||||
class InstanceDefinitionProxy(
|
||||
Base,
|
||||
speckle_type="Models.Proxies.InstanceDefinitionProxy",
|
||||
speckle_type="Speckle.Core.Models.Instances.InstanceDefinitionProxy",
|
||||
detachable={"objects"},
|
||||
):
|
||||
objects: List[str]
|
||||
|
||||
@@ -54,6 +54,7 @@ def test_polyline_creation(open_square_coords):
|
||||
polyline = Polyline(value=open_square_coords, units=Units.m)
|
||||
assert polyline.value == open_square_coords
|
||||
assert polyline.units == Units.m.value
|
||||
assert polyline.closed is False
|
||||
|
||||
|
||||
def test_polyline_domain(sample_polyline):
|
||||
@@ -63,23 +64,31 @@ def test_polyline_domain(sample_polyline):
|
||||
|
||||
|
||||
def test_polyline_is_closed(open_square_coords, closed_square_coords):
|
||||
open_poly = Polyline(value=open_square_coords, units=Units.m)
|
||||
closed_poly = Polyline(value=closed_square_coords, units=Units.m)
|
||||
# Test the static method
|
||||
assert not Polyline.is_closed(open_square_coords)
|
||||
assert Polyline.is_closed(closed_square_coords)
|
||||
|
||||
assert not open_poly.is_closed()
|
||||
assert closed_poly.is_closed()
|
||||
# Test with closed flag
|
||||
open_poly = Polyline(value=open_square_coords, units=Units.m)
|
||||
closed_poly = Polyline(value=closed_square_coords, units=Units.m, closed=True)
|
||||
assert not open_poly.closed
|
||||
assert closed_poly.closed
|
||||
|
||||
|
||||
def test_polyline_is_closed_with_tolerance(open_square_coords):
|
||||
almost_closed = open_square_coords + [
|
||||
0.0,
|
||||
0.0,
|
||||
0.001,
|
||||
] # last point slightly above start
|
||||
poly = Polyline(value=almost_closed, units=Units.m)
|
||||
0.001, # last point slightly above start
|
||||
]
|
||||
# Test static method with tolerance
|
||||
assert not Polyline.is_closed(almost_closed, tolerance=1e-6)
|
||||
assert Polyline.is_closed(almost_closed, tolerance=0.01)
|
||||
|
||||
assert not poly.is_closed(tolerance=1e-6)
|
||||
assert poly.is_closed(tolerance=0.01)
|
||||
# Also test with instance
|
||||
poly = Polyline(value=almost_closed, units=Units.m)
|
||||
# poly.closed should reflect what was passed in construction, not computed
|
||||
assert not poly.closed
|
||||
|
||||
|
||||
def test_polyline_length_open(sample_polyline):
|
||||
@@ -88,14 +97,13 @@ def test_polyline_length_open(sample_polyline):
|
||||
|
||||
|
||||
def test_polyline_length_closed(closed_square_coords):
|
||||
polyline = Polyline(value=closed_square_coords, units=Units.m)
|
||||
polyline = Polyline(value=closed_square_coords, units=Units.m, closed=True)
|
||||
polyline.length = polyline.calculate_length()
|
||||
assert polyline.length == 4.0
|
||||
|
||||
|
||||
def test_polyline_get_points(sample_polyline):
|
||||
points = sample_polyline.get_points()
|
||||
|
||||
assert len(points) == 4
|
||||
assert all(isinstance(p, Point) for p in points)
|
||||
assert all(p.units == Units.m.value for p in points)
|
||||
@@ -125,16 +133,25 @@ def test_polyline_invalid_coordinates():
|
||||
def test_polyline_units(open_square_coords):
|
||||
polyline = Polyline(value=open_square_coords, units=Units.m)
|
||||
assert polyline.units == Units.m.value
|
||||
|
||||
polyline.units = "mm"
|
||||
assert polyline.units == "mm"
|
||||
|
||||
|
||||
def test_polyline_closed_flag(open_square_coords, closed_square_coords):
|
||||
# Test default value
|
||||
poly1 = Polyline(value=open_square_coords, units=Units.m)
|
||||
assert poly1.closed is False
|
||||
|
||||
# Test explicit value
|
||||
poly2 = Polyline(value=closed_square_coords, units=Units.m, closed=True)
|
||||
assert poly2.closed is True
|
||||
|
||||
|
||||
def test_polyline_serialization(sample_polyline):
|
||||
serialized = serialize(sample_polyline)
|
||||
deserialized = deserialize(serialized)
|
||||
|
||||
assert deserialized.value == sample_polyline.value
|
||||
assert deserialized.units == sample_polyline.units
|
||||
assert deserialized.domain.start == sample_polyline.domain.start
|
||||
assert deserialized.domain.end == sample_polyline.domain.end
|
||||
assert deserialized.closed == sample_polyline.closed
|
||||
|
||||
Reference in New Issue
Block a user