AutoLISP : le guide complet — Chapitre 9 / 16

Interagir avec l'utilisateur

Jusqu'ici, nos programmes travaillaient avec des valeurs définies à l'avance dans le code. Mais un programme vraiment utile a besoin d'interagir avec l'utilisateur : lui demander où placer un objet, quelle dimension donner, quel nom attribuer. AutoLISP fournit une famille de fonctions dédiée à cet usage : les fonctions get*.

Le principe général

Toutes les fonctions get* suivent le même schéma :

  1. Elles affichent un message d'invite dans la ligne de commande
  2. Elles attendent que l'utilisateur fournisse une valeur (clic, saisie clavier, etc.)
  3. Elles retournent la valeur saisie dans le type approprié
(setq point (getpoint "\nCliquez un point : "))
(setq rayon (getreal "\nRayon du cercle : "))

Convention : commencez toujours votre message d'invite par \n pour qu'il s'affiche sur une nouvelle ligne dans la ligne de commande. Sans ce \n, le message se colle au texte précédent et devient difficile à lire.

Recueillir des points

getpoint — un point dans le dessin

getpoint demande à l'utilisateur de cliquer un point ou de saisir des coordonnées. Elle retourne une liste de trois réels (X Y Z) :

(setq point (getpoint "\nPoint d'insertion : "))
;; L'utilisateur clique → (125.0 80.5 0.0)

(car point)    ; → 125.0 (coordonnée X)
(cadr point)   ; → 80.5  (coordonnée Y)
(caddr point)  ; → 0.0   (coordonnée Z)

getpoint accepte un point de base optionnel. Quand il est fourni, AutoCAD dessine une ligne élastique entre ce point de base et le curseur, ce qui aide l'utilisateur à visualiser la direction :

(setq point1 (getpoint "\nPremier point : "))
(setq point2 (getpoint point1 "\nDeuxième point : "))

getcorner — un coin de rectangle

getcorner est similaire à getpoint, mais elle dessine un rectangle élastique entre le point de base et le curseur. Elle est idéale pour définir une zone rectangulaire :

(setq coin1 (getpoint "\nPremier coin : "))
(setq coin2 (getcorner coin1 "\nCoin opposé : "))

Attention : contrairement à getpoint, le point de base est obligatoire pour getcorner.

Recueillir des valeurs numériques

getint — un nombre entier

(setq nombre (getint "\nNombre de copies : "))
;; L'utilisateur tape 5 → 5

getint n'accepte que des nombres entiers. Si l'utilisateur tape 3.5 ou abc, AutoCAD lui demande de recommencer.

getreal — un nombre réel

(setq hauteur (getreal "\nHauteur du texte : "))
;; L'utilisateur tape 2.5 → 2.5

getdist — une distance

getdist est la fonction la plus polyvalente pour obtenir une valeur de distance. L'utilisateur peut soit taper une valeur, soit cliquer deux points dans le dessin — AutoCAD calcule alors la distance entre eux :

(setq longueur (getdist "\nLongueur : "))
;; L'utilisateur tape 50.0 → 50.0
;; OU clique deux points → distance entre les deux

Avec un point de base, l'utilisateur n'a besoin de cliquer qu'un seul point :

(setq point1 (getpoint "\nPoint de départ : "))
(setq longueur (getdist point1 "\nLongueur : "))
;; L'utilisateur clique un second point → distance calculée

Bonne pratique : getdist retourne toujours la valeur en unités internes du dessin, indépendamment du format d'affichage (architectural, décimal, etc.). C'est la fonction recommandée pour demander des dimensions, plutôt que getreal.

getangle — un angle

getangle demande un angle. L'utilisateur peut taper une valeur ou cliquer deux points pour définir la direction. L'angle est toujours retourné en radians, quelle que soit la variable système AUNITS :

(setq angle (getangle "\nAngle de rotation : "))
;; L'utilisateur tape 45 (degrés) → 0.785398 (radians)

Avec un point de base :

(setq point-base (getpoint "\nPoint de base : "))
(setq angle (getangle point-base "\nAngle : "))

getorient — un angle absolu

getorient fonctionne comme getangle, mais elle ignore les variables système ANGBASE (angle de base) et ANGDIR (sens des angles). L'angle retourné est toujours mesuré à partir de l'est, dans le sens trigonométrique. Utilisez getorient quand vous avez besoin d'un angle absolu, indépendant de la configuration de l'utilisateur.

(setq orientation (getorient "\nOrientation : "))

Quand choisir getangle ou getorient ? Utilisez getangle quand vous voulez un angle relatif (une rotation, un écart angulaire). Utilisez getorient quand vous voulez une direction absolue (l'orientation d'un texte, d'un bloc).

Recueillir du texte

getstring — une chaîne de caractères

(setq nom (getstring "\nNom du calque : "))
;; L'utilisateur tape "Construction" → "Construction"

Par défaut, getstring s'arrête au premier espace. Si vous avez besoin d'accepter des espaces (par exemple pour un nom complet), passez T comme premier argument :

(setq description (getstring T "\nDescription : "))
;; L'utilisateur peut taper "Mur porteur niveau 2" → "Mur porteur niveau 2"

Sans le T, la saisie "Mur porteur" serait tronquée à "Mur".

Recueillir un mot-clé

getkword — un choix parmi des options

getkword permet de proposer un menu de choix à l'utilisateur. On définit d'abord les options avec initget, puis on appelle getkword :

(initget "Oui Non")
(setq reponse (getkword "\nConfirmer ? [Oui/Non] : "))
;; L'utilisateur tape "Oui", "O", "Non" ou "N"

Les mots-clés sont insensibles à la casse. AutoLISP accepte aussi les abréviations : les lettres majuscules dans la chaîne initget définissent le préfixe minimum. Par exemple, "Oui Non" accepte O pour Oui et N pour Non.

Pour contrôler plus finement les abréviations :

(initget "Rouge Vert Bleu")
(setq couleur (getkword "\nCouleur ? [Rouge/Vert/Bleu] : "))
;; "R" → "Rouge", "V" → "Vert", "B" → "Bleu"

Si l'utilisateur tape un mot qui ne correspond à aucun mot-clé, AutoCAD affiche un message d'erreur et redemande la saisie.

Contrôler les saisies avec initget

La fonction initget permet de restreindre ce que l'utilisateur peut saisir. Elle s'appelle avant la fonction get* et affecte uniquement le prochain appel.

Les bits de contrôle

initget accepte un entier (ou une combinaison de bits) qui active différentes restrictions :

Bit Valeur Effet
1 1 Interdit une saisie vide (Entrée sans rien taper)
2 2 Interdit la valeur zéro
4 4 Interdit les valeurs négatives
8 8 Ne vérifie pas les limites du dessin (même si LIMCHECK est activé)
32 32 Affiche les coordonnées avec un tiret au lieu d'une virgule en 2D
64 64 Ignore la coordonnée Z (retourne un point 2D)
128 128 Autorise une saisie arbitraire (retourne la chaîne telle quelle)

Les bits se combinent par addition :

;; Interdire vide (1) + zéro (2) + négatif (4) = 7
(initget 7)
(setq rayon (getreal "\nRayon (valeur positive non nulle) : "))
;; Interdire saisie vide
(initget 1)
(setq point (getpoint "\nPoint obligatoire : "))

Combiner bits et mots-clés

initget peut recevoir à la fois des bits et des mots-clés :

(initget 7 "Diametre")
(setq valeur (getreal "\nRayon ou [Diamètre] : "))

Ici, l'utilisateur peut soit taper un nombre positif non nul, soit taper D (ou Diametre) pour choisir l'option diamètre. Quand un mot-clé est saisi, getreal retourne le mot-clé sous forme de chaîne au lieu d'un nombre — il faut donc tester le résultat.

Gérer les mots-clés dans les fonctions get*

Quand initget définit des mots-clés, les fonctions get* numériques (getreal, getint, getdist, etc.) et géométriques (getpoint, getcorner, etc.) peuvent retourner soit leur type normal, soit une chaîne (le mot-clé). Il faut donc tester le type de la valeur retournée :

(defun c:mon-cercle (/ centre valeur rayon)
  (setq centre (getpoint "\nCentre du cercle : "))

  (initget 7 "Diametre")
  (setq valeur (getdist centre "\nRayon ou [Diamètre] : "))

  (if (= (type valeur) 'STR)
    ;; L'utilisateur a tapé "Diametre"
    (progn
      (initget 7)
      (setq rayon (/ (getdist centre "\nDiamètre : ") 2.0))
    )
    ;; L'utilisateur a donné un nombre → c'est le rayon
    (setq rayon valeur)
  )

  (command "_CIRCLE" centre rayon)
  (princ)
)

Valeurs par défaut

Les fonctions get* ne gèrent pas nativement les valeurs par défaut, mais c'est facile à implémenter. L'idée : ne pas interdire la saisie vide (pas de bit 1 dans initget), et tester si le résultat est nil :

(defun c:texte-perso (/ hauteur)
  ;; Pas de bit 1 → saisie vide autorisée
  (initget 6)  ; Interdire zéro et négatif, mais autoriser vide
  (setq hauteur (getreal "\nHauteur du texte <2.5> : "))

  ;; Si l'utilisateur a appuyé sur Entrée sans rien taper
  (if (not hauteur)
    (setq hauteur 2.5)
  )

  (princ (strcat "\nHauteur choisie : " (rtos hauteur)))
  (princ)
)

Convention AutoCAD : la valeur par défaut est affichée entre chevrons < > dans le message d'invite. C'est une convention que tous les utilisateurs d'AutoCAD connaissent.

Exemple complet : dessiner un rectangle interactif

Voici un programme qui met en pratique toutes les fonctions vues dans ce chapitre :

(defun c:rectangle-interactif (/ coin1 mode largeur hauteur coin2 coin3 coin4)
  ;; Demander le premier coin
  (initget 1)
  (setq coin1 (getpoint "\nPremier coin : "))

  ;; Demander le mode de saisie
  (initget "Dimensions Coin")
  (setq mode (getkword "\nMode ? [Dimensions/Coin opposé] <Coin opposé> : "))

  (if (not mode)
    (setq mode "Coin")
  )

  (if (= mode "Dimensions")
    ;; Mode dimensions : demander largeur et hauteur
    (progn
      (initget 7)
      (setq largeur (getdist coin1 "\nLargeur : "))
      (initget 7)
      (setq hauteur (getdist coin1 "\nHauteur : "))

      (setq coin2 (list (+ (car coin1) largeur) (cadr coin1)))
      (setq coin3 (list (+ (car coin1) largeur) (+ (cadr coin1) hauteur)))
      (setq coin4 (list (car coin1) (+ (cadr coin1) hauteur)))
    )
    ;; Mode coin opposé : demander le coin diagonal
    (progn
      (setq coin3 (getcorner coin1 "\nCoin opposé : "))
      (setq coin2 (list (car coin3) (cadr coin1)))
      (setq coin4 (list (car coin1) (cadr coin3)))
    )
  )

  ;; Dessiner le rectangle
  (command "_LINE" coin1 coin2 coin3 coin4 "_Close")

  (princ (strcat "\nRectangle dessiné — "
    "Largeur : " (rtos (distance coin1 coin2))
    ", Hauteur : " (rtos (distance coin2 coin3))
  ))
  (princ)
)

Ce programme illustre plusieurs concepts :

  • getpoint pour le premier coin, avec initget 1 pour le rendre obligatoire
  • getkword pour proposer un choix de mode, avec une valeur par défaut
  • getdist pour les dimensions, avec le point de base pour la ligne élastique
  • getcorner pour le coin opposé, avec le rectangle élastique

Résumé

Fonction Retourne Usage
getpoint Liste (X Y Z) Cliquer ou saisir un point
getcorner Liste (X Y Z) Cliquer un coin (rectangle élastique)
getint Entier Saisir un nombre entier
getreal Réel Saisir un nombre réel
getdist Réel Saisir ou cliquer une distance
getangle Réel (radians) Saisir ou cliquer un angle relatif
getorient Réel (radians) Saisir ou cliquer un angle absolu
getstring Chaîne Saisir du texte
getkword Chaîne Choisir parmi des mots-clés
initget nil Configurer la prochaine fonction get*

Dans le prochain chapitre, nous allons utiliser ces saisies pour interagir avec le dessin AutoCAD : créer des lignes, des cercles, modifier des entités existantes.


Coup de pouce Besoin d'un développement AutoCAD (AutoLISP, ObjectARX, .NET, VBA) ? Contactez-moi pour un devis gratuit.