sergeluc Posté(e) le 27 mai 2006 Posté(e) le 27 mai 2006 Bonjour à tous ,J'ai rencontré une situation que je n'ai pas encore pu maitriser.Elle concerne un dwg avec des xrefs imbriqués dont certains introuvables et pour finirdes références croisées (dwgs insérés en blocs et déclarés en xref).C'est ce dernier point qui me pose un problème .Mon but est d'obtenir une compilation avec ce qui peut l'ètre avec l'option "lier" ,de détacher le reste et de supprimer ces références croisées en Lisp ou Vlisp.Pour détacher avec : (command "_.-XREF" "_d" "*") cela ne suffit pas à cause des références croisées. Si quelqu'un peut m'orienter ,merci d'avance .
autospeed Posté(e) le 28 mai 2006 Posté(e) le 28 mai 2006 Pour ce genre de probleme , il suffit d'ouvrir l'XREF concerné et de détacher les Xrefs introuvables. C'est ce que l'on fait manuellement quand on est confronté a ce genre de probleme.Phil http:// www.autospeed.biz Auteur du logiciel AutospeedAuteur de la théorie du site www.kheops.bizAuteur de nombreux livres
sergeluc Posté(e) le 28 mai 2006 Auteur Posté(e) le 28 mai 2006 BonjourManuellement cela ne m'a jamais posé de problème,j'ai mis ce message dans la rubrique lisp/vlisp pour obtenir une éventuelle réponse ou orientation dans ce sens. [Edité le 28/5/2006 par sergeluc]
(gile) Posté(e) le 28 mai 2006 Posté(e) le 28 mai 2006 Salut, je ne suis pas sûr de comprendre ce que tu veux faire, mais voici quelques lignes codes qui pourraient te servir. Pour récupérer les "noms" (vla-get-name) des Xrefs dans 3 listeslst : les noms de toutes les Xrefs du dessinlst1 : les noms des Xrefs "parents" (pouvant en contenir d'autres)lst2 : les noms des Xrefs imbriquées dans les Xrefs de lst1 ou dans celles de lst2 (imbrication double ou triple ou plus...), les Xrefs les plus "profondément imbriquées" se trouvant en fin de liste. ;; AcDoc : pointeur vers le document actif ;; ss : sélection de tous les blocs et Xrefs insérés sur les calques dévérouillés (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) ss (ssget "_X" '((0 . "INSERT"))) ) ;; On parcourt le jeu de sélection pour constituer une liste (lst) ;; avec seulement les noms des Xrefs (if ss (progn (repeat (setq n (sslength ss)) (setq obj (vlax-ename->vla-object (ssname ss (setq n (1- n)))) ) (if (and (not (member (vla-get-name obj) lst)) ;_ éviter les doublons (= :vlax-true ;_ uniquement les Xrefs (vla-get-isXref (vla-item (vla-get-Blocks AcDoc) (vla-get-Name obj)) ) ) ) (setq lst (cons (vla-get-name obj) lst ) ) ) ) (setq lst1 lst ;_ on conserve dans lst1 les xref "parents" n_lst 0 ) ;; On parcourt la liste lst et pour chaque Xref, on cherche si ;; dans ces composants il y a une (ou des) Xref. Si ces le cas, ;; elles sont rajoutées en fin de liste et seront traitées à leur tour. (while (setq name (nth n_lst lst)) (setq bloc (vla-item (vla-get-blocks acDoc) name)) (repeat (setq n (vla-get-count bloc)) ;_ nombre de composant du bloc (Xref) (setq ent (vla-item bloc (setq n (1- n)))) (if (and (= (vla-get-ObjectName ent) "AcDbBlockReference") ;_ si le composant est un bloc (not (member (vla-get-name ent) lst)) ;_ s'il n'est pas déjà dans la liste (= :vlax-true ;_ si c'est une Xref (vla-get-isXref (vla-item (vla-get-Blocks AcDoc) (vla-get-Name ent) ) ) ) ) (setq lst (reverse (cons (vla-get-Name ent) (reverse lst))) ;_ la Xref est ajoutée en fin de liste ) ) ) (setq n_lst (1+ n_lst)) ) ) ) ;; Constitution de lst2 : lst moins les éléments contenus dans lst1 (setq lst2 (vl-remove-if '(lambda (x) (member x lst1)) lst)) Si tu veux, par exemple, détacher toutes le Xrefs imbriquées, il faut commencer par les "plus profondément imbriquées". (mapcar '(lambda (x) (vla-detach (vla-item (vla-get-Blocks AcDoc) x)) ) (reverse lst2) ) Attention je n'ai pas testé, j'ai écrit çà à partir de la manière dont je récupère les blocs imbriqués dans Modifier des blocs [Edité le 29/5/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
sergeluc Posté(e) le 28 mai 2006 Auteur Posté(e) le 28 mai 2006 merci gile , c'est exactement ce dont j'avais besoin.Mon but est de pré-traiter des fichiers reçu par "E-transmit" .Il me restait à faire une analyse(cohérente) de manière a pouvoir assembler les plans déclarés en xref ,de nettoyer le reste et de sortir un listing de résultat car celui fait par autocad ne me convient pas.De plus cela va me pousser à me mettre au visual lisp ,c'est parfait .Bonne soirée
(gile) Posté(e) le 29 mai 2006 Posté(e) le 29 mai 2006 c'est exactement ce dont j'avais besoin. Je suis content de pouvoir t'aider, j'ai ajouté des commentaires au code ci-dessus pour qu'il soit plus facile à comprendre, et, éventuellement, à modifier. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
sergeluc Posté(e) le 29 mai 2006 Auteur Posté(e) le 29 mai 2006 Encore un grand merci gile pour ta gentillesse et tes compétences .
(gile) Posté(e) le 29 mai 2006 Posté(e) le 29 mai 2006 Encore une petite, pour détacher toutes les Xrefs dont le chemin n'est pas valude : (mapcar '(lambda (x) (setq path (vla-get-Path (vla-item (vla-get-blocks acdoc) x))) (if (not (open path "r")) (vla-detach (vla-item (vla-get-Blocks AcDoc) x)) ) ) lst ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
GEGEMATIC Posté(e) le 22 mai 2008 Posté(e) le 22 mai 2008 Salut Comme j'ai eu besoin de cette fonctionnalité, puisqu' autocad ne retourne pas correctement les informations prévues dans la structure dxf (voir les drapeaux du code 70: toutes ces infos devraient pouvoir s'obtenir directement sans devoir parcourir l'ensemble des blocs : sauf qu'en réalité ça ne marche pas Du coup j'ai simplement repris et aménagé le code original, de façon à ce 3listes_xref présente ses résultats de manière plus agréable, et surtout que l'on sache qui référence qui, car c'est ça mon problème (plein de références croisées = ingérable) ;;******************************************************************************** ;§/xref/Pour récupérer les "noms" (vla-get-name) des Xrefs dans 3 listes/none ;;;xref-lst : les noms de toutes les Xrefs du dessin ;;;xref-lst1 : les noms des Xrefs "parents" (pouvant en contenir d'autres) avec la listes des xrefs filles (contenues par) ;;;xref-lst2 : les noms des Xrefs imbriquées dans les Xrefs de xref-lst1 ou dans celles de xref-lst2 ;;;(imbrication double ou triple ou plus...), les Xrefs les plus "profondément imbriquées" se trouvant en fin de liste. ;;idée originale par giles ;;post original: ;;http://www.cadxp.com/modules.php?op=modload&name=XForum&file=viewthread&tid=10289#pid ;; AcDoc : pointeur vers le document actif ;; ss : sélection de tous les blocs et Xrefs insérés sur les calques dévérouillés (defun 3listes_xref () (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) ss (ssget "_X" '((0 . "INSERT"))) ) ;; On parcourt le jeu de sélection pour constituer une liste (xref-lst) ;; avec seulement les noms des Xrefs (if ss (progn (repeat (setq n (sslength ss)) (setq obj (vlax-ename->vla-object (ssname ss (setq n (1- n)))) ) (if (and (not (member (vla-get-name obj) xref-lst)) ;_ éviter les doublons (= :vlax-true ;_ uniquement les Xrefs (vla-get-isXref (vla-item (vla-get-Blocks AcDoc) (vla-get-Name obj)) ) ) ) (setq xref-lst (cons (vla-get-name obj) xref-lst ) ) ) ) ;;; (setq xref-lst1 xref-lst ;_ on conserve dans xref-lst1 les xref "parents" ;;; n_lst 0 ;;; ) (setq xref-lst1 nil) (setq n_lst 0) ;; On parcourt la liste xref-lst et pour chaque Xref, on cherche si ;; dans ces composants il y a une (ou des) Xref. Si ces le cas, ;; elles sont rajoutées en fin de liste et seront traitées à leur tour. (while (setq name (nth n_lst xref-lst)) (setq bloc (vla-item (vla-get-blocks acDoc) name)) (repeat (setq n (vla-get-count bloc)) ;_ nombre de composant du bloc (Xref) (setq ent (vla-item bloc (setq n (1- n)))) (if (and (= (vla-get-ObjectName ent) "AcDbBlockReference") ;_ si le composant est un bloc ;;; (not (member (vla-get-name ent) xref-lst)) ;_ s'il n'est pas déjà dans la liste (= :vlax-true ;_ si c'est une Xref (vla-get-isXref (vla-item (vla-get-Blocks AcDoc) (vla-get-Name ent) ) ) ) ) ;_#and (progn (if (not (member (vla-get-name ent) xref-lst)) ;_ s'il n'est pas déjà dans la liste (setq xref-lst (reverse (cons (vla-get-Name ent) (reverse xref-lst) ) ) ;_ la Xref est ajoutée en fin de liste ) ) ;;dans tous les cas, cette référence conient d'autre référence: (if (setq tmp (assoc name xref-lst1)) ;_ s'il est déjà dans la liste des références parentes (setq xref-lst1 (subst (append tmp (list (vla-get-Name ent))) tmp (cons name xref-lst1)) ) (setq xref-lst1 (reverse (cons (list name (vla-get-Name ent)) (reverse xref-lst1))) ;_ la Xref est ajoutée en fin de liste ) ) ) ) ;_#if ) (setq n_lst (1+ n_lst)) ) ) ) ;; Constitution de xref-lst2 : xref-lst moins les éléments parents contenus dans xref-lst1 (setq xref-lst2 (vl-remove-if '(lambda (x) (member x (mapcar 'car xref-lst1))) xref-lst) ) (prompt "\nXref du dessin:") (mapcar 'print xref-lst) (prompt "\nXref parentes du dessin est leurs sous xref:") (foreach l xref-lst1 (prompt (strcat "\nParent : " (car l))) (prompt "\n Fils : " ) (foreach ll (cdr l) (prompt (strcat "\n " ll)) ) ) (princ) ) ;;******************************************************************************** ;§/xref/Détache les xref imbriquées/none ;;idée originale : Gile ;;Si tu veux, par exemple, détacher toutes le Xrefs imbriquées, il faut commencer par les "plus profondément imbriquées". (defun c:detach_imbriquees () (if (not xref-lst2) (3listes_xref) ) (mapcar '(lambda (x) (vla-detach (vla-item (vla-get-Blocks AcDoc) x)) ) (reverse xref-lst2) ) ) ;******************************************************************************** ;§/xref/pour détacher toutes les Xrefs dont le chemin n'est pas valide/none ;;idée originale : Gile (defun c:detach_nonvalides () (if (not xref-lst) (3listes_xref) ) (mapcar '(lambda (x) (setq path (vla-get-Path (vla-item (vla-get-blocks acdoc) x))) (if (not (open path "r")) (vla-detach (vla-item (vla-get-Blocks AcDoc) x)) ) ) xref-lst ) ) ----------------------------------------------------------------------Site: https://www.g-eaux.frBlog: http://g-eaux.over-blog.com
Patrick_35 Posté(e) le 22 mai 2008 Posté(e) le 22 mai 2008 Salut Un lisp trouvé sur le net ;;; Stephan Koster 2002, posted to adesk customization ;;; newsgroup on 4/21/2002 (defun XrefTree (/ nested_p build_retlist firstLevelXrefs name nested-xrefs nestList xrefDBase retList i ) (defun nested_p (blockname / tn tmp) (and (setq tn (tblobjname "block" blockname)) (setq tmp (entget tn)) (setq tmp (cdr (assoc 330 tmp))) (setq tmp (entget tmp)) (not (member '(102 . "{BLKREFS") tmp)) ) ) ;;; (defun build_retlist(name / next) (setq retList (cons (cons i name) retList)) (and (setq next (cdr (assoc name nestList))) (setq i (1+ i)) (foreach z next (build_retlist z)) (setq i (1- i)) ) ) ;;; (vlax-for x (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) (if (= (vla-get-isXref x) :vlax-true) (progn (setq name (vla-get-Name x)) (or (nested_p name) (setq firstLevelXrefs (cons name firstLevelXrefs)) ) (setq nested-xrefs (list name)) (setq xrefDBase (vl-catch-all-apply 'vla-get-xrefdatabase (list x))) (or (vl-catch-all-error-p xrefDBase) (vlax-for xx (vla-get-Blocks xrefDBase) (if (= (vla-get-isXref xx) :vlax-true) (setq nested-xrefs (cons (vla-get-Name xx) nested-xrefs)) ) ) ) (if (cdr nested-xrefs) (setq nestList (cons (reverse nested-xrefs) nestList)) ) ) ) ) (foreach x firstLevelXrefs (setq i 0) (build_retlist x) ) (reverse retList) ) ;;; (defun c:XrefTree() (foreach x (XrefTree) (repeat (* 2 (car x)) (princ " ")) (princ (cdr x)) (princ "\n") ) (princ) ) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
GEGEMATIC Posté(e) le 22 mai 2008 Posté(e) le 22 mai 2008 Merci,C'est bien mieux, car c'est nettement plus rapide que de parcourir tous les blocs.Je note comment il récupère cette info sur l'imbrication:(102 . "{BLKREFS") : fallait y penser ... J'avais renoncé à utiliser une méthode élégante en voyant que le code suivant ne marche pas pour connaitre l'état d'imbrication, et j'ai remarqué qu'Autocad lui même s'emmêle les pinceaux d'une session à l'autre. ; **************************************************************************** ;;§/dxf/essai de retiurner des infos sur les xrefs/none ;returns a list of (xref_path block_name Resolved Referenced) ;;;>Non résolue ( ??? ) :: Ne peut pas être lue par AutoCAD. ;;;par exemple si tu es sous 2002 et que la ref est une 2004 ;;;Orpheline ( ??? ) : attachée à une autre xréf non référencée, non résolue ou non trouvée ;;;un ref imbriquée (de type attaché dans la xref que tu as dans ton dessin) et qui n'est pas résolue pour une des 3 raisons qu'ils citent ;;;(???) pour les deux derniers car je n'ai pas d'exemples ! ;;;pour l'état, c'est normalementr le code 70 : ;;; ;;;Drapeaux par type de bloc (valeurs binaires pouvant être combinées) : ;;;0 = indique qu'aucun des drapeaux suivants ne s'applique ;;;1 = bloc anonyme généré par hachure, cotation associative, d'autres opérations internes ou une application ;;;2 = ce bloc a des définitions d'attribut non constantes (ce bit n'est pas défini dans le cas contraire ou si le bloc n'a aucune définition d'attribut) ;;;4 = ce bloc est une référence externe (xréf) ;;;8 = ce bloc est un recouvrement de référence externe : ce qui veut dire superposé (sinon attaché bit = 0) ;;;16 = ce bloc a des dépendances externes : j'ai fait le test, ce bit n'est pas activé quand il devrait l'être en théorie ;;;32 = référence externe résolue ou dépendant d'une référence externe (bit ignoré à la saisie):ne permet pas de différencier une reference déchargée d'une introuvable ;;;64 = cette définition est une référence externe référencée (bit ignoré à la saisie) (defun GetXinfo ( / XrefInfo) (setq XrefInfo (list)) (setq Rewind t) (while (setq CurrBlock (tblnext "block" Rewind)) (setq Rewind nil) (setq Flags (cdr (assoc 70 CurrBlock))) (if (= (boole 1 Flags 4) 4) ; that means that this block in an xref (progn (print currblock) (setq NewXref (list (cdr (assoc 1 CurrBlock)) (cdr (assoc 2 CurrBlock)) (if (= (boole 1 Flags 32) 32) T nil ) ; that means that this block is a RESOLVED xref (if (= (boole 1 Flags 64) 64) T nil ) ; that means that this block is a REFERENCED xref ) ; list ) ; setq (setq XrefInfo (cons NewXref XrefInfo)) ) ; progn ) ; if block is an xref ) ; while XrefInfo ) ; defun ----------------------------------------------------------------------Site: https://www.g-eaux.frBlog: http://g-eaux.over-blog.com
GEGEMATIC Posté(e) le 28 novembre 2018 Posté(e) le 28 novembre 2018 Salut à tous,je m’aperçoit que la fonction (3listes_xref )ne marche plus (ou pas, je ne suis pas sur qu'elle ait été bien testée en 2008) avec une version 2015 et des xref imbriquées. ce qui plante c'est la ligne (if (setq tmp (assoc name xref-lst1)) ;_ s'il est déjà dans la liste des références parenteson a l'erreur suivante:"liste d'associations incorrecte: (\"P.DIR.R+1.F\" (\"P.DIR.R+1.F\" \"R+1 APD\" \"CZ DCE BAT1-2-3-4 \"))" dans mon cas, P.DIR.R+1.F contient également des xref imbriquées non résolues. de même la commande DETACH_NONVALIDES ne marche plus. Commande: DETACH_NONVALIDES"Erreur Automation Clé dupliquée" Ce qui est fout c'est que j'ai essayé de me replonger la dedans, mais je n'y comprend plus rien !10 ans ont passé ...a+gégé ----------------------------------------------------------------------Site: https://www.g-eaux.frBlog: http://g-eaux.over-blog.com
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant