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 //
57 template < typename Space ,typename KSpace >
60 DGtal::Display3D< Space ,KSpace >::setFillColor(DGtal::Color aColor)
62 myCurrentFillColor=aColor;
65 template < typename Space ,typename KSpace >
68 DGtal::Display3D< Space ,KSpace >::setFillTransparency(unsigned char alpha)
70 myCurrentFillColor.alpha(alpha);
73 template < typename Space ,typename KSpace >
76 DGtal::Display3D< Space ,KSpace >::setLineColor(DGtal::Color aColor)
78 myCurrentLineColor=aColor;
82 template < typename Space ,typename KSpace >
85 DGtal::Display3D< Space ,KSpace >::setKSpace( const KSpace & aKSpace )
88 *myCellEmbedder = CellEmbedder( myKSpace );
89 *mySCellEmbedder = SCellEmbedder( myKSpace );
93 template < typename Space ,typename KSpace >
96 DGtal::Display3D< Space ,KSpace >::getLineColor()
98 return myCurrentLineColor;
101 template < typename Space ,typename KSpace >
104 DGtal::Display3D< Space ,KSpace >::getFillColor()
106 return myCurrentFillColor;
109 //-----------------------------------------------------------------------------
110 template < typename Space ,typename KSpace >
113 DGtal::Display3D< Space ,KSpace >::
114 setName3d( DGtal::int32_t name )
119 //-----------------------------------------------------------------------------
120 template < typename Space ,typename KSpace >
123 DGtal::Display3D< Space ,KSpace >::
128 //-----------------------------------------------------------------------------
129 template < typename Space ,typename KSpace >
132 DGtal::Display3D< Space ,KSpace >::
133 setSelectCallback3D( 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 //-----------------------------------------------------------------------------
139 template < typename Space ,typename KSpace >
141 typename DGtal::Display3D< Space ,KSpace >::SelectCallbackFct
142 DGtal::Display3D< Space ,KSpace >::
143 getSelectCallback3D( 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 //-----------------------------------------------------------------------------
168 template < typename Space ,typename KSpace >
171 DGtal::Display3D< Space ,KSpace >::getMode( const std::string & objectName ) const
173 ModeMapping::const_iterator itm = myModes.find( objectName );
174 return itm == myModes.end() ? "" : itm->second;
178 template < typename Space ,typename KSpace >
181 DGtal::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());
198 template < typename Space ,typename KSpace >
201 DGtal::Display3D< Space ,KSpace >::deleteCubeList(const DGtal::int32_t idList)
203 return myCubesMap.erase(idList);
207 template < typename Space ,typename KSpace >
210 DGtal::Display3D< Space ,KSpace >::createNewBallList(std::string str)
212 std::vector< BallD3D > v;
213 myBallSetList.push_back(v);
214 myBallSetNameList.push_back(str);
217 template < typename Space ,typename KSpace >
220 DGtal::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());
250 template < typename Space ,typename KSpace >
253 DGtal::Display3D< Space ,KSpace >::deleteQuadList(const DGtal::int32_t idList)
255 return myQuadsMap.erase(idList);
260 template < typename Space ,typename KSpace >
263 DGtal::Display3D< Space ,KSpace >::createNewTriangleList(std::string str)
265 std::vector< TriangleD3D > v;
266 myTriangleSetList.push_back(v);
267 myTriangleSetNameList.push_back(str);
270 template < typename Space ,typename KSpace >
273 DGtal::Display3D< Space ,KSpace >::createNewPolygonList(std::string str)
275 std::vector< PolygonD3D > v;
276 myPolygonSetList.push_back(v);
277 myPolygonSetNameList.push_back(str);
281 template < typename Space ,typename KSpace >
284 DGtal::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 );
299 template < typename Space ,typename KSpace >
302 DGtal::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);
322 template < typename Space ,typename KSpace >
325 DGtal::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);
343 template < typename Space ,typename KSpace >
346 DGtal::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);
357 template < typename Space ,typename KSpace >
360 DGtal::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 );
441 template < typename Space ,typename KSpace >
444 DGtal::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);
478 template < typename Space ,typename KSpace >
481 DGtal::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);
530 template < typename Space ,typename KSpace >
533 DGtal::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);
705 template < typename Space ,typename KSpace >
708 DGtal::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));
744 template < typename Space ,typename KSpace >
747 DGtal::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
803 template < typename Space ,typename KSpace >
806 DGtal::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
939 template < typename Space ,typename KSpace >
942 DGtal::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));
1096 template < typename Space ,typename KSpace >
1099 DGtal::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));
1180 template < typename Space ,typename KSpace >
1183 DGtal::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;
1234 template < typename Space ,typename KSpace >
1236 typename DGtal::Display3D< Space ,KSpace >::RealPoint
1237 DGtal::Display3D< Space ,KSpace >::embed( const typename Space::Point & dp ) const
1239 ASSERT( myEmbedder->isValid());
1240 return myEmbedder->embed(dp);
1243 template < typename Space ,typename KSpace >
1245 typename DGtal::Display3D< Space ,KSpace >::RealPoint
1246 DGtal::Display3D< Space ,KSpace >::embedKS( const typename KSpace::SCell & scell ) const
1248 ASSERT( mySCellEmbedder->isValid());
1249 return mySCellEmbedder->embed(scell);
1252 template < typename Space ,typename KSpace >
1254 typename DGtal::Display3D< Space ,KSpace >::RealPoint
1255 DGtal::Display3D< Space ,KSpace >::embedKS( const TransformedPrism & aTrans ) const
1257 ASSERT( mySCellEmbedder->isValid());
1258 return mySCellEmbedder->embed(aTrans.mySurfel);
1262 template < typename Space ,typename KSpace >
1264 typename DGtal::Display3D< Space ,KSpace >::RealPoint
1265 DGtal::Display3D< Space ,KSpace >::embedK( const typename KSpace::Cell & cell ) const
1267 ASSERT( myCellEmbedder->isValid());
1268 return myCellEmbedder->embed(cell);
1271 template < typename Space ,typename KSpace >
1274 DGtal::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,
1389 template < typename Space ,typename KSpace >
1390 template<typename TDrawableWithDisplay3D>
1392 DGtal::Display3D< Space ,KSpace >&
1393 DGtal::Display3D< Space ,KSpace >::operator <<( const TDrawableWithDisplay3D & object )
1395 // BOOST_CONCEPT_ASSERT((CDrawableWithDisplay3D< TDrawableWithDisplay3D >));
1397 DGtal::Display3DFactory<Space,KSpace>::draw(*this, object);
1402 template < typename Space ,typename KSpace >
1405 DGtal::operator<< ( std::ostream & out,
1406 const Display3D< Space ,KSpace >& object )
1408 object.selfDisplay ( out );
1413 template < typename Space ,typename KSpace >
1416 DGtal::operator>> ( const Display3D< Space ,KSpace >&aDisplay3D, DGtal::Mesh< typename Display3D<Space , KSpace >::RealPoint > &aMesh)
1418 aDisplay3D.exportToMesh(aMesh);
1422 template < typename Space ,typename KSpace >
1425 DGtal::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;
1436 template < typename Space ,typename KSpace >
1439 DGtal::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];
1447 template < typename Space ,typename KSpace >
1450 DGtal::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);
1458 template < typename Space ,typename KSpace >
1461 DGtal::Display3D< Space ,KSpace >::isValid() const
1463 return myEmbedder->isValid()
1464 && myCellEmbedder->isValid()
1465 && mySCellEmbedder->isValid();
1468 template < typename Space ,typename KSpace >
1471 DGtal::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();
1487 myTriangleSetNameList.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 ///////////////////////////////////////////////////////////////////////////////