Outillage DCC / Addon Blender

BlenderCube

Addon Rubik's Cube paramétrique pour Blender

BlenderPythonbpyAddonRigging

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 Blender
  • spacing : écart entre les petits cubes
  • bevel_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 avec importlib.reload et appelle register() à 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ême register() et unregister().

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.

DCC tooling / Blender addon

BlenderCube

Parametric Rubik's Cube addon for Blender

BlenderPythonbpyAddonRigging

The idea

I wanted to get to grips with Blender’s Python API with a real addon rather than a throwaway script. It generates the mesh, colors the faces and builds an animatable rig. It is driven from Blender’s side panel and installs like any other addon.

Parametric generation

The OP_CreateRubik operator is the entry point. It exposes four properties in the panel:

  • grid: number of cubes per axis (2 to 5)
  • size: overall size of the cube in Blender units
  • spacing: gap between the small cubes
  • bevel_offset: bevel radius on the edges

Each small cube is built with bmesh, beveled, then smoothed. Everything derives from the overall size: to go from a 2x2 to a 5x5, I change grid in the panel and leave the code alone.

Per-face materials

material_tools.py walks the mesh in edit mode and finds the faces whose normal points outward on the full cube. Each of the six directions gets its own Principled BSDF: top white, bottom yellow, front red, back orange, left blue, right green. Internal faces, between two small cubes, stay neutral like on a real Rubik’s.

Rig with Child Of constraints

This is the densest part. I create a root armature, parent every small cube to it, then place three sets of controller bones along the X, Y and Z axes.

For each small cube, apply_child_of_constraints looks for the closest controller on each axis, measuring in world space the distance between the cube’s geometry center and the bone head. It then adds a Child Of constraint that only copies the rotation of that axis: translation and scale are disabled, and stray rotations are locked on the controllers. Rotating a layer’s bone then only moves the cubes of that layer.

Dual-mode script/addon architecture

__init__.py detects how it is launched, with if __name__ == "__main__".

  • As a script (development): it injects the current folder into sys.path, reloads modified modules with importlib.reload and calls register() by hand. I can iterate without reinstalling the addon.
  • As an addon: it declares bl_info (name, version, category), uses Blender’s relative imports, and Blender itself calls register() and unregister().

One entry file therefore serves both cases.

Acknowledged limitation

The rig isn’t finished. The proximity-based selection relies on the rest pose: once a layer has been rotated, the armature keeps reasoning on the starting positions of the geometry centers. Two rotations can’t be chained freely, as on a real Rubik’s.

I didn’t tackle it, it was out of reach for a weekend, and it is documented. It would need the layer membership to be recomputed after each rotation, or dynamic groups.