Aller au contenu

Messages recommandés

Posté(e)

Bonjour

 

Je cherche à récupérer sous forme de liste tous les points d'une polyligne sélectionnée.

 

setq courb (entget(car(entsel)))

pts (cons(assoc 10 courb))pts)

 

mais je ne récupère que mon premier point. Y a t il un while quelquechose à ajouter ?

Merci

Posté(e)

Salut,

 

Tu trouveras dans cette réponse plusieurs façon d'implémenter une fonction nommée massoc (pour multiple assoc).

La plus couramment vue est celle utilisant vl-remove-if-not, c'est la plus concise.

Ma préférée est la dernière (fonction récursive), c'est aussi, d'après mes tests, la plus rapide.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Merci. Seulement j'ai un problème... ça fonctionne bien sur une polyligne 2d mais pas sur une 3d. Est-ce normal ?

Je n'arrive pas non plus à trouver où se stocke ma liste ?

J'aimerai aussi enlver le 10 mais mon cdr ne prend rien...

dur dur !

 

(defun c:calroz(/)

(setq courb (entget(car(entsel))))

l_pts (cons(cdr(massoc 10 courb)l_pts))

)

 

(defun massoc (key alst)

(if (setq alst (member (assoc key alst) alst))

(cons (car alst) (massoc key (cdr alst)))

)

)

Posté(e)

Oui c'est normal.

Une "polyligne 2d", en fait une polyligne "optimisée" ou "allégée" (LightWeightPolyline) est une entité dite simple alors qu'une polyligne 3d (comme les anciennes polylignes 2d et les maillages) est une entité dite complexe parcque constituées de sous entités : les sommets (VERTEX).

Pour obtenir les sommets d'une polyligne 3d, avec AutoLISP il faut parcourir les entités suivant l'entité polyligne avec entnext tant que ces entités sont de type VERTEX ou utiliser la fonction vlax-curve-getPointAtParam avec des paramètre entiers ou encore, en Visual LISP, en reconstituant une liste de points avec la liste des coordonnées aplaties retournés par vla-get-Coordinates.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

C'est diabolique ! :huh: Trop pour moi...

Je vais continuer avec des poly 2d, j'ai trouvé une parade...

 

J'ai beau inspecter mes variables, je ne retrouve pas dans laquelle la liste se met. :/

Posté(e)
J'aimerai aussi enlver le 10 mais mon cdr ne prend rien...

Tu peux modifier massoc pour qu'elle ne retourne que les points (sans le 10) en remplaçant :

(cons (car alst) (massoc key (cdr alst)))

par :

(cons (cdr (car alst)) (massoc key (cdr alst)))

ou, mieux

(cons (cdar alst) (massoc key (cdr alst)))

 

(defun massoc (key alst)
 (if (setq alst (member (assoc key alst) alst))
   (cons (cdar alst) (massoc key (cdr alst)))
 )
)

 

 

Pour les sommets des polylignes 3d.

 

En "pur AutolISP" avec les listes DXF :

(defun getVertices (poly3d / elst pts)
 (setq elst (entget (entnext poly3d)))
 (while (= (cdr (assoc 0 elst)) "VERTEX")
   (setq pts  (cons (cdr (assoc 10 elst)) pts)
         elst (entget (entnext (cdr (assoc -1 elst))))
   )
 )
 (reverse pts)
)

 

avec vlax-curve (fonctionne pour tout type de polyligne)

(defun getVertices (poly3d / n pts)
 (vl-load-com)
 (repeat (setq n (1+ (fix (vlax-curve-getEndParam poly3d))))
   (setq pts (cons (vlax-curve-getPointAtParam poly3d (setq n (1- n))) pts))
 )
)

 

avec Visual LISP (poly3d doit être de type vla-object)

(defun getVertices (poly3d / coords pts)
 (vl-load-com)
 (setq coords (vlax-get poly3d 'Coordinates))
 (while coords
   (setq pts    (cons (list (car coords) (cadr coords) (caddr coords)) pts)
         coords (cdddr coords)
   )
 )
 (reverse pts)
)

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Dans :

 

(defun getVertices (poly3d / elst pts)

(setq elst (entget (entnext poly3d)))

(while (= (cdr (assoc 0 elst)) "VERTEX")

(setq pts (cons (cdr (assoc 10 elst)) pts)

elst (entget (entnext (cdr (assoc -1 elst))))

)

)

(reverse pts)

)

 

j'ai modifié :

 

defun getVertices en defun c:getVertices et je n'ai que ça dans mon programme.

 

(setq elst (entget (entnext poly3d))) en

 

(setq poly3d (entsel)))

(setq elst (entget (car (poly3d)))

 

Au lancement, j'ai "(<Nom d'entité: 7ffffb45d50> (985264.0 6.49177e+006 0.0))"

 

Ensuite,

 

Si la sélection affiche la liste créée est la même que pour une poly 2d, dans quelle variable se stocke les données ?

Je souhaite récupérer cette liste pour calculer des vecteurs et angles.

Posté(e)

La fonction getVertices requiert un argument (voir ce sujet et/ou le chapitre 6 de Introduction à AutoLISP). Il est donc parfaitement inutile de la préfixer avec 'c:', on fait ça pour pouvoir appeler directement une fonction LISP comme une commande et dans ce cas la fonction ne doit pas requérir d'argument.

 

Exemple d'utilisation :

(setq poly3d (car (entsel)))
(setq points (getVertices poly3d))

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e) (modifié)

J'ai avancé sur mon lisp mais j'ai un problème que je n'explique pas : (pour info, je cherche à calculer l'angulation des coudes de ma canalisation pour de la réalisation sur mesure, si le lisp peut servir à d'autres qui sont curieux mais ne "lisp" pas, une fois abouti...)

 

J'ai testé mon programme sur une polyligne assez simple (une dizaine de points) et le programme marchait.

J'ai comparé mes données avec un tableau excel et les résultats étaient cohérents.

 

Je l'ai testé sur une polyligne bien plus complexe, et là, mes résultats diffèrent.

 

En lien ma polyligne 3d , mon fichier excel avec les angles.

Autre problème que je ne sais pas traiter : en fin de lisp je retourne ma liste pour que les points soient dans l'ordre croissant. Mon problème est que dans mon résultat affiché j'ai ma liste dans un ordre décroissant et à la suite ma liste retrounée. Comment n'avoir que ma liste retournée ?

 

angle.zip

 

ci dessous mon lisp.

 

(defun c:roz ()

 (setq poly3d (car (entsel)))
 (setq points (getVertices poly3d))
 (setq nb_pts (length points))
 (calan)
)

(defun getVertices (poly3d / elst pts)
 (setq elst (entget (entnext poly3d)))
 (while (= (cdr (assoc 0 elst)) "VERTEX")
   (setq pts  (cons (cdr (assoc 10 elst)) pts)
         elst (entget (entnext (cdr (assoc -1 elst))))
   )
 )
 (reverse pts)
)

(defun ACOS (num)
 (cond
   ((equal num 1 1e-9) 0.0)
   ((equal num -1 1e-9) pi)
   ((< -1 num 1)
    (atan (sqrt (- 1 (expt num 2))) num)
   )
 )
)


