29 :
m_accessor(m.create_accessor<int64_t>(attribute))
39 std::map<PrimitiveType, attribute::MeshAttributeHandle>& label_handles,
40 const std::vector<int64_t>& input_values,
41 const int64_t output_value)
42 : m_mesh(pos_handle.mesh())
43 , m_pos_handle(pos_handle)
44 , m_input_values(input_values)
45 , m_output_value(output_value)
62 using namespace operations;
65 "todo_edgesplit_in_marching_component",
69 "splitted_edges_in_marching_component",
77 "Only one input value was given. Perform marching in between value {} and any other "
85 std::deque<TagAttribute> filters;
95 bool is_of_interest =
true;
97 if ((filter.m_accessor.const_scalar_attribute(edge) == filter.m_val) ==
99 is_of_interest =
false;
104 if (!is_of_interest) {
137 auto compute_edge_label =
139 const Eigen::MatrixX<int64_t>& labels,
140 const std::vector<Tuple>& tuples) -> Eigen::VectorX<int64_t> {
141 assert(labels.cols() == 2);
142 assert(labels.rows() == 1);
143 assert(tuples.size() == 2);
150 const int64_t val = acc.const_scalar_attribute(tuples[0]);
151 return Eigen::VectorX<int64_t>::Constant(1, val);
154 std::shared_ptr edge_tag_strategy = std::make_shared<
162 SplitBasicStrategy::Copy,
163 SplitRibBasicStrategy::None);
169 auto compute_face_label =
171 const Eigen::MatrixX<int64_t>& labels,
172 const std::vector<Tuple>& tuples) -> Eigen::VectorX<int64_t> {
173 assert(labels.cols() == 3);
174 assert(labels.rows() == 1);
175 assert(tuples.size() == 3);
183 const int64_t val = acc.const_scalar_attribute(tuples[0]);
184 return Eigen::VectorX<int64_t>::Constant(1, val);
187 std::shared_ptr face_tag_strategy = std::make_shared<
195 SplitBasicStrategy::Copy,
196 SplitRibBasicStrategy::None);
202 tmp->set_strategy(SplitBasicStrategy::None);
203 tmp->set_rib_strategy(
213 SplitBasicStrategy::Copy,
214 SplitRibBasicStrategy::None);
221 SplitBasicStrategy::None,
222 SplitRibBasicStrategy::None);
227 SplitBasicStrategy::None,
228 SplitRibBasicStrategy::None);
233 SplitBasicStrategy::None,
234 SplitRibBasicStrategy::None);
244 if (stats.number_of_successful_operations() == 0) {
255 auto inversion_invariant =
267 auto incident_edges =
269 for (
Tuple e : incident_edges) {
289 #if defined(WMTK_ENABLE_HASH_UPDATE)
290 assert(
m_mesh.is_valid_with_hash(v0));
291 assert(
m_mesh.is_valid_with_hash(v1));
296 const auto p0 = pos_acc.const_vector_attribute(v0);
297 const auto p1 = pos_acc.const_vector_attribute(v1);
298 const double sf0 = sf_acc.const_scalar_attribute(v0);
299 const double sf1 = sf_acc.const_scalar_attribute(v1);
301 auto p = pos_acc.vector_attribute(v);
303 const double u = (
m_isovalue - sf0) / (sf1 - sf0);
305 const Eigen::VectorXd p_opt = (1. - u) * p0 + u * p1;
306 const Eigen::VectorXd p_mid = p;
312 if (!inversion_invariant.after({}, tets)) {
321 if (u > 0 && u < 1 && inversion_invariant.after({}, tets)) {
326 Eigen::VectorXd p_valid = p_mid;
327 Eigen::VectorXd p_target = p_opt;
330 bool found_valid_position =
false;
332 p = 0.5 * (p_valid + p_target);
335 if (inversion_invariant.after({}, tets)) {
342 if (p_valid == p_mid) {
344 "Could not find a solution in the linesearch. Using the mid point: {}",
351 const double l = (p1 - p0).norm();
352 const double u_0 = (p - p0).norm() / l;
353 const double u_1 = (p1 - p).norm() / l;
354 const double sf_p = u_0 * sf0 + u_1 * sf1;
355 sf_acc.scalar_attribute(v) = sf_p;
377 pass_through.begin(),
383 const double isovalue)
attribute::TypedAttributeHandle< T > register_attribute_typed(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
virtual bool is_valid(const Tuple &tuple) const
check validity of tuple including its hash
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
SchedulerStats run_operation_on_all(operations::Operation &op)
T & scalar_attribute(const ArgType &t)
T const_scalar_attribute(const ArgType &t) const
auto as() const -> const held_handle_type< held_type_from_primitive< T >()> &
PrimitiveType primitive_type() const
std::vector< attribute::MeshAttributeHandle > m_pass_through_attributes
void add_filter(const attribute::MeshAttributeHandle &label, const int64_t value)
Add an edge filter to marching.
std::vector< int64_t > m_input_values
Marching(attribute::MeshAttributeHandle &pos_handle, std::map< PrimitiveType, attribute::MeshAttributeHandle > &label_handles, const std::vector< int64_t > &input_values, const int64_t output_value)
Initialize the marching method.
std::optional< attribute::MeshAttributeHandle > m_face_tag_handle
std::vector< attribute::MeshAttributeHandle > m_filter_labels
attribute::MeshAttributeHandle m_vertex_tag_handle
void set_isovalue_linesearch_iterations(const int64_t linesearch_iterations)
Set the number of iterations for the linesearch when trying to match the isovalue.
attribute::MeshAttributeHandle m_pos_handle
void invert_filter()
Invert the filter such that everything covered by the filter is ignored.
void add_isovalue(const attribute::MeshAttributeHandle &scalar_field, const double isovalue)
Position the new vertices along an edge according to an isovalue in a scalar field.
int64_t m_linesearch_iterations
void process()
Perform the actual marching.
void add_pass_through(const attribute::MeshAttributeHandle &pass_through)
Add pass through attributes.
std::optional< attribute::MeshAttributeHandle > m_edge_tag_handle
std::optional< attribute::MeshAttributeHandle > m_scalar_field
std::vector< int64_t > m_filter_values
wmtk::attribute::Accessor< int64_t > m_accessor
TagAttribute(Mesh &m, const attribute::MeshAttributeHandle &attribute, PrimitiveType ptype, int64_t val)
TagAttribute(TagAttribute &)=delete
void set_new_attribute_strategy(const attribute::MeshAttributeHandle &attribute, const std::shared_ptr< const operations::BaseSplitNewAttributeStrategy > &other)
void add_invariant(std::shared_ptr< Invariant > invariant)
void add_transfer_strategy(const std::shared_ptr< const operations::AttributeTransferStrategyBase > &other)
void top_dimension_cofaces_tuples(const PointMesh &mesh, const Simplex &simplex, SimplexCollection &collection)
std::vector< Tuple > cofaces_single_dimension_tuples(const Mesh &mesh, const Simplex &my_simplex, PrimitiveType cofaces_type)
void log_and_throw_error(const std::string &msg)
spdlog::logger & logger()
Retrieves the current logger.
Vector< T, Eigen::Dynamic > VectorX