Bonjour à tous,
Je travaille depuis plusieurs jours sur un projet lié à cadquery (j’ai créer un billet à ce sujet Billet CadQuery) et je sollicite votre aide.
Cadquery est une librairie python de conception de modèle 3D. Un problème majeur c’est que écrire du code sans visualiser ce qu’on créer ce n’est pas pratique, je développe donc une application ajoutant des fonctionnalités graphique au code que l’on écrit pour générer un modèle.
Dans CadQuery ce que l’on peut appeler une pièce est représenté par la classe Workplane
, toutes les méthodes de cette classe sont ce que j’appelle des opérations. Et dans CadQuery on peut chainer les opérations car chaque opération renvoie un objet Workplane
donc en gros chaque appel successif à une méthode prolonge l’arbre d’opérations.
On a en gros pour créer un pavé quelque chose comme ça :
mon_pavé = cadquery.Workplane().rect(1,1).extrude(10)
Qu’on peut venir modifier plus loin si l’on veut :
mon_pavé = mon_pavé.circle(0.5).cutThruAll()
Dans mon application l’utilisateur écris son code dans une console (une qtconsole pour être précis) et le code est exécuté avec exec
Moi j’ai besoin de récupérer plusieurs informations et ma question porte sur comment faire, malgré y avoir pas mal réfléchi je ne suis pas convaincu par mes solutions.
J’ai besoin lors d’une input utilisateur de :
- Récupérer les noms des méthodes appelées dans l’ordre avec les paramètres passés (stocké dans un dict), c’est ce que j’appelle la liste des opérations
- Identifier la pièce à laquelle est associée la liste des opérations (en gros si j’ai plusieurs instances de la classe
Workplane
je dois savoir à laquelle correspond la liste de mes opérations) (Je veux récupérer le nom de la variable)
Pour faire ça j’ai deux pistes, (j’ai surtout creusé la première) :
- Parser l’input de l’utilisateur en AST et analyser l’AST pour créer ma liste d’opérations et trouver à qu’elle instance de
Workplane
elle correspond. Je pense que ça peut fonctionner mais c’est très compliqué et on doit écrire beaucoup de code pour gérer tous les cas "corner cases". C’est particulièrement compliqué dans certains cas typiquement :
part = cq.Workplane().box(1,1,1).union(cq.Workplane().sphere(1.3))
- "monkey patcher" les méthodes de la classe
Workplane
pour qu’elles renvoient les infos voulus lorsqu’elles sont appelées. J’ai deux principaux soucis avec cette méthode
- Certaines méthodes de
Workplane
appellent d’autres méthodes en interne et je ne voudrais pas récupérer d’infos sur ces appels internes. - Je ne sais pas comment retrouver facilement à quel instance (et donc variable) l’appel de la méthode en question est rattaché étant donné que la méthode n’a connaissance que d’elle même.
Voila !
C’est un assez gros morceau, j’ai essayé de faire assez synthétique, je peux donner plus de précision si besoin. Actuellement j’ai pas mal avancé dans l’implémentation du point 1 mais plus j’essais de prendre en compte de cas de figures plus mon code se complique et moins c’est facile à utiliser.
En revanche j’ai le sentiment qu’il est possible d’arriver à une solution élégante avec la deuxième méthode mais je suis bloqué par les points cités.
Finalement, si vous avez d’autres idées, des pistes ou même de la documentation sur ce genre de truc je suis preneur. Je ne suis pas développeur et il n’y a pas autant d’exemples sur le net de comment parser un AST que d’inverser une liste …
Merci de m’avoir lu !