Aller au contenu

LISP - Création d'une certaine polyligne par décalage


Messages recommandés

Posté(e)

Bonjour,

 

j'essaye de faire un peu de programmation quand le temps me le permet, en utilisant cette formidable usine à gaz qu'est le monde du LISP, et j'avoue avoir beaucoup de mal.

J'ai un peu potassé un tuto trouvé sur le net : http://gilecad.azurewebsites.net/Tutorials/Introduction_a_AutoLISP.pdf

mais j'avoue ne pas tout saisir. Je ne suis pas familier à la programmation en général et même si je comprends l'ossature globale d'un lisp, la pratique est une autre paire de manches...

 

Bref, ce que je souhaite faire, c'est une commande qui :

- demande de séléctionner une polyligne

- la décale du côté que l'on choisit (comme lors de l'utilisation manuelle de la commande quoi) à une certaine valeur figée (que l'on ne renseigne pas donc), par exemple 0,1

- Que la polyligne créée en décalage ait une largeur globale figée elle aussi (exemple 0,04).

 

L'idée, si quelqu'un est assez aimable pour consacrer un peu de temps (je pense que cette chaîne de commande est assez simple en soit pour quelqu'un d'expérimenté), c'est que je comprenne là ou je me plante et aussi que je puisse poser des questions si jamais je ne saisis pas quelque chose.

 

Je vous en remercie d'avance !

 

Baptiste.

Posté(e)

j'ai un truc en tête, mais débutant moi aussi, ça me prendra des plombes..De plus enchainer brutalement les charrettes sous la clim du boulot et l'été caniculaire provençal ne va pas m'aider à être productif en soirée. Néant moins je vais être (ou ne pas être ?) confronté à des problèmes similaires sous peu.

Je cherche aussi des pistes.

Le débat (command ou (command-s me fait regarder comment créer une polyligne décalée avec (entmake.

 

mais ça à l'air balaise... d'autant que je veux le faire en 2d puis le projeter en 3d en fonction d'une pente... y inclure l'épaisseur et un pas fixe devrai être facile au passage...mais l'accouchement sera sans doute long...

Posté(e)

slt

 

voici un petit code qui devrait te soulager de quelque clic.

 

je me suis pas mal inspirer de CT de (gile) pour la partie re définition des variables globales. soit tu sélectionne une poly puis espace pour lancer le bouzin, soit tu fait espace pour changer un paramètre.

 

dans le code sont définis 2 paramètres par défaut que tu peu changer en "dur" si ils ne te conviennent pas...

 

(defun c:dec-fix (/ poly choix lst-poly pt ep0 ep1 tmp )

 ;;initialisation des variables globales si elle ne sont pas afféctées
 (if (/= (type *offset*) 'REAL)
(setq *offset* 1.0) ; changer ici la valeur du décalage par défaut
 )
 (if (/= (type *ep*) 'REAL)
(setq *ep* 0.1) ; changer ici la valeur de l'épaisseur par défaut de la polyligne décalée
 )

 (while
(and
 	(princ (strcat "\nDécalage actuel = "
	 	(rtos *offset*)
	 	"\nEpaisseur actuelle = "
	 	(rtos *ep*)
	 	" sélectionner une polyligne ou espace pour changer un paramètre"
 	)
 	)
 	(not (setq poly  (ssget )))
) ;_ Fin de and

	(initget 1 "Decalage Epaisseur")
	(setq choix
	(getkword
  	"\nChoix de l'option [Décalage Epaisseur]: "
	)
	)
	(cond
  	((= choix "Decalage")
(if (setq tmp
	   (getreal
	 	(strcat
	   	"\nLargeur du décalage (actuel <"
	   	(rtos *offset*)
	   	"> ): "
	 	)
	   )
	)
  (setq  tmp *offset* )
)
  	)
  	((= choix "Epaisseur")
 (if (setq tmp
		(getreal
	  	(strcat
		"\nLargeur du décalage (actuel <"
		(rtos *ep*)
		"> ): "
	  	)
		)
 	)
   (setq tmp *ep*)
 )
  	)
	)

 ) ;_ Fin de while  on a nos paramètres et une sélection

 (setq lst-poly (entget (ssname poly 0)))
 (if (/= "LWPOLYLINE" (cdr (assoc 0 lst-poly)))
(progn
 	(princ "\n l'entité n'est pas une polyligne")
 	(c:dec-fix)
)
 )

 (princ "\n sélectionnez un point sur le coté à décaler ")
 (setq pt (getpoint))

 (setvar "Cmdecho" 0)						; rendre inactif l’écho des commandes			
 (command "decaler" *offset* poly pt "")
 (setvar "Cmdecho" 1)						; remettre actif l’écho des commandes et l'aosmode

 ;; modification de l'épaisseur globale 
 ;;de la poly qui vien d'etre créée
 (setq lst-poly (entget (entlast)))
 (setq	ep0	 (assoc 43 lst-poly)
ep1	 (cons 43 *ep*)
lst-poly (subst ep1 ep0 lst-poly)
 )
 (entmod lst-poly)								
 (princ)
)

Posté(e)

Salut,

 

Il ne faut pas faire de complexes par rapport aux fonctions LISP command, vl-cmdf ou command-s.

Ces fonctions sont très utiles et permettent souvent de ne pas "réinventer la roue" en utilisant ce qu'AutoCAD nous fournit.

Un des derniers LISP que j'avais écrit (LinkData, sur cette page) mélange allègrement les fonctions Visual LISP (vla-*), les fonctions AutoLISP avancées (entmake, entmod, grread, ...) et les appels aux commandes AutoCAD native (ici : (vl-cmdf "_mtext" ...) pour bénéficier de l'éditeur de texte).

 

Pour ce qui nous préoccupe ici, le plus simple est vraiment d'appeler les commandes natives DECALER (_OFFSET) pour décaler la polyligne et PEDIT (_PEDIT) pour modifier la largeur globale de la polyligne générée.

 

(defun c:cmd1 ()
 (command "_.offset" 0.1 pause pause "")
 (command "_.pedit" (entlast) "_width" 0.04 "")
 (princ)
)

Le code ci-dessus fonctionnera sans problème tant que l'utilisateur fait exactement ce que le programme attend de lui :

  1. séléctionner une polyligne ;
  2. spécifier un point du côté du décalage.

 

Par exemple, si l'utilisateur annule pendant l'exécution de la commande DECALER au moment où il est invité à séléctionner une polyligne ou quand il doit spécifier le point sur le côté à décaler, ça génèrera une erreur, sans gravité dans ce cas, mais ça ne "fait pas propre" sur la ligne de commande :

  Citation
Commande: ; erreur: Fonction annulée

Ceci peut facilement être résolu avec l'utilisation de vl-cmdf à la place de command. La principale différence entre ces deux fonctions est que command appelle la commande AutoCAD avant d'évaluer les arguments qui lui sont passés et retourne toujours nil. vl-cmdf, de son côté, évalue d'abord les arguments, puis appelle la commande si aucun n'est nil et retorune T, ou, dans le cas où un des arguments est nil, retourne nil sans appeler la commande.

 

(defun c:cmd2 ()
 (if (vl-cmdf "_.offset" 0.1 pause pause "")
   (command "_.pedit" (entlast) "_width" 0.04 "")
 )
 (princ)
)

 

Reste à gérer le cas où l'utilisateur sélectionnerait autre chose qu'une polyligne, ce qui génèrerait une erreur avec DECALER si l'entité nest pas de type curviligne ou avec PEDIT si ce n'est pas une polyligne.

Pour ce faire, le code doit s'occuper de la sélection de l'entité et contrôler que c'est bien une polyligne.

 

On peut écrire un message en ligne de commande en cas de mauvaise saisie :

(defun c:cmd3 (/ pl)
 (if (setq pl (car (entsel "\nSélectionnez la polyligne à décaler: ")))
   (if	(= (cdr (assoc 0 (entget pl))) "LWPOLYLINE")
     (if (vl-cmdf "_.offset" 0.1 pl pause "")
(command "_.pedit" "_width" 0.04 "")
     )
     (prompt "\nL'objet sélectionné n'est pas une polyligne.")
   )
   (prompt "\nAucun objet sélectionné.")
 )
 (princ)
)

ou utiliser (and ...) qui arrêtera l'exécution dès qu'une expression retournera nil (à partir de A3013 on peut remplacer command par command-s, même si l'intéret ici est limité) :

(defun c:cmd3 (/ pl)
 (and
   (setq pl (car (entsel "\nSélectionnez la polyligne à décaler: ")))
   (= (cdr (assoc 0 (entget pl))) "LWPOLYLINE")
   (vl-cmdf "_.offset" 0.1 pl pause "")
   (command-s "_.pedit" "_width" 0.04 "")
 )
 (princ)
)

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

Posté(e)

slt (gile)... Quand je dis qu'il y a des artistes...

La gestions des erreurs est la partie à mon sens la moins facile d'un programme. Je te remercie pour la leçon, et j'en prends bonne note pour plus tard...

cmd3 est de toute beauté...

J'ai du mal avec le (and utilisé comme ça, mais il faut reconnaitre que c'est diablement efficace. Mais j'en suis encore à faire des codes laborieux et un peu "scolaires" il me faudra du temps pour que ça devienne naturel...

 

  Citation

J'ai un peu potassé un tuto trouvé sur le net : http://gilecad.azure..._a_AutoLISP.pdf

mais j'avoue ne pas tout saisir. Je ne suis pas familier à la programmation en général et même si je comprends l'ossature globale d'un lisp, la pratique est une autre paire de manches...

 

J'avoue avoir moi même mis du temps à digérer. Aussi, je me permet de rédiger une sorte d'introduction à ton introduction pour ceux qui n'ont jamais fait de programmation... c'est sans prétention et les codes que j'y donne serai sans conteste perfectibles. Mais ça peu aider à débuter...

 

 

 

 

.

Posté(e)

Bonjour !

Merci pour vos réponses, désolé d'écrire la mienne assez tardivement ...

J'avais testé des commandes dans le même sens que Gile, j'étais parvenu à décaler ma pligne, mais je n'arrivais pas à assigner une largeur globale après. Je pense que ce qu'il me manquait était le fameux "_width", d'ailleurs, c'est ce qui correspond à la largeur dans le menu déroulant ?

 

J'ai lu ton code x-all, j'avoue que je m'y suis un peu perdu haha !

 

Petite question subsidiaire :

Cette commande me servirait à créer des bordures en 2D (vue plan)

comment arriver ensuite à créer une commande avec une sorte de menu déroulant, ou on pourrait choisir quel type de bordure on veut (genre T2, P1 etc...) et qu'en fonction de ce qu'on lui dit, il exécute le bon décalage + largeur globale correspondant au type de bordure ?

Je pense que ça c'est bien plus complexe, c'est juste une question d'optimisation, sinon je fais plusieurs lisp comme celui de Gile ...

 

Encore merci !

Posté(e)

Bonjour,

 

  (initget "T1 T2 T3 T4 T5 P1 P2")
 (setq REP (getkword "\nType de bordure [T1/T2/T3/T4/T5/P1/P2] <T2> : "))
 (if (not rep) (setq rep "T2"))
 (cond
   ((= REP "T1") (setq EP 0.12))
   ((= REP "T2") (setq EP 0.15))
   ((= REP "T3") (setq EP 0.17))
   ((= REP "T4") (setq EP 0.20))
   ((= REP "T5") (setq EP 0.24))
   ((= REP "P1") (setq EP 0.08))
   ((= REP "P2") (setq EP 0.06))
 )

 

en utilisant initget et getkword, ce n'est pas beaucoup plus difficile pour avoir un menu déroulant. Après, l'utilisation du cond permet, en fonction de la réponse REP donnée par l'utilisateur, d'avoir une variable EP qui contient l'épaisseur qui correspond. Enfin, il suffit d'injecter cette variable EP dans la commande offset à la place de la constante 0.1

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Posté(e)

Dans la même idée que zebulon_ mais avec assoc au lieu de cond:

(initget "T1 T2 T3 T4 T5 P1 P2")
(setq Ep (cdr
          (assoc (getkword "\nType de bordure [T1/T2/T3/T4/T5/P1/P2] <T2> : ")
                 '((nil . 0.15) ("T1" . 0.12) ("T2" . 0.15) ("T3" . 0.17) ("T4" . 0.20) ("T5" . 0.24) ("P1" . 0.08))
          )
        )
)

Apprendre => Prendre => Rendre

Posté(e)

Merci de la rapidité de vos réponses !

 

Voilà ce que j'ai fait :

---------------------------------------------------------------------

(defun c:BOR (/ ent REP EP DC)

(initget "T2 P1")

(setq REP (getkword "\nType de bordure [T2/P1] <T2> : "))

(if (not rep) (setq rep "T2"))

(cond

((= REP "T2") (setq EP 0.1) (setq DC 0.1))

((= REP "P1") (setq EP 0.04) (setq DC 0.06))

)

(if (setq ent (car (entsel)))

(progn

(command "_.offset" DC ent pause "")

(command "_.pedit" (entlast) "la" EP "")

) ; fin progn

) ; fin if

(princ)

)

----------------------------------------------------------------------

 

Je pourrai rajouter pleins d'autres bordures après, c'est facile d'y rajouter quelques lignes ! En tout cas ça marche parfaitement bien !

 

(Gile), j'ai essayé tes expressions, ça me décale bien mais ça ne met pas de largeur globale à la pligne décalée. La commande se bloque après au niveau du menu déroulant de "pedit"

 

Pour la finaliser totalement, je vais essayer de lui entrer une autre variable qui servira à faire passer les deux plignes dans un calque spécifique. J'ai une petite idée mais je vais déjà cogiter de mon côté et si besoin est, je ferai appel à vos talents de programmateurs !

 

C'est formidable, je fais des trucs qui sont simples mais j'ai l'impression d'être un fou furieux... Haha !

 

Cordialement,

 

Baptiste

Posté(e)

Slt,

  Le 28/07/2015 à 12:38, hey_bapt a dit :

(Gile), j'ai essayé tes expressions, ça me décale bien mais ça ne met pas de largeur globale à la pligne décalée. La commande se bloque après au niveau du menu déroulant de "pedit"

Une coquille dans le copier-coller des expression de (gile) à fait sauter la fonction (entlast)

 

A+

Apprendre => Prendre => Rendre

Posté(e)
  Citation
je fais des trucs qui sont simples mais j'ai l'impression d'être un fou furieux...

 

Bienvenu au club !

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Posté(e)
  Citation

J'ai lu ton code x-all, j'avoue que je m'y suis un peu perdu haha !

 

il n'y a rien de compliqué, la 1ere partie sert à initialiser ou redéfinir 2 variables et la 2eme partie à faire le décalage juste que pour le changement d'épaisseur je passe par la modification du code DXF de la polyligne au lieux de Pedit, c'est vrai que ya plus direct. Mais bon... je débute aussi ;)

Posté(e)

Jamais rien n'est compliqué pour celui qui connait, haha ! (en fait c'est plus ta première partie ou j'ai pas tout pigé)

J'ai déjà compris la logique du LISP et quelques unes des fonctions les plus courantes, sachant qu'autocad m'était pratiquement inconnu - comme tout autre logiciel de CAO - il y a un peu plus d'1 an, je ne m'attends pas à devenir bon d'ici 2 semaines...

 

J'ai réussi à ajouter le changement de calque à mes deux entités, de manière pas catholique très certainement, mais ça a le mérite de marcher. Faut que j'étudie à nouveau pour voir comment sélectionner les deux entités d'un coup.

 

Je considère ce sujet comme résolu, plus que résolu même, et je voulais tous vous remercier pour le temps que vous avez pris à me fournir des réponses, des explications qui m'ont permis de mieux comprendre certains points.

 

Cordialement,

 

Baptiste

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é