ROOT logo
// $Id: ParaSurf.cxx 2198 2009-05-11 22:22:41Z 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/.

#include "ParaSurf.h"
#include "TriMesh.h"
#include "ParaSurf.c7"
#include <Stones/HTrans.h>
#include <Stones/ZTrans.h>

#include <Opcode/Opcode.h>

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


//==============================================================================
// ParaSurf
//==============================================================================

//__________________________________________________________________________
//
// Virtual base-class for describing the coordinate system of a 2D
// parametric surface. The surface is described with two parameters
// (f, g) and the third one accounts for distance in the normal
// direction (h, height).
//
// Methods in this class allow for mapping between parametric (f,g,h)
// space and world (x,y,z) space.

ClassImp(ParaSurf);

const Float_t ParaSurf::sEpsilonFac  = 1e-5;
const Float_t ParaSurf::sPi          = 3.14159265358979323846f;
const Float_t ParaSurf::sTwoPi       = 6.28318530717958647692f;
const Float_t ParaSurf::sPiHalf      = 1.57079632679489661923f;

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

void ParaSurf::_init()
{
  mMinF = mMaxF = mMinG = mMaxG = mMinH = mMaxH = mMeanH = mSigmaH = 0;
  mGravAtSurface = 10.0;
  mEpsilon = sEpsilonFac;
}

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

void ParaSurf::FindMinMaxFGH(TriMesh* mesh)
{
  static const Exc_t _eh("ParaSurf::FindMinMaxFGH ");

  if (mesh == 0) throw(_eh + "mesh null.");

  TringTvor & TT = * mesh->GetTTvor();
  if (TT.mNVerts < 1)
  {
    mMinF = mMaxF = mMinG = mMaxG = mMinH = mMaxH = mMeanH = mSigmaH = 0;
    return;
  }

  mMinF = mMinG = mMinH =  FLT_MAX;
  mMaxF = mMaxG = mMaxH = -FLT_MAX;
  Double_t sumh = 0, sumh2 = 0;

  Float_t * V  = TT.Verts();
  Int_t     N  = TT.mNVerts;
  Float_t   F[3];
  for (Int_t i=0; i<N; ++i, V+=3)
  {
    pos2fgh(V, F);
    if (F[0] < mMinF) mMinF = F[0]; else if (F[0] > mMaxF) mMaxF = F[0];
    if (F[1] < mMinG) mMinG = F[1]; else if (F[1] > mMaxG) mMaxG = F[1];
    if (F[2] < mMinH) mMinH = F[2]; else if (F[2] > mMaxH) mMaxH = F[2];
    sumh += F[2]; sumh2 += F[2]*F[2];
  }
  mMeanH   = sumh/N;
  mSigmaH  = TMath::Sqrt(TMath::Abs(sumh2/N - sumh*sumh/N/N));
  mEpsilon = sEpsilonFac*(mMaxH - mMinH);

  Stamp(FID());
}

void ParaSurf::FindMinMaxH(TriMesh* mesh)
{
  static const Exc_t _eh("ParaSurf::FindMinMaxH ");

  if (mesh == 0) throw(_eh + "mesh null.");

  TringTvor & TT = * mesh->GetTTvor();
  if (TT.mNVerts < 1)
  {
    mMinH = mMaxH = mMeanH = mSigmaH = 0;
    return;
  }

  mMinH =  FLT_MAX;
  mMaxH = -FLT_MAX;
  Double_t sumh = 0, sumh2 = 0;

  Float_t * V  = TT.Verts();
  Int_t     N  = TT.mNVerts;
  Float_t   F[3];
  for (Int_t i=0; i<N; ++i, V+=3)
  {
    pos2fgh(V, F);
    if (F[2] < mMinH) mMinH = F[2]; else if (F[2] > mMaxH) mMaxH = F[2];
    sumh += F[2]; sumh2 += F[2]*F[2];
  }
  mMeanH   = sumh/N;
  mSigmaH  = TMath::Sqrt(TMath::Abs(sumh2/N - sumh*sumh/N/N));
  mEpsilon = sEpsilonFac*(mMaxH - mMinH);

  Stamp(FID());
}

