コード例 #1
0
 public void AppendUniqueNeighbor(SimplifyVertex vertex)
 {
     if (!neighbors.Contains(vertex) && this != vertex)
     {
         neighbors.Add(vertex);
     }
 }
コード例 #2
0
    private float ComputeEdgeCollapseCost(SimplifyVertex u, SimplifyVertex v)
    {
        Vector3 tp         = v.position - u.position;
        float   edgelength = Vector3.SqrMagnitude(tp);
        float   curvature  = 0.0f; // 曲率

        List <SimplifyTriangle> sides = new List <SimplifyTriangle>();

        // 查找uv为边的三角形
        foreach (SimplifyTriangle simplifyTriangle in u.triangles)
        {
            if (simplifyTriangle.Contains(v))
            {
                sides.Add(simplifyTriangle);
            }
        }

        foreach (SimplifyTriangle triangle in u.triangles)
        {
            float mincurv = 1;
            foreach (SimplifyTriangle sTriangle in sides)
            {
                float dotprod = Vector3.Dot(triangle.normal, sTriangle.normal);
                mincurv = Mathf.Min(mincurv, (1.0f - dotprod) / 2.0f);
            }

            curvature = Mathf.Max(curvature, mincurv);
        }

        return(edgelength * curvature);
    }
コード例 #3
0
 public SimplifyTriangle(SimplifyVertex v0, SimplifyVertex v1, SimplifyVertex v2)
 {
     this.v0 = v0;
     this.v1 = v1;
     this.v2 = v2;
     this.v0.triangles.Add(this);
     this.v1.triangles.Add(this);
     this.v2.triangles.Add(this);
     ComputeNormal();
 }
コード例 #4
0
    private SimplifyVertex MiniCostEdge()
    {
        SimplifyVertex mn = vertices[0];

        foreach (SimplifyVertex v in vertices)
        {
            if (!v.isRemoved && v.cost < mn.cost)
            {
                mn = v;
            }
        }
        return(mn);
    }
コード例 #5
0
    public void RemvoeIfNonNeighbor(SimplifyVertex vertex)
    {
        if (!neighbors.Contains(vertex))
        {
            return;
        }
        foreach (SimplifyTriangle triangle in triangles)
        {
            if (triangle.Contains(vertex))
            {
                return;
            }
        }

        neighbors.Remove(vertex);
    }
コード例 #6
0
    // u->v 顶点v替换u 移除u
    private void Collapse(SimplifyVertex u, SimplifyVertex v)
    {
        if (v == null)
        {
            u.Remove();
            vertices.Remove(u);
            return;
        }

        int i;
        List <SimplifyVertex> tmp = new List <SimplifyVertex>();
        SimplifyTriangle      simplifyTriangle;

        for (i = 0; i < u.neighbors.Count; i++)
        {
            tmp.Add(u.neighbors[i]);
        }
        // 移除包含uv边的三角形
        for (i = u.triangles.Count - 1; i >= 0; i--)
        {
            if (u.triangles[i].Contains(v))
            {
                simplifyTriangle = u.triangles[i];
                triangles.Remove(simplifyTriangle);
                simplifyTriangle.Remove();
            }
        }

        // 用v替换u 更新包含u但不包含v的三角形
        for (i = u.triangles.Count - 1; i >= 0; i--)
        {
            u.triangles[i].ReplaceSimplifyVertex(u, v);
        }

        u.Remove();
        vertices.Remove(u);

        for (i = 0; i < tmp.Count; i++)
        {
            ComputeEdgeCostAtVertex(tmp[i]);
        }
    }
コード例 #7
0
    private void ComputeEdgeCostAtVertex(SimplifyVertex v)
    {
        if (v.neighbors.Count == 0)
        {
            v.collapse = null;
            v.cost     = -0.01f;
            return;
        }

        v.cost     = 1000000.0f;
        v.collapse = null;

        //if (v.isEdge) return;

        foreach (SimplifyVertex nVertex in v.neighbors)
        {
            float cost = ComputeEdgeCollapseCost(v, nVertex);
            if (cost < v.cost)
            {
                v.collapse = nVertex;
                v.cost     = cost;
            }
        }
    }
