haplokuon / netDxf

.net dxf Reader-Writer
MIT License
981 stars 400 forks source link

When create a outside block with a insert inside it, the text height of the insert's attribute text not scaled as the insert's scale. #408

Closed Snailya closed 1 year ago

Snailya commented 2 years ago

I create a inside block with a cicle of radisu 1 and text attribute of height 2. When inserting this block at a scale of (1600,1600,1600) in to the document, it displays as what I expected. image However, if i place this insert of the same scale with other entities to form a new block, it displays as below, which the text height of the attribute is reset to 1. image I was wonder is there any extra code should be added to get what I expected?

var _axios = new("_Axios", new[] { EntityUtil.CreateCircle(LayerUtil.GetAxis(), Vector2d.Zero, 1) }, new[] { new AttributeDefinition("A", 1, new TextStyle("COMPLEX", "complex.shx")) { Alignment = TextAlignment.MiddleCenter, Layer = LayerUtil.GetAxisText(), Value = "X", IsVisible = true, Position = Vector3.Zero } }); var label1 = new Insert(_axios, line.StartPoint - Vector3.Normalize(line.Direction) * 1600) { Scale = new Vector3(1600, 1600, 1600)}; var block = new Block($"grid{Level}", {label1});

Snailya commented 2 years ago

I think I've figured that, the Sync() method or the TransformAttributes() method must be called after change the insert's scale. This method will update the insert's attributes.

But I still wonder why this is not done automatically when seting insert's scale, which just as what autocad does. `

/// <summary>
/// Gets or sets the insert <see cref="Vector3">scale</see>.
/// </summary>
/// <remarks>None of the vector scale components can be zero.</remarks>
public Vector3 Scale
{

    get { return this.scale; }
    set
    {

        if (MathHelper.IsZero(value.X) || MathHelper.IsZero(value.Y) || MathHelper.IsZero(value.Z))
        {
            throw new ArgumentOutOfRangeException(nameof(value), value, "None of the vector scale components can be zero.");
        }

        this.scale = value;
        TransformAttributes(); // transfrom attributes after scale chang
    }
}

`

haplokuon commented 2 years ago

That is what you need to do a call to the TransformAttributes(). The reason is explained in the method comments. The transformation of the Insert is not necessarily inherited by the attributes, normally you want to but it is not mandatory. The way Autodesk implemented the attributes and attribute definitions leaves a lot to be desired it is very messy. If they wanted to make the attributes inherit the transformation of the insert they should have make it local like any other entity in the block.

Another reason is to avoid multiple unnecessary calls to this method when multiple properties, that affect the transformation, are changed.

On the other hand the TransformBy method will also transform the attributes.

Snailya commented 1 year ago

Thanks