Lisp Epaisseur de trait

Lisp Epaisseur de trait

Kevin_Megel
Mentor Mentor
7 253 Visites
99 Réponses
Message 1 sur 100

Lisp Epaisseur de trait

Kevin_Megel
Mentor
Mentor

Hello la communauté,

 

j'ai besoin de pouvoir tout selectionner les objets de l'espace objet ( juste de l'espace objet) pour leur mettre à tous la même epaisseur de trait.

il faut bien entendu la même chose pour les bloc donc je me suis dit que je pourrais passer par une lisp, et j'ai tenté l'aventure.

Pour le pas faire trop compliqué avant de pourvoir entré dans les bloc sans les exploser, je me suis dit que je vais déjà trouver comment tout selectionné sur l'espace objet et lancer la variable, et la je coince déjà, ça doit déjà faire sourir les pro du lisp, et je vais balancer le code que j'ai tenté de faire, et la ils vons exploser de rire....

 

(defun c: EPT
  (ssget "_X" ' ((0 . "ModelSpace"))
	 (command "_EPAISSLIGN")
	 )
  )

 

 

Bon avant tout j'aimerais avant que l'un d'entre vous me sorte la lisp toute faite, comprendre comment on fait et ou sont mes erreurs

 

J'ai peut être vue trop ambitieux pour une première ?

 

 

 

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Solutions acceptées (2)
7 254 Visites
99 Réponses
Replies (99)
Message 41 sur 100

_gile
Consultant
Consultant

Salut,

 

Encore une fois, il faut procéder avec rigueur et logique et pas tenter des trucs plus ou moins au hasard en espérant que ça fonctionne.

 

Ce que tu veux faire : appeler la commande _EXPLODE pour décomposer tous les blocs du dessin.

 

Première chose à faire : tester le fonctionnement de cette commande directement en ligne de commande :

- on appelle la commande en entrant _EXPLODE

- on est invité à sélectionner des objets

 

Donc en LISP, il faudra passer comme premier argument à la fonction command, le nom de la commande ("_EXPLODE") et comme deuxième argument, un jeu de sélection contenant tous les blocs.

 

Il faut donc, avant d'appeler la fonction command, créer ce jeu de sélection et le stocker dans une variable qu'on passera à la fonction command.

 

Pour créer ce jeu de sélection, on utilise la fonction ssget avec l'option "_X" et un filtre de sélection.

 

Un filtre de sélection simple (on ne parle pas de test relationnels ni de groupes logiques) est une liste associative utilisant les codes DXF. Quand on ne connait pas par coeur les valeurs associées aux codes DXF, comme par exemple le nom DXF des entités pour le code de groupe 0, on le vérifie en examinant la liste DXF d'une entité du type recherché (ici, les références de bloc) :

- on récupère le nom d'entité (ename) d'un bloc dans le dessin en le sélectionnant et on le stocke dans une variable :

(setq ent (car (entsel)))

- on peut ensuite récupérer la liste de données DXF de cette entité en faisant :

(entget ent)

et on examinera la valeur dans la paire du groupe 0.

Tout ceci peut se faire indifféremment dans la console de l'éditeur Visual LISP ou directement en ligne de commande.

On peut aussi récupérer directement la valeur pour un code de groupe donné (ici 0) avec une seule expression :

(cdr (assoc 0 (entget (car (entsel)))))

 

Une fois ceci fait, on peut essayer de créer le jeu de sélection et de le stocker dans une variable.Quand ça marche, on essaye d'appeler la commande "_EXPLODE" en lui passant la variableToutes ces étapes peuvent être faites avant même d'avoir ecrit le moindre (defun ...).

Ecrire le (defun ...) devrait, au moins quand on débute, ne se faire qu'après qu'on soit certain que toutes les expressions qu'on va y mettre fonctionnent.

 

<EDIT> Olivier a été plus rapide que moi et t'a donné la solution, dommage... On n'apprends jamais aussi bien que par soi-même.

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 42 sur 100

Kevin_Megel
Mentor
Mentor

ho t'inquiette pas j'essai déja de compredre se que dit Olivier, et ton post m'aide beacoup ^^

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 43 sur 100

Anonymous
Non applicable

Bonjour gilles,

 

Je suis désolé de t'avoir cour-circuité avec une réponse moins pertinente que la tienne. Effectivement je n'aurais pas dû expliquer plutôt que de mettre la réponse aussi directement.

 

Olivier

0 J'aime
Message 44 sur 100

Kevin_Megel
Mentor
Mentor

ok je me paume tout seul je crois,

 

si j'ai bien compris ( et c'est pas sur )

