This project has moved. For the latest updates, please go here.

Block attributes text style And InsertPosition

Feb 2, 2016 at 2:27 PM
hello
i define a text style and assign it to a block attributes,then create insert entity object from block using block.clone() method and change insert entity position.the problem is when i open saved document i need to run ATTSYNC in order to get correct location and text style.
i will appreciate your help
Feb 2, 2016 at 3:14 PM
this is my code,when I run program i should change block text style using "BE command" and then as i said previously using "ATTSYNC command" to change the size and Position
            this.Document.TextStyles.Add(new TextStyle("SazegarCEDXF_LinearRebarGroup", "simplex"));
            //this line changes defined text style height
            this.SetTextStyleParameters(DocumentTextStyles.LinearRebarGroup, 20); 

            LinearRebarGroupTextBlock = new Block("SazegarCEDXF_LinearRebarGroupTextBlock");
            AttributeDefinition LengthAttribute = new AttributeDefinition("Length");
            LengthAttribute.Alignment = TextAlignment.MiddleCenter;
            LengthAttribute.Position = new Vector3(this.GetTextStyle(DocumentTextStyles.LinearRebarGroup).Height * 5, 0, 0);
            LengthAttribute.Style = this.GetTextStyle(DocumentTextStyles.LinearRebarGroup);
            AttributeDefinition NumberAttribute = new AttributeDefinition("Number");
            NumberAttribute.Alignment = TextAlignment.MiddleCenter;
            NumberAttribute.Position = new Vector3(this.GetTextStyle(DocumentTextStyles.LinearRebarGroup).Height * -2, 0, 0);
            NumberAttribute.Style = this.GetTextStyle(DocumentTextStyles.LinearRebarGroup);
            AttributeDefinition SizeAttribute = new AttributeDefinition("Size");
            SizeAttribute.Alignment = TextAlignment.MiddleCenter;
            SizeAttribute.Position = new Vector3(0, 0, 0);
            SizeAttribute.Style = this.GetTextStyle(DocumentTextStyles.LinearRebarGroup);
            LinearRebarGroupTextBlock.AttributeDefinitions.Add(LengthAttribute);
            LinearRebarGroupTextBlock.AttributeDefinitions.Add(NumberAttribute);
            LinearRebarGroupTextBlock.AttributeDefinitions.Add(SizeAttribute); 
Feb 3, 2016 at 7:37 AM
hello again
below code is a simple example of my problem,if you open generated file you will see that it's position and style doesn't match with what i defined in code

DxfDocument Doc = new DxfDocument();
        TextStyle TS = new TextStyle("MyStyle", "simplex");
        TS.Height = 20;  

        Block block = new Block("Test");
        AttributeDefinition AD1 = new AttributeDefinition("Length");
        AttributeDefinition AD2 = new AttributeDefinition("Size");
        block.AttributeDefinitions.Add(AD1);
        block.AttributeDefinitions.Add(AD2);
        AD1.Style = TS;
        AD1.Alignment = TextAlignment.MiddleCenter;
        AD1.Position = new Vector3(-30, 0, 0);
        AD2.Style = TS;
        AD2.Alignment = TextAlignment.MiddleCenter;
        AD2.Position = new Vector3(30, 0, 0);

        block.AttributeDefinitions["Length"].Value = 1000;
        block.AttributeDefinitions["Size"].Value = 2000;

        Insert insert = new Insert((Block)block.Clone());
        insert.Position = new Vector3(100, 0, 0);

        Doc.AddEntity(insert);
        Doc.Save("AttTest.dxf");
Feb 3, 2016 at 7:55 AM
I found out that i should call "Sync()" method of insert bock before adding it to the block,if you set height of block attributes by "Height" property it works appropriately but if you set "Style" property of attribute it doesn't work.
below is the two different situations:

situation 1

DxfDocument Doc = new DxfDocument();
        TextStyle TS = new TextStyle("MyStyle", "simplex");
        TS.Height = 20;  

        Block block = new Block("Test");
        AttributeDefinition AD1 = new AttributeDefinition("Length");
        AttributeDefinition AD2 = new AttributeDefinition("Size");
        block.AttributeDefinitions.Add(AD1);
        block.AttributeDefinitions.Add(AD2);
        AD1.Alignment = TextAlignment.MiddleCenter;
        AD1.Height = 10;

        AD1.Position = new Vector3(-30, 0, 0);
        AD2.Alignment = TextAlignment.MiddleCenter;
        AD2.Height = 10;
        AD2.Position = new Vector3(30, 0, 0);

        block.AttributeDefinitions["Length"].Value = 1000;
        block.AttributeDefinitions["Size"].Value = 2000;

        Insert insert1 = new Insert((Block)block.Clone());
        insert1.Position = new Vector3(-100, 0, 0);
        insert1.Sync();

        Insert insert2 = new Insert((Block)block.Clone());
        insert2.Position = new Vector3(100, 0, 0);
        insert2.Sync();

        Doc.AddEntity(insert1);
        Doc.AddEntity(insert2);
        Doc.Save("AttTest.dxf");
situation 2

