210 assert(M.vertices.dimension() == 3);
213 const int nv = M.vertices.nb();
216 for (
int i = 0; i < nv; ++i)
227 if (M.cells.nb() == 0)
230 bool last_isolated =
true;
234 for (
int i = 0; i < (int)M.facets.nb(); ++i)
239 face.
vs.resize(M.facets.nb_vertices(i));
240 for (
int j = 0; j < (int)M.facets.nb_vertices(i); ++j)
242 face.
vs[j] = M.facets.vertex(i, j);
243 if ((
int)face.
vs[j] == nv - 1)
245 last_isolated =
false;
252 for (
int i = 0; i < 1; ++i)
257 int nf = M.facets.nb();
260 for (
int j = 0; j < nf; ++j)
265 for (
auto fid : cell.
fs)
269 sort(cell.
vs.begin(), cell.
vs.end());
270 cell.
vs.erase(unique(cell.
vs.begin(), cell.
vs.end()), cell.
vs.end());
272 for (
int j = 0; j < nf; ++j)
279 cell.
v_in_Kernel.push_back(M.vertices.point(nv - 1)[0]);
280 cell.
v_in_Kernel.push_back(M.vertices.point(nv - 1)[1]);
281 cell.
v_in_Kernel.push_back(M.vertices.point(nv - 1)[2]);
286 Eigen::RowVector3d p(0, 0, 0);
287 for (
int v : cell.
vs)
298 for (
int i = 0; i < 1; ++i)
322 auto opposite_cell_facet = [&M](
int c,
int cf) {
323 GEO::index_t c2 = M.cell_facets.adjacent_cell(cf);
324 if (c2 == GEO::NO_FACET)
328 for (
int lf = 0; lf < (int)M.cells.nb_facets(c2); ++lf)
332 if (c == (
int)M.cells.adjacent(c2, lf))
334 return (
int)M.cells.facet(c2, lf);
341 std::vector<int> cell_facet_to_facet(M.cell_facets.nb(), -1);
344 int facet_counter = 0;
347 for (
int c = 0; c < (int)M.cells.nb(); ++c)
351 cell.
hex = (M.cells.type(c) == GEO::MESH_HEX);
353 is_hex = is_hex && cell.
hex;
355 int nf = M.cells.nb_facets(c);
358 for (
int lf = 0; lf < nf; ++lf)
360 int cf = M.cells.facet(c, lf);
361 int cf2 = opposite_cell_facet(c, cf);
364 if (cf2 < 0 || cell_facet_to_facet[cf2] < 0)
369 assert(face.
vs.empty());
370 face.
vs.resize(M.cells.facet_nb_vertices(c, lf));
371 for (
int lv = 0; lv < (int)M.cells.facet_nb_vertices(c, lf); ++lv)
373 face.
vs[lv] = M.cells.facet_vertex(c, lf, lv);
376 cell.
fs[lf] = face.
id = facet_counter;
377 cell_facet_to_facet[cf] = facet_counter;
382 cell.
fs[lf] = cell_facet_to_facet[cf2];
387 for (
auto fid : cell.
fs)
391 sort(cell.
vs.begin(), cell.
vs.end());
392 cell.
vs.erase(unique(cell.
vs.begin(), cell.
vs.end()), cell.
vs.end());
395 Eigen::RowVector3d p(0, 0, 0);
396 for (
int v : cell.
vs)
524 const auto attach_p2 = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
527 if (n.nodes.size() > 0)
533 const int n_v1 = index.
vertex;
538 if ((n_v1 == nodes_ids[0] && n_v2 == nodes_ids[1]) || (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[1]))
540 else if ((n_v1 == nodes_ids[1] && n_v2 == nodes_ids[2]) || (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[2]))
542 else if ((n_v1 == nodes_ids[2] && n_v2 == nodes_ids[3]) || (n_v2 == nodes_ids[2] && n_v1 == nodes_ids[3]))
545 else if ((n_v1 == nodes_ids[0] && n_v2 == nodes_ids[3]) || (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[3]))
547 else if ((n_v1 == nodes_ids[0] && n_v2 == nodes_ids[2]) || (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[2]))
552 n.nodes.resize(1, 3);
553 n.nodes <<
V(nodes_ids[node_index], 0),
V(nodes_ids[node_index], 1),
V(nodes_ids[node_index], 2);
556 const auto attach_p3 = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
559 if (n.nodes.size() > 0)
565 const int n_v1 = index.
vertex;
570 if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[1])
575 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[1])
580 else if (n_v1 == nodes_ids[1] && n_v2 == nodes_ids[2])
585 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[2])
590 else if (n_v1 == nodes_ids[2] && n_v2 == nodes_ids[3])
595 else if (n_v2 == nodes_ids[2] && n_v1 == nodes_ids[3])
601 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[3])
606 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[3])
611 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[2])
616 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[2])
622 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[3])
633 n.nodes.resize(2, 3);
634 n.nodes.row(0) <<
V(nodes_ids[node_index1], 0),
V(nodes_ids[node_index1], 1),
V(nodes_ids[node_index1], 2);
635 n.nodes.row(1) <<
V(nodes_ids[node_index2], 0),
V(nodes_ids[node_index2], 1),
V(nodes_ids[node_index2], 2);
638 const auto attach_p3_face = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids,
int id) {
640 if (n.nodes.size() <= 0)
645 n.nodes.resize(1, 3);
646 n.nodes <<
V(nodes_ids[
id], 0),
V(nodes_ids[
id], 1),
V(nodes_ids[
id], 2);
650 const auto attach_p4 = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
653 if (n.nodes.size() > 0)
659 const int n_v1 = index.
vertex;
665 if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[1])
671 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[1])
678 else if (n_v1 == nodes_ids[1] && n_v2 == nodes_ids[2])
684 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[2])
691 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[2])
697 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[2])
704 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[3])
710 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[3])
717 else if (n_v2 == nodes_ids[2] && n_v1 == nodes_ids[3])
723 else if (n_v1 == nodes_ids[2] && n_v2 == nodes_ids[3])
730 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[3])
736 else if (n_v1 == nodes_ids[1] && n_v2 == nodes_ids[3])
747 n.nodes.resize(3, 3);
748 n.nodes.row(0) <<
V(nodes_ids[node_index1], 0),
V(nodes_ids[node_index1], 1),
V(nodes_ids[node_index1], 2);
749 n.nodes.row(1) <<
V(nodes_ids[node_index2], 0),
V(nodes_ids[node_index2], 1),
V(nodes_ids[node_index2], 2);
750 n.nodes.row(2) <<
V(nodes_ids[node_index3], 0),
V(nodes_ids[node_index3], 1),
V(nodes_ids[node_index3], 2);
753 const auto attach_p4_face = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
755 if (n.nodes.size() <= 0)
761 std::array<int, 3> vid = {{n.v1, n.v2, n.v3}};
762 std::sort(vid.begin(), vid.end());
764 std::array<int, 3> c1 = {{nodes_ids[0], nodes_ids[1], nodes_ids[2]}};
765 std::array<int, 3> c2 = {{nodes_ids[0], nodes_ids[1], nodes_ids[3]}};
766 std::array<int, 3> c3 = {{nodes_ids[0], nodes_ids[2], nodes_ids[3]}};
767 std::array<int, 3> c4 = {{nodes_ids[1], nodes_ids[2], nodes_ids[3]}};
769 std::sort(c1.begin(), c1.end());
770 std::sort(c2.begin(), c2.end());
771 std::sort(c3.begin(), c3.end());
772 std::sort(c4.begin(), c4.end());
828 n.nodes.resize(3, 3);
829 assert(
id + index0 < nodes_ids.size());
830 assert(
id + index1 < nodes_ids.size());
831 assert(
id + index2 < nodes_ids.size());
832 n.nodes.row(0) <<
V(nodes_ids[
id + index0], 0),
V(nodes_ids[
id + index0], 1),
V(nodes_ids[
id + index0], 2);
833 n.nodes.row(1) <<
V(nodes_ids[
id + index1], 0),
V(nodes_ids[
id + index1], 1),
V(nodes_ids[
id + index1], 2);
834 n.nodes.row(2) <<
V(nodes_ids[
id + index2], 0),
V(nodes_ids[
id + index2], 1),
V(nodes_ids[
id + index2], 2);
838 const auto attach_p4_cell = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
840 assert(nodes_ids.size() == 35);
841 assert(n.nodes.size() == 0);
843 if (n.nodes.size() <= 0)
849 n.nodes.resize(1, 3);
851 n.nodes <<
V(nodes_ids[34], 0),
V(nodes_ids[34], 1),
V(nodes_ids[34], 2);
855 assert(nodes.size() ==
n_cells());
857 for (
int c = 0; c <
n_cells(); ++c)
861 const auto &nodes_ids = nodes[c];
863 if (nodes_ids.size() == 4)
869 else if (nodes_ids.size() == 10)
873 for (
int le = 0; le < 3; ++le)
875 attach_p2(index, nodes_ids);
880 attach_p2(index, nodes_ids);
883 attach_p2(index, nodes_ids);
886 attach_p2(index, nodes_ids);
889 else if (nodes_ids.size() == 20)
893 for (
int le = 0; le < 3; ++le)
895 attach_p3(index, nodes_ids);
901 attach_p3(index, nodes_ids);
904 attach_p3(index, nodes_ids);
907 attach_p3(index, nodes_ids);
912 std::array<int, 4> indices;
915 std::array<int, 3> f16 = {{nodes_ids[0], nodes_ids[1], nodes_ids[2]}};
916 std::array<int, 3> f17 = {{nodes_ids[3], nodes_ids[1], nodes_ids[0]}};
917 std::array<int, 3> f18 = {{nodes_ids[0], nodes_ids[2], nodes_ids[3]}};
918 std::array<int, 3> f19 = {{nodes_ids[1], nodes_ids[2], nodes_ids[3]}};
919 std::sort(f16.begin(), f16.end());
920 std::sort(f17.begin(), f17.end());
921 std::sort(f18.begin(), f18.end());
922 std::sort(f19.begin(), f19.end());
933 std::sort(f0.begin(), f0.end());
934 std::sort(f1.begin(), f1.end());
935 std::sort(f2.begin(), f2.end());
936 std::sort(f3.begin(), f3.end());
938 const std::array<std::array<int, 3>, 4>
faces = {{f0, f1, f2, f3}};
939 const std::array<std::array<int, 3>, 4> nodes = {{f16, f17, f18, f19}};
940 for (
int i = 0; i < 4; ++i)
942 const auto &f =
faces[i];
944 for (
int j = 0; j < 4; ++j)
958 attach_p3_face(index, nodes_ids, indices[0]);
959 attach_p3_face(
switch_face(index), nodes_ids, indices[1]);
965 else if (nodes_ids.size() == 35)
968 for (
int le = 0; le < 3; ++le)
970 attach_p4(index, nodes_ids);
976 attach_p4(index, nodes_ids);
979 attach_p4(index, nodes_ids);
982 attach_p4(index, nodes_ids);
988 attach_p4_face(index, nodes_ids);
1075 std::vector<Eigen::MatrixXi> local_tris(
mesh_.
elements.size());
1076 std::vector<Eigen::MatrixXd> local_pts(
mesh_.
elements.size());
1077 Eigen::MatrixXi tets;
1082 ranges.push_back(0);
1084 Eigen::MatrixXd face_barys;
1087 Eigen::MatrixXd cell_barys;
1099 std::map<int, int> global_to_local;
1103 const int global_index = el.
vs[i];
1104 local_pt.row(i) =
mesh_.
points.col(global_index).transpose();
1105 global_to_local[global_index] = i;
1108 int n_local_faces = 0;
1109 for (
int i = 0; i <
n_faces; ++i)
1112 n_local_faces += f.vs.size();
1114 local_pt.row(
n_vertices + i) = face_barys.row(f.id);
1117 Eigen::MatrixXi local_faces(n_local_faces, 3);
1120 for (
int i = 0; i <
n_faces; ++i)
1125 const Eigen::RowVector3d e0 = (
point(f.vs[0]) - local_pt.row(
n_vertices + i));
1126 const Eigen::RowVector3d e1 = (
point(f.vs[1]) - local_pt.row(
n_vertices + i));
1127 const Eigen::RowVector3d normal = e0.cross(e1);
1129 const Eigen::RowVector3d check_dir = (cell_barys.row(e) -
point(f.vs[1]));
1131 const bool reverse_order = normal.dot(check_dir) > 0;
1138 local_faces(face_index, 0) = global_to_local[f.vs[jp]];
1139 local_faces(face_index, 1) = global_to_local[f.vs[j]];
1143 local_faces(face_index, 0) = global_to_local[f.vs[j]];
1144 local_faces(face_index, 1) = global_to_local[f.vs[jp]];
1152 local_pts[e] = local_pt;
1153 local_tris[e] = local_faces;
1155 total_tris += local_tris[e].rows();
1156 total_pts += local_pts[e].rows();
1158 ranges.push_back(total_tris);
1160 assert(local_pts[e].rows() == local_pt.rows());
1163 tris.resize(total_tris, 3);
1164 pts.resize(total_pts, 3);
1168 for (std::size_t i = 0; i < local_tris.size(); ++i)
1170 tris.block(tri_index, 0, local_tris[i].rows(), local_tris[i].cols()) = local_tris[i].array() + pts_index;
1171 tri_index += local_tris[i].rows();
1173 pts.block(pts_index, 0, local_pts[i].rows(), local_pts[i].cols()) = local_pts[i];
1174 pts_index += local_pts[i].rows();