MAC Posté(e) le 14 mai 2005 Posté(e) le 14 mai 2005 Bonjour!voici un petit lisp (qui m'as donné beaucoup de peine) qui me permet un double décalage (de chaque coté) sur une ligne ou polyligne._Est-ce qu'il y a un moyen de faire mieux et plus simple(moins d'appel a "progn" dans la fonction "IF")? _Sinon j'ai un probleme lors de l'utilisation de ce lisp : si le zoom dans la fenetre est trop eloigné le double décalage s'effectue mal, le dernier décalage se fait en superposition de la ligne selectionnée.L'autre est bon. si je zoom suffisament sur l'objet à décaler le résultat est bon. merci aux cadxpiens de la branche lispienne! (defun c:dcllpp (/ Vdist entité1 pt1 pt2 entitépoints anglepl PtGauche PtDroite) (setq Vdist (getdist "\n distance de decalage?:")) (setq entité1 (entget (car (entsel "Selectionner la ligne ou la polyligne:")) ) ) (if (eq (cdr (assoc 0 entité1)) "LINE");;; determine si l'objet est ligne ou polyligne (progn (Setq pt1 (cdr (assoc 10 entité1))) (setq pt2 (cdr (assoc 11 entité1))) ) (progn (setq entitépoints (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) entité1) ) ) (progn (progn (setq pt1 (car entitépoints))) (progn (setq pt2 (cadr entitépoints))) ) ) ) (setq anglepl (angle Pt1 Pt2)) (setq PtGauche (polar pt1 (+ anglepl (/ pi 2)) vdist)) (setq PtDroite (polar Pt1 (- anglepl (/ pi 2)) vdist)) (command "_offset" Vdist pt1 PtGauche "" ) (command "_offset" Vdist Pt1 PtDroite "" ) (princ))
didier Posté(e) le 14 mai 2005 Posté(e) le 14 mai 2005 Bonjour,je sais bien que tu postes dans le forum Lisp,mais puisque tu débutes, pourquoi ne pas se mettre au VBA ?voici ce que tu souhaites réaliser en VBA :Sub DoubleDecal()Dim Objet As AcadEntityThisDrawing.Utility.GetEntity Objet, basePnt, "Select an object"ObjetDecal1 = Objet.Offset(0.25)ObjetDecal2 = Objet.Offset(-0.25)End Subsimple, propre, efficace ...amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
gile Posté(e) le 14 mai 2005 Posté(e) le 14 mai 2005 Salut, mac Quelques petites remarques vite fait (si tu veux continuer en LISP, bien sûr !) : Tu peux effectivement supprimer tous "progn" de ta fonction (progn (Setq pt1 (cdr (assoc 10 entité1)))(setq pt2 (cdr (assoc 11 entité1)))) peut s'écrire : (setq pt1 (cdr (assoc 10 entité1)) pt2 (cdr (assoc 11 entité1)) ) de même pour les autres "progn". Pour ce qui est du zoom, c'est probablement un problème avec l'accochage aux objets. Essaye en changeant la valeur de "osmode" avant les "command" (setq init_os (getvar "osmode")) (setvar "osmode" 0) (command "_offset" .....) (setvar "osmode" init_os) Autre remarque, ton "if" pourrait être avantageusement remplacé par un "cond" ce qui te permettrait d'envisger d'autres conditionnelles, donc de décaler d'autres entités (cercles, arcs, etc.) et de renvoyer un message d'erreur si l'entité selectionnée ne peut être décalée. [Edité le 14/5/2005 par gile]
MAC Posté(e) le 14 mai 2005 Auteur Posté(e) le 14 mai 2005 Y'a toujours de l'activité sur ce forum.c'est formidable! Didier:ça fait un moment que je désire commencer en VBA mais je dois déja glaner de la doc pour débuter et ce concenter sur une seule chose permet de progresser plus vite et le lisp me paraitplus facile a comprendre.Est ce que le VBA est plus puissant?Ton exemple est parlant et faut que je vois ça. Gile:"osmode" a 0 n'a pas corrigé le probleme."cond" ? voilà une nouvelle fonction à découvrir et comprendre. A+
gile Posté(e) le 14 mai 2005 Posté(e) le 14 mai 2005 Il semble que le problème soit plutôt dû au choix de pt1 pour les "polar", essaye avec pt0 (milieu de pt1 et pt2), chez moi çà semble marcher : (setq anglepl (angle Pt1 Pt2) pt0 (mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2)) pt1 pt2) PtGauche (polar pt0 (+ anglepl (/ pi 2)) 1) PtDroite (polar Pt0 (- anglepl (/ pi 2)) 1) v1 (getvar "osmode") ) [Edité le 14/5/2005 par gile]
bonuscad Posté(e) le 14 mai 2005 Posté(e) le 14 mai 2005 Tu devrais regarder le fil de Tramber au sujet de sens du décalage Bien que je n'ai pus répondre à son problème, il ma permis de faire une routine très courte de double décalage. Merci Tramber ;) Celle ci est en VL et utilise activeX. Je n'ai pas fait de controle sur l'entité sélectionné (à savoir si elle supporte le décalage) mais c'est une autre méthode interessante. PS: Conseil; évite d'utiliser des caractères accentué pour les noms de variable que tu utilises, suivant les page de code utilisées dans l'environnement de l'OS cela risque de poser des problèmes. Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
bonuscad Posté(e) le 14 mai 2005 Posté(e) le 14 mai 2005 Une suggestion pour ton développement; la commande décaler lorsqu'elle demande un objet, tu peut fournir un point de sélection comme tu l'as fait qui pointera sur l'entité. Cette façon de faire peut être influencé par le mode d'accrochage objet (OSMODE) mais aussi par la taille d'ouverture de la cible de sélection (APERTURE) en effet si une entité plus récente dans la base de donnée que l'entité sélectionné passe dans la cible, elle risque d'être sélectionnée.Décaler accepte aussi le nom de l'entité tel que retourné par (entsel), et la tu seras sur que c'est bien la bonne entité qui sera soumis à la commande.ex:(setq ENT (entsel))(command "_.offset" valeur_decalage ENT ........) Je pense qu'en procédant comme ceci tu auras moins de soucis. On progresse, on progresse ....... Ciao Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
MAC Posté(e) le 14 mai 2005 Auteur Posté(e) le 14 mai 2005 Bien vu! c'est la taille d 'ouverture de la cible de selection qui est responsable de mon problème.Si la cible est plus large que la distance totale apparente des 2 lignes décalées = bug.Donc selection de l'entité par son nom pour les petits décalages vus des étoiles. Bonuscad:ta routine est en effet plus compacte mais elle m échappe un peut .J'ai encore des progrets à faire car je ne connais pas encore activeX dans le cadre d'autolisp. Merci à tous pour vos conseils. On progresse...
MAC Posté(e) le 15 mai 2005 Auteur Posté(e) le 15 mai 2005 bonuscad:ta routine c'est de la balle!.fonctionne avec tous les objets. Pour l'exercice je termine ce que j'ai commencé.(c'est bon pour les neurones!)_j'ai supprimé tous les "progn". (bien vu gile! maintenant c'est plus léger)_j'ai inclu la possibilité de ne pas entrer la valeur a chaque appel de la commande. (comment fait'on pour afficher la valeur courante "offsetdist" sur le message de la ligne de commande qui demande de saisir la distance.)_la selection de l'entité se fait par son nom dans la commande "_offset". à voir:_afficher la valeur par défault d' "offsetdist" au moment de la saisie de la distance.comment?_je peut intégrer l'effacement de l'objet source._voir ce que je peut faire avec "cond" afin de décaler tous les types d'objets. ____________________________________________________________________________(defun c:dcllpp (/ vdist entite1 pt1 pt2 entitepoints anglepl PtGauche PtDroite)(if (setq Vdist (getdist "\n Distance de décalage ou valider la précédente ?:")) (setvar "offsetdist" Vdist) (setq Vdist (getvar "offsetdist")) ) (setq entité1 (entget (car (setq select-ent (entsel "Selectionner la ligne ou la polyligne:"))) ) ) (if (eq (cdr (assoc 0 entite1)) "LINE");;; determine si l'objet est ligne ou polyligne (Setq pt1 (cdr (assoc 10 entite1)) pt2 (cdr (assoc 11 entite1))) (setq entitepoints (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) entité1) ) pt1 (car entitepoints) pt2 (cadr entitepoints)) ) (setq anglepl (angle Pt1 Pt2)) (setq PtGauche (polar Pt1 (+ anglepl (/ pi 2)) vdist)) (setq PtDroite (polar Pt1 (- anglepl (/ pi 2)) vdist)) (command "_offset" "" select-ent PtGauche "" ) (command "_offset" "" select-ent PtDroite "" ) (princ))___________________________________________________________________________
gile Posté(e) le 15 mai 2005 Posté(e) le 15 mai 2005 Pour continuer l'exercice : (comment fait'on pour afficher la valeur courante "offsetdist" sur le message de la ligne de commande qui demande de saisir la distance.) Tu peux faire un truc du genre : (initget 6) (if (setq Vdist (getdist (strcat "\nDistance de décalage <" (rtos (getvar "offsetdist")) "> :" ) ) ) (setvar "offsetdist" Vdist) (setq Vdist (getvar "offsetdist")) ) Le (initget 6) empèche l'entrée de zéro ou d'un nombre négatif mais permet "enter". Sinon regarde quand même ce que j'ai dit plus haut pour le côté de décalage, c'est pas un problème de LISP mais de géométrie : si pt1 (qui est un sommet de la polyligne) est situé sur un sommet en angle droit un des points spécifié pour le décalage peut appartenir à la polyligne et AutoCAD ne saura plus de quel côté décaler. D'où l'intérêt du point pt0 milieu de pt1 pt2 (essaye avec un rectangle) Et au risque de paraître tétu, je pense que c'est une bonne habitude que de mettre osmode à 0 avant de créer une entité de dessin avec (command) pour assurer une plus grande fiabilité. Pour effacer l'entité source (command "_erase" (car select_ent) "") ou plus "classe" (entdel (car select_ent)) A plus. [Edité le 15/5/2005 par gile]
MAC Posté(e) le 15 mai 2005 Auteur Posté(e) le 15 mai 2005 oui! je pense que c'est plus prudent de mettre "osmode" à 0.Je vais voir maintenant la modif avec pt0 .les autres modifs fonctionnent. merci pour tous ces conseils.A+
tiboulen Posté(e) le 16 mai 2005 Posté(e) le 16 mai 2005 bonjourje mets toujours osmode à 0 avant de creer un prog de creation d' objetPour tester si c'est bien une polyligne (je ne connais pas vba et travaille sur toolkit + autocadlt snif..)j' utilise :(while (or (null (setq pol0 (entget (car (entsel "\Designer une polyligne"))))) (/= (cdr (assoc 0 pol0)) "LWPOLYLINE"))(prompt "\nCe n'est pas une Polyligne\n"))meme principe pour une lignesalut
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