示例#1
0
        /// <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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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;
                }
            }
        }