LUDWIG Posté(e) le 30 novembre 2004 Posté(e) le 30 novembre 2004 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
bonuscad Posté(e) le 30 novembre 2004 Posté(e) le 30 novembre 2004 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
LUDWIG Posté(e) le 30 novembre 2004 Auteur Posté(e) le 30 novembre 2004 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
Serge Posté(e) le 30 novembre 2004 Posté(e) le 30 novembre 2004 Ludwig, Comme l'a dit Bruno, tu a vraiement intérêt à utiliser equal avec un écart admissible d,au moins 1e-8. Pour la dernière question, regarde du coté de sssetfirst Serge
didier Posté(e) le 30 novembre 2004 Posté(e) le 30 novembre 2004 hello Ludwigsi tu veux mettre en SURBRILLANCE,la syntaxe c'est :(setq ent (car(entsel"\nChoix de l'objet\n")))(redraw ent 3)bonne continuation,amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
Serge Posté(e) le 30 novembre 2004 Posté(e) le 30 novembre 2004 Didier, C'est jouer avec les mots. Cela ne permettra pas d'utiliser les poignées. De plus, il faudra un (redraw ent 4) ou un regen pour enlever cette surbrillance. Serge
Serge Posté(e) le 30 novembre 2004 Posté(e) le 30 novembre 2004 À 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
Théodoric Posté(e) le 1 décembre 2004 Posté(e) le 1 décembre 2004 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]
LUDWIG Posté(e) le 2 décembre 2004 Auteur Posté(e) le 2 décembre 2004 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
Théodoric Posté(e) le 2 décembre 2004 Posté(e) le 2 décembre 2004 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+
bonuscad Posté(e) le 2 décembre 2004 Posté(e) le 2 décembre 2004 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
LUDWIG Posté(e) le 2 décembre 2004 Auteur Posté(e) le 2 décembre 2004 ah ouais "initget" c'est sympa, moi qui pensait mettre quantitié de "if" derrière mon "get" pour contrôler la saisie utilisateur... Autocad 2021 - Revit 2022 - Windows 10
LUDWIG Posté(e) le 2 décembre 2004 Auteur Posté(e) le 2 décembre 2004 (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
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant