DGtal  0.9.2
Board3DTo2D.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 Board3DTo2D.ih
19  * @author Martial Tola <http://liris.cnrs.fr/martial.tola/>
20  * @date mercredi 22 juin 2011
21  *
22  * @brief
23  *
24  * Implementation of inline methods defined in Board3DTo2D.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 // IMPLEMENTATION of inline methods.
31 ///////////////////////////////////////////////////////////////////////////////
32 
33 #include <limits>
34 
35 // Cairo includes
36 #if defined(__clang__)
37 #pragma clang diagnostic push
38 #pragma clang diagnostic ignored "-Wdocumentation"
39 #endif
40 #include <cairo.h>
41 #include <cairo-pdf.h>
42 #include <cairo-ps.h>
43 #include <cairo-svg.h>
44 #if defined(__clang__)
45 #pragma clang diagnostic pop
46 #endif
47 // Cairo includes
48 //////////////////////////////////////////////////////////////////////////////
49 #include <cstdlib>
50 #include "DGtal/io/CDrawableWithDisplay3D.h"
51 #include "DGtal/io/boards/CDrawableWithBoard3DTo2D.h"
52 #include "DGtal/io/Color.h"
53 #include "DGtal/io/boards/Board3DTo2DFactory.h"
54 
55 //////////////////////////////////////////////////////////////////////////////
56 
57 
58 ///////////////////////////////////////////////////////////////////////////////
59 // //
60 // //
61 ///////////////////////////////////////////////////////////////////////////////
62 
63 
64 ///////////////////////////////////////////////////////////////////////////////
65 // Implementation of inline methods //
66 
67 /**
68  * Set the default color for future drawing.
69  * @param aColor: a DGtal::Color (allow to set a trasnparency value).
70  *
71  **/
72 template < typename Space, typename KSpace>
73 inline
74 DGtal::Board3DTo2D<Space, KSpace> &
75 DGtal::Board3DTo2D<Space, KSpace>::operator<<(const DGtal::Color & aColor)
76 {
77  myDefaultColor=aColor;
78  return *this;
79 }
80 
81 
82 /**
83  * Draws the drawable [object] in this board. It should satisfy
84  * the concept CDrawableWithBoard3DTo2D, which requires for instance a
85  * method setStyle( Board3DTo2D & ).
86  *
87  * @param object any drawable object.
88  * @return a reference on 'this'.
89  */
90 template < typename Space, typename KSpace>
91 template <typename TDrawableWithBoard3DTo2D>
92 inline
93 DGtal::Board3DTo2D<Space, KSpace> &
94 DGtal::Board3DTo2D<Space, KSpace>::operator<<( const TDrawableWithBoard3DTo2D & object )
95 {
96  BOOST_CONCEPT_ASSERT((concepts::CDrawableWithBoard3DTo2D< TDrawableWithBoard3DTo2D, Space, KSpace>));
97 
98  DGtal::Board3DTo2DFactory<Space,KSpace>::draw(*this, object);
99  return *this;
100 }
101 
102 // //
103 ///////////////////////////////////////////////////////////////////////////////
104 
105 
106 ///////////////////////////////////////////////////////////////////////////////
107 // Standard services - public :
108 
109 /*!
110 * \brief Constructor.
111 */
112 template < typename Space, typename KSpace>
113 DGtal::Board3DTo2D<Space, KSpace>::Board3DTo2D()
114 {
115  init();
116 }
117 // //
118 ///////////////////////////////////////////////////////////////////////////////
119 
120 ///////////////////////////////////////////////////////////////////////////////
121 // Interface - public :
122 
123 /**
124 * Writes/Displays the object on an output stream.
125 * @param out the output stream where the object is written.
126 */
127 template < typename Space, typename KSpace>
128 void
129 DGtal::Board3DTo2D<Space, KSpace>::selfDisplay ( std::ostream & out ) const
130 {
131  out << "[Board3DTo2D]";
132 }
133 
134 /**
135 * Checks the validity/consistency of the object.
136 * @return 'true' if the object is valid, 'false' otherwise.
137 */
138 template < typename Space, typename KSpace>
139 bool
140 DGtal::Board3DTo2D<Space, KSpace>::isValid() const
141 {
142  return true;
143 }
144 
145 
146 /**
147 * Transpose a 4x4 matrix.
148 * @param tmat destination matrix.
149 * @param mat source matrix.
150 */
151 template < typename Space, typename KSpace>
152 void
153 DGtal::Board3DTo2D<Space, KSpace>::TransposeMt(double tmat[16], double mat[16])
154 {
155  tmat[0] = mat[0]; tmat[1] = mat[4]; tmat[2] = mat[8]; tmat[3] = mat[12];
156  tmat[4] = mat[1]; tmat[5] = mat[5]; tmat[6] = mat[9]; tmat[7] = mat[13];
157  tmat[8] = mat[2]; tmat[9] = mat[6]; tmat[10] = mat[10]; tmat[11] = mat[14];
158  tmat[12] = mat[3]; tmat[13] = mat[7]; tmat[14] = mat[11]; tmat[15] = mat[15];
159 }
160 
161 /**
162 * Multiply a 3d vector by a 4x4 matrix.
163 * @param v destination vector.
164 * @param mat source matrix.
165 * @param b source vector.
166 */
167 template < typename Space, typename KSpace>
168 void
169 DGtal::Board3DTo2D<Space, KSpace>::MulMt(double v[4], double mat[16], double b[4])
170 {
171  v[0] = mat[0] * b[0] + mat[1] * b[1] + mat[2] * b[2] + mat[3] * b[3];
172  v[1] = mat[4] * b[0] + mat[5] * b[1] + mat[6] * b[2] + mat[7] * b[3];
173  v[2] = mat[8] * b[0] + mat[9] * b[1] + mat[10] * b[2] + mat[11] * b[3];
174  v[3] = mat[12] * b[0] + mat[13] * b[1] + mat[14] * b[2] + mat[15] * b[3];
175 }
176 
177 /**
178 * Compute 4x4 LookAt matrix.
179 * @param mat destination matrix.
180 * @param eyex x position of eye.
181 * @param eyey y position of eye.
182 * @param eyez z position of eye.
183 * @param dirx x direction of eye.
184 * @param diry y direction of eye.
185 * @param dirz z director of eye.
186 * @param upx x coordinate of up-vector.
187 * @param upy y coordinate of up-vector.
188 * @param upz z coordinate of up-vector.
189 */
190 template < typename Space, typename KSpace>
191 void
192 DGtal::Board3DTo2D<Space, KSpace>::LookAtMt(double mat[16],
193 double eyex, double eyey, double eyez,
194 double dirx, double diry, double dirz,
195 double upx, double upy, double upz)
196 {
197  double up[3]; up[0]= upx; up[1]= upy; up[2]= upz;
198 
199  double z[3]; z[0]= -dirx; z[1]= -diry; z[2]= -dirz; Display3D<Space,KSpace>::normalize(z);
200  double x[3]; Display3D<Space,KSpace>::cross (x, up, z); Display3D<Space,KSpace>::normalize(x);
201  double y[3]; Display3D<Space,KSpace>::cross (y, z, x); Display3D<Space,KSpace>::normalize(y);
202 
203  double m[16];
204  m[0] = x[0]; m[1] = x[1]; m[2] = x[2]; m[3] = 0;
205  m[4] = y[0]; m[5] = y[1]; m[6] = y[2]; m[7] = 0;
206  m[8] = z[0]; m[9] = z[1]; m[10] = z[2]; m[11] = 0;
207  m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
208 
209  double e[4]; e[0]= -eyex; e[1]= -eyey; e[2]= -eyez; e[3]= 1;
210  double eyePrime[4]; MulMt(eyePrime, m, e);
211 
212  TransposeMt(mat, m);
213  mat[12] = eyePrime[0]; mat[13] = eyePrime[1]; mat[14] = eyePrime[2];
214 }
215 
216 /**
217 * Precompute 4x4 projection matrix for 3D->2D projection.
218 */
219 template < typename Space, typename KSpace>
220 void DGtal::Board3DTo2D<Space, KSpace>::precompute_projection_matrix()
221 {
222  // Projection: from qglviewer
223  /*const double f = 1.0/tan(fieldOfView()/2.0);
224 projectionMatrix_[0] = f/aspectRatio();
225 projectionMatrix_[5] = f;
226 projectionMatrix_[10] = (ZNear + ZFar) / (ZNear - ZFar);
227 projectionMatrix_[11] = -1.0;
228 projectionMatrix_[14] = 2.0 * ZNear * ZFar / (ZNear - ZFar);
229 projectionMatrix_[15] = 0.0;
230 // same as gluPerspective( 180.0*fieldOfView()/M_PI, aspectRatio(), zNear(), zFar() );*/
231 
232  double fieldOfView = M_PI/4.;
233  double f = 1.0/tan(fieldOfView/2.0);
234  double aspectRatio = (double)Viewport[2]/Viewport[3];
235 
236  double Projection[16] = { f/aspectRatio, 0.00, 0.00, 0.00,
237  0.00, f, 0.00, 0.00,
238  0.00, 0.00, (ZNear + ZFar) / (ZNear - ZFar), -1.00,
239  0.00, 0.00, 2.0 * ZNear * ZFar / (ZNear - ZFar), 0.00 };
240 
241  double Modelview[16];
242  LookAtMt(Modelview,
243  camera_position[0], camera_position[1], camera_position[2],
244  camera_direction[0], camera_direction[1], camera_direction[2],
245  camera_upVector[0], camera_upVector[1], camera_upVector[2]);
246 
247  for (unsigned short m=0; m<4; ++m)
248  {
249  for (unsigned short l=0; l<4; ++l)
250  {
251  double sum = 0.0;
252  for (unsigned short k=0; k<4; ++k)
253  sum += Projection[l+4*k]*Modelview[k+4*m];
254  matrix[l+4*m] = sum;
255  }
256  }
257 }
258 
259 /**
260 * Project a 3d point (3D->2D).
261 * @param x3d x position of the 3d point.
262 * @param y3d y position of the 3d point.
263 * @param z3d z position of the 3d point.
264 * @param x2d x destination projection position of the 2d point.
265 * @param y2d y destination projection position of the 2d point.
266 */
267 template < typename Space, typename KSpace>
268 void DGtal::Board3DTo2D<Space, KSpace>::project(double x3d, double y3d, double z3d, double &x2d, double &y2d)
269 {
270  double v[4], vs[4];
271  v[0]=x3d; v[1]=y3d; v[2]=z3d; v[3]=1.0;
272 
273  vs[0]=matrix[0 ]*v[0] + matrix[4 ]*v[1] + matrix[8 ]*v[2] + matrix[12 ]*v[3];
274  vs[1]=matrix[1 ]*v[0] + matrix[5 ]*v[1] + matrix[9 ]*v[2] + matrix[13 ]*v[3];
275  vs[2]=matrix[2 ]*v[0] + matrix[6 ]*v[1] + matrix[10]*v[2] + matrix[14 ]*v[3];
276  vs[3]=matrix[3 ]*v[0] + matrix[7 ]*v[1] + matrix[11]*v[2] + matrix[15 ]*v[3];
277 
278  vs[0] /= vs[3];
279  vs[1] /= vs[3];
280  vs[2] /= vs[3];
281 
282  vs[0] = vs[0] * 0.5 + 0.5;
283  vs[1] = vs[1] * 0.5 + 0.5;
284  vs[2] = vs[2] * 0.5 + 0.5;
285 
286  vs[0] = vs[0] * Viewport[2] + Viewport[0];
287  vs[1] = vs[1] * Viewport[3] + Viewport[1];
288 
289  x2d = vs[0];
290  y2d = Viewport[3]-vs[1];
291 }
292 
293 /**
294 * Save a Cairo image.
295 * @param filename filename of the image to save.
296 * @param type type of the image to save (CairoPDF, CairoPNG, CairoPS, CairoEPS, CairoSVG).
297 * @param bWidth width of the image to save.
298 * @param bHeight height of the image to save.
299 */
300 template < typename Space, typename KSpace>
301 void
302 DGtal::Board3DTo2D<Space, KSpace>::saveCairo(const char *filename, CairoType type, int bWidth, int bHeight)
303 {
304  for(unsigned int i =0; i< Board3DTo2D<Space, KSpace>::myClippingPlaneList.size(); i++)
305  trace.info() << "-> ClippingPlane not implemented in Board3DTo2D" << std::endl;
306 
307  Viewport[0] = 0; Viewport[1] = 0; Viewport[2] = bWidth; Viewport[3] = bHeight;
308  precompute_projection_matrix();
309 
310  cairo_surface_t *surface;
311  cairo_t *cr;
312 
313  switch (type)
314  {
315  case CairoPDF:
316  surface = cairo_pdf_surface_create (filename, Viewport[2], Viewport[3]); break;
317  case CairoPS:
318  surface = cairo_ps_surface_create (filename, Viewport[2], Viewport[3]); break;
319  case CairoEPS:
320  surface = cairo_ps_surface_create (filename, Viewport[2], Viewport[3]);
321  cairo_ps_surface_set_eps(surface, true); break;
322  case CairoSVG:
323  surface = cairo_svg_surface_create (filename, Viewport[2], Viewport[3]); break;
324  case CairoPNG:
325  default:
326  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, Viewport[2], Viewport[3]);
327  }
328 
329  cr = cairo_create (surface);
330 
331  // Fill the background with gray
332  cairo_set_source_rgba (cr, .3, .3, .3, 1.);
333  cairo_rectangle (cr, 0, 0, Viewport[2], Viewport[3]);
334  cairo_fill (cr);
335 
336  // Draw the shapes
337 
338  // myBallSetList
339  for(unsigned int i=0; i<Board3DTo2D<Space, KSpace>::myBallSetList.size(); i++)
340  {
341  for (typename std::vector<typename Board3DTo2D<Space, KSpace>::BallD3D>::iterator s_it = Board3DTo2D<Space, KSpace>::myBallSetList.at(i).begin();
342  s_it != Board3DTo2D<Space, KSpace>::myBallSetList.at(i).end();
343  ++s_it)
344  {
345  {
346  cairo_save (cr);
347 
348  cairo_set_source_rgba (cr, (*s_it).color.red()/255.0, (*s_it).color.green()/255.0,
349  (*s_it).color.blue()/255.0, (*s_it).color.alpha()/255.0);
350  cairo_set_line_width (cr, 1.); // arbitraire car non set
351 
352  double x1, y1, x2, y2, x3, y3, x4, y4;
353  //double width=(*s_it).size/120.; // arbitraire
354  double width=0.05; // arbitraire
355  // TODO:
356  /*double distCam =sqrt((camera_position[0]-centerS.x)*(camera_position[0]-centerS.x)+
357 (camera_position[1]-centerS.y)*(camera_position[1]-centerS.y)+
358 (camera_position[2]-centerS.z)*(camera_position[2]-centerS.z));*/
359 
360  //z+
361  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]+width, x1, y1);
362  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
363  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]+width, x3, y3);
364  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]+width, x4, y4);
365  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr); Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
366  //z-
367  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]-width, x1, y1);
368  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]-width, x2, y2);
369  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]-width, x3, y3);
370  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
371  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr); Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
372  //x+
373  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]+width, x1, y1);
374  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
375  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]-width, x3, y3);
376  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
377  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr); Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
378  //x-
379  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]+width, x1, y1);
380  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
381  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]-width, x3, y3);
382  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
383  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr); Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
384  //y+
385  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]+width, x1, y1);
386  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
387  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]-width, x3, y3);
388  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]-width, x4, y4);
389  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr); Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
390  //y-
391  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]+width, x1, y1);
392  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]+width, x2, y2);
393  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]-width, x3, y3);
394  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
395  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr); Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
396 
397  cairo_restore (cr);
398  }
399  }
400  }
401 
402  // myLineSetList
403  for(unsigned int i=0; i<Board3DTo2D<Space, KSpace>::myLineSetList.size(); i++)
404  {
405  for (typename std::vector<typename Board3DTo2D<Space, KSpace>::LineD3D>::iterator s_it = Board3DTo2D<Space, KSpace>::myLineSetList.at(i).begin();
406  s_it != Board3DTo2D<Space, KSpace>::myLineSetList.at(i).end();
407  ++s_it)
408  {
409  {
410  cairo_save (cr);
411 
412  cairo_set_source_rgba (cr, (*s_it).color.red()/255.0, (*s_it).color.green()/255.0,
413  (*s_it).color.blue()/255.0, (*s_it).color.alpha()/255.0);
414 
415  double x1, y1;
416  double x2, y2;
417  project((*s_it).point1[0], (*s_it).point1[1], (*s_it).point1[2], x1, y1);
418  project((*s_it).point2[0], (*s_it).point2[1], (*s_it).point2[2], x2, y2);
419  cairo_move_to (cr, x1, y1);
420  cairo_line_to (cr, x2, y2);
421 
422  //cairo_set_line_width (cr, (*s_it).width);
423  cairo_set_line_width (cr, 1.); // arbitraire car non set
424 
425  cairo_stroke (cr);
426 
427  cairo_restore (cr);
428  }
429  }
430  }
431 
432  // myCubeSetList
433  for(typename Board3DTo2D<Space, KSpace>::CubesMap::const_iterator it = Board3DTo2D<Space, KSpace>::myCubesMap.begin();
434  it != Board3DTo2D<Space, KSpace>::myCubesMap.end(); it++)
435  {
436  for (typename std::vector< typename Board3DTo2D<Space, KSpace>::CubeD3D>::const_iterator s_it = it->second.begin();
437  s_it != it->second.end(); ++s_it)
438  {
439  {
440  cairo_save (cr);
441 
442  if (Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode")
443  cairo_set_source_rgba (cr, (*s_it).color.red()/255.0, (*s_it).color.green()/255.0,
444  (*s_it).color.blue()/255.0, (*s_it).color.alpha()/(255.0*1.75)); // *1.75 arbitraire
445  else
446  cairo_set_source_rgba (cr, (*s_it).color.red()/255.0, (*s_it).color.green()/255.0,
447  (*s_it).color.blue()/255.0, (*s_it).color.alpha()/(255.0*0.75)); // *0.75 arbitraire
448 
449  cairo_set_line_width (cr, 1.); // arbitraire car non set
450 
451  double x1, y1, x2, y2, x3, y3, x4, y4;
452  double width=(*s_it).width;
453 
454  //z+
455  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]+width, x1, y1);
456  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
457  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]+width, x3, y3);
458  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]+width, x4, y4);
459  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
460  //z-
461  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]-width, x1, y1);
462  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]-width, x2, y2);
463  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]-width, x3, y3);
464  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
465  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
466  //x+
467  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]+width, x1, y1);
468  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
469  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]-width, x3, y3);
470  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
471  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
472  //x-
473  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]+width, x1, y1);
474  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
475  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]-width, x3, y3);
476  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
477  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
478  //y+
479  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]+width, x1, y1);
480  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]+width, x2, y2);
481  project((*s_it).center[0]+width, (*s_it).center[1]+width, (*s_it).center[2]-width, x3, y3);
482  project((*s_it).center[0]-width, (*s_it).center[1]+width, (*s_it).center[2]-width, x4, y4);
483  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
484  //y-
485  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]+width, x1, y1);
486  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]+width, x2, y2);
487  project((*s_it).center[0]+width, (*s_it).center[1]-width, (*s_it).center[2]-width, x3, y3);
488  project((*s_it).center[0]-width, (*s_it).center[1]-width, (*s_it).center[2]-width, x4, y4);
489  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
490 
491  cairo_restore (cr);
492  }
493  }
494  }
495 
496  // for(typename Display3D<Space, KSpace>::QuadsMap::iterator it = myQuadsMap.begin(); it != myQuadsMap.end(); it++)
497  if ( myQuadsMap.begin() != myQuadsMap.end() )
498  trace.info() << "-> Quad not YET implemented in Board3DTo2D" << std::endl;
499 
500  // Drawing all Khalimsky Space Cells
501 
502  // Prism (from updateList)
503  for (typename std::vector<typename Board3DTo2D<Space, KSpace>::QuadD3D>::iterator s_it =Board3DTo2D<Space, KSpace>:: myPrismList.begin();
504  s_it != Board3DTo2D<Space, KSpace>::myPrismList.end();
505  ++s_it)
506  {
507  {
508  cairo_save (cr);
509 
510  if (Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode")
511  cairo_set_source_rgba (cr, (*s_it).color.red()/255.0, (*s_it).color.green()/255.0,
512  (*s_it).color.blue()/255.0, (*s_it).color.alpha()/(255.0*3.75)); // *3.75 arbitraire
513  else
514  cairo_set_source_rgba (cr, (*s_it).color.red()/255.0, (*s_it).color.green()/255.0,
515  (*s_it).color.blue()/255.0, (*s_it).color.alpha()/(255.0*0.75)); // *0.75 arbitraire
516 
517  cairo_set_line_width (cr, 1.); // arbitraire car non set
518 
519  double x1, y1, x2, y2, x3, y3, x4, y4;
520 
521  project((*s_it).point1[0], (*s_it).point1[1], (*s_it).point1[2], x1, y1);
522  project((*s_it).point2[0], (*s_it).point2[1], (*s_it).point2[2], x2, y2);
523  project((*s_it).point3[0], (*s_it).point3[1], (*s_it).point3[2], x3, y3);
524  project((*s_it).point4[0], (*s_it).point4[1], (*s_it).point4[2], x4, y4);
525  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr); Board3DTo2D<Space, KSpace>::myModes["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
526 
527  cairo_restore (cr);
528  }
529  }
530 
531  /*
532  // KSLinel
533  for(unsigned int i=0; i< myKSLinelList.size();i++)
534  {
535  //if (!myKSLinelList.at(i).isSigned) // for the moment, same for Signed or NonSigned
536  {
537  {
538  cairo_save (cr);
539 
540  cairo_set_source_rgba (cr, myKSLinelList.at(i).R/255.0, myKSLinelList.at(i).G/255.0, myKSLinelList.at(i).B/255.0, myKSLinelList.at(i).T/255.0);
541  cairo_set_line_width (cr, 4.); // arbitraire car non set
542 
543  double x1, y1, x2, y2;
544 
545  project(myKSLinelList.at(i).x1, myKSLinelList.at(i).y1, myKSLinelList.at(i).z1, x1, y1);
546  project(myKSLinelList.at(i).x2, myKSLinelList.at(i).y2, myKSLinelList.at(i).z2, x2, y2);
547  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_close_path (cr); cairo_stroke (cr);
548 
549  cairo_restore (cr);
550  }
551  }
552  }
553 
554 
555  // KSBallel
556  for(std::vector<ballD3D>::iterator it=myKSBallelList.begin(); it != myKSBallelList.end(); it++)
557  {
558  //if (!it->isSigned) // for the moment, same for Signed or NonSigned
559  {
560  {
561  cairo_save (cr);
562 
563  cairo_set_source_rgba (cr, it->R/255.0, it->G/255.0, it->B/255.0, it->T/255.0);
564  cairo_set_line_width (cr, 1.); // arbitraire car non set
565 
566  double x1, y1, x2, y2, x3, y3, x4, y4;
567  //double width=it->size/120.; // arbitraire
568  double width=0.04; // arbitraire
569 
570  //z+
571  project(it->x-width, it->y+width, it->z+width, x1, y1);
572  project(it->x+width, it->y+width, it->z+width, x2, y2);
573  project(it->x+width, it->y-width, it->z+width, x3, y3);
574  project(it->x-width, it->y-width, it->z+width, x4, y4);
575  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
576  //z-
577  project(it->x-width, it->y+width, it->z-width, x1, y1);
578  project(it->x+width, it->y+width, it->z-width, x2, y2);
579  project(it->x+width, it->y-width, it->z-width, x3, y3);
580  project(it->x-width, it->y-width, it->z-width, x4, y4);
581  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
582  //x+
583  project(it->x+width, it->y-width, it->z+width, x1, y1);
584  project(it->x+width, it->y+width, it->z+width, x2, y2);
585  project(it->x+width, it->y+width, it->z-width, x3, y3);
586  project(it->x+width, it->y-width, it->z-width, x4, y4);
587  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
588  //x-
589  project(it->x-width, it->y-width, it->z+width, x1, y1);
590  project(it->x-width, it->y+width, it->z+width, x2, y2);
591  project(it->x-width, it->y+width, it->z-width, x3, y3);
592  project(it->x-width, it->y-width, it->z-width, x4, y4);
593  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
594  //y+
595  project(it->x-width, it->y+width, it->z+width, x1, y1);
596  project(it->x+width, it->y+width, it->z+width, x2, y2);
597  project(it->x+width, it->y+width, it->z-width, x3, y3);
598  project(it->x-width, it->y+width, it->z-width, x4, y4);
599  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
600  //y-
601  project(it->x-width, it->y-width, it->z+width, x1, y1);
602  project(it->x+width, it->y-width, it->z+width, x2, y2);
603  project(it->x+width, it->y-width, it->z-width, x3, y3);
604  project(it->x-width, it->y-width, it->z-width, x4, y4);
605  cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_line_to (cr, x3, y3); cairo_line_to (cr, x4, y4); cairo_line_to (cr, x1, y1); cairo_close_path (cr);Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]=="SolidMode"?cairo_fill (cr):cairo_stroke (cr);
606 
607  cairo_restore (cr);
608  }
609  }
610  }
611  */
612 
613  if (type==CairoPNG)
614  cairo_surface_write_to_png (surface, filename);
615 
616  cairo_destroy (cr);
617  cairo_surface_destroy (surface);
618 }
619 
620 /*!
621 * \brief init function (should be in Constructor).
622 */
623 template < typename Space, typename KSpace>
624 void
625 DGtal::Board3DTo2D<Space, KSpace>::init()
626 {
627  Board3DTo2D<Space, KSpace>::createNewCubeList();
628 
629  std::vector<typename Board3DTo2D<Space, KSpace>::LineD3D> listeLine;
630  Board3DTo2D<Space, KSpace>::myLineSetList.push_back(listeLine);
631 
632  std::vector<typename Board3DTo2D<Space, KSpace>::BallD3D> listeBall;
633  Board3DTo2D<Space, KSpace>::myBallSetList.push_back(listeBall);
634 
635  Board3DTo2D<Space, KSpace>::myCurrentFillColor = DGtal::Color (220, 220, 220);
636  Board3DTo2D<Space, KSpace>::myCurrentLineColor = DGtal::Color (22, 22, 222, 50);
637 
638  /*createNewCubeList();
639 std::vector<cubeD3D> aKSCubeList;*/
640 
641  Board3DTo2D<Space, KSpace>::myDefaultColor= DGtal::Color(255, 255, 255);
642 
643  //
644 
645  camera_position[0] = 5.000000; camera_position[1] = 5.000000; camera_position[2] = 29.893368;
646  camera_direction[0] = 0.000000; camera_direction[1] = 0.000000; camera_direction[2] = -1.000000;
647  camera_upVector[0] = 0.000000; camera_upVector[1] = 1.000000; camera_upVector[2] = 0.000000;
648 
649  ZNear = 0.001;
650  ZFar = 100.0;
651  //ZNear = 4.578200;
652  //ZFar = 22.578199;
653 
654  Board3DTo2D<Space, KSpace>::myModes ["Board3DTo2D"]="SolidMode";
655 }
656 
657 // //
658 ///////////////////////////////////////////////////////////////////////////////