C# - Autocad api - 由于对象的当前状态,操作无效

C# - Autocad api - Operation is not valid due to the current state of the object

我正在尝试使用带有 C# 的 Autocad-API 绘制一些线条。我通常使用 Revit,但现在我正在探索 AutoCAD 的 API.

长话短说,我有一些折线矩形已拆分,转换为 Line2D,现在我正尝试将它们添加到另一个列表,但它们的信息并未随附。新列表显示它们在那里,但它们没有起点或终点,并且出现此错误:

Exception thrown: 'System.InvalidOperationException' in AcdbMgd.dll
An exception of type 'System.InvalidOperationException' occurred in AcdbMgd.dll but was not handled in user code
Additional information: Operation is not valid due to the current state of the object.

我认为这可能与块 table 记录或打开对象以供读取有关?我不知道。我环顾四周但没有找到任何信息。此外,关于 BlockTableRecord 的信息似乎......在其使用方式方面也很稀疏。我只发现 this link 在使用示例

上做了很好的解释

感谢任何帮助。

这是我的 3dLineList 的截图:

这是我的新 2dLinelist 的截图:

这是我的代码:


// Get the current document and database, and start a transaction
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database acCurDb = doc.Database;

using (Transaction tr = acCurDb.TransactionManager.StartTransaction())
                {

                    // Open the Block table record for read
                    BlockTable acBlkTbl;
                    acBlkTbl = tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                    // Open the Block table record Model space for read
                    BlockTableRecord acBlkTblRec;
                    acBlkTblRec = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

                    List<Line> lineList3d = new List<Line>();

                    doc.Editor.WriteMessage("\nModel space objects: ");
                    // Step through each object in Model space and
                    // display the type of object found
                    foreach (ObjectId objId in acBlkTblRec)
                    {
                        doc.Editor.WriteMessage("\n" + objId.ObjectClass.DxfName);
                        if (objId.ObjectClass.DxfName == "LWPOLYLINE")
                        {

                            Polyline polyline = (Polyline)tr.GetObject(objId, OpenMode.ForRead);

                            for (int i = 0; i < polyline.NumberOfVertices; i++)
                            {
                                if (i != polyline.NumberOfVertices - 1)
                                {
                                    Point3d pt1 = polyline.GetPoint3dAt(i);
                                    Point3d pt2 = polyline.GetPoint3dAt(i + 1); // TODO: getting index out of range here. fix it. 
                                    UnitsConverter.GetConversionFactor(UnitsValue.Inches, UnitsValue.Feet);

                                    var lineSegment = new Line(pt1, pt2);

                                    lineList3d.Add(lineSegment);
                                }
                                else if (i == polyline.NumberOfVertices - 1)
                                {
                                    Point3d pt1 = polyline.GetPoint3dAt(i);
                                    Point3d pt2 = polyline.GetPoint3dAt(0);
                                    UnitsConverter.GetConversionFactor(UnitsValue.Inches, UnitsValue.Feet);

                                    var lineSegment = new Line(pt1, pt2);

                                    lineList3d.Add(lineSegment);
                                }
                            }
                        }
                        else if (objId.ObjectClass.DxfName == "LINE")
                        {
                            Line line = (Line)tr.GetObject(objId, OpenMode.ForRead);
                            lineList3d.Add(line);
                        }
                    }


                    // find the other side of the wall
                    List<Line2d> lineList2d = new List<Line2d>();
                    foreach (Line xLine3d in lineList3d)
                    {
                        
                        // convert 3dline to line2d
                        Plane linePlane = xLine3d.GetPlane();
                        Point2d line1pt1 = xLine3d.StartPoint.Convert2d(linePlane);
                        Point2d line1pt2 = xLine3d.EndPoint.Convert2d(linePlane);
                        Line2d line2d = new Line2d(line1pt1, line1pt2);
                        lineList2d.Add(line2d);

                        Debug.WriteLine("line2d: " + line2d.StartPoint); // <-- Crash occurs here


                    }
                }

原来我应该使用 LineSegment2d 而不是 Line2d

¯_(ツ)_/¯

Autodesk.AutoCAD.Geometry.Line2d 代表一条无界线(没有起点和终点)。 如果需要二维线段列表(LineSegement2d),可以直接使用 Polyline.GetLineSegment2dAt() 方法获取。

        // Get the current document and database, and start a transaction
        var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
        var ed = doc.Editor;
        var db = doc.Database;

        using (var tr = db.TransactionManager.StartTransaction())
        {

            // Open the Block table record for read
            var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
            // Open the Block table record Model space for read
            var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

            var segments = new List<LineSegment2d>();

            doc.Editor.WriteMessage("\nModel space objects: ");
            // Step through each object in Model space and
            // display the type of object found
            foreach (ObjectId id in btr)
            {
                ed.WriteMessage("\n" + id.ObjectClass.DxfName);
                if (id.ObjectClass.DxfName == "LWPOLYLINE")
                {

                    var polyline = (Polyline)tr.GetObject(id, OpenMode.ForRead);

                    for (int i = 0; i < polyline.NumberOfVertices; i++)
                    {
                        if (i != polyline.NumberOfVertices - 1)
                        {
                            if (polyline.GetSegmentType(i) == SegmentType.Line)
                                segments.Add(polyline.GetLineSegment2dAt(i));
                        }
                    }
                }
                else if (id.ObjectClass.DxfName == "LINE")
                {
                    var line = (Line)tr.GetObject(id, OpenMode.ForRead);
                    var linePlane = line.GetPlane();
                    segments.Add(new LineSegment2d(line.StartPoint.Convert2d(linePlane), line.EndPoint.Convert2d(linePlane)));
                }
            }


            // find the other side of the wall
            foreach (var segment in segments)
            {
                Debug.WriteLine("line2d: " + segment.StartPoint); // <-- Crash occurs here
            }