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); }
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; } }
/// <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); }
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); }
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); }