Détectez les cotes forcées en AutoLISP sur votre dessin, l'intelligence artificielle vole à votre secours !

Bonjour, nous voici de retour dans l’assistant AutoCAD expert de Dessein-Tech pour une petite démonstration de génération d’une routine AutoLISP.

Cette fois-ci, nous allons demander à l’intelligence artificielle de nous créer un programme AutoLISP qui va montrer les cotes forcées sur votre espace objet.

[!Note]
Si cette démonstration a été faite avec Gemini 3 Pro, il est tout à fait possible pour de très simples petites routines comme cela d’utiliser la version gratuite de l’assistant AutoCAD® expert Dessein-Tech.

DetectCotesForcees.lsp (2,8 Ko)

(defun c:DetectCotesForcees (/ ss i ent elist txtVal ptCenter viewH size halfSize p1 p2 p3 p4 vecList count)
  ;; 1. Récupération de la hauteur de vue actuelle
  (setq viewH (getvar "VIEWSIZE"))
  ;; Taille du carré = 1/20ème de la hauteur de vue
  (setq size (/ viewH 20.0))
  (setq halfSize (/ size 2.0))
  
  (setq vecList '()) ;; Liste pour stocker les vecteurs
  (setq count 0)     ;; Compteur de cotes forcées

  ;; 2. Sélection de toutes les cotes du dessin
  (setq ss (ssget "_X" '((0 . "DIMENSION"))))

  (if ss
    (progn
      (setq i 0)
      (repeat (sslength ss)
        (setq ent (ssname ss i))
        (setq elist (entget ent))

        ;; 3. Vérification du forçage de texte (Code DXF 1)
        ;; Si le code 1 n'est pas vide (""), la cote est considérée comme forcée ou modifiée.
        (setq txtVal (cdr (assoc 1 elist)))

        (if (and (/= txtVal "") (/= txtVal "<>"))
          (progn
            (setq count (1+ count))
            
            ;; 4. Récupération de la position du texte (Code DXF 11)
            (setq ptCenter (cdr (assoc 11 elist)))
            
            ;; Conversion du point WCS (Général) vers UCS (Courant) pour l'affichage grvecs
            (setq ptCenter (trans ptCenter 0 1))

            ;; 5. Calcul des 4 coins du carré
            (setq p1 (list (- (car ptCenter) halfSize) (- (cadr ptCenter) halfSize) (caddr ptCenter)))
            (setq p2 (list (+ (car ptCenter) halfSize) (- (cadr ptCenter) halfSize) (caddr ptCenter)))
            (setq p3 (list (+ (car ptCenter) halfSize) (+ (cadr ptCenter) halfSize) (caddr ptCenter)))
            (setq p4 (list (- (car ptCenter) halfSize) (+ (cadr ptCenter) halfSize) (caddr ptCenter)))

            ;; 6. Construction de la liste de vecteurs
            ;; Format grvecs : (couleur pt1 pt2 couleur pt2 pt3 ...)
            ;; Couleur 1 = Rouge
            (setq vecList (append vecList (list 1 p1 p2 1 p2 p3 1 p3 p4 1 p4 p1)))
          )
        )
        (setq i (1+ i))
      )

      ;; 7. Dessin des vecteurs à l'écran
      (if (> count 0)
        (progn
          (grvecs vecList)
          (princ (strcat "\nTerminé : " (itoa count) " cote(s) forcée(s) identifiée(s) en rouge."))
        )
        (princ "\nAucune cote forcée trouvée dans le dessin.")
      )
    )
    (princ "\nAucune cote présente dans ce dessin.")
  )
  (princ)
)

Remarque: une autre utilisation des vecteurs en AutoLISP…

  • Super !
  • Bien
  • Ouais bof
  • Nul
0 votant

Bonjour,
Si cela fonctionne, je ne trouve pas l’idée de prendre la taille de la vue en référence merveilleuse.
La taille des textes me parait plus judicieuse.
Ni l’utilisation de GRVECS, qui fait disparaitre les contours au moindre zoom.
un tracé de polylignes dans un calques dédié me semble plus adapté, surtout pour des grands plans.
Cordialement

1 « J'aime »

Cela dépend du but que l’on a en tête, ici l’idée est de repérer visuellement les cotes forcées pas d’ajouter des objets qu’il faudra effacer par la suite.
La taille du carré est constante parce que l’idée n’est pas de représenter la taille d’un texte mais la position de son point d’insertion c’est un marqueur. Cela se fait couramment dans AutoCAD® comme par exemple les marqueurs autosnap.
Mais il est bien facile de demander ce qu’on veut à l’intelligence artificielle puisque elle va le faire quasiment immédiatement et cette démonstration ne consistait pas à montrer en particulier ce programme mais de démontrer que l’on pouvait générer très rapidement ce type de programme quel que soit ce que le programme est censé faire.

Mais bon, si tu préfères cette version la voilà. Il suffit de la demander à l’assistant.

(defun c:EntourerCotesForcees (/ *error* doc layerName ss i ent txtVal lastEnt copyEnt ssExp j entExp elistExp minPt maxPt ptList osm oldEcho)
  (vl-load-com)
  
  (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (setq layerName "COTES-FORCEES-CHECK")

  ;; Gestion d'erreur pour restaurer les variables système
  (defun *error* (msg)
    (if osm (setvar "OSMODE" osm))
    (if oldEcho (setvar "CMDECHO" oldEcho))
    (vla-EndUndoMark doc)
    (if (not (wcmatch (strcase msg t) "*break*,*cancel*,*exit*"))
      (princ (strcat "\nErreur: " msg))
    )
    (princ)
  )

  (vla-StartUndoMark doc)
  
  ;; Sauvegarde des variables
  (setq osm (getvar "OSMODE"))
  (setq oldEcho (getvar "CMDECHO"))
  (setvar "OSMODE" 0)
  (setvar "CMDECHO" 0)

  ;; 1. Création du calque rouge
  (if (not (tblsearch "LAYER" layerName))
    (command "_.LAYER" "_New" layerName "_Color" "1" layerName "")
  )

  ;; 2. Sélection des cotes
  (setq ss (ssget "_X" '((0 . "DIMENSION"))))

  (if ss
    (progn
      (setq i 0)
      (princ "\nAnalyse et traitement en cours...")
      
      (repeat (sslength ss)
        (setq ent (ssname ss i))
        (setq elistExp (entget ent))
        
        ;; 3. Vérification du forçage (Code DXF 1)
        (setq txtVal (cdr (assoc 1 elistExp)))

        (if (and (/= txtVal "") (/= txtVal "<>"))
          (progn
            ;; 4. Méthode "Commande" : Copier sur place et Exploser
            (setq lastEnt (entlast))
            (command "_.copy" ent "" "_non" '(0 0 0) "_non" '(0 0 0))
            (setq copyEnt (entlast))
            
            ;; On s'assure que la copie a bien eu lieu
            (if (not (equal lastEnt copyEnt))
              (progn
                (command "_.explode" copyEnt)
                
                ;; Récupération des objets explosés (Sélection Précédente)
                (setq ssExp (ssget "_P"))
                
                (if ssExp
                  (progn
                    (setq j 0)
                    (repeat (sslength ssExp)
                      (setq entExp (ssname ssExp j))
                      (setq elistExp (entget entExp))
                      
                      ;; On cherche l'objet TEXTE ou MTEXT parmi les débris
                      (if (wcmatch (cdr (assoc 0 elistExp)) "*TEXT")
                        (progn
                          ;; 5. Récupération de la BoundingBox via ActiveX (plus fiable sur le texte)
                          (vla-GetBoundingBox (vlax-ename->vla-object entExp) 'minPt 'maxPt)
                          (setq minPt (vlax-safearray->list minPt))
                          (setq maxPt (vlax-safearray->list maxPt))
                          
                          ;; Calcul des 4 coins
                          (setq ptList (list
                                         (list (car minPt) (cadr minPt) 0.0)
                                         (list (car maxPt) (cadr minPt) 0.0)
                                         (list (car maxPt) (cadr maxPt) 0.0)
                                         (list (car minPt) (cadr maxPt) 0.0)
                                       ))
                          
                          ;; 6. Création de la Polyligne
                          (entmake (list
                                     '(0 . "LWPOLYLINE")
                                     '(100 . "AcDbEntity")
                                     (cons 8 layerName)
                                     '(100 . "AcDbPolyline")
                                     '(90 . 4)
                                     '(70 . 1)
                                     (cons 10 (nth 0 ptList))
                                     (cons 10 (nth 1 ptList))
                                     (cons 10 (nth 2 ptList))
                                     (cons 10 (nth 3 ptList))
                                   ))
                        )
                      )
                      (setq j (1+ j))
                    )
                    ;; Nettoyage : suppression des objets explosés
                    (command "_.erase" ssExp "")
                  )
                )
              )
            )
          )
        )
        (setq i (1+ i))
      )
      (princ (strcat "\nTerminé. Vérifiez le calque : " layerName))
    )
    (princ "\nAucune cote trouvée.")
  )
  
  ;; Restauration des variables
  (setvar "OSMODE" osm)
  (setvar "CMDECHO" oldEcho)
  (vla-EndUndoMark doc)
  (princ)
)

En complément de cette discussion, voir ici d’intéressants commentaires au sujet de l’utilisation de l’intelligence artificielle.

C’est beaucoup mieux.
Moins hors sol.
Gestion des d’erreurs.
Il reste qu’un entmake au milieu de fonctions VLA fait un peut tache.
En utilisant une fonction comme celle ci aurais été parfait.

(defun addpol (lst clos / acobj acdc model pts)
	(setq acobj (vlax-get-acad-object)
          acdc (vla-get-activedocument acobj)
          model (vla-get-modelspace acdc)
		  lst (apply 'append (mapcar '(lambda (x)(list (car x) (cadr x))) lst)) 
		  pts (vlax-make-safearray vlax-vbDouble (cons 0 (- (length lst) 1))))
	(vlax-safearray-fill pts lst)
	(if clos
		(vla-put-Closed (vla-AddLightWeightPolyline model pts) :vlax-true)
		(vla-AddLightWeightPolyline model pts)
	)
)

ainsi que le remplacement des commands, qui rendrais le code beaucoup plus fluide pour les grands plans.
Mais nous constatons qu’il y a du mieux, au début « elles » n’arrivais à rien en Autolisp.

1 « J'aime »

Il est tout à fait possible d’obtenir ce que tu mentionnes, il aurait suffi de le demander dans le prompt initial. Je n’ai pas fait l’essai, mais enfin on peut le supposer.