Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Fast and Efficient Way to Delete a Large Number of Objects from a Drawing?

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
JC_BL
4115 Views, 8 Replies

Fast and Efficient Way to Delete a Large Number of Objects from a Drawing?

I need to find a way to quickly and efficiently delete a large number of objects from a drawing that are not in some specific layers.

 

Basically what I want to do is to reduce the drawing size in order to make sure it is small enough to be opened in AutoCAD 360 web site (max size allowed is 15MB), and also remove objects from the drawing that are not relevant to what the users want to see through AutoCAD 360.

 

Currently the method that I have chosen is to move the objects that I want to keep into a list of specific layers, thraw all layers and then I freeze those specific layers.  Finally I use a loop to select all the objects that are not on the frozen layers and delete each one by one.  All the steps run very fast except for the loop - It runs very slow.  This is OK for small drawings.  But when the drawing is big.  The loop becomes too slow and I have never been able to see it complete; after one hour I have to terminate AutoCAD.

 

The following is the program:

 

;All the layers have been thraw before we come here.
;All the objects that we want to keep have already been moved
;to the specific layers.

;Freeze all the specific layers that we want to keep.  These steps run fast.
(command "-layer" "freeze" "ABCInc-Productivity-*" "")
(command "-layer" "freeze" "ABCInc-Supply*"        "")
(command "-layer" "freeze" "ABCInc-Return*"        "")
(command "-layer" "freeze" "ABCInc-Exhaust*"       "")
(command "-layer" "freeze" "ABCInc-Relief*"        "")

;Delete all objects that are not on the specific layers.
(setq ssAllNotFrozen (ssget "_A"))   ;This step runs fast.
(if ssAllNotFrozen                   ;The selection-set has 606872 objects
   (repeat (sslength ssAllNotFrozen) ;This loop is very _s_l_o_w_.
      (entdel (ssname ssAllNotFrozen 0))
      (ssdel  (ssname ssAllNotFrozen 0) ssAllNotFrozen)
   )
)

 

 

Please let me know how to speed up the process or suggest an alternative.  Thanks in advance for any help.

 

Jay Chan

8 REPLIES 8
Message 2 of 9
bhull1985
in reply to: JC_BL

Yeah I think you'd be able to speed up that routine.

Here's a link to some pertinent information on the afralisp website.

About two thirds down the page you will see an example using the visual lisp method to delete items, try it out in your code!

http://www.afralisp.net/visual-lisp/tutorials/selection-sets.php

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Please use code tags and credit where credit is due. Accept as solution, if solved. Let's keep it trim people!
Message 3 of 9
Lee_Mac
in reply to: JC_BL

Note that the method you are using to iterate over the selection set is incredibly inefficient, as each entity in the set is moved down to a lower index for every iteration of the repeat loop; for more efficient methods, see my tutorial on Selection Set Processing.

 

However, for your case, it may be faster to simply iterate over the drawing database, e.g.:

 

(defun c:delobjs nil
    (vlax-for b (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
        (if (= :vlax-false (vla-get-isxref b))
            (vlax-for o b
                (if (and (not (wcmatch (vla-get-layer o) "ABCInc-Productivity-*,ABCInc-Supply*,ABCInc-Return*,ABCInc-Exhaust*,ABCInc-Relief*"))
                         (vlax-write-enabled-p o)
                    )
                    (vla-delete o)
                )
            )
        )
    )
    (princ)
)
(vl-load-com) (princ)
Message 4 of 9
JC_BL
in reply to: Lee_Mac

Thanks for telling me that using a loop to delete objects one by one is very inefficient. And thanks for giving me an idea to delete the whole selection-set all at onces. I use the command (command "erase" ssAllNotFrozen "") to replace the loop, and the program can delete all 607K objects very quickly.

I didn't use your direct way to select and delete the objects without freezing the objects first because when I saw the dual loops I got scared. Having said this, I make a note on this in case I work on a different project that doesn't want me to freeze/thraw layers all the time.
Message 5 of 9
JC_BL
in reply to: bhull1985

Thanks for your quick reply.  I have been reading the articles in your web site from time to time.  I really like your web site.

 

I decided not to use the (vla-delete) because I am under the impression that I need to use the corresponding (vla-get-selectionsets) command to create the selection-set.  Unfortunately I am not familiar with both commands.  Therefore, I stick with my original way of selecting the objects (that I understand) and use the (command "erase" ssSelectionSet "") command to get rid of the large number of objects.

 

Thanks again.

 

Jay Chan

Message 6 of 9
Kent1Cooper
in reply to: JC_BL


@jchan wrote:
..... I use the command (command "erase" ssAllNotFrozen "")..., and the program can delete all 607K objects very quickly.
....

I was on the verge of suggesting that, but hesitated because I wondered whether you might have things you would want to get rid of in different Paper Space layouts as well as probably in Model Space.  If so, you would need to switch to each space in order to use the Erase command, which will only "see" things in the current space [whereas (entdel) can remove things in any space].  But if it's all in Model Space, and that's where you are when you call it up, that's probably the simplest way.

Kent Cooper, AIA
Message 7 of 9
JC_BL
in reply to: Kent1Cooper

Luckily for me, I only need to deal with Model space.  I don't concern anything in the layouts.  Therefore, the simple command works fine for me.

 

Thanks for replying.

 

Jay Chan

Message 8 of 9
Lee_Mac
in reply to: JC_BL


@jchan wrote:

I didn't use your direct way to select and delete the objects without freezing the objects first because when I saw the dual loops I got scared. Having said this, I make a note on this in case I work on a different project that doesn't want me to freeze/thraw layers all the time.

No problem -

 

For completeness, the nested vlax-for loops are used to enable the program to delete the required objects in all drawing layouts and within all blocks & nested blocks (nested to any depth); since, when using the ERASE command, you are restricted to deleting only primary objects in the active layout or viewport. Of course, for processing only primary objects in modelspace, only a single vlax-for loop would be required to iterate over the objects contained in the modelspace block.

 

To provide other advantages & disadvantages, by using the ActiveX methods of Visual LISP, the function becomes comptible for use through an ObjectDBX interface, should you wish to batch process a number of drawings, whereas, when using the ERASE command, an AutoCAD Script must be used for batch processing.

 

Lee

Message 9 of 9
JC_BL
in reply to: Lee_Mac

Thanks for pointing out the use of ObjectDBX is good for batch processing drawings.  I didn't know that.  Actually what my current project is exactly doing batch processing drawings.  If I could start this project all over again, I would have investigate the use of ObjectDBX instead of using an AutoCAD startup script to process each drawing one by one.  I make a note on this for future use.

 

Jay Chan

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost