ROOT logo
// $Id: TringTvor.cxx 2500 2011-07-03 02:24:50Z 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/.

//==============================================================================
// TringTvor
//==============================================================================

//______________________________________________________________________
//
// Encapsulates low-level arrays for triangle meshes.
// Vertex and Triangle arrays are mandatory (called primary by methods).
// Optional:
//   per-vertex   normals and colors |
//   per-triangle normals and colors +-> secondary arrays
//   texture coords (per-vertex)     |
//   triangle strip data
//
// Serialization should mostly work. Secondary data is streamed as
// well.  As triangle-attributes (normals, colors) are usually
// calculated from vertex-attributes, some provision might be necessary to
// streamline this. Anyway ... this should really be managed by the lens
// using the tring-tvor as it also has the AdEnlightenment() virtual where
// post-serialization / pre-usage chores can be performed.
//
// Strip-data is not saved, nor is there any indication if it was used.
//
// Jul 2011
// This should really be templated for float / double.
// Texture arrays should be moved out and make independent.
// Maybe also the normal arrays -- or at least they should be templated with a
// different type so one can use char or short.

#include "TringTvor.h"

#include <TMath.h>
#include <TRandom.h>

#include <cmath>

#define INV3                    0.33333333333333333333f

ClassImp(TringTvor);

void TringTvor::_init()
{
  mBBoxOK = false;
  mMaxVertexDistance = mBBoxHalfDiagonal = 0;
  mMinEdgeLen = mMaxEdgeLen = 0;

  mNStripEls   = 0;  mStripEls    = 0;  mStripTrings = 0;
  mNStrips     = 0;  mStripBegs   = 0;  mStripLens   = 0;
}

TringTvor::TringTvor() :
  mNVerts  (0),
  mNTrings (0),
  mNormalMode  (M_None),
  mColorMode   (M_None),
  mTextureMode (M_None)
{
  _init();
}

TringTvor::TringTvor(Int_t nv, Int_t nt) :
  mNVerts  (nv),
  mNTrings (nt),
  mNormalMode  (M_None),
  mColorMode   (M_None),
  mTextureMode (M_None)
{
  _init();
  MakePrimaryArrays();
}

TringTvor::TringTvor(Int_t nv, Int_t nt, Mode_e normal, Mode_e color, Mode_e texture) :
  mNVerts      (nv),
  mNTrings     (nt),
  mNormalMode  (normal),
  mColorMode   (color),
  mTextureMode (texture)
{
  _init();
  MakePrimaryArrays();
  MakeSecondaryArrays();
}

TringTvor::TringTvor(Int_t nv, Int_t nt, Bool_t smoothp, Bool_t colp, Bool_t texp) :
  mNVerts      (nv),
  mNTrings     (nt),
  mNormalMode  (smoothp ? M_PerVertex : M_PerTriangle),
  mColorMode   (colp ? (smoothp ? M_PerVertex : M_PerTriangle) : M_None),
  mTextureMode (texp ? M_PerVertex : M_None)
{
  _init();
  MakePrimaryArrays();
  MakeSecondaryArrays();
}

TringTvor::~TringTvor()
{
  DeleteTriangleStrips();
  DeleteSecondaryArrays();
  DeletePrimaryArrays();
}

void TringTvor::Reset(Int_t nv, Int_t nt)
{
  DeleteTriangleStrips();
  DeleteSecondaryArrays();
  DeletePrimaryArrays();
  mNVerts      = nv;
  mNTrings     = nt;
  mNormalMode  = M_None;
  mColorMode   = M_None;
  mTextureMode = M_None;
  MakePrimaryArrays();
  mBBoxOK = false;
}

void TringTvor::Reset(Int_t nv, Int_t nt, Mode_e normal, Mode_e color, Mode_e texture)
{
  DeleteTriangleStrips();
  DeleteSecondaryArrays();
  DeletePrimaryArrays();
  mNVerts      = nv;
  mNTrings     = nt;
  mNormalMode  = normal;
  mColorMode   = color;
  mTextureMode = texture;
  MakePrimaryArrays();  
  MakeSecondaryArrays();
  mBBoxOK = false;
}

/**************************************************************************/

void TringTvor::MakePrimaryArrays()
{
  mVerts .resize(3*mNVerts);
  mTrings.resize(3*mNTrings);
}

void TringTvor::DeletePrimaryArrays()
{
  WipeVerts();  mNVerts  = 0;
  WipeTrings(); mNTrings = 0;
}

void TringTvor::MakeSecondaryArrays()
{
  switch (mNormalMode)
  {
    case M_PerVertex:   AssertNorms();      break;
    case M_PerTriangle: AssertTringNorms(); break;
    default: break;
  }
  switch (mColorMode)
  {
    case M_PerVertex:   AssertCols();      break;
    case M_PerTriangle: AssertTringCols(); break;
    default: break;
  }
  switch (mTextureMode)
  {
    case M_PerVertex:   AssertTexs();      break;
    case M_PerTriangle: AssertTringTexs(); break;
    default: break;
  }
}

void TringTvor::DeleteSecondaryArrays()
{
  WipeNorms();
  WipeCols();
  WipeTexs();

  WipeTringNorms();
  WipeTringCols();
  WipeTringTexs();
}

/**************************************************************************/

Int_t TringTvor::AddVertices(Int_t nv)
{
  // Returns old number of vertices.

  Int_t nold = mNVerts;
  mNVerts += nv;
  mVerts.resize(3*mNVerts);
  if (HasNorms()) MakeNorms();
  if (HasCols())  MakeCols();
  if (HasTexs())  MakeTexs();
  mBBoxOK = false;
  return nold;
}