コード例 #8
0
    public Mesh GetSimplifyMesh(int targetVerNum)
    {
        if (m_targetVerNum == targetVerNum)
        {
            return(null);
        }

        m_targetVerNum = targetVerNum;
        ComputeAllEdgeCollapseCosts();

        while (true)
        {
            int vertexCount = vertices.Count;
            if (vertexCount == 0 || vertexCount <= m_targetVerNum)
            {
                break;
            }

            SimplifyVertex mn = MiniCostEdge();

            //if (mn.isRemoved || mn.cost > 1000000.0f) break;

            Collapse(mn, mn.collapse);
            vertices.Remove(mn);
        }

        triangles.RemoveAll((triangle) => {
            return(triangle.isRemoved);
        });

        List <int>            indices   = new List <int>();
        List <Vector3>        tVertices = new List <Vector3>();
        List <Vector2>        tUVS      = new List <Vector2>();
        Dictionary <int, int> idindex   = new Dictionary <int, int>();

        int indexV = 0;

        foreach (SimplifyTriangle triangle in triangles)
        {
            if (!idindex.TryGetValue(triangle.v0.id, out indexV))
            {
                indexV = tVertices.Count;
                idindex.Add(triangle.v0.id, indexV);
                tVertices.Add(triangle.v0.position);
                tUVS.Add(triangle.v0.uv);
            }
            indices.Add(indexV);
            if (!idindex.TryGetValue(triangle.v1.id, out indexV))
            {
                indexV = tVertices.Count;
                idindex.Add(triangle.v1.id, indexV);
                tVertices.Add(triangle.v1.position);
                tUVS.Add(triangle.v1.uv);
            }
            indices.Add(indexV);
            if (!idindex.TryGetValue(triangle.v2.id, out indexV))
            {
                indexV = tVertices.Count;
                idindex.Add(triangle.v2.id, indexV);
                tVertices.Add(triangle.v2.position);
                tUVS.Add(triangle.v2.uv);
            }
            indices.Add(indexV);
        }

        Mesh simplifyMesh = new Mesh();

        simplifyMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        simplifyMesh.vertices    = tVertices.ToArray();
        //simplifyMesh.uv = tUVS.ToArray();
        simplifyMesh.triangles = indices.ToArray();
        simplifyMesh.RecalculateNormals();

        renderVerticesNum  = tVertices.Count;
        renderTrianglesNum = indices.Count / 3;
        return(simplifyMesh);
    }
コード例 #9
0
    public void ReplaceSimplifyVertex(SimplifyVertex vold, SimplifyVertex vnew)
    {
        if (vold == null || vnew == null)
        {
            return;
        }
        if (vold != v0 && vold != v1 && vold != v2)
        {
            return;
        }
        if (vnew == v0 || vnew == v1 || vnew == v2)
        {
            return;
        }

        if (vold == v0)
        {
            v0 = vnew;
        }

        if (vold == v1)
        {
            v1 = vnew;
        }

        if (vold == v2)
        {
            v2 = vnew;
        }

        int i;

        vold.triangles.Remove(this);

        if (vnew.triangles.Contains(this))
        {
            return;
        }

        vnew.triangles.Add(this);

        vold.RemoveNeighbor(v0);
        vold.RemoveNeighbor(v1);
        vold.RemoveNeighbor(v2);

        if (v0.GetSimplifyTriangleCount(this) == 1)
        {
            v0.AppendUniqueNeighbor(v1);
            v0.AppendUniqueNeighbor(v2);
        }

        if (v1.GetSimplifyTriangleCount(this) == 1)
        {
            v1.AppendUniqueNeighbor(v0);
            v1.AppendUniqueNeighbor(v2);
        }

        if (v2.GetSimplifyTriangleCount(this) == 1)
        {
            v2.AppendUniqueNeighbor(v0);
            v2.AppendUniqueNeighbor(v1);
        }

        ComputeNormal();
    }
コード例 #10
0
 public bool Contains(SimplifyVertex v)
 {
     return(v == v0 || v == v1 || v == v2);
 }