Code Red > .NET

** SOLVED ** - Alignment Parameter in Jig

(1/1)

cmwade77:
I am trying to create a jig that simulates the alignment parameter, which I found the code below at: https://spiderinnet1.typepad.com/blog/2012/11/autocad-net-jig-dynamic-block-with-alignment-parameter-using-entityjig.html

The problem is that it will align to non-nested entities, but not to any entities nested in a block or xRef, I have tried many different variations to fix this, but nothin has worked so far, can you please help me?

ETA: Solution in 3rd Post


--- Code - C#: ---public class DynamicBlockAlignmentJig : EntityJig{    #region Fields     private int mCurJigFactorNumber = 1;     private bool mIsDynamicAlignment = false;    private double mAlignmentAngle = 0.0;    private ObjectId mObjectIdToAlignWith = ObjectId.Null;     private double mAngleOffset = 0.0;    private Point3d mPosition = new Point3d(0, 0, 0); // Factor #1    private double mRotation = 0.0;                 // Factor #2    private double mScaleFactor = 1.0;              // Factor #3     #endregion     #region Constructors     public DynamicBlockAlignmentJig(BlockReference ent)        : base(ent)    {        mAngleOffset = ent.Rotation;         if (ent.IsDynamicBlock)            mIsDynamicAlignment = true;    }     #endregion     #region Properties     protected static Editor CurEditor    {        get        {            return Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument.Editor;        }    }     protected static Matrix3d UCS    {        get        {            return CurEditor.CurrentUserCoordinateSystem;        }    }     protected new BlockReference Entity    {        get        {            return (BlockReference)base.Entity;        }    }     #endregion     #region Overrides     protected override bool Update()    {        switch (mCurJigFactorNumber)        {            case 1:                Entity.Position = mPosition.TransformBy(UCS);                if (mIsDynamicAlignment && !mObjectIdToAlignWith.IsNull)                {                    if (mObjectIdToAlignWith.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Curve))))                    {                        Curve curve = (Curve)Entity.Database.TransactionManager.TopTransaction.GetObject(mObjectIdToAlignWith, OpenMode.ForRead);                        Vector3d dir = curve.GetFirstDerivative(curve.GetClosestPointTo(Entity.Position, false)).TransformBy(UCS.Inverse());                        mAlignmentAngle = Vector3d.XAxis.GetAngleTo(dir, Vector3d.ZAxis);                        Entity.Rotation = mAlignmentAngle + mAngleOffset;                    }                    else                        mObjectIdToAlignWith = ObjectId.Null;                }                break;            case 2:                Entity.Rotation = mRotation + mAngleOffset;                ;                break;            case 3:                Entity.ScaleFactors = new Scale3d(mScaleFactor);                break;            default:                break;        }         return true;    }     protected override SamplerStatus Sampler(JigPrompts prompts)    {        switch (mCurJigFactorNumber)        {            case 1:                JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nBlock insertion point:");                PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);                if (prResult1.Status == PromptStatus.Cancel)                    return SamplerStatus.Cancel;                 Point3d tempPt = prResult1.Value.TransformBy(UCS.Inverse());                if (tempPt.IsEqualTo(mPosition))                {                    return SamplerStatus.NoChange;                }                else                {                    mPosition = tempPt;                    mObjectIdToAlignWith = pickObjId;                    return SamplerStatus.OK;                }            case 2:                JigPromptAngleOptions prOptions2 = new JigPromptAngleOptions("\nBlock rotation angle:");                prOptions2.BasePoint = mPosition.TransformBy(UCS);                prOptions2.UseBasePoint = true;                PromptDoubleResult prResult2 = prompts.AcquireAngle(prOptions2);                if (prResult2.Status == PromptStatus.Cancel)                    return SamplerStatus.Cancel;                 if (prResult2.Value.Equals(mRotation))                {                    return SamplerStatus.NoChange;                }                else                {                    mRotation = prResult2.Value;                    return SamplerStatus.OK;                }            case 3:                JigPromptDistanceOptions prOptions3 = new JigPromptDistanceOptions("\nBlock scale factor:");                prOptions3.BasePoint = mPosition.TransformBy(UCS);                prOptions3.UseBasePoint = true;                PromptDoubleResult prResult3 = prompts.AcquireDistance(prOptions3);                if (prResult3.Status == PromptStatus.Cancel)                    return SamplerStatus.Cancel;                 if (prResult3.Value.Equals(mScaleFactor))                {                    return SamplerStatus.NoChange;                }                else                {                    mScaleFactor = prResult3.Value;                    return SamplerStatus.OK;                }            default:                break;        }         return SamplerStatus.OK;    }     #endregion     #region Point Monitor     private static ObjectId pickObjId = ObjectId.Null;    private static void Editor_PointMonitor(object sender, PointMonitorEventArgs e)    {        Point3d computedPt = e.Context.ComputedPoint;        FullSubentityPath[] pickedEnts = e.Context.GetPickedEntities();         if (pickedEnts != null && pickedEnts.Length > 0)        {            pickObjId = pickedEnts[0].GetObjectIds()[0];        }        else            pickObjId = ObjectId.Null;    }     #endregion     #region Method to Call     public static bool Jig(BlockReference ent)    {        try        {            DynamicBlockAlignmentJig jigger = new DynamicBlockAlignmentJig(ent);            PromptResult pr;            do            {                pr = CurEditor.Drag(jigger);                if (jigger.mCurJigFactorNumber == 1 && jigger.mIsDynamicAlignment && !jigger.mObjectIdToAlignWith.IsNull)                    jigger.mCurJigFactorNumber++;            } while (pr.Status != PromptStatus.Cancel && pr.Status != PromptStatus.Error && jigger.mCurJigFactorNumber++ <= 3);             return pr.Status == PromptStatus.OK;        }        catch        {            return false;        }    }     #endregion     #region Test Command     [CommandMethod("DynamicBlockAlignmentJig")]    public static void BlockAttributeJig_Method()    {        Database db = HostApplicationServices.WorkingDatabase;        try        {            PromptResult pr = CurEditor.GetString("\nName of the block to jig:");            if (pr.Status == PromptStatus.OK)            {                using (Transaction tr = db.TransactionManager.StartTransaction())                {                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);                    if (!bt.Has(pr.StringResult))                    {                        CurEditor.WriteMessage("\nThe block <{0}> does not exist.", pr.StringResult);                        return;                    }                     BlockTableRecord btr = tr.GetObject(bt[pr.StringResult], OpenMode.ForRead) as BlockTableRecord;                    using (BlockReference ent = new BlockReference(new Point3d(0, 0, 0), btr.ObjectId))                    {                        ent.TransformBy(UCS);                        BlockTableRecord modelspace = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);                        modelspace.AppendEntity(ent);                        tr.AddNewlyCreatedDBObject(ent, true);                         CurEditor.TurnForcedPickOn();                        CurEditor.PointMonitor += Editor_PointMonitor;                         if (DynamicBlockAlignmentJig.Jig(ent))                            tr.Commit();                         CurEditor.PointMonitor -= Editor_PointMonitor;                        CurEditor.TurnForcedPickOff();                    }                }            }        }        catch (Autodesk.AutoCAD.Runtime.Exception ex)        {            CurEditor.WriteMessage(ex.Message);        }    }     #endregion

cmwade77:
I also attempted a bit different approach, as follows:


--- Code - C#: --- public class BlockInsertJig : EntityJig {     private Point3d position;     private Matrix3d alignmentTransform;     private BlockReference blockRef;     private Point3d? point1;     private Point3d? point2;      public BlockInsertJig(BlockReference blockReference) : base(blockReference)     {         blockRef = blockReference;         position = blockReference.Position;         alignmentTransform = Matrix3d.Identity;     }      protected override SamplerStatus Sampler(JigPrompts prompts)     {         JigPromptPointOptions options = new JigPromptPointOptions("\nInsertion point: ");         options.UserInputControls = (UserInputControls.Accept3dCoordinates | UserInputControls.NoNegativeResponseAccepted);         PromptPointResult result = prompts.AcquirePoint(options);          if (result.Status == PromptStatus.OK && result.Value != position)         {             position = result.Value;             return SamplerStatus.OK;         }          return SamplerStatus.NoChange;     }      protected override bool Update()     {         if (point1.HasValue && point2.HasValue)         {             Vector3d direction = point2.Value - point1.Value;             double angle = Vector3d.XAxis.GetAngleTo(direction, Vector3d.ZAxis);             alignmentTransform = Matrix3d.Rotation(angle, Vector3d.ZAxis, blockRef.Position);         }         else         {             alignmentTransform = Matrix3d.Identity;         }          blockRef.Position = position;         blockRef.TransformBy(alignmentTransform);          return true;     }      public void SetAlignmentPoints(Point3d p1, Point3d p2)     {         point1 = p1;         point2 = p2;     }      public void ClearAlignmentPoints()     {         point1 = null;         point2 = null;     } }     public class Commands2 {     private static BlockInsertJig jig;     [CommandMethod("InsertAlignedBlock")]      public void InsertAlignedBlock()     {         Document doc = Application.DocumentManager.MdiActiveDocument;         Database db = doc.Database;         Editor ed = doc.Editor;          // Load or define the block to be inserted         ObjectId blockId = ObjectId.Null;         // Assuming the block is already defined in the drawing          using (Transaction tr = db.TransactionManager.StartTransaction())         {             BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);             BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);              BlockReference blockRef = new BlockReference(Point3d.Origin, bt["ROUND_TAKEOFF_SIDE"]);             btr.AppendEntity(blockRef);             tr.AddNewlyCreatedDBObject(blockRef, true);              jig = new BlockInsertJig(blockRef);              ed.PointMonitor += OnPointMonitor;              PromptResult res = ed.Drag(jig);              ed.PointMonitor -= OnPointMonitor;              if (res.Status == PromptStatus.OK)             {                 tr.Commit();             }             else             {                 tr.Abort();             }         }     }      private static void OnPointMonitor(object sender, PointMonitorEventArgs e)     {         Document doc = Application.DocumentManager.MdiActiveDocument;         Editor ed = doc.Editor;         FullSubentityPath[] paths = e.Context.GetPickedEntities();         if (paths.Length > 0)         {             using (Transaction tr = doc.TransactionManager.StartTransaction())             {                 Entity entity = tr.GetObject(paths[0].GetObjectIds()[0], OpenMode.ForRead) as Entity;                  if (entity != null && entity is Curve curve)                 {                     ed.WriteMessage("\nWorks");                     Point3d closestPoint = curve.GetClosestPointTo(e.Context.RawPoint, false);                     Vector3d direction = curve.GetFirstDerivative(closestPoint);                     Point3d secondPoint = closestPoint + direction;                      jig.SetAlignmentPoints(closestPoint, secondPoint);                 }                 else                 {                     jig.ClearAlignmentPoints();                 }                  tr.Commit();             }         }         else         {             jig.ClearAlignmentPoints();         }     }  }
In this one I tried using alignment points instead.