DxfDocument Doc = new DxfDocument();
        TextStyle TS = new TextStyle("MyStyle", "simplex");
        TS.Height = 20;  
        Block block = new Block("Test");
        AttributeDefinition AD1 = new AttributeDefinition("Length");
        AttributeDefinition AD2 = new AttributeDefinition("Size");
        block.AttributeDefinitions.Add(AD1);
        block.AttributeDefinitions.Add(AD2);
        AD1.Alignment = TextAlignment.MiddleCenter;
        AD1.Style = TS;
        AD1.Position = new Vector3(-30, 0, 0);
        AD2.Alignment = TextAlignment.MiddleCenter;
        AD2.Style = TS;
        AD2.Position = new Vector3(30, 0, 0);

        block.AttributeDefinitions["Length"].Value = 1000;
        block.AttributeDefinitions["Size"].Value = 2000;

        Insert insert1 = new Insert((Block)block.Clone());
        insert1.Position = new Vector3(-100, 0, 0);
        insert1.Sync();

        Insert insert2 = new Insert((Block)block.Clone());
        insert2.Position = new Vector3(100, 0, 0);
        insert2.Sync();

        Doc.AddEntity(insert1);
        Doc.AddEntity(insert2);
        Doc.Save("AttTest.dxf");
Coordinator
Feb 3, 2016 at 6:15 PM
I was going to say if you have not tried the insert's Sync() method, but it seems you already tried. This function is useful when you modify any block attribute definition after you have created the insert from it. Once an insert is created its attributes properties are independent from the properties of its block attribute definitions, this is how it works in AutoCad, you should call the insert's Sync() method after you have made all changes in the block's attribute definitions. If you only modify the insert's position, rotation, scale, or rotation it should be enough calling the method TransformAttributes(), in the documentation I wrote that "This method is called automatically when the Insert is added to a document" this is wrong.

I will look into more detail the code from you last post, but from a quick look I am seeing a few problems.
  1. You are creating two inserts from two cloned blocks but they still have the same name. You cannot have two blocks with the same name, so when adding the inserts to the document one will override the other. You could use the public override TableObject Clone(string newName) method instead to clone an existing block with a different name.
  2. Instead of changing the insert's position after you have created it, you can use directly the public Insert(Block block, Vector2 position) constructor. This way you will avoid using the Sync() or, in this case, better the TransformAttributes() method. The Sync() method will override all insert's attributes with the default defined in the block's attribute definitions.
  3. I do not see why you need to create two inserts from two cloned blocks which are basically the same. If you need to set the attribute value change it directly from the insert's attribute value not the block's attribute definition value. Usually, the block's attribute definition holds the default value for all insert's attributes created from it, afterwards, if every insert needs to hold a different value change its corresponding insert's attribute value.
  4. About the AttributeDefinition Style not working I will need to check it out. You can try to add your attribute definitions AD1 and AD2 to the block's attribute definition list after you have finished modifying them.
Hope this clarifies you doubts. All this works in a similar way as it does in AutoCad, but remember an insert is an instance of a block, something that it is not very clear in AutoCad, where many times we say block where we should say insert.

Daniel
Feb 4, 2016 at 6:36 PM
thank you so much for for your help,it was very useful and i appreciate because i know take your time to answer to my question (and i apologize if my English grammar is not good enough)
about your suggestions in last post based on your marking:

1.Actually i didn't get the first problem you mentioned in last post
2.It was useful,thanks
3.Again you are right,according to your explanation i get how insert block works now
4.I search a little more and i found out that by changing text style font,we get the changes for created insert(as you said instead of say block) but if we change text style size,it doesn't affect on created insert.I think this is another issue and there isn't any problem with your library.If you find out any useful information i will be glad to tell me about that.

I see a property named Reactors in insert entity.can you tell me more about reactor and usage of that? (i will create new discussion with this title for future search)


Another thing i like to mention is the following sentences i quote from one of your discussions :

1."I am NOT a programmer, I just enjoy writing code, sometimes, and it has its limits when I program just for myself"
actually i think you are a very good programmer,based on your netdxf library architecture i'm pretty sure that your do your best at the time you have wrote this library.

2." I know I haven't answer any of the discussions but I haven't even care, this project was mostly forgotten, and I apologize for that."
that was very valuable

3." I don't want this to sound like an apology or a declaration of future plans, but maybe as a rebirth?"
Why not??? :);)

And finally what you did and release that for free is a huge thing,even if someone wants to contribute in the stuff where your knowledge lacks (in bad manner actually)
I wish you the best,thanks
Coordinator
Feb 8, 2016 at 5:03 PM
I took a look about the trouble you had with the block's attribute definitions and its text style. I have no detected any problems and everything seems to work as expected. Perhaps, you are assuming that if you change the text style height the attribute definition height will also automatically change, that is not correct. This behavior mimics how it works in AutoCad, the text style height is only applied when the entity is created. You will find a constructor for attribute definitions that not only takes tag but also a text style. For those cases, what I would do is to add an additional constructor for the AttributeDefinition that takes a tag, a text height, and a text style.

It is a common practice to set always the default text style height to zero, this way AutoCad will ask for the height when creating, for example, a text entity. You usually have entities like texts, attributes, dimensions, that shares the same text style but they might have different heights, that is why the height of a text is independent to its style.

About the point 1 that you said you didn't understand. There are two main types of DxfObjects, EntityObjects and TableObjects. While entities are drawable objects, table objects describe how those entities are drawn. In the dxf file these table objects appear distributed in the Blocks, Tables, and Objects sections, I just made them inherit from the same class since its purpose and behavior is similar. In AutoCad every table object must have a unique name, and this applies to netDxf too. If two tables have the same name they are considered equals, keep in mind that these names are case insensitive.

So, going back to your case, you are making two clones of the same block. Both clones, even though, they are two different objects they are considered the same since both have the same name. That is why all table objects have a Clone method that takes a string as argument. Usually the clone methods are useful when moving objects between different dxf documents since two documents cannot share the same instance of a DxfObject.

Daniel