<commit_before>/*
 * copyright: (c) RDO-Team, 2009
 * filename : rdoparser_base.cpp
 * author   :  ,
 * date     :
 * bref     :
 * indent   : 4T
 */

// ====================================================================== PCH
#include "rdo_lib/rdo_converter/pch.h"
// ====================================================================== INCLUDES
// ====================================================================== SYNOPSIS
#include "rdo_lib/rdo_converter/rdoparser_base.h"
#include "rdo_lib/rdo_converter/rdoparser_rdo.h"
#include "rdo_lib/rdo_converter/rdoparser_corba.h"
#include "rdo_lib/rdo_converter/rdopat.h"
#include "rdo_lib/rdo_converter/rdoopr.h"
#include "rdo_lib/rdo_converter/rdodpt.h"
#include "rdo_lib/rdo_converter/rdosmr.h"
#include "rdo_lib/rdo_converter/rdofrm.h"
#include "rdo_lib/rdo_converter/rdopmd.h"
#include "rdo_lib/rdo_converter/rdortp.h"
// ===============================================================================

OPEN_RDO_CONVERTER_NAMESPACE

// ----------------------------------------------------------------------------
// ---------- RDOParserContainer
// ----------------------------------------------------------------------------
RDOParserContainer::RDOParserContainer()
{}

RDOParserContainer::~RDOParserContainer()
{}

ruint RDOParserContainer::insert(rdoModelObjectsConvertor::RDOParseType type, CREF(LPRDOParserItem) pParser)
{
	ASSERT(pParser);

	ruint min, max;
	RDOParserContainer::getMinMax(type, min, max);
	if (min != UNDEFINED_ID && max != UNDEFINED_ID)
	{
		List::iterator it = m_list.find(min);
		if (it == m_list.end())
		{
			m_list[min] = pParser;
			return min;
		}
		else
		{
			ruint index = it->first;
			while (it != m_list.end() && it->first <= max)
			{
				index++;
				it++;
			}
			if (index <= max)
			{
				m_list[index] = pParser;
				return index;
			}
			else
			{
				return 0;
			}
		}
	}
	return 0;
}

void RDOParserContainer::getMinMax(rdoModelObjectsConvertor::RDOParseType type, REF(ruint) min, REF(ruint) max)
{
	switch (type)
	{
		case rdoModelObjectsConvertor::obPRE : min = 100;  max = 199;  break;
		case rdoModelObjectsConvertor::obRTP : min = 200;  max = 299;  break;
		case rdoModelObjectsConvertor::obRSS : min = 300;  max = 399;  break;
		case rdoModelObjectsConvertor::obFUN : min = 400;  max = 499;  break;
		case rdoModelObjectsConvertor::obPAT : min = 500;  max = 599;  break;
		case rdoModelObjectsConvertor::obOPR : min = 600;  max = 699;  break;
		case rdoModelObjectsConvertor::obDPT : min = 700;  max = 799;  break;
		case rdoModelObjectsConvertor::obPMD : min = 800;  max = 899;  break;
		case rdoModelObjectsConvertor::obFRM : min = 900;  max = 999;  break;
		case rdoModelObjectsConvertor::obSMR : min = 1000; max = 1099; break;
		case rdoModelObjectsConvertor::obPOST: min = 1100; max = 1199; break;
		default                              : min = UNDEFINED_ID; max = UNDEFINED_ID; break;
	}
}

// ----------------------------------------------------------------------------
// ---------- RDOParserContainerModel
// ----------------------------------------------------------------------------
RDOParserContainerModel::RDOParserContainerModel()
	: RDOParserContainer()
{
	insert(rdoModelObjectsConvertor::obPRE, rdo::Factory<RDOParserSTDFUN> ::create());
	insert(rdoModelObjectsConvertor::obPRE, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::SMR, cnv_smr_file_parse, cnv_smr_file_error, cnv_smr_file_lex));
	insert(rdoModelObjectsConvertor::obRTP, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::RTP, cnv_rtpparse, cnv_rtperror, cnv_rtplex));
	insert(rdoModelObjectsConvertor::obRTP, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_proc_rtp_parse, cnv_proc_rtp_error, cnv_proc_rtp_lex));
	insert(rdoModelObjectsConvertor::obRSS, rdo::Factory<RDOParserRSS>    ::create());
	insert(rdoModelObjectsConvertor::obRSS, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_proc_rss_parse, cnv_proc_rss_error, cnv_proc_rss_lex));
	insert(rdoModelObjectsConvertor::obFUN, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::FUN, cnv_funparse, cnv_funerror, cnv_funlex));
	insert(rdoModelObjectsConvertor::obPAT, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::PAT, cnv_patparse, cnv_paterror, cnv_patlex));
	insert(rdoModelObjectsConvertor::obOPR, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::OPR, cnv_oprparse, cnv_oprerror, cnv_oprlex));
	insert(rdoModelObjectsConvertor::obDPT, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_proc_opr_parse, cnv_proc_opr_error, cnv_proc_opr_lex));
	insert(rdoModelObjectsConvertor::obDPT, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_dptparse, cnv_dpterror, cnv_dptlex));
	insert(rdoModelObjectsConvertor::obPMD, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::PMD, cnv_pmdparse, cnv_pmderror, cnv_pmdlex));
	insert(rdoModelObjectsConvertor::obFRM, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::FRM, cnv_frmparse, cnv_frmerror, cnv_frmlex));
	insert(rdoModelObjectsConvertor::obSMR, rdo::Factory<RDOParserRSSPost>::create());
	insert(rdoModelObjectsConvertor::obSMR, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::SMR, cnv_smr_sim_parse, cnv_smr_sim_error, cnv_smr_sim_lex));
}

// ----------------------------------------------------------------------------
// ---------- RDOParserContainerSMRInfo
// ----------------------------------------------------------------------------
RDOParserContainerSMRInfo::RDOParserContainerSMRInfo()
	: RDOParserContainer()
{
	insert(rdoModelObjectsConvertor::obPRE, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::SMR, cnv_smr_file_parse, cnv_smr_file_error, cnv_smr_file_lex));
}

CLOSE_RDO_CONVERTER_NAMESPACE
<commit_msg> - из конвертора удалена корба<commit_after>/*
 * copyright: (c) RDO-Team, 2009
 * filename : rdoparser_base.cpp
 * author   :  ,
 * date     :
 * bref     :
 * indent   : 4T
 */

// ====================================================================== PCH
#include "rdo_lib/rdo_converter/pch.h"
// ====================================================================== INCLUDES
// ====================================================================== SYNOPSIS
#include "rdo_lib/rdo_converter/rdoparser_base.h"
#include "rdo_lib/rdo_converter/rdoparser_rdo.h"
#include "rdo_lib/rdo_converter/rdopat.h"
#include "rdo_lib/rdo_converter/rdoopr.h"
#include "rdo_lib/rdo_converter/rdodpt.h"
#include "rdo_lib/rdo_converter/rdosmr.h"
#include "rdo_lib/rdo_converter/rdofrm.h"
#include "rdo_lib/rdo_converter/rdopmd.h"
#include "rdo_lib/rdo_converter/rdortp.h"
// ===============================================================================

OPEN_RDO_CONVERTER_NAMESPACE

// ----------------------------------------------------------------------------
// ---------- RDOParserContainer
// ----------------------------------------------------------------------------
RDOParserContainer::RDOParserContainer()
{}

RDOParserContainer::~RDOParserContainer()
{}

ruint RDOParserContainer::insert(rdoModelObjectsConvertor::RDOParseType type, CREF(LPRDOParserItem) pParser)
{
	ASSERT(pParser);

	ruint min, max;
	RDOParserContainer::getMinMax(type, min, max);
	if (min != UNDEFINED_ID && max != UNDEFINED_ID)
	{
		List::iterator it = m_list.find(min);
		if (it == m_list.end())
		{
			m_list[min] = pParser;
			return min;
		}
		else
		{
			ruint index = it->first;
			while (it != m_list.end() && it->first <= max)
			{
				index++;
				it++;
			}
			if (index <= max)
			{
				m_list[index] = pParser;
				return index;
			}
			else
			{
				return 0;
			}
		}
	}
	return 0;
}

void RDOParserContainer::getMinMax(rdoModelObjectsConvertor::RDOParseType type, REF(ruint) min, REF(ruint) max)
{
	switch (type)
	{
		case rdoModelObjectsConvertor::obPRE : min = 100;  max = 199;  break;
		case rdoModelObjectsConvertor::obRTP : min = 200;  max = 299;  break;
		case rdoModelObjectsConvertor::obRSS : min = 300;  max = 399;  break;
		case rdoModelObjectsConvertor::obFUN : min = 400;  max = 499;  break;
		case rdoModelObjectsConvertor::obPAT : min = 500;  max = 599;  break;
		case rdoModelObjectsConvertor::obOPR : min = 600;  max = 699;  break;
		case rdoModelObjectsConvertor::obDPT : min = 700;  max = 799;  break;
		case rdoModelObjectsConvertor::obPMD : min = 800;  max = 899;  break;
		case rdoModelObjectsConvertor::obFRM : min = 900;  max = 999;  break;
		case rdoModelObjectsConvertor::obSMR : min = 1000; max = 1099; break;
		case rdoModelObjectsConvertor::obPOST: min = 1100; max = 1199; break;
		default                              : min = UNDEFINED_ID; max = UNDEFINED_ID; break;
	}
}

// ----------------------------------------------------------------------------
// ---------- RDOParserContainerModel
// ----------------------------------------------------------------------------
RDOParserContainerModel::RDOParserContainerModel()
	: RDOParserContainer()
{
	insert(rdoModelObjectsConvertor::obPRE, rdo::Factory<RDOParserSTDFUN> ::create());
	insert(rdoModelObjectsConvertor::obPRE, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::SMR, cnv_smr_file_parse, cnv_smr_file_error, cnv_smr_file_lex));
	insert(rdoModelObjectsConvertor::obRTP, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::RTP, cnv_rtpparse, cnv_rtperror, cnv_rtplex));
	insert(rdoModelObjectsConvertor::obRTP, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_proc_rtp_parse, cnv_proc_rtp_error, cnv_proc_rtp_lex));
	insert(rdoModelObjectsConvertor::obRSS, rdo::Factory<RDOParserRSS>    ::create());
	insert(rdoModelObjectsConvertor::obRSS, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_proc_rss_parse, cnv_proc_rss_error, cnv_proc_rss_lex));
	insert(rdoModelObjectsConvertor::obFUN, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::FUN, cnv_funparse, cnv_funerror, cnv_funlex));
	insert(rdoModelObjectsConvertor::obPAT, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::PAT, cnv_patparse, cnv_paterror, cnv_patlex));
	insert(rdoModelObjectsConvertor::obOPR, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::OPR, cnv_oprparse, cnv_oprerror, cnv_oprlex));
	insert(rdoModelObjectsConvertor::obDPT, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_proc_opr_parse, cnv_proc_opr_error, cnv_proc_opr_lex));
	insert(rdoModelObjectsConvertor::obDPT, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::DPT, cnv_dptparse, cnv_dpterror, cnv_dptlex));
	insert(rdoModelObjectsConvertor::obPMD, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::PMD, cnv_pmdparse, cnv_pmderror, cnv_pmdlex));
	insert(rdoModelObjectsConvertor::obFRM, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::FRM, cnv_frmparse, cnv_frmerror, cnv_frmlex));
	insert(rdoModelObjectsConvertor::obSMR, rdo::Factory<RDOParserRSSPost>::create());
	insert(rdoModelObjectsConvertor::obSMR, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::SMR, cnv_smr_sim_parse, cnv_smr_sim_error, cnv_smr_sim_lex));
}

// ----------------------------------------------------------------------------
// ---------- RDOParserContainerSMRInfo
// ----------------------------------------------------------------------------
RDOParserContainerSMRInfo::RDOParserContainerSMRInfo()
	: RDOParserContainer()
{
	insert(rdoModelObjectsConvertor::obPRE, rdo::Factory<RDOParserRDOItem>::create(rdoModelObjectsConvertor::SMR, cnv_smr_file_parse, cnv_smr_file_error, cnv_smr_file_lex));
}

CLOSE_RDO_CONVERTER_NAMESPACE
<|endoftext|>


<commit_before>#include "ScriptManager.hpp"

#include <angelscript.h>
#include <scriptbuilder/scriptbuilder.h>
#include <scriptstdstring/scriptstdstring.h>
#include "../Util/Log.hpp"
#include "../Util/FileSystem.hpp"
#include "../Hymn.hpp"
#include "../Scene/Scene.hpp"
#include "../Component/Script.hpp"
#include "../Entity/Entity.hpp"

void print(const std::string& message) {
    Log() << message;
}

ScriptManager::ScriptManager() {
    // Create the script engine
    engine = asCreateScriptEngine();

    // Set the message callback to receive information on errors in human readable form.
    engine->SetMessageCallback(asFUNCTION(AngelScriptMessageCallback), 0, asCALL_CDECL);

    // Register add-ons.
    RegisterStdString(engine);

    // Register functions.
    engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL);
}

ScriptManager::~ScriptManager() {
    engine->ShutDownAndRelease();
}

void ScriptManager::BuildScript(const std::string& name) {
    std::string filename = Hymn().GetPath() + FileSystem::DELIMITER + "Scripts" + FileSystem::DELIMITER + name + ".as";
    if (!FileSystem::FileExists(filename.c_str())) {
        Log() << "Script file does not exist: " << filename << "\n";
        return;
    }

    CScriptBuilder builder;
    int r = builder.StartNewModule(engine, name.c_str());
    if (r < 0)
        Log() << "Couldn't start new module: " << name << ".\n";

    r = builder.AddSectionFromFile(filename.c_str());
    if (r < 0)
        Log() << "File section could not be added: " << filename << ".\n";

    r = builder.BuildModule();
    if (r < 0)
        Log() << "Compile errors.\n";
}

void ScriptManager::Update(Scene& scene) {
    for (Component::Script* script : scene.GetComponents<Component::Script>()) {
        if (!script->initialized) {
            // Create, load and build script module.
            asIScriptModule* module = engine->GetModule(script->entity->name.c_str(), asGM_ONLY_IF_EXISTS);

            // Find function to call.
            asIScriptFunction* function = module->GetFunctionByDecl("void Init()");
            if (function == nullptr)
                Log() << "Couldn't find \"void Init()\" function.\n";

            // Create context, prepare it and execute.
            asIScriptContext* context = engine->CreateContext();
            context->Prepare(function);
            int r = context->Execute();
            if (r != asEXECUTION_FINISHED) {
                // The execution didn't complete as expected. Determine what happened.
                if (r == asEXECUTION_EXCEPTION) {
                  // An exception occurred, let the script writer know what happened so it can be corrected.
                  Log() << "An exception '" << context->GetExceptionString() << "' occurred. Please correct the code and try again.\n";
                }
            }

            // Clean up.
            context->Release();

            script->initialized = true;
        }
    }
}
<commit_msg>Register Entity type<commit_after>#include "ScriptManager.hpp"

#include <angelscript.h>
#include <scriptbuilder/scriptbuilder.h>
#include <scriptstdstring/scriptstdstring.h>
#include "../Util/Log.hpp"
#include "../Util/FileSystem.hpp"
#include "../Hymn.hpp"
#include "../Scene/Scene.hpp"
#include "../Component/Script.hpp"
#include "../Entity/Entity.hpp"

void print(const std::string& message) {
    Log() << message;
}

ScriptManager::ScriptManager() {
    // Create the script engine
    engine = asCreateScriptEngine();

    // Set the message callback to receive information on errors in human readable form.
    engine->SetMessageCallback(asFUNCTION(AngelScriptMessageCallback), 0, asCALL_CDECL);

    // Register add-ons.
    RegisterStdString(engine);

    // Register Entity.
    engine->RegisterObjectType("Entity", 0, asOBJ_REF | asOBJ_NOCOUNT);
    engine->RegisterObjectProperty("Entity", "string name", asOFFSET(Entity, name));

    // Register functions.
    engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL);
}

ScriptManager::~ScriptManager() {
    engine->ShutDownAndRelease();
}

void ScriptManager::BuildScript(const std::string& name) {
    std::string filename = Hymn().GetPath() + FileSystem::DELIMITER + "Scripts" + FileSystem::DELIMITER + name + ".as";
    if (!FileSystem::FileExists(filename.c_str())) {
        Log() << "Script file does not exist: " << filename << "\n";
        return;
    }

    CScriptBuilder builder;
    int r = builder.StartNewModule(engine, name.c_str());
    if (r < 0)
        Log() << "Couldn't start new module: " << name << ".\n";

    r = builder.AddSectionFromFile(filename.c_str());
    if (r < 0)
        Log() << "File section could not be added: " << filename << ".\n";

    r = builder.BuildModule();
    if (r < 0)
        Log() << "Compile errors.\n";
}

void ScriptManager::Update(Scene& scene) {
    for (Component::Script* script : scene.GetComponents<Component::Script>()) {
        if (!script->initialized) {
            // Create, load and build script module.
            asIScriptModule* module = engine->GetModule(script->entity->name.c_str(), asGM_ONLY_IF_EXISTS);

            // Find function to call.
            asIScriptFunction* function = module->GetFunctionByDecl("void Init()");
            if (function == nullptr)
                Log() << "Couldn't find \"void Init()\" function.\n";

            // Create context, prepare it and execute.
            asIScriptContext* context = engine->CreateContext();
            context->Prepare(function);
            int r = context->Execute();
            if (r != asEXECUTION_FINISHED) {
                // The execution didn't complete as expected. Determine what happened.
                if (r == asEXECUTION_EXCEPTION) {
                  // An exception occurred, let the script writer know what happened so it can be corrected.
                  Log() << "An exception '" << context->GetExceptionString() << "' occurred. Please correct the code and try again.\n";
                }
            }

            // Clean up.
            context->Release();

            script->initialized = true;
        }
    }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkBSplineInterpolateImageFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include <iostream>

#include "itkImage.h"
#include "itkSize.h"
#include "itkBSplineInterpolateImageFunction.h"
#include "itkImageRegionIterator.h"

#include "vnl/vnl_math.h"

  typedef double InputPixelType;
  typedef double CoordRepType;

// Set up for 1D Images
  enum { ImageDimension1D = 1 };

  typedef itk::Image< InputPixelType, ImageDimension1D > ImageType1D;
  typedef ImageType1D::Pointer ImageTypePtr1D;
  typedef ImageType1D::SizeType SizeType1D;
  typedef itk::BSplineInterpolateImageFunction<ImageType1D,CoordRepType> InterpolatorType1D;
//  typedef InterpolatorType1D::IndexType                 IndexType1D;
  typedef InterpolatorType1D::PointType                 PointType1D;
  typedef InterpolatorType1D::ContinuousIndexType       ContinuousIndexType1D;

  void set1DData(ImageType1D::Pointer);

  // Set up for 2D Images
  enum { ImageDimension2D = 2 };

  typedef itk::Image< InputPixelType, ImageDimension2D > ImageType2D;
  typedef ImageType2D::Pointer ImageTypePtr2D;
  typedef ImageType2D::SizeType SizeType2D;
  typedef itk::BSplineInterpolateImageFunction<ImageType2D,CoordRepType> InterpolatorType2D;
//  typedef InterpolatorType2D::IndexType                 IndexType2D;
  typedef InterpolatorType2D::PointType                 PointType2D;
  typedef InterpolatorType2D::ContinuousIndexType       ContinuousIndexType2D;

  void set2DData(ImageType2D::Pointer);

  // Set up for 3D Images
  enum { ImageDimension3D = 3 };

  typedef itk::Image< InputPixelType, ImageDimension3D > ImageType3D;
  typedef ImageType3D::Pointer ImageTypePtr3D;
  typedef ImageType3D::SizeType SizeType3D;
  typedef itk::BSplineInterpolateImageFunction<ImageType3D,CoordRepType> InterpolatorType3D;
  typedef InterpolatorType3D::IndexType                 IndexType3D;
  typedef InterpolatorType3D::PointType                 PointType3D;
  typedef InterpolatorType3D::ContinuousIndexType       ContinuousIndexType3D;

  void set3DData(ImageType3D::Pointer);
  void set3DDerivativeData(ImageType3D::Pointer);

/**
 * Test a geometric point. Returns true if test has passed,
 * returns false otherwise
 */
template <class TInterpolator, class PointType>
bool TestGeometricPoint(
const TInterpolator * interp,
const PointType& point,
bool isInside,
double trueValue )
{

  std::cout << " Point: " << point;

  bool bvalue = interp->IsInsideBuffer( point );
  std::cout << " Inside: " << bvalue << " ";

  if( bvalue != isInside )
    {
    std::cout << "*** Error: inside should be " << isInside << std::endl;
    return false;
    }

  if( isInside )
    {
    double value = interp->Evaluate( point );
    std::cout << " Value: " << value;

    if( vnl_math_abs( value - trueValue ) > 1e-9 )
      {
      std::cout << "*** Error: value should be " << trueValue << std::endl;
      return false;
      }
    }

  std::cout << std::endl;
  return true;

}

/**
 * Test a continuous index. Returns true if test has passed,
 * returns false otherwise
 */
template<class TInterpolator, class ContinuousIndexType>
bool TestContinuousIndex(
const TInterpolator * interp,
const ContinuousIndexType& index,
bool isInside,
double trueValue )
{

  std::cout << " Index: " << index;

  bool bvalue = interp->IsInsideBuffer( index );
  std::cout << " Inside: " << bvalue;

  if( bvalue != isInside )
    {
    std::cout << "*** Error: inside should be " << isInside << std::endl;
    return false;
    }

  if( isInside )
    {
    double value = interp->EvaluateAtContinuousIndex( index );
    std::cout << " Value: " << value;

    if( vnl_math_abs( value - trueValue ) > 1e-4 )
      {
      std::cout << "*** Error: value should be " << trueValue << std::endl;
      return false;
      }
    }

  std::cout << std::endl;
  return true;

}
/**
 * Test a continuous index Derivative. Returns true if test has passed,
 * returns false otherwise
 */
template<class TInterpolator, class ContinuousIndexType>
bool TestContinuousIndexDerivative(
const TInterpolator * interp,
const ContinuousIndexType& index,
bool isInside,
double * trueValue )
{

  std::cout << " Index: " << index;

  bool bvalue = interp->IsInsideBuffer( index );
  std::cout << " Inside: " << bvalue << "\n";

  if( bvalue != isInside )
    {
    std::cout << "*** Error: inside should be " << isInside << std::endl;
    return false;
    }

  if( isInside )
    {
    typename TInterpolator::CovariantVectorType value;
    double value2 = interp->EvaluateAtContinuousIndex( index );
    std::cout << "Interpolated Value: " << value2 << "\n";
    value = interp->EvaluateDerivativeAtContinuousIndex( index );
    std::cout << " Value: ";
    for (int i=0; i < ImageDimension3D; i++)
        {
        if (i != 0)
          {
          std::cout << ", ";
          }
        std::cout << value[i] ;
        if ( vnl_math_abs( value[i] - trueValue[i] ) > 1e-4 )
          {
          std::cout << "*** Error: value should be " << trueValue[i] << std::endl;
          return false;
          }
        }

    }

  std::cout << std::endl;
  return true;

}

// Run a series of tests to validate the 1D
// cubic spline implementation.
int test1DCubicSpline()
{
  int flag = 0;

  // Allocate a simple test image
  ImageTypePtr1D image = ImageType1D::New();

  set1DData(image);

  // Set origin and spacing of physical coordinates
  double origin [] = { 0.5  };
  double spacing[] = { 0.1  };
  image->SetOrigin(origin);
  image->SetSpacing(spacing);

  // Create and initialize the interpolator
  InterpolatorType1D::Pointer interp = InterpolatorType1D::New();
//  interp->SetSplineOrder(1);
  interp->SetInputImage(image);
  interp->Print( std::cout );

  // Test evaluation at continuous indices and corresponding
  //gemetric points
  std::cout << "Testing 1D Cubic B-Spline:\n";
  std::cout << "Evaluate at: " << std::endl;
  ContinuousIndexType1D cindex;
  PointType1D point;
  bool passed;

  // These values test 1) near border,
  //    2) inside
  //    3) integer value
  //    4) outside image
#define NPOINTS 4  // number of points
  double darray1[NPOINTS] = {1.4, 8.9, 10.0, 40.0};
  double truth[NPOINTS] = {334.41265437584, 18.158173426944, 4.0000, 0};
  bool b_Inside[NPOINTS] = {true, true, true, false};

  // an integer position inside the image
  for (int ii=0; ii < NPOINTS; ii++)
    {

    cindex = ContinuousIndexType1D(&darray1[ii]);
    passed = TestContinuousIndex<InterpolatorType1D, ContinuousIndexType1D >( interp, cindex, b_Inside[ii], truth[ii] );

    if( !passed ) flag += 1;

    interp->ConvertContinuousIndexToPoint( cindex, point );
    passed = TestGeometricPoint<InterpolatorType1D, PointType1D>( interp, point, b_Inside[ii], truth[ii]  );

    if( !passed ) flag += 1;
    }

  return (flag);
}

int test2DSpline()
{
  int flag = 0;

  /* Allocate a simple test image */
  ImageTypePtr2D image = ImageType2D::New();

  set2DData(image);

  /* Set origin and spacing of physical coordinates */
  double origin [] = { 0.5, 1.0 };
  double spacing[] = { 0.1, 0.5  };
  image->SetOrigin(origin);
  image->SetSpacing(spacing);

  /* Create and initialize the interpolator */
  for (unsigned int splineOrder = 0; splineOrder<=5; splineOrder++)
    {
    InterpolatorType2D::Pointer interp = InterpolatorType2D::New();
    interp->SetSplineOrder(splineOrder);

    interp->SetInputImage(image);
    interp->Print( std::cout );

    /* Test evaluation at continuous indices and corresponding
    gemetric points */
    std::cout << "Testing 2D B-Spline of Order "<< splineOrder << ":\n";
    std::cout << "Evaluate at: " << std::endl;
    ContinuousIndexType2D cindex;
    PointType2D point;
    bool passed;

    // These values test 1) near border,
    //    2) inside
    //    3) integer value
    //    4) outside image
#define NPOINTS2 4  // number of points

      double darray1[NPOINTS2][2] = {{0.1, 0.2}, {3.4, 5.8}, {4.0, 6.0}, { 2.1, 8.0}};
      double truth[NPOINTS2][6] = {{154.5, 140.14, 151.86429192392, 151.650316034, 151.865916515, 151.882483111},
        { 0, 13.84, 22.688125812495, 22.411473093, 22.606968306, 22.908345604},
        { 36.2, 36.2, 36.2, 36.2, 36.2, 36.2 },
        {0, 0, 0,0,0,0}};
    bool b_Inside[NPOINTS2] = {true, true, true, false};
   // double darray1[2];

    // an integer position inside the image
    for (int ii=0; ii < NPOINTS2; ii++)
      {
     // darray1[0] = darray[ii][0];
     // darray1[1] = darray[ii][1];
      cindex = ContinuousIndexType2D(&darray1[ii][0]);
      passed = TestContinuousIndex<InterpolatorType2D, ContinuousIndexType2D >( interp, cindex, b_Inside[ii], truth[ii][splineOrder] );

      if( !passed ) flag += 1;

      interp->ConvertContinuousIndexToPoint( cindex, point );
      passed = TestGeometricPoint<InterpolatorType2D, PointType2D>( interp, point, b_Inside[ii], truth[ii][splineOrder ]  );

      if( !passed ) flag += 1;
      }
    }  // end of splineOrder

  return (flag);
}

int test3DSpline()
{
  int flag = 0;

  /* Allocate a simple test image */
  ImageTypePtr3D image = ImageType3D::New();

  set3DData(image);

  /* Set origin and spacing of physical coordinates */
  double origin [] = { 0.5, 1.0, 1.333};
  double spacing[] = { 0.1, 0.5, 0.75  };
  image->SetOrigin(origin);
  image->SetSpacing(spacing);

  /* Create and initialize the interpolator */
  for (int splineOrder = 2; splineOrder<=5; splineOrder++)
    {
    InterpolatorType3D::Pointer interp = InterpolatorType3D::New();
    interp->SetSplineOrder(splineOrder);
    interp->SetInputImage(image);
    interp->Print( std::cout );

    /* Test evaluation at continuous indices and corresponding
    gemetric points */
    std::cout << "Testing 3D B-Spline of Order "<< splineOrder << ":\n";
    std::cout << "Evaluate at: " << std::endl;
    ContinuousIndexType3D cindex;
    PointType3D point;
    bool passed;

    // These values test
    //    1) near border,
    //    2) inside
    //    3) integer value
    //    4) outside image
#define NPOINTS3 4  // number of points

      double darray1[NPOINTS3][ImageDimension3D] = {{0.1, 20.1, 28.4}, {21.58, 34.5, 17.2 }, {10, 20, 12}, { 15, 20.2, 31}};
      double truth[NPOINTS3][4] = {{48.621593795, 48.651173138, 48.656914878, 48.662256571},
        { 73.280126903, 73.280816965, 73.282780615, 73.285315943},
        { 42.0, 42.0, 42.0, 42.0},
        {0,0,0,0}};
    bool b_Inside[NPOINTS3] = {true, true, true, false};
   // double darray1[2];

    // an integer position inside the image
    for (int ii=0; ii < NPOINTS3; ii++)
      {
     // darray1[0] = darray[ii][0];
     // darray1[1] = darray[ii][1];
      cindex = ContinuousIndexType3D(&darray1[ii][0]);
      passed = TestContinuousIndex<InterpolatorType3D, ContinuousIndexType3D >( interp, cindex, b_Inside[ii], truth[ii][splineOrder -2] );

      if( !passed ) flag += 1;

      interp->ConvertContinuousIndexToPoint( cindex, point );
      passed = TestGeometricPoint<InterpolatorType3D, PointType3D>( interp, point, b_Inside[ii], truth[ii][splineOrder -2]  );

      if( !passed ) flag += 1;
      }
    }  // end of splineOrder

  return (flag);
}

int test3DSplineDerivative()
{
  int flag = 0;

  /* Allocate a simple test image */
  ImageTypePtr3D image = ImageType3D::New();

  set3DDerivativeData(image);

  /* Set origin and spacing of physical coordinates */
//  double origin [] = { 0.5, 1.0, 1.333};
//  double spacing[] = { 0.1, 0.5, 0.75  };
  double origin [] = { 0.0, 0.0, 0.0};
  double spacing[] = { 1,1,1  };
  image->SetOrigin(origin);
  image->SetSpacing(spacing);

  /* Create and initialize the interpolator */
  for (int splineOrder = 1; splineOrder<=5; splineOrder++)
    {
    InterpolatorType3D::Pointer interp = InterpolatorType3D::New();
    interp->SetSplineOrder(splineOrder);
    interp->SetInputImage(image);
    interp->Print( std::cout );

    /* Test evaluation at continuous indices and corresponding
    gemetric points */
    std::cout << "Testing Derivatives of 3D B-Spline of Order "<< splineOrder << ":\n";
    std::cout << "Evaluate at: " << std::endl;
    ContinuousIndexType3D cindex;
    PointType3D point;
    bool passed;

    // These values test
    //    1) near border,
    //    2) inside
    //    3) integer value
    //    4) outside image
#define NPOINTS4 4  // number of points

    double darray1[NPOINTS4][ImageDimension3D] = {{25.3,26.8,24.5}, {21.0, 1.4, 0.6}, {18, 31, 10 }, { 4.3, 17.9, 42} };
    // Calculated Truth is: {19.4158,5,-24}, {0.9,5,71.6}, {-7.2, 5, 34}, {0,0,0}
    // TODO: Value near border is way off, is this an algorithm problem?  Also,
    //       Is error for 1st order splines in the expected range?
    double truth[5][NPOINTS4][ImageDimension3D] = {
      { {23.6,   5,-24}, {0,        5,       72.0},    {-3.0,     5,       32},      {0,0,0} },
      { {19.345, 5,-24}, {0.875,    4.8873,  98.6607}, {-7.525,   5,       34},      {0,0,0} },
      { {19.399, 5,-24}, {0.9,      4.95411, 92.9006}, {-7.2,     5,       33.9999}, {0,0,0} },
      { {19.4164,5,-24}, {0.9,      4.9925,  94.5082}, {-7.2,     5.00044, 33.9976}, {0,0,0} },
      { {19.4223,5,-24}, {0.900157, 5.0544,  93.8607}, {-7.19929, 5.00189, 33.9879}, {0,0,0} }};
    bool b_Inside[NPOINTS4] = {true, true, true, false};
   // double darray1[2];

    // an integer position inside the image
    for (int ii=0; ii < NPOINTS4; ii++)
      {
     // darray1[0] = darray[ii][0];
     // darray1[1] = darray[ii][1];
      cindex = ContinuousIndexType3D(&darray1[ii][0]);
      passed = TestContinuousIndexDerivative<InterpolatorType3D, ContinuousIndexType3D >( interp, cindex, b_Inside[ii], &truth[splineOrder - 1][ii][0] );

      if( !passed ) flag += 1;

//      interp->ConvertContinuousIndexToPoint( cindex, point );
//      passed = TestGeometricPoint<InterpolatorType3D, PointType3D>( interp, point, b_Inside[ii], truth[ii][splineOrder -2]  );

      if( !passed ) flag += 1;
      }
    }  // end of splineOrder

  return (flag);
}

int
itkBSplineInterpolateImageFunctionTest(
    int argc,
    char **argv)
{
  int flag = 0;           /* Did this test program work? */

  std::cout << "Testing B Spline interpolation methods:\n";

  flag += test1DCubicSpline();

  flag += test2DSpline();

  flag += test3DSpline();

  flag += test3DSplineDerivative();

  /* Return results of test */
  if (flag != 0) {
    std::cout << "*** " << flag << " tests failed" << std::endl;

    return 1; }
  else {
    std::cout << "All tests successfully passed" << std::endl;
    return 0; }

}

void set1DData(ImageType1D::Pointer imgPtr)
{

  SizeType1D size = {{36}};
  double mydata[36] = {454.0000,  369.4000,  295.2000,  230.8000,  175.6000,  129.0000,   90.4000, 59.2000,   34.8000,   16.6000,    4.0000,   -3.6000,   -6.8000,   -6.2000,
    -2.4000,    4.0000,   12.4000,   22.2000,   32.8000,   43.6000,   54.0000, 63.4000,   71.2000,   76.8000,   79.6000,   79.0000,   74.4000,   65.2000,
    50.8000,   30.6000,    4.0000,  -29.6000,  -70.8000, -120.2000, -178.4000, -246.0000 };

  ImageType1D::RegionType region;
  region.SetSize( size );

  imgPtr->SetLargestPossibleRegion( region );
  imgPtr->SetBufferedRegion( region );
  imgPtr->Allocate();

  typedef itk::ImageRegionIterator<ImageType1D>    InputIterator;

  InputIterator inIter( imgPtr, region );

  int j = 0;
  while( !inIter.IsAtEnd() )
    {
    inIter.Set(mydata[j]);
    ++inIter;
    ++j;
    }

}

void set2DData(ImageType2D::Pointer imgPtr)
{
  SizeType2D size = {{7,7}};
  double mydata[ 49 ] = {  154.5000,   82.4000,   30.9000,         0,  -10.3000,         0,   30.9000 ,
    117.0000,   62.4000,   23.4000,         0,   -7.8000,         0,   23.4000 ,
   18.0000,    9.6000,    3.6000,         0,   -1.2000,         0,    3.6000 ,
 -120.0000,  -64.0000,  -24.0000,         0,    8.0000,         0,  -24.0000 ,
 -274.5000, -146.4000,  -54.9000,         0,   18.3000,         0,  -54.9000 ,
 -423.0000, -225.6000,  -84.6000,         0,   28.2000,         0,  -84.6000 ,
 -543.0000, -289.6000, -108.6000,         0,   36.2000,         0, -108.6000  };

  ImageType2D::RegionType region;
  region.SetSize( size );

  imgPtr->SetLargestPossibleRegion( region );
  imgPtr->SetBufferedRegion( region );
  imgPtr->Allocate();

  typedef itk::ImageRegionIterator<ImageType2D>  InputIterator;

  InputIterator inIter( imgPtr, region );

  int j = 0;
  while( !inIter.IsAtEnd() )
    {
    inIter.Set(mydata[j]);
    ++inIter;
    ++j;
    }

}

void set3DData(ImageType3D::Pointer imgPtr)
{
  SizeType3D size = {{80,40,30}};

  /* Allocate a simple test image */
  ImageType3D::RegionType region;
  region.SetSize( size );

  imgPtr->SetLargestPossibleRegion( region );
  imgPtr->SetBufferedRegion( region );
  imgPtr->Allocate();

  /* Set origin and spacing of physical coordinates */

  /* Initialize the image contents */
  IndexType3D index;
  for (unsigned int slice = 0; slice < size[2]; slice++) {
      index[2] = slice;
      for (unsigned int row = 0; row < size[1]; row++) {
          index[1] = row;
          for (unsigned int col = 0; col < size[0]; col++) {
              index[0] = col;
              imgPtr->SetPixel(index, slice+row+col);
          }
      }
  }
}

void set3DDerivativeData(ImageType3D::Pointer imgPtr)
{
  SizeType3D size = {{41,41,41}};

  /* Allocate a simple test image */
  ImageType3D::RegionType region;
  region.SetSize( size );

  imgPtr->SetLargestPossibleRegion( region );
  imgPtr->SetBufferedRegion( region );
  imgPtr->Allocate();

  /* Set origin and spacing of physical coordinates */

  /* Initialize the image contents */
  // Note [x,y,z] = [x,y,z] - 20 so that image ranges from -20 + 20;
  // f(x) = 0.1x^4 - 0.5x^3 + 2x - 43
  // f(y) = 5y + 7
  // f(z) = -2z^2 - 6z + 10
  // df(x)/dx = 0.4x^3 - 1.5x^2 + 2
  // df(y)/dy = 5
  // df(z)/dz = -4z - 6
  double value;
  double slice1, row1, col1;
  IndexType3D index;
  for (unsigned int slice = 0; slice < size[2]; slice++) {
      index[2] = slice;
      slice1 = slice - 20.0;  // Center offset
      for (unsigned int row = 0; row < size[1]; row++) {
          index[1] = row;
          row1 = row - 20.0;  // Center
          for (unsigned int col = 0; col < size[0]; col++) {
              index[0] = col;
              col1 = col - 20.0; //Center
              value = 0.1*col1*col1*col1*col1 - 0.5* col1*col1*col1 + 2.0*col1 - 43.0;
              value += 5.0*row1 + 7.0;
              value += -2.0*slice1*slice1 - 6.0* slice1 + 10.0;
              imgPtr->SetPixel(index, value);
//              imgPtr->SetPixel(index, row);
          }
      }
  }

}

<commit_msg>STYLE: Moved itkBSplineInterpolateImageFunctionTest to BasicFilters<commit_after><|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007      Torsten Rahn     <tackat@kde.org>"
//

#include "GlobeScanlineTextureMapper.h"

#include <cmath>

#include <QtCore/QDebug>

#include "GeoPoint.h"
#include "GeoPolygon.h"
#include "katlasdirs.h"
#include "TextureTile.h"
#include "TileLoader.h"

// Defining INTERLACE will make sure that for two subsequent scanlines
// every second scanline will be a deep copy of the first scanline.
// This results in a more coarse resolution and in a speedup for the
// texture mapping of approx. 25%.

// #define INTERLACE

GlobeScanlineTextureMapper::GlobeScanlineTextureMapper( const QString& path, QObject * parent  )
    : AbstractScanlineTextureMapper( path, parent )
{
    m_interpolate  = false;
    m_nBest = 0;

    m_n = 0;
    m_nInverse = 0.0;

    m_x = 0;
    m_y = 0;

    m_qr = 0.0;
    m_qx = 0.0;
    m_qy = 0.0;
    m_qz = 0.0;

    m_interlaced = true;
}

GlobeScanlineTextureMapper::~GlobeScanlineTextureMapper()
{
}

void GlobeScanlineTextureMapper::resizeMap(int width, int height)
{
    AbstractScanlineTextureMapper::resizeMap( width, height );

    // Find the optimal interpolation interval m_n for the
    // current image canvas width
    m_nBest = 2;

    int  nEvalMin = m_imageWidth - 1;
    for ( int it = 1; it < 48; ++it ) {
        int nEval = ( m_imageWidth - 1 ) / it + ( m_imageWidth - 1 ) % it;
        if ( nEval < nEvalMin ) {
            nEvalMin = nEval;
            m_nBest = it;
        }
    }
    // qDebug() << QString( "Optimized n = %1, remainder: %2" )
    //.arg(m_nBest).arg( ( m_imageWidth ) % m_nBest );
}

void GlobeScanlineTextureMapper::mapTexture(QImage* canvasImage,
                                            const int& radius,
                                            Quaternion& planetAxis)
{
    // Scanline based algorithm to texture map a sphere

    // Initialize needed variables:
    double  lon = 0.0;
    double  lat = 0.0;

    const double  inverseRadius = 1.0 / (double)(radius);

    m_tilePosX = 65535;
    m_tilePosY = 65535;

    m_fullNormLon = m_fullRangeLon - m_tilePosX;
    m_halfNormLon = m_halfRangeLon - m_tilePosX;
    m_halfNormLat = m_halfRangeLat - m_tilePosY;
    m_quatNormLat = m_quatRangeLat - m_tilePosY;

    // Reset backend
    m_tileLoader->resetTilehash();
    selectTileLevel(radius);

    // Evaluate the degree of interpolation
    m_n    = ( m_imageRadius < radius * radius ) ? m_nBest : 8;
    m_nInverse = 1.0 / (double)(m_n);

    // Calculate north pole position to decrease pole distortion later on
    Quaternion  northPole = GeoPoint( 0.0, (double)( -M_PI * 0.5 ) ).quaternion();

    Quaternion  inversePlanetAxis = planetAxis;
    inversePlanetAxis = inversePlanetAxis.inverse();

    northPole.rotateAroundAxis( inversePlanetAxis );

    // Calculate axis matrix to represent the planet's rotation.
    matrix  planetAxisMatrix;
    planetAxis.toMatrix( planetAxisMatrix );

    int skip = ( m_interlaced == true ) ? 1 : 0;

    // Calculate the actual y-range of the map on the screen
    const int yTop = ( ( m_imageHeight / 2 - radius < 0 )
                       ? 0 : m_imageHeight / 2 - radius );
    const int yBottom = ( (yTop == 0)
                          ? m_imageHeight - skip
                          : yTop + radius + radius - skip );

    for ( m_y = yTop; m_y < yBottom ; ++m_y ) {

        // Evaluate coordinates for the 3D position vector of the current pixel
        m_qy = inverseRadius * (double)( m_y - m_imageHeight / 2 );
        m_qr = 1.0 - m_qy * m_qy;

        // rx is the radius component in x direction
        int rx = (int)sqrt( (double)( radius * radius
                      - ( ( m_y - m_imageHeight / 2 )
                      * ( m_y - m_imageHeight / 2 ) ) ) );

        // Calculate the actual x-range of the map within the current scanline
        const int xLeft  = ( ( m_imageWidth / 2 - rx > 0 )
                             ? m_imageWidth / 2 - rx : 0 );
        const int xRight = ( ( m_imageWidth / 2 - rx > 0 )
                             ? xLeft + rx + rx : canvasImage -> width() );

        m_scanLine = (QRgb*)( canvasImage->scanLine( m_y ) ) + xLeft;

        int  xIpLeft  = 1;
        int  xIpRight = m_n * (int)( xRight / m_n - 1) + 1;

        if ( m_imageWidth / 2 - rx > 0 ) {
            xIpLeft  = m_n * (int)( xLeft  / m_n + 1 );
            xIpRight = m_n * (int)( xRight / m_n - 1 );
        }

        // Decrease pole distortion due to linear approximation ( y-axis )
        bool crossingPoleArea = false;
        int northPoleY = m_imageHeight / 2 + (int)( radius * northPole.v[Q_Y] );
        if ( northPole.v[Q_Z] > 0
             && northPoleY - ( m_n * 0.75 ) <= m_y
             && northPoleY + ( m_n * 0.75 ) >= m_y )
        {
            crossingPoleArea = true;
        }

        int ncount = 0;

        for ( int m_x = xLeft; m_x < xRight; ++m_x ) {
            // Prepare for interpolation

            int  leftInterval = xIpLeft + ncount * m_n;

            if ( m_x >= xIpLeft && m_x <= xIpRight ) {

                // Decrease pole distortion due to linear approximation ( x-axis )
                int northPoleX = m_imageWidth / 2 + (int)( radius * northPole.v[Q_X] );

//                qDebug() << QString("NorthPole X: %1, LeftInterval: %2").arg( northPoleX ).arg( leftInterval );
                if ( crossingPoleArea == true
                     && northPoleX >= leftInterval + m_n
                     && northPoleX < leftInterval + 2*m_n
                     && m_x < leftInterval + 3 * m_n )
                {
                    m_interpolate = false;
                }
                else {
                    m_x += m_n - 1;

                    m_interpolate = true;
                    ++ncount;
                }
            }
            else
                m_interpolate = false;

            // Evaluate more coordinates for the 3D position vector of
            // the current pixel.
            m_qx = (double)( m_x - m_imageWidth / 2 ) * inverseRadius;

            double qr2z = m_qr - m_qx * m_qx;
            m_qz = ( qr2z > 0.0 ) ? sqrt( qr2z ) : 0.0;

            // Create Quaternion from vector coordinates and rotate it
            // around globe axis
            m_qpos.set( 0.0, m_qx, m_qy, m_qz );
            m_qpos.rotateAroundAxis( planetAxisMatrix );

            m_qpos.getSpherical( lon, lat );

            // Approx for m_n-1 out of n pixels within the boundary of
            // xIpLeft to xIpRight
            if ( m_interpolate ) {
                pixelValueApprox( lon, lat, m_scanLine );

                m_scanLine += ( m_n - 1 );
            }

            // You can temporarily comment out this line and run Marble
            // to understand the interpolation:
            pixelValue( lon, lat, m_scanLine );

            m_prevLat = lat; // preparing for interpolation
            m_prevLon = lon;

            ++m_scanLine;
        }

        if ( m_interlaced == true ) { // copy scanline to improve performance

            int pixelByteSize = canvasImage->bytesPerLine() / m_imageWidth;

            memcpy( canvasImage->scanLine( m_y + 1 ) + xLeft * pixelByteSize,
                    canvasImage->scanLine( m_y ) + xLeft * pixelByteSize,
                    ( xRight - xLeft ) * pixelByteSize );
            ++m_y;
        }
    }

    m_tileLoader->cleanupTilehash();
}

// This method interpolates color values for skipped pixels in a scanline.
//
// While moving along the scanline we don't move from pixel to pixel but
// leave out m_n pixels each time and calculate the exact position and
// color value for the new pixel. The pixel values in between get
// approximated through linear interpolation across the direct connecting
// line on the original tiles directly.
// This method will do by far most of the calculations for the
// texturemapping, so we move towards integer math to improve speed.

void GlobeScanlineTextureMapper::pixelValueApprox(const double& lon,
                                                  const double& lat,
                                                  QRgb *scanLine)
{
    // stepLon/Lat: Distance between two subsequent approximated positions

    double stepLat = lat - m_prevLat;
    double stepLon = lon - m_prevLon;

    // As long as the distance is smaller than 180 deg we can assume that
    // we didn't cross the dateline.

    if ( fabs(stepLon) < M_PI ) {
        const int itStepLon = (int)( stepLon * m_nInverse * m_rad2PixelX * 128.0 );
        const int itStepLat = (int)( stepLat * m_nInverse * m_rad2PixelY * 128.0 );

        m_prevLon *= m_rad2PixelX;
        m_prevLat *= m_rad2PixelY;

        // To improve speed we unroll
        // AbstractScanlineTextureMapper::pixelValue(...) here and
        // calculate the performance critical issues via integers

        int itLon = (int)( ( m_prevLon + m_halfNormLon ) * 128.0 );
        int itLat = (int)( ( m_prevLat + m_quatNormLat ) * 128.0 );

        if ( m_tile->depth() == 8 ) {
            for ( int j=1; j < m_n; ++j ) {
                m_posX = ( itLon + itStepLon * j ) >> 7;
                m_posY = ( itLat + itStepLat * j ) >> 7;

                if (  m_posX >= m_tileLoader->tileWidth()
                   || m_posX < 0
                   || m_posY >= m_tileLoader->tileHeight()
                   || m_posY < 0 )
                {
                    nextTile();
                    itLon = (int)( ( m_prevLon + m_halfNormLon ) * 128.0 );
                    itLat = (int)( ( m_prevLat + m_quatNormLat ) * 128.0 );
                    m_posX = ( itLon + itStepLon * j ) >> 7;
                    m_posY = ( itLat + itStepLat * j ) >> 7;
                }

                *scanLine = m_tile->jumpTable8[m_posY][m_posX ];
                ++scanLine;
            }
        }
        else {
            for ( int j=1; j < m_n; ++j ) {
                m_posX = ( itLon + itStepLon * j ) >> 7;
                m_posY = ( itLat + itStepLat * j ) >> 7;

                if ( m_posX >= m_tileLoader->tileWidth()
                     || m_posX < 0
                     || m_posY >= m_tileLoader->tileHeight()
                     || m_posY < 0 )
                {
                    nextTile();
                    itLon = (int)( ( m_prevLon + m_halfNormLon ) * 128.0 );
                    itLat = (int)( ( m_prevLat + m_quatNormLat ) * 128.0 );
                    m_posX = ( itLon + itStepLon * j ) >> 7;
                    m_posY = ( itLat + itStepLat * j ) >> 7;
                }

                *scanLine = m_tile->jumpTable32[m_posY][m_posX ];
                ++scanLine;
            }
        }
    }

    // For the case where we cross the dateline between (lon, lat) and
    // (prevlon, prevlat) we need a more sophisticated calculation.
    // However as this will happen rather rarely, we use
    // pixelValue(...) directly to make the code more readable.

    else {
        stepLon = ( TWOPI - fabs(stepLon) ) * m_nInverse;
        stepLat = stepLat * m_nInverse;
        // We need to distinguish two cases:
        // crossing the dateline from east to west ...

        if ( m_prevLon < lon ) {
            for ( int j = 1; j < m_n; ++j ) {
                m_prevLat += stepLat;
                m_prevLon -= stepLon;
                if ( m_prevLon <= -M_PI )
                    m_prevLon += TWOPI;
                pixelValue( m_prevLon, m_prevLat, scanLine );
                ++scanLine;
            }
        }

        // ... and vice versa: from west to east.

        else {
            double curStepLon = lon - m_n * stepLon;

            for ( int j = 1; j < m_n; ++j ) {
                m_prevLat += stepLat;
                curStepLon += stepLon;
                double  evalLon = curStepLon;
                if ( curStepLon <= -M_PI )
                    evalLon += TWOPI;
                pixelValue( evalLon, m_prevLat, scanLine);
                ++scanLine;
            }
        }
    }
}
<commit_msg>Ooops, disable by default<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007      Torsten Rahn     <tackat@kde.org>"
//

#include "GlobeScanlineTextureMapper.h"

#include <cmath>

#include <QtCore/QDebug>

#include "GeoPoint.h"
#include "GeoPolygon.h"
#include "katlasdirs.h"
#include "TextureTile.h"
#include "TileLoader.h"

// Defining INTERLACE will make sure that for two subsequent scanlines
// every second scanline will be a deep copy of the first scanline.
// This results in a more coarse resolution and in a speedup for the
// texture mapping of approx. 25%.

// #define INTERLACE

GlobeScanlineTextureMapper::GlobeScanlineTextureMapper( const QString& path, QObject * parent  )
    : AbstractScanlineTextureMapper( path, parent )
{
    m_interpolate  = false;
    m_nBest = 0;

    m_n = 0;
    m_nInverse = 0.0;

    m_x = 0;
    m_y = 0;

    m_qr = 0.0;
    m_qx = 0.0;
    m_qy = 0.0;
    m_qz = 0.0;

    m_interlaced = false;
}

GlobeScanlineTextureMapper::~GlobeScanlineTextureMapper()
{
}

void GlobeScanlineTextureMapper::resizeMap(int width, int height)
{
    AbstractScanlineTextureMapper::resizeMap( width, height );

    // Find the optimal interpolation interval m_n for the
    // current image canvas width
    m_nBest = 2;

    int  nEvalMin = m_imageWidth - 1;
    for ( int it = 1; it < 48; ++it ) {
        int nEval = ( m_imageWidth - 1 ) / it + ( m_imageWidth - 1 ) % it;
        if ( nEval < nEvalMin ) {
            nEvalMin = nEval;
            m_nBest = it;
        }
    }
    // qDebug() << QString( "Optimized n = %1, remainder: %2" )
    //.arg(m_nBest).arg( ( m_imageWidth ) % m_nBest );
}

void GlobeScanlineTextureMapper::mapTexture(QImage* canvasImage,
                                            const int& radius,
                                            Quaternion& planetAxis)
{
    // Scanline based algorithm to texture map a sphere

    // Initialize needed variables:
    double  lon = 0.0;
    double  lat = 0.0;

    const double  inverseRadius = 1.0 / (double)(radius);

    m_tilePosX = 65535;
    m_tilePosY = 65535;

    m_fullNormLon = m_fullRangeLon - m_tilePosX;
    m_halfNormLon = m_halfRangeLon - m_tilePosX;
    m_halfNormLat = m_halfRangeLat - m_tilePosY;
    m_quatNormLat = m_quatRangeLat - m_tilePosY;

    // Reset backend
    m_tileLoader->resetTilehash();
    selectTileLevel(radius);

    // Evaluate the degree of interpolation
    m_n    = ( m_imageRadius < radius * radius ) ? m_nBest : 8;
    m_nInverse = 1.0 / (double)(m_n);

    // Calculate north pole position to decrease pole distortion later on
    Quaternion  northPole = GeoPoint( 0.0, (double)( -M_PI * 0.5 ) ).quaternion();

    Quaternion  inversePlanetAxis = planetAxis;
    inversePlanetAxis = inversePlanetAxis.inverse();

    northPole.rotateAroundAxis( inversePlanetAxis );

    // Calculate axis matrix to represent the planet's rotation.
    matrix  planetAxisMatrix;
    planetAxis.toMatrix( planetAxisMatrix );

    int skip = ( m_interlaced == true ) ? 1 : 0;

    // Calculate the actual y-range of the map on the screen
    const int yTop = ( ( m_imageHeight / 2 - radius < 0 )
                       ? 0 : m_imageHeight / 2 - radius );
    const int yBottom = ( (yTop == 0)
                          ? m_imageHeight - skip
                          : yTop + radius + radius - skip );

    for ( m_y = yTop; m_y < yBottom ; ++m_y ) {

        // Evaluate coordinates for the 3D position vector of the current pixel
        m_qy = inverseRadius * (double)( m_y - m_imageHeight / 2 );
        m_qr = 1.0 - m_qy * m_qy;

        // rx is the radius component in x direction
        int rx = (int)sqrt( (double)( radius * radius
                      - ( ( m_y - m_imageHeight / 2 )
                      * ( m_y - m_imageHeight / 2 ) ) ) );

        // Calculate the actual x-range of the map within the current scanline
        const int xLeft  = ( ( m_imageWidth / 2 - rx > 0 )
                             ? m_imageWidth / 2 - rx : 0 );
        const int xRight = ( ( m_imageWidth / 2 - rx > 0 )
                             ? xLeft + rx + rx : canvasImage -> width() );

        m_scanLine = (QRgb*)( canvasImage->scanLine( m_y ) ) + xLeft;

        int  xIpLeft  = 1;
        int  xIpRight = m_n * (int)( xRight / m_n - 1) + 1;

        if ( m_imageWidth / 2 - rx > 0 ) {
            xIpLeft  = m_n * (int)( xLeft  / m_n + 1 );
            xIpRight = m_n * (int)( xRight / m_n - 1 );
        }

        // Decrease pole distortion due to linear approximation ( y-axis )
        bool crossingPoleArea = false;
        int northPoleY = m_imageHeight / 2 + (int)( radius * northPole.v[Q_Y] );
        if ( northPole.v[Q_Z] > 0
             && northPoleY - ( m_n * 0.75 ) <= m_y
             && northPoleY + ( m_n * 0.75 ) >= m_y )
        {
            crossingPoleArea = true;
        }

        int ncount = 0;

        for ( int m_x = xLeft; m_x < xRight; ++m_x ) {
            // Prepare for interpolation

            int  leftInterval = xIpLeft + ncount * m_n;

            if ( m_x >= xIpLeft && m_x <= xIpRight ) {

                // Decrease pole distortion due to linear approximation ( x-axis )
                int northPoleX = m_imageWidth / 2 + (int)( radius * northPole.v[Q_X] );

//                qDebug() << QString("NorthPole X: %1, LeftInterval: %2").arg( northPoleX ).arg( leftInterval );
                if ( crossingPoleArea == true
                     && northPoleX >= leftInterval + m_n
                     && northPoleX < leftInterval + 2*m_n
                     && m_x < leftInterval + 3 * m_n )
                {
                    m_interpolate = false;
                }
                else {
                    m_x += m_n - 1;

                    m_interpolate = true;
                    ++ncount;
                }
            }
            else
                m_interpolate = false;

            // Evaluate more coordinates for the 3D position vector of
            // the current pixel.
            m_qx = (double)( m_x - m_imageWidth / 2 ) * inverseRadius;

            double qr2z = m_qr - m_qx * m_qx;
            m_qz = ( qr2z > 0.0 ) ? sqrt( qr2z ) : 0.0;

            // Create Quaternion from vector coordinates and rotate it
            // around globe axis
            m_qpos.set( 0.0, m_qx, m_qy, m_qz );
            m_qpos.rotateAroundAxis( planetAxisMatrix );

            m_qpos.getSpherical( lon, lat );

            // Approx for m_n-1 out of n pixels within the boundary of
            // xIpLeft to xIpRight
            if ( m_interpolate ) {
                pixelValueApprox( lon, lat, m_scanLine );

                m_scanLine += ( m_n - 1 );
            }

            // You can temporarily comment out this line and run Marble
            // to understand the interpolation:
            pixelValue( lon, lat, m_scanLine );

            m_prevLat = lat; // preparing for interpolation
            m_prevLon = lon;

            ++m_scanLine;
        }

        if ( m_interlaced == true ) { // copy scanline to improve performance

            int pixelByteSize = canvasImage->bytesPerLine() / m_imageWidth;

            memcpy( canvasImage->scanLine( m_y + 1 ) + xLeft * pixelByteSize,
                    canvasImage->scanLine( m_y ) + xLeft * pixelByteSize,
                    ( xRight - xLeft ) * pixelByteSize );
            ++m_y;
        }
    }

    m_tileLoader->cleanupTilehash();
}

// This method interpolates color values for skipped pixels in a scanline.
//
// While moving along the scanline we don't move from pixel to pixel but
// leave out m_n pixels each time and calculate the exact position and
// color value for the new pixel. The pixel values in between get
// approximated through linear interpolation across the direct connecting
// line on the original tiles directly.
// This method will do by far most of the calculations for the
// texturemapping, so we move towards integer math to improve speed.

void GlobeScanlineTextureMapper::pixelValueApprox(const double& lon,
                                                  const double& lat,
                                                  QRgb *scanLine)
{
    // stepLon/Lat: Distance between two subsequent approximated positions

    double stepLat = lat - m_prevLat;
    double stepLon = lon - m_prevLon;

    // As long as the distance is smaller than 180 deg we can assume that
    // we didn't cross the dateline.

    if ( fabs(stepLon) < M_PI ) {
        const int itStepLon = (int)( stepLon * m_nInverse * m_rad2PixelX * 128.0 );
        const int itStepLat = (int)( stepLat * m_nInverse * m_rad2PixelY * 128.0 );

        m_prevLon *= m_rad2PixelX;
        m_prevLat *= m_rad2PixelY;

        // To improve speed we unroll
        // AbstractScanlineTextureMapper::pixelValue(...) here and
        // calculate the performance critical issues via integers

        int itLon = (int)( ( m_prevLon + m_halfNormLon ) * 128.0 );
        int itLat = (int)( ( m_prevLat + m_quatNormLat ) * 128.0 );

        if ( m_tile->depth() == 8 ) {
            for ( int j=1; j < m_n; ++j ) {
                m_posX = ( itLon + itStepLon * j ) >> 7;
                m_posY = ( itLat + itStepLat * j ) >> 7;

                if (  m_posX >= m_tileLoader->tileWidth()
                   || m_posX < 0
                   || m_posY >= m_tileLoader->tileHeight()
                   || m_posY < 0 )
                {
                    nextTile();
                    itLon = (int)( ( m_prevLon + m_halfNormLon ) * 128.0 );
                    itLat = (int)( ( m_prevLat + m_quatNormLat ) * 128.0 );
                    m_posX = ( itLon + itStepLon * j ) >> 7;
                    m_posY = ( itLat + itStepLat * j ) >> 7;
                }

                *scanLine = m_tile->jumpTable8[m_posY][m_posX ];
                ++scanLine;
            }
        }
        else {
            for ( int j=1; j < m_n; ++j ) {
                m_posX = ( itLon + itStepLon * j ) >> 7;
                m_posY = ( itLat + itStepLat * j ) >> 7;

                if ( m_posX >= m_tileLoader->tileWidth()
                     || m_posX < 0
                     || m_posY >= m_tileLoader->tileHeight()
                     || m_posY < 0 )
                {
                    nextTile();
                    itLon = (int)( ( m_prevLon + m_halfNormLon ) * 128.0 );
                    itLat = (int)( ( m_prevLat + m_quatNormLat ) * 128.0 );
                    m_posX = ( itLon + itStepLon * j ) >> 7;
                    m_posY = ( itLat + itStepLat * j ) >> 7;
                }

                *scanLine = m_tile->jumpTable32[m_posY][m_posX ];
                ++scanLine;
            }
        }
    }

    // For the case where we cross the dateline between (lon, lat) and
    // (prevlon, prevlat) we need a more sophisticated calculation.
    // However as this will happen rather rarely, we use
    // pixelValue(...) directly to make the code more readable.

    else {
        stepLon = ( TWOPI - fabs(stepLon) ) * m_nInverse;
        stepLat = stepLat * m_nInverse;
        // We need to distinguish two cases:
        // crossing the dateline from east to west ...

        if ( m_prevLon < lon ) {
            for ( int j = 1; j < m_n; ++j ) {
                m_prevLat += stepLat;
                m_prevLon -= stepLon;
                if ( m_prevLon <= -M_PI )
                    m_prevLon += TWOPI;
                pixelValue( m_prevLon, m_prevLat, scanLine );
                ++scanLine;
            }
        }

        // ... and vice versa: from west to east.

        else {
            double curStepLon = lon - m_n * stepLon;

            for ( int j = 1; j < m_n; ++j ) {
                m_prevLat += stepLat;
                curStepLon += stepLon;
                double  evalLon = curStepLon;
                if ( curStepLon <= -M_PI )
                    evalLon += TWOPI;
                pixelValue( evalLon, m_prevLat, scanLine);
                ++scanLine;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>removing #<commit_after><|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "attribute_aspect_delayer.h"
#include <vespa/searchlib/attribute/configconverter.h>
#include <vespa/searchcore/proton/common/i_document_type_inspector.h>
#include <vespa/searchcore/proton/common/i_indexschema_inspector.h>
#include <vespa/searchcore/proton/common/config_hash.hpp>
#include <vespa/vespalib/stllike/hash_set.hpp>
#include <vespa/config-attributes.h>
#include <vespa/config-summary.h>
#include <vespa/config-summarymap.h>

using search::attribute::ConfigConverter;
using vespa::config::search::AttributesConfig;
using vespa::config::search::AttributesConfigBuilder;
using vespa::config::search::SummarymapConfig;
using vespa::config::search::SummarymapConfigBuilder;
using vespa::config::search::SummaryConfig;
using search::attribute::BasicType;

namespace proton {

namespace {

using AttributesConfigHash = ConfigHash<AttributesConfig::Attribute>;

bool fastPartialUpdateAttribute(const search::attribute::Config &cfg) {
    auto basicType = cfg.basicType().type();
    return ((basicType != BasicType::Type::PREDICATE) &&
            (basicType != BasicType::Type::TENSOR) &&
            (basicType != BasicType::Type::REFERENCE));
}

bool isStructFieldAttribute(const vespalib::string &name) {
    return name.find('.') != vespalib::string::npos;
}

bool willTriggerReprocessOnAttributeAspectRemoval(const search::attribute::Config &cfg,
                                                  const IIndexschemaInspector &indexschemaInspector,
                                                  const vespalib::string &name)
{
    return fastPartialUpdateAttribute(cfg) && !indexschemaInspector.isStringIndex(name) && !isStructFieldAttribute(name);
}

class KnownSummaryFields
{
    vespalib::hash_set<vespalib::string> _fields;

public:
    KnownSummaryFields(const SummaryConfig &summaryConfig);
    ~KnownSummaryFields();

    bool known(const vespalib::string &fieldName) const {
        return _fields.find(fieldName) != _fields.end();
    }
};

KnownSummaryFields::KnownSummaryFields(const SummaryConfig &summaryConfig)
    : _fields()
{
    for (const auto &summaryClass : summaryConfig.classes) {
        for (const auto &summaryField : summaryClass.fields) {
            _fields.insert(summaryField.name);
        }
    }
}

KnownSummaryFields::~KnownSummaryFields() = default;

}

AttributeAspectDelayer::AttributeAspectDelayer()
    : _attributesConfig(std::make_shared<AttributesConfigBuilder>()),
      _summarymapConfig(std::make_shared<SummarymapConfigBuilder>())
{
}

AttributeAspectDelayer::~AttributeAspectDelayer()
{
}

std::shared_ptr<AttributeAspectDelayer::AttributesConfig>
AttributeAspectDelayer::getAttributesConfig() const
{
    return _attributesConfig;
}

std::shared_ptr<AttributeAspectDelayer::SummarymapConfig>
AttributeAspectDelayer::getSummarymapConfig() const
{
    return _summarymapConfig;
}

namespace {

void
handleNewAttributes(const AttributesConfig &oldAttributesConfig,
                    const AttributesConfig &newAttributesConfig,
                    const SummarymapConfig &newSummarymapConfig,
                    const IIndexschemaInspector &oldIndexschemaInspector,
                    const IDocumentTypeInspector &inspector,
                    AttributesConfigBuilder &attributesConfig,
                    SummarymapConfigBuilder &summarymapConfig)
{
    vespalib::hash_set<vespalib::string> delayed;
    vespalib::hash_set<vespalib::string> delayedStruct;
    AttributesConfigHash oldAttrs(oldAttributesConfig.attribute);
    for (const auto &newAttr : newAttributesConfig.attribute) {
        search::attribute::Config newCfg = ConfigConverter::convert(newAttr);
        if (!inspector.hasUnchangedField(newAttr.name)) {
            // No reprocessing due to field type change, just use new config
            attributesConfig.attribute.emplace_back(newAttr);
        } else {
            auto oldAttr = oldAttrs.lookup(newAttr.name);
            if (oldAttr != nullptr) {
                search::attribute::Config oldCfg = ConfigConverter::convert(*oldAttr);
                if (willTriggerReprocessOnAttributeAspectRemoval(oldCfg, oldIndexschemaInspector, newAttr.name) || !oldAttr->fastaccess) {
                    // Delay change of fast access flag
                    newCfg.setFastAccess(oldAttr->fastaccess);
                    auto modNewAttr = newAttr;
                    modNewAttr.fastaccess = oldAttr->fastaccess;
                    attributesConfig.attribute.emplace_back(modNewAttr);
                    // TODO: Don't delay change of fast access flag if
                    // attribute type can change without doucment field
                    // type changing (needs a smarter attribute
                    // reprocessing initializer).
                } else {
                    // Don't delay change of fast access flag from true to
                    // false when removing attribute aspect in a way that
                    // doesn't trigger reprocessing.
                    attributesConfig.attribute.emplace_back(newAttr);
                }
            } else {
                // Delay addition of attribute aspect
                delayed.insert(newAttr.name);
                auto pos = newAttr.name.find('.');
                if (pos != vespalib::string::npos) {
                    delayedStruct.insert(newAttr.name.substr(0, pos));
                }
            }
        }
    }
    for (const auto &override : newSummarymapConfig.override) {
        if (override.command == "attribute") {
            auto itr = delayed.find(override.field);
            if (itr == delayed.end()) {
                summarymapConfig.override.emplace_back(override);
            }
        } else if (override.command == "attributecombiner") {
            auto itr = delayedStruct.find(override.field);
            if (itr == delayedStruct.end()) {
                summarymapConfig.override.emplace_back(override);
            }
        } else {
            summarymapConfig.override.emplace_back(override);
        }
    }
}

void
handleOldAttributes(const AttributesConfig &oldAttributesConfig,
                    const AttributesConfig &newAttributesConfig,
                    const SummarymapConfig &oldSummarymapConfig,
                    const SummaryConfig &newSummaryConfig,
                    const IIndexschemaInspector &oldIndexschemaInspector,
                    const IDocumentTypeInspector &inspector,
                    AttributesConfigBuilder &attributesConfig,
                    SummarymapConfigBuilder &summarymapConfig)
{
    vespalib::hash_set<vespalib::string> delayed;
    KnownSummaryFields knownSummaryFields(newSummaryConfig);
    AttributesConfigHash newAttrs(newAttributesConfig.attribute);
    for (const auto &oldAttr : oldAttributesConfig.attribute) {
        search::attribute::Config oldCfg = ConfigConverter::convert(oldAttr);
        if (inspector.hasUnchangedField(oldAttr.name)) {
            auto newAttr = newAttrs.lookup(oldAttr.name);
            if (newAttr == nullptr) {
                // Delay removal of attribute aspect if it would trigger
                // reprocessing.
                if (willTriggerReprocessOnAttributeAspectRemoval(oldCfg, oldIndexschemaInspector, oldAttr.name)) {
                    attributesConfig.attribute.emplace_back(oldAttr);
                    delayed.insert(oldAttr.name);
                }
            }
        }
    }
    for (const auto &override : oldSummarymapConfig.override) {
        if (override.command == "attribute") {
            auto itr = delayed.find(override.field);
            if (itr != delayed.end() && knownSummaryFields.known(override.field)) {
                summarymapConfig.override.emplace_back(override);
            }
        }
    }
}

}

void
AttributeAspectDelayer::setup(const AttributesConfig &oldAttributesConfig,
                             const SummarymapConfig &oldSummarymapConfig,
                             const AttributesConfig &newAttributesConfig,
                             const SummaryConfig &newSummaryConfig,
                             const SummarymapConfig &newSummarymapConfig,
                             const IIndexschemaInspector &oldIndexschemaInspector,
                             const IDocumentTypeInspector &inspector)
{
    (void) newSummaryConfig;
    handleNewAttributes(oldAttributesConfig, newAttributesConfig,
                        newSummarymapConfig,
                        oldIndexschemaInspector, inspector,
                        *_attributesConfig, *_summarymapConfig);
    handleOldAttributes(oldAttributesConfig, newAttributesConfig,
                        oldSummarymapConfig, newSummaryConfig,
                        oldIndexschemaInspector, inspector,
                        *_attributesConfig, *_summarymapConfig);
}

} // namespace proton
<commit_msg>Remove unneeded use of variable.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "attribute_aspect_delayer.h"
#include <vespa/searchlib/attribute/configconverter.h>
#include <vespa/searchcore/proton/common/i_document_type_inspector.h>
#include <vespa/searchcore/proton/common/i_indexschema_inspector.h>
#include <vespa/searchcore/proton/common/config_hash.hpp>
#include <vespa/vespalib/stllike/hash_set.hpp>
#include <vespa/config-attributes.h>
#include <vespa/config-summary.h>
#include <vespa/config-summarymap.h>

using search::attribute::ConfigConverter;
using vespa::config::search::AttributesConfig;
using vespa::config::search::AttributesConfigBuilder;
using vespa::config::search::SummarymapConfig;
using vespa::config::search::SummarymapConfigBuilder;
using vespa::config::search::SummaryConfig;
using search::attribute::BasicType;

namespace proton {

namespace {

using AttributesConfigHash = ConfigHash<AttributesConfig::Attribute>;

bool fastPartialUpdateAttribute(const search::attribute::Config &cfg) {
    auto basicType = cfg.basicType().type();
    return ((basicType != BasicType::Type::PREDICATE) &&
            (basicType != BasicType::Type::TENSOR) &&
            (basicType != BasicType::Type::REFERENCE));
}

bool isStructFieldAttribute(const vespalib::string &name) {
    return name.find('.') != vespalib::string::npos;
}

bool willTriggerReprocessOnAttributeAspectRemoval(const search::attribute::Config &cfg,
                                                  const IIndexschemaInspector &indexschemaInspector,
                                                  const vespalib::string &name)
{
    return fastPartialUpdateAttribute(cfg) && !indexschemaInspector.isStringIndex(name) && !isStructFieldAttribute(name);
}

class KnownSummaryFields
{
    vespalib::hash_set<vespalib::string> _fields;

public:
    KnownSummaryFields(const SummaryConfig &summaryConfig);
    ~KnownSummaryFields();

    bool known(const vespalib::string &fieldName) const {
        return _fields.find(fieldName) != _fields.end();
    }
};

KnownSummaryFields::KnownSummaryFields(const SummaryConfig &summaryConfig)
    : _fields()
{
    for (const auto &summaryClass : summaryConfig.classes) {
        for (const auto &summaryField : summaryClass.fields) {
            _fields.insert(summaryField.name);
        }
    }
}

KnownSummaryFields::~KnownSummaryFields() = default;

}

AttributeAspectDelayer::AttributeAspectDelayer()
    : _attributesConfig(std::make_shared<AttributesConfigBuilder>()),
      _summarymapConfig(std::make_shared<SummarymapConfigBuilder>())
{
}

AttributeAspectDelayer::~AttributeAspectDelayer()
{
}

std::shared_ptr<AttributeAspectDelayer::AttributesConfig>
AttributeAspectDelayer::getAttributesConfig() const
{
    return _attributesConfig;
}

std::shared_ptr<AttributeAspectDelayer::SummarymapConfig>
AttributeAspectDelayer::getSummarymapConfig() const
{
    return _summarymapConfig;
}

namespace {

void
handleNewAttributes(const AttributesConfig &oldAttributesConfig,
                    const AttributesConfig &newAttributesConfig,
                    const SummarymapConfig &newSummarymapConfig,
                    const IIndexschemaInspector &oldIndexschemaInspector,
                    const IDocumentTypeInspector &inspector,
                    AttributesConfigBuilder &attributesConfig,
                    SummarymapConfigBuilder &summarymapConfig)
{
    vespalib::hash_set<vespalib::string> delayed;
    vespalib::hash_set<vespalib::string> delayedStruct;
    AttributesConfigHash oldAttrs(oldAttributesConfig.attribute);
    for (const auto &newAttr : newAttributesConfig.attribute) {
        search::attribute::Config newCfg = ConfigConverter::convert(newAttr);
        if (!inspector.hasUnchangedField(newAttr.name)) {
            // No reprocessing due to field type change, just use new config
            attributesConfig.attribute.emplace_back(newAttr);
        } else {
            auto oldAttr = oldAttrs.lookup(newAttr.name);
            if (oldAttr != nullptr) {
                search::attribute::Config oldCfg = ConfigConverter::convert(*oldAttr);
                if (willTriggerReprocessOnAttributeAspectRemoval(oldCfg, oldIndexschemaInspector, newAttr.name) || !oldAttr->fastaccess) {
                    // Delay change of fast access flag
                    newCfg.setFastAccess(oldAttr->fastaccess);
                    auto modNewAttr = newAttr;
                    modNewAttr.fastaccess = oldAttr->fastaccess;
                    attributesConfig.attribute.emplace_back(modNewAttr);
                    // TODO: Don't delay change of fast access flag if
                    // attribute type can change without doucment field
                    // type changing (needs a smarter attribute
                    // reprocessing initializer).
                } else {
                    // Don't delay change of fast access flag from true to
                    // false when removing attribute aspect in a way that
                    // doesn't trigger reprocessing.
                    attributesConfig.attribute.emplace_back(newAttr);
                }
            } else {
                // Delay addition of attribute aspect
                delayed.insert(newAttr.name);
                auto pos = newAttr.name.find('.');
                if (pos != vespalib::string::npos) {
                    delayedStruct.insert(newAttr.name.substr(0, pos));
                }
            }
        }
    }
    for (const auto &override : newSummarymapConfig.override) {
        if (override.command == "attribute") {
            auto itr = delayed.find(override.field);
            if (itr == delayed.end()) {
                summarymapConfig.override.emplace_back(override);
            }
        } else if (override.command == "attributecombiner") {
            auto itr = delayedStruct.find(override.field);
            if (itr == delayedStruct.end()) {
                summarymapConfig.override.emplace_back(override);
            }
        } else {
            summarymapConfig.override.emplace_back(override);
        }
    }
}

void
handleOldAttributes(const AttributesConfig &oldAttributesConfig,
                    const AttributesConfig &newAttributesConfig,
                    const SummarymapConfig &oldSummarymapConfig,
                    const SummaryConfig &newSummaryConfig,
                    const IIndexschemaInspector &oldIndexschemaInspector,
                    const IDocumentTypeInspector &inspector,
                    AttributesConfigBuilder &attributesConfig,
                    SummarymapConfigBuilder &summarymapConfig)
{
    vespalib::hash_set<vespalib::string> delayed;
    KnownSummaryFields knownSummaryFields(newSummaryConfig);
    AttributesConfigHash newAttrs(newAttributesConfig.attribute);
    for (const auto &oldAttr : oldAttributesConfig.attribute) {
        search::attribute::Config oldCfg = ConfigConverter::convert(oldAttr);
        if (inspector.hasUnchangedField(oldAttr.name)) {
            auto newAttr = newAttrs.lookup(oldAttr.name);
            if (newAttr == nullptr) {
                // Delay removal of attribute aspect if it would trigger
                // reprocessing.
                if (willTriggerReprocessOnAttributeAspectRemoval(oldCfg, oldIndexschemaInspector, oldAttr.name)) {
                    attributesConfig.attribute.emplace_back(oldAttr);
                    delayed.insert(oldAttr.name);
                }
            }
        }
    }
    for (const auto &override : oldSummarymapConfig.override) {
        if (override.command == "attribute") {
            auto itr = delayed.find(override.field);
            if (itr != delayed.end() && knownSummaryFields.known(override.field)) {
                summarymapConfig.override.emplace_back(override);
            }
        }
    }
}

}

void
AttributeAspectDelayer::setup(const AttributesConfig &oldAttributesConfig,
                             const SummarymapConfig &oldSummarymapConfig,
                             const AttributesConfig &newAttributesConfig,
                             const SummaryConfig &newSummaryConfig,
                             const SummarymapConfig &newSummarymapConfig,
                             const IIndexschemaInspector &oldIndexschemaInspector,
                             const IDocumentTypeInspector &inspector)
{
    handleNewAttributes(oldAttributesConfig, newAttributesConfig,
                        newSummarymapConfig,
                        oldIndexschemaInspector, inspector,
                        *_attributesConfig, *_summarymapConfig);
    handleOldAttributes(oldAttributesConfig, newAttributesConfig,
                        oldSummarymapConfig, newSummaryConfig,
                        oldIndexschemaInspector, inspector,
                        *_attributesConfig, *_summarymapConfig);
}

} // namespace proton
<|endoftext|>


<commit_before>#include "tateti_struct.h"
#include <iostream>
using namespace std	;

tateti_struct::tateti_struct(MODE m) {
	this.table = new char[3][3]
	this.mode = m;
	this.activeplayer = get_player1();
}

tateti_struct::init_game(){
	while(!game_over())
	{
		int x;
		int y;

		cout<< "gimme me ya move "<< actual_player() << "!: ";
		cin >> x >> y;
		set_slot(x,y, actual_player);
		this.activeplayer = !this.activeplayer
	}

}

tateti_struct::get_player1(){
	default_random_engine generator;
	uniform_int_distribution<int> distribution(0,1);
	return distribution(generator);
}

tateti_struct::actual_player(){}//TODO

tateti_struct::set_slot(){} //TODO

tateti_struct::game_over()
{
	return no_valid_moves(0,0) || someone_won();
}//TODO

tateti_struct::someone_won();
{

}
<commit_msg>I MEAN; IT WAAAAS WY BETTER THAT NEMO!<commit_after>#include "tateti_struct.h"
#include <iostream>
using namespace std	;

tateti_struct::tateti_struct(MODE m) {
	this.table = new char[3][3]
	this.mode = m;
	this.activeplayer = get_player1();
}

tateti_struct::init_game(){
	while(!game_over())
	{
		int x;
		int y;

		cout<< "gimme me ya move "<< actual_player() << "!: ";
		cin >> x >> y;
		cout << endl;
		while(not_a_valid_move(x,y)){
			cout<<"stop being a cunt!:"<< endl;
			cin >> x >> y;
			cout << endl;
		}
		set_slot(x,y, actual_player);
		print_ttt();
		this.activeplayer = !this.activeplayer;

	}

}

bool tateti_struct::get_player1(){
	default_random_engine generator;
	uniform_int_distribution<int> distribution(0,1);
	return (bool)distribution(generator);
}

bool tateti_struct::actual_player(){}//TODO

void tateti_struct::set_slot(int x, int y, bool actPlyr )
{
	actPlyr?(this.table[x][y]='X'):(this.table[x][y]='O')
	//this.table[x][y] = (actPlyr? 'X' : 'O')
}

bool tateti_struct::game_over()
{
	//return no_valid_moves(0,0) || someone_won();
}//TODO

void tateti_struct::print_ttt()
{
	for(i=0; i<3, i++)
	{
		for(j=0; j<3, j++)
		{
			cout << not_a_valid_move(i,j)?('-'):this.table[x][y] << "\t"
		}
		cout << endl;
	}
}

bool tateti_struct::not_a_valid_move(int x,int y);
{
	return this.table[x][y]!=NULL;
}
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#pragma once

#include <fmt/ostream.h>
#include <fmt/printf.h>
#include <iostream>
#include <iomanip>
#include <chrono>
#include <sstream>
#include "core/sstring.hh"

#if 0
inline
std::ostream&
operator<<(std::ostream& os, const void* ptr) {
    auto flags = os.flags();
    os << "0x" << std::hex << reinterpret_cast<uintptr_t>(ptr);
    os.flags(flags);
    return os;
}
#endif

inline
std::ostream&
operator<<(std::ostream&& os, const void* ptr) {
    return os << ptr; // selects non-rvalue version
}

namespace seastar {

template <typename... A>
std::ostream&
fprint(std::ostream& os, const char* fmt, A&&... a) {
    ::fmt::fprintf(os, fmt, std::forward<A>(a)...);
    return os;
}

template <typename... A>
void
print(const char* fmt, A&&... a) {
    ::fmt::printf(fmt, std::forward<A>(a)...);
}

template <typename... A>
std::string
sprint(const char* fmt, A&&... a) {
    std::ostringstream os;
    ::fmt::fprintf(os, fmt, std::forward<A>(a)...);
    return os.str();
}

template <typename... A>
std::string
sprint(const sstring& fmt, A&&... a) {
    std::ostringstream os;
    ::fmt::fprintf(os, fmt.c_str(), std::forward<A>(a)...);
    return os.str();
}

template <typename Iterator>
std::string
format_separated(Iterator b, Iterator e, const char* sep = ", ") {
    std::string ret;
    if (b == e) {
        return ret;
    }
    ret += *b++;
    while (b != e) {
        ret += sep;
        ret += *b++;
    }
    return ret;
}

template <typename TimePoint>
struct usecfmt_wrapper {
    TimePoint val;
};

template <typename TimePoint>
inline
usecfmt_wrapper<TimePoint>
usecfmt(TimePoint tp) {
    return { tp };
};

template <typename Clock, typename Rep, typename Period>
std::ostream&
operator<<(std::ostream& os, usecfmt_wrapper<std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>> tp) {
    auto usec = std::chrono::duration_cast<std::chrono::microseconds>(tp.val.time_since_epoch()).count();
    std::ostream tmp(os.rdbuf());
    tmp << std::setw(12) << (usec / 1000000) << "." << std::setw(6) << std::setfill('0') << (usec % 1000000);
    return os;
}

template <typename... A>
void
log(A&&... a) {
    std::cout << usecfmt(std::chrono::high_resolution_clock::now()) << " ";
    print(std::forward<A>(a)...);
}

/**
 * Evaluate the formatted string in a native fmt library format
 *
 * @param fmt format string with the native fmt library syntax
 * @param a positional parameters
 *
 * @return sstring object with the result of applying the given positional
 *         parameters on a given format string.
 */
template <typename... A>
sstring
format(const char* fmt, A&&... a) {
    fmt::memory_buffer out;
    fmt::format_to(out, fmt, std::forward<A>(a)...);
    return sstring{out.data(), out.size()};
}
}
<commit_msg>print: add fmt_print()<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#pragma once

#include <fmt/ostream.h>
#include <fmt/printf.h>
#include <iostream>
#include <iomanip>
#include <chrono>
#include <sstream>
#include "core/sstring.hh"

#if 0
inline
std::ostream&
operator<<(std::ostream& os, const void* ptr) {
    auto flags = os.flags();
    os << "0x" << std::hex << reinterpret_cast<uintptr_t>(ptr);
    os.flags(flags);
    return os;
}
#endif

inline
std::ostream&
operator<<(std::ostream&& os, const void* ptr) {
    return os << ptr; // selects non-rvalue version
}

namespace seastar {

template <typename... A>
std::ostream&
fprint(std::ostream& os, const char* fmt, A&&... a) {
    ::fmt::fprintf(os, fmt, std::forward<A>(a)...);
    return os;
}

template <typename... A>
void
print(const char* fmt, A&&... a) {
    ::fmt::printf(fmt, std::forward<A>(a)...);
}

template <typename... A>
std::string
sprint(const char* fmt, A&&... a) {
    std::ostringstream os;
    ::fmt::fprintf(os, fmt, std::forward<A>(a)...);
    return os.str();
}

template <typename... A>
std::string
sprint(const sstring& fmt, A&&... a) {
    std::ostringstream os;
    ::fmt::fprintf(os, fmt.c_str(), std::forward<A>(a)...);
    return os.str();
}

template <typename Iterator>
std::string
format_separated(Iterator b, Iterator e, const char* sep = ", ") {
    std::string ret;
    if (b == e) {
        return ret;
    }
    ret += *b++;
    while (b != e) {
        ret += sep;
        ret += *b++;
    }
    return ret;
}

template <typename TimePoint>
struct usecfmt_wrapper {
    TimePoint val;
};

template <typename TimePoint>
inline
usecfmt_wrapper<TimePoint>
usecfmt(TimePoint tp) {
    return { tp };
};

template <typename Clock, typename Rep, typename Period>
std::ostream&
operator<<(std::ostream& os, usecfmt_wrapper<std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>> tp) {
    auto usec = std::chrono::duration_cast<std::chrono::microseconds>(tp.val.time_since_epoch()).count();
    std::ostream tmp(os.rdbuf());
    tmp << std::setw(12) << (usec / 1000000) << "." << std::setw(6) << std::setfill('0') << (usec % 1000000);
    return os;
}

template <typename... A>
void
log(A&&... a) {
    std::cout << usecfmt(std::chrono::high_resolution_clock::now()) << " ";
    print(std::forward<A>(a)...);
}

/**
 * Evaluate the formatted string in a native fmt library format
 *
 * @param fmt format string with the native fmt library syntax
 * @param a positional parameters
 *
 * @return sstring object with the result of applying the given positional
 *         parameters on a given format string.
 */
template <typename... A>
sstring
format(const char* fmt, A&&... a) {
    fmt::memory_buffer out;
    fmt::format_to(out, fmt, std::forward<A>(a)...);
    return sstring{out.data(), out.size()};
}

// temporary, use fmt::print() instead
template <typename... A>
std::ostream&
fmt_print(std::ostream& os, const char* format, A&&... a) {
    fmt::print(os, format, std::forward<A>(a)...);
    return os;
}

}
<|endoftext|>