261 std::vector<std::vector<std::tuple<int64_t, bool, bool>>>& VV,
262 std::vector<Vector2r>& V_pos,
263 std::vector<int64_t>& stack,
264 std::vector<int>& in_stack,
265 std::vector<int>& is_on_input,
266 std::vector<int>& is_used,
267 std::vector<std::vector<int64_t>>& in_stack_idx,
269 const int64_t v_prev,
270 std::vector<std::array<int64_t, 3>>& FV,
271 std::vector<std::array<int, 3>>& local_e_on_input)
273 if (in_stack[v] == 1) {
275 const int64_t begin_idx = in_stack_idx[v].back();
276 const int64_t end_idx = stack.size() - 1;
278 bool new_poly =
true;
279 for (int64_t i = begin_idx; i < end_idx; ++i) {
287 assert(end_idx - begin_idx >= 2);
290 for (int64_t i = begin_idx; i < end_idx; ++i) {
294 if (end_idx - begin_idx == 2) {
296 FV.push_back({{stack[begin_idx], stack[begin_idx + 1], stack[end_idx]}});
297 local_e_on_input.push_back(
298 {{is_on_input[begin_idx + 1], is_on_input[end_idx], is_on_input[begin_idx]}});
303 int64_t centroid_idx = V_pos.size();
304 for (int64_t i = begin_idx; i < end_idx + 1; ++i) {
305 centroid = centroid + V_pos[stack[i]];
306 int64_t next_stack_idx = (i == end_idx) ? begin_idx : i + 1;
307 FV.push_back({{stack[i], stack[next_stack_idx], centroid_idx}});
308 local_e_on_input.push_back({{0, 0, is_on_input[i]}});
311 V_pos.push_back(centroid /
double(end_idx - begin_idx + 1));
320 in_stack_idx[v].push_back(stack.size() - 1);
322 std::map<int64_t, int64_t> global_to_local_idx;
323 for (int64_t i = 0; i < VV[v].size(); ++i) {
324 global_to_local_idx[std::get<0>(VV[v][i])] = i;
328 std::vector<Vector2r> out_vec;
329 std::vector<int64_t> out_vertices;
332 std::vector<std::array<double, 2>> out_vec_double;
333 std::array<double, 2> prev_vec_double = {
334 {prev_vector[0].to_double(), prev_vector[1].to_double()}};
337 for (int64_t i = 0; i < VV[v].size(); ++i) {
338 if (std::get<0>(VV[v][i]) == v_prev) {
342 out_vec.push_back(V_pos[std::get<0>(VV[v][i])] - V_pos[v]);
343 out_vec_double.push_back(
344 {{(V_pos[std::get<0>(VV[v][i])] - V_pos[v])[0].to_double(),
345 (V_pos[std::get<0>(VV[v][i])] - V_pos[v])[1].to_double()}});
346 out_vertices.push_back(std::get<0>(VV[v][i]));
350 out_vec.push_back(prev_vector);
351 out_vertices.push_back(-1);
353 int64_t base_idx = out_vec.size() - 1;
358 std::vector<int64_t> ccw_vertices;
359 std::vector<Vector2r> ccw_vec;
360 std::vector<int64_t> ccw_local_idx;
362 int64_t start_idx = -1;
363 for (int64_t i = 0; i < cyclic_order_idx.size(); ++i) {
364 if (cyclic_order_idx[i] == base_idx) {
369 assert(start_idx > -1);
373 bool has_colinear_out =
false;
374 int64_t colinear_out_idx = -1;
375 int64_t iter = (start_idx + 1) % out_vec.size();
377 if (prev_vector[0] * out_vec[cyclic_order_idx[iter]][1] ==
378 prev_vector[1] * out_vec[cyclic_order_idx[iter]][0]) {
379 has_colinear_out =
true;
380 colinear_out_idx = iter;
381 iter = (iter + 1) % out_vec.size();
384 while (iter != start_idx) {
385 if (prev_vector[0] * out_vec[cyclic_order_idx[iter]][1] >=
386 prev_vector[1] * out_vec[cyclic_order_idx[iter]][0]) {
387 ccw_vertices.push_back(out_vertices[cyclic_order_idx[iter]]);
388 ccw_vec.push_back(out_vec[cyclic_order_idx[iter]]);
390 iter = (iter + 1) % out_vec.size();
393 if (has_colinear_out) {
394 ccw_vertices.push_back(out_vertices[cyclic_order_idx[colinear_out_idx]]);
395 ccw_vec.push_back(out_vec[cyclic_order_idx[colinear_out_idx]]);
400 for (int64_t i = 0; i < ccw_vertices.size(); ++i) {
401 if (!std::get<2>(VV[v][global_to_local_idx[ccw_vertices[i]]]) &&
402 ccw_vertices[i] != v_prev) {
403 is_on_input.push_back(
404 (std::get<1>(VV[v][global_to_local_idx[ccw_vertices[i]]])) ? 1 : 0);
405 is_used.push_back(0);
406 std::get<2>(VV[v][global_to_local_idx[ccw_vertices[i]]]) =
true;
421 is_on_input.pop_back();
428 in_stack_idx[v].pop_back();
486 std::vector<Vector2r>& v_final,
487 std::vector<std::array<int64_t, 3>>& FV_new,
488 std::vector<std::array<int, 3>>& local_e_on_input)
491 std::move(_trimesh));
498 Eigen::MatrixX<int64_t> EV_tmp;
505 Eigen::MatrixX<double> V_edge_double;
509 Eigen::VectorX<int64_t> _SVI, _SVJ;
510 Eigen::MatrixX<int64_t> EV_in;
511 Eigen::MatrixX<double> V_edge_tmp;
513 igl::remove_duplicate_vertices(V_edge_double, EV_tmp, 0, V_edge_tmp, _SVI, _SVJ, EV_in);
515 Eigen::MatrixX<Rational> V_edge;
517 V_edge.resize(V_edge_tmp.rows(), V_edge_tmp.cols());
518 for (int64_t i = 0; i < V_edge_tmp.rows(); ++i) {
519 for (int64_t j = 0; j < V_edge_tmp.cols(); ++j) {
520 V_edge(i, j) =
Rational(V_edge_tmp(i, j));
576 std::vector<std::array<int64_t, 2>> EV;
577 for (int64_t i = 0; i < EV_in.rows(); ++i) {
578 EV.push_back({{EV_in(i, 0), EV_in(i, 1)}});
585 auto bbox_min_handle =
588 auto bbox_max_handle =
592 auto position_handle =
596 auto segment_index_handle =
598 auto segment_index_accessor = trimesh.
create_accessor<int64_t>(segment_index_handle);
600 std::vector<attribute::MeshAttributeHandle> pass_through_attributes;
601 pass_through_attributes.push_back(bbox_min_handle);
602 pass_through_attributes.push_back(bbox_max_handle);
603 pass_through_attributes.push_back(position_handle);
612 const Vector2r& p0 = position_accessor.const_vector_attribute(v0);
613 const Vector2r& p1 = position_accessor.const_vector_attribute(v1);
614 const Vector2r& p2 = position_accessor.const_vector_attribute(v2);
618 bbox_min_accessor.vector_attribute(f) =
bbox[0];
619 bbox_max_accessor.vector_attribute(f) =
bbox[1];
623 for (int64_t i = 0; i < V_edge.rows(); ++i) {
632 bbox_min_accessor.const_vector_attribute(f),
633 bbox_max_accessor.const_vector_attribute(f))) {
642 const Vector2r& p0 = position_accessor.const_vector_attribute(v0);
643 const Vector2r& p1 = position_accessor.const_vector_attribute(v1);
644 const Vector2r& p2 = position_accessor.const_vector_attribute(v2);
646 const std::array<Vector2r, 3> ps = {{p0, p1, p2}};
650 if (in_tri_case == -1) {
653 switch (in_tri_case) {
658 for (
const auto& attr : pass_through_attributes) {
666 segment_index_handle,
670 for (
const auto& attr : pass_through_attributes) {
677 segment_index_handle,
684 position_accessor.vector_attribute(new_v) = p;
687 const Tuple new_f0 = new_v;
697 bbox_min_accessor.vector_attribute(new_f0) = bbox_0[0];
698 bbox_max_accessor.vector_attribute(new_f0) = bbox_0[1];
699 bbox_min_accessor.vector_attribute(new_f1) = bbox_1[0];
700 bbox_max_accessor.vector_attribute(new_f1) = bbox_1[1];
701 bbox_min_accessor.vector_attribute(new_f2) = bbox_2[0];
702 bbox_max_accessor.vector_attribute(new_f2) = bbox_2[1];
705 const auto original_edge =
708 const Tuple neighbor_f =
713 const Vector2r& pn = position_accessor.const_vector_attribute(oppo_v);
716 bbox_min_accessor.vector_attribute(neighbor_f) = bbox_n[0];
717 bbox_max_accessor.vector_attribute(neighbor_f) = bbox_n[1];
722 segment_index_accessor.scalar_attribute(new_v) = i;
730 for (
const auto& attr : pass_through_attributes) {
738 segment_index_handle,
747 position_accessor.vector_attribute(new_v) = p;
750 const Tuple new_f0 = new_v;
758 bbox_min_accessor.vector_attribute(new_f0) = bbox_0[0];
759 bbox_max_accessor.vector_attribute(new_f0) = bbox_0[1];
760 bbox_min_accessor.vector_attribute(new_f1) = bbox_1[0];
761 bbox_max_accessor.vector_attribute(new_f1) = bbox_1[1];
770 position_accessor.const_vector_attribute(trimesh.
switch_tuples(
772 {PrimitiveType::Edge, PrimitiveType::Vertex}));
777 bbox_min_accessor.vector_attribute(new_f2) = bbox_2[0];
778 bbox_max_accessor.vector_attribute(new_f2) = bbox_2[1];
779 bbox_min_accessor.vector_attribute(new_f3) = bbox_3[0];
780 bbox_max_accessor.vector_attribute(new_f3) = bbox_3[1];
783 segment_index_accessor.scalar_attribute(new_v) = i;
791 for (
const auto& attr : pass_through_attributes) {
799 segment_index_handle,
807 {PrimitiveType::Vertex, PrimitiveType::Edge})))
812 position_accessor.vector_attribute(new_v) = p;
815 const Tuple new_f0 = new_v;
823 bbox_min_accessor.vector_attribute(new_f0) = bbox_0[0];
824 bbox_max_accessor.vector_attribute(new_f0) = bbox_0[1];
825 bbox_min_accessor.vector_attribute(new_f1) = bbox_1[0];
826 bbox_max_accessor.vector_attribute(new_f1) = bbox_1[1];
835 position_accessor.const_vector_attribute(trimesh.
switch_tuples(
837 {PrimitiveType::Edge, PrimitiveType::Vertex}));
842 bbox_min_accessor.vector_attribute(new_f2) = bbox_2[0];
843 bbox_max_accessor.vector_attribute(new_f2) = bbox_2[1];
844 bbox_min_accessor.vector_attribute(new_f3) = bbox_3[0];
845 bbox_max_accessor.vector_attribute(new_f3) = bbox_3[1];
848 segment_index_accessor.scalar_attribute(new_v) = i;
856 for (
const auto& attr : pass_through_attributes) {
864 segment_index_handle,
875 position_accessor.vector_attribute(new_v) = p;
878 const Tuple new_f0 = new_v;
886 bbox_min_accessor.vector_attribute(new_f0) = bbox_0[0];
887 bbox_max_accessor.vector_attribute(new_f0) = bbox_0[1];
888 bbox_min_accessor.vector_attribute(new_f1) = bbox_1[0];
889 bbox_max_accessor.vector_attribute(new_f1) = bbox_1[1];
898 position_accessor.const_vector_attribute(trimesh.
switch_tuples(
900 {PrimitiveType::Edge, PrimitiveType::Vertex}));
905 bbox_min_accessor.vector_attribute(new_f2) = bbox_2[0];
906 bbox_max_accessor.vector_attribute(new_f2) = bbox_2[1];
907 bbox_min_accessor.vector_attribute(new_f3) = bbox_3[0];
908 bbox_max_accessor.vector_attribute(new_f3) = bbox_3[1];
911 segment_index_accessor.scalar_attribute(new_v) = i;
917 segment_index_accessor.scalar_attribute(v0) = i;
922 segment_index_accessor.scalar_attribute(v1) = i;
927 segment_index_accessor.scalar_attribute(v2) = i;
931 throw std::runtime_error(
"wrong inside triangle case");
946 std::vector<int64_t> v_map_seg_to_tri(V_edge.rows());
949 for (int64_t i = 0; i < vs.size(); ++i) {
950 int64_t seg_idx = segment_index_accessor.const_scalar_attribute(vs[i]);
956 assert(seg_idx < V_edge.rows());
957 v_map_seg_to_tri[seg_idx] = i;
964 Eigen::MatrixX<int64_t> FV;
965 Eigen::MatrixX<Rational> V_tris;
970 Eigen::MatrixX<int64_t>
edges;
971 igl::edges(FV,
edges);
974 v_final.resize(V_tris.rows());
976 for (int64_t i = 0; i < V_tris.rows(); ++i) {
977 v_final[i] = V_tris.row(i);
980 std::vector<Segment> segments;
981 for (int64_t i = 0; i <
edges.rows(); ++i) {
986 for (
int i = 0; i < EV.size(); ++i) {
987 EV[i][0] = v_map_seg_to_tri[EV[i][0]];
988 EV[i][1] = v_map_seg_to_tri[EV[i][1]];
991 for (int64_t i = 0; i < EV.size(); ++i) {
992 const int64_t idx0 = EV[i][0];
993 const int64_t idx1 = EV[i][1];
1000 std::vector<Segment> new_segments;
1001 bool s_already_exist =
false;
1003 for (int64_t j = 0; j < segments.size(); ++j) {
1004 auto& seg = segments[j];
1006 if (seg.deprecated)
continue;
1014 if ((s.
p0 == seg.p0 && s.
p1 == seg.p1) || (s.
p0 == seg.p1 && s.
p1 == seg.p0)) {
1016 s_already_exist =
true;
1017 seg.is_on_input =
true;
1022 seg.deprecated =
true;
1024 std::vector<std::pair<int64_t, Vector2r>> all_points;
1028 all_points.push_back(p);
1030 for (
const auto& p : seg.points_on_segment) {
1031 all_points.push_back(p);
1034 auto comp = [](
const std::pair<int64_t, Vector2r>& v0,
1035 const std::pair<int64_t, Vector2r>& v1) {
1036 if (v0.second[0] == v1.second[0]) {
1037 return v0.second[1] < v1.second[1];
1039 return v0.second[0] < v1.second[0];
1042 auto equal = [](
const std::pair<int64_t, Vector2r>& v0,
1043 const std::pair<int64_t, Vector2r>& v1) {
1044 return v0.second[0] == v1.second[0] && v0.second[1] == v1.second[1];
1048 std::sort(all_points.begin(), all_points.end(), comp);
1050 std::unique(all_points.begin(), all_points.end(), equal),
1053 int64_t p0_idx = -1, p1_idx = -1;
1055 for (int64_t k = 0; k < all_points.size(); ++k) {
1056 if (idx0 == all_points[k].first) {
1059 if (idx1 == all_points[k].first) {
1064 assert(p0_idx != -1 && p1_idx != -1);
1067 int64_t start_idx, end_idx;
1069 if (p0_idx < p1_idx) {
1078 if (start_idx != 0) {
1080 all_points[0].second,
1081 all_points[start_idx].second,
1082 all_points[0].first,
1083 all_points[start_idx].first);
1084 for (int64_t k = 1; k < start_idx; ++k) {
1090 new_segments.push_back(s0);
1094 for (int64_t k = start_idx; k <= end_idx; ++k) {
1098 if (end_idx != all_points.size() - 1) {
1100 all_points[end_idx].second,
1101 all_points[all_points.size() - 1].second,
1102 all_points[end_idx].first,
1103 all_points[all_points.size() - 1].first);
1104 for (int64_t k = end_idx + 1; k < all_points.size() - 1; ++k) {
1110 new_segments.push_back(s1);
1124 assert(t0 >= 0 && t0 <= 1);
1125 assert(t1 >= 0 && t1 <= 1);
1128 bool v_exist_on_0 =
false;
1129 bool v_exist_on_1 =
false;
1130 int64_t new_v_idx = -1;
1134 v_exist_on_0 =
true;
1140 for (int64_t k = 0; k < seg.points_on_segment.size(); ++k) {
1141 if (res == seg.points_on_segment[k].second) {
1142 v_exist_on_1 =
true;
1143 new_v_idx = seg.points_on_segment[k].first;
1148 if (!v_exist_on_0 && !v_exist_on_1) {
1149 v_final.push_back(res);
1150 new_v_idx = v_final.size() - 1;
1153 assert(new_v_idx > -1);
1155 if (!v_exist_on_0) {
1169 if (!v_exist_on_1) {
1180 seg.points_on_segment.push_back(std::make_pair(new_v_idx, res));
1185 for (
const auto& seg : new_segments) {
1186 segments.push_back(seg);
1189 if (!s_already_exist) {
1190 segments.push_back(s);
1196 auto comp = [](
const std::pair<int64_t, Vector2r>& v0,
const std::pair<int64_t, Vector2r>& v1) {
1197 if (v0.second[0] == v1.second[0]) {
1198 return v0.second[1] < v1.second[1];
1200 return v0.second[0] < v1.second[0];
1203 for (int64_t i = 0; i < segments.size(); ++i) {
1204 if (segments[i].deprecated) {
1207 std::sort(segments[i].points_on_segment.begin(), segments[i].points_on_segment.end(), comp);
1212 std::vector<std::vector<std::tuple<int64_t, bool, bool>>> VV(v_final.size());
1214 for (int64_t i = 0; i < segments.size(); ++i) {
1215 if (segments[i].deprecated) {
1218 for (int64_t j = 0; j < segments[i].points_on_segment.size() - 1; ++j) {
1219 VV[segments[i].points_on_segment[j].first].push_back(std::make_tuple(
1220 segments[i].points_on_segment[j + 1].first,
1221 segments[i].is_on_input,
1223 VV[segments[i].points_on_segment[j + 1].first].push_back(std::make_tuple(
1224 segments[i].points_on_segment[j].first,
1225 segments[i].is_on_input,