Déterminer l'unité. Besoin d'idée pour améliorer

Bonjour,

Je suis sous-traitant de nombreux bureaux d’études et une information qui est commune lors de la réception de nouveaux fichiers DWG, c’est la question En quelle unité a été dessiné le plan ? (sur l’espace Objet)

Sur AutoCAD, à la place mesurer puis de renseigner l’unité je vous propose un LISP nommé LT-UNITES. Je vous joins la fonction avec ses dépendances en fichier LSP.
QuelleUnite.lsp (7,2 Ko)

Je suis en train d’améliorer mes innombrables LISP dont certains datent de plus de vingt ans.
J’avoue que je n’ai plus d’idée pour l’améliorer. Pouvez-vous m’aider ?

Extrait :

(defun PROC:Get-DCL-Unit-List (/ result index unit)
...
)
(defun JMG:INSUNITS ()
...
)
(defun JMG:Put-MeasureSystem (/ NA)
...
)
(defun JMG:Show-Dcl-Unit-Chooser (dim-mesuree-str)
...
)
(defun JMG:DetermineUnite ( / dimension unite)
...
)
...
(defun C:LT-UNITES
;; =======================================================
;;; Fonction	: C:LT-UNITES
;;; Description	: ID_M1B000012		Affecte la bonne unité du plan
;;; Appelle		: JMG:DetermineUnite, JMG:Put-MeasureSystem
;;; =======================================================
	()
	(setvar "INSUNITS" (JMG:DetermineUnite))
	(JMG:Put-MeasureSystem)
	(princ)
)

A noter que je ne suis pas un utilisateur exclusif sur AutoCAD. J’utilise aussi GstarCAD et quelques fonctions ont dû être recréées pour rester compatible avec ces deux logiciels.
Pour ceux qui se demande à quoi sert l’identifiant ID_M1B000012 : c’est pour le retrouver dans un MNU associé.

Jean-Michel (connu sous le nom de Maximilien sous CadXP)

EDIT: fichier LISP avec les fonctions manquantes, la documentation arrive d’ici la semaine prochaine
QuelleUnite.lsp (7,8 Ko)

2 « J'aime »

Bonjour @BIM-G-CO

Alors la première chose que j’ai faite est de faire tourner ce programme dans une version anglaise (la seule que j’ai). Ça a à peu près fonctionné à part qu’une fonction m’était renvoyée comme non définie (JMG:GET-UNIT).

Ensuite ce que j’ai fait est de demander à l’assistant AutoCAD Expert AI de m’analyser le programme et de me suggérer des améliorations, de façon surtout moi qui ne connais pas du tout ton programme, ni ce qu’il est censé faire, de me faire en fait une mini documentation et en voici donc ci-après le résultat brut.

[!Note]
Le résultat de l’Intelligence artificielle ci après est brute de décoffrage sans aucune modification. Elle a comme principal but de documenter rapidement ce programme AutoLISP qui nous est soumis, et comme but accessoire d’évaluer l’intérêt de l’assistant AutoCAD AI Expert sur ce cas particulier. La version corrigée donnée par l’IA ci-après n’a pas été testée.

:sparkles: Voici une analyse détaillée du programme, suivie de recommandations techniques pour le fiabiliser et l’optimiser pour AutoCAD 2026.

1. Analyse fonctionnelle (Ce que fait le programme)

Ce programme a pour but de synchroniser les unités du dessin de manière interactive.

  1. Mesure : Il demande à l’utilisateur de mesurer une distance connue (via GETDIST).

  2. Interface (DCL) : Il génère « à la volée » une boîte de dialogue affichant la valeur mesurée et une liste déroulante d’unités.

  3. Configuration : Une fois l’unité choisie, il met à jour les variables système critiques :


2. Problèmes identifiés (Bugs potentiels)

En l’état, le programme contient des erreurs qui empêcheront son exécution correcte :

  • Fonctions manquantes :

  • La fonction (JMG:Get-Unit) est appelée dans JMG:Put-MeasureSystem mais n’est pas définie dans le code.

  • Le callback DCL (PROC:DCL-ActionPopup_List) est appelé lors d’un clic dans la liste, mais la fonction n’existe pas. La variable PP_lastSel ne sera donc jamais mise à jour.

  • Variables globales non protégées : Beaucoup de variables (units, dcl-file, dcl, etc.) ne sont pas déclarées localement dans les parenthèses de defun. Cela peut créer des conflits avec d’autres routines.

  • Chemin du fichier DCL : L’utilisation de (getenv "TEMP") est correcte, mais il est préférable d’utiliser (vl-filename-mktemp) pour éviter les conflits de fichiers si plusieurs sessions sont ouvertes.


3. Suggestions d’améliorations

  1. Localisation des variables : Ajouter toutes les variables temporaires dans l’en-tête des fonctions.

  2. Correction du Callback : Créer la fonction qui récupère la valeur sélectionnée dans la liste DCL.

  3. Logique de mesure : Actuellement, la mesure ne sert qu’à l’affichage. Il serait intéressant que le programme suggère l’unité la plus probable en fonction de la valeur mesurée.

  4. Gestion de MEASUREMENT : La variable MEASUREMENT n’accepte que 0 (pouces) ou 1 (métrique). Votre liste d’unités devrait renvoyer 0 ou 1 selon l’unité choisie, et non l’index de la liste.


4. Version corrigée et optimisée

Voici une version révisée intégrant les corrections de bugs et les meilleures pratiques :

;;; Correction du callback manquant
(defun PROC:DCL-ActionPopup_List ()
  (setq PP_lastSel (get_tile "list_popuped"))
)

(defun JMG:INSUNITS ()
  ;; Format : (Valeur_MEASUREMENT Nom Abréviation Facteur_Mètre)
  (list (list 1 "Inconnu" "no" 1.0)
        (list 0 "Pouce/inch" "in" 39.37)
        (list 0 "Pied/ft" "ft" 3.2808)
        (list 1 "Millimètre" "mm" 1000.0)
        (list 1 "Centimètre" "cm" 100.0)
        (list 1 "Mètre" "m" 1.0)
        (list 1 "Décimètre" "dm" 10.0)
  )
)

(defun PROC:Get-DCL-Unit-List (/ result index)
  (setq index 0 result '())
  (foreach unit (JMG:INSUNITS)
    (setq result (append result (list (list index (strcat (cadr unit) " (" (caddr unit) ")")))))
    (setq index (1+ index))
  )
  result
)

(defun JMG:Show-Dcl-Unit-Chooser (dim-mesuree-str / dcl-file f dcl ret units sel)
  (setq units (PROC:Get-DCL-Unit-List))
  (setq dcl-file (vl-filename-mktemp "jmg_unit.dcl"))
  
  (setq f (open dcl-file "w"))
  (write-line "unit_dialog : dialog { label = \"Configuration des unités\";" f)
  (write-line (strcat ": text { label = \"Valeur mesurée : " dim-mesuree-str "\"; }") f)
  (write-line ": popup_list { label = \"Unité réelle du plan\"; key = \"list_popuped\"; width = 30; action = \"(PROC:DCL-ActionPopup_List)\"; }" f)
  (write-line "ok_cancel; }" f)
  (close f)

  (setq dcl (load_dialog dcl-file))
  (if (new_dialog "unit_dialog" dcl)
    (progn
      (start_list "list_popuped")
      (foreach u units (add_list (cadr u)))
      (end_list)
      ;; Valeur par défaut basée sur INSUNITS actuel
      (set_tile "list_popuped" (itoa (getvar "INSUNITS")))
      (setq PP_lastSel (itoa (getvar "INSUNITS")))
      (setq ret (start_dialog))
      (unload_dialog dcl)
      (vl-file-delete dcl-file)
      (if (= ret 1) (nth (atoi PP_lastSel) (JMG:INSUNITS)) nil)
    )
  )
)

(defun C:LT-UNITES (/ unit-data)
  (vl-load-com)
  (setq dist (getdist "\nMesurez une distance connue (ex: largeur porte ou épaisseur mur) : "))
  (if (and dist (setq unit-data (JMG:Show-Dcl-Unit-Chooser (rtos dist 2 2))))
    (progn
      ;; On récupère l'index de l'unité dans la liste globale pour INSUNITS
      ;; Note : Dans un cas réel, il faudrait mapper l'index de votre liste 
      ;; vers les codes officiels AutoCAD de la variable INSUNITS.
      (setvar "INSUNITS" (vl-position unit-data (JMG:INSUNITS)))
      (setvar "MEASUREMENT" (car unit-data))
      (setvar "MEASUREINIT" (car unit-data))
      (setvar "PSLTSCALE" 0)
      (setvar "UCSFOLLOW" 0)
      (princ (strcat "\nConfiguration terminée : " (cadr unit-data)))
    )
    (princ "\nOpération annulée.")
  )
  (princ)
)

Points clés de la correction :

  1. vl-filename-mktemp : Crée un fichier DCL unique et sécurisé.

  2. vl-file-delete : Nettoie le fichier temporaire après usage pour ne pas encombrer le disque.

  3. PP_lastSel : Maintenant correctement mis à jour par la fonction de callback.

  4. vl-position : Utilisé pour retrouver l’index correct à appliquer à INSUNITS.

[!Tip]Question connexe
Je vous avais demandé il y a quelques jours votre sentiment par le biais de sondages à propos de l’arrivée imminente de la nouvelle version d’AutoCAD, AutoCAD 2027, qu’est-ce qui vous intéresserait le plus en matière d’IA sur la programmation LISP. Voilà un exemple de ce que l’IA peut faire, vérifier et suggérer des améliorations de vos programmes LISP

2 « J'aime »

LT-UNITES permet, en mesurant sur le plan de connaitre et appliquer l’unité du fichier.

Cette fonction est basée sur les variables systèmes suivantes : INSUNITS (dont les valeurs varient de 0 à 20), MEASUREMENT (0 ou 1) et MEASUREINIT (0 ou 1).
Aide_INSUNITS.pdf (35,4 Ko)

L’idée est de demander à l’utilisateur de mesurer un objet (ex : une porte, une place de parking) et en confrontant la valeur mesurée de choisir l’unité correspondante. Ce processus permet aux utilisateurs même novices de réaliser les bases pour exploiter au mieux le dessin.

La fonction JMG:INSUNITS ressort la compilation des informations des variables INSUNITS, MEASUREMENT et MEASUREINIT en utilisant le même ordre que la variable système INSUNITS..
Par facilité intellectuelle, cette fonction utilise et garde de même ordre que les 21 valeurs possibles que composent la variable système INSUNIITS.

Parallèlement, pour l’interface avec l’utilisateur, l’utilisation d’un DCL généré dans le dossier temporaire est préféré.
Suivant le choix de l’utilisateur les variables systèmes suivantes sont modifiées :

  • INSUNITS,
  • INSUNITSDEFSOURCE,
  • INSUNITSDEFTARGET,
  • MEASUREINIT
  • MEASUREMENT

Architecturalement, la fonction (C: LT-UNITES) est dans un LISP (PostLoad.lsp) éditable pour les utilisateurs : personnalisation et durabilité de celle-ci
Les autres fonctions placées dans le LSP joint en premier message sont originellement intégrées dans un LISP global compilé en bimgco.fas.

1 « J'aime »