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)
project(examples)
SET(CMAKE_BUILD_TYPE Release)
#SET(CMAKE_BUILD_TYPE Debug)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOTOPOWARNING")
......@@ -26,3 +29,6 @@ target_link_libraries( bench_trav ${CGoGN_LIBS_R} ${CGoGN_EXT_LIBS} )
add_executable(bench_remesh bench_remesh.cpp )
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
add_executable( movefrom ./movefrom.cpp)
target_link_libraries( movefrom
${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
{
area += convexFaceArea<PFP>(map, f, position);
}
,false,thread);
,AUTO,thread);
return area ;
}
......
......@@ -231,7 +231,7 @@ public:
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;
......@@ -249,7 +249,7 @@ public:
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;
......@@ -260,6 +260,22 @@ public:
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 *
**************************************/
......@@ -321,6 +337,13 @@ public:
*/
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 *
**************************************/
......
......@@ -224,7 +224,12 @@ inline unsigned int AttributeContainer::memorySize() 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
} 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 *
**************************************/
......
......@@ -128,6 +128,14 @@ public:
*/
bool compressFree();
inline void compressFull(unsigned int nb)
{
m_nbfree = 0;
m_nbref = nb;
m_nb = nb;
}
/**
* clear the container of free block
*/
......
......@@ -430,8 +430,17 @@ protected:
public:
/**
* 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)
......
......@@ -322,4 +322,11 @@ inline AttributeMultiVector<Dart>* GenericMap::getRelation(const std::string& na
return amv ;
}
inline float GenericMap::fragmentation(unsigned int orbit)
{
if (isOrbitEmbedded(orbit))
return m_attribs[orbit].fragmentation();
return 1.0f;
}
} //namespace CGoGN
......@@ -103,7 +103,7 @@ protected:
template <int I>
inline void permutationUnsew(Dart d);
inline virtual void compactTopo();
virtual void compactTopo();
/****************************************
* DARTS TRAVERSALS *
......
......@@ -186,33 +186,6 @@ inline void MapMono::permutationUnsew(Dart d)
(*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 *
......
......@@ -165,7 +165,7 @@ protected:
template <int I>
inline void permutationUnsew(Dart d);
inline virtual void compactTopo();
virtual void compactTopo();
/****************************************
* MR CONTAINER MANAGEMENT *
......
......@@ -297,48 +297,6 @@ inline void MapMulti::permutationUnsew(Dart d)
(*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 *
****************************************/
......
......@@ -213,100 +213,78 @@ void AttributeContainer::clear(bool removeAttrib)
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;
while ((m_holesBlocks[nbb])->empty())
{
--nbb;
nbe -= _BLOCKSIZE_;
}
++nbb;
//VERSION THAT PRESERVE ORDER OF ELEMENTS ?
// unsigned int down = 0;
// for (unsigned int occup = realBegin(); occup != realEnd(); next(occup))
// {
// mapOldNew[occup] = down;
// copyLine(down,occup);
// // copy ref counter
// setNbRefs(down,getNbRefs(occup));
// down++;
// }
mapOldNew.clear();
mapOldNew.reserve(nbe);
// fill the holes with data & create the map Old->New
unsigned int up = realRBegin();
unsigned int down = 0;
// now get the holes
unsigned int baseAdr = 0;
for (unsigned int i = 0; i < nbb; ++i)
while (down < up)
{
HoleBlockRef* block = m_holesBlocks[i];
for (unsigned int j = 0; j < _BLOCKSIZE_; ++j)
if (!used(down))
{
if (j < block->sizeTable())
{
if (block->used(j))
mapOldNew.push_back(baseAdr);
else
mapOldNew.push_back(0xffffffff);
}
else
mapOldNew.push_back(0xffffffff);
baseAdr++;
mapOldNew[up] = down;
// copy data
copyLine(down,up);
// copy ref counter
setNbRefs(down,getNbRefs(up));
// set next element to catch for hole filling
realRNext(up);
}
down++;
}
unsigned int last = mapOldNew.size() - 1;
// end of table = nb elements
m_maxSize = m_size;
for (unsigned int i = 0 ; i < last; ++i)
{
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);
}
// no more blocks empty
m_tableBlocksEmpty.clear();
// overwrite emptyLine with last line in free blocks
m_holesBlocks[bi]->overwrite(ib, m_holesBlocks[bj], jb);
// only the last block has free indices
m_tableBlocksWithFree.clear();
// set the map value
mapOldNew[last] = i;
--last;
}
}
// compute nb block full
unsigned int nbb = m_size / _BLOCKSIZE_;
// 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];
if (ptr->compressFree())
{
delete ptr;
m_holesBlocks.pop_back();
}
m_holesBlocks[nbb]->compressFull(nbe);
m_tableBlocksWithFree.push_back(nbb);
nbb++;
}
// maj de la table de block libre
m_tableBlocksWithFree.clear();
HoleBlockRef* block = m_holesBlocks.back();
if (!block->full())
m_tableBlocksWithFree.push_back(m_holesBlocks.size() - 1);
// free memory and resize
for (int i = m_holesBlocks.size() - 1; i > nbb; --i)
delete m_holesBlocks[i];
m_holesBlocks.resize(nbb);
// detruit les blocks de donnees inutiles
// release unused data memory
for(unsigned int j = 0; j < m_tableAttribs.size(); ++j)
{
if (m_tableAttribs[j] != NULL)
m_tableAttribs[j]->setNbBlocks(m_holesBlocks.size());
}
m_maxSize = (m_holesBlocks.back())->sizeTable() + (m_holesBlocks.size() - 1) * _BLOCKSIZE_;
}
/**************************************
* LINES MANAGEMENT *
**************************************/
......
......@@ -424,44 +424,33 @@ void GenericMap::dumpAttributesAndMarkers()
// }
}
void GenericMap::compact()
void GenericMap::compact(bool topoOnly)
{
// compact embedding attribs
std::vector< std::vector<unsigned int>* > oldnews;
oldnews.resize(NB_ORBITS);
compactTopo();
if (topoOnly)
return;
std::vector<unsigned int> oldnew;
for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
{
if ((orbit != DART) && (isOrbitEmbedded(orbit)))
{
oldnews[orbit] = new std::vector<unsigned int>;
m_attribs[orbit].compact(*(oldnews[orbit]));
}
}
// update embedding indices of topo
for (unsigned int i = m_attribs[DART].begin(); i != m_attribs[DART].end(); m_attribs[DART].next(i))
{
for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
{
if ((orbit != DART) && (isOrbitEmbedded(orbit)))
m_attribs[orbit].compact(oldnew);
for (unsigned int i = m_attribs[DART].begin(); i != m_attribs[DART].end(); m_attribs[DART].next(i))
{
unsigned int& idx = m_embeddings[orbit]->operator[](i);
unsigned int jdx = oldnews[orbit]->operator[](idx);
if ((jdx != 0xffffffff) && (jdx != idx))
unsigned int jdx = oldnew[idx];
if (jdx != 0xffffffff)
idx = jdx;
}
}
}
// delete allocated vectors
for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
if ((orbit != DART) && (isOrbitEmbedded(orbit)))
delete[] oldnews[orbit];
// compact topo (depends on map implementation)
compactTopo();
}
void GenericMap::dumpCSV() const
{
for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
......
......@@ -190,4 +190,35 @@ void MapMono::restore_topo_shortcuts()
}
}
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 (oldnew[d.index] != AttributeContainer::UNKNOWN)
(*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 (oldnew[d.index] != AttributeContainer::UNKNOWN)
(*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 (oldnew[d.index] != AttributeContainer::UNKNOWN)
(*m_involution[j])[i] = Dart(oldnew[d.index]);
}
}
}
} //namespace CGoGN
......@@ -416,4 +416,49 @@ void MapMulti::restore_topo_shortcuts()
}
}
// TODO A VERIFIER ET A TESTER
void MapMulti::compactTopo()
{
std::vector<unsigned int> oldnewMR;
m_mrattribs.compact(oldnewMR);
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 (oldnewMR[d] != AttributeContainer::UNKNOWN)
d = oldnewMR[d];
}
}
m_attribs[DART].compact(oldnewMR);
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 (oldnewMR[d.index] != AttributeContainer::UNKNOWN)
(*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 (oldnewMR[d.index] != AttributeContainer::UNKNOWN)
(*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 (oldnewMR[d.index] != AttributeContainer::UNKNOWN)
(*m_involution[j])[i] = Dart(oldnewMR[d.index]);
}
}
}