ROOT logo
// $Id: TringTvor.h 2545 2011-10-09 05:42:10Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

#ifndef Geom1_TringTvor_H
#define Geom1_TringTvor_H

#include <Gled/GledTypes.h>

class TringTvor
{
private:
  void _init();

public:

  Int_t                mNVerts;
  Int_t                mNTrings;

  // Default normal, color, texture modes.

  enum Mode_e { M_None, M_PerVertex, M_PerTriangle };

  Mode_e               mNormalMode;
  Mode_e               mColorMode;
  Mode_e               mTextureMode;

  // Vertex data

  std::vector<Float_t> mVerts;  // Vertex coordinates, 3*mNVert
  std::vector<Float_t> mNorms;  // Normals, 3*mNVert
  std::vector<UChar_t> mCols;   // RGBA color, 4*mNVert
  std::vector<Float_t> mTexs;   // Texture coordinates, 2*mNVert

  bool HasNorms() { return ! mNorms.empty(); }
  bool HasCols()  { return ! mCols .empty(); }
  bool HasTexs()  { return ! mTexs .empty(); }

  void MakeNorms() { mNorms.resize(3*mNVerts); }
  void MakeCols()  { mCols .resize(4*mNVerts); }
  void MakeTexs()  { mTexs .resize(2*mNVerts); }

  void AssertNorms() { if ( ! HasNorms()) MakeNorms(); }
  void AssertCols()  { if ( ! HasCols())  MakeCols();  }
  void AssertTexs()  { if ( ! HasTexs())  MakeTexs();  }

  void WipeVerts() { std::vector<Float_t> v; mVerts.swap(v); }
  void WipeNorms() { std::vector<Float_t> v; mNorms.swap(v); }
  void WipeCols()  { std::vector<UChar_t> v; mCols.swap(v);  }
  void WipeTexs()  { std::vector<Float_t> v; mTexs.swap(v);  }

  Int_t    NVerts() { return mNVerts;    }
  Float_t* Verts()  { return &mVerts[0]; }
  Float_t* Norms()  { return &mNorms[0]; }
  UChar_t* Cols()   { return &mCols[0];  }
  Float_t* Texs()   { return &mTexs[0];  }

  Float_t* Vertex(Int_t i)  { return &(mVerts[3*i]); }
  Float_t* Normal(Int_t i)  { return &(mNorms[3*i]); }
  UChar_t* Color(Int_t i)   { return &(mCols[4*i]);  }
  Float_t* Texture(Int_t i) { return &(mTexs[2*i]);  }

  // Triangle data

  std::vector<Int_t>   mTrings;       // Vertex-indices of triangles, 3*mNTrings
  std::vector<Float_t> mTringNorms;   // Triangle normals, 3*mNTrings
  std::vector<UChar_t> mTringCols;    // Triangle colors, 4*mNTrings
  std::vector<Float_t> mTringTexs;    // Triangle texture coords, 6*mNTrings

  Bool_t HasTringNorms()  { return ! mTringNorms.empty(); }
  Bool_t HasTringCols()   { return ! mTringCols .empty(); }
  Bool_t HasTringTexs()   { return ! mTringTexs .empty(); }

  void MakeTringNorms()   { mTringNorms.resize(3*mNTrings); }
  void MakeTringCols()    { mTringCols .resize(4*mNTrings); }
  void MakeTringTexs()    { mTringTexs .resize(6*mNTrings); }

  void AssertTringNorms() { if ( ! HasTringNorms()) MakeTringNorms(); }
  void AssertTringCols()  { if ( ! HasTringCols())  MakeTringCols();  }
  void AssertTringTexs()  { if ( ! HasTringTexs())  MakeTringTexs();  }

  void WipeTrings()     { std::vector<Int_t>   v; mTrings.swap(v);     }
  void WipeTringNorms() { std::vector<Float_t> v; mTringNorms.swap(v); }
  void WipeTringCols()  { std::vector<UChar_t> v; mTringCols.swap(v);  }
  void WipeTringTexs()  { std::vector<Float_t> v; mTringTexs.swap(v);  }

