Beispiel #1
0
        public override Vec Error(CMesh cm)
        {
            List <double> err = new List <double>();
            Vec           ans = new Vec(err);

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

            // メッシュの TopologyEdges 取得
            MeshTopologyEdgeList topo_edge = cm.mesh.TopologyEdges;
            List <int>           edges_id  = cm.inner_boundary_edges;

            // 辺長一定拘束 On の時
            if (is_set_length)
            {
                for (int i = 0; i < n; i++)
                {
                    int    edge_id       = edges_id[equal_edge_ids[i]];
                    double edge_length_i = topo_edge.EdgeLine(edge_id).Length;
                    err.Add((edge_length_i * edge_length_i - edge_length * edge_length) / (2 * edge_avarage_length * edge_avarage_length));
                }
                ans = new Vec(err);
            }

            // 辺長一定拘束 Off の時
            else
            {
                // 等長拘束の誤差取得
                for (int i = 0; i < n - 1; i++)
                {
                    int edge_id_i  = edges_id[equal_edge_ids[i]];
                    int edge_id_i1 = edges_id[equal_edge_ids[i + 1]];

                    double edge_length_i  = topo_edge.EdgeLine(edge_id_i).Length;
                    double edge_length_i1 = topo_edge.EdgeLine(edge_id_i1).Length;
                    err.Add((edge_length_i * edge_length_i - edge_length_i1 * edge_length_i1) / (2 * edge_avarage_length * edge_avarage_length));
                }

                ans = new Vec(err);
            }


            return(ans);
        }
Beispiel #2
0
        public Graph(Mesh mesh)
        {
            Vertices = mesh.Vertices.ToPoint3dArray().ToList();

            int numberOfCurves = mesh.TopologyEdges.Count * 2;

            Edges         = new Curve[numberOfCurves];
            EdgesWeights  = new double[numberOfCurves];
            GraphArray    = new int[2, numberOfCurves];
            AdjacencyList = new AdjacencyList(Vertices.Count);

            MeshTopologyEdgeList topologyEdgeList = mesh.TopologyEdges;

            int currentEdgeCount = 0;

            for (int i = 0; i < topologyEdgeList.Count; i++)
            {
                int firstVertexIndex  = topologyEdgeList.GetTopologyVertices(i).I;
                int secondVertexIndex = topologyEdgeList.GetTopologyVertices(i).J;

                double currentEdgeWeight = topologyEdgeList.EdgeLine(i).Length;

                Curve currentEdge = topologyEdgeList.EdgeLine(i).ToNurbsCurve();
                Edges[currentEdgeCount]         = currentEdge;
                EdgesWeights[currentEdgeCount]  = currentEdgeWeight;
                GraphArray[0, currentEdgeCount] = firstVertexIndex;
                GraphArray[1, currentEdgeCount] = secondVertexIndex;

                AdjacencyList.Vertices[firstVertexIndex].Add(secondVertexIndex);
                AdjacencyList.Edges[firstVertexIndex].Add(currentEdgeCount);
                currentEdgeCount += 1;

                Curve duplicateReversedEdge = currentEdge.DuplicateCurve();
                duplicateReversedEdge.Reverse();
                Edges[currentEdgeCount]         = duplicateReversedEdge;
                EdgesWeights[currentEdgeCount]  = currentEdgeWeight;
                GraphArray[0, currentEdgeCount] = secondVertexIndex;
                GraphArray[1, currentEdgeCount] = firstVertexIndex;

                AdjacencyList.Vertices[secondVertexIndex].Add(firstVertexIndex);
                AdjacencyList.Edges[secondVertexIndex].Add(currentEdgeCount);
                currentEdgeCount += 1;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Provides an Icon for the component.
        /// </summary>

        public override CRS Jacobian(CMesh cm)
        {
            Mesh          m       = cm.mesh;
            List <double> var     = new List <double>();
            List <int>    r_index = new List <int>();
            List <int>    c_index = new List <int>();
            CRS           Jaco    = new CRS(var, r_index, c_index, 0, 0);

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

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

            // メッシュの TopologyEdges 取得
            MeshTopologyEdgeList topo_edge = m.TopologyEdges;
            List <int>           edges_id  = cm.inner_boundary_edges;


            // 辺長一定拘束 On の時
            if (is_set_length)
            {
                for (int i = 0; i < n; i++)
                {
                    int edge_id    = edges_id[equal_edge_ids[i]];
                    int st_pti_id  = topo_edge.GetTopologyVertices(edge_id).I;
                    int end_pti_id = topo_edge.GetTopologyVertices(edge_id).J;

                    Vector3d vsti = verts[st_pti_id] - verts[end_pti_id];
                    Vector3d veti = -vsti;

                    for (int j = 0; j < 3; j++)
                    {
                        var.Add(vsti[j] / (edge_avarage_length * edge_avarage_length));
                        r_index.Add(i);
                        c_index.Add(3 * st_pti_id + j);
                        var.Add(veti[j] / (edge_avarage_length * edge_avarage_length));
                        r_index.Add(i);
                        c_index.Add(3 * end_pti_id + j);
                    }
                }
                Jaco = new CRS(var, r_index, c_index, n, verts.Count * 3);
            }
            else
            {
                for (int i = 0; i < n - 1; i++)
                {
                    int edge_id_i  = edges_id[equal_edge_ids[i]];
                    int edge_id_i1 = edges_id[equal_edge_ids[i + 1]];

                    int st_pti_id   = topo_edge.GetTopologyVertices(edge_id_i).I;
                    int end_pti_id  = topo_edge.GetTopologyVertices(edge_id_i).J;
                    int st_pti1_id  = topo_edge.GetTopologyVertices(edge_id_i1).I;
                    int end_pti1_id = topo_edge.GetTopologyVertices(edge_id_i1).J;

                    Vector3d vsti  = verts[st_pti_id] - verts[end_pti_id];
                    Vector3d veti  = -vsti;
                    Vector3d vsti1 = verts[end_pti1_id] - verts[st_pti1_id];
                    Vector3d veti1 = -vsti1;

                    for (int j = 0; j < 3; j++)
                    {
                        var.Add(vsti[j] / (edge_avarage_length * edge_avarage_length));
                        r_index.Add(i);
                        c_index.Add(3 * st_pti_id + j);
                        var.Add(veti[j] / (edge_avarage_length * edge_avarage_length));
                        r_index.Add(i);
                        c_index.Add(3 * end_pti_id + j);
                        var.Add(vsti1[j] / (edge_avarage_length * edge_avarage_length));
                        r_index.Add(i);
                        c_index.Add(3 * st_pti1_id + j);
                        var.Add(veti1[j] / (edge_avarage_length * edge_avarage_length));
                        r_index.Add(i);
                        c_index.Add(3 * end_pti1_id + j);
                    }
                }

                Jaco = new CRS(var, r_index, c_index, n - 1, verts.Count * 3);
            }

            return(Jaco);
        }
Beispiel #4
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);
        }
Beispiel #5
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);
        }