/// <summary> /// Calculates the insertion rotation matrix. /// </summary> /// <param name="insertionUnits">The insertion units.</param> /// <returns>The insert transformation matrix.</returns> public Matrix3 GetTransformation(DrawingUnits insertionUnits) { double docScale = UnitHelper.ConversionFactor(this.Block.Record.Units, insertionUnits); Matrix3 trans = MathHelper.ArbitraryAxis(this.Normal); trans *= Matrix3.RotationZ(this.rotation * MathHelper.DegToRad); trans *= Matrix3.Scale(this.scale * docScale); return(trans); }
/// <summary> /// Calculates the insertion rotation matrix. /// </summary> /// <returns>The insert transformation matrix.</returns> /// <remarks> /// This method uses the DefaultInsUnits defined by the Insert class to obtain the scale between the drawing and the block units. /// Additionally, if the insert belongs to a block the units to use are the ones defined in the BlockRecord, /// and if the insert belongs to a layout the units to use are the ones defined in the document drawing variable InsUnits. /// </remarks> public Matrix3 GetTransformation() { DrawingUnits insUnits; if (this.Owner == null) { insUnits = DefaultInsUnits; } else { insUnits = this.Owner.Record.Layout == null ? this.Owner.Record.Units : this.Owner.Record.Owner.Owner.DrawingVariables.InsUnits; } double docScale = UnitHelper.ConversionFactor(this.Block.Record.Units, insUnits); Matrix3 trans = MathHelper.ArbitraryAxis(this.Normal); trans *= Matrix3.RotationZ(this.rotation * MathHelper.DegToRad); trans *= Matrix3.Scale(this.scale * docScale); return(trans); }
/// <summary> /// Recalculate the attributes position, normal, rotation, text height, width factor, and oblique angle from the values applied to the insertion. /// </summary> /// <remarks> /// Changes to the insert, the block, or the document insertion units will require this method to be called manually.<br /> /// The attributes position, normal, rotation, text height, width factor, and oblique angle values includes the transformations applied to the insertion, /// if required this method will calculate the proper values according to the ones defined by the attribute definition.<br /> /// All the attribute values can be changed manually independently to its definition, /// but, usually, you will want them to be transformed with the insert based on the local values defined by the attribute definition.<br /> /// This method only applies to attributes that have a definition, some dxf files might generate attributes that have no definition in the block.<br /> /// At the moment the attribute width factor and oblique angle are not calculated, this is applied to inserts with non uniform scaling. /// </remarks> public void TransformAttributes() { // if the insert does not contain attributes there is nothing to do if (this.attributes.Count == 0) { return; } DrawingUnits insUnits; if (this.Owner == null) { insUnits = DrawingUnits.Unitless; } else { // if the insert belongs to a block the units to use are the ones defined in the BlockRecord // if the insert belongs to a layout the units to use are the ones defined in the Document insUnits = this.Owner.Record.Layout == null ? this.Owner.Record.Units : this.Owner.Record.Owner.Owner.DrawingVariables.InsUnits; } Vector3 insScale = this.scale * UnitHelper.ConversionFactor(this.block.Record.Units, insUnits); Matrix3 insTrans = this.GetTransformation(insUnits); foreach (Attribute att in this.attributes) { AttributeDefinition attdef = att.Definition; if (attdef == null) { continue; } Vector3 wcsAtt = insTrans * (attdef.Position - this.block.Origin); att.Position = this.position + wcsAtt; Vector2 txtU = new Vector2(attdef.WidthFactor, 0.0); txtU = MathHelper.Transform(txtU, attdef.Rotation * MathHelper.DegToRad, CoordinateSystem.Object, CoordinateSystem.World); Vector3 ocsTxtU = MathHelper.Transform(new Vector3(txtU.X, txtU.Y, 0.0), attdef.Normal, CoordinateSystem.Object, CoordinateSystem.World); Vector3 wcsTxtU = insTrans * ocsTxtU; Vector2 txtV = new Vector2(0.0, attdef.Height); txtV = MathHelper.Transform(txtV, attdef.Rotation * MathHelper.DegToRad, CoordinateSystem.Object, CoordinateSystem.World); Vector3 ocsTxtV = MathHelper.Transform(new Vector3(txtV.X, txtV.Y, 0.0), attdef.Normal, CoordinateSystem.Object, CoordinateSystem.World); Vector3 wcsTxtV = insTrans * ocsTxtV; Vector3 txtNormal = Vector3.CrossProduct(wcsTxtU, wcsTxtV); att.Normal = txtNormal; double txtHeight = MathHelper.PointLineDistance(wcsTxtV, Vector3.Zero, Vector3.Normalize(wcsTxtU)); att.Height = txtHeight; double txtAng = Vector2.Angle(new Vector2(txtU.X * insScale.X, txtU.Y * insScale.Y)) * MathHelper.RadToDeg; if (Vector3.Equals(attdef.Normal, Vector3.UnitZ)) { att.Rotation = this.rotation + txtAng; //double txtWidth = MathHelper.PointLineDistance(wcsTxtU, Vector3.Zero, Vector3.Normalize(wcsTxtV)); //att.WidthFactor = txtWidth; att.WidthFactor = attdef.WidthFactor; //double a1d1Ang = Vector2.Angle(new Vector2(txtV.X * insScale.X, txtV.Y * insScale.Y)) * MathHelper.RadToDeg; //double oblique = 90 - (a1d1Ang - txtAng); //if (oblique < -85.0 || oblique > 85.0) oblique = Math.Sign(oblique) * 85; //att.ObliqueAngle = oblique; att.ObliqueAngle = attdef.ObliqueAngle; } else { att.Rotation = txtAng; att.WidthFactor = attdef.WidthFactor; att.ObliqueAngle = attdef.ObliqueAngle; } } }