Author Topic: Rotate grip to match direction  (Read 3497 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6144
Rotate grip to match direction
« on: October 11, 2012, 12:45:19 PM »
I am not sure what the correct words are how to ask the question correctly, I cheated to pass Calculus 3.
 
 
If I got segment from a polyline the LineSegment3D has a direction property how do I apply that or what do I have to do to translate it?
 

 
For example in the pic above what do i have to do with direction vector information to make it rotate with line? I know it is some math but just not coming to me.
 
Here is the test code thrown together to see how it worked.
Code - C#: [Select]
  1.    public class ConduitGripData : GripData
  2.     {
  3.       public GripType GripType { get; set; }
  4.        public override bool ViewportDraw(Autodesk.AutoCAD.GraphicsInterface.ViewportDraw worldDraw, ObjectId entityId, DrawType type, Autodesk.AutoCAD.Geometry.Point3d? imageGripPoint, int gripSizeInPixels)
  5.        {
  6.            
  7.            Point2d glyphSize = worldDraw.Viewport.GetNumPixelsInUnitSquare(this.GripPoint);
  8.            Double glyphHeight = (gripSizeInPixels / glyphSize.Y);
  9.            Matrix3d e2w = worldDraw.Viewport.EyeToWorldTransform;
  10.            Point3d pnt = this.GripPoint.TransformBy(e2w);
  11.            Point3dCollection pnts = GlyphPoints(glyphHeight, pnt);
  12.            worldDraw.Geometry.DeviceContextPolygon(pnts);
  13.            return false;
  14.        }
  15.        private Point3dCollection GlyphPoints(double glyphHeight, Point3d pnt)
  16.        {
  17.            Point3dCollection pnts = new Point3dCollection();
  18.            switch (GripType)
  19.            {
  20.                case GripType.MidPoint:
  21.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 1.5), pnt.Y + (glyphHeight / 2), pnt.Z));
  22.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 1.5), pnt.Y - (glyphHeight / 2), pnt.Z));
  23.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 1.5), pnt.Y - (glyphHeight / 2), pnt.Z));
  24.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 1.5), pnt.Y + (glyphHeight / 2), pnt.Z));
  25.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 1.5), pnt.Y + (glyphHeight / 2), pnt.Z));
  26.                    return pnts;
  27.                default:
  28.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 0.57736), pnt.Y + glyphHeight, pnt.Z));
  29.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 1.1547), pnt.Y, pnt.Z));
  30.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 0.57736), pnt.Y - glyphHeight, pnt.Z));
  31.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 0.57736), pnt.Y - glyphHeight, pnt.Z));
  32.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 1.1547), pnt.Y, pnt.Z));
  33.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 0.57736), pnt.Y + glyphHeight, pnt.Z));
  34.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 0.57736), pnt.Y + glyphHeight, pnt.Z));
  35.                    return pnts;
  36.            }
  37.        }
  38.  

 
 

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Rotate grip to match direction
« Reply #1 on: October 12, 2012, 08:02:17 AM »
With a sample from Balaji Ramamoorthy I was able get it working for now.
 
 
Code - C#: [Select]
  1.  
  2.     public class ConduitGripData : GripData
  3.     {
  4.       public GripType GripType { get; set; }
  5.       public Vector3d Direction { get; set; }
  6.        public override bool ViewportDraw(Autodesk.AutoCAD.GraphicsInterface.ViewportDraw worldDraw, ObjectId entityId, DrawType type, Autodesk.AutoCAD.Geometry.Point3d? imageGripPoint, int gripSizeInPixels)
  7.        {
  8.            
  9.            Point2d glyphSize = worldDraw.Viewport.GetNumPixelsInUnitSquare(this.GripPoint);
  10.            Double glyphHeight = (gripSizeInPixels / glyphSize.Y);
  11.            Matrix3d e2w = worldDraw.Viewport.EyeToWorldTransform;
  12.            Point3d pnt = this.GripPoint.TransformBy(e2w);
  13.            Point3dCollection pnts = GlyphPoints(glyphHeight, pnt, this.Direction);
  14.            worldDraw.Geometry.DeviceContextPolygon(pnts);
  15.            return false;
  16.        }
  17.        private Point3dCollection GlyphPoints(double glyphHeight, Point3d pnt, Vector3d direction)
  18.        {
  19.            Point3dCollection pnts = new Point3dCollection();
  20.            switch (GripType)
  21.            {
  22.                case GripType.MidPoint:
  23.  
  24.                    Vector3d perpDirection = direction.GetPerpendicularVector();
  25.                    
  26.                    Matrix3d mat = Matrix3d.Displacement(direction.Negate().GetNormal() * glyphHeight * 1.5);
  27.                    mat = mat.PreMultiplyBy(Matrix3d.Displacement(perpDirection.GetNormal() * glyphHeight * 0.5));
  28.                    Point3d p1 = pnt.TransformBy(mat);
  29.  
  30.                    mat = Matrix3d.Displacement(direction.Negate().GetNormal() * glyphHeight * 1.5);          
  31.                    mat = mat.PreMultiplyBy(Matrix3d.Displacement(perpDirection.Negate().GetNormal() * glyphHeight * 0.5));        
  32.                    Point3d p2 = pnt.TransformBy(mat);
  33.  
  34.                    mat = Matrix3d.Displacement(direction.GetNormal() * glyphHeight * 1.5);    
  35.                    mat = mat.PreMultiplyBy(Matrix3d.Displacement(perpDirection.Negate().GetNormal() * glyphHeight * 0.5));
  36.                    Point3d p3 = pnt.TransformBy(mat);
  37.                    
  38.                    mat = Matrix3d.Displacement(direction.GetNormal() * glyphHeight * 1.5);
  39.                    mat = mat.PreMultiplyBy(Matrix3d.Displacement(perpDirection.GetNormal() * glyphHeight * 0.5));
  40.                    Point3d p4 = pnt.TransformBy(mat);
  41.                    
  42.                    pnts.Add(p1);
  43.                    pnts.Add(p2);
  44.                    pnts.Add(p3);
  45.                    pnts.Add(p4);
  46.                    pnts.Add(p1);
  47.                    return pnts;
  48.                default:
  49.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 0.57736), pnt.Y + glyphHeight, pnt.Z));
  50.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 1.1547), pnt.Y, pnt.Z));
  51.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 0.57736), pnt.Y - glyphHeight, pnt.Z));
  52.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 0.57736), pnt.Y - glyphHeight, pnt.Z));
  53.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 1.1547), pnt.Y, pnt.Z));
  54.                    pnts.Add(new Point3d(pnt.X - (glyphHeight * 0.57736), pnt.Y + glyphHeight, pnt.Z));
  55.                    pnts.Add(new Point3d(pnt.X + (glyphHeight * 0.57736), pnt.Y + glyphHeight, pnt.Z));
  56.                    return pnts;
  57.            }
  58.        }
  59.     }
  60.  

BlackBox

  • King Gator
  • Posts: 3770
Re: Rotate grip to match direction
« Reply #2 on: October 12, 2012, 09:13:23 AM »
I recently watched the first ADN DevTech video, and they went around the room speaking to participants that came to a DevDays session... One of them was adding custom grips as well, which sparked some interest for what we do here at my office.

Not really sure where to begin, so I thank you for posting the sample code here, Jeff.

Would you mind also posting a link, or file path (if part of SDK) to that sample you found useful?

TIA
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Rotate grip to match direction
« Reply #3 on: October 12, 2012, 09:37:19 AM »
That example did not do much as was starting off getting something working and actually does not work for doing anything for the grips.

The example mentioned was a email from ADn response so I am not sure I could post it and had nothing to do with grips but was similiar to below but asked for two points and added 4 DBPoints at four corners after finding midpoint.
 
Here is one that might help
http://through-the-interface.typepad.com/through_the_interface/2012/09/overriding-the-grips-of-an-autocad-polyline-to-maintain-fillet-segments-using-net.html

BlackBox

  • King Gator
  • Posts: 3770
Re: Rotate grip to match direction
« Reply #4 on: October 12, 2012, 09:40:38 AM »
That example did not do much as was starting off getting something working and actually does not work for doing anything for the grips.

The example mentioned was a email from ADn response so I am not sure I could post it and had nothing to do with grips but was similiar to below but asked for two points and added 4 DBPoints at four corners after finding midpoint.
 
