diff --git a/src/speckle_automate/automation_context.py b/src/speckle_automate/automation_context.py index 7476dbd3..efac6739 100644 --- a/src/speckle_automate/automation_context.py +++ b/src/speckle_automate/automation_context.py @@ -102,8 +102,17 @@ def receive_version(self) -> Base: commit = self.speckle_client.commit.get( self.automation_run_data.project_id, version_id ) - if not commit.referencedObject: - raise ValueError("The commit has no referencedObject, cannot receive it.") + if not commit or not commit.referencedObject: + raise ValueError( + f"""\ + Could not receive specified version. + {"The commit has no referencedObject." if not commit.referencedObject else ""} + Is your environment configured correctly? + project_id: {self.automation_run_data.project_id} + model_id: {self.automation_run_data.triggers[0].payload.model_id} + version_id: {self.automation_run_data.triggers[0].payload.version_id} + """ + ) base = operations.receive( commit.referencedObject, self._server_transport, self._memory_transport ) diff --git a/src/specklepy/core/api/models/current.py b/src/specklepy/core/api/models/current.py index 4826c46d..65e5606c 100644 --- a/src/specklepy/core/api/models/current.py +++ b/src/specklepy/core/api/models/current.py @@ -127,7 +127,7 @@ class Version(BaseModel): class Model(BaseModel): - author: LimitedUser + author: Optional[LimitedUser] createdAt: datetime description: Optional[str] displayName: str diff --git a/src/specklepy/objects_v2/graph_traversal/commit_object_builder.py b/src/specklepy/objects/graph_traversal/commit_object_builder.py similarity index 100% rename from src/specklepy/objects_v2/graph_traversal/commit_object_builder.py rename to src/specklepy/objects/graph_traversal/commit_object_builder.py diff --git a/src/specklepy/objects_v2/graph_traversal/traversal.py b/src/specklepy/objects/graph_traversal/traversal.py similarity index 100% rename from src/specklepy/objects_v2/graph_traversal/traversal.py rename to src/specklepy/objects/graph_traversal/traversal.py diff --git a/src/specklepy/objects/tests/asdasd.py b/src/specklepy/objects/tests/asdasd.py new file mode 100644 index 00000000..13e3089e --- /dev/null +++ b/src/specklepy/objects/tests/asdasd.py @@ -0,0 +1,9 @@ +from specklepy.objects.geometry import Point, Line +from specklepy.objects.models.units import Units + +p_1 = Point(x=0, y=0, z=0, units=Units.m) +p_2 = Point(x=3, y=0, z=0, units=Units.m) + +line = Line(start=p_1, end=p_2, units=Units.m) +line.length = line.calculate_length() +print(line.length) diff --git a/src/specklepy/objects_v2/GIS/CRS.py b/src/specklepy/objects_v2/GIS/CRS.py deleted file mode 100644 index 2527fe55..00000000 --- a/src/specklepy/objects_v2/GIS/CRS.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Optional - -from specklepy.objects.base import Base - - -class CRS(Base, speckle_type="Objects.GIS.CRS"): - """A Coordinate Reference System stored in wkt format""" - - name: Optional[str] = None - authority_id: Optional[str] = None - wkt: Optional[str] = None - units_native: Optional[str] = None - offset_x: Optional[float] = None - offset_y: Optional[float] = None - rotation: Optional[float] = None diff --git a/src/specklepy/objects_v2/GIS/__init__.py b/src/specklepy/objects_v2/GIS/__init__.py deleted file mode 100644 index 5ac3dff8..00000000 --- a/src/specklepy/objects_v2/GIS/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -"""Builtin Speckle object kit.""" - -from specklepy.objects.GIS.CRS import CRS -from specklepy.objects.GIS.geometry import ( - GisLineElement, - GisPointElement, - GisPolygonElement, - GisPolygonGeometry, - GisRasterElement, - PolygonGeometry, -) -from specklepy.objects.GIS.layers import RasterLayer, VectorLayer - -__all__ = [ - "VectorLayer", - "RasterLayer", - "GisPolygonGeometry", - "PolygonGeometry", - "GisPolygonElement", - "GisLineElement", - "GisPointElement", - "GisRasterElement", - "CRS", -] diff --git a/src/specklepy/objects_v2/GIS/geometry.py b/src/specklepy/objects_v2/GIS/geometry.py deleted file mode 100644 index 68df54cf..00000000 --- a/src/specklepy/objects_v2/GIS/geometry.py +++ /dev/null @@ -1,74 +0,0 @@ -from typing import List, Optional, Union - -from specklepy.objects.base import Base -from specklepy.objects.geometry import ( - Arc, - Circle, - Line, - Mesh, - Point, - Polycurve, - Polyline, -) - - -class PolygonGeometry(Base, speckle_type="Objects.GIS.PolygonGeometry"): - """GIS Polygon Geometry""" - - boundary: Optional[Polyline] - voids: Optional[List[Polyline]] - - -GisPolygonGeometry = PolygonGeometry - - -class GisPolygonElement(Base, speckle_type="Objects.GIS.PolygonElement"): - """GIS Polygon element""" - - geometry: Optional[List[GisPolygonGeometry]] = None - attributes: Optional[Base] = None - - -class GisLineElement(Base, speckle_type="Objects.GIS.LineElement"): - """GIS Polyline element""" - - geometry: Optional[List[Union[Polyline, Arc, Line, Circle, Polycurve]]] = None - attributes: Optional[Base] = None - - -class GisPointElement(Base, speckle_type="Objects.GIS.PointElement"): - """GIS Point element""" - - geometry: Optional[List[Point]] = None - attributes: Optional[Base] = None - - -class GisRasterElement( - Base, speckle_type="Objects.GIS.RasterElement", detachable={"displayValue"} -): - """GIS Raster element""" - - band_count: Optional[int] = None - band_names: Optional[List[str]] = None - x_origin: Optional[float] = None - y_origin: Optional[float] = None - x_size: Optional[int] = None - y_size: Optional[int] = None - x_resolution: Optional[float] = None - y_resolution: Optional[float] = None - noDataValue: Optional[List[float]] = None - displayValue: Optional[List[Mesh]] = None - - -class GisTopography( - GisRasterElement, - speckle_type="Objects.GIS.GisTopography", - detachable={"displayValue"}, -): - """GIS Raster element with 3d Topography representation""" - - -class GisNonGeometryElement(Base, speckle_type="Objects.GIS.NonGeometryElement"): - """GIS Table feature""" - - attributes: Optional[Base] = None diff --git a/src/specklepy/objects_v2/GIS/layers.py b/src/specklepy/objects_v2/GIS/layers.py deleted file mode 100644 index 3db33351..00000000 --- a/src/specklepy/objects_v2/GIS/layers.py +++ /dev/null @@ -1,142 +0,0 @@ -from typing import Any, Dict, List, Optional, Union - -from deprecated import deprecated - -from specklepy.objects.base import Base -from specklepy.objects.GIS.CRS import CRS -from specklepy.objects.other import Collection - - -@deprecated(version="2.15", reason="Use VectorLayer or RasterLayer instead") -class Layer(Base, detachable={"features"}): - """A GIS Layer""" - - def __init__( - self, - name: Optional[str] = None, - crs: Optional[CRS] = None, - units: str = "m", - features: Optional[List[Base]] = None, - layerType: str = "None", - geomType: str = "None", - renderer: Optional[Dict[str, Any]] = None, - **kwargs, - ) -> None: - super().__init__(**kwargs) - self.name = name - self.crs = crs - self.units = units - self.type = layerType - self.features = features or [] - self.geomType = geomType - self.renderer = renderer or {} - - -@deprecated(version="2.16", reason="Use VectorLayer or RasterLayer instead") -class VectorLayer( - Collection, - detachable={"elements"}, - speckle_type="VectorLayer", - serialize_ignore={"features"}, -): - """GIS Vector Layer""" - - name: Optional[str] = None - crs: Optional[Union[CRS, Base]] = None - units: Optional[str] = None - elements: Optional[List[Base]] = None - attributes: Optional[Base] = None - geomType: Optional[str] = "None" - renderer: Optional[Dict[str, Any]] = None - collectionType = "VectorLayer" - - @property - @deprecated(version="2.14", reason="Use elements") - def features(self) -> Optional[List[Base]]: - return self.elements - - @features.setter - def features(self, value: Optional[List[Base]]) -> None: - self.elements = value - - -@deprecated(version="2.16", reason="Use VectorLayer or RasterLayer instead") -class RasterLayer( - Collection, - detachable={"elements"}, - speckle_type="RasterLayer", - serialize_ignore={"features"}, -): - """GIS Raster Layer""" - - name: Optional[str] = None - crs: Optional[Union[CRS, Base]] = None - units: Optional[str] = None - rasterCrs: Optional[Union[CRS, Base]] = None - elements: Optional[List[Base]] = None - geomType: Optional[str] = "None" - renderer: Optional[Dict[str, Any]] = None - collectionType = "RasterLayer" - - @property - @deprecated(version="2.14", reason="Use elements") - def features(self) -> Optional[List[Base]]: - return self.elements - - @features.setter - def features(self, value: Optional[List[Base]]) -> None: - self.elements = value - - -class VectorLayer( # noqa: F811 - Collection, - detachable={"elements"}, - speckle_type="Objects.GIS.VectorLayer", - serialize_ignore={"features"}, -): - """GIS Vector Layer""" - - name: Optional[str] = None - crs: Optional[Union[CRS, Base]] = None - units: Optional[str] = None - elements: Optional[List[Base]] = None - attributes: Optional[Base] = None - geomType: Optional[str] = "None" - renderer: Optional[Dict[str, Any]] = None - collectionType = "VectorLayer" - - @property - @deprecated(version="2.14", reason="Use elements") - def features(self) -> Optional[List[Base]]: - return self.elements - - @features.setter - def features(self, value: Optional[List[Base]]) -> None: - self.elements = value - - -class RasterLayer( # noqa: F811 - Collection, - detachable={"elements"}, - speckle_type="Objects.GIS.RasterLayer", - serialize_ignore={"features"}, -): - """GIS Raster Layer""" - - name: Optional[str] = None - crs: Optional[Union[CRS, Base]] = None - units: Optional[str] = None - rasterCrs: Optional[Union[CRS, Base]] = None - elements: Optional[List[Base]] = None - geomType: Optional[str] = "None" - renderer: Optional[Dict[str, Any]] = None - collectionType = "RasterLayer" - - @property - @deprecated(version="2.14", reason="Use elements") - def features(self) -> Optional[List[Base]]: - return self.elements - - @features.setter - def features(self, value: Optional[List[Base]]) -> None: - self.elements = value diff --git a/src/specklepy/objects_v2/__init__.py b/src/specklepy/objects_v2/__init__.py deleted file mode 100644 index 3e363623..00000000 --- a/src/specklepy/objects_v2/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Builtin Speckle object kit.""" - -# from specklepy.objects import ( -# GIS, -# encoding, -# geometry, -# other, -# primitive, -# structural, -# units, -# ) -from specklepy.objects.base import Base - -__all__ = [ - "Base", - # "encoding", - # "geometry", - # "other", - # "units", - # "structural", - # "primitive", - # "GIS", -] diff --git a/src/specklepy/objects_v2/base.py b/src/specklepy/objects_v2/base.py deleted file mode 100644 index 035ee2fa..00000000 --- a/src/specklepy/objects_v2/base.py +++ /dev/null @@ -1,595 +0,0 @@ -import contextlib -from enum import Enum -from inspect import isclass -from typing import ( - Any, - ClassVar, - Dict, - ForwardRef, - List, - Optional, - Set, - Tuple, - Type, - Union, - get_type_hints, -) -from warnings import warn - -from stringcase import pascalcase - -from specklepy.logging.exceptions import SpeckleException, SpeckleInvalidUnitException -from specklepy.objects_v2.units import Units -from specklepy.transports.memory import MemoryTransport - -PRIMITIVES = (int, float, str, bool) - -# to remove from dir() when calling get_member_names() -REMOVE_FROM_DIR = { - "Config", - "_Base__dict_helper", - "__annotations__", - "__class__", - "__delattr__", - "__dict__", - "__dir__", - "__doc__", - "__eq__", - "__format__", - "__ge__", - "__getattribute__", - "__getitem__", - "__gt__", - "__hash__", - "__init__", - "__init_subclass__", - "__le__", - "__lt__", - "__module__", - "__ne__", - "__new__", - "__reduce__", - "__reduce_ex__", - "__repr__", - "__setattr__", - "__setitem__", - "__sizeof__", - "__str__", - "__subclasshook__", - "__weakref__", - "_chunk_size_default", - "_chunkable", - "_count_descendants", - "_attr_types", - "_detachable", - "_handle_object_count", - "_type_check", - "_type_registry", - "_units", - "add_chunkable_attrs", - "add_detachable_attrs", - "get_children_count", - "get_dynamic_member_names", - "get_id", - "get_member_names", - "get_registered_type", - "get_typed_member_names", - "to_dict", - "update_forward_refs", - "validate_prop_name", - "from_list", - "to_list", -} - - -class _RegisteringBase: - """ - Private Base model for Speckle types. - - This is an implementation detail, please do not use this outside this module. - - This class provides automatic registration of `speckle_type` into a global, - (class level) registry for each subclassing type. - The type registry is a base for accurate type based (de)serialization. - """ - - speckle_type: ClassVar[str] - _speckle_type_override: ClassVar[Optional[str]] = None - _speckle_namespace: ClassVar[Optional[str]] = None - _type_registry: ClassVar[Dict[str, Type["Base"]]] = {} - _attr_types: ClassVar[Dict[str, Type]] = {} - # dict of chunkable props and their max chunk size - _chunkable: Dict[str, int] = {} - _chunk_size_default: int = 1000 - _detachable: Set[str] = set() # list of defined detachable props - _serialize_ignore: Set[str] = set() - - @classmethod - def get_registered_type(cls, speckle_type: str) -> Optional[Type["Base"]]: - """Get the registered type from the protected mapping via the `speckle_type`""" - for full_name in reversed(speckle_type.split(":")): - maybe_type = cls._type_registry.get(full_name, None) - if maybe_type: - return maybe_type - return None - - @classmethod - def _determine_speckle_type(cls) -> str: - """ - This method brings the speckle_type construction in par with Speckle-sharp/Core. - - The implementation differs, because in Core the basis of the speckle_type if - type.FullName, which includes the dotnet namespace name too. - Copying that behavior is hard in python, where the concept of namespaces - means something entirely different. - - So we enabled a speckle_type override mechanism, that enables - """ - base_name = "Base" - if cls.__name__ == base_name: - return base_name - - bases = [ - b._full_name() - for b in reversed(cls.mro()) - if issubclass(b, Base) and b.__name__ != base_name - ] - return ":".join(bases) - - @classmethod - def _full_name(cls) -> str: - base_name = "Base" - if cls.__name__ == base_name: - return base_name - - if cls._speckle_type_override: - return cls._speckle_type_override - - # convert the module names to PascalCase to match c# namespace naming convention - # also drop specklepy from the beginning - namespace = ".".join( - pascalcase(m) - for m in filter(lambda name: name != "specklepy", cls.__module__.split(".")) - ) - return f"{namespace}.{cls.__name__}" - - def __init_subclass__( - cls, - speckle_type: Optional[str] = None, - chunkable: Optional[Dict[str, int]] = None, - detachable: Optional[Set[str]] = None, - serialize_ignore: Optional[Set[str]] = None, - **kwargs: Dict[str, Any], - ): - """ - Hook into subclass type creation. - - This is provides a mechanism to hook into the event of the subclass type object - initialization. This is reused to register each subclassing type into a class - level dictionary. - """ - # if not speckle_type: - # raise Exception("no type") - cls._speckle_type_override = speckle_type - cls.speckle_type = cls._determine_speckle_type() - # cls.speckle_type = speckle_type - if cls._full_name() in cls._type_registry: - raise ValueError( - f"The speckle_type: {speckle_type} is already registered for type: " - f"{cls._type_registry[cls._full_name()].__name__}. " - "Please choose a different type name." - ) - cls._type_registry[cls._full_name()] = cls # type: ignore - try: - cls._attr_types = get_type_hints(cls) - except Exception: - cls._attr_types = getattr(cls, "__annotations__", {}) - if chunkable: - chunkable = {k: v for k, v in chunkable.items() if isinstance(v, int)} - cls._chunkable = dict(cls._chunkable, **chunkable) - if detachable: - cls._detachable = cls._detachable.union(detachable) - if serialize_ignore: - cls._serialize_ignore = cls._serialize_ignore.union(serialize_ignore) - # we know, that the super here is object, that takes no args on init subclass - return super().__init_subclass__() - - -# T = TypeVar("T") - -# how i wish the code below would be correct, but we're also parsing into floats -# and converting into strings if the original type is string, but the value isn't -# def _validate_type(t: type, value: T) -> Tuple[bool, T]: - - -def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]: - # this should be reworked. Its only ok to return null for Optionals... - # if t is None and value is None: - if value is None: - return True, value - - # after fixing the None t above, this should be - # if t is Any: - # if t is None: - - if t is None or t is Any: - return True, value - - if isclass(t) and issubclass(t, Enum): - if isinstance(value, t): - return True, value - if value in t._value2member_map_: - return True, t(value) - - if getattr(t, "__module__", None) == "typing": - if isinstance(t, ForwardRef): - return True, value - - origin = t.__origin__ - # below is what in nicer for >= py38 - # origin = get_origin(t) - - # recursive validation for Unions on both types preferring the fist type - if origin is Union: - # below is what in nicer for >= py38 - # t_1, t_2 = get_args(t) - args = t.__args__ # type: ignore - for arg_t in args: - t_success, t_value = _validate_type(arg_t, value) - if t_success: - return True, t_value - return False, value - if origin is dict: - if not isinstance(value, dict): - return False, value - if value == {}: - return True, value - if not getattr(t, "__args__", None): - return True, value - t_key, t_value = t.__args__ # type: ignore - - if ( - getattr(t_key, "__name__", None), - getattr(t_value, "__name__", None), - ) == ("KT", "VT"): - return True, value - # we're only checking the first item, but the for loop and return after - # evaluating the first item is the fastest way - for dict_key, dict_value in value.items(): - valid_key, _ = _validate_type(t_key, dict_key) - valid_value, _ = _validate_type(t_value, dict_value) - - if valid_key and valid_value: - return True, value - return False, value - - if origin is list: - if not isinstance(value, list): - return False, value - if value == []: - return True, value - if not hasattr(t, "__args__"): - return True, value - t_items = t.__args__[0] # type: ignore - if getattr(t_items, "__name__", None) == "T": - return True, value - first_item_valid, _ = _validate_type(t_items, value[0]) - if first_item_valid: - return True, value - return False, value - - if origin is tuple: - if not isinstance(value, tuple): - return False, value - if not hasattr(t, "__args__"): - return True, value - args = t.__args__ # type: ignore - if args == tuple(): - return True, value - # we're not checking for empty tuple, cause tuple lengths must match - if len(args) != len(value): - return False, value - values = [] - for t_item, v_item in zip(args, value, strict=True): - item_valid, item_value = _validate_type(t_item, v_item) - if not item_valid: - return False, value - values.append(item_value) - return True, tuple(values) - - if origin is set: - if not isinstance(value, set): - return False, value - if not hasattr(t, "__args__"): - return True, value - t_items = t.__args__[0] # type: ignore - first_item_valid, _ = _validate_type(t_items, next(iter(value))) - if first_item_valid: - return True, value - return False, value - - if isinstance(value, t): - return True, value - - with contextlib.suppress(ValueError, TypeError): - if t is float and value is not None: - return True, float(value) - # TODO: dafuq, i had to add this not list check - # but it would also fail for objects and other complex values - if t is str and value and not isinstance(value, list): - return True, str(value) - - return False, value - - -class Base(_RegisteringBase, speckle_type="Base"): - # id: Union[str, None] = None - # totalChildrenCount: Union[int, None] = None - # applicationId: Union[str, None] = None - _units: Union[None, str] = None - - def __init__( - self, - id: str | None = None, - # totalChildrenCount: Union[int, None] = None, - applicationId: str | None = None, - **kwargs, - ) -> None: - self.id = id - # self.totalChildrenCount = totalChildrenCount - self.applicationId = applicationId - super().__init__() - for k, v in kwargs.items(): - self.__setattr__(k, v) - - def __repr__(self) -> str: - return ( - f"{self.__class__.__name__}(id: {self.id}, " - f"speckle_type: {self.speckle_type}, " - # f"totalChildrenCount: {self.totalChildrenCount})" - ) - - def __str__(self) -> str: - return self.__repr__() - - @classmethod - def of_type(cls, speckle_type: str, **kwargs) -> "Base": - """ - Get a plain Base object with a specified speckle_type. - - The speckle_type is protected and cannot be overwritten on a class instance. - This is to prevent problems with receiving in other platforms or connectors. - However, if you really need a base with a different type, here is a helper - to do that for you. - - This is used in the deserialisation of unknown types so their speckle_type - can be preserved. - """ - b = cls(**kwargs) - b.__dict__.update(speckle_type=speckle_type) - return b - - def __setitem__(self, name: str, value: Any) -> None: - self.validate_prop_name(name) - self.__dict__[name] = value - - def __getitem__(self, name: str) -> Any: - return self.__dict__[name] - - def __setattr__(self, name: str, value: Any) -> None: - """ - Type checking, guard attribute, and property set mechanism. - - The `speckle_type` is a protected class attribute it must not be overridden. - - This also performs a type check if the attribute is type hinted. - """ - if name == "speckle_type": - # not sure if we should raise an exception here?? - # raise SpeckleException( - # "Cannot override the `speckle_type`." - # "This is set manually by the class or on deserialisation" - # ) - return - # if value is not None: - value = self._type_check(name, value) - attr = getattr(self.__class__, name, None) - if isinstance(attr, property): - try: - attr.__set__(self, value) - except AttributeError: - return # the prop probably doesn't have a setter - super().__setattr__(name, value) - - @classmethod - def update_forward_refs(cls) -> None: - """ - Attempts to populate the internal defined types dict for type checking - sometime after defining the class. - This is already done when defining the class, but can be called - again if references to undefined types were - included. - - See `objects.geometry` for an example of how this is used with - the Brep class definitions. - """ - try: - cls._attr_types = get_type_hints(cls) - except Exception as e: - warn( - f"Could not update forward refs for class {cls.__name__}: {e}", - stacklevel=2, - ) - - @classmethod - def validate_prop_name(cls, name: str) -> None: - """Validator for dynamic attribute names.""" - if name in {"", "@"}: - raise ValueError("Invalid Name: Base member names cannot be empty strings") - if name.startswith("@@"): - raise ValueError( - "Invalid Name: Base member names cannot start with more than one '@'", - ) - if "." in name or "/" in name: - raise ValueError( - "Invalid Name: Base member names cannot contain characters '.' or '/'", - ) - - def _type_check(self, name: str, value: Any) -> Any: - """ - Lightweight type checking of values before setting them - - NOTE: Does not check subscripted types within generics as the performance hit - of checking each item within a given collection isn't worth it. - Eg if you have a type Dict[str, float], - we will only check if the value you're trying to set is a dict. - """ - types = getattr(self, "_attr_types", {}) - t = types.get(name, None) - - valid, checked_value = _validate_type(t, value) - - if valid: - return checked_value - - raise SpeckleException( - f"Cannot set '{self.__class__.__name__}.{name}':" - f"it expects type '{str(t)}'," - f"but received type '{type(value).__name__}'" - ) - - def add_chunkable_attrs(self, **kwargs: int) -> None: - """ - Mark defined attributes as chunkable for serialisation - - Arguments: - kwargs {int} -- the name of the attribute as the keyword - and the chunk size as the arg - """ - chunkable = {k: v for k, v in kwargs.items() if isinstance(v, int)} - self._chunkable = dict(self._chunkable, **chunkable) - - def add_detachable_attrs(self, names: Set[str]) -> None: - """ - Mark defined attributes as detachable for serialisation - - Arguments: - names {Set[str]} -- the names of the attributes to detach as a set of string - """ - self._detachable = self._detachable.union(names) - - @property - def units(self) -> Union[str, None]: - return self._units - - @units.setter - def units(self, value: Union[str, Units, None]): - """ - While this property accepts any string value, - geometry expects units to be specific strings (see Units enum) - """ - if isinstance(value, str) or value is None: - self._units = value - elif isinstance(value, Units): - self._units = value.value - else: - raise SpeckleInvalidUnitException( - f"Unknown type {type(value)} received for units" - ) - - def get_member_names(self) -> List[str]: - """Get all of the property names on this object, dynamic or not""" - attr_dir = list(set(dir(self)) - REMOVE_FROM_DIR) - return [ - name - for name in attr_dir - if not name.startswith("_") and not callable(getattr(self, name)) - ] - - def get_serializable_attributes(self) -> List[str]: - """Get the attributes that should be serialized""" - return sorted(list(set(self.get_member_names()) - self._serialize_ignore)) - - def get_typed_member_names(self) -> List[str]: - """Get all of the names of the defined (typed) properties of this object""" - return list(self._attr_types.keys()) - - def get_dynamic_member_names(self) -> List[str]: - """Get all of the names of the dynamic properties of this object""" - return list(set(self.__dict__.keys()) - set(self._attr_types.keys())) - - def get_children_count(self) -> int: - """Get the total count of children Base objects""" - parsed = [] - return 1 + self._count_descendants(self, parsed) - - def get_id(self, decompose: bool = False) -> str: - """ - Gets the id (a unique hash) of this object. - ⚠️ This method fully serializes the object which, - in the case of large objects (with many sub-objects), has a tangible cost. - Avoid using it! - - Note: the hash of a decomposed object differs from that of a - non-decomposed object - - Arguments: - decompose {bool} -- if True, will decompose the object in - the process of hashing it - - Returns: - str -- the hash (id) of the fully serialized object - """ - from specklepy.serialization.base_object_serializer import BaseObjectSerializer - - serializer = BaseObjectSerializer() - if decompose: - serializer.write_transports = [MemoryTransport()] - return serializer.traverse_base(self)[0] - - def _count_descendants(self, base: "Base", parsed: List) -> int: - if base in parsed: - return 0 - parsed.append(base) - - return sum( - self._handle_object_count(value, parsed) - for name, value in base.get_member_names() - if not name.startswith("@") - ) - - def _handle_object_count(self, obj: Any, parsed: List) -> int: - # pylint: disable=isinstance-second-argument-not-valid-type - count = 0 - if obj is None: - return count - if isinstance(obj, "Base"): - count += 1 - count += self._count_descendants(obj, parsed) - return count - elif isinstance(obj, list): - for item in obj: - if isinstance(item, "Base"): - count += 1 - count += self._count_descendants(item, parsed) - else: - count += self._handle_object_count(item, parsed) - elif isinstance(obj, dict): - for _, value in obj.items(): - if isinstance(value, "Base"): - count += 1 - count += self._count_descendants(value, parsed) - else: - count += self._handle_object_count(value, parsed) - return count - - -Base.update_forward_refs() - - -class DataChunk(Base, speckle_type="Speckle.Core.Models.DataChunk"): - data: Union[List[Any], None] = None - - def __init__(self) -> None: - super().__init__() - self.data = [] diff --git a/src/specklepy/objects_v2/encoding.py b/src/specklepy/objects_v2/encoding.py deleted file mode 100644 index eab2d873..00000000 --- a/src/specklepy/objects_v2/encoding.py +++ /dev/null @@ -1,131 +0,0 @@ -from enum import Enum -from typing import Any, Callable, Dict, List, Optional, Type - -from specklepy.logging.exceptions import SpeckleException -from specklepy.objects.base import Base - - -class CurveTypeEncoding(int, Enum): - Arc = 0 - Circle = 1 - Curve = 2 - Ellipse = 3 - Line = 4 - Polyline = 5 - Polycurve = 6 - - @property - def object_class(self) -> Type: - from . import geometry - - if self == self.Arc: - return geometry.Arc - elif self == self.Circle: - return geometry.Circle - elif self == self.Curve: - return geometry.Curve - elif self == self.Ellipse: - return geometry.Ellipse - elif self == self.Line: - return geometry.Line - elif self == self.Polyline: - return geometry.Polyline - elif self == self.Polycurve: - return geometry.Polycurve - raise SpeckleException( - f"No corresponding object class for CurveTypeEncoding: {self}" - ) - - -def curve_from_list(args: List[float]): - curve_type = CurveTypeEncoding(args[0]) - return curve_type.object_class.from_list(args) - - -class ObjectArray: - def __init__(self, data: Optional[list] = None) -> None: - self.data = data or [] - - @classmethod - def from_objects(cls, objects: List[Base]) -> "ObjectArray": - data_list = cls() - if not objects: - return data_list - - speckle_type = objects[0].speckle_type - - for obj in objects: - if speckle_type != obj.speckle_type: - raise SpeckleException( - "All objects in chunk should have the same speckle_type. " - f"Found {speckle_type} and {obj.speckle_type}" - ) - data_list.encode_object(obj=obj) - - return data_list - - @staticmethod - def decode_data( - data: List[Any], decoder: Callable[[List[Any]], Base], **kwargs: Dict[str, Any] - ) -> List[Base]: - bases: List[Base] = [] - if not data: - return bases - index = 0 - while index < len(data): - item_length = int(data[index]) - item_start = index + 1 - item_end = item_start + item_length - item_data = data[item_start:item_end] - index = item_end - decoded_data = decoder(item_data, **kwargs) - bases.append(decoded_data) - - return bases - - def decode(self, decoder: Callable[[List[Any]], Any], **kwargs: Dict[str, Any]): - return self.decode_data(data=self.data, decoder=decoder, **kwargs) - - def encode_object(self, obj: Base): - encoded = obj.to_list() - encoded.insert(0, len(encoded)) - self.data.extend(encoded) - - -class CurveArray(ObjectArray): - @classmethod - def from_curve(cls, curve: Base) -> "CurveArray": - crv_array = cls() - crv_array.data = curve.to_list() - return crv_array - - @classmethod - def from_curves(cls, curves: List[Base]) -> "CurveArray": - data = [] - for curve in curves: - curve_list = curve.to_list() - curve_list.insert(0, len(curve_list)) - data.extend(curve_list) - crv_array = cls() - crv_array.data = data - return crv_array - - @staticmethod - def curve_from_list(args: List[float]) -> Base: - curve_type = CurveTypeEncoding(args[0]) - return curve_type.object_class.from_list(args) - - @property - def type(self) -> CurveTypeEncoding: - return CurveTypeEncoding(self.data[0]) - - def to_curve(self) -> Base: - return self.type.object_class.from_list(self.data) - - @classmethod - def _curve_decoder(cls, data: List[float]) -> Base: - crv_array = cls(data) - return crv_array.to_curve() - - def to_curves(self) -> List[Base]: - return self.decode(decoder=self._curve_decoder) diff --git a/src/specklepy/objects_v2/geometry.py b/src/specklepy/objects_v2/geometry.py deleted file mode 100644 index 5f7f1e28..00000000 --- a/src/specklepy/objects_v2/geometry.py +++ /dev/null @@ -1,948 +0,0 @@ -from enum import Enum -from typing import Any, List, Optional - -from specklepy.objects_v2.base import Base -from specklepy.objects_v2.encoding import CurveArray, CurveTypeEncoding, ObjectArray -from specklepy.objects_v2.primitive import Interval -from specklepy.objects_v2.units import get_encoding_from_units, get_units_from_encoding - -GEOMETRY = "Objects.Geometry." - - -class Point(Base, speckle_type=GEOMETRY + "Point"): - x: float = 0.0 - y: float = 0.0 - z: float = 0.0 - - def __repr__(self) -> str: - return ( - f"{self.__class__.__name__}(x: {self.x}, y: {self.y}, z: {self.z}, id:" - f" {self.id}, speckle_type: {self.speckle_type})" - ) - - @classmethod - def from_list(cls, args: List[float]) -> "Point": - """ - Create a new Point from a list of three floats - representing the x, y, and z coordinates - """ - return cls(x=args[0], y=args[1], z=args[2]) - - def to_list(self) -> List[Any]: - return [self.x, self.y, self.z] - - @classmethod - def from_coords(cls, x: float = 0.0, y: float = 0.0, z: float = 0.0): - """Create a new Point from x, y, and z values""" - pt = Point() - pt.x, pt.y, pt.z = x, y, z - return pt - - -class Pointcloud( - Base, - speckle_type=GEOMETRY + "Pointcloud", - chunkable={"points": 31250, "colors": 62500, "sizes": 62500}, -): - points: Optional[List[float]] = None - colors: Optional[List[int]] = None - sizes: Optional[List[float]] = None - bbox: Optional["Box"] = None - - -class Vector(Base, speckle_type=GEOMETRY + "Vector"): - x: float = 0.0 - y: float = 0.0 - z: float = 0.0 - applicationId: Optional[str] = None - - 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})" - ) - - @classmethod - def from_list(cls, args: List[float]) -> "Vector": - """ - Create from a list of three floats representing the x, y, and z coordinates. - """ - return cls(x=args[0], y=args[1], z=args[2]) - - def to_list(self) -> List[float]: - return [self.x, self.y, self.z] - - @classmethod - def from_coords(cls, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> "Vector": - """Create a new Point from x, y, and z values""" - v = Vector() - v.x, v.y, v.z = x, y, z - return v - - -class ControlPoint(Point, speckle_type=GEOMETRY + "ControlPoint"): - weight: Optional[float] = None - - -class Plane(Base, speckle_type=GEOMETRY + "Plane"): - origin: Point = Point() - normal: Vector = Vector() - xdir: Vector = Vector() - ydir: Vector = Vector() - - @classmethod - def from_list(cls, args: List[Any]) -> "Plane": - return cls( - origin=Point.from_list(args[:3]), - normal=Vector.from_list(args[3:6]), - xdir=Vector.from_list(args[6:9]), - ydir=Vector.from_list(args[9:12]), - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - return [ - *self.origin.to_list(), - *self.normal.to_list(), - *self.xdir.to_list(), - *self.ydir.to_list(), - get_encoding_from_units(self._units), - ] - - -class Box(Base, speckle_type=GEOMETRY + "Box"): - basePlane: Plane = Plane() - xSize: Interval = Interval() - ySize: Interval = Interval() - zSize: Interval = Interval() - area: Optional[float] = None - volume: Optional[float] = None - - -class Line(Base, speckle_type=GEOMETRY + "Line"): - start: Point = Point() - end: Optional[Point] = None - domain: Optional[Interval] = None - bbox: Optional[Box] = None - length: Optional[float] = None - - @classmethod - def from_list(cls, args: List[Any]) -> "Line": - return cls( - start=Point.from_list(args[1:4]), - end=Point.from_list(args[4:7]), - domain=Interval.from_list(args[7:10]), - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - domain = self.domain.to_list() if self.domain else [0, 1] - return [ - CurveTypeEncoding.Line.value, - *self.start.to_list(), - *self.end.to_list(), - *domain, - get_encoding_from_units(self._units), - ] - - -class Arc(Base, speckle_type=GEOMETRY + "Arc"): - radius: Optional[float] = None - startAngle: Optional[float] = None - endAngle: Optional[float] = None - angleRadians: Optional[float] = None - plane: Optional[Plane] = None - domain: Optional[Interval] = None - startPoint: Optional[Point] = None - midPoint: Optional[Point] = None - endPoint: Optional[Point] = None - bbox: Optional[Box] = None - area: Optional[float] = None - length: Optional[float] = None - - @classmethod - def from_list(cls, args: List[Any]) -> "Arc": - return cls( - radius=args[1], - startAngle=args[2], - endAngle=args[3], - angleRadians=args[4], - domain=Interval.from_list(args[5:7]), - plane=Plane.from_list(args[7:20]), - startPoint=Point.from_list(args[20:23]), - midPoint=Point.from_list(args[23:26]), - endPoint=Point.from_list(args[26:29]), - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - return [ - CurveTypeEncoding.Arc.value, - self.radius, - self.startAngle, - self.endAngle, - self.angleRadians, - *self.domain.to_list(), - *self.plane.to_list(), - *self.startPoint.to_list(), - *self.midPoint.to_list(), - *self.endPoint.to_list(), - get_encoding_from_units(self._units), - ] - - -class Circle(Base, speckle_type=GEOMETRY + "Circle"): - radius: Optional[float] = None - plane: Optional[Plane] = None - domain: Optional[Interval] = None - bbox: Optional[Box] = None - area: Optional[float] = None - length: Optional[float] = None - - @classmethod - def from_list(cls, args: List[Any]) -> "Circle": - return cls( - radius=args[1], - domain=Interval.from_list(args[2:4]), - plane=Plane.from_list(args[4:17]), - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - return [ - CurveTypeEncoding.Circle.value, - self.radius, - *self.domain.to_list(), - *self.plane.to_list(), - get_encoding_from_units(self._units), - ] - - -class Ellipse(Base, speckle_type=GEOMETRY + "Ellipse"): - firstRadius: Optional[float] = None - secondRadius: Optional[float] = None - plane: Optional[Plane] = None - domain: Optional[Interval] = None - trimDomain: Optional[Interval] = None - bbox: Optional[Box] = None - area: Optional[float] = None - length: Optional[float] = None - - @classmethod - def from_list(cls, args: List[Any]) -> "Ellipse": - return cls( - firstRadius=args[1], - secondRadius=args[2], - domain=Interval.from_list(args[3:5]), - plane=Plane.from_list(args[5:18]), - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - return [ - CurveTypeEncoding.Ellipse.value, - self.firstRadius, - self.secondRadius, - *self.domain.to_list(), - *self.plane.to_list(), - get_encoding_from_units(self._units), - ] - - -class Polyline(Base, speckle_type=GEOMETRY + "Polyline", chunkable={"value": 20000}): - value: Optional[List[float]] = None - closed: Optional[bool] = None - domain: Optional[Interval] = None - bbox: Optional[Box] = None - area: Optional[float] = None - length: Optional[float] = None - - @classmethod - def from_points(cls, points: List[Point]): - """Create a new Polyline from a list of Points""" - polyline = cls() - polyline.units = points[0].units - polyline.value = [] - for point in points: - polyline.value.extend([point.x, point.y, point.z]) - return polyline - - @classmethod - def from_list(cls, args: List[Any]) -> "Polyline": - point_count = args[4] - return cls( - closed=bool(args[1]), - domain=Interval.from_list(args[2:4]), - value=args[5 : 5 + point_count], - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - return [ - CurveTypeEncoding.Polyline.value, - int(self.closed), - *self.domain.to_list(), - len(self.value), - *self.value, - get_encoding_from_units(self._units), - ] - - 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(x=v, y=next(values), z=next(values), units=self.units) for v in values - ] - - -class SpiralType(Enum): - Biquadratic = 0 - BiquadraticParabola = 1 - Bloss = 2 - Clothoid = 3 - Cosine = 4 - Cubic = 5 - CubicParabola = 6 - Radioid = 7 - Sinusoid = 8 - Unknown = 9 - - -class Spiral(Base, speckle_type=GEOMETRY + "Spiral", detachable={"displayValue"}): - startPoint: Optional[Point] = None - endPoint: Optional[Point] - plane: Optional[Plane] - turns: Optional[float] - pitchAxis: Optional[Vector] = Vector() - pitch: float = 0 - spiralType: Optional[SpiralType] = None - displayValue: Optional[Polyline] = None - bbox: Optional[Box] = None - length: Optional[float] = None - domain: Optional[Interval] = None - - -class Curve( - Base, - speckle_type=GEOMETRY + "Curve", - chunkable={"points": 20000, "weights": 20000, "knots": 20000}, -): - degree: Optional[int] = None - periodic: Optional[bool] = None - rational: Optional[bool] = None - points: Optional[List[float]] = None - weights: Optional[List[float]] = None - knots: Optional[List[float]] = None - domain: Optional[Interval] = None - displayValue: Optional[Polyline] = None - closed: Optional[bool] = None - bbox: Optional[Box] = None - area: Optional[float] = None - length: Optional[float] = None - - 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(x=v, y=next(values), z=next(values), units=self.units) for v in values - ] - - @classmethod - def from_list(cls, args: List[Any]) -> "Curve": - point_count = int(args[7]) - weights_count = int(args[8]) - knots_count = int(args[9]) - - points_start = 10 - weights_start = 10 + point_count - knots_start = weights_start + weights_count - knots_end = knots_start + knots_count - - return cls( - degree=int(args[1]), - periodic=bool(args[2]), - rational=bool(args[3]), - closed=bool(args[4]), - domain=Interval.from_list(args[5:7]), - points=args[points_start:weights_start], - weights=args[weights_start:knots_start], - knots=args[knots_start:knots_end], - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - return [ - CurveTypeEncoding.Curve.value, - self.degree, - int(self.periodic), - int(self.rational), - int(self.closed), - *self.domain.to_list(), - len(self.points), - len(self.weights), - len(self.knots), - *self.points, - *self.weights, - *self.knots, - get_encoding_from_units(self._units), - ] - - -class Polycurve(Base, speckle_type=GEOMETRY + "Polycurve"): - segments: Optional[List[Base]] = None - domain: Optional[Interval] = None - closed: Optional[bool] = None - bbox: Optional[Box] = None - area: Optional[float] = None - length: Optional[float] = None - - @classmethod - def from_list(cls, args: List[Any]) -> "Polycurve": - curve_arrays = CurveArray(args[5:-1]) - return cls( - closed=bool(args[1]), - domain=Interval.from_list(args[2:4]), - segments=curve_arrays.to_curves(), - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - curve_array = CurveArray.from_curves(self.segments).data - return [ - CurveTypeEncoding.Polycurve.value, - int(self.closed), - *self.domain.to_list(), - len(curve_array), - *curve_array, - get_encoding_from_units(self._units), - ] - - -class Extrusion(Base, speckle_type=GEOMETRY + "Extrusion"): - capped: Optional[bool] = None - profile: Optional[Base] = None - pathStart: Optional[Point] = None - pathEnd: Optional[Point] = None - pathCurve: Optional[Base] = None - pathTangent: Optional[Base] = None - profiles: Optional[List[Base]] = None - length: Optional[float] = None - area: Optional[float] = None - volume: Optional[float] = None - bbox: Optional[Box] = None - - -class Mesh( - Base, - speckle_type=GEOMETRY + "Mesh", - chunkable={ - "vertices": 2000, - "faces": 2000, - "colors": 2000, - "textureCoordinates": 2000, - }, -): - vertices: Optional[List[float]] = None - faces: Optional[List[int]] = None - colors: Optional[List[int]] = None - textureCoordinates: Optional[List[float]] = None - bbox: Optional[Box] = None - area: Optional[float] = None - volume: Optional[float] = None - - @classmethod - def create( - cls, - vertices: List[float], - faces: List[int], - colors: Optional[List[int]] = None, - texture_coordinates: Optional[List[float]] = None, - ) -> "Mesh": - """ - Create a new Mesh from lists representing its vertices, faces, - colors (optional), and texture coordinates (optional). - - This will initialise empty lists for colors and texture coordinates - if you do not provide any. - """ - return cls( - vertices=vertices, - faces=faces, - colors=colors or [], - textureCoordinates=texture_coordinates or [], - ) - - -class Surface(Base, speckle_type=GEOMETRY + "Surface"): - degreeU: Optional[int] = None - degreeV: Optional[int] = None - rational: Optional[bool] = None - area: Optional[float] = None - pointData: Optional[List[float]] = None - countU: Optional[int] = None - countV: Optional[int] = None - bbox: Optional[Box] = None - closedU: Optional[bool] = None - closedV: Optional[bool] = None - domainU: Optional[Interval] = None - domainV: Optional[Interval] = None - knotsU: Optional[List[float]] = None - knotsV: Optional[List[float]] = None - - @classmethod - def from_list(cls, args: List[Any]) -> "Surface": - point_count = int(args[11]) - knots_u_count = int(args[12]) - knots_v_count = int(args[13]) - - start_point_data = 14 - start_knots_u = start_point_data + point_count - start_knots_v = start_knots_u + knots_u_count - - return cls( - degreeU=int(args[0]), - degreeV=int(args[1]), - countU=int(args[2]), - countV=int(args[3]), - rational=bool(args[4]), - closedU=bool(args[5]), - closedV=bool(args[6]), - domainU=Interval(start=args[7], end=args[8]), - domainV=Interval(start=args[9], end=args[10]), - pointData=args[start_point_data:start_knots_u], - knotsU=args[start_knots_u:start_knots_v], - knotsV=args[start_knots_v : start_knots_v + knots_v_count], - units=get_units_from_encoding(args[-1]), - ) - - def to_list(self) -> List[Any]: - return [ - self.degreeU, - self.degreeV, - self.countU, - self.countV, - int(self.rational), - int(self.closedU), - int(self.closedV), - *self.domainU.to_list(), - *self.domainV.to_list(), - len(self.pointData), - len(self.knotsU), - len(self.knotsV), - *self.pointData, - *self.knotsU, - *self.knotsV, - get_encoding_from_units(self._units), - ] - - -class BrepFace(Base, speckle_type=GEOMETRY + "BrepFace"): - _Brep: Optional["Brep"] = None - SurfaceIndex: Optional[int] = None - OuterLoopIndex: Optional[int] = None - OrientationReversed: Optional[bool] = None - LoopIndices: Optional[List[int]] = None - - @property - def _outer_loop(self): - return self._Brep.Loops[self.OuterLoopIndex] # pylint: disable=no-member - - @property - def _surface(self): - return self._Brep.Surfaces[self.SurfaceIndex] # pylint: disable=no-member - - @property - def _loops(self): - if self.LoopIndices: - # pylint: disable=not-an-iterable, no-member - return [self._Brep.Loops[i] for i in self.LoopIndices] - - @classmethod - def from_list(cls, args: List[Any], brep: "Brep" = None) -> "BrepFace": - return cls( - _Brep=brep, - SurfaceIndex=args[0], - OuterLoopIndex=args[1], - OrientationReversed=bool(args[2]), - LoopIndices=args[3:], - ) - - def to_list(self) -> List[Any]: - return [ - self.SurfaceIndex, - self.OuterLoopIndex, - int(self.OrientationReversed), - *self.LoopIndices, - ] - - -class BrepEdge(Base, speckle_type=GEOMETRY + "BrepEdge"): - _Brep: Optional["Brep"] = None - Curve3dIndex: Optional[int] = None - TrimIndices: Optional[List[int]] = None - StartIndex: Optional[int] = None - EndIndex: Optional[int] = None - ProxyCurveIsReversed: Optional[bool] = None - Domain: Optional[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): - if self.TrimIndices: - # pylint: disable=not-an-iterable - return [self._Brep.Trims[i] for i in self.TrimIndices] - - @property - def _curve(self): - return self._Brep.Curve3D[self.Curve3dIndex] - - @classmethod - def from_list(cls, args: List[Any], brep: "Brep" = None) -> "BrepEdge": - domain_start = args[4] - domain_end = args[5] - domain = ( - Interval(start=domain_start, end=domain_end) - if None not in (domain_start, domain_end) - else None - ) - return cls( - _Brep=brep, - Curve3dIndex=int(args[0]), - TrimIndices=[int(t) for t in args[6:]], - StartIndex=int(args[1]), - EndIndex=int(args[2]), - ProxyCurveIsReversed=bool(args[3]), - Domain=domain, - ) - - def to_list(self) -> List[Any]: - return [ - self.Curve3dIndex, - self.StartIndex, - self.EndIndex, - int(self.ProxyCurveIsReversed), - self.Domain.start, - self.Domain.end, - *self.TrimIndices, - ] - - -class BrepLoopType(int, Enum): - Unknown = 0 - Outer = 1 - Inner = 2 - Slit = 3 - CurveOnSurface = 4 - PointOnSurface = 5 - - -class BrepLoop(Base, speckle_type=GEOMETRY + "BrepLoop"): - _Brep: Optional["Brep"] = None - FaceIndex: Optional[Optional[int]] = None - TrimIndices: Optional[List[int]] = None - Type: Optional[BrepLoopType] = None - - @property - def _face(self): - return self._Brep.Faces[self.FaceIndex] - - @property - def _trims(self): - if self.TrimIndices: - # pylint: disable=not-an-iterable - return [self._Brep.Trims[i] for i in self.TrimIndices] - - @classmethod - def from_list(cls, args: List[any], brep: "Brep" = None): - return cls( - _Brep=brep, - FaceIndex=args[0], - Type=BrepLoopType(args[1]), - TrimIndices=args[2:], - ) - - def to_list(self) -> List[int]: - return [ - self.FaceIndex, - self.Type.value, - *self.TrimIndices, - ] - - -class BrepTrimType(int, Enum): - Unknown = 0 - Boundary = 1 - Mated = 2 - Seam = 3 - Singular = 4 - CurveOnSurface = 5 - PointOnSurface = 6 - Slit = 7 - - -class BrepTrim(Base, speckle_type=GEOMETRY + "BrepTrim"): - _Brep: Optional["Brep"] = None - EdgeIndex: Optional[int] = None - StartIndex: Optional[int] = None - EndIndex: Optional[int] = None - FaceIndex: Optional[int] = None - LoopIndex: Optional[int] = None - CurveIndex: Optional[int] = None - IsoStatus: Optional[int] = None - TrimType: Optional[BrepTrimType] = None - IsReversed: Optional[bool] = None - Domain: Optional[Interval] = None - - @property - def _face(self): - if self._Brep: - return self._Brep.Faces[self.FaceIndex] # pylint: disable=no-member - - @property - def _loop(self): - if self._Brep: - return self._Brep.Loops[self.LoopIndex] # pylint: disable=no-member - - @property - def _edge(self): - if self._Brep: - # pylint: disable=no-member - return self._Brep.Edges[self.EdgeIndex] if self.EdgeIndex != -1 else None - - @property - def _curve_2d(self): - if self._Brep: - return self._Brep.Curve2D[self.CurveIndex] # pylint: disable=no-member - - @classmethod - def from_list(cls, args: List[Any], brep: "Brep" = None) -> "BrepTrim": - return cls( - _Brep=brep, - EdgeIndex=args[0], - StartIndex=args[1], - EndIndex=args[2], - FaceIndex=args[3], - LoopIndex=args[4], - CurveIndex=args[5], - IsoStatus=args[6], - TrimType=BrepTrimType(args[7]), - IsReversed=bool(args[8]), - ) - - def to_list(self) -> List[Any]: - return [ - self.EdgeIndex, - self.StartIndex, - self.EndIndex, - self.FaceIndex, - self.LoopIndex, - self.CurveIndex, - self.IsoStatus, - self.TrimType.value, - int(self.IsReversed), - ] - - -class Brep( - Base, - speckle_type=GEOMETRY + "Brep", - chunkable={ - "SurfacesValue": 31250, - "Curve3DValues": 31250, - "Curve2DValues": 31250, - "VerticesValue": 31250, - "EdgesValue": 62500, - "LoopsValue": 62500, - "FacesValue": 62500, - "TrimsValue": 62500, - }, - detachable={"displayValue"}, - serialize_ignore={ - "Surfaces", - "Curve3D", - "Curve2D", - "Vertices", - "Trims", - "Edges", - "Loops", - "Faces", - }, -): - provenance: Optional[str] = None - bbox: Optional[Box] = None - area: Optional[float] = None - volume: Optional[float] = None - _displayValue: Optional[List[Mesh]] = None - Surfaces: Optional[List[Surface]] = None - Curve3D: Optional[List[Base]] = None - Curve2D: Optional[List[Base]] = None - Vertices: Optional[List[Point]] = None - Edges: Optional[List[BrepEdge]] = None - Loops: Optional[List[BrepLoop]] = None - Faces: Optional[List[BrepFace]] = None - Trims: Optional[List[BrepTrim]] = None - IsClosed: Optional[bool] = None - Orientation: Optional[int] = None - - def _inject_self_into_children(self, children: Optional[List[Base]]) -> List[Base]: - if children is None: - return children - - for child in children: - child._Brep = self # pylint: disable=protected-access - return children - - # set as prop for now for backwards compatibility - @property - def displayValue(self) -> List[Mesh]: - return self._displayValue - - @displayValue.setter - def displayValue(self, value): - if isinstance(value, Mesh): - self._displayValue = [value] - elif isinstance(value, list): - self._displayValue = value - - @property - def EdgesValue(self) -> List[BrepEdge]: - return None if self.Edges is None else ObjectArray.from_objects(self.Edges).data - - @EdgesValue.setter - def EdgesValue(self, value: List[float]): - if not value: - return - - self.Edges = ObjectArray.decode_data(value, BrepEdge.from_list, brep=self) - - @property - def LoopsValue(self) -> List[BrepLoop]: - return None if self.Loops is None else ObjectArray.from_objects(self.Loops).data - - @LoopsValue.setter - def LoopsValue(self, value: List[int]): - if not value: - return - - self.Loops = ObjectArray.decode_data(value, BrepLoop.from_list, brep=self) - - @property - def FacesValue(self) -> List[int]: - return None if self.Faces is None else ObjectArray.from_objects(self.Faces).data - - @FacesValue.setter - def FacesValue(self, value: List[int]): - if not value: - return - - self.Faces = ObjectArray.decode_data(value, BrepFace.from_list, brep=self) - - @property - def SurfacesValue(self) -> List[float]: - return ( - None - if self.Surfaces is None - else ObjectArray.from_objects(self.Surfaces).data - ) - - @SurfacesValue.setter - def SurfacesValue(self, value: List[float]): - if not value: - return - - self.Surfaces = ObjectArray.decode_data(value, Surface.from_list) - - @property - def Curve3DValues(self) -> List[float]: - return ( - None if self.Curve3D is None else CurveArray.from_curves(self.Curve3D).data - ) - - @Curve3DValues.setter - def Curve3DValues(self, value: List[float]): - crv_array = CurveArray(value) - self.Curve3D = crv_array.to_curves() - - @property - def Curve2DValues(self) -> List[Base]: - return ( - None if self.Curve2D is None else CurveArray.from_curves(self.Curve2D).data - ) - - @Curve2DValues.setter - def Curve2DValues(self, value: List[float]): - crv_array = CurveArray(value) - self.Curve2D = crv_array.to_curves() - - @property - def VerticesValue(self) -> List[Point]: - if self.Vertices is None: - return None - encoded_unit = get_encoding_from_units(self.Vertices[0].units) - values = [encoded_unit] - for vertex in self.Vertices: - values.extend(vertex.to_list()) - return values - - @VerticesValue.setter - def VerticesValue(self, value: List[float]): - value = value.copy() - units = get_units_from_encoding(value.pop(0)) - - vertices = [] - - for i in range(0, len(value), 3): - vertex = Point.from_list(value[i : i + 3]) - vertex.units = units - vertices.append(vertex) - - self.Vertices = vertices - - # TODO: can this be consistent with loops, edges, faces, curves, - # etc and prepend with the chunk list? needs to happen in sharp first - @property - def TrimsValue(self) -> List[float]: - # return None if self.Trims is None else - # ObjectArray.from_objects(self.Trims).data - if not self.Trims: - return - value = [] - for trim in self.Trims: - value.extend(trim.to_list()) - return value - - @TrimsValue.setter - def TrimsValue(self, value: List[float]): - if not value: - return - - # self.Trims = ObjectArray.decode_data(value, BrepTrim.from_list, brep=self) - self.Trims = [ - BrepTrim.from_list(value[i : i + 9], self) for i in range(0, len(value), 9) - ] - - -BrepEdge.update_forward_refs() -BrepLoop.update_forward_refs() -BrepTrim.update_forward_refs() -BrepFace.update_forward_refs() diff --git a/src/specklepy/objects_v2/other.py b/src/specklepy/objects_v2/other.py deleted file mode 100644 index fbf4d436..00000000 --- a/src/specklepy/objects_v2/other.py +++ /dev/null @@ -1,311 +0,0 @@ -from typing import Any, List, Optional - -from deprecated import deprecated - -from specklepy.objects.geometry import Plane, Point, Polyline, Vector - -from .base import Base - -OTHER = "Objects.Other." -OTHER_REVIT = OTHER + "Revit." - -IDENTITY_TRANSFORM = [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, -] - - -class Material(Base, speckle_type=OTHER + "Material"): - """Generic class for materials containing generic parameters.""" - - name: Optional[str] = None - - -class RevitMaterial(Material, speckle_type="Objects.Other.Revit." + "RevitMaterial"): - materialCategory: Optional[str] = None - materialClass: Optional[str] = None - shininess: Optional[int] = None - smoothness: Optional[int] = None - transparency: Optional[int] = None - parameters: Optional[Base] = None - - -class RenderMaterial(Base, speckle_type=OTHER + "RenderMaterial"): - name: Optional[str] = None - opacity: float = 1 - metalness: float = 0 - roughness: float = 1 - diffuse: int = -2894893 # light gray arbg - emissive: int = -16777216 # black arbg - - -class MaterialQuantity(Base, speckle_type=OTHER + "MaterialQuantity"): - material: Optional[Material] = None - volume: Optional[float] = None - area: Optional[float] = None - - -class DisplayStyle(Base, speckle_type=OTHER + "DisplayStyle"): - """ - Minimal display style class. - Developed primarily for display styles in Rhino and AutoCAD. - Rhino object attributes uses OpenNURBS definition for linetypes and lineweights. - """ - - name: Optional[str] = None - color: int = -2894893 # light gray arbg - linetype: Optional[str] = None - lineweight: float = 0 - - -class Text(Base, speckle_type=OTHER + "Text"): - """ - Text object to render it on viewer. - """ - - plane: Plane - value: str - height: float - rotation: float - displayValue: Optional[List[Polyline]] = None - richText: Optional[str] = None - - -class Transform( - Base, - speckle_type=OTHER + "Transform", - serialize_ignore={"translation", "scaling", "is_identity", "value"}, -): - """The 4x4 transformation matrix - - The 3x3 sub-matrix determines scaling. - The 4th column defines translation, - where the last value is a divisor (usually equal to 1). - """ - - _value: Optional[List[float]] = None - - @property - @deprecated(version="2.12", reason="Use matrix") - def value(self) -> List[float]: - return self._value - - @value.setter - def value(self, value: List[float]) -> None: - self.matrix = value - - @property - def matrix(self) -> List[float]: - """The transform matrix represented as a flat list of 16 floats""" - return self._value - - @matrix.setter - def matrix(self, value: List[float]) -> None: - try: - value = [float(x) for x in value] - except (ValueError, TypeError) as error: - raise ValueError( - "Could not create a Transform object with the requested value. Input" - f" must be a 16 element list of numbers. Value provided: {value}" - ) from error - - if len(value) != 16: - raise ValueError( - "Could not create a Transform object: input list should be 16 floats" - f" long, but was {len(value)} long" - ) - - self._value = value - - @property - def translation(self) -> List[float]: - """The final column of the matrix which defines the translation""" - return [self._value[i] for i in (3, 7, 11, 15)] - - @property - def scaling(self) -> List[float]: - """The 3x3 scaling sub-matrix""" - return [self._value[i] for i in (0, 1, 2, 4, 5, 6, 8, 9, 10)] - - @property - def is_identity(self) -> bool: - return self._value == IDENTITY_TRANSFORM - - def apply_to_point(self, point: Point) -> Point: - """Transform a single speckle Point - - Arguments: - point {Point} -- the speckle Point to transform - - Returns: - Point -- a new transformed point - """ - coords = self.apply_to_point_value([point.x, point.y, point.z]) - return Point(x=coords[0], y=coords[1], z=coords[2], units=point.units) - - def apply_to_point_value(self, point_value: List[float]) -> List[float]: - """Transform a list of three floats representing a point - - Arguments: - point_value {List[float]} -- a list of 3 floats - - Returns: - List[float] -- the list with the transform applied - """ - transformed = [ - point_value[0] * self._value[i] - + point_value[1] * self._value[i + 1] - + point_value[2] * self._value[i + 2] - + self._value[i + 3] - for i in range(0, 15, 4) - ] - - return [transformed[i] / transformed[3] for i in range(3)] - - def apply_to_points(self, points: List[Point]) -> List[Point]: - """Transform a list of speckle Points - - Arguments: - points {List[Point]} -- the list of speckle Points to transform - - Returns: - List[Point] -- a new list of transformed points - """ - return [self.apply_to_point(point) for point in points] - - def apply_to_points_values(self, points_value: List[float]) -> List[float]: - """Transform a list of speckle Points - - Arguments: - points {List[float]} - -- a flat list of floats representing points to transform - - Returns: - List[float] -- a new transformed list - """ - if len(points_value) % 3 != 0: - raise ValueError( - "Cannot apply transform as the points list is malformed: expected" - " length to be multiple of 3" - ) - transformed = [] - for i in range(0, len(points_value), 3): - transformed.extend(self.apply_to_point_value(points_value[i : i + 3])) - - return transformed - - def apply_to_vector(self, vector: Vector) -> Vector: - """Transform a single speckle Vector - - Arguments: - point {Vector} -- the speckle Vector to transform - - Returns: - Vector -- a new transformed point - """ - coords = self.apply_to_vector_value([vector.x, vector.y, vector.z]) - return Vector(x=coords[0], y=coords[1], z=coords[2], units=vector.units) - - def apply_to_vector_value(self, vector_value: List[float]) -> List[float]: - """Transform a list of three floats representing a vector - - Arguments: - vector_value {List[float]} -- a list of 3 floats - - Returns: - List[float] -- the list with the transform applied - """ - return [ - vector_value[0] * self._value[i] - + vector_value[1] * self._value[i + 1] - + vector_value[2] * self._value[i + 2] - for i in range(0, 15, 4) - ][:3] - - @classmethod - def from_list(cls, value: Optional[List[float]] = None) -> "Transform": - """Returns a Transform object from a list of 16 numbers. - If no value is provided, an identity transform will be returned. - - Arguments: - value {List[float]} -- the matrix as a flat list of 16 numbers - (defaults to the identity transform) - - Returns: - Transform -- a complete transform object - """ - if not value: - value = IDENTITY_TRANSFORM - return cls(value=value) - - -class BlockDefinition( - Base, speckle_type=OTHER + "BlockDefinition", detachable={"geometry"} -): - name: Optional[str] = None - basePoint: Optional[Point] = None - geometry: Optional[List[Base]] = None - - -class Instance(Base, speckle_type=OTHER + "Instance", detachable={"definition"}): - transform: Optional[Transform] = None - definition: Optional[Base] = None - - -class BlockInstance( - Instance, speckle_type=OTHER + "BlockInstance", serialize_ignore={"blockDefinition"} -): - @property - @deprecated(version="2.13", reason="Use definition") - def blockDefinition(self) -> Optional[BlockDefinition]: - if isinstance(self.definition, BlockDefinition): - return self.definition - return None - - @blockDefinition.setter - def blockDefinition(self, value: Optional[BlockDefinition]) -> None: - self.definition = value - - -class RevitInstance(Instance, speckle_type=OTHER_REVIT + "RevitInstance"): - level: Optional[Base] = None - facingFlipped: bool - handFlipped: bool - parameters: Optional[Base] = None - elementId: Optional[str] - - -# TODO: prob move this into a built elements module, but just trialling this for now -class RevitParameter(Base, speckle_type="Objects.BuiltElements.Revit.Parameter"): - name: Optional[str] = None - value: Any = None - applicationUnitType: Optional[str] = None # eg UnitType UT_Length - applicationUnit: Optional[str] = None # DisplayUnitType eg DUT_MILLIMITERS - applicationInternalName: Optional[str] = ( - None # BuiltInParameterName or GUID for shared parameter - ) - isShared: bool = False - isReadOnly: bool = False - isTypeParameter: bool = False - - -class Collection( - Base, speckle_type="Speckle.Core.Models.Collection", detachable={"elements"} -): - name: Optional[str] = None - collectionType: Optional[str] = None - elements: Optional[List[Base]] = None diff --git a/src/specklepy/objects_v2/primitive.py b/src/specklepy/objects_v2/primitive.py deleted file mode 100644 index d4a4aaee..00000000 --- a/src/specklepy/objects_v2/primitive.py +++ /dev/null @@ -1,25 +0,0 @@ -from typing import Any, List - -from specklepy.objects.base import Base - -NAMESPACE = "Objects.Primitive" - - -class Interval(Base, speckle_type=f"{NAMESPACE}.Interval"): - start: float = 0.0 - end: float = 0.0 - - def length(self): - return abs(self.start - self.end) - - @classmethod - def from_list(cls, args: List[Any]) -> "Interval": - return cls(start=args[0], end=args[1]) - - def to_list(self) -> List[Any]: - return [self.start, self.end] - - -class Interval2d(Base, speckle_type=f"{NAMESPACE}.Interval2d"): - u: Interval - v: Interval diff --git a/src/specklepy/objects_v2/structural/__init__.py b/src/specklepy/objects_v2/structural/__init__.py deleted file mode 100644 index dc91f3a2..00000000 --- a/src/specklepy/objects_v2/structural/__init__.py +++ /dev/null @@ -1,142 +0,0 @@ -"""Builtin Speckle object kit.""" - -from specklepy.objects.structural.analysis import ( - Model, - ModelInfo, - ModelSettings, - ModelUnits, -) -from specklepy.objects.structural.axis import Axis, AxisType -from specklepy.objects.structural.geometry import ( - Element1D, - Element2D, - Element3D, - ElementType1D, - ElementType2D, - ElementType3D, - Node, - Restraint, -) -from specklepy.objects.structural.loading import ( - ActionType, - BeamLoadType, - CombinationType, - FaceLoadType, - Load, - LoadAxisType, - LoadBeam, - LoadCase, - LoadCombinations, - LoadDirection, - LoadDirection2D, - LoadFace, - LoadGravity, - LoadNode, - LoadType, -) -from specklepy.objects.structural.materials import ( - Concrete, - MaterialType, - Steel, - StructuralMaterial, - Timber, -) -from specklepy.objects.structural.properties import ( - BaseReferencePoint, - MemberType, - Property, - Property1D, - Property2D, - Property3D, - PropertyDamper, - PropertyMass, - PropertySpring, - PropertyType2D, - PropertyType3D, - PropertyTypeDamper, - PropertyTypeSpring, - ReferenceSurface, - ReferenceSurfaceEnum, - SectionProfile, - ShapeType, - shapeType, -) -from specklepy.objects.structural.results import ( - Result, - Result1D, - Result2D, - Result3D, - ResultGlobal, - ResultNode, - ResultSet1D, - ResultSet2D, - ResultSet3D, - ResultSetAll, - ResultSetNode, -) - -__all__ = [ - "Element1D", - "Element2D", - "Element3D", - "ElementType1D", - "ElementType2D", - "ElementType3D", - "AxisType", - "Axis", - "Node", - "Restraint", - "Load", - "LoadType", - "ActionType", - "BeamLoadType", - "FaceLoadType", - "LoadDirection", - "LoadDirection2D", - "LoadAxisType", - "CombinationType", - "LoadBeam", - "LoadCase", - "LoadCombinations", - "LoadFace", - "LoadGravity", - "LoadNode", - "Model", - "ModelInfo", - "ModelSettings", - "ModelUnits", - "MaterialType", - "Concrete", - "StructuralMaterial", - "Steel", - "Timber", - "Property", - "Property1D", - "Property2D", - "Property3D", - "PropertyDamper", - "PropertyMass", - "PropertySpring", - "SectionProfile", - "MemberType", - "BaseReferencePoint", - "ReferenceSurface", - "PropertyType2D", - "PropertyType3D", - "ShapeType", - "PropertyTypeSpring", - "PropertyTypeDamper", - "ReferenceSurfaceEnum", - "shapeType", - "Result", - "Result1D", - "ResultSet1D", - "Result2D", - "ResultSet2D", - "Result3D", - "ResultSet3D", - "ResultGlobal", - "ResultSetNode", - "ResultNode", - "ResultSetAll", -] diff --git a/src/specklepy/objects_v2/structural/analysis.py b/src/specklepy/objects_v2/structural/analysis.py deleted file mode 100644 index ee82eead..00000000 --- a/src/specklepy/objects_v2/structural/analysis.py +++ /dev/null @@ -1,49 +0,0 @@ -from typing import List, Optional - -from specklepy.objects.base import Base - -STRUCTURAL_ANALYSIS = "Objects.Structural.Analysis." - - -class ModelUnits(Base, speckle_type=STRUCTURAL_ANALYSIS + "ModelUnits"): - length: Optional[str] = None - sections: Optional[str] = None - displacements: Optional[str] = None - stress: Optional[str] = None - force: Optional[str] = None - mass: Optional[str] = None - time: Optional[str] = None - temperature: Optional[str] = None - velocity: Optional[str] = None - acceleration: Optional[str] = None - energy: Optional[str] = None - angle: Optional[str] = None - strain: Optional[str] = None - - -class ModelSettings(Base, speckle_type=STRUCTURAL_ANALYSIS + "ModelSettings"): - modelUnits: Optional[ModelUnits] = None - steelCode: Optional[str] = None - concreteCode: Optional[str] = None - coincidenceTolerance: float = 0.0 - - -class ModelInfo(Base, speckle_type=STRUCTURAL_ANALYSIS + "ModelInfo"): - name: Optional[str] = None - description: Optional[str] = None - projectNumber: Optional[str] = None - projectName: Optional[str] = None - settings: Optional[ModelSettings] = None - initials: Optional[str] = None - application: Optional[str] = None - - -class Model(Base, speckle_type=STRUCTURAL_ANALYSIS + "Model"): - specs: Optional[ModelInfo] = None - nodes: Optional[List] = None - elements: Optional[List] = None - loads: Optional[List] = None - restraints: Optional[List] = None - properties: Optional[List] = None - materials: Optional[List] = None - layerDescription: Optional[str] = None diff --git a/src/specklepy/objects_v2/structural/axis.py b/src/specklepy/objects_v2/structural/axis.py deleted file mode 100644 index aa4408de..00000000 --- a/src/specklepy/objects_v2/structural/axis.py +++ /dev/null @@ -1,17 +0,0 @@ -from enum import Enum -from typing import Optional - -from specklepy.objects.base import Base -from specklepy.objects.geometry import Plane - - -class AxisType(int, Enum): - Cartesian = 0 - Cylindrical = 1 - Spherical = 2 - - -class Axis(Base, speckle_type="Objects.Structural.Geometry.Axis"): - name: Optional[str] = None - axisType: Optional[AxisType] = None - plane: Optional[Plane] = None diff --git a/src/specklepy/objects_v2/structural/geometry.py b/src/specklepy/objects_v2/structural/geometry.py deleted file mode 100644 index f232529b..00000000 --- a/src/specklepy/objects_v2/structural/geometry.py +++ /dev/null @@ -1,110 +0,0 @@ -from enum import Enum -from typing import List, Optional - -from specklepy.objects.base import Base -from specklepy.objects.geometry import Line, Mesh, Plane, Point, Vector -from specklepy.objects.structural.axis import Axis -from specklepy.objects.structural.properties import ( - Property1D, - Property2D, - Property3D, - PropertyDamper, - PropertyMass, - PropertySpring, -) - -STRUCTURAL_GEOMETRY = "Objects.Structural.Geometry" - - -class ElementType1D(int, Enum): - Beam = 0 - Brace = 1 - Bar = 2 - Column = 3 - Rod = 4 - Spring = 5 - Tie = 6 - Strut = 7 - Link = 8 - Damper = 9 - Cable = 10 - Spacer = 11 - Other = 12 - Null = 13 - - -class ElementType2D(int, Enum): - Quad4 = 0 - Quad8 = 1 - Triangle3 = 2 - Triangle6 = 3 - - -class ElementType3D(int, Enum): - Brick8 = 0 - Wedge6 = 1 - Pyramid5 = 2 - Tetra4 = 3 - - -class Restraint(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Restraint"): - code: Optional[str] = None - stiffnessX: float = 0.0 - stiffnessY: float = 0.0 - stiffnessZ: float = 0.0 - stiffnessXX: float = 0.0 - stiffnessYY: float = 0.0 - stiffnessZZ: float = 0.0 - - -class Node(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Node"): - name: Optional[str] = None - basePoint: Optional[Point] = None - constraintAxis: Optional[Axis] = None - restraint: Optional[Restraint] = None - springProperty: Optional[PropertySpring] = None - massProperty: Optional[PropertyMass] = None - damperProperty: Optional[PropertyDamper] = None - - -class Element1D(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Element1D"): - name: Optional[str] = None - baseLine: Optional[Line] = None - property: Optional[Property1D] = None - type: Optional[ElementType1D] = None - end1Releases: Optional[Restraint] = None - end2Releases: Optional[Restraint] = None - end1Offset: Optional[Vector] = None - end2Offset: Optional[Vector] = None - orientationNode: Optional[Node] = None - orinetationAngle: float = 0.0 - localAxis: Optional[Plane] = None - parent: Optional[Base] = None - end1Node: Optional[Node] = None - end2Node: Optional[Node] = None - topology: Optional[List] = None - displayMesh: Optional[Mesh] = None - - -class Element2D(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Element2D"): - name: Optional[str] = None - property: Optional[Property2D] = None - type: Optional[ElementType2D] = None - offset: float = 0.0 - orientationAngle: float = 0.0 - parent: Optional[Base] = None - topology: Optional[List] = None - displayMesh: Optional[Mesh] = None - - -class Element3D(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Element3D"): - name: Optional[str] = None - baseMesh: Optional[Mesh] = None - property: Optional[Property3D] = None - type: Optional[ElementType3D] = None - orientationAngle: float = 0.0 - parent: Optional[Base] = None - topology: List - - -# class Storey needs ependency on built elements first diff --git a/src/specklepy/objects_v2/structural/loading.py b/src/specklepy/objects_v2/structural/loading.py deleted file mode 100644 index 9e6f1e59..00000000 --- a/src/specklepy/objects_v2/structural/loading.py +++ /dev/null @@ -1,137 +0,0 @@ -from enum import Enum -from typing import List, Optional - -from specklepy.objects.base import Base -from specklepy.objects.geometry import Vector -from specklepy.objects.structural.axis import Axis - -STRUCTURAL_LOADING = "Objects.Structural.Loading." - - -class LoadType(int, Enum): - none = 0 - Dead = 1 - SuperDead = 2 - Soil = 3 - Live = 4 - LiveRoof = 5 - ReducibleLive = 6 - Wind = 7 - Snow = 8 - Rain = 9 - Thermal = 10 - Notional = 11 - Prestress = 12 - Equivalent = 13 - Accidental = 14 - SeismicRSA = 15 - SeismicAccTorsion = 16 - SeismicStatic = 17 - Other = 18 - - -class ActionType(int, Enum): - none = 0 - Permanent = 1 - Variable = 2 - Accidental = 3 - - -class BeamLoadType(int, Enum): - Point = 0 - Uniform = 1 - Linear = 2 - Patch = 3 - TriLinear = 4 - - -class FaceLoadType(int, Enum): - Constant = 0 - Variable = 1 - Point = 2 - - -class LoadDirection2D(int, Enum): - X = 0 - Y = 1 - Z = 2 - - -class LoadDirection(int, Enum): - X = 0 - Y = 1 - Z = 2 - XX = 3 - YY = 4 - ZZ = 5 - - -class LoadAxisType(int, Enum): - Global = 0 - Local = 1 # local element axes - DeformedLocal = ( - 2 # element local axis that is embedded in the element as it deforms - ) - - -class CombinationType(int, Enum): - LinearAdd = 0 - Envelope = 1 - AbsoluteAdd = 2 - SRSS = 3 - RangeAdd = 4 - - -class LoadCase(Base, speckle_type=STRUCTURAL_LOADING + "LoadCase"): - name: Optional[str] = None - loadType: Optional[LoadType] = None - group: Optional[str] = None - actionType: Optional[ActionType] = None - description: Optional[str] = None - - -class Load(Base, speckle_type=STRUCTURAL_LOADING + "Load"): - name: Optional[str] = None - loadCase: Optional[LoadCase] = None - - -class LoadBeam(Load, speckle_type=STRUCTURAL_LOADING + "LoadBeam"): - elements: Optional[List] = None - loadType: Optional[BeamLoadType] = None - direction: Optional[LoadDirection] = None - loadAxis: Optional[Axis] = None - loadAxisType: Optional[LoadAxisType] = None - isProjected: Optional[bool] = None - values: Optional[List] = None - positions: Optional[List] = None - - -class LoadCombinations(Base, speckle_type=STRUCTURAL_LOADING + "LoadCombination"): - name: Optional[str] = None - loadCases: List - loadFactors: List - combinationType: CombinationType - - -class LoadFace(Load, speckle_type=STRUCTURAL_LOADING + "LoadFace"): - elements: Optional[List] = None - loadType: Optional[FaceLoadType] = None - direction: Optional[LoadDirection2D] = None - loadAxis: Optional[Axis] = None - loadAxisType: Optional[LoadAxisType] = None - isProjected: Optional[bool] = None - values: Optional[List] = None - positions: Optional[List] = None - - -class LoadGravity(Load, speckle_type=STRUCTURAL_LOADING + "LoadGravity"): - elements: Optional[List] = None - nodes: Optional[List] = None - gravityFactors: Optional[Vector] = None - - -class LoadNode(Load, speckle_type=STRUCTURAL_LOADING + "LoadNode"): - nodes: Optional[List] = None - loadAxis: Optional[Axis] = None - direction: Optional[LoadDirection] = None - value: float = 0.0 diff --git a/src/specklepy/objects_v2/structural/materials.py b/src/specklepy/objects_v2/structural/materials.py deleted file mode 100644 index ab0abcda..00000000 --- a/src/specklepy/objects_v2/structural/materials.py +++ /dev/null @@ -1,61 +0,0 @@ -from enum import Enum -from typing import Optional - -from specklepy.objects.base import Base - -STRUCTURAL_MATERIALS = "Objects.Structural.Materials" - - -class MaterialType(int, Enum): - Concrete = 0 - Steel = 1 - Timber = 2 - Aluminium = 3 - Masonry = 4 - FRP = 5 - Glass = 6 - Fabric = 7 - Rebar = 8 - Tendon = 9 - ColdFormed = 10 - Other = 11 - - -class StructuralMaterial( - Base, speckle_type=STRUCTURAL_MATERIALS + ".StructuralMaterial" -): - name: Optional[str] = None - grade: Optional[str] = None - materialType: Optional[MaterialType] = None - designCode: Optional[str] = None - codeYear: Optional[str] = None - strength: float = 0.0 - elasticModulus: float = 0.0 - poissonsRatio: float = 0.0 - shearModulus: float = 0.0 - density: float = 0.0 - thermalExpansivity: float = 0.0 - dampingRatio: float = 0.0 - cost: float = 0.0 - materialSafetyFactor: float = 0.0 - - -class Concrete(StructuralMaterial): - compressiveStrength: float = 0.0 - tensileStrength: float = 0.0 - flexuralStrength: float = 0.0 - maxCompressiveStrain: float = 0.0 - maxTensileStrain: float = 0.0 - maxAggregateSize: float = 0.0 - lightweight: Optional[bool] = None - - -class Steel(StructuralMaterial, speckle_type=STRUCTURAL_MATERIALS + ".Steel"): - yieldStrength: float = 0.0 - ultimateStrength: float = 0.0 - maxStrain: float = 0.0 - strainHardeningModulus: float = 0.0 - - -class Timber(StructuralMaterial, speckle_type=STRUCTURAL_MATERIALS + ".Timber"): - species: Optional[str] = None diff --git a/src/specklepy/objects_v2/structural/properties.py b/src/specklepy/objects_v2/structural/properties.py deleted file mode 100644 index e0153a1e..00000000 --- a/src/specklepy/objects_v2/structural/properties.py +++ /dev/null @@ -1,212 +0,0 @@ -from enum import Enum -from typing import Optional - -from specklepy.objects.base import Base -from specklepy.objects.structural.axis import Axis -from specklepy.objects.structural.materials import StructuralMaterial - -STRUCTURAL_PROPERTY = "Objects.Structural.Properties" - - -class MemberType(int, Enum): - Beam = 0 - Column = 1 - Generic1D = 2 - Slab = 3 - Wall = 4 - Generic2D = 5 - VoidCutter1D = 6 - VoidCutter2D = 7 - - -class BaseReferencePoint(int, Enum): - Centroid = 0 - TopLeft = 1 - TopCentre = 2 - TopRight = 3 - MidLeft = 4 - MidRight = 5 - BotLeft = 6 - BotCentre = 7 - BotRight = 8 - - -class ReferenceSurface(int, Enum): - Top = 0 - Middle = 1 - Bottom = 2 - - -class PropertyType2D(int, Enum): - Stress = 0 - Fabric = 1 - Plate = 2 - Shell = 3 - Curved = 4 - Wall = 5 - Strain = 6 - Axi = 7 - Load = 8 - - -class PropertyType3D(int, Enum): - Solid = 0 - Infinite = 1 - - -class ShapeType(int, Enum): - Rectangular = 0 - Circular = 1 - I = 2 # noqa: E741 - Tee = 3 - Angle = 4 - Channel = 5 - Perimeter = 6 - Box = 7 - Catalogue = 8 - Explicit = 9 - Undefined = 10 - - -class PropertyTypeSpring(int, Enum): - Axial = 0 - Torsional = 1 - General = 2 - Matrix = 3 - TensionOnly = 4 - CompressionOnly = 5 - Connector = 6 - LockUp = 7 - Gap = 8 - Friction = 9 - - -class PropertyTypeDamper(int, Enum): - Axial = 0 - Torsional = 1 - General = 2 - - -class Property(Base, speckle_type=STRUCTURAL_PROPERTY): - name: Optional[str] = None - - -class SectionProfile( - Base, speckle_type=STRUCTURAL_PROPERTY + ".Profiles.SectionProfile" -): - name: Optional[str] = None - shapeType: Optional[ShapeType] = None - area: float = 0.0 - Iyy: float = 0.0 - Izz: float = 0.0 - J: float = 0.0 - Ky: float = 0.0 - weight: float = 0.0 - - -class Property1D(Property, speckle_type=STRUCTURAL_PROPERTY + ".Property1D"): - memberType: Optional[MemberType] = None - material: Optional[StructuralMaterial] = None - profile: Optional[SectionProfile] = None - referencePoint: Optional[BaseReferencePoint] = None - offsetY: float = 0.0 - offsetZ: float = 0.0 - - -class Property2D(Property, speckle_type=STRUCTURAL_PROPERTY + ".Property2D"): - type: Optional[PropertyType2D] = None - thickness: float = 0.0 - material: Optional[StructuralMaterial] = None - orientationAxis: Optional[Axis] = None - refSurface: Optional[ReferenceSurface] = None - zOffset: float = 0.0 - modifierInPlane: float = 0.0 - modifierBending: float = 0.0 - modifierShear: float = 0.0 - modifierVolume: float = 0.0 - - -class Property3D(Property, speckle_type=STRUCTURAL_PROPERTY + ".Property3D"): - type: Optional[PropertyType3D] = None - material: Optional[StructuralMaterial] = None - orientationAxis: Optional[Axis] = None - - -class PropertyDamper(Property, speckle_type=STRUCTURAL_PROPERTY + ".PropertyDamper"): - damperType: Optional[PropertyTypeDamper] = None - dampingX: float = 0.0 - dampingY: float = 0.0 - dampingZ: float = 0.0 - dampingXX: float = 0.0 - dampingYY: float = 0.0 - dampingZZ: float = 0.0 - - -class PropertyMass(Property, speckle_type=STRUCTURAL_PROPERTY + ".PropertyMass"): - mass: float = 0.0 - inertiaXX: float = 0.0 - inertiaYY: float = 0.0 - inertiaZZ: float = 0.0 - inertiaXY: float = 0.0 - inertiaYZ: float = 0.0 - inertiaZX: float = 0.0 - massModified: Optional[bool] = None - massModifierX: float = 0.0 - massModifierY: float = 0.0 - massModifierZ: float = 0.0 - - -class PropertySpring(Property, speckle_type=STRUCTURAL_PROPERTY + ".PropertySpring"): - springType: Optional[PropertyTypeSpring] = None - springCurveX: float = 0.0 - stiffnessX: float = 0.0 - springCurveY: float = 0.0 - stiffnessY: float = 0.0 - springCurveZ: float = 0.0 - stiffnessZ: float = 0.0 - springCurveXX: float = 0.0 - stiffnessXX: float = 0.0 - springCurveYY: float = 0.0 - stiffnessYY: float = 0.0 - springCurveZZ: float = 0.0 - stiffnessZZ: float = 0.0 - dampingRatio: float = 0.0 - dampingX: float = 0.0 - dampingY: float = 0.0 - dampingZ: float = 0.0 - dampingXX: float = 0.0 - dampingYY: float = 0.0 - dampingZZ: float = 0.0 - matrix: float = 0.0 - postiveLockup: float = 0.0 - frictionCoefficient: float = 0.0 - - -class ReferenceSurfaceEnum(int, Enum): - Concrete = 0 - Steel = 1 - Timber = 2 - Aluminium = 3 - Masonry = 4 - FRP = 5 - Glass = 6 - Fabric = 7 - Rebar = 8 - Tendon = 9 - ColdFormed = 10 - Other = 11 - - -class shapeType(int, Enum): - Concrete = 0 - Steel = 1 - Timber = 2 - Aluminium = 3 - Masonry = 4 - FRP = 5 - Glass = 6 - Fabric = 7 - Rebar = 8 - Tendon = 9 - ColdFormed = 10 - Other = 11 diff --git a/src/specklepy/objects_v2/structural/results.py b/src/specklepy/objects_v2/structural/results.py deleted file mode 100644 index d014f458..00000000 --- a/src/specklepy/objects_v2/structural/results.py +++ /dev/null @@ -1,172 +0,0 @@ -from typing import List, Optional - -from specklepy.objects.base import Base -from specklepy.objects.structural.analysis import Model -from specklepy.objects.structural.geometry import Element1D, Element2D, Element3D, Node - -STRUCTURAL_RESULTS = "Objects.Structural.Results." - - -class Result(Base, speckle_type=STRUCTURAL_RESULTS + "Result"): - resultCase: Optional[Base] = None - permutation: Optional[str] = None - description: Optional[str] = None - - -class ResultSet1D(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSet1D"): - results1D: List - - -class Result1D(Result, speckle_type=STRUCTURAL_RESULTS + "Result1D"): - element: Optional[Element1D] = None - position: Optional[float] = None - dispX: Optional[float] = None - dispY: Optional[float] = None - dispZ: Optional[float] = None - rotXX: Optional[float] = None - rotYY: Optional[float] = None - rotZZ: Optional[float] = None - forceX: Optional[float] = None - forceY: Optional[float] = None - forceZ: Optional[float] = None - momentXX: Optional[float] = None - momentYY: Optional[float] = None - momentZZ: Optional[float] = None - axialStress: Optional[float] = None - shearStressY: Optional[float] = None - shearStressZ: Optional[float] = None - bendingStressYPos: Optional[float] = None - bendingStressYNeg: Optional[float] = None - bendingStressZPos: Optional[float] = None - bendingStressZNeg: Optional[float] = None - combinedStressMax: Optional[float] = None - combinedStressMin: Optional[float] = None - - -class ResultSet2D(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSet2D"): - results2D: List - - -class Result2D(Result, speckle_type=STRUCTURAL_RESULTS + "Result2D"): - element: Optional[Element2D] = None - position: List - dispX: Optional[float] = None - dispY: Optional[float] = None - dispZ: Optional[float] = None - forceXX: Optional[float] = None - forceYY: Optional[float] = None - forceXY: Optional[float] = None - momentXX: Optional[float] = None - momentYY: Optional[float] = None - momentXY: Optional[float] = None - shearX: Optional[float] = None - shearY: Optional[float] = None - stressTopXX: Optional[float] = None - stressTopYY: Optional[float] = None - stressTopZZ: Optional[float] = None - stressTopXY: Optional[float] = None - stressTopYZ: Optional[float] = None - stressTopZX: Optional[float] = None - stressMidXX: Optional[float] = None - stressMidYY: Optional[float] = None - stressMidZZ: Optional[float] = None - stressMidXY: Optional[float] = None - stressMidYZ: Optional[float] = None - stressMidZX: Optional[float] = None - stressBotXX: Optional[float] = None - stressBotYY: Optional[float] = None - stressBotZZ: Optional[float] = None - stressBotXY: Optional[float] = None - stressBotYZ: Optional[float] = None - stressBotZX: Optional[float] = None - - -class ResultSet3D(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSet3D"): - results3D: List - - -class Result3D(Result, speckle_type=STRUCTURAL_RESULTS + "Result3D"): - element: Optional[Element3D] = None - position: List - dispX: Optional[float] = None - dispY: Optional[float] = None - dispZ: Optional[float] = None - stressXX: Optional[float] = None - stressYY: Optional[float] = None - stressZZ: Optional[float] = None - stressXY: Optional[float] = None - stressYZ: Optional[float] = None - stressZX: Optional[float] = None - - -class ResultGlobal(Result, speckle_type=STRUCTURAL_RESULTS + "ResultGlobal"): - model: Optional[Model] = None - loadX: Optional[float] = None - loadY: Optional[float] = None - loadZ: Optional[float] = None - loadXX: Optional[float] = None - loadYY: Optional[float] = None - loadZZ: Optional[float] = None - reactionX: Optional[float] = None - reactionY: Optional[float] = None - reactionZ: Optional[float] = None - reactionXX: Optional[float] = None - reactionYY: Optional[float] = None - reactionZZ: Optional[float] = None - mode: Optional[float] = None - frequency: Optional[float] = None - loadFactor: Optional[float] = None - modalStiffness: Optional[float] = None - modalGeoStiffness: Optional[float] = None - effMassX: Optional[float] = None - effMassY: Optional[float] = None - effMassZ: Optional[float] = None - effMassXX: Optional[float] = None - effMassYY: Optional[float] = None - effMassZZ: Optional[float] = None - - -class ResultSetNode(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSetNode"): - resultsNode: List - - -class ResultNode(Result, speckle_type=STRUCTURAL_RESULTS + " ResultNode"): - node: Optional[Node] = None - dispX: Optional[float] = None - dispY: Optional[float] = None - dispZ: Optional[float] = None - rotXX: Optional[float] = None - rotYY: Optional[float] = None - rotZZ: Optional[float] = None - reactionX: Optional[float] = None - reactionY: Optional[float] = None - reactionZ: Optional[float] = None - reactionXX: Optional[float] = None - reactionYY: Optional[float] = None - reactionZZ: Optional[float] = None - constraintX: Optional[float] = None - constraintY: Optional[float] = None - constraintZ: Optional[float] = None - constraintXX: Optional[float] = None - constraintYY: Optional[float] = None - constraintZZ: Optional[float] = None - velX: Optional[float] = None - velY: Optional[float] = None - velZ: Optional[float] = None - velXX: Optional[float] = None - velYY: Optional[float] = None - velZZ: Optional[float] = None - accX: Optional[float] = None - accY: Optional[float] = None - accZ: Optional[float] = None - accXX: Optional[float] = None - accYY: Optional[float] = None - accZZ: Optional[float] = None - - -class ResultSetAll(Base, speckle_type=None): - resultSet1D: Optional[ResultSet1D] = None - resultSet2D: Optional[ResultSet2D] = None - resultSet3D: Optional[ResultSet3D] = None - resultsGlobal: Optional[ResultGlobal] = None - resultsNode: Optional[ResultSetNode] = None diff --git a/src/specklepy/objects_v2/units.py b/src/specklepy/objects_v2/units.py deleted file mode 100644 index 0afade75..00000000 --- a/src/specklepy/objects_v2/units.py +++ /dev/null @@ -1,124 +0,0 @@ -from enum import Enum -from typing import Union - -from specklepy.logging.exceptions import SpeckleException, SpeckleInvalidUnitException - -__all__ = [ - "Units", - "get_encoding_from_units", - "get_units_from_encoding", - "get_units_from_string", -] - - -class Units(Enum): - mm = "mm" - cm = "cm" - m = "m" - km = "km" - inches = "in" - feet = "ft" - yards = "yd" - miles = "mi" - none = "none" - - -UNITS_STRINGS = { - Units.mm: ["mm", "mil", "millimeters", "millimetres"], - Units.cm: ["cm", "centimetre", "centimeter", "centimetres", "centimeters"], - Units.m: ["m", "meter", "meters", "metre", "metres"], - Units.km: ["km", "kilometer", "kilometre", "kilometers", "kilometres"], - Units.inches: ["in", "inch", "inches"], - Units.feet: ["ft", "foot", "feet"], - Units.yards: ["yd", "yard", "yards"], - Units.miles: ["mi", "mile", "miles"], - Units.none: ["none", "null"], -} - - -UNITS_ENCODINGS = { - Units.none: 0, - None: 0, - Units.mm: 1, - Units.cm: 2, - Units.m: 3, - Units.km: 4, - Units.inches: 5, - Units.feet: 6, - Units.yards: 7, - Units.miles: 8, -} - - -UNIT_SCALE = { - Units.none: 1, - Units.mm: 0.001, - Units.cm: 0.01, - Units.m: 1.0, - Units.km: 1000.0, - Units.inches: 0.0254, - Units.feet: 0.3048, - Units.yards: 0.9144, - Units.miles: 1609.340, -} -"""Unit scaling factor to meters""" - - -def get_units_from_string(unit: str) -> Units: - if not isinstance(unit, str): - raise SpeckleInvalidUnitException(unit) - unit = str.lower(unit) - for name, alternates in UNITS_STRINGS.items(): - if unit in alternates: - return name - raise SpeckleInvalidUnitException(unit) - - -def get_units_from_encoding(unit: int) -> Units: - for name, encoding in UNITS_ENCODINGS.items(): - if unit == encoding: - return name or Units.none - - raise SpeckleException( - message=( - f"Could not understand what unit {unit} is referring to." - f"Please enter a valid unit encoding (eg {UNITS_ENCODINGS})." - ) - ) - - -def get_encoding_from_units(unit: Union[Units, str, None]): - maybe_sanitized_unit = unit - if isinstance(unit, str): - for unit_enum, aliases in UNITS_STRINGS.items(): - if unit in aliases: - maybe_sanitized_unit = unit_enum - try: - return UNITS_ENCODINGS[maybe_sanitized_unit] - except KeyError as e: - raise SpeckleException( - message=( - f"No encoding exists for unit {maybe_sanitized_unit}." - f"Please enter a valid unit to encode (eg {UNITS_ENCODINGS})." - ) - ) from e - - -def get_scale_factor_from_string(fromUnits: str, toUnits: str) -> float: - """Returns a scalar to convert distance values from one unit system to another""" - return get_scale_factor( - get_units_from_string(fromUnits), get_units_from_string(toUnits) - ) - - -def get_scale_factor(fromUnits: Units, toUnits: Units) -> float: - """Returns a scalar to convert distance values from one unit system to another""" - return get_scale_factor_to_meters(fromUnits) / get_scale_factor_to_meters(toUnits) - - -def get_scale_factor_to_meters(fromUnits: Units) -> float: - """Returns a scalar to convert distance values from one unit system to meters""" - if fromUnits not in UNIT_SCALE: - raise ValueError(f"Invalid units provided: {fromUnits}") - - return UNIT_SCALE[fromUnits] diff --git a/tests/integration/client/deprecated/test_objects.py b/tests/integration/client/deprecated/test_objects.py deleted file mode 100644 index f921ee66..00000000 --- a/tests/integration/client/deprecated/test_objects.py +++ /dev/null @@ -1,47 +0,0 @@ -import pytest - -from specklepy.api.models import Stream -from specklepy.objects import Base -from specklepy.objects.encoding import ObjectArray -from specklepy.serialization.base_object_serializer import BaseObjectSerializer -from specklepy.transports.sqlite import SQLiteTransport - - -class TestObject: - @pytest.fixture(scope="module") - def stream(self, client): - stream = Stream( - name="a sample stream for testing", - description="a stream created for testing", - isPublic=True, - ) - stream.id = client.stream.create( - stream.name, stream.description, stream.isPublic - ) - return stream - - def test_object_create(self, client, stream, base): - transport = SQLiteTransport() - s = BaseObjectSerializer(write_transports=[transport], read_transport=transport) - _, base_dict = s.traverse_base(base) - obj_id = client.object.create(stream_id=stream.id, objects=[base_dict])[0] - - assert isinstance(obj_id, str) - assert base_dict["@detach"]["speckle_type"] == "reference" - assert obj_id == base.get_id(True) - - def test_object_get(self, client, stream, base): - fetched_base = client.object.get( - stream_id=stream.id, object_id=base.get_id(True) - ) - - assert isinstance(fetched_base, Base) - assert fetched_base.name == base.name - assert isinstance(fetched_base.vertices, list) - # assert fetched_base["@detach"]["speckle_type"] == "reference" - - def test_object_array_decoder(self): - array = ObjectArray() - array.data = [5, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 1] - - assert array.decode(decoder=sum) == [5, 4, 3, 2, 1] diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 10a24360..cf78bef4 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -12,7 +12,7 @@ from specklepy.core.api.models import Stream, Version from specklepy.logging import metrics from specklepy.objects.base import Base -from specklepy.objects.fakemesh import FakeDirection, FakeMesh +from .fakemesh import FakeMesh, FakeDirection from specklepy.objects.geometry import Point from specklepy.transports.server.server import ServerTransport @@ -44,7 +44,8 @@ def seed_user(host: str) -> Dict[str, str]: if not r.ok: raise Exception(f"Cannot seed user: {r.reason}") redirect_url = urlparse(r.headers.get("location")) - access_code = parse_qs(redirect_url.query)["access_code"][0] # type: ignore + access_code = parse_qs(redirect_url.query)[ + "access_code"][0] # type: ignore r_tokens = requests.post( url=f"http://{host}/auth/token", @@ -113,7 +114,8 @@ def sample_stream(client: SpeckleClient) -> Stream: description="a stream created for testing", isPublic=True, ) - stream.id = client.stream.create(stream.name, stream.description, stream.isPublic) + stream.id = client.stream.create( + stream.name, stream.description, stream.isPublic) return stream diff --git a/src/specklepy/objects_v2/fakemesh.py b/tests/integration/fakemesh.py similarity index 97% rename from src/specklepy/objects_v2/fakemesh.py rename to tests/integration/fakemesh.py index dfa43448..5e0d646a 100644 --- a/src/specklepy/objects_v2/fakemesh.py +++ b/tests/integration/fakemesh.py @@ -3,7 +3,7 @@ from specklepy.objects.geometry import Point -from .base import Base +from specklepy.objects.base import Base CHUNKABLE_PROPS = { "vertices": 100, diff --git a/tests/integration/test_serialization.py b/tests/integration/test_serialization.py index 85bcd927..8c2e2603 100644 --- a/tests/integration/test_serialization.py +++ b/tests/integration/test_serialization.py @@ -3,8 +3,8 @@ import pytest from specklepy.api import operations -from specklepy.objects import Base -from specklepy.objects.fakemesh import FakeMesh +from specklepy.objects.base import Base +from .fakemesh import FakeMesh from specklepy.objects.geometry import Point from specklepy.transports.memory import MemoryTransport from specklepy.transports.server import ServerTransport diff --git a/tests/unit/test_base.py b/tests/unit/test_base.py index cf4af535..ede149d0 100644 --- a/tests/unit/test_base.py +++ b/tests/unit/test_base.py @@ -6,8 +6,8 @@ from specklepy.api import operations from specklepy.logging.exceptions import SpeckleException, SpeckleInvalidUnitException -from specklepy.objects_v2.base import Base -from specklepy.objects_v2.units import Units +from specklepy.objects.base import Base +from specklepy.objects.models.units import Units @pytest.mark.parametrize( diff --git a/tests/unit/test_geometry.py b/tests/unit/test_geometry.py deleted file mode 100644 index ad3da59a..00000000 --- a/tests/unit/test_geometry.py +++ /dev/null @@ -1,523 +0,0 @@ -# pylint: disable=redefined-outer-name -import json - -import pytest - -from specklepy.api import operations -from specklepy.logging.exceptions import SpeckleException -from specklepy.objects.base import Base -from specklepy.objects_v2.encoding import CurveArray, ObjectArray -from specklepy.objects_v2.geometry import ( - Arc, - Box, - Brep, - BrepEdge, - BrepFace, - BrepLoop, - BrepLoopType, - BrepTrim, - BrepTrimType, - Circle, - Curve, - Ellipse, - Interval, - Line, - Mesh, - Plane, - Point, - Polycurve, - Polyline, - Surface, - Vector, -) -from specklepy.objects_v2.units import Units -from specklepy.transports.memory import MemoryTransport - - -@pytest.fixture() -def interval(): - return Interval(start=0, end=5) - - -@pytest.fixture() -def point(): - return Point(x=1, y=10, z=0) - - -@pytest.fixture() -def vector(): - return Vector(x=1, y=32, z=10) - - -@pytest.fixture() -def plane(point, vector): - return Plane(origin=point, normal=vector, xdir=vector, ydir=vector, units="m") - - -@pytest.fixture() -def box(plane, interval): - return Box( - basePlane=plane, - ySize=interval, - zSize=interval, - xSize=interval, - area=20.4, - volume=44.2, - ) - - -@pytest.fixture() -def line(point, interval): - return Line( - start=point, - end=point, - domain=interval, - units="none", - # These attributes are not handled in C# - # bbox=None, - # length=None - ) - - -@pytest.fixture() -def arc(plane, interval, point): - return Arc( - radius=2.3, - startAngle=22.1, - endAngle=44.5, - angleRadians=33, - plane=plane, - domain=interval, - units="m", - startPoint=point, - midPoint=point, - endPoint=point, - # These attributes are not handled in C# - # bbox=None, - # area=None, - # length=None, - ) - - -@pytest.fixture() -def circle(plane, interval): - return Circle( - radius=22, - plane=plane, - domain=interval, - units="m", - # These attributes are not handled in C# - # bbox=None, - # area=None, - # length=None, - ) - - -@pytest.fixture() -def ellipse(plane, interval): - return Ellipse( - firstRadius=34, - secondRadius=22, - plane=plane, - domain=interval, - units="m", - # These attributes are not handled in C# - # trimDomain=None, - # bbox=None, - # area=None, - # length=None, - ) - - -@pytest.fixture() -def polyline(interval): - return Polyline( - value=[22, 44, 54.3, 99, 232, 21], - closed=True, - domain=interval, - units="m", - # These attributes are not handled in C# - # bbox=None, - # area=None, - # length=None, - ) - - -@pytest.fixture() -def curve(interval): - return Curve( - degree=90, - periodic=True, - rational=False, - closed=True, - domain=interval, - points=[23, 21, 44, 43, 56, 76, 1, 3, 2], - weights=[23, 11, 23], - knots=[22, 45, 76, 11], - units="m", - # These attributes are not handled in C# - # displayValue=None, - # bbox=None, - # area=None, - # length=None, - ) - - -@pytest.fixture() -def polycurve(interval, curve, polyline): - return Polycurve( - segments=[curve, polyline], - domain=interval, - closed=True, - units="m", - # These attributes are not handled in C# - # bbox=None, - # area=None, - # length=None - ) - - -@pytest.fixture() -def mesh(box): - return Mesh( - vertices=[2, 1, 2, 4, 77.3, 5, 33, 4, 2], - faces=[1, 2, 3, 4, 5, 6, 7], - colors=[111, 222, 333, 444, 555, 666, 777], - bbox=box, - area=233, - volume=232.2, - ) - - -@pytest.fixture() -def surface(interval): - return Surface( - degreeU=33, - degreeV=44, - rational=True, - pointData=[1, 2.2, 3, 4, 5, 6, 7, 8, 9], - countU=3, - countV=4, - closedU=True, - closedV=False, - domainU=interval, - domainV=interval, - knotsU=[1.1, 2.2, 3.3, 4.4], - knotsV=[9, 8, 7, 6, 5, 4.4], - units="m", - # These attributes are not handled in C# - # bbox=None, - # area=None, - ) - - -@pytest.fixture() -def brep_face(): - return BrepFace( - SurfaceIndex=3, - LoopIndices=[1, 2, 3, 4], - OuterLoopIndex=2, - OrientationReversed=False, - ) - - -@pytest.fixture() -def brep_edge(interval): - return BrepEdge( - Curve3dIndex=2, - TrimIndices=[4, 5, 6, 7], - StartIndex=2, - EndIndex=6, - ProxyCurveIsReversed=True, - Domain=interval, - ) - - -@pytest.fixture() -def brep_loop(): - return BrepLoop(FaceIndex=5, TrimIndices=[3, 4, 5], Type=BrepLoopType.Unknown) - - -@pytest.fixture() -def brep_trim(): - return BrepTrim( - EdgeIndex=3, - StartIndex=4, - EndIndex=6, - FaceIndex=1, - LoopIndex=4, - CurveIndex=7, - IsoStatus=6, - TrimType=BrepTrimType.Mated, - IsReversed=False, - # These attributes are not handled in C# - # Domain=None, - ) - - -@pytest.fixture -def brep( - mesh, - box, - surface, - curve, - polyline, - circle, - point, - brep_edge, - brep_loop, - brep_trim, - brep_face, -): - return Brep( - provenance="pytest", - bbox=box, - area=32, - volume=54, - displayValue=mesh, - Surfaces=[surface, surface, surface], - Curve3D=[curve, polyline], - Curve2D=[circle], - Vertices=[point, point, point, point], - Edges=[brep_edge], - Loops=[brep_loop, brep_loop], - Trims=[brep_trim], - Faces=[brep_face, brep_face], - IsClosed=False, - Orientation=3, - ) - - -@pytest.fixture -def geometry_objects_dict( - point, - vector, - plane, - line, - arc, - circle, - ellipse, - polyline, - curve, - polycurve, - surface, - brep_trim, -): - return { - "point": point, - "vector": vector, - "plane": plane, - "line": line, - "arc": arc, - "circle": circle, - "ellipse": ellipse, - "polyline": polyline, - "curve": curve, - "polycurve": polycurve, - "surface": surface, - "brep_trim": brep_trim, - } - - -@pytest.mark.parametrize( - "object_name", - [ - "point", - "vector", - "plane", - "line", - "arc", - "circle", - "ellipse", - "polyline", - "curve", - "polycurve", - "surface", - "brep_trim", - ], -) -def test_to_and_from_list(object_name: str, geometry_objects_dict): - obj = geometry_objects_dict[object_name] - assert hasattr(obj, "to_list") - assert hasattr(obj, "from_list") - - chunks = obj.to_list() - assert isinstance(chunks, list) - - object_class = obj.__class__ - decoded_object: Base = object_class.from_list(chunks) - assert decoded_object.get_id() == obj.get_id() - - -def test_brep_surfaces_value_serialization(surface): - brep = Brep() - assert brep.Surfaces is None - assert brep.SurfacesValue is None - brep.Surfaces = [surface, surface] - assert brep.SurfacesValue == ObjectArray.from_objects([surface, surface]).data - - brep.SurfacesValue = ObjectArray.from_objects([surface]).data - assert len(brep.Surfaces) == 1 - assert brep.Surfaces[0].get_id() == surface.get_id() - - -def test_brep_curve2d_values_serialization(curve, polyline, circle): - brep = Brep() - assert brep.Curve2D is None - assert brep.Curve2DValues is None - brep.Curve2D = [curve, polyline] - assert brep.Curve2DValues == CurveArray.from_curves([curve, polyline]).data - - brep.Curve2DValues = CurveArray.from_curves([circle]).data - assert len(brep.Curve2D) == 1 - assert brep.Curve2D[0].get_id() == circle.get_id() - - -def test_brep_curve3d_values_serialization(curve, polyline, circle): - brep = Brep() - assert brep.Curve3D is None - assert brep.Curve3DValues is None - brep.Curve3D = [curve, polyline] - assert brep.Curve3DValues == CurveArray.from_curves([curve, polyline]).data - - brep.Curve3DValues = CurveArray.from_curves([circle]).data - assert len(brep.Curve3D) == 1 - assert brep.Curve3D[0].get_id() == circle.get_id() - - -def test_brep_vertices_values_serialization(): - brep = Brep() - brep.VerticesValue = [1, 1, 1, 1, 2, 2, 2, 3, 3, 3] - assert brep.Vertices[0].get_id() == Point(x=1, y=1, z=1, units=Units.mm).get_id() - assert brep.Vertices[1].get_id() == Point(x=2, y=2, z=2, units=Units.mm).get_id() - assert brep.Vertices[2].get_id() == Point(x=3, y=3, z=3, units=Units.mm).get_id() - - -def test_trims_value_serialization(): - brep = Brep() - brep.TrimsValue = [ - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 2, - 1, - 1, - ] - - assert ( - brep.Trims[0].get_id() - == BrepTrim( - EdgeIndex=0, - StartIndex=0, - EndIndex=0, - FaceIndex=0, - LoopIndex=0, - CurveIndex=0, - IsoStatus=1, - TrimType=BrepTrimType.Boundary, - IsReversed=False, - ).get_id() - ) - - assert ( - brep.Trims[1].get_id() - == BrepTrim( - EdgeIndex=1, - StartIndex=0, - EndIndex=0, - FaceIndex=0, - LoopIndex=0, - CurveIndex=1, - IsoStatus=2, - TrimType=BrepTrimType.Boundary, - IsReversed=True, - ).get_id() - ) - - -def test_loops_value_serialization(): - brep = Brep() - brep.LoopsValue = [6, 0, 1, 0, 1, 2, 3] - - assert brep == brep.Loops[0]._Brep # pylint: disable=protected-access - assert ( - brep.Loops[0].get_id() - == BrepLoop( - FaceIndex=0, Type=BrepLoopType(1), TrimIndices=[0, 1, 2, 3] - ).get_id() - ) - - -def test_edges_value_serialization(): - brep = Brep() - brep.EdgesValue = [8, 0, 0, 1, 0, -8.13345756858629, 8.13345756858629, 1, 3] - - assert brep == brep.Edges[0]._Brep # pylint: disable=protected-access - assert ( - brep.Edges[0].get_id() - == BrepEdge( - Curve3dIndex=0, - StartIndex=0, - EndIndex=1, - ProxyCurveIsReversed=False, - Domain=Interval(start=-8.13345756858629, end=8.13345756858629), - TrimIndices=[1, 3], - ).get_id() - ) - - -def test_faces_value_serialization(): - brep = Brep() - brep.FacesValue = [4, 0, 0, 1, 0] - - assert brep == brep.Faces[0]._Brep # pylint: disable=protected-access - assert ( - brep.Faces[0].get_id() - == BrepFace( - SurfaceIndex=0, OuterLoopIndex=0, OrientationReversed=True, LoopIndices=[0] - ).get_id() - ) - - -def test_serialized_brep_attributes(brep: Brep): - transport = MemoryTransport() - serialized = operations.serialize(brep, [transport]) - serialized_dict = json.loads(serialized) - - removed_keys = [ - "Surfaces", - "Curve3D", - "Curve2D", - "Vertices", - "Trims", - "Loops", - "Edges", - "Faces", - ] - - for k in removed_keys: - assert k not in serialized_dict - - -def test_mesh_create(): - vertices = [2, 1, 2, 4, 77.3, 5, 33, 4, 2] - faces = [1, 2, 3, 4, 5, 6, 7] - mesh = Mesh.create(vertices, faces) - - with pytest.raises(SpeckleException): - bad_mesh = Mesh.create(vertices=7, faces=faces) # noqa: F841 - - assert mesh.vertices == vertices - assert mesh.textureCoordinates == [] diff --git a/tests/unit/test_graph_traversal.py b/tests/unit/test_graph_traversal.py index 9fb37d96..005f3084 100644 --- a/tests/unit/test_graph_traversal.py +++ b/tests/unit/test_graph_traversal.py @@ -2,8 +2,8 @@ from typing import Dict, List, Optional from unittest import TestCase -from specklepy.objects_v2 import Base -from specklepy.objects_v2.graph_traversal.traversal import GraphTraversal, TraversalRule +from specklepy.objects.base import Base +from specklepy.objects.graph_traversal.traversal import GraphTraversal, TraversalRule @dataclass() @@ -100,6 +100,7 @@ def test_traverse_dynamic(self): for context in GraphTraversal([traverse_lists_rule]).traverse(test_case) ] - self.assertCountEqual(ret, [test_case, expected_traverse, expected_traverse]) + self.assertCountEqual( + ret, [test_case, expected_traverse, expected_traverse]) self.assertNotIn(expected_ignore, ret) self.assertEqual(len(ret), 3) diff --git a/tests/unit/test_registering_base.py b/tests/unit/test_registering_base.py index 65639b06..1ad096b4 100644 --- a/tests/unit/test_registering_base.py +++ b/tests/unit/test_registering_base.py @@ -2,8 +2,7 @@ import pytest -from specklepy.objects_v2.base import Base -from specklepy.objects_v2.structural import Concrete +from specklepy.objects.base import Base class Foo(Base): @@ -28,10 +27,6 @@ class Baz(Bar): Baz, "Tests.Unit.TestRegisteringBase.Foo:Custom.Bar:Tests.Unit.TestRegisteringBase.Baz", ), - ( - Concrete, - "Objects.Structural.Materials.StructuralMaterial:Objects.Structural.Materials.Concrete", - ), ], ) def test_determine_speckle_type(klass: Type[Base], speckle_type: str): @@ -43,7 +38,6 @@ def test_determine_speckle_type(klass: Type[Base], speckle_type: str): [ (Base, "Base"), (Foo, "Tests.Unit.TestRegisteringBase.Foo"), - (Concrete, "Objects.Structural.Materials.Concrete"), ], ) def test_full_name(klass: Type[Base], fully_qualified_name: str): diff --git a/tests/unit/test_structural.py b/tests/unit/test_structural.py deleted file mode 100644 index 0064a588..00000000 --- a/tests/unit/test_structural.py +++ /dev/null @@ -1,143 +0,0 @@ -import pytest - -from specklepy.objects_v2.geometry import Line, Mesh, Point, Vector -from specklepy.objects_v2.structural.analysis import Model -from specklepy.objects_v2.structural.geometry import ( - Element1D, - Element2D, - ElementType1D, - ElementType2D, - Node, - Restraint, -) -from specklepy.objects_v2.structural.loading import LoadGravity -from specklepy.objects_v2.structural.materials import StructuralMaterial -from specklepy.objects_v2.structural.properties import ( - MemberType, - Property1D, - Property2D, - SectionProfile, - ShapeType, -) - - -@pytest.fixture() -def point(): - return Point(x=1, y=10, z=0) - - -@pytest.fixture() -def vector(): - return Vector(x=0, y=0, z=-1) - - -@pytest.fixture() -def line(point, interval): - return Line( - start=point, - end=point, - domain=interval, - # These attributes are not handled in C# - # bbox=None, - # length=None - ) - - -@pytest.fixture() -def mesh(box): - return Mesh( - vertices=[2, 1, 2, 4, 77.3, 5, 33, 4, 2], - faces=[1, 2, 3, 4, 5, 6, 7], - colors=[111, 222, 333, 444, 555, 666, 777], - bbox=box, - area=233, - volume=232.2, - ) - - -@pytest.fixture() -def restraint(): - return Restraint(code="FFFFFF") - - -@pytest.fixture() -def node(restraint, point): - return Node(basePoint=point, restraint=restraint, name="node1") - - -@pytest.fixture() -def material(): - return StructuralMaterial(name="TestMaterial") - - -@pytest.fixture() -def memberType(): - return MemberType(0) - - -@pytest.fixture() -def shapeType(): - return ShapeType(8) - - -@pytest.fixture() -def sectionProfile(shapeType): - return SectionProfile(name="Test", shapeType=shapeType) - - -@pytest.fixture() -def property1D(memberType, sectionProfile, material): - return Property1D( - Material=material, - SectionProfile=sectionProfile, - memberType=memberType, - ) - - -@pytest.fixture() -def elementType1D(): - return ElementType1D(0) - - -@pytest.fixture() -def element1D(line, restraint, elementType1D, property1D): - return Element1D( - baseLine=line, - end1Releases=restraint, - end2Releases=restraint, - type=elementType1D, - property=property1D, - ) - - -@pytest.fixture() -def property2D(material): - return Property2D(Material=material) - - -@pytest.fixture() -def elementType2D(): - return ElementType2D(0) - - -@pytest.fixture() -def element2D(point, elementType2D): - return Element2D( - topology=[point], - type=elementType2D, - ) - - -@pytest.fixture() -def loadGravity(element1D, element2D, vector): - return LoadGravity(elements=[element1D, element2D], gravityFactors=vector) - - -@pytest.fixture() -def model(loadGravity, element1D, element2D, material, property1D, property2D): - return Model( - loads=[loadGravity], - elements=[element1D, element2D], - materials=[material], - properties=[property1D, property2D], - ) diff --git a/tests/unit/test_transforms.py b/tests/unit/test_transforms.py deleted file mode 100644 index ea85dd4c..00000000 --- a/tests/unit/test_transforms.py +++ /dev/null @@ -1,129 +0,0 @@ -from typing import List - -import pytest - -from specklepy.api import operations -from specklepy.objects_v2.geometry import Point, Vector -from specklepy.objects_v2.other import Transform - - -@pytest.fixture() -def point(): - return Point(x=1, y=10, z=2) - - -@pytest.fixture() -def points(): - return [Point(x=1 + i, y=10 + i, z=2 + i) for i in range(5)] - - -@pytest.fixture() -def point_value(): - return [1, 10, 2] - - -@pytest.fixture() -def points_values(): - coords = [] - for i in range(5): - coords.extend([1 + i, 10 + i, 2 + 1]) - return coords - - -@pytest.fixture() -def vector(): - return Vector(x=1, y=10, z=2) - - -@pytest.fixture() -def vector_value(): - return [1, 1, 2] - - -@pytest.fixture() -def transform(): - """Translates to [1, 2, 0] and scales z by 0.5""" - return Transform.from_list( - [ - 1.0, - 0.0, - 0.0, - 1.0, - 0.0, - 1.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.5, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - ] - ) - - -def test_point_transform(point: Point, transform: Transform): - new_point = transform.apply_to_point(point) - - assert new_point.x == point.x + 1 - assert new_point.y == point.y + 2 - assert new_point.z == point.z * 0.5 - - -def test_points_transform(points: List[Point], transform: Transform): - new_points = transform.apply_to_points(points) - - for i, new_point in enumerate(new_points): - assert new_point.x == points[i].x + 1 - assert new_point.y == points[i].y + 2 - assert new_point.z == points[i].z * 0.5 - - -def test_point_value_transform(point_value: List[float], transform: Transform): - new_coords = transform.apply_to_point_value(point_value) - - assert new_coords[0] == point_value[0] + 1 - assert new_coords[1] == point_value[1] + 2 - assert new_coords[2] == point_value[2] * 0.5 - - -def test_points_values_transform(points_values: List[float], transform: Transform): - new_coords = transform.apply_to_points_values(points_values) - - for i in range(0, len(points_values), 3): - assert new_coords[i] == points_values[i] + 1 - assert new_coords[i + 1] == points_values[i + 1] + 2 - assert new_coords[i + 2] == points_values[i + 2] * 0.5 - - -def test_vector_transform(vector: Vector, transform: Transform): - new_vector = transform.apply_to_vector(vector) - - assert new_vector.x == vector.x - assert new_vector.y == vector.y - assert new_vector.z == vector.z * 0.5 - - -def test_vector_value_transform(vector_value: List[float], transform: Transform): - new_coords = transform.apply_to_vector_value(vector_value) - - assert new_coords[0] == vector_value[0] - assert new_coords[1] == vector_value[1] - assert new_coords[2] == vector_value[2] * 0.5 - - -def test_transform_fails_with_malformed_value(): - with pytest.raises(ValueError): - Transform.from_list("asdf") - with pytest.raises(ValueError): - Transform.from_list([7, 8, 9]) - - -def test_transform_serialisation(transform: Transform): - serialized = operations.serialize(transform) - deserialized = operations.deserialize(serialized) - - assert transform.get_id() == deserialized.get_id() diff --git a/tests/unit/test_traverse_value.py b/tests/unit/test_traverse_value.py index 847d3f40..47e8c75b 100644 --- a/tests/unit/test_traverse_value.py +++ b/tests/unit/test_traverse_value.py @@ -1,9 +1,11 @@ from typing import List +from dataclasses import dataclass -from specklepy.objects_v2.base import Base +from specklepy.objects.base import Base from specklepy.serialization.base_object_serializer import BaseObjectSerializer +@dataclass(kw_only=True) class FakeBase(Base): foo: List[str] bar: int diff --git a/tests/unit/test_type_validation.py b/tests/unit/test_type_validation.py index 4b845f7e..27fa539f 100644 --- a/tests/unit/test_type_validation.py +++ b/tests/unit/test_type_validation.py @@ -3,8 +3,8 @@ import pytest -from specklepy.objects_v2.base import Base, _validate_type -from specklepy.objects_v2.primitive import Interval +from specklepy.objects.base import Base, _validate_type +from specklepy.objects.primitive import Interval test_base = Base() @@ -87,7 +87,8 @@ def __init__(self, foo: str) -> None: (Tuple, (1, "foo", "bar"), True, (1, "foo", "bar")), # given our current rules, this is the reality. Its just sad... (Tuple[str, str, str], (1, "foo", "bar"), True, ("1", "foo", "bar")), - (Tuple[str, Optional[str], str], (1, None, "bar"), True, ("1", None, "bar")), + (Tuple[str, Optional[str], str], + (1, None, "bar"), True, ("1", None, "bar")), (Set[bool], set([1, 2]), False, set([1, 2])), (Set[int], set([1, 2]), True, set([1, 2])), (Set[int], set([None, 2]), True, set([None, 2])), @@ -99,7 +100,8 @@ def __init__(self, foo: str) -> None: (Optional[Union[List[int], List[FakeBase]]], None, True, None), (Optional[Union[List[int], List[FakeBase]]], "foo", False, "foo"), (Union[List[int], List[FakeBase], None], "foo", False, "foo"), - (Optional[Union[List[int], List[FakeBase]]], [1, 2, 3], True, [1, 2, 3]), + (Optional[Union[List[int], List[FakeBase]]], + [1, 2, 3], True, [1, 2, 3]), ( Optional[Union[List[int], List[FakeBase]]], fake_bases, @@ -113,7 +115,8 @@ def __init__(self, foo: str) -> None: True, {"foo": 1.0, "bar": 2.0}, ), - (Union[float, Dict[str, float]], {"foo": "bar"}, False, {"foo": "bar"}), + (Union[float, Dict[str, float]], { + "foo": "bar"}, False, {"foo": "bar"}), ], ) def test_validate_type( diff --git a/tests/unit/test_unit_scaling.py b/tests/unit/test_unit_scaling.py index a7d414e4..dbe1bfc5 100644 --- a/tests/unit/test_unit_scaling.py +++ b/tests/unit/test_unit_scaling.py @@ -1,6 +1,6 @@ import pytest -from specklepy.objects_v2.units import Units, get_scale_factor +from specklepy.objects.models.units import Units, get_scale_factor @pytest.mark.parametrize(