Chaque capacité est un point d’accès avant d’être un bouton

Un modeleur CAO que vos programmes pilotent aussi bien que vos mains.

Aucune opération de Lola3d n’existe uniquement dans l’interface. La barre d’outils, l’API REST, les outils MCP et l’assistant intégré appellent tous les mêmes 228 actions, validées par les mêmes schémas JSON, validées dans les mêmes révisions et étapes d’annulation.

Un catalogue, quatre appelants

La même action, quel que soit le demandeur.

GET /api/studio/actions est le schéma d’exécution qui fait foi — pas un document qui dérive du code, mais le catalogue sur lequel l’application elle-même est construite. Tout ce qu’il contient peut être appelé avec un jeton de session ou un jeton d’API.

Les mutations portent expected_revision. Une révision périmée est refusée avec un 409 plutôt que fusionnée par chance, et une erreur du noyau laisse le document inchangé à l’octet près.

REST
# Everything the modeler can do, with its schema
curl -H "Authorization: Bearer $TOKEN" \
     https://lola3d.app/api/studio/actions

# One edit, on the revision you hold
curl -X POST https://lola3d.app/api/studio/actions/push_pull \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model_id":"…","expected_revision":12,
       "args":{"target":"body1","face_id":"f7","distance":40}}'

# A hundred commands as one revision and one undo step
curl -X POST https://lola3d.app/api/studio/actions/batch …
Conception générative

Python, dans le noyau.

Un lot de commandes ne peut pas relire le modèle entre ses propres commandes. Cette seule limite sépare l’automatisation d’un clic de la génération d’une conception — et c’est ce que la console Python supprime.

Ce que cad vous donne

  • cad.create_box(width=100, …) — n’importe quelle action du catalogue, par son nom, validée par son propre schéma
  • cad.actions() / cad.help(name) — le catalogue, depuis le script
  • cad.document, cad.features, cad.find(name) — le modèle tel qu’il est
  • cad.objects(), cad.bounds() — les corps visibles, leur volume, leur aire et leur encombrement
  • params — les variables que vous avez passées ; print(…) capturé ; result renvoyé

Ce qu’il valide

  • Un script, c’est une modification et une étape d’annulation.
  • Un script qui lève une exception ne valide rien — et indique la ligne qui a échoué.
  • Un script qui ne change rien n’est pas une révision : mesurer est gratuit.
  • dry_run exécute tout et ne garde rien.

Ce que vaut le bac à sable — honnêtement

L’espace de noms restreint — pas de open, pas d’eval, pas d’exec, pas d’attributs dunder, et seulement les modules numériques et structurels — est un garde-fou, pas une frontière de sécurité. CPython n’a jamais offert de vrai bac à sable dans le processus et nous ne prétendrons pas le contraire.

Ce qui tient réellement : le script s’exécute dans un processus worker géométrique avec ses propres plafonds de mémoire et de CPU, sous une échéance que le worker fait respecter lui-même (une boucle active s’arrête d’elle-même au lieu de coûter un worker), et derrière une portéeadmin par défaut, car exécuter un script, c’est exécuter du code sur l’hôte géométrique. Un réglage l’ouvre à tous les éditeurs ; un autre retire complètement l’action du catalogue.

A lattice whose size follows its own arithmetic
n = params["cells"]
pitch = params["pitch"]
strut = params["strut"]

for i in range(n + 1):
    for j in range(n + 1):
        cad.create_box(width=strut, depth=strut,
                       height=n * pitch,
                       position=[i * pitch, j * pitch, 0])

print("struts:", len(cad.features))
result = {"struts": len(cad.features),
          "extent_mm": n * pitch}
Read the model back, then decide
# Nothing applied — so this costs no revision at all.
total = 0.0
for o in cad.objects():
    print(f"{o['name']:<24} {o['volume']:>14,.1f} mm3")
    total += o["volume"]

box = cad.bounds()
size = [round(box["max"][i] - box["min"][i], 2) for i in range(3)]
result = {"bodies": len(cad.objects()), "bbox_mm": size}
La console Python dans l’espace de travail, avec un script, sa sortie et les actions qu’il a appliquées.
Inspecteur → ⋯ → Console Python. Tab indente, Ctrl+Entrée exécute, Essai ne garde rien.
Modélisation par agents

Un agent dispose du même modeleur que vous — et des mêmes freins.

Le point d’accès MCP expose le catalogue sous forme d’outils, soumis aux mêmes portées de lecture et d’écriture que tout autre appelant. Un agent muni d’un jeton de lecture peut mesurer, inspecter et exporter ; muni d’un jeton d’écriture, il peut modéliser.

Il peut aussi travailler comme le ferait un collègue : prévisualiser une modification sans rien écrire, ou en proposer une. Une proposition dessine son propre fantôme dans votre vue avec les deux boutons qui y répondent ; une approbation applique toutes les commandes en une modification avec un groupe dans la chronologie autour de ce qu’elle a créé — un rejet ne laisse rien derrière lui.

  • Les outils de lecture sont libres ; les outils d’écriture passent par une approbation dans l’application.
  • Une exigence formulée en mots devient une annotation contrôlée, revérifiée à chaque reconstruction.
  • Les appels longs portent votre signal d’interruption : un client qui s’en va libère le worker.
MCP
POST /mcp
X-API-Key: ign_…          # scope: ai

{"jsonrpc": "2.0", "id": 1,
 "method": "tools/call",
 "params": {
   "name": "propose_changes",
   "arguments": {
     "model_id": "…",
     "title": "Lighten the web by 18%",
     "commands": [
       {"action": "shell",
        "args": {"target": "web", "thickness": 2.4}}
     ]
   }}}
Échanges

Votre géométrie sort comme elle est entrée.

FormatImportExportRemarques
STEP (.step)OuiOuiB-rep exact. Les assemblages arrivent sous forme de composants.
IGES (.iges)OuiOuiSurfaces cousues là où elles sont étanches.
BREP (.brep)OuiOuiLa forme exacte propre au noyau, avec noms et couleurs.
STL (.stl)OuiOuiCousu en solide s’il est étanche, gardé en faces sinon.
OBJ (.obj)OuiOuiExporté avec son MTL, dans un zip.
3MF (.3mf)OuiOuiCouleurs préservées.
glTF / GLBOuiOuiPour le web et les moteurs de rendu.
Collada (.dae)OuiOuiLa voie d’entrée et de sortie de SketchUp, qui n’a pas de format .skp ouvert.
IFC (.ifc)OuiOuiIFC4 ; corps en proxys, composants en assemblages.
DXF / SVGOuiOuiEn entrée, entités d’esquisse ; en sortie, depuis une esquisse, une coupe ou une mise en plan.
PDFOuiFeuilles de mise en plan.
JSONOuiOuiLe document modifiable lui-même, géométrie figée comprise.
G-codeOuiGRBL, LinuxCNC, Fanuc ou un post-processeur que vous décrivez vous-même.

Prenez un jeton et construisez quelque chose.

Connectez-vous, créez un jeton d’API dans les Paramètres, et tout le modeleur répond à curl. Écrivez ensuite le script qui vous aurait coûté un après-midi de clics.