Commit 24de3489 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge branch 'develop' of cgogn:~thery/CGoGN into develop

parents e75796dd 56f2be8c
...@@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 2.8) ...@@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 2.8)
project(examples) project(examples)
SET(CMAKE_BUILD_TYPE Release) SET(CMAKE_BUILD_TYPE Release)
#SET(CMAKE_BUILD_TYPE Debug)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOTOPOWARNING") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOTOPOWARNING")
...@@ -26,3 +29,6 @@ target_link_libraries( bench_trav ${CGoGN_LIBS_R} ${CGoGN_EXT_LIBS} ) ...@@ -26,3 +29,6 @@ target_link_libraries( bench_trav ${CGoGN_LIBS_R} ${CGoGN_EXT_LIBS} )
add_executable(bench_remesh bench_remesh.cpp ) add_executable(bench_remesh bench_remesh.cpp )
target_link_libraries( bench_remesh ${CGoGN_LIBS_R} ${CGoGN_EXT_LIBS} ) target_link_libraries( bench_remesh ${CGoGN_LIBS_R} ${CGoGN_EXT_LIBS} )
add_executable(bench_compact bench_compact.cpp )
target_link_libraries( bench_compact ${CGoGN_LIBS_R} ${CGoGN_EXT_LIBS} )
...@@ -46,3 +46,11 @@ target_link_libraries( copyfrom ...@@ -46,3 +46,11 @@ target_link_libraries( copyfrom
add_executable( movefrom ./movefrom.cpp) add_executable( movefrom ./movefrom.cpp)
target_link_libraries( movefrom target_link_libraries( movefrom
${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS}) ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS})
add_executable( compact ./compact.cpp)
target_link_libraries( compact
${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS})
add_executable( reusememory ./reusememory.cpp)
target_link_libraries( reusememory
${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS})
/*******************************************************************************
* 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 *
* *
*******************************************************************************/
#include "Topology/generic/parameters.h"
#include "Topology/map/embeddedMap2.h"
#include "Algo/Tiling/Surface/square.h"
#include "Algo/Geometry/area.h"
using namespace CGoGN ;
/**
* Struct that contains some informations about the types of the manipulated objects
* Mainly here to be used by the algorithms that are parameterized by it
*/
struct PFP2: public PFP_STANDARD
{
// definition of the type of the map
typedef EmbeddedMap2 MAP;
};
typedef PFP2::MAP MAP;
typedef PFP2::VEC3 VEC3;
int main()
{
// declare a map to handle the mesh
MAP myMap;
// add position attribute on vertices and get handler on it
VertexAttribute<VEC3, MAP> position = myMap.addAttribute<VEC3, VERTEX, MAP>("position");
Algo::Surface::Tilings::Square::Cube<PFP2> cube(myMap, 2, 2, 2);
cube.embedIntoCube(position, 10.0f, 10.0f, 10.0f);
FaceAttribute<VEC3, MAP> color = myMap.addAttribute<VEC3, FACE, MAP>("colorFace");
foreach_cell<FACE>(myMap, [&](Face f)
{
color[f] =(Algo::Surface::Geometry::faceCentroid<PFP2>(myMap,f,position)+ VEC3(5,5,5))/10.0f;
});
CGoGNout.toStd(false);
CGoGNout.toFile("compact_init.csv");
myMap.dumpCSV();
std::cout << "MAP dumped in compact_init.csv"<< std::endl;
// mark central vertex of each face of the cube
CellMarker<MAP,VERTEX> cm(myMap);
foreach_cell<VERTEX>(myMap, [&](Vertex v)
{
int nb=0;
if (position[v][0] == 0.0f)
nb++;
if (position[v][1] == 0.0f)
nb++;
if (position[v][2] == 0.0f)
nb++;
if (nb == 2)
cm.mark(v);
});
// remove central vertex of each face of the cube
foreach_cell<VERTEX>(myMap, [&](Vertex v)
{
if (cm.isMarked(v))
{
std::cout << "delete vertex"<< std::endl;
myMap.deleteVertex(v);
}
});
// remove middle points of each edge of the cube
foreach_cell<EDGE>(myMap, [&](Edge e)
{
Vertex v(e.dart);
if (myMap.vertexDegree(v)==2)
myMap.uncutEdge(myMap.phi_1(v));
});
CGoGNout.toFile("compact_before.csv");
myMap.dumpCSV();
std::cout << "MAP with holes dumped in compact_before.csv"<< std::endl;
std::cout << "Total area before simplif "<< Algo::Surface::Geometry::totalArea<PFP2>(myMap,position)<< std::endl;
myMap.compact();
CGoGNout.toFile("compact_after.csv");
myMap.dumpCSV();
std::cout << "Compacted MAP dumped in compact_after.csv"<< std::endl;
std::cout << "Total area after simplif"<< Algo::Surface::Geometry::totalArea<PFP2>(myMap,position)<< std::endl;
myMap.saveMapBin("compacted_map2.map");
return 0;
}
...@@ -80,7 +80,7 @@ typename PFP::REAL totalArea(typename PFP::MAP& map, const VertexAttribute<typen ...@@ -80,7 +80,7 @@ typename PFP::REAL totalArea(typename PFP::MAP& map, const VertexAttribute<typen
{ {
area += convexFaceArea<PFP>(map, f, position); area += convexFaceArea<PFP>(map, f, position);
} }
,false,thread); ,AUTO,thread);
return area ; return area ;
} }
......
...@@ -231,7 +231,7 @@ public: ...@@ -231,7 +231,7 @@ public:
unsigned int begin() const; unsigned int begin() const;
/** /**
* return the index of the last line of the container * return the index after the last line of the container
*/ */
unsigned int end() const; unsigned int end() const;
...@@ -249,7 +249,7 @@ public: ...@@ -249,7 +249,7 @@ public:
unsigned int realBegin() const; unsigned int realBegin() const;
/** /**
* return the index of the last line of the container * return the index after the last line of the container
*/ */
unsigned int realEnd() const; unsigned int realEnd() const;
...@@ -260,6 +260,22 @@ public: ...@@ -260,6 +260,22 @@ public:
void realNext(unsigned int &it) const; void realNext(unsigned int &it) const;
/**
* return the index of the last line of the container
*/
unsigned int realRBegin() const;
/**
* return the index before the first line of the container
*/
unsigned int realREnd() const;
/**
* get the index of the line before "it" in the container
* MUST BE USED INSTEAD OF ++ !
*/
void realRNext(unsigned int &it) const;
/************************************** /**************************************
* INFO ABOUT ATTRIBUTES * * INFO ABOUT ATTRIBUTES *
**************************************/ **************************************/
...@@ -321,6 +337,13 @@ public: ...@@ -321,6 +337,13 @@ public:
*/ */
void compact(std::vector<unsigned int>& mapOldNew); void compact(std::vector<unsigned int>& mapOldNew);
/**
* Test the fragmentation of container,
* in fact just size/max_size
* @return 1 if full filled - 0 is lots of holes
*/
inline float fragmentation();
/************************************** /**************************************
* LINES MANAGEMENT * * LINES MANAGEMENT *
**************************************/ **************************************/
......
...@@ -224,7 +224,12 @@ inline unsigned int AttributeContainer::memorySize() const ...@@ -224,7 +224,12 @@ inline unsigned int AttributeContainer::memorySize() const
inline bool AttributeContainer::used(unsigned int index) const inline bool AttributeContainer::used(unsigned int index) const
{ {
return m_holesBlocks[index / _BLOCKSIZE_]->used(index % _BLOCKSIZE_); return m_holesBlocks[index / _BLOCKSIZE_]->used(index % _BLOCKSIZE_) != 0;
}
inline float AttributeContainer::fragmentation()
{
return float(m_size) / float(m_maxSize);
} }
/************************************** /**************************************
...@@ -295,6 +300,31 @@ inline void AttributeContainer::realNext(unsigned int &it) const ...@@ -295,6 +300,31 @@ inline void AttributeContainer::realNext(unsigned int &it) const
} while ((it < m_maxSize) && (!used(it))); } while ((it < m_maxSize) && (!used(it)));
} }
inline unsigned int AttributeContainer::realRBegin() const
{
unsigned int it = m_maxSize-1;
while ((it != 0xffffffff) && (!used(it)))
--it;
return it;
}
inline unsigned int AttributeContainer::realREnd() const
{
return 0xffffffff; // -1
}
inline void AttributeContainer::realRNext(unsigned int &it) const
{
do
{
--it;
} while ((it !=0xffffffff) && (!used(it)));
}
/************************************** /**************************************
* LINES MANAGEMENT * * LINES MANAGEMENT *
**************************************/ **************************************/
......
...@@ -128,6 +128,14 @@ public: ...@@ -128,6 +128,14 @@ public:
*/ */
bool compressFree(); bool compressFree();
inline void compressFull(unsigned int nb)
{
m_nbfree = 0;
m_nbref = nb;
m_nb = nb;
}
/** /**
* clear the container of free block * clear the container of free block
*/ */
......
...@@ -430,8 +430,17 @@ protected: ...@@ -430,8 +430,17 @@ protected:
public: public:
/** /**
* compact the map * compact the map
* @warning the quickTraversals needs to be updated
*/ */
void compact() ; void compact(bool topoOnly = false) ;
/**
* test if containers are fragmented
* ~1.0 no need to compact
* ~0.0 need to compact
*/
inline float fragmentation(unsigned int orbit);
/** /**
* @brief dump all attributes of map in CSV format (; separated columns) * @brief dump all attributes of map in CSV format (; separated columns)
......
...@@ -322,4 +322,11 @@ inline AttributeMultiVector<Dart>* GenericMap::getRelation(const std::string& na ...@@ -322,4 +322,11 @@ inline AttributeMultiVector<Dart>* GenericMap::getRelation(const std::string& na
return amv ; return amv ;
} }
inline float GenericMap::fragmentation(unsigned int orbit)
{
if (isOrbitEmbedded(orbit))
return m_attribs[orbit].fragmentation();
return 1.0f;
}
} //namespace CGoGN } //namespace CGoGN
...@@ -103,7 +103,7 @@ protected: ...@@ -103,7 +103,7 @@ protected:
template <int I> template <int I>
inline void permutationUnsew(Dart d); inline void permutationUnsew(Dart d);
inline virtual void compactTopo(); virtual void compactTopo();
/**************************************** /****************************************
* DARTS TRAVERSALS * * DARTS TRAVERSALS *
......
...@@ -186,33 +186,6 @@ inline void MapMono::permutationUnsew(Dart d) ...@@ -186,33 +186,6 @@ inline void MapMono::permutationUnsew(Dart d)
(*m_permutation_inv[I])[e.index] = e ; (*m_permutation_inv[I])[e.index] = e ;
} }
inline void MapMono::compactTopo()
{
std::vector<unsigned int> oldnew;
m_attribs[DART].compact(oldnew);
for (unsigned int i = m_attribs[DART].begin(); i != m_attribs[DART].end(); m_attribs[DART].next(i))
{
for (unsigned int j = 0; j < m_permutation.size(); ++j)
{
Dart d = (*m_permutation[j])[i];
if (d.index != oldnew[d.index])
(*m_permutation[j])[i] = Dart(oldnew[d.index]);
}
for (unsigned int j = 0; j < m_permutation_inv.size(); ++j)
{
Dart d = (*m_permutation_inv[j])[i];
if (d.index != oldnew[d.index])
(*m_permutation_inv[j])[i] = Dart(oldnew[d.index]);
}
for (unsigned int j = 0; j < m_involution.size(); ++j)
{
Dart d = (*m_involution[j])[i];
if (d.index != oldnew[d.index])
(*m_involution[j])[i] = Dart(oldnew[d.index]);
}
}
}
/**************************************** /****************************************
* DARTS TRAVERSALS * * DARTS TRAVERSALS *
......
...@@ -165,7 +165,7 @@ protected: ...@@ -165,7 +165,7 @@ protected:
template <int I> template <int I>
inline void permutationUnsew(Dart d); inline void permutationUnsew(Dart d);
inline virtual void compactTopo(); virtual void compactTopo();
/**************************************** /****************************************
* MR CONTAINER MANAGEMENT * * MR CONTAINER MANAGEMENT *
......
...@@ -297,48 +297,6 @@ inline void MapMulti::permutationUnsew(Dart d) ...@@ -297,48 +297,6 @@ inline void MapMulti::permutationUnsew(Dart d)
(*m_permutation_inv[I])[e_index] = e ; (*m_permutation_inv[I])[e_index] = e ;
} }
inline void MapMulti::compactTopo()
{
std::vector<unsigned int> oldnewMR;
m_mrattribs.compact(oldnewMR);
std::vector<unsigned int> oldnew;
m_attribs[DART].compact(oldnew);
unsigned int nbl = m_mrDarts.size();
for (unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i))
{
for (unsigned int level = 0; level < nbl; ++level)
{
unsigned int& d = m_mrDarts[level]->operator[](i);
if (d != oldnew[d])
d = oldnew[d];
}
}
for (unsigned int i = m_attribs[DART].begin(); i != m_attribs[DART].end(); m_attribs[DART].next(i))
{
for (unsigned int j = 0; j < m_permutation.size(); ++j)
{
Dart d = (*m_permutation[j])[i];
if (d.index != oldnewMR[d.index])
(*m_permutation[j])[i] = Dart(oldnewMR[d.index]);
}
for (unsigned int j = 0; j < m_permutation_inv.size(); ++j)
{
Dart d = (*m_permutation_inv[j])[i];
if (d.index != oldnewMR[d.index])
(*m_permutation_inv[j])[i] = Dart(oldnewMR[d.index]);
}
for (unsigned int j = 0; j < m_involution.size(); ++j)
{
Dart d = (*m_involution[j])[i];
if (d.index != oldnewMR[d.index])
(*m_involution[j])[i] = Dart(oldnewMR[d.index]);
}
}
}
/**************************************** /****************************************
* MR CONTAINER MANAGEMENT * * MR CONTAINER MANAGEMENT *
****************************************/ ****************************************/
......
...@@ -213,100 +213,78 @@ void AttributeContainer::clear(bool removeAttrib) ...@@ -213,100 +213,78 @@ void AttributeContainer::clear(bool removeAttrib)
void AttributeContainer::compact(std::vector<unsigned int>& mapOldNew) void AttributeContainer::compact(std::vector<unsigned int>& mapOldNew)
{ {
unsigned int nbe = _BLOCKSIZE_ * m_holesBlocks.size(); mapOldNew.clear();
mapOldNew.resize(realEnd(),0xffffffff);
unsigned int nbb = m_holesBlocks.size() - 1; //VERSION THAT PRESERVE ORDER OF ELEMENTS ?
while ((m_holesBlocks[nbb])->empty()) // unsigned int down = 0;
{ // for (unsigned int occup = realBegin(); occup != realEnd(); next(occup))
--nbb; // {
nbe -= _BLOCKSIZE_; // mapOldNew[occup] = down;
} // copyLine(down,occup);
++nbb; // // copy ref counter
// setNbRefs(down,getNbRefs(occup));
// down++;
// }
mapOldNew.clear(); // fill the holes with data & create the map Old->New
mapOldNew.reserve(nbe); unsigned int up = realRBegin();
unsigned int down = 0;
// now get the holes while (down < up)
unsigned int baseAdr = 0;
for (unsigned int i = 0; i < nbb; ++i)
{ {
HoleBlockRef* block = m_holesBlocks[i]; if (!used(down))
for (unsigned int j = 0; j < _BLOCKSIZE_; ++j)
{ {
if (j < block->sizeTable()) mapOldNew[up] = down;
{ // copy data
if (block->used(j)) copyLine(down,up);
mapOldNew.push_back(baseAdr); // copy ref counter
else setNbRefs(down,getNbRefs(up));
mapOldNew.push_back(0xffffffff); // set next element to catch for hole filling
} realRNext(up);
else
mapOldNew.push_back(0xffffffff);
baseAdr++;
} }
down++;
} }
unsigned int last = mapOldNew.size() - 1; // end of table = nb elements
m_maxSize = m_size;
for (unsigned int i = 0 ; i < last; ++i) // no more blocks empty
{ m_tableBlocksEmpty.clear();
unsigned int val = mapOldNew[i];
if (val == 0xffffffff)
{
// first find last element
while (mapOldNew[last] == 0xffffffff)
--last;
// store it in the hole
// find the blocks and indices
unsigned int bi = i / _BLOCKSIZE_;
unsigned int ib = i % _BLOCKSIZE_;
unsigned int bj = last / _BLOCKSIZE_;
unsigned int jb = last % _BLOCKSIZE_;
//overwrite attributes
for(unsigned int j = 0; j < m_tableAttribs.size(); ++j)
{
if (m_tableAttribs[j] != NULL)
m_tableAttribs[j]->overwrite(bj, jb, bi, ib);
}
// overwrite emptyLine with last line in free blocks // only the last block has free indices
m_holesBlocks[bi]->overwrite(ib, m_holesBlocks[bj], jb); m_tableBlocksWithFree.clear();
// set the map value // compute nb block full
mapOldNew[last] = i; unsigned int nbb = m_size / _BLOCKSIZE_;
--last; // update holeblock
} for (unsigned int i=0; i<nbb; ++i)
} m_holesBlocks[i]->compressFull(_BLOCKSIZE_);
for (int i = m_holesBlocks.size() - 1; i >= 0; --i) //update last holeblock
unsigned int nbe = m_size % _BLOCKSIZE_;
if (nbe != 0)
{ {
HoleBlockRef* ptr = m_holesBlocks[i]; m_holesBlocks[nbb]->compressFull(nbe);
if (ptr->compressFree()) m_tableBlocksWithFree.push_back(nbb);
{ nbb++;
delete ptr;
m_holesBlocks.pop_back();
}
} }
// maj de la table de block libre // free memory and resize
m_tableBlocksWithFree.clear(); for (int i = m_holesBlocks.size() - 1; i > nbb; --i)
HoleBlockRef* block = m_holesBlocks.back(); delete m_holesBlocks[i];
if (!block->full()) m_holesBlocks.resize(nbb);
m_tableBlocksWithFree.push_back(m_holesBlocks.size() - 1);
// detruit les blocks de donnees inutiles // release unused data memory
for(unsigned int j = 0; j < m_tableAttribs.size(); ++j) for(unsigned int j = 0; j < m_tableAttribs.size(); ++j)
{ {
if (m_tableAttribs[j] != NULL) if (m_tableAttribs[j] != NULL)
m_tableAttribs[j]->setNbBlocks(m_holesBlocks.size()); m_tableAttribs[j]->setNbBlocks(m_holesBlocks.size());
} }
m_maxSize = (m_holesBlocks.back())->sizeTable() + (m_holesBlocks.size() - 1) * _BLOCKSIZE_;
} }
/************************************** /**************************************
* LINES MANAGEMENT * * LINES MANAGEMENT *
**************************************/ **************************************/
......
...@@ -424,44 +424,33 @@ void GenericMap::dumpAttributesAndMarkers() ...@@ -424,44 +424,33 @@ void GenericMap::dumpAttributesAndMarkers()
// } // }
} }
void GenericMap::compact()
void GenericMap::compact(bool topoOnly)
{ {
// compact embedding attribs compactTopo();
std::vector< std::vector<unsigned int>* > oldnews;
oldnews.resize(NB_ORBITS); if (topoOnly)
return;
std::vector