extract explicit mesh with topology information from implicit surfaces with boolean operations, and do surface/volume integrating on them.
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.
 
 
 

96 lines
2.8 KiB

// BITSET2
//
// Copyright Claas Bontus
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ClaasBontus/bitset2
//
#pragma once
#include "h_types.hpp"
#include <climits>
#include <algorithm>
namespace detail
{
template <size_t n_words, class T>
struct hash_impl {
using base_t = T;
using result_type = std::size_t;
using array_t = typename h_types<T>::template array_t<n_words>;
enum : size_t {
size_t_bits = sizeof(result_type) * CHAR_BIT ///< #bits in result_type
,
base_t_n_bits = h_types<T>::base_t_n_bits ///< #bits in T
,
bits_mod = base_t_n_bits % size_t_bits,
bits_div = base_t_n_bits / size_t_bits + (bits_mod > 0),
size_t_mod = size_t_bits % base_t_n_bits,
size_t_div = size_t_bits / base_t_n_bits
};
enum : bool { easy_bits = (size_t_bits >= base_t_n_bits), easy_ratio = (size_t_mod == 0) };
result_type operator()(array_t const &arr) const noexcept
{
if (n_words == 0) return 0;
if (n_words == 1) {
if (easy_bits) return arr[0];
return to_result_t(arr[0]);
} // if n_words == 1
return cmpsd_hash(arr);
}
result_type to_result_t(base_t a) const noexcept
{
result_type ret_val = 0;
size_t shft = 0;
for (size_t c = 0; c < bits_div; ++c, shft += size_t_bits) {
auto const crrnt = result_type(a >> shft);
do_combine(ret_val, crrnt, c);
}
return ret_val;
} // to_result_t
result_type cmpsd_hash(array_t const &arr) const noexcept
{
result_type ret_val = 0;
if (easy_ratio) {
for (size_t c = 0; c < n_words; c += size_t_div) {
result_type r = 0;
auto const uppr = std::min(n_words, c + size_t_div);
for (size_t w = c; w < uppr; ++w) r |= (result_type(arr[w]) << ((w - c) * base_t_n_bits));
do_combine(ret_val, r, c / size_t_div);
}
} else {
for (size_t c = 0; c < n_words; ++c) {
auto const crrnt = easy_bits ? result_type(arr[c]) : to_result_t(arr[c]);
do_combine(ret_val, crrnt, c);
}
}
return ret_val;
} // cmpsd_hash
void do_combine(result_type &r, result_type crrnt, size_t cnt) const noexcept
{
crrnt += cnt;
auto const n_rot = cnt % size_t_bits;
if (n_rot > 0) crrnt = (crrnt << n_rot) | (crrnt >> (size_t_bits - n_rot));
r ^= crrnt;
} // do_combine
}; // struct hash_impl
} // namespace detail