Aller au contenu

Propriété des filtres de calques


Messages recommandés

Posté(e)

Bonjour la communauté,

 

Voilà, j'ai fais une macro qui créé des calques en tous genres, mais j'aimerai créer en même temps, grace à quelques lignes de LiSP, un filtre qui correspondra aux nouveau calques.

 

Exemple, je créé une série de calques qui commencent tous par "DET_ECL", je devrais donc faire un filtre nommé "Détection Eclairage Public" qui filtrera sur "DET_ECL*"...

 

Si quelqu'un a un conseil ou une astuce, je suis preneur...

 

J'ai aussi ce post dans le forum "VBA et VB"

Denis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Bonjour DenisH,

 

Je ne suis pas sur de bien comprendre, tu voudrais donc pour chaque calque qui, par exemple, commence par "Détection Eclairage" soit stocké dans un filtre de calque nommé "DET_ECL" ?

 

Cordialement,

GJulien

Posté(e)

Bonjour GJulien,

 

Pas loin, c'est juste l'inverse, tous les noms de calque commençant par "DET_ECL" devraient faire partie du Filtre "Eclairage Public"...

 

Donc, j'aurais au final, le filtre "Eclairage Public" qui contiendra :

DET_ECL_A

DET_ECL_B

DET_ECL_C

DET_ECL_AERIEN

DET_ECL_PTRL

DET_ECL_SYMB

...

Bref : "DET_ECL_*"

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Salut

 

Pour accéder au dictionnaire

(setq dic (vla-item (vla-getextensiondictionary (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))) "ACAD_LAYERFILTERS"))

 

Pour récuperer les données du 1er filtre

(vla-getxdata (vla-item dic 0) "ACAD" 'dxf 'data)

 

Et trouver les codes dxf

(mapcar 'cons (vlax-safearray->list dxf)
      (mapcar 'vlax-variant-value (vlax-safearray->list data))
)

 

ps : Avec ceci, tu pourras aussi bien travailler en vlisp qu'en vba

 

@+

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

Posté(e)

voila une fonction que j'ai recupére je ne sais plus ou

pour faire des filtres

 

dans ton prog de creation de calques il faut lancer cette ligne

(MlayerF "TRAME" "*TRAME*")

 

et voilou

 

 

 

 

;;;creation des filtres calque
(defun MlayerF	(NAME	    FILTER     /	  LayTbl     ExtDict
	 LayColl    ExtDictData		  GrpList    NewDict
	 Temp	    XdLst      XrecData	  NewXRec)
 (setq LayTbl (cdr (assoc 330 (entget (tblobjname "LAYER" "0")))))
 (setq ExtDict (cdr (assoc 360 (entget LayTbl))))
 (if
   (not ExtDict)
    (progn
      (vl-load-com)
      (setq LayColl (vla-get-layers
	       (vla-get-activedocument
		 (vlax-get-acad-object)
		 ) ;_ Fin de vla-get-activedocument
	       ) ;_ Fin de vla-get-layers
     ) ;_ Fin de setq
      (setq ExtDict (vla-GetExtensionDictionary LayColl))
      (setq ExtDict (vlax-vla-object->ename ExtDict))
      ) ;_ Fin de progn
    ) ;_ Fin de if
 (setq ExtDictData (entget ExtDict))
 (while ExtDictData
   (setq Temp
	      (if (= (caar ExtDictData) 3)
		(list (cons (cdr (car ExtDictData))
			    (cdr (cadr ExtDictData))
			    ) ;_ Fin de cons
		      ) ;_ Fin de list
		) ;_ Fin de if
  ExtDictData (cdr ExtDictData)
  ) ;_ Fin de setq
   (setq GrpList (append GrpList Temp))
   ) ;_ Fin de while
 (if
   (or	(not GrpList)
(not (cdr (assoc "ACAD_LAYERFILTERS" GrpList)))
) ;_ Fin de or
    (progn
      (setq DictList (list (cons 0 "DICTIONARY")
		    (cons 100 "AcDbDictionary")
		    ) ;_ Fin de list
     ) ;_ Fin de setq
      (setq NewDict (entmakex DictList))
      (setq NewDict (dictadd ExtDict "ACAD_LAYERFILTERS" NewDict))
      ) ;_ Fin de progn
    (setq NewDict (cdr (assoc "ACAD_LAYERFILTERS" GrpList)))
    ) ;_ Fin de if
 (setq	ExtDictData
 Nil
Temp Nil
GrpList	Nil
) ;_ Fin de setq
 (setq ExtDictData (entget NewDict))
 (while ExtDictData
   (setq Temp
	      (if (= (caar ExtDictData) 3)
		(list (cons (cdr (car ExtDictData))
			    (cdr (cadr ExtDictData))
			    ) ;_ Fin de cons
		      ) ;_ Fin de list
		) ;_ Fin de if
  ExtDictData (cdr ExtDictData)
  ) ;_ Fin de setq
   (setq GrpList (append GrpList Temp))
   ) ;_ Fin de while
 (if
   (or	(not GrpList)
(not (cdr (assoc FILTER GrpList)))
) ;_ Fin de or
    (progn
      (setq XdLst (list (cons 0 "XRECORD")
		 (cons 100 "AcDbXrecord")
		 ) ;_ Fin de list
     ) ;_ Fin de setq
      (setq XrecData
      (append XdLst
	      (list (cons 1 NAME)
		    (cons 1 FILTER)
		    (cons 1 "*") ;color
		    (cons 1 "*") ;linetype
		    (cons 70 0) ;on off
		    (cons 1 "*") ;lineweight
		    (cons 1 "*") ;plot style
		    ) ;_ Fin de list
	      ) ;_ Fin de append
     ) ;_ Fin de setq
      (setq NewXRec (entmakex XRecData))
      (dictadd NewDict Name NewXRec)
      ) ;_ Fin de progn
    Nil
    ) ;_ Fin de if
 ) ;_ Fin de defun

Vous fîtes ce que vous pûtes

et vous m'épatâtes !!!!

Posté(e)

Bonsoir,

 

Et un grand merci à vous deux...

 

Je potasserais tout ça dès que j'ai du temps à y consacrer... Ca peut être l'année prochaine. ;)

 

