Commit c0fb7beb authored by Pierre Kraemer's avatar Pierre Kraemer

generic laplacian computation + cotangent weights

parent 3ea0e63a
......@@ -103,7 +103,7 @@ typename PFP::REAL vertexVoronoiArea(typename PFP::MAP& map, Dart d, const typen
Dart it = d ;
do
{
area += convexFaceArea<PFP>(map, it, position) ;
area += convexFaceArea<PFP>(map, it, position) / 3 ;
it = map.alpha1(it) ;
} while(it != d) ;
return area ;
......
......@@ -40,34 +40,34 @@ namespace Algo
namespace Geometry
{
template <typename PFP>
typename PFP::VEC3 computeLaplacianTopoVertex(
template <typename PFP, typename ATTR_TYPE>
ATTR_TYPE computeLaplacianTopoVertex(
typename PFP::MAP& map,
Dart d,
const typename PFP::TVEC3& position) ;
const AttributeHandler<ATTR_TYPE>& attr) ;
template <typename PFP>
typename PFP::VEC3 computeLaplacianCotanVertex(
template <typename PFP, typename ATTR_TYPE>
ATTR_TYPE computeLaplacianCotanVertex(
typename PFP::MAP& map,
Dart d,
const typename PFP::TVEC3& position,
const typename PFP::TREAL& edgeWeight,
const typename PFP::TREAL& vertexArea) ;
const typename PFP::TREAL& vertexArea,
const AttributeHandler<ATTR_TYPE>& attr) ;
template <typename PFP>
template <typename PFP, typename ATTR_TYPE>
void computeLaplacianTopoVertices(
typename PFP::MAP& map,
const typename PFP::TVEC3& position,
typename PFP::TVEC3& laplacian,
const AttributeHandler<ATTR_TYPE>& attr,
AttributeHandler<ATTR_TYPE>& laplacian,
const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
template <typename PFP, typename ATTR_TYPE>
void computeLaplacianCotanVertices(
typename PFP::MAP& map,
const typename PFP::TVEC3& position,
const typename PFP::TREAL& edgeWeight,
const typename PFP::TREAL& vertexArea,
typename PFP::TVEC3& laplacian,
const AttributeHandler<ATTR_TYPE>& attr,
AttributeHandler<ATTR_TYPE>& laplacian,
const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
......
......@@ -33,45 +33,42 @@ namespace Algo
namespace Geometry
{
template <typename PFP>
typename PFP::VEC3 computeLaplacianTopoVertex(
template <typename PFP, typename ATTR_TYPE>
ATTR_TYPE computeLaplacianTopoVertex(
typename PFP::MAP& map,
Dart d,
const typename PFP::TVEC3& position)
const AttributeHandler<ATTR_TYPE>& attr)
{
typedef typename PFP::VEC3 VEC3 ;
VEC3 l(0) ;
ATTR_TYPE l(0) ;
unsigned int val = 0 ;
Dart dd = d ;
Dart it = d ;
do
{
l += vectorOutOfDart<PFP>(map, dd, position) ;
l += attr[map.phi1(it)] - attr[it] ;
val++ ;
dd = map.alpha1(dd) ;
} while(dd != d) ;
it = map.alpha1(it) ;
} while(it != d) ;
l /= val ;
return l ;
}
template <typename PFP>
typename PFP::VEC3 computeLaplacianCotanVertex(
template <typename PFP, typename ATTR_TYPE>
ATTR_TYPE computeLaplacianCotanVertex(
typename PFP::MAP& map,
Dart d,
const typename PFP::TVEC3& position,
const typename PFP::TREAL& edgeWeight,
const typename PFP::TREAL& vertexArea)
const typename PFP::TREAL& vertexArea,
const AttributeHandler<ATTR_TYPE>& attr)
{
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
VEC3 l(0) ;
ATTR_TYPE l(0) ;
Dart it = d ;
REAL vArea = vertexArea[d] ;
REAL val = 0 ;
do
{
REAL w = edgeWeight[it] / vArea ;
VEC3 v = vectorOutOfDart<PFP>(map, it, position) * w ;
l += v ;
l += (attr[map.phi1(it)] - attr[it]) * w ;
val += w ;
it = map.alpha1(it) ;
} while(it != d) ;
......@@ -79,12 +76,12 @@ typename PFP::VEC3 computeLaplacianCotanVertex(
return l ;
}
template <typename PFP>
template <typename PFP, typename ATTR_TYPE>
void computeLaplacianTopoVertices(
typename PFP::MAP& map,
const typename PFP::TVEC3& position,
typename PFP::TVEC3& laplacian,
const FunctorSelect& select)
typename PFP::MAP& map,
const AttributeHandler<ATTR_TYPE>& attr,
AttributeHandler<ATTR_TYPE>& laplacian,
const FunctorSelect& select)
{
CellMarker marker(map, VERTEX);
for(Dart d = map.begin(); d != map.end(); map.next(d))
......@@ -92,19 +89,19 @@ void computeLaplacianTopoVertices(
if(select(d) && !marker.isMarked(d))
{
marker.mark(d);
laplacian[d] = computeLaplacianTopoVertex<PFP>(map, d, position) ;
laplacian[d] = computeLaplacianTopoVertex<PFP, ATTR_TYPE>(map, d, attr) ;
}
}
}
template <typename PFP>
template <typename PFP, typename ATTR_TYPE>
void computeLaplacianCotanVertices(
typename PFP::MAP& map,
const typename PFP::TVEC3& position,
const typename PFP::TREAL& edgeWeight,
const typename PFP::TREAL& vertexArea,
typename PFP::TVEC3& laplacian,
const FunctorSelect& select)
typename PFP::MAP& map,
const typename PFP::TREAL& edgeWeight,
const typename PFP::TREAL& vertexArea,
const AttributeHandler<ATTR_TYPE>& attr,
AttributeHandler<ATTR_TYPE>& laplacian,
const FunctorSelect& select)
{
CellMarker marker(map, VERTEX);
for(Dart d = map.begin(); d != map.end(); map.next(d))
......@@ -112,7 +109,7 @@ void computeLaplacianCotanVertices(
if(select(d) && !marker.isMarked(d))
{
marker.mark(d);
laplacian[d] = computeLaplacianCotanVertex<PFP>(map, d, position, edgeWeight, vertexArea) ;
laplacian[d] = computeLaplacianCotanVertex<PFP, ATTR_TYPE>(map, d, edgeWeight, vertexArea, attr) ;
}
}
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -22,8 +22,8 @@
* *
*******************************************************************************/
#ifndef __LINEAR_SOLVING_LAPLACIAN_SETUP__
#define __LINEAR_SOLVING_LAPLACIAN_SETUP__
#ifndef __LINEAR_SOLVING_VARIABLES_SETUP__
#define __LINEAR_SOLVING_VARIABLES_SETUP__
namespace CGoGN
{
......@@ -31,80 +31,122 @@ namespace CGoGN
namespace LinearSolving
{
template<typename PFP, class SOLVER_TRAITS>
class FunctorLaplacianTopo : public FunctorMap<typename PFP::MAP>
template <typename PFP, typename ATTR_TYPE, class SOLVER_TRAITS>
class FunctorMeshToSolver_Scalar : public FunctorType
{
protected:
LinearSolver<SOLVER_TRAITS>* solver ;
const AttributeHandler<unsigned int>& indexTable ;
CellMarker& lockingMarker ;
const AttributeHandler<ATTR_TYPE>& attrTable ;
bool lockedVertices ;
public:
typedef typename PFP::MAP MAP ;
FunctorMeshToSolver_Scalar(
LinearSolver<SOLVER_TRAITS>* s,
const AttributeHandler<unsigned int> index,
CellMarker& lm,
const AttributeHandler<ATTR_TYPE>& attr
) : solver(s), indexTable(index), lockingMarker(lm), attrTable(attr), lockedVertices(false)
{}
bool operator()(Dart d)
{
solver->variable(indexTable[d]).set_value(attrTable[d]) ;
if(lockingMarker.isMarked(d))
{
solver->variable(indexTable[d]).lock() ;
lockedVertices = true ;
}
return false ;
}
bool hasLockedVertices() { return lockedVertices ; }
} ;
FunctorLaplacianTopo(MAP& m, LinearSolver<SOLVER_TRAITS>* s, const AttributeHandler<unsigned int> index) :
FunctorMap<MAP>(m), solver(s), indexTable(index)
template <typename PFP, typename ATTR_TYPE, class SOLVER_TRAITS>
class FunctorMeshToSolver_Vector : public FunctorType
{
protected:
LinearSolver<SOLVER_TRAITS>* solver ;
const AttributeHandler<unsigned int>& indexTable ;
CellMarker& lockingMarker ;
const AttributeHandler<ATTR_TYPE>& attrTable ;
unsigned int coord ;
bool lockedVertices ;
public:
FunctorMeshToSolver_Vector(
LinearSolver<SOLVER_TRAITS>* s,
const AttributeHandler<unsigned int> index,
CellMarker& lm,
const AttributeHandler<ATTR_TYPE>& attr,
unsigned int c
) : solver(s), indexTable(index), lockingMarker(lm), attrTable(attr), coord(c), lockedVertices(false)
{}
bool operator()(Dart d)
{
solver->begin_row() ;
Dart dd = d ;
float aii = 0.0f ;
do
solver->variable(indexTable[d]).set_value((attrTable[d])[coord]) ;
if(lockingMarker.isMarked(d))
{
float aij = 1.0f ;
aii += aij ;
solver->add_coefficient(indexTable[this->m_map.phi2(dd)], aij) ;
dd = this->m_map.phi1(this->m_map.phi2(dd)) ;
} while(dd != d) ;
solver->add_coefficient(indexTable[d], -aii) ;
solver->set_right_hand_side(0.0f) ;
solver->normalize_row() ;
solver->end_row() ;
solver->variable(indexTable[d]).lock() ;
lockedVertices = true ;
}
return false ;
}
bool hasLockedVertices() { return lockedVertices ; }
} ;
template<typename PFP, class SOLVER_TRAITS>
class FunctorLaplacianCotan : public FunctorMap<typename PFP::MAP>
template <typename PFP, typename ATTR_TYPE, class SOLVER_TRAITS>
class FunctorSolverToMesh_Scalar : public FunctorType
{
protected:
LinearSolver<SOLVER_TRAITS>* solver ;
const AttributeHandler<unsigned int>& indexTable ;
const typename PFP::TREAL& edgeWeight ;
const typename PFP::TREAL& vertexArea ;
AttributeHandler<ATTR_TYPE>& attrTable ;
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::REAL REAL ;
FunctorSolverToMesh_Scalar(
LinearSolver<SOLVER_TRAITS>* s,
const AttributeHandler<unsigned int> index,
AttributeHandler<ATTR_TYPE>& attr
) : solver(s), indexTable(index), attrTable(attr)
{}
bool operator()(Dart d)
{
attrTable[d] = solver->variable(indexTable[d]).value() ;
return false ;
}
} ;
FunctorLaplacianCotan(MAP& m, LinearSolver<SOLVER_TRAITS>* s, const AttributeHandler<unsigned int> index, const typename PFP::TREAL& eWeight, const typename PFP::TREAL& vArea) :
FunctorMap<MAP>(m), solver(s), indexTable(index), edgeWeight(eWeight), vertexArea(vArea)
template <typename PFP, typename ATTR_TYPE, class SOLVER_TRAITS>
class FunctorSolverToMesh_Vector : public FunctorType
{
protected:
LinearSolver<SOLVER_TRAITS>* solver ;
const AttributeHandler<unsigned int>& indexTable ;
AttributeHandler<ATTR_TYPE>& attrTable ;
unsigned int coord ;
public:
FunctorSolverToMesh_Vector(
LinearSolver<SOLVER_TRAITS>* s,
const AttributeHandler<unsigned int> index,
AttributeHandler<ATTR_TYPE>& attr,
unsigned int c
) : solver(s), indexTable(index), attrTable(attr), coord(c)
{}
bool operator()(Dart d)
{
solver->begin_row() ;
Dart it = d ;
REAL vArea = vertexArea[d] ;
REAL aii = 0 ;
do
{
typename PFP::REAL aij = edgeWeight[it] / vArea ;
aii += aij ;
solver->add_coefficient(indexTable[this->m_map.phi2(it)], aij) ;
it = this->m_map.alpha1(it) ;
} while(it != d) ;
solver->add_coefficient(indexTable[d], -aii) ;
solver->set_right_hand_side(0.0f) ;
solver->normalize_row() ;
solver->end_row() ;
(attrTable[d])[coord] = solver->variable(indexTable[d]).value() ;
return false ;
}
} ;
}
} // namespace LinearSolving
}
} // namespace CGoGN
#endif
Markdown is supported
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