Aller au contenu

Messages recommandés

Posté(e)

Bonjour à tous !

 

Ce message s'adresse aux rois de la gestion des listes (Gile, par exemple :D )

 

J'aimerais avoir une liste de toutes les refs de blocs pourvues d'attributs dans un dessin..

Il faut donc rapatrier tous les noms des références de blocs, et passer par un tblsearch + code dxf 70 pour savoir quels blocs ont un code dxf de 66.

 

Je suis sur que l'on peut utiiser un mapcar + lambda pour trouver ça rapidement.

 

Je sais très bien qu'un foreach serait des plus simples ! Mais j'essaie de comprendre et d'utiliser ces fonctions de liste mapcar, apply, append, lambda etc...

 

Voilà.

J'ai commencé une routine qui ressemble à ça :

(mapcar '(lambda (x)(cdr (assoc 70 (tblsearch "block" x))))(lstab "block"))

 

Là j'arrive à voir les résultats du code DXF 70 pour chaque élément de la liste...

Après je n'arrive pas à lui donner une condition, puis à reprendre le nom de la référence de bloc...

 

La fonction LSTAB sert à lister toutes es refs de blocs présentes dans le dessin

;;; LSTAB
;;; Génère une liste des entités d'une des tables de la bd graphique.
;;; (LSTAB "layer") -> ("0" "structure")
(defun LSTAB (tabl)
    (if (eq (type tabl) 'STR)
         (progn
              (setq lb '() lb (cons (cdr (assoc 2 (tblnext tabl T))) lb))
              (while (setq x (cdr (assoc 2 (tblnext tabl))))(setq lb (cons x lb)))
              (if (/= (strcase tabl) "BLOCK")(setq lb (acad_strlsort lb)) lb )
              
         )
    )
)

 

Voilà voilà !

 

Merci d'avance.

A bientot.

Matt.

 

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Bonjour,

 

Regarde ce sujet avec les questions qui se sont posées sur le bit 70 de la table des blocs.

 

Y a pas de (mapcar) ni de (apply) mais une fonction récursive, qui permet d'explorer les niveaux d'imbrication éventuels d'un bloc parent.

 

Autrement pour ton problème de code, je pense qu'il faut que tu fasse une condition dans ton (lambda (x) (if (< (cdr (assoc 70 (setq dxf_blk (tblsearch "block" x))) 4) (setq lst_name (cons (cdr (assoc 2 dxf_blk)) lst_name)))

 

Pas testé, juste une piste écrite à la volée

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Salut BonusCad !

Merci pour ta réponse rapide !

Je vais aller voir et tester ton bout de code !

Merci !

 

A bientot.

Matt.

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Salut

 

Une réponse en pur autolisp

 

(defun lst_bloc_att(/ at bl lst)
 (setq bl (tblnext "block" T))
 (while bl
   (and (not (member (cdr (assoc 2 bl)) lst))
     (not (eq (logand (cdr (assoc 70 bl)) 1) 1))
     (not (eq (logand (cdr (assoc 70 bl)) 4) 4))
     (not (eq (logand (cdr (assoc 70 bl)) 16) 16))
     (setq at (cdr (assoc -2 bl)))
     (while at
(setq at (entget at))
       (if (eq (cdr (assoc 0 at)) "ATTDEF")
  (setq lst (cons (cdr (assoc 2 bl)) lst)
	at nil)
  (setq at (entnext (cdr (assoc -1 at))))
)
     )
   )
   (setq bl (tblnext "block"))
 )
 (if lst
   (acad_strlsort lst)
   nil
 )
)

(setq ma_liste (lst_bloc_att))

 

@+

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)

Petit début qui fonctionne plutot pas mal...

 

(defun essai (lst /)
    (setq lisb lst)
    (mapcar 
         '(lambda (x)
              (if (not (eq (cdr (assoc 70 (tblsearch "block" x))) 66))
                   (setq lisb (remove x lisb))
              )
         ) 
         lisb
    )
    lisb
)

 

Voilà...

 

Nota : Il faut charger la routine "remove" de gile qu'on peut trouver ici... D'ailleurs merci encore Gile pour ces routines !!

 

Pour le code 70, Je ne comprends pas trop la problématique, peut-être du fait que je n'utilise pas AutoCAD.... Si je passe un petit

(tblsearch "block" (cdr (assoc 2 (entget (car (entsel))))))

sur un bloc n'ayant pas d'attribs, il met un drapeau 64, par contre si c'est un bloc attrib, c'est le drapeau 66 qui vient...

 

Voila !

A bientot.

Matt

 

 

Ah oui ! Pour que cette routine fonctionne sur autoCad, il faut ajouter vl- à remove...

Et puis ce ,'est pas le drapeau 66, mais 34 pour le code DXF 70...

Genre ça :

;;;Version AutCAD
(defun essai (lst /)
   (setq lisb lst)
   (mapcar '(lambda (x)
                (if (not (eq (cdr (assoc 70 (tblsearch "block" x))) 34))
                    (setq lisb (vl-remove x lisb))
                )
            )
           lisb
   )
   lisb
)

 

