处理 Civil TIN 表面顶点 Autocad C#
Manipulating Civil TIN surface vertices Autocad C#
我的目标是修改现有 Civil TIN 表面中的大量顶点,并将不同的顶点组放置在不同的高程上。
我的问题是:无论我尝试做什么,在我第二次尝试访问 TinSurfaceVertex 作为更大操作的一部分时,都会抛出一条错误消息 "Operation is not valid due to the current state of the object"。我试过同时使用 surface.SetVerticesElevation(vertices, elevation) 和 surface.SetVertexElevation(vertex, elevation) - 但是对于第二个顶点或一组顶点,两者都会给我同样的错误。
我错过了什么?
这是一些代码:
public void levelTheVertexGroups()
{
foreach (VertexGroup group in this.verticeCollection) // VertexGroup is a custom class
{
List<TinSurfaceVertex> runVertices = new List<TinSurfaceVertex>();
// Filter out the vertices that have not yet been modified
foreach (TinSurfaceVertex vtx in group.ContainedVertices)
{
// Create a unique key for the vertex based on its location
// in order to filter out already updated vertices
// THIS BELOW LINE TRIGGERS THE NOTED ERROR ON
// THE SECOND RUN OF THE ORIGINAL FOREACH (VertexGroup-loop)
string key = VertexGroup.CreateUniqueVertexKey(vtx.Location);
if (!usedVertices.ContainsKey(key))
{
// Add it to the vertexes to update
runVertices.Add(vtx);
usedVertices.Add(key, vtx);
}
}
// Get the AutoCAD Editor
if (runVertices.Count > 0)
{
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
// Modify the vertices
modSurface.SetVerticesElevation(runVertices, 0.0);
modSurface.Dispose();
// Commit the transaction
tr.Commit();
}
}
}
}
似乎一旦 TIN 表面中的某些顶点被修改,所有顶点都被标记为 Civil 无法访问,其余循环变得无用。
如果我只有一个 VertexGroup,这段代码就像一个魅力。
希望有人能帮忙。非常感谢任何帮助!
更新:
我提交的原始代码反映了这样一种情况,即在第一次调用 SetVerticeElevations() 之后访问任何 TinSurfaceVertex 时,将抛出错误。我的代码与它无关。我可以设置 var test = vtx;
,同样的错误将在第二个循环的确切行上触发。
以下情况也会出现同样的错误:
foreach (VertexGroup group in this.verticeCollection)
{
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
// Modify the vertices
// THIS LINE RETURNS THE ERROR ON THE SECOND LOOP RUN
modSurface.SetVerticesElevation(group.ContainedVertices, 0.0);
// Commit the transaction
tr.Commit();
}
}
对于这种情况也是如此:
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
foreach (VertexGroup group in this.verticeCollection)
{
// Modify the vertices
// THIS LINE THROWS THE SAME ERROR ON LOOP NR 2
modSurface.SetVerticesElevation(group.ContainedVertices, 0.0);
}
// Commit the transaction
tr.Commit();
}
在这种情况下,一次编辑一个顶点:
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
foreach (VertexGroup group in this.verticeCollection)
{
// Modify the vertices
foreach(TinSurfaceVertex vtx in group.ContainedVertices)
{
// THIS LINE THROWS THE SAME ERROR ON LOOP NR 2
modSurface.SetVertexElevation(vtx, 0.0);
}
}
// Commit the transaction
tr.Commit();
}
如果我只编辑一 (1) 个顶点或一 (1) 组顶点,那么所有情况都非常有效。 C3D有问题-API?
好吧,我自己想出来了。
出现此问题是因为我尝试访问存储在 VertexGroup 中的顶点,但该顶点无效,因为它是在对表面进行更改之前存储的。
解决方法是重新获取需要修改的顶点,基于它的位置,如下所示:
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
foreach (VertexGroup group in this.verticeCollection)
{
// Populate a list of all vertices to run
List<TinSurfaceVertex> runVertices = new List<TinSurfaceVertex>();
// Try this
foreach (KeyValuePair<string, Point3d> keyVal in group.ContainedVerticePoints)
{
string key = keyVal.Key;
if (!usedVertices.ContainsKey(key))
{
// Re-fetch the vertex at xy
// THIS IS THE MAGIC
TinSurfaceVertex vtx = modSurface.FindVertexAtXY(keyVal.Value.X, keyVal.Value.Y);
// Add it to the vertexes to update
runVertices.Add(vtx);
usedVertices.Add(key, vtx);
}
}
// Only modify if not already modified
if (runVertices.Count > 0)
{
// Modify the vertices
modSurface.SetVerticesElevation(runVertices, 0.0);
}
}
// Commit the transaction
tr.Commit();
}
我的目标是修改现有 Civil TIN 表面中的大量顶点,并将不同的顶点组放置在不同的高程上。
我的问题是:无论我尝试做什么,在我第二次尝试访问 TinSurfaceVertex 作为更大操作的一部分时,都会抛出一条错误消息 "Operation is not valid due to the current state of the object"。我试过同时使用 surface.SetVerticesElevation(vertices, elevation) 和 surface.SetVertexElevation(vertex, elevation) - 但是对于第二个顶点或一组顶点,两者都会给我同样的错误。
我错过了什么?
这是一些代码:
public void levelTheVertexGroups()
{
foreach (VertexGroup group in this.verticeCollection) // VertexGroup is a custom class
{
List<TinSurfaceVertex> runVertices = new List<TinSurfaceVertex>();
// Filter out the vertices that have not yet been modified
foreach (TinSurfaceVertex vtx in group.ContainedVertices)
{
// Create a unique key for the vertex based on its location
// in order to filter out already updated vertices
// THIS BELOW LINE TRIGGERS THE NOTED ERROR ON
// THE SECOND RUN OF THE ORIGINAL FOREACH (VertexGroup-loop)
string key = VertexGroup.CreateUniqueVertexKey(vtx.Location);
if (!usedVertices.ContainsKey(key))
{
// Add it to the vertexes to update
runVertices.Add(vtx);
usedVertices.Add(key, vtx);
}
}
// Get the AutoCAD Editor
if (runVertices.Count > 0)
{
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
// Modify the vertices
modSurface.SetVerticesElevation(runVertices, 0.0);
modSurface.Dispose();
// Commit the transaction
tr.Commit();
}
}
}
}
似乎一旦 TIN 表面中的某些顶点被修改,所有顶点都被标记为 Civil 无法访问,其余循环变得无用。
如果我只有一个 VertexGroup,这段代码就像一个魅力。
希望有人能帮忙。非常感谢任何帮助!
更新:
我提交的原始代码反映了这样一种情况,即在第一次调用 SetVerticeElevations() 之后访问任何 TinSurfaceVertex 时,将抛出错误。我的代码与它无关。我可以设置 var test = vtx;
,同样的错误将在第二个循环的确切行上触发。
以下情况也会出现同样的错误:
foreach (VertexGroup group in this.verticeCollection)
{
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
// Modify the vertices
// THIS LINE RETURNS THE ERROR ON THE SECOND LOOP RUN
modSurface.SetVerticesElevation(group.ContainedVertices, 0.0);
// Commit the transaction
tr.Commit();
}
}
对于这种情况也是如此:
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
foreach (VertexGroup group in this.verticeCollection)
{
// Modify the vertices
// THIS LINE THROWS THE SAME ERROR ON LOOP NR 2
modSurface.SetVerticesElevation(group.ContainedVertices, 0.0);
}
// Commit the transaction
tr.Commit();
}
在这种情况下,一次编辑一个顶点:
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
foreach (VertexGroup group in this.verticeCollection)
{
// Modify the vertices
foreach(TinSurfaceVertex vtx in group.ContainedVertices)
{
// THIS LINE THROWS THE SAME ERROR ON LOOP NR 2
modSurface.SetVertexElevation(vtx, 0.0);
}
}
// Commit the transaction
tr.Commit();
}
如果我只编辑一 (1) 个顶点或一 (1) 组顶点,那么所有情况都非常有效。 C3D有问题-API?
好吧,我自己想出来了。
出现此问题是因为我尝试访问存储在 VertexGroup 中的顶点,但该顶点无效,因为它是在对表面进行更改之前存储的。
解决方法是重新获取需要修改的顶点,基于它的位置,如下所示:
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open for write
TinSurface modSurface = tr.GetObject(this.createdSurfaceId, OpenMode.ForWrite) as TinSurface;
foreach (VertexGroup group in this.verticeCollection)
{
// Populate a list of all vertices to run
List<TinSurfaceVertex> runVertices = new List<TinSurfaceVertex>();
// Try this
foreach (KeyValuePair<string, Point3d> keyVal in group.ContainedVerticePoints)
{
string key = keyVal.Key;
if (!usedVertices.ContainsKey(key))
{
// Re-fetch the vertex at xy
// THIS IS THE MAGIC
TinSurfaceVertex vtx = modSurface.FindVertexAtXY(keyVal.Value.X, keyVal.Value.Y);
// Add it to the vertexes to update
runVertices.Add(vtx);
usedVertices.Add(key, vtx);
}
}
// Only modify if not already modified
if (runVertices.Count > 0)
{
// Modify the vertices
modSurface.SetVerticesElevation(runVertices, 0.0);
}
}
// Commit the transaction
tr.Commit();
}