"NUKE" lisp?

"NUKE" lisp?

Netelaana
Enthusiast Enthusiast
4,223 Views
25 Replies
Message 1 of 26

"NUKE" lisp?

Netelaana
Enthusiast
Enthusiast

I have a CAD file with a couple layouts. I need to reduce the model & layouts content to its constituent parts without loosing visible information. Manually I go about it in this way:

 

1. select all

     -burst

          -repeat until no more items to burst

2. select all 

     - explode (ideally blocks explode onto the blocks layer not "0")

3. repeat 1&2 until no more items to burst or explode. 

4. repeat 1-3 for each layout

5. purge all

6. audit - fix errors

 

This seems an ideal job for a LISP that might aptly be named "NUKE"

Something along the lines of lee mac http://www.lee-mac.com/upgradedburst.html makes me think it should be possible. 

 

As one can imagine, this process takes quite a bit of time. Any help would be greatly appreciated,

 

Thanks!

0 Likes
4,224 Views
25 Replies
Replies (25)
Message 2 of 26

devitg
Advisor
Advisor

@Netelaana Would you, please upload a sample DWG ?

0 Likes
Message 3 of 26

pendean
Community Legend
Community Legend
Old School tip if you truly and genuinely need a "nuked" file.

Set up a DXB plotter.
Plot to DXB in that file, use the MONOCHROME plot style table.
Open a blank file, then DXBIN

You will get the 100% totally nuked DWG file on the planet that no one will every be able to use but can still see all of your information.

You are welcome.
0 Likes
Message 4 of 26

Kent1Cooper
Consultant
Consultant

@Netelaana wrote:

.... I need to reduce the model & layouts content to its constituent parts without loosing visible information. ....


Just a thought....  The procedure you outline will  lose certain kinds of visible information.  Do you ever use Polylines with width?  Exploding them will leave Lines and Arcs without  width.  There may be other things similarly affected.

Kent Cooper, AIA
0 Likes
Message 5 of 26

Netelaana
Enthusiast
Enthusiast

Thanks! I'll tuck that one into the toolbelt. I gave it a try, but it does not seem to work for this situation, ie publishing/ on the whole cad file?   I can only plot one layout at a time, which is only slightly faster than the manual method I currently use. It also forces everything to layer 0.

 

My goal is not to make it "non-usable" - on the contrary, I need to keep the dwg intact and usable with all layouts & layers  intact - it just needs to be in its most basic form (no blocks, polylines, etc).

 

The end goal is to have a cad file that can be edited, plotted, and published to a pdf that is (more or less) indistinguishable (ie pdf looks the same) from the original, but the entities in the CAD file are in their most basic form (just lines, arcs, & text). 

 

Thanks for your thoughts!

Message 6 of 26

Netelaana
Enthusiast
Enthusiast

Yes, I do lose pl width, but we rely primarily on color dependent plotting (hence keeping layers/colors intact is needed), and we rarely use set width on polylines.  On the occasion that we do have wide poly's, I don't need to keep that in my "bare bones" version. 

 

Thanks for your thoughts!

0 Likes
Message 7 of 26

Netelaana
Enthusiast
Enthusiast

Maybe my title is unhelpful - my simple goal is to automate this process:

 

1. select all, burst, repeat until no more items to burst

2. select all, explode once (ideally blocks explode onto the blocks layer not "0")

3. repeat steps 1-2 until no more items to burst or explode. 

4. repeat steps 1-3 for each layout

5. purge all (and overkill)

6. audit - fix errors

 

My cave-man attempts to smash the following lisps together and add step 4 to accomplish this has gone nowhere. 

 

;;  Author:  Lee Mac, Copyright © 2010  -  www.lee-mac.com              ;;
;;----------------------------------------------------------------------;;

