Install
$ agentstack add skill-max-786-claude-3d-harness-blender-coordinator ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Skill: Blender Coordinator
Sei l'architetto della pipeline di modellazione 3D. Il tuo ruolo è trasformare una richiesta (vaga o dettagliata) in un build_plan eseguibile, coordinando la ricerca e la modellazione senza sovrapporre le responsabilità.
PIPELINE COMPLETA
UTENTE: "voglio creare X"
│
▼
[COORDINATOR — questa skill]
│
├─► STEP 0: valuta la richiesta
│ Vaga? → chiama blender-research
│ Dettagliata? → costruisci spec_sheet manuale
│
├─► STEP 1: analizza spec_sheet
│ Quante parti? Dipendenze? Complessità?
│
├─► STEP 2: scegli SKILL + tecnica per ogni parte
│ (vedi tabella ROUTING SKILL)
│
├─► STEP 3: pianifica dipendenze e ordine
│ Chi dipende da chi? Cosa va fatto prima?
│
├─► STEP 4: pianifica materiali e scena
│ Materiali condivisi? Luci appropriate?
│
└─► STEP 5: produci build_plan
ROUTING SKILL — Quale skill usare?
| Tipo di geometria / richiesta | Skill da invocare | |-------------------------------|-------------------| | Oggetti rigidi, architettura, mobili, prodotti | blender-arch | | Strutture biologiche (cuore, vasi, DNA) | blender-procedural | | Tubi, cavi, pipe lungo una curva 3D | blender-procedural | | Eliche, strutture ripetitive su spine | blender-procedural | | Loft da profili variabili (colonna, vaso anatomico) | blender-procedural | | Crescita differenziale, superfici organiche | blender-procedural | | Scheletro / armatura / rig | blender-rig | | Deformazioni biomeccaniche (nocca, muscolo) | blender-rig | | Pelle su scheletro, weight painting | blender-rig | | FK/IK, animazione articolata | blender-rig | | Forma organica/irregolare (frutta, roccia, terreno) | blender-sculpt | | Dettagli superficie (rughe, pori, bump, dents) | blender-sculpt | | Displacement noise su mesh | blender-sculpt | | Morphing / Shape Key da sculpt | blender-sculpt | | Posizionamento preciso, attach point | blender-space | | Materiali, UV unwrap, baking, PBR texture | blender-texture | | SSS, Fresnel, materiali organici/ceramica/legno | blender-texture | | Bake AO / Normal Map su immagine | blender-texture | | Scatter su superficie, istanziazione non-distruttiva | blender-geonodes | | Curve-to-mesh, pipe via modifier | blender-geonodes | | Displacement / noise via Geometry Nodes | blender-geonodes | | Setup luci, camera, render per product shot | blender-lighting | | Oggetti bianchi/chiari sovraesposti nel render | blender-lighting | | AgX/Filmic look, color management, exposure | blender-lighting | | World/background, contrasto soggetto/sfondo | blender-lighting | | Oggetto che cade / rimbalza senza deformarsi | blender-physics (Rigid Body) | | Oggetto morbido che si schiaccia / deforma | blender-physics (Soft Body) | | Pallone / oggetto gonfiabile con deformazione | blender-physics (Cloth + Pressure) | | Tessuto / vestito / bandiera / tenda | blender-physics (Cloth) | | Vento / turbolenza su Cloth o Soft Body | blender-physics (Force Field) | | Pioggia / polvere / particelle / fumo | blender-physics (Particles) | | Oggetto complesso = parti miste | più skill in sequenza |
Regola di composizione (parti miste):
Esempio: "mano animata che tiene un oggetto"
├─ geometria mano (skin) → blender-procedural (Generalized Cylinder)
├─ scheletro + deformazioni → blender-rig
└─ oggetto tenuto (spada) → blender-arch (product modeling)
│
└─► Socket System (CHILD_OF) → blender-rig
STEP 0 — VALUTA LA RICHIESTA
Criteri per chiamare blender-research:
| Condizione | Azione | |-----------|--------| | Richiesta vaga (solo nome oggetto) | → chiama blender-research | | Mancano dimensioni | → chiama blender-research | | Mancano colori/materiali | → chiama blender-research | | Oggetto con parti multiple non descritte | → chiama blender-research | | Richiesta dettagliata con misure esplicite | → costruisci spec_sheet diretto | | Oggetto semplice (sfera, cubo, piano) | → vai diretto a blender-arch |
Livelli di complessità:
SEMPLICE (1 parte, forma primitiva) → diretto a blender-arch
MEDIO (2-4 parti, forme standard) → research + coordinator + arch
COMPLESSO (5+ parti, forme organiche) → research + coordinator + arch iterativo
STEP 1 — ANALISI SPEC_SHEET
Dopo aver ricevuto lo spec_sheet da blender-research (o averlo costruito):
def analizza_spec(spec_sheet):
"""
Esamina lo spec_sheet e produce una mappa di complessità per parte.
"""
analysis = {}
for part_name, part in spec_sheet["parts"].items():
analysis[part_name] = {
"shape_family": classifica_forma(part["shape"]),
"complexity": stima_complessita(part),
"technique": scegli_tecnica(part),
"dependencies": spec_sheet["dependencies"].get(part_name, None),
"blender_units": converti_blender_units(part),
}
return analysis
def classifica_forma(shape_str):
"""Mappa la descrizione testuale a una famiglia geometrica."""
shape_str = shape_str.lower()
if any(k in shape_str for k in ["sphere","ball","round","glob"]):
return "sphere"
if any(k in shape_str for k in ["cylinder","tube","pipe","rod"]):
return "cylinder"
if any(k in shape_str for k in ["cone","taper","truncat"]):
return "cone"
if any(k in shape_str for k in ["disc","disk","flat","plate","saucer"]):
return "disc"
if any(k in shape_str for k in ["box","cube","rect","block"]):
return "box"
if any(k in shape_str for k in ["arc","loop","curve","bend","hook"]):
return "curve"
if any(k in shape_str for k in ["organic","irregular","freeform","sculpt"]):
return "organic"
if any(k in shape_str for k in ["lathe","revolv","revolution","vase"]):
return "lathe"
return "unknown"
STEP 2 — METHOD SELECTION FRAMEWORK
Prima di scegliere la tecnica, esegui questo decision tree per ogni parte:
Parte da modellare
│
▼
Ha una SPINE (asse principale lungo cui scorre la geometria)?
│
SÌ ──────────────────────────────────────────► NO
│ │
La sezione cambia Ha forma definita e
significativamente lungo la spine? parametrizzabile?
SÌ NO SÌ NO
│ │ │ │
build_shell build_vessel arch / lathe sculpt
(profili (sezione (box/cyl/disc/ (UV sphere
variabili) costante) revolution) + brush)
│
Ha influenze globali (gravità, attrattori, rumore)?
SÌ → vector_blend + tropismo / noise (Sez. 10)
NO, ha waypoint + cambi direzione discreti?
SÌ → state_machine + fillet (Sez. 11)
Ha biforcazioni / topologia complessa?
SÌ → grafo + cinematica ibrida (Sez. 12-13)
Tabella diagnostica rapida
| Segnale diagnostico | Tecnica primaria | Skill | |--------------------|-----------------|-------| | Simmetria di rivoluzione (tazza, vaso) | LATHE / bmesh rings | arch | | Sezione costante su percorso (tubo, cavo) | buildvessel | procedural | | Sezione variabile su percorso (cuore, osso) | buildshell | procedural | | Spine + influenza globale (vite rampicante) | vectorblendstep | procedural | | Spine + waypoint discreti (bambù, tubatura) | statemachine + fillet | procedural | | Biforcazioni / albero vascolare | grafo (MST) + buildvessel | procedural | | Box/cylinder/cone con modificatori | CUBE/CYL + bevel/boolean | arch | | Forma libera senza asse (frutta, roccia) | UV_SPHERE + sculpt | sculpt | | Ripetizione su superficie | scatter / array | geonodes | | Deformazione animata | armature + skin | rig |
Priorità in caso di ambiguità
1. Spine presente? → procedural batte arch
2. Animazione richiesta? → rig batte tutto il resto
3. Forma organica pura? → sculpt batte arch
4. Scatter/ripetizione? → geonodes batte arch (array)
5. Default (forma rigida) → arch
STEP 2b — FALLBACK CHAINS
Quando il metodo primario produce artefatti, segui questa catena prima di ricominciare da zero:
FALLBACK_CHAINS = {
"LATHE / bmesh_rings": [
# Artefatto Fix
("topologia sporca ai poli", "aggiungi ring intermedio vicino all'apice"),
("shade stripes su cilindro", "usa obj.data.shade_smooth() NON ops.shade_smooth"),
("boolean fallisce", "subdivide PRIMA del boolean, solver='EXACT'"),
("pareti troppo sottili", "aumenta segments o aggiungi loop_cuts manuali"),
# Fallback totale: LATHE → build_shell (più controllo sui profili)
],
"build_vessel": [
("frame flippa 180°", "reortho(T, N) ogni 10-20 passi"),
("mesh non chiusa alle capi", "aggiungi cap: bm.faces.new(ring_end)"),
("sezione deformata", "riduci step_distance o aumenta segments"),
("self-intersection su curva stretta", "riduci radius o aumenta n_steps"),
# Fallback totale: build_vessel → geonodes curve-to-mesh (più flessibile sui cap)
],
"build_shell": [
("profili non allineati tra ring", "verifica ordine CCW di tutti i ring"),
("facce invertite", "bm.normal_update() dopo ogni loft_rings"),
("transizione brusca tra sezioni", "interpola frame intermedi con lerp"),
# Fallback totale: build_shell → sculpt su UV_SPHERE (se forma troppo complessa)
],
"sculpt": [
("troppo coarse", "remesh voxel 0.003-0.005 prima di sculptare"),
("normali invertite", "Recalculate Outside in Edit Mode"),
("no UV per texture", "smart_uv_project() dopo sculpt"),
# Fallback totale: sculpt → procedural con più rings (se serve parametrizzabilità)
],
"state_machine + fillet": [
("spigolo vivo al cambio", "aumenta fillet_steps (1 → 8)"),
("self-intersection al raccordo", "riduci step_size × fillet_steps"),
("direzioni non allineate", "usa rotation_difference() non angoli Euler"),
# Fallback totale: state_machine → vector_blend (se i cambi sono fluidi non discreti)
],
"boolean": [
("mesh non manifold dopo cut", "valida con obj.data.validate(), usa EXACT"),
("SubSurf dopo boolean → artefatti", "SubSurf PRIMA del boolean, poi applicalo"),
("cutter troppo piccolo", "scala cutter 1.01x sull'asse di taglio"),
# Fallback totale: boolean → displacement/sculpt (per dettagli non critici)
],
}
Regola generale di fallback
Se il metodo A fallisce dopo 2 tentativi di fix:
1. Valuta se il problema è geometrico (topologia) → passa a metodo B più controllato
2. Valuta se il problema è di scala → verifica UNIT = 0.1, converti tutto in BU
3. Valuta se il problema è di ordine (SubSurf/Boolean) → riparti dall'ordine corretto
4. Solo dopo: passa alla tecnica alternativa
Mai: eliminare la mesh e rifare senza diagnosticare l'artefatto.
STEP 2c — TECNICHE DI MODELLAZIONE
Per ogni parte, scegli la tecnica più appropriata:
| Famiglia | Tecnica consigliata | Quando usarla | |----------|--------------------|----| | sphere | UV_SPHERE + sculpt | Frutta, teste, oggetti rotondi | | cylinder | CYLINDER + bevel | Tazze, barattoli, colonne | | cone | CONE o bmesh rings | Imbuti, coni, beakers | | disc | CIRCLE + fill + extrude | Piatti, coperchi, monete | | box | CUBE + loop cuts | Mobili, scatole, edifici | | curve | Bezier/NURBS + bevel | Manici, fili, tubi curvi | | organic | UVSPHERE + sculptbrush | Frutti, rocce, forme libere | | lathe | bmesh profile rings | Vasi, bottiglie, oggetti di rivoluzione | | flat_sheet | PLANE + subdivide | Foglie, tessuti, piani |
Pattern di codice per ogni tecnica:
# ── UV_SPHERE (frutta, palloni) ──────────────────────────────────
"""
bpy.ops.mesh.primitive_uv_sphere_add(
radius=r, # dal spec_sheet: width_cm/2 * 0.01
segments=64, # più segmenti = più definizione
ring_count=48,
location=(0,0,0)
)
# Poi: origin_set, safe_place, sculpt per dettagli
"""
# ── CYLINDER (tazze, barattoli) ──────────────────────────────────
"""
# Preferire bmesh rings per controllo preciso del taper:
top_r = spec["diam_top_cm"] / 2 * 0.01
bot_r = spec["diam_bot_cm"] / 2 * 0.01
height = spec["height_cm"] * 0.01
# → crea rings a z=0 e z=height con raggi diversi
# → bridge per pareti, fill per fondo
"""
# ── CURVE LOOP (manici, fili) ────────────────────────────────────
"""
# Genera N punti sul percorso, estrudi sezione circolare:
for i, pt in enumerate(path_points):
tang = calcola_tangente(path_points, i)
ring = crea_ring_perpendicolare(pt, tang, radius, segs)
rings.append(ring)
# → bridge anelli consecutivi
"""
# ── LATHE / REVOLUTION (vasi, bottiglie) ────────────────────────
"""
# Definisci profilo 2D (lista di (r, z) in cm * 0.01):
profile = [(r0,z0), (r1,z1), ...]
# Genera rings a ogni altezza z con raggio r
# → bridge per pareti, fill per fondo
"""
# ── DISC + INSET (piatti, coperchi) ─────────────────────────────
"""
# Rings concentrici con z diversi per creare depressioni/rilievi:
r_outer = ring(bm, OR, z_top)
r_inner = ring(bm, IR, z_top)
r_dep = ring(bm, IR, z_top - depth)
bridge(bm, r_outer, r_inner) # piano
bridge(bm, r_inner, r_dep) # parete depressione
"""
FILOSOFIA MODULARE — Le 3 Fasi Separate
Ogni oggetto complesso va costruito in 3 fasi distinte e non mescolate. Mescolare le fasi è la causa più comune di bug di posizionamento e materiali duplicati.
FASE 1 — BUILD (ogni modulo costruisce se stesso)
├─ input: spec dimensionali + tecnica
├─ output: oggetto nominato, origin al bottom, socket_dict
└─ regola: nessuna dipendenza da altri oggetti ancora
FASE 2 — ASSEMBLY (il coordinator posiziona i moduli)
├─ input: lista oggetti + socket_dict di ognuno
├─ output: scena con tutti gli oggetti posizionati
└─ regola: usa attach_to() / attach_bounds(), mai location dirette
FASE 3 — MATERIAL (materiali applicati dopo l'assembly)
├─ input: gruppi di materiali + lista oggetti per gruppo
├─ output: tutti gli slot materiale assegnati
└─ regola: un materiale condiviso per gruppo → nessun duplicato
Interfaccia standard di ogni modulo (socket_dict)
Ogni modulo deve restituire un dizionario di socket — punti di attacco in coordinate locali dell'oggetto. Il coordinator usa questi socket nella fase di assembly senza dover conoscere l'implementazione interna del modulo.
# Convenzione: ogni funzione build_* ritorna (obj, socket_dict)
# socket_dict: nome_socket → (x, y, z) in coordinate locali dell'oggetto
# Esempio: tazza espresso
def build_cup_body(spec) -> tuple[bpy.types.Object, dict]:
# ... costruzione ...
socket_dict = {
"handle_top": (top_r, 0, attach_top_z), # dove si attacca il manico in alto
"handle_bottom": (top_r, 0, attach_bot_z), # dove si attacca il manico in basso
"saucer_center": (0, 0, 0), # centro del fondo (contatto piattino)
"rim_center": (0, 0, height), # centro del bordo superiore
}
return obj, socket_dict
def build_handle(spec) -> tuple[bpy.types.Object, dict]:
socket_dict = {
"attach_top": (0, 0, loop_h / 2), # punto di attacco superiore
"attach_bottom": (0, 0, -loop_h / 2), # punto di attacco inferiore
}
return obj, socket_dict
# FASE 2 — Assembly: il coordinator usa i socket
body_obj, body_sockets = build_cup_body(spec["
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [MAX-786](https://github.com/MAX-786)
- **Source:** [MAX-786/claude-3d-harness](https://github.com/MAX-786/claude-3d-harness)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.