ROOT logo
// $Id: RectTerrain.cxx 2440 2010-08-15 21:14:45Z 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/.

//__________________________________________________________________________
//
// A rectangular mNx * mNy height field.
// mO(x|y) ~ origin, mD(x|y) ~ grid spacing.
// Can be set from a ZImage via void SetFromImage(ZImage* image).
//
// If ColSep == 0, coloring is not done.
//
// Renderer is stupid, so expect it to be slow for large grids (512x512).

#include "RectTerrain.h"
#include <Glasses/ZImage.h>
#include <Stones/TringTvor.h>
#include "RectTerrain.c7"

#include <IL/il.h>

#include <TMath.h>

#include <stdio.h>

ClassImp(RectTerrain);

Float_t RectTerrain::sMaxEpsilon = 0.0001;

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

void RectTerrain::_init()
{
  // Override settings from ZGlass
  bUseDispList = true;

  mNx = mNy = 0;
  mDx = mDy = 1;

  mMinZ = 0; mMaxZ = 0;
  mMinCol.gray(0.2); mMaxCol.gray(1);
  mColSep = 1;

  mRnrMode    = RM_Histo;
  mBorderCond = BC_Zero;
  mOriginMode = OM_Edge;
  mBValue = 0;
  bBorder = false;

  mSmoothFac = 0.2;

  bStudySize = false;

  pTTvor      = 0;
  mTTvorStamp = 0;
  bUseTringStrips    = false;
  mMaxTSVerts        = 256;
  bRndColTringStrips = false;
}

RectTerrain::~RectTerrain()
{
  delete pTTvor;
}

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

void RectTerrain::ApplyBorderCondition()
{
  const Int_t MX = mNx + 1;
  const Int_t MY = mNy + 1;
  const Int_t mx = mNx - 1;
  const Int_t my = mNy - 1;

  switch (mBorderCond) {

  case BC_Zero:
  case BC_Const: {
    const Float_t C = (mBorderCond == BC_Zero) ? 0 : mBValue;
    mP(0,0) = mP(MX,MY) = C;
    for(Int_t i=0; i<=MX; ++i) { mP(i, 0) = mP(i, MY) = C; }
    for(Int_t i=1; i< MY; ++i) { mP(0, i) = mP(MX, i) = C; }
    break;
  }
  case BC_External: {
    break;
  }
  case BC_Equal: {
    mP(0 ,0) = mP(1,1);   mP( 0,MY) = mP(1,mNy);
    mP(MX,0) = mP(mNx,1); mP(MX,MY) = mP(mNx,mNy);
    for(Int_t i=1; i<MX; ++i) { mP(i, 0) = mP(i,1); mP(i, MY) = mP(i,mNy); }
    for(Int_t i=1; i<MY; ++i) { mP(0, i) = mP(1,i); mP(MX, i) = mP(mNx,i); }
    break;
  }
  case BC_Sym: {
    mP(0 ,0) = mP(2,2);  mP( 0,MY) = mP(2,my);
    mP(MX,0) = mP(mx,2); mP(MX,MY) = mP(mx,my);
    for(Int_t i=1; i<MX; ++i) { mP(i, 0) = mP(i,2); mP(i, MY) = mP(i,my); }
    for(Int_t i=1; i<MY; ++i) { mP(0, i) = mP(2,i); mP(MX, i) = mP(mx,i); }
    break;
  }
  case BC_ASym: {
    mP(0 ,0) = 2*mP(1,1)   - mP(2,2);  mP( 0,MY) = 2*mP(1,  mNy) - mP(2,my);
    mP(MX,0) = 2*mP(mNx,1) - mP(mx,2); mP(MX,MY) = 2*mP(mNx,mNy) - mP(mx,my);
    for(Int_t i=1; i<MX; ++i) {
      mP(i, 0) = 2*mP(i,1) - mP(i,2); mP(i, MY) = 2*mP(i,mNy) - mP(i,my);
    }
    for(Int_t i=1; i<MY; ++i) {
      mP(0, i) = 2*mP(1,i) - mP(2,i); mP(MX, i) = 2*mP(mNx,i) - mP(mx,i);
    }
    break;
  }
  case BC_Wrap: {
    mP(0, 0) = mP(mNx,mNy); mP(0, MY) = mP(1,mNy);
    mP(MX,0) = mP(1,  mNy); mP(MX,MY) = mP(1,1);
    for(Int_t i=1; i<MX; ++i) { mP(i, 0) = mP(i,mNy); mP(i, MY) = mP(i,1); }
    for(Int_t i=1; i<MY; ++i) { mP(0, i) = mP(mNx,i); mP(MX, i) = mP(1,i); }
    break;
  }

  } // end switch mBCond

  mStampReqTring = Stamp(FID());
}

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

void RectTerrain::SetFromImage(ZImage* image, Float_t zfac)
{
  static const Exc_t _eh("RectTerrain::SetFromImage ");

  if(!image->IsBindable())
    throw(_eh + "image '" + image->Identify() + "' not bindable.");

  ZImage::sILMutex.Lock();
  image->bind();
  int w = image->w(), h = image->h();
  ILushort* data = new ILushort[w*h];
  ilCopyPixels(0,0,0, w,h,1, IL_LUMINANCE,IL_UNSIGNED_SHORT, data);
  image->unbind();
  ZImage::sILMutex.Unlock();

  mNx = w; mNy = h;
  mP.Clear();
  mP.ResizeTo(mNx + 2, mNy + 2);
  mMinZ = 1e9; mMaxZ = -1e9;

  for(Int_t y=1; y<=mNy; ++y) {
    ILushort* bar = &(data[(y-1)*w]);
    for(Int_t x=1; x<=mNx; ++x) {
      const float z = (float)(*(bar++));
      if(z > mMaxZ) mMaxZ = z;
      if(z < mMinZ) mMinZ = z;
      mP(x,y) = z;
    }
  }
  delete [] data;

  float zoffset = 0; // set z = 0 at 0

  float delta = (1 + sMaxEpsilon)*(mMaxZ - mMinZ);
  for(Int_t x=1; x<=mNx; ++x) {
    for(Int_t y=1; y<=mNy; ++y) {
      mP(x,y) = ( (mP(x,y) - mMinZ)/delta - zoffset ) * zfac;
    }
  }

  if(zfac > 0) {
    mMinZ = -zoffset * zfac; mMaxZ = (1 - zoffset) * zfac;
  } else {
    mMaxZ = -zoffset * zfac; mMinZ = (1 - zoffset) * zfac;
  }

  mStampReqTring = Stamp(FID());
}

void RectTerrain::SetFromHisto(TH2* histo)
{
  mNx = histo->GetNbinsX(); mNy = histo->GetNbinsY();
  const Int_t MX = mNx + 1, MY = mNy + 1;
  mP.Clear();
  mP.ResizeTo(mNx+2, mNy+2);
  mMinZ = 1e9; mMaxZ = -1e9;

  for(Int_t x=0; x<=MX; ++x) {
    for(Int_t y=0; y<=MY; ++y) {
      mP(x,y) = histo->GetBinContent(x,y);
    }
  }
  mMinZ = histo->GetMinimum();
  mMaxZ = histo->GetMaximum();

  float zoffset = 0; // set z = 0 at 0
  float zfac = 1;    // scale not

  float delta = 1.001*(mMaxZ - mMinZ);
  for(Int_t x=0; x<=MX; ++x) {
    for(Int_t y=0; y<=MY; ++y) {
      mP(x,y) = ( (mP(x,y) - mMinZ)/delta - zoffset ) * zfac;
    }
  }

  if(zfac > 0) {
    mMinZ = -zoffset * zfac; mMaxZ = (1 - zoffset) * zfac;
  } else {
    mMaxZ = -zoffset * zfac; mMinZ = (1 - zoffset) * zfac;
  }

  mStampReqTring = Stamp(FID());
}

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

void RectTerrain::Smooth(Float_t fac)
{
  TMatrixF M(mP);
  Double_t fa = (fac == 0) ? mSmoothFac : fac;
  Double_t fb = fa/TMath::Sqrt(2.0);
  Double_t normfac = 1/(1 + 4*fa + 4*fb);
  for(Int_t i=1; i<=mNx; ++i) {
    for(Int_t j=1; j<=mNy; ++j) {
      mP(i,j) = (M(i,j) + fa*(M(i-1,j) + M(i+1,j) + M(i,j-1) + M(i,j+1)) +
                      fb*(M(i-1,j-1) + M(i+1,j+1) + M(i+1,j-1) + M(i-1,j+1))
		 ) * normfac;
    }
  }
  mStampReqTring = Stamp(FID());
}