D'abor on definit la variable :

(Setq ss (ssget "_X" '((0 . "_INSERT"))))

 

d'ailleur pourquoi la commande  INSERT ? ça permet d'inserer un bloc ???

 

ensuite on defini la liste des entités :

(cdr (assoc 0 (entget (car (entsel)))))

(sssetfirst nil ss)

 

puis on fait la commande qui rappelle la variable:

(Command "_Explode" ss "")

 

 

donc le code que j'ai pondu

 

(defun c:EA (/ ss) 
(Setq ss (ssget "_X" '((0 . "_INSERT")))) (cdr (assoc 0 (entget (car (entsel))))) (sssetfirst nil ss) (Command "_Explode" ss "") (princ) )

 

mais je suis tjr pas bon ... il me demande tjr de faire une selection ! j'ai retourner en long en lagre et en travert "introduction à autolisp" pour voir si j'ai aps oublier un truc ou ajouter un truc, et je trouve rien!!!

 

J'ai verifier 5 fois chaque  "mot" pour être sur que j'ai pas fait une faute, vérifier les espaces

 

tu vois même si Olivier donne la réponse, moi je la vois toujours pas !!!

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 45 sur 100

Anonymous
Non applicable

La première ligne de code était la correction de ton jeu de sélection. Relis une 6ème fois car tu as fais une erreur de copie. Le code tel que tu le poste ne peut pas fonctionner. Comme le dis Gilles, le code n'est pas écris au hasard, chaque caractère à son importance et tu dois absolument comprendre chacun d'entre eux.

 

Les 2 autres séries étaient des éléments pour pouvoir te permettre de comprendre comment avoir les bons éléments.

Dans l'éditeur Visual lisp,  ouvre la console (touche F6) puis la ligne codes que j'ai donnée.

 

(cdr (assoc 0 (entget (car (entsel)))))

 L'éditeur va te répondre par le type d'objet que tu as sélectionner. Tu pourras alors te servir de ce type pour ton filtre.

 

La série suivante :

 

(setq ss (cdr (assoc 0 (entget (car (entsel))))))

(sssetfirst nil ss)

 

Là encore c'était uniquement pour tes tests.

Lorsque tu écris un programme tu peux vérifier que ton filtre de sélection est correct grâce à la fonction sssetfirst.

Test les 2 lignes dans l'éditeur pour voir le résultat.

 

Tout ceci ne doit pas aparaitre dans ton programme. Cela te permet juste de connaitre l'écriture exacte des types d'objets pour tes filtres puis à vérifier que ton filtre est correct avant d'aller plus loin.

 

Lorsque que tu programme, test les éléments au fûr et à mesure que tu les ajoute. En commencant par le plus imbriqué.

 

_$ (entsel)
(<Nom d'entité: 7ffffb992f0> (-21.458 -1271.81 0.0))
_$ (car (entsel))
<Nom d'entité: 7ffffb992f0>
_$ (entget (car (entsel)))
((-1 . <Nom d'entité: 7ffffb992f0>) (0 . "INSERT") (5 . "F02F") (102 . "{ACAD_XDICTIONARY") (360 . <Nom d'entité: 7ffffb99630>) (102 . "}") (330 . <Nom d'entité: 7ffffb21d10>) (100 . "AcDbEntity") (67 . 1) (410 . "01A") (8 . "0") (62 . 0) (100 . "AcDbBlockReference") (66 . 1) (2 . "*U13") (10 -71.9991 -1309.93 0.0) (41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0))
_$ (assoc 0 (entget (car (entsel))))
(0 . "INSERT")
_$ (cdr (assoc 0 (entget (car (entsel)))))
"INSERT"
_$ 

Regarde dans l'aide les fonction que l'on te donne pour comprendre une par une leur fonctionnement.

Quel type d'information est nécessaire. Quel type d'information est renvoyée.

 

Olivier

0 J'aime
Message 46 sur 100

Kevin_Megel
Mentor
Mentor

ok donc

(ssget "_X" '((0 . "INSERT")))

(setq ss (cdr (assoc 0 (entget (car (entsel))))))

 

 

apelle tout les blocs

 

en faisant ça dans la consol j'ai

 

(ssget "_X" '((0 . "INSERT")))
  (setq ss (cdr (assoc 0 (entget (car (entsel))))))
<Selection set: 791b>
"INSERT"

 

mais quand j'ajoute  la ligne

 

(command "_explode" ss "")

 

il me demande le choix de l'objet

 

j'en déduit que le soucis vien de cette ligne, mais j'en suis pas sur car pour moi  c'est bon je fait la commande, j'apelle la variable et je  valide

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 47 sur 100

Anonymous
Non applicable

Comme je l'ai dis, seule la première ligne que j'ai posté sert dans ton programme pour remplacer ton filtre de sélection.

Il faut ensuite que tu explore bien la commande décompose pour bien te servir de cette sélection.

 

Dans ton premier poste, tu avais mis

(ssget "_x" ' ((0 . "_Block")))

Ce filtre ne fonctionne pas.

Utilise la fonction (sssetfirst nil  le jeu de sélection à vérifier ) Tu pourra ainsi visuliser les objets de ta sélection.

La ligne ci-dessous ne doit pas apparaître dans ton programme. J'ai du mal m'exprimer.

(cdr (assoc 0 (entget (car (entsel)))))

Cette ligne te sert uniquement pour connaitre le type de l'objet que tu veux filtrer. Une fois connu tu n'as pas besoin de cette ligne dans ton code.

Je me répette mais teste bien chaque éléments toi même dans l'éditeur pour bien comprendre chaque symbole.

 

Lorsque que tu est sûr que ton filtre est correct et enregistré, tu peux faire la suite du programme avec l'utilisation de la commande _explode. Essaye manuellement dans Autocad pour bien connaitre les différentes étapes et les reproduire dans ton programme.

 

Olivier

 

0 J'aime
Message 48 sur 100

_gile
Consultant
Consultant

Salut,

 

Si ton enthousiasme t'honore, tant qu'il se traduira par une précipitation frénétique à essayer des assemblages hasardeux d'expressions approximatives, tu n'y arriveras pas. On ne peut pas courir avant de savoir tenir debout.

 

Si tu (re)lis pausément et attentivement les réponses qu'Olivier et moi avons pris le temps de te faire plus haut, tu y trouveras les réponses à tes questions.


Megeon a écrit :
en faisant ça dans la consol j'ai

 

(ssget "_X" '((0 . "INSERT")))
  (setq ss (cdr (assoc 0 (entget (car (entsel))))))
<Selection set: 791b>
"INSERT"

 

mais quand j'ajoute  la ligne

 

(command "_explode" ss "")

 

il me demande le choix de l'objet

 

j'en déduit que le soucis vien de cette ligne, mais j'en suis pas sur car pour moi  c'est bon je fait la commande, j'apelle la variable et je  valide


Si tu as du mal à comprendre ce que te renvoie la console, passe lui les expressions une par une et observe attentivement la valeur retournée pour chacune.

Que contient la variable ss que tu veux passer à la fonction command ?

Est-ce bien le type de valeur requis pour cette commande ?

 

Quand tu lances : (command "_explode" ss "") et que ça ne marche pas, ouvre la fenêtre de texte d'AutoCAD (F2) pour y lire attentivement ce qui s'est passé depuis le lancement de l'expression LISP. Ceci te renseignera sur la ou les erreurs.

 

Tu as, normalement, tous les éléments pour parvenir tout seul à finaliser ce LISP. Il faut juste être calme, concentré, méthodique, rigoureux dans les tests que tu fais.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 J'aime
Message 49 sur 100

Kevin_Megel
Mentor
Mentor

hello, j'ai failli abandonner une bonne dizaine de fois, j'ai decomposé le code et regarder ce que donnait chaque élément, et j'e suis arrivé a ceci

 

Révélation
(defun c:EA(/ ss)
  (Setq ss (ssget "_X" '((0 . "INSERT"))))
  (Command "_Explode" ss)
  (princ)
)

 

j'ai testé, et ça m'explose qu'un bloc, j'en déduis donc qu'il me faux une boucle, j'ai donc chercher, et je suis tombé ici et d'apres se que j'ai vu il me semble que j'ai besoin d'un while ! et sur ce principe j'ai fait ceci

 

(defun c:EA(/ ss)
  (while
  (Setq ss (ssget "_X" '((0 . "INSERT"))))
  (Command "_Explode" ss))
  (princ)
)

 

mais étant donné mon niveau relativement bas en ecriture de Lisp je vous demande a vous chere professionel de me dire si il y a pas une coquille quelquepart

 

et si il y en a pas champagne car même si il a l'aire simple, il fut compliqué à créer !!!

 

 

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 50 sur 100

Anonymous
Non applicable

Bonjour Megeon,

Pourquoi ne pas tester avant de venir poser une question ?

 

Olivier

PS : J'ai appris le peu que je connais du lisp avec l'aide Autocad et les forums.Je ne suis pas un professionnel de la programmation mais un simple dessinateur.

 

0 J'aime
Message 51 sur 100

Kevin_Megel
Mentor
Mentor

mais j'ai testé

 

mais je vien voir si j'ai pas fait une erreur, du stile "y a plus simple" ou autres...

 

(et il doit y avoir aussi un peu de "vous voyez j'ai compris finalement" )

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 52 sur 100

Anonymous
Non applicable

Comme déjà dit par Gilles et moi avant de programmer, il faut savoir se servir parfaitement des commandes en manuel. Lance la commande _EXPLODE et regarde les différentes invites. En programmation le hasard fait le plus souvent mal les choses. Ne désespère pas. Il faut juste de la rigueur.

 

Olivier

Message 53 sur 100

_gile
Consultant
Consultant

Salut,

 

Oui, il y a surtout plus efficient.

Ce que fait ton code, c'est faire une sélection de tous les blocs pour décomposer le premier bloc du jeu de sélection et recommencer tant qu'il y a des blocs à sélectionner.

 

Si tu lis attentivement le chapitre consacré aux jeux de sélection dans Intoduction à AutoLISP (chapitre 16.3 page 37), tu verras, à la fin de la page 38, un exemple pour parcourir un jeu de sélection avec while. En adaptant cet exemple, tu ne fais qu'une seule fois la sélection de tous les blocs, puis tu décomposes tour à tour chacun des blocs contenus dans le jeu de sélection.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 54 sur 100

Kevin_Megel
Mentor
Mentor

j'avais doncraisondefairevérifier, ce n'est pasparcequelecodefonctionne qu'il estcorrect

je vais regarder ça de plus pres!

 

je pensais surtout de mettre trompé au sujet de la répétition, et que se ne soit pas While qu'il fallais utiliser

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 55 sur 100

Kevin_Megel
Mentor
Mentor

je ne susi pas sur de comprendre les dernière ligne de code de l'exemple

 

(entmod (subst '(8 . "Hachures")
                (assoc 8 elst)
                 elst
         )
)

 a quoi correspond le chiffre 8 ?

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 56 sur 100

Anonymous
Non applicable

Le code 8 corrsepond au nom du calque d'une entité.

Les codes dxf sont donnés dans la partie de l'aide pour les développeurs chapitre DXF REFERENCE.

 

Ce code permet de modifier les propriétés d'un objet. Il n'est pas nécessaire pour ton programme.

 

Olivier

Message 57 sur 100

Kevin_Megel
Mentor
Mentor

bon bon bon

 

1 : Il faut initialiser l’indice :

(Setq n 0)

 

2 : il faut le filtre de sélection

(setq ss (ssget "_X " ‘((0 . ‘INSERT ")))

 

3: On accède à chacune des entités

(while (setq ent (ssname ss n))

 

En faisant une liste

(setq elst (entget ent)

 

Et en incrémentant l’indice

 

n (1+ n)

 

et si ces condition son réunit on peut lancer la commande

 

(command "_EXPLODE" ss)

 

Seulement la variable ss ramène au filtre de sélection, et donc il faut l’amener à la liste, donc

 

(command "_EXPLODE" elst)

 

J’en déduis que le code s’écrit comme ça :

 

  (Setq n 0)
  (if (setq ss (ssget "_X" '((0 . "INSERT")))
	    (while (setq ent (ssname ss n))
	      (setq elst (entget ent)
		    n (1+ n)
		    )
	      (command "_EXPLODE" elst)
	      )
	     )
    )

 

 

 seulement en testant j'ai eu ceci dans les ligne de commande

 

structure incorrecte de la liste en entréenombre d'arguments insuffisant dans SETQ: (SETQ SS (SSGET "_X" (QUOTE ((0 . "INSERT")))) (WHILE (SETQ ENT (SSNAME SS N)) (SETQ ELST (ENTGET ENT) N (1+ N)) (COMMAND "_EXPLODE" ELST)))nombre d'arguments insuffisant: (IF (SETQ SS (SSGET "_X" (QUOTE ((0 . "INSERT")))) (WHILE (SETQ ENT (SSNAME SS N)) (SETQ ELST (ENTGET ENT) N (1+ N)) (COMMAND "_EXPLODE" ELST))))

 

 

Je commence vraiment à désespérer !

 

Je suis proche du but ?

Je suis a coté de la plaque ?

Ou allors faut que j'arrête de jouer a l'apprenti sorcier et je retourne a dessiner des carrer les un a coté des autres ?

 

Smiley triste

 

 

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 58 sur 100

_gile
Consultant
Consultant

Salut,

 

Le message d'erreur te dit que la structure de la liste est incorrecte, c'est en général (et là en particulier) un problème de parenthèses.

 

Sinon, lis le chapitre 16 de l'introduction à AutoLISP, tu verras à quoi sert la fonction entget et tu devrais comprendre que tu n'en a pas besoin dans ton cas.

Si tu as compris ce que tu cherches à faire il te suffit de récupérer un nom d'entité (ENAME) pour le passer à la commande "_EXPLODE".



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 59 sur 100

Kevin_Megel
Mentor
Mentor

J'ai pas besoin de entget qui retourne a la list DXF de l'entité, car j'ai juste besoin de l'ENAME, ce que fait ssname

 

 

j'ai donc juste besoin de récupérer les noms, d'utilisert la variable _Explode

 

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime
Message 60 sur 100

Kevin_Megel
Mentor
Mentor

j'ai toujours le même probleme de parenthèse,et j'ai beau cherche je ne la vois pas !

 

(defun c:EA (/ n ss ent)
  (setq n 0)
  (setq ss (ssget "_X" '((0 . "INSERT")))
	(while
	  (setq ent (ssname ss n))
	  (setq n (1+ n))
	  (command "_EXPLODE" ent)
	  )
	 )
  (princ)
  )

 

j'ai essayer de composé le code en décomposant ce que je veux faire c-à-d

 

1: récupérer la liste des blocs

2: les décomposer

 

pour récupérer la liste j'ai donc

 

  (setq ss (ssget "_X" '((0 . "INSERT")))
	

 

et pour décomposer les bloc

 

 (command "_EXPLODE" ent)
	

 il faut donc inserer une incrémentation des noms

 

(setq ent (ssname ss n))
(setq n (1+ n))
	 

 

et refaire la commende tant que tout la liste n'est pas passer

 

(While ...)

 la suite  j'ai du mal, je ne vois pas comment mettre ça dans l'ordre

Kevin Megel
Ce post vous a été utile ? N'hésitez pas à aimer ce post.
Ce post a-t-il répondu à votre question ? Cliquez sur le bouton Accepter la solution.

EESignature

Je suis un simple utilisateur, je ne travaille pas pour Autodesk

0 J'aime