Int_t TringTvor::AddTriangles(Int_t nt)
{
  // Returns old number of triangles.

  Int_t nold = mNTrings;
  mNTrings += nt;
  mTrings.resize(3*mNTrings);
  if (HasTringNorms()) MakeTringNorms();
  if (HasTringCols())  MakeTringCols();
  if (HasTringTexs())  MakeTringTexs();
  mBBoxOK = false;
  return nold;
}

/**************************************************************************/

void TringTvor::CalculateBoundingBox()
{
  if (mNVerts == 0 || mNTrings == 0)
  {
    for (Int_t i = 0; i < 6; ++i)
    {
      mMinMaxBox[i] = mCtrExtBox[i] = 0;
    }
    mMaxVertexDistance = mMinEdgeLen = mMaxEdgeLen = 0;
    return;
  }

  Float_t *V = Verts(), *m = mMinMaxBox, *M = m + 3;
  m[0] = M[0] = V[0];
  m[1] = M[1] = V[1];
  m[2] = M[2] = V[2];
  mMaxVertexDistance = V[0]*V[0] + V[1]*V[1] + V[2]*V[2];
  V += 3;
  for (Int_t v = 1; v < mNVerts; ++v, V+=3)
  {
    if (V[0] < m[0]) m[0] = V[0]; else if (V[0] > M[0]) M[0] = V[0];
    if (V[1] < m[1]) m[1] = V[1]; else if (V[1] > M[1]) M[1] = V[1];
    if (V[2] < m[2]) m[2] = V[2]; else if (V[2] > M[2]) M[2] = V[2];

    Float_t vd = V[0]*V[0] + V[1]*V[1] + V[2]*V[2];
    if (vd > mMaxVertexDistance)
      mMaxVertexDistance = vd;
  }
  mMaxVertexDistance = sqrtf(mMaxVertexDistance);

  Float_t *C = mCtrExtBox, *E = C + 3;
  C[0] = 0.5f*(M[0]+m[0]); C[1] = 0.5f*(M[1]+m[1]); C[2] = 0.5f*(M[2]+m[2]);
  E[0] = 0.5f*(M[0]-m[0]); E[1] = 0.5f*(M[1]-m[1]); E[2] = 0.5f*(M[2]-m[2]);

  mBBoxHalfDiagonal = sqrtf(E[0]*E[0] + E[1]*E[1] + E[2]*E[2]);

  // Find min/max edge length.
  // Not optimal, we visit most of the edges twice.
  SqrMinMaxEdgeLen(0, mMinEdgeLen, mMaxEdgeLen);
  for (Int_t t = 1; t < mNTrings; ++t)
  {
    Float_t min, max;
    SqrMinMaxEdgeLen(t, min, max);
    if (min < mMinEdgeLen) mMinEdgeLen = min;
    if (max > mMaxEdgeLen) mMaxEdgeLen = max;
  }
  mMinEdgeLen = sqrtf(mMinEdgeLen);
  mMaxEdgeLen = sqrtf(mMaxEdgeLen);

  mBBoxOK = true;
}

Float_t TringTvor::BoundingBoxXYArea() const
{
  const Float_t *E = mCtrExtBox + 3;
  return 4.0f * E[0]*E[1];
}

Float_t TringTvor::BoundingBoxVolume() const
{
  const Float_t *E = mCtrExtBox + 3;
  return 8.0f * E[0] * E[1] * E[2];
}

/**************************************************************************/

Float_t TringTvor::CalculateTriangleNormal(Int_t ti, Float_t normal[3])
{
  // Calculates triangle normal from vertex-data and stores it into 'normal'.
  // Returns original norm of the vector.
  //
  // This is to be used when triangle normals are not stored or during
  // construction of the tvor.

  const Int_t*    T = Triangle(ti);
  const Float_t* v0 = Vertex(T[0]);
  const Float_t* v1 = Vertex(T[1]);
  const Float_t* v2 = Vertex(T[2]);
  Float_t e1[3], e2[3];
  e1[0] = v1[0]-v0[0]; e1[1] = v1[1]-v0[1]; e1[2] = v1[2]-v0[2];
  e2[0] = v2[0]-v0[0]; e2[1] = v2[1]-v0[1]; e2[2] = v2[2]-v0[2];

  return TMath::NormCross(e1, e2, normal);
}

Float_t TringTvor::CalculateTriangleNormalAndCog(Int_t ti, Float_t normal[3], Float_t cog[3])
{
  // Calculates triangle normal from vertex-data and stores it into
  // 'normal'. Returns original norm of the vector. Center-of-gravity
  // of the triangle is returned in 'cog'.
  //
  // This is to be used when triangle normals are not stored or during
  // construction of the tvor.

  const Int_t*    T = Triangle(ti);
  const Float_t* v0 = Vertex(T[0]);
  const Float_t* v1 = Vertex(T[1]);
  const Float_t* v2 = Vertex(T[2]);
  Float_t e1[3], e2[3];
  e1[0] = v1[0]-v0[0]; e1[1] = v1[1]-v0[1]; e1[2] = v1[2]-v0[2];
  e2[0] = v2[0]-v0[0]; e2[1] = v2[1]-v0[1]; e2[2] = v2[2]-v0[2];

  cog[0] = (v0[0] + v1[0] + v2[0]) * INV3;
  cog[1] = (v0[1] + v1[1] + v2[1]) * INV3;
  cog[2] = (v0[2] + v1[2] + v2[2]) * INV3;

  return TMath::NormCross(e1, e2, normal);
}

void TringTvor::GenerateTriangleNormals()
{
  AssertTringNorms();

  for(Int_t t=0; t<mNTrings; ++t) 
  {
    CalculateTriangleNormal(t, TriangleNormal(t));
  }
}

void TringTvor::GenerateTriangleNormalsAndColors
  (void (*foo)(Float_t*, UChar_t*, void*), void* ud)
{
  AssertTringNorms();
  AssertTringCols();

  Float_t  cog[3];

  for(Int_t t=0; t<mNTrings; ++t)
  {
    CalculateTriangleNormalAndCog(t, TriangleNormal(t), cog);
    foo(cog, TriangleColor(t), ud);
  }
}

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

