Author Topic: Debugging Help  (Read 388 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
Debugging Help
« on: February 29, 2024, 07:53:09 PM »
I am having some errors on occasion with the code below:

The errors are below the code, I believe the errors are coming form IsCursorOnEntity, but not positive.
If anyone can help, I would greatly appreciate it.

I have also attached the block that I am inserting with this code, I know the issue is inside the jig somewhere though.

Code - C#: [Select]
  1.     internal class BlockJig : EntityJig
  2.     {
  3.         private Database _database; // Add a field to store the database
  4.         private Point3d mPosition = Point3d.Origin;        
  5.         private ObjectId mObjectIdToAlignWith = ObjectId.Null;
  6.         private DynamicBlockReferenceProperty mLengthProperty = null;
  7.         private static ObjectId pickObjId = ObjectId.Null;
  8.         private static ObjectId pickBlockRefId = ObjectId.Null;
  9.         private double mAngleOffset = 0.0;
  10.         private bool mFlipAlignment = false; // Field to store the flip state
  11.         private double mAlignmentAngle = 0.0;
  12.         private bool mLastTabState = false;
  13.         private DateTime mLastTabToggleTime = DateTime.MinValue;
  14.         private TimeSpan mDebounceInterval = TimeSpan.FromMilliseconds(200);
  15.            
  16.        
  17.  
  18.  
  19.         public BlockJig(BlockReference blockRef, Database database) : base(blockRef)
  20.         {
  21.             // Check if the block has an alignment parameter
  22.             if (blockRef.IsDynamicBlock)
  23.             {
  24.                 mLengthProperty = AutoCADFunctions.GetProperty(blockRef, "DUCT_1") ?? AutoCADFunctions.GetProperty(blockRef, "LENGTH");
  25.             }
  26.             mAngleOffset = blockRef.Rotation;
  27.             _database = database;
  28.         }
  29.  
  30.         protected static Editor CurEditor
  31.         {
  32.             get
  33.             {
  34.                 return Application.DocumentManager.MdiActiveDocument.Editor;
  35.             }
  36.         }
  37.  
  38.         protected static Matrix3d UCS
  39.         {
  40.             get
  41.             {
  42.                 return CurEditor.CurrentUserCoordinateSystem;
  43.             }
  44.         }
  45.  
  46.         protected new BlockReference Entity
  47.         {
  48.             get
  49.             {
  50.                 return (BlockReference)base.Entity;
  51.             }
  52.         }
  53.  
  54.  
  55.         protected override SamplerStatus Sampler(JigPrompts prompts)
  56.         {
  57.             JigPromptPointOptions options;
  58.             options = new JigPromptPointOptions("\nBlock insertion point [<Tab> to Flip alignment]:");
  59.  
  60.  
  61.             options.UserInputControls = UserInputControls.Accept3dCoordinates
  62.                                 | UserInputControls.UseBasePointElevation
  63.                                 | UserInputControls.GovernedByOrthoMode
  64.                                 | UserInputControls.NoDwgLimitsChecking
  65.                                 | UserInputControls.NoNegativeResponseAccepted
  66.                                 | UserInputControls.NoZeroResponseAccepted;
  67.  
  68.             PromptPointResult result = prompts.AcquirePoint(options);
  69.  
  70.             if (mPosition.IsEqualTo(result.Value))
  71.             {
  72.                 return SamplerStatus.NoChange;
  73.             }
  74.             else
  75.             {
  76.                 if (result.Status == PromptStatus.Cancel)
  77.                 {
  78.                     return SamplerStatus.Cancel;
  79.                 }
  80.             }            
  81.             mPosition = result.Value.TransformBy(UCS.Inverse());
  82.             mObjectIdToAlignWith = pickObjId;
  83.  
  84.  
  85.             return SamplerStatus.OK;
  86.         }
  87.  
  88.  
  89.  
  90.         protected override bool Update()
  91.         {
  92.             Entity.Position = mPosition;
  93.            
  94.  
  95.             if (!mObjectIdToAlignWith.IsNull)
  96.             {
  97.                 bool currentTabState = Keyboard.IsKeyDown(Key.Tab);
  98.                 DateTime currentTime = DateTime.Now;
  99.  
  100.                 if (currentTabState != mLastTabState && // Check if the Tab key state has changed
  101.                     currentTime - mLastTabToggleTime > mDebounceInterval) // Check if the debounce interval has passed
  102.                 {
  103.                     mFlipAlignment = !mFlipAlignment;
  104.                     mLastTabToggleTime = currentTime;
  105.                 }
  106.  
  107.                 mLastTabState = currentTabState;
  108.  
  109.  
  110.  
  111.                
  112.  
  113.                 using (Transaction tr = _database.TransactionManager.StartTransaction())
  114.                 {
  115.                     using (DBObject obj = tr.GetObject(mObjectIdToAlignWith, OpenMode.ForRead))
  116.                     {
  117.  
  118.                         if (obj is Curve curve)
  119.                         {
  120.                             Matrix3d transform = Matrix3d.Identity;
  121.                             if (!pickBlockRefId.IsNull) // Check if the subentity is part of a block
  122.                             {
  123.                                 using (BlockReference blockRef = tr.GetObject(pickBlockRefId, OpenMode.ForRead) as BlockReference)
  124.                                 {
  125.                                     if (blockRef != null)
  126.                                     {
  127.                                         transform = blockRef.BlockTransform;
  128.                                     }
  129.                                 }
  130.                             }
  131.  
  132.                             curve = (Curve)curve.GetTransformedCopy(transform);
  133.                             Point3d closestPoint = curve.GetClosestPointTo(Entity.Position, false);
  134.                             Vector3d dir = curve.GetFirstDerivative(closestPoint).TransformBy(UCS.Inverse());
  135.  
  136.                             mAlignmentAngle = Vector3d.XAxis.GetAngleTo(dir, Vector3d.ZAxis);
  137.  
  138.                             // Apply the flip based on the mFlipAlignment flag
  139.                             if (mFlipAlignment)
  140.                             {
  141.                                 mAlignmentAngle += Math.PI; // Add 180 degrees
  142.                             }
  143.  
  144.                             Entity.Rotation = mAlignmentAngle + mAngleOffset;
  145.                         }
  146.                         else
  147.                         {
  148.                             mObjectIdToAlignWith = ObjectId.Null;
  149.                         }
  150.                     }
  151.  
  152.                     tr.Commit();
  153.                 }                
  154.             }
  155.             else
  156.             {
  157.                     Entity.Rotation = 0.0;                    
  158.  
  159.             }
  160.             AutoCADFunctions.SetDynamicProperties(Entity, 40.0);
  161.             return true;
  162.         }
  163.  
  164.  
  165.  
  166.         public static void Editor_PointMonitor(object sender, PointMonitorEventArgs e)
  167.         {
  168.             Document doc = Application.DocumentManager.MdiActiveDocument;
  169.             Database db = doc.Database;
  170.             Editor ed = doc.Editor;
  171.  
  172.             if (e.Context == null)
  173.             {
  174.                 return;
  175.             }
  176.  
  177.             FullSubentityPath[] fullEntPath = e.Context.GetPickedEntities();
  178.  
  179.             if (fullEntPath.Length > 0)
  180.             {
  181.                 try
  182.                 {
  183.                     using (Transaction tr = db.TransactionManager.StartTransaction())
  184.                     {
  185.                         using (Entity topLevelEntity = tr.GetObject(fullEntPath.First().GetObjectIds().First(), OpenMode.ForRead) as Entity)
  186.                         {
  187.  
  188.                             Point3d cursorPosition = e.Context.ComputedPoint;
  189.  
  190.                             if (topLevelEntity is BlockReference blockRef)
  191.                             {
  192.                                 using (BlockTableRecord blockDef = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord)
  193.                                 {
  194.                                     foreach (ObjectId entId in blockDef)
  195.                                     {
  196.                                         using (Entity subEntity = tr.GetObject(entId, OpenMode.ForRead) as Entity)
  197.                                         {
  198.                                             if (IsCursorOnEntity(subEntity, cursorPosition, blockRef, tr))
  199.                                             {
  200.                                                 pickObjId = subEntity.ObjectId;
  201.                                                 pickBlockRefId = blockRef.ObjectId; // Store the block reference ObjectId
  202.                                                 break;
  203.                                             }
  204.                                         }
  205.                                     }
  206.                                 }
  207.                             }
  208.                             else
  209.                             {
  210.                                 pickObjId = topLevelEntity.ObjectId;
  211.                                 pickBlockRefId = ObjectId.Null; // Reset the block reference ObjectId
  212.                             }
  213.                         }
  214.                         tr.Commit();
  215.                     }
  216.                 }
  217.                 catch (System.Exception ex)
  218.                 {
  219.                     if (!string.Equals(ex.Message, "enullextents", StringComparison.OrdinalIgnoreCase))
  220.                     {
  221.                         ed.WriteMessage("\nError: " + ex.Message);
  222.                         pickObjId = ObjectId.Null;
  223.                         pickBlockRefId = ObjectId.Null;
  224.                     }                    
  225.                 }
  226.             }
  227.             else
  228.             {
  229.                 pickObjId = ObjectId.Null;
  230.                 pickBlockRefId = ObjectId.Null;
  231.             }
  232.         }
  233.  
  234.         private static bool IsCursorOnEntity(Entity entity, Point3d cursorPosition, BlockReference blockRef, Transaction tr)
  235.         {
  236.             // Adjust tolerance as needed
  237.             double tolerance = 0.01;
  238.  
  239.             // Transform the cursor position from WCS to the block reference's ECS
  240.             Matrix3d transform = blockRef.BlockTransform.Inverse();
  241.             Point3d transformedCursorPosition = cursorPosition.TransformBy(transform);
  242.  
  243.             // Check if the entity's linetype is ByLayer and the layer is plottable
  244.             if (string.Equals(entity.Linetype, "BYLAYER", StringComparison.OrdinalIgnoreCase))
  245.             {
  246.                 LayerTableRecord layer = tr.GetObject(entity.LayerId, OpenMode.ForRead) as LayerTableRecord;
  247.                 if (layer != null && layer.IsPlottable)
  248.                 {
  249.                     if (entity is Curve curve)
  250.                     {
  251.                         // Get the closest point on the curve to the transformed cursor position
  252.                         Point3d closestPoint = curve.GetClosestPointTo(transformedCursorPosition, false);
  253.                         // Check if the distance between the closest point and the transformed cursor position is within the tolerance
  254.                         return transformedCursorPosition.DistanceTo(closestPoint) <= tolerance;
  255.                     }
  256.                     else
  257.                     {
  258.                         // For non-curve entities, check if the transformed cursor position is within the entity's geometric extents
  259.                         Extents3d extents = entity.GeometricExtents;
  260.                         return transformedCursorPosition.X >= extents.MinPoint.X - tolerance &&
  261.                                transformedCursorPosition.X <= extents.MaxPoint.X + tolerance &&
  262.                                transformedCursorPosition.Y >= extents.MinPoint.Y - tolerance &&
  263.                                transformedCursorPosition.Y <= extents.MaxPoint.Y + tolerance &&
  264.                                transformedCursorPosition.Z >= extents.MinPoint.Z - tolerance &&
  265.                                transformedCursorPosition.Z <= extents.MaxPoint.Z + tolerance;
  266.                     }
  267.                 }
  268.             }
  269.             return false;
  270.         }
  271.  
  272.  
  273.     }


The errors I am getting are as follows:
Quote
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll
The thread 0xb3c has exited with code 0 (0x0).
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
The thread 0x5f4c has exited with code 0 (0x0).
The thread 0x3550 has exited with code 0 (0x0).
The thread 0x52b0 has exited with code 0 (0x0).

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Debugging Help
« Reply #1 on: March 01, 2024, 01:36:41 AM »
Hi,
Quote
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
This means that somewhere in the code, you create lines (calling new Line() or exploding some entity) that you neither add to the database and transaction nor explicitly dispose. But it does not seem to be in the code you show.
Speaking English as a French Frog

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8690
  • AKA Daniel
Re: Debugging Help
« Reply #2 on: March 01, 2024, 03:21:56 AM »
I think GetTransformedCopy is a new object, I'd try wrapping it in a using statement

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Debugging Help
« Reply #3 on: March 01, 2024, 01:43:21 PM »
Hi,
Quote
Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Line): DisposableWrapper
This means that somewhere in the code, you create lines (calling new Line() or exploding some entity) that you neither add to the database and transaction nor explicitly dispose. But it does not seem to be in the code you show.