(defun calan ()

 (setq i 0) ;compteur à 0

 (repeat (- nb_pts 2)

   (setq x_va         (- (car (nth (+ i 1) points)) (car (nth i points)))
         y_va         (- (cadr (nth (+ i 1) points)) (cadr (nth i points)))
         z_va         (- (caddr (nth (+ i 1) points)) (caddr (nth i points)))
         x_vb         (- (car (nth (+ i 2) points)) (car (nth (+ 1 i) points)))
         y_vb         (- (cadr (nth (+ i 2) points)) (cadr (nth (+ 1 i) points)))
         z_vb         (- (caddr (nth (+ i 2) points)) (caddr (nth (+ 1 i) points)))
         mod_a        (sqrt (+ (* x_va x_va) (* y_va y_va) (* z_va z_va)))
         mod_b        (sqrt (+ (* x_vb x_vb) (* y_vb y_vb) (* z_vb z_vb)))
         scl_ab       (+ (* x_va x_vb) (* y_va y_vb) (* z_va z_vb))
         cos_angl_ab  (/ scl_ab (* mod_a mod_B))
         angl_ab      (/ (* 180 (acos cos_angl_ab)) pi)
         paf          (+ 1 i)
         cor_paf      (nth i points)
         list_pt_angl (list paf cor_paf angl_ab)
         list_cal     (reverse (cons list_pt_angl list_cal))
         i            (+ 1 i)
   )
 )
 strcat
 list_cal
)

Modifié par (gile)
Formatage du code et ajout des balises bbcode
Posté(e)

Salut,

 

Je ne comprends pas bien toutes tes demandes.

Essaye de t'exprimer plus clairement ce que tu veux faire, c'est la base, si tu poses clairement le problème, tu as presque fait la moitié du boulot, il reste juste à traduire en code.

 

Tu devrais déclarer tes variables, ça t'éviterait des surprises...

 

PS : pense à utiliser les balises bbcode quand tu postes du code (bouton : ).

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Ce que je fais :

 

- Je sélectionne ma polyligne 3d

- Je liste les coordonnées de mes points

- Je calcule le produit scalaire de ma entre mes vecteurs PT1-2 PT2-3 pour avoir mon angle entre les segments.

 

- Je créé une liste de point avec (numero de point du profil (coordonnées du point ) angle au niveau du point)

 

J'ai pensé ne pas déclarer mes variables car pour les vérifier je me servais du !variable sous autocad pour me vérifier.

 

Ensuite, ne sachant pas faire d'export vers excel, je copie mon résultat affiché sous excel,

je le transforme pour avoir en colonne A mes points, en B mes coordonnées, en C mon angle.

 

Pour les balises, je ne connais pas encore...

Posté(e)

Utilisation des balises bbcodes :

[code] ici le code [/code]

donne :

 ici  le code 

Accessible via l'icône :

http://gilecad.azurewebsites.net/Resources/bbcode.png

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Quand tu fais :

(setq [...]
 list_cal (reverse (cons list_pt_angl list_cal))
[...])

tu inverses la liste à chaque fois que tu ajoutes un élément.

 

Essaye :

(setq l nil i 0) 
(repeat 5 (setq l (reverse (cons i l)) i (1+ i)))
l

et l vaudra successivement : (0) -> (0 1) -> (1 0 2) -> (2 0 1 3) -> (3 1 0 2 4)

 

Il faut que tu construises ta liste et que tu ne l'inverse qu'une fois la liste terminée.

(setq l nil i 0) 
(repeat 5 (setq l (cons i l) i (1+ i))) 
(reverse l)

là l vaut (0 1 2 3 4)

 

Pour ce qui concerne l'export vers Excel, je ne saurais que trop te recommander de créer un fichier CSV ce qui est relativement simple en LISP.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Bonjour,

 

je suis tombé sur ça grâce à Google : ICI

 

C'est pas tout jeune, mais il y a beaucoup de chose basique y compris l'écriture d'un fichier texte à partir des coordonnées d'objets points dans AutoCAD et à la fin, il y a les pages scannées du manuel V12 avec les fonctions décrites en français.

 

Olivier

Posté(e)

C'est vraiment basique et un peu ancien cette doc. Si tu n'as pas l'intention d'aller beaucoup plus loin en programmation, ça suffira, sinon il faudra te pencher très sérieusement sur le bouquin de Gilles et comme il l'a ajouté, il est INDISPENSABLE de savoir lire l'anglais et à peu près l'écrire (pas forcément le parler couramment ou le comprendre à l'oral, même si c'est toujours mieux) sinon ça te bloquera très très vite dans l'apprentissage de la programmation.

 

Olivier

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité