2. Modélisation polygonale et modificateurs
Sections
Réglages de lecture
Aucune voix pour cette langue dans ce navigateur.
Plus de voix
Code et termes techniques en anglais
Désactivé : la voix de la page lit tout, sans pause entre deux voix.
Aucune voix pour cette langue dans ce navigateur.
Plus de voix
D’autres voix : Microsoft Edge propose des voix naturelles en ligne, et Windows (Paramètres › Heure et langue › Voix), macOS et Android en installent d’autres.
Code : le script de la leçon, scripts/l02_modeling.py, le modèle de la touche, scripts/fretboard.py, et le rapport, expected/l02_modeling.txt.
De quoi est fait un maillage
Section intitulée « De quoi est fait un maillage »Un maillage (mesh) est une liste de sommets (des points), d’arêtes (des paires de sommets) et de faces (des polygones fermés de trois sommets ou plus). Blender ajoute un quatrième élément que les tutoriels mentionnent rarement : la boucle (loop), ou coin de face. Une face à quatre sommets a quatre boucles, et un sommet partagé par trois faces appartient à trois boucles. Tout ce qui peut différer d’une face à l’autre au même sommet est stocké par boucle : les coordonnées UV (leçon 3), les normales séparées (split normals), les couleurs de sommets.
La touche du cours commence comme une plaque effilée de huit sommets et six quadrilatères, donnés à Mesh.from_pydata sous forme de listes Python, comme on remplirait un vertex buffer et un index buffer :
verts = [ (0, -w0, -THICKNESS), (length, -w1, -THICKNESS), (length, w1, -THICKNESS), (0, w0, -THICKNESS), (0, -w0, 0), (length, -w1, 0), (length, w1, 0), (0, w0, 0),]faces = [(0, 3, 2, 1), (4, 5, 6, 7), (0, 1, 5, 4), (1, 2, 6, 5), (2, 3, 7, 6), (3, 0, 4, 7)]mesh = bpy.data.meshes.new(name)mesh.from_pydata(verts, [], faces)mesh.validate()from_pydata déduit les arêtes des faces, et validate cherche des données invalides dans le résultat et corrige ce qu’il trouve. Le rapport :
== A mesh from vertices and faces (from_pydata)fretboard slab: V 8 E 12 F 6 loops 24topology: {'quads': 6} boundary edges 0 non-manifold edges 0 V-E+F 2face 0 (bottom) vertices [0, 3, 2, 1] normal (0.000, 0.000, -1.000)face 1 (top) vertices [4, 5, 6, 7] normal (0.000, 0.000, 1.000)the bottom face wound the other way: normal (0.000, 0.000, 1.000)L’ordre des sommets d’une face, son sens d’enroulement (winding), fixe sa normale : vus du côté vers lequel pointe la normale, les sommets tournent dans le sens inverse des aiguilles d’une montre. Enroule la face du dessous dans l’autre sens, et sa normale pointe vers l’intérieur de la plaque. Les moteurs de rendu et les exporteurs utilisent les normales pour l’ombrage et pour l’élimination des faces arrière (back-face culling), donc une face retournée apparaît noire ou disparaît dans three.js. En Edit Mode, Mesh › Normals › Recalculate Outside (Shift + N) tourne les faces sélectionnées vers l’extérieur.
La topologie
Section intitulée « La topologie »Les modeleurs parlent de topologie : la façon dont les éléments sont connectés, indépendamment de la position des sommets. Le script compte quelques propriétés avec bmesh, la structure de maillage modifiable de Blender :
== Open and non-manifold meshesone quad: V 4 E 4 F 1 {'quads': 1} boundary edges 4 non-manifold edges 4 V-E+F 1three quads sharing one edge: V 8 E 10 F 3 {'quads': 3} boundary edges 9 non-manifold edges 10 V-E+F 1the slab triangulated: V 8 E 18 F 12 {'tris': 12} boundary edges 0 non-manifold edges 0 V-E+F 2- Un maillage manifold (variété close) est un maillage où chaque arête a exactement deux faces : une surface fermée, comme la plaque. Une arête de bord (boundary) n’a qu’une face : c’est le bord d’une feuille ouverte. Une arête à trois faces, comme le dos d’un livre de trois pages, est elle aussi non manifold. L’impression 3D et les opérations booléennes attendent des maillages manifold.
- Pour une surface fermée, V − E + F est la caractéristique d’Euler : 2 pour tout ce qui a la forme d’une sphère, quelle que soit sa subdivision, 0 pour un tore (exercice 1). C’est une vérification peu coûteuse qu’un maillage généré n’a pas de trous.
- Les quadrilatères (quads) sont la norme en modélisation, parce que les boucles de quads se subdivisent proprement et que les outils de boucles d’arêtes les suivent. Les triangles sont ce que dessinent les GPU : l’exporteur glTF (leçon 3) et le GPU triangulent tout de toute façon. Les faces de plus de quatre côtés, les n-gons, conviennent aux surfaces planes et posent problème sur les surfaces courbes.
Un Mesh stocke des tableaux plats, compacts et rapides à lire. Un BMesh stocke les adjacences : chaque sommet connaît ses arêtes, chaque arête ses faces. C’est sur lui que travaille l’Edit Mode, et c’est lui qu’utilisent les scripts pour changer la topologie. On passe de l’un à l’autre avec bm.from_mesh(mesh) et bm.to_mesh(mesh), comme on chargerait un tableau immuable dans une structure de graphe pour le modifier puis le réécrire.
L’Edit Mode
Section intitulée « L’Edit Mode »Sélectionne le cube, appuie sur Tab, et te voilà en Edit Mode, où tu travailles sur les sommets (1), les arêtes (2) ou les faces (3). Les outils qu’un débutant utilise le plus, avec leurs raccourcis par défaut :
| Outil | Raccourci | Ce qu’il fait |
|---|---|---|
| Extrude | E |
tire la sélection vers l’extérieur, avec de nouvelles faces sur ses côtés |
| Inset | I |
crée une face plus petite à l’intérieur de chaque face sélectionnée |
| Loop cut | Ctrl + R |
ajoute une boucle d’arêtes en travers d’une bande de quads |
| Bevel | Ctrl + B |
remplace les arêtes vives par une bande de faces |
| Knife | K |
découpe de nouvelles arêtes en travers des faces |
Ces outils modifient le maillage lui-même. Un modèle construit uniquement avec eux est une suite de modifications dont l’historique est perdu à l’enregistrement : revenir changer la largeur d’un biseau oblige à annuler tout ce qui a suivi.
La pile de modificateurs
Section intitulée « La pile de modificateurs »Un modificateur (modifier) est une opération sur la géométrie d’un objet qui n’est pas appliquée au maillage : le maillage reste tel quel, et Blender recalcule le résultat chaque fois que quelque chose change. Les modificateurs d’un objet forment une pile (stack), exécutée de haut en bas, chacun prenant la sortie du précédent. Pour un développeur C# ou Java, c’est une chaîne de décorateurs autour du maillage, ou un pipeline LINQ ou Stream, évalué par un graphe de dépendances quand une entrée change.
Le script ajoute un Bevel puis un Subdivision Surface à un cube, et demande le maillage évalué au graphe de dépendances :
def evaluated(obj): depsgraph = bpy.context.evaluated_depsgraph_get() eval_obj = obj.evaluated_get(depsgraph) text = counts(eval_obj.to_mesh()) eval_obj.to_mesh_clear() return text== The modifier stack is evaluated; the mesh stays as it isstack ['Bevel', 'Subdivision']cube.data: V 8 E 12 F 6 | evaluated: V 866 E 1728 F 864stack ['Subdivision', 'Bevel'] | evaluated: V 98 E 192 F 96Subdivision hidden in the viewport | evaluated: V 56 E 108 F 54Bevel applied: stack ['Subdivision'] | cube.data: V 56 E 108 F 54 | evaluated: V 866 E 1728 F 864cube.datagarde ses 8 sommets, quoi que fasse la pile. Ce que dessine le viewport et ce que rend le moteur de rendu, c’est le maillage évalué, que calculeDepsgraph.to_meshdonne une copie temporaire, queto_mesh_clearlibère. L’exporteur glTF fait exception : il écrit le maillage sans ses modificateurs, sauf si tu actives Apply Modifiers (export_apply, désactivé par défaut).- L’ordre compte. Avec le Bevel d’abord, les 12 arêtes du cube sont arrondies, puis la subdivision lisse un maillage biseauté : un cube arrondi. Avec la subdivision d’abord, le cube devient une quasi-sphère de 96 quads, puis le biseau ne fait rien : sa méthode de limite par défaut ne biseaute que les arêtes dont les faces se rencontrent à plus de 30°, et il n’en reste aucune. L’image montre les deux.
- Chaque modificateur peut être masqué dans le viewport ou dans les rendus sans être supprimé.
- Apply écrit le résultat d’un modificateur dans le maillage et le retire de la pile : les 56 sommets du biseau sont désormais de vrais sommets de
cube.data. C’est la seule étape qui n’est pas réversible.

