Commit e6c58f5b authored by untereiner's avatar untereiner

Merge cgogn:~kraemer/CGoGN

parents 4ed0fd10 a52d10da
......@@ -298,7 +298,7 @@ bool MeshTablesSurface<PFP>::importOff(const std::string& filename, std::vector<
do
{
std::getline (fp, ligne);
} while (ligne.size()==0);
} while (ligne.size() == 0);
std::stringstream oss(ligne);
oss >> m_nbVertices;
......@@ -344,10 +344,10 @@ bool MeshTablesSurface<PFP>::importOff(const std::string& filename, std::vector<
} while (ligne.size() == 0);
std::stringstream oss(ligne);
int n;
unsigned int n;
oss >> n;
m_nbEdges.push_back(n);
for (int j=0;j<n; ++j)
for (unsigned int j = 0; j < n; ++j)
{
int index; // index du plongement
oss >> index;
......@@ -455,7 +455,7 @@ bool MeshTablesSurface<PFP>::importObj(const std::string& filename, std::vector<
unsigned int ind = 0;
while ( (ind<str.length()) && (str[ind]!='/'))
while ((ind<str.length()) && (str[ind]!='/'))
ind++;
if (ind > 0)
......
......@@ -35,8 +35,9 @@ namespace Import
{
template <typename PFP>
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, typename PFP::TVEC3& position) ;
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames) ;
template <typename PFP>
class QuadTreeNode
{
public:
......@@ -46,6 +47,7 @@ public:
indices[i] = -1 ;
for(unsigned int i = 0; i < 4; ++i)
children[i] = NULL ;
parent = NULL ;
}
~QuadTreeNode()
......@@ -59,23 +61,112 @@ public:
{
assert(children[0] == NULL) ;
for(unsigned int i = 0; i < 4; ++i)
{
children[i] = new QuadTreeNode() ;
children[i]->parent = this ;
}
}
bool isSubdivided()
{
return children[0] != NULL ;
}
void embed(typename PFP::MAP& map, Dart d, std::vector<unsigned int>& vID, CellMarker& cm, bool CCW)
{
if(isSubdivided())
{
unsigned int emb0 = vID[children[0]->indices[0]] ;
unsigned int emb1 = vID[children[0]->indices[1]] ;
unsigned int emb2 = vID[children[0]->indices[2]] ;
Dart d0 = map.phi1(d) ;
Dart d1, d2 ;
if(CCW)
{
d1 = map.phi_1(d) ;
d2 = d ;
}
else
{
d1 = d ;
d2 = map.phi_1(d) ;
}
map.incCurrentLevel() ;
map.embedOrbit(VERTEX, map.phi1(d0), emb0) ;
map.embedOrbit(VERTEX, map.phi1(d1), emb1) ;
map.embedOrbit(VERTEX, map.phi1(d2), emb2) ;
map.decCurrentLevel() ;
Dart t0 = map.phi_1(d) ;
map.incCurrentLevel() ;
t0 = map.phi2(map.phi1(t0)) ;
children[0]->embed(map, t0, vID, cm, CCW) ;
map.decCurrentLevel() ;
Dart t1 = d ;
map.incCurrentLevel() ;
children[1]->embed(map, t1, vID, cm, !CCW) ;
map.decCurrentLevel() ;
Dart t2 = map.phi1(d) ;
map.incCurrentLevel() ;
t2 = map.phi1(t2) ;
children[2]->embed(map, t2, vID, cm, !CCW) ;
map.decCurrentLevel() ;
Dart t3 = map.phi_1(d) ;
map.incCurrentLevel() ;
t3 = map.phi_1(t3) ;
children[3]->embed(map, t3, vID, cm, !CCW) ;
map.decCurrentLevel() ;
}
}
void print()
{
std::cout << indices[0] << " " << indices[1] << " " << indices[2] << std::endl ;
if(isSubdivided())
{
for(unsigned int i = 0; i < 4; ++i)
children[i]->print() ;
}
}
unsigned int indices[3] ;
QuadTreeNode* children[4] ;
QuadTreeNode* parent ;
} ;
template <typename PFP>
class QuadTree
{
public:
std::vector<QuadTreeNode*> roots ;
std::vector<QuadTreeNode<PFP>*> roots ;
std::vector<Dart> darts ;
~QuadTree()
{
for(unsigned int i = 0; i < roots.size(); ++i)
delete roots[i] ;
}
void embed(typename PFP::MAP& map, std::vector<unsigned int>& vID)
{
CellMarker cm(map, VERTEX) ;
for(unsigned int i = 0; i < roots.size(); ++i)
roots[i]->embed(map, darts[i], vID, cm, true) ;
}
void print()
{
std::cout << "printing quadtree (" << roots.size() << " roots)" << std::endl ;
for(unsigned int i = 0; i < roots.size(); ++i)
{
std::cout << "root " << i << std::endl ;
roots[i]->print() ;
}
}
} ;
} // namespace Import
......
......@@ -39,8 +39,15 @@ inline void nextNonEmptyLine(std::ifstream& fp, std::string& line)
}
template <typename PFP>
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, typename PFP::TVEC3& position)
bool importMRDAT(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames)
{
AttributeHandler<typename PFP::VEC3> position = map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
if (!position.isValid())
position = map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
attrNames.push_back(position.name()) ;
AttributeContainer& container = map.getAttributeContainer(VERTEX) ;
// open file
......@@ -66,8 +73,11 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, typename P
{
nextNonEmptyLine(fp, line) ;
std::stringstream oss(line) ;
std::string s ;
oss >> s ;
oss >> depth ;
}
std::cout << "MR depth -> " << depth << std::endl ;
// read vertices
nextNonEmptyLine(fp, line) ;
......@@ -78,35 +88,35 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, typename P
return false ;
}
std::vector<typename PFP::VEC3> positions ;
std::vector<unsigned int> nbVerticesPerLevel ;
nbVerticesPerLevel.resize(depth + 1) ;
std::vector<unsigned int> verticesID ;
nextNonEmptyLine(fp, line) ;
while(line.rfind("Triangles") != std::string::npos)
while(line.rfind("Triangles") == std::string::npos)
{
std::stringstream oss(line) ;
unsigned int level ;
oss >> level ;
++nbVerticesPerLevel[level - (depth + 1)] ;
float x, y, z ;
oss >> x ;
oss >> y ;
oss >> z ;
positions.push_back(typename PFP::VEC3(x, y, z)) ;
typename PFP::VEC3 pos(x, y, z) ;
unsigned int id = container.insertLine() ;
position[id] = pos ;
verticesID.push_back(id) ;
nextNonEmptyLine(fp, line) ;
}
QuadTree qt ;
QuadTreeNode* current = NULL ;
QuadTree<PFP> qt ;
QuadTreeNode<PFP>* current = NULL ;
unsigned int prevNum = -1 ;
nextNonEmptyLine(fp, line) ;
while(line.rfind("end") != std::string::npos)
while(line.rfind("end") == std::string::npos)
{
std::stringstream oss(line) ;
......@@ -123,7 +133,7 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, typename P
if(root == 1)
{
assert(num == 0) ;
QuadTreeNode* n = new QuadTreeNode() ;
QuadTreeNode<PFP>* n = new QuadTreeNode<PFP>() ;
n->indices[0] = idx0 ;
n->indices[1] = idx1 ;
n->indices[2] = idx2 ;
......@@ -133,28 +143,109 @@ bool importMRDAT(typename PFP::MAP& map, const std::string& filename, typename P
}
else
{
if(num > prevNum) // on lit un autre triangle du même niveau
if(num == prevNum + 1) // on lit un autre triangle du même niveau
{
current = current->parent->children[num] ;
}
else // on subdivise le triangle courant
else // on monte ou on descend d'un niveau
{
if(num == 0)
if(num == 0) // on subdivise le triangle courant
{
current->subdivide() ;
current = current->children[0] ;
}
else
else // on remonte d'un niveau
{
assert(prevNum == 3) ;
assert(current->parent->parent != NULL) ;
current = current->parent->parent->children[num] ;
}
}
current->indices[0] = idx0 ;
current->indices[1] = idx1 ;
current->indices[2] = idx2 ;
prevNum = num ;
}
nextNonEmptyLine(fp, line) ;
}
fp.close();
return true;
fp.close() ;
AutoAttributeHandler< NoMathIONameAttribute< std::vector<Dart> > > vecDartsPerVertex(map, VERTEX, "incidents") ;
DartMarkerNoUnmark m(map) ;
unsigned nbf = qt.roots.size() ;
// for each root face
for(unsigned int i = 0; i < nbf; ++i)
{
Dart d = map.newFace(3, false) ;
qt.darts.push_back(d) ;
for (unsigned int j = 0; j < 3; ++j)
{
unsigned int idx = qt.roots[i]->indices[j] ;
unsigned int emb = verticesID[idx] ;
FunctorSetEmb<typename PFP::MAP> fsetemb(map, VERTEX, emb) ;
map.foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb) ;
m.mark(d) ; // mark on the fly to unmark on second loop
vecDartsPerVertex[emb].push_back(d) ; // store incident darts for fast adjacency reconstruction
d = map.phi1(d) ;
}
}
// reconstruct neighbourhood between root faces
unsigned int nbBoundaryEdges = 0 ;
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
if (m.isMarked(d))
{
// darts incident to end vertex of edge
std::vector<Dart>& vec = vecDartsPerVertex[map.phi1(d)] ;
unsigned int embd = map.getEmbedding(VERTEX, d) ;
Dart good_dart = NIL ;
for (typename std::vector<Dart>::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it)
{
if (map.getEmbedding(VERTEX, map.phi1(*it)) == embd)
good_dart = *it ;
}
if (good_dart != NIL)
{
map.sewFaces(d, good_dart, false) ;
m.unmarkOrbit(EDGE, d) ;
}
else
{
m.unmark(d) ;
++nbBoundaryEdges ;
}
}
}
if (nbBoundaryEdges > 0)
{
// map.closeMap() ;
CGoGNout << "Open mesh.. not managed for now.." << CGoGNendl ;
return false ;
}
for(unsigned int i = 0; i < depth; ++i)
map.addNewLevel(false) ;
map.setCurrentLevel(0) ;
qt.embed(map, verticesID) ;
for(unsigned int l = 0; l <= map.getMaxLevel(); ++l)
{
map.setCurrentLevel(l) ;
map.check() ;
}
return true ;
}
} // namespace Import
......
......@@ -49,7 +49,7 @@ public:
bool isOddVertex(Dart d) ;
void addNewLevel() ;
void addNewLevel(bool embedNewVertices) ;
void addSynthesisFilter(Multiresolution::MRFilter* f) { synthesisFilters.push_back(f) ; }
void addAnalysisFilter(Multiresolution::MRFilter* f) { analysisFilters.push_back(f) ; }
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#include "Topology/map/map2MR/map2MR_PrimalRegular.h"
namespace CGoGN
{
Map2MR_PrimalRegular::Map2MR_PrimalRegular() :
shareVertexEmbeddings(true)
{
initMR() ;
}
bool Map2MR_PrimalRegular::isOddVertex(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"isOddVertex : called with a dart inserted after current level") ;
return getDartLevel(d) == getCurrentLevel() ;
}
void Map2MR_PrimalRegular::addNewLevel(bool embedNewVertices)
{
pushLevel() ;
addLevel() ;
setCurrentLevel(getMaxLevel()) ;
for(unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i))
{
unsigned int newindex = copyDartLine((*m_mrDarts[m_mrCurrentLevel])[i]) ; // duplicate all darts
(*m_mrDarts[m_mrCurrentLevel])[i] = newindex ; // on the new max level
if(!shareVertexEmbeddings)
(*m_embeddings[VERTEX])[newindex] = EMBNULL ; // set vertex embedding to EMBNULL if no sharing
}
// cut edges
TraversorE<Map2MR_PrimalRegular> travE(*this) ;
for (Dart d = travE.begin(); d != travE.end(); d = travE.next())
{
if(!shareVertexEmbeddings)
{
if(getEmbedding(VERTEX, d) == EMBNULL)
embedNewCell(VERTEX, d) ;
if(getEmbedding(VERTEX, phi1(d)) == EMBNULL)
embedNewCell(VERTEX, d) ;
}
cutEdge(d) ;
travE.mark(d) ;
travE.mark(phi1(d)) ;
if(embedNewVertices)
embedNewCell(VERTEX, phi1(d)) ;
}
// split faces
TraversorF<Map2MR_PrimalRegular> travF(*this) ;
for (Dart d = travF.begin(); d != travF.end(); d = travF.next())
{
Dart old = d ;
if(getDartLevel(old) == getMaxLevel())
old = phi1(old) ;
decCurrentLevel() ;
unsigned int degree = faceDegree(old) ;
incCurrentLevel() ;
if(degree == 3) // if subdividing a triangle
{
Dart dd = phi1(old) ;
Dart e = phi1(phi1(dd)) ;
splitFace(dd, e) ;
travF.mark(dd) ;
dd = e ;
e = phi1(phi1(dd)) ;
splitFace(dd, e) ;
travF.mark(dd) ;
dd = e ;
e = phi1(phi1(dd)) ;
splitFace(dd, e) ;
travF.mark(dd) ;
travF.mark(e) ;
}
else // if subdividing a polygonal face
{
Dart dd = phi1(old) ;
Dart next = phi1(phi1(dd)) ;
splitFace(dd, next) ; // insert a first edge
Dart ne = alpha1(dd) ;
cutEdge(ne) ; // cut the new edge to insert the central vertex
travF.mark(dd) ;
if(embedNewVertices)
embedNewCell(VERTEX, phi1(ne)) ;
dd = phi1(phi1(next)) ;
while(dd != ne) // turn around the face and insert new edges
{ // linked to the central vertex
Dart tmp = phi1(ne) ;
splitFace(tmp, dd) ;
travF.mark(tmp) ;
dd = phi1(phi1(dd)) ;
}
travF.mark(ne) ;
}
}
popLevel() ;
}
void Map2MR_PrimalRegular::analysis()
{
assert(getCurrentLevel() > 0 || !"analysis : called on level 0") ;
decCurrentLevel() ;
for(unsigned int i = 0; i < analysisFilters.size(); ++i)
(*analysisFilters[i])() ;
}
void Map2MR_PrimalRegular::synthesis()
{
assert(getCurrentLevel() < getMaxLevel() || !"synthesis : called on max level") ;
for(unsigned int i = 0; i < synthesisFilters.size(); ++i)
(*synthesisFilters[i])() ;
incCurrentLevel() ;
}
} // namespace CGoGN
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