代码之家  ›  专栏  ›  技术社区  ›  Nik

AutoCAD Associative Framework GetEdgeVertexSubentities()致命错误

  •  0
  • Nik  · 技术社区  · 7 年前

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

    无论是否连接调试器,都会发生这种情况。换句话说,从快捷方式启动的发布版本也会出现相同的错误。

    我试过使用不同的绘图,不同的计算机,甚至不同的操作系统(如Win7,Win10),所有这些都有相同的结果。下面的错误消息和崩溃。

    引发异常:AcdbMgd.dll中的“System.AccessViolationException”

    enter image description here

    这是完整的测试命令。有问题的代码行被清楚地标记,大约在代码段的一半。

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

    // 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;
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Gray_Rhino    7 年前

    我想这和你的visualstudio设置有关。我的建议是重新检查属性->调试。我的一个外接程序也有类似的问题,当我在调试设置中添加了工作目录和固定的命令行参数后,它开始正常工作。