Jump to content

Lisp to detach xrefs and delete layers


plackowski

Recommended Posts

We regularly export Civil3D files to CAD so we can use them in either CAD and Revit. We have run into a few problems with this workflow, since any xrefs that aren't detached before exporting become blocks in the CAD file. Additionally, Revit automatically enables all the layers when you insert the CAD file, so you have to manually disable them again. I have created a simple lisp that detaches the xrefs and deletes the listed layers using code I pulled from various forums. However, I've got two issues:

 

1. The dellayers function claims to delete the DR_X_Text layer, but the layer and the entities on that layer remain in my drawing after running the command.

2. I'd like to princ the list of removed xrefs as well, but I'm not sure where to place that code.

 

(defun c:Civil3DtoCAD  (/)
	(c:detachxrefs)
	(c:dellayers)
	(princ)
)

(defun c:dellayers (/ e)
	(foreach layer '("DR_X_Text" "_11-2606G1K-1-24" "_11-2607G1K-1-24" "_11-2608G1K-1-24")
		(if	(setq e (tblobjname "layer" layer))
			(progn
				(vl-catch-all-apply 'vla-delete (list (vlax-ename->vla-object e)))
				
				(princ "Layer ")
				(princ layer)
				(princ " deleted.\n")
			)
			(progn
				(princ "Layer ")
				(princ layer)
				(princ " not found.\n")
			)
		)
	)
	(princ)
)

(defun C:Detachall (/ *error*
	mip:layer-status-restore mip:layer-status-save
	delete-xref-img-underlay delete-all-dict
	)
	(vl-load-com)
	(defun *error* (msg)
		(mip:layer-status-restore)
		(princ msg)
		(princ)
	) ;_ end of defun
	(defun mip:layer-status-restore ()
		(foreach item *PD_LAYER_LST*
			(if (not (vlax-erased-p (car item)))
				(vl-catch-all-apply
					'(lambda ()
						(vla-put-lock (car item) (cdr (assoc "lock" (cdr item))))
						(vla-put-freeze
							(car item)
							(cdr (assoc "freeze" (cdr item)))
						) ;_ end of vla-put-freeze
					) ;_ end of lambda
				) ;_ end of vl-catch-all-apply
			) ;_ end of if
		) ;_ end of foreach
		(setq *PD_LAYER_LST* nil)
	) ;_ end of defun

	(defun mip:layer-status-save ()
		(setq *PD_LAYER_LST* nil)
		(vlax-for item (vla-get-layers
		(vla-get-activedocument (vlax-get-acad-object))
		) ;_ end of vla-get-layers
		(setq *PD_LAYER_LST*
		(cons (list item
		(cons "freeze" (vla-get-freeze item))
		(cons "lock" (vla-get-lock item))
		) ;_ end of cons
		*PD_LAYER_LST*
		) ;_ end of cons
		) ;_ end of setq
		(vla-put-lock item :vlax-false)
		(if (= (vla-get-freeze item) :vlax-true)
		(vl-catch-all-apply
		'(lambda () (vla-put-freeze item :vlax-false))
		) ;_ end of vl-catch-all-apply
		) ;_ end of if
		) ;_ end of vlax-for
	) ;_ end of defun
	(defun delete-xref-img-underlay (/ count txt)
	(mip:layer-status-save)
	(vlax-for Blk (vla-get-Blocks
	(vla-get-activedocument (vlax-get-acad-object))
	) ;_ end of vla-get-Blocks
	(if (and (= (vla-get-IsXref Blk) :vlax-false)
	(not (wcmatch (vla-get-name Blk) "*|*"))
	) ;_ end of and
	(progn
	(setq count 0
	txt (strcat " Erase Xref and Underlay in "
	(vla-get-name Blk)
	) ;_ end of strcat
	) ;_ end of setq
	(grtext -1 txt)
	(vlax-for Obj Blk
	(setq count (1+ count))
	(if (zerop (rem count 10))
	(grtext -1 (strcat txt " : " (itoa count)))
	) ;_ end of if
	(if
	(and (vlax-write-enabled-p Obj)
	(or
	(and ;_ XREF
	(= (vla-get-ObjectName obj) "AcDbBlockReference")
	(vlax-property-available-p Obj "Path")
	) ;_ end of and
	(and ;_ UNDERLAY
	(wcmatch (vla-get-ObjectName obj) "*Reference")
	(vlax-property-available-p Obj "UnderlayName")
	) ;_ end of and
	(= (vla-get-ObjectName obj) "AcDbRasterImage") ;_ IMAGE
	) ;_ end of or
	) ;_ end of and
	(VL-CATCH-ALL-APPLY 'vla-Delete (list Obj))
	) ;_ end of if
	) ;_ end of vlax-for
	) ;_ end of progn
	) ;_ end of if
	) ;_ end of vlax-for
	(mip:layer-status-restore)
	) ;_ end of defun
	(defun delete-all-dict (dict)
	;;; dict - dict name (like "ACAD_IMAGE_DICT", "ACAD_PDFDEFINITIONS" ... )
	(vl-catch-all-apply
	'(lambda ()
	(vlax-map-Collection
	(vla-item
	(vla-get-dictionaries
	(vla-get-activedocument (vlax-get-acad-object))
	) ;_ end of vla-get-dictionaries
	dict ;_ "ACAD_IMAGE_DICT"
	) ;_ end of vla-Item
	'vla-delete
	) ;_ end of vlax-map-Collection
	) ;_ end of lambda
	) ;_ end of vl-catch-all-apply
	) ;_ end of defun
	(vl-load-com)
	(delete-xref-img-underlay)
	(command "_-xref" "_d" "*")
	(while (> (getvar "CMDACTIVE") 0) (command))
	(mapcar 'delete-all-dict
	(list "ACAD_IMAGE_DICT"
	"ACAD_PDFDEFINITIONS"
	"ACAD_DWFDEFINITIONS"
	"ACAD_DGNDEFINITIONS"
	) ;_ end of list
	) ;_ end of mapcar
	(command "_.regenall")
	(command "_.externalreferences")
	(princ)
) ;_ end of defun
	


