Jump to content

Redefine blocks


gile

Recommended Posts

Hi,

 

Instead of multiplying links to another web site, I post here my Edit_bloc routine.

 

This function (command name: Edit_bloc) allows some changes on blocks definitions in the current drawing (the complete collection, all inserted, or a selection).

All componants of the block are edited, even nested blocks and attributes.

A dialog box allows to choose which properties shall be edited : global scale, units (only available on R2006 & R2007), componants on layer "0", color, line type, line width and plot style of componants to ByBlock.

 

With another function (Edit_bloc_rep) it's possible to edit all the dwg files (wblock) of a repertory. This one must be launched from a virgin drawing and runed with "All collection" option.

editblock.png

Edit_Bloc_3.5.zip

  • Like 1
Link to comment
Share on other sites

Hi,

 

Instead of multiplying links to another web site, I post here my Edit_bloc routine.

 

This function (command name: Edit_bloc) allows some changes on blocks definitions in the current drawing (the complete collection, all inserted, or a selection).

All componants of the block are edited, even nested blocks and attributes.

A dialog box allows to choose which properties shall be edited : global scale, units (only available on R2006 & R2007), componants on layer "0", color, line type, line width and plot style of componants to ByBlock.

 

With another function (Edit_bloc_rep) it's possible to edit all the dwg files (wblock) of a repertory. This one must be launched from a virgin drawing and runed with "All collection" option.

 

I will try it.. to check if I can modify the blocks to be "Unitless"... but if you know this lisp... you must know already... does it allow us to change this property in selected blocks?

----------------------

 

 

So, you say it also redefines selected blocks using the current scale?... I must check it out.

Link to comment
Share on other sites

I wrote this LISP and it does set the insertion unit of the selected blocks to the selected one in the popup list.

 

I just can't solve problem with changing scales on dynamic blocks (in this case you'll be alerted by a dialog box).

Link to comment
Share on other sites

I wrote this LISP and it does set the insertion unit of the selected blocks to the selected one in the popup list.

 

I just can't solve problem with changing scales on dynamic blocks (in this case you'll be alerted by a dialog box).

 

Well, I tested it... It seems it certainly change blocks units, but it does dot redefine blocks to be scale 1,1,1 from the current size... but I think I can use it for one of the 3 things I need.

 

Being honest I am not very sure if it always work, because I changed 3 testing blocks' units to none... then I change current drawing units to inches and wblock all those blocks that were supposed unitless, and when I opened extracted drawings, they were in inches units... so I think they grabbed the drawing units from the drawing they belong.

 

Then I made another test.. and changed the blocks to milimeters and extracted them from the same inches units drawings.. and extracted drawing were milimeters... so it worked in this case.. I guess I just need to make sure to work all those compilation drawings as unitless and run your lisp to all the blocks and cross fingers...

 

thanks.

 

Then I moved into playing a little some with the units... and it seems this routine only scales the blocks... but does not redefine them.. it does not keep the size. I can scale all the blocks and resize them, but to redefine them using the current size is what I am looking for.

 

What I need basically is a routine that will do this:

 

I got the blocks... some are scale 1, some scale 1.5, some other scale.. 0.254...or whatever... but I got them all inserted and sized correctly... Now I need to explode each one preserving their insertion point, name, layer, color.. everything.. just need to explode each one, then go to command block, grab own insertion point, grab own name, and select previously exploded objects.. and redefine... and voalá.. but instead of doing that by miself... I would need a lisp to do that by its own... to use it for some thousands of blocks.

Link to comment
Share on other sites

Being honest I am not very sure if it always work
Try to insert the blocks you wblocked in a new drawing and look at their units in the properties palette...

 

and it seems this routine only scales the blocks... but does not redefine them.

The LISP redefines the block definitions and update the inserted references according to these changes.

Try to change units or global scale and insert a redined block, it will display the same as the updated inserted references (if they were 1x1x1 scaled)...

 

If I don't misunderstand, your request is quite different, it needs to get the block insertion scale to rescale definitions.

This can be done if there're 2d blocks and the references uniformly scaled.

Link to comment
Share on other sites

