Commit 5481fed0 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge cgogn:~cgogn/CGoGN

Conflicts:
	Apps/Examples/viewer.cpp
parents ddce97d7 e42d0200
......@@ -185,7 +185,7 @@ void Viewer::cb_Open()
void Viewer::cb_Save()
{
std::string filters("all (*.*);; map (*.map);; off (*.off);; ply (*.ply);; plygen (*.plygen)") ;
std::string filters("all (*.*);; map (*.map);; off (*.off);; ply (*.ply)") ;
std::string filename = selectFileSave("Save Mesh", "", filters) ;
exportMesh(filename) ;
......@@ -239,7 +239,7 @@ void Viewer::importMesh(std::string& filename)
updateGLMatrices() ;
}
void Viewer::exportMesh(std::string& filename)
void Viewer::exportMesh(std::string& filename, bool askExportMode)
{
size_t pos = filename.rfind(".") ; // position of "." in filename
std::string extension = filename.substr(pos) ;
......@@ -248,9 +248,13 @@ void Viewer::exportMesh(std::string& filename)
Algo::Export::exportOFF<PFP>(myMap, position, filename.c_str(), allDarts) ;
else if (extension.compare(0, 4, std::string(".ply")) == 0)
{
std::vector<VertexAttribute<VEC3>*> attributes ;
int ascii = 0 ;
if (askExportMode)
Utils::QT::inputValues(Utils::QT::VarCombo("binary mode;ascii mode",ascii,"Save in")) ;
std::vector<AttributeHandler<VEC3, VERTEX>*> attributes ;
attributes.push_back(&position) ;
Algo::Export::exportPLYnew<PFP>(myMap, attributes, filename.c_str(), true, allDarts) ;
Algo::Export::exportPLYnew<PFP>(myMap, attributes, filename.c_str(), !ascii, allDarts) ;
}
else if (extension == std::string(".map"))
myMap.saveMapBin(filename) ;
......@@ -307,6 +311,21 @@ void Viewer::slot_normalsSize(int i)
updateGL() ;
}
void Viewer::cb_keyPress(int keycode)
{
switch(keycode)
{
case 'c' :
myMap.check();
break;
default:
break;
}
updateGLMatrices() ;
updateGL();
}
/**********************************************************************************************
* MAIN FUNCTION *
**********************************************************************************************/
......@@ -327,7 +346,7 @@ int main(int argc, char **argv)
{
std::string filenameExp(argv[2]) ;
std::cout << "Exporting " << filename << " as " << filenameExp << " ... "<< std::flush ;
sqt.exportMesh(filenameExp) ;
sqt.exportMesh(filenameExp, false) ;
std::cout << "done!" << std::endl ;
return (0) ;
......
......@@ -46,6 +46,7 @@
#include "Utils/Shaders/shaderVectorPerVertex.h"
#include "Utils/pointSprite.h"
#include "Utils/text3d.h"
#include "Utils/Qt/qtInputs.h"
#include "Algo/Geometry/boundingbox.h"
#include "Algo/Geometry/normal.h"
......@@ -117,8 +118,10 @@ public:
void cb_Open() ;
void cb_Save() ;
void cb_keyPress(int keycode);
void importMesh(std::string& filename) ;
void exportMesh(std::string& filename);
void exportMesh(std::string& filename, bool askExportMode = true);
public slots:
void slot_drawVertices(bool b) ;
......
......@@ -319,6 +319,18 @@ int main(int argc, char **argv)
position = myMap.getAttribute<PFP::VEC3, VERTEX>(attrNames[0]) ;
}
if(extension == std::string(".node"))
{
if(!Algo::Import::importMeshV<PFP>(myMap, argv[1], attrNames, Algo::Import::ImportVolumique::NODE))
{
std::cerr << "could not import " << argv[1] << std::endl ;
return 1;
}
else
position = myMap.getAttribute<PFP::VEC3,VERTEX>(attrNames[0]) ;
}
if(extension == std::string(".off"))
{
if(!Algo::Import::importMeshToExtrude<PFP>(myMap, argv[1], attrNames))
......
......@@ -29,9 +29,11 @@
#include "Algo/Import/import.h"
#include "Algo/Export/export.h"
using namespace CGoGN ;
int main(int argc, char **argv)
{
// // interface
......@@ -197,7 +199,7 @@ void MyQT::createMap(int n)
{
if (dm.isMarked(d) && (!myMap.isBoundaryMarked(d)))
{
int n = random();
int n = rand();
float r = float(n&0x7f)/255.0f + 0.25f;
float g = float((n>>8)&0x7f)/255.0f + 0.25f;
float b = float((n>>16)&0x7f)/255.0 + 0.25f;
......@@ -273,7 +275,7 @@ void MyQT::cb_keyPress(int keycode)
{
if (!myMap.isBoundaryMarked(d))
{
int n = random();
int n = rand();
float r = float(n&0x7f)/255.0f + 0.25f;
float g = float((n>>8)&0x7f)/255.0f + 0.25f;
float b = float((n>>16)&0x7f)/255.0 + 0.25f;
......@@ -388,7 +390,7 @@ void MyQT::importMesh(std::string& filename)
{
if (dm.isMarked(d) && (!myMap.isBoundaryMarked(d)))
{
int n = random();
int n = rand();
float r = float(n&0x7f)/255.0f + 0.25f;
float g = float((n>>8)&0x7f)/255.0f + 0.25f;
float b = float((n>>16)&0x7f)/255.0 + 0.25f;
......
......@@ -25,8 +25,10 @@
#include "tuto_oper3.h"
#include "Algo/Geometry/boundingbox.h"
#include "Algo/Modelisation/polyhedron.h"
#include "Algo/Modelisation/tetrahedralization.h"
#include "Algo/Modelisation/primitives3d.h"
#include "Algo/Geometry/centroid.h"
#include "Algo/Geometry/normal.h"
#include "Algo/Import/import.h"
#include "Algo/Export/export.h"
......@@ -146,7 +148,14 @@ void MyQT::operation(int x)
CGoGNout <<"split volume"<<CGoGNendl;
if (!m_selecteds.empty())
{
std::cout << "start" << std::endl;
for(std::vector<Dart>::iterator it = m_selecteds.begin() ; it != m_selecteds.end() ; ++it)
std::cout << *it << " et phi2() = " << myMap.phi2(*it) << std::endl;
std::cout << "end" << std::endl;
myMap.splitVolume(m_selecteds);
m_selecteds.clear();
dm.markAll();
updateMap();
}
......@@ -175,6 +184,24 @@ void MyQT::operation(int x)
updateMap();
}
break;
case 10:
CGoGNout <<"split vertex"<<CGoGNendl;
if (!m_selecteds.empty() && m_selected != NIL)
{
Dart dit = m_selecteds.front();
PFP::VEC3 Q = (position[myMap.phi1(m_selected)] + position[m_selected])/2.0f;
//PFP::VEC3 c1 = Algo::Geometry::volumeCentroid<PFP>(myMap, dit, position);
//Dart dres = myMap.splitVertex(m_selecteds);
Dart dres = Algo::Modelisation::Tetrahedralization::splitVertex<PFP>(myMap, m_selecteds);
position[dres] = position[dit] + Q*0.25f;
//position[dit] = position[dit] - c1*0.5f;
m_selecteds.clear();
m_selected = NIL;
dm.markAll();
updateMap();
std::cout << "nb darts after = " << myMap.getNbDarts() << std::endl;
}
break;
default:
break;
}
......@@ -193,6 +220,15 @@ void MyQT::createMap(int n)
prim.hexaGrid_topo(n,n,n);
prim.embedHexaGrid(1.0f,1.0f,1.0f);
// Dart d = Algo::Modelisation::createTetrahedron<PFP>(myMap);
// myMap.closeMap();
//
// position[d] = typename PFP::VEC3(0.0f, 0.0f, 0.0f);
// position[myMap.phi1(d)] = typename PFP::VEC3(0.0f, 1.0f, 0.0f);
// position[myMap.phi1(myMap.phi1(d))] = typename PFP::VEC3(1.0f, 0.5f, 0.0f);
// position[myMap.phi_1(myMap.phi2(d))] = typename PFP::VEC3(0.5f, 0.5f, 1.0f);
// bounding box of scene
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
setParamObject(bb.maxSize(), bb.center().data()) ;
......
......@@ -71,7 +71,7 @@
</item>
<item>
<property name="text">
<string>collapsedge</string>
<string>collapseEdge</string>
</property>
</item>
<item>
......@@ -99,6 +99,11 @@
<string>collapseVolume</string>
</property>
</item>
<item>
<property name="text">
<string>splitVertex</string>
</property>
</item>
</widget>
</item>
<item>
......@@ -110,7 +115,7 @@
<number>10</number>
</property>
<property name="singleStep">
<number>2</number>
<number>0</number>
</property>
<property name="value">
<number>1</number>
......
......@@ -121,5 +121,11 @@ ENDIF(WIN32)
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
IF(WIN32)
link_directories( ${CGoGN_ROOT_DIR}/lib/ ${Boost_LIBRARY_DIRS} )
ELSE (WIN32)
link_directories( ${CGoGN_ROOT_DIR}/lib/Debug ${CGoGN_ROOT_DIR}/lib/Release)
ENDIF (WIN32)
......@@ -134,6 +134,16 @@ bool exportPlyPTMgeneric(typename PFP::MAP& map, const VertexAttribute<typename
template <typename PFP>
bool exportPLYPTM(typename PFP::MAP& map, const char* filename, const VertexAttribute<typename PFP::VEC3>& position, const VertexAttribute<typename PFP::VEC3> frame[3], const VertexAttribute<typename PFP::VEC3> colorPTM[6], const FunctorSelect& good = allDarts) ;
/**
* export meshes used at the workbench
* export just a list of vertices and edges connectivity
* @param map
* @param position
* @return
*/
template <typename PFP>
bool exportChoupi(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const FunctorSelect& good = allDarts) ;
} // namespace Export
} // namespace Algo
......
......@@ -910,6 +910,39 @@ bool exportPLYPTM(typename PFP::MAP& map, const char* filename, const VertexAttr
return true ;
}
template <typename PFP>
bool exportChoupi(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const FunctorSelect& good)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
std::ofstream out(filename, std::ios::out) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << CGoGNendl ;
return false ;
}
out << map.getNbOrbits(VERTEX) << " " << map.getNbOrbits(EDGE) << std::endl;
TraversorV<typename PFP::MAP> travV(map);
for(Dart dit = travV.begin() ; dit != travV.end() ; dit = travV.next())
{
out << map.getEmbedding(VERTEX, dit) << " " << position[dit] << std::endl;
}
TraversorE<typename PFP::MAP> travE(map);
unsigned int indexE = 0;
for(Dart dit = travE.begin() ; dit != travE.end() ; dit = travE.next())
{
out << indexE << " " << map.getEmbedding(VERTEX, dit) << " " << map.getEmbedding(VERTEX, map.phi2(dit)) << std::endl;
++indexE;
}
out.close() ;
return true ;
}
} // namespace Export
} // namespace Algo
......
......@@ -83,6 +83,15 @@ template <typename PFP>
bool importMoka(typename PFP::MAP& gmap, const std::string& filename, std::vector<std::string>& attrNames);
/**
* import a Choupi file
* @param map
* @param filename
* @return
*/
template <typename PFP>
bool importChoupi(const std::string& filename, const std::vector<typename PFP::VEC3>& tabV, const std::vector<unsigned int>& tabE);
/*
* TODO a transformer en utilisant un MeshTableVolume.
*/
......@@ -117,4 +126,6 @@ bool importTs(typename PFP::MAP& the_map, const std::string& filename, std::vect
#include "Algo/Import/importTs.hpp"
#include "Algo/Import/importNodeEle.hpp"
#include "Algo/Import/importChoupi.hpp"
#endif
......@@ -22,107 +22,96 @@
* *
*******************************************************************************/
#include "Topology/map/map2MR/map2MR_PM.h"
namespace CGoGN
{
Map2MR_PM::Map2MR_PM() :
shareVertexEmbeddings(true)
namespace Algo
{
initMR() ;
}
void Map2MR_PM::addNewLevel(bool embedNewVertices)
namespace Import
{
pushLevel() ;
//Add the current level higher
unsigned int newLevel = m_mrDarts.size() ;
std::stringstream ss ;
ss << "MRdart_"<< newLevel ;
AttributeMultiVector<unsigned int>* newAttrib = m_mrattribs.addAttribute<unsigned int>(ss.str()) ;
m_mrDarts.push_back(newAttrib) ;
m_mrNbDarts.push_back(0) ;
template <typename PFP>
bool importChoupi(const std::string& filename, std::vector<typename PFP::VEC3>& tabV, std::vector<unsigned int>& tabE)
{
typedef typename PFP::VEC3 VEC3;
if(m_mrDarts.size() > 1)
//open file
std::ifstream fp(filename.c_str(), std::ios::in);
if (!fp.good())
{
for(unsigned int i = newLevel; i > 0 ; --i)
{
AttributeMultiVector<unsigned int>* currentAttrib = m_mrDarts[i] ;
AttributeMultiVector<unsigned int>* prevAttrib = m_mrDarts[i - 1] ; // copy the indices of
m_mrattribs.copyAttribute(currentAttrib->getIndex(), prevAttrib->getIndex()) ; // previous level into new level
}
CGoGNerr << "Unable to open file " << filename << CGoGNendl;
return false;
}
popLevel() ;
std::string ligne;
unsigned int nbv, nbe;
std::getline(fp, ligne);
setCurrentLevel(0);
std::stringstream oss(ligne);
oss >> nbv;
oss >> nbe;
//DartMarker me(*this);
selectedEdges = new DartMarkerStore(*this);
std::vector<unsigned int> index;
index.reserve(1024);
TraversorE<Map2MR_PM> travE(*this);
for (Dart d = travE.begin(); d != travE.end(); d = travE.next())
//read vertices
unsigned int id = 0;
for(unsigned int j=0 ; j < nbv ; ++j)
{
if(!selectedEdges->isMarked(d))
do
{
if(edgeCanCollapse(d))
{
//interdire la contraction d'arete partageant un meme sommet
//interdire la contraction d'arete
//interdire la contraction d'une arete d'une face incidente au sommet de d
//=> mark incident edges of vertices adjacent to the vertex of d through a common face
Traversor2VVaF<Map2MR_PM> travVVaF(*this, d);
for (Dart dit = travVVaF.begin(); dit != travVVaF.end(); dit = travVVaF.next())
{
Dart ditV = dit;
do
{
if(!selectedEdges->isMarked(ditV))
selectedEdges->markOrbit<EDGE>(ditV);
ditV = phi2(phi_1(ditV));
} while(ditV != dit);
}
//=> the same for the vertex phi2(d)
Traversor2VVaF<Map2MR_PM> travVVaF2(*this, phi2(d));
for (Dart dit = travVVaF2.begin(); dit != travVVaF2.end(); dit = travVVaF2.next())
{
Dart ditV = dit;
do
{
if(!selectedEdges->isMarked(ditV))
selectedEdges->markOrbit<EDGE>(ditV);
ditV = phi2(phi_1(ditV));
} while(ditV != dit);
}
}
}
std::getline(fp, ligne);
} while(ligne.size() == 0);
std::stringstream oss(ligne);
float i, x, y, z;
oss >> i;
oss >> x;
oss >> y;
oss >> z;
VEC3 pos(x,y,z);
index[i] = id;
tabV.push_back(pos);
++id;
}
}
void Map2MR_PM::analysis()
{
assert(getCurrentLevel() > 0 || !"analysis : called on level 0") ;
std::stringstream oss2(ligne);
decCurrentLevel() ;
for(unsigned int i=0 ; i < nbe ; ++i)
{
do
{
std::getline(fp, ligne);
}while(ligne.size() == 0);
for(unsigned int i = 0; i < analysisFilters.size(); ++i)
(*analysisFilters[i])() ;
}
std::stringstream oss(ligne);
void Map2MR_PM::synthesis()
{
assert(getCurrentLevel() < getMaxLevel() || !"synthesis : called on max level") ;
unsigned int x, y;
oss >> x;
oss >> x;
oss >> y;
tabE.push_back(index[x]);
tabE.push_back(index[y]);
}
//for(typename std::vector<VEC3>::iterator it = tabV.begin() ; it < tabV.end() ; ++it)
// std::cout << *it << std::endl;
for(unsigned int i = 0; i < synthesisFilters.size(); ++i)
(*synthesisFilters[i])() ;
//for(std::vector<unsigned int>::iterator it = tabE.begin() ; it < tabE.end() ; it = it + 2)
// std::cout << *it << " " << *(it + 1) << std::endl;
incCurrentLevel() ;
return true;
}
} // namespace Import
} // namespace Algo
} // namespace CGoGN
......@@ -121,6 +121,8 @@ protected:
int per_vertex_color_float32, per_vertex_color_uint8 ;
int has_normals;
char *old_locale;
};
} // namespace CGoGN
......
......@@ -44,6 +44,13 @@ namespace Tetrahedralization
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
/************************************************************************************************
* Collapse / Split Operators
************************************************************************************************/
template <typename PFP>
Dart splitVertex(typename PFP::MAP& map, std::vector<Dart>& vd);
/************************************************************************************************
* Tetrahedron functions *
************************************************************************************************/
......@@ -56,6 +63,14 @@ void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
template <typename PFP>
bool isTetrahedron(typename PFP::MAP& the_map, Dart d);
/**
* test if a mesh (or submesh) is a tetrahedral mesh
* @param map
* @param selected
*/
template <typename PFP>
bool isTetrahedralization(typename PFP::MAP& map, const FunctorSelect& selected = allDarts);
/************************************************************************************************
* Swap Functions *
************************************************************************************************/
......
......@@ -55,7 +55,44 @@ void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d)
/************************************************************************************************
* Tetrahedron functions *
* Collapse / Split Operators
************************************************************************************************/
template <typename PFP>
Dart splitVertex(typename PFP::MAP& map, std::vector<Dart>& vd)
{
//split the vertex
Dart dres = map.splitVertex(vd);
//split the faces incident to the new vertex
Dart dbegin = map.phi1(map.phi2(vd.front()));
Dart dit = dbegin;
do
{
map.splitFace(map.phi1(dit),map.phi_1(dit));
dit = map.alpha2(dit);
}
while(dbegin != dit);
//split the volumes incident to the new vertex
for(unsigned int i = 0; i < vd.size(); ++i)
{
Dart dit = vd[i];
std::vector<Dart> v;
v.push_back(map.phi1(map.phi1(map.phi2(dit))));
std::cout << "[" << v.back();
v.push_back(map.phi1(dit));
std::cout << " - " << v.back();
v.push_back(map.phi1(map.phi2(map.phi_1(dit))));
std::cout << " - " << v.back() << "]" << std::endl;
//map.splitVolume(v);
}
return dres;
}
/************************************************************************************************
* Tetrahedron functions *
************************************************************************************************/
template <typename PFP>
......@@ -80,8 +117,21 @@ bool isTetrahedron(typename PFP::MAP& the_map, Dart d)
return true;
}
template <typename PFP>
bool isTetrahedralization(typename PFP::MAP& map, const FunctorSelect& selected)
{
TraversorV<typename PFP::MAP> travV(map, selected);
for(Dart dit = travV.begin() ; dit != travV.end() ; dit = travV.next())
{
if(!isTetrahedron<PFP>(map, dit))
return false;
}
return true;
}
/************************************************************************************************
* Topological functions *
* Topological functions *
************************************************************************************************/
//sew a face into the edge
......@@ -380,7 +430,7 @@ void swap5To4(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positions)
}
/************************************************************************************************
* Flip Functions *
* Flip Functions *
************************************************************************************************/
template <typename PFP>
......
......@@ -37,6 +37,12 @@ class EmbeddedMap3 : public Map3
public:
typedef Map3 TOPO_MAP;
//!