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.
134 lines
6.3 KiB
134 lines
6.3 KiB
#pragma once
|
|
|
|
#include <container/hashmap.hpp>
|
|
|
|
#include <utils/fwd_types.hpp>
|
|
|
|
struct simplified_vertex_header_t {
|
|
uint32_t volume_index{};
|
|
uint32_t local_vertex_index{};
|
|
};
|
|
|
|
struct component_header_t {
|
|
uint32_t vertex_index{};
|
|
uint32_t component_index{};
|
|
};
|
|
|
|
struct face_with_orient_t {
|
|
uint32_t face_id{};
|
|
int8_t orient{};
|
|
};
|
|
|
|
namespace std
|
|
{
|
|
template <>
|
|
struct hash<simplified_vertex_header_t> {
|
|
size_t operator()(const simplified_vertex_header_t &k) const
|
|
{
|
|
return (static_cast<size_t>(k.volume_index) << 32) | k.local_vertex_index;
|
|
// return std::hash<uint32_t>()(k.volume_index) ^ std::hash<uint32_t>()(k.local_vertex_index);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hash<component_header_t> {
|
|
size_t operator()(const component_header_t &k) const
|
|
{
|
|
return (static_cast<size_t>(k.vertex_index) << 32) | k.component_index;
|
|
// return std::hash<uint32_t>()(k.vertex_index) ^ std::hash<uint32_t>()(k.component_index);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hash<face_with_orient_t> {
|
|
size_t operator()(const face_with_orient_t &k) const
|
|
{
|
|
return (static_cast<size_t>(k.face_id) << 32) | k.orient;
|
|
// return std::hash<uint32_t>()(k.face_id) ^ std::hash<int8_t>()(k.orient);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct equal_to<simplified_vertex_header_t> {
|
|
bool operator()(const simplified_vertex_header_t &k1, const simplified_vertex_header_t &k2) const
|
|
{
|
|
return k1.volume_index == k2.volume_index && k1.local_vertex_index == k2.local_vertex_index;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct equal_to<component_header_t> {
|
|
bool operator()(const component_header_t &k1, const component_header_t &k2) const
|
|
{
|
|
return k1.vertex_index == k2.vertex_index && k1.component_index == k2.component_index;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct equal_to<face_with_orient_t> {
|
|
bool operator()(const face_with_orient_t &k1, const face_with_orient_t &k2) const
|
|
{
|
|
return k1.face_id == k2.face_id && k1.orient == k2.orient;
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
// topological ray shooting for implicit arrangement
|
|
ISNP_API void topo_ray_shooting(const tetrahedron_mesh_t &tet_mesh,
|
|
const stl_vector_mp<std::shared_ptr<arrangement_t>> &cut_results,
|
|
const stl_vector_mp<iso_vertex_t> &iso_verts,
|
|
const stl_vector_mp<polygon_face_t> &iso_faces,
|
|
const stl_vector_mp<stl_vector_mp<uint32_t>> &patches,
|
|
const stl_vector_mp<uint32_t> &patch_of_face,
|
|
const stl_vector_mp<stl_vector_mp<uint32_t>> &shells,
|
|
const stl_vector_mp<uint32_t> &shell_of_half_patch,
|
|
const stl_vector_mp<stl_vector_mp<uint32_t>> &components,
|
|
const stl_vector_mp<uint32_t> &component_of_patch,
|
|
stl_vector_mp<std::pair<uint32_t, uint32_t>> &shell_links);
|
|
|
|
// Given tet mesh,
|
|
// build the map: v-->v_next, where v_next has lower order than v
|
|
ISNP_API void build_next_vert(const tetrahedron_mesh_t &tet_mesh, stl_vector_mp<uint32_t> &next_vert);
|
|
|
|
// find extremal edge for each component
|
|
ISNP_API void find_extremal_edges(const stl_vector_mp<raw_point_t> &pts,
|
|
const stl_vector_mp<iso_vertex_t> &iso_verts,
|
|
const stl_vector_mp<polygon_face_t> &iso_faces,
|
|
const stl_vector_mp<stl_vector_mp<uint32_t>> &patches,
|
|
const stl_vector_mp<stl_vector_mp<uint32_t>> &components,
|
|
const stl_vector_mp<uint32_t> &component_of_patch,
|
|
const stl_vector_mp<uint32_t> &next_vert,
|
|
// extremal edge of component i is stored at position [2*i], [2*i+1]
|
|
stl_vector_mp<uint32_t> &extremal_edge_of_component,
|
|
// store an iso-vert index on edge (v, v_next), None means there is no such iso-vert
|
|
stl_vector_mp<uint32_t> &iso_vert_on_v_v_next,
|
|
// map: (tet_id, tet_face_id) --> iso_face_id
|
|
flat_hash_map_mp<face_header_t, uint32_t> &iso_face_id_of_tet_face,
|
|
// map: (tet_id, tet_vert_id) --> (iso_vert_id, component_id)
|
|
flat_hash_map_mp<simplified_vertex_header_t, component_header_t> &iso_vId_compId_of_tet_vert);
|
|
|
|
// compute the order of iso-vertices on a tet edge v->u, v,u in {0,1,2,3}
|
|
// return a list of sorted vertex indices {v_id, i1, i2, ..., u_id}
|
|
ISNP_API void compute_edge_intersection_order(const arrangement_t &tet_cut_result,
|
|
uint32_t v,
|
|
uint32_t u,
|
|
stl_vector_mp<uint32_t> &vert_indices);
|
|
|
|
// find the two faces passing v1 and v2, v1->v2 is part of a tet edge
|
|
ISNP_API void compute_passing_face_pair(const arrangement_t &tet_cut_result,
|
|
uint32_t v1,
|
|
uint32_t v2,
|
|
face_with_orient_t &face_orient1,
|
|
face_with_orient_t &face_orient2);
|
|
|
|
// find the face passing v, v->u is part of a tet edge, and u is a tet vertex
|
|
ISNP_API void compute_passing_face(const arrangement_t &tet_cut_result,
|
|
uint32_t v,
|
|
uint32_t u,
|
|
face_with_orient_t &face_orient);
|
|
|
|
// point (x,y,z): dictionary order
|
|
inline bool point_xyz_less(const raw_point_t &p, const raw_point_t &q)
|
|
{
|
|
return std::lexicographical_compare(p.begin(), p.end(), q.begin(), q.end());
|
|
}
|