Commit b780824b authored by untereiner's avatar untereiner

- adding multilevel extrusion to importMeshExtrud

- volumetric decimation
parent 6a57cabf
...@@ -621,7 +621,7 @@ void MyQT::cb_keyPress(int keycode) ...@@ -621,7 +621,7 @@ void MyQT::cb_keyPress(int keycode)
// Sélectionne des faces // Sélectionne des faces
case 'f': case 'f':
d_faces.clear(); d_faces.clear();
Algo::Selection:: facesRaySelection<PFP>(myMap, position, SelectorTrue(), rayA, AB, d_faces); Algo::Selection::facesRaySelection<PFP>(myMap, position, SelectorTrue(), rayA, AB, d_faces);
if (!d_faces.empty()) if (!d_faces.empty())
{ {
......
...@@ -126,7 +126,7 @@ void decimate( ...@@ -126,7 +126,7 @@ void decimate(
selector = new EdgeSelector_Curvature<PFP>(map, position, approximators, selected) ; selector = new EdgeSelector_Curvature<PFP>(map, position, approximators, selected) ;
break ; break ;
case S_MinDetail : case S_MinDetail :
selector = new EdgeSelector_Random<PFP>(map, position, approximators, selected) ; selector = new EdgeSelector_MinDetail<PFP>(map, position, approximators, selected) ;
break ; break ;
case S_hLightfield : case S_hLightfield :
selector = new HalfEdgeSelector_Lightfield<PFP>(map, position, approximators, selected) ; selector = new HalfEdgeSelector_Lightfield<PFP>(map, position, approximators, selected) ;
......
...@@ -946,14 +946,10 @@ bool EdgeSelector_MinDetail<PFP>::init() ...@@ -946,14 +946,10 @@ bool EdgeSelector_MinDetail<PFP>::init()
edges.clear() ; edges.clear() ;
CellMarker<EDGE> eMark(m) ; TraversorE<MAP> travE(m);
for(Dart d = m.begin(); d != m.end(); m.next(d)) for(Dart dit = travE.begin() ; dit != travE.end() ; dit = travE.next())
{ {
if(!eMark.isMarked(d)) initEdgeInfo(dit);
{
initEdgeInfo(d) ; // init the edges with their optimal position
eMark.mark(d) ; // and insert them in the multimap according to their error
}
} }
cur = edges.begin() ; // init the current edge to the first one cur = edges.begin() ; // init the current edge to the first one
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define __APPROXIMATOR_VOLUMES_H__ #define __APPROXIMATOR_VOLUMES_H__
#include "Algo/DecimationVolumes/operator.h" #include "Algo/DecimationVolumes/operator.h"
#include "Algo/DecimationVolumes/predictor.h"
namespace CGoGN namespace CGoGN
{ {
...@@ -38,7 +39,7 @@ namespace DecimationVolumes ...@@ -38,7 +39,7 @@ namespace DecimationVolumes
enum ApproximatorType enum ApproximatorType
{ {
A_Centroid //barycenter of the n-cells A_QEM
}; };
template <typename PFP> template <typename PFP>
...@@ -60,9 +61,12 @@ public: ...@@ -60,9 +61,12 @@ public:
virtual const std::string& getApproximatedAttributeName() const = 0 ; virtual const std::string& getApproximatedAttributeName() const = 0 ;
virtual ApproximatorType getType() const = 0 ; virtual ApproximatorType getType() const = 0 ;
virtual bool init() = 0 ; virtual bool init() = 0 ;
virtual const PredictorGen<PFP>* getPredictor() const = 0 ;
virtual void approximate(Operator<PFP>* op) = 0 ; virtual void approximate(Operator<PFP>* op) = 0 ;
virtual void saveApprox(Operator<PFP>* op) = 0 ; virtual void saveApprox(Operator<PFP>* op) = 0 ;
virtual void affectApprox(Operator<PFP>* op) = 0 ; virtual void affectApprox(Operator<PFP>* op) = 0 ;
virtual void approximate(Dart d) = 0;
} ; } ;
...@@ -74,39 +78,91 @@ public: ...@@ -74,39 +78,91 @@ public:
typedef typename PFP::REAL REAL; typedef typename PFP::REAL REAL;
protected: protected:
Predictor<PFP, T>* m_predictor ;
//TODO ajouter un predictor //Vertex attribute to be approximated
VertexAttribute<T>& m_attrV;
VertexAttribute<T>& m_attrV; // vertex attribute to be approximated //Attribute to store approximation result
EdgeAttribute<T> m_approx;
//TODO Attribute to store approximation result // attribute to store detail information for reconstruction
//TODO attribute to store detail information for reconstruction EdgeAttribute<T> m_detail ;
T m_app; T m_app;
public: public:
Approximator(MAP& m, VertexAttribute<T>& a): Approximator(MAP& m, VertexAttribute<T>& a, Predictor<PFP, T>* predictor) :
ApproximatorGen<PFP>(m), m_attrV(a) ApproximatorGen<PFP>(m), m_predictor(predictor), m_attrV(a)
{} {
std::stringstream aname ;
aname << "approx_" << m_attrV.name() ;
m_approx = this->m_map.template addAttribute<T, EDGE>(aname.str()) ;
if(m_predictor) // if a predictor is associated to the approximator
{ // create an attribute to store the detail needed for reconstruction
std::stringstream dname ;
dname << "detail_" << m_attrV.name() ;
m_detail = this->m_map.template addAttribute<T, EDGE>(dname.str()) ;
}
}
//virtual ~Approximator(); virtual ~Approximator()
{
this->m_map.template removeAttribute(m_approx) ;
if(m_predictor)
this->m_map.template removeAttribute(m_detail) ;
}
const std::string& getApproximatedAttributeName() const const std::string& getApproximatedAttributeName() const
{ {
return m_attrV.name() ; return m_attrV.name() ;
} }
void saveApprox(Operator<PFP>* op) const T& getApprox(Dart d) const
{ {
Dart d = op->getEdge(); return m_approx[d] ;
//m_app = m_approx[d] ; }
const Predictor<PFP, T>* getPredictor() const
{
return m_predictor ;
} }
void affectApprox(Operator<PFP>* op) const T& getDetail(Dart d) const
{
assert(m_predictor || !"Trying to get detail on a non-predictive scheme") ;
return m_detail[d] ;
}
void setDetail(Dart d, T& val)
{
assert(m_predictor || !"Trying to set detail on a non-predictive scheme") ;
m_detail[d] = val ;
}
virtual void saveApprox(Operator<PFP>* op)
{ {
Dart d = op->getEdge(); Dart d = op->getEdge();
m_attrV[d] = m_app ; m_app = m_approx[d];
} }
virtual void affectApprox(Operator<PFP>* op)
{
Dart d = op->getEdge();
m_attrV[d] = m_app;
}
// void saveApprox(Dart d)
// {
// m_app = m_approx[d] ;
// }
//
// void affectApprox(Dart d)
// {
// m_attrV[d] = m_app ;
// }
}; };
......
...@@ -38,13 +38,13 @@ void decimate( ...@@ -38,13 +38,13 @@ void decimate(
) )
{ {
std::vector<ApproximatorGen<PFP>*> approximators ; std::vector<ApproximatorGen<PFP>*> approximators ;
Selector<PFP>* selector = NULL ; EdgeSelector<PFP>* selector = NULL ;
//choose the Approximator //choose the Approximator
switch(a) switch(a)
{ {
case A_Centroid : case A_QEM :
approximators.push_back(new Approximator_Centroid<PFP>(map, position)) ; approximators.push_back(new Approximator_QEM<PFP>(map, position)) ;
break ; break ;
default : default :
CGoGNout << "not yet implemented" << CGoGNendl; CGoGNout << "not yet implemented" << CGoGNendl;
...@@ -54,11 +54,8 @@ void decimate( ...@@ -54,11 +54,8 @@ void decimate(
//choose the Selector //choose the Selector
switch(s) switch(s)
{ {
case S_MapOrder : case S_QEM :
selector = new EdgeSelector_MapOrder<PFP>(map, position, approximators, selected); selector = new EdgeSelector_QEM<PFP>(map, position, approximators, selected) ;
break ;
case S_Random :
//selector = new EdgeSelector_Random<PFP>(map, position, approximators, selected);
break ; break ;
default: default:
CGoGNout << "not yet implemented" << CGoGNendl; CGoGNout << "not yet implemented" << CGoGNendl;
...@@ -77,33 +74,38 @@ void decimate( ...@@ -77,33 +74,38 @@ void decimate(
CGoGNout << " decimate (" << nbVertices << " vertices).." << /* flush */ CGoGNendl ; CGoGNout << " decimate (" << nbVertices << " vertices).." << /* flush */ CGoGNendl ;
bool finished = false ; bool finished = false ;
Dart d;
while(!finished) while(!finished)
{ {
//Next Operator to perform //Next Operator to perform
Operator<PFP> *op; Operator<PFP> *op;
if(!selector->nextOperator(&op)) //if(!selector->nextOperator(&op))
if((op = selector->nextOperator()) == NULL)
break; break;
// compute approximated attributes // compute approximated attributes
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it) for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
{ {
(*it)->approximate(op) ; (*it)->approximate(op) ;
(*it)->saveApprox(op) ;
} }
//Update the selector before performing operation //Update the selector before performing operation
selector->updateBeforeOperation(&op); if(!selector->updateBeforeOperation(op))
break;
//Perform the topological operation and //Perform the topological operation and
//compute the number of resulting cells //compute the number of resulting cells
nbVertices -= op->perform(map, position); nbVertices -= op->perform(map, position);
//for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it) for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
// (*it)->affectApprox(op); // affect data to the resulting vertex (*it)->affectApprox(op); // affect data to the resulting vertex
//Update the embedded position and //Update the embedded position and
//search the next operation to perform //search the next operation to perform
selector->updateAfterOperation(&op); selector->updateAfterOperation(op);
if(nbVertices <= nbWantedVertices) if(nbVertices <= nbWantedVertices)
finished = true ; finished = true ;
...@@ -126,3 +128,35 @@ void decimate( ...@@ -126,3 +128,35 @@ void decimate(
} //namespace Algo } //namespace Algo
} //namespace CGoGN } //namespace CGoGN
// if(!selector->nextEdge(d))
// break ;
//
//
// Dart d2 = map.phi2(map.phi_1(d)) ;
// Dart dd2 = map.phi2(map.phi_1(map.phi2(d))) ;
//
// std::cout << "bin a contracter : " << d << std::endl;
// std::cout << "voisin d2 : " << d2 << std::endl;
// std::cout << "voisin dd2 : " << dd2 << std::endl;
//
// --nbVertices ;
//
// for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
// {
// (*it)->approximate(d) ; // compute approximated attributes
// (*it)->saveApprox(d) ;
// }
//
// selector->updateBeforeCollapse(d) ; // update selector
//
// map.collapseEdge(d) ; // collapse edge
//
// for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
// (*it)->affectApprox(d2); // affect data to the resulting vertex
//
// selector->updateAfterCollapse(d2, dd2) ;// update selector
//
// if(nbVertices <= nbWantedVertices)
// finished = true ;
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "Container/fakeAttribute.h" #include "Container/fakeAttribute.h"
#include "Algo/DecimationVolumes/selector.h" #include "Algo/DecimationVolumes/selector.h"
#include "Algo/DecimationVolumes/operator.h" #include "Algo/DecimationVolumes/operator.h"
#include "Utils/qem.h"
#include "Topology/generic/traversorCell.h"
namespace CGoGN namespace CGoGN
{ {
...@@ -35,140 +37,62 @@ public: ...@@ -35,140 +37,62 @@ public:
}; };
/********************************************************************************
* Map Order Edge Selector *
********************************************************************************/
template <typename PFP> template <typename PFP>
class EdgeSelector_MapOrder : public EdgeSelector<PFP> class EdgeSelector_QEM : public EdgeSelector<PFP>
{ {
public: public:
typedef typename PFP::MAP MAP ; typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3 ; typedef typename PFP::VEC3 VEC3;
typedef typename PFP::REAL REAL; typedef typename PFP::REAL REAL;
private: private:
Dart cur; typedef struct
{
typename std::multimap<float, Dart>::iterator it;
bool valid;
static std::string CGoGNnameOfType() { return "QEMedgeInfo" ; }
} QEMedgeInfo;
public: typedef NoMathIOAttribute<QEMedgeInfo> EdgeInfo;
EdgeSelector_MapOrder(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
EdgeSelector<PFP>(m, pos, approx, select)
{}
~EdgeSelector_MapOrder() EdgeAttribute<EdgeInfo> edgeInfo;
{} VertexAttribute<Quadric<REAL> > quadric;
Quadric<REAL> tmpQ;
SelectorType getType() { return S_MapOrder; } std::multimap<float, Dart> edges;
Dart nextCell() { return cur; } typename std::multimap<float, Dart>::iterator cur;
bool init(); Approximator<PFP, typename PFP::VEC3>* m_positionApproximator;
bool nextOperator(Operator<PFP>** op);
void updateBeforeOperation(Operator<PFP>** op)
{ }
void updateAfterOperation(Operator<PFP>** op);
void finish()
{ }
void initEdgeInfo(Dart d);
void updateEdgeInfo(Dart d, bool recompute);
void computeEdgeInfo(Dart d, EdgeInfo& einfo);
public:
EdgeSelector_QEM(MAP& m, VertexAttribute<typename PFP::VEC3>& pos,
std::vector<ApproximatorGen<PFP>* >& approx, const FunctorSelect& select) :
EdgeSelector<PFP>(m, pos, approx, select)
{
edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo");
quadric = m.template addAttribute<Quadric<REAL>, VERTEX>("QEMquadric");
}
~EdgeSelector_QEM()
{
this->m_map.removeAttribute(quadric);
this->m_map.removeAttribute(edgeInfo);
}
SelectorType getType() { return S_QEM; }
bool init();
Operator<PFP>* nextOperator();
bool updateBeforeOperation(Operator<PFP>* op);
void updateAfterOperation(Operator<PFP>* op);
void finish() { }
}; };
/********************************************************************************
* Random Selector *
********************************************************************************/
//template <typename PFP>
//class EdgeSelector_Random : public EdgeSelector<PFP>
//{
//public:
// typedef typename PFP::MAP MAP ;
// typedef typename PFP::VEC3 VEC3 ;
// typedef typename PFP::REAL REAL ;
//
//private:
// std::vector<Dart> darts ;
// unsigned int cur ;
// bool allSkipped ;
//
//public:
// EdgeSelector_Random(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
// EdgeSelector<PFP>(m, pos, approx, select)
// {}
//
// ~EdgeSelector_Random()
// {}
//
// SelectorType getType() { return S_Random; }
//// Dart nextCell() { return darts[cur]; }
//
// bool init();
// bool nextOperator(Operator<PFP>** op);
// void updateBeforeOperation(Operator<PFP>* op)
// { }
// void updateAfterOperation(Operator<PFP>* op);
// void finish()
// { }
//
//} ;
///********************************************************************************
// * Length Edge Selector *
// ********************************************************************************/
//template <typename PFP>
//class EdgeSelector_Length : public EdgeSelector<PFP>
//{
//public:
// typedef typename PFP::MAP MAP;
// typedef typename PFP::VEC3 VEC3;
// typedef typename PFP::REAL REAL;
//
//protected:
// /*
// * Update the Edge Informations
// */
// void updateEdgeInfo(Dart d, typename PFP::VEC3 e);
// /*
// * Init the Edge informations
// */
// void initEdgeInfo(Dart d);
// /*
// * Erase The Edge informations
// */
// void eraseEdgeInfo(Dart d);
//
//private:
// //New embedding type for storing informations
// typedef struct {
// typename std::multimap<float,Dart>::iterator it ;
// bool valid ;
// } LengthEdgeInfo ;
//
// typedef NoMathIOAttribute<LengthEdgeInfo> EdgeInfo ;
//
// EdgeAttribute<EdgeInfo> edgeInfo ;
//
// std::multimap<float,Dart> edges ;
// typename std::multimap<float,Dart>::iterator cur ;
//
//
//public:
// EdgeSelector_Length(MAP& m, VertexAttribute<typename PFP::VEC3>& pos) :
// EdgeSelector<PFP>(m, pos)
// {
// edgeInfo = m.template addAttribute<EdgeInfo>(EDGE, "edgeInfo") ;
// }
//
// ~EdgeSelector_Length()
// {
// this->m_map.removeAttribute(edgeInfo) ;
// }
//
// SelectorType getType() { return S_EdgeLength; }
// Dart nexCell() { return (*cur).second; }
//
// void init(Algo::DecimationVolumique::Approximator<PFP>* approx);
// bool nextOperator();
// void updateBeforeOperation(Algo::DecimationVolumique::Operator<PFP>* op);
// void updateAfterOperation(Algo::DecimationVolumique::Operator<PFP>* op);
// void finish()
// { }
//};
} //end namespace DecimationVolumes } //end namespace DecimationVolumes
......
...@@ -35,179 +35,222 @@ namespace DecimationVolumes ...@@ -35,179 +35,222 @@ namespace DecimationVolumes
{ {
/************************************************************************************ /************************************************************************************
* Map Order Edge Selector * * QUADRIC ERROR METRIC *
************************************************************************************/ ************************************************************************************/
template <typename PFP> template <typename PFP>
bool EdgeSelector_MapOrder<PFP>::init() bool EdgeSelector_QEM<PFP>::init()
{ {
cur = this->m_map.begin() ; MAP& m = this->m_map ;
//searching the Geometry Approximator
bool ok = false ;
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = this->m_approximators.begin();
it != this->m_approximators.end() && !ok;
++it)
{
if((*it)->getApproximatedAttributeName() == "position")