Code Red > .NET

Converting dynamic block to static block

(1/2) > >>

jon:
Hello wizards of the swamp!

I have a problem when I try to convert a Dynamic Block into a Static Block through C#, the problem is that some of the blocks I convert end up with the wrong rotation.

I have a DWG that my company works in, and here I run a custom command called "STATIFY". This command removes some Dynamic Blocks my company prefers to work with and insert new Static Blocks from an external DWG given to us by our customer. Because of specifications given by the customer, the DWG we produce needs to contain the Static Blocks provided by the customer. This leaves the built-in ConvertToStaticBlock method useless as when you use the ConvertToStaticBlock method, your "new" converted block's name will be the anonymous name of the dynamic block. I.E a converted block gets the name *UXX while I want the name to be CUSTOMER_BLOCK_TYPE_YY.

So my STATIFY command works pretty alright, for some blocks it even works perfectly but that isn't good enough. So in short I pass the Dynamic Blocks' block reference values to the Static Blocks' block reference values.

--- Code: ---...
NewBlockRef.Rotation = OldBlockRef.Rotation
NewBlockRef.Scaling = OldBlockRef.Scaling
...

--- End code ---
At this point I get into trouble since when I set the rotational value it doesn't always work right. At first I thought it was because of the flip states, but after closer inspection I think there is a problem with the Dynamic Blocks in the DWG I have to work with. For instance I have noticed that a 90 degree rotation works in different ways on different blocks even though it shouldn't:


I suspect this might be caused by an user error, but I think I will be a pretty unpopular man if I tell people they have to redo all their DWGs and also I think I am close to a solution that will work:

--- Code: ---//This line fixes the rotation
NewBlockRef.BlockTableRecord = OldBlockRef.BlockTableRecord
//This next line fixes my problem too
NewBlockRef.BlockTableRecord = OldBlockRef.AnonymousBlockTableRecord
//The following line does NOT fix the rotation
NewBlockRef.BlockTableRecord = OldBlockRef.DynamicBlockTableRecord

--- End code ---
Unfortunately these two fixes leads to my new Static Blocks getting the names of the anonymous blocks (*UXX and not Customer_Block_YY). When I don't set:

--- Code: ---NewBlockRef.BlockTableRecord = OldBlockRef.BlockTableRecord

--- End code ---
all my new blocks get the names they are supposed to btw. Had I been able to change the name from *UXX to CUSTOMER_BLOCK_TYPE_YY I think my solution would have been complete, but this does not work because I get a DuplicateNameError. I am also unable to change the name to CUSTOMER_BLOCK_TYPE_YY*UXX as this leads to InvalidInputError. I suspect that these errors are caused by my lack of knowledge of AutoCAD and what BlockReference and BlockTableRecord really are, and also something tells me that the statement

--- Code: ---NewBlockRef.BlockTableRecord = OldBlockRef.BlockTableRecord

--- End code ---
is problematic. Despite this, my brain tells me that I have to be onto something here. There has to be some data in the OldBlockRef.BlockTableRecord or OldBlockRef.AnonymousBlockTableRecord that will make the rotation of my NewBlock correct? What data could this be and how would I proceed to extract it? For instance I tried to check if there was a Transformational Matrix I could extract from the OldBlockRef, but this didn't work either.

I am not at my workstation right now so I don't have access to the code, but if anyone wants to give this a go I can post some code when I get back to work. I do have to take some precautions with what code I post as this is a work project though, but if I am able to get my code to work with help from The Swamp I will obviously write up a working example I can post so others might learn from my mistakes.

It's Alive!:

Hi, could it be that you’re using the wrong function?

public virtual void ConvertToStaticBlock();
public virtual void ConvertToStaticBlock(string newBlockName);

Converts the dynamic block instance to a legacy (nondynamic) block. 

When successful, the dynamic block properties are frozen at their current values and the reference ceases to be a dynamic block. A new block is defined with the name newBlockName, which must not already exist in the drawing and must satisfy all of the naming restrictions of normal block references.




jon:
Thanks for your tips!

I have tried using
--- Code: ---oldBlkRef.ConvertToStaticBlock(name)
--- End code ---
but this also yields a DuplicateNameError. I guess if I create a new name consisting of the anonymous block name and the block name I want to use, this method would sort of work. Still I see two limitations with this method:

1) The block that is converted is not my customer's static block. The block converted ends up being my company's dynamic block, without the dynamic properties. Because of that I would have to programmatically change some things about the converted block to make it look like the static blocks, but in the end it will not be the static block I want it to be.

2) I am quite new to AutoCAD development and I am very curious on what I am getting wrong. In my head my method should work and I want to understand what I am currently not understanding.

I do see your suggestion as a possible workaround though. So I tried to do this:

--- Code: ---//Turns out having a * in the string I want as a name is what made me get the InalidInputError
oldBlockRef.ConvertToStaticBlock(customerBlockName+anonymousBlockName.Subtring(1))
newBlockRef.Rotation = oldBlockRef.Rotation
...
newBlockRef.BlockTableRecord = oldBlockRef.BlockTableRecord

--- End code ---
And now I have the right type of blocks with the name: Customer_Block_YYUXX. I would definitely prefer the name to simply being Customer_Block_YY but this is closer to a solution than I have been so far I guess and I think I can work with this so I get a solution that is good enough.

But this is not perfect, and I really want to understand what I am doing wrong just for the sake of learning. What data does the BlockRecordTable contain that make the rotations work perfectly? Might WCS and UCS (which I have no experience with) be involved in this? Why can't I create blocks with identical names? I mean, I have seen DWGs with multiple occurrences of Customer_Block_YY and I manage to create blocks with multiple occurrences of Customer_Block_YY as long as I do not set

--- Code: ---newBlockRef.BlockTableRecord = oldBlockRef.BlockTableRecord

--- End code ---

kdub_nz:
Jon ,
I'm just running past ..

Define Blocks (.NET)
http://help.autodesk.com/view/ACD/2017/ENU/?guid=GUID-DF67671C-101D-4917-808B-DD2C5BE3C7E9

Insert Blocks (.NET)
http://help.autodesk.com/view/ACD/2017/ENU/?guid=GUID-2656E245-6EAA-41A3-ABE9-742868182821

Try to absorb these.

There are probably better examples, but essentially, in concept
the definition is similar in concept to a class definition.
the insertion instance is similar in concept to a class instance, adds the elements from the definition and applies scale, rotation, location, layer etc.

Once you grok that, it gets easier.

Attributes are the next step ...



Welcome to TheSwamp

Regards,



jon:
Thank you for your explanation, you put me on the right track and I managed to put together a solution. The solution was quite simple, I just had to explode the dynamic block and store the values of the exploded block instead of the values of the dynamic block.

I will post the solution code/pseudo code within a couple of days in case anyone is interested.

Navigation

[0] Message Index

[#] Next page

Go to full version