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