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