Initial commit: Fusion->Blender->GLB pipeline + contract for ThreeJS bridge
This commit is contained in:
73
BRIDGE_NOTES.md
Normal file
73
BRIDGE_NOTES.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Note operative — produttore GLB (Fusion → Blender)
|
||||
|
||||
Questo file è la sponda **produttore** del [FUSION_GLB_CONTRACT.md](FUSION_GLB_CONTRACT.md).
|
||||
Tutte le risposte ai problemi `[OPEN]` del contratto vivono qui finché non vengono spostate nello stato `[RESOLVED]` del contratto stesso.
|
||||
|
||||
---
|
||||
|
||||
## Risposte ai problemi aperti del contratto §8
|
||||
|
||||
### 1) Motion link con `joint1: null`
|
||||
**Stato:** è un limite dell'API Fusion. Quando l'utente crea il motion link tramite la finestra "Collegamento movimento", Fusion lo memorizza con un riferimento interno (entity-token) ma il proxy `motionLink.entityOne` può ritornare `None` se il joint è stato creato/rinominato dopo il link. L'add-in **non** può inventarsi il nome.
|
||||
|
||||
**Workaround consigliato a chi consuma:**
|
||||
- I 5 driver (`A`, `X`, `Y`, `PEN`, `Z`) NON sono mai `null` su `joint2`: i link con `joint2 == driver` sono usabili anche senza `joint1` (basta non propagare nulla).
|
||||
- Per i link con `joint2: null` AND `joint1: null` (es. `"Collegamento movimento 32"`, `"Collegamento movimento 4"`): sono rumore, ignorabili.
|
||||
- Per i link con `joint1: null` ma `joint2` valorizzato (es. `"Collegamento movimento 14"` → `Motore asse X`, `"Collegamento movimento 28"` → `Rivoluzione 26`, `"Collegamento movimento 38"` → `Asse Penna `):
|
||||
- **`Motore asse X`** è il driver, non ha bisogno di slave esterni — la traslazione del carrello X è già descritta dal rigid group `Gruppo rigido 6` (`end stop X PIastrina:1 | binario SX:1 | Cinghia T5:1`).
|
||||
- **`Asse Penna `** idem: lo slider muove direttamente `guida lineare:1`, gli altri pezzi seguono via rigid groups.
|
||||
|
||||
→ **TL;DR per il viewer:** ignora tranquillamente i link con `joint1: null`. Tutta la propagazione necessaria passa dai rigid groups + i 5 driver diretti.
|
||||
|
||||
### 2) `Motore A` esiste in `asBuiltJoints`?
|
||||
**Confermato.** Verificato sul file corrente: presente con nome esatto `"Motore A"`, tipo `revolute`, `child = "6627T331_Stepper Motor (1) (1):1"`, `axis ≈ [0, 0, 1]`.
|
||||
|
||||
L'eventuale mismatch lato viewer dipende dal `child` name: nel JSON è esattamente `"6627T331_Stepper Motor (1) (1):1"` (due " (1)" di seguito), che nasce dal fatto che in Fusion il componente è stato copiato/incollato due volte. Se il viewer non lo trova, il bug è nel matching, non nell'export.
|
||||
|
||||
### 3) Convenzione multi-macchina
|
||||
Da concordare quando servirà. Proposta minimale:
|
||||
```
|
||||
exports/
|
||||
plotter/
|
||||
plotter.glb
|
||||
plotter.joints.json
|
||||
<altra_macchina>/
|
||||
<altra_macchina>.glb
|
||||
<altra_macchina>.joints.json
|
||||
```
|
||||
Lato viewer un file `machines.json` indicizza nome → coppia (glb, json, DRIVERS map).
|
||||
|
||||
---
|
||||
|
||||
## Stato attuale dell'export (rispetto alla checklist §6 del contratto)
|
||||
|
||||
| Voce checklist | Stato | Note |
|
||||
|---|---|---|
|
||||
| GLB in metri | ✅ | `build_glb_from_fusion_export.py` applica `scaleFactor=0.01` al root, mesh OBJ importate in cm sono rimpicciolite di 100× → metri |
|
||||
| Gerarchia Empty 1:1 | ✅ | Pass 1 crea un Empty per ogni `node` del `hierarchy.json` |
|
||||
| `fusion_name` e `fusion_path` per ogni Empty | ✅ (dal 2026-06-09) | Aggiunti come custom properties; coincidono byte-per-byte con `Joint.child` / `Joint.childFullPath` |
|
||||
| Mesh figlie degli Empty, non joinate | ✅ | OBJ importati e re-parentati all'Empty corrispondente |
|
||||
| Stato salvato = posa "tutti i driver a 0" | ⚠️ | Posa "as built" di Fusion al momento dell'export. Se l'utente esporta con `slideValue ≠ 0` o `rotationValue ≠ 0` la posa neutra slitta. **Convenzione:** in Fusion riportare i 5 driver a zero prima di lanciare lo script. |
|
||||
| Manifest embedded `scene["fusion"]` | ✅ | Il GLB contiene già il JSON completo in `scene.extras.fusion` |
|
||||
|
||||
---
|
||||
|
||||
## Comandi operativi
|
||||
|
||||
Rigenera GLB dopo modifica codice:
|
||||
```powershell
|
||||
.\build_glb.bat "C:\Users\croce\OneDrive\Desktop\export"
|
||||
```
|
||||
|
||||
Riallinea script Fusion (da fare dopo ogni `edit` di `ExportKinematicGraph.py`):
|
||||
```powershell
|
||||
python -c "import py_compile; py_compile.compile(r'C:\Users\croce\OneDrive\Desktop\export grafo fusion\ExportKinematicGraph.py', doraise=True); print('OK')"; if($LASTEXITCODE -eq 0){ Copy-Item -Force 'C:\Users\croce\OneDrive\Desktop\export grafo fusion\ExportKinematicGraph.py' (Join-Path $env:APPDATA 'Autodesk\Autodesk Fusion 360\API\Scripts\ExportKinematicGraph'); Write-Host "Sync OK" }
|
||||
```
|
||||
|
||||
Sanity-check sui driver nel JSON:
|
||||
```powershell
|
||||
$j = Get-Content 'C:\Users\croce\OneDrive\Desktop\export\joints.json' -Raw | ConvertFrom-Json
|
||||
$names = @('Motore asse X','Motore asse Y','Asse Penna ','asse Z pneumatico M5?')
|
||||
foreach($n in $names){ $j.joints | Where-Object name -eq $n | Select-Object name,type,child,axis,@{n='limits';e={ if($_.slideLimits){'slide '+$_.slideLimits.minimumValue+'..'+$_.slideLimits.maximumValue}elseif($_.rotationLimits){'rot '+$_.rotationLimits.minimumValue+'..'+$_.rotationLimits.maximumValue} }} | Format-List }
|
||||
$j.asBuiltJoints | Where-Object name -eq 'Motore A' | Select-Object name,type,child,axis | Format-List
|
||||
```
|
||||
Reference in New Issue
Block a user