<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2018, John Haddon. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "GafferScene/Wireframe.h"

#include "Gaffer/StringPlug.h"

#include "IECoreScene/MeshPrimitive.h"
#include "IECoreScene/CurvesPrimitive.h"

#include "IECore/DataAlgo.h"

#include "boost/functional/hash.hpp"

#include <unordered_set>

using namespace std;
using namespace Imath;
using namespace IECore;
using namespace IECoreScene;
using namespace Gaffer;
using namespace GafferScene;

//////////////////////////////////////////////////////////////////////////
// Internal utilities
//////////////////////////////////////////////////////////////////////////

namespace
{

struct MakeWireframe
{

	CurvesPrimitivePtr operator() ( const V2fVectorData *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
	{
		return makeWireframe<V2fVectorData>( data, mesh, name, primitiveVariable );
	}

	CurvesPrimitivePtr operator() ( const V3fVectorData *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
	{
		return makeWireframe<V3fVectorData>( data, mesh, name, primitiveVariable );
	}

	CurvesPrimitivePtr operator() ( const Data *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
	{
		throw IECore::Exception( boost::str(
			boost::format( "PrimitiveVariable \"%1%\" has unsupported type \"%2%\"" ) % name % data->typeName()
		) );
	}

	private :

		template<typename T>
		CurvesPrimitivePtr makeWireframe( const T *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
		{
			using Vec = typename T::ValueType::value_type;
			using DataView = PrimitiveVariable::IndexedView<Vec>;

			DataView dataView;
			const vector<int> *vertexIds = nullptr;
			switch( primitiveVariable.interpolation )
			{
				case PrimitiveVariable::Vertex :
				case PrimitiveVariable::Varying :
					vertexIds = &mesh->vertexIds()->readable();
					dataView = DataView( primitiveVariable );
					break;
				case PrimitiveVariable::FaceVarying :
					vertexIds = primitiveVariable.indices ? &primitiveVariable.indices->readable() : nullptr;
					dataView = DataView( data->readable(), nullptr );
					break;
				default :
					throw IECore::Exception( boost::str(
						boost::format( "Primitive variable \"%1%\" must have Vertex, Varying or FaceVarying interpolation" ) % name
					) );
			}

			IECore::V3fVectorDataPtr pData = new V3fVectorData;
			pData->setInterpretation( GeometricData::Point );
			vector<V3f> &p = pData->writable();

			using Edge = std::pair<int, int>;
			using EdgeSet = unordered_set<Edge, boost::hash<Edge>>;
			EdgeSet edgesVisited;

			int vertexIdsIndex = 0;
			for( int numVertices : mesh->verticesPerFace()->readable() )
			{
				for( int i = 0; i < numVertices; ++i )
				{
					int index0 = vertexIdsIndex + i;
					int index1 = vertexIdsIndex + (i + 1) % numVertices;
					if( vertexIds )
					{
						index0 = (*vertexIds)[index0];
						index1 = (*vertexIds)[index1];
					}

					Edge edge( min( index0, index1 ), max( index0, index1 ) );
					if( edgesVisited.insert( edge ).second )
					{
						p.push_back( v3f( dataView[index0] ) );
						p.push_back( v3f( dataView[index1] ) );
					}
				}
				vertexIdsIndex += numVertices;
			}

			IECore::IntVectorDataPtr vertsPerCurveData = new IntVectorData;
			vertsPerCurveData->writable().resize( p.size() / 2, 2 );

			CurvesPrimitivePtr result = new CurvesPrimitive( vertsPerCurveData );
			result->variables["P"] = PrimitiveVariable( PrimitiveVariable::Vertex, pData );
			return result;
		}

		V3f v3f( const Imath::V3f &v )
		{
			return v;
		}

		V3f v3f( const Imath::V2f &v )
		{
			return V3f( v.x, v.y, 0.0f );
		}

};

/// \todo Perhaps this could go in IECoreScene::MeshAlgo
CurvesPrimitivePtr wireframe( const MeshPrimitive *mesh, const std::string &position )
{
	auto it = mesh->variables.find( position );
	if( it == mesh->variables.end() )
	{
		throw IECore::Exception( boost::str(
			boost::format( "MeshPrimitive has no primitive variable named \"%1%\"" ) % position
		) );
	}

	CurvesPrimitivePtr result = dispatch( it->second.data.get(), MakeWireframe(), mesh, it->first, it->second );
	return result;
}

} // namespace

//////////////////////////////////////////////////////////////////////////
// Wireframe
//////////////////////////////////////////////////////////////////////////

IE_CORE_DEFINERUNTIMETYPED( Wireframe );

size_t Wireframe::g_firstPlugIndex = 0;

Wireframe::Wireframe( const std::string &name )
	:	SceneElementProcessor( name, PathMatcher::NoMatch )
{
	storeIndexOfNextChild( g_firstPlugIndex );
	addChild( new StringPlug( "position", Plug::In, "P" ) );
	addChild( new FloatPlug( "width", Plug::In, 1.0f, 0.0f ) );

	// Fast pass-throughs for things we don't modify
	outPlug()->attributesPlug()->setInput( inPlug()->attributesPlug() );
	outPlug()->transformPlug()->setInput( inPlug()->transformPlug() );
}

Wireframe::~Wireframe()
{
}

Gaffer::StringPlug *Wireframe::positionPlug()
{
	return getChild<StringPlug>( g_firstPlugIndex );
}

const Gaffer::StringPlug *Wireframe::positionPlug() const
{
	return getChild<StringPlug>( g_firstPlugIndex );
}

Gaffer::FloatPlug *Wireframe::widthPlug()
{
	return getChild<FloatPlug>( g_firstPlugIndex + 1 );
}

const Gaffer::FloatPlug *Wireframe::widthPlug() const
{
	return getChild<FloatPlug>( g_firstPlugIndex + 1 );
}

void Wireframe::affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const
{
	SceneElementProcessor::affects( input, outputs );

	if(
		input == positionPlug() ||
		input == widthPlug()
	)
	{
		outputs.push_back( outPlug()->objectPlug() );
	}
}

bool Wireframe::processesBound() const
{
	return true;
}

void Wireframe::hashProcessedBound( const ScenePath &path, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
	outPlug()->objectPlug()->hash( h );
}

Imath::Box3f Wireframe::computeProcessedBound( const ScenePath &path, const Gaffer::Context *context, const Imath::Box3f &inputBound ) const
{
	ConstObjectPtr object = outPlug()->objectPlug()->getValue();
	if( const CurvesPrimitive *wireframe = runTimeCast<const CurvesPrimitive>( object.get() ) )
	{
		return wireframe->bound();
	}
	return inputBound;
}

bool Wireframe::processesObject() const
{
	return true;
}

void Wireframe::hashProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
	positionPlug()->hash( h );
	widthPlug()->hash( h );
}

IECore::ConstObjectPtr Wireframe::computeProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::ConstObjectPtr inputObject ) const
{
	const MeshPrimitive *mesh = runTimeCast<const MeshPrimitive>( inputObject.get() );
	if( !mesh )
	{
		return inputObject;
	}

	CurvesPrimitivePtr result = wireframe( mesh, positionPlug()->getValue() );
	for( const auto &pv : mesh->variables )
	{
		if( pv.second.interpolation == PrimitiveVariable::Constant )
		{
			// OK to reference data directly, because result becomes const upon return.
			result->variables.insert( pv );
		}
	}
	result->variables["width"] = PrimitiveVariable( PrimitiveVariable::Constant, new FloatData( widthPlug()->getValue() ) );

	return result;
}
<commit_msg>Wireframe : Reserve space for `edgesVisited`<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2018, John Haddon. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "GafferScene/Wireframe.h"

#include "Gaffer/StringPlug.h"

#include "IECoreScene/MeshPrimitive.h"
#include "IECoreScene/CurvesPrimitive.h"

#include "IECore/DataAlgo.h"

#include "boost/functional/hash.hpp"

#include <unordered_set>

using namespace std;
using namespace Imath;
using namespace IECore;
using namespace IECoreScene;
using namespace Gaffer;
using namespace GafferScene;

//////////////////////////////////////////////////////////////////////////
// Internal utilities
//////////////////////////////////////////////////////////////////////////

namespace
{

struct MakeWireframe
{

	CurvesPrimitivePtr operator() ( const V2fVectorData *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
	{
		return makeWireframe<V2fVectorData>( data, mesh, name, primitiveVariable );
	}

	CurvesPrimitivePtr operator() ( const V3fVectorData *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
	{
		return makeWireframe<V3fVectorData>( data, mesh, name, primitiveVariable );
	}

	CurvesPrimitivePtr operator() ( const Data *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
	{
		throw IECore::Exception( boost::str(
			boost::format( "PrimitiveVariable \"%1%\" has unsupported type \"%2%\"" ) % name % data->typeName()
		) );
	}

	private :

		template<typename T>
		CurvesPrimitivePtr makeWireframe( const T *data, const MeshPrimitive *mesh, const string &name, const PrimitiveVariable &primitiveVariable )
		{
			using Vec = typename T::ValueType::value_type;
			using DataView = PrimitiveVariable::IndexedView<Vec>;

			DataView dataView;
			const vector<int> *vertexIds = nullptr;
			switch( primitiveVariable.interpolation )
			{
				case PrimitiveVariable::Vertex :
				case PrimitiveVariable::Varying :
					vertexIds = &mesh->vertexIds()->readable();
					dataView = DataView( primitiveVariable );
					break;
				case PrimitiveVariable::FaceVarying :
					vertexIds = primitiveVariable.indices ? &primitiveVariable.indices->readable() : nullptr;
					dataView = DataView( data->readable(), nullptr );
					break;
				default :
					throw IECore::Exception( boost::str(
						boost::format( "Primitive variable \"%1%\" must have Vertex, Varying or FaceVarying interpolation" ) % name
					) );
			}

			IECore::V3fVectorDataPtr pData = new V3fVectorData;
			pData->setInterpretation( GeometricData::Point );
			vector<V3f> &p = pData->writable();

			using Edge = std::pair<int, int>;
			using EdgeSet = unordered_set<Edge, boost::hash<Edge>>;
			EdgeSet edgesVisited;
			edgesVisited.reserve( mesh->variableSize( PrimitiveVariable::FaceVarying ) );

			int vertexIdsIndex = 0;
			for( int numVertices : mesh->verticesPerFace()->readable() )
			{
				for( int i = 0; i < numVertices; ++i )
				{
					int index0 = vertexIdsIndex + i;
					int index1 = vertexIdsIndex + (i + 1) % numVertices;
					if( vertexIds )
					{
						index0 = (*vertexIds)[index0];
						index1 = (*vertexIds)[index1];
					}

					Edge edge( min( index0, index1 ), max( index0, index1 ) );
					if( edgesVisited.insert( edge ).second )
					{
						p.push_back( v3f( dataView[index0] ) );
						p.push_back( v3f( dataView[index1] ) );
					}
				}
				vertexIdsIndex += numVertices;
			}

			IECore::IntVectorDataPtr vertsPerCurveData = new IntVectorData;
			vertsPerCurveData->writable().resize( p.size() / 2, 2 );

			CurvesPrimitivePtr result = new CurvesPrimitive( vertsPerCurveData );
			result->variables["P"] = PrimitiveVariable( PrimitiveVariable::Vertex, pData );
			return result;
		}

		V3f v3f( const Imath::V3f &v )
		{
			return v;
		}

		V3f v3f( const Imath::V2f &v )
		{
			return V3f( v.x, v.y, 0.0f );
		}

};

/// \todo Perhaps this could go in IECoreScene::MeshAlgo
CurvesPrimitivePtr wireframe( const MeshPrimitive *mesh, const std::string &position )
{
	auto it = mesh->variables.find( position );
	if( it == mesh->variables.end() )
	{
		throw IECore::Exception( boost::str(
			boost::format( "MeshPrimitive has no primitive variable named \"%1%\"" ) % position
		) );
	}

	CurvesPrimitivePtr result = dispatch( it->second.data.get(), MakeWireframe(), mesh, it->first, it->second );
	return result;
}

} // namespace

//////////////////////////////////////////////////////////////////////////
// Wireframe
//////////////////////////////////////////////////////////////////////////

IE_CORE_DEFINERUNTIMETYPED( Wireframe );

size_t Wireframe::g_firstPlugIndex = 0;

Wireframe::Wireframe( const std::string &name )
	:	SceneElementProcessor( name, PathMatcher::NoMatch )
{
	storeIndexOfNextChild( g_firstPlugIndex );
	addChild( new StringPlug( "position", Plug::In, "P" ) );
	addChild( new FloatPlug( "width", Plug::In, 1.0f, 0.0f ) );

	// Fast pass-throughs for things we don't modify
	outPlug()->attributesPlug()->setInput( inPlug()->attributesPlug() );
	outPlug()->transformPlug()->setInput( inPlug()->transformPlug() );
}

Wireframe::~Wireframe()
{
}

Gaffer::StringPlug *Wireframe::positionPlug()
{
	return getChild<StringPlug>( g_firstPlugIndex );
}

const Gaffer::StringPlug *Wireframe::positionPlug() const
{
	return getChild<StringPlug>( g_firstPlugIndex );
}

Gaffer::FloatPlug *Wireframe::widthPlug()
{
	return getChild<FloatPlug>( g_firstPlugIndex + 1 );
}

const Gaffer::FloatPlug *Wireframe::widthPlug() const
{
	return getChild<FloatPlug>( g_firstPlugIndex + 1 );
}

void Wireframe::affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const
{
	SceneElementProcessor::affects( input, outputs );

	if(
		input == positionPlug() ||
		input == widthPlug()
	)
	{
		outputs.push_back( outPlug()->objectPlug() );
	}
}

bool Wireframe::processesBound() const
{
	return true;
}

void Wireframe::hashProcessedBound( const ScenePath &path, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
	outPlug()->objectPlug()->hash( h );
}

Imath::Box3f Wireframe::computeProcessedBound( const ScenePath &path, const Gaffer::Context *context, const Imath::Box3f &inputBound ) const
{
	ConstObjectPtr object = outPlug()->objectPlug()->getValue();
	if( const CurvesPrimitive *wireframe = runTimeCast<const CurvesPrimitive>( object.get() ) )
	{
		return wireframe->bound();
	}
	return inputBound;
}

bool Wireframe::processesObject() const
{
	return true;
}

void Wireframe::hashProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
	positionPlug()->hash( h );
	widthPlug()->hash( h );
}

IECore::ConstObjectPtr Wireframe::computeProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::ConstObjectPtr inputObject ) const
{
	const MeshPrimitive *mesh = runTimeCast<const MeshPrimitive>( inputObject.get() );
	if( !mesh )
	{
		return inputObject;
	}

	CurvesPrimitivePtr result = wireframe( mesh, positionPlug()->getValue() );
	for( const auto &pv : mesh->variables )
	{
		if( pv.second.interpolation == PrimitiveVariable::Constant )
		{
			// OK to reference data directly, because result becomes const upon return.
			result->variables.insert( pv );
		}
	}
	result->variables["width"] = PrimitiveVariable( PrimitiveVariable::Constant, new FloatData( widthPlug()->getValue() ) );

	return result;
}
<|endoftext|>


<commit_before>#include "Genes/Look_Ahead_Gene.h"

#include <cmath>
#include <cassert>

#include "Genes/Gene.h"
#include "Utility.h"
#include "Game/Board.h"
#include "Game/Clock.h"
#include "Moves/Complete_Move.h"

Look_Ahead_Gene::Look_Ahead_Gene() :
    mean_game_length(50),
    game_length_uncertainty(0.5),
    speculation_constant(0.0)
{
    recalculate_exponent();
}

void Look_Ahead_Gene::reset_properties() const
{
    properties["Mean Game Length"] = mean_game_length;
    properties["Game Length Uncertainty"] = game_length_uncertainty;
    properties["Speculation Constant"] = speculation_constant;
}

void Look_Ahead_Gene::load_properties()
{
    mean_game_length = properties["Mean Game Length"];
    game_length_uncertainty = properties["Game Length Uncertainty"];
    speculation_constant = properties["Speculation Constant"];
    recalculate_exponent();
}

double Look_Ahead_Gene::time_to_examine(const Board& board, const Clock& clock) const
{
    if( ! is_active())
    {
        return 0.0;
    }

    auto time_left = clock.time_left(board.whose_turn());
    auto moves_to_reset = clock.moves_to_reset(board.whose_turn());

    auto moves_so_far = board.get_game_record().size()/2; // only count moves by this player
    auto moves_left = Math::average_moves_left(mean_game_length, game_length_uncertainty, moves_so_far);

    return time_left/std::min(moves_left, double(moves_to_reset));
}

void Look_Ahead_Gene::gene_specific_mutation()
{
    switch(Random::random_integer(1, 3))
    {
        case 1:
            mean_game_length = std::max(1.0, mean_game_length + Random::random_normal(1.0));
            break;
        case 2:
            game_length_uncertainty = std::abs(game_length_uncertainty + Random::random_normal(0.01));
            break;
        case 3:
            speculation_constant += Random::random_normal(0.01);
            speculation_constant = std::max(speculation_constant, 0.0);
            speculation_constant = std::min(speculation_constant, 1.0);
            recalculate_exponent();
            break;
        default:
            assert(false); // If here, random_integer() called with wrong parameters
            break;
    }
}

Look_Ahead_Gene* Look_Ahead_Gene::duplicate() const
{
    return new Look_Ahead_Gene(*this);
}

std::string Look_Ahead_Gene::name() const
{
    return "Look Ahead Gene";
}

double Look_Ahead_Gene::score_board(const Board&, Color) const
{
    return 0.0;
}

bool Look_Ahead_Gene::enough_time_to_recurse(double time_allotted, const Board& board, double positions_per_second) const
{
    // The idea is that, if the time allotted to a move is less than the time
    // this gene thinks it takes to examine every move of the resulting board state
    // without recursion, then it should still recurse with a probability that is a
    // function of the ratio of the time allotted to time needed. The speculation_constant
    // specifies how often this should happen, with 0 being never and 1 being always
    // (see the recalculate_exponent() function for the math).

    auto minimum_time_to_recurse = board.legal_moves().size()/positions_per_second;
    auto base = time_allotted/minimum_time_to_recurse;

    if(base <= 0.0)
    {
        return false;
    }

    if(base >= 1.0)
    {
        return true;
    }

    return Random::success_probability(std::pow(base, speculation_exponent));
}

void Look_Ahead_Gene::recalculate_exponent()
{
    if(speculation_constant > 0.0)
    {
        speculation_exponent = (1.0 - speculation_constant)/speculation_constant;
    }
    else
    {
        speculation_exponent = Math::infinity;
    }

    // constant = 0.0 ==> exponent = infinity
    // constant = 0.5 ==> exponent = 1
    // constant = 1.0 ==> exponent = 0
    //
    // Additionally, the function is symmetric about constant = 0.5:
    //    constant --> 1 - constant ==> exponent --> 1/exponent
    //
    // This results in a value of the std::pow() expression in enough_time_to_recurse()
    //
    //    value = (0 < base < 1)^exponent
    //
    // Large exponents result in values near zero, which means recursion with little time
    // has little probability. Small exponents result in values near 1, so recursion with
    // little time is more likely.
}
<commit_msg>Start with more aggressive Look Ahead speculation<commit_after>#include "Genes/Look_Ahead_Gene.h"

#include <cmath>
#include <cassert>

#include "Genes/Gene.h"
#include "Utility.h"
#include "Game/Board.h"
#include "Game/Clock.h"
#include "Moves/Complete_Move.h"

Look_Ahead_Gene::Look_Ahead_Gene() :
    mean_game_length(50),
    game_length_uncertainty(0.5),
    speculation_constant(0.5)
{
    recalculate_exponent();
}

void Look_Ahead_Gene::reset_properties() const
{
    properties["Mean Game Length"] = mean_game_length;
    properties["Game Length Uncertainty"] = game_length_uncertainty;
    properties["Speculation Constant"] = speculation_constant;
}

void Look_Ahead_Gene::load_properties()
{
    mean_game_length = properties["Mean Game Length"];
    game_length_uncertainty = properties["Game Length Uncertainty"];
    speculation_constant = properties["Speculation Constant"];
    recalculate_exponent();
}

double Look_Ahead_Gene::time_to_examine(const Board& board, const Clock& clock) const
{
    if( ! is_active())
    {
        return 0.0;
    }

    auto time_left = clock.time_left(board.whose_turn());
    auto moves_to_reset = clock.moves_to_reset(board.whose_turn());

    auto moves_so_far = board.get_game_record().size()/2; // only count moves by this player
    auto moves_left = Math::average_moves_left(mean_game_length, game_length_uncertainty, moves_so_far);

    return time_left/std::min(moves_left, double(moves_to_reset));
}

void Look_Ahead_Gene::gene_specific_mutation()
{
    switch(Random::random_integer(1, 3))
    {
        case 1:
            mean_game_length = std::max(1.0, mean_game_length + Random::random_normal(1.0));
            break;
        case 2:
            game_length_uncertainty = std::abs(game_length_uncertainty + Random::random_normal(0.01));
            break;
        case 3:
            speculation_constant += Random::random_normal(0.01);
            speculation_constant = std::max(speculation_constant, 0.0);
            speculation_constant = std::min(speculation_constant, 1.0);
            recalculate_exponent();
            break;
        default:
            assert(false); // If here, random_integer() called with wrong parameters
            break;
    }
}

Look_Ahead_Gene* Look_Ahead_Gene::duplicate() const
{
    return new Look_Ahead_Gene(*this);
}

std::string Look_Ahead_Gene::name() const
{
    return "Look Ahead Gene";
}

double Look_Ahead_Gene::score_board(const Board&, Color) const
{
    return 0.0;
}

bool Look_Ahead_Gene::enough_time_to_recurse(double time_allotted, const Board& board, double positions_per_second) const
{
    // The idea is that, if the time allotted to a move is less than the time
    // this gene thinks it takes to examine every move of the resulting board state
    // without recursion, then it should still recurse with a probability that is a
    // function of the ratio of the time allotted to time needed. The speculation_constant
    // specifies how often this should happen, with 0 being never and 1 being always
    // (see the recalculate_exponent() function for the math).

    auto minimum_time_to_recurse = board.legal_moves().size()/positions_per_second;
    auto base = time_allotted/minimum_time_to_recurse;

    if(base <= 0.0)
    {
        return false;
    }

    if(base >= 1.0)
    {
        return true;
    }

    return Random::success_probability(std::pow(base, speculation_exponent));
}

void Look_Ahead_Gene::recalculate_exponent()
{
    if(speculation_constant > 0.0)
    {
        speculation_exponent = (1.0 - speculation_constant)/speculation_constant;
    }
    else
    {
        speculation_exponent = Math::infinity;
    }

    // constant = 0.0 ==> exponent = infinity
    // constant = 0.5 ==> exponent = 1
    // constant = 1.0 ==> exponent = 0
    //
    // Additionally, the function is symmetric about constant = 0.5:
    //    constant --> 1 - constant ==> exponent --> 1/exponent
    //
    // This results in a value of the std::pow() expression in enough_time_to_recurse()
    //
    //    value = (0 < base < 1)^exponent
    //
    // Large exponents result in values near zero, which means recursion with little time
    // has little probability. Small exponents result in values near 1, so recursion with
    // little time is more likely.
}
<|endoftext|>


<commit_before>/*
* this file is part of the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
*
* based on the Null Theme Engine for Gtk+.
* Copyright (c) 2008 Robert Staudinger <robert.staudinger@gmail.com>
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or( at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygendemodialog.h"
#include "oxygeninputdemowidget.h"
#include "oxygenbuttondemowidget.h"
#include "oxygenframedemowidget.h"
#include "oxygentabdemowidget.h"

#include <iostream>

namespace Oxygen
{

    //_____________________________________________
    DemoDialog::DemoDialog( void )
    {

        // create main widget
        _mainWidget = gtk_window_new( GTK_WINDOW_TOPLEVEL );
        gtk_window_set_default_size( GTK_WINDOW( _mainWidget ), 630, 500 );
        gtk_window_set_title( GTK_WINDOW( _mainWidget ), "Oxygen-gtk Demo" );
        gtk_container_set_border_width( GTK_CONTAINER( _mainWidget ), 10 );

        // vertical container
        GtkWidget* vbox( gtk_vbox_new( false, 5 ) );
        gtk_container_add( GTK_CONTAINER( _mainWidget ), vbox );
        gtk_widget_show( vbox );

        GtkWidget* iconView(0L);
        {
            // first horizontal container
            GtkWidget* hbox( gtk_hbox_new( false, 8 ) );
            gtk_box_pack_start( GTK_BOX( vbox ), hbox, true, true, 0 );
            gtk_widget_show( hbox );

            // iconview model
            _model = gtk_list_store_new( 2, GDK_TYPE_PIXBUF, G_TYPE_STRING );

            // inconview
            GtkWidget* scrolledWindow( gtk_scrolled_window_new( 0L, 0L ) );
            gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scrolledWindow ), GTK_SHADOW_IN );
            gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolledWindow ), GTK_POLICY_NEVER, GTK_POLICY_NEVER );
            gtk_box_pack_start( GTK_BOX( hbox ), scrolledWindow, false, true, 0 );
            gtk_widget_show( scrolledWindow );

            iconView = gtk_icon_view_new_with_model( GTK_TREE_MODEL( _model ) );
            gtk_icon_view_set_pixbuf_column( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_text_column( GTK_ICON_VIEW( iconView ), 1 );
            gtk_icon_view_set_columns( GTK_ICON_VIEW( iconView ), 1 );

            gtk_icon_view_set_item_width( GTK_ICON_VIEW( iconView ), 108 );
            gtk_icon_view_set_spacing( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_margin( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_column_spacing( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_row_spacing( GTK_ICON_VIEW( iconView ), 0 );

            // get list of renderers, find text renderer and make font format bold
            GList* cells( gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( iconView ) ) );
            for( GList *cell = g_list_first( cells ); cell; cell = g_list_next( cell ) )
            {
                if( !GTK_IS_CELL_RENDERER_TEXT( cell->data ) ) continue;

                // create pango attributes list
                PangoAttrList* attributes( pango_attr_list_new() );
                pango_attr_list_insert( attributes, pango_attr_weight_new( PANGO_WEIGHT_BOLD ) );

                GValue val = { 0, };
                g_value_init(&val, PANGO_TYPE_ATTR_LIST );
                g_value_set_boxed( &val, attributes );
                g_object_set_property( G_OBJECT( cell->data ), "attributes", &val );

                pango_attr_list_unref( attributes );

            }

            if( cells ) g_list_free( cells );

            // connect signals
            _selectionChangedId.connect( G_OBJECT(iconView), "selection-changed", G_CALLBACK( selectionChanged ), this );

            gtk_container_add( GTK_CONTAINER( scrolledWindow ), iconView );
            gtk_widget_show( iconView );

            // notebook
            _notebook = gtk_notebook_new();
            gtk_notebook_set_show_tabs( GTK_NOTEBOOK( _notebook ), false );
            gtk_box_pack_start( GTK_BOX( hbox ), _notebook, true, true, 0 );
            gtk_widget_show( _notebook );

        }

        {
            // statusbar
            GtkWidget* statusBar( gtk_hbox_new( false, 2 ) );
            gtk_box_pack_start( GTK_BOX( vbox ), statusBar, false, true, 0 );
            gtk_widget_show( statusBar );

            // enable checkbox
            _stateButton = gtk_check_button_new_with_label( "Enabled" );
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( _stateButton ), true );
            gtk_box_pack_start( GTK_BOX( statusBar ), _stateButton, false, false, 0 );
            gtk_widget_show( _stateButton );

            _toggleEnableStateId.connect( G_OBJECT(_stateButton), "toggled", G_CALLBACK( toggleEnableState ), this );

            // button box
            #if GTK_CHECK_VERSION( 3, 0, 0 )
            GtkWidget* buttonBox( gtk_button_box_new( GTK_ORIENTATION_HORIZONTAL) );
            #else
            GtkWidget* buttonBox( gtk_hbutton_box_new() );
            #endif

            gtk_button_box_set_layout( GTK_BUTTON_BOX( buttonBox ), GTK_BUTTONBOX_END );
            gtk_box_pack_end( GTK_BOX( statusBar ), buttonBox, true, true, 0 );
            gtk_widget_show( buttonBox );

            // close button
            GtkWidget* button = gtk_button_new_from_stock( GTK_STOCK_OK );
            gtk_box_pack_end( GTK_BOX( buttonBox ), button, false, true, 0 );
            gtk_widget_show( button );

            g_signal_connect( G_OBJECT(button), "clicked", G_CALLBACK( gtk_main_quit ), 0L );

        }

        addPage( new InputDemoWidget() );
        addPage( new TabDemoWidget() );
        addPage( new ButtonDemoWidget() );
        addPage( new FrameDemoWidget() );

        // select first raw
        GtkTreePath *path( gtk_tree_path_new_from_indices(0, -1 ) );
        gtk_icon_view_select_path( GTK_ICON_VIEW( iconView ), path );

    }

    //_____________________________________________
    DemoDialog::~DemoDialog( void )
    {}

    //_____________________________________________
    void DemoDialog::addPage( DemoWidget* page )
    {
        // get icon
        GdkPixbuf* icon( 0L );
        if( !page->iconName().empty() )
        {

            // TODO: should get this icon size from options
            GtkIconTheme* theme( gtk_icon_theme_get_default() );
            icon = gtk_icon_theme_load_icon( theme, page->iconName().c_str(), 32, (GtkIconLookupFlags) 0, 0L );

        }

        // insert in list
        GtkTreeIter iter;
        gtk_list_store_append( _model, &iter );
        gtk_list_store_set( _model, &iter, 0, icon, 1, page->name().c_str(), -1 );

        // add to notebook
        int index( gtk_notebook_append_page( GTK_NOTEBOOK( _notebook ), page->mainWidget(), 0L ) );
        gtk_widget_show( page->mainWidget() );

        _pages.insert( std::make_pair( index, page ) );
    }

    //_____________________________________________
    void DemoDialog::selectionChanged( GtkIconView* view, gpointer data )
    {
        // get pointer to dialog
        DemoDialog& dialog( *static_cast<DemoDialog*>( data ) );

        // get selection
        GList* selection = gtk_icon_view_get_selected_items( view );
        if( !selection ) return;

        // get first child
        GtkTreePath* path( static_cast<GtkTreePath*>( g_list_first( selection )->data ) );
        const int page( gtk_tree_path_get_indices( path )[0] );
        gtk_notebook_set_current_page( GTK_NOTEBOOK( dialog._notebook ), page );
        g_list_free( selection );

        // store enable state
        const bool enabled( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dialog._stateButton ) ) );

        // get matching page
        DemoWidget* widget( dialog._pages[page] );
        widget->setEnabled( enabled );

    }

    //_____________________________________________
    void DemoDialog::toggleEnableState( GtkToggleButton* button, gpointer data )
    {

        // get pointer to dialog
        DemoDialog& dialog( *static_cast<DemoDialog*>( data ) );

        // store enable state
        const bool enabled( gtk_toggle_button_get_active( button ) );

        // get current page
        const int page( gtk_notebook_get_current_page( GTK_NOTEBOOK( dialog._notebook ) ) );

        // get matching page
        DemoWidget* widget( dialog._pages[page] );
        widget->setEnabled( enabled );

    }
}
<commit_msg>Make it impossible to deselect an item in oxygen-gtk-demo iconview<commit_after>/*
* this file is part of the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
*
* based on the Null Theme Engine for Gtk+.
* Copyright (c) 2008 Robert Staudinger <robert.staudinger@gmail.com>
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or( at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygendemodialog.h"
#include "oxygeninputdemowidget.h"
#include "oxygenbuttondemowidget.h"
#include "oxygenframedemowidget.h"
#include "oxygentabdemowidget.h"

#include <iostream>

namespace Oxygen
{

    //_____________________________________________
    DemoDialog::DemoDialog( void )
    {

        // create main widget
        _mainWidget = gtk_window_new( GTK_WINDOW_TOPLEVEL );
        gtk_window_set_default_size( GTK_WINDOW( _mainWidget ), 630, 500 );
        gtk_window_set_title( GTK_WINDOW( _mainWidget ), "Oxygen-gtk Demo" );
        gtk_container_set_border_width( GTK_CONTAINER( _mainWidget ), 10 );

        // vertical container
        GtkWidget* vbox( gtk_vbox_new( false, 5 ) );
        gtk_container_add( GTK_CONTAINER( _mainWidget ), vbox );
        gtk_widget_show( vbox );

        GtkWidget* iconView(0L);
        {
            // first horizontal container
            GtkWidget* hbox( gtk_hbox_new( false, 8 ) );
            gtk_box_pack_start( GTK_BOX( vbox ), hbox, true, true, 0 );
            gtk_widget_show( hbox );

            // iconview model
            _model = gtk_list_store_new( 2, GDK_TYPE_PIXBUF, G_TYPE_STRING );

            // inconview
            GtkWidget* scrolledWindow( gtk_scrolled_window_new( 0L, 0L ) );
            gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scrolledWindow ), GTK_SHADOW_IN );
            gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolledWindow ), GTK_POLICY_NEVER, GTK_POLICY_NEVER );
            gtk_box_pack_start( GTK_BOX( hbox ), scrolledWindow, false, true, 0 );
            gtk_widget_show( scrolledWindow );

            iconView = gtk_icon_view_new_with_model( GTK_TREE_MODEL( _model ) );
            gtk_icon_view_set_pixbuf_column( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_text_column( GTK_ICON_VIEW( iconView ), 1 );
            gtk_icon_view_set_columns( GTK_ICON_VIEW( iconView ), 1 );

            gtk_icon_view_set_item_width( GTK_ICON_VIEW( iconView ), 108 );
            gtk_icon_view_set_spacing( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_margin( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_column_spacing( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_row_spacing( GTK_ICON_VIEW( iconView ), 0 );
            gtk_icon_view_set_selection_mode( GTK_ICON_VIEW( iconView ), GTK_SELECTION_BROWSE );

            // get list of renderers, find text renderer and make font format bold
            GList* cells( gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( iconView ) ) );
            for( GList *cell = g_list_first( cells ); cell; cell = g_list_next( cell ) )
            {
                if( !GTK_IS_CELL_RENDERER_TEXT( cell->data ) ) continue;

                // create pango attributes list
                PangoAttrList* attributes( pango_attr_list_new() );
                pango_attr_list_insert( attributes, pango_attr_weight_new( PANGO_WEIGHT_BOLD ) );

                GValue val = { 0, };
                g_value_init(&val, PANGO_TYPE_ATTR_LIST );
                g_value_set_boxed( &val, attributes );
                g_object_set_property( G_OBJECT( cell->data ), "attributes", &val );

                pango_attr_list_unref( attributes );

            }

            if( cells ) g_list_free( cells );

            // connect signals
            _selectionChangedId.connect( G_OBJECT(iconView), "selection-changed", G_CALLBACK( selectionChanged ), this );

            gtk_container_add( GTK_CONTAINER( scrolledWindow ), iconView );
            gtk_widget_show( iconView );

            // notebook
            _notebook = gtk_notebook_new();
            gtk_notebook_set_show_tabs( GTK_NOTEBOOK( _notebook ), false );
            gtk_box_pack_start( GTK_BOX( hbox ), _notebook, true, true, 0 );
            gtk_widget_show( _notebook );

        }

        {
            // statusbar
            GtkWidget* statusBar( gtk_hbox_new( false, 2 ) );
            gtk_box_pack_start( GTK_BOX( vbox ), statusBar, false, true, 0 );
            gtk_widget_show( statusBar );

            // enable checkbox
            _stateButton = gtk_check_button_new_with_label( "Enabled" );
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( _stateButton ), true );
            gtk_box_pack_start( GTK_BOX( statusBar ), _stateButton, false, false, 0 );
            gtk_widget_show( _stateButton );

            _toggleEnableStateId.connect( G_OBJECT(_stateButton), "toggled", G_CALLBACK( toggleEnableState ), this );

            // button box
            #if GTK_CHECK_VERSION( 3, 0, 0 )
            GtkWidget* buttonBox( gtk_button_box_new( GTK_ORIENTATION_HORIZONTAL) );
            #else
            GtkWidget* buttonBox( gtk_hbutton_box_new() );
            #endif

            gtk_button_box_set_layout( GTK_BUTTON_BOX( buttonBox ), GTK_BUTTONBOX_END );
            gtk_box_pack_end( GTK_BOX( statusBar ), buttonBox, true, true, 0 );
            gtk_widget_show( buttonBox );

            // close button
            GtkWidget* button = gtk_button_new_from_stock( GTK_STOCK_OK );
            gtk_box_pack_end( GTK_BOX( buttonBox ), button, false, true, 0 );
            gtk_widget_show( button );

            g_signal_connect( G_OBJECT(button), "clicked", G_CALLBACK( gtk_main_quit ), 0L );

        }

        addPage( new InputDemoWidget() );
        addPage( new TabDemoWidget() );
        addPage( new ButtonDemoWidget() );
        addPage( new FrameDemoWidget() );

        // select first raw
        GtkTreePath *path( gtk_tree_path_new_from_indices(0, -1 ) );
        gtk_icon_view_select_path( GTK_ICON_VIEW( iconView ), path );

    }

    //_____________________________________________
    DemoDialog::~DemoDialog( void )
    {}

    //_____________________________________________
    void DemoDialog::addPage( DemoWidget* page )
    {
        // get icon
        GdkPixbuf* icon( 0L );
        if( !page->iconName().empty() )
        {

            // TODO: should get this icon size from options
            GtkIconTheme* theme( gtk_icon_theme_get_default() );
            icon = gtk_icon_theme_load_icon( theme, page->iconName().c_str(), 32, (GtkIconLookupFlags) 0, 0L );

        }

        // insert in list
        GtkTreeIter iter;
        gtk_list_store_append( _model, &iter );
        gtk_list_store_set( _model, &iter, 0, icon, 1, page->name().c_str(), -1 );

        // add to notebook
        int index( gtk_notebook_append_page( GTK_NOTEBOOK( _notebook ), page->mainWidget(), 0L ) );
        gtk_widget_show( page->mainWidget() );

        _pages.insert( std::make_pair( index, page ) );
    }

    //_____________________________________________
    void DemoDialog::selectionChanged( GtkIconView* view, gpointer data )
    {
        // get pointer to dialog
        DemoDialog& dialog( *static_cast<DemoDialog*>( data ) );

        // get selection
        GList* selection = gtk_icon_view_get_selected_items( view );
        if( !selection ) return;

        // get first child
        GtkTreePath* path( static_cast<GtkTreePath*>( g_list_first( selection )->data ) );
        const int page( gtk_tree_path_get_indices( path )[0] );
        gtk_notebook_set_current_page( GTK_NOTEBOOK( dialog._notebook ), page );
        g_list_free( selection );

        // store enable state
        const bool enabled( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dialog._stateButton ) ) );

        // get matching page
        DemoWidget* widget( dialog._pages[page] );
        widget->setEnabled( enabled );

    }

    //_____________________________________________
    void DemoDialog::toggleEnableState( GtkToggleButton* button, gpointer data )
    {

        // get pointer to dialog
        DemoDialog& dialog( *static_cast<DemoDialog*>( data ) );

        // store enable state
        const bool enabled( gtk_toggle_button_get_active( button ) );

        // get current page
        const int page( gtk_notebook_get_current_page( GTK_NOTEBOOK( dialog._notebook ) ) );

        // get matching page
        DemoWidget* widget( dialog._pages[page] );
        widget->setEnabled( enabled );

    }
}
<|endoftext|>


<commit_before>#include "lexicalAnalyzer.h"
#include <iostream>
#include <string>

using namespace std;

bool isDigit(const char &symbol)
{
	return (symbol >= '0' && symbol <= '9');
}

bool isDot(const char &symbol)
{
	return (symbol == '.');
}

bool isSign(const char &symbol)
{
	return (symbol == '+' || symbol == '-');
}

bool isExponent(const char &symbol)
{
	return (symbol == 'E');
}

bool isLastSymbol(int index, int sizeOfStr)
{
	return (index == sizeOfStr - 1);
}

bool isRealNumber(const string &str)
{
	const int sizeOfStr = str.length();
	int state = 0;
	char symbol = '0';

	for (int i = 0; i < sizeOfStr; ++i)
	{
		symbol = str[i];
		switch (state)
		{
		case 0:
		{
			if (isDigit(symbol))
			{
				state = 1;
			}
			else
			{
				return false;
			}
			break;
		}
		case 1:
		{
			if (isDigit(symbol))
			{
				state = 1;
			}
			else if (isDot(symbol) && !isLastSymbol(i, sizeOfStr))
			{
				state = 2;
			}
			else if (isExponent(symbol) && !isLastSymbol(i, sizeOfStr))
			{
				state = 4;
			}
			else
			{
				return false;
			}
			break;
		}
		case 2:
		{
			if (isDigit(symbol))
			{
				state = 3;
			}
			else
			{
				return false;
			}
			break;
		}
		case 3:
		{
			if (isDigit(symbol))
			{
				state = 3;
			}
			else if (isExponent(symbol) && !isLastSymbol(i, sizeOfStr))
			{
				state = 4;
			}
			else
			{
				return false;
			}
			break;
		}
		case 4:
		{
			if (isSign(symbol) && !isLastSymbol(i, sizeOfStr))
			{
				state = 5;
			}
			else if (isDigit(symbol))
			{
				state = 5;
			}
			else
			{
				return false;
			}
			break;
		}
		case 5:
		{
			if (isDigit(symbol))
			{
				state = 5;
			}
			else
			{
				return false;
			}
			break;
		}
		}
	}
	return true;
}<commit_msg>Removed isLastSymbol<commit_after>#include "lexicalAnalyzer.h"
#include <iostream>
#include <string>

using namespace std;

bool isDigit(const char &symbol)
{
	return (symbol >= '0' && symbol <= '9');
}

bool isDot(const char &symbol)
{
	return (symbol == '.');
}

bool isSign(const char &symbol)
{
	return (symbol == '+' || symbol == '-');
}

bool isExponent(const char &symbol)
{
	return (symbol == 'E');
}

bool isRealNumber(const string &str)
{
	const int sizeOfStr = str.length();
	int state = 0;
	char symbol = '0';

	for (int i = 0; i < sizeOfStr; ++i)
	{
		symbol = str[i];
		switch (state)
		{
		case 0:
		{
			if (isDigit(symbol))
			{
				state = 1;
			}
			else
			{
				return false;
			}
			break;
		}
		case 1:
		{
			if (isDigit(symbol))
			{
				state = 1;
			}
			else if (isDot(symbol))
			{
				state = 2;
			}
			else if (isExponent(symbol))
			{
				state = 4;
			}
			else
			{
				return false;
			}
			break;
		}
		case 2:
		{
			if (isDigit(symbol))
			{
				state = 3;
			}
			else
			{
				return false;
			}
			break;
		}
		case 3:
		{
			if (isDigit(symbol))
			{
				state = 3;
			}
			else if (isExponent(symbol))
			{
				state = 4;
			}
			else
			{
				return false;
			}
			break;
		}
		case 4:
		{
			if (isSign(symbol))
			{
				state = 5;
			}
			else if (isDigit(symbol))
			{
				state = 6;
			}
			else
			{
				return false;
			}
			break;
		}
		case 5:
		{
			if (isDigit(symbol))
			{
				state = 6;
			}
			else
			{
				return false;
			}
			break;
		}
		case 6:
		{
			if (isDigit(symbol))
			{
				state = 6;
			}
			else
			{
				return false;
			}
			break;
		}
		}
	}
	return (state == 1 || state == 3 || state == 6);
}<|endoftext|>


<commit_before>#include "test_slitherlink_field.h"
#include "test.h"

#include <cassert>
#include <vector>

#include "../slitherlink/sl_field.h"
#include "../slitherlink/sl_database.h"

namespace
{
// Place clues and check edges
void DoAddClueTest(penciloid::Y height, penciloid::X width, std::vector<const char*> test_target, penciloid::slitherlink::Database *db)
{
	using namespace penciloid;
	using namespace penciloid::slitherlink;

	Field field(height, width);
	field.SetDatabase(db);

	for (Y y = 0; y < height; ++y) {
		for (X x = 0; x < width; ++x) {
			if ('0' <= test_target[y * 2 + 1][x * 2 + 1] && test_target[y * 2 + 1][x * 2 + 1] <= '3') {
				field.AddClue(Position(y, x), test_target[y * 2 + 1][x * 2 + 1] - '0');
			}
		}
	}

	for (Y y = 0; y <= 2 * height; ++y) {
		for (X x = 0; x <= 2 * width; ++x) {
			if (y % 2 != x % 2) {
				Field::EdgeState expected;
				if (test_target[y][x] == 'x') expected = Field::EDGE_BLANK;
				else if (test_target[y][x] == ' ') expected = Field::EDGE_UNDECIDED;
				else expected = Field::EDGE_LINE;

				if (field.GetEdge(Position(y, x)) != expected) {
					y = y;
				}
				assert(field.GetEdge(Position(y, x)) == expected);
			}
		}
	}
}
}

namespace penciloid
{
namespace test
{
void RunAllSlitherlinkFieldTest()
{
	SlitherlinkFieldAddClue();
	SlitherlinkFieldTheorem();
}
void SlitherlinkFieldAddClue()
{
	using namespace slitherlink;

	Database db;
	db.CreateDefault();

	DoAddClueTest(3, 3, {
		"+ + + +",
		"       ",
		"+ +x+ +",
		"  x0x  ",
		"+ +x+ +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+x+ + +",
		"x1     ",
		"+ + + +",
		"       ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+ +-+ +",
		" 2     ",
		"+ + + +",
		"|      ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+ + +",
		"|3     ",
		"+ + + +",
		"       ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+x+x+-+",
		"x0x2| |",
		"+x+-+x+",
		"x | x |",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+-+-+",
		"|2x1x |",
		"+x+x+ +",
		"| x    ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+-+-+",
		"|2x1x |",
		"+x+x+-+",
		"| x2| x",
		"+ +-+x+",
		"    x x",
		"+ +x+x+",
	}, &db);
}
void SlitherlinkFieldTheorem()
{
	using namespace slitherlink;

	Database db;
	db.CreateDefault();

	DoAddClueTest(3, 3, {
		"+ + + +",
		"  x    ",
		"+ + + +",
		"|3|3|  ",
		"+ + + +",
		"  x    ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 4, {
		"+ + +-+x+",
		"     3| x",
		"+ + + + +",
		"  |3     ",
		"+x+-+ + +",
		"  x      ",
		"+ + + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+-+-+",
		"| x x |",
		"+x+-+x+",
		"|3|3| |",
		"+-+x+ +",
		"x1x    ",
		"+x+x+ +",
	}, &db);
}
}
}
<commit_msg>Slitherlink: check IsInconsistent and IsFullySolved in DoAddClueTest<commit_after>#include "test_slitherlink_field.h"
#include "test.h"

#include <cassert>
#include <vector>

#include "../slitherlink/sl_field.h"
#include "../slitherlink/sl_database.h"

namespace
{
// Place clues and check edges
void DoAddClueTest(penciloid::Y height, penciloid::X width, std::vector<const char*> test_target, penciloid::slitherlink::Database *db, bool inconsistent = false, bool fully_solved = false)
{
	using namespace penciloid;
	using namespace penciloid::slitherlink;

	Field field(height, width);
	field.SetDatabase(db);

	for (Y y = 0; y < height; ++y) {
		for (X x = 0; x < width; ++x) {
			if ('0' <= test_target[y * 2 + 1][x * 2 + 1] && test_target[y * 2 + 1][x * 2 + 1] <= '3') {
				field.AddClue(Position(y, x), test_target[y * 2 + 1][x * 2 + 1] - '0');
			}
		}
	}

	for (Y y = 0; y <= 2 * height; ++y) {
		for (X x = 0; x <= 2 * width; ++x) {
			if (y % 2 != x % 2) {
				Field::EdgeState expected;
				if (test_target[y][x] == 'x') expected = Field::EDGE_BLANK;
				else if (test_target[y][x] == ' ') expected = Field::EDGE_UNDECIDED;
				else expected = Field::EDGE_LINE;

				if (field.GetEdge(Position(y, x)) != expected) {
					y = y;
				}
				assert(field.GetEdge(Position(y, x)) == expected);
			}
		}
	}

	assert(field.IsInconsistent() == inconsistent);
	assert(field.IsFullySolved() == fully_solved);
}
}

namespace penciloid
{
namespace test
{
void RunAllSlitherlinkFieldTest()
{
	SlitherlinkFieldAddClue();
	SlitherlinkFieldTheorem();
}
void SlitherlinkFieldAddClue()
{
	using namespace slitherlink;

	Database db;
	db.CreateDefault();

	DoAddClueTest(3, 3, {
		"+ + + +",
		"       ",
		"+ +x+ +",
		"  x0x  ",
		"+ +x+ +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+x+ + +",
		"x1     ",
		"+ + + +",
		"       ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+ +-+ +",
		" 2     ",
		"+ + + +",
		"|      ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+ + +",
		"|3     ",
		"+ + + +",
		"       ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+x+x+-+",
		"x0x2| |",
		"+x+-+x+",
		"x | x |",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+-+-+",
		"|2x1x |",
		"+x+x+ +",
		"| x    ",
		"+ + + +",
		"       ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+-+-+",
		"|2x1x |",
		"+x+x+-+",
		"| x2| x",
		"+ +-+x+",
		"    x x",
		"+ +x+x+",
	}, &db);
}
void SlitherlinkFieldTheorem()
{
	using namespace slitherlink;

	Database db;
	db.CreateDefault();

	DoAddClueTest(3, 3, {
		"+ + + +",
		"  x    ",
		"+ + + +",
		"|3|3|  ",
		"+ + + +",
		"  x    ",
		"+ + + +",
	}, &db);
	DoAddClueTest(3, 4, {
		"+ + +-+x+",
		"     3| x",
		"+ + + + +",
		"  |3     ",
		"+x+-+ + +",
		"  x      ",
		"+ + + + +",
	}, &db);
	DoAddClueTest(3, 3, {
		"+-+-+-+",
		"| x x |",
		"+x+-+x+",
		"|3|3| |",
		"+-+x+ +",
		"x1x    ",
		"+x+x+ +",
	}, &db);
}
}
}
<|endoftext|>


<commit_before>#include <iostream>
#include <seqan/sequence.h>

int computeScore(seqan::String<seqan::Dna> subText, seqan::String<seqan::Dna> pattern)
{
    int localScore = 0;
    for (unsigned i = 0; i < seqan::length(pattern); ++i)
        if (subText[i] == pattern[i])
            ++localScore;

    return localScore;
}

int main()
{
    seqan::String<seqan::Dna> text = "This is an awesome tutorial to get to now the basic principles of SeqAn!";
    seqan::String<seqan::Dna> pattern = "tutorial";

    seqan::String<int> score;
    seqan::resize(score, seqan::length(text), 0);

    for (unsigned i = 0; i < seqan::length(text) - seqan::length(pattern) + 1; ++i)
        score[i] = computeScore(seqan::infix(text, i, i + seqan::length(pattern)), pattern);

    for (unsigned i = 0; i < seqan::length(score); ++i)
        std::cout << score[i] << " ";
    std::cout << std::endl;

    return 0;
}
<commit_msg>[DOC] Added a print statement to the example code.<commit_after>#include <iostream>
#include <seqan/sequence.h>

int computeScore(seqan::String<seqan::Dna> subText, seqan::String<seqan::Dna> pattern)
{
    int localScore = 0;
    for (unsigned i = 0; i < seqan::length(pattern); ++i)
        if (subText[i] == pattern[i])
            ++localScore;

    return localScore;
}

int main()
{
    seqan::String<seqan::Dna> text = "This is an awesome tutorial to get to now the basic principles of SeqAn!";
    seqan::String<seqan::Dna> pattern = "tutorial";

    std::cout << text << std::endl;

    seqan::String<int> score;
    seqan::resize(score, seqan::length(text), 0);

    for (unsigned i = 0; i < seqan::length(text) - seqan::length(pattern) + 1; ++i)
        score[i] = computeScore(seqan::infix(text, i, i + seqan::length(pattern)), pattern);

    for (unsigned i = 0; i < seqan::length(score); ++i)
        std::cout << score[i] << " ";
    std::cout << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>#ifndef MATH_CPP
#define MATH_CPP
#include <cmath>

#include "math.hpp"

float distanceTo(float aX, float aY, float bX, float bY)
{
    //ax-bx sq + ay-by sq
    float x=aX-bX;
    float y=aY-bY;
    return sqrtf(x*x + y*y);
}
float manhattanTo(float aX, float aY, float bX, float bY)
{
    //ax-bx sq + ay-by sq
    float x=aX-bX;
    float y=aY-bY;
    return x*x + y*y;
}
float pointTowards(float aX, float aY, float bX, float bY)
{
    return radToDeg(atan2f((bY-aY) , (bX-aX)));
}
float magnitude(float x, float y)
{
    return distanceTo(0, 0, x, y);
}
void normalize(coordinate* toNormalize)
{
	float length=magnitude(toNormalize->x, toNormalize->y);
    if (length > 0)
    {
        toNormalize->x/=length;
        toNormalize->y/=length;
    }
}
coordinate getVectorNormal(float x, float y, bool right)
{
	coordinate returnCoord;
	if (!right)
	{
		returnCoord.x=-y;
		returnCoord.y=x;
	}
	else
	{
		returnCoord.x=y;
		returnCoord.y=-x;
	}
	return returnCoord;
}
coordinate getVectorNormal(coordinate* vectorIn, bool right)
{
	coordinate returnCoord;
	if (!right)
	{
		returnCoord.x=-vectorIn->y;
		returnCoord.y=vectorIn->x;
	}
	else
	{
		returnCoord.x=vectorIn->y;
		returnCoord.y=-vectorIn->x;
	}
	return returnCoord;
}
float radToDeg(float radian)
{
	//180/pi
	return radian*57.295779513;
}
float degToRad(float degree)
{
	//pi/180
	return degree*0.017453278;
}
coordinate degToVec(float degree)
{
	coordinate result;
	float radian=degToRad(degree);
	result.x=cosf(radian);
	result.y=sinf(radian);
	return result;
}
bool isVisible(int x, int y, int wX, int wY, int windowW, int windowH)
{
	if (x + wX < 0 || y + wY < 0) return false;
	if (x > windowW || y > windowH) return false;
	return true;
}
#endif
<commit_msg>Changed manhattan function to abs rather than square<commit_after>#ifndef MATH_CPP
#define MATH_CPP
#include <cmath>

#include "math.hpp"

float distanceTo(float aX, float aY, float bX, float bY)
{
    //ax-bx sq + ay-by sq
    float x=aX-bX;
    float y=aY-bY;
    return sqrtf(x*x + y*y);
}
float manhattanTo(float aX, float aY, float bX, float bY)
{
    //ax-bx abs + ay-by abs
    float x=aX-bX;
    float y=aY-bY;
    return fabs(x) + fabs(y);
}
float pointTowards(float aX, float aY, float bX, float bY)
{
    return radToDeg(atan2f((bY-aY) , (bX-aX)));
}
float magnitude(float x, float y)
{
    return distanceTo(0, 0, x, y);
}
void normalize(coordinate* toNormalize)
{
	float length=magnitude(toNormalize->x, toNormalize->y);
    if (length > 0)
    {
        toNormalize->x/=length;
        toNormalize->y/=length;
    }
}
coordinate getVectorNormal(float x, float y, bool right)
{
	coordinate returnCoord;
	if (!right)
	{
		returnCoord.x=-y;
		returnCoord.y=x;
	}
	else
	{
		returnCoord.x=y;
		returnCoord.y=-x;
	}
	return returnCoord;
}
coordinate getVectorNormal(coordinate* vectorIn, bool right)
{
	coordinate returnCoord;
	if (!right)
	{
		returnCoord.x=-vectorIn->y;
		returnCoord.y=vectorIn->x;
	}
	else
	{
		returnCoord.x=vectorIn->y;
		returnCoord.y=-vectorIn->x;
	}
	return returnCoord;
}
float radToDeg(float radian)
{
	//180/pi
	return radian*57.295779513;
}
float degToRad(float degree)
{
	//pi/180
	return degree*0.017453278;
}
coordinate degToVec(float degree)
{
	coordinate result;
	float radian=degToRad(degree);
	result.x=cosf(radian);
	result.y=sinf(radian);
	return result;
}
bool isVisible(int x, int y, int wX, int wY, int windowW, int windowH)
{
	if (x + wX < 0 || y + wY < 0) return false;
	if (x > windowW || y > windowH) return false;
	return true;
}
#endif
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2012, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECoreGL/ColorTexture.h"
#include "IECoreGL/Exception.h"
#include "IECoreGL/NumericTraits.h"

#include "IECore/VectorTypedData.h"
#include "IECore/MessageHandler.h"

using namespace IECoreGL;
using namespace IECore;
using namespace Imath;
using namespace std;
using namespace boost;

IE_CORE_DEFINERUNTIMETYPED( ColorTexture );

ColorTexture::ColorTexture( unsigned int width, unsigned int height )
{
	glGenTextures( 1, &m_texture );
	ScopedBinding binding( *this );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
		GL_FLOAT, 0 );
}

ColorTexture::ColorTexture( unsigned int width, unsigned int height, IECore::ConstDataPtr r,
	IECore::ConstDataPtr g, IECore::ConstDataPtr b, IECore::ConstDataPtr a )
{
	construct( width, height, r, g, b, a );
}

static IECore::ConstDataPtr findChannel( const IECore::PrimitiveVariableMap &variables, const char **names )
{
	while( *names!=0 )
	{
		IECore::PrimitiveVariableMap::const_iterator it = variables.find( *names );
		if( it!=variables.end() )
		{
			PrimitiveVariable::Interpolation interpolation = it->second.interpolation;
			if( interpolation==PrimitiveVariable::Vertex ||
				interpolation==PrimitiveVariable::Varying ||
				interpolation==PrimitiveVariable::FaceVarying )
			{
				return it->second.data;
			}
		}
		names++;
	}
	return 0;
}

ColorTexture::ColorTexture( IECore::ConstImagePrimitivePtr image )
{
	static const char *redNames[] = { "r", "R", "red", 0 };
	static const char *greenNames[] = { "g", "G", "green", 0 };
	static const char *blueNames[] = { "b", "B", "blue", 0 };
	static const char *alphaNames[] = { "a", "A", "alpha", 0 };

	IECore::ConstDataPtr r = findChannel( image->variables, redNames );
	IECore::ConstDataPtr g = findChannel( image->variables, greenNames );
	IECore::ConstDataPtr b = findChannel( image->variables, blueNames );
	IECore::ConstDataPtr a = findChannel( image->variables, alphaNames );

	if( !(r && g && b) )
	{
		throw Exception( "Unsupported color format." );
	}

	int width = image->getDataWindow().size().x + 1;
	int height = image->getDataWindow().size().y + 1;
	construct( width, height, r, g, b, a );
}

ColorTexture::~ColorTexture()
{
}

void ColorTexture::construct( unsigned int width, unsigned int height, IECore::ConstDataPtr r,
	IECore::ConstDataPtr g, IECore::ConstDataPtr b, IECore::ConstDataPtr a )
{
	if( r->typeId() != g->typeId() ||
		r->typeId() != b->typeId() ||
		( a && (r->typeId() != a->typeId()) ) )
	{
		throw Exception( "Channel types do not match." );
	}

	if( r->typeId()==UCharVectorData::staticTypeId() )
	{
		castConstruct<UCharVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==CharVectorData::staticTypeId() )
	{
		castConstruct<CharVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==UIntVectorData::staticTypeId() )
	{
		castConstruct<UIntVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==IntVectorData::staticTypeId() )
	{
		castConstruct<IntVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==HalfVectorData::staticTypeId() )
	{
		castConstruct<HalfVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==FloatVectorData::staticTypeId() )
	{
		castConstruct<FloatVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==DoubleVectorData::staticTypeId() )
	{
		castConstruct<DoubleVectorData>( width, height, r, g, b, a );
	}
	else {
		throw Exception( boost::str( boost::format( "Unsupported channel type \"%s\"." ) % r->typeName() ) );
	}
}

template<class T>
void ColorTexture::castConstruct( unsigned int width, unsigned int height, IECore::ConstDataPtr r,
	IECore::ConstDataPtr g, IECore::ConstDataPtr b, IECore::ConstDataPtr a )
{
	templateConstruct( width, height,
		staticPointerCast<const T>( r ),
		staticPointerCast<const T>( g ),
		staticPointerCast<const T>( b ),
		staticPointerCast<const T>( a )	);
}

template<typename T>
void ColorTexture::templateConstruct( unsigned int width, unsigned int height, IECore::IntrusivePtr<const T> r,
	IECore::IntrusivePtr<const T> g,  IECore::IntrusivePtr<const T> b, IECore::IntrusivePtr<const T> a )
{
	typedef typename T::ValueType::value_type ElementType;

	const std::vector<ElementType> &rr = r->readable();
	const std::vector<ElementType> &rg = g->readable();
	const std::vector<ElementType> &rb = b->readable();
	const std::vector<ElementType> *ra = a ? &a->readable() : 0;

	unsigned int n = width * height;
	if( rr.size()!=n || rg.size()!=n || rb.size()!=n || (ra && ra->size()!=n) )
	{
		throw IECore::Exception( "Image data has wrong size." );
	}

	std::vector<ElementType> interleaved( n * (ra ? 4 : 3) );

	unsigned int i = 0;
	for( int y=height-1; y>=0; y-- )
	{
		const ElementType *dr = &rr[y*width];
		const ElementType *dg = &rg[y*width];
		const ElementType *db = &rb[y*width];
		const ElementType *da = ra ? &(*ra)[y*width] : 0;

		for( unsigned int x=0; x<width; x++ )
		{
			interleaved[i++] = dr[x];
			interleaved[i++] = dg[x];
			interleaved[i++] = db[x];
			if( da )
			{
				interleaved[i++] = da[x];
			}
		}
	}

	glGenTextures( 1, &m_texture );

	ScopedBinding binding( *this );

	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

	glTexImage2D( GL_TEXTURE_2D, 0, ra ? GL_RGBA16 : GL_RGB16, width, height, 0, ra ? GL_RGBA : GL_RGB,
		NumericTraits<ElementType>::glType(), &interleaved[0] );

	Exception::throwIfError();

}

ImagePrimitivePtr ColorTexture::imagePrimitive() const
{
	ScopedBinding binding( *this );

	GLint width = 0;
	GLint height = 0;
	glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width );
	glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height );

	GLint internalFormat = 0;
	glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat );

	unsigned int numChannels = 4;
	vector<float> data( width * height * numChannels );

	glGetTexImage( GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &data[0] );

	FloatVectorDataPtr rd = new FloatVectorData();
	vector<float> &r = rd->writable(); r.resize( width * height );

	FloatVectorDataPtr gd = new FloatVectorData();
	vector<float> &g = gd->writable(); g.resize( width * height );

	FloatVectorDataPtr bd = new FloatVectorData();
	vector<float> &b = bd->writable(); b.resize( width * height );

	FloatVectorDataPtr ad = 0;
	vector<float> *a = 0;
	// there are potentially loads of different internal formats which denote alpha.
	// these are the only ones encountered so far, but it's not a great way of testing
	// and i can't find another way of doing it.
	if( internalFormat==GL_RGBA || internalFormat==GL_RGBA8_EXT )
	{
		ad = new FloatVectorData();
		a = &ad->writable(); a->resize( width * height );
	}

	unsigned int i = 0;
	for( int y=height-1; y>=0; y-- )
	{
		float *rr = &r[y*width];
		float *rg = &g[y*width];
		float *rb = &b[y*width];
		float *ra = a ? &(*a)[y*width] : 0;
		for( int x=0; x<width; x++ )
		{
			rr[x] = data[i++];
			rg[x] = data[i++];
			rb[x] = data[i++];
			if( ra )
			{
				ra[x] = data[i++];
			}
		}
	}

	Box2i imageExtents( V2i( 0, 0 ), V2i( width-1, height-1 ) );
	ImagePrimitivePtr image = new ImagePrimitive( imageExtents, imageExtents );
	image->variables["R"] = PrimitiveVariable( PrimitiveVariable::Vertex, rd );
	image->variables["G"] = PrimitiveVariable( PrimitiveVariable::Vertex, gd );
	image->variables["B"] = PrimitiveVariable( PrimitiveVariable::Vertex, bd );
	if( a )
	{
		image->variables["A"] = PrimitiveVariable( PrimitiveVariable::Vertex, ad );
	}

	Exception::throwIfError();

	return image;
}
<commit_msg>Fixed the failing IECoreGL::ColorTexture test cases.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2012, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECoreGL/ColorTexture.h"
#include "IECoreGL/Exception.h"
#include "IECoreGL/NumericTraits.h"

#include "IECore/VectorTypedData.h"
#include "IECore/MessageHandler.h"

using namespace IECoreGL;
using namespace IECore;
using namespace Imath;
using namespace std;
using namespace boost;

IE_CORE_DEFINERUNTIMETYPED( ColorTexture );

ColorTexture::ColorTexture( unsigned int width, unsigned int height )
{
	glGenTextures( 1, &m_texture );
	ScopedBinding binding( *this );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
		GL_FLOAT, 0 );
}

ColorTexture::ColorTexture( unsigned int width, unsigned int height, IECore::ConstDataPtr r,
	IECore::ConstDataPtr g, IECore::ConstDataPtr b, IECore::ConstDataPtr a )
{
	construct( width, height, r, g, b, a );
}

static IECore::ConstDataPtr findChannel( const IECore::PrimitiveVariableMap &variables, const char **names )
{
	while( *names!=0 )
	{
		IECore::PrimitiveVariableMap::const_iterator it = variables.find( *names );
		if( it!=variables.end() )
		{
			PrimitiveVariable::Interpolation interpolation = it->second.interpolation;
			if( interpolation==PrimitiveVariable::Vertex ||
				interpolation==PrimitiveVariable::Varying ||
				interpolation==PrimitiveVariable::FaceVarying )
			{
				return it->second.data;
			}
		}
		names++;
	}
	return 0;
}

ColorTexture::ColorTexture( IECore::ConstImagePrimitivePtr image )
{
	static const char *redNames[] = { "r", "R", "red", 0 };
	static const char *greenNames[] = { "g", "G", "green", 0 };
	static const char *blueNames[] = { "b", "B", "blue", 0 };
	static const char *alphaNames[] = { "a", "A", "alpha", 0 };

	IECore::ConstDataPtr r = findChannel( image->variables, redNames );
	IECore::ConstDataPtr g = findChannel( image->variables, greenNames );
	IECore::ConstDataPtr b = findChannel( image->variables, blueNames );
	IECore::ConstDataPtr a = findChannel( image->variables, alphaNames );

	if( !(r && g && b) )
	{
		throw Exception( "Unsupported color format." );
	}

	int width = image->getDataWindow().size().x + 1;
	int height = image->getDataWindow().size().y + 1;
	construct( width, height, r, g, b, a );
}

ColorTexture::~ColorTexture()
{
}

void ColorTexture::construct( unsigned int width, unsigned int height, IECore::ConstDataPtr r,
	IECore::ConstDataPtr g, IECore::ConstDataPtr b, IECore::ConstDataPtr a )
{
	if( r->typeId() != g->typeId() ||
		r->typeId() != b->typeId() ||
		( a && (r->typeId() != a->typeId()) ) )
	{
		throw Exception( "Channel types do not match." );
	}

	if( r->typeId()==UCharVectorData::staticTypeId() )
	{
		castConstruct<UCharVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==CharVectorData::staticTypeId() )
	{
		castConstruct<CharVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==UIntVectorData::staticTypeId() )
	{
		castConstruct<UIntVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==IntVectorData::staticTypeId() )
	{
		castConstruct<IntVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==HalfVectorData::staticTypeId() )
	{
		castConstruct<HalfVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==FloatVectorData::staticTypeId() )
	{
		castConstruct<FloatVectorData>( width, height, r, g, b, a );
	}
	else if( r->typeId()==DoubleVectorData::staticTypeId() )
	{
		castConstruct<DoubleVectorData>( width, height, r, g, b, a );
	}
	else {
		throw Exception( boost::str( boost::format( "Unsupported channel type \"%s\"." ) % r->typeName() ) );
	}
}

template<class T>
void ColorTexture::castConstruct( unsigned int width, unsigned int height, IECore::ConstDataPtr r,
	IECore::ConstDataPtr g, IECore::ConstDataPtr b, IECore::ConstDataPtr a )
{
	templateConstruct( width, height,
		staticPointerCast<const T>( r ),
		staticPointerCast<const T>( g ),
		staticPointerCast<const T>( b ),
		staticPointerCast<const T>( a )	);
}

template<typename T>
void ColorTexture::templateConstruct( unsigned int width, unsigned int height, IECore::IntrusivePtr<const T> r,
	IECore::IntrusivePtr<const T> g,  IECore::IntrusivePtr<const T> b, IECore::IntrusivePtr<const T> a )
{
	typedef typename T::ValueType::value_type ElementType;

	const std::vector<ElementType> &rr = r->readable();
	const std::vector<ElementType> &rg = g->readable();
	const std::vector<ElementType> &rb = b->readable();
	const std::vector<ElementType> *ra = a ? &a->readable() : 0;

	unsigned int n = width * height;
	if( rr.size()!=n || rg.size()!=n || rb.size()!=n || (ra && ra->size()!=n) )
	{
		throw IECore::Exception( "Image data has wrong size." );
	}

	std::vector<ElementType> interleaved( n * (ra ? 4 : 3) );

	unsigned int i = 0;
	for( int y=height-1; y>=0; y-- )
	{
		const ElementType *dr = &rr[y*width];
		const ElementType *dg = &rg[y*width];
		const ElementType *db = &rb[y*width];
		const ElementType *da = ra ? &(*ra)[y*width] : 0;

		for( unsigned int x=0; x<width; x++ )
		{
			interleaved[i++] = dr[x];
			interleaved[i++] = dg[x];
			interleaved[i++] = db[x];
			if( da )
			{
				interleaved[i++] = da[x];
			}
		}
	}

	glGenTextures( 1, &m_texture );

	ScopedBinding binding( *this );

	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

	glTexImage2D( GL_TEXTURE_2D, 0, ra ? GL_RGBA16 : GL_RGB16, width, height, 0, ra ? GL_RGBA : GL_RGB,
		NumericTraits<ElementType>::glType(), &interleaved[0] );

	Exception::throwIfError();

}

ImagePrimitivePtr ColorTexture::imagePrimitive() const
{
	ScopedBinding binding( *this );

	GLint width = 0;
	GLint height = 0;
	glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width );
	glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height );

	GLint internalFormat = 0;
	glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat );

	unsigned int numChannels = 4;
	vector<float> data( width * height * numChannels );

	glGetTexImage( GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &data[0] );

	FloatVectorDataPtr rd = new FloatVectorData();
	vector<float> &r = rd->writable(); r.resize( width * height );

	FloatVectorDataPtr gd = new FloatVectorData();
	vector<float> &g = gd->writable(); g.resize( width * height );

	FloatVectorDataPtr bd = new FloatVectorData();
	vector<float> &b = bd->writable(); b.resize( width * height );

	FloatVectorDataPtr ad = 0;
	vector<float> *a = 0;
	// there are potentially loads of different internal formats which denote alpha.
	// these are the only ones encountered so far, but it's not a great way of testing
	// and i can't find another way of doing it.
	if( internalFormat==GL_RGBA || internalFormat==GL_RGBA8_EXT || internalFormat==GL_RGBA16 )
	{
		ad = new FloatVectorData();
		a = &ad->writable(); a->resize( width * height );
	}

	unsigned int i = 0;
	for( int y=height-1; y>=0; y-- )
	{
		float *rr = &r[y*width];
		float *rg = &g[y*width];
		float *rb = &b[y*width];
		float *ra = a ? &(*a)[y*width] : 0;
		for( int x=0; x<width; x++ )
		{
			rr[x] = data[i++];
			rg[x] = data[i++];
			rb[x] = data[i++];
			if( ra )
			{
				ra[x] = data[i++];
			}
		}
	}

	Box2i imageExtents( V2i( 0, 0 ), V2i( width-1, height-1 ) );
	ImagePrimitivePtr image = new ImagePrimitive( imageExtents, imageExtents );
	image->variables["R"] = PrimitiveVariable( PrimitiveVariable::Vertex, rd );
	image->variables["G"] = PrimitiveVariable( PrimitiveVariable::Vertex, gd );
	image->variables["B"] = PrimitiveVariable( PrimitiveVariable::Vertex, bd );
	if( a )
	{
		image->variables["A"] = PrimitiveVariable( PrimitiveVariable::Vertex, ad );
	}

	Exception::throwIfError();

	return image;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2008 Werner Mayer <werner.wm.mayer@gmx.de>              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <qobject.h>
#endif

#include "Workbench.h"
#include <Gui/ToolBarManager.h>
#include <Gui/MenuManager.h>

using namespace FemGui;

#if 0 // needed for Qt's lupdate utility
    qApp->translate("Workbench", "FEM");
    qApp->translate("Workbench", "&FEM");
#endif

/// @namespace FemGui @class Workbench
TYPESYSTEM_SOURCE(FemGui::Workbench, Gui::StdWorkbench)

Workbench::Workbench()
{
}

Workbench::~Workbench()
{
}

Gui::ToolBarItem* Workbench::setupToolBars() const
{
    Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
    Gui::ToolBarItem* fem = new Gui::ToolBarItem(root);
    fem->setCommand("FEM");
    *fem << "Fem_MechanicalMaterial"
         << "Fem_NewMechanicalAnalysis"
         << "Fem_MechanicalJobControl"
         << "Separator"
         << "Fem_CreateNodesSet"
         << "Separator"
         << "Fem_ConstraintFixed"
         << "Fem_ConstraintForce"
         << "Fem_ConstraintBearing"
         << "Fem_ConstraintGear"
         << "Fem_ConstraintPulley"
         << "Separator"
         << "Fem_ShowResult";
    return root;
}

Gui::MenuItem* Workbench::setupMenuBar() const
{
    Gui::MenuItem* root = StdWorkbench::setupMenuBar();
    Gui::MenuItem* item = root->findItem("&Windows");
    Gui::MenuItem* fem = new Gui::MenuItem;
    root->insertItem(item, fem);
    fem->setCommand("&FEM");
    *fem << "Fem_MechanicalMaterial"
         << "Fem_NewMechanicalAnalysis"
         << "Fem_MechanicalJobControl"
         << "Separator"
         << "Fem_CreateNodesSet"
         << "Separator"
         << "Fem_ConstraintFixed"
         << "Fem_ConstraintForce"
         << "Fem_ConstraintBearing"
         << "Fem_ConstraintGear"
         << "Fem_ConstraintPulley"
         << "Separator"
         << "Fem_ShowResult"
         ;

    return root;
}
<commit_msg>FEM: Change order of FEM toolbar items<commit_after>/***************************************************************************
 *   Copyright (c) 2008 Werner Mayer <werner.wm.mayer@gmx.de>              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <qobject.h>
#endif

#include "Workbench.h"
#include <Gui/ToolBarManager.h>
#include <Gui/MenuManager.h>

using namespace FemGui;

#if 0 // needed for Qt's lupdate utility
    qApp->translate("Workbench", "FEM");
    qApp->translate("Workbench", "&FEM");
#endif

/// @namespace FemGui @class Workbench
TYPESYSTEM_SOURCE(FemGui::Workbench, Gui::StdWorkbench)

Workbench::Workbench()
{
}

Workbench::~Workbench()
{
}

Gui::ToolBarItem* Workbench::setupToolBars() const
{
    Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
    Gui::ToolBarItem* fem = new Gui::ToolBarItem(root);
    fem->setCommand("FEM");
    *fem << "Fem_NewMechanicalAnalysis"
         << "Fem_MechanicalMaterial"
         << "Separator"
         << "Fem_CreateNodesSet"
         << "Separator"
         << "Fem_ConstraintFixed"
         << "Fem_ConstraintForce"
         << "Fem_ConstraintBearing"
         << "Fem_ConstraintGear"
         << "Fem_ConstraintPulley"
         << "Separator"
         << "Fem_MechanicalJobControl"
         << "Fem_ShowResult";
    return root;
}

Gui::MenuItem* Workbench::setupMenuBar() const
{
    Gui::MenuItem* root = StdWorkbench::setupMenuBar();
    Gui::MenuItem* item = root->findItem("&Windows");
    Gui::MenuItem* fem = new Gui::MenuItem;
    root->insertItem(item, fem);
    fem->setCommand("&FEM");
    *fem << "Fem_NewMechanicalAnalysis"
         << "Fem_MechanicalMaterial"
         << "Separator"
         << "Fem_CreateNodesSet"
         << "Separator"
         << "Fem_ConstraintFixed"
         << "Fem_ConstraintForce"
         << "Fem_ConstraintBearing"
         << "Fem_ConstraintGear"
         << "Fem_ConstraintPulley"
         << "Separator"
         << "Fem_MechanicalJobControl"
         << "Fem_ShowResult";

    return root;
}
<|endoftext|>