void TringTvor::GenerateTriangleColorsFromVertexColors()
{
  AssertTringCols();
  GenerateTriangleColorsFromVertexColors(Cols(), TringCols());
}

void TringTvor::GenerateTriangleColorsFromVertexColors(UChar_t* VCA, UChar_t* TCA)
{
  Int_t   *T = Trings();
  UChar_t *C = TCA;
  for (Int_t t=0; t<mNTrings; ++t, T+=3, C+=4)
  {
    UChar_t *c0 = &VCA[4*T[0]];
    UChar_t *c1 = &VCA[4*T[1]];
    UChar_t *c2 = &VCA[4*T[2]];
    C[0] = (UChar_t) (((UInt_t) c0[0] + c1[0] + c2[0]) * INV3);
    C[1] = (UChar_t) (((UInt_t) c0[1] + c1[1] + c2[1]) * INV3);
    C[2] = (UChar_t) (((UInt_t) c0[2] + c1[2] + c2[2]) * INV3);
    C[3] = (UChar_t) (((UInt_t) c0[3] + c1[3] + c2[3]) * INV3);
  }
}

void TringTvor::GenerateTriangleColorsFromVertexColors(set<Int_t>& triangles)
{
  AssertTringCols();
  GenerateTriangleColorsFromVertexColors(triangles, Cols(), TringCols());
}

void TringTvor::GenerateTriangleColorsFromVertexColors(set<Int_t>& triangles, UChar_t* VCA, UChar_t* TCA)
{
  for (set<Int_t>::iterator t = triangles.begin(); t != triangles.end(); ++t)
  {
    Int_t   *T  = Triangle(*t);
    UChar_t *C  = &TCA[4*(*t)];
    UChar_t *c0 = &VCA[4*T[0]];
    UChar_t *c1 = &VCA[4*T[1]];
    UChar_t *c2 = &VCA[4*T[2]];
    C[0] = (UChar_t) (((UInt_t) c0[0] + c1[0] + c2[0]) * INV3);
    C[1] = (UChar_t) (((UInt_t) c0[1] + c1[1] + c2[1]) * INV3);
    C[2] = (UChar_t) (((UInt_t) c0[2] + c1[2] + c2[2]) * INV3);
    C[3] = (UChar_t) (((UInt_t) c0[3] + c1[3] + c2[3]) * INV3);
  }
}

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

void TringTvor::GenerateTriangleColorsFromTriangleStrips()
{
  // Assign random colors to different triangle strips.

  if (!HasTrianlgeStrips())
    return;
  AssertTringCols();

  TRandom rnd(0);

  for (Int_t i = 0; i < mNStrips; ++i)
  {
    UChar_t r = (UChar_t) rnd.Integer(256);
    UChar_t g = (UChar_t) rnd.Integer(256);
    UChar_t b = (UChar_t) rnd.Integer(256);

    Int_t* tring_idxp = mStripTrings + (mStripBegs[i] - mStripEls) + 2;
    Int_t  n          = mStripLens[i] - 2;
    while (n-- > 0)
    {
      UChar_t* tc = TriangleColor(*tring_idxp);
      tc[0] = r; tc[1] = g; tc[2] = b;
      ++tring_idxp;
    }
  }
}

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

void TringTvor::GenerateVertexNormals()
{
  // Generate per-vertex normals by averaging over normals of all triangles
  // sharing the vertex.
  // Requires building of intermediate structure.
  //
  // ??? Need an argument: weight normal contribution by triangle area
  // ??? or ... perhaps better ... by vertex angle.
  //     This is somewhat done in vertex-connection stuff in Var1::TriMesh.

  // Could reuse tring-normals if they do exist.

  vector<Int_t> *trings_per_vert = new vector<Int_t> [mNVerts];
  FindTrianglesPerVertex(trings_per_vert);

  AssertNorms();

  Float_t *v0, *v1, *v2;
  Int_t   *t;
  Float_t e1[3], e2[3], n[3];
  Float_t* N = &mNorms[0];
  for (Int_t i=0; i<mNVerts; ++i, N+=3) {
    vector<Int_t>& v = trings_per_vert[i];
    Int_t       size = (Int_t) v.size();
    //printf("V=%3d : Nt = %2d : ", i, size);
    N[0] = N[1] = N[2] = 0;
    for (Int_t j=0; j<size; ++j) {
      //printf("%3d ", v[j]);
      t  = Triangle(v[j]);
      v0 = Vertex(t[0]); v1 = Vertex(t[1]); v2 = Vertex(t[2]);
      e1[0] = v1[0] - v0[0]; e1[1] = v1[1] - v0[1]; e1[2] = v1[2] - v0[2];
      e2[0] = v2[0] - v0[0]; e2[1] = v2[1] - v0[1]; e2[2] = v2[2] - v0[2];
      TMath::NormCross(e1, e2, n);
      N[0] += n[0]; N[1] += n[1]; N[2] += n[2];
    }
    TMath::Normalize(N);
    //printf(" : %f %f %f\n", N[0], N[1], N[2]);
  }

  delete [] trings_per_vert;
}

/**************************************************************************/
// Intermediate structures
/**************************************************************************/

void TringTvor::FindTrianglesPerVertex(vector<Int_t>* trings_per_vert)
{
  // Populate array of vectors 'trings_per_vert' from triangle data.
  // The output array must be properly allocated in advance.

  Int_t* T = Trings();
  for (Int_t t=0; t<mNTrings; ++t, T+=3)
  {
    trings_per_vert[T[0]].push_back(t);
    trings_per_vert[T[1]].push_back(t);
    trings_per_vert[T[2]].push_back(t);
  }
}

Int_t TringTvor::FindNeighboursPerVertex(vector<Int_t>* neighbours)
{
  // Populate array of vectors 'neighbours' from triangle data.
  // The output array must be properly allocated in advance.
  // Returns total number of connections (which is 2*N_edge for closed
  // surfaces).

  const Int_t vP[3][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 } };

  Int_t  nc = 0;
  Int_t* T  = Trings();
  for (Int_t t=0; t<mNTrings; ++t, T+=3)
  {
    for (Int_t eti=0; eti<3; ++eti)
    {
      const  Int_t   v0 = T[vP[eti][0]],   v1 = T[vP[eti][1]];
      vector<Int_t> &n0 = neighbours[v0], &n1 = neighbours[v1];

      if (find(n0.begin(), n0.end(), v1) == n0.end())
      { n0.push_back(v1); ++nc; }
      if (find(n1.begin(), n1.end(), v0) == n1.end())
      { n1.push_back(v0); ++nc; }
    }
  }
  return nc;
}


/**************************************************************************/
// Triangle strips
/**************************************************************************/

#include <ACTC/tc.h>

namespace {
  struct xx_tring {
    Int_t v1,v2,v3;
    xx_tring(Int_t _v1, Int_t _v2, Int_t _v3) : v1(_v1), v2(_v2), v3(_v3) {}

    bool operator==(const xx_tring& x) const
    // { return v1==x.v1 && v2==x.v2 && v3==x.v3;}
    { return
	(v1==x.v1 || v1==x.v2 || v1==x.v3) &&
	(v2==x.v1 || v2==x.v2 || v2==x.v3) &&
	(v3==x.v1 || v3==x.v2 || v3==x.v3);}
  };
}
namespace __gnu_cxx {
  template<>
  struct hash<xx_tring> {
    size_t operator()(const xx_tring& xx) const
    { size_t i = xx.v1 * xx.v2 * xx.v3; return i; }
  };
}

void TringTvor::GenerateTriangleStrips(Int_t max_verts)
{
  static const Exc_t _eh("TringTvor::GenerateTriangleStrips ");

  hash_map<xx_tring, Int_t> tring_map;

  ACTCData *tc = actcNew();
  if (tc == 0) throw(_eh + "failed to allocate TC structure.");
  // actcParami(tc, ACTC_OUT_MIN_FAN_VERTS, is maxint);
  // actcParami(tc, ACTC_OUT_MAX_PRIM_VERTS, 128);
  actcParami(tc, ACTC_OUT_MAX_PRIM_VERTS, max_verts);
  actcParami(tc, ACTC_OUT_HONOR_WINDING, 1);
  actcBeginInput(tc);
  for(Int_t t=0; t<mNTrings; ++t)
  {
    Int_t* T = Triangle(t);
    tring_map[ xx_tring(T[0], T[1], T[2]) ] = t;
    actcAddTriangle(tc, T[0], T[1], T[2]);
  }
  actcEndInput(tc);

  actcBeginOutput(tc);
  int prim;
  int v1, v2, v3;
  int cnt = 0, cntp;
  list<vector<int>* > strip_list;
  while ((prim = actcStartNextPrim(tc, &v1, &v2)) != ACTC_DATABASE_EMPTY)
  {
    cntp = 2;
    vector<int>* vecp = new vector<int>;
    vecp->push_back(v1); vecp->push_back(v2);
    while (actcGetNextVert(tc, &v3) != ACTC_PRIM_COMPLETE)
    {
      vecp->push_back(v3);
      ++cntp;
    }
    strip_list.push_back(vecp);
    cnt += cntp;
  }
  actcEndOutput(tc);

  actcDelete(tc);

  if (mNStripEls || mNStrips) DeleteTriangleStrips();

  mNStripEls = cnt;
  mNStrips   = strip_list.size();

  mStripEls    = new Int_t [mNStripEls];
  mStripTrings = new Int_t [mNStripEls];
  mStripBegs   = new Int_t*[mNStrips];
  mStripLens   = new Int_t [mNStrips];

  Int_t       idx = 0;
  Int_t strip_idx = 0;
  while (!strip_list.empty())
  {
    vector<int>* vecp = strip_list.front();
    Int_t s_len = vecp->size();
    mStripBegs[strip_idx] = &(mStripEls[idx]);
    mStripLens[strip_idx] = s_len;

    for (Int_t i=0; i<s_len; ++i, ++idx)
    {
      mStripEls[idx] = (*vecp)[i];

      if (i > 1) {
	xx_tring xx(mStripEls[idx-2], mStripEls[idx-1], mStripEls[idx]);
	hash_map<xx_tring, Int_t>::iterator xi;
	xi = tring_map.find(xx);
	if (xi != tring_map.end()) {
	  mStripTrings[idx] = xi->second;
	} else {
	  printf("%sSafr: %zu %d.\n", _eh.Data(), strip_list.size(), i);
	}
      }

    }

    strip_list.pop_front();
    delete vecp;
    ++strip_idx;
  }
}

void TringTvor::DeleteTriangleStrips()
{
  mNStripEls = 0;
  delete [] mStripEls;    mStripEls  = 0;
  delete [] mStripTrings; mStripTrings = 0;
  mNStrips = 0;
  delete [] mStripBegs;   mStripBegs = 0;
  delete [] mStripLens;   mStripLens = 0;
}

/**************************************************************************/
// Export
/**************************************************************************/

namespace {
template<typename T> void dump3vec(ostream& o, T v) {
  o << "< " << v[0] << ", " << v[1] << ", " << v[2] << " >, \n";
}
}

