Commit cca8d75d authored by untereiner's avatar untereiner

Merge cgogn:~thery/CGoGN

Conflicts:
	Apps/Examples/volumeExplorer.cpp
	include/Algo/Modelisation/tetrahedralization.hpp
	include/Algo/Render/GL2/explodeVolumeRender.hpp
parents c5d24cc1 dd2af627
......@@ -29,10 +29,12 @@
#include "Algo/Modelisation/primitives3d.h"
#include "Algo/Modelisation/polyhedron.h"
#include "Algo/Import/import.h"
#include "Algo/Geometry/volume.h"
PFP::MAP myMap;
PFP::TVEC3 position ;
PFP::TVEC3 color ;
void MyQT::volumes_onoff(bool x)
{
......@@ -52,7 +54,7 @@ void MyQT::topo_onoff(bool x)
if (render_topo)
{
SelectorDartNoBoundary<PFP::MAP> nb(myMap);
m_topo_render->updateData<PFP>(myMap, position, 0.8f, 0.8f, m_explode_factor, nb);
m_topo_render->updateData<PFP>(myMap, position, 0.8f, m_explode_factorf-0.05f, m_explode_factor, nb);
}
updateGL();
......@@ -92,11 +94,18 @@ void MyQT::hide_onoff(bool x)
void MyQT::slider_explode(int x)
{
m_explode_factor = 0.01f*(x+1);
m_explode_factor = 0.01f*(x+1)-0.0001f;
m_explode_render->setExplodeVolumes(m_explode_factor);
updateGL();
}
void MyQT::slider_explodeF(int x)
{
m_explode_factorf = 0.01f*(x+1);
m_explode_render->setExplodeFaces(m_explode_factorf);
updateGL();
}
void MyQT::slider_pressed()
{
......@@ -113,7 +122,7 @@ void MyQT::slider_released()
if (render_topo)
{
SelectorDartNoBoundary<PFP::MAP> nb(myMap);
m_topo_render->updateData<PFP>(myMap, position, 0.8f, 0.8f, m_explode_factor, nb);
m_topo_render->updateData<PFP>(myMap, position, 0.8f, m_explode_factorf-0.05f, m_explode_factor, nb);
}
updateGL();
}
......@@ -126,14 +135,15 @@ void MyQT::cb_initGL()
// create the renders
m_topo_render = new Algo::Render::GL2::Topo3Render();
m_explode_render = new Algo::Render::GL2::ExplodeVolumeRender();
m_explode_render = new Algo::Render::GL2::ExplodeVolumeRender(true,true);
SelectorDartNoBoundary<PFP::MAP> nb(myMap);
m_topo_render->updateData<PFP>(myMap, position, 0.8f, 0.8f, 0.8f, nb);
m_explode_render->updateData<PFP>(myMap,position);
m_explode_render->updateData<PFP>(myMap,position,color);
m_explode_render->setExplodeVolumes(0.8f);
m_explode_render->setExplodeFaces(0.9f);
m_explode_render->setAmbiant(Geom::Vec4f(0.2f,0.2f,0.2f,1.0f));
m_explode_render->setDiffuse(Geom::Vec4f(0.6f,0.6f,0.9f,1.0f));
m_explode_render->setBackColor(Geom::Vec4f(0.9f,0.9f,0.9f,1.0f));
m_explode_render->setColorLine(Geom::Vec4f(0.8f,0.2f,0.2f,1.0f));
registerShader(m_explode_render->shaderFaces());
......@@ -213,8 +223,6 @@ void MyQT::cb_mousePress(int button, int x, int y)
if (fr_picked != 0)
{
m_pickedAxis=fr_picked;
std::cout << "PICKED:"<< m_pickedAxis << std::endl;
m_frame->highlight(m_pickedAxis);
m_frame->storeProjection(m_pickedAxis);
updateGL();
......@@ -324,14 +332,36 @@ int main(int argc, char **argv)
myMap.closeMap();
}
}
color = myMap.addAttribute<PFP::VEC3>(VOLUME, "color");
TraversorCell<PFP::MAP> tra(myMap,VOLUME);
float maxV=0.0f;
for (Dart d = tra.begin(); d != tra.end(); d=tra.next())
{
float v = Algo::Geometry::tetrahedronVolume<PFP>(myMap,d,position);
color[d] = PFP::VEC3(v,0,0);
if (v>maxV)
maxV=v;
}
for (unsigned int i = color.begin(); i!=color.end(); color.next(i))
{
color[i][0] /= maxV;
color[i][2] = 1.0f -color[i][0];
}
}
else
{
position = myMap.addAttribute<PFP::VEC3>(VERTEX, "position");
Algo::Modelisation::Primitive3D<PFP> prim(myMap, position);
int nb = 10;
int nb = 32;
prim.hexaGrid_topo(nb,nb,nb);
prim.embedHexaGrid(1.0f,1.0f,1.0f);
color = myMap.addAttribute<PFP::VEC3>(VOLUME, "color");
TraversorCell<PFP::MAP> tra(myMap,VOLUME);
for (Dart d = tra.begin(); d != tra.end(); d=tra.next())
color[d] = position[d] + PFP::VEC3(0.5,0.5,0.5);
}
// un peu d'interface
QApplication app(argc, argv);
......@@ -361,9 +391,16 @@ int main(int argc, char **argv)
sqt.setCallBack( dock.slider_explode, SIGNAL(sliderPressed()), SLOT(slider_pressed()) );
sqt.setCallBack( dock.slider_explode, SIGNAL(sliderReleased()), SLOT(slider_released()) );
sqt.setCallBack( dock.slider_explode_face, SIGNAL(valueChanged(int)), SLOT(slider_explodeF(int)) );
sqt.setCallBack( dock.slider_explode_face, SIGNAL(sliderPressed()), SLOT(slider_pressed()) );
sqt.setCallBack( dock.slider_explode_face, SIGNAL(sliderReleased()), SLOT(slider_released()) );
sqt.show();
dock.slider_explode->setValue(80);
dock.slider_explode_face->setValue(80);
sqt.clipping_onoff(true);
// et on attend la fin.
......
......@@ -87,6 +87,7 @@ class MyQT: public Utils::QT::SimpleQT
Algo::Render::GL2::ExplodeVolumeRender* m_explode_render;
float m_explode_factor;
float m_explode_factorf;
// for clipping plane manipulation
Utils::Pickable* m_PlanePick;
......@@ -132,6 +133,7 @@ public slots:
void slider_explode(int x);
void slider_pressed();
void slider_released();
void slider_explodeF(int x);
};
#endif
......@@ -84,6 +84,13 @@
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="slider_explode_face">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
......@@ -133,5 +140,22 @@
</widget>
</widget>
<resources/>
<connections/>
<connections>
<connection>
<sender>checkBox_plane</sender>
<signal>clicked(bool)</signal>
<receiver>checkBox_hide</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>74</x>
<y>174</y>
</hint>
<hint type="destinationlabel">
<x>74</x>
<y>200</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -30,6 +30,7 @@
#include "Algo/Modelisation/primitives3d.h"
#include "Algo/Modelisation/polyhedron.h"
#include "Algo/Modelisation/subdivision.h"
#include "Algo/Modelisation/subdivision3.h"
#include "Algo/Render/GL2/topo3Render.h"
#include "Algo/Render/SVG/mapSVGRender.h"
......@@ -258,6 +259,20 @@ void MyQT::cb_keyPress(int code)
else
m_timer->start(1000/30); // 30 fps
}
if(code == 'c')
{
SelectorDartNoBoundary<PFP::MAP> nb(myMap);
Algo::Modelisation::catmullClarkVol<PFP>(myMap, position, nb);
m_positionVBO->updateData(position);
m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::TRIANGLES);
m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::LINES);
m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::POINTS);
m_render_topo->updateData<PFP>(myMap, position, 0.9f, 0.9f, 0.9f, nb);
}
}
......
......@@ -27,14 +27,14 @@
#include <iostream>
#define WITH_GMAP 1
#define WITH_GMAP 0
#include "Topology/generic/parameters.h"
#ifdef WITH_GMAP
#include "Topology/gmap/embeddedGMap3.h"
#else
//#ifdef WITH_GMAP
// #include "Topology/gmap/embeddedGMap3.h"
//#else
#include "Topology/map/embeddedMap3.h"
#endif
//#endif
#include "Geometry/vector_gen.h"
#include "Algo/Geometry/boundingbox.h"
......@@ -65,11 +65,11 @@ using namespace CGoGN ;
struct PFP: public PFP_STANDARD
{
// definition de la carte
#ifdef WITH_GMAP
typedef EmbeddedGMap3 MAP;
#else
//#ifdef WITH_GMAP
// typedef EmbeddedGMap3 MAP;
//#else
typedef EmbeddedMap3 MAP;
#endif
//#endif
};
......
......@@ -361,6 +361,13 @@ public:
virtual bool foreach_dart_of_volume(Dart d, FunctorType& f, unsigned int thread = 0) ;
virtual bool foreach_dart_of_cc(Dart d, FunctorType& f, unsigned int thread = 0) ;
virtual bool foreach_dart_of_vertex2(Dart d, FunctorType& f, unsigned int thread = 0);
virtual bool foreach_dart_of_edge2(Dart d, FunctorType& f, unsigned int thread = 0);
virtual bool foreach_dart_of_face2(Dart d, FunctorType& f, unsigned int thread = 0);
//@}
......
......@@ -368,6 +368,30 @@ inline bool ImplicitHierarchicalMap3::foreach_dart_of_cc(Dart d, FunctorType& f,
}
inline bool ImplicitHierarchicalMap3::foreach_dart_of_vertex2(Dart d, FunctorType& f, unsigned int thread)
{
Dart dNext = d;
do
{
if (f(dNext))
return true;
dNext = phi2(phi_1(dNext));
} while (dNext != d);
return false;
}
inline bool ImplicitHierarchicalMap3::foreach_dart_of_edge2(Dart d, FunctorType& f, unsigned int thread)
{
if (f(d))
return true;
return f(phi2(d));
}
inline bool ImplicitHierarchicalMap3::foreach_dart_of_face2(Dart d, FunctorType& f, unsigned int thread)
{
return foreach_dart_of_oriented_face(d,f,thread);
}
/***************************************************
* LEVELS MANAGEMENT *
***************************************************/
......
......@@ -60,6 +60,9 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos
template <typename PFP>
Dart subdivideVolumeClassic(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
template <typename PFP>
Dart subdivideVolumeClassic2(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
/***********************************************************************************
* Simplification *
......
......@@ -209,9 +209,6 @@ Dart subdivideVolumeClassic(typename PFP::MAP& map, Dart d, typename PFP::TVEC3&
mf.markOrbit(FACE, old) ;
// TraversorW<typename PFP::MAP> tw(map);
// for(Dart d = tw.begin(); d != tw.end(); d = tw.next())
for(unsigned int i = 0; i < visitedFaces.size(); ++i)
{
Dart e = visitedFaces[i] ;
......@@ -380,6 +377,162 @@ Dart subdivideVolumeClassic(typename PFP::MAP& map, Dart d, typename PFP::TVEC3&
return subdividedfaces.begin()->first;
}
template <typename PFP>
Dart subdivideVolumeClassic2(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position)
{
assert(map.getDartLevel(d) <= map.getCurrentLevel() || !"Access to a dart introduced after current level") ;
assert(!map.volumeIsSubdivided(d) || !"Trying to subdivide an already subdivided volume") ;
assert(!map.isBoundaryMarked(d) || !"Trying to subdivide a dart marked boundary");
unsigned int vLevel = map.volumeLevel(d);
Dart old = map.volumeOldestDart(d);
unsigned int cur = map.getCurrentLevel();
map.setCurrentLevel(vLevel);
/*
* Compute volume centroid
*/
typename PFP::VEC3 volCenter = Algo::Geometry::volumeCentroid<PFP>(map, old, position);
/*
* Subdivide Faces
*/
std::vector<std::pair<Dart,Dart> > subdividedfaces;
subdividedfaces.reserve(25);
Traversor3WF<typename PFP::MAP> traF(map, old);
for(Dart dit = traF.begin(); dit != traF.end(); dit = traF.next())
{
//if needed subdivide face
if(!map.faceIsSubdivided(dit))
Algo::IHM::subdivideFace<PFP>(map, dit, position, Algo::IHM::S_QUAD);
//save a dart from the subdivided face
unsigned int cur = map.getCurrentLevel() ;
unsigned int fLevel = map.faceLevel(d) + 1; //puisque dans tous les cas, la face est subdivisee
map.setCurrentLevel(fLevel) ;
//le brin est forcement du niveau cur
Dart cf = map.phi1(d);
Dart e = cf;
do
{
subdividedfaces.push_back(std::pair<Dart,Dart>(e,map.phi2(e)));
e = map.phi2(map.phi1(e));
}while (e != cf);
map.setCurrentLevel(cur);
}
/*
* Create inside volumes
*/
std::vector<Dart> newEdges; //save darts from inner edges
newEdges.reserve(50);
Dart centralDart = NIL;
Traversor3WV<typename PFP::MAP> traV(map, old);
map.setCurrentLevel(vLevel + 1) ; // go to the next level to perform volume subdivision
for(Dart dit = traV.begin(); dit != traV.end(); dit = traV.next())
{
Dart e = dit;
std::vector<Dart> v ;
do
{
v.push_back(map.phi1(map.phi1(e)));
v.push_back(map.phi1(e));
e = map.phi2(map.phi_1(e));
}
while(e != dit);
map.splitVolume(v) ;
// Dart old = map.phi2(map.phi1(dit));
// Dart dd = map.phi1(map.phi1(old)) ;
// map.splitFace(old,dd) ;
//
// unsigned int idface = map.getNewFaceId();
// map.setFaceId(dd,idface, FACE);
//
// Dart ne = map.phi1(map.phi1(old)) ;
//
// map.cutEdge(ne);
// centralDart = map.phi1(ne);
// newEdges.push_back(ne);
// newEdges.push_back(map.phi1(ne));
//
// unsigned int id = map.getNewEdgeId() ;
// map.setEdgeId(ne, id, EDGE) ;
//
// Dart stop = map.phi2(map.phi1(ne));
// ne = map.phi2(ne);
// do
// {
// dd = map.phi1(map.phi1(map.phi1(ne)));
//
// map.splitFace(ne, dd) ;
// unsigned int idface = map.getNewFaceId();
// map.setFaceId(dd,idface, FACE);
//
// newEdges.push_back(map.phi1(dd));
//
// ne = map.phi2(map.phi_1(ne));
// dd = map.phi1(map.phi1(dd));
// }
// while(dd != stop);
}
// map.deleteVolume(map.phi3(map.phi2(map.phi1(traV.begin()))));
//
// //Third step : 3-sew internal faces
// for (std::vector<std::pair<Dart,Dart> >::iterator it = subdividedfaces.begin(); it != subdividedfaces.end(); ++it)
// {
// Dart f1 = (*it).first;
// Dart f2 = (*it).second;
//
// if(map.isBoundaryFace(map.phi2(f1)) && map.isBoundaryFace(map.phi2(f2)))
// {
// //id pour toutes les faces interieures
// map.sewVolumes(map.phi2(f1), map.phi2(f2));
//
// //Fais a la couture !!!!!
// unsigned int idface = map.getNewFaceId();
// map.setFaceId(map.phi2(f1),idface, FACE);
// }
//
// //FAIS a la couture !!!!!!!
// //id pour toutes les aretes exterieurs des faces quadrangulees
// unsigned int idedge = map.getEdgeId(f1);
// map.setEdgeId(map.phi2(f1), idedge, DART);
// map.setEdgeId( map.phi2(f2), idedge, DART);
// }
//
// //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!!
// //id pour les aretes interieurs : (i.e. 6 pour un hexa)
// DartMarker mne(map);
// for(unsigned int i = 0; i < newEdges.size(); ++i)
// {
// if(!mne.isMarked(newEdges[i]))
// {
// unsigned int idedge = map.getNewEdgeId();
// map.setEdgeId(newEdges[i], idedge, EDGE);
// mne.markOrbit(EDGE, newEdges[i]);
// }
// }
//
//
// position[centralDart] = volCenter; //plonger a la fin de la boucle ????
map.setCurrentLevel(cur) ;
return subdividedfaces.begin()->first;
}
template <typename PFP>
Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position)
{
......
......@@ -181,6 +181,7 @@ void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelec
Dart d = *it;
//unsew all around the vertex
//there are 2 links to unsew for each face around (-> quadrangulation)
std::vector<Dart> v;
do
{
Dart dN = map.phi1(map.phi2(d));
......@@ -190,7 +191,7 @@ void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelec
if(map.phi2(dRing)!=dRing)
{
toSew.insert(std::pair<Dart,Dart>(dRing,map.phi2(dRing)));
map.unsewFaces(dRing);
v.push_back(dRing);
}
dRing = map.phi1(dRing);
......@@ -198,40 +199,61 @@ void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelec
if(map.phi2(dRing)!=dRing)
{
toSew.insert(std::pair<Dart,Dart>(dRing,map.phi2(dRing)));
map.unsewFaces(dRing);
v.push_back(dRing);
}
d = dN;
} while (*it!=d);
} while (d != *it);
//close the generated hole and create the central vertex
unsigned int degree = map.closeHole(map.phi1(d));
// //close the generated hole and create the central vertex
// //unsigned int degree = map.closeHole(map.phi1(d));
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);
//TODO : pb de face en trop avec splitVolume
//map.splitVolume(v);
Dart e = v.front();
for(std::vector<Dart>::iterator it = v.begin() ; it != v.end() ; ++it)
if(map.Map2::isBoundaryEdge(*it))
map.unsewFaces(*it);
map.fillHole(e) ;
// 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];
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));
}
// 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));
// }
}
// map.deleteVolume(map.phi3(map.phi2(map.phi1(l_vertices.front()))));
map.check();
//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));
}
// Dart f1 = map.phi2((*it).first);
// Dart f2 = map.phi2((*it).second);
// if(map.isBoundaryFace(f1) && map.isBoundaryFace(f2))
// {
// map.sewVolumes(f1, f2);
// }
//Dart dT = map.phi2(it->first);
// if(dT==map.phi3(dT))
// {
// map.sewVolumes(dT,map.phi2(it->second));
// }
}
}
......
......@@ -51,6 +51,7 @@ void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d)
map.splitVolume(sp);
}
/************************************************************************************************
* Tetrahedron functions *
************************************************************************************************/
......
......@@ -58,10 +58,14 @@ protected:
bool m_cpf;
bool m_ef;
Utils::ShaderExplodeVolumesLines* m_shaderL;
Utils::VBO* m_vboPos;
Utils::VBO* m_vboColors;
Utils::VBO* m_vboPosLine;
/**
......@@ -71,23 +75,23 @@ protected:
GLuint m_nbLines;
Geom::Vec3f m_globalColor;
public:
/**
* Constructor
* @param map the map to draw
* @param good functor that return true for darts of part to draw
* @param type_vbo vbo to alloc ( VBO_P, VBO_PN, VBO_PNC, VBO_PC ..)
* @param withColorPerFace affect a color per face
* @param withExplodeFace shrinj each face
*/
ExplodeVolumeRender(bool withColorPerFace=false) ;
ExplodeVolumeRender(bool withColorPerFace=false, bool withExplodeFace=false) ;
/**
* Destructor
*/
~ExplodeVolumeRender() ;
/**
* return a ptr on used shader do not forgot to register
*/
......@@ -98,15 +102,14 @@ public:
*/
Utils::GLSLShader* shaderLines() ;
/**
* update all drawing buffers
* @param map the map
* @param positions attribute of position vertices
* @param good selector
*/
template<typename PFP>
void updateData(typename PFP::MAP& map, typename PFP::TVEC3& positions, const FunctorSelect& good = allDarts) ;
// template<typename PFP>
// void updateData(typename PFP::MAP& map, typename PFP::TVEC3& positions, const FunctorSelect& good = allDarts) ;
/**
* update all drawing buffers
......@@ -133,6 +136,11 @@ public:
*/
void setExplodeVolumes(float explode) ;
/**
* set exploding volume coefficient parameter
*/
void setExplodeFaces(float explode) ;
/**
* set clipping plane
*/
......@@ -149,9 +157,9 @@ public:
void setAmbiant(const Geom::Vec4f& ambiant) ;
/**
* set diffuse color parameter
* set back color parameter
*/
void setDiffuse(const Geom::Vec4f& diffuse) ;
void setBackColor(const Geom::Vec4f& color) ;
/**