void RectTerrain::RecalcMinMax()
{
  mMinZ = 1e9; mMaxZ = -1e9;
  for(Int_t i=1; i<=mNx; ++i) {
    for(Int_t j=1; j<=mNy; ++j) {
      if(mP(i,j) > mMaxZ) mMaxZ = mP(i,j);
      if(mP(i,j) < mMinZ) mMinZ = mP(i,j);
    }
  }
  mMaxZ *= (1 + sMaxEpsilon);
  mStampReqTring = Stamp(FID());
}

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

void RectTerrain::ReTring()
{
  mStampReqTring = Stamp(FID());
}

#include <TRandom.h>
#include <TVirtualMutex.h>

void RectTerrain::Boobofy()
{
  // Must set Ribbon to booby.pov for best effect.

  TH2F* h=new TH2F("Booboo","exampul",128,-5,5,64,-2.5,2.5);
  TRandom r;
  for(int i=0;i<1000000;++i) {
    h->Fill(r.Gaus() - 2, r.Gaus());
    h->Fill(r.Gaus() + 2, r.Gaus());
  }
  for(int i=0;i<6000;++i) {
    h->Fill(0.1*r.Gaus() - 2, 0.1*r.Gaus());
    h->Fill(0.1*r.Gaus() + 2, 0.1*r.Gaus());
  }
  {
    R__LOCKGUARD(GledNS::GetCINTMutex());
    h->Draw("LEGO2");
  }
  SetFromHisto(h);
  for(int i=0; i<5; ++i) Smooth(1);
  RecalcMinMax();
}

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

void RectTerrain::color_filler(Float_t* v, UChar_t* c, void* rt)
{
  ((RectTerrain*)rt)->make_color(v[2]).to_ubyte(c);
}

TringTvor* RectTerrain::SpawnTringTvor(Bool_t smoothp, Bool_t flatp,
                                       Bool_t colp,    Bool_t texp)
{
  // Create TringTvor from height field.
  // This can be also be called by an outside client that wants to extract
  // triangulation of this terrain as a triangle mesh.

  Int_t minX = 1, maxX = mNx, minY = 1, maxY = mNy;
  if(bBorder) {
    --minX; ++maxX; --minY; ++maxY;
  }
  Int_t       nx = maxX - minX + 1,       ny = maxY - minY + 1;
  Float_t tex_fx = 1.0/(maxX - minX), tex_fy = 1.0/(maxY - minY);

  TringTvor& TT = * new TringTvor(nx*ny, (nx-1)*(ny-1)*2, smoothp, colp, texp);

  Int_t          idx = 0;
  Int_t    tring_idx = 0;

  for(Int_t j=minY; j<=maxY; ++j)
  {
    for(Int_t i=minX; i<=maxX; ++i)
    {
      Float_t *v = TT.Vertex(idx);
      v[0] = (i-1)*mDx; v[1] = (j-1)*mDy; v[2] = mP[i][j];

      if (smoothp)
      {
	Int_t il=i,ih=i,jh=j,jl=j;
	if(i>0) il--; if(i<=mNx) ih++;
	if(j>0) jl--; if(j<=mNy) jh++;
	Float_t dvx[] = { (ih-il)*mDx, 0, mP[ih][j] - mP[il][j] };
	Float_t dvy[] = { 0, (jh-jl)*mDy, mP[i][jh] - mP[i][jl] };
	Float_t *n = TT.Normal(idx);
	n[0] = -dvy[1]*dvx[2];
        n[1] = -dvx[0]*dvy[2];
        n[2] =  dvx[0]*dvy[1];
        TMath::Normalize(n);

	if (colp)
	{
	  make_color(mP[i][j]).to_ubyte(TT.Color(idx));
	}
      }

      if (texp)
      {
	Float_t* t = TT.Texture(idx);
	t[0] = tex_fx*(i-minX);
	t[1] = tex_fy*(j-minY);
      }

      if (i < maxX && j < maxY)
      {
	Float_t d1 = TMath::Abs(mP[i][j]   - mP[i+1][j+1] );
	Float_t d2 = TMath::Abs(mP[i][j+1] - mP[i+1][j]   );
	Int_t* T = TT.Triangle(tring_idx);
	// printf("j=%3d i=%3d idx=%4d tidx=%4d d1=%f, d2=%f\n",
        //        j, i, idx, tring_idx, d1, d2);
	if(d1 > d2) {
	  T[0] = idx;   T[1] = idx+1;    T[2] = idx+nx;   T += 3;
	  T[0] = idx+1; T[1] = idx+nx+1; T[2] = idx+nx;
	} else {
	  T[0] = idx;   T[1] = idx+1;    T[2] = idx+nx+1; T += 3;
	  T[0] = idx;   T[1] = idx+nx+1; T[2] = idx+nx;
	}
	tring_idx += 2;
      }

      ++idx;
    }
  }

  if(flatp) {
    if(colp)
      TT.GenerateTriangleNormalsAndColors(color_filler, this);
    else
      TT.GenerateTriangleNormals();
  }

  return &TT;
}

