diff --git a/docs/algorithms.rst b/docs/algorithms.rst index f1779f9ba2c10e447f9780ccaf17e9facb017121..01273ecf62494f3c8d82ccf39b30c758db9c2f3d 100644 --- a/docs/algorithms.rst +++ b/docs/algorithms.rst @@ -60,6 +60,145 @@ A small helper that merges vertices based on a user criterion. .. doxygenfunction:: polymesh::deduplicate + +Delaunay +-------- + +An incomplete collection of algorithms for Delaunay triangulations. + +:: + + #include <polymesh/algorithms/delaunay.hh> + + pm::Mesh m; + auto pos = m.vertices().make_attribute<tg::pos3>(); + load(...); + + // makes mesh surface delaunay via flipping + pm::make_delaunay(m, pos); + +.. doxygenfunction:: polymesh::make_delaunay + +There is also a 2D version that starts with a vertex-only mesh and creates faces via 2D Delaunay: + +.. doxygenfunction:: polymesh::create_delaunay_triangulation + + +Edge Split +---------- + +A generic edge splitting routine. + +:: + + #include <polymesh/algorithms/edge_split.hh> + + pm::Mesh m; + auto pos = m.vertices().make_attribute<tg::pos3>(); + load(...); + + auto const target_edge_length = 0.1f; + + // split all edges longer than 0.1 in descending length order + pm::split_edges_trimesh(m, + // function to provide a priority value and signal if the edge should not be split + [&](pm::edge_handle e) -> tg::optional<float> { + auto const l = pm::edge_length(e, pos); + if (l < target_edge_length) + return {}; + return l; + }, + // a function performing the split + [&](pm::vertex_handle v, pm::halfedge_handle, pm::vertex_handle v_from, pm::vertex_handle v_to) { + pos[v] = mix(pos[v_to], pos[v_from], 0.5f); + // .. and propagate other attributes if desire + }); + +For polygonal meshes, splitting edges can either be very simple (only insert a vertex) or complex (re-triangulate polygons, ensure user constraints). +The following function provides a generic interface: + +.. doxygenfunction:: polymesh::split_edges + +If the mesh is known to be triangular (and should stay triangular), then the split is well defined and the split function only has to fill in missing attributes: + +.. doxygenfunction:: polymesh::split_edges_trimesh + +These functions guarantee that meshes stay *compact* (see :ref:`memory-model`) and are, in general, quite fast. + + +Normal Estimation +----------------- + +A simple estimation algorithm for computing smoothed vertex normals. +Edges that should not be smoothed over can be declared in a generic interface. + +:: + + #include <polymesh/algorithms/normal_estimation.hh> + + pm::Mesh m; + auto pos = m.vertices().make_attribute<tg::pos3>(); + load(...); + + auto fnormals = pm::face_normals(pos); + + // compute smooth vertex normals without smoothing over more than 60° edges + auto vnormals = pm::normal_estimation(fnormals, [&](pm::edge_handle e) { + return dot(fnormals[e.faceA()], fnormals[e.faceB()]) < 0.5; + }); + + // .. or just smooth over everything + auto vnormals2 = pm::normal_estimation(pos, [](auto) { return false; }); + +This function has two versions, one based on face normals, the other on vertex positions (which internally computes face normals): + +.. doxygenfunction:: polymesh::normal_estimation(face_attribute<Vec3> const&, IsHardEdgeF&&) + +.. doxygenfunction:: polymesh::normal_estimation(vertex_attribute<Pos3> const&, IsHardEdgeF&&) + + +Normalization +------------- + +An incomplete collection of helpers for ensuring different normalization constraints. + +:: + + #include <polymesh/algorithms/normalize.hh> + + pm::Mesh m; + auto pos = m.vertices().make_attribute<tg::pos3>(); + load(...); + + // translates and uniformly rescales the mesh + // so it fits in the [-1, 1] cube and is centered at the origin + pm::normalize(pos); + +.. doxygenfunction:: polymesh::normalize + + +Cache Optimization +------------------ + +An incomplete collection of algorithms that reorder the internal memory layout to improve cache coherence in different scenarios. + +:: + + #include <polymesh/algorithms/cache-optimization.hh> + + pm::Mesh m; + load(...); + + // reorder memory layout for improved performance when performing vertex-traversal algorithms + pm::optimize_for_vertex_traversal(m); + + +.. doxygenfunction:: polymesh::optimize_for_face_traversal + +.. doxygenfunction:: polymesh::optimize_for_vertex_traversal + + + TODO: preserve line breaks in doxygen -TODO: decimate, dedup, delaunay, edge_split, subdivision, interpolation, iteration, normal-estimation, normalize, operations, optimizations, sampling, smoothing, stats, topology, tracing, triangulate +TODO: decimate, subdivision, interpolation, iteration, sampling, smoothing, stats, topology, tracing, triangulate diff --git a/docs/mesh-topology.rst b/docs/mesh-topology.rst index 72fa4788b7f40fac7d2c9643b8f4102f99dbc341..7185499368df63e290ea5a7e54d9105bd0ff6b90 100644 --- a/docs/mesh-topology.rst +++ b/docs/mesh-topology.rst @@ -43,6 +43,7 @@ Functions returning a mesh with new ownership should use ``std::unique_ptr<pm::M :func:`polymesh::Mesh::create` is a static helper function to create a ``unique_ptr<Mesh>`` though the typical way to just use ``pm::Mesh`` as a member or as a local variable. +.. _memory-model: Memory Model ------------ diff --git a/docs/reference.rst b/docs/reference.rst index 675a7940671feedbd09dff8b4ad3f00983cb9e1e..8ff3de521ea509eecf24167236be43d5ab81ad14 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -215,6 +215,40 @@ Algorithms .. doxygenfunction:: polymesh::deduplicate +.. doxygenfunction:: polymesh::make_delaunay + +.. doxygenfunction:: polymesh::create_delaunay_triangulation + +.. doxygenfunction:: polymesh::split_edges + +.. doxygenfunction:: polymesh::split_edges_trimesh + +.. doxygenfunction:: polymesh::normal_estimation(face_attribute<Vec3> const&, IsHardEdgeF&&) + +.. doxygenfunction:: polymesh::normal_estimation(vertex_attribute<Pos3> const&, IsHardEdgeF&&) + +.. doxygenfunction:: polymesh::normalize + +.. doxygenfunction:: polymesh::remove_faces + +.. doxygenfunction:: polymesh::remove_edges_and_faces + +.. doxygenfunction:: polymesh::optimize_for_face_traversal + +.. doxygenfunction:: polymesh::optimize_for_vertex_traversal + +.. doxygenfunction:: polymesh::optimize_edges_for_faces + +.. doxygenfunction:: polymesh::optimize_vertices_for_faces + +.. doxygenfunction:: polymesh::optimize_edges_for_vertices + +.. doxygenfunction:: polymesh::optimize_faces_for_vertices + +.. doxygenfunction:: polymesh::cache_coherent_face_layout + +.. doxygenfunction:: polymesh::cache_coherent_vertex_layout + Low-Level API ------------- diff --git a/src/polymesh/algorithms.hh b/src/polymesh/algorithms.hh index bc6d5db191f75a5dc4d9dd031598b08314a16127..759b1c26072a9ea192c0f5d6219ddb732f7e41a2 100644 --- a/src/polymesh/algorithms.hh +++ b/src/polymesh/algorithms.hh @@ -15,6 +15,7 @@ // - intersections // - statistics +#include "algorithms/cache-optimization.hh" #include "algorithms/components.hh" #include "algorithms/decimate.hh" #include "algorithms/deduplicate.hh" @@ -24,7 +25,6 @@ #include "algorithms/iteration.hh" #include "algorithms/normalize.hh" #include "algorithms/operations.hh" -#include "algorithms/optimization.hh" #include "algorithms/sampling.hh" #include "algorithms/smoothing.hh" #include "algorithms/stats.hh" diff --git a/src/polymesh/algorithms/optimization.cc b/src/polymesh/algorithms/cache-optimization.cc similarity index 99% rename from src/polymesh/algorithms/optimization.cc rename to src/polymesh/algorithms/cache-optimization.cc index 5ff1291563a473c5949ea096cbd782957a992dc9..b4833d172ba2c95e36018e74ac68c976b5c5da32 100644 --- a/src/polymesh/algorithms/optimization.cc +++ b/src/polymesh/algorithms/cache-optimization.cc @@ -1,4 +1,4 @@ -#include "optimization.hh" +#include "cache-optimization.hh" #include <polymesh/detail/permutation.hh> #include <polymesh/detail/random.hh> diff --git a/src/polymesh/algorithms/optimization.hh b/src/polymesh/algorithms/cache-optimization.hh similarity index 100% rename from src/polymesh/algorithms/optimization.hh rename to src/polymesh/algorithms/cache-optimization.hh diff --git a/src/polymesh/algorithms/normalize.hh b/src/polymesh/algorithms/normalize.hh index cc354c6b83be510eff8ce807cb8328e235188e42..e1340d31c1665dd1253b1f7bad983aac8744dc28 100644 --- a/src/polymesh/algorithms/normalize.hh +++ b/src/polymesh/algorithms/normalize.hh @@ -5,7 +5,7 @@ namespace polymesh { -// Applies a translation and a uniform rescaling such that the mesh is centerd at (0,0,0) and withing the [-1 .. 1] cube +/// Applies a translation and a uniform rescaling such that the mesh is centerd at (0,0,0) and within the [-1 .. 1] cube template <class Pos3> void normalize(vertex_attribute<Pos3>& pos) {