Skip to content

Commit

Permalink
Update classes using PlaneFrame
Browse files Browse the repository at this point in the history
  • Loading branch information
Leo Arnal authored and nmellado committed Jun 9, 2023
1 parent bf79736 commit 45ce2a6
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 81 deletions.
38 changes: 7 additions & 31 deletions Ponca/src/Fitting/covariancePlaneFit.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "./primitive.h"
#include "./mean.h" // used to define CovarianceLineFit
#include "./covarianceFit.h" // use to define CovariancePlaneFit
#include "./planeFrame.h" // use to define CovariancePlaneFit

#include <Eigen/Eigenvalues>

Expand All @@ -38,13 +39,12 @@ PONCA_FITTING_DECLARE_MATRIX_TYPE
protected:
enum
{
Check = Base::PROVIDES_PLANE &&
Base::PROVIDES_POSITION_COVARIANCE,
Check = Base::PROVIDES_POSITION_COVARIANCE
and Base::PROVIDES_PLANE_FRAME,
/*!
* \brief Expose a method worldToTangentPlane(VectorType), which turns a point
* \brief Fit the tangent plane and store it into Plane and PlaneFrame which turn a point
* in ambient 3D space to the tangent plane.
* \see worldToTangentPlane
* \see tangentPlaneToWorld
* \see PlaneFrame
*/
PROVIDES_TANGENT_PLANE_BASIS
};
Expand All @@ -53,31 +53,6 @@ PONCA_FITTING_DECLARE_MATRIX_TYPE
PONCA_EXPLICIT_CAST_OPERATORS(CovariancePlaneFitImpl,covariancePlaneFit)
PONCA_FITTING_DECLARE_FINALIZE

/**************************************************************************/
/* Results */
/**************************************************************************/

/*!
* \brief Express a point in ambient space relatively to the tangent plane.
*
* Output vector is: [h, u, v]^T, where u, v are 2d coordinates on the plane,
* and h the height of the sample.
* \tparam ignoreTranslation must be set to true when passing vectors instead of points
* \param _q Point coordinates expressed in ambient space
* \return Point coordinates expressed in local tangent frame
*/
template <bool ignoreTranslation = false>
PONCA_MULTIARCH inline VectorType worldToTangentPlane(const VectorType &_q) const;

/*!
* \brief Transform a point from the tangent plane [h, u, v]^T to ambient space
*
* \tparam ignoreTranslation must be set to true when passing vectors instead of points
* \param _q Point coordinates expressed in local tangent frame
* \return Point coordinates expressed in ambient space
*/
template <bool ignoreTranslation = false>
PONCA_MULTIARCH inline VectorType tangentPlaneToWorld(const VectorType &_q) const;
}; //class CovariancePlaneFitImpl

/// \brief Helper alias for Plane fitting on 3D points using CovariancePlaneFitImpl
Expand All @@ -87,7 +62,8 @@ PONCA_FITTING_DECLARE_MATRIX_TYPE
CovariancePlaneFitImpl<DataPoint, _WFunctor,
CovarianceFitBase<DataPoint, _WFunctor,
MeanPosition<DataPoint, _WFunctor,
Plane<DataPoint, _WFunctor,T>>>>;
PlaneFrame<DataPoint, _WFunctor,
Plane<DataPoint, _WFunctor,T>>>>>;
//! [CovariancePlaneFit Definition]

/*!
Expand Down
30 changes: 2 additions & 28 deletions Ponca/src/Fitting/covariancePlaneFit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,11 @@ CovariancePlaneFitImpl<DataPoint, _WFunctor, T>::finalize ()
if (Base::plane().isValid()) Base::m_eCurrentState = CONFLICT_ERROR_FOUND;
Base::setPlane(Base::m_solver.eigenvectors().col(0), Base::barycenter());
}

Base::m_u = Base::m_solver.eigenvectors().col(1);
Base::m_v = Base::m_solver.eigenvectors().col(2);
return Base::m_eCurrentState;
}

template < class DataPoint, class _WFunctor, typename T>
template <bool ignoreTranslation>
typename CovariancePlaneFitImpl<DataPoint, _WFunctor, T>::VectorType
CovariancePlaneFitImpl<DataPoint, _WFunctor, T>::worldToTangentPlane (const VectorType& _q) const
{
if (ignoreTranslation)
return Base::m_solver.eigenvectors().transpose() * _q;
else {
// apply rotation and translation to get uv coordinates
return Base::m_solver.eigenvectors().transpose() * (Base::m_w.convertToLocalBasis(_q));
}
}

template < class DataPoint, class _WFunctor, typename T>
template <bool ignoreTranslation>
typename CovariancePlaneFitImpl<DataPoint, _WFunctor, T>::VectorType
CovariancePlaneFitImpl<DataPoint, _WFunctor, T>::tangentPlaneToWorld (const VectorType& _lq) const
{
if (ignoreTranslation)
return Base::m_solver.eigenvectors().transpose().inverse() * _lq;
else {
return Base::m_solver.eigenvectors().transpose().inverse() * _lq + Base::m_w.basisCenter();
}
}



template < class DataPoint, class _WFunctor, int DiffType, typename T>
FIT_RESULT
CovariancePlaneDerImpl<DataPoint, _WFunctor, DiffType, T>::finalize()
Expand Down
3 changes: 2 additions & 1 deletion Ponca/src/Fitting/meanPlaneFit.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ namespace Ponca
\inherit Concept::FittingProcedureConcept
\see Plane, PlaneFrame
\see Plane
\see PlaneFrame
*/
template < class DataPoint, class _WFunctor, typename T >
class MeanPlaneFitImpl : public T
Expand Down
21 changes: 16 additions & 5 deletions Ponca/src/Fitting/mongePatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class MongePatch : public T
PONCA_FITTING_DECLARE_DEFAULT_TYPES

