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"
using namespace std;
template <typename CubicalComplex>
struct DiagonalPriority {
typedef typename CubicalComplex::CellMapIterator CellMapIterator;
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 ) );
}
const CubicalComplex& myComplex;
};
int main(
int argc,
char** argv )
{
typedef std::map<Cell, CubicalCellData>
Map;
typedef CubicalComplex< KSpace, Map >
CC;
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);
typedef Viewer3D<Space, KSpace> MyViewer;
{
viewer.show();
for ( Dimension d = 0; d <= 3; ++d )
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();
for ( Dimension d = 0; d <= 3; ++d )
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();
}
}
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.
boost::uint64_t uint64_t
unsigned 64-bit integer.
int main(int argc, char **argv)
std::unordered_map< Cell, CubicalCellData > Map
CubicalComplex< KSpace, Map > CC
CC::CellMapConstIterator CellMapConstIterator
PointVector< 3, double > RealPoint