AutoCAD关联框架GetEdgeVertexSubentities()严重错误

时间:2018-11-22 22:38:18

标签: c# autocad autocad-plugin

AutoCAD 2015-我目前正在学习用于创建几何约束的.NET API(注意:一般来说,我对AutoCAD API并不陌生)。我正在使用从其中一本AutoDesk课程中获得的代码示例进行学习,并且似乎无法弄清为什么在尝试使用{{1检索实体的顶点时,出现“致命错误”并崩溃的问题。 }}。没有引发异常,Autocad只会弹出消息并崩溃。 Try / Catch不执行任何操作,因此无法检查异常消息或调用堆栈。如果有人以前见过这个,或者有我可以看或尝试的想法,将不胜感激。

在有或没有附加调试器的情况下都会发生这种情况。换句话说,从快捷方式启动的发布版本也会发生相同的错误。

我尝试使用不同的绘图,不同的计算机,甚至使用不同的OS(即Win7,Win10),但最终结果都相同。下面的错误消息并崩溃。

Visual Studio输出窗口消息:

  

抛出异常:AcdbMgd.dll中的'System.AccessViolationException'

并弹出错误消息:

enter image description here

这是完整的测试命令。令人讨厌的代码行已清楚标记,大约在代码段的一半下方。

GetEdgeVertexSubentities(..)

要运行该命令,您还将需要此帮助程序方法。以下代码没有已知问题,只需复制并粘贴即可。

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();
  }
}

1 个答案:

答案 0 :(得分:0)

(我想将此添加为评论,但我还没有评论的资格) 我认为这与您的Visual Studio设置有关。我的建议是再次检查“属性”->“调试”。我的一个插件有类似的问题,在我添加了工作目录并在调试设置中修复了命令行参数之后,它按预期的方式开始工作。