void TringTvor::ExportPovMesh(ostream& o, Bool_t smoothp)
{
  // Exports triangle-data as POV mesh2 object.
  // By experimentation I would say that smooth triangles do not work properly
  // in pov-3.6.1 (15.10.2006).

  o << "mesh2 {\n";

  {
    o << "  vertex_vectors { " << mNVerts << ",\n";
    Float_t* V = Verts();
    for (Int_t i=0; i<mNVerts; ++i, V+=3) {
      o << "    "; dump3vec<Float_t*>(o, V);
    }
    o << "  }\n";
  }

  if (smoothp) {
    Bool_t no_normals = ! HasNorms();
    if (no_normals) GenerateVertexNormals();
    o << "  normal_vectors { " << mNVerts << ",\n";
    Float_t* N = Norms();
    for (Int_t i=0; i<mNVerts; ++i, N+=3) {
      o << "    "; dump3vec<Float_t*>(o, N);
    }
    o << "  }\n";
    if (no_normals) { WipeNorms(); }
  }

  {
    o << "  face_indices { " << mNTrings << ",\n";
    Int_t* T = Trings();
    for (Int_t i=0; i<mNTrings; ++i, T+=3) {
      o << "    "; dump3vec<Int_t*>(o, T);
    }
    o << "  }\n";
  }

  o << "}\n";
}
 TringTvor.cxx:1
 TringTvor.cxx:2
 TringTvor.cxx:3
 TringTvor.cxx:4
 TringTvor.cxx:5
 TringTvor.cxx:6
 TringTvor.cxx:7
 TringTvor.cxx:8
 TringTvor.cxx:9
 TringTvor.cxx:10
 TringTvor.cxx:11
 TringTvor.cxx:12
 TringTvor.cxx:13
 TringTvor.cxx:14
 TringTvor.cxx:15
 TringTvor.cxx:16
 TringTvor.cxx:17
 TringTvor.cxx:18
 TringTvor.cxx:19
 TringTvor.cxx:20
 TringTvor.cxx:21
 TringTvor.cxx:22
 TringTvor.cxx:23
 TringTvor.cxx:24
 TringTvor.cxx:25
 TringTvor.cxx:26
 TringTvor.cxx:27
 TringTvor.cxx:28
 TringTvor.cxx:29
 TringTvor.cxx:30
 TringTvor.cxx:31
 TringTvor.cxx:32
 TringTvor.cxx:33
 TringTvor.cxx:34
 TringTvor.cxx:35
 TringTvor.cxx:36
 TringTvor.cxx:37
 TringTvor.cxx:38
 TringTvor.cxx:39
 TringTvor.cxx:40
 TringTvor.cxx:41
 TringTvor.cxx:42
 TringTvor.cxx:43
 TringTvor.cxx:44
 TringTvor.cxx:45
 TringTvor.cxx:46
 TringTvor.cxx:47
 TringTvor.cxx:48
 TringTvor.cxx:49
 TringTvor.cxx:50
 TringTvor.cxx:51
 TringTvor.cxx:52
 TringTvor.cxx:53
 TringTvor.cxx:54
 TringTvor.cxx:55
 TringTvor.cxx:56
 TringTvor.cxx:57
 TringTvor.cxx:58
 TringTvor.cxx:59
 TringTvor.cxx:60
 TringTvor.cxx:61
 TringTvor.cxx:62
 TringTvor.cxx:63
 TringTvor.cxx:64
 TringTvor.cxx:65
 TringTvor.cxx:66
 TringTvor.cxx:67
 TringTvor.cxx:68
 TringTvor.cxx:69
 TringTvor.cxx:70
 TringTvor.cxx:71
 TringTvor.cxx:72
 TringTvor.cxx:73
 TringTvor.cxx:74
 TringTvor.cxx:75
 TringTvor.cxx:76
 TringTvor.cxx:77
 TringTvor.cxx:78
 TringTvor.cxx:79
 TringTvor.cxx:80
 TringTvor.cxx:81
 TringTvor.cxx:82
 TringTvor.cxx:83
 TringTvor.cxx:84
 TringTvor.cxx:85
 TringTvor.cxx:86
 TringTvor.cxx:87
 TringTvor.cxx:88
 TringTvor.cxx:89
 TringTvor.cxx:90
 TringTvor.cxx:91
 TringTvor.cxx:92
 TringTvor.cxx:93
 TringTvor.cxx:94
 TringTvor.cxx:95
 TringTvor.cxx:96
 TringTvor.cxx:97
 TringTvor.cxx:98
 TringTvor.cxx:99
 TringTvor.cxx:100
 TringTvor.cxx:101
 TringTvor.cxx:102
 TringTvor.cxx:103
 TringTvor.cxx:104
 TringTvor.cxx:105
 TringTvor.cxx:106
 TringTvor.cxx:107
 TringTvor.cxx:108
 TringTvor.cxx:109
 TringTvor.cxx:110
 TringTvor.cxx:111
 TringTvor.cxx:112
 TringTvor.cxx:113
 TringTvor.cxx:114
 TringTvor.cxx:115
 TringTvor.cxx:116
 TringTvor.cxx:117
 TringTvor.cxx:118
 TringTvor.cxx:119
 TringTvor.cxx:120
 TringTvor.cxx:121
 TringTvor.cxx:122
 TringTvor.cxx:123
 TringTvor.cxx:124
 TringTvor.cxx:125
 TringTvor.cxx:126
 TringTvor.cxx:127
 TringTvor.cxx:128
 TringTvor.cxx:129
 TringTvor.cxx:130
 TringTvor.cxx:131
 TringTvor.cxx:132
 TringTvor.cxx:133
 TringTvor.cxx:134
 TringTvor.cxx:135
 TringTvor.cxx:136
 TringTvor.cxx:137
 TringTvor.cxx:138
 TringTvor.cxx:139
 TringTvor.cxx:140
 TringTvor.cxx:141
 TringTvor.cxx:142
 TringTvor.cxx:143
 TringTvor.cxx:144
 TringTvor.cxx:145
 TringTvor.cxx:146
 TringTvor.cxx:147
 TringTvor.cxx:148
 TringTvor.cxx:149
 TringTvor.cxx:150
 TringTvor.cxx:151
 TringTvor.cxx:152
 TringTvor.cxx:153
 TringTvor.cxx:154
 TringTvor.cxx:155
 TringTvor.cxx:156
 TringTvor.cxx:157
 TringTvor.cxx:158
 TringTvor.cxx:159
 TringTvor.cxx:160
 TringTvor.cxx:161
 TringTvor.cxx:162
 TringTvor.cxx:163
 TringTvor.cxx:164
 TringTvor.cxx:165
 TringTvor.cxx:166
 TringTvor.cxx:167
 TringTvor.cxx:168
 TringTvor.cxx:169
 TringTvor.cxx:170
 TringTvor.cxx:171
 TringTvor.cxx:172
 TringTvor.cxx:173
 TringTvor.cxx:174
 TringTvor.cxx:175
 TringTvor.cxx:176
 TringTvor.cxx:177
 TringTvor.cxx:178
 TringTvor.cxx:179
 TringTvor.cxx:180
 TringTvor.cxx:181
 TringTvor.cxx:182
 TringTvor.cxx:183
 TringTvor.cxx:184
 TringTvor.cxx:185
 TringTvor.cxx:186
 TringTvor.cxx:187
 TringTvor.cxx:188
 TringTvor.cxx:189
 TringTvor.cxx:190
 TringTvor.cxx:191
 TringTvor.cxx:192
 TringTvor.cxx:193
 TringTvor.cxx:194
 TringTvor.cxx:195
 TringTvor.cxx:196
 TringTvor.cxx:197
 TringTvor.cxx:198
 TringTvor.cxx:199
 TringTvor.cxx:200
 TringTvor.cxx:201
 TringTvor.cxx:202
 TringTvor.cxx:203
 TringTvor.cxx:204
 TringTvor.cxx:205
 TringTvor.cxx:206
 TringTvor.cxx:207
 TringTvor.cxx:208
 TringTvor.cxx:209
 TringTvor.cxx:210
 TringTvor.cxx:211
 TringTvor.cxx:212
 TringTvor.cxx:213
 TringTvor.cxx:214
 TringTvor.cxx:215
 TringTvor.cxx:216
 TringTvor.cxx:217
 TringTvor.cxx:218
 TringTvor.cxx:219
 TringTvor.cxx:220
 TringTvor.cxx:221
 TringTvor.cxx:222
 TringTvor.cxx:223
 TringTvor.cxx:224
 TringTvor.cxx:225
 TringTvor.cxx:226
 TringTvor.cxx:227
 TringTvor.cxx:228
 TringTvor.cxx:229
 TringTvor.cxx:230
 TringTvor.cxx:231
 TringTvor.cxx:232
 TringTvor.cxx:233
 TringTvor.cxx:234
 TringTvor.cxx:235
 TringTvor.cxx:236
 TringTvor.cxx:237
 TringTvor.cxx:238
 TringTvor.cxx:239
 TringTvor.cxx:240
 TringTvor.cxx:241
 TringTvor.cxx:242
 TringTvor.cxx:243
 TringTvor.cxx:244
 TringTvor.cxx:245
 TringTvor.cxx:246
 TringTvor.cxx:247
 TringTvor.cxx:248
 TringTvor.cxx:249
 TringTvor.cxx:250
 TringTvor.cxx:251
 TringTvor.cxx:252
 TringTvor.cxx:253
 TringTvor.cxx:254
 TringTvor.cxx:255
 TringTvor.cxx:256
 TringTvor.cxx:257
 TringTvor.cxx:258
 TringTvor.cxx:259
 TringTvor.cxx:260
 TringTvor.cxx:261
 TringTvor.cxx:262
 TringTvor.cxx:263
 TringTvor.cxx:264
 TringTvor.cxx:265
 TringTvor.cxx:266
 TringTvor.cxx:267
 TringTvor.cxx:268
 TringTvor.cxx:269
 TringTvor.cxx:270
 TringTvor.cxx:271
 TringTvor.cxx:272
 TringTvor.cxx:273
 TringTvor.cxx:274
 TringTvor.cxx:275
 TringTvor.cxx:276
 TringTvor.cxx:277
 TringTvor.cxx:278
 TringTvor.cxx:279
 TringTvor.cxx:280
 TringTvor.cxx:281
 TringTvor.cxx:282
 TringTvor.cxx:283
 TringTvor.cxx:284
 TringTvor.cxx:285
 TringTvor.cxx:286
 TringTvor.cxx:287
 TringTvor.cxx:288
 TringTvor.cxx:289
 TringTvor.cxx:290
 TringTvor.cxx:291
 TringTvor.cxx:292
 TringTvor.cxx:293
 TringTvor.cxx:294
 TringTvor.cxx:295
 TringTvor.cxx:296
 TringTvor.cxx:297
 TringTvor.cxx:298
 TringTvor.cxx:299
 TringTvor.cxx:300
 TringTvor.cxx:301
 TringTvor.cxx:302
 TringTvor.cxx:303
 TringTvor.cxx:304
 TringTvor.cxx:305
 TringTvor.cxx:306
 TringTvor.cxx:307
 TringTvor.cxx:308
 TringTvor.cxx:309
 TringTvor.cxx:310
 TringTvor.cxx:311
 TringTvor.cxx:312
 TringTvor.cxx:313
 TringTvor.cxx:314
 TringTvor.cxx:315
 TringTvor.cxx:316
 TringTvor.cxx:317
 TringTvor.cxx:318
 TringTvor.cxx:319
 TringTvor.cxx:320
 TringTvor.cxx:321
 TringTvor.cxx:322
 TringTvor.cxx:323
 TringTvor.cxx:324
 TringTvor.cxx:325
 TringTvor.cxx:326
 TringTvor.cxx:327
 TringTvor.cxx:328
 TringTvor.cxx:329
 TringTvor.cxx:330
 TringTvor.cxx:331
 TringTvor.cxx:332
 TringTvor.cxx:333
 TringTvor.cxx:334
 TringTvor.cxx:335
 TringTvor.cxx:336
 TringTvor.cxx:337
 TringTvor.cxx:338
 TringTvor.cxx:339
 TringTvor.cxx:340
 TringTvor.cxx:341
 TringTvor.cxx:342
 TringTvor.cxx:343
 TringTvor.cxx:344
 TringTvor.cxx:345
 TringTvor.cxx:346
 TringTvor.cxx:347
 TringTvor.cxx:348
 TringTvor.cxx:349
 TringTvor.cxx:350
 TringTvor.cxx:351
 TringTvor.cxx:352
 TringTvor.cxx:353
 TringTvor.cxx:354
 TringTvor.cxx:355
 TringTvor.cxx:356
 TringTvor.cxx:357
 TringTvor.cxx:358
 TringTvor.cxx:359
 TringTvor.cxx:360
 TringTvor.cxx:361
 TringTvor.cxx:362
 TringTvor.cxx:363
 TringTvor.cxx:364
 TringTvor.cxx:365
 TringTvor.cxx:366
 TringTvor.cxx:367
 TringTvor.cxx:368
 TringTvor.cxx:369
 TringTvor.cxx:370
 TringTvor.cxx:371
 TringTvor.cxx:372
 TringTvor.cxx:373
 TringTvor.cxx:374
 TringTvor.cxx:375
 TringTvor.cxx:376
 TringTvor.cxx:377
 TringTvor.cxx:378
 TringTvor.cxx:379
 TringTvor.cxx:380
 TringTvor.cxx:381
 TringTvor.cxx:382
 TringTvor.cxx:383
 TringTvor.cxx:384
 TringTvor.cxx:385
 TringTvor.cxx:386
 TringTvor.cxx:387
 TringTvor.cxx:388
 TringTvor.cxx:389
 TringTvor.cxx:390
 TringTvor.cxx:391
 TringTvor.cxx:392
 TringTvor.cxx:393
 TringTvor.cxx:394
 TringTvor.cxx:395
 TringTvor.cxx:396
 TringTvor.cxx:397
 TringTvor.cxx:398
 TringTvor.cxx:399
 TringTvor.cxx:400
 TringTvor.cxx:401
 TringTvor.cxx:402
 TringTvor.cxx:403
 TringTvor.cxx:404
 TringTvor.cxx:405
 TringTvor.cxx:406
 TringTvor.cxx:407
 TringTvor.cxx:408
 TringTvor.cxx:409
 TringTvor.cxx:410
 TringTvor.cxx:411
 TringTvor.cxx:412
 TringTvor.cxx:413
 TringTvor.cxx:414
 TringTvor.cxx:415
 TringTvor.cxx:416
 TringTvor.cxx:417
 TringTvor.cxx:418
 TringTvor.cxx:419
 TringTvor.cxx:420
 TringTvor.cxx:421
 TringTvor.cxx:422
 TringTvor.cxx:423
 TringTvor.cxx:424
 TringTvor.cxx:425
 TringTvor.cxx:426
 TringTvor.cxx:427
 TringTvor.cxx:428
 TringTvor.cxx:429
 TringTvor.cxx:430
 TringTvor.cxx:431
 TringTvor.cxx:432
 TringTvor.cxx:433
 TringTvor.cxx:434
 TringTvor.cxx:435
 TringTvor.cxx:436
 TringTvor.cxx:437
 TringTvor.cxx:438
 TringTvor.cxx:439
 TringTvor.cxx:440
 TringTvor.cxx:441
 TringTvor.cxx:442
 TringTvor.cxx:443
 TringTvor.cxx:444
 TringTvor.cxx:445
 TringTvor.cxx:446
 TringTvor.cxx:447
 TringTvor.cxx:448
 TringTvor.cxx:449
 TringTvor.cxx:450
 TringTvor.cxx:451
 TringTvor.cxx:452
 TringTvor.cxx:453
 TringTvor.cxx:454
 TringTvor.cxx:455
 TringTvor.cxx:456
 TringTvor.cxx:457
 TringTvor.cxx:458
 TringTvor.cxx:459
 TringTvor.cxx:460
 TringTvor.cxx:461
 TringTvor.cxx:462
 TringTvor.cxx:463
 TringTvor.cxx:464
 TringTvor.cxx:465
 TringTvor.cxx:466
 TringTvor.cxx:467
 TringTvor.cxx:468
 TringTvor.cxx:469
 TringTvor.cxx:470
 TringTvor.cxx:471
 TringTvor.cxx:472
 TringTvor.cxx:473
 TringTvor.cxx:474
 TringTvor.cxx:475
 TringTvor.cxx:476
 TringTvor.cxx:477
 TringTvor.cxx:478
 TringTvor.cxx:479
 TringTvor.cxx:480
 TringTvor.cxx:481
 TringTvor.cxx:482
 TringTvor.cxx:483
 TringTvor.cxx:484
 TringTvor.cxx:485
 TringTvor.cxx:486
 TringTvor.cxx:487
 TringTvor.cxx:488
 TringTvor.cxx:489
 TringTvor.cxx:490
 TringTvor.cxx:491
 TringTvor.cxx:492
 TringTvor.cxx:493
 TringTvor.cxx:494
 TringTvor.cxx:495
 TringTvor.cxx:496
 TringTvor.cxx:497
 TringTvor.cxx:498
 TringTvor.cxx:499
 TringTvor.cxx:500
 TringTvor.cxx:501
 TringTvor.cxx:502
 TringTvor.cxx:503
 TringTvor.cxx:504
 TringTvor.cxx:505
 TringTvor.cxx:506
 TringTvor.cxx:507
 TringTvor.cxx:508
 TringTvor.cxx:509
 TringTvor.cxx:510
 TringTvor.cxx:511
 TringTvor.cxx:512
 TringTvor.cxx:513
 TringTvor.cxx:514
 TringTvor.cxx:515
 TringTvor.cxx:516
 TringTvor.cxx:517
 TringTvor.cxx:518
 TringTvor.cxx:519
 TringTvor.cxx:520
 TringTvor.cxx:521
 TringTvor.cxx:522
 TringTvor.cxx:523
 TringTvor.cxx:524
 TringTvor.cxx:525
 TringTvor.cxx:526
 TringTvor.cxx:527
 TringTvor.cxx:528
 TringTvor.cxx:529
 TringTvor.cxx:530
 TringTvor.cxx:531
 TringTvor.cxx:532
 TringTvor.cxx:533
 TringTvor.cxx:534
 TringTvor.cxx:535
 TringTvor.cxx:536
 TringTvor.cxx:537
 TringTvor.cxx:538
 TringTvor.cxx:539
 TringTvor.cxx:540
 TringTvor.cxx:541
 TringTvor.cxx:542
 TringTvor.cxx:543
 TringTvor.cxx:544
 TringTvor.cxx:545
 TringTvor.cxx:546
 TringTvor.cxx:547
 TringTvor.cxx:548
 TringTvor.cxx:549
 TringTvor.cxx:550
 TringTvor.cxx:551
 TringTvor.cxx:552
 TringTvor.cxx:553
 TringTvor.cxx:554
 TringTvor.cxx:555
 TringTvor.cxx:556
 TringTvor.cxx:557
 TringTvor.cxx:558
 TringTvor.cxx:559
 TringTvor.cxx:560
 TringTvor.cxx:561
 TringTvor.cxx:562
 TringTvor.cxx:563
 TringTvor.cxx:564
 TringTvor.cxx:565
 TringTvor.cxx:566
 TringTvor.cxx:567
 TringTvor.cxx:568
 TringTvor.cxx:569
 TringTvor.cxx:570
 TringTvor.cxx:571
 TringTvor.cxx:572
 TringTvor.cxx:573
 TringTvor.cxx:574
 TringTvor.cxx:575
 TringTvor.cxx:576
 TringTvor.cxx:577
 TringTvor.cxx:578
 TringTvor.cxx:579
 TringTvor.cxx:580
 TringTvor.cxx:581
 TringTvor.cxx:582
 TringTvor.cxx:583
 TringTvor.cxx:584
 TringTvor.cxx:585
 TringTvor.cxx:586
 TringTvor.cxx:587
 TringTvor.cxx:588
 TringTvor.cxx:589
 TringTvor.cxx:590
 TringTvor.cxx:591
 TringTvor.cxx:592
 TringTvor.cxx:593
 TringTvor.cxx:594
 TringTvor.cxx:595
 TringTvor.cxx:596
 TringTvor.cxx:597
 TringTvor.cxx:598
 TringTvor.cxx:599
 TringTvor.cxx:600
 TringTvor.cxx:601
 TringTvor.cxx:602
 TringTvor.cxx:603
 TringTvor.cxx:604
 TringTvor.cxx:605
 TringTvor.cxx:606
 TringTvor.cxx:607
 TringTvor.cxx:608
 TringTvor.cxx:609
 TringTvor.cxx:610
 TringTvor.cxx:611
 TringTvor.cxx:612
 TringTvor.cxx:613
 TringTvor.cxx:614
 TringTvor.cxx:615
 TringTvor.cxx:616
 TringTvor.cxx:617
 TringTvor.cxx:618
 TringTvor.cxx:619
 TringTvor.cxx:620
 TringTvor.cxx:621
 TringTvor.cxx:622
 TringTvor.cxx:623
 TringTvor.cxx:624
 TringTvor.cxx:625
 TringTvor.cxx:626
 TringTvor.cxx:627
 TringTvor.cxx:628
 TringTvor.cxx:629
 TringTvor.cxx:630
 TringTvor.cxx:631
 TringTvor.cxx:632
 TringTvor.cxx:633
 TringTvor.cxx:634
 TringTvor.cxx:635
 TringTvor.cxx:636
 TringTvor.cxx:637
 TringTvor.cxx:638
 TringTvor.cxx:639
 TringTvor.cxx:640
 TringTvor.cxx:641
 TringTvor.cxx:642
 TringTvor.cxx:643
 TringTvor.cxx:644
 TringTvor.cxx:645
 TringTvor.cxx:646
 TringTvor.cxx:647
 TringTvor.cxx:648
 TringTvor.cxx:649
 TringTvor.cxx:650
 TringTvor.cxx:651
 TringTvor.cxx:652
 TringTvor.cxx:653
 TringTvor.cxx:654
 TringTvor.cxx:655
 TringTvor.cxx:656
 TringTvor.cxx:657
 TringTvor.cxx:658
 TringTvor.cxx:659
 TringTvor.cxx:660
 TringTvor.cxx:661
 TringTvor.cxx:662
 TringTvor.cxx:663
 TringTvor.cxx:664
 TringTvor.cxx:665
 TringTvor.cxx:666
 TringTvor.cxx:667
 TringTvor.cxx:668
 TringTvor.cxx:669
 TringTvor.cxx:670
 TringTvor.cxx:671
 TringTvor.cxx:672
 TringTvor.cxx:673
 TringTvor.cxx:674
 TringTvor.cxx:675
 TringTvor.cxx:676
 TringTvor.cxx:677
 TringTvor.cxx:678
 TringTvor.cxx:679
 TringTvor.cxx:680
 TringTvor.cxx:681
 TringTvor.cxx:682
 TringTvor.cxx:683
 TringTvor.cxx:684
 TringTvor.cxx:685
 TringTvor.cxx:686
 TringTvor.cxx:687