protected:
enum { Check = Base::PROVIDES_PLANE && Base::PROVIDES_TANGENT_PLANE_BASIS };
enum { Check = Base::PROVIDES_PLANE_FRAME };

public:
using SampleMatrix = Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>;
Expand Down Expand Up @@ -57,19 +57,19 @@ PONCA_FITTING_DECLARE_DEFAULT_TYPES

/*! \brief Value of the scalar field at the evaluation point */
PONCA_MULTIARCH inline Scalar potential(const VectorType& _q) const {
VectorType x = Base::worldToTangentPlane(_q);
VectorType x = Base::worldToLocalFrame(_q);
return evalUV(*(x.data()+1),*(x.data()+2)) - *(x.data());
}

//! \brief Orthogonal projecting on the patch, such that h = f(u,v)
PONCA_MULTIARCH inline VectorType project (const VectorType& _q) const
{
VectorType x = Base::worldToTangentPlane(_q);
VectorType x = Base::worldToLocalFrame(_q);
*(x.data()) = evalUV(*(x.data()+1),*(x.data()+2));
return Base::tangentPlaneToWorld(x);
return Base::localFrameToWorld(x);
}

PONCA_MULTIARCH inline const Scalar & h_uu () const { return *(m_x.data()); }
PONCA_MULTIARCH inline const Scalar & h_uu () const { return *(m_x.data()); }
PONCA_MULTIARCH inline const Scalar & h_vv () const { return *(m_x.data()+1); }
PONCA_MULTIARCH inline const Scalar & h_uv () const { return *(m_x.data()+2); }
PONCA_MULTIARCH inline const Scalar & h_u () const { return *(m_x.data()+3); }
Expand All @@ -78,6 +78,17 @@ PONCA_FITTING_DECLARE_DEFAULT_TYPES

};

/// \brief Helper alias for MongePatch fitting on 3D points using MongePatch
//! [MongePatchFit Definition]
template < class DataPoint, class _WFunctor, typename T>
using MongePatchFit = Ponca::MongePatch<DataPoint, _WFunctor,
Ponca::CovariancePlaneFitImpl<DataPoint, _WFunctor,
Ponca::CovarianceFitBase<DataPoint, _WFunctor,
Ponca::MeanPosition<DataPoint, _WFunctor,
Ponca::PlaneFrame<DataPoint, _WFunctor,
Ponca::Plane<DataPoint, _WFunctor,T>>>>>>;
//! [MongePatchFit Definition]

