예제 #1
0
        public void GetValleyFacePairBasicInfo(CMesh cm)
        {
            Mesh m = cm.mesh;

            List <Tuple <double, double> > face_heignt_pairs = new List <Tuple <double, double> >();
            List <double> edge_length_between_face_pairs     = new List <double>();

            m.FaceNormals.ComputeFaceNormals();

            MeshVertexList vert = m.Vertices;

            for (int e_ind = 0; e_ind < cm.valley_edges.Count; e_ind++)
            {
                // Register indices
                IndexPair edge_ind = cm.valley_edges[e_ind];
                int       u        = edge_ind.I;
                int       v        = edge_ind.J;
                IndexPair face_ind = cm.valley_face_pairs[e_ind];
                int       P        = face_ind.I;
                int       Q        = face_ind.J;

                MeshFace face_P = m.Faces[P];
                MeshFace face_Q = m.Faces[Q];
                int      p      = 0;
                int      q      = 0;
                for (int i = 0; i < 3; i++)
                {
                    if (!edge_ind.Contains(face_P[i]))
                    {
                        p = face_P[i];
                    }
                    if (!edge_ind.Contains(face_Q[i]))
                    {
                        q = face_Q[i];
                    }
                }
                /// Compute h_P & cot_Pu
                Vector3d vec_up = vert[p] - vert[u];
                Vector3d vec_uv = vert[v] - vert[u];
                double   sin_Pu = (Vector3d.CrossProduct(vec_up, vec_uv) / (vec_up.Length * vec_uv.Length)).Length;
                double   len_up = (vec_up - vec_uv).Length;
                double   h_P    = len_up * sin_Pu;
                /// Compute h_Q & cot_Qu
                Vector3d vec_uq = vert[q] - vert[u];
                double   sin_Qu = (Vector3d.CrossProduct(vec_uq, vec_uv) / (vec_uq.Length * vec_uv.Length)).Length;
                double   len_uq = (vec_uq - vec_uv).Length;
                double   h_Q    = len_uq * sin_Qu;
                // Compute len_uv
                double len_uv = vec_uv.Length;
                // Set Tuple<h_P, h_Q>
                Tuple <double, double> face_height_pair = new Tuple <double, double>(h_P, h_Q);
                face_heignt_pairs.Add(face_height_pair);
                edge_length_between_face_pairs.Add(len_uv);
            }
            cm.valley_face_height_pairs        = face_heignt_pairs;
            cm.length_of_valley_diagonal_edges = edge_length_between_face_pairs;
        }
예제 #2
0
        public override CRS Jacobian(CMesh cm)
        {
            // 等長拘束をかける辺の数取得
            int n = equal_fold_angle_edge_id.Count;

            List <double> var  = new List <double>();
            List <int>    rind = new List <int>();
            List <int>    cind = new List <int>();


            List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray());
            Mesh           m     = cm.mesh;

            m.FaceNormals.ComputeFaceNormals();

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

            for (int i = 0; i < n; i++)
            {
                // 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];
                /// Compute h_P & cot_Pu
                Vector3d vec_up = verts[p] - verts[u];
                Vector3d vec_uv = verts[v] - verts[u];
                double   sin_Pu = (Vector3d.CrossProduct(vec_up, vec_uv) / (vec_up.Length * vec_uv.Length)).Length;
                double   cos_Pu = (vec_up * vec_uv) / (vec_up.Length * vec_uv.Length);
                double   cot_Pu = cos_Pu / sin_Pu;
                double   len_up = vec_up.Length;
                double   h_P    = len_up * sin_Pu;
                /// Compute cot_Pv
                Vector3d vec_vp = verts[p] - verts[v];
                Vector3d vec_vu = verts[u] - verts[v];
                double   sin_Pv = (Vector3d.CrossProduct(vec_vp, vec_vu) / (vec_vp.Length * vec_vu.Length)).Length;
                double   cos_Pv = (vec_vp * vec_vu) / (vec_vp.Length * vec_vu.Length);
                double   cot_Pv = cos_Pv / sin_Pv;
                /// Compute h_Q & cot_Qu
                Vector3d vec_uq = verts[q] - verts[u];
                double   sin_Qu = (Vector3d.CrossProduct(vec_uq, vec_uv) / (vec_uq.Length * vec_uv.Length)).Length;
                double   cos_Qu = (vec_uq * vec_uv) / (vec_uq.Length * vec_uv.Length);
                double   cot_Qu = cos_Qu / sin_Qu;
                double   len_uq = vec_uq.Length;
                double   h_Q    = len_uq * sin_Qu;
                /// Compute cot_Qv
                Vector3d      vec_vq        = verts[q] - verts[v];
                double        sin_Qv        = (Vector3d.CrossProduct(vec_vq, vec_vu) / (vec_vq.Length * vec_vu.Length)).Length;
                double        cos_Qv        = vec_vq * vec_vu / (vec_vq.Length * vec_vu.Length);
                double        cot_Qv        = cos_Qv / sin_Qv;
                List <double> normal_P_list = new List <double>();
                List <double> normal_Q_list = new List <double>();
                normal_P_list.Add(normal_P.X);
                normal_P_list.Add(normal_P.Y);
                normal_P_list.Add(normal_P.Z);
                normal_Q_list.Add(normal_Q.X);
                normal_Q_list.Add(normal_Q.Y);
                normal_Q_list.Add(normal_Q.Z);
                /// Compute coefficients
                double co_pv = (-1 * cot_Pv) / (cot_Pu + cot_Pv);
                double co_qv = (-1 * cot_Qv) / (cot_Qu + cot_Qv);
                double co_pu = (-1 * cot_Pu) / (cot_Pu + cot_Pv);
                double co_qu = (-1 * cot_Qu) / (cot_Qu + cot_Qv);
                /// Compute Jacobian
                for (int v_ind = 0; v_ind < verts.Count; v_ind++)
                {
                    if (v_ind == p)
                    {
                        for (int x = 0; x < 3; x++)
                        {
                            var.Add((normal_P_list[x] / (h_P)));
                            cind.Add(3 * v_ind + x);
                            rind.Add(i);
                        }
                    }
                    if (v_ind == q)
                    {
                        for (int x = 0; x < 3; x++)
                        {
                            var.Add((normal_Q_list[x] / (h_Q)));
                            cind.Add(3 * v_ind + x);
                            rind.Add(i);
                        }
                    }
                    if (v_ind == u)
                    {
                        for (int x = 0; x < 3; x++)
                        {
                            var.Add(((co_pv * (normal_P_list[x] / h_P) + co_qv * (normal_Q_list[x] / h_Q))));
                            cind.Add(3 * v_ind + x);
                            rind.Add(i);
                        }
                    }
                    if (v_ind == v)
                    {
                        for (int x = 0; x < 3; x++)
                        {
                            var.Add(((co_pu * (normal_P_list[x] / h_P) + co_qu * (normal_Q_list[x] / h_Q))));
                            cind.Add(3 * v_ind + x);
                            rind.Add(i);
                        }
                    }
                }
            }

            CRS Jaco = new CRS(var, rind, cind, n, verts.Count * 3);

            return(Jaco);
        }
예제 #3
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);
        }