DGtal 1.4.0
Loading...
Searching...
No Matches
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
42template <typename Space, typename KSpace>
43template <DGtal::Dimension dimEmbedded, DGtal::Dimension dimAmbient, typename TLinearAlgebraBackend, typename TInteger>
44inline
45void
46DGtal::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
69template <typename Space, typename KSpace>
70template <typename TCalculus, DGtal::Order order, DGtal::Duality duality>
71inline
72void
73DGtal::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
99template <typename Space, typename KSpace>
100template <typename Calculus, DGtal::Order order, DGtal::Duality duality, typename ColorMap>
101inline
102void
103DGtal::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
126template <typename Space, typename KSpace>
127template <typename Calculus, DGtal::Duality duality>
128void
129DGtal::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
157template <typename Space, typename KSpace>
158template <typename TV>
159inline
160void
161DGtal::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
211template <typename Space, typename KSpace>
212template <typename TPoint>
213inline
214void 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
222template <typename Space, typename KSpace>
223template <typename TPoint>
224inline
225void 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
272template <typename Space, typename KSpace>
273template <typename TIterator, typename TInteger, int connectivity>
274inline
275void 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
305template <typename Space, typename KSpace>
306template <typename TIterator, typename TInteger, int connectivity>
307inline
308void
309DGtal::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
434template <typename Space, typename KSpace>
435template <typename TIterator, typename TInteger, int connectivity>
436inline
437void 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
455template <typename Space, typename KSpace>
456template <typename TIterator, typename TInteger, int connectivity>
457inline
458void 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
488template <typename Space, typename KSpace>
489template <typename TIterator, typename TInteger, int connectivity>
490inline
491void
492DGtal::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
617template <typename Space, typename KSpace>
618template <typename TIterator, typename TInteger, int connectivity>
619inline
620void 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
637template <typename Space, typename KSpace>
638template<typename Domain, typename Compare>
639inline
640void 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
658template <typename Space, typename KSpace>
659template<typename Domain, typename Compare>
660inline
661void 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
678template <typename Space, typename KSpace>
679template<typename Domain, typename Compare>
680inline
681void 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
697template <typename Space, typename KSpace>
698template<typename Domain, typename Compare>
699inline
700void 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
724template <typename Space, typename KSpace>
725template<typename Domain, typename Container>
726inline
727void 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
744template <typename Space, typename KSpace>
745template<typename Domain, typename Container>
746inline
747void 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
764template <typename Space, typename KSpace>
765template<typename Domain, typename Container>
766inline
767void 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
784template <typename Space, typename KSpace>
785template<typename Domain, typename Container>
786inline
787void 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
811template <typename Space, typename KSpace>
812template<typename Domain>
813inline
814void 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
832template <typename Space, typename KSpace>
833template<typename Domain>
834inline
835void 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
853template <typename Space, typename KSpace>
854template<typename Domain>
855inline
856void 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
873template <typename Space, typename KSpace>
874template<typename Domain>
875inline
876void 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
900template <typename Space, typename KSpace>
901template <typename SpaceDom>
902inline
903void 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
1010template <typename Space, typename KSpace>
1011template <typename SpaceDom>
1012inline
1013void 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
1079template <typename Space, typename KSpace>
1080template <typename SpaceDom>
1081inline
1082void 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
1108template <typename Space, typename KSpace>
1109template <typename SpaceDom>
1110inline
1111void 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
1142template <typename Space, typename KSpace>
1143template <typename SpaceDom>
1144inline
1145void
1146DGtal::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
1209template <typename Space, typename KSpace>
1210inline
1211void 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
1290template <typename Space, typename KSpace>
1291inline
1292void 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
1317template <typename Space, typename KSpace>
1318inline
1319void 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
1345template <typename Space, typename KSpace>
1346inline
1347void 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
1441template <typename Space, typename KSpace>
1442template <typename TDigitalTopology, typename TDigitalSet>
1443inline
1444void 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
1472template <typename Space, typename KSpace>
1473template <typename TDigitalTopology, typename TDigitalSet>
1474inline
1475void 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
1498template <typename Space, typename KSpace>
1499template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1500inline
1501void 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
1512template <typename Space, typename KSpace>
1513template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1514inline
1515void 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
1524template <typename Space, typename KSpace>
1525template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1526inline
1527void 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
1565template <typename Space, typename KSpace>
1566template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1567inline
1568void 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
1593template <typename Space, typename KSpace>
1594template<DGtal::Dimension dim, typename TComponent1, typename TComponent2, typename TContainer1, typename TContainer2>
1595inline
1596void 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
1610template <typename Space, typename KSpace>
1611inline
1612void 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
1626template <typename Space, typename KSpace>
1627template <typename TIterator, typename TSCell>
1628inline
1629void 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
1645template <typename Space, typename KSpace>
1646template <typename TIterator>
1647inline
1648void 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
1665template <typename Space, typename KSpace>
1666template <typename TIterator>
1667inline
1668void 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
1687template <typename TSpace, typename TKSpace>
1688template <typename TIterator>
1689inline
1690void 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
1710template <typename Space, typename KSpace>
1711template <typename TIterator>
1712inline
1713void 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
1731template <typename Space, typename KSpace>
1732template <typename TIterator>
1733inline
1734void 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
1752template <typename Space, typename KSpace>
1753template <typename TIterator>
1754inline
1755void 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
1777template <typename Space, typename KSpace>
1778inline
1779void 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
1786template< typename Space, typename KSpace>
1787inline
1788void 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
1795template< typename Space, typename KSpace>
1796inline
1797void 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
1804template< typename Space, typename KSpace>
1805inline
1806void 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
1812template< typename Space, typename KSpace>
1813inline
1814void 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//-----------------------------------------------------------------------------
1853template< typename Space, typename KSpace>
1854inline
1855void
1856DGtal::Display3DFactory<Space,KSpace>::
1857draw( 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//-----------------------------------------------------------------------------
1864template< typename Space, typename KSpace>
1865inline
1866void
1867DGtal::Display3DFactory<Space,KSpace>::
1868draw( Display & display, const DGtal::SetSelectCallback3D& aFct )
1869{
1870 display.setSelectCallback3D( aFct.myFct, aFct.myData, aFct.myMin, aFct.myMax );
1871}
1872
1873// //
1874///////////////////////////////////////////////////////////////////////////////