  Int_t    NTrings()    { return mNTrings;        }
  Int_t*   Trings()     { return &mTrings[0];     }
  Float_t* TringNorms() { return &mTringNorms[0]; }
  UChar_t* TringCols()  { return &mTringCols[0];  }
  Float_t* TringTexs()  { return &mTringTexs[0];  }

  Int_t*   Triangle(Int_t i)       { return &mTrings[3*i];     }
  Float_t* TriangleNormal(Int_t i) { return &mTringNorms[3*i]; }
  UChar_t* TriangleColor(Int_t i)  { return &mTringCols[4*i];  }
  Float_t* TriangleTexture(Int_t i){ return &mTringTexs[6*i];  }

  Bool_t   TriangleOtherVertices(Int_t t, Int_t v, Int_t& v_prev, Int_t& v_next);

  // Bounding-box stuff

  Bool_t   mBBoxOK;
  Float_t  mMinMaxBox[6];
  Float_t  mCtrExtBox[6];
  Float_t  mMaxVertexDistance; // Maximum distance of any vertex from the origin.
  Float_t  mBBoxHalfDiagonal;  // Half-length of bounding-box diagonal.
  Float_t  mMinEdgeLen;
  Float_t  mMaxEdgeLen;

  // Triangle strip data

  Int_t    mNStripEls;    //! Number of trianlge strip vertices (= 2*n-strips + n-of-triangles).
  Int_t*   mStripEls;     //! [mNStripEls] Vertex indices for all strips.
  Int_t*   mStripTrings;  //! [mNStripEls] Indices of triangles belonging to strip vertices, mNStripEls (first two triangles of each strip are not used). Needed for flat shading.
  Int_t    mNStrips;      //! Number of trianlge strips.
  Int_t**  mStripBegs;    //! [mNStrips] Pointers to strip beginnings into mStripEls, needed for glMultiDrawElements.
  Int_t*   mStripLens;    //! [mNStrips] Lengths of strips.

  Bool_t   HasTrianlgeStrips() const { return mNStripEls != 0; }

  // --------------------------------------------------------------

  TringTvor();
  TringTvor(Int_t nv, Int_t nt);
  TringTvor(Int_t nv, Int_t nt, Mode_e normal, Mode_e color, Mode_e texture);
  TringTvor(Int_t nv, Int_t nt, Bool_t smoothp, Bool_t colp=false, Bool_t texp=false);
  ~TringTvor();

  void Reset(Int_t nv, Int_t nt);
  void Reset(Int_t nv, Int_t nt, Mode_e normal, Mode_e color, Mode_e texture);

  void MakePrimaryArrays();
  void DeletePrimaryArrays();
  void MakeSecondaryArrays();
  void DeleteSecondaryArrays();

  void SetNormalMode(Mode_e mode)  { mNormalMode  = mode; }
  void SetColorMode(Mode_e mode)   { mColorMode   = mode; }
  void SetTextureMode(Mode_e mode) { mTextureMode = mode; }

  Int_t AddVertices(Int_t nv);
  Int_t AddTriangles(Int_t nt);

  void SetVertex(Int_t i, Float_t x, Float_t y, Float_t z)
  { Float_t* v = Vertex(i); v[0] = x; v[1] = y; v[2] = z; }
  void SetVertex(Int_t i, const Float_t q[3])
  { Float_t* v = Vertex(i); v[0] = q[0]; v[1] = q[1]; v[2] = q[2]; }
  void SetNormal(Int_t i, Float_t x, Float_t y, Float_t z)
  { Float_t* v = Normal(i); v[0] = x; v[1] = y; v[2] = z; }
  void SetTriangle(Int_t i, Int_t v0, Int_t v1, Int_t v2)
  { Int_t* t = Triangle(i); t[0] = v0; t[1] = v1; t[2] = v2; }
  void SetTriangleNormal(Int_t i, Float_t x, Float_t y, Float_t z)
  { Float_t* v = TriangleNormal(i); v[0] = x; v[1] = y; v[2] = z; }
  void SetTriangleColor(Int_t i, UChar_t r, UChar_t g, UChar_t b, UChar_t a=255)
  { UChar_t* c = TriangleColor(i); c[0] = r; c[1] = g; c[2] = b; c[3] = a; }
  void SetTriangleTexture(Int_t i, Float_t u0, Float_t v0, Float_t u1, Float_t v1, Float_t u2, Float_t v2)
  { Float_t* t = TriangleTexture(i); t[0] = u0; t[1] = v0; t[2] = u1; t[3] = v1; t[4] = u2; t[5] = v2; }

