ROOT logo
// $Id: GTSIsoMaker.cxx 2502 2011-07-11 01:41:35Z 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/.

//__________________________________________________________________________
// GTSIsoMaker
//
//

#include "GTSIsoMaker.h"
#include "GTSIsoMaker.c7"
#include <Stones/GTSIsoMakerFunctor.h>
#include <GTS/GTS.h>

#include "TF3.h"
#include "TH1.h"
#include "TCanvas.h"
#include "Gled/XTReqCanvas.h"

ClassImp(GTSIsoMaker);

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

void GTSIsoMaker::_init()
{
  mTarget = 0;
  mAlgo   = A_Cartesian;
  mValue  = 0;
  mXmin = mYmin = mZmin = -1;
  mXmax = mYmax = mZmax =  1;
  mXdiv = mYdiv = mZdiv = 20;
  bInvertCartesian = bInvertTetra = false;
  mFixPointEpsilon = 1e-12;
  mFixPointMaxIter = 1000;
}

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

void GTSIsoMaker::SetXAxis(Double_t min, Double_t max, Int_t div)
{
  mXmin = min; mXmax = max; mXdiv = div;
  Stamp(FID());
}

void GTSIsoMaker::SetYAxis(Double_t min, Double_t max, Int_t div)
{
  mYmin = min; mYmax = max; mYdiv = div;
  Stamp(FID());
}

void GTSIsoMaker::SetZAxis(Double_t min, Double_t max, Int_t div)
{
  mZmin = min; mZmax = max; mZdiv = div;
  Stamp(FID());
}

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

namespace
{
  void form_to_plane(GTS::gdouble **a, GTS::GtsCartesianGrid g,
		     GTS::guint i, GTS::gpointer data)
  {
    Double_t z = g.z;
    // printf("form_to_plane called w/ i=%d => z=%lf\n", i, z);
    TF3& formula = *((TF3*)data);

    Double_t x = g.x;
    for(unsigned int nx=0; nx<g.nx; ++nx) {
      Double_t y = g.y;
      for(unsigned int ny=0; ny<g.ny; ++ny) {
	a[nx][ny] = formula.Eval(x, y, z);
	y += g.dy;
      }
      x += g.dx;
    }
  }

  void functor_to_plane(GTS::gdouble **a, GTS::GtsCartesianGrid g,
			GTS::guint i, GTS::gpointer data)
  {
    Double_t z = g.z;
    // printf("form_to_plane called w/ i=%d => z=%lf\n", i, z);
    GTSIsoMakerFunctor &functor = *((GTSIsoMakerFunctor*)data);

    Double_t x = g.x;
    for(unsigned int nx=0; nx<g.nx; ++nx) {
      Double_t y = g.y;
      for(unsigned int ny=0; ny<g.ny; ++ny) {
	a[nx][ny] = functor.GTSIsoFunc(x, y, z);
	y += g.dy;
      }
      x += g.dx;
    }
  }
}

void GTSIsoMaker::MakeSurface()
{
  static const Exc_t _eh("GTSIsoMaker::MakeSurface ");

  using namespace GTS;

  GTSurf* target = *mTarget;
  if (target == 0)
  {
    throw _eh + "Link Target should be set.";
  }

  GTS::gpointer            user_data = 0;
  GTS::GtsIsoCartesianFunc user_func = 0;

  GTSIsoMakerFunctor *functor = dynamic_cast<GTSIsoMakerFunctor*>(*mFunctor);
  TF3                *formula = 0;

  if (mFunctor != 0 && functor == 0)
  {
    throw _eh + "Link Functor is set, but it is not a GTSIsoMakerFunctor.";
  }

  if (functor)
  {
    user_data = functor;
    user_func = functor_to_plane;
    functor->GTSIsoBegin(this, mValue);
  }
  else
  {
    formula = new TF3;
    formula->Compile(mFormula);
    formula->SetRange(mXmin, mXmax, mYmin, mYmax, mZmin, mZmax);
    user_data = formula;
    user_func = form_to_plane;
  }

  GtsCartesianGrid grid = {
    mXdiv + 1, mYdiv + 1, mZdiv + 1,
    mXmin, (mXmax - mXmin) / mXdiv,
    mYmin, (mYmax - mYmin) / mYdiv,
    mZmin, (mZmax - mZmin) / mZdiv
  };

  GtsSurface* s = MakeDefaultSurface();

  switch (mAlgo)
  {
  case A_Cartesian:
    gts_isosurface_cartesian(s, grid, user_func, user_data, mValue);
    break;
  case A_Tetra:
    gts_isosurface_tetra(s, grid, user_func, user_data, mValue);
    break;
  case A_TetraBounded:
    gts_isosurface_tetra_bounded(s, grid, user_func, user_data, mValue);
    break;
  case A_TetraBCL:
    gts_isosurface_tetra_bcl(s, grid, user_func, user_data, mValue);
    break;
  }

  if (functor)
  {
    functor->GTSIsoEnd();
  }
  else
  {
    delete formula;
  }

  if ((mAlgo == A_Cartesian && bInvertCartesian) ||
      (mAlgo >  A_Cartesian && bInvertTetra))
  {
    GTS::InvertSurface(s);
  }

  target->WriteLock();
  target->ReplaceSurface(s);
  target->WriteUnlock();
}

//==============================================================================

namespace
{
  struct iso_compare_arg
  {
    GTSIsoMakerFunctor *functor;
    TH1                *histo;
    Double_t            iso_value;

    iso_compare_arg(GTSIsoMakerFunctor *f, TH1 *h, Double_t v) :
      functor(f), histo(h), iso_value(v)
    {}
  };

  void vertex_iso_comparator(GTS::GtsVertex* v, iso_compare_arg* arg)
  {
    arg->histo->Fill(arg->functor->GTSIsoFunc(v->p.x, v->p.y, v->p.z) - arg->iso_value);
  }
}

void GTSIsoMaker::MakeIsoDistanceHisto(const TString& canvas_name,
				       const TString& canvas_title)
{
  // Calculate difference from iso-value for all points of target and
  // histogram it.

  static const Exc_t _eh("GTSIsoMaker::MakeIsoDistanceHisto ");

  using namespace GTS;

  GTSurf* target = *mTarget;
  if (target == 0)
    throw _eh + "Link Target should be set.";

  GtsSurface *surf = target->GetSurf();
  if (surf == 0)
    throw _eh + "Target must have non-null surface.";

  GTSIsoMakerFunctor *functor = dynamic_cast<GTSIsoMakerFunctor*>(*mFunctor);
  if (functor == 0)
    throw _eh + "Link Functor must be set to a GTSIsoMakerFunctor.";

  TH1I *h = new TH1I("IsoDelta", "Func at Vertex - IsoValue", 256, 0, 0);
  h->SetBuffer(10000);

  iso_compare_arg arg(functor, h, mValue);
  
  functor->GTSIsoBegin(this, mValue);
  gts_surface_foreach_vertex(surf, (GtsFunc) vertex_iso_comparator, &arg);
  functor->GTSIsoEnd();

  TCanvas *canvas = XTReqCanvas::Request(canvas_name, canvas_title);
  canvas->cd();
  h->Draw();
  XTReqPadUpdate::Update(canvas);
}

//==============================================================================

namespace
{
  struct iso_fix_arg
  {
    GTSIsoMakerFunctor *functor;
    Double_t            iso_value;
    Double_t            iso_epsilon;
    Int_t               max_iter;
    Int_t               n_fail;

    iso_fix_arg(GTSIsoMakerFunctor *f, Double_t v, Double_t e, Int_t m) :
      functor(f), iso_value(v), iso_epsilon(e), max_iter(m), n_fail(0)
    {}
  };

  void vertex_iso_fixer(GTS::GtsVertex* v, iso_fix_arg* arg)
  {
    HPointD  g;
    Double_t f, d, k;
    Int_t N = 0;
    do
    {
      f = arg->functor->GTSIsoGradient(v->p.x, v->p.y, v->p.z, g);
      d = (arg->iso_value - f);
      k = d / g.Mag2();

      v->p.x += k * g.x;
      v->p.y += k * g.y;
      v->p.z += k * g.z;
    }
    while (TMath::Abs(d) > arg->iso_epsilon && ++N < arg->max_iter);

    if (N >= arg->max_iter) ++arg->n_fail;
  }
}

void GTSIsoMaker::MovePointsOntoIsoSurface()
{
  // Move points so that they have exactly iso value.

  static const Exc_t _eh("GTSIsoMaker::MovePointsOntoIsoSurface ");

  using namespace GTS;

  GTSurf* target = *mTarget;
  if (target == 0)
    throw _eh + "Link Target should be set.";

  GtsSurface *surf = target->GetSurf();
  if (surf == 0)
    throw _eh + "Target must have non-null surface.";

  GTSIsoMakerFunctor *functor = dynamic_cast<GTSIsoMakerFunctor*>(*mFunctor);
  if (functor == 0)
    throw _eh + "Link Functor must be set to a GTSIsoMakerFunctor.";


  iso_fix_arg arg(functor, mValue, mFixPointEpsilon, mFixPointMaxIter);
  
  functor->GTSIsoBegin(this, mValue);
  gts_surface_foreach_vertex(surf, (GtsFunc) vertex_iso_fixer, &arg);
  functor->GTSIsoEnd();

  if (arg.n_fail)
  {
    ISwarn(_eh + GForm("failed for %d points.", arg.n_fail));
  }

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