2 * This program is free software: you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public License
4 * as published by the Free Software Foundation, either version 3 of
5 * the License, or (at your option) any later version.
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.
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/>.
19 * @author Bertrand Kerautret (\c kerautre@loria.fr )
20 * LORIA (CNRS, UMR 7503), University of Nancy, France
24 * Implementation of inline methods defined in Display3D.h
26 * This file is part of the DGtal library.
29///////////////////////////////////////////////////////////////////////////////
30// IMPLEMENTATION of inline methods.
31///////////////////////////////////////////////////////////////////////////////
33//////////////////////////////////////////////////////////////////////////////
36#include "DGtal/io/CDrawableWithDisplay3D.h"
37#include "DGtal/io/Display3DFactory.h"
38#include "DGtal/io/writers/MeshWriter.h"
44//////////////////////////////////////////////////////////////////////////////
46///////////////////////////////////////////////////////////////////////////////
47// Implementation of inline methods //
51///////////////////////////////////////////////////////////////////////////////
53///////////////////////////////////////////////////////////////////////////////
54// Implementation of inline functions and external operators //
57template < typename Space ,typename KSpace >
60DGtal::Display3D< Space ,KSpace >::setFillColor(DGtal::Color aColor)
62 myCurrentFillColor=aColor;
65template < typename Space ,typename KSpace >
68DGtal::Display3D< Space ,KSpace >::setFillTransparency(unsigned char alpha)
70 myCurrentFillColor.alpha(alpha);
73template < typename Space ,typename KSpace >
76DGtal::Display3D< Space ,KSpace >::setLineColor(DGtal::Color aColor)
78 myCurrentLineColor=aColor;
82template < typename Space ,typename KSpace >
85DGtal::Display3D< Space ,KSpace >::setKSpace( const KSpace & aKSpace )
88 *myCellEmbedder = CellEmbedder( myKSpace );
89 *mySCellEmbedder = SCellEmbedder( myKSpace );
93template < typename Space ,typename KSpace >
96DGtal::Display3D< Space ,KSpace >::getLineColor()
98 return myCurrentLineColor;
101template < typename Space ,typename KSpace >
104DGtal::Display3D< Space ,KSpace >::getFillColor()
106 return myCurrentFillColor;
109//-----------------------------------------------------------------------------
110template < typename Space ,typename KSpace >
113DGtal::Display3D< Space ,KSpace >::
114setName3d( DGtal::int32_t name )
119//-----------------------------------------------------------------------------
120template < typename Space ,typename KSpace >
123DGtal::Display3D< Space ,KSpace >::
128//-----------------------------------------------------------------------------
129template < typename Space ,typename KSpace >
132DGtal::Display3D< Space ,KSpace >::
133setSelectCallback3D( SelectCallbackFct fct, void* data,
134 DGtal::int32_t min_name, DGtal::int32_t max_name )
136 mySelectCallBackFcts.insert( SelectCallbackFctStore( fct, data, min_name, max_name ) );
138//-----------------------------------------------------------------------------
139template < typename Space ,typename KSpace >
141typename DGtal::Display3D< Space ,KSpace >::SelectCallbackFct
142DGtal::Display3D< Space ,KSpace >::
143getSelectCallback3D( DGtal::int32_t aName, void*& data ) const
145 typedef typename std::set<SelectCallbackFctStore>::const_iterator SetConstIterator;
146 SelectCallbackFctStore seek( 0, 0, aName, aName );
147 SetConstIterator it_up = mySelectCallBackFcts.upper_bound( seek );
148 if ( ( it_up != mySelectCallBackFcts.end() ) && it_up->isSelected( aName ) )
153 if (it_up == mySelectCallBackFcts.begin()){
158 if ( ( it_up != mySelectCallBackFcts.end() ) && it_up->isSelected( aName ) )
167//-----------------------------------------------------------------------------
168template < typename Space ,typename KSpace >
171DGtal::Display3D< Space ,KSpace >::getMode( const std::string & objectName ) const
173 ModeMapping::const_iterator itm = myModes.find( objectName );
174 return itm == myModes.end() ? "" : itm->second;
178template < typename Space ,typename KSpace >
181DGtal::Display3D< Space ,KSpace >::createNewCubeList()
183 // looking for an empty key
184 DGtal::int32_t aKey=0;
185 bool found = myCubesMap.count(aKey) == 0;
188 found = (myCubesMap.count(aKey) == 0) &&
189 (myQuadsMap.count(aKey) == 0);
190 }while (!found && aKey < std::numeric_limits<DGtal::int32_t>::max());
198template < typename Space ,typename KSpace >
201DGtal::Display3D< Space ,KSpace >::deleteCubeList(const DGtal::int32_t idList)
203 return myCubesMap.erase(idList);
207template < typename Space ,typename KSpace >
210DGtal::Display3D< Space ,KSpace >::createNewBallList(std::string str)
212 std::vector< BallD3D > v;
213 myBallSetList.push_back(v);
214 myBallSetNameList.push_back(str);
217template < typename Space ,typename KSpace >
220DGtal::Display3D< Space ,KSpace >::createNewLineList(std::string str)
222 std::vector< LineD3D > v;
223 myLineSetList.push_back(v);
224 myLineSetNameList.push_back(str);
227 template < typename Space ,typename KSpace >
230 DGtal::Display3D< Space ,KSpace >::createNewQuadList()
232 // looking for an empty key
233 DGtal::int32_t aKey=0;
234 bool found = myQuadsMap.count(aKey) == 0;
237 found = (myCubesMap.count(aKey) == 0) &&
238 (myQuadsMap.count(aKey) == 0);
239 }while (!found && aKey < std::numeric_limits<DGtal::int32_t>::max());
250template < typename Space ,typename KSpace >
253DGtal::Display3D< Space ,KSpace >::deleteQuadList(const DGtal::int32_t idList)
255 return myQuadsMap.erase(idList);
260template < typename Space ,typename KSpace >
263DGtal::Display3D< Space ,KSpace >::createNewTriangleList(std::string str)
265 std::vector< TriangleD3D > v;
266 myTriangleSetList.push_back(v);
267 myTriangleSetNameList.push_back(str);
270template < typename Space ,typename KSpace >
273DGtal::Display3D< Space ,KSpace >::createNewPolygonList(std::string str)
275 std::vector< PolygonD3D > v;
276 myPolygonSetList.push_back(v);
277 myPolygonSetNameList.push_back(str);
281template < typename Space ,typename KSpace >
284DGtal::Display3D< Space ,KSpace >::addCube(const RealPoint ¢er, double width)
286 //because the width in the cube parameters is actually the distance between the center and the faces
288 updateBoundingBox(center);
291 v.color = getFillColor();
294 myCubesMap[ v.name ].push_back( v );
299template < typename Space ,typename KSpace >
302DGtal::Display3D< Space ,KSpace >::addBall(const RealPoint ¢er,
304 const unsigned int resolution)
306 updateBoundingBox(center);
309 p.color = getFillColor();
313 p.resolution = resolution;
315 if (myBallSetList.size()== 0)
316 createNewBallList("Ball Root");
317 (myBallSetList.at(myBallSetList.size()-1)).push_back(p);
322template < typename Space ,typename KSpace >
325DGtal::Display3D< Space ,KSpace >::addLine(const RealPoint &p1, const RealPoint &p2, const double width)
327 updateBoundingBox(p1);
328 updateBoundingBox(p2);
332 l.color = getLineColor();
337 if (myLineSetList.size()== 0)
338 createNewLineList("Line Root");
340 (myLineSetList.at(myLineSetList.size()-1)).push_back(l);
343template < typename Space ,typename KSpace >
346DGtal::Display3D< Space ,KSpace >::addQuad(const RealPoint &p1, const RealPoint &p2,
347 const RealPoint &p3, const RealPoint &p4)
350 double u[3]; double v [3]; double n [3];
351 u[0]=p2[0]-p1[0]; u[1]=p2[1]-p1[1]; u[2]=p2[2]-p1[2];
352 v[0]=p3[0]-p1[0]; v[1]=p3[1]-p1[1]; v[2]=p3[2]-p1[2];
355 addQuadWithNormal(p1, p2, p3, p4, RealPoint(n[0], n[1], n[2]), false);
357template < typename Space ,typename KSpace >
360DGtal::Display3D< Space ,KSpace >::addQuadWithNormal(const RealPoint &p1, const RealPoint &p2,
361 const RealPoint &p3, const RealPoint &p4,
363 const bool enableReorientation,
364 const bool enableDoubleFace)
366 QuadD3D aQuad,aQuad2;
367 updateBoundingBox(p1);
368 updateBoundingBox(p2);
369 updateBoundingBox(p3);
370 updateBoundingBox(p4);
372 u[0]=p2[0]-p1[0]; u[1]=p2[1]-p1[1]; u[2]=p2[2]-p1[2];
374 v[0]=p3[0]-p2[0]; v[1]=p3[1]-p2[1]; v[2]=p3[2]-p2[2];
376 cross(crossprod, u,v);
377 double epsilon = 0.0001;
379 if(u[0]==0.0 && u[1]==0.0 && u[2]==0.0)
381 trace.warning()<< "Warning quad not added due to identical vertex... "<<std::endl;
385 if ((enableReorientation)
386 && ((crossprod[0]*n[0] + crossprod[1]*n[1] +crossprod[2]*n[2]) < 0.0))
395 aQuad.color = getFillColor();
397 if (enableDoubleFace)
399 aQuad2.point1 = (p1 - epsilon*n);
400 aQuad2.point2 = (p2 - epsilon*n);
401 aQuad2.point3 = (p3 - epsilon*n);
402 aQuad2.point4 = (p4 - epsilon*n);
406 aQuad2.color = getFillColor();
410 { // Note: order of points is changed
418 aQuad.color = getFillColor();
420 if (enableDoubleFace)
422 aQuad2.point1 = (p1 - epsilon*n);
423 aQuad2.point2 = (p4 - epsilon*n);
424 aQuad2.point3 = (p3 - epsilon*n);
425 aQuad2.point4 = (p2 - epsilon*n);
429 aQuad2.color = getFillColor();
432 aQuad.name = name3d();
433 aQuad2.name = name3d();
435 myQuadsMap[ aQuad.name ] .push_back( aQuad );
436 if (enableDoubleFace)
437 myQuadsMap[ aQuad2.name ].push_back( aQuad2 );
441template < typename Space ,typename KSpace >
444DGtal::Display3D< Space ,KSpace >::addTriangle(const RealPoint &p1, const RealPoint &p2, const RealPoint &p3)
446 updateBoundingBox(p1);
447 updateBoundingBox(p2);
448 updateBoundingBox(p3);
450 TriangleD3D aTriangle;
451 double u[3]; double v [3]; double n [3];
452 u[0]=p2[0]-p1[0]; u[1]=p2[1]-p1[1]; u[2]=p2[2]-p1[2];
453 v[0]=p3[0]-p1[0]; v[1]=p3[1]-p1[1]; v[2]=p3[2]-p1[2];
458 if(u[0]==0.0 && u[1]==0.0 && u[2]==0.0)
460 trace.error()<< "Warning triangle not added due to identical vertex... "<<std::endl;
463 aTriangle.point1 = p1;
464 aTriangle.point2 = p2;
465 aTriangle.point3 = p3;
469 aTriangle.color = getFillColor();
470 aTriangle.name = name3d();
471 if (myTriangleSetList.size()== 0)
472 createNewTriangleList("Triangle Root");
474 (myTriangleSetList.at(myTriangleSetList.size()-1)).push_back(aTriangle);
478template < typename Space ,typename KSpace >
481DGtal::Display3D< Space ,KSpace >::addPolygon(const std::vector<RealPoint> &vertices)
484 ASSERT_MSG(vertices.size()>2, "Polygon must have at least two vertices");
487 for(unsigned int i=0; i< vertices.size();i++)
489 polygon.vertices.push_back(vertices[i]);
490 updateBoundingBox(vertices[i]);
493 double x1 = vertices[0][0];
494 double y1 = vertices[0][1];
495 double z1 = vertices[0][2];
497 double x2 = vertices[1][0];
498 double y2 = vertices[1][1];
499 double z2 = vertices[1][2];
501 double x3 = vertices[2][0];
502 double y3 = vertices[2][1];
503 double z3 = vertices[2][2];
505 double u[3]; double v[3]; double n[3];
506 u[0]=x2-x1; u[1]=y2-y1; u[2]=z2-z1;
507 v[0]=x3-x1; v[1]=y3-y1; v[2]=z3-z1;
511 if(u[0]==0.0 && u[1]==0.0 && u[2]==0.0)
513 trace.error()<< "Warning polygon not added due to identical vertices... "<<std::endl;
520 polygon.color = getFillColor();
521 polygon.name = name3d();
522 if (myPolygonSetList.size()== 0)
523 createNewPolygonList("Polygon Root");
525 (myPolygonSetList.at(myPolygonSetList.size()-1)).push_back(polygon);
530template < typename Space ,typename KSpace >
533DGtal::Display3D< Space ,KSpace >::addPrism(const RealPoint &baseQuadCenter,
534 bool xSurfel, bool ySurfel, bool zSurfel,
535 double sizeShiftFactor,
536 double sizeFactor, bool isSigned, bool aSign)
538 updateBoundingBox(baseQuadCenter);
539 double retract = 0.05*(sizeShiftFactor+myCurrentfShiftVisuPrisms);
540 double width = 0.03*(sizeShiftFactor+myCurrentfShiftVisuPrisms);
543 double x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
544 double x5, y5, z5, x6, y6, z6, x7, y7, z7, x8, y8, z8;
548 ASSERT( xSurfel || ySurfel || zSurfel );
549 boost::ignore_unused_variable_warning( xSurfel );
553 x1= baseQuadCenter[0]-(0.5*sizeFactor); y1= baseQuadCenter[1]-(0.5*sizeFactor); z1= baseQuadCenter[2]-0.5;
554 x2= baseQuadCenter[0]+(0.5*sizeFactor); y2= baseQuadCenter[1]-(0.5*sizeFactor); z2= baseQuadCenter[2]-0.5;
555 x3= baseQuadCenter[0]+(0.5*sizeFactor); y3= baseQuadCenter[1]+(0.5*sizeFactor); z3= baseQuadCenter[2]-0.5;
556 x4= baseQuadCenter[0]-(0.5*sizeFactor); y4= baseQuadCenter[1]+(0.5*sizeFactor); z4= baseQuadCenter[2]-0.5;
557 y1+=retract; y2+=retract; y3-=retract; y4-=retract;
558 x1+=retract; x2-=retract; x3-=retract; x4+=retract;
559 dx=0.0; dy=0.0; dz=width;
563 x1= baseQuadCenter[0]-(0.5*sizeFactor); y1= baseQuadCenter[1]-0.5; z1= baseQuadCenter[2]-(0.5*sizeFactor);
564 x2= baseQuadCenter[0]-(0.5*sizeFactor); y2= baseQuadCenter[1]-0.5; z2= baseQuadCenter[2]+(0.5*sizeFactor);
565 x3= baseQuadCenter[0]+(0.5*sizeFactor); y3= baseQuadCenter[1]-0.5; z3= baseQuadCenter[2]+(0.5*sizeFactor);
566 x4= baseQuadCenter[0]+(0.5*sizeFactor); y4= baseQuadCenter[1]-0.5; z4= baseQuadCenter[2]-(0.5*sizeFactor);
567 x1+=retract; x2+=retract; x3-=retract; x4-=retract;
568 z1+=retract; z2-=retract; z3-=retract; z4+=retract;
569 dx=0.0; dy=width; dz=0.0;
573 x1= baseQuadCenter[0]-0.5; y1= baseQuadCenter[1]-(0.5*sizeFactor); z1= baseQuadCenter[2]-(0.5*sizeFactor);
574 x2= baseQuadCenter[0]-0.5; y2= baseQuadCenter[1]+(0.5*sizeFactor); z2= baseQuadCenter[2]-(0.5*sizeFactor);
575 x3= baseQuadCenter[0]-0.5; y3= baseQuadCenter[1]+(0.5*sizeFactor); z3= baseQuadCenter[2]+(0.5*sizeFactor);
576 x4= baseQuadCenter[0]-0.5; y4= baseQuadCenter[1]-(0.5*sizeFactor); z4= baseQuadCenter[2]+(0.5*sizeFactor);
577 y1+=retract; y2-=retract; y3-=retract; y4+=retract;
578 z1+=retract; z2+=retract; z3-=retract; z4-=retract;
579 dx=width; dy=0.0; dz=0.0;
582 double xcenter= (x1+x2+x3+x4)/4.0;
583 double ycenter= (y1+y2+y3+y4)/4.0;
584 double zcenter= (z1+z2+z3+z4)/4.0;
586 x5=x1-dx; y5=y1-dy; z5= z1-dz;
587 x6=x2-dx; y6=y2-dy; z6= z2-dz;
588 x7=x3-dx; y7=y3-dy; z7= z3-dz;
589 x8=x4-dx; y8=y4-dy; z8= z4-dz;
591 x1=x1+dx; y1=y1+dy; z1= z1+dz;
592 x2=x2+dx; y2=y2+dy; z2= z2+dz;
593 x3=x3+dx; y3=y3+dy; z3= z3+dz;
594 x4=x4+dx; y4=y4+dy; z4= z4+dz;
596 //if cell is oriented positively we retrac the upper face:
597 if(isSigned && aSign)
599 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;
600 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;
601 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;
604 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;
605 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;
606 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;
611 double normaleUp [3];
612 normaleUp[0] = dx!=0.0? 1.0:0.0;
613 normaleUp[1] = dy!=0.0 ? 1.0:0.0;
614 normaleUp[2] = dz!=0.0? 1.0:0.0;
615 qFaceUp.nx= normaleUp[0];
616 qFaceUp.ny= normaleUp[1];
617 qFaceUp.nz= normaleUp[2];
618 qFaceUp.point1[0]=x1; qFaceUp.point1[1]=y1; qFaceUp.point1[2]= z1;
619 qFaceUp.point2[0]=x2; qFaceUp.point2[1]=y2; qFaceUp.point2[2]= z2;
620 qFaceUp.point3[0]=x3; qFaceUp.point3[1]=y3; qFaceUp.point3[2]= z3;
621 qFaceUp.point4[0]=x4; qFaceUp.point4[1]=y4; qFaceUp.point4[2]= z4;
622 qFaceUp.color = myCurrentFillColor;
623 qFaceUp.name = name3d();
624 myPrismList.push_back(qFaceUp);
628 qFaceDown.nx= -normaleUp[0];
629 qFaceDown.ny= -normaleUp[1];
630 qFaceDown.nz= -normaleUp[2];
631 qFaceDown.point1[0]=x5; qFaceDown.point1[1]=y5; qFaceDown.point1[2]= z5;
632 qFaceDown.point2[0]=x8; qFaceDown.point2[1]=y8; qFaceDown.point2[2]= z8;
633 qFaceDown.point3[0]=x7; qFaceDown.point3[1]=y7; qFaceDown.point3[2]= z7;
634 qFaceDown.point4[0]=x6; qFaceDown.point4[1]=y6; qFaceDown.point4[2]= z6;
635 qFaceDown.color = myCurrentFillColor;
636 qFaceDown.name = name3d();
637 myPrismList.push_back(qFaceDown);
641 double vF1[3]; double v1 [3]; double n1 [3];
642 vF1[0] = x2-x1; vF1[1] = y2-y1; vF1[2] = z2-z1;
643 v1[0] = x5-x1; v1[1] = y5-y1; v1[2] = z5-z1;
646 qFace1.nx=n1[0]; qFace1.ny=n1[1]; qFace1.nz=n1[2];
647 qFace1.point1[0]= x1; qFace1.point1[1] =y1; qFace1.point1[2]=z1;
648 qFace1.point2[0]= x5; qFace1.point2[1] =y5; qFace1.point2[2]=z5;
649 qFace1.point3[0]= x6; qFace1.point3[1] =y6; qFace1.point3[2]=z6;
650 qFace1.point4[0]= x2; qFace1.point4[1] =y2; qFace1.point4[2]=z2;
651 qFace1.color = myCurrentFillColor;
652 qFace1.name = name3d();
653 myPrismList.push_back(qFace1);
657 double vF2[3]; double v2 [3]; double n2[3];
658 vF2[0]= x3-x2; vF2[1]= y3-y2; vF2[2]= z3-z2;
659 v2[0] = x6-x2; v2[1] = y6-y2; v2[2] = z6-z2;
662 qFace2.nx=n2[0]; qFace2.ny=n2[1]; qFace2.nz=n2[2];
663 qFace2.point1[0]= x2; qFace2.point1[1] =y2; qFace2.point1[2]=z2;
664 qFace2.point2[0]= x6; qFace2.point2[1] =y6; qFace2.point2[2]=z6;
665 qFace2.point3[0]= x7; qFace2.point3[1] =y7; qFace2.point3[2]=z7;
666 qFace2.point4[0]= x3; qFace2.point4[1] =y3; qFace2.point4[2]=z3;
667 qFace2.color = myCurrentFillColor;
668 qFace2.name = name3d();
669 myPrismList.push_back(qFace2);
673 double vF3[3]; double v3 [3]; double n3[3];
674 vF3[0] = x4-x3; vF3[1] = y4-y3; vF3[2] = z4-z3;
675 v3[0] = x7-x3; v3[1] = y7-y3; v3[2] = z7-z3;
678 qFace3.nx=n3[0]; qFace3.ny=n3[1]; qFace3.nz=n3[2];
679 qFace3.point1[0]= x3; qFace3.point1[1] =y3; qFace3.point1[2]=z3;
680 qFace3.point2[0]= x7; qFace3.point2[1] =y7; qFace3.point2[2]=z7;
681 qFace3.point3[0]= x8; qFace3.point3[1] =y8; qFace3.point3[2]=z8;
682 qFace3.point4[0]= x4; qFace3.point4[1] =y4; qFace3.point4[2]=z4;
683 qFace3.color = myCurrentFillColor;
684 qFace3.name = name3d();
685 myPrismList.push_back(qFace3);
689 double vF4[3]; double v4 [3]; double n4[3];
690 vF4[0] = x1-x4; vF4[1] = y1-y4; vF4[2] = z1-z4;
691 v4[0] = x8-x4; v4[1] = y8-y4; v4[2] = z8-z4;
694 qFace4.nx=n4[0]; qFace4.ny=n4[1]; qFace4.nz=n4[2];
695 qFace4.point1[0]= x4; qFace4.point1[1] =y4; qFace4.point1[2]=z4;
696 qFace4.point2[0]= x8; qFace4.point2[1] =y8; qFace4.point2[2]=z8;
697 qFace4.point3[0]= x5; qFace4.point3[1] =y5; qFace4.point3[2]=z5;
698 qFace4.point4[0]= x1; qFace4.point4[1] =y1; qFace4.point4[2]=z1;
699 qFace4.color = myCurrentFillColor;
700 qFace4.name = name3d();
701 myPrismList.push_back(qFace4);
705template < typename Space ,typename KSpace >
708DGtal::Display3D< Space ,KSpace >::addQuadFromSurfelCenter(const RealPoint &baseQuadCenter,
709 bool xSurfel, bool ySurfel, bool zSurfel)
711 updateBoundingBox(baseQuadCenter);
712 ASSERT( xSurfel || ySurfel || zSurfel );
713 boost::ignore_unused_variable_warning( xSurfel );
715 double x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
719 x1= baseQuadCenter[0]-0.5; y1= baseQuadCenter[1]-0.5; z1= baseQuadCenter[2]-0.5;
720 x2= baseQuadCenter[0]+0.5; y2= baseQuadCenter[1]-0.5; z2= baseQuadCenter[2]-0.5;
721 x3= baseQuadCenter[0]+0.5; y3= baseQuadCenter[1]+0.5; z3= baseQuadCenter[2]-0.5;
722 x4= baseQuadCenter[0]-0.5; y4= baseQuadCenter[1]+0.5; z4= baseQuadCenter[2]-0.5;
726 x1= baseQuadCenter[0]-0.5; y1= baseQuadCenter[1]-0.5; z1= baseQuadCenter[2]-0.5;
727 x2= baseQuadCenter[0]-0.5; y2= baseQuadCenter[1]-0.5; z2= baseQuadCenter[2]+0.5;
728 x3= baseQuadCenter[0]+0.5; y3= baseQuadCenter[1]-0.5; z3= baseQuadCenter[2]+0.5;
729 x4= baseQuadCenter[0]+0.5; y4= baseQuadCenter[1]-0.5; z4= baseQuadCenter[2]-0.5;
733 x1= baseQuadCenter[0]-0.5; y1= baseQuadCenter[1]-0.5; z1= baseQuadCenter[2]-0.5;
734 x2= baseQuadCenter[0]-0.5; y2= baseQuadCenter[1]+0.5; z2= baseQuadCenter[2]-0.5;
735 x3= baseQuadCenter[0]-0.5; y3= baseQuadCenter[1]+0.5; z3= baseQuadCenter[2]+0.5;
736 x4= baseQuadCenter[0]-0.5; y4= baseQuadCenter[1]-0.5; z4= baseQuadCenter[2]+0.5;
739 addQuad(RealPoint(x1, y1, z1), RealPoint(x2 ,y2, z2),
740 RealPoint(x3, y3, z3), RealPoint(x4, y4, z4));
744template < typename Space ,typename KSpace >
747DGtal::Display3D< Space ,KSpace >::addQuadFromSurfelCenterWithNormal(const RealPoint &baseQuadCenter,
748 bool xSurfel, bool ySurfel, bool zSurfel,
749 const RealVector &aNormal,
750 const bool enableReorientation,
752 const bool enableDoubleFace )
754 updateBoundingBox(baseQuadCenter);
755 ASSERT( xSurfel || ySurfel || zSurfel );
756 boost::ignore_unused_variable_warning( xSurfel );
758 double x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
762 x1= baseQuadCenter[0]-0.5; y1= baseQuadCenter[1]-0.5; z1= baseQuadCenter[2]-0.5;
763 x2= baseQuadCenter[0]+0.5; y2= baseQuadCenter[1]-0.5; z2= baseQuadCenter[2]-0.5;
764 x3= baseQuadCenter[0]+0.5; y3= baseQuadCenter[1]+0.5; z3= baseQuadCenter[2]-0.5;
765 x4= baseQuadCenter[0]-0.5; y4= baseQuadCenter[1]+0.5; z4= baseQuadCenter[2]-0.5;
770 x1= baseQuadCenter[0]-0.5; y1= baseQuadCenter[1]-0.5; z1= baseQuadCenter[2]-0.5;
771 x2= baseQuadCenter[0]-0.5; y2= baseQuadCenter[1]-0.5; z2= baseQuadCenter[2]+0.5;
772 x3= baseQuadCenter[0]+0.5; y3= baseQuadCenter[1]-0.5; z3= baseQuadCenter[2]+0.5;
773 x4= baseQuadCenter[0]+0.5; y4= baseQuadCenter[1]-0.5; z4= baseQuadCenter[2]-0.5;
777 x1= baseQuadCenter[0]-0.5; y1= baseQuadCenter[1]-0.5; z1= baseQuadCenter[2]-0.5;
778 x2= baseQuadCenter[0]-0.5; y2= baseQuadCenter[1]+0.5; z2= baseQuadCenter[2]-0.5;
779 x3= baseQuadCenter[0]-0.5; y3= baseQuadCenter[1]+0.5; z3= baseQuadCenter[2]+0.5;
780 x4= baseQuadCenter[0]-0.5; y4= baseQuadCenter[1]-0.5; z4= baseQuadCenter[2]+0.5;
783 //If we need to use the surfel sign and if it is negative, we
784 //reorder the points (see drawOriented... vs drawUnoriented methods
785 //in Display3DFactory).
786 if ((!enableReorientation) && (!sign))
787 addQuadWithNormal(RealPoint(x1, y1, z1),RealPoint(x4, y4, z4),
788 RealPoint(x3, y3, z3),
789 RealPoint(x2 ,y2, z2), aNormal,
793 addQuadWithNormal(RealPoint(x1, y1, z1), RealPoint(x2 ,y2, z2),
794 RealPoint(x3, y3, z3), RealPoint(x4, y4, z4), aNormal,
802// add multiple triangular faces which form a hexagonal-based pyramid
803template < typename Space ,typename KSpace >
806DGtal::Display3D< Space ,KSpace >::addCone(const RealPoint &p1, const RealPoint &p2,
809 updateBoundingBox(p1);
810 updateBoundingBox(p2);
812 int nbPoints = 6; //the number of point on the base of the cone
813 double degree = 360 / nbPoints; // the angle between two points
814 double radian = degree * M_PI/180.0;
815 double norm; // norm of the vectors
817 // A(x1,y1,z1) and B(x2,y2,z2) vector AB
818 double xab, yab, zab;
824 norm = sqrt( xab*xab + yab*yab + zab*zab);
825 if (norm == 0) return;
830 //take a third point M different from A and B
835 while (p1[0] == xm || p2[0] ==xm) xm++;
836 while (p1[1] == ym || p2[1] ==ym) ym++;
837 while (p1[2] == zm || p2[2] ==zm) zm++;
840 double xam, yam, zam;
841 //normal vector n = AB^AM
844 // ensure that M is not collinear to AB
851 norm = sqrt( xam*xam + yam*yam + zam*zam);
857 xn = yab*zam - yam*zab;
858 yn = xam*zab - xab*zam;
859 zn = xab*yam - xam*yab;
861 //divide n by its norm
862 norm = sqrt( xn*xn + yn*yn + zn*zn);
873 //the first point of the base
876 xf = p2[0] + width * xn;
877 yf = p2[1] + width * yn;
878 zf = p2[2] + width * zn;
880 //two following points of the base
886 //r = AB^n for the future rotation
889 createNewTriangleList("Cone");
890 for (int i =0; i < nbPoints-1; i ++)
893 xr = yab*zn - yn*zab;
894 yr = xn*zab - xab*zn;
895 zr = xab*yn - xn*yab;
898 xn = cos(radian)*xn + sin(radian)*xr;
899 yn = cos(radian)*yn + sin(radian)*yr;
900 zn = cos(radian)*zn + sin(radian)*zr;
902 //divide n by its norm
903 norm = sqrt( xn*xn + yn*yn + zn*zn);
911 // calculate one point with the normal vector at a distance width
912 xb2 = p2[0] + width * xn;
913 yb2 = p2[1] + width * yn;
914 zb2 = p2[2] + width * zn;
916 //adding the triangles associated with this point
918 RealPoint(xb1, yb1, zb1),
919 RealPoint(xb2, yb2, zb2));
921 RealPoint(xb1, yb1, zb1),
922 RealPoint(xb2, yb2, zb2));
929 //Last part to close the cone
931 RealPoint(xb1, yb1,zb1),
932 RealPoint(xf, yf, zf));
934 RealPoint(xb1, yb1, zb1),
935 RealPoint(xf, yf, zf));
938// add multiple triangular faces which form a hexagonal-based cylinder
939template < typename Space ,typename KSpace >
942DGtal::Display3D< Space ,KSpace >::addCylinder(const RealPoint &p1, const RealPoint &p2,
945 updateBoundingBox(p1);
946 updateBoundingBox(p2);
948 int nbPoints = 6; //the number of point on the base of the cone
949 double degree = 360 / nbPoints; // the angle between two points
950 double radian = degree * M_PI/180.0;
951 double norm; // norm of the vectors
953 // A(p1[0],p1[1],p1[2]) and B(p2[0],p2[1],p2[2]) vector AB
954 double xab, yab, zab;
960 norm = sqrt( xab*xab + yab*yab + zab*zab);
966 //take a third point M different from A and B
971 while (p1[0] == xm || p2[0] ==xm) xm++;
972 while (p1[1] == ym || p2[1] ==ym) ym++;
973 while (p1[2] == zm || p2[2] ==zm) zm++;
976 double xam, yam, zam;
982 norm = sqrt( xam*xam + yam*yam + zam*zam);
988 //normal vector n = AB^AM
991 xn = yab*zam - yam*zab;
992 yn = xam*zab - xab*zam;
993 zn = xab*yam - xam*yab;
995 //divide n by its norm
996 norm = sqrt( xn*xn + yn*yn + zn*zn);
1003 //the first point of the bases
1004 double xbf, ybf, zbf;
1005 double xaf, yaf, zaf;
1007 xbf = p2[0] + width * xn;
1008 ybf = p2[1] + width * yn;
1009 zbf = p2[2] + width * zn;
1011 xaf = p1[0] + width * xn;
1012 yaf = p1[1] + width * yn;
1013 zaf = p1[2] + width * zn;
1015 //two following points of the bases
1019 double xb2,yb2, zb2;
1024 double xa2,ya2, za2;
1026 //r = AB^n for the future rotation
1029 createNewTriangleList("Cylinder");
1030 //createNewQuadList("Cylinder");
1031 for (int i =0; i < nbPoints-1; i ++)
1034 xr = yab*zn - yn*zab;
1035 yr = xn*zab - xab*zn;
1036 zr = xab*yn - xn*yab;
1038 //rotate n by degree
1039 xn = cos(radian)*xn + sin(radian)*xr;
1040 yn = cos(radian)*yn + sin(radian)*yr;
1041 zn = cos(radian)*zn + sin(radian)*zr;
1043 //divide n by its norm (used when a bug appear)
1044 norm = sqrt( xn*xn + yn*yn + zn*zn);
1050 // calculate one point with the normal vector at a distance width
1051 xb2 = p2[0] + width * xn;
1052 yb2 = p2[1] + width * yn;
1053 zb2 = p2[2] + width * zn;
1055 xa2 = p1[0] + width * xn;
1056 ya2 = p1[1] + width * yn;
1057 za2 = p1[2] + width * zn;
1059 //adding the triangles and the quad associated with those points
1061 RealPoint(xa1, ya1, za1),
1062 RealPoint(xa2, ya2, za2));
1064 RealPoint(xb1, yb1, zb1),
1065 RealPoint(xb2, yb2, zb2));
1066 addQuad(RealPoint(xb1, yb1, zb1),
1067 RealPoint(xb2, yb2, zb2),
1068 RealPoint(xa2, ya2, za2),
1069 RealPoint(xa1, ya1, za1));
1081 //Last part to close the cylinder
1083 RealPoint(xa1, ya1, za1),
1084 RealPoint(xaf, yaf, zaf));
1086 RealPoint(xb1, yb1, zb1),
1087 RealPoint(xbf, ybf, zbf));
1088 addQuad(RealPoint(xb1, yb1, zb1),
1089 RealPoint(xbf, ybf, zbf),
1090 RealPoint(xaf, yaf, zaf),
1091 RealPoint(xa1, ya1, za1));
1096template < typename Space ,typename KSpace >
1099DGtal::Display3D< Space ,KSpace >::addClippingPlane(double a, double b, double c, double d, bool drawPlane)
1101 ClippingPlaneD3D cp;
1102 cp.a=a; cp.b=b; cp.c=c; cp.d=d;
1103 myClippingPlaneList.push_back(cp);
1109 double norm = sqrt(a*a+b*b+c*c);
1111 // Z dominant projection of the upper face
1112 if(std::abs(c)>=std::abs(b) && std::abs(c) >= std::abs(a))
1114 x1= myBoundingPtUp[0]+a*dec/norm; y1= myBoundingPtUp[1]+b*dec/norm;
1115 z1 = c*dec/norm +(-d-a*myBoundingPtUp[0]-b*myBoundingPtUp[1])/c;
1116 x2= myBoundingPtLow[0]+a*dec/norm; y2= myBoundingPtUp[1]+b*dec/norm;
1117 z2= c*dec/norm+(-d-a*myBoundingPtLow[0]-b*myBoundingPtUp[1])/c;
1118 x3= myBoundingPtLow[0]+a*dec/norm; y3= myBoundingPtLow[1]+b*dec/norm;
1119 z3= c*dec/norm+(-d-a*myBoundingPtLow[0]-b*myBoundingPtLow[1])/c;
1120 x4= myBoundingPtUp[0]+a*dec/norm; y4= myBoundingPtLow[1]+b*dec/norm;
1121 z4= c*dec/norm+(-d-a*myBoundingPtUp[0]-b*myBoundingPtLow[1])/c;
1124 addQuad(RealPoint(x4,y4,z4),RealPoint(x3,y3,z3),
1125 RealPoint(x2,y2,z2),RealPoint(x1,y1,z1) );
1128 addQuad(RealPoint(x1,y1,z1), RealPoint( x2,y2,z2),
1129 RealPoint(x3,y3,z3), RealPoint(x4,y4,z4));
1131 }// Y dominant projection of the upper face
1132 else if(std::abs(b)>=std::abs(c) && std::abs(b) >= std::abs(a))
1134 x1= myBoundingPtUp[0]+a*dec/norm; z1= myBoundingPtUp[2]+c*dec/norm;
1135 y1= b*dec/norm +(-d-a*myBoundingPtUp[0]-c*myBoundingPtUp[2])/b;
1136 x2= myBoundingPtUp[0]+a*dec/norm; z2= myBoundingPtLow[2]+c*dec/norm;
1137 y2= b*dec/norm +(-d-a*myBoundingPtUp[0]-c*myBoundingPtLow[2])/b;
1138 x3= myBoundingPtLow[0]+a*dec/norm; z3= myBoundingPtLow[2]+c*dec/norm;
1139 y3= b*dec/norm +(-d-a*myBoundingPtLow[0]-c*myBoundingPtLow[2])/b;
1140 x4= myBoundingPtLow[0]+a*dec/norm; z4= myBoundingPtUp[2]+c*dec/norm;
1141 y4= b*dec/norm +(-d-a*myBoundingPtLow[0]-c*myBoundingPtUp[2])/b;
1144 addQuad(RealPoint(x4,y4,z4),RealPoint(x3, y3,z3),
1145 RealPoint(x2,y2,z2), RealPoint(x1,y1,z1));
1148 addQuad(RealPoint(x1,y1,z1), RealPoint(x2,y2,z2),
1149 RealPoint(x3,y3,z3), RealPoint(x4,y4,z4));
1151 }// X dominant projection of the upper face
1152 else if(std::abs(a)>=std::abs(c) && std::abs(a) >= std::abs(b))
1154 y1= myBoundingPtUp[1]+b*dec/norm; z1= myBoundingPtUp[2]+c*dec/norm;
1155 x1= a*dec/norm +(-d-b*myBoundingPtUp[1]-c*myBoundingPtUp[2])/a;
1156 y2= myBoundingPtLow[1]+b*dec/norm; z2= myBoundingPtUp[2]+c*dec/norm;
1157 x2= a*dec/norm +(-d-b*myBoundingPtLow[1]-c*myBoundingPtUp[2])/a;
1158 y3= myBoundingPtLow[1]+b*dec/norm; z3= myBoundingPtLow[2]+c*dec/norm;
1159 x3= a*dec/norm +(-d-b*myBoundingPtLow[1]-c*myBoundingPtLow[2])/a;
1160 y4= myBoundingPtUp[1]+b*dec/norm; z4= myBoundingPtLow[2]+c*dec/norm;
1161 x4= a*dec/norm +(-d-b*myBoundingPtUp[1]-c*myBoundingPtLow[2])/a;
1166 addQuad(RealPoint(x4,y4,z4),
1167 RealPoint(x3,y3,z3),
1168 RealPoint(x2,y2,z2),
1169 RealPoint(x1,y1,z1));
1172 addQuad( RealPoint(x1,y1,z1), RealPoint(x2,y2,z2),
1173 RealPoint(x3,y3,z3),RealPoint(x4,y4,z4));
1180template < typename Space ,typename KSpace >
1183DGtal::Display3D< Space ,KSpace >::updateBoundingBox(const RealPoint &p)
1185 if (myBoundingPtEmptyTag)
1187 myBoundingPtLow[0]= p[0];
1188 myBoundingPtLow[1]= p[1];
1189 myBoundingPtLow[2]= p[2];
1190 myBoundingPtUp[0]= p[0];
1191 myBoundingPtUp[1]= p[1];
1192 myBoundingPtUp[2]= p[2];
1193 myBoundingPtEmptyTag = false;
1194 myBoundingPtChangedTag = true;
1198 if ( p[ 0 ] < myBoundingPtLow[ 0 ] )
1200 myBoundingPtLow[ 0 ] = p[ 0 ];
1201 myBoundingPtChangedTag = true;
1203 if ( p[ 1 ] < myBoundingPtLow[ 1 ] )
1205 myBoundingPtLow[ 1 ] = p[ 1 ];
1206 myBoundingPtChangedTag = true;
1209 if ( p[ 2 ] < myBoundingPtLow[ 2 ] )
1211 myBoundingPtLow[ 2 ] = p[ 2 ];
1212 myBoundingPtChangedTag = true;
1215 if ( p[ 0 ] > myBoundingPtUp[ 0 ] )
1217 myBoundingPtUp[ 0 ] = p[ 0 ];
1218 myBoundingPtChangedTag = true;
1220 if ( p[ 1 ] > myBoundingPtUp[ 1 ] )
1222 myBoundingPtUp[ 1 ] = p[ 1 ];
1223 myBoundingPtChangedTag = true;
1225 if ( p[ 2 ] > myBoundingPtUp[ 2 ] )
1227 myBoundingPtUp[ 2 ] = p[ 2 ];
1228 myBoundingPtChangedTag = true;
1234template < typename Space ,typename KSpace >
1236typename DGtal::Display3D< Space ,KSpace >::RealPoint
1237DGtal::Display3D< Space ,KSpace >::embed( const typename Space::Point & dp ) const
1239 ASSERT( myEmbedder->isValid());
1240 return myEmbedder->embed(dp);
1243template < typename Space ,typename KSpace >
1245typename DGtal::Display3D< Space ,KSpace >::RealPoint
1246DGtal::Display3D< Space ,KSpace >::embedKS( const typename KSpace::SCell & scell ) const
1248 ASSERT( mySCellEmbedder->isValid());
1249 return mySCellEmbedder->embed(scell);
1252template < typename Space ,typename KSpace >
1254typename DGtal::Display3D< Space ,KSpace >::RealPoint
1255DGtal::Display3D< Space ,KSpace >::embedKS( const TransformedPrism & aTrans ) const
1257 ASSERT( mySCellEmbedder->isValid());
1258 return mySCellEmbedder->embed(aTrans.mySurfel);
1262template < typename Space ,typename KSpace >
1264typename DGtal::Display3D< Space ,KSpace >::RealPoint
1265DGtal::Display3D< Space ,KSpace >::embedK( const typename KSpace::Cell & cell ) const
1267 ASSERT( myCellEmbedder->isValid());
1268 return myCellEmbedder->embed(cell);
1271template < typename Space ,typename KSpace >
1274DGtal::Display3D< Space ,KSpace >::exportToMesh(DGtal::Mesh<RealPoint> &aMesh) const
1276 unsigned int vertexIndex=0;
1278 // Export of SurfelPrism lists (generated from KhalimskyCell or SignedKhalimskyCell (through addPrism))
1279 for (unsigned int i=0; i< myPrismList.size(); i++)
1281 QuadD3D quad = myPrismList.at(i);
1282 RealPoint p1, p2, p3, p4;
1287 aMesh.addVertex(p1);
1288 aMesh.addVertex(p2);
1289 aMesh.addVertex(p3);
1290 aMesh.addVertex(p4);
1291 aMesh.addQuadFace(vertexIndex, vertexIndex+1, vertexIndex+2,vertexIndex+3,
1298 for (typename QuadsMap::const_iterator it = myQuadsMap.begin(); it != myQuadsMap.end(); it++)
1300 for (typename std::vector<QuadD3D>::const_iterator aQuad = it->second.begin(); aQuad!=it->second.end();aQuad ++)
1302 RealPoint p1, p2, p3, p4;
1307 aMesh.addVertex(p4);
1308 aMesh.addVertex(p3);
1309 aMesh.addVertex(p2);
1310 aMesh.addVertex(p1);
1311 aMesh.addQuadFace(vertexIndex,vertexIndex+1, vertexIndex+2, vertexIndex+3,
1317 // Export the mesh from TriangleList
1318 for ( typename std::vector<std::vector<TriangleD3D> >::const_iterator it =myTriangleSetList.begin(); it != myTriangleSetList.end(); it++)
1320 for (typename std::vector<TriangleD3D>::const_iterator aTriangle = it->begin(); aTriangle!=it->end();aTriangle ++)
1322 RealPoint p1, p2, p3;
1323 p1=aTriangle->point1;
1324 p2=aTriangle->point2;
1325 p3=aTriangle->point3;
1326 aMesh.addVertex(p1);
1327 aMesh.addVertex(p2);
1328 aMesh.addVertex(p3);
1329 aMesh.addTriangularFace(vertexIndex, vertexIndex+1, vertexIndex+2,
1335 // Export of cubeSet (generated from addCube)
1337 for (typename CubesMap::const_iterator it = myCubesMap.begin(); it != myCubesMap.end(); it++)
1339 for (typename std::vector<CubeD3D>::const_iterator itCube = it->second.begin(); itCube!=it->second.end(); itCube++)
1342 CubeD3D cube = *itCube;
1343 RealPoint p1, p2, p3, p4, p5, p6, p7, p8;
1344 double width= cube.width;
1346 p1 = RealPoint(cube.center[0]-width, cube.center[1]+width, cube.center[2]+width);
1347 p2 = RealPoint(cube.center[0]+width, cube.center[1]+width, cube.center[2]+width);
1348 p3 = RealPoint(cube.center[0]+width, cube.center[1]-width, cube.center[2]+width);
1349 p4 = RealPoint(cube.center[0]-width, cube.center[1]-width, cube.center[2]+width);
1350 p5 = RealPoint(cube.center[0]-width, cube.center[1]+width, cube.center[2]-width);
1351 p6 = RealPoint(cube.center[0]+width, cube.center[1]+width, cube.center[2]-width);
1352 p7 = RealPoint(cube.center[0]+width, cube.center[1]-width, cube.center[2]-width);
1353 p8 = RealPoint(cube.center[0]-width, cube.center[1]-width, cube.center[2]-width);
1355 aMesh.addVertex(p1);
1356 aMesh.addVertex(p2);
1357 aMesh.addVertex(p3);
1358 aMesh.addVertex(p4);
1359 aMesh.addVertex(p5);
1360 aMesh.addVertex(p6);
1361 aMesh.addVertex(p7);
1362 aMesh.addVertex(p8);
1365 aMesh.addQuadFace(vertexIndex, vertexIndex+3, vertexIndex+2, vertexIndex+1,
1368 aMesh.addQuadFace(vertexIndex+4, vertexIndex+5, vertexIndex+6, vertexIndex+7,
1371 aMesh.addQuadFace(vertexIndex+1, vertexIndex+2, vertexIndex+6, vertexIndex+5,
1374 aMesh.addQuadFace(vertexIndex, vertexIndex+4, vertexIndex+7, vertexIndex+3,
1377 aMesh.addQuadFace(vertexIndex, vertexIndex+1, vertexIndex+5, vertexIndex+4,
1380 aMesh.addQuadFace(vertexIndex+3, vertexIndex+7, vertexIndex+6, vertexIndex+2,
1389template < typename Space ,typename KSpace >
1390template<typename TDrawableWithDisplay3D>
1392DGtal::Display3D< Space ,KSpace >&
1393DGtal::Display3D< Space ,KSpace >::operator <<( const TDrawableWithDisplay3D & object )
1395 // BOOST_CONCEPT_ASSERT((CDrawableWithDisplay3D< TDrawableWithDisplay3D >));
1397 DGtal::Display3DFactory<Space,KSpace>::draw(*this, object);
1402template < typename Space ,typename KSpace >
1405DGtal::operator<< ( std::ostream & out,
1406 const Display3D< Space ,KSpace >& object )
1408 object.selfDisplay ( out );
1413template < typename Space ,typename KSpace >
1416DGtal::operator>> ( const Display3D< Space ,KSpace >&aDisplay3D, DGtal::Mesh< typename Display3D<Space , KSpace >::RealPoint > &aMesh)
1418 aDisplay3D.exportToMesh(aMesh);
1422template < typename Space ,typename KSpace >
1425DGtal::operator>> ( const Display3D< Space ,KSpace >&aDisplay3D, std::string aFilename)
1427 // exporting with a mesh containing color (parameter constructor to true):
1428 DGtal::Mesh<typename Display3D<Space , KSpace >::RealPoint> mesh(true);
1430 trace.info() << "generating faces done." << std::endl;
1432 trace.info() << "file exported in file: " << aFilename << std::endl;
1436template < typename Space ,typename KSpace >
1439DGtal::Display3D< Space ,KSpace >::cross (double dst[3], double srcA[3], double srcB[3])
1441 dst[0] = srcA[1]*srcB[2] - srcA[2]*srcB[1];
1442 dst[1] = srcA[2]*srcB[0] - srcA[0]*srcB[2];
1443 dst[2] = srcA[0]*srcB[1] - srcA[1]*srcB[0];
1447template < typename Space ,typename KSpace >
1450DGtal::Display3D< Space ,KSpace >::normalize (double vec[3])
1452 const double squaredLen = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
1453 vec[0] /= sqrt (squaredLen);
1454 vec[1] /= sqrt (squaredLen);
1455 vec[2] /= sqrt (squaredLen);
1458template < typename Space ,typename KSpace >
1461DGtal::Display3D< Space ,KSpace >::isValid() const
1463 return myEmbedder->isValid()
1464 && myCellEmbedder->isValid()
1465 && mySCellEmbedder->isValid();
1468template < typename Space ,typename KSpace >
1471DGtal::Display3D< Space ,KSpace >::clear()
1474 myLineSetList.clear();
1475 myBallSetList.clear();
1476 myClippingPlaneList.clear();
1477 myPrismList.clear();
1479 myTriangleSetList.clear();
1480 myPolygonSetList.clear();
1481 myCubeSetNameList.clear();
1482 myLineSetNameList.clear();
1483 myBallSetNameList.clear();
1484 myClippingPlaneNameList.clear();
1485 myPrismNameList.clear();
1487myTriangleSetNameList.clear();
1488 myPolygonSetNameList.clear();
1490 //Bounding box reset
1491 myBoundingPtEmptyTag = true;
1492 for (unsigned int i=0; i< 3; i++)
1494 myBoundingPtUp[i] = 0.0;
1495 myBoundingPtLow[i] = 0.0;
1502///////////////////////////////////////////////////////////////////////////////