Commit 3b558815 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge cgogn:~untereiner/CGoGN

Conflicts:
	include/Algo/Import/import2tablesSurface.hpp
parents 7db271ad 50a9f367
......@@ -92,7 +92,6 @@ void MyQT::operation(int x)
if (m_selected != NIL)
{
dm.markAll();
PFP::VEC3 Q = position[myMap.phi1(m_selected)];
myMap.uncutEdge(m_selected);
updateMap();
}
......@@ -104,7 +103,6 @@ void MyQT::operation(int x)
if (myMap.deleteEdgePreCond(m_selected))
{
dm.markAll();
PFP::VEC3 Q = position[myMap.phi1(m_selected)];
myMap.deleteEdge(m_selected);
m_selected = NIL;
updateMap();
......@@ -155,7 +153,30 @@ void MyQT::operation(int x)
updateMap();
}
break;
case 8:
CGoGNout <<"collapse face"<<CGoGNendl;
if (m_selected != NIL)
{
PFP::VEC3 Q = Algo::Geometry::faceCentroid<PFP>(myMap,m_selected,position);
Dart x = myMap.collapseFace(m_selected);
dm.markAll();
position[x]= Q;
m_selected = NIL;
updateMap();
}
break;
case 9:
CGoGNout <<"collapse volume"<<CGoGNendl;
if (m_selected != NIL)
{
PFP::VEC3 Q = Algo::Geometry::volumeCentroid<PFP>(myMap,m_selected,position);
Dart x = myMap.collapseVolume(m_selected);
dm.markAll();
position[x]= Q;
m_selected = NIL;
updateMap();
}
break;
default:
break;
}
......@@ -284,8 +305,9 @@ void MyQT::cb_keyPress(int keycode)
updateMap();
updateGL();
break;
case 'c':
myMap.check();
break;
case 'a':
m_selected = myMap.phi1(m_selected);
updateGL();
......@@ -409,7 +431,7 @@ void MyQT::svg()
void MyQT::cb_Open()
{
std::string filters("all (*.*);; trian (*.trian);; off (*.off);; ply (*.ply);; map (*.map)") ;
std::string filters("all (*.*);; map (*.map)") ;
std::string filename = selectFile("Open Mesh", "", filters) ;
if (!filename.empty())
importMesh(filename);
......@@ -434,16 +456,40 @@ void MyQT::importMesh(std::string& filename)
myMap.loadMapBin(filename);
position = myMap.getAttribute<PFP::VEC3>(VERTEX, "position") ;
}
else
else if (extension == std::string(".node"))
{
std::vector<std::string> attrNames ;
if(!Algo::Import::importMeshV<PFP>(myMap, filename, attrNames, Algo::Import::ImportVolumique::NODE))
{
std::cerr << "could not import " << filename << std::endl ;
return ;
}
position = myMap.getAttribute<PFP::VEC3>(VERTEX, attrNames[0]) ;
}
else if(extension == std::string(".tet"))
{
std::vector<std::string> attrNames ;
if(!Algo::Import::importMesh<PFP>(myMap, filename.c_str(), attrNames))
if(!Algo::Import::importMeshV<PFP>(myMap, filename, attrNames, Algo::Import::ImportVolumique::TET))
{
CGoGNerr << "could not import " << filename << CGoGNendl ;
return;
std::cerr << "could not import " << filename << std::endl ;
return ;
}
position = myMap.getAttribute<PFP::VEC3>(VERTEX, attrNames[0]) ;
}
else if(extension == std::string(".off"))
{
std::vector<std::string> attrNames ;
if(!Algo::Import::importMeshV<PFP>(myMap, filename, attrNames, Algo::Import::ImportVolumique::OFF))
{
std::cerr << "could not import " << filename << std::endl ;
return ;
}
position = myMap.getAttribute<PFP::VEC3>(VERTEX, attrNames[0]) ;
}
else
{
std::cerr << "could not import " << filename << std::endl ;
}
m_selected = NIL;
m_selected2 = NIL;
......
......@@ -89,6 +89,16 @@
<string>splitVolume</string>
</property>
</item>
<item>
<property name="text">
<string>collapseFace</string>
</property>
</item>
<item>
<property name="text">
<string>collapseVolume</string>
</property>
</item>
</widget>
</item>
<item>
......
......@@ -89,6 +89,9 @@ bool importMoka(typename PFP::MAP& gmap, const std::string& filename, std::vecto
template <typename PFP>
bool importOFFWithELERegions(typename PFP::MAP& the_map, const std::string& filenameOFF, const std::string& filenameELE, std::vector<std::string>& attrNames);
template <typename PFP>
bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenameNode, const std::string& filenameELE, std::vector<std::string>& attrNames);
template <typename PFP>
bool importTet(typename PFP::MAP& the_map, const std::string& filename, std::vector<std::string>& attrNames, float scaleFactor = 1.0f);
......@@ -112,5 +115,6 @@ bool importTs(typename PFP::MAP& the_map, const std::string& filename, std::vect
#include "Algo/Import/importObjEle.hpp"
#include "Algo/Import/importTet.hpp"
#include "Algo/Import/importTs.hpp"
#include "Algo/Import/importNodeEle.hpp"
#endif
......@@ -57,7 +57,7 @@ namespace Import
namespace ImportVolumique
{
enum ImportType { UNKNOWNVOLUME , TET, ELE, TS };
enum ImportType { UNKNOWNVOLUME , TET, OFF, TS, NODE};
}
......
......@@ -591,7 +591,7 @@ bool MeshTablesSurface<PFP>::importPly(const std::string& filename, std::vector<
CGoGNerr << "Unable to open file " << filename << CGoGNendl;
return false;
}
AttributeHandler<typename PFP::VEC3> colors = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "color") ;
if (pid.hasColors())
{
......@@ -1102,7 +1102,6 @@ bool MeshTablesSurface<PFP>::importPlyPTM(const std::string& filename, std::vect
}
*/
template <typename PFP>
bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector<std::string>& attrNames)
{
......@@ -1116,7 +1115,6 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
return false;
}
// Read header
AHEMHeader hdr;
......@@ -1126,11 +1124,9 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
if(hdr.magic != AHEM_MAGIC)
CGoGNerr << "Warning: " << filename << " invalid magic" << CGoGNendl;
m_nbVertices = hdr.meshHdr.vxCount;
m_nbFaces = hdr.meshHdr.faceCount;
// Read attributes
AHEMAttributeDescriptor* ahemAttrDesc = new AHEMAttributeDescriptor[hdr.attributesChunkNumber];
......@@ -1144,7 +1140,6 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
fp.read(ahemAttrNames[i], ahemAttrDesc[i].nameSize);
ahemAttrNames[i][ahemAttrDesc[i].nameSize] = '\0';
}
// Compute buffer size for largest chunk and allocate
......@@ -1154,23 +1149,18 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
if(ahemAttrDesc[i].attributeChunkSize > bufferSize)
bufferSize = ahemAttrDesc[i].attributeChunkSize;
char* buffer = new char[bufferSize];
// Allocate vertices
AttributeContainer& vxContainer = m_map.getAttributeContainer(VERTEX);
std::vector<unsigned int> verticesId;
verticesId.resize(hdr.meshHdr.vxCount);
for(unsigned int i = 0 ; i < hdr.meshHdr.vxCount ; i++)
verticesId[i] = vxContainer.insertLine();
// Read faces stream
m_nbEdges.resize(hdr.meshHdr.faceCount);
......@@ -1200,8 +1190,6 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
fCount += fbd->batchLength;
batch = (char*)ix;
}
// Read positions
......@@ -1215,11 +1203,13 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
AHEMAttributeDescriptor* posDesc = NULL;
for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++)
{
if(IsEqualGUID(ahemAttrDesc[i].semantic, AHEMATTRIBUTE_POSITION))
{
posDesc = ahemAttrDesc + i;
break;
}
}
fp.seekg(posDesc->fileStartOffset, std::ios_base::beg);
fp.read(buffer, posDesc->attributeChunkSize);
......@@ -1232,9 +1222,6 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
q += 3;
}
// Close file and release allocated stuff
fp.close();
......@@ -1249,7 +1236,6 @@ bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector
return true;
}
#ifdef WITH_ASSIMP
template<typename PFP>
void MeshTablesSurface<PFP>::extractMeshRec(AttributeContainer& container, AttributeHandler<typename PFP::VEC3>& positions, const struct aiScene* scene, const struct aiNode* nd, struct aiMatrix4x4* trafo)
......@@ -1332,9 +1318,9 @@ bool MeshTablesSurface<PFP>::importASSIMP(const std::string& filename, std::vect
template<typename PFP>
bool MeshTablesSurface<PFP>::mergeCloseVertices()
{
const int NBV=64; // seems to be good
const int NBV = 64; // seems to be good
const int NEIGH[27]={
const int NEIGH[27] = {
-NBV*NBV - NBV - 1, -NBV*NBV - NBV, -NBV*NBV - NBV + 1,
-NBV*NBV - 1, -NBV*NBV, -NBV*NBV + 1,
-NBV*NBV + NBV - 1, -NBV*NBV + NBV, - NBV*NBV + NBV + 1,
......@@ -1368,12 +1354,10 @@ bool MeshTablesSurface<PFP>::mergeCloseVertices()
bb.addPoint( bb.min() - one);
bb.addPoint( bb.max() + one);
bbsize = (bb.max() - bb.min());
AutoAttributeHandler<unsigned int> gridIndex(m_map,VERTEX, "gridIndex");
AutoAttributeHandler<unsigned int> newIndices(m_map,VERTEX, "newIndices");
// Store each vertex in the grid and store voxel index in vertex attribute
for (unsigned int i = positions.begin(); i != positions.end(); positions.next(i))
{
......@@ -1479,8 +1463,6 @@ bool MeshTablesSurface<PFP>::mergeCloseVertices()
return true;
}
} // namespace Import
} // namespace Algo
......
......@@ -37,8 +37,8 @@ ImportVolumique::ImportType MeshTablesVolume<PFP>::getFileType(const std::string
if ((filename.rfind(".tet")!=std::string::npos) || (filename.rfind(".TET")!=std::string::npos))
return ImportVolumique::TET;
if ((filename.rfind(".ele")!=std::string::npos) || (filename.rfind(".ELE")!=std::string::npos))
return ImportVolumique::ELE;
if ((filename.rfind(".node")!=std::string::npos) || (filename.rfind(".NODE")!=std::string::npos))
return ImportVolumique::NODE;
if ((filename.rfind(".ts")!=std::string::npos) || (filename.rfind(".TS")!=std::string::npos))
return ImportVolumique::TS;
......@@ -56,7 +56,7 @@ bool MeshTablesVolume<PFP>::importMesh(const std::string& filename, std::vector<
case ImportVolumique::TET:
return importTet(filename, attrNames, scaleFactor);
break;
case ImportVolumique::ELE:
case ImportVolumique::NODE:
break;
case ImportVolumique::TS:
break;
......
......@@ -268,8 +268,8 @@ bool importMeshV(typename PFP::MAP& map, const std::string& filename, std::vecto
if ((filename.rfind(".tet") != std::string::npos) || (filename.rfind(".TET") != std::string::npos))
kind = ImportVolumique::TET;
if ((filename.rfind(".ele") != std::string::npos) || (filename.rfind(".ELE") != std::string::npos))
kind = ImportVolumique::ELE;
if ((filename.rfind(".off") != std::string::npos) || (filename.rfind(".OFF") != std::string::npos))
kind = ImportVolumique::OFF;
if ((filename.rfind(".ts") != std::string::npos) || (filename.rfind(".TS") != std::string::npos))
kind = ImportVolumique::TS;
......@@ -279,13 +279,22 @@ bool importMeshV(typename PFP::MAP& map, const std::string& filename, std::vecto
case ImportVolumique::TET:
return Algo::Import::importTet<PFP>(map, filename, attrNames, 1.0f);
break;
case ImportVolumique::ELE:
case ImportVolumique::OFF:
{
size_t pos = filename.rfind(".");
std::string fileOFF = filename;
fileOFF.erase(pos);
fileOFF.append(".off");
return Algo::Import::importOFFWithELERegions<PFP>(map, fileOFF, filename, attrNames);
std::string fileEle = filename;
fileEle.erase(pos);
fileEle.append(".ele");
return Algo::Import::importOFFWithELERegions<PFP>(map, filename, fileEle, attrNames);
break;
}
case ImportVolumique::NODE:
{
size_t pos = filename.rfind(".");
std::string fileEle = filename;
fileEle.erase(pos);
fileEle.append(".ele");
return Algo::Import::importNodeWithELERegions<PFP>(map, filename, fileEle, attrNames);
break;
}
case ImportVolumique::TS:
......
......@@ -323,7 +323,7 @@ public:
/**
* Traverse volumes adjacent to a volumee by a vertex
* Traverse volumes adjacent to a volume by a vertex
*/
template <typename MAP>
class Traversor3WWaV: public Traversor3XXaY<MAP>
......@@ -333,7 +333,7 @@ public:
};
/**
* Traverse volumes adjacent to a volumee by an edge
* Traverse volumes adjacent to a volume by an edge
*/
template <typename MAP>
class Traversor3WWaE: public Traversor3XXaY<MAP>
......@@ -343,7 +343,7 @@ public:
};
/**
* Traverse volumes adjacent to a volumee by a face
* Traverse volumes adjacent to a volume by a face
*/
template <typename MAP>
class Traversor3WWaF: public Traversor3XXaY<MAP>
......
......@@ -78,6 +78,12 @@ public:
*/
virtual void splitFace(Dart d, Dart e);
//!
/*!
*
*/
virtual Dart collapseFace(Dart d, bool delDegenerateVolumes = true);
//!
/*!
*/
......@@ -98,6 +104,11 @@ public:
*/
virtual void splitVolume(std::vector<Dart>& vd);
//!
/*!
*/
virtual Dart collapseVolume(Dart d, bool delDegenerateVolumes = true);
//!
/*! No attribute is attached to the new volume
*/
......
/*******************************************************************************
* 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 *
* *
*******************************************************************************/
#ifndef __MAP2MR_PM__
#define __MAP2MR_PM__
#include "Topology/map/embeddedMap2.h"
#include "Topology/generic/traversorCell.h"
#include "Topology/generic/traversor2.h"
#include "Topology/map/map2MR/filters_Primal.h"
#include "Algo/Modelisation/subdivision.h"
namespace CGoGN
{
class SelectorCollapsingEdges : public FunctorSelect
{
protected:
const DartMarker& m_dm;
public:
SelectorCollapsingEdges(const DartMarker& dm): m_dm(dm) {}
bool operator()(Dart d) const { return m_dm.isMarked(d); }
FunctorSelect* copy() const { return new SelectorCollapsingEdges(m_dm);}
};
class Map2MR_PM : public EmbeddedMap2
{
protected:
bool shareVertexEmbeddings ;
std::vector<Multiresolution::MRFilter*> synthesisFilters ;
std::vector<Multiresolution::MRFilter*> analysisFilters ;
DartMarkerStore* selectedEdges;
public:
Map2MR_PM() ;
virtual std::string mapTypeName() const { return "Map2MR_PM" ; }
void addNewLevel(bool embedNewVertices = true) ;
void addSynthesisFilter(Multiresolution::MRFilter* f) { synthesisFilters.push_back(f) ; }
void addAnalysisFilter(Multiresolution::MRFilter* f) { analysisFilters.push_back(f) ; }
void clearSynthesisFilters() { synthesisFilters.clear() ; }
void clearAnalysisFilters() { analysisFilters.clear() ; }
void analysis() ;
void synthesis() ;
} ;
} ;
} // namespace CGoGN
#endif
......@@ -198,6 +198,13 @@ public:
*/
virtual void splitFace(Dart d, Dart e);
//! Collapse a face (that is deleted) possibly merging its vertices
/*! \warning
* @param d a dart in the deleted face
* @return a dart of the resulting vertex
*/
virtual Dart collapseFace(Dart d, bool delDegenerateVolumes = true);
//! Delete a volume if and only if it has a face with degree < 3 or only 3 vertices
/*! If the volume is sewed to two distinct adjacent volumes and if the face degree
* of the two adjacent volumes is equal then those two volumes are sewed
......@@ -235,6 +242,13 @@ public:
/*! @param vd a vector of darts
*/
virtual void splitVolume(std::vector<Dart>& vd);
//! Collapse a volume (that is deleted) possibly merging its vertices
/*! \warning
* @param d a dart in the deleted volume
* @return a dart of the resulting vertex
*/
virtual Dart collapseVolume(Dart d, bool delDegenerateVolumes = true);
//@}
/*! @name Topological Queries
......
......@@ -309,11 +309,13 @@ public:
typename PFP::VEC3 p = Algo::Geometry::faceCentroid<PFP>(m_map, d, m_position);
m_map.incCurrentLevel() ;
Dart midF = m_map.phi2(m_map.phi1(d));
m_position[midF] = p ;
if(m_map.faceDegree(d) != 3)
{
Dart midF = m_map.phi2(m_map.phi1(d));
m_position[midF] = p ;
}
m_map.decCurrentLevel() ;
}
}
} ;
......@@ -338,15 +340,19 @@ public:
m_map.incCurrentLevel() ;
Dart midV = m_map.phi_1(m_map.phi2(m_map.phi1(d)));
m_position[midV] = p ;
if(!m_map.isTetrahedron(d))
{
Dart midV = m_map.phi_1(m_map.phi2(m_map.phi1(d)));
m_position[midV] = p ;
}
m_map.decCurrentLevel() ;
}
}
} ;
/* Loop on Boundary Vertices
/* Loop on Boundary Vertices and SHW04 on Insides Vertices
*********************************************************************************/
template <typename PFP>
class LoopEvenSynthesisFilter : public MRFilter
......@@ -516,233 +522,6 @@ public:
}
} ;
/*********************************************************************************
* FUNCTORS
*********************************************************************************/
/* Linear Interpolation
*********************************************************************************/
template <typename PFP>
class LerpVertexVertexFunctor : public FunctorType
{
protected:
typename PFP::MAP& m_map ;
typename PFP::TVEC3& m_position ;
public:
LerpVertexVertexFunctor(typename PFP::MAP& m, typename PFP::TVEC3& p) : m_map(m), m_position(p)
{}
bool operator() (Dart d)
{
m_map.decCurrentLevel() ;
typename PFP::VEC3 p = m_position[d] ;
m_map.incCurrentLevel() ;
m_position[d] = p ;
return false ;
}
};
template <typename PFP>
class LerpEdgeVertexFunctor : public FunctorType
{
protected:
typename PFP::MAP& m_map ;
typename PFP::TVEC3& m_position ;
public:
LerpEdgeVertexFunctor(typename PFP::MAP& m, typename PFP::TVEC3& p) : m_map(m), m_position(p)
{}
bool operator() (Dart d)
{
Dart d1 = m_map.phi2(d);
m_map.decCurrentLevel();
Dart d2 = m_map.phi2(d1);
typename PFP::VEC3 p = (m_position[d1] + m_position[d2]) * typename PFP::REAL(0.5);
m_map.incCurrentLevel();
m_position[d] = p;
return false;
}
} ;
template <typename PFP>
class LerpFaceVertexFunctor : public FunctorType
{
protected:
typename PFP::MAP& m_map ;
typename PFP::TVEC3& m_position ;
public:
LerpFaceVertexFunctor(typename PFP::MAP& m, typename PFP::TVEC3& p) : m_map(m), m_position(p)
{}
bool operator() (Dart d)
{
Dart df = m_map.phi1(m_map.phi1(d)) ;
m_map.decCurrentLevel