SuperAPI AI Directory

crosstech-impl-speckle-blender

Design & creation

View repository

Updated 10-15 22:17

About this skill

crosstech-impl-speckle-blender

Quick Reference

Technology Boundary

Aspect Side A: Speckle Side B: Blender
Data model Base object graph (hash-based, immutable) bpy.data collections (mutable, ID blocks)
Geometry Mesh, Curve, Polycurve, Point, NURBS Mesh, Bezier Curve, NURBS Curve, Empty
Materials RenderMaterial (diffuse, opacity, metalness, roughness) Principled BSDF node tree (full PBR)
Hierarchy Collection with elements list bpy.data.collections with linked objects
Units String property on Base (mm, m, cm) Scene unit system (bpy.context.scene.unit_settings)
Storage Server, SQLite cache, Memory transport .blend file (binary)
Versions Speckle Server 2.x / 3.x, SpecklePy 2.x Blender 3.x / 4.x

The Bridge: Speckle Blender Connector

The Speckle Blender connector is a Blender add-on that converts between Speckle Base objects and Blender data blocks. It uses SpecklePy internally for transport and serialization.

Direction What Happens
Blender -> Speckle (Send) Mesh/Curve data extracted from bpy.data, materials reduced to RenderMaterial, collections mapped to Speckle Collections
Speckle -> Blender (Receive) Base objects converted to bpy.data.meshes/curves, RenderMaterials recreated as Principled BSDF, Collections mapped to bpy.data.collections

Supported Conversions

Blender Type Speckle Type Direction
Mesh Mesh Bidirectional
Bezier Curve Curve / Polycurve Bidirectional
NURBS Curve Curve / Polycurve Bidirectional
Empty / Collection Collection Bidirectional
Material (Principled BSDF) RenderMaterial Bidirectional

Critical Warnings

NEVER expect full IFC fidelity through Speckle -- Speckle transmits geometry and basic properties, NOT parametric definitions or IFC relationships.

NEVER assume complex Blender shader node trees survive the round-trip -- only the first Principled BSDF node's basic parameters (diffuse color, opacity, metalness, roughness) are extracted.

NEVER rely on Bonsai/IFC metadata surviving a Speckle round-trip -- Bonsai's native IFC object model is richer than Speckle's Base representation.

ALWAYS verify unit settings match between Speckle and Blender before send/receive -- unit mismatch causes geometry scaling errors.

ALWAYS use applicationId tracking when updating previously received models -- this prevents duplicate objects on subsequent receives.


Side A: Speckle Data Model

Base Object Fundamentals

Every object in Speckle inherits from Base. Key properties:

Property Type Purpose
id string Hash-based unique ID (content-addressable)
applicationId string Host application identity (enables update tracking)
speckle_type string Type discriminator
units string Unit system for geometry values
displayValue List[Mesh] Visual representation meshes

Speckle Collections

Collections represent hierarchical groupings:

from specklepy.objects import Base
from specklepy.objects.other import Collection

root = Collection(name="Building", collectionType="model")
level1 = Collection(name="Level 1", collectionType="level")
root.elements = [level1]
level1.elements = [wall_obj, door_obj]

Collections MUST form a directed tree -- no cycles allowed.

RenderMaterial

from specklepy.objects.other import RenderMaterial

mat = RenderMaterial()
mat.name = "Concrete"
mat.diffuse = 0xFFA0A0A0   # ARGB integer
mat.opacity = 1.0
mat.metalness = 0.0
mat.roughness = 0.8

CRITICAL: RenderMaterial supports ONLY diffuse color, opacity, metalness, and roughness. Texture maps, normal maps, emission, subsurface scattering, and all other PBR channels are NOT supported.

Proxy Collections (v3)

In Speckle v3, organizational data is stored at the root level as proxy collections:

  • renderMaterialProxies -- material assignments
  • levelProxies -- building levels
  • instanceDefinitionProxies -- block/component definitions

Each proxy references objects by applicationId, requiring a two-step lookup.


Side B: Blender Data Model

Relevant bpy.data Collections

Collection Type Maps To
bpy.data.meshes Mesh geometry Speckle Mesh
bpy.data.curves Bezier/NURBS curves Speckle Curve/Polycurve
bpy.data.objects Object wrappers Speckle Base with displayValue
bpy.data.collections Hierarchy groups Speckle Collection
bpy.data.materials Shader node trees Speckle RenderMaterial

Blender Material Structure

A Blender Principled BSDF material exposes ~20+ parameters. The Speckle connector extracts ONLY:

Principled BSDF Input RenderMaterial Property Preserved?
Base Color diffuse YES
Alpha opacity YES
Metallic metalness YES
Roughness roughness YES
Normal Map -- NO
Emission -- NO
Subsurface -- NO
Specular -- NO
All texture nodes -- NO

The Bridge: Send/Receive Workflows

Workflow 1: Send from Blender to Speckle (Connector UI)

  1. Open the Speckle panel in Blender sidebar
  2. Authenticate with your Speckle account
  3. Select the project and model (branch)
  4. Choose objects to send (selection, collection, or all)
  5. Click Send -- the connector converts Blender data to Base objects and pushes to the server

Workflow 2: Receive from Speckle into Blender (Connector UI)

  1. Open the Speckle panel in Blender sidebar
  2. Select the project, model, and version to receive
  3. Click Receive -- the connector downloads Base objects and converts to Blender data
  4. Objects appear in a new collection named after the model

Workflow 3: SpecklePy Programmatic Send

import bpy
from specklepy.objects import Base
from specklepy.objects.geometry import Mesh as SpeckleMesh
from specklepy.transports.server import ServerTransport
from specklepy.api import operations
from specklepy.api.client import SpeckleClient
from specklepy.api.credentials import get_default_account

