...
 
Commits (10)
......@@ -42,6 +42,17 @@ endif()
add_subdirectory(Patate/common EXCLUDE_FROM_ALL)
#endif()
################################################################################
# Generate install target #
################################################################################
if (NOT INCLUDE_INSTALL_DIR)
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include)
endif (NOT INCLUDE_INSTALL_DIR)
install(DIRECTORY Patate DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING REGEX ".*\\.(hpp|h)$")
message("Patate will be installed in ${INCLUDE_INSTALL_DIR}/Patate")
################################################################################
# Generate Vitelotte's shaders #
# TODO: find a more appropriate place for this. #
......
......@@ -99,7 +99,8 @@ public:
m_ul = VectorType::Zero();
m_uq = Scalar(0.0);
m_isNormalized = false;
// prevent to apply default Pratt norm leading to a division by zero
m_isNormalized = true;
}
/*! \brief Reading access to the basis center (evaluation position) */
......@@ -116,7 +117,7 @@ public:
//m_uq is not changed
m_p = newbasis;
m_isNormalized = false;
applyPrattNorm();
//applyPrattNorm();
}
/*! \brief compute the Pratt norm of the implicit scalar field. */
......@@ -124,12 +125,14 @@ public:
{
MULTIARCH_STD_MATH(sqrt);
return sqrt(prattNorm2());
//return sqrt(std::abs(prattNorm2()));
}
/*! \brief compute the squared Pratt norm of the implicit scalar field. */
MULTIARCH inline Scalar prattNorm2() const
{
return m_ul.squaredNorm() - Scalar(4.) * m_uc * m_uq;
//return m_ul.x() * m_ul.x() + m_ul.y() * m_ul.y() - Scalar(4.) * m_uc * m_uq;
}
/*!
......@@ -215,8 +218,33 @@ public:
return bReady && bPlanar;
}
#ifdef PATATE_EXPERIMENTAL
//! \brief Set sphere parameters
MULTIARCH inline void setParameters(const Scalar& uc, const VectorType& ul, const Scalar& uq, const VectorType& p);
//! \brief Compute interpolation of two spheres
MULTIARCH inline void combine(const AlgebraicSphere& q1, const AlgebraicSphere &q2, Scalar alpha);
MULTIARCH inline void combine(const AlgebraicSphere& q0, const AlgebraicSphere& q1, const AlgebraicSphere &q2, Scalar gamma1, Scalar gamma2);
//! \brief Compute the distance segment sphere
MULTIARCH inline Scalar distanceSegSphere(const VectorType& v0, const VectorType& v1);
//! \brief Compute the distance face sphere
MULTIARCH inline Scalar distanceFaceSphere(const VectorType& v0, const VectorType& v1, const VectorType& v2);
MULTIARCH inline Scalar gradientFaceSphere(const VectorType& v0, const VectorType& v1, const VectorType& v2, const VectorType& n0, const VectorType& n1, const VectorType& n2);
/*!
\brief Used to know if two algebraic spheres are the same
\return true if the two algebraic spheres are the same
*/
MULTIARCH inline bool hasSameParameter(const AlgebraicSphere& q1) const;
#endif //PATATE_EXPERIMENTAL
}; //class AlgebraicSphere
#include "algebraicSphere.hpp"
}
......
......@@ -60,3 +60,163 @@ AlgebraicSphere<DataPoint, _WFunctor, T>::primitiveGradient( const VectorType &_
return (m_ul + Scalar(2.f) * m_uq * lq);
}
/**************************************************************************/
/* Experimentation (CM) */
/**************************************************************************/
#ifdef PATATE_EXPERIMENTAL
template < class DataPoint, class _WFunctor, typename T>
void
AlgebraicSphere<DataPoint, _WFunctor, T>::setParameters(const Scalar& uc, const VectorType& ul, const Scalar& uq, const VectorType& p)
{
m_uc = uc;
m_ul = ul;
m_uq = uq;
m_p = p;
m_isNormalized = false;
Base::m_eCurrentState = STABLE;
}
template < class DataPoint, class _WFunctor, typename T>
void
AlgebraicSphere<DataPoint, _WFunctor, T>::combine(const AlgebraicSphere& q1, const AlgebraicSphere &q2, Scalar alpha)
{
VectorType new_base = q1.m_p + alpha * (q2.m_p - q1.m_p);
AlgebraicSphere q1_new_base = q1;
AlgebraicSphere q2_new_base = q2;
// compute Salpha = S1 + alpha(S2 - S1)
Scalar new_uc = q1_new_base.m_uc + alpha * (q2_new_base.m_uc - q1_new_base.m_uc);
VectorType new_ul = q1_new_base.m_ul + alpha * (q2_new_base.m_ul - q1_new_base.m_ul);
Scalar new_uq = q1_new_base.m_uq + alpha * (q2_new_base.m_uq - q1_new_base.m_uq);
VectorType new_p = new_base;
//new_ul.normalize(); // no need
setParameters(new_uc, new_ul, new_uq, new_p);
applyPrattNorm();
}
template < class DataPoint, class _WFunctor, typename T>
void
AlgebraicSphere<DataPoint, _WFunctor, T>::combine(const AlgebraicSphere& q0, const AlgebraicSphere& q1, const AlgebraicSphere &q2, Scalar gamma1, Scalar gamma2)
{
VectorType new_base = gamma1 * q0.m_p + gamma2 * q1.m_p + (1.0 - gamma1 - gamma2) * q2.m_p;
AlgebraicSphere q0_new_base = q0;
AlgebraicSphere q1_new_base = q1;
AlgebraicSphere q2_new_base = q2;
// compute Salpha = gamma1 * S0 + gamma2 * S1 + (1.0 - gamma1 - gamma2) * S2
Scalar new_uc = gamma1 * q0_new_base.m_uc + gamma2 * q1_new_base.m_uc + (1.0 - gamma1 - gamma2) * q2_new_base.m_uc;
VectorType new_ul = gamma1 * q0_new_base.m_ul + gamma2 * q1_new_base.m_ul + (1.0 - gamma1 - gamma2) * q2_new_base.m_ul;
Scalar new_uq = gamma1 * q0_new_base.m_uq + gamma2 * q1_new_base.m_uq + (1.0 - gamma1 - gamma2) * q2_new_base.m_uq;
VectorType new_p = new_base;
new_ul.normalize();
setParameters(new_uc, new_ul, new_uq, new_p);
applyPrattNorm();
}
template < class DataPoint, class _WFunctor, typename T>
typename DataPoint::Scalar
AlgebraicSphere<DataPoint, _WFunctor, T>::distanceSegSphere(const VectorType& v0, const VectorType& v1)
{
VectorType v0_centered = v0 - m_p;
VectorType v1_centered = v1 - m_p;
VectorType seg = v1_centered - v0_centered;
AlgebraicSphere prim;
prim.setParameters(0.0, 0.5 * m_ul + m_uq * v0_centered, (1.0/3.0) * m_uq, VectorType::Zero()); //v0_centered
Scalar norm = (v1 - v0).norm(); // v1 and v0 centered
// (S(v0) + S'(v1 - v0)) * norm(v1-v0)
Scalar dist = (potential(v0) + prim.potential(seg)) * norm; // to have the same results than the short paper
// eurographics 2017 (2)
//Scalar dist = (potential(v0_centered) + prim.potential(seg)) * norm; // to have the same results than the short paper
// eurographics 2017 (1)
return dist;
}
template < class DataPoint, class _WFunctor, typename T>
typename DataPoint::Scalar
// https://en.wikipedia.org/wiki/Barycentric_coordinate_system
AlgebraicSphere<DataPoint, _WFunctor, T>::distanceFaceSphere(const VectorType& v0, const VectorType& v1, const VectorType& v2)
{
VectorType v0_centered = v0 - m_p;
VectorType v1_centered = v1 - m_p;
VectorType v2_centered = v2 - m_p;
AlgebraicSphere prim;
prim.setParameters(0.0, (1.0/6.0) * m_ul + (1.0/3.0) * m_uq * v2_centered, (1.0/12.0) * m_uq, VectorType::Zero());
Scalar residual = (1.0/12.0) * m_uq * (v1_centered - v2_centered).dot(v0_centered - v2_centered);
Scalar area = ( ( ( v1 - v0 ).cross( v2 - v0 ) ).norm() * 0.5 );
Scalar dist = 0.0;
dist = 2.0 * area * (0.5 * potential(v2) + prim.potential(v0 - v2) + prim.potential(v1 - v2) + residual) ;
// test
//gradient_weight = 1.0 - ((radius() - min_radius) / (max_radius - min_radius));
//gradient_weight = ((radius() - min_radius) / (max_radius - min_radius));
//gradient_weight = (radius() / (max_radius - min_radius));
// adding gradient
//dist += gradient_weight * (1.0 - ( m_ul.dot(n) + 2.0 * m_uq * v2.dot(n) - 2.0 * m_uq * basisCenter().dot(n) +
// m_uq * (v0 - v2).dot(n) + m_uq * (v1 - v0).dot(n) +
// (1.0/3.0) * m_uq * (v0 + v2 - 2.0 * v1).dot(n)));
return dist;
}
template < class DataPoint, class _WFunctor, typename T>
typename DataPoint::Scalar
// https://en.wikipedia.org/wiki/Barycentric_coordinate_system
AlgebraicSphere<DataPoint, _WFunctor, T>::gradientFaceSphere(const VectorType& v0, const VectorType& v1, const VectorType& v2, const VectorType& n0, const VectorType& n1, const VectorType& n2)
{
Scalar dist_gradient = 0.0;
Scalar dt = 0.05;
VectorType grad = VectorType(0.0, 0.0, 0.0);
VectorType n = VectorType(0.0, 0.0, 0.0);
Scalar area = ( ( ( v1 - v0 ).cross( v2 - v0 ) ).norm() * 0.5 );
for (Scalar gamma2 = 0.0; gamma2 <= 1.0; gamma2 += dt) // we go through the face
{
for (Scalar gamma1 = 0.0; gamma1 <= 1.0 - gamma2; gamma1 += dt)
{
// gradient
grad = primitiveGradient(gamma1 * v0 + gamma2 * v1 + (1.0 - gamma1 - gamma2) * v2);
grad.normalize();
// normal
n = gamma1 * n0 + gamma2 * n1 + (1.0 - gamma1 - gamma2) * n2;
n.normalize();
//dist_gradient += gradient_weight * (1.0 - grad.dot(n));
dist_gradient += (1.0 - grad.dot(n));
}
}
return 2.0 * area * dist_gradient;
//test
//gradient_weight = 1.0 - ((radius() - min_radius) / (max_radius - min_radius));
//gradient_weight = (radius() - min_radius) / (max_radius - min_radius);
//gradient_weight = (radius() / (max_radius - min_radius));
// adding gradient
/*
Scalar area = ( ( ( v1 - v0 ).cross( v2 - v0 ) ).norm() * 0.5 );
Scalar dist = 2 * area * (0.5 - 0.5 * m_ul.dot(n) - (1.0/3.0) * m_uq * (v1 - v2).dot(n) - (1.0/3.0) * m_uq * (v0 - v2).dot(n) - m_uq * (v2 - basisCenter()).dot(n));
return dist;
*/
}
template < class DataPoint, class _WFunctor, typename T>
bool
AlgebraicSphere<DataPoint, _WFunctor, T>::hasSameParameter(const AlgebraicSphere& q1) const
{
Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision();
return ((q1.m_uc - m_uc) < epsilon && (q1.m_ul - m_ul).norm() < epsilon && (q1.m_uq - m_uq) < epsilon);
}
#endif //PATATE_EXPERIMENTAL
......@@ -69,7 +69,10 @@ public:
/* Processing */
/**************************************************************************/
/*! \copydoc Concept::FittingProcedureConcept::addNeighbor() */
MULTIARCH inline bool addNeighbor(const DataPoint &_nei);
MULTIARCH inline Scalar addNeighbor(const DataPoint &_nei);
/*! \todo */
MULTIARCH inline bool addNeighbor(const DataPoint &_nei, const Scalar w);
/*! \copydoc Concept::FittingProcedureConcept::finalize() */
MULTIARCH inline FIT_RESULT finalize();
......
......@@ -22,7 +22,7 @@ OrientedSphereFit<DataPoint, _WFunctor, T>::init(const VectorType& _evalPos)
}
template < class DataPoint, class _WFunctor, typename T>
bool
typename OrientedSphereFit<DataPoint, _WFunctor, T>::Scalar
OrientedSphereFit<DataPoint, _WFunctor, T>::addNeighbor(const DataPoint& _nei)
{
// centered basis
......@@ -40,6 +40,31 @@ OrientedSphereFit<DataPoint, _WFunctor, T>::addNeighbor(const DataPoint& _nei)
m_sumDotPP += w * q.squaredNorm();
m_sumW += w;
/*! \todo Handle add of multiple similar neighbors (maybe user side)*/
++(Base::m_nbNeighbors);
return w;
}
return 0.0;
}
// TODO
template < class DataPoint, class _WFunctor, typename T>
bool
OrientedSphereFit<DataPoint, _WFunctor, T>::addNeighbor(const DataPoint& _nei, const Scalar w)
{
// centered basis
VectorType q = _nei.pos() - Base::basisCenter();
if (w > Scalar(0.))
{
// increment matrix
m_sumP += q * w;
m_sumN += _nei.normal() * w;
m_sumDotPN += w * _nei.normal().dot(q);
m_sumDotPP += w * q.squaredNorm();
m_sumW += w;
/*! \todo Handle add of multiple similar neighbors (maybe user side)*/
++(Base::m_nbNeighbors);
return true;
......@@ -48,7 +73,6 @@ OrientedSphereFit<DataPoint, _WFunctor, T>::addNeighbor(const DataPoint& _nei)
return false;
}
template < class DataPoint, class _WFunctor, typename T>
FIT_RESULT
OrientedSphereFit<DataPoint, _WFunctor, T>::finalize ()
......
......@@ -93,6 +93,43 @@ protected:
};// class DistWeightFunc
template <class DataPoint, class WeightKernel>
class RIMLSWeightFunc
{
public:
/*! \brief Scalar type from DataPoint */
typedef typename DataPoint::Scalar Scalar;
/*! \brief Vector type from DataPoint */
typedef typename DataPoint::VectorType VectorType;
/*!
\brief Constructor
*/
MULTIARCH inline RIMLSWeightFunc()
{
}
/*!
\brief Compute the weight of the given query with respect to its coordinates.
*/
MULTIARCH inline Scalar w(const VectorType& _q, const DataPoint& _d);
//MULTIARCH inline Scalar setSigmaR(const Scalar& r) { m_sigma_r = r; }
//MULTIARCH inline Scalar setSigmaR(const Scalar& n) { m_sigma_n = n; }
protected:
int m_i;
VectorType m_x;
Scalar m_f;
VectorType m_grad_f;
Scalar m_sigma_r;
Scalar m_sigma_n;
Scalar m_hi;
};// class RIMLSWeightFunc
#include "weightFunc.hpp"
}// namespace Grenaille
......
......@@ -34,3 +34,43 @@ DistWeightFunc<DataPoint, WeightKernel>::scaledw( const VectorType& _q,
Scalar d = _q.norm();
return (d <= m_t) ? Scalar( - d*m_wk.df(d/m_t)/(m_t*m_t) ) : Scalar(0.);
}
//-----------------------------------------------
/*
Scalar phi(Scalar x, Scalar hi)
{
return std::pow(1.0 - (x / (hi * hi)), 4.0);
}
Scalar dphi(Scalar x, Scalar hi)
{
return (-4.0 / (hi * hi)) * std::pow(1.0 - (x / (hi * hi)), 3.0);
}
template <class DataPoint, class WeightKernel>
typename RIMLSWeightFunc<DataPoint, WeightKernel>::Scalar
RIMLSWeightFunc<DataPoint, WeightKernel>::w( const VectorType& _q, const DataPoint& _d)
{
VectorType px = m_x - _q;
VectorType n = _d.normal();
Scalar m_fx = px.dot(n);
Scalar alpha = 0.0;
if (m_i > 0)
{
Scalar omega = std::exp(-((fx - m_f)/m_sigma_r)*((fx - m_f)/m_sigma_r));
Scalar omega_n = std::exp(-((n - m_grad_f).norm()/m_sigma_n)*((n - m_grad_f).norm()/m_sigma_n));
alpha = omega * omega_n;
}
else
{
alpha = 1.0;
}
Scalar m_w = alpha * phi(px.norm() * px.norm(), m_hi);
Scalar m_grad_w = alpha * 2.0 * px * dphi(px.norm() * px.norm(), m_hi);
return w;
}
*/
......@@ -68,6 +68,7 @@ public:
MULTIARCH inline Scalar ddf(const Scalar& _x) const { return Scalar(12.)*_x*_x - Scalar(4.); }
};//class SmoothWeightKernel
}// namespace Grenaille
......