Commit 47552d07 authored by Philip Trettner's avatar Philip Trettner
Browse files

added range to std collection and weighted avg

parent f35c789f
......@@ -20,5 +20,6 @@ Best used with glm and glow.
* mid-level topo API: edge-rotate-next/prev, edge-split, edge-collapse, halfedge-split, halfedge-collapse, vertex-collapse
* annotate property preservation for mid-level topo API
* vector, set, map -> range
* range -> vector, set, map
* weighted avg
\ No newline at end of file
* opposite edges (from vertex)
* cotangens weights etc.
* smoothing
\ No newline at end of file
......@@ -136,6 +136,26 @@ auto smart_range<this_t, ElementT>::avg(FuncT &&f) const -> tmp::decayed_result_
return s / cnt;
}
template <class this_t, class ElementT>
template <class FuncT, class WeightT>
auto smart_range<this_t, ElementT>::weighted_avg(FuncT &&f, WeightT &&w) const -> tmp::decayed_result_type_of<FuncT, ElementT>
{
auto it_begin = static_cast<this_t const *>(this)->begin();
auto it_end = static_cast<this_t const *>(this)->end();
assert(it_begin != it_end && "requires non-empty range");
auto e = *it_begin;
auto s = f(e);
auto ws = w(e);
++it_begin;
while (it_begin != it_end)
{
auto ee = *it_begin;
s = s + f(ee);
ws = ws + w(ee);
}
return s / ws;
}
template <class this_t, class ElementT>
template <class FuncT>
auto smart_range<this_t, ElementT>::aabb(FuncT &&f) const -> polymesh::aabb<typename tmp::decayed_result_of<FuncT, ElementT>::type>
......@@ -144,7 +164,7 @@ auto smart_range<this_t, ElementT>::aabb(FuncT &&f) const -> polymesh::aabb<type
auto it_end = static_cast<this_t const *>(this)->end();
assert(it_begin != it_end && "requires non-empty range");
auto v = f(*it_begin);
polymesh::aabb<typename tmp::decayed_result_of<FuncT, ElementT>::type> r = { v, v };
polymesh::aabb<typename tmp::decayed_result_of<FuncT, ElementT>::type> r = {v, v};
++it_begin;
while (it_begin != it_end)
{
......@@ -162,6 +182,54 @@ auto smart_range<this_t, ElementT>::minmax(FuncT &&f) const -> polymesh::aabb<ty
return aabb(f);
}
template <class this_t, class ElementT>
std::vector<ElementT> smart_range<this_t, ElementT>::to_vector() const
{
std::vector<ElementT> v;
for (auto h : *static_cast<this_t const *>(this))
v.push_back(h);
return v;
}
template <class this_t, class ElementT>
std::set<ElementT> smart_range<this_t, ElementT>::to_set() const
{
std::set<ElementT> s;
for (auto h : *static_cast<this_t const *>(this))
s.insert(h);
return s;
}
template <class this_t, class ElementT>
template <class FuncT>
auto smart_range<this_t, ElementT>::to_vector(FuncT &&f) const -> std::vector<tmp::decayed_result_type_of<FuncT, ElementT>>
{
std::vector<tmp::decayed_result_type_of<FuncT, ElementT>> v;
for (auto h : *static_cast<this_t const *>(this))
v.push_back(f(h));
return v;
}
template <class this_t, class ElementT>
template <class FuncT>
auto smart_range<this_t, ElementT>::to_set(FuncT &&f) const -> std::set<tmp::decayed_result_type_of<FuncT, ElementT>>
{
std::set<tmp::decayed_result_type_of<FuncT, ElementT>> s;
for (auto h : *static_cast<this_t const *>(this))
s.insert(f(h));
return s;
}
template <class this_t, class ElementT>
template <class FuncT>
auto smart_range<this_t, ElementT>::to_map(FuncT &&f) const -> std::map<ElementT, tmp::decayed_result_type_of<FuncT, ElementT>>
{
std::map<ElementT, tmp::decayed_result_type_of<FuncT, ElementT>> m;
for (auto h : *static_cast<this_t const *>(this))
m[h] = f(h);
return m;
}
template <class mesh_ptr, class tag, class iterator>
int smart_collection<mesh_ptr, tag, iterator>::size() const
{
......
#pragma once
#include <cstddef>
#include <map>
#include <set>
#include <vector>
#include "iterators.hh"
......@@ -14,6 +16,13 @@ struct aabb
T max;
};
template <class V, class W>
struct weighted_sample
{
V value;
W weight;
};
template <class this_t, class ElementT>
struct smart_range
{
......@@ -62,6 +71,12 @@ struct smart_range
template <class FuncT>
auto avg(FuncT&& f) const -> tmp::decayed_result_type_of<FuncT, ElementT>;
/// calculates the weighted avg of f(e) with weight w(e) over all elements
/// undefined behavior if range is empty
/// requires operator+ for the elements and weights as well as operator/(ElementT, WeightT)
template <class FuncT, class WeightT>
auto weighted_avg(FuncT&& f, WeightT&& w) const -> tmp::decayed_result_type_of<FuncT, ElementT>;
/// calculates the aabb (min and max) of f(e) over all elements
/// undefined behavior if range is empty
/// works for std::min/max and everything reachable by ADL (calls min/max(_, _))
......@@ -71,11 +86,26 @@ struct smart_range
template <class FuncT>
auto minmax(FuncT&& f) const -> polymesh::aabb<tmp::decayed_result_type_of<FuncT, ElementT>>;
/// converts this range to a vector
std::vector<ElementT> to_vector() const;
/// converts this range to a set
std::set<ElementT> to_set() const;
/// converts this range to a vector containing f(v) entries
template <class FuncT>
auto to_vector(FuncT&& f) const -> std::vector<tmp::decayed_result_type_of<FuncT, ElementT>>;
/// converts this range to a set containing f(v) entries
template <class FuncT>
auto to_set(FuncT&& f) const -> std::set<tmp::decayed_result_type_of<FuncT, ElementT>>;
/// converts this range to a map containing {v, f(v)} entries
template <class FuncT>
auto to_map(FuncT&& f) const -> std::map<ElementT, tmp::decayed_result_type_of<FuncT, ElementT>>;
// TODO: (requires new ranges)
// - filter (or where?)
// - map
// - skip
// - only_valid
// - conversions from vector/set/map
};
// ================= COLLECTION =================
......
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