This commit is contained in:
sorlinv
2026-02-20 19:27:27 +01:00
commit b556cce88c
23 changed files with 8182 additions and 0 deletions

293
CLAUDE.md Normal file
View File

@@ -0,0 +1,293 @@
# CLAUDE.md — Multi Render Blender
## Projet
Application **Electron** qui pilote **Blender en mode background** (`blender -b`) pour effectuer des rendus multi-cameras.
Chaque camera possede ses propres parametres (resolution, frames, format, dossier de sortie).
L'application construit une file de rendu (render queue) et execute les commandes Blender une par une,
avec affichage de l'image rendue apres chaque etape.
---
## Stack technique
| Couche | Technologie |
|--------------|--------------------------------------|
| Application | **Electron** (main + renderer) |
| Backend | **Node.js** (`child_process.spawn`) |
| Frontend | **HTML / CSS / JS vanilla** |
| CSS | **Bootstrap 5** via CDN |
| Icones | **Material Design Icons (MDI)** CDN |
| Scripts | **Python** (executes par Blender) |
| Rendu | **Blender CLI** (`blender -b`) |
> Pas de React, pas de framework JS lourd. HTML/CSS/JS natif uniquement (conforme a la Norme).
---
## Architecture des fichiers
```
multi_render_blender/
|-- package.json
|-- main.js # Process principal Electron
|-- preload.js # Bridge IPC (contextBridge)
|-- src/
| |-- renderer/
| | |-- index.html # Page principale
| | |-- styles/
| | | |-- Main.css
| | |-- scripts/
| | |-- App.js # Point d'entree renderer
| | |-- CameraList.js # Gestion liste cameras
| | |-- CameraConfig.js # Formulaires config par camera
| | |-- RenderQueue.js # Affichage file de rendu
| | |-- PreviewPanel.js # Affichage image rendue
| | |-- ProgressBar.js # Barre de progression
| | |-- ConsoleLog.js # Console logs UI
| |-- main/
| | |-- BlenderProcess.js # Spawn et gestion process Blender
| | |-- QueueManager.js # File d'attente de rendu
| | |-- CameraParser.js # Extraction cameras depuis .blend
| | |-- ConfigManager.js # Sauvegarde/chargement config JSON
| | |-- PathResolver.js # Gestion chemins dynamiques
| |-- python/
| |-- list_cameras.py # Script : lister les cameras
| |-- setup_render.py # Script : configurer scene avant rendu
|-- config/
| |-- default_config.json # Config par defaut
|-- CLAUDE.md
|-- Norme.md
```
### Conventions de nommage fichiers
- **Fichiers JS** : `PascalCase.js` (ex: `QueueManager.js`)
- **Fichiers Python** : `snake_case.py` (ex: `list_cameras.py`)
- **Fichiers CSS** : `PascalCase.css` (ex: `Main.css`)
- **Fichiers HTML** : `snake_case.html`
---
## Conventions de code (resume Norme.md)
### JavaScript / Node.js
| Regle | Detail |
|------------------------------|--------------------------------------------------|
| Variables | `snake_case` avec prefixes (`nb_`, `is_`, `list_`, `str_`, `obj_`, `has_`) |
| Classes | `PascalCase`, un seul mot si possible |
| Constantes globales | `MAJUSCULES` |
| Indentation | 4 espaces |
| Point-virgule | Obligatoire |
| Fonctions | Flechees preferees (`() => {}`) |
| `async/await` | **INTERDIT** — utiliser `.then()` / `.catch()` |
| `forEach()` | **INTERDIT** — utiliser `for...of` |
| Accolades | Meme ligne que l'instruction |
| Variables | Declarees en debut de fonction |
| Frameworks | Aucun (JS natif uniquement) |
### Python (scripts Blender)
| Regle | Detail |
|------------------------------|--------------------------------------------------|
| Variables | `snake_case` avec memes prefixes que JS |
| Type hints | **Obligatoires** sur toutes les signatures |
| Docstrings | **Obligatoires** en francais sur fonctions publiques |
| `print()` | Interdit en production, utiliser `logging` |
| Constantes globales | `MAJUSCULES` |
| Imports | Standard > Tiers > Projet |
| Erreurs | `try/except` doit loguer ET remonter |
### Gestion des erreurs
- Toute erreur doit etre **loguee** (console technique) ET **affichee a l'utilisateur** (UI).
- Aucune erreur ne doit etre ignoree silencieusement.
- En JS : toujours un `.catch()` sur chaque chaine de promesse.
- En Python : tout `try/except` doit loguer l'erreur ET la remonter.
---
## Architecture Electron (IPC)
```
[Renderer Process] <--IPC--> [Main Process] <--spawn--> [Blender CLI]
(UI) preload (Node.js) (blender -b)
```
### Communication IPC
Le `preload.js` expose une API via `contextBridge` :
```js
// preload.js — API exposee au renderer
contextBridge.exposeInMainWorld("api", {
select_blend_file: () => ipcRenderer.invoke("select-blend-file"),
get_cameras: (str_path) => ipcRenderer.invoke("get-cameras", str_path),
start_render: (obj_config) => ipcRenderer.invoke("start-render", obj_config),
pause_render: () => ipcRenderer.invoke("pause-render"),
stop_render: () => ipcRenderer.invoke("stop-render"),
on_render_progress: (fn_callback) => ipcRenderer.on("render-progress", fn_callback),
on_render_complete: (fn_callback) => ipcRenderer.on("render-complete", fn_callback),
on_render_error: (fn_callback) => ipcRenderer.on("render-error", fn_callback),
on_preview_update: (fn_callback) => ipcRenderer.on("preview-update", fn_callback),
});
```
> Toute communication entre renderer et main passe par IPC. Jamais d'acces direct a `child_process` ou `fs` depuis le renderer.
---
## Fonctionnalites principales
### 1. Chargement fichier .blend
- Selection via dialog natif Electron (`dialog.showOpenDialog`)
- Extraction des cameras via :
```
blender -b fichier.blend --python-expr "import bpy; print([o.name for o in bpy.data.objects if o.type=='CAMERA'])"
```
- Parsing du stdout pour recuperer la liste
### 2. Configuration par camera
Chaque camera possede :
- `is_enabled` : activer/desactiver
- `nb_resolution_x` : resolution horizontale
- `nb_resolution_y` : resolution verticale
- `nb_frame_start` : premiere frame
- `nb_frame_end` : derniere frame
- `str_format` : format de sortie (PNG, JPEG, EXR)
- `str_output_path` : dossier de sortie
### 3. Modes de rendu
- **Mode 1 — Camera par camera** : toutes les frames d'une camera avant de passer a la suivante
- **Mode 2 — Frame par frame** : toutes les cameras pour une frame avant de passer a la suivante
### 4. Commande Blender generee
```bash
blender -b fichier.blend \
--python-expr "
import bpy;
scene=bpy.context.scene;
scene.camera=bpy.data.objects['NomCamera'];
scene.render.resolution_x=1920;
scene.render.resolution_y=1080
" \
-o ./renders/NomCamera/frame_##### \
-F PNG \
-f 120
```
### 5. File d'attente (Render Queue)
- Construction d'une queue interne (tableau d'objets commande)
- Execution sequentielle : attendre la fin du process avant le suivant
- Controles : **Start** / **Pause** / **Stop**
### 6. Preview de l'image rendue
Workflow apres chaque rendu :
```
Render termine -> Process exit -> Lire image -> Afficher preview -> Lancer suivant
```
- Detection du fichier genere via le chemin de sortie
- Affichage dans un panneau preview (balise `<img>` avec rechargement)
### 7. Indicateurs UI
- Camera en cours
- Frame en cours
- Progression (X / total)
- Image preview
- Console logs
---
## Modeles de donnees
### Configuration camera
```js
let obj_camera_config = {
str_name: "Camera.001",
is_enabled: true,
nb_resolution_x: 1920,
nb_resolution_y: 1080,
nb_frame_start: 1,
nb_frame_end: 250,
str_format: "PNG",
str_output_path: "./renders/Camera.001/"
};
```
### Element de la queue
```js
let obj_queue_item = {
str_camera_name: "Camera.001",
nb_frame: 120,
nb_resolution_x: 1920,
nb_resolution_y: 1080,
str_format: "PNG",
str_output_path: "./renders/Camera.001/frame_00120.png",
str_status: "pending" // "pending" | "rendering" | "done" | "error" | "skipped"
};
```
### Configuration globale
```js
let obj_render_config = {
str_blend_file: "/chemin/vers/fichier.blend",
str_render_mode: "camera_by_camera", // "camera_by_camera" | "frame_by_frame"
list_cameras: [ /* obj_camera_config */ ]
};
```
---
## Regles pour l'IA
1. **Respecter strictement la Norme.md** — c'est la reference absolue pour le style de code.
2. **Jamais de `async/await`** — utiliser `.then()` / `.catch()` avec retour de promesse.
3. **Jamais de `forEach()`** — utiliser `for...of`.
4. **Nommage strict** — `snake_case` avec prefixes, `PascalCase` pour classes et fichiers JS.
5. **Separation IPC** — le renderer ne touche jamais directement Node.js APIs.
6. **Une fonction = une responsabilite** — extraire la logique repetee.
7. **Gestion d'erreurs systematique** — `.catch()` sur chaque promesse, message utilisateur visible.
8. **Pas de dependance externe inutile** — seulement Bootstrap 5 et MDI en CDN.
9. **Python : type hints + docstrings** obligatoires sur les scripts Blender.
10. **Pas de `print()` en Python** — utiliser `logging` (sauf stdout pour communication avec Node.js).
11. **Tester chaque commande Blender** avant de la considerer fonctionnelle.
12. **Commenter rarement** — le code doit etre autoportant via le nommage.
13. **4 espaces d'indentation**, point-virgule obligatoire en JS.
---
## Bonus (a implementer progressivement)
- [ ] Skip si image deja existante
- [ ] Resume apres crash
- [ ] Sauvegarde / chargement config JSON
- [ ] Drag & drop du fichier .blend
- [ ] Multi-thread (plusieurs Blender en parallele)
- [ ] Detection automatique du chemin Blender installe
- [ ] Estimation du temps restant
---
## Commandes utiles
```bash
# Lancer l'app en dev
npm start
# Lister les cameras d'un .blend
blender -b fichier.blend --python-expr "import bpy; print([o.name for o in bpy.data.objects if o.type=='CAMERA'])"
# Render une frame specifique
blender -b fichier.blend --python-expr "import bpy; scene=bpy.context.scene; scene.camera=bpy.data.objects['Camera']" -o //output_##### -F PNG -f 1
# Packager l'app
npx electron-builder
```
---
## Git
- Un commit = une fonctionnalite complete.
- Aucun commit casse ou incomplet.
- Messages de commit clairs et descriptifs.