BlenderCube
Addon Rubik's Cube paramétrique pour Blender
L'idée
Je voulais me frotter à l’API Python de Blender avec un vrai addon plutôt qu’un script jetable. Il génère le mesh, colore les faces et monte un rig animable. Il se pilote depuis le panneau latéral de Blender et s’installe comme n’importe quel addon.
Génération paramétrique
L’opérateur OP_CreateRubik est le point d’entrée. Il expose quatre propriétés dans le panneau :
grid: nombre de cubes par axe (de 2 à 5)size: taille globale du cube en unités Blenderspacing: écart entre les petits cubesbevel_offset: rayon du biseau sur les arêtes
Chaque petit cube est construit avec bmesh, biseauté, puis lissé. Tout dérive de la taille globale : pour passer d’un 2x2 à un 5x5, je change grid dans le panneau et je ne touche pas au code.
Matériaux par face
material_tools.py parcourt le maillage en mode édition et repère les faces dont la normale pointe vers l’extérieur du cube global. Chacune des six directions reçoit son Principled BSDF : haut blanc, bas jaune, avant rouge, arrière orange, gauche bleu, droite vert. Les faces internes, entre deux petits cubes, restent neutres comme sur un vrai Rubik’s.
Rig avec contraintes Child Of
C’est la partie la plus dense. Je crée une armature racine à laquelle je parente chaque petit cube, puis je place trois séries de bones contrôleurs le long des axes X, Y et Z.
Pour chaque petit cube, apply_child_of_constraints cherche le contrôleur le plus proche sur chaque axe, en mesurant en espace monde la distance entre le centre de géométrie du cube et la tête du bone. Il ajoute ensuite une contrainte Child Of qui copie seulement la rotation de cet axe : translations et échelle sont désactivées, et les rotations parasites sont verrouillées sur les contrôleurs. Tourner le bone d’une tranche n’entraîne alors que les cubes de cette tranche.
Architecture dual-mode script/addon
__init__.py détecte comment il est lancé, avec if __name__ == "__main__".
- En script (développement) : il injecte le dossier courant dans
sys.path, recharge les modules modifiés avecimportlib.reloadet appelleregister()à la main. Je peux itérer sans réinstaller l’addon. - En addon : il déclare
bl_info(nom, version, catégorie), passe par les imports relatifs de Blender, et Blender appelle lui-mêmeregister()etunregister().
Un seul fichier d’entrée sert donc aux deux cas.
Limite assumée
Le rig n’est pas terminé. La sélection par proximité se base sur la pose de repos : une fois une tranche tournée, l’armature continue de raisonner sur les positions de départ des centres de géométrie. On ne peut donc pas enchaîner deux rotations librement, comme sur un vrai Rubik’s.
Je ne l’ai pas traité, c’était hors de portée d’un week-end, et c’est documenté. Il faudrait recalculer l’appartenance aux tranches après chaque rotation, ou passer par des groupes dynamiques.