Compare commits

...

5 Commits

Author SHA1 Message Date
Jedd Morgan 37032cc7aa Merge pull request #172 from specklesystems/jrm/deps/specklepy216
better error message when user has no valid accounts
2023-09-12 12:35:03 +01:00
Jedd Morgan 6027325878 better error message when user has no valid accounts 2023-09-12 11:59:39 +01:00
Jedd Morgan 5ddb2aa052 Merge pull request #171 from specklesystems/jrm/deps/specklepy216
fix(receive)!: Fixed issue with collection name conflicts
2023-09-12 10:50:15 +01:00
Jedd Morgan 67a18821cc fix(receive)!: Collections will no longer update 2023-09-12 10:36:22 +01:00
Jedd Morgan 56216a6137 bump specklepy 2023-09-08 15:39:25 +01:00
8 changed files with 125 additions and 127 deletions
+2 -1
View File
@@ -18,4 +18,5 @@ ELEMENTS_PROPERTY_ALIASES = {"elements", "@elements"}
OBJECT_NAME_MAX_LENGTH = 62
SPECKLE_ID_LENGTH = 32
OBJECT_NAME_SEPERATOR = " -- "
OBJECT_NAME_SPECKLE_SEPARATOR = " -- "
OBJECT_NAME_NUMERAL_SEPARATOR = '.'
+72 -51
View File
@@ -1,6 +1,6 @@
import math
from typing import Any, Dict, Iterable, List, Optional, Union, Collection, cast
from bpy_speckle.convert.constants import DISPLAY_VALUE_PROPERTY_ALIASES, ELEMENTS_PROPERTY_ALIASES, OBJECT_NAME_MAX_LENGTH, OBJECT_NAME_SEPERATOR, SPECKLE_ID_LENGTH
from typing import Any, Dict, Iterable, List, Optional, Sequence, Union, Collection, cast
from bpy_speckle.convert.constants import DISPLAY_VALUE_PROPERTY_ALIASES, ELEMENTS_PROPERTY_ALIASES, OBJECT_NAME_MAX_LENGTH, OBJECT_NAME_NUMERAL_SEPARATOR, OBJECT_NAME_SPECKLE_SEPARATOR, SPECKLE_ID_LENGTH
from bpy_speckle.functions import get_default_traversal_func, get_scale_length, _report
from bpy_speckle.convert.util import ConversionSkippedException
from mathutils import (
@@ -20,7 +20,7 @@ from specklepy.objects.geometry import Mesh, Line, Polyline, Curve, Arc, Polycur
from bpy.types import Object, Collection as BCollection
from .util import (
add_to_heirarchy,
add_to_hierarchy,
get_render_material,
get_vertex_color_material,
render_material_to_native,
@@ -40,7 +40,7 @@ CAN_CONVERT_TO_NATIVE = (
)
def _has_native_convesion(speckle_object: Base) -> bool:
def _has_native_conversion(speckle_object: Base) -> bool:
return any(isinstance(speckle_object, t) for t in CAN_CONVERT_TO_NATIVE) or "View" in speckle_object.speckle_type #hack
def _has_fallback_conversion(speckle_object: Base) -> bool:
@@ -48,27 +48,10 @@ def _has_fallback_conversion(speckle_object: Base) -> bool:
def can_convert_to_native(speckle_object: Base) -> bool:
if(_has_native_convesion(speckle_object) or _has_fallback_conversion(speckle_object)):
if(_has_native_conversion(speckle_object) or _has_fallback_conversion(speckle_object)):
return True
return False
def create_new_object(obj_data: Optional[bpy.types.ID], desired_name: str, counter: int = 0) -> bpy.types.Object:
"""
Creates a new blender object with a unique name,
if the desired_name is already taken
we'll append a number, with the format .xxx to the desired_name to ensure the name is unique.
"""
name = desired_name if counter == 0 else f"{desired_name[:OBJECT_NAME_MAX_LENGTH - 4]}.{counter:03d}" # format counter as name.xxx, truncate to ensure we don't exceed the object name max length
#TODO: This is very slow, and gets slower the more objects you receive with the same name...
# We could use a binary/galloping search, and/or cache the name -> index within a receive.
if name in bpy.data.objects.keys():
#Object already exists, increment counter and try again!
return create_new_object(obj_data, desired_name, counter + 1)
blender_object = bpy.data.objects.new(name, obj_data)
return blender_object
convert_instances_as: str #HACK: This is hacky, we need a better way to pass settings down to the converter
def set_convert_instances_as(value: str):
global convert_instances_as
@@ -87,7 +70,7 @@ def convert_to_native(speckle_object: Base) -> Object:
children: list[Object] = []
# convert elements/breps
if not _has_native_convesion(speckle_object):
if not _has_native_conversion(speckle_object):
(converted, children) = display_value_to_native(speckle_object, object_name, scale)
if not converted and not children:
raise Exception(f"Zero geometry converted from displayValues for {speckle_object}")
@@ -150,8 +133,8 @@ def _members_to_native(speckle_object: Base, name: str, scale: float, members: I
display = getattr(speckle_object, alias, None)
count = 0
MAX_DEPTH = 255 # some large value, to prevent infinite reccursion
def seperate(value: Any) -> bool:
MAX_DEPTH = 255 # some large value, to prevent infinite recursion
def separate(value: Any) -> bool:
nonlocal meshes, others, count, MAX_DEPTH
if combineMeshes and isinstance(value, Mesh):
@@ -163,11 +146,11 @@ def _members_to_native(speckle_object: Base, name: str, scale: float, members: I
if(count > MAX_DEPTH):
return True
for x in value:
seperate(x)
separate(x)
return False
did_halt = seperate(display)
did_halt = separate(display)
if did_halt:
_report(f"Traversal of {speckle_object.speckle_type} {speckle_object.id} halted after traversal depth exceeds MAX_DEPTH={MAX_DEPTH}. Are there circular references object structure?")
@@ -543,7 +526,7 @@ def icurve_to_native(speckle_curve: Base, name: str, scale: float) -> bpy.types.
"""
Transforms and Intances
Transforms and Instances
"""
def transform_to_native(transform: Transform, scale: float) -> MMatrix:
@@ -586,7 +569,7 @@ def _get_instance_name(instance: Instance) -> str:
or _get_friendly_object_name(instance.definition)
or _simplified_speckle_type(instance.speckle_type)
)
return f"{name_prefix}{OBJECT_NAME_SEPERATOR}{instance.id}"
return f"{name_prefix}{OBJECT_NAME_SPECKLE_SEPARATOR}{instance.id}"
def instance_to_native_object(instance: Instance, scale: float) -> Object:
@@ -605,12 +588,12 @@ def instance_to_native_object(instance: Instance, scale: float) -> Object:
traversal_root: Base = definition
if not can_convert_to_native(definition):
# Non-convertable (like all blocks, and some revit instances) will not be converted as part of the deep_traversal.
# Non-convertible (like all blocks, and some revit instances) will not be converted as part of the deep_traversal.
# so we explicitly convert them as empties.
native_instance = create_new_object(None, name)
native_instance.empty_display_size = 0
converted_objects["__ROOT"] = native_instance # we create a dummy root to avoid id conflicts, since revit definitions have displayValues, they are convertable
converted_objects["__ROOT"] = native_instance # we create a dummy root to avoid id conflicts, since revit definitions have displayValues, they are convertible
traversal_root = Base(elements=definition, id="__ROOT")
#Convert definition + "elements" on definition
@@ -652,7 +635,7 @@ def instance_to_native_collection_instance(instance: Instance, scale: float) ->
instance_transform = transform_to_native(instance.transform, scale)
native_instance = bpy.data.objects.new(name, None)
native_instance = create_new_object(None, name)
#add_custom_properties(instance, native_instance)
# hide the instance axes so they don't clutter the viewport
@@ -672,11 +655,11 @@ def _instance_definition_to_native(definition: Union[Base, BlockDefinition]) ->
if native_def:
return native_def
native_def = bpy.data.collections.new(name)
native_def = create_new_collection(name)
native_def["applicationId"] = definition.applicationId
converted_objects = {}
converted_objects["__ROOT"] = native_def # we create a dummy root to avoid id conflicts, since revit definitions have displayValues, they are convertable
converted_objects["__ROOT"] = native_def # we create a dummy root to avoid id conflicts, since revit definitions have displayValues, they are convertible
dummyRoot = Base(elements=definition, id="__ROOT")
_deep_conversion(dummyRoot, converted_objects, True)
@@ -709,7 +692,7 @@ def _deep_conversion(root: Base, converted_objects: Dict[str, Union[Object, BCol
converted_objects[current.id] = converted
add_to_heirarchy(converted, item, converted_objects, preserve_transform)
add_to_hierarchy(converted, item, converted_objects, preserve_transform)
_report(f"Successfully converted {type(current).__name__} {current.id} as '{converted_data_type}'")
except ConversionSkippedException as ex:
@@ -728,28 +711,66 @@ def collection_to_native(collection: SCollection) -> BCollection:
return ret
def get_or_create_collection(name: str, clear_collection: bool = True) -> BCollection:
existing = cast(BCollection, bpy.data.collections.get(name))
if existing:
if clear_collection:
for obj in existing.objects:
existing.objects.unlink(obj)
return existing
else:
new_collection = bpy.data.collections.new(name)
#Disabled for now, since update mode needs rescoping.
# existing = cast(Optional[BCollection], bpy.data.collections.get(name))
# if existing:
# if clear_collection:
# for obj in existing.objects:
# existing.objects.unlink(obj)
# return existing
# else:
new_collection = create_new_collection(name)
#NOTE: We want to not render revit "Rooms" collections by default.
if name == "Rooms":
new_collection.hide_viewport = True
new_collection.hide_render = True
#NOTE: We want to not render revit "Rooms" collections by default.
if name == "Rooms":
new_collection.hide_viewport = True
new_collection.hide_render = True
return new_collection
return new_collection
"""
Object Naming
Object Naming and Creation
"""
def create_new_collection( desired_name: str) -> bpy.types.Collection:
"""
Creates a new blender collection with a unique name
If the desired_name is already taken
we'll append a number, with the format .xxx to the desired_name to ensure the name is unique.
"""
name = _make_unique_name(desired_name, bpy.data.collections.keys())
blender_collection = bpy.data.collections.new(name)
return blender_collection
def create_new_object(obj_data: Optional[bpy.types.ID], desired_name: str) -> bpy.types.Object:
"""
Creates a new blender object with a unique name,
If the desired_name is already taken
we'll append a number, with the format .xxx to the desired_name to ensure the name is unique.
"""
name = _make_unique_name(desired_name, bpy.data.objects.keys())
blender_object = bpy.data.objects.new(name, obj_data)
return blender_object
def _make_unique_name( desired_name: str, taken_names: Collection[str], counter: int = 0) -> str:
"""
Using Blenders default naming (append numeral in .xxx format) to avoid name conflicts with taken names
"""
name = desired_name if counter == 0 else f"{desired_name[:OBJECT_NAME_MAX_LENGTH - 4]}{OBJECT_NAME_NUMERAL_SEPARATOR}{counter:03d}" # format counter as name.xxx, truncate to ensure we don't exceed the object name max length
#TODO: This is very slow, and gets slower the more objects you receive with the same name...
# We could use a binary/galloping search, and/or cache the name -> index within a receive.
if name in taken_names:
#Name already taken, increment counter and try again!
return _make_unique_name(desired_name, taken_names, counter + 1)
return name
def _get_friendly_object_name(speckle_object: Base) -> Optional[str]:
return (getattr(speckle_object, "name", None)
or getattr(speckle_object, "Name", None)
@@ -764,7 +785,7 @@ def _get_friendly_object_name(speckle_object: Base) -> Optional[str]:
def _truncate_object_name(name: str) -> str:
MAX_NAME_LENGTH = OBJECT_NAME_MAX_LENGTH - SPECKLE_ID_LENGTH - len(OBJECT_NAME_SEPERATOR)
MAX_NAME_LENGTH = OBJECT_NAME_MAX_LENGTH - SPECKLE_ID_LENGTH - len(OBJECT_NAME_SPECKLE_SEPARATOR)
return name[:MAX_NAME_LENGTH]
@@ -780,7 +801,7 @@ def _generate_object_name(speckle_object: Base) -> str:
else:
prefix = _simplified_speckle_type(speckle_object.speckle_type)
return f"{prefix}{OBJECT_NAME_SEPERATOR}{speckle_object.id}"
return f"{prefix}{OBJECT_NAME_SPECKLE_SEPARATOR}{speckle_object.id}"
def get_scale_factor(speckle_object: Base, fallback: float = 1.0) -> float:
+19 -19
View File
@@ -20,7 +20,7 @@ from specklepy.objects.geometry import (
Mesh, Curve, Interval, Box, Point, Vector, Polyline,
)
from bpy_speckle.blender_commit_object_builder import BlenderCommitObjectBuilder
from bpy_speckle.convert.constants import OBJECT_NAME_SEPERATOR, SPECKLE_ID_LENGTH
from bpy_speckle.convert.constants import OBJECT_NAME_SPECKLE_SEPARATOR, SPECKLE_ID_LENGTH
from bpy_speckle.convert.util import (
ConversionSkippedException,
get_blender_custom_properties,
@@ -107,7 +107,7 @@ def mesh_to_speckle_meshes(blender_object: Object, data: bpy.types.Mesh) -> List
for i in submesh_data:
index_mapping: Dict[int, int] = {}
#Loop through each polygon, and map indicies to their new index in m_verts
#Loop through each polygon, and map indices to their new index in m_verts
mesh_area = 0
m_verts: List[float] = []
@@ -176,8 +176,8 @@ def bezier_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, name: Optional[
num_points = len(points)
flattend_points = []
for row in points: flattend_points.extend(row)
flattened_points = []
for row in points: flattened_points.extend(row)
knot_count = num_points + degree - 1
knots = [0] * knot_count
@@ -192,7 +192,7 @@ def bezier_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, name: Optional[
degree=degree,
closed=spline.use_cyclic_u,
periodic= not spline.use_endpoint_u,
points=flattend_points,
points=flattened_points,
weights=[1] * num_points,
knots=knots,
rational=True,
@@ -219,15 +219,15 @@ def nurbs_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, name: Optional[s
points = [tuple(matrix @ pt.co.xyz * UnitsScale) for pt in spline.points] # type: ignore
flattend_points = []
for row in points: flattend_points.extend(row)
flattened_points = []
for row in points: flattened_points.extend(row)
if spline.use_cyclic_u:
for i in range(0, degree * 3, 3):
# Rhino expects n + degree number of points (for closed curves). So we need to add an extra point for each degree
flattend_points.append(flattend_points[i + 0])
flattend_points.append(flattend_points[i + 1])
flattend_points.append(flattend_points[i + 2])
flattened_points.append(flattened_points[i + 0])
flattened_points.append(flattened_points[i + 1])
flattened_points.append(flattened_points[i + 2])
for i in range(0, degree):
weights.append(weights[i])
@@ -237,7 +237,7 @@ def nurbs_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, name: Optional[s
degree=degree,
closed=spline.use_cyclic_u,
periodic= not spline.use_endpoint_u,
points=flattend_points,
points=flattened_points,
weights=weights,
knots=knots,
rational=is_rational,
@@ -305,27 +305,27 @@ def bezier_to_speckle_polyline(matrix: MMatrix, spline: bpy.types.Spline, length
domain = Interval(start=0, end=length, totalChildrenCount=0)
return Polyline(value=points, closed = spline.use_cyclic_u, domain=domain, area=0, len=length)
_QUICK_TEST_NAME_LENGTH = SPECKLE_ID_LENGTH + len(OBJECT_NAME_SEPERATOR)
_QUICK_TEST_NAME_LENGTH = SPECKLE_ID_LENGTH + len(OBJECT_NAME_SPECKLE_SEPARATOR)
def to_speckle_name(blender_object: bpy.types.ID) -> str:
does_name_contain_id = len(blender_object.name) > _QUICK_TEST_NAME_LENGTH and OBJECT_NAME_SEPERATOR in blender_object.name
does_name_contain_id = len(blender_object.name) > _QUICK_TEST_NAME_LENGTH and OBJECT_NAME_SPECKLE_SEPARATOR in blender_object.name
if does_name_contain_id:
return blender_object.name.rsplit(OBJECT_NAME_SEPERATOR, 1)[0]
return blender_object.name.rsplit(OBJECT_NAME_SPECKLE_SEPARATOR, 1)[0]
else:
return blender_object.name
def poly_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, name: Optional[str] = None) -> Polyline:
points = [tuple(matrix @ pt.co.xyz * UnitsScale) for pt in spline.points] # type: ignore
flattend_points = []
for row in points: flattend_points.extend(row)
flattened_points = []
for row in points: flattened_points.extend(row)
length = spline.calc_length()
domain = Interval(start=0, end=length, totalChildrenCount=0)
return Polyline(
name=name,
closed=bool(spline.use_cyclic_u),
value=list(flattend_points),
value=list(flattened_points),
length=length,
domain=domain,
bbox=Box(area=0.0, volume=0.0),
@@ -466,7 +466,7 @@ def vector_to_speckle(xyz: MVector) -> Vector:
)
def transform_to_speckle(blender_transform: Union[Iterable[Iterable[float]], MMatrix]) -> Transform:
iterable_transform = cast(Iterable[Iterable[float]], blender_transform) #NOTE: Matrix are itterable, even if type hinting says they are not
iterable_transform = cast(Iterable[Iterable[float]], blender_transform) #NOTE: Matrix are iterable, even if type hinting says they are not
value = [y for x in iterable_transform for y in x]
# scale the translation
for i in (3, 7, 11):
@@ -521,7 +521,7 @@ def empty_to_speckle(blender_object: Object) -> Union[BlockInstance, Base]:
wrapper = Base()
wrapper["@displayValue"] = matrix_to_speckle_point(cast(MMatrix, blender_object.matrix_world))
return wrapper
#TODO: we could do a Empty -> Point conversion here. However, the viewer (and likly other apps) don't support a pont with "elements"
#TODO: we could do a Empty -> Point conversion here. However, the viewer (and likely other apps) don't support a pont with "elements"
#return matrix_to_speckle_point(cast(MMatrix, blender_object.matrix_world))
+1 -1
View File
@@ -449,7 +449,7 @@ def link_object_to_collection_nested(obj: Object, col: BCollection):
for child in obj.children: #type: ignore
link_object_to_collection_nested(child, col)
def add_to_heirarchy(converted: Union[Object, BCollection], traversalContext : 'TraversalContext', converted_objects: Dict[str, Union[Object, BCollection]], preserve_transform: bool) -> None:
def add_to_hierarchy(converted: Union[Object, BCollection], traversalContext : 'TraversalContext', converted_objects: Dict[str, Union[Object, BCollection]], preserve_transform: bool) -> None:
nextParent = traversalContext.parent
# Traverse up the tree to find a direct parent object, and a containing collection
+2 -2
View File
@@ -33,7 +33,7 @@ from bpy_speckle.functions import (
from bpy_speckle.clients import speckle_clients
from bpy_speckle.operators.users import add_user_stream
from bpy_speckle.properties.scene import SpeckleSceneSettings, SpeckleUserObject, get_speckle
from bpy_speckle.convert.util import ConversionSkippedException, add_to_heirarchy
from bpy_speckle.convert.util import ConversionSkippedException, add_to_hierarchy
from specklepy.core.api.models import Commit
from specklepy.core.api import operations, host_applications
from specklepy.core.api.wrapper import StreamWrapper
@@ -223,7 +223,7 @@ class ReceiveStreamObjects(bpy.types.Operator):
converted_objects[current.id] = converted
add_to_heirarchy(converted, item, converted_objects, True)
add_to_hierarchy(converted, item, converted_objects, True)
_report(f"Successfully converted {type(current).__name__} {current.id} as '{converted_data_type}'")
except ConversionSkippedException as ex:
+24 -10
View File
@@ -73,6 +73,9 @@ class LoadUsers(bpy.types.Operator):
},
)
if not profiles:
raise Exception("Zero accounts were found, please add one through Speckle Manager or a local account")
for profile in profiles:
user = users.add()
user.server_name = profile.serverInfo.name or "Speckle Server"
@@ -91,16 +94,24 @@ class LoadUsers(bpy.types.Operator):
client.authenticate_with_account(profile)
speckle_clients.append(client)
except Exception as ex:
_report(ex)
_report(f"Failed to authenticate user {user.email} with server {user.server_url}: {ex}")
users.remove(len(users) - 1)
if profile.isDefault:
active_user_index = len(users) - 1
_report(f"Authenticated {len(users)}/{len(profiles)} accounts")
if active_user_index < len(users):
speckle.active_user = str(active_user_index)
bpy.context.view_layer.update()
if context.area:
context.area.tag_redraw()
if not users:
raise Exception("Zero valid user accounts were found, please ensure account is valid and the server is running")
return {"FINISHED"}
@@ -139,7 +150,7 @@ def add_user_stream(user: SpeckleUserObject, stream: Stream):
class LoadUserStreams(bpy.types.Operator):
"""
Load all available streams for active user user
Load all available streams for active user
"""
bl_idname = "speckle.load_user_streams"
@@ -147,34 +158,37 @@ class LoadUserStreams(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"}
bl_description = "(Re)load all available user streams"
stream_limit: int = 20
branch_limit: int = 20
def execute(self, context):
try:
self.add_stream_from_url(context)
self.load_user_stream(context)
return {"FINISHED"}
except Exception as ex:
_report(f"{self.bl_idname} failed: {ex}")
return {"CANCELLED"}
def add_stream_from_url(self, context: Context) -> None:
def load_user_stream(self, context: Context) -> None:
speckle = get_speckle(context)
user = speckle.validate_user_selection()
client = speckle_clients[int(speckle.active_user)]
try:
streams = client.stream.list(stream_limit=20)
except Exception as e:
_report(f"Failed to retrieve streams: {e}")
return
streams = client.stream.list(stream_limit=self.stream_limit)
except Exception as ex:
raise Exception(f"Failed to retrieve streams") from ex
if not streams:
_report("Failed to retrieve streams.")
raise Exception("Zero streams found")
return
user.streams.clear()
for s in streams:
assert(s.id)
sstream = client.stream.get(id=s.id, branch_limit=20)
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit)
add_user_stream(user, sstream)
bpy.context.view_layer.update()
Generated
+4 -41
View File
@@ -489,43 +489,6 @@ files = [
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
[[package]]
name = "numpy"
version = "1.24.4"
description = "Fundamental package for array computing in Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"},
{file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"},
{file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"},
{file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"},
{file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"},
{file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"},
{file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"},
{file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"},
{file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"},
{file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"},
{file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"},
{file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"},
{file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"},
{file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"},
{file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"},
{file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"},
{file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"},
{file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"},
{file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"},
{file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"},
{file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"},
{file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"},
{file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"},
{file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"},
{file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"},
{file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"},
{file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"},
{file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"},
]
[[package]]
name = "pathspec"
version = "0.11.2"
@@ -780,13 +743,13 @@ files = [
[[package]]
name = "specklepy"
version = "2.16.1"
version = "2.16.2"
description = "The Python SDK for Speckle 2.0"
optional = false
python-versions = ">=3.7.2,<4.0"
files = [
{file = "specklepy-2.16.1-py3-none-any.whl", hash = "sha256:279b098d8daa13860101b998d4d96ad345f640cbaaa9255a5a0dc5742f1db5f3"},
{file = "specklepy-2.16.1.tar.gz", hash = "sha256:78bb78ddb966f5ccae94080b1b6c3544e006020d3a7297b1ee417ae2e42e3f7b"},
{file = "specklepy-2.16.2-py3-none-any.whl", hash = "sha256:3337a9512d73cdf0528c9a40f0318aa68ee859326e4197cd908a9ab159184365"},
{file = "specklepy-2.16.2.tar.gz", hash = "sha256:a48dbc17e289cc85e6adbc6415430292f2d681bdda0dad5b299ea635dd5430d4"},
]
[package.dependencies]
@@ -1179,4 +1142,4 @@ multidict = ">=4.0"
[metadata]
lock-version = "2.0"
python-versions = ">=3.8, <4.0.0"
content-hash = "b8b127b83f339dcf551a711fe480069d1afbaa7dc528071d9713b483caf32432"
content-hash = "ad84c181cbbc02f1fe3c3b72743382d850e60713b5a9e2f01e442c6b2a568a1b"
+1 -2
View File
@@ -7,14 +7,13 @@ license = "Apache-2.0"
[tool.poetry.dependencies]
python = ">=3.8, <4.0.0"
specklepy = "^2.16.1"
specklepy = "^2.16.2"
attrs = "^23.1.0"
# [tool.poetry.group.local_specklepy.dependencies]
# specklepy = {path = "../specklepy", develop = true}
[tool.poetry.group.dev.dependencies]
numpy = "^1.23.5"
fake-bpy-module-latest = "^20230117"
black = "^22.10.0"
pylint = "^2.15.7"