ROOT logo
// $Id: WSSeed.cxx 2400 2010-07-03 21:13:17Z 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/.

//______________________________________________________________________
// WSSeed
//
// Weaver Symbol Seed. Serves as container for WSPoints that make up
// the actual symbol. Provides triangulation service and stores
// triangulation data.

#include "WSSeed.h"
#include "ZImage.h"
#include "WSSeed.c7"
#include "WSPoint.h"

#include <Stones/TubeTvor.h>

#include <Gled/GThread.h>

#include <TMath.h>
#include <TF1.h>

//--- tmp ---
#include <Glasses/ZQueen.h>
#include <Glasses/Sphere.h>
#include <TRandom.h>

ClassImp(WSSeed);

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

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

  mTLevel = 16; mPLevel = 16;

  mTexUOffset = mTexVOffset = 0;
  mTexUScale  = mTexVScale  = 1;

  mTrueLength = 0; bRenormLen = false; mLength = 1;

  mLineW = 2; bFat = true;

  mTexture = 0;

  mDtexU = mDtexV = 0;

  pTuber = 0;     bTextured = false;
  m_first_point = m_last_point = 0; m_num_points = 0;

  bAnimRunning = false;
  mAnimSleepMS = 50;
  mAnimTime    = 0;
  mAnimStepFac = 1;
  m_anim_tick  = 0;
}

WSSeed::~WSSeed() { delete pTuber; }

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

void WSSeed::on_insert(iterator it)
{
  PARENT_GLASS::on_insert(it);

  WSPoint* m = dynamic_cast<WSPoint*>(it->fLens);
  if(m == 0)
    return;

  Float_t delta_len = 0;
  iterator i = it; ++i;
  WSPoint* n = 0;
  while(i != end()) {
    n = dynamic_cast<WSPoint*>((i++)->fLens);
    if(n != 0) {
      n->mPrevPoint = m;
      m->mNextPoint = n;
      delta_len += m->mStretch;
      break;
    }
  }
  if(n == 0)
    m_last_point = m;

  WSPoint* p = 0;
  while(it != begin()) {
    p = dynamic_cast<WSPoint*>((--it)->fLens);
    if(p != 0) {
      m->mPrevPoint = p;
      if(p->mNextPoint == 0)
	delta_len += p->mStretch;
      p->mNextPoint = m;
      break;
    }
  }
  if(p == 0)
    m_first_point  = m;

  ++m_num_points;
  mTrueLength += delta_len;

  mStampReqTring = Stamp(FID());
}

void WSSeed::on_remove(iterator it)
{
  PARENT_GLASS::on_remove(it);

  WSPoint* m = dynamic_cast<WSPoint*>(it->fLens);
  if(m == 0)
    return;

  Float_t delta_len = 0;
  if(m->mPrevPoint) {
    if(m->mNextPoint == 0)
      delta_len -= m->mPrevPoint->mStretch;
    m->mPrevPoint->mNextPoint = m->mNextPoint;
  } else {
    m_first_point = m->mNextPoint;
  }
  if(m->mNextPoint) {
    m->mNextPoint->mPrevPoint = m->mPrevPoint;
    delta_len -= m->mStretch;
  } else {
    m_last_point  = m->mPrevPoint;
  }
  m->mPrevPoint = 0;
  m->mNextPoint = 0;

  --m_num_points;
  mTrueLength += delta_len;

  mStampReqTring = Stamp(FID());
}

void WSSeed::on_rebuild()
{
  PARENT_GLASS::on_rebuild();

  mTrueLength = 0;
  m_first_point = m_last_point = 0; m_num_points = 0;
  WSPoint *p = 0, *n = 0;
  for(iterator i=begin(); i!=end(); ++i) {
    n = dynamic_cast<WSPoint*>(i->fLens);
    if(n != 0) {
      if(p != 0) {
	n->mPrevPoint = p;
	p->mNextPoint = n;
	mTrueLength += p->mStretch;
      } else {
	m_first_point = n;
      }
      m_last_point = p = n;
      ++m_num_points;
    }
  }
  mStampReqTring = Stamp(FID());
}

