处理 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();

}