Aller au contenu

Sélection de plusieurs polyligne, arc, spline + execution lisp


Messages recommandés

Posté(e)

Bonjour :)

 

Grâce à Didier et un lisp trouvé sur le net, j'ai réussi à faire le code suivant qui me permet de tracer une ligne droite entre le point de départ et d'arrivée d'une polyligne, arc ou spline et de noter ça longueur au centre de la ligne :

 

(defun c:Topher (/ pt1 pt2 dep ang obj pdep pfin)

;Création du calque si il n'existe pas pour séparer les infos
(command "calque" "E" "@_Lg_Poly" "")

;Code pour la Mediatrice
(vl-load-com)
(setq obj (vlax-ename->vla-object (car (entsel "objet")))
	  pdep (vlax-curve-getstartpoint Obj)
      pfin (vlax-curve-getendpoint Obj)
	)

;Code pour le calcul de la longueur ligne polyligne
(vl-load-com)
(setq obj (vlax-ename->vla-object (car (entsel "objet")))
	  pdep (vlax-curve-getstartpoint Obj)
      pfin (vlax-curve-getendpoint Obj)
	)

;Trace une ligne virtuelle en rouge
;(grdraw pdep pfin 1)

;Trace la ligne physique
(command "ligne" pdep  pfin "")

;Calcul longueur ligne
(setq LL (rtos (distance pdep pfin)))

;Cherche la médiatrice de la ligne pour placer la distance au milieu de la ligne
 (if (equal (caddr pdep) (caddr pfin) 1e-009)
   (progn
     (setq dep	 (mapcar (function (lambda (x1 x2) (/ (+ x1 x2) 2))) pdep pfin)
    ang (+ (angle dep pdep) (/ pi 2))
     )

     (vl-cmdf "texte" "_non" dep (strcat "<" (angtos ang (getvar "AUNITS") 15)) 20 "" LL)
   )
   (prompt
     "Les points ne sont pas dans un plan parallèle au plan du SCU courant."
   )
 )
 (princ)
)

0
Recherche

 

J'imagine qu'il y a plus simple pour trouver le milieu de ma ligne et placer la valeur de la longueur mais bon se n'est pas mon soucis actuel.

 

Maintenant j'aimerais pouvoir sélectionner plusieurs polyligne, arc ou spline en une fois et exécuter mon lisp automatiquement (pour éviter de relancer mon lisp sur mes polylignes, arc spline une par une).

 

Pour info, toutes mes polylignes, arc spline sont sur le même calque, du coup j'ai trouvé le lisp de Gile qui selectionne tous :

 

;; Sélection par calque
(defun c:ssl (/ ss ent)
 (and
   (or
     (and
(setq ss (cadr (ssgetfirst)))
(= 1 (sslength ss))
(setq ent (ssname ss 0))
     )
     (and
(sssetfirst nil nil)
(setq ent (car (entsel)))
     )
   )
   (sssetfirst nil (ssget "_X" (list (assoc 8 (entget ent)))))
 )
 (princ)
)

 

Mais je n'arrive pas à l'intégrer à mon code.

 

Merci de votre aide :)

Posté(e)

Salut,

 

Il me semble qu'avant d'essayer d'intégrer une routine qui ne fait que sélectionner tous les objets sur un calque, il faut comprendre comment on traite un jeu de sélection.

 

Pour essayer de rendre les choses plus claires, on peut extraire la fonction qui traite une entité de ton code.

 

Il s'agit de faire une fonction LISP qui requiert un argument, à savoir une entité, et exécute la procédure pour cette entité.

J'ai simplifié un peu le code : les fonctions vlax-curve* acceptent aussi bien un ename qu'un vla-object donc inutile de faire la conversion avec vlax-ename->vla-object.

J'ai internationalisé les noms de commandes.

J'ai ajouté une correction de l'angle pour que le texte (désormais aligné avec la ligne) soit toujours dans le sens de la lecture.

 