void WSSeed::clear_list()
{
  PARENT_GLASS::clear_list();

  mTrueLength = 0;
  m_first_point = m_last_point = 0; m_num_points = 0;

  mStampReqTring = Stamp(FID());
}

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

void WSSeed::Triangulate()
{
  // Should be called under ReadLock.

  if(m_num_points < 2) {
    delete pTuber; pTuber = 0;
    return;
  }
  if(!bFat) {
    // !!!!! Could at least call Coffs !!!!!
    // Then don't need them in line rnr
    // and in TransAtTime
    return;
  }

  bTextured = (mTexture != 0);
  if(pTuber == 0) pTuber = new TubeTvor;
  pTuber->Init(0, mTLevel*(m_num_points - 1) + 1, mPLevel, false, bTextured);

  Float_t len_fac = (bRenormLen) ? mLength / mTrueLength : 1;

  bool first = true;
  WSPoint *a, *b;
  b = m_first_point;
  ZTrans* lcfp = 0;
  while((a=b, b=b->mNextPoint, b) != 0) {
    a->Coff(b);
    if(first) {
      first = false;
      lcfp  = init_slide(a);
      hTexU = 0;
      hTexV = 0;
    }
    Float_t delta = 1.0/mTLevel, max = 1 - delta/2;
    for(Float_t t=0; t<max; t+=delta) {
      ring(*lcfp, a, t);
      hTexU += delta * a->mStretch * len_fac;
      hTexV += delta * a->mTwist;
    }
  }
  ring(*lcfp, a->mPrevPoint, 1);
  delete lcfp;
}

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

Float_t WSSeed::Length()
{
  return bRenormLen ? mLength : mTrueLength;
}

Float_t WSSeed::MeasureLength()
{
  GMutexHolder lstlck(mListMutex);

  Float_t len = 0;
  if(m_num_points >= 2) {
    WSPoint* a = m_first_point;
    while(a->mNextPoint != 0) {
      len += a->mStretch;
      a = a->mNextPoint;
    }
  }
  if(len != mTrueLength)
    SetTrueLength(len);
  return len;
}

void WSSeed::MeasureAndSetLength()
{
  mLength = MeasureLength();
  mStampReqTring = Stamp(FID());
}

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

void WSSeed::TransAtTime(ZTrans& lcf, Double_t time, Bool_t repeat_p, Bool_t reinit_trans_p)
{
  // Positions lcf to time.
  // If repeat_p is true, the time is clamped into the range.
  // 'Up' and 'right' axes are Gram-Schmidt orto-normalized wrt 'front'.

  static const Exc_t _eh("WSSeed::TransAtTime ");

  if(m_num_points < 2)
    throw(_eh + "nedd at least two points.");

  // Here should call triangulate if mStamReqTex < mTimeStamp
  // The triangulation could measure lengths etc, store them in local data.
  // Then also don't need Coff call below.
  // Coff is now optimised.

  Double_t len_fac = 1;
  Double_t len     = mTrueLength;
  if(bRenormLen) {
    len_fac = mLength/len;
    len     = mLength;
  }

  if(time < 0 || time > len) {
    if(repeat_p) {
      time -= ((int)(time/len))*len;
      if(time < 0) time += len;
    } else {
      time = (time < 0) ? 0 : len;
    }
  }

  // printf("OK ... came up with time=%f\n", time);

  Double_t done = 0;
  WSPoint *a, *b;
  b = m_first_point;
  while((a=b, b=b->mNextPoint, b) != 0) {
    done += a->mStretch * len_fac;
    if(done >= time) break;
  }
  Double_t t;
  if(b != 0) {
    t = 1  -  (done - time) / (a->mStretch * len_fac);
  } else {
    t = 1;
    b = a; a = b->mPrevPoint;
  }
  a->Coff(b);

  if(reinit_trans_p)
    lcf = a->RefTrans();

  const Double_t t2 = t*t, t3 = t2*t;
  Double_t* Pnt = lcf.ArrT();
  Double_t* Axe = lcf.ArrX();

  for(Int_t i=0; i<3; i++) {
    const TMatrixDRow R( a->mCoffs[i] );
    Pnt[i] = R[0] +   R[1]*t +   R[2]*t2 + R[3]*t3;
    Axe[i] = R[1] + 2*R[2]*t + 3*R[3]*t2;
  }

  lcf.OrtoNorm3();
}

/**************************************************************************/
// Protected
/**************************************************************************/

WSPoint* WSSeed::get_first_point()
{
  GMutexHolder lmh(mListMutex);
  Stepper<WSPoint> s(this);
  if(s.step()) return *s;
  return 0;
}

ZTrans* WSSeed::init_slide(WSPoint* f)
{
  if(f == 0) f = get_first_point();
  if(f == 0) return 0;
  return new ZTrans(f->RefTrans());
}

void WSSeed::ring(ZTrans& lcf, WSPoint* f, Double_t t)
{
  Double_t *Pnt = lcf.ArrT();
  Double_t *Axe = lcf.ArrX(), *Up = lcf.ArrY(), *Aw = lcf.ArrZ();

  const Double_t t2 = t*t, t3 = t2*t;

  for (Int_t i=0; i<3; i++)
  {
    Pnt[i] = f->mCoffs(i, 0) + f->mCoffs(i, 1)*t +
      f->mCoffs(i, 2)*t2 + f->mCoffs(i, 3)*t3;
    Axe[i] = f->mCoffs(i, 1) + 2*f->mCoffs(i, 2)*t +
      3*f->mCoffs(i, 3)*t2;
  }
  Double_t w = f->mCoffs(3, 0) + f->mCoffs(3, 1)*t +
    f->mCoffs(3, 2)*t2 + f->mCoffs(3, 3)*t3;
  Double_t dwdt = TMath::ATan(f->mCoffs(3, 1) + 2*f->mCoffs(3, 2)*t +
			      3*f->mCoffs(3, 3)*t2);
  Double_t dwc = TMath::Cos(dwdt);
  Double_t dws = TMath::Sin(dwdt);

  lcf.OrtoNorm3();

  pTuber->NewRing(mPLevel, true);
  Double_t phi = 0, step = 2*TMath::Pi()/mPLevel;
  Float_t R[3], N[3], T[2];
  for (int j=0; j<mPLevel; j++, phi-=step)
  {
    Double_t cp = TMath::Cos(phi), sp = TMath::Sin(phi);
    for (Int_t i=0; i<3; ++i)
    {
      R[i] = Pnt[i] + cp*w*Up[i] + sp*w*Aw[i];
      N[i] = -dws*Axe[i] + dwc*(cp*Up[i] + sp*Aw[i]);
    }
    // perhaps should invert normals for w<0
    T[0] = hTexU; T[1] = hTexV  - phi/TMath::TwoPi();
    pTuber->NewVert(R, N, 0, T);
  }
  { // last one
    phi = -TMath::TwoPi();
    Double_t cp = TMath::Cos(phi), sp = TMath::Sin(phi);
    for (Int_t i=0; i<3; ++i)
    {
      R[i] = Pnt[i] + cp*w*Up[i] + sp*w*Aw[i];
      N[i] = -dws*Axe[i] + dwc*(cp*Up[i] + sp*Aw[i]);
    }
    // perhaps should invert normals for w<0
    T[0] = hTexU; T[1] = hTexV + 1;
    pTuber->NewVert(R, N, 0, T);
  }

}

/**************************************************************************/
// Animation, TimeTick
/**************************************************************************/

void WSSeed::StartAnimation()
{
  if(bAnimRunning) return;

  {
    GLensWriteHolder wlck(this);
    bAnimRunning = true;
    Stamp(FID());
  }
  Double_t dt = 0;
  while(bAnimRunning) {
    TimeTick(mAnimTime, dt);
    dt = 0.001*mAnimSleepMS*mAnimStepFac;
    GTime::SleepMiliSec(mAnimSleepMS);
    mAnimTime += dt;
  }
}

void WSSeed::StopAnimation()
{
  if(!bAnimRunning) return;
  bAnimRunning = false;
  Stamp(FID());
}

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

void WSSeed::TimeTick(Double_t t, Double_t dt)
{
  GLensWriteHolder wlck(this);
  if(mDtexU != 0 || mDtexV != 0) {
    mTexUOffset += dt*mDtexU;
    mTexVOffset += dt*mDtexV;
    if(++m_anim_tick % 1000 == 0) {
      if(mTexUOffset >  100) mTexUOffset -= 200;
      if(mTexUOffset < -100) mTexUOffset += 200;
      if(mTexVOffset >  100) mTexVOffset -= 200;
      if(mTexVOffset < -100) mTexVOffset += 200;
    }
    Stamp(FID());
  }
}

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