Try to insert the blocks you wblocked in a new drawing and look at their units in the properties palette...

 

 

The LISP redefines the block definitions and update the inserted references according to these changes.

Try to change units or global scale and insert a redined block, it will display the same as the updated inserted references (if they were 1x1x1 scaled)...

 

If I don't misunderstand, your request is quite different, it needs to get the block insertion scale to rescale definitions.

This can be done if there're 2d blocks and the references uniformly scaled.

 

Well yeap, I guess it will work for the units thing... and yes, what I need is a lisp to rescale each block to 1,1,1 taking their current scale whatever it is, so they won´t get moved or resized (by this lisp), but redefining them to 1,1,1, in order to be used as standard for anybody in Metric or English units without having to change or scale them unless required per their specific needs.

 

I will need it to complete my task in the most appropiate way, I could even sell it after all this work... but is the beauty of me, if I get these things for free... let's keep it free.

Link to comment
Share on other sites

When I started writing Edit_bloc (2004) the goal was exactly to avoid having to do what you've done: scaling references because of their creation unit...

 

Here's a quickie which redefines blocks according to their insertion sclale.

It doesn't treat ununiform scaled references.

Unpredictable results with nested blocks (cause they can be both redefined and rescaled in the parent block).

 

(defun c:rescaleBlocks (/ acdoc blocks ss scl name def base)
 (vl-load-com)
 (setq acdoc  (vla-get-ActiveDocument (vlax-get-acad-object))
       blocks (vla-get-Blocks acdoc)
 )
 (if (ssget "_X" '((0 . "iNSERT")))
   (progn
     (vla-StartUndoMark acdoc)
     (vlax-for b (setq ss (vla-get-ActiveSelectionSet acdoc))
       (setq scl (vla-get-XScaleFactor b))
       (if (and (= scl (vla-get-YScaleFactor b) (vla-get-ZScaleFactor b))
                (/= 1.0 scl)
                (setq name (vla-get-Name b))
                (setq def (vla-item blocks name))
           )
         (progn
           (setq base (vla-get-Origin def))
           (vlax-for o def
             (vla-ScaleEntity o base scl)
           )
           (vla-put-XScaleFactor b 1.0)
           (vla-put-YScaleFactor b 1.0)
           (vla-put-ZScaleFactor b 1.0)
           (if (vla-get-HasAttributes b)
             (vl-cmdf "_.attsync" "_name" name)
           )
         )
       )
     )
     (vla-Delete ss)
     (vla-Regen acdoc acAllViewports)
     (vla-EndUndoMark acdoc)
   )
 )
 (princ)
)

Link to comment
Share on other sites

When I started writing Edit_bloc (2004) the goal was exactly to avoid having to do what you've done: scaling references because of their creation unit...

 

Here's a quickie which redefines blocks according to their insertion sclale.

It doesn't treat ununiform scaled references.

Unpredictable results with nested blocks (cause they can be both redefined and rescaled in the parent block).

 

(defun c:rescaleBlocks (/ acdoc blocks ss scl name def base)
 (vl-load-com)
 (setq acdoc  (vla-get-ActiveDocument (vlax-get-acad-object))
       blocks (vla-get-Blocks acdoc)
 )
 (if (ssget "_X" '((0 . "iNSERT")))
   (progn
     (vla-StartUndoMark acdoc)
     (vlax-for b (setq ss (vla-get-ActiveSelectionSet acdoc))
       (setq scl (vla-get-XScaleFactor b))
       (if (and (= scl (vla-get-YScaleFactor b) (vla-get-ZScaleFactor b))
                (/= 1.0 scl)
                (setq name (vla-get-Name b))
                (setq def (vla-item blocks name))
           )
         (progn
           (setq base (vla-get-Origin def))
           (vlax-for o def
             (vla-ScaleEntity o base scl)
           )
           (vla-put-XScaleFactor b 1.0)
           (vla-put-YScaleFactor b 1.0)
           (vla-put-ZScaleFactor b 1.0)
           (if (vla-get-HasAttributes b)
             (vl-cmdf "_.attsync" "_name" name)
           )
         )
       )
     )
     (vla-Delete ss)
     (vla-Regen acdoc acAllViewports)
     (vla-EndUndoMark acdoc)
   )
 )
 (princ)
)

 

 

Well, I've been doing this also... I used a lisp to turn all blocks to their original 1,1,1 scale... after that I asked in this forum for a modification to that lisp so It could attsync only selected blocks.. and Lee Mac has been answering and updating it several times and now it's a great tool for updating selected blocks, attribute blocks and dynamic blocks to the current dimscale.. but..

 

All these lisp just rescale the blocks, they are useful, but my task here includes to redefine many blocks, I know most of the people use blocks at different scales.. but most of the blocks I am organizing are real objects that don´t need to be rescaled or resized... they have a unique dimension, like cars, airplanes, windows, furniture, Also, I want to make a version where the drawing units are inches and another where the drawing units are meters... also, many of the blocks I downloaded don´t have a real dimension, I need to scale them and set that new scale as 1,1,1. To do so, I need to redefine each block one by one, copying the block name to the memory, place a mark in the insertion point, and then explode... then make a new block, must purge before to paste the same name or select the name from the file memory, pick the existing point and select previous exploded objects.. that way I get the same objects and the same block redefined to scale 1,1,1 with the new dimensions I fixed.

 

Then the lisp I need is to do all those steps in all selected blocks...

 

But it's nice to have another version of a block scaling lisp...

 

------------

 

sorry that I used the word rescale... I meant explode and redefine using their current size (any scale)

Link to comment
Share on other sites

sorry that I used the word rescale... I meant explode and redefine using their current size (any scale)
It's the second time you say "The LISP doesn't redefine blocks" even it DOES !

RescaleBlocks DOES redefine blocks even it doesn't explode them. While programming, it isn't needed to explode a block to resize all its components within the block definition.

 

Sorry but I can't understand neither what you want nor the way you're working. I think you have the (powerfull) tools you need, learn how to use them...

Link to comment
Share on other sites

It's the second time you say "The LISP doesn't redefine blocks" even it DOES !

RescaleBlocks DOES redefine blocks even it doesn't explode them. While programming, it isn't needed to explode a block to resize all its components within the block definition.

 

Sorry but I can't understand neither what you want nor the way you're working. I think you have the (powerfull) tools you need, learn how to use them...

 

Here some files... to explain you my needs with some graphics... and a example dwg file..

 

If you get into the drawing... you will see 4 or 5 different scales in the blocks... 0.0394, 1, 2, 0236, etc... I need them all to be 1,1,1 but without changing their current size, name nor insertion point...

 

When I use your rescaleblock.. It will change all of them to 1,1,1 but will just scale the blocks, preserving their name and insertion point but changing their current size..

 

If I use your edit_bloc and select the blocks, then select global scale=1, and taking the option none units.... (using edit_bloc.jpg) it changes block scales, but kind of converts from their original units or something but doesn´t get them to 1,1,1 (as you can see in the Properties dialog for blocks scale in the "result.jpg")..

 

What I need (I did it manually one by one for this case) Is shown in the "what I need.jpg) as you can see there in the properties dialog box, all blocks are scale 1,1,1 and their size didn´t change. I know a lisp could retain their names and insertion points... So what I need is basically turn them scale 1,1,1 without changing their current size.

example.dwg

blocks_original_status.jpg

using edit_bloc.jpg

result.jpg

what I need.jpg

Link to comment
Share on other sites

OK, RescaleBlocks needed tests if the references are uniformly scaled and doesn't treat them if they aren't. this test needed a fuzz factor on comparing X and Y scales, it's the reason why 4 blocks in your example.dwg were not treated.

 

I never said edit_bloc set scale to 1x1x1. It only works on block definitions (and update the references), so, a global unit set to 1 will do nothing.

 

After runing edit_bloc to set all blocks to unitless the blocks still have their insertion scaling. For example the right upper one (table and 10 chairs) which scale was 0.0276 has now to 0.7 (0.0276 x 25.4) becaus it has been inserted with this scale (or rescaled to 0.7 after inserted).

 

Then if you run RescaleBlocks (new version) the block will be redefined with 1x1x1 scaling.

 

(defun c:rescaleBlocks (/ acdoc blocks ss scl name def base)
 (vl-load-com)
 (setq acdoc  (vla-get-ActiveDocument (vlax-get-acad-object))
       blocks (vla-get-Blocks acdoc)
 )
 (if (ssget "X" '((0 . "iNSERT")))
   (progn
     (vla-StartUndoMark acdoc)
     (vlax-for b (setq ss (vla-get-ActiveSelectionSet acdoc))
       (setq scl (vla-get-XScaleFactor b))
       (if (and (equal scl (vla-get-YScaleFactor b) 1e-9)
                (/= 1.0 scl)
                (setq name (vla-get-Name b))
                (setq def (vla-item blocks name))
           )
         (progn
           (setq base (vla-get-Origin def))
           (vlax-for o def
             (vla-ScaleEntity o base scl)
           )
           (vla-put-XScaleFactor b 1.0)
           (vla-put-YScaleFactor b 1.0)
           (vla-put-ZScaleFactor b 1.0)
           (if (= (vla-get-HasAttributes b) :vlax-true)
             (vl-cmdf "_.attsync" "_name" name)
           )
         )
       )
     )
     (vla-Delete ss)
     (vla-Regen acdoc acAllViewports)
     (vla-EndUndoMark acdoc)
   )
 )
 (princ)
)

Attached the example.dwg after runing edit_bloc (All inserted, None units, Layer 0, Color, Lintype and Lineweight byBlock) and RescaleBlocks

 

PS: IMO, you have much more work to get these blocks usable: most have their insertion point far away at 75 to 150 units and they don't seem to be the same scale (some chairs too large and others too small)...

example.dwg

Link to comment
Share on other sites

OK, RescaleBlocks needed tests if the references are uniformly scaled and doesn't treat them if they aren't. this test needed a fuzz factor on comparing X and Y scales, it's the reason why 4 blocks in your example.dwg were not treated.

 

I never said edit_bloc set scale to 1x1x1. It only works on block definitions (and update the references), so, a global unit set to 1 will do nothing.

 

After runing edit_bloc to set all blocks to unitless the blocks still have their insertion scaling. For example the right upper one (table and 10 chairs) which scale was 0.0276 has now to 0.7 (0.0276 x 25.4) becaus it has been inserted with this scale (or rescaled to 0.7 after inserted).

 

Then if you run RescaleBlocks (new version) the block will be redefined with 1x1x1 scaling.

 

(defun c:rescaleBlocks (/ acdoc blocks ss scl name def base)
 (vl-load-com)
 (setq acdoc  (vla-get-ActiveDocument (vlax-get-acad-object))
       blocks (vla-get-Blocks acdoc)
 )
 (if (ssget "X" '((0 . "iNSERT")))
   (progn
     (vla-StartUndoMark acdoc)
     (vlax-for b (setq ss (vla-get-ActiveSelectionSet acdoc))
       (setq scl (vla-get-XScaleFactor b))
       (if (and (equal scl (vla-get-YScaleFactor b) 1e-9)
                (/= 1.0 scl)
                (setq name (vla-get-Name b))
                (setq def (vla-item blocks name))
           )
         (progn
           (setq base (vla-get-Origin def))
           (vlax-for o def
             (vla-ScaleEntity o base scl)
           )
           (vla-put-XScaleFactor b 1.0)
           (vla-put-YScaleFactor b 1.0)
           (vla-put-ZScaleFactor b 1.0)
           (if (= (vla-get-HasAttributes b) :vlax-true)
             (vl-cmdf "_.attsync" "_name" name)
           )
         )
       )
     )
     (vla-Delete ss)
     (vla-Regen acdoc acAllViewports)
     (vla-EndUndoMark acdoc)
   )
 )
 (princ)
)

Attached the example.dwg after runing edit_bloc (All inserted, None units, Layer 0, Color, Lintype and Lineweight byBlock) and RescaleBlocks

 

PS: IMO, you have much more work to get these blocks usable: most have their insertion point far away at 75 to 150 units and they don't seem to be the same scale (some chairs too large and others too small)...

 

 

 

wwoooow... It really works :0

 

First I made the test with the same file, and worked, then I moved to the original, but it has 1786 blocks... so I just grabbed 204 with different scales... and It worked again... So I guess it will continue working...

 

Finally I got what I need... just need to use both your edit_bloc and rescaleblocks and I will turn all the blocks as I need them.... This will save like Tons of hours, maybe weeks of time for this task...

 

I will let you know when I am done with all the collection.., thanks so much for all your help.... I still have to spend many hours in looking at each block and placing it in its own drawing, but without this tool, I would have take like 2 more weeks to finish, now It will be reduced to a few.. or maybe a couple hours....

 

 

About the blocks... well, I will be changing all insertion points to be at one corner or center depending of each block, also the block scale will be set to equal... and I am wblocking all to rename them using a file renamer (advanced renamer) that way each block in the collection will have its own name. What I am now trying to figure out is how to batch rename all the blocks in a drawing, so I wouldn´t need to do it outside of the drawing to avoid reorganizing them in the drawing. Also I would prefer this tool because I am thinking that I should use block names for spanish and english as I will need your lisp for turning metric blocks into english units blocks.

 

But well... I hope someone answers that one later.. or I will do the search when I am done with all the drafting.

 

Incredible...

 

And just to give you an Idea, I currently have about 20 files already worked from different collections, each one has in average 1,000 blocks, this one of 1700 is just one of them.. and I still have about 10 gigabytes of some other collections in their original compressed rar files because I don´t have enough room in my hard disk to extract them all.. I am extracting... renaming, purging, auditing, reinserting and deleting...

 

I know you will like this collection when I am done...

 

I just got some other tools, I just found and tested one for changing all blocks in the current drawing to color bylayer, and layer 0, its was supposed to work for both at the same time, but didn´t work for both, so I kind of edit it, and splitted it in one lisp for each... and they both work now..

 

Also, I am using the wblockm.lsp to wblock all the blocks in the current drawing to a selected directory...

 

and finally I am using a lisp to insert all blocks in a directory to the current drawing using a distance between them... it is the most messy lisp of all of them, due to blocks insertion points and scale... but at least I am not inserting them one by one.

Link to comment
Share on other sites

I just got some other tools, I just found and tested one for changing all blocks in the current drawing to color bylayer, and layer 0, its was supposed to work for both at the same time, but didn´t work for both, so I kind of edit it, and splitted it in one lisp for each... and they both work now..

 

Edit_bloc does this too...

Link to comment
Share on other sites

Edit_bloc does this too...

 

oops... I forgot to checkk that option yesterday... but.... you know I wanted to check that out today and I can´t use it, I got an error... I will check if it is due to all the other configuration I got... but this is the error sequence...

 

I used it in autocad 2009 yesterday... now I tried it on 2008, could it be the reason?

1sucesfully loaded.jpg

2error.jpg

3error.jpg

4error.jpg

5error.jpg

Link to comment
Share on other sites

It's a problem with your AutoCAD: "Base.dcl Can't find file"

 

Base.dcl is an AutoCAD provided file where DCL controls are defined. It have to be in your search path.

Link to comment
Share on other sites

It's a problem with your AutoCAD: "Base.dcl Can't find file"

 

Base.dcl is an AutoCAD provided file where DCL controls are defined. It have to be in your search path.

 

You're right... I was changing my support path to run autocad faster on one batch task, and deleted the "\AutoCAD 2008\UserDataCache\Support" by mistake.. now It works...

 

and also checked the layer and color bylayer and worked on all blocks without a single problem....

 

Now it is the most amazing lisp I've found... It will work a lot for this task...

 

thank you very much.

Link to comment
Share on other sites

Hey, Gile... I was wondering... WE are using standard blocks in our office and your lisp will help me a lot for changing all blocks' units to unitless... but I was wondering...

 

there is a variable called "annotativedwg" that works for the current drawing and helps us to make blocks annotative but in the "one by one" mode.. (wblock all dwgs... open each one.... set annotativedwg=1... save and close... and redefine blocks by purging and reinserting in a compilation drawing)

 

So, how difficult would it be to add the variable annotativedwg=0 to your lisp (to convert blocks to non-annotative)?

 

------------

Nevermind... I am almost done updating our library with these tasks... nothing but a few days to get it done...

Link to comment
Share on other sites

Yep... I had to wblock all to transform them back to non-annotative and redefine all blocks at once by another method, but then I had trouble with the units... some inches or milimeters, and I started to fix them one by one.. then decided to give this lisp a chance... and worked!! by using the redefine to non-units I fixed 90% of the blocks... I think I saved like 8 hours of work...

 

Thank you very much again gilles... I owe you

Hey, Gile... I was wondering... WE are using standard blocks in our office and your lisp will help me a lot for changing all blocks' units to unitless... but I was wondering...

 

there is a variable called "annotativedwg" that works for the current drawing and helps us to make blocks annotative but in the "one by one" mode.. (wblock all dwgs... open each one.... set annotativedwg=1... save and close... and redefine blocks by purging and reinserting in a compilation drawing)

 

So, how difficult would it be to add the variable annotativedwg=0 to your lisp (to convert blocks to non-annotative)?

 

------------

Nevermind... I am almost done updating our library with these tasks... nothing but a few days to get it done...

Link to comment
Share on other sites

Hey, Gile... I've just found this new information and I want to share it with you....

 

You know. I found your edit_bloc really amazing for some tasks... specially transforming blocks to unitless.. but.. For some reason it worked in about 70 or 80% of my blocks... converting them to unitless... but it didn´t fix the rest and I had to transform them one by one by copying each one of them in a new "good" drawing file with correct units... and saving it as the original name (overwriting it)...

 

and well... I think that it is because there are more than one variables affecting units as you can read below... Is it possible to add them to your lisp at least for the none-units option... it may help me a lot to finish my block compilation task in the most perfect way.

 

http://www.cadplan.co.za/tips_tricks.html

 

Why does AutoCAD insert my blocks in wrong scale?

Blocks and Xrefs contain their insertion unit settings, which are used for automatic scale conversion when they are inserted/attached to a drawing using other units. These units are defined in the INSUNITS (default units), INSUNITSDEFSOURCE (source units) and INSUNITSDEFTARGET (target units) variables.

In older AutoCAD versions, these variables were used only for the block inserts/drags from DesignCenter. AutoCAD 2006 (and higher) uses them for all methods of insertion of blocks, xrefs and images.

 

If your blocks are inserted in an improper scale (e.g. 0.254, 10 or 1000), you have probably wrong (different) settings of your block insertion units. Set INSUNITS e.g. to 0 (unitless) - then both the INSUNITSDEFxxxx variables will apply - set them also to 0 (other settings apply when dealing with AEC drawings).

Link to comment
Share on other sites

  • 3 months later...

Outstanding ! I was building a tool set using a blank DWG and seeding it with blocks from various files. Many of them were dynamic blocks and contained lots of useful features. Unfortunately many were defined to 'inches' or 'feet' instead of 'unitless':(. i discovered that you can redefine in the block dialog from feet to inches or inches to feet, but not to unitless:?. Since I would then have to tear these blocks apart and recreate them as unitless (and redo all the dynamic features :x) I was really happy to find this routine.

using a copy of the original file (always belt AND suspenders is the best rule) I ran this wonderful bit of magic and Whoo Hoo, all blocks are now unitless and the dynamic stuff is all still there.

 

Nice work, Thank you very much.

Joe A Perkins

Prime Engineering Inc.

 

 

Hi,

 

Instead of multiplying links to another web site, I post here my Edit_bloc routine.

 

This function (command name: Edit_bloc) allows some changes on blocks definitions in the current drawing (the complete collection, all inserted, or a selection).

All componants of the block are edited, even nested blocks and attributes.

A dialog box allows to choose which properties shall be edited : global scale, units (only available on R2006 & R2007), componants on layer "0", color, line type, line width and plot style of componants to ByBlock.

 

With another function (Edit_bloc_rep) it's possible to edit all the dwg files (wblock) of a repertory. This one must be launched from a virgin drawing and runed with "All collection" option.

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