ROOT logo
// $Id: TriMesh.h 2548 2011-10-10 07:03:57Z 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 Var1_TriMesh_H
#define Var1_TriMesh_H

#include <Glasses/ZGlass.h>
#include <Stones/TringTvor.h>
#include <Stones/HTrans.h>

class ParaSurf;

class ZImage;
class RGBAPalette;
class RectTerrain;
class GTSurf;

namespace Opcode
{
  class Model;
  class MeshInterface;
  class AABB;
  class Point;
}

class TriMeshColorArraySource
{
public:
  TriMeshColorArraySource() {}
  virtual ~TriMeshColorArraySource() {}

  virtual void     AssertVertexColorArray() = 0;
  virtual UChar_t* GetVertexColorArray()    = 0;
  virtual UChar_t* GetTriangleColorArray()  = 0;
  virtual void     ColorArraysModified()    = 0;

  static TriMeshColorArraySource* CastLens(const Exc_t& eh, ZGlass* lens, Bool_t null_ok);

  ClassDef(TriMeshColorArraySource, 0); // Abstract interface - provide color arrays for TriMesh vertices and triangles.
};


class TriMesh : public ZGlass,
		public TriMeshColorArraySource
{
  MAC_RNR_FRIENDS(TriMesh);

public:
  struct Edge
  {
    Int_t v1, v2;
    Edge(Int_t a, Int_t b) { if (a<b) v1=a, v2=b; else v1=b, v2=a; }

    // Symmetric operator== declared outside of TriMesh.

    struct hash
    {
      size_t operator()(const Edge& xx) const
      { size_t i = (xx.v1 << 16) + xx.v2; return i; }
    };
  };

#ifndef __CINT__
  typedef hash_map<Edge, Int_t, Edge::hash> hEdge_t;
  typedef hEdge_t::iterator                 hEdge_i;

         Int_t fill_edge_map(hEdge_t& edge_map, Int_t label);
  static Int_t fill_edge_map(Int_t n_triangles, Int_t* triangles, hEdge_t& edge_map, Int_t label);
#endif

  struct EdgeData
  {
    // Topology, depends on connectivity only
    Int_t   fV1, fV2;      // Vertex idcs
    Int_t   fT1, fT2;      // Triangle idcs on the left/right of v1->v2 (-1 for no tring)

    // Metrics & morphology, depends on vertex positions and parasurf
    Float_t fDistance;     // Distance between vertices
    Float_t fDh;           // Difference of height h(v2) - h(v1)
    Float_t fAngle;        // Angle in local f/g coords
    Float_t fSurface;      // Sum of 1/3 of triangle surfaces
    Float_t fSpr1, fSpr2;  // Spreads for vertices

    EdgeData();

    Bool_t has_second_triangle() const { return fT2 != -1; }

    Int_t other_vertex(Int_t v)   const { return v == fV1 ? fV2 : fV1; }
    Int_t left_triangle(Int_t v)  const { return v == fV1 ? fT1 : fT2; }
    Int_t right_triangle(Int_t v) const { return v == fV1 ? fT2 : fT1; }

    Float_t distance()      const { return fDistance; }
    Float_t dh(Int_t v)     const { return v == fV1 ? fDh : -fDh; }
    Float_t angle(Int_t v)  const
    { static const Float_t pi=3.14159265f; return v == fV1 ? fAngle : (fAngle >= pi ? fAngle - pi : fAngle + pi); }
    Float_t surface()       const { return fSurface; }
    Float_t spread(Int_t v) const { return v == fV1 ? fSpr1 : fSpr2; }

    Float_t sign(Int_t v)   const { return v == fV1 ? 1.0f : -1.0f; }

    Bool_t  match(Int_t va, Int_t vb) const
    { return (va == fV1 && vb == fV2) || (va == fV2 && vb == fV1); }
  };

  struct VertexData
  {
    Int_t             fNEdges;    // Number of edges
    Int_t            *fEdgeArr;   // Array of edge idcss, sorted by their angle
    Float_t           fSurface;   // Sum of 1/3 of triangle surfaces
    Float_t           fSpread;    // Sum of triangle angles

    VertexData() : fNEdges(0), fEdgeArr(0), fSurface(0), fSpread(0) {}

    Int_t n_edges()      const { return fNEdges; }
    Int_t edge(Int_t ei) const { return fEdgeArr[ei]; }

    // For use during construction
    void insert_edge(Int_t ei) { fEdgeArr[fNEdges++] = ei; }
  };

  struct VertexVisitor
  {
    TriMesh* mMesh;

    VertexVisitor(TriMesh* m) : mMesh(m) {}
    virtual ~VertexVisitor() {}

    virtual Bool_t VisitVertex(Int_t vertex) = 0;
  };

  struct VertexVisitorMaxDist : public VertexVisitor
  {
    Float_t mOrigin[3];
    Float_t mMaxDistSqr;
    Float_t mLastDistSqr;

    VertexVisitorMaxDist(TriMesh* m, const Float_t origin[3], Float_t max_dist);

    virtual Bool_t VisitVertex(Int_t vertex);
  };

private:
  void _init();

protected:
  ZLink<ZImage>           mDefTexture; //  X{GS} L{}
  ZLink<ParaSurf>         mParaSurf;   //  X{GS} L{a}

  TringTvor*              mTTvor;      //! X{gs}

  Opcode::Model*          mOPCModel;   //! X{g}
  Opcode::MeshInterface*  mOPCMeshIf;  //! X{g}

  Float_t                 mVolume;     // X{GS} 7 ValOut(-join=>1)
  Float_t                 mXYArea;     // X{GS} 7 ValOut()

  Float_t                 mM;          // X{GS} 7 ValOut(-join=>1)
  Float_t                 mSurface;    // X{GS} 7 ValOut()
  HPointF                 mSection;    // X{RS} 7 HPointF(-const=>1)
  HPointF                 mCOM;        // X{RS} 7 HPointF(-const=>1)
  HPointF                 mJ;          // X{RS} 7 HPointF(-const=>1)

  vector<TriMesh::VertexData>   mVDataVec;  //! X{R}
  vector<TriMesh::EdgeData>     mEDataVec;  //! X{R}
  vector<Int_t>                 mECursVec;  //! X{R} Cursor array, one entry per vertex.

  void assert_tvor(const Exc_t& eh);

  void make_tetra(Int_t vo, Int_t to,
                  Float_t l1, Float_t l2,
                  Float_t z, Float_t w, Float_t h);
  void make_tetra_blade(Int_t vo, Int_t to,
                        const Float_t* org, const Float_t* dir,
                        Float_t w, Float_t h);
  void make_cubus(Int_t vo, Int_t to,
                  Float_t x0, Float_t y0, Float_t z0,
                  Float_t a,  Float_t b,  Float_t c);

  void extrude_triangle(Int_t ti, Float_t h);
  void extrude_triangle(Int_t ti, Float_t x, Float_t y, Float_t z);

  void calculate_surface_and_areas();

  void colorize_trings_std();
  void colorize_trings_single(UChar_t r, UChar_t g, UChar_t b, UChar_t a);

  EdgeData& find_edge(const VertexData& vd, Int_t v1, Int_t v2);
  EdgeData& find_edge(Int_t v1, Int_t v2);

public:
  TriMesh(const Text_t* n="TriMesh", const Text_t* t=0) :
    ZGlass(n,t) { _init(); }
  virtual ~TriMesh();

  // Virtuals from TriMeshColorArraySource.
  virtual void     AssertVertexColorArray();
  virtual UChar_t* GetVertexColorArray();
  virtual UChar_t* GetTriangleColorArray();
  virtual void     ColorArraysModified();

  virtual void ResetTTvorDependants();

  void SetMassAndSpeculate(Float_t mass, Float_t mass_frac_on_mesh=0.4);
  void SetMassFromBBox(Float_t sfac, Float_t hfac, Float_t density, Float_t mass_frac_on_mesh=0.4);

  void StdSurfacePostImport();
  void StdDynamicoPostImport();

  Opcode::AABB& ref_mesh_bbox() { return *(Opcode::AABB*)mTTvor->mCtrExtBox; }

  void BuildOpcStructs();
  void AssertOpcStructs();

  // TringTvor interface
  void CalculateBoundingBox();    // X{ED} 7 MButt()
  void GenerateVertexNormals();   // X{ED} 7 MButt()
  void GenerateTriangleNormals(); // X{ED} 7 MButt()
  void ImportRectTerrain(RectTerrain* rt,
                         Bool_t colp=true,
                         Bool_t texp=false); // X{ED} C{1} 7 MCWButt()

  void ImportGTSurf(GTSurf* gts); // X{ED} C{1} 7 MCWButt()
  void ExportGTSurf(GTSurf* gts); // X{ED} C{1} 7 MCWButt()

  void ImportOoliteDAT(const TString& filename, Bool_t invert_triangles=false);

  void ExportPovMesh(const Text_t* fname, Bool_t smoothp=false); // X{E} 7 MCWButt()

  void MakeTetrahedron(Float_t l1=0.8, Float_t l2=0.2,
                       Float_t  w=0.4, Float_t  h=0.4); // X{E} 7 MCWButt()
  void MakeTetraFlyer (Float_t l1=0.8, Float_t l2=0.2,
                       Float_t  w=0.2, Float_t  h=0.2,
                       Float_t wing_l1=0.4, Float_t wing_l2=0.1, Float_t wing_z=0.01,
                       Float_t wing_w=0.8,  Float_t wing_h=0.02); // X{E} 7 MCWButt()
  void MakeTetraChopper(Float_t l1=0.3, Float_t l2=0, Float_t l3=0.2, Float_t l4=0.8,
                        Float_t w=0.2, Float_t h=0.2,
                        Float_t wing_l1=0.4, Float_t wing_l2=0.8,
                        Float_t wing_w=0.12, Float_t wing_h=0.02); // X{E} 7 MCWButt()
  void MakeTetraMark(Float_t r0=0.5, Float_t h0=2,
		     Float_t r1=3,   Float_t w1=1, Float_t h1=0.05); // X{E} 7 MCWButt()

  void MakeBox(Float_t a=5, Float_t b=4, Float_t c=3);

  void MakeIcosahedron();

  void NormalizeVertices();
  void ScaleVertices(Float_t s);

  void   BuildVertexConnections();
  void   AssertVertexConnections();
  Bool_t HasVertexConnections();

  Bool_t FindPointFromFGH(const Float_t fgh[3], Bool_t absolute_h,
			  Float_t xyz_out[3], Float_t* h_out=0, Int_t* triangle_idx=0);

  Bool_t FindPointFromXYZH(const Float_t xyz_in[3], Float_t h_in,
			   Float_t xyz_out[3], Float_t* h_out=0, Int_t* triangle_idx=0);

  Int_t  FindClosestVertex(Int_t triangle, const Float_t xyz[3], Float_t* sqr_dist=0);

  Bool_t FindTriangleExitPoint(Int_t triangle, const Float_t xyz[3], const Float_t dir[3],
			       Float_t xyz_out[3], Int_t* next_triangle=0);

  Int_t  VisitVertices(Int_t vertex, VertexVisitor& vertex_visitor,
                       set<Int_t>& visited_vertices,
                       set<Int_t>& accepted_vertices);

  // Colorizers

  void ColorByCoord (RGBAPalette* pal, ZGlass* carr_src_lens=0,
		     Int_t axis=2, Float_t fac=1, Float_t offset=0); // X{E} C{2} 7 MCWButt(-join=>1)
  void ColorByNormal(RGBAPalette* pal, ZGlass* carr_src_lens=0,
		     Int_t axis=2, Float_t min=-1, Float_t max=1);   // X{E} C{2} 7 MCWButt()

  void ColorByParaSurfCoord (RGBAPalette* pal, ZGlass* carr_src_lens=0,
			     Int_t axis=2,
			     Float_t fac=1, Float_t offset=0);       // X{E} C{2} 7 MCWButt(-join=>1)
  void ColorByParaSurfNormal(RGBAPalette* pal, ZGlass* carr_src_lens=0,
			     Int_t axis=2,
			     Float_t min=-1, Float_t max=1);         // X{E} C{2} 7 MCWButt()

  void ColorByCoordFormula (RGBAPalette* pal, ZGlass* carr_src_lens=0,
			    const Text_t* formula="z",
			    Float_t min=0, Float_t max=10);          // X{E} C{2} 7 MCWButt(-join=>1)
  void ColorByNormalFormula(RGBAPalette* pal, ZGlass* carr_src_lens=0,
			    const Text_t* formula="sqrt(x*x+y*y)",
			    Float_t min=0, Float_t max=1);           // X{E} C{2} 7 MCWButt()

#include "TriMesh.h7"
  ClassDef(TriMesh, 1);
}; // endclass TriMesh


inline TriMesh::EdgeData& TriMesh::find_edge(const VertexData& vd,
                                             Int_t v1, Int_t v2)
{
  for (Int_t i=0; i<vd.fNEdges; ++i)
  {
    EdgeData& ed = mEDataVec[vd.edge(i)];
    if ((ed.fV1 == v1 && ed.fV2 == v2) || (ed.fV1 == v2 && ed.fV2 == v1))
      return ed;
  }
  throw (Exc_t("Safertundhell ... edge not found."));
}

inline TriMesh::EdgeData& TriMesh::find_edge(Int_t v1, Int_t v2)
{
  VertexData& vd = mVDataVec[v1];
  return find_edge(vd, v1, v2);
}

inline bool operator==(const TriMesh::Edge& a, const TriMesh::Edge& b)
{ return a.v1 == b.v1 && a.v2 == b.v2; }

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