# Authenticate
client = SpeckleClient(host="https://app.speckle.systems")
account = get_default_account()
client.authenticate_with_account(account)

# Extract mesh data from Blender
bl_obj = bpy.data.objects["MyObject"]
bl_mesh = bl_obj.data
bl_mesh.calc_loop_triangles()

vertices = []
for v in bl_mesh.vertices:
    vertices.extend([v.co.x, v.co.y, v.co.z])

faces = []
for tri in bl_mesh.loop_triangles:
    faces.append(3)  # triangle face count
    faces.extend(tri.vertices)

# Create Speckle Mesh
spk_mesh = SpeckleMesh()
spk_mesh.vertices = vertices
spk_mesh.faces = faces
spk_mesh.units = "m"

# Send
transport = ServerTransport(client=client, stream_id="your_stream_id")
obj_hash = operations.send(base=spk_mesh, transports=[transport])

# Create version
commit_id = client.commit.create(
    stream_id="your_stream_id",
    object_id=obj_hash,
    message="Blender mesh export"
)

Workflow 4: SpecklePy Programmatic Receive

from specklepy.transports.server import ServerTransport
from specklepy.api import operations

transport = ServerTransport(client=client, stream_id="your_stream_id")

# Get latest commit
commits = client.commit.list("your_stream_id", limit=1)
latest = commits[0]

# Receive object graph
received = operations.receive(
    obj_id=latest.referencedObject,
    remote_transport=transport
)

# Convert to Blender mesh
def speckle_mesh_to_blender(spk_mesh, name="SpeckleImport"):
    verts = []
    for i in range(0, len(spk_mesh.vertices), 3):
        verts.append((
            spk_mesh.vertices[i],
            spk_mesh.vertices[i + 1],
            spk_mesh.vertices[i + 2]
        ))

    faces = []
    idx = 0
    while idx < len(spk_mesh.faces):
        n = spk_mesh.faces[idx]
        face = tuple(spk_mesh.faces[idx + 1 : idx + 1 + n])
        faces.append(face)
        idx += n + 1

    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(verts, [], faces)
    mesh.update()

    obj = bpy.data.objects.new(name, mesh)
    bpy.context.collection.objects.link(obj)
    return obj

IFC Data Through Speckle

One-Way Limitation: Bonsai -> Speckle (Send Only)

The IFC/Bonsai to Speckle workflow is ONE-DIRECTIONAL:

Direction Status Result
Bonsai -> Speckle (Send) WORKS IFC elements sent as Speckle Base objects with geometry + basic properties
Speckle -> Bonsai (Receive) DOES NOT WORK Received objects are plain Blender meshes, NOT recognized as IFC elements by Bonsai

What Transfers (IFC -> Speckle -> Blender)

IFC Data Transferred? Notes
Mesh geometry YES Triangulated during conversion
Material assignments YES Basic properties only (diffuse, opacity)
Spatial hierarchy YES Mapped to Speckle Collections -> Blender collections
Basic property sets PARTIAL Flattened to dynamic properties on Base
IfcRelAggregates NO Relationship semantics lost
IfcRelContainedInSpatialStructure NO Spatial containment details lost
Parametric definitions NO Only display mesh transferred
Bonsai editing capability NO Cannot edit as IFC after round-trip

Data Loss Decision Tree

Is full IFC fidelity required?
├── YES → Do NOT use Speckle as transport. Use native IFC files directly.
└── NO → Is visual review sufficient?
    ├── YES → Speckle is appropriate. Geometry + basic materials transfer.
    └── NO → Do you need property data?
        ├── YES (basic props) → Speckle works. Properties flatten but transfer.
        └── YES (full psets) → Use IFC files directly or IfcOpenShell.

Collection Structure Mapping

Blender -> Speckle

Blender Scene Collection           Speckle Root Collection
├── Building                  →    ├── Collection("Building")
│   ├── Level 1               →    │   ├── Collection("Level 1")
│   │   ├── Wall.001          →    │   │   ├── Base(displayValue=[Mesh])
│   │   └── Door.001          →    │   │   └── Base(displayValue=[Mesh])
│   └── Level 2               →    │   └── Collection("Level 2")
└── Site                      →    └── Collection("Site")

Speckle -> Blender

On receive, the connector creates a root collection named [ProjectName] - [ModelName]. All received objects are placed inside, preserving the source hierarchy.


Round-Trip Data Integrity

What SURVIVES Blender -> Speckle -> Blender

  • Mesh vertex positions and face topology
  • Basic material properties (diffuse, opacity, metalness, roughness)
  • Collection hierarchy and object names
  • Object transforms (location, rotation, scale)

What is LOST or DEGRADED

  • Complex shader node trees (reduced to single Principled BSDF parameters)
  • Texture maps and UV-linked images
  • Modifiers (ALWAYS apply modifiers before sending)
  • Shape keys / blend shapes
  • Particle systems
  • Physics simulations
  • Constraints and drivers
  • Custom properties on objects (use Speckle dynamic properties instead)
  • Vertex groups (partial support)

ALWAYS apply all modifiers before sending if the modified geometry is needed. The connector reads the evaluated mesh, but modifier stacks are NOT preserved.


Unit Handling

Blender Unit Speckle Unit String Notes
Meters "m" Default for architectural scenes
Millimeters "mm" Common for BIM data from Revit
Centimeters "cm"
None "m" Blender defaults to meters when unit system is "None"

ALWAYS set bpy.context.scene.unit_settings.length_unit to match the expected Speckle data units before receiving. Unit mismatch causes geometry to appear at wrong scale.


Reference Links

Official Sources