(defun c:myburst nil
    (LM:startundo (LM:acdoc))
    (LM:burst
        (LM:ssget "\nSelect blocks to burst: "
            (list "_:L"
                (append '((0 . "INSERT"))
                    (
                        (lambda ( / def lst )
                            (while (setq def (tblnext "block" (null def)))
                                (if (= 4 (logand 4 (cdr (assoc 70 def))))
                                    (setq lst (vl-list* "," (cdr (assoc 2 def)) lst))
                                )
                            )
                            (if lst (list '(-4 . "<NOT") (cons 2 (apply 'strcat (cdr lst))) '(-4 . "NOT>")))
                        )
                    )
                    (if (= 1 (getvar 'cvport))
                        (list (cons 410 (getvar 'ctab)))
                       '((410 . "Model"))
                    )
                )
            )
        )
    )
    (LM:endundo (LM:acdoc))
    (princ)
)

(defun LM:burst ( sel / cmd col ent idx lay lin lst obj qaf tmp )
    (if (= 'pickset (type sel))
        (repeat (setq idx (sslength sel))
            (setq obj (vlax-ename->vla-object (ssname sel (setq	idx (1- idx))))
                  lay (vla-get-layer obj)
                  col (vla-get-color obj)
                  lin (vla-get-linetype obj)
            )
            (if (and (= "AcDbBlockReference" (vla-get-objectname obj))
                     (vlax-write-enabled-p obj)
                     (or (and (LM:usblock-p obj)
                              (not (vl-catch-all-error-p (setq lst (vl-catch-all-apply 'vlax-invoke (list obj 'explode)))))
                         )
                         (progn
                             (setq tmp (vla-copy obj)
                                   ent (LM:entlast)
                                   cmd (getvar 'cmdecho)
                                   qaf (getvar 'qaflags)
                             )
                             (setvar 'cmdecho 0)
                             (setvar 'qaflags 0)
                             (vl-cmdf "_.explode" (vlax-vla-object->ename tmp))
                             (setvar 'qaflags qaf)
                             (setvar 'cmdecho cmd)
                             (while (setq ent (entnext ent))
                                 (setq lst (cons (vlax-ename->vla-object ent) lst))
                             )
                             lst
                         )
                     )
                )
                (progn
                    (foreach att (vlax-invoke obj 'getattributes)
                        (if (vlax-write-enabled-p att)
                            (progn
                                (if (= "0" (vla-get-layer att))
                                    (vla-put-layer att lay)
                                )
                                (if (= acbyblock (vla-get-color att))
                                    (vla-put-color att col)
                                )
                                (if (= "byblock" (strcase (vla-get-linetype att) t))
                                    (vla-put-linetype att lin)
                                )
                            )
                        )
                        (if (= :vlax-false (vla-get-invisible att))
                            (   (if (and (vlax-property-available-p att 'mtextattribute) (= :vlax-true (vla-get-mtextattribute att)))
                                    LM:burst:matt2mtext 
                                    LM:burst:att2text
                                )
                                (entget (vlax-vla-object->ename att))
                            )
                        )
                    )
                    (foreach new lst
                        (if (vlax-write-enabled-p new)
                            (progn
                                (if (= "0" (vla-get-layer new))
                                    (vla-put-layer new lay)
                                )
                                (if (= acbyblock (vla-get-color new))
                                    (vla-put-color new col)
                                )
                                (if (= "byblock" (strcase (vla-get-linetype new) t))
                                    (vla-put-linetype new lin)
                                )
                                (if (= "AcDbAttributeDefinition" (vla-get-objectname new))
                                    (progn
                                        (if (and (= :vlax-true (vla-get-constant new)) (= :vlax-false (vla-get-invisible new)))
                                            (   (if (and (vlax-property-available-p new 'mtextattribute) (= :vlax-true (vla-get-mtextattribute new)))
                                                    LM:burst:matt2mtext 
                                                    LM:burst:att2text
                                                )
                                                (entget (vlax-vla-object->ename new))
                                            )
                                        )
                                        (vla-delete new)
                                    )
                                )
                            )
                        )
                    )
                    (vla-delete obj)
                )
            )
        )
    )
    (princ)
)

(defun LM:burst:removepairs ( itm lst )
    (vl-remove-if '(lambda ( x ) (member (car x) itm)) lst)
)

(defun LM:burst:remove1stpairs ( itm lst )
    (vl-remove-if '(lambda ( x ) (if (member (car x) itm) (progn (setq itm (vl-remove (car x) itm)) t))) lst)
)
  
(defun LM:burst:att2text ( enx )
    (entmakex
        (append '((0 . "TEXT"))
            (LM:burst:removepairs '(000 002 003 070 074 100 280)
                (subst (cons 73 (cdr (assoc 74 enx))) (assoc 74 enx) enx)
            )
        )
    )
)

(defun LM:burst:matt2mtext ( enx )
    (entmakex
        (append '((0 . "MTEXT") (100 . "AcDbEntity") (100 . "AcDbMText"))
            (LM:burst:remove1stpairs  '(001 007 010 011 040 041 050 071 072 073 210)
                (LM:burst:removepairs '(000 002 003 042 043 051 070 074 100 101 102 280 330 360) enx)
            )
        )
    )
)

;; Uniformly Scaled Block  -  Lee Mac
;; Returns T if the supplied VLA Block Reference is uniformly scaled
;; obj - [vla] VLA Block Reference

(defun LM:usblock-p ( obj / s )
    (if (vlax-property-available-p obj 'xeffectivescalefactor)
        (setq s "effectivescalefactor")
        (setq s "scalefactor")
    )
    (eval
        (list 'defun 'LM:usblock-p '( obj )
            (list 'and
                (list 'equal
                    (list 'abs (list 'vlax-get-property 'obj (strcat "x" s)))
                    (list 'abs (list 'vlax-get-property 'obj (strcat "y" s)))
                    1e-8
                )
                (list 'equal
                    (list 'abs (list 'vlax-get-property 'obj (strcat "x" s)))
                    (list 'abs (list 'vlax-get-property 'obj (strcat "z" s)))
                    1e-8
                )
            )
        )
    )
    (LM:usblock-p obj)
)

;; entlast  -  Lee Mac
;; A wrapper for the entlast function to return the last subentity in the database

(defun LM:entlast ( / ent tmp )
    (setq ent (entlast))
    (while (setq tmp (entnext ent)) (setq ent tmp))
    ent
)

;; ssget  -  Lee Mac
;; A wrapper for the ssget function to permit the use of a custom selection prompt
;; msg - [str] selection prompt
;; arg - [lst] list of ssget arguments

(defun LM:ssget ( msg arg / sel )
    (princ msg)
    (setvar 'nomutt 1)
    (setq sel (vl-catch-all-apply 'ssget arg))
    (setvar 'nomutt 0)
    (if (not (vl-catch-all-error-p sel)) sel)
)

;; Start Undo  -  Lee Mac
;; Opens an Undo Group.

(defun LM:startundo ( doc )
    (LM:endundo doc)
    (vla-startundomark doc)
)

;; End Undo  -  Lee Mac
;; Closes an Undo Group.

(defun LM:endundo ( doc )
    (while (= 8 (logand 8 (getvar 'undoctl)))
        (vla-endundomark doc)
    )
)

;; Active Document  -  Lee Mac
;; Returns the VLA Active Document Object

(defun LM:acdoc nil
    (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
    (LM:acdoc)
)

;;----------------------------------------------------------------------;;

(vl-load-com)
(princ
    (strcat
        "\n:: BurstUpgraded.lsp | Version 1.4 | \\U+00A9 Lee Mac "
        (menucmd "m=$(edtime,0,yyyy)")
        " www.lee-mac.com ::"
        "\n:: Type \"myburst\" to Invoke ::"
    )
)
(princ)

;;----------------------------------------------------------------------;;
;;                             End of File                              ;;
;;----------------------------------------------------------------------;;

and

(defun c:nuke ( / ndx bss ess nss pss)			; *** Explodes all blocks in drawing.
(setq testx (getstring "This command explodes and purges all blocks from drawing.  Hit Enter to continue or ESC to cancel"))
(setvar "cmdecho" 0)
(command "undo" "m")
	(setq 	ndx 	0
		bss	(ssget"x"'((2 . "*")))
	)
	(if bss	(progn
			(princ"\n---------------------------------------")
			(repeat (sslength bss)
				(setq	pss	(ssname bss ndx)
					ndx	(1+ ndx)
					ess	(entget pss)
					nss	(cdr (assoc 2 ess))
				)
				(princ "\nExploding block:\t ")(princ nss)
				(command "_.explode" pss)
			)
			(princ"\n---------------------------------------")
                        (princ "\n")
                        (princ)
                        (command "purge" "bl" "*" "n")
			(prompt"\nAll blocks exploded and purged!")

		)
			(alert"No blocks present in drawing.")
	)
        (setvar "cmdecho" 1) 	
	(princ)
)

(defun c:blocklist ( / pss ndx ess nss)
	(setq	bss	(ssget"x"'((2 . "*")))
		ndx	0)
	(if bss	(progn
			(textpage)
			(princ"\n----------------------------")
			(princ"\nPresent blocks in drawing: ")
			(terpri)
			(repeat (sslength bss)
				(setq	pss	(ssname bss ndx)
					ndx	(1+ ndx)
					ess	(entget pss)
					nss	(cdr (assoc 2 ess))
				)
				(terpri)(princ nss)
			)
			(princ"\n----------------------------")
		)
		(alert"No blocks present in drawing.")
	)
	(princ)
)


(princ)

and 

(defun C:CCAD ( / )

;; First we explode everything a few times...

(command ".explode" (ssget "_X" ) "")
(command ".explode" (ssget "_X" ) "")
(command ".explode" (ssget "_X" ) "")
(command ".explode" (ssget "_X" ) "")

;;define allobjects
(setq allobjects (ssget "_X" ))

;; Now OVERKILL
(command "_OVERKILL" allobjects "" "Yes" "Yes")

;; Now AUDIT
(command "_AUDIT" "Yes")

 

any help would be greatly appreciated! 

 

0 Likes
Message 8 of 26

roland.r71
Collaborator
Collaborator

Why not export to WMF, delete all & import the WMF again?

Instead of setting up plotters and what not.

 

That's how I've done it for the last 16 years, or so.

0 Likes
Message 9 of 26

roland.r71
Collaborator
Collaborator

If your goal is to have a DWG which is useless to work on, but still looks just like the Original...

 

as i just said, the by far easiest way is to export it to a wmf, delete everything and import the wmf again.

 

It will look exactly the same, including colours, line widths etc, etc.

...but even text is made up of lines now…

 

I used this method a lot in the past, when the company i worked for had to supply DWG's to companies in China.

0 Likes
Message 10 of 26

Netelaana
Enthusiast
Enthusiast

This looks like a great option for a simple model, however, the sticking point in my sequence is

 

"4. repeat 1-3 for each layout" ....I have dozens of them.

 

the goal is to keep all layouts intact (but "simplified") as well.

 

or maybe am I missing something with the wmf export- is there a way to export including layouts as well (without doing each one individually)?

 

thanks for your thoughts!

0 Likes
Message 11 of 26

roland.r71
Collaborator
Collaborator

You would need to repeat for each layout.

But that's fairly easy to do.

 

I might still have the lisp i used for it somewhere @ home .

Not that it would take a lot code to do.

 

I'll get back on that.

 

edit:

I did just notice one potential problem:

2. select all, explode once (ideally blocks explode onto the blocks layer not "0")

 

Using the export-import method with WMF's, that's probably not going to work.

0 Likes
Message 12 of 26

roland.r71
Collaborator
Collaborator

Ok, I found it, but it was a part of my "M-Tools" collection, so it won't run on its own.

Needs DOSlib too.

 

I'll extract the commands used from it, as a start & for you to see how and if it works for you.

 

 

(setq dwgname (getvar "DWGNAME"))        ; retrieve current filename
(setq path    (getvar "DWGPREFIX"))      ; retrieve current filepath
(setq wmfname (strcat (substr dwgname 1 (- (strlen dwgname) 3)) "wmf")) ; filename with WMF extention
(setq wmfexp  (strcat path wmfname))     ; WMF file path&name to export

(command "_model")                       ; Model space
(command "_zoom" "_e")                   ; zoom extents
(command "_export" wmfexp "all" "")      ; Export WMF file
(command "_erase" "all" "")              ; Clear the drawing
(command "_import" wmfexp)               ; Import WMF file
(command "_explode" "all")               ; Explode wmf block
(command "_purge" "all" "*" "N")         ; Purge all
(command "_zoom" "_e")                   ; Zoom extents
(DOS_DELETE wmfexp)                      ; Delete WMF file
(command "_save" (strcat path dwgname))  ; Save the 'flattened' DWG

 

Note: DOS_DELETE is a DOSlib command, so you need to either install DOSlib, or use/find an alternative to delete the wmf file.

 

Warning: This will overwrite the dwg. So use a copy, or change the save path and/or dwg name.

 

 

0 Likes
Message 13 of 26

roland.r71
Collaborator
Collaborator

You can use:

(vl-file-delete wmfexp)

 

instead of

(DOS_DELETE wmfexp)

 

& I could easily (re)write a new version of my lisp, to run solo & include layouts.

Although I never tested/tried it with layouts before, so I'm not sure if that will actually work as desired (yet).

0 Likes
Message 14 of 26

roland.r71
Collaborator
Collaborator

I did a quick test last night, and got it to work with layouts. The result is however not as desired. The quality of the wmf export is just to low. It works perfect with circuit diagrams in modelspace, but is already a bit lacking with layouts for circuit diagrams  (looks just like a pdf conversion). If i use a (big) construction plan nothing usefull remains.

0 Likes
Message 15 of 26

roland.r71
Collaborator
Collaborator

Re-reading your post with all the code, it sounds like the only step you didn't succeed at yet is to do it for all layouts?

 

For if that's the case, the solution would be very simple:

(foreach ltab (layoutlist)
   (setvar 'ctab ltab)
   ; --- add your code here
)

This will activate each layout in sequence. All you need to do is call your code as it works for 1 layout.

0 Likes
Message 16 of 26

Netelaana
Enthusiast
Enthusiast

Thanks for the help. I tried to keep it to the basics for starters. It seems to run through the layouts, but does not actually burst or explode anything. My coding ability is nil, so I'm not sure what the catch is.

(defun C:SIMPLIFYCAD ( / )
(foreach ltab (layoutlist)
(setvar 'ctab ltab)
(command "_pspace")                               ; paper space
(command "_zoom" "_e")                           ; zoom extents
  (setq ssAll (ssget "X" '((0 . "INSERT")))
	   drwordr (getvar "draworderctl")
  )
  (setvar "draworderctl" 0);supress warnings
  (sssetfirst nil ssAll) ;makes ssAll both gripped and selected. 
  (c:burst)
(command "_explode" "all")                       ; Explode
(command "_purge" "all" "*" "N")                 ; Purge all
(command "_zoom" "_e")                           ; Zoom extents
(command "_OVERKILL" allobjects "" "Yes" "Yes")    ;; Now OVERKILL
(command "_AUDIT")                           ;; Now AUDIT
)
)

 

my goal is simple enough:

 

1. select all, burst, repeat until no more items to burst

2. select all, explode once (ideally blocks explode onto the blocks' layer not "0")

3. repeat steps 1-2 until no more items to burst or explode.

4. repeat steps 1-3 for each layout

5. purge all (and overkill)

6. audit - fix errors

 

...I just can't seem to make it happen

0 Likes
Message 17 of 26

roland.r71
Collaborator
Collaborator

The problem here is "burst". Its not a native autocad command, but a lisp from expresstools. Those work nice from the commandline, but not from a lisp. You're already close to a solution, Lee Mac's upgraded burst, which will take care of any nested blocks as well (nburst).

 

...but you'll need to change it a bit, to bypass the manual selection part and use a selectionset.

Although acad will ignore blocks not on the current layout, it might be wise to select only blocks on the current layout.

 

However, there is one odity with you're 'workflow':

Burst is basically the same as explode, with the difference that it converts attribute values to text.

After bursting everything (your point 1) there is no block left to explode (your point 2)

0 Likes
Message 18 of 26

roland.r71
Collaborator
Collaborator

Try this:

 

(defun c:NukeDWG ( / ltab bss fnd)

   (setvar "cmdecho" 0)
   (foreach ltab (layoutlist)
      (setvar 'ctab ltab)
      (command "_zoom" "_a")                           
      (setq bss (ssget "X" (list (cons 0 "INSERT")(cons 410 ltab)))
      )
      (princ"\n---------------------------------------")
      (if bss
         (progn
            (princ (strcat "\nBursting blocks on layout: " ltab))
            (LM:burstsel bss t)
            (setq fnd t)
            (command "_explode" "all")                       
         )
         (princ (strcat "\nNo blocks found on layout: " ltab))
      )
   )
   (princ"\n---------------------------------------")
   (command "_purge" "all" "*" "N")
   (command "_OVERKILL" allobjects "" "Yes" "Yes")
   (command "_AUDIT")
   (if fnd
      (alert "\nThis drawing got Nuked!")
      (alert "No blocks present in drawing!")
   )
   (setvar "cmdecho" 1) 	
   (princ)
)

 

 

Note: For this I took a look at Lee Mac's Burst Upgraded v1.7

I'm directly calling one of the subfunctions using a selectionset, bypassing the LM:burst's own selection.

 

Currently I'm unable to test it myself.

0 Likes
Message 19 of 26

Netelaana
Enthusiast
Enthusiast

@roland.r71 wrote:

 

However, there is one odity with you're 'workflow':

Burst is basically the same as explode, with the difference that it converts attribute values to text.

After bursting everything (your point 1) there is no block left to explode (your point 2)


Thanks! The workflow I describe is what I manually have to do. For whatever reason, I can burst until there is nothing left to burst (usually 3 or 4 times), and then explode, and it will find plenty (polylines for example). Additionally, once I do explode, if I run burst again, it will pick up more items to burst (hence the repeat of that sequence), so there must also be some blocks that avoid the burst command. I think it has something to do with nested dynamic blocks with attributes. That experience has been true for most drawings I work with.

0 Likes
Message 20 of 26

Netelaana
Enthusiast
Enthusiast
(defun c:NukeDWG ( / ltab bss fnd)

 

...thanks!! I will give it a try and see how it goes.

0 Likes