You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
3.7 KiB
93 lines
3.7 KiB
9 months ago
|
#include <container/hashmap.hpp>
|
||
|
#include <algorithm/glue_algorithm.hpp>
|
||
|
|
||
|
#include "ia_cut_face.hpp"
|
||
|
#include "robust_assert.hpp"
|
||
|
|
||
|
template <size_t N>
|
||
|
static inline std::array<uint32_t, 3> ia_cut_1_face_impl(IAComplex<N>& ia_complex,
|
||
|
uint32_t eid,
|
||
|
uint32_t plane_index,
|
||
|
const int8_t* orientations)
|
||
|
{
|
||
|
auto& vertices = ia_complex.vertices;
|
||
|
auto& edges = ia_complex.edges;
|
||
|
vertices.reserve(vertices.size() + 1);
|
||
|
edges.reserve(edges.size() + 2);
|
||
|
|
||
|
uint32_t positive_subedge_id = INVALID_INDEX;
|
||
|
uint32_t negative_subedge_id = INVALID_INDEX;
|
||
|
uint32_t intersection_id = INVALID_INDEX;
|
||
|
|
||
|
const auto& e = edges[eid];
|
||
|
const auto& end_points = e.vertices;
|
||
|
const auto o0 = orientations[end_points[0]];
|
||
|
const auto o1 = orientations[end_points[1]];
|
||
|
|
||
|
intersection_id = end_points[o1 == 0];
|
||
|
// if (o0 == 0) intersection_id = end_points[0];
|
||
|
// if (o1 == 0) intersection_id = end_points[1];
|
||
|
|
||
|
auto compute_intersection_id = [&]() {
|
||
|
if constexpr (N == 2) {
|
||
|
auto p0 = e.supporting_plane;
|
||
|
vertices.push_back({p0, plane_index});
|
||
|
return static_cast<uint32_t>(vertices.size() - 1);
|
||
|
} else {
|
||
|
auto p0 = e.supporting_planes[0];
|
||
|
auto p1 = e.supporting_planes[1];
|
||
|
vertices.push_back({p0, p1, plane_index});
|
||
|
return static_cast<uint32_t>(vertices.size() - 1);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// do nothing if edge is coplanar with plane (o0 == 0 && o1 == 0)
|
||
|
if (o0 >= 0 && o1 >= 0) {
|
||
|
positive_subedge_id = eid;
|
||
|
} else if (o0 <= 0 && o1 <= 0) {
|
||
|
negative_subedge_id = eid;
|
||
|
} else {
|
||
|
ROBUST_ASSERT(intersection_id == INVALID_INDEX);
|
||
|
intersection_id = compute_intersection_id();
|
||
|
IAEdge<N> positive_subedge, negative_subedge;
|
||
|
|
||
|
if (o0 > 0 && o1 < 0) {
|
||
|
positive_subedge.vertices = {end_points[0], intersection_id};
|
||
|
negative_subedge.vertices = {intersection_id, end_points[1]};
|
||
|
} else {
|
||
|
ROBUST_ASSERT(o0 < 0);
|
||
|
ROBUST_ASSERT(o1 > 0);
|
||
|
negative_subedge.vertices = {end_points[0], intersection_id};
|
||
|
positive_subedge.vertices = {intersection_id, end_points[1]};
|
||
|
}
|
||
|
|
||
|
// Update supporting materials.
|
||
|
if constexpr (N == 2) {
|
||
|
positive_subedge.supporting_plane = e.supporting_plane;
|
||
|
negative_subedge.supporting_plane = e.supporting_plane;
|
||
|
positive_subedge.positive_face = e.positive_face;
|
||
|
positive_subedge.negative_face = e.negative_face;
|
||
|
negative_subedge.positive_face = e.positive_face;
|
||
|
negative_subedge.negative_face = e.negative_face;
|
||
|
} else {
|
||
|
positive_subedge.supporting_planes = e.supporting_planes;
|
||
|
negative_subedge.supporting_planes = e.supporting_planes;
|
||
|
}
|
||
|
|
||
|
edges.emplace_back(std::move(positive_subedge));
|
||
|
edges.emplace_back(std::move(negative_subedge));
|
||
|
positive_subedge_id = static_cast<uint32_t>(edges.size() - 2);
|
||
|
negative_subedge_id = static_cast<uint32_t>(edges.size() - 1);
|
||
|
}
|
||
|
return {positive_subedge_id, negative_subedge_id, intersection_id};
|
||
|
}
|
||
|
|
||
|
std::array<uint32_t, 3> ia_cut_1_face(IAComplex<2>& ia_complex, uint32_t eid, uint32_t plane_index, const int8_t* orientations)
|
||
|
{
|
||
|
return ia_cut_1_face_impl(ia_complex, eid, plane_index, orientations);
|
||
|
}
|
||
|
|
||
|
std::array<uint32_t, 3> ia_cut_1_face(IAComplex<3>& ia_complex, uint32_t eid, uint32_t plane_index, const int8_t* orientations)
|
||
|
{
|
||
|
return ia_cut_1_face_impl(ia_complex, eid, plane_index, orientations);
|
||
|
}
|