#include "mongePatch.hpp"

} //namespace Ponca
2 changes: 1 addition & 1 deletion Ponca/src/Fitting/mongePatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ MongePatch<DataPoint, _WFunctor, T>::addLocalNeighbor(Scalar w,
else // base plane is ready, we can now fit the patch
{
// express neighbor in local coordinate frame
const VectorType local = Base::worldToTangentPlane(attributes.pos());
const VectorType local = Base::worldToLocalFrame(attributes.pos());
const Scalar& h = *(local.data());
const Scalar& u = *(local.data()+1);
const Scalar& v = *(local.data()+2);
Expand Down
20 changes: 11 additions & 9 deletions Ponca/src/Fitting/planeFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace Ponca
This class can be used to do base change from the global frame to the local frame of the plane.
\see Plane
\see worldToLocalFrame
\see localFrameToWorld
*/
template < class DataPoint, class _WFunctor, typename T >
class PlaneFrame : public T
Expand All @@ -34,10 +36,10 @@ class PlaneFrame : public T

public:
PONCA_EXPLICIT_CAST_OPERATORS(PlaneFrame,planeFrame)
/*! \brief Set the scalar field values to 0 and reset the isNormalized() status

\warning Set m_ul to Zero(), which leads to nans in OrientedSphere::normal()
*/
/*! \brief Set the vectors of the local frame to zero
* \param _basisCenter Center of the local frame
*/
PONCA_MULTIARCH inline void init(const VectorType& _basisCenter = VectorType::Zero())
{
Base::init(_basisCenter);
Expand All @@ -46,26 +48,26 @@ class PlaneFrame : public T
}

/*!
* \brief Express a point in ambient space relatively to the tangent plane.
* \brief Express a point in ambient space relatively to the local frame.
*
* Output vector is: [h, u, v]^T, where u, v are 2d coordinates on the plane,
* and h the height of the sample.
* \tparam ignoreTranslation must be set to true when passing vectors instead of points
* \param _q Point coordinates expressed in ambient space
* \return Point coordinates expressed in local tangent frame
* \return Point coordinates expressed in local frame
*/
template <bool ignoreTranslation = false>
PONCA_MULTIARCH inline VectorType worldToTangentPlane(const VectorType &_q) const;
PONCA_MULTIARCH inline VectorType worldToLocalFrame(const VectorType &_q) const;

/*!
* \brief Transform a point from the tangent plane [h, u, v]^T to ambient space
* \brief Transform a point from the local frame [h, u, v]^T to ambient space
*
* \tparam ignoreTranslation must be set to true when passing vectors instead of points
* \param _q Point coordinates expressed in local tangent frame
* \param _q Point coordinates expressed in local frame
* \return Point coordinates expressed in ambient space
*/
template <bool ignoreTranslation = false>
PONCA_MULTIARCH inline VectorType tangentPlaneToWorld(const VectorType &_q) const;
PONCA_MULTIARCH inline VectorType localFrameToWorld(const VectorType &_q) const;

}; //class PlaneFrame

Expand Down
4 changes: 2 additions & 2 deletions Ponca/src/Fitting/planeFrame.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
template < class DataPoint, class _WFunctor, typename T>
template <bool ignoreTranslation>
typename PlaneFrame<DataPoint, _WFunctor, T>::VectorType
PlaneFrame<DataPoint, _WFunctor, T>::worldToTangentPlane (const VectorType& _q) const
PlaneFrame<DataPoint, _WFunctor, T>::worldToLocalFrame (const VectorType& _q) const
{
MatrixType B;
B << Base::plane().normal(), m_u, m_v;
Expand All @@ -16,7 +16,7 @@ PlaneFrame<DataPoint, _WFunctor, T>::worldToTangentPlane (const VectorType& _q)
template < class DataPoint, class _WFunctor, typename T>
template <bool ignoreTranslation>
typename PlaneFrame<DataPoint, _WFunctor, T>::VectorType
PlaneFrame<DataPoint, _WFunctor, T>::tangentPlaneToWorld (const VectorType& _lq) const
PlaneFrame<DataPoint, _WFunctor, T>::localFrameToWorld (const VectorType& _lq) const
{
MatrixType B;
B << Base::plane().normal(), m_u, m_v;
Expand Down
2 changes: 1 addition & 1 deletion tests/src/basket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void callSubTests()
//! [HybridType]
// Create an hybrid structure fitting a plane and a sphere at the same time
using Hybrid = Basket<Point, WeightFunc,
AlgebraicSphere, Plane, // primitives
AlgebraicSphere, Plane, PlaneFrame, // primitives
MeanNormal, MeanPosition, // shared computation
OrientedSphereFitImpl, // sphere fitting
CovarianceFitBase, CovariancePlaneFitImpl>; // plane fitting
Expand Down
2 changes: 1 addition & 1 deletion tests/src/fit_monge_patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void testFunction(bool _bUnoriented = false, bool _bAddPositionNoise = false, bo
VERIFY(Scalar(1.) - std::abs(fit.primitiveGradient(queryPos).dot(direction)) <= epsilon);

// Projecting to tangent plane and going back to world should not change the position
VERIFY((fit.tangentPlaneToWorld(fit.worldToTangentPlane(queryPos)) - queryPos).norm() <= epsilon);
VERIFY((fit.localFrameToWorld(fit.worldToLocalFrame(queryPos)) - queryPos).norm() <= epsilon);

if(!_bAddPositionNoise) {
// Check if the query point is on the plane
Expand Down
4 changes: 2 additions & 2 deletions tests/src/fit_plane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ void callSubTests()

// test if conflicts are detected
//! [Conflicting type]
typedef Basket<Point, WeightConstantFunc, Plane,
typedef Basket<Point, WeightConstantFunc, Plane, PlaneFrame,
MeanNormal, MeanPosition, MeanPlaneFitImpl,
CovarianceFitBase, CovariancePlaneFitImpl> Hybrid1; //test conflict detection in one direction
//! [Conflicting type]
typedef Basket<Point, WeightConstantFunc, Plane,
typedef Basket<Point, WeightConstantFunc, Plane, PlaneFrame,
MeanPosition, CovarianceFitBase, CovariancePlaneFitImpl,
MeanNormal, MeanPlaneFitImpl> Hybrid2; //test conflict detection in the second direction

Expand Down

0 comments on commit 45ce2a6

Please sign in to comment.