Compare commits
40 Commits
2.11.2
...
2.13.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
| 52136d3ef6 | |||
| fe764d7f0c | |||
| 669dd67521 | |||
| f74b2c37f0 | |||
| ebb4e32fff | |||
| 25903baf83 | |||
| cb6d6d7ad8 | |||
| fd2687aa3c | |||
| f5c65068de | |||
| 235b49d8c6 | |||
| a1ec137c67 | |||
| b95f621272 | |||
| a1fcdad0e3 | |||
| 584e543964 | |||
| ef20c5240c | |||
| 9fe12a018a | |||
| 8411c01f1b | |||
| 63b82a30cb | |||
| 0b6e39cf38 | |||
| b7efcec517 | |||
| 0ab0096aac | |||
| cbd8fc99bb | |||
| 2a9287e762 | |||
| 98c70f237c | |||
| 048047cf05 | |||
| 6118215cae | |||
| 8e06432fe6 | |||
| cb8620ff8a | |||
| e0eddea8ab | |||
| 35b96eaa4e | |||
| c229bb2414 | |||
| 318bd086c0 | |||
| 977994e141 | |||
| d9cbc80ee7 | |||
| 45038fad79 | |||
| cda621d735 | |||
| 2d052d1379 | |||
| 46ce2bc0df | |||
| 80e2216aa0 | |||
| 10d69aa44b |
@@ -36,8 +36,13 @@ loading a Blender file
|
||||
|
||||
@persistent
|
||||
def load_handler(dummy):
|
||||
bpy.ops.speckle.users_load()
|
||||
|
||||
pass
|
||||
# Calling users_load is an expensive operation, one that force users to wait a good 10s every time blender loads.
|
||||
# Until we can do this non-blocking, we will make the user hit the refresh button each time.
|
||||
#bpy.ops.speckle.users_load()
|
||||
|
||||
# Instead, we shall just reset the user selection to an uninitiailised state
|
||||
bpy.ops.speckle.users_reset()
|
||||
|
||||
"""
|
||||
Permanent handle on callbacks
|
||||
|
||||
+474
-208
@@ -1,13 +1,23 @@
|
||||
import math
|
||||
from typing import Union
|
||||
from typing import Tuple, Union, Collection
|
||||
from bpy_speckle.functions import get_scale_length, _report
|
||||
import mathutils
|
||||
import bpy, bmesh, bpy_types
|
||||
from specklepy.objects.other import *
|
||||
from mathutils import (
|
||||
Matrix as MMatrix,
|
||||
Vector as MVector,
|
||||
Quaternion as MQuaternion,
|
||||
)
|
||||
import bpy, bmesh
|
||||
from specklepy.objects.other import (
|
||||
Instance,
|
||||
Transform,
|
||||
BlockDefinition,
|
||||
)
|
||||
from specklepy.objects.geometry import *
|
||||
from bpy.types import Object
|
||||
from .util import (
|
||||
add_blender_material,
|
||||
get_render_material,
|
||||
link_object_to_collection_nested,
|
||||
render_material_to_native,
|
||||
add_custom_properties,
|
||||
add_vertices,
|
||||
add_faces,
|
||||
@@ -15,147 +25,216 @@ from .util import (
|
||||
add_uv_coords,
|
||||
)
|
||||
|
||||
SUPPORTED_CURVES = (Line, Polyline, Curve, Arc, Polycurve)
|
||||
SUPPORTED_CURVES = (Line, Polyline, Curve, Arc, Polycurve, Ellipse, Circle)
|
||||
|
||||
CAN_CONVERT_TO_NATIVE = (
|
||||
Mesh,
|
||||
Brep,
|
||||
*SUPPORTED_CURVES,
|
||||
Transform,
|
||||
BlockDefinition,
|
||||
BlockInstance,
|
||||
Instance,
|
||||
)
|
||||
|
||||
|
||||
def _has_native_convesion(speckle_object: Base) -> bool:
|
||||
return any(isinstance(speckle_object, t) for t in CAN_CONVERT_TO_NATIVE)
|
||||
|
||||
def _has_fallback_conversion(speckle_object: Base) -> bool:
|
||||
return any(getattr(speckle_object, alias, None) for alias in DISPLAY_VALUE_PROPERTY_ALIASES)
|
||||
|
||||
def can_convert_to_native(speckle_object: Base) -> bool:
|
||||
if type(speckle_object) in CAN_CONVERT_TO_NATIVE:
|
||||
return True
|
||||
if getattr(
|
||||
speckle_object, "displayValue", getattr(speckle_object, "displayMesh", None)
|
||||
):
|
||||
|
||||
if(_has_native_convesion(speckle_object) or _has_fallback_conversion(speckle_object)):
|
||||
return True
|
||||
|
||||
_report(f"Could not convert unsupported Speckle object: {speckle_object}")
|
||||
return False
|
||||
|
||||
|
||||
def convert_to_native(speckle_object: Base, name: Optional[str] = None) -> Optional[Union[list, Object]]:
|
||||
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
|
||||
|
||||
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
|
||||
convert_instances_as = value
|
||||
|
||||
def convert_to_native(speckle_object: Base) -> list[Object]:
|
||||
|
||||
speckle_type = type(speckle_object)
|
||||
speckle_name = (
|
||||
name
|
||||
or getattr(speckle_object, "name", None)
|
||||
or f"{speckle_object.speckle_type} -- {speckle_object.id}"
|
||||
)
|
||||
# convert unsupported types with display values
|
||||
if speckle_type not in CAN_CONVERT_TO_NATIVE:
|
||||
elements = getattr(speckle_object, "elements", getattr(speckle_object, "@elements", []))
|
||||
display = getattr(
|
||||
speckle_object, "displayValue", getattr(speckle_object, "@displayValue", None)
|
||||
)
|
||||
if not elements and not display:
|
||||
_report(f"Could not convert unsupported Speckle object: {speckle_object}")
|
||||
return None
|
||||
if isinstance(display, list):
|
||||
elements.extend(display)
|
||||
else:
|
||||
elements.append(display)
|
||||
# TODO: depreciate the parent type
|
||||
# add parent type here so we can use it as a blender custom prop
|
||||
# not making it hidden, so it will get added on send as i think it might be helpful? can reconsider
|
||||
converted = []
|
||||
for item in elements:
|
||||
if not isinstance(item, Base):
|
||||
continue
|
||||
item.parent_speckle_type = speckle_object.speckle_type
|
||||
blender_object = convert_to_native(item)
|
||||
if isinstance(blender_object, list):
|
||||
converted.extend(blender_object)
|
||||
else:
|
||||
add_custom_properties(speckle_object, blender_object)
|
||||
converted.append(blender_object)
|
||||
return converted
|
||||
|
||||
try:
|
||||
# convert breps
|
||||
if speckle_type is Brep:
|
||||
meshes = getattr(
|
||||
speckle_object, "displayValue", getattr(speckle_object, "displayMesh", iter([]))
|
||||
)
|
||||
if material := getattr(speckle_object, "renderMaterial", getattr(speckle_object, "@renderMaterial", None),):
|
||||
for mesh in meshes:
|
||||
mesh["renderMaterial"] = material
|
||||
object_name = _generate_object_name(speckle_object)
|
||||
scale = get_scale_factor(speckle_object)
|
||||
|
||||
return [convert_to_native(mesh) for mesh in meshes]
|
||||
obj_data: Optional[Union[bpy.types.ID, bpy.types.Object]] = None
|
||||
converted: list[Object] = []
|
||||
|
||||
# convert elements/breps
|
||||
if not _has_native_convesion(speckle_object):
|
||||
(obj_data, converted) = element_to_native(speckle_object, object_name, scale)
|
||||
if not obj_data and not converted:
|
||||
_report(f"Unsupported type {speckle_object.speckle_type}")
|
||||
|
||||
scale = 1.0
|
||||
if units := getattr(speckle_object, "units", None):
|
||||
scale = get_scale_length(units) / bpy.context.scene.unit_settings.scale_length
|
||||
# convert supported geometry
|
||||
if isinstance(speckle_object, Mesh):
|
||||
obj_data = mesh_to_native(speckle_object, name=speckle_name, scale=scale)
|
||||
elif isinstance(speckle_object, Mesh):
|
||||
obj_data = mesh_to_native(speckle_object, object_name, scale)
|
||||
elif speckle_type in SUPPORTED_CURVES:
|
||||
obj_data = icurve_to_native(speckle_object, name=speckle_name, scale=scale)
|
||||
elif isinstance(speckle_object, Transform):
|
||||
obj_data = transform_to_native(speckle_object, scale=scale)
|
||||
elif isinstance(speckle_object, BlockDefinition):
|
||||
obj_data = block_def_to_native(speckle_object, scale=scale)
|
||||
elif isinstance(speckle_object, BlockInstance): # speckle_type is BlockInstance:
|
||||
obj_data = block_instance_to_native(speckle_object, scale=scale)
|
||||
obj_data = icurve_to_native(speckle_object, object_name, scale)
|
||||
elif isinstance(speckle_object, Instance):
|
||||
if convert_instances_as == "linked_duplicates":
|
||||
(obj_data, converted) = instance_to_native_object(speckle_object, scale)
|
||||
else: # convert_instances_as == collection_instance
|
||||
obj_data = instance_to_native_collection_instance(speckle_object, scale)
|
||||
else:
|
||||
_report(f"Unsupported type {speckle_type}")
|
||||
return None
|
||||
return []
|
||||
except Exception as ex: # conversion error
|
||||
_report(f"Error converting {speckle_object} \n{ex}")
|
||||
return None
|
||||
return []
|
||||
|
||||
if speckle_name in bpy.data.objects.keys():
|
||||
blender_object = bpy.data.objects[speckle_name]
|
||||
blender_object.data = (
|
||||
obj_data.data if isinstance(obj_data, bpy_types.Object) else obj_data
|
||||
)
|
||||
blender_object.matrix_world = (
|
||||
blender_object.matrix_world
|
||||
if speckle_type is BlockInstance
|
||||
else mathutils.Matrix()
|
||||
)
|
||||
if hasattr(obj_data, "materials"):
|
||||
blender_object.data.materials.clear()
|
||||
else:
|
||||
blender_object = (
|
||||
obj_data
|
||||
if isinstance(obj_data, bpy_types.Object)
|
||||
else bpy.data.objects.new(speckle_name, obj_data)
|
||||
)
|
||||
|
||||
blender_object = obj_data if isinstance(obj_data, Object) else create_new_object(obj_data, object_name)
|
||||
|
||||
blender_object.speckle.object_id = str(speckle_object.id)
|
||||
blender_object.speckle.enabled = True
|
||||
add_custom_properties(speckle_object, blender_object)
|
||||
add_blender_material(speckle_object, blender_object)
|
||||
|
||||
return blender_object
|
||||
for child in converted:
|
||||
child.parent = blender_object
|
||||
|
||||
converted.append(blender_object)
|
||||
_report(f"Successfully converted {object_name} as {blender_object.type}")
|
||||
return converted
|
||||
|
||||
|
||||
def mesh_to_native(speckle_mesh: Mesh, name: str, scale=1.0) -> bpy.types.Mesh:
|
||||
DISPLAY_VALUE_PROPERTY_ALIASES = ["displayValue", "@displayValue", "displayMesh", "@displayMesh", "elements", "@elements"]
|
||||
|
||||
def element_to_native(speckle_object: Base, name: str, scale: float, combineMeshes: bool = True) -> tuple[Optional[bpy.types.Mesh], list[bpy.types.Object]]:
|
||||
"""
|
||||
Converts a given speckle_object by converting displayValue properties (elements treated the same as displayValues)
|
||||
|
||||
if combineMeshes == True
|
||||
Converts mesh displayValues as one mesh
|
||||
Converts non-mesh displayValues as child Objects
|
||||
if combineMeshes == False
|
||||
Converts all displayValues as child objects (first item of the returned tuple will be None)
|
||||
"""
|
||||
meshes: list[Mesh] = []
|
||||
elements: list[Base] = []
|
||||
|
||||
#NOTE: raw Mesh elements will be treated like displayValues, which is not ideal, but no connector sends raw Mesh elements so it's fine
|
||||
for alias in DISPLAY_VALUE_PROPERTY_ALIASES:
|
||||
display = getattr(speckle_object, alias, None)
|
||||
|
||||
count = 0
|
||||
MAX_DEPTH = 255 # some large value, to prevent infinite reccursion
|
||||
def seperate(value: Any) -> bool:
|
||||
nonlocal meshes, elements, count, MAX_DEPTH
|
||||
|
||||
if combineMeshes and isinstance(value, Mesh):
|
||||
meshes.append(value)
|
||||
elif isinstance(value, Base):
|
||||
elements.append(value)
|
||||
elif isinstance(value, list):
|
||||
count += 1
|
||||
if(count > MAX_DEPTH):
|
||||
return True
|
||||
for x in value:
|
||||
seperate(x)
|
||||
|
||||
return False
|
||||
|
||||
did_halt = seperate(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?")
|
||||
|
||||
|
||||
converted: list[Object] = []
|
||||
mesh = None
|
||||
|
||||
if meshes:
|
||||
mesh = meshes_to_native(speckle_object, meshes, name, scale)
|
||||
|
||||
for item in elements:
|
||||
# add parent type here so we can use it as a blender custom prop
|
||||
# not making it hidden, so it will get added on send as i think it might be helpful? can reconsider
|
||||
item.parent_speckle_type = speckle_object.speckle_type #TODO: consider if this is still useful, as we now properly structure object parenting
|
||||
blender_object = convert_to_native(item)
|
||||
if isinstance(blender_object, list):
|
||||
converted.extend(blender_object)
|
||||
else:
|
||||
add_custom_properties(speckle_object, blender_object)
|
||||
converted.append(blender_object)
|
||||
|
||||
return (mesh, converted)
|
||||
|
||||
|
||||
def mesh_to_native(speckle_mesh: Mesh, name: str, scale: float) -> bpy.types.Mesh:
|
||||
return meshes_to_native(speckle_mesh, [speckle_mesh], name, scale)
|
||||
|
||||
def meshes_to_native(element: Base, meshes: Collection[Mesh], name: str, scale: float) -> bpy.types.Mesh:
|
||||
if name in bpy.data.meshes.keys():
|
||||
blender_mesh = bpy.data.meshes[name]
|
||||
else:
|
||||
blender_mesh = bpy.data.meshes.new(name=name)
|
||||
return bpy.data.meshes[name]
|
||||
|
||||
blender_mesh = bpy.data.meshes.new(name=name)
|
||||
|
||||
fallback_material = get_render_material(element)
|
||||
|
||||
bm = bmesh.new()
|
||||
|
||||
add_vertices(speckle_mesh, bm, scale)
|
||||
add_faces(speckle_mesh, bm)
|
||||
add_colors(speckle_mesh, bm)
|
||||
add_uv_coords(speckle_mesh, bm)
|
||||
# First pass, add vertex data
|
||||
for mesh in meshes:
|
||||
scale = get_scale_factor(mesh, scale)
|
||||
add_vertices(mesh, bm, scale)
|
||||
|
||||
bm.verts.ensure_lookup_table()
|
||||
|
||||
# Second pass, add face data
|
||||
offset = 0
|
||||
for i, mesh in enumerate(meshes):
|
||||
add_faces(mesh, bm, offset, i)
|
||||
|
||||
render_material = get_render_material(mesh) or fallback_material
|
||||
if render_material is not None:
|
||||
native_material = render_material_to_native(render_material)
|
||||
blender_mesh.materials.append(native_material)
|
||||
|
||||
offset += len(mesh.vertices) // 3
|
||||
|
||||
bm.faces.ensure_lookup_table()
|
||||
bm.verts.index_update()
|
||||
|
||||
# Third pass, add vertex instance data
|
||||
for mesh in meshes:
|
||||
add_colors(mesh, bm)
|
||||
add_uv_coords(mesh, bm)
|
||||
|
||||
bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
|
||||
|
||||
bm.to_mesh(blender_mesh)
|
||||
bm.free()
|
||||
bm.free()
|
||||
|
||||
return blender_mesh
|
||||
|
||||
def line_to_native(speckle_curve: Line, blender_curve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
|
||||
|
||||
"""
|
||||
Curves
|
||||
"""
|
||||
|
||||
def line_to_native(speckle_curve: Line, blender_curve: bpy.types.Curve, scale: float) -> list[bpy.types.Spline]:
|
||||
if not speckle_curve.end: return []
|
||||
|
||||
line = blender_curve.splines.new("POLY")
|
||||
line.points.add(1)
|
||||
|
||||
@@ -166,95 +245,93 @@ def line_to_native(speckle_curve: Line, blender_curve: bpy.types.Curve, scale: f
|
||||
1,
|
||||
)
|
||||
|
||||
if speckle_curve.end:
|
||||
line.points[1].co = (
|
||||
float(speckle_curve.end.x) * scale,
|
||||
float(speckle_curve.end.y) * scale,
|
||||
float(speckle_curve.end.z) * scale,
|
||||
1,
|
||||
)
|
||||
|
||||
line.points[1].co = (
|
||||
float(speckle_curve.end.x) * scale,
|
||||
float(speckle_curve.end.y) * scale,
|
||||
float(speckle_curve.end.z) * scale,
|
||||
return [line]
|
||||
|
||||
|
||||
def polyline_to_native(scurve: Polyline, bcurve: bpy.types.Curve, scale: float) -> list[bpy.types.Spline]:
|
||||
if not (value := scurve.value): return []
|
||||
N = len(value) // 3
|
||||
|
||||
polyline = bcurve.splines.new("POLY")
|
||||
|
||||
if hasattr(scurve, "closed"):
|
||||
polyline.use_cyclic_u = scurve.closed
|
||||
|
||||
# if "closed" in scurve.keys():
|
||||
# polyline.use_cyclic_u = scurve["closed"]
|
||||
|
||||
polyline.points.add(N - 1)
|
||||
for i in range(N):
|
||||
polyline.points[i].co = (
|
||||
float(value[i * 3]) * scale,
|
||||
float(value[i * 3 + 1]) * scale,
|
||||
float(value[i * 3 + 2]) * scale,
|
||||
1,
|
||||
)
|
||||
|
||||
return line
|
||||
return [polyline]
|
||||
|
||||
|
||||
|
||||
def polyline_to_native(scurve: Polyline, bcurve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
|
||||
if value := scurve.value:
|
||||
N = len(value) // 3
|
||||
def nurbs_to_native(scurve: Curve, bcurve: bpy.types.Curve, scale: float) -> list[bpy.types.Spline]:
|
||||
if not (points := scurve.points): return []
|
||||
|
||||
polyline = bcurve.splines.new("POLY")
|
||||
# Closed curves from rhino will have n + degree points. We ignore the extras
|
||||
num_points = len(points) // 3 - scurve.degree if (scurve.closed) else (
|
||||
len(points) // 3)
|
||||
|
||||
nurbs = bcurve.splines.new("NURBS")
|
||||
nurbs.use_cyclic_u = scurve.closed
|
||||
nurbs.use_endpoint_u = not scurve.periodic
|
||||
|
||||
nurbs.points.add(num_points - 1)
|
||||
use_weights = len(scurve.weights) >= num_points
|
||||
for i in range(num_points):
|
||||
nurbs.points[i].co = (
|
||||
float(points[i * 3]) * scale,
|
||||
float(points[i * 3 + 1]) * scale,
|
||||
float(points[i * 3 + 2]) * scale,
|
||||
1,
|
||||
)
|
||||
|
||||
nurbs.points[i].weight = scurve.weights[i] if use_weights else 1
|
||||
|
||||
if hasattr(scurve, "closed"):
|
||||
polyline.use_cyclic_u = scurve.closed
|
||||
nurbs.order_u = scurve.degree + 1
|
||||
|
||||
# if "closed" in scurve.keys():
|
||||
# polyline.use_cyclic_u = scurve["closed"]
|
||||
|
||||
polyline.points.add(N - 1)
|
||||
for i in range(N):
|
||||
polyline.points[i].co = (
|
||||
float(value[i * 3]) * scale,
|
||||
float(value[i * 3 + 1]) * scale,
|
||||
float(value[i * 3 + 2]) * scale,
|
||||
1,
|
||||
)
|
||||
|
||||
return polyline
|
||||
|
||||
|
||||
def nurbs_to_native(scurve: Curve, bcurve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
|
||||
if points := scurve.points:
|
||||
N = len(points) // 3
|
||||
|
||||
nurbs = bcurve.splines.new("NURBS")
|
||||
|
||||
if hasattr(scurve, "closed"):
|
||||
nurbs.use_cyclic_u = scurve.closed != 0
|
||||
|
||||
nurbs.points.add(N - 1)
|
||||
for i in range(N):
|
||||
nurbs.points[i].co = (
|
||||
float(points[i * 3]) * scale,
|
||||
float(points[i * 3 + 1]) * scale,
|
||||
float(points[i * 3 + 2]) * scale,
|
||||
1,
|
||||
)
|
||||
|
||||
if len(scurve.weights) == len(nurbs.points):
|
||||
for i, w in enumerate(scurve.weights):
|
||||
nurbs.points[i].weight = w
|
||||
|
||||
# TODO: anaylize curve knots to decide if use_endpoint_u or use_bezier_u should be enabled
|
||||
# nurbs.use_endpoint_u = True
|
||||
nurbs.order_u = scurve.degree + 1
|
||||
|
||||
return nurbs
|
||||
return [nurbs]
|
||||
|
||||
|
||||
def arc_to_native(rcurve: Arc, bcurve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
|
||||
# TODO: improve Blender representation of arc
|
||||
# TODO: improve Blender representation of arc - check autocad test stream
|
||||
|
||||
plane = rcurve.plane
|
||||
if not plane:
|
||||
return None
|
||||
|
||||
normal = mathutils.Vector([plane.normal.x, plane.normal.y, plane.normal.z])
|
||||
normal = MVector([plane.normal.x, plane.normal.y, plane.normal.z])
|
||||
|
||||
radius = rcurve.radius * scale
|
||||
startAngle = rcurve.startAngle
|
||||
endAngle = rcurve.endAngle
|
||||
|
||||
startQuat = mathutils.Quaternion(normal, startAngle)
|
||||
endQuat = mathutils.Quaternion(normal, endAngle)
|
||||
startQuat = MQuaternion(normal, startAngle)
|
||||
endQuat = MQuaternion(normal, endAngle)
|
||||
|
||||
# Get start and end vectors, centre point, angles, etc.
|
||||
r1 = mathutils.Vector([plane.xdir.x, plane.xdir.y, plane.xdir.z])
|
||||
r1 = MVector([plane.xdir.x, plane.xdir.y, plane.xdir.z])
|
||||
r1.rotate(startQuat)
|
||||
|
||||
r2 = mathutils.Vector([plane.xdir.x, plane.xdir.y, plane.xdir.z])
|
||||
r2 = MVector([plane.xdir.x, plane.xdir.y, plane.xdir.z])
|
||||
r2.rotate(endQuat)
|
||||
|
||||
c = mathutils.Vector([plane.origin.x, plane.origin.y, plane.origin.z]) * scale
|
||||
c = MVector([plane.origin.x, plane.origin.y, plane.origin.z]) * scale
|
||||
|
||||
spt = c + r1 * radius
|
||||
ept = c + r2 * radius
|
||||
@@ -270,7 +347,7 @@ def arc_to_native(rcurve: Arc, bcurve: bpy.types.Curve, scale: float) -> Optiona
|
||||
|
||||
Ndiv = max(int(math.floor(angle / 0.3)), 2)
|
||||
step = angle / float(Ndiv)
|
||||
stepQuat = mathutils.Quaternion(normal, step)
|
||||
stepQuat = MQuaternion(normal, step)
|
||||
tan = math.tan(step / 2) * radius
|
||||
|
||||
arc.points.add(Ndiv + 1)
|
||||
@@ -293,7 +370,7 @@ def arc_to_native(rcurve: Arc, bcurve: bpy.types.Curve, scale: float) -> Optiona
|
||||
return arc
|
||||
|
||||
|
||||
def polycurve_to_native(scurve: Polycurve, bcurve: bpy.types.Curve, scale: float):
|
||||
def polycurve_to_native(scurve: Polycurve, bcurve: bpy.types.Curve, scale: float) -> list[bpy.types.Spline]:
|
||||
"""
|
||||
Convert Polycurve object
|
||||
"""
|
||||
@@ -305,48 +382,110 @@ def polycurve_to_native(scurve: Polycurve, bcurve: bpy.types.Curve, scale: float
|
||||
speckle_type = type(seg)
|
||||
|
||||
if speckle_type in SUPPORTED_CURVES:
|
||||
curves.append(icurve_to_native_spline(seg, bcurve, scale=scale))
|
||||
curves.append(icurve_to_native_spline(seg, bcurve, scale))
|
||||
else:
|
||||
_report(f"Unsupported curve type: {speckle_type}")
|
||||
|
||||
return curves
|
||||
|
||||
def circle_to_native(circle: Circle, bcurve: bpy.types.Curve, units_scale: float) -> list[bpy.types.Spline]:
|
||||
#HACK: violates typing, but it works...
|
||||
circle["firstRadius"] = circle.radius
|
||||
circle["secondRadius"] = circle.radius
|
||||
return ellipse_to_native(circle, bcurve, units_scale)
|
||||
|
||||
def ellipse_to_native(ellipse: Ellipse, bcurve: bpy.types.Curve, units_scale: float) -> list[bpy.types.Spline]:
|
||||
plane = ellipse.plane
|
||||
|
||||
def icurve_to_native_spline(speckle_curve: Base, blender_curve: bpy.types.Curve, scale=1.0):
|
||||
curve_type = type(speckle_curve)
|
||||
if curve_type is Line:
|
||||
return line_to_native(speckle_curve, blender_curve, scale)
|
||||
if curve_type is Polyline:
|
||||
return polyline_to_native(speckle_curve, blender_curve, scale)
|
||||
if curve_type is Curve:
|
||||
return nurbs_to_native(speckle_curve, blender_curve, scale)
|
||||
if curve_type is Polycurve:
|
||||
radX = ellipse.firstRadius * units_scale
|
||||
radY = ellipse.secondRadius * units_scale
|
||||
|
||||
D = 0.5522847498307936 # (4/3)*tan(pi/8)
|
||||
|
||||
right_handles = [
|
||||
(+radX, +radY * D, 0.0),
|
||||
(-radX * D, +radY, 0.0),
|
||||
(-radX, -radY * D, 0.0),
|
||||
(+radX * D, -radY, 0.0),
|
||||
]
|
||||
|
||||
left_handles = [
|
||||
(+radX, -radY * D, 0.0),
|
||||
(+radX * D, +radY, 0.0),
|
||||
(-radX, +radY * D, 0.0),
|
||||
(-radX * D, -radY, 0.0),
|
||||
]
|
||||
|
||||
points = [
|
||||
(+radX, 0.0, 0.0),
|
||||
(0.0, +radY, 0.0),
|
||||
(-radX, 0.0, 0.0),
|
||||
(0.0, -radY, 0.0),
|
||||
]
|
||||
transform = plane_to_native_transform(plane, units_scale)
|
||||
|
||||
spline = bcurve.splines.new("BEZIER")
|
||||
spline.bezier_points.add(len(points) - 1)
|
||||
|
||||
for i in range(len(points)):
|
||||
spline.bezier_points[i].co = transform @ MVector(points[i])
|
||||
spline.bezier_points[i].handle_left = transform @ MVector(left_handles[i])
|
||||
spline.bezier_points[i].handle_right = transform @ MVector(right_handles[i])
|
||||
|
||||
spline.use_cyclic_u = True
|
||||
|
||||
#TODO support trims?
|
||||
return [spline]
|
||||
|
||||
|
||||
def icurve_to_native_spline(speckle_curve: Base, blender_curve: bpy.types.Curve, scale: float) -> list[bpy.types.Spline]:
|
||||
# polycurves
|
||||
if isinstance(speckle_curve, Polycurve):
|
||||
return polycurve_to_native(speckle_curve, blender_curve, scale)
|
||||
if curve_type is Arc:
|
||||
return arc_to_native(speckle_curve, blender_curve, scale)
|
||||
|
||||
# single curves
|
||||
if isinstance(speckle_curve, Line):
|
||||
spline = line_to_native(speckle_curve, blender_curve, scale)
|
||||
elif isinstance(speckle_curve, Curve):
|
||||
spline = nurbs_to_native(speckle_curve, blender_curve, scale)
|
||||
elif isinstance(speckle_curve, Polyline):
|
||||
spline = polyline_to_native(speckle_curve, blender_curve, scale)
|
||||
elif isinstance(speckle_curve, Arc):
|
||||
spline = arc_to_native(speckle_curve, blender_curve, scale)
|
||||
elif isinstance(speckle_curve, Ellipse):
|
||||
spline = ellipse_to_native(speckle_curve, blender_curve, scale)
|
||||
elif isinstance(speckle_curve, Circle):
|
||||
spline = circle_to_native(speckle_curve, blender_curve, scale)
|
||||
else:
|
||||
raise TypeError(f"{speckle_curve} is not a supported curve type. Supported types: {SUPPORTED_CURVES}")
|
||||
|
||||
return [spline] if spline is not None else []
|
||||
|
||||
|
||||
def icurve_to_native(speckle_curve: Base, name=None, scale=1.0) -> Optional[Curve]:
|
||||
def icurve_to_native(speckle_curve: Base, name: str, scale: float) -> Optional[bpy.types.Curve]:
|
||||
curve_type = type(speckle_curve)
|
||||
if curve_type not in SUPPORTED_CURVES:
|
||||
_report(f"Unsupported curve type: {curve_type}")
|
||||
return None
|
||||
name = name or f"{curve_type} -- {speckle_curve.id}"
|
||||
blender_curve = (
|
||||
bpy.data.curves[name]
|
||||
if name in bpy.data.curves.keys()
|
||||
else bpy.data.curves.new(name, type="CURVE")
|
||||
)
|
||||
blender_curve.dimensions = "3D"
|
||||
blender_curve.resolution_u = 12
|
||||
blender_curve.resolution_u = 12 #TODO: We could maybe decern the resolution from the ployline displayValue
|
||||
|
||||
icurve_to_native_spline(speckle_curve, blender_curve, scale)
|
||||
|
||||
return blender_curve
|
||||
|
||||
|
||||
def transform_to_native(transform: Transform, scale=1.0) -> mathutils.Matrix:
|
||||
mat = mathutils.Matrix(
|
||||
"""
|
||||
Transforms and Intances
|
||||
"""
|
||||
|
||||
def transform_to_native(transform: Transform, scale: float) -> MMatrix:
|
||||
mat = MMatrix(
|
||||
[
|
||||
transform.value[:4],
|
||||
transform.value[4:8],
|
||||
@@ -359,38 +498,165 @@ def transform_to_native(transform: Transform, scale=1.0) -> mathutils.Matrix:
|
||||
mat[i][3] *= scale
|
||||
return mat
|
||||
|
||||
def plane_to_native_transform(plane: Plane, fallback_scale:float = 1) -> MMatrix:
|
||||
scale_factor = get_scale_factor(plane, fallback_scale)
|
||||
tx = (plane.origin.x * scale_factor)
|
||||
ty = (plane.origin.y * scale_factor)
|
||||
tz = (plane.origin.z * scale_factor)
|
||||
|
||||
def block_def_to_native(definition: BlockDefinition, scale=1.0) -> bpy.types.Collection:
|
||||
native_def = bpy.data.collections.get(definition.name)
|
||||
return MMatrix((
|
||||
(plane.xdir.x, plane.xdir.y, plane.xdir.z , 0),
|
||||
(plane.ydir.x, plane.ydir.y, plane.ydir.z , 0),
|
||||
(plane.normal.x, plane.normal.y, plane.normal.z , 0),
|
||||
(tx, ty, tz, 1)
|
||||
)).transposed()
|
||||
|
||||
|
||||
"""
|
||||
Instances / Blocks
|
||||
"""
|
||||
|
||||
def _get_instance_name(instance: Instance) -> str:
|
||||
name_prefix = _speckle_object_name(instance) or _speckle_object_name(instance.definition) or _simplified_speckle_name(instance.speckle_type)
|
||||
return f"{name_prefix}{OBJECT_NAME_SEPERATOR}{instance.id}"
|
||||
|
||||
|
||||
def instance_to_native_object(instance: Instance, scale: float) -> Tuple[bpy.types.Object, List[bpy.types.Object]]:
|
||||
"""
|
||||
Converts Instance to a unique object with (potentially) shared data (linked duplicate)
|
||||
"""
|
||||
if not instance.definition: raise Exception(f"Instance is missing a definition")
|
||||
if not instance.transform: raise Exception(f"Instance is missing a transform")
|
||||
|
||||
name = _get_instance_name(instance)
|
||||
definition = instance.definition
|
||||
|
||||
native_instance: Object
|
||||
native_elements: List[Object] = []
|
||||
elements_on_instance: List[Object] = []
|
||||
|
||||
if isinstance(definition, BlockDefinition): #NOTE: We have to handle BlockDefinitions specially here, since they don't follow normal traversal rules
|
||||
native_instance = create_new_object(None, name) #Instance will be empty
|
||||
native_instance.empty_display_size = 0
|
||||
for geo in definition.geometry:
|
||||
native_elements.append(convert_to_native(geo)[-1])
|
||||
else:
|
||||
native_instance = convert_to_native(instance.definition)[-1] # Convert assuming that definition is convertable
|
||||
|
||||
instance_transform = transform_to_native(instance.transform, scale)
|
||||
instance_transform_inverted = instance_transform.inverted()
|
||||
native_instance.matrix_world = instance_transform
|
||||
|
||||
(_, elements_on_instance) = element_to_native(instance, name, scale)
|
||||
for c in elements_on_instance:
|
||||
c.matrix_world = instance_transform_inverted @ c.matrix_world #Undo the instance transform on elements
|
||||
|
||||
native_elements.extend(elements_on_instance)
|
||||
|
||||
return (native_instance, native_elements) #TODO: need to double check that all child objects have custom props attached correctly
|
||||
|
||||
def instance_to_native_collection_instance(instance: Instance, scale: float) -> bpy.types.Object:
|
||||
"""
|
||||
Convert an Instance as a transformed Object with the `instance_collection` property
|
||||
set to be the `instance.Definition` converted as a collection
|
||||
|
||||
The definition collection won't be linked to the current scene
|
||||
Any Elements on the instance object will also be converted (and spacially transformed)
|
||||
"""
|
||||
if not instance.definition: raise Exception(f"Instance is missing a definition")
|
||||
if not instance.transform: raise Exception(f"Instance is missing a transform")
|
||||
|
||||
name = _get_instance_name(instance)
|
||||
|
||||
# Get/Convert definition collection
|
||||
collection_def = _instance_definition_to_native(instance.definition)
|
||||
|
||||
# Convert elements as children of collection instance object
|
||||
(_, elements) = element_to_native(instance, name, scale, False)
|
||||
|
||||
instance_transform = transform_to_native(instance.transform, scale)
|
||||
instance_transform_inverted = instance_transform.inverted()
|
||||
|
||||
native_instance = bpy.data.objects.new(name, None)
|
||||
|
||||
#add_custom_properties(instance, native_instance)
|
||||
# hide the instance axes so they don't clutter the viewport
|
||||
native_instance.empty_display_size = 0
|
||||
native_instance.instance_collection = collection_def
|
||||
native_instance.instance_type = "COLLECTION"
|
||||
native_instance.matrix_world =instance_transform
|
||||
|
||||
for c in elements:
|
||||
c.matrix_world = instance_transform_inverted @ c.matrix_world #Undo the instance transform on elements
|
||||
c.parent = native_instance #TODO: need to double check that all child objects have custom props attached correctly
|
||||
|
||||
return native_instance
|
||||
|
||||
def _instance_definition_to_native(definition: Union[Base, BlockDefinition]) -> bpy.types.Collection:
|
||||
"""
|
||||
Converts a geometry carrying Base as a collection (does not link it to the scene)
|
||||
"""
|
||||
name = _generate_object_name(definition)
|
||||
native_def = bpy.data.collections.get(name)
|
||||
if native_def:
|
||||
return native_def
|
||||
|
||||
native_def = bpy.data.collections.new(definition.name)
|
||||
native_def = bpy.data.collections.new(name)
|
||||
native_def["applicationId"] = definition.applicationId
|
||||
for geo in definition.geometry:
|
||||
if b_obj := convert_to_native(geo):
|
||||
native_def.objects.link(
|
||||
b_obj
|
||||
if isinstance(b_obj, bpy_types.Object)
|
||||
else bpy.data.objects.new(b_obj.name, b_obj)
|
||||
)
|
||||
|
||||
#TODO could maybe replace BlockDefinition awareness with a single traverse member call
|
||||
geometry = definition.geometry if isinstance(definition, BlockDefinition) else [definition]
|
||||
|
||||
for geo in geometry:
|
||||
if not geo: continue
|
||||
converted = convert_to_native(geo)[-1] #NOTE: we assume the last item is the root converted item
|
||||
link_object_to_collection_nested(converted, native_def)
|
||||
|
||||
|
||||
return native_def
|
||||
|
||||
|
||||
def block_instance_to_native(instance: BlockInstance, scale=1.0) -> bpy.types.Object:
|
||||
"""
|
||||
Convert BlockInstance to native
|
||||
"""
|
||||
name = f"{getattr(instance, 'name', None) or instance.blockDefinition.name} -- {instance.id}"
|
||||
native_def = block_def_to_native(instance.blockDefinition, scale)
|
||||
"""
|
||||
Object Naming
|
||||
"""
|
||||
|
||||
native_instance = bpy.data.objects.new(name, None)
|
||||
add_custom_properties(instance, native_instance)
|
||||
native_instance["name"] = getattr(instance, 'name', None) or instance.blockDefinition.name
|
||||
# hide the instance axes so they don't clutter the viewport
|
||||
native_instance.empty_display_size = 0
|
||||
native_instance.instance_collection = native_def
|
||||
native_instance.instance_type = "COLLECTION"
|
||||
native_instance.matrix_world = transform_to_native(instance.transform, scale)
|
||||
return native_instance
|
||||
def _speckle_object_name(speckle_object: Base) -> Optional[str]:
|
||||
return (getattr(speckle_object, "name", None)
|
||||
or getattr(speckle_object, "Name", None)
|
||||
or getattr(speckle_object, "family", None)
|
||||
)
|
||||
|
||||
|
||||
# Blender object names must not exceed 62 characters
|
||||
# We need to ensure the complete ID is included in the name (to prevent identity collisions)
|
||||
# So we if the name is too long, we need to truncate
|
||||
OBJECT_NAME_MAX_LENGTH = 62
|
||||
SPECKLE_ID_LENGTH = 32
|
||||
OBJECT_NAME_SEPERATOR = " -- "
|
||||
|
||||
def _truncate_name(name: str) -> str:
|
||||
|
||||
MAX_NAME_LENGTH = OBJECT_NAME_MAX_LENGTH - SPECKLE_ID_LENGTH - len(OBJECT_NAME_SEPERATOR)
|
||||
|
||||
return name[:MAX_NAME_LENGTH]
|
||||
|
||||
|
||||
def _simplified_speckle_name(speckle_type: str) -> str:
|
||||
return(speckle_type.rsplit('.')[-1]) #Take only the most specific object type name (without namespace)
|
||||
|
||||
def _generate_object_name(speckle_object: Base) -> str:
|
||||
prefix: str
|
||||
name = _speckle_object_name(speckle_object)
|
||||
if name:
|
||||
prefix = _truncate_name(name)
|
||||
else:
|
||||
prefix = _simplified_speckle_name(speckle_object.speckle_type)
|
||||
|
||||
return f"{prefix}{OBJECT_NAME_SEPERATOR}{speckle_object.id}"
|
||||
|
||||
|
||||
def get_scale_factor(speckle_object: Base, fallback: float = 1.0) -> float:
|
||||
scale = fallback
|
||||
if units := getattr(speckle_object, "units", None):
|
||||
scale = get_scale_length(units) / bpy.context.scene.unit_settings.scale_length
|
||||
return scale
|
||||
@@ -1,12 +1,19 @@
|
||||
from typing import Optional
|
||||
from typing import Dict, Iterable, Optional, Tuple
|
||||
import bpy
|
||||
from bpy.types import Depsgraph, MeshVertColor, MeshVertex, Object
|
||||
from bpy.types import Depsgraph, Material, MeshPolygon, Object
|
||||
from deprecated import deprecated
|
||||
from mathutils.geometry import interpolate_bezier
|
||||
from mathutils import (
|
||||
Matrix as MMatrix,
|
||||
Vector as MVector,
|
||||
)
|
||||
from specklepy.objects.geometry import Mesh, Curve, Interval, Box, Point, Polyline
|
||||
from specklepy.objects.other import *
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.convert.util import (
|
||||
get_blender_custom_properties,
|
||||
make_knots,
|
||||
nurb_make_curve,
|
||||
to_argb_int,
|
||||
)
|
||||
|
||||
@@ -23,7 +30,7 @@ def convert_to_speckle(blender_object: Object, scale: float, units: str, desgrap
|
||||
return None
|
||||
|
||||
speckle_objects = []
|
||||
speckle_material = material_to_speckle(blender_object)
|
||||
# speckle_material = material_to_speckle_old(blender_object) #TODO: What about curves with materials...
|
||||
if desgraph:
|
||||
blender_object = blender_object.evaluated_get(desgraph)
|
||||
converted = None
|
||||
@@ -40,12 +47,11 @@ def convert_to_speckle(blender_object: Object, scale: float, units: str, desgrap
|
||||
speckle_objects.extend([c for c in converted if c != None])
|
||||
else:
|
||||
speckle_objects.append(converted)
|
||||
|
||||
for so in speckle_objects:
|
||||
so.properties = get_blender_custom_properties(blender_object)
|
||||
so.applicationId = so.properties.pop("applicationId", None)
|
||||
|
||||
if speckle_material:
|
||||
so["renderMaterial"] = speckle_material
|
||||
|
||||
# Set object transform
|
||||
if blender_type != "EMPTY":
|
||||
@@ -55,56 +61,70 @@ def convert_to_speckle(blender_object: Object, scale: float, units: str, desgrap
|
||||
|
||||
return speckle_objects
|
||||
|
||||
def mesh_to_speckle(blender_object: Object, data: bpy.types.Mesh, scale: float = 1.0) -> List[Mesh]:
|
||||
#if data.loop_triangles is None or len(data.loop_triangles) < 1:
|
||||
# data.calc_loop_triangles()
|
||||
|
||||
def mesh_to_speckle(blender_object: Object, data: bpy.types.Mesh, scale=1.0) -> List[Mesh]:
|
||||
if data.loop_triangles is None or len(data.loop_triangles) < 1:
|
||||
data.calc_loop_triangles()
|
||||
# Categorise polygons by material index
|
||||
submesh_data: Dict[int, List[MeshPolygon]] = {}
|
||||
|
||||
for p in data.polygons:
|
||||
if p.material_index not in submesh_data:
|
||||
submesh_data[p.material_index] = []
|
||||
submesh_data[p.material_index].append(p)
|
||||
|
||||
transform = blender_object.matrix_world
|
||||
scaled_vertices = [tuple(transform @ x.co * scale) for x in data.vertices]
|
||||
|
||||
# Create Speckle meshes for each material
|
||||
submeshes = []
|
||||
index_counter = 0
|
||||
for i in submesh_data:
|
||||
index_mapping: Dict[int, int] = {}
|
||||
|
||||
#Loop through each polygon, and map indicies to their new index in m_verts
|
||||
|
||||
m_verts: List[float] = []
|
||||
m_faces: List[int] = []
|
||||
m_texcoords: List[float] = []
|
||||
for face in submesh_data[i]:
|
||||
u_indices = face.vertices
|
||||
m_faces.append(len(u_indices))
|
||||
for u_index in u_indices:
|
||||
if u_index not in index_mapping:
|
||||
# Create mapping between index in blender mesh, and new index in speckle submesh
|
||||
index_mapping[u_index] = len(m_verts) // 3
|
||||
vert = scaled_vertices[u_index]
|
||||
m_verts.append(vert[0])
|
||||
m_verts.append(vert[1])
|
||||
m_verts.append(vert[2])
|
||||
|
||||
if data.uv_layers.active:
|
||||
vt = data.uv_layers.active.data[index_counter]
|
||||
m_texcoords.extend([vt.uv.x, vt.uv.y])
|
||||
|
||||
m_faces.append(index_mapping[u_index])
|
||||
index_counter += 1
|
||||
|
||||
speckle_mesh = Mesh(
|
||||
vertices=m_verts,
|
||||
faces=m_faces,
|
||||
colors=[],
|
||||
textureCoordinates=m_texcoords,
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
)
|
||||
|
||||
if i < len(data.materials):
|
||||
material = data.materials[i]
|
||||
if material is not None:
|
||||
speckle_mesh["renderMaterial"] = material_to_speckle(material)
|
||||
submeshes.append(speckle_mesh)
|
||||
|
||||
return submeshes
|
||||
|
||||
|
||||
mat = blender_object.matrix_world
|
||||
|
||||
verts = [tuple(mat @ x.co * scale) for x in data.vertices]
|
||||
|
||||
flattend_verts = []
|
||||
for row in verts: flattend_verts.extend(row)
|
||||
|
||||
faces = [p.vertices for p in data.polygons]
|
||||
unit_system = bpy.context.scene.unit_settings.system
|
||||
|
||||
sm = Mesh(
|
||||
name=blender_object.name,
|
||||
vertices=flattend_verts,
|
||||
faces=[],
|
||||
colors=[],
|
||||
textureCoordinates=[],
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
)
|
||||
|
||||
if data.uv_layers.active:
|
||||
for vt in data.uv_layers.active.data:
|
||||
sm.textureCoordinates.extend([vt.uv.x, vt.uv.y])
|
||||
|
||||
for f in faces:
|
||||
n = len(f)
|
||||
if n == 3:
|
||||
sm.faces.append(0)
|
||||
elif n == 4:
|
||||
sm.faces.append(1)
|
||||
else:
|
||||
sm.faces.append(n)
|
||||
sm.faces.extend(f)
|
||||
|
||||
# TODO: figure out how to align vertex colors and vertices consistantly in receiving applications
|
||||
# we are seeing the same issue as with texture coordinate alignment
|
||||
#if data.color_attributes.active_color:
|
||||
# sm.colors = [to_argb_int(x.color) for x in data.color_attributes.active_color.data]
|
||||
|
||||
|
||||
return [sm]
|
||||
|
||||
|
||||
def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Curve:
|
||||
def bezier_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Curve:
|
||||
degree = 3
|
||||
closed = spline.use_cyclic_u
|
||||
|
||||
@@ -142,50 +162,121 @@ def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: floa
|
||||
name=name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
periodic= not spline.use_endpoint_u,
|
||||
points=flattend_points,
|
||||
weights=[1] * num_points,
|
||||
knots=knots,
|
||||
rational=False,
|
||||
rational=True,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
displayValue = bezier_to_speckle_polyline(matrix, spline, scale, length),
|
||||
)
|
||||
|
||||
|
||||
def nurbs_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Curve:
|
||||
knots = make_knots(spline)
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
def nurbs_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Curve:
|
||||
|
||||
degree = spline.order_u - 1
|
||||
knots = make_knots(spline)
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
|
||||
weights = [pt.weight for pt in spline.points]
|
||||
is_rational = all(w == weights[0] for w in weights)
|
||||
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
|
||||
flattend_points = []
|
||||
for row in points: flattend_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])
|
||||
|
||||
for i in range(0, degree):
|
||||
weights.append(weights[i])
|
||||
|
||||
return Curve(
|
||||
name=name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
periodic= not spline.use_endpoint_u,
|
||||
points=flattend_points,
|
||||
weights=[pt.weight for pt in spline.points],
|
||||
weights=weights,
|
||||
knots=knots,
|
||||
rational=False,
|
||||
rational=is_rational,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
displayValue=nurbs_to_speckle_polyline(matrix, spline, scale, length),
|
||||
)
|
||||
|
||||
def nurbs_to_speckle_polyline(matrix: MMatrix, spline: bpy.types.Spline, scale: float, length: Optional[float] = None) -> Polyline:
|
||||
"""
|
||||
Samples a nurbs curve with resolution_u creating a polyline
|
||||
"""
|
||||
points = []
|
||||
sampled_points = nurb_make_curve(spline, spline.resolution_u, 3)
|
||||
for i in range(0, len(sampled_points), 3):
|
||||
scaled_point = matrix @ MVector((
|
||||
sampled_points[i + 0],
|
||||
sampled_points[i + 1],
|
||||
sampled_points[i + 2])) * scale
|
||||
|
||||
def poly_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Polyline:
|
||||
points.append(scaled_point.x)
|
||||
points.append(scaled_point.y)
|
||||
points.append(scaled_point.z)
|
||||
|
||||
length = length or spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
return Polyline(value=points, closed = spline.use_cyclic_u, domain=domain, area=0, len=length)
|
||||
|
||||
|
||||
#Inspired by https://blender.stackexchange.com/a/689 (CC BY-SA 3.0)
|
||||
def bezier_to_speckle_polyline(matrix: MMatrix, spline: bpy.types.Spline, scale: float, length: Optional[float] = None) -> Optional[Polyline]:
|
||||
"""
|
||||
Samples a Bézier curve with resolution_u creating a polyline
|
||||
"""
|
||||
segments = len(spline.bezier_points)
|
||||
if segments < 2: return None
|
||||
|
||||
R = spline.resolution_u + 1
|
||||
|
||||
points = []
|
||||
if not spline.use_cyclic_u:
|
||||
segments -= 1
|
||||
|
||||
points: List[float] = []
|
||||
for i in range(segments):
|
||||
inext = (i + 1) % len(spline.bezier_points)
|
||||
|
||||
knot1 = spline.bezier_points[i].co
|
||||
handle1 = spline.bezier_points[i].handle_right
|
||||
handle2 = spline.bezier_points[inext].handle_left
|
||||
knot2 = spline.bezier_points[inext].co
|
||||
|
||||
_points = interpolate_bezier(knot1, handle1, handle2, knot2, R)
|
||||
for p in _points:
|
||||
scaled_point = matrix @ p * scale
|
||||
points.append(scaled_point.x)
|
||||
points.append(scaled_point.y)
|
||||
points.append(scaled_point.z)
|
||||
|
||||
length = length or spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
return Polyline(value=points, closed = spline.use_cyclic_u, domain=domain, area=0, len=length)
|
||||
|
||||
def poly_to_speckle(matrix: MMatrix, spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Polyline:
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
|
||||
flattend_points = []
|
||||
@@ -233,7 +324,7 @@ def icurve_to_speckle(blender_object: Object, data: bpy.types.Curve, scale=1.0)
|
||||
|
||||
return curves
|
||||
|
||||
|
||||
@deprecated
|
||||
def ngons_to_speckle_polylines(blender_object: Object, data: bpy.types.Mesh, scale=1.0) -> Optional[List[Polyline]]:
|
||||
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
|
||||
|
||||
@@ -266,15 +357,7 @@ def ngons_to_speckle_polylines(blender_object: Object, data: bpy.types.Mesh, sca
|
||||
return polylines
|
||||
|
||||
|
||||
def material_to_speckle(blender_object: Object) -> Optional[RenderMaterial]:
|
||||
"""Create and return a render material from a blender object"""
|
||||
if not getattr(blender_object.data, "materials", None):
|
||||
return None
|
||||
|
||||
blender_mat: bpy.types.Material = blender_object.data.materials[0]
|
||||
if not blender_mat:
|
||||
return None
|
||||
|
||||
def material_to_speckle(blender_mat: bpy.types.Material) -> RenderMaterial:
|
||||
speckle_mat = RenderMaterial()
|
||||
speckle_mat.name = blender_mat.name
|
||||
|
||||
@@ -296,7 +379,19 @@ def material_to_speckle(blender_object: Object) -> Optional[RenderMaterial]:
|
||||
return speckle_mat
|
||||
|
||||
|
||||
def transform_to_speckle(blender_transform: List[float], scale=1.0) -> Transform:
|
||||
def material_to_speckle_old(blender_object: Object) -> Optional[RenderMaterial]:
|
||||
"""Create and return a render material from a blender object"""
|
||||
if not getattr(blender_object.data, "materials", None):
|
||||
return None
|
||||
|
||||
blender_mat: bpy.types.Material = blender_object.data.materials[0]
|
||||
if not blender_mat:
|
||||
return None
|
||||
|
||||
return material_to_speckle(blender_mat)
|
||||
|
||||
|
||||
def transform_to_speckle(blender_transform: Iterable[Iterable[float]], scale=1.0) -> Transform:
|
||||
value = [y for x in blender_transform for y in x]
|
||||
# scale the translation
|
||||
for i in (3, 7, 11):
|
||||
|
||||
+184
-66
@@ -1,13 +1,13 @@
|
||||
import math
|
||||
from typing import Tuple
|
||||
from typing import Any, Optional, Tuple
|
||||
from bmesh.types import BMesh
|
||||
import bpy, struct, idprop
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry import Mesh
|
||||
from specklepy.serialization.base_object_serializer import BaseObjectSerializer
|
||||
from specklepy.objects.geometry import Circle, Mesh, Ellipse
|
||||
from specklepy.objects.other import RenderMaterial
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy.types import Object
|
||||
from bpy.types import Material, Object
|
||||
|
||||
IGNORED_PROPERTY_KEYS = {
|
||||
"id",
|
||||
@@ -25,7 +25,7 @@ IGNORED_PROPERTY_KEYS = {
|
||||
}
|
||||
|
||||
|
||||
def to_rgba(argb_int: int) -> Tuple[float]:
|
||||
def to_rgba(argb_int: int) -> Tuple[float, float, float, float]:
|
||||
"""Converts the int representation of a colour into a percent RGBA tuple"""
|
||||
alpha = ((argb_int >> 24) & 255) / 255
|
||||
red = ((argb_int >> 16) & 255) / 255
|
||||
@@ -35,18 +35,27 @@ def to_rgba(argb_int: int) -> Tuple[float]:
|
||||
return (red, green, blue, alpha)
|
||||
|
||||
|
||||
def to_argb_int(diffuse_colour) -> int:
|
||||
def to_argb_int(rgba_color: list[float]) -> int:
|
||||
"""Converts an RGBA array to an ARGB integer"""
|
||||
diffuse_colour = diffuse_colour[-1:] + diffuse_colour[:3]
|
||||
diffuse_colour = [int(val * 255) for val in diffuse_colour]
|
||||
argb_color = rgba_color[-1:] + rgba_color[:3]
|
||||
int_color = [int(val * 255) for val in argb_color]
|
||||
|
||||
return int.from_bytes(diffuse_colour, byteorder="big", signed=True)
|
||||
return int.from_bytes(int_color, byteorder="big", signed=True)
|
||||
|
||||
def set_custom_property(key: str, value: Any, blender_object: Object) -> None:
|
||||
try:
|
||||
#Expected c types: float, int, string, float[], int[]
|
||||
blender_object[key] = value
|
||||
except (OverflowError, TypeError) as ex:
|
||||
print(f"Skipping setting property ({key}={value}) on {blender_object.name_full}, Reason: {ex}")
|
||||
except Exception as ex:
|
||||
#TODO: Log this as it's unexpected!!!
|
||||
print(f"Skipping setting property ({key}={value}) on {blender_object.name_full}, Reason: {ex}")
|
||||
|
||||
def add_custom_properties(speckle_object: Base, blender_object: Object):
|
||||
if blender_object is None:
|
||||
return
|
||||
|
||||
serializer = BaseObjectSerializer()
|
||||
blender_object["_speckle_type"] = type(speckle_object).__name__
|
||||
|
||||
app_id = getattr(speckle_object, "applicationId", None)
|
||||
@@ -59,39 +68,28 @@ def add_custom_properties(speckle_object: Base, blender_object: Object):
|
||||
continue
|
||||
|
||||
if isinstance(val, (int, str, float)):
|
||||
blender_object[key] = val
|
||||
set_custom_property(key, val, blender_object)
|
||||
elif key == "properties" and isinstance(val, Base):
|
||||
val["applicationId"] = None
|
||||
add_custom_properties(val, blender_object)
|
||||
elif isinstance(val, list):
|
||||
items = [item for item in val if not isinstance(item, Base)]
|
||||
if items:
|
||||
blender_object[key] = items
|
||||
set_custom_property(key, items, blender_object)
|
||||
elif isinstance(val,dict):
|
||||
for (k,v) in val.items():
|
||||
if not isinstance(v, Base):
|
||||
blender_object[k] = v
|
||||
set_custom_property(k, v, blender_object)
|
||||
|
||||
|
||||
def add_blender_material(speckle_object: Base, blender_object: Object) -> None:
|
||||
"""Add material to a blender object if the corresponding speckle object has a render material"""
|
||||
if blender_object.data is None:
|
||||
return
|
||||
|
||||
speckle_mat = getattr(
|
||||
speckle_object,
|
||||
"renderMaterial",
|
||||
getattr(speckle_object, "@renderMaterial", None),
|
||||
)
|
||||
if not speckle_mat:
|
||||
return
|
||||
|
||||
mat_name = getattr(speckle_mat, "name", None) or speckle_mat.__dict__.get("@name")
|
||||
def render_material_to_native(speckle_mat: RenderMaterial) -> Material:
|
||||
|
||||
mat_name = speckle_mat.name
|
||||
if not mat_name:
|
||||
mat_name = speckle_mat.applicationId or speckle_mat.id or speckle_mat.get_id()
|
||||
|
||||
blender_mat = bpy.data.materials.get(mat_name)
|
||||
if not blender_mat:
|
||||
if blender_mat is None:
|
||||
blender_mat = bpy.data.materials.new(mat_name)
|
||||
|
||||
# for now, we're not updating these materials. as per tom's suggestion, we should have a toggle
|
||||
@@ -105,10 +103,24 @@ def add_blender_material(speckle_object: Base, blender_object: Object) -> None:
|
||||
inputs["Metallic"].default_value = speckle_mat.metalness
|
||||
inputs["Alpha"].default_value = speckle_mat.opacity
|
||||
|
||||
if speckle_mat.opacity < 1:
|
||||
if speckle_mat.opacity < 1.0:
|
||||
blender_mat.blend_method = "BLEND"
|
||||
|
||||
blender_object.data.materials.append(blender_mat)
|
||||
return blender_mat
|
||||
|
||||
def get_render_material(speckle_object: Base) -> Optional[RenderMaterial]:
|
||||
"""Trys to get a RenderMaterial on given speckle_object and convert it to a blender material"""
|
||||
|
||||
speckle_mat = getattr(
|
||||
speckle_object,
|
||||
"renderMaterial",
|
||||
getattr(speckle_object, "@renderMaterial", None),
|
||||
)
|
||||
if not isinstance(speckle_mat, RenderMaterial):
|
||||
return None
|
||||
|
||||
return speckle_mat
|
||||
|
||||
|
||||
|
||||
def add_vertices(speckle_mesh: Mesh, blender_mesh: BMesh, scale=1.0):
|
||||
@@ -124,12 +136,11 @@ def add_vertices(speckle_mesh: Mesh, blender_mesh: BMesh, scale=1.0):
|
||||
)
|
||||
)
|
||||
|
||||
blender_mesh.verts.ensure_lookup_table()
|
||||
|
||||
|
||||
def add_faces(speckle_mesh: Mesh, blender_mesh: BMesh, smooth=False):
|
||||
def add_faces(speckle_mesh: Mesh, blender_mesh: BMesh, indexOffset: int, materialIndex: int = 0, smooth:bool = True):
|
||||
sfaces = speckle_mesh.faces
|
||||
|
||||
|
||||
if sfaces and len(sfaces) > 0:
|
||||
i = 0
|
||||
while i < len(sfaces):
|
||||
@@ -140,16 +151,14 @@ def add_faces(speckle_mesh: Mesh, blender_mesh: BMesh, smooth=False):
|
||||
i += 1
|
||||
try:
|
||||
f = blender_mesh.faces.new(
|
||||
[blender_mesh.verts[int(x)] for x in sfaces[i : i + n]]
|
||||
[blender_mesh.verts[x + indexOffset] for x in sfaces[i : i + n]]
|
||||
)
|
||||
f.material_index = materialIndex
|
||||
f.smooth = smooth
|
||||
except Exception as e:
|
||||
_report(f"Failed to create face for mesh {speckle_mesh.id} \n{e}")
|
||||
i += n
|
||||
|
||||
blender_mesh.faces.ensure_lookup_table()
|
||||
blender_mesh.verts.index_update()
|
||||
|
||||
|
||||
def add_colors(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
|
||||
@@ -196,7 +205,7 @@ def add_uv_coords(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
)
|
||||
else:
|
||||
_report(
|
||||
f"Failed to match UV coordinates to vert data. Blender mesh verts: {len(blender_mesh.verts)}, Speckle UVs * 2: {len(s_uvs) * 2}"
|
||||
f"Failed to match UV coordinates to vert data. Blender mesh verts: {len(blender_mesh.verts)}, Speckle UVs: {len(s_uvs) // 2}"
|
||||
)
|
||||
return
|
||||
|
||||
@@ -243,41 +252,37 @@ def get_blender_custom_properties(obj, max_depth=1000):
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
"""
|
||||
Python implementation of Blender's NURBS curve generation for to Speckle conversion
|
||||
from: https://blender.stackexchange.com/a/34276
|
||||
based on https://projects.blender.org/blender/blender/src/branch/main/source/blender/blenkernel/intern/curve.cc (check old version)
|
||||
"""
|
||||
|
||||
|
||||
def macro_knotsu(nu):
|
||||
def macro_knotsu(nu: bpy.types.Spline) -> int:
|
||||
return nu.order_u + nu.point_count_u + (nu.order_u - 1 if nu.use_cyclic_u else 0)
|
||||
|
||||
|
||||
def macro_segmentsu(nu):
|
||||
def macro_segmentsu(nu: bpy.types.Spline) -> int:
|
||||
return nu.point_count_u if nu.use_cyclic_u else nu.point_count_u - 1
|
||||
|
||||
|
||||
def make_knots(nu):
|
||||
knots = [0.0] * (4 + macro_knotsu(nu))
|
||||
def make_knots(nu: bpy.types.Spline) -> list[float]:
|
||||
knots = [0.0] * macro_knotsu(nu)
|
||||
flag = nu.use_endpoint_u + (nu.use_bezier_u << 1)
|
||||
if nu.use_cyclic_u:
|
||||
calc_knots(knots, nu.point_count_u, nu.order_u, 0)
|
||||
makecyclicknots(knots, nu.point_count_u, nu.order_u)
|
||||
else:
|
||||
calc_knots(knots, nu.point_count_u, nu.order_u, flag)
|
||||
return knots
|
||||
|
||||
|
||||
def calc_knots(knots, point_count, order, flag):
|
||||
def calc_knots(knots: list[float], point_count: int, order: int, flag: int) -> None:
|
||||
pts_order = point_count + order
|
||||
if flag == 1:
|
||||
if flag == 1: # CU_NURB_ENDPOINT
|
||||
k = 0.0
|
||||
for a in range(1, pts_order + 1):
|
||||
knots[a - 1] = k
|
||||
if a >= order and a <= point_count:
|
||||
k += 1.0
|
||||
elif flag == 2:
|
||||
elif flag == 2: # CU_NURB_BEZIER
|
||||
if order == 4:
|
||||
k = 0.34
|
||||
for a in range(pts_order):
|
||||
@@ -290,24 +295,137 @@ def calc_knots(knots, point_count, order, flag):
|
||||
k += 0.5
|
||||
knots[a] = math.floor(k)
|
||||
else:
|
||||
for a in range(pts_order):
|
||||
knots[a] = a
|
||||
for a in range(1, len(knots) - 1):
|
||||
knots[a] = a - 1
|
||||
|
||||
knots[-1] = knots[-2]
|
||||
|
||||
def makecyclicknots(knots, point_count, order):
|
||||
order2 = order - 1
|
||||
def basis_nurb(t: float, order: int, point_count: int, knots: list[float], basis: list[float], start: int, end: int) -> Tuple[int, int]:
|
||||
i1 = i2 = 0
|
||||
orderpluspnts = order + point_count
|
||||
opp2 = orderpluspnts - 1
|
||||
|
||||
if order > 2:
|
||||
b = point_count + order2
|
||||
for a in range(1, order2):
|
||||
if knots[b] != knots[b - a]:
|
||||
break
|
||||
# this is for float inaccuracy
|
||||
if t < knots[0]:
|
||||
t = knots[0]
|
||||
elif t > knots[opp2]:
|
||||
t = knots[opp2]
|
||||
|
||||
if a == order2:
|
||||
knots[point_count + order - 2] += 1.0
|
||||
# this part is order '1'
|
||||
o2 = order + 1
|
||||
for i in range(opp2):
|
||||
if knots[i] != knots[i + 1] and t >= knots[i] and t <= knots[i + 1]:
|
||||
basis[i] = 1.0
|
||||
i1 = i - o2
|
||||
if i1 < 0:
|
||||
i1 = 0
|
||||
i2 = i
|
||||
i += 1
|
||||
while i < opp2:
|
||||
basis[i] = 0.0
|
||||
i += 1
|
||||
break
|
||||
|
||||
b = order
|
||||
c = point_count + order + order2
|
||||
for a in range(point_count + order2, c):
|
||||
knots[a] = knots[a - 1] + (knots[b] - knots[b - 1])
|
||||
b -= 1
|
||||
else:
|
||||
basis[i] = 0.0
|
||||
|
||||
basis[i] = 0.0
|
||||
|
||||
# this is order 2, 3, ...
|
||||
for j in range(2, order + 1):
|
||||
|
||||
if i2 + j >= orderpluspnts:
|
||||
i2 = opp2 - j
|
||||
|
||||
for i in range(i1, i2 + 1):
|
||||
if basis[i] != 0.0:
|
||||
d = ((t - knots[i]) * basis[i]) / (knots[i + j - 1] - knots[i])
|
||||
else:
|
||||
d = 0.0
|
||||
|
||||
if basis[i + 1] != 0.0:
|
||||
e = ((knots[i + j] - t) * basis[i + 1]) / (knots[i + j] - knots[i + 1])
|
||||
else:
|
||||
e = 0.0
|
||||
|
||||
basis[i] = d + e
|
||||
|
||||
start = 1000
|
||||
end = 0
|
||||
|
||||
for i in range(i1, i2 + 1):
|
||||
if basis[i] > 0.0:
|
||||
end = i
|
||||
if start == 1000:
|
||||
start = i
|
||||
|
||||
return start, end
|
||||
|
||||
def nurb_make_curve(nu: bpy.types.Spline, resolu: int, stride: int = 3) -> list[float]:
|
||||
""""BKE_nurb_makeCurve"""
|
||||
EPS = 1e-6
|
||||
coord_index = istart = iend = 0
|
||||
|
||||
coord_array = [0.0] * (3 * nu.resolution_u * macro_segmentsu(nu))
|
||||
sum_array = [0] * nu.point_count_u
|
||||
basisu = [0.0] * macro_knotsu(nu)
|
||||
knots = make_knots(nu)
|
||||
|
||||
resolu = resolu * macro_segmentsu(nu)
|
||||
ustart = knots[nu.order_u - 1]
|
||||
uend = knots[nu.point_count_u + nu.order_u - 1] if nu.use_cyclic_u else \
|
||||
knots[nu.point_count_u]
|
||||
ustep = (uend - ustart) / (resolu - (0 if nu.use_cyclic_u else 1))
|
||||
cycl = nu.order_u - 1 if nu.use_cyclic_u else 0
|
||||
|
||||
u = ustart
|
||||
while resolu:
|
||||
resolu -= 1
|
||||
istart, iend = basis_nurb(u, nu.order_u, nu.point_count_u + cycl, knots, basisu, istart, iend)
|
||||
|
||||
#/* calc sum */
|
||||
sumdiv = 0.0
|
||||
sum_index = 0
|
||||
pt_index = istart - 1
|
||||
for i in range(istart, iend + 1):
|
||||
if i >= nu.point_count_u:
|
||||
pt_index = i - nu.point_count_u
|
||||
else:
|
||||
pt_index += 1
|
||||
|
||||
sum_array[sum_index] = basisu[i] * nu.points[pt_index].co[3]
|
||||
sumdiv += sum_array[sum_index]
|
||||
sum_index += 1
|
||||
|
||||
if (sumdiv != 0.0) and (sumdiv < 1.0 - EPS or sumdiv > 1.0 + EPS):
|
||||
sum_index = 0
|
||||
for i in range(istart, iend + 1):
|
||||
sum_array[sum_index] /= sumdiv
|
||||
sum_index += 1
|
||||
|
||||
coord_array[coord_index: coord_index + 3] = (0.0, 0.0, 0.0)
|
||||
|
||||
sum_index = 0
|
||||
pt_index = istart - 1
|
||||
for i in range(istart, iend + 1):
|
||||
if i >= nu.point_count_u:
|
||||
pt_index = i - nu.point_count_u
|
||||
else:
|
||||
pt_index += 1
|
||||
|
||||
if sum_array[sum_index] != 0.0:
|
||||
for j in range(3):
|
||||
coord_array[coord_index + j] += sum_array[sum_index] * nu.points[pt_index].co[j]
|
||||
sum_index += 1
|
||||
|
||||
coord_index += stride
|
||||
u += ustep
|
||||
|
||||
return coord_array
|
||||
|
||||
def link_object_to_collection_nested(obj: bpy.types.Object, col: bpy.types.Collection):
|
||||
if obj.name not in col.objects:
|
||||
col.objects.link(obj)
|
||||
|
||||
for child in obj.children:
|
||||
link_object_to_collection_nested(child, col)
|
||||
@@ -17,7 +17,7 @@ def modules_path() -> Path:
|
||||
|
||||
# set user modules path at beginning of paths for earlier hit
|
||||
if sys.path[1] != modules_path:
|
||||
sys.path.insert(1, modules_path)
|
||||
sys.path.insert(1, str(modules_path))
|
||||
|
||||
return modules_path
|
||||
|
||||
@@ -113,14 +113,14 @@ def _import_dependencies() -> None:
|
||||
|
||||
def ensure_dependencies() -> None:
|
||||
try:
|
||||
install_dependencies()
|
||||
invalidate_caches()
|
||||
_import_dependencies()
|
||||
print("Found all dependencies, proceed with loading")
|
||||
except ImportError:
|
||||
print("Failed to load all dependencies, trying to install them...")
|
||||
install_dependencies()
|
||||
|
||||
invalidate_caches()
|
||||
_import_dependencies()
|
||||
raise Exception(
|
||||
"Cannot automatically ensure Speckle dependencies. Please restart Blender!"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .users import LoadUsers, LoadUserStreams
|
||||
from .users import LoadUsers, LoadUserStreams, ResetUsers
|
||||
from .object import (
|
||||
UpdateObject,
|
||||
ResetObject,
|
||||
@@ -27,6 +27,7 @@ from .misc import OpenSpeckleGuide, OpenSpeckleTutorials, OpenSpeckleForum
|
||||
|
||||
operator_classes = [
|
||||
LoadUsers,
|
||||
ResetUsers,
|
||||
ReceiveStreamObjects,
|
||||
SendStreamObjects,
|
||||
LoadUserStreams,
|
||||
|
||||
@@ -3,13 +3,15 @@ Commit operators
|
||||
"""
|
||||
import bpy
|
||||
from bpy.props import BoolProperty
|
||||
from bpy_speckle.functions import _check_speckle_client_user_stream
|
||||
from bpy_speckle.functions import _check_speckle_client_user_stream, _report
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.properties.scene import SpeckleSceneSettings
|
||||
|
||||
|
||||
class DeleteCommit(bpy.types.Operator):
|
||||
"""
|
||||
Delete stream
|
||||
Deletes the selected commit from the selected stream.
|
||||
To execute from code, call: `bpy.ops.speckle.delete_commit(are_you_sure=True)`
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.delete_commit"
|
||||
@@ -37,27 +39,39 @@ class DeleteCommit(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
|
||||
if not self.are_you_sure:
|
||||
_report(f"{self.bl_idname}: cancelled by user")
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.are_you_sure = False
|
||||
|
||||
speckle = context.scene.speckle
|
||||
speckle: SpeckleSceneSettings = context.scene.speckle
|
||||
|
||||
check = _check_speckle_client_user_stream(context.scene)
|
||||
if check is None:
|
||||
user = speckle.get_active_user()
|
||||
if user is None:
|
||||
print(f"{self.bl_idname}: failed - No user selected/found")
|
||||
return {"CANCELLED"}
|
||||
|
||||
user, stream = check
|
||||
client = speckle_clients[int(context.scene.speckle.active_user)]
|
||||
stream = user.get_active_stream()
|
||||
if stream is None:
|
||||
print(f"{self.bl_idname}: failed - No stream selected/found")
|
||||
return {"CANCELLED"}
|
||||
|
||||
stream = user.streams[user.active_stream]
|
||||
if len(stream.branches) < 1:
|
||||
branch = stream.get_active_branch()
|
||||
if branch is None:
|
||||
print(f"{self.bl_idname}: failed - No branch selected/found")
|
||||
return {"CANCELLED"}
|
||||
branch = stream.branches[int(stream.branch)]
|
||||
if len(branch.commits) < 1:
|
||||
|
||||
commit = branch.get_active_commit()
|
||||
if commit is None:
|
||||
print(f"{self.bl_idname}: failed - No commit selected/found")
|
||||
return {"CANCELLED"}
|
||||
commit = branch.commits[int(branch.commit)]
|
||||
|
||||
client = speckle_clients[int(speckle.active_user)]
|
||||
|
||||
deleted = client.commit.delete(stream_id=stream.id, commit_id=commit.id)
|
||||
if not deleted:
|
||||
print(f"{self.bl_idname}: failed - Delete operation failed")
|
||||
return {"CANCELLED"}
|
||||
|
||||
print(f"{self.bl_idname}: succeeded - commit {commit.id} ({commit.message}) has been deleted from stream {stream.id}")
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -28,7 +28,6 @@ class UpdateObject(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
user = context.scene.speckle.users[int(context.scene.speckle.active_user)]
|
||||
client = speckle_clients[int(context.scene.speckle.active_user)]
|
||||
stream = user.streams[user.active_stream]
|
||||
|
||||
active = context.active_object
|
||||
_report(active)
|
||||
|
||||
@@ -3,16 +3,23 @@ Stream operators
|
||||
"""
|
||||
from itertools import chain
|
||||
from math import radians
|
||||
from typing import Callable, Dict, Iterable
|
||||
from typing import Callable, Dict, Iterable, Optional
|
||||
import bpy
|
||||
from bpy_speckle.convert.util import link_object_to_collection_nested
|
||||
from bpy_speckle.properties.scene import SpeckleSceneSettings
|
||||
from specklepy.api.models import Commit
|
||||
import webbrowser
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
BoolProperty,
|
||||
EnumProperty,
|
||||
)
|
||||
from bpy.types import Context, Object
|
||||
from bpy_speckle.convert.to_native import can_convert_to_native, convert_to_native
|
||||
from bpy_speckle.convert.to_native import (
|
||||
can_convert_to_native,
|
||||
convert_to_native,
|
||||
set_convert_instances_as,
|
||||
)
|
||||
from bpy_speckle.convert.to_speckle import (
|
||||
convert_to_speckle,
|
||||
)
|
||||
@@ -21,7 +28,6 @@ from bpy_speckle.functions import (
|
||||
get_scale_length,
|
||||
_report,
|
||||
)
|
||||
from bpy_speckle.convert import get_speckle_subobjects
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.operators.users import add_user_stream
|
||||
|
||||
@@ -79,8 +85,6 @@ def get_objects_collections_recursive(base: Base, parent_col: Optional[bpy.types
|
||||
|
||||
for name in base.get_dynamic_member_names():
|
||||
value = base[name]
|
||||
if name == "parameters" and "Revit" in base.speckle_type:
|
||||
continue
|
||||
if isinstance(value, list):
|
||||
objects.extend(item for item in value if isinstance(item, Base))
|
||||
if isinstance(value, Base):
|
||||
@@ -127,7 +131,7 @@ def get_receive_funcs(context: Context, created_objects: Dict[str, Object]) -> t
|
||||
nonlocal created_objects
|
||||
nonlocal objectCallback
|
||||
|
||||
progress += 1 #TODO: Progress bar never reaches 100 because func is only called for convertible objects
|
||||
progress += 1 #NOTE:XXX Progress bar never reaches 100 because func is only called for convertible objects
|
||||
context.window_manager.progress_update(progress)
|
||||
created_objects[obj.name] = obj
|
||||
|
||||
@@ -148,7 +152,7 @@ def bases_to_native(context: bpy.types.Context, collections: Dict[str, list], sc
|
||||
for obj in objects:
|
||||
if isinstance(obj, dict):
|
||||
bases_to_native(context, obj, scale, stream_id, func)
|
||||
elif isinstance(obj, list):
|
||||
elif isinstance(obj, list): #FIXME: wtf are these nested if statement, can this not be a recursive call?
|
||||
for item in obj:
|
||||
if isinstance(item, dict):
|
||||
bases_to_native(context, item, scale, stream_id, func)
|
||||
@@ -161,7 +165,7 @@ def bases_to_native(context: bpy.types.Context, collections: Dict[str, list], sc
|
||||
|
||||
else:
|
||||
_report(
|
||||
f"Something went wrong when receiving collection: {col_name}"
|
||||
f"Something went wrong when receiving collection: {col_name}" #FIXME: undescript report message
|
||||
)
|
||||
|
||||
bpy.context.view_layer.update()
|
||||
@@ -179,17 +183,17 @@ def base_to_native(context: bpy.types.Context,
|
||||
existing: Dict[str, Object],
|
||||
func: ObjectCallback = None
|
||||
):
|
||||
|
||||
new_objects = convert_to_native(base)
|
||||
if not isinstance(new_objects, list):
|
||||
new_objects = [new_objects]
|
||||
|
||||
if hasattr(base, "properties") and base.properties is not None:
|
||||
new_objects.extend(get_speckle_subobjects(base.properties, scale, base.id))
|
||||
elif isinstance(base, dict) and "properties" in base.keys():
|
||||
new_objects.extend(
|
||||
get_speckle_subobjects(base["properties"], scale, base["id"])
|
||||
)
|
||||
|
||||
#NOTE: this code is ancient, and in testing does nothing, so we are removing it.
|
||||
# if hasattr(base, "properties") and base.properties is not None:
|
||||
# new_objects.extend(get_speckle_subobjects(base.properties, scale, base.id))
|
||||
# elif isinstance(base, dict) and "properties" in base.keys():
|
||||
# new_objects.extend(
|
||||
# get_speckle_subobjects(base["properties"], scale, base["id"])
|
||||
# )
|
||||
|
||||
"""
|
||||
Set object Speckle settings
|
||||
"""
|
||||
@@ -201,11 +205,11 @@ def base_to_native(context: bpy.types.Context,
|
||||
Run injected function
|
||||
"""
|
||||
if func:
|
||||
new_object = func(context, new_object, base) #this base object isn't the right one for hosted elements!
|
||||
new_object = func(context, new_object, base) #this base object isn't always the right one for hosted elements! #TODO: may be it now, need to double check!
|
||||
|
||||
if (
|
||||
new_object is None
|
||||
): # Make sure that the injected function returned an object
|
||||
): # If the injected function returned None, then we should ignore this object.
|
||||
_report(f"Script '{func.__module__}' returned None.")
|
||||
continue
|
||||
|
||||
@@ -218,8 +222,9 @@ def base_to_native(context: bpy.types.Context,
|
||||
new_object.name = name
|
||||
col.objects.unlink(existing[new_object.speckle.object_id])
|
||||
|
||||
if new_object.name not in col.objects:
|
||||
col.objects.link(new_object)
|
||||
link_object_to_collection_nested(new_object, col)
|
||||
#if new_object.name not in col.objects:
|
||||
#col.objects.link(new_object)
|
||||
|
||||
|
||||
def create_collection(name: str, clear_collection=True) -> bpy.types.Collection:
|
||||
@@ -246,7 +251,7 @@ def get_existing_collection_objs(col: bpy.types.Collection) -> Dict[str, bpy.typ
|
||||
}
|
||||
|
||||
|
||||
def get_collection_parents(collection, names):
|
||||
def get_collection_parents(collection: bpy.types.Collection, names: list[str]) -> None:
|
||||
for parent in bpy.data.collections:
|
||||
if collection.name in parent.children.keys():
|
||||
# TODO: this should be rethought to make it clear when this is an IFC delim so we know to replace it
|
||||
@@ -255,7 +260,7 @@ def get_collection_parents(collection, names):
|
||||
get_collection_parents(parent, names)
|
||||
|
||||
|
||||
def get_collection_hierarchy(collection):
|
||||
def get_collection_hierarchy(collection: Optional[bpy.types.Collection]) -> list[str]:
|
||||
if not collection:
|
||||
return []
|
||||
names = [collection.name.replace("/", "::").replace(".", "::")]
|
||||
@@ -264,7 +269,7 @@ def get_collection_hierarchy(collection):
|
||||
return names
|
||||
|
||||
|
||||
def create_nested_hierarchy(base, hierarchy, objects):
|
||||
def create_nested_hierarchy(base: Base, hierarchy: List[str], objects: Any):
|
||||
child = base
|
||||
|
||||
while hierarchy:
|
||||
@@ -274,13 +279,23 @@ def create_nested_hierarchy(base, hierarchy, objects):
|
||||
child.add_detachable_attrs({name})
|
||||
child = child[name]
|
||||
|
||||
# TODO: what do we call this attribute?
|
||||
if not hasattr(child, "@objects"):
|
||||
child["@objects"] = []
|
||||
child["@objects"].extend(objects)
|
||||
if not hasattr(child, "@elements"):
|
||||
child["@elements"] = []
|
||||
child["@elements"].extend(objects)
|
||||
|
||||
return base
|
||||
|
||||
#RECEIVE_MODES = [#TODO: modes
|
||||
# ("create", "Create", "Add new geometry, without removing any existing objects"),
|
||||
# ("replace", "Replace", "Replace objects from previous receive operations from the same stream"),
|
||||
# #("update","Update", "") #TODO: update mode!
|
||||
#]
|
||||
|
||||
INSTANCES_SETTINGS = [
|
||||
("collection_instance", "Collection Instace", "Receive Instances as Collection Instances"),
|
||||
("linked_duplicates", "Linked Duplicates", "Receive Instances as Linked Duplicates"),
|
||||
]
|
||||
|
||||
class ReceiveStreamObjects(bpy.types.Operator):
|
||||
"""
|
||||
Receive stream objects
|
||||
@@ -294,10 +309,16 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
|
||||
clean_meshes: BoolProperty(name="Clean Meshes", default=False)
|
||||
|
||||
#receive_mode: EnumProperty(items=RECEIVE_MODES, name="Receive Type", default="replace", description="The behaviour of the recieve operation")
|
||||
receive_instances_as: EnumProperty(items=INSTANCES_SETTINGS, name="Receive Instances As", default="collection_instance", description="How to receive speckle Instances")
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.prop(self, "clean_meshes")
|
||||
#col.prop(self, "receive_mode")
|
||||
col.prop(self, "receive_instances_as")
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
@@ -333,30 +354,31 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
bpy.context.view_layer.objects.active = None
|
||||
|
||||
check = _check_speckle_client_user_stream(context.scene)
|
||||
if check is None:
|
||||
speckle: SpeckleSceneSettings = context.scene.speckle
|
||||
|
||||
#Get UI Selection
|
||||
user = speckle.get_active_user()
|
||||
if not user:
|
||||
print("No user selected/found")
|
||||
return {"CANCELLED"}
|
||||
|
||||
user, bstream = check
|
||||
|
||||
client = speckle_clients[int(context.scene.speckle.active_user)]
|
||||
|
||||
stream = client.stream.get(id=bstream.id, branch_limit=20)
|
||||
if stream.branches.totalCount < 1:
|
||||
stream = user.get_active_stream()
|
||||
if not stream:
|
||||
print("No stream selected/found")
|
||||
return {"CANCELLED"}
|
||||
|
||||
if not stream.branches:
|
||||
branch = stream.get_active_branch()
|
||||
if not branch:
|
||||
print("No branch selected/found")
|
||||
return {"CANCELLED"}
|
||||
|
||||
branch = stream.branches.items[int(bstream.branch)]
|
||||
|
||||
bbranch = bstream.branches[int(bstream.branch)]
|
||||
|
||||
if branch.commits.totalCount < 1:
|
||||
_report("No commits found. Probably an empty stream.")
|
||||
commit = branch.get_active_commit()
|
||||
if commit is None:
|
||||
print("No commit selected/found")
|
||||
return {"CANCELLED"}
|
||||
|
||||
commit: Commit = branch.commits.items[int(bbranch.commit)]
|
||||
#Get actual stream data
|
||||
client = speckle_clients[int(speckle.active_user)]
|
||||
|
||||
transport = ServerTransport(stream.id, client)
|
||||
|
||||
@@ -364,33 +386,40 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
metrics.RECEIVE,
|
||||
getattr(transport, "account", None),
|
||||
custom_props={
|
||||
"sourceHostApp": host_applications.get_host_app_from_string(commit.sourceApplication).slug,
|
||||
"sourceHostAppVersion": commit.sourceApplication
|
||||
"sourceHostApp": host_applications.get_host_app_from_string(commit.source_application).slug,
|
||||
"sourceHostAppVersion": commit.source_application
|
||||
},
|
||||
)
|
||||
stream_data = operations._untracked_receive(commit.referencedObject, transport)
|
||||
commit_object = operations._untracked_receive(commit.referenced_object, transport)
|
||||
client.commit.received(
|
||||
bstream.id,
|
||||
stream.id,
|
||||
commit.id,
|
||||
source_application="blender",
|
||||
message="received commit from Speckle Blender",
|
||||
)
|
||||
|
||||
context.window_manager.progress_begin(0, stream_data.totalChildrenCount)
|
||||
context.window_manager.progress_begin(0, commit_object.totalChildrenCount or 1)
|
||||
|
||||
set_convert_instances_as(self.receive_instances_as) #HACK: we need a better way to pass settings down to the converter
|
||||
|
||||
"""
|
||||
Create or get Collection for stream objects
|
||||
"""
|
||||
collections = get_objects_collections(stream_data)
|
||||
collections = get_objects_collections(commit_object)
|
||||
|
||||
if not collections:
|
||||
print("Unusual commit structure - did not correctly create collections")
|
||||
return {"CANCELLED"}
|
||||
|
||||
name = "{} [ {} @ {} ]".format(stream.name, branch.name, commit.id)
|
||||
# name = ""
|
||||
# if self.receive_mode == "create":
|
||||
name = "{} [ {} @ {} ]".format(stream.name, branch.name, commit.id) # Matches Rhino "Create" naming
|
||||
# else:
|
||||
# name = stream.name # Doesn't quite match rhino's Update layer naming, but is close enough no?
|
||||
|
||||
col = create_collection(name)
|
||||
col.speckle.stream_id = stream.id
|
||||
col.speckle.units = stream_data.units or "m"
|
||||
col.speckle.units = commit_object.units or "m"
|
||||
|
||||
if col.name not in bpy.context.scene.collection.children:
|
||||
bpy.context.scene.collection.children.link(col)
|
||||
@@ -418,6 +447,7 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
"""
|
||||
Iterate through retrieved resources
|
||||
"""
|
||||
|
||||
bases_to_native(context, collections, scale, stream.id, func)
|
||||
context.window_manager.progress_end()
|
||||
|
||||
@@ -476,10 +506,11 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
check = _check_speckle_client_user_stream(context.scene)
|
||||
if check is None:
|
||||
user, bstream = check
|
||||
|
||||
if user is None:
|
||||
return {"CANCELLED"}
|
||||
|
||||
user, bstream = check
|
||||
stream = user.streams[user.active_stream]
|
||||
branch = stream.branches[int(stream.branch)]
|
||||
|
||||
@@ -558,17 +589,20 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
|
||||
transport = ServerTransport(stream.id, client)
|
||||
|
||||
_report(f"Sending to {stream}")
|
||||
obj_id = operations.send(
|
||||
base,
|
||||
[transport],
|
||||
)
|
||||
client.commit.create(
|
||||
|
||||
commitId = client.commit.create(
|
||||
stream.id,
|
||||
obj_id,
|
||||
branch.name,
|
||||
message=self.commit_message,
|
||||
source_application="blender",
|
||||
)
|
||||
_report(f"Commit Created {user.server_url}/streams/{stream.id}/commits/{commitId}")
|
||||
|
||||
bpy.ops.speckle.load_user_streams()
|
||||
|
||||
|
||||
@@ -4,12 +4,35 @@ User account operators
|
||||
import bpy
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.properties.scene import SpeckleSceneSettings
|
||||
from bpy_speckle.properties.scene import SpeckleCommitObject, SpeckleSceneSettings
|
||||
from specklepy.api.client import SpeckleClient
|
||||
from specklepy.api.models import Stream, User
|
||||
from specklepy.api.credentials import get_local_accounts
|
||||
from datetime import datetime
|
||||
|
||||
class ResetUsers(bpy.types.Operator):
|
||||
"""
|
||||
Reset loaded users
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.users_reset"
|
||||
bl_label = "Reset users"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
self.reset_ui(context)
|
||||
|
||||
bpy.context.view_layer.update()
|
||||
if context.area:
|
||||
context.area.tag_redraw()
|
||||
return {"FINISHED"}
|
||||
|
||||
@staticmethod
|
||||
def reset_ui(context: bpy.types.Context):
|
||||
speckle: SpeckleSceneSettings = context.scene.speckle
|
||||
|
||||
speckle.users.clear()
|
||||
speckle_clients.clear()
|
||||
|
||||
class LoadUsers(bpy.types.Operator):
|
||||
"""
|
||||
@@ -24,11 +47,10 @@ class LoadUsers(bpy.types.Operator):
|
||||
|
||||
_report("Loading users...")
|
||||
|
||||
speckle : SpeckleSceneSettings = context.scene.speckle
|
||||
speckle: SpeckleSceneSettings = context.scene.speckle
|
||||
users = speckle.users
|
||||
|
||||
speckle.users.clear()
|
||||
speckle_clients.clear()
|
||||
ResetUsers.reset_ui(context)
|
||||
|
||||
profiles = get_local_accounts()
|
||||
active_user_index = 0
|
||||
@@ -40,13 +62,12 @@ class LoadUsers(bpy.types.Operator):
|
||||
user.name = profile.userInfo.name
|
||||
user.email = profile.userInfo.email
|
||||
user.company = profile.userInfo.company or ""
|
||||
user.authToken = profile.token
|
||||
try:
|
||||
client = SpeckleClient(
|
||||
host=profile.serverInfo.url,
|
||||
use_ssl="https" in profile.serverInfo.url,
|
||||
)
|
||||
client.authenticate(user.authToken)
|
||||
client.authenticate_with_account(profile)
|
||||
speckle_clients.append(client)
|
||||
except Exception as ex:
|
||||
_report(ex)
|
||||
@@ -54,7 +75,7 @@ class LoadUsers(bpy.types.Operator):
|
||||
if profile.isDefault:
|
||||
active_user_index = len(users) - 1
|
||||
|
||||
speckle.active_user_index = int(speckle.active_user) #TODO: what is this?
|
||||
#speckle.active_user_index = int(speckle.active_user) #TODO Wtf is this?
|
||||
speckle.active_user = str(active_user_index)
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
@@ -81,13 +102,14 @@ def add_user_stream(user: User, stream: Stream):
|
||||
continue
|
||||
|
||||
for c in b.commits.items:
|
||||
commit = branch.commits.add()
|
||||
commit: SpeckleCommitObject = branch.commits.add()
|
||||
commit.id = commit.name = c.id
|
||||
commit.message = c.message or ""
|
||||
commit.author_name = c.authorName
|
||||
commit.author_id = c.authorId
|
||||
commit.created_at = datetime.strftime(c.createdAt, "%Y-%m-%d %H:%M:%S.%f%Z")
|
||||
commit.source_application = str(c.sourceApplication)
|
||||
commit.referenced_object = c.referencedObject
|
||||
|
||||
if hasattr(s, "baseProperties"):
|
||||
s.units = stream.baseProperties.units
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Scene properties
|
||||
"""
|
||||
from typing import Optional
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
@@ -18,12 +19,13 @@ class SpeckleSceneObject(bpy.types.PropertyGroup):
|
||||
|
||||
|
||||
class SpeckleCommitObject(bpy.types.PropertyGroup):
|
||||
id: StringProperty(default="abc")
|
||||
message: StringProperty(default="A simple commit")
|
||||
author_name: StringProperty(default="Author name")
|
||||
author_id: StringProperty(default="Author ID")
|
||||
created_at: StringProperty(default="Today")
|
||||
source_application: StringProperty(default="Unknown")
|
||||
id: StringProperty(default="")
|
||||
message: StringProperty(default="")
|
||||
author_name: StringProperty(default="")
|
||||
author_id: StringProperty(default="")
|
||||
created_at: StringProperty(default="")
|
||||
source_application: StringProperty(default="")
|
||||
referenced_object: StringProperty(default="")
|
||||
|
||||
|
||||
class SpeckleBranchObject(bpy.types.PropertyGroup):
|
||||
@@ -42,6 +44,12 @@ class SpeckleBranchObject(bpy.types.PropertyGroup):
|
||||
description="Active commit",
|
||||
items=get_commits,
|
||||
)
|
||||
|
||||
def get_active_commit(self) -> Optional[SpeckleCommitObject]:
|
||||
selected_index = int(self.commit)
|
||||
if 0 <= selected_index < len(self.commits):
|
||||
return self.commits[selected_index]
|
||||
return None
|
||||
|
||||
|
||||
class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
@@ -66,6 +74,12 @@ class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
items=get_branches,
|
||||
)
|
||||
|
||||
def get_active_branch(self) -> Optional[SpeckleBranchObject]:
|
||||
selected_index = int(self.branch)
|
||||
if 0 <= selected_index < len(self.branches):
|
||||
return self.branches[selected_index]
|
||||
return None
|
||||
|
||||
|
||||
class SpeckleUserObject(bpy.types.PropertyGroup):
|
||||
server_name: StringProperty(default="SpeckleXYZ")
|
||||
@@ -73,10 +87,14 @@ class SpeckleUserObject(bpy.types.PropertyGroup):
|
||||
name: StringProperty(default="Speckle User")
|
||||
email: StringProperty(default="user@speckle.xyz")
|
||||
company: StringProperty(default="SpeckleSystems")
|
||||
authToken: StringProperty(default="", subtype='PASSWORD')
|
||||
streams: CollectionProperty(type=SpeckleStreamObject)
|
||||
active_stream: IntProperty(default=0)
|
||||
|
||||
def get_active_stream(self) -> Optional[SpeckleStreamObject]:
|
||||
selected_index = int(self.active_stream)
|
||||
if 0 <= selected_index < len(self.streams):
|
||||
return self.streams[selected_index]
|
||||
return None
|
||||
|
||||
class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
def get_scripts(self, context):
|
||||
@@ -104,8 +122,8 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
|
||||
active_user: EnumProperty(
|
||||
items=get_users,
|
||||
name="User",
|
||||
description="Select user",
|
||||
name="Account",
|
||||
description="Select account",
|
||||
update=set_user,
|
||||
get=None,
|
||||
set=None,
|
||||
@@ -132,3 +150,9 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
description="Script to run when sending stream objects.",
|
||||
items=get_scripts,
|
||||
)
|
||||
|
||||
def get_active_user(self) -> Optional[SpeckleUserObject]:
|
||||
selected_index = int(self.active_user)
|
||||
if 0 < selected_index < len(self.users):
|
||||
return self.users[selected_index]
|
||||
return None
|
||||
|
||||
@@ -115,7 +115,7 @@ class VIEW3D_PT_SpeckleUser(bpy.types.Panel):
|
||||
col = layout.column()
|
||||
|
||||
if len(speckle.users) < 1:
|
||||
col.label(text="No users found.")
|
||||
col.label(text="Refresh to initialise")
|
||||
else:
|
||||
col.prop(speckle, "active_user", text="")
|
||||
user = speckle.users[int(speckle.active_user)]
|
||||
|
||||
Generated
+259
-261
@@ -8,7 +8,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "2.13.2"
|
||||
version = "2.15.0"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -16,7 +16,7 @@ python-versions = ">=3.7.2"
|
||||
|
||||
[package.dependencies]
|
||||
lazy-object-proxy = ">=1.4.0"
|
||||
typing-extensions = ">=4.0.0"
|
||||
typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""}
|
||||
wrapt = [
|
||||
{version = ">=1.11,<2", markers = "python_version < \"3.11\""},
|
||||
{version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
|
||||
@@ -62,11 +62,11 @@ python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.0.1"
|
||||
version = "3.1.0"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
@@ -114,7 +114,7 @@ graph = ["objgraph (>=1.7.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "fake-bpy-module-latest"
|
||||
version = "20221006"
|
||||
version = "20230117"
|
||||
description = "Collection of the fake Blender Python API module for the code completion."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -165,15 +165,15 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "5.11.4"
|
||||
version = "5.12.0"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
python-versions = ">=3.8.0"
|
||||
|
||||
[package.extras]
|
||||
colors = ["colorama (>=0.4.3,<0.5.0)"]
|
||||
pipfile-deprecated-finder = ["pipreqs", "requirementslib"]
|
||||
colors = ["colorama (>=0.4.3)"]
|
||||
pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
|
||||
plugins = ["setuptools"]
|
||||
requirements-deprecated-finder = ["pip-api", "pipreqs"]
|
||||
|
||||
@@ -203,15 +203,15 @@ python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "0.4.3"
|
||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.24.1"
|
||||
version = "1.24.2"
|
||||
description = "Fundamental package for array computing in Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -219,7 +219,7 @@ python-versions = ">=3.8"
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.10.3"
|
||||
version = "0.11.1"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -227,19 +227,19 @@ python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.6.2"
|
||||
version = "3.1.1"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
|
||||
docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "1.10.4"
|
||||
version = "1.10.6"
|
||||
description = "Data validation and settings management using python type hints"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -254,14 +254,14 @@ email = ["email-validator (>=1.0.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pylint"
|
||||
version = "2.15.10"
|
||||
version = "2.17.0"
|
||||
description = "python code static checker"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.2"
|
||||
|
||||
[package.dependencies]
|
||||
astroid = ">=2.12.13,<=2.14.0-dev0"
|
||||
astroid = ">=2.15.0,<=2.17.0-dev0"
|
||||
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
|
||||
dill = [
|
||||
{version = ">=0.2", markers = "python_version < \"3.11\""},
|
||||
@@ -317,7 +317,7 @@ python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "specklepy"
|
||||
version = "2.11.4"
|
||||
version = "2.13.0"
|
||||
description = "The Python SDK for Speckle 2.0"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -357,7 +357,7 @@ python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.4.0"
|
||||
version = "4.5.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -373,7 +373,7 @@ python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.26.14"
|
||||
version = "1.26.15"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -394,7 +394,7 @@ python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "wrapt"
|
||||
version = "1.14.1"
|
||||
version = "1.15.0"
|
||||
description = "Module for decorators, wrappers and monkey patching."
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -415,7 +415,7 @@ multidict = ">=4.0"
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = ">=3.8, <4.0.0"
|
||||
content-hash = "3f076527ffe644678e70b173cb65154c053f7abd0b69c6e763a741cb73dd81ed"
|
||||
content-hash = "1c637a755112bbd1507a8bb66b1ba006ec6ff797000dc41329d9e80514d52474"
|
||||
|
||||
[metadata.files]
|
||||
appdirs = [
|
||||
@@ -423,8 +423,8 @@ appdirs = [
|
||||
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
|
||||
]
|
||||
astroid = [
|
||||
{file = "astroid-2.13.2-py3-none-any.whl", hash = "sha256:8f6a8d40c4ad161d6fc419545ae4b2f275ed86d1c989c97825772120842ee0d2"},
|
||||
{file = "astroid-2.13.2.tar.gz", hash = "sha256:3bc7834720e1a24ca797fd785d77efb14f7a28ee8e635ef040b6e2d80ccb3303"},
|
||||
{file = "astroid-2.15.0-py3-none-any.whl", hash = "sha256:e3e4d0ffc2d15d954065579689c36aac57a339a4679a679579af6401db4d3fdb"},
|
||||
{file = "astroid-2.15.0.tar.gz", hash = "sha256:525f126d5dc1b8b0b6ee398b33159105615d92dc4a17f2cd064125d57f6186fa"},
|
||||
]
|
||||
backoff = [
|
||||
{file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"},
|
||||
@@ -449,94 +449,81 @@ certifi = [
|
||||
{file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
|
||||
]
|
||||
charset-normalizer = [
|
||||
{file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"},
|
||||
{file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"},
|
||||
{file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
|
||||
{file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
|
||||
]
|
||||
click = [
|
||||
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
|
||||
@@ -555,8 +542,8 @@ dill = [
|
||||
{file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"},
|
||||
]
|
||||
fake-bpy-module-latest = [
|
||||
{file = "fake-bpy-module-latest-20221006.tar.gz", hash = "sha256:26513339e36b976ae3a7540e3f9ef5130f29eb262114591c643bae5ddeb58647"},
|
||||
{file = "fake_bpy_module_latest-20221006-py3-none-any.whl", hash = "sha256:76b6b52dff83827605ae93ad579712ca100c7d18f13eb00d26933ac24a6610e8"},
|
||||
{file = "fake-bpy-module-latest-20230117.tar.gz", hash = "sha256:b58957036fe5573b2374a159aeb7a4cbd92255f447e55a49e16ff7c06850cdd1"},
|
||||
{file = "fake_bpy_module_latest-20230117-py3-none-any.whl", hash = "sha256:73613c27418446bc2942baed6220f8ac4ddde694a3712dd595aa97f902a79242"},
|
||||
]
|
||||
gql = [
|
||||
{file = "gql-3.4.0-py2.py3-none-any.whl", hash = "sha256:59c8a0b8f0a2f3b0b2ff970c94de86f82f65cb1da3340bfe57143e5f7ea82f71"},
|
||||
@@ -571,8 +558,8 @@ idna = [
|
||||
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
|
||||
]
|
||||
isort = [
|
||||
{file = "isort-5.11.4-py3-none-any.whl", hash = "sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b"},
|
||||
{file = "isort-5.11.4.tar.gz", hash = "sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6"},
|
||||
{file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"},
|
||||
{file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"},
|
||||
]
|
||||
lazy-object-proxy = [
|
||||
{file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"},
|
||||
@@ -693,88 +680,88 @@ multidict = [
|
||||
{file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
|
||||
]
|
||||
mypy-extensions = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
numpy = [
|
||||
{file = "numpy-1.24.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:179a7ef0889ab769cc03573b6217f54c8bd8e16cef80aad369e1e8185f994cd7"},
|
||||
{file = "numpy-1.24.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b09804ff570b907da323b3d762e74432fb07955701b17b08ff1b5ebaa8cfe6a9"},
|
||||
{file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1b739841821968798947d3afcefd386fa56da0caf97722a5de53e07c4ccedc7"},
|
||||
{file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e3463e6ac25313462e04aea3fb8a0a30fb906d5d300f58b3bc2c23da6a15398"},
|
||||
{file = "numpy-1.24.1-cp310-cp310-win32.whl", hash = "sha256:b31da69ed0c18be8b77bfce48d234e55d040793cebb25398e2a7d84199fbc7e2"},
|
||||
{file = "numpy-1.24.1-cp310-cp310-win_amd64.whl", hash = "sha256:b07b40f5fb4fa034120a5796288f24c1fe0e0580bbfff99897ba6267af42def2"},
|
||||
{file = "numpy-1.24.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7094891dcf79ccc6bc2a1f30428fa5edb1e6fb955411ffff3401fb4ea93780a8"},
|
||||
{file = "numpy-1.24.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28e418681372520c992805bb723e29d69d6b7aa411065f48216d8329d02ba032"},
|
||||
{file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e274f0f6c7efd0d577744f52032fdd24344f11c5ae668fe8d01aac0422611df1"},
|
||||
{file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0044f7d944ee882400890f9ae955220d29b33d809a038923d88e4e01d652acd9"},
|
||||
{file = "numpy-1.24.1-cp311-cp311-win32.whl", hash = "sha256:442feb5e5bada8408e8fcd43f3360b78683ff12a4444670a7d9e9824c1817d36"},
|
||||
{file = "numpy-1.24.1-cp311-cp311-win_amd64.whl", hash = "sha256:de92efa737875329b052982e37bd4371d52cabf469f83e7b8be9bb7752d67e51"},
|
||||
{file = "numpy-1.24.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b162ac10ca38850510caf8ea33f89edcb7b0bb0dfa5592d59909419986b72407"},
|
||||
{file = "numpy-1.24.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26089487086f2648944f17adaa1a97ca6aee57f513ba5f1c0b7ebdabbe2b9954"},
|
||||
{file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caf65a396c0d1f9809596be2e444e3bd4190d86d5c1ce21f5fc4be60a3bc5b36"},
|
||||
{file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0677a52f5d896e84414761531947c7a330d1adc07c3a4372262f25d84af7bf7"},
|
||||
{file = "numpy-1.24.1-cp38-cp38-win32.whl", hash = "sha256:dae46bed2cb79a58d6496ff6d8da1e3b95ba09afeca2e277628171ca99b99db1"},
|
||||
{file = "numpy-1.24.1-cp38-cp38-win_amd64.whl", hash = "sha256:6ec0c021cd9fe732e5bab6401adea5a409214ca5592cd92a114f7067febcba0c"},
|
||||
{file = "numpy-1.24.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28bc9750ae1f75264ee0f10561709b1462d450a4808cd97c013046073ae64ab6"},
|
||||
{file = "numpy-1.24.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84e789a085aabef2f36c0515f45e459f02f570c4b4c4c108ac1179c34d475ed7"},
|
||||
{file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e669fbdcdd1e945691079c2cae335f3e3a56554e06bbd45d7609a6cf568c700"},
|
||||
{file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef85cf1f693c88c1fd229ccd1055570cb41cdf4875873b7728b6301f12cd05bf"},
|
||||
{file = "numpy-1.24.1-cp39-cp39-win32.whl", hash = "sha256:87a118968fba001b248aac90e502c0b13606721b1343cdaddbc6e552e8dfb56f"},
|
||||
{file = "numpy-1.24.1-cp39-cp39-win_amd64.whl", hash = "sha256:ddc7ab52b322eb1e40521eb422c4e0a20716c271a306860979d450decbb51b8e"},
|
||||
{file = "numpy-1.24.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed5fb71d79e771ec930566fae9c02626b939e37271ec285e9efaf1b5d4370e7d"},
|
||||
{file = "numpy-1.24.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad2925567f43643f51255220424c23d204024ed428afc5aad0f86f3ffc080086"},
|
||||
{file = "numpy-1.24.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cfa1161c6ac8f92dea03d625c2d0c05e084668f4a06568b77a25a89111621566"},
|
||||
{file = "numpy-1.24.1.tar.gz", hash = "sha256:2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2"},
|
||||
{file = "numpy-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eef70b4fc1e872ebddc38cddacc87c19a3709c0e3e5d20bf3954c147b1dd941d"},
|
||||
{file = "numpy-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d2859428712785e8a8b7d2b3ef0a1d1565892367b32f915c4a4df44d0e64f5"},
|
||||
{file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6524630f71631be2dabe0c541e7675db82651eb998496bbe16bc4f77f0772253"},
|
||||
{file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51725a815a6188c662fb66fb32077709a9ca38053f0274640293a14fdd22978"},
|
||||
{file = "numpy-1.24.2-cp310-cp310-win32.whl", hash = "sha256:2620e8592136e073bd12ee4536149380695fbe9ebeae845b81237f986479ffc9"},
|
||||
{file = "numpy-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:97cf27e51fa078078c649a51d7ade3c92d9e709ba2bfb97493007103c741f1d0"},
|
||||
{file = "numpy-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7de8fdde0003f4294655aa5d5f0a89c26b9f22c0a58790c38fae1ed392d44a5a"},
|
||||
{file = "numpy-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4173bde9fa2a005c2c6e2ea8ac1618e2ed2c1c6ec8a7657237854d42094123a0"},
|
||||
{file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cecaed30dc14123020f77b03601559fff3e6cd0c048f8b5289f4eeabb0eb281"},
|
||||
{file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a23f8440561a633204a67fb44617ce2a299beecf3295f0d13c495518908e910"},
|
||||
{file = "numpy-1.24.2-cp311-cp311-win32.whl", hash = "sha256:e428c4fbfa085f947b536706a2fc349245d7baa8334f0c5723c56a10595f9b95"},
|
||||
{file = "numpy-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:557d42778a6869c2162deb40ad82612645e21d79e11c1dc62c6e82a2220ffb04"},
|
||||
{file = "numpy-1.24.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d0a2db9d20117bf523dde15858398e7c0858aadca7c0f088ac0d6edd360e9ad2"},
|
||||
{file = "numpy-1.24.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c72a6b2f4af1adfe193f7beb91ddf708ff867a3f977ef2ec53c0ffb8283ab9f5"},
|
||||
{file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29e6bd0ec49a44d7690ecb623a8eac5ab8a923bce0bea6293953992edf3a76a"},
|
||||
{file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eabd64ddb96a1239791da78fa5f4e1693ae2dadc82a76bc76a14cbb2b966e96"},
|
||||
{file = "numpy-1.24.2-cp38-cp38-win32.whl", hash = "sha256:e3ab5d32784e843fc0dd3ab6dcafc67ef806e6b6828dc6af2f689be0eb4d781d"},
|
||||
{file = "numpy-1.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:76807b4063f0002c8532cfeac47a3068a69561e9c8715efdad3c642eb27c0756"},
|
||||
{file = "numpy-1.24.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4199e7cfc307a778f72d293372736223e39ec9ac096ff0a2e64853b866a8e18a"},
|
||||
{file = "numpy-1.24.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adbdce121896fd3a17a77ab0b0b5eedf05a9834a18699db6829a64e1dfccca7f"},
|
||||
{file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:889b2cc88b837d86eda1b17008ebeb679d82875022200c6e8e4ce6cf549b7acb"},
|
||||
{file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f64bb98ac59b3ea3bf74b02f13836eb2e24e48e0ab0145bbda646295769bd780"},
|
||||
{file = "numpy-1.24.2-cp39-cp39-win32.whl", hash = "sha256:63e45511ee4d9d976637d11e6c9864eae50e12dc9598f531c035265991910468"},
|
||||
{file = "numpy-1.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:a77d3e1163a7770164404607b7ba3967fb49b24782a6ef85d9b5f54126cc39e5"},
|
||||
{file = "numpy-1.24.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92011118955724465fb6853def593cf397b4a1367495e0b59a7e69d40c4eb71d"},
|
||||
{file = "numpy-1.24.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9006288bcf4895917d02583cf3411f98631275bc67cce355a7f39f8c14338fa"},
|
||||
{file = "numpy-1.24.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:150947adbdfeceec4e5926d956a06865c1c690f2fd902efede4ca6fe2e657c3f"},
|
||||
{file = "numpy-1.24.2.tar.gz", hash = "sha256:003a9f530e880cb2cd177cba1af7220b9aa42def9c4afc2a2fc3ee6be7eb2b22"},
|
||||
]
|
||||
pathspec = [
|
||||
{file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"},
|
||||
{file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"},
|
||||
{file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"},
|
||||
{file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"},
|
||||
{file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"},
|
||||
{file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"},
|
||||
{file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"},
|
||||
]
|
||||
pydantic = [
|
||||
{file = "pydantic-1.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5635de53e6686fe7a44b5cf25fcc419a0d5e5c1a1efe73d49d48fe7586db854"},
|
||||
{file = "pydantic-1.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6dc1cc241440ed7ca9ab59d9929075445da6b7c94ced281b3dd4cfe6c8cff817"},
|
||||
{file = "pydantic-1.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51bdeb10d2db0f288e71d49c9cefa609bca271720ecd0c58009bd7504a0c464c"},
|
||||
{file = "pydantic-1.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78cec42b95dbb500a1f7120bdf95c401f6abb616bbe8785ef09887306792e66e"},
|
||||
{file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8775d4ef5e7299a2f4699501077a0defdaac5b6c4321173bcb0f3c496fbadf85"},
|
||||
{file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:572066051eeac73d23f95ba9a71349c42a3e05999d0ee1572b7860235b850cc6"},
|
||||
{file = "pydantic-1.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:7feb6a2d401f4d6863050f58325b8d99c1e56f4512d98b11ac64ad1751dc647d"},
|
||||
{file = "pydantic-1.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39f4a73e5342b25c2959529f07f026ef58147249f9b7431e1ba8414a36761f53"},
|
||||
{file = "pydantic-1.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:983e720704431a6573d626b00662eb78a07148c9115129f9b4351091ec95ecc3"},
|
||||
{file = "pydantic-1.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d52162fe6b2b55964fbb0af2ee58e99791a3138588c482572bb6087953113a"},
|
||||
{file = "pydantic-1.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdf8d759ef326962b4678d89e275ffc55b7ce59d917d9f72233762061fd04a2d"},
|
||||
{file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05a81b006be15655b2a1bae5faa4280cf7c81d0e09fcb49b342ebf826abe5a72"},
|
||||
{file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d88c4c0e5c5dfd05092a4b271282ef0588e5f4aaf345778056fc5259ba098857"},
|
||||
{file = "pydantic-1.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:6a05a9db1ef5be0fe63e988f9617ca2551013f55000289c671f71ec16f4985e3"},
|
||||
{file = "pydantic-1.10.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:887ca463c3bc47103c123bc06919c86720e80e1214aab79e9b779cda0ff92a00"},
|
||||
{file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdf88ab63c3ee282c76d652fc86518aacb737ff35796023fae56a65ced1a5978"},
|
||||
{file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a48f1953c4a1d9bd0b5167ac50da9a79f6072c63c4cef4cf2a3736994903583e"},
|
||||
{file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a9f2de23bec87ff306aef658384b02aa7c32389766af3c5dee9ce33e80222dfa"},
|
||||
{file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cd8702c5142afda03dc2b1ee6bc358b62b3735b2cce53fc77b31ca9f728e4bc8"},
|
||||
{file = "pydantic-1.10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6e7124d6855b2780611d9f5e1e145e86667eaa3bd9459192c8dc1a097f5e9903"},
|
||||
{file = "pydantic-1.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b53e1d41e97063d51a02821b80538053ee4608b9a181c1005441f1673c55423"},
|
||||
{file = "pydantic-1.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:55b1625899acd33229c4352ce0ae54038529b412bd51c4915349b49ca575258f"},
|
||||
{file = "pydantic-1.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:301d626a59edbe5dfb48fcae245896379a450d04baeed50ef40d8199f2733b06"},
|
||||
{file = "pydantic-1.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6f9d649892a6f54a39ed56b8dfd5e08b5f3be5f893da430bed76975f3735d15"},
|
||||
{file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7b5a3821225f5c43496c324b0d6875fde910a1c2933d726a743ce328fbb2a8c"},
|
||||
{file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f2f7eb6273dd12472d7f218e1fef6f7c7c2f00ac2e1ecde4db8824c457300416"},
|
||||
{file = "pydantic-1.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:4b05697738e7d2040696b0a66d9f0a10bec0efa1883ca75ee9e55baf511909d6"},
|
||||
{file = "pydantic-1.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a9a6747cac06c2beb466064dda999a13176b23535e4c496c9d48e6406f92d42d"},
|
||||
{file = "pydantic-1.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb992a1ef739cc7b543576337bebfc62c0e6567434e522e97291b251a41dad7f"},
|
||||
{file = "pydantic-1.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:990406d226dea0e8f25f643b370224771878142155b879784ce89f633541a024"},
|
||||
{file = "pydantic-1.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e82a6d37a95e0b1b42b82ab340ada3963aea1317fd7f888bb6b9dfbf4fff57c"},
|
||||
{file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9193d4f4ee8feca58bc56c8306bcb820f5c7905fd919e0750acdeeeef0615b28"},
|
||||
{file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2b3ce5f16deb45c472dde1a0ee05619298c864a20cded09c4edd820e1454129f"},
|
||||
{file = "pydantic-1.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9cbdc268a62d9a98c56e2452d6c41c0263d64a2009aac69246486f01b4f594c4"},
|
||||
{file = "pydantic-1.10.4-py3-none-any.whl", hash = "sha256:4948f264678c703f3877d1c8877c4e3b2e12e549c57795107f08cf70c6ec7774"},
|
||||
{file = "pydantic-1.10.4.tar.gz", hash = "sha256:b9a3859f24eb4e097502a3be1fb4b2abb79b6103dd9e2e0edb70613a4459a648"},
|
||||
{file = "pydantic-1.10.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9289065611c48147c1dd1fd344e9d57ab45f1d99b0fb26c51f1cf72cd9bcd31"},
|
||||
{file = "pydantic-1.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c32b6bba301490d9bb2bf5f631907803135e8085b6aa3e5fe5a770d46dd0160"},
|
||||
{file = "pydantic-1.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd9b9e98068fa1068edfc9eabde70a7132017bdd4f362f8b4fd0abed79c33083"},
|
||||
{file = "pydantic-1.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c84583b9df62522829cbc46e2b22e0ec11445625b5acd70c5681ce09c9b11c4"},
|
||||
{file = "pydantic-1.10.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b41822064585fea56d0116aa431fbd5137ce69dfe837b599e310034171996084"},
|
||||
{file = "pydantic-1.10.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61f1f08adfaa9cc02e0cbc94f478140385cbd52d5b3c5a657c2fceb15de8d1fb"},
|
||||
{file = "pydantic-1.10.6-cp310-cp310-win_amd64.whl", hash = "sha256:32937835e525d92c98a1512218db4eed9ddc8f4ee2a78382d77f54341972c0e7"},
|
||||
{file = "pydantic-1.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbd5c531b22928e63d0cb1868dee76123456e1de2f1cb45879e9e7a3f3f1779b"},
|
||||
{file = "pydantic-1.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e277bd18339177daa62a294256869bbe84df1fb592be2716ec62627bb8d7c81d"},
|
||||
{file = "pydantic-1.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f15277d720aa57e173954d237628a8d304896364b9de745dcb722f584812c7"},
|
||||
{file = "pydantic-1.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b243b564cea2576725e77aeeda54e3e0229a168bc587d536cd69941e6797543d"},
|
||||
{file = "pydantic-1.10.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3ce13a558b484c9ae48a6a7c184b1ba0e5588c5525482681db418268e5f86186"},
|
||||
{file = "pydantic-1.10.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3ac1cd4deed871dfe0c5f63721e29debf03e2deefa41b3ed5eb5f5df287c7b70"},
|
||||
{file = "pydantic-1.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:b1eb6610330a1dfba9ce142ada792f26bbef1255b75f538196a39e9e90388bf4"},
|
||||
{file = "pydantic-1.10.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4ca83739c1263a044ec8b79df4eefc34bbac87191f0a513d00dd47d46e307a65"},
|
||||
{file = "pydantic-1.10.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea4e2a7cb409951988e79a469f609bba998a576e6d7b9791ae5d1e0619e1c0f2"},
|
||||
{file = "pydantic-1.10.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53de12b4608290992a943801d7756f18a37b7aee284b9ffa794ee8ea8153f8e2"},
|
||||
{file = "pydantic-1.10.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:60184e80aac3b56933c71c48d6181e630b0fbc61ae455a63322a66a23c14731a"},
|
||||
{file = "pydantic-1.10.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:415a3f719ce518e95a92effc7ee30118a25c3d032455d13e121e3840985f2efd"},
|
||||
{file = "pydantic-1.10.6-cp37-cp37m-win_amd64.whl", hash = "sha256:72cb30894a34d3a7ab6d959b45a70abac8a2a93b6480fc5a7bfbd9c935bdc4fb"},
|
||||
{file = "pydantic-1.10.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3091d2eaeda25391405e36c2fc2ed102b48bac4b384d42b2267310abae350ca6"},
|
||||
{file = "pydantic-1.10.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:751f008cd2afe812a781fd6aa2fb66c620ca2e1a13b6a2152b1ad51553cb4b77"},
|
||||
{file = "pydantic-1.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12e837fd320dd30bd625be1b101e3b62edc096a49835392dcf418f1a5ac2b832"},
|
||||
{file = "pydantic-1.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d92831d0115874d766b1f5fddcdde0c5b6c60f8c6111a394078ec227fca6d"},
|
||||
{file = "pydantic-1.10.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:476f6674303ae7965730a382a8e8d7fae18b8004b7b69a56c3d8fa93968aa21c"},
|
||||
{file = "pydantic-1.10.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3a2be0a0f32c83265fd71a45027201e1278beaa82ea88ea5b345eea6afa9ac7f"},
|
||||
{file = "pydantic-1.10.6-cp38-cp38-win_amd64.whl", hash = "sha256:0abd9c60eee6201b853b6c4be104edfba4f8f6c5f3623f8e1dba90634d63eb35"},
|
||||
{file = "pydantic-1.10.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6195ca908045054dd2d57eb9c39a5fe86409968b8040de8c2240186da0769da7"},
|
||||
{file = "pydantic-1.10.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43cdeca8d30de9a897440e3fb8866f827c4c31f6c73838e3a01a14b03b067b1d"},
|
||||
{file = "pydantic-1.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c19eb5163167489cb1e0161ae9220dadd4fc609a42649e7e84a8fa8fff7a80f"},
|
||||
{file = "pydantic-1.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:012c99a9c0d18cfde7469aa1ebff922e24b0c706d03ead96940f5465f2c9cf62"},
|
||||
{file = "pydantic-1.10.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:528dcf7ec49fb5a84bf6fe346c1cc3c55b0e7603c2123881996ca3ad79db5bfc"},
|
||||
{file = "pydantic-1.10.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:163e79386c3547c49366e959d01e37fc30252285a70619ffc1b10ede4758250a"},
|
||||
{file = "pydantic-1.10.6-cp39-cp39-win_amd64.whl", hash = "sha256:189318051c3d57821f7233ecc94708767dd67687a614a4e8f92b4a020d4ffd06"},
|
||||
{file = "pydantic-1.10.6-py3-none-any.whl", hash = "sha256:acc6783751ac9c9bc4680379edd6d286468a1dc8d7d9906cd6f1186ed682b2b0"},
|
||||
{file = "pydantic-1.10.6.tar.gz", hash = "sha256:cf95adb0d1671fc38d8c43dd921ad5814a735e7d9b4d9e437c088002863854fd"},
|
||||
]
|
||||
pylint = [
|
||||
{file = "pylint-2.15.10-py3-none-any.whl", hash = "sha256:9df0d07e8948a1c3ffa3b6e2d7e6e63d9fb457c5da5b961ed63106594780cc7e"},
|
||||
{file = "pylint-2.15.10.tar.gz", hash = "sha256:b3dc5ef7d33858f297ac0d06cc73862f01e4f2e74025ec3eff347ce0bc60baf5"},
|
||||
{file = "pylint-2.17.0-py3-none-any.whl", hash = "sha256:e097d8325f8c88e14ad12844e3fe2d963d3de871ea9a8f8ad25ab1c109889ddc"},
|
||||
{file = "pylint-2.17.0.tar.gz", hash = "sha256:1460829b6397cb5eb0cdb0b4fc4b556348e515cdca32115f74a1eb7c20b896b4"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
|
||||
@@ -803,8 +790,8 @@ ruff = [
|
||||
{file = "ruff-0.0.166.tar.gz", hash = "sha256:804fa54aa04e0253b2f39a0ce7089359ea6ba2f037f299f5d8606605e5e37bfa"},
|
||||
]
|
||||
specklepy = [
|
||||
{file = "specklepy-2.11.4-py3-none-any.whl", hash = "sha256:cb8481a98c0072c680bb57a59e7381e1d81a9c627d001f53e7ebce7ff4668930"},
|
||||
{file = "specklepy-2.11.4.tar.gz", hash = "sha256:605b07e308b9284cec55c1ac910e4a448009181ed81551a9e8c25a7bbcbb32fa"},
|
||||
{file = "specklepy-2.13.0-py3-none-any.whl", hash = "sha256:7111a30c641f0dd929985c20d4e0bb6c8205c6fb5f591b0acb7e6d7745de6abe"},
|
||||
{file = "specklepy-2.13.0.tar.gz", hash = "sha256:5f3d9b120191b032fdb1c856c5d1b3a7fadb14561fbc46a237dcbf02aad08fea"},
|
||||
]
|
||||
stringcase = [
|
||||
{file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"},
|
||||
@@ -818,8 +805,8 @@ tomlkit = [
|
||||
{file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"},
|
||||
]
|
||||
typing-extensions = [
|
||||
{file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"},
|
||||
{file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"},
|
||||
{file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"},
|
||||
{file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"},
|
||||
]
|
||||
ujson = [
|
||||
{file = "ujson-5.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5eba5e69e4361ac3a311cf44fa71bc619361b6e0626768a494771aacd1c2f09b"},
|
||||
@@ -889,8 +876,8 @@ ujson = [
|
||||
{file = "ujson-5.7.0.tar.gz", hash = "sha256:e788e5d5dcae8f6118ac9b45d0b891a0d55f7ac480eddcb7f07263f2bcf37b23"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"},
|
||||
{file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"},
|
||||
{file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"},
|
||||
{file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"},
|
||||
]
|
||||
websockets = [
|
||||
{file = "websockets-10.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d58804e996d7d2307173d56c297cf7bc132c52df27a3efaac5e8d43e36c21c48"},
|
||||
@@ -964,70 +951,81 @@ websockets = [
|
||||
{file = "websockets-10.4.tar.gz", hash = "sha256:eef610b23933c54d5d921c92578ae5f89813438fded840c2e9809d378dc765d3"},
|
||||
]
|
||||
wrapt = [
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"},
|
||||
{file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"},
|
||||
{file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"},
|
||||
{file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"},
|
||||
{file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"},
|
||||
{file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"},
|
||||
{file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"},
|
||||
{file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"},
|
||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"},
|
||||
{file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"},
|
||||
{file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"},
|
||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"},
|
||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"},
|
||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"},
|
||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"},
|
||||
{file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"},
|
||||
{file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"},
|
||||
{file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"},
|
||||
{file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"},
|
||||
{file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"},
|
||||
{file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"},
|
||||
{file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"},
|
||||
{file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"},
|
||||
]
|
||||
yarl = [
|
||||
{file = "yarl-1.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5"},
|
||||
|
||||
+2
-2
@@ -7,14 +7,14 @@ license = "Apache-2.0"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.8, <4.0.0"
|
||||
specklepy = "^2.11.4"
|
||||
specklepy = "^2.13.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 = "^20221006"
|
||||
fake-bpy-module-latest = "^20230117"
|
||||
black = "^22.10.0"
|
||||
pylint = "^2.15.7"
|
||||
ruff = "^0.0.166"
|
||||
|
||||
Reference in New Issue
Block a user