Compare commits
3 Commits
2.15.0-alpha6
...
2.15.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 201ca5f26e | |||
| 89528437b1 | |||
| 91bde24fe9 |
@@ -73,20 +73,6 @@ class BlenderCommitObjectBuilder(CommitObjectBuilder[Object]):
|
||||
|
||||
return convered_collection
|
||||
|
||||
# def find_collection_parent(self, col: Collection) -> Optional[Collection]:
|
||||
# for p in bpy.data.collections:
|
||||
# if col.name in p.children.keys():
|
||||
# return p
|
||||
# return None
|
||||
|
||||
#TODO: I've started an approach that will not work
|
||||
# Goal #1 get all collections sending
|
||||
# Sync with Claire, ask how we handle this in Rhino with partial selection of layers (proably how I'm expecting it works, but good to double check)
|
||||
# Goal #2 Figure out how to send collections
|
||||
# - all collections
|
||||
# - all collections that contain a child collection that has geometry...
|
||||
# - only collections explicitly selected
|
||||
|
||||
def build_commit_object(self, root_commit_object: Base) -> None:
|
||||
assert(root_commit_object.applicationId in self.converted)
|
||||
|
||||
@@ -131,4 +117,4 @@ class BlenderCommitObjectBuilder(CommitObjectBuilder[Object]):
|
||||
return should_remove_this_col
|
||||
|
||||
if should_remove_unuseful_collection(root_commit_object):
|
||||
_report("WARNING: Only empty collections have been converted!") #TODO: consider raising exception here, to halt the send operation
|
||||
_report("WARNING: Only empty collections have been converted!") #TODO: consider raising exception here, to halt the send operation
|
||||
|
||||
@@ -22,6 +22,7 @@ from bpy.types import Object, Collection as BCollection
|
||||
from .util import (
|
||||
add_to_heirarchy,
|
||||
get_render_material,
|
||||
get_vertex_color_material,
|
||||
render_material_to_native,
|
||||
add_custom_properties,
|
||||
add_vertices,
|
||||
@@ -219,6 +220,8 @@ def view_to_native(speckle_view, name: str, scale: float) -> bpy.types.Object:
|
||||
def mesh_to_native(speckle_mesh: Mesh, name: str, scale: float) -> bpy.types.Mesh:
|
||||
return meshes_to_native(speckle_mesh, [speckle_mesh], name, scale)
|
||||
|
||||
|
||||
|
||||
def meshes_to_native(element: Base, meshes: Collection[Mesh], name: str, scale: float) -> bpy.types.Mesh:
|
||||
if name in bpy.data.meshes.keys():
|
||||
return bpy.data.meshes[name]
|
||||
@@ -242,10 +245,16 @@ def meshes_to_native(element: Base, meshes: Collection[Mesh], name: str, scale:
|
||||
|
||||
add_faces(mesh, bm, offset, i)
|
||||
|
||||
render_material = get_render_material(mesh) or fallback_material
|
||||
if render_material is not None:
|
||||
native_material = render_material_to_native(render_material)
|
||||
blender_mesh.materials.append(native_material)
|
||||
try:
|
||||
render_material = get_render_material(mesh) or fallback_material
|
||||
if render_material is not None:
|
||||
native_material = render_material_to_native(render_material)
|
||||
blender_mesh.materials.append(native_material)
|
||||
elif mesh.colors:
|
||||
native_material = get_vertex_color_material()
|
||||
blender_mesh.materials.append(native_material)
|
||||
except Exception as ex:
|
||||
_report(f"Failed converting render material for {name}: {ex}")
|
||||
|
||||
offset += len(mesh.vertices) // 3
|
||||
|
||||
@@ -254,8 +263,15 @@ def meshes_to_native(element: Base, meshes: Collection[Mesh], name: str, scale:
|
||||
|
||||
# Third pass, add vertex instance data
|
||||
for mesh in meshes:
|
||||
add_colors(mesh, bm)
|
||||
add_uv_coords(mesh, bm)
|
||||
try:
|
||||
add_colors(mesh, bm)
|
||||
except Exception as ex:
|
||||
_report(f"Skipping converting vertex colors for {name}: {ex}")
|
||||
|
||||
try:
|
||||
add_uv_coords(mesh, bm)
|
||||
except Exception as ex:
|
||||
_report(f"Skipping converting uv coordinates for {name}: {ex}")
|
||||
|
||||
bm.to_mesh(blender_mesh)
|
||||
bm.free()
|
||||
|
||||
+40
-11
@@ -1,14 +1,14 @@
|
||||
import math
|
||||
from typing import Any, Dict, Optional, Tuple, Union
|
||||
from typing import Any, Dict, Optional, Tuple, Union, cast
|
||||
from bmesh.types import BMesh
|
||||
import bpy, struct, idprop
|
||||
import bpy, idprop
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry import Mesh
|
||||
from specklepy.objects.other import RenderMaterial
|
||||
from bpy_speckle.convert.constants import IGNORED_PROPERTY_KEYS
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy.types import Material, Object, Collection as BCollection
|
||||
from bpy.types import Material, Object, Collection as BCollection, Node, ShaderNodeVertexColor
|
||||
|
||||
from bpy_speckle.specklepy_extras.traversal import TraversalContext
|
||||
|
||||
@@ -98,18 +98,42 @@ def render_material_to_native(speckle_mat: RenderMaterial) -> Material:
|
||||
|
||||
return blender_mat
|
||||
|
||||
_vertex_color_material: Optional[Material] = None
|
||||
|
||||
def get_vertex_color_material() -> Material:
|
||||
global _vertex_color_material
|
||||
|
||||
#see https://stackoverflow.com/a/69807985
|
||||
if not _vertex_color_material:
|
||||
_vertex_color_material = bpy.data.materials.new("Vertex Color Material")
|
||||
_vertex_color_material.use_nodes = True
|
||||
nodes = _vertex_color_material.node_tree.nodes
|
||||
principled_bsdf_node = cast(Node, nodes.get("Principled BSDF"))
|
||||
|
||||
if not "VERTEX_COLOR" in [node.type for node in nodes]:
|
||||
vertex_color_node = cast(ShaderNodeVertexColor, nodes.new(type = "ShaderNodeVertexColor"))
|
||||
else:
|
||||
vertex_color_node = cast(ShaderNodeVertexColor, nodes.get("Vertex Color"))
|
||||
vertex_color_node.layer_name = "Col"
|
||||
|
||||
links = _vertex_color_material.node_tree.links
|
||||
link = links.new(vertex_color_node.outputs[0], principled_bsdf_node.inputs[0])
|
||||
|
||||
return _vertex_color_material
|
||||
|
||||
def get_render_material(speckle_object: Base) -> Optional[RenderMaterial]:
|
||||
"""Trys to get a RenderMaterial on given speckle_object and convert it to a blender material"""
|
||||
"""Trys to get a RenderMaterial on given speckle_object"""
|
||||
|
||||
speckle_mat = getattr(
|
||||
speckle_object,
|
||||
"renderMaterial",
|
||||
getattr(speckle_object, "@renderMaterial", None),
|
||||
)
|
||||
if not isinstance(speckle_mat, RenderMaterial):
|
||||
return None
|
||||
|
||||
return speckle_mat
|
||||
if isinstance(speckle_mat, RenderMaterial):
|
||||
return speckle_mat
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@@ -159,10 +183,8 @@ def add_colors(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
if len(scolors) > 0:
|
||||
|
||||
for i in range(len(scolors)):
|
||||
col = int(scolors[i])
|
||||
(a, r, g, b) = [
|
||||
int(x) for x in struct.unpack("!BBBB", struct.pack("!i", col))
|
||||
]
|
||||
argb = int(scolors[i])
|
||||
(a, r, g, b) = argb_split(argb)
|
||||
colors.append(
|
||||
(
|
||||
float(r) / 255.0,
|
||||
@@ -180,6 +202,13 @@ def add_colors(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
for loop in face.loops:
|
||||
loop[color_layer] = colors[loop.vert.index]
|
||||
|
||||
def argb_split(argb: int) -> Tuple[int, int, int, int]:
|
||||
alpha = (argb >> 24) & 0xFF
|
||||
red = (argb >> 16) & 0xFF
|
||||
green = (argb >> 8) & 0xFF
|
||||
blue = argb & 0xFF
|
||||
|
||||
return (alpha, red, green, blue)
|
||||
|
||||
def add_uv_coords(speckle_mesh: Mesh, blender_mesh: BMesh):
|
||||
s_uvs = speckle_mesh.textureCoordinates
|
||||
|
||||
@@ -196,6 +196,7 @@ class ReceiveStreamObjects(bpy.types.Operator):
|
||||
for item in traversalFunc.traverse(commit_object):
|
||||
|
||||
current: Base = item.current
|
||||
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user