18 int64_t collapse_type,
21 , m_coordinate_handle(coordinate)
22 , m_energy_handle(energy)
23 , m_edge_length_handle(edge_length)
24 , m_target_edge_length_handle(target_edge_length)
25 , m_collapse_type(collapse_type)
36 if (
mesh().top_simplex_type() ==
PT) {
41 auto target_edge_length_accessor =
44 const double current_length = edge_length_accessor.const_scalar_attribute(s.
tuple());
45 const double target_length = target_edge_length_accessor.const_scalar_attribute(s.
tuple());
46 const bool mini_edge = current_length <= target_length *
m_eps;
48 double old_energy_max = std::numeric_limits<double>::lowest();
49 double new_energy_max = std::numeric_limits<double>::lowest();
55 const auto v1_pos = position_accessor.const_vector_attribute(v1);
58 const auto& v0_incident_tets =
60 const auto& v1_incident_tets =
64 for (
const auto& t : v1_incident_tets) {
65 const std::array<Tuple, 4> lv = {
73 std::max(old_energy_max, amips_accessor.const_scalar_attribute(t.tuple()));
95 const std::array<Eigen::Vector<Rational, 3>, 4> lv_pos = {
96 {position_accessor.const_vector_attribute(v0),
97 position_accessor.const_vector_attribute(lv[1]),
98 position_accessor.const_vector_attribute(lv[2]),
99 position_accessor.const_vector_attribute(lv[3])}};
118 {{lv_pos[3][0].to_double(),
119 lv_pos[3][1].to_double(),
120 lv_pos[3][2].to_double(),
121 lv_pos[0][0].to_double(),
122 lv_pos[0][1].to_double(),
123 lv_pos[0][2].to_double(),
124 lv_pos[1][0].to_double(),
125 lv_pos[1][1].to_double(),
126 lv_pos[1][2].to_double(),
127 lv_pos[2][0].to_double(),
128 lv_pos[2][1].to_double(),
129 lv_pos[2][2].to_double()}});
132 {{lv_pos[3][0].to_double(),
133 lv_pos[3][1].to_double(),
134 lv_pos[3][2].to_double(),
135 lv_pos[0][0].to_double(),
136 lv_pos[0][1].to_double(),
137 lv_pos[0][2].to_double(),
138 lv_pos[2][0].to_double(),
139 lv_pos[2][1].to_double(),
140 lv_pos[2][2].to_double(),
141 lv_pos[1][0].to_double(),
142 lv_pos[1][1].to_double(),
143 lv_pos[1][2].to_double()}});
145 new_energy_max = std::max(new_energy_max, new_energy);
149 for (int64_t i = 0; i < 3; ++i) {
151 if (!v1_pos[i].is_rounded())
return true;
160 for (
const auto& t : v0_incident_tets) {
161 const std::array<Tuple, 4> lv = {
186 const double energy = amips_accessor.const_scalar_attribute(t.tuple());
187 old_energy_max = std::max(old_energy_max, energy);
190 new_energy_max = std::max(new_energy_max, energy);
198 const auto v0_pos = position_accessor.const_vector_attribute(v0);
201 const auto& v0_incident_tets =
203 const auto& v1_incident_tets =
207 for (
const auto& t : v0_incident_tets) {
208 const std::array<Tuple, 4> lv = {
216 std::max(old_energy_max, amips_accessor.const_scalar_attribute(t.tuple()));
237 const std::array<Eigen::Vector<Rational, 3>, 4> lv_pos = {
238 {position_accessor.const_vector_attribute(v1),
239 position_accessor.const_vector_attribute(lv[1]),
240 position_accessor.const_vector_attribute(lv[2]),
241 position_accessor.const_vector_attribute(lv[3])}};
260 {{lv_pos[3][0].to_double(),
261 lv_pos[3][1].to_double(),
262 lv_pos[3][2].to_double(),
263 lv_pos[0][0].to_double(),
264 lv_pos[0][1].to_double(),
265 lv_pos[0][2].to_double(),
266 lv_pos[1][0].to_double(),
267 lv_pos[1][1].to_double(),
268 lv_pos[1][2].to_double(),
269 lv_pos[2][0].to_double(),
270 lv_pos[2][1].to_double(),
271 lv_pos[2][2].to_double()}});
274 {{lv_pos[3][0].to_double(),
275 lv_pos[3][1].to_double(),
276 lv_pos[3][2].to_double(),
277 lv_pos[0][0].to_double(),
278 lv_pos[0][1].to_double(),
279 lv_pos[0][2].to_double(),
280 lv_pos[2][0].to_double(),
281 lv_pos[2][1].to_double(),
282 lv_pos[2][2].to_double(),
283 lv_pos[1][0].to_double(),
284 lv_pos[1][1].to_double(),
285 lv_pos[1][2].to_double()}});
287 new_energy_max = std::max(new_energy_max, new_energy);
291 for (int64_t i = 0; i < 3; ++i) {
293 if (!v0_pos[i].is_rounded())
return true;
302 for (
const auto& t : v1_incident_tets) {
303 const std::array<Tuple, 4> lv = {
328 const double energy = amips_accessor.const_scalar_attribute(t.tuple());
329 old_energy_max = std::max(old_energy_max, energy);
332 new_energy_max = std::max(new_energy_max, energy);
339 throw std::runtime_error(
"not implemented");
342 default:
throw std::runtime_error(
"Invalid collapse type");
345 return new_energy_max <= old_energy_max;
347 }
else if (
mesh().top_simplex_type() ==
PF) {
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
virtual bool is_ccw(const Tuple &tuple) const =0
TODO this needs dimension?
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
Handle that represents attributes for some mesh.
const attribute::TypedAttributeHandle< Rational > m_coordinate_handle
const attribute::TypedAttributeHandle< double > m_target_edge_length_handle
const int64_t m_collapse_type
const attribute::TypedAttributeHandle< double > m_energy_handle
bool before(const simplex::Simplex &s) const override
CollapseSoftEnergyBeforeInvariant(const Mesh &m, const attribute::TypedAttributeHandle< Rational > &coordinate, const attribute::TypedAttributeHandle< double > &energy, const attribute::TypedAttributeHandle< double > &edge_length, const attribute::TypedAttributeHandle< double > &target_edge_length, int64_t collapse_type=0, double eps=0.1)
const attribute::TypedAttributeHandle< double > m_edge_length_handle
const Mesh & mesh() const
const Tuple & tuple() const
static Simplex vertex(const Mesh &m, const Tuple &t)
static bool equal(const Mesh &m, const Simplex &s0, const Simplex &s1)
constexpr wmtk::PrimitiveType PT
constexpr wmtk::PrimitiveType PF
double Tet_AMIPS_energy(const std::array< double, 12 > &T)
void top_dimension_cofaces(const Simplex &simplex, SimplexCollection &simplex_collection, const bool sort_and_clean)
Get all top dimension cofaces of the given simplex.
int wmtk_orient3d(const Eigen::Ref< const Eigen::Vector3< Rational >> &p0, const Eigen::Ref< const Eigen::Vector3< Rational >> &p1, const Eigen::Ref< const Eigen::Vector3< Rational >> &p2, const Eigen::Ref< const Eigen::Vector3< Rational >> &p3)
constexpr PrimitiveType PV
constexpr PrimitiveType PE