Aller au contenu

Lignes de même longueur


LUDWIG

Messages recommandés

Je n'arrive pas à faire un lisp qui sélectionnerai les lignes de même longueur que la ligne sélectionnée. HELP

 

(defun c:ml (/ LIGNE X Y Z LONG jeu n Xn Yn Zn LONGn)

 

(setq LIGNE (entsel "Ligne de référence\n"))

;(setq X (- (cadr(assoc 11 LIGNE))(cadr(assoc 10 LIGNE))))

;(setq Y (- (caddr(assoc 11 LIGNE))(caddr(assoc 10 LIGNE))))

;(setq Z (- (cdr(caddr(assoc 11 LIGNE)))(cdr(caddr(assoc 10 LIGNE)))))

;(setq LONG sqrt (+(* X X) (* Y Y) (* Z Z)))

(setq LONG (distance '(cdr(assoc 11 LIGNE))'(cdr(assoc 10 LIGNE))))

(setq SELECTION (ssadd LIGNE))

 

(prompt "\nChoisissez la zone ou rechercher les lignes de longueur ")

(print LONG)

(prompt " :\n")

(setq jeu (ssget)'((0 . "LINE")))

 

(Foreach n Jeu

;(setq Xn (- (cadr(assoc 11 n))(cadr(assoc 10 n))))

;(setq Yn (- (caddr(assoc 11 n))(caddr(assoc 10 n))))

;(setq Zn (- (cdr(caddr(assoc 11 n)))(cdr(caddr(assoc 10 n)))))

;(setq LONGn sqrt (+(* Xn Xn) (* Yn Yn) (* Zn Zn)))

(setq LONGn (distance '(cdr(assoc 11 n))'(cdr(assoc 10 n))))

(If (= LONG LONGn)(ssadd n SELECTION))

)

Autocad 2021 - Revit 2022 - Windows 10

Lien vers le commentaire
Partager sur d’autres sites

Voilà une correction qui garde ton esprit de départ:

(defun c:ml (/ e_ref LIGNE LONG selection jeu en e_name n LONGn)
(setq LIGNE (entget (setq e_ref (car (entsel "\nLigne de référence: ")))))
(setq LONG (distance (cdr(assoc 11 LIGNE)) (cdr(assoc 10 LIGNE))))
(setq SELECTION (ssadd e_ref))
(princ (strcat "\nChoisissez la zone ou rechercher les lignes de longueur " (rtos long)))
(setq jeu (ssget '((0 . "LINE"))) n 0)
(if jeu
	(repeat (sslength jeu)
		(setq en (entget (setq e_name (ssname jeu n))) n (1+ n))
		(setq LONGn (distance (cdr(assoc 11 en)) (cdr(assoc 10 en))))
		(If (eq LONG LONGn)
			(ssadd e_name SELECTION)
		)
	)
)
(command "_.erase" selection "")
(princ)
)

Essaye de comprendre là où tu as péché, les petites erreurs sont repérables :casstet:

foreach n'etait pas adapté pour parcourir la sélection qui n'est pas une liste.

 

PS: Tu peux aussi utiliser la fonction (equal LONG LONGn x) avec x représentant l'écart accepté pour la comparaison des longueurs

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Merci bien pour cette correction si rapide !

Je vais regardé mes erreurs et en tirer des leçons...

 

Question : j'ai enlevé la commande erase à la fin de ton lisp, mais comment avoir mes éléments sélectionnés (en pointillés) prêts à "subir" une autre commande (move, rotate, erase...) ?

 

[Edité le 30/11/2004 par LUDWIG]

Autocad 2021 - Revit 2022 - Windows 10

Lien vers le commentaire
Partager sur d’autres sites

À tous,

 

En passant, puisqu'il y a des programmeurs en Arx, le inputPointManager qui permet d'allumer les objets comme le font AutoCAD Mechanical ou Architectural Desktop. Depuis AutoCAD 2000i.

 

Signature:

virtual AcEdInputPointManager * AcApDocument::inputPointManager() const;

 

Serge

 

Lien vers le commentaire
Partager sur d’autres sites

Salut

 

Comme l'a suggéré Serge, la fonction (sssetfirst) est une bonne solution.

 

Une version remaniée du programme serait :

 

(defun c:ml (/ e_ref LIGNE LONG selection jeu en e_name n LONGn)

(sssetfirst nil nil)

(setq LIGNE (entget (setq e_ref (car (entsel "\nLigne de référence: ")))))

(setq LONG (distance (cdr(assoc 11 LIGNE)) (cdr(assoc 10 LIGNE))))

(setq SELECTION (ssadd e_ref))

(princ (strcat "\nChoisissez la zone ou rechercher les lignes de longueur " (rtos long)))

(setq jeu (ssget '((0 . "LINE"))) n 0)

(if jeu

(repeat (sslength jeu)

(setq en (entget (setq e_name (ssname jeu n))) n (1+ n))

(setq LONGn (distance (cdr(assoc 11 en)) (cdr(assoc 10 en))))

(If (eq LONG LONGn)

(ssadd e_name SELECTION)

)

)

)

(sssetfirst SELECTION SELECTION)

(setq SELECTION nil jeu nil)

(princ)

)

 

Le premier sssetfirst permet de supprimer toute sélection préalable, le second présélectionne les lignes pour un traitement éventuel.

Ne pas oublier de libérer les jeux de sélection en mettant les variables à nil !

 

A+

Théodoric

 

 

 

 

[Edité le 1/12/2004 par Théodoric]

Lien vers le commentaire
Partager sur d’autres sites

Merci pour vos aides. sssetfirst, je savais pas trop comment l'utilisé donc merci pour la correction. J'ai rajouté la possibilité de tolérance. Question : à quoi ça sert de déclarer les variables après le defun ? Car j'ai vu des lisp fonctionnant bien sans cette déclaration...

 

(defun c:ml2 (/ e_ref LIGNE LONG selection jeu en e_name n LONGn tol)

(sssetfirst nil nil)

(setq

LIGNE (entget (setq e_ref (car (entsel "\nLigne de référence: ")))

)

)

(setq tol (getdist "\nSélectionnez une tolérance: "))

(setq LONG (distance (cdr (assoc 11 LIGNE)) (cdr (assoc 10 LIGNE))))

(setq SELECTION (ssadd e_ref))

(princ

(strcat "\nChoisissez la zone ou rechercher les lignes de longueur "

(rtos long)

)

)

(setq jeu (ssget '((0 . "LINE")))

n 0

)

(if jeu

(repeat (sslength jeu)

(setq en (entget (setq e_name (ssname jeu n)))

n (1+ n)

)

(setq LONGn (distance (cdr (assoc 11 en)) (cdr (assoc 10 en))))

(If (equal LONG LONGn tol)

(ssadd e_name SELECTION)

)

)

)

(sssetfirst SELECTION SELECTION)

(setq SELECTION nil

jeu nil

)

(princ)

)

 

Autocad 2021 - Revit 2022 - Windows 10

Lien vers le commentaire
Partager sur d’autres sites

Salut Ludwig,

 

La déclaration des variables après le defun permet de limiter leur durée de vie à celle de la fonction. En clair, elles n'existent que pendant l'exécution de la fonction et la mémoire qu'elles occupent est automatiquement libérée à la fin de celle-ci.

 

Si tu ne les déclare pas de cette façon, elles seront toujours accessibles et utilisables dans AutoCAD, et ce, même après la fin de la fonction. Cette possibilité est toutefois intéressante lorsque l'on désire partager des variables entre plusieurs programmes.

 

A+

Lien vers le commentaire
Partager sur d’autres sites

Ludwig,

 

Rien à rajouter sur la déclaration des variables, Théodoric a bien fait cela. A savoir que la déclaration est soit "globale", soit "locale" (Une discussion existe a ce propos sur ce sujet dans ce forum)

 

Par contre une remarque sur l'emploi des fonctions (get......)

Je te conseille vivement d'utiliser la fonction (initget [bit de controle]) avant leur appel.

En effet si l'utilisateur n'entre pas une valeur pour la tolérance, le programme va être arrêté. (pas cool) :mad:

 

Voici par exemple ce que tu peux faire:

(initget (+ 1 4))
(setq tol (getdist "\nSélectionnez une tolérance: "))

 

Ou mieux encore:


(initget 4)
(setq tol (getdist "\nSélectionnez une tolérance:<0.0> "))
(if (not tol) (setq tol 0.0))

De cette manière l'utilisateur peut simplement valider la tolérance à 0.0 par défaut.

ET si la variable n'est pas déclarée en globale, tu pourrais envisager de récupérer sa valeur d'une utilisation antérieure pour la reproposer par défaut.

Je te laisse chercher cette manière, si elle t'interesse.

 

Bonne continuation

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

(princ (strcat "\nChoisissez la zone ou rechercher les lignes de longueur " (rtos long)))

(setq jeu (ssget '((0 . "LINE"))) n 0)

 

Je souhaiterais que cette invite soit du style "Choisissez la zone ou rechercher les lignes de longueur XXX ". S'il appuie direct sur entrée, la sélection est "_all" (ssget "X").

Autocad 2021 - Revit 2022 - Windows 10

Lien vers le commentaire
Partager sur d’autres sites

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é