void WSSeed::MakeLissajou(Double_t t_min, Double_t t_max, Int_t n_points,
			  Double_t ax, Double_t wx, Double_t dx,
			  Double_t ay, Double_t wy, Double_t dy,
			  Double_t az, Double_t wz, Double_t dz,
			  Float_t def_width)
{
  // Creates a WeaverSymbol following a Lissajou curve.
  // Each coordinate specified as: x(t) = ax * sin(wx * t + dx).

  ClearList();

  using namespace TMath;

  Double_t step = (t_max - t_min) / (n_points - 1);
  Double_t t    = t_min;

  ZTrans trans;
  for(Int_t i=1; i<=n_points; ++i, t+=step) {
    if(i == n_points) t = t_max;

    Double_t pos_x = ax*Sin(wx*t + dx);
    Double_t pos_y = ay*Sin(wy*t + dy);
    Double_t pos_z = az*Sin(wz*t + dz);
    Double_t der_x = ax*wx*Cos(wx*t + dx);
    Double_t der_y = ay*wy*Cos(wy*t + dy);
    Double_t der_z = az*wz*Cos(wz*t + dz);

    trans.SetPos(pos_x, pos_y, pos_z);
    trans.SetBaseVec(1, der_x, der_y, der_z);
    trans.OrtoNorm3();

    WSPoint* p = new WSPoint(GForm("Point %d", i));
    p->SetTrans(trans);
    p->mW = def_width;

    mQueen->CheckIn(p);
    Add(p);
  }

  mStampReqTring = Stamp(FID());
}