Voilà voilà !

Dites moi ce que vous en pensez !

[Edité le 30/8/2007 par Matt666][Edité le 30/8/2007 par Matt666]

 

[Edité le 30/8/2007 par Matt666]

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Salut Patrick_35 !

 

Je viens de tester ta routine et nous arrivons au même résultat ! :D

 

Par contre je ne comprends toujours pas les drapeaux du code 70 de la table des blocs....

Si je fais un (tblsearch "block" (cdr (assoc 2 (entget (car (entsel))))))

sur un bloc ou un bloc-attributs, je ne tombe jamais sur un 1 ou 4 ou 16 !

 

Et puis c'est quoi LOGAND !! Raaah lala je suis pommé encore une fois....

 

Je vais mieux regarder ta routine, j'ai du oublier une chose importante...

 

Merci !

A bientot.

Matt.

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Salut,

 

Extrait de l'aide aux développeurs sur le code de groupe DXF 70 de définitions de bloc :

Drapeaux par type de bloc (valeurs binaires pouvant être combinées):

 

0 = Indique qu'aucun des drapeaux suivants ne s'applique

 

1 = Ce bloc anonyme est généré par une opération de hachage, de cotation associative ou tout autre type d'opération, ou par une application

 

2 = Ce bloc a des définitions d'attribut non constantes (ce bit n'est pas défini si le bloc comporte des définitions d'attribut constantes ou s'il n'a aucune définition d'attribut)

 

4 = Ce bloc est une référence externe (xréf)

 

8 = Ce bloc est une superposition de xréf

 

16 = Ce bloc est dépendant en externe

 

32 = Il s'agit d'une référence externe non résolue ou d'un élément dépendant d'une référence externe (ignorée lors de la saisie)

 

64 = Cette définition est une référence externe référencée (ignorée

 

lors de la saisie)

 

La fonction LISP logand correspond à un opérateur logique AND sur des valeurs binaires. Elle retourne la somme des valeurs binares présentes dans les entiers (sommes de valeurs binaires) qui lui sont passés comme argument.

 

Exemples :

 

(logand 1 4) retourne 0

(logand 1 3) ou (logand 1 (+ 1 2)) retourne 1

(logand 3 7) ou (logand (+ 1 2) (+ 1 2 3)) retourne 3 (1 + 2)

 

par exemple, dans sa routine, Patrick_35 aurait pu remplacer :

(not (eq (logand (cdr (assoc 70 bl)) 1) 1))
 (not (eq (logand (cdr (assoc 70 bl)) 4) 4))
 (not (eq (logand (cdr (assoc 70 bl)) 16) 16)) 

 

par (plus cout mais moins explicite) :

(zerop (logand (cdr (assoc 70 bl)) 21)) 

où 21 correspond à la somme 1 + 4 + 16

 

 

[Edité le 30/8/2007 par (gile)]

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

Posté(e)

(zerop (logand (cdr (assoc 70 bl)) 21))

Je n'y avais pas pensé. Comme quoi :cool:

 

Sinon pour être plus explicite, j'aurai tendance à faire

(zerop (logand (cdr (assoc 70 bl)) (+ 1 4 16)))

 

Merci (gile)

 

@+

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)

D'accord je comprends mieux pour les drapeaux... Merci pour ces infos !

