Dessiner Polyligne 2D ou 3D

Méthodes de création des
Polylignes

Il existe principalement deux méthodes pour créer une entité POLYLIGNE dans AutoCAD par programmation.
Deux méthodes en AutoLisp du moins, celles dont je parle dans cet article.
Les méthodes utilisant Visual Lisp seront expliquées ailleurs et quand ce sera fait je mettrai un lien de redirection pour relier ces méthodes.

Une méthode avec "COMMAND"
Et une autre avec "ENTMAKE"
(les liens renvoient vers la ligne dans cette page )

Tout d'abord je vais faire une routine qui va stocker les points cliqués à l'écran dans une liste (list), cette routine servira pour les deux méthodes, "command" et  "entmake".
Dans les deux cas de figure les données de départ pour dessiner cette polyligne sont enregistrées dans une liste de points sous forme de liste (list) de triplets (x y z) de coordonnées sous la forme :
((x1 y1 z1) (x2 y2 z2) (x3 y3 z3) (xn yn zn)...)


Le principe de cette saisie est de demander à l'utilisateur de cliquer des points à l'écran, il peut choisir d'utiliser l'accrochage aux objets s'il le souhaite.
Vous remarquerez que j'ai activé une (très) ancienne variable : "blipmode", elle sert à visualiser les points cliqués à l'écran, pour ceux qui ne connaissent pas cette option il faut savoir que ce n'est que du pixel d'affichage, au moindre zoom, pan ou redess les marques disparaissent, à la fin je remets cette variable obsolète dans son état initial pour ne pas polluer l'affichage.

Ensuite je renseigne une variable de liste (list) vide, ce n'est pas obligatoire mais en apprentissage c'est plus compréhensible, puis en lançant une boucle avec (while) je laisse l'utilisateur cliquer autant de points qu'il a besoin, à chaque clic la liste se complète de ce point cliqué par concaténation avec la fonction (cons).
En appuyant sur Entrée (validation) la saisie de points s'arrête (fin de while) et la liste est enregistrée pour être traitée ultérieurement.

(defun c:sp ( / pt)
  ;|
  sp comme SaisiePoints
  Création d'une liste des points cliqués à l'écran
  |;
  
  (setq pt-lst '());liste vide
  
  (setvar "blipmode" 1); pixel d'affichage en fonction
  
  (while
    (setq pt
	   (getpoint 
            "\nCliquez un point... (Valid pour arrêter)")
	  )
    (setq pt-lst (cons pt pt-lst))
    ); fin de while
  
  (setvar "blipmode" 0); extinction des pixel d'affichage
  (reverse pt-lst); liste remise dans le sens de saisie
  )

Puisque la fonction (defun) est définie avec un "c:" on doit taper la commande SP en ligne de commande.
Il va vous être demandé de cliquer des points, rien ne se passera visuellement (à part les marques de blipmode) mais la variable pt-lst se renseigne petit à petit en concaténant chaque point cliqué pour prendre cette forme de liste à la fin de la saisie :

((13.781 11.3792 0.0) (15.6537 8.93817 0.0) (13.3196 6.95821 0.0) (10.9855 9.562 0.0) (7.59288 7.12094 0.0))

Cette liste (list) se fabrique par concaténation des listes (x y z) de coordonnées des points au fur et à mesure des choix à l'écran.
en dernière ligne la fonction (reverse) va "retourner" la liste.
L'ordre de dessin (sens de la polyligne) sera respecté en prenant le premier point de la liste comme départ, sachant que ce premier point de la liste est le dernier sélectionné à l'écran, donc en retournant la liste (list) cet ordre de dessin sera correct.

Utilisation de COMMAND

Cette méthode est parfaite pour les débutants, elle se rapproche de ce qu'on fait "à la main" ou "à la souris" dans AutoCAD en dessinant.
On lance la commande, on clique les sommets et à la fin on décide de clore (ou pas) la polyligne créée.
Dans notre cas de figure on ne va pas avoir à cliquer les points puisqu'on a pris le soin de les stocker sous forme de liste de points dans une variable précédemment.
On peut tout à fait imaginer ne pas faire de sous-routine de saisie et de faire la polyligne "à la volée", j'en mettrai une version plus loin dans cette page.

(defun poc (liste_points / item)
  (command "_.pline")
  (foreach item liste_points (command "_non" item))
  (command "_close")
  (princ)
  )
 

Que fait ce code ?
Lancement de la commande "_.pline".
Commande polyligne en langage originel du logiciel car précédé d'un "underscore" (tiret bas) et d'un point qui oblige à utiliser la vraie commande native pour ignorer le cas où elle serait redéfinie sur votre machine (redefine).
Puis parcours (avec la fonction foreach) de chaque élément de la liste (item) des points en interdisant tout accrochage aux objets par l'utilisation du "_non".
Une fois que toute la liste est parcourue, on ferme la polyligne  par l'appel de "_close"
Derrière le (defun) il n'y a pas c: donc il faut lancer la commande avec en argument le nom de la variable qui contient les points à relier ainsi :
(poc1 pt-lst)

Simple, précis, efficace, merci qui ? merci AutoLISP.

Je vous en parlais plus haut une autre façon d'utiliser (command) est de dessiner la polyligne "à l'avancée" ...
Je dépose ce code simple à comprendre :

(command "_pline")
(setq pt nil)
(while
  (if pt
    (setq pt (getpoint pt "\nPoint Suivant: "))
    (setq pt (getpoint "\nPoint de Départ "))
    )
  (command pt)
)
(command)

On est d'accord, c'est assez simple , utilisez le formulaire de contact si ce n'est pas le cas.


utilisation de ENTMAKE

(defun da:DessPoly2D (listesommets z closed)
  ; dessin de polyligne 2D depuis liste de sommmets
  (entmake
    (append
      (list
        '(0 . "LWPOLYLINE")
        '(100 . "AcDbEntity")
        '(100 . "AcDbPolyline")
        (if z (cons 38 z))
        (cons 90 (length listesommets))
	(if closed (cons 70 1) (cons 70 0))
        ;;'(70 . 0)
        )
      (mapcar '(lambda (p) (cons 10 p)) listesommets)
      ) 
    ) ;_ Fin de entmake
  ) ; fin de defun da:DessPoly2D

Cette fonction requiert trois arguments :

  1. listom qui est une liste de liste de triplets(x y z)
  2. z qui est l'élévation de la polygne à dessiner sous forme de réel (real)
  3. closed qui sera à nil ou T

Avec command si le premier point sélectionné a une valeur d'altitude la polyligne va prendre cette valeur comme "élévation", l'élévation est une valeur altimétrique appliquée à tous les sommets de la polyligne, ce n'est pas vraiment du 3D avec différentes valeurs de Z sur chaque sommets.

Avec entmake même si le premier point sélectionné a une valeur d'altitude la polyligne n'aura pas d'élévation, elles sera dessinée à un Z = 0 (zéro)

Si vous ne constatez pas ce que je viens d'écrire, je vous remercie de me le faire savoir par le formulaire de contact pour que je fasse plus de tests et corrige ma prose le cas échéant.

La routine de saisie des points va être réutilisée pour ce programme de dessin de polyligne qui utilise la fonction (entmake).
En effet on a besoin de la même forme de liste, pour mémoire : 
((x1 y1 z1) (x2 y2 z2) (x3 y3 z3) (xn yn zn)...)

Exemple de contenu de l'argument de liste des sommets :
(setq listsom
'((25.3145 3.96057 0.0) (25.4915 6.48058 0.0)(24.9122 8.93948 0.0)
(23.6288 11.1154 0.0)(21.7571 12.812 0.0)(19.466 13.8763 0.0)
(16.9622 14.2121 0.0))
)

Si on souhaite dessiner une polyligne passant par ces points il suffira de l'indiquer en premier argument, admettons qu'on veuille la dessiner à l'élévation de 32.12, ce sera le deuxième argument, et si on veut qu'elle soit fermée (close) on répondra T au troisième argument, comme ceci :

(da:desspoly2d listsom 32.12 T)

Et pour en dessiner une qui n'est pas fermée et sans élévation (Z zéro)

(da:desspoly2d listsom 0 nil)


Dessin de polyligne 3D

 

(defun da:DessPoly3D (ptlist / pt)
  ; dessin de polyligne 3D depuis liste de sommmets
  (entmake (list '(0 . "POLYLINE") '(100 . "AcDbEntity")
		 '(100 . "AcDb3dPolyline") '(70 . 8)))
  (repeat (length ptlist)
    (setq pt     (car ptlist)
          ptlist (cdr ptlist)
          )
    (entmake (list
               '(0 . "VERTEX")
               '(100 . "AcDb3dPolylineVertex")
               (cons 10 pt)
               '(70 . 32)
               )
             )
    ) ;_ repeat
  (entmake '((0 . "SEQEND")))
  ) ; fin de defun da:DessPoly3D

Avec cette fonction il va être possible, en donnant en argument unique une liste de sommets, comme dans la fonction précédente mais avec un renseignement Z différent sur chaque point, de dessiner cette-fois-ci une Polyligne3D

Exemple d'utilisation :

(da:desspoly3d listsom)



haut de page

retour aux exercices sur polylignes


29 Octobre 2019