cmwade77:
I finally got it, it may not be the most elegant solution, but it does get the job done:

--- Code - C#: ---public class DynamicBlockAlignmentJig : EntityJig{    #region Fields     private int mCurJigFactorNumber = 1;     private bool mIsDynamicAlignment = false;    private double mAlignmentAngle = 0.0;    private ObjectId mObjectIdToAlignWith = ObjectId.Null;     private double mAngleOffset = 0.0;    private Point3d mPosition = new Point3d(0, 0, 0); // Factor #1    private double mRotation = 0.0;                 // Factor #2    private double mScaleFactor = 1.0;              // Factor #3    private static ObjectId pickBlockRefId = ObjectId.Null;     #endregion     #region Constructors     public DynamicBlockAlignmentJig(BlockReference ent)        : base(ent)    {        mAngleOffset = ent.Rotation;         if (ent.IsDynamicBlock)            mIsDynamicAlignment = true;    }     #endregion     #region Properties     protected static Editor CurEditor    {        get        {            return Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument.Editor;        }    }     protected static Matrix3d UCS    {        get        {            return CurEditor.CurrentUserCoordinateSystem;        }    }     protected new BlockReference Entity    {        get        {            return (BlockReference)base.Entity;        }    }     #endregion     #region Overrides     protected override bool Update()    {        switch (mCurJigFactorNumber)        {            case 1:                Entity.Position = mPosition.TransformBy(UCS);                if (mIsDynamicAlignment && !mObjectIdToAlignWith.IsNull)                {                    using (Transaction tr = Entity.Database.TransactionManager.StartTransaction())                    {                        DBObject obj = tr.GetObject(mObjectIdToAlignWith, OpenMode.ForRead);                        if (obj is Curve curve)                        {                            Matrix3d transform = Matrix3d.Identity;                            if (!pickBlockRefId.IsNull) // Check if the subentity is part of a block                            {                                BlockReference blockRef = tr.GetObject(pickBlockRefId, OpenMode.ForRead) as BlockReference;                                if (blockRef != null)                                {                                    transform = blockRef.BlockTransform;                                }                            }                             curve = (Curve)curve.GetTransformedCopy(transform);                            Point3d closestPoint = curve.GetClosestPointTo(Entity.Position, false);                            Vector3d dir = curve.GetFirstDerivative(closestPoint).TransformBy(UCS.Inverse());                            mAlignmentAngle = Vector3d.XAxis.GetAngleTo(dir, Vector3d.ZAxis);                            Entity.Rotation = mAlignmentAngle + mAngleOffset;                        }                        else                        {                            mObjectIdToAlignWith = ObjectId.Null;                        }                         tr.Commit();                    }                }                break;                // Other cases remain unchanged        }         return true;    }      protected override SamplerStatus Sampler(JigPrompts prompts)    {        switch (mCurJigFactorNumber)        {            case 1:                JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nBlock insertion point:");                PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);                if (prResult1.Status == PromptStatus.Cancel)                    return SamplerStatus.Cancel;                 Point3d tempPt = prResult1.Value.TransformBy(UCS.Inverse());                if (tempPt.IsEqualTo(mPosition))                {                    return SamplerStatus.NoChange;                }                else                {                    mPosition = tempPt;                    mObjectIdToAlignWith = pickObjId;                    return SamplerStatus.OK;                }            case 2:                JigPromptAngleOptions prOptions2 = new JigPromptAngleOptions("\nBlock rotation angle:");                prOptions2.BasePoint = mPosition.TransformBy(UCS);                prOptions2.UseBasePoint = true;                PromptDoubleResult prResult2 = prompts.AcquireAngle(prOptions2);                if (prResult2.Status == PromptStatus.Cancel)                    return SamplerStatus.Cancel;                 if (prResult2.Value.Equals(mRotation))                {                    return SamplerStatus.NoChange;                }                else                {                    mRotation = prResult2.Value;                    return SamplerStatus.OK;                }            case 3:                JigPromptDistanceOptions prOptions3 = new JigPromptDistanceOptions("\nBlock scale factor:");                prOptions3.BasePoint = mPosition.TransformBy(UCS);                prOptions3.UseBasePoint = true;                PromptDoubleResult prResult3 = prompts.AcquireDistance(prOptions3);                if (prResult3.Status == PromptStatus.Cancel)                    return SamplerStatus.Cancel;                 if (prResult3.Value.Equals(mScaleFactor))                {                    return SamplerStatus.NoChange;                }                else                {                    mScaleFactor = prResult3.Value;                    return SamplerStatus.OK;                }            default:                break;        }         return SamplerStatus.OK;    }     #endregion     #region Point Monitor     private static ObjectId pickObjId = ObjectId.Null;     private static void Editor_PointMonitor(object sender, PointMonitorEventArgs e)    {        Document doc = Application.DocumentManager.MdiActiveDocument;        Database db = doc.Database;        Editor ed = doc.Editor;         if (e.Context == null)        {            return;        }         FullSubentityPath[] fullEntPath = e.Context.GetPickedEntities();         if (fullEntPath.Length > 0)        {            try            {                using (Transaction tr = db.TransactionManager.StartTransaction())                {                    Entity topLevelEntity = tr.GetObject(fullEntPath.First().GetObjectIds().First(), OpenMode.ForRead) as Entity;                    Point3d cursorPosition = e.Context.ComputedPoint;                     if (topLevelEntity is BlockReference blockRef)                    {                        BlockTableRecord blockDef = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;                         foreach (ObjectId entId in blockDef)                        {                            Entity subEntity = tr.GetObject(entId, OpenMode.ForRead) as Entity;                            if (IsCursorOnEntity(subEntity, cursorPosition, blockRef, tr))                            {                                pickObjId = subEntity.ObjectId;                                pickBlockRefId = blockRef.ObjectId; // Store the block reference ObjectId                                break;                            }                        }                    }                    else                    {                        pickObjId = topLevelEntity.ObjectId;                        pickBlockRefId = ObjectId.Null; // Reset the block reference ObjectId                    }                     tr.Commit();                }            }            catch (System.Exception ex)            {                pickObjId = ObjectId.Null;                pickBlockRefId = ObjectId.Null;            }        }        else        {            pickObjId = ObjectId.Null;            pickBlockRefId = ObjectId.Null;        }    }      #endregion      // Helper method to check if the cursor is on the entity within a block reference    private static bool IsCursorOnEntity(Entity entity, Point3d cursorPosition, BlockReference blockRef, Transaction tr)    {        // Adjust tolerance as needed        double tolerance = 0.01;         // Transform the cursor position from WCS to the block reference's ECS        Matrix3d transform = blockRef.BlockTransform.Inverse();        Point3d transformedCursorPosition = cursorPosition.TransformBy(transform);         if (entity is Curve curve)        {            // Get the closest point on the curve to the transformed cursor position            Point3d closestPoint = curve.GetClosestPointTo(transformedCursorPosition, false);            // Check if the distance between the closest point and the transformed cursor position is within the tolerance            return transformedCursorPosition.DistanceTo(closestPoint) <= tolerance;        }        else        {            // For non-curve entities, check if the transformed cursor position is within the entity's geometric extents            Extents3d extents = entity.GeometricExtents;            return transformedCursorPosition.X >= extents.MinPoint.X - tolerance &&                   transformedCursorPosition.X <= extents.MaxPoint.X + tolerance &&                   transformedCursorPosition.Y >= extents.MinPoint.Y - tolerance &&                   transformedCursorPosition.Y <= extents.MaxPoint.Y + tolerance &&                   transformedCursorPosition.Z >= extents.MinPoint.Z - tolerance &&                   transformedCursorPosition.Z <= extents.MaxPoint.Z + tolerance;        }    }          #region Method to Call     public static bool Jig(BlockReference ent)    {        try        {            DynamicBlockAlignmentJig jigger = new DynamicBlockAlignmentJig(ent);            PromptResult pr;            do            {                pr = CurEditor.Drag(jigger);                if (jigger.mCurJigFactorNumber == 1 && jigger.mIsDynamicAlignment && !jigger.mObjectIdToAlignWith.IsNull)                    jigger.mCurJigFactorNumber++;            } while (pr.Status != PromptStatus.Cancel && pr.Status != PromptStatus.Error && jigger.mCurJigFactorNumber++ <= 3);             return pr.Status == PromptStatus.OK;        }        catch        {            return false;        }    }     #endregion     #region Test Command     [CommandMethod("DynamicBlockAlignmentJig")]    public static void BlockAttributeJig_Method()    {        Database db = HostApplicationServices.WorkingDatabase;        try        {            string pr = "ROUND_TAKEOFF_SIDE";             using (Transaction tr = db.TransactionManager.StartTransaction())            {                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);                if (!bt.Has(pr))                {                    CurEditor.WriteMessage("\nThe block <{0}> does not exist.", pr);                    return;                }                 BlockTableRecord btr = tr.GetObject(bt[pr], OpenMode.ForRead) as BlockTableRecord;                using (BlockReference ent = new BlockReference(new Point3d(0, 0, 0), btr.ObjectId))                {                    ent.TransformBy(UCS);                    BlockTableRecord modelspace = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);                    modelspace.AppendEntity(ent);                    tr.AddNewlyCreatedDBObject(ent, true);                     CurEditor.TurnForcedPickOn();                    CurEditor.PointMonitor += Editor_PointMonitor;                     if (DynamicBlockAlignmentJig.Jig(ent))                        tr.Commit();                     CurEditor.PointMonitor -= Editor_PointMonitor;                    CurEditor.TurnForcedPickOff();                }            }         }        catch (Autodesk.AutoCAD.Runtime.Exception ex)        {            CurEditor.WriteMessage(ex.Message);        }         #endregion        }}

Navigation

[0] Message Index

Go to full version