[{"data":1,"prerenderedAt":13118},["ShallowReactive",2],{"author-count-basile-fr":3,"author-basile-fr":4,"posts-author-basile-fr-1":19,"tags-header-fr":13034,"tags-footer-fr":13096},23,{"id":5,"title":6,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":10,"meta":11,"navigation":13,"pageType":14,"path":15,"seo":16,"slug":10,"stem":17,"__hash__":18},"jsonPages/fr/authors/basile.json","Basile Samel",null,"json","fr","basile",{"name":6,"profile_image":12},"",true,"authors","/fr/authors/basile",{},"fr/authors/basile","n6U9yLNRpKRIaliEeexRdWCkXqGgcNPwyXLGH7ee0mM",[20,575,979,1832,2566,3180,3877,4364,5219,5960,6434,7193,7759,8133,8821,9327,9846,10427,10933,11312,11702,12019,12526],{"id":21,"title":22,"authors":23,"body":27,"description":12,"extension":557,"feature_image":558,"html":7,"meta":559,"navigation":13,"path":563,"published_at":564,"seo":565,"slug":566,"stem":567,"tags":568,"__hash__":574,"updated_at":560,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/automated-kitsu-pdf-reports/index.md","Automatiser des rapports Kitsu avec Python et Gazu (2026)",[24],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},"630632b2ca5910003d4a70af","https://blog.cg-wire.com/author/basile/",{"type":28,"value":29,"toc":547},"minimark",[30,47,51,54,57,60,63,68,71,87,90,99,102,105,139,141,145,148,151,160,167,170,194,196,200,203,211,252,255,299,314,316,320,323,326,329,332,338,348,367,376,387,390,392,396,407,428,435,438,445,448,456,462,464,468,471,474,480,492,503,505,509,512,515,518,536],[31,32,37,42],"div",{"className":33},[34,35,36],"kg-card","kg-callout-card","kg-callout-card-yellow",[31,38,41],{"className":39},[40],"kg-callout-emoji","📊",[31,43,46],{"className":44},[45],"kg-callout-text","Transformez des heures de reporting manuel en un PDF Kitsu entièrement automatisé en quelques secondes.",[48,49,50],"p",{},"Combien d’heures passez-vous chaque semaine à récupérer des données et à générer des rapports ?",[48,52,53],{},"Les studios d’animation utilisent Kitsu pour suivre l’avancement, mais nous voyons encore des superviseurs passer des heures à compiler manuellement ces données en PDF, juste pour tenir les producteurs et réalisateurs informés. C’est un énorme drain d’énergie créative, et un point de défaillance manuel que l’équipe senior ne devrait pas avoir à gérer. Si les données existent déjà dans notre logiciel de suivi, les partager ne devrait pas être une galère.",[48,55,56],{},"En tant que lead technique, votre mission est d’automatiser les tâches fastidieuses afin que les artistes puissent se concentrer sur l’art. Et en utilisant le client Python de Gazu, nous pouvons combler l’écart entre la base de données de Kitsu et le rapport final destiné aux parties prenantes.",[48,58,59],{},"Aujourd’hui, nous allons créer un script qui récupère automatiquement des indicateurs de projet et génère un PDF personnalisé, transformant une tâche manuelle de 2 heures en un travail automatisé de 5 secondes.",[61,62],"hr",{},[64,65,67],"h2",{"id":66},"why-custom-reports","Pourquoi des rapports personnalisés ?",[48,69,70],{},"Kitsu est une bouée de sauvetage pour garder l’organisation du chaos de la production. Le tableau de bord intégré couvre tous les cas d’usage, y compris l’analyse multi-production. Mais parfois, « standard » ne suffit pas.",[72,73,76],"figure",{"className":74},[34,75],"kg-image-card",[77,78],"img",{"src":79,"className":80,"alt":12,"loading":82,"width":83,"height":84,"srcSet":85,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png",[81],"kg-image","lazy",1600,900,"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png 1600w","(min-width: 720px) 720px",[48,88,89],{},"Par exemple, les clients voudront peut-être avoir l’impression qu’ils paient pour un service premium. Leur envoyer une capture brute du logiciel ou un lien générique peut donner une impression un peu amateur. En utilisant des rapports personnalisés, vous pouvez fournir des mises à jour d’avancement encapsulées dans le branding de votre studio, ce qui garantit une présentation aussi soignée que les images que vous livrez.",[48,91,92,93,98],{},"Il y a ensuite la difficulté de trouver un format qui conviendra au producteur. Le producteur demande un tableau croisé Excel très spécifique ou un PDF hérité pour les archives, qui suit une logique interne étrange, compréhensible uniquement par lui. Si vous devez exporter une liste filtrée de chaque plan de la Séquence 02 qui est actuellement « En cours » mais bloqué par des retakes « En retard », un rapport personnalisé vous fournit ces données instantanément. ",[94,95,97],"a",{"href":96},"https://blog.cg-wire.com/reduce-rework-animation/","Cela vous évite le cauchemar du copier-coller manuel"," et vous permet de revenir à l’animation.",[48,100,101],{},"Certains studios ont aussi besoin de vues personnalisées pour un suivi avancé. Des données sur mesure peuvent vous aider à repérer des goulots d’étranglement par département : par exemple, quand l’équipe d’éclairage est constamment en pause parce que le cache FX accuse du retard. Vous pouvez ainsi résoudre la friction avant qu’elle ne se transforme en rush de fin de semaine.",[48,103,104],{},"Heureusement, Kitsu est très simple à étendre.",[31,106,109,113],{"className":107},[34,35,108],"kg-callout-card-blue",[31,110,112],{"className":111},[40],"💡",[31,114,116,124,127,129,130,132,134,135],{"className":115},[45],[117,118,119],"b",{},[120,121,123],"strong",{"style":122},"white-space: pre-wrap;","Vous cherchez des exemples concrets ?",[125,126],"br",{},[125,128],{},"Vous pouvez trouver le code source complet de l’exemple d’intégration présenté dans ce guide sur notre GitHub :",[125,131],{},[125,133],{},"🔗 ",[94,136,138],{"href":137},"https://github.com/cgwire/blog-tutorials/tree/main/custom-kitsu-reports?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/custom-kitsu-reports",[61,140],{},[64,142,144],{"id":143},"_1-kitsu-setup-authentication","1. Configuration Kitsu & authentification",[48,146,147],{},"Tout d’abord, vous devez parler à votre instance Kitsu.",[48,149,150],{},"Si vous n’avez pas encore d’URL de studio et que vous souhaitez lancer Kitsu sur votre propre machine, Docker est le moyen le plus rapide pour mettre en place un environnement prêt pour la production :",[152,153,154],"pre",{},[155,156,159],"code",{"className":157},[158],"language-bash","docker run --init -ti --rm -p 80:80 -p 1080:1080 --name cgwire cgwire/cgwire\n",[48,161,162,163,166],{},"Pour le scripting, nous utiliserons le SDK Python officiel de Kitsu, ",[155,164,165],{},"gazu",".",[48,168,169],{},"Vous pouvez vous authentifier avec vos identifiants utilisateur, ce qui convient très bien aux tests locaux :",[152,171,172,177],{},[155,173,176],{"className":174},[175],"language-python","import gazu\n",[48,178,179],{},[155,180,182,183,188,189,193],{"className":181},[175],"gazu.set_host(\"",[94,184,185],{"href":185,"rel":186},"http://localhost/api",[187],"nofollow","\")\nuser = gazu.log_in(\"",[94,190,192],{"href":191},"mailto:admin@example.com","admin@example.com","\", \"mysecretpassword\")\n",[61,195],{},[64,197,199],{"id":198},"_2-fetch-production-data","2. Récupérer les données de production",[48,201,202],{},"Avant d’écrire la moindre ligne de code, nous devons parler des données que Kitsu expose. Si elles existent dans l’interface, vous pouvez probablement les récupérer via Gazu.",[48,204,205,206,210],{},"L’API est étonnamment riche. ",[94,207,209],{"href":208},"https://blog.cg-wire.com/how-to-track-properly-the-cg-artist-progress/","Pour un rapport de production solide",", vous pourriez généralement récupérer :",[212,213,214,221,227,233,239,245],"ul",{},[215,216,217,220],"li",{},[120,218,219],{},"Indicateurs d’avancement :"," changements de statut (par exemple, passer de « WIP » à « Review interne » via des événements).",[215,222,223,226],{},[120,224,225],{},"Suivi du temps :"," la durée d’un plan « En cours » par rapport à l’estimation initiale.",[215,228,229,232],{},[120,230,231],{},"Listes d’interprétation :"," chaque personnage, environnement et accessoire associé à un épisode ou une séquence donnée.",[215,234,235,238],{},[120,236,237],{},"Charge de travail :"," le nombre exact de frames ou d’assets actuellement assignés à un artiste spécifique.",[215,240,241,244],{},[120,242,243],{},"Budget :"," l’évolution de la quota de l’équipe dans le temps.",[215,246,247,248,166],{},"Et bien d’autres ressources à découvrir dans ",[94,249,251],{"href":250},"https://gazu.cg-wire.com/data?ref=blog.cg-wire.com","notre documentation développeur détaillée",[48,253,254],{},"Regardons un scénario courant : vous devez obtenir rapidement un récapitulatif de toutes les tâches actuellement assignées à vos membres d’équipe pour un projet donné. C’est la base de tout rapport « Qui fait quoi ? ».",[152,256,257,294],{},[155,258,260,261,265,268,273,286],{"className":259},[175],"projects = gazu.project.all_projects()\nproject = projects",[262,263,264],"span",{},"0",[48,266,267],{},"tasks = gazu.task.all_tasks_for_project(project)",[48,269,270,271],{},"report = ",[262,272],{},[48,274,275,276],{},"for task in tasks:\nassignees = ",[262,277,278,279,282,283],{},"gazu.person.get_person(p_id)",[262,280,281],{},"\"full_name\""," for p_id in task",[262,284,285],{},"\"assignees\"",[152,287,292],{"className":288,"code":290,"language":291},[289],"language-text","task_info = {\n    \"date\": task[\"updated_at\"],\n    \"entity\": gazu.entity.get_entity(task[\"entity_id\"])[\"name\"],\n    \"type\": gazu.task.get_task_type(task[\"task_type_id\"])[\"name\"],\n    \"status\": gazu.task.get_task_status(task[\"task_status_id\"])[\"name\"]\n}\n\nfor artist in assignees:\n    report.append({**task_info, \"artist\": artist})\n","text",[155,293,290],{"__ignoreMap":12},[48,295,296],{},[155,297],{"className":298},[175],[48,300,301,302,305,306,309,310,313],{},"Gazu renvoie des dictionnaires. Lorsque vous récupérez ",[155,303,304],{},"all_tasks_for_project",", gardez à l’esprit qu’en production long métrage, cela peut représenter une quantité massive de données. Essayez toujours de filtrer vos données. Par exemple, par ",[155,307,308],{},"task_status"," ou ",[155,311,312],{},"entity_type",", si vous ne devez voir que des plans d’Animation actifs, par exemple.",[61,315],{},[64,317,319],{"id":318},"_3-creating-a-reusable-template","3. Créer un modèle réutilisable",[48,321,322],{},"Ensuite, vous devez décider comment générer le PDF. Il existe deux options principales.",[48,324,325],{},"Vous pouvez utiliser ReportLab. C’est la méthode la plus directe. C’est rapide et ne nécessite aucune dépendance externe non-Python. Idéal pour des rapports techniques internes, des tableaux simples, et de l’automatisation par lots très rapide.",[48,327,328],{},"Ou vous pouvez créer une chaîne de rendu HTML vers PDF en utilisant Jinja2 (gabarits) et WeasyPrint. C’est souvent la méthode préférée, car vous pouvez utiliser le CSS pour styliser le rapport. Si vous pouvez créer une page web, vous pouvez créer un rapport. C’est le mieux pour les livrables destinés aux clients, le branding important, et les mises en page complexes.",[48,330,331],{},"Définissons votre configuration et votre modèle :",[152,333,334],{},[155,335,337],{"className":336},[175],"STUDIO_NAME = \"My Animation Studio\"\nSTUDIO_LOGO = \"studio_logo.png\"  # chemin de fichier local\nPROJECT_NAME = \"My Project\"\nOUTPUT_PDF = \"activity_report.pdf\"\n",[48,339,340,341,347],{},"Vous utilisez la syntaxe Jinja2 (",[155,342,343],{},[344,345],"binding",{"value":346},"variable",") pour injecter vos données Python dans du HTML standard.",[152,349,350,361],{},[155,351,354,355],{"className":352},[353],"language-html","\u003C!doctype html>\n\u003Chtml>\n\u003Chead>\n\u003Cmeta charset=\"utf-8\" />\n\u003Cstyle>\nbody {\nfont-family: Arial, sans-serif;\nmargin: 40px;\n}\nheader {\ndisplay: flex;\nalign-items: center;\nmargin-bottom: 30px;\n}\nheader img {\nheight: 50px;\nmargin-right: 20px;\n}\nh1 {\ncolor: #2a2a2a;\n}\ntable {\nwidth: 100%;\nborder-collapse: collapse;\nmargin-top: 20px;\n}\nth {\nbackground: #222;\ncolor: white;\npadding: 8px;\ntext-align: left;\n}\ntd {\npadding: 8px;\nborder-bottom: 1px solid #ccc;\n}\n.footer {\nmargin-top: 40px;\nfont-size: 10px;\ncolor: #777;\ntext-align: center;\n}\n\u003C/style>\n\u003C/head>",[152,356,359],{"className":357,"code":358,"language":291},[289],"&lt;body&gt;\n    &lt;header&gt;\n        &lt;img src=\"{{ studio_logo }}\" /&gt;\n        &lt;h1&gt;{{ studio_name }} – Activity Report&lt;/h1&gt;\n    &lt;/header&gt;\n\n    &lt;p&gt;\n        &lt;strong&gt;Project:&lt;/strong&gt; {{ project_name }}&lt;br /&gt;\n        &lt;strong&gt;Report Date:&lt;/strong&gt; {{ report_date }}\n    &lt;/p&gt;\n\n    &lt;table&gt;\n        &lt;tr&gt;\n            &lt;th&gt;Date&lt;/th&gt;\n            &lt;th&gt;Artist&lt;/th&gt;\n            &lt;th&gt;Task&lt;/th&gt;\n            &lt;th&gt;Entity&lt;/th&gt;\n            &lt;th&gt;Status&lt;/th&gt;\n        &lt;/tr&gt;\n        {% for row in rows %}\n        &lt;tr&gt;\n            &lt;td&gt;{{ row.date }}&lt;/td&gt;\n            &lt;td&gt;{{ row.artist }}&lt;/td&gt;\n            &lt;td&gt;{{ row.entity }}&lt;/td&gt;\n            &lt;td&gt;{{ row.type }}&lt;/td&gt;\n            &lt;td&gt;{{ row.status }}&lt;/td&gt;\n        &lt;/tr&gt;\n        {% endfor %}\n    &lt;/table&gt;\n\n    &lt;div class=\"footer\"&gt;Generated automatically by {{ studio_name }}&lt;/div&gt;\n&lt;/body&gt;\n",[155,360,358],{"__ignoreMap":12},[48,362,363],{},[155,364,366],{"className":365},[353],"\u003C/html>\n",[48,368,369,370,375],{},"Ce fichier HTML agit comme un modèle Jinja2 qui définit la structure visuelle et le style du rapport, y compris la mise en page, les polices, les couleurs et un tableau pour afficher les données d’activité. Les expressions ",[155,371,372],{},[344,373],{"value":374},"..."," marquent des emplacements pour des valeurs comme le nom du studio, l’URL du logo, le nom du projet et la date du rapport, tandis que le CSS intégré garantit que le document a un rendu soigné et prêt à imprimer une fois rendu ou converti en PDF.",[48,377,378,379,382,383,386],{},"Lorsque le code Python rend ce modèle, Jinja2 remplace tous les emplacements par les valeurs réelles transmises depuis le script et exécute la boucle ",[155,380,381],{},"{% for row in rows %}"," pour générer une ligne de tableau par enregistrement d’activité. Chaque dictionnaire ",[155,384,385],{},"row"," fournit la date, l’artiste, la tâche, l’entité, le statut et les valeurs d’heures, avec le champ des heures explicitement formaté à deux décimales, ce qui produit un document HTML complet avec un tableau entièrement rempli.",[48,388,389],{},"Le HTML rendu est donné à WeasyPrint, qui interprète à la fois la structure HTML et le CSS en ligne pour disposer le contenu comme un document imprimable. Le logo du studio est chargé via son URL ou un chemin relatif, le tableau et le texte sont stylisés exactement comme défini dans le modèle, et tout est rendu dans un fichier PDF qui correspond visuellement à la maquette HTML, en se terminant par le pied de page qui confirme que le rapport a été généré automatiquement.",[61,391],{},[64,393,395],{"id":394},"_4-rendering","4. Rendu",[48,397,398,399,402,403,406],{},"Enfin, vous assemblez tout. Vous utilisez ",[155,400,401],{},"jinja2"," pour renseigner les emplacements dans le HTML avec vos données, puis ",[155,404,405],{},"WeasyPrint"," convertit cette chaîne HTML en un fichier PDF :",[152,408,409,422],{},[155,410,412,413,416,419],{"className":411},[175],"from jinja2 import Environment, FileSystemLoader\nfrom weasyprint import HTML\nfrom datetime import date",[48,414,415],{},"env = Environment(loader=FileSystemLoader(\".\"))\ntemplate = env.get_template(\"report.html\")",[48,417,418],{},"html = template.render(\nstudio_name=STUDIO_NAME,\nstudio_logo=STUDIO_LOGO,\nproject_name=PROJECT_NAME,\nreport_date=date.today().isoformat(),\nrows=report,\n)",[48,420,421],{},"HTML(string=html, base_url=\".\").write_pdf(OUTPUT_PDF)",[48,423,424],{},[155,425,427],{"className":426},[175],"print(f\"PDF generated: {OUTPUT_PDF}\")\n",[48,429,430,431,434],{},"La première partie du code configure Jinja2 pour charger un modèle HTML depuis le répertoire courant, puis récupère le ",[155,432,433],{},"report.html"," mentionné plus haut.",[48,436,437],{},"Ensuite, le modèle est rendu en un document HTML complet en injectant des données d’exécution dans ces emplacements. Les métadonnées du studio et du projet sont transmises, et la date du jour est générée au format ISO. Le résultat de cette étape est une simple chaîne HTML dans laquelle toutes les valeurs dynamiques sont déjà résolues.",[48,439,440,441,444],{},"Enfin, le HTML rendu est confié à WeasyPrint, qui analyse le HTML, ainsi que tout CSS et ressources associés, puis le convertit en fichier PDF. Le paramètre ",[155,442,443],{},"base_url"," permet de garantir que les chemins relatifs vers les images ou feuilles de style fonctionnent correctement, et le PDF final est écrit vers le chemin de sortie avant d’afficher un message de confirmation.",[48,446,447],{},"Nous obtenons ce résultat final :",[72,449,451],{"className":450},[34,75],[77,452],{"src":453,"className":454,"alt":12,"loading":82,"width":83,"height":84,"srcSet":455,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png 1600w",[48,457,458,459,166],{},"Vous pouvez essayer d’exécuter le script vous-même en une minute en ",[94,460,461],{"href":137},"clonant notre dépôt Github correspondant",[61,463],{},[64,465,467],{"id":466},"_5-automation-tips","5. Conseils d’automatisation",[48,469,470],{},"L’automatisation est là que ce workflow prend vraiment toute sa valeur : une fois que votre script de rapport fonctionne en local, l’étape suivante consiste à s’assurer qu’il tourne de façon fiable sans intervention humaine, et que la sortie arrive là où les gens regardent déjà.",[48,472,473],{},"Au lieu d’exécuter le script manuellement, configurez une tâche cron sur votre serveur pour l’exécuter à un moment prévisible. Par exemple, lancer le script chaque jour de la semaine à 18h00 permet de générer le PDF pendant la nuit et de le préparer avant le début de journée des producteurs. C’est particulièrement utile pour les suivis quotidiens « burn-down » ou les résumés de statut des plans.",[48,475,476,477,479],{},"Une fois le PDF généré, utilisez ",[155,478,165],{}," pour le joindre directement à une entité pertinente dans Kitsu, comme une Production, un Épisode ou une tâche récurrente. Cela transforme votre rapport en un livrable de premier ordre, avec un historique permanent. Par exemple, envoyer le rapport de chaque journée à une tâche « Daily Production Report » facilite l’audit des changements dans le temps ou la référence à des décisions passées. Astuce pratique : incluez la date à la fois dans le nom du fichier et dans le commentaire de la pièce jointe, afin que les rapports soient faciles à parcourir dans l’interface Kitsu sans devoir les télécharger un par un.",[48,481,482,483,486,487,491],{},"Pour pousser le rapport directement aux parties prenantes, utilisez le ",[155,484,485],{},"smtplib"," intégré à Python (ou un service d’e-mails transactionnels) pour envoyer le PDF en pièce jointe. C’est idéal pour ",[94,488,490],{"href":489},"https://blog.cg-wire.com/collaborative-animation-production/","les producteurs ou clients qui ne vivent pas dans Kitsu"," toute la journée. Un modèle concret consiste à envoyer un court résumé dans le corps du message — « Plans bloqués : 12, plans finalisés : 3 » — puis à joindre le PDF complet pour les détails.",[48,493,494,495,498,499,502],{},"Au lieu de coder en dur une seule mise en page HTML, stockez plusieurs modèles Jinja2 comme ",[155,496,497],{},"client_report.html"," et ",[155,500,501],{},"internal_audit.html"," pour générer différents styles de rapports à partir des mêmes données Kitsu. Par exemple, des résumés propres et haut niveau pour les clients et des tableaux plus détaillés pour le suivi interne. Une approche utile consiste à partager des modèles de base et des macros (en-têtes, tableaux, badges de statut) afin que les changements de branding ou de mise en page se répercutent sur tous les types de rapports. Versionnez ces modèles avec votre code : ainsi, vous pourrez reproduire exactement d’anciens rapports si nécessaire.",[61,504],{},[64,506,508],{"id":507},"conclusion","Conclusion",[48,510,511],{},"L’idée majeure ici ne concerne pas seulement les PDF : il s’agit de récupérer du temps et de l’attention pour le travail qui fait vraiment avancer une production !",[48,513,514],{},"En extrayant des données structurées de Kitsu avec Gazu, en les façonnant avec Python, puis en les rendant en rapports automatisés et soignés, vous remplacez une routine manuelle fragile par un système reproductible qui tourne tranquillement en arrière-plan. Ce qui prenait autrefois des heures de copier-coller, de mise en forme et de double vérification devient un pipeline fiable : des données exactes, livrées à temps, dans un format que les producteurs et les clients ont réellement envie de lire. Les rapports personnalisés vous permettent de communiquer l’avancement avec confiance, de mettre en évidence les problèmes avant qu’ils ne deviennent un crunch, et de présenter votre studio comme à la fois créatif et rigoureux techniquement.",[48,516,517],{},"Plus votre pipeline est complexe, plus il devient important de créer des rapports personnalisés : assurez-vous donc de lire davantage de nos guides de script pour vous inspirer !",[31,519,521,525],{"className":520},[34,35,36],[31,522,524],{"className":523},[40],"📽️",[31,526,528,529,535],{"className":527},[45],"Pour en savoir plus sur le processus d’animation ",[94,530,534],{"href":531,"rel":532},"https://www.cg-wire.com/community?ref=blog.cg-wire.com",[533],"noreferrer","envisagez de rejoindre notre communauté Discord"," ! Nous échangeons avec plus d’un millier d’experts qui partagent les meilleures pratiques et organisent parfois des événements en personne. Nous serions ravis de vous accueillir ! 😊",[31,537,541],{"className":538},[34,539,540],"kg-button-card","kg-align-center",[94,542,546],{"href":531,"className":543},[544,545],"kg-btn","kg-btn-accent","Rejoignez notre communauté Discord",{"title":12,"searchDepth":548,"depth":548,"links":549},2,[550,551,552,553,554,555,556],{"id":66,"depth":548,"text":67},{"id":143,"depth":548,"text":144},{"id":198,"depth":548,"text":199},{"id":318,"depth":548,"text":319},{"id":394,"depth":548,"text":395},{"id":466,"depth":548,"text":467},{"id":507,"depth":548,"text":508},"md","https://images.unsplash.com/photo-1666875753105-c63a6f3bdc86?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGRhc2hib2FyZHxlbnwwfHx8fDE3NzAwMjAyODZ8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":560,"featured_at":561,"visibility":562},"2026-02-20T06:03:57.000+01:00","false","public","/blog-i18n/fr/automated-kitsu-pdf-reports","2026-02-02T10:00:12.000+01:00",{"title":22,"description":12},"automated-kitsu-pdf-reports","blog-i18n/fr/automated-kitsu-pdf-reports/index",[569],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"5fff0e54653a0c003924f7f2","Pipeline Automation","pipeline","https://blog.cg-wire.com/tag/pipeline/","z7g1xeiAnrBe5ieUg_PSbkIuXzF3D96-BI1Nt3DaHlQ",{"id":576,"title":577,"authors":578,"body":580,"description":12,"extension":557,"feature_image":964,"html":7,"meta":965,"navigation":13,"path":967,"published_at":968,"seo":969,"slug":970,"stem":971,"tags":972,"__hash__":978,"updated_at":966,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/automating-kitsu-production-onboarding/index.md","Mettre à l’échelle la configuration de production dans Kitsu avec des imports CSV (2026)",[579],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":581,"toc":956},[582,593,600,603,606,609,634,636,640,643,684,691,694,697,707,709,713,716,719,736,742,748,751,753,757,760,770,777,787,789,793,796,820,823,826,829,832,835,837,841,844,875,878,885,888,891,894,902,908,910,912,915,918,932,935,949],[31,583,585,589],{"className":584},[34,35,36],[31,586,588],{"className":587},[40],"🚀",[31,590,592],{"className":591},[45],"Lancez de nouvelles productions Kitsu en quelques minutes en important automatiquement des données de studio propres.",[48,594,595,596,166],{},"Si créer une nouvelle série ou une nouvelle scène dans Kitsu implique de cliquer dans des formulaires, de recréer des listes d’assets et d’attribuer des artistes un par un, ",[94,597,599],{"href":598},"https://blog.cg-wire.com/client-communication-animation/","votre onboarding est incomplet",[48,601,602],{},"Cette charge manuelle s’accumule très vite. Chaque nouvelle production répète le même rituel de configuration, chaque onboarding d’équipe devient une course au copier-coller, et chaque étape ajoute une opportunité de faire casser quelque chose. À l’échelle d’un studio, ces frictions coûtent du temps réel, de l’argent réel et de la santé mentale réelle.",[48,604,605],{},"Les studios les plus rapides n’utilisent pas seulement Kitsu : ils l’intègrent dans leur pipeline. Ils le traitent comme une base de données de production, en l’alimentant avec des données de studio propres et structurées pour mettre en ligne de nouvelles séries, des plans ou des départements en quelques minutes, et non en quelques jours. Les pipelines sont clonés, les équipes sont rattachées automatiquement, et Kitsu devient un moteur plutôt qu’un goulot d’étranglement.",[48,607,608],{},"Dans cet article, nous allons détailler un workflow pratique et éprouvé en production pour faire exactement cela, en utilisant des fichiers CSV et l’API Python de Kitsu (Gazu) afin d’automatiser l’onboarding de production et de faire disparaître le travail de configuration.",[31,610,612,615],{"className":611},[34,35,108],[31,613,112],{"className":614},[40],[31,616,618,622,624,129,626,628,134,630],{"className":617},[45],[117,619,620],{},[120,621,123],{"style":122},[125,623],{},[125,625],{},[125,627],{},[125,629],{},[94,631,633],{"href":632},"https://github.com/cgwire/blog-tutorials/tree/main/import-spreadsheet-to-kitsu?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/import-spreadsheet-to-kitsu",[61,635],{},[64,637,639],{"id":638},"what-you-can-import","Ce que vous pouvez importer",[48,641,642],{},"Dans une production réelle, la quasi-totalité des données se répartissent dans quelques catégories répétables, idéales pour l’automatisation :",[212,644,645,663,678],{},[215,646,647,650,651,655,656,309,659,662],{},[120,648,649],{},"Artistes"," - Votre équipe existe déjà quelque part ailleurs : une feuille RH, une export de paie, une table Notion. Ces données incluent généralement des noms, des e-mails et des rôles comme ",[652,653,654],"em",{},"Animator",", ",[652,657,658],{},"TD",[652,660,661],{},"Supervisor",". Au lieu de recréer des utilisateurs à la main dans Kitsu, vous pouvez importer cette liste en une seule passe et avoir votre équipe prête dès le premier jour.",[215,664,665,668,669,655,672,309,675],{},[120,666,667],{},"Assets"," - Personnages, accessoires, environnements… tout ce qui suit une convention de nommage s’automatise facilement. Un CSV contenant des entrées comme ",[155,670,671],{},"CHAR_RobotA",[155,673,674],{},"PROP_Sword_01",[155,676,677],{},"ENV_CityBlock",[215,679,680,683],{},[120,681,682],{},"Tâches"," - Les tâches sont aussi là où la configuration manuelle fait vraiment mal. Modélisation, Rigging, Surfacing, Animation… ces types de tâches changent rarement d’un show à l’autre. En important les tâches en masse, vous pouvez automatiquement attacher la bonne pile de tâches à chaque asset et même pré-assigner des artistes ou des départements, au lieu de cliquer dans des centaines de lignes dans l’interface.",[48,685,686,687,690],{},"Au-delà des bases, vous pouvez importer ",[94,688,689],{"href":250},"n’importe quel type de données orienté production que Kitsu comprend : séquences, plans, épisodes, ou même des productions entières",". Cela rend trivial la duplication de la structure d’un show précédent ou le lancement d’une nouvelle saison avec la même mise en page et les mêmes règles de nommage.",[48,692,693],{},"La plupart des studios stockent déjà tout cela dans des tableurs. Traitez ces tableurs comme des sources de données, alimentez-les directement dans Kitsu, et laissez l’automatisation faire le travail de configuration.",[48,695,696],{},"Si l’interface de Kitsu prend en charge des imports basiques de tableurs, la programmation va beaucoup plus loin : avec l’API Python de Kitsu (Gazu), vous pouvez enchaîner des automatisations comme synchroniser des tâches depuis Notion, mettre en miroir votre gestionnaire d’assets, ou régénérer des listes de tâches chaque fois que le planning change.",[72,698,700],{"className":699},[34,75],[77,701],{"src":702,"className":703,"alt":12,"loading":82,"width":704,"height":705,"srcSet":706},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-82a7e584-d2c0-4457-9ea4-4e97c794b6ff.png",[81],600,611,"https://blog.cg-wire.com/content/images/2026/02/data-src-image-82a7e584-d2c0-4457-9ea4-4e97c794b6ff.png 600w",[61,708],{},[64,710,712],{"id":711},"_1-csv-parser","1. Analyseur CSV",[48,714,715],{},"La première étape consiste à standardiser la manière dont vous lisez les données de studio. Le CSV est idéal : il est simple pour la production de l’éditer, et simple pour les scripts de le parser.",[48,717,718],{},"Dans ce tutoriel, nous allons nous concentrer sur le modèle de données des artistes pour plus de simplicité, mais nous pourrions faire quelque chose de similaire avec des assets stockés dans Google Drive, ou des tâches dans Trello.",[152,720,721,726],{},[155,722,725],{"className":723},[724],"language-py","def load_csv(file_path: Path) -> pd.DataFrame:\n    \"\"\"Load a CSV file into a pandas DataFrame.\"\"\"\n    return pd.read_csv(file_path)\n",[48,727,728],{},[155,729,731,732,735],{"className":730},[724],"def parse_artists(df: pd.DataFrame) -> List",[262,733,734],{},"Dict",":\n\"\"\"\nExpected columns:\n- email\n- first_name\n- last_name\n- role\n\"\"\"\nreturn df.to_dict(orient=\"records\")\n",[48,737,738,741],{},[155,739,740],{},"load_csv"," est le point d’entrée qui transforme un fichier CSV brut en quelque chose avec lequel Python peut travailler. Il lit le fichier depuis le disque à l’aide de pandas et renvoie un DataFrame, vous donnant une représentation structurée de type tableur que vous pouvez filtrer, valider ou transformer avant d’envoyer quoi que ce soit à Kitsu.",[48,743,744,747],{},[155,745,746],{},"parse_artists"," prend un DataFrame représentant des données d’artistes et convertit chaque ligne en un dictionnaire contenant l’e-mail, le nom et le rôle d’un artiste. En renvoyant une liste de ces dictionnaires, vous produisez des données prêtes pour l’API qui peuvent être transmises directement à Kitsu ou Gazu pour créer des utilisateurs en masse, au lieu d’ajouter des artistes un par un.",[48,749,750],{},"Un studio d’animation TV qui exporte des listes d’équipe depuis Google Sheets peut simplement les enregistrer en CSV, par exemple. La production conserve la responsabilité des données, tandis que les TD automatisent l’ingestion sans demander des changements de format à chaque show.",[61,752],{},[64,754,756],{"id":755},"_2-kitsu-auth","2. Auth Kitsu",[48,758,759],{},"Avant de téléverser quoi que ce soit, vous devez vous authentifier auprès de votre instance Kitsu :",[152,761,762],{},[155,763,182,765,188,768,193],{"className":764},[724],[94,766,185],{"href":185,"rel":767},[187],[94,769,192],{"href":191},[48,771,772,773,776],{},"En pratique, les studios utilisent souvent un ",[120,774,775],{},"compte pipeline ou admin dédié"," pour l’automatisation. Cela évite les problèmes de permissions et maintient les journaux d’audit propres lorsque des scripts créent ou modifient des données.",[48,778,779,780,166],{},"Pour les tests locaux, il est conseillé de ",[94,781,783,784],{"href":782},"https://blog.cg-wire.com/dcc-integration-blender-kitsu/","utiliser l’installation ",[155,785,786],{},"kitsu-docker",[61,788],{},[64,790,792],{"id":791},"_3-loading-data","3. Chargement des données",[48,794,795],{},"Les artistes sont généralement le premier goulot d’étranglement pendant l’onboarding. Vous devez collecter des e-mails, envoyer des invitations, les assigner à des tâches… automatiser leur création supprime des heures de travail manuel pour les coordinateurs de production.",[152,797,798,815],{},[155,799,801,802,804,805,808,809],{"className":800},[724],"def upload_artists(artists: List",[262,803,734],{},"):\n\"\"\"\nCreate artists if they do not already exist.\n\"\"\"\nexisting_users = {\nuser",[262,806,807],{},"\"email\"",": user\nfor user in gazu.person.all_persons()\n}",[152,810,813],{"className":811,"code":812,"language":291},[289],"for artist in artists:\n    if artist[\"email\"] in existing_users:\n        print(f\"Artist exists: {artist['email']}\")\n        continue\n\n    gazu.person.new_person(\n        artist[\"first_name\"],\n        artist[\"last_name\"],\n        artist[\"email\"],\n    )\n    print(f\"Created artist: {artist['email']}\")\n",[155,814,812],{"__ignoreMap":12},[48,816,817],{},[155,818],{"className":819},[724],[48,821,822],{},"Cette fonction prend une liste de dictionnaires d’artistes et les synchronise dans Kitsu tout en évitant les doublons.",[48,824,825],{},"Elle commence par interroger Kitsu pour tous les utilisateurs existants et construire une table de recherche indexée par e-mail, ce qui permet de vérifier rapidement si un artiste existe déjà.",[48,827,828],{},"Ensuite, elle parcourt les données d’artistes entrantes et, pour chaque entrée, compare l’e-mail avec cette table de recherche : si une correspondance est trouvée, le script ignore la création et journalise le fait que l’artiste existe déjà. Si aucune correspondance n’est trouvée, il crée un nouvel utilisateur dans Kitsu en utilisant le nom et l’e-mail de l’artiste via l’API Gazu, puis affiche une confirmation.",[48,830,831],{},"Le résultat est une étape d’import « idempotente » que vous pouvez relancer sans risque : les nouveaux artistes sont ajoutés, les artistes existants restent inchangés.",[48,833,834],{},"Lors d’un ramp-up pour un long-métrage, un studio pourrait importer des centaines d’artistes depuis les données RH en moins d’une minute. Les embauches tardives peuvent être ajoutées simplement en mettant à jour le CSV et en relançant le script sans dupliquer des utilisateurs ni faire de vérifications manuelles.",[61,836],{},[64,838,840],{"id":839},"_4-tying-it-all-together","4. Tout relier ensemble",[48,842,843],{},"Le point d’entrée principal assemble tout :",[152,845,846,870],{},[155,847,849,850,853,854,857,858,188,861,863,864],{"className":848},[724],"if ",[120,851,852],{},"name"," == \"",[120,855,856],{},"main","\":\ngazu.set_host(\"",[94,859,185],{"href":185,"rel":860},[187],[94,862,192],{"href":191},"\", \"mysecretpassword\")",[152,865,868],{"className":866,"code":867,"language":291},[289],"artists_df = load_csv(Path(\"artists.csv\"))\n\nartists = parse_artists(artists_df)\n\nupload_artists(artists)\n",[155,869,867],{"__ignoreMap":12},[48,871,872],{},[155,873],{"className":874},[724],[48,876,877],{},"Ce bloc ne s’exécute que lorsque le fichier est lancé directement, et non lorsqu’il est importé par un autre module.",[48,879,880,881,884],{},"Après l’authentification, il charge le fichier ",[155,882,883],{},"artists.csv"," dans un DataFrame pandas, convertit ces lignes en une liste de dictionnaires d’artistes via parse_artists, puis récupère une production existante dans Kitsu par son nom.",[48,886,887],{},"Enfin, il appelle upload_artists, qui se charge d’itérer sur ces données préparées et de créer les comptes d’artistes dans Kitsu, en complétant l’étape d’onboarding automatisée sans aucun travail manuel dans l’interface.",[48,889,890],{},"En pratique, les studios versionnent ces scripts avec leurs outils de pipeline. Un nouveau show devient une commande répétable, pas une checklist.",[48,892,893],{},"À présent, vous pouvez vous reconnecter à votre tableau de bord Kitsu et voir le résultat final :",[72,895,897],{"className":896},[34,75],[77,898],{"src":899,"className":900,"alt":12,"loading":82,"width":83,"height":84,"srcSet":901,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png 1600w",[48,903,904,907],{},[94,905,906],{"href":632},"Jetez un œil à notre dépôt Github correspondant"," pour un exemple fonctionnel que vous pouvez facilement fork afin de l’adapter à vos besoins !",[61,909],{},[64,911,508],{"id":507},[48,913,914],{},"Dans le meilleur des cas, l’automatisation de Kitsu permet aux directeurs techniques de reprendre le contrôle sur la manière dont les productions naissent. Lorsque votre pipeline peut se créer lui-même à partir de données propres, l’onboarding ne devient plus une corvée. En important directement les artistes, les assets et les tâches dans Kitsu, vous éliminez le travail redondant, réduisez les erreurs humaines et rendez l’onboarding de production prévisible. Cette approche s’adapte des petites équipes aux studios produisant plusieurs shows.",[48,916,917],{},"Voici quelques fonctionnalités supplémentaires que vous pourriez ajouter pour rendre votre pipeline d’importation encore plus intéressant :",[212,919,920,923,926,929],{},[215,921,922],{},"assigner automatiquement les tâches aux artistes en fonction de leur rôle",[215,924,925],{},"remplir les départements pour le suivi de production",[215,927,928],{},"générer des estimations de départ et des calendriers spécifiques à chaque département à partir de contraintes budgétaires",[215,930,931],{},"transformer un script en liste de découpage pour chaque plan et l’utiliser pour pré-générer des assets",[48,933,934],{},"La liste pourrait continuer, mais il suffit de commencer petit !",[31,936,938,941],{"className":937},[34,35,36],[31,939,524],{"className":940},[40],[31,942,944,945,948],{"className":943},[45],"Pour en apprendre davantage sur le processus d’animation, ",[94,946,534],{"href":531,"rel":947},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent les meilleures pratiques et organisent parfois des événements en présentiel. Nous serions ravis de vous accueillir ! 😊",[31,950,952],{"className":951},[34,539,540],[94,953,955],{"href":531,"className":954},[544,545],"Rejoignez Notre Communauté Discord",{"title":12,"searchDepth":548,"depth":548,"links":957},[958,959,960,961,962,963],{"id":638,"depth":548,"text":639},{"id":711,"depth":548,"text":712},{"id":755,"depth":548,"text":756},{"id":791,"depth":548,"text":792},{"id":839,"depth":548,"text":840},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1504868584819-f8e8b4b6d7e3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fHNwcmVhZHNoZWV0fGVufDB8fHx8MTc3MDA0NDU0MXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":966,"featured_at":561,"visibility":562},"2026-02-20T06:03:58.000+01:00","/blog-i18n/fr/automating-kitsu-production-onboarding","2026-02-16T10:00:37.000+01:00",{"title":577,"description":12},"automating-kitsu-production-onboarding","blog-i18n/fr/automating-kitsu-production-onboarding/index",[973],{"id":974,"name":975,"slug":976,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":977},"5fff0e4b653a0c003924f7f0","Production Management","production-management","https://blog.cg-wire.com/tag/production-management/","5bQwhXQIJ81teFQ6iWZxJ16UBexeFbdQ4RdhUKdt_X4",{"id":980,"title":981,"authors":982,"body":984,"description":12,"extension":557,"feature_image":1816,"html":7,"meta":1817,"navigation":13,"path":1819,"published_at":1820,"seo":1821,"slug":1822,"stem":1823,"tags":1824,"__hash__":1831,"updated_at":1818,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-addon-ui-scripting-guide/index.md","Un guide 2026 pour le développement d’une interface d’add-on Blender",[983],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":985,"toc":1798},[986,997,1005,1008,1034,1036,1042,1045,1065,1074,1081,1084,1091,1111,1117,1128,1143,1181,1187,1190,1193,1198,1204,1209,1215,1220,1226,1233,1235,1241,1244,1258,1261,1271,1276,1282,1287,1293,1298,1304,1309,1315,1318,1356,1359,1361,1367,1370,1380,1383,1389,1440,1446,1452,1455,1467,1520,1526,1529,1541,1602,1608,1611,1623,1648,1655,1680,1682,1688,1691,1713,1723,1729,1738,1741,1759,1761,1765,1768,1774,1777,1791],[31,987,989,993],{"className":988},[34,35,36],[31,990,992],{"className":991},[40],"📄",[31,994,996],{"className":995},[45],"Transformez vos scripts Blender en de vrais outils que les artistes ont envie d’utiliser—voici comment créer des panneaux UI propres et intuitifs pour vos add-ons.",[48,998,999,1000,1004],{},"Si vous avez déjà ",[94,1001,1003],{"href":1002},"https://blog.cg-wire.com/blender-scripting-animation/","écrit un script Blender",", vous avez probablement réalisé que réussir la fonctionnalité ne représente qu’une partie du travail : l’autre partie, c’est d’amener quelqu’un à s’en servir ! Une interface utilisateur claire est indispensable pour partager et vendre des add-ons Blender.",[48,1006,1007],{},"Dans ce guide, vous apprendrez comment construire des interfaces pour vos add-ons Blender grâce au système de mise en page intégré. Nous couvrirons les types les plus courants de composants UI, où les panneaux peuvent apparaître, et nous passerons en revue un exemple minimal fonctionnel. À la fin, vous saurez comment donner à votre add-on une interface graphique native de Blender.",[31,1009,1011,1014],{"className":1010},[34,35,108],[31,1012,112],{"className":1013},[40],[31,1015,1017,1022,1024,129,1026,1028,134,1030],{"className":1016},[45],[117,1018,1019],{},[120,1020,1021],{"style":122},"Vous cherchez des exemples qui fonctionnent ?",[125,1023],{},[125,1025],{},[125,1027],{},[125,1029],{},[94,1031,1033],{"href":1032},"https://github.com/cgwire/blender-ui-addon-script?ref=blog.cg-wire.com","https://github.com/cgwire/blender-ui-addon-script",[61,1035],{},[64,1037,1039],{"id":1038},"_1-common-ui-components",[120,1040,1041],{},"1. Les composants UI courants",[48,1043,1044],{},"Dans Blender, chaque élément de l’interface utilisateur a son équivalent dans la bibliothèque Python. Vous construisez l’UI en créant des classes qui héritent de l’un des types suivants :",[212,1046,1047,1053,1059],{},[215,1048,1049,1052],{},[155,1050,1051],{},"bpy.types.Panel"," - pour les panneaux personnalisés (les plus courants)",[215,1054,1055,1058],{},[155,1056,1057],{},"bpy.types.Menu"," - pour les menus et sous-menus",[215,1060,1061,1064],{},[155,1062,1063],{},"bpy.types.Operator"," - pour les actions ou outils qui peuvent être lancés via des boutons",[72,1066,1068],{"className":1067},[34,75],[77,1069],{"src":1070,"className":1071,"alt":12,"loading":82,"width":1072,"height":1073},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-daa22afa-ac20-4e3e-8543-c694588146bf.png",[81],334,542,[48,1075,1076,1077,1080],{},"Chacune de ces classes peut implémenter une méthode ",[155,1078,1079],{},"draw(self, context)",", dans laquelle vous décrivez à quoi l’interface doit ressembler en utilisant des commandes de mise en page. Le système de mise en page de Blender gère automatiquement l’espacement, l’alignement et le positionnement : c’est un système UI déclaratif où vous décrivez simplement ce qui doit apparaître et dans quel ordre.",[48,1082,1083],{},"Voici les éléments de mise en page les plus courants que vous utiliserez :",[1085,1086,1088],"h3",{"id":1087},"basic-display-elements",[120,1089,1090],{},"Éléments d’affichage de base",[212,1092,1093,1102],{},[215,1094,1095,1098,1099],{},[120,1096,1097],{},"Label"," - Affiche du texte simple, non interactif. Format : ",[155,1100,1101],{},"layout.label(text=\"Hello!\")",[215,1103,1104,1107,1108],{},[120,1105,1106],{},"Separator"," - Ajoute un espace vertical entre les éléments pour la lisibilité. Format : ",[155,1109,1110],{},"layout.separator()",[1085,1112,1114],{"id":1113},"buttons-inputs-props-and-operators",[120,1115,1116],{},"Boutons, entrées, propriétés (props) et opérateurs",[212,1118,1119],{},[215,1120,1121,1124,1125],{},[120,1122,1123],{},"Bouton d’opérateur"," - Crée un bouton cliquable qui déclenche un opérateur (une fonction enregistrée comme commande Blender). Vous pouvez l’utiliser pour des actions comme exporter, dupliquer ou exécuter un script personnalisé. Syntaxe : ",[155,1126,1127],{},"layout.operator(\"myaddon.some_action\", text=\"Run Action\")",[48,1129,1130,1131,1134,1135,1138,1139,1142],{},"La méthode ",[155,1132,1133],{},"layout.prop()"," sert à afficher des propriétés Blender éditables, qui proviennent soit de données intégrées (comme ",[155,1136,1137],{},"context.object","), soit de vos propres propriétés personnalisées. Par exemple, ",[155,1140,1141],{},"layout.prop(context.object, \"name\")"," affiche un champ de texte éditable pour le nom de l’objet. Blender choisit automatiquement le bon widget (zone de texte, curseur, case à cocher, etc.) en fonction du type de la propriété :",[212,1144,1145,1154,1163,1172],{},[215,1146,1147,1150,1151],{},[120,1148,1149],{},"Case à cocher (propriété booléenne)"," - Affiche une case à cocher de type bascule. Exemple : ",[155,1152,1153],{},"layout.prop(context.object, \"hide_viewport\")",[215,1155,1156,1159,1160],{},[120,1157,1158],{},"Champ numérique / curseur (Float ou Int)"," - Affiche une saisie numérique, souvent avec un curseur. Exemple : ",[155,1161,1162],{},"layout.prop(context.object, \"location\", index=0, text=\"X Location\")",[215,1164,1165,1168,1169],{},[120,1166,1167],{},"Menu déroulant (propriété Enum)"," - Affiche une liste déroulante lorsque la propriété est une EnumProperty. Exemple : ",[155,1170,1171],{},"layout.prop(context.object, \"type\")",[215,1173,1174,1177,1178],{},[120,1175,1176],{},"Saisie de texte ","- Affiche une zone de texte pour les propriétés de type chaîne. Exemple : ",[155,1179,1180],{},"layout.prop(my_settings, \"username\")",[1085,1182,1184],{"id":1183},"organizing-the-layout",[120,1185,1186],{},"Organiser la mise en page",[48,1188,1189],{},"Pour garder votre UI structurée et facile à comprendre, Blender fournit des conteneurs de mise en page comme des lignes, des colonnes et des boîtes.",[48,1191,1192],{},"Un panneau contient des lignes et des colonnes. Les lignes et les colonnes contiennent des propriétés, des opérateurs et des labels. Blender gère automatiquement les marges, l’alignement et la mise à l’échelle pour respecter le thème et les règles de mise en page.",[212,1194,1195],{},[215,1196,1197],{},"Une ligne (regroupement horizontal) place les éléments côte à côte horizontalement :",[152,1199,1200],{},[155,1201,1203],{"className":1202},[175],"row = layout.row()\nrow.prop(obj, \"location\")\nrow.prop(obj, \"rotation_euler\")",[212,1205,1206],{},[215,1207,1208],{},"Une colonne (regroupement vertical) empile les éléments verticalement :",[152,1210,1211],{},[155,1212,1214],{"className":1213},[175],"col = layout.column()\ncol.prop(obj, \"scale\")\ncol.prop(obj, \"dimensions\")",[212,1216,1217],{},[215,1218,1219],{},"Une boîte (regroupement visuel) dessine un cadre qui regroupe visuellement des contrôles associés, comme des sections :",[152,1221,1222],{},[155,1223,1225],{"className":1224},[175],"box = layout.box()\nbox.label(text=\"Transform Settings\")\nbox.prop(obj, \"location\")\nbox.prop(obj, \"rotation_euler\")",[48,1227,1228,1229,166],{},"Pour la liste complète des composants UI, consultez ",[94,1230,1232],{"href":1231},"https://docs.blender.org/manual/en/latest/interface/index.html?ref=blog.cg-wire.com","la page Interface utilisateur de la documentation officielle Blender",[61,1234],{},[64,1236,1238],{"id":1237},"_2-where-you-can-put-ui-panels",[120,1239,1240],{},"2. Où placer les panneaux UI",[48,1242,1243],{},"Lorsque vous créez un panneau personnalisé dans Blender, vous pouvez décider où dans l’interface il apparaît et quelle zone il occupe grâce à deux attributs de classe clés :",[212,1245,1246,1252],{},[215,1247,1248,1251],{},[155,1249,1250],{},"bl_space_type"," - indique l’éditeur ou l’espace de travail auquel votre panneau appartient (par exemple, la Vue 3D, l’Éditeur des propriétés ou l’Éditeur de nœuds).",[215,1253,1254,1257],{},[155,1255,1256],{},"bl_region_type"," - indique la partie de cet éditeur dans laquelle le panneau apparaît (par exemple, la barre latérale, la barre d’outils ou la fenêtre principale).",[48,1259,1260],{},"Voici une liste des zones les plus typiques où vous pourriez placer un panneau personnalisé :",[72,1262,1264],{"className":1263},[34,75],[77,1265],{"src":1266,"className":1267,"alt":12,"loading":82,"width":1268,"height":1269,"srcSet":1270,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png",[81],1125,650,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png 1125w",[212,1272,1273],{},[215,1274,1275],{},"La barre latérale de la vue 3D apparaît dans la barre latérale du panneau N à droite de la Vue 3D. C’est l’emplacement le plus courant pour les outils de modélisation, de rigging ou de scène :",[152,1277,1278],{},[155,1279,1281],{"className":1280},[175],"bl_space_type = 'VIEW_3D'\nbl_region_type = 'UI'",[212,1283,1284],{},[215,1285,1286],{},"Vous pouvez ajouter des panneaux dans l’Éditeur des propriétés, entre les onglets Objet, Matériau ou Scène. Utilisez cela lorsque votre add-on traite des matériaux, des objets, des réglages de rendu ou des propriétés de scène :",[152,1288,1289],{},[155,1290,1292],{"className":1291},[175],"bl_space_type = 'PROPERTIES'\nbl_region_type = 'WINDOW'",[212,1294,1295],{},[215,1296,1297],{},"Dans la barre latérale de l’Éditeur UV/Image (utile pour les outils de textures ou les utilitaires d’images) :",[152,1299,1300],{},[155,1301,1303],{"className":1302},[175],"bl_space_type = 'IMAGE_EDITOR'\nbl_region_type = 'UI'",[212,1305,1306],{},[215,1307,1308],{},"Dans la barre latérale des éditeurs Shader, Geometry Node ou Compositor pour les outils qui fonctionnent avec des nœuds, des shaders ou des systèmes procéduraux :",[152,1310,1311],{},[155,1312,1314],{"className":1313},[175],"bl_space_type = 'NODE_EDITOR'\nbl_region_type = 'UI'",[48,1316,1317],{},"L’emplacement de panneau le plus adapté dépend de l’objectif de votre outil :",[212,1319,1320,1331,1340,1348],{},[215,1321,1322,1323,1326,1327,1330],{},"Outils de modélisation / objets → Barre latérale de la Vue 3D (",[155,1324,1325],{},"VIEW_3D"," + ",[155,1328,1329],{},"UI",")",[215,1332,1333,1334,1326,1337,1330],{},"Réglages de matériau ou de rendu → Éditeur des propriétés (",[155,1335,1336],{},"PROPERTIES",[155,1338,1339],{},"WINDOW",[215,1341,1342,1343,1326,1346,1330],{},"Utilitaires de textures → Barre latérale de l’éditeur d’image (",[155,1344,1345],{},"IMAGE_EDITOR",[155,1347,1329],{},[215,1349,1350,1351,1326,1354,1330],{},"Outils Shader / Géométrie → Barre latérale de l’éditeur de nœuds (",[155,1352,1353],{},"NODE_EDITOR",[155,1355,1329],{},[48,1357,1358],{},"Choisir le bon espace aide les utilisateurs à trouver votre add-on là où ils s’attendent naturellement à ce qu’il soit, tout en gardant votre UI cohérente avec Blender.",[61,1360],{},[64,1362,1364],{"id":1363},"_3-minimal-example-custom-panel-in-the-3d-view-sidebar",[120,1365,1366],{},"3. Exemple minimal : panneau personnalisé dans la barre latérale de la Vue 3D",[48,1368,1369],{},"Faisons un test avec un plugin simple : un panneau personnalisé dans la barre latérale de la vue 3D qui affiche une alerte « hello world » quand on clique sur un bouton.",[1085,1371,1373],{"id":1372},"_1-blinfoaddon-metadata",[120,1374,1375,1376,1379],{},"1) ",[155,1377,1378],{},"bl_info"," - métadonnées de l’add-on",[48,1381,1382],{},"On commence par définir les métadonnées de l’add-on pour indiquer à Blender comment le présenter à un utilisateur potentiel :",[152,1384,1385],{},[155,1386,1388],{"className":1387},[175],"bl_info = {\n    \"name\": \"Simple Addon Example\",\n    \"author\": \"Your Name\",\n    \"version\": (1, 0),\n    \"blender\": (4, 0, 0),\n    \"location\": \"View3D > Sidebar > Simple Tab\",\n    \"description\": \"A simple example addon that prints a message\",\n    \"category\": \"3D View\",\n}",[212,1390,1391],{},[215,1392,1393,1395,1396],{},[155,1394,1378],{}," est un dictionnaire au niveau du module que Blender utilise pour afficher les infos de l’add-on dans Préférences → Add-ons",[212,1397,1398,1404,1410,1416,1422,1428,1434],{},[215,1399,1400,1403],{},[155,1401,1402],{},"name:"," nom lisible affiché dans la liste",[215,1405,1406,1409],{},[155,1407,1408],{},"author:"," chaîne de l’auteur",[215,1411,1412,1415],{},[155,1413,1414],{},"version:"," tuple représentant la version de l’add-on",[215,1417,1418,1421],{},[155,1419,1420],{},"blender:"," version minimale de Blender ciblée par cet add-on (tuple)",[215,1423,1424,1427],{},[155,1425,1426],{},"location:"," emplacement où apparaît l’UI de l’add-on (utile pour les utilisateurs)",[215,1429,1430,1433],{},[155,1431,1432],{},"description:"," courte description utilisée dans l’UI",[215,1435,1436,1439],{},[155,1437,1438],{},"category:"," catégorie de regroupement dans la liste Add-ons",[48,1441,1442,1443,1445],{},"Il est essentiel de garder votre ",[155,1444,1378],{}," exact, car Blender le lit lors du scan des add-ons installés.",[1085,1447,1449],{"id":1448},"_2-define-an-operator-class",[120,1450,1451],{},"2) Définir une classe d’opérateur",[48,1453,1454],{},"On définit ensuite une sous-classe Operator. Les opérateurs sont la manière officielle d’exécuter des actions dans Blender : ils peuvent être invoqués depuis l’UI, via des raccourcis, via le menu de recherche, etc.",[152,1456,1457,1461],{},[155,1458,1460],{"className":1459},[175],"class SIMPLEADDON_OT_hello(bpy.types.Operator):\n    bl_idname = \"simple_addon.say_hello\"\n    bl_label = \"Say Hello\"\n    bl_description = \"Prints a message to the console\"\n",[48,1462,1463],{},[155,1464,1466],{"className":1465},[175],"    def execute(self, context):\n        self.report({'INFO'}, \"Hello from Blender Addon!\")\n         print(\"Hello from Blender Addon!\")\n        return {'FINISHED'}",[212,1468,1469,1483,1489,1495],{},[215,1470,1471,1474,1475,1478,1479,1482],{},[155,1472,1473],{},"bl_idname"," - une chaîne d’identifiant unique sous la forme ",[155,1476,1477],{},"\"module_name.operator_name\"",", en minuscules et avec un point. C’est ainsi que vous appelez l’opérateur depuis le code ou l’UI (",[155,1480,1481],{},"bpy.ops.simple_addon.say_hello()",").",[215,1484,1485,1488],{},[155,1486,1487],{},"bl_label"," - libellé visible côté utilisateur, qui apparaît sur les boutons/menus.",[215,1490,1491,1494],{},[155,1492,1493],{},"bl_description"," - infobulle/description affichée dans l’UI.",[215,1496,1497,1500,1501,1504,1505,1508,1509,1512,1513,309,1516,1519],{},[155,1498,1499],{},"execute(self, context)"," - méthode principale appelée lorsque l’opérateur s’exécute (exécution synchrone). ",[155,1502,1503],{},"context"," donne accès à l’état actuel de Blender (objet actif, scène, zone, etc.). ",[155,1506,1507],{},"self.report({'INFO'}, \"…\")"," affiche un petit message dans la barre d’infos / statut de Blender (utile pour le retour utilisateur). ",[155,1510,1511],{},"print(\"…\")"," envoie un message dans la console système / Blender (utile pour le débogage). Renvoie un ensemble comme ",[155,1514,1515],{},"{'FINISHED'}",[155,1517,1518],{},"{'CANCELLED'}",". Blender utilise ce résultat pour savoir si l’opérateur s’est terminé avec succès.",[1085,1521,1523],{"id":1522},"_3-panel-classui-placement",[120,1524,1525],{},"3) Classe de panneau - emplacement UI",[48,1527,1528],{},"On arrive ensuite à la sous-classe Panel pour ajouter de l’UI dans Blender :",[152,1530,1531,1535],{},[155,1532,1534],{"className":1533},[175],"class SIMPLEADDON_PT_panel(bpy.types.Panel):\n    bl_label = \"Simple Addon Panel\"\n    bl_idname = \"SIMPLEADDON_PT_panel\"\n    bl_space_type = 'VIEW_3D'\n    bl_region_type = 'UI'\n    bl_category = 'Simple'",[48,1536,1537],{},[155,1538,1540],{"className":1539},[175],"    def draw(self, context):\n        layout = self.layout\n        layout.operator(\"simple_addon.say_hello\")",[212,1542,1543,1548,1553,1559,1568,1574,1579,1589],{},[215,1544,1545,1547],{},[155,1546,1487],{}," - titre du panneau affiché dans l’UI.",[215,1549,1550,1552],{},[155,1551,1473],{}," - identifiant unique du panneau.",[215,1554,1555,1558],{},[155,1556,1557],{},"bl_space_type = 'VIEW_3D'"," indique à Blender que ce panneau appartient à la zone de la Vue 3D.",[215,1560,1561,1564,1565,1482],{},[155,1562,1563],{},"bl_region_type = 'UI'"," l’affiche dans la zone à droite (le panneau N). D’autres zones existent (par exemple, ",[155,1566,1567],{},"'TOOLS', 'WINDOW'",[215,1569,1570,1573],{},[155,1571,1572],{},"bl_category = 'Simple'"," - le nom de l’onglet dans la barre latérale. Le panneau apparaîtra sous un onglet intitulé « Simple ».",[215,1575,1576,1578],{},[155,1577,1079],{}," est appelé pour dessiner la mise en page UI.",[215,1580,1581,1584,1585,1588],{},[155,1582,1583],{},"self.layout"," est un objet ",[155,1586,1587],{},"UILayout"," utilisé pour placer boutons, labels, propriétés, etc.",[215,1590,1591,1594,1595,1598,1599,1601],{},[155,1592,1593],{},"layout.operator(\"simple_addon.say_hello\")"," crée un bouton qui, une fois cliqué, appelle l’opérateur avec l’identifiant bl_idname ",[155,1596,1597],{},"\"simple_addon.say_hello\"",". Le texte du bouton est pris de la valeur ",[155,1600,1487],{}," de l’opérateur.",[1085,1603,1605],{"id":1604},"_4-register-unregister-functions",[120,1606,1607],{},"4) Fonctions register / unregister",[48,1609,1610],{},"Blender exige que les classes qui définissent l’UI, les opérateurs, les panneaux, les propriétés, etc., soient enregistrées afin que Blender sache qu’elles existent :",[152,1612,1613,1617],{},[155,1614,1616],{"className":1615},[175],"def register():\n    bpy.utils.register_class(SIMPLEADDON_OT_hello)\n    bpy.utils.register_class(SIMPLEADDON_PT_panel)",[48,1618,1619],{},[155,1620,1622],{"className":1621},[175],"def unregister():\n    bpy.utils.unregister_class(SIMPLEADDON_PT_panel)\n    bpy.utils.unregister_class(SIMPLEADDON_OT_hello)",[212,1624,1625,1635,1638],{},[215,1626,1627,1630,1631,1634],{},[155,1628,1629],{},"bpy.utils.register_class(Class)"," enregistre une classe ; ",[155,1632,1633],{},"unregister_class"," la retire.",[215,1636,1637],{},"Il est important de désenregistrer les classes dans l’ordre inverse de l’enregistrement, surtout quand les classes se référencent entre elles. C’est pourquoi le panneau est désenregistré avant l’opérateur.",[215,1639,1640,1641,1644,1645,166],{},"Lorsque l’add-on est activé dans les Préférences, Blender appelle ",[155,1642,1643],{},"register()",". Lorsqu’il est désactivé, il appelle ",[155,1646,1647],{},"unregister()",[48,1649,1650,1651,1654],{},"On met le code complet dans un fichier Python ",[155,1652,1653],{},"addon.py"," :",[152,1656,1657,1675],{},[155,1658,1388,1660,1663,1666,1669,1671,1673],{"className":1659},[175],[48,1661,1662],{},"import bpy",[48,1664,1665],{},"class SIMPLEADDON_OT_hello(bpy.types.Operator):\n    bl_idname = \"simple_addon.say_hello\"\n    bl_label = \"Say Hello\"\n    bl_description = \"Prints a message to the console\"",[48,1667,1668],{},"    def execute(self, context):\n        self.report({'INFO'}, \"Hello from Blender Addon!\")\n        print(\"Hello from Blender Addon!\")\n        return {'FINISHED'}",[48,1670,1534],{},[48,1672,1540],{},[48,1674,1616],{},[48,1676,1677],{},[155,1678,1622],{"className":1679},[175],[61,1681],{},[64,1683,1685],{"id":1684},"_4-running-and-packaging-your-add-on",[120,1686,1687],{},"4. Lancer et empaqueter votre add-on",[48,1689,1690],{},"Une fois que vous avez écrit votre script d’add-on, vous pouvez le charger dans Blender et le tester immédiatement. Aucun outil requis.",[1692,1693,1694,1700,1703,1710],"ol",{},[215,1695,1696,1697,166],{},"Enregistrez votre script - Enregistrez votre fichier Python avec un nom clair comme ",[155,1698,1699],{},"my_addon.py",[215,1701,1702],{},"Ouvrez les Préférences des add-ons de Blender - Allez dans Edition → Préférences → Add-ons. C’est ici que Blender gère toutes les extensions installées.",[215,1704,1705,1706,1709],{},"Installez l’add-on - Cliquez sur le bouton Installer… en haut de la fenêtre des préférences. ",[155,1707,1708],{},"Sélectionnez votre fichier my_addon.py"," puis cliquez sur Installer l’add-on.",[215,1711,1712],{},"L’activez - Après l’installation, votre add-on doit apparaître dans la liste. Trouvez-le (vous pouvez rechercher « Mon add-on ») puis cochez la case pour l’activer s’il n’est pas déjà activé.",[72,1714,1716],{"className":1715},[34,75],[77,1717],{"src":1718,"className":1719,"alt":12,"loading":82,"width":1720,"height":1721,"srcSet":1722,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png",[81],1227,800,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png 1227w",[1692,1724,1726],{"start":1725},5,[215,1727,1728],{},"Testez-le dans l’interface - Ouvrez la Vue 3D, ouvrez la barre latérale et cherchez l’onglet appelé Simple. Votre panneau personnalisé devrait y être, prêt à être utilisé !",[72,1730,1732],{"className":1731},[34,75],[77,1733],{"src":1734,"className":1735,"alt":12,"loading":82,"width":1720,"height":1736,"srcSet":1737,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png",[81],741,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png 1227w",[48,1739,1740],{},"Quand vous voulez partager votre add-on avec d’autres, vous pouvez le téléverser sur GitHub, Blender Artists ou Gumroad pour la distribution. Ajoutez un README.md court qui explique ce que fait l’add-on et comment l’installer.",[48,1742,1743,1744,1747,1748,1751,1752,1758],{},"Pour les add-ons composés de plusieurs fichiers (par ex. modules séparés, icônes ou ressources), créez un dossier puis compressez l’ensemble du dossier (",[155,1745,1746],{},"my_addon.zip",") et partagez-le. Blender peut installer des archives ",[155,1749,1750],{},".zip"," directement via le même bouton Installer… : il n’est donc pas nécessaire de l’extraire au préalable. Le point d’entrée principal doit s’appeler ",[155,1753,1754,1757],{},[120,1755,1756],{},"init",".py",", car Blender le traite comme un package Python.",[61,1760],{},[64,1762,1763],{"id":507},[120,1764,508],{},[48,1766,1767],{},"Créer une UI pour les add-ons Blender peut sembler intimidant au début, mais c’est l’une des façons les plus simples de partager un outil que vous avez créé. Une fois que vous comprenez comment fonctionnent les panneaux et les mises en page, vous pouvez ajouter rapidement des boutons, des propriétés et des sections bien organisées que les utilisateurs trouveront intuitives.",[48,1769,1770,1773],{},[94,1771,1772],{"href":1032},"Jetez un œil au dépôt de code sur Github"," pour tester l’exemple par vous-même.",[48,1775,1776],{},"Commencez modestement en ajoutant un panneau simple, un label et un bouton pour créer une action, puis développez à partir de là !",[31,1778,1780,1783],{"className":1779},[34,35,36],[31,1781,524],{"className":1782},[40],[31,1784,1786,1787,1790],{"className":1785},[45],"Pour en savoir plus sur le processus d’animation, ",[94,1788,534],{"href":531,"rel":1789},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent les bonnes pratiques et organisent parfois des événements en présentiel. Nous serions ravis de vous accueillir ! 😊",[31,1792,1794],{"className":1793},[34,539,540],[94,1795,1797],{"href":531,"className":1796},[544,545],"Rejoindre notre communauté Discord",{"title":12,"searchDepth":548,"depth":548,"links":1799},[1800,1806,1807,1814,1815],{"id":1038,"depth":548,"text":1041,"children":1801},[1802,1804,1805],{"id":1087,"depth":1803,"text":1090},3,{"id":1113,"depth":1803,"text":1116},{"id":1183,"depth":1803,"text":1186},{"id":1237,"depth":548,"text":1240},{"id":1363,"depth":548,"text":1366,"children":1808},[1809,1811,1812,1813],{"id":1372,"depth":1803,"text":1810},"1) bl_info - métadonnées de l’add-on",{"id":1448,"depth":1803,"text":1451},{"id":1522,"depth":1803,"text":1525},{"id":1604,"depth":1803,"text":1607},{"id":1684,"depth":548,"text":1687},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1760548425425-e42e77fa38f1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGNvZGluZyUyMGludGVyZmFjZSUyMHRvb2xzfGVufDB8fHx8MTc2Mzg5MzE4MXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":1818,"featured_at":561,"visibility":562},"2026-02-20T06:03:59.000+01:00","/blog-i18n/fr/blender-addon-ui-scripting-guide","2025-11-24T10:00:34.000+01:00",{"title":981,"description":12},"blender-addon-ui-scripting-guide","blog-i18n/fr/blender-addon-ui-scripting-guide/index",[1825,1826],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"69c20ddbcb09d8000107cfe5","Blender","blender","https://blog.cg-wire.com/tag/blender/","eLQ2SAY5txedwQKCvYSpavqNAox9v8oBwBDK0osL_B4",{"id":1833,"title":1834,"authors":1835,"body":1837,"description":12,"extension":557,"feature_image":2554,"html":7,"meta":2555,"navigation":13,"path":2557,"published_at":2558,"seo":2559,"slug":2560,"stem":2561,"tags":2562,"__hash__":2565,"updated_at":2556,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-kitsu-breakdown-automation/index.md","Comment générer automatiquement des plans Blender avec Python et Kitsu (2026)",[1836],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":1838,"toc":2545},[1839,1850,1857,1863,1866,1869,1876,1903,1905,1911,1927,1930,1933,1974,1984,1990,1993,2001,2008,2035,2040,2043,2045,2051,2058,2061,2105,2110,2117,2120,2122,2128,2131,2138,2145,2151,2160,2163,2165,2171,2182,2193,2205,2224,2227,2229,2235,2246,2261,2274,2284,2286,2292,2295,2304,2473,2478,2487,2497,2506,2508,2512,2515,2524,2527,2539],[31,1840,1842,1846],{"className":1841},[34,35,36],[31,1843,1845],{"className":1844},[40],"🧩",[31,1847,1849],{"className":1848},[45],"Automatisez la préparation de vos plans et éliminez des heures de placement manuel d’assets.",[48,1851,1852,1853,1856],{},"Les studios d’animation s’appuient sur des ",[120,1854,1855],{},"listes de breakdown"," pour suivre les assets qui doivent apparaître dans chaque plan.",[48,1858,1859,1860],{},"Imaginez ceci. Vous êtes un(e) artiste VFX, face à un viewport Blender vide pour la production en cours. Votre responsable vous remet la liste détaillée des assets, des plans et des repères de timing, puis vous dit : ",[652,1861,1862],{},"\"Transforme ça en scène Blender.\"",[48,1864,1865],{},"Votre première idée pourrait être de vous connecter à votre gestionnaire d’assets et de placer chaque objet manuellement. Mais qu’en est-il des scènes complexes avec des centaines d’assets ?",[48,1867,1868],{},"C’est à ce moment qu’une simple automatisation peut sauver la mise. Avec le scripting Python pour Blender, vous pouvez lire les données de breakdown de Kitsu et générer automatiquement une scène initiale en quelques minutes.",[48,1870,1871,1872,1875],{},"Dans cet article, nous allons parcourir un exemple complet : récupérer des breakdowns via la ",[120,1873,1874],{},"API Python de Gazu",", créer une nouvelle scène Blender, télécharger les assets, et les importer dans Blender. À la fin, vous disposerez d’un pipeline minimal qui construit des scènes automatiquement, prêtes pour le layout ou l’animation.",[31,1877,1879,1882],{"className":1878},[34,35,108],[31,1880,112],{"className":1881},[40],[31,1883,1885,1890,1892,1894,1895,1897,134,1899],{"className":1884},[45],[117,1886,1887],{},[120,1888,1889],{"style":122},"Vous cherchez des exemples fonctionnels ?",[125,1891],{},[125,1893],{},"Vous pouvez trouver le code source complet de l’intégration de l’exemple présentée dans ce guide sur notre GitHub :",[125,1896],{},[125,1898],{},[94,1900,1902],{"href":1901},"https://github.com/cgwire/blender-kitsu-automated-scene-composition?ref=blog.cg-wire.com","https://github.com/cgwire/blender-kitsu-automated-scene-composition",[61,1904],{},[64,1906,1908],{"id":1907},"_1-getting-the-breakdown",[120,1909,1910],{},"1. Obtenir le breakdown",[48,1912,1913,1914,1926],{},"Chaque plan 3D commence comme une toile vierge, mais les instructions pour remplir cette toile existent déjà dans Kitsu :",[94,1915,1917,1918],{"href":1916},"https://blog.cg-wire.com/3d-animation-process/"," ",[1919,1920,1921,1922,1925],"u",{},"le ",[120,1923,1924],{},"breakdown"," indique précisément ce qui doit se trouver sur scène"," avant que l’animateur commence son travail.",[48,1928,1929],{},"Un breakdown typique fournit le contexte narratif essentiel dont votre script a besoin pour assembler la scène : la scène (images de départ et de fin, durée et autres annotations stockées dans les informations de séquence), et la distribution (le breakdown réel des modèles de personnages, des props et des assets d’environnement).",[48,1931,1932],{},"Avant d’écrire du code, vous devez définir le breakdown dans le tableau de bord Kitsu. C’est là que vous reliez manuellement votre bibliothèque d’assets 3D aux plans spécifiques pour lesquels ils sont requis. Ici, vous ne créez pas de nouveaux modèles : vous affectez simplement des « acteurs » (assets) à un plan précis :",[1692,1934,1935,1944,1954,1964],{},[215,1936,1937,1940,1941,166],{},[120,1938,1939],{},"Accédez à votre production"," - Naviguez vers votre projet dans Kitsu et ouvrez l’onglet ",[120,1942,1943],{},"Shots",[215,1945,1946,1949,1950,1953],{},[120,1947,1948],{},"Trouvez la feuille de casting"," - Cherchez l’onglet ",[120,1951,1952],{},"Breakdown"," (généralement situé dans le panneau de droite ou dans un onglet dédié selon votre version).",[215,1955,1956,1959,1960,1963],{},[120,1957,1958],{},"Sélectionnez le plan"," - Cliquez sur le plan précis que vous souhaitez remplir (par ex. ",[155,1961,1962],{},"SH01",") pour ouvrir la vue détaillée du casting.",[215,1965,1966,1969,1970,1973],{},[120,1967,1968],{},"Assignez les assets"," - Dans le panneau latéral droit, cliquez sur le bouton ",[120,1971,1972],{},"+ (Plus)"," ou sur « Add Asset ». Vous pouvez aussi indiquer ici la quantité de chaque asset dont vous avez besoin.",[72,1975,1977],{"className":1976},[34,75],[77,1978],{"src":1979,"className":1980,"alt":12,"loading":82,"width":1981,"height":1982,"srcSet":1983,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png",[81],1466,804,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png 1466w",[48,1985,1986,1987,1989],{},"Assurez-vous que votre page ",[120,1988,667],{}," contient déjà les modèles (Characters, Props, etc.) que vous avez l’intention d’utiliser.",[48,1991,1992],{},"Une fois que vous cliquez sur enregistrer, le lien est établi. Maintenant, lorsque votre script Python demande à Gazu : « Qui est dans ce plan ? », Kitsu répond avec la liste des assets que vous venez d’assigner. Votre script Python joue le rôle de passerelle : il analyse ce casting pour remplir automatiquement le viewport Blender.",[48,1994,1995,1996,166],{},"Si vous avez besoin d’un environnement local de développement, jetez un œil à ",[94,1997,1917,1998],{"href":782},[1919,1999,2000],{},"comment installer Kitsu depuis Docker dans le guide Custom DCC Bridge",[48,2002,2003,2004,2007],{},"Pendant que Kitsu détient les données, nous avons besoin d’un moyen de les récupérer. Passons à ",[120,2005,2006],{},"Gazu",", le SDK Python pour l’API REST de Kitsu :",[152,2009,2010,2029],{},[155,2011,176,2013,2022,2026],{"className":2012},[175],[48,2014,2015,2016,2019,2020,863],{},"gazu.set_host(\"\u003C",[94,2017,185],{"href":185,"rel":2018},[187],">\")\nuser = gazu.log_in(\"",[94,2021,192],{"href":191},[48,2023,260,2024],{},[262,2025,264],{},[48,2027,2028],{},"sequence = gazu.shot.get_sequence_by_name(project, \"SQ01\")\nshot = gazu.shot.get_shot_by_name(sequence, \"SH01\")",[48,2030,2031],{},[155,2032,2034],{"className":2033},[175],"assets = gazu.casting.get_shot_casting(shot)",[48,2036,2037,2039],{},[125,2038],{},"On se connecte à notre instance locale de Kitsu, puis on choisit notre première production (vous pouvez aussi récupérer une production par nom) et le plan pour lequel nous avons besoin du casting.",[48,2041,2042],{},"Nous pouvons utiliser cet identifiant de plan pour récupérer le casting correspondant des assets, c’est-à-dire la liste de breakdown.",[61,2044],{},[64,2046,2048],{"id":2047},"_2-getting-assets-from-a-breakdown",[120,2049,2050],{},"2. Obtenir des assets à partir d’un breakdown",[48,2052,2053,2054,2057],{},"Maintenant que nous savons ",[652,2055,2056],{},"qui"," se trouve dans le plan, nous devons déterminer à quoi ils ressemblent.",[48,2059,2060],{},"Dans Kitsu, un asset peut avoir de nombreux fichiers d’aperçu que nous pouvons utiliser selon les révisions. Notre script doit pouvoir parcourir ces données pour obtenir la dernière révision de chaque asset :",[152,2062,2063,2099],{},[155,2064,2066,2067,2069,2070,2073,2074,1330,2077,2082,2085,2096],{"className":2065},[175],"local_paths = ",[262,2068],{},"\nfor asset in assets:\n    tasks = gazu.task.all_tasks_for_asset(asset",[262,2071,2072],{},"\"asset_id\"",")\n    last_task = max(tasks, key=lambda x: x",[262,2075,2076],{},"\"updated_at\"",[48,2078,2079,2080,1330],{},"    preview_files = gazu.files.get_all_preview_files_for_task(last_task)\n    last_preview_file = max(preview_files, key=lambda x: x",[262,2081,2076],{},[48,2083,2084],{},"    download_dir = \"./previews\"\n    os.makedirs(download_dir, exist_ok=True)",[48,2086,2087,2088,2091,2092,2095],{},"    save_path = os.path.join(\n        download_dir,\n        last_preview_file",[262,2089,2090],{},"\"original_name\""," + \".\" + last_preview_file",[262,2093,2094],{},"\"extension\"",",\n    )",[48,2097,2098],{},"    gazu.files.download_preview_file(last_preview_file, save_path)",[48,2100,2101],{},[155,2102,2104],{"className":2103},[175],"    local_paths.append(save_path)",[48,2106,2107,2109],{},[125,2108],{},"Pour chaque asset, nous récupérons une liste de toutes les tasks correspondantes, quel que soit le type (« Modeling », « Animation », etc.) ou le statut (« done », « todo »…). Nous filtrons cette liste pour obtenir la task mise à jour le plus récemment.",[48,2111,2112,2113,2116],{},"Nous pouvons utiliser l’identifiant de cette task pour obtenir la dernière révision du fichier d’aperçu correspondant et le télécharger dans un dossier local ",[155,2114,2115],{},"previews",". Nous conservons ces chemins de téléchargement en mémoire pour l’étape d’import.",[48,2118,2119],{},"À la fin de cette boucle, vous avez transformé avec succès des entrées de base de données en fichiers modèles concrets sur votre disque dur, prêts à être importés par Blender.",[61,2121],{},[64,2123,2125],{"id":2124},"_3-creating-a-new-blender-scene",[120,2126,2127],{},"3. Créer une nouvelle scène Blender",[48,2129,2130],{},"Une fois les fichiers d’assets téléchargés en toute sécurité, la tâche suivante consiste à préparer l’environnement Blender afin d’accueillir son nouveau membre de distribution.",[48,2132,2133,2134,2137],{},"Le module ",[155,2135,2136],{},"bpy",", l’API Python native de Blender, agit comme votre console de commandes et vous permet de manipuler chaque élément de l’application.",[48,2139,2140,2141,2144],{},"Avant d’importer nos assets Kitsu, nous devons supprimer tous les objets par défaut qui accompagnent une nouvelle scène Blender. Pour ce tutoriel simple, nous visons le ",[120,2142,2143],{},"Cube"," par défaut, souvent le seul objet présent en dehors de la Camera et de la Light :",[152,2146,2147],{},[155,2148,2150],{"className":2149},[175],"bpy.data.objects.remove(bpy.data.objects.get(\"Cube\"), do_unlink=True)",[48,2152,2153,2155,2156,2159],{},[125,2154],{},"Le paramètre ",[155,2157,2158],{},"do_unlink=True"," indique à Blender de supprimer complètement le bloc de données de l’objet (comme ses données de maillage) s’il n’est plus utilisé par un autre objet, afin de ne laisser aucun élément superflu.",[48,2161,2162],{},"Nous sommes maintenant prêts à placer les assets importés à leur position.",[61,2164],{},[64,2166,2168],{"id":2167},"_4-importing-asset-files",[120,2169,2170],{},"4. Importer des fichiers d’assets",[48,2172,2173,2174,2177,2178,2181],{},"Passons au résultat ! Le fichier que nous avons téléchargé depuis Kitsu est un format d’échange standardisé ",[155,2175,2176],{},".glb",", qui gère à la fois la géométrie et les matériaux de base ; nous utilisons donc l’opérateur d’import dédié ",[155,2179,2180],{},"gltf"," de Blender.",[48,2183,2184,2185,2188,2189,2192],{},"La partie cruciale est de fournir le ",[120,2186,2187],{},"chemin de fichier absolu"," (",[155,2190,2191],{},"glb_path",") vers l’asset téléchargé. Heureusement, nous les avons stockés dans l’extrait de code précédent :",[152,2194,2195,2199],{},[155,2196,2198],{"className":2197},[175],"for path in local_paths:\n    if path.lower().endswith((\".glb\")):\n        print(f\"Importing: {path}\")\n        bpy.ops.import_scene.gltf(filepath=path)",[48,2200,2201],{},[155,2202,2204],{"className":2203},[175],"print(\"All preview GLB files imported successfully!\")",[48,2206,2207,2209,2210,2213,2214,655,2217,498,2220,2223],{},[125,2208],{},"Une fois que ",[155,2211,2212],{},"bpy.ops.import_scene.gltf()"," s’exécute, Blender lit le fichier et crée automatiquement les ",[120,2215,2216],{},"objets",[120,2218,2219],{},"meshes",[120,2221,2222],{},"materials"," correspondants dans la scène en cours.",[48,2225,2226],{},"L’asset importé est désormais un objet Blender à part entière, placé à l’origine du monde (0, 0, 0), prêt pour les étapes suivantes du pipeline.",[61,2228],{},[64,2230,2232],{"id":2231},"_5-saving-the-scene",[120,2233,2234],{},"5. Enregistrer la scène",[48,2236,2237,2238,2241,2242,2245],{},"La dernière étape dans ce segment de pipeline est d’enregistrer la mise en page assemblée dans un fichier permanent et versionnable. Si vous fermez Blender sans cette étape, tout le travail automatisé est perdu : nous utilisons donc l’opérateur ",[155,2239,2240],{},"bpy.ops.wm.save_as_mainfile",". C’est l’équivalent programmatique du clic ",[120,2243,2244],{},"File &gt; Save As"," dans l’interface Blender :",[152,2247,2248,2255],{},[155,2249,2251,2252],{"className":2250},[175],"scene_save_dir = \"./\"\nos.makedirs(scene_save_dir, exist_ok=True)",[48,2253,2254],{},"blend_filename = \"SH01.blend\"\nblend_path = os.path.join(scene_save_dir, blend_filename)",[48,2256,2257],{},[155,2258,2260],{"className":2259},[175],"bpy.ops.wm.save_as_mainfile(filepath=blend_path)",[48,2262,2263,2265,2266,2269,2270,2273],{},[125,2264],{},"Le résultat est un nouveau fichier Blender, ",[155,2267,2268],{},"SH01.blend",", qui reflète parfaitement les ",[120,2271,2272],{},"exigences de breakdown"," depuis Kitsu, prêt pour que le prochain département puisse le récupérer.",[72,2275,2277],{"className":2276},[34,75],[77,2278],{"src":2279,"className":2280,"alt":12,"loading":82,"width":2281,"height":2282,"srcSet":2283,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png",[81],1460,828,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png 1460w",[61,2285],{},[64,2287,2289],{"id":2288},"_6-user-friendly-addon",[120,2290,2291],{},"6. Un addon convivial",[48,2293,2294],{},"Le script fonctionne comme prévu, mais qu’en est-il des artistes ? Tout le monde ne sait pas comment exécuter un script.",[48,2296,2297,2298,1654],{},"Modifions légèrement notre code pour ",[94,2299,1917,2301],{"href":2300},"https://blog.cg-wire.com/blender-addon-ui-scripting-guide/",[1919,2302,2303],{},"le transformer en addon Blender",[152,2305,2306,2463],{},[155,2307,2309,2310,2313,2316,2319,2336,2353,2368,2371,2374,2377,2380,2383,2386,2389,2394,2400,2406,2411,2420,2423,2426,2429,2432,2439,2442,2445,2448,2451,2454,2457,2460],{"className":2308},[175],"bl_info = {\n    \"name\": \"Kitsu Shot Auto-Importer\",\n    \"description\": \"Pick a project and shot and auto-import the latest preview assets\",\n    \"author\": \"cgwire\",\n    \"version\": (1, 0, 0),\n    \"blender\": (3, 0, 0),\n    \"location\": \"Viewport > N-Panel > Kitsu\",\n    \"category\": \"Import-Export\",\n}",[48,2311,2312],{},"import os\nimport sys",[48,2314,2315],{},"sys.path.append(\"~/.local/lib/python3.11/site-packages\")",[48,2317,2318],{},"import bpy\nimport gazu\nfrom bpy.props import EnumProperty, StringProperty",[48,2320,2321,2322,2333,2334],{},"def get_projects():\n    try:\n        projects = gazu.project.all_projects()\n        return ",[262,2323,2324,2325,2328,2329,2332],{},"(p",[262,2326,2327],{},"\"id\"",", p",[262,2330,2331],{},"\"name\"",", \"\") for p in projects","\n    except:\n        return ",[262,2335],{},[48,2337,2338,2339,2341,2342,2333,2351],{},"def get_sequences(project_id):\n    if not project_id:\n        return ",[262,2340],{},"\n    try:\n        seqs = gazu.shot.all_sequences_for_project(project_id)\n        return ",[262,2343,2344,2345,2347,2348,2350],{},"(s",[262,2346,2327],{},", s",[262,2349,2331],{},", \"\") for s in seqs",[262,2352],{},[48,2354,2355,2356,2358,2359,2333,2366],{},"def get_shots(sequence_id):\n    if not sequence_id:\n        return ",[262,2357],{},"\n    try:\n        shots = gazu.shot.all_shots_for_sequence(sequence_id)\n        return ",[262,2360,2344,2361,2347,2363,2365],{},[262,2362,2327],{},[262,2364,2331],{},", \"\") for s in shots",[262,2367],{},[48,2369,2370],{},"class KITSU_Props(bpy.types.PropertyGroup):\n    project: EnumProperty(name=\"Project\", items=lambda self, context: get_projects())",[48,2372,2373],{},"    sequence: EnumProperty(\n        name=\"Sequence\", items=lambda self, context: get_sequences(self.project)\n    )",[48,2375,2376],{},"    shot: EnumProperty(\n        name=\"Shot\", items=lambda self, context: get_shots(self.sequence)\n    )",[48,2378,2379],{},"class KITSU_OT_import_shot(bpy.types.Operator):\n    bl_idname = \"kitsu.import_shot_assets\"\n    bl_label = \"Import Shot Assets\"\n    bl_description = (\n        \"Download and import latest preview GLB/GLTF files for selected shot\"\n    )",[48,2381,2382],{},"    def execute(self, context):\n        props = context.scene.kitsu_props",[48,2384,2385],{},"        # Fetch shot data\n        shot = gazu.shot.get_shot(props.shot)\n        assets = gazu.casting.get_shot_casting(shot)",[48,2387,2388],{},"        download_dir = os.path.join(bpy.app.tempdir, \"kitsu_previews\")\n        os.makedirs(download_dir, exist_ok=True)",[48,2390,2391,2392],{},"        local_paths = ",[262,2393],{},[48,2395,2396,2397,2399],{},"        for asset in assets:\n            tasks = gazu.task.all_tasks_for_asset(asset",[262,2398,2072],{},")\n            if not tasks:\n                continue",[48,2401,2402,2403,2405],{},"            last_task = max(tasks, key=lambda x: x",[262,2404,2076],{},")\n            preview_files = gazu.files.get_all_preview_files_for_task(last_task)\n            if not preview_files:\n                continue",[48,2407,2408,2409,1330],{},"            last_preview = max(preview_files, key=lambda x: x",[262,2410,2076],{},[48,2412,2413,2414,2416,2417,2419],{},"            save_path = os.path.join(\n                download_dir,\n                last_preview",[262,2415,2090],{}," + \".\" + last_preview",[262,2418,2094],{},",\n            )",[48,2421,2422],{},"            gazu.files.download_preview_file(last_preview, save_path)\n            local_paths.append(save_path)",[48,2424,2425],{},"        # Clean default cube\n        obj = bpy.data.objects.get(\"Cube\")\n        if obj:\n            bpy.data.objects.remove(obj, do_unlink=True)",[48,2427,2428],{},"        # Import GLB/GLTF assets\n        for path in local_paths:\n            if path.lower().endswith((\".glb\", \".gltf\")):\n                bpy.ops.import_scene.gltf(filepath=path)",[48,2430,2431],{},"        # Auto-save blend file\n        save_dir = os.path.join(os.path.expanduser(\"~\"), \"kitsu_scenes\")\n        os.makedirs(save_dir, exist_ok=True)",[48,2433,2434,2435,2438],{},"        blend_path = os.path.join(save_dir, f\"{shot",[262,2436,2437],{},"'name'","}.blend\")\n        bpy.ops.wm.save_as_mainfile(filepath=blend_path)",[48,2440,2441],{},"        self.report({\"INFO\"}, f\"Imported assets and saved: {blend_path}\")\n        return {\"FINISHED\"}",[48,2443,2444],{},"class KITSU_PT_panel(bpy.types.Panel):\n    bl_label = \"Kitsu Auto-Importer\"\n    bl_idname = \"KITSU_PT_auto_importer\"\n    bl_space_type = \"VIEW_3D\"\n    bl_region_type = \"UI\"\n    bl_category = \"Kitsu\"",[48,2446,2447],{},"    def draw(self, context):\n        props = context.scene.kitsu_props\n        layout = self.layout",[48,2449,2450],{},"        layout.separator()\n        layout.prop(props, \"project\")\n        layout.prop(props, \"sequence\")\n        layout.prop(props, \"shot\")",[48,2452,2453],{},"        layout.separator()\n        layout.operator(\"kitsu.import_shot_assets\", icon=\"IMPORT\")",[48,2455,2456],{},"classes = (\n    KITSU_Props,\n    KITSU_OT_import_shot,\n    KITSU_PT_panel,\n)",[48,2458,2459],{},"def register():\n    for c in classes:\n        bpy.utils.register_class(c)\n    bpy.types.Scene.kitsu_props = bpy.props.PointerProperty(type=KITSU_Props)",[48,2461,2462],{},"def unregister():\n    for c in classes:\n        bpy.utils.unregister_class(c)\n    del bpy.types.Scene.kitsu_props",[48,2464,2465],{},[155,2466,849,2468,853,2470,2472],{"className":2467},[175],[120,2469,852],{},[120,2471,856],{},"\":\n    register()",[48,2474,2475,2477],{},[125,2476],{},"Vous pouvez maintenant choisir manuellement une production, une séquence et un plan pour récupérer les données de breakdown, puis importer le casting correspondant dans le viewport Blender actuel :",[72,2479,2481],{"className":2480},[34,75],[77,2482],{"src":2483,"className":2484,"alt":12,"loading":82,"width":2485,"height":2486},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-bf3ea18d-fd62-4db5-9977-6374b3ee1aef.png",[81],480,270,[48,2488,2489,2490,2492,2493,2496],{},"La logique est simple : on utilise le même code ",[155,2491,165],{}," pour alimenter les menus déroulants, et on encapsule tout cela dans un panneau de la vue. Un bouton ",[155,2494,2495],{},"import"," télécharge tous les assets de breakdown correspondants et les importe dans l’espace de travail actuel.",[48,2498,2499,2500,2502,2503,2505],{},"N’oubliez pas que l’ajout de ",[155,2501,2315],{}," permet à Blender d’utiliser l’installation Python de votre système pour charger des bibliothèques externes comme ",[155,2504,165],{},". Comme Blender est fourni avec son propre environnement Python isolé, gérer l’installation des packages peut être contraignant. En étendant le chemin, vous indiquez simplement à Blender de vérifier aussi vos modules locaux. Assurez-vous d’ajuster ce chemin pour qu’il corresponde à votre configuration.",[61,2507],{},[64,2509,2510],{"id":507},[120,2511,508],{},[48,2513,2514],{},"En récupérant directement les listes de breakdown depuis Kitsu et en scriptant Blender pour assembler des scènes, vous éliminez les étapes manuelles répétitives et vous garantissez la cohérence des assets sur tous les plans. Cette approche ne fait pas que gagner du temps : elle réduit aussi les erreurs humaines et garantit que chaque artiste démarre avec la bonne version d’assets et la configuration de scène requise par le producteur. Ainsi, vous pouvez gérer facilement dix plans ou dix mille, avec la même fiabilité.",[48,2516,2517,2518,2523],{},"Mais ne nous croyez pas sur parole,",[94,2519,1917,2520],{"href":1901},[1919,2521,2522],{},"cloniez le dépôt GitHub"," pour tester le résultat !",[48,2525,2526],{},"Vous pouvez étendre ce workflow en générant des aperçus automatisés, des rapports, ou même en mettant à jour les informations d’assets à partir des nouvelles révisions créées pendant l’animation du plan.",[31,2528,2530,2533],{"className":2529},[34,35,36],[31,2531,524],{"className":2532},[40],[31,2534,528,2536,948],{"className":2535},[45],[94,2537,534],{"href":531,"rel":2538},[533],[31,2540,2542],{"className":2541},[34,539,540],[94,2543,546],{"href":531,"className":2544},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":2546},[2547,2548,2549,2550,2551,2552,2553],{"id":1907,"depth":548,"text":1910},{"id":2047,"depth":548,"text":2050},{"id":2124,"depth":548,"text":2127},{"id":2167,"depth":548,"text":2170},{"id":2231,"depth":548,"text":2234},{"id":2288,"depth":548,"text":2291},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1725888358557-9f70661012c4?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGFuaW1hdGlvbiUyMHBpcGVsaW5lfGVufDB8fHx8MTc2NTA5ODQ2Mnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":2556,"featured_at":561,"visibility":562},"2026-02-20T06:04:00.000+01:00","/blog-i18n/fr/blender-kitsu-breakdown-automation","2025-12-07T18:11:31.000+01:00",{"title":1834,"description":12},"blender-kitsu-breakdown-automation","blog-i18n/fr/blender-kitsu-breakdown-automation/index",[2563,2564],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"tFkVl3dqsSZX6PYXRU8JEZ4NyPBfOdsOLMK4CQyzT-c",{"id":2567,"title":2568,"authors":2569,"body":2571,"description":12,"extension":557,"feature_image":3168,"html":7,"meta":3169,"navigation":13,"path":3171,"published_at":3172,"seo":3173,"slug":3174,"stem":3175,"tags":3176,"__hash__":3179,"updated_at":3170,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-kitsu-low-res-preview/index.md","Automatiser les aperçus d’animation basse résolution dans Blender avec Kitsu (2026)",[2570],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":2572,"toc":3158},[2573,2584,2587,2590,2593,2596,2614,2617,2643,2645,2651,2654,2657,2673,2682,2684,2690,2697,2711,2714,2717,2719,2725,2732,2742,2763,2770,2773,2776,2779,2785,2795,2798,2800,2806,2820,2823,2841,2878,2881,2889,2896,2898,2904,2913,2916,2980,3000,3010,3013,3016,3026,3029,3039,3041,3047,3050,3057,3063,3066,3072,3081,3083,3089,3092,3095,3104,3106,3110,3113,3133,3136,3139,3152],[31,2574,2576,2580],{"className":2575},[34,35,36],[31,2577,2579],{"className":2578},[40],"⚡",[31,2581,2583],{"className":2582},[45],"Accélérez les revues d’animation grâce à des aperçus légers qui se rendent en quelques secondes, pas en heures.",[48,2585,2586],{},"Attendre des rendus pleine résolution juste pour évaluer un plan ralentit toute la production. Les artistes passent du temps à attendre et les superviseurs voient leurs retours différés. La boucle d’itération est inefficace.",[48,2588,2589],{},"Pour y remédier, nous pouvons créer des aperçus d’animation basse résolution directement dans Blender et les téléverser automatiquement sur Kitsu via Python dans le cadre de notre pipeline d’animation. Ces aperçus se rendent rapidement, sont faciles à examiner et peuvent être utilisés sans délai dans Kitsu pour validation.",[48,2591,2592],{},"C’est un gros avantage, car les rendus pleine résolution peuvent prendre des heures, et les coûts de stockage cloud et de bande passante réseau ne sont pas anodins quand vous gérez des milliers de plans. Passer de 1080p à 480p peut diviser la taille jusqu’à 5× !",[48,2594,2595],{},"Dans ce tutoriel, nous allons voir comment :",[212,2597,2598,2601,2604,2611],{},[215,2599,2600],{},"Configurer les réglages de rendu Blender pour des aperçus basse résolution",[215,2602,2603],{},"Automatiser le processus de rendu avec Python",[215,2605,2606,2607,2610],{},"Utiliser ",[155,2608,2609],{},"ffmpeg"," pour ajouter un filigrane et un horodatage à la vidéo afin de la contextualiser rapidement",[215,2612,2613],{},"Exporter les vidéos et les téléverser sur Kitsu",[48,2615,2616],{},"À la fin, vous disposerez d’un script qui fait gagner du temps sur les revues de plans sans sacrifier la qualité des retours.",[31,2618,2620,2623],{"className":2619},[34,35,108],[31,2621,112],{"className":2622},[40],[31,2624,2626,2630,2632,2634,2635,2637,134,2639],{"className":2625},[45],[117,2627,2628],{},[120,2629,1889],{"style":122},[125,2631],{},[125,2633],{},"Vous pouvez trouver le code source complet de l’intégration d’exemple présentée dans ce guide sur notre GitHub :",[125,2636],{},[125,2638],{},[94,2640,2642],{"href":2641},"https://github.com/cgwire/blender-kitsu-low-res-preview?ref=blog.cg-wire.com","https://github.com/cgwire/blender-kitsu-low-res-preview",[61,2644],{},[64,2646,2648],{"id":2647},"_1-simple-blender-scene-setup",[120,2649,2650],{},"1. Configuration simple de la scène Blender",[48,2652,2653],{},"Avant de pouvoir créer un aperçu animé, nous avons besoin d’un objet de départ dans la scène. Pour ce tutoriel, nous utiliserons le cube par défaut de Blender.",[48,2655,2656],{},"D’abord, nous créons une référence de la scène et du cube :",[152,2658,2659,2663],{},[155,2660,2662],{"className":2661},[175],"import bpy\n",[48,2664,2665],{},[155,2666,2668,2669,2672],{"className":2667},[175],"cube = bpy.data.objects",[262,2670,2671],{},"\"Cube\"","\nscene = bpy.context.scene",[72,2674,2676],{"className":2675},[34,75],[77,2677],{"src":2678,"className":2679,"alt":12,"loading":82,"width":83,"height":2680,"srcSet":2681,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png",[81],901,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png 1600w",[61,2683],{},[64,2685,2687],{"id":2686},"_2-adding-keyframes-for-animation",[120,2688,2689],{},"2. Ajouter des keyframes pour l’animation",[48,2691,2692,2693,2696],{},"La prochaine étape consiste à animer notre cube. Pour des aperçus rapides de modélisation, des séquences courtes sont idéales. Ici, nous allons créer une ",[120,2694,2695],{},"rotation de 360°"," sur 48 frames (2 secondes à 24 FPS) :",[152,2698,2699],{},[155,2700,2702,2703,2706,2707,2710],{"className":2701},[175],"for frame, angle in ",[262,2704,2705],{},"(1, 0), (12, 1.57), (24, 3.14), (36, 4.71), (48, 6.28)",":\n    scene.frame_set(frame)\n    cube.rotation_euler",[262,2708,2709],{},"2"," = angle\n    cube.keyframe_insert(data_path=\"rotation_euler\", index=2)",[48,2712,2713],{},"Cette boucle place des keyframes à intervalles réguliers, en faisant tourner le cube en douceur autour de son axe Z par incréments de pi/2. Utiliser un nombre limité de frames permet de garder le rendu rapide et rend le résultat parfait pour un usage d’aperçu.",[48,2715,2716],{},"À ce stade, vous pouvez parcourir la timeline dans Blender pour vérifier que le cube tourne comme prévu.",[61,2718],{},[64,2720,2722],{"id":2721},"_3-low-resolution-rendering",[120,2723,2724],{},"3. Rendu basse résolution",[48,2726,2727,2728,2731],{},"Une fois l’animation en place, nous pouvons configurer Blender pour rendre un ",[120,2729,2730],{},"aperçu rapide en basse résolution",". L’objectif est la vitesse plutôt que la qualité : nous voulons quelque chose d’assez clair pour être évalué, mais rapide à produire.",[48,2733,2734,2735,2741],{},"Ici, nous utilisons",[94,2736,1917,2738],{"href":2737},"https://blog.cg-wire.com/getting-started-with-blender-rendering/",[1919,2739,2740],{},"le moteur de rendu Eevee pour gagner en vitesse et réduire la surcharge de rendu inutile",". Il est beaucoup plus rapide que Cycles, car c’est un moteur de rasterisation simple, et dans 90 % des cas, nous n’avons pas besoin d’un rendu hyper réaliste.",[152,2743,2744,2757],{},[155,2745,2747,2748,2751,2754],{"className":2746},[175],"scene.render.engine = \"BLENDER_EEVEE\"",[48,2749,2750],{},"scene.render.resolution_x = 1920\nscene.render.resolution_y = 1080\nscene.render.resolution_percentage = 50",[48,2752,2753],{},"scene.render.fps = 24\nscene.frame_start = 1\nscene.frame_end = 48  # match your animation length",[48,2755,2756],{},"scene.render.image_settings.file_format = \"FFMPEG\"\nscene.render.ffmpeg.format = \"MPEG4\"\nscene.render.ffmpeg.codec = \"H264\"",[48,2758,2759],{},[155,2760,2762],{"className":2761},[175],"scene.render.filepath = \"//preview.mp4\"",[48,2764,2765,2766,2769],{},"Bien que nous partions d’une résolution classique en paysage, réduire ",[155,2767,2768],{},"resolution_percentage"," ou désactiver l’échantillonnage de haute qualité dans Eevee peut diminuer drastiquement les temps de rendu pour les aperçus.",[48,2771,2772],{},"Le reste des réglages est assez standard : 24 images par seconde, 48 frames au total, et une vidéo de sortie en mp4 avec encodage H264 (pour une compression plus rapide) écrite dans le dossier courant du script.",[48,2774,2775],{},"Selon votre cas d’usage, vous pouvez réduire la résolution, diminuer le taux de rafraîchissement et abaisser le débit (bitrate) pour réduire la taille de vos aperçus. Il faut toutefois garder une qualité suffisante pour le processus de revue, donc ajustez les réglages pour obtenir un équilibre optimal avec les performances.",[48,2777,2778],{},"Enfin, nous pouvons lancer le rendu en une seule ligne :",[152,2780,2781],{},[155,2782,2784],{"className":2783},[175],"bpy.ops.render.render(animation=True)",[72,2786,2788],{"className":2787},[34,75],[77,2789],{"src":2790,"className":2791,"alt":12,"loading":82,"width":2792,"height":2793,"srcSet":2794,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png",[81],1088,722,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png 1088w",[48,2796,2797],{},"La vidéo d’aperçu peut être utilisée immédiatement pour la revue, ou traitée davantage avec des outils comme FFmpeg pour les horodatages, les filigranes ou des conventions de nommage personnalisées avant téléversement sur Kitsu.",[61,2799],{},[64,2801,2803],{"id":2802},"_4-ffmpeg-processing-timestamp-naming-watermark",[120,2804,2805],{},"4. Traitement avec FFmpeg : horodatage, nommage, filigrane",[48,2807,2808,2809,2812,2813,2819],{},"Une fois que Blender a rendu votre animation dans un fichier vidéo, vous pouvez la traiter davantage avec ",[120,2810,2811],{},"FFmpeg",". C’est",[94,2814,1917,2816],{"href":2815},"https://blog.cg-wire.com/ffmpeg-commands-for-animators/",[1919,2817,2818],{},"une étape courante dans les pipelines de production"," pour ajouter des horodatages, des filigranes ou un nommage personnalisé, afin de préparer les aperçus pour la revue.",[48,2821,2822],{},"Lancez la commande suivante dans un terminal après avoir rendu votre aperçu :",[152,2824,2825],{},[155,2826,2828,2829,2832,2833,2836,2837,2840],{"className":2827},[158],"ffmpeg -framerate 24 \\\\\n  -i preview.mp4 \\\\\n  -i watermark.png \\\\\n  -filter_complex \"\\\\\n    ",[262,2830,2831],{},"0:v","drawtext=text='%{pts\\\\:hms}':x=10:y=10:fontsize=24:fontcolor=white:bordercolor=black:borderw=2",[262,2834,2835],{},"v1","; \\\\\n    [v1]",[262,2838,2839],{},"1:v","overlay=W-w-20:H-h-20\" \\\\\n  -c:v libx264 -crf 22 -pix_fmt yuv420p \\\\\n  preview_with_stamp.mp4",[212,2842,2843,2851,2863,2871],{},[215,2844,2845,2850],{},[120,2846,2847],{},[155,2848,2849],{},"drawtext"," superpose un horodatage en cours dans le coin supérieur gauche.",[215,2852,2853,2858,2859,2862],{},[155,2854,2855],{},[120,2856,2857],{},"overlay"," place une image de filigrane (",[155,2860,2861],{},"watermark.png",") dans le coin inférieur droit.",[215,2864,2865,2870],{},[120,2866,2867],{},[155,2868,2869],{},"c:v libx264 -crf 22 -pix_fmt yuv420p"," garantit une bonne qualité et une compatibilité étendue pour la lecture vidéo.",[215,2872,2873,2874,2877],{},"Le fichier de sortie, ",[155,2875,2876],{},"preview_with_stamp.mp4",", est votre aperçu finalisé prêt pour la revue.",[48,2879,2880],{},"Bien sûr, vous pouvez ajuster la taille de la police, la position ou le placement du filigrane selon vos besoins pour standardiser les aperçus pour vos revues d’équipe ou clients.",[72,2882,2884],{"className":2883},[34,75],[77,2885],{"src":2886,"className":2887,"alt":12,"loading":82,"width":2792,"height":2793,"srcSet":2888,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png 1088w",[48,2890,2891,2892,2895],{},"Cette étape termine la préparation d’un aperçu d’animation basse résolution prêt pour la production. Le fichier est maintenant prêt à être téléversé sur ",[120,2893,2894],{},"Kitsu"," pour un retour rapide.",[61,2897],{},[64,2899,2901],{"id":2900},"_5-uploading-to-kitsu-via-gazu",[120,2902,2903],{},"5. Téléverser sur Kitsu via Gazu",[48,2905,2906,2907,2909,2910,2912],{},"Une fois votre aperçu basse résolution prêt, vous pouvez le téléverser directement sur ",[120,2908,2894],{}," via le tableau de bord ou utiliser le SDK Python ",[155,2911,165],{},". Kitsu est un outil collaboratif de suivi de pipeline qui permet aux artistes et aux superviseurs d’accéder à l’aperçu immédiatement pour la revue.",[48,2914,2915],{},"Le script Python suivant fournit une CLI interactive simple qui vous permet de choisir le projet et la tâche vers lesquels téléverser votre aperçu :",[152,2917,2918,2974],{},[155,2919,2921,2922,2931,2945,2958,2965,2968,2971],{"className":2920},[175],"import gazu",[48,2923,2924,2925,2927,2928],{},"def pickProject(label, list_of_items):\n    \"\"\"Helper UI to pick one item from a list.\"\"\"\n    for i, item in enumerate(list_of_items):\n        print(f\"{i + 1}. {item",[262,2926,2437],{},"}\")\n    idx = int(input(f\"Choose {label} number: \")) - 1\n    return list_of_items",[262,2929,2930],{},"idx",[48,2932,2933,2934,2937,2938,2941,2942,1330],{},"def pickTask(label, list_of_items):\n    \"\"\"Helper UI to pick one item from a list.\"\"\"\n    for i, item in enumerate(list_of_items):\n        asset = gazu.entity.get_entity(item",[262,2935,2936],{},"\"entity_id\"",")\n        status = gazu.task.get_task_status(item",[262,2939,2940],{},"\"task_status_id\"",")\n        type = gazu.task.get_task_type(item",[262,2943,2944],{},"\"task_type_id\"",[48,2946,2947,2948,2950,2951,2953,2954,2927,2956],{},"        print(f\"{i + 1}. {asset",[262,2949,2437],{},"} {type",[262,2952,2437],{},"} {status",[262,2955,2437],{},[262,2957,2930],{},[48,2959,2015,2960,2019,2963,863],{},[94,2961,185],{"href":185,"rel":2962},[187],[94,2964,192],{"href":191},[48,2966,2967],{},"projects = gazu.project.all_projects()\nproject = pickProject(\"project\", projects)",[48,2969,2970],{},"tasks = gazu.task.all_tasks_for_project(project)\ntask = pickTask(\"task\", tasks)",[48,2972,2973],{},"print(\"Uploading preview...\")\ntask_status = gazu.task.get_task_status_by_name(\"todo\")\nresult = gazu.task.publish_preview(\n    task,\n    task_status,\n    comment=\"Auto-generated preview\",\n    preview_file_path=\"./preview.mp4\",\n)",[48,2975,2976],{},[155,2977,2979],{"className":2978},[175],"print(\"Done:\", result)",[48,2981,2982,2983,2985,2986,2991,2992,2995,2996,2999],{},"D’abord, nous nous connectons à Kitsu via ",[155,2984,165],{}," avec vos identifiants. Nous utilisons le",[94,2987,1917,2988],{"href":782},[1919,2989,2990],{},"mode d’installation pour le développement local via Kitsu Docker",". Le programme vous permet de sélectionner le ",[120,2993,2994],{},"projet"," et la ",[120,2997,2998],{},"tâche"," parmi les options disponibles à l’aide de différents endpoints de l’API Kitsu afin d’obtenir toutes vos données de production :",[72,3001,3003],{"className":3002},[34,75],[77,3004],{"src":3005,"className":3006,"alt":12,"loading":82,"width":3007,"height":3008,"srcSet":3009,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png",[81],1343,816,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png 1343w",[48,3011,3012],{},"Ensuite, nous téléversons la vidéo d’aperçu générée des étapes précédentes vers la tâche sélectionnée.",[48,3014,3015],{},"Une fois terminé, l’aperçu est disponible dans l’interface de revue de Kitsu, ce qui permet aux membres de l’équipe et aux superviseurs de donner leur avis sans attendre des rendus pleine résolution.",[72,3017,3019],{"className":3018},[34,75],[77,3020],{"src":3021,"className":3022,"alt":12,"loading":82,"width":3023,"height":3024,"srcSet":3025,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-78d2cd48-21e9-4599-9b2b-a5e5bef63f76.png",[81],985,948,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-78d2cd48-21e9-4599-9b2b-a5e5bef63f76.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-78d2cd48-21e9-4599-9b2b-a5e5bef63f76.png 985w",[48,3027,3028],{},"Moteur de revue parfait pour annoter rapidement les images et ajouter des commentaires sur des plans précis :",[72,3030,3032],{"className":3031},[34,75],[77,3033],{"src":3034,"className":3035,"alt":12,"loading":82,"width":3036,"height":3037,"srcSet":3038,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png",[81],1438,809,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png 1438w",[61,3040],{},[64,3042,3044],{"id":3043},"_6-putting-it-all-together",[120,3045,3046],{},"6. Tout assembler",[48,3048,3049],{},"Pour automatiser la tâche de bout en bout, écrivons une commande bash rapide :",[48,3051,3052],{},[120,3053,3054],{},[1919,3055,3056],{},"preview.sh",[152,3058,3059],{},[155,3060,3062],{"className":3061},[175],"python3 render.py && ./watermark.sh && python3 upload.py",[48,3064,3065],{},"Ensuite, nous pouvons exécuter le script chaque fois que nous devons partager un aperçu :",[152,3067,3068],{},[155,3069,3071],{"className":3070},[175],"./preview.sh",[48,3073,3074,3075,3080],{},"Jetez un œil à notre",[94,3076,1917,3077],{"href":2641},[1919,3078,3079],{},"dépôt Github blender-kitsu-low-res-preview"," pour tester le résultat final par vous-même.",[61,3082],{},[64,3084,3086],{"id":3085},"_7-artist-friendly-addon-overview",[120,3087,3088],{},"7. Aperçu de l’addon pensé pour les artistes",[48,3090,3091],{},"Bien que cela sorte du cadre de cet article, il pourrait être simple d’envelopper notre code dans un addon Blender afin que les artistes puissent l’utiliser facilement.",[48,3093,3094],{},"Vous auriez besoin d’un panneau principal pour contenir des menus déroulants afin de choisir une production, un asset et une tâche à téléverser. Et d’un bouton à cliquer pour téléverser. La logique de téléversement prendrait en charge le rendu, l’appel à ffmpeg en tant que sous-processus pour le filigrane, et l’envoi des fichiers temporaires vers Kitsu.",[48,3096,3097,3098,3103],{},"Consultez notre article sur",[94,3099,1917,3100],{"href":2300},[1919,3101,3102],{},"le développement d’interface pour un add-on Blender"," pour plus d’informations.",[61,3105],{},[64,3107,3108],{"id":507},[120,3109,508],{},[48,3111,3112],{},"D’ici là, vous aurez mis en place un pipeline complet : créer un objet 3D simple dans Blender, l’animer, générer un aperçu basse résolution, ajouter des horodatages et des filigranes, puis le téléverser sur Kitsu. Les bénéfices sont immédiats :",[212,3114,3115,3121,3127],{},[215,3116,3117,3120],{},[120,3118,3119],{},"Des revues plus rapides"," - Les superviseurs et les membres de l’équipe peuvent regarder les aperçus immédiatement sans attendre des rendus pleine résolution.",[215,3122,3123,3126],{},[120,3124,3125],{},"Des itérations plus rapides"," - Les artistes reçoivent des retours plus tôt, ce qui raccourcit la boucle d’itération et réduit les goulots d’étranglement.",[215,3128,3129,3132],{},[120,3130,3131],{},"Moins de blocages"," - Les aperçus et téléversements automatisés éliminent les étapes manuelles répétitives du pipeline pour garantir des livrables cohérents.",[48,3134,3135],{},"Ce qui prenait autrefois une heure de travail manuel peut désormais être géré avec quelques scripts, offrant à l’équipe plus de temps pour se concentrer sur le côté créatif de la production plutôt que sur des tâches répétitives.",[48,3137,3138],{},"Vous pouvez aller encore plus loin avec ce workflow selon les besoins de votre studio d’animation : ajouter des boutons ou des panneaux dans Blender pour exécuter l’intégralité du pipeline en un clic, générer automatiquement des aperçus par lot pour plusieurs plans ou scènes dans un seul script, etc.",[31,3140,3142,3145],{"className":3141},[34,35,36],[31,3143,524],{"className":3144},[40],[31,3146,528,3148,3151],{"className":3147},[45],[94,3149,534],{"href":531,"rel":3150},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent les meilleures pratiques et organisent occasionnellement des événements en personne. Nous serions ravis de vous accueillir ! 😊",[31,3153,3155],{"className":3154},[34,539,540],[94,3156,1797],{"href":531,"className":3157},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":3159},[3160,3161,3162,3163,3164,3165,3166,3167],{"id":2647,"depth":548,"text":2650},{"id":2686,"depth":548,"text":2689},{"id":2721,"depth":548,"text":2724},{"id":2802,"depth":548,"text":2805},{"id":2900,"depth":548,"text":2903},{"id":3043,"depth":548,"text":3046},{"id":3085,"depth":548,"text":3088},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1653200256306-6dc84510dfb6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fGFuaW1hdGlvbiUyMHBpcGVsaW5lfGVufDB8fHx8MTc2NTA5ODQ2Mnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":3170,"featured_at":561,"visibility":562},"2026-02-20T06:04:01.000+01:00","/blog-i18n/fr/blender-kitsu-low-res-preview","2025-12-15T10:00:23.000+01:00",{"title":2568,"description":12},"blender-kitsu-low-res-preview","blog-i18n/fr/blender-kitsu-low-res-preview/index",[3177,3178],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"170wyq20d2qJm0mUN-v6ZZuSEjvoz5Zwl_GvM3o48fA",{"id":3181,"title":3182,"authors":3183,"body":3185,"description":12,"extension":557,"feature_image":3866,"html":7,"meta":3867,"navigation":13,"path":3868,"published_at":3869,"seo":3870,"slug":3871,"stem":3872,"tags":3873,"__hash__":3876,"updated_at":3170,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-kitsu-versioning-addon/index.md","Gérer les révisions de fichiers Blender avec un addon de versioning Kitsu (2026)",[3184],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":3186,"toc":3857},[3187,3198,3205,3208,3213,3216,3219,3222,3225,3228,3230,3236,3239,3242,3268,3271,3296,3298,3304,3312,3336,3345,3348,3351,3381,3391,3394,3397,3400,3402,3408,3414,3434,3443,3450,3453,3456,3472,3475,3478,3493,3500,3514,3517,3559,3562,3568,3571,3573,3579,3582,3589,3607,3610,3613,3646,3648,3654,3661,3664,3667,3684,3687,3690,3715,3718,3720,3726,3733,3750,3780,3783,3804,3807,3817,3819,3823,3826,3829,3838,3851],[31,3188,3190,3194],{"className":3189},[34,35,36],[31,3191,3193],{"className":3192},[40],"🧱",[31,3195,3197],{"className":3196},[45],"Remplacez une nomenclature chaotique par une source unique de vérité pour les révisions Blender.",[48,3199,3200,3201,3204],{},"Chaque projet commence avec de bonnes intentions. Vous démarrez avec un ",[155,3202,3203],{},"model.blend"," bien propre, des dossiers organisés, et la promesse que, cette fois, vous garderez tout bien rangé.",[48,3206,3207],{},"Mais quand les délais se resserrent, la tranquille entropie de la production s’installe. Très vite, votre dossier de projet commence à ressembler à un site de fouilles archéologiques d’ultimes modifications prises dans la panique :",[152,3209,3210],{},[155,3211,3212],{},"model.blend\nmodel_v2.blend\nmodel_v2b.blend\nmodel_final.blend\nmodel_final_really_final.blend\nmodel_FINAL_v3.blend",[48,3214,3215],{},"Vous savez comment ça se passe : quelqu’un a besoin d’un changement rapide, un autre artiste part sur une version « juste au cas où », et bientôt plus personne n’est vraiment sûr de savoir quel fichier est « le vrai ». Les commentaires dans les fils de discussion contredisent les noms de fichiers, des rendus de plans sortent à partir de versions obsolètes, et le superviseur soupire profondément.",[48,3217,3218],{},"Dans un studio d’animation, ces micro-instants de chaos s’accumulent. C’est là qu’une source de vérité adaptée doit entrer en scène.",[48,3220,3221],{},"Pour beaucoup d’équipes, cette source, c’est Kitsu. Et pour les artistes Blender, la pièce manquante est un pont automatisé qui conserve les fichiers versionnés, traçables et alignés avec les données de production du projet.",[48,3223,3224],{},"Alors vous décidez de reprendre le contrôle : vous allez faire parler Blender avec Kitsu et construire un système de versioning qui donne à votre pipeline l’impression, enfin, d’avoir votre dos.",[48,3226,3227],{},"Dans ce tutoriel, nous allons créer un addon qui gère les révisions de fichiers directement depuis Blender. Vous pourrez connecter Blender à un projet Kitsu, créer et téléverser des révisions de vos modèles 3D, consulter toutes les révisions existantes, et ramener d’anciennes révisions dans Blender.",[61,3229],{},[64,3231,3233],{"id":3232},"workflow-overview",[120,3234,3235],{},"Aperçu du workflow",[48,3237,3238],{},"Dans un workflow typique piloté par Kitsu, un artiste ouvre une scène Blender, fait son travail, atteint une étape (milestone) et téléverse une révision. Les artistes consultent, itèrent, révisent et téléversent à nouveau. Kitsu garde chaque étape bien rangée.",[48,3240,3241],{},"Mais ça ne ferait pas de mal de pouvoir simplement téléverser ou ramener des révisions d’un clic, non ?",[1692,3243,3244,3250,3256,3262],{},[215,3245,3246,3249],{},[120,3247,3248],{},"Démarrer dans Blender"," - Nous ouvrons notre scène de travail : modélisation, shading, rigging, bref, tout ce que la tâche exige.",[215,3251,3252,3255],{},[120,3253,3254],{},"Créer un point de contrôle"," - Quand on atteint une étape (« blocking terminé », « prêt pour la relecture »), on crée une nouvelle révision dans Kitsu.",[215,3257,3258,3261],{},[120,3259,3260],{},"Consulter l’historique"," - Kitsu stocke toutes les révisions, ce qui donne aux superviseurs une chronologie claire et vous permet de comparer des versions sans fouiller dans les fichiers.",[215,3263,3264,3267],{},[120,3265,3266],{},"Ramener de nouveaux changements"," - Quand nous avons besoin d’une version différente, il suffit de cliquer pour ramener un asset dans notre espace de travail actuel.",[48,3269,3270],{},"C’est un workflow très basique, donc nous risquons de rencontrer des problèmes comme la façon de gérer la résolution de conflits (et si deux artistes travaillent sur le même plan et créent chacun une nouvelle révision, comment gère-t-on cela ?), mais c’est suffisant pour nous donner un addon fonctionnel que nous pourrons améliorer plus tard pour répondre aux besoins du pipeline d’animation.",[31,3272,3274,3277],{"className":3273},[34,35,108],[31,3275,112],{"className":3276},[40],[31,3278,3280,3284,3286,129,3288,3290,134,3292],{"className":3279},[45],[117,3281,3282],{},[120,3283,123],{"style":122},[125,3285],{},[125,3287],{},[125,3289],{},[125,3291],{},[94,3293,3295],{"href":3294},"https://github.com/cgwire/blender-kitsu-versioning-addon?ref=blog.cg-wire.com","https://github.com/cgwire/blender-kitsu-versioning-addon",[61,3297],{},[64,3299,3301],{"id":3300},"_1-populating-the-kitsu-dashboard",[120,3302,3303],{},"1. Renseigner le tableau de bord Kitsu",[48,3305,3306,3307,1654],{},"L’interface web de Kitsu est conçue pour que les producteurs, coordinateurs ou leads puissent rapidement mettre en place la structure d’un projet. Avant que les artistes Blender puissent publier des révisions, nous devons alimenter notre production avec des assets en cours. Dans",[94,3308,1917,3309],{"href":782},[1919,3310,3311],{},"l’instance Docker Kitsu pour le développement local",[1692,3313,3314,3320,3326,3333],{},[215,3315,3316,3317,166],{},"Connectez-vous au ",[120,3318,3319],{},"tableau de bord Kitsu",[215,3321,3322,3323,166],{},"Dans la barre de navigation principale, allez dans ",[120,3324,3325],{},"Productions",[215,3327,3328,3329,3332],{},"Cliquez sur ",[120,3330,3331],{},"\"Create production\""," (généralement le coin supérieur droit).",[215,3334,3335],{},"Renseignez les détails de la production",[72,3337,3339],{"className":3338},[34,75],[77,3340],{"src":3341,"className":3342,"alt":12,"loading":82,"width":3023,"height":3343,"srcSet":3344,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-58cb0571-2b74-4110-9b07-9e15030bbd05.png",[81],694,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-58cb0571-2b74-4110-9b07-9e15030bbd05.png 600w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-58cb0571-2b74-4110-9b07-9e15030bbd05.png 985w",[48,3346,3347],{},"La nouvelle production apparaît dans la liste, et vous pouvez l’ouvrir pour commencer à ajouter des assets.",[48,3349,3350],{},"Les assets sont les éléments de base de votre projet : personnages, props, environnements, véhicules… tout ce qui doit être tracé dans la production.",[1692,3352,3353,3359,3365,3370],{},[215,3354,3355,3356,166],{},"Allez dans ",[120,3357,3358],{},"Productions → le nom de votre production",[215,3360,3361,3362,3364],{},"Ouvrez l’onglet ",[120,3363,667],{}," à l’intérieur de la production.",[215,3366,3328,3367,166],{},[120,3368,3369],{},"\"Create Asset\"",[215,3371,3372,3373,3376,3377,3380],{},"Renseignez un ",[120,3374,3375],{},"Asset Name"," (par ex. « RobotHead ») et un ",[120,3378,3379],{},"Asset Type"," (Character, Prop, Set, etc.)",[72,3382,3384],{"className":3383},[34,75],[77,3385],{"src":3386,"className":3387,"alt":12,"loading":82,"width":3388,"height":3389,"srcSet":3390,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png",[81],1270,870,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png 1270w",[48,3392,3393],{},"Votre asset existe désormais et possède 3 tâches qui lui sont assignées. ",[48,3395,3396],{},"Les tâches définissent les étapes du workflow (Modélisation, Shading, Rigging, etc.) que les artistes effectueront sur chaque asset.",[48,3398,3399],{},"Nous avons maintenant tout ce qu’il faut pour tester notre addon.",[61,3401],{},[64,3403,3405],{"id":3404},"_2-linking-the-current-blender-project-to-a-kitsu-task",[120,3406,3407],{},"2. Lier le projet Blender actuel à une tâche Kitsu",[48,3409,3410,3411,3413],{},"Nous commençons par une déclaration d’addon minimale qui définit l’emplacement de l’interface, charge ",[155,3412,165],{},", et prépare les données que nous exposerons dans les menus déroulants :",[152,3415,3416,3428],{},[155,3417,3419,3420,3423,3425],{"className":3418},[175],"bl_info = {\n    \"name\": \"Model Versioning (Production/Task/Asset/Revisions)\",\n    \"author\": \"cgwire\",\n    \"version\": (1, 0, 0),\n    \"blender\": (2, 80, 0),\n    \"location\": \"View3D > Sidebar > ModelVersioning\",\n    \"description\": \"Browse productions, tasks, assets, and manage revisions (list/create/load)\",\n     \"category\": \"3D View\",\n}\n",[48,3421,3422],{},"import sys",[48,3424,2315],{},[48,3426,3427],{},"import os\nimport tempfile",[48,3429,3430],{},[155,3431,3433],{"className":3432},[175],"import bpy\nimport gazu\nfrom bpy.props import EnumProperty, PointerProperty\nfrom bpy.types import Operator, Panel, PropertyGroup",[48,3435,3436,3437,3439,3440,3442],{},"Notez que ",[155,3438,2315],{}," nous permet d’utiliser notre installation Python locale pour accéder à des packages externes comme ",[155,3441,165],{},". Par défaut, Blender exécute sa propre installation Python, donc installer des packages peut être fastidieux. Pour résoudre ce problème, on indique simplement à Blender d’aller regarder nos modules locaux. Mettez ce chemin à jour pour qu’il corresponde à la configuration de votre système.",[48,3444,3445,3446,3449],{},"Avant de pouvoir automatiser le versioning, Blender doit savoir ",[652,3447,3448],{},"où"," dans Kitsu appartient le modèle actuel. Cela signifie d’identifier le projet, l’asset, la tâche, et finalement les révisions qui y sont associées.",[48,3451,3452],{},"La première étape est simple : s’authentifier auprès de Kitsu, récupérer les productions disponibles, et laisser l’artiste choisir le contexte directement depuis l’interface de la Sidebar.",[48,3454,3455],{},"Une fois l’addon chargé, on s’authentifie et on pointe l’addon vers l’hôte de l’API Kitsu :",[152,3457,3458,3466],{},[155,3459,2015,3461,2019,3464,863],{"className":3460},[175],[94,3462,185],{"href":185,"rel":3463},[187],[94,3465,192],{"href":191},[48,3467,3468],{},[155,3469,3471],{"className":3470},[175],"temp_dir_path = tempfile.gettempdir()",[48,3473,3474],{},"Cela établit la session que nous utiliserons pour parcourir les productions, trouver des tâches, et finalement créer des révisions.",[48,3476,3477],{},"À partir de là, nous pouvons commencer à exposer la structure de la production. Avec des fonctions d’assistance pour la recherche de projet, d’asset, de tâche et de révision, nous remplissons chaque menu déroulant de manière dynamique :",[152,3479,3480,3487],{},[155,3481,3483,3484],{"className":3482},[175],"def find_project(name):\n    return gazu.project.get_project_by_name(name)",[48,3485,3486],{},"def find_asset(project, name):\n    return gazu.asset.get_asset_by_name(project, name)",[48,3488,3489],{},[155,3490,3492],{"className":3491},[175],"def find_task(asset, type_id):\n    return gazu.task.get_task_by_name(asset, type_id, \"main\")",[48,3494,3495,3496,3499],{},"Chaque rappel de ",[155,3497,3498],{},"EnumProperty"," récupère des données fraîches depuis Kitsu :",[152,3501,3502],{},[155,3503,3505,3506,3508,3509,2328,3511,3513],{"className":3504},[175],"def enum_projects(self, context):\n    items = ",[262,3507],{},"\n    projects = gazu.project.all_projects()\n    for p in projects:\n        items.append((p",[262,3510,2331],{},[262,3512,2331],{},", \"\"))\n    if not items:\n        items.append((\"NONE\", \"--- no productions ---\", \"\"))\n    return items",[48,3515,3516],{},"Les assets, tâches et révisions suivent le même schéma :",[152,3518,3519,3543],{},[155,3520,3522,3523,3525,3526,3528,3529,3531,3532],{"className":3521},[175],"def enum_assets(self, context):\n    project = find_project(context.scene.mv_state.project)\n    items = ",[262,3524],{},"\n    if project:\n        assets = gazu.asset.all_assets_for_project(project)\n        for t in assets:\n            items.append((t",[262,3527,2331],{},", t",[262,3530,2331],{},", \"\"))\n    if not items:\n        items.append((\"NONE\", \"--- no tasks ---\", \"\"))\n    return items",[48,3533,3534,3535,3537,3538,3528,3540,3531],{},"def enum_tasks(self, context):\n    project = find_project(context.scene.mv_state.project)\n    asset = find_asset(project, context.scene.mv_state.asset)\n    items = ",[262,3536],{},"\n    if asset:\n        tasks = gazu.task.all_tasks_for_asset(asset)\n        for t in tasks:\n            items.append((t",[262,3539,2944],{},[262,3541,3542],{},"\"task_type_name\"",[48,3544,3545],{},[155,3546,3548,3549,3551,3552,3555,3556,3558],{"className":3547},[175],"def enum_revisions(self, context):\n    project = find_project(context.scene.mv_state.project)\n    asset = find_asset(project, context.scene.mv_state.asset)\n    task = find_task(asset, context.scene.mv_state.task)\n    items = ",[262,3550],{},"\n    if task:\n        revisions = gazu.files.get_all_preview_files_for_task(task)\n        for r in revisions:\n            items.append((str(r",[262,3553,3554],{},"\"revision\"","), str(r",[262,3557,3554],{},"), \"\"))\n    if not items:\n        items.append((\"NONE\", \"--- no revisions ---\", \"\"))\n    return items",[48,3560,3561],{},"Enfin, nous stockons toutes les sélections de l’interface dans un unique objet d’état :",[152,3563,3564],{},[155,3565,3567],{"className":3566},[175],"class MV_State(PropertyGroup):\n    project: EnumProperty(\n        name=\"Project\", description=\"Select project\", items=enum_projects\n    )\n    asset: EnumProperty(name=\"Asset\", description=\"Select asset\", items=enum_assets)\n    task: EnumProperty(name=\"Task\", description=\"Select task\", items=enum_tasks)\n    revision: EnumProperty(\n        name=\"Revision\", description=\"Select revision\", items=enum_revisions\n     )",[48,3569,3570],{},"Voici la base de notre intégration au pipeline : Blender sait maintenant parcourir Kitsu et se lier à la tâche exacte sur laquelle l’artiste travaille. À partir de là, nous pouvons commencer à travailler sur le cycle de vie des révisions.",[61,3572],{},[64,3574,3576],{"id":3575},"_3-creating-a-new-revision-button",[120,3577,3578],{},"3. Créer un bouton « Nouvelle révision »",[48,3580,3581],{},"Nous pouvons commencer à automatiser la partie avec laquelle les artistes interagissent le plus : la création de nouvelles révisions. Dans un workflow manuel classique, vous exportez votre fichier puis vous le téléversez dans Kitsu sur la tâche correcte. Notre addon simplifie tout cela en une seule pression de bouton à l’intérieur de Blender.",[48,3583,3584,3585,3588],{},"Kitsu gère les nouvelles révisions via ",[155,3586,3587],{},"publish_preview()",". Cet appel envoie à la fois le fichier et les métadonnées :",[152,3590,3591,3601],{},[155,3592,3594,3595,3598],{"className":3593},[175],"temp_file_path = os.path.join(temp_dir_path, \"new_version.glb\")",[48,3596,3597],{},"bpy.ops.export_scene.gltf(filepath=temp_file_path, export_format=\"GLB\")",[48,3599,3600],{},"(comment, preview_file) = gazu.task.publish_preview(\n    task,\n    task_status,\n    revision=new_revision,\n    comment=\"increment revision\",\n    preview_file_path=temp_file_path,\n)",[48,3602,3603],{},[155,3604,3606],{"className":3605},[175],"os.remove(temp_file_path)",[48,3608,3609],{},"Dans notre addon, on déclenchera cela depuis un bouton dans la Sidebar.",[48,3611,3612],{},"L’opérateur effectue trois étapes principales : récupérer les sélections de l’utilisateur depuis l’état de l’addon, calculer le prochain numéro de révision, puis téléverser le fichier exporté comme nouvelle révision :",[152,3614,3615,3640],{},[155,3616,3618,3619,3622,3625,3628,3631,3634,3637],{"className":3617},[175],"class MV_OT_create_revision(Operator):\n    bl_idname = \"mv.create_revision\"\n    bl_label = \"Create Revision\"",[48,3620,3621],{},"    def invoke(self, context, event):\n        wm = context.window_manager\n        return wm.invoke_props_dialog(self, width=400)",[48,3623,3624],{},"    def execute(self, context):\n        project = find_project(context.scene.mv_state.project)\n        asset = find_asset(project, context.scene.mv_state.asset)\n         task = find_task(asset, context.scene.mv_state.task)\n         revision = context.scene.mv_state.revision\n         new_revision = int(revision) + 1",[48,3626,3627],{},"        task_status = gazu.task.get_task_status_by_name(\"todo\")",[48,3629,3630],{},"        temp_file_path = os.path.join(temp_dir_path, \"new_version.glb\")",[48,3632,3633],{},"        bpy.ops.export_scene.gltf(filepath=temp_file_path, export_format=\"GLB\")",[48,3635,3636],{},"        (comment, preview_file) = gazu.task.publish_preview(\n            task,\n            task_status,\n            revision=new_revision,\n            comment=\"increment revision\",\n            preview_file_path=temp_file_path,\n        )",[48,3638,3639],{},"        os.remove(temp_file_path)",[48,3641,3642],{},[155,3643,3645],{"className":3644},[175],"        self.report({\"INFO\"}, \"Revision created\")\n        return {\"FINISHED\"}",[61,3647],{},[64,3649,3651],{"id":3650},"_4-pulling-a-revision-into-blender",[120,3652,3653],{},"4. Importer une révision dans Blender",[48,3655,3656,3657,3660],{},"Le versioning n’est pas seulement une question de publication de votre travail : il s’agit aussi de pouvoir ",[652,3658,3659],{},"revenir en arrière",". Que vous révisiez des étapes précédentes, compariez la topologie, ou récupériez un détail depuis une itération antérieure, vous avez besoin d’un moyen rapide et fiable pour charger de nouvelles révisions et d’anciennes révisions dans Blender.",[48,3662,3663],{},"Une fois qu’une tâche est sélectionnée, importer une révision depuis Kitsu devient une opération simple en deux étapes : télécharger le fichier d’aperçu associé à la révision sélectionnée, puis l’importer dans Blender.",[48,3665,3666],{},"Après avoir récupéré tous les fichiers d’aperçu pour la tâche en cours, nous pouvons cibler la révision via son index et apporter l’asset directement dans Blender :",[152,3668,3669,3679],{},[155,3670,3594,3672],{"className":3671},[175],[48,3673,3674,3675,3678],{},"preview_file = preview_files",[262,3676,3677],{},"int(revision) - 1","\ngazu.files.download_preview_file(preview_file, temp_file_path)\nbpy.ops.import_scene.gltf(filepath=temp_file_path)",[48,3680,3681],{},[155,3682,3606],{"className":3683},[175],[48,3685,3686],{},"Cela nous donne une façon cohérente de récupérer les assets tels qu’ils étaient exactement à ce moment de la production.",[48,3688,3689],{},"Nous encapsulons ce workflow dans un opérateur qui reproduit la structure du bouton « Create Revision » :",[152,3691,3692,3709],{},[155,3693,3695,3696,3699,3701,3707],{"className":3694},[175],"class MV_OT_load_revision(Operator):\n    bl_idname = \"mv.load_revision\"\n    bl_label = \"Load Revision\"",[48,3697,3698],{},"    def execute(self, context):\n        project = find_project(context.scene.mv_state.project)\n        asset = find_asset(project, context.scene.mv_state.asset)\n        task = find_task(asset, context.scene.mv_state.task)\n        revision = context.scene.mv_state.revision\n        preview_files = gazu.files.get_all_preview_files_for_task(task)",[48,3700,3630],{},[48,3702,3703,3704,3706],{},"        preview_file = preview_files",[262,3705,3677],{},"\n        gazu.files.download_preview_file(preview_file, temp_file_path)\n        bpy.ops.import_scene.gltf(filepath=temp_file_path)",[48,3708,3639],{},[48,3710,3711],{},[155,3712,3714],{"className":3713},[175],"        self.report({\"INFO\"}, \"Opened Revision\")\n        return {\"FINISHED\"}",[48,3716,3717],{},"Cet opérateur permet aux artistes de parcourir et charger n’importe quelle version stockée dans Kitsu sans quitter Blender.",[61,3719],{},[64,3721,3723],{"id":3722},"_5-registering-the-addon",[120,3724,3725],{},"5. Enregistrer l’addon",[48,3727,3728,1654],{},[94,3729,3730],{"href":2300},[1919,3731,3732],{},"Le panneau relie maintenant l’ensemble du workflow de révision",[212,3734,3735,3738,3741,3744,3747],{},[215,3736,3737],{},"Sélectionnez le projet",[215,3739,3740],{},"Choisissez l’asset",[215,3742,3743],{},"Choisissez la tâche",[215,3745,3746],{},"Parcourez les révisions",[215,3748,3749],{},"Créez ou chargez des versions en un seul clic",[152,3751,3752,3774],{},[155,3753,3755,3756,3759,3762,3765,3768,3771],{"className":3754},[175],"class MV_PT_panel(Panel):\n    bl_label = \"Model Versioning\"\n    bl_idname = \"MV_PT_panel\"\n    bl_space_type = \"VIEW_3D\"\n    bl_region_type = \"UI\"\n    bl_category = \"ModelVersion\"",[48,3757,3758],{},"    def draw(self, context):\n        layout = self.layout\n        scene = context.scene\n        mv = scene.mv_state",[48,3760,3761],{},"        layout.label(text=\"Project\")\n        layout.prop(mv, \"project\", text=\"\")\n        layout.separator()",[48,3763,3764],{},"        layout.label(text=\"Asset\")\n        layout.prop(mv, \"asset\", text=\"\")\n        layout.separator()",[48,3766,3767],{},"        layout.label(text=\"Task\")\n        layout.prop(mv, \"task\", text=\"\")\n        layout.separator()",[48,3769,3770],{},"        layout.label(text=\"Revision\")\n        layout.prop(mv, \"revision\", text=\"\")\n        layout.separator()",[48,3772,3773],{},"        row = layout.row(align=True)\n        row.operator(\"mv.create_revision\", text=\"Create Revision\", icon=\"ADD\")",[48,3775,3776],{},[155,3777,3779],{"className":3778},[175],"        layout.operator(\n            \"mv.load_revision\", text=\"Load Selected Revision\", icon=\"IMPORT\"\n        )",[48,3781,3782],{},"Enfin, nous enregistrons les opérateurs, le panneau et l’état pour que Blender sache comment construire l’interface :",[152,3784,3785,3795],{},[155,3786,3788,3789,3792],{"className":3787},[175],"classes = (\n    MV_State,\n    MV_OT_create_revision,\n    MV_OT_load_revision,\n    MV_PT_panel,\n)",[48,3790,3791],{},"def register():\n    for c in classes:\n        bpy.utils.register_class(c)\n    bpy.types.Scene.mv_state = PointerProperty(type=MV_State)",[48,3793,3794],{},"def unregister():\n    for c in reversed(classes):\n        bpy.utils.unregister_class(c)\n    if hasattr(bpy.types.Scene, \"mv_state\"):\n        del bpy.types.Scene.mv_state",[48,3796,3797],{},[155,3798,849,3800,853,3802,2472],{"className":3799},[175],[120,3801,852],{},[120,3803,856],{},[48,3805,3806],{},"À ce stade, le workflow de versioning des modèles est entièrement bidirectionnel : vous pouvez publier de nouvelles révisions depuis Blender et récupérer instantanément les révisions précédentes.",[72,3808,3810],{"className":3809},[34,75],[77,3811],{"src":3812,"className":3813,"alt":12,"loading":82,"width":3814,"height":3815,"srcSet":3816,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-00e861e7-3b2e-4bdc-80b8-1af740cab480.png",[81],759,488,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-00e861e7-3b2e-4bdc-80b8-1af740cab480.png 600w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-00e861e7-3b2e-4bdc-80b8-1af740cab480.png 759w",[61,3818],{},[64,3820,3821],{"id":507},[120,3822,508],{},[48,3824,3825],{},"Avec seulement quelques opérateurs de l’API Blender et la commodité du SDK Gazu, nous avons construit un workflow de versioning pratique (mais basique) qui vit directement dans Blender et reste synchronisé avec Kitsu. Les artistes peuvent lier leur scène Blender à un projet Kitsu, un asset et une tâche, créer de nouvelles révisions en un seul clic, parcourir l’historique complet des révisions pour n’importe quelle tâche, puis ramener d’anciennes versions directement dans Blender chaque fois qu’ils doivent comparer ou récupérer un travail.",[48,3827,3828],{},"Ce workflow n’est qu’un début. Ensuite, vous pourriez étendre l’addon avec des exports automatisés, des rendus de vignettes ou de turntable, la prise en charge de plusieurs formats de sortie, des outils de revue pour les superviseurs, voire des connexions vers un render farm.",[48,3830,3831,3832,3837],{},"Pour vous lancer, assurez-vous de cloner",[94,3833,1917,3834],{"href":3294},[1919,3835,3836],{},"notre repository Github"," pour cet addon de versioning et testez-le par vous-même !",[31,3839,3841,3844],{"className":3840},[34,35,36],[31,3842,524],{"className":3843},[40],[31,3845,1786,3847,3850],{"className":3846},[45],[94,3848,534],{"href":531,"rel":3849},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent des bonnes pratiques et qui organisent parfois des événements en personne. Nous serions ravis de vous accueillir ! 😊",[31,3852,3854],{"className":3853},[34,539,540],[94,3855,1797],{"href":531,"className":3856},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":3858},[3859,3860,3861,3862,3863,3864,3865],{"id":3232,"depth":548,"text":3235},{"id":3300,"depth":548,"text":3303},{"id":3404,"depth":548,"text":3407},{"id":3575,"depth":548,"text":3578},{"id":3650,"depth":548,"text":3653},{"id":3722,"depth":548,"text":3725},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1617746533234-288e5cf484e2?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDMwfHxhbmltYXRpb24lMjBwaXBlbGluZXxlbnwwfHx8fDE3NjYzODE5ODZ8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":3170,"featured_at":561,"visibility":562},"/blog-i18n/fr/blender-kitsu-versioning-addon","2025-12-22T10:00:20.000+01:00",{"title":3182,"description":12},"blender-kitsu-versioning-addon","blog-i18n/fr/blender-kitsu-versioning-addon/index",[3874,3875],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"37-KV4iy7_fdO_I5aewYlnv9Q_WsT02RjuFezAWeiGQ",{"id":3878,"title":3879,"authors":3880,"body":3882,"description":12,"extension":557,"feature_image":4352,"html":7,"meta":4353,"navigation":13,"path":4355,"published_at":4356,"seo":4357,"slug":4358,"stem":4359,"tags":4360,"__hash__":4363,"updated_at":4354,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-programmatic-rendering/index.md","Rendu vidéo programmatique dans Blender avec Python (2026)",[3881],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":3883,"toc":4343},[3884,3895,3898,3901,3904,3907,3913,3916,3918,3924,3927,3971,3974,3977,4003,4006,4032,4034,4040,4043,4049,4059,4068,4070,4076,4079,4085,4091,4094,4100,4103,4111,4113,4119,4129,4132,4138,4141,4147,4150,4158,4160,4166,4175,4184,4187,4193,4196,4202,4205,4211,4214,4220,4223,4229,4232,4237,4239,4245,4251,4277,4280,4286,4289,4297,4313,4315,4319,4322,4325,4337],[31,3885,3887,3891],{"className":3886},[34,35,36],[31,3888,3890],{"className":3889},[40],"🧠",[31,3892,3894],{"className":3893},[45],"Transformez Blender en moteur de rendu programmable avec seulement quelques lignes de Python.",[48,3896,3897],{},"Apprendre Blender en tant qu’artiste 3D signifie généralement découvrir son écosystème d’add-ons. Des tâches qui prendraient des heures, comme le rig d’un personnage, peuvent être réduites à quelques secondes grâce à des add-ons comme Rigify. Il en va de même pour la plupart des workflows, et on finit souvent par se poser la même question récurrente : « Blender peut-il faire ça automatiquement ? »",[48,3899,3900],{},"La réponse est oui. La clé, c’est le langage de programmation Python.",[48,3902,3903],{},"Blender inclut un moteur de script intégré puissant, et avec quelques lignes de code, vous pouvez créer des objets, positionner des caméras, et même déclencher des rendus complets.",[48,3905,3906],{},"Vous n’aurez pas besoin de payer un add-on si vous savez comment en créer un vous-même. Et à la base, un add-on n’est rien d’autre qu’un script enveloppé dans une interface utilisateur Blender personnalisée.",[48,3908,3909,3910,3912],{},"Si vous n’avez jamais scripté dans Blender auparavant, découvrir le module ",[155,3911,2136],{}," donne l’impression d’ouvrir une porte secrète à l’intérieur d’un outil que vous pensiez déjà connaître : soudain, chaque partie de l’interface devient programmable. Vous ne faites plus seulement des clics sur des boutons, vous donnez des instructions pour construire des systèmes reproductibles.",[48,3914,3915],{},"L’un des workflows les plus importants que vous pouvez automatiser, c’est le rendu. Non seulement pour accélérer votre pipeline, mais aussi pour aider à maintenir des réglages de rendu cohérents et prévisibles. Dans ce tutoriel, nous allons mettre en place un système de rendu programmatique de base pour animer automatiquement un texte 3D et le transformer en une vidéo Full HD. Nous partirons de zéro, en explorant comment exécuter Python pour Blender et comment l’utiliser pour contrôler la scène. À la fin, vous aurez une bonne vue d’ensemble de la manière d’automatiser des tâches d’animation courantes.",[61,3917],{},[64,3919,3921],{"id":3920},"use-cases",[120,3922,3923],{},"Cas d’usage",[48,3925,3926],{},"Le rendu programmatique débloque une grande variété de workflows puissants, bien au-delà de la construction manuelle traditionnelle de scènes :",[212,3928,3929,3935,3941,3947,3953,3959,3965],{},[215,3930,3931,3934],{},[120,3932,3933],{},"Motion graphics pilotés par les données"," — Graphiques animés, graphismes diffusés en temps réel via API, ou encore vidéos sociales générées automatiquement.",[215,3936,3937,3940],{},[120,3938,3939],{},"Art génératif"," — Motifs procéduraux, champs de bruit, expériences de particules et illustrations algorithmiques qui évoluent à partir du code.",[215,3942,3943,3946],{},[120,3944,3945],{},"Variantes rendues par lots"," — Publicités personnalisées, variations de couleur produit, recadrages automatiques au bon format, et génération massive d’assets sociaux.",[215,3948,3949,3952],{},[120,3950,3951],{},"Contenu 3D procédural"," — Générateurs de terrain, modélisation paramétrique, peuplement de la végétation / monde, et variations automatisées d’assets 3D.",[215,3954,3955,3958],{},[120,3956,3957],{},"UI & systèmes de design génératifs"," — SVG dynamiques, bannières pré-écrites, et graphismes cohérents avec la marque rendus à la demande.",[215,3960,3961,3964],{},[120,3962,3963],{},"Scripting VFX et animation"," — Contrôles de rig automatisés, systèmes de foule, population de particules, et setups de simulation reproductibles.",[215,3966,3967,3970],{},[120,3968,3969],{},"Visualisations de simulation"," — Simulations de fluide et de fumée, dynamique du trafic et de la foule, et rendus scientifiques ou basés sur la physique.",[48,3972,3973],{},"De nombreuses tâches de modélisation 3D sont répétitives et longues. En les intégrant à un pipeline automatisé piloté par script, les artistes peuvent se concentrer davantage sur la construction créative du monde, tandis que Python gère les parties fastidieuses en arrière-plan.",[48,3975,3976],{},"Dans tous les cas, le workflow de développement reste quasiment le même :",[1692,3978,3979,3985,3991,3997],{},[215,3980,3981,3984],{},[120,3982,3983],{},"Configuration"," - définir les données d’entrée nécessaires et nettoyer la scène",[215,3986,3987,3990],{},[120,3988,3989],{},"Génération de géométrie"," - modéliser les assets nécessaires à la tâche",[215,3992,3993,3996],{},[120,3994,3995],{},"Animation"," - définir les transformations et leurs keyframes associées",[215,3998,3999,4002],{},[120,4000,4001],{},"Sortie"," - les assets souhaités (modèles 3D, vidéo, séquence d’images, etc.)",[48,4004,4005],{},"Et c’est exactement le chemin que nous allons suivre pour notre exemple de rendu vidéo de texte 3D.",[31,4007,4009,4012],{"className":4008},[34,35,108],[31,4010,112],{"className":4011},[40],[31,4013,4015,4019,4021,4023,4024,4026,134,4028],{"className":4014},[45],[117,4016,4017],{},[120,4018,1021],{"style":122},[125,4020],{},[125,4022],{},"Vous pouvez trouver le code source complet de l’intégration de l’exemple présenté dans ce guide sur notre GitHub :",[125,4025],{},[125,4027],{},[94,4029,4031],{"href":4030},"https://github.com/cgwire/blender-programmatic-rendering?ref=blog.cg-wire.com","https://github.com/cgwire/blender-programmatic-rendering",[61,4033],{},[64,4035,4037],{"id":4036},"_1-scene-setup",[120,4038,4039],{},"1. Configuration de la scène",[48,4041,4042],{},"Avant de nous lancer dans la génération de scènes, il nous faut d’abord un point de départ propre. Lorsque vous ouvrez Blender, il charge une scène par défaut contenant généralement un cube, une caméra et une lumière. Pour ce tutoriel, nous n’aurons besoin que des deux derniers.",[48,4044,4045,4046,4048],{},"La première étape pour utiliser Blender de manière programmatique consiste à importer le module ",[155,4047,2136],{},". Cela vous donne un accès complet aux données, outils et pipeline de rendu de Blender directement depuis Python :",[152,4050,4051,4054],{},[155,4052,2662],{"className":4053},[175],[48,4055,4056],{},[155,4057,2150],{"className":4058},[175],[48,4060,4061,4062,4064,4065,4067],{},"Ici, nous supprimons l’objet ",[120,4063,2143],{}," par défaut. Le paramètre ",[155,4066,2158],{}," garantit que Blender supprime non seulement l’objet, mais aussi le désunlinks de toute scène susceptible d’y faire référence.",[61,4069],{},[64,4071,4073],{"id":4072},"_2-manipulating-3d-text",[120,4074,4075],{},"2. Manipuler du texte 3D",[48,4077,4078],{},"Ensuite, nous ajoutons un objet de texte 3D à la scène pour en faire l’élément central que nous allons manipuler et, finalement, rendre de manière programmatique.",[152,4080,4081],{},[155,4082,4084],{"className":4083},[175],"bpy.ops.object.text_add(location=(0, 0, 0))\ntext_obj = bpy.context.object\ntext_obj.name = \"CaptionText\"\ntext_obj.data.body = \"Hello world!\"",[48,4086,4087,4088,166],{},"Ce fragment de code crée un nouvel objet texte à l’origine du monde, lui assigne un nom lisible, et définit le texte affiché sur ",[155,4089,4090],{},"\"Hello world!\"",[48,4092,4093],{},"Pour donner plus de présence au texte dans la scène, nous pouvons ajuster sa géométrie. En augmentant sa taille et en ajoutant une extrusion, on obtient un texte pleinement 3D, et le centrer sur les deux axes simplifie les futures transformations et animations :",[152,4095,4096],{},[155,4097,4099],{"className":4098},[175],"text_obj.data.size = 0.6\ntext_obj.data.extrude = 0.05\ntext_obj.data.align_x = \"CENTER\"\ntext_obj.data.align_y = \"CENTER\"",[48,4101,4102],{},"Avec ces ajustements, le texte est proprement centré, correctement mis à l’échelle, et prêt pour un traitement ultérieur.",[72,4104,4106],{"className":4105},[34,75],[77,4107],{"src":4108,"className":4109,"alt":12,"loading":82,"width":83,"height":2680,"srcSet":4110,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png 1600w",[61,4112],{},[64,4114,4116],{"id":4115},"_3-adding-keyframes",[120,4117,4118],{},"3. Ajouter des keyframes",[48,4120,4121,4122,4128],{},"Nous",[94,4123,1917,4125],{"href":4124},"https://blog.cg-wire.com/stepped-animation/",[1919,4126,4127],{},"créons une animation simple en insérant des keyframes"," pour la position du texte au fil du temps.",[48,4130,4131],{},"Tout d’abord, nous déplaçons le curseur de la timeline sur la frame 1, positionnons le texte à l’emplacement de départ, puis enregistrons cette position avec une keyframe :",[152,4133,4134],{},[155,4135,4137],{"className":4136},[175],"bpy.context.scene.frame_set(1)\ntext_obj.location = (-4.0, 0.0, 1.0)\ntext_obj.keyframe_insert(data_path=\"location\", frame=1)",[48,4139,4140],{},"Ensuite, nous avançons à la frame 40, décalons le texte le long de l’axe X, et insérons une nouvelle keyframe pour marquer sa nouvelle position :",[152,4142,4143],{},[155,4144,4146],{"className":4145},[175],"bpy.context.scene.frame_set(40)\ntext_obj.location = (0.0, 0.0, 1.0)\ntext_obj.keyframe_insert(data_path=\"location\", frame=40)",[48,4148,4149],{},"Avec ces deux keyframes en place, Blender interpole automatiquement le mouvement entre elles, créant une animation fluide pendant que le texte glisse vers le centre de l’image.",[72,4151,4153],{"className":4152},[34,75],[77,4154],{"src":4155,"className":4156,"alt":12,"loading":82,"width":83,"height":2680,"srcSet":4157,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png 1600w",[61,4159],{},[64,4161,4163],{"id":4162},"_4-video-rendering",[120,4164,4165],{},"4. Rendu vidéo",[48,4167,4168,4169,4174],{},"Il ne nous reste plus qu’à",[94,4170,1917,4171],{"href":2737},[1919,4172,4173],{},"configurer les réglages de rendu de Blender"," et à générer la vidéo finale.",[48,4176,4177,4178,309,4181,166],{},"Le premier choix concerne le moteur de rendu à utiliser : ",[120,4179,4180],{},"Eevee",[120,4182,4183],{},"Cycles",[48,4185,4186],{},"Eevee est un moteur de rasterisation temps réel, ce qui le rend extrêmement rapide et idéal pour les aperçus ou les animations stylisées. Cycles, quant à lui, est un traceur de trajectoires physiquement basé qui produit un éclairage plus réaliste, mais nécessite des temps de rendu beaucoup plus longs. Pour un prototypage rapide et la plupart des workflows automatisés, Eevee est généralement le meilleur choix :",[152,4188,4189],{},[155,4190,4192],{"className":4191},[175],"bpy.context.scene.render.engine = \"BLENDER_EEVEE\"",[48,4194,4195],{},"Ensuite, nous spécifions la résolution de sortie :",[152,4197,4198],{},[155,4199,4201],{"className":4200},[175],"bpy.context.scene.render.resolution_x = 1920\nbpy.context.scene.render.resolution_y = 1080",[48,4203,4204],{},"Puis nous définissons la fréquence d’images et la plage d’animation. Ici, un plan de 60 frames à 24 fps :",[152,4206,4207],{},[155,4208,4210],{"className":4209},[175],"bpy.context.scene.render.fps = 24\nbpy.context.scene.frame_start = 1\nbpy.context.scene.frame_end = 60",[48,4212,4213],{},"Blender doit aussi savoir comment encoder la vidéo finale. Nous l’exportons en MP4 en utilisant l’encodage vidéo H.264 pour la vitesse de rendu :",[152,4215,4216],{},[155,4217,4219],{"className":4218},[175],"bpy.context.scene.render.image_settings.file_format = \"FFMPEG\"\nbpy.context.scene.render.ffmpeg.format = \"MPEG4\"\nbpy.context.scene.render.ffmpeg.codec = \"H264\"",[48,4221,4222],{},"Enfin, nous choisissons où le fichier de sortie sera écrit, en utilisant le dossier courant pour plus de commodité :",[152,4224,4225],{},[155,4226,4228],{"className":4227},[175],"bpy.context.scene.render.filepath = \"//render.mp4\"",[48,4230,4231],{},"Une fois tout configuré, nous pouvons lancer le rendu avec une seule commande :",[152,4233,4234],{},[155,4235,2784],{"className":4236},[175],[61,4238],{},[64,4240,4242],{"id":4241},"_5-putting-it-all-together",[120,4243,4244],{},"5. Tout réunir",[48,4246,4247,4248,1654],{},"Notre code est terminé : il ne reste plus qu’à le placer dans un fichier Python ",[155,4249,4250],{},"render.py",[152,4252,4253,4272],{},[155,4254,1662,4256,4258,4260,4262,4264,4266,4269],{"className":4255},[175],[48,4257,2150],{},[48,4259,4084],{},[48,4261,4099],{},[48,4263,4137],{},[48,4265,4146],{},[48,4267,4268],{},"bpy.context.scene.render.engine = \"BLENDER_EEVEE\"\nbpy.context.scene.render.resolution_x = 1920\nbpy.context.scene.render.resolution_y = 1080\nbpy.context.scene.render.resolution_percentage = 100\nbpy.context.scene.render.fps = 24\nbpy.context.scene.frame_start = 1\nbpy.context.scene.frame_end = 60",[48,4270,4271],{},"bpy.context.scene.render.image_settings.file_format = \"FFMPEG\"\nbpy.context.scene.render.ffmpeg.format = \"MPEG4\"  # container\nbpy.context.scene.render.ffmpeg.codec = \"H264\"\nbpy.context.scene.render.ffmpeg.constant_rate_factor = \"HIGH\"\nbpy.context.scene.render.ffmpeg.gopsize = 12\nbpy.context.scene.render.ffmpeg.audio_codec = \"AAC\"\nbpy.context.scene.render.filepath = \"//render.mp4\"",[48,4273,4274],{},[155,4275,2784],{"className":4276},[175],[48,4278,4279],{},"Maintenant, exécutez le script pour démarrer le rendu :",[152,4281,4282],{},[155,4283,4285],{"className":4284},[158],"python3 render.py",[48,4287,4288],{},"Une fois le rendu terminé, vérifiez votre répertoire de travail et votre animation générée entièrement de manière programmatique devrait maintenant être prête à être visionnée.",[72,4290,4292],{"className":4291},[34,75],[77,4293],{"src":4294,"className":4295,"alt":12,"loading":82,"width":2792,"height":2793,"srcSet":4296,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png 1088w",[31,4298,4300,4304],{"className":4299},[34,35,108],[31,4301,4303],{"className":4302},[40],"🔗",[31,4305,4307,4308],{"className":4306},[45],"Vous pouvez trouver notre code dans un dépôt Github pour une reproductibilité facile :",[94,4309,1917,4310],{"href":4030},[1919,4311,4312],{},"github.com/cgwire/blender-programmatic-rendering",[61,4314],{},[64,4316,4317],{"id":507},[120,4318,508],{},[48,4320,4321],{},"Dans cette démo pas à pas, vous avez construit un pipeline automatisé complet à l’intérieur de Blender : configurer une scène propre, créer et modifier du texte 3D, l’animer avec des keyframes, puis rendre la séquence avec une interpolation fluide. Tout cela est géré via Python, sans aucun réglage manuel nécessaire !",[48,4323,4324],{},"Maintenant que vous avez vu à quel point l’API Blender offre du contrôle, vous pouvez aller beaucoup plus loin avec ces idées : automatiser vos workflows, générer des graphismes à partir de données, construire des outils internes qui assemblent des scènes, rendre des variantes, ou créer des animations entières avec une seule commande... la liste pour aider votre studio d’animation à gagner en productivité ne s’arrête jamais.",[31,4326,4328,4331],{"className":4327},[34,35,36],[31,4329,524],{"className":4330},[40],[31,4332,528,4334,535],{"className":4333},[45],[94,4335,534],{"href":531,"rel":4336},[533],[31,4338,4340],{"className":4339},[34,539,540],[94,4341,1797],{"href":531,"className":4342},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":4344},[4345,4346,4347,4348,4349,4350,4351],{"id":3920,"depth":548,"text":3923},{"id":4036,"depth":548,"text":4039},{"id":4072,"depth":548,"text":4075},{"id":4115,"depth":548,"text":4118},{"id":4162,"depth":548,"text":4165},{"id":4241,"depth":548,"text":4244},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1622547748225-3fc4abd2cca0?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJlbmRlcnN8ZW58MHx8fHwxNzY2MzgyNjA1fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":4354,"featured_at":561,"visibility":562},"2026-02-20T06:04:02.000+01:00","/blog-i18n/fr/blender-programmatic-rendering","2025-12-29T10:00:10.000+01:00",{"title":3879,"description":12},"blender-programmatic-rendering","blog-i18n/fr/blender-programmatic-rendering/index",[4361,4362],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"NwtID8SrkpQdHNIDBLUw2pnwigsNNhe1kkLVg-uGpAI",{"id":4365,"title":4366,"authors":4367,"body":4369,"description":12,"extension":557,"feature_image":5207,"html":7,"meta":5208,"navigation":13,"path":5210,"published_at":5211,"seo":5212,"slug":5213,"stem":5214,"tags":5215,"__hash__":5218,"updated_at":5209,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-scripting-animation/index.md","Blender Scripting pour des pipelines d’animation : introduction 2026",[4368],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":4370,"toc":5198},[4371,4382,4385,4388,4390,4396,4399,4402,4423,4425,4431,4434,4453,4479,4481,4487,4498,4507,4510,4516,4519,4530,4540,4543,4549,4552,4558,4561,4563,4569,4572,4581,4584,4587,4598,4612,4615,4621,4650,4653,4659,4677,4680,4686,4706,4715,4718,4727,4749,4752,4758,4762,4765,4788,4790,4796,4799,4805,4812,4819,4827,4834,4840,4847,4850,4856,4860,4867,4885,4888,4890,4896,4899,4905,5027,5030,5162,5164,5168,5171,5174,5177,5180,5192],[31,4372,4374,4378],{"className":4373},[34,35,36],[31,4375,4377],{"className":4376},[40],"⚙️",[31,4379,4381],{"className":4380},[45],"Vous pouvez plier Blender à votre volonté avec seulement quelques lignes de code. Des clics répétitifs ? Fini. Des scènes complexes ? Construites en quelques secondes. Des outils personnalisés ? À vous de les concevoir. C’est la magie du scripting.",[48,4383,4384],{},"L’interface utilisateur graphique de Blender est sans aucun doute impressionnante, mais il y a toujours certaines tâches qui donnent l’impression d’être une corvée : partager des aperçus avec l’équipe, ajuster d’innombrables paramètres dans un nouveau projet, ou refaire les mêmes étapes encore et encore. Parfois, on aimerait juste avoir un bouton qui fait le travail, et le scripting permet justement de l’obtenir !",[48,4386,4387],{},"Dans cet article, nous allons ouvrir les possibilités de la fonctionnalité de scripting de Blender grâce au langage de programmation Python. Vous apprendrez à écrire votre premier script, à l’exécuter, et à comprendre comment les modules de scripting de Blender sont organisés. À la fin, vous aurez une bonne compréhension de la façon de commencer à optimiser votre pipeline de production.",[61,4389],{},[64,4391,4393],{"id":4392},"what-can-i-do-with-scripting",[120,4394,4395],{},"Que puis-je faire avec le scripting ?",[48,4397,4398],{},"Le scripting dans Blender n’est pas seulement une astuce sympa pour les passionnés : c’est une nécessité pour des studios de toutes tailles.",[48,4400,4401],{},"En production, la vitesse et la cohérence sont tout. Les studios font constamment face à des délais serrés, à de grandes bibliothèques d’actifs, et au besoin de garder des dizaines de plans et de scènes parfaitement synchronisés sur plusieurs postes de travail. Le faire manuellement est lent, source d’erreurs et coûteux : c’est pourquoi l’automatisation est si importante !",[48,4403,4404,4405,4408,4409,4412,4413,4418,4419,4422],{},"Le scripting ne consiste pas à écrire du code, mais à vous donner des raccourcis créatifs et des superpouvoirs. Avec Python, vous pouvez automatiser les tâches ennuyeuses et répétitives qui grignotent votre temps, ou générer de la géométrie procédurale, des matériaux, et même des environnements entiers en quelques lignes. Vous pouvez ",[120,4406,4407],{},"concevoir vos propres outils et menus"," adaptés à votre workflow, et ",[120,4410,4411],{},"prendre un contrôle total sur les scènes",",",[94,4414,1917,4415],{"href":2737},[1919,4416,4417],{},"les paramètres de rendu",", les caméras et les lumières. Le scripting vous permet même de ",[120,4420,4421],{},"connecter Blender à des outils externes ou à des APIs",", faisant de cette approche une partie puissante de pipelines plus larges.",[61,4424],{},[64,4426,4428],{"id":4427},"prerequisites",[120,4429,4430],{},"Prérequis",[48,4432,4433],{},"Avant de vous lancer, assurez-vous d’avoir :",[212,4435,4436,4447],{},[215,4437,4438,4440,4441,166],{},[120,4439,1828],{}," - Téléchargez et installez la dernière version depuis",[94,4442,1917,4444],{"href":4443},"https://www.blender.org/download/?ref=blog.cg-wire.com",[1919,4445,4446],{},"blender.org",[215,4448,4449,4452],{},[120,4450,4451],{},"Python"," - Vous aurez besoin du langage de programmation Python pour utiliser les modules de scripting natifs de Blender et exécuter des programmes depuis le terminal de votre système d’exploitation.",[31,4454,4457,4460],{"className":4455},[34,35,4456],"kg-callout-card-green",[31,4458,112],{"className":4459},[40],[31,4461,4463,4467,4469,129,4471,4473,134,4475],{"className":4462},[45],[117,4464,4465],{},[120,4466,1021],{"style":122},[125,4468],{},[125,4470],{},[125,4472],{},[125,4474],{},[94,4476,4478],{"href":4477},"https://github.com/cgwire/intro-blender-scripting?ref=blog.cg-wire.com","https://github.com/cgwire/intro-blender-scripting",[61,4480],{},[64,4482,4484],{"id":4483},"_1-create-a-new-script",[120,4485,4486],{},"1. Créer un nouveau script",[48,4488,4489,4490,4493,4494,4497],{},"Dans Blender, ouvrez l’",[120,4491,4492],{},"espace de travail Scripting",". Vous verrez un panneau d’éditeur de texte où vous pouvez créer un nouveau script en cliquant sur ",[120,4495,4496],{},"New",". C’est ici que vous pouvez écrire votre code Python, et c’est particulièrement utile pour voir les résultats en temps réel :",[72,4499,4501],{"className":4500},[34,75],[77,4502],{"src":4503,"className":4504,"alt":12,"loading":82,"width":83,"height":4505,"srcSet":4506,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png",[81],731,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png 1600w",[48,4508,4509],{},"Pour un pipeline de production, il est généralement plus utile d’exécuter un script depuis l’interface en ligne de commande. Heureusement, Python est désormais livré avec des modules Blender. Dans ce tutoriel, nous allons exécuter un programme Python directement depuis le terminal de l’OS pour éviter les étapes supplémentaires liées à la navigation dans l’interface graphique, donc la première étape consiste à installer le module Blender requis :",[152,4511,4512],{},[155,4513,4515],{"className":4514},[158],"pip install bpy==3.6.0 --extra-index-url \u003Chttps://download.blender.org/pypi/>",[48,4517,4518],{},"Pour tester, créons un nouveau fichier Blender vide en utilisant Python :",[152,4520,4521,4524],{},[155,4522,2662],{"className":4523},[175],[48,4525,4526],{},[155,4527,4529],{"className":4528},[175],"bpy.ops.wm.save_as_mainfile(filepath=\"./new_empty_file.blend\")",[48,4531,4532,4533,4536,4537,4539],{},"Tout d’abord, nous importons le ",[120,4534,4535],{},"module d’API Python"," de Blender ",[155,4538,2136],{},", qui nous permet de contrôler presque tout dans Blender (objets, matériaux, rendu, etc.). Ensuite, nous sauvegardons l’espace de travail actuel dans un nouveau fichier.",[48,4541,4542],{},"Nous pouvons exécuter le programme dans le terminal comme ceci :",[152,4544,4545],{},[155,4546,4548],{"className":4547},[175],"python3 script.py",[48,4550,4551],{},"Nous pouvons aussi ouvrir le fichier nouvellement créé avec la CLI de Blender :",[152,4553,4554],{},[155,4555,4557],{"className":4556},[158],"blender new_empty_file.blend",[48,4559,4560],{},"Félicitations ! Vous avez terminé votre premier script. Passons maintenant à un exemple plus utile : générer du texte 3D.",[61,4562],{},[64,4564,4566],{"id":4565},"_2-hello-world-text-example",[120,4567,4568],{},"2. Exemple de texte « Hello World »",[48,4570,4571],{},"Imaginez que vous vouliez créer une animation d’introduction inspirée de Star Wars. Celle, justement, avec un texte qui défile lentement vers le haut en angle :",[72,4573,4575],{"className":4574},[34,75],[77,4576],{"src":4577,"className":4578,"alt":12,"loading":82,"width":83,"height":4579,"srcSet":4580,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png",[81],681,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png 1600w",[48,4582,4583],{},"Comment feriez-vous cela de manière efficace pour que ce soit facile à modifier ? En utilisant un script, bien sûr ! Alors essayons un exemple simple et générons du texte 3D.",[48,4585,4586],{},"Nous créons un nouveau fichier et supprimons tous les objets de la scène pour partir sur une base propre :",[152,4588,4589,4592],{},[155,4590,1662],{"className":4591},[175],[48,4593,4594],{},[155,4595,4597],{"className":4596},[175],"bpy.ops.object.select_all(action='SELECT')\nbpy.ops.object.delete(use_global=False)",[212,4599,4600,4606],{},[215,4601,4602,4605],{},[155,4603,4604],{},"bpy.ops.object.select_all(action='SELECT')"," : Sélectionne tous les objets présents actuellement dans la scène.",[215,4607,4608,4611],{},[155,4609,4610],{},"bpy.ops.object.delete(use_global=False)"," : Supprime tous les objets sélectionnés.",[48,4613,4614],{},"Deux instructions suffisent pour ajouter un nouvel objet texte à la scène :",[152,4616,4617],{},[155,4618,4620],{"className":4619},[175],"bpy.ops.object.text_add(enter_editmode=False, location=(0, 0, 0))\ntext_obj = bpy.context.object",[212,4622,4623,4637],{},[215,4624,4625,4628,4629,4632,4633,4636],{},[155,4626,4627],{},"bpy.ops.object.text_add(...)"," : Ajoute un ",[120,4630,4631],{},"objet Texte"," à l’emplacement ",[155,4634,4635],{},"(0, 0, 0)"," dans le monde 3D (coordonnées XYZ).",[215,4638,4639,4642,4643,4646,4647,166],{},[155,4640,4641],{},"text_obj = bpy.context.object"," : Stocke une référence vers le nouvel objet texte créé dans la variable ",[155,4644,4645],{},"text_obj",". Chaque fois que vous ajoutez quelque chose de nouveau, Blender en fait l’objet actif, que vous pouvez récupérer via ",[155,4648,4649],{},"bpy.context.object",[48,4651,4652],{},"Changeons la chaîne de texte en « Hello World » :",[152,4654,4655],{},[155,4656,4658],{"className":4657},[175],"text_obj.data.body = \"Hello World\"",[212,4660,4661,4671],{},[215,4662,4663,4666,4667,4670],{},[155,4664,4665],{},"text_obj.data"," fait référence au ",[120,4668,4669],{},"Text DataBlock",", c’est-à-dire le contenu réel ou les paramètres de l’objet texte.",[215,4672,4673,4676],{},[155,4674,4675],{},".body = \"Hello World\""," définit la chaîne affichée sur « Hello World ».",[48,4678,4679],{},"Ensuite, nous pouvons ajuster quelques paramètres de texte pour lui donner un peu d’épaisseur et le centrer sur les axes x et y :",[152,4681,4682],{},[155,4683,4685],{"className":4684},[175],"text_obj.data.extrude = 0.05\ntext_obj.data.align_x = 'CENTER'\ntext_obj.data.align_y = 'CENTER'",[212,4687,4688,4694,4700],{},[215,4689,4690,4693],{},[155,4691,4692],{},"extrude = 0.05"," : Donne de la profondeur au texte, en le faisant passer d’un texte 2D plat à un texte 3D légèrement extrudé.",[215,4695,4696,4699],{},[155,4697,4698],{},"align_x = 'CENTER'"," : Centre horizontalement le texte.",[215,4701,4702,4705],{},[155,4703,4704],{},"align_y = 'CENTER'"," : Centre verticalement le texte.",[48,4707,4708,4709,166],{},"Vous pouvez trouver davantage d’options en lisant",[94,4710,1917,4712],{"href":4711},"https://docs.blender.org/manual/en/latest/modeling/texts/properties.html?ref=blog.cg-wire.com",[1919,4713,4714],{},"la documentation sur les propriétés de l’objet texte de Blender",[48,4716,4717],{},"Enfin, nous pouvons faire pivoter le texte pour qu’il soit orienté vers la caméra plutôt que posé à plat au sol, puisque par défaut le texte de Blender est posé à plat sur le plan XY :",[152,4719,4720],{},[155,4721,4723,4724,4726],{"className":4722},[175],"text_obj.rotation_euler",[262,4725,264],{}," = 1.5708   # 90 degrés en radians",[212,4728,4729,4740],{},[215,4730,4731,4736,4737,166],{},[155,4732,4733,4734],{},"rotation_euler",[262,4735,264],{}," : Fait référence à la ",[120,4738,4739],{},"rotation autour de l’axe X",[215,4741,4742,4745,4746,166],{},[155,4743,4744],{},"1.5708"," radians ≈ ",[120,4747,4748],{},"90 degrés",[48,4750,4751],{},"Nous pouvons sauvegarder le résultat en utilisant l’instruction mentionnée précédemment :",[152,4753,4754],{},[155,4755,4757],{"className":4756},[175],"bpy.ops.wm.save_as_mainfile(filepath=\"./text.blend\")",[48,4759,4760],{},[125,4761],{},[48,4763,4764],{},"Pour résumer, voici à quoi ressemble notre code final :",[152,4766,4767,4783],{},[155,4768,1662,4770,4772,4774,4776,4778],{"className":4769},[175],[48,4771,4597],{},[48,4773,4620],{},[48,4775,4658],{},[48,4777,4685],{},[48,4779,4723,4780,4782],{},[262,4781,264],{}," = 1.5708",[48,4784,4785],{},[155,4786,4757],{"className":4787},[175],[61,4789],{},[64,4791,4793],{"id":4792},"_3-how-to-run-a-script-script-loading",[120,4794,4795],{},"3. Comment exécuter un script (chargement du script)",[48,4797,4798],{},"Comme mentionné précédemment, la syntaxe pour exécuter un script en mode headless est simplement la même que pour n’importe quel programme Python :",[152,4800,4801],{},[155,4802,4804],{"className":4803},[175],"python3 text.py",[48,4806,4807,4808,4811],{},"Et c’est tout ! Vous venez d’exécuter votre premier script ",[652,4809,4810],{},"utile"," de Blender. Il est super pratique pour l’automatisation, les pipelines ou le traitement par lots.",[48,4813,4814,4815,4818],{},"Ouvrez simplement le fichier ",[155,4816,4817],{},"text.blend"," et regardez le résultat :",[72,4820,4822],{"className":4821},[34,75],[77,4823],{"src":4824,"className":4825,"alt":12,"loading":82,"width":83,"height":4505,"srcSet":4826,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png 1600w",[48,4828,4829,4830,4833],{},"Vous pouvez aussi ouvrir un fichier ",[155,4831,4832],{},".blend"," spécifique et exécuter le script dans ce contexte :",[152,4835,4836],{},[155,4837,4839],{"className":4838},[175],"bpy.ops.wm.open_mainfile(filepath='my_scene.blend')",[48,4841,4842,4843,4846],{},"Celui-ci charge d’abord ",[155,4844,4845],{},"my_scene.blend",", puis exécute le reste du script dessus.",[48,4848,4849],{},"Parfois, vous voulez envoyer des arguments personnalisés :",[152,4851,4852],{},[155,4853,4855],{"className":4854},[158],"python3 args.py – --text \"CLI Hello\"",[48,4857,4858],{},[125,4859],{},[48,4861,4862,4863,4866],{},"Dans ",[155,4864,4865],{},"args.py",", vous pouvez accéder à ces arguments comme ceci :",[152,4868,4869,4879],{},[155,4870,3422,4872],{"className":4871},[175],[48,4873,4874,4875,4878],{},"argv = sys.argv\nargv = argv",[262,4876,4877],{},"argv.index(\"--\") + 1:","  # récupérer les arguments après --",[48,4880,4881],{},[155,4882,4884],{"className":4883},[175],"print(\"Custom args:\", argv)",[48,4886,4887],{},"C’est tout pour les bases, mais il vous reste encore beaucoup à découvrir.",[61,4889],{},[64,4891,4893],{"id":4892},"_4-scripting-modules-explained",[120,4894,4895],{},"4. Modules de scripting expliqués",[48,4897,4898],{},"Blender expose ses fonctionnalités de scripting via différents modules. Comprendre ce que fait chaque module vous aide à définir ce que vous pouvez écrire en script, et comment rechercher la documentation pour le coder.",[48,4900,4901,4902,4904],{},"Tout d’abord, les modules ",[155,4903,2136],{}," de base :",[212,4906,4907,4919,4934,4943,4956,4975,4987,4999,5015],{},[215,4908,4909,4915,4916,4918],{},[120,4910,4911,4914],{},[155,4912,4913],{},"bpy.context"," (Accès au contexte)"," - Fournit des informations sur l’état actuel de Blender (objet actif, scène, mode, objets sélectionnés, etc.), par exemple ",[155,4917,4649],{}," obtient l’objet actif.",[215,4920,4921,4927,4928,4933],{},[120,4922,4923,4926],{},[155,4924,4925],{},"bpy.data"," (Accès aux données)"," - Donne un accès direct aux datablocks de Blender tels que les maillages, objets, matériaux et caméras. Exemple : ",[155,4929,4930,4931],{},"bpy.data.objects",[262,4932,2671],{}," récupère l’objet Cube.",[215,4935,4936,4942],{},[120,4937,4938,4941],{},[155,4939,4940],{},"bpy.msgbus"," (Message Bus)"," - Un système pub/sub pour écouter les changements dans les données de Blender et déclencher des rappels comme l’abonnement à des événements de changement de frame.",[215,4944,4945,4951,4952,4955],{},[120,4946,4947,4950],{},[155,4948,4949],{},"bpy.ops"," (Opérateurs)"," - Expose des fonctions qui imitent des actions de l’interface utilisateur comme l’ajout d’objets, la suppression ou le rendu. Exemple : ",[155,4953,4954],{},"bpy.ops.mesh.primitive_cube_add()"," ajoute un cube.",[215,4957,4958,4964,4965,655,4968,655,4971,4974],{},[120,4959,4960,4963],{},[155,4961,4962],{},"bpy.types"," (Types)"," - Définit les classes de base des données de Blender (par ex. ",[155,4966,4967],{},"Object",[155,4969,4970],{},"Mesh",[155,4972,4973],{},"Material",") pour l’extension et la personnalisation, afin de créer des panneaux ou des opérateurs personnalisés.",[215,4976,4977,4983,4984,166],{},[120,4978,4979,4982],{},[155,4980,4981],{},"bpy.utils"," (Utilitaires)"," - Fournit des fonctions d’aide pour l’enregistrement des classes, la gestion des add-ons et l’accès aux chemins système, par exemple ",[155,4985,4986],{},"bpy.utils.register_class(MyOperator)",[215,4988,4989,4995,4996,166],{},[120,4990,4991,4994],{},[155,4992,4993],{},"bpy.path"," (Utilitaires de chemin)"," - Outils pour gérer les chemins de fichiers, y compris la résolution des chemins relatifs et la création des chemins absolus, par exemple ",[155,4997,4998],{},"bpy.path.abspath(\"//textures/wood.png\")",[215,5000,5001,5007,5008,5011,5012,166],{},[120,5002,5003,5006],{},[155,5004,5005],{},"bpy.app"," (Données d’application)"," - Fournit des informations sur Blender lui-même comme la version, les détails de build et le mode d’exécution. Exemple : ",[155,5009,5010],{},"bpy.app.version"," renvoie ",[155,5013,5014],{},"(3, 6, 2)",[215,5016,5017,5023,5024,166],{},[120,5018,5019,5022],{},[155,5020,5021],{},"bpy.props"," (Définitions de propriétés)"," - Utilisé pour définir des propriétés personnalisées comme des nombres, des chaînes et des énumérations pour les opérateurs, panneaux ou add-ons, par exemple ",[155,5025,5026],{},"my_prop: bpy.props.IntProperty(name=\"My Number\")",[48,5028,5029],{},"Ensuite, vous pouvez trouver d’autres bibliothèques plus spécialisées :",[212,5031,5032,5041,5054,5063,5075,5084,5093,5102,5113,5122,5131,5140],{},[215,5033,5034,5040],{},[120,5035,5036,5039],{},[155,5037,5038],{},"aud"," (Système audio)"," - La bibliothèque audio de Blender pour jouer des sons, charger des fichiers et mixer l’audio. Exemple : jouer un fichier .wav directement dans Blender avec Python.",[215,5042,5043,5049,5050,5053],{},[120,5044,5045,5048],{},[155,5046,5047],{},"bgl"," (Wrapper OpenGL)"," - Un wrapper OpenGL de bas niveau pour le dessin de viewport 3D personnalisé (remplacé par ",[155,5051,5052],{},"gpu","). Pour dessiner par exemple des surcouches personnalisées.",[215,5055,5056,5062],{},[120,5057,5058,5061],{},[155,5059,5060],{},"bl_math"," (Fonctions mathématiques supplémentaires)"," - Des aides mathématiques supplémentaires pour l’interpolation, le calcul de distances et les opérations de géométrie, par exemple pour calculer des distances entre des points.",[215,5064,5065,5071,5072,166],{},[120,5066,5067,5070],{},[155,5068,5069],{},"blf"," (Dessin de polices)"," - Le module de dessin de polices de Blender pour rendre du texte dans les surcouches du viewport ou dans des panneaux, par exemple ",[155,5073,5074],{},"blf.draw(font_id, \"Hello World\")",[215,5076,5077,5083],{},[120,5078,5079,5082],{},[155,5080,5081],{},"bmesh"," (Module BMesh)"," - Fournit un accès direct de bas niveau au système d’édition de maillage de Blender pour la modélisation procédurale et les opérations de topologie. Exemple : créer ou modifier des sommets et des faces en mode édition.",[215,5085,5086,5092],{},[120,5087,5088,5091],{},[155,5089,5090],{},"bpy_extras"," (Utilitaires supplémentaires)"," - Contient des fonctions d’aide comme le support d’import/export, des conversions mathématiques et des utilitaires view3d, par exemple simplifier des conversions de coordonnées.",[215,5094,5095,5101],{},[120,5096,5097,5100],{},[155,5098,5099],{},"freestyle"," (Module Freestyle)"," - Contrôle le rendu de lignes Freestyle de Blender pour le rendu d’arêtes non photoréaliste. Exemple : ajuster des styles de ligne ou des règles de visibilité.",[215,5103,5104,5109,5110,5112],{},[120,5105,5106,5108],{},[155,5107,5052],{}," (Module GPU)"," - Une API moderne de rendu GPU qui permet des shaders personnalisés et des surcouches du viewport (successeur à ",[155,5111,5047],{},"). Exemple : rendu avec des shaders GLSL personnalisés.",[215,5114,5115,5121],{},[120,5116,5117,5120],{},[155,5118,5119],{},"gpu_extras"," (Utilitaires GPU)"," - Fonctions d’aide pour le dessin GPU, simplifiant le rendu de formes sans code GLSL complet, par exemple dessiner un rectangle simple.",[215,5123,5124,5130],{},[120,5125,5126,5129],{},[155,5127,5128],{},"idprop.types"," (Accès aux propriétés ID)"," - Fournit un accès structuré aux propriétés d’ID personnalisées de Blender sous forme de dictionnaire/tableau. Par exemple, pour manipuler des métadonnées personnalisées sur les objets.",[215,5132,5133,5139],{},[120,5134,5135,5138],{},[155,5136,5137],{},"imbuf"," (Tampon d’image)"," - Gère les tampons d’image, permettant le chargement, la sauvegarde et la manipulation au niveau des pixels, par exemple la génération d’images procédurales.",[215,5141,5142,5148,5149,655,5152,655,5155,5158,5159,166],{},[120,5143,5144,5147],{},[155,5145,5146],{},"mathutils"," (Types & utilitaires mathématiques)"," - La bibliothèque de mathématiques de Blender proposant ",[155,5150,5151],{},"Vector",[155,5153,5154],{},"Matrix",[155,5156,5157],{},"Quaternion"," et des utilitaires géométriques, par exemple ",[155,5160,5161],{},"Vector((1,0,0)).cross(Vector((0,1,0))) → (0,0,1)",[61,5163],{},[64,5165,5166],{"id":507},[120,5167,508],{},[48,5169,5170],{},"Le scripting de Blender avec Python est l’une des façons les plus puissantes d’étendre et de personnaliser votre workflow.",[48,5172,5173],{},"Dans cet article, nous avons exploré comment créer et exécuter des scripts, afficher votre tout premier « Hello World » dans le monde 3D, et utiliser le module bpy pour faire faire à Blender exactement ce que vous voulez.",[48,5175,5176],{},"Au premier abord, le scripting peut sembler intimidant, mais comme vous l’avez vu, même quelques lignes peuvent ouvrir la porte à des possibilités totalement nouvelles !",[48,5178,5179],{},"À présent, c’est à vous. Automatisez les tâches ennuyeuses ou créez des outils depuis zéro pour votre pipeline en studio. Vous pouvez le faire !",[31,5181,5183,5186],{"className":5182},[34,35,36],[31,5184,524],{"className":5185},[40],[31,5187,528,5189,535],{"className":5188},[45],[94,5190,534],{"href":531,"rel":5191},[533],[31,5193,5195],{"className":5194},[34,539,540],[94,5196,546],{"href":531,"className":5197},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":5199},[5200,5201,5202,5203,5204,5205,5206],{"id":4392,"depth":548,"text":4395},{"id":4427,"depth":548,"text":4430},{"id":4483,"depth":548,"text":4486},{"id":4565,"depth":548,"text":4568},{"id":4792,"depth":548,"text":4795},{"id":4892,"depth":548,"text":4895},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1760548425425-e42e77fa38f1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fCUyMHNjcmlwdGluZ3xlbnwwfHx8fDE3NjA2MTMxODl8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":5209,"featured_at":561,"visibility":562},"2026-02-20T06:04:03.000+01:00","/blog-i18n/fr/blender-scripting-animation","2025-10-21T10:00:42.000+02:00",{"title":4366,"description":12},"blender-scripting-animation","blog-i18n/fr/blender-scripting-animation/index",[5216,5217],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"y3yvfJsMl_Gmjzulb7LSHo_fbZLX9kKrTN6c8E2oLCg",{"id":5220,"title":5221,"authors":5222,"body":5224,"description":12,"extension":557,"feature_image":5948,"html":7,"meta":5949,"navigation":13,"path":5951,"published_at":5952,"seo":5953,"slug":5954,"stem":5955,"tags":5956,"__hash__":5959,"updated_at":5950,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-scripting-geometry-nodes-2/index.md","Comment script des Geometry Nodes dans Blender avec Python (2026)",[5223],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":5225,"toc":5932},[5226,5237,5240,5243,5246,5252,5254,5260,5263,5266,5269,5294,5296,5302,5305,5316,5323,5325,5331,5334,5377,5382,5392,5394,5400,5403,5413,5421,5428,5435,5437,5443,5446,5449,5455,5461,5467,5470,5476,5479,5491,5505,5511,5528,5534,5539,5545,5548,5554,5592,5598,5609,5623,5643,5649,5652,5658,5665,5671,5674,5728,5772,5775,5863,5866,5876,5879,5887,5889,5893,5896,5903,5911,5914,5926],[31,5227,5229,5233],{"className":5228},[34,35,36],[31,5230,5232],{"className":5231},[40],"🐍",[31,5234,5236],{"className":5235},[45],"La modélisation procédurale devient bien plus puissante lorsque vous générez des nœuds avec du code, plutôt que de les câbler à la main.",[48,5238,5239],{},"Les Geometry Nodes sont une fonctionnalité incroyable de Blender, mais saviez-vous que l’API Python de Blender vous permet aussi de script des geometry nodes, comme n’importe quel autre bloc de données ?",[48,5241,5242],{},"Vous pouvez créer des nœuds, définir leurs paramètres et les connecter par programmation, ouvrant la porte à la génération automatisée de scènes, à des outils personnalisés et au prototypage rapide de modèles avec seulement quelques lignes de code—au lieu de câbler manuellement des dizaines de nœuds.",[48,5244,5245],{},"Dans ce tutoriel, vous allez apprendre comment créer des configurations de geometry nodes entièrement depuis un script Python. Nous couvrirons le processus complet, de la création d’un nouvel arbre de nœuds à son affectation à un objet, avec des exemples clairs que vous pouvez copier-coller directement dans l’éditeur de scripting de Blender.",[48,5247,5248,5249,166],{},"Au cas où vous l’auriez manqué, jetez d’abord un œil à ",[94,5250,5251],{"href":1002},"notre introduction au scripting Blender",[61,5253],{},[64,5255,5257],{"id":5256},"why-script-geometry-nodes",[120,5258,5259],{},"Pourquoi script des Geometry Nodes ?",[48,5261,5262],{},"L’éditeur Geometry Nodes de Blender est un excellent système visuel pour construire des outils procéduraux : il est intuitif, flexible et idéal pour l’expérimentation une fois que vous avez le coup de main. Mais lorsque les projets deviennent plus complexes, gérer manuellement de grands réseaux de nœuds peut devenir fastidieux et difficile à maintenir, surtout si vous devez les réutiliser dans de nombreux pipelines de modélisation 3D.",[48,5264,5265],{},"Une configuration de nœuds scriptée n’est pas liée à un seul fichier .blend : elle peut être stockée, versionnée et partagée comme n’importe quel autre morceau de code. Cela facilite la création d’une bibliothèque d’outils procéduraux réutilisables sur différents projets, ou à partager avec d’autres artistes et développeurs.",[48,5267,5268],{},"Voyons comment le scripting fonctionne dans la pratique avec quelques extraits de code.",[31,5270,5272,5275],{"className":5271},[34,35,108],[31,5273,112],{"className":5274},[40],[31,5276,5278,5282,5284,2634,5286,5288,134,5290],{"className":5277},[45],[117,5279,5280],{},[120,5281,1021],{"style":122},[125,5283],{},[125,5285],{},[125,5287],{},[125,5289],{},[94,5291,5293],{"href":5292},"https://github.com/cgwire/blender-scripting-geometry-nodes?ref=blog.cg-wire.com","https://github.com/cgwire/blender-scripting-geometry-nodes",[61,5295],{},[64,5297,5299],{"id":5298},"_1-creating-a-new-node-tree",[120,5300,5301],{},"1. Créer une nouvelle arborescence de nœuds",[48,5303,5304],{},"Toute configuration de Geometry Nodes commence comme une arborescence de nœuds, qui stocke les nœuds et leurs connexions. Vous pouvez en créer une depuis Python grâce à l’API de données de Blender :",[152,5306,5307,5310],{},[155,5308,2662],{"className":5309},[175],[48,5311,5312],{},[155,5313,5315],{"className":5314},[175],"node_tree = bpy.data.node_groups.new(\"MyGeoNodesTree\", 'GeometryNodeTree')",[48,5317,5318,5319,5322],{},"Vous pouvez considérer ce ",[155,5320,5321],{},"node_tree"," comme la toile numérique qui contiendra toute la logique procédurale. Une fois créé, vous pouvez ajouter des nœuds, les connecter et définir leurs propriétés comme dans l’interface utilisateur graphique de Blender.",[61,5324],{},[64,5326,5328],{"id":5327},"_2-add-nodes-and-connect-them",[120,5329,5330],{},"2. Ajouter des nœuds et les connecter",[48,5332,5333],{},"Ensuite, ajoutons quelques nœuds de base. Nous allons créer un nœud Input Geometry, un nœud Subdivision Surface et un nœud Group Output, puis les connecter et appliquer le résultat à notre cube.",[152,5335,5336,5371],{},[155,5337,5339,5340,5343,5346,5351,5367],{"className":5338},[175],"# ADD NODES\ngeo_input = node_tree.interface.new_socket(\n    name=\"Geometry\",\n    in_out='INPUT',\n    socket_type='NodeSocketGeometry'\n)\ngeo_output = node_tree.interface.new_socket(\n    name=\"Geometry\",\n    in_out='OUTPUT',\n    socket_type='NodeSocketGeometry'\n)",[48,5341,5342],{},"input_node = node_tree.nodes.new(\"NodeGroupInput\")\nsubdivide_node = node_tree.nodes.new(\"GeometryNodeSubdivideMesh\")\noutput_node = node_tree.nodes.new(\"NodeGroupOutput\")",[48,5344,5345],{},"input_node.location = (-300, 0)\nsubdivide_node.location = (0, 0)\noutput_node.location = (300, 0)",[5347,5348,5350],"h1",{"id":5349},"link-nodes","LINK NODES",[48,5352,5353,5354,5357,5358,5361,5362,5364,5365,1330],{},"node_tree.links.new(input_node.outputs",[262,5355,5356],{},"'Geometry'",", subdivide_node.inputs",[262,5359,5360],{},"'Mesh'",")\nnode_tree.links.new(subdivide_node.outputs",[262,5363,5360],{},", output_node.inputs",[262,5366,5356],{},[5347,5368,5370],{"id":5369},"apply-to-current-object","APPLY TO CURRENT OBJECT",[48,5372,5373],{},[155,5374,5376],{"className":5375},[175],"obj = bpy.context.object\nmod = obj.modifiers.new(\"MyGeoNodesModifier\", \"NODES\")\nmod.node_group = node_tree",[48,5378,5379,5381],{},[125,5380],{},"Lorsque vous exécutez ce script, vous obtenez une configuration de geometry nodes fonctionnelle (bien que simple) qui subdivise toute géométrie à laquelle elle est appliquée :",[72,5383,5385],{"className":5384},[34,75],[77,5386],{"src":5387,"className":5388,"alt":12,"loading":82,"width":5389,"height":5390,"srcSet":5391,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png",[81],1314,889,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png 1314w",[61,5393],{},[64,5395,5397],{"id":5396},"_3-set-parameters-and-link-geometry-to-objects",[120,5398,5399],{},"3. Définir les paramètres et relier la géométrie aux objets",[48,5401,5402],{},"Vous pouvez modifier les paramètres directement via les propriétés du nœud. Par exemple, augmentons le niveau de subdivision et appliquons ce groupe de nœuds à un objet :",[152,5404,5405],{},[155,5406,5408,5409,5412],{"className":5407},[175],"subdivide_node.inputs",[262,5410,5411],{},"'Level'",".default_value = 3",[72,5414,5416],{"className":5415},[34,75],[77,5417],{"src":5418,"className":5419,"alt":12,"loading":82,"width":5389,"height":5390,"srcSet":5420,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png 1314w",[48,5422,5423,5424,5427],{},"Ajuster ",[155,5425,5426],{},"default_value"," pour les entrées est une façon simple de paramétrer votre configuration.",[48,5429,5430,5431,166],{},"Pour un aperçu complet des paramètres disponibles et de leurs types, reportez-vous à ",[94,5432,5434],{"href":5433},"https://docs.blender.org/api/current/bpy.types.Node.html?ref=blog.cg-wire.com","la documentation officielle de l’API Python de Blender",[61,5436],{},[64,5438,5440],{"id":5439},"_4-create-a-custom-%E2%80%9Ccube-crowd-generator%E2%80%9D-node-group-programmatically",[120,5441,5442],{},"4. Créer un groupe de nœuds personnalisé « Cube Crowd Generator » par programmation",[48,5444,5445],{},"Nous savons maintenant comment définir des geometry nodes par programmation, mais qu’en est-il de la création de nœuds personnalisés réutilisables ?",[48,5447,5448],{},"Travaillons sur un nouvel exemple qui construit un mini-système procédural qui disperse beaucoup de cubes sur une surface. Le script crée un groupe Geometry Nodes qui prend une surface, disperse des points dessus, décale aléatoirement ces points, place un cube sur chaque point (instances), convertit les instances en géométrie réelle, puis affiche le maillage final comme « Cubes ».",[1085,5450,5452],{"id":5451},"_1-create-a-new-node-group",[120,5453,5454],{},"1) Créer un nouveau groupe de nœuds",[48,5456,5457,5458,166],{},"Tout d’abord, créons un nouveau groupe Geometry Node dans Blender nommé ",[155,5459,5460],{},"\"CubeCrowdGenerator\"",[152,5462,5463],{},[155,5464,5466],{"className":5465},[175],"crowd_group = bpy.data.node_groups.new(\"CubeCrowdGenerator\", \"GeometryNodeTree\")",[48,5468,5469],{},"Comme une fonction, nous voulons pouvoir attacher ce nœud à n’importe quel objet avec un modificateur Geometry Nodes plus tard.",[1085,5471,5473],{"id":5472},"_2-add-group-input-and-output-nodes-uientry-points",[120,5474,5475],{},"2) Ajouter des nœuds d’entrée et de sortie de groupe (points UI/entrée)",[48,5477,5478],{},"Nous plaçons les groupes d’entrée et de sortie standard sur la toile, comme d’habitude :",[152,5480,5481,5485],{},[155,5482,5484],{"className":5483},[175],"group_in = crowd_group.nodes.new(\"NodeGroupInput\")\ngroup_out = crowd_group.nodes.new(\"NodeGroupOutput\")",[48,5486,5487],{},[155,5488,5490],{"className":5489},[175],"group_in.location = (-600, 0)\ngroup_out.location = (600, 0)",[212,5492,5493,5502],{},[215,5494,5495,498,5498,5501],{},[155,5496,5497],{},"group_in",[155,5499,5500],{},"group_out"," sont les prises visibles du groupe de nœuds dans l’éditeur Geometry Nodes.",[215,5503,5504],{},"Le script les positionne aussi pour que le graphe soit lisible.",[1085,5506,5508],{"id":5507},"_3-define-the-group-interface-what-the-group-acceptsreturns",[120,5509,5510],{},"3) Définir l’interface du groupe (ce que le groupe accepte/retourne)",[48,5512,5513,5514,5520,5521,5527],{},"Nous devons exposer une ",[120,5515,5516,5517],{},"prise d’entrée nommée ",[155,5518,5519],{},"Surface"," dans laquelle nous brancherons le maillage que vous voulez remplir (par ex. un plan), et une ",[120,5522,5523,5524],{},"prise de sortie nommée ",[155,5525,5526],{},"Cubes",", la géométrie résultante.",[152,5529,5530],{},[155,5531,5533],{"className":5532},[175],"interface = crowd_group.interface\ninterface.new_socket(name=\"Surface\", in_out=\"INPUT\", socket_type=\"NodeSocketGeometry\")\ninterface.new_socket(name=\"Cubes\", in_out=\"OUTPUT\", socket_type=\"NodeSocketGeometry\")",[48,5535,5536,5537,166],{},"Dans la pratique, lorsque vous ajoutez ce groupe de nœuds à un objet, vous branchez sa surface (la géométrie originale de l’objet) dans ",[155,5538,5519],{},[1085,5540,5542],{"id":5541},"_4-create-the-internal-nodes-the-building-blocks",[120,5543,5544],{},"4) Créer les nœuds internes (les blocs de construction)",[48,5546,5547],{},"Nous pouvons ensuite travailler sur la logique interne réelle :",[152,5549,5550],{},[155,5551,5553],{"className":5552},[175],"distribute = crowd_group.nodes.new(\"GeometryNodeDistributePointsOnFaces\")\nrand_vec = crowd_group.nodes.new(\"FunctionNodeRandomValue\")\nset_pos = crowd_group.nodes.new(\"GeometryNodeSetPosition\")\ncube = crowd_group.nodes.new(\"GeometryNodeMeshCube\")\ninstance = crowd_group.nodes.new(\"GeometryNodeInstanceOnPoints\")\nrealize = crowd_group.nodes.new(\"GeometryNodeRealizeInstances\")",[212,5555,5556,5562,5568,5574,5580,5586],{},[215,5557,5558,5561],{},[120,5559,5560],{},"GeometryNodeDistributePointsOnFaces"," : crée des points sur la surface d’entrée (contrôle le nombre de points, la distribution).",[215,5563,5564,5567],{},[120,5565,5566],{},"FunctionNodeRandomValue (Float Vector)"," : génère un vecteur 3D aléatoire par point, utilisé comme décalage.",[215,5569,5570,5573],{},[120,5571,5572],{},"GeometryNodeSetPosition"," : déplace chaque point par un vecteur (le décalage aléatoire).",[215,5575,5576,5579],{},[120,5577,5578],{},"GeometryNodeMeshCube"," : génère un maillage de cube qui sera utilisé comme objet d’instance.",[215,5581,5582,5585],{},[120,5583,5584],{},"GeometryNodeInstanceOnPoints"," : place le cube sur chaque point. Il ne crée pas de géométrie réelle, c’est juste une instance « légère » du cube d’origine.",[215,5587,5588,5591],{},[120,5589,5590],{},"GeometryNodeRealizeInstances"," : convertit les instances en géométrie de maillage réelle afin de pouvoir les afficher comme un maillage unique.",[1085,5593,5595],{"id":5594},"_5-configure-the-random-vector-node",[120,5596,5597],{},"5) Configurer le nœud de vecteur aléatoire",[48,5599,5600,5601,5604,5605,5608],{},"Nous configurons le nœud ",[155,5602,5603],{},"Random Value"," pour qu’il renvoie un ",[120,5606,5607],{},"vecteur à 3 composantes ","que nous pouvons utiliser pour décaler les cubes générés dans l’espace 3D :",[152,5610,5611],{},[155,5612,5614,5615,5618,5619,5622],{"className":5613},[175],"rand_vec.data_type = \"FLOAT_VECTOR\"\nrand_vec.inputs",[262,5616,5617],{},"\"Min\"",".default_value = (-0.5, -0.5, 0.0)\nrand_vec.inputs",[262,5620,5621],{},"\"Max\"",".default_value = (0.5, 0.5, 0.5)",[212,5624,5625,5640],{},[215,5626,5627,498,5630,5633,5634,498,5637,166],{},[155,5628,5629],{},"Min",[155,5631,5632],{},"Max"," définissent la plage pour chaque composante. Par exemple, X est entre ",[155,5635,5636],{},"-0.5",[155,5638,5639],{},"0.5",[215,5641,5642],{},"Résultat : chaque point reçoit un décalage légèrement différent, donc les cubes ne se superposent pas exactement.",[1085,5644,5646],{"id":5645},"_6-node-layout-ui-only",[120,5647,5648],{},"6) Disposition des nœuds (UI uniquement)",[48,5650,5651],{},"Nous positionnons ensuite les nœuds internes pour qu’ils soient faciles à comprendre si nous voulons vérifier notre workflow dans Blender :",[152,5653,5654],{},[155,5655,5657],{"className":5656},[175],"distribute.location = (-400, 0)\nrand_vec.location = (-200, -200)\nset_pos.location = (-100, 0)\ninstance.location = (100, 0)\ncube.location = (-400, -200)\nrealize.location = (300, 0)",[48,5659,5660,5661,5664],{},"Ces affectations de ",[155,5662,5663],{},"location"," ne concernent que la manière dont les nœuds sont arrangés visuellement dans l’éditeur de nœuds. Elles n’affectent pas le fonctionnement du graphe.",[1085,5666,5668],{"id":5667},"_7-wire-the-nodes-together",[120,5669,5670],{},"7) Câbler les nœuds entre eux",[48,5672,5673],{},"Enfin, nous définissons le flux de données :",[152,5675,5676],{},[155,5677,5679,5680,5683,5684,5687,5688,5691,5692,5695,5696,5691,5699,5702,5703,5705,5706,5708,5709,5705,5711,5714,5715,5718,5719,5721,5722,5724,5725,1330],{"className":5678},[175],"links.new(group_in.outputs",[262,5681,5682],{},"\"Surface\"",", distribute.inputs",[262,5685,5686],{},"\"Mesh\"",")\nlinks.new(distribute.outputs",[262,5689,5690],{},"\"Points\"",", set_pos.inputs",[262,5693,5694],{},"\"Geometry\"",")\nlinks.new(rand_vec.outputs",[262,5697,5698],{},"\"Value\"",[262,5700,5701],{},"\"Offset\"",")\nlinks.new(set_pos.outputs",[262,5704,5694],{},", instance.inputs",[262,5707,5690],{},")\nlinks.new(cube.outputs",[262,5710,5686],{},[262,5712,5713],{},"\"Instance\"",")\nlinks.new(instance.outputs",[262,5716,5717],{},"\"Instances\"",", realize.inputs",[262,5720,5694],{},")\nlinks.new(realize.outputs",[262,5723,5694],{},", group_out.inputs",[262,5726,5727],{},"\"Cubes\"",[1692,5729,5730,5736,5742,5748,5754,5760,5766],{},[215,5731,5732,5735],{},[120,5733,5734],{},"Surface → DistributePointsOnFaces"," : la surface d’entrée (plan) est utilisée pour créer des points dispersés.",[215,5737,5738,5741],{},[120,5739,5740],{},"Points → SetPosition (Geometry)"," : Set position reçoit les points sous forme de géométrie à déplacer.",[215,5743,5744,5747],{},[120,5745,5746],{},"RandomValue → SetPosition (Offset)"," : chaque point reçoit un vecteur de décalage aléatoire.",[215,5749,5750,5753],{},[120,5751,5752],{},"SetPosition → InstanceOnPoints (Points)"," : les points déplacés deviennent les positions d’ancrage pour les instances.",[215,5755,5756,5759],{},[120,5757,5758],{},"Cube Mesh → InstanceOnPoints (Instance)"," : chaque point reçoit une instance de cube.",[215,5761,5762,5765],{},[120,5763,5764],{},"InstanceOnPoints → RealizeInstances"," : les instances sont converties en géométrie de maillage.",[215,5767,5768,5771],{},[120,5769,5770],{},"RealizeInstances → Group Output (« Cubes »)"," : le résultat final est disponible en tant que sortie du groupe.",[48,5773,5774],{},"Voici le code complet que nous avons obtenu :",[152,5776,5777,5829],{},[155,5778,1662,5780,5784,5786,5790,5792,5794,5798,5800,5804,5807,5811,5819,5823,5825],{"className":5779},[175],[5347,5781,5783],{"id":5782},"create-a-new-geometry-node-group","Create a new Geometry Node group",[48,5785,5466],{},[5347,5787,5789],{"id":5788},"create-inputoutput-nodes","Create input/output nodes",[48,5791,5484],{},[48,5793,5490],{},[5347,5795,5797],{"id":5796},"define-group-interface-sockets","Define group interface sockets",[48,5799,5533],{},[5347,5801,5803],{"id":5802},"create-internal-nodes","Create internal nodes",[48,5805,5806],{},"distribute = crowd_group.nodes.new(\"GeometryNodeDistributePointsOnFaces\")\ninstance = crowd_group.nodes.new(\"GeometryNodeInstanceOnPoints\")\ncube = crowd_group.nodes.new(\"GeometryNodeMeshCube\")\nrealize = crowd_group.nodes.new(\"GeometryNodeRealizeInstances\")\nset_pos = crowd_group.nodes.new(\"GeometryNodeSetPosition\")\nrand_vec = crowd_group.nodes.new(\"FunctionNodeRandomValue\")",[5347,5808,5810],{"id":5809},"configure-random-vector-node","Configure random vector node",[48,5812,5614,5813,5815,5816,5818],{},[262,5814,5617],{},".default_value = (-0.5, -0.5, 0.0)  # minimum offset\nrand_vec.inputs",[262,5817,5621],{},".default_value = (0.5, 0.5, 0.5)  # maximum offset",[5347,5820,5822],{"id":5821},"layout-nodes","Layout nodes",[48,5824,5657],{},[5347,5826,5828],{"id":5827},"create-links","Create links",[48,5830,5831],{},[155,5832,5834,5835,5683,5837,5687,5839,5691,5841,5695,5843,5691,5845,5702,5847,5705,5849,5708,5851,5705,5853,5714,5855,5718,5857,5721,5859,5724,5861,1330],{"className":5833},[175],"links = crowd_group.links\nlinks.new(group_in.outputs",[262,5836,5682],{},[262,5838,5686],{},[262,5840,5690],{},[262,5842,5694],{},[262,5844,5698],{},[262,5846,5701],{},[262,5848,5694],{},[262,5850,5690],{},[262,5852,5686],{},[262,5854,5713],{},[262,5856,5717],{},[262,5858,5694],{},[262,5860,5694],{},[262,5862,5727],{},[48,5864,5865],{},"Maintenant, il ne reste plus qu’à copier-coller ce script dans l’espace de travail de scripting, l’exécuter, puis vous pourrez ajouter notre nœud personnalisé depuis l’espace de travail des geometry nodes :",[72,5867,5869],{"className":5868},[34,75],[77,5870],{"src":5871,"className":5872,"alt":12,"loading":82,"width":5873,"height":5874,"srcSet":5875,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png",[81],1430,920,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png 1430w",[48,5877,5878],{},"Nous pouvons ouvrir le groupe de nœuds pour voir ce qu’il contient en double-cliquant dessus :",[72,5880,5882],{"className":5881},[34,75],[77,5883],{"src":5884,"className":5885,"alt":12,"loading":82,"width":5873,"height":5874,"srcSet":5886,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png 1430w",[61,5888],{},[64,5890,5891],{"id":507},[120,5892,508],{},[48,5894,5895],{},"Avec seulement quelques dizaines de lignes de code, vous pouvez script des configurations de Geometry Nodes qui prendraient beaucoup plus de temps à assembler manuellement. Dans cet article, vous avez appris comment créer des arborescences de nœuds Geometry Node, ajouter et connecter des nœuds par programmation, contrôler les paramètres et assigner des arborescences de nœuds aux objets, puis construire un système procédural complet.",[48,5897,5898,5899,5902],{},"Jetez un œil à ",[94,5900,5901],{"href":5292},"l’annuaire du code sur Github"," pour essayer l’exemple vous-même !",[72,5904,5906],{"className":5905},[34,75],[77,5907],{"src":5908,"className":5909,"alt":12,"loading":82,"width":5389,"height":5390,"srcSet":5910,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png 1314w",[48,5912,5913],{},"Cette approche libère un potentiel d’automatisation sans fin, du développement d’outils à l’art génératif. ",[31,5915,5917,5920],{"className":5916},[34,35,36],[31,5918,524],{"className":5919},[40],[31,5921,1786,5923,535],{"className":5922},[45],[94,5924,534],{"href":531,"rel":5925},[533],[31,5927,5929],{"className":5928},[34,539,540],[94,5930,1797],{"href":531,"className":5931},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":5933},[5934,5935,5936,5937,5938,5947],{"id":5256,"depth":548,"text":5259},{"id":5298,"depth":548,"text":5301},{"id":5327,"depth":548,"text":5330},{"id":5396,"depth":548,"text":5399},{"id":5439,"depth":548,"text":5442,"children":5939},[5940,5941,5942,5943,5944,5945,5946],{"id":5451,"depth":1803,"text":5454},{"id":5472,"depth":1803,"text":5475},{"id":5507,"depth":1803,"text":5510},{"id":5541,"depth":1803,"text":5544},{"id":5594,"depth":1803,"text":5597},{"id":5645,"depth":1803,"text":5648},{"id":5667,"depth":1803,"text":5670},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1675044794037-9262cedb6d5d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGJsZW5kZXIlMjBnZW9tZXRyeSUyMG5vZGVzfGVufDB8fHx8MTc2MzM2OTc0N3ww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":5950,"featured_at":561,"visibility":562},"2026-02-20T06:04:04.000+01:00","/blog-i18n/fr/blender-scripting-geometry-nodes-2","2025-11-17T10:13:21.000+01:00",{"title":5221,"description":12},"blender-scripting-geometry-nodes-2","blog-i18n/fr/blender-scripting-geometry-nodes-2/index",[5957,5958],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"l6vF4MtyASTXwSB5Kcrxa8D5w40ywVOUFHIpOrZ79xg",{"id":5961,"title":5962,"authors":5963,"body":5965,"description":12,"extension":557,"feature_image":6424,"html":7,"meta":6425,"navigation":13,"path":6426,"published_at":6427,"seo":6428,"slug":6429,"stem":6430,"tags":6431,"__hash__":6433,"updated_at":5950,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-scripting-geometry-nodes/index.md","Le guide du débutant pour les Geometry Nodes dans Blender 2026",[5964],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":5966,"toc":6403},[5967,5977,5980,5983,5985,5991,5994,6003,6006,6008,6014,6021,6024,6048,6050,6056,6059,6067,6075,6078,6081,6112,6120,6123,6126,6129,6131,6137,6140,6143,6146,6152,6155,6158,6164,6167,6170,6176,6179,6182,6192,6198,6201,6204,6213,6219,6222,6225,6231,6234,6237,6243,6246,6249,6259,6265,6268,6271,6277,6280,6283,6289,6292,6298,6301,6304,6310,6313,6316,6322,6325,6328,6334,6337,6340,6361,6363,6367,6370,6373,6384,6397],[31,5968,5970,5973],{"className":5969},[34,35,36],[31,5971,1845],{"className":5972},[40],[31,5974,5976],{"className":5975},[45],"Reconstruire des scènes à la main, c’est du niveau 2010. Les Geometry Nodes vous permettent d’automatiser, de randomiser et de contrôler des projets Blender avec précision — transformant des heures de modélisation manuelle en quelques minutes de magie procédurale.",[48,5978,5979],{},"Passer des heures à dupliquer manuellement de la géométrie, à la remodeler ou à animer des mouvements répétitifs dans Blender n’est pas vraiment amusant. Certains workflows fonctionnent comme ça : vous devez refaire des tâches répétitives encore et encore, avec seulement de légères variations.",[48,5981,5982],{},"Mais il existe une façon plus intelligente et plus rapide de créer des effets procéduraux : les geometry nodes. Ils peuvent sembler intimidants et demander du temps pour être maîtrisés, mais à la fin de cet article, vous saurez ce que sont les geometry nodes, pourquoi ils comptent, et comment commencer à les utiliser dans vos propres projets Blender.",[61,5984],{},[64,5986,5988],{"id":5987},"what-are-geometry-nodes",[120,5989,5990],{},"Que sont les Geometry Nodes ?",[48,5992,5993],{},"Les Geometry Nodes sont la manière de Blender de vous permettre de créer et de manipuler des modèles de façon procédurale. Au lieu de modifier directement les objets maillage, vous connectez des nœuds visuels qui définissent des opérations comme l’instanciation, la transformation ou la dispersion d’objets, le tout de manière non destructive et modulaire.",[72,5995,5997],{"className":5996},[34,75],[77,5998],{"src":5999,"className":6000,"alt":12,"loading":82,"width":83,"height":6001,"srcSet":6002,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png",[81],830,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png 1600w",[48,6004,6005],{},"Chaque nœud effectue une petite tâche, mais une fois connectés, ils peuvent produire des résultats incroyablement détaillés : de forêts constituées de milliers d’arbres randomisés à des traînées de particules animées ou des motifs architecturaux. Les Geometry Nodes vous permettent de construire une fois et de tout contrôler grâce à des paramètres ajustables.",[61,6007],{},[64,6009,6011],{"id":6010},"why-geometry-nodes-are-important",[120,6012,6013],{},"Pourquoi les Geometry Nodes sont importants",[48,6015,6016,6020],{},[94,6017,6019],{"href":6018},"https://blog.cg-wire.com/3d-modeling-animation/","Les workflows traditionnels de modélisation et d’animation"," reposent souvent sur des ajustements manuels qui prennent du temps, où chaque changement ou variation nécessite des modifications directes sur le modèle. Les Geometry Nodes révolutionnent ce processus en introduisant un contrôle procédural : un système qui permet de générer et de modifier dynamiquement des modèles via des valeurs d’entrée, du hasard ou des relations mathématiques.",[48,6022,6023],{},"Cette approche offre plusieurs avantages majeurs. Elle vous rend plus productif en vous permettant de mettre à jour ou randomiser instantanément des scènes complexes sans avoir besoin de tout reconstruire depuis zéro. Elle apporte aussi de la flexibilité à votre pipeline, car les paramètres peuvent être ajustés à n’importe quelle étape de la production. Les Geometry Nodes ouvrent la porte à l’expérimentation pour produire des formes, des motifs et des effets complexes qu’il serait difficile, voire impossible, d’obtenir à la main — comme générer une grande zone d’herbe. Cette fonctionnalité est idéale pour de la modélisation à grande échelle, comme les simulations de foule ou les environnements naturels réalistes.",[31,6025,6027,6030],{"className":6026},[34,35,4456],[31,6028,112],{"className":6029},[40],[31,6031,6033,6037,6039,6041,6042,6044,134,6046],{"className":6032},[45],[117,6034,6035],{},[120,6036,1889],{"style":122},[125,6038],{},[125,6040],{},"Vous pouvez trouver le code source complet de l’exemple d’intégration Blender–Kitsu présenté dans ce guide sur notre GitHub :",[125,6043],{},[125,6045],{},[94,6047,5293],{"href":5292},[61,6049],{},[64,6051,6053],{"id":6052},"adding-a-geometry-node",[120,6054,6055],{},"Ajouter un Geometry Node",[48,6057,6058],{},"Je sais que le concept peut paraître intimidant, mais donnez-moi 5 minutes et nous créerons votre première configuration de geometry node.",[1692,6060,6061,6064],{},[215,6062,6063],{},"Ouvrez un nouveau projet Blender avec un cube par défaut.",[215,6065,6066],{},"Dans l’onglet Geometry Nodes, cliquez sur New pour créer un nouveau groupe de geometry nodes.",[72,6068,6070],{"className":6069},[34,75],[77,6071],{"src":6072,"className":6073,"alt":12,"loading":82,"width":5389,"height":5390,"srcSet":6074,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png 1314w",[48,6076,6077],{},"Vous verrez maintenant un arbre de nœuds vide dans l’espace de travail de l’éditeur Geometry Node, avec deux nœuds par défaut : Group Input et Group Output. Ils représentent le début et la fin de votre flux de données : la géométrie arrive, est modifiée, puis sort.",[48,6079,6080],{},"Pour voir votre configuration en action, il vous suffit d’ajouter votre premier nœud :",[1692,6082,6083,6098,6109],{},[215,6084,3328,6085,6088,6089,6088,6092,6088,6095,166],{},[120,6086,6087],{},"Add"," → ",[120,6090,6091],{},"Geometry",[120,6093,6094],{},"Operations",[120,6096,6097],{},"Transform Geometry",[215,6099,6100,6101,6088,6104,6088,6106,166],{},"Connectez le ",[120,6102,6103],{},"Group Input",[120,6105,6097],{},[120,6107,6108],{},"Group Output",[215,6110,6111],{},"Réglez les valeurs de translation ou d’échelle dans le nœud Transform.",[72,6113,6115],{"className":6114},[34,75],[77,6116],{"src":6117,"className":6118,"alt":12,"loading":82,"width":5389,"height":5390,"srcSet":6119,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png 1314w",[48,6121,6122],{},"Vous verrez immédiatement votre objet bouger ou changer de taille dans l’aperçu. Félicitations, vous venez de construire votre premier modificateur procédural !",[48,6124,6125],{},"Les Geometry Nodes se répartissent en plusieurs grandes catégories, chacune gérant différents aspects de votre scène. Considérez ces catégories comme des boîtes à outils : chacune se concentre sur un type de tâche différent, de la génération de formes au contrôle des données ou des opérations mathématiques en coulisses.",[48,6127,6128],{},"Voici un aperçu rapide des différents types de nœuds pour trouver ceux dont vous avez besoin pour un nouveau workflow :",[61,6130],{},[64,6132,6134],{"id":6133},"_1-input-nodes",[120,6135,6136],{},"1. Nœuds d’entrée (Input Nodes)",[48,6138,6139],{},"Les nœuds d’entrée fournissent les informations de départ pour votre arbre de nœuds. Ils importent des données existantes provenant de votre objet ou de votre scène, comme la position, la normale, l’index ou les informations sur l’objet, que d’autres nœuds peuvent utiliser pour calculer ou transformer la géométrie.",[48,6141,6142],{},"Par exemple, un nœud Input → Scene → Object info vous donne toutes les informations nécessaires sur une instance d’objet pour effectuer des calculs.",[48,6144,6145],{},"Lors de la création d’un nouvel arbre de nœuds, Blender ajoutera toujours un nouveau nœud Group Input représentant le groupe de modèles de la scène actuelle.",[64,6147,6149],{"id":6148},"_2-output-nodes",[120,6150,6151],{},"2. Nœuds de sortie (Output Nodes)",[48,6153,6154],{},"Les nœuds de sortie définissent ce que quitte votre système de nœuds : la géométrie finale que Blender rend ou affiche. Le nœud Group Output est le plus courant : il relie le résultat de l’ensemble de votre réseau de nœuds à votre objet dans la vue.",[48,6156,6157],{},"D’autres sorties spécialisées (comme Material Output dans les configurations de shader) transmettent des données à différentes parties du système de Blender. Dans les Geometry Nodes, l’étape de sortie détermine quelle géométrie, quelles instances ou quelles attributs sont visibles dans le résultat.",[64,6159,6161],{"id":6160},"_3-geometry-nodes",[120,6162,6163],{},"3. Geometry Nodes",[48,6165,6166],{},"Les geometry nodes modifient directement, combinent ou génèrent de la géométrie : les formes réelles de votre scène.",[48,6168,6169],{},"Ce sont le cœur de la modélisation procédurale. Au lieu de sculpter à la main, vous pouvez créer des systèmes qui génèrent automatiquement de la géométrie, puis les ajuster plus tard sans détruire votre maillage de base.",[64,6171,6173],{"id":6172},"_4-mesh-nodes",[120,6174,6175],{},"4. Nœuds de maillage (Mesh Nodes)",[48,6177,6178],{},"Les nœuds de maillage se concentrent sur un contrôle fin des structures de maillage : les sommets, arêtes et faces qui composent votre géométrie. Ils vous permettent d’accéder et de modifier des éléments de maillage spécifiques ou de convertir des types de géométrie.",[48,6180,6181],{},"Quand vous avez besoin d’un contrôle précis de la topologie, choisissez les mesh nodes. Ils sont parfaits pour des tâches de modélisation procédurale comme créer des grilles, manipuler des boucles d’arêtes, ou générer une nouvelle topologie à partir de maillages existants.",[72,6183,6185],{"className":6184},[34,75],[77,6186],{"src":6187,"className":6188,"alt":12,"loading":82,"width":6189,"height":6190,"srcSet":6191,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-da4fe358-ac3b-482a-8641-6b0540c9d792.png",[81],947,897,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-da4fe358-ac3b-482a-8641-6b0540c9d792.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-da4fe358-ac3b-482a-8641-6b0540c9d792.png 947w",[64,6193,6195],{"id":6194},"_5-instance-nodes",[120,6196,6197],{},"5. Nœuds d’instance (Instance Nodes)",[48,6199,6200],{},"Les nœuds d’instance créent des copies (instances) d’objets, dispersées sur des surfaces ou sur des points. Des nœuds comme Instance on Points ou Realize Instances gèrent ce type de tâche.",[48,6202,6203],{},"L’instanciation fait partie des fonctionnalités les plus puissantes des Geometry Nodes, car elle vous permet de dupliquer des milliers d’objets (comme des arbres, des rochers ou des particules) sans ralentir votre scène : vous ne rendez qu’une seule copie « réelle », tout en la référencent plusieurs fois.",[72,6205,6207],{"className":6206},[34,75],[77,6208],{"src":6209,"className":6210,"alt":12,"loading":82,"width":83,"height":6211,"srcSet":6212,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png",[81],1085,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png 1600w",[64,6214,6216],{"id":6215},"_6-attribute-nodes",[120,6217,6218],{},"6. Nœuds d’attribut (Attribute Nodes)",[48,6220,6221],{},"Les nœuds d’attribut contrôlent ou transmettent des propriétés personnalisées attachées à la géométrie, comme la couleur, l’échelle ou des valeurs aléatoires par point. Ces attributs peuvent être utilisés pour piloter des transformations, des matériaux ou des effets.",[48,6223,6224],{},"Les attributs vous permettent d’ajouter de la variation et du contrôle à vos systèmes procéduraux. Vous pouvez randomiser la taille des objets dispersés, changer différemment la couleur des particules, ou lier des effets de matériau aux données de géométrie.",[64,6226,6228],{"id":6227},"_7-utilities-and-fields",[120,6229,6230],{},"7. Utilitaires et champs (Utilities and Fields)",[48,6232,6233],{},"Les nœuds utilitaires gèrent la logique et les opérations mathématiques derrière votre réseau de géométrie. Ils incluent des opérations comme Math, Vector Math, Compare ou Map Range, et sont souvent utilisés pour traiter ou contrôler les entrées d’autres nœuds, comme dans un langage de programmation.",[48,6235,6236],{},"Ce sont les « cerveaux » de votre configuration : ils vous permettent d’établir des relations, de créer des dégradés, de randomiser des valeurs, etc.",[64,6238,6240],{"id":6239},"_8-curve-nodes",[120,6241,6242],{},"8. Nœuds de courbe (Curve Nodes)",[48,6244,6245],{},"Les nœuds de courbe fonctionnent avec une géométrie basée sur les courbes : lignes, splines ou chemins. Ils sont utiles pour générer des câbles, des lianes, des routes ou des traînées de mouvement abstraites. Des nœuds comme Resample Curve, Curve to Mesh et Set Curve Radius vous permettent d’ajuster la forme, la résolution ou l’épaisseur des courbes de façon procédurale.",[48,6247,6248],{},"Les courbes peuvent aussi piloter l’instanciation : vous pouvez placer des objets le long d’un chemin ou animer leur mouvement dans le temps.",[72,6250,6252],{"className":6251},[34,75],[77,6253],{"src":6254,"className":6255,"alt":12,"loading":82,"width":6256,"height":6257,"srcSet":6258,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png",[81],1142,936,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png 1142w",[64,6260,6262],{"id":6261},"_9-grease-pencil-nodes",[120,6263,6264],{},"9. Nœuds Grease Pencil",[48,6266,6267],{},"Les nœuds Grease Pencil intègrent le système de dessin 2D de Blender dans le workflow des Geometry Nodes. Vous pouvez modifier procéduralement des tracés, convertir des dessins en géométrie, ou appliquer des effets comme le bruit, l’extrusion, ou la déformation à des lignes 2D.",[48,6269,6270],{},"Ces nœuds font le pont entre l’animation 2D et le design procédural, offrant aux artistes de nouvelles façons de styliser des motion graphics ou des scènes hybrides 2D/3D.",[64,6272,6274],{"id":6273},"_10-point-nodes",[120,6275,6276],{},"10. Nœuds de point (Point Nodes)",[48,6278,6279],{},"Les nœuds de point manipulent des points individuels dans votre géométrie : les éléments de base qui servent à disperser, positionner ou transformer des instances. Vous pouvez ajouter, déplacer ou faire pivoter des points, ou attribuer des attributs comme la couleur ou l’échelle à chacun.",[48,6281,6282],{},"Par exemple, Distribute Points on Faces génère des points placés uniformément ou aléatoirement sur une surface, qui peuvent ensuite servir de positions de placement pour des instances comme de l’herbe ou des particules.",[64,6284,6286],{"id":6285},"_11-volume-nodes",[120,6287,6288],{},"11. Nœuds de volume (Volume Nodes)",[48,6290,6291],{},"Les nœuds de volume vous permettent de créer et de manipuler des données volumétriques comme le brouillard, la fumée ou des champs de densité procéduraux. Vous pouvez les utiliser pour générer des textures 3D, modeler des nuages, ou remplir une géométrie avec des effets basés sur la densité. Ils ouvrent la porte à des effets atmosphériques ou organiques qui dépassent largement la modélisation de surface.",[64,6293,6295],{"id":6294},"_12-material-nodes",[120,6296,6297],{},"12. Nœuds de matériau (Material Nodes)",[48,6299,6300],{},"Les nœuds de matériau assignent ou modifient des matériaux et des données de shading. Les nœuds Set Material ou Material Index vous permettent d’appliquer dynamiquement différents matériaux en fonction d’attributs, de graines aléatoires, ou de régions de votre modèle.",[48,6302,6303],{},"Cela facilite par exemple le codage couleur de parties d’une structure ou l’assignation procédurale de matériaux à des objets dispersés.",[64,6305,6307],{"id":6306},"_13-texture-nodes",[120,6308,6309],{},"13. Nœuds de texture (Texture Nodes)",[48,6311,6312],{},"Les nœuds de texture échantillonnent ou génèrent des textures procédurales qui peuvent piloter des transformations de géométrie ou des variations visuelles. Ils peuvent fournir des masques en niveaux de gris, des motifs de bruit ou des dégradés qui influencent l’échelle, le déplacement ou la couleur.",[48,6314,6315],{},"En combinant des données de texture avec des nœuds de mathématiques ou d’attributs, vous pouvez créer une randomisation naturelle pour des terrains irréguliers, des surfaces ondulées ou une distribution à motifs.",[64,6317,6319],{"id":6318},"_14-group-nodes",[120,6320,6321],{},"14. Nœuds de groupe (Group Nodes)",[48,6323,6324],{},"Les nœuds de groupe regroupent plusieurs nœuds dans une unité réutilisable. Ils sont essentiels pour organiser des configurations complexes et garder vos arbres de nœuds propres. Vous pouvez exposer des paramètres sur les entrées/sorties du groupe pour qu’ils soient ajustables, transformant ainsi votre configuration personnalisée en un « super nœud ».",[48,6326,6327],{},"Une fois que vous commencez à construire vos propres groupes, vous n’utilisez plus seulement les Geometry Nodes : vous créez vos propres outils procéduraux.",[64,6329,6331],{"id":6330},"_15-hair-nodes",[120,6332,6333],{},"15. Nœuds de cheveux (Hair Nodes)",[48,6335,6336],{},"Les nœuds de cheveux sont conçus pour générer, coiffer et contrôler des systèmes de cheveux ou de fourrure procéduraux. Ils donnent accès à la longueur des mèches, à la densité et aux attributs de grooming, vous permettant de simuler tout, des champs d’herbe aux cheveux d’un personnage.",[48,6338,6339],{},"Ces nœuds remplacent les anciens workflows basés sur les particules par une approche moderne et procédurale, intégrée de manière transparente au nouveau système de cheveux de Blender.",[72,6341,6344,6350],{"className":6342},[34,75,6343],"kg-card-hascaption",[77,6345],{"src":6346,"className":6347,"alt":12,"loading":82,"width":83,"height":6348,"srcSet":6349,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png",[81],916,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png 1600w",[6351,6352,6353],"figcaption",{},[6354,6355,6356],"i",{},[652,6357,6360],{"className":6358,"style":122},[6359],"italic","Source : Blender Stack Exchange",[61,6362],{},[64,6364,6365],{"id":507},[120,6366,508],{},[48,6368,6369],{},"Les Geometry Nodes peuvent sembler abstraits ou intimidants au premier abord, mais ce sont parmi les fonctionnalités les plus passionnantes de Blender. Une fois que vous comprenez comment combiner les nœuds, vous pouvez générer des animations entières, des environnements ou des effets visuels pilotés par une logique procédurale plutôt que par des modifications manuelles.",[48,6371,6372],{},"Ne vous sentez toutefois pas obligé de tout mémoriser. La plupart des configurations de Geometry Nodes s’appuient sur quelques nœuds clés que vous prendrez naturellement en main au fur et à mesure que vous expérimentez.",[48,6374,6375,6379,6380,6383],{},[94,6376,6378],{"href":6377},"https://blog.cg-wire.com/","Dans notre prochain article",", nous irons plus loin : vous apprendrez à ",[94,6381,6382],{"href":1002},"créer vos propres groupes de nœuds personnalisés à l’aide de scripts"," afin d’automatiser des effets tout en réduisant la complexité de vos workflows pour des pipelines d’animation uniques.",[31,6385,6387,6390],{"className":6386},[34,35,36],[31,6388,524],{"className":6389},[40],[31,6391,1786,6393,6396],{"className":6392},[45],[94,6394,534],{"href":531,"rel":6395},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent des bonnes pratiques et organisent parfois des événements en présentiel. Nous serions ravis de vous accueillir ! 😊",[31,6398,6400],{"className":6399},[34,539,540],[94,6401,546],{"href":531,"className":6402},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":6404},[6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423],{"id":5987,"depth":548,"text":5990},{"id":6010,"depth":548,"text":6013},{"id":6052,"depth":548,"text":6055},{"id":6133,"depth":548,"text":6136},{"id":6148,"depth":548,"text":6151},{"id":6160,"depth":548,"text":6163},{"id":6172,"depth":548,"text":6175},{"id":6194,"depth":548,"text":6197},{"id":6215,"depth":548,"text":6218},{"id":6227,"depth":548,"text":6230},{"id":6239,"depth":548,"text":6242},{"id":6261,"depth":548,"text":6264},{"id":6273,"depth":548,"text":6276},{"id":6285,"depth":548,"text":6288},{"id":6294,"depth":548,"text":6297},{"id":6306,"depth":548,"text":6309},{"id":6318,"depth":548,"text":6321},{"id":6330,"depth":548,"text":6333},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1639322537504-6427a16b0a28?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fGJsZW5kZXIlMjBnZW9tZXRyeSUyMG5vZGVzfGVufDB8fHx8MTc2Mjc1NzU1NXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":5950,"featured_at":561,"visibility":562},"/blog-i18n/fr/blender-scripting-geometry-nodes","2025-11-10T10:00:00.000+01:00",{"title":5962,"description":12},"blender-scripting-geometry-nodes","blog-i18n/fr/blender-scripting-geometry-nodes/index",[6432],{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"fADd8ighNDXuLTK56sxg8BApk5doMpRZ5wdt7YKci1A",{"id":6435,"title":6436,"authors":6437,"body":6439,"description":12,"extension":557,"feature_image":7181,"html":7,"meta":7182,"navigation":13,"path":7184,"published_at":7185,"seo":7186,"slug":7187,"stem":7188,"tags":7189,"__hash__":7192,"updated_at":7183,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/blender-shaders-explained/index.md","Travailler avec les shaders Blender (2026) : Nodes & scripting",[6438],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":6440,"toc":7164},[6441,6452,6459,6462,6465,6471,6473,6479,6482,6491,6496,6513,6516,6530,6539,6541,6547,6550,6553,6556,6563,6577,6584,6587,6589,6595,6601,6609,6614,6617,6654,6659,6662,6670,6676,6679,6717,6723,6726,6746,6752,6755,6781,6787,6790,6816,6822,6825,6851,6857,6860,6868,6874,6877,6891,6893,6899,6906,6909,6912,6937,6943,6946,6966,6969,6992,6995,7028,7032,7035,7079,7082,7092,7098,7108,7110,7114,7121,7132,7146,7158],[31,6442,6444,6448],{"className":6443},[34,35,36],[31,6445,6447],{"className":6446},[40],"🎨",[31,6449,6451],{"className":6450},[45],"Les shaders ne sont pas de la magie : ce sont des recettes visuelles que vous pouvez contrôler et automatiser.",[48,6453,6454,6455,6458],{},"La première fois que vous entendez le mot ",[652,6456,6457],{},"shader",", il est facile de paniquer. Quelqu’un mentionne GLSL, les GPU se mettent à transpirer, et vous imaginez soudain des murs de code illisible pendant que le ventilateur de votre ordinateur hurle, demandant grâce.",[48,6460,6461],{},"oVoici la partie que personne ne vous dit assez tôt : vous n’avez pas besoin d’être mathématicien ou programmeur en informatique graphique pour utiliser des shaders. On ne vous demande pas d’écrire du code GPU bas niveau, ni de comprendre toutes les équations derrière la physique de la lumière. Blender n’attend pas cela de vous. À la place, il vous donne des nœuds : des briques visuelles qui ressemblent plus à du Lego qu’à du code. Vous assemblez les éléments, vous voyez le résultat instantanément, puis vous ajustez jusqu’à ce que ça vous semble juste.",[48,6463,6464],{},"Pensez aux shaders moins comme du code et plus comme des recettes. Vous mélangez des valeurs, des textures et de la logique pour décrire comment une surface doit réagir à la lumière. Parfois, vous suivrez une recette connue, parfois vous improviserez, et parfois vous casserez des choses juste pour voir ce qui se passe. C’est comme ça que vous apprendrez.",[48,6466,6467,6470],{},[120,6468,6469],{},"Dans cet article, nous allons démystifier ce qu’est réellement l’ombrage, enlever la peur qui l’entoure, et explorer comment manipuler les shaders de manière procédurale avec le système de nœuds de Blender ou, un peu, avec du scripting pour une chaîne de production d’animation."," À la fin, l’ombrage ne ressemblera plus à une pièce interdite.",[61,6472],{},[64,6474,6476],{"id":6475},"whats-a-shader",[120,6477,6478],{},"Qu’est-ce qu’un Shader ?",[48,6480,6481],{},"Pour comprendre les shaders, il faut arrêter de penser aux « couleurs » et commencer à penser à la « physique ».",[48,6483,6484,6490],{},[94,6485,6487],{"href":6486},"https://blog.cg-wire.com/hard-surface-modeling/",[1919,6488,6489],{},"Si vous peignez une chaise en bois en rouge dans le monde réel",", vous ne changez pas seulement sa couleur. Vous ajoutez une couche de matériau qui interagit avec la lumière. Cette peinture rouge possède une rugosité spécifique (dans quelle mesure elle diffuse la lumière), une spécularité spécifique (à quel point elle est brillante) et un indice de réfraction spécifique.",[48,6492,6493],{},[120,6494,6495],{},"Un shader est un ensemble d’instructions qui dit à l’ordinateur comment simuler cette interaction avec la lumière.",[72,6497,6499,6505],{"className":6498},[34,75,6343],[77,6500],{"src":6501,"className":6502,"alt":12,"loading":82,"width":83,"height":6503,"srcSet":6504,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png",[81],1067,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png 1600w",[6351,6506,6507],{},[6354,6508,6509],{},[652,6510,6512],{"className":6511,"style":122},[6359],"Source : TurboSquid",[48,6514,6515],{},"Quand un rayon de lumière issu de votre soleil numérique frappe la surface de votre objet, le shader intervient et demande :",[212,6517,6518,6521,6524,6527],{},[215,6519,6520],{},"« Vous réfléchissez ? » (Réflexion)",[215,6522,6523],{},"« Vous traversez ? » (Transmission/Verre)",[215,6525,6526],{},"« Vous vous faites piéger à l’intérieur ? » (Absorption)",[215,6528,6529],{},"« Vous diffusez sous la peau ? » (Subsurface Scattering)",[48,6531,6532,6533],{},"Si vous modélisez une rue pavée mouillée, une simple texture image la fait ressembler à une photo plate d’une rue. Un shader indique au moteur de rendu que l’eau dans les fissures est parfaitement réfléchissante et lisse, tandis que la pierre est rugueuse et terne. Il dit à la lumière de rebondir différemment sur les parties mouillées que sur les parties sèches.",[94,6534,1917,6536],{"href":6535},"https://blog.cg-wire.com/how-light-shapes-emotion-in-animation/",[1919,6537,6538],{},"La lumière façonne la réalité.",[61,6540],{},[64,6542,6544],{"id":6543},"why-you-must-master-shader-nodes",[120,6545,6546],{},"Pourquoi Vous Devez Maîtriser les Nodes de Shader",[48,6548,6549],{},"Vous pourriez vous demander : « Pourquoi ne pas simplement télécharger des textures ? »",[48,6551,6552],{},"La numérisation de photos est excellente, mais le shading procédural offre trois super-pouvoirs que des images fixes ne peuvent pas égaler.",[48,6554,6555],{},"Quand vous utilisez une texture image (JPG ou PNG), vous êtes limité par les pixels. Si vous zoomez trop près d’un mur, elle devient floue.",[48,6557,6558,6559,6562],{},"Les shaders utilisent les mathématiques. ",[120,6560,6561],{},"Les mathématiques n’ont aucune limite de résolution."," Vous pouvez zoomer sur une rayure procédurale dans le métal jusqu’à voir les micro-reliefs, et cela restera net. Même si vous avez un modèle dont vous êtes fier, avec une topologie propre et de belles proportions, il aura quand même l’air plat sans shaders.",[48,6564,6565,6566,6569,6570,6573,6574,6576],{},"Les nodes de shader de Blender rendent le ",[120,6567,6568],{},"fait d’ajuster vos textures de manière cohérente"," incroyablement simple. Prenons un exemple : vous texturez un vaisseau spatial. Vous appliquez de la rouille sur la coque à l’aide d’une texture. Votre directeur artistique arrive et dit : « D’accord, mais le vaisseau a l’air trop vieux. Réduis la rouille de 50 %. » Si vous l’avez peinte à la main, vous devez tout recommencer ou passer des heures à effacer. Avec les nodes de shader, vous repérez simplement la valeur « Rust Amount » que vous avez créée, puis vous la faites passer de ",[155,6571,6572],{},"1.0"," à ",[155,6575,5639],{},". C’est fait.",[48,6578,6579,6580,6583],{},"Les textures statiques donnent une impression figée, mais ",[120,6581,6582],{},"les shaders peuvent aussi être animés",". Vous pouvez construire un setup de shader où de la mousse pousse sur une roche au fil du temps en fonction du numéro de frame, ou bien un bouclier qui s’illumine davantage quand il se fait toucher. Les shaders permettent à vos matériaux de réagir à l’environnement.",[48,6585,6586],{},"Pour toutes ces raisons, apprendre à maîtriser les nodes de shader est un énorme levier pour les artistes professionnels qui ont des délais serrés.",[61,6588],{},[64,6590,6592],{"id":6591},"the-different-types-of-shader-nodes",[120,6593,6594],{},"Les Différents Types de Nodes de Shader",[48,6596,6597,6598,6600],{},"Le système de nœuds de Blender fonctionne comme un organigramme. Vous cliquez sur ",[155,6599,6087],{}," pour ajouter des nœuds et les relier entre eux. Les données circulent de gauche à droite. Pour exploiter chaque fonctionnalité, vous devez comprendre les différents types de nœuds disponibles.",[72,6602,6604],{"className":6603},[34,75],[77,6605],{"src":6606,"className":6607,"alt":12,"loading":82,"width":83,"height":84,"srcSet":6608,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png 1600w",[1085,6610,6611],{"id":6133},[120,6612,6613],{},"1. Nodes d’entrée",[48,6615,6616],{},"Les nodes d’entrée fournissent des données depuis la scène, l’objet, la géométrie ou des valeurs définies par l’utilisateur, vers le réseau de shader.",[212,6618,6619,6625,6630,6636,6642,6648],{},[215,6620,6621,6624],{},[120,6622,6623],{},"Texture Coordinate"," - Fournit les coordonnées UV, objet, générées et caméra + utilisez la sortie UV pour mapper correctement une texture image sur un modèle déplié en UV",[215,6626,6627,6629],{},[120,6628,6091],{}," - Donne des informations géométriques comme les normales et l’« aspect pointu » + utilisez Pointiness pour créer une accumulation de saleté dans les creux",[215,6631,6632,6635],{},[120,6633,6634],{},"Fresnel"," - Calcule la réflectivité basée sur l’angle de vue + utilisez-le pour créer des réflexions plus fortes sur les bords du verre",[215,6637,6638,6641],{},[120,6639,6640],{},"Object Info"," - Fournit des données par objet comme des valeurs aléatoires ou la couleur de l’objet + utilisez la sortie Random pour donner à chaque objet une couleur légèrement différente",[215,6643,6644,6647],{},[120,6645,6646],{},"Value"," - Sort une valeur numérique constante + utilisez-la pour contrôler la rugosité avec un seul curseur",[215,6649,6650,6653],{},[120,6651,6652],{},"Color"," - Sort une valeur de couleur constante + utilisez-la comme couleur de base pour un matériau stylisé",[1085,6655,6656],{"id":6148},[120,6657,6658],{},"2. Nodes de sortie",[48,6660,6661],{},"Les nodes de sortie définissent le résultat final d’un shader et connectent le réseau de nœuds au système de rendu de Blender.",[212,6663,6664],{},[215,6665,6666,6669],{},[120,6667,6668],{},"Material Output"," - Sort les données finales de surface, de volume et de displacement + connectez un Principled BSDF à l’entrée Surface",[1085,6671,6673],{"id":6672},"_3-shader-nodes",[120,6674,6675],{},"3. Nodes de shader",[48,6677,6678],{},"Les nodes de shader définissent comment la lumière interagit avec une surface, y compris la réflexion, la réfraction et l’émission.",[212,6680,6681,6687,6693,6699,6705,6711],{},[215,6682,6683,6686],{},[120,6684,6685],{},"Principled BSDF"," - Shader de surface tout-en-un basé sur la physique + créez des matériaux réalistes en métal, plastique ou peau",[215,6688,6689,6692],{},[120,6690,6691],{},"Diffuse BSDF"," - Produit des surfaces mates et non réfléchissantes + utilisez-le pour la craie, l’argile ou la pierre non polie",[215,6694,6695,6698],{},[120,6696,6697],{},"Glossy BSDF"," - Produit des réflexions comme un miroir + utilisez-le pour le métal poli ou des miroirs",[215,6700,6701,6704],{},[120,6702,6703],{},"Glass BSDF"," - Combine réfraction et réflexion + utilisez-le pour des fenêtres ou des bouteilles en verre",[215,6706,6707,6710],{},[120,6708,6709],{},"Emission"," - Émet de la lumière depuis une surface + utilisez-le pour des écrans, des LED ou des enseignes néon",[215,6712,6713,6716],{},[120,6714,6715],{},"Mix Shader"," - Mélange deux sorties de shader + mélangez des shaders diffuse et glossy pour du métal usé",[1085,6718,6720],{"id":6719},"_4-displacement-nodes",[120,6721,6722],{},"4. Nodes de displacement",[48,6724,6725],{},"Les nodes de displacement modifient le détail de la surface en agissant sur la géométrie ou sur les normales d’ombrage.",[212,6727,6728,6734,6740],{},[215,6729,6730,6733],{},[120,6731,6732],{},"Displacement"," - Réalise un vrai déplacement géométrique + créez une profondeur réelle dans un mur en briques grâce à une height map (Cycles)",[215,6735,6736,6739],{},[120,6737,6738],{},"Bump"," - Simule le détail de surface via une perturbation des normales + ajoutez de fines rayures sans augmenter la géométrie",[215,6741,6742,6745],{},[120,6743,6744],{},"Normal Map"," - Convertit des textures de normales en données de normales utilisables + appliquez une normal map cuite depuis un asset de jeu",[1085,6747,6749],{"id":6748},"_5-color-nodes",[120,6750,6751],{},"5. Nodes de couleur",[48,6753,6754],{},"Les nodes de couleur ajustent, mélangent et transforment l’information de couleur au sein du réseau de shader.",[212,6756,6757,6763,6769,6775],{},[215,6758,6759,6762],{},[120,6760,6761],{},"Mix Color"," - Mélange deux couleurs ou textures + mélangez une texture de saleté sur une couleur de base propre",[215,6764,6765,6768],{},[120,6766,6767],{},"RGB Curves"," - Ajuste le contraste et l’équilibre des couleurs + augmentez le contraste de la texture sans retoucher l’image",[215,6770,6771,6774],{},[120,6772,6773],{},"Hue/Saturation"," - Modifie la teinte, la saturation et la valeur + teintez un matériau en bleu sans repeindre les textures",[215,6776,6777,6780],{},[120,6778,6779],{},"Invert"," - Inverse les valeurs de couleur + inversez une map de rugosité pour créer une map de brillance",[1085,6782,6784],{"id":6783},"_6-texture-nodes",[120,6785,6786],{},"6. Nodes de texture",[48,6788,6789],{},"Les nodes de texture génèrent ou chargent des images et des textures procédurales pour les matériaux.",[212,6791,6792,6798,6804,6810],{},[215,6793,6794,6797],{},[120,6795,6796],{},"Image Texture"," - Charge des fichiers d’image externes + utilisez une albedo map pour un matériau PBR",[215,6799,6800,6803],{},[120,6801,6802],{},"Noise Texture"," - Génère un bruit procédural lisse + ajoutez une variation subtile de rugosité au plastique",[215,6805,6806,6809],{},[120,6807,6808],{},"Voronoi Texture"," - Produit des motifs basés sur des cellules + créez des fissures, des échelles ou des dalles de pierre",[215,6811,6812,6815],{},[120,6813,6814],{},"Gradient Texture"," - Sort des dégradés lisses + utilisez-les comme masque pour mélanger des matériaux",[1085,6817,6819],{"id":6818},"_7-utility-nodes",[120,6820,6821],{},"7. Nodes utilitaires",[48,6823,6824],{},"Les nodes utilitaires réalisent des opérations mathématiques et des conversions de données.",[212,6826,6827,6833,6839,6845],{},[215,6828,6829,6832],{},[120,6830,6831],{},"Mapping"," - Transforme les coordonnées de texture + met à l’échelle et fait tourner un motif de texture",[215,6834,6835,6838],{},[120,6836,6837],{},"Math"," - Effectue des opérations numériques + limite les valeurs de rugosité pour éviter les extrêmes",[215,6840,6841,6844],{},[120,6842,6843],{},"Vector Math"," - Réalise des calculs basés sur les vecteurs + modifie les vecteurs de normales ou de direction",[215,6846,6847,6850],{},[120,6848,6849],{},"Clamp"," - Limite les valeurs à une plage donnée + évite les valeurs d’émission trop lumineuses",[1085,6852,6854],{"id":6853},"_8-group-nodes",[120,6855,6856],{},"8. Nodes de groupe",[48,6858,6859],{},"Les nodes de groupe emballent plusieurs nœuds dans des composants réutilisables et organisés.",[212,6861,6862],{},[215,6863,6864,6867],{},[120,6865,6866],{},"Node Group"," - Encapsule des setups de nœuds complexes + créez un « Rust Shader » réutilisable utilisé sur plusieurs assets",[1085,6869,6871],{"id":6870},"_9-layout-nodes",[120,6872,6873],{},"9. Nodes de mise en page",[48,6875,6876],{},"Les nodes de mise en page organisent le graphe de nœuds visuellement et n’affectent pas le rendu.",[212,6878,6879,6885],{},[215,6880,6881,6884],{},[120,6882,6883],{},"Frame"," - Regroupe visuellement les nœuds liés + cadre tous les nœuds liés aux textures ensemble",[215,6886,6887,6890],{},[120,6888,6889],{},"Reroute"," - Redirige les connexions de nœuds pour plus de clarté + nettoie les connexions enchevêtrées",[61,6892],{},[64,6894,6896],{"id":6895},"the-next-level-scripting-your-shaders",[120,6897,6898],{},"Niveau supérieur : Scripter vos shaders",[48,6900,6901,6902,6905],{},"Quand vous êtes à l’aise pour connecter les nœuds manuellement, vous pouvez créer du bois, du plastique, de l’or, ou n’importe quel type de matériau. Mais ",[120,6903,6904],{},"et si vous avez une scène avec 500 objets uniques, et que vous devez générer une variation aléatoire"," d’un matériau métallique usé pour chacun, avec quelques ajustements ?",[48,6907,6908],{},"C’est là que le scripting Python devient essentiel. Vous pouvez l’utiliser pour vous assurer que chaque matériau de votre projet suit la même structure de nœuds. Vous pouvez écrire un script qui dit : « Rendez ce matériau rouge, mais faites varier légèrement la teinte avec un nombre aléatoire pour chaque objet. »",[48,6910,6911],{},"Passons à l’action. Nous allons écrire un script Python qui crée un nouveau matériau, ajoute un Principled BSDF, génère une texture de bruit pour contrôler la couleur, puis connecte tout ensemble.",[31,6913,6915,6918],{"className":6914},[34,35,108],[31,6916,112],{"className":6917},[40],[31,6919,6921,6925,6927,129,6929,6931,134,6933],{"className":6920},[45],[117,6922,6923],{},[120,6924,1889],{"style":122},[125,6926],{},[125,6928],{},[125,6930],{},[125,6932],{},[94,6934,6936],{"href":6935},"https://github.com/cgwire/blog-tutorials/tree/main/blender-shaders?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/blender-shaders",[48,6938,3361,6939,6942],{},[652,6940,6941],{},"Scripting"," dans Blender, créez un nouveau bloc de texte, puis suivez.",[48,6944,6945],{},"D’abord, nous devons importer la bibliothèque et indiquer à Blender que nous voulons créer un nouveau matériau.",[152,6947,6948,6960],{},[155,6949,6951,6952,6954,6957],{"className":6950},[175],"import random\n",[48,6953,1662],{},[48,6955,6956],{},"def create_procedural_material(mat_name):\n    mat = bpy.data.materials.new(name=mat_name)",[48,6958,6959],{},"    mat.use_nodes = True\n    nodes = mat.node_tree.nodes\n    links = mat.node_tree.links",[48,6961,6962],{},[155,6963,6965],{"className":6964},[175],"    nodes.clear()",[48,6967,6968],{},"Maintenant, ajoutons les nœuds. Pensez-y comme si vous sortiez des éléments du menu « Add », mais de façon programmatique :",[152,6970,6971,6978],{},[155,6972,6974,6975],{"className":6973},[175],"    node_output = nodes.new(type='ShaderNodeOutputMaterial')\n    node_output.location = (400, 0)",[48,6976,6977],{},"    node_principled = nodes.new(type='ShaderNodeBsdfPrincipled')\n    node_principled.location = (0, 0)",[48,6979,6980],{},[155,6981,6983,6984,6987,6988,6991],{"className":6982},[175],"    node_principled.inputs",[262,6985,6986],{},"'Roughness'",".default_value = 0.2\n    node_principled.inputs",[262,6989,6990],{},"'Metallic'",".default_value = 1.0",[48,6993,6994],{},"Maintenant, rendons-le intéressant. Nous allons ajouter une Noise Texture et une ColorRamp pour générer un motif de couleur aléatoire.",[152,6996,6997,7018],{},[155,6998,7000,7001,7004,7005,7008,7009,7012],{"className":6999},[175],"node_noise = nodes.new(type='ShaderNodeTexNoise')\n    node_noise.location = (-600, 0)\n    node_noise.inputs",[262,7002,7003],{},"'Scale'",".default_value = 15.0\n    node_noise.inputs",[262,7006,7007],{},"'Detail'",".default_value = 10.0",[48,7010,7011],{},"    node_ramp = nodes.new(type='ShaderNodeValToRGB')\n    node_ramp.location = (-300, 0)",[48,7013,7014,7015,7017],{},"    node_ramp.color_ramp.elements",[262,7016,264],{},".color = (0.1, 0.1, 0.1, 1)",[48,7019,7020],{},[155,7021,7023,7024,7027],{"className":7022},[175],"    rand_r = random.random()\n    rand_g = random.random()\n    rand_b = random.random()\n    node_ramp.color_ramp.elements",[262,7025,7026],{},"1",".color = (rand_r, rand_g, rand_b, 1)",[48,7029,7030],{},[125,7031],{},[48,7033,7034],{},"Enfin, il faut tout câbler et appliquer ce nouveau shader au contexte actuel (le cube par défaut) :",[152,7036,7037,7073],{},[155,7038,7040,7041,7044,7045,1330,7047,7057,7067,7070],{"className":7039},[175],"    links.new(node_noise.outputs",[262,7042,7043],{},"'Fac'",", node_ramp.inputs",[262,7046,7043],{},[48,7048,7049,7050,7053,7054,1330],{},"    links.new(node_ramp.outputs",[262,7051,7052],{},"'Color'",", node_principled.inputs",[262,7055,7056],{},"'Base Color'",[48,7058,7059,7060,7063,7064,1330],{},"    links.new(node_principled.outputs",[262,7061,7062],{},"'BSDF'",", node_output.inputs",[262,7065,7066],{},"'Surface'",[48,7068,7069],{},"    return mat",[48,7071,7072],{},"my_new_mat = create_procedural_material(\"SciFi_Metal_Random\")",[48,7074,7075],{},[155,7076,7078],{"className":7077},[175],"bpy.context.object.data.materials.append(my_new_mat)",[48,7080,7081],{},"Copiez ce code dans votre éditeur de texte et appuyez sur « Run Script » (le bouton Play). Regardez votre objet actif. Il s’agit maintenant d’une surface métallique avec un motif de bruit de couleur aléatoire. Lancez-le à nouveau (changez le nom dans l’appel de fonction) et vous obtiendrez une autre couleur.",[72,7083,7085],{"className":7084},[34,75],[77,7086],{"src":7087,"className":7088,"alt":12,"loading":82,"width":7089,"height":7090,"srcSet":7091,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png",[81],1268,827,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png 1268w",[48,7093,7094,7095],{},"Félicitations, ",[120,7096,7097],{},"vous venez de créer un générateur de matériau procédural !",[48,7099,7100,7101,7107],{},"Jetez un œil à",[94,7102,1917,7104],{"href":6935,"rel":7103},[533],[1919,7105,7106],{},"notre dépôt GitHub associé"," pour jouer avec le code !",[61,7109],{},[64,7111,7112],{"id":507},[120,7113,508],{},[48,7115,7116,7117,7120],{},"Les shaders ne servent pas qu’à colorer à l’intérieur des lignes. Ce sont la peau de votre monde numérique. ",[120,7118,7119],{},"Ils racontent l’histoire de l’objet"," : depuis quand il a l’air vieux, où il est passé, et de quoi il est fait.",[48,7122,7123,7124,7127,7128,7131],{},"En comprenant la logique des nodes de shader, ",[120,7125,7126],{},"vous pouvez créer tout, de la peau photoréaliste au feu de cartoon stylisé",". Et en faisant le pas vers le scripting Python, vous débloquez la capacité de ",[120,7129,7130],{},"travailler plus vite et plus intelligemment",", en automatisant les parties fastidieuses du travail pour que vous puissiez vous concentrer sur l’art.",[48,7133,7134,7135,7138,7139,7145],{},"Mais ce n’est qu’une pièce du puzzle. Vous pouvez changer la surface, mais qu’en est-il de la forme ? La prochaine étape logique de votre parcours, c’est ",[652,7136,7137],{},"Geometry Nodes",". Tout comme les Shader Nodes contrôlent la couleur et la lumière de manière procédurale, les Geometry Nodes contrôlent le maillage et la structure de manière programmatique.",[94,7140,1917,7142],{"href":7141},"https://blog.cg-wire.com/blender-scripting-geometry-nodes-2/",[1919,7143,7144],{},"Jetez un œil à notre article dédié"," pour créer des scènes entières à partir de code !",[31,7147,7149,7152],{"className":7148},[34,35,36],[31,7150,524],{"className":7151},[40],[31,7153,1786,7155,535],{"className":7154},[45],[94,7156,534],{"href":531,"rel":7157},[533],[31,7159,7161],{"className":7160},[34,539,540],[94,7162,1797],{"href":531,"className":7163},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":7165},[7166,7167,7168,7179,7180],{"id":6475,"depth":548,"text":6478},{"id":6543,"depth":548,"text":6546},{"id":6591,"depth":548,"text":6594,"children":7169},[7170,7171,7172,7173,7174,7175,7176,7177,7178],{"id":6133,"depth":1803,"text":6613},{"id":6148,"depth":1803,"text":6658},{"id":6672,"depth":1803,"text":6675},{"id":6719,"depth":1803,"text":6722},{"id":6748,"depth":1803,"text":6751},{"id":6783,"depth":1803,"text":6786},{"id":6818,"depth":1803,"text":6821},{"id":6853,"depth":1803,"text":6856},{"id":6870,"depth":1803,"text":6873},{"id":6895,"depth":548,"text":6898},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1664526936810-ec0856d31b92?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fHNoYWRlciUyMG5vZGVzfGVufDB8fHx8MTc2NzYwMzU4M3ww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":7183,"featured_at":561,"visibility":562},"2026-03-26T09:56:11.000+01:00","/blog-i18n/fr/blender-shaders-explained","2026-01-05T10:35:18.000+01:00",{"title":6436,"description":12},"blender-shaders-explained","blog-i18n/fr/blender-shaders-explained/index",[7190,7191],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"ClBBnYQeZn8xIGKZGK6f7s_mmtJ5tCppbG4Y3vsBv3M",{"id":7194,"title":7195,"authors":7196,"body":7198,"description":12,"extension":557,"feature_image":7747,"html":7,"meta":7748,"navigation":13,"path":7750,"published_at":7751,"seo":7752,"slug":7753,"stem":7754,"tags":7755,"__hash__":7758,"updated_at":7749,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/dcc-integration-blender-kitsu/index.md","De Blender à Kitsu : comment créer une passerelle DCC personnalisée (2026)",[7197],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":7199,"toc":7738},[7200,7210,7222,7225,7228,7231,7233,7239,7246,7255,7271,7273,7279,7282,7288,7295,7302,7305,7308,7310,7316,7341,7344,7347,7353,7356,7363,7377,7380,7383,7391,7400,7410,7415,7423,7428,7438,7441,7447,7450,7475,7486,7488,7494,7497,7500,7520,7554,7557,7565,7568,7574,7584,7586,7592,7595,7598,7618,7621,7624,7633,7636,7642,7645,7655,7657,7663,7666,7689,7699,7701,7705,7708,7711,7720,7732],[31,7201,7203,7206],{"className":7202},[34,35,36],[31,7204,4377],{"className":7205},[40],[31,7207,7209],{"className":7208},[45],"Avez-vous déjà souhaité que vos outils créatifs puissent communiquer avec votre outil de suivi de production ? Avec une intégration DCC sur mesure, c’est enfin possible — fini les téléversements manuels, les versions qui ne correspondent pas, ou la perte de temps entre Blender et Kitsu.",[48,7211,7212,7213,655,7215,309,7218,7221],{},"Les artistes s’appuient sur des outils de création de contenu numérique (DCC) comme ",[120,7214,1828],{},[120,7216,7217],{},"Maya",[120,7219,7220],{},"Houdini"," pour donner vie aux histoires.",[48,7223,7224],{},"Mais si le travail créatif se fait dans ces outils, le suivi de production se fait ailleurs. Cette déconnexion peut entraîner des décalages de versions, du temps perdu dans des téléversements manuels répétitifs, et au final moins de temps consacré à la création. Sans connexion fluide entre le logiciel DCC et votre outil de suivi, votre pipeline en pâtit.",[48,7226,7227],{},"C’est là que les intégrations sur mesure entrent en jeu.",[48,7229,7230],{},"Dans cet article, nous passons en revue les bases de la création d’une intégration Blender dans Kitsu, similaire à Kitsu Publisher, pour publier des aperçus de modèles 3D depuis Blender vers Kitsu.",[61,7232],{},[64,7234,7236],{"id":7235},"what%E2%80%99s-a-dcc-integration",[120,7237,7238],{},"Qu’est-ce qu’une intégration DCC ?",[48,7240,7241,7242,7245],{},"Une intégration DCC est ",[120,7243,7244],{},"un pont entre un logiciel de création et un autre outil",", comme un outil de suivi de production.",[48,7247,7248,7249,166],{},"Par exemple, au lieu d’exporter des fichiers, d’ouvrir un navigateur web et de téléverser manuellement des versions, une intégration pourrait",[94,7250,1917,7252],{"href":7251},"https://blog.cg-wire.com/working-with-multiple-digital-content-creation-tools/",[1919,7253,7254],{},"permettre aux artistes de publier directement depuis l’outil de leur choix",[48,7256,7257,7258,4412,7264,7270],{},"Les intégrations peuvent gérer des tâches telles que",[94,7259,1917,7261],{"href":7260},"https://blog.cg-wire.com/rendering-explained/",[1919,7262,7263],{},"la gestion de pipelines de rendu complexes",[94,7265,1917,7267],{"href":7266},"https://blog.cg-wire.com/animation-asset-storage/",[1919,7268,7269],{},"la gestion du stockage des assets et du versionnage",", ou encore générer des images d’aperçu : elles automatisent les parties ennuyeuses de la production pour que les artistes puissent se concentrer sur la narration.",[61,7272],{},[64,7274,7276],{"id":7275},"why-dcc-integration",[120,7277,7278],{},"Pourquoi une intégration DCC ?",[48,7280,7281],{},"À terme, chaque studio rencontre le même goulot d’étranglement : à mesure que les projets grossissent, les processus manuels se dégradent.",[48,7283,7284,7287],{},[120,7285,7286],{},"Les intégrations font gagner du temps"," en supprimant les changements de contexte entre logiciels.",[48,7289,7290,7291,7294],{},"Elles ",[120,7292,7293],{},"réduisent aussi les erreurs en standardisant les tâches répétitives"," comme la livraison de résultats en imposant des conventions de nommage, des formats et une cohérence des métadonnées.",[48,7296,7297,7298,7301],{},"Enfin, mais pas des moindres, elles ",[120,7299,7300],{},"améliorent la gestion de projet et la communication"," en fournissant des mises à jour en temps réel aux superviseurs et aux producteurs.",[48,7303,7304],{},"Tous les studios d’animation professionnels s’appuient sur un pipeline, et les intégrations DCC sont essentielles.",[48,7306,7307],{},"Pour vous donner un exemple concret, essayons de créer une intégration sous forme de script qui téléverse un aperçu depuis Blender vers Kitsu afin de faciliter la revue du travail avec votre équipe.",[61,7309],{},[64,7311,7313],{"id":7312},"_1-getting-started",[120,7314,7315],{},"1. Bien démarrer",[31,7317,7319,7322],{"className":7318},[34,35,4456],[31,7320,112],{"className":7321},[40],[31,7323,7325,7329,7331,6041,7333,7335,134,7337],{"className":7324},[45],[117,7326,7327],{},[120,7328,123],{"style":122},[125,7330],{},[125,7332],{},[125,7334],{},[125,7336],{},[94,7338,7340],{"href":7339},"https://github.com/cgwire/blender-kitsu-dcc-integration-example?ref=blog.cg-wire.com","github.com/cgwire/blender-kitsu-dcc-integration-example",[48,7342,7343],{},"Avant de nous lancer dans la programmation, configurons d’abord une instance locale de Kitsu afin de pouvoir tester notre intégration en toute sécurité.",[48,7345,7346],{},"Le moyen le plus simple de lancer Kitsu en local consiste à utiliser le dépôt kitsu-docker. Clonez le dépôt sur votre machine et suivez les instructions :",[152,7348,7349],{},[155,7350,7352],{"className":7351},[158],"git clone \u003Chttps://github.com/cgwire/kitsu-docker.git>\ncd kitsu-docker\ndocker build -t cgwire/cgwire .\ndocker run --init -ti --rm -p 80:80 -p 1080:1080 --name cgwire cgwire/cgwire",[48,7354,7355],{},"Cela démarre tous les services nécessaires : Kitsu, la base de données postgres et les composants de support.",[48,7357,7358,7359,7362],{},"Une fois les conteneurs lancés, ouvrez ",[155,7360,7361],{},"http://localhost:80"," dans votre navigateur. Utilisez les identifiants par défaut :",[212,7364,7365,7371],{},[215,7366,7367,7370],{},[120,7368,7369],{},"Email"," : admin@example.com",[215,7372,7373,7376],{},[120,7374,7375],{},"Mot de passe :"," mysecretpassword",[48,7378,7379],{},"Vous serez redirigé vers le tableau de bord Kitsu.",[48,7381,7382],{},"Avant de pouvoir téléverser des aperçus, il nous faut une cible pour les téléverser. Dans Kitsu :",[1692,7384,7385],{},[215,7386,7387,7388,7390],{},"Créez une nouvelle production (par exemple, Blender Test Project) en allant sur la page \"",[120,7389,3325],{},"\" dans la barre latérale.",[72,7392,7394],{"className":7393},[34,75],[77,7395],{"src":7396,"className":7397,"alt":12,"loading":82,"width":7398,"height":7399},"https://blog.cg-wire.com/content/images/2025/10/CleanShot-2025-10-13-at-9---.26.46-1.png",[81],206,479,[72,7401,7403],{"className":7402},[34,75],[77,7404],{"src":7405,"className":7406,"alt":12,"loading":82,"width":7407,"height":7408,"srcSet":7409,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-0e43401b-afb6-4345-b773-db3d9b03bed3.png",[81],946,914,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-0e43401b-afb6-4345-b773-db3d9b03bed3.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-0e43401b-afb6-4345-b773-db3d9b03bed3.png 946w",[1692,7411,7412],{"start":548},[215,7413,7414],{},"Dans la production, créez un asset.",[72,7416,7418],{"className":7417},[34,75],[77,7419],{"src":7420,"className":7421,"alt":12,"loading":82,"width":7407,"height":7408,"srcSet":7422,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-83cce3b0-70a0-486d-87e7-4914a5304262.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-83cce3b0-70a0-486d-87e7-4914a5304262.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-83cce3b0-70a0-486d-87e7-4914a5304262.png 946w",[1692,7424,7425],{"start":1803},[215,7426,7427],{},"La création d’un asset ajoute automatiquement de nouvelles tâches pour toutes les catégories de tâches sélectionnées lors de la création de la production. Nous pouvons les utiliser pour téléverser les aperçus.",[48,7429,7430,7431,7437],{},"Pour interagir avec Kitsu par programme,",[94,7432,1917,7434],{"href":7433},"https://github.com/cgwire/gazu?ref=blog.cg-wire.com",[1919,7435,7436],{},"nous utilisons gazu, le client Python officiel pour l’API Kitsu",". Il nous permet de nous authentifier, de créer des entités et de téléverser des aperçus directement depuis des scripts.",[48,7439,7440],{},"Installez-le avec :",[152,7442,7443],{},[155,7444,7446],{"className":7445},[158],"pip install gazu",[48,7448,7449],{},"Ensuite, authentifiez-vous auprès de votre instance Kitsu avec votre nom d’utilisateur et votre mot de passe :",[152,7451,7452,7466],{},[155,7453,176,7455,7461],{"className":7454},[175],[48,7456,2015,7457,7460],{},[94,7458,185],{"href":185,"rel":7459},[187],">\")",[48,7462,7463,7464,863],{},"user = gazu.log_in(\"",[94,7465,192],{"href":191},[48,7467,7468],{},[155,7469,7471,7472,1330],{"className":7470},[175],"print(\"Logged in as:\", user['user']",[262,7473,7474],{},"'full_name'",[48,7476,7477,7479,7480,166],{},[125,7478],{},"Une fois connecté, nous pouvons",[94,7481,1917,7483],{"href":7482},"https://gazu.cg-wire.com/?ref=blog.cg-wire.com",[1919,7484,7485],{},"utiliser gazu pour récupérer les productions, les assets et les tâches, puis y attacher des fichiers médias",[61,7487],{},[64,7489,7491],{"id":7490},"_2-creating-a-preview-from-blender",[120,7492,7493],{},"2. Créer un aperçu depuis Blender",[48,7495,7496],{},"Produire un rendu d’aperçu est un cas d’usage courant pour les animateurs. Vous devez obtenir des retours réguliers tout au long de la phase de production, et un aperçu est plus facile à évaluer que d’importer l’intégralité d’un projet.",[48,7498,7499],{},"Vous pouvez l’automatiser via l’API Python de Blender en configurant une capture de viewport pour rendre une seule image, en sauvegardant le résultat dans un dossier temporaire, puis en appliquant les réglages de rendu à l’échelle du studio (résolution, format, watermark) :",[152,7501,7502,7514],{},[155,7503,1662,7505,7508,7511],{"className":7504},[175],[48,7506,7507],{},"bpy.ops.wm.open_mainfile(filepath=\"./project.blend\")",[48,7509,7510],{},"bpy.context.scene.render.resolution_x = 256\nbpy.context.scene.render.resolution_y = 256\nbpy.context.scene.render.resolution_percentage = 100",[48,7512,7513],{},"bpy.context.scene.render.image_settings.file_format = 'PNG'\nbpy.context.scene.render.filepath = \"./preview.png\"",[48,7515,7516],{},[155,7517,7519],{"className":7518},[175],"bpy.ops.render.render(write_still=True)",[212,7521,7522,7527,7536,7544],{},[215,7523,7524,7526],{},[155,7525,1662],{}," : Importer l’API Python de Blender",[215,7528,117,7529,7532,7533],{},[155,7530,7531],{},"py.ops.wm.open_mainfile(filepath=\"./project.blend\")"," : Ouvre un fichier de projet Blender existant nommé ",[155,7534,7535],{},"project.blend",[215,7537,7538,7543],{},[155,7539,7540,7541],{},"bpy.context.scene.render.resolution_x = 256 ",[262,7542,374],{},"Nous configurons la résolution de rendu à 256 pixels par 256 pixels, sans réduction (downscale).",[215,7545,7546,7549,7550,7553],{},[155,7547,7548],{},"bpy.context.scene.render.image_settings.file_format = 'PNG'"," : Définir le format de sortie sur PNG et préciser le chemin de sortie pour  ",[155,7551,7552],{},"preview.png"," avant d’exécuter un rendu fixe (still) de la scène.",[48,7555,7556],{},"Ce script vous fournit un fichier d’aperçu léger, facile à stocker dans Kitsu et rapide à faire relire par les superviseurs.",[72,7558,7560],{"className":7559},[34,75],[77,7561],{"src":7562,"className":7563,"alt":12,"loading":82,"width":7407,"height":7408,"srcSet":7564,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-e936efc9-2c3b-43ea-86f7-8845bdc6c50f.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-e936efc9-2c3b-43ea-86f7-8845bdc6c50f.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-e936efc9-2c3b-43ea-86f7-8845bdc6c50f.png 946w",[48,7566,7567],{},"Pour l’exécuter, installez simplement le package bpy et lancez le programme comme pour n’importe quel autre script Python :",[152,7569,7570],{},[155,7571,7573],{"className":7572},[158],"python3 preview.py",[72,7575,7577],{"className":7576},[34,75],[77,7578],{"src":7579,"className":7580,"alt":12,"loading":82,"width":7581,"height":7582,"srcSet":7583},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-8fc4a1a4-01c7-4fcb-a8a6-b5d50588d6b8.png",[81],687,768,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-8fc4a1a4-01c7-4fcb-a8a6-b5d50588d6b8.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-8fc4a1a4-01c7-4fcb-a8a6-b5d50588d6b8.png 687w",[61,7585],{},[64,7587,7589],{"id":7588},"_3-uploading-a-preview-to-kitsu",[120,7590,7591],{},"3. Téléverser un aperçu vers Kitsu",[48,7593,7594],{},"Une fois le fichier d’aperçu prêt, la dernière étape consiste à pousser les données dans Kitsu avec gazu.",[48,7596,7597],{},"D’abord, nous récupérons la tâche que nous avons créée précédemment :",[152,7599,7600,7609],{},[155,7601,7603,7604],{"className":7602},[175],"projects = gazu.project.all_projects()",[48,7605,7606,7607,1330],{},"assets = gazu.asset.all_assets_for_project(projects",[262,7608,264],{},[48,7610,7611],{},[155,7612,7614,7615,7617],{"className":7613},[175],"tasks = gazu.task.all_tasks_for_asset(assets",[262,7616,264],{},")\ntask_status = gazu.task.get_task_status_by_short_name(\"todo\")",[48,7619,7620],{},"Pour ce faire, on récupère d’abord une liste de toutes les productions disponibles, puis les assets de notre nouvelle production créée, et enfin les tâches assignées à cet asset.",[48,7622,7623],{},"Nous publions un commentaire pour la tâche tout en liant le fichier d’aperçu :",[152,7625,7626],{},[155,7627,7629,7630,7632],{"className":7628},[175],"(comment, preview_file) = gazu.task.publish_preview(\n tasks",[262,7631,264],{},",\n task_status,\n    comment=\"upload preview\",\n    preview_file_path=\"./preview.png\"\n)",[48,7634,7635],{},"Puis on exécute le script :",[152,7637,7638],{},[155,7639,7641],{"className":7640},[158],"python3 upload.py",[48,7643,7644],{},"Une fois téléversé, le fichier devient instantanément disponible dans l’interface web de Kitsu. Les superviseurs peuvent le consulter, laisser des retours et mettre à jour les statuts—sans aucun jonglage manuel de fichiers de la part de l’artiste.",[72,7646,7648],{"className":7647},[34,75],[77,7649],{"src":7650,"className":7651,"alt":12,"loading":82,"width":7652,"height":7653,"srcSet":7654,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-e9710dd1-d727-4e9f-85f8-9db075a159f4.png",[81],955,931,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-e9710dd1-d727-4e9f-85f8-9db075a159f4.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-e9710dd1-d727-4e9f-85f8-9db075a159f4.png 955w",[61,7656],{},[64,7658,7660],{"id":7659},"_4-distribution",[120,7661,7662],{},"4. Distribution",[48,7664,7665],{},"Une fois que votre script fonctionne, vous avez plusieurs options pour l’utiliser ou le partager :",[212,7667,7668,7677,7683],{},[215,7669,7670,7673,7674,7676],{},[120,7671,7672],{},"Le lancer directement dans Blender"," - Ouvrez l’espace ",[652,7675,6941],{}," et exécutez le script depuis là.",[215,7678,7679,7682],{},[120,7680,7681],{},"Lancer depuis la ligne de commande"," - Comme tout à l’heure, vous pouvez exécuter votre script depuis le terminal comme pour n’importe quel programme Python.",[215,7684,7685,7688],{},[120,7686,7687],{},"Le conditionner sous forme d’add-on"," - Cela vous permet de l’activer depuis les préférences de Blender et même de concevoir une interface utilisateur personnalisée pour un accès plus facile.",[48,7690,7691,7692,7698],{},"Créer un add-on complet avec sa propre interface est indispensable pour partager des intégrations avec les artistes, mais c’est un sujet beaucoup plus vaste que nous n’aborderons pas ici. Si vous souhaitez aller plus loin, consultez le",[94,7693,1917,7695],{"href":7694},"https://docs.blender.org/manual/en/latest/advanced/scripting/addon_tutorial.html?ref=blog.cg-wire.com",[1919,7696,7697],{},"tutoriel officiel Blender pour les add-ons",". Et restez à l’écoute : nous aborderons ce sujet plus en détail dans un prochain article !",[61,7700],{},[64,7702,7703],{"id":507},[120,7704,508],{},[48,7706,7707],{},"Les intégrations de pipeline DCC sont fondamentales pour des studios d’animation efficaces : en reliant des outils comme Blender directement à Kitsu, vous réduisez les frictions, améliorez la communication et facilitez la vie à la fois des artistes et des responsables de production.",[48,7709,7710],{},"Vous n’avez pas besoin d’une énorme équipe pipeline pour profiter des avantages des intégrations. Même un petit studio peut commencer simplement, automatiser quelques points pénibles, puis monter en puissance au fil du temps, selon les besoins.",[48,7712,7713,7719],{},[94,7714,7716],{"href":7715},"https://github.com/cgwire/kitsu-publisher-next?ref=blog.cg-wire.com#readme",[1919,7717,7718],{},"Consultez la documentation de Kitsu Publisher"," pour une solution d’intégration DCC prête pour la production, avec Blender, Toon Boom Harmony et Unreal Engine !",[31,7721,7723,7726],{"className":7722},[34,35,36],[31,7724,524],{"className":7725},[40],[31,7727,528,7729,948],{"className":7728},[45],[94,7730,534],{"href":531,"rel":7731},[533],[31,7733,7735],{"className":7734},[34,539,540],[94,7736,1797],{"href":531,"className":7737},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":7739},[7740,7741,7742,7743,7744,7745,7746],{"id":7235,"depth":548,"text":7238},{"id":7275,"depth":548,"text":7278},{"id":7312,"depth":548,"text":7315},{"id":7490,"depth":548,"text":7493},{"id":7588,"depth":548,"text":7591},{"id":7659,"depth":548,"text":7662},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1580894894513-541e068a3e2b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fFNvZnR3YXJlJTIwaW50ZWdyYXRpb258ZW58MHx8fHwxNzYwMzE0NjM1fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":7749,"featured_at":561,"visibility":562},"2026-02-20T06:04:22.000+01:00","/blog-i18n/fr/dcc-integration-blender-kitsu","2025-10-14T11:23:34.000+02:00",{"title":7195,"description":12},"dcc-integration-blender-kitsu","blog-i18n/fr/dcc-integration-blender-kitsu/index",[7756,7757],{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"EnPFDMSVM0b4QHXc2LzyjjRAy3lVqBGMCW9-nH8o2Ic",{"id":7760,"title":7761,"authors":7762,"body":7764,"description":12,"extension":557,"feature_image":8123,"html":7,"meta":8124,"navigation":13,"path":8126,"published_at":8125,"seo":8127,"slug":8128,"stem":8129,"tags":8130,"__hash__":8132,"updated_at":8125,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/estimating-render-costs-animation/index.md","Comment les studios d’animation estiment la capacité de leur ferme de rendu",[7763],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":7765,"toc":8114},[7766,7777,7780,7783,7786,7792,7794,7798,7803,7809,7816,7823,7825,7829,7834,7837,7840,7878,7881,7883,7887,7892,7895,7901,7904,7907,7909,7913,7918,7924,7927,7930,7936,7942,7944,7948,7953,7956,7994,8001,8003,8007,8012,8015,8058,8065,8072,8074,8076,8081,8087,8096,8108],[31,7767,7769,7773],{"className":7768},[34,35,36],[31,7770,7772],{"className":7771},[40],"😀",[31,7774,7776],{"className":7775},[45],"Les coûts de rendu ne sont pas une affaire de hasard. Avec le bon cadre, ils deviennent prévisibles.",[48,7778,7779],{},"Tout le monde a déjà vu une ferme de rendu avancer vers 16 h, scrutant une barre de progression qui n’a pas bougé depuis dix minutes, en se demandant si le rendu sera terminé avant la fin de la journée. Ce moment où la file est pleine, où les artistes sont bloqués et où les superviseurs demandent un ETA (estimation de fin) ressemble à un problème d’estimation.",[48,7781,7782],{},"Le rendu donne souvent l’impression d’être impossible à prévoir. Un léger ajustement de l’éclairage double le temps par image. Un réglage qui fonctionnait hier explose la mémoire aujourd’hui. Sans cadre d’estimation des coûts, vous vous retrouvez avec des fermes saturées, des délais manqués et une confiance entamée dans le pipeline.",[48,7784,7785],{},"La bonne nouvelle : les coûts de rendu ne sont pas de la magie. Ils sont mesurables, décomposables et prévisibles si vous abordez l’estimation avec un cadre plutôt qu’avec l’intuition.",[48,7787,7788,7791],{},[120,7789,7790],{},"Ce guide expose un modèle d’estimation clair et pratique que vous pouvez appliquer immédiatement."," Il est conçu pour les développeurs de pipeline qui ont besoin de chiffres qu’ils peuvent défendre lors d’une réunion de production.",[61,7793],{},[64,7795,7797],{"id":7796},"why-estimating-rendering-costs","Pourquoi Estimer les Coûts de Rendu",[48,7799,7800],{},[94,7801],{"href":7802},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#why-estimating-rendering-costs",[48,7804,7805,7808],{},[120,7806,7807],{},"Une estimation précise du coût de rendu protège le planning"," avant qu’il ne soit menacé. Quand une séquence estimée à 2 heures par image rend en silence à 6 heures, l’occupation de la ferme est multipliée par trois, et les équipes en aval restent en suspens.",[48,7810,7811,7812,7815],{},"La visibilité des coûts ",[120,7813,7814],{},"influence aussi directement les décisions créatives",". Quand les artistes voient que l’activation de volumétriques de haute qualité ajoute 35 % de temps de rendu, ils sont plus enclins à explorer des alternatives. Sans ce retour, les choix se font par préférence visuelle, et la ferme absorbe l’impact plus tard.",[48,7817,7818,7819,7822],{},"Des estimations fiables sont ",[120,7820,7821],{},"indispensables pour le pilotage de l’infrastructure et du budget",". La capacité de la ferme, le cloud bursting et la planification de la livraison dépendent tous de chiffres prévisibles. Une séquence de 120 images à 3 heures par image se comporte très différemment d’une séquence de 9 heures, surtout sur plusieurs projets diffusés en parallèle. Quand les estimations retombent régulièrement dans la bonne fourchette, la production fait confiance au pipeline. Cette confiance libère alors de la place pour des décisions techniques plus intelligentes.",[61,7824],{},[64,7826,7828],{"id":7827},"_1-what-actually-affects-rendering-costs","1. Qu’est-ce Qui Influence Vraiment les Coûts de Rendu ?",[48,7830,7831],{},[94,7832],{"href":7833},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#1-what-actually-affects-rendering-costs",[48,7835,7836],{},"Le coût de rendu ne dépend jamais d’une seule action. C’est le résultat de multiplicateurs qui s’empilent les uns sur les autres.",[48,7838,7839],{},"Si une image coûte trop cher, tout ce qui suit devient pénible. La conversation doit donc toujours commencer par ce qui influence le coût par image :",[212,7841,7842,7848,7854,7860,7866,7872],{},[215,7843,7844,7847],{},[120,7845,7846],{},"Résolution"," - Passer de 1080p à 4K n’augmente pas « légèrement ». C’est quatre fois plus de pixels. Si une image se rend en cinq minutes en 1080p, il est tout à fait raisonnable de voir vingt minutes en 4K avec les mêmes réglages.",[215,7849,7850,7853],{},[120,7851,7852],{},"Fréquence d’images"," - Dix secondes à 24 fps, c’est 240 images. Les mêmes dix secondes à 60 fps, c’est 600 images. Si chaque image coûte huit minutes, vous venez de transformer 32 heures de rendu en 80 sans toucher à un seul shader ni à une seule lumière.",[215,7855,7856,7859],{},[120,7857,7858],{},"Choix du moteur de rendu"," - Le rendu CPU vs GPU dépend moins de la vitesse que des limites de mémoire. Les GPU peuvent être dramatiquement plus rapides par image, mais ils sont contraints par la VRAM. Une scène avec 12 Go de textures et une géométrie lourde peut tenir confortablement en RAM système, tout en dépassant une GPU à 24 Go une fois les structures d’accélération et les surcoûts inclus.",[215,7861,7862,7865],{},[120,7863,7864],{},"Échantillonnage"," - Doubler le nombre d’échantillons double presque le temps de rendu. Si le bruit disparaît de façon acceptable à 192 échantillons mais que les artistes montent à 512 « pour être sûrs », le temps de rendu peut presque tripler pour un gain visuel négligeable.",[215,7867,7868,7871],{},[120,7869,7870],{},"Complexité de la scène"," - Les rendus modernes gèrent des millions de polygones, mais les temps de construction des structures d’accélération et l’usage de la mémoire évoluent aussi. Un asset héros de cinq millions de polygones est très bien isolé. Cinquante duplicatas qui ne sont pas correctement instanciés peuvent doubler la mémoire de la scène et augmenter sensiblement le temps de préparation du rendu. C’est pareil pour les textures, le brouillard volumétrique, les systèmes procéduraux (cheveux, fourrure, foule) et les simulations.",[215,7873,7874,7877],{},[120,7875,7876],{},"Longueur de l’animation"," - Le nombre total d’images est la durée multipliée par la fréquence d’images. Un film de 30 secondes à 24 fps, c’est 720 images. Si chaque image prend douze minutes, cela fait 144 heures de rendu.",[48,7879,7880],{},"Les paramètres à prendre en compte peuvent sembler écrasants, c’est pourquoi le seul indicateur qui compte est le coût par image. Si l’objectif est huit minutes par image et que les premiers tests d’éclairage montrent qu’on est à quatorze, le projet part déjà sur un dépassement important, même si seules quelques images ont été rendues.",[61,7882],{},[64,7884,7886],{"id":7885},"_2-understanding-the-core-formula","2. Comprendre la Formule de Base",[48,7888,7889],{},[94,7890],{"href":7891},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#2-understanding-the-core-formula",[48,7893,7894],{},"Toute discussion sérieuse sur le coût de rendu doit commencer par la formule de base :",[7896,7897,7898],"blockquote",{},[120,7899,7900],{},"Coût total de rendu = ((temps de rendu moyen par image * nombre total d’images) / vitesse de rendu) * coût de calcul horaire",[48,7902,7903],{},"Si une séquence contient 1 200 images, chacune avec une moyenne de 18 minutes sur un seul GPU, et que la ferme traite 40 images en parallèle à 2,50 $ par heure de GPU, les calculs montrent immédiatement si l’ajustement d’éclairage vient seulement d’ajouter des milliers au budget. Cela met des chiffres sur chaque décision.",[48,7905,7906],{},"L’estimation du temps de rendu par image doit être ancrée dans la réalité de production, pas dans l’optimisme.",[61,7908],{},[64,7910,7912],{"id":7911},"_3-local-rendering-vs-cloud","3. Rendu Local vs Cloud",[48,7914,7915],{},[94,7916],{"href":7917},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#3-local-rendering-vs-cloud",[48,7919,7920,7923],{},[120,7921,7922],{},"Il peut être difficile d’évaluer le coût total de possession par rapport au coût total d’exécution"," quand on hésite entre construire sa propre ferme de rendu ou passer au rendu cloud.",[48,7925,7926],{},"Le rendu sur poste de travail local semble peu coûteux parce que le matériel est déjà là. Mais ce GPU ou CPU n’était pas gratuit. Un poste de travail à 6 000 $ amorti sur trois ans revient à environ 166 $ par mois avant même de rendre une seule image. Ajoutez l’électricité : par exemple, une machine de 700 W qui tourne 10 heures par jour à 0,20 $ le kWh, et vous obtenez environ 42 $ par mois juste pour la maintenir allumée. Ensuite, tenez compte de la maintenance : SSD défaillants, conflits de pilotes, mises à jour du système qui cassent des plugins. Même une estimation prudente de quatre heures de travail IT par mois à 75 $/heure ajoute 300 $. Ce « nœud » de rendu « gratuit » coûte soudainement plus de 500 $ par mois avant même d’envisager l’impact sur la production. Le coût d’opportunité est un autre tueur silencieux de budget. Sur une équipe de 10 personnes facturant 600 $ par artiste et par jour, un poste de travail bloqué peut facilement représenter des milliers en délais indirects sur une semaine de crunch.",[48,7928,7929],{},"Le rendu cloud inverse le modèle : de l’investissement (capex) vers des dépenses d’exploitation (opex). Au lieu d’acheter une machine, vous louez de la puissance de calcul au prix de l’heure-GPU. Par exemple, si une image nécessite 2 heures-GPU et que le fournisseur facture 1,20 $ par heure-GPU, cela fait 2,40 $ par image. Multipliez par 500 images : la tâche coûte 1 200 $ en calcul brut. Ce chiffre est transparent et évolue linéairement avec la charge de travail, ce qui rend les estimations plus prévisibles. La scalabilité est là où le cloud devient stratégiquement puissant. Si 500 images doivent être livrées en 24 heures et que chaque image prend 2 heures, en local cela représente 1 000 heures-GPU. Sur un seul poste de travail, cela dépasse 40 jours de rendu. Même avec cinq machines, c’est encore plus d’une semaine. Dans le cloud, en lançant 100 GPU, le job se termine en environ 10 heures. Cet écart peut faire la différence entre gagner un client ou rater le délai. Mais les coûts cachés du cloud sont souvent là où les estimations se fissurent.",[48,7931,7932,7935],{},[120,7933,7934],{},"L’approche pratique est une réflexion hybride."," Par exemple, conservez une petite ferme locale pour rendre les dailies la nuit et utilisez le rendu cloud pour les finales, les pics et les simulations qui dépassent votre capacité interne. Ajustez selon les besoins.",[48,7937,7938,7941],{},[120,7939,7940],{},"Estimer le coût de rendu, c’est modéliser le comportement, pas seulement les machines."," Une fois de plus, il est important de connaître votre temps de rendu moyen par image et de l’intégrer aux estimateurs de coûts, en local comme dans le cloud.",[61,7943],{},[64,7945,7947],{"id":7946},"_4-hidden-costs-animators-forget","4. Les Coûts Cachés Que les Artistes Oublient",[48,7949,7950],{},[94,7951],{"href":7952},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#4-hidden-costs-animators-forget",[48,7954,7955],{},"Tout le monde budgète le temps de rendu, mais les coûts cachés s’accumulent au fil des plans. Si l’objectif est une livraison prévisible, ces coûts doivent être visibles et activement pilotés.",[212,7957,7958,7964,7970,7976],{},[215,7959,7960,7963],{},[120,7961,7962],{},"Les révisions"," sont la partie la plus évidente, mais la vraie dépense ne se limite pas aux heures CPU supplémentaires. C’est l’effet en cascade. Un ajustement tardif de l’animation sur un plan « hero » force l’éclairage à se remettre en file, la comp à invalider les caches et le modeling à réexporter les textures. Sur un plan 4K de 300 images avec des volumes lourds, un changement de timing « léger » peut signifier des dizaines de milliers d’heures de calcul de base, plus du temps d’attente pour les artistes. Des validations claires de versions peuvent éviter beaucoup de dépenses.",[215,7965,7966,7969],{},[120,7967,7968],{},"Le stockage"," est un autre tueur silencieux de budget, surtout avec des séquences EXR. Un seul EXR 4K 16 bits multi-couches peut facilement atteindre 80 à 150 Mo par image. À 1 000 images, cela fait 80 à 150 Go pour une seule version d’un seul plan.",[215,7971,7972,7975],{},[120,7973,7974],{},"La bande passante"," devient visible dès que les artistes travaillent à distance ou entre plusieurs sites. Synchroniser une publication de 120 Go sur une ligne 1 Gbps prend théoriquement environ 15 minutes, mais en pratique, avec la contention et les surcoûts, cela peut être beaucoup plus long. Maintenant, multipliez par dix artistes qui récupèrent les mêmes plaques le lundi matin. La ferme est alors immobilisée parce que la comp attend les transferts. L’approche pratique consiste à mettre en cache et à travailler localement : par exemple avec un NAS et des synchronisations locales « granuleuses ».",[215,7977,7978,7981,7982,7985,7986,7989,7990,7993],{},[120,7979,7980],{},"Les politiques de sauvegarde et d’archivage"," entraînent aussi des coûts réels pour les mêmes raisons. ",[120,7983,7984],{},"Les licences logicielles"," sont souvent traitées comme des frais fixes, mais elles peuvent aussi évoluer de manière imprévisible dans le cas de licences « render only ». ",[120,7987,7988],{},"Le temps IT et la configuration du pipeline"," n’entrent presque jamais dans les budgets des shows, mais ils devraient absolument y figurer. Chaque nouvelle configuration de show, chaque schéma USD personnalisé ou intégration à la ferme, c’est du temps d’ingénierie qui entre en concurrence avec le support et le R&D. Enfin, quand la livraison se comprime, tout devient plus cher. Le rendu cloud en burst coûte plus par heure de calcul, les fournisseurs facturent des ",[120,7991,7992],{},"frais d’accélération",", et les heures supplémentaires augmentent la charge de la masse salariale.",[48,7995,7996,7997,8000],{},"Aucun de ces coûts n’est mystérieux. Ils sont simplement faciles à ignorer quand on se concentre sur la production créative. ",[120,7998,7999],{},"Le rôle d’un pipeline solide est de rendre ces multiplicateurs invisibles mesurables et pilotables."," Quand les équipes voient le vrai coût d’une « petite modification », elles prennent de meilleures décisions, et la production entière subit moins de surprises.",[61,8002],{},[64,8004,8006],{"id":8005},"_5-a-simple-estimation-framework","5. Un Cadre d’Estimation Simple",[48,8008,8009],{},[94,8010],{"href":8011},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#5-a-simple-estimation-framework",[48,8013,8014],{},"Pour estimer les coûts de rendu, il faut s’appuyer sur la réalité. Maintenant que vous avez tous les éléments, voici quelques étapes simples pour construire votre estimation, mais ne soyez pas simpliste : adaptez-les au workflow de votre studio.",[1692,8016,8017,8024,8030,8037,8044,8051],{},[215,8018,8019,8020,8023],{},"Le point de départ le plus fiable est ",[120,8021,8022],{},"la scène la plus lourde de la production en cours",". Prenez le plan le plus complexe que vous puissiez trouver : nombre de personnages maximal, FX complets, volumétriques, motion blur, le tout.",[215,8025,8026,8029],{},[120,8027,8028],{},"Rendez 5 à 10 images finales de qualité"," dans de vrais réglages de production. Par exemple, si le plan de bataille « hero » a six personnages, des FX de pluie et une sortie en 4K, rendez les images 101 à 110 exactement comme elles seraient livrées. Tout le reste, c’est se mentir.",[215,8031,8032,8033,8036],{},"Une fois ces images terminées, ",[120,8034,8035],{},"calculez le temps de rendu moyen par image sur l’ensemble du lot."," Si les dix images vont de 18 à 26 minutes et que la moyenne tombe à 22 minutes par image, alors 22 minutes est votre référence.",[215,8038,8039,8040,8043],{},"Avec cette référence en main, ",[120,8041,8042],{},"ajoutez une marge"," avant que quelqu’un ne la demande. La réalité de production garantit du bruit. Une marge de 15 à 30 % est saine selon la volatilité du show. Si cette moyenne de 22 minutes passe à 28 minutes après une marge de 25 %, vous avez prévu un espace pour l’inévitable dérive du look-dev. Sur un spot stylisé avec un éclairage figé, 15 % peuvent suffire. Sur une séquence de long métrage encore en évolution, 30 % est plus sûr et reste défendable.",[215,8045,8046,8047,8050],{},"Ensuite, ajustez à la taille du show. ",[120,8048,8049],{},"Multipliez le temps par image (avec marge) par le nombre total d’images."," Une séquence de 90 secondes à 24 fps, c’est 2 160 images. À 28 minutes par image, cela fait 60 480 minutes de rendu, soit un peu plus de 1 008 heures de rendu. Sur une ferme de 200 nœuds où chaque nœud exécute une image à la fois, cela correspond à environ cinq heures de temps « wall-clock », en supposant une répartition parfaite et zéro contention. Cette hypothèse ne sera jamais vraie, mais elle donne à la production quelque chose de concret sur quoi raisonner.",[215,8052,8053,8054,8057],{},"Vient ensuite ",[120,8055,8056],{},"la marge pour les révisions."," Prévoyez 10 à 25 % d’images supplémentaires à rerendre au cours de la vie de la séquence. Si l’historique montre que les retours clients déclenchent typiquement deux rerenders, orientez-vous vers 20 à 25 %. Une marge de révision de 20 % ajoute 432 images. À 28 minutes par image, cela fait encore 201 heures de rendu à budgéter.",[48,8059,8060,8061,8064],{},"Et comme mentionné plus tôt, ",[120,8062,8063],{},"n’oubliez pas les coûts cachés, comme le stockage et les coûts de bande passante !"," Calculez-les dès le départ et assurez-vous que le réseau et les disques peuvent supporter ce débit soutenu.",[48,8066,8067,8068,8071],{},"Quand toutes ces pièces sont réunies, vous obtenez un chiffre qui résiste à l’examen. ",[120,8069,8070],{},"Ce chiffre est à la fois une estimation des coûts et une contrainte de production"," : il vous indique s’il faut optimiser les shaders, réduire les volumétriques, augmenter la capacité de la ferme ou renégocier le périmètre.",[61,8073],{},[64,8075,508],{"id":507},[48,8077,8078],{},[94,8079],{"href":8080},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#conclusion",[48,8082,8083,8086],{},[120,8084,8085],{},"L’estimation du coût de rendu vise au final à gérer l’incertitude."," Aucune estimation ne survit vraiment au contact des changements créatifs tardifs ou des contraintes techniques inattendues. L’approche pratique est simple : testez tôt avec des images représentatives, basez vos projections sur des données mesurées plutôt que sur l’intuition, ajoutez des marges réalistes pour les révisions, puis recalibrez en continu une fois que les rendus réels atteignent la ferme. Chaque projet dérive : l’objectif est de détecter cette dérive tôt et de l’absorber grâce à une planification, plutôt que de paniquer.",[48,8088,8089,8090,8095],{},"Si un contrôle plus serré de cette incertitude vous semble intéressant, ",[94,8091,8094],{"href":8092,"rel":8093},"https://blog.cg-wire.com/flamenco-without-nas-kitsu/",[187],"envisagez d’essayer l’hébergement autonome d’une ferme de rendu",". Faire tourner votre propre infrastructure vous donne un accès direct à des métriques de performance, des taux d’échec, le comportement des files d’attente et de vrais coûts de rendu par plan, plutôt que de vous fier à des résumés de facturation cloud opaques. Même une petite configuration de pilote avec quelques nœuds rendant un projet interne court peut révéler des goulots d’étranglement, valider des benchmarks et produire les données historiques nécessaires aux estimations futures. Posséder la boucle de retour entre la complexité de la scène, la performance du matériel et la pression sur la planification est souvent la manière la plus rapide de transformer l’estimation du coût de rendu d’un exercice au feeling en un avantage opérationnel.",[31,8097,8099,8102],{"className":8098},[34,35,36],[31,8100,524],{"className":8101},[40],[31,8103,1786,8105,948],{"className":8104},[45],[94,8106,534],{"href":531,"rel":8107},[533],[31,8109,8111],{"className":8110},[34,539,540],[94,8112,955],{"href":531,"className":8113},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":8115},[8116,8117,8118,8119,8120,8121,8122],{"id":7796,"depth":548,"text":7797},{"id":7827,"depth":548,"text":7828},{"id":7885,"depth":548,"text":7886},{"id":7911,"depth":548,"text":7912},{"id":7946,"depth":548,"text":7947},{"id":8005,"depth":548,"text":8006},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1719014745427-663137ae50f6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGFuaW1hdGlvbiUyMHJlbmRlcmluZ3xlbnwwfHx8fDE3NzMwMzg3NTR8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":8125,"featured_at":561,"visibility":562},"2026-03-09T07:51:00.000+01:00","/blog-i18n/fr/estimating-render-costs-animation",{"title":7761,"description":12},"estimating-render-costs-animation","blog-i18n/fr/estimating-render-costs-animation/index",[8131],{"id":974,"name":975,"slug":976,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":977},"RfQ-fAloFTDyPtTIUyac64AbxGi4Ta8LNSvZiB9dHLM",{"id":8134,"title":8135,"authors":8136,"body":8138,"description":12,"extension":557,"feature_image":8810,"html":7,"meta":8811,"navigation":13,"path":8813,"published_at":8814,"seo":8815,"slug":8816,"stem":8817,"tags":8818,"__hash__":8820,"updated_at":8812,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/ffmpeg-commands-for-animators/index.md","10 commandes FFmpeg que chaque animateur devrait connaître en 2026",[8137],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":8139,"toc":8796},[8140,8158,8161,8164,8167,8169,8175,8178,8201,8204,8206,8212,8218,8221,8227,8266,8268,8274,8282,8285,8291,8321,8323,8329,8332,8335,8341,8367,8377,8379,8385,8388,8391,8397,8425,8433,8436,8442,8444,8450,8453,8456,8462,8488,8490,8496,8499,8502,8508,8540,8542,8548,8551,8558,8564,8584,8586,8592,8595,8601,8607,8623,8631,8633,8639,8642,8652,8658,8676,8686,8692,8698,8706,8708,8714,8717,8720,8723,8729,8732,8738,8752,8754,8758,8761,8764,8775,8790],[31,8141,8143,8147],{"className":8142},[34,35,36],[31,8144,8146],{"className":8145},[40],"📼",[31,8148,8150,8151,8157],{"className":8149},[45],"Vous pensez que les outils de conversion vidéo sont uniquement pour les monteurs ? Pensez encore. FFmpeg est l’arme secrète cachée dans chaque pipeline d’animation — utilisée par des studios comme YouTube, Blender et DaVinci Resolve — et elle peut vous faire gagner ",[6354,8152,8153],{},[652,8154,8156],{"className":8155,"style":122},[6359],"des heures"," de travail manuel dès que vous savez comment l’utiliser.",[48,8159,8160],{},"Si vous travaillez dans l’animation ou la production vidéo, vous avez déjà rencontré FFmpeg.",[48,8162,8163],{},"Bien qu’il soit open source et utilisé par des géants comme YouTube, Blender et DaVinci Resolve, FFmpeg reste souvent dans l’ombre et peu d’artistes connaissent sa vraie valeur.",[48,8165,8166],{},"Dans ce guide, nous allons passer en revue 10 commandes FFmpeg pratiques que chaque animateur ou artiste de pipeline devrait connaître afin d’économiser des heures de travail manuel.",[61,8168],{},[64,8170,8172],{"id":8171},"whats-ffmpeg",[120,8173,8174],{},"Qu’est-ce que FFmpeg ?",[48,8176,8177],{},"FFmpeg est un puissant kit à ligne de commande open source pour travailler avec des données vidéo, audio et image. Ce n’est pas un seul programme : c’est plutôt une suite d’outils qui gèrent presque tous les types de tâches de traitement multimédia imaginables :",[212,8179,8180,8183,8186,8189,8192,8195,8198],{},[215,8181,8182],{},"Convertir entre pratiquement n’importe quel format vidéo, audio ou image.",[215,8184,8185],{},"Assembler des séquences d’images en films (et inversement).",[215,8187,8188],{},"Compresser ou transcoder de gros fichiers pour les revues ou les téléversements.",[215,8190,8191],{},"Filtres : recadrage, mise à l’échelle, correction des couleurs, superposition, flou, etc.",[215,8193,8194],{},"Synchroniser ou combiner plusieurs sources audio/vidéo.",[215,8196,8197],{},"Analyser les métadonnées multimédia (fréquence d’image, codec, profondeur de bits, etc.).",[215,8199,8200],{},"Automatiser le traitement par lots dans les pipelines via des scripts.",[48,8202,8203],{},"Nous ne pouvons pas lister toutes les super fonctionnalités qu’il propose, mais commençons par 10 commandes FFmpeg pratiques avec des exemples que vous pouvez utiliser directement dans votre terminal.",[61,8205],{},[64,8207,8209],{"id":8208},"_1-compile-an-image-sequence-into-a-video",[120,8210,8211],{},"1. Compiler une séquence d’images en vidéo",[48,8213,8214,8217],{},[94,8215,8216],{"href":2737},"Les moteurs de rendu comme Blender"," permettent de générer des séquences d’images (par ex., des milliers d’EXR ou de PNG) plutôt que des fichiers vidéo uniques. C’est plus sûr : si un rendu plante, vous pouvez reprendre à partir de là. Le problème, c’est que ces séquences ne sont ni lisibles directement ni faciles à relire.",[48,8219,8220],{},"FFmpeg peut assembler toutes les images en une seule vidéo en quelques secondes pour créer une version légère et partageable de votre plan :",[152,8222,8223],{},[155,8224,8226],{"className":8225},[158],"ffmpeg -framerate 24 -i frame_%04d.png -c:v libx264 -pix_fmt yuv420p output.mp4",[212,8228,8229,8235,8248,8254,8260],{},[215,8230,8231,8234],{},[155,8232,8233],{},"-framerate 24"," - indique à FFmpeg de lire la séquence à 24 images par seconde.",[215,8236,8237,8240,8241,655,8244,8247],{},[155,8238,8239],{},"-i frame_%04d.png - %04d"," signifie quatre chiffres complétés par des zéros (par ex. ",[155,8242,8243],{},"0001",[155,8245,8246],{},"0002"," …). Vous aurez besoin de plus de chiffres si votre séquence dépasse 1000 images.",[215,8249,8250,8253],{},[155,8251,8252],{},"-c:v libx264"," - encode la vidéo avec le codec H.264, un bon choix par défaut pour les revues.",[215,8255,8256,8259],{},[155,8257,8258],{},"-pix_fmt yuv420p"," - garantit une compatibilité large (notamment avec les lecteurs multimédias et les navigateurs).",[215,8261,8262,8265],{},[155,8263,8264],{},"output.mp4"," - le nom du fichier vidéo final.",[61,8267],{},[64,8269,8271],{"id":8270},"_2-create-a-quick-low-res-review",[120,8272,8273],{},"2. Créer une rapide revue en basse résolution",[48,8275,8276,8277,8281],{},"Les rendus haute résolution (4K, EXR pleine qualité ou ProRes) de plusieurs Go sont trop lourds ",[94,8278,8280],{"href":8279},"https://blog.cg-wire.com/how-to-give-efficient-animation-feedback/","pour les envoyer sur Slack afin d’obtenir des retours"," : vous avez besoin de versions plus petites, qui se chargent vite, pour les revues quotidiennes.",[48,8283,8284],{},"Rassemblez simplement et compressez automatiquement une vidéo maître pour obtenir une version lisible sans refaire le rendu :",[152,8286,8287],{},[155,8288,8290],{"className":8289},[158],"ffmpeg -i output.mp4 -vf scale=960:-1 -b:v 1M review.mp4",[212,8292,8293,8299,8309,8315],{},[215,8294,8295,8298],{},[155,8296,8297],{},"-i output.mp4"," - fichier d’entrée (votre rendu de haute qualité).",[215,8300,8301,8304,8305,8308],{},[155,8302,8303],{},"-vf scale=960:-1"," - redimensionne la largeur de la vidéo à 960 pixels et ajuste automatiquement la hauteur (",[155,8306,8307],{},"-1",") pour conserver le ratio d’aspect.",[215,8310,8311,8314],{},[155,8312,8313],{},"-b:v 1M"," - définit le débit vidéo à 1 mégabit par seconde : un bon compromis entre faible taille et vitesse.",[215,8316,8317,8320],{},[155,8318,8319],{},"review.mp4"," - fichier de sortie.",[61,8322],{},[64,8324,8326],{"id":8325},"_3-overlay-a-logo-or-watermark",[120,8327,8328],{},"3. Superposer un logo ou un filigrane",[48,8330,8331],{},"Les studios et les freelances partagent souvent des fichiers en cours de réalisation. Mais sans filigrane, les aperçus peuvent être redistribués, fuités ou confondus avec des versions finales.",[48,8333,8334],{},"Avec une seule commande FFmpeg, vous pouvez superposer un logo de studio, un nom d’utilisateur ou une étiquette « Work In Progress » sur chaque image.",[152,8336,8337],{},[155,8338,8340],{"className":8339},[158],"ffmpeg -i input.mp4 -i logo.png -filter_complex \"overlay=10:10\" branded.mp4",[212,8342,8343,8349,8355,8361],{},[215,8344,8345,8348],{},[155,8346,8347],{},"-i input.mp4"," - vidéo principale.",[215,8350,8351,8354],{},[155,8352,8353],{},"-i logo.png"," - image à superposer (elle doit avoir de la transparence, sinon vous obtiendrez une boîte opaque).",[215,8356,8357,8360],{},[155,8358,8359],{},"-filter_complex \"overlay=10:10\""," - applique un filtre de superposition, en plaçant le logo à 10 px du coin supérieur gauche.",[215,8362,8363,8366],{},[155,8364,8365],{},"branded.mp4"," - résultat avec filigrane appliqué.",[72,8368,8370],{"className":8369},[34,75],[77,8371],{"src":8372,"className":8373,"alt":12,"loading":82,"width":8374,"height":8375,"srcSet":8376,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-44bab5d8-5532-4d0b-9347-12812a0e1271.png",[81],848,527,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-44bab5d8-5532-4d0b-9347-12812a0e1271.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-44bab5d8-5532-4d0b-9347-12812a0e1271.png 848w",[61,8378],{},[64,8380,8382],{"id":8381},"_4-burn-frame-numbers-or-timecode",[120,8383,8384],{},"4. Insérer des numéros d’images ou un timecode",[48,8386,8387],{},"Lors des revues client ou équipe, tout le monde doit référencer des images exactes pour les notes : des séquences non étiquetées rendent impossible l’alignement des retours.",[48,8389,8390],{},"Le filtre drawtext de FFmpeg peut insérer des numéros d’images ou des timecodes « en cours » dans votre vidéo, pour fournir un système de référence précis. Cela aide les superviseurs et les animateurs à rester synchronisés pendant les revues.",[152,8392,8393],{},[155,8394,8396],{"className":8395},[158],"ffmpeg -i input.mp4 -vf \"drawtext=text='%{n}':x=10:y=H-th-10:fontsize=24:fontcolor=white\" numbered.mp4",[212,8398,8399,8404,8410,8416],{},[215,8400,8401,8403],{},[155,8402,2849],{}," : le filtre dessine du texte sur chaque image.",[215,8405,8406,8409],{},[155,8407,8408],{},"text='%{n}'"," - insère le numéro d’image.",[215,8411,8412,8415],{},[155,8413,8414],{},"x=10:y=H-th-10"," - place le texte à 10 px du bas à gauche.",[215,8417,8418,655,8421,8424],{},[155,8419,8420],{},"fontsize",[155,8422,8423],{},"fontcolor"," - contrôle l’aspect.",[72,8426,8428],{"className":8427},[34,75],[77,8429],{"src":8430,"className":8431,"alt":12,"loading":82,"width":8374,"height":8375,"srcSet":8432,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-84b1c23e-6e65-493e-bf3c-96c254d28234.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-84b1c23e-6e65-493e-bf3c-96c254d28234.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-84b1c23e-6e65-493e-bf3c-96c254d28234.png 848w",[48,8434,8435],{},"Ou pour le timecode, en utilisant l’horodatage de présentation (PTS) formaté en heures:minutes:secondes :",[152,8437,8438],{},[155,8439,8441],{"className":8440},[158],"ffmpeg -i input.mp4 -vf \"drawtext=text='%{pts\\:hms}':x=10:y=H-th-10:fontsize=24:fontcolor=white\" timecode.mp4",[61,8443],{},[64,8445,8447],{"id":8446},"_5-create-looping-clips-turntables",[120,8448,8449],{},"5. Créer des extraits en boucle (table tournante)",[48,8451,8452],{},"Pour présenter des modèles 3D ou des plans, vous avez souvent besoin de boucles « turntables » pour des portfolios, des bibliothèques internes ou des démos. Dupliquer les clips manuellement dans un éditeur est fastidieux.",[48,8454,8455],{},"FFmpeg peut boucler n’importe quel extrait un nombre choisi de fois avec -stream_loop, créant des lectures continues instantanément, sans re-rendre :",[152,8457,8458],{},[155,8459,8461],{"className":8460},[158],"ffmpeg -stream_loop 3 -i turntable.mp4 -c copy looped.mp4",[212,8463,8464,8470,8476,8482],{},[215,8465,8466,8469],{},[155,8467,8468],{},"-stream_loop 3"," - lit l’entrée 3 fois supplémentaires.",[215,8471,8472,8475],{},[155,8473,8474],{},"-i turntable.mp4"," - votre animation d’origine.",[215,8477,8478,8481],{},[155,8479,8480],{},"-c copy"," - copie les flux audio/vidéo sans réencodage (rapide, sans perte).",[215,8483,8484,8487],{},[155,8485,8486],{},"looped.mp4"," - sortie finale.",[61,8489],{},[64,8491,8493],{"id":8492},"_6-add-sound-to-a-silent-render",[120,8494,8495],{},"6. Ajouter du son à un rendu silencieux",[48,8497,8498],{},"Les rendus issus de logiciels 3D n’incluent pas l’audio, même si votre animation est synchronisée avec du dialogue ou de la musique, et ajouter le son manuellement dans Premiere ou After Effects peut prendre du temps pour de simples aperçus.",[48,8500,8501],{},"FFmpeg peut fusionner instantanément un rendu silencieux avec une piste audio, en les synchronisant sans passer par un éditeur basé sur une timeline.",[152,8503,8504],{},[155,8505,8507],{"className":8506},[158],"ffmpeg -i render.mp4 -i music.wav -c:v copy -c:a aac -shortest final.mp4",[212,8509,8510,8516,8522,8528,8534],{},[215,8511,8512,8515],{},[155,8513,8514],{},"-i render.mp4"," - entrée vidéo.",[215,8517,8518,8521],{},[155,8519,8520],{},"-i music.wav"," - entrée audio.",[215,8523,8524,8527],{},[155,8525,8526],{},"-c:v copy"," - conserve le flux vidéo existant (pas de re-rendu).",[215,8529,8530,8533],{},[155,8531,8532],{},"-c:a aac"," - encode l’audio en AAC (largement pris en charge).",[215,8535,8536,8539],{},[155,8537,8538],{},"-shortest"," - arrête l’encodage lorsque la piste la plus courte se termine.",[61,8541],{},[64,8543,8545],{"id":8544},"_7-extract-every-nth-frame",[120,8546,8547],{},"7. Extraire chaque n-ième image",[48,8549,8550],{},"Revoir toutes les images d’un plan long est lent, surtout pour l’analyse de mouvement, la détection de flicker (scintillement) ou la vérification de changements d’exposition. Parfois, vous voulez simplement échantillonner des images à raison d’une toutes les 10 ou 20.",[48,8552,8553,8554,8557],{},"Le filtre ",[155,8555,8556],{},"select"," de FFmpeg vous permet d’extraire automatiquement chaque n-ième image. C’est idéal pour des diagnostics rapides du mouvement, créer des planches contact ou générer des miniatures :",[152,8559,8560],{},[155,8561,8563],{"className":8562},[158],"ffmpeg -i input.mp4 -vf \"select='not(mod(n,10))',setpts=N/FRAME_RATE/TB\" frames_%04d.png",[212,8565,8566,8572,8578],{},[215,8567,8568,8571],{},[155,8569,8570],{},"select='not(mod(n,10))'"," - ne traite que les images dont le numéro n est divisible par 10 (toutes les 10e).",[215,8573,8574,8577],{},[155,8575,8576],{},"setpts=N/FRAME_RATE/TB"," - corrige les timestamps pour que la sortie ne soit pas lue trop vite.",[215,8579,8580,8583],{},[155,8581,8582],{},"frames_%04d.png"," - motif de nommage des images extraites.",[61,8585],{},[64,8587,8589],{"id":8588},"_8-compare-two-versions-ab-diff",[120,8590,8591],{},"8. Comparer deux versions (A/B Diff)",[48,8593,8594],{},"Quand vous testez des ajustements d’éclairage, des corrections de couleur ou des mises à jour de débruitage, il est difficile de repérer de petites différences visuelles entre deux versions à l’œil.",[48,8596,8553,8597,8600],{},[155,8598,8599],{},"blend=all_mode=difference"," de FFmpeg soustrait une version de l’autre et affiche les différences sous forme de pixels clairs. C’est une façon rapide de faire de l’assurance qualité (QA) sur les changements de version.",[152,8602,8603],{},[155,8604,8606],{"className":8605},[158],"ffmpeg -i old.mp4 -i new.mp4 -filter_complex \"blend=all_mode=difference\" diff.mp4",[212,8608,8609,8612,8617],{},[215,8610,8611],{},"Deux fichiers d’entrée : l’ancienne et la nouvelle version.",[215,8613,8614,8616],{},[155,8615,8599],{}," - soustrait les valeurs des pixels de l’une à l’autre, en montrant l’endroit où elles diffèrent.",[215,8618,8619,8622],{},[155,8620,8621],{},"diff.mp4"," - pixels clairs = changements, sombre = aucune différence.",[72,8624,8626],{"className":8625},[34,75],[77,8627],{"src":8628,"className":8629,"alt":12,"loading":82,"width":8374,"height":8375,"srcSet":8630,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-57adc37e-d8c2-407a-9057-1739a959c61f.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-57adc37e-d8c2-407a-9057-1739a959c61f.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-57adc37e-d8c2-407a-9057-1739a959c61f.png 848w",[61,8632],{},[64,8634,8636],{"id":8635},"_9-combine-render-passes-side-by-side",[120,8637,8638],{},"9. Combiner des passes de rendu côte à côte",[48,8640,8641],{},"Les artistes ont souvent besoin de comparer deux passes (par ex. anciennes vs. nouvelles). Les ouvrir dans un logiciel de compositing uniquement pour comparer la mise en page ou l’éclairage est un excès.",[48,8643,8553,8644,8647,8648,8651],{},[155,8645,8646],{},"hstack"," (ou ",[155,8649,8650],{},"vstack",") place les vidéos côte à côte ou verticalement pour faciliter la comparaison. C’est parfait pour les exports de revue ou les vidéos avant/après qui montrent les changements pour les clients ou les superviseurs.",[152,8653,8654],{},[155,8655,8657],{"className":8656},[158],"ffmpeg -i pass1.mp4 -i pass2.mp4 -filter_complex \"hstack\" side_by_side.mp4",[212,8659,8660,8663,8671],{},[215,8661,8662],{},"Deux vidéos en entrée.",[215,8664,8665,8667,8668,8670],{},[155,8666,8646],{}," - les empile horizontalement. Utilisez ",[155,8669,8650],{}," pour les empiler verticalement à la place.",[215,8672,8673,8320],{},[155,8674,8675],{},"side_by_side.mp4",[72,8677,8679],{"className":8678},[34,75],[77,8680],{"src":8681,"className":8682,"alt":12,"loading":82,"width":8683,"height":8684,"srcSet":8685,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png",[81],1186,748,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png 1186w",[48,8687,8688,8689,8691],{},"Vous pouvez aussi inclure la vidéo résultante de la commande ",[155,8690,8599],{}," précédente pour voir rapidement les différences entre les images :",[152,8693,8694],{},[155,8695,8697],{"className":8696},[158],"ffmpeg -i pass1.mp4 -i diff.mp4 -i pass2.mp4 \\\n-filter_complex \"[0:v][1:v]hstack=inputs=2[top]; [top][2:v]hstack=inputs=2\" \\\nside_by_side2.mp4",[72,8699,8701],{"className":8700},[34,75],[77,8702],{"src":8703,"className":8704,"alt":12,"loading":82,"width":8683,"height":8684,"srcSet":8705,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png 1186w",[61,8707],{},[64,8709,8711],{"id":8710},"_10-re-time-animation-slow-mo-or-speed-up",[120,8712,8713],{},"10. Ajuster le timing de l’animation (ralenti ou accéléré)",[48,8715,8716],{},"Les ajustements de timing comme prévisualiser un mouvement de caméra plus lent ou vérifier un test de mouvement rapide nécessitent généralement de refaire le rendu ou d’éditer dans un logiciel. C’est inefficace juste pour essayer différents rythmes.",[48,8718,8719],{},"FFmpeg peut modifier la vitesse de lecture à la volée en ajustant les timestamps des images, afin de permettre aux animateurs de prévisualiser immédiatement des vitesses alternatives.",[48,8721,8722],{},"Ralentir à la moitié :",[152,8724,8725],{},[155,8726,8728],{"className":8727},[158],"ffmpeg -i input.mp4 -filter:v \"setpts=2.0*PTS\" slowmo.mp4",[48,8730,8731],{},"Accélérer x2 :",[152,8733,8734],{},[155,8735,8737],{"className":8736},[158],"ffmpeg -i input.mp4 -filter:v \"setpts=0.5*PTS\" fast.mp4",[212,8739,8740,8746,8749],{},[215,8741,8553,8742,8745],{},[155,8743,8744],{},"setpts"," manipule les timestamps de présentation (PTS) de chaque image.",[215,8747,8748],{},"Multiplier par 2.0 double le temps de lecture (donc plus lent).",[215,8750,8751],{},"Multiplier par 0.5 le divise par deux (donc plus rapide).",[61,8753],{},[64,8755,8756],{"id":507},[120,8757,508],{},[48,8759,8760],{},"FFmpeg n’est pas seulement un convertisseur vidéo. Avec quelques lignes de texte, vous pouvez automatiser des tâches qui prennent d’ordinaire des minutes ou des heures dans des logiciels traditionnels : rendu par lots, comparaisons de versions, exports de revue… Bref, tout ce que vous voulez.",[48,8762,8763],{},"Une fois que vous êtes à l’aise avec la syntaxe, FFmpeg devient une extension de votre workflow créatif. Choisissez une commande dans cette liste, intégrez-la dans votre prochain pipeline de rendu, et observez à quel point votre production quotidienne devient plus fluide !",[48,8765,8766,8767,8770,8771,8774],{},"Mais ce n’est pas tout. Combinez la puissance de ffmpeg avec des scripts DCC (comme ",[94,8768,8769],{"href":1002},"Blender scripting",") et vous débloquerez des super-pouvoirs au-delà de la compréhension humaine (comme automatiser la création de scènes entières). ",[94,8772,8773],{"href":6377},"Abonnez-vous à notre blog"," pour en savoir plus !",[31,8776,8778,8781],{"className":8777},[34,35,36],[31,8779,524],{"className":8780},[40],[31,8782,8784,8785,8789],{"className":8783},[45],"Pour en apprendre davantage sur le processus d’animation ",[94,8786,8788],{"href":531,"rel":8787},[533],"pensez à rejoindre notre communauté Discord"," ! Nous échangeons avec plus d’un millier d’experts qui partagent les bonnes pratiques et organisent parfois des événements en personne. Nous serons ravis de vous accueillir ! 😊",[31,8791,8793],{"className":8792},[34,539,540],[94,8794,1797],{"href":531,"className":8795},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":8797},[8798,8799,8800,8801,8802,8803,8804,8805,8806,8807,8808,8809],{"id":8171,"depth":548,"text":8174},{"id":8208,"depth":548,"text":8211},{"id":8270,"depth":548,"text":8273},{"id":8325,"depth":548,"text":8328},{"id":8381,"depth":548,"text":8384},{"id":8446,"depth":548,"text":8449},{"id":8492,"depth":548,"text":8495},{"id":8544,"depth":548,"text":8547},{"id":8588,"depth":548,"text":8591},{"id":8635,"depth":548,"text":8638},{"id":8710,"depth":548,"text":8713},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1727142073871-d40f5a7c76d8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDMwfHx2aWRlbyUyMGVuY29kaW5nJTIwdGVybWluYWx8ZW58MHx8fHwxNzYyMjQ1NjQ3fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":8812,"featured_at":561,"visibility":562},"2026-02-20T06:04:25.000+01:00","/blog-i18n/fr/ffmpeg-commands-for-animators","2025-11-04T10:09:54.000+01:00",{"title":8135,"description":12},"ffmpeg-commands-for-animators","blog-i18n/fr/ffmpeg-commands-for-animators/index",[8819],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"XYUMD-ERXT1Lm1ZIKD32xWwdB54yOBU6J7asYDCf4ZU",{"id":8822,"title":8823,"authors":8824,"body":8826,"description":12,"extension":557,"feature_image":9317,"html":7,"meta":9318,"navigation":13,"path":9319,"published_at":9320,"seo":9321,"slug":9322,"stem":9323,"tags":9324,"__hash__":9326,"updated_at":8812,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/flamenco-without-nas-kitsu/index.md","Rendu Flamenco sans NAS avec une intégration Kitsu (2026)",[8825],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":8827,"toc":9307},[8828,8838,8841,8844,8851,8854,8857,8860,8885,8887,8891,8894,8899,8902,8905,8908,8911,8913,8917,8920,8923,8936,8943,8946,8953,8956,8963,8969,8972,8978,8984,8986,8990,8995,9002,9008,9011,9014,9016,9020,9023,9034,9056,9059,9125,9128,9130,9134,9144,9165,9168,9171,9173,9177,9185,9188,9194,9197,9199,9203,9206,9216,9245,9248,9256,9259,9262,9265,9267,9269,9272,9275,9278,9281,9288,9301],[31,8829,8831,8834],{"className":8830},[34,35,36],[31,8832,3890],{"className":8833},[40],[31,8835,8837],{"className":8836},[45],"Exécutez Flamenco sans stockage partagé en laissant Kitsu piloter le contexte de rendu et les fichiers.",[48,8839,8840],{},"Vous voulez utiliser Flamenco, mais vous ne voulez pas acheter un NAS.",[48,8842,8843],{},"Si vous êtes un artiste solo ou une micro-structure d’animation, c’est une décision parfaitement rationnelle : le stockage partagé peut être coûteux, ajoute de la charge de maintenance et résout des problèmes que vous n’aurez peut-être pas vraiment avant d’avoir essayé de lancer une ferme de rendu.",[48,8845,8846,8850],{},[94,8847,8849],{"href":8848},"https://blog.cg-wire.com/self-hosted-blender-render-farm","Flamenco part d’une configuration studio traditionnelle"," : fichiers partagés, chemins partagés, accès instantané. Sans NAS, cette hypothèse est difficile à contourner. Flamenco n’a pas de notion de contexte de production : il ne sait donc pas quel plan vous voulez rendre, quelle version est approuvée, ni où se trouvent les fichiers de job. Et sans ces informations, il ne peut pas fonctionner en toute sécurité dans un environnement sans NAS.",[48,8852,8853],{},"C’est là qu’intervient Kitsu.",[48,8855,8856],{},"Kitsu sait déjà ce que Flamenco ne sait pas : tâches, plans, versions, approbations. En traitant Kitsu comme un stockage réseau asynchrone, vous pouvez déplacer les données vers le manager Flamenco quand c’est nécessaire, effectuer le rendu, et éviter complètement le stockage partagé “dur”.",[48,8858,8859],{},"Flamenco ne prend pas en charge ce workflow “out of the box”. Pour que cela fonctionne, vous devez créer un type de job Flamenco personnalisé qui récupère le contexte et les fichiers depuis Kitsu, les met en scène localement, et contrôle quand et comment les rendus sont lancés. Cet article vous montre précisément comment faire.",[31,8861,8863,8866],{"className":8862},[34,35,108],[31,8864,112],{"className":8865},[40],[31,8867,8869,8873,8875,2634,8877,8879,134,8881],{"className":8868},[45],[117,8870,8871],{},[120,8872,1021],{"style":122},[125,8874],{},[125,8876],{},[125,8878],{},[125,8880],{},[94,8882,8884],{"href":8883},"https://github.com/cgwire/blog-tutorials/tree/main/flamenco-kitsu-render-farm?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/flamenco-kitsu-render-farm",[61,8886],{},[64,8888,8890],{"id":8889},"high-level-architecture","Architecture de haut niveau",[48,8892,8893],{},"Notre configuration repose sur une idée simple : Flamenco effectue le rendu, Kitsu fournit la vérité.",[152,8895,8896],{},[155,8897,8898],{},"Kitsu\n  ↑↓ (REST API)\nCustom Flamenco Job Type\n  ├── Pre-task Python (fetch task data & files)\n  ├── Blender render tasks (Flamenco-managed)\n  └── Post-task Python (upload renders back to Kitsu)\nFlamenco Manager\n  ↓\nFlamenco Worker(s)\n",[48,8900,8901],{},"Flamenco fonctionne exactement comme prévu, avec un Manager qui planifie le travail et des Workers qui exécutent les tâches Blender. Ce qui change, c’est la manière dont les jobs sont définis. Au lieu d’indiquer à Flamenco un dossier partagé et d’espérer que chaque machine verra les mêmes fichiers, nous introduisons un type de job Flamenco personnalisé qui comprend les données de production et sait comment communiquer avec Kitsu.",[48,8903,8904],{},"Kitsu se trouve en dehors de la ferme et expose tout via son API REST : plans, tâches, versions et emplacements des fichiers. Lorsqu’un job de rendu est démarré — manuellement ou via une automatisation — le type de job personnalisé interroge Kitsu pour déterminer exactement ce qu’il faut rendre. Par exemple, il peut demander : « Donne-moi la dernière version d’éclairage approuvée pour le plan 020. » Kitsu répond, et cette réponse devient le job de rendu.",[48,8906,8907],{},"Côté Flamenco, le Manager ne sonde pas Kitsu et ne suit pas l’état de production. Il exécute simplement la définition de job qui lui est fournie. Le type de job personnalisé utilise un petit script Python “pre-task” pour récupérer les métadonnées et les fichiers depuis Kitsu, les mettre en scène localement dans un dossier de job, puis les transmettre à des tâches standards de rendu Blender que Flamenco sait gérer efficacement.",[48,8909,8910],{},"Une fois le rendu terminé, une étape “post-task” en Python renvoie les résultats à Kitsu : téléversement des images rendues, création d’une nouvelle version, ou mise à jour du statut de la tâche. À aucun moment les workers n’ont besoin d’un stockage partagé ou d’un accès permanent au même système de fichiers. Chaque worker récupère ce dont il a besoin, rend en local, puis pousse les résultats de manière asynchrone.",[61,8912],{},[64,8914,8916],{"id":8915},"_1-creating-a-new-job-type","1. Créer un nouveau type de job",[48,8918,8919],{},"Un type de job Flamenco définit comment un job devient un travail concret. C’est la couche de traduction entre « je veux rendre ça » et les tâches concrètes que Flamenco planifie à travers la ferme. Conceptuellement, un type de job déclare les informations dont il a besoin et comment compiler ces informations en tâches.",[48,8921,8922],{},"Le plus simplement possible, un type de job décrit une étiquette et un ensemble de réglages, puis fournit une fonction qui reçoit ces réglages et construit le job. En code, cela ressemble à ceci :",[152,8924,8925,8930],{},[155,8926,8929],{"className":8927},[8928],"language-js","const JOB_TYPE = {\n  label: \"Kitsu Render\",\n  settings: [\n    // { key: \"message\", type: \"string\", required: true },\n    // { key: \"sleep_duration_seconds\", type: \"int32\", default: 1 },\n  ],\n};\n",[48,8931,8932],{},[155,8933,8935],{"className":8934},[8928],"function compileJob(job) {\nconst settings = job.settings;\n}\n",[48,8937,8938,8939,8942],{},"Ce code définit le squelette d’un type de job Flamenco personnalisé. L’objet ",[155,8940,8941],{},"JOB_TYPE"," décrit comment le job apparaît dans Flamenco : son libellé lisible par les humains et les paramètres qu’il attend lorsqu’un job est créé.",[48,8944,8945],{},"Ces réglages agissent comme des entrées typées, avec validation gérée par Flamenco : dans cet exemple, une chaîne requise et un entier optionnel avec une valeur par défaut.",[48,8947,8948,8949,8952],{},"La fonction ",[155,8950,8951],{},"compileJob"," est l’endroit où le job est transformé en tâches exécutables ; elle reçoit le job soumis, lit les réglages résolus, et les utiliserait normalement pour générer les étapes de rendu, “pre-task” et “post-task”. Telle qu’elle est écrite, la fonction ne fait encore aucun travail, mais elle définit le point d’entrée où la logique de production vivra.",[48,8954,8955],{},"En production réelle, au lieu d’un message générique, vous passez un identifiant de tâche Kitsu, un nom de plan, l’emplacement de sortie souhaité, ou même la version de Blender à utiliser.",[48,8957,8958,8959,8962],{},"L’endroit où vit cette logique a de l’importance. Les types de job Flamenco personnalisés tournent sur le ",[120,8960,8961],{},"Flamenco Manager",", pas sur les workers. Sur disque, ils se trouvent à côté du programme du manager, par exemple :",[152,8964,8965],{},[155,8966,8968],{"className":8967},[158],"$ flamenco\n└── flamenco-manager\n└── scripts/\n└── kitsu-render.js\n",[48,8970,8971],{},"En pratique, les studios considèrent ces scripts de types de job comme faisant partie de leur base de code de pipeline. Ils sont suivis en contrôle de version, évoluent au fil du temps et sont déployés avec les mises à jour de Flamenco. Ainsi, vous pouvez modifier la manière dont les jobs sont construits et comment Kitsu est interrogé sans redéployer ni reconfigurer chaque machine worker de la ferme.",[48,8973,8974,8975,1654],{},"Pour les scripts worker appelés par les types de job personnalisés en tant que commandes, nous les plaçons à côté de notre programme ",[155,8976,8977],{},"flamenco-worker",[152,8979,8980],{},[155,8981,8983],{"className":8982},[158],"$ flamenco\n└── flamenco-worker\n└── kitsu-render.py\n",[61,8985],{},[64,8987,8989],{"id":8988},"_2-adding-tasks","2. Ajouter des tâches",[48,8991,4862,8992,8994],{},[155,8993,8951],{},", vous définissez explicitement les tâches qui composent le job. C’est ici que la demande de haut niveau « rendre ce plan » se transforme en travail concret, planifiable, que Flamenco peut confier aux workers.",[48,8996,8997,8998,9001],{},"L’exemple ci-dessous montre la tâche la plus simple possible. Une tâche ",[155,8999,9000],{},"echo"," est créée via l’API d’édition de tâches de Flamenco, fournie avec une catégorie, puis assignée à une seule commande. Cette commande passe le réglage de job résolu dans la tâche, qui imprimera simplement le message lorsqu’elle s’exécutera. Enfin, la tâche est ajoutée au job pour que le Manager puisse la planifier.",[152,9003,9004],{},[155,9005,9007],{"className":9006},[8928],"const echoTask = author.Task(\"echo\", \"misc\");\nechoTask.addCommand(\nauthor.Command(\"echo\", {\nmessage: settings.message,\n}),\n);\njob.addTask(echoTask);\n",[48,9009,9010],{},"Même si cette tâche ne fait rien d’utile par elle-même, le pattern est la partie importante. Le même mécanisme sert à exécuter des scripts Python, à lancer Blender en mode “arrière-plan” pour le rendu, ou à effectuer des contrôles de validation avant qu’une tâche soit considérée comme terminée. Chaque tâche est conçue pour être atomique et redémarrable : cela signifie qu’en cas de crash d’un worker ou d’échec d’un rendu à 3 h du matin, Flamenco peut réessayer uniquement cette tâche sans compromettre l’ensemble du job. Cette fiabilité permet à cette approche de passer à l’échelle quand vous exécutez des centaines de plans pendant la nuit.",[48,9012,9013],{},"Passons maintenant à la partie la plus “dense” du tutoriel : coder une tâche qui télécharge des assets depuis Kitsu, rend avec Blender, puis re-téléverse le résultat vers Kitsu.",[61,9015],{},[64,9017,9019],{"id":9018},"_3-subcommand-1-downloading-assets-from-kitsu","3. Sous-commande 1 : Télécharger des assets depuis Kitsu",[48,9021,9022],{},"La première vraie tâche de notre job piloté par Kitsu consiste à récupérer exactement les données dont nous avons besoin depuis Kitsu et à préparer un espace de travail local propre sur le worker. Avant même que Blender démarre, le worker doit savoir quelle tâche il rend et où se trouvent les fichiers du job.",[48,9024,9025,9026,9029,9030,166],{},"Au lieu d’écrire la logique en Javascript, nous utilisons le bien plus simple SDK Python gazu pour créer un script ",[155,9027,9028],{},"kitsu-render",", puis l’appelons depuis Javascript. Si vous n’avez pas Python installé dans l’environnement de votre worker, envisagez ",[94,9031,9033],{"href":9032},"https://blog.cg-wire.com/kitsu-cli-single-binary/","de créer un binaire exécutable à partir du script Python",[152,9035,9036,9050],{},[155,9037,9039,9040,9043],{"className":9038},[8928],"function compileJob(job) {\nconst settings = job.settings;",[48,9041,9042],{},"const task = author.Task(\"kitsu-render\", \"misc\");",[48,9044,9045,9046,9049],{},"task.addCommand(\nauthor.Command(\"exec\", { exe: \"python3\", args: ",[262,9047,9048],{},"\"kitsu-render.py\""," }),\n);",[48,9051,9052],{},[155,9053,9055],{"className":9054},[8928],"job.addTask(task);\n}\n",[48,9057,9058],{},"Le script Python s’authentifie auprès de l’API Kitsu, recherche des tâches de rendu TODO, puis télécharge le fichier de preview associé contenant un projet .blend à rendre.",[152,9060,9061,9119],{},[155,9062,9064,9065,9072,9076,9078,9081,9098,9101,9107,9110],{"className":9063},[175],"import os\nimport gazu",[48,9066,182,9067,188,9070,863],{},[94,9068,185],{"href":185,"rel":9069},[187],[94,9071,192],{"href":191},[48,9073,260,9074],{},[262,9075,264],{},[48,9077,267],{},[48,9079,9080],{},"rendering = gazu.task.get_task_type_by_name(\"Rendering\")\ntodo = gazu.task.get_task_status_by_name(\"todo\")",[48,9082,9083,9084],{},"render_tasks = ",[262,9085,9086,9087,9089,9090,9092,9093,9095,9096],{},"\nt\nfor t in tasks\nif t",[262,9088,2944],{}," == rendering",[262,9091,2327],{}," and t",[262,9094,2940],{}," == todo",[262,9097,2327],{},[48,9099,9100],{},"for task in render_tasks:\nfiles = gazu.files.get_all_preview_files_for_task(task)\nif not files:\ncontinue",[152,9102,9105],{"className":9103,"code":9104,"language":291},[289],"latest = files[-1]\nif latest[\"extension\"] == \"blend\":\n    task_to_render = task\n    latest_blend = latest\n    break\n",[155,9106,9104],{"__ignoreMap":12},[48,9108,9109],{},"if task_to_render is None:\nraise RuntimeError(\"No render task with a .blend preview found\")",[48,9111,9112,9113,9115,9116,9118],{},"target_path = os.path.join(\n\"/tmp\", latest_blend",[262,9114,2090],{}," + \".\" + latest_blend",[262,9117,2094],{},"\n)",[48,9120,9121],{},[155,9122,9124],{"className":9123},[175],"gazu.files.download_preview_file(latest_blend, target_path)\n",[48,9126,9127],{},"Cette étape rend un workflow sans NAS viable. Chaque worker récupère uniquement les fichiers dont il a besoin pour la tâche spécifique qu’il exécute, au lieu de monter ou synchroniser un arbre de production complet. Si le téléchargement échoue, Flamenco peut réessayer automatiquement la tâche sans intervention humaine.",[61,9129],{},[64,9131,9133],{"id":9132},"_4-subcommand-2-blender-render","4. Sous-commande 2 : Rendu Blender",[48,9135,9136,9137,9141,9142,1654],{},"Une fois le fichier blend à rendre préparé localement sur le worker, nous pouvons ",[94,9138,9140],{"href":9139},"https://blog.cg-wire.com/blender-programmatic-rendering/","le rendre de façon programmatique"," avec la bibliothèque ",[155,9143,2136],{},[152,9145,9146,9159],{},[155,9147,9149,9150,9156],{"className":9148},[724],"bpy.ops.wm.open_mainfile(filepath=target_path)",[48,9151,9152,9153,9155],{},"output_path = os.path.join(\n\"/tmp\", latest_blend",[262,9154,2331],{}," + \".mp4\"\n)",[48,9157,9158],{},"bpy.context.scene.render.image_settings.file_format = \"FFMPEG\"\nbpy.context.scene.render.ffmpeg.format = \"MPEG4\"\nbpy.context.scene.render.ffmpeg.codec = \"H264\"\nbpy.context.scene.render.ffmpeg.constant_rate_factor = \"HIGH\"\nbpy.context.scene.render.ffmpeg.gopsize = 12\nbpy.context.scene.render.ffmpeg.audio_codec = \"AAC\"\nbpy.context.scene.render.filepath = output_path",[48,9160,9161],{},[155,9162,9164],{"className":9163},[724],"bpy.ops.render.render(animation=True)\n",[48,9166,9167],{},"Un pipeline plus avancé exploiterait la commande native “blender-render” de Flamenco pour découper automatiquement la plage de frames en unités de travail plus petites et les distribuer sur les workers disponibles. Si une machine tombe ou qu’une frame échoue, seules ces frames sont relancées : il n’est donc pas nécessaire de redémarrer tout le plan, ni de construire une logique de file d’attente personnalisée pour gérer le parallélisme.",[48,9169,9170],{},"Mais pour garder notre exemple simple, nous rendons simplement toute la vidéo sur un seul worker.",[61,9172],{},[64,9174,9176],{"id":9175},"_5-subcommand-3-uploading-results-back-to-kitsu","5. Sous-commande 3 : Téléverser les résultats vers Kitsu",[48,9178,9179,9180,9184],{},"La dernière étape du job est ",[94,9181,9183],{"href":9182},"https://blog.cg-wire.com/blender-kitsu-low-res-preview/","une sous-commande “post-render” qui renvoie les résultats de rendu vers Kitsu",". À ce stade, le worker a terminé sa plage de frames en local, et la responsabilité de la ferme passe du calcul à la publication. C’est là que la sortie rendue devient visible pour le reste de la production.",[48,9186,9187],{},"L’exemple ci-dessous montre une instruction Python minimale qui téléverse le fichier vidéo résultant dans Kitsu en tant que pièce jointe sur la tâche d’origine.",[152,9189,9190],{},[155,9191,9193],{"className":9192},[175],"result = gazu.task.publish_preview(\ntask_to_render,\ntodo,\ncomment=\"rendered\",\npreview_file_path=output_path,\n)\n",[48,9195,9196],{},"Dans un pipeline de production réel, cette étape fait généralement plus que simplement téléverser des fichiers. Nous pouvons créer une nouvelle version dans Kitsu, mettre à jour le statut de la tâche à quelque chose comme Done, et déclencher des workflows de review ou de notification afin que les superviseurs sachent que la nouvelle sortie est prête. Comme cette logique est simplement du Python exécuté à l’intérieur d’une tâche Flamenco, il est facile d’évoluer à mesure que les besoins de production changent, sans toucher à la ferme de rendu elle-même.",[61,9198],{},[64,9200,9202],{"id":9201},"_6-triggering-the-workflow","6. Déclencher le workflow",[48,9204,9205],{},"Une fois le type de job personnalisé en place, le workflow est déclenché en soumettant une demande de job au Flamenco Manager. Pendant le développement, cela se fait souvent manuellement en appelant directement l’API REST du Manager. C’est une façon rapide de valider que la compilation du job fonctionne, que les réglages sont correctement câblés, et que les tâches se comportent comme prévu avant d’ajouter une couche d’automatisation.",[48,9207,9208,9209,9211,9212,9215],{},"L’exemple ci-dessous soumet un job de type ",[155,9210,9028],{}," au Manager. Avec, en plus, des métadonnées de base pour le suivi et l’attribution, la requête inclut une valeur de priorité et un objet ",[155,9213,9214],{},"settings"," vide, qui contiendrait normalement des entrées propres à la production, comme un ID de production Kitsu. Lorsque le job est accepté, le Manager invoque le type de job personnalisé, compile les tâches et les planifie sur les workers disponibles.",[152,9217,9218],{},[155,9219,9222,9223,9225,9226,9230,9231,9233,9234,9236,9237,9239,9240,9244],{"className":9220},[9221],"language-sh","curl -X 'POST' ",[125,9224],{},"\n'",[94,9227,9228],{"href":9228,"rel":9229},"http://172.17.0.1:8080/api/v3/jobs",[187],"' ",[125,9232],{},"\n-H 'accept: application/json' ",[125,9235],{},"\n-H 'Content-Type: application/json' ",[125,9238],{},"\n-d '{\n\"metadata\": {\n\"project\": \"kitsu\",\n\"user.email\": \"",[94,9241,9243],{"href":9242},"mailto:basunako@gmail.com","basunako@gmail.com","\",\n\"user.name\": \"kitsu\"\n},\n\"name\": \"Kitsu Render\",\n\"priority\": 50,\n\"settings\": {},\n\"submitter_platform\": \"linux\",\n\"type\": \"kitsu-render\"\n}'\n",[48,9246,9247],{},"Nous pouvons voir que le manager a bien reçu la demande de job et l’a assignée à un worker :",[72,9249,9251],{"className":9250},[34,75],[77,9252],{"src":9253,"className":9254,"alt":12,"loading":82,"width":83,"height":84,"srcSet":9255,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png 1600w",[48,9257,9258],{},"Ce déclenchement manuel est principalement un outil de développement. Il vous permet d’itérer sur la logique des jobs, de tester des cas limites et de relancer des jobs sans impliquer les artistes ni les outils de production.",[48,9260,9261],{},"En production, les studios automatisent toujours cette étape. Un petit service (souvent un cron ou un listener webhook léger) interroge périodiquement Kitsu pour trouver des tâches prêtes à être rendues, comme des plans nouvellement approuvés ou publiés. Lorsqu’il en trouve une, il soumet un job correspondant au Flamenco Manager en utilisant le même appel API.",[48,9263,9264],{},"Une fois cela en place, Flamenco devient un backend de rendu conscient de la production, plutôt que d’attendre que des humains appuient sur des boutons : il réagit automatiquement aux changements dans Kitsu et garde la ferme synchronisée avec l’état de la production.",[61,9266],{},[64,9268,508],{"id":507},[48,9270,9271],{},"Ce que vous avez construit dans cet article est une manière fondamentalement différente de penser le rendu dans les petits studios.",[48,9273,9274],{},"En utilisant un type de job Flamenco personnalisé pour récupérer du contexte et des données depuis Kitsu, mettre en scène le travail en local, rendre via le planificateur natif de Flamenco, puis renvoyer les résultats de façon asynchrone, vous avez supprimé le besoin de stockage partagé sans sacrifier la fiabilité ni la capacité de montée en charge.",[48,9276,9277],{},"Chaque élément a une responsabilité claire : Kitsu définit ce qui est vrai en production, Flamenco décide comment le travail s’exécute, et votre type de job personnalisé fait l’interface qui les maintient synchronisés. Cette séparation rend le système robuste, débogable et adaptable à mesure que votre pipeline grandit.",[48,9279,9280],{},"Comprendre ce pattern est important, car cela vous permet de construire une infrastructure de rendu qui correspond à la réalité des artistes solo et des micro-studios.",[48,9282,9283,9284,9287],{},"Mais ne vous arrêtez pas là : ",[94,9285,9286],{"href":8883},"cliquez sur le dépôt GitHub de notre exemple"," pour cet article et commencez à rendre dès aujourd’hui !",[31,9289,9291,9294],{"className":9290},[34,35,36],[31,9292,524],{"className":9293},[40],[31,9295,528,9297,9300],{"className":9296},[45],[94,9298,534],{"href":531,"rel":9299},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent leurs bonnes pratiques et organisent parfois des événements en présentiel. Nous serions ravis de vous accueillir ! 😊",[31,9302,9304],{"className":9303},[34,539,540],[94,9305,955],{"href":531,"className":9306},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":9308},[9309,9310,9311,9312,9313,9314,9315,9316],{"id":8889,"depth":548,"text":8890},{"id":8915,"depth":548,"text":8916},{"id":8988,"depth":548,"text":8989},{"id":9018,"depth":548,"text":9019},{"id":9132,"depth":548,"text":9133},{"id":9175,"depth":548,"text":9176},{"id":9201,"depth":548,"text":9202},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1666858452715-1399b952befb?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fHJlbmRlcmluZ3xlbnwwfHx8fDE3NzAwNDMxNzB8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":8812,"featured_at":561,"visibility":562},"/blog-i18n/fr/flamenco-without-nas-kitsu","2026-02-09T10:00:32.000+01:00",{"title":8823,"description":12},"flamenco-without-nas-kitsu","blog-i18n/fr/flamenco-without-nas-kitsu/index",[9325],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"liXMYw6Z2V6Ixs7MWCOoAo7C1w3uEyQAHWrUUPV6tH8",{"id":9328,"title":9329,"authors":9330,"body":9332,"description":12,"extension":557,"feature_image":9835,"html":7,"meta":9836,"navigation":13,"path":9838,"published_at":9839,"seo":9840,"slug":9841,"stem":9842,"tags":9843,"__hash__":9845,"updated_at":9837,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/forward-vs-inverse-kinematics-blender/index.md","Comment utiliser la cinématique directe et la cinématique inverse dans Blender (2026)",[9331],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":9333,"toc":9827},[9334,9352,9355,9358,9360,9366,9373,9391,9394,9408,9411,9413,9419,9425,9432,9435,9460,9462,9468,9471,9483,9492,9501,9509,9517,9526,9532,9542,9547,9556,9568,9578,9584,9592,9601,9604,9607,9609,9615,9618,9626,9636,9648,9656,9672,9680,9708,9718,9726,9741,9751,9761,9764,9767,9769,9775,9788,9791,9794,9796,9800,9803,9806,9809,9821],[31,9335,9337,9341],{"className":9336},[34,35,36],[31,9338,9340],{"className":9339},[40],"🤖",[31,9342,9344,9345,9351],{"className":9343},[45],"Un modèle 3D n’est qu’un mannequin inanimé tant que vous",[94,9346,1917,9348],{"href":9347},"https://blog.cg-wire.com/rigging-in-animation/",[1919,9349,9350],{},"ne le mettez pas en place",". La vraie magie se produit lorsque les animateurs le font bouger, et c’est là qu’intervient la cinématique.",[48,9353,9354],{},"Le problème, c’est que ce n’est pas aussi simple que de déplacer le bras ou la jambe d’un personnage. Si vous poussez trop loin, le coude de votre personnage se plie soudain vers l’arrière, ou sa course ressemble à un jouet à ressort cassé. Si vous jouez trop la prudence, le mouvement paraît raide et robotique. Trouver l’équilibre entre une physique crédible et l’expression, c’est difficile.",[48,9356,9357],{},"Dans cet article, nous allons explorer ce qu’est la cinématique et comment elle fonctionne dans Blender. À la fin, vous aurez créé votre premier rig pour l’animation.",[61,9359],{},[64,9361,9363],{"id":9362},"what-are-kinematics",[120,9364,9365],{},"Qu’est-ce que la cinématique",[48,9367,9368,9369,9372],{},"La cinématique est ",[120,9370,9371],{},"l’étude de la façon dont les choses se déplacent dans l’espace"," sans se soucier des forces qui provoquent le mouvement. En animation, cela signifie se concentrer sur la façon dont les articulations, les membres et les différentes parties d’un personnage ou d’un objet se transforment d’une pose à la suivante, plutôt que de s’inquiéter des muscles ou de la gravité qui les tire.",[72,9374,9376,9383],{"className":9375},[34,75,6343],[77,9377],{"src":9378,"className":9379,"alt":12,"loading":82,"width":9380,"height":9381,"srcSet":9382,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-1727ea30-70cc-42b6-a5e1-085ffa16eef4.png",[81],841,431,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-1727ea30-70cc-42b6-a5e1-085ffa16eef4.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-1727ea30-70cc-42b6-a5e1-085ffa16eef4.png 841w",[6351,9384,9385],{},[6354,9386,9387],{},[652,9388,9390],{"className":9389,"style":122},[6359],"Source : MathWorks",[48,9392,9393],{},"La cinématique donne aux animateurs des règles et des outils pour faire bouger des modèles 3D d’une manière cohérente et crédible. Il est important de distinguer la cinématique directe de la cinématique inverse :",[212,9395,9396,9402],{},[215,9397,9398,9401],{},[120,9399,9400],{},"Cinématique directe"," : En FK, le mouvement commence en haut de la hiérarchie. Si vous voulez déplacer une main, vous faites d’abord pivoter l’épaule, puis le coude, puis le poignet. C’est intuitif pour les arcs et les mouvements naturels (comme faire un signe de la main ou balancer une épée), car vous contrôlez le maillon de la chaîne un par un. Mais cela peut être fastidieux : si vous animez un doigt qui touche un point dans l’espace, vous devez ajuster manuellement toutes les articulations pour les aligner.",[215,9403,9404,9407],{},[120,9405,9406],{},"Cinématique inverse"," : L’IK inverse le problème. Au lieu de faire pivoter chaque articulation, vous placez l’extrémité de la chaîne à l’endroit où vous la voulez (par exemple, la main d’un personnage posée sur une table), et l’ordinateur calcule comment l’épaule et le coude doivent se plier pour atteindre ce point. L’IK est idéale pour les mouvements verrouillés, comme garder les pieds posés au sol pendant que le corps bouge. En revanche, elle peut parfois créer des courbures peu naturelles si elle n’est pas contrôlée avec soin ; vous devrez donc définir des contraintes complexes.",[48,9409,9410],{},"Les animateurs ne choisissent pas l’une ou l’autre exclusivement. Ils passent de la FK à l’IK selon le type de mouvement dont ils ont besoin : la FK pour les arcs fluides, l’IK pour un placement précis, et souvent un mélange des deux afin d’obtenir le déplacement le plus naturel possible du bout à l’autre.",[61,9412],{},[64,9414,9416],{"id":9415},"why-kinematics-are-important",[120,9417,9418],{},"Pourquoi la cinématique est importante",[48,9420,9421,9424],{},[120,9422,9423],{},"La cinématique garantit que le mouvement d’un personnage respecte une logique anatomique"," : les articulations se plient dans le bon sens, les membres gardent les bonnes relations entre eux et les actions s’enchaînent naturellement. Sans cela, même le meilleur modèle 3D paraîtra cassé pendant l’animation. Quand un personnage tend la main pour attraper une tasse sur une table, le coude doit se plier correctement et le poignet doit pivoter naturellement. Sans la cinématique, le bras risque de s’hyperétendre, ou la main pourrait se tordre d’une manière impossible.",[48,9426,9427,9428,9431],{},"En utilisant la cinématique directe et la cinématique inverse, ",[120,9429,9430],{},"les animateurs peuvent contrôler des parties complexes du corps avec beaucoup moins d’étapes",". Au lieu de régler chaque image de chaque articulation, ils peuvent poser des chaînes entières en une seule fois tout en réduisant les erreurs de pose. Au lieu d’ajuster manuellement la cheville, le genou et la hanche à chaque image, l’animateur verrouille simplement le pied à l’endroit voulu grâce à la cinématique inverse, et le logiciel s’occupe du reste.",[48,9433,9434],{},"Essayons de faire le rig d’un modèle simple dans Blender pour mieux comprendre comment cela fonctionne.",[31,9436,9438,9441],{"className":9437},[34,35,4456],[31,9439,112],{"className":9440},[40],[31,9442,9444,9448,9450,129,9452,9454,134,9456],{"className":9443},[45],[117,9445,9446],{},[120,9447,1021],{"style":122},[125,9449],{},[125,9451],{},[125,9453],{},[125,9455],{},[94,9457,9459],{"href":9458},"https://github.com/cgwire/blender-ik-fk?ref=blog.cg-wire.com","https://github.com/cgwire/blender-ik-fk",[61,9461],{},[64,9463,9465],{"id":9464},"forward-kinematics-fk-in-blender",[120,9466,9467],{},"La cinématique directe (FK) dans Blender",[48,9469,9470],{},"La FK, c’est comme déplacer une marionnette : vous contrôlez chaque ficelle une par une, en commençant par l’épaule et en descendant jusqu’aux extrémités des doigts. Chaque rotation s’appuie sur la précédente.",[1692,9472,9473],{},[215,9474,9475,9476,9479,9480,1482],{},"Ajoutez un cube (",[155,9477,9478],{},"Add → Mesh → Cube",") et mettez-le à l’échelle pour obtenir un parallélépipède rectangle. Normalisez l’échelle à 1 pour le biseautage (",[155,9481,9482],{},"Object → Apply → Scale",[72,9484,9486],{"className":9485},[34,75],[77,9487],{"src":9488,"className":9489,"alt":12,"loading":82,"width":83,"height":9490,"srcSet":9491,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png",[81],646,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png 1600w",[1692,9493,9494],{"start":548},[215,9495,9496,9497,9500],{},"En mode Édition, biseautez les arêtes pour arrondir chaque côté. Assurez-vous d’utiliser le mode ",[155,9498,9499],{},"Edge"," et de sélectionner les quatre arêtes dont nous avons besoin. Dans la fenêtre Bevel qui apparaît, augmentez le nombre de segments pour créer des arêtes arrondies.",[72,9502,9504],{"className":9503},[34,75],[77,9505],{"src":9506,"className":9507,"alt":12,"loading":82,"width":83,"height":3008,"srcSet":9508,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png 1600w",[1692,9510,9511],{"start":1803},[215,9512,9513,9514,9516],{},"Créez deux autres segments pour obtenir un bras mécanique. En mode ",[155,9515,4967],{},", sélectionnez le parallélépipède et dupliquez-le. Répétez une fois de plus pour avoir trois segments.",[72,9518,9520],{"className":9519},[34,75],[77,9521],{"src":9522,"className":9523,"alt":12,"loading":82,"width":9524,"height":9525},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-318d3ca9-6f1f-4afe-b602-ccff95474782.png",[81],315,171,[1692,9527,9529],{"start":9528},4,[215,9530,9531],{},"Placez les segments le long de l’axe X pour créer la chaîne. Essayez de les positionner de façon à ce qu’ils puissent se placer bout à bout avec une position de joint bien visible.",[72,9533,9535],{"className":9534},[34,75],[77,9536],{"src":9537,"className":9538,"alt":12,"loading":82,"width":9539,"height":9540,"srcSet":9541,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-82b2e2e0-c34c-46a2-9418-f313e5c0f788.png",[81],847,467,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-82b2e2e0-c34c-46a2-9418-f313e5c0f788.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-82b2e2e0-c34c-46a2-9418-f313e5c0f788.png 847w",[1692,9543,9544],{"start":1725},[215,9545,9546],{},"Configurez la hiérarchie parent-enfant (chaîne FK). Construisez la chaîne de la base vers l’extrémité. Sélectionnez d’abord l’objet enfant, puis associez-le au parent prévu (celui qui est plus proche de la base). Répétez l’opération pour que chaque segment soit parenté au segment précédent.",[72,9548,9550],{"className":9549},[34,75],[77,9551],{"src":9552,"className":9553,"alt":12,"loading":82,"width":9554,"height":9555},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-408d19e7-ccac-4706-90fa-1aa9ace327b7.png",[81],319,218,[1692,9557,9559],{"start":9558},6,[215,9560,9561,9562,655,9564,9567],{},"Placez l’origine de chaque objet au niveau de son joint. Pour que la rotation soit correcte, l’origine doit se trouver à l’extrémité du joint de chaque segment. Utilisez l’outil curseur pour positionner l’origine. Puis, en mode ",[155,9563,4967],{},[155,9565,9566],{},"Object → Set Origin → Origin to 3D Cursor",". Faites-le pour chaque segment.",[72,9569,9571],{"className":9570},[34,75],[77,9572],{"src":9573,"className":9574,"alt":12,"loading":82,"width":9575,"height":9576,"srcSet":9577,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-7a11ca12-b043-4f94-b663-b87271e51597.png",[81],817,416,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-7a11ca12-b043-4f94-b663-b87271e51597.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-7a11ca12-b043-4f94-b663-b87271e51597.png 817w",[1692,9579,9581],{"start":9580},7,[215,9582,9583],{},"Donnez à chaque segment une petite rotation par défaut pour observer comment se comporte la cinématique directe. Lorsque vous pivotez l’objet de base (parent), les enfants suivent grâce à la chaîne de parenté.",[72,9585,9587],{"className":9586},[34,75],[77,9588],{"src":9589,"className":9590,"alt":12,"loading":82,"width":9575,"height":9576,"srcSet":9591,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-50da86d0-88ec-4673-a55b-227f9df93c0b.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-50da86d0-88ec-4673-a55b-227f9df93c0b.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-50da86d0-88ec-4673-a55b-227f9df93c0b.png 817w",[48,9593,9594,9595,9600],{},"Vous pouvez ensuite simplement faire pivoter le bras comme vous le souhaitez, créer des images-clés pour la position, et",[94,9596,1917,9597],{"href":2737},[1919,9598,9599],{},"rendre le résultat final pour obtenir une animation"," !",[48,9602,9603],{},"Comme vous pouvez le constater, la FK est excellente pour les mouvements fluides en arc, comme faire un signe de la main, balancer une batte ou danser.",[48,9605,9606],{},"Pour des rigs plus avancés (IK, contrôles, contraintes), les animateurs Blender utilisent une Armature au lieu de la parenté d’objets.",[61,9608],{},[64,9610,9612],{"id":9611},"inverse-kinematics-ik-in-blender",[120,9613,9614],{},"La cinématique inverse (IK) dans Blender",[48,9616,9617],{},"L’IK ressemble davantage au contrôle de la main d’une marionnette : le bras détermine comment le coude et l’épaule doivent se plier pour vous suivre.",[1692,9619,9620],{},[215,9621,9622,9625],{},[120,9623,9624],{},"Dupliquez le mesh de la main FK."," Sélectionnez votre bras FK en trois segments, dupliquez-le et déplacez-le sur le côté pour conserver la version FK en comparaison.",[72,9627,9629],{"className":9628},[34,75],[77,9630],{"src":9631,"className":9632,"alt":12,"loading":82,"width":9633,"height":9634,"srcSet":9635,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png",[81],1349,526,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png 1349w",[1692,9637,9638],{"start":548},[215,9639,9640,9643,9644,9647],{},[120,9641,9642],{},"Fusionnez les segments en un seul objet."," Sélectionnez la nouvelle copie du bras et joignez chaque segment en un seul mesh (",[155,9645,9646],{},"Select all → Object → Join","). Vous avez maintenant un objet continu qui représente l’ensemble du bras.",[72,9649,9651],{"className":9650},[34,75],[77,9652],{"src":9653,"className":9654,"alt":12,"loading":82,"width":9633,"height":9634,"srcSet":9655,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png 1349w",[1692,9657,9658],{"start":1803},[215,9659,9660,9663,9664,9667,9668,9671],{},[120,9661,9662],{},"Créez une chaîne d’armature."," Ajoutez une Armature dans ",[155,9665,9666],{},"Add → Armature",". Dans l’ ",[120,9669,9670],{},"Edit Mode"," de l’Armature, extrudez des os pour qu’ils correspondent aux segments. Sélectionnez l’extrémité du premier os à extruder et placez-la au niveau du coude. Extrudez à nouveau pour la « main ».",[72,9673,9675],{"className":9674},[34,75],[77,9676],{"src":9677,"className":9678,"alt":12,"loading":82,"width":9633,"height":9634,"srcSet":9679,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png 1349w",[1692,9681,9682],{"start":9528},[215,9683,9684,9687,9688,9691,9692,9695,9696,9703,9704,9707],{},[120,9685,9686],{},"Ajoutez le contrôleur IK."," Passez en ",[120,9689,9690],{},"Pose Mode"," et sélectionnez l’os ",[652,9693,9694],{},"hand",". Appuyez sur ",[155,9697,9698,9699,9702],{},"Shift+I → ",[652,9700,9701],{},"Add Inverse Kinematics"," → Without Targets",". La chaîne IK fera désormais bouger le bras. Dans l’onglet Bone Constraints, définissez ",[652,9705,9706],{},"Chain Length"," = 3.",[72,9709,9711],{"className":9710},[34,75],[77,9712],{"src":9713,"className":9714,"alt":12,"loading":82,"width":9715,"height":9716,"srcSet":9717,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png",[81],1008,423,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png 1008w",[72,9719,9721],{"className":9720},[34,75],[77,9722],{"src":9723,"className":9724,"alt":12,"loading":82,"width":9715,"height":9716,"srcSet":9725,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png 1008w",[1692,9727,9728],{"start":1725},[215,9729,9730,9733,9734,9736,9737,9740],{},[120,9731,9732],{},"Liez le mesh à l’armature (skinning)."," En mode ",[155,9735,4967],{},", sélectionnez d’abord le mesh, puis Ctrl-sélectionnez l’armature. Faites un clic droit sur les objets et sélectionnez ",[155,9738,9739],{},"Parent → Armature Deform → With Automatic Weights",". Blender attribue des groupes de sommets à chaque os afin que le bras suive le rig.",[72,9742,9744],{"className":9743},[34,75],[77,9745],{"src":9746,"className":9747,"alt":12,"loading":82,"width":9748,"height":9749,"srcSet":9750,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c7343c3-1d1b-4ad3-b68a-804bdf1e1ba4.png",[81],992,531,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-0c7343c3-1d1b-4ad3-b68a-804bdf1e1ba4.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c7343c3-1d1b-4ad3-b68a-804bdf1e1ba4.png 992w",[1692,9752,9753],{"start":9558},[215,9754,9755,9687,9758,9760],{},[120,9756,9757],{},"Animer avec l’IK.",[120,9759,9690],{},", attrapez l’os du contrôleur IK et déplacez-le : tout le bras suit naturellement !",[48,9762,9763],{},"Vous pouvez toujours utiliser la FK en déplaçant les os dans la chaîne parent.",[48,9765,9766],{},"Notez que le mesh se déforme par défaut de cette façon. Vous devrez ajouter des Bone Constraints pour obtenir le mouvement souhaité, par exemple en n’autorisant le bras à bouger que le long d’un seul axe afin d’imiter le comportement d’un bras mécanique.",[61,9768],{},[64,9770,9772],{"id":9771},"fkik-switch",[120,9773,9774],{},"Commutateur FK/IK",[48,9776,9777,9778,9781,9782,166],{},"La plupart des rigs dans Blender utilisent un ",[120,9779,9780],{},"système hybride"," : la FK pour les arcs fluides et l’IK pour le contact fixe. En général, un animateur",[94,9783,1917,9785],{"href":9784},"https://blog.cg-wire.com/staging-animation-principle/",[1919,9786,9787],{},"commence avec la FK pour la mise en place gestuelle, puis passe à l’IK pour les moments de contact ou le placement précis",[48,9789,9790],{},"Sur des rigs plus avancés, les animateurs Blender créent une propriété personnalisée (souvent un curseur ou une bascule dans le panneau N ou sur un os de contrôleur) pour passer de la FK à l’IK.",[48,9792,9793],{},"Cela sort du cadre de cet article, mais il est important de l’avoir en tête.",[61,9795],{},[64,9797,9798],{"id":507},[120,9799,508],{},[48,9801,9802],{},"La cinématique est la base du rigging et du skinning, et c’est ce qui fait la différence entre un mannequin 3D rigide et un personnage qui semble vivant.",[48,9804,9805],{},"La cinématique directe vous donne des arcs fluides et un enchaînement naturel, tandis que la cinématique inverse « attache » votre personnage au monde avec un contact crédible.",[48,9807,9808],{},"Mais ne faites pas que la lire : ouvrez Blender, prenez un modèle et commencez à jouer ! Un rig bien construit ne fait pas que relier les os : il définit la manière dont un personnage se déplace, se met en pose et interagit avec le monde 3D.",[31,9810,9812,9815],{"className":9811},[34,35,36],[31,9813,524],{"className":9814},[40],[31,9816,528,9818,535],{"className":9817},[45],[94,9819,8788],{"href":531,"rel":9820},[533],[31,9822,9824],{"className":9823},[34,539,540],[94,9825,1797],{"href":531,"className":9826},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":9828},[9829,9830,9831,9832,9833,9834],{"id":9362,"depth":548,"text":9365},{"id":9415,"depth":548,"text":9418},{"id":9464,"depth":548,"text":9467},{"id":9611,"depth":548,"text":9614},{"id":9771,"depth":548,"text":9774},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1590285381943-9fbf39f4f75d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fDNEJTIwY2hhcmFjdGVyJTIwcmlnfGVufDB8fHx8MTc2MDkyMDExNnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":9837,"featured_at":561,"visibility":562},"2026-02-20T06:04:27.000+01:00","/blog-i18n/fr/forward-vs-inverse-kinematics-blender","2025-10-28T10:00:04.000+01:00",{"title":9329,"description":12},"forward-vs-inverse-kinematics-blender","blog-i18n/fr/forward-vs-inverse-kinematics-blender/index",[9844],{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"kYxJtTo4b_-RhLsCx4spj8NGCNY96U3YseVsWiPQ8Dc",{"id":9847,"title":9848,"authors":9849,"body":9851,"description":12,"extension":557,"feature_image":10416,"html":7,"meta":10417,"navigation":13,"path":10419,"published_at":10420,"seo":10421,"slug":10422,"stem":10423,"tags":10424,"__hash__":10426,"updated_at":10418,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/kitsu-cli-single-binary/index.md","Créer un CLI Kitsu portable avec Python et Gazu (2026)",[9850],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":9852,"toc":10407},[9853,9864,9871,9876,9883,9886,9889,9892,9898,9900,9904,9911,9921,9928,9935,9960,9962,9966,9975,9981,9987,9993,9999,10025,10032,10038,10044,10046,10050,10055,10058,10065,10080,10087,10093,10099,10101,10105,10115,10118,10125,10145,10148,10150,10154,10168,10178,10184,10191,10194,10200,10214,10226,10229,10235,10241,10251,10254,10256,10260,10263,10277,10280,10286,10289,10326,10364,10367,10373,10375,10377,10383,10389,10401],[31,9854,9856,9860],{"className":9855},[34,35,36],[31,9857,9859],{"className":9858},[40],"🧰",[31,9861,9863],{"className":9862},[45],"Transformez des scripts Python fragiles en un outil unique et fiable qui se contente de fonctionner.",[48,9865,9866,9867,9870],{},"Nous sommes en fin de production, le planning est serré, et vous devez déployer un outil de pipeline essentiel sur une nouvelle machine : quelque chose pour synchroniser les statuts des shots, publier des playblasts ou ",[94,9868,9869],{"href":782},"automatiser un workflow Kitsu",". L’outil en lui-même n’est pas compliqué. C’est simplement du Python. Vous l’avez déjà écrit.",[48,9872,9873],{},[120,9874,9875],{},"Le problème, c’est tout ce qui l’entoure.",[48,9877,9878,9879,9882],{},"La machine sur laquelle vous le déployez n’a pas Python d’installé. Ou alors, elle a une version incorrecte. Le serveur Linux du studio est verrouillé. La machine Windows d’un freelance ne peut pas compiler les dépendances. Quelqu’un demande s’il faut ",[155,9880,9881],{},"pip",", un environnement virtuel ou le SDK Gazu. Et soudain, un « script simple » devient de la documentation, du dépannage… et du temps perdu.",[48,9884,9885],{},"Au lieu de construire des outils de pipeline, vous gérez des environnements.",[48,9887,9888],{},"C’est la partie que personne n’aime : installer Python, figer les versions, traquer les bibliothèques manquantes, et espérer que rien ne casse lors des mises à jour du système. Et lorsque votre outil doit tourner sur les postes des artistes, sur des nœuds de rendu ou sur des serveurs CI, cette fragilité devient un vrai risque pour la production.",[48,9890,9891],{},"Ce que vous voulez réellement est simple : un outil, une commande, qui fonctionne.",[48,9893,9894,9897],{},[120,9895,9896],{},"Dans cet article, vous allez apprendre à empaqueter vos workflows Kitsu en encapsulant le SDK Python de Kitsu (Gazu) dans une interface en ligne de commande (CLI) et en le compilant en un seul binaire exécutable."," Pas d’installations de Python. Pas de gestion des dépendances. Juste un exécutable fiable que vous pouvez déposer sur n’importe quelle machine et utiliser immédiatement.",[61,9899],{},[64,9901,9903],{"id":9902},"why-you-need-a-cli","Pourquoi avez-vous besoin d’une CLI",[48,9905,9906,9907,9910],{},"Les interfaces graphiques sont excellentes pour le travail créatif, mais ",[120,9908,9909],{},"une fois que vous gérez un pipeline, une interface web peut rapidement devenir un fardeau",". Lorsque vous transférez les bonnes tâches Kitsu dans une CLI, vous débloquez une façon de travailler plus rapide, plus scalable et plus propice à l’automatisation.",[48,9912,9913,9914,9917,9918],{},"Vous finissez d’animer cinq shots et vous devez mettre à jour leurs statuts et envoyer des aperçus. Dans un navigateur, cela implique des changements de contexte : Alt-Tab, ouvrir Chrome, naviguer vers Kitsu, entrer dans le projet, trouver l’épisode, cliquer sur le shot, changer le statut, envoyer la vidéo. Puis recommencer pour chaque shot. Avec une CLI, vous restez exactement où vous êtes. Vous tapez ",[155,9915,9916],{},"kitsu publish --status Review",", vous appuyez sur Entrée, et vous passez à autre chose. ",[120,9919,9920],{},"Vous ne quittez jamais le clavier, vous ne perdez jamais votre focus, et vous n’avez pas à payer le « coût cognitif » des clics dans les menus.",[48,9922,9923,9924,9927],{},"Une CLI vous pousse naturellement à penser en arguments, en listes et en automatisation, et c’est là que ça commence à s’accumuler. ",[120,9925,9926],{},"Si vous pouvez mettre à jour un shot, vous pouvez en mettre à jour dix ou cent avec exactement la même commande."," Vous pouvez boucler sur une séquence, envoyer des noms de shots via un flux, ou piloter l’opération directement depuis un DCC ou une sortie de rendu. Une heure de clics répétitifs dans une interface web devient quelques secondes de travail scripté. Et c’est cohérent, répétable et facile à versionner.",[48,9929,9930,9931,9934],{},"Enfin, ",[120,9932,9933],{},"tout dans un pipeline ne s’exécute pas sur un poste de travail avec un écran."," Parfois, des tâches doivent avoir lieu sur un nœud de ferme de rendu, sur un serveur de build, ou sous forme de processus en arrière-plan qui réagit à des fichiers présents sur le disque. Dans ces environnements, il n’y a ni navigateur, ni utilisateur pour cliquer sur des boutons. Une CLI fonctionne partout où vous avez un shell. Vous pouvez automatiser les publications, les changements de statut, les validations et les opérations de synchronisation, et Kitsu s’intègre plus profondément au pipeline.",[31,9936,9938,9941],{"className":9937},[34,35,108],[31,9939,112],{"className":9940},[40],[31,9942,9944,9948,9950,129,9952,9954,134,9956],{"className":9943},[45],[117,9945,9946],{},[120,9947,1021],{"style":122},[125,9949],{},[125,9951],{},[125,9953],{},[125,9955],{},[94,9957,9959],{"href":9958},"https://github.com/cgwire/blog-tutorials/tree/main/kitsu-cli?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/kitsu-cli",[61,9961],{},[64,9963,9965],{"id":9964},"_1-designing-the-cli-interface","1. Concevoir l’interface de la CLI",[48,9967,9968,9969,309,9972,166],{},"Avant de toucher à l’API Kitsu, il nous faut l’ossature de notre outil. En Python, il existe plusieurs façons d’analyser les arguments de la ligne de commande, mais pour un outil de pipeline professionnel, je recommande fortement d’utiliser des bibliothèques comme ",[155,9970,9971],{},"Click",[155,9973,9974],{},"Typer",[48,9976,9977,9978,166],{},"Pour cette démonstration, imaginons un outil appelé ",[155,9979,9980],{},"kitsu-cli",[48,9982,9983,9986],{},[120,9984,9985],{},"Pensez à votre outil comme à un arbre."," Le tronc est l’exécutable principal, et les branches sont vos commandes et sous-commandes :",[152,9988,9989],{},[155,9990,9992],{"className":9991},[289],"kitsu-cli (root)\n└── production (commands related to productions)\n    └── list (list all productions)\n",[48,9994,9995,9996,9998],{},"Voici comment structurer cette logique en Python avec ",[155,9997,9971],{},". Cette structure est cruciale, car elle rend votre outil extensible. Aujourd’hui, vous gérez des productions ; demain, vous pourriez gérer des assets ou des playlists.",[152,10000,10001,10014],{},[155,10002,10004,10005,10008,10011],{"className":10003},[175],"import click\n",[48,10006,10007],{},"@click.group()\ndef cli():\n\"\"\"My Studio Kitsu Tool\"\"\"\npass",[48,10009,10010],{},"@cli.group()\ndef production():\n\"\"\"Commands for managing productions\"\"\"\npass",[48,10012,10013],{},"@production.command()\n@click.option('--name', help='Filter by name')\ndef list(name):\n\"\"\"List productions\"\"\"\nclick.echo(f\"Listing productions: {name}\")",[48,10015,10016],{},[155,10017,849,10019,10021,10022,10024],{"className":10018},[175],[120,10020,852],{}," == '",[120,10023,856],{},"':\ncli()\n",[48,10026,10027,10028,10031],{},"À lui seul, cet extrait vous donne un menu d’aide. Si l’utilisateur saisit ",[155,10029,10030],{},"kit-cli --help",", il voit la documentation. C’est de l’empathie développeur : construire des outils qui apprennent à l’utilisateur comment s’en servir.",[48,10033,10034,10037],{},[120,10035,10036],{},"Pour exécuter la CLI",", utilisez simplement la même commande que pour un programme Python classique :",[152,10039,10040],{},[155,10041,10043],{"className":10042},[724],"python3 cli.py production list\n",[61,10045],{},[64,10047,10049],{"id":10048},"_2-adding-gazu-features","2. Ajouter des fonctionnalités Gazu",[48,10051,10052,10053,166],{},"Maintenant que nous avons l’ossature, il nous faut les « muscles ». Kitsu fournit un excellent client Python appelé ",[120,10054,2006],{},[48,10056,10057],{},"Si vous n’avez jamais utilisé Gazu auparavant, c’est le pont entre votre script et votre serveur Kitsu.",[48,10059,10060,10061,10064],{},"La première difficulté de tout outil de pipeline, c’est ",[120,10062,10063],{},"l’authentification",". Vous ne voulez pas que vos artistes codent en dur leurs mots de passe dans des scripts. Une CLI robuste vérifie si une session existe déjà. Si ce n’est pas le cas, elle invite l’utilisateur à se connecter une fois et enregistre le token localement. Pour simplifier, nous allons « coder en dur » notre logique d’authentification :",[152,10066,10067,10070],{},[155,10068,2921],{"className":10069},[175],[48,10071,10072],{},[155,10073,182,10075,188,10078,193],{"className":10074},[175],[94,10076,185],{"href":185,"rel":10077},[187],[94,10079,192],{"href":191},[48,10081,10082,10083,10086],{},"Une fois authentifié, nous pouvons étoffer la commande ",[155,10084,10085],{},"list"," que nous avons écrite plus haut. Pour lister les productions :",[152,10088,10089],{},[155,10090,10092],{"className":10091},[175],"@production.command()\n@click.option('--name', help='Filter by name')\ndef list(name):\n\"\"\"List productions\"\"\"\nclick.echo(f\"Listing productions: {name}\")\n",[48,10094,10095,10096],{},"Inutile d’ouvrir un navigateur, d’attendre le chargement de l’application Vue, ni de filtrer la vue. ",[120,10097,10098],{},"Ce script renvoie des données brutes instantanément.",[61,10100],{},[64,10102,10104],{"id":10103},"_3-interactive-interface","3. Interface interactive",[48,10106,10107,10108,10111,10112,166],{},"Les options de commande (comme ",[155,10109,10110],{},"--name test",") sont très bien, mais ",[120,10113,10114],{},"ce serait bien plus agréable de choisir les productions dans une liste interactive",[48,10116,10117],{},"Au lieu d’obliger l’utilisateur à taper le nom exact d’une séquence (qu’il risque inévitablement d’orthographier de travers), nous pouvons rendre notre CLI plus intelligente en ajoutant des invites. Si l’utilisateur oublie de fournir un argument, on lui demande simplement.",[48,10119,10120,10121,10124],{},"Une bibliothèque comme ",[155,10122,10123],{},"questionary"," est idéale pour cela : elle ajoute des listes de sélection interactives et auto-documentées au terminal.",[152,10126,10127,10140],{},[155,10128,10130,10131,10134],{"className":10129},[175],"import questionary",[48,10132,10133],{},"@production.command()\ndef select():\n\"\"\"List available productions\"\"\"\nproductions = gazu.project.all_projects()",[152,10135,10138],{"className":10136,"code":10137,"language":291},[289],"selected_project = questionary.select(\n    \"Which project are you working on?\", choices=productions\n).ask()\n\nclick.echo(f\"You selected {selected_project}. Loading assets...\")\n",[155,10139,10137],{"__ignoreMap":12},[48,10141,10142],{},[155,10143],{"className":10144},[175],[48,10146,10147],{},"Cette petite amélioration change l’expérience utilisateur : on passe de « outil de hacker effrayant » à « assistant utile ». Elle réduit les taux d’erreur à presque zéro, car l’utilisateur ne peut sélectionner que des options valides récupérées directement depuis Kitsu.",[61,10149],{},[64,10151,10153],{"id":10152},"_4-the-single-executable-binary","4. Le binaire exécutable unique",[48,10155,9930,10156,10159,10160,655,10162,655,10165,10167],{},[120,10157,10158],{},"il nous faut résoudre le problème « Ça ne marche pas sur mon ordinateur portable »",". Nous avons un script Python avec des dépendances :",[155,10161,165],{},[155,10163,10164],{},"click",[155,10166,10123],{},", etc.",[48,10169,10170,10171,10174,10175,166],{},"Pour le lancer sur la machine d’un freelance, il faudrait normalement installer Python, ou créer un environnement virtuel, puis ",[155,10172,10173],{},"pip install"," les prérequis. Pour supprimer toutes ces étapes, on peut utiliser ",[155,10176,10177],{},"PyInstaller",[152,10179,10180],{},[155,10181,10183],{"className":10182},[9221],"python3 -m pip install pyinstaller\n",[48,10185,10186,10187,10190],{},"PyInstaller analyse votre script Python, trouve chaque bibliothèque importée, regroupe aussi l’interpréteur Python lui-même, puis encapsule le tout dans un fichier unique ",[155,10188,10189],{},".exe"," (sur Windows) ou un binaire cible (sur Linux/Mac).",[48,10192,10193],{},"Allez dans le dossier de votre script dans votre terminal et lancez :",[152,10195,10196],{},[155,10197,10199],{"className":10198},[158],"python3 -m PyInstaller --onefile --name kitsu-cli cli.py\n",[212,10201,10202,10208],{},[215,10203,10204,10207],{},[155,10205,10206],{},"--onefile"," : ce paramètre indique à PyInstaller d’empaqueter tout dans un seul fichier, plutôt que dans un dossier de dépendances « lâches ».",[215,10209,10210,10213],{},[155,10211,10212],{},"--name"," : le nom du fichier binaire final.",[48,10215,10216,10217,10220,10221,8647,10223,1482],{},"Une fois le processus terminé, vérifiez le dossier ",[155,10218,10219],{},"dist/",". Vous y trouverez un fichier nommé ",[155,10222,9980],{},[155,10224,10225],{},"kitsu-cli.exe",[48,10227,10228],{},"Vous pouvez maintenant prendre ce fichier, le mettre sur une clé USB, l’envoyer par e-mail, ou le déposer sur un lecteur réseau. Un artiste peut le glisser sur son bureau et le lancer tant qu’il a été compilé pour la même architecture système (macOS, Windows, etc.). Il n’a pas besoin que Python soit installé. Il n’a pas besoin d’installer Gazu manuellement. Ça fonctionne juste :",[152,10230,10231],{},[155,10232,10234],{"className":10233},[9221],"./kitsu-cli production list\n",[48,10236,10237,10238,166],{},"Mais ne vous contentez pas de me croire sur parole : testez-le vous-même en ",[94,10239,10240],{},"clonant notre dépôt Github",[72,10242,10244],{"className":10243},[34,75],[77,10245],{"src":10246,"className":10247,"alt":12,"loading":82,"width":10248,"height":10249,"srcSet":10250,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png",[81],1319,913,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png 1319w",[48,10252,10253],{},"Si vous devez compiler votre CLI pour cibler différents systèmes d’exploitation, vous pouvez utiliser Github Actions.",[61,10255],{},[64,10257,10259],{"id":10258},"cli-example-the-render-fetcher","Exemple de CLI : « Render Fetcher »",[48,10261,10262],{},"Passons à un scénario plus centré pipeline.",[48,10264,10265,10266,10269,10270,10273,10274,10276],{},"Imaginez un workflow où vous ",[94,10267,10268],{"href":2737},"gérerez le rendu distribué"," sur plusieurs machines. Chaque nœud de rendu doit régulièrement récupérer de nouvelles tâches depuis Kitsu : des shots marqués ",[652,10271,10272],{},"TODO"," pour le rendu, ainsi que leurs fichiers ",[155,10275,4832],{}," d’aperçu correspondants. Ces machines sont sans interface (headless), verrouillées et volontairement minimales : pas d’installations Python, pas d’environnements virtuels, pas de gestion compliquée des dépendances.",[48,10278,10279],{},"Ce que vous voulez, c’est un exécutable unique que vous pouvez déposer sur n’importe quel serveur et exécuter comme tâche cron ou service :",[152,10281,10282],{},[155,10283,10285],{"className":10284},[158],"./kitsu-cli pull MechaFight /home/user/flamenco/jobs\n",[48,10287,10288],{},"Le code correspondant ressemblerait à ceci :",[152,10290,10291,10316],{},[155,10292,10294,10295,10298,10305,10307,10310],{"className":10293},[175],"import os",[48,10296,10297],{},"import click\nimport gazu\nimport questionary",[48,10299,182,10300,188,10303,863],{},[94,10301,185],{"href":185,"rel":10302},[187],[94,10304,192],{"href":191},[48,10306,10007],{},[48,10308,10309],{},"@cli.command()\n@click.argument(\"project_name\", required=True)\n@click.argument(\"output_path\", required=True)\ndef pull(project_name, output_path):\nclick.echo(f\"Fetching TODO render tasks for project: {project_name}\")",[152,10311,10314],{"className":10312,"code":10313,"language":291},[289],"project = gazu.project.get_project_by_name(project_name)\n\ntasks = gazu.task.all_tasks_for_project(project)\n\nrendering = gazu.task.get_task_type_by_name(\"Rendering\")\ntodo = gazu.task.get_task_status_by_name(\"todo\")\n\nrender_tasks = [\n    t\n    for t in tasks\n    if t[\"task_type_id\"] == rendering[\"id\"] and t[\"task_status_id\"] == todo[\"id\"]\n]\n\nfor task in render_tasks:\n    files = gazu.files.get_all_preview_files_for_task(task)\n    size = len(files)\n\n    if size &gt; 0:\n        latest = files[size - 1]\n        if latest[\"extension\"] == \"blend\":\n            target_path = os.path.join(\n                output_path, latest[\"name\"] + \".\" + latest[\"extension\"]\n            )\n            gazu.files.download_preview_file(latest, target_path)\n",[155,10315,10313],{"__ignoreMap":12},[48,10317,10318],{},[155,10319,849,10321,853,10323,10325],{"className":10320},[175],[120,10322,852],{},[120,10324,856],{},"\":\ncli()\n",[1692,10327,10328,10337,10349,10358],{},[215,10329,10330,10333,10334,10336],{},[120,10331,10332],{},"Interroger Kitsu"," - La CLI se connecte à Kitsu (via Gazu) et récupère toutes les tâches de rendu ayant un statut ",[652,10335,10272],{}," pour un projet donné.",[215,10338,10339,10342,10343,10346,10347,1482],{},[120,10340,10341],{},"Filtrer les tâches"," - Elle filtre les tâches marquées ",[155,10344,10345],{},"todo"," et qui ont un fichier d’aperçu associé (dans ce cas, un fichier ",[155,10348,4832],{},[215,10350,10351,10354,10355,10357],{},[120,10352,10353],{},"Télécharger les assets"," - Pour chaque tâche, la CLI télécharge le fichier d’aperçu ",[155,10356,4832],{}," correspondant vers le chemin de sortie indiqué sur le disque.",[215,10359,10360,10363],{},[120,10361,10362],{},"Rendu"," - Une fois téléchargés, les fichiers sont prêts pour que Blender les récupère, manuellement ou via un orchestrateur de rendu automatisé comme Flamenco.",[48,10365,10366],{},"Lorsque cette CLI est compilée en un binaire unique, le déploiement devient trivial. Vous pouvez la déposer sur des nœuds de rendu Linux et la lancer depuis cron ou systemd, sans installer Python ni les dépendances. Tous les serveurs récupèrent le travail de la même façon. Les structures de dossiers sont cohérentes. L’état des tâches vient directement de Kitsu. Et votre ferme de rendu reste concentrée sur le rendu.",[48,10368,10369,10370,166],{},"Encore une fois, jetez-y un œil sur ",[94,10371,10372],{},"le dépôt Github correspondant",[61,10374],{},[64,10376,508],{"id":507},[48,10378,10379,10382],{},[120,10380,10381],{},"Créer votre propre CLI Kitsu ne doit pas être compliqué."," En encapsulant la bibliothèque Gazu dans une CLI facile à utiliser, puis en la « figeant » avec PyInstaller, vous mettez à l’échelle votre pipeline. Vous supprimez la friction technique liée à la gestion des environnements et vous laissez vos artistes se concentrer sur ce qu’ils font le mieux : créer de belles animations.",[48,10384,10385,10386,9600],{},"En savoir plus sur la combinaison de Kitsu et du scripting Blender en ",[94,10387,10388],{"href":6377},"vous abonnant à notre blog",[31,10390,10392,10395],{"className":10391},[34,35,36],[31,10393,524],{"className":10394},[40],[31,10396,1786,10398,6396],{"className":10397},[45],[94,10399,534],{"href":531,"rel":10400},[533],[31,10402,10404],{"className":10403},[34,539,540],[94,10405,1797],{"href":531,"className":10406},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":10408},[10409,10410,10411,10412,10413,10414,10415],{"id":9902,"depth":548,"text":9903},{"id":9964,"depth":548,"text":9965},{"id":10048,"depth":548,"text":10049},{"id":10103,"depth":548,"text":10104},{"id":10152,"depth":548,"text":10153},{"id":10258,"depth":548,"text":10259},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1484417894907-623942c8ee29?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIxfHxzb2Z0d2FyZSUyMGRldmVsb3BtZW50fGVufDB8fHx8MTc2NzYwNzcwNHww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":10418,"featured_at":561,"visibility":562},"2026-02-20T06:04:43.000+01:00","/blog-i18n/fr/kitsu-cli-single-binary","2026-01-12T10:00:37.000+01:00",{"title":9848,"description":12},"kitsu-cli-single-binary","blog-i18n/fr/kitsu-cli-single-binary/index",[10425],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"wO5YwNE_psD6OZzMU2E33RAMXHkFgP_Mzlq3xT-J4jU",{"id":10428,"title":10429,"authors":10430,"body":10432,"description":12,"extension":557,"feature_image":10923,"html":7,"meta":10924,"navigation":13,"path":10926,"published_at":10925,"seo":10927,"slug":10928,"stem":10929,"tags":10930,"__hash__":10932,"updated_at":10925,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/kitsu-telegram-bot-integration/index.md","Intégrer des plateformes de messagerie aux données de production de Kitsu",[10431],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":10433,"toc":10915},[10434,10445,10448,10451,10458,10460,10464,10467,10470,10481,10484,10486,10490,10493,10496,10507,10510,10520,10523,10530,10537,10543,10554,10557,10563,10566,10574,10577,10584,10586,10590,10593,10600,10603,10633,10645,10652,10663,10672,10674,10678,10684,10687,10716,10719,10722,10737,10740,10746,10748,10752,10755,10762,10765,10780,10783,10806,10812,10815,10822,10837,10840,10843,10849,10852,10869,10875,10884,10886,10888,10891,10894,10897,10909],[31,10435,10437,10441],{"className":10436},[34,35,36],[31,10438,10440],{"className":10439},[40],"💬",[31,10442,10444],{"className":10443},[45],"Transformez les événements de production en notifications et commandes instantanées grâce à un bot de messagerie Kitsu.",[48,10446,10447],{},"Les interfaces de chat dominent le lieu de travail moderne : les équipes de production coordonnent leurs actions dans des conversations, les validations se font par e-mail, et les assistants basés sur des LLM deviennent une partie des opérations quotidiennes.",[48,10449,10450],{},"Le vrai problème, c’est l’intégration correcte. Un message qui dit « Shot prêt à être revu » devrait permettre à un superviseur d’approuver ce shot et de mettre à jour le statut dans Kitsu pour le bon utilisateur, mais, dans un monde idéal, cela nécessiterait un petit service backend, une connexion API sécurisée à Kitsu et un mappage fiable entre les utilisateurs du chat et les utilisateurs de Kitsu. Bonne nouvelle : vous pouvez déjà le faire avec Kitsu !",[48,10452,10453,10454,10457],{},"Un point de départ simple consiste à utiliser un bot Telegram avec une commande comme ",[155,10455,10456],{},"/hello",". Le bot associe l’utilisateur du chat à son compte Kitsu une seule fois, puis répond via l’API et l’affiche dans le chat. À chaque fois qu’un événement survient dans Kitsu, le bot vous notifie. Cette petite intégration prouve le concept, et c’est exactement ce que nous allons construire dans cet article.",[61,10459],{},[64,10461,10463],{"id":10462},"why-custom-messaging-integrations","Pourquoi créer des intégrations de messagerie sur mesure",[48,10465,10466],{},"Les intégrations de messagerie sur mesure centralisent la communication autour d’une source unique de vérité. Au lieu que les superviseurs transfèrent des e-mails concernant un changement d’état d’une tâche, la mise à jour peut être envoyée automatiquement au canal de l’équipe concernée. Par exemple, lorsqu’une tâche d’éclairage passe sur « retake » dans Kitsu, le groupe Telegram de l’éclairage reçoit immédiatement un message structuré avec le nom du shot, l’assigné et la date limite. Le suivi de production devient proactif.",[48,10468,10469],{},"L’expérience utilisateur s’améliore lorsque des événements bruts de base de données sont transformés en résumés lisibles. Les artistes ne devraient pas avoir besoin de parcourir les journaux d’activité pour comprendre ce qui a changé. Un récapitulatif quotidien envoyé dans un canal Telegram peut résumer les validations, les nouvelles attributions et les dates limites à venir en langage clair. Ce récapitulatif peut être généré directement depuis l’API de Kitsu et livré automatiquement chaque soir afin de transformer les données de production en quelque chose que les gens consultent réellement.",[48,10471,10472,10473,10476,10477,10480],{},"Cette approche est là où l’automatisation prend vraiment tout son sens. Les plateformes de messagerie peuvent agir comme des interfaces de commande légères. Un coordinateur qui tape « ",[155,10474,10475],{},"/late_shots"," » sur Telegram peut déclencher une requête contre Kitsu et recevoir instantanément un rapport des tâches en retard. Un lead qui tape « ",[155,10478,10479],{},"/assign SH010 alice"," » peut déclencher un appel backend qui met à jour l’attribution dans Kitsu. Le chat devient une surface opérationnelle pour la base de données de production.",[48,10482,10483],{},"Mais comme nous l’avons dit, commençons simplement avec un bot Telegram qui interagit avec Kitsu.",[61,10485],{},[64,10487,10489],{"id":10488},"_1-create-a-new-telegram-bot","1. Créer un nouveau bot Telegram",[48,10491,10492],{},"Commencez par créer un bot dédié dans Telegram. La séparation permet de garder les identifiants propres et d’éviter les futurs problèmes de sécurité lorsque l’intégration est confiée à l’IT de production.",[48,10494,10495],{},"Ouvrez Telegram et recherchez BotFather, qui est le bot officiel pour gérer d’autres bots.",[48,10497,10498,10499,10502,10503,10506],{},"Démarrez une conversation et envoyez ",[155,10500,10501],{},"/newbot",". Le déroulement est simple : fournissez un nom lisible par des humains comme « Kitsu Notifications », puis un nom d’utilisateur unique, par exemple ",[155,10504,10505],{},"kitsu_pipeline_bot",". Le nom d’utilisateur doit se terminer par « bot » et il doit être globalement unique : attendez-vous à tester plusieurs variantes dans un environnement de studio.",[48,10508,10509],{},"BotFather renvoie un jeton API. Traitez ce jeton comme un secret de production, pas comme une simple chaîne à coller dans Slack ou à valider sur Git. Enregistrez-le dans votre système de configuration d’environnement. Si ce jeton fuit, n’importe qui peut envoyer des messages comme votre bot de production, ce qui peut rapidement passer du divertissement au désastre lorsque des producteurs commencent à recevoir du spam.",[72,10511,10513],{"className":10512},[34,75],[77,10514],{"src":10515,"className":10516,"alt":12,"loading":82,"width":10517,"height":10518,"srcSet":10519,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-10.png",[81],976,925,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-10.png 600w, https://blog.cg-wire.com/content/images/2026/03/image-10.png 976w",[48,10521,10522],{},"Avant de l’intégrer au système d’événements de Kitsu, validons le jeton manuellement.",[48,10524,10525,10526,10529],{},"Recherchez votre bot nouvellement créé par son nom d’utilisateur dans Telegram et lancez une conversation avec lui. Envoyez un simple « ",[155,10527,10528],{},"/start"," » pour que Telegram enregistre votre chat.",[48,10531,10532,10533,10536],{},"Pour récupérer votre identifiant client (chat), appelez l’endpoint ",[155,10534,10535],{},"getUpdates"," avec curl en utilisant le jeton. Par exemple :",[152,10538,10539],{},[155,10540,10542],{"className":10541},[158],"curl https://api.telegram.org/bot\u003CTOKEN>/getUpdates\n",[48,10544,10545,10546,10549,10550,10553],{},"La réponse contiendra une charge utile JSON avec un objet ",[155,10547,10548],{},"chat"," et un champ ",[155,10551,10552],{},"id",". Cet identifiant numérique est celui sur lequel votre intégration se basera. Dans un scénario de pipeline réel, il peut s’agir de l’ID de chat d’un groupe de superviseurs plutôt que d’un utilisateur individuel.",[48,10555,10556],{},"Testez maintenant l’envoi de messages sortants directement. Utilisez curl pour vous envoyer un message à vous-même :",[152,10558,10559],{},[155,10560,10562],{"className":10561},[158],"curl -X POST https://api.telegram.org/bot\u003CTOKEN>/sendMessage -d chat_id=\u003CCHAT_ID> -d text=\"Kitsu integration test\"\n",[48,10564,10565],{},"Si le message apparaît dans Telegram, le jeton et l’ID de chat sont valides. Cette étape de vérification manuelle permet de gagner des heures de débogage plus tard, lorsque vous branchez le même appel dans un hook d’événement Kitsu et que quelque chose échoue silencieusement.",[72,10567,10569],{"className":10568},[34,75],[77,10570],{"src":10571,"className":10572,"alt":12,"loading":82,"width":10517,"height":10518,"srcSet":10573,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-11.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-11.png 600w, https://blog.cg-wire.com/content/images/2026/03/image-11.png 976w",[48,10575,10576],{},"Une fois le bot validé, l’étape suivante consiste à le connecter au système d’événements de Kitsu pour que, par exemple, lorsqu’un nouvel asset est créé, un message soit automatiquement envoyé au groupe Telegram des superviseurs.",[48,10578,10579,10580,10583],{},"Le même endpoint ",[155,10581,10582],{},"sendMessage"," que vous avez testé avec curl devient une partie d’un petit service ou d’une fonction sans serveur déclenchée par Kitsu.",[61,10585],{},[64,10587,10589],{"id":10588},"_2-set-a-kitsu-event-listener","2. Configurer un écouteur d’événements Kitsu",[48,10591,10592],{},"Ensuite, nous devons nous abonner aux événements en temps réel provenant de Kitsu. L’objectif est simple : réagir dès que les données de production changent.",[48,10594,10595,10596,10599],{},"Nous pouvons utiliser le SDK Python ",[155,10597,10598],{},"zou"," de Kitsu pour ouvrir une connexion websocket et écouter les événements de mise à jour des tâches.",[48,10601,10602],{},"Par exemple, connectez-vous au flux d’événements Kitsu et filtrez les événements de création d’assets :",[152,10604,10605,10627],{},[155,10606,10608,10609,10622],{"className":10607},[175],"import gazu \n",[48,10610,182,10611,10615,10616,10619,10620,863],{},[94,10612,10613],{"href":10613,"rel":10614},"http://localhost:80/api",[187],"\")\ngazu.set_event_host(\"",[94,10617,10613],{"href":10613,"rel":10618},[187],"\")\ngazu.log_in(\"",[94,10621,192],{"href":191},[48,10623,10624,10625,1330],{},"def my_callback(data):\nprint(\"Asset created %s\" % data",[262,10626,2072],{},[48,10628,10629],{},[155,10630,10632],{"className":10631},[175],"event_client = gazu.events.init()\ngazu.events.add_listener(event_client, \"asset:new\", my_callback)\ngazu.events.run_client(event_client)\n",[48,10634,10635,10636,10638,10639,10644],{},"Nous utilisons la bibliothèque ",[155,10637,165],{}," pour nous connecter à un serveur API Kitsu hébergé localement à ",[155,10640,10641],{},[94,10642,10613],{"href":10613,"rel":10643},[187],", pour nous authentifier avec les identifiants admin fournis, puis pour écouter les événements en temps réel.",[48,10646,10647,10648,10651],{},"Le snippet définit une fonction de rappel ",[155,10649,10650],{},"my_callback"," qui affiche l’ID d’un nouvel asset créé, chaque fois qu’elle est déclenchée.",[48,10653,10654,10655,10658,10659,10662],{},"Après avoir initialisé un client d’événements avec ",[155,10656,10657],{},"gazu.events.init()",", le script enregistre le rappel pour écouter l’événement ",[155,10660,10661],{},"\"asset:new\""," (qui se déclenche chaque fois qu’un nouvel asset est créé dans le système).",[48,10664,10665,10668,10669,166],{},[155,10666,10667],{},"gazu.events.run_client(event_client)"," démarre la boucle d’événements qui maintient le script en exécution afin que, chaque fois qu’un nouvel asset est ajouté dans Kitsu, le rappel s’exécute et affiche son ",[155,10670,10671],{},"asset_id",[61,10673],{},[64,10675,10677],{"id":10676},"_3-use-the-telegram-api-to-send-a-message","3. Utiliser l’API Telegram pour envoyer un message",[48,10679,10680,10681,10683],{},"Pendant que les événements arrivent, envoyez des messages via l’endpoint ",[155,10682,10582],{}," de Telegram comme nous l’avons fait plus tôt pour les tests. L’API n’est qu’un HTTP POST qui inclut le jeton du bot, l’ID du chat et la charge utile de texte.",[48,10685,10686],{},"Encapsulez cela dans une petite fonction utilitaire :",[152,10688,10689,10711],{},[155,10690,10692,10693,10696,10705],{"className":10691},[175],"import requests\nimport os",[48,10694,10695],{},"TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')\nTELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')",[48,10697,10698,10699,10704],{},"def send_telegram_message(text):\nurl = f\"",[94,10700,10703],{"href":10701,"rel":10702},"https://api.telegram.org/bot%7BTELEGRAM_BOT_TOKEN%7D/sendMessage",[187],"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage","\"\npayload = {\n\"chat_id\": TELEGRAM_CHAT_ID,\n\"text\": text,\n\"parse_mode\": \"Markdown\"\n}",[152,10706,10709],{"className":10707,"code":10708,"language":291},[289],"response = requests.post(url, json=payload, timeout=5)\n\nif not response.ok:\n    raise RuntimeError(\n        f\"Telegram API error {response.status_code}: {response.text}\"\n    )\n",[155,10710,10708],{"__ignoreMap":12},[48,10712,10713],{},[155,10714],{"className":10715},[175],[48,10717,10718],{},"Notez que nous avons défini des variables d’environnement secrètes pour éviter de les conserver dans un dépôt Git.",[48,10720,10721],{},"Puis appelez-la depuis le callback d’événement :",[152,10723,10724,10728],{},[155,10725,10727],{"className":10726},[175],"from your_telegram_module import send_telegram_message",[48,10729,10730],{},[155,10731,10733,10734,10736],{"className":10732},[175],"def my_callback(data):\nsend_telegram_message(\"Asset created %s\" % data",[262,10735,2072],{},")\n",[48,10738,10739],{},"Pour tester notre écouteur d’événements :",[152,10741,10742],{},[155,10743,10745],{"className":10744},[158],"TELEGRAM_BOT_TOKEN=\u003CTELEGRAM_BOT_TOKEN> TELEGRAM_CHAT_ID=\u003CCHAT_ID> python server.py\n",[61,10747],{},[64,10749,10751],{"id":10750},"_4-receiving-messages-with-a-custom-kitsu-api-endpoint","4. Recevoir des messages avec un endpoint API Kitsu personnalisé",[48,10753,10754],{},"Les notifications sont utiles, mais la communication bidirectionnelle est là où l’intégration devient vraiment intéressante.",[48,10756,10757,10758,10761],{},"Pour cela, nous devons étendre le backend de Kitsu avec un plugin personnalisé qui enregistre une nouvelle route comme ",[155,10759,10760],{},"/plugins/telegram/webhook",". Veuillez consulter notre guide officiel sur le développement de plugins Kitsu pour les étapes détaillées.",[48,10763,10764],{},"Le manifeste ressemblera à ceci :",[152,10766,10767],{},[155,10768,10771,10772,10776,10777,10779],{"className":10769},[10770],"language-toml","id = \"telegram\"\nname = \"Telegram Bot\"\ndescription = \"Telegram Bot\"\nversion = \"0.1.0\"\nmaintainer = \"Frank Rousseau \u003C",[94,10773,10775],{"href":10774},"mailto:frank@cg-wire.com","frank@cg-wire.com",">\"\nwebsite = \"kitsu.cloud\"\nlicense = \"AGPL-3.0-only\"\nmaintainer_name = \"Frank Rousseau\"\nmaintainer_email = \"",[94,10778,10775],{"href":10774},"\"\nfrontend_project_enabled = true\nfrontend_studio_enabled = true\nicon = \"telegram\"\n",[48,10781,10782],{},"Et notre route personnalisée analysera les commandes entrantes et les associera à des actions backend explicites :",[152,10784,10785,10801],{},[155,10786,10788,10789,10795],{"className":10787},[175],"from flask_restful import Resource",[48,10790,10791,10792,1330],{},"class WebhookResource(Resource):\ndef post(self):\nargs = self.get_args(",[262,10793,10794],{},"\n(\"message\", {}, True),\n(\"chat\", {}, True),\n",[152,10796,10799],{"className":10797,"code":10798,"language":291},[289],"    message = args['message']\n    chat_id = args['chat'].get(\"id\")\n    text = message.get(\"text\", \"\")\n\n    if text == \"/hello\":    \n        send_telegram_message(\"it works\")\n\n    return jsonify({\"status\": \"ok\"})\n",[155,10800,10798],{"__ignoreMap":12},[48,10802,10803],{},[155,10804],{"className":10805},[175],[48,10807,10808,10809,10811],{},"Par souci de simplicité, nous définissons une seule commande ",[155,10810,10456],{},", mais vous pouvez en créer bien d’autres et utiliser des services Kitsu pour interroger des données de production.",[48,10813,10814],{},"Les commandes déterministes sont plus faciles à tester, journaliser et sécuriser. Vous pouvez aller plus loin en appelant un LLM pour mapper une demande en langage naturel vers une commande.",[48,10816,10817,10818,1654],{},"Il suffit d’enregistrer la route dans l’entrée principale ",[155,10819,10820,1757],{},[120,10821,1756],{},[152,10823,10824,10828],{},[155,10825,10827],{"className":10826},[724],"from . import resources",[48,10829,10830],{},[155,10831,10833,10834],{"className":10832},[724],"routes = ",[262,10835,10836],{},"(f\"/telegram/webhook\", resources.WebhookResource)",[48,10838,10839],{},"Après avoir empaqueté et installé votre plugin sur votre instance de serveur Kitsu, il est temps d’indiquer à votre bot Telegram comment l’atteindre.",[48,10841,10842],{},"Si vous utilisez un environnement de développement local, vous pouvez exposer le serveur via un tunnel. Par exemple, avec ngrok, si votre serveur tourne sur le port 5000 :",[152,10844,10845],{},[155,10846,10848],{"className":10847},[158],"ngrok http 5000\n",[48,10850,10851],{},"Vous devez ensuite configurer le webhook de votre bot Telegram pour pointer vers cette URL :",[152,10853,10854],{},[155,10855,10857,10858,10862,10863,10865,10866,10868],{"className":10856},[158],"curl -X POST \"",[94,10859,10860],{"href":10860,"rel":10861},"https://api.telegram.org/bot&lt;YOUR_BOT_TOKEN&gt;/setWebhook",[187],"\" ",[125,10864],{},"\n-H \"Content-Type: application/json\" ",[125,10867],{},"\n-d '{\"url\": \"https://\u003Crandom>.ngrok-free.app/plugin/telegram/webhook\"}'\n",[48,10870,10871,10872,10874],{},"Envoyez maintenant ",[155,10873,10456],{}," à votre bot dans votre conversation Telegram et observez le résultat :",[72,10876,10878],{"className":10877},[34,75],[77,10879],{"src":10880,"className":10881,"alt":12,"loading":82,"width":10882,"height":10883},"https://blog.cg-wire.com/content/images/2026/03/image-12.png",[81],525,560,[61,10885],{},[64,10887,508],{"id":507},[48,10889,10890],{},"Une intégration de messagerie sur mesure avec Kitsu suit toujours un schéma similaire : créer un bot sur une plateforme de messagerie, s’abonner aux événements de Kitsu, envoyer des notifications structurées et exposer des routes backend pour gérer les messages entrants.",[48,10892,10893],{},"Mais ce n’est pas tout : pensez aussi à étendre votre plugin Kitsu avec des vues !",[48,10895,10896],{},"Par exemple, pour afficher l’activité du bot ou les interactions récentes directement dans le tableau de bord. Les superviseurs travaillant à l’intérieur de Kitsu pourront voir quelles alertes ont été envoyées et quelles commandes ont été déclenchées. Les possibilités sont infinies !",[31,10898,10900,10903],{"className":10899},[34,35,36],[31,10901,524],{"className":10902},[40],[31,10904,1786,10906,535],{"className":10905},[45],[94,10907,534],{"href":531,"rel":10908},[533],[31,10910,10912],{"className":10911},[34,539,540],[94,10913,546],{"href":531,"className":10914},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":10916},[10917,10918,10919,10920,10921,10922],{"id":10462,"depth":548,"text":10463},{"id":10488,"depth":548,"text":10489},{"id":10588,"depth":548,"text":10589},{"id":10676,"depth":548,"text":10677},{"id":10750,"depth":548,"text":10751},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1577563908411-5077b6dc7624?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fG1lc3NhZ2V8ZW58MHx8fHwxNzczMDM5MzU5fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":10925,"featured_at":561,"visibility":562},"2026-03-09T08:00:23.000+01:00","/blog-i18n/fr/kitsu-telegram-bot-integration",{"title":10429,"description":12},"kitsu-telegram-bot-integration","blog-i18n/fr/kitsu-telegram-bot-integration/index",[10931],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"cyNggdBnGd2GnkftW0OaYj0hVpHvdrj6fRgmMtJQFz4",{"id":10934,"title":10935,"authors":10936,"body":10938,"description":12,"extension":557,"feature_image":11302,"html":7,"meta":11303,"navigation":13,"path":11305,"published_at":11304,"seo":11306,"slug":11307,"stem":11308,"tags":11309,"__hash__":11311,"updated_at":11304,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/kitsu-webhooks-pipeline-automation/index.md","Utiliser les webhooks Kitsu pour déclencher des actions de pipeline",[10937],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":10939,"toc":11293},[10940,10950,10957,10960,10967,10970,10995,10997,11001,11009,11012,11015,11018,11021,11024,11027,11029,11033,11039,11062,11065,11067,11071,11077,11101,11111,11118,11123,11129,11142,11154,11156,11160,11163,11190,11197,11200,11207,11213,11216,11218,11222,11225,11228,11231,11234,11241,11243,11247,11250,11253,11259,11262,11265,11267,11269,11272,11275,11287],[31,10941,10943,10946],{"className":10942},[34,35,36],[31,10944,2579],{"className":10945},[40],[31,10947,10949],{"className":10948},[45],"Transformez les événements de production en actions de pipeline instantanées grâce aux webhooks Kitsu.",[48,10951,10952,10953,10956],{},"Quand un studio grandit, les fissures d’un pipeline manuel deviennent plus bruyantes : un artiste publie un actif, un superviseur approuve un plan, une tâche passe à ",[652,10954,10955],{},"Terminé",", mais quelque part plus tard, un autre outil attend encore d’être informé. Ces retards s’accumulent.",[48,10958,10959],{},"L’API d’événements de Kitsu change la donne en diffusant ce qui se passe en production au moment même où cela se produit. Pas de vérifications périodiques, pas de suppositions. Juste des signaux en temps réel sur lesquels vous pouvez agir.",[48,10961,10962,10963,10966],{},"Avec les webhooks, vous pouvez déclencher des actions automatisées dès que les données de production changent, comme ",[94,10964,10965],{"href":9139},"lancement de rendus",", synchronisation des outils de tracking, notification des équipes ou mise à jour de systèmes en aval, sans relances humaines.",[48,10968,10969],{},"Dans cet article, nous allons détailler comment les configurer et les mettre à profit, avec un exemple concret, testé en studio, que vous pouvez intégrer à un pipeline réel.",[31,10971,10973,10976],{"className":10972},[34,35,108],[31,10974,112],{"className":10975},[40],[31,10977,10979,10983,10985,129,10987,10989,134,10991],{"className":10978},[45],[117,10980,10981],{},[120,10982,1021],{"style":122},[125,10984],{},[125,10986],{},[125,10988],{},[125,10990],{},[94,10992,10994],{"href":10993},"https://github.com/cgwire/blog-tutorials/tree/main/kitsu-webhooks%20?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/kitsu-webhooks%20",[61,10996],{},[64,10998,11000],{"id":10999},"why-webhooks","Pourquoi les webhooks",[72,11002,11004],{"className":11003},[34,75],[77,11005],{"src":11006,"className":11007,"alt":12,"loading":82,"width":83,"height":84,"srcSet":11008,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png 1600w",[48,11010,11011],{},"Interroger l’API toutes les quelques minutes revient à demander des mises à jour à la production en criant à travers toute la salle : c’est lent, bruyant et facile à manquer au moment exact où quelque chose compte.",[48,11013,11014],{},"Les webhooks inversent ce modèle : au lieu de vérifier si Kitsu a changé, Kitsu informe votre pipeline immédiatement quand c’est le cas.",[48,11016,11017],{},"En pratique, cela apporte plusieurs bénéfices : un modéliseur crée une nouvelle prop dans Kitsu, et en quelques secondes, votre système de génération d’actifs met en place la structure de répertoires correcte sur le serveur, enregistre l’actif dans vos outils DCC, et le rend visible pour le layout. Personne n’a besoin de copier un nom ou de cliquer sur un bouton.",[48,11019,11020],{},"Plus tard dans le planning, une tâche d’éclairage passe à Terminé. Ce simple changement de statut peut déclencher automatiquement votre système de gestion des rendus pour envoyer le plan, en utilisant les derniers fichiers approuvés et les réglages de rendu corrects pour la production. Au moment où quelqu’un constate que la tâche est terminée, les images sont déjà en train d’être rendues.",[48,11022,11023],{},"Lorsqu’un artiste publie un fichier, le webhook peut pousser cette version directement dans votre pile de review. Le média est transcodé, téléversé et rattaché au bon plan avant que le superviseur n’ouvre sa boîte de réception. Les reviews ont lieu plus tôt, les commentaires reviennent plus vite, et le travail continue de circuler au lieu d’attendre que quelqu’un se souvienne de l’étape suivante.",[48,11025,11026],{},"C’est ce que les webhooks vous permettent d’obtenir : des données de production qui se transforment directement en action. Moins de relances, des boucles de feedback plus serrées, et un pipeline qui réagit aussi vite que vos artistes travaillent.",[61,11028],{},[64,11030,11032],{"id":11031},"available-events","Événements disponibles",[48,11034,11035,11036,1654],{},"Kitsu émet des événements pour toutes les actions de production couvertes par ",[94,11037,11038],{"href":250},"les modèles de données disponibles",[212,11040,11041,11044,11047,11050,11053,11056,11059],{},[215,11042,11043],{},"Création et mises à jour d’actifs",[215,11045,11046],{},"Création et mises à jour de plans",[215,11048,11049],{},"Changements de statut des tâches",[215,11051,11052],{},"Création et publication des fichiers de preview",[215,11054,11055],{},"Gestion des personnes",[215,11057,11058],{},"Changements au niveau de l’organisation",[215,11060,11061],{},"Mises à jour de plans et de séquences",[48,11063,11064],{},"Chaque événement transporte des données structurées (ID, timestamps, informations utilisateur) afin que vous puissiez identifier précisément ce qui a changé et réagir en conséquence : un journal de production en temps réel auquel vous pouvez vous abonner !",[61,11066],{},[64,11068,11070],{"id":11069},"_1-create-an-event-listener","1. Créer un écouteur d’événements",[48,11072,11073,11074,11076],{},"La première étape consiste à enregistrer un écouteur d’événements à l’aide du client Python Kitsu (",[155,11075,165],{},"). Cet écouteur agit comme un point de terminaison de webhook : il attend les événements et appelle votre fonction de rappel lorsqu’ils surviennent.",[152,11078,11079,11096],{},[155,11080,176,11082,11092],{"className":11081},[724],[48,11083,182,11084,10615,11087,188,11090,863],{},[94,11085,185],{"href":185,"rel":11086},[187],[94,11088,185],{"href":185,"rel":11089},[187],[94,11091,192],{"href":191},[48,11093,10624,11094,1330],{},[262,11095,2072],{},[48,11097,11098],{},[155,11099,10632],{"className":11100},[724],[48,11102,11103,11104,498,11107,11110],{},"Tout d’abord, on importe Gazu, le client Python officiel pour Kitsu, et on le configure pour communiquer avec un serveur Kitsu lancé localement. À la fois ",[155,11105,11106],{},"set_host",[155,11108,11109],{},"set_event_host"," pointent vers la même URL d’API : la première est utilisée pour les appels REST classiques, tandis que la seconde est spécifiquement dédiée au point d’entrée des événements (websocket). En production, il est recommandé de configurer les deux dans des threads différents, car l’écoute des événements est bloquante. Mais pour simplifier, nous faisons tout dans un seul point d’entrée dans ce tutoriel.",[48,11112,11113,11114,11117],{},"Ensuite, on s’authentifie en tant qu’utilisateur. Appeler ",[155,11115,11116],{},"gazu.log_in"," se connecte avec les identifiants fournis et établit une session afin que le client soit autorisé à recevoir des événements depuis Kitsu.",[48,11119,8948,11120,11122],{},[155,11121,10650],{}," définit la façon dont votre pipeline réagit lorsqu’un événement est reçu. Elle prend comme entrée la charge utile de l’événement et, dans ce cas, affiche simplement l’ID de l’actif nouvellement créé. Dans un studio d’animation de taille intermédiaire, ce rappel pourrait, par exemple, déclencher un script qui crée une structure de répertoires standardisée sur le serveur de fichiers dès qu’un nouvel actif est ajouté dans Kitsu. Les artistes n’ont plus besoin de le faire manuellement, et les conventions de nommage restent cohérentes.",[48,11124,11125,11126,11128],{},"Après cela, le script initialise un client d’événements avec ",[155,11127,10657],{},". Ce client conserve une connexion persistante avec le système d’événements de Kitsu.",[48,11130,11131,11132,11135,11136,11138,11139,11141],{},"L’appel à ",[155,11133,11134],{},"gazu.events.add_listener"," enregistre la fonction de rappel pour un type d’événement spécifique : ",[155,11137,10661],{},". Cela indique à Gazu : « Chaque fois que Kitsu émet un événement signalant qu’un nouvel actif a été créé, appelez ",[155,11140,10650],{}," avec les données de l’événement. »",[48,11143,9930,11144,11146,11147,11150,11151,11153],{},[155,11145,10667],{}," démarre la boucle d’événements. À partir de ce moment, le script se bloque et écoute en continu via une connexion WebSocket. Dès que quelqu’un crée un actif dans Kitsu, Kitsu émet un événement ",[155,11148,11149],{},"asset:new",", Gazu le reçoit, et ",[155,11152,10650],{}," est exécuté immédiatement.",[61,11155],{},[64,11157,11159],{"id":11158},"_2-send-test-events","2. Envoyer des événements de test",[48,11161,11162],{},"Pour valider votre configuration, vous devez générer de vrais événements. Le moyen le plus simple consiste à effectuer des actions API standard que vous utilisez déjà en production. Par exemple, en créant un actif par programmation :",[152,11164,11165,11184],{},[155,11166,2921,11168,11175,11179],{"className":11167},[724],[48,11169,182,11170,188,11173,863],{},[94,11171,185],{"href":185,"rel":11172},[187],[94,11174,192],{"href":191},[48,11176,260,11177],{},[262,11178,264],{},[48,11180,11181,11182],{},"asset_types = gazu.asset.all_asset_types()\nasset_type = asset_types",[262,11183,264],{},[48,11185,11186],{},[155,11187,11189],{"className":11188},[724],"asset = gazu.asset.new_asset(\nproject,\nasset_type,\n\"My new asset\",\n\"My asset description\"\n)\n",[48,11191,11192,11193,11196],{},"Après l’authentification, nous récupérons la liste de tous les projets visibles pour l’utilisateur connecté en appelant ",[155,11194,11195],{},"gazu.project.all_projects()",". Dans cette liste, nous sélectionnons le premier projet. Dans un outil de production réel, vous chercheriez généralement un projet spécifique par nom ou par ID, mais cela permet de garder l’exemple simple.",[48,11198,11199],{},"Le même schéma est utilisé pour les types d’actifs. Le script interroge tous les types d’actifs disponibles, puis choisit le premier. Les types d’actifs définissent le type d’actif qui est créé (personnage, prop, environnement, etc.), et Kitsu exige qu’on en spécifie un lors de la création d’un nouvel actif.",[48,11201,11202,11203,11206],{},"Avec un projet et un type d’actif en main, nous créons un nouvel actif en appelant ",[155,11204,11205],{},"gazu.asset.new_asset",". La fonction prend le projet cible, le type d’actif, un nom et une description. Lorsque cet appel réussit, Kitsu crée immédiatement l’actif dans sa base de données et renvoie l’objet de l’actif nouvellement créé.",[48,11208,11209,11210,11212],{},"À ce stade, l’actif existe dans Kitsu exactement comme s’il avait été créé via l’interface web. Cette action émet aussi un événement ",[155,11211,11149],{},", permettant au reste de votre pipeline de réagir automatiquement.",[48,11214,11215],{},"Avant de le déployer à tout le studio, un pipeline TD peut créer des actifs dans un projet de staging afin de confirmer que l’événement déclenche bien l’automatisation en aval sans toucher aux données de production réelles.",[61,11217],{},[64,11219,11221],{"id":11220},"_3-react-to-events-with-callbacks","3. Réagir aux événements avec des rappels",[48,11223,11224],{},"Les callbacks sont le moment où les événements Kitsu deviennent des actions concrètes de pipeline. Lorsqu’un rappel est exécuté, il reçoit une charge utile décrivant exactement ce qui a changé : un actif a été créé, une tâche a basculé vers un nouveau statut, ou un fichier a été publié. Cette charge utile devient votre point d’entrée pour piloter l’automatisation.",[48,11226,11227],{},"Une étape fréquente à l’intérieur d’un callback consiste à utiliser les ID présents dans les données de l’événement afin de récupérer le contexte complet depuis Kitsu. Par exemple, lorsqu’un événement de mise à jour de tâche est reçu, vous pouvez récupérer la tâche complète, le plan lié et le projet associé pour comprendre où, dans la production, ce changement s’est produit et quelles règles doivent s’appliquer.",[48,11229,11230],{},"À partir de là, les callbacks réalisent généralement des effets secondaires qui, autrement, nécessiteraient une intervention manuelle. Un événement de création d’actif pourrait, par exemple, entraîner la création d’un arbre de dossiers standardisé sur le disque. Un événement de publication de fichier peut envoyer le média dans votre système de review, y attacher des métadonnées, et le rendre visible aux superviseurs immédiatement.",[48,11232,11233],{},"L’idée clé est que les callbacks permettent à l’état de production de piloter le comportement. Au lieu de laisser des personnes réagir aux mises à jour, votre pipeline le fait, de manière cohérente et instantanée, en utilisant les mêmes règles à chaque fois.",[48,11235,11236,11240],{},[94,11237,11239],{"href":10993,"rel":11238},[533],"Forkez notre dépôt Github d’exemple"," pour l’essayer par vous-même.",[61,11242],{},[64,11244,11246],{"id":11245},"_4-search-events","4. Rechercher des événements",[48,11248,11249],{},"Les événements en direct ne racontent qu’une partie de l’histoire. Kitsu conserve aussi un historique des événements passés, ce qui vous donne une trace fiable de ce qui s’est réellement produit en production. Quand quelque chose tourne mal, ou quand vous devez prouver qu’un traitement a fonctionné, cet historique d’événements est un outil de débogage essentiel.",[48,11251,11252],{},"Via l’API, vous pouvez interroger les événements récents et les filtrer par plage de temps ou par type d’événement. Récupérer les cent derniers événements suffit souvent à obtenir le contexte immédiat après un échec. Réduire la requête à une plage de dates précise permet d’inspecter ce qui s’est passé pendant un créneau particulier ou lors d’une exécution nocturne. Filtrer sur les événements liés aux fichiers est particulièrement utile pour suivre les problèmes de publications et d’ingestion de médias.",[152,11254,11255],{},[155,11256,11258],{"className":11257},[724],"events = gazu.client.get(\"data/events/last?page_size=100\")\nevents = gazu.client.get(\"data/events/last?page_size=100&before=2019-02-01\")\nevents = gazu.client.get(\"data/events/last?page_size=100&before=2019-02-01&after=2019-01-01\")\nevents = gazu.client.get(\"data/events/last?page_size=100&only_files=true\")\n",[48,11260,11261],{},"En pratique, c’est ainsi que vous reconstituez une automatisation cassée. Imaginez qu’un script de publication échoue quelque part pendant la nuit, et que l’équipe du matin constate que des médias manquent dans le système de review. Au lieu de demander aux artistes quand ils ont publié ou de fouiller dans les journaux sur plusieurs machines, vous pouvez interroger Kitsu pour tous les événements de fichiers de la veille. Cela fournit une séquence exacte de publications, avec les timestamps, les utilisateurs et les entités liées.",[48,11263,11264],{},"Vous pouvez aussi suivre des événements spécifiques dans votre pipeline pour produire des rapports de productivité. Par exemple, vous pourriez compiler l’historique d’activité de votre équipe d’animation pour savoir qui a fait quoi.",[61,11266],{},[64,11268,508],{"id":507},[48,11270,11271],{},"Les événements de l’API Kitsu vous offrent une façon propre et fiable de construire des pipelines réactifs. En écoutant les changements de production plutôt que de les interroger régulièrement, vous réduisez la latence, supprimez les étapes manuelles et rendez votre studio plus résilient au fur et à mesure qu’il s’agrandit.",[48,11273,11274],{},"Bien sûr, les webhooks n’iront que jusqu’à votre maîtrise du scripting Kitsu : assurez-vous donc de consulter davantage de tutoriels techniques sur notre blog pour mieux comprendre ce que vous pouvez construire !",[31,11276,11278,11281],{"className":11277},[34,35,36],[31,11279,524],{"className":11280},[40],[31,11282,528,11284,535],{"className":11283},[45],[94,11285,534],{"href":531,"rel":11286},[533],[31,11288,11290],{"className":11289},[34,539,540],[94,11291,1797],{"href":531,"className":11292},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":11294},[11295,11296,11297,11298,11299,11300,11301],{"id":10999,"depth":548,"text":11000},{"id":11031,"depth":548,"text":11032},{"id":11069,"depth":548,"text":11070},{"id":11158,"depth":548,"text":11159},{"id":11220,"depth":548,"text":11221},{"id":11245,"depth":548,"text":11246},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1644088379091-d574269d422f?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGNvbm5lY3Rpb25zfGVufDB8fHx8MTc3MDA0NTM2OXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":11304,"featured_at":561,"visibility":562},"2026-02-23T10:00:39.000+01:00","/blog-i18n/fr/kitsu-webhooks-pipeline-automation",{"title":10935,"description":12},"kitsu-webhooks-pipeline-automation","blog-i18n/fr/kitsu-webhooks-pipeline-automation/index",[11310],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"dUtmV6rU4OtiOAue3yI-Ta6582EpHJ3ZAiMtswH_EsQ",{"id":11313,"title":11314,"authors":11315,"body":11317,"description":12,"extension":557,"feature_image":11692,"html":7,"meta":11693,"navigation":13,"path":11695,"published_at":11694,"seo":11696,"slug":11697,"stem":11698,"tags":11699,"__hash__":11701,"updated_at":11694,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/retopology-animation-blender-guide/index.md","Pourquoi la retopologie est essentielle pour les pipelines d’animation",[11316],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":11318,"toc":11682},[11319,11329,11332,11338,11341,11343,11347,11362,11367,11383,11386,11389,11392,11395,11397,11401,11406,11413,11419,11425,11431,11433,11437,11442,11449,11452,11455,11458,11466,11469,11471,11475,11480,11483,11486,11488,11492,11497,11504,11507,11525,11531,11534,11541,11544,11550,11552,11556,11561,11567,11570,11588,11591,11597,11600,11602,11606,11611,11618,11621,11630,11633,11636,11639,11642,11644,11646,11651,11654,11657,11660,11663,11676],[31,11320,11322,11325],{"className":11321},[34,35,36],[31,11323,1845],{"className":11324},[40],[31,11326,11328],{"className":11327},[45]," La retopologie transforme des maillages 3D en désordre en assets prêts pour l’animation.",[48,11330,11331],{},"Les outils d’IA peuvent désormais générer des modèles 3D en quelques minutes, mais ils produisent généralement une topologie brouillonne : la façon dont les polygones sont disposés à la surface est irrégulière et mal structurée. Cela peut sembler correct à l’œil, mais ça se brisera dès que vous commencerez à l’animer.",[48,11333,11334,11335,166],{},"Si vous faites n’importe quel type d’animation ou de rendu, considérez que ",[120,11336,11337],{},"vous aurez besoin de retopologie",[48,11339,11340],{},"Si vous ne savez pas par où commencer, on s’occupe de vous. Dans cet article, nous allons passer le processus en revue étape par étape et expliquer les différents outils que vous pouvez utiliser pour le rendre plus simple.",[61,11342],{},[64,11344,11346],{"id":11345},"whats-retopology","Qu’est-ce que la retopologie",[31,11348,11350,11353],{"className":11349},[34,35,108],[31,11351,112],{"className":11352},[40],[31,11354,11356,11361],{"className":11355},[45],[117,11357,11358],{},[120,11359,11360],{"style":122},"La retopologie consiste à reconstruire la topologie de surface d’un modèle 3D afin d’obtenir une disposition plus propre des polygones sur un sculpt existant"," pour qu’il se déforme correctement pendant l’animation.",[48,11363,11364],{},[94,11365],{"href":11366},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#whats-retopology",[72,11368,11370,11375],{"className":11369},[34,75,6343],[77,11371],{"src":11372,"className":11373,"alt":12,"loading":82,"width":10883,"height":11374},"https://blog.cg-wire.com/content/images/2026/03/image-5.png",[81],220,[6351,11376,11377],{},[6354,11378,11379],{},[652,11380,11382],{"className":11381,"style":122},[6359],"Source : Blender Manual",[48,11384,11385],{},"Par exemple, on n’anime généralement pas directement le sculpt dense qui sort de ZBrush. À la place, on construit un maillage plus léger et structuré par-dessus.",[48,11387,11388],{},"Un maillage est un objet 3D constitué de sommets (des points), d’arêtes (des lignes entre les points) et de faces (des surfaces).",[48,11390,11391],{},"Avant même de penser au rigging, on examine le maillage en mode filaire et on repère les amas denses, les polygones étirés, ainsi que le flux d’arêtes chaotique (la direction dans laquelle les arêtes suivent sur la surface).",[48,11393,11394],{},"Pour un personnage, par exemple, on pourrait reconstruire l’épaule en utilisant des quads (des polygones à quatre côtés) répartis uniformément plutôt que des triangles, afin que le bras puisse tourner sans pincer. C’est de la retopologie.",[61,11396],{},[64,11398,11400],{"id":11399},"why-retopology-is-key","Pourquoi la retopologie est essentielle",[48,11402,11403],{},[94,11404],{"href":11405},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#why-retopology-is-key",[48,11407,11408,11409,11412],{},"La retopologie reconstruit la surface d’un modèle avec une géométrie propre, et vous en avez besoin si vous voulez ",[120,11410,11411],{},"des assets maintenables et réutilisables"," d’une production à l’autre. Les animateurs n’expédient pas une topologie de sculpt dense en aval. Ils la reconstruisent plutôt avec de belles boucles d’arêtes pour que le prochain animateur ou riggeur puisse comprendre et modifier rapidement.",[48,11414,11415,11418],{},[120,11416,11417],{},"Une bonne retopologie facilite aussi l’animation, car la déformation devient prévisible."," La déformation est la façon dont un maillage change de forme quand un joint pivote, et il faut la soutenir avec des quads répartis uniformément autour des coudes, des genoux et de la bouche. Si vous placez cinq à sept boucles d’arêtes radiales autour d’un joint, vous donnez à la peau assez de géométrie pour se plier sans s’effondrer.",[48,11420,9930,11421,11424],{},[120,11422,11423],{},"maîtriser la densité des polygones réduit le coût de rendu."," Un polygone est une face de géométrie, et plus il y a de polygones, plus il y a de données à traiter. On concentre donc généralement les détails là où les silhouettes changent et on garde les zones plates légères pour réduire les coûts.",[48,11426,11427,11430],{},[120,11428,11429],{},"La retopologie s’avère utile à un moment ou à un autre",", que ce soit pour corriger un modèle 3D ou créer différents niveaux de détail (LOD). Alors retroussez vos manches et entrons dans le vif du sujet.",[61,11432],{},[64,11434,11436],{"id":11435},"_1-back-up-your-3d-model","1. Sauvegardez votre modèle 3D",[48,11438,11439],{},[94,11440],{"href":11441},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#1-back-up-your-3d-model",[48,11443,11444,11445,11448],{},"D’abord, ",[120,11446,11447],{},"il est important de sauvegarder votre modèle avant de toucher à la retopologie",", à chaque fois, sans exception.",[48,11450,11451],{},"Les outils de retopologie automatisés reconstruisent la topologie depuis zéro, ce qui signifie qu’ils écrasent ou suppriment les données de maillage d’origine. Cela arrive souvent : les artistes lancent un passage d’auto-retopo en fin de journée, pour se rendre compte ensuite que le nouveau flux d’arêtes casse la déformation autour des épaules et que le sculpt original a disparu.",[48,11453,11454],{},"Ne comptez pas sur l’annulation (undo). Enregistrez une copie propre et archivez le maillage actuel dans votre scène avant de lancer quoi que ce soit de destructif.",[48,11456,11457],{},"En production, créez aussi une nouvelle version dans Kitsu pour garder les changements traçables et récupérables. Ainsi, si la nouvelle topologie échoue lors des tests de rigging, vous pourrez faire marche arrière en quelques minutes au lieu de demander à l’équipe IT une restauration de fichier.",[72,11459,11461],{"className":11460},[34,75],[77,11462],{"src":11463,"className":11464,"alt":12,"loading":82,"width":3036,"height":3037,"srcSet":11465,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-6.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-6.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-6.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-6.png 1438w",[48,11467,11468],{},"Traitez les sauvegardes comme une partie intégrante du processus de retopologie lui-même ! Un changement de version de deux minutes et une sauvegarde en doublon peuvent protéger des jours de sculpt et maintenir le pipeline en mouvement quand les superviseurs demandent de comparer les maillages « avant » et « après ».",[61,11470],{},[64,11472,11474],{"id":11473},"_2-general-process","2. Processus général",[48,11476,11477],{},[94,11478],{"href":11479},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#2-general-process",[48,11481,11482],{},"Le workflow général est simple : nettoyez le sculpt, faites un remesh voxel pour la stabilité, un remesh quad pour la structure, puis affinez manuellement les zones de déformation comme les épaules et les hanches.",[48,11484,11485],{},"Testez toujours tôt avec des poids de skin rapides et des poses extrêmes.",[61,11487],{},[64,11489,11491],{"id":11490},"_3-automated-retopology-with-remeshing","3. Retopologie automatisée avec remeshing",[48,11493,11494],{},[94,11495],{"href":11496},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#3-automated-retopology-with-remeshing",[48,11498,11499,11500,11503],{},"Si une créature arrive avec 8 millions de polygones et des triangles chaotiques, ",[120,11501,11502],{},"on ne commence pas tout de suite par une retopologie manuelle",". À la place, on lance d’abord un passage de remesh automatisé pour établir la structure.",[48,11505,11506],{},"Pour cela, Blender propose deux algorithmes de remeshing : Voxel et quad.",[72,11508,11510,11517],{"className":11509},[34,75,6343],[77,11511],{"src":11512,"className":11513,"alt":12,"loading":82,"width":11514,"height":11515,"srcSet":11516,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-7.png",[81],1280,720,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-7.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-7.png 1280w",[6351,11518,11519],{},[6354,11520,11521],{},[652,11522,11524],{"className":11523,"style":122},[6359],"Source : Sofia Pahaoja sur Medium",[48,11526,11527,11530],{},[120,11528,11529],{},"Le remeshing voxel"," (VDB Remesh) fonctionne en convertissant le maillage en une grille 3D de petits cubes (des voxels), puis en reconstruisant la surface à partir du volume plutôt que du flux d’arêtes d’origine.",[48,11532,11533],{},"La géométrie produite, uniformément répartie, explique pourquoi c’est idéal pour corriger les trous, la géométrie non-manifold (une structure qu’on ne peut pas déplier en un plan 2D avec des normales de surface cohérentes) et les parties qui s’intersectent. Vous utilisez le voxel quand vous avez besoin d’une base de maillage nouvelle et que vous vous souciez peu de préserver la topologie existante : le résultat peut donc être brouillon.",[48,11535,11536,11537,11540],{},"En revanche, vous pouvez utiliser le ",[120,11538,11539],{},"remeshing quad"," lorsque vous voulez des boucles d’arêtes adaptées à l’animation. Le remeshing quad analyse la courbure de la surface et génère des quads qui se déforment de manière prévisible sous le skinning. QuadriFlow suit la forme de votre modèle.",[48,11542,11543],{},"Bien entendu, vous pouvez combiner les deux. Sur un rig facial, par exemple, vous pourriez lancer un remesh quad après un nettoyage voxel, puis ajuster les guides pour forcer les boucles autour des yeux et de la bouche.",[48,11545,11546,11547],{},"Il est important de garder en tête que ",[120,11548,11549],{},"la retopologie automatisée est le plus souvent un point de départ, pas une livraison finale.",[61,11551],{},[64,11553,11555],{"id":11554},"_4-manual-retopology-with-poly-build","4. Retopologie manuelle avec Poly Build",[48,11557,11558],{},[94,11559],{"href":11560},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#4-manual-retopology-with-poly-build",[48,11562,11563,11566],{},[120,11564,11565],{},"La retopologie manuelle avec l’outil Poly Build"," est ce que vous utilisez quand la qualité de la déformation est essentielle, notamment sur les personnages « hero » qui recevront des plans serrés.",[48,11568,11569],{},"Dans Blender, l’outil Poly Build vous permet de dessiner de nouveaux polygones directement sur la surface d’un maillage dense, en « accrochant » chaque sommet au sculpt.",[72,11571,11573,11580],{"className":11572},[34,75,6343],[77,11574],{"src":11575,"className":11576,"alt":12,"loading":82,"width":11577,"height":11578,"srcSet":11579,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-8.png",[81],1078,516,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-8.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-8.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-8.png 1078w",[6351,11581,11582],{},[6354,11583,11584],{},[652,11585,11587],{"className":11586,"style":122},[6359],"Source : Blender Nation",[48,11589,11590],{},"Pour reprendre l’exemple du rig facial, un artiste pourrait reconstruire la zone de la bouche en plaçant d’abord des quads (des polygones à quatre côtés) autour des lèvres, afin de s’assurer que les boucles d’arêtes suivent les lignes du sourire. Cela donnerait au riggeur des boucles prévisibles pour les blendshapes et éviterait que la géométrie ne s’effondre pendant les phonèmes extrêmes.",[48,11592,11593,11596],{},[120,11594,11595],{},"Vous pouvez aussi utiliser d’autres modificateurs comme le Subdivision Surface Modifier ou le Multiresolution Modifier"," pour accomplir des tâches spécifiques.",[48,11598,11599],{},"Dans cette étape, l’expérience compte énormément. La plupart des animateurs apprennent en étudiant la topologie de modèles de haute qualité, puis en réappliquant les mêmes principes à leurs propres modèles. C’est une connaissance implicite : la pratique est donc essentielle !",[61,11601],{},[64,11603,11605],{"id":11604},"_5-measuring-retopology-performance","5. Mesurer les performances de retopologie",[48,11607,11608],{},[94,11609],{"href":11610},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#5-measuring-retopology-performance",[48,11612,11613,11614,11617],{},"La retopologie consiste autant à l’esthétique, mais ",[120,11615,11616],{},"il est une bonne pratique de mesurer les performances avec des chiffres"," en comptant les maillages présents dans votre scène. De cette façon, vous pouvez estimer la quantité de travail que nécessite une retopologie et suivre votre progression.",[48,11619,11620],{},"Dans Blender, ouvrez l’Outliner et vérifiez combien d’objets de type maillage sont présents, puis activez Statistics dans les overlays de la vue pour voir les nombres de sommets et de faces en temps réel.",[72,11622,11624],{"className":11623},[34,75],[77,11625],{"src":11626,"className":11627,"alt":12,"loading":82,"width":11628,"height":11629},"https://blog.cg-wire.com/content/images/2026/03/image-9.png",[81],317,159,[48,11631,11632],{},"Un modèle de personnage peut sembler léger, mais les statistiques peuvent indiquer 120k faces réparties sur plusieurs maillages de vêtements. Et il suffit parfois de fusionner des accessoires statiques et de supprimer les faces internes invisibles pour réduire fortement le total avant de démarrer des opérations de retopologie plus complexes.",[48,11634,11635],{},"Il est aussi important de prendre en compte le nombre de maillages séparés selon les stratégies de LOD.",[48,11637,11638],{},"LOD, ou Level of Detail (niveau de détail), signifie créer plusieurs versions du même asset avec des résolutions différentes : le moteur les remplace en fonction de la distance de la caméra.",[48,11640,11641],{},"Réduire le nombre de maillages et optimiser les LOD vise également les performances à l’exécution. On retopologise donc des zones clés de déformation comme les épaules et les hanches pour que le LOD inférieur se plie correctement pendant l’animation sans passer trop de temps sur les détails. Le contexte est important.",[61,11643],{},[64,11645,508],{"id":507},[48,11647,11648],{},[94,11649],{"href":11650},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#conclusion",[48,11652,11653],{},"Les modèles 3D générés par IA ont rendu incroyablement rapide le passage d’une idée à un maillage. Mais la vitesse sans structure a un coût. Une topologie propre transforme un asset brut et brouillon en quelque chose de prêt pour la production.",[48,11655,11656],{},"Dans ce guide, nous avons expliqué ce qu’est la retopologie, pourquoi elle compte pour la maintenabilité, l’animation et les performances de rendu, et comment l’aborder étape par étape à l’intérieur de Blender.",[48,11658,11659],{},"Vous avez vu pourquoi sauvegarder votre maillage d’origine est crucial. Ensuite, nous avons exploré la retopologie automatisée à l’aide d’outils de remeshing comme les méthodes Voxel et Quad pour obtenir des résultats rapides, ainsi que la retopologie manuelle avec des modificateurs lorsque la précision compte le plus. Enfin, nous avons étudié comment mesurer les performances en analysant le nombre de maillages et en comprenant les compromis entre les LOD et la topologie.",[48,11661,11662],{},"La retopologie n’est pas seulement une étape de nettoyage. Et même si nous avons montré le processus dans Blender, les mêmes principes s’appliquent à tous les principaux outils DCC : que vous travailliez dans Blender, Maya, Houdini, ou tout autre logiciel 3D, les fondamentaux restent identiques.",[31,11664,11666,11669],{"className":11665},[34,35,36],[31,11667,524],{"className":11668},[40],[31,11670,528,11672,11675],{"className":11671},[45],[94,11673,534],{"href":531,"rel":11674},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent des bonnes pratiques et organisent parfois des événements en personne. Nous serions ravis de vous accueillir ! 😊",[31,11677,11679],{"className":11678},[34,539,540],[94,11680,546],{"href":531,"className":11681},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":11683},[11684,11685,11686,11687,11688,11689,11690,11691],{"id":11345,"depth":548,"text":11346},{"id":11399,"depth":548,"text":11400},{"id":11435,"depth":548,"text":11436},{"id":11473,"depth":548,"text":11474},{"id":11490,"depth":548,"text":11491},{"id":11554,"depth":548,"text":11555},{"id":11604,"depth":548,"text":11605},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1590285359328-dce54ee24c1c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDQwfHxhbmltYXRpb24lMjBtb2RlbHxlbnwwfHx8fDE3NzMwMzgxMDN8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":11694,"featured_at":561,"visibility":562},"2026-03-09T07:41:49.000+01:00","/blog-i18n/fr/retopology-animation-blender-guide",{"title":11314,"description":12},"retopology-animation-blender-guide","blog-i18n/fr/retopology-animation-blender-guide/index",[11700],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"yS1JCmnot4gSARi7KXjfyVP-4v7pterZokB31mlP8gg",{"id":11703,"title":11704,"authors":11705,"body":11707,"description":12,"extension":557,"feature_image":12009,"html":7,"meta":12010,"navigation":13,"path":12012,"published_at":12011,"seo":12013,"slug":12014,"stem":12015,"tags":12016,"__hash__":12018,"updated_at":12011,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/scaling-animation-studio-systems/index.md","Passer d’un studio d’animation de 5 à 50 artistes",[11706],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":11708,"toc":12001},[11709,11720,11723,11726,11731,11734,11736,11740,11745,11748,11755,11763,11770,11777,11779,11783,11788,11791,11798,11801,11808,11816,11823,11831,11833,11837,11842,11845,11851,11854,11863,11866,11869,11875,11882,11884,11888,11893,11896,11901,11904,11910,11920,11927,11929,11933,11938,11941,11947,11961,11963,11965,11970,11977,11980,11983,11995],[31,11710,11712,11716],{"className":11711},[34,35,36],[31,11713,11715],{"className":11714},[40],"📈",[31,11717,11719],{"className":11718},[45],"Faire grandir un studio d’animation, c’est moins embaucher plus d’artistes et davantage construire les bons systèmes.",[48,11721,11722],{},"Dans une petite équipe, tout le monde parle à tout le monde et les problèmes se résolvent en se tournant dans une chaise. À cinquante personnes, cette même habitude crée du bruit et des retards.",[48,11724,11725],{},"La pensée systémique (concevoir des processus répétables plutôt que de compter sur des exploits individuels) est difficile à apprendre sans l’avoir vue au sein d’un studio plus grand. Beaucoup d’artistes ne s’en rendent compte que lorsque le projet dérape, parce que personne n’a défini qui valide les plans, où vivent les fichiers ou comment le feedback est suivi. Multipliez cela par dix nouvelles recrues et une échéance, et le chaos s’installe.",[48,11727,11728],{},[120,11729,11730],{},"Le défi consiste à construire des structures qui rendent le bon travail prévisible. Et la solution consiste à concevoir volontairement, avant que la croissance n’impose des leçons douloureuses, la façon dont circulent l’information, les assets et les décisions.",[48,11732,11733],{},"Dans cet article, nous définissons des bonnes pratiques pour vous aider à anticiper.",[61,11735],{},[64,11737,11739],{"id":11738},"_1-layered-team-structure","1. Structure d’équipe en couches",[48,11741,11742],{},[94,11743],{"href":11744},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#1-layered-team-structure",[48,11746,11747],{},"Quand un studio compte cinq artistes, tout le monde touche à tout et les décisions se prennent dans la même pièce. À cinquante, ce modèle ne mène qu’à la confusion.",[48,11749,11750,11751,11754],{},"Il est important de ",[120,11752,11753],{},"mettre en place tôt une structure d’équipe en couches"," en définissant des départements tels que l’animation, le rigging, l’éclairage ou le compositing, des superviseurs responsables de la direction créative et technique, et des artistes qui exécutent dans ce périmètre. Le superviseur est la personne responsable de la qualité finale et des validations, pas seulement l’animateur le plus senior. Une fois que chaque département a un superviseur clairement identifié et un seul chemin de validation, le feedback circule via un seul canal et le délai de turnaround des plans diminue.",[72,11756,11758],{"className":11757},[34,75],[77,11759],{"src":11760,"className":11761,"alt":12,"loading":82,"width":3036,"height":3037,"srcSet":11762,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image.png 1438w",[48,11764,11765,11766,11769],{},"Les départements doivent être répartis pour ",[120,11767,11768],{},"réduire les dépendances entre départements",", afin de concevoir des pipelines qui permettent aux équipes de travailler en parallèle plutôt que d’attendre les unes les autres. Une dépendance correspond à toute tâche qui bloque le démarrage d’une autre tâche. Vous pouvez aussi standardiser les rigs, les conventions de nommage et les processus de publication pour que l’animation n’attende pas des ajustements de rig de dernière minute.",[48,11771,11772,11773,11776],{},"Une structure d’équipe claire facilite aussi le ",[120,11774,11775],{},"pilotage du budget"," lorsque vous augmentez l’effectif : suivez votre burn rate (la vitesse à laquelle l’argent est dépensé chaque mois) pour guider les décisions d’embauche. Lorsque la production constate que l’ajout de deux animateurs de niveau intermédiaire permet de maintenir le burn rate aligné avec les jalons de livraison, l’embauche n’est plus un pari.",[61,11778],{},[64,11780,11782],{"id":11781},"_2-centralized-asset-management","2. Gestion centralisée des assets",[48,11784,11785],{},[94,11786],{"href":11787},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#2-centralized-asset-management",[48,11789,11790],{},"Vous devez centraliser la gestion des assets tôt, car cinq artistes peuvent crier dans la pièce pour obtenir le dernier rig, mais pas cinquante.",[48,11792,11793,11794,11797],{},"La gestion des assets naît d’un besoin simple : ",[120,11795,11796],{},"tout le monde doit toujours travailler sur l’asset le plus à jour."," Rien n’est plus frustrant que de voir une personne en éclairage passer une demi-journée à peaufiner un plan, pour découvrir que le rig du personnage a deux versions de retard. Il est important de remplacer rapidement les dossiers dispersés et le partage de fichiers “au fil de l’eau” par une seule source de vérité où vivent les fichiers validés.",[48,11799,11800],{},"Les tableurs peuvent sembler suffisants pour suivre les plans et les versions, mais ils s’effondrent dès que trois superviseurs les mettent à jour en même temps, ou que quelqu’un oublie d’enregistrer un changement. Google Drive est séduisant car vous le connaissez déjà, mais vous ne pouvez pas facilement versionner les assets et l’aperçu des rendus va rapidement consommer votre quota de stockage.",[48,11802,11803,11804,11807],{},"La solution est simple : ",[120,11805,11806],{},"stockez tous les assets de production sur un serveur sécurisé avec un accès contrôlé",", afin que les fichiers ne soient pas transmis manuellement et que les droits empêchent les écrasements accidentels. Verrouillez les choix d’outils DCC, les formats de partage, et mettez en place des stratégies de versioning.",[72,11809,11811],{"className":11810},[34,75],[77,11812],{"src":11813,"className":11814,"alt":12,"loading":82,"width":3036,"height":3037,"srcSet":11815,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-1.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-1.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-1.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-1.png 1438w",[48,11817,11818,11819,11822],{},"Le versioning signifie enregistrer des itérations incrémentales, clairement numérotées, d’un fichier pour pouvoir suivre les changements et revenir en arrière. Au lieu de laisser les artistes renommer des fichiers comme “final_v7_reallyFinal”, vous pouvez ",[120,11820,11821],{},"imposer une publication automatique des versions via votre pipeline DCC",". Exemple concret : lorsqu’un rigger publie un nouveau personnage dans Kitsu, le système incrémente la version. Les animateurs ouvrent les plans et référencent automatiquement le dernier rig approuvé.",[72,11824,11826],{"className":11825},[34,75],[77,11827],{"src":11828,"className":11829,"alt":12,"loading":82,"width":3036,"height":3037,"srcSet":11830,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-2.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-2.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-2.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-2.png 1438w",[61,11832],{},[64,11834,11836],{"id":11835},"_3-tracking-documentation","3. Suivi & documentation",[48,11838,11839],{},[94,11840],{"href":11841},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#3-tracking--documentation",[48,11843,11844],{},"Dans un grand studio, la responsabilité ne vit plus dans des conversations informelles.",[48,11846,11847,11850],{},[120,11848,11849],{},"Vous avez besoin d’un outil de suivi de production comme système partagé"," pour attribuer des tâches, des échéances et des responsables dans un endroit visible.",[48,11852,11853],{},"Dans Kitsu par exemple, vous pouvez configurer chaque concept, asset, plan et scène comme une tâche traçable, et attribuer un responsable unique et clair.",[72,11855,11857],{"className":11856},[34,75],[77,11858],{"src":11859,"className":11860,"alt":12,"loading":82,"width":3036,"height":11861,"srcSet":11862,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-3.png",[81],833,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-3.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-3.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-3.png 1438w",[48,11864,11865],{},"Dans une petite équipe, tout le monde se souvient de qui peaufine le cycle de marche. Dans une équipe plus grande, deux animateurs peuvent supposer que l’autre s’en occupe. Un simple tracker évite cette confusion en rendant la responsabilité explicite.",[48,11867,11868],{},"Associez-le à des jalons définis afin que l’avancement soit mesuré par rapport à des points de contrôle concrets plutôt qu’à une intuition.",[48,11870,11871,11874],{},[120,11872,11873],{},"La documentation doit aussi évoluer avec les effectifs."," Vous avez besoin d’une base de connaissances pour centraliser les outils, les processus et les conventions afin que tout le monde puisse les appliquer. Par exemple, créez un wiki de studio dans des outils comme Notion ou Confluence et demandez aux artistes de documenter les nouveaux outils et les correctifs dans le cadre de la validation de leur tâche.",[48,11876,11877,11878,11881],{},"Enfin et surtout, ",[120,11879,11880],{},"utilisez des outils de prévision"," pour repérer les retards tôt. Si le layout dépasse systématiquement de deux jours par séquence, ajustez les devis et le staffing avant que les échéances ne glissent, pas après que les clients se plaignent.",[61,11883],{},[64,11885,11887],{"id":11886},"_4-structure-review-loops-team-communication","4. Structurer les boucles de validation & la communication d’équipe",[48,11889,11890],{},[94,11891],{"href":11892},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#4-structure-review-loops--team-communication",[48,11894,11895],{},"Les cycles de feedback nécessitent aussi une structure.",[48,11897,11898],{},[120,11899,11900],{},"Une boucle de validation doit être un processus planifié et répétable, où le travail est soumis, relu, révisé et validé à des étapes clairement définies.",[48,11902,11903],{},"La communication écrite est aussi essentielle, car elle crée une trace et supprime l’ambiguïté. Faites en sorte que les soumissions aient lieu à des horaires fixes chaque semaine et demandez aux artistes d’ajouter une courte note écrite d’intention expliquant ce qui a changé et quel feedback est demandé, ou utilisez des commentaires asynchrones qui ne nécessitent pas que tout le monde soit présent au même moment pour réduire la surcharge des réunions.",[48,11905,11906,11909],{},[120,11907,11908],{},"Un moteur de validation"," comme celui de Kitsu centralise les versions, les notes et les validations, pour éviter que le feedback ne se perde dans les fils de discussion :",[72,11911,11913],{"className":11912},[34,75],[77,11914],{"src":11915,"className":11916,"alt":12,"loading":82,"width":11917,"height":11918,"srcSet":11919,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-4.png",[81],1122,549,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-4.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-4.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-4.png 1122w",[48,11921,11922,11923,11926],{},"Vous pouvez ",[120,11924,11925],{},"le combiner avec une plateforme de messagerie"," pour des clarifications rapides, tout en conservant les notes finales dans le système de validation. Beaucoup d’équipes découvrent que lorsque les superviseurs arrêtent de donner les grandes notes en message privé et les publient plutôt publiquement dans l’outil de validation, l’alignement s’améliore et le travail en double diminue nettement.",[61,11928],{},[64,11930,11932],{"id":11931},"_5-infrastructure-pipeline-management","5. Infrastructure & gestion du pipeline",[48,11934,11935],{},[94,11936],{"href":11937},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#5-infrastructure--pipeline-management",[48,11939,11940],{},"L’infrastructure cesse d’être une préoccupation “en arrière-plan” quand un studio grandit. À cinquante artistes, quinze minutes de friction quotidienne par personne à attendre que les fichiers se synchronisent, à re-liéer les textures et à relancer des plans cassés, cela s’accumule et dépasse plus de douze heures de temps de production perdu chaque jour.",[48,11942,11943,11946],{},[120,11944,11945],{},"Une équipe de pipeline dédiée est importante."," Au lieu que tout le monde corrige les problèmes au fur et à mesure qu’ils apparaissent, vous pouvez confier à une équipe de pipeline l’ownership des standards, du versioning et de l’automatisation, afin que les artistes restent concentrés sur les plans. Les technical artists gèrent plusieurs éléments clés d’un studio d’animation :",[212,11948,11949,11952,11955,11958],{},[215,11950,11951],{},"Un NAS (Network Attached Storage) garantit que tout le monde travaille à partir de la même source de vérité. Au lieu de copier des fichiers via le chat, les assets sont publiés à un emplacement unique.",[215,11953,11954],{},"La sauvegarde et la redondance protègent des catastrophes. Un disque corrompu ne devrait pas immobiliser un studio de 50 personnes. Des sauvegardes automatiques nocturnes et des serveurs miroirs évitent la panique.",[215,11956,11957],{},"Une ferme de rendu scalable empêche l’éclairage de bloquer l’animation.",[215,11959,11960],{},"Des automatisations sur mesure s’accumulent rapidement lorsque vous gérez des centaines de milliers d’images tout au long de la production.",[61,11962],{},[64,11964,508],{"id":507},[48,11966,11967],{},[94,11968],{"href":11969},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#conclusion",[48,11971,11972,11973,11976],{},"Faire grandir un studio d’animation, ce n’est pas seulement recruter plus d’artistes : ",[120,11974,11975],{},"vous devez concevoir un système qui permette à davantage d’artistes de réussir"," sans se gêner les uns les autres.",[48,11978,11979],{},"La prise de décision a besoin de couches. Les assets ont besoin de structure. Les tâches ont besoin de visibilité. Le feedback a besoin d’un processus. L’infrastructure a besoin d’un responsable. Ce qui, autrefois, vivait dans des conversations et dans une intuition partagée doit évoluer vers des systèmes documentés et des responsabilités clairement définies. Chacun de ces systèmes renforce les autres, et ensemble ils soutiennent la croissance de votre studio.",[48,11981,11982],{},"Si vous souhaitez passer à l’échelle en douceur sans sacrifier la qualité ni la culture, vous avez besoin d’outils qui soutiennent cette structure. C’est là que Kitsu intervient. Conçu spécifiquement pour les studios d’animation et VFX, Kitsu vous aide à centraliser le suivi, gérer les assets, structurer les validations et maintenir la visibilité entre les départements au même endroit. Passez à l’échelle avec confiance grâce aux bons systèmes !",[31,11984,11986,11989],{"className":11985},[34,35,36],[31,11987,524],{"className":11988},[40],[31,11990,528,11992,3151],{"className":11991},[45],[94,11993,8788],{"href":531,"rel":11994},[533],[31,11996,11998],{"className":11997},[34,539,540],[94,11999,546],{"href":531,"className":12000},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":12002},[12003,12004,12005,12006,12007,12008],{"id":11738,"depth":548,"text":11739},{"id":11781,"depth":548,"text":11782},{"id":11835,"depth":548,"text":11836},{"id":11886,"depth":548,"text":11887},{"id":11931,"depth":548,"text":11932},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1648014613911-e355dc51e2e3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGFuaW1hdGlvbiUyMHN0dWRpbyUyMHRlYW18ZW58MHx8fHwxNzczMDM2OTgyfDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":12011,"featured_at":561,"visibility":562},"2026-03-09T07:18:45.000+01:00","/blog-i18n/fr/scaling-animation-studio-systems",{"title":11704,"description":12},"scaling-animation-studio-systems","blog-i18n/fr/scaling-animation-studio-systems/index",[12017],{"id":974,"name":975,"slug":976,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":977},"3wixclgcmgH7uSCPRkv9ffITVJRg4_HY_OdeTTY5BKs",{"id":12020,"title":12021,"authors":12022,"body":12024,"description":12,"extension":557,"feature_image":12514,"html":7,"meta":12515,"navigation":13,"path":12517,"published_at":12518,"seo":12519,"slug":12520,"stem":12521,"tags":12522,"__hash__":12525,"updated_at":12516,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/self-hosted-blender-render-farm/index.md","Héberger soi-même un render farm Blender avec Flamenco en 2026",[12023],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":12025,"toc":12504},[12026,12037,12040,12043,12046,12049,12052,12062,12064,12068,12071,12081,12092,12099,12106,12108,12112,12119,12125,12128,12130,12134,12137,12151,12161,12163,12167,12191,12194,12203,12206,12214,12216,12220,12225,12228,12231,12239,12245,12247,12251,12254,12283,12293,12298,12316,12319,12328,12330,12334,12337,12343,12354,12357,12395,12405,12411,12429,12431,12434,12444,12447,12458,12460,12464,12470,12473,12476,12479,12486,12498],[31,12027,12029,12033],{"className":12028},[34,35,36],[31,12030,12032],{"className":12031},[40],"🖥️",[31,12034,12036],{"className":12035},[45],"Transformez des machines inutilisées en un puissant render farm Blender sans toucher au cloud.",[48,12038,12039],{},"Quand est-ce que vous avez presque manqué une échéance à cause du rendu, pour la dernière fois ?",[48,12041,12042],{},"À chaque fois que vous ouvrez Blender, votre station de travail ressemble à un moteur d’avion en préparation du décollage, et tout le film valant des mois de travail se retrouve pris en otage par une seule barre de progression.",[48,12044,12045],{},"Pendant ce temps, votre vieux PC portable de l’université est rangé dans une boîte, à prendre la poussière. Ce n’est pas une bête de course, mais il a un GPU. Il a de la RAM. C’est un ordinateur parfaitement fonctionnel qui ne fait absolument rien pendant que vous paniquez.",[48,12047,12048],{},"Le concept de « render farm » peut sembler intimidant pour un studio à une seule personne. Vous imaginez peut-être des racks de serveurs dans une pièce climatisée, des licences coûteuses et des professionnels de l’IT qui s’alarment en hurlant au sujet des adresses IP.",[48,12050,12051],{},"Mais dans l’écosystème Blender moderne, ce n’est plus la réalité.",[48,12053,12054,12055,12061],{},"Dans cet article, ",[120,12056,12057,12058,166],{},"je vais vous montrer comment transformer de vieux appareils en un système de rendu unifié grâce à ",[652,12059,12060],{},"Flamenco"," Nous allons rendre la configuration réseau beaucoup plus simple et vous faire produire vos rendus sur plusieurs machines en quelques heures.",[61,12063],{},[64,12065,12067],{"id":12066},"why-self-host-a-render-farm","Pourquoi s’auto-héberger un render farm ?",[48,12069,12070],{},"Avant de brancher des câbles Ethernet, parlons du « pourquoi ». Vous pourriez vous dire : « Pourquoi ne pas tout envoyer simplement à un render farm cloud ? » Les render farms cloud sont incroyables, mais avoir un render farm local auto-hébergé change votre workflow de trois façons fondamentales.",[48,12072,12073,12074,12077,12078],{},"Quand vous payez un render farm cloud, vous payez la sortie finale. ",[94,12075,12076],{"href":9182},"Ce qui vous décourage psychologiquement de faire des tests de rendu",". ",[120,12079,12080],{},"Vous avez peur de cliquer sur « Render » tant que vous n’êtes pas à 100 % certain que tout est parfait.",[48,12082,12083,12084,12087,12088,12091],{},"Quand vous possédez le render farm, le coût d’un rendu, c’est l’électricité. ",[94,12085,12086],{"href":2737},"Vous pouvez rendre une animation approximative"," en résolution à 50 % pour vérifier le timing ou l’éclairage. ",[120,12089,12090],{},"Cette liberté vous permet d’itérer plus vite."," Vous arrêtez d’hésiter et vous commencez à tester.",[48,12093,12094,12095,12098],{},"Parfois, travailler sur un projet commercial pour un client tech avec un NDA est tellement strict que vous n’êtes même pas autorisé à prononcer ne serait-ce que le nom du produit. ",[120,12096,12097],{},"Le fait de téléverser ces assets sur un serveur cloud tiers — même sécurisé — peut parfois enfreindre des clauses strictes du NDA."," Garder vos données sur votre réseau local (LAN) garantit qu’aucun pixel ne quitte votre studio tant que vous ne l’avez pas décidé.",[48,12100,12101,12102,12105],{},"Il y a un type bien particulier d’angoisse à téléverser un fichier de projet de 2 Go dans le cloud, à attendre le rendu, à télécharger les images, puis à se rendre compte que vous avez oublié d’« en bucher » un cache de physique. ",[120,12103,12104],{},"Avec un render farm local comme Flamenco, si vous repérez une erreur, vous cliquez simplement sur « Cancel », vous corrigez, puis vous cliquez à nouveau sur « Render ». Pas de temps de téléversement, pas de temps de téléchargement."," On a l’impression que c’est une extension de votre station de travail.",[61,12107],{},[64,12109,12111],{"id":12110},"what-is-blender-flamenco","Qu’est-ce que Blender Flamenco ?",[48,12113,12114,12115,12118],{},"Configurer un render farm à partir de zéro ",[94,12116,12117],{"href":9139},"impliquait autrefois du scripting complexe"," ou des logiciels tiers coûteux. Maintenant, nous avons Blender Flamenco.",[48,12120,12121,12124],{},[120,12122,12123],{},"Flamenco est le render farm open-source de Blender."," La mise en place est extrêmement simple : le manager est le cerveau qui détient la liste des tâches (les frames à rendre) et indique aux autres ordinateurs quoi faire. Les workers sont vos ordinateurs portables ou bureaux supplémentaires. Ils écoutent le Manager, demandent une frame, la rendent, la sauvegardent, puis demandent la suivante.",[48,12126,12127],{},"Flamenco est conçu pour être « zéro configuration ». Il se découvre quasiment tout seul sur votre réseau. Si vous pouvez installer Blender, vous pouvez configurer Flamenco.",[61,12129],{},[64,12131,12133],{"id":12132},"_1-the-setup","1. La configuration",[48,12135,12136],{},"Pour ce tutoriel, nous commençons avec la configuration la plus simple possible : notre ordinateur de bureau agit à la fois comme manager et comme worker. Nous verrons plus tard comment ajouter notre ordinateur portable.",[1692,12138,12139,12145],{},[215,12140,12141,12144],{},[120,12142,12143],{},"Installer Blender"," - Assurez-vous que Blender est installé sur votre ordinateur.",[215,12146,12147,12150],{},[120,12148,12149],{},"Télécharger Flamenco"," - Allez sur le site de Flamenco et téléchargez le package pour votre système d’exploitation. Décompressez-le dans un dossier.",[72,12152,12154],{"className":12153},[34,75],[77,12155],{"src":12156,"className":12157,"alt":12,"loading":82,"width":12158,"height":12159,"srcSet":12160,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png",[81],1064,721,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png 1064w",[61,12162],{},[64,12164,12166],{"id":12165},"_2-run-flamenco-manager","2. Lancer Flamenco Manager",[1692,12168,12169,12172,12178,12181,12184],{},[215,12170,12171],{},"Ouvrez le dossier Flamenco que vous venez d’extraire.",[215,12173,12174,12175,166],{},"Double-cliquez sur ",[155,12176,12177],{},"flamenco-manager",[215,12179,12180],{},"Une fenêtre de terminal s’ouvrira avec des logs de texte.",[215,12182,12183],{},"Suivez l’assistant de configuration pour définir le dossier de job dans lequel vous téléverserez vos fichiers .blend à rendre.",[215,12185,12186,12187,12190],{},"Peu après, votre navigateur web devrait s’ouvrir automatiquement sur ",[155,12188,12189],{},"http://localhost:8080",". C’est l’interface web de Flamenco.",[48,12192,12193],{},"Si vous voyez un tableau de bord convivial en thème sombre, félicitations. Vous êtes déjà à moitié administrateur de serveur. Le Manager est en vie.",[72,12195,12197],{"className":12196},[34,75],[77,12198],{"src":12199,"className":12200,"alt":12,"loading":82,"width":10248,"height":12201,"srcSet":12202,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png",[81],821,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png 1319w",[48,12204,12205],{},"Le manager vous demandera de télécharger l’addon. Faites-le maintenant, car nous en aurons besoin à l’étape 4.",[72,12207,12209],{"className":12208},[34,75],[77,12210],{"src":12211,"className":12212,"alt":12,"loading":82,"width":12158,"height":12159,"srcSet":12213,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png 1064w",[61,12215],{},[64,12217,12219],{"id":12218},"_3-the-worker","3. Le Worker",[48,12221,12222,12223,166],{},"Maintenant, laissez le manager en cours et double-cliquez sur ",[155,12224,8977],{},[48,12226,12227],{},"C’est tout.",[48,12229,12230],{},"Le Worker va analyser votre réseau local, trouver le Manager en cours d’exécution sur le même ordinateur, puis se présenter. Si vous regardez le navigateur web de votre Desktop (l’interface du Manager), vous devriez le voir apparaître dans l’onglet « Workers », listé comme « Idle » et prêt à entrer en action.",[72,12232,12234],{"className":12233},[34,75],[77,12235],{"src":12236,"className":12237,"alt":12,"loading":82,"width":10248,"height":12201,"srcSet":12238,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png 1319w",[48,12240,12241,12242,12244],{},"Vous devriez aussi lancer ",[155,12243,8977],{}," sur votre Desktop ! Votre ordinateur principal peut rendre et gérer en même temps.",[61,12246],{},[64,12248,12250],{"id":12249},"_4-add-the-blend-file-and-render","4. Ajouter le fichier Blend et lancer le rendu",[48,12252,12253],{},"La scène est prête. Maintenant, on passe à l’action !",[1692,12255,12256,12262,12268,12274],{},[215,12257,12258,12261],{},[120,12259,12260],{},"Ouvrez Blender"," sur votre Desktop.",[215,12263,12264,12267],{},[120,12265,12266],{},"Activez l’Addon"," - Allez dans Edit > Preferences > Add-ons > Install from Disk. Recherchez le fichier zip flamenco que vous avez téléchargé pendant la configuration du manager.",[215,12269,12270,12273],{},[120,12271,12272],{},"Lier le Manager"," - Dans les préférences de l’addon Flamenco, copiez/collez l’adresse URL du manager.",[215,12275,12276,12279,12280,12282],{},[120,12277,12278],{},"Enregistrez votre fichier"," - Enregistrez votre fichier ",[155,12281,4832],{}," dans le dossier de job configuré.",[72,12284,12286],{"className":12285},[34,75],[77,12287],{"src":12288,"className":12289,"alt":12,"loading":82,"width":12290,"height":12291,"srcSet":12292,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-88504c81-44cf-4d32-a374-0b2dc6746b56.png",[81],724,732,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-88504c81-44cf-4d32-a374-0b2dc6746b56.png 600w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-88504c81-44cf-4d32-a374-0b2dc6746b56.png 724w",[48,12294,12295,12296,166],{},"Dans l’onglet Render Properties de Blender, descendez jusqu’au panneau ",[120,12297,12060],{},[1692,12299,12300,12305,12311],{},[215,12301,3328,12302,166],{},[120,12303,12304],{},"« Fetch Job Types »",[215,12306,12307,12308,166],{},"Sélectionnez ",[120,12309,12310],{},"« Simple Render »",[215,12312,3328,12313,166],{},[120,12314,12315],{},"« Submit to Flamenco »",[48,12317,12318],{},"Maintenant, basculez vers votre navigateur web. Vous verrez le job apparaître. Les barres d’état dans votre liste « Workers » passeront au vert. Votre Desktop récupère une frame à la fois pour la rendre.",[72,12320,12322],{"className":12321},[34,75],[77,12323],{"src":12324,"className":12325,"alt":12,"loading":82,"width":10248,"height":12326,"srcSet":12327,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png",[81],918,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png 1319w",[61,12329],{},[64,12331,12333],{"id":12332},"_5-bringing-in-the-laptop","5. Ajouter l’ordinateur portable",[48,12335,12336],{},"Maintenant, il est temps d’ajouter votre ordinateur portable poussiéreux au render farm.",[48,12338,12339,12340],{},"Voici le conseil le plus directement actionnable que je puisse vous donner, et c’est là que 90 % des débutants se trompent : ",[120,12341,12342],{},"Tous les ordinateurs doivent voir les fichiers exactement au même endroit.",[48,12344,12345,12346,12349,12350,12353],{},"Si votre texture est située à ",[155,12347,12348],{},"C:\\Users\\Dave\\Texture.png"," sur votre desktop, votre ordinateur portable ",[652,12351,12352],{},"ne peut pas"," accéder à ce chemin. Le portable n’a pas d’utilisateur nommé Dave, et il n’a pas le fichier sur son disque C.",[48,12355,12356],{},"Vous avez besoin d’un dossier réseau partagé, typiquement via un NAS. Selon votre système d’exploitation, les étapes sont similaires, mais peuvent légèrement différer :",[1692,12358,12359,12362,12368,12382],{},[215,12360,12361],{},"Connectez votre desktop et votre ordinateur portable via un câble Ethernet",[215,12363,12364,12365,166],{},"Créez un dossier NAS sur votre Desktop appelé ",[155,12366,12367],{},"RenderFarm",[215,12369,12370,12371,12374,12375,12374,12378,12381],{},"Clic droit dessus > ",[120,12372,12373],{},"Propriétés"," > ",[120,12376,12377],{},"Partage",[120,12379,12380],{},"Partager",". Donnez les permissions de lecture/écriture à votre utilisateur.",[215,12383,12384,12387,12388,12391,12392,12394],{},[120,12385,12386],{},"Associez le lecteur réseau :"," Sur votre Desktop, associez ce dossier à une lettre de lecteur, par exemple ",[155,12389,12390],{},"Z:",". Sur votre Laptop, allez dans le partage réseau du Desktop et associez-le à **la même lettre ",[155,12393,12390],{},"**.",[48,12396,12397,12398,12401,12402,12404],{},"Maintenant, lorsque vous enregistrez votre fichier Blender dans ",[155,12399,12400],{},"Z:\\RenderFarm\\MyProject.blend",", les deux ordinateurs le voient à ",[155,12403,12400],{},". Le chemin est absolu et identique.",[48,12406,12407,12408,166],{},"Laissez maintenant le Desktop en cours d’exécution et passez sur ",[120,12409,12410],{},"Computer B (Laptop)",[1692,12412,12413,12419,12422,12425],{},[215,12414,12415,12416,12418],{},"Assurez-vous que votre lecteur ",[155,12417,12390],{}," (ou le stockage partagé que vous avez configuré) est accessible. Ouvrez un fichier dedans pour vérifier.",[215,12420,12421],{},"Installez et ouvrez le dossier Flamenco sur l’ordinateur portable.",[215,12423,12424],{},"Vérifiez que vous avez la même version de Blender installée que sur votre desktop.",[215,12426,12174,12427,166],{},[155,12428,8977],{},[48,12430,12227],{},[48,12432,12433],{},"Le Worker analysera votre réseau local et trouvera le Manager lancé sur le Desktop.",[72,12435,12437],{"className":12436},[34,75],[77,12438],{"src":12439,"className":12440,"alt":12,"loading":82,"width":12441,"height":12442,"srcSet":12443,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png",[81],1504,932,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png 1504w",[48,12445,12446],{},"Flamenco va maintenant orchestrer automatiquement les jobs entre vos ordinateurs.",[48,12448,12449,12450,12453,12454,12457],{},"Si vous n’avez pas accès à un NAS ou ne souhaitez pas en acheter un, vous pouvez regarder comment installer un serveur Samba gratuit sur un poste Linux. L’utilisation d’un stockage cloud n’est pas possible car Flamenco ne gère pas les services asynchrones, sauf si vous créez votre propre type de job. Nous verrons comment faire ",[94,12451,12452],{"href":6377},"dans un futur article",", en utilisant Kitsu comme ",[94,12455,12456],{"href":7266},"serveur de stockage d’assets"," asynchrone.",[61,12459],{},[64,12461,12463],{"id":12462},"conclusion-knowing-when-to-scale","Conclusion : savoir quand étendre",[48,12465,12466,12467],{},"Nous avons couvert la configuration matérielle, la logique cruciale du stockage partagé, ainsi que l’installation du logiciel. Si vous avez suivi, ",[120,12468,12469],{},"vous avez maintenant un render farm fonctionnel chez vous, et votre ordinateur portable poussiéreux est devenu un membre productif de votre équipe.",[48,12471,12472],{},"Flamenco rend l’entrée vers le rendu auto-hébergé incroyablement simple. Il respecte votre vie privée, ne coûte rien à part l’électricité, et vous permet d’extraire chaque once de performance du matériel que vous possédez déjà.",[48,12474,12475],{},"Mais il y a une limite à ce que vous pouvez accomplir seul.",[48,12477,12478],{},"À un moment, vous rencontrerez une échéance où même la combinaison Desktop + Laptop ne suffit plus. Peut-être que vous devez rendre une séquence 4K avec de lourds volumetrics en 24 heures, et que votre render farm à la maison estime un temps de complétion de 3 semaines. C’est le plafond de l’auto-hébergement.",[48,12480,12481,12482,12485],{},"Quand vous atteignez ce mur, vous n’avez pas besoin d’acheter cinq ordinateurs de plus. ",[120,12483,12484],{},"C’est là que vous passez à un service comme Ranch Computing",", qui vous permet d’accéder instantanément à des centaines de nœuds CPU/GPU. Votre render farm maison est un excellent outil du quotidien, parfait pour les tests, les prévisualisations et les projets plus légers, tandis qu’un render farm cloud est indispensable pour rendre rapidement des livrables de haute qualité pour vos clients.",[31,12487,12489,12492],{"className":12488},[34,35,36],[31,12490,524],{"className":12491},[40],[31,12493,528,12495,535],{"className":12494},[45],[94,12496,8788],{"href":531,"rel":12497},[533],[31,12499,12501],{"className":12500},[34,539,540],[94,12502,546],{"href":531,"className":12503},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":12505},[12506,12507,12508,12509,12510,12511,12512,12513],{"id":12066,"depth":548,"text":12067},{"id":12110,"depth":548,"text":12111},{"id":12132,"depth":548,"text":12133},{"id":12165,"depth":548,"text":12166},{"id":12218,"depth":548,"text":12219},{"id":12249,"depth":548,"text":12250},{"id":12332,"depth":548,"text":12333},{"id":12462,"depth":548,"text":12463},"https://images.unsplash.com/photo-1683322499436-f4383dd59f5a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fGRhdGElMjBjZW50ZXJ8ZW58MHx8fHwxNzY3NjE4NDAxfDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":12516,"featured_at":561,"visibility":562},"2026-02-20T06:04:52.000+01:00","/blog-i18n/fr/self-hosted-blender-render-farm","2026-01-19T10:00:41.000+01:00",{"title":12021,"description":12},"self-hosted-blender-render-farm","blog-i18n/fr/self-hosted-blender-render-farm/index",[12523,12524],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1827,"name":1828,"slug":1829,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1830},"H5V9WqFCtuEBqT5IyPlJeObvFfs168gOv0RQbKgwtpI",{"id":12527,"title":12528,"authors":12529,"body":12531,"description":12,"extension":557,"feature_image":13023,"html":7,"meta":13024,"navigation":13,"path":13026,"published_at":13027,"seo":13028,"slug":13029,"stem":13030,"tags":13031,"__hash__":13033,"updated_at":13025,"featured_at":561,"visibility":562},"blog/blog-i18n/fr/share-kitsu-playlists/index.md","(2026) Comment exporter et partager des playlists Kitsu avec Python",[12530],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":12532,"toc":13015},[12533,12544,12555,12562,12565,12572,12575,12582,12585,12610,12612,12616,12622,12625,12636,12639,12650,12653,12659,12667,12669,12673,12676,12683,12698,12705,12730,12737,12760,12766,12768,12772,12775,12781,12786,12789,12792,12800,12803,12815,12822,12840,12843,12849,12852,12861,12864,12878,12881,12887,12890,12892,12896,12902,12914,12917,12922,12925,12927,12931,12937,12943,12951,12957,12959,12961,12967,12970,12976,12984,12996,13009],[31,12534,12536,12540],{"className":12535},[34,35,36],[31,12537,12539],{"className":12538},[40],"📥",[31,12541,12543],{"className":12542},[45],"Partagez clairement les playlists Kitsu, même lorsque vos clients n’ont pas accès à Kitsu directement.",[48,12545,12546,12547,12550,12551,12554],{},"Au début de votre carrière en tant qu’animateur, vous allez probablement apprendre une vérité difficile : parfois, de façon douloureuse : ",[120,12548,12549],{},"faire un excellent travail n’est qu’une moitié du travail, et le partager clairement est l’autre moitié",". Vous vous souvenez peut-être d’un projet de court métrage où l’animation elle-même était solide, mais où le processus de review était un véritable chaos. Des allers-retours rapides de QuickTimes par email, des fichiers nommés comme ",[155,12552,12553],{},"shot_final_v3_really_final.mov",", et personne n’est vraiment sûr de savoir à quelles versions correspondent les notes. Les clients étaient perdus, les superviseurs frustrés, et vous passiez plus de temps à gérer des fichiers qu’à animer.",[48,12556,12557,12558,12561],{},"Avancez de quelques années, et des outils comme les ",[120,12559,12560],{},"playlists Kitsu"," changent complètement la façon dont les studios passent en revue l’animation.",[48,12563,12564],{},"Elles vous apportent une structure, une traçabilité, et une manière propre de présenter le travail. Vous pouvez regrouper les plans, suivre les versions et centraliser les retours. Pour la plupart des équipes, rien que ça représente un énorme gain.",[48,12566,12567,12568,12571],{},"Mais voici le point que l’on apprend au fil des années de production : ",[94,12569,12570],{"href":8279},"aucun studio ni client ne partage exactement le même workflow de review",". Parfois, vous devez envoyer des assets hors ligne. Parfois, un client veut tout emballé proprement par séquence. Parfois, des contraintes légales ou de sécurité signifient que vous ne pouvez pas donner un accès direct à Kitsu. Dans ces cas, vous souhaitez quand même tirer parti des forces de Kitsu sans être verrouillé dans une seule manière de partager.",[48,12573,12574],{},"C’est exactement de cela que traite cet article.",[48,12576,12577,12578,12581],{},"À la fin, vous saurez comment ",[120,12579,12580],{},"créer une playlist Kitsu, en extraire les données avec Python, télécharger tous les assets associés dans une structure de dossiers propre, et compresser le tout pour un partage facile",". Cette approche peut vous faire gagner des heures sur de vraies productions et rendre les reviews plus fluides pour les artistes comme pour les clients.",[48,12583,12584],{},"Décomposons le tout étape par étape.",[31,12586,12588,12591],{"className":12587},[34,35,108],[31,12589,112],{"className":12590},[40],[31,12592,12594,12598,12600,129,12602,12604,134,12606],{"className":12593},[45],[117,12595,12596],{},[120,12597,123],{"style":122},[125,12599],{},[125,12601],{},[125,12603],{},[125,12605],{},[94,12607,12609],{"href":12608},"https://github.com/cgwire/blog-tutorials/tree/main/share-kitsu-playlist?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/share-kitsu-playlist",[61,12611],{},[64,12613,12615],{"id":12614},"_1-create-a-kitsu-playlist","1. Créer une playlist Kitsu",[48,12617,12618,12621],{},[120,12619,12620],{},"Tout bon workflow de review commence par une intention claire"," : sur quoi voulez-vous exactement obtenir un retour ? Les playlists Kitsu sont faites pour ça.",[48,12623,12624],{},"Créer une playlist depuis le tableau de bord Kitsu est simple. Allez dans votre projet, rendez-vous dans la section Shots ou Assets, puis commencez à sélectionner les éléments à faire relire. Il est utile de penser aux playlists comme à des récits de review. Au lieu de tout balancer, posez-vous ces questions :",[212,12626,12627,12630,12633],{},[215,12628,12629],{},"S’agit-il d’une review bloquante ?",[215,12631,12632],{},"S’agit-il d’une passe de finition ?",[215,12634,12635],{},"La focus porte-t-elle sur l’animation, l’éclairage ou le compositing ?",[48,12637,12638],{},"Par exemple, sur un court projet cinématographique, vous pourriez créer des playlists séparées pour :",[212,12640,12641,12644,12647],{},[215,12642,12643],{},"« Animation Blocking – Act 1 »",[215,12645,12646],{},"« Facial Polish – Key Shots »",[215,12648,12649],{},"« Final Lighting Review »",[48,12651,12652],{},"Cette petite organisation peut rendre les reviews clients beaucoup plus ciblées.",[48,12654,12655,12656],{},"Dans Kitsu, une fois vos plans sélectionnés, vous pouvez créer une nouvelle playlist, la nommer clairement, puis ordonner les plans de manière à raconter une histoire. L’ordre compte plus qu’on ne le pense. ",[94,12657,12658],{"href":598},"Quand un client lance la lecture, il peut juger l’art, le timing et les révisions au même endroit.",[72,12660,12662],{"className":12661},[34,75],[77,12663],{"src":12664,"className":12665,"alt":12,"loading":82,"width":10248,"height":12201,"srcSet":12666,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png 1319w",[61,12668],{},[64,12670,12672],{"id":12671},"_2-get-the-playlist-data","2. Récupérer les données de la playlist",[48,12674,12675],{},"Maintenant que la playlist est prête, il est temps de coder.",[48,12677,12678,12679,12682],{},"On commence par ",[120,12680,12681],{},"s’authentifier auprès de Kitsu"," en utilisant le client de l’API Gazu :",[152,12684,12685,12688],{},[155,12686,176],{"className":12687},[724],[48,12689,12690],{},[155,12691,182,12693,10619,12696,193],{"className":12692},[724],[94,12694,185],{"href":185,"rel":12695},[187],[94,12697,192],{"href":191},[48,12699,12700,12701,12704],{},"Ensuite, on ",[120,12702,12703],{},"interroge Kitsu pour obtenir les projets disponibles"," et on les affiche dans le terminal. L’utilisateur choisit un projet, et ce choix définit le périmètre de tout ce qui suit. Comme les projets sont récupérés dynamiquement, le script fonctionne sur plusieurs productions sans modification :",[152,12706,12707,12721],{},[155,12708,12710,12711],{"className":12709},[724],"productions = gazu.project.all_projects()",[48,12712,12713,12714,12717,12718,12720],{},"for i, p in enumerate(productions):\nprint(f\"",[262,12715,12716],{},"{i}"," {p",[262,12719,2437],{},"}\")",[48,12722,12723],{},[155,12724,12726,12727],{"className":12725},[724],"production = productions",[262,12728,12729],{},"int(input(\"Select project: \"))",[48,12731,12732,12733,12736],{},"À partir de là, ",[120,12734,12735],{},"les playlists sont interrogées depuis le projet sélectionné"," et affichées de la même façon. Lorsqu’une playlist est choisie, le script récupère l’objet complet de la playlist via l’API.",[152,12738,12739,12751],{},[155,12740,12742,12743],{"className":12741},[724],"playlists = gazu.playlist.all_playlists_for_project(production)",[48,12744,12745,12746,12748,12749,12720],{},"for i, pl in enumerate(playlists):\nprint(f\"",[262,12747,12716],{}," {pl",[262,12750,2437],{},[48,12752,12753],{},[155,12754,12756,12757,10736],{"className":12755},[724],"playlist = gazu.playlist.get_playlist(playlists",[262,12758,12759],{},"int(input(\"Select playlist: \"))",[48,12761,12762,12765],{},[155,12763,12764],{},"playlist"," contient la référence complète de la sélection éditoriale : les plans, les versions, l’ordre, et les fichiers liés sont tous accessibles via cet objet.",[61,12767],{},[64,12769,12771],{"id":12770},"_3-download-related-assets","3. Télécharger les assets associés",[48,12773,12774],{},"La prochaine étape consiste à transformer les données de la playlist en quelque chose qui soit consultable sur disque.",[48,12776,12777,12780],{},[120,12778,12779],{},"Le résultat est une hiérarchie de dossiers qui reflète la réalité de la production"," : la playlist en haut, les séquences en dessous, les plans à l’intérieur, puis les médias réels là où chacun s’attend à les trouver.",[152,12782,12783],{},[155,12784,12785],{},"Playlist_Name/\n└── Seq_010/\n├── Shot_010_001/\n│   ├── anim_v003.mov\n│   └── anim_v003.png\n└── Shot_010_002/\n└── Seq_020/\n└── Shot_020_005/\n",[48,12787,12788],{},"Cette structure est l’idée principale. Elle supprime l’ambiguïté, évite de déverser les fichiers à plat, et permet aux superviseurs comme aux clients de naviguer par contexte plutôt que par noms de fichiers.",[48,12790,12791],{},"Le nom de la playlist est utilisé comme dossier racine, ainsi chaque export reste autonome et ré-exécutable.",[152,12793,12794],{},[155,12795,12797,12798],{"className":12796},[724],"playlist_name = playlist",[262,12799,2331],{},[48,12801,12802],{},"Ensuite, on parcourt chaque entrée de la playlist et on récupère l’enregistrement complet du plan, car la playlist elle-même ne contient pas les données de séquence.",[152,12804,12805],{},[155,12806,12808,12809,12812,12813,10736],{"className":12807},[724],"for shot in playlist",[262,12810,12811],{},"\"shots\"",":\nshot_data = gazu.shot.get_shot(shot",[262,12814,2936],{},[48,12816,12817,12818,12821],{},"On utilise le nom de la séquence et le nom du plan pour construire un chemin de dossier déterministe. Cela impose une structure ",[155,12819,12820],{},"playlist/sequence/shot"," cohérente sur le disque.",[152,12823,12824,12834],{},[155,12825,12827,12828,12830,12831],{"className":12826},[724],"shot_name = shot_data",[262,12829,2331],{},"\nsequence_name = shot_data",[262,12832,12833],{},"\"sequence_name\"",[48,12835,12836],{},[155,12837,12839],{"className":12838},[724],"shot_dir = os.path.join(\nplaylist_name,\nsequence_name,\nshot_name,\n)\n",[48,12841,12842],{},"Si le dossier n’existe pas, on le crée. Cela permet au script de tourner plusieurs fois sans échouer ni écraser des téléchargements partiels.",[152,12844,12845],{},[155,12846,12848],{"className":12847},[724],"os.makedirs(shot_dir, exist_ok=True)\n",[48,12850,12851],{},"On peut ensuite récupérer les informations du fichier d’aperçu correspondant à chaque plan. Typiquement, une image ou une vidéo :",[152,12853,12854],{},[155,12855,12857,12858,10736],{"className":12856},[724],"preview = gazu.files.get_preview_file(shot",[262,12859,12860],{},"\"preview_file_id\"",[48,12862,12863],{},"On conserve le nom de fichier et l’extension d’origine afin que le résultat corresponde à ce que les artistes et les superviseurs s’attendent à voir.",[152,12865,12866],{},[155,12867,12869,12870,12873,12874,12877],{"className":12868},[724],"preview_filename = f\"{preview",[262,12871,12872],{},"'original_name'","}.{preview",[262,12875,12876],{},"'extension'","}\"\npreview_path = os.path.join(shot_dir, preview_filename)\n",[48,12879,12880],{},"On télécharge directement le média d’aperçu dans le dossier du plan. À ce stade, la playlist existe sur le disque sous forme d’arborescence propre, prête pour la review.",[152,12882,12883],{},[155,12884,12886],{"className":12885},[724],"gazu.files.download_preview_file(preview, preview_path)\n",[48,12888,12889],{},"Le résultat est un miroir local de la playlist qui peut être zippé, envoyé, archivé ou relu sans explications.",[61,12891],{},[64,12893,12895],{"id":12894},"_4-compress-the-folder","4. Compresser le dossier",[48,12897,12898,12899,1654],{},"Une fois tout téléchargé, l’étape finale consiste à faciliter le partage. ",[120,12900,12901],{},"Votre script doit compresser automatiquement le dossier racine de la playlist en une archive unique",[152,12903,12904,12908],{},[155,12905,12907],{"className":12906},[724],"import shutil",[48,12909,12910],{},[155,12911,12913],{"className":12912},[724],"shutil.make_archive(\nbase_name=playlist_name,\nformat=\"zip\",\nroot_dir=os.path.dirname(playlist_name),\nbase_dir=os.path.basename(playlist_name),\n)\n",[48,12915,12916],{},"Cette archive devient votre livrable. Vous pouvez la télécharger vers un stockage cloud, l’envoyer via un portail client sécurisé, ou l’archiver en interne comme dossier de sauvegarde.",[48,12918,12919],{},[120,12920,12921],{},"Les clients ne s’inquiètent pas des fichiers manquants ou des structures cassées. Ils téléchargent une fois, décompressent une fois, et tout fonctionne.",[48,12923,12924],{},"Incluez le nom de la playlist et la date dans le nom du fichier d’archive. Six mois plus tard, quand quelqu’un demandera : « Quelle version nous a-t-on envoyée ? », vous serez content de l’avoir fait.",[61,12926],{},[64,12928,12930],{"id":12929},"onboard-clients-in-kitsu","Intégrer les clients dans Kitsu",[48,12932,12933,12934],{},"À un moment, exporter des playlists Kitsu commence à gêner. C’est OK quand vous envoyez un aperçu rapide ou quand vous faites une passe de notes ponctuelle, mais dès que le projet entre dans une vraie phase d’itération, tout se complique très vite. Vous ré-exportez pour chaque petit ajustement, les clients commentent des versions déjà dépassées, et les retours se retrouvent éparpillés entre emails, PDF et fils de discussion. ",[120,12935,12936],{},"Beaucoup d’énergie est consacrée à comprendre à quoi renvoie la note, au lieu de corriger réellement le plan.",[48,12938,12939,12942],{},[120,12940,12941],{},"C’est généralement à ce moment-là que ça vaut la peine d’intégrer les clients directement dans Kitsu."," Ils consultent toujours la version actuelle, ils peuvent dessiner ou commenter directement sur l’image, et tout le monde voit les notes dans leur contexte. L’historique des versions reste intact : quand un client demande quelque chose « à partir de deux versions en arrière », vous pouvez réellement le voir. Pour l’équipe, cela signifie moins de moments d’hésitation et moins de temps passé à recopier les notes d’un endroit à l’autre.",[72,12944,12946],{"className":12945},[34,75],[77,12947],{"src":12948,"className":12949,"alt":12,"loading":82,"width":3036,"height":3037,"srcSet":12950,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png 1438w",[48,12952,12953,12954],{},"Les exports sont bons pour les contrôles rapides, mais ils ne passent pas à l’échelle en production réelle. ",[120,12955,12956],{},"Garder les clients dans Kitsu maintient tout le monde ancré dans la même réalité.",[61,12958],{},[64,12960,508],{"id":507},[48,12962,12963,12964],{},"Après des années dans l’animation, une leçon revient sans cesse : plus votre workflow de review est fluide, meilleur est votre rendu créatif. Kitsu vous donne déjà une base solide avec les playlists, la gestion des versions et les retours centralisés. ",[120,12965,12966],{},"En exploitant ses données et en construisant de petits outils d’automatisation, vous pouvez l’adapter à presque n’importe quel scénario de review.",[48,12968,12969],{},"Mais vous pouvez aussi extraire les données des playlists depuis Kitsu et les remodeler pour correspondre à vos workflows de review personnalisés. Que vous envoyiez des packs hors ligne, que vous organisiez des assets pour des partenaires externes, ou que vous cherchiez juste à faciliter la vie de vos clients, cette approche vous met aux commandes.",[48,12971,12972,12975],{},[94,12973,12974],{},"Consultez le dépôt public Github"," pour cloner et modifier notre code afin de l’adapter à votre workflow !",[72,12977,12979],{"className":12978},[34,75],[77,12980],{"src":12981,"className":12982,"alt":12,"loading":82,"width":10248,"height":12201,"srcSet":12983,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png 1319w",[48,12985,12986,12987,12990,12991,12995],{},"Et s’il y a un dernier conseil qui vaut vraiment le coup : ",[120,12988,12989],{},"intégrez vos clients directement dans Kitsu dès que possible !"," Une fois qu’ils ",[94,12992,12994],{"href":12993},"https://www.cg-wire.com/review-engine?ref=blog.cg-wire.com","font l’expérience de vraies salles de review en temps réel",", avec des notes annotées et l’historique des versions, la plupart ne veulent plus revenir à des fils d’emails chaotiques.",[31,12997,12999,13002],{"className":12998},[34,35,36],[31,13000,524],{"className":13001},[40],[31,13003,1786,13005,13008],{"className":13004},[45],[94,13006,534],{"href":531,"rel":13007},[533]," ! Nous échangeons avec plus d’un millier d’experts qui partagent leurs bonnes pratiques et organisent parfois des événements en personne. Nous serions ravis de vous accueillir ! 😊",[31,13010,13012],{"className":13011},[34,539,540],[94,13013,1797],{"href":531,"className":13014},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":13016},[13017,13018,13019,13020,13021,13022],{"id":12614,"depth":548,"text":12615},{"id":12671,"depth":548,"text":12672},{"id":12770,"depth":548,"text":12771},{"id":12894,"depth":548,"text":12895},{"id":12929,"depth":548,"text":12930},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1727142073871-d40f5a7c76d8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHZpZGVvJTIwZWRpdCUyMHN1aXRlfGVufDB8fHx8MTc2NzYyMDEwNnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":13025,"featured_at":561,"visibility":562},"2026-02-20T06:04:53.000+01:00","/blog-i18n/fr/share-kitsu-playlists","2026-01-26T10:00:19.000+01:00",{"title":12528,"description":12},"share-kitsu-playlists","blog-i18n/fr/share-kitsu-playlists/index",[13032],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"aDiXaYDf81PhPpXhUSglh-5TLXduZbPIGzEzwPZuppU",[13035,13043,13052,13061,13070,13078,13087],{"id":13036,"title":1828,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":1829,"meta":13037,"navigation":13,"pageType":13038,"path":13039,"seo":13040,"slug":1829,"stem":13041,"__hash__":13042},"jsonPages/fr/tags/blender.json",{"name":1828},"tags","/fr/tags/blender",{},"fr/tags/blender","u-xLCehv_Ilq2anh5_cFS1bx4PNMvys14B7kvQ884Uo",{"id":13044,"title":13045,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13046,"meta":13047,"navigation":13,"pageType":13038,"path":13048,"seo":13049,"slug":13046,"stem":13050,"__hash__":13051},"jsonPages/fr/tags/company.json","Entreprise","entreprise",{"name":13045},"/fr/tags/company",{},"fr/tags/company","ZnxcgShl8j1LrB9lNissqyDBBv-M0IQ1UTvfM9VA7uA",{"id":13053,"title":13054,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13055,"meta":13056,"navigation":13,"pageType":13038,"path":13057,"seo":13058,"slug":13055,"stem":13059,"__hash__":13060},"jsonPages/fr/tags/customer-stories.json","Témoignages Clients","temoignages-clients",{"name":13054},"/fr/tags/customer-stories",{},"fr/tags/customer-stories","PkwpZviQy6qvOrnpkoEf2r_jEdZHBRpm0_3YomqKBrQ",{"id":13062,"title":13063,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13064,"meta":13065,"navigation":13,"pageType":13038,"path":13066,"seo":13067,"slug":13064,"stem":13068,"__hash__":13069},"jsonPages/fr/tags/glossary.json","Glossaire","glossaire",{"name":13063},"/fr/tags/glossary",{},"fr/tags/glossary","1cqZB0j3SRYa-cITb-b3kMPlofRoQawI2W7KdpahrzQ",{"id":13071,"title":13072,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":572,"meta":13073,"navigation":13,"pageType":13038,"path":13074,"seo":13075,"slug":572,"stem":13076,"__hash__":13077},"jsonPages/fr/tags/pipeline.json","Pipeline",{"name":13072},"/fr/tags/pipeline",{},"fr/tags/pipeline","kfaZYlzFQKfsv4EziXrMBjLDHb768UBv6eNirJ3oRNo",{"id":13079,"title":13080,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13081,"meta":13082,"navigation":13,"pageType":13038,"path":13083,"seo":13084,"slug":13081,"stem":13085,"__hash__":13086},"jsonPages/fr/tags/production-management.json","Gestion de Production","gestion-de-production",{"name":13080},"/fr/tags/production-management",{},"fr/tags/production-management","olfUuTcaQuuPL2oXUqUxC1V-VMiQ6_de80ZdQsDJpp8",{"id":13088,"title":13089,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13090,"meta":13091,"navigation":13,"pageType":13038,"path":13092,"seo":13093,"slug":13090,"stem":13094,"__hash__":13095},"jsonPages/fr/tags/resources.json","Ressources Animation","ressources",{"name":13089},"/fr/tags/resources",{},"fr/tags/resources","4ipa755g5-wReMgNYNc3YBVdop1OSilM_6y3UCpoFyI",[13097,13100,13103,13106,13109,13112,13115],{"id":13036,"title":1828,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":1829,"meta":13098,"navigation":13,"pageType":13038,"path":13039,"seo":13099,"slug":1829,"stem":13041,"__hash__":13042},{"name":1828},{},{"id":13044,"title":13045,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13046,"meta":13101,"navigation":13,"pageType":13038,"path":13048,"seo":13102,"slug":13046,"stem":13050,"__hash__":13051},{"name":13045},{},{"id":13053,"title":13054,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13055,"meta":13104,"navigation":13,"pageType":13038,"path":13057,"seo":13105,"slug":13055,"stem":13059,"__hash__":13060},{"name":13054},{},{"id":13062,"title":13063,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13064,"meta":13107,"navigation":13,"pageType":13038,"path":13066,"seo":13108,"slug":13064,"stem":13068,"__hash__":13069},{"name":13063},{},{"id":13071,"title":13072,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":572,"meta":13110,"navigation":13,"pageType":13038,"path":13074,"seo":13111,"slug":572,"stem":13076,"__hash__":13077},{"name":13072},{},{"id":13079,"title":13080,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13081,"meta":13113,"navigation":13,"pageType":13038,"path":13083,"seo":13114,"slug":13081,"stem":13085,"__hash__":13086},{"name":13080},{},{"id":13088,"title":13089,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13090,"meta":13116,"navigation":13,"pageType":13038,"path":13092,"seo":13117,"slug":13090,"stem":13094,"__hash__":13095},{"name":13089},{},1776340317537]