Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c8d6b3ebea | |||
| b2e7a899f6 | |||
| ef0f7ef46f | |||
| 8799f52dfb | |||
| 22c1fb4fb2 | |||
| bce03f9e38 |
@@ -4,8 +4,7 @@ from mathutils import Matrix
|
||||
from .from_speckle import *
|
||||
from .to_speckle import *
|
||||
from .util import *
|
||||
from bpy_speckle.util import find_key_case_insensitive
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.functions import _report, get_scale_length
|
||||
|
||||
from specklepy.objects.geometry import *
|
||||
from specklepy.objects.other import RenderMaterial
|
||||
@@ -21,17 +20,6 @@ FROM_SPECKLE_SCHEMAS = {
|
||||
}
|
||||
|
||||
|
||||
# FROM_SPECKLE = {
|
||||
# "Mesh": import_mesh,
|
||||
# "Brep": import_brep,
|
||||
# "Curve": import_curve,
|
||||
# "Line": import_curve,
|
||||
# "Polyline": import_curve,
|
||||
# "Polycurve":import_curve,
|
||||
# "Arc":import_curve,
|
||||
# }
|
||||
|
||||
|
||||
TO_SPECKLE = {
|
||||
"MESH": export_mesh,
|
||||
"CURVE": export_curve,
|
||||
@@ -146,7 +134,10 @@ def add_custom_properties(speckle_object, blender_object):
|
||||
blender_object["_speckle_type"] = type(speckle_object).__name__
|
||||
# blender_object['_speckle_name'] = "SpeckleObject"
|
||||
|
||||
ignore = ["_chunkable", "_units"]
|
||||
ignore = ["_chunkable", "_units", "units"]
|
||||
|
||||
if hasattr(speckle_object, "applicationId"):
|
||||
blender_object["applicationId"] = speckle_object.applicationId
|
||||
|
||||
for key in speckle_object.get_dynamic_member_names():
|
||||
if key in ignore:
|
||||
@@ -186,6 +177,10 @@ def from_speckle_object(speckle_object, scale, name=None):
|
||||
or speckle_object.speckle_type + f" -- {speckle_object.id}"
|
||||
)
|
||||
|
||||
units = getattr(speckle_object, "units", None)
|
||||
if units:
|
||||
scale = get_scale_length(units) / bpy.context.scene.unit_settings.scale_length
|
||||
|
||||
# try native conversion
|
||||
if type(speckle_object) in FROM_SPECKLE_SCHEMAS.keys():
|
||||
print("Got object type: {}".format(type(speckle_object)))
|
||||
@@ -278,12 +273,12 @@ def get_blender_custom_properties(obj, max_depth=1000):
|
||||
return obj
|
||||
|
||||
if hasattr(obj, "keys"):
|
||||
d = {}
|
||||
for key in obj.keys():
|
||||
if key in ignored_keys or key.startswith("_"):
|
||||
continue
|
||||
d[key] = get_blender_custom_properties(obj[key], max_depth - 1)
|
||||
return d
|
||||
return {
|
||||
key: get_blender_custom_properties(obj[key], max_depth - 1)
|
||||
for key in obj.keys()
|
||||
if key not in ignored_keys and not key.startswith("_")
|
||||
}
|
||||
|
||||
elif isinstance(obj, (list, tuple, idprop.types.IDPropertyArray)):
|
||||
return [get_blender_custom_properties(o, max_depth - 1) for o in obj]
|
||||
else:
|
||||
@@ -302,6 +297,7 @@ def to_speckle_object(blender_object, scale):
|
||||
|
||||
for so in speckle_objects:
|
||||
so.properties = get_blender_custom_properties(blender_object)
|
||||
so.applicationId = so.properties.pop("applicationId", None)
|
||||
|
||||
if speckle_material:
|
||||
so["renderMaterial"] = speckle_material
|
||||
|
||||
@@ -2,8 +2,100 @@ import bpy, bmesh, struct
|
||||
from specklepy.objects.geometry import Curve, Interval, Box, Polyline
|
||||
from bpy_speckle.convert.to_speckle.mesh import export_mesh
|
||||
|
||||
UNITS = "m"
|
||||
|
||||
|
||||
def bezier_to_speckle(matrix, spline, scale, name=None):
|
||||
degree = 3
|
||||
closed = spline.use_cyclic_u
|
||||
|
||||
points = []
|
||||
for i, bp in enumerate(spline.bezier_points):
|
||||
if i > 0:
|
||||
points.append(tuple(matrix @ bp.handle_left * scale))
|
||||
points.append(tuple(matrix @ bp.co * scale))
|
||||
if i < len(spline.bezier_points) - 1:
|
||||
points.append(tuple(matrix @ bp.handle_right * scale))
|
||||
|
||||
if closed:
|
||||
points.append(tuple(matrix @ spline.bezier_points[-1].handle_right * scale))
|
||||
points.append(tuple(matrix @ spline.bezier_points[0].handle_left * scale))
|
||||
points.append(tuple(matrix @ spline.bezier_points[0].co * scale))
|
||||
|
||||
num_points = len(points)
|
||||
|
||||
knot_count = num_points + degree - 1
|
||||
knots = [0] * knot_count
|
||||
|
||||
for i in range(1, len(knots)):
|
||||
knots[i] = i // 3
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
return Curve(
|
||||
name=name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[1] * num_points,
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
)
|
||||
|
||||
|
||||
def nurbs_to_speckle(matrix, spline, scale, name=None):
|
||||
knots = makeknots(spline)
|
||||
# print("knots: {}".format(knots))
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
degree = spline.order_u - 1
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
|
||||
return Curve(
|
||||
name=name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[pt.weight for pt in spline.points],
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units=UNITS,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
)
|
||||
|
||||
|
||||
def poly_to_speckle(matrix, spline, scale, name=None):
|
||||
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(start=0, end=length, totalChildrenCount=0)
|
||||
return Polyline(
|
||||
name=name,
|
||||
closed=spline.use_cyclic_u,
|
||||
value=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
length=length,
|
||||
domain=domain,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
area=0,
|
||||
units=UNITS,
|
||||
)
|
||||
|
||||
|
||||
def export_curve(blender_object, data, scale=1.0):
|
||||
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
|
||||
|
||||
if blender_object.type != "CURVE":
|
||||
return None
|
||||
@@ -18,115 +110,22 @@ def export_curve(blender_object, data, scale=1.0):
|
||||
mesh = export_mesh(blender_object, blender_object.to_mesh(), scale)
|
||||
curves.extend(mesh)
|
||||
|
||||
unit_system = bpy.context.scene.unit_settings.system
|
||||
|
||||
for spline in data.splines:
|
||||
if spline.type == "BEZIER":
|
||||
|
||||
degree = 3
|
||||
closed = spline.use_cyclic_u
|
||||
|
||||
points = []
|
||||
for i, bp in enumerate(spline.bezier_points):
|
||||
if i > 0:
|
||||
points.append(tuple(mat @ bp.handle_left * scale))
|
||||
points.append(tuple(mat @ bp.co * scale))
|
||||
if i < len(spline.bezier_points) - 1:
|
||||
points.append(tuple(mat @ bp.handle_right * scale))
|
||||
|
||||
if closed:
|
||||
points.append(
|
||||
tuple(mat @ spline.bezier_points[-1].handle_right * scale)
|
||||
)
|
||||
points.append(tuple(mat @ spline.bezier_points[0].handle_left * scale))
|
||||
points.append(tuple(mat @ spline.bezier_points[0].co * scale))
|
||||
|
||||
num_points = len(points)
|
||||
|
||||
knot_count = num_points + degree - 1
|
||||
knots = [0] * knot_count
|
||||
|
||||
for i in range(1, len(knots), 1):
|
||||
knots[i] = i // 3
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(
|
||||
start=0, end=length, totalChildrenCount=0, applicationId="Blender"
|
||||
)
|
||||
bezier = Curve(
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[1] * num_points,
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
applicationId="Blender",
|
||||
)
|
||||
|
||||
curves.append(bezier)
|
||||
curves.append(bezier_to_speckle(mat, spline, scale, blender_object.name))
|
||||
|
||||
elif spline.type == "NURBS":
|
||||
|
||||
knots = makeknots(spline)
|
||||
# print("knots: {}".format(knots))
|
||||
points = [tuple(mat @ pt.co.xyz * scale) for pt in spline.points]
|
||||
degree = spline.order_u - 1
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(
|
||||
start=0, end=length, totalChildrenCount=0, applicationId="Blender"
|
||||
)
|
||||
nurbs = Curve(
|
||||
name=blender_object.name,
|
||||
degree=degree,
|
||||
closed=spline.use_cyclic_u,
|
||||
periodic=spline.use_cyclic_u,
|
||||
points=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
weights=[pt.weight for pt in spline.points],
|
||||
knots=knots,
|
||||
rational=False,
|
||||
area=0,
|
||||
volume=0,
|
||||
length=length,
|
||||
domain=domain,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
applicationId="Blender",
|
||||
)
|
||||
|
||||
curves.append(nurbs)
|
||||
curves.append(nurbs_to_speckle(mat, spline, scale, blender_object.name))
|
||||
|
||||
elif spline.type == "POLY":
|
||||
points = [tuple(mat @ pt.co.xyz * scale) for pt in spline.points]
|
||||
|
||||
length = spline.calc_length()
|
||||
domain = Interval(
|
||||
start=0, end=length, totalChildrenCount=0, applicationId="Blender"
|
||||
)
|
||||
poly = Polyline(
|
||||
name=blender_object.name,
|
||||
closed=spline.use_cyclic_u,
|
||||
value=list(sum(points, ())), # magic (flatten list of tuples)
|
||||
length=length,
|
||||
domain=domain,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
area=0,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
applicationId="Blender",
|
||||
)
|
||||
curves.append(poly)
|
||||
curves.append(poly_to_speckle(mat, spline, scale, blender_object.name))
|
||||
|
||||
return curves
|
||||
|
||||
|
||||
def export_ngons_as_polylines(blender_object, data, scale=1.0):
|
||||
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
|
||||
|
||||
if blender_object.type != "MESH":
|
||||
return None
|
||||
|
||||
@@ -139,7 +138,7 @@ def export_ngons_as_polylines(blender_object, data, scale=1.0):
|
||||
for v in poly.vertices:
|
||||
value.extend(mat @ verts[v].co * scale)
|
||||
|
||||
domain = Interval(start=0, end=1, applicationId="Blender")
|
||||
domain = Interval(start=0, end=1)
|
||||
poly = Polyline(
|
||||
name="{}_{}".format(blender_object.name, i),
|
||||
closed=True,
|
||||
@@ -148,8 +147,7 @@ def export_ngons_as_polylines(blender_object, data, scale=1.0):
|
||||
domain=domain,
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
area=0,
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
applicationId="Blender",
|
||||
units=UNITS,
|
||||
)
|
||||
|
||||
polylines.append(poly)
|
||||
|
||||
@@ -26,7 +26,6 @@ def export_mesh(blender_object, data, scale=1.0):
|
||||
colors=[],
|
||||
units="m" if unit_system == "METRIC" else "ft",
|
||||
bbox=Box(area=0.0, volume=0.0),
|
||||
applicationId="Blender",
|
||||
)
|
||||
|
||||
for f in faces:
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
from specklepy.api.client import SpeckleClient
|
||||
import requests
|
||||
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
|
||||
"""
|
||||
|
||||
@@ -110,7 +110,7 @@ class DeleteObject(bpy.types.Operator):
|
||||
for x in res["resource"]["objects"]
|
||||
if x["_id"] == active.speckle.object_id
|
||||
]
|
||||
if existing == None:
|
||||
if existing is None:
|
||||
return {"CANCELLED"}
|
||||
# print("Existing: %s" % SpeckleResource.to_json_pretty(existing))
|
||||
new_objects = [
|
||||
@@ -177,7 +177,7 @@ class UploadNgonsAsPolylines(bpy.types.Operator):
|
||||
res = client.objects.create([polyline])
|
||||
print(res)
|
||||
|
||||
if res == None:
|
||||
if res is None:
|
||||
_report(client.me)
|
||||
continue
|
||||
placeholders.extend(res)
|
||||
@@ -185,7 +185,7 @@ class UploadNgonsAsPolylines(bpy.types.Operator):
|
||||
# polyline['_id'] = res['_id']
|
||||
# placeholders.append({'type':'Placeholder', '_id':res['_id']})
|
||||
|
||||
if len(placeholders) < 1:
|
||||
if not placeholders:
|
||||
return {"CANCELLED"}
|
||||
|
||||
# Get list of existing objects in stream and append new object to list
|
||||
@@ -247,7 +247,7 @@ class UploadObject(bpy.types.Operator):
|
||||
sm = to_speckle_object(active, scale)
|
||||
|
||||
placeholders = client.objects.create([sm])
|
||||
if placeholders == None:
|
||||
if placeholders is None:
|
||||
return {"CANCELLED"}
|
||||
|
||||
sstream = client.streams.get(stream.id)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Stream operators
|
||||
"""
|
||||
from itertools import chain
|
||||
import bpy, bmesh, os
|
||||
import webbrowser
|
||||
from bpy.props import (
|
||||
@@ -31,12 +32,13 @@ from specklepy.objects.geometry import *
|
||||
|
||||
|
||||
def get_objects_collections(base):
|
||||
"""Create collections based on the dynamic members on a root commit object"""
|
||||
collections = {}
|
||||
for name in base.get_dynamic_member_names():
|
||||
value = base[name]
|
||||
if isinstance(value, list):
|
||||
col = create_collection(name)
|
||||
collections[name] = [item for item in value if isinstance(item, Base)]
|
||||
collections[name] = get_objects_nested_lists(value)
|
||||
if isinstance(value, Base):
|
||||
col = create_collection(name)
|
||||
collections[name] = get_objects_collections_recursive(value, col)
|
||||
@@ -44,7 +46,21 @@ def get_objects_collections(base):
|
||||
return collections
|
||||
|
||||
|
||||
def get_objects_nested_lists(items):
|
||||
"""For handling the weird nested lists that come from Grasshopper"""
|
||||
objects = []
|
||||
|
||||
if isinstance(items[0], list):
|
||||
items = list(chain.from_iterable(items))
|
||||
objects.extend(get_objects_nested_lists(items))
|
||||
else:
|
||||
objects = [item for item in items if isinstance(item, Base)]
|
||||
|
||||
return objects
|
||||
|
||||
|
||||
def get_objects_collections_recursive(base, parent_col=None):
|
||||
"""Recursively create collections based on the dynamic members on nested `Base` objects within the root commit object"""
|
||||
objects = []
|
||||
for name in base.get_dynamic_member_names():
|
||||
value = base[name]
|
||||
|
||||
Reference in New Issue
Block a user