DrawMesh.hh 29.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openflipper.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenFlipper.                                        *
 *                                                                           *
 *  OpenFlipper is free software: you can redistribute it and/or modify      *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenFlipper is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenFlipper. If not,                                  *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
\*===========================================================================*/



//=============================================================================
//
//  CLASS DrawMeshT
//
//=============================================================================


#ifndef ACG_DRAW_MESH_HH
#define ACG_DRAW_MESH_HH


//== INCLUDES =================================================================

#include <vector>
59
#include <list>
60
61
62
63
64
65
66
#include <OpenMesh/Core/Utils/Property.hh>
#include <OpenMesh/Core/IO/MeshIO.hh>

#include <ACG/Config/ACGDefines.hh>

#include <ACG/GL/GLState.hh>

67
68
#include <ACG/GL/IRenderer.hh>

69
70
71
72
73
74
75
76
77
78
79
80
//== FORWARDDECLARATIONS ======================================================


//== NAMESPACES ===============================================================

namespace ACG {

//== CLASS DEFINITION =========================================================


/** \brief Mesh Drawing Class
 *
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
 * Functional description:
 *
 * This class prepares the OpenMesh object for efficient rendering.
 * This is done in the function Rebuild() :
 *   1. Triangulation to guarantee a triangle mesh  (ConvertToTriangleMesh)
 *   2. Create a big 3*NumTris vertex buffer, so that each triangle has it's own 3 vertices
 *   3. Minimize this Vertex Buffer so that each vertex is unique
 *   4. Fix for Flat-Shading mode:
 *       OpenGL does not support Face-Normal generation on the fly, so we have to guarantee
 *       that the last vertex of each triangle is not shared with any other triangle.
 *       If flat shading is enabled, we need to update the vertex buffer and store the face normal
 *       for each triangle in this unshared vertex.
 *   5. Sort triangles by material:
 *       To minimize state OpenGL state changes and draw calls, triangles are sorted by material.
 *       This information is stored in Subsets
 *   6. GPU-Cache-Optimization:
 *       Optimize triangles for each subset for efficient gpu vertex cache usage.
 *       After that reorder vertices to avoid big gpu-memory jumps when reading in vertices
 *   while processing maintain the following maps:
 *     vertex index in the final vertex buffer -> halfedge index in OpenMesh  (vertexMap_)
 *     triangle index in the final index buffer -> face index in OpenMesh  (triToFaceMap_)
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 */
template <class Mesh>
class DrawMeshT
{
private:

#pragma pack(push, 1)
  /// full precision vertex, 40 bytes w/o tangent
  struct Vertex
  {
    Vertex();

    float pos[3]; /*!< Position */
    float tex[2]; /*!< per halfedge texture coordinates */
    float n[3];   /*!< normal vector */
//    float tan[4]; /*!< tangent vector + parity */

    unsigned int vcol; /*!<  per vertex color */
    unsigned int fcol; /*!<  per face color */

    int equals(const Vertex& r);
  };

  /// compressed vertex, 22 bytes
  struct VertexC
  {
    unsigned short pos[3];
    unsigned short u, v;
    unsigned int n;
//    unsigned int tan;

    unsigned int vcol;
    unsigned int fcol;
  };
#pragma pack(pop)

  struct Subset
  {
    int  materialID;
Jan Möbius's avatar
Jan Möbius committed
141
142
    unsigned long startIndex;
    unsigned long numTris;
143
144
  };

145
  enum REBUILD_TYPE {REBUILD_NONE = 0, REBUILD_FULL = 1, REBUILD_GEOMETRY = 2, REBUILD_TOPOLOGY = 4, REBUILD_TEXTURES = 8};
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161


public:

  DrawMeshT(Mesh& _mesh);
  virtual ~DrawMeshT();

  void disableColors()      {colorMode_ = 0;}
  void usePerVertexColors() {colorMode_ = 1;}
  void usePerFaceColors()   {colorMode_ = 2;}

  void setFlatShading()     {flatMode_ = 1;}
  void setSmoothShading()   {flatMode_ = 0;}

  void usePerVertexTexcoords()     {textureMode_ = 0;}
  void usePerHalfedgeTexcoords()   {textureMode_ = 1;}
162
163
  void usePerVertexNormals()   {halfedgeNormalMode_ = 0;}
  void usePerHalfedgeNormals()   {halfedgeNormalMode_ = 1;}
164
165
166
167

  /** \brief eventually rebuilds buffers used for rendering and binds index and vertex buffer
  */
  void bindBuffers();
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  /** \brief get opengl vertex buffer id
  */
  GLuint getVBO();

  /** \brief get opengl index buffer id
  */
  GLuint getIBO();


  /** \brief get vertex declaration used for per-vertex color rendering
  */
  VertexDeclaration* getVertexDeclaration();

  /** \brief map from vertex index of the original mesh point buffer to the corresponding vertex index inside the VBO.
  @param _v vertex index into mesh points
  @return vertex index into VBO
  */
  unsigned int mapVertexToVBOIndex(unsigned int _v);


189
190
  /** \brief eventually rebuilds buffers used for rendering and binds index and vertex buffer
  */
191
  void bindBuffersToRenderObject(RenderObject* _obj);
192

193
194
195
196
197
198
  /** \brief disables vertex, normal, texcoord and color pointers in OpenGL
  */
  void unbindBuffers();

  /** \brief binds index and vertex buffer and executes draw calls
  *
Jan Möbius's avatar
Jan Möbius committed
199
  *   @param _textureMap maps from internally texture-id to OpenGL texture id
200
201
202
  *   may be null to disable textured rendering
  */
  void draw(std::map< int, GLuint>* _textureMap);
Isaak Lim's avatar
Isaak Lim committed
203

204
  /** \brief adds RenderObjects to a deferred draw call renderer
205
  *
206
207
  *   @param _renderer renderobjects are added to this renderer
  *   @param _baseObj address of the base renderobject with information about shader generation, gl states, matrices ..
208
209
210
  *   @param _textureMap maps from internally texture-id to OpenGL texture id
  *   may be null to disable textured rendering
  */
211
  void addTriRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, std::map< int, GLuint>* _textureMap);
212
213
214
215
216

  /** \brief render the mesh in wireframe mode
  */
  void drawLines();

217
218
  /** \brief render the mesh in wireframe mode, deferred draw call
  */
219
  void addLineRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj);
220

221
222
223
224
225

  /** \brief render vertices only
  */
  void drawVertices();

226
227
  /** \brief render vertices only, deferred draw call
  */
228
  void addPointRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj);
229

230
231
232
233
234

  unsigned int getNumTris() const {return numTris_;}
  unsigned int getNumVerts() const {return numVerts_;}
  unsigned int getNumSubsets() const {return numSubsets_;}

235
236
237
238
239
240

  /** \brief measures the size in bytes of allocated memory.
  eventually prints a report to std::cout
  */
  unsigned int getMemoryUsage(bool _printReport = false);

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
  // The updateX functions give a hint on what to update.
  //  may perform a full rebuild internally!

  /** \brief request an update for the mesh topology
   */
  void updateTopology() {rebuild_ |= REBUILD_TOPOLOGY;}

  /** \brief request an update for the mesh vertices
   */
  void updateGeometry() {rebuild_ |= REBUILD_GEOMETRY;}

  /** \brief request an update for the textures
     */
  void updateTextures() {rebuild_ |= REBUILD_TEXTURES;}

  /** \brief request a full rebuild of the mesh
   *
   */
  void updateFull() {rebuild_ |= REBUILD_FULL;}

  /** \brief returns the number of used textured of this mesh
   *
   * @return Number of different textures used in the mesh
   */
  unsigned int getNumTextures();

  /** \brief set the name of the property used for texture index specification
  *
  * The given property name will define a texture index. The strip processor checks this
  * property and generates strips which contain only the same index. If the property is not
  * found, strips will be independent of this property
  *
  * @param _indexPropertyName
  */
  void setTextureIndexPropertyName( std::string _indexPropertyName );

  /** \brief get the name of the texture index property
   *
   * @return name of the texture index property
   */
  const std::string& getTextureIndexPropertyName() const { return textureIndexPropertyName_; };

  /** \brief set the name of the property used for texture coordinate
  *
  * The given property name will define per face Texture coordinates. This property has to be a
  * halfedge property. The coordinate on each edge is the texture coordinate of the to vertex.
  * If this property is not available, textures will not be processed by the strip processor.
  *
  * @param _perFaceTextureCoordinatePropertyName
  */
  void setPerFaceTextureCoordinatePropertyName( std::string _perFaceTextureCoordinatePropertyName );
Isaak Lim's avatar
Isaak Lim committed
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  /** \brief Check if per Face Texture coordinates are available
  *
  * If this function returns true, a per face per vertex texture array is available
  *
  * @return zero if not available, nonzero otherwise
  */
  int perFaceTextureCoordinateAvailable();

  /** \brief Check if texture indices are available
  *
  * If this function returns true, the strip processor will respect textures during strip generation.
  * Each returned strip has than an index that has to be used as a texture index during strip rendering.
  *
  * @return zero if not available, nonzero otherwise
  */
  int perFaceTextureIndexAvailable();

private:
  // processing pipeline:

  /** \brief  draw_mesh updater
   *
   */
  void rebuild();


Jan Möbius's avatar
Jan Möbius committed
319
  /** \brief Convert from halfedge data structure to triangle index list
320
   *
Jan Möbius's avatar
Jan Möbius committed
321
   * \note Only operates on indices
322
   *
Jan Möbius's avatar
Jan Möbius committed
323
   * @param _dstIndexBuf pointer to the resulting index buffer
Isaak Lim's avatar
Isaak Lim committed
324
325
   * @param _maxFaceVertexCount maximum number of vertices per face seen in mesh
   * @return number of triangles,  also fills triToFaceMap
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
   */
  unsigned int convertToTriangleMesh(unsigned int* _dstIndexBuf, unsigned int _maxFaceVertexCount);

  /** \brief create the big 3 * NumTris vertex buffer
   *
   * @param _dstVertexBuf [out] pointer to the resulting vertex buffer
   * @param _dstVertexMap [out] pointer to the resulting vertex map
   * @param _indexBuf [in] pointer to the original index buffer, which is not needed anymore after this call
   */
  void createBigVertexBuf(Vertex* _dstVertexBuf, unsigned int* _dstVertexMap, const unsigned int* _indexBuf);

  /** \brief reads a vertex from mesh_ and write it to _pDst
   *
   * @param _pDst [out] pointer to the resulting vertex
   * @param _vh mesh vertex handle to read from
   * @param _hh corresponding halfedge handle of this vertex
   * @param _fh corresponding face handle of this vertex
   */
344
345
346
347
  void readVertex(Vertex*                             _pDst,
                  const typename Mesh::VertexHandle   _vh,
                  const typename Mesh::HalfedgeHandle _hh,
                  const typename Mesh::FaceHandle     _fh);
348
349
350
351
352
353
354
355
356
357
358
359
360
361

  /** \brief
   *
   */
  void removeIsolatedVerts();

  /** \brief minimize the big vertex buffer
   *
   * @param _dstVertexBuf [out] pointer to the resulting vertex buffer
   * @param _srcVertexBuf [in] pointer to the big vertex buffer
   * @param _dstIndexBuf [out] pointer to the resutling index buffer
   * @param _dstVertexMap [out] pointer to the resulting vertex map (new -> old vertex)
   * @param _srcVertexMap [in] pointer to the previously used vertex map (new -> old vertex)
   * @param _duplicatesMap [out] maps from a duplicate vertex to it's first occurrence (OpenMesh vertex indices)
Jan Möbius's avatar
Jan Möbius committed
362
   * @return new number of vertices
363
364
365
366
367
368
   */
  unsigned int weldVertices(Vertex*             _dstVertexBuf,
                            const Vertex*       _srcVertexBuf,
                            unsigned int*       _dstIndexBuf,
                            unsigned int*       _dstVertexMap,
                            const unsigned int* _srcVertexMap,
Jan Möbius's avatar
Jan Möbius committed
369
                            std::list< std::pair<unsigned int, unsigned int> >& _duplicatesMap);
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

  /** \brief sort triangles by material id
   *
   *
   * also creates subsets: subsets_
   *
   * _dstIndexBuf and _srcIndexBuf must be different!
   *
   * @param _dstIndexBuf [out] pointer to the resulting index buffer
   * @param _srcIndexBuf [in] pointer to the index buffer about to be sorted
   */
  void sortTrisByMaterial(unsigned int* _dstIndexBuf, const unsigned int* _srcIndexBuf);

  /** \brief GPU cache optimization
   *
   * _dstIndexBuf == _srcIndexBuf allowed (inplace operation)
   * tris are optimized based on subsets
   * SortTrisByMaterial must be called prior!!
   * also maintains triToFaceMap_
   *
   * @param _dstIndexBuf [out] pointer to the resulting index buffer
   * @param _srcIndexBuf [in] pointer to the unoptimized index buffer
   */
  void optimizeTris(unsigned int* _dstIndexBuf, unsigned int* _srcIndexBuf);

  /** \brief optimize vertex layout
   *
   * for best results, call this after optimizeTris
   * also maintains vertexMap_,
   * NOTE: _srcVertexMap is invalid after this call
   * _srcVertexBuf != _dstVertexBuf!!
   *
   * @param _dstVertexBuf [out] pointer to the resulting vertex buffer
   * @param _srcVertexBuf [in] pointer to the source vertex buffer
   * @param _inOutIndexBuf [in, out] pointer to the index buffer, altered by this function
   * @param _srcVertexMap [in] pointer to the vertex map (new -> old vertex)
   */
  void optimizeVerts(Vertex*             _dstVertexBuf,
                     const Vertex*       _srcVertexBuf,
                     unsigned int*       _inOutIndexBuf,
                     const unsigned int* _srcVertexMap);


413
414
415
416
417
  /** \brief  eventually update vertex and index buffers
   *
   */
  void updateGPUBuffers();

418
419
420
421
422
423
424
425
426
427
  /** \brief  stores the vertex buffer on the gpu
   *
   */
  void createVBO();

  /** \brief stores the index buffer on the gpu
   *
   */
  void createIBO();

428
429
430
431
432
  /** \brief creates all vertex declarations needed for deferred draw call renderer
   *
   */
  void createVertexDeclarations();

433
434
435
436
437
438
439
440
441
442
public:
  // color picking

   /** Call this function to update the color picking array
  * The _offsett value can be used to shift the color in the resulting arrays.
  * pick Any uses the offset to generate arrays for picking everything.
  *
  * @param _state
  * @param _offset
  */
Isaak Lim's avatar
Isaak Lim committed
443
  void updatePickingVertices(ACG::GLState& _state , uint _offset = 0);
444
445
446
447
448

  /** \brief get a pointer to the per vertex picking color buffer
  *
  * This function will return a pointer to the first element of the picking buffer.
  * Use updatePickingVertices to update the buffer before you render it via
449
  * ACG::GLState::colorPointer.
450
451
452
453
  *
  * @return pointer to the first element of the picking buffer
  */
  ACG::Vec4uc * pickVertexColorBuffer(){
Jan Möbius's avatar
Jan Möbius committed
454
    if ( !pickVertColBuf_.empty() )
455
456
457
458
459
460
461
462
463
464
465
      return &(pickVertColBuf_)[0];
    else {
      std::cerr << "Illegal request to pickVertexColorBuffer when buffer is empty!" << std::endl;
      return 0;
    }
  };

  /** \brief get a pointer to the per vertex picking vertex buffer
  *
  * This function will return a pointer to the first element of the picking buffer.
  * Use updatePickingVertices to update the buffer before you render it via
466
  * ACG::GLState::vertexPointer.
467
468
469
470
  *
  * @return pointer to the first element of the picking buffer
  */
  ACG::Vec3f * pickVertexBuffer(){
Jan Möbius's avatar
Jan Möbius committed
471
    if ( !pickVertBuf_.empty() )
472
473
      return &(pickVertBuf_)[0];
    else {
474
      std::cerr << "Illegal request to pickVertexBuffer when buffer is empty!" << std::endl;
475
476
477
      return 0;
    }
  };
Isaak Lim's avatar
Isaak Lim committed
478
479
480

private:

481
482
  /// The vertex buffer used for vertex picking
  std::vector< ACG::Vec3f > pickVertBuf_;
483
  /// The color buffer used for vertex picking
484
  std::vector< ACG::Vec4uc > pickVertColBuf_;
485
486
487
488



public:
Isaak Lim's avatar
Isaak Lim committed
489

490
491
492
493
494
495
496
497
498
  /**  \brief Update color picking array for edges
   *
   * Call this function to update the color picking array
   * The _offsett value can be used to shift the color in the resulting arrays.
   * pick Any uses the offset to generate arrays for picking everything.
   *
   * @param _state
   * @param _offset
   */
Isaak Lim's avatar
Isaak Lim committed
499
500
  void updatePickingEdges(ACG::GLState& _state , uint _offset = 0 );

501
502
503
504
  /** \brief get a pointer to the per edge picking color buffer
  *
  * This function will return a pointer to the first element of the picking buffer.
  * Use updatePickingEdges to update the buffer before you render it via
505
  * ACG::GLState::colorPointer.
506
507
508
509
  *
  * @return pointer to the first element of the picking buffer
  */
  ACG::Vec4uc * pickEdgeColorBuffer(){
Jan Möbius's avatar
Jan Möbius committed
510
    if ( !pickEdgeBuf_.empty() )
511
512
513
514
515
516
      return &(pickEdgeBuf_)[0];
    else {
      std::cerr << "Illegal request to pickEdgeColorBuffer when buffer is empty!" << std::endl;
      return 0;
    }
  }
Isaak Lim's avatar
Isaak Lim committed
517
518
519

private:

520
521
522
523
524
  std::vector< ACG::Vec4uc > pickEdgeBuf_;



public:
Isaak Lim's avatar
Isaak Lim committed
525

526
527
528
529
  /**  \brief Update color picking array for faces
   *
   * @param _state
   */
Isaak Lim's avatar
Isaak Lim committed
530
531
  void updatePickingFaces(ACG::GLState& _state );

532
533
534
535
  /** \brief get a pointer to the per face picking color buffer
  *
  * This function will return a pointer to the first element of the picking buffer.
  * Use updatePickingFaces to update the buffer before you render it via
536
  * ACG::GLState::colorPointer.
537
538
539
540
  *
  * @return pointer to the per face picking color buffer
  */
  ACG::Vec4uc * pickFaceColorBuffer(){
Jan Möbius's avatar
Jan Möbius committed
541
    if ( !pickFaceColBuf_.empty() )
542
543
544
545
546
547
548
549
550
551
552
      return &(pickFaceColBuf_)[0];
    else {
      std::cerr << "Illegal request to pickFaceColorBuffer when buffer is empty!" << std::endl;
      return 0;
    }
  }

  /** \brief get a pointer to the per vertex picking color buffer
    *
    * This function will return a pointer to the first element of the picking buffer.
    * Use updatePickingFaces to update the buffer before you render it via
553
    * ACG::GLState::colorPointer.
554
555
556
557
    *
    * @return pointer to the first element of the picking buffer
    */
  ACG::Vec3f * pickFaceVertexBuffer(){
Jan Möbius's avatar
Jan Möbius committed
558
    if ( !pickFaceVertexBuf_.empty() )
559
560
561
562
563
564
      return &(pickFaceVertexBuf_)[0];
    else {
      std::cerr << "Illegal request to pickFaceVertexBuffer when buffer is empty!" << std::endl;
      return 0;
    }
  }
Isaak Lim's avatar
Isaak Lim committed
565
566

private:
567
568
569
570
571
572
573
574
575
576
577
578
579

  std::vector< ACG::Vec3f > pickFaceVertexBuf_;
  std::vector< ACG::Vec4uc > pickFaceColBuf_;


public:
  /** \brief Call this function to update the color picking array
  *
  * This function calls the updatePickingVertices, updatePickingEdges, updatePickingVertices
  * functions with an appropriate offset so that the standard arrays will be updated.
  *
  * @param _state OpenGL state
  */
Isaak Lim's avatar
Isaak Lim committed
580
581
  void updatePickingAny(ACG::GLState& _state );

582
583
584
585
  /** \brief get a pointer to the any picking color buffer
  *
  * This function will return a pointer to the first element of the picking buffer.
  * Use updatePickingAny to update the buffer before you render it via
586
  * ACG::GLState::colorPointer.
587
588
589
  *
  * @return Pointer to the first element of the picking buffer
  */
Jan Möbius's avatar
Jan Möbius committed
590
591
592
  ACG::Vec4uc * pickAnyFaceColorBuffer(){
    if ( !pickAnyFaceColBuf_.empty() )
      return &(pickAnyFaceColBuf_)[0];
593
    else {
Jan Möbius's avatar
Jan Möbius committed
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
      std::cerr << "Illegal request to pickAnyFaceColorBuffer when buffer is empty!" << std::endl;
      return 0;
    }
  }

  /** \brief get a pointer to the any picking color buffer
  *
  * This function will return a pointer to the first element of the picking buffer.
  * Use updatePickingAny to update the buffer before you render it via
  * ACG::GLState::colorPointer.
  *
  * @return Pointer to the first element of the picking buffer
  */
  ACG::Vec4uc * pickAnyEdgeColorBuffer(){
    if ( !pickAnyEdgeColBuf_.empty() )
      return &(pickAnyEdgeColBuf_)[0];
    else {
      std::cerr << "Illegal request to pickAnyEdgeColorBuffer when buffer is empty!" << std::endl;
      return 0;
    }
  }

  /** \brief get a pointer to the any picking color buffer
  *
  * This function will return a pointer to the first element of the picking buffer.
  * Use updatePickingAny to update the buffer before you render it via
  * ACG::GLState::colorPointer.
  *
  * @return Pointer to the first element of the picking buffer
  */
  ACG::Vec4uc * pickAnyVertexColorBuffer(){
    if ( !pickAnyVertexColBuf_.empty() )
      return &(pickAnyVertexColBuf_)[0];
    else {
      std::cerr << "Illegal request to pickAnyVertexColorBuffer when buffer is empty!" << std::endl;
629
630
631
      return 0;
    }
  }
Isaak Lim's avatar
Isaak Lim committed
632
633
634

private:

Jan Möbius's avatar
Jan Möbius committed
635
636
637
  std::vector< ACG::Vec4uc > pickAnyFaceColBuf_;
  std::vector< ACG::Vec4uc > pickAnyEdgeColBuf_;
  std::vector< ACG::Vec4uc > pickAnyVertexColBuf_;
Isaak Lim's avatar
Isaak Lim committed
638

639
640
641
642
643
644
645
646
647
648
649
650

private:

  // small helper functions

  /** \brief Number of triangles after triangulation of the mesh
   *
   * returns the number of tris after triangulation of this mesh
   * if needed, also returns the highest number of vertices of a face
   *
   * @param _pOutMaxPolyVerts
   *
Jan Möbius's avatar
Jan Möbius committed
651
   * @return  number of triangles
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
  */
  unsigned int countTris(unsigned int* _pOutMaxPolyVerts = 0);

  /** \brief get the texture index of a triangle
   *
   *
   *  @param _tri Triangle index (-1 if not available)
   *
   *  @return Texture index of a triangle
   */
  int getTextureIDofTri(unsigned int _tri);

private:

  /// OpenMesh object to be rendered
  Mesh& mesh_;

  unsigned int numTris_, numVerts_;

  /// final index buffer used for rendering
  unsigned int* indices_;

  /// final vertex buffer used for rendering
  Vertex* vertices_;

  /// hint on what to rebuild
  unsigned int rebuild_;

  /** used to track mesh changes, that require a full rebuild
    * values directly taken from Mesh template
    */
  unsigned int prevNumFaces_,prevNumVerts_;


  // per material/texture subsets
  unsigned int numSubsets_;
  Subset* subsets_;

  GLuint vbo_,
         ibo_;

  /// index buffer used in Wireframe / Hiddenline mode
  GLuint lineIBO_;

  /// support for 2 and 4 byte unsigned integers
  GLenum indexType_;

  /// Color Mode: 0: none, 1: per vertex,  else: per face
  int colorMode_;
  /// flat / smooth shade mode toggle
  int flatMode_;
Isaak Lim's avatar
Isaak Lim committed
703

704
705
706
707
708
709
710
711
712
  /// normals in VBO currently in flat / smooth mode
  int bVBOinFlatMode_;

  /// per vertex / halfedge texture mode toggle:  0: per vertex,  1: per halfedge
  int textureMode_;

  /// texcoords in VBO currently in per vertex / halfedge mode toggle
  int bVBOinHalfedgeTexMode_;

713
714
715
716
717
718
  /// per vertex / halfedge normals mode toggle:  0: per vertex,  1: per halfedge
  int halfedgeNormalMode_;

  /// normals in VBO currently in per vertex / halfedge mode toggle
  int bVBOinHalfedgeNormalMode_;

719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

  /** remapping for faster mesh change updates
   *  maps from triangle index to Mesh::FaceHandle::idx
   */
  unsigned int* triToFaceMap_;

  /// vertex index in vbo -> original OpenMesh halfedge index
  unsigned int* vertexMap_;

  /** inverse vertex map: original OpenMesh vertex index -> one vertex index in vbo
      this map is ambiguous and only useful for per vertex attributes rendering i.e. lines!
  */
  unsigned int* invVertexMap_;


734
735
736
737
738
739
  /// vertex buffer layout declaration with per vertex colors
  VertexDeclaration* vertexDeclVCol_;

  /// vertex buffer layout declaration with per face colors
  VertexDeclaration* vertexDeclFCol_;

740
741
742
743
744
745
746
747
748
  /// vertex buffer layout declaration with per edge colors
  VertexDeclaration* vertexDeclEdgeCol_;

  /// vertex buffer layout declaration with per halfedge colors
  VertexDeclaration* vertexDeclHalfedgeCol_;

  /// vertex buffer layout declaration with halfedge positions only
  VertexDeclaration* vertexDeclHalfedgePos_;

749

750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
  //========================================================================
  // internal processing
  // temporal buffer allocations to avoid memory requests while updating
  //========================================================================

  unsigned int* indicesTmp_;
  Vertex* verticesTmp_;

  //========================================================================
  // texture handling
  //========================================================================

  /** \brief Property for the per face texture index.
  *
  * This property is used by the mesh for texture index specification.
  * If this is invalid, then it is assumed that there is one or no active
Isaak Lim's avatar
Isaak Lim committed
766
  * texture. This means that the generated strips will be independent of texture
767
  * information.
Isaak Lim's avatar
Isaak Lim committed
768
  */
769
770
771
772
773
774
  std::string textureIndexPropertyName_;

  /** \brief Property for the per face texture coordinates.
  *
  * This property is used by the mesh for texture coordinate specification.
  * If this is invalid, then the strip processor will ignore per face textures during processing.
Isaak Lim's avatar
Isaak Lim committed
775
  */
