Compare commits
2 Commits
2.7.0
...
2.9.0-alpha
| Author | SHA1 | Date | |
|---|---|---|---|
| ea2b6dfb0e | |||
| 83610cec38 |
@@ -1,4 +1,7 @@
|
||||
"""
|
||||
Permanent handle on all user clients
|
||||
"""
|
||||
speckle_clients = []
|
||||
from specklepy.api.client import SpeckleClient
|
||||
|
||||
|
||||
speckle_clients: list[SpeckleClient] = []
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from bpy_speckle.convert.to_native import convert_to_native
|
||||
from specklepy.objects.base import Base
|
||||
|
||||
|
||||
def get_speckle_subobjects(attr, scale, name):
|
||||
def get_speckle_subobjects(attr: dict | Base, scale: float, name: str) -> list:
|
||||
subobjects = []
|
||||
keys = attr.keys() if isinstance(attr, dict) else attr.get_dynamic_member_names()
|
||||
for key in keys:
|
||||
|
||||
@@ -4,6 +4,7 @@ import mathutils
|
||||
import bpy, bmesh, bpy_types
|
||||
from specklepy.objects.other import *
|
||||
from specklepy.objects.geometry import *
|
||||
from bpy.types import Object
|
||||
from .util import (
|
||||
add_blender_material,
|
||||
add_custom_properties,
|
||||
@@ -25,7 +26,7 @@ CAN_CONVERT_TO_NATIVE = (
|
||||
)
|
||||
|
||||
|
||||
def can_convert_to_native(speckle_object):
|
||||
def can_convert_to_native(speckle_object: Base) -> bool:
|
||||
if type(speckle_object) in CAN_CONVERT_TO_NATIVE:
|
||||
return True
|
||||
if getattr(
|
||||
@@ -37,7 +38,7 @@ def can_convert_to_native(speckle_object):
|
||||
return False
|
||||
|
||||
|
||||
def convert_to_native(speckle_object, name=None):
|
||||
def convert_to_native(speckle_object: Base, name: str = None) -> list | Object:
|
||||
speckle_type = type(speckle_object)
|
||||
speckle_name = (
|
||||
name
|
||||
@@ -52,7 +53,7 @@ def convert_to_native(speckle_object, name=None):
|
||||
)
|
||||
if not elements and not display:
|
||||
_report(f"Could not convert unsupported Speckle object: {speckle_object}")
|
||||
return
|
||||
return None
|
||||
if isinstance(display, list):
|
||||
elements.extend(display)
|
||||
else:
|
||||
@@ -130,7 +131,7 @@ def convert_to_native(speckle_object, name=None):
|
||||
return blender_object
|
||||
|
||||
|
||||
def mesh_to_native(speckle_mesh: Mesh, name, scale=1.0):
|
||||
def mesh_to_native(speckle_mesh: Mesh, name: str, scale=1.0) -> bpy.types.Mesh:
|
||||
|
||||
if name in bpy.data.meshes.keys():
|
||||
blender_mesh = bpy.data.meshes[name]
|
||||
@@ -150,7 +151,7 @@ def mesh_to_native(speckle_mesh: Mesh, name, scale=1.0):
|
||||
|
||||
return blender_mesh
|
||||
|
||||
def line_to_native(speckle_curve, blender_curve, scale):
|
||||
def line_to_native(speckle_curve: Line, blender_curve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
|
||||
line = blender_curve.splines.new("POLY")
|
||||
line.points.add(1)
|
||||
|
||||
@@ -173,7 +174,7 @@ def line_to_native(speckle_curve, blender_curve, scale):
|
||||
return line
|
||||
|
||||
|
||||
def polyline_to_native(scurve, bcurve, scale):
|
||||
def polyline_to_native(scurve: Polyline, bcurve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
|
||||
if value := scurve.value:
|
||||
N = len(value) // 3
|
||||
|
||||
@@ -197,7 +198,7 @@ def polyline_to_native(scurve, bcurve, scale):
|
||||
return polyline
|
||||
|
||||
|
||||
def nurbs_to_native(scurve, bcurve, scale):
|
||||
def nurbs_to_native(scurve: Curve, bcurve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
|
||||
if points := scurve.points:
|
||||
N = len(points) // 3
|
||||
|
||||
@@ -226,12 +227,12 @@ def nurbs_to_native(scurve, bcurve, scale):
|
||||
return nurbs
|
||||
|
||||
|
||||
def arc_to_native(rcurve, bcurve, scale):
|
||||
def arc_to_native(rcurve: Arc, bcurve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
|
||||
# TODO: improve Blender representation of arc
|
||||
|
||||
plane = rcurve.plane
|
||||
if not plane:
|
||||
return
|
||||
return None
|
||||
|
||||
normal = mathutils.Vector([plane.normal.x, plane.normal.y, plane.normal.z])
|
||||
|
||||
@@ -288,7 +289,7 @@ def arc_to_native(rcurve, bcurve, scale):
|
||||
return arc
|
||||
|
||||
|
||||
def polycurve_to_native(scurve, bcurve, scale):
|
||||
def polycurve_to_native(scurve: Polycurve, bcurve: bpy.types.Curve, scale: float):
|
||||
"""
|
||||
Convert Polycurve object
|
||||
"""
|
||||
@@ -307,7 +308,7 @@ def polycurve_to_native(scurve, bcurve, scale):
|
||||
return curves
|
||||
|
||||
|
||||
def icurve_to_native_spline(speckle_curve, blender_curve, scale=1.0):
|
||||
def icurve_to_native_spline(speckle_curve: Base, blender_curve: bpy.types.Curve, scale=1.0):
|
||||
curve_type = type(speckle_curve)
|
||||
if curve_type is Line:
|
||||
return line_to_native(speckle_curve, blender_curve, scale)
|
||||
@@ -321,7 +322,7 @@ def icurve_to_native_spline(speckle_curve, blender_curve, scale=1.0):
|
||||
return arc_to_native(speckle_curve, blender_curve, scale)
|
||||
|
||||
|
||||
def icurve_to_native(speckle_curve, name=None, scale=1.0):
|
||||
def icurve_to_native(speckle_curve: Base, name=None, scale=1.0) -> Curve | None:
|
||||
curve_type = type(speckle_curve)
|
||||
if curve_type not in SUPPORTED_CURVES:
|
||||
_report(f"Unsupported curve type: {curve_type}")
|
||||
@@ -340,7 +341,7 @@ def icurve_to_native(speckle_curve, name=None, scale=1.0):
|
||||
return blender_curve
|
||||
|
||||
|
||||
def transform_to_native(transform: Transform, scale=1.0):
|
||||
def transform_to_native(transform: Transform, scale=1.0) -> mathutils.Matrix:
|
||||
mat = mathutils.Matrix(
|
||||
[
|
||||
transform.value[:4],
|
||||
@@ -355,7 +356,7 @@ def transform_to_native(transform: Transform, scale=1.0):
|
||||
return mat
|
||||
|
||||
|
||||
def block_def_to_native(definition: BlockDefinition, scale=1.0):
|
||||
def block_def_to_native(definition: BlockDefinition, scale=1.0) -> bpy.types.Collection:
|
||||
native_def = bpy.data.collections.get(definition.name)
|
||||
if native_def:
|
||||
return native_def
|
||||
@@ -373,7 +374,7 @@ def block_def_to_native(definition: BlockDefinition, scale=1.0):
|
||||
return native_def
|
||||
|
||||
|
||||
def block_instance_to_native(instance: BlockInstance, scale=1.0):
|
||||
def block_instance_to_native(instance: BlockInstance, scale=1.0) -> bpy.types.Object:
|
||||
"""
|
||||
Convert BlockInstance to native
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import bpy
|
||||
from bpy.types import MeshVertColor, MeshVertex, Object
|
||||
from specklepy.objects.geometry import Mesh, Curve, Interval, Box, Point, Polyline
|
||||
from specklepy.objects.other import *
|
||||
from bpy_speckle.functions import _report
|
||||
@@ -13,12 +14,12 @@ UNITS = "m"
|
||||
CAN_CONVERT_TO_SPECKLE = ("MESH", "CURVE", "EMPTY")
|
||||
|
||||
|
||||
def convert_to_speckle(blender_object, scale, units, desgraph=None):
|
||||
def convert_to_speckle(blender_object: Object, scale: float, units: str, desgraph=None) -> list | None:
|
||||
global UNITS
|
||||
UNITS = units
|
||||
blender_type = blender_object.type
|
||||
if blender_type not in CAN_CONVERT_TO_SPECKLE:
|
||||
return
|
||||
return None
|
||||
|
||||
speckle_objects = []
|
||||
speckle_material = material_to_speckle(blender_object)
|
||||
@@ -54,10 +55,11 @@ def convert_to_speckle(blender_object, scale, units, desgraph=None):
|
||||
return speckle_objects
|
||||
|
||||
|
||||
def mesh_to_speckle(blender_object, data, scale=1.0):
|
||||
def mesh_to_speckle(blender_object: Object, data: bpy.types.Mesh, scale=1.0) -> List[Mesh]:
|
||||
if data.loop_triangles is None or len(data.loop_triangles) < 1:
|
||||
data.calc_loop_triangles()
|
||||
|
||||
|
||||
mat = blender_object.matrix_world
|
||||
|
||||
verts = [tuple(mat @ x.co * scale) for x in data.vertices]
|
||||
@@ -89,10 +91,16 @@ def mesh_to_speckle(blender_object, data, scale=1.0):
|
||||
sm.faces.append(n)
|
||||
sm.faces.extend(f)
|
||||
|
||||
# TODO: figure out how to align vertex colors and vertices consistantly in receiving applications
|
||||
# we are seeing the same issue as with texture coordinate alignment
|
||||
#if data.color_attributes.active_color:
|
||||
# sm.colors = [to_argb_int(x.color) for x in data.color_attributes.active_color.data]
|
||||
|
||||
|
||||
return [sm]
|
||||
|
||||
|
||||
def bezier_to_speckle(matrix, spline, scale, name=None):
|
||||
def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name:str = None) -> Curve:
|
||||
degree = 3
|
||||
closed = spline.use_cyclic_u
|
||||
|
||||
@@ -141,7 +149,7 @@ def bezier_to_speckle(matrix, spline, scale, name=None):
|
||||
)
|
||||
|
||||
|
||||
def nurbs_to_speckle(matrix, spline, scale, name=None):
|
||||
def nurbs_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name:str = None) -> Curve:
|
||||
knots = make_knots(spline)
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
degree = spline.order_u - 1
|
||||
@@ -167,7 +175,7 @@ def nurbs_to_speckle(matrix, spline, scale, name=None):
|
||||
)
|
||||
|
||||
|
||||
def poly_to_speckle(matrix, spline, scale, name=None):
|
||||
def poly_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: str = None) -> Polyline:
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
|
||||
length = spline.calc_length()
|
||||
@@ -184,7 +192,7 @@ def poly_to_speckle(matrix, spline, scale, name=None):
|
||||
)
|
||||
|
||||
|
||||
def icurve_to_speckle(blender_object, data, scale=1.0):
|
||||
def icurve_to_speckle(blender_object: Object, data: bpy.types.Curve, scale=1.0) -> List[Base] | None:
|
||||
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
|
||||
|
||||
if blender_object.type != "CURVE":
|
||||
@@ -213,7 +221,7 @@ def icurve_to_speckle(blender_object, data, scale=1.0):
|
||||
return curves
|
||||
|
||||
|
||||
def ngons_to_speckle_polylines(blender_object, data, scale=1.0):
|
||||
def ngons_to_speckle_polylines(blender_object: Object, data: bpy.types.Mesh, scale=1.0) -> List[Polyline] | None:
|
||||
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
|
||||
|
||||
if blender_object.type != "MESH":
|
||||
@@ -245,14 +253,14 @@ def ngons_to_speckle_polylines(blender_object, data, scale=1.0):
|
||||
return polylines
|
||||
|
||||
|
||||
def material_to_speckle(blender_object) -> RenderMaterial:
|
||||
def material_to_speckle(blender_object: Object) -> RenderMaterial | None:
|
||||
"""Create and return a render material from a blender object"""
|
||||
if not getattr(blender_object.data, "materials", None):
|
||||
return
|
||||
return None
|
||||
|
||||
blender_mat = blender_object.data.materials[0]
|
||||
blender_mat: bpy.types.Material = blender_object.data.materials[0]
|
||||
if not blender_mat:
|
||||
return
|
||||
return None
|
||||
|
||||
speckle_mat = RenderMaterial()
|
||||
speckle_mat.name = blender_mat.name
|
||||
@@ -275,7 +283,7 @@ def material_to_speckle(blender_object) -> RenderMaterial:
|
||||
return speckle_mat
|
||||
|
||||
|
||||
def transform_to_speckle(blender_transform, scale=1.0):
|
||||
def transform_to_speckle(blender_transform: List[float], scale=1.0) -> Transform:
|
||||
value = [y for x in blender_transform for y in x]
|
||||
# scale the translation
|
||||
for i in (3, 7, 11):
|
||||
@@ -284,7 +292,7 @@ def transform_to_speckle(blender_transform, scale=1.0):
|
||||
return Transform(value=value, units=UNITS)
|
||||
|
||||
|
||||
def block_def_to_speckle(blender_definition, scale=1.0):
|
||||
def block_def_to_speckle(blender_definition: bpy.types.Collection, scale=1.0) -> BlockDefinition:
|
||||
geometry = []
|
||||
for geo in blender_definition.objects:
|
||||
geometry.extend(convert_to_speckle(geo, scale, UNITS))
|
||||
@@ -299,7 +307,7 @@ def block_def_to_speckle(blender_definition, scale=1.0):
|
||||
return block_def
|
||||
|
||||
|
||||
def block_instance_to_speckle(blender_instance, scale=1.0):
|
||||
def block_instance_to_speckle(blender_instance: Object, scale=1.0):
|
||||
return BlockInstance(
|
||||
blockDefinition=block_def_to_speckle(
|
||||
blender_instance.instance_collection, scale
|
||||
@@ -310,7 +318,7 @@ def block_instance_to_speckle(blender_instance, scale=1.0):
|
||||
)
|
||||
|
||||
|
||||
def empty_to_speckle(blender_object, scale=1.0):
|
||||
def empty_to_speckle(blender_object: Object, scale=1.0) -> BlockInstance | None:
|
||||
# probably an instance collection (block) so let's try it
|
||||
try:
|
||||
geo = blender_object.instance_collection.objects.items()
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import math
|
||||
from typing import Tuple
|
||||
from bmesh.types import BMesh
|
||||
import bpy, struct, idprop
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry import Mesh
|
||||
from specklepy.serialization.base_object_serializer import BaseObjectSerializer
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy.types import Object
|
||||
|
||||
IGNORED_PROPERTY_KEYS = {
|
||||
"id",
|
||||
@@ -38,7 +42,7 @@ def to_argb_int(diffuse_colour) -> int:
|
||||
|
||||
return int.from_bytes(diffuse_colour, byteorder="big", signed=True)
|
||||
|
||||
def add_custom_properties(speckle_object, blender_object):
|
||||
def add_custom_properties(speckle_object: Base, blender_object: Object):
|
||||
if blender_object is None:
|
||||
return
|
||||
|
||||
@@ -69,7 +73,7 @@ def add_custom_properties(speckle_object, blender_object):
|
||||
blender_object[k] = v
|
||||
|
||||
|
||||
def add_blender_material(speckle_object, blender_object) -> None:
|
||||
def add_blender_material(speckle_object: Base, blender_object: Object) -> None:
|
||||
"""Add material to a blender object if the corresponding speckle object has a render material"""
|
||||
if blender_object.data is None:
|
||||
return
|
||||
@@ -107,7 +111,7 @@ def add_blender_material(speckle_object, blender_object) -> None:
|
||||
blender_object.data.materials.append(blender_mat)
|
||||
|
||||
|
||||
def add_vertices(speckle_mesh, blender_mesh, scale=1.0):
|
||||
def add_vertices(speckle_mesh: Mesh, blender_mesh: BMesh, scale=1.0):
|
||||
sverts = speckle_mesh.vertices
|
||||
|
||||
if sverts and len(sverts) > 0:
|
||||
@@ -123,7 +127,7 @@ def add_vertices(speckle_mesh, blender_mesh, scale=1.0):
|
||||
blender_mesh.verts.ensure_lookup_table()
|
||||
|
||||
|
||||
def add_faces(speckle_mesh, blender_mesh, smooth=False):
|
||||
def add_faces(speckle_mesh: Mesh, blender_mesh: BMesh, smooth=False):
|
||||
sfaces = speckle_mesh.faces
|
||||
|
||||
if sfaces and len(sfaces) > 0:
|
||||
@@ -147,7 +151,7 @@ def add_faces(speckle_mesh, blender_mesh, smooth=False):
|
||||
blender_mesh.verts.index_update()
|
||||
|
||||
|
||||
def add_colors(speckle_mesh, blender_mesh):
|
||||
def add_colors(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
|
||||
scolors = speckle_mesh.colors
|
||||
|
||||
@@ -178,7 +182,7 @@ def add_colors(speckle_mesh, blender_mesh):
|
||||
loop[color_layer] = colors[loop.vert.index]
|
||||
|
||||
|
||||
def add_uv_coords(speckle_mesh, blender_mesh):
|
||||
def add_uv_coords(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
s_uvs = speckle_mesh.textureCoordinates
|
||||
if not s_uvs:
|
||||
return
|
||||
|
||||
@@ -33,7 +33,7 @@ def _report(msg):
|
||||
print("SpeckleBlender: {}".format(msg))
|
||||
|
||||
|
||||
def get_scale_length(units):
|
||||
def get_scale_length(units: str) -> float:
|
||||
if units.lower() in unit_scale.keys():
|
||||
return unit_scale[units]
|
||||
_report("Units <{}> are not supported.".format(units))
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
Stream operators
|
||||
"""
|
||||
from itertools import chain
|
||||
from typing import Dict
|
||||
from math import radians
|
||||
from typing import Callable, Dict, Iterable
|
||||
import bpy
|
||||
from specklepy.api.models import Commit
|
||||
import webbrowser
|
||||
@@ -10,6 +11,7 @@ from bpy.props import (
|
||||
StringProperty,
|
||||
BoolProperty,
|
||||
)
|
||||
from bpy.types import Object
|
||||
from bpy_speckle.convert.to_native import can_convert_to_native, convert_to_native
|
||||
from bpy_speckle.convert.to_speckle import (
|
||||
convert_to_speckle,
|
||||
@@ -32,7 +34,7 @@ from specklepy.objects.geometry import *
|
||||
from specklepy.logging.exceptions import SpeckleException
|
||||
|
||||
|
||||
def get_objects_collections(base) -> Dict:
|
||||
def get_objects_collections(base: Base) -> Dict[str, list]:
|
||||
"""Create collections based on the dynamic members on a root commit object"""
|
||||
collections = {}
|
||||
for name in base.get_dynamic_member_names():
|
||||
@@ -47,7 +49,7 @@ def get_objects_collections(base) -> Dict:
|
||||
return collections
|
||||
|
||||
|
||||
def get_objects_nested_lists(items, parent_col=None) -> List:
|
||||
def get_objects_nested_lists(items: list, parent_col: bpy.types.Collection = None) -> List:
|
||||
"""For handling the weird nested lists that come from Grasshopper"""
|
||||
objects = []
|
||||
|
||||
@@ -64,7 +66,7 @@ def get_objects_nested_lists(items, parent_col=None) -> List:
|
||||
return objects
|
||||
|
||||
|
||||
def get_objects_collections_recursive(base, parent_col=None) -> List:
|
||||
def get_objects_collections_recursive(base: Base, parent_col: bpy.types.Collection = None) -> List:
|
||||
"""Recursively create collections based on the dynamic members on nested `Base` objects within the root commit object"""
|
||||
# if it's a convertable (registered) class and not just a plain `Base`, return the object itself
|
||||
if can_convert_to_native(base):
|
||||
@@ -94,7 +96,7 @@ def get_objects_collections_recursive(base, parent_col=None) -> List:
|
||||
return objects
|
||||
|
||||
|
||||
def bases_to_native(context, collections, scale, stream_id, func=None):
|
||||
def bases_to_native(context: bpy.types.Context, collections: Dict[str, list], scale: float, stream_id: str, func: Callable = None):
|
||||
for col_name, objects in collections.items():
|
||||
col = bpy.data.collections[col_name]
|
||||
existing = get_existing_collection_objs(col)
|
||||
@@ -126,7 +128,8 @@ def bases_to_native(context, collections, scale, stream_id, func=None):
|
||||
context.area.tag_redraw()
|
||||
|
||||
|
||||
def base_to_native(context, base, scale, stream_id, col, existing, func=None):
|
||||
|
||||
def base_to_native(context: bpy.types.Context, base: Base, scale: float, stream_id: str, col: bpy.types.Collection, existing: Dict[str, Object], func: Callable = None):
|
||||
new_objects = convert_to_native(base)
|
||||
if not isinstance(new_objects, list):
|
||||
new_objects = [new_objects]
|
||||
@@ -170,7 +173,7 @@ def base_to_native(context, base, scale, stream_id, col, existing, func=None):
|
||||
col.objects.link(new_object)
|
||||
|
||||
|
||||
def create_collection(name, clear_collection=True):
|
||||
def create_collection(name: str, clear_collection=True) -> bpy.types.Collection:
|
||||
if name in bpy.data.collections:
|
||||
col = bpy.data.collections[name]
|
||||
if clear_collection:
|
||||
@@ -182,13 +185,13 @@ def create_collection(name, clear_collection=True):
|
||||
return col
|
||||
|
||||
|
||||
def create_child_collections(parent_col, children_names):
|
||||
def create_child_collections(parent_col: bpy.types.Collection, children_names: Iterable[str]):
|
||||
for name in children_names:
|
||||
col = create_collection(name)
|
||||
parent_col.children.link(col)
|
||||
|
||||
|
||||
def get_existing_collection_objs(col):
|
||||
def get_existing_collection_objs(col: bpy.types.Collection) -> Dict[str, bpy.types.Object]:
|
||||
return {
|
||||
obj.speckle.object_id: obj for obj in col.objects if obj.speckle.object_id != ""
|
||||
}
|
||||
@@ -240,6 +243,49 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Receive objects from active stream"
|
||||
|
||||
|
||||
clean_meshes: BoolProperty(name="Clean Meshes", default=False)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.prop(self, "clean_meshes")
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
@staticmethod
|
||||
def clean_converted_meshes(context: bpy.types.Context, convertedObjects: dict[str, Object]):
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
active = None
|
||||
for obj in convertedObjects.values():
|
||||
if obj.type != 'MESH':
|
||||
continue
|
||||
|
||||
# This seems to be required inorder to select the object here
|
||||
if obj.name not in context.scene.collection.objects:
|
||||
context.scene.collection.objects.link(obj)
|
||||
|
||||
obj.select_set(True, view_layer=context.scene.view_layers[0])
|
||||
active = obj
|
||||
|
||||
|
||||
if active == None:
|
||||
return
|
||||
context.view_layer.objects.active = active
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='SELECT')
|
||||
bpy.ops.mesh.remove_doubles()
|
||||
bpy.ops.mesh.dissolve_limited(angle_limit=radians(0.1))
|
||||
|
||||
# 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
|
||||
|
||||
def execute(self, context):
|
||||
bpy.context.view_layer.objects.active = None
|
||||
|
||||
@@ -277,6 +323,9 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
message="received commit from Speckle Blender",
|
||||
)
|
||||
|
||||
context.window_manager.progress_begin(0, stream_data.totalChildrenCount)
|
||||
|
||||
|
||||
"""
|
||||
Create or get Collection for stream objects
|
||||
"""
|
||||
@@ -309,20 +358,45 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
"""
|
||||
Get script from text editor for injection
|
||||
"""
|
||||
func = None
|
||||
userFunc = None
|
||||
if context.scene.speckle.receive_script in bpy.data.texts:
|
||||
mod = bpy.data.texts[context.scene.speckle.receive_script].as_module()
|
||||
if hasattr(mod, "execute"):
|
||||
func = mod.execute
|
||||
userFunc = mod.execute
|
||||
|
||||
createdObjects:Dict[str, Object] = {}
|
||||
|
||||
progress = 0
|
||||
def func(scene, obj: Object):
|
||||
nonlocal progress
|
||||
nonlocal context
|
||||
nonlocal createdObjects
|
||||
|
||||
progress += 1 #TODO: Progress bar neverreaches 100 because func is only called for convertable objects
|
||||
context.window_manager.progress_update(progress)
|
||||
createdObjects[obj.name] = obj
|
||||
|
||||
if userFunc:
|
||||
return userFunc(scene, obj)
|
||||
else:
|
||||
return obj
|
||||
|
||||
|
||||
"""
|
||||
Iterate through retrieved resources
|
||||
"""
|
||||
bases_to_native(context, collections, scale, stream.id, func)
|
||||
context.window_manager.progress_end()
|
||||
|
||||
|
||||
if self.clean_meshes:
|
||||
self.clean_converted_meshes(context, createdObjects)
|
||||
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
class SendStreamObjects(bpy.types.Operator):
|
||||
"""
|
||||
Send stream objects
|
||||
|
||||
@@ -5,6 +5,7 @@ import bpy
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from specklepy.api.client import SpeckleClient
|
||||
from specklepy.api.models import Stream, User
|
||||
from specklepy.api.credentials import get_local_accounts
|
||||
from datetime import datetime
|
||||
|
||||
@@ -59,7 +60,7 @@ class LoadUsers(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
def add_user_stream(user, stream):
|
||||
def add_user_stream(user: User, stream: Stream):
|
||||
s = user.streams.add()
|
||||
s.name = stream.name
|
||||
s.id = stream.id
|
||||
|
||||
Reference in New Issue
Block a user