AutoCAD Associative Framework GetEdgeVertexSubentities() FATAL ERROR












0














AutoCAD 2015 - I am currently learning the .NET API for creating geometric constraints (note: I am no stranger to AutoCAD API in general). I am working with a code sample I got from one of the AutoDesk courses to learn from, and I can't seem to figure out why I am getting a "FATAL ERROR" and crash when trying to retrieve an entity's vertices with GetEdgeVertexSubentities(..). There is no Exception thrown, Autocad just pops up the message and crashes. Try/Catch doesn't do anything, so can't inspect the exception message or the call stack. If anyone has seen this before or has some ideas as what I can look at or try, it would be much appreciated.



This happens with and without the debugger attached. In other words, same error occurs with a release build, launched from a shortcut.



I've tried using a different drawing, different computer, and even different OS (ie Win7, Win10), all having the same end result. Error message below and crash.



Visual Studio Output Window message:




Exception thrown: 'System.AccessViolationException' in AcdbMgd.dll




And the error message pop-up:



enter image description here



Here's the full test command. The offending line of code is clearly marked, about half way down the code snippet.



using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

[CommandMethod("TESTFIXED")]
public static void testFixedCommand()
{
Database db = Application.DocumentManager.MdiActiveDocument.Database;
Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
using (Transaction transaction = tm.StartTransaction())
{
// Create DB resident line
BlockTable blockTable = (BlockTable)transaction.GetObject(db.BlockTableId, OpenMode.ForRead, false);
BlockTableRecord modelSpace = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);
Entity entity = new Line(new Point3d(12, 5, 0), new Point3d(15, 12, 0));
modelSpace.AppendEntity(entity);
transaction.AddNewlyCreatedDBObject(entity, true);

AssocPersSubentityIdPE subentityIdPE;
RXClass protocolClass = AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE));
IntPtr pSubentityIdPE = entity.QueryX(protocolClass);
if (pSubentityIdPE == IntPtr.Zero)
{
return;
}
subentityIdPE = AssocPersSubentityIdPE.Create(pSubentityIdPE, false) as AssocPersSubentityIdPE;
if (subentityIdPE == null)
{
return;
}
// Now we have the PE, we query the subentities
// First we retrieve a list of all edges (a line has one edge)
SubentityId edgeSubentityIds = null;
edgeSubentityIds = subentityIdPE.GetAllSubentities(entity, SubentityType.Edge);
SubentityId test = edgeSubentityIds[0];
SubentityId startSID = SubentityId.Null;
// Now we retrieve the vertices associated with the first edge in our array.
// In this case we have one edge, and the edge has three vertices - start, end and middle.
SubentityId endSID = SubentityId.Null;
SubentityId other = null;

//****** This next line is the offender ********
subentityIdPE.GetEdgeVertexSubentities(entity, test, ref startSID, ref endSID, ref other);
//************************************************

// The PE returns a SubEntId. We want a FullSubentityPath
FullSubentityPath subentPathEdge = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, edgeSubentityIds[0]); // The line edge
FullSubentityPath subentPath1 = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, startSID); // The edge's startpoint.

// We call a helper function to retrieve or create a constraints group
ObjectId constraintGroupID = getConstraintGroup(true);
using (Assoc2dConstraintGroup constraintGroup = (Assoc2dConstraintGroup)transaction.GetObject(constraintGroupID, OpenMode.ForWrite, false))
{
// Pass in geometry to constrain (the line edge)
ConstrainedGeometry constraintedGeometry = constraintGroup.AddConstrainedGeometry(subentPathEdge);
// Now create the constraint, a Fixed constraint applied to the line's startpoint.
FullSubentityPath paths = new FullSubentityPath[1] { subentPath1 };
GeometricalConstraint newConstraint = constraintGroup.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, paths);
}

// Evaluate the network to update the parameters of the constrained geometry
String temp = "";
ObjectId networkId = AssocNetwork.GetInstanceFromDatabase(db, true, temp);
using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
{
AssocEvaluationCallback callBack = null;
network.Evaluate(callBack);
}
transaction.Commit();
}
}


To run that command, you will also need this helper method. There are no known issues with the code below, just copy and paste.



// Helper function to retrieve (or create) constraint group
internal static ObjectId getConstraintGroup(bool createIfDoesNotExist)
{
// Calculate the current plane on which new entities are added by the editor
// (A combination of UCS and ELEVATION sysvar).
Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
Matrix3d ucsMatrix = editor.CurrentUserCoordinateSystem;
Point3d origin = ucsMatrix.CoordinateSystem3d.Origin;
Vector3d xAxis = ucsMatrix.CoordinateSystem3d.Xaxis;
Vector3d yAxis = ucsMatrix.CoordinateSystem3d.Yaxis;
Vector3d zAxis = ucsMatrix.CoordinateSystem3d.Zaxis;
origin = origin + Convert.ToDouble(Application.GetSystemVariable("ELEVATION")) * zAxis;
Plane currentPlane = new Plane(origin, xAxis, yAxis);

// get the constraint group from block table record
ObjectId ret = ObjectId.Null;
Database database = HostApplicationServices.WorkingDatabase;
ObjectId networkId = AssocNetwork.GetInstanceFromObject(SymbolUtilityServices.GetBlockModelSpaceId(database), createIfDoesNotExist, true, "");
if (!networkId.IsNull)
{
// Try to find the constraint group in the associative network
using (Transaction transaction = database.TransactionManager.StartTransaction())
{
using (AssocNetwork network = transaction.GetObject(networkId, OpenMode.ForRead, false) as AssocNetwork)
{
if (network != null)
{
// Iterate all actions in network to find Assoc2dConstraintGroups
ObjectIdCollection actionsInNetwork = network.GetActions;
for (int nCount = 0; nCount <= actionsInNetwork.Count - 1; nCount++)
{
ObjectId idAction = actionsInNetwork[nCount];
if (idAction == ObjectId.Null)
{
continue;
}

// Is this action a type of Assoc2dConstraintGroup?
if (idAction.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Assoc2dConstraintGroup))))
{
using (AssocAction action = (AssocAction)transaction.GetObject(idAction, OpenMode.ForRead, false))
{
if (action == null)
{
continue;
}

Assoc2dConstraintGroup constGrp = action as Assoc2dConstraintGroup;
// Is this the Assoc2dConstraintGroup for our plane of interest?
if (constGrp.WorkPlane.IsCoplanarTo(currentPlane))
{
// If it is then we've found an existing constraint group we can use.
ret = idAction;
break;
}
}
}
}
}
}

// If we get to here, a suitable contraint group doesn't exist, create a new one if that's what calling fn wanted.
if (ret.IsNull && createIfDoesNotExist)
{
using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
{
// Create construction plane
Plane constraintPlane = new Plane(currentPlane);
// If model extent is far far away from origin then we need to shift
// construction plane origin within the model extent.
// (Use Pextmin, PExtmax in paper space)
Point3d extmin = database.Extmin;
Point3d extmax = database.Extmax;
if (extmin.GetAsVector().Length > 100000000.0)
{
Point3d originL = extmin + (extmax - extmin) / 2.0;
PointOnSurface result = currentPlane.GetClosestPointTo(originL);
constraintPlane.Set(result.GetPoint(), currentPlane.Normal);
}
// Create the new constraint group and add it to the associative network.
using (Assoc2dConstraintGroup constGrp = new Assoc2dConstraintGroup(constraintPlane))
{
ret = database.AddDBObject(constGrp);
}
network.AddAction(ret, true);
}
}
transaction.Commit();
}
}
return ret;
}









share|improve this question





























    0














    AutoCAD 2015 - I am currently learning the .NET API for creating geometric constraints (note: I am no stranger to AutoCAD API in general). I am working with a code sample I got from one of the AutoDesk courses to learn from, and I can't seem to figure out why I am getting a "FATAL ERROR" and crash when trying to retrieve an entity's vertices with GetEdgeVertexSubentities(..). There is no Exception thrown, Autocad just pops up the message and crashes. Try/Catch doesn't do anything, so can't inspect the exception message or the call stack. If anyone has seen this before or has some ideas as what I can look at or try, it would be much appreciated.



    This happens with and without the debugger attached. In other words, same error occurs with a release build, launched from a shortcut.



    I've tried using a different drawing, different computer, and even different OS (ie Win7, Win10), all having the same end result. Error message below and crash.



    Visual Studio Output Window message:




    Exception thrown: 'System.AccessViolationException' in AcdbMgd.dll




    And the error message pop-up:



    enter image description here



    Here's the full test command. The offending line of code is clearly marked, about half way down the code snippet.



    using System;
    using System.Collections.Generic;
    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Geometry;
    using Autodesk.AutoCAD.EditorInput;

    [CommandMethod("TESTFIXED")]
    public static void testFixedCommand()
    {
    Database db = Application.DocumentManager.MdiActiveDocument.Database;
    Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
    using (Transaction transaction = tm.StartTransaction())
    {
    // Create DB resident line
    BlockTable blockTable = (BlockTable)transaction.GetObject(db.BlockTableId, OpenMode.ForRead, false);
    BlockTableRecord modelSpace = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);
    Entity entity = new Line(new Point3d(12, 5, 0), new Point3d(15, 12, 0));
    modelSpace.AppendEntity(entity);
    transaction.AddNewlyCreatedDBObject(entity, true);

    AssocPersSubentityIdPE subentityIdPE;
    RXClass protocolClass = AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE));
    IntPtr pSubentityIdPE = entity.QueryX(protocolClass);
    if (pSubentityIdPE == IntPtr.Zero)
    {
    return;
    }
    subentityIdPE = AssocPersSubentityIdPE.Create(pSubentityIdPE, false) as AssocPersSubentityIdPE;
    if (subentityIdPE == null)
    {
    return;
    }
    // Now we have the PE, we query the subentities
    // First we retrieve a list of all edges (a line has one edge)
    SubentityId edgeSubentityIds = null;
    edgeSubentityIds = subentityIdPE.GetAllSubentities(entity, SubentityType.Edge);
    SubentityId test = edgeSubentityIds[0];
    SubentityId startSID = SubentityId.Null;
    // Now we retrieve the vertices associated with the first edge in our array.
    // In this case we have one edge, and the edge has three vertices - start, end and middle.
    SubentityId endSID = SubentityId.Null;
    SubentityId other = null;

    //****** This next line is the offender ********
    subentityIdPE.GetEdgeVertexSubentities(entity, test, ref startSID, ref endSID, ref other);
    //************************************************

    // The PE returns a SubEntId. We want a FullSubentityPath
    FullSubentityPath subentPathEdge = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, edgeSubentityIds[0]); // The line edge
    FullSubentityPath subentPath1 = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, startSID); // The edge's startpoint.

    // We call a helper function to retrieve or create a constraints group
    ObjectId constraintGroupID = getConstraintGroup(true);
    using (Assoc2dConstraintGroup constraintGroup = (Assoc2dConstraintGroup)transaction.GetObject(constraintGroupID, OpenMode.ForWrite, false))
    {
    // Pass in geometry to constrain (the line edge)
    ConstrainedGeometry constraintedGeometry = constraintGroup.AddConstrainedGeometry(subentPathEdge);
    // Now create the constraint, a Fixed constraint applied to the line's startpoint.
    FullSubentityPath paths = new FullSubentityPath[1] { subentPath1 };
    GeometricalConstraint newConstraint = constraintGroup.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, paths);
    }

    // Evaluate the network to update the parameters of the constrained geometry
    String temp = "";
    ObjectId networkId = AssocNetwork.GetInstanceFromDatabase(db, true, temp);
    using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
    {
    AssocEvaluationCallback callBack = null;
    network.Evaluate(callBack);
    }
    transaction.Commit();
    }
    }


    To run that command, you will also need this helper method. There are no known issues with the code below, just copy and paste.



    // Helper function to retrieve (or create) constraint group
    internal static ObjectId getConstraintGroup(bool createIfDoesNotExist)
    {
    // Calculate the current plane on which new entities are added by the editor
    // (A combination of UCS and ELEVATION sysvar).
    Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
    Matrix3d ucsMatrix = editor.CurrentUserCoordinateSystem;
    Point3d origin = ucsMatrix.CoordinateSystem3d.Origin;
    Vector3d xAxis = ucsMatrix.CoordinateSystem3d.Xaxis;
    Vector3d yAxis = ucsMatrix.CoordinateSystem3d.Yaxis;
    Vector3d zAxis = ucsMatrix.CoordinateSystem3d.Zaxis;
    origin = origin + Convert.ToDouble(Application.GetSystemVariable("ELEVATION")) * zAxis;
    Plane currentPlane = new Plane(origin, xAxis, yAxis);

    // get the constraint group from block table record
    ObjectId ret = ObjectId.Null;
    Database database = HostApplicationServices.WorkingDatabase;
    ObjectId networkId = AssocNetwork.GetInstanceFromObject(SymbolUtilityServices.GetBlockModelSpaceId(database), createIfDoesNotExist, true, "");
    if (!networkId.IsNull)
    {
    // Try to find the constraint group in the associative network
    using (Transaction transaction = database.TransactionManager.StartTransaction())
    {
    using (AssocNetwork network = transaction.GetObject(networkId, OpenMode.ForRead, false) as AssocNetwork)
    {
    if (network != null)
    {
    // Iterate all actions in network to find Assoc2dConstraintGroups
    ObjectIdCollection actionsInNetwork = network.GetActions;
    for (int nCount = 0; nCount <= actionsInNetwork.Count - 1; nCount++)
    {
    ObjectId idAction = actionsInNetwork[nCount];
    if (idAction == ObjectId.Null)
    {
    continue;
    }

    // Is this action a type of Assoc2dConstraintGroup?
    if (idAction.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Assoc2dConstraintGroup))))
    {
    using (AssocAction action = (AssocAction)transaction.GetObject(idAction, OpenMode.ForRead, false))
    {
    if (action == null)
    {
    continue;
    }

    Assoc2dConstraintGroup constGrp = action as Assoc2dConstraintGroup;
    // Is this the Assoc2dConstraintGroup for our plane of interest?
    if (constGrp.WorkPlane.IsCoplanarTo(currentPlane))
    {
    // If it is then we've found an existing constraint group we can use.
    ret = idAction;
    break;
    }
    }
    }
    }
    }
    }

    // If we get to here, a suitable contraint group doesn't exist, create a new one if that's what calling fn wanted.
    if (ret.IsNull && createIfDoesNotExist)
    {
    using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
    {
    // Create construction plane
    Plane constraintPlane = new Plane(currentPlane);
    // If model extent is far far away from origin then we need to shift
    // construction plane origin within the model extent.
    // (Use Pextmin, PExtmax in paper space)
    Point3d extmin = database.Extmin;
    Point3d extmax = database.Extmax;
    if (extmin.GetAsVector().Length > 100000000.0)
    {
    Point3d originL = extmin + (extmax - extmin) / 2.0;
    PointOnSurface result = currentPlane.GetClosestPointTo(originL);
    constraintPlane.Set(result.GetPoint(), currentPlane.Normal);
    }
    // Create the new constraint group and add it to the associative network.
    using (Assoc2dConstraintGroup constGrp = new Assoc2dConstraintGroup(constraintPlane))
    {
    ret = database.AddDBObject(constGrp);
    }
    network.AddAction(ret, true);
    }
    }
    transaction.Commit();
    }
    }
    return ret;
    }









    share|improve this question



























      0












      0








      0







      AutoCAD 2015 - I am currently learning the .NET API for creating geometric constraints (note: I am no stranger to AutoCAD API in general). I am working with a code sample I got from one of the AutoDesk courses to learn from, and I can't seem to figure out why I am getting a "FATAL ERROR" and crash when trying to retrieve an entity's vertices with GetEdgeVertexSubentities(..). There is no Exception thrown, Autocad just pops up the message and crashes. Try/Catch doesn't do anything, so can't inspect the exception message or the call stack. If anyone has seen this before or has some ideas as what I can look at or try, it would be much appreciated.



      This happens with and without the debugger attached. In other words, same error occurs with a release build, launched from a shortcut.



      I've tried using a different drawing, different computer, and even different OS (ie Win7, Win10), all having the same end result. Error message below and crash.



      Visual Studio Output Window message:




      Exception thrown: 'System.AccessViolationException' in AcdbMgd.dll




      And the error message pop-up:



      enter image description here



      Here's the full test command. The offending line of code is clearly marked, about half way down the code snippet.



      using System;
      using System.Collections.Generic;
      using Autodesk.AutoCAD.Runtime;
      using Autodesk.AutoCAD.ApplicationServices;
      using Autodesk.AutoCAD.DatabaseServices;
      using Autodesk.AutoCAD.Geometry;
      using Autodesk.AutoCAD.EditorInput;

      [CommandMethod("TESTFIXED")]
      public static void testFixedCommand()
      {
      Database db = Application.DocumentManager.MdiActiveDocument.Database;
      Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
      using (Transaction transaction = tm.StartTransaction())
      {
      // Create DB resident line
      BlockTable blockTable = (BlockTable)transaction.GetObject(db.BlockTableId, OpenMode.ForRead, false);
      BlockTableRecord modelSpace = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);
      Entity entity = new Line(new Point3d(12, 5, 0), new Point3d(15, 12, 0));
      modelSpace.AppendEntity(entity);
      transaction.AddNewlyCreatedDBObject(entity, true);

      AssocPersSubentityIdPE subentityIdPE;
      RXClass protocolClass = AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE));
      IntPtr pSubentityIdPE = entity.QueryX(protocolClass);
      if (pSubentityIdPE == IntPtr.Zero)
      {
      return;
      }
      subentityIdPE = AssocPersSubentityIdPE.Create(pSubentityIdPE, false) as AssocPersSubentityIdPE;
      if (subentityIdPE == null)
      {
      return;
      }
      // Now we have the PE, we query the subentities
      // First we retrieve a list of all edges (a line has one edge)
      SubentityId edgeSubentityIds = null;
      edgeSubentityIds = subentityIdPE.GetAllSubentities(entity, SubentityType.Edge);
      SubentityId test = edgeSubentityIds[0];
      SubentityId startSID = SubentityId.Null;
      // Now we retrieve the vertices associated with the first edge in our array.
      // In this case we have one edge, and the edge has three vertices - start, end and middle.
      SubentityId endSID = SubentityId.Null;
      SubentityId other = null;

      //****** This next line is the offender ********
      subentityIdPE.GetEdgeVertexSubentities(entity, test, ref startSID, ref endSID, ref other);
      //************************************************

      // The PE returns a SubEntId. We want a FullSubentityPath
      FullSubentityPath subentPathEdge = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, edgeSubentityIds[0]); // The line edge
      FullSubentityPath subentPath1 = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, startSID); // The edge's startpoint.

      // We call a helper function to retrieve or create a constraints group
      ObjectId constraintGroupID = getConstraintGroup(true);
      using (Assoc2dConstraintGroup constraintGroup = (Assoc2dConstraintGroup)transaction.GetObject(constraintGroupID, OpenMode.ForWrite, false))
      {
      // Pass in geometry to constrain (the line edge)
      ConstrainedGeometry constraintedGeometry = constraintGroup.AddConstrainedGeometry(subentPathEdge);
      // Now create the constraint, a Fixed constraint applied to the line's startpoint.
      FullSubentityPath paths = new FullSubentityPath[1] { subentPath1 };
      GeometricalConstraint newConstraint = constraintGroup.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, paths);
      }

      // Evaluate the network to update the parameters of the constrained geometry
      String temp = "";
      ObjectId networkId = AssocNetwork.GetInstanceFromDatabase(db, true, temp);
      using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
      {
      AssocEvaluationCallback callBack = null;
      network.Evaluate(callBack);
      }
      transaction.Commit();
      }
      }


      To run that command, you will also need this helper method. There are no known issues with the code below, just copy and paste.



      // Helper function to retrieve (or create) constraint group
      internal static ObjectId getConstraintGroup(bool createIfDoesNotExist)
      {
      // Calculate the current plane on which new entities are added by the editor
      // (A combination of UCS and ELEVATION sysvar).
      Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
      Matrix3d ucsMatrix = editor.CurrentUserCoordinateSystem;
      Point3d origin = ucsMatrix.CoordinateSystem3d.Origin;
      Vector3d xAxis = ucsMatrix.CoordinateSystem3d.Xaxis;
      Vector3d yAxis = ucsMatrix.CoordinateSystem3d.Yaxis;
      Vector3d zAxis = ucsMatrix.CoordinateSystem3d.Zaxis;
      origin = origin + Convert.ToDouble(Application.GetSystemVariable("ELEVATION")) * zAxis;
      Plane currentPlane = new Plane(origin, xAxis, yAxis);

      // get the constraint group from block table record
      ObjectId ret = ObjectId.Null;
      Database database = HostApplicationServices.WorkingDatabase;
      ObjectId networkId = AssocNetwork.GetInstanceFromObject(SymbolUtilityServices.GetBlockModelSpaceId(database), createIfDoesNotExist, true, "");
      if (!networkId.IsNull)
      {
      // Try to find the constraint group in the associative network
      using (Transaction transaction = database.TransactionManager.StartTransaction())
      {
      using (AssocNetwork network = transaction.GetObject(networkId, OpenMode.ForRead, false) as AssocNetwork)
      {
      if (network != null)
      {
      // Iterate all actions in network to find Assoc2dConstraintGroups
      ObjectIdCollection actionsInNetwork = network.GetActions;
      for (int nCount = 0; nCount <= actionsInNetwork.Count - 1; nCount++)
      {
      ObjectId idAction = actionsInNetwork[nCount];
      if (idAction == ObjectId.Null)
      {
      continue;
      }

      // Is this action a type of Assoc2dConstraintGroup?
      if (idAction.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Assoc2dConstraintGroup))))
      {
      using (AssocAction action = (AssocAction)transaction.GetObject(idAction, OpenMode.ForRead, false))
      {
      if (action == null)
      {
      continue;
      }

      Assoc2dConstraintGroup constGrp = action as Assoc2dConstraintGroup;
      // Is this the Assoc2dConstraintGroup for our plane of interest?
      if (constGrp.WorkPlane.IsCoplanarTo(currentPlane))
      {
      // If it is then we've found an existing constraint group we can use.
      ret = idAction;
      break;
      }
      }
      }
      }
      }
      }

      // If we get to here, a suitable contraint group doesn't exist, create a new one if that's what calling fn wanted.
      if (ret.IsNull && createIfDoesNotExist)
      {
      using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
      {
      // Create construction plane
      Plane constraintPlane = new Plane(currentPlane);
      // If model extent is far far away from origin then we need to shift
      // construction plane origin within the model extent.
      // (Use Pextmin, PExtmax in paper space)
      Point3d extmin = database.Extmin;
      Point3d extmax = database.Extmax;
      if (extmin.GetAsVector().Length > 100000000.0)
      {
      Point3d originL = extmin + (extmax - extmin) / 2.0;
      PointOnSurface result = currentPlane.GetClosestPointTo(originL);
      constraintPlane.Set(result.GetPoint(), currentPlane.Normal);
      }
      // Create the new constraint group and add it to the associative network.
      using (Assoc2dConstraintGroup constGrp = new Assoc2dConstraintGroup(constraintPlane))
      {
      ret = database.AddDBObject(constGrp);
      }
      network.AddAction(ret, true);
      }
      }
      transaction.Commit();
      }
      }
      return ret;
      }









      share|improve this question















      AutoCAD 2015 - I am currently learning the .NET API for creating geometric constraints (note: I am no stranger to AutoCAD API in general). I am working with a code sample I got from one of the AutoDesk courses to learn from, and I can't seem to figure out why I am getting a "FATAL ERROR" and crash when trying to retrieve an entity's vertices with GetEdgeVertexSubentities(..). There is no Exception thrown, Autocad just pops up the message and crashes. Try/Catch doesn't do anything, so can't inspect the exception message or the call stack. If anyone has seen this before or has some ideas as what I can look at or try, it would be much appreciated.



      This happens with and without the debugger attached. In other words, same error occurs with a release build, launched from a shortcut.



      I've tried using a different drawing, different computer, and even different OS (ie Win7, Win10), all having the same end result. Error message below and crash.



      Visual Studio Output Window message:




      Exception thrown: 'System.AccessViolationException' in AcdbMgd.dll




      And the error message pop-up:



      enter image description here



      Here's the full test command. The offending line of code is clearly marked, about half way down the code snippet.



      using System;
      using System.Collections.Generic;
      using Autodesk.AutoCAD.Runtime;
      using Autodesk.AutoCAD.ApplicationServices;
      using Autodesk.AutoCAD.DatabaseServices;
      using Autodesk.AutoCAD.Geometry;
      using Autodesk.AutoCAD.EditorInput;

      [CommandMethod("TESTFIXED")]
      public static void testFixedCommand()
      {
      Database db = Application.DocumentManager.MdiActiveDocument.Database;
      Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
      using (Transaction transaction = tm.StartTransaction())
      {
      // Create DB resident line
      BlockTable blockTable = (BlockTable)transaction.GetObject(db.BlockTableId, OpenMode.ForRead, false);
      BlockTableRecord modelSpace = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);
      Entity entity = new Line(new Point3d(12, 5, 0), new Point3d(15, 12, 0));
      modelSpace.AppendEntity(entity);
      transaction.AddNewlyCreatedDBObject(entity, true);

      AssocPersSubentityIdPE subentityIdPE;
      RXClass protocolClass = AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE));
      IntPtr pSubentityIdPE = entity.QueryX(protocolClass);
      if (pSubentityIdPE == IntPtr.Zero)
      {
      return;
      }
      subentityIdPE = AssocPersSubentityIdPE.Create(pSubentityIdPE, false) as AssocPersSubentityIdPE;
      if (subentityIdPE == null)
      {
      return;
      }
      // Now we have the PE, we query the subentities
      // First we retrieve a list of all edges (a line has one edge)
      SubentityId edgeSubentityIds = null;
      edgeSubentityIds = subentityIdPE.GetAllSubentities(entity, SubentityType.Edge);
      SubentityId test = edgeSubentityIds[0];
      SubentityId startSID = SubentityId.Null;
      // Now we retrieve the vertices associated with the first edge in our array.
      // In this case we have one edge, and the edge has three vertices - start, end and middle.
      SubentityId endSID = SubentityId.Null;
      SubentityId other = null;

      //****** This next line is the offender ********
      subentityIdPE.GetEdgeVertexSubentities(entity, test, ref startSID, ref endSID, ref other);
      //************************************************

      // The PE returns a SubEntId. We want a FullSubentityPath
      FullSubentityPath subentPathEdge = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, edgeSubentityIds[0]); // The line edge
      FullSubentityPath subentPath1 = new FullSubentityPath(new ObjectId[1] { entity.ObjectId }, startSID); // The edge's startpoint.

      // We call a helper function to retrieve or create a constraints group
      ObjectId constraintGroupID = getConstraintGroup(true);
      using (Assoc2dConstraintGroup constraintGroup = (Assoc2dConstraintGroup)transaction.GetObject(constraintGroupID, OpenMode.ForWrite, false))
      {
      // Pass in geometry to constrain (the line edge)
      ConstrainedGeometry constraintedGeometry = constraintGroup.AddConstrainedGeometry(subentPathEdge);
      // Now create the constraint, a Fixed constraint applied to the line's startpoint.
      FullSubentityPath paths = new FullSubentityPath[1] { subentPath1 };
      GeometricalConstraint newConstraint = constraintGroup.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, paths);
      }

      // Evaluate the network to update the parameters of the constrained geometry
      String temp = "";
      ObjectId networkId = AssocNetwork.GetInstanceFromDatabase(db, true, temp);
      using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
      {
      AssocEvaluationCallback callBack = null;
      network.Evaluate(callBack);
      }
      transaction.Commit();
      }
      }


      To run that command, you will also need this helper method. There are no known issues with the code below, just copy and paste.



      // Helper function to retrieve (or create) constraint group
      internal static ObjectId getConstraintGroup(bool createIfDoesNotExist)
      {
      // Calculate the current plane on which new entities are added by the editor
      // (A combination of UCS and ELEVATION sysvar).
      Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
      Matrix3d ucsMatrix = editor.CurrentUserCoordinateSystem;
      Point3d origin = ucsMatrix.CoordinateSystem3d.Origin;
      Vector3d xAxis = ucsMatrix.CoordinateSystem3d.Xaxis;
      Vector3d yAxis = ucsMatrix.CoordinateSystem3d.Yaxis;
      Vector3d zAxis = ucsMatrix.CoordinateSystem3d.Zaxis;
      origin = origin + Convert.ToDouble(Application.GetSystemVariable("ELEVATION")) * zAxis;
      Plane currentPlane = new Plane(origin, xAxis, yAxis);

      // get the constraint group from block table record
      ObjectId ret = ObjectId.Null;
      Database database = HostApplicationServices.WorkingDatabase;
      ObjectId networkId = AssocNetwork.GetInstanceFromObject(SymbolUtilityServices.GetBlockModelSpaceId(database), createIfDoesNotExist, true, "");
      if (!networkId.IsNull)
      {
      // Try to find the constraint group in the associative network
      using (Transaction transaction = database.TransactionManager.StartTransaction())
      {
      using (AssocNetwork network = transaction.GetObject(networkId, OpenMode.ForRead, false) as AssocNetwork)
      {
      if (network != null)
      {
      // Iterate all actions in network to find Assoc2dConstraintGroups
      ObjectIdCollection actionsInNetwork = network.GetActions;
      for (int nCount = 0; nCount <= actionsInNetwork.Count - 1; nCount++)
      {
      ObjectId idAction = actionsInNetwork[nCount];
      if (idAction == ObjectId.Null)
      {
      continue;
      }

      // Is this action a type of Assoc2dConstraintGroup?
      if (idAction.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Assoc2dConstraintGroup))))
      {
      using (AssocAction action = (AssocAction)transaction.GetObject(idAction, OpenMode.ForRead, false))
      {
      if (action == null)
      {
      continue;
      }

      Assoc2dConstraintGroup constGrp = action as Assoc2dConstraintGroup;
      // Is this the Assoc2dConstraintGroup for our plane of interest?
      if (constGrp.WorkPlane.IsCoplanarTo(currentPlane))
      {
      // If it is then we've found an existing constraint group we can use.
      ret = idAction;
      break;
      }
      }
      }
      }
      }
      }

      // If we get to here, a suitable contraint group doesn't exist, create a new one if that's what calling fn wanted.
      if (ret.IsNull && createIfDoesNotExist)
      {
      using (AssocNetwork network = (AssocNetwork)transaction.GetObject(networkId, OpenMode.ForWrite, false))
      {
      // Create construction plane
      Plane constraintPlane = new Plane(currentPlane);
      // If model extent is far far away from origin then we need to shift
      // construction plane origin within the model extent.
      // (Use Pextmin, PExtmax in paper space)
      Point3d extmin = database.Extmin;
      Point3d extmax = database.Extmax;
      if (extmin.GetAsVector().Length > 100000000.0)
      {
      Point3d originL = extmin + (extmax - extmin) / 2.0;
      PointOnSurface result = currentPlane.GetClosestPointTo(originL);
      constraintPlane.Set(result.GetPoint(), currentPlane.Normal);
      }
      // Create the new constraint group and add it to the associative network.
      using (Assoc2dConstraintGroup constGrp = new Assoc2dConstraintGroup(constraintPlane))
      {
      ret = database.AddDBObject(constGrp);
      }
      network.AddAction(ret, true);
      }
      }
      transaction.Commit();
      }
      }
      return ret;
      }






      c# autocad autocad-plugin






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 23 at 0:47

























      asked Nov 22 at 22:38









      Nik

      1,3231619




      1,3231619
























          1 Answer
          1






          active

          oldest

          votes


















          0














          (I wanted to add this as comment but I am not eligible for commenting yet)
          I think it has to do with your Visual Studio settings. My suggestion would be to double check Properties -> Debugging. I had similar problem with one of my add-ins and it started working as expected after I added Working Directory and fixed Command Line Argument in Debugging settings.






          share|improve this answer





















          • Thanks for the suggestion. I've been developing this project for years now, and this is the first time I've seen this. Somehow I doubt this is the issue, but at this point I am willing to try anything. Could you be more specific about what you mean by "I added Working Directory and fixed Command Line Argument in Debugging settings".
            – Nik
            Nov 23 at 0:35










          • btw, I've tried running a release build without the debugger attached. Same effect.
            – Nik
            Nov 23 at 0:36










          • So in your Debug Setting should be as follow: 1. Start external program: C:Program FilesAutodeskAutoCAD 2018acad.exe 2. Command Line Arguments: /ld "C:Program FilesAutodeskAutoCAD 2018\AecBase.dbx" /p "<<C3D_Imperial>>" 3. Working Directory: C:Program FilesAutodeskAutoCAD 2018UserDataCache . Once I changed my setting to above the similar error that i had disappeared.
            – Rray_Rhino
            Nov 23 at 0:48












          • Thanks, but that doesn't appear to be it. Still same crash.
            – Nik
            Nov 23 at 1:19











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438729%2fautocad-associative-framework-getedgevertexsubentities-fatal-error%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          (I wanted to add this as comment but I am not eligible for commenting yet)
          I think it has to do with your Visual Studio settings. My suggestion would be to double check Properties -> Debugging. I had similar problem with one of my add-ins and it started working as expected after I added Working Directory and fixed Command Line Argument in Debugging settings.






          share|improve this answer





















          • Thanks for the suggestion. I've been developing this project for years now, and this is the first time I've seen this. Somehow I doubt this is the issue, but at this point I am willing to try anything. Could you be more specific about what you mean by "I added Working Directory and fixed Command Line Argument in Debugging settings".
            – Nik
            Nov 23 at 0:35










          • btw, I've tried running a release build without the debugger attached. Same effect.
            – Nik
            Nov 23 at 0:36










          • So in your Debug Setting should be as follow: 1. Start external program: C:Program FilesAutodeskAutoCAD 2018acad.exe 2. Command Line Arguments: /ld "C:Program FilesAutodeskAutoCAD 2018\AecBase.dbx" /p "<<C3D_Imperial>>" 3. Working Directory: C:Program FilesAutodeskAutoCAD 2018UserDataCache . Once I changed my setting to above the similar error that i had disappeared.
            – Rray_Rhino
            Nov 23 at 0:48












          • Thanks, but that doesn't appear to be it. Still same crash.
            – Nik
            Nov 23 at 1:19
















          0














          (I wanted to add this as comment but I am not eligible for commenting yet)
          I think it has to do with your Visual Studio settings. My suggestion would be to double check Properties -> Debugging. I had similar problem with one of my add-ins and it started working as expected after I added Working Directory and fixed Command Line Argument in Debugging settings.






          share|improve this answer





















          • Thanks for the suggestion. I've been developing this project for years now, and this is the first time I've seen this. Somehow I doubt this is the issue, but at this point I am willing to try anything. Could you be more specific about what you mean by "I added Working Directory and fixed Command Line Argument in Debugging settings".
            – Nik
            Nov 23 at 0:35










          • btw, I've tried running a release build without the debugger attached. Same effect.
            – Nik
            Nov 23 at 0:36










          • So in your Debug Setting should be as follow: 1. Start external program: C:Program FilesAutodeskAutoCAD 2018acad.exe 2. Command Line Arguments: /ld "C:Program FilesAutodeskAutoCAD 2018\AecBase.dbx" /p "<<C3D_Imperial>>" 3. Working Directory: C:Program FilesAutodeskAutoCAD 2018UserDataCache . Once I changed my setting to above the similar error that i had disappeared.
            – Rray_Rhino
            Nov 23 at 0:48












          • Thanks, but that doesn't appear to be it. Still same crash.
            – Nik
            Nov 23 at 1:19














          0












          0








          0






          (I wanted to add this as comment but I am not eligible for commenting yet)
          I think it has to do with your Visual Studio settings. My suggestion would be to double check Properties -> Debugging. I had similar problem with one of my add-ins and it started working as expected after I added Working Directory and fixed Command Line Argument in Debugging settings.






          share|improve this answer












          (I wanted to add this as comment but I am not eligible for commenting yet)
          I think it has to do with your Visual Studio settings. My suggestion would be to double check Properties -> Debugging. I had similar problem with one of my add-ins and it started working as expected after I added Working Directory and fixed Command Line Argument in Debugging settings.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 23 at 0:29









          Rray_Rhino

          112




          112












          • Thanks for the suggestion. I've been developing this project for years now, and this is the first time I've seen this. Somehow I doubt this is the issue, but at this point I am willing to try anything. Could you be more specific about what you mean by "I added Working Directory and fixed Command Line Argument in Debugging settings".
            – Nik
            Nov 23 at 0:35










          • btw, I've tried running a release build without the debugger attached. Same effect.
            – Nik
            Nov 23 at 0:36










          • So in your Debug Setting should be as follow: 1. Start external program: C:Program FilesAutodeskAutoCAD 2018acad.exe 2. Command Line Arguments: /ld "C:Program FilesAutodeskAutoCAD 2018\AecBase.dbx" /p "<<C3D_Imperial>>" 3. Working Directory: C:Program FilesAutodeskAutoCAD 2018UserDataCache . Once I changed my setting to above the similar error that i had disappeared.
            – Rray_Rhino
            Nov 23 at 0:48












          • Thanks, but that doesn't appear to be it. Still same crash.
            – Nik
            Nov 23 at 1:19


















          • Thanks for the suggestion. I've been developing this project for years now, and this is the first time I've seen this. Somehow I doubt this is the issue, but at this point I am willing to try anything. Could you be more specific about what you mean by "I added Working Directory and fixed Command Line Argument in Debugging settings".
            – Nik
            Nov 23 at 0:35










          • btw, I've tried running a release build without the debugger attached. Same effect.
            – Nik
            Nov 23 at 0:36










          • So in your Debug Setting should be as follow: 1. Start external program: C:Program FilesAutodeskAutoCAD 2018acad.exe 2. Command Line Arguments: /ld "C:Program FilesAutodeskAutoCAD 2018\AecBase.dbx" /p "<<C3D_Imperial>>" 3. Working Directory: C:Program FilesAutodeskAutoCAD 2018UserDataCache . Once I changed my setting to above the similar error that i had disappeared.
            – Rray_Rhino
            Nov 23 at 0:48












          • Thanks, but that doesn't appear to be it. Still same crash.
            – Nik
            Nov 23 at 1:19
















          Thanks for the suggestion. I've been developing this project for years now, and this is the first time I've seen this. Somehow I doubt this is the issue, but at this point I am willing to try anything. Could you be more specific about what you mean by "I added Working Directory and fixed Command Line Argument in Debugging settings".
          – Nik
          Nov 23 at 0:35




          Thanks for the suggestion. I've been developing this project for years now, and this is the first time I've seen this. Somehow I doubt this is the issue, but at this point I am willing to try anything. Could you be more specific about what you mean by "I added Working Directory and fixed Command Line Argument in Debugging settings".
          – Nik
          Nov 23 at 0:35












          btw, I've tried running a release build without the debugger attached. Same effect.
          – Nik
          Nov 23 at 0:36




          btw, I've tried running a release build without the debugger attached. Same effect.
          – Nik
          Nov 23 at 0:36












          So in your Debug Setting should be as follow: 1. Start external program: C:Program FilesAutodeskAutoCAD 2018acad.exe 2. Command Line Arguments: /ld "C:Program FilesAutodeskAutoCAD 2018\AecBase.dbx" /p "<<C3D_Imperial>>" 3. Working Directory: C:Program FilesAutodeskAutoCAD 2018UserDataCache . Once I changed my setting to above the similar error that i had disappeared.
          – Rray_Rhino
          Nov 23 at 0:48






          So in your Debug Setting should be as follow: 1. Start external program: C:Program FilesAutodeskAutoCAD 2018acad.exe 2. Command Line Arguments: /ld "C:Program FilesAutodeskAutoCAD 2018\AecBase.dbx" /p "<<C3D_Imperial>>" 3. Working Directory: C:Program FilesAutodeskAutoCAD 2018UserDataCache . Once I changed my setting to above the similar error that i had disappeared.
          – Rray_Rhino
          Nov 23 at 0:48














          Thanks, but that doesn't appear to be it. Still same crash.
          – Nik
          Nov 23 at 1:19




          Thanks, but that doesn't appear to be it. Still same crash.
          – Nik
          Nov 23 at 1:19


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438729%2fautocad-associative-framework-getedgevertexsubentities-fatal-error%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          What visual should I use to simply compare current year value vs last year in Power BI desktop

          How to ignore python UserWarning in pytest?

          Alexandru Averescu