  void CalculateBoundingBox();
  void AssertBoundingBox() { if (mBBoxOK == false) CalculateBoundingBox(); }

  Float_t GetMaxVertexDistance()    const { return mMaxVertexDistance; }
  Float_t BoundingBoxDiagonal()     const { return 2.0f * mBBoxHalfDiagonal; }
  Float_t BoundingBoxHalfDiagonal() const { return mBBoxHalfDiagonal; }
  Float_t BoundingBoxXYArea()       const;
  Float_t BoundingBoxVolume()       const;
  Float_t GetMinEdgeLen()           const { return mMinEdgeLen; }
  Float_t GetMaxEdgeLen()           const { return mMaxEdgeLen; }

  Float_t CalculateTriangleNormal(Int_t ti, Float_t normal[3]);
  Float_t CalculateTriangleNormalAndCog(Int_t ti, Float_t normal[3], Float_t cog[3]);

  void GenerateTriangleNormals();
  void GenerateTriangleNormalsAndColors(void (*foo)(Float_t*, UChar_t*, void*),
					void* ud);

  void GenerateTriangleColorsFromVertexColors();
  void GenerateTriangleColorsFromVertexColors(UChar_t* VCA, UChar_t* TCA);
  void GenerateTriangleColorsFromVertexColors(set<Int_t>& triangles);
  void GenerateTriangleColorsFromVertexColors(set<Int_t>& triangles, UChar_t* VCA, UChar_t* TCA);

  void GenerateTriangleColorsFromTriangleStrips();

  void GenerateVertexNormals();

  // Helper function for determining vertex connectivity
  void  FindTrianglesPerVertex(vector<Int_t>* trings_per_vert);
  Int_t FindNeighboursPerVertex(vector<Int_t>* neighbours);

  // Triangle strips
  void GenerateTriangleStrips(Int_t max_verts=128);
  void DeleteTriangleStrips();

  // Export
  void ExportPovMesh(ostream& o, Bool_t smoothp=false);

  // FUQ (frequently used queries)
  Float_t SqrDistanceToVertex(Int_t vi, const Float_t p[3]);
  Float_t SqrLen(const Float_t a[3], const Float_t b[3]);
  void    SqrMinMaxEdgeLen(Int_t ti, Float_t& min, Float_t& max);

  // ----------------------------------------------------------------

  ClassDefNV(TringTvor, 1); // Tvor of triangles, a triangle mesh.
}; // endclass TringTvor


/**************************************************************************/
// Inlines
/**************************************************************************/

inline Bool_t TringTvor::TriangleOtherVertices(Int_t t, Int_t v,
                                               Int_t& v_prev, Int_t& v_next)
{
  // Find other two vertices (than v) in triangle t.
  // If you do: e1 = v_prev - v, e2 = v_next - v, then: e2 x e1 points
  // in the normal direction.

  Int_t * T = Triangle(t);
  if (T[0] == v) { v_prev = T[2]; v_next = T[1]; return true; }
  if (T[1] == v) { v_prev = T[0]; v_next = T[2]; return true; }
  if (T[2] == v) { v_prev = T[1]; v_next = T[0]; return true; }
  return false;
}

inline Float_t TringTvor::SqrDistanceToVertex(Int_t vi, const Float_t p[3])
{
  // Returns square distance from vertex vi to fiven point p.

  const Float_t* v = Vertex(vi);
  const Float_t dx = p[0] - v[0], dy = p[1] - v[1], dz = p[2] - v[2];
  return dx*dx + dy*dy + dz*dz;
}