L’image a été rendue par scripts/render_images.py avec Cycles, avec un ombrage lisse (smooth shading) sur les deux objets. L’ombrage lisse ne change que les normales utilisées pour l’éclairage, pas la géométrie : la silhouette de la sphère montre encore ses facettes.
Mirror et Array
Section intitulée « Mirror et Array »Deux modificateurs se chargent de copier de la géométrie. Mirror reflète le maillage par rapport à l’origine de l’objet, si bien qu’on ne modélise que la moitié d’un objet symétrique. Array le répète avec un décalage, relatif à la taille de l’objet ou constant :
== Mirror and Arraya cube whose center is 1 m from the origin, mirrored in X, then 5 copies in Y: V 80 E 120 F 60copies that touch, with Merge on: V 48 E 88 F 52local bounds: evaluated (-1.50, -0.50, -0.50) (0.50, 4.50, 0.50) | cube.data (0.50, -0.50, -0.50) (1.50, 0.50, 0.50)Le miroir s’applique par rapport à l’origine de l’objet, pas au centre du maillage : c’est parce que le maillage est décalé de 1 m par rapport à l’origine que les deux moitiés sont séparées. Avec des copies qui se touchent et Merge activé, le modificateur Array soude les sommets là où les copies se rencontrent : 8 contacts, 4 sommets et 4 arêtes chacun, soit 32 sommets et 32 arêtes de moins, et les deux faces plaquées l’une contre l’autre à chaque contact n’en font plus qu’une, soit 8 faces de moins. Cette face reste, à l’intérieur du solide. Les limites évaluées vont de −1,5 à 1,5 en X, alors que le maillage lui-même va de 0,5 à 1,5.
La touche du cours
Section intitulée « La touche du cours »fretboard.py construit le modèle que les leçons suivantes éclairent, texturent, rendent et exportent :
- la touche, la plaque ci-dessus, longue de 476 mm, large de 43 mm au sillet et de 56 mm à la dernière frette ;
- 22 fils de frette : un seul maillage de cube, et 22 objets, chacun avec sa propre position et sa propre échelle, ayant la touche pour parent ;
- 10 repères ronds aux frettes 3, 5, 7, 9, 12 (deux), 15, 17, 19 et 21, qui partagent un maillage de cylindre.
Le tempérament égal place la frette n à diapason × (1 − 2−n/12) du sillet, donc chaque intervalle est 21/12 fois plus court que le précédent. Un modificateur Array ne sait répéter qu’un décalage constant ou relatif, donc il ne peut pas placer des frettes. Une boucle le peut :
for n in range(1, FRETS + 1): x = fret_x(n) obj = bpy.data.objects.new(f"Fret {n:02d}", wire) obj.location = (x, 0, FRET_WIRE_HEIGHT / 2) obj.scale = (FRET_WIRE_WIDTH, width_at(x), FRET_WIRE_HEIGHT) obj.parent = board coll.objects.link(obj)== The course's fretboardmesh 'Fret wire': V 8 E 12 F 6, 22 objects: Fret 01 to Fret 22mesh 'Fretboard': V 8 E 12 F 6, 1 objects: Fretboard to Fretboardmesh 'Inlay dot': V 48 E 72 F 26, 10 objects: Inlay 03 to Inlay 21Fret 01: x 36.37 mm, length 44.01 mmFret 12: x 324.00 mm, length 52.04 mmFret 22: x 466.16 mm, length 56.00 mmobjects 33 | vertices stored 64 | vertices drawn 664world bounds in mm (0.0, -28.1, -6.0) (476.2, 28.1, 1.2)La 12e frette est à 324 mm, la moitié du diapason : l’octave. Les duplications liées de la leçon 1 portent leurs fruits ici : 64 sommets sont stockés pour 664 dessinés, et changer le profil du fil revient à changer un seul maillage. Avant de lire les limites dans le repère du monde, le script appelle bpy.context.view_layer.update() : les objets créés depuis Python ne reçoivent leur matrice monde, qui inclut la transformation du parent, qu’à la prochaine évaluation du view layer.
Points clés
Section intitulée « Points clés »- Un maillage, ce sont des sommets, des arêtes, des faces et des boucles ; les données qui peuvent différer d’une face à l’autre en un même sommet, comme les UV, vivent sur les boucles.
- Le sens d’enroulement d’une face fixe sa normale ; dans un maillage fermé, chaque arête appartient à deux faces, et V − E + F = 2 quand il a la forme d’une sphère.
Meshstocke des tableaux plats ;bmeshstocke les adjacences, et c’est avec lui qu’on modifie la topologie.- Les modificateurs forment une pile évaluée par le graphe de dépendances ; le maillage reste inchangé tant que tu n’en appliques pas un, et l’ordre de la pile change le résultat.
- Lis le maillage évalué avec
evaluated_get(depsgraph).to_mesh(), et libère-le avecto_mesh_clear(). - Certaines formes suivent une règle qu’aucun modificateur ne connaît, comme les frettes ; un script les place dans une boucle.
Exercices
Section intitulée « Exercices »- Ajoute un tore avec
bpy.ops.mesh.primitive_torus_add(major_segments=48, minor_segments=12). Prédis ses nombres de sommets, d’arêtes et de faces, et son V − E + F, puis vérifie. - Mets Subdivision avant Bevel, comme dans la leçon, et trouve le réglage du Bevel qui lui fait biseauter le cube subdivisé. Combien de sommets le résultat a-t-il ?
- Vérifie à partir de
fretboard.fret_xque le rapport entre deux intervalles de frettes consécutifs est le même tout le long du manche, et compare-le à 21/12.
Solution 1
== Exercise 1: the Euler characteristic of a torustorus: V 576 E 1152 F 576 {'quads': 576} boundary edges 0 non-manifold edges 0 V-E+F 048 × 12 = 576 quads, et autant de sommets, puisque chaque sommet commence un quad. Chaque quad a 4 arêtes partagées par 2 faces : 576 × 4 / 2 = 1152 arêtes. La surface est fermée et manifold, et V − E + F = 0, la valeur pour un tore.
Solution 2
La Limit Method du biseau (limit_method) vaut par défaut ANGLE, avec 30°. Mets-la à NONE et chaque arête est biseautée :
== Exercise 2: Subdivision then Bevel, without the angle limitlimit_method ANGLE angle 30.0 | evaluated: V 98 E 192 F 96limit_method NONE | evaluated: V 866 E 1728 F 864Les nombres se trouvent être les mêmes que dans l’autre ordre, mais les formes diffèrent : un maillage presque sphérique avec un biseau étroit sur chacune de ses arêtes, et non un cube arrondi.
Solution 3
gaps = [fretboard.fret_x(n + 1) - fretboard.fret_x(n) for n in range(fretboard.FRETS)]== Exercise 3: the spacing of fretsgap nut-1 36.369 mm | gap 21-22 10.813 mm | gap n / gap n+1 ['1.059463'] | 2 ** (1/12) 1.059463Les 21 rapports s’arrondissent tous aux mêmes six décimales, 1,059463, soit 21/12. L’intervalle diminue de ce facteur à chaque frette, et c’est pourquoi le décalage constant d’un modificateur Array ne peut pas le reproduire.
- Manuel de Blender 5.2 : structure des maillages, modificateurs, Bevel, Subdivision Surface, Mirror, Array, Extrude Region, outil Bevel.
- API Python de Blender 5.2 :
Mesh,bmesh,Depsgraph,BevelModifier. - Code source de Blender à 5.2.2 :
blender_default.py, le keymap par défaut.