Collapse of 3D cubical complex that is made of 20x20x20 voxels with their faces. Fixed cells were marked in red. It was the eight vertices, plus all border linels on the upper faces plus a random linel within the complex. The priority was the distance to the diagonal. Note that the Euler characteristic of the complex is unchanged after collapse.
#include <iostream>
#include <map>
#include "DGtal/base/Common.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/io/DrawWithDisplay3DModifier.h"
#include "DGtal/io/viewers/Viewer3D.h"
#include "DGtal/topology/KhalimskySpaceND.h"
#include "DGtal/topology/CubicalComplex.h"
template <typename CubicalComplex>
struct DiagonalPriority {
DiagonalPriority(
const CubicalComplex& complex ) : myComplex( complex ) {}
bool operator()( const CellMapIterator& it1, const CellMapIterator& it2 ) const
{
Point k1 = myComplex.
space().uKCoords( it1->first );
Point k2 = myComplex.
space().uKCoords( it2->first );
double d1 = Point::diagonal( 1 ).dot( k1 ) / sqrt( (double) KSpace::dimension );
double d2 = Point::diagonal( 1 ).dot( k2 ) / sqrt( (double) KSpace::dimension );;
RealPoint v1( k1[ 0 ] - d1 * k1[ 0 ], k1[ 1 ] - d1 * k1[ 1 ], k1[ 2 ] - d1 * k1[ 2 ] );
RealPoint v2( k2[ 0 ] - d2 * k2[ 0 ], k2[ 1 ] - d2 * k2[ 1 ], k2[ 2 ] - d2 * k2[ 2 ] );
double n1 = v1.dot( v1 );
double n2 = v2.dot( v2 );
return ( n1 < n2 ) || ( ( n1 == n2 ) && ( it1->first < it2->first ) );
}
};
int main(
int argc,
char** argv )
{
typedef std::map<Cell, CubicalCellData>
Map;
std::vector<Cell> S;
{
S.push_back(
K.uCell( k1 ) );
double d1 = Point::diagonal( 1 ).dot( k1 ) / (double) KSpace::dimension;
v1 -= d1 * RealPoint::diagonal( 1.0 );
double n1 = v1.norm();
bool fixed = ( ( x == 0 ) && ( y == 0 ) && ( z == 0 ) )
|| ( ( x == 0 ) && ( y == m ) && ( z == 0 ) )
|| ( ( x == m ) && ( y == 0 ) && ( z == 0 ) )
|| ( ( x == m ) && ( y == m ) && ( z == 0 ) )
|| ( ( x == m/3 ) && ( y == 2*m/3 ) && ( z == 2*m/3 ) )
|| ( ( x == 0 ) && ( y == 0 ) && ( z == m ) )
|| ( ( x == 0 ) && ( y == m ) && ( z == m ) )
|| ( ( x == m ) && ( y == 0 ) && ( z == m ) )
|| ( ( x == m ) && ( y == m ) && ( z == m ) )
|| ( ( x == 0 ) && ( y == m ) )
|| ( ( x == m ) && ( y == m ) )
|| ( ( z == 0 ) && ( y == m ) )
|| ( ( z == m ) && ( y == m ) );
complex.insertCell( S.back(),
fixed ? CC::FIXED
);
}
trace.
info() <<
"After close: " << complex << std::endl;
QApplication application(argc,argv);
{
viewer.show();
it != itE; ++it )
{
bool fixed = (it->second.data == CC::FIXED);
if ( fixed ) viewer.setFillColor( Color::Red );
else viewer.setFillColor( Color::White );
viewer << it->first;
}
viewer<< MyViewer::updateDisplay;
application.exec();
}
CC::DefaultCellMapIteratorPriority P;
= functions::collapse( complex, S.begin(), S.end(), P, true, true, true );
trace.
info() <<
"Collapse removed " << removed <<
" cells." << std::endl;
trace.
info() <<
"After collapse: " << complex << std::endl;
{
viewer.show();
it != itE; ++it )
{
bool fixed = (it->second.data == CC::FIXED);
if ( fixed ) viewer.setFillColor( Color::Red );
else viewer.setFillColor( Color::White );
viewer << it->first;
}
viewer<< MyViewer::updateDisplay;
return application.exec();
}
}
Aim: This class represents an arbitrary cubical complex living in some Khalimsky space....
const KSpace & space() const
TKSpace KSpace
Type of the cellular grid space.
KSpace::Cell Cell
Type for a cell in the space.
KSpace::Point Point
Type for a point in the digital space.
CellMap::iterator CellMapIterator
Iterator for visiting type CellMap.
void beginBlock(const std::string &keyword="")
Point::Coordinate Integer
Z3i this namespace gathers the standard of types for 3D imagery.
DGtal is the top-level namespace which contains all DGtal functions and types.
boost::uint32_t uint32_t
unsigned 32-bit integer.
DGtal::uint32_t Dimension
boost::uint64_t uint64_t
unsigned 64-bit integer.
std::unordered_map< Cell, CubicalCellData > Map
CubicalComplex< KSpace, Map > CC
CC::CellMapConstIterator CellMapConstIterator
PointVector< 3, double > RealPoint