void WSSeed::MakeFromFormulas(Double_t t_min, Double_t t_max, Int_t n_points,
			      TString fx, TString fy, TString fz,
			      Float_t def_width)
{
  // Creates a WeaverSymbol following formulas for x, y and z.
  // The name of the time variable in formulas is 'x' and thus one
  // should write, eg: "0.5*x^2".

  ClearList();

  using namespace TMath;

  Double_t step = (t_max - t_min) / (n_points - 1);
  Double_t t    = t_min;

  TF1 tfx(GForm("WSSeed_x_%d", GetSaturnID()), fx.Data(), t_min, t_max);
  TF1 tfy(GForm("WSSeed_y_%d", GetSaturnID()), fy.Data(), t_min, t_max);
  TF1 tfz(GForm("WSSeed_z_%d", GetSaturnID()), fz.Data(), t_min, t_max);

  ZTrans trans;
  for(Int_t i=1; i<=n_points; ++i, t+=step) {
    if(i == n_points) t = t_max;

    Double_t pos_x = tfx.Eval(t);
    Double_t pos_y = tfy.Eval(t);
    Double_t pos_z = tfz.Eval(t);
    Double_t der_x = tfx.Derivative(t);
    Double_t der_y = tfy.Derivative(t);
    Double_t der_z = tfz.Derivative(t);

    trans.SetPos(pos_x, pos_y, pos_z);
    trans.SetBaseVec(1, der_x, der_y, der_z);
    trans.OrtoNorm3();

    WSPoint* p = new WSPoint(GForm("Point %d", i));
    p->SetTrans(trans);
    p->mW = def_width;

    mQueen->CheckIn(p);
    Add(p);
  }

  mStampReqTring = Stamp(FID());
}
 WSSeed.cxx:1
 WSSeed.cxx:2
 WSSeed.cxx:3
 WSSeed.cxx:4
 WSSeed.cxx:5
 WSSeed.cxx:6
 WSSeed.cxx:7
 WSSeed.cxx:8
 WSSeed.cxx:9
 WSSeed.cxx:10
 WSSeed.cxx:11
 WSSeed.cxx:12
 WSSeed.cxx:13
 WSSeed.cxx:14
 WSSeed.cxx:15
 WSSeed.cxx:16
 WSSeed.cxx:17
 WSSeed.cxx:18
 WSSeed.cxx:19
 WSSeed.cxx:20
 WSSeed.cxx:21
 WSSeed.cxx:22
 WSSeed.cxx:23
 WSSeed.cxx:24
 WSSeed.cxx:25
 WSSeed.cxx:26
 WSSeed.cxx:27
 WSSeed.cxx:28
 WSSeed.cxx:29
 WSSeed.cxx:30
 WSSeed.cxx:31
 WSSeed.cxx:32
 WSSeed.cxx:33
 WSSeed.cxx:34
 WSSeed.cxx:35
 WSSeed.cxx:36
 WSSeed.cxx:37
 WSSeed.cxx:38
 WSSeed.cxx:39
 WSSeed.cxx:40
 WSSeed.cxx:41
 WSSeed.cxx:42
 WSSeed.cxx:43
 WSSeed.cxx:44
 WSSeed.cxx:45
 WSSeed.cxx:46
 WSSeed.cxx:47
 WSSeed.cxx:48
 WSSeed.cxx:49
 WSSeed.cxx:50
 WSSeed.cxx:51
 WSSeed.cxx:52
 WSSeed.cxx:53
 WSSeed.cxx:54
 WSSeed.cxx:55
 WSSeed.cxx:56
 WSSeed.cxx:57
 WSSeed.cxx:58
 WSSeed.cxx:59
 WSSeed.cxx:60
 WSSeed.cxx:61
 WSSeed.cxx:62
 WSSeed.cxx:63
 WSSeed.cxx:64
 WSSeed.cxx:65
 WSSeed.cxx:66
 WSSeed.cxx:67
 WSSeed.cxx:68
 WSSeed.cxx:69
 WSSeed.cxx:70
 WSSeed.cxx:71
 WSSeed.cxx:72
 WSSeed.cxx:73
 WSSeed.cxx:74
 WSSeed.cxx:75
 WSSeed.cxx:76
 WSSeed.cxx:77
 WSSeed.cxx:78
 WSSeed.cxx:79
 WSSeed.cxx:80
 WSSeed.cxx:81
 WSSeed.cxx:82
 WSSeed.cxx:83
 WSSeed.cxx:84
 WSSeed.cxx:85
 WSSeed.cxx:86
 WSSeed.cxx:87
 WSSeed.cxx:88
 WSSeed.cxx:89
 WSSeed.cxx:90
 WSSeed.cxx:91
 WSSeed.cxx:92
 WSSeed.cxx:93
 WSSeed.cxx:94
 WSSeed.cxx:95
 WSSeed.cxx:96
 WSSeed.cxx:97
 WSSeed.cxx:98
 WSSeed.cxx:99
 WSSeed.cxx:100
 WSSeed.cxx:101
 WSSeed.cxx:102
 WSSeed.cxx:103
 WSSeed.cxx:104
 WSSeed.cxx:105
 WSSeed.cxx:106
 WSSeed.cxx:107
 WSSeed.cxx:108
 WSSeed.cxx:109
 WSSeed.cxx:110
 WSSeed.cxx:111
 WSSeed.cxx:112
 WSSeed.cxx:113
 WSSeed.cxx:114
 WSSeed.cxx:115
 WSSeed.cxx:116
 WSSeed.cxx:117
 WSSeed.cxx:118
 WSSeed.cxx:119
 WSSeed.cxx:120
 WSSeed.cxx:121
 WSSeed.cxx:122
 WSSeed.cxx:123
 WSSeed.cxx:124
 WSSeed.cxx:125
 WSSeed.cxx:126
 WSSeed.cxx:127
 WSSeed.cxx:128
 WSSeed.cxx:129
 WSSeed.cxx:130
 WSSeed.cxx:131
 WSSeed.cxx:132
 WSSeed.cxx:133
 WSSeed.cxx:134
 WSSeed.cxx:135
 WSSeed.cxx:136
 WSSeed.cxx:137
 WSSeed.cxx:138
 WSSeed.cxx:139
 WSSeed.cxx:140
 WSSeed.cxx:141
 WSSeed.cxx:142
 WSSeed.cxx:143
 WSSeed.cxx:144
 WSSeed.cxx:145
 WSSeed.cxx:146
 WSSeed.cxx:147
 WSSeed.cxx:148
 WSSeed.cxx:149
 WSSeed.cxx:150
 WSSeed.cxx:151
 WSSeed.cxx:152
 WSSeed.cxx:153
 WSSeed.cxx:154
 WSSeed.cxx:155
 WSSeed.cxx:156
 WSSeed.cxx:157
 WSSeed.cxx:158
 WSSeed.cxx:159
 WSSeed.cxx:160
 WSSeed.cxx:161
 WSSeed.cxx:162
 WSSeed.cxx:163
 WSSeed.cxx:164
 WSSeed.cxx:165
 WSSeed.cxx:166
 WSSeed.cxx:167
 WSSeed.cxx:168
 WSSeed.cxx:169
 WSSeed.cxx:170
 WSSeed.cxx:171
 WSSeed.cxx:172
 WSSeed.cxx:173
 WSSeed.cxx:174
 WSSeed.cxx:175
 WSSeed.cxx:176
 WSSeed.cxx:177
 WSSeed.cxx:178
 WSSeed.cxx:179
 WSSeed.cxx:180
 WSSeed.cxx:181
 WSSeed.cxx:182
 WSSeed.cxx:183
 WSSeed.cxx:184
 WSSeed.cxx:185
 WSSeed.cxx:186
 WSSeed.cxx:187
 WSSeed.cxx:188
 WSSeed.cxx:189
 WSSeed.cxx:190
 WSSeed.cxx:191
 WSSeed.cxx:192
 WSSeed.cxx:193
 WSSeed.cxx:194
 WSSeed.cxx:195
 WSSeed.cxx:196
 WSSeed.cxx:197
 WSSeed.cxx:198
 WSSeed.cxx:199
 WSSeed.cxx:200
 WSSeed.cxx:201
 WSSeed.cxx:202
 WSSeed.cxx:203
 WSSeed.cxx:204
 WSSeed.cxx:205
 WSSeed.cxx:206
 WSSeed.cxx:207
 WSSeed.cxx:208
 WSSeed.cxx:209
 WSSeed.cxx:210
 WSSeed.cxx:211
 WSSeed.cxx:212
 WSSeed.cxx:213
 WSSeed.cxx:214
 WSSeed.cxx:215
 WSSeed.cxx:216
 WSSeed.cxx:217
 WSSeed.cxx:218
 WSSeed.cxx:219
 WSSeed.cxx:220
 WSSeed.cxx:221
 WSSeed.cxx:222
 WSSeed.cxx:223
 WSSeed.cxx:224
 WSSeed.cxx:225
 WSSeed.cxx:226
 WSSeed.cxx:227
 WSSeed.cxx:228
 WSSeed.cxx:229
 WSSeed.cxx:230
 WSSeed.cxx:231
 WSSeed.cxx:232
 WSSeed.cxx:233
 WSSeed.cxx:234
 WSSeed.cxx:235
 WSSeed.cxx:236
 WSSeed.cxx:237
 WSSeed.cxx:238
 WSSeed.cxx:239
 WSSeed.cxx:240
 WSSeed.cxx:241
 WSSeed.cxx:242
 WSSeed.cxx:243
 WSSeed.cxx:244
 WSSeed.cxx:245
 WSSeed.cxx:246
 WSSeed.cxx:247
 WSSeed.cxx:248
 WSSeed.cxx:249
 WSSeed.cxx:250
 WSSeed.cxx:251
 WSSeed.cxx:252
 WSSeed.cxx:253
 WSSeed.cxx:254
 WSSeed.cxx:255
 WSSeed.cxx:256
 WSSeed.cxx:257
 WSSeed.cxx:258
 WSSeed.cxx:259
 WSSeed.cxx:260
 WSSeed.cxx:261
 WSSeed.cxx:262
 WSSeed.cxx:263
 WSSeed.cxx:264
 WSSeed.cxx:265
 WSSeed.cxx:266
 WSSeed.cxx:267
 WSSeed.cxx:268
 WSSeed.cxx:269
 WSSeed.cxx:270
 WSSeed.cxx:271
 WSSeed.cxx:272
 WSSeed.cxx:273
 WSSeed.cxx:274
 WSSeed.cxx:275
 WSSeed.cxx:276
 WSSeed.cxx:277
 WSSeed.cxx:278
 WSSeed.cxx:279
 WSSeed.cxx:280
 WSSeed.cxx:281
 WSSeed.cxx:282
 WSSeed.cxx:283
 WSSeed.cxx:284
 WSSeed.cxx:285
 WSSeed.cxx:286
 WSSeed.cxx:287
 WSSeed.cxx:288
 WSSeed.cxx:289
 WSSeed.cxx:290
 WSSeed.cxx:291
 WSSeed.cxx:292
 WSSeed.cxx:293
 WSSeed.cxx:294
 WSSeed.cxx:295
 WSSeed.cxx:296
 WSSeed.cxx:297
 WSSeed.cxx:298
 WSSeed.cxx:299
 WSSeed.cxx:300
 WSSeed.cxx:301
 WSSeed.cxx:302
 WSSeed.cxx:303
 WSSeed.cxx:304
 WSSeed.cxx:305
 WSSeed.cxx:306
 WSSeed.cxx:307
 WSSeed.cxx:308
 WSSeed.cxx:309
 WSSeed.cxx:310
 WSSeed.cxx:311
 WSSeed.cxx:312
 WSSeed.cxx:313
 WSSeed.cxx:314
 WSSeed.cxx:315
 WSSeed.cxx:316
 WSSeed.cxx:317
 WSSeed.cxx:318
 WSSeed.cxx:319
 WSSeed.cxx:320
 WSSeed.cxx:321
 WSSeed.cxx:322
 WSSeed.cxx:323
 WSSeed.cxx:324
 WSSeed.cxx:325
 WSSeed.cxx:326
 WSSeed.cxx:327
 WSSeed.cxx:328
 WSSeed.cxx:329
 WSSeed.cxx:330
 WSSeed.cxx:331
 WSSeed.cxx:332
 WSSeed.cxx:333
 WSSeed.cxx:334
 WSSeed.cxx:335
 WSSeed.cxx:336
 WSSeed.cxx:337
 WSSeed.cxx:338
 WSSeed.cxx:339
 WSSeed.cxx:340
 WSSeed.cxx:341
 WSSeed.cxx:342
 WSSeed.cxx:343
 WSSeed.cxx:344
 WSSeed.cxx:345
 WSSeed.cxx:346
 WSSeed.cxx:347
 WSSeed.cxx:348
 WSSeed.cxx:349
 WSSeed.cxx:350
 WSSeed.cxx:351
 WSSeed.cxx:352
 WSSeed.cxx:353
 WSSeed.cxx:354
 WSSeed.cxx:355
 WSSeed.cxx:356
 WSSeed.cxx:357
 WSSeed.cxx:358
 WSSeed.cxx:359
 WSSeed.cxx:360
 WSSeed.cxx:361
 WSSeed.cxx:362
 WSSeed.cxx:363
 WSSeed.cxx:364
 WSSeed.cxx:365
 WSSeed.cxx:366
 WSSeed.cxx:367
 WSSeed.cxx:368
 WSSeed.cxx:369
 WSSeed.cxx:370
 WSSeed.cxx:371
 WSSeed.cxx:372
 WSSeed.cxx:373
 WSSeed.cxx:374
 WSSeed.cxx:375
 WSSeed.cxx:376
 WSSeed.cxx:377
 WSSeed.cxx:378
 WSSeed.cxx:379
 WSSeed.cxx:380
 WSSeed.cxx:381
 WSSeed.cxx:382
 WSSeed.cxx:383
 WSSeed.cxx:384
 WSSeed.cxx:385
 WSSeed.cxx:386
 WSSeed.cxx:387
 WSSeed.cxx:388
 WSSeed.cxx:389
 WSSeed.cxx:390
 WSSeed.cxx:391
 WSSeed.cxx:392
 WSSeed.cxx:393
 WSSeed.cxx:394
 WSSeed.cxx:395
 WSSeed.cxx:396
 WSSeed.cxx:397
 WSSeed.cxx:398
 WSSeed.cxx:399
 WSSeed.cxx:400
 WSSeed.cxx:401
 WSSeed.cxx:402
 WSSeed.cxx:403
 WSSeed.cxx:404
 WSSeed.cxx:405
 WSSeed.cxx:406
 WSSeed.cxx:407
 WSSeed.cxx:408
 WSSeed.cxx:409
 WSSeed.cxx:410
 WSSeed.cxx:411
 WSSeed.cxx:412
 WSSeed.cxx:413
 WSSeed.cxx:414
 WSSeed.cxx:415
 WSSeed.cxx:416
 WSSeed.cxx:417
 WSSeed.cxx:418
 WSSeed.cxx:419
 WSSeed.cxx:420
 WSSeed.cxx:421
 WSSeed.cxx:422
 WSSeed.cxx:423
 WSSeed.cxx:424
 WSSeed.cxx:425
 WSSeed.cxx:426
 WSSeed.cxx:427
 WSSeed.cxx:428
 WSSeed.cxx:429
 WSSeed.cxx:430
 WSSeed.cxx:431
 WSSeed.cxx:432
 WSSeed.cxx:433
 WSSeed.cxx:434
 WSSeed.cxx:435
 WSSeed.cxx:436
 WSSeed.cxx:437
 WSSeed.cxx:438
 WSSeed.cxx:439
 WSSeed.cxx:440
 WSSeed.cxx:441
 WSSeed.cxx:442
 WSSeed.cxx:443
 WSSeed.cxx:444
 WSSeed.cxx:445
 WSSeed.cxx:446
 WSSeed.cxx:447
 WSSeed.cxx:448
 WSSeed.cxx:449
 WSSeed.cxx:450
 WSSeed.cxx:451
 WSSeed.cxx:452
 WSSeed.cxx:453
 WSSeed.cxx:454
 WSSeed.cxx:455
 WSSeed.cxx:456
 WSSeed.cxx:457
 WSSeed.cxx:458
 WSSeed.cxx:459
 WSSeed.cxx:460
 WSSeed.cxx:461
 WSSeed.cxx:462
 WSSeed.cxx:463
 WSSeed.cxx:464
 WSSeed.cxx:465
 WSSeed.cxx:466
 WSSeed.cxx:467
 WSSeed.cxx:468
 WSSeed.cxx:469
 WSSeed.cxx:470
 WSSeed.cxx:471
 WSSeed.cxx:472
 WSSeed.cxx:473
 WSSeed.cxx:474
 WSSeed.cxx:475
 WSSeed.cxx:476
 WSSeed.cxx:477
 WSSeed.cxx:478
 WSSeed.cxx:479
 WSSeed.cxx:480
 WSSeed.cxx:481
 WSSeed.cxx:482
 WSSeed.cxx:483
 WSSeed.cxx:484
 WSSeed.cxx:485
 WSSeed.cxx:486
 WSSeed.cxx:487
 WSSeed.cxx:488
 WSSeed.cxx:489
 WSSeed.cxx:490
 WSSeed.cxx:491
 WSSeed.cxx:492
 WSSeed.cxx:493
 WSSeed.cxx:494
 WSSeed.cxx:495
 WSSeed.cxx:496
 WSSeed.cxx:497
 WSSeed.cxx:498
 WSSeed.cxx:499
 WSSeed.cxx:500
 WSSeed.cxx:501
 WSSeed.cxx:502
 WSSeed.cxx:503
 WSSeed.cxx:504
 WSSeed.cxx:505
 WSSeed.cxx:506
 WSSeed.cxx:507
 WSSeed.cxx:508
 WSSeed.cxx:509
 WSSeed.cxx:510
 WSSeed.cxx:511
 WSSeed.cxx:512
 WSSeed.cxx:513
 WSSeed.cxx:514
 WSSeed.cxx:515
 WSSeed.cxx:516
 WSSeed.cxx:517
 WSSeed.cxx:518
 WSSeed.cxx:519
 WSSeed.cxx:520
 WSSeed.cxx:521
 WSSeed.cxx:522
 WSSeed.cxx:523
 WSSeed.cxx:524
 WSSeed.cxx:525
 WSSeed.cxx:526
 WSSeed.cxx:527
 WSSeed.cxx:528
 WSSeed.cxx:529
 WSSeed.cxx:530
 WSSeed.cxx:531
 WSSeed.cxx:532