Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

Commit aaf8b223 authored by Maire Nicolas's avatar Maire Nicolas
Browse files

pb map3.cpp

parent e1f0767d
......@@ -47,7 +47,7 @@
#include "glm/gtc/type_precision.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "Utils/textures.h"
//#include "Utils/textures.h"
using namespace CGoGN;
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2011, 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.u-strasbg.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#include <list>
#include <set>
#include <map>
#include <vector>
#include "Topology/map/map3.h"
namespace CGoGN
{
/*! @name Generator and Deletor
* To generate or delete volumes in a 3-map
*************************************************************************/
//ok
void Map3::deleteOrientedVolume(Dart d)
{
DartMarkerStore mark(*this); // Lock a marker
std::vector<Dart> visitedFaces; // Faces that are traversed
visitedFaces.reserve(16);
visitedFaces.push_back(d); // Start with the face of d
// // For every face added to the list
// for (face = visitedFaces.begin(); !found && face != visitedFaces.end(); ++face)
// {
// if (!mark.isMarked(*face)) // Face has not been visited yet
// {
// unsewVolumes(*face);
//
// Dart dNext = *face ;
// do
// {
// mark.mark(dNext); // Mark
// Dart adj = phi2(dNext); // Get adjacent face
// if (adj != dNext && !mark.isMarked(adj))
// visitedFaces.push_back(adj); // Add it
// dNext = phi1(dNext);
// } while(dNext != *face);
// }
// }
mark.markOrbit(FACE, d) ;
for(std::vector<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
{
Dart e = *face ;
unsewVolumes(e);
do // add all face neighbours to the table
{
Dart ee = phi2(e) ;
if(!mark.isMarked(ee)) // not already marked
{
visitedFaces.push_back(ee) ;
mark.markOrbit(FACE, ee) ;
}
e = phi1(e) ;
} while(e != *face) ;
}
// delete every visited face
for (std::vector<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
Map1::deleteOrientedFace(*face);
}
/*! @name Topological Operators
* Topological operations on 3-maps
*************************************************************************/
void Map3::sewVolumes(Dart d, Dart e)
{
assert(faceDegree(d) == faceDegree(e));
Dart fitD = d ;
Dart fitE = e ;
do
{
phi3sew(fitD,fitE);
fitD = phi1(fitD) ;
fitE = phi_1(fitE) ;
} while(fitD != d) ;
}
void Map3::unsewVolumes(Dart d)
{
Dart fitD = d;
do
{
phi3unsew(fitD);
fitD = phi1(fitD);
} while(fitD != d);
}
bool Map3::mergeVolumes(Dart d)
{
Dart e = phi3(d) ;
if(e != d)
{
unsewVolumes(d);
Map2::mergeVolumes(d, e); // merge the two volumes along common face
return true ;
}
return false ;
}
void Map3::splitFace(Dart d, Dart e)
{
Map2::splitFace(d,e);
if (phi3(d) != d)
{
Dart dd = phi1(phi3(d));
Dart ee = phi1(phi3(e));
Map2::splitFace(dd,ee);
phi3sew(phi_1(d), phi_1(ee));
phi3sew(phi_1(e), phi_1(dd));
}
}
void Map3::cutEdge(Dart d)
{
if(phi3(d) == d)
d = phi2(d);
Dart prev = d;
Dart dd = alpha2(d);
Map2::cutEdge(d);
while (dd!=d)
{
prev = dd;
dd = alpha2(dd);
Map2::cutEdge(prev);
if (phi3(prev) != prev)
{
Dart d3 = phi3(prev);
phi3unsew(prev);
phi3sew(prev, phi1(d3));
phi3sew(d3, phi1(prev));
}
}
if (phi3(d) != d)
{
Dart d3 = phi3(d);
phi3unsew(d);
phi3sew(d, phi1(d3));
phi3sew(d3, phi1(d));
}
}
void Map3::uncutEdge(Dart d)
{
if(phi3(d) == d)
d = phi_1(phi2(d));
Dart prev = d;
Dart dd = alpha2(d);
Map2::uncutEdge(prev);
if(phi3(dd) != dd)
phi3sew(dd,phi2(prev));
while (dd!=d)
{
prev = dd;
dd = alpha2(dd);
Map2::uncutEdge(prev);
phi3sew(dd, phi2(prev));
}
}
bool Map3::deleteVertex(Dart d)
{
DartMarkerStore mv(*this); // Lock a marker
std::list<Dart> darts_list; //Darts that are traversed
darts_list.push_back(d); //Start with the dart d
std::list<Dart>::iterator darts;
mv.mark(d);
std::list<Dart> unique_darts_list;
//unique_darts_list.reserve(30);
unique_darts_list.push_back(d);
bool boundary = false;
if(isBoundaryVertex(d))
boundary = true;
for(darts = darts_list.begin(); darts != darts_list.end() ; ++darts)
{
Dart dc = *darts;
//add phi21 and phi23 successor if they are not marked yet
Dart d2 = phi2(dc);
Dart d21 = phi1(d2); // turn in volume
Dart d23 = phi3(d2); // change volume
if(!mv.isMarked(d21))
{
darts_list.push_back(d21);
mv.mark(d21);
}
if((d23!=d2) && !mv.isMarked(d23))
{
darts_list.push_back(d23);
unique_darts_list.push_back(d23);
mv.mark(d23);
}
}
for(darts = unique_darts_list.begin(); darts != unique_darts_list.end() ; ++darts)
{
mergeVolumes(*darts);
}
if(boundary)
{
Dart vit = d ;
do
{
Dart f = phi_1(phi2(vit)) ;
phi1sew(vit, f) ;
vit = phi2(phi_1((vit))) ;
} while(vit != d) ;
Map1::deleteFace(d) ;
}
return true;
}
//TODO
//bool Map3::flipEdge(Dart d)
//{
// if(phi3(d) == d)
// d = phi2(d);
//
// Dart e = alpha2(d);
// Dart e2 = phi2(e);
//
// // Test if an opposite
// if (e != d)
// {
// Dart dPrev = phi_1(d);
// Dart dNext = phi1(d);
// Dart e2Prev = phi_1(e2);
// Dart e2Next = phi1(e2);
//
// phi1sew(d, e2Prev); // Detach the two
// phi1sew(e2, dPrev); // vertices of the edge
// phi1sew(d, dNext); // Insert the edge in its
// phi1sew(e2, e2Next); // new vertices after flip
// return true;
// }
// else // flip a border edge with Map2 flipEdge
// return Map2::flipEdge(d);
//}
//TODO
//bool Map3::flipBackEdge(Dart d)
//{
// return false;
//}
////TODO
//bool Map3::flipFace(Dart d)
//{
// //prevoir de refaire un linkFace et de ne pas
// //faire inserFace si flipEdge renvoie faux
//
// //save a dart from a non-modifed-face of one tetrahedron
// Dart r = phi2(d);
//
// //detach common face from tetrahedron from the rest of the faces
// //unlinkFace(d);
// Map3::mergeVolumes(d);
//
// //flip the common edge
// Map2::flipEdge(r);
//
// //insert the old face in the new flipped edge
// //Map3::insertFace(r,d);
// Map3::splitFace(r,d);
//
// return true;
//}
//void Map3::insertFace(Dart d, Dart e)
//{
// assert(faceDegree(d) == faceDegree(e)); //les faces ont la meme longueur
//
// Dart dd = d;
// Dart nFd = e;
//
// do {
// //sewFace(dd,nFd);
//
// Dart d2 = phi2(dd);
// unsewFaces(dd);
// sewFaces(d2,phi3(nFd));
// sewFaces(dd,nFd);
//
// dd = phi_1(phi2(phi_1(dd)));
// nFd = phi1(nFd);
// } while (nFd != e);
//
//}
int Map3::collapseEdge(Dart d, bool delDegenerateFaces,
bool delDegenerateVolumes)
{
Dart e = d;
int i = 0;
//stocke un brin par volume autour de l'arete
std::list<Dart> tmp;
do
{
tmp.push_back(e);
e = alpha2(e);
i++;
} while (e != d);
for (std::list<Dart>::iterator it = tmp.begin(); it != tmp.end(); ++it)
{
Dart e = phi2(*it);
cutSpike(e);
Dart t1=e,t2=e;
//si les faces opposées ont un tetraedre cousu
if(phi3(phi2(phi1(e))) != phi2(phi1(e))) {
t1 = phi3(phi2(phi1(e)));
unsewVolumes(t1);
}
if(phi3(phi2(phi_1(e))) != phi2(phi_1(e))) {
t2 = phi3(phi2(phi_1(e)));
unsewVolumes(t2);
}
if(t1 != e && t2 != e) {
sewVolumes(t1,t2);
}
//unsewVolumes(e);
//unsewVolumes(*it);
deleteOrientedVolume(*it);
}
return i;
}
// CGoGNout << "coll topo" << CGoGNendl;
// Dart e = d;
//
// //stocke un brin par volume autour de l'arete
// std::list<Dart> tmp;
// do
// {
// tmp.push_back(e);
// e = alpha2(e);
// } while (e != d);
//
// //contraction de la 2 carte de chaque 2-arete
// for (std::list<Dart>::iterator it = tmp.begin(); it != tmp.end(); ++it)
// {
// //un brin d'une face adjacente a l'arrete contracte
// Dart d = phi2(phi_1(*it));
// Map2::collapseEdge(*it, delDegenerateFaces);
//
// //test de la degeneresence
// //impossible d'avoir un volume de moins de 4 faces sans avoir de phi2 en points fixe donc on les vire
// if(delDegenerateVolumes && Map2::volumeDegree(d) < 4)
// {
// CGoGNout << "del vol" << CGoGNendl;
// Dart e = d;
// //pour tous les brins de la face adjacente
//
// do
// {
// Dart ee = phi3(e);
// Dart ff = phi3(phi2(e));
//
// //si les brins ont un voisin par phi3
// if(ee != e)
// phi3unsew(ee);
//
// if(ff != phi2(e))
// phi3unsew(ff);
//
// //si les deux en ont un, il faut les coudres ensemble
// if(ee != e && ff != phi2(e))
// phi3sew(ee, ff);
//
// //on peut supprimer les brins de cette arete
// deleteDart(e);
// deleteDart(phi2(e));
// e = phi1(e);
//
// } while (e != d);
// }
// }
//TODO
void Map3::collapseFace(Dart d, bool delDegenerateFaces,
bool delDegenerateVolumes)
{
Dart e = d;
std::list<Dart> tmp;
//save a dart from the edge for all neighbors
do
{
//if(phi3(phi2(e)) != phi2(e))
// tmp.push_back(phi3(phi2(e)));
tmp.push_back(phi3(phi2(e)));
e = phi1(e);
}while(e != d);
//del the last one (n-1 edge collapse)
tmp.pop_back();
//CGoGNout << "#voisin=" << tmp.size() << CGoGNendl;
//collapse all the edges in the list
for(std::list<Dart>::iterator it = tmp.begin() ; it != tmp.end() ; ++it)
{
Dart d = *it;
//CGoGNout << "collapseEdge" << CGoGNendl;
//collapseEdge(*it, delDegenerateFaces, delDegenerateVolumes);
//stocke un brin par volume autour de l'arete
Dart e = d;
//stocke un brin par volume autour de l'arete
std::list<Dart> tmpedge;
do
{
tmpedge.push_back(e);
e = alpha2(e);
} while (e != d);
for (std::list<Dart>::iterator it = tmpedge.begin(); it != tmpedge.end(); ++it)
{
Dart e = phi2(*it);
cutSpike(e);
Dart t1=e,t2=e;
//si les faces opposées ont un tetraedre cousu
if(phi3(phi2(phi1(e))) != phi2(phi1(e))) {
t1 = phi3(phi2(phi1(e)));
unsewVolumes(t1);
}
if(phi3(phi2(phi_1(e))) != phi2(phi_1(e))) {
t2 = phi3(phi2(phi_1(e)));
unsewVolumes(t2);
}
if(t1 != e && t2 != e) {
sewVolumes(t1,t2);
}
//deleteOrientedVolume(*it);
}
}
// for(std::list<Dart>::iterator it = tmp.begin() ; it != tmp.end() ; ++it)
// {
// deleteOrientedVolume(*it);
// }
}
//TODO
void Map3::collapseVolume(Dart d, bool delDegenerateFaces,
bool delDegenerateVolumes)
{
//pour toutes les faces du volume
//sauvegarder un brin du voisin s'il existe
std::vector<Dart> neighborsVol;
neighborsVol.reserve(16);
DartMarkerStore mark(*this); // Lock a marker
std::vector<Dart> visitedFaces; // Faces that are traversed
visitedFaces.reserve(16);
visitedFaces.push_back(d); // Start with the face of d
std::vector<Dart>::iterator face;
// For every face added to the list
for (face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
{
Dart dsave = *face ;
if(phi3(dsave) != dsave)
neighborsVol.push_back(dsave);
}
// delete every visited face
for (face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
Map1::deleteOrientedFace(*face);
//enlever le dernier (n-1) face collapse
//contracter toutes les faces de la liste
}
//TODO
void Map3::mergeFaces(Dart d, Dart e)
{
}
Dart Map3::cutSpike(Dart d)
{
Dart e=d;
int nb=0;
Dart dNew;
int tet=0;
//CGoGNout << "cut" << CGoGNendl;
//count the valence of the vertex
do {
nb++;
e=phi1(phi2(e));
} while (e!=d);
if(nb<3)
{
CGoGNout << "Warning : cannot cut 2 volumes without creating a degenerated face " << CGoGNendl;
return d;
}
else
{
//triangulate around the vertex
do {
if(phi1(phi1(phi1(e)))!=e)
{
splitFace(phi_1(e),phi1(e));
//CGoGNout << "split" << CGoGNendl;
}
else
tet++;
e=phi1(phi2(e));
} while (e!=d);
// CGoGNout << "#tet= " << tet << CGoGNendl;
// CGoGNout << "#nb= " << nb << CGoGNendl;
//si toute ces faces ne sont pas triangulaires (on insere une face)
if(tet != nb) {
//CGoGNout << "new face" << CGoGNendl;
dNew=newFace(nb);
Dart d3 = newFace(nb);
sewVolumes(dNew,d3);
//sew a face following the triangles
Dart dTurn=dNew;
do {
Dart d1 = phi1(e);
Dart dSym = phi2(d1);
phi2unsew(d1);
phi2sew(dTurn,d1);
phi2sew(phi3(dTurn),dSym);
dTurn = phi1(dTurn);
e=phi1(phi2(e));
}while(e!=d);
}
else
dNew = d;
}
return dNew;
}
int Map3::edgeDegree(Dart d)
{
int deg = 0;
Dart e = d;