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
}
我正在尝试使用带有 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
}