public override CRS Jacobian(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); Mesh m = cm.mesh; List <double> var = new List <double>(); List <int> r_index = new List <int>(); List <int> c_index = new List <int>(); for (int i = 0; i < this.anchors_index.Count; i++) { Point3d ancpt = this.anchors_position[this.anchors_index[i]]; Point3d pt = m.Vertices[this.anchors_index[i]]; for (int j = 0; j < 3; j++) { var.Add(strength * (pt[j] - ancpt[j]) / (edge_avarage_length * edge_avarage_length)); r_index.Add(i); c_index.Add(3 * this.anchors_index[i] + j); } } CRS Jaco = new CRS(var, r_index, c_index, this.anchors_index.Count, verts.Count * 3); return(Jaco); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { CMesh cmesh = null; if (!DA.GetData(0, ref cmesh)) { return; } Mesh m = cmesh.mesh; List <Point3d> verts = new List <Point3d>(m.Vertices.ToPoint3dArray()); List <int> edges_id = cmesh.inner_boundary_edges; List <Point3d> pts = new List <Point3d>(); // List<TextDot> id_texts = new List<TextDot>(); for (int i = 0; i < edges_id.Count; i++) { IndexPair edge_end_pt_id_pair = m.TopologyEdges.GetTopologyVertices(edges_id[i]); Point3d ptI = verts[edge_end_pt_id_pair.I]; Point3d ptJ = verts[edge_end_pt_id_pair.J]; Point3d pt = (ptI + ptJ) / 2; // TextDot id_text = new TextDot(i.ToString(), pt); // id_texts.Add(id_text); pts.Add(pt); } DA.SetDataList(0, pts); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from input parameters and /// to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { // 値をセットする毎に public member をリフレッシュ anchors_position = new List <Point3d>(); anchors_index = new List <int>(); strength = 1.0; CMesh cmesh = null; if (!DA.GetData(0, ref cmesh)) { return; } if (!DA.GetDataList(1, anchors_index)) { return; } DA.GetData(2, ref strength); anchors_position = new List <Point3d>(cmesh.mesh.Vertices.ToPoint3dArray()); int edge_count = cmesh.mesh.TopologyEdges.Count; for (int i = 0; i < edge_count; i++) { edge_avarage_length += cmesh.mesh.TopologyEdges.EdgeLine(i).Length; } edge_avarage_length /= edge_count; DA.SetData(0, this); }
public CMesh(CMesh _cmesh) { this.mesh = _cmesh.mesh.DuplicateMesh(); this.edgeInfo = _cmesh.edgeInfo; this.orig_faces = _cmesh.orig_faces; this.inner_edges = _cmesh.inner_edges; this.inner_edge_assignment = _cmesh.inner_edge_assignment; this.boundary_edges = _cmesh.boundary_edges; this.inner_boundary_edges = _cmesh.inner_boundary_edges; this.face_pairs = _cmesh.face_pairs; this.face_height_pairs = _cmesh.face_height_pairs; this.length_of_diagonal_edges = _cmesh.length_of_diagonal_edges; this.foldang = _cmesh.foldang; this.triangulated_edges = _cmesh.triangulated_edges; this.triangulated_face_pairs = _cmesh.triangulated_face_pairs; this.triangulated_face_height_pairs = _cmesh.triangulated_face_height_pairs; this.length_of_triangulated_diagonal_edges = _cmesh.length_of_triangulated_diagonal_edges; this.mountain_edges = _cmesh.mountain_edges; this.mountain_face_pairs = _cmesh.mountain_face_pairs; this.mountain_face_height_pairs = _cmesh.mountain_face_height_pairs; this.length_of_mountain_diagonal_edges = _cmesh.length_of_mountain_diagonal_edges; this.valley_edges = _cmesh.valley_edges; this.valley_face_pairs = _cmesh.valley_face_pairs; this.valley_face_height_pairs = _cmesh.valley_face_height_pairs; this.length_of_valley_diagonal_edges = _cmesh.length_of_valley_diagonal_edges; }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { // 値をセットするごとに public member をリフレッシュ goal_plane = new Plane(); anchor_vertex_ids = new List <int>(); CMesh cm = null; strength = 1.0; // 値をセット if (!DA.GetData(0, ref cm)) { return; } if (!DA.GetData(1, ref goal_plane)) { return; } if (!DA.GetDataList(2, anchor_vertex_ids)) { return; } DA.GetData(3, ref strength); int edge_count = cm.mesh.TopologyEdges.Count; for (int i = 0; i < edge_count; i++) { edge_avarage_length += cm.mesh.TopologyEdges.EdgeLine(i).Length; } edge_avarage_length /= edge_count; DA.SetData(0, this); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { CMesh cm = null; anchors_index = new List <int>(); strength = 1.0; if (!DA.GetData(0, ref cm)) { return; } if (!DA.GetDataList(1, anchors_index)) { return; } DA.GetData(2, ref strength); int edge_count = cm.mesh.TopologyEdges.Count; for (int i = 0; i < edge_count; i++) { edge_avarage_length += cm.mesh.TopologyEdges.EdgeLine(i).Length; } edge_avarage_length /= edge_count; DA.SetData(0, this); }
public override CRS Jacobian(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> var = new List <double>(); List <int> r_index = new List <int>(); List <int> c_index = new List <int>(); for (int i = 0; i < anchor_vertex_ids.Count; i++) { Point3d pt_on_plane = goal_plane.ClosestPoint(verts[anchor_vertex_ids[i]]); for (int j = 0; j < 3; j++) { var.Add(strength * (verts[anchor_vertex_ids[i]][j] - pt_on_plane[j]) / (edge_avarage_length * edge_avarage_length)); r_index.Add(i); c_index.Add(3 * anchor_vertex_ids[i] + j); } } CRS Jaco = new CRS(var, r_index, c_index, anchor_vertex_ids.Count, verts.Count * 3); return(Jaco); }
public override CRS Jacobian(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); Mesh m = cm.mesh; List <double> var = new List <double>(); List <int> r_index = new List <int>(); List <int> c_index = new List <int>(); for (int i = 0; i < this.glue_vertices_index.Count - 1; i++) { Point3d pti = m.Vertices[this.glue_vertices_index[i]]; Point3d pti1 = m.Vertices[this.glue_vertices_index[i + 1]]; for (int j = 0; j < 3; j++) { var.Add((pti[j] - pti1[j]) / (edge_avarage_length * edge_avarage_length)); r_index.Add(i); c_index.Add(3 * this.glue_vertices_index[i] + j); var.Add((pti1[j] - pti[j]) / (edge_avarage_length * edge_avarage_length)); r_index.Add(i); c_index.Add(3 * this.glue_vertices_index[i + 1] + j); } } CRS Jaco = new CRS(var, r_index, c_index, this.glue_vertices_index.Count - 1, verts.Count * 3); return(Jaco); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { // 値をセットするごとに public member をリフレッシュ equal_edge_ids = new List <int>(); is_set_length = false; CMesh cmesh = null; if (!DA.GetData(0, ref cmesh)) { return; } if (!DA.GetDataList(1, equal_edge_ids)) { return; } is_set_length = DA.GetData(2, ref edge_length); int edge_count = cmesh.mesh.TopologyEdges.Count; for (int i = 0; i < edge_count; i++) { edge_avarage_length += cmesh.mesh.TopologyEdges.EdgeLine(i).Length; } edge_avarage_length /= edge_count; DA.SetData(0, this); }
public override CRS Jacobian(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> var = new List <double>(); List <int> r_index = new List <int>(); List <int> c_index = new List <int>(); for (int i = 0; i < anchors_index.Count; i++) { double parm; anchor_curve.ClosestPoint(verts[anchors_index[i]], out parm); Point3d pt_on_curve = anchor_curve.PointAt(parm); for (int j = 0; j < 3; j++) { var.Add(strength * (verts[anchors_index[i]][j] - pt_on_curve[j]) / (edge_avarage_length * edge_avarage_length)); r_index.Add(i); c_index.Add(3 * anchors_index[i] + j); } } CRS Jaco = new CRS(var, r_index, c_index, anchors_index.Count, verts.Count * 3); return(Jaco); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { // 値をセットする毎に public member をリフレッシュ glue_vertices_index = new List <int>(); edge_avarage_length = 0; CMesh cmesh = null; if (!DA.GetData(0, ref cmesh)) { return; } if (!DA.GetDataList(1, glue_vertices_index)) { return; } int edge_count = cmesh.mesh.TopologyEdges.Count; for (int i = 0; i < edge_count; i++) { edge_avarage_length += cmesh.mesh.TopologyEdges.EdgeLine(i).Length; } edge_avarage_length /= edge_count; DA.SetData(0, this); }
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; }
private Mesh ReconstructQuadMesh(CMesh cm) { var faces = cm.orig_faces; Mesh mesh = cm.mesh.DuplicateMesh(); mesh.Faces.Destroy(); mesh.Faces.AddFaces(faces); return(mesh); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from input parameters and /// to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { CMesh cmesh = null; if (!DA.GetData(0, ref cmesh)) { return; } Mesh mesh = ReconstructQuadMesh(cmesh); var edges = cmesh.mesh.TopologyEdges; List <Line> m = new List <Line>(); List <Line> v = new List <Line>(); List <Line> b = new List <Line>(); List <Line> u = new List <Line>(); List <Line> t = new List <Line>(); List <Line> e = new List <Line>(); for (int i = 0; i < edges.Count; i++) { int info = cmesh.edgeInfo[i]; if (info == 'M') { m.Add(edges.EdgeLine(i)); } else if (info == 'V') { v.Add(edges.EdgeLine(i)); } else if (info == 'U') { u.Add(edges.EdgeLine(i)); } else if (info == 'B') { b.Add(edges.EdgeLine(i)); } else if (info == 'T') { t.Add(edges.EdgeLine(i)); } e.Add(edges.EdgeLine(i)); } DA.SetData(0, mesh); DA.SetDataList(1, m); DA.SetDataList(2, v); DA.SetDataList(3, b); DA.SetDataList(4, u); DA.SetDataList(5, t); DA.SetDataList(6, e); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; List <Char> edgeinfo = new List <Char>(); if (!DA.GetData(0, ref mesh)) { return; } DA.GetDataList(1, edgeinfo); CMesh cmesh = new CMesh(mesh, edgeinfo); DA.SetData(0, cmesh); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; if (!DA.GetData(0, ref mesh)) { return; } mesh.Vertices.CombineIdentical(true, true); CMesh cmesh = new CMesh(mesh); DA.SetData(0, cmesh); }
public override Vec Error(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> err = new List <double>(); for (int i = 0; i < glue_vertices_index.Count - 1; i++) { double dist = verts[glue_vertices_index[i]].DistanceToSquared(verts[glue_vertices_index[i + 1]]); err.Add(dist / (2 * edge_avarage_length * edge_avarage_length)); } Vec ans = new Vec(err); return(ans); }
public override Vec Error(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> err = new List <double>(); foreach (int i in this.anchors_index) { double dist = verts[i].DistanceToSquared(anchors_position[i]); err.Add(strength * dist / (2 * edge_avarage_length * edge_avarage_length)); } Vec ans = new Vec(err); return(ans); }
public override Vec Error(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> err = new List <double>(); foreach (int i in anchor_vertex_ids) { double dist = goal_plane.DistanceTo(verts[i]); err.Add(strength * dist * dist / (2 * edge_avarage_length * edge_avarage_length)); } Vec ans = new Vec(err); return(ans); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; List <Line> m = new List <Line>(); List <Line> v = new List <Line>(); if (!DA.GetData(0, ref mesh)) { return; } DA.GetDataList(1, m); DA.GetDataList(2, v); CMesh cmesh = new CMesh(mesh, m, v); DA.SetData(0, cmesh); }
public override Vec Error(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> err = new List <double>(); foreach (int i in this.anchors_index) { double z = verts[i].Z; err.Add(z * z / (strength * 2 * edge_avarage_length * edge_avarage_length)); } Vec ans = new Vec(err); return(ans); }
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 override CRS Jacobian(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> var = new List <double>(); List <int> r_index = new List <int>(); List <int> c_index = new List <int>(); for (int i = 0; i < this.anchors_index.Count; i++) { double z = verts[anchors_index[i]].Z; var.Add(z / (strength * edge_avarage_length * edge_avarage_length)); r_index.Add(i); c_index.Add(3 * this.anchors_index[i] + 2); } CRS Jaco = new CRS(var, r_index, c_index, this.anchors_index.Count, verts.Count * 3); return(Jaco); }
public override Vec Error(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> err = new List <double>(); foreach (int i in anchors_index) { double parm; anchor_curve.ClosestPoint(verts[i], out parm); double dist = anchor_curve.PointAt(parm).DistanceTo(verts[i]); err.Add(strength * dist * dist / (2 * edge_avarage_length * edge_avarage_length)); } Vec ans = new Vec(err); return(ans); }
public override Vec Error(CMesh cm) { List <Point3d> verts = new List <Point3d>(cm.mesh.Vertices.ToPoint3dArray()); List <double> err = new List <double>(); foreach (int i in anchor_vertex_ids) { double u = 0; double v = 0; goal_surface.ClosestPoint(verts[i], out u, out v); Point3d pt_on_surface = goal_surface.PointAt(u, v); double dist = pt_on_surface.DistanceTo(verts[i]); err.Add(strength * dist * dist / (2 * edge_avarage_length * edge_avarage_length)); } Vec ans = new Vec(err); return(ans); }
public abstract CRS Jacobian(CMesh cm);
/// <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 abstract Vec Error(CMesh cm);
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; //位置ベクトル取得 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 += Vector3d.VectorAngle(vecs[n - 1], vecs[0]); } else { sum += Vector3d.VectorAngle(vecs[i - 1], vecs[i]); } } sum -= 2 * Math.PI; err.Add((double)sum); } Vec ans = new Vec(err); return(ans); }
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>(); 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>(); List <Vector3d> normals = new List <Vector3d>(); int n = index_neighbors.Count; //位置ベクトル取得 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++) { Vector3d temp = new Vector3d(); if (i == 0) { temp = Vector3d.CrossProduct(vecs[n - 1], vecs[0]); } else { temp = Vector3d.CrossProduct(vecs[i - 1], vecs[i]); } temp.Unitize(); normals.Add(temp); } Vector3d v_center = new Vector3d(); for (int i = 0; i < n; i++) { int index = index_neighbors[i]; Vector3d v1 = Vector3d.CrossProduct(normals[i], vecs[i]); v1 *= 1 / vecs[i].SquareLength; Vector3d v2 = Vector3d.CrossProduct(normals[(i + 1) % n], vecs[i]); v2 *= 1 / vecs[i].SquareLength; v1 -= v2; v_center -= v1; var.Add((double)v1.X); var.Add((double)v1.Y); var.Add((double)v1.Z); c_index.Add(index * 3); c_index.Add(index * 3 + 1); c_index.Add(index * 3 + 2); r_index.Add(r); r_index.Add(r); r_index.Add(r); } var.Add((double)v_center.X); var.Add((double)v_center.Y); var.Add((double)v_center.Z); c_index.Add(index_center * 3); c_index.Add(index_center * 3 + 1); c_index.Add(index_center * 3 + 2); r_index.Add(r); r_index.Add(r); r_index.Add(r); } CRS Jaco = new CRS(var, r_index, c_index, internalVertices.Count, topo.Count * 3); return(Jaco); }