352 lines
8.9 KiB
Python
352 lines
8.9 KiB
Python
from .base import Base
|
|
from typing import Any, List
|
|
|
|
GEOMETRY = "Objects.Geometry."
|
|
|
|
|
|
class Interval(Base, speckle_type="Objects.Primitive.Interval"):
|
|
start: float = 0
|
|
end: float = 0
|
|
|
|
def length(self):
|
|
return abs(self.start - self.end)
|
|
|
|
|
|
class Point(Base, speckle_type=GEOMETRY + "Point"):
|
|
x: float = 0
|
|
y: float = 0
|
|
z: float = 0
|
|
|
|
def __init__(self, x: float = 0, y: float = 0, z: float = 0, **data: Any) -> None:
|
|
super().__init__(**data)
|
|
self.x, self.y, self.z = x, y, z
|
|
|
|
def __repr__(self) -> str:
|
|
return f"{self.__class__.__name__}(x: {self.x}, y: {self.y}, z: {self.z}, id: {self.id}, speckle_type: {self.speckle_type})"
|
|
|
|
|
|
class Vector(Point, speckle_type=GEOMETRY + "Vector"):
|
|
pass
|
|
|
|
|
|
class ControlPoint(Point, speckle_type=GEOMETRY + "ControlPoint"):
|
|
weight: float = None
|
|
|
|
|
|
class Plane(Base, speckle_type=GEOMETRY + "Plane"):
|
|
origin: Point = Point()
|
|
normal: Vector = Vector()
|
|
xdir: Vector = Vector()
|
|
ydir: Vector = Vector()
|
|
|
|
|
|
class Box(Base, speckle_type=GEOMETRY + "Box"):
|
|
basePlane: Plane = Plane()
|
|
ySize: Interval = Interval()
|
|
zSize: Interval = Interval()
|
|
xSize: Interval = Interval()
|
|
area: float = None
|
|
volume: float = None
|
|
|
|
|
|
class Line(Base, speckle_type=GEOMETRY + "Line"):
|
|
start: Point = Point()
|
|
end: Point = None
|
|
domain: Interval = None
|
|
bbox: Box = None
|
|
length: float = None
|
|
|
|
|
|
class Arc(Base, speckle_type=GEOMETRY + "Arc"):
|
|
radius: float = None
|
|
startAngle: float = None
|
|
endAngle: float = None
|
|
angleRadians: float = None
|
|
plane: Plane = None
|
|
domain: Interval = None
|
|
startPoint: Point = None
|
|
midPoint: Point = None
|
|
endPoint: Point = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
length: float = None
|
|
|
|
|
|
class Circle(Base, speckle_type=GEOMETRY + "Circle"):
|
|
radius: float = None
|
|
plane: Plane = None
|
|
domain: Interval = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
length: float = None
|
|
|
|
|
|
class Ellipse(Base, speckle_type=GEOMETRY + "Ellipse"):
|
|
firstRadius: float = None
|
|
secondRadius: float = None
|
|
plane: Plane = None
|
|
domain: Interval = None
|
|
trimDomain: Interval = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
length: float = None
|
|
|
|
|
|
class Polyline(Base, speckle_type=GEOMETRY + "Polyline"):
|
|
value: List[float] = None
|
|
closed: bool = None
|
|
domain: Interval = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
length: float = None
|
|
|
|
def __init__(self, **data: Any) -> None:
|
|
super().__init__(**data)
|
|
self.add_chunkable_attrs(value=20000)
|
|
|
|
@classmethod
|
|
def from_points(cls, points: List[Point]):
|
|
polyline = cls()
|
|
polyline.units = points[0].units
|
|
for point in points:
|
|
polyline.value.extend([point.x, point.y, point.z])
|
|
return polyline
|
|
|
|
# @property
|
|
# def value(self) -> List[float]:
|
|
# return self._value
|
|
|
|
# @value.setter
|
|
# def value(self, coords) -> None:
|
|
# if len(coords) % 3:
|
|
# coords.extend([0] * (3 - len(coords) % 3))
|
|
# self._value = coords
|
|
|
|
def as_points(self) -> List[Point]:
|
|
"""Converts the `value` attribute to a list of Points"""
|
|
if not self.value:
|
|
return
|
|
|
|
if len(self.value) % 3:
|
|
raise ValueError("Points array malformed: length%3 != 0.")
|
|
|
|
values = iter(self.value)
|
|
return [Point(v, next(values), next(values), units=self.units) for v in values]
|
|
|
|
|
|
class Curve(Base, speckle_type=GEOMETRY + "Curve"):
|
|
degree: int = None
|
|
periodic: bool = None
|
|
rational: bool = None
|
|
points: List[float] = None
|
|
weights: List[float] = None
|
|
knots: List[float] = None
|
|
domain: Interval = None
|
|
displayValue: Polyline = None
|
|
closed: bool = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
length: float = None
|
|
|
|
def __init__(self, **data: Any) -> None:
|
|
super().__init__(**data)
|
|
self.add_chunkable_attrs(points=20000, weights=20000, knots=20000)
|
|
|
|
def as_points(self) -> List[Point]:
|
|
"""Converts the `value` attribute to a list of Points"""
|
|
if not self.points:
|
|
return
|
|
|
|
if len(self.points) % 3:
|
|
raise ValueError("Points array malformed: length%3 != 0.")
|
|
|
|
values = iter(self.points)
|
|
return [Point(v, next(values), next(values), units=self.units) for v in values]
|
|
|
|
|
|
class Polycurve(Base, speckle_type=GEOMETRY + "Polycurve"):
|
|
segments: List[Base] = []
|
|
domain: Interval = None
|
|
closed: bool = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
length: float = None
|
|
|
|
|
|
class Extrusion(Base, speckle_type=GEOMETRY + "Extrusion"):
|
|
capped: bool = None
|
|
profile: Base = None
|
|
pathStart: Point = None
|
|
pathEnd: Point = None
|
|
pathCurve: Base = None
|
|
pathTangent: Base = None
|
|
profiles: List[Base] = None
|
|
length: float = None
|
|
area: float = None
|
|
volume: float = None
|
|
bbox: Box = None
|
|
|
|
|
|
class Mesh(Base, speckle_type=GEOMETRY + "Mesh"):
|
|
vertices: List[float] = None
|
|
faces: List[int] = None
|
|
colors: List[int] = None
|
|
textureCoordinates: List[float] = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
volume: float = None
|
|
|
|
def __init__(self, **data) -> None:
|
|
super().__init__(**data)
|
|
self.add_chunkable_attrs(
|
|
vertices=2000, faces=2000, colors=2000, textureCoordinates=2000
|
|
)
|
|
|
|
|
|
class Surface(Base, speckle_type=GEOMETRY + "Surface"):
|
|
degreeU: int = None
|
|
degreeV: int = None
|
|
rational: bool = None
|
|
area: float = None
|
|
pointData: List[float] = None
|
|
countU: int = None
|
|
countV: int = None
|
|
bbox: Box = None
|
|
|
|
|
|
class BrepFace(Base, speckle_type=GEOMETRY + "BrepFace"):
|
|
_Brep: "Brep" = None
|
|
SurfaceIndex: int = None
|
|
LoopIndices: List[int] = None
|
|
OuterLoopIndex: int = None
|
|
OrientationReversed: bool = None
|
|
|
|
@property
|
|
def _outer_loop(self):
|
|
return self._Brep.Loops[self.OuterLoopIndex]
|
|
|
|
@property
|
|
def _surface(self):
|
|
return self._Brep.Surfaces[self.SurfaceIndex]
|
|
|
|
@property
|
|
def _loops(self):
|
|
return [self._Brep.Loops[index] for index in self.LoopIndices]
|
|
|
|
|
|
class BrepEdge(Base, speckle_type=GEOMETRY + "BrepEdge"):
|
|
_Brep: "Brep" = None
|
|
Curve3dIndex: int = None
|
|
TrimIndices: List[int] = None
|
|
StartIndex: int = None
|
|
EndIndex: int = None
|
|
ProxyCurveIsReversed: bool = None
|
|
Domain: Interval = None
|
|
|
|
@property
|
|
def _start_vertex(self):
|
|
return self._Brep.Vertices[self.StartIndex]
|
|
|
|
@property
|
|
def _end_vertex(self):
|
|
return self._Brep.Vertices[self.EndIndex]
|
|
|
|
@property
|
|
def _trims(self):
|
|
return [self._Brep.Trims[i] for i in self.TrimIndices]
|
|
|
|
@property
|
|
def _curve(self):
|
|
return self._Brep.Curve3D[self.Curve3dIndex]
|
|
|
|
|
|
class BrepLoop(Base, speckle_type=GEOMETRY + "BrepLoop"):
|
|
_Brep: "Brep" = None
|
|
FaceIndex: int = None
|
|
TrimIndices: List[int] = None
|
|
Type: str = None
|
|
|
|
@property
|
|
def _face(self):
|
|
return self._Brep.Faces[self.FaceIndex]
|
|
|
|
@property
|
|
def _trims(self):
|
|
return [self._Brep.Trims[i] for i in self.TrimIndices]
|
|
|
|
|
|
class BrepTrim(Base, speckle_type=GEOMETRY + "BrepTrim"):
|
|
_Brep: "Brep" = None
|
|
EdgeIndex: int = None
|
|
StartIndex: int = None
|
|
EndIndex: int = None
|
|
FaceIndex: int = None
|
|
LoopIndex: int = None
|
|
CurveIndex: int = None
|
|
IsoStatus: int = None
|
|
TrimType: str = None
|
|
IsReversed: bool = None
|
|
Domain: Interval = None
|
|
|
|
@property
|
|
def _face(self):
|
|
return self._Brep.Faces[self.FaceIndex]
|
|
|
|
@property
|
|
def _loop(self):
|
|
return self._Brep.Loops[self.LoopIndex]
|
|
|
|
@property
|
|
def _edge(self):
|
|
return self._Brep.Edges[self.EdgeIndex] if self.EdgeIndex != -1 else None
|
|
|
|
@property
|
|
def _curve_2d(self):
|
|
return self._Brep.Curve2D[self.CurveIndex]
|
|
|
|
|
|
class Brep(Base, speckle_type=GEOMETRY + "Brep"):
|
|
provenance: str = None
|
|
bbox: Box = None
|
|
area: float = None
|
|
volume: float = None
|
|
displayValue: Mesh = None
|
|
Surfaces: List[Surface] = []
|
|
Curve3D: List[Base] = []
|
|
Curve2D: List[Base] = []
|
|
Vertices: List[Point] = []
|
|
Edges: List[BrepEdge] = []
|
|
Loops: List[BrepLoop] = []
|
|
Trims: List[BrepTrim] = []
|
|
Faces: List[BrepFace] = []
|
|
IsClosed: bool = None
|
|
Orientation: int = 0
|
|
|
|
def __init__(self, **data: Any) -> None:
|
|
super().__init__(**data)
|
|
self.add_detachable_attrs({"displayValue"})
|
|
self.add_chunkable_attrs(
|
|
Surfaces=200,
|
|
Curve3D=200,
|
|
Curve2D=200,
|
|
Vertices=5000,
|
|
Edges=5000,
|
|
Loops=5000,
|
|
Trims=5000,
|
|
Faces=5000,
|
|
)
|
|
|
|
def __setattr__(self, name: str, value: Any) -> None:
|
|
if not value:
|
|
return
|
|
if name in ["Edges", "Loops", "Trims", "Faces"]:
|
|
for val in value:
|
|
val._Brep = self
|
|
super().__setattr__(name, value)
|
|
|
|
|
|
BrepEdge.update_forward_refs()
|
|
BrepLoop.update_forward_refs()
|
|
BrepTrim.update_forward_refs()
|
|
BrepFace.update_forward_refs()
|