But I am not doing anything with lines or exploding anything anywhere in my code.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Debugging Help
« Reply #4 on: March 01, 2024, 01:46:36 PM »
I think GetTransformedCopy is a new object, I'd try wrapping it in a using statement

I found where that is and I have modified it, so that got rid of the disposed error, but I am still getting the error
 Exception thrown: 'Autodesk.AutoCAD.Runtime.Exception' in acdbmgd.dll

with the code below:

Code - C#: [Select]
  1.     internal class BlockJig : EntityJig
  2.     {
  3.         private Database _database; // Add a field to store the database
  4.         private Point3d mPosition = Point3d.Origin;        
  5.         private ObjectId mObjectIdToAlignWith = ObjectId.Null;
  6.         private DynamicBlockReferenceProperty mLengthProperty = null;
  7.         private static ObjectId pickObjId = ObjectId.Null;
  8.         private static ObjectId pickBlockRefId = ObjectId.Null;
  9.         private double mAngleOffset = 0.0;
  10.         private bool mFlipAlignment = false; // Field to store the flip state
  11.         private double mAlignmentAngle = 0.0;
  12.         private bool mLastTabState = false;
  13.         private DateTime mLastTabToggleTime = DateTime.MinValue;
  14.         private TimeSpan mDebounceInterval = TimeSpan.FromMilliseconds(200);
  15.            
  16.        
  17.  
  18.  
  19.         public BlockJig(BlockReference blockRef, Database database) : base(blockRef)
  20.         {
  21.             // Check if the block has an alignment parameter
  22.             if (blockRef.IsDynamicBlock)
  23.             {
  24.                 mLengthProperty = AutoCADFunctions.GetProperty(blockRef, "DUCT_1") ?? AutoCADFunctions.GetProperty(blockRef, "LENGTH");
  25.             }
  26.             mAngleOffset = blockRef.Rotation;
  27.             _database = database;
  28.         }
  29.  
  30.         protected static Editor CurEditor
  31.         {
  32.             get
  33.             {
  34.                 return Application.DocumentManager.MdiActiveDocument.Editor;
  35.             }
  36.         }
  37.  
  38.         protected static Matrix3d UCS
  39.         {
  40.             get
  41.             {
  42.                 return CurEditor.CurrentUserCoordinateSystem;
  43.             }
  44.         }
  45.  
  46.         protected new BlockReference Entity
  47.         {
  48.             get
  49.             {
  50.                 return (BlockReference)base.Entity;
  51.             }
  52.         }
  53.  
  54.  
  55.         protected override SamplerStatus Sampler(JigPrompts prompts)
  56.         {
  57.             JigPromptPointOptions options;
  58.             options = new JigPromptPointOptions("\nBlock insertion point [<Tab> to Flip alignment]:");
  59.  
  60.  
  61.             options.UserInputControls = UserInputControls.Accept3dCoordinates
  62.                                 | UserInputControls.UseBasePointElevation
  63.                                 | UserInputControls.GovernedByOrthoMode
  64.                                 | UserInputControls.NoDwgLimitsChecking
  65.                                 | UserInputControls.NoNegativeResponseAccepted
  66.                                 | UserInputControls.NoZeroResponseAccepted;
  67.  
  68.             PromptPointResult result = prompts.AcquirePoint(options);
  69.  
  70.             if (mPosition.IsEqualTo(result.Value))
  71.             {
  72.                 return SamplerStatus.NoChange;
  73.             }
  74.             else
  75.             {
  76.                 if (result.Status == PromptStatus.Cancel)
  77.                 {
  78.                     return SamplerStatus.Cancel;
  79.                 }
  80.             }            
  81.             mPosition = result.Value.TransformBy(UCS.Inverse());
  82.             mObjectIdToAlignWith = pickObjId;
  83.  
  84.  
  85.             return SamplerStatus.OK;
  86.         }
  87.  
  88.  
  89.  
  90.         protected override bool Update()
  91.         {
  92.             Entity.Position = mPosition;
  93.            
  94.  
  95.             if (!mObjectIdToAlignWith.IsNull)
  96.             {
  97.                 bool currentTabState = Keyboard.IsKeyDown(Key.Tab);
  98.                 DateTime currentTime = DateTime.Now;
  99.  
  100.                 if (currentTabState != mLastTabState && // Check if the Tab key state has changed
  101.                     currentTime - mLastTabToggleTime > mDebounceInterval) // Check if the debounce interval has passed
  102.                 {
  103.                     mFlipAlignment = !mFlipAlignment;
  104.                     mLastTabToggleTime = currentTime;
  105.                 }
  106.  
  107.                 mLastTabState = currentTabState;
  108.  
  109.  
  110.  
  111.                
  112.  
  113.                 using (Transaction tr = _database.TransactionManager.StartTransaction())
  114.                 {
  115.                     using (DBObject obj = tr.GetObject(mObjectIdToAlignWith, OpenMode.ForRead))
  116.                     {
  117.  
  118.                         if (obj is Curve curve)
  119.                         {
  120.                             Matrix3d transform = Matrix3d.Identity;
  121.                             if (!pickBlockRefId.IsNull) // Check if the subentity is part of a block
  122.                             {
  123.                                 using (BlockReference blockRef = tr.GetObject(pickBlockRefId, OpenMode.ForRead) as BlockReference)
  124.                                 {
  125.                                     if (blockRef != null)
  126.                                     {
  127.                                         transform = blockRef.BlockTransform;
  128.                                     }
  129.                                 }
  130.                             }
  131.  
  132.                             using (curve = (Curve)curve.GetTransformedCopy(transform))
  133.                             {
  134.                                 Point3d closestPoint = curve.GetClosestPointTo(Entity.Position, false);
  135.                                 Vector3d dir = curve.GetFirstDerivative(closestPoint).TransformBy(UCS.Inverse());
  136.                                 mAlignmentAngle = Vector3d.XAxis.GetAngleTo(dir, Vector3d.ZAxis);
  137.                             }
  138.  
  139.                             // Apply the flip based on the mFlipAlignment flag
  140.                             if (mFlipAlignment)
  141.                             {
  142.                                 mAlignmentAngle += Math.PI; // Add 180 degrees
  143.                             }
  144.  
  145.                             Entity.Rotation = mAlignmentAngle + mAngleOffset;
  146.                         }
  147.                         else
  148.                         {
  149.                             mObjectIdToAlignWith = ObjectId.Null;
  150.                         }
  151.                     }
  152.  
  153.                     tr.Commit();
  154.                 }                
  155.             }
  156.             else
  157.             {
  158.                     Entity.Rotation = 0.0;                    
  159.  
  160.             }
  161.             AutoCADFunctions.SetDynamicProperties(Entity, 40.0);
  162.             return true;
  163.         }
  164.  
  165.  
  166.  
  167.         public static void Editor_PointMonitor(object sender, PointMonitorEventArgs e)
  168.         {
  169.             Document doc = Application.DocumentManager.MdiActiveDocument;
  170.             Database db = doc.Database;
  171.             Editor ed = doc.Editor;
  172.  
  173.             if (e.Context == null)
  174.             {
  175.                 return;
  176.             }
  177.  
  178.             FullSubentityPath[] fullEntPath = e.Context.GetPickedEntities();
  179.  
  180.             if (fullEntPath.Length > 0)
  181.             {
  182.                 try
  183.                 {
  184.                     using (Transaction tr = db.TransactionManager.StartTransaction())
  185.                     {
  186.                         using (Entity topLevelEntity = tr.GetObject(fullEntPath.First().GetObjectIds().First(), OpenMode.ForRead) as Entity)
  187.                         {
  188.  
  189.                             Point3d cursorPosition = e.Context.ComputedPoint;
  190.  
  191.                             if (topLevelEntity is BlockReference)
  192.                             {
  193.                                 using (BlockReference blockRef = (BlockReference)topLevelEntity)
  194.                                 {
  195.                                     using (BlockTableRecord blockDef = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord)
  196.                                     {
  197.                                         foreach (ObjectId entId in blockDef)
  198.                                         {
  199.                                             using (Entity subEntity = tr.GetObject(entId, OpenMode.ForRead) as Entity)
  200.                                             {
  201.                                                 if (IsCursorOnEntity(subEntity, cursorPosition, blockRef, tr))
  202.                                                 {
  203.                                                     pickObjId = subEntity.ObjectId;
  204.                                                     pickBlockRefId = blockRef.ObjectId; // Store the block reference ObjectId
  205.                                                     break;
  206.                                                 }
  207.                                             }
  208.                                         }
  209.                                     }
  210.                                 }
  211.                             }
  212.                             else
  213.                             {
  214.                                 pickObjId = topLevelEntity.ObjectId;
  215.                                 pickBlockRefId = ObjectId.Null; // Reset the block reference ObjectId
  216.                             }
  217.                         }
  218.                         tr.Commit();
  219.                     }
  220.                 }
  221.                 catch (System.Exception ex)
  222.                 {
  223.                     if (!string.Equals(ex.Message, "enullextents", StringComparison.OrdinalIgnoreCase))
  224.                     {
  225.                         ed.WriteMessage("\nError: " + ex.Message);
  226.                         pickObjId = ObjectId.Null;
  227.                         pickBlockRefId = ObjectId.Null;
  228.                     }                    
  229.                 }
  230.             }
  231.             else
  232.             {
  233.                 pickObjId = ObjectId.Null;
  234.                 pickBlockRefId = ObjectId.Null;
  235.             }
  236.         }
  237.  
  238.         private static bool IsCursorOnEntity(Entity entity, Point3d cursorPosition, BlockReference blockRef, Transaction tr)
  239.         {
  240.             // Adjust tolerance as needed
  241.             double tolerance = 0.01;
  242.  
  243.             // Transform the cursor position from WCS to the block reference's ECS
  244.             Matrix3d transform = blockRef.BlockTransform.Inverse();
  245.             Point3d transformedCursorPosition = cursorPosition.TransformBy(transform);
  246.  
  247.             // Check if the entity's linetype is ByLayer and the layer is plottable
  248.             if (string.Equals(entity.Linetype, "BYLAYER", StringComparison.OrdinalIgnoreCase))
  249.             {
  250.                 LayerTableRecord layer = tr.GetObject(entity.LayerId, OpenMode.ForRead) as LayerTableRecord;
  251.                 if (layer != null && layer.IsPlottable)
  252.                 {
  253.                     if (entity is Curve curve)
  254.                     {                        
  255.                             // Get the closest point on the curve to the transformed cursor position
  256.                             Point3d closestPoint = curve.GetClosestPointTo(transformedCursorPosition, false);
  257.                             // Check if the distance between the closest point and the transformed cursor position is within the tolerance
  258.                             return transformedCursorPosition.DistanceTo(closestPoint) <= tolerance;                        
  259.                     }
  260.                        
  261.                     else
  262.                     {
  263.                         // For non-curve entities, check if the transformed cursor position is within the entity's geometric extents
  264.                         Extents3d extents = entity.GeometricExtents;
  265.                         return transformedCursorPosition.X >= extents.MinPoint.X - tolerance &&
  266.                                transformedCursorPosition.X <= extents.MaxPoint.X + tolerance &&
  267.                                transformedCursorPosition.Y >= extents.MinPoint.Y - tolerance &&
  268.                                transformedCursorPosition.Y <= extents.MaxPoint.Y + tolerance &&
  269.                                transformedCursorPosition.Z >= extents.MinPoint.Z - tolerance &&
  270.                                transformedCursorPosition.Z <= extents.MaxPoint.Z + tolerance;
  271.                     }
  272.                 }
  273.             }
  274.             return false;
  275.         }
  276.  
  277.  
  278.     }
I have also attached the complete code in case there is an issue somewhere in there since it is too long to post here.
« Last Edit: March 01, 2024, 02:13:52 PM by cmwade77 »