KRBeckman Posted March 10, 2010 Posted March 10, 2010 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? Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 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)) Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 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? Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 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 Not sure what you mean about the attributes though? Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 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)) Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 Ahh.. sod's law that you want the other option that I suggested 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. Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 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? Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 Ahh.. sod's law that you want the other option that I suggested 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 Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 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)) Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 It does exactly what I asked, but I forgot to ask for one additional thing. I also need it to delete the original blocks. Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 Perfect. Thanks a ton again... Someday hopefully I'll understand what's going on in some of the code you write. Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 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 Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 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. Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 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] Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 Great explaining! Thanks Marco, I'm glad it helps Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 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 Quote
Lee Mac Posted March 10, 2010 Posted March 10, 2010 Anything non-nil is deemed to be true, hence the only way for the IF statement to fail is for the selection set to be empty and hence return nil. Quote
KRBeckman Posted March 10, 2010 Author Posted March 10, 2010 really??? whoa, never knew you could do it that way. Quote
Recommended Posts
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.