DGtal  0.9.3beta
testUmbrellaComputer.cpp
1 
30 #include <iostream>
32 #include <fstream>
33 #include "DGtal/base/Common.h"
34 #include "DGtal/shapes/implicit/ImplicitBall.h"
35 #include "DGtal/shapes/GaussDigitizer.h"
36 #include "DGtal/topology/LightImplicitDigitalSurface.h"
37 #include "DGtal/topology/DigitalSurface.h"
38 #include "DGtal/topology/UmbrellaComputer.h"
40 
41 using namespace std;
42 using namespace DGtal;
43 
45 // Functions for testing class UmbrellaComputer.
47 
48 bool testUmbrellaComputer()
49 {
50  using namespace Z3i;
51 
53  typedef ImplicitBall<Space> EuclideanShape;
57  typedef Boundary::SurfelConstIterator ConstIterator;
58  //typedef Boundary::Tracker Tracker;
59  typedef Boundary::Surfel Surfel;
60  typedef Boundary::DigitalSurfaceTracker DigitalSurfaceTracker;
62  typedef UmbrellaComputer<DigitalSurfaceTracker> MyUmbrellaComputer;
63 
64  unsigned int nbok = 0;
65  unsigned int nb = 0;
66  trace.beginBlock ( "Testing block ... UmbrellaComputer" );
67  // Creating shape
68  Point c( 0, 0, 0 );
69  EuclideanShape ball( c, 2 ); // ball r=4
70  DigitalShape shape;
71  shape.attach( ball );
72  shape.init( RealPoint( -10.0, -10.0, -10.0 ),
73  RealPoint( 10.0, 10.0, 10.0 ), 1.0 );
74  // Creating cellular grid space around.
75  Domain domain = shape.getDomain();
76  KSpace K;
77  nbok += K.init( domain.lowerBound(), domain.upperBound(), true ) ? 1 : 0;
78  nb++;
79  trace.info() << "(" << nbok << "/" << nb << ") "
80  << "K.init() is ok" << std::endl;
81  // Find start surfel on surface.
82  Surfel bel = Surfaces<KSpace>::findABel( K, shape, 10000 );
83  // Define surface container then surface itself.
84  Boundary boundary( K, // cellular space
85  shape, // point predicate
86  SurfelAdjacency<KSpace::dimension>( true ), // adjacency
87  bel // starting surfel
88  );
89  MyDigitalSurface digSurf( boundary ); // boundary is cloned
90 
91  // Get tracker on surface.
92  DigitalSurfaceTracker* ptrTracker = boundary.newTracker( bel );
93  MyUmbrellaComputer umbrella;
94  KSpace::DirIterator dirIt = K.sDirs( bel );
95  Dimension k = *dirIt;
96  Dimension j = *(++dirIt);
97  trace.beginBlock ( "Testing block ... forward umbrella" );
98  umbrella.init( *ptrTracker, k, true, j );
99  unsigned int nb_forward = 0;
100  Surfel init_bel = bel;
101  do {
102  Point x = K.sKCoords( bel );
103  trace.info() << x << std::endl;
104  umbrella.next();
105  ++nb_forward;
106  bel = umbrella.surfel();
107  } while ( bel != init_bel );
108  trace.endBlock();
109  trace.beginBlock ( "Testing block ... backward umbrella" );
110  unsigned int nb_backward = 0;
111  do {
112  Point x = K.sKCoords( bel );
113  trace.info() << x << std::endl;
114  umbrella.previous();
115  ++nb_backward;
116  bel = umbrella.surfel();
117  } while ( bel != init_bel );
118  nb++, nbok += nb_forward == nb_backward ? 1 : 0;
119 
120  trace.info() << "(" << nbok << "/" << nb << ") "
121  << " nb_forward(" << nb_forward
122  << ") == nb_backward(" << nb_backward << ")"
123  << std::endl;
124  trace.endBlock();
125  unsigned int nbsurfels = 0;
126  for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
127  it != it_end; ++it )
128  {
129  ++nbsurfels;
130  }
131  trace.info() << nbsurfels << " surfels found." << std::endl;
132 
133  trace.endBlock();
134 
135  delete ptrTracker;
136  return nbok == nb;
137 }
138 
139 bool testCombinatorialSurface()
140 {
141  using namespace Z3i;
142 
143  typedef Space::RealPoint RealPoint;
144  typedef ImplicitBall<Space> EuclideanShape;
145  typedef GaussDigitizer<Space,EuclideanShape> DigitalShape;
148  typedef Boundary::SurfelConstIterator ConstIterator;
149  //typedef Boundary::Tracker Tracker;
150  typedef Boundary::Surfel Surfel;
151  //typedef Boundary::DigitalSurfaceTracker DigitalSurfaceTracker;
152  typedef DigitalSurface<Boundary> MyDigitalSurface;
153  //typedef UmbrellaComputer<DigitalSurfaceTracker> MyUmbrellaComputer;
154  typedef DigitalSurface<Boundary>::Face Face;
155  typedef DigitalSurface<Boundary>::Arc Arc;
156  typedef DigitalSurface<Boundary>::Vertex Vertex;
157 
158  unsigned int nbok = 0;
159  unsigned int nb = 0;
160  trace.beginBlock ( "Testing block ... Combinatorial surface" );
161  // Creating shape
162  Point c( 0, 0, 0 );
163  EuclideanShape ball( c, 8 ); // ball r=4
164  DigitalShape shape;
165  shape.attach( ball );
166  shape.init( RealPoint( -2.0, -3.0, -10.0 ),
167  RealPoint( 10.0, 10.0, 10.0 ), 1.0 );
168  // Creating cellular grid space around.
169  Domain domain = shape.getDomain();
170  KSpace K;
171  nbok += K.init( domain.lowerBound(), domain.upperBound(), true ) ? 1 : 0;
172  nb++;
173  trace.info() << "(" << nbok << "/" << nb << ") "
174  << "K.init() is ok" << std::endl;
175  // Find start surfel on surface.
176  Surfel bel = Surfaces<KSpace>::findABel( K, shape, 10000 );
177  // Define surface container then surface itself.
178  Boundary boundary( K, // cellular space
179  shape, // point predicate
180  SurfelAdjacency<KSpace::dimension>( true ), // adjacency
181  bel // starting surfel
182  );
183  MyDigitalSurface digSurf( boundary ); // boundary is cloned
184 
185 
186  trace.beginBlock ( "Testing block ... Digital surface faces." );
187  MyDigitalSurface::FaceSet all_faces = digSurf.allFaces();
188  for ( MyDigitalSurface::FaceSet::const_iterator it = all_faces.begin(),
189  it_end = all_faces.end(); it != it_end; ++it )
190  {
191  std::cerr << " face=" << K.sKCoords( digSurf.pivot( *it ) ) << ":";
192  std::cerr << "(" << it->nbVertices << ")" << (it->isClosed() ? "C": "O");
193  MyDigitalSurface::VertexRange vtx = digSurf.verticesAroundFace( *it );
194  for ( unsigned int i = 0; i < vtx.size(); ++i )
195  {
196  std::cerr << " " << K.sKCoords( vtx[ i ] );
197  }
198  std::cerr << std::endl;
199  }
200  trace.endBlock();
201 
202  // Checks that vertices of a face are in the same order as the
203  // incident arcs.
204  trace.beginBlock( "Testing block ...Check order faces/arcs" );
205  unsigned int nbvtcs = 0;
206  unsigned int nbarcs = 0;
207  unsigned int nbfaces = 0;
208  for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
209  it != it_end; ++it, ++nbvtcs )
210  {
211  const Vertex & vtx = *it;
212  MyDigitalSurface::ArcRange arcs = digSurf.outArcs( vtx );
213  for ( unsigned int i = 0; i < arcs.size(); ++i, ++nbarcs )
214  {
215  const Arc & arc = arcs[ i ];
217  faces = digSurf.facesAroundArc( arc );
218  for ( unsigned int j = 0; j < faces.size(); ++j, ++nbfaces )
219  {
220  const Face & face = faces[ j ];
221  // search vertex in face.
223  vertices = digSurf.verticesAroundFace( face );
224  unsigned int k = 0;
225  while ( ( k < vertices.size() ) && ( vertices[ k ] != vtx ) )
226  ++k;
227  ++nb;
228  if ( k == vertices.size() )
229  trace.info() << "Error at vertex " << vtx
230  << ". Vertex not found in incident face."
231  << std::endl;
232  else ++nbok;
233  ++nb;
234  if ( digSurf.head( arc ) != vertices[ (k+1) % vertices.size() ] )
235  trace.info() << "Error at vertex " << vtx
236  << ". Arc is not in incident face."
237  << std::endl;
238  else ++nbok;
239  }
240  }
241  }
242  trace.info() << "(" << nbok << "/" << nb << ") "
243  << "Tested nbvtcs=" << nbvtcs
244  << " nbarcs=" << nbarcs
245  << " nbfaces=" << nbfaces
246  << std::endl;
247  trace.endBlock();
248 
249  trace.beginBlock( "Testing block ... export as OFF: ex-digital-surface.off" );
250  ofstream fout( "ex-digital-surface.off" );
251  if ( fout.good() )
252  digSurf.exportSurfaceAs3DOFF( fout );
253  fout.close();
254  trace.endBlock();
255 
256 
257 
258  unsigned int nbsurfels = 0;
259  for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
260  it != it_end; ++it )
261  {
262  ++nbsurfels;
263  }
264  trace.info() << nbsurfels << " surfels found." << std::endl;
265  trace.endBlock();
266 
267  return nbok == nb;
268 }
269 
270 
272 // Standard services - public :
273 
274 int main( int argc, char** argv )
275 {
276  trace.beginBlock ( "Testing class UmbrellaComputer" );
277  trace.info() << "Args:";
278  for ( int i = 0; i < argc; ++i )
279  trace.info() << " " << argv[ i ];
280  trace.info() << endl;
281 
282  bool res = testUmbrellaComputer()
283  && testCombinatorialSurface(); // && ... other tests
284  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
285  trace.endBlock();
286  return res ? 0 : 1;
287 }
288 // //
void beginBlock(const std::string &keyword="")
std::vector< Vertex > VertexRange
The range of vertices is defined as a vector.
std::vector< Arc > ArcRange
The range of arcs is defined as a vector.
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as the boundary of an impl...
Trace trace
Definition: Common.h:137
Aim: A utility class for constructing surfaces (i.e. set of (n-1)-cells).
Definition: Surfaces.h:78
DGtal::uint32_t Dimension
Definition: Common.h:120
KhalimskySpaceND< 2, Integer > KSpace
Definition: StdDefs.h:77
STL namespace.
double endBlock()
Aim: Represents a set of n-1-cells in a nD space, together with adjacency relation between these cell...
std::set< Face > FaceSet
The set of faces is defined as set.
Aim: Implements basic operations that will be used in Point and Vector classes.
Definition: PointVector.h:141
void attach(const EuclideanShape &shape)
void init(const RealPoint &xLow, const RealPoint &xUp, typename RealVector::Component gridStep)
std::vector< Face > FaceRange
The range of faces is defined as a vector.
std::ostream & emphase()
Aim: A class for computing the Gauss digitization of some Euclidean shape, i.e. its intersection with...
Domain getDomain() const
Aim: model of CEuclideanOrientedShape and CEuclideanBoundedShape concepts to create a ball in nD...
Definition: ImplicitBall.h:64
Surfel Vertex
Defines the type for a vertex.
const Point & upperBound() const
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & info()
std::pair< typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_iterator, typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_iterator > vertices(const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
Space::RealPoint RealPoint
Definition: StdDefs.h:97
const Point & lowerBound() const