Exclure xrefs de la sélection des blocs

Exclure xrefs de la sélection des blocs

Anonymous
Non applicable
501 Visites
4 Réponses
Message 1 sur 5

Exclure xrefs de la sélection des blocs

Anonymous
Non applicable

Hello,

 

J'ai fait ce script qui supprime les points dans le dessin et à l'intérieur des blocs.

Il fonctionne très bien tant qu'il n'y a pas de xrefs...

 

Est-ce que vous savez comment faire pour supprimer les xrefs de la sélection ?

 

(defun c:DELPOINTS () 

(setq points (ssget "_x" '((0 . "POINT"))))
(command "_ERASE" points "")


(vl-load-com) ; chargement vl
(setq blocs (ssget "_x" '((0 . "INSERT")))) ; sélection de tous les blocs dans le dessin
(setq nblocs (sslength blocs)) ; calcul du nombre de blocs

(repeat nblocs ; boucle d'itération
  (setq nblocs (1- nblocs)) ; incrémentation

   (setq name (ssname blocs nblocs)) ; récupération du Ename du bloc à l'indice spécifique        
   (setq sbn (vla-get-effectivename (vlax-ename->vla-object name))) ; obtention du nom réel
   (command "-modifbloc" sbn) ; ouverture du bloc à l'indice spécifique
   (if (setq dp (ssget "_X" '((0 . "POINT")))) ; s'il y a des points suppresion de ceux ci
    (command "_ERASE" dp "" "fermerbloc" "E") ; suppresion et fermeture du blocs quand il y a des points
    (command "fermerbloc") ; fermeture du bloc s'il n'a pas de points
   )
   
)


)

 

D'avance merci beaucoup !

0 J'aime
Solutions acceptées (1)
502 Visites
4 Réponses
Replies (4)
Message 2 sur 5

_gile
Consultant
Consultant

Salut,

 

Avec la méthode que tu emploies (sélection dans le dessin et appels de commande), il faut filtrer les références de bloc qui ne sont pas des Xrefs.

Un moyen consiste à parcourir la table des blocs (qui contient aussi les Xrefs et les blocs dépendant des Xrefs) et de ne retenir que les noms des blocs qui ne sont pas une Xref ou ne dépendent pas d'une Xref. Dans la liste retournée par tblnext, le groupe 70 contient un "drapeau" qui, lorsqu'il est supérieur à 4, indique que le bloc est une Xref ou dépend d'une Xref.

 

 

(defun c:DELPOINTS (/ points nomsBlocs defBloc blocs nblocs name sbn dp)
  (setq points (ssget "_x" '((0 . "POINT"))))
  (command "_ERASE" points "")

  ;; on parcourt la table des blocs pour ne conserver que les noms des blocs qui ne sont pas des xrefs
  (setq nomsBlocs "")
  (while (setq defBloc (tblnext "BLOCK" (not defBloc)))
    (if	(< (cdr (assoc 70 defBloc)) 4)	; si le drapeau est égal ou supérieir à 4, c'est une xref
      (setq nomsBlocs (strcat nomsBlocs (cdr (assoc 2 defBlocs))))
    )
  )

  (vl-load-com)				; chargement vl
  (setq blocs (ssget "_x" (list '(0 . "INSERT") (cons 2 nomsBlocs)))); sélection de tous les blocs dans le dessin
  (setq nblocs (sslength blocs))	; calcul du nombre de blocs

  (repeat nblocs			; boucle d'itération
    (setq nblocs (1- nblocs))		; incrémentation
    (setq name (ssname blocs nblocs))	; récupération du Ename du bloc à l'indice spécifique        
    (setq sbn (vla-get-effectivename (vlax-ename->vla-object name))) ; obtention du nom réel
    (command "-modifbloc" sbn)		; ouverture du bloc à l'indice spécifique
    (if	(setq dp (ssget "_X" '((0 . "POINT")))) ; s'il y a des points suppresion de ceux ci
      (command "_ERASE" dp "" "fermerbloc" "E") ; suppresion et fermeture du blocs quand il y a des points
      (command "fermerbloc")		; fermeture du bloc s'il n'a pas de points
    )
  )
)

Une autre méthode consiste à traiter directement les définitions de blocs (et les espaces objet et papier qui sont aussi considérés comme des définitions de bloc).

 

Visual LISP (interface COM/ActiveX) permet de faire ça assez facilement :

 

(defun delPoints (/ acdoc)
  (vl-load-com)
  (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object))) ;_ le document courant
  (vlax-for blk	(vla-get-Blocks acdoc) ;_ pour toutes les définitions de bloc du document (y compris les espaces)
    (if	(= (vla-get-IsXref blk) :vlax-false) ;_ si la définition n'est pas une Xref
      (vlax-for	obj blk ;_ pour tous les objets dans la définition
	(if (= (vla-get-ObjectName obj) "AcDbPoint") ;_ si l'objet est un point
	  (vla-Delete obj) ;_ on le supprime
	)
      )
    )
  )
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 sur 5

Anonymous
Non applicable

Merci beaucoup pour ta réponse !

J'ai essayé les deux scripts mais il n'arrivent pas à supprimer les points à l'intérieur des blocs...

Est ce que c'est normal ?

0 J'aime
Message 4 sur 5

_gile
Consultant
Consultant
Solution acceptée

Oupss !...

Il y avait effectivement deux erreurs dans le premier code et le second ne régénérait pas le dessin.

 

(defun c:DELPOINTS (/ points nomsBlocs defBloc blocs nblocs name sbn dp)
  (setq points (ssget "_x" '((0 . "POINT"))))
  (command "_ERASE" points "")

  ;; on parcourt la table des blocs pour ne conserver que les noms des blocs qui ne sont pas des xrefs
  (setq nomsBlocs "")
  (while (setq defBloc (tblnext "BLOCK" (not defBloc)))
    (if	(< (cdr (assoc 70 defBloc)) 4)	; si le drapeau est égal ou supérieir à 4, c'est une xref
      (setq nomsBlocs (strcat nomsBlocs (cdr (assoc 2 defBloc))","))
    )
  )

  (vl-load-com)				; chargement vl
  (setq blocs (ssget "_x" (list '(0 . "INSERT") (cons 2 nomsBlocs)))); sélection de tous les blocs dans le dessin
  (setq nblocs (sslength blocs))	; calcul du nombre de blocs

  (repeat nblocs			; boucle d'itération
    (setq nblocs (1- nblocs))		; incrémentation
    (setq name (ssname blocs nblocs))	; récupération du Ename du bloc à l'indice spécifique        
    (setq sbn (vla-get-effectivename (vlax-ename->vla-object name))) ; obtention du nom réel
    (command "-modifbloc" sbn)		; ouverture du bloc à l'indice spécifique
    (if	(setq dp (ssget "_X" '((0 . "POINT")))) ; s'il y a des points suppresion de ceux ci
      (command "_ERASE" dp "" "fermerbloc" "E") ; suppresion et fermeture du blocs quand il y a des points
      (command "fermerbloc")		; fermeture du bloc s'il n'a pas de points
    )
  )
)
(defun c:delPoints (/ acdoc)
  (vl-load-com)
  (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object))) ;_ le document courant
  (vlax-for blk	(vla-get-Blocks acdoc) ;_ pour toutes les définitions de bloc du document (y compris les espaces)
    (if	(= (vla-get-IsXref blk) :vlax-false) ;_ si la définition n'est pas une Xref
      (vlax-for	obj blk ;_ pour tous les objets dans la définition
	(if (= (vla-get-ObjectName obj) "AcDbPoint") ;_ si l'objet est un point
	  (vla-Delete obj) ;_ on le supprime
	)
      )
    )
  )
  (vla-Regen acdoc acAllViewports)
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 sur 5

Anonymous
Non applicable

Génial merci beaucoup !

Maintenant je vais regarder ça au ralenti pour comprendre 😉

0 J'aime