DGtal  0.9.4.1
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  size_t 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  ASSERT(Space::dimension == 3 || "drawAsGrid-NOT-YET-IMPLEMENTED-in-ND");
1018 
1019  if (Space::dimension == 3)
1020  {
1021  // Face XY
1022  for (auto z = h.myLowerBound[2]; z <= h.myUpperBound[2]; z++)
1023  {
1024  for (auto x = h.myLowerBound[0]; x <= h.myUpperBound[0]; x++)
1025  {
1026  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, h.myLowerBound[1], z) );
1027  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, h.myUpperBound[1], z) );
1028 
1029  display.addLine( rp1, rp2);
1030  }
1031  for (auto y = h.myLowerBound[1]; y <= h.myUpperBound[1]; y++)
1032  {
1033  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(h.myLowerBound[0], y, z) );
1034  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(h.myUpperBound[0], y, z) );
1035 
1036  display.addLine( rp1, rp2 );
1037  }
1038  }
1039 
1040  // Faces XZ
1041  for (auto y = h.myLowerBound[1]; y <= h.myUpperBound[1]; y++)
1042  {
1043  for (auto x = h.myLowerBound[0]; x <= h.myUpperBound[0]; x++)
1044  {
1045  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, y, h.myLowerBound[2]) );
1046  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, y, h.myLowerBound[2]) );
1047 
1048  display.addLine( rp1, rp2);
1049  }
1050  for (auto z = h.myLowerBound[2]; z <= h.myUpperBound[2]; z++)
1051  {
1052  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(h.myLowerBound[0], y, z) );
1053  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(h.myUpperBound[0], y, z) );
1054 
1055  display.addLine( rp1, rp2);
1056  }
1057  }
1058 
1059  // Faces YZ
1060  for (auto x = h.myLowerBound[0]; x <= h.myUpperBound[0]; x++)
1061  {
1062  for (auto y = h.myLowerBound[1]; y <= h.myUpperBound[1]; y++)
1063  {
1064  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, y, h.myLowerBound[2]) );
1065  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, y, h.myUpperBound[2]) );
1066 
1067  display.addLine( rp1, rp2);
1068  }
1069  for (auto z = h.myLowerBound[2]; z <= h.myUpperBound[2]; z++)
1070  {
1071  DGtal::Z3i::RealPoint rp1 = display.embed( DGtal::Z3i::Point(x, h.myLowerBound[1], z) );
1072  DGtal::Z3i::RealPoint rp2 = display.embed( DGtal::Z3i::Point(x, h.myLowerBound[1], z) );
1073 
1074  display.addLine( rp1, rp2);
1075  }
1076  }
1077  }
1078 }
1079 
1080 template <typename Space, typename KSpace>
1081 template <typename SpaceDom>
1082 inline
1083 void DGtal::Display3DFactory<Space,KSpace>::drawAsPavingBalls( Display & display,
1084  const DGtal::HyperRectDomain<SpaceDom> & h )
1085 {
1086  DGtal::Color fillColorSave = display.getFillColor();
1087 
1088  ASSERT(Space::dimension == 3 || "drawAsPavingPoints-NOT-YET-IMPLEMENTED-in-ND");
1089  if (Space::dimension == 3)
1090  {
1091  // Face XY
1092  for (auto z = h.myLowerBound[2]; z <= h.myUpperBound[2]; z++)
1093  {
1094  for (auto x = h.myLowerBound[0]; x <= h.myUpperBound[0]; x++)
1095  {
1096 
1097  for (auto y = h.myLowerBound[1]; y <= h.myUpperBound[1]; y++)
1098  {
1099  DGtal::Z3i::RealPoint rp = display.embed( DGtal::Z3i::Point(x, y, z) );
1100  display.setFillColor(DGtal::Color(255, 0 ,0));
1101  display.addBall(rp,1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1102  }
1103  }
1104  }
1105  }
1106  display.setFillColor(fillColorSave);
1107 }
1108 
1109 template <typename Space, typename KSpace>
1110 template <typename SpaceDom>
1111 inline
1112 void DGtal::Display3DFactory<Space,KSpace>::drawAsPaving( Display & display,
1113  const DGtal::HyperRectDomain<SpaceDom> & h )
1114 {
1115  DGtal::Color fillColorSave = display.getFillColor();
1116 
1117  ASSERT(Space::dimension == 3 || "drawAsPaving-NOT-YET-IMPLEMENTED-in-ND");
1118 
1119  if (Space::dimension == 3)
1120  {
1121  // Face XY
1122  for (auto z = h.myLowerBound[2]; z <= h.myUpperBound[2]; z++)
1123  {
1124  for (auto x = h.myLowerBound[0]; x <= h.myUpperBound[0]; x++)
1125  {
1126  for (auto y = h.myLowerBound[1]; y <= h.myUpperBound[1]; y++)
1127  {
1128  DGtal::Z3i::RealPoint rp = display.embed( DGtal::Z3i::Point(x, y, z) );
1129  rp[0]+=0.5;
1130  rp[1]+=0.5;
1131  rp[2]+=0.5;
1132  //a transparent color for the paving
1133  display.setFillColor( Color(255, 255 ,255, 15));
1134  display.addCube(rp, 1.0);
1135  }
1136  }
1137  }
1138  }
1139  display.setFillColor(fillColorSave);
1140 }
1141 
1142 
1143 template <typename Space, typename KSpace>
1144 template <typename SpaceDom>
1145 inline
1146 void
1147 DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::HyperRectDomain<SpaceDom> & aDomain )
1148 {
1149  std::string mode = display.getMode( aDomain.className() );
1150 
1151  ASSERT((mode=="" || mode=="Grid" || mode=="Paving"|| mode=="PavingPoints"|| mode=="PavingGrids" ||
1152  mode=="BoundingBox")||
1153  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display3DD<Space, KSpace> & display, const DGtal::HyperRectDomain<Space> & aDomain ): Unknown mode "+mode)=="");
1154 
1155  /*
1156  if ( mode == "BoundingBox" )
1157  {
1158  display.createNewLineList(aDomain.className());
1159  drawAsBoundingBox( display, aDomain );
1160  }else if( ( mode == "" ) || (mode == "Grid"))
1161  {
1162  display.createNewLineList(aDomain.className());
1163  drawAsGrid( display, aDomain );
1164  }
1165  else if ( mode == "Paving" )
1166  {
1167  display.createNewCubeList( aDomain.className());
1168  }
1169  */
1170 
1171  ASSERT((Space::dimension==3)|| (Space::dimension==2));
1172  ASSERT((Space::dimension!=3) || (mode=="" || mode=="Grid" || mode=="Paving"|| mode=="PavingPoints"|| mode=="PavingGrids" ||
1173  mode=="BoundingBox")||
1174  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::HyperRectDomain<Space> & aDomain ): Unknown mode "+mode)=="");
1175  ASSERT((Space::dimension!=2) || (mode=="" || mode=="BoundingBox" || mode=="Grid") ||
1176  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::HyperRectDomain<Space> & aDomain ): Unknown mode "+mode)=="");
1177 
1178  if(Space::dimension == 2)
1179  {
1180  if (mode=="")
1181  mode="BoundingBox";
1182  }else if ( mode == "BoundingBox" )
1183  {
1184  display.createNewLineList(aDomain.className());
1185  drawAsBoundingBox( display, aDomain );
1186  }else if(( mode == "" ) || (mode == "Grid"))
1187  {
1188  display.createNewLineList(aDomain.className());
1189  drawAsGrid( display, aDomain );
1190  } else if ( mode == "Paving" )
1191  {
1192  display.createNewCubeList();
1193  drawAsPaving( display, aDomain );
1194  } else if ( mode == "PavingPoints" )
1195  {
1196  display.createNewBallList(aDomain.className());
1197  drawAsPavingBalls( display, aDomain );
1198  }else if ( mode == "PavingGrids" )
1199  {
1200  display.createNewLineList(aDomain.className());
1201  display.createNewCubeList( );
1202  drawAsGrid( display, aDomain );
1203  drawAsPaving( display, aDomain );
1204  }
1205 }
1206 // HyperRectDomain
1207 
1208 
1209 // KhalimskyCell
1210 template <typename Space, typename KSpace>
1211 inline
1212 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1213  const typename KSpace::Cell & k )
1214 {
1215  ASSERT(Space::dimension == 3);
1216  DGtal::Color fillColorSave = display.getFillColor();
1217  std::string mode = display.getMode( k.className() );
1218  ASSERT((mode=="" || mode=="Highlighted" || mode=="Transparent"|| mode=="Basic"|| mode=="Illustration"||mode=="IllustrationCustomColor")||
1219  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::KhalimskyCell<dim, TInteger> & k ): Unknown mode "+mode)=="");
1220  // used to display surfels located at a same position.
1221  double factorVolSurfel=1.0;
1222  if(mode=="Highlighted")
1223  {
1224  factorVolSurfel = 1.1;
1225  display.setFillColor(DGtal::Color(255, 50, 50, 255));
1226  }else if(mode=="Transparent")
1227  {
1228  display.setFillColor(DGtal::Color(180, 180, 250, 25));
1229  }
1230 
1231  DGtal::Z3i::RealPoint rp = display.embedK( k );
1232  bool xodd = ( NumberTraits<typename KSpace::Integer>::castToInt64_t(k.preCell().coordinates[ 0 ]) & 1 );
1233  bool yodd = ( NumberTraits<typename KSpace::Integer>::castToInt64_t(k.preCell().coordinates[ 1 ]) & 1 );
1234  bool zodd = ( NumberTraits<typename KSpace::Integer>::castToInt64_t(k.preCell().coordinates[ 2 ]) & 1 );
1235  unsigned int spaceDim= (xodd ? 1:0) + (yodd ? 1:0) + (zodd ? 1:0);
1236 
1237  switch (spaceDim) {
1238  case 0:
1239 
1240  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1241  {
1242  display.setFillColor(DGtal::Color(200, 200, 20, 255));
1243  }
1244 
1245  display.addBall(rp, 1.0/static_cast<double>(POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1246  break;
1247  case 1:
1248  if(mode!=""&& mode!="Basic" && mode!="IllustrationCustomColor")
1249  {
1250  display.setFillColor(DGtal::Color(255, 255, 50, 255));
1251  }
1252 
1253 
1254  display.addCylinder(DGtal::Z3i::RealPoint(rp[0]- (xodd? 0.5:0 ), rp[1]- (yodd? 0.5:0 ), rp[2]- (zodd? 0.5:0 )),
1255  DGtal::Z3i::RealPoint(rp[0]+ (xodd? 0.5:0 ), rp[1]+ (yodd? 0.5:0 ), rp[2]+ (zodd? 0.5:0 )));
1256  break;
1257  case 2:
1258  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1259  {
1260  display.setFillColor(DGtal::Color(20, 200, 200, 255));
1261  }
1262  if(mode=="Basic")
1263  {
1264  display.addQuadFromSurfelCenter(DGtal::Z3i::RealPoint(rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 )),
1265  ! xodd, !yodd, !zodd);
1266  }
1267  else
1268  display.addPrism(DGtal::Z3i::RealPoint(rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 )),
1269  ! xodd, !yodd, !zodd, factorVolSurfel,1.0, false, false);
1270  break;
1271  case 3:
1272  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1273  {
1274  display.setFillColor(DGtal::Color(255, 180, 250, 255));
1275  }
1276  if(mode=="Illustration"|| mode=="IllustrationCustomColor")
1277  {
1278  display.createNewCubeList();
1279  display.addCube(rp,0.80);
1280  }else{
1281  display.createNewCubeList();
1282  display.addCube(rp,0.90);
1283  }
1284  break;
1285  }
1286  display.setFillColor(fillColorSave);
1287 }
1288 // KhalimskyCell
1289 
1290 // KhalimskyCell
1291 template <typename Space, typename KSpace>
1292 inline
1293 void DGtal::Display3DFactory<Space,KSpace>::drawUnorientedSurfelWithNormal( Display & display,
1294  const typename KSpace::Cell & k ,
1295  const RealVector &normalVector,
1296  const bool enableDoubleFace)
1297 {
1298  ASSERT(Space::dimension == 3);
1299  DGtal::Color fillColorSave = display.getFillColor();
1300  std::string mode = display.getMode( k.className() );
1301  ASSERT(( mode=="Basic")|| ( mode=="") ||
1302  ("DGtal::Display3DFactory<Space,KSpace>::drawUnorientedSurfelWithNormal( Display & display, const DGtal::KhalimskyCell<dim, TInteger> & k ): Unknown mode "+mode)=="");
1303 
1304  RealPoint rp = display.embedK( k );
1305  const KSpace& K = display.space();
1306  bool xodd = K.uIsOpen( k, 0 );
1307  bool yodd = K.uIsOpen( k, 1 );
1308  bool zodd = K.uIsOpen( k, 2 );
1309  display.addQuadFromSurfelCenterWithNormal
1310  ( RealPoint( rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 ) ),
1311  ! xodd, ! yodd, ! zodd, normalVector,
1312  true, true, //reorientation enabled
1313  enableDoubleFace);
1314 }
1315 // KhalimskyCell
1316 
1317 // KhalimskyCell
1318 template <typename Space, typename KSpace>
1319 inline
1320 void DGtal::Display3DFactory<Space,KSpace>::drawOrientedSurfelWithNormal( Display & display,
1321  const typename KSpace::SCell & k ,
1322  const RealVector &normalVector,
1323  const bool enableDoubleFace)
1324 {
1325  ASSERT(Space::dimension == 3);
1326  DGtal::Color fillColorSave = display.getFillColor();
1327  std::string mode = display.getMode( k.className() );
1328  ASSERT(( mode=="Basic")|| ( mode=="") ||
1329  ("DGtal::Display3DFactory<Space,KSpace>::drawOrientedSurfelWithNormal( Display & display, const DGtal::KhalimskyCell<dim, TInteger> & k ): Unknown mode "+mode)=="");
1330 
1331  RealPoint rp = display.embedKS( k );
1332  const KSpace& K = display.space();
1333  bool xodd = K.sIsOpen( k, 0 );
1334  bool yodd = K.sIsOpen( k, 1 );
1335  bool zodd = K.sIsOpen( k, 2 );
1336  bool sign = K.sDirect( k, K.sOrthDir( k ) ); // tells the direction toward the inside
1337  display.addQuadFromSurfelCenterWithNormal
1338  ( RealPoint( rp[0]+(xodd? 0:0.5 ), rp[1]+(yodd? 0:0.5 ), rp[2]+(zodd? 0:0.5 ) ),
1339  ! xodd, ! yodd, ! zodd, normalVector,
1340  false, !sign, enableDoubleFace );
1341 }
1342 // KhalimskyCell
1343 
1344 
1345 // SignedKhalimskyCell
1346 template <typename Space, typename KSpace>
1347 inline
1348 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1349  const typename KSpace::SCell & sk )
1350 {
1351 
1352  ASSERT(Space::dimension == 3);
1353  DGtal::Color fillColorSave = display.getFillColor();
1354  std::string mode = display.getMode( sk.className() );
1355  ASSERT((mode=="" || mode=="Highlighted" || mode=="Transparent" || mode=="Basic" || mode=="Illustration" || mode=="IllustrationCustomColor")||
1356  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::SignedKhalimskyCell<dim, TInteger> & sk ): Unknown mode "+mode)=="");
1357  // used to display surfels located at a same position.
1358  double factorVolSurfel=1.0;
1359  if(mode=="Highlighted")
1360  {
1361  factorVolSurfel = 1.2;
1362  display.setFillColor(DGtal::Color(255, 50, 50, 255));
1363  }else if(mode=="Transparent")
1364  {
1365  display.setFillColor(DGtal::Color(180, 180, 250, 25));
1366  }
1367 
1368  DGtal::Z3i::RealPoint rps = display.embedKS( sk );
1369  bool xodd = ( sk.preCell().coordinates[ 0 ] & 1 );
1370  bool yodd = ( sk.preCell().coordinates[ 1 ] & 1 );
1371  bool zodd = ( sk.preCell().coordinates[ 2 ] & 1 );
1372  unsigned int spaceDim= (xodd ? 1:0) + (yodd ? 1:0) + (zodd ? 1:0);
1373  // pointel
1374 
1375  switch (spaceDim)
1376  {
1377  case 0:
1378  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1379  {
1380  if( sk.preCell().positive)
1381  display.setFillColor(DGtal::Color(20, 20, 250, 255));
1382  else
1383  display.setFillColor(DGtal::Color(20, 20, 150, 255));
1384  }
1385  display.addBall(rps, 1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1386  break;
1387  case 1:
1388  if(mode!="" && mode!="Basic" && mode!="IllustrationCustomColor")
1389  {
1390  display.setFillColor( DGtal::Color(255, 50, 50, 255));
1391  }
1392  if (sk.preCell().positive)
1393  {
1394  display.addCone(DGtal::Z3i::RealPoint(rps[0]- (xodd? 0.5:0 ), rps[1]- (yodd? 0.5:0 ), rps[2]- (zodd? 0.5:0 )),
1395  DGtal::Z3i::RealPoint(rps[0]+ (xodd? 0.5:0 ), rps[1]+ (yodd? 0.5:0 ), rps[2]+ (zodd? 0.5:0 )));
1396  }
1397  else
1398  {
1399  display.addCone(DGtal::Z3i::RealPoint(rps[0]+ (xodd? 0.5:0 ), rps[1]+ (yodd? 0.5:0 ), rps[2]+ (zodd? 0.5:0 )),
1400  DGtal::Z3i::RealPoint(rps[0]- (xodd? 0.5:0 ),rps[1]- (yodd? 0.5:0 ), rps[2]- (zodd? 0.5:0 )));
1401  }
1402  break;
1403  case 2:
1404  if(mode=="Basic")
1405  {
1406  display.addQuadFromSurfelCenter(DGtal::Z3i::RealPoint(rps[0]+(xodd? 0:0.5 ), rps[1]+(yodd? 0:0.5 ), rps[2]+(zodd? 0:0.5 )),
1407  ! xodd, !yodd, !zodd );
1408  }else
1409  display.addPrism(DGtal::Z3i::RealPoint(rps[0]+(xodd? 0:0.5 ), rps[1]+(yodd? 0:0.5 ), rps[2]+(zodd? 0:0.5 )),
1410  ! xodd, !yodd, !zodd, factorVolSurfel,1.0, true, sk.preCell().positive );
1411  break;
1412  case 3:
1413  if(mode!="" && mode!="IllustrationCustomColor")
1414  {
1415  if( sk.preCell().positive)
1416  {
1417  display.setFillColor(DGtal::Color(200, 20, 20, 255));
1418  }else
1419  {
1420  display.setFillColor(DGtal::Color(20, 200, 20, 255));
1421  }
1422  }
1423  if(mode=="Illustration"|| mode=="IllustrationCustomColor")
1424  {
1425  //KSCube
1426  display.createNewCubeList();
1427  display.addCube(rps, 0.80);
1428  }else
1429  {
1430  display.createNewCubeList();
1431  display.addCube(rps, 0.90 );
1432  }
1433  break;
1434  }
1435  display.setFillColor(fillColorSave);
1436 }
1437 // SignedKhalimskyCell
1438 
1439 
1440 
1441 // Object
1442 template <typename Space, typename KSpace>
1443 template <typename TDigitalTopology, typename TDigitalSet>
1444 inline
1445 void DGtal::Display3DFactory<Space,KSpace>::drawWithAdjacencies( Display & display,
1446  const DGtal::Object<TDigitalTopology, TDigitalSet> & o )
1447 {
1448  typedef typename TDigitalSet::Point Point;
1449 
1450  typedef typename TDigitalSet::Domain Domain;
1451  typedef
1452  typename DigitalSetSelector < Domain,
1453  SMALL_DS + HIGH_ITER_DS >::Type SmallSet;
1454  typedef Object<TDigitalTopology, SmallSet> SmallObject;
1455 
1456  Point p;
1457  for (typename TDigitalSet::ConstIterator it = o.pointSet().begin();
1458  it != o.pointSet().end();
1459  ++it)
1460  {
1461  //Brute-force scan of the neighborhood.
1462  SmallObject neig = o.properNeighborhood(*it);
1463  for (typename SmallObject::DigitalSet::ConstIterator it2 = neig.pointSet().begin();
1464  it2 != neig.pointSet().end();
1465  ++it2)
1466  {
1467  p = (*it2) - (*it);
1468  draw(display, p, (*it));
1469  }
1470  }
1471 }
1472 
1473 template <typename Space, typename KSpace>
1474 template <typename TDigitalTopology, typename TDigitalSet>
1475 inline
1476 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1477  const DGtal::Object<TDigitalTopology, TDigitalSet> & o )
1478 {
1479  std::string mode = display.getMode( o.className() );
1480  if ( mode == "Basic" || mode == "" )
1481  draw( display, o.pointSet() );
1482  else if ( mode == "PavingTransp" )
1483  {
1484  drawAsPavingTransparent( display, o.pointSet() );
1485 
1486  }
1487  else if ( mode == "DrawAdjacencies" )
1488  {
1489  draw( display, o.pointSet() );
1490  drawWithAdjacencies( display, o );
1491  }
1492  else
1493  ASSERT(false && (("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::Object<TDigitalTopology, TDigitalSet> & o ): Unknown mode " + mode) == ""));
1494 }
1495 // Object
1496 
1497 
1498 // PointVector
1499 template <typename Space, typename KSpace>
1500 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1501 inline
1502 void DGtal::Display3DFactory<Space,KSpace>::drawAsGrid( Display & display,
1503  const DGtal::PointVector<dim, TComponent, TContainer> & p )
1504 {
1505  DGtal::Color fillColorSave = display.getFillColor();
1506  ASSERT(dim == 3);
1507  DGtal::Z3i::RealPoint rp = display.embed( p );
1508  display.setFillColor(display.getLineColor());
1509  display.addBall(rp,1.0/static_cast<double>( POINT_AS_BALL_RADIUS), POINT_AS_BALL_RES);
1510  display.setFillColor(fillColorSave);
1511 }
1512 
1513 template <typename Space, typename KSpace>
1514 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1515 inline
1516 void DGtal::Display3DFactory<Space,KSpace>::drawAsPaving( Display & display,
1517  const DGtal::PointVector<dim, TComponent, TContainer> & p )
1518 {
1519  ASSERT(dim == 3);
1520 
1521  DGtal::Z3i::RealPoint rp = display.embed( p );
1522  display.addCube(rp);
1523 }
1524 
1525 template <typename Space, typename KSpace>
1526 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1527 inline
1528 void DGtal::Display3DFactory<Space,KSpace>::drawAsPavingWired( Display & display,
1529  const DGtal::PointVector<dim, TComponent, TContainer> & p )
1530 {
1531  DGtal::Color lineColorSave = display.getLineColor();
1532  ASSERT(dim == 3);
1533 
1534  DGtal::Z3i::RealPoint rp = display.embed( p );
1535  display.addCube(rp);
1536  display.setLineColor(DGtal::Color(0,0,0));
1537  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]-0.5),
1538  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]-0.5));
1539  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]-0.5),
1540  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]-0.5));
1541  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]-0.5),
1542  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]-0.5));
1543  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]-0.5),
1544  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]-0.5));
1545 
1546  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]+0.5),
1547  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]+0.5));
1548  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]+0.5),
1549  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]+0.5));
1550  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]+0.5),
1551  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]+0.5));
1552  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]+0.5),
1553  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]+0.5));
1554 
1555  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]-0.5),
1556  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]-0.5, rp[2]+0.5));
1557  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]-0.5),
1558  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]-0.5, rp[2]+0.5));
1559  display.addLine(DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]-0.5),
1560  DGtal::Z3i::RealPoint(rp[0]+0.5, rp[1]+0.5, rp[2]+0.5));
1561  display.addLine(DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]-0.5),
1562  DGtal::Z3i::RealPoint(rp[0]-0.5, rp[1]+0.5, rp[2]+0.5));
1563  display.setLineColor(lineColorSave);
1564 }
1565 
1566 template <typename Space, typename KSpace>
1567 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1568 inline
1569 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1570  const DGtal::PointVector<dim, TComponent, TContainer> & p )
1571 {
1572  DGtal::Color fillColorSave = display.getFillColor();
1573  ASSERT(dim == 3);
1574 
1575  std::string mode = display.getMode( p.className() );
1576  ASSERT( (mode=="Paving" || mode=="Grid" || mode=="Both" || mode=="PavingWired"|| mode=="") );
1577 
1578  if ( mode == "Paving" || ( mode == "" ) )
1579  drawAsPaving( display, p );
1580  else if ( mode == "Grid" )
1581  drawAsGrid( display, p );
1582  else if ( ( mode == "Both" ) )
1583  {
1584  drawAsPaving( display, p );
1585  drawAsGrid( display, p );
1586  }
1587  else if( mode=="PavingWired")
1588  {
1589  drawAsPavingWired( display, p );
1590  }
1591  display.setFillColor(fillColorSave);
1592 }
1593 
1594 template <typename Space, typename KSpace>
1595 template<DGtal::Dimension dim, typename TComponent1, typename TComponent2, typename TContainer1, typename TContainer2>
1596 inline
1597 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1598  const DGtal::PointVector<dim, TComponent1, TContainer1> & p,
1599  const DGtal::PointVector<dim, TComponent2, TContainer2> & aPoint )
1600 {
1601  ASSERT(dim == 3);
1602 
1603  DGtal::Z3i::RealPoint rp = display.embed(p );
1604  DGtal::Z3i::RealPoint rpa = display.embed(aPoint );
1605  display.addLine(rpa, DGtal::Z3i::RealPoint( rpa[0] + rp[0], rpa[1] + rp[1], rpa[2] + rp[2]));
1606 }
1607 // PointVector
1608 
1609 
1610 // GridCurve
1611 template <typename Space, typename KSpace>
1612 inline
1613 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1614  const DGtal::GridCurve<KSpace> & gc)
1615 {
1616  typedef typename DGtal::GridCurve<KSpace>::SCellsRange Range;
1617  Range r = gc.getSCellsRange();
1618  for ( typename Range::ConstIterator it = r.begin(), itEnd = r.end();
1619  it != itEnd; ++it )
1620  {
1621  draw( display, *it );
1622  }
1623 }
1624 // GridCurve
1625 
1626 // SCellsRange
1627 template <typename Space, typename KSpace>
1628 template <typename TIterator, typename TSCell>
1629 inline
1630 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1631  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::Identity, TSCell> & object )
1632 {
1633  typedef DGtal::ConstRangeAdapter<TIterator, DGtal::functors::Identity, TSCell> Range;
1634  typedef typename Range::ConstIterator ConstIterator;
1635 
1636  ConstIterator it ( object.begin() );
1637  ConstIterator itEnd ( object.end() );
1638  for( ; it != itEnd; ++it)
1639  {
1640  draw( display, *it);
1641  }
1642 }
1643 // SCellsRange
1644 
1645 // PointsRange
1646 template <typename Space, typename KSpace>
1647 template <typename TIterator>
1648 inline
1649 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1650  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::SCellToPoint<KSpace>, typename KSpace::Point> & object )
1651 {
1652  typedef ConstRangeAdapter<TIterator, functors::SCellToPoint<KSpace>, typename KSpace::Point> 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  display << SetMode3D(it->className(),"Paving");
1660  display << *it;
1661  }
1662 }
1663 // PointsRange
1664 
1665 // MidPointsRange
1666 template <typename Space, typename KSpace>
1667 template <typename TIterator>
1668 inline
1669 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1670  const DGtal::ConstRangeAdapter<TIterator, CanonicSCellEmbedder<KSpace>,
1671  typename KSpace::Space::RealPoint> & object )
1672 {
1673  typedef typename KSpace::Space::RealPoint RPoint;
1674  typedef ConstRangeAdapter<TIterator, CanonicSCellEmbedder<KSpace>, RPoint > Range;
1675  typedef typename Range::ConstIterator ConstIterator;
1676 
1677  ConstIterator it ( object.begin() );
1678  ConstIterator itEnd ( object.end() );
1679  for( ; it != itEnd; ++it)
1680  {
1681  display << SetMode3D(it->className(),"Grid");
1682  display << *it;
1683  }
1684 }
1685 // MidPointsRange
1686 
1687 // ArrowsRange
1688 template <typename TSpace, typename TKSpace>
1689 template <typename TIterator>
1690 inline
1691 void DGtal::Display3DFactory<TSpace,TKSpace>::draw( Display & display,
1692  const DGtal::ConstRangeAdapter<TIterator, functors::SCellToArrow<KSpace>,
1693  std::pair<typename KSpace::Point, typename KSpace::Vector> > & object )
1694 {
1695  typedef typename KSpace::Point Point;
1696  typedef typename KSpace::Vector Vector;
1697  typedef std::pair<Point, Vector> Arrow;
1698  typedef ConstRangeAdapter<TIterator, functors::SCellToArrow<KSpace>, Arrow > Range;
1699  typedef typename Range::ConstIterator ConstIterator;
1700 
1701  ConstIterator it ( object.begin() );
1702  ConstIterator itEnd ( object.end() );
1703  for( ; it != itEnd; ++it)
1704  { //display the associated cell
1705  draw( display, *(it.base()) );
1706  }
1707 }
1708 // ArrowsRange
1709 
1710 // InnerPointsRange
1711 template <typename Space, typename KSpace>
1712 template <typename TIterator>
1713 inline
1714 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1715  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::SCellToInnerPoint<KSpace>, typename KSpace::Point> & object )
1716 {
1717  typedef ConstRangeAdapter<TIterator, DGtal::functors::SCellToInnerPoint<KSpace>, typename KSpace::Point> Range;
1718  typedef typename Range::ConstIterator ConstIterator;
1719 
1720  ConstIterator it ( object.begin() );
1721  ConstIterator itEnd ( object.end() );
1722  for( ; it != itEnd; ++it)
1723  {
1724  display << SetMode3D(it->className(),"Paving");
1725  display << CustomColors3D(Color(0, 0, 255,0),Color(0, 0, 200, 100));
1726  display << *it;
1727  }
1728 }
1729 // InnerPointsRange
1730 
1731 // OuterPointsRange
1732 template <typename Space, typename KSpace>
1733 template <typename TIterator>
1734 inline
1735 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1736  const DGtal::ConstRangeAdapter<TIterator, DGtal::functors::SCellToOuterPoint<KSpace>, typename KSpace::Point> & object )
1737 {
1738  typedef ConstRangeAdapter<TIterator, DGtal::functors::SCellToOuterPoint<KSpace>, typename KSpace::Point> Range;
1739  typedef typename Range::ConstIterator ConstIterator;
1740 
1741  ConstIterator it ( object.begin() );
1742  ConstIterator itEnd ( object.end() );
1743  for( ; it != itEnd; ++it)
1744  {
1745  display << SetMode3D(it->className(),"Paving");
1746  display << CustomColors3D(Color(0, 255, 0 ,0),Color(0, 200, 0, 100));
1747  display << *it;
1748  }
1749 }
1750 // OuterPointsRange
1751 
1752 // IncidentPointsRange
1753 template <typename Space, typename KSpace>
1754 template <typename TIterator>
1755 inline
1756 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1757  const DGtal::ConstRangeAdapter<TIterator, functors::SCellToIncidentPoints<KSpace>,
1758  std::pair<typename KSpace::Point, typename KSpace::Point > > & object )
1759 {
1760  typedef std::pair<typename KSpace::Point, typename KSpace::Point > Pair;
1761  typedef ConstRangeAdapter<TIterator, functors::SCellToIncidentPoints<KSpace>, Pair> Range;
1762  typedef typename Range::ConstIterator ConstIterator;
1763 
1764  ConstIterator it ( object.begin() );
1765  ConstIterator itEnd ( object.end() );
1766  for( ; it != itEnd; ++it)
1767  {
1768  Pair pair( *it );
1769  display << SetMode3D(pair.first.className(),"Paving");
1770  display << CustomColors3D(Color(0, 0, 255,0),Color(0, 0, 200, 100));
1771  display << pair.first;
1772  display << CustomColors3D(Color(0, 255, 0 ,0),Color(0, 200, 0, 100));
1773  display << pair.second;
1774  }
1775 }
1776 // IncidentPointsRange
1777 
1778 template <typename Space, typename KSpace>
1779 inline
1780 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1781  const DGtal::SetMode3D & sm3d )
1782 {
1783  if ( display.myModes[ sm3d.myClassname ] != sm3d.myMode )
1784  display.myModes[ sm3d.myClassname ] = sm3d.myMode;
1785 }
1786 
1787 template< typename Space, typename KSpace>
1788 inline
1789 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1790  const DGtal::CustomStyle3D & cs3d )
1791 {
1792  if (display.myStyles[ cs3d.myClassname ] != cs3d.myStyle )
1793  display.myStyles[ cs3d.myClassname ] = cs3d.myStyle;
1794 }
1795 
1796 template< typename Space, typename KSpace>
1797 inline
1798 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::CustomColors3D & cc3d )
1799 {
1800  display.setFillColor(cc3d.myFillColor);
1801  display.setLineColor(cc3d.myPenColor);
1802 }
1803 
1804 
1805 template< typename Space, typename KSpace>
1806 inline
1807 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display,
1808  const DGtal::ClippingPlane & cl )
1809 {
1810  display.addClippingPlane(cl.myA, cl.myB, cl.myC, cl.myD, cl.myDrawPlane);
1811 }
1812 
1813 template< typename Space, typename KSpace>
1814 inline
1815 void DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::TransformedPrism & aTransformedPrism)
1816 {
1817 
1818  DGtal::Color fillColorSave = display.getFillColor();
1819  std::string mode = display.getMode( aTransformedPrism.mySurfel.className() );
1820  ASSERT((mode=="" || mode=="Highlighted" || mode=="Transparent" || mode=="Basic" || mode=="Illustration")||
1821  ("DGtal::Display3DFactory<Space,KSpace>::draw( Display & display, const DGtal::ShiftedKSSurfel & aTransformedPrism ): Unknown mode "+mode)=="");
1822  // used to display surfels located at a same position.
1823  double factorVolSurfel=1.0;
1824  if(mode=="Highlighted")
1825  {
1826  factorVolSurfel = 1.2;
1827  display.setFillColor(DGtal::Color(255, 50, 50, 255));
1828  }else if(mode=="Transparent")
1829  {
1830  display.setFillColor(DGtal::Color(180, 180, 250, 25));
1831  }else if(mode=="Basic")
1832  {
1833  // basicMode=true;
1834  }
1835  DGtal::Z3i::RealPoint rps = display.embedKS(aTransformedPrism );
1836 
1837  auto const& preSurfel = aTransformedPrism.mySurfel.preCell();
1838 
1839  bool xodd = ( preSurfel.coordinates[ 0 ] & 1 );
1840  bool yodd = ( preSurfel.coordinates[ 1 ] & 1 );
1841  bool zodd = ( preSurfel.coordinates[ 2 ] & 1 );
1842 
1843  unsigned int spaceDim= (xodd ? 1:0) + (yodd ? 1:0) + (zodd ? 1:0);
1844  ASSERT(spaceDim ==2 );
1845  boost::ignore_unused_variable_warning(spaceDim);
1846 
1847  //display.addSurfelPrism(rps[0], rps[1], rps[2],! xodd, !yodd, !zodd, factorVolSurfel, aTransformedSurfelPrism.mySizeFactor, true, aTransformedSurfelPrism.mySurfel.positive );
1848  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 );
1849  display.setFillColor(fillColorSave);
1850 
1851 }
1852 
1853 //-----------------------------------------------------------------------------
1854 template< typename Space, typename KSpace>
1855 inline
1856 void
1857 DGtal::Display3DFactory<Space,KSpace>::
1858 draw( Display & display, const DGtal::SetName3D& aName3d )
1859 {
1860  // Simply sets the "OpenGL name" of class Display3D, so that it
1861  // names the next graphical structures with it.
1862  display.setName3d( aName3d.name );
1863 }
1864 //-----------------------------------------------------------------------------
1865 template< typename Space, typename KSpace>
1866 inline
1867 void
1868 DGtal::Display3DFactory<Space,KSpace>::
1869 draw( Display & display, const DGtal::SetSelectCallback3D& aFct )
1870 {
1871  display.setSelectCallback3D( aFct.myFct, aFct.myData, aFct.myMin, aFct.myMax );
1872 }
1873 
1874 // //
1875 ///////////////////////////////////////////////////////////////////////////////