Skip to content
Snippets Groups Projects
Commit 132e6734 authored by Philip Trettner's avatar Philip Trettner
Browse files

more properties, small change to attributes

parent 913e7b51
No related branches found
No related tags found
No related merge requests found
......@@ -13,4 +13,5 @@ else()
target_compile_options(polymesh PRIVATE -Wall -Werror -fPIC)
target_compile_options(polymesh PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-std=c++11>)
target_link_libraries(polymesh PUBLIC -fuse-ld=gold)
endif()
......@@ -39,21 +39,65 @@ bool is_isolated(edge_handle v);
int valence(vertex_handle v);
/// returns the area of the (flat) polygonal face
template <class Vec3>
typename field_3d<Vec3>::Scalar face_area(face_handle f, vertex_attribute<Vec3> const& position);
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar face_area(face_handle f, vertex_attribute<Vec3> const& position);
/// returns the center of gravity for a given (flat) polygonal face
template <class Vec3>
Vec3 face_centroid(face_handle f, vertex_attribute<Vec3> const& position);
/// returns the area of a given triangle
/// returns the (CCW) oriented face normal (assumes planar polygon)
template <class Vec3>
typename field_3d<Vec3>::Scalar triangle_area(face_handle f, vertex_attribute<Vec3> const& position);
Vec3 face_normal(face_handle f, vertex_attribute<Vec3> const& position);
/// returns the area of a given triangle
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar triangle_area(face_handle f, vertex_attribute<Vec3> const& position);
/// returns the center of gravity for a given triangle
template <class Vec3>
Vec3 triangle_centroid(face_handle f, vertex_attribute<Vec3> const& position);
/// returns the (CCW) oriented face normal
template <class Vec3>
Vec3 triangle_normal(face_handle f, vertex_attribute<Vec3> const& position);
/// returns a barycentric interpolation of a triangular face
template <class Vec3>
Vec3 bary_interpolate(face_handle f, Vec3 bary, vertex_attribute<Vec3> const& position);
/// returns the length of an edge
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar edge_length(edge_handle e, vertex_attribute<Vec3> const& position);
/// returns the length of an edge
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar edge_length(halfedge_handle h, vertex_attribute<Vec3> const& position);
/// returns the (non-normalized) vector from -> to
template <class Vec3>
Vec3 edge_vector(halfedge_handle h, vertex_attribute<Vec3> const& position);
/// returns the (normalized) vector from -> to (0 if from == to)
template <class Vec3>
Vec3 edge_dir(halfedge_handle h, vertex_attribute<Vec3> const& position);
/// calculates the angle between this half-edge and the next one
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar angle_to_next(halfedge_handle h, vertex_attribute<Vec3> const& position);
/// calculates the angle between this half-edge and the previous one
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar angle_to_prev(halfedge_handle h, vertex_attribute<Vec3> const& position);
/// sum of face angles at this vertex
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar angle_sum(vertex_handle v, vertex_attribute<Vec3> const& position);
/// difference between 2pi and the angle sum (positive means less than 2pi)
template <class Vec3, class Scalar = typename field_3d<Vec3>::Scalar>
Scalar angle_defect(vertex_handle v, vertex_attribute<Vec3> const& position);
/// ======== IMPLEMENTATION ========
inline bool is_boundary(vertex_handle v) { return v.is_boundary(); }
......@@ -70,8 +114,8 @@ inline bool is_isolated(edge_handle v) { return v.is_isolated(); }
inline int valence(vertex_handle v) { return v.adjacent_vertices().size(); }
template <class Vec3>
typename field_3d<Vec3>::Scalar triangle_area(face_handle f, vertex_attribute<Vec3> const& position)
template <class Vec3, class Scalar>
Scalar triangle_area(face_handle f, vertex_attribute<Vec3> const& position)
{
auto h = f.any_halfedge();
auto p0 = position[h.vertex_from()];
......@@ -93,7 +137,31 @@ Vec3 triangle_centroid(face_handle f, vertex_attribute<Vec3> const& position)
}
template <class Vec3>
typename field_3d<Vec3>::Scalar face_area(face_handle f, vertex_attribute<Vec3> const& position)
Vec3 face_normal(face_handle f, vertex_attribute<Vec3> const& position)
{
auto c = face_centroid(f, position);
auto e = f.any_halfedge();
auto v0 = e.vertex_from()[position];
auto v1 = e.vertex_to()[position];
auto n = field_3d<Vec3>::cross(v0 - c, v1 - c);
auto l = field_3d<Vec3>::length(n);
return l == 0 ? field_3d<Vec3>::zero() : n / l;
}
template <class Vec3>
Vec3 triangle_normal(face_handle f, vertex_attribute<Vec3> const& position)
{
auto e = f.any_halfedge();
auto v0 = e.vertex_from()[position];
auto v1 = e.vertex_to()[position];
auto v2 = e.next().vertex_to()[position];
auto n = field_3d<Vec3>::cross(v1 - v0, v2 - v0);
auto l = field_3d<Vec3>::length(n);
return l == 0 ? field_3d<Vec3>::zero() : n / l;
}
template <class Vec3, class Scalar>
Scalar face_area(face_handle f, vertex_attribute<Vec3> const& position)
{
auto varea = field_3d<Vec3>::zero();
......@@ -150,4 +218,98 @@ Vec3 face_centroid(face_handle f, vertex_attribute<Vec3> const& position)
return centroid / (3.0f * area);
}
template <class Vec3, class Scalar>
Scalar edge_length(edge_handle e, vertex_attribute<Vec3> const& position)
{
return field_3d<Vec3>::length(position[e.vertexA()] - position[e.vertexB()]);
}
template <class Vec3, class Scalar>
Scalar edge_length(halfedge_handle h, vertex_attribute<Vec3> const& position)
{
return field_3d<Vec3>::length(position[h.vertex_from()] - position[h.vertex_to()]);
}
template <class Vec3>
Vec3 edge_vector(halfedge_handle h, vertex_attribute<Vec3> const& position)
{
return position[h.vertex_to()] - position[h.vertex_from()];
}
template <class Vec3>
Vec3 edge_dir(halfedge_handle h, vertex_attribute<Vec3> const& position)
{
auto d = position[h.vertex_to()] - position[h.vertex_from()];
auto l = field_3d<Vec3>::length(d);
if (l == 0)
return field_3d<Vec3>::zero();
return d / l;
}
template <class Vec3, class Scalar>
Scalar angle_to_next(halfedge_handle h, vertex_attribute<Vec3> const& position)
{
auto v0 = h.vertex_from()[position];
auto v1 = h.vertex_to()[position];
auto v2 = h.next().vertex_to()[position];
auto v01 = v0 - v1;
auto v21 = v2 - v1;
auto l01 = field_3d<Vec3>::length(v01);
auto l21 = field_3d<Vec3>::length(v21);
if (l01 == 0 || l21 == 0)
return 0;
auto ca = field_3d<Vec3>::dot(v01, v21) / (l01 * l21);
return std::acos(ca);
}
template <class Vec3, class Scalar>
Scalar angle_to_prev(halfedge_handle h, vertex_attribute<Vec3> const& position)
{
auto v0 = h.vertex_to()[position];
auto v1 = h.vertex_from()[position];
auto v2 = h.prev().vertex_from()[position];
auto v01 = v0 - v1;
auto v21 = v2 - v1;
auto l01 = field_3d<Vec3>::length(v01);
auto l21 = field_3d<Vec3>::length(v21);
if (l01 == 0 || l21 == 0)
return 0;
auto ca = field_3d<Vec3>::dot(v01, v21) / (l01 * l21);
return std::acos(ca);
}
template <class Vec3, class Scalar>
Scalar angle_sum(vertex_handle v, vertex_attribute<Vec3> const& position)
{
Scalar sum = 0;
for (auto h : v.outgoing_halfedges())
if (!h.is_boundary())
sum += angle_to_prev(h, position);
return sum;
}
template <class Vec3, class Scalar>
Scalar angle_defect(vertex_handle v, vertex_attribute<Vec3> const& position)
{
return 2 * M_PI - angle_sum(v, position);
}
template <class Vec3>
Vec3 bary_interpolate(face_handle f, Vec3 bary, vertex_attribute<Vec3> const& position)
{
auto h = f.any_halfedge();
auto v0 = h.vertex_to()[position];
auto v1 = h.next().vertex_to()[position];
auto v2 = h.next().next().vertex_to()[position];
return v0 * bary[0] + v1 * bary[1] + v2 * bary[2];
}
}
......@@ -55,7 +55,7 @@ public:
/// returns a new attribute where the given function was applied to each entry
template <class FuncT>
auto map(FuncT&& f) const -> attribute<tmp::decayed_result_type_of<FuncT, AttrT>>;
/// applies to given function to each attribute entry
/// applies to given function to each attribute entry (calls f(e))
template <class FuncT>
void apply(FuncT&& f);
......
#include "ply.hh"
// TODO
#pragma once
#include <glm/glm.hpp>
#include <iostream>
#include <string>
#include "../Mesh.hh"
namespace polymesh
{
// TODO
// void write_ply(std::string const& filename, Mesh const& mesh, vertex_attribute<glm::vec3> const& position);
// void write_ply(std::ostream& out, Mesh const& mesh, vertex_attribute<glm::vec3> const& position);
// bool read_off(std::string const& filename, Mesh& mesh, vertex_attribute<glm::vec3>& position);
// bool read_off(std::istream& input, Mesh& mesh, vertex_attribute<glm::vec3>& position);
}
......@@ -253,6 +253,6 @@ void primitive_attribute<tag, AttrT>::apply(FuncT &&f)
auto s = size();
auto d = data();
for (auto i = 0; i < s; ++i)
d[i] = f(d[i]);
f(d[i]);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment