RectangleJig Question

RectangleJig Question

Amremad
Collaborator Collaborator
3,163 Views
18 Replies
Message 1 of 19

RectangleJig Question

Amremad
Collaborator
Collaborator

any one help me to write a class to draw rectangle  and can user determine the base point, angle and dimension during dragging .

0 Likes
3,164 Views
18 Replies
Replies (18)
Message 2 of 19

_gile
Consultant
Consultant

Hi,

 

Here's a little example.

 

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using static System.Math;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
using AcGi = Autodesk.AutoCAD.GraphicsInterface;

[assembly: CommandClass(typeof(RectangleJigSample.Commands))]

namespace RectangleJigSample
{
    public class Commands
    {
        [CommandMethod("TEST")]
        public void Test()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var ppr = ed.GetPoint("\nSpecify first corner point: ");
            if (ppr.Status != PromptStatus.OK)
                return;
            var pt = ppr.Value;
            using (var tr = db.TransactionManager.StartTransaction())
            using (var pline = new Polyline(4))
            {
                pline.AddVertexAt(0, new Point2d(pt.X, pt.Y), 0.0, 0.0, 0.0);
                pline.AddVertexAt(1, new Point2d(pt.X + 1.0, pt.Y), 0.0, 0.0, 0.0);
                pline.AddVertexAt(2, new Point2d(pt.X + 1.0, pt.Y + 1.0), 0.0, 0.0, 0.0);
                pline.AddVertexAt(3, new Point2d(pt.X, pt.Y + 1.0), 0.0, 0.0, 0.0);
                pline.Closed = true;
                pline.Elevation = pt.Z;
                var ucs = ed.CurrentUserCoordinateSystem;
                pline.TransformBy(ucs);

                // create a RectangleJig
                var rectJig = new RectangleJig(pline, 0.0);

                // Loop while the user specify other corner or cancel
                while (true)
                {
                    var pr = ed.Drag(rectJig);
                    // Other corner is specified
                    if (pr.Status == PromptStatus.OK)
                    {
                        var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                        curSpace.AppendEntity(pline);
                        tr.AddNewlyCreatedDBObject(pline, true);
                        break;
                    }
                    // Rotation option
                    if (pr.Status == PromptStatus.Keyword)
                    {
                        // use a RotationJig to get the rectangle rotation
                        var rotJig = new RotationJig(pline, pline.GetPoint3dAt(0), pline.Normal);
                        var result = ed.Drag(rotJig);
                        if (result.Status == PromptStatus.OK)
                            rectJig = new RectangleJig(pline, rotJig.Rotation);
                        else
                            break;
                    }
                    // Cancel
                    else
                        break;
                }
                tr.Commit();
            }
        }
    }

    public struct Rectangle
    {
        public Point2d Point0 { get; }
        public Point2d Point1 { get; }
        public Point2d Point2 { get; }
        public Point2d Point3 { get; }

        public Rectangle(Point2d firstCorner, Point2d oppositeCorner, double rotation)
        {
            Vector2d u = new Vector2d(Cos(rotation), Sin(rotation));
            Vector2d v = new Vector2d(-Sin(rotation), Cos(rotation));
            Vector2d diag = firstCorner.GetVectorTo(oppositeCorner);
            Point0 = firstCorner;
            Point1 = firstCorner + u * u.DotProduct(diag);
            Point2 = oppositeCorner;
            Point3 = firstCorner + v * v.DotProduct(diag);
        }
    }

    public class RectangleJig : EntityJig
    {
        Polyline pline;
        double ucsRot, rotation;
        Plane plane;
        Point3d dragPt, basePt;
        Point2d pt2D;
        Editor ed;
        CoordinateSystem3d ucs;

        public RectangleJig(Polyline pline, double rotation) : base(pline)
        {
            this.pline = pline;
            this.rotation = rotation;
            plane = new Plane(Point3d.Origin, pline.Normal);
            basePt = pline.GetPoint3dAt(0);
            pt2D = pline.GetPoint2dAt(0);
            ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
            ucs = ed.CurrentUserCoordinateSystem.CoordinateSystem3d;
            Matrix3d mat = Matrix3d.WorldToPlane(plane);
            ucsRot = Vector3d.XAxis.GetAngleTo(ucs.Xaxis.TransformBy(mat), Vector3d.ZAxis);
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            var msg = "\nSpecify other corner point or [Rotation]: ";
            var options = new JigPromptPointOptions(msg, "Rotation");
            options.AppendKeywordsToMessage = true;
            options.UseBasePoint = true;
            options.BasePoint = basePt;
            options.UserInputControls =
                UserInputControls.Accept3dCoordinates |
                UserInputControls.UseBasePointElevation;
            PromptPointResult result = prompts.AcquirePoint(options);
            if (result.Status == PromptStatus.Keyword)
            {
                pline.TransformBy(Matrix3d.Rotation(-rotation, pline.Normal, basePt));
                return SamplerStatus.OK;
            }
            if (result.Value.IsEqualTo(dragPt))
                return SamplerStatus.NoChange;

            dragPt = result.Value;
            return SamplerStatus.OK;
        }

        protected override bool Update()
        {
            var rectangle = new Rectangle(pt2D, dragPt.Convert2d(plane), rotation + ucsRot);
            pline.SetPointAt(1, rectangle.Point1);
            pline.SetPointAt(2, rectangle.Point2);
            pline.SetPointAt(3, rectangle.Point3);
            return true;
        }
    }

    public class RotationJig : DrawJig
    {
        Entity entity;
        double rotation;
        Point3d basePoint;
        Vector3d normal;

        public double Rotation => rotation;

        public RotationJig(Entity entity, Point3d basePoint, Vector3d normal)
        {
            this.entity = entity;
            this.basePoint = basePoint;
            this.normal = normal;
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            var options = new JigPromptAngleOptions("\nSpecify rotation angle: ");
            options.BasePoint = basePoint;
            options.UseBasePoint = true;
            options.Cursor = CursorType.RubberBand;
            options.UserInputControls =
                UserInputControls.Accept3dCoordinates |
                UserInputControls.UseBasePointElevation;
            var result = prompts.AcquireAngle(options);
            if (result.Value == rotation)
                return SamplerStatus.NoChange;
            rotation = result.Value;
            return SamplerStatus.OK;
        }

        protected override bool WorldDraw(AcGi.WorldDraw draw)
        {
            AcGi.WorldGeometry geom = draw.Geometry;
            if (geom != null)
            {
                geom.PushModelTransform(Matrix3d.Rotation(rotation, normal, basePoint));
                geom.Draw(entity);
                geom.PopModelTransform();
            }
            return true;
        }
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 19

Alexander.Rivilis
Mentor
Mentor

My sample with dynamic dimensions:

 

    using System;
    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Geometry;
    using Autodesk.AutoCAD.EditorInput;
     
    #pragma warning disable 0618
     
    // This line is not mandatory, but improves loading performances
    [assembly: CommandClass(typeof(TestDrawJigWithDynDim.MyCommands))]
     
    namespace TestDrawJigWithDynDim
    {
      public class MyCommands
      {
        [CommandMethod("TestDrawJig")]
        public void MyCommand() // This method can have any name
        {
          Document doc = Application.DocumentManager.MdiActiveDocument;
          Database db = doc.Database;
          if (doc == null) return;
          Editor ed = doc.Editor;
          Matrix3d mat = ed.CurrentUserCoordinateSystem;
          PromptPointResult res = ed.GetPoint("\nУкажите базовую точку: ");
          if (res.Status == PromptStatus.OK)
          {
            Point3d basePt = res.Value.TransformBy(mat);
            DrawJigWithDynDim jig = new DrawJigWithDynDim(basePt, 500, 500);
            if (jig.DragMe() == PromptStatus.OK)
            {
              Point3dCollection pts = new Point3dCollection();
              pts.Add(basePt);
              pts.Add(basePt + new Vector3d(0,         jig.height, 0));
              pts.Add(basePt + new Vector3d(jig.width, jig.height, 0));
              pts.Add(basePt + new Vector3d(jig.width,      0,     0));
              using (Polyline3d poly = new Polyline3d(Poly3dType.SimplePoly, pts, true))
              {
                using (BlockTableRecord btr = db.CurrentSpaceId.Open(OpenMode.ForWrite) as BlockTableRecord)
                {
                  btr.AppendEntity(poly);
                }
              }
            }
          }
        }
      }
     
      public class DrawJigWithDynDim: DrawJig
      {
        private DynamicDimensionDataCollection dimCol = new DynamicDimensionDataCollection();
        private Point3d basePt, prevPt;
        public double width  = 100, height  = 100;
        private double minWidth = 100, minHeight = 100;
        private bool bFixWidth  = false;
        private bool bFixHeight = false;
        public DrawJigWithDynDim(Point3d pt, double w, double h)
        {
          basePt = prevPt = pt; width = w; height = h;
        }
        public PromptStatus DragMe()
        {
          Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
          Database db = Application.DocumentManager.MdiActiveDocument.Database;
          Point3d p1 = basePt;
          Point3d p2 = basePt + new Vector3d(width, 0, 0);
          Point3d p3 = basePt + new Vector3d(0, height, 0);
          AlignedDimension dim1 = new AlignedDimension();
          dim1.DynamicDimension = true;
          AlignedDimension dim2 = new AlignedDimension();
          dim2.DynamicDimension = true;
          DynamicDimensionData ddim1 = new DynamicDimensionData(dim1, true, false);
          ddim1.Editable = true; ddim1.Focal = true;
          dimCol.Add(ddim1);
          DynamicDimensionData ddim2 = new DynamicDimensionData(dim2, true, false);
          ddim2.Editable = true; ddim2.Focal = true;
          dimCol.Add(ddim2);
          UpdateDimensions();
          PromptResult res;
          while ((res = ed.Drag(this)).Status == PromptStatus.Other);
          return (res.Status == PromptStatus.None) ? PromptStatus.OK : res.Status;
        }
        protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
        {
          Point3dCollection pts = new Point3dCollection();
          pts.Add(basePt);
          pts.Add(basePt + new Vector3d(0, height, 0));
          pts.Add(basePt + new Vector3d(width, height, 0));
          pts.Add(basePt + new Vector3d(width, 0, 0));
          pts.Add(basePt);
          return draw.Geometry.Polygon(pts);
        }
     
        protected override DynamicDimensionDataCollection GetDynamicDimensionData(double dimScale)
        {
          return dimCol;
        }
     
        protected override void OnDimensionValueChanged(DynamicDimensionChangedEventArgs e)
        {
          switch (e.Index)
          {
            case 0:
              if (e.Value.ToString() != "0") 
              {
                width = e.Value * Math.Sign(prevPt.X - basePt.X);
                bFixWidth = true;
              }
              else
              {
                bFixWidth = false;
              }
     
              break;
            case 1:
              if (e.Value.ToString() != "0")
              {
                height = e.Value * Math.Sign(prevPt.Y - basePt.Y);
                bFixHeight = true;
              }
              else
              {
                bFixHeight = false;
              }
     
              break;
          }
          UpdateDimensions();
        }
     
        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
          JigPromptPointOptions jigOpts = new JigPromptPointOptions();
          jigOpts.UserInputControls = 
            ( UserInputControls.Accept3dCoordinates | UserInputControls.NullResponseAccepted);
          jigOpts.BasePoint = basePt;
          jigOpts.UseBasePoint = true;
          jigOpts.Cursor = CursorType.RubberBand;
     
          jigOpts.Message = "\nУкажите диагональную точку: ";
          PromptPointResult dres = prompts.AcquirePoint(jigOpts);
          if (dres.Status != PromptStatus.OK && dres.Status != PromptStatus.Other)
            return SamplerStatus.Cancel;
          if (dres.Status == PromptStatus.OK)
          {
            Point3d curPt = dres.Value;
            if (curPt.DistanceTo(prevPt) < 1e-3)
              return SamplerStatus.NoChange;
            prevPt = curPt;
            if (!bFixWidth)
              width = Math.Max(Math.Abs(curPt.X - basePt.X), minWidth) * Math.Sign(curPt.X - basePt.X);
            if (!bFixHeight)
              height = Math.Max(Math.Abs(curPt.Y - basePt.Y), minHeight) * Math.Sign(curPt.Y - basePt.Y);
          }
          UpdateDimensions();
          return SamplerStatus.OK;
        }
     
        protected void UpdateDimensions()
        {
          Point3d p1 = basePt;
          Point3d p2 = basePt + new Vector3d(width, 0, 0);
          Point3d p3 = basePt + new Vector3d(0, height, 0);
          Point3d p4 = basePt + new Vector3d(width, height, 0);
          AlignedDimension dim;
          dim = dimCol[0].Dimension as AlignedDimension;
          dim.XLine1Point = p1;
          dim.XLine2Point = p2;
          dim.DimLinePoint = p1 + (p2 - p1) * 0.5 - 
            new Vector3d(0, minHeight, 0) * Math.Sign(p4.Y - p1.Y); 
          dim = dimCol[1].Dimension as AlignedDimension;
          dim.XLine1Point = p1;
          dim.XLine2Point = p3;
          dim.DimLinePoint = p1 + (p3 - p1) * 0.5 - 
            new Vector3d(minWidth, 0, 0) * Math.Sign(p4.X - p1.X); 
        }
      }
    }

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 4 of 19

Amremad
Collaborator
Collaborator

wow it's amazing .. 

 

but i need to learn all about Jig , but i can't find any full and easy lesson to help me about that . 

 

can't help me to find any lessons . 

0 Likes
Message 5 of 19

Alexander.Rivilis
Mentor
Mentor

@Anonymous wrote:

wow it's amazing .. 

 

but i need to learn all about Jig , but i can't find any full and easy lesson to help me about that . 

 

can't help me to find any lessons . 


It is impossible know ALL about Jig as far as this API is very complicated. There is no easy lesson. But you can study ready to use samples and can ask questions. Two samples you can see above.

 

Also some links:

 

http://adndevblog.typepad.com/autocad/2012/10/autocadnet-lesson-7-jig.html

http://through-the-interface.typepad.com/.services/blog/6a00d83452464869e200d83452baa169e2/search?filter.q=jig

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 6 of 19

Amremad
Collaborator
Collaborator

🙂 i'm trying to understand all samples that i found it since one week . 

 

it's very difficult 🙂 🙂 🙂 

 

i'm trying to make a jig sample can insert a rectangle with dim(250X300), and user can choose the angle in jig sampler after draw it , and if cancel won't draw any thing. 

 

so i'm trying to understand all this examples and try to modified it but failure to run. 

 

i hope to find any lesson just teach me abc for jig 🙂   i will see this link 

 

thanks every body

0 Likes
Message 7 of 19

Amremad
Collaborator
Collaborator

123.JPG

0 Likes
Message 8 of 19

Alexander.Rivilis
Mentor
Mentor

I just downloaded this file from the link. It's all right and it's in place.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 9 of 19

Amremad
Collaborator
Collaborator

i'm trying to open it but chrome tell me

Capture.JPG 

0 Likes
Message 10 of 19

Alexander.Rivilis
Mentor
Mentor

I've attached webcast to this post.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 11 of 19

Amremad
Collaborator
Collaborator

IT DOESN'T WORK ALSO

0 Likes
Message 12 of 19

Alexander.Rivilis
Mentor
Mentor

How bad it all is ...

1. Download attached zip-file

2. Extract (copy in other directory) all files from zip-file.

3. Do as I show:

 

4. If you do not hear the sounds, you can open the Audio1.wmv file from the Audio directory

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 13 of 19

BKSpurgeon
Collaborator
Collaborator

i might write a tutorial on this Revills jig - looks very nice doesn't it?

 

might be two weeks but i'll get there.

0 Likes
Message 14 of 19

Alexander.Rivilis
Mentor
Mentor

@BKSpurgeon

 

Sorry but there are 3 mistakes in my surname. How can you write a guide to my jig?  😉

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 15 of 19

BKSpurgeon
Collaborator
Collaborator
Apologies sir for the spelling i will make a good attempt at the guide - if
you have no objections and will permit me 🙂

Chrs

Ben
0 Likes
Message 16 of 19

Alexander.Rivilis
Mentor
Mentor

You can try do it.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 17 of 19

BKSpurgeon
Collaborator
Collaborator

Hi Gilles

 

Thank you for your code.

 

Would you be able to elaborate on what Matrix3d.WorldToPlane(plane) method is doing?

 

(If a tranformation matrix is return from this method, and if it describes how to convert from one coordinate system to another, how can it work? (Because when a plane is defined: a normal vector and an origin is enough to define it - meaning that the x and y axis can be pointing anywhere - so am confused as to what it is doing, and how it will work. )

 

The documentation gives this reply, which I can't make sense of:

 

 

 

WorldToPlane.PNG

0 Likes
Message 18 of 19

_gile
Consultant
Consultant

@BKSpurgeon wrote:

Would you be able to elaborate on what Matrix3d.WorldToPlane(plane) method is doing?

 

(If a tranformation matrix is return from this method, and if it describes how to convert from one coordinate system to another, how can it work? (Because when a plane is defined: a normal vector and an origin is enough to define it - meaning that the x and y axis can be pointing anywhere - so am confused as to what it is doing, and how it will work. )


To define a coordinate system given a normal vector (Z axis), AutoCAD uses the "Arbitrary Axis Algorithm".



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 19 of 19

BKSpurgeon
Collaborator
Collaborator

Thank you!

0 Likes