Par contre (je suis désolé d'être neuneu comme ça...) je vois pas l'utilité...

 

Dans mon dessin je veux savoir quels sont les noms de blocs avec des attributs.

D'abord si on passe une petite routine dans un dessin (149 blocs)

(sort (remove-doubles (mapcar '(lambda (x)(cdr (assoc 70 
(tblsearch "block" x))))(lstab "block"))) '<)

(remove-doubles) est une petite routine de Gile très appréciable disponible ici... Quant à (sort), elle correspond à (vl-sort) sur AutoCAD...

Le résultat :

(32 33 34) 

Bon... Ensuite si on regarde un peu mieux :

32 correspond aux blocs sans attributs

33 correspond aux blocs anonymes

34 correspond aux blocs avec attributs

 

Donc il n'y a plus qu'à faire un filtre sur le drapeau 34 du code 70 des références de la table des blocs...

 

Voilà...

Qu'en dites-vous ??

 

Sinon, j'ai essayé la routine montrée ci-dessus

(defun essai (lst /)
    (setq lib lst)
    (mapcar 
         '(lambda (x)
              (if (not (eq (cdr (assoc 70 (tblsearch "block" x))) 34))
                   (setq lib (remove x lib))
              )
         ) 
         lib
    )
    (acad_strlsort lib)
)

 

et je l'ai comparée à un foreach

(defun essai2 (lst /)
    (setq listbl34 nil)
    (foreach pt lst 
         (if (eq 34 (cdr (assoc 70 (tblsearch "block" pt))))
              (setq listbl34 (cons pt listbl34))
         )
    )
    (acad_strlsort listbl34)
)

 

Il s'avère que le foreach, par rapport à un mapcar, est beaucoup plus rapide...

Est-ce que c'est normal ???

 

Merci à vous pour votre patience...

A bientot !

Matt.

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Dans mon dessin je veux savoir quels sont les noms de blocs avec des attributs.

donc !

 

2 = Ce bloc a des définitions d'attribut non constantes (ce bit n'est pas défini si le bloc comporte des définitions d'attribut constantes ou s'il n'a aucune définition d'attribut)

 

En résumé le flag 70 devra être armé du bit 2 pour être un bloc avec attribut

 

donc

