Que fait polywright ?
Le hub pour le travail de modélisation 3D. Il décide comment un modèle est créé, conserve chaque actif dans un dossier unique avec un manifeste, et prouve chaque étape avec des chiffres et une image. Les compétences sœurs contiennent la profondeur.
Script : scripts/pw.py dans ce dossier de compétence (Python 3.9+, bibliothèque standard, un objet JSON par commande ; scripts/pw_bpy.py est sa moitié Blender, jamais exécuté à la main).
Exécutez python <ce dossier>/scripts/pw.py doctor une fois par session : il trouve Blender (tout OS), les bibliothèques de maillage Python, les slicers et les hôtes ComfyUI, et indique ce qui manque. Liste complète des commandes : references/cli.md.
Étape 1 : le brief (ne demandez que ce que vous ne pouvez pas déduire)
- Quoi : l'objet ou le lieu, réel ou imaginaire, et son degré de reconnaissance requis.
- Cibles : une ou plusieurs de
pw.py check --list(game-roblox, game-unity, game-unreal, web-threejs, ar-usdz, commerce-gltf, print-fdm, print-resin, video-blockout, cad-step). La cible définit le budget. - Taille réelle en mètres (un banc fait 1,8 m de long ; une personne 1,7 à 1,8 m). Une échelle erronée est l'erreur silencieuse la plus courante ;
check --real-size-mla détecte. - Entrées : un prompt, des photos, un croquis, des mesures, un emplacement cartographique, un maillage existant.
- Fidélité et budget : blockout, prêt pour le jeu, héroïque ; combien de temps ou d'argent un générateur hébergé peut coûter.
Échafaudage : pw.py new <dir> --name <Nom> --kind real|imagined|hybrid --route <route> --targets a,b --real-size-m X.
Dossier : refs/ (références, chacune enregistrée comme une source), work/ (.blend, intermédiaires), out/ (un livrable par cible), renders/ (planches de révision), brief.md, manifest.json. Contrat pour les autres plugins : references/contract.md.
Étape 2 : choisir la voie (la moins coûteuse qui répond au brief)
| Situation | Voie | Compétence |
|---|---|---|
| Un objet courant ; la licence autorise la réutilisation | trouver : Poly Haven, Kenney, Quaternius (CC0), Sketchfab et sites d'impression (vérifier chaque licence) | cette compétence, references/routes.md |
| A des dimensions, des pièces qui s'emboîtent, des arêtes vives (support, boîtier, bâtiment, meuble) | coder (--route procedural) : bpy, build123d/CadQuery/OpenSCAD | polywright-generate, polywright-blender |
| Un lieu réel (parc, rue, campus, terrain) | lieu : OSM + élévation (pw.py place) | polywright-capture |
| Un objet réel que l'on peut photographier ou scanner | capturer : photogrammétrie, splats, scanner, ou modèle à partir de mesures | polywright-capture |
| Organique imaginé ou pièce unique (statue, créature, accessoire) | générer : planche de référence, puis image-vers-3D | polywright-references, polywright-generate |
| Personnage héroïque qui se déforme | générer ou sculpter comme base, puis retopologie et rigging | polywright-generate, polywright-finish |
La plupart des bons résultats mixent les voies : un parc OSM avec des accessoires héroïques générés, une maison codée avec une statue générée. Enregistrez la voie par pièce dans le manifeste.
Étape 3 : les références avant la géométrie
Pour tout ce qui n'est pas trouvé tout fait, rassemblez ou générez d'abord des références (polywright-references) : vues orthographiques sur une ligne de sol commune avec une barre de hauteur, échantillons de matériaux, références d'échelle. Les entrées générées déterminent la majeure partie d'un résultat image-vers-3D.
Étape 4 : construire, puis prouver (toutes les voies)
- Blockout d'abord à taille réelle : primitives pour la silhouette et les proportions. Corrigez l'échelle ici ; c'est peu coûteux maintenant.
- Chiffres :
pw.py inspect <fichier>: triangles, objets, taille, matériaux, textures, UVs, étanchéité, pièces. Lisez-le avant et après chaque étape destructive. - Image :
pw.py render <fichier> --out renders/<étape>: six vues et unsheet.png. Lisez la planche, pas six captures d'écran. Comparez avec les références : silhouette, proportions, pièces manquantes ou flottantes, pics d'ombrage, mauvais axe (couché sur le côté), mauvaise échelle. - Cible :
pw.py check <fichier> --target <c> --real-size-m X. Échec signifie corriger avant de livrer ; avertissement signifie le mentionner dans le transfert. - Enregistrer :
pw.py manifest <dossier> --add-output out/<fichier> --target <c> --inspect, chaque source avec--add-source <url> --licence <l> --author <a>, puis--validate.
Planifier, agir et critiquer sont des passages séparés : après la construction, regardez la planche comme le ferait un critique et listez les défauts avant de déclarer le travail terminé. Deux cycles de correction d'un traceback en valent la peine ; au-delà, repensez l'approche. Sauvegardez un .blend numéroté par jalon (work/<nom>_v03.blend) afin qu'un long travail puisse reprendre depuis le disque.
Composer un modèle dans une image
Lorsqu'un modèle d'image ou de vidéo continue de dessiner un accessoire conçu de manière incorrecte (un storyboard, une référence de décor, une affiche), prenez la composition de l'image et la forme du modèle :
- Choisissez l'image pour la composition uniquement : où se tiennent les personnages, la lumière, l'objectif. Un accessoire de substitution simple suffit.
pw.py match model.blend --still pic.png --out work/match.png --anchor-px X,Y --anchor-local=X,Y,Z --aim-px X,Y --aim-local=X,Y,Z --depth M --horizon ROW --hide BOX --mask-add BOX: l'ancre du modèle (une poignée) atterrit sur la main, son point de visée (une pointe) sur le pixel exact, rendu en RGBA avec l'objectif et l'horizon de l'image. Définissez--depthpour que sa largeur en pixels corresponde à celle du substitut (largeur = f_px x diamètre / profondeur ;f_pxest dans le résultat).--hidecache la pièce derrière une main ;--mask-addajoute les mains au masque.- Lisez
match_paste.pngrecadré à 3x : forme, taille dans le cadre, visée. Corrigez la profondeur et les pixels, relancez (secondes). - Fusionnez à l'intérieur de
match_mask.pngavec une édition d'image masquée à faible débruitage (FLUX.2 Klein ou tout modèle inpainting : débruitage 0.3 à 0.5, cfg bas), puis collez le résultat à travers le masque de sorte que chaque pixel à l'extérieur reste celui de l'image d'origine. Une édition sur toute l'image redessine tout (couleur HDR, un accessoire plus grand). - Vérifiez en taille réelle ; gardez deux graines aléatoires ou plus.
Les planches de référence de l'accessoire proviennent également du modèle (polywright-references, Étape 2b).
Sprites de jeu à partir d'un modèle
Lorsqu'un modèle d'image continue de mal dessiner un mécanisme dans un sprite de jeu (une roue qui n'est pas ronde, une lame sur le toit), construisez le modèle, rendez-le à travers la propre caméra du jeu et laissez le modèle d'image uniquement peindre :
pw.py spritecam <registry.json> --like <sprite> --out camera.json: la caméra orthographique ajustée à partir des losanges au sol du jeu (L-014). Définisseztile_mdans celui-ci aux mètres du modèle par tuile.- Construisez le modèle avec un préfixe de pièce par objet (
wheel_,roof_...) dans la propriété de scènesprite_parts, en déplaçant les pièces sous un empty pivot construit dans l'espace du pivot, et le mouvement dans la propriété de scèneloop. pw.py sprite model.blend --camera camera.json --out renders/L1 --scale 10.6667(1024 px pour un sprite de 96 px) : lisez les passes et le rendu final en stylesheetà 1x à côté des sprites du jeu ;--frames N --frame-passes id,pospour une pièce animée,--hide wheel_pour une plaque sans elle. Ensuite, vérifiez la taille par rapport aux voisins du jeu avant de peindre :aw.py sprite <rendu à 96 px> --refs <sprites de même classe>échoue si la couverture est inférieure à 0,9 de leur médiane. L'ajustement du losange définit l'échelle au sol, pas la taille perçue du bâtiment : ajoutez d'abord du volume et des accessoires (murs plus hauts, un appentis, une cour), puis augmentezpx_per_tileet déplacezfootprint_centre_pxpour que la boîte englobante couvre le canevas comme les voisins (L-016). Gardez les poutres fines hors de la silhouette d'un cylindre : un rondin de niveau sur des pentes inclinées donne l'impression de passer au-dessus et en dessous d'elles (L-017).- Peignez le rendu final avec un Canny de l'argile comme contrôle (un modèle d'image avec un ControlNet), découpez-le avec l'alpha du rendu pour que le cadrage et le
groundBaserestent exacts, puis vérifiez la peinture par rapport aux données d'ID et de bordure danssprite.json.
Illustrations de scène à partir d'un modèle
Un écran de chargement, un key art ou une couverture autour d'un modèle qui existe déjà (un bâtiment, une machine) : construisez la scène dans Blender et laissez le modèle d'image la peindre, de sorte que le mécanisme et la disposition restent corrects.
- Construisez la scène autour du modèle avec un préfixe de pièce par objet dans la propriété de scène
scene_parts, les roues et les disques dansrings, les points clés ou les chemins dansscene_points. Les talus, digues et murs le long d'un chemin sont chacun unsweep(importez-le depuisscripts/pw_scene.pydans un scriptpw.py bpy), pas une rangée de boîtes (L-020). pw.py framecam problem.json --out cameras.json: points du monde avec des boîtes à l'écran, points maintenus dans le cadre et hors des bandes de texte de l'interface utilisateur, une mesure de taille à maximiser ; imprime les meilleures caméras en tant que préréglages. Prenez les bandes du fichier d'interface utilisateur réel (son padding et ses ancres), pas d'une règle empirique (L-018).pw.py scene scene.blend --cameras cameras.json --camera framecam_1 --out renders/v1 --size 1280x720(taille de premier passage du flux de travail de peinture) : argile, rendu final, profondeur, normale, id, ligne etscene.json. Lisez d'abord l'argile et la profondeur ; laissez la plage de profondeur à la propre mesure de la scène à moins qu'un préréglage n'ait besoin qu'elle soit fixée (L-019).- Peignez avec contrôle (profondeur ou ligne), puis filtrez la peinture par rapport à
scene.json: bords des anneaux, points, couleurs d'ID.
Blockouts de foule et de bataille (vidéo IA)
Les modèles vidéo échouent sur les foules ; Blender non. Laissez Blender placer l'armée et le modèle vidéo peindre l'apparence :
pw.py crowd --out work/crowd --action clash --preview(ou march, advance, charge, hold ;--view,--lens,--move), puis lisezwork/crowd/sheet.png.- Supprimez
--previewpour le plan complet :depth.mp4(contrôle principal),pose.mp4(premiers rangs),mask.mp4,clay.mp4,camera.json; 832x480, 81 images à 16 ips par défaut (Wan). - Repeignez l'argile de l'image 1 en une image de départ approuvée ; pilotez Wan VACE ou Wan 2.2 Fun Control avec la vidéo de profondeur et cette image. Indiquez le costume, la couleur par camp, la lumière et la brume, pas le nombre de figurants.
Détails et ce qui n'est pas testé : references/crowd-blockouts.md. La planification des plans relève de cinewright.
Deux combattants : pw.py duel shot.json --preview pose deux mannequins à leurs marques dans le décor, à travers la caméra du plan (examples/duel.json) ; lisez sheet.png, puis supprimez --preview pour chaque mp4 de contrôle. Plus d'informations : crowd-blockouts.md, "Two fighters".
Un petit casting de figures réelles ou de jouets (côtés échangés, figurine supplémentaire, marquages perdus) : maillage de chacun à partir de photos, corrigez la couleur et les marquages peints avec pw.py mark, donnez au modèle vidéo les images de pw.py turnaround comme références et un pw.py lineup (équipes sur des côtés fixes, profondeur et masque) comme ouverture : references/figures-for-video.md.
Décors et accessoires pour un plan de film : references/film-and-video.md.
Étape 5 : finition et transfert
La finition par cible (UVs, LODs, convention de normale, conversion d'axe et d'unité, compression) est gérée par polywright-finish ; l'impression (solide étanche, parois, base, division, 3MF) par polywright-print. Transférez le dossier au plugin qui l'utilise : pages three.js (threewright), film et vidéo (cinewright), lieux Roblox (roblox-agent), projets Unity (unity-agent), une compétence spécifique à l'imprimante ou au slicer pour les paramètres d'impression, une compétence image pour plus d'images. Ils lisent manifest.json et out/.
Message de transfert :
Modèle : <nom> (<voie>) -> out/<fichier> pour <cible> : <tris> tris, <taille> m, <étanche/pièces>
Vérification : <cible> succès|avertissement (<règles>) Révision : renders/<étape>/sheet.png
Sources : <n> avec licences ; parties créées par IA : <lesquelles, quel modèle> Dû : <ce qui n'est pas fait>
Règles
- Taille réelle en mètres dans Blender et glTF (+Z vers le haut dans Blender, +Y vers le haut dans glTF) ; millimètres uniquement dans les fichiers d'impression.
- Ne prétendez jamais qu'un maillage est correct de par son nom de fichier ou la parole d'un générateur : inspectez, rendez, vérifiez.
- Chaque entrée téléchargée ou générée reçoit une ligne de source avec sa licence. Les boutiques et sites d'impression (Fab, Unity Asset Store, Sketchfab, MakerWorld, Printables, Steam) exigent la divulgation du contenu créé par IA ; le manifeste l'enregistre.
- Les ponts Blender via MCP exécutent du Python arbitraire : préférez
pw.py bpysur des copies ; utilisez une session MCP en direct uniquement lorsque l'utilisateur regarde (polywright-blender). - Les tuiles 3D photoréalistes Google peuvent être visualisées, jamais exportées, mises en cache ou tracées (leurs conditions d'utilisation).
Maintenance
Unité persistante (evergreen), niveau fast (les générateurs et Blender changent tous les mois). Compagnons : RESEARCH.md, CHANGELOG.md, LEARNINGS.md, TESTS.md avec evals/evals.json, MAINTENANCE.md, état dans evergreen.json. Lisez evergreen.json à chaque utilisation ; si c'est dû, faites la tâche, puis rafraîchissez (evergreen-refresh). Écrivez les leçons dans LEARNINGS.md au fur et à mesure.