Aller au contenu

Constituer un filtre dynamique avec les codes DXF


bonuscad

Messages recommandés

Bonjour,

 

J'ai essayé de créer une routine un peu comme SSX (filtre d'objet;pour ceux qui se souviennent), mais de façon dynamique.

Pour l'usage (il faut bien connaitre les codes DXF); il suffit de balader le curseur (sans click) sur des objets.

Les codes DXF principaux (communs à toutes les entités) se retrouvent affichés en dynamique dans la barre d'état (à la place des coordonnées)

Une fois validé par (espace,entrée ou click-droit), la liste du filtre est affiché sur la lignes de commandes.

Celle-ci contient des codes DXF supplémentaires suivant le genre d'entité sélectionnée.

On peut alors supprimer les codes qui ne nous interessent plus pour fabriquer le fitre. (on peut entrer les codes par le click-droit)

Une entrée nulle à ce stade valide le filtre et l'applique au dessin.

 

Mon petit problème, est que lors de la 1ere utilisation les grips ne sont pas activés sur la sélection. (mais effacer ou autres agit bien sur la séléction mais ont voit pas les grips)

Alors que lors d'utilisations suivantes, pas de problème.

 

Où est ce que cela pêche? Une idée?

 

(defun data2string (l_dxf / l_dxf lst_pair grp_el typ_el ch1 ch2 ch)
(setq ch "")
(while l_dxf
	(setq lst_pair (car l_dxf))
	(setq grp_el (car lst_pair) typ_el (cdr lst_pair))
	(cond
		((eq (type grp_el) 'INT)
			(setq ch1 (itoa grp_el))
		)
		((eq (type grp_el) 'REAL)
			(setq ch1 (rtos grp_el 2 4))
		)
		((eq (type grp_el) 'STR)
			(setq ch1 (strcat "\"" grp_el "\""))
		)
		(T
			(setq ch1 "")
		)
	)
	(cond
		((eq (type typ_el) 'INT)
			(setq ch2 (itoa typ_el))
		)
		((eq (type typ_el) 'REAL)
			(setq ch2 (rtos typ_el 2 4))
		)
		((eq (type typ_el) 'STR)
			(setq ch2 (strcat "\"" typ_el "\""))
		)
		((eq (type typ_el) 'LIST)
			(setq ch2 (strcat (rtos (car typ_el) 2 4) " " (rtos (cadr typ_el) 2 4) (if (caddr typ_el) (strcat " " (rtos (caddr typ_el) 2 4)) "")))
		)
		(T
			(setq ch2 "")
		)
	)
	(if (eq (type typ_el) 'LIST)
		(setq ch (strcat ch "(" ch1 " " ch2 ") "))
		(setq ch (strcat ch "(" ch1 " . " ch2 ") "))
	)
	(setq l_dxf (cdr l_dxf) ch1 "" ch2 "")
)
(strcat "(" ch ")")
)
(defun c:dyn_filter ( / sv_shmnu oldim key pt_sel l_dxfcod m_filt ent dxf_ent typ_ent msg ss)
(setq
	sv_shmnu (getvar "SHORTCUTMENU")
	oldim (getvar "dimzin")
)
(setvar "dimzin" 0)
(setvar "SHORTCUTMENU" 11)
(while (and (setq key (grread T 4 0)) (not (member key '((2 13) (2 32)))) (/= (car key) 25))
	(setq
		l_dxfcod nil m_filt nil
		pt_sel (osnap (list (caadr key) (cadadr key)) "_near")
	)
	(if pt_sel
		(progn
			(setq ss (ssget "_C" pt_sel pt_sel))
			(if ss (setq ent (ssname ss 0)))
		)
		(setq ent (car (nentselp (list (caadr key) (cadadr key)))))
	)
	(cond
		(ent
			(setq dxf_ent (entget ent))
			(setq l_dxfcod (append '(38 39 48 370 62 6 8 67 0) l_dxfcod))
			(if (member (cdr (assoc 0 dxf_ent)) '("HATCH" "INSERT" "MLINE" "SHAPE"))
				(if (assoc 2 dxf_ent) (setq l_dxfcod (cons 2 l_dxfcod)))
			)
			(foreach n l_dxfcod (if (assoc n dxf_ent) (setq m_filt (cons (assoc n dxf_ent) m_filt))))
			(grtext -2 (data2string m_filt))
		)
		(T (grtext -2 ""))
	)
)
(setq typ_ent (cdr (assoc 0 dxf_ent)) m_filt nil)
(cond
	((eq typ_ent "LWPOLYLINE")
		(setq l_dxfcod (cons 43 l_dxfcod))
	)
	((or (eq typ_ent "POLYLINE") (eq typ_ent "MLINE"))
		(setq l_dxfcod (cons 70 l_dxfcod))
	)
	((or (eq typ_ent "DIMENSION") (eq typ_ent "LEADER"))
		(setq l_dxfcod (cons 3 l_dxfcod))
		(setq l_dxfcod (cons 70 l_dxfcod))
	)
	((or (eq typ_ent "ACR") (eq typ_ent "CIRCLE") (eq typ_ent "ELLIPSE"))
		(setq l_dxfcod (cons 40 l_dxfcod))
	)
	((or (eq typ_ent "TEXT") (eq typ_ent "MTEXT") (eq typ_ent "ATTDEF"))
		(setq l_dxfcod (cons 7 l_dxfcod))
		(setq l_dxfcod (cons 40 l_dxfcod))
	)
)
(foreach n l_dxfcod (if (assoc n dxf_ent) (setq m_filt (cons (assoc n dxf_ent) m_filt))))
(princ (strcat "\n(ssget \"" "_X" "\" " (data2string m_filt) ")"))
(setq msg "")
(initget (foreach n m_filt (setq msg (strcat (itoa (car n)) " " msg))))
(setq msg "")
(setq msg (strcat "\nCode DXF a supprimer? [" (foreach n m_filt (setq msg (strcat (itoa (car n)) "/" msg))) "]"))
(while (setq what (getkword msg))
	(setq m_filt (vl-remove (assoc (atoi what) m_filt) m_filt))
	(princ (strcat "\n(ssget \"" "_X" "\"" (data2string m_filt) ")"))
	(setq msg "")
	(initget (foreach n m_filt (setq msg (strcat (itoa (car n)) " " msg))))
	(setq msg "")
	(setq msg (strcat "\nCode DXF a supprimer? [" (foreach n m_filt (setq msg (strcat (itoa (car n)) "/" msg))) "]"))
)
(if (zerop (getvar "PICKFIRST")) (setvar "PICKFIRST" 1))
(sssetfirst nil nil)
(setq ss (ssget "_X" m_filt))
(sssetfirst nil ss)
(setvar "SHORTCUTMENU" sv_shmnu)
(setvar "dimzin" oldim) 
(prin1)
)

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

Salut,

 

C'est peut être dû à un fonctionnement aléatoire de sssetfirst. J'ai fait un ptit lisp qui sélectionne tous les objets d'un fichier, en filtrant le calque d'un représentant. il y a 2 paramètres pour sssetfirst, j'ai pas trouvé d'aide à leur sujet et j'ai tâtonné jusqu'à ce que ça marche.

 

Cela marche bien dans ma version 2004, mais un copain à qui je l'ai filé me dit que ça ne marche pas dans sa 2006 ? (et comme je n'ai pas la 2006 ...)

 

 

 

(defun c:laysel ()
 (setq P (car (entsel "Choix objet :")))
 (if P
   (progn
     (setq E (entget P))
     (setq LAY (assoc 8 E))
     (setq SS (ssget "X" (list LAY)))
     (sssetfirst nil SS)
   )
 )
 (princ)
) 

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)

Lien vers le commentaire
Partager sur d’autres sites

Merci Zebulon d'avoir tenté de répondre.

 

Fait bizzare j'ai le même symptôme avec ton lisp.

Avec un dessin; pour tout dire que je me sert pour faire mes tests (il contient tous les types d'entités crées dans différents SCU,calques, couleurs, etc...) et de taille tout à fait raisonnable.

La sélection s'effectue, les grips sont activé, mais pas visible (ceci à la 1ere utilisation, je le rapelles)

Il me suffit de cliquer 1 fois dans le vide pour que les grips s'affichent.

 

Ceci est constaté sur une 2000-2002-2005.

Bien sur "PICKFIRST" ainsi que "GRIPS" sont à 1 dans tout les cas.

 

Enfin drôle de phénomène, mais pas trop génant car il ne le fait que si les grips n'ont pas été utilisés au moins 1 fois avant.

 

Peut être un comportement qui perdure sur la 2006?

 

A propos de ton lisp si la conditon est remplie; 1 entité sélectionnée (pas de controle à ce niveau) :(

La suite devrait se dérouler comme il faut car tu utilises des fonctions lisp basiques (pas de vl- ni vlax-). Je suis surpris qu'il ne fonctionne pas sous 2006.

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

Salut

 

J'ai lancé autocad 2004, Je crée une ligne ou deux et un arc, je charge ton lisp et je le lance.

 

Je place mon curseur sur une entité, je clique à droite et les codes dxf de l'entité s'affichent puis je valide avec entrée et les poignées de sélection s'affichent sans problème, du premier coup.

 

Sinon, avant que Autodesk ne rajoute la sélection rapide, j'étais un grand consommateur de la commande FILTER et dans cette commande il y a un bouton "Ajouter l'objet sélectionné", qui permet de faire un peu la même chose que ton lisp, mais affiché sous forme de boîte de dialogue. De plus, de la manière dont c'est présenté, il ne faut pas absolument être une bête en code dxf pour pouvoir l'utiliser.

Le défaut majeur de la commande FILTER est dû à une problème de traduction (une fois de plus). La liste des critères de sélection est triée en fonction de la liste anglo-saxonne. Dans la version française, on a donc du mal à retrouver ses petits.

 

Amicalement

 

Zebulon_

 

 

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)

Lien vers le commentaire
Partager sur d’autres sites

Salut

 

Ma routine, je te l'accorde n'apporte pas grand chose, surtout si on est pas familier avec les codes DXF.

 

L'option "Ajouter object sélectionné" de "filter" si elle fait la même chose, rapatrie , à mon goût, trop d'informations (en fait pratiquement toutes) que l'on est obligé dans la majorité des cas de virer.

Et puis tu peux croire sélectionner une ligne alors que c'est une polyligne, ou alors incrusté dans un bloc/xref, donc obligé de vider la liste de "filter" de recommencer ta sélection sur un autre objet.

 

Donc des fois au bout du compte, beaucoup de manip dans la boite de dialogue pour monter le filtre.

Avec ma routine je vois de suite si le filtre principal me convient et les codes complémentaires rajoutés (dans certain cas) sont les plus utilisés pour les filtres

 

En fait j'aimais bien l'ancienne routine d'Autodesk "SSX", j'ai voulu faire le même principe en la simplifiant quelque peu et voir le fitre en dynamique dans la barre d'état.

 

Si je publie le code, c'est pour aussi donner des idées et pas forcément pour réinventer la roue ;)

 

La solution de la mise à jour de (initget) (getkword) dans une boucle peuvent donné des solutions pour d'autre routines. L'emploi de (grread) (grtext) est interessant aussi.

 

En bref, ce n'est pas que la fonction finale qui peut servir et être interressante, mais simplement quelque bout de ligne que l'on peut exploiter pour laisser libre court a son esprit d'inventivité.

 

Je repose quand même la question car il y en avait une!

Bien que l'importance soit minime, d'où peut venir le comportement aléatoire de (sssetfirst) dans certain dessins.

 

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

on avait déjà parlé de sssetfirst il y a un petit moment

 

http://www.cadxp.com/sujetXForum-1355.htm

 

Essaie de changer ton code en mettant

 

(sssetfirst ss ss) au lieu de (sssetfirst nil ss)

 

Pour ce qui est de la commande filter, je suis tout à fait d'accord qu'elle est lourdingue et c'est pour ça que la sélection rapide me plait beaucoup plus.

 

Mais ce qui me plait dans filter, c'est la présentation de la liste des filtres dans un liste d'une boîte de dialogue.

 

Ce qui serait top, ce serait d'avoir la même chose que _qselect, mais avec un petit bouton, à côté de la case valeur, qui permettrait de piquer cette valeur sur un objet existant.

 

Pour ce qui est de l'emploi de grread et grtext, ça n'a, à mon avis, de sens que dans des routines où l'on est sûr de ne pas avoir besoin d'accroche objet. On en avait déjà causé aussi

 

http://www.cadxp.com/sujetXForum-5461.htm

 

Amicalement

 

Zebulon_

 

 

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)

Lien vers le commentaire
Partager sur d’autres sites

Salut Bonus

Ton lisp fonctionne parfaitement chez moi

J'ai testé plusieurs cas et tout fonctionne sauf quand tu fais un clic droit et que rien n'est indiqué dans la ligne de statue, mais à part ça ;)

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

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é