Files
slice_wrap_addon/CLAUDE.md
T
angeandClaude Opus 5.5 bc01a01e09 Préparation pour la chaîne d'outils a2m
- Manifest : Blender 5.1 minimum, maintainer Ange-Marie MAURIN, website
  (fiche a2msystemes.org), .a2m/ exclu du paquet
- CHANGELOG.md (en) et CHANGELOG.fr.md (fr) : historique 1.0.0 → 1.4.0 repris
  du CLAUDE.md, mise au format a2m dans la section non publiée
- tools/Build-Package.ps1 et tools/New-GiteaRelease.ps1 retirés : remplacés
  par a2m build et a2m release
- README, CLAUDE.md, .gitignore : commandes a2m, historique dans le CHANGELOG,
  note « dépôt d'extensions » rattachée à APC

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:14:32 +02:00

12 KiB
Raw Permalink Blame History

Slice Wrap — add-on Blender : surface propre à partir d'un maillage troué, wrap, nettoyage et analyse

L'utilisateur parle français : répondre et documenter en français. Libellés d'interface Blender en anglais (convention Blender), descriptions / docstrings / README en français.

But

Transformer un maillage troué, à doubles parois ou bruité (scan, génération IA type Pixal3D / Trellis — ex. tête brute de 11,8 M faces) en une surface fermée, propre et détaillée, prête à sculpter ou à retopologiser, puis fournir une analyse de forme (densité de détail, tags, direction des plis). Né pendant le projet personnage « Chiara » (C:\Users\a-mma\Desktop\CharacterDesign\Work3D) : le Voxel Remesh de Blender donnait du moiré et des fuites sur la tête générée ; un script de remplissage voxel tranche par tranche a résolu le problème, d'où l'add-on.

Concept à préserver : Slice Wrap = « maillage troué → surface propre + analyse ». Aucune logique de topologie / flow ici : la retopologie guidée est un projet séparé, Slice Retopo (E:\0000WorkTechnique\0002dev\slice_retopo_addon), qui lit les attributs produits par Slice Wrap.