Here is one that might help
http://through-the-interface.typepad.com/through_the_interface/2012/09/overriding-the-grips-of-an-autocad-polyline-to-maintain-fillet-segments-using-net.html

No worries; Thanks for the link!
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Rotate grip to match direction
« Reply #5 on: October 12, 2012, 09:44:01 AM »
There is much more to add but for starters for drawing your grip points you can use the class in previous post that inherits from GripData, and set the points that will be called in the ViewportDraw method in previous post from GetGrippoints in a class below that inherits GripOverrule
 
Code - C#: [Select]
  1.  
  2.   public class ConduitGripOverrule : GripOverrule
  3.     {
  4.         public static bool OverrulesOn = false;
  5.         public static ConduitGripOverrule CndtOverrule = new ConduitGripOverrule();
  6.         public override void GetGripPoints(Entity entity, GripDataCollection grips, double curViewUnitSize, int gripSize, Vector3d curViewDir, GetGripPointsFlags bitFlags)
  7.         {
  8.             Polyline plyLine = entity as Polyline;
  9.             SegmentType previousSegmentType = SegmentType.Empty;
  10.             for (int i = 0; i < plyLine.NumberOfVertices; i++)
  11.             {
  12.                 if (plyLine.GetSegmentType(i) == SegmentType.Line)
  13.                 {
  14.                     LineSegment3d lseg = plyLine.GetLineSegmentAt(i);
  15.                     if (previousSegmentType != SegmentType.Line)
  16.                     {
  17.                         ConduitGripData cndtGripDataStartPoint = new ConduitGripData();
  18.                         cndtGripDataStartPoint.GripPoint = lseg.StartPoint;
  19.                         cndtGripDataStartPoint.GripType = GripType.StartPoint;
  20.                         cndtGripDataStartPoint.Direction = lseg.Direction;
  21.                         grips.Add(cndtGripDataStartPoint);
  22.                     }
  23.                     ConduitGripData cndtGripDataMidPoint = new ConduitGripData();
  24.                     cndtGripDataMidPoint.GripPoint = lseg.MidPoint;
  25.                     cndtGripDataMidPoint.GripType = GripType.MidPoint;
  26.                     cndtGripDataMidPoint.Direction = lseg.Direction;
  27.                     grips.Add(cndtGripDataMidPoint);
  28.  
  29.                     ConduitGripData cndtGripDataEndPoint = new ConduitGripData();
  30.                     cndtGripDataEndPoint.GripPoint = lseg.EndPoint;
  31.                     cndtGripDataEndPoint.GripType = GripType.EndPoint;
  32.                     cndtGripDataEndPoint.Direction = lseg.Direction;
  33.                     grips.Add(cndtGripDataEndPoint);
  34.                    
  35.                 }
  36.                 previousSegmentType = plyLine.GetSegmentType(i);
  37.             }
  38.            
  39.             //base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags);
  40.         }
  41.         public override void MoveGripPointsAt(Entity entity, GripDataCollection grips, Vector3d offset, MoveGripPointsFlags bitFlags)
  42.         {
  43.             base.MoveGripPointsAt(entity, grips, offset, bitFlags);
  44.         }
  45.         //public override void MoveGripPointsAt(Entity entity, IntegerCollection indices, Vector3d offset)
  46.         //{
  47.         //    base.MoveGripPointsAt(entity, indices, offset);
  48.         //}
  49.     }
  50.  

TheMaster

  • Guest
Re: Rotate grip to match direction
« Reply #6 on: October 13, 2012, 10:08:09 PM »
With a sample from Balaji Ramamoorthy I was able get it working for now.
 
 
Code - C#: [Select]
  1.  
  2.  
  3.   <snip>
  4.  
  5.  
  6.  

That's the example he gave you?

To merely rotate the grip, you can just push/pop the model transform
before/after supermessaging the base class's ViewportDraw method, and
there's no need to draw it yourself.

See Geometry.PushOrientation() and Geometry.PopOrientation() in the docs.

The first would be called before you call base.ViewportDraw(), and the
second would be called after it returns.

If this is a representative example of the kind of support that paying customers get, then they're getting robbed.