Commit 40d944d0 authored by Thomas's avatar Thomas

modif check 3-carte plongee, ajout catmull clark volumique

parent 54ef6990
/*******************************************************************************
* 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 *
* *
*******************************************************************************/
#ifndef __SUBDIVISION3MAP_H__
#define __SUBDIVISION3MAP_H__
#include <math.h>
#include <vector>
namespace CGoGN
{
namespace Algo
{
namespace Modelisation
{
/**
* Cut a 3D ear from a mesh : the ear is sewn by phi3 to the rest of the volume
* @param d dart of the point of the ear
* @return a dart from the new face connecting the ear and the rest of the volume
*/
template <typename PFP>
Dart cut3Ear(typename PFP::MAP& map, Dart d);
/**
* subdivide a hexahedron into 5 tetrahedron
* @param d dart of the hexahedron
*/
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
/**
* catmull clark volumic : do not move the original vertices
* @param map the map
* @param attributs geometric attributes of the vertices
* @param selected a functor to select volumes to subdivide
* TODO : test if it works for the functorselect
*/
template <typename PFP, typename EMBV, typename EMB>
void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelect& selected= SelectorTrue());
template <typename PFP>
void catmullClarkVol(typename PFP::MAP& map, typename PFP::TVEC3& position, const FunctorSelect& selected= SelectorTrue())
{
catmullClarkVol<PFP,typename PFP::TVEC3, typename PFP::VEC3>(map, position, selected);
}
} // namespace Modelisation
} // namespace Algo
} // namespace CGoGN
#include "Algo/Modelisation/subdivision3map.hpp"
#endif
/*******************************************************************************
* 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 "Algo/Geometry/centroid.h"
#include "Algo/Modelisation/subdivision.h"
#include "Algo/Modelisation/extrusion.h"
namespace CGoGN
{
namespace Algo
{
namespace Modelisation
{
template <typename PFP>
Dart cut3Ear(typename PFP::MAP& map, Dart d)
{
Dart e=d;
int nb=0;
Dart dNew;
Dart dRing;
Dart dRing2;
//count the valence of the vertex
do
{
nb++;
e=map.phi1(map.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
{
Dart dN = map.phi1(map.phi2(e));
if(map.template phi<111>(e)!=e)
map.splitFace(map.phi_1(e), map.phi1(e));
dRing = map.phi1(e);
dRing2 = map.phi2(dRing);
map.unsewFaces(dRing);
e= dN;
} while (e!=d);
map.closeHole(dRing);
map.closeHole(dRing2);
map.sewVolumes(map.phi2(dRing),map.phi2(dRing2));
}
return map.phi2(dRing);
}
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d)
{
Dart d1 = d;
Dart d2 = map.phi1(map.phi1(d));
Dart d3 = map.phi_1(map.phi2(d));
Dart d4 = map.phi1(map.phi1(map.phi2(map.phi_1(d3))));
cut3Ear<PFP>(map,d1);
cut3Ear<PFP>(map,d2);
cut3Ear<PFP>(map,d3);
cut3Ear<PFP>(map,d4);
}
template <typename PFP, typename EMBV, typename EMB>
void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelect& selected)
{
std::vector<Dart> l_centers;
std::vector<Dart> l_vertices;
DartMarkerNoUnmark mv(map);
CellMarkerNoUnmark me(map, EDGE);
CellMarker mf(map, FACE);
AutoAttributeHandler< EMB > attBary(map,VOLUME);
CellMarker vol(map,VOLUME);
//pre-computation : compute the centroid of all volume
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
if(selected(d) && !vol.isMarked(d))
{
vol.mark(d);
attBary[d] = Algo::Geometry::volumeCentroidGen<PFP,EMBV,EMB>(map,d,attributs);
}
}
std::cout << "test" << std::endl;
// mv.unmarkAll();
// first pass: cut edges
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
//memorize each vertices per volumes
if(selected(d) && !mv.isMarked(d))
{
l_vertices.push_back(d);
Dart dd = d;
do {
mv.mark(dd);
dd = map.phi1(map.phi2(dd));
} while(dd!=d);
}
//cut edges
if (selected(d) && !me.isMarked(d))
{
std::cout << "edge to cut " << d << std::endl;
std::cout << "edge degree " << map.edgeDegree(d) << std::endl;
Dart f = map.phi1(d);
map.cutEdge(d);
Dart e = map.phi1(d) ;
std::cout << "cut cut cut " << std::endl;
attributs[e] = attributs[d];
attributs[e] += attributs[f];
attributs[e] *= 0.5;
me.mark(d);
me.mark(e);
//mark new vertices
mv.markOrbit(VERTEX, e);
Dart dd = d;
do
{
mf.mark(dd) ;
mf.mark(map.phi2(dd));
dd = map.alpha2(dd);
} while(dd != d);
}
}
std::cout << "edge cut" << std::endl;
// second pass: quandrangule faces
std::map<Dart,Dart> toSew;
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
mv.unmark(d);
if (selected(d) && mf.isMarked(d)) // for each face not subdivided
{
mf.unmark(d);
// compute center skip darts of new vertices non embedded
EMB center = AttribOps::zero<EMB,PFP>();
unsigned int count = 0 ;
Dart it = d;
do
{
me.unmark(it);
me.unmark(map.phi1(it));
center += attributs[it];
++count ;
it = map.template phi<11>(it) ;
} while(it != d) ;
center /= double(count);
Dart cf = quadranguleFace<PFP>(map, d); // quadrangule the face
attributs[cf] = center; // affect the data to the central vertex
}
}
std::cout << "nb vertices " << l_vertices.size() << std::endl;
//third pass : create the inner faces
for (std::vector<Dart>::iterator it = l_vertices.begin(); it != l_vertices.end(); ++it)
{
Dart d = *it;
//unsew all around the vertex
//there are 2 links to unsew for each face around (-> quadrangulation)
do
{
Dart dN = map.phi1(map.phi2(d));
Dart dRing = map.phi1(d);
if(map.phi2(dRing)!=dRing)
{
toSew.insert(std::pair<Dart,Dart>(dRing,map.phi2(dRing)));
map.unsewFaces(dRing);
}
dRing = map.phi1(dRing);
if(map.phi2(dRing)!=dRing)
{
toSew.insert(std::pair<Dart,Dart>(dRing,map.phi2(dRing)));
map.unsewFaces(dRing);
}
d= dN;
} while (*it!=d);
//close the generated hole and create the central vertex
unsigned int degree = map.closeHole(map.phi1(d));
std::cout << "degree " << degree << std::endl;
Dart dd = map.phi1(map.phi2(map.phi1(d)));
map.splitFace(map.phi_1(dd),map.phi1(dd));
Dart dS = map.phi1(dd);
map.cutEdge(dS);
attributs[map.phi1(dS)] = attBary[d];
//TODO : test with vertices with degree higher than 3
for(unsigned int i=0; i < (degree/2)-2; ++i)
{
map.splitFace(map.phi2(dS),map.template phi<111>(map.phi2(dS)));
dS = map.template phi<111>(map.phi2(dS));
}
}
//sew all faces leading to the central vertex
for (std::map<Dart,Dart>::iterator it = toSew.begin(); it != toSew.end(); ++it)
{
Dart dT = map.phi2(it->first);
if(dT==map.phi3(dT))
{
map.sewVolumes(dT,map.phi2(it->second));
}
}
}
} //namespace Modelisation
} //namespace Algo
} //namespace CGoGN
......@@ -62,7 +62,10 @@ void EmbeddedMap3<MAP3>::sewVolumes(Dart d, Dart e)
//embed the face orbit from the volume sewn
if (MAP3::isOrbitEmbedded(FACE))
MAP3::copyDartEmbedding(FACE, e, d) ;
{
unsigned int vEmb1 = MAP3::getEmbedding(FACE, d);
MAP3::embedOrbit(FACE, e, vEmb1) ;
}
}
template <typename MAP3>
......@@ -346,34 +349,61 @@ bool EmbeddedMap3<MAP3>::check()
return false ;
}
if(MAP3::phi3(d) != d && MAP3::getEmbedding(VERTEX, d) != MAP3::getEmbedding(VERTEX, MAP3::phi1(MAP3::phi3(d))))
{
CGoGNout << "Check: different embeddings on vertex in the 2 oriented faces" << CGoGNendl ;
std::cout << "Dart #" << d << std::endl;
std::cout << "Emb(d) = " << MAP3::getEmbedding(VERTEX, d) << std::endl;
std::cout << "Emb(phi32(d)) = " << MAP3::getEmbedding(VERTEX, MAP3::phi3(MAP3::phi2(d))) << std::endl;
return false ;
}
if(MAP3::phi3(d) != d && MAP3::getEmbedding(VERTEX, d) != MAP3::getEmbedding(VERTEX, MAP3::phi1(MAP3::phi3(d))))
{
CGoGNout << "Check: different embeddings on vertex in the 2 oriented faces" << CGoGNendl ;
CGoGNout << "Dart #" << d << CGoGNendl;
CGoGNout << "Emb(d) = " << MAP3::getEmbedding(VERTEX, d) << CGoGNendl;
CGoGNout << "Emb(phi32(d)) = " << MAP3::getEmbedding(VERTEX, MAP3::phi3(MAP3::phi2(d))) << CGoGNendl;
return false ;
}
}
// if (MAP2::isOrbitEmbedded(EDGE))
// {
// if (MAP2::getEmbedding(EDGE, d) != MAP2::getEmbedding(EDGE, MAP2::phi2(d)))
// {
// CGoGNout << "Check: different embeddings on edge" << CGoGNendl ;
// return false ;
// }
// }
//
// if (MAP2::isOrbitEmbedded(FACE))
// {
// if (MAP2::getEmbedding(FACE, d) != MAP2::getEmbedding(FACE, MAP2::phi1(d)))
// {
// CGoGNout << "Check: different embeddings on face" << CGoGNendl ;
// return false ;
// }
// }
if (MAP3::isOrbitEmbedded(EDGE))
{
if (MAP3::getEmbedding(EDGE, d) != MAP3::getEmbedding(EDGE, MAP3::phi2(d)))
{
CGoGNout << "Check: different embeddings on edge" << CGoGNendl ;
return false ;
}
if (MAP3::getEmbedding(EDGE, d) != MAP3::getEmbedding(EDGE, MAP3::phi3(d)))
{
CGoGNout << "Check: different embeddings on edge" << CGoGNendl ;
return false ;
}
}
if (MAP3::isOrbitEmbedded(FACE))
{
if (MAP3::getEmbedding(FACE, d) != MAP3::getEmbedding(FACE, MAP3::phi1(d)))
{
CGoGNout << "Check: different embeddings on face" << CGoGNendl ;
return false ;
}
if (MAP3::getEmbedding(FACE, d) != MAP3::getEmbedding(FACE, MAP3::phi3(d)))
{
CGoGNout << "Check: different embeddings on face" << CGoGNendl ;
return false ;
}
}
if (MAP3::isOrbitEmbedded(VOLUME))
{
if (MAP3::getEmbedding(VOLUME, d) != MAP3::getEmbedding(VOLUME, MAP3::phi1(d)))
{
CGoGNout << "Check: different embeddings in volume" << CGoGNendl ;
return false ;
}
if (MAP3::getEmbedding(VOLUME, d) != MAP3::getEmbedding(VOLUME, MAP3::phi2(d)))
{
CGoGNout << "Check: different embeddings in volume" << CGoGNendl ;
return false ;
}
}
}
CGoGNout << "Check: embedding ok" << CGoGNendl ;
return true ;
......
......@@ -635,15 +635,15 @@ unsigned int Map3::vertexDegree(Dart d)
int count = 0;
DartMarkerStore mv(*this); // Lock a marker
std::vector<Dart> darts; //Darts that are traversed
darts.reserve(512);
darts.push_back(d); //Start with the dart d
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);
for(std::vector<Dart>::iterator it = darts.begin(); it != darts.end() ; ++it)
for(darts = darts_list.begin(); darts != darts_list.end() ; ++darts)
{
Dart dc = *it;
Dart dc = *darts;
//add phi21 and phi23 successor if they are not marked yet
Dart d2 = phi2(dc);
......@@ -652,27 +652,27 @@ unsigned int Map3::vertexDegree(Dart d)
if(!mv.isMarked(d21))
{
darts.push_back(d21);
darts_list.push_back(d21);
mv.mark(d21);
}
if((d23!=d2) && !mv.isMarked(d23))
{
darts.push_back(d23);
darts_list.push_back(d23);
mv.mark(d23);
}
}
std::cout << "#darts = " << darts.size() << std::endl;
std::cout << "#darts = " << darts_list.size() << std::endl;
DartMarkerStore me(*this);
for(std::vector<Dart>::iterator it = darts.begin(); it != darts.end() ; ++it)
for(darts = darts_list.begin(); darts != darts_list.end() ; ++darts)
{
if(!me.isMarked(*it))
if(!me.isMarked(*darts))
{
++count;
me.markOrbit(EDGE, *it);
me.markOrbit(EDGE, *darts);
}
}
......
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