Jump to content

Reset all blocks in drawing


KRBeckman

Recommended Posts

Sometimes when I'm creating my drawings I have to rotate a block to fit the application better, which is fine for the current drawing, but if I want to use that drawing as a base to create another drawing I need the block "un-rotated". Is there a way to re-insert all blocks at point (0,0,0) and a rotation angle of 0?

Link to comment
Share on other sites

  • Replies 20
  • Created
  • Last Reply

Top Posters In This Topic

  • Lee Mac

    11

  • KRBeckman

    9

  • MarcoW

    1

Popular Days

Top Posters In This Topic

I suppose you could go about it in two ways, using the blocks in the block table (may include blocks that aren't present in the drawing but have not been purged), or use the blocks that are visible. I suppose it depends on what you want to achieve.

 

This uses the blocks in the block table, inserting them into ModelSpace.

 

(defun c:ReInsertAll (/ GetName Blocks)
 (vl-load-com)

 (setq GetName (lambda (obj) (if (vlax-property-available-p obj 'EffectiveName)
                               (vla-get-EffectiveName obj)
                               (vla-get-Name obj))))

 (vlax-for obj (vla-get-Blocks
                 (setq doc (vla-get-ActiveDocument
                             (vlax-get-acad-object))))

   (if (and (zerop (vlax-get obj 'isLayout))
            (zerop (vlax-get obj 'isXref)))
     (setq Blocks (cons (GetName obj) Blocks))))

 (foreach x Blocks
   (vla-InsertBlock (vla-get-ModelSpace doc)
     (vlax-3D-point '(0 0 0)) x 1. 1. 1. 0.))

 (princ))

Link to comment
Share on other sites

Lee Mac, thanks a ton, this is very close to what I'm looking for... how would you filter what blocks get re-inserted so that only the ones that are in modelspace have this done. Also, how hard would it be to retain any attribute definitions?

Link to comment
Share on other sites

Lee Mac, thanks a ton, this is very close to what I'm looking for... how would you filter what blocks get re-inserted so that only the ones that are in modelspace have this done. Also, how hard would it be to retain any attribute definitions?

 

Ahh.. sod's law that you want the other option that I suggested :D

 

Not sure what you mean about the attributes though?

Link to comment
Share on other sites

How about this?

 

(defun c:ReInsertAll (/ GetName Blocks ss)
 (vl-load-com)

 (setq GetName (lambda (obj) (if (vlax-property-available-p obj 'EffectiveName)
                               (vla-get-EffectiveName obj)
                               (vla-get-Name obj))))

 (if (ssget "_X" '((0 . "INSERT") (410 . "Model")))
   (progn
     (vlax-for obj (setq ss (vla-get-ActiveSelectionSet
                              (setq doc (vla-get-ActiveDocument
                                          (vlax-get-acad-object)))))
       
       (if (not (vl-position (setq Nme (GetName obj)) Blocks))
         (setq Blocks (cons Nme Blocks))))
     
     (vla-delete ss)

     (foreach x Blocks
       (vla-InsertBlock (vla-get-ModelSpace doc)
         (vlax-3D-point '(0 0 0)) x 1. 1. 1. 0.))))
 
 (princ))

     

Link to comment
Share on other sites

Ahh.. sod's law that you want the other option that I suggested :D

 

Always seems to happen that way...

 

Not sure what you mean about the attributes though?

 

The blocks that are being re-inserted have attributes tagged to them, ie. Part Number, Description, etc., that get filled out after the block is inserted. I would like to extract the attribute definitions before deleting the old blocks, and then apply those definitions to the same tags in the new blocks.

Link to comment
Share on other sites

The blocks that are being re-inserted have attributes tagged to them, ie. Part Number, Description, etc., that get filled out after the block is inserted. I would like to extract the attribute definitions before deleting the old blocks, and then apply those definitions to the same tags in the new blocks.

 

Oh I see. Currently the code is inserting each block only once - which is why I questioned the remark about attributes. So I suppose you want to reinsert every instance of every block at '(0 0 0), am I correct?

Link to comment
Share on other sites

Ahh.. sod's law that you want the other option that I suggested :D

 

Not sure what you mean about the attributes though?

 

Oh I see. Currently the code is inserting each block only once - which is why I questioned the remark about attributes. So I suppose you want to reinsert every instance of every block at '(0 0 0), am I correct?

 

Guess I'm not really sure how it works... I can have multiple attributes per block. I've attached an example, if you look at the properties of the 3-d block there will be 10-ish attributes and 2 for the 2-d block, that can be different for each instance of the block that's inserted.

Attribute Example.dwg

Link to comment
Share on other sites

If I've understood, give this a shot:

 

(defun c:ReInsertAll (/ GetName Blocks ss Model Var Obj)
 (vl-load-com)

 (setq GetName (lambda (obj) (if (vlax-property-available-p obj 'EffectiveName)
                               (vla-get-EffectiveName obj)
                               (vla-get-Name obj))))

 (if (ssget "_X" '((0 . "INSERT") (410 . "Model")))
   (progn
     (vlax-for obj (setq ss (vla-get-ActiveSelectionSet
                              (setq doc (vla-get-ActiveDocument
                                          (vlax-get-acad-object)))))

       (setq Blocks
         (cons
           (list (GetName obj) obj
                 (if (eq :vlax-true (vla-get-HasAttributes obj))
                   (mapcar
                     (function
                       (lambda (attrib) (cons (vla-get-TagString attrib)
                                              (vla-get-TextString attrib))))
                     
                     (vlax-invoke obj 'GetAttributes))))

           Blocks)))
     
     (vla-delete ss)
     (setq Model (vla-get-ModelSpace doc) Var (vlax-3D-point '(0 0 0)))

     (foreach x Blocks
       (setq Obj (vla-InsertBlock Model Var (car x) 1. 1. 1. 0.))
       (vla-delete (cadr x))
       
       (if (and (caddr x)
                (eq :vlax-true (vla-get-HasAttributes Obj)))
         
         (foreach att (vlax-invoke obj 'GetAttributes)
           (if (setq tag (assoc (vla-get-TagString att) (caddr x)))
             (vla-put-TextString att (cdr tag))))))))        
 
 (princ))

Link to comment
Share on other sites

It does exactly what I asked, but I forgot to ask for one additional thing. I also need it to delete the original blocks.

Link to comment
Share on other sites

Perfect. Thanks a ton again... Someday hopefully I'll understand what's going on in some of the code you write.

Link to comment
Share on other sites

Perfect. Thanks a ton again... Someday hopefully I'll understand what's going on in some of the code you write.

 

You're welcome, if you do have trouble understanding the code, I'd be more than happy to explain any part of it :)

Link to comment
Share on other sites

I would greatly appriciate it, the only problem is you'd have to explain the entire thing... and not just the functions, how the functions work together in certain situations to achive the disired result. You're welcome to try, but a: I don't know how easy that will be over a forum, and b: I don't know how much of it will go over my head. lol.

Link to comment
Share on other sites

This explains the function in layman's terms - I could elaborate further if you are still confused :)

 

[b][color=RED]([/color][/b][b][color=BLUE]defun[/color][/b] c:ReInsertAll [b][color=RED]([/color][/b][b][color=BLUE]/[/color][/b] GetName Blocks ss Model Var Obj[b][color=RED])[/color][/b]
 [i][color=#990099];; Define function, localise variables[/color][/i]

 [b][color=RED]([/color][/b][b][color=BLUE]vl-load-com[/color][/b][b][color=RED])[/color][/b]
 [i][color=#990099];; Load Visual LISP Functionality[/color][/i]

 [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] GetName [b][color=RED]([/color][/b][b][color=BLUE]lambda[/color][/b] [b][color=RED]([/color][/b]obj[b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]vlax-property-available-p[/color][/b] obj [b][color=DARKRED]'[/color][/b]EffectiveName[b][color=RED])[/color][/b]
                               [b][color=RED]([/color][/b][b][color=BLUE]vla-get-EffectiveName[/color][/b] obj[b][color=RED])[/color][/b]
                               [b][color=RED]([/color][/b][b][color=BLUE]vla-get-Name[/color][/b] obj[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
 [i][color=#990099];; Bound the anonymous function 'lambda' to the symbol 'GetName'[/color][/i]
 [i][color=#990099];; GetName takes one argument, a VLA-Object and returns the[/color][/i]
 [i][color=#990099];; Effective Name property (if it has one), this is used for[/color][/i]
 [i][color=#990099];; Dynamic Blocks, else the standard block name.[/color][/i]

 [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]ssget[/color][/b] [b][color=#a52a2a]"_X"[/color][/b] [b][color=DARKRED]'[/color][/b][b][color=RED]([/color][/b][b][color=RED]([/color][/b][b][color=#009900]0[/color][/b] . [b][color=#a52a2a]"INSERT"[/color][/b][b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=#009900]410[/color][/b] . [b][color=#a52a2a]"Model"[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
   [i][color=#990099];; If we can get a SelectionSet of all Blocks in ModelSpace[/color][/i]
   [i][color=#990099];; then do the following...[/color][/i]
   
   [b][color=RED]([/color][/b][b][color=BLUE]progn[/color][/b]
     [i][color=#990099];; The 'then' statement is > 1 expression, so we will[/color][/i]
     [i][color=#990099];; wrap all the expressions within 1 progn statement[/color][/i]
     [i][color=#990099];; so that it may be taken as 1 expression.[/color][/i]
     
     [b][color=RED]([/color][/b][b][color=BLUE]vlax-for[/color][/b] obj [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] ss [b][color=RED]([/color][/b][b][color=BLUE]vla-get-ActiveSelectionSet[/color][/b]
                              [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] doc [b][color=RED]([/color][/b][b][color=BLUE]vla-get-ActiveDocument[/color][/b]
                                          [b][color=RED]([/color][/b][b][color=BLUE]vlax-get-acad-object[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
       [i][color=#990099];; Vlax-for is equivalent to 'foreach' but for VLA[/color][/i]
       [i][color=#990099];; collections. SelectionSets in VL are collections, so we[/color][/i]
       [i][color=#990099];; retrieve the active one (the one we just collected), and[/color][/i]
       [i][color=#990099];; iterate through the objects contained within. This is quicker[/color][/i]
       [i][color=#990099];; than converting each entity name in a Vanilla LISP SelSet into[/color][/i]
       [i][color=#990099];; a VLA-Object.[/color][/i]

       [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] Blocks
         [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b]
           [b][color=RED]([/color][/b][b][color=BLUE]list[/color][/b] [b][color=RED]([/color][/b]GetName obj[b][color=RED])[/color][/b] obj
                 [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]eq[/color][/b] [color=Blue][b]:vlax-true[/b][/color] [b][color=RED]([/color][/b][b][color=BLUE]vla-get-HasAttributes[/color][/b] obj[b][color=RED])[/color][/b][b][color=RED])[/color][/b]
                   [b][color=RED]([/color][/b][b][color=BLUE]mapcar[/color][/b]
                     [b][color=RED]([/color][/b][b][color=BLUE]function[/color][/b]
                       [b][color=RED]([/color][/b][b][color=BLUE]lambda[/color][/b] [b][color=RED]([/color][/b]attrib[b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]vla-get-TagString[/color][/b] attrib[b][color=RED])[/color][/b]
                                              [b][color=RED]([/color][/b][b][color=BLUE]vla-get-TextString[/color][/b] attrib[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
                     
                     [b][color=RED]([/color][/b][b][color=BLUE]vlax-invoke[/color][/b] obj [b][color=DARKRED]'[/color][/b]GetAttributes[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]

           Blocks[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
     [i][color=#990099];; Here we are making a list of all the blocks in the SelectionSet[/color][/i]
     [i][color=#990099];; the list contains the Block Name (as retrieved by our GetName function),[/color][/i]
     [i][color=#990099];; the Block object (so that we may delete it later), and, if there are any[/color][/i]
     [i][color=#990099];; attributes, an associated list of Attribute Tags and their respective values.[/color][/i]
     [i][color=#990099];; The list would look something like:[/color][/i]
     [i][color=#990099];; '((<blockname> <VLA-Object> (("TAG1" . "VALUE1") ("TAG2" . "VALUE2"))) ...)[/color][/i]
     [i][color=#990099];; for an attributed block and:[/color][/i]
     [i][color=#990099];; '((<blockname> <VLA-Object> nil) ...)[/color][/i]
     [i][color=#990099];; for a non-attributed block.[/color][/i]
     
     [b][color=RED]([/color][/b][b][color=BLUE]vla-delete[/color][/b] ss[b][color=RED])[/color][/b]
     [i][color=#990099];; We now delete the SelectionSet object from the Collection of all SelectionSets[/color][/i]
     [i][color=#990099];; as we are now finished with it.[/color][/i]
     
     [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] Model [b][color=RED]([/color][/b][b][color=BLUE]vla-get-ModelSpace[/color][/b] doc[b][color=RED])[/color][/b] Var [b][color=RED]([/color][/b][b][color=BLUE]vlax-3D-point[/color][/b] [b][color=DARKRED]'[/color][/b][b][color=RED]([/color][/b][b][color=#009900]0[/color][/b] [b][color=#009900]0[/color][/b] [b][color=#009900]0[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
     [i][color=#990099];; Here I bound the ModelSpace block and origin (as a variant) to variables[/color][/i]
     [i][color=#990099];; to save me from having to collect them in the foreach loop, making the[/color][/i]
     [i][color=#990099];; program quicker.[/color][/i]

     [b][color=RED]([/color][/b][b][color=BLUE]foreach[/color][/b] x Blocks
       [i][color=#990099];; For every block that we have listed...[/color][/i]
       
       [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] Obj [b][color=RED]([/color][/b][b][color=BLUE]vla-InsertBlock[/color][/b] Model Var [b][color=RED]([/color][/b][b][color=BLUE]car[/color][/b] x[b][color=RED])[/color][/b] [b][color=#009999]1.[/color][/b] [b][color=#009999]1.[/color][/b] [b][color=#009999]1.[/color][/b] [b][color=#009999]0.[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
       [i][color=#990099];; Insert a block with the same name into ModelSpace with a scale of 1.0[/color][/i]
       [i][color=#990099];; and rotation of 0.0. Notice we use (car x) to retrieve the block name.[/color][/i]
       
       [b][color=RED]([/color][/b][b][color=BLUE]vla-delete[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]cadr[/color][/b] x[b][color=RED])[/color][/b][b][color=RED])[/color][/b]
       [i][color=#990099];; Delete the old block (second item in our collected list).[/color][/i]
       
       [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]and[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]caddr[/color][/b] x[b][color=RED])[/color][/b]
                [b][color=RED]([/color][/b][b][color=BLUE]eq[/color][/b] [color=Blue][b]:vlax-true[/b][/color] [b][color=RED]([/color][/b][b][color=BLUE]vla-get-HasAttributes[/color][/b] Obj[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
         [i][color=#990099];; If we have collected some attributes for this block[/color][/i]
         [i][color=#990099];; AND the block we have just inserted has attributes...[/color][/i]
         
         [b][color=RED]([/color][/b][b][color=BLUE]foreach[/color][/b] att [b][color=RED]([/color][/b][b][color=BLUE]vlax-invoke[/color][/b] obj [b][color=DARKRED]'[/color][/b]GetAttributes[b][color=RED])[/color][/b]
           [i][color=#990099];; For every attribute in the newly inserted block[/color][/i]
           [i][color=#990099];; (this is like using (entnext) until reaching a "SEQEND"[/color][/i]
           [i][color=#990099];; but the (vlax-invoke obj 'GetAttributes) gets a list[/color][/i]
           [i][color=#990099];; of all the attributes in one go).[/color][/i]
           
           [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] tag [b][color=RED]([/color][/b][b][color=BLUE]assoc[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]vla-get-TagString[/color][/b] att[b][color=RED])[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]caddr[/color][/b] x[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
             [i][color=#990099];; If the attribute tag appears in the list of attributes[/color][/i]
             [i][color=#990099];; we collected earlier. (This is like getting a DXF code[/color][/i]
             [i][color=#990099];; from the return of 'entget' ).[/color][/i]
             
             [b][color=RED]([/color][/b][b][color=BLUE]vla-put-TextString[/color][/b] att [b][color=RED]([/color][/b][b][color=BLUE]cdr[/color][/b] tag[b][color=RED])[/color][/b][b][color=RED])[/color][/b]
             [i][color=#990099];; Then set the Value of the new attribute to the value[/color][/i]
             [i][color=#990099];; we collected earlier.[/color][/i]

           [b][color=RED])[/color][/b] [i][color=#990099]; IF[/color][/i]
           
         [b][color=RED])[/color][/b] [i][color=#990099]; FOREACH[/color][/i]

       [b][color=RED])[/color][/b] [i][color=#990099]; IF[/color][/i]

     [b][color=RED])[/color][/b] [i][color=#990099]; FOREACH[/color][/i]

   [b][color=RED])[/color][/b] [i][color=#990099]; PROGN[/color][/i]
   
 [b][color=RED])[/color][/b] [i][color=#990099]; IF[/color][/i]
 
 [b][color=RED]([/color][/b][b][color=BLUE]princ[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
[i][color=#990099];; Exit Cleanly[/color][/i]

Link to comment
Share on other sites

Probably my first of many questions, but in this line:

 

 [b][color=red]([/color][/b][b][color=blue]if[/color][/b] [b][color=red]([/color][/b][b][color=blue]ssget[/color][/b] [b][color=#a52a2a]"_X"[/color][/b] [b][color=darkred]'[/color][/b][b][color=red]([/color][/b][b][color=red]([/color][/b][b][color=#009900]0[/color][/b] . [b][color=#a52a2a]"INSERT"[/color][/b][b][color=red])[/color][/b] [b][color=red]([/color][/b][b][color=#009900]410[/color][/b] . [b][color=#a52a2a]"Model"[/color][/b][b][color=red])[/color][/b][b][color=red])[/color][/b][b][color=red])[/color][/b]
   [i][color=#990099];; If we can get a SelectionSet of all Blocks in ModelSpace[/color][/i]
   [i][color=#990099];; then do the following...[/color][/i]

 

I'm confused, there aren't any comparison functions, like = or

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