776
777
  std::string perFaceTextureCoordinatePropertyName_;

Isaak Lim's avatar
Isaak Lim committed
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
public:
  //========================================================================
  // per edge buffers

  /** \brief Update of the buffers
  *
  * This function will set all per edge buffers to invalid and will force an update
  * whe they are requested
  */
  void invalidatePerEdgeBuffers() {updatePerEdgeBuffers_ = 1;}

  /** \brief Update all per edge drawing buffers
  *
  * The updated buffers are: vertex buffer ( 2 vertices per edge ), color buffer
  */
  void updatePerEdgeBuffers();
Isaak Lim's avatar
Isaak Lim committed
795

796
797
798
799
800
  /** \brief get a pointer to the per edge vertex buffer
  *
  * This function will return a pointer to the first element of the vertex buffer.
  */
  ACG::Vec3f* perEdgeVertexBuffer();
Isaak Lim's avatar
Isaak Lim committed
801

802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
  /** \brief get a pointer to the per edge color buffer
  *
  * This function will return a pointer to the first element of the color buffer.
  */
  ACG::Vec4f* perEdgeColorBuffer();

  /** \brief Update of the buffers
  *
  * This function will set all per edge buffers to invalid and will force an update
  * whe they are requested
  */
  void invalidatePerHalfedgeBuffers() {updatePerHalfedgeBuffers_ = 1;}

  /** \brief Update all per edge drawing buffer
  *n
  * The updated buffers are: per edge vertex buffer ( 2 vertices per edge )
  */
  void updatePerHalfedgeBuffers();
Isaak Lim's avatar
Isaak Lim committed
820

821
822
823
824
825
  /** \brief get a pointer to the per edge vertex buffer
  *
  * This function will return a pointer to the first element of the vertex buffer.
  */
  ACG::Vec3f* perHalfedgeVertexBuffer();
Isaak Lim's avatar
Isaak Lim committed
826

827
828
829
830
831
832
833
  /** \brief get a pointer to the per edge color buffer
  *
  * This function will return a pointer to the first element of the color buffer.
  */
  ACG::Vec4f* perHalfedgeColorBuffer();


834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
  /** \brief updates per edge and halfedge vertex declarations
  */
  void updateEdgeHalfedgeVertexDeclarations();


  /** \brief getter for vertex declarations
  */
  const VertexDeclaration* getEdgeColoredVertexDeclaration() const {return vertexDeclEdgeCol_;}

  /** \brief getter for vertex declarations
  */
  const VertexDeclaration* getHalfedgeVertexDeclaration() const {return vertexDeclHalfedgePos_;}

  /** \brief getter for vertex declarations
  */
  const VertexDeclaration* getHalfedgeColoredVertexDeclaration() const {return vertexDeclHalfedgeCol_;}


852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
private:
  int updatePerEdgeBuffers_;
  std::vector<ACG::Vec3f> perEdgeVertexBuf_;
  std::vector<ACG::Vec4f> perEdgeColorBuf_;

  int updatePerHalfedgeBuffers_;
  std::vector<ACG::Vec3f> perHalfedgeVertexBuf_;
  std::vector<ACG::Vec4f> perHalfedgeColorBuf_;

  /** \brief compute halfedge point
  * compute visualization point for halfedge (shifted to interior of face)
  *
  * @param _heh
  *
  * @return
  */
  typename Mesh::Point halfedge_point(const typename Mesh::HalfedgeHandle _heh);

};



//=============================================================================
} // namespace ACG
//=============================================================================
#if defined(INCLUDE_TEMPLATES) && !defined(ACG_DRAW_MESH_C)
#define ACG_DRAW_MESH_TEMPLATES
#include "DrawMesh.cc"
#endif
//=============================================================================
#endif // ACG_DRAW_MESH_HH defined
//=============================================================================