Pipeline (bouton « Slice Wrap » = étapes 1 → 3, + 4 si « Despike After »)

  1. Envelope (core.build_envelope) — sur la source (jamais modifiée) : échantillonnage de surface (sommets + points sur les triangles > ½ voxel) → voxels occupés → fermeture morphologique (close_iter) → remplissage 3D global ∪ remplissage 2D tranche par tranche selon X, Y, Z (un trou ne fait fuir que les tranches qu'il traverse) → ouverture (open_iter, filaments) → surface en cubes → Voxel Remesh de Blender sur ce volume déjà plein (aucune fuite possible) → plus grande pièce → lissage de Taubin (smooth_iter). Numpy pur (pas de scipy / skimage dans le Python de Blender).
  2. Wrap Setup — gonflement le long des normales (défaut 2 voxels) pour que l'enveloppe soit entièrement au-dessus de la peau, Multires (niveaux, Catmull-Clark) puis Shrinkwrap : Project, aucun axe (= le long des normales), Negative seul, Limit (défaut 4 × gonflement), Cull Off, Offset 0.
  3. Freeze — copie évaluée → multires_reshape (la projection est figée DANS les niveaux du Multires : base légère + détails) ; Repair Missed Rays : chaque sommet est comparé avant / après projection ; resté sur place (< 0,3 × gonflement → aiguille) ou parti trop loin (> 2 × la moyenne de ses voisins → creux sur une paroi interne) = raté, reconstruit par diffusion depuis ses voisins réussis.
  4. Despike (manuel ou en fin de chaîne) — ne corrige qu'un sommet isolé : écart à la moyenne des voisins

    Distance (0 = longueur moyenne d'arête) ET > Isolation × l'écart moyen des voisins ; Strength, Iterations ; filtres par groupes de sommets (poids = intensité ; liste vide = toute la surface ; liste non vide mais aucun groupe trouvé = refus) ; Protect Detail (× (1 − détail)).

  5. Analyze (optionnel, ne modifie pas la géométrie) — tenseur de covariance des normales sur Neighborhood anneaux (valeurs propres λ1 ≥ λ2 ≥ λ3) + courbure moyenne signée : sw_detail (λ2+λ3 normalisé), sw_anisotropy ((λ2−λ3)/(λ2+λ3)), sw_curvature, sw_shape (0 Flat, 1 Bulge, 2 Hollow, 3 Ridge, 4 Fold, 5 Saddle), sw_flow (vecteur propre de λ3 = direction du pli), couleurs SW_Detail_Color / SW_Shape_Color, groupes SW_Detail, SW_Bulge, SW_Hollow, SW_Ridge, SW_Fold, SW_Saddle. Écrit sur les N premiers sommets du maillage évalué = sommets de base.

Décisions et pourquoi

  • Pas de vrai modificateur (impossible en Python) → opérateurs + paramètres mémorisés sur le résultat (slice_wrap_source, slice_wrap_pitch, slice_wrap_inflate) + Regenerate (recalcul sur place).
  • Nom du résultat = source + Suffix (défaut _slicewrapped), numéroté .001, .002… : aucun objet existant n'est jamais écrasé (avant la v1.3, relancer remplaçait le maillage existant — corrigé). Seul Regenerate recalcule l'objet actif. Refusé si l'enveloppe est déjà wrappée (Multires / Shrinkwrap).
  • Collection optionnelle (défaut cochée, SliceWrapCollection) : réutilisée si elle existe (contenu intact), sinon créée et liée à la scène ; décochée → collections de la source.
  • Voxel Relative / Absolute — conservé (décision utilisateur, 2026-10-17) : Relative (défaut 0,6 % de la plus grande dimension, ≈ 170 voxels) rend le réglage indépendant de l'échelle (têtes IA normalisées à ~1 m, tête réelle 23 cm, main C4D importée à 3,7 m) ; Absolute donne la même densité physique à plusieurs parties d'un même personnage (tête, mains, pieds à raccorder). L'équivalent absolu du mode Relative est affiché. Possible plus tard : ranger Absolute dans une option avancée repliée.
  • Défaut 0,6 % (et non 0,4 %) : une base trop dense fait « voir » le grain de la source à la projection.
  • Despike par isolation et non par seuil seul : le seuil seul attrapait 8 % des sommets (oreilles, paupières).
  • Réparation des ratés au Freeze (on connaît exactement les sommets ratés) plutôt que deviner après coup.
  • Couleurs suffixées _Color : groupes de sommets et attributs partagent le même espace de noms.
  • Plus de réglage Target (décision utilisateur, 2026-10-17) : il compliquait l'interface pour rien. Tout s'applique à l'objet actif et sélectionné (_obj_mode_mesh) ; Wrap Setup projette sur slice_wrap_source.
  • Calculs longs = générateurs + opérateur modal (_LongOperator) : l'API bpy n'est pas thread-safe, donc pas de thread. Les étapes (step_*, core.build_envelope, despike, fix_missed_rays, analyze_shape…) cèdent la main en produisant (fraction, texte) ; core.sub imbrique les progressions, core.run exécute d'une traite (scripts / tests, bpy.ops sans INVOKE). Depuis l'UI : confirmation (invoke_props_dialog, préférence confirm_long), puis timer 0,02 s, tranches de 0,15 s, saisie absorbée, Échap → gen.close() : chaque étape nettoie dans except BaseException / finally (aucun demi-résultat ; la scène n'est modifiée qu'à la fin). Progression : workspace.status_text_set(fonction) + boîte en haut du panneau. Les étapes lisent bpy.context à chaque usage (le contexte d'un opérateur n'est plus valide aux ticks suivants). Pas de REGISTER sur ces opérateurs (un redo relancerait un modal). Surcoût mesuré ~10 %. Appels Blender d'un seul tenant (Multires subdivide / Reshape, Voxel Remesh) : l'écran reste figé sur leur libellé.

Fichiers

  • __init__.py : réglages (SliceWrapSettings), étapes (step_envelope, step_wrap, step_freeze, step_despike, step_analyze, _reshape_from_evaluated, _result_collection), opérateurs (run, envelope, regenerate, wrap_setup, freeze, despike, analyze, show, group_add/remove/clear), panneaux (principal, Steps replié, Despike, Analyze replié), liste SLICEWRAP_UL_groups.
  • core.py : voxels (dilate, erode, _outside, fill), maillage (mesh_world_arrays, sample_surface, voxelize, blocky_mesh), nettoyage (taubin, keep_largest_island, despike, group_weights, fix_missed_rays), analyse (analyze_shape, write_analysis), unique_object_name, build_envelope.
  • tests/run_tests.py : suite (sphère trouée bruitée ; --head = tête réelle + rendus). Exclu du paquet.
  • blender_manifest.toml : extension 5.1+ (décidé le 2026-10-20) ; [build] exclut __pycache__/, zips, .a2m/, .claude/, .git/, .gitignore, CLAUDE.md, tests/, dist/.
  • .a2m/project.toml : données du projet pour la chaîne d'outils a2m et le site (écrit par a2m adopt).
  • CHANGELOG.md (en) / CHANGELOG.fr.md (fr) : historique ; la section « Unreleased » / « Non publié » donne les notes de la prochaine release.

Commandes

  • Tests : "C:\Program Files\Blender Foundation\Blender 5.2\blender.exe" -b -P tests/run_tests.py -- <dossier> [--head] → RESULTAT : TOUT OK (~1 min, 29 contrôles dont annulations) ; avec --head, regarder slice_wrap_head_face.png / _cote.png. À lancer avant chaque release (la chaîne a2m ne lance pas encore les tests de l'addon).
  • Construction et publication : chaîne d'outils a2m (repo ange/apc-toolchain, remplace les anciens tools/Build-Package.ps1 et tools/New-GiteaRelease.ps1, retirés le 2026-10-20) : a2m validate --load (manifest validé et addon chargé dans Blender 5.1 et 5.2, profil temporaire), a2m build → dist\slice_wrap-<version>.zip, a2m release [patch|minor|major] (version du manifest, CHANGELOG, commit, tag v<version>, release Gitea avec le zip et publication.json), a2m release --dev (pré-release de test, réservée aux membres). Publication = action externe : ne la lancer qu'à la demande de l'utilisateur.
  • .gitignore : __pycache__/, dist/, *.zip, rendus de test.

Historique

Voir CHANGELOG.fr.md (une entrée par version ; les changements à venir dans « Non publié »).

Mesures de référence (Blender 5.2.1, tête Pixal3D brute 11,8 M faces)

Enveloppe 70 k faces en 11 s ; chaîne complète ~1,5–2 min ; ~93 k ratés réparés au Freeze ; Despike filtré « Oreilles » 683 corrections vs 4 749 global ; Analyze 9 s (Flat 86 %, Ridge 5 %, Bulge 3 %, Fold 3 %, Hollow 2 %, Saddle 1 % — hélice des oreilles et lèvres en Ridge, paupières et commissures en Fold).

Dépôt d'extensions Blender sur a2msystemes.org (idée du 2026-10-17, prise en charge par APC)

But : les addons de l'utilisateur (Slice Wrap, Slice Retopo, suivants) installables et mis à jour via Preferences > Get Extensions > Repositories > Add Remote Repository, au lieu d'Install from Disk. Cette note est à l'origine du projet APC (A2M Publication Contract) : le dépôt n'est plus à écrire ici.

  • Publication : a2m release (chaîne d'outils ange/apc-toolchain) joint à chaque release Gitea le zip et un publication.json (contrat ange/apc-spec) ; le script de déploiement du site (ange/site-a2msystemes-org) en fabrique blender-addons/index.json et les pages du projet. Adresse du dépôt et pages : voir le site.
  • À rappeler à l'utilisateur : les addons déjà installés par Install from Disk (dépôt user_default) ne reçoivent pas les mises à jour → les désinstaller puis réinstaller une fois depuis le nouveau dépôt.

Pistes

  • Option avancée repliée pour Absolute ; préréglages par type d'objet (tête, main, accessoire).
  • Accélérer le remplissage (propagation par lignes / scanline au lieu d'une dilatation voxel par voxel).
  • Surplombs (pavillon de l'oreille) : seconde projection Nearest Surface Point limitée à un groupe de sommets.
  • Remaillage adaptatif (octree + Dual Contouring) pour props / LOD / cible de bake (pas pour l'animation).
  • Retopologie guidée → projet Slice Retopo (marqueurs + retopo_tags + motifs ; voir son CLAUDE.md).

Préférences de travail de l'utilisateur

  • « Ne fais rien, explique » = aucune modification ; valider le plan avant les gros lancements ; expliquer les paramètres (à quoi ils servent) avant de décider.
  • Ne pas casser le concept de base d'un add-on en ajoutant des fonctions : sous-panneaux optionnels.
  • Dans son Blender ouvert (MCP) : lecture seule d'abord, copie « au cas où », sauvegarder / restaurer la vue.
  • Calculs longs dans des fenêtres PowerShell externes ; vider la VRAM ComfyUI avant chaque génération (~/.claude/CLAUDE.md).

Skills du projet (.claude/skills/)

  • slice-wrap-dev — faire évoluer, tester et livrer cet add-on.
  • mesh-wrap-cleanup — la méthode wrap et le nettoyage manifold (à la main ou avec l'add-on).
  • blender-addon-testing — tests en arrière-plan, rendus de contrôle, paquet d'extension, pièges de l'API.
  • blender-live-mcp — travailler dans le Blender ouvert de l'utilisateur sans rien casser.
  • ai-3d-asset-pipeline — génération 3D par IA (ComfyUI) qui produit les maillages sources.