inline Float_t TringTvor::SqrLen(const Float_t a[3], const Float_t b[3])
{
  // Returns square length of line between a and b.

  Float_t c[3] = { b[0] - a[0], b[1] - a[1], b[2] - a[2] };
  return c[0]*c[0] + c[1]*c[1] + c[2]*c[2];
}

inline void TringTvor::SqrMinMaxEdgeLen(Int_t ti, Float_t& min, Float_t& max)
{
  // Stores min and max edge lengths into the passed refs.

  const Int_t    *t   = Triangle(ti);
  const Float_t *v[3] = { Vertex(t[0]), Vertex(t[1]), Vertex(t[2]) };
  const float ab = SqrLen(v[0], v[1]);
  const float ac = SqrLen(v[0], v[2]);
  const float bc = SqrLen(v[1], v[2]);

  if (ab > ac) { min = ac; max = ab; }
  else         { min = ab; max = ac; }

  if (bc > max)      max = bc;
  else if (bc < min) min = bc;
}

#endif
 TringTvor.h:1
 TringTvor.h:2
 TringTvor.h:3
 TringTvor.h:4
 TringTvor.h:5
 TringTvor.h:6
 TringTvor.h:7
 TringTvor.h:8
 TringTvor.h:9
 TringTvor.h:10
 TringTvor.h:11
 TringTvor.h:12
 TringTvor.h:13
 TringTvor.h:14
 TringTvor.h:15
 TringTvor.h:16
 TringTvor.h:17
 TringTvor.h:18
 TringTvor.h:19
 TringTvor.h:20
 TringTvor.h:21
 TringTvor.h:22
 TringTvor.h:23
 TringTvor.h:24
 TringTvor.h:25
 TringTvor.h:26
 TringTvor.h:27
 TringTvor.h:28
 TringTvor.h:29
 TringTvor.h:30
 TringTvor.h:31
 TringTvor.h:32
 TringTvor.h:33
 TringTvor.h:34
 TringTvor.h:35
 TringTvor.h:36
 TringTvor.h:37
 TringTvor.h:38
 TringTvor.h:39
 TringTvor.h:40
 TringTvor.h:41
 TringTvor.h:42
 TringTvor.h:43
 TringTvor.h:44
 TringTvor.h:45
 TringTvor.h:46
 TringTvor.h:47
 TringTvor.h:48
 TringTvor.h:49
 TringTvor.h:50
 TringTvor.h:51
 TringTvor.h:52
 TringTvor.h:53
 TringTvor.h:54
 TringTvor.h:55
 TringTvor.h:56
 TringTvor.h:57
 TringTvor.h:58
 TringTvor.h:59
 TringTvor.h:60
 TringTvor.h:61
 TringTvor.h:62
 TringTvor.h:63
 TringTvor.h:64
 TringTvor.h:65
 TringTvor.h:66
 TringTvor.h:67
 TringTvor.h:68
 TringTvor.h:69
 TringTvor.h:70
 TringTvor.h:71
 TringTvor.h:72
 TringTvor.h:73
 TringTvor.h:74
 TringTvor.h:75
 TringTvor.h:76
 TringTvor.h:77
 TringTvor.h:78
 TringTvor.h:79
 TringTvor.h:80
 TringTvor.h:81
 TringTvor.h:82
 TringTvor.h:83
 TringTvor.h:84
 TringTvor.h:85
 TringTvor.h:86
 TringTvor.h:87
 TringTvor.h:88
 TringTvor.h:89
 TringTvor.h:90
 TringTvor.h:91
 TringTvor.h:92
 TringTvor.h:93
 TringTvor.h:94
 TringTvor.h:95
 TringTvor.h:96
 TringTvor.h:97
 TringTvor.h:98
 TringTvor.h:99
 TringTvor.h:100
 TringTvor.h:101
 TringTvor.h:102
 TringTvor.h:103
 TringTvor.h:104
 TringTvor.h:105
 TringTvor.h:106
 TringTvor.h:107
 TringTvor.h:108
 TringTvor.h:109
 TringTvor.h:110
 TringTvor.h:111
 TringTvor.h:112
 TringTvor.h:113
 TringTvor.h:114
 TringTvor.h:115
 TringTvor.h:116
 TringTvor.h:117
 TringTvor.h:118
 TringTvor.h:119
 TringTvor.h:120
 TringTvor.h:121
 TringTvor.h:122
 TringTvor.h:123
 TringTvor.h:124
 TringTvor.h:125
 TringTvor.h:126
 TringTvor.h:127
 TringTvor.h:128
 TringTvor.h:129
 TringTvor.h:130
 TringTvor.h:131
 TringTvor.h:132
 TringTvor.h:133
 TringTvor.h:134
 TringTvor.h:135
 TringTvor.h:136
 TringTvor.h:137
 TringTvor.h:138
 TringTvor.h:139
 TringTvor.h:140
 TringTvor.h:141
 TringTvor.h:142
 TringTvor.h:143
 TringTvor.h:144
 TringTvor.h:145
 TringTvor.h:146
 TringTvor.h:147
 TringTvor.h:148
 TringTvor.h:149
 TringTvor.h:150
 TringTvor.h:151
 TringTvor.h:152
 TringTvor.h:153
 TringTvor.h:154
 TringTvor.h:155
 TringTvor.h:156
 TringTvor.h:157
 TringTvor.h:158
 TringTvor.h:159
 TringTvor.h:160
 TringTvor.h:161
 TringTvor.h:162
 TringTvor.h:163
 TringTvor.h:164
 TringTvor.h:165
 TringTvor.h:166
 TringTvor.h:167
 TringTvor.h:168
 TringTvor.h:169
 TringTvor.h:170
 TringTvor.h:171
 TringTvor.h:172
 TringTvor.h:173
 TringTvor.h:174
 TringTvor.h:175
 TringTvor.h:176
 TringTvor.h:177
 TringTvor.h:178
 TringTvor.h:179
 TringTvor.h:180
 TringTvor.h:181
 TringTvor.h:182
 TringTvor.h:183
 TringTvor.h:184
 TringTvor.h:185
 TringTvor.h:186
 TringTvor.h:187
 TringTvor.h:188
 TringTvor.h:189
 TringTvor.h:190
 TringTvor.h:191
 TringTvor.h:192
 TringTvor.h:193
 TringTvor.h:194
 TringTvor.h:195
 TringTvor.h:196
 TringTvor.h:197
 TringTvor.h:198
 TringTvor.h:199
 TringTvor.h:200
 TringTvor.h:201
 TringTvor.h:202
 TringTvor.h:203
 TringTvor.h:204
 TringTvor.h:205
 TringTvor.h:206
 TringTvor.h:207
 TringTvor.h:208
 TringTvor.h:209
 TringTvor.h:210
 TringTvor.h:211
 TringTvor.h:212
 TringTvor.h:213
 TringTvor.h:214
 TringTvor.h:215
 TringTvor.h:216
 TringTvor.h:217
 TringTvor.h:218
 TringTvor.h:219
 TringTvor.h:220
 TringTvor.h:221
 TringTvor.h:222
 TringTvor.h:223
 TringTvor.h:224
 TringTvor.h:225
 TringTvor.h:226
 TringTvor.h:227
 TringTvor.h:228
 TringTvor.h:229
 TringTvor.h:230
 TringTvor.h:231
 TringTvor.h:232
 TringTvor.h:233
 TringTvor.h:234
 TringTvor.h:235
 TringTvor.h:236
 TringTvor.h:237
 TringTvor.h:238
 TringTvor.h:239
 TringTvor.h:240
 TringTvor.h:241
 TringTvor.h:242
 TringTvor.h:243
 TringTvor.h:244
 TringTvor.h:245
 TringTvor.h:246
 TringTvor.h:247
 TringTvor.h:248
 TringTvor.h:249
 TringTvor.h:250
 TringTvor.h:251
 TringTvor.h:252
 TringTvor.h:253
 TringTvor.h:254
 TringTvor.h:255
 TringTvor.h:256
 TringTvor.h:257
 TringTvor.h:258
 TringTvor.h:259
 TringTvor.h:260
 TringTvor.h:261
 TringTvor.h:262