Allolib  1.0
C++ Components For Interactive Multimedia
al_Mesh.hpp
1 #ifndef INCLUDE_AL_GRAPHICS_MESH_HPP
2 #define INCLUDE_AL_GRAPHICS_MESH_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  A generic mesh object for vertex-based geometry
40 
41  File author(s):
42  Wesley Smith, 2010, wesley.hoke@gmail.com
43  Lance Putnam, 2010, putnam.lance@gmail.com
44  Graham Wakefield, 2010, grrrwaaa@gmail.com
45  Keehong Youn, 2017, younkeehong@gmail.com
46 
47 */
48 
49 #include "al/graphics/al_OpenGL.hpp"
50 #include "al/math/al_Mat.hpp"
51 #include "al/math/al_Vec.hpp"
52 #include "al/types/al_Color.hpp"
53 #include <vector>
54 
55 namespace al {
56 
58 
62 class Mesh {
63 public:
64  enum Primitive : unsigned int {
65  POINTS = GL_POINTS,
66  LINES = GL_LINES,
67  LINE_STRIP = GL_LINE_STRIP,
68  LINE_LOOP = GL_LINE_LOOP,
69  TRIANGLES = GL_TRIANGLES,
70  TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
71  TRIANGLE_FAN = GL_TRIANGLE_FAN,
72  LINES_ADJACENCY = GL_LINES_ADJACENCY,
73  LINE_STRIP_ADJACENCY = GL_LINE_STRIP_ADJACENCY,
74  TRIANGLES_ADJACENCY = GL_TRIANGLES_ADJACENCY,
75  TRIANGLE_STRIP_ADJACENCY = GL_TRIANGLE_STRIP_ADJACENCY
76  };
77 
78  typedef Vec3f Vertex;
79  typedef Vec3f Normal;
80  typedef float TexCoord1;
81  typedef Vec2f TexCoord2;
82  typedef Vec3f TexCoord3;
83  typedef unsigned int Index;
84 
85  typedef std::vector<Vertex> Vertices;
86  typedef std::vector<Normal> Normals;
87  typedef std::vector<Color> Colors;
88  typedef std::vector<TexCoord1> TexCoord1s;
89  typedef std::vector<TexCoord2> TexCoord2s;
90  typedef std::vector<TexCoord3> TexCoord3s;
91  typedef std::vector<Index> Indices;
92 
94  Mesh(Primitive p = TRIANGLES);
95 
96  Mesh(const Mesh &cpy);
97 
98  void copy(Mesh const &m);
99 
101 
104  void getBounds(Vec3f &min, Vec3f &max) const;
105 
107  Vec3f getCenter() const;
108 
109  // destructive edits to internal vertices:
110 
112  void compress();
113 
115  void decompress();
116 
118 
122 
124  void merge(const Mesh &src);
125 
127  void toTriangles();
128 
131 
133  void unitize(bool proportional = true);
134 
136  Mesh &scale(float x, float y, float z);
137  Mesh &scale(float s) { return scale(s, s, s); }
138 
139  template <class T> Mesh &scale(const Vec<3, T> &v) {
140  return scale(v[0], v[1], v[2]);
141  }
142 
144  Mesh &translate(float x, float y, float z);
145 
146  template <class T> Mesh &translate(const Vec<3, T> &v) {
147  return translate(v[0], v[1], v[2]);
148  }
149 
150  template <class T> Mesh &translate(const T &v) { return translate(v, v, v); }
151 
153 
158  template <class T>
159  Mesh &transform(const Mat<4, T> &m, int begin = 0, int end = -1);
160 
162 
173  void generateNormals(bool normalize = true, bool equalWeightPerFace = false);
174 
177 
179 
184  void createNormalsMesh(Mesh &mesh, float length = 0.1, bool perFace = false);
185 
187 
194  void ribbonize(float width = 0.04, bool faceBinormal = false) {
195  ribbonize(&width, 0, faceBinormal);
196  }
197 
199 
208  void ribbonize(float *widths, int widthsStride = 1,
209  bool faceBinormal = false);
210 
212 
219  void smooth(float amount = 1, int weighting = 0);
220 
221  Primitive primitive() const { return mPrimitive; }
222  const std::vector<Vertex> &vertices() const { return mVertices; }
223  const std::vector<Normal> &normals() const { return mNormals; }
224  const std::vector<Color> &colors() const { return mColors; }
225  const std::vector<TexCoord1> &texCoord1s() const { return mTexCoord1s; }
226  const std::vector<TexCoord2> &texCoord2s() const { return mTexCoord2s; }
227  const std::vector<TexCoord3> &texCoord3s() const { return mTexCoord3s; }
228  const std::vector<Index> &indices() const { return mIndices; }
229 
231  // virtual for graphics lib implementations
232  Mesh &primitive(Primitive p) {
233  mPrimitive = p;
234  return *this;
235  }
236 
239 
241  void index(unsigned int i) { indices().push_back(i); }
242 
244  template <class Tindex>
245  void index(const Tindex *buf, int size, Tindex indexOffset = 0) {
246  for (int i = 0; i < size; ++i)
247  index((Index)(buf[i] + indexOffset));
248  }
249 
250  template <class... Indices> void index(unsigned i, Indices... indices) {
251  index(i);
252  index(indices...);
253  }
254 
256  void color(const Color &v) { colors().push_back(v); }
257 
259  void color(const HSV &v) { colors().push_back(v); }
260 
262  void color(const RGB &v) { colors().push_back(v); }
263 
265  void color(float r, float g, float b, float a = 1) {
266  color(Color(r, g, b, a));
267  }
268 
270  template <class T> void color(const Vec<4, T> &v) {
271  color(v[0], v[1], v[2], v[3]);
272  }
273 
275  template <class T> void color(const T *src, int numColors) {
276  for (int i = 0; i < numColors; ++i)
277  color(src[4 * i + 0], src[4 * i + 1], src[4 * i + 2], src[4 * i + 3]);
278  }
279 
281  void normal(float x, float y, float z = 0) { normal(Normal(x, y, z)); }
282 
284  void normal(const Normal &v) { normals().push_back(v); }
285 
287  template <class T> void normal(const Vec<2, T> &v, float z = 0) {
288  normal(v[0], v[1], z);
289  }
290 
292  template <class T> void normal(const T *src, int numNormals) {
293  for (int i = 0; i < numNormals; ++i)
294  normal(src[3 * i + 0], src[3 * i + 1], src[3 * i + 2]);
295  }
296 
298  void texCoord(float u) { texCoord1s().push_back(TexCoord1(u)); }
299 
301  void texCoord(float u, float v) { texCoord2s().push_back(TexCoord2(u, v)); }
302 
304  template <class T> void texCoord(const Vec<2, T> &v) { texCoord(v[0], v[1]); }
305 
307  void texCoord(float u, float v, float w) {
308  texCoord3s().push_back(TexCoord3(u, v, w));
309  }
310 
312  template <class T> void texCoord(const Vec<3, T> &v) {
313  texCoord(v[0], v[1], v[2]);
314  }
315 
317  void vertex(float x, float y, float z = 0) { vertex(Vertex(x, y, z)); }
318 
320  void vertex(const Vertex &v) { vertices().push_back(v); }
321 
323  template <class T> void vertex(const Vec<2, T> &v, float z = 0) {
324  vertex(v[0], v[1], z);
325  }
326 
328  template <class T> void vertex(const T *src, int numVerts) {
329  for (int i = 0; i < numVerts; ++i)
330  vertex(src[3 * i + 0], src[3 * i + 1], src[3 * i + 2]);
331  }
332 
334  template <class T> void vertex(const Vec<3, T> *src, int numVerts) {
335  for (int i = 0; i < numVerts; ++i)
336  vertex(src[i][0], src[i][1], src[i][2]);
337  }
338 
339  Vertices &vertices() { return mVertices; }
340  Normals &normals() { return mNormals; }
341  Colors &colors() { return mColors; }
342  TexCoord1s &texCoord1s() { return mTexCoord1s; }
343  TexCoord2s &texCoord2s() { return mTexCoord2s; }
344  TexCoord3s &texCoord3s() { return mTexCoord3s; }
345  Indices &indices() { return mIndices; }
346 
348 
355  bool save(const char *filePath, const char *solidName = "",
356  bool binary = true) const;
357 
359 
368  bool saveSTL(const char *filePath, const char *solidName = "") const;
369 
371 
378  bool savePLY(const char *filePath, const char *solidName = "",
379  bool binary = true) const;
380 
382  void print(FILE *dst = stderr) const;
383 
384 protected:
385  // Only populated (size>0) buffers will be used
386  Vertices mVertices;
387  Normals mNormals;
388  Colors mColors;
389  TexCoord1s mTexCoord1s;
390  TexCoord2s mTexCoord2s;
391  TexCoord3s mTexCoord3s;
392  Indices mIndices;
393 
394  Primitive mPrimitive;
395 };
396 
397 template <class T>
398 Mesh &Mesh::transform(const Mat<4, T> &m, int begin, int end) {
399  if (end < 0)
400  end += vertices().size() + 1; // negative index wraps to end of array
401  for (int i = begin; i < end; ++i) {
402  Vertex &v = vertices()[i];
403  v.set(m * Vec<4, T>(v, 1));
404  }
405  return *this;
406 }
407 
408 } // namespace al
409 
410 #endif
Fixed-size n-by-n square matrix.
Definition: al_Mat.hpp:78
Stores buffers related to rendering graphical objects.
Definition: al_Mesh.hpp:62
void unitize(bool proportional=true)
Scale all vertices to lie in [-1,1].
Mesh & transform(const Mat< 4, T > &m, int begin=0, int end=-1)
Transform vertices by projective transform matrix.
Definition: al_Mesh.hpp:398
void smooth(float amount=1, int weighting=0)
Smooths a triangle mesh.
void color(const Vec< 4, T > &v)
Append color to color buffer.
Definition: al_Mesh.hpp:270
bool saveSTL(const char *filePath, const char *solidName="") const
Save mesh to an STL file.
void index(unsigned int i)
Append index to index buffer.
Definition: al_Mesh.hpp:241
void decompress()
Convert indices (if any) to flat vertex buffers.
void texCoord(float u)
Append texture coordinate to 1D texture coordinate buffer.
Definition: al_Mesh.hpp:298
void vertex(const Vec< 3, T > *src, int numVerts)
Append vertices to vertex buffer.
Definition: al_Mesh.hpp:334
void normal(const Normal &v)
Append normal to normal buffer.
Definition: al_Mesh.hpp:284
void vertex(const T *src, int numVerts)
Append vertices from flat array.
Definition: al_Mesh.hpp:328
void texCoord(const Vec< 2, T > &v)
Append texture coordinate to 2D texture coordinate buffer.
Definition: al_Mesh.hpp:304
Vec3f getCenter() const
Get center of vertices.
Mesh & primitive(Primitive p)
Set geometric primitive.
Definition: al_Mesh.hpp:232
Mesh & repeatLast()
Repeat last vertex element(s)
void vertex(float x, float y, float z=0)
Append vertex to vertex buffer.
Definition: al_Mesh.hpp:317
void color(const HSV &v)
Append color to color buffer.
Definition: al_Mesh.hpp:259
void invertNormals()
Invert direction of normals.
void print(FILE *dst=stderr) const
Print information about Mesh.
void ribbonize(float width=0.04, bool faceBinormal=false)
Ribbonize curve.
Definition: al_Mesh.hpp:194
void normal(const T *src, int numNormals)
Append normals from flat array.
Definition: al_Mesh.hpp:292
void toTriangles()
Convert triangle strip to triangles.
void color(const T *src, int numColors)
Append colors from flat array.
Definition: al_Mesh.hpp:275
void texCoord(float u, float v)
Append texture coordinate to 2D texture coordinate buffer.
Definition: al_Mesh.hpp:301
void compress()
Generates indices for a set of vertices.
bool savePLY(const char *filePath, const char *solidName="", bool binary=true) const
Save mesh to a PLY file.
void getBounds(Vec3f &min, Vec3f &max) const
Get corners of bounding box of vertices.
void index(const Tindex *buf, int size, Tindex indexOffset=0)
Append indices to index buffer.
Definition: al_Mesh.hpp:245
Mesh(Primitive p=TRIANGLES)
void normal(float x, float y, float z=0)
Append normal to normal buffer.
Definition: al_Mesh.hpp:281
bool save(const char *filePath, const char *solidName="", bool binary=true) const
Save mesh to file.
void vertex(const Vec< 2, T > &v, float z=0)
Append vertex to vertex buffer.
Definition: al_Mesh.hpp:323
Mesh & scale(float x, float y, float z)
Scale all vertices.
void equalizeBuffers()
Extend buffers to match number of vertices.
void texCoord(float u, float v, float w)
Append texture coordinate to 3D texture coordinate buffer.
Definition: al_Mesh.hpp:307
void texCoord(const Vec< 3, T > &v)
Append texture coordinate to 3D texture coordinate buffer.
Definition: al_Mesh.hpp:312
void merge(const Mesh &src)
Append buffers from another mesh:
void normal(const Vec< 2, T > &v, float z=0)
Append normal to normal buffer.
Definition: al_Mesh.hpp:287
void color(const RGB &v)
Append color to color buffer.
Definition: al_Mesh.hpp:262
Mesh & reset()
Reset all buffers.
Mesh & translate(float x, float y, float z)
Translate all vertices.
void color(float r, float g, float b, float a=1)
Append color to color buffer.
Definition: al_Mesh.hpp:265
void generateNormals(bool normalize=true, bool equalWeightPerFace=false)
Generates normals for a set of vertices.
void createNormalsMesh(Mesh &mesh, float length=0.1, bool perFace=false)
Creates a mesh filled with lines for each normal of the source.
void ribbonize(float *widths, int widthsStride=1, bool faceBinormal=false)
Ribbonize curve.
void color(const Color &v)
Append color to color buffer.
Definition: al_Mesh.hpp:256
void vertex(const Vertex &v)
Append vertex to vertex buffer.
Definition: al_Mesh.hpp:320
Vec & set(const Vec< N, T2 > &v)
Set elements from another vector.
Definition: al_Vec.hpp:301
T min(const T &v1, const T &v2, const T &v3)
T max(const T &v1, const T &v2, const T &v3)
Definition: al_App.hpp:23
Color represented by hue, saturation, and value.
Definition: al_Color.hpp:397
Color represented by red, green, and blue components.
Definition: al_Color.hpp:503