Compare commits

...

6 Commits

Author SHA1 Message Date
izzy lyseggen c8d6b3ebea Merge pull request #41 from specklesystems/izzy/grasshopper-fix
fix(receive): handle nested lists from grasshopper
2021-07-01 17:20:28 +01:00
izzy lyseggen b2e7a899f6 fix(receive): handle nested lists from grasshopper 2021-07-01 17:03:45 +01:00
izzy lyseggen ef0f7ef46f Merge pull request #39 from specklesystems/izzy/units-and-conversions
General fixes regarding units, curves, and props
2021-07-01 16:02:51 +01:00
izzy lyseggen 8799f52dfb refactor: bit more cleanup 2021-07-01 16:00:00 +01:00
izzy lyseggen 22c1fb4fb2 refactor(curve): clean up curve conversions 2021-07-01 15:59:37 +01:00
izzy lyseggen bce03f9e38 feat(convert): adjust unit and prop handling 2021-07-01 15:59:12 +01:00
6 changed files with 136 additions and 129 deletions
+16 -20
View File
@@ -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
+99 -101
View File
@@ -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)
-1
View File
@@ -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:
-2
View File
@@ -1,6 +1,4 @@
from specklepy.api.client import SpeckleClient
import requests
from bpy_speckle.clients import speckle_clients
"""
+4 -4
View File
@@ -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)
+17 -1
View File
@@ -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]