Commit 1364013e authored by Philip Trettner's avatar Philip Trettner
Browse files

more docs

parent 49b36c45
Algorithms
==========
TODO
The headers located in ``polymesh/algorithms/*`` or included by ``polymesh/algorithms.hh`` contain useful algorithms operating on meshes.
In contrast to the :doc:`properties` or the functional-inspired :doc:`smart-ranges`, these algorithms are often non-trivial and perform substantial transformations on the mesh.
As most built-in geometry-related methods, the algorithms tend to be very generic, providing extensive customization points and using the :doc:`vector-math` wrapper to support many different math types.
A reference of all algorithms can be found in :ref:`algorithms-ref`.
Components
----------
This category of algorithms contains methods to compute connected components on meshes.
::
#include <polymesh/algorithms/components.hh>
pm::Mesh m;
load(m, /* ... */);
// computes all vertex components of the mesh
int vcomp_count;
auto vcomp = pm::vertex_components(m, vcomp_count);
for (auto v : m.vertices())
std::cout << "vertex " << int(v) << " belongs to component " << vcomp[v] << " of " << vcomp_count << std::endl;
// special iterator to iterate over a single component
pm::face_handle f = /* ... */;
for (auto ff : pm::face_component(f))
std::cout << "face " << int(ff) << " is in the same connected component as face " << int(f) << std::endl;
.. doxygenfunction:: polymesh::vertex_components
.. doxygenfunction:: polymesh::face_components
.. doxygenfunction:: polymesh::vertex_component
.. doxygenfunction:: polymesh::face_component(face_handle)
.. doxygenfunction:: polymesh::face_component(vertex_handle)
Deduplicate
-----------
A small helper that merges vertices based on a user criterion.
::
#include <polymesh/algorithms/deduplicate.hh>
pm::Mesh m;
auto pos = m.vertices().make_attribute<tg::pos3>();
load("some-file.stl", m, pos);
// merges all vertices with the same position
pm::deduplicate(m, pos);
.. doxygenfunction:: polymesh::deduplicate
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
......@@ -160,6 +160,8 @@ Geometric Properties
.. doxygenfunction:: polymesh::bary_interpolate
.. doxygenfunction:: polymesh::barycoords_of
.. doxygenfunction:: polymesh::edge_length(edge_handle, vertex_attribute<Pos3> const&)
.. doxygenfunction:: polymesh::edge_length(halfedge_handle, vertex_attribute<Pos3> const&)
......@@ -196,6 +198,24 @@ Geometric Properties
.. doxygenfunction:: polymesh::can_collapse_without_flips
.. _algorithms-ref:
Algorithms
----------
.. doxygenfunction:: polymesh::vertex_components
.. doxygenfunction:: polymesh::face_components
.. doxygenfunction:: polymesh::vertex_component
.. doxygenfunction:: polymesh::face_component(face_handle)
.. doxygenfunction:: polymesh::face_component(vertex_handle)
.. doxygenfunction:: polymesh::deduplicate
Low-Level API
-------------
......
......@@ -236,7 +236,7 @@ private:
};
} // namespace polymesh
/// ======== IMPLEMENTATIONS ========
// ======== IMPLEMENTATIONS ========
#include "impl/impl_attributes.hh"
#include "impl/impl_cursors.hh"
......
#pragma once
#include "../Mesh.hh"
#include "../fields.hh"
namespace polymesh
{
/// calculates the barycentric coordinates of a given point p within a face f
/// NOTE: asserts that f is triangular
/// NOTE: also works for other points in the same plane as f
template <class Pos3, class Scalar = typename field3<Pos3>::scalar_t>
std::array<Scalar, 3> barycoords(face_handle f, vertex_attribute<Pos3> const& positions, Pos3 p);
/// ======== IMPLEMENTATION ========
template <class Pos3, class Scalar>
std::array<Scalar, 3> barycoords(face_handle f, vertex_attribute<Pos3> const& positions, Pos3 p)
{
POLYMESH_ASSERT(f.vertices().size() == 3 && "only supports triangles");
auto ps = f.vertices().to_array<3>(positions);
auto e10 = ps[1] - ps[0];
auto e21 = ps[2] - ps[1];
auto n = field3<Pos3>::cross(e10, e21);
auto signed_area = [&](Pos3 const& v0, Pos3 const& v1, Pos3 const& v2) {
auto d1 = v1 - v0;
auto d2 = v2 - v0;
auto a = field3<Pos3>::cross(d1, d2);
return field3<Pos3>::dot(a, n);
};
auto a = signed_area(ps[0], ps[1], ps[2]);
auto a0 = signed_area(p, ps[1], ps[2]);
auto a1 = signed_area(p, ps[2], ps[0]);
auto a2 = signed_area(p, ps[0], ps[1]);
auto inv_a = Scalar(1) / a;
return {a0 * inv_a, a1 * inv_a, a2 * inv_a};
}
}
......@@ -23,9 +23,11 @@ detail::bfs_range<vertex_tag> vertex_component(vertex_handle v);
/// returns a range that iterates over all connected faces in BFS order
detail::bfs_range<face_tag> face_component(face_handle f);
/// returns a range that iterates over all connected faces in BFS order
detail::bfs_range<face_tag> face_component(vertex_handle v);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
inline detail::bfs_range<vertex_tag> vertex_component(vertex_handle v) { return {v}; }
inline detail::bfs_range<face_tag> face_component(face_handle f) { return {f}; }
......
......@@ -76,7 +76,7 @@ struct decimate_config
}
};
/*
/**
* Error-function-based incremental decimation
*
* Initial per-vertex errors must be provided in vertex_errors
......@@ -97,6 +97,7 @@ void decimate(pm::Mesh& m, //
pm::vertex_attribute<ErrorF>& errors,
ConfigT const& config);
/// calls decimate with a default configuration that decimates until a target vertex count is reached
template <class Pos3, class ErrorF>
void decimate_down_to(pm::Mesh& m, //
pm::vertex_attribute<Pos3>& pos,
......@@ -106,6 +107,7 @@ void decimate_down_to(pm::Mesh& m, //
return decimate(m, pos, errors, decimate_config<Pos3, ErrorF>::down_to(target_vertex_cnt));
}
/// calls decimate with a default configuration that decimates until a target error value is reached
template <class Pos3, class ErrorF, class ErrorValueT>
void decimate_up_to_error(pm::Mesh& m, //
pm::vertex_attribute<Pos3>& pos,
......
......@@ -23,10 +23,12 @@ namespace polymesh
/// CAUTION: currently only works on faces and will remove isolated vertices/edges
///
/// returns number of removed vertices (-1 if deduplication failed (e.g. due to non-manifoldness))
///
/// TODO: use a function_ref and implement this in a .cc
template <class KeyF>
int deduplicate(Mesh& m, KeyF&& kf);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class KeyF>
int deduplicate(Mesh& m, KeyF&& kf)
......
......@@ -49,7 +49,7 @@ T interpolate(handle_t h, attr_t<T> const& attr, W const* ws, int wcnt);
template <class T, class WeightFuncT, class handle_t, template <class> class attr_t, class Enabled = decltype(std::declval<WeightFuncT>()(0, typename primitive<typename attr_t<T>::tag_t>::handle{}))>
T interpolate(handle_t h, attr_t<T> const& attr, WeightFuncT&& wh);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
namespace detail
{
......
......@@ -13,7 +13,7 @@ void remove_faces(Mesh& m);
/// NOTE: does NOT compactify!
void remove_edges_and_faces(Mesh& m);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
inline void remove_faces(Mesh& m)
{
......
......@@ -18,7 +18,7 @@ namespace polymesh
template <class Vec3 = void>
void print_stats(std::ostream& out, Mesh const& m, vertex_attribute<Vec3> const* position = nullptr);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class Vec3>
void print_stats(std::ostream& out, Mesh const& m, vertex_attribute<Vec3> const* position)
{
......
......@@ -9,7 +9,7 @@ namespace polymesh
template <class VertexF>
void subdivide_sqrt3(Mesh& m, VertexF&& vf);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class VertexF>
void subdivide_sqrt3(Mesh& m, VertexF&& vf)
......
......@@ -10,7 +10,7 @@ namespace polymesh
/// (i.e. the last face that would be visited in a BFS)
face_handle farthest_face(face_handle f);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
inline face_handle farthest_face(face_handle f)
{
......
......@@ -16,7 +16,7 @@ namespace polymesh
template <class Scalar = float, class EdgeLengthF>
std::pair<halfedge_handle, float> trace_step(halfedge_handle h, EdgeLengthF&& edge_length, Scalar x, Scalar d1_sqr, Scalar d2_sqr);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class Scalar, class EdgeLengthF>
std::pair<halfedge_handle, float> trace_step(halfedge_handle h, EdgeLengthF&& edge_length, Scalar x, Scalar d1_sqr, Scalar d2_sqr)
......
......@@ -106,7 +106,7 @@ private:
attribute<enum_t> entries;
};
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class enum_t, class mesh_ptr, class tag, class iterator>
flags<enum_t, tag> make_flags(smart_collection<mesh_ptr, tag, iterator> const& c, enum_t initial_value)
......
......@@ -84,7 +84,7 @@ private:
int partitions;
};
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class mesh_ptr, class tag, class iterator>
partitioning<tag> make_partitioning(smart_collection<mesh_ptr, tag, iterator> const& c)
......
......@@ -19,7 +19,7 @@ bool is_valid_permutation(std::vector<int> const& p);
/// p[curr_idx] = new_idx
std::vector<std::pair<int, int>> transpositions_of(std::vector<int> const& p);
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
inline bool is_valid_permutation(std::vector<int> const& p)
{
......
......@@ -13,7 +13,7 @@ namespace polymesh::objects
template <class coneF>
auto add_cone(Mesh& m, coneF&& qf, int segments, bool closed = true) -> decltype(qf(vertex_handle{}, float{}, float{}), vertex_handle{});
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class coneF>
auto add_cone(Mesh& m, coneF&& qf, int segments, bool closed) -> decltype(qf(vertex_handle{}, float{}, float{}), vertex_handle{})
......
......@@ -18,7 +18,7 @@ auto add_cube(Mesh& m, CubeF&& cf) -> decltype(cf(vertex_handle{}, int{}, int{},
template <class Pos3>
auto add_cube(Mesh& m, vertex_attribute<Pos3>& pos) -> vertex_handle;
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class Pos3>
auto add_cube(Mesh& m, vertex_attribute<Pos3>& pos) -> vertex_handle
......
......@@ -13,7 +13,7 @@ namespace polymesh::objects
template <class CylinderF>
auto add_cylinder(Mesh& m, CylinderF&& qf, int segments, bool closed = true) -> decltype(qf(vertex_handle{}, float{}, float{}), vertex_handle{});
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class CylinderF>
auto add_cylinder(Mesh& m, CylinderF&& qf, int segments, bool closed) -> decltype(qf(vertex_handle{}, float{}, float{}), vertex_handle{})
......
......@@ -14,7 +14,7 @@ namespace objects
template <class QuadF>
auto add_quad(Mesh& m, QuadF&& qf, int w = 1, int h = 1) -> decltype(qf(vertex_handle{}, float{}, float{}), vertex_handle{});
/// ======== IMPLEMENTATION ========
// ======== IMPLEMENTATION ========
template <class QuadF>
auto add_quad(Mesh& m, QuadF&& qf, int w, int h) -> decltype(qf(vertex_handle{}, float{}, float{}), vertex_handle{})
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment