DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Display3D.ih
1 
29 
30 // IMPLEMENTATION of inline methods.
32 
34 #include <cstdlib>
35 #include "DGtal/io/CDrawableWithDisplay3D.h"
36 
37 #include "DGtal/io/Display3DFactory.h"
38 #include "DGtal/io/writers/MeshWriter.h"
40 
41 
42 
44 // Implementation of inline methods //
45 
46 
48 // Implementation of inline functions and external operators //
49 
50 
51 
58 static inline
59 void DGtal::cross (double dst[3], double srcA[3], double srcB[3])
60 {
61  dst[0] = srcA[1]*srcB[2] - srcA[2]*srcB[1];
62  dst[1] = srcA[2]*srcB[0] - srcA[0]*srcB[2];
63  dst[2] = srcA[0]*srcB[1] - srcA[1]*srcB[0];
64 }
65 
70 static inline
71 void
72 DGtal::normalize (double vec[3])
73 {
74  const double squaredLen = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
75  vec[0] /= sqrt (squaredLen);
76  vec[1] /= sqrt (squaredLen);
77  vec[2] /= sqrt (squaredLen);
78 }
79 
80 inline
81 void
83 {
84  myCurrentFillColor=aColor;
85 }
86 
87 
88 inline
89 void
91 {
92  myCurrentLineColor=aColor;
93 }
94 
95 
96 inline
99 {
100  return myCurrentLineColor;
101 }
102 
103 inline
106 {
107  return myCurrentFillColor;
108 }
109 
110 
111 inline
112 std::string
113 DGtal::Display3D::getMode( const std::string & objectName ) const
114 {
115  ModeMapping::const_iterator itm = myModes.find( objectName );
116  return itm == myModes.end() ? "" : itm->second;
117 }
118 
119 
120 
121 inline
122 void
124 {
125  std::vector< voxelD3D > v;
126  myVoxelSetList.push_back(v);
127  myListVoxelDepthTest.push_back(depthTest);
128 
129 }
130 
131 
132 
133 inline
134 void
136 {
137  std::vector< pointD3D > v;
138  myPointSetList.push_back(v);
139 }
140 
141 
142 inline
143 void
145 {
146  std::vector< lineD3D > v;
147  myLineSetList.push_back(v);
148 }
149 
150 
151 
152 
153 
154 
155 inline
156 void
158  DGtal::Color aColor, double width, bool withWire)
159 {
160  updateBoundingBox((double)x, (double)y, (double)z);
161  voxelD3D v;
162  v.x=(int)x;
163  v.y=(int)y;
164  v.z=(int)z;
165  v.R=aColor.red();
166  v.G=aColor.green();
167  v.B=aColor.blue();
168  v.T=aColor.alpha();
169  v.width=width;
170  if(withWire)
171  {
172  addLine(x-0.5, y-0.5, z-0.5, x+0.5, y-0.5, z-0.5, DGtal::Color(0,0,0), 2);
173  addLine(x+0.5, y-0.5, z-0.5, x+0.5, y+0.5, z-0.5, DGtal::Color(0,0,0), 2);
174  addLine(x+0.5, y+0.5, z-0.5, x-0.5, y+0.5, z-0.5, DGtal::Color(0,0,0), 2);
175  addLine(x-0.5, y+0.5, z-0.5, x-0.5, y-0.5, z-0.5, DGtal::Color(0,0,0), 2);
176 
177  addLine(x-0.5, y-0.5, z+0.5, x+0.5, y-0.5, z+0.5, DGtal::Color(0,0,0), 2);
178  addLine(x+0.5, y-0.5, z+0.5, x+0.5, y+0.5, z+0.5, DGtal::Color(0,0,0), 2);
179  addLine(x+0.5, y+0.5, z+0.5, x-0.5, y+0.5, z+0.5, DGtal::Color(0,0,0), 2);
180  addLine(x-0.5, y+0.5, z+0.5, x-0.5, y-0.5, z+0.5, DGtal::Color(0,0,0), 2);
181 
182  addLine(x-0.5, y-0.5, z-0.5, x-0.5, y-0.5, z+0.5, DGtal::Color(0,0,0), 2);
183  addLine(x+0.5, y-0.5, z-0.5, x+0.5, y-0.5, z+0.5, DGtal::Color(0,0,0), 2);
184  addLine(x+0.5, y+0.5, z-0.5, x+0.5, y+0.5, z+0.5, DGtal::Color(0,0,0), 2);
185  addLine(x-0.5, y+0.5, z-0.5, x-0.5, y+0.5, z+0.5, DGtal::Color(0,0,0), 2);
186 
187  }
188  (myVoxelSetList.at(myVoxelSetList.size()-1)).push_back(v);
189 
190 }
191 
192 
193 
194 inline
195 void
196 DGtal::Display3D::addPoint(double x, double y, double z ,const DGtal::Color &aColor, double size)
197 {
198  updateBoundingBox(x, y, z);
199  pointD3D p;
200  p.x=x;
201  p.y=y;
202  p.z=z;
203  p.R=aColor.red();
204  p.G=aColor.green();
205  p.B=aColor.blue();
206  p.T=aColor.alpha();
207  p.isSigned=false;
208  p.signPos=false;
209  p.size=size;
210  (myPointSetList.at(myPointSetList.size()-1)).push_back(p);
211 }
212 
213 
214 
215 
216 inline
217 void
218 DGtal::Display3D::addLine(double x1, double y1, double z1, double x2, double y2, double z2,
219  const DGtal::Color & aColor, double width)
220 {
221  updateBoundingBox(x1, y1, z1);
222  updateBoundingBox(x2, y2, z2);
223  lineD3D l;
224  l.x1=x1;
225  l.y1=y1;
226  l.z1=z1;
227 
228  l.x2=x2;
229  l.y2=y2;
230  l.z2=z2;
231 
232  l.R=aColor.red();
233  l.G=aColor.green();
234  l.B=aColor.blue();
235  l.T=aColor.alpha();
236  l.width=width;
237  l.isSigned=false;
238  l.signPos=false;
239 
240  (myLineSetList.at(myLineSetList.size()-1)).push_back(l);
241 
242 }
243 
244 
245 
246 
247 
248 inline
249 void
250 DGtal::Display3D::addQuad(double x1, double y1, double z1,
251  double x2, double y2, double z2,
252  double x3, double y3, double z3,
253  double x4, double y4, double z4, DGtal::Color aColor)
254 {
255  quadD3D aQuad;
256  updateBoundingBox(x1, y1, z1);
257  updateBoundingBox(x2, y2, z2);
258  updateBoundingBox(x3, y3, z3);
259  updateBoundingBox(x4, y4, z4);
260  double u[3]; double v [3]; double n [3];
261  u[0]=x2-x1; u[1]=y2-y1; u[2]=z2-z1;
262  v[0]=x3-x1; v[1]=y3-y1; v[2]=z3-z1;
263  cross(n, u, v );
264  normalize(n);
265 
266  if(u[0]==0.0 && u[1]==0.0 && u[2]==0.0){
267  trace.error()<< "Warning quad not added due to identical vertex... "<<endl;
268  return;
269  }
270 
271  aQuad.x1=x1; aQuad.y1=y1; aQuad.z1=z1;
272  aQuad.x2=x2; aQuad.y2=y2; aQuad.z2=z2;
273  aQuad.x3=x3; aQuad.y3=y3; aQuad.z3=z3;
274  aQuad.x4=x4; aQuad.y4=y4; aQuad.z4=z4;
275  aQuad.nx= n[0];
276  aQuad.ny= n[1];
277  aQuad.nz= n[2];
278 
279  aQuad.R=aColor.red();
280  aQuad.G=aColor.green();
281  aQuad.B=aColor.blue();
282  aQuad.T=aColor.alpha();
283 
284  myQuadList.push_back(aQuad);
285 }
286 
287 
288 
289 
290 
291 inline
292 void
293 DGtal::Display3D::addTriangle(double x1, double y1, double z1, double x2,
294  double y2, double z2,
295  double x3, double y3, double z3, DGtal::Color aColor)
296 {
297  updateBoundingBox(x1, y1, z1);
298  updateBoundingBox(x2, y2, z2);
299  updateBoundingBox(x3, y3, z3);
300 
301  triangleD3D aTriangle;
302  double u[3]; double v [3]; double n [3];
303  u[0]=x2-x1; u[1]=y2-y1; u[2]=z2-z1;
304  v[0]=x3-x1; v[1]=y3-y1; v[2]=z3-z1;
305  cross(n, u, v );
306  cross(n, u, v );
307  normalize(n);
308 
309  if(u[0]==0.0 && u[1]==0.0 && u[2]==0.0){
310  trace.error()<< "Warning triangle not added due to identical vertex... "<<endl;
311  return;
312  }
313 
314  aTriangle.x1=x1; aTriangle.y1=y1; aTriangle.z1=z1;
315  aTriangle.x2=x2; aTriangle.y2=y2; aTriangle.z2=z2;
316  aTriangle.x3=x3; aTriangle.y3=y3; aTriangle.z3=z3;
317 
318  aTriangle.nx= n[0];
319  aTriangle.ny= n[1];
320  aTriangle.nz= n[2];
321 
322  aTriangle.R=aColor.red();
323  aTriangle.G=aColor.green();
324  aTriangle.B=aColor.blue();
325  aTriangle.T=aColor.alpha();
326 
327  myTriangleList.push_back(aTriangle);
328 }
329 
330 
331 
332 
333 
334 inline
335 void
336 DGtal::Display3D::addPolygon(vector<Display3D::pointD3D> vectPointsPolygon, DGtal::Color aColor)
337 {
338  polygonD3D aPolygon;
339  for(unsigned int i=0; i< vectPointsPolygon.size();i++){
340  aPolygon.vectPoints.push_back(vectPointsPolygon.at(i));
341  updateBoundingBox(vectPointsPolygon.at(i).x, vectPointsPolygon.at(i).y, vectPointsPolygon.at(i).z);
342  }
343 
344 
345 
346  double x1= vectPointsPolygon.at(0).x;
347  double y1= vectPointsPolygon.at(0).y;
348  double z1= vectPointsPolygon.at(0).z;
349 
350  double x2= vectPointsPolygon.at(1).x;
351  double y2= vectPointsPolygon.at(1).y;
352  double z2= vectPointsPolygon.at(1).z;
353 
354  double x3= vectPointsPolygon.at(2).x;
355  double y3= vectPointsPolygon.at(2).y;
356  double z3= vectPointsPolygon.at(2).z;
357 
358  double u[3]; double v [3]; double n [3];
359  u[0]=x2-x1; u[1]=y2-y1; u[2]=z2-z1;
360  v[0]=x3-x1; v[1]=y3-y1; v[2]=z3-z1;
361  cross(n, u, v );
362  normalize(n);
363 
364  if(u[0]==0.0 && u[1]==0.0 && u[2]==0.0){
365  trace.error()<< "Warning polygin not added due to identical vertex... "<<endl;
366  return;
367  }
368 
369  aPolygon.nx= n[0];
370  aPolygon.ny= n[1];
371  aPolygon.nz= n[2];
372 
373  aPolygon.R=aColor.red();
374  aPolygon.G=aColor.green();
375  aPolygon.B=aColor.blue();
376  aPolygon.T=aColor.alpha();
377 
378 
379  myPolygonList.push_back(aPolygon);
380 
381 }
382 
383 
384 inline
385 void
386 DGtal::Display3D::addKSSurfel(double x, double y, double z,
387  bool xSurfel, bool ySurfel, bool zSurfel, double sizeShiftFactor,
388  double positionShift, double sizeFactor,
389  bool isSigned, bool aSign, bool basicMode )
390 {
391  updateBoundingBox(x, y, z);
392  double retract= 0.05*(sizeShiftFactor+myCurrentfShiftVisuKSSurfels);
393  double width= 0.03*(sizeShiftFactor+myCurrentfShiftVisuKSSurfels);
394  if(basicMode){
395  width=0.0;
396  retract=0.0;
397  }
398 
399 
400  double x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
401  double x5, y5, z5, x6, y6, z6, x7, y7, z7, x8, y8, z8;
402  double dx, dy, dz;
403 
404 
405  ASSERT( xSurfel || ySurfel || zSurfel );
406 
407  if(zSurfel)
408  {
409  x1= x-(0.5*sizeFactor); y1= y-(0.5*sizeFactor); z1= z-0.5+positionShift;
410  x2= x+(0.5*sizeFactor); y2= y-(0.5*sizeFactor); z2= z-0.5+positionShift;
411  x3= x+(0.5*sizeFactor); y3= y+(0.5*sizeFactor); z3= z-0.5+positionShift;
412  x4= x-(0.5*sizeFactor); y4= y+(0.5*sizeFactor); z4= z-0.5+positionShift;
413  y1+=retract; y2+=retract; y3-=retract; y4-=retract;
414  x1+=retract; x2-=retract; x3-=retract; x4+=retract;
415  dx=0.0; dy=0.0; dz=width;
416  }
417  else if(ySurfel)
418  {
419  x1= x-(0.5*sizeFactor); y1= y-0.5+positionShift; z1= z-(0.5*sizeFactor);
420  x2= x-(0.5*sizeFactor); y2= y-0.5+positionShift; z2= z+(0.5*sizeFactor);
421  x3= x+(0.5*sizeFactor); y3= y-0.5+positionShift; z3= z+(0.5*sizeFactor);
422  x4= x+(0.5*sizeFactor); y4= y-0.5+positionShift; z4= z-(0.5*sizeFactor);
423  x1+=retract; x2+=retract; x3-=retract; x4-=retract;
424  z1+=retract; z2-=retract; z3-=retract; z4+=retract;
425  dx=0.0; dy=width; dz=0.0;
426  }
427  else
428  {
429  x1= x-0.5+positionShift; y1= y-(0.5*sizeFactor); z1= z-(0.5*sizeFactor);
430  x2= x-0.5+positionShift; y2= y+(0.5*sizeFactor); z2= z-(0.5*sizeFactor);
431  x3= x-0.5+positionShift; y3= y+(0.5*sizeFactor); z3= z+(0.5*sizeFactor);
432  x4= x-0.5+positionShift; y4= y-(0.5*sizeFactor); z4= z+(0.5*sizeFactor);
433  y1+=retract; y2-=retract; y3-=retract; y4+=retract;
434  z1+=retract; z2+=retract; z3-=retract; z4-=retract;
435  dx=width; dy=0.0; dz=0.0;
436  }
437 
438  double xcenter= (x1+x2+x3+x4)/4.0;
439  double ycenter= (y1+y2+y3+y4)/4.0;
440  double zcenter= (z1+z2+z3+z4)/4.0;
441 
442  x5=x1-dx; y5=y1-dy; z5= z1-dz;
443  x6=x2-dx; y6=y2-dy; z6= z2-dz;
444  x7=x3-dx; y7=y3-dy; z7= z3-dz;
445  x8=x4-dx; y8=y4-dy; z8= z4-dz;
446 
447  x1=x1+dx; y1=y1+dy; z1= z1+dz;
448  x2=x2+dx; y2=y2+dy; z2= z2+dz;
449  x3=x3+dx; y3=y3+dy; z3= z3+dz;
450  x4=x4+dx; y4=y4+dy; z4= z4+dz;
451 
452  //if cell is oriented positively we retrac the upper face:
453  if(isSigned && aSign && !basicMode)
454  {
455  x1= 0.6*x1+0.4*xcenter; x2= 0.6*x2+0.4*xcenter; x3= 0.6*x3+0.4*xcenter; x4= 0.6*x4+0.4*xcenter;
456  y1= 0.6*y1+0.4*ycenter; y2= 0.6*y2+0.4*ycenter; y3= 0.6*y3+0.4*ycenter; y4= 0.6*y4+0.4*ycenter;
457  z1= 0.6*z1+0.4*zcenter; z2= 0.6*z2+0.4*zcenter; z3= 0.6*z3+0.4*zcenter; z4= 0.6*z4+0.4*zcenter;
458  }else if (isSigned && !basicMode)
459  {
460  x5= 0.6*x5+0.4*xcenter; x6= 0.6*x6+0.4*xcenter; x7= 0.6*x7+0.4*xcenter; x8= 0.6*x8+0.4*xcenter;
461  y5= 0.6*y5+0.4*ycenter; y6= 0.6*y6+0.4*ycenter; y7= 0.6*y7+0.4*ycenter; y8= 0.6*y8+0.4*ycenter;
462  z5= 0.6*z5+0.4*zcenter; z6= 0.6*z6+0.4*zcenter; z7= 0.6*z7+0.4*zcenter; z8= 0.6*z8+0.4*zcenter;
463  }
464 
465 
466 
467  if(basicMode)
468  {
469  if(! aSign)
470  this->addQuad(x1,y1,z1,x2,y2,z2, x3,y3,z3, x4,y4,z4,myCurrentFillColor );
471  else
472  this->addQuad(x4,y4,z4,x3,y3,z3, x2,y2,z2, x1,y1,z1,myCurrentFillColor );
473 
474  }
475  else
476  {
477  //main up face
478  quadD3D qFaceUp;
479  double normaleUp [3];
480  normaleUp[0] = dx!=0.0? 1.0:0.0;
481  normaleUp[1] = dy!=0.0 ? 1.0:0.0;
482  normaleUp[2] = dz!=0.0? 1.0:0.0;
483  qFaceUp.nx= normaleUp[0];
484  qFaceUp.ny= normaleUp[1];
485  qFaceUp.nz= normaleUp[2];
486 
487  qFaceUp.x1=x1; qFaceUp.y1=y1; qFaceUp.z1= z1;
488  qFaceUp.x2=x2; qFaceUp.y2=y2; qFaceUp.z2= z2;
489  qFaceUp.x3=x3; qFaceUp.y3=y3; qFaceUp.z3= z3;
490  qFaceUp.x4=x4; qFaceUp.y4=y4; qFaceUp.z4= z4;
491 
492  qFaceUp.R=myCurrentFillColor.red();qFaceUp.G=myCurrentFillColor.green(); qFaceUp.B=myCurrentFillColor.blue();
493  qFaceUp.T=myCurrentFillColor.alpha();
494  myKSSurfelList.push_back(qFaceUp);
495  //main down face
496  quadD3D qFaceDown;
497  qFaceDown.nx= -normaleUp[0];
498  qFaceDown.ny= -normaleUp[1];
499  qFaceDown.nz= -normaleUp[2];
500  qFaceDown.x1=x5; qFaceDown.y1=y5; qFaceDown.z1= z5;
501  qFaceDown.x2=x6; qFaceDown.y2=y6; qFaceDown.z2= z6;
502  qFaceDown.x3=x7; qFaceDown.y3=y7; qFaceDown.z3= z7;
503  qFaceDown.x4=x8; qFaceDown.y4=y8; qFaceDown.z4= z8;
504  qFaceDown.R=myCurrentFillColor.red();qFaceDown.G=myCurrentFillColor.green(); qFaceDown.B=myCurrentFillColor.blue();
505  qFaceDown.T=myCurrentFillColor.alpha();
506  myKSSurfelList.push_back(qFaceDown);
507 
508  //small face 1
509  quadD3D qFace1;
510  double vF1[3]; double v1 [3]; double n1 [3];
511  vF1[0] = x2-x1; vF1[1] = y2-y1; vF1[2] = z2-z1;
512  v1[0] = x5-x1; v1[1] = y5-y1; v1[2] = z5-z1;
513 
514  cross(n1, v1,vF1);
515  normalize(n1);
516  qFace1.nx=n1[0]; qFace1.ny=n1[1]; qFace1.nz=n1[2];
517  qFace1.x1= x1; qFace1.y1 =y1; qFace1.z1=z1;
518  qFace1.x2= x2; qFace1.y2 =y2; qFace1.z2=z2;
519  qFace1.x3= x6; qFace1.y3 =y6; qFace1.z3=z6;
520  qFace1.x4= x5; qFace1.y4 =y5; qFace1.z4=z5;
521  qFace1.R=myCurrentFillColor.red();qFace1.G=myCurrentFillColor.green(); qFace1.B=myCurrentFillColor.blue();
522  qFace1.T=myCurrentFillColor.alpha();
523  myKSSurfelList.push_back(qFace1);
524 
525  //small face 2
526  quadD3D qFace2;
527  double vF2[3]; double v2 [3]; double n2[3];
528  vF2[0]= x3-x2; vF2[1]=y3-y2; vF2[2]= z3-z2;
529  v2[0]= x6-x2; v2[1]= y6-y2; v2[2]=z6-z2;
530  cross(n2, v2, vF2);
531  normalize(n2);
532 
533  qFace2.nx=n2[0]; qFace2.ny=n2[1]; qFace2.nz=n2[2];
534  qFace2.x1= x2; qFace2.y1 =y2; qFace2.z1=z2;
535  qFace2.x2= x3; qFace2.y2 =y3; qFace2.z2=z3;
536  qFace2.x3= x7; qFace2.y3 =y7; qFace2.z3=z7;
537  qFace2.x4= x6; qFace2.y4 =y6; qFace2.z4=z6;
538  qFace2.R=myCurrentFillColor.red();qFace2.G=myCurrentFillColor.green(); qFace2.B=myCurrentFillColor.blue();
539  qFace2.T=myCurrentFillColor.alpha();
540  myKSSurfelList.push_back(qFace2);
541 
542 
543  //small face 3
544  quadD3D qFace3;
545  double vF3[3]; double v3 [3]; double n3[3];
546  vF3[0]= x4-x3; vF3[1]=y4-y3; vF3[2]= z4-z3;
547  v3[0]= x7-x3; v3[1]= y7-y3; v3[2]=z7-z3;
548  cross(n3, v3, vF3);
549  normalize(n3);
550  qFace3.nx=n3[0]; qFace3.ny=n3[1]; qFace3.nz=n3[2];
551  qFace3.x1= x3; qFace3.y1 =y3; qFace3.z1=z3;
552  qFace3.x2= x4; qFace3.y2 =y4; qFace3.z2=z4;
553  qFace3.x3= x8; qFace3.y3 =y8; qFace3.z3=z8;
554  qFace3.x4= x7; qFace3.y4 =y7; qFace3.z4=z7;
555  qFace3.R=myCurrentFillColor.red();qFace3.G=myCurrentFillColor.green(); qFace3.B=myCurrentFillColor.blue();
556  qFace3.T=myCurrentFillColor.alpha();
557  myKSSurfelList.push_back(qFace3);
558 
559  //small face 4
560  quadD3D qFace4;
561  double vF4[3]; double v4 [3]; double n4[3];
562  vF4[0]= x1-x4; vF4[1]=y1-y4; vF4[2]= z1-z4;
563  v4[0]= x5-x4; v4[1]= y5-y4; v4[2]=z5-z4;
564  cross(n4, v4, vF4);
565  normalize(n4);
566  qFace4.nx=n4[0]; qFace4.ny=n4[1]; qFace4.nz=n4[2];
567  qFace4.x1= x4; qFace4.y1 =y4; qFace4.z1=z4;
568  qFace4.x2= x1; qFace4.y2 =y1; qFace4.z2=z1;
569  qFace4.x3= x5; qFace4.y3 =y5; qFace4.z3=z5;
570  qFace4.x4= x8; qFace4.y4 =y8; qFace4.z4=z8;
571  qFace4.R=myCurrentFillColor.red();qFace4.G=myCurrentFillColor.green(); qFace4.B=myCurrentFillColor.blue();
572  qFace4.T=myCurrentFillColor.alpha();
573  myKSSurfelList.push_back(qFace4);
574  }
575 
576 }
577 
578 
579 
580 
581 
582 inline
583 void
584 DGtal::Display3D::addKSPointel(double x, double y, double z,
585  double size, bool isSigned, bool signPos)
586 {
587  updateBoundingBox(x, y, z);
588  pointD3D pt;
589  pt.x=x; pt.y=y; pt.z=z; pt.size=size;
590  pt.R=myCurrentFillColor.red();
591  pt.G=myCurrentFillColor.green();
592  pt.B=myCurrentFillColor.blue();
593  pt.T= myCurrentFillColor.alpha();
594  pt.isSigned=isSigned;
595  pt.signPos=signPos;
596  myKSPointelList.push_back(pt);
597 }
598 
599 
600 
601 
602 inline
603 void
604 DGtal::Display3D::addKSVoxel(int x, int y, int z, double sizeFactor)
605 {
606  updateBoundingBox(x, y, z);
607  voxelD3D v;
608  v.x=x;
609  v.y=y;
610  v.z=z;
611  v.R=myCurrentFillColor.red();
612  v.G=myCurrentFillColor.green();
613  v.B=myCurrentFillColor.blue();
614  v.T=myCurrentFillColor.alpha();
615  v.width=0.5*sizeFactor;
616  (myVoxelSetList.at(0)).push_back(v);
617 }
618 
619 
620 
621 
622 
623 inline
624 void
625 DGtal::Display3D::addKSLinel(double x1, double y1, double z1,
626  double x2, double y2, double z2,
627  double width, bool isSigned, bool signPos)
628 {
629  updateBoundingBox(x1, y1, z1);
630  updateBoundingBox(x2, y2, z2);
631  lineD3D l;
632  l.x1=x1; l.y1=y1; l.z1=z1; l.x2=x2; l.y2=y2; l.z2=z2;
633  l.width=width;
634  l.R= myCurrentFillColor.red();
635  l.G= myCurrentFillColor.green();
636  l.B=myCurrentFillColor.blue();
637  l.T=myCurrentFillColor.alpha();
638  l.isSigned=isSigned;
639  l.signPos=signPos;
640  myKSLinelList.push_back(l);
641 }
642 
643 
644 
645 
646 
647 inline
648 void
649 DGtal::Display3D::addClippingPlane(double a, double b, double c, double d, bool drawPlane)
650 {
651  if(myClippingPlaneList.size()<5)
652  {
653  clippingPlaneD3D cp;
654  cp.a=a; cp.b=b; cp.c=c; cp.d=d;
655  myClippingPlaneList.push_back(cp);
656  if(drawPlane)
657  {
658  double x1,x2,x3,x4;
659  double y1,y2,y3,y4;
660  double z1,z2,z3,z4;
661  double norm = sqrt(a*a+b*b+c*c);
662  double dec=0.1;
663  // Z dominant projection of the upper face
664  if(abs(c)>=abs(b) && abs(c) >= abs(a))
665  {
666  x1= myBoundingPtUp[0]+a*dec/norm; y1= myBoundingPtUp[1]+b*dec/norm;
667  z1 = c*dec/norm +(-d-a*myBoundingPtUp[0]-b*myBoundingPtUp[1])/c;
668  x2= myBoundingPtLow[0]+a*dec/norm; y2= myBoundingPtUp[1]+b*dec/norm;
669  z2= c*dec/norm+(-d-a*myBoundingPtLow[0]-b*myBoundingPtUp[1])/c;
670  x3= myBoundingPtLow[0]+a*dec/norm; y3= myBoundingPtLow[1]+b*dec/norm;
671  z3= c*dec/norm+(-d-a*myBoundingPtLow[0]-b*myBoundingPtLow[1])/c;
672  x4= myBoundingPtUp[0]+a*dec/norm; y4= myBoundingPtLow[1]+b*dec/norm;
673  z4= c*dec/norm+(-d-a*myBoundingPtUp[0]-b*myBoundingPtLow[1])/c;
674  if(c>0)
675  {
676  addQuad(x4,y4,z4,x3,y3,z3, x2,y2,z2, x1,y1,z1, DGtal::Color(205,0,0, 30));
677  }else
678  {
679  addQuad( x1,y1,z1, x2,y2,z2, x3,y3,z3,x4,y4,z4 , DGtal::Color(205,0,0, 30));
680  }
681 
682  }// Y dominant projection of the upper face
683  else if(abs(b)>=abs(c) && abs(b) >= abs(a))
684  {
685  x1= myBoundingPtUp[0]+a*dec/norm; z1= myBoundingPtUp[2]+c*dec/norm;
686  y1= b*dec/norm +(-d-a*myBoundingPtUp[0]-c*myBoundingPtUp[2])/b;
687  x2= myBoundingPtUp[0]+a*dec/norm; z2= myBoundingPtLow[2]+c*dec/norm;
688  y2= b*dec/norm +(-d-a*myBoundingPtUp[0]-c*myBoundingPtLow[2])/b;
689  x3= myBoundingPtLow[0]+a*dec/norm; z3= myBoundingPtLow[2]+c*dec/norm;
690  y3= b*dec/norm +(-d-a*myBoundingPtLow[0]-c*myBoundingPtLow[2])/b;
691  x4= myBoundingPtLow[0]+a*dec/norm; z4= myBoundingPtUp[2]+c*dec/norm;
692  y4= b*dec/norm +(-d-a*myBoundingPtLow[0]-c*myBoundingPtUp[2])/b;
693  if(b>0)
694  {
695  addQuad(x4,y4,z4,x3,y3,z3, x2,y2,z2, x1,y1,z1, DGtal::Color(205,0,0, 30));
696  }else
697  {
698  addQuad( x1,y1,z1, x2,y2,z2, x3,y3,z3,x4,y4,z4 , DGtal::Color(205,0,0, 30));
699  }
700  }// X dominant projection of the upper face
701  else if(abs(a)>=abs(c) && abs(a) >= abs(b))
702  {
703  y1= myBoundingPtUp[1]+b*dec/norm; z1= myBoundingPtUp[2]+c*dec/norm;
704  x1= a*dec/norm +(-d-b*myBoundingPtUp[1]-c*myBoundingPtUp[2])/a;
705  y2= myBoundingPtLow[1]+b*dec/norm; z2= myBoundingPtUp[2]+c*dec/norm;
706  x2= a*dec/norm +(-d-b*myBoundingPtLow[1]-c*myBoundingPtUp[2])/a;
707  y3= myBoundingPtLow[1]+b*dec/norm; z3= myBoundingPtLow[2]+c*dec/norm;
708  x3= a*dec/norm +(-d-b*myBoundingPtLow[1]-c*myBoundingPtLow[2])/a;
709  y4= myBoundingPtUp[1]+b*dec/norm; z4= myBoundingPtLow[2]+c*dec/norm;
710  x4= a*dec/norm +(-d-b*myBoundingPtUp[1]-c*myBoundingPtLow[2])/a;
711 
712  if(a>0)
713  {
714  addQuad(x4,y4,z4,x3,y3,z3, x2,y2,z2, x1,y1,z1, DGtal::Color(205,0,0, 30));
715  }else
716  {
717  addQuad( x1,y1,z1, x2,y2,z2, x3,y3,z3,x4,y4,z4 , DGtal::Color(205,0,0, 30));
718  }
719  }
720 
721  }
722 
723  }else
724  {
725  std::cerr <<"Warning maximal clipping plane added" << endl;
726  }
727 }
728 
729 inline
730 void
731 DGtal::Display3D::updateBoundingBox(double x, double y, double z)
732 {
733  if (myBoundingPtEmptyTag)
734  {
735  myBoundingPtLow[0]= x;
736  myBoundingPtLow[1]= y;
737  myBoundingPtLow[2]= z;
738  myBoundingPtUp[0]= x;
739  myBoundingPtUp[1]= y;
740  myBoundingPtUp[2]= z;
741  myBoundingPtEmptyTag = false;
742  }
743  else
744  {
745  if(x <myBoundingPtLow[0]) myBoundingPtLow[0]= x;
746  if(y <myBoundingPtLow[1]) myBoundingPtLow[1]= y;
747  if(z <myBoundingPtLow[2]) myBoundingPtLow[2]= z;
748 
749  if(x >myBoundingPtUp[0]) myBoundingPtUp[0]= x;
750  if(y >myBoundingPtUp[1]) myBoundingPtUp[1]= y;
751  if(z >myBoundingPtUp[2]) myBoundingPtUp[2]= z;
752  }
753 }
754 
755 
756 inline
757 void
758 DGtal::Display3D::setScale(float sx, float sy, float sz){
759  myScaleX = sx;
760  myScaleY = sy;
761  myScaleZ = sz;
762 }
763 
764 
765 
766 inline
767 void
769 
770  unsigned int vertexIndex=0;
771 
772  // Export of KSSurfel lists (generated from KhalimskyCell or SignedKhalimskyCell (through addKSSurfel))
773  for (unsigned int i=0; i< myKSSurfelList.size(); i++){
774  quadD3D quad = myKSSurfelList.at(i);
775  pointD3D p1, p2, p3, p4;
776  p1.x=quad.x1*myScaleX; p1.y=quad.y1*myScaleY ;p1.z=quad.z1*myScaleZ;
777  p2.x=quad.x2*myScaleX; p2.y=quad.y2*myScaleY ;p2.z=quad.z2*myScaleZ;
778  p3.x=quad.x3*myScaleX; p3.y=quad.y3*myScaleY ;p3.z=quad.z3*myScaleZ;
779  p4.x=quad.x4*myScaleX; p4.y=quad.y4*myScaleY ;p4.z=quad.z4*myScaleZ;
780  aMesh.addVertex(p1);
781  aMesh.addVertex(p2);
782  aMesh.addVertex(p3);
783  aMesh.addVertex(p4);
784  aMesh.addQuadFace(vertexIndex, vertexIndex+1, vertexIndex+2,vertexIndex+3,
785  DGtal::Color(quad.R, quad.G, quad.B, quad.T));
786  vertexIndex+=4;
787  }
788 
789 
790  // Export QuadList
791  for (unsigned int i=0; i<myQuadList.size(); i++){
792  quadD3D quad = myQuadList.at(i);
793  pointD3D p1, p2, p3, p4;
794  p1.x=quad.x1*myScaleX; p1.y=quad.y1*myScaleY ;p1.z=quad.z1*myScaleZ;
795  p2.x=quad.x2*myScaleX; p2.y=quad.y2*myScaleY ;p2.z=quad.z2*myScaleZ;
796  p3.x=quad.x3*myScaleX; p3.y=quad.y3*myScaleY ;p3.z=quad.z3*myScaleZ;
797  p4.x=quad.x4*myScaleX; p4.y=quad.y4*myScaleY ;p4.z=quad.z4*myScaleZ;
798  aMesh.addVertex(p4);
799  aMesh.addVertex(p3);
800  aMesh.addVertex(p2);
801  aMesh.addVertex(p1);
802  aMesh.addQuadFace(vertexIndex,vertexIndex+1, vertexIndex+2, vertexIndex+3,
803  DGtal::Color(quad.R, quad.G, quad.B, quad.T));
804  vertexIndex+=4;
805  }
806 
807 
808  // Export the mesh from TriangleList
809  for (unsigned int i=0; i < myTriangleList.size(); i++){
810  triangleD3D aTriangle = myTriangleList.at(i);
811  pointD3D p1, p2, p3;
812  p1.x = aTriangle.x1*myScaleX; p1.y = aTriangle.y1*myScaleY; p1.z = aTriangle.z1*myScaleZ;
813  p2.x = aTriangle.x2*myScaleX; p2.y = aTriangle.y2*myScaleY; p2.z = aTriangle.z2*myScaleZ;
814  p3.x = aTriangle.x3*myScaleX; p3.y = aTriangle.y3*myScaleY; p3.z = aTriangle.z3*myScaleZ;
815  aMesh.addVertex(p1);
816  aMesh.addVertex(p2);
817  aMesh.addVertex(p3);
818  aMesh.addTriangularFace(vertexIndex, vertexIndex+1, vertexIndex+2,
819  DGtal::Color(aTriangle.R, aTriangle.G,
820  aTriangle.B, aTriangle.T));
821  vertexIndex+=3;
822  }
823 
824 
825 
826 
827  // Export of voxelSet (generated from addVoxel)
828  for(unsigned int j=0; j<myVoxelSetList.size(); j++){
829  for (unsigned int i=0; i< myVoxelSetList.at(j).size(); i++){
830  voxelD3D voxel = myVoxelSetList.at(j).at(i);
831  pointD3D p1, p2, p3, p4, p5, p6, p7, p8;
832  double width= voxel.width;
833 
834  p1.x = (voxel.x-width)*myScaleX; p1.y = (voxel.y+width)*myScaleY; p1.z = (voxel.z+width)*myScaleZ;
835  p2.x = (voxel.x+width)*myScaleX; p2.y = (voxel.y+width)*myScaleY; p2.z = (voxel.z+width)*myScaleZ;
836  p3.x = (voxel.x+width)*myScaleX; p3.y = (voxel.y-width)*myScaleY; p3.z = (voxel.z+width)*myScaleZ;
837  p4.x = (voxel.x-width)*myScaleX; p4.y = (voxel.y-width)*myScaleY; p4.z = (voxel.z+width)*myScaleZ;
838  p5.x = (voxel.x-width)*myScaleX; p5.y = (voxel.y+width)*myScaleY; p5.z = (voxel.z-width)*myScaleZ;
839 
840  p6.x = (voxel.x+width)*myScaleX; p6.y = (voxel.y+width)*myScaleY; p6.z = (voxel.z-width)*myScaleZ;
841  p7.x = (voxel.x+width)*myScaleX; p7.y = (voxel.y-width)*myScaleY; p7.z = (voxel.z-width)*myScaleZ;
842  p8.x = (voxel.x-width)*myScaleX; p8.y = (voxel.y-width)*myScaleY; p8.z = (voxel.z-width)*myScaleZ;
843 
844  aMesh.addVertex(p1);
845  aMesh.addVertex(p2);
846  aMesh.addVertex(p3);
847  aMesh.addVertex(p4);
848  aMesh.addVertex(p5);
849  aMesh.addVertex(p6);
850  aMesh.addVertex(p7);
851  aMesh.addVertex(p8);
852 
853  //z+
854  aMesh.addQuadFace(vertexIndex, vertexIndex+3, vertexIndex+2, vertexIndex+1,
855  DGtal::Color(voxel.R, voxel.G, voxel.B, voxel.T));
856 
857  //z-
858  aMesh.addQuadFace(vertexIndex+4, vertexIndex+5, vertexIndex+6, vertexIndex+7,
859  DGtal::Color(voxel.R, voxel.G, voxel.B, voxel.T));
860 
861  //y+
862  aMesh.addQuadFace(vertexIndex+1, vertexIndex+2, vertexIndex+6, vertexIndex+5,
863  DGtal::Color(voxel.R, voxel.G, voxel.B, voxel.T));
864 
865  //y-
866  aMesh.addQuadFace(vertexIndex, vertexIndex+4, vertexIndex+7, vertexIndex+3,
867  DGtal::Color(voxel.R, voxel.G, voxel.B, voxel.T));
868 
869  //x+
870  aMesh.addQuadFace(vertexIndex, vertexIndex+1, vertexIndex+5, vertexIndex+4,
871  DGtal::Color(voxel.R, voxel.G, voxel.B, voxel.T));
872 
873  //x-
874  aMesh.addQuadFace(vertexIndex+3, vertexIndex+7, vertexIndex+6, vertexIndex+2,
875  DGtal::Color(voxel.R, voxel.G, voxel.B, voxel.T));
876 
877  vertexIndex+=8;
878  }
879  }
880 
881 
882 }
883 
884 
885 
886 
887 
888 
889 template <typename TDrawableWithDisplay3D>
890 inline
892 DGtal::Display3D::operator<<( const TDrawableWithDisplay3D & object )
893 {
894  // BOOST_CONCEPT_ASSERT((CDrawableWithDisplay3D< TDrawableWithDisplay3D >));
895 
896  DGtal::Display3DFactory::draw(*this, object);
897  return *this;
898 }
899 
906 inline
907 std::ostream&
908 DGtal::operator<< ( std::ostream & out,
909  const Display3D & object )
910 {
911  object.selfDisplay ( out );
912  return out;
913 }
914 
915 
916 inline
917 void
919 {
920  aDisplay3D.exportToMesh(aMesh);
921 }
922 
923 
924 
925 inline
926 void
927 DGtal::operator>> ( const Display3D &aDisplay3D, string aFilename)
928 {
929  // exporting with a mesh containing color (parameter constructor to true):
931  aDisplay3D >> mesh;
932  trace.info() << "generating faces done." << endl;
933  mesh >> aFilename;
934  trace.info() << "file exported in file: " << aFilename << endl;
935 }
936 
937 
938 
939 
940 
941 
942 // //
944 
945