((lambda ( / dxf_blk l_blk)
(setq dxf_blk (tblnext "BLOCK" T))
(while dxf_blk
	(cond
;			((not (zerop (boole 1 (cdr (assoc 70 dxf_blk)) 2)))
		((eq (logand (cdr (assoc 70 dxf_blk)) 2) 2)
			(setq l_blk (cons (assoc 2 dxf_blk) l_blk))
		)
	)
	(setq dxf_blk (tblnext "BLOCK"))
)
(if l_blk (foreach n l_blk (print (cdr n))))
(prin1)
)) 

devrait suffire.

J'ai mis les 2 tests possibles (soit avec boole, soit avec logand)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Salut Bonuscad !

Oui oui, j'ai très bien compris ce système !

 

J'ai l'impression de ne pas être clair du tout !!

Cela ne répond pas à ma question... Vous faites tous les logand, ou des boole pour retrouver les blocs avec attributs... Perso je demande juste les blocs dans le code DXF 70 retourne 34 !!

 

Pourquoi cette différence ?? Et en plus on arrive au même résultat !!!

 

Voilà..

J'espère avoir été un peu explicite !!

 

Merci d'avance, pour votre pateince à tous et aussi pour la transmission de savoir quotidienne... C'est vraiment dément.

 

Matt, from Rennes in Blood.

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Perso je demande juste les blocs dans le code DXF 70 retourne 34 !!

 

Tu fais presque la même chose!

34 = bit 32 + bit 2

 

Cela veut dire que tu t'interesse aux XREF (bit 32) qui auraient des blocs avec attributs(bit 2), mais les blocs propre au dessin seront ignoré si ils ont des attributs.

 

Si tu mets seulement le bit 2, tu incluras TOUT les blocs ayant des attributs (Xref compris).

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Oui d'accord... Mais lorsque je charge ce petit bout de code

(cdr (assoc 70 (tblsearch "block" (cdr (assoc 2 (entget (car (entsel))))))))

sur tous les blocs du dessin, aucun ne retourne la valeur 2 sur le code dxf 70 !!!

c'est soit 32, 33 ou 34 !!

 

Et non, j' ne m'intéresse pas aux XREF !! Je n'ai aucun plan lié par XREF dans mon plan actuel !!!

Décidément c'est très bizarre tout ça !!!

 

Pour un bloc-attributs anodin le code DXF retourné ressemble à ça : (70 . 34) !!

Tu vois ?

 

C'est ça que je ne comprends vraiment pas...

 

Ptet que c'est ça : J'utilise autoCAD 2000... Je n'ai pas essayé sur des versions plus récentes...

 

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Salut,

 

sur tous les blocs du dessin, aucun ne retourne la valeur 2 sur le code dxf 70 !!!

c'est soit 32, 33 ou 34 !!

 

32, 33 et 34 sont de sommes de valeurs binaires, repectivement 32, 32 + 1 et 32 + 2.

La dernière contient bien la valeur 2.

 

Si tu fais :

(logand 32 2) -> 0 => pas d'attibuts

(logand 33 2) -> 0 => pas d'attibuts

(logand 34 2) -> 2 => le block contient un ou des attributs

 

Pour connaitre les valeurs binaires dont un entier est la somme, tu peux utiliser cette routine que j'avais donnée je ne sais plus où sous une autre forme :

 

(defun b-lst (n / b)
 (if (/= 0 n)
   (cons (setq b (expt 2 (fix (/ (log n) (log 2)))))
  (b-lst (- n b))
   )
 )
) 

 

 

 

[Edité le 1/9/2007 par (gile)]

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

Posté(e)

Pour un bloc-attributs anodin le code DXF retourné ressemble à ça : (70 . 34) !!

Tu vois ?

 

C'est vrai que la logique ne saute pas aux yeux, même en lisant l'aide!

 

32 = Il s'agit d'une référence externe non résolue ou d'un élément dépendant d'une référence externe (ignorée lors de la saisie)

 

J'ai l'impression qu'il considère qu'un bloc standard du dessin comme

Il s'agit d'une référence externe non résolue , d'où l'explication qu' Autocad attribue le bit 32 à un bloc standard mais aussi à un bloc contenu dans un xref.

 

C'est ce que j'ai déduit en faisant des test, car je m'étais posé la même question que toi lorsque j'avais planché sur la valeur de ce bit ou j'obtenais aussi (70 . 34)

 

J'ai essayé de lire entre les lignes de l'aide, et c'est ce que j'ai compris, mais je me trompe peut être.... :casstet: (le sens de la traduction de l'aide en Français n'est peut être pas parfaitement exacte)

 

En tout cas, si tu remplace dans ma routine

((eq (logand (cdr (assoc 70 dxf_blk)) 2) 2)

par

((eq (logand (cdr (assoc 70 dxf_blk)) 34) 34)

tu n'obtiendras que les noms de bloc ayant des attributs ET contenu dans les Xrefs, alors que précédemment tu obtenais TOUT les blocs ayant des attributs.

 

Si quelqu'un à une explication plus compréhensible, elle sera la bien venue

 

:P

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Ok... C'est ça !! Les codes DXF 70 des réfs de blocs ont changé depuis la version 2000...

 

Maintenant, les drapeaux sont les mêmes que vous !!

 

Ooouuuffff !!! Enfin je comprends mieux !!!

 

Merci pour votre patience ! Saloperie de MAJ...

 

Bon WE !!

Matt.

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Merci Bonuscad pour ta patience et tes réponses précises et rapides !

 

C'est vraiment ça je pense... Le fait de faire des tests sur AutoCAD 2000 !! Un essai sur la 2006, et c'était exactement ce que tu disais...

Un bloc de base, sans attribut = code dxf 70 retourne 0

Un bloc-attributs = Code DXF 70 retourne 2

 

Ca se complique encore un peu dans le dxf70, parce que j'utilise BricsCAD, qui retourne 64, 65 ou 66 !! J'utilise seulement AutoCAD pour vérifier le fonctionnement des routines...

 

Ils pourraient pas se mettre d'accord ceux là !!!

 

Merci, vraiment !!

A bientot !!!

Matt.

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Il y avait une erreur dans la routine b-lst donnée plus haut, je l'ai corrigée.

Une autre version (non récursive) est donnée ici dans un sujet qui traite aussi des valeurs binaires dans les codes DXF.

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

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é