DGtal 1.4.2
Loading...
Searching...
No Matches
Mesh.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17/**
18 * @file Mesh.ih
19 * @author Bertrand Kerautret (\c kerautre@loria.fr )
20 * LORIA (CNRS, UMR 7503), University of Nancy, France
21 *
22 * @date 2012/06/29
23 *
24 * Implementation of inline methods defined in Mesh.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <limits>
32#include <cstdlib>
33#include <map>
34#include <DGtal/kernel/BasicPointPredicates.h>
35//////////////////////////////////////////////////////////////////////////////
36
37///////////////////////////////////////////////////////////////////////////////
38// IMPLEMENTATION of inline methods.
39///////////////////////////////////////////////////////////////////////////////
40
41///////////////////////////////////////////////////////////////////////////////
42// ----------------------- Standard services ------------------------------
43
44
45/**
46 * Constructor.
47 */
48template <typename TPoint>
49inline
50DGtal::Mesh<TPoint>::Mesh(bool saveFaceColor)
51{
52 mySaveFaceColor=saveFaceColor;
53 myDefaultColor = DGtal::Color::White;
54}
55
56/**
57 * Constructor.
58 */
59template <typename TPoint>
60inline
61DGtal::Mesh<TPoint>::Mesh(const DGtal::Color &aColor)
62{
63 mySaveFaceColor=false;
64 myDefaultColor = aColor;
65}
66
67/**
68 * Destructor.
69 */
70template <typename TPoint>
71inline
72DGtal::Mesh<TPoint>::~Mesh()
73{
74}
75
76
77template <typename TPoint>
78inline
79DGtal::Mesh<TPoint>::Mesh ( const Mesh & other ): myFaceList(other.myFaceList),
80 myVertexList(other.myVertexList),
81 myFaceColorList(other.myFaceColorList),
82 mySaveFaceColor(other.mySaveFaceColor),
83 myDefaultColor(other.myDefaultColor)
84{
85
86}
87
88template <typename TPoint>
89inline
90DGtal::Mesh<TPoint> &
91DGtal::Mesh<TPoint>::operator= ( const Mesh & other )
92{
93 myFaceList = other.myFaceList;
94 myVertexList = other.myVertexList;
95 myFaceColorList = other.myFaceColorList;
96 mySaveFaceColor = other.mySaveFaceColor;
97 myDefaultColor = other. myDefaultColor;
98 return *this;
99}
100
101
102///////////////////////////////////////////////////////////////////////////////
103// Interface - public :
104
105/**
106 * Writes/Displays the object on an output stream.
107 * @param out the output stream where the object is written.
108 */
109template <typename TPoint>
110inline
111void
112DGtal::Mesh<TPoint>::selfDisplay ( std::ostream & out ) const
113{
114 out << "[Mesh]";
115}
116
117/**
118 * Checks the validity/consistency of the object.
119 * @return 'true' if the object is valid, 'false' otherwise.
120 */
121template <typename TPoint>
122inline
123bool
124DGtal::Mesh<TPoint>::isValid() const
125{
126 return true;
127}
128
129
130
131
132///////////////////////////////////////////////////////////////////////////////
133// Implementation of inline functions //
134
135
136
137
138
139
140
141template<typename TPoint>
142inline
143DGtal::Mesh<TPoint>::Mesh(const VertexStorage &vertexSet)
144{
145 mySaveFaceColor=false;
146 for(int i =0; i< vertexSet.size(); i++)
147 {
148 myVertexList.push_back(vertexSet.at(i));
149 }
150
151}
152
153
154
155template<typename TPoint>
156inline
157void
158DGtal::Mesh<TPoint>::addVertex(const TPoint &point)
159{
160 myVertexList.push_back(point);
161}
162
163
164
165template<typename TPoint>
166inline
167void
168DGtal::Mesh<TPoint>::addTriangularFace(Index indexVertex1, Index indexVertex2,
169 Index indexVertex3, const DGtal::Color &aColor)
170{
171 MeshFace aFace;
172 aFace.push_back(indexVertex1);
173 aFace.push_back(indexVertex2);
174 aFace.push_back(indexVertex3);
175 myFaceList.push_back(aFace);
176 if(mySaveFaceColor)
177 {
178 myFaceColorList.push_back(aColor);
179 }
180}
181
182
183
184
185template<typename TPoint>
186inline
187void
188DGtal::Mesh<TPoint>::addQuadFace(Index indexVertex1,Index indexVertex2,
189 Index indexVertex3, Index indexVertex4,
190 const DGtal::Color &aColor)
191{
192 MeshFace aFace;
193 aFace.push_back(indexVertex1);
194 aFace.push_back(indexVertex2);
195 aFace.push_back(indexVertex3);
196 aFace.push_back(indexVertex4);
197 myFaceList.push_back(aFace);
198 if(mySaveFaceColor)
199 {
200 myFaceColorList.push_back(aColor);
201 }
202}
203
204
205
206template<typename TPoint>
207inline
208void
209DGtal::Mesh<TPoint>::addFace(const MeshFace &aFace, const DGtal::Color &aColor){
210 myFaceList.push_back(aFace);
211 if(mySaveFaceColor)
212 {
213 myFaceColorList.push_back(aColor);
214 }
215}
216
217
218
219template<typename TPoint>
220inline
221void
222DGtal::Mesh<TPoint>::removeFaces(const std::vector<Index> &facesIndex){
223 DGtal::Mesh<TPoint> newMesh(true);
224
225 std::vector<unsigned int> indexVertexFaceCard(nbVertex());
226 std::vector<bool> indexFaceOK(nbFaces());
227 std::fill(indexVertexFaceCard.begin(), indexVertexFaceCard.end(), 0);
228 std::fill(indexFaceOK.begin(), indexFaceOK.end(), true);
229 for (unsigned int i = 0; i<facesIndex.size(); i++){
230 indexFaceOK[facesIndex[i]]=false;
231 }
232 // for each face remaining in the mesh we add +1 to each vertex used in a face
233 for(unsigned int i = 0; i < nbFaces(); i++){
234 if( indexFaceOK[i] ){
235 DGtal::Mesh<TPoint>::MeshFace aFace = getFace(i);
236 for (unsigned int j=0; j< aFace.size() ; j++) {
237 indexVertexFaceCard[aFace[j]] += 1;
238 }
239 }
240 }
241 // we remove all vertex with a face == 0 and compute the new vertex association:
242 std::vector<unsigned int> newVertexIndex;
243 unsigned int currentIndex=0;
244 for (unsigned int i=0; i< nbVertex(); i++) {
245 if (indexVertexFaceCard[i]!=0){
246 newMesh.addVertex(getVertex(i));
247 newVertexIndex.push_back(currentIndex);
248 currentIndex++;
249 }else{
250 newVertexIndex.push_back(0);
251 }
252 }
253 for (unsigned int i = 0; i < nbFaces(); i++) {
254 if(indexFaceOK[i]){
255 MeshFace aFace = getFace(i);
256 MeshFace aNewFace = aFace;
257 // translate the old face with new index:
258 for (unsigned int j=0; j< aFace.size() ; j++) {
259 aNewFace[j] = newVertexIndex[aFace[j]];
260 }
261 newMesh.addFace(aNewFace);
262 newMesh.setFaceColor(newMesh.nbFaces()-1, getFaceColor(i));
263 }
264 }
265 myFaceList = newMesh.myFaceList;
266 myVertexList = newMesh.myVertexList;
267 myFaceColorList = newMesh.myFaceColorList;
268}
269
270
271
272
273
274template<typename TPoint>
275inline
276const TPoint &
277DGtal::Mesh<TPoint>::getVertex(Index i) const
278{
279 return myVertexList.at(i);
280}
281
282
283
284template<typename TPoint>
285inline
286TPoint &
287DGtal::Mesh<TPoint>::getVertex(Index i)
288{
289 return myVertexList.at(i);
290}
291
292
293
294template<typename TPoint>
295inline
296const typename DGtal::Mesh<TPoint>::MeshFace &
297DGtal::Mesh<TPoint>::getFace(Index i) const
298{
299 return myFaceList.at(i);
300}
301
302
303template<typename TPoint>
304inline
305typename DGtal::Mesh<TPoint>::MeshFace &
306DGtal::Mesh<TPoint>::getFace(Index i)
307{
308 return myFaceList.at(i);
309}
310
311
312template<typename TPoint>
313inline
314typename DGtal::Mesh<TPoint>::RealPoint
315DGtal::Mesh<TPoint>::getFaceBarycenter(Index i) const
316{
317 DGtal::Mesh<TPoint>::RealPoint c;
318 MeshFace aFace = getFace(i);
319 for ( auto &j: aFace){
320 TPoint p = getVertex(j);
321 for (typename TPoint::Dimension k = 0; k < TPoint::dimension; k++){
322 c[k] += static_cast<typename RealPoint::Component>(p[k]) ;
323 }
324 }
325 return c/static_cast<typename RealPoint::Component>(aFace.size());
326}
327
328
329template<typename TPoint>
330inline
331typename DGtal::Mesh<TPoint>::Size
332DGtal::Mesh<TPoint>::nbFaces() const
333{
334 return myFaceList.size();
335}
336
337template<typename TPoint>
338inline
339typename DGtal::Mesh<TPoint>::Size
340DGtal::Mesh<TPoint>::nbVertex() const
341{
342 return myVertexList.size();
343}
344
345
346template<typename TPoint>
347inline
348const DGtal::Color &
349DGtal::Mesh<TPoint>::getFaceColor(Index i) const
350{
351 if(mySaveFaceColor)
352 {
353 return myFaceColorList.at(i);
354 }
355 else
356 {
357 return myDefaultColor;
358 }
359}
360
361template <typename TPoint>
362struct MeshBoundingBoxCompPoints
363{
364 MeshBoundingBoxCompPoints(typename TPoint::Dimension d): myDim(d){};
365 bool operator() (const TPoint &p1, const TPoint &p2){return p1[myDim]<p2[myDim];};
366 typename TPoint::Dimension myDim;
367};
368
369template<typename TPoint>
370inline
371std::pair<TPoint, TPoint>
372DGtal::Mesh<TPoint>::getBoundingBox() const
373{
374 std::pair<TPoint, TPoint> theResult;
375 TPoint lowerBound, upperBound;
376 for(unsigned int i=0; i< TPoint::size(); i++)
377 {
378 const MeshBoundingBoxCompPoints<TPoint> cmp_points(i);
379 upperBound[i] = (*(std::max_element(vertexBegin(), vertexEnd(), cmp_points)))[i];
380 lowerBound[i] = (*(std::min_element(vertexBegin(), vertexEnd(), cmp_points)))[i];
381 }
382 theResult.first = lowerBound ;
383 theResult.second = upperBound ;
384 return theResult;
385}
386
387
388template<typename TPoint>
389inline
390void
391DGtal::Mesh<TPoint>::setFaceColor(const Index index,
392 const DGtal::Color &aColor)
393{
394 if (!mySaveFaceColor)
395 {
396 for(unsigned int i = 0; i<myFaceList.size(); i++)
397 {
398 myFaceColorList.push_back(myDefaultColor);
399 }
400 mySaveFaceColor=true;
401 }
402 myFaceColorList.at(index) = aColor;
403}
404
405
406template<typename TPoint>
407inline
408bool
409DGtal::Mesh<TPoint>::isStoringFaceColors() const
410{
411 return mySaveFaceColor;
412}
413
414
415
416
417template<typename TPoint>
418inline
419void
420DGtal::Mesh<TPoint>::invertVertexFaceOrder(){
421 for(unsigned int i=0; i<myFaceList.size(); i++)
422 {
423 auto aFace = myFaceList.at(i);
424 for(unsigned int j=0; j < aFace.size()/2; j++)
425 {
426 const auto tmp=aFace.at(j);
427 aFace.at(j)=aFace.at(aFace.size()-1-j);
428 aFace.at(aFace.size()-1-j)=tmp;
429 }
430 }
431}
432
433template<typename TPoint>
434inline
435void
436DGtal::Mesh<TPoint>::clearFaces(){
437 myFaceList.clear();
438}
439
440
441template<typename TPoint>
442inline
443void
444DGtal::Mesh<TPoint>::clearVertices(){
445 myVertexList.clear();
446}
447
448template <typename TPoint>
449void
450DGtal::Mesh<TPoint>::removeIsolatedVertices(){
451 typedef typename Mesh<TPoint>::Index MIndex;
452 DGtal::Mesh<TPoint>::VertexStorage vSt;
453 std::vector<bool> vertexUsed (nbVertex(), false);
454 for ( MIndex f = 0; f< nbFaces(); f++ )
455 {
456 auto face = getFace(f);
457 for (MIndex i = 0; i<face.size(); i++)
458 {
459 vertexUsed[face[i]] = true;
460 }
461 }
462 std::vector<MIndex> translateIndexId;
463 MIndex currentIndex = 0;
464 MIndex nbV = nbVertex();
465 for(MIndex i = 0; i < nbV; i++ )
466 {
467 if (vertexUsed[i])
468 {
469 translateIndexId.push_back(currentIndex);
470 vSt.push_back(myVertexList[i]);
471 currentIndex++;
472 }
473 else
474 {
475 translateIndexId.push_back(0);
476 }
477 }
478 myVertexList = vSt;
479 for ( MIndex f = 0; f< nbFaces(); f++ )
480 {
481 auto &face = getFace(f);
482 for (MIndex i = 0; i<face.size(); i++)
483 {
484 face[i]=translateIndexId[face[i]];
485 }
486 }
487}
488
489template<typename TPoint>
490inline
491void
492DGtal::Mesh<TPoint>::rescale(const typename TPoint::Component aScale){
493 for(typename VertexStorage::iterator it = vertexBegin(); it != vertexEnd(); it++)
494 {
495 (*it) *= aScale;
496 }
497}
498
499
500template<typename TPoint>
501inline
502double
503DGtal::Mesh<TPoint>::subDivideTriangularFaces(const double minArea){
504 double maxArea = 0;
505 std::vector<Mesh<TPoint>::MeshFace> facesToAdd;
506 for(unsigned int i =0; i< nbFaces(); i++)
507 {
508 typename Mesh<TPoint>::MeshFace aFace = getFace(i);
509 if(aFace.size()==3)
510 {
511 TPoint p1 = getVertex(aFace[0]);
512 TPoint p2 = getVertex(aFace[1]);
513 TPoint p3 = getVertex(aFace[2]);
514 TPoint c = (p1+p2+p3)/3.0;
515 double a = ((p2-p1).crossProduct(p3-p1)).norm()/2.0;
516 if (a>maxArea)
517 {
518 maxArea = a;
519 }
520
521 if(a>=minArea)
522 {
523 addVertex(c);
524 MeshFace f1, f2, f3;
525 f1.push_back(aFace[0]);
526 f1.push_back(aFace[1]);
527 f1.push_back(nbVertex()-1);
528 facesToAdd.push_back(f1);
529
530 f2.push_back(aFace[1]);
531 f2.push_back(aFace[2]);
532 f2.push_back(nbVertex()-1);
533 facesToAdd.push_back(f2);
534
535 f3.push_back(aFace[2]);
536 f3.push_back(aFace[0]);
537 f3.push_back(nbVertex()-1);
538 facesToAdd.push_back(f3);
539 }
540 else
541 {
542 facesToAdd.push_back(aFace);
543 }
544
545 }
546 }
547 clearFaces();
548 for(unsigned i=0; i<facesToAdd.size(); i++)
549 {
550 addFace(facesToAdd[i]);
551 }
552 return maxArea;
553}
554
555
556
557template<typename TPoint>
558inline
559unsigned int
560DGtal::Mesh<TPoint>::quadToTriangularFaces(){
561 unsigned int nbQuadT=0;
562 std::vector<Mesh<TPoint>::MeshFace> facesToAdd;
563 for(unsigned int i =0; i< nbFaces(); i++)
564 {
565 typename Mesh<TPoint>::MeshFace aFace = getFace(i);
566 if(aFace.size()==4)
567 {
568 MeshFace f1, f2;
569 f1.push_back(aFace[0]);
570 f1.push_back(aFace[1]);
571 f1.push_back(aFace[2]);
572 facesToAdd.push_back(f1);
573
574 f2.push_back(aFace[2]);
575 f2.push_back(aFace[3]);
576 f2.push_back(aFace[0]);
577 facesToAdd.push_back(f2);
578 nbQuadT++;
579 }
580 else
581 {
582 facesToAdd.push_back(aFace);
583 }
584 }
585 clearFaces();
586 for(unsigned i=0; i<facesToAdd.size(); i++)
587 {
588 addFace(facesToAdd[i]);
589 }
590 return nbQuadT;
591}
592
593
594
595
596//------------------------------------------------------------------------------
597template<typename TPoint>
598inline
599std::string
600DGtal::Mesh<TPoint>::className() const
601{
602 return "Mesh";
603}
604
605
606
607
608
609
610template <typename TPoint>
611inline
612void
613DGtal::Mesh<TPoint>::createTubularMesh(DGtal::Mesh<TPoint> &aMesh, const std::vector<TPoint> &aSkeleton,
614 const double aRadius,
615 const double angleStep, const DGtal::Color &aMeshColor)
616{
617 std::vector<double> aVecR;
618 aVecR.push_back(aRadius);
619 DGtal::Mesh<TPoint>::createTubularMesh(aMesh, aSkeleton,
620 aVecR, angleStep, aMeshColor);
621
622}
623
624
625template <typename TPoint>
626inline
627void
628DGtal::Mesh<TPoint>::createTubularMesh(DGtal::Mesh<TPoint> &aMesh, const std::vector<TPoint> &aSkeleton,
629 const std::vector<double> &aVectRadius,
630 const double angleStep, const DGtal::Color &aMeshColor)
631{
632 auto nbVertexInitial = aMesh.nbVertex();
633 ASSERT(aVectRadius.size() > 0);
634 // Generating vertices..
635 for(auto i = 0; i< (int)aSkeleton.size(); i++)
636 {
637 TPoint vectDir;
638 TPoint uDir1, uDirPrec;
639 TPoint uDir2;
640 TPoint firstPoint;
641
642 if(i != (int)aSkeleton.size()-1)
643 {
644 vectDir = aSkeleton.at(i+1) - aSkeleton.at(i);
645 }
646 else
647 {
648 vectDir = aSkeleton.at(i) - aSkeleton.at(i-1);
649 }
650
651 double d = -vectDir[0]* aSkeleton.at(i)[0] - vectDir[1]*aSkeleton.at(i)[1]
652 - vectDir[2]*aSkeleton.at(i)[2];
653 TPoint pRefOrigin;
654 if(vectDir[0]!=0)
655 {
656 pRefOrigin [0]= -d/vectDir[0];
657 pRefOrigin [1]= 0.0;
658 pRefOrigin [2]= 0.0;
659 if(aSkeleton.at(i) == pRefOrigin ||
660 (vectDir[1]==0 && vectDir[2]==0))
661 {
662 pRefOrigin[1]=-1.0;
663 }
664
665 }
666 else if (vectDir[1]!=0)
667 {
668 pRefOrigin [0]= 0.0;
669 pRefOrigin [1]= -d/vectDir[1];
670 pRefOrigin [2]= 0.0;
671 if(aSkeleton.at(i) == pRefOrigin ||
672 (vectDir[0]==0 && vectDir[2]==0))
673 {
674 pRefOrigin[0]=-1.0;
675 }
676 }else if (vectDir[2]!=0)
677 {
678 pRefOrigin [0]= 0.0;
679 pRefOrigin [1]= 0.0;
680 pRefOrigin [2]= -d/vectDir[2];
681 if(aSkeleton.at(i) == pRefOrigin ||
682 (vectDir[0]==0 && vectDir[1]==0))
683 {
684 pRefOrigin[0]=-1.0;
685 }
686 }
687 uDir1=(pRefOrigin-aSkeleton.at(i))/((pRefOrigin-aSkeleton.at(i)).norm());
688 uDir2[0] = uDir1[1]*vectDir[2]-uDir1[2]*vectDir[1];
689 uDir2[1] = uDir1[2]*vectDir[0]-uDir1[0]*vectDir[2];
690 uDir2[2] = uDir1[0]*vectDir[1]-uDir1[1]*vectDir[0];
691 uDir2/=uDir2.norm();
692 for(double a = 0.0; a < 2.0*M_PI; a += angleStep)
693 {
694 TPoint vMove = aVectRadius.at(i%aVectRadius.size())*(uDir1*cos(a) + uDir2*sin(a));
695 aMesh.addVertex(vMove + aSkeleton[i]);
696 if(a==0)
697 {
698 firstPoint = vMove + aSkeleton[i]+vectDir;
699 }
700
701 }
702 }
703 unsigned int nbPtPerFaces = static_cast<unsigned int>((aMesh.nbVertex()-nbVertexInitial)/aSkeleton.size());
704
705 // Generating faces...
706 for(auto i = 0; i< (int)aSkeleton.size()-1; i++)
707 {
708 if (aSkeleton.at(i)==aSkeleton.at(i+1)){
709 trace.warning() << "Two skeleton points are identical, ignoring one point." << std::endl;
710 continue;
711 }
712 // Computing best shift between two consecutive ring points to generate tube face.
713 // (criteria defined by the minimal distance between 4 sampling points)
714 double minDistance = std::numeric_limits<double>::max();
715 TPoint ptRefRing1 = aMesh.getVertex(nbVertexInitial+i*nbPtPerFaces);
716 TPoint ptRefRing2 = aMesh.getVertex(nbVertexInitial+i*nbPtPerFaces+nbPtPerFaces/4);
717 TPoint ptRefRing3 = aMesh.getVertex(nbVertexInitial+i*nbPtPerFaces+2*(nbPtPerFaces/4));
718 TPoint ptRefRing4 = aMesh.getVertex(nbVertexInitial+i*nbPtPerFaces+3*(nbPtPerFaces/4));
719
720 unsigned int shift = 0;
721 TPoint vectDir;
722 if(i != (int)aSkeleton.size()-1)
723 {
724 vectDir = aSkeleton.at(i+1) - aSkeleton.at(i);
725 }
726 else
727 {
728 vectDir = aSkeleton.at(i) - aSkeleton.at(i-1);
729 }
730
731 for(unsigned int k=0; k<nbPtPerFaces; k++)
732 {
733 TPoint pScan1 = aMesh.getVertex(nbVertexInitial+(i+1)*nbPtPerFaces+k);
734 TPoint pScan2 = aMesh.getVertex(nbVertexInitial+(i+1)*nbPtPerFaces+
735 (nbPtPerFaces/4+k)%nbPtPerFaces);
736 TPoint pScan3 = aMesh.getVertex(nbVertexInitial+(i+1)*nbPtPerFaces+
737 (2*(nbPtPerFaces/4)+k)%nbPtPerFaces);
738 TPoint pScan4 = aMesh.getVertex(nbVertexInitial+(i+1)*nbPtPerFaces+
739 (3*(nbPtPerFaces/4)+k)%nbPtPerFaces);
740 double distance = (ptRefRing1 - pScan1).norm()+(ptRefRing2 - pScan2).norm()+
741 (ptRefRing3 - pScan3).norm()+(ptRefRing4 - pScan4).norm();
742 if(distance<minDistance){
743 shift = k;
744 minDistance = distance;
745 }
746
747 }
748 for(unsigned int k=0; k<nbPtPerFaces; k++)
749 {
750 Mesh<TPoint>::MeshFace aFace;
751 aMesh.addQuadFace(nbVertexInitial+k+i*nbPtPerFaces,
752 nbVertexInitial+(shift+k)%nbPtPerFaces+nbPtPerFaces*(i+1),
753 nbVertexInitial+(shift+k+1)%nbPtPerFaces+nbPtPerFaces*(i+1),
754 nbVertexInitial+(k+1)%nbPtPerFaces+i*nbPtPerFaces,
755 aMeshColor);
756 }
757 }
758}
759
760
761
762
763
764template <typename TPoint>
765template <typename TValue>
766inline
767void
768DGtal::Mesh<TPoint>::createMeshFromHeightSequence(Mesh<TPoint> &aMesh, const std::vector<TValue> & anValueSequence,
769 const unsigned int lengthSequence,
770 double stepX, double stepY, double stepZ,
771 const DGtal::Color &aMeshColor ){
772 const auto nbVertexInitial = aMesh.nbVertex();
773 // Generating vertices..
774 int i = 0;
775 unsigned int posY = 0;
776 while(i+(int)lengthSequence-1 < (int)anValueSequence.size()){
777 for(unsigned int j = 0; j < lengthSequence; j++, i++){
778 aMesh.addVertex(TPoint(j*stepX, posY*stepY, stepZ*anValueSequence.at(i)));
779 }
780 posY++;
781 }
782 // Generating faces...
783 i = 0;
784 posY = 0;
785 while(i+(int)lengthSequence-1 < (int)anValueSequence.size() - (int)lengthSequence){
786 for(auto j = 0; j < (int)lengthSequence-1; j++, i++){
787 aMesh.addQuadFace(nbVertexInitial+i, nbVertexInitial+i+1,
788 nbVertexInitial+i+1+lengthSequence,
789 nbVertexInitial+i+lengthSequence,
790 aMeshColor);
791 }
792 i++;
793 posY++;
794 }
795}
796
797
798
799
800template <typename TPoint>
801inline
802std::ostream&
803DGtal::operator<< ( std::ostream & out,
804 const Mesh<TPoint> & object )
805{
806 object.selfDisplay( out );
807 return out;
808}
809
810
811
812
813
814// //
815///////////////////////////////////////////////////////////////////////////////
816
817