void ParaSurf::RandomizeH(TriMesh* mesh,
                          Float_t  fg_chr_len, Float_t h_chr_len,
                          Float_t  alpha,      Bool_t  accum_dh,
                          Float_t  n_pass)
{
  // Randomize vertex heights by fractional brownian rules.
  // Does random selection of vertex-pairs, number of edges visited in
  // each pass is estimated as 3 * Nvert.
  // fg_chr_len - characteristic length in f,g direction
  // h_chr_len  - characteristic length in h direction

  static const Exc_t _eh("ParaSurf::RandomizeH ");

  if (mesh == 0) throw(_eh + "mesh null.");

  using namespace Opcode;

  TringTvor& TT = * mesh->GetTTvor();
  Int_t  NV = TT.mNVerts;
  Int_t  NT = TT.mNTrings;
  Point* X  = (Point*) TT.Verts();
  Point* U  = new Point [NV];

  // Calculate up-dirs for each vertex.
  for (Int_t i=0; i<NV; ++i)
    pos2hdir(X[i], U[i]);

  TRandom rnd(0);
  const Int_t   n_max      = Int_t( 3*NV*n_pass );
  const Float_t fg_fac     = 1/fg_chr_len/fg_chr_len;
  const Float_t alpha_half = 0.5*alpha;

  for (Int_t i = 0; i < n_max; ++i)
  {
    Int_t  *vs  = TT.Triangle( rnd.Integer(NT) );
    Int_t   v1  = vs[ rnd.Integer(3) ];
    Int_t   v2  = vs[ v1 < 2 ? v1 + 1 : 0 ];

    Point   n   = U[v1] + U[v2];  n.Normalize();
    Point   dx  = X[v2] - X[v1];
    Float_t odh = dx | n;
    dx.TMsc(n, odh);
    // get random delta h from gaussian ...
    Float_t dfgsq = fg_fac * dx.SquareMagnitude();
    Float_t sgm   = h_chr_len * powf(dfgsq, alpha_half);
    Float_t dh    = rnd.Gaus(0, sgm);
    Float_t hh    = 0.5 * (accum_dh ? dh : dh + odh);
    X[v1].TMac(U[v1], hh);
    X[v2].TMsc(U[v2], hh);
  }

  delete [] U;
}

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

Bool_t ParaSurf::IsValidFGH(const Float_t f[3], Bool_t check_h)
{
  if (f[0] < mMinF || f[0] > mMaxF || f[1] < mMinG || f[1] > mMaxG)
    return false;
  if (check_h && (f[2] < mMinH || f[2] > mMaxH))
    return false;
  return true;
}

Bool_t ParaSurf::IsValidPos(const Float_t x[3], Bool_t check_h)
{
  Float_t f[3];
  pos2fgh(x, f);
  return IsValidFGH(f);
}

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

Float_t ParaSurf::CharacteristicLength()
{
  return sqrtf(Surface());
}

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

void ParaSurf::origin_fgh(Float_t* f)
{
  f[0] = f[1] = f[2] = 0.0f;
}

void ParaSurf::origin_pos(Float_t* x)
{
  Float_t fgh[3];
  origin_fgh(fgh);
  fgh2pos(fgh, x);
}

void ParaSurf::origin_trans(HTransF& t)
{
  Float_t fgh[3];
  origin_fgh(fgh);
  fgh2trans(fgh, t);
}

void ParaSurf::origin_trans(ZTrans& t)
{
  HTransF ht;
  origin_trans(ht);
  t.SetFromArray(ht.Array());
}

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

void ParaSurf::fgh2trans(const Float_t* f, HTransF& t)
{
  fgh2fdir(f, t.ArrX());
  fgh2gdir(f, t.ArrY());
  fgh2hdir(f, t.ArrZ());
  fgh2pos (f, t.ArrT());
}

void ParaSurf::fgh2trans(const Float_t* f, ZTrans& t)
{
  HTransF ht;
  fgh2trans(f, ht);
  t.SetFromArray(ht.Array());
}

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

void ParaSurf::pos2fghdir(const Float_t* x, Float_t* fdir, Float_t* gdir, Float_t* hdir)
{
  Float_t fgh[3];
  pos2fgh(x, fgh);
  fgh2fdir(fgh, fdir);
  fgh2gdir(fgh, gdir);
  fgh2hdir(fgh, hdir);
}

void ParaSurf::sub_fgh(Float_t* a, Float_t* b, Float_t* delta)
{
  // Subtract fgh values, taking care of U(1) variables (like angles).
  // This base-class version does simple delta = a - b, which is ok for
  // PSRectangle and PSTriangle.

  delta[0] = a[0] - b[0];
  delta[1] = a[1] - b[1];
  delta[2] = a[2] - b[2];
}

void ParaSurf::regularize_fg(Float_t* f)
{
  // Put fg values into regular intervals.
  // Here we just clamp them to min, max values which is ok for
  // PSRectangle and PSTriangle.

  if (f[0] < mMinF) f[0] = mMinF; else if (f[0] > mMaxF) f[0] = mMaxF;
  if (f[1] < mMinG) f[1] = mMinG; else if (f[1] > mMaxG) f[1] = mMaxG;
}

void ParaSurf::random_pos(TRandom& rnd, Float_t* x)
{
  Float_t fgh[3];
  random_fgh(rnd, fgh);
  fgh2pos(fgh, x);
}

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