Ассоциативная структура AutoCAD GetEdgeVertexSubentities () ФАТАЛЬНАЯ ОШИБКА - PullRequest
0 голосов
/ 23 ноября 2018

AutoCAD 2015 - в настоящее время я изучаю .NET API для создания геометрических ограничений (примечание: я не новичок в AutoCAD API в целом).Я работаю с примером кода, который я изучил на одном из курсов AutoDesk, и не могу понять, почему у меня возникает «ФАТАЛЬНАЯ ОШИБКА» и происходит сбой при попытке получить вершины объекта с помощью GetEdgeVertexSubentities(..),Исключение не выдается, Autocad просто выскакивает сообщение и вылетает.Try / Catch ничего не делает, поэтому не может проверить сообщение об исключении или стек вызовов.Если кто-то видел это раньше или имеет какие-то идеи, как то, на что я могу посмотреть или попробовать, это будет высоко оценено.

Это происходит с отладчиком и без него.Другими словами, такая же ошибка возникает при сборке релиза, запущенной с ярлыка.

Я пробовал использовать другой чертеж, другой компьютер и даже другую ОС (например, Win7, Win10), все с одинаковымиконечный результат.Приведенное ниже сообщение об ошибке и сбой.

Сообщение в окне вывода Visual Studio:

Исключение: 'System.AccessViolationException' в AcdbMgd.dll

Ивсплывающее сообщение об ошибке:

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 Ответ

0 голосов
/ 23 ноября 2018

(я хотел добавить это как комментарий, но пока не имею права комментировать) Я думаю, что это связано с вашими настройками Visual Studio.Мое предложение будет дважды проверить свойства -> отладка.У меня была похожая проблема с одной из моих надстроек, и она начала работать, как и ожидалось, после того, как я добавил рабочий каталог и исправил аргумент командной строки в настройках отладки.

...