245 simplex_ids_to_delete = get_split_simplices_to_delete(m_operating_tuple, m_mesh);
250 assert(new_vids.size() == 1);
251 const int64_t v_new = new_vids[0];
252 m_split_new_vid = v_new;
256 assert(new_eids.size() == 2);
257 std::copy(new_eids.begin(), new_eids.end(), m_split_new_spine_eids.begin());
264 const auto [incident_tets, incident_faces] = get_incident_tets_and_faces(m_operating_tuple);
265 const bool loop_flag = (incident_tets.size() == incident_faces.size());
267 const size_t facet_size = incident_tets.size();
268 std::vector<int64_t> new_facet_ids =
270 assert(new_facet_ids.size() == 2 * facet_size);
271 const size_t face_size = incident_faces.size();
272 std::vector<int64_t> new_face_ids =
274 assert(new_face_ids.size() == 2 * face_size);
277 std::vector<FaceSplitData> new_incident_face_data;
278 for (int64_t i = 0; i < incident_faces.size(); ++i) {
282 fsd.
fid_old = m_mesh.id_face(incident_faces[i]);
284 new_face_ids.begin() + 2 * i,
285 new_face_ids.begin() + 2 * (i + 1),
290 fsd.
eid_rib = splitting_eids[0];
292 new_incident_face_data.emplace_back(fsd);
296 int64_t incident_face_cnt = new_incident_face_data.size();
299 m_incident_tet_datas.clear();
300 for (int64_t i = 0; i < incident_tets.size(); ++i) {
305 tsd.
tid = m_mesh.id_tet(incident_tets[i]);
307 new_facet_ids.begin() + 2 * i,
308 new_facet_ids.begin() + 2 * (i + 1),
310 tsd.
rib_f = split_fids[0];
313 split_facet_data().add_facet(m_mesh, m_operating_tuple, tsd.
split_t);
316 Tuple ear1 = m_mesh.switch_face(m_mesh.switch_edge(incident_tets[i]));
317 if (!m_mesh.is_boundary_face(ear1)) {
319 tsd.
ears[0] =
EarTet{m_mesh.id_tet(ear1), m_mesh.id_face(ear1)};
321 tsd.
ears[0] =
EarTet{-1, m_mesh.id_face(ear1)};
324 Tuple ear2 = m_mesh.switch_face(m_mesh.switch_edge(m_mesh.switch_vertex(incident_tets[i])));
325 if (!m_mesh.is_boundary_face(ear2)) {
327 tsd.
ears[1] =
EarTet{m_mesh.id_tet(ear2), m_mesh.id_face(ear2)};
329 tsd.
ears[1] =
EarTet{-1, m_mesh.id_face(ear2)};
333 new_incident_face_data[(i + incident_face_cnt - 1) % incident_face_cnt];
342 tsd.
v0 = m_mesh.id_vertex(incident_tets[i]);
343 tsd.
v1 = m_mesh.id_vertex(m_mesh.switch_vertex(incident_tets[i]));
344 tsd.
v2 = m_mesh.id_vertex(m_mesh.switch_vertex(
345 m_mesh.switch_edge(m_mesh.switch_face(incident_tets[i]))));
346 tsd.
v3 = m_mesh.id_vertex(
347 m_mesh.switch_vertex(m_mesh.switch_edge(incident_tets[i])));
349 tsd.
e01 = m_mesh.id_edge(incident_tets[i]);
350 tsd.
e03 = m_mesh.id_edge(m_mesh.switch_edge(incident_tets[i]));
351 tsd.
e13 = m_mesh.id_edge(
352 m_mesh.switch_edge(m_mesh.switch_vertex(incident_tets[i])));
353 tsd.
e02 = m_mesh.id_edge(
354 m_mesh.switch_edge(m_mesh.switch_face(incident_tets[i])));
355 tsd.
e12 = m_mesh.id_edge(m_mesh.switch_edge(
356 m_mesh.switch_face(m_mesh.switch_vertex(incident_tets[i]))));
357 tsd.
e23 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_vertex(
358 m_mesh.switch_face(m_mesh.switch_edge(incident_tets[i])))));
360 m_incident_tet_datas.emplace_back(tsd);
364 m_incident_face_datas.clear();
365 for (int64_t i = 0; i < m_incident_tet_datas.size(); ++i) {
366 auto& data = m_incident_face_datas.emplace_back();
367 data.fid = m_incident_tet_datas[i].new_face_data[1].fid_old;
368 data.ear_eids[0] = m_incident_tet_datas[i].e03;
369 data.ear_eids[1] = m_incident_tet_datas[i].e13;
370 data.new_edge_id = m_incident_tet_datas[i].new_face_data[1].eid_rib;
371 data.split_f[0] = m_incident_tet_datas[i].new_face_data[1].fid_new[0];
372 data.split_f[1] = m_incident_tet_datas[i].new_face_data[1].fid_new[1];
373 data.local_operating_tuple = m_incident_tet_datas[i].new_face_data[1].local_operating_tuple;
377 auto& data = m_incident_face_datas.emplace_back();
378 data.fid = m_incident_tet_datas[0].new_face_data[0].fid_old;
379 data.ear_eids[0] = m_incident_tet_datas[0].e02;
380 data.ear_eids[1] = m_incident_tet_datas[0].e12;
381 data.new_edge_id = m_incident_tet_datas[0].new_face_data[0].eid_rib;
382 data.split_f[0] = m_incident_tet_datas[0].new_face_data[0].fid_new[0];
383 data.split_f[1] = m_incident_tet_datas[0].new_face_data[0].fid_new[1];
384 data.local_operating_tuple = m_incident_tet_datas[0].new_face_data[0].local_operating_tuple;
387 assert(m_incident_face_datas.size() == new_incident_face_data.size());
391 for (int64_t i = 0; i < m_incident_face_datas.size(); ++i) {
392 assert(m_incident_face_datas[i].fid == new_incident_face_data[i].fid_old);
398 int64_t return_local_vid = -1;
399 int64_t return_local_eid = -1;
400 int64_t return_local_fid = -1;
401 int64_t return_tid = -1;
405 int64_t return_fid = -1;
406 int64_t return_split_fid = -1;
410 for (int64_t i = 0; i < m_incident_tet_datas.size(); ++i) {
412 const auto& data = m_incident_tet_datas[i];
413 const int64_t vid_new = v_new;
414 const int64_t v0 = data.v0;
415 const int64_t v1 = data.v1;
416 const int64_t v2 = data.v2;
417 const int64_t v3 = data.v3;
418 const int64_t e_spine_1 = new_eids[0];
419 const int64_t e_spine_2 = new_eids[1];
420 const int64_t e_rib_1 = data.new_face_data[0].eid_rib;
421 const int64_t e_rib_2 = data.new_face_data[1].eid_rib;
422 const int64_t e01 = data.e01;
423 const int64_t e02 = data.e02;
424 const int64_t e12 = data.e12;
425 const int64_t e03 = data.e03;
426 const int64_t e13 = data.e13;
427 const int64_t e23 = data.e23;
428 const int64_t f_ear_1 = data.ears[0].fid;
429 const int64_t f_ear_2 = data.ears[1].fid;
430 const int64_t f1 = data.new_face_data[0].fid_new[0];
431 const int64_t f2 = data.new_face_data[0].fid_new[1];
432 const int64_t f_old_1 = data.new_face_data[0].fid_old;
433 const int64_t f3 = data.new_face_data[1].fid_new[0];
434 const int64_t f4 = data.new_face_data[1].fid_new[1];
435 const int64_t f_old_2 = data.new_face_data[1].fid_old;
436 const int64_t f_rib = data.rib_f;
437 const int64_t t_ear_1 = data.ears[0].tid;
438 const int64_t t_ear_2 = data.ears[1].tid;
439 const int64_t t1 = data.split_t[0];
440 const int64_t t2 = data.split_t[1];
441 const int64_t t_old = data.tid;
509 bool return_flag =
false;
510 if (t_old == m_operating_tet_id) {
513 logger().trace(
"split fid is {}", f_rib);
514 logger().trace(
"fids {} {} are joined by edge {}", f3, f4, e_rib_2);
517 return_split_fid = f_rib;
521 int64_t prev_index = (i - 1 + m_incident_tet_datas.size()) % m_incident_tet_datas.size();
522 int64_t next_index = (i + 1 + m_incident_tet_datas.size()) % m_incident_tet_datas.size();
525 t_f1 = m_incident_tet_datas[prev_index].split_t[0];
526 t_f2 = m_incident_tet_datas[prev_index].split_t[1];
527 t_f3 = m_incident_tet_datas[next_index].split_t[0];
528 t_f4 = m_incident_tet_datas[next_index].split_t[1];
530 if (m_incident_tet_datas.size() == 1) {
541 t_f1 = m_incident_tet_datas[prev_index].split_t[0];
542 t_f2 = m_incident_tet_datas[prev_index].split_t[1];
544 if (i == m_incident_tet_datas.size() - 1) {
549 t_f3 = m_incident_tet_datas[next_index].split_t[0];
550 t_f4 = m_incident_tet_datas[next_index].split_t[1];
558 update_ear_connectivity(t_ear_1, t1, t_old, f_ear_1);
560 auto tt = tt_accessor.index_access().vector_attribute(t1);
561 auto tf = tf_accessor.index_access().vector_attribute(t1);
562 auto te = te_accessor.index_access().vector_attribute(t1);
563 auto tv = tv_accessor.index_access().vector_attribute(t1);
579 tt = tt_accessor.index_access().vector_attribute(t_old);
580 tf = tf_accessor.index_access().vector_attribute(t_old);
581 te = te_accessor.index_access().vector_attribute(t_old);
582 tv = tv_accessor.index_access().vector_attribute(t_old);
587 for (
int k = 0; k < 4; ++k) {
589 if (tv(k) == m_spine_vids[0]) {
590 return_local_vid = k;
594 if (tf(k) == m_operating_face_id) {
595 return_local_fid = k;
600 for (
int k = 0; k < 6; ++k) {
602 return_local_eid = k;
609 for (
size_t k = 0; k < 4; ++k) {
616 if (tf(k) == f_old_1) {
618 m_incident_tet_datas[i].incident_face_local_fid[0] = k;
623 if (tf(k) == f_old_2) {
625 m_incident_tet_datas[i].incident_face_local_fid[1] = k;
630 if (tf(k) == f_ear_2) {
636 for (
size_t k = 0; k < 6; ++k) {
653 update_ear_connectivity(t_ear_2, t2, t_old, f_ear_2);
655 auto tt = tt_accessor.index_access().vector_attribute(t2);
656 auto tf = tf_accessor.index_access().vector_attribute(t2);
657 auto te = te_accessor.index_access().vector_attribute(t2);
658 auto tv = tv_accessor.index_access().vector_attribute(t2);
674 tt = tt_accessor.index_access().const_vector_attribute(t_old);
675 tf = tf_accessor.index_access().const_vector_attribute(t_old);
676 te = te_accessor.index_access().const_vector_attribute(t_old);
677 tv = tv_accessor.index_access().const_vector_attribute(t_old);
678 for (
size_t k = 0; k < 4; ++k) {
685 if (tf(k) == f_old_1) {
689 if (tf(k) == f_old_2) {
693 if (tf(k) == f_ear_1) {
699 for (
size_t k = 0; k < 6; ++k) {
714 ft_accessor.index_access().scalar_attribute(f_ear_1) = t1;
715 ft_accessor.index_access().scalar_attribute(f_ear_2) = t2;
716 ft_accessor.index_access().scalar_attribute(f1) = t1;
717 ft_accessor.index_access().scalar_attribute(f2) = t2;
718 ft_accessor.index_access().scalar_attribute(f3) = t1;
719 ft_accessor.index_access().scalar_attribute(f4) = t2;
720 ft_accessor.index_access().scalar_attribute(f_rib) = t1;
723 et_accessor.index_access().scalar_attribute(e02) = t1;
724 et_accessor.index_access().scalar_attribute(e12) = t2;
725 et_accessor.index_access().scalar_attribute(e03) = t1;
726 et_accessor.index_access().scalar_attribute(e13) = t2;
727 et_accessor.index_access().scalar_attribute(e23) = t1;
728 et_accessor.index_access().scalar_attribute(e_spine_1) = t1;
729 et_accessor.index_access().scalar_attribute(e_spine_2) = t2;
730 et_accessor.index_access().scalar_attribute(e_rib_1) = t1;
731 et_accessor.index_access().scalar_attribute(e_rib_2) = t1;
734 vt_accessor.index_access().scalar_attribute(v0) = t1;
735 vt_accessor.index_access().scalar_attribute(v1) = t2;
736 vt_accessor.index_access().scalar_attribute(v2) = t1;
737 vt_accessor.index_access().scalar_attribute(v3) = t1;
738 vt_accessor.index_access().scalar_attribute(vid_new) = t1;
747 assert(return_tid > -1);
748 assert(return_local_vid > -1);
749 assert(return_local_eid > -1);
750 assert(return_local_fid > -1);
752 assert(return_local_vid == m_operating_tuple.local_vid());
753 assert(return_local_eid == m_operating_tuple.local_eid());
754 assert(return_local_fid == m_operating_tuple.local_fid());
755 m_output_tuple =
Tuple(return_local_vid, return_local_eid, return_local_fid, return_tid);
770 assert(!m_mesh.is_boundary_face(m_mesh.switch_tuples(m_output_tuple, {PE, PF})));
777 simplex_ids_to_delete = get_collapse_simplices_to_delete(m_operating_tuple, m_mesh);
795 auto [incident_tets, incident_faces] = get_incident_tets_and_faces(m_operating_tuple);
798 for (
const Tuple& tet : incident_tets) {
801 tcd.
tid = m_mesh.id_tet(tet);
804 Tuple ear1 = m_mesh.switch_face(m_mesh.switch_edge(tet));
805 if (!m_mesh.is_boundary_face(ear1)) {
807 tcd.
ears[0] =
EarTet{m_mesh.id_tet(ear1), m_mesh.id_face(ear1)};
809 tcd.
ears[0] =
EarTet{-1, m_mesh.id_face(ear1)};
812 Tuple ear2 = m_mesh.switch_face(m_mesh.switch_edge(m_mesh.switch_vertex(tet)));
813 if (!m_mesh.is_boundary_face(ear2)) {
815 tcd.
ears[1] =
EarTet{m_mesh.id_tet(ear2), m_mesh.id_face(ear2)};
817 tcd.
ears[1] =
EarTet{-1, m_mesh.id_face(ear2)};
820 tcd.
v0 = m_mesh.id_vertex(tet);
821 tcd.
v1 = m_mesh.id_vertex(m_mesh.switch_vertex(tet));
823 m_mesh.id_vertex(m_mesh.switch_vertex(m_mesh.switch_edge(m_mesh.switch_face(tet))));
824 tcd.
v3 = m_mesh.id_vertex(m_mesh.switch_vertex(m_mesh.switch_edge(tet)));
826 tcd.
e01 = m_mesh.id_edge(tet);
827 tcd.
e03 = m_mesh.id_edge(m_mesh.switch_edge(tet));
828 tcd.
e13 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_vertex(tet)));
829 tcd.
e02 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_face(tet)));
830 tcd.
e12 = m_mesh.id_edge(m_mesh.switch_edge(m_mesh.switch_face(m_mesh.switch_vertex(tet))));
831 tcd.
e23 = m_mesh.id_edge(
832 m_mesh.switch_edge(m_mesh.switch_vertex(m_mesh.switch_face(m_mesh.switch_edge(tet)))));
834 m_incident_tet_datas.emplace_back(tcd);
838 m_incident_face_datas.clear();
839 for (int64_t i = 0; i < m_incident_tet_datas.size(); ++i) {
840 auto& data = m_incident_face_datas.emplace_back();
841 data.ear_eids[0] = m_incident_tet_datas[i].e03;
842 data.ear_eids[1] = m_incident_tet_datas[i].e13;
843 data.new_edge_id = data.ear_eids[1];
846 if (incident_tets.size() != incident_faces.size()) {
847 auto& data = m_incident_face_datas.emplace_back();
848 data.ear_eids[0] = m_incident_tet_datas[0].e02;
849 data.ear_eids[1] = m_incident_tet_datas[0].e12;
850 data.new_edge_id = data.ear_eids[1];
853 assert(m_incident_face_datas.size() == incident_faces.size());
857 int64_t return_local_vid = -1;
858 int64_t return_local_eid = -1;
859 int64_t return_local_fid = -1;
860 int64_t return_tid = -1;
862 std::map<int64_t, int64_t> edge_replacement;
867 const int64_t v0 = data.v0;
868 const int64_t v1 = data.v1;
869 const int64_t v2 = data.v2;
870 const int64_t v3 = data.v3;
871 const int64_t e01 = data.e01;
872 const int64_t e02 = data.e02;
873 const int64_t e12 = data.e12;
874 const int64_t e03 = data.e03;
875 const int64_t e13 = data.e13;
876 const int64_t e23 = data.e23;
877 const int64_t f_ear_1 = data.ears[0].fid;
878 const int64_t f_ear_2 = data.ears[1].fid;
879 const int64_t t_ear_1 = data.ears[0].tid;
880 const int64_t t_ear_2 = data.ears[1].tid;
881 const int64_t t_old = data.tid;
883 edge_replacement[e02] = e12;
884 edge_replacement[e03] = e13;
917 assert(t_ear_1 > -1 || t_ear_2 > -1);
920 bool return_flag =
false;
921 if (t_old == m_operating_tet_id) {
925 return_tid = (t_ear_2 > -1) ? t_ear_2 : t_ear_1;
939 auto tt = tt_accessor.index_access().vector_attribute(t_ear_1);
940 auto tf = tf_accessor.index_access().vector_attribute(t_ear_1);
941 auto te = te_accessor.index_access().vector_attribute(t_ear_1);
942 auto tv = tv_accessor.index_access().vector_attribute(t_ear_1);
945 if (return_flag && return_tid == t_ear_1) {
946 for (
int k = 0; k < 4; ++k) {
948 if (tf(k) == f_ear_1) {
949 return_local_fid = k;
954 return_local_vid = k;
958 for (
int k = 0; k < 6; ++k) {
961 return_local_eid = k;
969 for (
int k = 0; k < 4; ++k) {
970 if (tf(k) == f_ear_1) {
971 assert(tt(k) == t_old);
978 for (
int k = 0; k < 6; ++k) {
990 auto tt = tt_accessor.index_access().vector_attribute(t_ear_2);
991 auto tf = tf_accessor.index_access().vector_attribute(t_ear_2);
992 auto te = te_accessor.index_access().vector_attribute(t_ear_2);
993 auto tv = tv_accessor.index_access().vector_attribute(t_ear_2);
997 if (return_flag && return_tid == t_ear_2) {
998 for (
int k = 0; k < 4; ++k) {
1000 return_local_vid = k;
1002 if (tf(k) == f_ear_2) {
1003 return_local_fid = k;
1007 for (
int k = 0; k < 6; ++k) {
1009 return_local_eid = k;
1015 for (
int k = 0; k < 4; ++k) {
1016 if (tt(k) == t_old) {
1023 const int64_t t_ear_valid = (t_ear_2 > -1) ? t_ear_2 : t_ear_1;
1026 data.merged_face_tid = t_ear_valid;
1028 ft_accessor.index_access().scalar_attribute(f_ear_2) = t_ear_valid;
1030 data.new_face_id = f_ear_2;
1033 et_accessor.index_access().scalar_attribute(e12) = t_ear_valid;
1034 et_accessor.index_access().scalar_attribute(e13) = t_ear_valid;
1035 et_accessor.index_access().scalar_attribute(e23) = t_ear_valid;
1038 vt_accessor.index_access().scalar_attribute(v1) = t_ear_valid;
1039 vt_accessor.index_access().scalar_attribute(v2) = t_ear_valid;
1040 vt_accessor.index_access().scalar_attribute(v3) = t_ear_valid;
1045 const int64_t v0 = m_spine_vids[0];
1046 const int64_t v1 = m_spine_vids[1];
1050 const int64_t tid = m_mesh.id(t);
1051 auto tv = tv_accessor.index_access().vector_attribute(tid);
1052 auto te = te_accessor.index_access().vector_attribute(tid);
1053 for (
int i = 0; i < 4; ++i) {
1059 for (
int i = 0; i < 6; ++i) {
1060 if (edge_replacement.find(te(i)) != edge_replacement.end()) {
1061 te(i) = edge_replacement[te(i)];
1071 assert(m_mesh.is_connectivity_valid());
1072 assert(return_tid > -1);
1073 assert(return_local_fid > -1);
1074 assert(return_local_eid > -1);
1075 assert(return_local_vid > -1);
1076 m_output_tuple =
Tuple(return_local_vid, return_local_eid, return_local_fid, return_tid);
1078 assert(m_mesh.id_vertex(m_output_tuple) == v1);