to_list and from_list updated
This commit is contained in:
@@ -1,12 +1,17 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Tuple
|
||||
from typing import List, Tuple, Any
|
||||
import math
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry.point import Point
|
||||
from specklepy.objects.geometry.plane import Plane
|
||||
from specklepy.objects.geometry.vector import Vector
|
||||
from specklepy.objects.interfaces import ICurve, IHasUnits, ITransformable
|
||||
from specklepy.objects.primitive import Interval
|
||||
from specklepy.objects.models.units import (
|
||||
get_encoding_from_units,
|
||||
get_units_from_encoding
|
||||
)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
@@ -54,40 +59,80 @@ class Arc(Base, IHasUnits, ICurve, ITransformable, speckle_type="Objects.Geometr
|
||||
)
|
||||
return True, transformed
|
||||
|
||||
def to_list(self) -> List[float]:
|
||||
from specklepy.objects.models.units import get_encoding_from_units
|
||||
|
||||
def to_list(self) -> List[Any]:
|
||||
"""
|
||||
returns a serializable list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
radius, measure,
|
||||
domain_start, domain_end,
|
||||
plane_origin_x, plane_origin_y, plane_origin_z,
|
||||
plane_normal_x, plane_normal_y, plane_normal_z,
|
||||
plane_xdir_x, plane_xdir_y, plane_xdir_z,
|
||||
plane_ydir_x, plane_ydir_y, plane_ydir_z,
|
||||
start_x, start_y, start_z,
|
||||
mid_x, mid_y, mid_z,
|
||||
end_x, end_y, end_z]
|
||||
"""
|
||||
result = []
|
||||
result.append(self.radius)
|
||||
result.append(0)
|
||||
result.append(0)
|
||||
result.append(self.measure)
|
||||
result.append(self.domain.start)
|
||||
result.append(self.domain.end)
|
||||
result.extend(self.plane.to_list())
|
||||
result.extend(self.startPoint.to_list())
|
||||
result.extend(self.midPoint.to_list())
|
||||
result.extend(self.endPoint.to_list())
|
||||
result.append(get_encoding_from_units(self.units))
|
||||
result.extend([self.radius, self.measure])
|
||||
result.extend([self.domain.start, self.domain.end])
|
||||
# skip length, type, units from Plane
|
||||
result.extend(self.plane.to_list()[3:])
|
||||
# skip length, type, units from Point
|
||||
result.extend(self.startPoint.to_list()[3:])
|
||||
# skip length, type, units from Point
|
||||
result.extend(self.midPoint.to_list()[3:])
|
||||
# skip length, type, units from Point
|
||||
result.extend(self.endPoint.to_list()[3:])
|
||||
|
||||
result.insert(0, 1)
|
||||
result.insert(0, len(result))
|
||||
# add header information
|
||||
result.insert(0, get_encoding_from_units(self.units))
|
||||
result.insert(0, self.speckle_type)
|
||||
result.insert(0, len(result) + 1)
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, coords: List[float]) -> "Arc":
|
||||
from specklepy.objects.models.units import get_units_from_encoding
|
||||
def from_list(cls, coords: List[Any]) -> "Arc":
|
||||
"""
|
||||
creates an Arc from a list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
radius, measure,
|
||||
domain_start, domain_end,
|
||||
plane_origin_x, plane_origin_y, plane_origin_z,
|
||||
plane_normal_x, plane_normal_y, plane_normal_z,
|
||||
plane_xdir_x, plane_xdir_y, plane_xdir_z,
|
||||
plane_ydir_x, plane_ydir_y, plane_ydir_z,
|
||||
start_x, start_y, start_z,
|
||||
mid_x, mid_y, mid_z,
|
||||
end_x, end_y, end_z]
|
||||
"""
|
||||
units = get_units_from_encoding(coords[2])
|
||||
|
||||
units = get_units_from_encoding(int(coords[-1]))
|
||||
domain = Interval(start=coords[5], end=coords[6])
|
||||
|
||||
arc = cls(
|
||||
domain=Interval(start=coords[6], end=coords[7]),
|
||||
units=units,
|
||||
plane=Plane.from_list(coords[8:21]),
|
||||
startPoint=Point.from_list(coords[21:24], units),
|
||||
midPoint=Point.from_list(coords[24:27], units),
|
||||
endPoint=Point.from_list(coords[27:30], units)
|
||||
# extract plane components
|
||||
plane = Plane(
|
||||
origin=Point(x=coords[7], y=coords[8], z=coords[9], units=units),
|
||||
normal=Vector(x=coords[10], y=coords[11],
|
||||
z=coords[12], units=units),
|
||||
xdir=Vector(x=coords[13], y=coords[14], z=coords[15], units=units),
|
||||
ydir=Vector(x=coords[16], y=coords[17], z=coords[18], units=units),
|
||||
units=units
|
||||
)
|
||||
|
||||
arc.plane.units = arc.units
|
||||
return arc
|
||||
# extract points
|
||||
start_point = Point(
|
||||
x=coords[19], y=coords[20], z=coords[21], units=units)
|
||||
mid_point = Point(x=coords[22], y=coords[23],
|
||||
z=coords[24], units=units)
|
||||
end_point = Point(x=coords[25], y=coords[26],
|
||||
z=coords[27], units=units)
|
||||
|
||||
return cls(
|
||||
plane=plane,
|
||||
startPoint=start_point,
|
||||
midPoint=mid_point,
|
||||
endPoint=end_point,
|
||||
domain=domain,
|
||||
units=units
|
||||
)
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Tuple
|
||||
from typing import List, Tuple, Any
|
||||
|
||||
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
|
||||
from specklepy.objects.primitive import Interval
|
||||
from specklepy.objects.models.units import (
|
||||
Units,
|
||||
get_encoding_from_units
|
||||
)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
@@ -29,23 +32,53 @@ class Line(Base, IHasUnits, ICurve, speckle_type="Objects.Geometry.Line"):
|
||||
def _domain(self) -> Interval:
|
||||
return self.domain
|
||||
|
||||
def to_list(self) -> List[float]:
|
||||
def to_list(self) -> List[Any]:
|
||||
"""
|
||||
returns a serializable list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
start_x, start_y, start_z,
|
||||
end_x, end_y, end_z,
|
||||
domain_start, domain_end]
|
||||
"""
|
||||
result = []
|
||||
result.extend(self.start.to_list())
|
||||
result.extend(self.end.to_list())
|
||||
# skip length, type, units from Point
|
||||
result.extend(self.start.to_list()[3:])
|
||||
# skip length, type, units from Point
|
||||
result.extend(self.end.to_list()[3:])
|
||||
result.extend([self.domain.start, self.domain.end])
|
||||
|
||||
# add header information
|
||||
result.insert(0, get_encoding_from_units(self.units))
|
||||
result.insert(0, self.speckle_type)
|
||||
result.insert(0, len(result) + 1) # +1 for the length we're adding
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, coords: List[float], units: str | Units) -> "Line":
|
||||
if len(coords) < 6:
|
||||
raise ValueError(
|
||||
"Line from coordinate array requires 6 coordinates.")
|
||||
|
||||
start = Point(x=coords[0], y=coords[1], z=coords[2], units=units)
|
||||
end = Point(x=coords[3], y=coords[4], z=coords[5], units=units)
|
||||
|
||||
return cls(start=start, end=end, units=units)
|
||||
def from_list(cls, coords: List[Any], units: str | Units) -> "Line":
|
||||
"""
|
||||
creates a Line from a list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
start_x, start_y, start_z,
|
||||
end_x, end_y, end_z,
|
||||
domain_start, domain_end]
|
||||
"""
|
||||
start = Point(
|
||||
x=coords[3],
|
||||
y=coords[4],
|
||||
z=coords[5],
|
||||
units=units
|
||||
)
|
||||
end = Point(
|
||||
x=coords[6],
|
||||
y=coords[7],
|
||||
z=coords[8],
|
||||
units=units
|
||||
)
|
||||
domain = Interval(
|
||||
start=coords[9],
|
||||
end=coords[10]
|
||||
)
|
||||
return cls(start=start, end=end, domain=domain, units=units)
|
||||
|
||||
@classmethod
|
||||
def from_coords(
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Tuple
|
||||
from typing import List, Tuple, Any
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry.point import Point
|
||||
from specklepy.objects.interfaces import IHasArea, IHasVolume, IHasUnits, ITransformable
|
||||
from specklepy.objects.models.units import Units, get_scale_factor, get_units_from_string
|
||||
from specklepy.objects.models.units import (
|
||||
Units,
|
||||
get_scale_factor,
|
||||
get_units_from_string,
|
||||
get_units_from_encoding,
|
||||
get_encoding_from_units
|
||||
)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
@@ -185,3 +191,95 @@ class Mesh(
|
||||
i += vertex_count + 1
|
||||
|
||||
return all(count == 2 for count in edge_counts.values())
|
||||
|
||||
def to_list(self) -> List[Any]:
|
||||
"""Returns a serializable list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
vertices_count, v1x, v1y, v1z, v2x, v2y, v2z, ...,
|
||||
faces_count, f1, f2, f3, ...,
|
||||
colors_count, c1, c2, c3, ...,
|
||||
texture_coords_count, t1u, t1v, t2u, t2v, ...,
|
||||
area, volume]"""
|
||||
result = []
|
||||
|
||||
# Add vertices
|
||||
result.append(len(self.vertices))
|
||||
result.extend(self.vertices)
|
||||
|
||||
# Add faces
|
||||
result.append(len(self.faces))
|
||||
result.extend(self.faces)
|
||||
|
||||
# Add colors (if any)
|
||||
result.append(len(self.colors))
|
||||
if self.colors:
|
||||
result.extend(self.colors)
|
||||
|
||||
# Add texture coordinates (if any)
|
||||
result.append(len(self.textureCoordinates))
|
||||
if self.textureCoordinates:
|
||||
result.extend(self.textureCoordinates)
|
||||
|
||||
# Add area and volume
|
||||
result.extend([self.area, self.volume])
|
||||
|
||||
# Add header information
|
||||
result.insert(0, get_encoding_from_units(self.units))
|
||||
result.insert(0, self.speckle_type)
|
||||
result.insert(0, len(result) + 1)
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, coords: List[Any]) -> "Mesh":
|
||||
"""Creates a Mesh from a list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
vertices_count, v1x, v1y, v1z, v2x, v2y, v2z, ...,
|
||||
faces_count, f1, f2, f3, ...,
|
||||
colors_count, c1, c2, c3, ...,
|
||||
texture_coords_count, t1u, t1v, t2u, t2v, ...,
|
||||
area, volume]"""
|
||||
units = get_units_from_encoding(coords[2])
|
||||
|
||||
index = 3
|
||||
|
||||
# Extract vertices
|
||||
vertices_count = int(coords[index])
|
||||
index += 1
|
||||
vertices = coords[index:index + vertices_count]
|
||||
index += vertices_count
|
||||
|
||||
# Extract faces
|
||||
faces_count = int(coords[index])
|
||||
index += 1
|
||||
faces = [int(f) for f in coords[index:index + faces_count]]
|
||||
index += faces_count
|
||||
|
||||
# Extract colors
|
||||
colors_count = int(coords[index])
|
||||
index += 1
|
||||
colors = []
|
||||
if colors_count > 0:
|
||||
colors = [int(c) for c in coords[index:index + colors_count]]
|
||||
index += colors_count
|
||||
|
||||
# Extract texture coordinates
|
||||
texture_coords_count = int(coords[index])
|
||||
index += 1
|
||||
texture_coords = []
|
||||
if texture_coords_count > 0:
|
||||
texture_coords = coords[index:index + texture_coords_count]
|
||||
index += texture_coords_count
|
||||
|
||||
# Extract area and volume
|
||||
area = coords[index]
|
||||
volume = coords[index + 1]
|
||||
|
||||
return cls(
|
||||
vertices=vertices,
|
||||
faces=faces,
|
||||
colors=colors,
|
||||
textureCoordinates=texture_coords,
|
||||
area=area,
|
||||
volume=volume,
|
||||
units=units
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Tuple
|
||||
from typing import List, Tuple, Any
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry.point import Point
|
||||
@@ -32,34 +32,67 @@ class Plane(Base, ITransformable, IHasUnits, speckle_type="Objects.Geometry.Plan
|
||||
f"units: {self.units})"
|
||||
)
|
||||
|
||||
def to_list(self) -> List[float]:
|
||||
"""
|
||||
returns the values of this Plane as a list of numbers
|
||||
def to_list(self) -> List[Any]:
|
||||
"""
|
||||
returns a serializable list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
origin_x, origin_y, origin_z,
|
||||
normal_x, normal_y, normal_z,
|
||||
xdir_x, xdir_y, xdir_z,
|
||||
ydir_x, ydir_y, ydir_z]
|
||||
"""
|
||||
result = []
|
||||
result.extend(self.origin.to_list())
|
||||
result.extend(self.normal.to_list())
|
||||
result.extend(self.xdir.to_list())
|
||||
result.extend(self.ydir.to_list())
|
||||
result.append(get_encoding_from_units(self.units))
|
||||
# skip length, type, units from Point
|
||||
result.extend(self.origin.to_list()[3:])
|
||||
# skip length, type, units from Vector
|
||||
result.extend(self.normal.to_list()[3:])
|
||||
# skip length, type, units from Vector
|
||||
result.extend(self.xdir.to_list()[3:])
|
||||
# skip length, type, units from Vector
|
||||
result.extend(self.ydir.to_list()[3:])
|
||||
|
||||
# add header information
|
||||
result.insert(0, get_encoding_from_units(self.units))
|
||||
result.insert(0, self.speckle_type)
|
||||
result.insert(0, len(result) + 1)
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, coords: List[float]) -> "Plane":
|
||||
def from_list(cls, coords: List[Any]) -> "Plane":
|
||||
"""
|
||||
creates a new Plane based on a list of values
|
||||
creates a Plane from a list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
origin_x, origin_y, origin_z,
|
||||
normal_x, normal_y, normal_z,
|
||||
xdir_x, xdir_y, xdir_z,
|
||||
ydir_x, ydir_y, ydir_z]
|
||||
"""
|
||||
units = get_units_from_encoding(int(coords[-1]))
|
||||
units = get_units_from_encoding(coords[2])
|
||||
|
||||
plane = cls(
|
||||
origin=Point(x=coords[0], y=coords[1], z=coords[2], units=units),
|
||||
normal=Vector(x=coords[3], y=coords[4], z=coords[5], units=units),
|
||||
xdir=Vector(x=coords[6], y=coords[7], z=coords[8], units=units),
|
||||
ydir=Vector(x=coords[9], y=coords[10], z=coords[11], units=units),
|
||||
units=units,
|
||||
origin = Point(
|
||||
x=coords[3], y=coords[4], z=coords[5],
|
||||
units=units
|
||||
)
|
||||
normal = Vector(
|
||||
x=coords[6], y=coords[7], z=coords[8],
|
||||
units=units
|
||||
)
|
||||
xdir = Vector(
|
||||
x=coords[9], y=coords[10], z=coords[11],
|
||||
units=units
|
||||
)
|
||||
ydir = Vector(
|
||||
x=coords[12], y=coords[13], z=coords[14],
|
||||
units=units
|
||||
)
|
||||
|
||||
return plane
|
||||
return cls(
|
||||
origin=origin,
|
||||
normal=normal,
|
||||
xdir=xdir,
|
||||
ydir=ydir,
|
||||
units=units
|
||||
)
|
||||
|
||||
def transform_to(self, transform) -> Tuple[bool, Base]:
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Tuple
|
||||
from typing import List, Tuple, Any
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.interfaces import IHasUnits, ITransformable
|
||||
@@ -7,6 +7,7 @@ from specklepy.objects.models.units import (
|
||||
Units,
|
||||
get_scale_factor,
|
||||
get_units_from_string,
|
||||
get_encoding_from_units
|
||||
)
|
||||
|
||||
|
||||
@@ -23,12 +24,25 @@ class Point(Base, IHasUnits, ITransformable, speckle_type="Objects.Geometry.Poin
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.__class__.__name__}(x: {self.x}, y: {self.y}, z: {self.z}, units: {self.units})"
|
||||
|
||||
def to_list(self) -> List[float]:
|
||||
return [self.x, self.y, self.z]
|
||||
def to_list(self) -> List[Any]:
|
||||
"""
|
||||
returns a serializable list of format:
|
||||
[total_length, speckle_type, units_encoding, x, y, z]
|
||||
"""
|
||||
result = [self.x, self.y, self.z]
|
||||
result.insert(0, get_encoding_from_units(self.units))
|
||||
result.insert(0, self.speckle_type)
|
||||
result.insert(0, len(result) + 1) # +1 for the length we're adding
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, coords: List[float], units: str | Units) -> "Point":
|
||||
return cls(x=coords[0], y=coords[1], z=coords[2], units=units)
|
||||
def from_list(cls, coords: List[Any], units: str | Units) -> "Point":
|
||||
"""
|
||||
creates a Point from a list of format:
|
||||
[total_length, speckle_type, units_encoding, x, y, z]
|
||||
"""
|
||||
x, y, z = coords[3:6] # geometric data starts at index 3
|
||||
return cls(x=x, y=y, z=z, units=units)
|
||||
|
||||
@classmethod
|
||||
def from_coords(cls, x: float, y: float, z: float, units: str | Units) -> "Point":
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Tuple
|
||||
from typing import List, Tuple, Any
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry.point import Point
|
||||
@@ -59,33 +59,47 @@ class Polyline(Base, IHasUnits, ICurve, ITransformable, speckle_type="Objects.Ge
|
||||
)
|
||||
return points
|
||||
|
||||
def to_list(self) -> List[float]:
|
||||
"""
|
||||
returns the values of this Polyline as a list of numbers
|
||||
def to_list(self) -> List[Any]:
|
||||
"""
|
||||
returns a serializable list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
is_closed,
|
||||
domain_start, domain_end,
|
||||
coords_count,
|
||||
x1, y1, z1, x2, y2, z2, ...]
|
||||
"""
|
||||
result = []
|
||||
result.append(len(self.value) + 6) # total list length
|
||||
# type indicator for polyline ?? not sure about this
|
||||
result.append("Objects.Geometry.Polyline")
|
||||
result.append(1 if self.closed else 0)
|
||||
result.append(self.domain.start)
|
||||
result.append(self.domain.end)
|
||||
result.append(len(self.value))
|
||||
result.extend(self.value)
|
||||
result.append(get_encoding_from_units(self.units))
|
||||
result.append(1 if self.closed else 0) # convert bool to int
|
||||
result.extend([self.domain.start, self.domain.end])
|
||||
result.append(len(self.value)) # number of coordinates
|
||||
result.extend(self.value) # all vertex coordinates
|
||||
|
||||
# add header information
|
||||
result.insert(0, get_encoding_from_units(self.units))
|
||||
result.insert(0, self.speckle_type)
|
||||
result.insert(0, len(result) + 1)
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, coords: List[float], units: str | Units) -> "Polyline":
|
||||
def from_list(cls, coords: List[Any], units: str | Units) -> "Polyline":
|
||||
"""
|
||||
creates a new Polyline based on a list of coordinates
|
||||
"""
|
||||
point_count = int(coords[5])
|
||||
creates a Polyline from a list of format:
|
||||
[total_length, speckle_type, units_encoding,
|
||||
is_closed,
|
||||
domain_start, domain_end,
|
||||
coords_count,
|
||||
x1, y1, z1, x2, y2, z2, ...]
|
||||
"""
|
||||
is_closed = bool(coords[3])
|
||||
domain = Interval(start=coords[4], end=coords[5])
|
||||
coords_count = int(coords[6])
|
||||
vertex_coords = coords[7:7 + coords_count]
|
||||
|
||||
return cls(
|
||||
closed=(int(coords[2]) == 1),
|
||||
domain=Interval(start=coords[3], end=coords[4]),
|
||||
value=coords[6: 6 + point_count],
|
||||
units=units,
|
||||
value=vertex_coords,
|
||||
closed=is_closed,
|
||||
domain=domain,
|
||||
units=units
|
||||
)
|
||||
|
||||
def transform_to(self, transform) -> Tuple[bool, "Polyline"]:
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
from typing import List, Any
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.interfaces import IHasUnits, ITransformable
|
||||
from specklepy.objects.models.units import Units
|
||||
from specklepy.objects.models.units import (
|
||||
Units,
|
||||
get_encoding_from_units
|
||||
)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
@@ -23,12 +26,25 @@ class Vector(Base, IHasUnits, ITransformable, speckle_type="Objects.Geometry.Vec
|
||||
def length(self) -> float:
|
||||
return (self.x ** 2 + self.y ** 2 + self.z ** 2) ** 0.5
|
||||
|
||||
def to_list(self) -> List[float]:
|
||||
return [self.x, self.y, self.z]
|
||||
def to_list(self) -> List[Any]:
|
||||
"""
|
||||
returns a serializable list of format:
|
||||
[total_length, speckle_type, units_encoding, x, y, z]
|
||||
"""
|
||||
result = [self.x, self.y, self.z]
|
||||
result.insert(0, get_encoding_from_units(self.units))
|
||||
result.insert(0, self.speckle_type)
|
||||
result.insert(0, len(result) + 1) # +1 for the length we're adding
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_list(cls, coords: List[float], units: str | Units) -> "Vector":
|
||||
return cls(x=coords[0], y=coords[1], z=coords[2], units=units)
|
||||
def from_list(cls, coords: List[Any], units: str | Units) -> "Vector":
|
||||
"""
|
||||
creates a Vector from a list of format:
|
||||
[total_length, speckle_type, units_encoding, x, y, z]
|
||||
"""
|
||||
x, y, z = coords[3:6] # geometric data starts at index 3
|
||||
return cls(x=x, y=y, z=z, units=units)
|
||||
|
||||
def transform_to(self, transform):
|
||||
m = transform.matrix
|
||||
|
||||
@@ -87,3 +87,65 @@ def test_arc_domain(sample_arc):
|
||||
assert sample_arc.domain.start == 0.0
|
||||
assert sample_arc.domain.end == 1.0
|
||||
assert sample_arc._domain == sample_arc.domain
|
||||
|
||||
|
||||
def test_arc_to_list():
|
||||
plane = Plane(
|
||||
origin=Point(x=0.0, y=0.0, z=0.0, units="m"),
|
||||
normal=Vector(x=0.0, y=0.0, z=1.0, units="m"),
|
||||
xdir=Vector(x=1.0, y=0.0, z=0.0, units="m"),
|
||||
ydir=Vector(x=0.0, y=1.0, z=0.0, units="m"),
|
||||
units="m"
|
||||
)
|
||||
arc = Arc(
|
||||
plane=plane,
|
||||
startPoint=Point(x=1.0, y=0.0, z=0.0, units="m"),
|
||||
midPoint=Point(x=0.7071, y=0.7071, z=0.0, units="m"),
|
||||
endPoint=Point(x=0.0, y=1.0, z=0.0, units="m"),
|
||||
domain=Interval(start=0.0, end=1.0),
|
||||
units="m"
|
||||
)
|
||||
|
||||
coords = arc.to_list()
|
||||
assert len(coords) == 28 # total_length, type, units_encoding + data
|
||||
assert coords[0] == 28 # total length
|
||||
assert coords[1] == "Objects.Geometry.Arc" # speckle type
|
||||
assert coords[5:7] == [0.0, 1.0] # domain
|
||||
# Check plane coordinates
|
||||
assert coords[7:10] == [0.0, 0.0, 0.0] # plane origin
|
||||
assert coords[10:13] == [0.0, 0.0, 1.0] # plane normal
|
||||
assert coords[13:16] == [1.0, 0.0, 0.0] # plane xdir
|
||||
assert coords[16:19] == [0.0, 1.0, 0.0] # plane ydir
|
||||
# Check point coordinates
|
||||
assert coords[19:22] == [1.0, 0.0, 0.0] # start point
|
||||
assert coords[22:25] == [0.7071, 0.7071, 0.0] # mid point
|
||||
assert coords[25:28] == [0.0, 1.0, 0.0] # end point
|
||||
|
||||
|
||||
def test_arc_from_list():
|
||||
coords = [
|
||||
28, "Objects.Geometry.Arc", 3, # header
|
||||
1.0, 1.5708, # radius, measure
|
||||
0.0, 1.0, # domain
|
||||
0.0, 0.0, 0.0, # plane origin
|
||||
0.0, 0.0, 1.0, # plane normal
|
||||
1.0, 0.0, 0.0, # plane xdir
|
||||
0.0, 1.0, 0.0, # plane ydir
|
||||
1.0, 0.0, 0.0, # start point
|
||||
0.7071, 0.7071, 0.0, # mid point
|
||||
0.0, 1.0, 0.0 # end point
|
||||
]
|
||||
|
||||
arc = Arc.from_list(coords)
|
||||
assert arc.units == "m"
|
||||
assert arc.domain.start == 0.0
|
||||
assert arc.domain.end == 1.0
|
||||
assert arc.startPoint.x == 1.0
|
||||
assert arc.startPoint.y == 0.0
|
||||
assert arc.startPoint.z == 0.0
|
||||
assert abs(arc.midPoint.x - 0.7071) < 0.0001
|
||||
assert abs(arc.midPoint.y - 0.7071) < 0.0001
|
||||
assert arc.midPoint.z == 0.0
|
||||
assert arc.endPoint.x == 0.0
|
||||
assert arc.endPoint.y == 1.0
|
||||
assert arc.endPoint.z == 0.0
|
||||
|
||||
@@ -49,11 +49,18 @@ def test_line_serialization(sample_line):
|
||||
|
||||
|
||||
def test_line_from_list():
|
||||
coords = [0.0, 0.0, 0.0, 3.0, 4.0, 0.0]
|
||||
line = Line.from_list(coords, Units.m)
|
||||
assert line.start.x == 0.0
|
||||
assert line.end.x == 3.0
|
||||
assert line.units == Units.m.value
|
||||
coords = [11, "Objects.Geometry.Line", 3,
|
||||
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 0.0, 1.0]
|
||||
line = Line.from_list(coords, "m")
|
||||
assert line.start.x == 1.0
|
||||
assert line.start.y == 2.0
|
||||
assert line.start.z == 3.0
|
||||
assert line.end.x == 4.0
|
||||
assert line.end.y == 5.0
|
||||
assert line.end.z == 6.0
|
||||
assert line.domain.start == 0.0
|
||||
assert line.domain.end == 1.0
|
||||
assert line.units == "m"
|
||||
|
||||
|
||||
def test_line_from_coords():
|
||||
|
||||
@@ -134,3 +134,79 @@ def test_mesh_convert_units(sample_mesh):
|
||||
assert sample_mesh.area == 1.0 * (1000 ** 2)
|
||||
|
||||
assert sample_mesh.volume == 0.0
|
||||
|
||||
|
||||
def test_mesh_to_list():
|
||||
mesh = Mesh(
|
||||
vertices=[0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0],
|
||||
faces=[3, 0, 1, 2],
|
||||
colors=[255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255],
|
||||
textureCoordinates=[0.0, 0.0, 1.0, 0.0, 0.0, 1.0],
|
||||
units="m",
|
||||
area=0.5,
|
||||
volume=0.0
|
||||
)
|
||||
|
||||
coords = mesh.to_list()
|
||||
assert len(coords) > 3 # Should have at least header info
|
||||
assert coords[0] > 3 # total length
|
||||
assert coords[1] == "Objects.Geometry.Mesh" # speckle type
|
||||
|
||||
index = 3
|
||||
vertices_count = coords[index]
|
||||
assert vertices_count == 9 # 3 vertices * 3 coordinates
|
||||
index += 1
|
||||
assert coords[index:index + vertices_count] == [0.0,
|
||||
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
|
||||
|
||||
index += vertices_count
|
||||
faces_count = coords[index]
|
||||
assert faces_count == 4 # 1 face with 3 vertices + count
|
||||
index += 1
|
||||
assert coords[index:index + faces_count] == [3, 0, 1, 2]
|
||||
|
||||
index += faces_count
|
||||
colors_count = coords[index]
|
||||
assert colors_count == 12 # 3 vertices * 4 rgba values
|
||||
index += 1
|
||||
assert coords[index:index + colors_count] == [255,
|
||||
0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255]
|
||||
|
||||
index += colors_count
|
||||
texture_coords_count = coords[index]
|
||||
assert texture_coords_count == 6 # 3 vertices * 2 uv coordinates
|
||||
index += 1
|
||||
assert coords[index:index + texture_coords_count] == [0.0,
|
||||
0.0, 1.0, 0.0, 0.0, 1.0]
|
||||
|
||||
index += texture_coords_count
|
||||
assert coords[index] == 0.5 # area
|
||||
assert coords[index + 1] == 0.0 # volume
|
||||
|
||||
|
||||
def test_mesh_from_list():
|
||||
coords = [
|
||||
26, "Objects.Geometry.Mesh", 3, # header
|
||||
9, # vertices count
|
||||
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, # vertices
|
||||
4, # faces count
|
||||
3, 0, 1, 2, # faces
|
||||
12, # colors count
|
||||
255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, # colors
|
||||
6, # texture coordinates count
|
||||
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, # texture coordinates
|
||||
0.5, 0.0 # area, volume
|
||||
]
|
||||
|
||||
mesh = Mesh.from_list(coords)
|
||||
assert mesh.units == "m"
|
||||
assert len(mesh.vertices) == 9
|
||||
assert mesh.vertices == [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
|
||||
assert len(mesh.faces) == 4
|
||||
assert mesh.faces == [3, 0, 1, 2]
|
||||
assert len(mesh.colors) == 12
|
||||
assert mesh.colors == [255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255]
|
||||
assert len(mesh.textureCoordinates) == 6
|
||||
assert mesh.textureCoordinates == [0.0, 0.0, 1.0, 0.0, 0.0, 1.0]
|
||||
assert mesh.area == 0.5
|
||||
assert mesh.volume == 0.0
|
||||
|
||||
@@ -50,22 +50,40 @@ def test_plane_serialization(sample_plane):
|
||||
assert deserialized.units == sample_plane.units
|
||||
|
||||
|
||||
def test_plane_to_list(sample_plane):
|
||||
coords = sample_plane.to_list()
|
||||
assert len(coords) == 13
|
||||
def test_plane_to_list():
|
||||
plane = Plane(
|
||||
origin=Point(x=1.0, y=2.0, z=3.0, units="m"),
|
||||
normal=Vector(x=0.0, y=0.0, z=1.0, units="m"),
|
||||
xdir=Vector(x=1.0, y=0.0, z=0.0, units="m"),
|
||||
ydir=Vector(x=0.0, y=1.0, z=0.0, units="m"),
|
||||
units="m"
|
||||
)
|
||||
coords = plane.to_list()
|
||||
# total_length, type, units_encoding + 12 coordinates
|
||||
assert len(coords) == 15
|
||||
assert coords[3:6] == [1.0, 2.0, 3.0] # origin
|
||||
assert coords[6:9] == [0.0, 0.0, 1.0] # normal
|
||||
assert coords[9:12] == [1.0, 0.0, 0.0] # xdir
|
||||
assert coords[12:15] == [0.0, 1.0, 0.0] # ydir
|
||||
|
||||
|
||||
def test_plane_from_list():
|
||||
coords = [
|
||||
0.0, 0.0, 0.0, # origin
|
||||
0.0, 0.0, 1.0, # normal
|
||||
1.0, 0.0, 0.0, # xdir
|
||||
0.0, 1.0, 0.0, # ydir
|
||||
1 # units encoding (1 = mm)
|
||||
]
|
||||
coords = [15, "Objects.Geometry.Plane", 3, # header
|
||||
1.0, 2.0, 3.0, # origin
|
||||
0.0, 0.0, 1.0, # normal
|
||||
1.0, 0.0, 0.0, # xdir
|
||||
0.0, 1.0, 0.0] # ydir
|
||||
plane = Plane.from_list(coords)
|
||||
assert plane.origin.x == 0.0
|
||||
assert plane.origin.x == 1.0
|
||||
assert plane.origin.y == 2.0
|
||||
assert plane.origin.z == 3.0
|
||||
assert plane.normal.x == 0.0
|
||||
assert plane.normal.y == 0.0
|
||||
assert plane.normal.z == 1.0
|
||||
assert plane.xdir.x == 1.0
|
||||
assert plane.xdir.y == 0.0
|
||||
assert plane.xdir.z == 0.0
|
||||
assert plane.ydir.x == 0.0
|
||||
assert plane.ydir.y == 1.0
|
||||
assert plane.units == "mm"
|
||||
assert plane.ydir.z == 0.0
|
||||
assert plane.units == "m"
|
||||
|
||||
@@ -51,3 +51,22 @@ def test_point_serialization():
|
||||
assert deserialized.y == p1.y
|
||||
assert deserialized.z == p1.z
|
||||
assert deserialized.units == p1.units
|
||||
|
||||
|
||||
def test_point_to_list():
|
||||
point = Point(x=1.0, y=2.0, z=3.0, units="m")
|
||||
coords = point.to_list()
|
||||
# total_length, type, units_encoding + 3 coordinates
|
||||
assert len(coords) == 6
|
||||
assert coords[0] == 6 # total length
|
||||
assert coords[1] == "Objects.Geometry.Point" # speckle type
|
||||
assert coords[3:] == [1.0, 2.0, 3.0] # coordinates
|
||||
|
||||
|
||||
def test_point_from_list():
|
||||
coords = [6, "Objects.Geometry.Point", 3, 1.0, 2.0, 3.0]
|
||||
point = Point.from_list(coords, "m")
|
||||
assert point.x == 1.0
|
||||
assert point.y == 2.0
|
||||
assert point.z == 3.0
|
||||
assert point.units == "m"
|
||||
|
||||
@@ -99,32 +99,29 @@ def test_polyline_serialization(sample_polyline):
|
||||
assert deserialized.domain.end == sample_polyline.domain.end
|
||||
|
||||
|
||||
def test_polyline_to_list(sample_polyline):
|
||||
result = sample_polyline.to_list()
|
||||
|
||||
assert isinstance(result, list)
|
||||
assert result[2] == 1
|
||||
assert result[3] == 0.0
|
||||
assert result[4] == 1.0
|
||||
assert result[5] == len(sample_polyline.value)
|
||||
def test_polyline_to_list():
|
||||
polyline = Polyline(
|
||||
value=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
|
||||
closed=True,
|
||||
domain=Interval(start=0.0, end=1.0),
|
||||
units="m"
|
||||
)
|
||||
coords = polyline.to_list()
|
||||
assert coords[3] == 1 # is_closed (True = 1)
|
||||
assert coords[4:6] == [0.0, 1.0] # domain
|
||||
assert coords[6] == 6 # coords_count
|
||||
assert coords[7:] == [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] # coordinates
|
||||
|
||||
|
||||
def test_polyline_from_list():
|
||||
input_list = [
|
||||
18, "Objects.Geometry.Polyline",
|
||||
1,
|
||||
0.0, 1.0,
|
||||
12,
|
||||
0.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0
|
||||
]
|
||||
|
||||
polyline = Polyline.from_list(input_list, Units.m)
|
||||
|
||||
coords = [11, "Objects.Geometry.Polyline", 3, # header
|
||||
1, # closed
|
||||
0.0, 1.0, # domain
|
||||
6, # coords_count
|
||||
1.0, 2.0, 3.0, 4.0, 5.0, 6.0] # coordinates
|
||||
polyline = Polyline.from_list(coords, "m")
|
||||
assert polyline.closed is True
|
||||
assert len(polyline.value) == 12
|
||||
assert polyline.units == Units.m.value
|
||||
assert polyline.domain.start == 0.0
|
||||
assert polyline.domain.end == 1.0
|
||||
assert polyline.value == [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
|
||||
assert polyline.units == "m"
|
||||
|
||||
@@ -56,15 +56,16 @@ def test_vector_serialization(sample_vectors):
|
||||
|
||||
|
||||
def test_vector_from_list():
|
||||
coords = [1.0, 2.0, 3.0]
|
||||
v = Vector.from_list(coords, Units.m)
|
||||
assert v.x == 1.0
|
||||
assert v.y == 2.0
|
||||
assert v.z == 3.0
|
||||
assert v.units == Units.m.value
|
||||
coords = [6, "Objects.Geometry.Vector", 3, 1.0, 2.0, 3.0]
|
||||
vector = Vector.from_list(coords, "m")
|
||||
assert vector.x == 1.0
|
||||
assert vector.y == 2.0
|
||||
assert vector.z == 3.0
|
||||
assert vector.units == "m"
|
||||
|
||||
|
||||
def test_vector_to_list(sample_vectors):
|
||||
v1, _ = sample_vectors
|
||||
coords = v1.to_list()
|
||||
assert coords == [1.0, 2.0, 3.0]
|
||||
def test_vector_to_list():
|
||||
vector = Vector(x=1.0, y=2.0, z=3.0, units="m")
|
||||
coords = vector.to_list()
|
||||
assert len(coords) == 6
|
||||
assert coords[3:] == [1.0, 2.0, 3.0]
|
||||
|
||||
Reference in New Issue
Block a user