Denis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

  • 3 semaines après...
Posté(e)

Bonjour à tous,

 

Capde06, je n'arrive pas à faire fonctionner ton LiSP...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Salut

 

(defun c:test(/ dict xdic)
 (setq xdic (vlax-vla-object->ename (vla-getextensiondictionary (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))))
 (if (setq dict (dictsearch xdic "ACAD_LAYERFILTERS"))
   (setq dict (cdr (assoc -1 dict)))
   (setq dict (dictadd xdic "ACAD_LAYERFILTERS" (entmakex '((0 . "dictionary")
						     (100 . "AcDbDictionary")
						     (280 . 0)
						     (281 . 1)
						    )
					 )
       )
   )
 )
 (dictadd dict "DenisH" (entmakex '((0 . "xrecord")
			     (100 . "AcDbXrecord")
			     (280 . 1)
			     (1 . "DenisH")
			     (1 . "DET_ECL_*")
			     (1 . "*")
			     (1 . "*")
			     (70 . 0)
			     (1 . "*")
			     (1 . "*")
			     (-3 (   "ACAD" (1000 . "( NAME== \"DET_ECL_*\" )")))
			    )
		 )
 )
 (princ)
)

 

@+

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

Posté(e)

Salut Patrick_35 et merci pour ton aide

 

Effectivement, ton LiSP "test" fonctionne correctement. Mais de là à en faire une routine comme l'avait proposé Capde06 de type (NomCommande "NomFiltre" "Filtres") il y a des kilomètres ! ! !

 

Merci encore pour ton aide toujours précieuse...

 

J'ai fais, vite fais, un petit truc de ce genre :

(defun c:DenTest (Nom Filtre/ dict xdic)
 (setq	xdic (vlax-vla-object->ename
       (vla-getextensiondictionary
	 (vla-get-layers
	   (vla-get-activedocument (vlax-get-acad-object))
	 )
       )
     )
 )
 (if (setq dict (dictsearch xdic "ACAD_LAYERFILTERS"))
   (setq dict (cdr (assoc -1 dict)))
   (setq dict (dictadd	xdic
		"ACAD_LAYERFILTERS"
		(entmakex '((0 . "dictionary")
			    (100 . "AcDbDictionary")
			    (280 . 0)
			    (281 . 1)
			   )
		)
       )
   )
 )
 (dictadd dict
   Nom
   (entmakex
     '((0 . "xrecord")
       (100 . "AcDbXrecord")
       (280 . 1)
       (1 . Nom)
       (1 . Filtre)
       (1 . "*")
       (1 . "*")
       (70 . 0)
       (1 . "*")
       (1 . "*")
       (-3 ("ACAD" (1000 . "( NAME== \"DET_ECL_*\" )")))
      )
   )
 )
 (princ)
)

 

