Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 47258cb7a6 | |||
| b216f95187 | |||
| 695135b655 | |||
| 5f7e47221c | |||
| 38ee1c6ef9 | |||
| d8b3c49dee | |||
| dceec1b061 | |||
| 2071c3f3b4 | |||
| d45419ba5e | |||
| 2c640b7272 | |||
| c00635d093 | |||
| a07d4f0a8e | |||
| 61e721716f | |||
| 91d12b5a6c | |||
| f331846138 | |||
| d350887860 | |||
| 8ad607a8e0 | |||
| 13f242e47f | |||
| 9f55acd02d | |||
| 476f947b68 | |||
| f56dea0a35 | |||
| c8d6b3ebea | |||
| b2e7a899f6 | |||
| ef0f7ef46f | |||
| 8799f52dfb | |||
| 22c1fb4fb2 | |||
| bce03f9e38 |
@@ -1,5 +1,5 @@
|
||||
# SpeckleBlender 2.0
|
||||
Speckle add-on for Blender 2.92
|
||||
Speckle add-on for Blender 2.92 & 2.93
|
||||
|
||||
[](https://twitter.com/SpeckleSystems) [](https://discourse.speckle.works) [](https://speckle.systems) [](https://speckle.guide/dev/)
|
||||
|
||||
@@ -45,7 +45,7 @@ This code is WIP and as such should be used with extreme caution on non-sensitiv
|
||||
## Custom properties
|
||||
|
||||
- **SpeckleBlender** will look for a `texture_coordinates` property and use that to create a UV layer for the imported object. These texture coordinates are a space-separated list of floats (`[u v u v u v etc...]`) that is encoded as a base64 blob. This is subject to change as **SpeckleBlender** develops.
|
||||
- If a `material` property is found, **SpeckleBlender** will create a material named using the sub-property `material.name`. If a material with that name already exists in Blender, **SpeckleBlender** will just assign that existing material to the object. This allows geometry to be updated without having to re-assign and re-create materials.
|
||||
- If a `renderMaterial` property is found, **SpeckleBlender** will create a material named using the sub-property `renderMaterial.name`. If a material with that name already exists in Blender, **SpeckleBlender** will just assign that existing material to the object. This allows geometry to be updated without having to re-assign and re-create materials.
|
||||
- Vertex colors are supported. The `colors` list from Speckle meshes is translated to a vertex color layer.
|
||||
- Speckle properties will be imported as custom properties on Blender objects. Nested dictionaries are expanded to individual properties by flattening their key hierarchy. I.e. `propA:{'propB': {'propC':10, 'propD':'foobar'}}` is flattened to `propA.propB.propC = 10` and `propA.propB.propD = "foobar"`.
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ from mathutils import Matrix
|
||||
from .from_speckle import *
|
||||
from .to_speckle import *
|
||||
from .util import *
|
||||
from bpy_speckle.util import find_key_case_insensitive
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.functions import _report, get_scale_length
|
||||
|
||||
from specklepy.objects.geometry import *
|
||||
from specklepy.objects.other import RenderMaterial
|
||||
|
||||
|
||||
FROM_SPECKLE_SCHEMAS = {
|
||||
Mesh: import_mesh,
|
||||
Brep: import_brep,
|
||||
@@ -21,17 +21,6 @@ FROM_SPECKLE_SCHEMAS = {
|
||||
}
|
||||
|
||||
|
||||
# FROM_SPECKLE = {
|
||||
# "Mesh": import_mesh,
|
||||
# "Brep": import_brep,
|
||||
# "Curve": import_curve,
|
||||
# "Line": import_curve,
|
||||
# "Polyline": import_curve,
|
||||
# "Polycurve":import_curve,
|
||||
# "Arc":import_curve,
|
||||
# }
|
||||
|
||||
|
||||
TO_SPECKLE = {
|
||||
"MESH": export_mesh,
|
||||
"CURVE": export_curve,
|
||||
@@ -60,13 +49,14 @@ def add_blender_material(smesh, blender_object) -> None:
|
||||
if blender_object.data is None:
|
||||
return
|
||||
|
||||
if not hasattr(smesh, "renderMaterial"):
|
||||
if not hasattr(smesh, "renderMaterial") and not hasattr(smesh, "@renderMaterial"):
|
||||
return
|
||||
|
||||
speckle_mat = smesh.renderMaterial
|
||||
mat_name = getattr(speckle_mat, "name", None)
|
||||
speckle_mat = getattr(smesh, "renderMaterial", None) or smesh["@renderMaterial"]
|
||||
mat_name = getattr(speckle_mat, "name", None) or speckle_mat.__dict__.get("@name")
|
||||
if not mat_name:
|
||||
mat_name = speckle_mat.applicationId or speckle_mat.id
|
||||
|
||||
blender_mat = bpy.data.materials.get(mat_name)
|
||||
if not blender_mat:
|
||||
blender_mat = bpy.data.materials.new(mat_name)
|
||||
@@ -146,7 +136,10 @@ def add_custom_properties(speckle_object, blender_object):
|
||||
blender_object["_speckle_type"] = type(speckle_object).__name__
|
||||
# blender_object['_speckle_name'] = "SpeckleObject"
|
||||
|
||||
ignore = ["_chunkable", "_units"]
|
||||
ignore = ["_chunkable", "_units", "units"]
|
||||
|
||||
if hasattr(speckle_object, "applicationId"):
|
||||
blender_object["applicationId"] = speckle_object.applicationId
|
||||
|
||||
for key in speckle_object.get_dynamic_member_names():
|
||||
if key in ignore:
|
||||
@@ -186,6 +179,10 @@ def from_speckle_object(speckle_object, scale, name=None):
|
||||
or speckle_object.speckle_type + f" -- {speckle_object.id}"
|
||||
)
|
||||
|
||||
units = getattr(speckle_object, "units", None)
|
||||
if units:
|
||||
scale = get_scale_length(units) / bpy.context.scene.unit_settings.scale_length
|
||||
|
||||
# try native conversion
|
||||
if type(speckle_object) in FROM_SPECKLE_SCHEMAS.keys():
|
||||
print("Got object type: {}".format(type(speckle_object)))
|
||||
@@ -201,6 +198,7 @@ def from_speckle_object(speckle_object, scale, name=None):
|
||||
if speckle_name in bpy.data.objects.keys():
|
||||
blender_object = bpy.data.objects[speckle_name]
|
||||
blender_object.data = obdata
|
||||
blender_object.matrix_world = Matrix()
|
||||
if hasattr(obdata, "materials"):
|
||||
blender_object.data.materials.clear()
|
||||
else:
|
||||
@@ -278,30 +276,33 @@ def get_blender_custom_properties(obj, max_depth=1000):
|
||||
return obj
|
||||
|
||||
if hasattr(obj, "keys"):
|
||||
d = {}
|
||||
for key in obj.keys():
|
||||
if key in ignored_keys or key.startswith("_"):
|
||||
continue
|
||||
d[key] = get_blender_custom_properties(obj[key], max_depth - 1)
|
||||
return d
|
||||
return {
|
||||
key: get_blender_custom_properties(obj[key], max_depth - 1)
|
||||
for key in obj.keys()
|
||||
if key not in ignored_keys and not key.startswith("_")
|
||||
}
|
||||
|
||||
elif isinstance(obj, (list, tuple, idprop.types.IDPropertyArray)):
|
||||
return [get_blender_custom_properties(o, max_depth - 1) for o in obj]
|
||||
else:
|
||||
return obj
|
||||
|
||||
|
||||
def to_speckle_object(blender_object, scale):
|
||||
def to_speckle_object(blender_object, scale, desgraph=None):
|
||||
blender_type = blender_object.type
|
||||
speckle_objects = []
|
||||
speckle_material = material_to_speckle(blender_object)
|
||||
|
||||
if blender_type in TO_SPECKLE.keys():
|
||||
if desgraph:
|
||||
blender_object = blender_object.evaluated_get(desgraph)
|
||||
converted = TO_SPECKLE[blender_type](blender_object, blender_object.data, scale)
|
||||
if isinstance(converted, list):
|
||||
speckle_objects.extend([c for c in converted if c != None])
|
||||
|
||||
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
|
||||
|
||||
@@ -157,7 +157,7 @@ def import_mesh(speckle_mesh, scale=1.0, name=None):
|
||||
if not name:
|
||||
name = speckle_mesh.geometryHash or speckle_mesh.id
|
||||
|
||||
if name in bpy.data.meshes.keys() and False:
|
||||
if name in bpy.data.meshes.keys():
|
||||
mesh = bpy.data.meshes[name]
|
||||
else:
|
||||
mesh = bpy.data.meshes.new(name=name)
|
||||
|
||||
@@ -2,8 +2,100 @@ import bpy, bmesh, struct
|
||||
from specklepy.objects.geometry import Curve, Interval, Box, Polyline
|
||||
from bpy_speckle.convert.to_speckle.mesh import export_mesh
|
||||
|
||||
UNITS = "m"
|
||||
|
||||
|
||||
def bezier_to_speckle(matrix, spline, scale, name=None):
|
||||
degree = 3
|
||||
closed = spline.use_cyclic_u
|
||||
|
||||
points = []
|
||||
for i, bp in enumerate(spline.bezier_points):
|
||||
if i > 0:
|
||||
points.append(tuple(matrix @ bp.handle_left * scale))
|
||||
points.append(tuple(matrix @ bp.co * scale))
|
||||
if i < len(spline.bezier_points) - 1:
|
||||
points.append(tuple(matrix @ bp.handle_right * scale))
|
||||
|
||||
if closed:
|
||||
points.append(tuple(matrix @ spline.bezier_points[-1].handle_right * scale))
|
||||
points.append(tuple(matrix @ spline.bezier_points[0].handle_left * scale))
|
||||
points.append(tuple(matrix @ spline.bezier_points[0].co * scale))
|
||||
|
||||
num_points = len(points)
|
||||
|
||||
knot_count = num_points + degree - 1
|
||||
knots = [0] * knot_count
|
||||
|
||||
for i in range(1, len(knots)):
|
||||
knots[i] = i // 3
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
return Curve(
|
||||
name=name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[1] * num_points,
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
)
|
||||
|
||||
|
||||
def nurbs_to_speckle(matrix, spline, scale, name=None):
|
||||
knots = makeknots(spline)
|
||||
# print("knots: {}".format(knots))
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
degree = spline.order_u - 1
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
|
||||
return Curve(
|
||||
name=name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[pt.weight for pt in spline.points],
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
)
|
||||
|
||||
|
||||
def poly_to_speckle(matrix, spline, scale, name=None):
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
return Polyline(
|
||||
name=name,
|
||||
closed=spline.use_cyclic_u,
|
||||
value=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
length=length,
|
||||
domain=domain,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
area=0,
|
||||
units=UNITS,
|
||||
)
|
||||
|
||||
|
||||
def export_curve(blender_object, data, scale=1.0):
|
||||
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
|
||||
|
||||
if blender_object.type != "CURVE":
|
||||
return None
|
||||
@@ -18,115 +110,22 @@ def export_curve(blender_object, data, scale=1.0):
|
||||
mesh = export_mesh(blender_object, blender_object.to_mesh(), scale)
|
||||
curves.extend(mesh)
|
||||
|
||||
unit_system = bpy.context.scene.unit_settings.system
|
||||
|
||||
for spline in data.splines:
|
||||
if spline.type == "BEZIER":
|
||||
|
||||
degree = 3
|
||||
closed = spline.use_cyclic_u
|
||||
|
||||
points = []
|
||||
for i, bp in enumerate(spline.bezier_points):
|
||||
if i > 0:
|
||||
points.append(tuple(mat @ bp.handle_left * scale))
|
||||
points.append(tuple(mat @ bp.co * scale))
|
||||
if i < len(spline.bezier_points) - 1:
|
||||
points.append(tuple(mat @ bp.handle_right * scale))
|
||||
|
||||
if closed:
|
||||
points.append(
|
||||
tuple(mat @ spline.bezier_points[-1].handle_right * scale)
|
||||
)
|
||||
points.append(tuple(mat @ spline.bezier_points[0].handle_left * scale))
|
||||
points.append(tuple(mat @ spline.bezier_points[0].co * scale))
|
||||
|
||||
num_points = len(points)
|
||||
|
||||
knot_count = num_points + degree - 1
|
||||
knots = [0] * knot_count
|
||||
|
||||
for i in range(1, len(knots), 1):
|
||||
knots[i] = i // 3
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(
|
||||
start=0, end=length, totalChildrenCount=0, applicationId="Blender"
|
||||
)
|
||||
bezier = Curve(
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[1] * num_points,
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
applicationId="Blender",
|
||||
)
|
||||
|
||||
curves.append(bezier)
|
||||
curves.append(bezier_to_speckle(mat, spline, scale, blender_object.name))
|
||||
|
||||
elif spline.type == "NURBS":
|
||||
|
||||
knots = makeknots(spline)
|
||||
# print("knots: {}".format(knots))
|
||||
points = [tuple(mat @ pt.co.xyz * scale) for pt in spline.points]
|
||||
degree = spline.order_u - 1
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(
|
||||
start=0, end=length, totalChildrenCount=0, applicationId="Blender"
|
||||
)
|
||||
nurbs = Curve(
|
||||
name=blender_object.name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[pt.weight for pt in spline.points],
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
applicationId="Blender",
|
||||
)
|
||||
|
||||
curves.append(nurbs)
|
||||
curves.append(nurbs_to_speckle(mat, spline, scale, blender_object.name))
|
||||
|
||||
elif spline.type == "POLY":
|
||||
points = [tuple(mat @ pt.co.xyz * scale) for pt in spline.points]
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(
|
||||
start=0, end=length, totalChildrenCount=0, applicationId="Blender"
|
||||
)
|
||||
poly = Polyline(
|
||||
name=blender_object.name,
|
||||
closed=spline.use_cyclic_u,
|
||||
value=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
length=length,
|
||||
domain=domain,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
area=0,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
applicationId="Blender",
|
||||
)
|
||||
curves.append(poly)
|
||||
curves.append(poly_to_speckle(mat, spline, scale, blender_object.name))
|
||||
|
||||
return curves
|
||||
|
||||
|
||||
def export_ngons_as_polylines(blender_object, data, scale=1.0):
|
||||
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
|
||||
|
||||
if blender_object.type != "MESH":
|
||||
return None
|
||||
|
||||
@@ -139,7 +138,7 @@ def export_ngons_as_polylines(blender_object, data, scale=1.0):
|
||||
for v in poly.vertices:
|
||||
value.extend(mat @ verts[v].co * scale)
|
||||
|
||||
domain = Interval(start=0, end=1, applicationId="Blender")
|
||||
domain = Interval(start=0, end=1)
|
||||
poly = Polyline(
|
||||
name="{}_{}".format(blender_object.name, i),
|
||||
closed=True,
|
||||
@@ -148,8 +147,7 @@ def export_ngons_as_polylines(blender_object, data, scale=1.0):
|
||||
domain=domain,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
area=0,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
applicationId="Blender",
|
||||
units=UNITS,
|
||||
)
|
||||
|
||||
polylines.append(poly)
|
||||
|
||||
@@ -26,7 +26,6 @@ def export_mesh(blender_object, data, scale=1.0):
|
||||
colors=[],
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
applicationId="Blender",
|
||||
)
|
||||
|
||||
for f in faces:
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
from specklepy.api.client import SpeckleClient
|
||||
import requests
|
||||
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
|
||||
"""
|
||||
|
||||
@@ -17,12 +17,14 @@ from .streams import (
|
||||
)
|
||||
from .streams import (
|
||||
UpdateGlobal,
|
||||
AddStreamFromURL,
|
||||
CreateStream,
|
||||
CopyStreamId,
|
||||
CopyCommitId,
|
||||
CopyBranchName,
|
||||
)
|
||||
from .commit import DeleteCommit
|
||||
from .misc import OpenSpeckleGuide, OpenSpeckleTutorials, OpenSpeckleForum
|
||||
|
||||
operator_classes = [
|
||||
LoadUsers,
|
||||
@@ -49,5 +51,15 @@ operator_classes.extend(
|
||||
)
|
||||
|
||||
operator_classes.extend(
|
||||
[ViewStreamDataApi, DeleteStream, SelectOrphanObjects, UpdateGlobal, CreateStream,]
|
||||
[
|
||||
ViewStreamDataApi,
|
||||
DeleteStream,
|
||||
SelectOrphanObjects,
|
||||
UpdateGlobal,
|
||||
AddStreamFromURL,
|
||||
CreateStream,
|
||||
OpenSpeckleGuide,
|
||||
OpenSpeckleTutorials,
|
||||
OpenSpeckleForum,
|
||||
]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import bpy
|
||||
import webbrowser
|
||||
|
||||
|
||||
class OpenSpeckleGuide(bpy.types.Operator):
|
||||
bl_idname = "speckle.open_speckle_guide"
|
||||
bl_label = "Speckle Guide"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Browse the documentation on the Speckle Guide"
|
||||
|
||||
def execute(self, context):
|
||||
webbrowser.open("https://speckle.guide/user/blender.html")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class OpenSpeckleTutorials(bpy.types.Operator):
|
||||
bl_idname = "speckle.open_speckle_tutorials"
|
||||
bl_label = "Tutorials Portal"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Visit our tutorials portal for learning resources"
|
||||
|
||||
def execute(self, context):
|
||||
webbrowser.open("https://speckle.systems/tutorials/")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class OpenSpeckleForum(bpy.types.Operator):
|
||||
bl_idname = "speckle.open_speckle_forum"
|
||||
bl_label = "Community Forum"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Ask questions and join the discussion on our community forum"
|
||||
|
||||
def execute(self, context):
|
||||
webbrowser.open("https://speckle.community/")
|
||||
return {"FINISHED"}
|
||||
@@ -110,7 +110,7 @@ class DeleteObject(bpy.types.Operator):
|
||||
for x in res["resource"]["objects"]
|
||||
if x["_id"] == active.speckle.object_id
|
||||
]
|
||||
if existing == None:
|
||||
if existing is None:
|
||||
return {"CANCELLED"}
|
||||
# print("Existing: %s" % SpeckleResource.to_json_pretty(existing))
|
||||
new_objects = [
|
||||
@@ -177,7 +177,7 @@ class UploadNgonsAsPolylines(bpy.types.Operator):
|
||||
res = client.objects.create([polyline])
|
||||
print(res)
|
||||
|
||||
if res == None:
|
||||
if res is None:
|
||||
_report(client.me)
|
||||
continue
|
||||
placeholders.extend(res)
|
||||
@@ -185,7 +185,7 @@ class UploadNgonsAsPolylines(bpy.types.Operator):
|
||||
# polyline['_id'] = res['_id']
|
||||
# placeholders.append({'type':'Placeholder', '_id':res['_id']})
|
||||
|
||||
if len(placeholders) < 1:
|
||||
if not placeholders:
|
||||
return {"CANCELLED"}
|
||||
|
||||
# Get list of existing objects in stream and append new object to list
|
||||
@@ -247,7 +247,7 @@ class UploadObject(bpy.types.Operator):
|
||||
sm = to_speckle_object(active, scale)
|
||||
|
||||
placeholders = client.objects.create([sm])
|
||||
if placeholders == None:
|
||||
if placeholders is None:
|
||||
return {"CANCELLED"}
|
||||
|
||||
sstream = client.streams.get(stream.id)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
"""
|
||||
Stream operators
|
||||
"""
|
||||
from itertools import chain
|
||||
from typing import Dict
|
||||
import bpy, bmesh, os
|
||||
from specklepy.api.models import Commit
|
||||
import webbrowser
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
@@ -10,7 +13,6 @@ from bpy.props import (
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
)
|
||||
|
||||
from bpy_speckle.functions import (
|
||||
_check_speckle_client_user_stream,
|
||||
_create_stream,
|
||||
@@ -22,21 +24,25 @@ from bpy_speckle.convert.to_speckle import export_ngons_as_polylines
|
||||
|
||||
from bpy_speckle.convert import from_speckle_object
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.operators.users import add_user_stream
|
||||
|
||||
from specklepy.api import operations
|
||||
from specklepy.api.credentials import StreamWrapper
|
||||
from specklepy.api.resources.stream import Stream
|
||||
from specklepy.transports.server import ServerTransport
|
||||
from specklepy.objects import Base
|
||||
from specklepy.objects.geometry import *
|
||||
from specklepy.logging.exceptions import SpeckleException
|
||||
|
||||
|
||||
def get_objects_collections(base):
|
||||
def get_objects_collections(base) -> Dict:
|
||||
"""Create collections based on the dynamic members on a root commit object"""
|
||||
collections = {}
|
||||
for name in base.get_dynamic_member_names():
|
||||
value = base[name]
|
||||
if isinstance(value, list):
|
||||
col = create_collection(name)
|
||||
collections[name] = [item for item in value if isinstance(item, Base)]
|
||||
collections[name] = get_objects_nested_lists(value, col)
|
||||
if isinstance(value, Base):
|
||||
col = create_collection(name)
|
||||
collections[name] = get_objects_collections_recursive(value, col)
|
||||
@@ -44,8 +50,37 @@ def get_objects_collections(base):
|
||||
return collections
|
||||
|
||||
|
||||
def get_objects_collections_recursive(base, parent_col=None):
|
||||
def get_objects_nested_lists(items, parent_col=None) -> List:
|
||||
"""For handling the weird nested lists that come from Grasshopper"""
|
||||
objects = []
|
||||
|
||||
if isinstance(items[0], list):
|
||||
items = list(chain.from_iterable(items))
|
||||
objects.extend(get_objects_nested_lists(items, parent_col))
|
||||
else:
|
||||
objects = [
|
||||
get_objects_collections_recursive(item, parent_col)
|
||||
for item in items
|
||||
if isinstance(item, Base)
|
||||
]
|
||||
|
||||
return objects
|
||||
|
||||
|
||||
def get_objects_collections_recursive(base, parent_col=None) -> List:
|
||||
"""Recursively create collections based on the dynamic members on nested `Base` objects within the root commit object"""
|
||||
# if it's a convertable (registered) class and not just a plain `Base`, return the object itself
|
||||
object_type = Base.get_registered_type(base.speckle_type)
|
||||
if (
|
||||
(object_type and object_type != Base)
|
||||
or hasattr(base, "displayMesh")
|
||||
or hasattr(base, "displayValue")
|
||||
):
|
||||
return [base]
|
||||
|
||||
# if it's an unknown type, try to drill further down to find convertable objects
|
||||
objects = []
|
||||
|
||||
for name in base.get_dynamic_member_names():
|
||||
value = base[name]
|
||||
if isinstance(value, list):
|
||||
@@ -53,8 +88,10 @@ def get_objects_collections_recursive(base, parent_col=None):
|
||||
if isinstance(item, Base):
|
||||
objects.append(item)
|
||||
if isinstance(value, Base):
|
||||
col = create_collection(name)
|
||||
parent_col.children.link(col)
|
||||
col = parent_col.children.get(name)
|
||||
if not parent_col.children.get(name):
|
||||
col = create_collection(name)
|
||||
parent_col.children.link(col)
|
||||
objects.append({name: get_objects_collections_recursive(value, col)})
|
||||
|
||||
return objects
|
||||
@@ -69,60 +106,71 @@ def bases_to_native(context, collections, scale, stream_id, func=None):
|
||||
elif isinstance(objects, list):
|
||||
for obj in objects:
|
||||
if isinstance(obj, dict):
|
||||
bases_to_native(context, obj, scale, stream_id)
|
||||
bases_to_native(context, obj, scale, stream_id, func)
|
||||
elif isinstance(obj, list):
|
||||
for item in obj:
|
||||
if isinstance(item, dict):
|
||||
bases_to_native(context, item, scale, stream_id, func)
|
||||
elif isinstance(item, Base):
|
||||
base_to_native(
|
||||
context, item, scale, stream_id, col, existing, func
|
||||
)
|
||||
elif isinstance(obj, Base):
|
||||
base_to_native(context, obj, scale, stream_id, col, existing, func)
|
||||
else:
|
||||
new_objects = [from_speckle_object(obj, scale)]
|
||||
_report(
|
||||
f"Something went wrong when receiving collection: {col_name}"
|
||||
)
|
||||
|
||||
if hasattr(obj, "properties") and obj.properties is not None:
|
||||
new_objects.extend(
|
||||
get_speckle_subobjects(obj.properties, scale, obj.id)
|
||||
)
|
||||
elif isinstance(obj, dict) and "properties" in obj.keys():
|
||||
new_objects.extend(
|
||||
get_speckle_subobjects(obj["properties"], scale, obj["id"])
|
||||
)
|
||||
|
||||
"""
|
||||
Set object Speckle settings
|
||||
"""
|
||||
for new_object in new_objects:
|
||||
if new_object is None:
|
||||
continue
|
||||
|
||||
"""
|
||||
Run injected function
|
||||
"""
|
||||
if func:
|
||||
new_object = func(context.scene, new_object)
|
||||
|
||||
if (
|
||||
new_object is None
|
||||
): # Make sure that the injected function returned an object
|
||||
new_obj = new_object
|
||||
_report(
|
||||
"Script '{}' returned None.".format(func.__module__)
|
||||
)
|
||||
continue
|
||||
|
||||
new_object.speckle.stream_id = stream_id
|
||||
new_object.speckle.send_or_receive = "receive"
|
||||
|
||||
if new_object.speckle.object_id in existing.keys():
|
||||
name = existing[new_object.speckle.object_id].name
|
||||
existing[new_object.speckle.object_id].name = (
|
||||
name + "__deleted"
|
||||
)
|
||||
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)
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
if context.area:
|
||||
context.area.tag_redraw()
|
||||
|
||||
|
||||
def base_to_native(context, base, scale, stream_id, col, existing, func=None):
|
||||
new_objects = [from_speckle_object(base, scale)]
|
||||
|
||||
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
|
||||
"""
|
||||
for new_object in new_objects:
|
||||
if new_object is None:
|
||||
continue
|
||||
|
||||
"""
|
||||
Run injected function
|
||||
"""
|
||||
if func:
|
||||
new_object = func(context.scene, new_object)
|
||||
|
||||
if (
|
||||
new_object is None
|
||||
): # Make sure that the injected function returned an object
|
||||
new_obj = new_object
|
||||
_report("Script '{}' returned None.".format(func.__module__))
|
||||
continue
|
||||
|
||||
new_object.speckle.stream_id = stream_id
|
||||
new_object.speckle.send_or_receive = "receive"
|
||||
|
||||
if new_object.speckle.object_id in existing.keys():
|
||||
name = existing[new_object.speckle.object_id].name
|
||||
existing[new_object.speckle.object_id].name = name + "__deleted"
|
||||
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)
|
||||
|
||||
|
||||
def create_collection(name, clear_collection=True):
|
||||
if name in bpy.data.collections:
|
||||
col = bpy.data.collections[name]
|
||||
@@ -241,8 +289,10 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
bpy.context.scene.collection.children.link(col)
|
||||
|
||||
for child_col in collections.keys():
|
||||
col.children.link(bpy.data.collections[child_col])
|
||||
|
||||
try:
|
||||
col.children.link(bpy.data.collections[child_col])
|
||||
except:
|
||||
pass
|
||||
"""
|
||||
Set conversion scale from stream units
|
||||
"""
|
||||
@@ -278,6 +328,7 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Send selected objects to active stream"
|
||||
|
||||
apply_modifiers: BoolProperty(name="Apply modifiers", default=True)
|
||||
commit_message: StringProperty(
|
||||
name="Message",
|
||||
default="Pushed elements from Blender.",
|
||||
@@ -287,6 +338,7 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.prop(self, "commit_message")
|
||||
col.prop(self, "apply_modifiers")
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
@@ -359,7 +411,13 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
if ngons:
|
||||
converted = export_ngons_as_polylines(obj, scale)
|
||||
else:
|
||||
converted = to_speckle_object(obj, scale)
|
||||
converted = to_speckle_object(
|
||||
obj,
|
||||
scale,
|
||||
bpy.context.evaluated_depsgraph_get()
|
||||
if self.apply_modifiers
|
||||
else None,
|
||||
)
|
||||
|
||||
if not converted:
|
||||
continue
|
||||
@@ -417,6 +475,84 @@ class ViewStreamDataApi(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
class AddStreamFromURL(bpy.types.Operator):
|
||||
"""
|
||||
Add / select a stream using its url
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.add_stream_from_url"
|
||||
bl_label = "Add stream from URL"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Add an existing stream by providing its URL"
|
||||
stream_url: StringProperty(
|
||||
name="Stream URL", default="https://speckle.xyz/streams/3073b96e86"
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.prop(self, "stream_url")
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
if len(context.scene.speckle.users) > 0:
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
return {"CANCELLED"}
|
||||
|
||||
def execute(self, context):
|
||||
speckle = context.scene.speckle
|
||||
|
||||
wrapper = StreamWrapper(self.stream_url)
|
||||
user_index = next(
|
||||
(i for i, u in enumerate(speckle.users) if wrapper.host in u.server_url),
|
||||
None,
|
||||
)
|
||||
if user_index is None:
|
||||
return {"CANCELLED"}
|
||||
speckle.active_user = str(user_index)
|
||||
user = speckle.users[user_index]
|
||||
|
||||
client = speckle_clients[user_index]
|
||||
stream = client.stream.get(wrapper.stream_id)
|
||||
if not isinstance(stream, Stream):
|
||||
raise SpeckleException("Could not get the requested stream")
|
||||
|
||||
index, b_stream = next(
|
||||
((i, s) for i, s in enumerate(user.streams) if s.id == stream.id),
|
||||
(None, None),
|
||||
)
|
||||
|
||||
if index is None:
|
||||
add_user_stream(user, stream)
|
||||
user.active_stream, b_stream = next(
|
||||
(i, s) for i, s in enumerate(user.streams) if s.id == stream.id
|
||||
)
|
||||
else:
|
||||
user.active_stream = index
|
||||
|
||||
if wrapper.branch_name:
|
||||
b_index = b_stream.branches.find(wrapper.branch_name)
|
||||
b_stream.branch = str(b_index if b_index != -1 else 0)
|
||||
elif wrapper.commit_id:
|
||||
commit = client.commit.get(wrapper.stream_id, wrapper.commit_id)
|
||||
if isinstance(commit, Commit):
|
||||
b_index = b_stream.branches.find(commit.branchName)
|
||||
if b_index == -1:
|
||||
b_index = 0
|
||||
b_stream.branch = str(b_index)
|
||||
c_index = b_stream.branches[b_index].commits.find(commit.id)
|
||||
b_stream.branches[b_index].commit = str(c_index if c_index != -1 else 0)
|
||||
|
||||
# Update view layer
|
||||
context.view_layer.update()
|
||||
|
||||
if context.area:
|
||||
context.area.tag_redraw()
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class CreateStream(bpy.types.Operator):
|
||||
"""
|
||||
Create new stream
|
||||
|
||||
@@ -55,6 +55,8 @@ class LoadUsers(bpy.types.Operator):
|
||||
except Exception as ex:
|
||||
_report(ex)
|
||||
users.remove(len(users) - 1)
|
||||
if profile.isDefault:
|
||||
context.scene.speckle.active_user = str(len(users) - 1)
|
||||
|
||||
context.scene.speckle.active_user_index = int(context.scene.speckle.active_user)
|
||||
bpy.ops.speckle.load_user_streams()
|
||||
@@ -65,6 +67,37 @@ class LoadUsers(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
def add_user_stream(user, stream):
|
||||
s = user.streams.add()
|
||||
s.name = stream.name
|
||||
s.id = stream.id
|
||||
s.description = stream.description
|
||||
|
||||
if not stream.branches:
|
||||
return
|
||||
|
||||
for b in stream.branches.items:
|
||||
branch = s.branches.add()
|
||||
branch.name = b.name
|
||||
|
||||
if not b.commits:
|
||||
continue
|
||||
|
||||
for c in b.commits.items:
|
||||
commit = branch.commits.add()
|
||||
commit.id = commit.name = c.id
|
||||
commit.message = c.message
|
||||
commit.author_name = c.authorName
|
||||
commit.author_id = c.authorId
|
||||
commit.created_at = c.createdAt
|
||||
commit.source_application = str(c.sourceApplication)
|
||||
|
||||
if hasattr(s, "baseProperties"):
|
||||
s.units = stream.baseProperties.units
|
||||
else:
|
||||
s.units = "Meters"
|
||||
|
||||
|
||||
class LoadUserStreams(bpy.types.Operator):
|
||||
"""
|
||||
Load all available streams for active user user
|
||||
@@ -97,36 +130,8 @@ class LoadUserStreams(bpy.types.Operator):
|
||||
default_units = "Meters"
|
||||
|
||||
for s in streams:
|
||||
stream = user.streams.add()
|
||||
stream.name = s.name
|
||||
stream.id = s.id
|
||||
stream.description = s.description
|
||||
|
||||
sstream = client.stream.get(id=s.id)
|
||||
|
||||
if not sstream.branches:
|
||||
continue
|
||||
|
||||
for b in sstream.branches.items:
|
||||
branch = stream.branches.add()
|
||||
branch.name = b.name
|
||||
|
||||
if not b.commits:
|
||||
continue
|
||||
|
||||
for c in b.commits.items:
|
||||
commit = branch.commits.add()
|
||||
commit.id = c.id
|
||||
commit.message = c.message
|
||||
commit.author_name = c.authorName
|
||||
commit.author_id = c.authorId
|
||||
commit.created_at = c.createdAt
|
||||
commit.source_application = str(c.sourceApplication)
|
||||
|
||||
if hasattr(s, "baseProperties"):
|
||||
stream.units = s.baseProperties.units
|
||||
else:
|
||||
stream.units = default_units
|
||||
add_user_stream(user, sstream)
|
||||
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from .view3d import (
|
||||
VIEW3D_PT_SpeckleUser,
|
||||
VIEW3D_PT_SpeckleStreams,
|
||||
VIEW3D_PT_SpeckleActiveStream,
|
||||
VIEW3D_PT_SpeckleHelp,
|
||||
)
|
||||
|
||||
ui_classes = [
|
||||
@@ -13,5 +14,5 @@ ui_classes = [
|
||||
VIEW3D_PT_SpeckleActiveStream,
|
||||
VIEW3D_UL_SpeckleUsers,
|
||||
VIEW3D_UL_SpeckleStreams,
|
||||
# OBJECT_PT_speckle,
|
||||
VIEW3D_PT_SpeckleHelp,
|
||||
]
|
||||
|
||||
@@ -144,11 +144,11 @@ class VIEW3D_PT_SpeckleStreams(bpy.types.Panel):
|
||||
col.label(text="No stream data.")
|
||||
else:
|
||||
user = speckle.users[int(speckle.active_user)]
|
||||
# col.label(text="Streams")
|
||||
col.template_list(
|
||||
"VIEW3D_UL_SpeckleStreams", "", user, "streams", user, "active_stream"
|
||||
)
|
||||
row = col.row(align=True)
|
||||
row.operator("speckle.add_stream_from_url", text="", icon="URL")
|
||||
row.operator("speckle.create_stream", text="", icon="ADD")
|
||||
row.operator("speckle.delete_stream", text="", icon="REMOVE")
|
||||
row.operator("speckle.load_user_streams", text="", icon="FILE_REFRESH")
|
||||
@@ -253,3 +253,25 @@ class VIEW3D_PT_SpeckleActiveStream(bpy.types.Panel):
|
||||
area.separator()
|
||||
col.separator()
|
||||
col.operator("speckle.view_stream_data_api", text="Open Stream in Web")
|
||||
|
||||
|
||||
class VIEW3D_PT_SpeckleHelp(bpy.types.Panel):
|
||||
"""
|
||||
Speckle Help UI panel in the 3d viewport
|
||||
"""
|
||||
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = Region
|
||||
bl_category = "Speckle"
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Help"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
|
||||
col.operator("speckle.open_speckle_guide")
|
||||
col.separator()
|
||||
col.operator("speckle.open_speckle_tutorials")
|
||||
col.separator()
|
||||
col.operator("speckle.open_speckle_forum")
|
||||
|
||||
Generated
+124
-91
@@ -86,14 +86,28 @@ category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "2.0.4"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5.0"
|
||||
|
||||
[package.extras]
|
||||
unicode_backport = ["unicodedata2"]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "3.20.2"
|
||||
version = "3.21.1.post1"
|
||||
description = "CMake is an open-source, cross-platform family of tools designed to build, test and package software"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.extras]
|
||||
test = ["codecov (>=2.0.5)", "coverage (>=4.2)", "flake8 (>=3.0.4)", "path.py (>=11.5.0)", "pytest (>=3.0.3)", "pytest-cov (>=2.4.0)", "pytest-runner (>=2.9)", "pytest-virtualenv (>=1.7.0)", "scikit-build (>=0.10.0)", "setuptools (>=28.0.0)", "virtualenv (>=15.0.3)", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "cmake-generators"
|
||||
version = "1.0.9"
|
||||
@@ -115,7 +129,7 @@ pygments = ["Pygments (>=2.2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "distro"
|
||||
version = "1.5.0"
|
||||
version = "1.6.0"
|
||||
description = "Distro - an OS platform information API"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -134,15 +148,15 @@ smmap = ">=3.0.1,<5"
|
||||
|
||||
[[package]]
|
||||
name = "gitpython"
|
||||
version = "3.1.17"
|
||||
version = "3.1.20"
|
||||
description = "Python Git Library"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
gitdb = ">=4.0.1,<5"
|
||||
typing-extensions = {version = ">=3.7.4.0", markers = "python_version < \"3.8\""}
|
||||
typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""}
|
||||
|
||||
[[package]]
|
||||
name = "gql"
|
||||
@@ -153,7 +167,10 @@ optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = {version = ">=3.7.1,<3.8.0", optional = true, markers = "extra == \"all\""}
|
||||
graphql-core = ">=3.1.5,<3.2"
|
||||
requests = {version = ">=2.23,<3", optional = true, markers = "extra == \"all\""}
|
||||
websockets = {version = ">=9,<10", optional = true, markers = "extra == \"all\""}
|
||||
yarl = ">=1.6,<2.0"
|
||||
|
||||
[package.extras]
|
||||
@@ -175,11 +192,11 @@ python-versions = ">=3.6,<4"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "2.10"
|
||||
version = "3.2"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "multidict"
|
||||
@@ -199,7 +216,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.20.3"
|
||||
version = "1.21.1"
|
||||
description = "NumPy is the fundamental package for array computing with Python."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -222,7 +239,7 @@ email = ["email-validator (>=1.0.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.1"
|
||||
version = "2.8.2"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -233,21 +250,21 @@ six = ">=1.5"
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.25.1"
|
||||
version = "2.26.0"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
chardet = ">=3.0.2,<5"
|
||||
idna = ">=2.5,<3"
|
||||
charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
|
||||
idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
|
||||
urllib3 = ">=1.21.1,<1.27"
|
||||
|
||||
[package.extras]
|
||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
|
||||
use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
@@ -267,19 +284,16 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "specklepy"
|
||||
version = "2.2.2"
|
||||
version = "2.2.8"
|
||||
description = "The Python SDK for Speckle 2.0"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.5,<4.0.0"
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = ">=3.7.3,<4.0.0"
|
||||
appdirs = ">=1.4.4,<2.0.0"
|
||||
gql = ">=3.0.0a5,<4.0.0"
|
||||
gql = {version = ">=3.0.0a6", extras = ["all"]}
|
||||
pydantic = ">=1.7.3,<2.0.0"
|
||||
requests = ">=2.25.1,<3.0.0"
|
||||
websockets = ">=8.1,<9.0"
|
||||
|
||||
[[package]]
|
||||
name = "svn"
|
||||
@@ -303,7 +317,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.26.5"
|
||||
version = "1.26.6"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -316,7 +330,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "websockets"
|
||||
version = "8.1"
|
||||
version = "9.1"
|
||||
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -338,7 +352,7 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = ">=3.7,<3.8"
|
||||
content-hash = "921705639801601eab9c92905b94cc8fecda65723331b9757f36a18df433184f"
|
||||
content-hash = "6ddf074f0ed0182ddf60e5f97f1a3f606f6af295351900f4d984f2390e3d3a88"
|
||||
|
||||
[metadata.files]
|
||||
aiohttp = [
|
||||
@@ -408,16 +422,20 @@ chardet = [
|
||||
{file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
|
||||
{file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
|
||||
]
|
||||
charset-normalizer = [
|
||||
{file = "charset-normalizer-2.0.4.tar.gz", hash = "sha256:f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"},
|
||||
{file = "charset_normalizer-2.0.4-py3-none-any.whl", hash = "sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b"},
|
||||
]
|
||||
cmake = [
|
||||
{file = "cmake-3.20.2-py2.py3-none-macosx_10_10_universal2.macosx_10_10_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl", hash = "sha256:9447e5697fdd4712a86b0f7c9b626b49f0ae985dbfcfeccbfa3571047625ca5c"},
|
||||
{file = "cmake-3.20.2-py2.py3-none-manylinux1_i686.whl", hash = "sha256:3f571ad204c808325e96bba7fc1476da343a91a157d5ae4798340d46b9e387ce"},
|
||||
{file = "cmake-3.20.2-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:8be74cf80a16b62ba9df14d90ed1dc15f73abbcb39ecfa946c0cd23e8293e3e7"},
|
||||
{file = "cmake-3.20.2-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0da86069980ef9e7613909a624572b722b96badcac6e00beadef54273aceeb36"},
|
||||
{file = "cmake-3.20.2-py2.py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:412f590015ea91c3339fd2ef3cadb8ba207db95c2041429d46e6f92baac16ad4"},
|
||||
{file = "cmake-3.20.2-py2.py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5bcd0ca0077d89fac452d522b623c27f8eb1c76fb21efc0366ddc2b0fb2a770"},
|
||||
{file = "cmake-3.20.2-py2.py3-none-win32.whl", hash = "sha256:b6aae4b86e1165fdf6b63628ec39eaed25b43b59e43993499f6cadee7c8c6897"},
|
||||
{file = "cmake-3.20.2-py2.py3-none-win_amd64.whl", hash = "sha256:2eec53a432c0d6d91e15398aaaede368ed3f16cf74aef2f2390f85bb61944512"},
|
||||
{file = "cmake-3.20.2.tar.gz", hash = "sha256:ad0ee1a0eaac577f3c594795267c1617d53e4c31ce71208b96266ca7ef6fa857"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-macosx_10_10_universal2.macosx_10_10_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl", hash = "sha256:4b8c1810b2defc30b35b8973aec5d8055038fde1e9df984812e09a290d4b65a3"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e21f75ba51b04f7fa8cbf6965bfb194db32f4b04eb7757c312a621c0a4dd847"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d637b7153d337c118df79aca9189f8c44d4200f0c99d2aaf021d7696a535f9a"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaea4911f6fccaf5a84110b2c9d4b5d99e9792112199ca25408c635bd2fd8584"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:caa81c3f3985b552bc2e38fb339ba84c0c237441d508f4de01d44a2948eddd36"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1cf061e78e9a16f7f40f768f12d806483fe0eee7c1f9eeb4766610cb9122cb73"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-win32.whl", hash = "sha256:e000ef5d4893ceaec852f468d6adc7698ca08ebaecb6df38d81ceed32b4ad9e3"},
|
||||
{file = "cmake-3.21.1.post1-py2.py3-none-win_amd64.whl", hash = "sha256:a3f32247ef6000616585ab847bcb367787606ad33ab34f64dcfc85d304dafea9"},
|
||||
{file = "cmake-3.21.1.post1.tar.gz", hash = "sha256:2fc534f714347c2bfca7b15a0004f224f61164658130f33402341e10a5188658"},
|
||||
]
|
||||
cmake-generators = [
|
||||
{file = "cmake-generators-1.0.9.tar.gz", hash = "sha256:2b03bdcd69345c03ffa56aa025b3163bd26b1465561c365a79cf1c6a31672ebf"},
|
||||
@@ -428,16 +446,16 @@ devtools = [
|
||||
{file = "devtools-0.6.1.tar.gz", hash = "sha256:a054307594d35d28fae8df7629967363e851ae0ac7b2152640a8a401c39d42d7"},
|
||||
]
|
||||
distro = [
|
||||
{file = "distro-1.5.0-py2.py3-none-any.whl", hash = "sha256:df74eed763e18d10d0da624258524ae80486432cd17392d9c3d96f5e83cd2799"},
|
||||
{file = "distro-1.5.0.tar.gz", hash = "sha256:0e58756ae38fbd8fc3020d54badb8eae17c5b9dcbed388b17bb55b8a5928df92"},
|
||||
{file = "distro-1.6.0-py2.py3-none-any.whl", hash = "sha256:c8713330ab31a034623a9515663ed87696700b55f04556b97c39cd261aa70dc7"},
|
||||
{file = "distro-1.6.0.tar.gz", hash = "sha256:83f5e5a09f9c5f68f60173de572930effbcc0287bb84fdc4426cb4168c088424"},
|
||||
]
|
||||
gitdb = [
|
||||
{file = "gitdb-4.0.7-py3-none-any.whl", hash = "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0"},
|
||||
{file = "gitdb-4.0.7.tar.gz", hash = "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005"},
|
||||
]
|
||||
gitpython = [
|
||||
{file = "GitPython-3.1.17-py3-none-any.whl", hash = "sha256:29fe82050709760081f588dd50ce83504feddbebdc4da6956d02351552b1c135"},
|
||||
{file = "GitPython-3.1.17.tar.gz", hash = "sha256:ee24bdc93dce357630764db659edaf6b8d664d4ff5447ccfeedd2dc5c253f41e"},
|
||||
{file = "GitPython-3.1.20-py3-none-any.whl", hash = "sha256:b1e1c269deab1b08ce65403cf14e10d2ef1f6c89e33ea7c5e5bb0222ea593b8a"},
|
||||
{file = "GitPython-3.1.20.tar.gz", hash = "sha256:df0e072a200703a65387b0cfdf0466e3bab729c0458cf6b7349d0e9877636519"},
|
||||
]
|
||||
gql = [
|
||||
{file = "gql-3.0.0a6.tar.gz", hash = "sha256:bdcbf60bc37b11d6d2f2ed271f69292c4e96d56df7000ba1dad52e487330bdce"},
|
||||
@@ -447,8 +465,8 @@ graphql-core = [
|
||||
{file = "graphql_core-3.1.5-py3-none-any.whl", hash = "sha256:91d96ef0e86665777bb7115d3bbb6b0326f43dc7dbcdd60da5486a27a50cfb11"},
|
||||
]
|
||||
idna = [
|
||||
{file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
|
||||
{file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"},
|
||||
{file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
|
||||
{file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},
|
||||
]
|
||||
multidict = [
|
||||
{file = "multidict-5.1.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f"},
|
||||
@@ -495,30 +513,34 @@ nose = [
|
||||
{file = "nose-1.3.7.tar.gz", hash = "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"},
|
||||
]
|
||||
numpy = [
|
||||
{file = "numpy-1.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:70eb5808127284c4e5c9e836208e09d685a7978b6a216db85960b1a112eeace8"},
|
||||
{file = "numpy-1.20.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6ca2b85a5997dabc38301a22ee43c82adcb53ff660b89ee88dded6b33687e1d8"},
|
||||
{file = "numpy-1.20.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5bf0e132acf7557fc9bb8ded8b53bbbbea8892f3c9a1738205878ca9434206a"},
|
||||
{file = "numpy-1.20.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db250fd3e90117e0312b611574cd1b3f78bec046783195075cbd7ba9c3d73f16"},
|
||||
{file = "numpy-1.20.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:637d827248f447e63585ca3f4a7d2dfaa882e094df6cfa177cc9cf9cd6cdf6d2"},
|
||||
{file = "numpy-1.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8b7bb4b9280da3b2856cb1fc425932f46fba609819ee1c62256f61799e6a51d2"},
|
||||
{file = "numpy-1.20.3-cp37-cp37m-win32.whl", hash = "sha256:67d44acb72c31a97a3d5d33d103ab06d8ac20770e1c5ad81bdb3f0c086a56cf6"},
|
||||
{file = "numpy-1.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:43909c8bb289c382170e0282158a38cf306a8ad2ff6dfadc447e90f9961bef43"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f1452578d0516283c87608a5a5548b0cdde15b99650efdfd85182102ef7a7c17"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6e51534e78d14b4a009a062641f465cfaba4fdcb046c3ac0b1f61dd97c861b1b"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e515c9a93aebe27166ec9593411c58494fa98e5fcc219e47260d9ab8a1cc7f9f"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1c09247ccea742525bdb5f4b5ceeacb34f95731647fe55774aa36557dbb5fa4"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:66fbc6fed94a13b9801fb70b96ff30605ab0a123e775a5e7a26938b717c5d71a"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ea9cff01e75a956dbee133fa8e5b68f2f92175233de2f88de3a682dd94deda65"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-win32.whl", hash = "sha256:f39a995e47cb8649673cfa0579fbdd1cdd33ea497d1728a6cb194d6252268e48"},
|
||||
{file = "numpy-1.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:1676b0a292dd3c99e49305a16d7a9f42a4ab60ec522eac0d3dd20cdf362ac010"},
|
||||
{file = "numpy-1.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:830b044f4e64a76ba71448fce6e604c0fc47a0e54d8f6467be23749ac2cbd2fb"},
|
||||
{file = "numpy-1.20.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:55b745fca0a5ab738647d0e4db099bd0a23279c32b31a783ad2ccea729e632df"},
|
||||
{file = "numpy-1.20.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5d050e1e4bc9ddb8656d7b4f414557720ddcca23a5b88dd7cff65e847864c400"},
|
||||
{file = "numpy-1.20.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9c65473ebc342715cb2d7926ff1e202c26376c0dcaaee85a1fd4b8d8c1d3b2f"},
|
||||
{file = "numpy-1.20.3-cp39-cp39-win32.whl", hash = "sha256:16f221035e8bd19b9dc9a57159e38d2dd060b48e93e1d843c49cb370b0f415fd"},
|
||||
{file = "numpy-1.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:6690080810f77485667bfbff4f69d717c3be25e5b11bb2073e76bb3f578d99b4"},
|
||||
{file = "numpy-1.20.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e465afc3b96dbc80cf4a5273e5e2b1e3451286361b4af70ce1adb2984d392f9"},
|
||||
{file = "numpy-1.20.3.zip", hash = "sha256:e55185e51b18d788e49fe8305fd73ef4470596b33fc2c1ceb304566b99c71a69"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a75b4498b1e93d8b700282dc8e655b8bd559c0904b3910b144646dbbbc03e062"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1412aa0aec3e00bc23fbb8664d76552b4efde98fb71f60737c83efbac24112f1"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e46ceaff65609b5399163de5893d8f2a82d3c77d5e56d976c8b5fb01faa6b671"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c6a2324085dd52f96498419ba95b5777e40b6bcbc20088fddb9e8cbb58885e8e"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-win32.whl", hash = "sha256:73101b2a1fef16602696d133db402a7e7586654682244344b8329cdcbbb82172"},
|
||||
{file = "numpy-1.21.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7a708a79c9a9d26904d1cca8d383bf869edf6f8e7650d85dbc77b041e8c5a0f8"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95b995d0c413f5d0428b3f880e8fe1660ff9396dcd1f9eedbc311f37b5652e16"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:635e6bd31c9fb3d475c8f44a089569070d10a9ef18ed13738b03049280281267"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a3d5fb89bfe21be2ef47c0614b9c9c707b7362386c9a3ff1feae63e0267ccb6"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a326af80e86d0e9ce92bcc1e65c8ff88297de4fa14ee936cb2293d414c9ec63"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:791492091744b0fe390a6ce85cc1bf5149968ac7d5f0477288f78c89b385d9af"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0318c465786c1f63ac05d7c4dbcecd4d2d7e13f0959b01b534ea1e92202235c5"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a513bd9c1551894ee3d31369f9b07460ef223694098cf27d399513415855b68"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91c6f5fc58df1e0a3cc0c3a717bb3308ff850abdaa6d2d802573ee2b11f674a8"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-win32.whl", hash = "sha256:978010b68e17150db8765355d1ccdd450f9fc916824e8c4e35ee620590e234cd"},
|
||||
{file = "numpy-1.21.1-cp38-cp38-win_amd64.whl", hash = "sha256:9749a40a5b22333467f02fe11edc98f022133ee1bfa8ab99bda5e5437b831214"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d7a4aeac3b94af92a9373d6e77b37691b86411f9745190d2c351f410ab3a791f"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9e7912a56108aba9b31df688a4c4f5cb0d9d3787386b87d504762b6754fbb1b"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:25b40b98ebdd272bc3020935427a4530b7d60dfbe1ab9381a39147834e985eac"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a92c5aea763d14ba9d6475803fc7904bda7decc2a0a68153f587ad82941fec1"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05a0f648eb28bae4bcb204e6fd14603de2908de982e761a2fc78efe0f19e96e1"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01f28075a92eede918b965e86e8f0ba7b7797a95aa8d35e1cc8821f5fc3ad6a"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-win32.whl", hash = "sha256:88c0b89ad1cc24a5efbb99ff9ab5db0f9a86e9cc50240177a571fbe9c2860ac2"},
|
||||
{file = "numpy-1.21.1-cp39-cp39-win_amd64.whl", hash = "sha256:01721eefe70544d548425a07c80be8377096a54118070b8a62476866d5208e33"},
|
||||
{file = "numpy-1.21.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d4d1de6e6fb3d28781c73fbde702ac97f03d79e4ffd6598b880b2d95d62ead4"},
|
||||
{file = "numpy-1.21.1.zip", hash = "sha256:dff4af63638afcc57a3dfb9e4b26d434a7a602d225b42d746ea7fe2edf1342fd"},
|
||||
]
|
||||
pydantic = [
|
||||
{file = "pydantic-1.8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739"},
|
||||
@@ -545,12 +567,12 @@ pydantic = [
|
||||
{file = "pydantic-1.8.2.tar.gz", hash = "sha256:26464e57ccaafe72b7ad156fdaa4e9b9ef051f69e175dbbb463283000c05ab7b"},
|
||||
]
|
||||
python-dateutil = [
|
||||
{file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
|
||||
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
|
||||
{file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
|
||||
{file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"},
|
||||
{file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
@@ -561,8 +583,8 @@ smmap = [
|
||||
{file = "smmap-4.0.0.tar.gz", hash = "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182"},
|
||||
]
|
||||
specklepy = [
|
||||
{file = "specklepy-2.2.2-py3-none-any.whl", hash = "sha256:73936229bd4c1e9703fa2bdfb6ed59ec06394365e2386d0d8ca96b8361096b65"},
|
||||
{file = "specklepy-2.2.2.tar.gz", hash = "sha256:4cd33ba43e4345c68d8dc6193e451a1ad0ca31b78e85541c562766e7fb73fa7e"},
|
||||
{file = "specklepy-2.2.8-py3-none-any.whl", hash = "sha256:1fc27f563237b3acca628d983542434a86bb01be45ba11172a97671a93d1e0ae"},
|
||||
{file = "specklepy-2.2.8.tar.gz", hash = "sha256:8cdf016beb23d953a902af6997f4586ed14e8a6765d90da8ef4ba4af981a8ff8"},
|
||||
]
|
||||
svn = [
|
||||
{file = "svn-1.0.1.tar.gz", hash = "sha256:55f81f07853cc1d66d4800b0cfe2d3376ff02361a2b2361459dc22a0fab95247"},
|
||||
@@ -573,32 +595,43 @@ typing-extensions = [
|
||||
{file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.26.5-py2.py3-none-any.whl", hash = "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c"},
|
||||
{file = "urllib3-1.26.5.tar.gz", hash = "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"},
|
||||
{file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"},
|
||||
{file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"},
|
||||
]
|
||||
websockets = [
|
||||
{file = "websockets-8.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c"},
|
||||
{file = "websockets-8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170"},
|
||||
{file = "websockets-8.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8"},
|
||||
{file = "websockets-8.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb"},
|
||||
{file = "websockets-8.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5"},
|
||||
{file = "websockets-8.1-cp36-cp36m-win32.whl", hash = "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a"},
|
||||
{file = "websockets-8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5"},
|
||||
{file = "websockets-8.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989"},
|
||||
{file = "websockets-8.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d"},
|
||||
{file = "websockets-8.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779"},
|
||||
{file = "websockets-8.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8"},
|
||||
{file = "websockets-8.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422"},
|
||||
{file = "websockets-8.1-cp37-cp37m-win32.whl", hash = "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc"},
|
||||
{file = "websockets-8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308"},
|
||||
{file = "websockets-8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092"},
|
||||
{file = "websockets-8.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485"},
|
||||
{file = "websockets-8.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1"},
|
||||
{file = "websockets-8.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55"},
|
||||
{file = "websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824"},
|
||||
{file = "websockets-8.1-cp38-cp38-win32.whl", hash = "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36"},
|
||||
{file = "websockets-8.1-cp38-cp38-win_amd64.whl", hash = "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"},
|
||||
{file = "websockets-8.1.tar.gz", hash = "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f"},
|
||||
{file = "websockets-9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da"},
|
||||
{file = "websockets-9.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4"},
|
||||
{file = "websockets-9.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2cf04601633a4ec176b9cc3d3e73789c037641001dbfaf7c411f89cd3e04fcaf"},
|
||||
{file = "websockets-9.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:5c8f0d82ea2468282e08b0cf5307f3ad022290ed50c45d5cb7767957ca782880"},
|
||||
{file = "websockets-9.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:caa68c95bc1776d3521f81eeb4d5b9438be92514ec2a79fececda814099c8314"},
|
||||
{file = "websockets-9.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d2c2d9b24d3c65b5a02cac12cbb4e4194e590314519ed49db2f67ef561c3cf58"},
|
||||
{file = "websockets-9.1-cp36-cp36m-win32.whl", hash = "sha256:f31722f1c033c198aa4a39a01905951c00bd1c74f922e8afc1b1c62adbcdd56a"},
|
||||
{file = "websockets-9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:3ddff38894c7857c476feb3538dd847514379d6dc844961dc99f04b0384b1b1b"},
|
||||
{file = "websockets-9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:51d04df04ed9d08077d10ccbe21e6805791b78eac49d16d30a1f1fe2e44ba0af"},
|
||||
{file = "websockets-9.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f68c352a68e5fdf1e97288d5cec9296664c590c25932a8476224124aaf90dbcd"},
|
||||
{file = "websockets-9.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:b43b13e5622c5a53ab12f3272e6f42f1ce37cd5b6684b2676cb365403295cd40"},
|
||||
{file = "websockets-9.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9147868bb0cc01e6846606cd65cbf9c58598f187b96d14dd1ca17338b08793bb"},
|
||||
{file = "websockets-9.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:836d14eb53b500fd92bd5db2fc5894f7c72b634f9c2a28f546f75967503d8e25"},
|
||||
{file = "websockets-9.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:48c222feb3ced18f3dc61168ca18952a22fb88e5eb8902d2bf1b50faefdc34a2"},
|
||||
{file = "websockets-9.1-cp37-cp37m-win32.whl", hash = "sha256:900589e19200be76dd7cbaa95e9771605b5ce3f62512d039fb3bc5da9014912a"},
|
||||
{file = "websockets-9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ab5ee15d3462198c794c49ccd31773d8a2b8c17d622aa184f669d2b98c2f0857"},
|
||||
{file = "websockets-9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85e701a6c316b7067f1e8675c638036a796fe5116783a4c932e7eb8e305a3ffe"},
|
||||
{file = "websockets-9.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b2e71c4670ebe1067fa8632f0d081e47254ee2d3d409de54168b43b0ba9147e0"},
|
||||
{file = "websockets-9.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:230a3506df6b5f446fed2398e58dcaafdff12d67fe1397dff196411a9e820d02"},
|
||||
{file = "websockets-9.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:7df3596838b2a0c07c6f6d67752c53859a54993d4f062689fdf547cb56d0f84f"},
|
||||
{file = "websockets-9.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:826ccf85d4514609219725ba4a7abd569228c2c9f1968e8be05be366f68291ec"},
|
||||
{file = "websockets-9.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0dd4eb8e0bbf365d6f652711ce21b8fd2b596f873d32aabb0fbb53ec604418cc"},
|
||||
{file = "websockets-9.1-cp38-cp38-win32.whl", hash = "sha256:1d0971cc7251aeff955aa742ec541ee8aaea4bb2ebf0245748fbec62f744a37e"},
|
||||
{file = "websockets-9.1-cp38-cp38-win_amd64.whl", hash = "sha256:7189e51955f9268b2bdd6cc537e0faa06f8fffda7fb386e5922c6391de51b077"},
|
||||
{file = "websockets-9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9e5fd6dbdf95d99bc03732ded1fc8ef22ebbc05999ac7e0c7bf57fe6e4e5ae2"},
|
||||
{file = "websockets-9.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9e7fdc775fe7403dbd8bc883ba59576a6232eac96dacb56512daacf7af5d618d"},
|
||||
{file = "websockets-9.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:597c28f3aa7a09e8c070a86b03107094ee5cdafcc0d55f2f2eac92faac8dc67d"},
|
||||
{file = "websockets-9.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:ad893d889bc700a5835e0a95a3e4f2c39e91577ab232a3dc03c262a0f8fc4b5c"},
|
||||
{file = "websockets-9.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:1d6b4fddb12ab9adf87b843cd4316c4bd602db8d5efd2fb83147f0458fe85135"},
|
||||
{file = "websockets-9.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:ebf459a1c069f9866d8569439c06193c586e72c9330db1390af7c6a0a32c4afd"},
|
||||
{file = "websockets-9.1-cp39-cp39-win32.whl", hash = "sha256:be5fd35e99970518547edc906efab29afd392319f020c3c58b0e1a158e16ed20"},
|
||||
{file = "websockets-9.1-cp39-cp39-win_amd64.whl", hash = "sha256:85db8090ba94e22d964498a47fdd933b8875a1add6ebc514c7ac8703eb97bbf0"},
|
||||
{file = "websockets-9.1.tar.gz", hash = "sha256:276d2339ebf0df4f45df453923ebd2270b87900eda5dfd4a6b0cfa15f82111c3"},
|
||||
]
|
||||
yarl = [
|
||||
{file = "yarl-1.6.3-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434"},
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ license = "Apache-2.0"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.7,<3.8"
|
||||
specklepy = "^2.2.2"
|
||||
specklepy = "^2.2.8"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
devtools = "^0.6.1"
|
||||
|
||||
Reference in New Issue
Block a user