244 simplex_ids_to_delete = get_split_simplices_to_delete(m_operating_tuple, m_mesh);
249 assert(new_vids.size() == 1);
250 const int64_t v_new = new_vids[0];
251 m_split_new_vid = v_new;
255 assert(new_eids.size() == 2);
256 std::copy(new_eids.begin(), new_eids.end(), m_split_new_spine_eids.begin());
263 const auto [incident_tets, incident_faces] = get_incident_tets_and_faces(m_operating_tuple);
264 const bool loop_flag = (incident_tets.size() == incident_faces.size());
266 const size_t facet_size = incident_tets.size();
267 std::vector<int64_t> new_facet_ids =
269 assert(new_facet_ids.size() == 2 * facet_size);
270 const size_t face_size = incident_faces.size();
271 std::vector<int64_t> new_face_ids =
273 assert(new_face_ids.size() == 2 * face_size);
276 std::vector<FaceSplitData> new_incident_face_data;
277 for (int64_t i = 0; i < incident_faces.size(); ++i) {
281 fsd.
fid_old = m_mesh.id_face(incident_faces[i]);
283 new_face_ids.begin() + 2 * i,
284 new_face_ids.begin() + 2 * (i + 1),
289 fsd.
eid_rib = splitting_eids[0];
291 new_incident_face_data.emplace_back(fsd);
295 int64_t incident_face_cnt = new_incident_face_data.size();
298 m_incident_tet_datas.clear();
299 for (int64_t i = 0; i < incident_tets.size(); ++i) {
304 tsd.
tid = m_mesh.id_tet(incident_tets[i]);
306 new_facet_ids.begin() + 2 * i,
307 new_facet_ids.begin() + 2 * (i + 1),
309 tsd.
rib_f = split_fids[0];
312 split_facet_data().add_facet(m_mesh, m_operating_tuple, tsd.
split_t);
315 Tuple ear1 = m_mesh.switch_face(m_mesh.switch_edge(incident_tets[i]));
316 if (!m_mesh.is_boundary_face(ear1)) {
318 tsd.
ears[0] =
EarTet{m_mesh.id_tet(ear1), m_mesh.id_face(ear1)};
320 tsd.
ears[0] =
EarTet{-1, m_mesh.id_face(ear1)};
323 Tuple ear2 = m_mesh.switch_face(m_mesh.switch_edge(m_mesh.switch_vertex(incident_tets[i])));
324 if (!m_mesh.is_boundary_face(ear2)) {
326 tsd.
ears[1] =
EarTet{m_mesh.id_tet(ear2), m_mesh.id_face(ear2)};
328 tsd.
ears[1] =
EarTet{-1, m_mesh.id_face(ear2)};
332 new_incident_face_data[(i + incident_face_cnt - 1) % incident_face_cnt];
341 tsd.
v0 = m_mesh.id_vertex(incident_tets[i]);
342 tsd.
v1 = m_mesh.id_vertex(m_mesh.switch_vertex(incident_tets[i]));
343 tsd.
v2 = m_mesh.id_vertex(m_mesh.switch_vertex(
344 m_mesh.switch_edge(m_mesh.switch_face(incident_tets[i]))));
345 tsd.
v3 = m_mesh.id_vertex(
346 m_mesh.switch_vertex(m_mesh.switch_edge(incident_tets[i])));
348 tsd.
e01 = m_mesh.id_edge(incident_tets[i]);
349 tsd.
e03 = m_mesh.id_edge(m_mesh.switch_edge(incident_tets[i]));
350 tsd.
e13 = m_mesh.id_edge(
351 m_mesh.switch_edge(m_mesh.switch_vertex(incident_tets[i])));
352 tsd.
e02 = m_mesh.id_edge(
353 m_mesh.switch_edge(m_mesh.switch_face(incident_tets[i])));
354 tsd.
e12 = m_mesh.id_edge(m_mesh.switch_edge(
355 m_mesh.switch_face(m_mesh.switch_vertex(incident_tets[i]))));
356 tsd.
e23 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_vertex(
357 m_mesh.switch_face(m_mesh.switch_edge(incident_tets[i])))));
359 m_incident_tet_datas.emplace_back(tsd);
363 m_incident_face_datas.clear();
364 for (int64_t i = 0; i < m_incident_tet_datas.size(); ++i) {
365 auto& data = m_incident_face_datas.emplace_back();
366 data.fid = m_incident_tet_datas[i].new_face_data[1].fid_old;
367 data.ear_eids[0] = m_incident_tet_datas[i].e03;
368 data.ear_eids[1] = m_incident_tet_datas[i].e13;
369 data.new_edge_id = m_incident_tet_datas[i].new_face_data[1].eid_rib;
370 data.split_f[0] = m_incident_tet_datas[i].new_face_data[1].fid_new[0];
371 data.split_f[1] = m_incident_tet_datas[i].new_face_data[1].fid_new[1];
372 data.local_operating_tuple = m_incident_tet_datas[i].new_face_data[1].local_operating_tuple;
376 auto& data = m_incident_face_datas.emplace_back();
377 data.fid = m_incident_tet_datas[0].new_face_data[0].fid_old;
378 data.ear_eids[0] = m_incident_tet_datas[0].e02;
379 data.ear_eids[1] = m_incident_tet_datas[0].e12;
380 data.new_edge_id = m_incident_tet_datas[0].new_face_data[0].eid_rib;
381 data.split_f[0] = m_incident_tet_datas[0].new_face_data[0].fid_new[0];
382 data.split_f[1] = m_incident_tet_datas[0].new_face_data[0].fid_new[1];
383 data.local_operating_tuple = m_incident_tet_datas[0].new_face_data[0].local_operating_tuple;
386 assert(m_incident_face_datas.size() == new_incident_face_data.size());
390 for (int64_t i = 0; i < m_incident_face_datas.size(); ++i) {
391 assert(m_incident_face_datas[i].fid == new_incident_face_data[i].fid_old);
397 int64_t return_local_vid = -1;
398 int64_t return_local_eid = -1;
399 int64_t return_local_fid = -1;
400 int64_t return_tid = -1;
404 int64_t return_fid = -1;
405 int64_t return_split_fid = -1;
409 for (int64_t i = 0; i < m_incident_tet_datas.size(); ++i) {
411 const auto& data = m_incident_tet_datas[i];
412 const int64_t vid_new = v_new;
413 const int64_t v0 = data.v0;
414 const int64_t v1 = data.v1;
415 const int64_t v2 = data.v2;
416 const int64_t v3 = data.v3;
417 const int64_t e_spine_1 = new_eids[0];
418 const int64_t e_spine_2 = new_eids[1];
419 const int64_t e_rib_1 = data.new_face_data[0].eid_rib;
420 const int64_t e_rib_2 = data.new_face_data[1].eid_rib;
421 const int64_t e01 = data.e01;
422 const int64_t e02 = data.e02;
423 const int64_t e12 = data.e12;
424 const int64_t e03 = data.e03;
425 const int64_t e13 = data.e13;
426 const int64_t e23 = data.e23;
427 const int64_t f_ear_1 = data.ears[0].fid;
428 const int64_t f_ear_2 = data.ears[1].fid;
429 const int64_t f1 = data.new_face_data[0].fid_new[0];
430 const int64_t f2 = data.new_face_data[0].fid_new[1];
431 const int64_t f_old_1 = data.new_face_data[0].fid_old;
432 const int64_t f3 = data.new_face_data[1].fid_new[0];
433 const int64_t f4 = data.new_face_data[1].fid_new[1];
434 const int64_t f_old_2 = data.new_face_data[1].fid_old;
435 const int64_t f_rib = data.rib_f;
436 const int64_t t_ear_1 = data.ears[0].tid;
437 const int64_t t_ear_2 = data.ears[1].tid;
438 const int64_t t1 = data.split_t[0];
439 const int64_t t2 = data.split_t[1];
440 const int64_t t_old = data.tid;
508 bool return_flag =
false;
509 if (t_old == m_operating_tet_id) {
512 logger().trace(
"split fid is {}", f_rib);
513 logger().trace(
"fids {} {} are joined by edge {}", f3, f4, e_rib_2);
516 return_split_fid = f_rib;
520 int64_t prev_index = (i - 1 + m_incident_tet_datas.size()) % m_incident_tet_datas.size();
521 int64_t next_index = (i + 1 + m_incident_tet_datas.size()) % m_incident_tet_datas.size();
524 t_f1 = m_incident_tet_datas[prev_index].split_t[0];
525 t_f2 = m_incident_tet_datas[prev_index].split_t[1];
526 t_f3 = m_incident_tet_datas[next_index].split_t[0];
527 t_f4 = m_incident_tet_datas[next_index].split_t[1];
529 if (m_incident_tet_datas.size() == 1) {
540 t_f1 = m_incident_tet_datas[prev_index].split_t[0];
541 t_f2 = m_incident_tet_datas[prev_index].split_t[1];
543 if (i == m_incident_tet_datas.size() - 1) {
548 t_f3 = m_incident_tet_datas[next_index].split_t[0];
549 t_f4 = m_incident_tet_datas[next_index].split_t[1];
557 update_ear_connectivity(t_ear_1, t1, t_old, f_ear_1);
559 auto tt = tt_accessor.vector_attribute(t1);
560 auto tf = tf_accessor.vector_attribute(t1);
561 auto te = te_accessor.vector_attribute(t1);
562 auto tv = tv_accessor.vector_attribute(t1);
578 tt = tt_accessor.vector_attribute(t_old);
579 tf = tf_accessor.vector_attribute(t_old);
580 te = te_accessor.vector_attribute(t_old);
581 tv = tv_accessor.vector_attribute(t_old);
586 for (
int k = 0; k < 4; ++k) {
588 if (tv(k) == m_spine_vids[0]) {
589 return_local_vid = k;
593 if (tf(k) == m_operating_face_id) {
594 return_local_fid = k;
599 for (
int k = 0; k < 6; ++k) {
601 return_local_eid = k;
608 for (
size_t k = 0; k < 4; ++k) {
615 if (tf(k) == f_old_1) {
617 m_incident_tet_datas[i].incident_face_local_fid[0] = k;
622 if (tf(k) == f_old_2) {
624 m_incident_tet_datas[i].incident_face_local_fid[1] = k;
629 if (tf(k) == f_ear_2) {
635 for (
size_t k = 0; k < 6; ++k) {
652 update_ear_connectivity(t_ear_2, t2, t_old, f_ear_2);
654 auto tt = tt_accessor.vector_attribute(t2);
655 auto tf = tf_accessor.vector_attribute(t2);
656 auto te = te_accessor.vector_attribute(t2);
657 auto tv = tv_accessor.vector_attribute(t2);
673 tt = tt_accessor.const_vector_attribute(t_old);
674 tf = tf_accessor.const_vector_attribute(t_old);
675 te = te_accessor.const_vector_attribute(t_old);
676 tv = tv_accessor.const_vector_attribute(t_old);
677 for (
size_t k = 0; k < 4; ++k) {
684 if (tf(k) == f_old_1) {
688 if (tf(k) == f_old_2) {
692 if (tf(k) == f_ear_1) {
698 for (
size_t k = 0; k < 6; ++k) {
713 ft_accessor.scalar_attribute(f_ear_1) = t1;
714 ft_accessor.scalar_attribute(f_ear_2) = t2;
715 ft_accessor.scalar_attribute(f1) = t1;
716 ft_accessor.scalar_attribute(f2) = t2;
717 ft_accessor.scalar_attribute(f3) = t1;
718 ft_accessor.scalar_attribute(f4) = t2;
719 ft_accessor.scalar_attribute(f_rib) = t1;
722 et_accessor.scalar_attribute(e02) = t1;
723 et_accessor.scalar_attribute(e12) = t2;
724 et_accessor.scalar_attribute(e03) = t1;
725 et_accessor.scalar_attribute(e13) = t2;
726 et_accessor.scalar_attribute(e23) = t1;
727 et_accessor.scalar_attribute(e_spine_1) = t1;
728 et_accessor.scalar_attribute(e_spine_2) = t2;
729 et_accessor.scalar_attribute(e_rib_1) = t1;
730 et_accessor.scalar_attribute(e_rib_2) = t1;
733 vt_accessor.scalar_attribute(v0) = t1;
734 vt_accessor.scalar_attribute(v1) = t2;
735 vt_accessor.scalar_attribute(v2) = t1;
736 vt_accessor.scalar_attribute(v3) = t1;
737 vt_accessor.scalar_attribute(vid_new) = t1;
745 assert(return_tid > -1);
746 assert(return_local_vid > -1);
747 assert(return_local_eid > -1);
748 assert(return_local_fid > -1);
750 assert(return_local_vid == m_operating_tuple.local_vid());
751 assert(return_local_eid == m_operating_tuple.local_eid());
752 assert(return_local_fid == m_operating_tuple.local_fid());
753 m_output_tuple =
Tuple(return_local_vid, return_local_eid, return_local_fid, return_tid);
768 assert(!m_mesh.is_boundary_face(m_mesh.switch_tuples(m_output_tuple, {PE, PF})));
775 simplex_ids_to_delete = get_collapse_simplices_to_delete(m_operating_tuple, m_mesh);
793 auto [incident_tets, incident_faces] = get_incident_tets_and_faces(m_operating_tuple);
796 for (
const Tuple& tet : incident_tets) {
799 tcd.
tid = m_mesh.id_tet(tet);
802 Tuple ear1 = m_mesh.switch_face(m_mesh.switch_edge(tet));
803 if (!m_mesh.is_boundary_face(ear1)) {
805 tcd.
ears[0] =
EarTet{m_mesh.id_tet(ear1), m_mesh.id_face(ear1)};
807 tcd.
ears[0] =
EarTet{-1, m_mesh.id_face(ear1)};
810 Tuple ear2 = m_mesh.switch_face(m_mesh.switch_edge(m_mesh.switch_vertex(tet)));
811 if (!m_mesh.is_boundary_face(ear2)) {
813 tcd.
ears[1] =
EarTet{m_mesh.id_tet(ear2), m_mesh.id_face(ear2)};
815 tcd.
ears[1] =
EarTet{-1, m_mesh.id_face(ear2)};
818 tcd.
v0 = m_mesh.id_vertex(tet);
819 tcd.
v1 = m_mesh.id_vertex(m_mesh.switch_vertex(tet));
821 m_mesh.id_vertex(m_mesh.switch_vertex(m_mesh.switch_edge(m_mesh.switch_face(tet))));
822 tcd.
v3 = m_mesh.id_vertex(m_mesh.switch_vertex(m_mesh.switch_edge(tet)));
824 tcd.
e01 = m_mesh.id_edge(tet);
825 tcd.
e03 = m_mesh.id_edge(m_mesh.switch_edge(tet));
826 tcd.
e13 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_vertex(tet)));
827 tcd.
e02 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_face(tet)));
828 tcd.
e12 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_face(m_mesh.switch_vertex(tet))));
829 tcd.
e23 = m_mesh.id_edge(
830 m_mesh.switch_edge(m_mesh.switch_vertex(m_mesh.switch_face(m_mesh.switch_edge(tet)))));
832 m_incident_tet_datas.emplace_back(tcd);
836 m_incident_face_datas.clear();
837 for (int64_t i = 0; i < m_incident_tet_datas.size(); ++i) {
838 auto& data = m_incident_face_datas.emplace_back();
839 data.ear_eids[0] = m_incident_tet_datas[i].e03;
840 data.ear_eids[1] = m_incident_tet_datas[i].e13;
841 data.new_edge_id = data.ear_eids[1];
844 if (incident_tets.size() != incident_faces.size()) {
845 auto& data = m_incident_face_datas.emplace_back();
846 data.ear_eids[0] = m_incident_tet_datas[0].e02;
847 data.ear_eids[1] = m_incident_tet_datas[0].e12;
848 data.new_edge_id = data.ear_eids[1];
851 assert(m_incident_face_datas.size() == incident_faces.size());
855 int64_t return_local_vid = -1;
856 int64_t return_local_eid = -1;
857 int64_t return_local_fid = -1;
858 int64_t return_tid = -1;
860 std::map<int64_t, int64_t> edge_replacement;
865 const int64_t v0 = data.v0;
866 const int64_t v1 = data.v1;
867 const int64_t v2 = data.v2;
868 const int64_t v3 = data.v3;
869 const int64_t e01 = data.e01;
870 const int64_t e02 = data.e02;
871 const int64_t e12 = data.e12;
872 const int64_t e03 = data.e03;
873 const int64_t e13 = data.e13;
874 const int64_t e23 = data.e23;
875 const int64_t f_ear_1 = data.ears[0].fid;
876 const int64_t f_ear_2 = data.ears[1].fid;
877 const int64_t t_ear_1 = data.ears[0].tid;
878 const int64_t t_ear_2 = data.ears[1].tid;
879 const int64_t t_old = data.tid;
881 edge_replacement[e02] = e12;
882 edge_replacement[e03] = e13;
915 assert(t_ear_1 > -1 || t_ear_2 > -1);
918 bool return_flag =
false;
919 if (t_old == m_operating_tet_id) {
923 return_tid = (t_ear_2 > -1) ? t_ear_2 : t_ear_1;
937 auto tt = tt_accessor.vector_attribute(t_ear_1);
938 auto tf = tf_accessor.vector_attribute(t_ear_1);
939 auto te = te_accessor.vector_attribute(t_ear_1);
940 auto tv = tv_accessor.vector_attribute(t_ear_1);
943 if (return_flag && return_tid == t_ear_1) {
944 for (
int k = 0; k < 4; ++k) {
946 if (tf(k) == f_ear_1) {
947 return_local_fid = k;
952 return_local_vid = k;
956 for (
int k = 0; k < 6; ++k) {
959 return_local_eid = k;
967 for (
int k = 0; k < 4; ++k) {
968 if (tf(k) == f_ear_1) {
969 assert(tt(k) == t_old);
976 for (
int k = 0; k < 6; ++k) {
988 auto tt = tt_accessor.vector_attribute(t_ear_2);
989 auto tf = tf_accessor.vector_attribute(t_ear_2);
990 auto te = te_accessor.vector_attribute(t_ear_2);
991 auto tv = tv_accessor.vector_attribute(t_ear_2);
995 if (return_flag && return_tid == t_ear_2) {
996 for (
int k = 0; k < 4; ++k) {
998 return_local_vid = k;
1000 if (tf(k) == f_ear_2) {
1001 return_local_fid = k;
1005 for (
int k = 0; k < 6; ++k) {
1007 return_local_eid = k;
1013 for (
int k = 0; k < 4; ++k) {
1014 if (tt(k) == t_old) {
1021 const int64_t t_ear_valid = (t_ear_2 > -1) ? t_ear_2 : t_ear_1;
1024 data.merged_face_tid = t_ear_valid;
1026 ft_accessor.scalar_attribute(f_ear_2) = t_ear_valid;
1028 data.new_face_id = f_ear_2;
1031 et_accessor.scalar_attribute(e12) = t_ear_valid;
1032 et_accessor.scalar_attribute(e13) = t_ear_valid;
1033 et_accessor.scalar_attribute(e23) = t_ear_valid;
1036 vt_accessor.scalar_attribute(v1) = t_ear_valid;
1037 vt_accessor.scalar_attribute(v2) = t_ear_valid;
1038 vt_accessor.scalar_attribute(v3) = t_ear_valid;
1043 const int64_t v0 = m_spine_vids[0];
1044 const int64_t v1 = m_spine_vids[1];
1048 const int64_t tid = m_mesh.id(t);
1049 auto tv = tv_accessor.vector_attribute(tid);
1050 auto te = te_accessor.vector_attribute(tid);
1051 for (
int i = 0; i < 4; ++i) {
1057 for (
int i = 0; i < 6; ++i) {
1058 if (edge_replacement.find(te(i)) != edge_replacement.end()) {
1059 te(i) = edge_replacement[te(i)];
1068 assert(m_mesh.is_connectivity_valid());
1069 assert(return_tid > -1);
1070 assert(return_local_fid > -1);
1071 assert(return_local_eid > -1);
1072 assert(return_local_vid > -1);
1073 m_output_tuple =
Tuple(return_local_vid, return_local_eid, return_local_fid, return_tid);
1075 assert(m_mesh.id_vertex(m_output_tuple) == v1);