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.
104 lines
3.1 KiB
104 lines
3.1 KiB
#include <container/hashmap.hpp>
|
|
#include <algorithm/glue_algorithm.hpp>
|
|
#include <implicit_predicates.h>
|
|
|
|
#include "ia_cut_face.hpp"
|
|
#include "robust_assert.hpp"
|
|
|
|
inline int8_t signof(Orientation o)
|
|
{
|
|
ROBUST_ASSERT(o != ORIENTATION_INVALID);
|
|
if (o > 0)
|
|
return 1;
|
|
else if (o < 0)
|
|
return -1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
#ifdef LUT_GENERATE
|
|
extern std::array<std::array<bool, 3>, 4> vertex_signs;
|
|
extern std::array<bool, 6> edge_signs;
|
|
|
|
template <size_t N>
|
|
static inline int8_t ia_cut_0_face_impl(const PlaneGroup<N>& planes,
|
|
const IAComplex<N>& ia_complex,
|
|
uint32_t vid,
|
|
uint32_t plane_index)
|
|
{
|
|
ROBUST_ASSERT(plane_index == 4 || plane_index == 5);
|
|
const auto& v = ia_complex.vertices[vid];
|
|
|
|
if (v.i0 < 4 && v.i1 < 4 && v.i2 < 4) {
|
|
// Case 1: v is a tet vertex.
|
|
for (size_t i = 0; i < 4; i++) {
|
|
if (i != v.i0 && i != v.i1 && i != v.i2) { return vertex_signs[i][plane_index - 4] ? 1 : -1; }
|
|
}
|
|
ROBUST_ASSERT(false);
|
|
}
|
|
|
|
// Case 2: v is on a tet edge.
|
|
ROBUST_ASSERT(plane_index == 5);
|
|
auto edge_key = INVALID_INDEX;
|
|
auto P1 = INVALID_INDEX, P2 = INVALID_INDEX;
|
|
for (size_t i = 0; i < 3; i++) {
|
|
if ((&v.i0)[i] < 4) {
|
|
if (P1 == INVALID_INDEX) {
|
|
P1 = (&v.i0)[i];
|
|
} else {
|
|
P2 = (&v.i0)[i];
|
|
}
|
|
}
|
|
}
|
|
if (P1 > P2) std::swap(P1, P2);
|
|
|
|
if (P1 == 0 && P2 == 1) {
|
|
edge_key = 5;
|
|
} else if (P1 == 0 && P2 == 2) {
|
|
edge_key = 4;
|
|
} else if (P1 == 0 && P2 == 3) {
|
|
edge_key = 3;
|
|
} else if (P1 == 1 && P2 == 2) {
|
|
edge_key = 2;
|
|
} else if (P1 == 1 && P2 == 3) {
|
|
edge_key = 1;
|
|
} else if (P1 == 2 && P2 == 3) {
|
|
edge_key = 0;
|
|
}
|
|
|
|
return edge_signs[edge_key] ? 1 : -1;
|
|
}
|
|
#else
|
|
template <size_t N>
|
|
static inline int8_t ia_cut_0_face_impl(const PlaneGroup<N>& planes,
|
|
const IAComplex<N>& ia_complex,
|
|
uint32_t vid,
|
|
uint32_t plane_index)
|
|
{
|
|
const auto& p = planes.get_plane(plane_index);
|
|
const auto& v = ia_complex.vertices[vid];
|
|
const auto& p0 = planes.get_plane(v.i0);
|
|
const auto& p1 = planes.get_plane(v.i1);
|
|
|
|
if constexpr (N == 2) {
|
|
return signof(orient2d(&p0.f0, &p1.f0, &p.f0));
|
|
} else {
|
|
const auto& p2 = planes.get_plane(v.i2);
|
|
return signof(orient3d(&p0.f0, &p1.f0, &p2.f0, &p.f0));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
int8_t ia_cut_0_face(const PlaneGroup2D& planes, const IAComplex<2>& ia_complex, uint32_t vid, uint32_t plane_index)
|
|
{
|
|
#ifdef LUT_GENERATE
|
|
throw std::runtime_error("Only 3D lookup table generation is supported.");
|
|
#else
|
|
return ia_cut_0_face_impl<2>(planes, ia_complex, vid, plane_index);
|
|
#endif
|
|
}
|
|
|
|
int8_t ia_cut_0_face(const PlaneGroup3D& planes, const IAComplex<3>& ia_complex, uint32_t vid, uint32_t plane_index)
|
|
{
|
|
return ia_cut_0_face_impl<3>(planes, ia_complex, vid, plane_index);
|
|
}
|