void RectTerrain::MakeTringTvor()
{
  // Creates TringTvor appropriate for current data-member settings.

  Bool_t smoothp = (mRnrMode == RM_SmoothTring);
  Bool_t flatp   = ! smoothp;
  Bool_t colp    = (mColSep  != 0);
  Bool_t texp    = (mTexture != 0);

  delete pTTvor;
  pTTvor = SpawnTringTvor(smoothp, flatp, colp, texp);

  if(bUseTringStrips) {
    pTTvor->GenerateTriangleStrips(mMaxTSVerts);
    if(bRndColTringStrips) {
      pTTvor->GenerateTriangleColorsFromTriangleStrips();
    }
  }

  mTTvorStamp = mTimeStamp;
}

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

Float_t RectTerrain::GetMinX(Bool_t include_border) const
{
  return (bBorder && include_border) ? -mDx : 0;
}

Float_t RectTerrain::GetMaxX(Bool_t include_border) const
{
  Int_t n = (bBorder && include_border) ? mNx : mNx-1;
  return n*mDx;
}

Float_t RectTerrain::GetMinY(Bool_t include_border) const
{
  return (bBorder && include_border) ? -mDy : 0;
}

Float_t RectTerrain::GetMaxY(Bool_t include_border) const
{
  Int_t n = (bBorder && include_border) ? mNy : mNy-1;
  return n*mDy;
}

 RectTerrain.cxx:1
 RectTerrain.cxx:2
 RectTerrain.cxx:3
 RectTerrain.cxx:4
 RectTerrain.cxx:5
 RectTerrain.cxx:6
 RectTerrain.cxx:7
 RectTerrain.cxx:8
 RectTerrain.cxx:9
 RectTerrain.cxx:10
 RectTerrain.cxx:11
 RectTerrain.cxx:12
 RectTerrain.cxx:13
 RectTerrain.cxx:14
 RectTerrain.cxx:15
 RectTerrain.cxx:16
 RectTerrain.cxx:17
 RectTerrain.cxx:18
 RectTerrain.cxx:19
 RectTerrain.cxx:20
 RectTerrain.cxx:21
 RectTerrain.cxx:22
 RectTerrain.cxx:23
 RectTerrain.cxx:24
 RectTerrain.cxx:25
 RectTerrain.cxx:26
 RectTerrain.cxx:27
 RectTerrain.cxx:28
 RectTerrain.cxx:29
 RectTerrain.cxx:30
 RectTerrain.cxx:31
 RectTerrain.cxx:32
 RectTerrain.cxx:33
 RectTerrain.cxx:34
 RectTerrain.cxx:35
 RectTerrain.cxx:36
 RectTerrain.cxx:37
 RectTerrain.cxx:38
 RectTerrain.cxx:39
 RectTerrain.cxx:40
 RectTerrain.cxx:41
 RectTerrain.cxx:42
 RectTerrain.cxx:43
 RectTerrain.cxx:44
 RectTerrain.cxx:45
 RectTerrain.cxx:46
 RectTerrain.cxx:47
 RectTerrain.cxx:48
 RectTerrain.cxx:49
 RectTerrain.cxx:50
 RectTerrain.cxx:51
 RectTerrain.cxx:52
 RectTerrain.cxx:53
 RectTerrain.cxx:54
 RectTerrain.cxx:55
 RectTerrain.cxx:56
 RectTerrain.cxx:57
 RectTerrain.cxx:58
 RectTerrain.cxx:59
 RectTerrain.cxx:60
 RectTerrain.cxx:61
 RectTerrain.cxx:62
 RectTerrain.cxx:63
 RectTerrain.cxx:64
 RectTerrain.cxx:65
 RectTerrain.cxx:66
 RectTerrain.cxx:67
 RectTerrain.cxx:68
 RectTerrain.cxx:69
 RectTerrain.cxx:70
 RectTerrain.cxx:71
 RectTerrain.cxx:72
 RectTerrain.cxx:73
 RectTerrain.cxx:74
 RectTerrain.cxx:75
 RectTerrain.cxx:76
 RectTerrain.cxx:77
 RectTerrain.cxx:78
 RectTerrain.cxx:79
 RectTerrain.cxx:80
 RectTerrain.cxx:81
 RectTerrain.cxx:82
 RectTerrain.cxx:83
 RectTerrain.cxx:84
 RectTerrain.cxx:85
 RectTerrain.cxx:86
 RectTerrain.cxx:87
 RectTerrain.cxx:88
 RectTerrain.cxx:89
 RectTerrain.cxx:90
 RectTerrain.cxx:91
 RectTerrain.cxx:92
 RectTerrain.cxx:93
 RectTerrain.cxx:94
 RectTerrain.cxx:95
 RectTerrain.cxx:96
 RectTerrain.cxx:97
 RectTerrain.cxx:98
 RectTerrain.cxx:99
 RectTerrain.cxx:100
 RectTerrain.cxx:101
 RectTerrain.cxx:102
 RectTerrain.cxx:103
 RectTerrain.cxx:104
 RectTerrain.cxx:105
 RectTerrain.cxx:106
 RectTerrain.cxx:107
 RectTerrain.cxx:108
 RectTerrain.cxx:109
 RectTerrain.cxx:110
 RectTerrain.cxx:111
 RectTerrain.cxx:112
 RectTerrain.cxx:113
 RectTerrain.cxx:114
 RectTerrain.cxx:115
 RectTerrain.cxx:116
 RectTerrain.cxx:117
 RectTerrain.cxx:118
 RectTerrain.cxx:119
 RectTerrain.cxx:120
 RectTerrain.cxx:121
 RectTerrain.cxx:122
 RectTerrain.cxx:123
 RectTerrain.cxx:124
 RectTerrain.cxx:125
 RectTerrain.cxx:126
 RectTerrain.cxx:127
 RectTerrain.cxx:128
 RectTerrain.cxx:129
 RectTerrain.cxx:130
 RectTerrain.cxx:131
 RectTerrain.cxx:132
 RectTerrain.cxx:133
 RectTerrain.cxx:134
 RectTerrain.cxx:135
 RectTerrain.cxx:136
 RectTerrain.cxx:137
 RectTerrain.cxx:138
 RectTerrain.cxx:139
 RectTerrain.cxx:140
 RectTerrain.cxx:141
 RectTerrain.cxx:142
 RectTerrain.cxx:143
 RectTerrain.cxx:144
 RectTerrain.cxx:145
 RectTerrain.cxx:146
 RectTerrain.cxx:147
 RectTerrain.cxx:148
 RectTerrain.cxx:149
 RectTerrain.cxx:150
 RectTerrain.cxx:151
 RectTerrain.cxx:152
 RectTerrain.cxx:153
 RectTerrain.cxx:154
 RectTerrain.cxx:155
 RectTerrain.cxx:156
 RectTerrain.cxx:157
 RectTerrain.cxx:158
 RectTerrain.cxx:159
 RectTerrain.cxx:160
 RectTerrain.cxx:161
 RectTerrain.cxx:162
 RectTerrain.cxx:163
 RectTerrain.cxx:164
 RectTerrain.cxx:165
 RectTerrain.cxx:166
 RectTerrain.cxx:167
 RectTerrain.cxx:168
 RectTerrain.cxx:169
 RectTerrain.cxx:170
 RectTerrain.cxx:171
 RectTerrain.cxx:172
 RectTerrain.cxx:173
 RectTerrain.cxx:174
 RectTerrain.cxx:175
 RectTerrain.cxx:176
 RectTerrain.cxx:177
 RectTerrain.cxx:178
 RectTerrain.cxx:179
 RectTerrain.cxx:180
 RectTerrain.cxx:181
 RectTerrain.cxx:182
 RectTerrain.cxx:183
 RectTerrain.cxx:184
 RectTerrain.cxx:185
 RectTerrain.cxx:186
 RectTerrain.cxx:187
 RectTerrain.cxx:188
 RectTerrain.cxx:189
 RectTerrain.cxx:190
 RectTerrain.cxx:191
 RectTerrain.cxx:192
 RectTerrain.cxx:193
 RectTerrain.cxx:194
 RectTerrain.cxx:195
 RectTerrain.cxx:196
 RectTerrain.cxx:197
 RectTerrain.cxx:198
 RectTerrain.cxx:199
 RectTerrain.cxx:200
 RectTerrain.cxx:201
 RectTerrain.cxx:202
 RectTerrain.cxx:203
 RectTerrain.cxx:204
 RectTerrain.cxx:205
 RectTerrain.cxx:206
 RectTerrain.cxx:207
 RectTerrain.cxx:208
 RectTerrain.cxx:209
 RectTerrain.cxx:210
 RectTerrain.cxx:211
 RectTerrain.cxx:212
 RectTerrain.cxx:213
 RectTerrain.cxx:214
 RectTerrain.cxx:215
 RectTerrain.cxx:216
 RectTerrain.cxx:217
 RectTerrain.cxx:218
 RectTerrain.cxx:219
 RectTerrain.cxx:220
 RectTerrain.cxx:221
 RectTerrain.cxx:222
 RectTerrain.cxx:223
 RectTerrain.cxx:224
 RectTerrain.cxx:225
 RectTerrain.cxx:226
 RectTerrain.cxx:227
 RectTerrain.cxx:228
 RectTerrain.cxx:229
 RectTerrain.cxx:230
 RectTerrain.cxx:231
 RectTerrain.cxx:232
 RectTerrain.cxx:233
 RectTerrain.cxx:234
 RectTerrain.cxx:235
 RectTerrain.cxx:236
 RectTerrain.cxx:237
 RectTerrain.cxx:238
 RectTerrain.cxx:239
 RectTerrain.cxx:240
 RectTerrain.cxx:241
 RectTerrain.cxx:242
 RectTerrain.cxx:243
 RectTerrain.cxx:244
 RectTerrain.cxx:245
 RectTerrain.cxx:246
 RectTerrain.cxx:247
 RectTerrain.cxx:248
 RectTerrain.cxx:249
 RectTerrain.cxx:250
 RectTerrain.cxx:251
 RectTerrain.cxx:252
 RectTerrain.cxx:253
 RectTerrain.cxx:254
 RectTerrain.cxx:255
 RectTerrain.cxx:256
 RectTerrain.cxx:257
 RectTerrain.cxx:258
 RectTerrain.cxx:259
 RectTerrain.cxx:260
 RectTerrain.cxx:261
 RectTerrain.cxx:262
 RectTerrain.cxx:263
 RectTerrain.cxx:264
 RectTerrain.cxx:265
 RectTerrain.cxx:266
 RectTerrain.cxx:267
 RectTerrain.cxx:268
 RectTerrain.cxx:269
 RectTerrain.cxx:270
 RectTerrain.cxx:271
 RectTerrain.cxx:272
 RectTerrain.cxx:273
 RectTerrain.cxx:274
 RectTerrain.cxx:275
 RectTerrain.cxx:276
 RectTerrain.cxx:277
 RectTerrain.cxx:278
 RectTerrain.cxx:279
 RectTerrain.cxx:280
 RectTerrain.cxx:281
 RectTerrain.cxx:282
 RectTerrain.cxx:283
 RectTerrain.cxx:284
 RectTerrain.cxx:285
 RectTerrain.cxx:286
 RectTerrain.cxx:287
 RectTerrain.cxx:288
 RectTerrain.cxx:289
 RectTerrain.cxx:290
 RectTerrain.cxx:291
 RectTerrain.cxx:292
 RectTerrain.cxx:293
 RectTerrain.cxx:294
 RectTerrain.cxx:295
 RectTerrain.cxx:296
 RectTerrain.cxx:297
 RectTerrain.cxx:298
 RectTerrain.cxx:299
 RectTerrain.cxx:300
 RectTerrain.cxx:301
 RectTerrain.cxx:302
 RectTerrain.cxx:303
 RectTerrain.cxx:304
 RectTerrain.cxx:305
 RectTerrain.cxx:306
 RectTerrain.cxx:307
 RectTerrain.cxx:308
 RectTerrain.cxx:309
 RectTerrain.cxx:310
 RectTerrain.cxx:311
 RectTerrain.cxx:312
 RectTerrain.cxx:313
 RectTerrain.cxx:314
 RectTerrain.cxx:315
 RectTerrain.cxx:316
 RectTerrain.cxx:317
 RectTerrain.cxx:318
 RectTerrain.cxx:319
 RectTerrain.cxx:320
 RectTerrain.cxx:321
 RectTerrain.cxx:322
 RectTerrain.cxx:323
 RectTerrain.cxx:324
 RectTerrain.cxx:325
 RectTerrain.cxx:326
 RectTerrain.cxx:327
 RectTerrain.cxx:328
 RectTerrain.cxx:329
 RectTerrain.cxx:330
 RectTerrain.cxx:331
 RectTerrain.cxx:332
 RectTerrain.cxx:333
 RectTerrain.cxx:334
 RectTerrain.cxx:335
 RectTerrain.cxx:336
 RectTerrain.cxx:337
 RectTerrain.cxx:338
 RectTerrain.cxx:339
 RectTerrain.cxx:340
 RectTerrain.cxx:341
 RectTerrain.cxx:342
 RectTerrain.cxx:343
 RectTerrain.cxx:344
 RectTerrain.cxx:345
 RectTerrain.cxx:346
 RectTerrain.cxx:347
 RectTerrain.cxx:348
 RectTerrain.cxx:349
 RectTerrain.cxx:350
 RectTerrain.cxx:351
 RectTerrain.cxx:352
 RectTerrain.cxx:353
 RectTerrain.cxx:354
 RectTerrain.cxx:355
 RectTerrain.cxx:356
 RectTerrain.cxx:357
 RectTerrain.cxx:358
 RectTerrain.cxx:359
 RectTerrain.cxx:360
 RectTerrain.cxx:361
 RectTerrain.cxx:362
 RectTerrain.cxx:363
 RectTerrain.cxx:364
 RectTerrain.cxx:365
 RectTerrain.cxx:366
 RectTerrain.cxx:367
 RectTerrain.cxx:368
 RectTerrain.cxx:369
 RectTerrain.cxx:370
 RectTerrain.cxx:371
 RectTerrain.cxx:372
 RectTerrain.cxx:373
 RectTerrain.cxx:374
 RectTerrain.cxx:375
 RectTerrain.cxx:376
 RectTerrain.cxx:377
 RectTerrain.cxx:378
 RectTerrain.cxx:379
 RectTerrain.cxx:380
 RectTerrain.cxx:381
 RectTerrain.cxx:382
 RectTerrain.cxx:383
 RectTerrain.cxx:384
 RectTerrain.cxx:385
 RectTerrain.cxx:386
 RectTerrain.cxx:387
 RectTerrain.cxx:388
 RectTerrain.cxx:389
 RectTerrain.cxx:390
 RectTerrain.cxx:391
 RectTerrain.cxx:392
 RectTerrain.cxx:393
 RectTerrain.cxx:394
 RectTerrain.cxx:395
 RectTerrain.cxx:396
 RectTerrain.cxx:397
 RectTerrain.cxx:398
 RectTerrain.cxx:399
 RectTerrain.cxx:400
 RectTerrain.cxx:401
 RectTerrain.cxx:402
 RectTerrain.cxx:403
 RectTerrain.cxx:404
 RectTerrain.cxx:405
 RectTerrain.cxx:406
 RectTerrain.cxx:407
 RectTerrain.cxx:408
 RectTerrain.cxx:409
 RectTerrain.cxx:410
 RectTerrain.cxx:411
 RectTerrain.cxx:412
 RectTerrain.cxx:413