Mais je reste bloqué à la ligne

                   (-3.("ACAD"........

 

Et je ne comprend pas pourquoi il y a plusieurs

	       (1 . "*")

 

Denis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Pour comprendre comment Autocad gère les filtres, et bien tu fais au plus simple.

Tu créés ton filtre via autocad et tu regardes les codes dxf.

 

J'avais essayé en vlisp, mais impossible de voir le filtre créé bien que les données soit présentes. Je pense que c'est l'écriture des xdatas qui doivent poser problème.

 

Donc le -3 correspond aux xdatas et tu trouveras la réponse des "*" dans le lisp de capde06

 

J'avais aussi fait une recherche sur le net et trouvé ces valeurs.

 

@+

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

Posté(e)

       (1 . Nom)
       (1 . Filtre)

Une chose, cela ne va pas fonctionner comme cela.

Il faudrait plus une liste du style

(list	'(0 . "xrecord")
(cons 1 Nom)
(cons 1 Filtre)
'(1 . "*")
)

 

@+

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

Posté(e)

Bonjour Patrick_35 et encore merci pour ton aide.

 

Donc, si j'ai bien compris, j'aurais :

(dictadd dict
 Nom
 (entmakex
   (list '(0 . "xrecord")
	 '(100 . "AcDbXrecord")
	 '(280 . 1)
	 (1 . Nom)
	 (1 . Filtre)
	 '(1 . "*")
	 '(1 . "*")
	 '(70 . 0)
	 '(1 . "*")
	 '(1 . "*")
   )
 )
)

 

Comme le LiSP de Capde06 n'utilise pas le code DXF -3, je vais essayer de faire pareils...

 

Mais chose normale, AutoCAD me répond :

Commande: (Dentest "DenisTest" "Den*")

; erreur: no function definition: DENTEST

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Bonne année a tous

la fonction de creation de filtres marche tres bien chez moi.

je crois que je l'ai recuperé chez LEE MAC ICI

Vous fîtes ce que vous pûtes

et vous m'épatâtes !!!!

Posté(e)

Bonjour Capde06 et merci de me répondre.

 

Je ne trouve pas "MlayerF" dans la liste des LiSP de Lee Mac, aurais-tu son nom d'origine s'il te plait ?

 

Et bonne année à tous...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Salut

 

Ahhhhhh. J'ai réussi en vlisp à créer le filter.

 

La routine

(defun creer_filtre(nom filtre / dict xdic)
 (setq xdic (vla-getextensiondictionary (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))))
 (and (vl-catch-all-error-p (setq dict (vl-catch-all-apply 'vla-item (list xdic "ACAD_LAYERFILTERS"))))
   (setq dict (vla-addobject xdic "ACAD_LAYERFILTERS" "AcDbDictionary"))
 )
 (vla-setxrecorddata (vla-addxrecord dict nom)
	      (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger '(0 . 6)) '(1 1 1 1 70 1 1))
	      (vlax-safearray-fill (vlax-make-safearray vlax-vbvariant '(0 . 6)) (mapcar 'vlax-make-variant (list nom filtre "*" "*" 0 "*" "*")))
 )
 (princ)
)

 

Pour créer le filtre

(creer_filtre "DenisH" "DET_ECL_*")

 

J"ai aussi testé la routine de capde06 qui fonctionne

(MlayerF "DenisH" "DET_ECL_*")

 

@+

  • Upvote 1

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

Posté(e)

Merci à vous deux...

 

Capde06 : merci pour ce lien...

 

Patrick_35 : Nikel, ça fonctionne super, juste une petite question, pour ajouter une "ligne" au filtre, on utilise quoi comme séparateur ?

 

Exemple : Nom du filtre = "Denis" qui contient 3 lignes de filtre comme "1_*", "2_*" et "3_*".

 

J'ai trouvé, c'est la virgule qui est utilisée comme séparateur...

 

Encore merci à vous deux...

 

Denis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

J'ai amélioré et simplifié la routine.

 

Vérif si le filtre existe et si oui, lui ré-écrire les valeurs.

Valeur retournée par la fonction --> Objet vla du filtre. (pour l'effacer par exemple)

 

(defun creer_filtre(nom filtre / dict ndic xdic)
 (setq xdic (vla-getextensiondictionary (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))))
 (and (vl-catch-all-error-p (setq dict (vl-catch-all-apply 'vla-item (list xdic "ACAD_LAYERFILTERS"))))
   (setq dict (vla-addobject xdic "ACAD_LAYERFILTERS" "AcDbDictionary"))
 )
 (and (vl-catch-all-error-p (setq ndic (vl-catch-all-apply 'vla-item (list dict nom))))
   (setq ndic (vla-addxrecord dict nom))
 )
 (vlax-invoke ndic 'setxrecorddata
	    '(1 1 1 1 70 1 1)
	    (list nom filtre "*" "*" 0 "*" "*")
 )
 ndic
)

 

@+

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

Posté(e)

Bonjour Patrick_35,

 

Ça fonctionne nickel... Merci...

 

Mais il y a un truc bizarre, qui n’est certainement pas en rapport avec cette routine, mais lorsque le filtre est créé, il apparait bien dans le gestionnaire de calque mais il est inopérant. Pire, parfois ils n'apparaissent pas dans le gestionnaire de calques...

 

Il faut changer de dessin puis revenir sur le premier DWG pour que le(s) nouveau(x) filtres soient « actif(s) »...

 

Curieux, non ?

 

Encore merci...

 

Denis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Salut

 

Oui, en effet.

J'ai remarqué qu'à la création du 1er filtre, tout fonctionne correctement.

C'est à la création d'un 2em que l'affichage ne se met pas à jour sur le filtre (mais le filtre créé est bien présent avec les bons paramètres).

Cela se produit aussi sur de nouveaux dessins à partir de la création du 2em filtre, ce qui n'est pas logique. Même sur des dessins vierges.

J'ai aussi testé avec le lisp donné par capde06 qui a le même problème.

 

Il suffit de cocher l'inversion d'un filtre et de le décocher pour que tout rentre dans l'ordre.

De même, si le gestionnaire des calques est affiché et que l'on créé un filtre, celui-ci ne s'affiche pas.

En fermant puis en ré-ouvrant le gestionnaire, celui-ci apparait.

 

Je pense qu'il faut mettre à jour le gestionnaire des calques suite à la création des filtres par programmation pour palier à ces problèmes. Reste à trouver comment.

 

@+

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

Posté(e)
Je pense qu'il faut mettre à jour le gestionnaire des calques suite à la création des filtres par programmation pour palier à ces problèmes. Reste à trouver comment.

 

Peut-être avec un truc comme çà :

(setq old_LayerVar (getvar "LAYERMANAGERSTATE"))
......
......
(setvar "LAYERMANAGERSTATE" 0)
(setvar "LAYERMANAGERSTATE" old_LayerVar)

 

J'ai retranscris ça vite fait depuis mes macros en VBA... Il faudrait tester...

 

En tous cas, merci pour ton aide...

 

Denis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Peut-être avec un truc comme çà :

(setq old_LayerVar (getvar "LAYERMANAGERSTATE"))
......
......
(setvar "LAYERMANAGERSTATE" 0)
(setvar "LAYERMANAGERSTATE" old_LayerVar)

 

J'ai retranscris ça vite fait depuis mes macros en VBA... Il faudrait tester...

 

En tous cas, merci pour ton aide...

 

Denis...

Cela règle le problème du gestionnaire de calque ouvert, mais pas de l'actualisation du filtre

 

@+

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

Posté(e)

Effectivement, ça ne fonctionne pas, ni depuis le LiSP, ni depuis VBA...

 

"LAYERMANAGERSTATE" ne sert à rien pour notre problème...

 

Désolé...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

  • 1 an après...
Posté(e)

Bonsoir, je déterre un peu le sujet, car la solution est très simple (bien que pas très propre), puisque le seul problème de la fonction en "command..." est que c'est une commande qui ne se termine qu'en appuyant sur la touche "echap", il suffit de terminer par un (command) seul qui simule cette touche.

 

Cela ne marche pas depuis l’éditeur lisp interne d'autocad mais fonctionne très bien en réalité, pour vérifier vous pouvez simplement copier/coller les 4 lignes de l'exemple dans la ligne de commande d'autocad.

 

 

example:

 

(setq tx1 "toto")

(setq tx4 (strcat tx1 "_*"))

 

(command "_-layer" "_filter" "_delete" tx1 "_x" (command))

(command "_-layer" "_filter" "_new" "_group" "" tx4 tx1 "_x" (command))

 

A noter: on efface d'abord le filtre même si il n'existe pas, puis on le crée (car si on le crée alors qu'il existait déjà il voudra savoir si il doit l’écraser ou non). Attention au doubles guillemets indispensables!

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é