335 assert(M.vertices.dimension() == 3);
338 const int nv = M.vertices.nb();
341 for (
int i = 0; i < nv; ++i)
352 if (M.cells.nb() == 0)
355 bool last_isolated =
true;
359 for (
int i = 0; i < (int)M.facets.nb(); ++i)
364 face.
vs.resize(M.facets.nb_vertices(i));
365 for (
int j = 0; j < (int)M.facets.nb_vertices(i); ++j)
367 face.
vs[j] = M.facets.vertex(i, j);
368 if ((
int)face.
vs[j] == nv - 1)
370 last_isolated =
false;
377 for (
int i = 0; i < 1; ++i)
382 int nf = M.facets.nb();
385 for (
int j = 0; j < nf; ++j)
390 for (
auto fid : cell.
fs)
394 sort(cell.
vs.begin(), cell.
vs.end());
395 cell.
vs.erase(unique(cell.
vs.begin(), cell.
vs.end()), cell.
vs.end());
397 for (
int j = 0; j < nf; ++j)
404 cell.
v_in_Kernel.push_back(M.vertices.point(nv - 1)[0]);
405 cell.
v_in_Kernel.push_back(M.vertices.point(nv - 1)[1]);
406 cell.
v_in_Kernel.push_back(M.vertices.point(nv - 1)[2]);
411 Eigen::RowVector3d p(0, 0, 0);
412 for (
int v : cell.
vs)
423 for (
int i = 0; i < 1; ++i)
447 auto opposite_cell_facet = [&M](
int c,
int cf) {
448 GEO::index_t c2 = M.cell_facets.adjacent_cell(cf);
449 if (c2 == GEO::NO_FACET)
453 for (
int lf = 0; lf < (int)M.cells.nb_facets(c2); ++lf)
455 if (c == (
int)M.cells.adjacent(c2, lf))
457 return (
int)M.cells.facet(c2, lf);
464 std::vector<int> cell_facet_to_facet(M.cell_facets.nb(), -1);
467 int facet_counter = 0;
470 for (
int c = 0; c < (int)M.cells.nb(); ++c)
474 cell.
hex = (M.cells.type(c) == GEO::MESH_HEX);
476 is_hex = is_hex && cell.
hex;
478 int nf = M.cells.nb_facets(c);
481 for (
int lf = 0; lf < nf; ++lf)
483 int cf = M.cells.facet(c, lf);
484 int cf2 = opposite_cell_facet(c, cf);
485 if (cf2 < 0 || cell_facet_to_facet[cf2] < 0)
489 assert(face.
vs.empty());
490 face.
vs.resize(M.cells.facet_nb_vertices(c, lf));
491 for (
int lv = 0; lv < (int)M.cells.facet_nb_vertices(c, lf); ++lv)
493 face.
vs[lv] = M.cells.facet_vertex(c, lf, lv);
496 cell.
fs[lf] = face.
id = facet_counter;
497 cell_facet_to_facet[cf] = facet_counter;
502 cell.
fs[lf] = cell_facet_to_facet[cf2];
507 for (
auto fid : cell.
fs)
511 sort(cell.
vs.begin(), cell.
vs.end());
512 cell.
vs.erase(unique(cell.
vs.begin(), cell.
vs.end()), cell.
vs.end());
515 Eigen::RowVector3d p(0, 0, 0);
516 for (
int v : cell.
vs)
591 assert(
F.cols() == 4 ||
F.cols() == 5 ||
F.cols() == 6 ||
F.cols() == 8);
597 M.vertices.create_vertices((
int)
V.rows());
598 for (
int i = 0; i < (int)M.vertices.nb(); ++i)
600 GEO::vec3 &p = M.vertices.point(i);
606 static const std::vector<int> permute_tet = {0, 1, 2, 3};
607 static const std::vector<int> permute_pyramid = {0, 1, 2, 3, 4};
608 static const std::vector<int> permute_prism = {0, 1, 2, 3, 4, 5};
610 static const std::vector<int> permute_hex = {1, 0, 2, 3, 5, 4, 6, 7};
612 auto add_cell = [&](
int c, GEO::MeshCellType t,
int nv,
const std::vector<int> &perm) {
613 GEO::index_t cid = M.cells.create_cells(1, t);
614 for (
int lv = 0; lv < nv; ++lv)
616 int vi =
F(c, perm[lv]);
617 assert(vi >= 0 && vi <
V.rows());
618 M.cells.set_vertex(cid, lv, GEO::index_t(vi));
622 for (
int c = 0; c <
F.rows(); ++c)
625 for (nV = 0; nV <
F.cols(); ++nV)
632 for (
int k = nV; k <
F.cols(); ++k)
634 assert(
F(c, k) == -1);
638 add_cell(c, GEO::MESH_TET, 4, permute_tet);
640 add_cell(c, GEO::MESH_PYRAMID, 5, permute_pyramid);
642 add_cell(c, GEO::MESH_PRISM, 6, permute_prism);
644 add_cell(c, GEO::MESH_HEX, 8, permute_hex);
665 const auto attach_p2 = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
668 if (n.nodes.size() > 0)
674 const int n_v1 = index.
vertex;
679 if ((n_v1 == nodes_ids[0] && n_v2 == nodes_ids[1]) || (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[1]))
681 else if ((n_v1 == nodes_ids[1] && n_v2 == nodes_ids[2]) || (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[2]))
683 else if ((n_v1 == nodes_ids[2] && n_v2 == nodes_ids[3]) || (n_v2 == nodes_ids[2] && n_v1 == nodes_ids[3]))
686 else if ((n_v1 == nodes_ids[0] && n_v2 == nodes_ids[3]) || (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[3]))
688 else if ((n_v1 == nodes_ids[0] && n_v2 == nodes_ids[2]) || (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[2]))
693 n.nodes.resize(1, 3);
694 n.nodes <<
V(nodes_ids[node_index], 0),
V(nodes_ids[node_index], 1),
V(nodes_ids[node_index], 2);
695 n.nodes_ids.push_back(nodes_ids[node_index]);
698 const auto attach_p3 = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
701 if (n.nodes.size() > 0)
707 const int n_v1 = index.
vertex;
712 if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[1])
717 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[1])
722 else if (n_v1 == nodes_ids[1] && n_v2 == nodes_ids[2])
727 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[2])
732 else if (n_v1 == nodes_ids[2] && n_v2 == nodes_ids[3])
737 else if (n_v2 == nodes_ids[2] && n_v1 == nodes_ids[3])
743 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[3])
748 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[3])
753 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[2])
758 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[2])
764 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[3])
775 n.nodes.resize(2, 3);
776 n.nodes.row(0) <<
V(nodes_ids[node_index1], 0),
V(nodes_ids[node_index1], 1),
V(nodes_ids[node_index1], 2);
777 n.nodes.row(1) <<
V(nodes_ids[node_index2], 0),
V(nodes_ids[node_index2], 1),
V(nodes_ids[node_index2], 2);
778 n.nodes_ids.push_back(nodes_ids[node_index1]);
779 n.nodes_ids.push_back(nodes_ids[node_index2]);
782 const auto attach_p3_face = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids,
int id) {
784 if (n.nodes.size() <= 0)
789 n.nodes.resize(1, 3);
790 n.nodes <<
V(nodes_ids[
id], 0),
V(nodes_ids[
id], 1),
V(nodes_ids[
id], 2);
791 n.nodes_ids.push_back(nodes_ids[
id]);
795 const auto attach_p4 = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
798 if (n.nodes.size() > 0)
804 const int n_v1 = index.
vertex;
810 if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[1])
816 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[1])
823 else if (n_v1 == nodes_ids[1] && n_v2 == nodes_ids[2])
829 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[2])
836 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[2])
842 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[2])
849 else if (n_v2 == nodes_ids[0] && n_v1 == nodes_ids[3])
855 else if (n_v1 == nodes_ids[0] && n_v2 == nodes_ids[3])
862 else if (n_v2 == nodes_ids[2] && n_v1 == nodes_ids[3])
868 else if (n_v1 == nodes_ids[2] && n_v2 == nodes_ids[3])
875 else if (n_v2 == nodes_ids[1] && n_v1 == nodes_ids[3])
881 else if (n_v1 == nodes_ids[1] && n_v2 == nodes_ids[3])
892 n.nodes.resize(3, 3);
893 n.nodes.row(0) <<
V(nodes_ids[node_index1], 0),
V(nodes_ids[node_index1], 1),
V(nodes_ids[node_index1], 2);
894 n.nodes.row(1) <<
V(nodes_ids[node_index2], 0),
V(nodes_ids[node_index2], 1),
V(nodes_ids[node_index2], 2);
895 n.nodes.row(2) <<
V(nodes_ids[node_index3], 0),
V(nodes_ids[node_index3], 1),
V(nodes_ids[node_index3], 2);
896 n.nodes_ids.push_back(nodes_ids[node_index1]);
897 n.nodes_ids.push_back(nodes_ids[node_index2]);
898 n.nodes_ids.push_back(nodes_ids[node_index3]);
901 const auto attach_p4_face = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
903 if (n.nodes.size() <= 0)
909 std::array<int, 3> vid = {{n.v1, n.v2, n.v3}};
910 std::sort(vid.begin(), vid.end());
912 std::array<int, 3> c1 = {{nodes_ids[0], nodes_ids[1], nodes_ids[2]}};
913 std::array<int, 3> c2 = {{nodes_ids[0], nodes_ids[1], nodes_ids[3]}};
914 std::array<int, 3> c3 = {{nodes_ids[0], nodes_ids[2], nodes_ids[3]}};
915 std::array<int, 3> c4 = {{nodes_ids[1], nodes_ids[2], nodes_ids[3]}};
917 std::sort(c1.begin(), c1.end());
918 std::sort(c2.begin(), c2.end());
919 std::sort(c3.begin(), c3.end());
920 std::sort(c4.begin(), c4.end());
976 n.nodes.resize(3, 3);
977 assert(
id + index0 < nodes_ids.size());
978 assert(
id + index1 < nodes_ids.size());
979 assert(
id + index2 < nodes_ids.size());
980 n.nodes.row(0) <<
V(nodes_ids[
id + index0], 0),
V(nodes_ids[
id + index0], 1),
V(nodes_ids[
id + index0], 2);
981 n.nodes.row(1) <<
V(nodes_ids[
id + index1], 0),
V(nodes_ids[
id + index1], 1),
V(nodes_ids[
id + index1], 2);
982 n.nodes.row(2) <<
V(nodes_ids[
id + index2], 0),
V(nodes_ids[
id + index2], 1),
V(nodes_ids[
id + index2], 2);
983 n.nodes_ids.push_back(nodes_ids[
id + index0]);
984 n.nodes_ids.push_back(nodes_ids[
id + index1]);
985 n.nodes_ids.push_back(nodes_ids[
id + index2]);
989 const auto attach_p4_cell = [&](
const Navigation3D::Index &index,
const std::vector<int> &nodes_ids) {
991 assert(nodes_ids.size() == 35);
992 assert(n.nodes.size() == 0);
994 if (n.nodes.size() <= 0)
1000 n.nodes.resize(1, 3);
1002 n.nodes <<
V(nodes_ids[34], 0),
V(nodes_ids[34], 1),
V(nodes_ids[34], 2);
1003 n.nodes_ids.push_back(nodes_ids[34]);
1007 assert(nodes.size() ==
n_cells());
1009 for (
int c = 0; c <
n_cells(); ++c)
1013 const auto &nodes_ids = nodes[c];
1015 if (nodes_ids.size() == 4)
1021 else if (nodes_ids.size() == 10)
1025 for (
int le = 0; le < 3; ++le)
1027 attach_p2(index, nodes_ids);
1032 attach_p2(index, nodes_ids);
1035 attach_p2(index, nodes_ids);
1038 attach_p2(index, nodes_ids);
1041 else if (nodes_ids.size() == 20)
1045 for (
int le = 0; le < 3; ++le)
1047 attach_p3(index, nodes_ids);
1053 attach_p3(index, nodes_ids);
1056 attach_p3(index, nodes_ids);
1059 attach_p3(index, nodes_ids);
1064 std::array<int, 4> indices;
1067 std::array<int, 3> f16 = {{nodes_ids[0], nodes_ids[1], nodes_ids[2]}};
1068 std::array<int, 3> f17 = {{nodes_ids[3], nodes_ids[1], nodes_ids[0]}};
1069 std::array<int, 3> f18 = {{nodes_ids[0], nodes_ids[2], nodes_ids[3]}};
1070 std::array<int, 3> f19 = {{nodes_ids[1], nodes_ids[2], nodes_ids[3]}};
1071 std::sort(f16.begin(), f16.end());
1072 std::sort(f17.begin(), f17.end());
1073 std::sort(f18.begin(), f18.end());
1074 std::sort(f19.begin(), f19.end());
1085 std::sort(f0.begin(), f0.end());
1086 std::sort(f1.begin(), f1.end());
1087 std::sort(f2.begin(), f2.end());
1088 std::sort(f3.begin(), f3.end());
1090 const std::array<std::array<int, 3>, 4>
faces = {{f0, f1, f2, f3}};
1091 const std::array<std::array<int, 3>, 4> nodes = {{f16, f17, f18, f19}};
1092 for (
int i = 0; i < 4; ++i)
1094 const auto &f =
faces[i];
1096 for (
int j = 0; j < 4; ++j)
1100 indices[i] = j + 16;
1110 attach_p3_face(index, nodes_ids, indices[0]);
1111 attach_p3_face(
switch_face(index), nodes_ids, indices[1]);
1117 else if (nodes_ids.size() == 35)
1120 for (
int le = 0; le < 3; ++le)
1122 attach_p4(index, nodes_ids);
1128 attach_p4(index, nodes_ids);
1131 attach_p4(index, nodes_ids);
1134 attach_p4(index, nodes_ids);
1140 attach_p4_face(index, nodes_ids);