UCS command programatically

UCS command programatically

Anonymous
Not applicable
1,004 Views
7 Replies
Message 1 of 8

UCS command programatically

Anonymous
Not applicable

How could I execute the

 

UCS "origin point" "point in X axis" "point in XY plane"

programatically? I checked this post but it's not helping me.

0 Likes
Accepted solutions (1)
1,005 Views
7 Replies
Replies (7)
Message 2 of 8

Anonymous
Not applicable
0 Likes
Message 3 of 8

_gile
Consultant
Consultant

Hi,

 

Here's a way:

        static Matrix3d Ucs3Points(Point3d origin, Point3d pointOnXaxis, Point3d pointOnXYplane)
        {
            Vector3d toXAxis = origin.GetVectorTo(pointOnXaxis).GetNormal();
            Vector3d toZAxis = toXAxis.CrossProduct(origin.GetVectorTo(pointOnXYplane)).GetNormal();
            Vector3d toYAxis = toZAxis.CrossProduct(toXAxis).GetNormal();
            return Matrix3d.AlignCoordinateSystem(
                Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
                origin, toXAxis, toYAxis, toZAxis);
        }

Using example:

        [CommandMethod("UCS3PTS")]
        public static void UcsThreePoints()
        {
            var ed = Application.DocumentManager.MdiActiveDocument.Editor;
            var ppo = new PromptPointOptions("\nNew origin: ");
            var ppr = ed.GetPoint(ppo);
            if (ppr.Status != PromptStatus.OK)
                return;
            var org = ppr.Value;
            ppo.BasePoint = org;
            ppo.UseBasePoint = true;
            ppo.Message = "\nPoint on new X axis: ";
            ppr = ed.GetPoint(ppo);
            if (ppr.Status != PromptStatus.OK)
                return;
            var pt1 = ppr.Value;
            ppo.Message = "\nPoint on new XY plane: ";
            ppr = ed.GetPoint(ppo);
            if (ppr.Status != PromptStatus.OK)
                return;
            var pt2 = ppr.Value;
            var oldUcs = ed.CurrentUserCoordinateSystem;
            var newUcs = Ucs3Points(org.TransformBy(oldUcs), pt1.TransformBy(oldUcs), pt2.TransformBy(oldUcs));
            ed.CurrentUserCoordinateSystem = newUcs;
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 8

Anonymous
Not applicable

Thank you for answering. The function works fine.

 

My aim is to change the coordinate system with that function, then draw an angular dimension in that coordinate system, and finally go back to the default coordinate system, but it's not working. The dimension is drawn in the old coordinate system.

0 Likes
Message 5 of 8

Anonymous
Not applicable

This is what I'm trying to do: I have a list of line pairs that share their start or end points, and I want to draw the angular dimension between them. I want the dimension to be drawn to a distance of a fourth of the shortest line from the origin.

 

I used your function and I think the only thing that's wrong is the ArcPoint, the rest looks fine.

 

public static void CreateAngularDimensions(List<(ObjectId, ObjectId)> linePairs, Point3d origin, Transaction trans, BlockTableRecord btr) {

            Matrix3d oldUcs = Editor.CurrentUserCoordinateSystem;

            foreach ((ObjectId l1, ObjectId l2) in linePairs) {
                Line line1 = trans.GetObject(l1, OpenMode.ForRead) as Line;
                Line line2 = trans.GetObject(l2, OpenMode.ForRead) as Line;
                Vector3d vec1;
                Vector3d vec2;
                Point3d end1, end2;
                Matrix3d newUcs;

                if (line1.StartPoint.Equals(origin)) {
                    vec1 = origin.GetVectorTo(line1.EndPoint);
                    end1 = line1.EndPoint;
                } else {
                    vec1 = origin.GetVectorTo(line1.StartPoint);
                    end1 = line1.StartPoint;
                }
                if (line2.StartPoint.Equals(origin)) {
                    vec2 = origin.GetVectorTo(line2.EndPoint);
                    end2 = line2.EndPoint;
                } else {
                    vec2 = origin.GetVectorTo(line2.StartPoint);
                    end2 = line2.StartPoint;
                }

                newUcs = Ucs3Points(origin, end1, end2);
                Editor.CurrentUserCoordinateSystem = newUcs;

                LineAngularDimension2 dimension = new LineAngularDimension2();
                dimension.XLine1Start = origin;
                dimension.XLine2Start = origin;
                dimension.XLine2Start = end1;
                dimension.XLine2End = end2;

                Vector3d dimVec1 = dimension.XLine1Start.GetVectorTo(dimension.XLine1End);
                Vector3d dimVec2 = dimension.XLine2Start.GetVectorTo(dimension.XLine2End);

                Vector3d bisectorVec = dimVec1.Add(dimVec2).GetNormal();
                dimension.ArcPoint = origin.Add(bisectorVec.MultiplyBy(Math.Min(line1.Length, line2.Length) / 4));

                dimension.DimensionStyle = Database.Dimstyle;
                CreateLayer("Cotas");
                dimension.Layer = "Cotas";

                btr.AppendEntity(dimension);
                trans.AddNewlyCreatedDBObject(dimension, true);

            }

            Editor.CurrentUserCoordinateSystem = oldUcs;
        }
0 Likes
Message 6 of 8

ActivistInvestor
Mentor
Mentor

The CurrentUserCoordinateSystem doesn't determine the coordinate system of Dimensions created programmatically. You have to explicitly set the coordinate system of the new dimension by transforming it to the desired UCS or by setting the appropriate properties. 

0 Likes
Message 7 of 8

Anonymous
Not applicable

I tried transforming all the dimension properties by using the method TransformBy(newUcs) but I'm not getting the right angle or ArcPoint.

 

LineAngularDimension2 dimension = new LineAngularDimension2 {
                    XLine1Start = origin.TransformBy(newUcs),
                    XLine2Start = origin.TransformBy(newUcs),
                    XLine1End = end1.TransformBy(newUcs),
                    XLine2End = end2.TransformBy(newUcs)
                };

Vector3d dimVec1 = dimension.XLine1Start.GetVectorTo(dimension.XLine1End);
Vector3d dimVec2 = dimension.XLine2Start.GetVectorTo(dimension.XLine2End);

Vector3d bisectorVec = dimVec1.Add(dimVec2).GetNormal();
dimension.ArcPoint = origin.TransformBy(newUcs).Add(bisectorVec.MultiplyBy(Math.Min(line1.Length, line2.Length) / 4));

dimension.DimensionStyle = Database.Dimstyle;
CreateLayer("Cotas");
dimension.Layer = "Cotas";

dimension.TransformBy(newUcs);

btr.AppendEntity(dimension);
trans.AddNewlyCreatedDBObject(dimension, true);
0 Likes
Message 8 of 8

_gile
Consultant
Consultant
Accepted solution

Here's an example using the plane which contains two intersecting lines with the Matrix3d.worldToPlane and Matrix3d.PlaneToWorld transformations.

 

        [CommandMethod("TEST")]
        public static void Test()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var opts = new PromptEntityOptions("\nSelect first line: ");
            opts.SetRejectMessage("\nSelected object is not a Line.");
            opts.AddAllowedClass(typeof(Line), true);
            var rslt = ed.GetEntity(opts);
            if (rslt.Status != PromptStatus.OK)
                return;
            var lineId1 = rslt.ObjectId;

            opts.Message = "\nSelect second line: ";
            rslt = ed.GetEntity(opts);
            if (rslt.Status != PromptStatus.OK)
                return;
            var lineId2 = rslt.ObjectId;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                var line1 = (Line)tr.GetObject(lineId1, OpenMode.ForRead);
                var line2 = (Line)tr.GetObject(lineId2, OpenMode.ForRead);

                // get the lines intersection point
                var intersPts = new Point3dCollection();
                line1.IntersectWith(line2, Intersect.ExtendBoth, intersPts, IntPtr.Zero, IntPtr.Zero);
                if (intersPts.Count == 0)
                {
                    ed.WriteMessage("\nNone intersection.");
                    return;
                }
                var org = intersPts[0];

                // get the vector from the intersection point to the farest point of line1
                var pt1 = org.DistanceTo(line1.StartPoint) < org.DistanceTo(line1.EndPoint) ?
                    line1.EndPoint : line1.StartPoint;
                var vect1 = org.GetVectorTo(pt1);

                // get the vector from the intersection point to the farest point of line1
                var pt2 = org.DistanceTo(line2.StartPoint) < org.DistanceTo(line2.EndPoint) ?
                    line2.EndPoint : line2.StartPoint;
                var vect2 = org.GetVectorTo(pt2);

                // get the plane which contains the two lines
                var normal = vect1.CrossProduct(vect2);
                var plane = new Plane(org, normal);

                // get the transformation matrix from WCS to the plane
                var xform = Matrix3d.WorldToPlane(plane);

                // create an angular dimension on the WCS XY plane using transformed points from WCS to plane
                var dim = new LineAngularDimension2();
                dim.XLine1Start = dim.XLine2Start = org.TransformBy(xform);
                dim.XLine1End = pt1.TransformBy(xform);
                dim.XLine2End = pt2.TransformBy(xform);
                dim.ArcPoint = (org + (vect1 + vect2) / 2.0).TransformBy(xform);
                var space = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                space.AppendEntity(dim);
                tr.AddNewlyCreatedDBObject(dim, true);

                // transform the new created dimension from plane to WCS
                dim.TransformBy(Matrix3d.PlaneToWorld(plane));
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes