<commit_before>//--------------------------------------------------------------------------
//          Test for the LUdivine LUP factorisation
//--------------------------------------------------------------------------
// Clement Pernet, Morgan Brassel
// 17/06/2002
// Last modified 02/04/2003
// usage: Test_LUdivine p A n, for n LUP fatorisation of A over Z/pZ
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
#define DEBUG 0
// Debug option  0: no debug
//               1: check A = LUP
//               2: trace the recursive algorithm
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
// Diplay positions of errors in LUP!=A
#define DISP_ERRORS 0
//-------------------------------------------------------------------------

#include <iostream.h>
#include "givinit.h"
#include "givgfq.h"
#include "givtimer.h"
#include "Matio.h"
#include "givzpz32std.h"
#include "FFLAP.h"

using namespace std;

//----------------------------------------------------------------------------
// Choice of the finite field representation
//typedef GFqDom<long> GFqDomain;
typedef ZpzDom<Std32> GFqDomain;
//----------------------------------------------------------------------------

int main(int argc, char** argv){
  int i,j,m,n,nbf,R;
  GFqDomain F(atoi(argv[1]));
  GFqDomain::element * A;

  A = read_field(F,argv[2],&m,&n);

  size_t *Permut = new size_t[n];
  for ( i=0;i<m;i++)
    Permut[i]=0;
#if DEBUG
  GFqDomain::element  * A_debug = new GFqDomain::element[m*n];
  for ( i=0;i<m;i++)
    for ( j=0;j<n;j++){
      A_debug[j+n*i] = A[j+n*i];
    }
#endif
  nbf = atoi(argv[3]);

  Timer tim,tim1;
  tim.clear();

#if DEBUG==2
  cerr<<"A="<<endl;
  write_field(F,cerr,A,m,n,n);
#endif
  for ( i=0;i<nbf;i++){
    if (i) A = read_field(F,argv[2],&m,&n);
    for (j=0;j<n;j++)
      Permut[j]=0;
    tim1.clear();
    tim1.start();
    R = FFLAP::LUdivine( F, FFLAS::FflasUnit, m, n, A, n, Permut);
    tim1.stop();
    tim+=tim1;
#if DEBUG == 0
    delete[] A;
#endif
  }

#if DEBUG
  size_t MN=(m<n)?m:n;
  GFqDomain::element  U[m*n];
  GFqDomain::element  L[m*n];

  for ( i=0;i<m;i++){
    for (j=0;j<n;j++){
      if (j<=i){
	U[i*n+j]=F.zero;
      }
      else{
	U[i*n+j]=A[i*n+j];
      }
    }
    U[i+i*n]=F.one;
  }
  for ( i=0;i<m;i++){
    for ( j=0;j<n;j++){
      if (j<=i){
	L[i*n+j]=A[i*n+j];
      }
      else
	L[i*n+j]=F.zero;
    }
  }
#endif

#if DEBUG==2
  cerr<<"L="<<endl;
  write_field(F,cerr,L,m,n,n);
  cerr<<"U="<<endl;
  write_field(F,cerr,U,m,n,n);
#endif
#if DEBUG
  FFLAS::fgemm(F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,MN,F.one,L,n,U,n,
		 F.zero,U,n);
#endif
#if DEBUG==2
  cerr<<"L*U="<<endl;
  write_field(F,cerr,U,m,n,n);
#endif
  // Apply P
#if DEBUG
  int affiche=0;
  size_t nl = n;
  FFLAP::flaswp(F, m, U, nl, 0, R, Permut, -1);
  for ( i=0;i<m;++i){
    for ( j=0;j<n;++j){
      if (!F.areEqual(A_debug[n*i+j],U[n*i+j])){
	//cerr<< " error in i="<<i<<" j="<<j<<endl;
#if DISP_ERRORS
	cerr << "X ";
#endif
	affiche=1;
      }
      else{
#if DISP_ERRORS
	cerr << ". ";
#endif
      }
    }
#if DISP_ERRORS
    cerr<<endl;
#endif
  }
  if (affiche) cerr<<"Error occured during in computation: A!=LUP"<<endl;
#endif
#if DEBUG==2
  cerr<< "L*U*P ="<<endl;
  write_field(F, cerr, U,m,n,n);
  write_field(F,cerr, A,m,n,n);
#endif

  double t = tim.usertime();
  double numops = m*m/1000.0*(m+3*n)/6.0;

   cerr
   	    <<m
   	    <<"x"
  	    << n
   	    << " : rank = " << R << "  ["
   	    << ((double)nbf/1000.0*(double)numops / t)
   	    << " MFops "
   	    << " in "
   	    << t<<"s]"
   	    << endl;
  cout<<m<<" "<<((double)nbf/1000.0*(double)numops / t)<<endl;

  return 0;
}

<commit_msg>The test for LSP=A is now valid for S having zero rows<commit_after>//--------------------------------------------------------------------------
//          Test for the LUdivine LUP factorisation
//--------------------------------------------------------------------------
// Clement Pernet, Morgan Brassel
// 17/06/2002
// Last modified 02/04/2003
// usage: Test_LUdivine p A n, for n LUP fatorisation of A over Z/pZ
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
#define DEBUG 1
// Debug option  0: no debug
//               1: check A = LUP
//               2: trace the recursive algorithm
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
// Diplay positions of errors in LUP!=A
#define DISP_ERRORS 1
//-------------------------------------------------------------------------

#include <iostream.h>
#include "givinit.h"
#include "givgfq.h"
#include "givtimer.h"
#include "Matio.h"
#include "givzpz32std.h"
#include "FFLAP.h"

using namespace std;

//----------------------------------------------------------------------------
// Choice of the finite field representation
//typedef GFqDom<long> GFqDomain;
typedef ZpzDom<Std32> GFqDomain;
//----------------------------------------------------------------------------

int main(int argc, char** argv){
  int i,j,m,n,nbf,R;
  GFqDomain F(atoi(argv[1]));
  GFqDomain::element * A;

  A = read_field(F,argv[2],&m,&n);

  size_t *Permut = new size_t[n];
  for ( i=0;i<m;i++)
    Permut[i]=0;
#if DEBUG
  GFqDomain::element  * A_debug = new GFqDomain::element[m*n];
  for ( i=0;i<m;i++)
    for ( j=0;j<n;j++){
      A_debug[j+n*i] = A[j+n*i];
    }
#endif
  nbf = atoi(argv[3]);

  Timer tim,tim1;
  tim.clear();

#if DEBUG==1
  cerr<<"A="<<endl;
  write_field(F,cerr,A,m,n,n);
#endif
  for ( i=0;i<nbf;i++){
    if (i) A = read_field(F,argv[2],&m,&n);
    for (j=0;j<n;j++)
      Permut[j]=0;
    tim1.clear();
    tim1.start();
    R = FFLAP::LUdivine( F, FFLAS::FflasNonUnit, m, n, A, n, Permut, FFLAP:: FflapLSP);
    tim1.stop();
    tim+=tim1;
#if DEBUG == 0
    delete[] A;
#endif
  }

#if DEBUG
  size_t MN=(m<n)?m:n;
  GFqDomain::element  U[m*n];
  GFqDomain::element  L[m*m];

  size_t pivot = 0;
  for ( i=0;i<n;i++){
    if (!F.iszero(A[i*n+pivot])){
       for (j=0;j<pivot;++j)
	 U[i*n+j]=F.zero;
       for (j=pivot;j<n;++j)
	 U[i*n+j]=A[i*n+j];
       pivot++;
    }
    else{
      for (j=0;j<=pivot;++j)
	U[i*n+j]=F.zero;
      for (j=pivot+1;j<n;++j)
	U[i*n+j]=A[i*n+j];
    }
  }

  size_t jl=0;
  pivot = 0;
  for ( j=0;j<R;++j){
    for ( i=0; i<pivot;++i){
      L[i*m+jl] = F.zero;
    }
    L[pivot*m+jl] = F.one;
    for ( i=pivot+1;i<m;++i){
      L[i*m+jl] = A[i*n+j];
    }
    // search for the next non zero pivot
    pivot++;
    jl++;
    while ( F.iszero ( A[j+1+n*pivot]) && jl<m){
      // inserting 0 column in L
      for ( i = 0; i<m; ++i )
	L[i*m+jl] = F.zero;
      pivot++;
      jl++;
    }

  }

#endif

  #if DEBUG==1
  cerr<<"L="<<endl;
  write_field(F,cerr,L,m,m,m);
  cerr<<"U="<<endl;
  write_field(F,cerr,U,m,n,n);
  #endif
#if DEBUG
  FFLAS::fgemm(F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,MN,F.one,L,n,U,n,
		 F.zero,U,n);
#endif
#if DEBUG==2
  cerr<<"L*U="<<endl;
  write_field(F,cerr,U,m,n,n);
#endif
  // Apply P
#if DEBUG
  int affiche=0;
  size_t nl = n;
  FFLAP::flaswp(F, m, U, nl, 0, R, Permut, -1);
  for ( i=0;i<m;++i){
    for ( j=0;j<n;++j){
      if (!F.areEqual(A_debug[n*i+j],U[n*i+j])){
	//cerr<< " error in i="<<i<<" j="<<j<<endl;
#if DISP_ERRORS
	cerr << "X ";
#endif
	affiche=1;
      }
      else{
#if DISP_ERRORS
	cerr << ". ";
#endif
      }
    }
#if DISP_ERRORS
    cerr<<endl;
#endif
  }
  if (affiche) cerr<<"Error occured during in computation: A!=LUP"<<endl;
#endif
#if DEBUG==1
  cerr<< "L*U*P ="<<endl;
  write_field(F, cerr, U,m,n,n);
  write_field(F,cerr, A,m,n,n);
#endif

  double t = tim.realtime();
  double numops = m*m/1000.0*(m+3*n)/6.0;

   cerr
   	    <<m
   	    <<"x"
  	    << n
   	    << " : rank = " << R << "  ["
   	    << ((double)nbf/1000.0*(double)numops / t)
   	    << " MFops "
   	    << " in "
   	    << t<<"s]"
   	    << endl;
  cout<<m<<" "<<((double)nbf/1000.0*(double)numops / t)<<endl;

  return 0;
}

<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName         :    AFCPropertyMgr.cpp
//    @Author           :    Ark Game Tech
//    @Date             :    2012-03-01
//    @Module           :    AFCPropertyMgr
//
// -------------------------------------------------------------------------

#include "AFCPropertyMgr.h"

AFCPropertyMgr::AFCPropertyMgr(const AFGUID& self)
{
    mxSelf = self;
}

AFCPropertyMgr::~AFCPropertyMgr()
{
    Clear();
}

void AFCPropertyMgr::Clear()
{
    for (size_t i = 0; i < mxPropertys.size(); ++i)
    {
        delete mxPropertys[i];
    }

    mxPropertys.clear();
    mxIndices.Clear();
}

const AFGUID& AFCPropertyMgr::Self() const
{
    return mxSelf;
}

bool AFCPropertyMgr::RegisterCallback(const std::string& strProperty, const PROPERTY_EVENT_FUNCTOR_PTR& cb)
{
    size_t index;
    if (!FindIndex(strProperty.c_str(), index))
    {
        return false;
    }

    mxPropertyCBs.emplace(std::make_pair(strProperty.c_str(), cb));
    return true;
}

bool AFCPropertyMgr::FindIndex(const char* name, size_t& index)
{
    if (!mxIndices.GetData(name, index))
    {
        return false;
    }

    return true;
}

bool AFCPropertyMgr::OnPropertyCallback(const char* name, const AFIData& oldData, const AFIData& newData)
{
    if (mxPropertyCBs.empty())
    {
        return false;
    }

    for (auto& iter : mxPropertyCBs)
    {
        (*(iter.second))(mxSelf, name, oldData, newData);
    }

    return true;
}

bool AFCPropertyMgr::AddProperty(const char* name, const AFIData& value, bool bPublic, bool bPrivate, bool bSave, bool bRealTime)
{
    AFProperty* pProperty = new AFProperty();
    pProperty->name = name;
    pProperty->prop_value = value;
    pProperty->bPublic = bPublic;
    pProperty->bPrivate = bPrivate;
    pProperty->bSave = bSave;
    pProperty->bRealtime = bRealTime;
    mxIndices.Add(name, mxPropertys.size());
    mxPropertys.push_back(pProperty);

    return true;
}

bool AFCPropertyMgr::SetProperty(const char* name, const AFIData& value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    mxPropertys[index]->prop_value = value;

    //TODO:call cb

    return true;
}

bool AFCPropertyMgr::SetPropertyBool(const char* name, const bool value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    bool oldValue = mxPropertys[index]->prop_value.GetBool();
    oldData.SetBool(oldValue);

    mxPropertys[index]->prop_value.SetBool(value);

    if (oldValue != value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyInt(const char* name, const int32_t value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    int32_t oldValue = mxPropertys[index]->prop_value.GetInt();
    oldData.SetInt(oldValue);

    mxPropertys[index]->prop_value.SetInt(value);

    if (oldValue != value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyInt64(const char* name, const int64_t value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    int64_t oldValue = mxPropertys[index]->prop_value.GetInt64();
    oldData.SetInt64(oldValue);

    mxPropertys[index]->prop_value.SetInt64(value);

    if (oldValue != value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyFloat(const char* name, const float value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    float oldValue = mxPropertys[index]->prop_value.GetFloat();
    oldData.SetFloat(oldValue);

    mxPropertys[index]->prop_value.SetFloat(value);

    if (!IsZeroFloat(oldValue - value))
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyDouble(const char* name, const double value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    double oldValue = mxPropertys[index]->prop_value.GetDouble();
    oldData.SetDouble(oldValue);

    mxPropertys[index]->prop_value.SetDouble(value);

    if (!IsZeroDouble(oldValue - value))
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyString(const char* name, const std::string& value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    std::string oldValue = mxPropertys[index]->prop_value.GetString();
    oldData.SetString(oldValue.c_str());

    mxPropertys[index]->prop_value.SetString(value.c_str());

    if (oldValue == value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyObject(const char* name, const AFGUID& value)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    AFGUID oldValue = mxPropertys[index]->prop_value.GetObject();
    oldData.SetObject(oldValue);

    mxPropertys[index]->prop_value.SetObject(value);

    if (oldValue == value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::GetPropertyBool(const char* name)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return NULL_BOOLEAN;
    }

    return mxPropertys[index]->prop_value.GetBool();
}

int32_t AFCPropertyMgr::GetPropertyInt(const char* name)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return NULL_INT;
    }

    return mxPropertys[index]->prop_value.GetInt();
}

int64_t AFCPropertyMgr::GetPropertyInt64(const char* name)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return NULL_INT64;
    }

    return mxPropertys[index]->prop_value.GetInt64();
}

float AFCPropertyMgr::GetPropertyFloat(const char* name)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return NULL_FLOAT;
    }

    return mxPropertys[index]->prop_value.GetFloat();
}

double AFCPropertyMgr::GetPropertyDouble(const char* name)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return NULL_DOUBLE;
    }

    return mxPropertys[index]->prop_value.GetDouble();
}

const char* AFCPropertyMgr::GetPropertyString(const char* name)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return NULL_STR.c_str();
    }

    return mxPropertys[index]->prop_value.GetString();
}

const AFGUID& AFCPropertyMgr::GetPropertyObject(const char* name)
{
    size_t index;
    if (!FindIndex(name, index))
    {
        return NULL_GUID;
    }

    return mxPropertys[index]->prop_value.GetObject();
}<commit_msg>fix property callback function bug<commit_after>// -------------------------------------------------------------------------
//    @FileName         :    AFCPropertyMgr.cpp
//    @Author           :    Ark Game Tech
//    @Date             :    2012-03-01
//    @Module           :    AFCPropertyMgr
//
// -------------------------------------------------------------------------

#include "AFCPropertyMgr.h"

AFCPropertyMgr::AFCPropertyMgr(const AFGUID& self)
{
    mxSelf = self;
}

AFCPropertyMgr::~AFCPropertyMgr()
{
    Clear();
}

void AFCPropertyMgr::Clear()
{
    for(size_t i = 0; i < mxPropertys.size(); ++i)
    {
        delete mxPropertys[i];
    }

    mxPropertys.clear();
    mxIndices.Clear();
}

const AFGUID& AFCPropertyMgr::Self() const
{
    return mxSelf;
}

bool AFCPropertyMgr::RegisterCallback(const std::string& strProperty, const PROPERTY_EVENT_FUNCTOR_PTR& cb)
{
    size_t index;
    if(!FindIndex(strProperty.c_str(), index))
    {
        return false;
    }

    mxPropertyCBs.emplace(std::make_pair(strProperty.c_str(), cb));
    return true;
}

bool AFCPropertyMgr::FindIndex(const char* name, size_t& index)
{
    if(!mxIndices.GetData(name, index))
    {
        return false;
    }

    return true;
}

bool AFCPropertyMgr::OnPropertyCallback(const char* name, const AFIData& oldData, const AFIData& newData)
{
    if(mxPropertyCBs.empty())
    {
        return false;
    }

    auto& range = mxPropertyCBs.equal_range(name);
    for(auto& iter = range.first; iter != range.second; ++iter)
    {
        (*(iter->second))(mxSelf, name, oldData, newData);
    }

    return true;
}

bool AFCPropertyMgr::AddProperty(const char* name, const AFIData& value, bool bPublic, bool bPrivate, bool bSave, bool bRealTime)
{
    AFProperty* pProperty = new AFProperty();
    pProperty->name = name;
    pProperty->prop_value = value;
    pProperty->bPublic = bPublic;
    pProperty->bPrivate = bPrivate;
    pProperty->bSave = bSave;
    pProperty->bRealtime = bRealTime;
    mxIndices.Add(name, mxPropertys.size());
    mxPropertys.push_back(pProperty);

    return true;
}

bool AFCPropertyMgr::SetProperty(const char* name, const AFIData& value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    mxPropertys[index]->prop_value = value;

    //TODO:call cb

    return true;
}

bool AFCPropertyMgr::SetPropertyBool(const char* name, const bool value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    bool oldValue = mxPropertys[index]->prop_value.GetBool();
    oldData.SetBool(oldValue);

    mxPropertys[index]->prop_value.SetBool(value);

    if(oldValue != value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyInt(const char* name, const int32_t value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    int32_t oldValue = mxPropertys[index]->prop_value.GetInt();
    oldData.SetInt(oldValue);

    mxPropertys[index]->prop_value.SetInt(value);

    if(oldValue != value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyInt64(const char* name, const int64_t value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    int64_t oldValue = mxPropertys[index]->prop_value.GetInt64();
    oldData.SetInt64(oldValue);

    mxPropertys[index]->prop_value.SetInt64(value);

    if(oldValue != value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyFloat(const char* name, const float value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    float oldValue = mxPropertys[index]->prop_value.GetFloat();
    oldData.SetFloat(oldValue);

    mxPropertys[index]->prop_value.SetFloat(value);

    if(!IsZeroFloat(oldValue - value))
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyDouble(const char* name, const double value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    double oldValue = mxPropertys[index]->prop_value.GetDouble();
    oldData.SetDouble(oldValue);

    mxPropertys[index]->prop_value.SetDouble(value);

    if(!IsZeroDouble(oldValue - value))
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyString(const char* name, const std::string& value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    std::string oldValue = mxPropertys[index]->prop_value.GetString();
    oldData.SetString(oldValue.c_str());

    mxPropertys[index]->prop_value.SetString(value.c_str());

    if(oldValue == value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::SetPropertyObject(const char* name, const AFGUID& value)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return false;
    }

    //old value
    AFXData oldData;
    AFGUID oldValue = mxPropertys[index]->prop_value.GetObject();
    oldData.SetObject(oldValue);

    mxPropertys[index]->prop_value.SetObject(value);

    if(oldValue == value)
    {
        //property callbacks
        OnPropertyCallback(name, oldData, mxPropertys[index]->prop_value);
    }

    return true;
}

bool AFCPropertyMgr::GetPropertyBool(const char* name)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return NULL_BOOLEAN;
    }

    return mxPropertys[index]->prop_value.GetBool();
}

int32_t AFCPropertyMgr::GetPropertyInt(const char* name)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return NULL_INT;
    }

    return mxPropertys[index]->prop_value.GetInt();
}

int64_t AFCPropertyMgr::GetPropertyInt64(const char* name)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return NULL_INT64;
    }

    return mxPropertys[index]->prop_value.GetInt64();
}

float AFCPropertyMgr::GetPropertyFloat(const char* name)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return NULL_FLOAT;
    }

    return mxPropertys[index]->prop_value.GetFloat();
}

double AFCPropertyMgr::GetPropertyDouble(const char* name)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return NULL_DOUBLE;
    }

    return mxPropertys[index]->prop_value.GetDouble();
}

const char* AFCPropertyMgr::GetPropertyString(const char* name)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return NULL_STR.c_str();
    }

    return mxPropertys[index]->prop_value.GetString();
}

const AFGUID& AFCPropertyMgr::GetPropertyObject(const char* name)
{
    size_t index;
    if(!FindIndex(name, index))
    {
        return NULL_GUID;
    }

    return mxPropertys[index]->prop_value.GetObject();
}<|endoftext|>


<commit_before>#include <iostream>
#include "centralizedReconfiguration.h"
#include "bfs.h"
#include "catoms2DWorld.h"
#include "coordinate.h"
#include "catoms2DMove.h"
#include "map.h"

using namespace std;
using namespace Catoms2D;

#define COLOR_DEBUG
#define ROTATION_DIRECTION Catoms2DMove::ROTATE_CW
#define UNDEFINED_GRADIENT -1

enum state_t {IN_SHAPE = 0, OUT_SHAPE = 1, WELL_PLACED = 2};

static Coordinate getMapBottomRight() {
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  Catoms2DBlock  *c;
  Coordinate rb(INT_MIN,INT_MAX);

  map<int, BuildingBlock*>::iterator it;
  for (it=world->getMap().begin() ; it != world->getMap().end(); ++it) {
    c = (Catoms2DBlock*) it->second;
    Coordinate cc(c->position[0], c->position[2]);
    /*if (cc.x >= rb.x) {
      rb.x = cc.x;
      if (cc.y <= rb.y) {
	rb.y = cc.y;
      }
      }*/
    if (cc.y <= rb.y) {
      rb.y = cc.y;
      if (cc.x >= rb.x) {
	rb.x = cc.x;
      }
    }
  }
  return rb;
}

static Coordinate getTargetBottomLeft() {
  Coordinate p(INT_MIN,INT_MIN);
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  int *gridSize = world->getGridSize();
  for (int iy = 0; iy < gridSize[2]; iy++) {
    for (int ix = 0; ix < gridSize[0]; ix++) {
      if (world->getTargetGrid(ix,0,iy) == fullCell ) {
	Coordinate cc(ix, iy);
	if (cc.y <= p.y) {
	  p.y = cc.y;
	  if (cc.x <= p.x) {
	    p.x = cc.x;
	  }
	}
      }
    }
  }
  return p;
}

static bool isOver() {
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  int *gridSize = world->getGridSize();
  for (int iy = 0; iy < gridSize[2]; iy++) {
    for (int ix = 0; ix < gridSize[0]; ix++) {
      if (world->getTargetGrid(ix,0,iy) == fullCell ) {
        if (!world->getGridPtr(ix,0,iy)) {
	  return false;
	}
      }
    }
  }
  return true;
}

static P2PNetworkInterface*
nextInterface(Catoms2DBlock *c, Catoms2DMove::direction_t d, P2PNetworkInterface *p2p) {
  int p2pDirection = c->getDirection(p2p);
  cout << "next: ";
  cout << "i: " << p2pDirection;
  if (d == Catoms2DMove::ROTATE_CCW) {
    if (p2pDirection == NeighborDirection::BottomRight) {
      p2pDirection = NeighborDirection::Right;
    } else {
      p2pDirection++;
    }
  } else if (d == Catoms2DMove::ROTATE_CW) {
    if (p2pDirection == NeighborDirection::Right) {
      p2pDirection = NeighborDirection::BottomRight;
    } else {
      p2pDirection--;
    }
  }
  cout << "n: " << p2pDirection << endl;
  return c->getInterface((NeighborDirection::Direction)p2pDirection);
}

static P2PNetworkInterface *lastNeighborInDirection(Catoms2DBlock *c, Catoms2DMove::direction_t d) {
  P2PNetworkInterface *p1 = NULL, *p2 = NULL;

  if (c->nbNeighbors() == 0) {
    return NULL;
  }

  // pick-up a neighbor of c
  for (int i = 0; i < 6; i++) {
    p1 = c->getInterface((NeighborDirection::Direction)i);
    if (p1->connectedInterface) {
      break;
    }
  }

  if (c->nbNeighbors() == 1) {
    return p1;
  }

  p2 = p1;
  while (true) {
    if (d == Catoms2DMove::ROTATE_CCW) {
      p2 = nextInterface(c, Catoms2DMove::ROTATE_CW, p2);
    } else if (d == Catoms2DMove::ROTATE_CW) {
      p2 = nextInterface(c, Catoms2DMove::ROTATE_CCW, p2);
    }

    if (!p2->connectedInterface) {
      return p1;
    }
    p1 = p2;
  }
}

static Catoms2DMove* nextMove(Catoms2DBlock  *c) {
  P2PNetworkInterface *p1 = NULL, *p2 = NULL;
  Catoms2DBlock  *pivot;
  int i = 0;

  // pick-up a neighbor of c
  for (i = 0; i < 6; i++) {
    p1 = c->getInterface((NeighborDirection::Direction)i);
    if (p1->connectedInterface) {
      break;
    }
  }

  if ((i == 5) && !p1->connectedInterface) {
    return NULL;
  }

  p2 = p1;
  cout << "p1 dir: " << c->getDirection(p2) << endl;
  while (true) {
    if (ROTATION_DIRECTION == Catoms2DMove::ROTATE_CCW) {
      p2 = nextInterface(c, Catoms2DMove::ROTATE_CW, p2);
    } else if (ROTATION_DIRECTION == Catoms2DMove::ROTATE_CW) {
      p2 = nextInterface(c, Catoms2DMove::ROTATE_CCW, p2);
    }

    cout << "p2 dir: " << c->getDirection(p2) << endl;
    if (p2->connectedInterface) {
      cout << "connected p2 dir: " << c->getDirection(p2) << endl;
      pivot = (Catoms2DBlock*)p2->connectedInterface->hostBlock;
      Catoms2DMove m(pivot,ROTATION_DIRECTION);
      if (c->canMove(m)) {
	cout << c->blockId << " can move arround " << pivot->blockId << endl;
	return new Catoms2DMove(m);
      }
      cout << "can't move" << endl;
    }
    if (p1 == p2) {
      return NULL;
    }
  }
}

static Coordinate getPosition(Catoms2DBlock* c, Catoms2DMove &m) {
  P2PNetworkInterface *p2p = m.getPivot()->getP2PNetworkInterfaceByBlockRef(c);
  Coordinate position(m.getPivot()->position[0], m.getPivot()->position[2]);
  p2p = nextInterface(m.getPivot(),m.getDirection(),p2p);
  return Map::getPosition(m.getPivot(),position,p2p);
}

static bool isInTarget(Coordinate &p) {
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  return (world->getTargetGrid(p.x,0,p.y) == fullCell);
}

#define CONSECUTIVE_NEIGHBORS
//#define GRADIENT
static bool canMove(Catoms2DBlock *c, int gradient[]) {
#ifdef CONSECUTIVE_NEIGHBORS
  // on the border (r)
  int nbNeighbors = c->nbNeighbors();
  int nbConsecutiveNeighbors = c->nbConsecutiveNeighbors();
  bool r = (nbNeighbors <= 4) && (nbConsecutiveNeighbors == nbNeighbors);
  return r;
#elif defined(GRADIENT)
  // can algorithmically move (gradient higher or equal than all neighbors)
  int id1 = c->blockId;

  if (gradient[id1] ==  UNDEFINED_GRADIENT) {
    return false;
  }

  for (int i = 0; i < 6; i++) {
    P2PNetworkInterface *p2p = c->getInterface((NeighborDirection::Direction)i);
    if (p2p->connectedInterface) {
      int id2 = p2p->connectedInterface->hostBlock->blockId;

      if (gradient[id2] ==  UNDEFINED_GRADIENT) {
	return false;
      }

      if (gradient[id1] < gradient[id2]) {
	return false;
      }
    }
  }
  return true;
#endif
}

static void move(Catoms2DBlock* c, Catoms2DMove &m) {
  if (!c->canMove(m)) {
    cerr << "error illegal move" << endl;
    return;
  }
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  // final position
  Coordinate p = getPosition(c,m);
  // disconnect
  world->disconnectBlock(c);
  // rotate
  c->angle += 60*m.getDirection();
  // set grid and update gl world
  world->setGridPtr(p.x,0,p.y,c);
  c->setPosition(Vecteur(p.x,0,p.y));
  world->updateGlData(c,world->gridToWorldPosition(c->position),c->angle);
  // connect
  world->connectBlock(c);
}

static void updateGradient(Catoms2DBlock *c, int gradient[]) {
// can algorithmically move (gradient higher or equal than all neighbors)
  int id1 = c->blockId;
  int minGradient = INT_MAX;

  for (int i = 0; i < 6; i++) {
    P2PNetworkInterface *p2p = c->getInterface((NeighborDirection::Direction)i);
    if (p2p->connectedInterface) {
      int id2 = p2p->connectedInterface->hostBlock->blockId;
      if (gradient[id2] == UNDEFINED_GRADIENT) {
	cerr << "error: update gradient" << endl;
      }
      minGradient = min(minGradient,gradient[id2]);
    }
  }
  gradient[id1] = minGradient + 1;
}

//#define STRATEGY_ONE
#define STRATEGY_TWO
static bool pivotShouldMoveBefore(Catoms2DBlock *c, Catoms2DMove &mv,
				  int gradient[]) {
  Coordinate p1(c->position[0], c->position[2]);
  Coordinate p2 = getPosition(c,mv);

  bool pcm = canMove(mv.getPivot(),gradient);
  bool psmb = false;

  if (pcm) {
    Coordinate pivotP1(mv.getPivot()->position[0],
		       mv.getPivot()->position[2]);
    Catoms2DMove *pivotMv = nextMove(mv.getPivot());

    if (pivotMv != NULL) {
	Coordinate pivotP2 = getPosition(mv.getPivot(),*pivotMv);
	psmb = (!isInTarget(pivotP1) ||
		(isInTarget(pivotP1) && isInTarget(pivotP2)));
#if defined(STRATEGY_ONE)
	psmb = psmb && (pivotP1.y <= p1.y);
#elif defined(STRATEGY_TWO)
	if (mv.getPivot() ==
	    lastNeighborInDirection(c,ROTATION_DIRECTION)->hostBlock) {
	  psmb = true;
	}
#endif
    }
  }
  return psmb;
}

void centralized_reconfiguration() {
  cout << "centralized reconfiguration" << endl;
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  Catoms2DBlock *seed = NULL;
  int gradient[world->getSize()+1];
  //state_t states[world->getSize()+1];
  Tree *bfs = NULL;
  int moves = 0;

  Coordinate mapBottomRight = getMapBottomRight();
  seed = world->getGridPtr(mapBottomRight.x,0,mapBottomRight.y);
#ifdef COLOR_DEBUG
  seed->setColor(RED);
#endif

  for (int i = 0; i < (world->getSize()+1); i++) {
    gradient[i] = UNDEFINED_GRADIENT;
    //if (
    //states[i] =
  }

  bfs = Tree::bfs(seed->blockId,gradient,world->getSize());

  while (!isOver()) {
    // algorithm moving condition of catom c1:
    // FALSE ???:
    // c1 gradient will be lower in the destination cell.
    // none of the gradient of c1's neighbors will change (ie gradient is lower or equal to c1).

    // physical moving condition
    // move CW around i connector: i+1 and i+2 should be free
    // move CCW around i connector: i-1 and i-2 should be free
    Catoms2DWorld *world = Catoms2DWorld::getWorld();
    Catoms2DBlock  *c;

    map<int, BuildingBlock*>::iterator it;
    for (it=world->getMap().begin() ; it != world->getMap().end(); ++it) {

      c = (Catoms2DBlock*) it->second;
      if (c == seed) {
	continue;
      }

      if (canMove(c,gradient)) {
	//cout << "c satisfies gradient condition" << endl;
	//cout << "@" << c->blockId << " can physically move" << endl;
	Coordinate p1(c->position[0], c->position[2]);
	Catoms2DMove *mv = nextMove(c);
	if (mv != NULL) {
	  Coordinate p2 = getPosition(c,*mv);

	  bool psmb = pivotShouldMoveBefore(c,*mv,gradient);

	  if (!psmb &&
	      (!isInTarget(p1) || (isInTarget(p1) && isInTarget(p2)))) {
	    cout << c->blockId << " is moving from " << p1 << " to "
		 << p2 << " using " << mv->getPivot()->blockId << " in direction " << mv->getDirection() << "...";
	    move(c,*mv);
	    moves++;
	    cout << c->blockId << " has " << c->nbNeighbors() << " neighbors" << endl;
	    gradient[c->blockId] = UNDEFINED_GRADIENT;
	    updateGradient(c,gradient);
	    cout << " done" << endl;
	    getchar();
	  } /*else {
	    cout << "hors figure ?" << endl;
	    }*/
	  delete mv;
	} else { cout << " move == NULL" << endl;}
      }
    }
  }
  cout << "reconfiguration over in " << moves << " moves." << endl;
  /*Coordinate targetBottomLeft = getTargetBottomLeft();
  Coordinate
  Coordinate trTargetBottomLeft = Map::real2Virtual(*/

  /* Current map:
     int *gridSize = world->getGridSize();
     for (int iy = 0; iy < gridSize[2]; iy++) {
     for (int ix = 0; ix < gridSize[0]; ix++) {
     Catoms2DBlock* c = world->getGridPtr(ix,0,iy);
     if (c != NULL) {

     }
     }
     }*/

  /* Target map:
  Coordinate pmin(INT_MAX,INT_MAX);
  Coordinate pmax(INT_MIN,INT_MIN);
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  int *gridSize = world->getGridSize();
  for (int iy = 0; iy < gridSize[2]; iy++) {
    for (int ix = 0; ix < gridSize[0]; ix++) {
      if (world->getTargetGrid(ix,0,iy) == fullCell ) {
	pmin.x = min(pmin.x, ix);
	pmin.y = min(pmin.y, iy);
	pmax.x = max(pmax.x, ix);
	pmax.y = max(pmax.y, iy);
	Coordinate real(ix,iy);
	Coordinate t =  map.real2Virtual(real);
	cout << "target: (" << t.x << " " << t.y << ")" << endl;
	ctuples.out(ContextTuple(string("target"),t));
      }
    }
  }
  Rectangle bounds(pmin,pmax);
  CTuple::setBounds(bounds);
  */
}
<commit_msg>rewrite next move (algorithmic) conditions<commit_after>#include <iostream>
#include "centralizedReconfiguration.h"
#include "bfs.h"
#include "catoms2DWorld.h"
#include "coordinate.h"
#include "catoms2DMove.h"
#include "map.h"

using namespace std;
using namespace Catoms2D;

#define COLOR_DEBUG
#define ROTATION_DIRECTION Catoms2DMove::ROTATE_CW
#define UNDEFINED_GRADIENT -1

enum state_t {IN_SHAPE = 0, OUT_SHAPE = 1, WELL_PLACED = 2};

static Coordinate getMapBottomRight() {
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  Catoms2DBlock  *c;
  Coordinate rb(INT_MIN,INT_MAX);

  map<int, BuildingBlock*>::iterator it;
  for (it=world->getMap().begin() ; it != world->getMap().end(); ++it) {
    c = (Catoms2DBlock*) it->second;
    Coordinate cc(c->position[0], c->position[2]);
    /*if (cc.x >= rb.x) {
      rb.x = cc.x;
      if (cc.y <= rb.y) {
	rb.y = cc.y;
      }
      }*/
    if (cc.y <= rb.y) {
      rb.y = cc.y;
      if (cc.x >= rb.x) {
	rb.x = cc.x;
      }
    }
  }
  return rb;
}

static Coordinate getTargetBottomLeft() {
  Coordinate p(INT_MIN,INT_MIN);
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  int *gridSize = world->getGridSize();
  for (int iy = 0; iy < gridSize[2]; iy++) {
    for (int ix = 0; ix < gridSize[0]; ix++) {
      if (world->getTargetGrid(ix,0,iy) == fullCell ) {
	Coordinate cc(ix, iy);
	if (cc.y <= p.y) {
	  p.y = cc.y;
	  if (cc.x <= p.x) {
	    p.x = cc.x;
	  }
	}
      }
    }
  }
  return p;
}

static bool isOver() {
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  int *gridSize = world->getGridSize();
  for (int iy = 0; iy < gridSize[2]; iy++) {
    for (int ix = 0; ix < gridSize[0]; ix++) {
      if (world->getTargetGrid(ix,0,iy) == fullCell ) {
        if (!world->getGridPtr(ix,0,iy)) {
	  return false;
	}
      }
    }
  }
  return true;
}

static P2PNetworkInterface*
nextInterface(Catoms2DBlock *c, Catoms2DMove::direction_t d, P2PNetworkInterface *p2p) {
  int p2pDirection = c->getDirection(p2p);
  cout << "next: ";
  cout << "i: " << p2pDirection;
  if (d == Catoms2DMove::ROTATE_CCW) {
    if (p2pDirection == NeighborDirection::BottomRight) {
      p2pDirection = NeighborDirection::Right;
    } else {
      p2pDirection++;
    }
  } else if (d == Catoms2DMove::ROTATE_CW) {
    if (p2pDirection == NeighborDirection::Right) {
      p2pDirection = NeighborDirection::BottomRight;
    } else {
      p2pDirection--;
    }
  }
  cout << "n: " << p2pDirection << endl;
  return c->getInterface((NeighborDirection::Direction)p2pDirection);
}

static P2PNetworkInterface *lastNeighborInDirection(Catoms2DBlock *c, Catoms2DMove::direction_t d) {
  P2PNetworkInterface *p1 = NULL, *p2 = NULL;

  if (c->nbNeighbors() == 0) {
    return NULL;
  }

  // pick-up a neighbor of c
  for (int i = 0; i < 6; i++) {
    p1 = c->getInterface((NeighborDirection::Direction)i);
    if (p1->connectedInterface) {
      break;
    }
  }

  if (c->nbNeighbors() == 1) {
    return p1;
  }

  p2 = p1;
  while (true) {
    if (d == Catoms2DMove::ROTATE_CCW) {
      p2 = nextInterface(c, Catoms2DMove::ROTATE_CW, p2);
    } else if (d == Catoms2DMove::ROTATE_CW) {
      p2 = nextInterface(c, Catoms2DMove::ROTATE_CCW, p2);
    }

    if (!p2->connectedInterface) {
      return p1;
    }
    p1 = p2;
  }
}

static Catoms2DMove* nextMove(Catoms2DBlock  *c) {
  P2PNetworkInterface *p2p = lastNeighborInDirection(c,ROTATION_DIRECTION);
  Catoms2DBlock* pivot = (Catoms2DBlock*)p2p->connectedInterface->hostBlock;
  Catoms2DMove m(pivot,ROTATION_DIRECTION);
  if (c->canMove(m)) {
    cout << c->blockId << " can move arround " << pivot->blockId << endl;
    return new Catoms2DMove(m);
  }
  return NULL;
}

static Coordinate getPosition(Catoms2DBlock* c, Catoms2DMove &m) {
  P2PNetworkInterface *p2p = m.getPivot()->getP2PNetworkInterfaceByBlockRef(c);
  Coordinate position(m.getPivot()->position[0], m.getPivot()->position[2]);
  p2p = nextInterface(m.getPivot(),m.getDirection(),p2p);
  return Map::getPosition(m.getPivot(),position,p2p);
}

static bool isInTarget(Coordinate &p) {
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  return (world->getTargetGrid(p.x,0,p.y) == fullCell);
}

#define CONSECUTIVE_NEIGHBORS
//#define GRADIENT
static bool canMove(Catoms2DBlock *c, int gradient[]) {
#ifdef CONSECUTIVE_NEIGHBORS
  // on the border (r)
  int nbNeighbors = c->nbNeighbors();
  int nbConsecutiveNeighbors = c->nbConsecutiveNeighbors();
  bool r = (nbNeighbors <= 4) && (nbConsecutiveNeighbors == nbNeighbors);
  return r;
#elif defined(GRADIENT)
  // can algorithmically move (gradient higher or equal than all neighbors)
  int id1 = c->blockId;

  if (gradient[id1] ==  UNDEFINED_GRADIENT) {
    return false;
  }

  for (int i = 0; i < 6; i++) {
    P2PNetworkInterface *p2p = c->getInterface((NeighborDirection::Direction)i);
    if (p2p->connectedInterface) {
      int id2 = p2p->connectedInterface->hostBlock->blockId;

      if (gradient[id2] ==  UNDEFINED_GRADIENT) {
	return false;
      }

      if (gradient[id1] < gradient[id2]) {
	return false;
      }
    }
  }
  return true;
#endif
}

static void move(Catoms2DBlock* c, Catoms2DMove &m) {
  if (!c->canMove(m)) {
    cerr << "error illegal move" << endl;
    return;
  }
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  // final position
  Coordinate p = getPosition(c,m);
  // disconnect
  world->disconnectBlock(c);
  // rotate
  c->angle += 60*m.getDirection();
  // set grid and update gl world
  world->setGridPtr(p.x,0,p.y,c);
  c->setPosition(Vecteur(p.x,0,p.y));
  world->updateGlData(c,world->gridToWorldPosition(c->position),c->angle);
  // connect
  world->connectBlock(c);
}

static void updateGradient(Catoms2DBlock *c, int gradient[]) {
// can algorithmically move (gradient higher or equal than all neighbors)
  int id1 = c->blockId;
  int minGradient = INT_MAX;

  for (int i = 0; i < 6; i++) {
    P2PNetworkInterface *p2p = c->getInterface((NeighborDirection::Direction)i);
    if (p2p->connectedInterface) {
      int id2 = p2p->connectedInterface->hostBlock->blockId;
      if (gradient[id2] == UNDEFINED_GRADIENT) {
	cerr << "error: update gradient" << endl;
      }
      minGradient = min(minGradient,gradient[id2]);
    }
  }
  gradient[id1] = minGradient + 1;
}

//#define STRATEGY_ONE
#define STRATEGY_TWO
static bool pivotShouldMoveBefore(Catoms2DBlock *c, Catoms2DMove &mv,
				  int gradient[]) {
  Coordinate p1(c->position[0], c->position[2]);
  Coordinate p2 = getPosition(c,mv);

  bool pcm = canMove(mv.getPivot(),gradient);
  bool psmb = false;

  if (pcm) {
    Coordinate pivotP1(mv.getPivot()->position[0],
		       mv.getPivot()->position[2]);
    Catoms2DMove *pivotMv = nextMove(mv.getPivot());

    if (pivotMv != NULL) {
	Coordinate pivotP2 = getPosition(mv.getPivot(),*pivotMv);
	psmb = (!isInTarget(pivotP1) ||
		(isInTarget(pivotP1) && isInTarget(pivotP2)));
#if defined(STRATEGY_ONE)
	psmb = psmb && (pivotP1.y <= p1.y);
#elif defined(STRATEGY_TWO)
	if (mv.getPivot() ==
	    lastNeighborInDirection(c,ROTATION_DIRECTION)->hostBlock) {
	  psmb = true;
	}
#endif
    }
  }
  return psmb;
}

void centralized_reconfiguration() {
  cout << "centralized reconfiguration" << endl;
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  Catoms2DBlock *seed = NULL;
  int gradient[world->getSize()+1];
  //state_t states[world->getSize()+1];
  Tree *bfs = NULL;
  int moves = 0;

  Coordinate mapBottomRight = getMapBottomRight();
  seed = world->getGridPtr(mapBottomRight.x,0,mapBottomRight.y);
#ifdef COLOR_DEBUG
  seed->setColor(RED);
#endif

  for (int i = 0; i < (world->getSize()+1); i++) {
    gradient[i] = UNDEFINED_GRADIENT;
    //if (
    //states[i] =
  }

  bfs = Tree::bfs(seed->blockId,gradient,world->getSize());

  while (!isOver()) {
    // algorithm moving condition of catom c1:
    // FALSE ???:
    // c1 gradient will be lower in the destination cell.
    // none of the gradient of c1's neighbors will change (ie gradient is lower or equal to c1).

    // physical moving condition
    // move CW around i connector: i+1 and i+2 should be free
    // move CCW around i connector: i-1 and i-2 should be free
    Catoms2DWorld *world = Catoms2DWorld::getWorld();
    Catoms2DBlock  *c;

    map<int, BuildingBlock*>::iterator it;
    for (it=world->getMap().begin() ; it != world->getMap().end(); ++it) {

      c = (Catoms2DBlock*) it->second;
      if (c == seed) {
	continue;
      }

      if (canMove(c,gradient)) {
	//cout << "c satisfies gradient condition" << endl;
	//cout << "@" << c->blockId << " can physically move" << endl;
	Coordinate p1(c->position[0], c->position[2]);
	Catoms2DMove *mv = nextMove(c);
	if (mv != NULL) {
	  Coordinate p2 = getPosition(c,*mv);

	  bool psmb = pivotShouldMoveBefore(c,*mv,gradient);

	  if (!psmb &&
	      (!isInTarget(p1) || (isInTarget(p1) && isInTarget(p2)))) {
	    cout << c->blockId << " is moving from " << p1 << " to "
		 << p2 << " using " << mv->getPivot()->blockId << " in direction " << mv->getDirection() << "...";
	    move(c,*mv);
	    moves++;
	    cout << c->blockId << " has " << c->nbNeighbors() << " neighbors" << endl;
	    gradient[c->blockId] = UNDEFINED_GRADIENT;
	    updateGradient(c,gradient);
	    cout << " done" << endl;
	    getchar();
	  } /*else {
	    cout << "hors figure ?" << endl;
	    }*/
	  delete mv;
	} else { cout << " move == NULL" << endl;}
      }
    }
  }
  cout << "reconfiguration over in " << moves << " moves." << endl;
  /*Coordinate targetBottomLeft = getTargetBottomLeft();
  Coordinate
  Coordinate trTargetBottomLeft = Map::real2Virtual(*/

  /* Current map:
     int *gridSize = world->getGridSize();
     for (int iy = 0; iy < gridSize[2]; iy++) {
     for (int ix = 0; ix < gridSize[0]; ix++) {
     Catoms2DBlock* c = world->getGridPtr(ix,0,iy);
     if (c != NULL) {

     }
     }
     }*/

  /* Target map:
  Coordinate pmin(INT_MAX,INT_MAX);
  Coordinate pmax(INT_MIN,INT_MIN);
  Catoms2DWorld *world = Catoms2DWorld::getWorld();
  int *gridSize = world->getGridSize();
  for (int iy = 0; iy < gridSize[2]; iy++) {
    for (int ix = 0; ix < gridSize[0]; ix++) {
      if (world->getTargetGrid(ix,0,iy) == fullCell ) {
	pmin.x = min(pmin.x, ix);
	pmin.y = min(pmin.y, iy);
	pmax.x = max(pmax.x, ix);
	pmax.y = max(pmax.y, iy);
	Coordinate real(ix,iy);
	Coordinate t =  map.real2Virtual(real);
	cout << "target: (" << t.x << " " << t.y << ")" << endl;
	ctuples.out(ContextTuple(string("target"),t));
      }
    }
  }
  Rectangle bounds(pmin,pmax);
  CTuple::setBounds(bounds);
  */
}
<|endoftext|>


<commit_before>/*
 *  Copyright (C) 2010 - 2015 Leonid Kostrykin
 *
 *  Chair of Medical Engineering (mediTEC)
 *  RWTH Aachen University
 *  Pauwelsstr. 20
 *  52074 Aachen
 *  Germany
 *
 */

#include <Carna/presets/RayMarchingStage.h>
#include <Carna/base/Mesh.h>
#include <Carna/base/Vertex.h>
#include <Carna/base/IndexBuffer.h>
#include <Carna/base/ShaderManager.h>
#include <Carna/base/RenderState.h>
#include <Carna/base/ShaderUniform.h>
#include <Carna/base/Log.h>
#include <Carna/base/math.h>
#include <Carna/base/text.h>

namespace Carna
{

namespace presets
{

// ----------------------------------------------------------------------------------
// RayMarchingStage :: Details
// ----------------------------------------------------------------------------------

struct RayMarchingStage::Details
{
    Details();

    base::RenderTask* renderTask;
    const base::Viewport* viewPort;
    unsigned int sampleRate;
};

RayMarchingStage::Details::Details()
    : renderTask( nullptr )
    , viewPort( nullptr )
    , sampleRate( DEFAULT_SAMPLE_RATE )
{
}

// ----------------------------------------------------------------------------------
// RayMarchingStage :: VideoResources
// ----------------------------------------------------------------------------------

struct RayMarchingStage::VideoResources
{
    VideoResources( const base::ShaderProgram& shader, unsigned int sampleRate );

    const base::ShaderProgram& shader;
    std::map< unsigned int, base::Sampler* > samplers;

    typedef base::Mesh< base::VertexBase, uint16_t > SlicesMesh;
    SlicesMesh::VideoResourceAcquisition& slicesMesh( unsigned int sampleRate );

private:

    unsigned int mySampleRate;
    std::unique_ptr< SlicesMesh::VideoResourceAcquisition > mySlicesMesh;
    static SlicesMesh::VideoResourceAcquisition* createSlicesMesh( unsigned int sampleRate );
};

RayMarchingStage::VideoResources::VideoResources( const base::ShaderProgram& shader, unsigned int sampleRate )
    : shader( shader )
    , mySampleRate( sampleRate + 1 )
{
    /* Create the slices mesh.
     */
    slicesMesh( sampleRate );
}

RayMarchingStage::VideoResources::SlicesMesh::VideoResourceAcquisition* RayMarchingStage::VideoResources::createSlicesMesh
    ( unsigned int sampleRate )
{
    /* The mesh is constructed in model space. The box [-0,5; +0.5]^3 defines the
     * space that we need to cover. For a ray that hits the center, the distant-most
     * point of the box is half the square root of 3.
     */
    const float radius = std::sqrt( 3.f ) / 2;

    /* Create slices.
     */
    std::vector< typename SlicesMesh::Vertex > vertices( 4 * sampleRate );
    std::vector< typename SlicesMesh::Index  >  indices( 6 * sampleRate );
    for( unsigned int sliceIdx = 0; sliceIdx < sampleRate; ++sliceIdx )
    {
        const float progress = static_cast< float >( sliceIdx ) / ( sampleRate - 1 );
        const float offset = 2 * radius * ( 0.5f - progress );

        /* Create slice vertices.
         */
        vertices[ 4 * sliceIdx + 0 ].x = -radius;
        vertices[ 4 * sliceIdx + 0 ].y = -radius;
        vertices[ 4 * sliceIdx + 0 ].z =  offset;

        vertices[ 4 * sliceIdx + 1 ].x = +radius;
        vertices[ 4 * sliceIdx + 1 ].y = -radius;
        vertices[ 4 * sliceIdx + 1 ].z =  offset;

        vertices[ 4 * sliceIdx + 2 ].x = +radius;
        vertices[ 4 * sliceIdx + 2 ].y = +radius;
        vertices[ 4 * sliceIdx + 2 ].z =  offset;

        vertices[ 4 * sliceIdx + 3 ].x = -radius;
        vertices[ 4 * sliceIdx + 3 ].y = +radius;
        vertices[ 4 * sliceIdx + 3 ].z =  offset;

        /* Create slice indices.
         */
        indices[ 6 * sliceIdx + 0 ] = 4 * sliceIdx + 0;
        indices[ 6 * sliceIdx + 1 ] = 4 * sliceIdx + 1;
        indices[ 6 * sliceIdx + 2 ] = 4 * sliceIdx + 2;
        indices[ 6 * sliceIdx + 3 ] = 4 * sliceIdx + 2;
        indices[ 6 * sliceIdx + 4 ] = 4 * sliceIdx + 3;
        indices[ 6 * sliceIdx + 5 ] = 4 * sliceIdx + 0;
    }

    /* Create the mesh.
     */
    SlicesMesh& mesh = SlicesMesh::create
        ( base::IndexBufferBase::PRIMITIVE_TYPE_TRIANGLES
        , &vertices.front(), vertices.size()
        , &indices.front(), indices.size() );

    /* Acquire the video resources and release the mesh s.t. it is deleted when the
     * video resources are released.
     */
    SlicesMesh::VideoResourceAcquisition* const meshVR = new SlicesMesh::VideoResourceAcquisition( mesh );
    mesh.release();
    return meshVR;
}

RayMarchingStage::VideoResources::SlicesMesh::VideoResourceAcquisition& RayMarchingStage::VideoResources::slicesMesh
    ( unsigned int sampleRate )
{
    if( mySampleRate != sampleRate )
    {
        mySampleRate = sampleRate;
        mySlicesMesh.reset( createSlicesMesh( sampleRate ) );

        std::stringstream msg;
        msg << "RayMarchingStage: Created new slices mesh with " << sampleRate << " samples per pixel.";
        base::Log::instance().record( base::Log::debug, msg.str() );
    }
    return *mySlicesMesh;
}

// ----------------------------------------------------------------------------------
// RayMarchingStage
// ----------------------------------------------------------------------------------

RayMarchingStage::RayMarchingStage( unsigned int geometryType )
    : base::GeometryStage< base::Renderable::BackToFront >::GeometryStage( geometryType )
    , pimpl( new Details() )
{
}

RayMarchingStage::~RayMarchingStage()
{
    activateGLContext();
    if( vr.get() != nullptr )
    {
        /* Release main shader.
         */
        base::ShaderManager::instance().releaseShader( vr->shader );

        /* Release texture samplers.
         */
        for( auto samplerItr = vr->samplers.begin(); samplerItr != vr->samplers.end(); ++samplerItr )
        {
            delete samplerItr->second;
        }
    }
}

void RayMarchingStage::render( const base::Renderable& renderable )
{
    using base::math::Matrix4f;
    using base::math::Vector4f;

    /* Hereinafter the term 'model' is identified with 'segment'.
     */
    const Matrix4f& modelView = renderable.modelViewTransform();

    /* Compute the directional vector from eye to segment center.
     * This vector needs to be renormalized since 'viewModel' may contain scalings.
     */
    const Matrix4f viewModel = modelView.inverse();
    const Vector4f viewDirectionInModelSpace = ( viewModel * Vector4f( 0, 0, -1, 0 ) ).normalized();

    /* Construct billboard at segment center, i.e. a plane that always faces the
     * camera. We choose the planes normal vector inverse to the view direction to
     * ensure that the slices are rendered from back to front.
     */
    const Vector4f modelNormal    = -viewDirectionInModelSpace;
    const Vector4f modelTangent   = ( viewModel * Vector4f( 1, 0, 0, 0 ) ).normalized();
    const Vector4f modelBitangent = ( viewModel * Vector4f( 0, 1, 0, 0 ) ).normalized();
    const Matrix4f tangentModel   = base::math::basis4f( modelTangent, modelBitangent, modelNormal );

    /* Bind all 'Texture3D' geometry features.
     */
    unsigned int lastUnit = base::Texture3D::SETUP_UNIT;
    std::vector< unsigned int > roles;
    const base::Texture3D* anyTexture;
    renderable.geometry().visitFeatures( [&]( base::GeometryFeature& gf, unsigned int role )
        {
            if( dynamic_cast< base::Texture3D* >( &gf ) != nullptr )
            {
                const base::Texture3D& texture = static_cast< const base::Texture3D& >( gf );
                anyTexture = &texture;
                videoResource( texture ).bind( ++lastUnit );
                vr->samplers[ role ]->bind( lastUnit );
                roles.push_back( role );
            }
        }
    );

    /* We assume here that the texture coordinates correction is same for all
     * textures, i.e. all textures have same resolution.
     */
    const base::math::Matrix4f modelTexture =
        ( anyTexture == nullptr ? base::math::identity4f() : anyTexture->textureCoordinatesCorrection )
        * base::math::translation4f( 0.5f, 0.5f, 0.5f );

    /* Configure shader.
     */
    base::ShaderUniform< base::math::Matrix4f >( "modelViewProjection", pimpl->renderTask->projection * modelView ).upload();
    base::ShaderUniform< base::math::Matrix4f >( "modelTexture", modelTexture ).upload();
    base::ShaderUniform< base::math::Matrix4f >( "tangentModel", tangentModel ).upload();
    for( unsigned int samplerOffset = 0; samplerOffset < roles.size(); ++samplerOffset )
    {
        const unsigned int role = roles[ samplerOffset ];
        const unsigned int unit = base::Texture3D::SETUP_UNIT + 1 + samplerOffset;
        const std::string& uniformName = this->uniformName( role );
        base::ShaderUniform< int >( uniformName, unit ).upload();
    }

    /* Invoke shader.
     */
    VideoResources::SlicesMesh::VideoResourceAcquisition& slicesMesh = vr->slicesMesh( pimpl->sampleRate );
    slicesMesh.render();
}

void RayMarchingStage::loadVideoResources()
{
    const base::ShaderProgram& shader = loadShader();
    vr.reset( new VideoResources( shader, pimpl->sampleRate ) );
    createSamplers( [&]( unsigned int role, base::Sampler* sampler )
        {
            CARNA_ASSERT( vr->samplers.find( role ) == vr->samplers.end() );
            vr->samplers[ role ] = sampler;
        }
    );
}

void RayMarchingStage::renderPass
    ( const base::math::Matrix4f& vt
    , base::RenderTask& rt
    , const base::Viewport& vp )
{
    if( vr.get() == nullptr )
    {
        loadVideoResources();
    }

    rt.renderer.glContext().setShader( vr->shader );
    configureShader();

    pimpl->renderTask = &rt;
    pimpl->viewPort = &vp;

    /* Configure proper OpenGL state.
     */
    base::RenderState rs;
    rs.setDepthWrite( false );

    /* Do the rendering.
     */
    base::GeometryStage< base::Renderable::BackToFront >::renderPass( vt, rt, vp );

    /* There is no guarantee that 'renderTask' will be valid later.
     */
    pimpl->renderTask = nullptr;
}

void RayMarchingStage::setSampleRate( unsigned int sampleRate )
{
    CARNA_ASSERT( sampleRate >= 2 );
    pimpl->sampleRate = sampleRate;
}

unsigned int RayMarchingStage::sampleRate() const
{
    return pimpl->sampleRate;
}

}  // namespace Carna :: presets

}  // namespace Carna
<commit_msg>Fixed slices rendering order in RayMarchingState.<commit_after>/*
 *  Copyright (C) 2010 - 2015 Leonid Kostrykin
 *
 *  Chair of Medical Engineering (mediTEC)
 *  RWTH Aachen University
 *  Pauwelsstr. 20
 *  52074 Aachen
 *  Germany
 *
 */

#include <Carna/presets/RayMarchingStage.h>
#include <Carna/base/Mesh.h>
#include <Carna/base/Vertex.h>
#include <Carna/base/IndexBuffer.h>
#include <Carna/base/ShaderManager.h>
#include <Carna/base/RenderState.h>
#include <Carna/base/ShaderUniform.h>
#include <Carna/base/Log.h>
#include <Carna/base/math.h>
#include <Carna/base/text.h>

namespace Carna
{

namespace presets
{

// ----------------------------------------------------------------------------------
// RayMarchingStage :: Details
// ----------------------------------------------------------------------------------

struct RayMarchingStage::Details
{
    Details();

    base::RenderTask* renderTask;
    const base::Viewport* viewPort;
    unsigned int sampleRate;
};

RayMarchingStage::Details::Details()
    : renderTask( nullptr )
    , viewPort( nullptr )
    , sampleRate( DEFAULT_SAMPLE_RATE )
{
}

// ----------------------------------------------------------------------------------
// RayMarchingStage :: VideoResources
// ----------------------------------------------------------------------------------

struct RayMarchingStage::VideoResources
{
    VideoResources( const base::ShaderProgram& shader, unsigned int sampleRate );

    const base::ShaderProgram& shader;
    std::map< unsigned int, base::Sampler* > samplers;

    typedef base::Mesh< base::VertexBase, uint16_t > SlicesMesh;
    SlicesMesh::VideoResourceAcquisition& slicesMesh( unsigned int sampleRate );

private:

    unsigned int mySampleRate;
    std::unique_ptr< SlicesMesh::VideoResourceAcquisition > mySlicesMesh;
    static SlicesMesh::VideoResourceAcquisition* createSlicesMesh( unsigned int sampleRate );
};

RayMarchingStage::VideoResources::VideoResources( const base::ShaderProgram& shader, unsigned int sampleRate )
    : shader( shader )
    , mySampleRate( sampleRate + 1 )
{
    /* Create the slices mesh.
     */
    slicesMesh( sampleRate );
}

RayMarchingStage::VideoResources::SlicesMesh::VideoResourceAcquisition* RayMarchingStage::VideoResources::createSlicesMesh
    ( unsigned int sampleRate )
{
    /* The mesh is constructed in model space. The box [-0,5; +0.5]^3 defines the
     * space that we need to cover. For a ray that hits the center, the distant-most
     * point of the box is half the square root of 3.
     */
    const float radius = std::sqrt( 3.f ) / 2;

    /* Create slices.
     */
    std::vector< typename SlicesMesh::Vertex > vertices( 4 * sampleRate );
    std::vector< typename SlicesMesh::Index  >  indices( 6 * sampleRate );
    for( unsigned int sliceIdx = 0; sliceIdx < sampleRate; ++sliceIdx )
    {
        const float progress = static_cast< float >( sliceIdx ) / ( sampleRate - 1 );
        const float   offset = -2 * radius * ( 0.5f - progress );

        /* Create slice vertices.
         */
        vertices[ 4 * sliceIdx + 0 ].x = -radius;
        vertices[ 4 * sliceIdx + 0 ].y = -radius;
        vertices[ 4 * sliceIdx + 0 ].z =  offset;

        vertices[ 4 * sliceIdx + 1 ].x = +radius;
        vertices[ 4 * sliceIdx + 1 ].y = -radius;
        vertices[ 4 * sliceIdx + 1 ].z =  offset;

        vertices[ 4 * sliceIdx + 2 ].x = +radius;
        vertices[ 4 * sliceIdx + 2 ].y = +radius;
        vertices[ 4 * sliceIdx + 2 ].z =  offset;

        vertices[ 4 * sliceIdx + 3 ].x = -radius;
        vertices[ 4 * sliceIdx + 3 ].y = +radius;
        vertices[ 4 * sliceIdx + 3 ].z =  offset;

        /* Create slice indices.
         */
        indices[ 6 * sliceIdx + 0 ] = 4 * sliceIdx + 0;
        indices[ 6 * sliceIdx + 1 ] = 4 * sliceIdx + 1;
        indices[ 6 * sliceIdx + 2 ] = 4 * sliceIdx + 2;
        indices[ 6 * sliceIdx + 3 ] = 4 * sliceIdx + 2;
        indices[ 6 * sliceIdx + 4 ] = 4 * sliceIdx + 3;
        indices[ 6 * sliceIdx + 5 ] = 4 * sliceIdx + 0;
    }

    /* Create the mesh.
     */
    SlicesMesh& mesh = SlicesMesh::create
        ( base::IndexBufferBase::PRIMITIVE_TYPE_TRIANGLES
        , &vertices.front(), vertices.size()
        , &indices.front(), indices.size() );

    /* Acquire the video resources and release the mesh s.t. it is deleted when the
     * video resources are released.
     */
    SlicesMesh::VideoResourceAcquisition* const meshVR = new SlicesMesh::VideoResourceAcquisition( mesh );
    mesh.release();
    return meshVR;
}

RayMarchingStage::VideoResources::SlicesMesh::VideoResourceAcquisition& RayMarchingStage::VideoResources::slicesMesh
    ( unsigned int sampleRate )
{
    if( mySampleRate != sampleRate )
    {
        mySampleRate = sampleRate;
        mySlicesMesh.reset( createSlicesMesh( sampleRate ) );

        std::stringstream msg;
        msg << "RayMarchingStage: Created new slices mesh with " << sampleRate << " samples per pixel.";
        base::Log::instance().record( base::Log::debug, msg.str() );
    }
    return *mySlicesMesh;
}

// ----------------------------------------------------------------------------------
// RayMarchingStage
// ----------------------------------------------------------------------------------

RayMarchingStage::RayMarchingStage( unsigned int geometryType )
    : base::GeometryStage< base::Renderable::BackToFront >::GeometryStage( geometryType )
    , pimpl( new Details() )
{
}

RayMarchingStage::~RayMarchingStage()
{
    activateGLContext();
    if( vr.get() != nullptr )
    {
        /* Release main shader.
         */
        base::ShaderManager::instance().releaseShader( vr->shader );

        /* Release texture samplers.
         */
        for( auto samplerItr = vr->samplers.begin(); samplerItr != vr->samplers.end(); ++samplerItr )
        {
            delete samplerItr->second;
        }
    }
}

void RayMarchingStage::render( const base::Renderable& renderable )
{
    using base::math::Matrix4f;
    using base::math::Vector4f;

    /* Hereinafter the term 'model' is identified with 'segment'.
     */
    const Matrix4f& modelView = renderable.modelViewTransform();

    /* Compute the directional vector from eye to segment center.
     * This vector needs to be renormalized since 'viewModel' may contain scalings.
     */
    const Matrix4f viewModel = modelView.inverse();
    const Vector4f viewDirectionInModelSpace = ( viewModel * Vector4f( 0, 0, -1, 0 ) ).normalized();

    /* Construct billboard at segment center, i.e. a plane that always faces the
     * camera. We choose the planes normal vector inverse to the view direction to
     * ensure that the slices are rendered from back to front.
     */
    const Vector4f modelNormal    = -viewDirectionInModelSpace;
    const Vector4f modelTangent   = ( viewModel * Vector4f( 1, 0, 0, 0 ) ).normalized();
    const Vector4f modelBitangent = ( viewModel * Vector4f( 0, 1, 0, 0 ) ).normalized();
    const Matrix4f tangentModel   = base::math::basis4f( modelTangent, modelBitangent, modelNormal );

    /* Bind all 'Texture3D' geometry features.
     */
    unsigned int lastUnit = base::Texture3D::SETUP_UNIT;
    std::vector< unsigned int > roles;
    const base::Texture3D* anyTexture;
    renderable.geometry().visitFeatures( [&]( base::GeometryFeature& gf, unsigned int role )
        {
            if( dynamic_cast< base::Texture3D* >( &gf ) != nullptr )
            {
                const base::Texture3D& texture = static_cast< const base::Texture3D& >( gf );
                anyTexture = &texture;
                videoResource( texture ).bind( ++lastUnit );
                vr->samplers[ role ]->bind( lastUnit );
                roles.push_back( role );
            }
        }
    );

    /* We assume here that the texture coordinates correction is same for all
     * textures, i.e. all textures have same resolution.
     */
    const base::math::Matrix4f modelTexture =
        ( anyTexture == nullptr ? base::math::identity4f() : anyTexture->textureCoordinatesCorrection )
        * base::math::translation4f( 0.5f, 0.5f, 0.5f );

    /* Configure shader.
     */
    base::ShaderUniform< base::math::Matrix4f >( "modelViewProjection", pimpl->renderTask->projection * modelView ).upload();
    base::ShaderUniform< base::math::Matrix4f >( "modelTexture", modelTexture ).upload();
    base::ShaderUniform< base::math::Matrix4f >( "tangentModel", tangentModel ).upload();
    for( unsigned int samplerOffset = 0; samplerOffset < roles.size(); ++samplerOffset )
    {
        const unsigned int role = roles[ samplerOffset ];
        const unsigned int unit = base::Texture3D::SETUP_UNIT + 1 + samplerOffset;
        const std::string& uniformName = this->uniformName( role );
        base::ShaderUniform< int >( uniformName, unit ).upload();
    }

    /* Invoke shader.
     */
    VideoResources::SlicesMesh::VideoResourceAcquisition& slicesMesh = vr->slicesMesh( pimpl->sampleRate );
    slicesMesh.render();
}

void RayMarchingStage::loadVideoResources()
{
    const base::ShaderProgram& shader = loadShader();
    vr.reset( new VideoResources( shader, pimpl->sampleRate ) );
    createSamplers( [&]( unsigned int role, base::Sampler* sampler )
        {
            CARNA_ASSERT( vr->samplers.find( role ) == vr->samplers.end() );
            vr->samplers[ role ] = sampler;
        }
    );
}

void RayMarchingStage::renderPass
    ( const base::math::Matrix4f& vt
    , base::RenderTask& rt
    , const base::Viewport& vp )
{
    if( vr.get() == nullptr )
    {
        loadVideoResources();
    }

    rt.renderer.glContext().setShader( vr->shader );
    configureShader();

    pimpl->renderTask = &rt;
    pimpl->viewPort = &vp;

    /* Configure proper OpenGL state.
     */
    base::RenderState rs;
    rs.setDepthWrite( false );

    /* Do the rendering.
     */
    base::GeometryStage< base::Renderable::BackToFront >::renderPass( vt, rt, vp );

    /* There is no guarantee that 'renderTask' will be valid later.
     */
    pimpl->renderTask = nullptr;
}

void RayMarchingStage::setSampleRate( unsigned int sampleRate )
{
    CARNA_ASSERT( sampleRate >= 2 );
    pimpl->sampleRate = sampleRate;
}

unsigned int RayMarchingStage::sampleRate() const
{
    return pimpl->sampleRate;
}

}  // namespace Carna :: presets

}  // namespace Carna
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 Rokas Kupstys
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include <fmt/format.h>
#include "GeneratorContext.h"
#include "Urho3DCustomPass.h"

namespace Urho3D
{

void Urho3DCustomPassLate::NamespaceStart()
{
    // Fix name to property-compatible as this can be turned to a property.
    if (auto* entity = generator->GetSymbol("Urho3D::Menu::ShowPopup"))
        entity->name_ = "GetShowPopup";

    // cppast bug workaround
    if (auto* entity = generator->GetSymbol("Urho3D::Localization::Get(Urho3D::String const&,int)"))
        entity->children_[1]->defaultValue_ = "-1";
}

bool Urho3DCustomPassLate::Visit(MetaEntity* entity, cppast::visitor_info info)
{
    if (info.event == info.container_entity_exit)
        return true;

    if (entity->kind_ == cppast::cpp_entity_kind::enum_t && entity->name_.empty())
    {
        if (entity->children_.empty())
        {
            entity->Remove();
            return true;
        }

        // Give initial value to first element if there isn't any. This will keep correct enum values when they are
        // merged into mega-enum.
        MetaEntity* firstVar = entity->children_[0].get();
        if (firstVar->GetDefaultValue().empty())
            firstVar->defaultValue_ = "0";

        std::string targetEnum;
        if (firstVar->name_.find("SDL") == 0)
            targetEnum = "SDL";
        else
        {
            spdlog::get("console")->warn("No idea where to put {} and it's siblings.", firstVar->name_);
            entity->Remove();
            return false;
        }

        // Sort out anonymous SDL enums
        auto* toEnum = generator->GetSymbol(targetEnum);
        if (toEnum == nullptr)
        {
            std::shared_ptr<MetaEntity> newEnum(new MetaEntity());
            toEnum = newEnum.get();
            toEnum->name_ = toEnum->uniqueName_ = toEnum->symbolName_ = targetEnum;
            toEnum->kind_ = cppast::cpp_entity_kind::enum_t;
            entity->GetParent()->Add(toEnum);
            generator->symbols_[targetEnum] = toEnum->shared_from_this();
        }

        auto children = entity->children_;
        for (const auto& child : children)
            toEnum->Add(child.get());

        // No longer needed
        entity->Remove();
    }

    return true;
}

}
<commit_msg>CSharp: Fix default value for ImGuiDock API.<commit_after>//
// Copyright (c) 2018 Rokas Kupstys
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include <fmt/format.h>
#include "GeneratorContext.h"
#include "Urho3DCustomPass.h"

namespace Urho3D
{

void Urho3DCustomPassLate::NamespaceStart()
{
    // Fix name to property-compatible as this can be turned to a property.
    if (auto* entity = generator->GetSymbol("Urho3D::Menu::ShowPopup"))
        entity->name_ = "GetShowPopup";

    // cppast bug workaround
    if (auto* entity = generator->GetSymbol("Urho3D::Localization::Get(Urho3D::String const&,int)"))
        entity->children_[1]->defaultValue_ = "-1";

    if (auto* entity = generator->GetSymbol("ImGui::BeginDock(char const*,bool*,ImGuiWindowFlags,ImVec2 const&)"))
        entity->children_[3]->defaultValue_ = "new Vector2(-1, -1)";
}

bool Urho3DCustomPassLate::Visit(MetaEntity* entity, cppast::visitor_info info)
{
    if (info.event == info.container_entity_exit)
        return true;

    if (entity->kind_ == cppast::cpp_entity_kind::enum_t && entity->name_.empty())
    {
        if (entity->children_.empty())
        {
            entity->Remove();
            return true;
        }

        // Give initial value to first element if there isn't any. This will keep correct enum values when they are
        // merged into mega-enum.
        MetaEntity* firstVar = entity->children_[0].get();
        if (firstVar->GetDefaultValue().empty())
            firstVar->defaultValue_ = "0";

        std::string targetEnum;
        if (firstVar->name_.find("SDL") == 0)
            targetEnum = "SDL";
        else
        {
            spdlog::get("console")->warn("No idea where to put {} and it's siblings.", firstVar->name_);
            entity->Remove();
            return false;
        }

        // Sort out anonymous SDL enums
        auto* toEnum = generator->GetSymbol(targetEnum);
        if (toEnum == nullptr)
        {
            std::shared_ptr<MetaEntity> newEnum(new MetaEntity());
            toEnum = newEnum.get();
            toEnum->name_ = toEnum->uniqueName_ = toEnum->symbolName_ = targetEnum;
            toEnum->kind_ = cppast::cpp_entity_kind::enum_t;
            entity->GetParent()->Add(toEnum);
            generator->symbols_[targetEnum] = toEnum->shared_from_this();
        }

        auto children = entity->children_;
        for (const auto& child : children)
            toEnum->Add(child.get());

        // No longer needed
        entity->Remove();
    }

    return true;
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_POSIX_WRAPPER_SHARED_MEMORY_OBJECT_ALLOCATOR_HPP
#define IOX_UTILS_POSIX_WRAPPER_SHARED_MEMORY_OBJECT_ALLOCATOR_HPP

#include <cstdint>
namespace iox
{
namespace posix
{
class SharedMemoryObject;

class Allocator
{
    using byte_t = uint8_t;

  public:
    static constexpr uint64_t MEMORY_ALIGNMENT = 8U;
    /// @brief A bump allocator for the memory provided in the ctor arguments
    /// @param[in] startAddress of the memory this allocator manages
    /// @param[in] length of the memory this allocator manages
    Allocator(void* const startAddress, const uint64_t length) noexcept;

    Allocator(const Allocator&) = delete;
    Allocator(Allocator&&) noexcept = default;
    Allocator& operator=(const Allocator&) noexcept = delete;
    Allocator& operator=(Allocator&&) = default;
    ~Allocator() = default;

    /// @brief allocates on the memory supplied with the ctor
    /// @param[in] size of the memory to allocate
    /// @param[in] alignment of the memory to allocate
    /// @note terminates if out of memory of finalizeAllocation was called before
    void* allocate(const uint64_t size, const uint64_t alignment) noexcept;

  protected:
    friend class SharedMemoryObject;
    void finalizeAllocation() noexcept;

  private:
    byte_t* m_startAddress{nullptr};
    uint64_t m_length{0u};
    uint64_t m_currentPosition = 0u;
    bool m_allocationFinalized = false;
};
} // namespace posix
} // namespace iox

#endif // IOX_UTILS_POSIX_WRAPPER_SHARED_MEMORY_OBJECT_ALLOCATOR_HPP
<commit_msg>iox-#261 Rephrase doxygen comment in allocator<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_POSIX_WRAPPER_SHARED_MEMORY_OBJECT_ALLOCATOR_HPP
#define IOX_UTILS_POSIX_WRAPPER_SHARED_MEMORY_OBJECT_ALLOCATOR_HPP

#include <cstdint>
namespace iox
{
namespace posix
{
class SharedMemoryObject;

class Allocator
{
    using byte_t = uint8_t;

  public:
    static constexpr uint64_t MEMORY_ALIGNMENT = 8U;
    /// @brief A bump allocator for the memory provided in the ctor arguments
    /// @param[in] startAddress of the memory this allocator manages
    /// @param[in] length of the memory this allocator manages
    Allocator(void* const startAddress, const uint64_t length) noexcept;

    Allocator(const Allocator&) = delete;
    Allocator(Allocator&&) noexcept = default;
    Allocator& operator=(const Allocator&) noexcept = delete;
    Allocator& operator=(Allocator&&) = default;
    ~Allocator() = default;

    /// @brief allocates on the memory supplied with the ctor
    /// @param[in] size of the memory to allocate
    /// @param[in] alignment of the memory to allocate
    /// @note May terminate if out of memory or finalizeAllocation() was called before
    void* allocate(const uint64_t size, const uint64_t alignment) noexcept;

  protected:
    friend class SharedMemoryObject;
    void finalizeAllocation() noexcept;

  private:
    byte_t* m_startAddress{nullptr};
    uint64_t m_length{0u};
    uint64_t m_currentPosition = 0u;
    bool m_allocationFinalized = false;
};
} // namespace posix
} // namespace iox

#endif // IOX_UTILS_POSIX_WRAPPER_SHARED_MEMORY_OBJECT_ALLOCATOR_HPP
<|endoftext|>


<commit_before>#include "Global.h"
#include "Loggers/None.h"
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/date_duration.hpp>

//std::ofstream ofs("output.nl");
//Logger logger(std::ofstream("output.nl"));
float Global::INF = std::numeric_limits<float>::infinity();
float Global::MV = -999;
float Global::NC = -998;

boost::variate_generator<boost::mt19937, boost::uniform_01<> > Global::mRand(boost::mt19937(0), boost::uniform_01<>());

Logger* Global::logger = new LoggerNone(Logger::message);

void Global::setLogger(Logger* iLogger) {
   if(logger)
      delete logger;
   logger = iLogger;
}

bool Global::isValid(float iValue) {
   return !std::isnan(iValue) && !std::isinf(iValue) && !Global::isMissing(iValue);
}
bool Global::isMissing(float iValue) {
   return iValue == Global::MV;
}

float Global::getMoment(const std::vector<float>& iValues, int iMoment) {
   float moment = 0;
   // Find mean
   float mean = 0;
   int meanC = 0;
   for(int i = 0; i < (int) iValues.size(); i++) {
      assert(!std::isnan(iValues[i]));
      assert(!std::isinf(iValues[i]));
      if(!isMissing(iValues[i])) {
         mean += iValues[i];
         meanC++;
      }
   }
   if(meanC == 0) {
      return Global::MV;
   }

   mean = mean / meanC;

   if(iMoment == 1) {
      return mean;
   }
   else {
      // Compute central moment
      // TODO
      for(int i = 0; i < (int) iValues.size(); i++) {
         if(iValues[i] != Global::MV) {
            if(iMoment == 2)
               moment +=  (iValues[i] - mean)*(iValues[i] - mean);
            else
               moment += pow((double) iValues[i] - mean, (double) iMoment);
         }
      }
      if(meanC == 0)
         return Global::MV;
      else
         return moment / meanC;
   }
}
float Global::getTime(int iDate, int iInit, float iOffset) {
   float newOffset = iOffset + iInit;
   float time = getOffset(iDate, newOffset);
   assert(time >= 0 && time <= 24);
   return time;
}
int Global::getDate(int iDate, float iOffset) {
   return getDate(iDate, 0, iOffset);
}
int Global::getDayOfWeek(int iDate) {
   int year  = floor(iDate / 10000);
   int month = floor(iDate % 10000)/100;
   int day   = floor(iDate % 100);

   boost::gregorian::date currDate(year, month, day);
   return currDate.day_of_week();
}
int Global::getYear(int iDate) {
   return floor(iDate / 10000);
}
int Global::getMonth(int iDate) {
   return floor(iDate % 10000)/100;
}
int Global::getDay(int iDate) {
   return floor(iDate % 100);
}
int Global::getDate(int iDate, int iInit, float iOffset) {
   int year  = floor(iDate / 10000);
   int month = floor(iDate % 10000)/100;
   int day   = floor(iDate % 100);

   int offDay = floor((iOffset+iInit)/24);
   //std::cout << floor(2.5) << " " << ceil(2.5) << std::endl;
   //std::cout << floor(-2.5) << " " << ceil(-2.5) << std::endl;
   // Negative offsets round up, so subtract a day
   //if(iOffset < 0)
   //   offDay = iOffset - 1;

   boost::gregorian::date currDate(year, month, day);
   boost::gregorian::date_duration diff(offDay);
   boost::gregorian::date newDate = currDate + diff;
   int newYear  = newDate.year();
   int newMonth = newDate.month();
   int newDay   = newDate.day();
   int returnDate = newYear * 10000 + newMonth * 100 + newDay;
   return returnDate;
}

float Global::getOffset(int iDate, float iOffset) {
   float offset;
   if(iOffset < 0) {
      int addDay = -floor(iOffset/24);
      offset = iOffset + 24*addDay;
   }
   else {
      offset = fmod(iOffset, 24);
   }
   assert(offset < 24);
   assert(offset >= 0);
   return offset;
}

float Global::getTimeDiff(int iDate1, int iInit1, float iOffset1, int iDate2, int iInit2, float iOffset2) {
   int year1 = floor(iDate1 / 10000);
   int month1= floor(iDate1 % 10000)/100;
   int day1  = floor(iDate1 % 100);

   int year2 = floor(iDate2 / 10000);
   int month2= floor(iDate2 % 10000)/100;
   int day2  = floor(iDate2 % 100);

   boost::gregorian::date date1(year1, month1, day1);
   boost::gregorian::date date2(year2, month2, day2);
   boost::gregorian::date_period diff(date2, date1);
   long int numDays = diff.length().days();

   return numDays*24 + (iOffset1 - iOffset2);
}

float Global::getJulianDay(int iDate, int iInit, float iOffset) {
   int year  = floor(iDate / 10000);
   int month = floor(iDate % 10000)/100;
   int day   = floor(iDate % 100);

   boost::gregorian::date currDate(year, month, day);
   return currDate.day_of_year();

   /*
   struct tm tm1;

   tm1.tm_year  = year-1900;
   tm1.tm_mon   = month-1;
   tm1.tm_mday  = day;
   tm1.tm_hour  = 0;
   tm1.tm_min   = 0;
   tm1.tm_sec   = 0;
   tm1.tm_isdst = 0;

   time_t time = mktime(&tm1) + iOffset/60;

   struct tm *tm2 = gmtime(&time);

   return tm2->tm_yday;
   */

}
double Global::clock() {
   timeval t;
   gettimeofday(&t, NULL);
   double sec = (t.tv_sec);
   double msec= (t.tv_usec);
   return sec + msec/1e6;
}

int Global::getLowerIndex(float iX, std::vector<float> iValues) {
   int index = Global::MV;
   float nearestBelow = -Global::INF;
   for(int i = 0; i < (int) iValues.size(); i++) {
      float currValue = iValues[i];
      if(Global::isValid(currValue)) {
         if(currValue <= iX && currValue > nearestBelow) {
            index = i;
            nearestBelow = currValue;
         }
      }
   }
   return index;
}
int Global::getUpperIndex(float iX, std::vector<float> iValues) {
   int index = Global::MV;
   float nearestAbove = Global::INF;
   for(int i = iValues.size()-1; i >= 0; i--) {
      float currValue = iValues[i];
      if(Global::isValid(currValue)) {
         if(currValue >= iX && currValue < nearestAbove) {
            index = i;
            nearestAbove = currValue;
         }
      }
   }
   return index;
}
int Global::getNumValid(std::vector<float> iValues) {
   int num = 0;
   for(int i = 0; i < iValues.size(); i++) {
      if(Global::isValid(iValues[i])) {
         num++;
      }
   }
   return num;
}

float Global::interp(float x, float x0, float x1, float y0, float y1) {
   if(isValid(x) && isValid(x0) && isValid(x1) && isValid(y0) && isValid(y1)) {
      if(x0 == x1) {
         return (y1 + y0)/2;
      }
      else {
         assert(x >=x0);
         assert(x <=x1);
         assert(x1 != x0);
         return y0 + (y1 - y0)*(x - x0)/(x1 - x0);
      }
   }
   else {
      return Global::MV;
   }
}
float Global::getRand() {
   return mRand();
}

int Global::getCurrentDate() {
    boost::gregorian::date today = boost::gregorian::day_clock::local_day();
    return today.year()*10000 + today.month()*100 + today.day();
}

int Global::getInt(const std::string& iString) {
   std::stringstream ss(iString);
   int value;
   ss >> value;
   return(value);
}
<commit_msg>Fixes bug in computing time difference when using an init value<commit_after>#include "Global.h"
#include "Loggers/None.h"
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/date_duration.hpp>

//std::ofstream ofs("output.nl");
//Logger logger(std::ofstream("output.nl"));
float Global::INF = std::numeric_limits<float>::infinity();
float Global::MV = -999;
float Global::NC = -998;

boost::variate_generator<boost::mt19937, boost::uniform_01<> > Global::mRand(boost::mt19937(0), boost::uniform_01<>());

Logger* Global::logger = new LoggerNone(Logger::message);

void Global::setLogger(Logger* iLogger) {
   if(logger)
      delete logger;
   logger = iLogger;
}

bool Global::isValid(float iValue) {
   return !std::isnan(iValue) && !std::isinf(iValue) && !Global::isMissing(iValue);
}
bool Global::isMissing(float iValue) {
   return iValue == Global::MV;
}

float Global::getMoment(const std::vector<float>& iValues, int iMoment) {
   float moment = 0;
   // Find mean
   float mean = 0;
   int meanC = 0;
   for(int i = 0; i < (int) iValues.size(); i++) {
      assert(!std::isnan(iValues[i]));
      assert(!std::isinf(iValues[i]));
      if(!isMissing(iValues[i])) {
         mean += iValues[i];
         meanC++;
      }
   }
   if(meanC == 0) {
      return Global::MV;
   }

   mean = mean / meanC;

   if(iMoment == 1) {
      return mean;
   }
   else {
      // Compute central moment
      // TODO
      for(int i = 0; i < (int) iValues.size(); i++) {
         if(iValues[i] != Global::MV) {
            if(iMoment == 2)
               moment +=  (iValues[i] - mean)*(iValues[i] - mean);
            else
               moment += pow((double) iValues[i] - mean, (double) iMoment);
         }
      }
      if(meanC == 0)
         return Global::MV;
      else
         return moment / meanC;
   }
}
float Global::getTime(int iDate, int iInit, float iOffset) {
   float newOffset = iOffset + iInit;
   float time = getOffset(iDate, newOffset);
   assert(time >= 0 && time <= 24);
   return time;
}
int Global::getDate(int iDate, float iOffset) {
   return getDate(iDate, 0, iOffset);
}
int Global::getDayOfWeek(int iDate) {
   int year  = floor(iDate / 10000);
   int month = floor(iDate % 10000)/100;
   int day   = floor(iDate % 100);

   boost::gregorian::date currDate(year, month, day);
   return currDate.day_of_week();
}
int Global::getYear(int iDate) {
   return floor(iDate / 10000);
}
int Global::getMonth(int iDate) {
   return floor(iDate % 10000)/100;
}
int Global::getDay(int iDate) {
   return floor(iDate % 100);
}
int Global::getDate(int iDate, int iInit, float iOffset) {
   int year  = floor(iDate / 10000);
   int month = floor(iDate % 10000)/100;
   int day   = floor(iDate % 100);

   int offDay = floor((iOffset+iInit)/24);
   //std::cout << floor(2.5) << " " << ceil(2.5) << std::endl;
   //std::cout << floor(-2.5) << " " << ceil(-2.5) << std::endl;
   // Negative offsets round up, so subtract a day
   //if(iOffset < 0)
   //   offDay = iOffset - 1;

   boost::gregorian::date currDate(year, month, day);
   boost::gregorian::date_duration diff(offDay);
   boost::gregorian::date newDate = currDate + diff;
   int newYear  = newDate.year();
   int newMonth = newDate.month();
   int newDay   = newDate.day();
   int returnDate = newYear * 10000 + newMonth * 100 + newDay;
   return returnDate;
}

float Global::getOffset(int iDate, float iOffset) {
   float offset;
   if(iOffset < 0) {
      int addDay = -floor(iOffset/24);
      offset = iOffset + 24*addDay;
   }
   else {
      offset = fmod(iOffset, 24);
   }
   assert(offset < 24);
   assert(offset >= 0);
   return offset;
}

float Global::getTimeDiff(int iDate1, int iInit1, float iOffset1, int iDate2, int iInit2, float iOffset2) {
   int year1 = floor(iDate1 / 10000);
   int month1= floor(iDate1 % 10000)/100;
   int day1  = floor(iDate1 % 100);

   int year2 = floor(iDate2 / 10000);
   int month2= floor(iDate2 % 10000)/100;
   int day2  = floor(iDate2 % 100);

   boost::gregorian::date date1(year1, month1, day1);
   boost::gregorian::date date2(year2, month2, day2);
   boost::gregorian::date_period diff(date2, date1);
   long int numDays = diff.length().days();

   return numDays*24 + (iInit1 - iInit2) + (iOffset1 - iOffset2);
}

float Global::getJulianDay(int iDate, int iInit, float iOffset) {
   int year  = floor(iDate / 10000);
   int month = floor(iDate % 10000)/100;
   int day   = floor(iDate % 100);

   boost::gregorian::date currDate(year, month, day);
   return currDate.day_of_year();

   /*
   struct tm tm1;

   tm1.tm_year  = year-1900;
   tm1.tm_mon   = month-1;
   tm1.tm_mday  = day;
   tm1.tm_hour  = 0;
   tm1.tm_min   = 0;
   tm1.tm_sec   = 0;
   tm1.tm_isdst = 0;

   time_t time = mktime(&tm1) + iOffset/60;

   struct tm *tm2 = gmtime(&time);

   return tm2->tm_yday;
   */

}
double Global::clock() {
   timeval t;
   gettimeofday(&t, NULL);
   double sec = (t.tv_sec);
   double msec= (t.tv_usec);
   return sec + msec/1e6;
}

int Global::getLowerIndex(float iX, std::vector<float> iValues) {
   int index = Global::MV;
   float nearestBelow = -Global::INF;
   for(int i = 0; i < (int) iValues.size(); i++) {
      float currValue = iValues[i];
      if(Global::isValid(currValue)) {
         if(currValue <= iX && currValue > nearestBelow) {
            index = i;
            nearestBelow = currValue;
         }
      }
   }
   return index;
}
int Global::getUpperIndex(float iX, std::vector<float> iValues) {
   int index = Global::MV;
   float nearestAbove = Global::INF;
   for(int i = iValues.size()-1; i >= 0; i--) {
      float currValue = iValues[i];
      if(Global::isValid(currValue)) {
         if(currValue >= iX && currValue < nearestAbove) {
            index = i;
            nearestAbove = currValue;
         }
      }
   }
   return index;
}
int Global::getNumValid(std::vector<float> iValues) {
   int num = 0;
   for(int i = 0; i < iValues.size(); i++) {
      if(Global::isValid(iValues[i])) {
         num++;
      }
   }
   return num;
}

float Global::interp(float x, float x0, float x1, float y0, float y1) {
   if(isValid(x) && isValid(x0) && isValid(x1) && isValid(y0) && isValid(y1)) {
      if(x0 == x1) {
         return (y1 + y0)/2;
      }
      else {
         assert(x >=x0);
         assert(x <=x1);
         assert(x1 != x0);
         return y0 + (y1 - y0)*(x - x0)/(x1 - x0);
      }
   }
   else {
      return Global::MV;
   }
}
float Global::getRand() {
   return mRand();
}

int Global::getCurrentDate() {
    boost::gregorian::date today = boost::gregorian::day_clock::local_day();
    return today.year()*10000 + today.month()*100 + today.day();
}

int Global::getInt(const std::string& iString) {
   std::stringstream ss(iString);
   int value;
   ss >> value;
   return(value);
}
<|endoftext|>