(defun topher (ent / pdep pfin LL dep ang perp)
 ;; point de départ
 (setq pdep (vlax-curve-getStartPoint ent))

 ;; point de fin
 (setq pfin (vlax-curve-getEndPoint ent))

 ;; contrôles de validité des points
 (if (equal pdep pfin 1e-9)
   (prompt "\nLes points sont de départ et de fin sont confondus.")
   (if (not (equal (caddr pdep) (caddr pfin) 1e-009))
     (prompt "Les points ne sont pas dans un plan parallèle au plan du SCU courant.")
     ;; création de la ligne et du texte
     (progn
       (setq LL  (rtos (distance pdep pfin))
             dep (mapcar (function (lambda (x1 x2) (/ (+ x1 x2) 2))) pdep pfin)
             ang (angle pdep pfin)
       )
       ;; correction de l'angle pour être dans le sens de la lecture
       (if (< (* pi 0.5) ang (* pi 1.5))
         (setq ang (+ ang pi))
       )
       (command "_.line" pdep pfin "")
       (command "_.text"
                "_non"
                (polar dep (+ ang (* pi 0.5)) 15)
                20
                (angtos ang (getvar "AUNITS") 15)
                LL
       )
     )
   )
 )
)

 

Maintenant, on peut utiliser cette fonction comme n'importe quelle autre fonction LISP native (note l'absence du préfixe "c:") en lui passant une entité comme argument.

 

L'équivalent de ta commande devient :

(defun c:topher1 (/ ent)
 ;; si l'utilisateur sélectionne une entité...
 (if (setq ent (car (entsel "\nSélectionnez un arc, une polyligne ou une spline: ")))
   (progn
     ;; ...on crée le calque...
     (command "_.layer" "_make" "@_Lg_Poly" "")
     ;; ...et on traite l'entité en la passant comme argument à la fonction topher
     (topher ent)
   )
 )
 (princ)
)

 

Pour traiter en une seule fois plusieurs entités sélectionnées, on commence par faire un jeu de sélection.

On peut utiliser un filtre de sélection pour ne retenir que certains types d'entités (arcs, polylignes, splines). On pourrait aussi ajouter au jeu de sélection un ou plusieurs calques.

Il faut ensuite parcourir le jeu de sélection pour récupérer chacune des entités qu'il contient et la passer à la fonction topher

 

(defun c:topher2 (/ selSet i)
 ;; si l'utilisateur sélectionne des entités
 (if (setq selSet (ssget '((0 . "ARC,LWPOLYLINE,SPLINE"))))
   (progn
     ;; on initialise un index à 0
     (setq i 0)
     ;; on établit le calque
     (command "_.layer" "_make" "@_Lg_Poly" "")
     ;; tant que le jeu de sélection contient une entité à l'index
     (while (setq ent (ssname selSet i))
       ;; on traite l'entité en la passant comme argument à la fonction topher
       (topher ent)
       ;; on incrémente l'index pour passer à l'entité suivante
       (setq i (1+ i))
     )
   )
 )
 (princ)
)

 

Si tu veux sélectionner tous les arcs, polylignes et splines sur une calque spécifique, tu n'as qu'à remplacer la ligne :

(if (setq selSet (ssget '((0 . "ARC,LWPOLYLINE,SPLINE"))))

par :

(if (setq selSet (ssget "_X" '((0 . "ARC,LWPOLYLINE,SPLINE") (8 . "NomDuCalque")))

Comme tu peux le voir, on n'a pas eu à intégrer la routine SSL.

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

Posté(e)

Bonjour Gile,

 

Tous d'abord merci à toi, mon problème est résolu laugh.gif !

 

Pour ce qui est :

"Il me semble qu'avant d'essayer d'intégrer une routine qui ne fait que sélectionner tous les objets sur un calque, il faut comprendre comment on traite un jeu de sélection."

 

Je suis d'accord avec toi, le fait est que je n'ai AUCUNE base en lisp :( .

Je comprends certains arguments à taper pour avoir certains résultats (création de calque ou mise en place de texte) mais c'est tous !

J’avoue ne pas y mettre beaucoup de bonne volonté :P ,je trouve ce langage très compliqué :wacko: .

 

En plus on ne trouve pas énormément de lisps avec commentaires à chaque lignes, alors que j'ai "appris" le VBA en modifiant des bouts de codes (avec énormément de commentaires) et en utilisant l'enregistreur de macro (chose non disponible à ma connaissance sur Autocad).

 

Je me demande même où vous avez appris ce langage !

 

En tous cas, forcé de constater que ce forum est très actif, réactif et qu'on y trouve bon nombre d'infos et de conseils quand on est bloqué.

 

Encore merci à vous !

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • 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é