操纵Civil TIN曲面顶点Autocad C#

时间:2016-02-03 14:44:05

标签: c# autocad

我的目标是修改现有Civil TIN曲面中的大量顶点,并将不同的顶点组放在不同的高程上。

我的问题是:无论我尝试做什么,我都会抛出错误说"由于对象的当前状态,操作无效"我第二次尝试访问TinSurfaceVertex作为更大操作的一部分。我尝试过使用surface.SetVerticesElevation(顶点,高程)和surface.SetVertexElevation(顶点,高程) - 但两者都为第二个顶点或顶点组投掷了相同的错误。

enter image description here

我错过了什么?

这里有一些代码:

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中是否存在问题?

1 个答案:

答案 0 :(得分:0)

好的,我自己想出来了。

出现此问题是因为我尝试访问存储在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();

}