Compare commits
14 Commits
2.17.1
...
2.19.0-rc2
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e3c2ece2f | |||
| cfc58d9456 | |||
| a2f7ab422f | |||
| 8c58d9d14c | |||
| 90e61b6dc1 | |||
| 5c479e4c0e | |||
| 97d20ad7b1 | |||
| 2800b84747 | |||
| 511d69314e | |||
| 24e7f02213 | |||
| c1d7947085 | |||
| 21281e5d77 | |||
| 29bbdc69a2 | |||
| efe6e6a4a0 |
+37
-14
@@ -71,24 +71,44 @@ jobs:
|
||||
build-installer-win:
|
||||
executor:
|
||||
name: win/default
|
||||
shell: cmd.exe
|
||||
environment:
|
||||
SSM: 'C:\Program Files\DigiCert\DigiCert One Signing Manager Tools'
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ./
|
||||
- run:
|
||||
name: Patch installer
|
||||
shell: powershell.exe
|
||||
command: python patch_installer.py (Get-Content -Raw SEMVER)
|
||||
- run:
|
||||
name: Create Innosetup signing cert
|
||||
shell: powershell.exe
|
||||
command: |
|
||||
echo $env:PFX_B64 > "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt"
|
||||
certutil -decode "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt" "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.pfx"
|
||||
- run:
|
||||
name: Installer
|
||||
shell: cmd.exe #does not work in powershell
|
||||
command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\blender.iss /Sbyparam=$p
|
||||
- unless: # Build installers unsigned on non-tagged builds
|
||||
condition: << pipeline.git.tag >>
|
||||
steps:
|
||||
- run:
|
||||
name: Build Installer
|
||||
command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\blender.iss /Sbyparam=$p
|
||||
shell: cmd.exe #does not work in powershell
|
||||
- when: # Setup certificates and build installers signed for tagged builds
|
||||
condition: << pipeline.git.tag >>
|
||||
steps:
|
||||
- run:
|
||||
name: "Digicert Signing Manager Setup"
|
||||
command: |
|
||||
cd C:\
|
||||
curl.exe -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:$env:SM_API_KEY" -o smtools-windows-x64.msi
|
||||
msiexec.exe /i smtools-windows-x64.msi /quiet /qn | Wait-Process
|
||||
- run:
|
||||
name: Create Auth & OV Signing Cert
|
||||
command: |
|
||||
cd C:\
|
||||
echo $env:SM_CLIENT_CERT_FILE_B64 > certificate.txt
|
||||
certutil -decode certificate.txt certificate.p12
|
||||
- run:
|
||||
name: Sync Certs
|
||||
command: |
|
||||
& $env:SSM\smksp_cert_sync.exe
|
||||
- run:
|
||||
name: Build Installer
|
||||
command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\blender.iss /Sbyparam=$p /DSIGN_INSTALLER /DCODE_SIGNING_CERT_FINGERPRINT=%SM_CODE_SIGNING_CERT_SHA1_HASH%
|
||||
shell: cmd.exe #does not work in powershell
|
||||
- persist_to_workspace:
|
||||
root: ./
|
||||
paths:
|
||||
@@ -109,6 +129,9 @@ jobs:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: ./
|
||||
- run:
|
||||
name: Exit if External PR
|
||||
command: if [ "$CIRCLE_PR_REPONAME" ]; then circleci-agent step halt; fi
|
||||
- run:
|
||||
name: Install mono
|
||||
command: |
|
||||
@@ -214,7 +237,7 @@ workflows:
|
||||
filters: *build_filters
|
||||
|
||||
- build-installer-win:
|
||||
context: innosetup
|
||||
context: digicert-keylocker
|
||||
name: Windows Installer Build
|
||||
requires:
|
||||
- package-connector
|
||||
@@ -304,4 +327,4 @@ workflows:
|
||||
- Windows Installer Build
|
||||
- Mac Intel Build
|
||||
- Mac ARM Build
|
||||
filters: *deploy_filters
|
||||
filters: *deploy_filters
|
||||
|
||||
@@ -49,8 +49,7 @@ Head to the [**📚 documentation**](https://speckle.guide/user/blender.html) fo
|
||||
|
||||
## Installation
|
||||
|
||||
Currently, we are supporting all Blender 3.X versions on Windows and Mac.
|
||||
We have experimental support for Blender 4.0 and greater.
|
||||
We officially support Blender 3.3 and newer, on Windows and Mac.
|
||||
|
||||
Please follow our installation instructions on our [connector docs](https://speckle.guide/user/blender.html#installation)
|
||||
|
||||
@@ -59,10 +58,10 @@ Once enabled in `Preferences -> Addons`,
|
||||
The Speckle connector UI can be found in the 3d viewport toolbar (N), under the `Speckle` tab.
|
||||
|
||||
- Available user accounts are automatically detected and made available. To add user accounts use **Speckle Manager**.
|
||||
- Select the user from the dropdown list in the `Users` panel. This will populate the `Streams` list with available streams for the selected user.
|
||||
- Select a branch and commit from the dropdown menus.
|
||||
- Click on `Receive` to download the objects from the selected stream, branch, and commit. The stream objects will be loaded into a Blender Collection, named `<STREAM_NAME> [ <STREAM_BRANCH> @ <BRANCH_COMMIT> ]`. <!-- You can filter the stream by entering a query into the `Filter` field (i.e. `properties.weight>10` or `type="Mesh"`). -->
|
||||
- Click on `Open Stream in Web` to view the stream in your web browser.
|
||||
- Select the user from the dropdown list in the `Users` panel. This will populate the `Projects` list with available projects for the selected user account.
|
||||
- Select a model and version from the dropdown menus.
|
||||
- Click on `Receive` to download and convert the objects from the selected model version. The objects will be linked into a Blender Collection, named `<PROJECT_NAME> [ <MODEL_NAME> @ <VERSION_ID> ]`.
|
||||
- Click on `Open Model in Web` to view the model in your web browser.
|
||||
|
||||
## Supported Elements
|
||||
|
||||
@@ -77,7 +76,7 @@ The full matrix of supported Blender and Speckle types [can be found here](https
|
||||
|
||||
- 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.
|
||||
|
||||
- Receiving vertex colors are supported. The `colors` list from Speckle meshes is translated to a vertex color layer.
|
||||
- Receiving vertex colors is supported. The `colors` list from Speckle meshes is translated to a vertex color layer.
|
||||
|
||||
- Receive/Send scripts. Allow injecting a custom python function to the receive/send process to automate any blender operations
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class BlenderCommitObjectBuilder(CommitObjectBuilder[Object]):
|
||||
# Set the Child -> Parent relationships
|
||||
parent = native_object.parent
|
||||
|
||||
parent_collections: Tuple[Collection] = native_object.users_collection # type: ignore
|
||||
parent_collections = native_object.users_collection
|
||||
parent_collection = parent_collections[0] if len(parent_collections) > 0 else None #NOTE: we don't support objects appearing in more than one collection, for now, we will just take the zeroth one
|
||||
|
||||
app_id = _id(native_object)
|
||||
@@ -79,7 +79,7 @@ class BlenderCommitObjectBuilder(CommitObjectBuilder[Object]):
|
||||
# Create all collections
|
||||
root_col = self.ensure_collection(bpy.context.scene.collection)
|
||||
root_col.collectionType = "Scene Collection"
|
||||
for col in bpy.context.scene.collection.children_recursive: #type: ignore
|
||||
for col in bpy.context.scene.collection.children_recursive:
|
||||
self.ensure_collection(col)
|
||||
|
||||
objects_to_build = set(self.converted.values())
|
||||
|
||||
@@ -540,7 +540,7 @@ def transform_to_native(transform: Transform, scale: float) -> MMatrix:
|
||||
)
|
||||
# scale the translation
|
||||
for i in range(3):
|
||||
mat[i][3] *= scale # type: ignore
|
||||
mat[i][3] *= scale
|
||||
return mat
|
||||
|
||||
def plane_to_native_transform(plane: Plane, fallback_scale:float = 1) -> MMatrix:
|
||||
@@ -774,15 +774,21 @@ def _make_unique_name( desired_name: str, taken_names: Collection[str], counter:
|
||||
def _get_friendly_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)
|
||||
or _get_revit_family_name(speckle_object)
|
||||
)
|
||||
|
||||
def _get_revit_family_name(speckle_object: Base) -> Optional[str]:
|
||||
family = getattr(speckle_object, "family", None)
|
||||
family_type = getattr(speckle_object, "type", None)
|
||||
|
||||
if family and family_type:
|
||||
return f"{family_type}-{family}"
|
||||
else:
|
||||
return 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
|
||||
|
||||
|
||||
def _truncate_object_name(name: str) -> str:
|
||||
|
||||
MAX_NAME_LENGTH = OBJECT_NAME_MAX_LENGTH - SPECKLE_ID_LENGTH - len(OBJECT_NAME_SPECKLE_SEPARATOR)
|
||||
|
||||
@@ -101,7 +101,7 @@ def mesh_to_speckle_meshes(blender_object: Object, data: bpy.types.Mesh) -> List
|
||||
submesh_data[p.material_index].append(p)
|
||||
|
||||
transform = cast(MMatrix, blender_object.matrix_world)
|
||||
scaled_vertices = [tuple(transform @ x.co * UnitsScale) for x in data.vertices] # type: ignore
|
||||
scaled_vertices = [tuple(transform @ x.co * UnitsScale) for x in data.vertices]
|
||||
|
||||
# Create Speckle meshes for each material
|
||||
submeshes = []
|
||||
@@ -445,8 +445,8 @@ def camera_to_speckle_view(blender_object: Object, data: NCamera) -> Base:
|
||||
raise Exception(f"Cameras of type {data.type} are not currently supported")
|
||||
|
||||
matrix = cast(MMatrix, blender_object.matrix_world)
|
||||
up = matrix.col[1].xyz # type: ignore
|
||||
forwards = -matrix.col[2].xyz # type: ignore
|
||||
up = cast(MVector, matrix.col[1].xyz)
|
||||
forwards = cast(MVector, -matrix.col[2].xyz)
|
||||
translation = matrix.translation
|
||||
|
||||
view = Base.of_type("Objects.BuiltElements.View:Objects.BuiltElements.View3D") #HACK: views are not in specklepy yet!
|
||||
|
||||
@@ -168,7 +168,7 @@ def add_faces(speckle_mesh: Mesh, blender_mesh: BMesh, indexOffset: int, materia
|
||||
i += 1
|
||||
try:
|
||||
f = blender_mesh.faces.new(
|
||||
[blender_mesh.verts[x + indexOffset] for x in sfaces[i : i + n]] # type: ignore
|
||||
[blender_mesh.verts[x + indexOffset] for x in sfaces[i : i + n]]
|
||||
)
|
||||
f.material_index = materialIndex
|
||||
f.smooth = smooth
|
||||
@@ -198,10 +198,10 @@ def add_colors(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
)
|
||||
|
||||
# Make vertex colors
|
||||
if len(scolors) == len(blender_mesh.verts): # type: ignore
|
||||
if len(scolors) == len(blender_mesh.verts):
|
||||
color_layer = blender_mesh.loops.layers.color.new("Col")
|
||||
|
||||
for face in blender_mesh.faces: # type: ignore
|
||||
for face in blender_mesh.faces:
|
||||
for loop in face.loops:
|
||||
loop[color_layer] = colors[loop.vert.index]
|
||||
|
||||
@@ -220,21 +220,21 @@ def add_uv_coords(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
try:
|
||||
uv = []
|
||||
|
||||
if len(s_uvs) // 2 == len(blender_mesh.verts): # type: ignore
|
||||
if len(s_uvs) // 2 == len(blender_mesh.verts):
|
||||
uv.extend(
|
||||
(float(s_uvs[i]), float(s_uvs[i + 1]))
|
||||
for i in range(0, len(s_uvs), 2)
|
||||
)
|
||||
else:
|
||||
_report(
|
||||
f"Failed to match UV coordinates to vert data. Blender mesh verts: {len(blender_mesh.verts)}, Speckle UVs: {len(s_uvs) // 2}" # type: ignore
|
||||
f"Failed to match UV coordinates to vert data. Blender mesh verts: {len(blender_mesh.verts)}, Speckle UVs: {len(s_uvs) // 2}"
|
||||
)
|
||||
return
|
||||
|
||||
# Make UVs
|
||||
uv_layer = blender_mesh.loops.layers.uv.verify()
|
||||
|
||||
for f in blender_mesh.faces: # type: ignore
|
||||
for f in blender_mesh.faces:
|
||||
for l in f.loops:
|
||||
luv = l[uv_layer]
|
||||
luv.uv = uv[l.vert.index]
|
||||
@@ -450,7 +450,7 @@ def link_object_to_collection_nested(obj: Object, col: BCollection):
|
||||
if obj.name not in col.objects: #type: ignore
|
||||
col.objects.link(obj)
|
||||
|
||||
for child in obj.children: #type: ignore
|
||||
for child in obj.children:
|
||||
link_object_to_collection_nested(child, col)
|
||||
|
||||
def add_to_hierarchy(converted: Union[Object, BCollection], traversalContext : 'TraversalContext', converted_objects: Dict[str, Union[Object, BCollection]], preserve_transform: bool) -> None:
|
||||
|
||||
@@ -156,7 +156,12 @@ def install_requirements(host_application: str) -> None:
|
||||
PYTHON_PATH,
|
||||
"-m",
|
||||
"pip",
|
||||
"-q",
|
||||
"--disable-pip-version-check",
|
||||
"install",
|
||||
"--prefer-binary",
|
||||
"--ignore-installed",
|
||||
"--no-compile",
|
||||
"-t",
|
||||
str(path),
|
||||
"-r",
|
||||
|
||||
@@ -20,6 +20,7 @@ from .streams import (
|
||||
CopyStreamId,
|
||||
CopyCommitId,
|
||||
CopyBranchName,
|
||||
CopyModelId,
|
||||
)
|
||||
from .commit import DeleteCommit
|
||||
from .misc import OpenSpeckleGuide, OpenSpeckleTutorials, OpenSpeckleForum
|
||||
@@ -33,6 +34,7 @@ operator_classes = [
|
||||
CopyStreamId,
|
||||
CopyCommitId,
|
||||
CopyBranchName,
|
||||
CopyModelId,
|
||||
]
|
||||
|
||||
operator_classes.extend([DeleteCommit])
|
||||
|
||||
@@ -4,25 +4,26 @@ Commit operators
|
||||
import bpy
|
||||
from bpy.props import BoolProperty
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.properties.scene import get_speckle
|
||||
from specklepy.logging import metrics
|
||||
|
||||
|
||||
class DeleteCommit(bpy.types.Operator):
|
||||
"""
|
||||
Deletes the selected commit from the selected stream.
|
||||
Permanently deletes the selected version from the selected model.
|
||||
To execute from code, call: `bpy.ops.speckle.delete_commit(are_you_sure=True)`
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.delete_commit"
|
||||
bl_label = "Delete commit"
|
||||
bl_label = "Delete Version"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Delete active commit permanently"
|
||||
bl_description = "Permanently Deletes the selected version from the selected model"
|
||||
|
||||
are_you_sure: BoolProperty(
|
||||
name="Confirm",
|
||||
default=False,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -38,23 +39,19 @@ class DeleteCommit(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.delete_commit(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
print(f"{self.bl_idname}: failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
|
||||
def delete_commit(self, context: bpy.types.Context) -> None:
|
||||
|
||||
if not self.are_you_sure:
|
||||
raise Exception("Cancelled by user")
|
||||
|
||||
_report("Cancelled by user")
|
||||
return {"CANCELLED"}
|
||||
self.are_you_sure = False
|
||||
|
||||
self.delete_commit(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
@staticmethod
|
||||
def delete_commit(context: bpy.types.Context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, stream, _, commit) = speckle.validate_commit_selection()
|
||||
(_, stream, branch, commit) = speckle.validate_commit_selection()
|
||||
|
||||
client = speckle_clients[int(speckle.active_user)]
|
||||
|
||||
@@ -71,5 +68,5 @@ class DeleteCommit(bpy.types.Operator):
|
||||
if not deleted:
|
||||
raise Exception("Delete operation failed")
|
||||
|
||||
print(f"{self.bl_idname}: succeeded - commit {commit.id} ({commit.message}) has been deleted from stream {stream.id}")
|
||||
print(f"Version {commit.id} ({commit.message}) of model {branch.id} ({branch.name}) has been deleted from project {stream.id} ({stream.name})")
|
||||
|
||||
|
||||
@@ -3,14 +3,18 @@ import webbrowser
|
||||
from specklepy.logging import metrics
|
||||
|
||||
|
||||
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"
|
||||
|
||||
|
||||
class OpenSpeckleGuide(bpy.types.Operator):
|
||||
_guide_url = "https://speckle.guide/user/blender.html"
|
||||
|
||||
bl_idname = "speckle.open_speckle_guide"
|
||||
bl_label = "Speckle Docs"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = f"Browse the documentation on the Speckle Guide ({_guide_url})"
|
||||
|
||||
def execute(self, context):
|
||||
webbrowser.open("https://speckle.guide/user/blender.html")
|
||||
webbrowser.open(self._guide_url)
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
None,
|
||||
@@ -22,13 +26,15 @@ class OpenSpeckleGuide(bpy.types.Operator):
|
||||
|
||||
|
||||
class OpenSpeckleTutorials(bpy.types.Operator):
|
||||
_tutorials_url = "https://speckle.systems/tutorials/"
|
||||
|
||||
bl_idname = "speckle.open_speckle_tutorials"
|
||||
bl_label = "Tutorials Portal"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Visit our tutorials portal for learning resources"
|
||||
bl_description = f"Visit our tutorials portal for learning resources ({_tutorials_url})"
|
||||
|
||||
def execute(self, context):
|
||||
webbrowser.open("https://speckle.systems/tutorials/")
|
||||
webbrowser.open(self._tutorials_url)
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
None,
|
||||
@@ -40,13 +46,15 @@ class OpenSpeckleTutorials(bpy.types.Operator):
|
||||
|
||||
|
||||
class OpenSpeckleForum(bpy.types.Operator):
|
||||
_forum_url = "https://speckle.community/"
|
||||
|
||||
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"
|
||||
bl_description = f"Ask questions and join the discussion on our community forum ({_forum_url})"
|
||||
|
||||
def execute(self, context):
|
||||
webbrowser.open("https://speckle.community/")
|
||||
webbrowser.open(self._forum_url)
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
None,
|
||||
|
||||
@@ -13,6 +13,7 @@ from bpy_speckle.functions import get_scale_length, _report
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from specklepy.logging import metrics
|
||||
|
||||
@deprecated
|
||||
class UpdateObject(bpy.types.Operator):
|
||||
"""
|
||||
Update local (receive) or remote (send) object depending on
|
||||
@@ -21,7 +22,7 @@ class UpdateObject(bpy.types.Operator):
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.update_object"
|
||||
bl_label = "Update Object"
|
||||
bl_label = "Update Object (DEPRECATED)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
client = None
|
||||
@@ -68,14 +69,14 @@ class UpdateObject(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
@deprecated
|
||||
class ResetObject(bpy.types.Operator):
|
||||
"""
|
||||
Reset Speckle object settings
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.reset_object"
|
||||
bl_label = "Reset Object"
|
||||
bl_label = "Reset Object (DEPRECATED)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
@@ -96,14 +97,14 @@ class ResetObject(bpy.types.Operator):
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@deprecated
|
||||
class DeleteObject(bpy.types.Operator):
|
||||
"""
|
||||
Delete object from the server and update relevant stream
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.delete_object"
|
||||
bl_label = "Delete Object"
|
||||
bl_label = "Delete Object (DEPRECATED)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
@@ -158,7 +159,7 @@ class UploadNgonsAsPolylines(bpy.types.Operator):
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.upload_ngons_as_polylines"
|
||||
bl_label = "Upload Ngons As Polylines"
|
||||
bl_label = "Upload Ngons As Polylines (DEPRECATED)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
clear_stream: BoolProperty(
|
||||
@@ -247,7 +248,7 @@ def get_custom_speckle_props(self, context):
|
||||
|
||||
return [(x, "{}".format(x), "") for x in active.keys()]
|
||||
|
||||
|
||||
@deprecated
|
||||
class SelectIfSameCustomProperty(bpy.types.Operator):
|
||||
"""
|
||||
Select scene objects if they have the same custom property
|
||||
@@ -255,7 +256,7 @@ class SelectIfSameCustomProperty(bpy.types.Operator):
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.select_if_same_custom_props"
|
||||
bl_label = "Select Identical Custom Props"
|
||||
bl_label = "Select Identical Custom Props (DEPRECATED)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
custom_prop: EnumProperty(
|
||||
@@ -307,7 +308,7 @@ class SelectIfSameCustomProperty(bpy.types.Operator):
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@deprecated
|
||||
class SelectIfHasCustomProperty(bpy.types.Operator):
|
||||
"""
|
||||
Select scene objects if they have the same custom property
|
||||
@@ -315,7 +316,7 @@ class SelectIfHasCustomProperty(bpy.types.Operator):
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.select_if_has_custom_props"
|
||||
bl_label = "Select Same Custom Prop"
|
||||
bl_label = "Select Same Custom Prop (DEPRECATED)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
custom_prop: EnumProperty(
|
||||
|
||||
+276
-199
@@ -2,7 +2,7 @@
|
||||
Stream operators
|
||||
"""
|
||||
from math import radians
|
||||
from typing import Callable, Dict, Optional, Union, cast
|
||||
from typing import Callable, Dict, Optional, Tuple, Union, cast
|
||||
import webbrowser
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
@@ -15,6 +15,7 @@ from bpy.types import (
|
||||
Object,
|
||||
Collection
|
||||
)
|
||||
from deprecated import deprecated
|
||||
from bpy_speckle.blender_commit_object_builder import BlenderCommitObjectBuilder
|
||||
from bpy_speckle.convert.to_native import (
|
||||
can_convert_to_native,
|
||||
@@ -31,8 +32,8 @@ from bpy_speckle.functions import (
|
||||
get_scale_length,
|
||||
)
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.operators.users import add_user_stream
|
||||
from bpy_speckle.properties.scene import SpeckleSceneSettings, SpeckleUserObject, get_speckle
|
||||
from bpy_speckle.operators.users import LoadUserStreams, add_user_stream
|
||||
from bpy_speckle.properties.scene import SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle
|
||||
from bpy_speckle.convert.util import ConversionSkippedException, add_to_hierarchy
|
||||
from specklepy.core.api.models import Commit
|
||||
from specklepy.core.api import operations, host_applications
|
||||
@@ -80,19 +81,18 @@ INSTANCES_SETTINGS = [
|
||||
|
||||
class ReceiveStreamObjects(bpy.types.Operator):
|
||||
"""
|
||||
Receive stream objects
|
||||
Receive objects from selected model version
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.receive_stream_objects"
|
||||
bl_label = "Download Stream Objects"
|
||||
bl_label = "Receive"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Receive objects from active stream"
|
||||
bl_description = "Receive objects from selected model version"
|
||||
|
||||
|
||||
clean_meshes: BoolProperty(name="Clean Meshes", default=False)
|
||||
clean_meshes: BoolProperty(name="Clean Meshes", default=False) # type: ignore
|
||||
|
||||
#receive_mode: EnumProperty(items=RECEIVE_MODES, name="Receive Type", default="replace", description="The behaviour of the receive operation")
|
||||
receive_instances_as: EnumProperty(items=INSTANCES_SETTINGS, name="Receive Instances As", default="collection_instance", description="How to receive speckle Instances")
|
||||
receive_instances_as: EnumProperty(items=INSTANCES_SETTINGS, name="Receive Instances As", default="collection_instance", description="How to receive speckle Instances") # type: ignore
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
@@ -130,23 +130,19 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
# Reset state to previous (not quite sure if this is 100% necessary)
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = None
|
||||
bpy.context.view_layer.objects.active = None # type: ignore
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.receive(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"Failed to receive objects: {type(ex)} {ex}")
|
||||
return {"CANCELLED"}
|
||||
self.receive(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
def receive(self, context: Context) -> None:
|
||||
bpy.context.view_layer.objects.active = None
|
||||
bpy.context.view_layer.objects.active = None # type: ignore
|
||||
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(user, stream, branch, commit) = speckle.validate_commit_selection()
|
||||
|
||||
|
||||
client = speckle_clients[int(speckle.active_user)]
|
||||
|
||||
transport = ServerTransport(stream.id, client)
|
||||
@@ -157,7 +153,7 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
stream.id,
|
||||
commit.id,
|
||||
source_application="blender",
|
||||
message="received commit from Speckle Blender",
|
||||
message="Received model version from Speckle Blender",
|
||||
)
|
||||
|
||||
metrics.track(
|
||||
@@ -193,7 +189,7 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
|
||||
# ensure commit object has a name if not already
|
||||
if not commit_object.name:
|
||||
commit_object.name = "{} [ {} @ {} ]".format(stream.name, branch.name, commit.id) # Matches Rhino "Create" naming
|
||||
commit_object.name = f"{stream.name} [ {branch.name} @ {commit.id} ]" # Matches Rhino "Create" naming
|
||||
|
||||
for item in traversalFunc.traverse(commit_object):
|
||||
|
||||
@@ -201,7 +197,8 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
|
||||
if can_convert_to_native(current) or isinstance(current, SCollection):
|
||||
try:
|
||||
if not current or not current.id: raise Exception(f"{current} was an invalid speckle object")
|
||||
if not current or not current.id:
|
||||
raise Exception(f"{current} was an invalid Speckle object")
|
||||
|
||||
#Convert the object!
|
||||
converted_data_type: str
|
||||
@@ -248,19 +245,19 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
|
||||
class SendStreamObjects(bpy.types.Operator):
|
||||
"""
|
||||
Send stream objects
|
||||
Send selected objects to selected model
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.send_stream_objects"
|
||||
bl_label = "Send stream objects"
|
||||
bl_label = "Send"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Send selected objects to active stream"
|
||||
bl_description = "Send selected objects to selected model"
|
||||
|
||||
apply_modifiers: BoolProperty(name="Apply modifiers", default=True)
|
||||
apply_modifiers: BoolProperty(name="Apply modifiers", default=True) # type: ignore
|
||||
commit_message: StringProperty(
|
||||
name="Message",
|
||||
default="Pushed elements from Blender.",
|
||||
)
|
||||
default="Sent elements from Blender.",
|
||||
) # type: ignore
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -270,23 +267,22 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
if len(context.scene.speckle.users) <= 0: return {"CANCELLED"}
|
||||
|
||||
speckle = get_speckle(context)
|
||||
if len(speckle.users) <= 0:
|
||||
_report("No user accounts")
|
||||
return {"CANCELLED"}
|
||||
|
||||
N = len(context.selected_objects)
|
||||
if N == 1:
|
||||
self.commit_message = f"Pushed {N} element from Blender."
|
||||
self.commit_message = f"Sent {N} element from Blender."
|
||||
else:
|
||||
self.commit_message = f"Pushed {N} elements from Blender."
|
||||
self.commit_message = f"Sent {N} elements from Blender."
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.send(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"Send failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
self.send(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
def send(self, context: Context) -> None:
|
||||
|
||||
@@ -376,7 +372,13 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
message=self.commit_message,
|
||||
source_application="blender",
|
||||
)
|
||||
_report(f"Commit Created {user.server_url}/streams/{stream.id}/commits/{COMMIT_ID}")
|
||||
|
||||
if client.account.serverInfo.frontend2:
|
||||
sent_url = f"{user.server_url}/projects/{stream.id}/models/{branch.id}@{COMMIT_ID}"
|
||||
else:
|
||||
sent_url = f"{user.server_url}/streams/{stream.id}/commits/{COMMIT_ID}"
|
||||
|
||||
_report(f"Commit Created {sent_url}")
|
||||
|
||||
bpy.ops.speckle.load_user_streams() # refresh loaded commits
|
||||
context.view_layer.update()
|
||||
@@ -388,25 +390,23 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
|
||||
class ViewStreamDataApi(bpy.types.Operator):
|
||||
bl_idname = "speckle.view_stream_data_api"
|
||||
bl_label = "Open Stream in Web"
|
||||
bl_label = "Open Model in Web"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "View the stream in the web browser"
|
||||
bl_description = "View the selected model in the web browser"
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.view_stream_data_api(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
self.view_stream_data_api(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
def view_stream_data_api(self, context: Context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(user, stream) = speckle.validate_stream_selection()
|
||||
url = self._get_url_from_selection(speckle)
|
||||
|
||||
_report(f"Opening {url} in web browser")
|
||||
|
||||
if not webbrowser.open("%s/streams/%s" % (user.server_url, stream.id), new=2):
|
||||
raise Exception("Failed to open stream in browser")
|
||||
if not webbrowser.open(url, new=2):
|
||||
raise Exception(f"Failed to open model in browser ({url})")
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
@@ -416,19 +416,41 @@ class ViewStreamDataApi(bpy.types.Operator):
|
||||
},
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _get_url_from_selection(speckleScene : SpeckleSceneSettings) -> str:
|
||||
|
||||
client = speckle_clients[int(speckleScene.active_user)]
|
||||
(user, stream) = speckleScene.validate_stream_selection()
|
||||
branch = stream.get_active_branch()
|
||||
commit = branch.get_active_commit() if branch else None
|
||||
|
||||
if client.account.serverInfo.frontend2:
|
||||
server_url = f"{user.server_url}/projects/{stream.id}/"
|
||||
if branch:
|
||||
server_url += f"models/{branch.id}"
|
||||
if commit:
|
||||
server_url += f"@{commit.id}"
|
||||
else:
|
||||
server_url = f"{user.server_url}/streams/{stream.id}/"
|
||||
if commit:
|
||||
server_url += f"commits/{commit.id}"
|
||||
elif branch:
|
||||
server_url += f"branches/{branch.name}"
|
||||
|
||||
return server_url
|
||||
|
||||
class AddStreamFromURL(bpy.types.Operator):
|
||||
"""
|
||||
Add / select a stream using its url
|
||||
Add / select an existing project by providing its URL
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.add_stream_from_url"
|
||||
bl_label = "Add stream from URL"
|
||||
bl_label = "Add Project From URL"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Add an existing stream by providing its URL"
|
||||
bl_description = "Add / select an existing project by providing its URL"
|
||||
stream_url: StringProperty(
|
||||
name="Stream URL", default="https://speckle.xyz/streams/3073b96e86"
|
||||
)
|
||||
name="Project URL", default=""
|
||||
) # type: ignore
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -444,13 +466,26 @@ class AddStreamFromURL(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.add_stream_from_url(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
self.add_stream_from_url(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
@staticmethod
|
||||
def _get_or_add_stream(user : SpeckleUserObject, stream : Stream) -> Tuple[int, SpeckleStreamObject]:
|
||||
index, b_stream = next(
|
||||
((i, cast(SpeckleStreamObject, s)) for i, s in enumerate(user.streams) if s.id == stream.id),
|
||||
(None, None),
|
||||
)
|
||||
|
||||
if index is not None:
|
||||
assert(b_stream)
|
||||
return (index, b_stream)
|
||||
|
||||
add_user_stream(user, stream)
|
||||
return next(
|
||||
(i, cast(SpeckleStreamObject, s)) for i, s in enumerate(user.streams) if s.id == stream.id
|
||||
)
|
||||
|
||||
|
||||
def add_stream_from_url(self, context: Context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
@@ -460,28 +495,20 @@ class AddStreamFromURL(bpy.types.Operator):
|
||||
None,
|
||||
)
|
||||
if user_index is None:
|
||||
raise Exception("Unable to find user stream server")
|
||||
raise Exception(f"No user account credentials for {wrapper.host}, have you added your account in Manager?")
|
||||
|
||||
speckle.active_user = str(user_index)
|
||||
user = cast(SpeckleUserObject, speckle.users[user_index])
|
||||
|
||||
client = speckle_clients[user_index]
|
||||
stream = client.stream.get(wrapper.stream_id, branch_limit=20)
|
||||
stream = client.stream.get(wrapper.stream_id, branch_limit=LoadUserStreams.branch_limit, commit_limit=LoadUserStreams.commits_limit)
|
||||
if not isinstance(stream, Stream):
|
||||
raise SpeckleException("Could not get the requested stream")
|
||||
raise SpeckleException(f"Could not get the requested project {wrapper.stream_id}")
|
||||
|
||||
index, b_stream = next(
|
||||
((i, s) for i, s in enumerate(user.streams) if s.id == stream.id),
|
||||
(None, None),
|
||||
)
|
||||
(index, b_stream) = self._get_or_add_stream(user, stream)
|
||||
user.active_stream = index
|
||||
|
||||
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
|
||||
_report(f"Selecting project at index {index} ({b_stream.id} - {b_stream.name})")
|
||||
|
||||
if wrapper.branch_name:
|
||||
b_index = b_stream.branches.find(wrapper.branch_name)
|
||||
@@ -513,18 +540,18 @@ class AddStreamFromURL(bpy.types.Operator):
|
||||
|
||||
class CreateStream(bpy.types.Operator):
|
||||
"""
|
||||
Create new stream
|
||||
Create a new Speckle project using the selected user account
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.create_stream"
|
||||
bl_label = "Create stream"
|
||||
bl_label = "Create Project"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Create new stream"
|
||||
bl_description = "Create a new Speckle project using the selected user account"
|
||||
|
||||
stream_name: StringProperty(name="Stream name")
|
||||
stream_name: StringProperty(name="Project name") # type: ignore
|
||||
stream_description: StringProperty(
|
||||
name="Stream description", default="This is a Blender stream."
|
||||
)
|
||||
name="Project description", default="My new project"
|
||||
) # type: ignore
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -541,12 +568,8 @@ class CreateStream(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.create_stream(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
self.create_stream(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
def create_stream(self, context: Context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
@@ -579,22 +602,24 @@ class CreateStream(bpy.types.Operator):
|
||||
)
|
||||
|
||||
|
||||
@deprecated
|
||||
class DeleteStream(bpy.types.Operator):
|
||||
"""
|
||||
Delete stream
|
||||
Permanently delete the selected project
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.delete_stream"
|
||||
bl_label = "Delete stream"
|
||||
bl_label = "Delete Project"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Delete selected stream permanently"
|
||||
bl_description = "Permanently delete the selected project"
|
||||
|
||||
are_you_sure: BoolProperty(
|
||||
name="Confirm",
|
||||
description="⚠ This action will delete your entire stream permanently ⚠",
|
||||
default=False,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
delete_collection: BoolProperty(name="Delete collection", default=False)
|
||||
delete_collection: BoolProperty(name="Delete collection", default=False) # type: ignore
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -611,19 +636,16 @@ class DeleteStream(bpy.types.Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.delete_stream(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
|
||||
def delete_stream(self, context: Context) -> None:
|
||||
if not self.are_you_sure:
|
||||
raise Exception("Cancelled by user")
|
||||
|
||||
_report(f"Cancelled by user - are_you_sure was {self.are_you_sure}")
|
||||
return {"CANCELLED"}
|
||||
self.are_you_sure = False
|
||||
|
||||
self.delete_stream(context, self.delete_collection)
|
||||
return {"FINISHED"}
|
||||
|
||||
@staticmethod
|
||||
def delete_stream(context: Context, delete_collection: bool) -> None:
|
||||
speckle = get_speckle(context)
|
||||
(_, stream) = speckle.validate_stream_selection()
|
||||
|
||||
@@ -631,7 +653,8 @@ class DeleteStream(bpy.types.Operator):
|
||||
|
||||
client.stream.delete(id=stream.id)
|
||||
|
||||
if self.delete_collection:
|
||||
if delete_collection:
|
||||
# This may not work anymore since we changed the collection naming...
|
||||
col_name = "SpeckleStream_{}_{}".format(stream.name, stream.id)
|
||||
if col_name in bpy.data.collections:
|
||||
collection = bpy.data.collections[col_name]
|
||||
@@ -651,7 +674,157 @@ class DeleteStream(bpy.types.Operator):
|
||||
},
|
||||
)
|
||||
|
||||
@deprecated
|
||||
class SelectOrphanObjects(bpy.types.Operator):
|
||||
"""
|
||||
Select Speckle objects that don't belong to any stream
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.select_orphans"
|
||||
bl_label = "Select Orphaned Objects (DEPRECATED)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Select Speckle objects that don't belong to any stream"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
for o in context.scene.objects:
|
||||
if (
|
||||
o.speckle.stream_id
|
||||
and o.speckle.stream_id not in context.scene["speckle_streams"]
|
||||
):
|
||||
o.select = True
|
||||
else:
|
||||
o.select = False
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "SelectOrphanObjects"
|
||||
},
|
||||
)
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
class CopyStreamId(bpy.types.Operator):
|
||||
"""
|
||||
Copy the selected project id to clipboard
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.stream_copy_id"
|
||||
bl_label = "Copy Project Id"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy the selected project id to clipboard"
|
||||
|
||||
def execute(self, context):
|
||||
self.copy_stream_id(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
def copy_stream_id(self, context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, stream) = speckle.validate_stream_selection()
|
||||
bpy.context.window_manager.clipboard = stream.id
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "copy_stream_id"
|
||||
},
|
||||
)
|
||||
|
||||
class CopyCommitId(bpy.types.Operator):
|
||||
"""
|
||||
Copy the selected version id to clipboard
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.commit_copy_id"
|
||||
bl_label = "Copy Version Id"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy the selected version id to clipboard"
|
||||
|
||||
def execute(self, context):
|
||||
self.copy_commit_id(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
def copy_commit_id(self, context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, _, _, commit) = speckle.validate_commit_selection()
|
||||
bpy.context.window_manager.clipboard = commit.id
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "copy_commit_id"
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CopyModelId(bpy.types.Operator):
|
||||
"""
|
||||
Copy model id to clipboard
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.model_copy_id"
|
||||
bl_label = "Copy model id"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy model id to clipboard"
|
||||
|
||||
def execute(self, context):
|
||||
self.copy_model_id(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
def copy_model_id(self, context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, _, branch) = speckle.validate_branch_selection()
|
||||
|
||||
bpy.context.window_manager.clipboard = branch.id
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "copy_branch_id"
|
||||
},
|
||||
)
|
||||
|
||||
@deprecated
|
||||
class CopyBranchName(bpy.types.Operator):
|
||||
"""
|
||||
Copy branch name to clipboard
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.branch_copy_name"
|
||||
bl_label = "Copy branch name"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy branch name to clipboard"
|
||||
|
||||
def execute(self, context):
|
||||
self.copy_branch_id(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
def copy_branch_id(self, context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, _, branch) = speckle.validate_branch_selection()
|
||||
|
||||
bpy.context.window_manager.clipboard = branch.name
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "copy_branch_id"
|
||||
},
|
||||
)
|
||||
|
||||
@deprecated
|
||||
class SelectOrphanObjects(bpy.types.Operator):
|
||||
"""
|
||||
Select Speckle objects that don't belong to any stream
|
||||
@@ -683,100 +856,4 @@ class SelectOrphanObjects(bpy.types.Operator):
|
||||
},
|
||||
)
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
class CopyStreamId(bpy.types.Operator):
|
||||
"""
|
||||
Copy stream ID to clipboard
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.stream_copy_id"
|
||||
bl_label = "Copy stream ID"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy stream ID to clipboard"
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.copy_stream_id(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
|
||||
def copy_stream_id(self, context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, stream) = speckle.validate_stream_selection()
|
||||
bpy.context.window_manager.clipboard = stream.id
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "copy_stream_id"
|
||||
},
|
||||
)
|
||||
|
||||
class CopyCommitId(bpy.types.Operator):
|
||||
"""
|
||||
Copy commit ID to clipboard
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.commit_copy_id"
|
||||
bl_label = "Copy commit ID"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy commit ID to clipboard"
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.copy_commit_id(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
|
||||
def copy_commit_id(self, context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, _, _, commit) = speckle.validate_commit_selection()
|
||||
bpy.context.window_manager.clipboard = commit.id
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "copy_commit_id"
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CopyBranchName(bpy.types.Operator):
|
||||
"""
|
||||
Copy branch name to clipboard
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.branch_copy_name"
|
||||
bl_label = "Copy branch name"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy branch name to clipboard"
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.copy_branch_id(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
|
||||
def copy_branch_id(self, context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
|
||||
(_, _, branch) = speckle.validate_branch_selection()
|
||||
|
||||
bpy.context.window_manager.clipboard = branch.name
|
||||
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
custom_props={
|
||||
"name": "copy_branch_id"
|
||||
},
|
||||
)
|
||||
return {"FINISHED"}
|
||||
@@ -1,12 +1,12 @@
|
||||
"""
|
||||
User account operators
|
||||
"""
|
||||
from typing import cast
|
||||
from typing import List, cast
|
||||
import bpy
|
||||
from bpy.types import Context
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.properties.scene import SpeckleCommitObject, SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle
|
||||
from bpy_speckle.properties.scene import SpeckleBranchObject, SpeckleCommitObject, SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle
|
||||
from specklepy.core.api.client import SpeckleClient
|
||||
from specklepy.core.api.models import Stream
|
||||
from specklepy.core.api.credentials import get_local_accounts, Account
|
||||
@@ -18,7 +18,7 @@ class ResetUsers(bpy.types.Operator):
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.users_reset"
|
||||
bl_label = "Reset users"
|
||||
bl_label = "Reset Users"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
@@ -46,18 +46,20 @@ class ResetUsers(bpy.types.Operator):
|
||||
|
||||
class LoadUsers(bpy.types.Operator):
|
||||
"""
|
||||
Load all users from local user database
|
||||
Loads all user accounts from the credentials in the local database.
|
||||
See docs to add accounts via Manager
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.users_load"
|
||||
bl_label = "Load users"
|
||||
bl_label = "Load Users"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Loads all user accounts from the credentials in the local database.\nSee docs to add accounts via Manager"
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
_report("Loading users...")
|
||||
|
||||
speckle = cast(SpeckleSceneSettings, context.scene.speckle) #type: ignore
|
||||
speckle = get_speckle(context)
|
||||
users_list = speckle.users
|
||||
|
||||
ResetUsers.reset_ui(context)
|
||||
@@ -133,13 +135,17 @@ def add_user_stream(user: SpeckleUserObject, stream: Stream):
|
||||
s.id = stream.id
|
||||
s.description = stream.description
|
||||
|
||||
_report(f"Adding stream {s.id} - {s.name}")
|
||||
|
||||
if not stream.branches:
|
||||
return
|
||||
|
||||
# branches = [branch for branch in stream.branches.items if branch.name != "globals"]
|
||||
for b in stream.branches.items:
|
||||
branch = s.branches.add()
|
||||
branch = cast(SpeckleBranchObject, s.branches.add())
|
||||
branch.name = b.name
|
||||
branch.id = b.id
|
||||
branch.description = b.description or ""
|
||||
|
||||
if not b.commits:
|
||||
continue
|
||||
@@ -154,32 +160,25 @@ def add_user_stream(user: SpeckleUserObject, stream: Stream):
|
||||
commit.source_application = str(c.sourceApplication)
|
||||
commit.referenced_object = c.referencedObject
|
||||
|
||||
if hasattr(s, "baseProperties"):
|
||||
s.units = stream.baseProperties.units # type: ignore
|
||||
else:
|
||||
s.units = "Meters"
|
||||
|
||||
|
||||
class LoadUserStreams(bpy.types.Operator):
|
||||
"""
|
||||
Load all available streams for active user
|
||||
(Re)Load all available projects for active user
|
||||
"""
|
||||
|
||||
bl_idname = "speckle.load_user_streams"
|
||||
bl_label = "Load user streams"
|
||||
bl_label = "Load User's Projects"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "(Re)load all available user streams"
|
||||
bl_description = "(Re)Load all available projects for active user"
|
||||
|
||||
stream_limit: int = 20
|
||||
branch_limit: int = 100
|
||||
commits_limit: int = 10
|
||||
|
||||
def execute(self, context):
|
||||
try:
|
||||
self.load_user_stream(context)
|
||||
return {"FINISHED"}
|
||||
except Exception as ex:
|
||||
_report(f"{self.bl_idname} failed: {ex}")
|
||||
return {"CANCELLED"}
|
||||
self.load_user_stream(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
def load_user_stream(self, context: Context) -> None:
|
||||
speckle = get_speckle(context)
|
||||
@@ -190,17 +189,17 @@ class LoadUserStreams(bpy.types.Operator):
|
||||
try:
|
||||
streams = client.stream.list(stream_limit=self.stream_limit)
|
||||
except Exception as ex:
|
||||
raise Exception(f"Failed to retrieve streams") from ex
|
||||
raise Exception(f"Failed to retrieve projects") from ex
|
||||
|
||||
if not streams:
|
||||
raise Exception("Zero streams found")
|
||||
_report("Zero projects found")
|
||||
return
|
||||
|
||||
user.streams.clear()
|
||||
|
||||
for s in streams:
|
||||
assert(s.id)
|
||||
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit)
|
||||
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit, commit_limit=10)
|
||||
add_user_stream(user, sstream)
|
||||
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
@@ -5,7 +5,7 @@ import bpy
|
||||
|
||||
|
||||
class SpeckleCollectionSettings(bpy.types.PropertyGroup):
|
||||
enabled: bpy.props.BoolProperty(default=False, name="Enabled")
|
||||
enabled: bpy.props.BoolProperty(default=False, name="Enabled") # type: ignore
|
||||
|
||||
send_or_receive: bpy.props.EnumProperty(
|
||||
name="Mode",
|
||||
@@ -13,7 +13,6 @@ class SpeckleCollectionSettings(bpy.types.PropertyGroup):
|
||||
("send", "Send", "Send data to Speckle server."),
|
||||
("receive", "Receive", "Receive data from Speckle server."),
|
||||
),
|
||||
)
|
||||
stream_id: bpy.props.StringProperty(default="")
|
||||
name: bpy.props.StringProperty(default="")
|
||||
units: bpy.props.StringProperty(default="")
|
||||
) # type: ignore
|
||||
stream_id: bpy.props.StringProperty(default="") # type: ignore
|
||||
name: bpy.props.StringProperty(default="") # type: ignore
|
||||
|
||||
@@ -13,6 +13,6 @@ class SpeckleObjectSettings(bpy.types.PropertyGroup):
|
||||
("send", "Send", "Send data to Speckle server."),
|
||||
("receive", "Receive", "Receive data from Speckle server."),
|
||||
),
|
||||
)
|
||||
stream_id: bpy.props.StringProperty(default="")
|
||||
object_id: bpy.props.StringProperty(default="")
|
||||
) # type: ignore
|
||||
stream_id: bpy.props.StringProperty(default="") # type: ignore
|
||||
object_id: bpy.props.StringProperty(default="") # type: ignore
|
||||
|
||||
@@ -1,48 +1,49 @@
|
||||
"""
|
||||
Scene properties
|
||||
"""
|
||||
from typing import Optional, Tuple
|
||||
from typing import Iterable, Optional, Tuple, cast
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
BoolProperty,
|
||||
FloatProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
PointerProperty,
|
||||
)
|
||||
|
||||
class SpeckleSceneObject(bpy.types.PropertyGroup):
|
||||
name: bpy.props.StringProperty(default="")
|
||||
name: bpy.props.StringProperty(default="") # type: ignore
|
||||
|
||||
|
||||
class SpeckleCommitObject(bpy.types.PropertyGroup):
|
||||
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="")
|
||||
id: StringProperty(default="") # type: ignore
|
||||
message: StringProperty(default="") # type: ignore
|
||||
author_name: StringProperty(default="") # type: ignore
|
||||
author_id: StringProperty(default="") # type: ignore
|
||||
created_at: StringProperty(default="") # type: ignore
|
||||
source_application: StringProperty(default="") # type: ignore
|
||||
referenced_object: StringProperty(default="") # type: ignore
|
||||
|
||||
|
||||
class SpeckleBranchObject(bpy.types.PropertyGroup):
|
||||
def get_commits(self, context):
|
||||
if self.commits != None and len(self.commits) > 0:
|
||||
COMMITS = cast(Iterable[SpeckleCommitObject], self.commits)
|
||||
return [
|
||||
(str(i), commit.id, commit.message, i)
|
||||
for i, commit in enumerate(self.commits)
|
||||
for i, commit in enumerate(COMMITS)
|
||||
]
|
||||
return [("0", "<none>", "<none>", 0)]
|
||||
|
||||
name: StringProperty(default="main")
|
||||
commits: CollectionProperty(type=SpeckleCommitObject)
|
||||
|
||||
name: StringProperty(default="main") # type: ignore
|
||||
id: StringProperty(default="") # type: ignore
|
||||
description: StringProperty(default="") # type: ignore
|
||||
commits: CollectionProperty(type=SpeckleCommitObject) # type: ignore
|
||||
commit: EnumProperty(
|
||||
name="Commit",
|
||||
description="Active commit",
|
||||
name="Version",
|
||||
description="Selected model version",
|
||||
items=get_commits,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
def get_active_commit(self) -> Optional[SpeckleCommitObject]:
|
||||
selected_index = int(self.commit)
|
||||
@@ -54,24 +55,23 @@ class SpeckleBranchObject(bpy.types.PropertyGroup):
|
||||
class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
def get_branches(self, context):
|
||||
if self.branches:
|
||||
BRANCHES = cast(Iterable[SpeckleBranchObject], self.branches)
|
||||
return [
|
||||
(str(i), branch.name, branch.name, i)
|
||||
for i, branch in enumerate(self.branches)
|
||||
(str(i), branch.name, branch.description, i)
|
||||
for i, branch in enumerate(BRANCHES)
|
||||
if branch.name != "globals"
|
||||
]
|
||||
return [("0", "<none>", "<none>", 0)]
|
||||
|
||||
name: StringProperty(default="SpeckleStream")
|
||||
description: StringProperty(default="No description provided.")
|
||||
id: StringProperty(default="")
|
||||
units: StringProperty(default="Meters")
|
||||
query: StringProperty(default="")
|
||||
branches: CollectionProperty(type=SpeckleBranchObject)
|
||||
name: StringProperty(default="") # type: ignore
|
||||
description: StringProperty(default="") # type: ignore
|
||||
id: StringProperty(default="") # type: ignore
|
||||
branches: CollectionProperty(type=SpeckleBranchObject) # type: ignore
|
||||
branch: EnumProperty(
|
||||
name="Branch",
|
||||
description="Active branch",
|
||||
name="Model",
|
||||
description="Selected Model",
|
||||
items=get_branches,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
def get_active_branch(self) -> Optional[SpeckleBranchObject]:
|
||||
selected_index = int(self.branch)
|
||||
@@ -81,14 +81,14 @@ class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
|
||||
|
||||
class SpeckleUserObject(bpy.types.PropertyGroup):
|
||||
server_name: StringProperty(default="SpeckleXYZ")
|
||||
server_url: StringProperty(default="https://speckle.xyz")
|
||||
id: StringProperty(default="")
|
||||
name: StringProperty(default="Speckle User")
|
||||
email: StringProperty(default="user@speckle.xyz")
|
||||
company: StringProperty(default="SpeckleSystems")
|
||||
streams: CollectionProperty(type=SpeckleStreamObject)
|
||||
active_stream: IntProperty(default=0)
|
||||
server_name: StringProperty(default="SpeckleXYZ") # type: ignore
|
||||
server_url: StringProperty(default="https://speckle.xyz") # type: ignore
|
||||
id: StringProperty(default="") # type: ignore
|
||||
name: StringProperty(default="Speckle User") # type: ignore
|
||||
email: StringProperty(default="user@speckle.xyz") # type: ignore
|
||||
company: StringProperty(default="SpeckleSystems") # type: ignore
|
||||
streams: CollectionProperty(type=SpeckleStreamObject) # type: ignore
|
||||
active_stream: IntProperty(default=0) # type: ignore
|
||||
|
||||
def get_active_stream(self) -> Optional[SpeckleStreamObject]:
|
||||
selected_index = int(self.active_stream)
|
||||
@@ -107,18 +107,19 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
name="Available streams",
|
||||
description="Available streams associated with user.",
|
||||
items=[],
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
users: CollectionProperty(type=SpeckleUserObject)
|
||||
users: CollectionProperty(type=SpeckleUserObject) # type: ignore
|
||||
|
||||
def get_users(self, context):
|
||||
USERS = cast(Iterable[SpeckleUserObject], self.users)
|
||||
return [
|
||||
(str(i), "{} ({})".format(user.email, user.server_name), user.server_url, i)
|
||||
for i, user in enumerate(self.users)
|
||||
(str(i), f"{user.email} ({user.server_name})", user.server_url, i)
|
||||
for i, user in enumerate(USERS)
|
||||
]
|
||||
|
||||
def set_user(self, context):
|
||||
bpy.ops.speckle.load_user_streams()
|
||||
bpy.ops.speckle.load_user_streams() # type: ignore
|
||||
|
||||
active_user: EnumProperty(
|
||||
items=get_users,
|
||||
@@ -127,29 +128,29 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
update=set_user,
|
||||
get=None,
|
||||
set=None,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
objects: CollectionProperty(type=SpeckleSceneObject)
|
||||
objects: CollectionProperty(type=SpeckleSceneObject) # type: ignore
|
||||
|
||||
scale: FloatProperty(default=0.001)
|
||||
scale: FloatProperty(default=0.001) # type: ignore
|
||||
|
||||
user: StringProperty(
|
||||
name="User",
|
||||
description="Current user.",
|
||||
description="Current user",
|
||||
default="Speckle User",
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
receive_script: EnumProperty(
|
||||
name="Receive script",
|
||||
description="Script to run when receiving stream objects.",
|
||||
description="Custom py script to execute when receiving objects. See docs for function signature.",
|
||||
items=get_scripts,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
send_script: EnumProperty(
|
||||
name="Send script",
|
||||
description="Script to run when sending stream objects.",
|
||||
description="Custom py script to execute when sending objects. See docs for function signature",
|
||||
items=get_scripts,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
def get_active_user(self) -> Optional[SpeckleUserObject]:
|
||||
selected_index = int(self.active_user)
|
||||
@@ -161,7 +162,7 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
def validate_user_selection(self) -> SpeckleUserObject:
|
||||
user = self.get_active_user()
|
||||
if not user:
|
||||
raise SelectionException("No user selected/found")
|
||||
raise SelectionException("No user account selected/found")
|
||||
return user
|
||||
|
||||
def validate_stream_selection(self) -> Tuple[SpeckleUserObject, SpeckleStreamObject]:
|
||||
@@ -169,7 +170,7 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
|
||||
stream = user.get_active_stream()
|
||||
if not stream:
|
||||
raise SelectionException("No stream selected/found")
|
||||
raise SelectionException("No project selected/found")
|
||||
|
||||
return (user, stream)
|
||||
|
||||
@@ -178,14 +179,14 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
|
||||
branch = stream.get_active_branch()
|
||||
if not branch:
|
||||
raise SelectionException("No branch selected/found")
|
||||
raise SelectionException("No model selected/found")
|
||||
return (user, stream, branch)
|
||||
|
||||
def validate_commit_selection(self) ->Tuple[SpeckleUserObject, SpeckleStreamObject, SpeckleBranchObject, SpeckleCommitObject]:
|
||||
(user, stream, branch) = self.validate_branch_selection()
|
||||
commit = branch.get_active_commit()
|
||||
if commit is None:
|
||||
raise SelectionException("No commit selected/found")
|
||||
raise SelectionException("No model version selected/found")
|
||||
|
||||
return (user, stream, branch, commit)
|
||||
|
||||
@@ -193,4 +194,7 @@ class SelectionException(Exception):
|
||||
pass
|
||||
|
||||
def get_speckle(context: bpy.types.Context) -> SpeckleSceneSettings:
|
||||
"""
|
||||
Gets the speckle scene object
|
||||
"""
|
||||
return context.scene.speckle #type: ignore
|
||||
@@ -10,8 +10,9 @@ from bpy.props import (
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
)
|
||||
from deprecated import deprecated
|
||||
|
||||
|
||||
@deprecated
|
||||
class OBJECT_PT_speckle(bpy.types.Panel):
|
||||
bl_space_type = "PROPERTIES"
|
||||
# bl_idname = 'OBJECT_PT_speckle'
|
||||
@@ -28,7 +29,7 @@ class OBJECT_PT_speckle(bpy.types.Panel):
|
||||
layout.active = ob.speckle.enabled
|
||||
col = layout.column()
|
||||
col.prop(ob.speckle, "send_or_receive", expand=True)
|
||||
col.prop(ob.speckle, "stream_id", text="Stream ID")
|
||||
col.prop(ob.speckle, "stream_id", text="Project ID")
|
||||
col.prop(ob.speckle, "object_id", text="Object ID")
|
||||
col.operator("speckle.update_object", text="Update")
|
||||
col.operator("speckle.reset_object", text="Reset")
|
||||
|
||||
+24
-35
@@ -4,20 +4,10 @@ Speckle UI elements for the 3d viewport
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
BoolProperty,
|
||||
FloatProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
)
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
"""
|
||||
Compatibility
|
||||
TODO: evaluate if we should still support Blender <2.80
|
||||
"""
|
||||
from bpy_speckle.properties.scene import get_speckle
|
||||
|
||||
Region = "TOOLS" if bpy.app.version < (2, 80, 0) else "UI"
|
||||
|
||||
@@ -78,7 +68,7 @@ class VIEW3D_UL_SpeckleUsers(bpy.types.UIList):
|
||||
|
||||
class VIEW3D_UL_SpeckleStreams(bpy.types.UIList):
|
||||
"""
|
||||
Speckle stream list
|
||||
Speckle projects list
|
||||
"""
|
||||
|
||||
def draw_item(self, context, layout, data, stream, active_data, active_propname):
|
||||
@@ -94,7 +84,7 @@ class VIEW3D_UL_SpeckleStreams(bpy.types.UIList):
|
||||
|
||||
elif self.layout_type in {"GRID"}:
|
||||
layout.alignment = "CENTER"
|
||||
layout.label(text="Streams", icon_value=0)
|
||||
layout.label(text="Projects", icon_value=0)
|
||||
|
||||
|
||||
class VIEW3D_PT_SpeckleUser(bpy.types.Panel):
|
||||
@@ -106,10 +96,10 @@ class VIEW3D_PT_SpeckleUser(bpy.types.Panel):
|
||||
bl_region_type = Region
|
||||
bl_category = "Speckle"
|
||||
bl_context = "objectmode"
|
||||
bl_label = "User"
|
||||
bl_label = "User Account"
|
||||
|
||||
def draw(self, context):
|
||||
speckle = context.scene.speckle
|
||||
speckle = get_speckle(context)
|
||||
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
@@ -119,28 +109,28 @@ class VIEW3D_PT_SpeckleUser(bpy.types.Panel):
|
||||
else:
|
||||
col.prop(speckle, "active_user", text="")
|
||||
user = speckle.users[int(speckle.active_user)]
|
||||
col.label(text="{} ({})".format(user.server_name, user.server_url))
|
||||
col.label(text="{} ({})".format(user.name, user.email))
|
||||
|
||||
col.label(text=f"{user.server_name} ({user.server_url})")
|
||||
col.label(text=f"{user.name} ({user.email})")
|
||||
|
||||
col.operator("speckle.users_load", text="", icon="FILE_REFRESH")
|
||||
|
||||
class VIEW3D_PT_SpeckleStreams(bpy.types.Panel):
|
||||
"""
|
||||
Speckle Streams UI panel in the 3d viewport
|
||||
Speckle projects UI panel in the 3d viewport
|
||||
"""
|
||||
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = Region
|
||||
bl_category = "Speckle"
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Streams"
|
||||
bl_label = "Projects"
|
||||
|
||||
def draw(self, context):
|
||||
speckle = context.scene.speckle
|
||||
speckle = get_speckle(context)
|
||||
col = self.layout.column()
|
||||
|
||||
if len(speckle.users) < 1:
|
||||
col.label(text="No stream data.")
|
||||
col.label(text="No Projects")
|
||||
else:
|
||||
user = speckle.users[int(speckle.active_user)]
|
||||
col.template_list(
|
||||
@@ -149,31 +139,31 @@ class VIEW3D_PT_SpeckleStreams(bpy.types.Panel):
|
||||
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")
|
||||
|
||||
|
||||
class VIEW3D_PT_SpeckleActiveStream(bpy.types.Panel):
|
||||
"""
|
||||
Speckle Active Streams UI panel in the 3d viewport
|
||||
Speckle Active Projects UI panel in the 3d viewport
|
||||
"""
|
||||
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = Region
|
||||
bl_category = "Speckle"
|
||||
bl_context = "objectmode"
|
||||
bl_label = "Active stream"
|
||||
bl_label = "Active Project"
|
||||
|
||||
def draw(self, context):
|
||||
speckle = context.scene.speckle
|
||||
speckle = get_speckle(context)
|
||||
col = self.layout.column()
|
||||
|
||||
if len(speckle.users) < 1:
|
||||
col.label(text="No stream data.")
|
||||
col.label(text="No projects")
|
||||
else:
|
||||
user = speckle.users[int(speckle.active_user)]
|
||||
user = speckle.validate_user_selection()
|
||||
#user = speckle.users[int(speckle.active_user)]
|
||||
if len(user.streams) < 1:
|
||||
col.label(text="No active stream.")
|
||||
col.label(text="No active project")
|
||||
else:
|
||||
stream = user.streams[user.active_stream]
|
||||
# user.active_stream = min(user.active_stream, len(user.streams) - 1)
|
||||
@@ -183,14 +173,14 @@ class VIEW3D_PT_SpeckleActiveStream(bpy.types.Panel):
|
||||
col.separator()
|
||||
|
||||
row = col.row()
|
||||
row.prop(stream, "branch", text="")
|
||||
row.operator("speckle.branch_copy_name", text="", icon="COPY_ID")
|
||||
row.prop(stream, "branch", text="Model")
|
||||
row.operator("speckle.model_copy_id", text="", icon="COPY_ID")
|
||||
|
||||
if len(stream.branches) > 0:
|
||||
branch = stream.branches[int(stream.branch)]
|
||||
|
||||
row = col.row()
|
||||
row.prop(branch, "commit", text="")
|
||||
row.prop(branch, "commit", text="Version")
|
||||
row.operator("speckle.commit_copy_id", text="", icon="COPY_ID")
|
||||
|
||||
if len(branch.commits) > 0:
|
||||
@@ -213,7 +203,7 @@ class VIEW3D_PT_SpeckleActiveStream(bpy.types.Panel):
|
||||
col.label(text=f"{commit.author_name} ({commit.author_id})")
|
||||
col.label(text=commit.source_application)
|
||||
else:
|
||||
col.label(text="No branches found!")
|
||||
col.label(text="No models found!")
|
||||
|
||||
col.separator()
|
||||
|
||||
@@ -225,7 +215,6 @@ class VIEW3D_PT_SpeckleActiveStream(bpy.types.Panel):
|
||||
subcol = row.column()
|
||||
subcol.operator("speckle.send_stream_objects", text="Send")
|
||||
subcol.prop(speckle, "send_script", text="")
|
||||
area.prop(stream, "query", text="Filter")
|
||||
|
||||
col.separator()
|
||||
|
||||
@@ -246,7 +235,7 @@ class VIEW3D_PT_SpeckleActiveStream(bpy.types.Panel):
|
||||
|
||||
area.separator()
|
||||
col.separator()
|
||||
col.operator("speckle.view_stream_data_api", text="Open Stream in Web")
|
||||
col.operator("speckle.view_stream_data_api", text="Open Model in Web")
|
||||
|
||||
|
||||
class VIEW3D_PT_SpeckleHelp(bpy.types.Panel):
|
||||
|
||||
Generated
+142
-124
@@ -16,13 +16,13 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""}
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.2.0"
|
||||
version = "4.3.0"
|
||||
description = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"},
|
||||
{file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"},
|
||||
{file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"},
|
||||
{file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -98,32 +98,39 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "22.12.0"
|
||||
version = "23.11.0"
|
||||
description = "The uncompromising code formatter."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"},
|
||||
{file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"},
|
||||
{file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"},
|
||||
{file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"},
|
||||
{file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"},
|
||||
{file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"},
|
||||
{file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"},
|
||||
{file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"},
|
||||
{file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"},
|
||||
{file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"},
|
||||
{file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"},
|
||||
{file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"},
|
||||
{file = "black-23.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911"},
|
||||
{file = "black-23.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f"},
|
||||
{file = "black-23.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394"},
|
||||
{file = "black-23.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f"},
|
||||
{file = "black-23.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479"},
|
||||
{file = "black-23.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244"},
|
||||
{file = "black-23.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221"},
|
||||
{file = "black-23.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5"},
|
||||
{file = "black-23.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187"},
|
||||
{file = "black-23.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6"},
|
||||
{file = "black-23.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b"},
|
||||
{file = "black-23.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142"},
|
||||
{file = "black-23.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055"},
|
||||
{file = "black-23.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4"},
|
||||
{file = "black-23.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06"},
|
||||
{file = "black-23.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07"},
|
||||
{file = "black-23.11.0-py3-none-any.whl", hash = "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e"},
|
||||
{file = "black-23.11.0.tar.gz", hash = "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
packaging = ">=22.0"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
|
||||
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
@@ -314,13 +321,13 @@ test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "fake-bpy-module-latest"
|
||||
version = "20230117"
|
||||
version = "20240212"
|
||||
description = "Collection of the fake Blender Python API module for the code completion."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "fake-bpy-module-latest-20230117.tar.gz", hash = "sha256:b58957036fe5573b2374a159aeb7a4cbd92255f447e55a49e16ff7c06850cdd1"},
|
||||
{file = "fake_bpy_module_latest-20230117-py3-none-any.whl", hash = "sha256:73613c27418446bc2942baed6220f8ac4ddde694a3712dd595aa97f902a79242"},
|
||||
{file = "fake-bpy-module-latest-20240212.tar.gz", hash = "sha256:5b33c6cdeaaa92f1a55ca1e5f23771216dc5cd233dd6922a500bf8101e666a82"},
|
||||
{file = "fake_bpy_module_latest-20240212-py3-none-any.whl", hash = "sha256:7616834644bf90d37bd774112a851fd940096fd859eca704ece63e3d8215719c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -378,13 +385,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.2"
|
||||
version = "1.0.4"
|
||||
description = "A minimal low-level HTTP client."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"},
|
||||
{file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"},
|
||||
{file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"},
|
||||
{file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -395,7 +402,7 @@ h11 = ">=0.13,<0.15"
|
||||
asyncio = ["anyio (>=4.0,<5.0)"]
|
||||
http2 = ["h2 (>=3,<5)"]
|
||||
socks = ["socksio (==1.*)"]
|
||||
trio = ["trio (>=0.22.0,<0.23.0)"]
|
||||
trio = ["trio (>=0.22.0,<0.25.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
@@ -613,6 +620,17 @@ files = [
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
@@ -641,18 +659,18 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.6.1"
|
||||
version = "2.6.2"
|
||||
description = "Data validation using Python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic-2.6.1-py3-none-any.whl", hash = "sha256:0b6a909df3192245cb736509a92ff69e4fef76116feffec68e93a567347bae6f"},
|
||||
{file = "pydantic-2.6.1.tar.gz", hash = "sha256:4fd5c182a2488dc63e6d32737ff19937888001e2a6d86e94b3f233104a5d1fa9"},
|
||||
{file = "pydantic-2.6.2-py3-none-any.whl", hash = "sha256:37a5432e54b12fecaa1049c5195f3d860a10e01bdfd24f1840ef14bd0d3aeab3"},
|
||||
{file = "pydantic-2.6.2.tar.gz", hash = "sha256:a09be1c3d28f3abe37f8a78af58284b236a92ce520105ddc91a6d29ea1176ba7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
annotated-types = ">=0.4.0"
|
||||
pydantic-core = "2.16.2"
|
||||
pydantic-core = "2.16.3"
|
||||
typing-extensions = ">=4.6.1"
|
||||
|
||||
[package.extras]
|
||||
@@ -660,90 +678,90 @@ email = ["email-validator (>=2.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.16.2"
|
||||
version = "2.16.3"
|
||||
description = ""
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3fab4e75b8c525a4776e7630b9ee48aea50107fea6ca9f593c98da3f4d11bf7c"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8bde5b48c65b8e807409e6f20baee5d2cd880e0fad00b1a811ebc43e39a00ab2"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2924b89b16420712e9bb8192396026a8fbd6d8726224f918353ac19c4c043d2a"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16aa02e7a0f539098e215fc193c8926c897175d64c7926d00a36188917717a05"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:936a787f83db1f2115ee829dd615c4f684ee48ac4de5779ab4300994d8af325b"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:459d6be6134ce3b38e0ef76f8a672924460c455d45f1ad8fdade36796df1ddc8"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9ee4febb249c591d07b2d4dd36ebcad0ccd128962aaa1801508320896575ef"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40a0bd0bed96dae5712dab2aba7d334a6c67cbcac2ddfca7dbcc4a8176445990"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:870dbfa94de9b8866b37b867a2cb37a60c401d9deb4a9ea392abf11a1f98037b"},
|
||||
{file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:308974fdf98046db28440eb3377abba274808bf66262e042c412eb2adf852731"},
|
||||
{file = "pydantic_core-2.16.2-cp310-none-win32.whl", hash = "sha256:a477932664d9611d7a0816cc3c0eb1f8856f8a42435488280dfbf4395e141485"},
|
||||
{file = "pydantic_core-2.16.2-cp310-none-win_amd64.whl", hash = "sha256:8f9142a6ed83d90c94a3efd7af8873bf7cefed2d3d44387bf848888482e2d25f"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:406fac1d09edc613020ce9cf3f2ccf1a1b2f57ab00552b4c18e3d5276c67eb11"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce232a6170dd6532096cadbf6185271e4e8c70fc9217ebe105923ac105da9978"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90fec23b4b05a09ad988e7a4f4e081711a90eb2a55b9c984d8b74597599180f"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8aafeedb6597a163a9c9727d8a8bd363a93277701b7bfd2749fbefee2396469e"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9957433c3a1b67bdd4c63717eaf174ebb749510d5ea612cd4e83f2d9142f3fc8"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0d7a9165167269758145756db43a133608a531b1e5bb6a626b9ee24bc38a8f7"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dffaf740fe2e147fedcb6b561353a16243e654f7fe8e701b1b9db148242e1272"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8ed79883b4328b7f0bd142733d99c8e6b22703e908ec63d930b06be3a0e7113"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cf903310a34e14651c9de056fcc12ce090560864d5a2bb0174b971685684e1d8"},
|
||||
{file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46b0d5520dbcafea9a8645a8164658777686c5c524d381d983317d29687cce97"},
|
||||
{file = "pydantic_core-2.16.2-cp311-none-win32.whl", hash = "sha256:70651ff6e663428cea902dac297066d5c6e5423fda345a4ca62430575364d62b"},
|
||||
{file = "pydantic_core-2.16.2-cp311-none-win_amd64.whl", hash = "sha256:98dc6f4f2095fc7ad277782a7c2c88296badcad92316b5a6e530930b1d475ebc"},
|
||||
{file = "pydantic_core-2.16.2-cp311-none-win_arm64.whl", hash = "sha256:ef6113cd31411eaf9b39fc5a8848e71c72656fd418882488598758b2c8c6dfa0"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:88646cae28eb1dd5cd1e09605680c2b043b64d7481cdad7f5003ebef401a3039"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7b883af50eaa6bb3299780651e5be921e88050ccf00e3e583b1e92020333304b"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bf26c2e2ea59d32807081ad51968133af3025c4ba5753e6a794683d2c91bf6e"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99af961d72ac731aae2a1b55ccbdae0733d816f8bfb97b41909e143de735f522"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02906e7306cb8c5901a1feb61f9ab5e5c690dbbeaa04d84c1b9ae2a01ebe9379"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5362d099c244a2d2f9659fb3c9db7c735f0004765bbe06b99be69fbd87c3f15"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ac426704840877a285d03a445e162eb258924f014e2f074e209d9b4ff7bf380"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b94cbda27267423411c928208e89adddf2ea5dd5f74b9528513f0358bba019cb"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6db58c22ac6c81aeac33912fb1af0e930bc9774166cdd56eade913d5f2fff35e"},
|
||||
{file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396fdf88b1b503c9c59c84a08b6833ec0c3b5ad1a83230252a9e17b7dfb4cffc"},
|
||||
{file = "pydantic_core-2.16.2-cp312-none-win32.whl", hash = "sha256:7c31669e0c8cc68400ef0c730c3a1e11317ba76b892deeefaf52dcb41d56ed5d"},
|
||||
{file = "pydantic_core-2.16.2-cp312-none-win_amd64.whl", hash = "sha256:a3b7352b48fbc8b446b75f3069124e87f599d25afb8baa96a550256c031bb890"},
|
||||
{file = "pydantic_core-2.16.2-cp312-none-win_arm64.whl", hash = "sha256:a9e523474998fb33f7c1a4d55f5504c908d57add624599e095c20fa575b8d943"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ae34418b6b389d601b31153b84dce480351a352e0bb763684a1b993d6be30f17"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:732bd062c9e5d9582a30e8751461c1917dd1ccbdd6cafb032f02c86b20d2e7ec"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b52776a2e3230f4854907a1e0946eec04d41b1fc64069ee774876bbe0eab55"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef551c053692b1e39e3f7950ce2296536728871110e7d75c4e7753fb30ca87f4"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ebb892ed8599b23fa8f1799e13a12c87a97a6c9d0f497525ce9858564c4575a4"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa6c8c582036275997a733427b88031a32ffa5dfc3124dc25a730658c47a572f"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ba0884a91f1aecce75202473ab138724aa4fb26d7707f2e1fa6c3e68c84fbf"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7924e54f7ce5d253d6160090ddc6df25ed2feea25bfb3339b424a9dd591688bc"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69a7b96b59322a81c2203be537957313b07dd333105b73db0b69212c7d867b4b"},
|
||||
{file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7e6231aa5bdacda78e96ad7b07d0c312f34ba35d717115f4b4bff6cb87224f0f"},
|
||||
{file = "pydantic_core-2.16.2-cp38-none-win32.whl", hash = "sha256:41dac3b9fce187a25c6253ec79a3f9e2a7e761eb08690e90415069ea4a68ff7a"},
|
||||
{file = "pydantic_core-2.16.2-cp38-none-win_amd64.whl", hash = "sha256:f685dbc1fdadb1dcd5b5e51e0a378d4685a891b2ddaf8e2bba89bd3a7144e44a"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:55749f745ebf154c0d63d46c8c58594d8894b161928aa41adbb0709c1fe78b77"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b30b0dd58a4509c3bd7eefddf6338565c4905406aee0c6e4a5293841411a1286"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18de31781cdc7e7b28678df7c2d7882f9692ad060bc6ee3c94eb15a5d733f8f7"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5864b0242f74b9dd0b78fd39db1768bc3f00d1ffc14e596fd3e3f2ce43436a33"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8f9186ca45aee030dc8234118b9c0784ad91a0bb27fc4e7d9d6608a5e3d386c"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc6f6c9be0ab6da37bc77c2dda5f14b1d532d5dbef00311ee6e13357a418e646"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa057095f621dad24a1e906747179a69780ef45cc8f69e97463692adbcdae878"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ad84731a26bcfb299f9eab56c7932d46f9cad51c52768cace09e92a19e4cf55"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3b052c753c4babf2d1edc034c97851f867c87d6f3ea63a12e2700f159f5c41c3"},
|
||||
{file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0f686549e32ccdb02ae6f25eee40cc33900910085de6aa3790effd391ae10c2"},
|
||||
{file = "pydantic_core-2.16.2-cp39-none-win32.whl", hash = "sha256:7afb844041e707ac9ad9acad2188a90bffce2c770e6dc2318be0c9916aef1469"},
|
||||
{file = "pydantic_core-2.16.2-cp39-none-win_amd64.whl", hash = "sha256:9da90d393a8227d717c19f5397688a38635afec89f2e2d7af0df037f3249c39a"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f60f920691a620b03082692c378661947d09415743e437a7478c309eb0e4f82"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:47924039e785a04d4a4fa49455e51b4eb3422d6eaacfde9fc9abf8fdef164e8a"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6294e76b0380bb7a61eb8a39273c40b20beb35e8c87ee101062834ced19c545"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe56851c3f1d6f5384b3051c536cc81b3a93a73faf931f404fef95217cf1e10d"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d776d30cde7e541b8180103c3f294ef7c1862fd45d81738d156d00551005784"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:72f7919af5de5ecfaf1eba47bf9a5d8aa089a3340277276e5636d16ee97614d7"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4bfcbde6e06c56b30668a0c872d75a7ef3025dc3c1823a13cf29a0e9b33f67e8"},
|
||||
{file = "pydantic_core-2.16.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ff7c97eb7a29aba230389a2661edf2e9e06ce616c7e35aa764879b6894a44b25"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9b5f13857da99325dcabe1cc4e9e6a3d7b2e2c726248ba5dd4be3e8e4a0b6d0e"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a7e41e3ada4cca5f22b478c08e973c930e5e6c7ba3588fb8e35f2398cdcc1545"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60eb8ceaa40a41540b9acae6ae7c1f0a67d233c40dc4359c256ad2ad85bdf5e5"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7beec26729d496a12fd23cf8da9944ee338c8b8a17035a560b585c36fe81af20"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22c5f022799f3cd6741e24f0443ead92ef42be93ffda0d29b2597208c94c3753"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:eca58e319f4fd6df004762419612122b2c7e7d95ffafc37e890252f869f3fb2a"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed957db4c33bc99895f3a1672eca7e80e8cda8bd1e29a80536b4ec2153fa9804"},
|
||||
{file = "pydantic_core-2.16.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:459c0d338cc55d099798618f714b21b7ece17eb1a87879f2da20a3ff4c7628e2"},
|
||||
{file = "pydantic_core-2.16.2.tar.gz", hash = "sha256:0ba503850d8b8dcc18391f10de896ae51d37fe5fe43dbfb6a35c5c5cad271a06"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"},
|
||||
{file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"},
|
||||
{file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"},
|
||||
{file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"},
|
||||
{file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"},
|
||||
{file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"},
|
||||
{file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"},
|
||||
{file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"},
|
||||
{file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"},
|
||||
{file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"},
|
||||
{file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"},
|
||||
{file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"},
|
||||
{file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"},
|
||||
{file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -840,24 +858,24 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.0"
|
||||
version = "1.3.1"
|
||||
description = "Sniff out which async library your code is running under"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
|
||||
{file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
|
||||
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
|
||||
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "specklepy"
|
||||
version = "2.17.17"
|
||||
version = "2.18.2"
|
||||
description = "The Python SDK for Speckle 2.0"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0,<4.0"
|
||||
files = [
|
||||
{file = "specklepy-2.17.17-py3-none-any.whl", hash = "sha256:793705a803423b69d0873bc98314fbb0cd805b4b10657957bd13ef5cdcad08ce"},
|
||||
{file = "specklepy-2.17.17.tar.gz", hash = "sha256:73abeee1c958299818518266dd734d4dc0c82b3e665bb6c4e5b54bad09f118c1"},
|
||||
{file = "specklepy-2.18.2-py3-none-any.whl", hash = "sha256:8efdc0200e575703cbed4612180b961382319e615c99607c5622f0ed3ae46325"},
|
||||
{file = "specklepy-2.18.2.tar.gz", hash = "sha256:1b674c69dd7de27dc18c7eec6926f439f676160fa6869eabf916108693f1b4bd"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -904,13 +922,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.9.0"
|
||||
version = "4.10.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
|
||||
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
|
||||
{file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
|
||||
{file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -989,13 +1007,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.0"
|
||||
version = "2.2.1"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"},
|
||||
{file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"},
|
||||
{file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
|
||||
{file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@@ -1268,4 +1286,4 @@ multidict = ">=4.0"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.8, <4.0.0"
|
||||
content-hash = "4013ed20ddaf1e3d73013848e1de434f487a9d53b4cbf4c902c70c9135f207b3"
|
||||
content-hash = "2bf735c64d321d45ba8cc7f8ba24e36e1e8ffebbdeaf8a87161d88333a90cb71"
|
||||
|
||||
+3
-3
@@ -7,15 +7,15 @@ license = "Apache-2.0"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.8, <4.0.0"
|
||||
specklepy = "^2.17.17"
|
||||
specklepy = "^2.18.2"
|
||||
attrs = "^23.1.0"
|
||||
|
||||
# [tool.poetry.group.local_specklepy.dependencies]
|
||||
# specklepy = {path = "../specklepy", develop = true}
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
fake-bpy-module-latest = "^20230117"
|
||||
black = "^22.10.0"
|
||||
fake-bpy-module-latest = "^20240212"
|
||||
black = "23.11.0"
|
||||
pylint = "^2.15.7"
|
||||
ruff = "^0.0.187"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user