AutoCAD Associative Framework GetEdgeVertexSubentities() FATAL ERROR
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:
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
add a comment |
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:
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
add a comment |
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:
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
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:
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
c# autocad autocad-plugin
edited Nov 23 at 0:47
asked Nov 22 at 22:38
Nik
1,3231619
1,3231619
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
(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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
(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.
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
add a comment |
(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.
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
add a comment |
(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.
(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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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