2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
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 Martial Tola <http://liris.cnrs.fr/martial.tola/>
20 * @date mercredi 22 juin 2011
24 * Implementation of inline methods defined in Board3D.h
26 * This file is part of the DGtal library.
29 ///////////////////////////////////////////////////////////////////////////////
30 // IMPLEMENTATION of inline methods.
31 ///////////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////////
35 #include "DGtal/io/CDrawableWithDisplay3D.h"
36 #include "DGtal/io/Color.h"
39 //////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
42 // Implementation of inline methods //
45 * Set the default color for future drawing.
47 * @param aColor a DGtal::Color (allow to set a trasnparency value).
50 template < typename Space, typename KSpace>
52 DGtal::Board3D<Space, KSpace> &
53 DGtal::Board3D<Space, KSpace>::operator<<(const DGtal::Color & aColor)
55 myDefaultColor=aColor;
61 * Draws the drawable [object] in this board. It should satisfy
62 * the concept CDrawableWithBoard3D, which requires for instance a
63 * method setStyle( Board3D & ).
65 * @param object any drawable object.
66 * @return a reference on 'this'.
68 template < typename Space, typename KSpace>
69 template <typename TDrawableWithDisplay3D>
71 DGtal::Board3D<Space, KSpace> &
72 DGtal::Board3D<Space, KSpace>::operator<<( const TDrawableWithDisplay3D & object )
74 BOOST_CONCEPT_ASSERT((concepts::CDrawableWithDisplay3D< TDrawableWithDisplay3D, Space, KSpace>));
76 DGtal::Display3DFactory<Space,KSpace>::draw(*this, object);
82 ///////////////////////////////////////////////////////////////////////////////
83 // Standard services - public :
88 template < typename Space, typename KSpace>
90 DGtal::Board3D<Space, KSpace>::Board3D() : Display3D<Space,KSpace>()
95 ///////////////////////////////////////////////////////////////////////////////
96 // Interface - public :
99 * Writes/Displays the object on an output stream.
100 * @param outOBJ the output stream where the object is written.
102 template < typename Space, typename KSpace>
105 DGtal::Board3D<Space, KSpace>::selfDisplay ( std::ostream & outOBJ ) const
107 outOBJ << "[Board3D]";
111 * Checks the validity/consistency of the object.
112 * @return 'true' if the object is valid, 'false' otherwise.
114 template < typename Space, typename KSpace>
116 DGtal::Board3D<Space, KSpace>::isValid() const
124 * @param filename filename of the image to save.
126 template < typename Space, typename KSpace>
128 void DGtal::Board3D<Space, KSpace>::saveOBJ(const std::string & filename, const bool normalization)
131 size_t k, j; //id of each elements and sub elements of a list for the .OBJ identification
132 std::ofstream outOBJ; //OBJ file where to write
133 std::ofstream outMTL; //MTL file where to write
135 //the filename without OBJ any extention
137 size_t lastdot = filename.find_last_of(".");
138 if (lastdot != std::string::npos)
139 noExt = filename.substr(0, lastdot);
143 std::stringstream nameOBJ;
144 std::stringstream nameMTL;
145 nameOBJ << noExt << ".obj";
146 nameMTL << noExt << ".mtl";
148 outOBJ.open(nameOBJ.str().c_str());
149 outOBJ << "# OBJ format"<< "\n";
150 outOBJ << "# generated from Board3D from the DGtal library"<< "\n";
151 outOBJ << "mtllib " << nameMTL.str() << "\n";
154 outMTL.open(nameMTL.str().c_str());
155 outMTL << "# MTL format"<< "\n";
156 outMTL << "# generated from Board3D from the DGtal library"<< "\n";
159 //myClippingPlaneList++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
160 //std::vector< clippingPlaneD3D >::const_iterator
162 if(Board3D<Space, KSpace>::myClippingPlaneList.size()> 0)
164 trace.info() << "number of clipping plane : "
165 << Board3D<Space, KSpace>::myClippingPlaneList.size() << std::endl;
169 // normalization -----------------------------------------------------------------------
171 typename Space::RealPoint shift(0.0,0.0,0.0);
174 //We center the shape W.r.t. its bounding box
175 for(unsigned int i=0; i < 3; i++)
176 shift[i] = (this->myBoundingPtUp[i] + this->myBoundingPtLow[i])/2.0;
178 //We compute the scale of the largest direction so that it fits
179 //in [-1/2,1/2] interval
183 while ((i<3) && (this->myBoundingPtUp[i] - this->myBoundingPtLow[i] == 0))
185 ASSERT_MSG(i < 3, "Error when computing the scale from the bounding box. The Bbox seems to be empty.");
187 scale = 1.0/(this->myBoundingPtUp[i] - this->myBoundingPtLow[i]);
190 tmpwidth = (this->myBoundingPtUp[i] - this->myBoundingPtLow[i]);
191 if ((tmpwidth != 0.0) && (scale > 1.0/tmpwidth))
192 scale = 1.0/tmpwidth;
194 outOBJ << "# Normalization was used. Scale= "<< scale << " and Shift= "<<shift<< "\n";
197 // Draw the shapes -----------------------------------------------------------------------
199 ///Temporary variables
200 typename Space::RealPoint apoint, apoint1, apoint2, apoint3, apoint4;
202 // myBallSetList++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
204 k=0;//id of each BallSetList for the .OBJ identification
205 for ( typename std::vector< std::vector< typename Board3D<Space, KSpace>::BallD3D> >::const_iterator it = Board3D<Space, KSpace>::myBallSetList.begin();
206 it != Board3D<Space, KSpace>::myBallSetList.end(); it++)
208 std::ostringstream tmpStream; // checking that points exist before creating an object
209 for (typename std::vector< typename Board3D<Space, KSpace>::BallD3D>::const_iterator s_it = it->begin();
210 s_it != it->end(); s_it++)
212 //test if a clipping plane do not cut it
214 typename std::vector< typename Board3D<Space, KSpace>::ClippingPlaneD3D>::const_iterator itClip = Board3D<Space, KSpace>::myClippingPlaneList.begin();
215 while (itClip !=Board3D<Space, KSpace>::myClippingPlaneList.end() && notCut )
217 double d2 = ( itClip->a * (*s_it)[0]) + (itClip->b * (*s_it)[1]) + ( itClip->c * (*s_it)[2] ) + itClip->d;
224 double thetaResolution = s_it->resolution;
225 double thetaStep= (2.0*M_PI)/thetaResolution;
226 double phiResolution = s_it->resolution;
227 double phiStep= M_PI/phiResolution;
229 double radius = s_it->radius*scale;
230 double xCenter = (s_it->center[0]-shift[0])*scale;
231 double yCenter = (s_it->center[1]-shift[0])*scale;
232 double zCenter = (s_it->center[2]-shift[0])*scale;
234 for(unsigned int jj =0; jj < phiResolution; jj++)
236 double phi0 = M_PI/2.0-jj*phiStep;
237 double phi1 = M_PI/2.0-(jj+1)*phiStep;
238 for(unsigned int i =0; i < thetaResolution; i++)
240 double theta0 = i * thetaStep;
241 double theta1 = (i+1) * thetaStep;
242 tmpStream << "v " << xCenter+cos(phi0)*cos(theta0)*radius
243 << " " << yCenter+ cos(phi0)*sin(theta0)*radius << " " << zCenter+ sin(phi0)*radius << "\n";
244 tmpStream << "v " << xCenter+cos(phi0)*cos(theta1)*radius
245 << " " << yCenter+ cos(phi0)*sin(theta1)*radius << " " << zCenter+ sin(phi0)*radius << "\n";
246 tmpStream << "v " << xCenter+cos(phi1)*cos(theta0)*radius << " "
247 << yCenter+ cos(phi1)*sin(theta0)*radius << " " <<zCenter+ sin(phi1)*radius << "\n";
248 tmpStream << "f " << "-1" << " " << "-2" << " " << "-3"<< "\n";
250 tmpStream << "v " << xCenter+cos(phi0)*cos(theta1)*radius
251 << " " << yCenter+ cos(phi0)*sin(theta1)*radius << " " << zCenter+ sin(phi0)*radius << "\n";
252 tmpStream << "v " << xCenter+cos(phi1)*cos(theta0)*radius << " "
253 << yCenter+ cos(phi1)*sin(theta0)*radius << " " <<zCenter+ sin(phi1)*radius << "\n";
254 tmpStream << "v " << xCenter+cos(phi1)*cos(theta1)*radius << " "
255 << yCenter+ cos(phi1)*sin(theta1)*radius << " " <<zCenter+ sin(phi1)*radius << "\n";
256 tmpStream << "f " << "-3" << " " << "-2" << " " << "-1"<< "\n";
262 if (tmpStream.str().size() > 0)
264 std::stringstream name;
265 name << Board3D<Space, KSpace>::myBallSetNameList.at(k);
266 if ( name.str() == "")
268 name << "myBallSetList_" << k ;
271 typename std::vector< typename Board3D<Space, KSpace>::BallD3D>::const_iterator itBegin = it->begin();
272 unsigned int matid = getMaterialIndex(itBegin->color);
273 std::stringstream matName;
274 matName << "Mat_" << matid;
275 outOBJ << "o " << name.str() << "\n";
276 outOBJ << "usemtl " << matName.str() << "\n";
277 outOBJ << tmpStream.str();
283 // myLineSetList+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
286 k=0;//id of each LineSetList for the .OBJ identification
287 for(typename std::vector<std::vector< typename Board3D<Space, KSpace>::LineD3D> >::const_iterator it =Board3D<Space, KSpace>::myLineSetList.begin();
288 it!= Board3D<Space, KSpace>::myLineSetList.end(); it++)
290 std::ostringstream tmpStream;
291 for (typename std::vector< typename Board3D<Space, KSpace>::LineD3D>::const_iterator s_it = it->begin();
292 s_it != it->end();++s_it)
295 //test if a clipping plane do not cut it
297 double width = s_it->width;
298 typename std::vector< typename Board3D<Space, KSpace>::ClippingPlaneD3D>::const_iterator itClip = Board3D<Space, KSpace>::myClippingPlaneList.begin();
299 while (itClip !=Board3D<Space, KSpace>::myClippingPlaneList.end() && notCut )
301 double a = itClip->a;
302 double b = itClip->b;
303 double c = itClip->c;
304 double d = itClip->d;
306 d2 = ( a * s_it->point1[0]) + (b * (s_it->point1[1] -width)) + ( c * s_it->point1[2] ) + d;
308 d2 = ( a * s_it->point1[0]) + (b * (s_it->point1[1] +width)) + ( c * s_it->point1[2] ) + d;
309 notCut = ( notCut && ( d2 >= 0) );
310 d2 = ( a * s_it->point2[0]) + (b * (s_it->point2[1] +width)) + ( c * s_it->point2[2] ) + d;
311 notCut = ( notCut && ( d2 >= 0) );
312 d2 = ( a * s_it->point2[0]) + (b * (s_it->point2[1] -width)) + ( c * s_it->point2[2] ) + d;
313 notCut = ( notCut && ( d2 >= 0) );
314 d2 = ( a * s_it->point1[0]) + (b * s_it->point1[1]) + ( c * (s_it->point1[2] -width )) + d;
315 notCut = ( notCut && ( d2 >= 0) );
316 d2 = ( a * s_it->point1[0]) + (b * s_it->point1[1]) + ( c * (s_it->point1[2] +width )) + d;
317 notCut = ( notCut && ( d2 >= 0) );
318 d2 = ( a * s_it->point2[0]) + (b * s_it->point2[1]) + ( c * (s_it->point2[2] +width )) + d;
319 notCut = ( notCut && ( d2 >= 0) );
320 d2 = ( a * s_it->point2[0]) + (b * s_it->point2[1]) + ( c * (s_it->point2[2] -width )) + d;
321 notCut = ( notCut && ( d2 >= 0) );
328 // OBJ dont know how to draw lines, have to make a
329 // cuboid with a depth and height of a pixel width
331 apoint1 = ((s_it->point1) - shift)*scale;
332 apoint2 = ((s_it->point2) - shift)*scale;
333 tmpStream << "v " << apoint1[0] << " " << apoint1[1] -width << " " << apoint1[2] -width << "\n";
334 tmpStream << "v " << apoint1[0] << " " << apoint1[1] -width << " " << apoint1[2] +width << "\n";
335 tmpStream << "v " << apoint1[0] << " " << apoint1[1] +width << " " << apoint1[2] -width << "\n";
336 tmpStream << "v " << apoint1[0] << " " << apoint1[1] +width << " " << apoint1[2] +width<< "\n";
338 tmpStream << "v " << apoint2[0] << " " << apoint2[1] -width << " " << apoint2[2] -width << "\n";
339 tmpStream << "v " << apoint2[0] << " " << apoint2[1] -width << " " << apoint2[2] +width << "\n";
340 tmpStream << "v " << apoint2[0] << " " << apoint2[1] +width << " " << apoint2[2] -width << "\n";
341 tmpStream << "v " << apoint2[0] << " " << apoint2[1] +width << " " << apoint2[2] +width<< "\n";
343 tmpStream << "vn " << "0" << " " << "0" << " " << "1" << "\n";//up
344 tmpStream << "vn " << "0" << " " << "0" << " " << "-1" << "\n";//back
346 tmpStream << "f " << "-7//" << " " << "-8//" << " " << "-4//"<< " " << "-3//" << "\n";//left
347 tmpStream << "f " << "-5//" << " " << "-7//" << " " << "-3//"<< " " << "-1//"<< "\n";//front
348 tmpStream << "f " << "-3//-2" << " " << "-4//-2" << " " << "-2//-2"<< " " << "-1//-2"<< "\n";//up
349 tmpStream << "f " << "-8//-1" << " " << "-7//-1" << " " << "-5//-1"<< " " << "-6//-1"<< "\n";//back
350 tmpStream << "f " << "-2//" << " " << "-4//" << " " << "-8//"<< " " << "-6//"<< "\n";//down
351 tmpStream << "f " << "-1//" << " " << "-2//" << " " << "-6//"<< " " << "-5//"<< "\n";//right
356 if (tmpStream.str() != "")
358 std::stringstream name;
359 name << Board3D<Space, KSpace>::myLineSetNameList.at(k);
360 if ( name.str()== "")
362 name << "myLineSetList_" << k ;
365 typename std::vector< typename Board3D<Space, KSpace>::LineD3D>::const_iterator itBegin = it->begin();
366 unsigned int matid = getMaterialIndex(itBegin->color);
367 std::stringstream matName;
368 matName << "Mat_" << matid;
369 outOBJ << "o " << name.str() << "\n";
370 outOBJ << "usemtl " << matName.str() << "\n";
371 outOBJ << tmpStream.str();
378 // myCubeSetList++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
380 j = 0 ; //id of each Cube sub list for the .OBJ identification
384 for(typename Board3D<Space, KSpace>::CubesMap::const_iterator it =Board3D<Space, KSpace>::myCubesMap.begin();
385 it != Board3D<Space, KSpace>::myCubesMap.end(); it++)
388 std::stringstream name;
389 std::ostringstream tmpStream;
391 name << "myCubeSetList_" << it->first ;
392 outOBJ << "o " << name.str() << "\n";
395 //For each list, we force the cube color to be set in the OBJ file
396 unsigned int prevMaterialIndex = std::numeric_limits<unsigned int>::max(); //index to the last voxel material
398 //Foreach cube in the list
399 for (typename std::vector< typename Board3D<Space, KSpace>::CubeD3D>::const_iterator s_it = it->second.begin();
400 s_it != it->second.end(); ++s_it)
403 unsigned int matid = getMaterialIndex(s_it->color);
404 if (matid != prevMaterialIndex)
406 std::stringstream matName;
407 matName << "Mat_" << matid;
408 outOBJ << "usemtl " << matName.str() << "\n";
409 prevMaterialIndex = matid;
412 double wid = s_it->width;
413 double x = s_it->center[0];
414 double y = s_it->center[1];
415 double z = s_it->center[2];
423 //test if a clipping plane do not cut it
425 typename std::vector< typename Board3D<Space, KSpace>::ClippingPlaneD3D>::const_iterator itClip = Board3D<Space, KSpace>::myClippingPlaneList.begin();
426 while (itClip !=Board3D<Space, KSpace>::myClippingPlaneList.end() && notCut )
428 double a = itClip->a;
429 double b = itClip->b;
430 double c = itClip->c;
431 double d = itClip->d;
432 double d2 = ( a * x1) + (b * y1) + ( c * z2 ) + d;
435 d2 = ( a * x2) + (b * y1) + ( c * z2) + d;
436 notCut = ( notCut && ( d2 >= 0) );
437 d2 = ( a * x1) + (b * y1) + ( c * z1) + d;
438 notCut = ( notCut && ( d2 >= 0) );
439 d2 = ( a * x2) + (b * y1) + ( c * z1) + d;
440 notCut = ( notCut && ( d2 >= 0) );
441 d2 = ( a * x1) + (b * y2) + ( c * z2) + d;
442 notCut = ( notCut && ( d2 >= 0) );
443 d2 = ( a * x2) + (b * y2) + ( c * z2) + d;
444 notCut = ( notCut && ( d2 >= 0) );
445 d2 = ( a * x1) + (b * y2) + ( c * z1) + d;
446 notCut = ( notCut && ( d2 >= 0) );
447 d2 = ( a * x2) + (b * y2) + ( c * z1) + d;
448 notCut = ( notCut && ( d2 >= 0) );
457 // this version is one cube with (x,y,z) the center of it and wid its distance between it and its faces
459 x1 = (x1-shift[0])*scale;
460 y1 = (y1-shift[1])*scale;
461 z1 = (z1-shift[2])*scale;
462 x2 = (x2-shift[0])*scale;
463 y2 = (y2-shift[1])*scale;
464 z2 = (z2-shift[2])*scale;
466 outOBJ << "v " << x1 << " " << y1 << " " << z1 << "\n";
467 outOBJ << "v " << x1 << " " << y2 << " " << z1 << "\n";
468 outOBJ << "v " << x2 << " " << y2 << " " << z1 << "\n";
469 outOBJ << "v " << x2 << " " << y1 << " " << z1 << "\n";
470 outOBJ << "v " << x1 << " " << y1 << " " << z2 << "\n";
471 outOBJ << "v " << x1 << " " << y2 << " " << z2 << "\n";
472 outOBJ << "v " << x2 << " " << y2 << " " << z2 << "\n";
473 outOBJ << "v " << x2 << " " << y1 << " " << z2 << "\n";
475 outOBJ << "f " << "-8" << " " << "-7" << " " <<"-6" << " " <<"-5" << "\n";//bottom
476 outOBJ << "f " << "-8" << " " << "-4" << " " <<"-3" << " " <<"-7" << "\n";//back
477 outOBJ << "f " << "-2" << " " << "-1" << " " <<"-5" << " " <<"-6" << "\n";//front
478 outOBJ << "f " << "-7" << " " << "-3" << " " <<"-2" << " " <<"-6" << "\n";//right
479 outOBJ << "f " << "-8" << " " << "-5" << " " <<"-1" << " " <<"-4" << "\n";//left
480 outOBJ << "f " << "-4" << " " << "-1" << " " <<"-2" << " " <<"-3" << "\n";//top
496 // myQuadList++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
498 k = 0; // id of each list
500 std::stringstream matName;
501 //we init the previousCol var.
502 if (Board3D<Space, KSpace>::myQuadsMap.begin() != Board3D<Space, KSpace>::myQuadsMap.end())
503 previousCol = Board3D<Space, KSpace>::myQuadsMap.begin()->second.begin()->color;
508 for (typename Board3D<Space, KSpace>::QuadsMap::const_iterator it = Board3D<Space, KSpace>::myQuadsMap.begin();
509 it != Board3D<Space, KSpace>::myQuadsMap.end(); it++)
512 outOBJ << "o myQuadSetList_" << it->first <<"\n";
513 //For each list, we force the material
514 unsigned int matid = getMaterialIndex(previousCol);
515 outOBJ << "usemtl Mat_" << matid << "\n";
518 //We scan the quads of the list
519 for (typename std::vector<typename Board3D<Space, KSpace>::QuadD3D>::const_iterator aQuad = it->second.begin();
520 aQuad!=it->second.end();aQuad ++)
522 if (previousCol != aQuad->color)
524 previousCol = aQuad->color;
526 matid = getMaterialIndex(previousCol);
527 outOBJ << "usemtl Mat_" << matid << "\n";
530 apoint1 = (aQuad->point1 -shift)*scale;
531 apoint2 = (aQuad->point2 -shift)*scale;
532 apoint3 = (aQuad->point3 -shift)*scale;
533 apoint4 = (aQuad->point4 -shift)*scale;
535 outOBJ << "v " << apoint1[0] << " " << apoint1[1] << " " << apoint1[2] << "\n";
536 outOBJ << "v " << apoint2[0] << " " << apoint2[1] << " " << apoint2[2] << "\n";
537 outOBJ << "v " << apoint3[0] << " " << apoint3[1] << " " << apoint3[2] << "\n";
538 outOBJ << "v " << apoint4[0] << " " << apoint4[1] << " " << apoint4[2] << "\n";
539 outOBJ << "vn " << aQuad->nx << " " << aQuad->ny << " " << aQuad->nz << "\n";
540 outOBJ << "f " << "-4//-1" << " " << "-3//-1" << " " << "-2//-1"<< " " << "-1//-1"<< "\n";
548 // myTriangleList++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
550 //std::vector<triangleD3D>::const_iterator
551 k = 0; // id of each list
552 for(typename std::vector<std::vector< typename Board3D<Space, KSpace>::TriangleD3D> >::const_iterator it =Board3D<Space, KSpace>::myTriangleSetList.begin();
553 it != Board3D<Space, KSpace>::myTriangleSetList.end(); it++)
555 std::ostringstream tmpStream;
556 for (typename std::vector< typename Board3D<Space, KSpace>::TriangleD3D>::const_iterator s_it = it->begin();
557 s_it != it->end(); ++s_it)
559 //test if a clipping plane do not cut it
561 typename std::vector< typename Board3D<Space, KSpace>::ClippingPlaneD3D>::const_iterator itClip =
562 Board3D<Space, KSpace>::myClippingPlaneList.begin();
563 while (itClip !=Board3D<Space, KSpace>::myClippingPlaneList.end() && notCut )
565 double a = itClip->a;
566 double b = itClip->b;
567 double c = itClip->c;
568 double d = itClip->d;
569 double d2 = ( a * s_it->point1[0]) + (b * s_it->point1[1]) + ( c * s_it->point1[2] ) + d;
571 d2 = ( a * s_it->point2[0]) + (b * s_it->point2[1]) + ( c * s_it->point2[2]) + d;
572 notCut = ( notCut && ( d2 >= 0) );
573 d2 = ( a * s_it->point3[0]) + (b * s_it->point3[1]) + ( c * s_it->point3[2]) + d;
574 notCut = ( notCut && ( d2 >= 0) );
580 apoint1 = (s_it->point1 - shift)*scale;
581 apoint2 = (s_it->point2 - shift)*scale;
582 apoint3 = (s_it->point3 - shift)*scale;
585 tmpStream << "v " << apoint1[0] << " " << apoint1[1] << " " << apoint1[2] << "\n";
586 tmpStream << "v " << apoint2[0] << " " << apoint2[1] << " " << apoint2[2] << "\n";
587 tmpStream << "v " << apoint3[0] << " " << apoint3[1] << " " << apoint3[2] << "\n";
589 tmpStream << "vn " << s_it->nx << " " << s_it->ny << " " << s_it->nz << "\n";
591 tmpStream << "f " << "-3//-1" << " " << "-2//-1"<< " " << "-1//-1"<< "\n";
595 if (tmpStream.str() != "")
597 std::stringstream name;
598 name << Board3D<Space, KSpace>::myTriangleSetNameList.at(k);
599 if ( name.str() == "")
601 name << "myTriangleSetList_" << k ;
603 typename std::vector< typename Board3D<Space, KSpace>::TriangleD3D>::const_iterator itBegin = it->begin();
604 unsigned int matid = getMaterialIndex(itBegin->color);
605 std::stringstream matName;
606 matName << "Mat_" << matid;
607 outOBJ << "o " << name.str() << "\n";
608 outOBJ << "usemtl " << matName.str() << "\n";
609 outOBJ << tmpStream.str();
617 // Drawing all Khalimsky Space Cells --------------------------------------------------------------------
619 // Prism (from updateList)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
623 std::ostringstream tmpStream;
625 for (typename std::vector< typename Board3D<Space, KSpace>::QuadD3D>::iterator s_it = Board3D<Space, KSpace>::myPrismList.begin();
626 s_it != Board3D<Space, KSpace>::myPrismList.end();
629 //test if a clipping plane do not cut it
631 typename std::vector< typename Board3D<Space, KSpace>::ClippingPlaneD3D>::const_iterator itClip = Board3D<Space, KSpace>::myClippingPlaneList.begin();
632 while (itClip !=Board3D<Space, KSpace>::myClippingPlaneList.end() && notCut )
634 double a = itClip->a;
635 double b = itClip->b;
636 double c = itClip->c;
637 double d = itClip->d;
638 double d2 = ( a * s_it->point1[0]) + (b * s_it->point1[1]) + ( c * s_it->point1[2] ) + d;
640 d2 = ( a * s_it->point2[0]) + (b * s_it->point2[1]) + ( c * s_it->point2[2]) + d;
641 notCut = ( notCut && ( d2 >= 0) );
642 d2 = ( a * s_it->point3[0]) + (b * s_it->point3[1]) + ( c * s_it->point3[2]) + d;
643 notCut = ( notCut && ( d2 >= 0) );
644 d2 = ( a * s_it->point4[0]) + (b * s_it->point4[1]) + ( c * s_it->point4[2]) + d;
645 notCut = ( notCut && ( d2 >= 0) );
651 apoint1 = (s_it->point1 -shift)*scale;
652 apoint2 = (s_it->point2 -shift)*scale;
653 apoint3 = (s_it->point3 -shift)*scale;
654 apoint4 = (s_it->point4 -shift)*scale;
656 tmpStream << "v " << apoint1[0] << " " << apoint1[1] << " " << apoint1[2] << "\n";
657 tmpStream << "v " << apoint2[0] << " " << apoint2[1] << " " << apoint2[2] << "\n";
658 tmpStream << "v " << apoint3[0] << " " << apoint3[1] << " " << apoint3[2] << "\n";
659 tmpStream << "v " << apoint4[0] << " " << apoint4[1] << " " << apoint4[2] << "\n";
661 tmpStream << "vn " << s_it->nx << " " << s_it->ny << " " << s_it->nz << "\n";
663 tmpStream << "f " << "-4//-1" << " " << "-3//-1" << " " << "-2//-1"<< " " << "-1//-1" << "\n";
668 if (tmpStream.str() != "")
670 std::stringstream name;
671 name << "myPrismList" << j;
672 std::stringstream matName;
673 matName << "myPrismList" << j << "MAT";
674 typename std::vector< typename Board3D<Space, KSpace>::QuadD3D>::const_iterator itBegin = Board3D<Space, KSpace>::myPrismList.begin();
675 unsigned int matid = getMaterialIndex(itBegin->color);
676 matName << "Mat_" << matid;
677 outOBJ << "o " << name.str() << "\n";
678 outOBJ << "usemtl " << matName.str() << "\n";
679 outOBJ << tmpStream.str();
686 //end Prism (from updateList)+++++++++++++++++++++++++++++++
687 outMTL << myMTLBuffer.str();
696 template < typename Space, typename KSpace>
699 DGtal::Board3D<Space, KSpace>::init()
704 Board3D<Space, KSpace>::createNewCubeList();
705 Board3D<Space, KSpace>::createNewLineList();
706 Board3D<Space, KSpace>::createNewBallList();
708 Board3D<Space, KSpace>::myCurrentFillColor = DGtal::Color (220, 220, 220);
709 Board3D<Space, KSpace>::myCurrentLineColor = DGtal::Color (22, 22, 222, 50);
710 Board3D<Space, KSpace>::myDefaultColor= DGtal::Color(255, 255, 255);
711 Board3D<Space, KSpace>::myModes["Board3D"]="SolidMode";
713 std::string nameLineSet;
714 Board3D<Space, KSpace>::myLineSetNameList.push_back(nameLineSet);
716 std::string nameBallSet;
717 Board3D<Space, KSpace>::myBallSetNameList.push_back(nameBallSet);
720 std::string nameQuad;
721 Board3D<Space, KSpace>::myQuadSetNameList.push_back(nameQuad);
723 std::string nameTriangle;
724 Board3D<Space, KSpace>::myTriangleSetNameList.push_back(nameTriangle);
726 std::string namePolygon;
727 Board3D<Space, KSpace>::myPolygonSetNameList.push_back(namePolygon);
729 ///////////////////////////////////////////////////////////////////////////////
730 template < typename Space, typename KSpace>
733 DGtal::Board3D<Space, KSpace>::getMaterialIndex(const DGtal::Color &aColor)
735 std::map<DGtal::Color, unsigned int>::iterator it;
737 it = myMaterialMap.find(aColor);
739 //The material exists
740 if (it != myMaterialMap.end())
743 myMaterialMap.insert( std::pair<DGtal::Color,unsigned int>(aColor,myMaterialIndex) );
744 std::stringstream matName ;
745 matName << "Mat_" <<myMaterialIndex;
746 myMTLBuffer << "newmtl " << matName.str() <<"\n";
747 myMTLBuffer << "Ka " << aColor.red()/255.0 << " " << aColor.green()/255.0 << " " << aColor.blue()/255.0 << "\n";
748 myMTLBuffer << "Kd " << aColor.red()/255.0 << " " << aColor.green()/255.0 << " " << aColor.blue()/255.0 << "\n";
749 myMTLBuffer << "Ks 0 0 0" << "\n";
750 myMTLBuffer << "d " << aColor.alpha()/255.0 << "\n";
751 myMTLBuffer << "illum 2" << std::endl << "\n";
754 return (myMaterialIndex - 1);
759 ///////////////////////////////////////////////////////////////////////////////