(defun c:detachxrefs ( / block-lst xref-lst nxt-blk n)
	(PROGN
		(SETQ block-lst (LIST (TBLNEXT "BLOCK" T)))
		(SETQ xref-lst NIL)
		(WHILE (SETQ nxt-blk (TBLNEXT "BLOCK"))
		(SETQ block-lst (APPEND block-lst (LIST nxt-blk)))
		) ;_ end of WHILE
		(FOREACH n block-lst
		(IF (AND (ASSOC 70 n) (EQ (BOOLE 1 4 (CDR (ASSOC 70 n))) 4))
		(SETQ xref-lst
		(APPEND
		xref-lst
		(LIST (LIST (CDR (ASSOC 2 n)) (CDR (ASSOC 1 n)))
		) ;_ end of LIST
		) ;_ end of APPEND
		) ;_ end of SETQ
		) ;_ end of IF
		) ;_ end of FOREACH
		(IF xref-lst
		(c:detachall)
		(PROGN
		(PRINC "\nNo References to Detach... ")
		(PRINC)
		)
		) ;_ end of IF
		(PRINC)
	) ;_ end of PROGN
) ;_ end of defun	

 

Link to comment
Share on other sites

I managed to resolve the first issue by using

(command-s "_.-laydel" "_N" layer "" "_Y")

instead of 

(vl-catch-all-apply 'vla-delete (list (vlax-ename->vla-object e)))

in the c:dellayers function.

 

 

I also added a purge command that runs after the layers have been deleted. However, the laydel function and the purge function both seem to override any (setvar "cmdecho" 0) I set, and they dump their outputs to the command line. Is there a way to disable their output?

Link to comment
Share on other sites

2 hours ago, plackowski said:

I also added a purge command that runs after the layers have been deleted. However, the laydel function and the purge function both seem to override any (setvar "cmdecho" 0) I set, and they dump their outputs to the command line. Is there a way to disable their output?

Take a look at the NOMUTT (System Variable) https://help.autodesk.com/view/ACD/2021/ENU/?guid=GUID-9289326E-DEE9-40E7-839C-A4B031A29B2A

Make sure it gets reset on end or error before trying any AutoCAD commands for obvious reasons.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...