Commit 4323777e authored by Sylvain Thery's avatar Sylvain Thery

Merge branch 'master' of cgogn:~untereiner/CGoGN

parents cd46a2be 244d50f3
......@@ -146,21 +146,21 @@ void MyQT::cb_Open()
size_t pos = filename.rfind("."); // position of "." in filename
std::string extension = filename.substr(pos);
if(extension == std::string(".off"))
{
if(!Algo::Volume::Import::importMeshToExtrude<PFP>(myMap, filename, attrNames))
{
std::cerr << "could not import " << filename << std::endl ;
return ;
}
else
{
position = myMap.getAttribute<PFP::VEC3, VERTEX>(attrNames[0]) ;
myMap.closeMap();
}
}
else
{
// if(extension == std::string(".off"))
// {
// if(!Algo::Volume::Import::importMeshToExtrude<PFP>(myMap, filename, attrNames))
// {
// std::cerr << "could not import " << filename << std::endl ;
// return ;
// }
// else
// {
// position = myMap.getAttribute<PFP::VEC3, VERTEX>(attrNames[0]) ;
// myMap.closeMap();
// }
// }
// else
// {
if(!Algo::Volume::Import::importMesh<PFP>(myMap, filename, attrNames))
{
std::cerr << "could not import " << filename << std::endl ;
......@@ -168,7 +168,7 @@ void MyQT::cb_Open()
}
else
position = myMap.getAttribute<PFP::VEC3,VERTEX>(attrNames[0]) ;
}
// }
color = myMap.addAttribute<PFP::VEC3, VOLUME>("color");
......
......@@ -357,10 +357,9 @@ void MyQT::cb_Open()
void MyQT::cb_Save()
{
std::string filename = selectFileSave("Export Map file ",".","(*.map)");
//Algo::Surface::Export::exportOFF<PFP>(myMap,position,filename.c_str());
if(!myMap.saveMapBin(filename))
std::cout << "could not save file : " << filename << std::endl;
std::string filename = selectFileSave("Export Off file ",".","(*.off)");
Algo::Surface::Export::exportOFF<PFP>(myMap,position,filename.c_str());
//std::cout << "could not save file : " << filename << std::endl;
}
void MyQT::importMesh(std::string& filename)
......
......@@ -44,7 +44,10 @@ enum ApproximatorType
{
A_QEM,
A_MidEdge,
A_hHalfCollapse
A_MidFace,
A_MidVolume,
A_hHalfEdgeCollapse,
A_QEM
};
template <typename PFP>
......@@ -63,7 +66,7 @@ public:
{}
virtual ~ApproximatorGen()
{}
virtual const std::string& getApproximatedAttributeName() const = 0 ;
virtual const std::string& getApproximatedAttributeName(unsigned int index = 0) const = 0 ;
virtual ApproximatorType getType() const = 0 ;
virtual bool init() = 0 ;
virtual void approximate(Dart d) = 0 ;
......@@ -73,67 +76,101 @@ public:
} ;
template <typename PFP, typename T>
template <typename PFP, typename T, unsigned int ORBIT>
class Approximator : public ApproximatorGen<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL;
protected:
Predictor<PFP, T>* m_predictor ;
//Vertex attribute to be approximated
VertexAttribute<T>& m_attrV;
//Attribute to store approximation result
EdgeAttribute<T> m_approx;
// attribute to store detail information for reconstruction
EdgeAttribute<T> m_detail ;
T m_app;
std::vector<VertexAttribute<T>* > m_attrV ; // vertex attributes to be approximated
std::vector<AttributeHandler<T,ORBIT> > m_approx ; // attributes to store approximation result
std::vector<AttributeHandler<T,ORBIT> > m_detail ; // attributes to store detail information for reconstruction
std::vector<T> m_app ;
public:
Approximator(MAP& m, VertexAttribute<T>& a, Predictor<PFP, T>* predictor) :
ApproximatorGen<PFP>(m), m_predictor(predictor), m_attrV(a)
Approximator(MAP& m, std::vector<VertexAttribute<T>* > va, Predictor<PFP, T> * predictor) :
ApproximatorGen<PFP>(m), m_predictor(predictor), m_attrV(va)
{
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()) ;
const unsigned int& size = m_attrV.size() ;
assert(size > 0 || !"Approximator: no attributes provided") ;
m_approx.resize(size) ;
m_detail.resize(size) ;
m_app.resize(size) ;
for (unsigned int i = 0 ; i < size ; ++i)
{
if (!m_attrV[i]->isValid())
std::cerr << "Approximator Warning: attribute number " << i << " is not valid" << std::endl ;
std::stringstream aname ;
aname << "approx_" << m_attrV[i]->name() ;
m_approx[i] = this->m_map.template addAttribute<T, ORBIT>(aname.str()) ;
if(m_predictor) // if predictors are associated to the approximator
{ // create attributes to store the details needed for reconstruction
std::stringstream dname ;
dname << "detail_" << m_attrV[i]->name() ;
m_detail[i] = this->m_map.template addAttribute<T, ORBIT>(dname.str()) ;
}
}
}
virtual ~Approximator()
{
this->m_map.template removeAttribute(m_approx) ;
if(m_predictor)
this->m_map.template removeAttribute(m_detail) ;
for (unsigned int i = 0 ; i < m_attrV.size() ; ++i)
{
this->m_map.template removeAttribute(m_approx[i]) ;
if(m_predictor)
this->m_map.template removeAttribute(m_detail[i]) ;
}
}
const std::string& getApproximatedAttributeName() const
const std::string& getApproximatedAttributeName(unsigned int index = 0) const
{
return m_attrV.name() ;
return m_attrV[index]->name() ;
}
const T& getApprox(Dart d) const
unsigned int getNbApproximated() const
{
return m_approx[d] ;
return m_attrV.size() ;
}
void saveApprox(Dart d)
{
m_app = m_approx[d] ;
for (unsigned int i = 0 ; i < m_attrV.size() ; ++i)
m_app[i] = m_approx[i][d] ;
}
void affectApprox(Dart d)
{
m_attrV[d] = m_app ;
for (unsigned int i = 0 ; i < m_attrV.size() ; ++i)
m_attrV[i]->operator[](d) = m_app[i] ;
}
const T& getApprox(Dart d, unsigned int index = 0) const
{
return m_approx[index][d] ;
}
const VertexAttribute<T>& getAttr(unsigned int index = 0) const
{
return *(m_attrV[index]) ;
}
std::vector<T> getAllApprox(Dart d) const
{
std::vector<T> res ;
res.resize(m_attrV.size()) ;
for (unsigned int i = 0 ; i < m_attrV.size() ; ++i)
res[i] = m_approx[i][d] ;
return res ;
}
const Predictor<PFP, T>* getPredictor() const
......
......@@ -40,16 +40,18 @@ namespace Decimation
{
template <typename PFP>
class Approximator_MidEdge : public Approximator<PFP, typename PFP::VEC3>
class Approximator_MidEdge : public Approximator<PFP, typename PFP::VEC3, EDGE>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
Approximator_MidEdge(MAP& m, VertexAttribute<VEC3>& pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3>(m, pos, pred)
{}
Approximator_MidEdge(MAP& m, std::vector<VertexAttribute<VEC3>* > pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3, EDGE>(m, pos, pred)
{
assert(pos.size() > 0 || !"Approximator_MidEdge: attribute vector is empty") ;
}
~Approximator_MidEdge()
{}
ApproximatorType getType() const { return A_MidEdge ; }
......@@ -58,25 +60,90 @@ public:
} ;
template <typename PFP>
class Approximator_HalfCollapse : public Approximator<PFP, typename PFP::VEC3>
class Approximator_MidFace : public Approximator<PFP, typename PFP::VEC3, FACE>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
Approximator_MidFace(MAP& m, std::vector<VertexAttribute<VEC3>* > pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3, FACE>(m, pos, pred)
{
assert(pos.size() > 0 || !"Approximator_MidFace: attribute vector is empty") ;
}
~Approximator_MidFace()
{}
ApproximatorType getType() const { return A_MidFace ; }
bool init() ;
void approximate(Dart d) ;
} ;
template <typename PFP>
class Approximator_MidVolume : public Approximator<PFP, typename PFP::VEC3, VOLUME>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
Approximator_HalfCollapse(MAP& m, VertexAttribute<VEC3>& pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3>(m, pos, pred)
Approximator_MidVolume(MAP& m, std::vector<VertexAttribute<VEC3>* > pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3, VOLUME>(m, pos, pred)
{
assert(pos.size() > 0 || !"Approximator_HalfCollapse: attribute vector is empty") ;
assert(pos.size() > 0 || !"Approximator_MidVolume: attribute vector is empty") ;
}
~Approximator_HalfCollapse()
~Approximator_MidVolume()
{}
ApproximatorType getType() const { return A_hHalfCollapse ; }
ApproximatorType getType() const { return A_MidVolume ; }
bool init() ;
void approximate(Dart d) ;
} ;
template <typename PFP>
class Approximator_HalfEdgeCollapse : public Approximator<PFP, typename PFP::VEC3, DART>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
Approximator_HalfEdgeCollapse(MAP& m, std::vector<VertexAttribute<VEC3>* > pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3, DART>(m, pos, pred)
{
assert(pos.size() > 0 || !"Approximator_HalfEdgeCollapse: attribute vector is empty") ;
}
~Approximator_HalfEdgeCollapse()
{}
ApproximatorType getType() const { return A_hHalfEdgeCollapse ; }
bool init() ;
void approximate(Dart d) ;
} ;
//template <typename PFP>
//class Approximator_QEM : public Approximator<PFP, typename PFP::VEC3, EDGE>
//{
//public:
// typedef typename PFP::MAP MAP ;
// typedef typename PFP::VEC3 VEC3 ;
// typedef typename PFP::REAL REAL ;
//
//protected:
// VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
//
//public:
// Approximator_QEM(MAP& m, std::vector<VertexAttribute<VEC3>* > pos, Predictor<PFP, VEC3>* pred = NULL) :
// Approximator<PFP, VEC3, EDGE>(m, pos, pred)
// {
// assert(pos.size() > 0 || !"Approximator_QEM: attribute vector is empty") ;
// }
// ~Approximator_QEM()
// {}
// ApproximatorType getType() const { return A_QEM ; }
// bool init() ;
// void approximate(Dart d) ;
//} ;
} //namespace Decimation
......
......@@ -53,19 +53,78 @@ void Approximator_MidEdge<PFP>::approximate(Dart d)
MAP& m = this->m_map ;
// get some darts
Dart dd = m.phi2(d) ;
Dart d1 = m.phi1(d) ;
// get the contracted edge vertices positions
VEC3 v1 = this->m_attrV[d] ;
VEC3 v2 = this->m_attrV[dd] ;
VEC3 v1 = this->m_attrV[0]->operator[](d) ;
VEC3 v2 = this->m_attrV[0]->operator[](d1) ;
// Compute the approximated position
this->m_approx[d] = (v1 + v2) / REAL(2) ;
this->m_approx[0][d] = (v1 + v2) / REAL(2) ;
// if(this->m_predictor)
// {
//
// }
//TODO predictor part
}
/************************************************************************************
* MID FACE *
************************************************************************************/
template <typename PFP>
bool Approximator_MidFace<PFP>::init()
{
return true ;
}
template <typename PFP>
void Approximator_MidFace<PFP>::approximate(Dart d)
{
MAP& m = this->m_map ;
// get some darts
Dart d1 = m.phi1(d) ;
Dart d_1 = m.phi_1(d) ;
// get the contracted edge vertices positions
VEC3 v1 = this->m_attrV[0]->operator[](d) ;
VEC3 v2 = this->m_attrV[0]->operator[](d1) ;
VEC3 v3 = this->m_attrV[0]->operator[](d_1) ;
// Compute the approximated position
this->m_approx[0][d] = (v1 + v2 + v3) / REAL(3) ;
//TODO predictor part
}
/************************************************************************************
* MID VOLUME *
************************************************************************************/
template <typename PFP>
bool Approximator_MidVolume<PFP>::init()
{
return true ;
}
template <typename PFP>
void Approximator_MidVolume<PFP>::approximate(Dart d)
{
MAP& m = this->m_map ;
// get some darts
Dart d1 = m.phi1(d) ;
Dart d_1 = m.phi_1(d) ;
Dart d2_1 = m.phi_1(m.phi2(d)) ;
// get the contracted edge vertices positions
VEC3 v1 = this->m_attrV[0]->operator[](d) ;
VEC3 v2 = this->m_attrV[0]->operator[](d1) ;
VEC3 v3 = this->m_attrV[0]->operator[](d_1) ;
VEC3 v4 = this->m_attrV[0]->operator[](d2_1) ;
// Compute the approximated position
this->m_approx[0][d] = (v1 + v2 + v3 + v4) / REAL(4) ;
//TODO predictor part
}
/************************************************************************************
......@@ -73,54 +132,37 @@ void Approximator_MidEdge<PFP>::approximate(Dart d)
************************************************************************************/
template <typename PFP>
bool Approximator_HalfCollapse<PFP>::init()
bool Approximator_HalfEdgeCollapse<PFP>::init()
{
// if(this->m_predictor)
// {
// if(! ( this->m_predictor->getType() == P_HalfCollapse ) )
// {
// return false ;
// }
// }
return true ;
}
template <typename PFP>
void Approximator_HalfCollapse<PFP>::approximate(Dart d)
void Approximator_HalfEdgeCollapse<PFP>::approximate(Dart d)
{
MAP& m = this->m_map ;
this->m_approx[d] = this->m_attrV[d];
for (unsigned int i = 0 ; i < this->m_attrV.size() ; ++i)
this->m_approx[i][d] = this->m_attrV[i]->operator[](d) ;
//TODO predictor part
}
///************************************************************************************
// * QUADRIC ERROR METRIC *
// ************************************************************************************/
//template <typename PFP>
//bool Approximator_QEM<PFP>::init()
//{
// m_quadric = this->m_map.template getAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
// // Does not require to be valid (if it is not, altenatives will be used).
//
// if(this->m_predictor)
// {
// Dart dd = m.phi2(d) ;
// Dart d2 = m.phi2(m.phi_1(d)) ;
// Dart dd2 = m.phi2(m.phi_1(dd)) ;
//
// VEC3 v2 = this->m_attrV[0]->operator[](dd) ;
//
// // temporary edge collapse
// m.extractTrianglePair(d) ;
// unsigned int newV = m.template embedNewCell<VERTEX>(d2) ;
// for (unsigned int i = 0 ; i < this->m_attrV.size() ; ++i)
// {
// this->m_attrV[i]->operator[](newV) = this->m_approx[i][d] ;
// }
//
// // compute the detail vector
// this->m_predictor->predict(d2, dd2) ;
// for (unsigned int i = 0 ; i < this->m_attrV.size() ; ++i)
// {
// this->m_detail[i][d] = v2 - this->m_predictor->getPredict(1) ;
// }
//
// // vertex split to reset the initial connectivity and embeddings
// m.insertTrianglePair(d, d2, dd2) ;
// m.template embedOrbit<VERTEX>(d, m.template getEmbedding<VERTEX>(d)) ;
// m.template embedOrbit<VERTEX>(dd, m.template getEmbedding<VERTEX>(dd)) ;
// return false ;
// }
}
// return true ;
//}
} //end namespace Decimation
......
......@@ -26,7 +26,7 @@ enum SelectorType
} ;
template <typename PFP> class ApproximatorGen ;
template <typename PFP, typename T> class Approximator ;
template <typename PFP, typename T, unsigned int ORBIT> class Approximator ;
/********************************************************************************
* Parent Selector *
......@@ -62,13 +62,13 @@ public:
virtual void updateWithoutCollapse() = 0;
};
} //end namespace Decimation
} // namespace Decimation
} //namespace Volume
} // namespace Volume
} //end namespace Algo
} // namespace Algo
} //end namespace CGoGN
} // namespace CGoGN
#endif
......@@ -142,6 +142,7 @@ public:
void setDartLevel(Dart d, unsigned int i) ;
/***************************************************
* EDGE ID MANAGEMENT *
***************************************************/
......@@ -160,6 +161,8 @@ public:
void setEdgeId(Dart d, unsigned int i) ;
unsigned int getMaxEdgeId();
/***************************************************
* CELLS INFORMATION *
***************************************************/
......
......@@ -326,6 +326,11 @@ inline void ImplicitHierarchicalMap::setEdgeId(Dart d, unsigned int i)
m_edgeId[d] = i ;
}
inline unsigned int ImplicitHierarchicalMap::getMaxEdgeId()
{
return m_idCount;
}
/***************************************************
* CELLS INFORMATION *
***************************************************/
......
......@@ -146,6 +146,7 @@ inline Dart ImplicitHierarchicalMap3::phi2bis(Dart d)
it = Map3::phi2(it) ;
/* du cote des volumes non subdivise (subdiv adapt) */
if(m_faceId[it] == faceId)
return it;
else
......
......@@ -72,6 +72,8 @@ void subdivideFace(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP:
unsigned int cur = map.getCurrentLevel() ;
map.setCurrentLevel(fLevel) ; // go to the level of the face to subdivide its edges
std::cout << "subdiv" << std::endl;
unsigned int degree = 0 ;
typename PFP::VEC3 p ;
Dart it = old ;
......@@ -92,38 +94,82 @@ void subdivideFace(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP:
Dart dd = map.phi1(old) ;
Dart e = map.phi1(map.phi1(dd)) ;
map.splitFace(dd, e) ; // insert a new edge
unsigned int id = map.getNewEdgeId() ;
map.setEdgeId(map.phi_1(dd), id) ; // set the edge id of the inserted
map.setEdgeId(map.phi_1(e), id) ; // edge to the next available id
//unsigned int id = map.getNewEdgeId() ;
//map.setEdgeId(map.phi_1(dd), id) ; // set the edge id of the inserted
//map.setEdgeId(map.phi_1(e), id) ; // edge to the next available id
dd = e ;
e = map.phi1(map.phi1(dd)) ;
map.splitFace(dd, e) ;
id = map.getNewEdgeId() ;
map.setEdgeId(map.phi_1(dd), id) ;
map.setEdgeId(map.phi_1(e), id) ;
//id = map.getNewEdgeId() ;
//map.setEdgeId(map.phi_1(dd), id) ;
//map.setEdgeId(map.phi_1(e), id) ;
dd = e ;
e = map.phi1(map.phi1(dd)) ;
map.splitFace(dd, e) ;
id = map.getNewEdgeId() ;
map.setEdgeId(map.phi_1(dd), id) ;
map.setEdgeId(map.phi_1(e), id) ;
//id = map.getNewEdgeId() ;
//map.setEdgeId(map.phi_1(dd), id) ;
//map.setEdgeId(map.phi_1(e), id) ;
Dart stop = map.phi2(map.phi1(old));
Dart dit = stop;
do
{
unsigned int dId = map.getEdgeId(map.phi_1(map.phi2(dit)));
unsigned int eId = map.getEdgeId(map.phi1(map.phi2(dit)));
unsigned int t = dId + eId;
if(t == 0)
{
map.setEdgeId(dit, 1);
map.setEdgeId(map.phi2(dit), 1);
}