Ejemplo n.º 1
0
        public override Vec Error(CMesh cm)
        {
            Mesh m = cm.mesh;

            List <double> err = new List <double>();

            m.Normals.ComputeNormals();
            var topo = m.TopologyVertices;

            topo.SortEdges();

            List <bool> isNaked          = new List <bool>(m.GetNakedEdgePointStatus());
            List <int>  internalVertices = new List <int>();

            for (int i = 0; i < topo.Count; i++)
            {
                if (!isNaked[i])
                {
                    internalVertices.Add(i);
                }
            }

            //各内部頂点について
            for (int r = 0; r < internalVertices.Count; r++)
            {
                //内部頂点のインデックス、位置ベクトル
                int      index_center = internalVertices[r];
                Vector3d center       = new Vector3d(topo[index_center]);

                //接続点のインデックス、位置ベクトル
                List <int>      index_neighbors = new List <int>();
                List <Vector3d> neighbors       = new List <Vector3d>();
                index_neighbors.AddRange(topo.ConnectedTopologyVertices(index_center));

                //エッジベクトル
                List <Vector3d> vecs = new List <Vector3d>();
                double          sum  = 0;

                int n = index_neighbors.Count;

                //三角形分割の区別
                List <int>  connected_edges = new List <int>(topo.ConnectedEdges(index_center));
                List <bool> is_corrects     = new List <bool>();

                for (int i = 0; i < n; i++)
                {
                    bool is_correct = m.TopologyEdges.GetTopologyVertices(connected_edges[i]).Contains(index_neighbors[i]);
                    is_corrects.Add(is_correct);
                }

                List <double> signs = new List <double>();
                for (int i = -1; i < n - 1; i++)
                {
                    if (i == -1)
                    {
                        signs.Add(1);
                    }
                    else if (cm.edgeInfo[connected_edges[i]] != 'T')
                    {
                        signs.Add(-signs[i]);
                    }
                    else
                    {
                        signs.Add(signs[i]);
                    }
                }

                //位置ベクトル取得
                foreach (int index_neighbor in index_neighbors)
                {
                    neighbors.Add(new Vector3d(topo[index_neighbor]));
                }

                //方向ベクトル取得
                foreach (Vector3d neighbor in neighbors)
                {
                    Vector3d temp = neighbor - center;
                    vecs.Add(temp);
                }

                for (int i = 0; i < n; i++)
                {
                    if (i == 0)
                    {
                        sum += signs[i] * Vector3d.VectorAngle(vecs[n - 1], vecs[0]);
                    }
                    else
                    {
                        sum += signs[i] * Vector3d.VectorAngle(vecs[i - 1], vecs[i]);
                    }
                }

                err.Add((double)sum);
            }

            Vec ans = new Vec(err);

            return(ans);
        }
Ejemplo n.º 2
0
        public override Vec Error(CMesh cm)
        {
            Mesh           m       = cm.mesh;
            List <Point3d> verts   = new List <Point3d>(m.Vertices.ToPoint3dArray());
            List <double>  foldang = new List <double>();

            // 等長拘束をかける辺の数取得
            int n = equal_fold_angle_edge_id.Count;

            // メッシュの TopologyEdges 取得
            MeshTopologyEdgeList topo_edges = m.TopologyEdges;

            // 法線方向計算
            m.FaceNormals.ComputeFaceNormals();

            for (int i = 0; i < n; i++)
            {
                double foldang_i = 0;
                /// Register indices
                int       edge_index = equal_fold_angle_edge_id[i];
                IndexPair edge_ind   = topo_edges.GetTopologyVertices(edge_index);
                int       u          = edge_ind.I;
                int       v          = edge_ind.J;
                IndexPair face_ind   = cm.face_pairs[edge_index];
                int       P          = face_ind[0];
                int       Q          = face_ind[1];

                MeshFace face_P = m.Faces[P];
                MeshFace face_Q = m.Faces[Q];
                int      p      = 0;
                int      q      = 0;
                for (int j = 0; j < 3; j++)
                {
                    if (!edge_ind.Contains(face_P[j]))
                    {
                        p = face_P[j];
                    }
                    if (!edge_ind.Contains(face_Q[j]))
                    {
                        q = face_Q[j];
                    }
                }
                /// Compute normals
                Vector3d normal_P = m.FaceNormals[P];
                Vector3d normal_Q = m.FaceNormals[Q];
                /// cos(foldang_e) = n_i * n_j
                double cos_foldang_e = normal_P * normal_Q;
                /// sin(foldang_e) = n_i × n_j
                Vector3d vec_e = verts[u] - verts[v];
                vec_e.Unitize();
                double sin_foldang_e = Vector3d.CrossProduct(normal_P, normal_Q) * vec_e;
                if (sin_foldang_e >= 0)
                {
                    if (cos_foldang_e >= 1.0)
                    {
                        foldang_i = 0;
                    }
                    else if (cos_foldang_e <= -1.0)
                    {
                        foldang_i = Math.PI;
                    }
                    else
                    {
                        foldang_i = Math.Acos(cos_foldang_e);
                    }
                }
                else
                {
                    if (cos_foldang_e >= 1.0)
                    {
                        foldang_i = 0;
                    }
                    else if (cos_foldang_e <= -1.0)
                    {
                        foldang_i = -Math.PI;
                    }
                    else
                    {
                        foldang_i = -Math.Acos(cos_foldang_e);
                    }
                }
                if (is_set_angle)
                {
                    foldang_i -= fold_angle;
                }
                foldang.Add(foldang_i);
            }
            Vec ans = new Vec(foldang);

            return(ans);
        }