DGtal  0.9.2
Display3DFactory.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file Display3DFactory.ih
19  * @author Martial Tola <http://liris.cnrs.fr/martial.tola/>
20  * @date mercredi 21 septembre 2011
21  *
22  * @brief
23  *
24  * Implementation of inline methods defined in Display3DFactory.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 #include "DGtal/helpers/StdDefs.h"
30 #include "DGtal/images/ImageHelper.h"
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 // Implementation of inline methods //
34 
35 //
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // Implementation of inline functions and external operators //
40 
41 // DiscreteExteriorCalculus
42 template <typename Space, typename KSpace>
43 template <DGtal::Dimension dimEmbedded, DGtal::Dimension dimAmbient, typename TLinearAlgebraBackend, typename TInteger>
44 inline
45 void
46 DGtal::Display3DFactory<Space, KSpace>::draw(Display3D<Space, KSpace>& display, const DGtal::DiscreteExteriorCalculus<dimEmbedded, dimAmbient, TLinearAlgebraBackend, TInteger>& calculus)
47 {
48  BOOST_STATIC_ASSERT(( dimAmbient == 3 ));
49 
50  typedef DiscreteExteriorCalculus<dimEmbedded, dimAmbient, TLinearAlgebraBackend, TInteger> Calculus;
51  typedef typename Calculus::ConstIterator ConstIterator;
52  typedef typename Calculus::Cell Cell;
53  typedef typename Calculus::SCell SCell;
54  typedef typename Calculus::KSpace KSpace;
55 
56  display << DGtal::CustomColors3D(DGtal::Color::Black, DGtal::Color::White);
57 
58  for (ConstIterator ci=calculus.begin(), cie=calculus.end(); ci!=cie; ci++)
59  {
60  const Cell& cell = ci->first;
61  const bool& flipped = ci->second.flipped;
62  const SCell displayed_cell = calculus.myKSpace.signs(cell, flipped ? KSpace::NEG : KSpace::POS);
63 
64  display << displayed_cell;
65  }
66 }
67 // DiscreteExteriorCalculus
68 
69 // KForm
70 template <typename Space, typename KSpace>
71 template <typename TCalculus, DGtal::Order order, DGtal::Duality duality>
72 inline
73 void
74 DGtal::Display3DFactory<Space, KSpace>::draw(Display3D<Space, KSpace>& display, const DGtal::KForm<TCalculus, order, duality>& kform, double cmap_min, double cmap_max)
75 {
76  typedef typename TCalculus::Scalar Scalar;
77  typedef typename TCalculus::Index Index;
78 
79  if (cmap_min == 0 && cmap_max == 0)
80  {
81  bool first = true;
82  for (Index index=0; index<kform.myContainer.rows(); index++)
83  {
84  const Scalar value = kform.myContainer(index);
85  if (!std::isfinite(value)) continue;
86  if (first || cmap_min > value) cmap_min = value;
87  if (first || cmap_max < value) cmap_max = value;
88  first = false;
89  }
90  }
91 
92  if (cmap_min == cmap_max) cmap_max += 1;
93 
94  typedef typename DGtal::GradientColorMap<Scalar, DGtal::CMAP_JET> ColorMap;
95  const ColorMap color_map(cmap_min, cmap_max);
96 
97  drawWithColorMap(display, kform, color_map);
98 }
99 
100 template <typename Space, typename KSpace>
101 template <typename Calculus, DGtal::Order order, DGtal::Duality duality, typename ColorMap>
102 inline
103 void
104 DGtal::Display3DFactory<Space, KSpace>::drawWithColorMap(Display3D<Space, KSpace>& display, const DGtal::KForm<Calculus, order, duality>& kform, const ColorMap& colormap)
105 {
106  BOOST_STATIC_ASSERT(( Calculus::dimensionAmbient == 3 ));
107  ASSERT( kform.myCalculus );
108 
109  typedef typename Calculus::Scalar Scalar;
110  typedef typename Calculus::SCell SCell;
111  typedef typename Calculus::Index Index;
112 
113  for (Index index=0; index<kform.length(); index++)
114  {
115  const SCell displayed_cell = kform.getSCell(index);
116  const Scalar displayed_value = kform.myContainer(index);
117 
118  if (std::isfinite(displayed_value)) display << DGtal::CustomColors3D(DGtal::Color::Black, colormap(displayed_value) );
119  else continue;
120 
121  display << displayed_cell;
122  }
123 }
124 // KForm
125 
126 // VectorField
127 template <typename Space, typename KSpace>
128 template <typename Calculus, DGtal::Duality duality>
129 void
130 DGtal::Display3DFactory<Space, KSpace>::draw(Display3D<Space, KSpace>& display, const DGtal::VectorField<Calculus, duality>& vector_field, const double& scale, const double& epsilon, const DGtal::Color color)
131 {
132  BOOST_STATIC_ASSERT(( Calculus::dimensionAmbient == 3 ));
133  ASSERT( vector_field.myCalculus );
134 
135  typedef typename DGtal::VectorField<Calculus, duality>::Vector Vector;
136 
137  display << DGtal::CustomColors3D(DGtal::Color::Black, color);
138 
139  for (typename Calculus::Index index=0; index<vector_field.length(); index++)
140  {
141  const typename Calculus::SCell& cell = vector_field.getSCell(index);
142  const DGtal::Z3i::RealPoint origin = display.sCellEmbedder()(cell);
143 
144  Vector vector = vector_field.getVector(index);
145 
146  vector *= scale;
147  if (!std::isfinite(vector[0]) || !std::isfinite(vector[1]) || !std::isfinite(vector[2])) continue;
148  const typename Calculus::Scalar& norm = vector.norm();
149  if (norm <= epsilon) continue;
150  if (norm <= .5) vector *= .5/norm;
151 
152  display.addCone(origin+vector, origin);
153  }
154 }
155 // VectorField
156 
157 // SphericalAccumulator
158 template <typename Space, typename KSpace>
159 template <typename TV>
160 inline
161 void
162 DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
163  const DGtal::SphericalAccumulator<TV> & aAccumulator,
164  const typename DGtal::Z3i::RealVector &shift,
165  const double radius)
166 {
167  DGtal::Color saveFillColor = display.getFillColor();
168  typedef typename DGtal::SphericalAccumulator<TV>::Size Size;
169  typename DGtal::SphericalAccumulator<TV>::RealVector a,b,c,d;
170  Size i,j;
171  DGtal::int32_t m = 1, M=0;
172  for(typename DGtal::SphericalAccumulator<TV>::ConstIterator it = aAccumulator.begin(),
173  itend= aAccumulator.end(); it != itend; ++it)
174  {
175  aAccumulator.binCoordinates(it, i,j);
176  if (aAccumulator.isValidBin(i,j))
177  {
178  if (aAccumulator.count(i,j) > M) M=aAccumulator.count(i,j);
179  if (aAccumulator.count(i,j) < m) m=aAccumulator.count(i,j);
180  }
181  }
182  HueShadeColorMap<typename DGtal::SphericalAccumulator<TV>::Quantity> cmap(m,M+1);
183 
184  for(typename DGtal::SphericalAccumulator<TV>::ConstIterator it = aAccumulator.begin(),
185  itend= aAccumulator.end(); it != itend; ++it)
186  {
187  aAccumulator.binCoordinates(it, i,j);
188  if (aAccumulator.isValidBin(i,j))
189  {
190  aAccumulator.binCoordinates(it, i,j);
191  aAccumulator.getBinGeometry(i,j,a,b,c,d);
192  a+= shift;
193  b+= shift;
194  c+= shift;
195  d+= shift;
196  a = a*radius;
197  b = b*radius;
198  c = c*radius;
199  d = d*radius;
200 
201  display.setFillColor(cmap(aAccumulator.count(i,j)));
202  display.addQuad(a, b, c, d);
203  }
204  }
205  display.setFillColor( saveFillColor);
206 }
207 // SphericalAccumulator
208 
209 
210 
211 // Mesh
212 template <typename Space, typename KSpace>
213 template <typename TPoint>
214 inline
215 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
216  const DGtal::Mesh<TPoint> & aMesh )
217 {
218  std::string mode = display.getMode( aMesh.className() );
219  if ( mode == "Faces" || mode=="")
220  drawAsFaces( display, aMesh );
221 }
222 
223 template <typename Space, typename KSpace>
224 template <typename TPoint>
225 inline
226 void DGtal::Display3DFactory<Space,KSpace>::drawAsFaces( Display & display,
227  const DGtal::Mesh<TPoint> & aMesh )
228 {
229  DGtal::Color fillColorSave = display.getFillColor();
230  bool useGlobalColor = !aMesh.isStoringFaceColors();
231  for(unsigned int i=0; i< aMesh.nbFaces(); i++)
232  {
233  typename Mesh<TPoint>::MeshFace aFace = aMesh.getFace(i);
234  unsigned int aNum = aFace.size();
235  if(!useGlobalColor){
236  display.setFillColor(aMesh.getFaceColor(i));
237  }
238  if(aNum==4)
239  {
240  TPoint p1 = aMesh.getVertex(aFace.at(0));
241  TPoint p2 = aMesh.getVertex(aFace.at(1));
242  TPoint p3 = aMesh.getVertex(aFace.at(2));
243  TPoint p4 = aMesh.getVertex(aFace.at(3));
244 
245  display.addQuad(p1, p2, p3, p4);
246  }else if(aNum==3)
247  {
248  TPoint p1 = aMesh.getVertex(aFace.at(0));
249  TPoint p2 = aMesh.getVertex(aFace.at(1));
250  TPoint p3 = aMesh.getVertex(aFace.at(2));
251 
252  display.addTriangle(p1, p2,p3);
253  }else if(aNum>4)
254  {
255  std::vector<typename Display::RealPoint> vectPoly;
256  for(unsigned int j=0; j< aFace.size(); j++)
257  {
258  typename Display::RealPoint point(aMesh.getVertex(aFace.at(j)));
259  vectPoly.push_back(point);
260  }
261  display.addPolygon(vectPoly);
262  }else
263  {
264  trace.warning()<< "Face not valid, only "<< aNum << "vertex... "<< std::endl;
265  }
266  }
267  display.setFillColor(fillColorSave);
268 }
269 // Mesh
270 
271 
272 // StandardDSS6Computer
273 template <typename Space, typename KSpace>
274 template <typename TIterator, typename TInteger, int connectivity>
275 inline
276 void DGtal::Display3DFactory<Space,KSpace>::drawAsBalls( Display & display,
277  const DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity> & a )
278 {
279  typedef TIterator ConstIterator;
280  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Point3d;
281 
282  // Draw points
283  display << CustomColors3D( display.getLineColor(), display.getFillColor() );
284  for (ConstIterator i = a.begin(); i != a.end(); ++i)
285  {
286  display << *i;
287  }
288 
289  // Draw a linking polygonal line if the voxels are drawn as points.
290  if(display.getMode("PointVector")=="Grid")
291  {
292  ConstIterator k = a.begin();
293  Point3d prevp = *k;
294  DGtal::Z3i::RealPoint rprevp = display.embed( prevp);
295  ++k;
296  for ( ; k != a.end(); ++k) {
297  Point3d p = *k;
298  DGtal::Z3i::RealPoint rp = display.embed( p );
299 
300  display.addLine(rprevp,rp);
301  rprevp = rp;
302  }
303  }
304 }
305 
306 template <typename Space, typename KSpace>
307 template <typename TIterator, typename TInteger, int connectivity>
308 inline
309 void
310 DGtal::Display3DFactory<Space,KSpace>::drawAsBoundingBox( Display & display,
311  const DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity> & a )
312 {
313 
314  typedef TIterator ConstIterator;
315 
316  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Point3d;
317  typedef DGtal::PointVector<3,double> PointD3d;
318  typedef typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::PointR3d PointR3d;
319 
320  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Vector3d;
321  typedef DGtal::PointVector<3,double> VectorD3d;
322 
323  typedef TInteger Integer;
324 
325  //get DSS parameters
326  Vector3d v; //direction vector
327  PointR3d muR; //intercept
328  PointR3d omegaR; //thickness
329  a.getParameters ( v, muR, omegaR );
330 
331  PointD3d mu;
332  mu[0] = NumberTraits<Integer>::castToDouble ( muR[0].first ) / NumberTraits<Integer>::castToDouble ( muR[0].second );
333  mu[1] = NumberTraits<Integer>::castToDouble ( muR[1].first ) / NumberTraits<Integer>::castToDouble ( muR[1].second );
334  mu[2] = NumberTraits<Integer>::castToDouble ( muR[2].first ) / NumberTraits<Integer>::castToDouble ( muR[2].second );
335 
336  PointD3d omega;
337  omega[0] = NumberTraits<Integer>::castToDouble ( omegaR[0].first ) / NumberTraits<Integer>::castToDouble ( omegaR[0].second );
338  omega[1] = NumberTraits<Integer>::castToDouble ( omegaR[1].first ) / NumberTraits<Integer>::castToDouble ( omegaR[1].second );
339  omega[2] = NumberTraits<Integer>::castToDouble ( omegaR[2].first ) / NumberTraits<Integer>::castToDouble ( omegaR[2].second );
340 
341  //casting coordinates of v in double
342  VectorD3d u = VectorD3d(NumberTraits<Integer>::castToDouble(v[0]),
343  NumberTraits<Integer>::castToDouble(v[1]),
344  NumberTraits<Integer>::castToDouble(v[2]) );
345  //L2 norm of u
346  double n = u[0]*u[0] + u[1]*u[1] + u[2]*u[2];
347 
348  //first and last points
349  Point3d first = *a.begin();
350  Point3d last = *(--a.end());
351  PointD3d f = PointD3d(NumberTraits<Integer>::castToDouble(first[0]),
352  NumberTraits<Integer>::castToDouble(first[1]),
353  NumberTraits<Integer>::castToDouble(first[2]) );
354  PointD3d l = PointD3d(NumberTraits<Integer>::castToDouble(last[0]),
355  NumberTraits<Integer>::castToDouble(last[1]),
356  NumberTraits<Integer>::castToDouble(last[2]) );
357 
358  if (n != 0) {
359 
360  //last coefficient of the normal plane to the DSS direction
361  //passing trough f and l
362  double df = -u[0]*f[0] -u[1]*f[1] -u[2]*f[2];
363  double dl = -u[0]*l[0] -u[1]*l[1] -u[2]*l[2];
364 
365  //omega masks
366  PointD3d omega1, omega2;
367  if (omega[0] == 0) {
368  omega1 = PointD3d(0,omega[1],0);
369  omega2 = PointD3d(0,0,omega[2]);
370  } else {
371  if (omega[1] == 0) {
372  omega1 = PointD3d(omega[0],0,0);
373  omega2 = PointD3d(0,0,omega[2]);
374  } else {//omega[2] == 0
375  omega1 = PointD3d(omega[0],0,0);
376  omega2 = PointD3d(0,omega[1],0);
377  }
378  }
379 
380  double m1 = u[0]*mu[0] + u[1]*mu[1] + u[2]*mu[2];
381  double m2 = u[0]*(mu[0]+omega1[0]) + u[1]*(mu[1]+omega1[1]) + u[2]*(mu[2]+omega1[2]);
382  double m3 = u[0]*(mu[0]+omega2[0]) + u[1]*(mu[1]+omega2[1]) + u[2]*(mu[2]+omega2[2]);
383  double m4 = u[0]*(mu[0]+omega[0]) + u[1]*(mu[1]+omega[1]) + u[2]*(mu[2]+omega[2]);
384 
385  //4 lines
386  PointD3d pf = PointD3d( mu[0] - ( (m1+df)*u[0] )/n,
387  mu[1] - ( (m1+df)*u[1] )/n,
388  mu[2] - ( (m1+df)*u[2] )/n );
389  PointD3d pl = PointD3d( mu[0] - ( (m1+dl)*u[0] )/n,
390  mu[1] - ( (m1+dl)*u[1] )/n,
391  mu[2] - ( (m1+dl)*u[2] )/n );
392 
393  display.addLine(pf, pl);
394 
395  PointD3d pf2 = PointD3d((mu[0]+omega1[0]) - ( (m2+df)*u[0] )/n,
396  (mu[1]+omega1[1]) - ( (m2+df)*u[1] )/n,
397  (mu[2]+omega1[2]) - ( (m2+df)*u[2] )/n );
398  PointD3d pl2 = PointD3d((mu[0]+omega1[0]) - ( (m2+dl)*u[0] )/n,
399  (mu[1]+omega1[1]) - ( (m2+dl)*u[1] )/n,
400  (mu[2]+omega1[2]) - ( (m2+dl)*u[2] )/n );
401 
402  display.addLine(pf2, pl2);
403 
404  PointD3d pf3 = PointD3d((mu[0]+omega2[0]) - ( (m3+df)*u[0] )/n,
405  (mu[1]+omega2[1]) - ( (m3+df)*u[1] )/n,
406  (mu[2]+omega2[2]) - ( (m3+df)*u[2] )/n );
407  PointD3d pl3 = PointD3d((mu[0]+omega2[0]) - ( (m3+dl)*u[0] )/n,
408  (mu[1]+omega2[1]) - ( (m3+dl)*u[1] )/n,
409  (mu[2]+omega2[2]) - ( (m3+dl)*u[2] )/n );
410 
411  display.addLine(pf3, pl3);
412 
413  PointD3d pf4 = PointD3d((mu[0]+omega[0]) - ( (m4+df)*u[0] )/n,
414  (mu[1]+omega[1]) - ( (m4+df)*u[1] )/n,
415  (mu[2]+omega[2]) - ( (m4+df)*u[2] )/n );
416  PointD3d pl4 = PointD3d((mu[0]+omega[0]) - ( (m4+dl)*u[0] )/n,
417  (mu[1]+omega[1]) - ( (m4+dl)*u[1] )/n,
418  (mu[2]+omega[2]) - ( (m4+dl)*u[2] )/n );
419 
420  display.addLine(pf4, pl4);
421 
422  //two end facets
423  display.addLine(pf, pf2);
424  display.addLine(pf2,pf4);
425  display.addLine(pf4, pf3);
426  display.addLine(pf3, pf);
427 
428  display.addLine(pl, pl2);
429  display.addLine(pl2, pl4);
430  display.addLine(pl4, pl3);
431  display.addLine(pl3, pl);
432  }
433 }
434 
435 template <typename Space, typename KSpace>
436 template <typename TIterator, typename TInteger, int connectivity>
437 inline
438 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
439  const DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity> & a )
440 {
441  std::string mode = display.getMode( a.className() );
442  if ( mode == "BoundingBox" )
443  drawAsBoundingBox( display, a );
444  else if ( mode == "Points" )
445  drawAsBalls( display, a );
446  else if ( ( mode == "" ) )
447  {
448  drawAsBalls( display, a );
449  }
450 }
451 // StandardDSS6Computer
452 
453 
454 // Naive3DDSSComputer
455 
456 template <typename Space, typename KSpace>
457 template <typename TIterator, typename TInteger, int connectivity>
458 inline
459 void DGtal::Display3DFactory<Space,KSpace>::drawAsBalls( Display & display,
460  const DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity> & a )
461 {
462  typedef TIterator ConstIterator;
463  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Point3d;
464 
465  // Draw points
466  display << CustomColors3D( display.getLineColor(), display.getFillColor() );
467  for (ConstIterator it = a.begin(); it != a.end(); ++it)
468  {
469  display << *it;
470  }
471 
472  // Draw a linking polygonal line if the voxels are drawn as points.
473  if(display.getMode("PointVector")=="Grid")
474  {
475  ConstIterator it = a.begin();
476  Point3d prevp = *it;
477  DGtal::Z3i::RealPoint rprevp = display.embed( prevp);
478  ++it;
479  for ( ; it != a.end(); ++it) {
480  Point3d p = *it;
481  DGtal::Z3i::RealPoint rp = display.embed( p );
482 
483  display.addLine(rprevp,rp);
484  rprevp = rp;
485  }
486  }
487 }
488 
489 template <typename Space, typename KSpace>
490 template <typename TIterator, typename TInteger, int connectivity>
491 inline
492 void
493 DGtal::Display3DFactory<Space,KSpace>::drawAsBoundingBox( Display & display,
494  const DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity> & a )
495 {
496 
497  typedef TIterator ConstIterator;
498 
499  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Point3d;
500  typedef DGtal::PointVector<3,double> PointD3d;
501  typedef typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::PointR3d PointR3d;
502 
503  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Vector3d;
504  typedef DGtal::PointVector<3,double> VectorD3d;
505 
506  typedef TInteger Integer;
507 
508  //get DSS parameters
509  Vector3d v; //direction vector
510  PointR3d muR; //intercept
511  PointR3d omegaR; //thickness
512  a.getParameters ( v, muR, omegaR );
513 
514  PointD3d mu;
515  mu[0] = NumberTraits<Integer>::castToDouble ( muR[0].first ) / NumberTraits<Integer>::castToDouble ( muR[0].second );
516  mu[1] = NumberTraits<Integer>::castToDouble ( muR[1].first ) / NumberTraits<Integer>::castToDouble ( muR[1].second );
517  mu[2] = NumberTraits<Integer>::castToDouble ( muR[2].first ) / NumberTraits<Integer>::castToDouble ( muR[2].second );
518 
519  PointD3d omega;
520  omega[0] = NumberTraits<Integer>::castToDouble ( omegaR[0].first ) / NumberTraits<Integer>::castToDouble ( omegaR[0].second );
521  omega[1] = NumberTraits<Integer>::castToDouble ( omegaR[1].first ) / NumberTraits<Integer>::castToDouble ( omegaR[1].second );
522  omega[2] = NumberTraits<Integer>::castToDouble ( omegaR[2].first ) / NumberTraits<Integer>::castToDouble ( omegaR[2].second );
523 
524  //casting coordinates of v in double
525  VectorD3d u = VectorD3d(NumberTraits<Integer>::castToDouble(v[0]),
526  NumberTraits<Integer>::castToDouble(v[1]),
527  NumberTraits<Integer>::castToDouble(v[2]) );
528  //Squared L2 norm of u
529  double n = u[0]*u[0] + u[1]*u[1] + u[2]*u[2];
530 
531  //first and last points
532  Point3d first = *a.begin();
533  Point3d last = *(--a.end());
534  PointD3d f = PointD3d(NumberTraits<Integer>::castToDouble(first[0]),
535  NumberTraits<Integer>::castToDouble(first[1]),
536  NumberTraits<Integer>::castToDouble(first[2]) );
537  PointD3d l = PointD3d(NumberTraits<Integer>::castToDouble(last[0]),
538  NumberTraits<Integer>::castToDouble(last[1]),
539  NumberTraits<Integer>::castToDouble(last[2]) );
540 
541  if (n != 0) {
542 
543  //last coefficient of the normal plane to the DSS direction
544  //passing trough f and l
545  double df = -u[0]*f[0] -u[1]*f[1] -u[2]*f[2];
546  double dl = -u[0]*l[0] -u[1]*l[1] -u[2]*l[2];
547 
548  //omega masks
549  PointD3d omega1, omega2;
550  if (omega[0] == 0) {
551  omega1 = PointD3d(0,omega[1],0);
552  omega2 = PointD3d(0,0,omega[2]);
553  } else {
554  if (omega[1] == 0) {
555  omega1 = PointD3d(omega[0],0,0);
556  omega2 = PointD3d(0,0,omega[2]);
557  } else {//omega[2] == 0
558  omega1 = PointD3d(omega[0],0,0);
559  omega2 = PointD3d(0,omega[1],0);
560  }
561  }
562 
563  double m1 = u[0]*mu[0] + u[1]*mu[1] + u[2]*mu[2];
564  double m2 = u[0]*(mu[0]+omega1[0]) + u[1]*(mu[1]+omega1[1]) + u[2]*(mu[2]+omega1[2]);
565  double m3 = u[0]*(mu[0]+omega2[0]) + u[1]*(mu[1]+omega2[1]) + u[2]*(mu[2]+omega2[2]);
566  double m4 = u[0]*(mu[0]+omega[0]) + u[1]*(mu[1]+omega[1]) + u[2]*(mu[2]+omega[2]);
567 
568  //4 lines
569  PointD3d pf = PointD3d( mu[0] - ( (m1+df)*u[0] )/n,
570  mu[1] - ( (m1+df)*u[1] )/n,
571  mu[2] - ( (m1+df)*u[2] )/n );
572  PointD3d pl = PointD3d( mu[0] - ( (m1+dl)*u[0] )/n,
573  mu[1] - ( (m1+dl)*u[1] )/n,
574  mu[2] - ( (m1+dl)*u[2] )/n );
575 
576  display.addLine(pf, pl);
577 
578  PointD3d pf2 = PointD3d((mu[0]+omega1[0]) - ( (m2+df)*u[0] )/n,
579  (mu[1]+omega1[1]) - ( (m2+df)*u[1] )/n,
580  (mu[2]+omega1[2]) - ( (m2+df)*u[2] )/n );
581  PointD3d pl2 = PointD3d((mu[0]+omega1[0]) - ( (m2+dl)*u[0] )/n,
582  (mu[1]+omega1[1]) - ( (m2+dl)*u[1] )/n,
583  (mu[2]+omega1[2]) - ( (m2+dl)*u[2] )/n );
584 
585  display.addLine(pf2, pl2);
586 
587  PointD3d pf3 = PointD3d((mu[0]+omega2[0]) - ( (m3+df)*u[0] )/n,
588  (mu[1]+omega2[1]) - ( (m3+df)*u[1] )/n,
589  (mu[2]+omega2[2]) - ( (m3+df)*u[2] )/n );
590  PointD3d pl3 = PointD3d((mu[0]+omega2[0]) - ( (m3+dl)*u[0] )/n,
591  (mu[1]+omega2[1]) - ( (m3+dl)*u[1] )/n,
592  (mu[2]+omega2[2]) - ( (m3+dl)*u[2] )/n );
593 
594  display.addLine(pf3, pl3);
595 
596  PointD3d pf4 = PointD3d((mu[0]+omega[0]) - ( (m4+df)*u[0] )/n,
597  (mu[1]+omega[1]) - ( (m4+df)*u[1] )/n,
598  (mu[2]+omega[2]) - ( (m4+df)*u[2] )/n );
599  PointD3d pl4 = PointD3d((mu[0]+omega[0]) - ( (m4+dl)*u[0] )/n,
600  (mu[1]+omega[1]) - ( (m4+dl)*u[1] )/n,
601  (mu[2]+omega[2]) - ( (m4+dl)*u[2] )/n );
602 
603  display.addLine(pf4, pl4);
604 
605  //two end facets
606  display.addLine(pf, pf2);
607  display.addLine(pf2,pf4);
608  display.addLine(pf4, pf3);
609  display.addLine(pf3, pf);
610 
611  display.addLine(pl, pl2);
612  display.addLine(pl2, pl4);
613  display.addLine(pl4, pl3);
614  display.addLine(pl3, pl);
615  }
616 }
617 
618 template <typename Space, typename KSpace>
619 template <typename TIterator, typename TInteger, int connectivity>
620 inline
621 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
622  const DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity> & a )
623 {
624  std::string mode = display.getMode( a.className() );
625  if ( mode == "BoundingBox" )
626  drawAsBoundingBox( display, a );
627  else if ( mode == "Points" )
628  drawAsBalls( display, a );
629  else if ( ( mode == "" ) )
630  {
631  drawAsBalls( display, a );
632  }
633 }
634 // Naive3DDSSComputer
635 
636 
637 // DigitalSetBySTLSet
638 template <typename Space, typename KSpace>
639 template<typename Domain, typename Compare>
640 inline
641 void DGtal::Display3DFactory<Space,KSpace>::drawAsPavingTransparent( Display & display,
642  const DGtal::DigitalSetBySTLSet<Domain, Compare> & s )
643 {
644  typedef typename Domain::Point Point;
645  typedef typename std::set<Point>::const_iterator ConstIterator;
646 
647  ASSERT(Domain::Space::dimension == 3);
648 
649  display.createNewCubeList();
650  for ( ConstIterator it = s.begin();
651  it != s.end();
652  ++it )
653  {
654  DGtal::Z3i::RealPoint rp = display.embed((*it) );
655  display.addCube(rp);
656  }
657 }
658 
659 template <typename Space, typename KSpace>
660 template<typename Domain, typename Compare>
661 inline
662 void DGtal::Display3DFactory<Space,KSpace>::drawAsPaving( Display & display,
663  const DGtal::DigitalSetBySTLSet<Domain, Compare> & s )
664 {
665  typedef typename DGtal::DigitalSetBySTLSet<Domain, Compare>::ConstIterator ConstIterator;
666 
667  ASSERT(Domain::Space::dimension == 3);
668 
669  display.createNewCubeList( );
670  for ( ConstIterator it = s.begin();
671  it != s.end();
672  ++it )
673  {
674  DGtal::Z3i::RealPoint rp = display.embed((*it) );
675  display.addCube(rp);
676  }
677 }
678 
679 template <typename Space, typename KSpace>
680 template<typename Domain, typename Compare>
681 inline
682 void DGtal::Display3DFactory<Space,KSpace>::drawAsGrid( Display & display,
683  const DGtal::DigitalSetBySTLSet<Domain, Compare> & s )
684 {
685  typedef typename DGtal::DigitalSetBySTLSet<Domain, Compare>::ConstIterator ConstIterator;
686 
687  ASSERT(Domain::Space::dimension == 3);
688 
689  for ( ConstIterator it = s.begin();
690  it != s.end();
691  ++it )
692  {
693  DGtal::Z3i::RealPoint rp = display.embed((*it) );
694  display.addBall(rp,1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
695  }
696 }
697 
698 template <typename Space, typename KSpace>
699 template<typename Domain, typename Compare>
700 inline
701 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
702  const DGtal::DigitalSetBySTLSet<Domain, Compare> & s )
703 {
704  ASSERT(Domain::Space::dimension == 3);
705 
706  std::string mode = display.getMode( s.className() );
707  ASSERT( (mode=="Paving" || mode=="PavingTransp" || mode=="Grid" || mode=="Both" || mode=="") );
708 
709  if ( mode == "Paving" || ( mode == "" ) )
710  drawAsPaving( display, s );
711  else if ( mode == "PavingTransp" )
712  drawAsPavingTransparent( display, s );
713  else if ( mode == "Grid" )
714  drawAsGrid( display, s );
715  else if ( ( mode == "Both" ) )
716  {
717  drawAsPaving( display, s );
718  drawAsGrid( display, s );
719  }
720 }
721 // DigitalSetBySTLSet
722 
723 
724 // DigitalSetByAssociativeContainer
725 template <typename Space, typename KSpace>
726 template<typename Domain, typename Container>
727 inline
728 void DGtal::Display3DFactory<Space,KSpace>::drawAsPavingTransparent( Display & display,
729  const DGtal::DigitalSetByAssociativeContainer<Domain, Container> & s )
730 {
731  typedef typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::ConstIterator ConstIterator;
732 
733  ASSERT(Domain::Space::dimension == 3);
734 
735  display.createNewCubeList( );
736  for ( ConstIterator it = s.begin();
737  it != s.end();
738  ++it )
739  {
740  DGtal::Z3i::RealPoint rp = display.embed((*it) );
741  display.addCube(rp);
742  }
743 }
744 
745 template <typename Space, typename KSpace>
746 template<typename Domain, typename Container>
747 inline
748 void DGtal::Display3DFactory<Space,KSpace>::drawAsPaving( Display & display,
749  const DGtal::DigitalSetByAssociativeContainer<Domain, Container> & s )
750 {
751  typedef typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::ConstIterator ConstIterator;
752 
753  ASSERT(Domain::Space::dimension == 3);
754 
755  display.createNewCubeList( );
756  for ( ConstIterator it = s.begin();
757  it != s.end();
758  ++it )
759  {
760  DGtal::Z3i::RealPoint rp = display.embed((*it) );
761  display.addCube(rp);
762  }
763 }
764 
765 template <typename Space, typename KSpace>
766 template<typename Domain, typename Container>
767 inline
768 void DGtal::Display3DFactory<Space,KSpace>::drawAsGrid( Display & display,
769  const DGtal::DigitalSetByAssociativeContainer<Domain, Container> & s )
770 {
771  typedef typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::ConstIterator ConstIterator;
772 
773 
774  ASSERT(Domain::Space::dimension == 3);
775 
776  for ( ConstIterator it = s.begin();
777  it != s.end();
778  ++it )
779  {
780  DGtal::Z3i::RealPoint rp = display.embed((*it) );
781  display.addBall(rp,1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
782  }
783 }
784 
785 template <typename Space, typename KSpace>
786 template<typename Domain, typename Container>
787 inline
788 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
789  const DGtal::DigitalSetByAssociativeContainer<Domain, Container> & s )
790 {
791  ASSERT(Domain::Space::dimension == 3);
792 
793  std::string mode = display.getMode( s.className() );
794  ASSERT( (mode=="Paving" || mode=="PavingTransp" || mode=="Grid" || mode=="Both" || mode=="") );
795 
796  if ( mode == "Paving" || ( mode == "" ) )
797  drawAsPaving( display, s );
798  else if ( mode == "PavingTransp" )
799  drawAsPavingTransparent( display, s );
800  else if ( mode == "Grid" )
801  drawAsGrid( display, s );
802  else if ( ( mode == "Both" ) )
803  {
804  drawAsPaving( display, s );
805  drawAsGrid( display, s );
806  }
807 }
808 // DigitalSetByAssociativeContainer
809 
810 
811 // DigitalSetBySTLVector
812 template <typename Space, typename KSpace>
813 template<typename Domain>
814 inline
815 void DGtal::Display3DFactory<Space,KSpace>::drawAsPavingTransparent( Display & display,
816  const DGtal::DigitalSetBySTLVector<Domain> & v )
817 {
818  typedef typename Domain::Point Point;
819  typedef typename std::vector<Point>::const_iterator ConstIterator;
820 
821  ASSERT(Domain::Space::dimension == 3);
822 
823  display.createNewCubeList( );
824  for ( ConstIterator it = v.begin();
825  it != v.end();
826  ++it )
827  {
828  DGtal::Z3i::RealPoint rp = display.embed((*it) );
829  display.addCube(rp);
830  }
831 }
832 
833 template <typename Space, typename KSpace>
834 template<typename Domain>
835 inline
836 void DGtal::Display3DFactory<Space,KSpace>::drawAsPaving( Display & display,
837  const DGtal::DigitalSetBySTLVector<Domain> & v )
838 {
839  typedef typename Domain::Point Point;
840  typedef typename std::vector<Point>::const_iterator ConstIterator;
841 
842  ASSERT(Domain::Space::dimension == 3);
843 
844  display.createNewCubeList( );
845  for ( ConstIterator it = v.begin();
846  it != v.end();
847  ++it )
848  {
849  DGtal::Z3i::RealPoint rp = display.embed((*it) );
850  display.addCube(rp);
851  }
852 }
853 
854 template <typename Space, typename KSpace>
855 template<typename Domain>
856 inline
857 void DGtal::Display3DFactory<Space,KSpace>::drawAsGrid( Display & display,
858  const DGtal::DigitalSetBySTLVector<Domain> & v )
859 {
860  typedef typename Domain::Point Point;
861  typedef typename std::vector<Point>::const_iterator ConstIterator;
862 
863  ASSERT(Domain::Space::dimension == 3);
864 
865  for ( ConstIterator it = v.begin();
866  it != v.end();
867  ++it )
868  {
869  DGtal::Z3i::RealPoint rp = display.embed((*it) );
870  display.addBall(rp,1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
871  }
872 }
873 
874 template <typename Space, typename KSpace>
875 template<typename Domain>
876 inline
877 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
878  const DGtal::DigitalSetBySTLVector<Domain> & v )
879 {
880  ASSERT(Domain::Space::dimension == 3);
881 
882  std::string mode = display.getMode( v.className() );
883  ASSERT( (mode=="Paving" || mode=="PavingTransp" || mode=="Grid" || mode=="Both" || mode=="") );
884 
885  if ( mode == "Paving" || ( mode == "" ) )
886  drawAsPaving( display, v );
887  else if ( mode == "PavingTransp" )
888  drawAsPavingTransparent( display, v );
889  else if ( mode == "Grid" )
890  drawAsGrid( display, v );
891  else if ( ( mode == "Both" ) )
892  {
893  drawAsPaving( display, v);
894  drawAsGrid( display, v );
895  }
896 }
897 // DigitalSetBySTLVector
898 
899 
900 // HyperRectDomain
901 template <typename Space, typename KSpace>
902 template <typename SpaceDom>
903 inline
904 void DGtal::Display3DFactory<Space,KSpace>::drawAsBoundingBox( Display & display,
905  const DGtal::HyperRectDomain<SpaceDom> & h )
906 {
907  DGtal::Color fillColorSave = display.getFillColor();
908  ASSERT(Space::dimension == 2 || Space::dimension == 3 || "drawAsBoundingBox-NOT-YET-IMPLEMENTED-in-ND");
909 
910  DGtal::Z3i::RealPoint upperBound;
911  DGtal::Z3i::RealPoint lowerBound;
912 
913  if (SpaceDom::dimension == 3)
914  {
915  upperBound = display.embed( DGtal::Z3i::Point(h.myUpperBound[0], h.myUpperBound[1], h.myUpperBound[2]));
916  lowerBound = display.embed( DGtal::Z3i::Point(h.myLowerBound[0], h.myLowerBound[1], h.myLowerBound[2]));
917  }
918  if (SpaceDom::dimension == 2)
919  {
920  upperBound = display.embed( DGtal::Z3i::Point(h.myUpperBound[0], h.myUpperBound[1], 0));
921  lowerBound = display.embed( DGtal::Z3i::Point(h.myLowerBound[0], h.myLowerBound[1], 0));
922  }
923 
924 
925  display.setFillColor(DGtal::Color(250,250,250,10));
926  double shiftSize=0.01;
927  if (SpaceDom::dimension == 3)
928  {
929  //Z upper face
930  display.addQuad(DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
931  upperBound[1]+(0.5+shiftSize),
932  upperBound[2]+(0.5+shiftSize)),
933  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
934  upperBound[1]+(0.5+shiftSize),
935  upperBound[2]+(0.5+shiftSize)),
936  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
937  lowerBound[1]-(0.5+shiftSize),
938  upperBound[2]+(0.5+shiftSize)),
939  DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
940  lowerBound[1]-(0.5+shiftSize),
941  upperBound[2]+(0.5+shiftSize)));
942  //Z lower face
943  display.addQuad(DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
944  upperBound[1]+(0.5+shiftSize),
945  lowerBound[2]-(0.5+shiftSize)),
946  DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
947  lowerBound[1]-(0.5+shiftSize),
948  lowerBound[2]-(0.5+shiftSize)),
949  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
950  lowerBound[1]-(0.5+shiftSize),
951  lowerBound[2]-(0.5+shiftSize)),
952  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
953  upperBound[1]+(0.5+shiftSize),
954  lowerBound[2]-(0.5+shiftSize)));
955  //Y upper face
956  display.addQuad(DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
957  upperBound[1]+(0.5+shiftSize),
958  upperBound[2]+(0.5+shiftSize)),
959  DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
960  upperBound[1]+(0.5+shiftSize),
961  lowerBound[2]-(0.5+shiftSize)),
962  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
963  upperBound[1]+(0.5+shiftSize),
964  lowerBound[2]-(0.5+shiftSize)),
965  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
966  upperBound[1]+(0.5+shiftSize),
967  upperBound[2]+(0.5+shiftSize)));
968  //Y lower face
969  display.addQuad(DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
970  lowerBound[1]-(0.5+shiftSize),
971  upperBound[2]+(0.5+shiftSize)),
972  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
973  lowerBound[1]-(0.5+shiftSize),
974  upperBound[2]+(0.5+shiftSize)),
975  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
976  lowerBound[1]-(0.5+shiftSize),
977  lowerBound[2]-(0.5+shiftSize)),
978  DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
979  lowerBound[1]-(0.5+shiftSize),
980  lowerBound[2]-(0.5+shiftSize)));
981  // X upper face
982  display.addQuad(DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
983  upperBound[1]+(0.5+shiftSize),
984  upperBound[2]+(0.5+shiftSize)),
985  DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
986  lowerBound[1]-(0.5+shiftSize),
987  upperBound[2]+(0.5+shiftSize)),
988  DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
989  lowerBound[1]-(0.5+shiftSize),
990  lowerBound[2]-(0.5+shiftSize)),
991  DGtal::Z3i::RealPoint(upperBound[0]+(0.5+shiftSize),
992  upperBound[1]+(0.5+shiftSize),
993  lowerBound[2]-(0.5+shiftSize)));
994  // X lower face
995  display.addQuad(DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
996  upperBound[1]+(0.5+shiftSize),
997  upperBound[2]+(0.5+shiftSize)),
998  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
999  upperBound[1]+(0.5+shiftSize),
1000  lowerBound[2]-(0.5+shiftSize)),
1001  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
1002  lowerBound[1]-(0.5+shiftSize),
1003  lowerBound[2]-(0.5+shiftSize)),
1004  DGtal::Z3i::RealPoint(lowerBound[0]-(0.5+shiftSize),
1005  lowerBound[1]-(0.5+shiftSize),
1006  upperBound[2]+(0.5+shiftSize)));
1007  }
1008  display.setFillColor( fillColorSave);
1009 }
1010 
1011 template <typename Space, typename KSpace>
1012 template <typename SpaceDom>
1013 inline
1014 void DGtal::Display3DFactory<Space,KSpace>::drawAsGrid( Display & display,
1015  const DGtal::HyperRectDomain<SpaceDom> & h )
1016 {
1017  typedef typename Space::Integer Integer;
1018 
1019  ASSERT(Space::dimension == 3 || "drawAsGrid-NOT-YET-IMPLEMENTED-in-ND");
1020 
1021  if (Space::dimension == 3)
1022  {
1023  // Face XY
1024  for (int64_t z = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[2]);
1025  z <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[2]); z++)
1026  {
1027  for (int64_t x = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[0]);
1028  x <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[0]); x++)
1029  {
1030  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, h.myLowerBound[1], z) );
1031  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, h.myUpperBound[1], z) );
1032 
1033  display.addLine( rp1, rp2);
1034  }
1035  for (int64_t y = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[1]);
1036  y <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[1]); y++)
1037  {
1038  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(h.myLowerBound[0], y, z) );
1039  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(h.myUpperBound[0], y, z) );
1040 
1041  display.addLine( rp1, rp2 );
1042  }
1043  }
1044 
1045  // Faces XZ
1046  for (int64_t y = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[1]);
1047  y <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[1]); y++)
1048  {
1049  for (int64_t x = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[0]);
1050  x <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[0]); x++)
1051  {
1052  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, y, h.myLowerBound[2]) );
1053  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, y, h.myLowerBound[2]) );
1054 
1055  display.addLine( rp1, rp2);
1056  }
1057  for (int64_t z = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[2]);
1058  z <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[2]); z++)
1059  {
1060  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(h.myLowerBound[0], y, z) );
1061  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(h.myUpperBound[0], y, z) );
1062 
1063  display.addLine( rp1, rp2);
1064  }
1065  }
1066 
1067  // Faces YZ
1068  for (int64_t x = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[0]);
1069  x <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[0]); x++)
1070  {
1071  for (int64_t y = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[1]);
1072  y <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[1]); y++)
1073  {
1074  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, y, h.myLowerBound[2]) );
1075  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, y, h.myUpperBound[2]) );
1076 
1077  display.addLine( rp1, rp2);
1078  }
1079  for (int64_t z = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[2]);
1080  z <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[2]); z++)
1081  {
1082  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, h.myLowerBound[1], z) );
1083  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, h.myLowerBound[1], z) );
1084 
1085  display.addLine( rp1, rp2);
1086  }
1087  }
1088  }
1089 }
1090 
1091 template <typename Space, typename KSpace>
1092 template <typename SpaceDom>
1093 inline
1094 void DGtal::Display3DFactory<Space,KSpace>::drawAsPavingBalls( Display & display,
1095  const DGtal::HyperRectDomain<SpaceDom> & h )
1096 {
1097  DGtal::Color fillColorSave = display.getFillColor();
1098  typedef typename Space::Integer Integer;
1099 
1100  ASSERT(Space::dimension == 3 || "drawAsPavingPoints-NOT-YET-IMPLEMENTED-in-ND");
1101  if (Space::dimension == 3)
1102  {
1103  // Face XY
1104  for (int64_t z = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[2]);
1105  z <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[2]); z++)
1106  {
1107  for (int64_t x = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[0]);
1108  x <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[0]); x++)
1109  {
1110 
1111  for (int64_t y = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[1]);
1112  y <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[1]); y++)
1113  {
1114  DGtal::Z3i::RealPoint rp = display.embed( DGtal::Z3i::Point(x, y, z) );
1115  display.setFillColor(DGtal::Color(255, 0 ,0));
1116  display.addBall(rp,1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1117  }
1118  }
1119  }
1120  }
1121  display.setFillColor(fillColorSave);
1122 }
1123 
1124 template <typename Space, typename KSpace>
1125 template <typename SpaceDom>
1126 inline
1127 void DGtal::Display3DFactory<Space,KSpace>::drawAsPaving( Display & display,
1128  const DGtal::HyperRectDomain<SpaceDom> & h )
1129 {
1130  DGtal::Color fillColorSave = display.getFillColor();
1131  typedef typename Space::Integer Integer;
1132 
1133  ASSERT(Space::dimension == 3 || "drawAsPaving-NOT-YET-IMPLEMENTED-in-ND");
1134 
1135  if (Space::dimension == 3)
1136  {
1137  // Face XY
1138  for (int64_t z = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[2]);
1139  z <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[2]); z++)
1140  {
1141  for (int64_t x = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[0]);
1142  x <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[0]); x++)
1143  {
1144  for (int64_t y = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[1]);
1145  y <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[1]); y++)
1146  {
1147  DGtal::Z3i::RealPoint rp = display.embed( DGtal::Z3i::Point(x, y, z) );
1148  rp[0]+=0.5;
1149  rp[1]+=0.5;
1150  rp[2]+=0.5;
1151  //a transparent color for the paving
1152  display.setFillColor( Color(255, 255 ,255, 15));
1153  display.addCube(rp, 1.0);
1154  }
1155  }
1156  }
1157  }
1158  display.setFillColor(fillColorSave);
1159 }
1160 
1161 
1162 template <typename Space, typename KSpace>
1163 template <typename SpaceDom>
1164 inline
1165 void
1166 DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::HyperRectDomain<SpaceDom> & aDomain )
1167 {
1168  std::string mode = display.getMode( aDomain.className() );
1169 
1170  ASSERT((mode=="" || mode=="Grid" || mode=="Paving"|| mode=="PavingPoints"|| mode=="PavingGrids" ||
1171  mode=="BoundingBox")||
1172  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display3DD<Space, KSpace> & display, const DGtal::HyperRectDomain<Space> & aDomain ): Unknown mode "+mode)=="");
1173 
1174  /*
1175  if ( mode == "BoundingBox" )
1176  {
1177  display.createNewLineList(aDomain.className());
1178  drawAsBoundingBox( display, aDomain );
1179  }else if( ( mode == "" ) || (mode == "Grid"))
1180  {
1181  display.createNewLineList(aDomain.className());
1182  drawAsGrid( display, aDomain );
1183  }
1184  else if ( mode == "Paving" )
1185  {
1186  display.createNewCubeList( aDomain.className());
1187  }
1188  */
1189 
1190  ASSERT((Space::dimension==3)|| (Space::dimension==2));
1191  ASSERT((Space::dimension!=3) || (mode=="" || mode=="Grid" || mode=="Paving"|| mode=="PavingPoints"|| mode=="PavingGrids" ||
1192  mode=="BoundingBox")||
1193  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::HyperRectDomain<Space> & aDomain ): Unknown mode "+mode)=="");
1194  ASSERT((Space::dimension!=2) || (mode=="" || mode=="BoundingBox" || mode=="Grid") ||
1195  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::HyperRectDomain<Space> & aDomain ): Unknown mode "+mode)=="");
1196 
1197  if(Space::dimension == 2)
1198  {
1199  if (mode=="")
1200  mode="BoundingBox";
1201  }else if ( mode == "BoundingBox" )
1202  {
1203  display.createNewLineList(aDomain.className());
1204  drawAsBoundingBox( display, aDomain );
1205  }else if(( mode == "" ) || (mode == "Grid"))
1206  {
1207  display.createNewLineList(aDomain.className());
1208  drawAsGrid( display, aDomain );
1209  } else if ( mode == "Paving" )
1210  {
1211  display.createNewCubeList();
1212  drawAsPaving( display, aDomain );
1213  } else if ( mode == "PavingPoints" )
1214  {
1215  display.createNewBallList(aDomain.className());
1216  drawAsPavingBalls( display, aDomain );
1217  }else if ( mode == "PavingGrids" )
1218  {
1219  display.createNewLineList(aDomain.className());
1220  display.createNewCubeList( );
1221  drawAsGrid( display, aDomain );
1222  drawAsPaving( display, aDomain );
1223  }
1224 }
1225 // HyperRectDomain
1226 
1227 
1228 // KhalimskyCell
1229 template <typename Space, typename KSpace>
1230 inline
1231 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1232  const typename KSpace::Cell & k )
1233 {
1234  ASSERT(Space::dimension == 3);
1235  DGtal::Color fillColorSave = display.getFillColor();
1236  std::string mode = display.getMode( k.className() );
1237  ASSERT((mode=="" || mode=="Highlighted" || mode=="Transparent"|| mode=="Basic"|| mode=="Illustration"||mode=="IllustrationCustomColor")||
1238  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::KhalimskyCell<dim, TInteger> & k ): Unknown mode "+mode)=="");
1239  // used to display surfels located at a same position.
1240  double factorVolSurfel=1.0;
1241  if(mode=="Highlighted")
1242  {
1243  factorVolSurfel = 1.1;
1244  display.setFillColor(DGtal::Color(255, 50, 50, 255));
1245  }else if(mode=="Transparent")
1246  {
1247  display.setFillColor(DGtal::Color(180, 180, 250, 25));
1248  }
1249 
1250  DGtal::Z3i::RealPoint rp = display.embedK( k );
1251  bool xodd = ( NumberTraits<typename KSpace::Integer>::castToInt64_t(k.preCell().coordinates[ 0 ]) & 1 );
1252  bool yodd = ( NumberTraits<typename KSpace::Integer>::castToInt64_t(k.preCell().coordinates[ 1 ]) & 1 );
1253  bool zodd = ( NumberTraits<typename KSpace::Integer>::castToInt64_t(k.preCell().coordinates[ 2 ]) & 1 );
1254  unsigned int spaceDim= (xodd ? 1:0) + (yodd ? 1:0) + (zodd ? 1:0);
1255 
1256  switch (spaceDim) {
1257  case 0:
1258 
1259  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1260  {
1261  display.setFillColor(DGtal::Color(200, 200, 20, 255));
1262  }
1263 
1264  display.addBall(rp, 1.0/static_cast<double>(POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1265  break;
1266  case 1:
1267  if(mode!=""&& mode!="Basic" && mode!="IllustrationCustomColor")
1268  {
1269  display.setFillColor(DGtal::Color(255, 255, 50, 255));
1270  }
1271 
1272 
1273  display.addCylinder(DGtal::Z3i::RealPoint(rp[0]- (xodd? 0.5:0 ), rp[1]- (yodd? 0.5:0 ), rp[2]- (zodd? 0.5:0 )),
1274  DGtal::Z3i::RealPoint(rp[0]+ (xodd? 0.5:0 ), rp[1]+ (yodd? 0.5:0 ), rp[2]+ (zodd? 0.5:0 )));
1275  break;
1276  case 2:
1277  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1278  {
1279  display.setFillColor(DGtal::Color(20, 200, 200, 255));
1280  }
1281  if(mode=="Basic")
1282  {
1283  display.addQuadFromSurfelCenter(DGtal::Z3i::RealPoint(rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 )),
1284  ! xodd, !yodd, !zodd);
1285  }
1286  else
1287  display.addPrism(DGtal::Z3i::RealPoint(rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 )),
1288  ! xodd, !yodd, !zodd, factorVolSurfel,1.0, false, false);
1289  break;
1290  case 3:
1291  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1292  {
1293  display.setFillColor(DGtal::Color(255, 180, 250, 255));
1294  }
1295  if(mode=="Illustration"|| mode=="IllustrationCustomColor")
1296  {
1297  display.createNewCubeList();
1298  display.addCube(rp,0.80);
1299  }else{
1300  display.createNewCubeList();
1301  display.addCube(rp,0.90);
1302  }
1303  break;
1304  }
1305  display.setFillColor(fillColorSave);
1306 }
1307 // KhalimskyCell
1308 
1309 // KhalimskyCell
1310 template <typename Space, typename KSpace>
1311 inline
1312 void DGtal::Display3DFactory<Space,KSpace>::drawUnorientedSurfelWithNormal( Display & display,
1313  const typename KSpace::Cell & k ,
1314  const RealVector &normalVector,
1315  const bool enableDoubleFace)
1316 {
1317  ASSERT(Space::dimension == 3);
1318  DGtal::Color fillColorSave = display.getFillColor();
1319  std::string mode = display.getMode( k.className() );
1320  ASSERT(( mode=="Basic")|| ( mode=="") ||
1321  ("DGtal::Display3DFactory<Space,KSpace>::drawUnorientedSurfelWithNormal( Display & display, const DGtal::KhalimskyCell<dim, TInteger> & k ): Unknown mode "+mode)=="");
1322 
1323  RealPoint rp = display.embedK( k );
1324  const KSpace& K = display.space();
1325  bool xodd = K.uIsOpen( k, 0 );
1326  bool yodd = K.uIsOpen( k, 1 );
1327  bool zodd = K.uIsOpen( k, 2 );
1328  display.addQuadFromSurfelCenterWithNormal
1329  ( RealPoint( rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 ) ),
1330  ! xodd, ! yodd, ! zodd, normalVector,
1331  true, true, //reorientation enabled
1332  enableDoubleFace);
1333 }
1334 // KhalimskyCell
1335 
1336 // KhalimskyCell
1337 template <typename Space, typename KSpace>
1338 inline
1339 void DGtal::Display3DFactory<Space,KSpace>::drawOrientedSurfelWithNormal( Display & display,
1340  const typename KSpace::SCell & k ,
1341  const RealVector &normalVector,
1342  const bool enableDoubleFace)
1343 {
1344  ASSERT(Space::dimension == 3);
1345  DGtal::Color fillColorSave = display.getFillColor();
1346  std::string mode = display.getMode( k.className() );
1347  ASSERT(( mode=="Basic")|| ( mode=="") ||
1348  ("DGtal::Display3DFactory<Space,KSpace>::drawOrientedSurfelWithNormal( Display & display, const DGtal::KhalimskyCell<dim, TInteger> & k ): Unknown mode "+mode)=="");
1349 
1350  RealPoint rp = display.embedKS( k );
1351  const KSpace& K = display.space();
1352  bool xodd = K.sIsOpen( k, 0 );
1353  bool yodd = K.sIsOpen( k, 1 );
1354  bool zodd = K.sIsOpen( k, 2 );
1355  bool sign = K.sDirect( k, K.sOrthDir( k ) ); // tells the direction toward the inside
1356  display.addQuadFromSurfelCenterWithNormal
1357  ( RealPoint( rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 ) ),
1358  ! xodd, ! yodd, ! zodd, normalVector,
1359  false, !sign, enableDoubleFace );
1360 }
1361 // KhalimskyCell
1362 
1363 
1364 // SignedKhalimskyCell
1365 template <typename Space, typename KSpace>
1366 inline
1367 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1368  const typename KSpace::SCell & sk )
1369 {
1370 
1371  ASSERT(Space::dimension == 3);
1372  DGtal::Color fillColorSave = display.getFillColor();
1373  std::string mode = display.getMode( sk.className() );
1374  ASSERT((mode=="" || mode=="Highlighted" || mode=="Transparent" || mode=="Basic" || mode=="Illustration" || mode=="IllustrationCustomColor")||
1375  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::SignedKhalimskyCell<dim, TInteger> & sk ): Unknown mode "+mode)=="");
1376  // used to display surfels located at a same position.
1377  double factorVolSurfel=1.0;
1378  if(mode=="Highlighted")
1379  {
1380  factorVolSurfel = 1.2;
1381  display.setFillColor(DGtal::Color(255, 50, 50, 255));
1382  }else if(mode=="Transparent")
1383  {
1384  display.setFillColor(DGtal::Color(180, 180, 250, 25));
1385  }
1386 
1387  DGtal::Z3i::RealPoint rps = display.embedKS( sk );
1388  bool xodd = ( sk.preCell().coordinates[ 0 ] & 1 );
1389  bool yodd = ( sk.preCell().coordinates[ 1 ] & 1 );
1390  bool zodd = ( sk.preCell().coordinates[ 2 ] & 1 );
1391  unsigned int spaceDim= (xodd ? 1:0) + (yodd ? 1:0) + (zodd ? 1:0);
1392  // pointel
1393 
1394  switch (spaceDim)
1395  {
1396  case 0:
1397  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1398  {
1399  if( sk.preCell().positive)
1400  display.setFillColor(DGtal::Color(20, 20, 250, 255));
1401  else
1402  display.setFillColor(DGtal::Color(20, 20, 150, 255));
1403  }
1404  display.addBall(rps, 1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1405  break;
1406  case 1:
1407  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1408  {
1409  display.setFillColor( DGtal::Color(255, 50, 50, 255));
1410  }
1411  if (sk.preCell().positive)
1412  {
1413  display.addCone(DGtal::Z3i::RealPoint(rps[0]- (xodd? 0.5:0 ), rps[1]- (yodd? 0.5:0 ), rps[2]- (zodd? 0.5:0 )),
1414  DGtal::Z3i::RealPoint(rps[0]+ (xodd? 0.5:0 ), rps[1]+ (yodd? 0.5:0 ), rps[2]+ (zodd? 0.5:0 )));
1415  }
1416  else
1417  {
1418  display.addCone(DGtal::Z3i::RealPoint(rps[0]+ (xodd? 0.5:0 ), rps[1]+ (yodd? 0.5:0 ), rps[2]+ (zodd? 0.5:0 )),
1419  DGtal::Z3i::RealPoint(rps[0]- (xodd? 0.5:0 ),rps[1]- (yodd? 0.5:0 ), rps[2]- (zodd? 0.5:0 )));
1420  }
1421  break;
1422  case 2:
1423  if(mode=="Basic")
1424  {
1425  display.addQuadFromSurfelCenter(DGtal::Z3i::RealPoint(rps[0]+(xodd? 0:0.5 ), rps[1]+(yodd? 0:0.5 ), rps[2]+(zodd? 0:0.5 )),
1426  ! xodd, !yodd, !zodd );
1427  }else
1428  display.addPrism(DGtal::Z3i::RealPoint(rps[0]+(xodd? 0:0.5 ), rps[1]+(yodd? 0:0.5 ), rps[2]+(zodd? 0:0.5 )),
1429  ! xodd, !yodd, !zodd, factorVolSurfel,1.0, true, sk.preCell().positive );
1430  break;
1431  case 3:
1432  if(mode!="" && mode!="IllustrationCustomColor")
1433  {
1434  if( sk.preCell().positive)
1435  {
1436  display.setFillColor(DGtal::Color(200, 20, 20, 255));
1437  }else
1438  {
1439  display.setFillColor(DGtal::Color(20, 200, 20, 255));
1440  }
1441  }
1442  if(mode=="Illustration"|| mode=="IllustrationCustomColor")
1443  {
1444  //KSCube
1445  display.createNewCubeList();
1446  display.addCube(rps, 0.80);
1447  }else
1448  {
1449  display.createNewCubeList();
1450  display.addCube(rps, 0.90 );
1451  }
1452  break;
1453  }
1454  display.setFillColor(fillColorSave);
1455 }
1456 // SignedKhalimskyCell
1457 
1458 
1459 
1460 // Object
1461 template <typename Space, typename KSpace>
1462 template <typename TDigitalTopology, typename TDigitalSet>
1463 inline
1464 void DGtal::Display3DFactory<Space,KSpace>::drawWithAdjacencies( Display & display,
1465  const DGtal::Object<TDigitalTopology, TDigitalSet> & o )
1466 {
1467  typedef typename TDigitalSet::Point Point;
1468 
1469  typedef typename TDigitalSet::Domain Domain;
1470  typedef
1471  typename DigitalSetSelector < Domain,
1472  SMALL_DS + HIGH_ITER_DS >::Type SmallSet;
1473  typedef Object<TDigitalTopology, SmallSet> SmallObject;
1474 
1475  Point p;
1476  for (typename TDigitalSet::ConstIterator it = o.pointSet().begin();
1477  it != o.pointSet().end();
1478  ++it)
1479  {
1480  //Brute-force scan of the neighborhood.
1481  SmallObject neig = o.properNeighborhood(*it);
1482  for (typename SmallObject::DigitalSet::ConstIterator it2 = neig.pointSet().begin();
1483  it2 != neig.pointSet().end();
1484  ++it2)
1485  {
1486  p = (*it2) - (*it);
1487  draw(display, p, (*it));
1488  }
1489  }
1490 }
1491 
1492 template <typename Space, typename KSpace>
1493 template <typename TDigitalTopology, typename TDigitalSet>
1494 inline
1495 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1496  const DGtal::Object<TDigitalTopology, TDigitalSet> & o )
1497 {
1498  std::string mode = display.getMode( o.className() );
1499  if ( mode == "Basic" || mode == "" )
1500  draw( display, o.pointSet() );
1501  else if ( mode == "PavingTransp" )
1502  {
1503  drawAsPavingTransparent( display, o.pointSet() );
1504 
1505  }
1506  else if ( mode == "DrawAdjacencies" )
1507  {
1508  draw( display, o.pointSet() );
1509  drawWithAdjacencies( display, o );
1510  }
1511  else
1512  ASSERT(false && (("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::Object<TDigitalTopology, TDigitalSet> & o ): Unknown mode " + mode) == ""));
1513 }
1514 // Object
1515 
1516 
1517 // PointVector
1518 template <typename Space, typename KSpace>
1519 template<DGtal::Dimension dim, typename TComponent>
1520 inline
1521 void DGtal::Display3DFactory<Space,KSpace>::drawAsGrid( Display & display,
1522  const DGtal::PointVector<dim,TComponent> & p )
1523 {
1524  DGtal::Color fillColorSave = display.getFillColor();
1525  ASSERT(dim == 3);
1526  DGtal::Z3i::RealPoint rp = display.embed( p );
1527  display.setFillColor(display.getLineColor());
1528  display.addBall(rp,1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1529  display.setFillColor(fillColorSave);
1530 }
1531 
1532 template <typename Space, typename KSpace>
1533 template<DGtal::Dimension dim, typename TComponent>
1534 inline
1535 void DGtal::Display3DFactory<Space,KSpace>::drawAsPaving( Display & display,
1536  const DGtal::PointVector<dim,TComponent> & p )
1537 {
1538  ASSERT(dim == 3);
1539 
1540  DGtal::Z3i::RealPoint rp = display.embed( p );
1541  display.addCube(rp);
1542 }
1543 
1544 template <typename Space, typename KSpace>
1545 template<DGtal::Dimension dim, typename TComponent>
1546 inline
1547 void DGtal::Display3DFactory<Space,KSpace>::drawAsPavingWired( Display & display,
1548  const DGtal::PointVector<dim,TComponent> & p )
1549 {
1550  DGtal::Color lineColorSave = display.getLineColor();
1551  ASSERT(dim == 3);
1552 
1553  DGtal::Z3i::RealPoint rp = display.embed( p );
1554  display.addCube(rp);
1555  display.setLineColor(DGtal::Color(0,0,0));
1556  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]-0.5),
1557  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]-0.5));
1558  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]-0.5),
1559  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]-0.5));
1560  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]-0.5),
1561  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]-0.5));
1562  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]-0.5),
1563  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]-0.5));
1564 
1565  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]+0.5),
1566  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]+0.5));
1567  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]+0.5),
1568  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]+0.5));
1569  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]+0.5),
1570  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]+0.5));
1571  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]+0.5),
1572  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]+0.5));
1573 
1574  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]-0.5),
1575  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]+0.5));
1576  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]-0.5),
1577  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]+0.5));
1578  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]-0.5),
1579  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]+0.5));
1580  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]-0.5),
1581  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]+0.5));
1582  display.setLineColor(lineColorSave);
1583 }
1584 
1585 template <typename Space, typename KSpace>
1586 template<DGtal::Dimension dim, typename TComponent>
1587 inline
1588 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1589  const DGtal::PointVector<dim,TComponent> & p )
1590 {
1591  DGtal::Color fillColorSave = display.getFillColor();
1592  ASSERT(dim == 3);
1593 
1594  std::string mode = display.getMode( p.className() );
1595  ASSERT( (mode=="Paving" || mode=="Grid" || mode=="Both" || mode=="PavingWired"|| mode=="") );
1596 
1597  if ( mode == "Paving" || ( mode == "" ) )
1598  drawAsPaving( display, p );
1599  else if ( mode == "Grid" )
1600  drawAsGrid( display, p );
1601  else if ( ( mode == "Both" ) )
1602  {
1603  drawAsPaving( display, p );
1604  drawAsGrid( display, p );
1605  }
1606  else if( mode=="PavingWired")
1607  {
1608  drawAsPavingWired( display, p );
1609  }
1610  display.setFillColor(fillColorSave);
1611 }
1612 
1613 template <typename Space, typename KSpace>
1614 template<DGtal::Dimension dim, typename TComponent>
1615 inline
1616 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1617  const DGtal::PointVector<dim,TComponent> & p,
1618  const DGtal::PointVector<dim,TComponent> & aPoint )
1619 {
1620  ASSERT(dim == 3);
1621 
1622  DGtal::Z3i::RealPoint rp = display.embed(p );
1623  DGtal::Z3i::RealPoint rpa = display.embed(aPoint );
1624  display.addLine(rpa, DGtal::Z3i::RealPoint( rpa[0] + rp[0], rpa[1] + rp[1], rpa[2] + rp[2]));
1625 }
1626 // PointVector
1627 
1628 
1629 // GridCurve
1630 template <typename Space, typename KSpace>
1631 inline
1632 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1633  const DGtal::GridCurve<KSpace> & gc)
1634 {
1635  typedef typename DGtal::GridCurve<KSpace>::SCellsRange Range;
1636  Range r = gc.getSCellsRange();
1637  for ( typename Range::ConstIterator it = r.begin(), itEnd = r.end();
1638  it != itEnd; ++it )
1639  {
1640  draw( display, *it );
1641  }
1642 }
1643 // GridCurve
1644 
1645 // SCellsRange
1646 template <typename Space, typename KSpace>
1647 template <typename TIterator, typename TSCell>
1648 inline
1649 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1650  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::Identity, TSCell> & object )
1651 {
1652  typedef DGtal::ConstRangeAdapter<TIterator, DGtal::functors::Identity, TSCell> Range;
1653  typedef typename Range::ConstIterator ConstIterator;
1654 
1655  ConstIterator it ( object.begin() );
1656  ConstIterator itEnd ( object.end() );
1657  for( ; it != itEnd; ++it)
1658  {
1659  draw( display, *it);
1660  }
1661 }
1662 // SCellsRange
1663 
1664 // PointsRange
1665 template <typename Space, typename KSpace>
1666 template <typename TIterator>
1667 inline
1668 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1669  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::SCellToPoint<KSpace>, typename KSpace::Point> & object )
1670 {
1671  typedef ConstRangeAdapter<TIterator, functors::SCellToPoint<KSpace>, typename KSpace::Point> Range;
1672  typedef typename Range::ConstIterator ConstIterator;
1673 
1674  ConstIterator it ( object.begin() );
1675  ConstIterator itEnd ( object.end() );
1676  for( ; it != itEnd; ++it)
1677  {
1678  display << SetMode3D(it->className(),"Paving");
1679  display << *it;
1680  }
1681 }
1682 // PointsRange
1683 
1684 // MidPointsRange
1685 template <typename Space, typename KSpace>
1686 template <typename TIterator>
1687 inline
1688 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1689  const DGtal::ConstRangeAdapter<TIterator, CanonicSCellEmbedder<KSpace>,
1690  typename KSpace::Space::RealPoint> & object )
1691 {
1692  typedef typename KSpace::Space::RealPoint RPoint;
1693  typedef ConstRangeAdapter<TIterator, CanonicSCellEmbedder<KSpace>, RPoint > Range;
1694  typedef typename Range::ConstIterator ConstIterator;
1695 
1696  ConstIterator it ( object.begin() );
1697  ConstIterator itEnd ( object.end() );
1698  for( ; it != itEnd; ++it)
1699  {
1700  display << SetMode3D(it->className(),"Grid");
1701  display << *it;
1702  }
1703 }
1704 // MidPointsRange
1705 
1706 // ArrowsRange
1707 template <typename TSpace, typename TKSpace>
1708 template <typename TIterator>
1709 inline
1710 void DGtal::Display3DFactory<TSpace,TKSpace>::draw( Display & display,
1711  const DGtal::ConstRangeAdapter<TIterator, functors::SCellToArrow<KSpace>,
1712  std::pair<typename KSpace::Point, typename KSpace::Vector> > & object )
1713 {
1714  typedef typename KSpace::Point Point;
1715  typedef typename KSpace::Vector Vector;
1716  typedef std::pair<Point, Vector> Arrow;
1717  typedef ConstRangeAdapter<TIterator, functors::SCellToArrow<KSpace>, Arrow > Range;
1718  typedef typename Range::ConstIterator ConstIterator;
1719 
1720  ConstIterator it ( object.begin() );
1721  ConstIterator itEnd ( object.end() );
1722  for( ; it != itEnd; ++it)
1723  { //display the associated cell
1724  draw( display, *(it.base()) );
1725  }
1726 }
1727 // ArrowsRange
1728 
1729 // InnerPointsRange
1730 template <typename Space, typename KSpace>
1731 template <typename TIterator>
1732 inline
1733 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1734  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::SCellToInnerPoint<KSpace>, typename KSpace::Point> & object )
1735 {
1736  typedef ConstRangeAdapter<TIterator, DGtal::functors::SCellToInnerPoint<KSpace>, typename KSpace::Point> Range;
1737  typedef typename Range::ConstIterator ConstIterator;
1738 
1739  ConstIterator it ( object.begin() );
1740  ConstIterator itEnd ( object.end() );
1741  for( ; it != itEnd; ++it)
1742  {
1743  display << SetMode3D(it->className(),"Paving");
1744  display << CustomColors3D(Color(0, 0, 255,0),Color(0, 0, 200, 100));
1745  display << *it;
1746  }
1747 }
1748 // InnerPointsRange
1749 
1750 // OuterPointsRange
1751 template <typename Space, typename KSpace>
1752 template <typename TIterator>
1753 inline
1754 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1755  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::SCellToOuterPoint<KSpace>, typename KSpace::Point> & object )
1756 {
1757  typedef ConstRangeAdapter<TIterator, DGtal::functors::SCellToOuterPoint<KSpace>, typename KSpace::Point> Range;
1758  typedef typename Range::ConstIterator ConstIterator;
1759 
1760  ConstIterator it ( object.begin() );
1761  ConstIterator itEnd ( object.end() );
1762  for( ; it != itEnd; ++it)
1763  {
1764  display << SetMode3D(it->className(),"Paving");
1765  display << CustomColors3D(Color(0, 255, 0 ,0),Color(0, 200, 0, 100));
1766  display << *it;
1767  }
1768 }
1769 // OuterPointsRange
1770 
1771 // IncidentPointsRange
1772 template <typename Space, typename KSpace>
1773 template <typename TIterator>
1774 inline
1775 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1776  const DGtal::ConstRangeAdapter<TIterator, functors::SCellToIncidentPoints<KSpace>,
1777  std::pair<typename KSpace::Point, typename KSpace::Point > > & object )
1778 {
1779  typedef std::pair<typename KSpace::Point, typename KSpace::Point > Pair;
1780  typedef ConstRangeAdapter<TIterator, functors::SCellToIncidentPoints<KSpace>, Pair> Range;
1781  typedef typename Range::ConstIterator ConstIterator;
1782 
1783  ConstIterator it ( object.begin() );
1784  ConstIterator itEnd ( object.end() );
1785  for( ; it != itEnd; ++it)
1786  {
1787  Pair pair( *it );
1788  display << SetMode3D(pair.first.className(),"Paving");
1789  display << CustomColors3D(Color(0, 0, 255,0),Color(0, 0, 200, 100));
1790  display << pair.first;
1791  display << CustomColors3D(Color(0, 255, 0 ,0),Color(0, 200, 0, 100));
1792  display << pair.second;
1793  }
1794 }
1795 // IncidentPointsRange
1796 
1797 template <typename Space, typename KSpace>
1798 inline
1799 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1800  const DGtal::SetMode3D & sm3d )
1801 {
1802  if ( display.myModes[ sm3d.myClassname ] != sm3d.myMode )
1803  display.myModes[ sm3d.myClassname ] = sm3d.myMode;
1804 }
1805 
1806 template< typename Space, typename KSpace>
1807 inline
1808 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1809  const DGtal::CustomStyle3D & cs3d )
1810 {
1811  if (display.myStyles[ cs3d.myClassname ] != cs3d.myStyle )
1812  display.myStyles[ cs3d.myClassname ] = cs3d.myStyle;
1813 }
1814 
1815 template< typename Space, typename KSpace>
1816 inline
1817 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::CustomColors3D & cc3d )
1818 {
1819  display.setFillColor(cc3d.myFillColor);
1820  display.setLineColor(cc3d.myPenColor);
1821 }
1822 
1823 
1824 template< typename Space, typename KSpace>
1825 inline
1826 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1827  const DGtal::ClippingPlane & cl )
1828 {
1829  display.addClippingPlane(cl.myA, cl.myB, cl.myC, cl.myD, cl.myDrawPlane);
1830 }
1831 
1832 template< typename Space, typename KSpace>
1833 inline
1834 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::TransformedPrism & aTransformedPrism)
1835 {
1836 
1837  DGtal::Color fillColorSave = display.getFillColor();
1838  std::string mode = display.getMode( aTransformedPrism.mySurfel.className() );
1839  ASSERT((mode=="" || mode=="Highlighted" || mode=="Transparent" || mode=="Basic" || mode=="Illustration")||
1840  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::ShiftedKSSurfel & aTransformedPrism ): Unknown mode "+mode)=="");
1841  // used to display surfels located at a same position.
1842  double factorVolSurfel=1.0;
1843  if(mode=="Highlighted")
1844  {
1845  factorVolSurfel = 1.2;
1846  display.setFillColor(DGtal::Color(255, 50, 50, 255));
1847  }else if(mode=="Transparent")
1848  {
1849  display.setFillColor(DGtal::Color(180, 180, 250, 25));
1850  }else if(mode=="Basic")
1851  {
1852  // basicMode=true;
1853  }
1854  DGtal::Z3i::RealPoint rps = display.embedKS(aTransformedPrism );
1855 
1856  auto const& preSurfel = aTransformedPrism.mySurfel.preCell();
1857 
1858  bool xodd = ( preSurfel.coordinates[ 0 ] & 1 );
1859  bool yodd = ( preSurfel.coordinates[ 1 ] & 1 );
1860  bool zodd = ( preSurfel.coordinates[ 2 ] & 1 );
1861 
1862  unsigned int spaceDim= (xodd ? 1:0) + (yodd ? 1:0) + (zodd ? 1:0);
1863  ASSERT(spaceDim ==2 );
1864  boost::ignore_unused_variable_warning(spaceDim);
1865 
1866  //display.addSurfelPrism(rps[0], rps[1], rps[2],! xodd, !yodd, !zodd, factorVolSurfel, aTransformedSurfelPrism.mySizeFactor, true, aTransformedSurfelPrism.mySurfel.positive );
1867  display.addPrism(DGtal::Z3i::RealPoint(rps[0]+(xodd? 0:0.5 ), rps[1]+(yodd? 0:0.5 ), rps[2]+(zodd? 0:0.5 )),! xodd, !yodd, !zodd, factorVolSurfel,1.0, true, preSurfel.positive );
1868  display.setFillColor(fillColorSave);
1869 
1870 }
1871 
1872 //-----------------------------------------------------------------------------
1873 template< typename Space, typename KSpace>
1874 inline
1875 void
1876 DGtal::Display3DFactory<Space,KSpace>::
1877 draw( Display & display, const DGtal::SetName3D& aName3d )
1878 {
1879  // Simply sets the "OpenGL name" of class Display3D, so that it
1880  // names the next graphical structures with it.
1881  display.setName3d( aName3d.name );
1882 }
1883 //-----------------------------------------------------------------------------
1884 template< typename Space, typename KSpace>
1885 inline
1886 void
1887 DGtal::Display3DFactory<Space,KSpace>::
1888 draw( Display & display, const DGtal::SetSelectCallback3D& aFct )
1889 {
1890  display.setSelectCallback3D( aFct.myFct, aFct.myData, aFct.myMin, aFct.myMax );
1891 }
1892 
1893 // //
1894 ///////////////////////////////////////////////////////////////////////////////