Aller au contenu

Détacher XREFS imbriqués et réf croisées


sergeluc

Messages recommandés

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 finir

des 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 .

Lien vers le commentaire
Partager sur d’autres sites

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 listes

lst : les noms de toutes les Xrefs du dessin

lst1 : 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

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

  • 1 an après...

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.fr

Blog: http://g-eaux.over-blog.com

Lien vers le commentaire
Partager sur d’autres sites

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 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

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.fr

Blog: http://g-eaux.over-blog.com

Lien vers le commentaire
Partager sur d’autres sites

  • 10 ans après...

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 parentes

on 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.fr

Blog: http://g-eaux.over-blog.com

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é