<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008-2009, Image Engine Design Inc. All rights reserved.
//
//  Copyright 2010 Dr D Studios Pty Limited (ACN 127 184 954) (Dr. D Studios),
//  its affiliates and/or its licensors.
//
//  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 "boost/format.hpp"

#include "IECore/PointsPrimitive.h"
#include "IECore/MeshPrimitive.h"
#include "IECore/ObjectParameter.h"
#include "IECore/CompoundParameter.h"
#include "IECore/CompoundObject.h"
#include "IECore/VectorTypedData.h"
#include "IECore/RunTimeTyped.h"
#include "IECore/PointSmoothSkinningOp.h"
#include "IECore/SmoothSkinningData.h"
#include "IECore/PrimitiveEvaluator.h"
#include "IECore/VectorOps.h"
#include "IECore/DespatchTypedData.h"

using namespace IECore;
using namespace Imath;
using namespace std;

IE_CORE_DEFINERUNTIMETYPED( PointSmoothSkinningOp );

PointSmoothSkinningOp::PointSmoothSkinningOp() :
	        ModifyOp(
	                "Deforms points and normals based on a pose and SmoothSkinningData.",
	                new PrimitiveParameter(
	                        "result",
	                        "The updated Primitive with deformed points and normals.",
	                        new PointsPrimitive()
	                        ),
	                new PrimitiveParameter(
	                        "input",
	                        "The input Primitive with points and normals to deform.",
	                        new PointsPrimitive()
	                        )
	                )
{
    m_positionVarParameter = new StringParameter(
            "positionVar",
            "The variable name to use as per-point position.",
            "P" );
    parameters()->addParameter( m_positionVarParameter );

    m_normalVarParameter = new StringParameter(
            "normalVar",
            "The variable name to use as per-point normal.",
            "N" );
    parameters()->addParameter( m_normalVarParameter );

	m_deformNormalsParameter = new BoolParameter(
	        "deformNormals",
	        "Deform the normals of the mesh or just the points.",
	        false
	);
	parameters()->addParameter( m_deformNormalsParameter );

	IntParameter::PresetsContainer blendPresets;
	blendPresets.push_back( IntParameter::Preset( "Linear", Linear ) );
	m_blendParameter = new IntParameter(
	        "blend",
	        "Blending algorithm used to deform the mesh.",
	        Linear,
	        Linear,
	        Linear,
	        blendPresets,
	        true
	);
	parameters()->addParameter( m_blendParameter );

	m_smoothSkinningDataParameter = new SmoothSkinningDataParameter(
		"smoothSkinningData",
		"Set the SmoothSkinningData to be used in the deformation",
		new SmoothSkinningData()
	);
	parameters()->addParameter( m_smoothSkinningDataParameter );

	m_deformationPoseParameter = new M44fVectorParameter(
		"deformationPose",
		"Set the deformationPose (a M44fVectorData object) to be used in the deformation",
		new M44fVectorData()
	);
	parameters()->addParameter( m_deformationPoseParameter );

	m_refIndicesParameter = new IntVectorParameter(
		"referenceIndices",
		"Set the reference indices to be used for querying the smooth skinning data in the deformation.",
		new IntVectorData()
	);
	parameters()->addParameter( m_refIndicesParameter );

}

PointSmoothSkinningOp::~PointSmoothSkinningOp()
{
}

StringParameter * PointSmoothSkinningOp::positionVarParameter()
{
        return m_positionVarParameter.get();
}

const StringParameter * PointSmoothSkinningOp::positionVarParameter() const
{
        return m_positionVarParameter.get();
}

StringParameter * PointSmoothSkinningOp::normalVarParameter()
{
        return m_normalVarParameter.get();
}

const StringParameter * PointSmoothSkinningOp::normalVarParameter() const
{
        return m_normalVarParameter.get();
}

M44fVectorParameter * PointSmoothSkinningOp::deformationPoseParameter()
{
	return m_deformationPoseParameter.get();
}

const M44fVectorParameter * PointSmoothSkinningOp::deformationPoseParameter() const
{
	return m_deformationPoseParameter.get();
}

SmoothSkinningDataParameter * PointSmoothSkinningOp::smoothSkinningDataParameter()
{
	return m_smoothSkinningDataParameter.get();
}

const SmoothSkinningDataParameter * PointSmoothSkinningOp::smoothSkinningDataParameter() const
{
	return m_smoothSkinningDataParameter.get();
}

BoolParameter * PointSmoothSkinningOp::deformNormalsParameter()
{
	return m_deformNormalsParameter.get();
}

const BoolParameter * PointSmoothSkinningOp::deformNormalsParameter() const
{
	return m_deformNormalsParameter.get();
}

IntParameter * PointSmoothSkinningOp::blendParameter()
{
	return m_blendParameter.get();
}

const IntParameter * PointSmoothSkinningOp::blendParameter() const
{
	return m_blendParameter.get();
}

IntVectorParameter * PointSmoothSkinningOp::refIndicesParameter()
{
	return m_refIndicesParameter;
}

const IntVectorParameter * PointSmoothSkinningOp::refIndicesParameter() const
{
	return m_refIndicesParameter;
}

void PointSmoothSkinningOp::modify( Object *input, const CompoundObject *operands )
{
	// get the input parameters
    Primitive *pt = static_cast<Primitive *>( input );

    bool deform_n = operands->member<BoolData>( "deformNormals" )->readable();
	Blend blend = static_cast<Blend>( m_blendParameter->getNumericValue() );
    string position_var = operands->member<StringData>( "positionVar" )->readable();
    string normal_var = operands->member<StringData>( "normalVar" )->readable();
    SmoothSkinningDataPtr ssd = smoothSkinningDataParameter()->getTypedValue< SmoothSkinningData >( );
	M44fVectorDataPtr def = runTimeCast<M44fVectorData>(deformationPoseParameter()->getValue( ));
	const std::vector<int> &refId_data = operands->member<IntVectorData>( "referenceIndices" )->readable();

	// verify position and normal data
    if ( pt->variables.count(position_var)==0 )
    {
    	throw Exception( "Could not find position variable on primitive!" );
    }

    V3fVectorData *p = pt->variableData<V3fVectorData>(position_var);
    if ( !p )
    {
    	throw Exception("Could not get position data from primitive!");
    }

    std::vector<V3f> &p_data =  p->writable();
    int p_size = p_data.size();

	// Check reference id data. If provided, it must be the same size as P.
	int refId_size = refId_data.size();
	if( refId_size && refId_size != p_size )
	{
		throw InvalidArgumentException( "Number of reference indices does not match point count on Primitive given to PointSmoothSkinningOp" );
	}

    // verify the SmoothSkinningData
	if ( !ssd )
	{
		return;
	}

	int ssd_p_size = ssd->pointInfluenceCounts()->readable().size();

	if ( !refId_size && ssd_p_size != p_size )
	{
		throw InvalidArgumentException( "Number of points in SmoothSkinningData does not match point count on Primitive given to PointSmoothSkinningOp" );
	}

	// get the deformation pose and check its compatibility with the SmoothSkinningData
	const std::vector<M44f> &def_data = def->readable();
	int def_size = def_data.size();

	int inf_size = ssd->influencePose()->readable().size();

	if (def_size != inf_size)
	{
		throw InvalidArgumentException( "Number of elements in SmoothSkinningData.influencePose does not match number of elements in deformationPose given to PointSmoothSkinningOp" );
	}

	// check if the smooth skinning data has changed since the last time the op was used;
	// validating the ssd can be expensive and unnecessary for the case that the ssd is not changing
	// so we are storing an internal copy of the ssd as a comparison is much faster than a complete validation
	if ( ssd != m_prevSmoothSkinningData )
	{
		ssd->validate();
		m_prevSmoothSkinningData = ssd->copy();
	}

	// test n data
	if ( deform_n )
	{
		PrimitiveVariableMap::const_iterator it = pt->variables.find(normal_var);
		if ( it != pt->variables.end() )
		{
			if( !pt->isPrimitiveVariableValid( it->second )  )
			{
				throw Exception("Normal variable on primitive is invalid!");
			}
			if (it->second.interpolation == PrimitiveVariable::FaceVarying )
			{
				MeshPrimitive *mesh = dynamic_cast<MeshPrimitive *>( pt );
				if( !mesh )
				{
					V3fVectorData *n = pt->variableData<V3fVectorData>(normal_var);
					int n_size = n->readable().size();
					if ( p_size != n_size )
					{
						throw Exception("Position and normal variables must be the same length!");
					}
				}
			}
		}
		else
		{
			throw Exception( "Could not find normal variable on primitive!" );
		}
	}

	// generate skinning matrices
	// we are pre-creating these as in the typical use-case the number of influence objects is much lower
	// than the number of vertices that are going to be deformed
    std::vector<M44f> skin_data;
	skin_data.reserve( inf_size );

	std::vector<M44f>::const_iterator ip_it = ssd->influencePose()->readable().begin();

	for( std::vector<M44f>::const_iterator dp_it = def_data.begin();
		 dp_it!=def_data.end(); ++dp_it )
	{

		M44f mat = (*ip_it) *  (*dp_it);
		skin_data.push_back( mat );
		++ip_it;
	}

	// iterate through all the points in the source primitive and deform using the weighted skinning matrices
	if ( blend == Linear )
	{
        std::vector<V3f>::iterator p_it = p_data.begin();

	const std::vector<int> &pointIndexOffsets = ssd->pointIndexOffsets()->readable();
	const std::vector<int> &pointInfluenceCounts = ssd->pointInfluenceCounts()->readable();
	const std::vector<int> &pointInfluenceIndices = ssd->pointInfluenceIndices()->readable();
	const std::vector<float> &pointInfluenceWeights = ssd->pointInfluenceWeights()->readable();

		// todo, thread this
        // deform our P
        for ( p_it=p_data.begin(); p_it!=p_data.end(); ++p_it )
        {
			V3f p_new(0,0,0);

			int p_id = p_it - p_data.begin();

			if( refId_size )
			{
				// get the actual index to look up in the smooth skinning data
				p_id = refId_data[p_id];
			}

			int p_influence_count = pointInfluenceCounts[p_id];
			int p_index_offset = pointIndexOffsets[p_id];

			for (int p_influence_id = p_index_offset; p_influence_id < (p_index_offset+p_influence_count);
					p_influence_id++)
			{
				int influence_id = pointInfluenceIndices[p_influence_id];
				float weight = pointInfluenceWeights[p_influence_id];
				p_new += (*p_it) * skin_data[influence_id] * weight;
			}

			(*p_it) = p_new;

        }

        // deform our N
        if ( deform_n )
        {
		PrimitiveVariableMap::const_iterator it = pt->variables.find(normal_var);
		if ( it != pt->variables.end() )
		{
			V3fVectorData *n = pt->variableData<V3fVectorData>(normal_var);
			std::vector<V3f> &n_data =  n->writable();

			std::vector<V3f>::iterator n_it = n_data.begin();
			V3f n_unw;

			std::vector<int> vertexIndicesData;
			if (it->second.interpolation == PrimitiveVariable::FaceVarying )
			{
				MeshPrimitive *mesh = dynamic_cast<MeshPrimitive *>( pt );
				if( mesh )
				{
					vertexIndicesData = mesh->vertexIds()->readable();
				}
			}

			for ( n_it=n_data.begin(); n_it!=n_data.end(); ++n_it )
			{
				V3f n_new(0,0,0);

				int n_id = n_it - n_data.begin();

				if( vertexIndicesData.size() )
				{
					n_id = vertexIndicesData[n_id];
				}
				if( refId_size )
				{
					n_id = refId_data[n_id];
				}

				int n_influence_count = pointInfluenceCounts[n_id];
				int n_index_offset = pointIndexOffsets[n_id];

				for (int n_influence_id = n_index_offset; n_influence_id < (n_index_offset+n_influence_count);
						n_influence_id++)
				{
					int influence_id = pointInfluenceIndices[n_influence_id];
					float weight = pointInfluenceWeights[n_influence_id];

					skin_data[influence_id].multDirMatrix((*n_it),n_unw);
					n_new += n_unw * weight;
				}
				(*n_it) = n_new;
			}
		}
        }
	}
	else
	{
		// this should never happen
		assert(0);
	}

}
<commit_msg>Fixing return value for newly added parameter.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008-2009, Image Engine Design Inc. All rights reserved.
//
//  Copyright 2010 Dr D Studios Pty Limited (ACN 127 184 954) (Dr. D Studios),
//  its affiliates and/or its licensors.
//
//  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 "boost/format.hpp"

#include "IECore/PointsPrimitive.h"
#include "IECore/MeshPrimitive.h"
#include "IECore/ObjectParameter.h"
#include "IECore/CompoundParameter.h"
#include "IECore/CompoundObject.h"
#include "IECore/VectorTypedData.h"
#include "IECore/RunTimeTyped.h"
#include "IECore/PointSmoothSkinningOp.h"
#include "IECore/SmoothSkinningData.h"
#include "IECore/PrimitiveEvaluator.h"
#include "IECore/VectorOps.h"
#include "IECore/DespatchTypedData.h"

using namespace IECore;
using namespace Imath;
using namespace std;

IE_CORE_DEFINERUNTIMETYPED( PointSmoothSkinningOp );

PointSmoothSkinningOp::PointSmoothSkinningOp() :
	        ModifyOp(
	                "Deforms points and normals based on a pose and SmoothSkinningData.",
	                new PrimitiveParameter(
	                        "result",
	                        "The updated Primitive with deformed points and normals.",
	                        new PointsPrimitive()
	                        ),
	                new PrimitiveParameter(
	                        "input",
	                        "The input Primitive with points and normals to deform.",
	                        new PointsPrimitive()
	                        )
	                )
{
    m_positionVarParameter = new StringParameter(
            "positionVar",
            "The variable name to use as per-point position.",
            "P" );
    parameters()->addParameter( m_positionVarParameter );

    m_normalVarParameter = new StringParameter(
            "normalVar",
            "The variable name to use as per-point normal.",
            "N" );
    parameters()->addParameter( m_normalVarParameter );

	m_deformNormalsParameter = new BoolParameter(
	        "deformNormals",
	        "Deform the normals of the mesh or just the points.",
	        false
	);
	parameters()->addParameter( m_deformNormalsParameter );

	IntParameter::PresetsContainer blendPresets;
	blendPresets.push_back( IntParameter::Preset( "Linear", Linear ) );
	m_blendParameter = new IntParameter(
	        "blend",
	        "Blending algorithm used to deform the mesh.",
	        Linear,
	        Linear,
	        Linear,
	        blendPresets,
	        true
	);
	parameters()->addParameter( m_blendParameter );

	m_smoothSkinningDataParameter = new SmoothSkinningDataParameter(
		"smoothSkinningData",
		"Set the SmoothSkinningData to be used in the deformation",
		new SmoothSkinningData()
	);
	parameters()->addParameter( m_smoothSkinningDataParameter );

	m_deformationPoseParameter = new M44fVectorParameter(
		"deformationPose",
		"Set the deformationPose (a M44fVectorData object) to be used in the deformation",
		new M44fVectorData()
	);
	parameters()->addParameter( m_deformationPoseParameter );

	m_refIndicesParameter = new IntVectorParameter(
		"referenceIndices",
		"Set the reference indices to be used for querying the smooth skinning data in the deformation.",
		new IntVectorData()
	);
	parameters()->addParameter( m_refIndicesParameter );

}

PointSmoothSkinningOp::~PointSmoothSkinningOp()
{
}

StringParameter * PointSmoothSkinningOp::positionVarParameter()
{
        return m_positionVarParameter.get();
}

const StringParameter * PointSmoothSkinningOp::positionVarParameter() const
{
        return m_positionVarParameter.get();
}

StringParameter * PointSmoothSkinningOp::normalVarParameter()
{
        return m_normalVarParameter.get();
}

const StringParameter * PointSmoothSkinningOp::normalVarParameter() const
{
        return m_normalVarParameter.get();
}

M44fVectorParameter * PointSmoothSkinningOp::deformationPoseParameter()
{
	return m_deformationPoseParameter.get();
}

const M44fVectorParameter * PointSmoothSkinningOp::deformationPoseParameter() const
{
	return m_deformationPoseParameter.get();
}

SmoothSkinningDataParameter * PointSmoothSkinningOp::smoothSkinningDataParameter()
{
	return m_smoothSkinningDataParameter.get();
}

const SmoothSkinningDataParameter * PointSmoothSkinningOp::smoothSkinningDataParameter() const
{
	return m_smoothSkinningDataParameter.get();
}

BoolParameter * PointSmoothSkinningOp::deformNormalsParameter()
{
	return m_deformNormalsParameter.get();
}

const BoolParameter * PointSmoothSkinningOp::deformNormalsParameter() const
{
	return m_deformNormalsParameter.get();
}

IntParameter * PointSmoothSkinningOp::blendParameter()
{
	return m_blendParameter.get();
}

const IntParameter * PointSmoothSkinningOp::blendParameter() const
{
	return m_blendParameter.get();
}

IntVectorParameter * PointSmoothSkinningOp::refIndicesParameter()
{
	return m_refIndicesParameter.get();
}

const IntVectorParameter * PointSmoothSkinningOp::refIndicesParameter() const
{
	return m_refIndicesParameter.get();
}

void PointSmoothSkinningOp::modify( Object *input, const CompoundObject *operands )
{
	// get the input parameters
    Primitive *pt = static_cast<Primitive *>( input );

    bool deform_n = operands->member<BoolData>( "deformNormals" )->readable();
	Blend blend = static_cast<Blend>( m_blendParameter->getNumericValue() );
    string position_var = operands->member<StringData>( "positionVar" )->readable();
    string normal_var = operands->member<StringData>( "normalVar" )->readable();
    SmoothSkinningDataPtr ssd = smoothSkinningDataParameter()->getTypedValue< SmoothSkinningData >( );
	M44fVectorDataPtr def = runTimeCast<M44fVectorData>(deformationPoseParameter()->getValue( ));
	const std::vector<int> &refId_data = operands->member<IntVectorData>( "referenceIndices" )->readable();

	// verify position and normal data
    if ( pt->variables.count(position_var)==0 )
    {
    	throw Exception( "Could not find position variable on primitive!" );
    }

    V3fVectorData *p = pt->variableData<V3fVectorData>(position_var);
    if ( !p )
    {
    	throw Exception("Could not get position data from primitive!");
    }

    std::vector<V3f> &p_data =  p->writable();
    int p_size = p_data.size();

	// Check reference id data. If provided, it must be the same size as P.
	int refId_size = refId_data.size();
	if( refId_size && refId_size != p_size )
	{
		throw InvalidArgumentException( "Number of reference indices does not match point count on Primitive given to PointSmoothSkinningOp" );
	}

    // verify the SmoothSkinningData
	if ( !ssd )
	{
		return;
	}

	int ssd_p_size = ssd->pointInfluenceCounts()->readable().size();

	if ( !refId_size && ssd_p_size != p_size )
	{
		throw InvalidArgumentException( "Number of points in SmoothSkinningData does not match point count on Primitive given to PointSmoothSkinningOp" );
	}

	// get the deformation pose and check its compatibility with the SmoothSkinningData
	const std::vector<M44f> &def_data = def->readable();
	int def_size = def_data.size();

	int inf_size = ssd->influencePose()->readable().size();

	if (def_size != inf_size)
	{
		throw InvalidArgumentException( "Number of elements in SmoothSkinningData.influencePose does not match number of elements in deformationPose given to PointSmoothSkinningOp" );
	}

	// check if the smooth skinning data has changed since the last time the op was used;
	// validating the ssd can be expensive and unnecessary for the case that the ssd is not changing
	// so we are storing an internal copy of the ssd as a comparison is much faster than a complete validation
	if ( ssd != m_prevSmoothSkinningData )
	{
		ssd->validate();
		m_prevSmoothSkinningData = ssd->copy();
	}

	// test n data
	if ( deform_n )
	{
		PrimitiveVariableMap::const_iterator it = pt->variables.find(normal_var);
		if ( it != pt->variables.end() )
		{
			if( !pt->isPrimitiveVariableValid( it->second )  )
			{
				throw Exception("Normal variable on primitive is invalid!");
			}
			if (it->second.interpolation == PrimitiveVariable::FaceVarying )
			{
				MeshPrimitive *mesh = dynamic_cast<MeshPrimitive *>( pt );
				if( !mesh )
				{
					V3fVectorData *n = pt->variableData<V3fVectorData>(normal_var);
					int n_size = n->readable().size();
					if ( p_size != n_size )
					{
						throw Exception("Position and normal variables must be the same length!");
					}
				}
			}
		}
		else
		{
			throw Exception( "Could not find normal variable on primitive!" );
		}
	}

	// generate skinning matrices
	// we are pre-creating these as in the typical use-case the number of influence objects is much lower
	// than the number of vertices that are going to be deformed
    std::vector<M44f> skin_data;
	skin_data.reserve( inf_size );

	std::vector<M44f>::const_iterator ip_it = ssd->influencePose()->readable().begin();

	for( std::vector<M44f>::const_iterator dp_it = def_data.begin();
		 dp_it!=def_data.end(); ++dp_it )
	{

		M44f mat = (*ip_it) *  (*dp_it);
		skin_data.push_back( mat );
		++ip_it;
	}

	// iterate through all the points in the source primitive and deform using the weighted skinning matrices
	if ( blend == Linear )
	{
        std::vector<V3f>::iterator p_it = p_data.begin();

	const std::vector<int> &pointIndexOffsets = ssd->pointIndexOffsets()->readable();
	const std::vector<int> &pointInfluenceCounts = ssd->pointInfluenceCounts()->readable();
	const std::vector<int> &pointInfluenceIndices = ssd->pointInfluenceIndices()->readable();
	const std::vector<float> &pointInfluenceWeights = ssd->pointInfluenceWeights()->readable();

		// todo, thread this
        // deform our P
        for ( p_it=p_data.begin(); p_it!=p_data.end(); ++p_it )
        {
			V3f p_new(0,0,0);

			int p_id = p_it - p_data.begin();

			if( refId_size )
			{
				// get the actual index to look up in the smooth skinning data
				p_id = refId_data[p_id];
			}

			int p_influence_count = pointInfluenceCounts[p_id];
			int p_index_offset = pointIndexOffsets[p_id];

			for (int p_influence_id = p_index_offset; p_influence_id < (p_index_offset+p_influence_count);
					p_influence_id++)
			{
				int influence_id = pointInfluenceIndices[p_influence_id];
				float weight = pointInfluenceWeights[p_influence_id];
				p_new += (*p_it) * skin_data[influence_id] * weight;
			}

			(*p_it) = p_new;

        }

        // deform our N
        if ( deform_n )
        {
		PrimitiveVariableMap::const_iterator it = pt->variables.find(normal_var);
		if ( it != pt->variables.end() )
		{
			V3fVectorData *n = pt->variableData<V3fVectorData>(normal_var);
			std::vector<V3f> &n_data =  n->writable();

			std::vector<V3f>::iterator n_it = n_data.begin();
			V3f n_unw;

			std::vector<int> vertexIndicesData;
			if (it->second.interpolation == PrimitiveVariable::FaceVarying )
			{
				MeshPrimitive *mesh = dynamic_cast<MeshPrimitive *>( pt );
				if( mesh )
				{
					vertexIndicesData = mesh->vertexIds()->readable();
				}
			}

			for ( n_it=n_data.begin(); n_it!=n_data.end(); ++n_it )
			{
				V3f n_new(0,0,0);

				int n_id = n_it - n_data.begin();

				if( vertexIndicesData.size() )
				{
					n_id = vertexIndicesData[n_id];
				}
				if( refId_size )
				{
					n_id = refId_data[n_id];
				}

				int n_influence_count = pointInfluenceCounts[n_id];
				int n_index_offset = pointIndexOffsets[n_id];

				for (int n_influence_id = n_index_offset; n_influence_id < (n_index_offset+n_influence_count);
						n_influence_id++)
				{
					int influence_id = pointInfluenceIndices[n_influence_id];
					float weight = pointInfluenceWeights[n_influence_id];

					skin_data[influence_id].multDirMatrix((*n_it),n_unw);
					n_new += n_unw * weight;
				}
				(*n_it) = n_new;
			}
		}
        }
	}
	else
	{
		// this should never happen
		assert(0);
	}

}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2010, 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 "boost/python.hpp"

#include "IECore/ModifyOp.h"
#include "IECore/Parameter.h"
#include "IECore/Object.h"
#include "IECore/CompoundObject.h"
#include "IECorePython/ModifyOpBinding.h"
#include "IECorePython/RunTimeTypedBinding.h"
#include "IECorePython/Wrapper.h"
#include "IECorePython/ScopedGILLock.h"

using namespace boost;
using namespace boost::python;
using namespace IECore;

namespace IECorePython
{

class ModifyOpWrap : public ModifyOp, public Wrapper<ModifyOp>
{
	public :

		ModifyOpWrap( PyObject *self, const std::string &description, ParameterPtr resultParameter, ParameterPtr inputParameter )
			: ModifyOp( description, resultParameter, inputParameter ), Wrapper<ModifyOp>( self, this )
		{
		};

		virtual void modify( Object * object, const CompoundObject * operands )
		{
			ScopedGILLock gilLock;
			this->get_override( "modify" )( ObjectPtr( object ), CompoundObjectPtr( const_cast<CompoundObject *>( operands ) ) );
		};

};

void bindModifyOp()
{
	RunTimeTypedClass<ModifyOp, ModifyOpWrap>()
		.def( init< const std::string &, ParameterPtr, ParameterPtr >() )
	;
}

} // namespace IECorePython
<commit_msg>ModifyOp Binding : Use RunTimeTypedClass and RunTimeTypedWrapper<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2010, 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 "boost/python.hpp"

#include "IECore/ModifyOp.h"
#include "IECore/Parameter.h"
#include "IECore/Object.h"
#include "IECore/CompoundObject.h"
#include "IECorePython/ModifyOpBinding.h"
#include "IECorePython/RunTimeTypedBinding.h"
#include "IECorePython/ScopedGILLock.h"

using namespace boost;
using namespace boost::python;
using namespace IECore;
using namespace IECorePython;

namespace
{

class ModifyOpWrapper : public RunTimeTypedWrapper<ModifyOp>
{
	public :

		ModifyOpWrapper( PyObject *self, const std::string &description, ParameterPtr resultParameter, ParameterPtr inputParameter )
			: RunTimeTypedWrapper<ModifyOp>( self, description, resultParameter, inputParameter )
		{
		};

		virtual void modify( Object * object, const CompoundObject * operands )
		{
			ScopedGILLock gilLock;
			this->methodOverride( "modify" )( ObjectPtr( object ), CompoundObjectPtr( const_cast<CompoundObject *>( operands ) ) );
		};

};

} // namespace

namespace IECorePython
{

void bindModifyOp()
{
	RunTimeTypedClass<ModifyOp, ModifyOpWrapper>()
		.def( init< const std::string &, ParameterPtr, ParameterPtr >() )
	;
}

} // namespace IECorePython
<|endoftext|>


<commit_before>/*
   Copyright 2012 Tzvetan Mikov <tmikov@gmail.com>
   All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef BASE_HPP
#define	BASE_HPP

#include <stdint.h>
#include <limits>
#include <cstring>
#include <stdexcept>
#include <iostream>
#include <cstdlib>
#include <errno.h>
#include <cstdarg>
#include <cstdio>
#include <cassert>

#include <string>

#include <boost/noncopyable.hpp>

#include "gc/gc_cpp.h"
#include "gc/gc_allocator.h"

#ifdef __GNUC__
  #define DEFINITION_IS_NOT_USED __attribute__ ((unused))
#else
  #define DEFINITION_IS_NOT_USED
#endif

#ifdef __GNUC__
  #ifndef __forceinline
    #define __forceinline __attribute__((__always_inline__)) inline
  #endif
  #ifndef __neverinline
    #define __neverinline __attribute__((__noinline__)) inline
  #endif
#else
    #define __forceinline inline
#endif

#if defined(_MSC_VER)
  #define COMPILE_TIME_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#elif defined(__GNUC__)
  #define COMPILE_TIME_ASSERT(e) extern char __C_ASSERT__[(e)?1:-1] __attribute__((unused))
#else
  #define COMPILE_TIME_ASSERT(e)
#endif

#if defined(__GNUC__)
  #define likely( x )   __builtin_expect( !!(x), true )
  #define unlikely( x ) __builtin_expect( !!(x), false )
#else
  #define likely( x )    x
  #define unlikely( x )  x
#endif

typedef std::basic_string<char,std::char_traits<char>, gc_allocator<char> > gc_string;

typedef char gc_char;

std::string & vappendFormatStr ( std::string & res, const char * message, std::va_list ap );
std::string & appendFormatStr ( std::string & res, const char * message, ... );

std::string vformatStr ( const char * message, std::va_list ap );
std::string formatStr ( const char * message, ... );

const gc_char * vformatGCStr ( const char * message, std::va_list ap );
const gc_char * formatGCStr ( const char * message, ... );

#endif	/* BASE_HPP */

<commit_msg>base.hpp: add container_of and AUTO_DECL<commit_after>/*
   Copyright 2012 Tzvetan Mikov <tmikov@gmail.com>
   All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef BASE_HPP
#define	BASE_HPP

#include <stdint.h>
#include <limits>
#include <cstring>
#include <stdexcept>
#include <iostream>
#include <cstdlib>
#include <errno.h>
#include <cstdarg>
#include <cstdio>
#include <cassert>

#include <string>

#include <boost/noncopyable.hpp>

#include "gc/gc_cpp.h"
#include "gc/gc_allocator.h"

#ifdef __GNUC__
  #define DEFINITION_IS_NOT_USED __attribute__ ((unused))
#else
  #define DEFINITION_IS_NOT_USED
#endif

#ifdef __GNUC__
  #ifndef __forceinline
    #define __forceinline __attribute__((__always_inline__)) inline
  #endif
  #ifndef __neverinline
    #define __neverinline __attribute__((__noinline__)) inline
  #endif
#else
    #define __forceinline inline
#endif

#if defined(_MSC_VER)
  #define COMPILE_TIME_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#elif defined(__GNUC__)
  #define COMPILE_TIME_ASSERT(e) extern char __C_ASSERT__[(e)?1:-1] __attribute__((unused))
#else
  #define COMPILE_TIME_ASSERT(e)
#endif

#if defined(__GNUC__)
  #define likely( x )   __builtin_expect( !!(x), true )
  #define unlikely( x ) __builtin_expect( !!(x), false )
#else
  #define likely( x )    x
  #define unlikely( x )  x
#endif

#define container_of( pointer, type, field ) \
  ({ const __typeof( ((type *)0)->field ) *__fptr = (pointer); \
     (type *)( (char *)__fptr - offsetof(type,field) ); })

typedef std::basic_string<char,std::char_traits<char>, gc_allocator<char> > gc_string;

typedef char gc_char;

std::string & vappendFormatStr ( std::string & res, const char * message, std::va_list ap );
std::string & appendFormatStr ( std::string & res, const char * message, ... );

std::string vformatStr ( const char * message, std::va_list ap );
std::string formatStr ( const char * message, ... );

const gc_char * vformatGCStr ( const char * message, std::va_list ap );
const gc_char * formatGCStr ( const char * message, ... );

#define AUTO_DECL( name, value )  __typeof(value) name = (value)

#endif	/* BASE_HPP */

<|endoftext|>


<commit_before>// $Id$
//***************************************************************************
// File:
//	Sparc.cpp
//
// Purpose:
//
// History:
//	7/15/01	 -  Vikram Adve  -  Created
//**************************************************************************/

#include "llvm/Target/Sparc.h"
#include "SparcInternals.h"
#include "llvm/Method.h"
#include "llvm/CodeGen/InstrScheduling.h"
#include "llvm/CodeGen/InstrSelection.h"

#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
#include "llvm/CodeGen/PhyRegAlloc.h"

// Build the MachineInstruction Description Array...
const MachineInstrDescriptor SparcMachineInstrDesc[] = {
#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
          NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS)             \
  { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE,             \
          NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS },
#include "SparcInstr.def"
};

//----------------------------------------------------------------------------
// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
//----------------------------------------------------------------------------
//

TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }

//----------------------------------------------------------------------------
// Entry point for register allocation for a module
//----------------------------------------------------------------------------

void AllocateRegisters(Method *M, TargetMachine &TM)
{

  if ( (M)->isExternal() )     // don't process prototypes
    return;

  if( DEBUG_RA ) {
    cerr << endl << "******************** Method "<< (M)->getName();
    cerr <<        " ********************" <<endl;
  }

  MethodLiveVarInfo LVI(M );   // Analyze live varaibles
  LVI.analyze();

  PhyRegAlloc PRA(M, TM , &LVI); // allocate registers
  PRA.allocateRegisters();

  if( DEBUG_RA )  cerr << endl << "Register allocation complete!" << endl;

}

//---------------------------------------------------------------------------
// class UltraSparcInstrInfo
//
// Purpose:
//   Information about individual instructions.
//   Most information is stored in the SparcMachineInstrDesc array above.
//   Other information is computed on demand, and most such functions
//   default to member functions in base class MachineInstrInfo.
//---------------------------------------------------------------------------

/*ctor*/
UltraSparcInstrInfo::UltraSparcInstrInfo()
  : MachineInstrInfo(SparcMachineInstrDesc,
		     /*descSize = */ NUM_TOTAL_OPCODES,
		     /*numRealOpCodes = */ NUM_REAL_OPCODES)
{
}

//---------------------------------------------------------------------------
// class UltraSparcSchedInfo
//
// Purpose:
//   Scheduling information for the UltraSPARC.
//   Primarily just initializes machine-dependent parameters in
//   class MachineSchedInfo.
//---------------------------------------------------------------------------

/*ctor*/
UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
  : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
		     mii,
		     SparcRUsageDesc,
		     SparcInstrUsageDeltas,
		     SparcInstrIssueDeltas,
		     sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
		     sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
{
  maxNumIssueTotal = 4;
  longestIssueConflict = 0;		// computed from issuesGaps[]

  branchMispredictPenalty = 4;		// 4 for SPARC IIi
  branchTargetUnknownPenalty = 2;	// 2 for SPARC IIi
  l1DCacheMissPenalty = 8;		// 7 or 9 for SPARC IIi
  l1ICacheMissPenalty = 8;		// ? for SPARC IIi

  inOrderLoads = true;			// true for SPARC IIi
  inOrderIssue = true;			// true for SPARC IIi
  inOrderExec  = false;			// false for most architectures
  inOrderRetire= true;			// true for most architectures

  // must be called after above parameters are initialized.
  this->initializeResources();
}

void
UltraSparcSchedInfo::initializeResources()
{
  // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
  MachineSchedInfo::initializeResources();

  // Machine-dependent fixups go here.  None for now.
}

//---------------------------------------------------------------------------
// class UltraSparcMachine
//
// Purpose:
//   Primary interface to machine description for the UltraSPARC.
//   Primarily just initializes machine-dependent parameters in
//   class TargetMachine, and creates machine-dependent subclasses
//   for classes such as MachineInstrInfo.
//
//---------------------------------------------------------------------------

UltraSparc::UltraSparc()
  : TargetMachine("UltraSparc-Native"),
    instrInfo(),
    schedInfo(&instrInfo),
    regInfo( this )
{
  optSizeForSubWordData = 4;
  minMemOpWordSize = 8;
  maxAtomicMemOpWordSize = 8;
}

bool UltraSparc::compileMethod(Method *M) {

  if (SelectInstructionsForMethod(M, *this))
    {
      cerr << "Instruction selection failed for method " << M->getName()
	   << "\n\n";
      return true;
    }

  if (ScheduleInstructionsWithSSA(M, *this))
    {
      cerr << "Instruction scheduling before allocation failed for method "
	   << M->getName() << "\n\n";
      return true;
    }

  AllocateRegisters(M, *this);    // allocate registers

  return false;
}

<commit_msg>Moved implementation of class UltraSparcInstrInfo to SparcInstrInfo.cpp.<commit_after>// $Id$
//***************************************************************************
// File:
//	Sparc.cpp
//
// Purpose:
//
// History:
//	7/15/01	 -  Vikram Adve  -  Created
//**************************************************************************/

#include "llvm/Target/Sparc.h"
#include "SparcInternals.h"
#include "llvm/Method.h"
#include "llvm/CodeGen/InstrScheduling.h"
#include "llvm/CodeGen/InstrSelection.h"

#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
#include "llvm/CodeGen/PhyRegAlloc.h"

// Build the MachineInstruction Description Array...
const MachineInstrDescriptor SparcMachineInstrDesc[] = {
#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
          NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS)             \
  { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE,             \
          NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS },
#include "SparcInstr.def"
};

//----------------------------------------------------------------------------
// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
//----------------------------------------------------------------------------
//

TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }

//----------------------------------------------------------------------------
// Entry point for register allocation for a module
//----------------------------------------------------------------------------

void AllocateRegisters(Method *M, TargetMachine &TM)
{

  if ( (M)->isExternal() )     // don't process prototypes
    return;

  if( DEBUG_RA ) {
    cerr << endl << "******************** Method "<< (M)->getName();
    cerr <<        " ********************" <<endl;
  }

  MethodLiveVarInfo LVI(M );   // Analyze live varaibles
  LVI.analyze();

  PhyRegAlloc PRA(M, TM , &LVI); // allocate registers
  PRA.allocateRegisters();

  if( DEBUG_RA )  cerr << endl << "Register allocation complete!" << endl;

}

//---------------------------------------------------------------------------
// class UltraSparcSchedInfo
//
// Purpose:
//   Scheduling information for the UltraSPARC.
//   Primarily just initializes machine-dependent parameters in
//   class MachineSchedInfo.
//---------------------------------------------------------------------------

/*ctor*/
UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
  : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
		     mii,
		     SparcRUsageDesc,
		     SparcInstrUsageDeltas,
		     SparcInstrIssueDeltas,
		     sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
		     sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
{
  maxNumIssueTotal = 4;
  longestIssueConflict = 0;		// computed from issuesGaps[]

  branchMispredictPenalty = 4;		// 4 for SPARC IIi
  branchTargetUnknownPenalty = 2;	// 2 for SPARC IIi
  l1DCacheMissPenalty = 8;		// 7 or 9 for SPARC IIi
  l1ICacheMissPenalty = 8;		// ? for SPARC IIi

  inOrderLoads = true;			// true for SPARC IIi
  inOrderIssue = true;			// true for SPARC IIi
  inOrderExec  = false;			// false for most architectures
  inOrderRetire= true;			// true for most architectures

  // must be called after above parameters are initialized.
  this->initializeResources();
}

void
UltraSparcSchedInfo::initializeResources()
{
  // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
  MachineSchedInfo::initializeResources();

  // Machine-dependent fixups go here.  None for now.
}

//---------------------------------------------------------------------------
// class UltraSparcMachine
//
// Purpose:
//   Primary interface to machine description for the UltraSPARC.
//   Primarily just initializes machine-dependent parameters in
//   class TargetMachine, and creates machine-dependent subclasses
//   for classes such as MachineInstrInfo.
//
//---------------------------------------------------------------------------

UltraSparc::UltraSparc()
  : TargetMachine("UltraSparc-Native"),
    instrInfo(),
    schedInfo(&instrInfo),
    regInfo( this )
{
  optSizeForSubWordData = 4;
  minMemOpWordSize = 8;
  maxAtomicMemOpWordSize = 8;
}

bool UltraSparc::compileMethod(Method *M) {

  if (SelectInstructionsForMethod(M, *this))
    {
      cerr << "Instruction selection failed for method " << M->getName()
	   << "\n\n";
      return true;
    }

  if (ScheduleInstructionsWithSSA(M, *this))
    {
      cerr << "Instruction scheduling before allocation failed for method "
	   << M->getName() << "\n\n";
      return true;
    }

  AllocateRegisters(M, *this);    // allocate registers

  return false;
}

<|endoftext|>


<commit_before>#ifndef VEXCL_TYPES_HPP
#define VEXCL_TYPES_HPP

/*
The MIT License

Copyright (c) 2012-2013 Denis Demidov <ddemidov@ksu.ru>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   types.hpp
 * \author Pascal Germroth <pascal@ensieve.org>
 * \brief  C++ sugar for OpenCL vector types, eg. cl::float4, operator+.
 */

namespace vex {

    /// Get the corresponding scalar type for a CL vector (or scalar) type.
    /** \code cl_scalar_of<cl_float4>::type == cl_float \endcode */
    template <class T>
    struct cl_scalar_of {};

    /// Get the corresponding vector type for a CL scalar type.
    /** \code cl_vector_of<cl_float, 4>::type == cl_float4 \endcode */
    template <class T, int dim>
    struct cl_vector_of {};

} // namespace vex

#define BIN_OP(base_type, len, op) \
cl_##base_type##len &operator op##= (cl_##base_type##len &a, const cl_##base_type##len &b) { \
    for(size_t i = 0 ; i < len ; i++) a.s[i] op##= b.s[i]; \
    return a; \
} \
cl_##base_type##len operator op(const cl_##base_type##len &a, const cl_##base_type##len &b) { \
    cl_##base_type##len res = a; return res op##= b; \
}

// `scalar OP vector` acts like `(vector_t)(scalar) OP vector` in OpenCl:
// all components are set to the scalar value.
#define BIN_SCALAR_OP(base_type, len, op) \
cl_##base_type##len &operator op##= (cl_##base_type##len &a, const cl_##base_type &b) { \
    for(size_t i = 0 ; i < len ; i++) a.s[i] op##= b; \
    return a; \
} \
cl_##base_type##len operator op(const cl_##base_type##len &a, const cl_##base_type &b) { \
    cl_##base_type##len res = a; return res op##= b; \
} \
cl_##base_type##len operator op(const cl_##base_type &a, const cl_##base_type##len &b) { \
    cl_##base_type##len res = b; return res op##= a; \
}

#define CL_VEC_TYPE(base_type, len) \
BIN_OP(base_type, len, +) \
BIN_OP(base_type, len, -) \
BIN_OP(base_type, len, *) \
BIN_OP(base_type, len, /) \
BIN_SCALAR_OP(base_type, len, +) \
BIN_SCALAR_OP(base_type, len, -) \
BIN_SCALAR_OP(base_type, len, *) \
BIN_SCALAR_OP(base_type, len, /) \
cl_##base_type##len operator -(const cl_##base_type##len &a) { \
    cl_##base_type##len res; \
    for(size_t i = 0 ; i < len ; i++) res.s[i] = -a.s[i]; \
    return res; \
} \
std::ostream &operator<<(std::ostream &os, const cl_##base_type##len &value) { \
    os << "(" #base_type #len ")("; \
    for(std::size_t i = 0 ; i < len ; i++) { \
        if(i != 0) os << ','; \
        os << value.s[i]; \
    } \
    return os << ')'; \
} \
namespace vex { \
    template <> struct cl_scalar_of<cl_##base_type##len> { typedef cl_##base_type type; }; \
    template <> struct cl_vector_of<cl_##base_type, len> { typedef cl_##base_type##len type; }; \
}

#define CL_TYPES(base_type) \
CL_VEC_TYPE(base_type, 2); \
CL_VEC_TYPE(base_type, 4); \
CL_VEC_TYPE(base_type, 8); \
CL_VEC_TYPE(base_type, 16); \
namespace vex { \
    template <> struct cl_scalar_of<cl_##base_type> { typedef cl_##base_type type; }; \
}

CL_TYPES(float);
CL_TYPES(double);
CL_TYPES(char);  CL_TYPES(uchar);
CL_TYPES(short); CL_TYPES(ushort);
CL_TYPES(int);   CL_TYPES(uint);
CL_TYPES(long);  CL_TYPES(ulong);

#undef BIN_OP
#undef CL_VEC_TYPE
#undef CL_TYPES

#endif
<commit_msg>Add cl_vector_length trait.<commit_after>#ifndef VEXCL_TYPES_HPP
#define VEXCL_TYPES_HPP

/*
The MIT License

Copyright (c) 2012-2013 Denis Demidov <ddemidov@ksu.ru>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   types.hpp
 * \author Pascal Germroth <pascal@ensieve.org>
 * \brief  C++ sugar for OpenCL vector types, eg. cl_float4, operator+.
 */

namespace vex {

    /// Get the corresponding scalar type for a CL vector (or scalar) type.
    /** \code cl_scalar_of<cl_float4>::type == cl_float \endcode */
    template <class T>
    struct cl_scalar_of {};

    /// Get the corresponding vector type for a CL scalar type.
    /** \code cl_vector_of<cl_float, 4>::type == cl_float4 \endcode */
    template <class T, int dim>
    struct cl_vector_of {};

    /// Get the number of values in a CL vector (or scalar) type.
    /** \code cl_vector_length<cl_float4>::value == 4 \endcode */
    template <class T>
    struct cl_vector_length {};

} // namespace vex

#define BIN_OP(base_type, len, op) \
cl_##base_type##len &operator op##= (cl_##base_type##len &a, const cl_##base_type##len &b) { \
    for(size_t i = 0 ; i < len ; i++) a.s[i] op##= b.s[i]; \
    return a; \
} \
cl_##base_type##len operator op(const cl_##base_type##len &a, const cl_##base_type##len &b) { \
    cl_##base_type##len res = a; return res op##= b; \
}

// `scalar OP vector` acts like `(vector_t)(scalar) OP vector` in OpenCl:
// all components are set to the scalar value.
#define BIN_SCALAR_OP(base_type, len, op) \
cl_##base_type##len &operator op##= (cl_##base_type##len &a, const cl_##base_type &b) { \
    for(size_t i = 0 ; i < len ; i++) a.s[i] op##= b; \
    return a; \
} \
cl_##base_type##len operator op(const cl_##base_type##len &a, const cl_##base_type &b) { \
    cl_##base_type##len res = a; return res op##= b; \
} \
cl_##base_type##len operator op(const cl_##base_type &a, const cl_##base_type##len &b) { \
    cl_##base_type##len res = b; return res op##= a; \
}

#define CL_VEC_TYPE(base_type, len) \
BIN_OP(base_type, len, +) \
BIN_OP(base_type, len, -) \
BIN_OP(base_type, len, *) \
BIN_OP(base_type, len, /) \
BIN_SCALAR_OP(base_type, len, +) \
BIN_SCALAR_OP(base_type, len, -) \
BIN_SCALAR_OP(base_type, len, *) \
BIN_SCALAR_OP(base_type, len, /) \
cl_##base_type##len operator -(const cl_##base_type##len &a) { \
    cl_##base_type##len res; \
    for(size_t i = 0 ; i < len ; i++) res.s[i] = -a.s[i]; \
    return res; \
} \
std::ostream &operator<<(std::ostream &os, const cl_##base_type##len &value) { \
    os << "(" #base_type #len ")("; \
    for(std::size_t i = 0 ; i < len ; i++) { \
        if(i != 0) os << ','; \
        os << value.s[i]; \
    } \
    return os << ')'; \
} \
namespace vex { \
    template <> struct cl_scalar_of<cl_##base_type##len> { typedef cl_##base_type type; }; \
    template <> struct cl_vector_of<cl_##base_type, len> { typedef cl_##base_type##len type; }; \
    template <> struct cl_vector_length<cl_##base_type##len> { enum { value = len }; }; \
}

#define CL_TYPES(base_type) \
CL_VEC_TYPE(base_type, 2); \
CL_VEC_TYPE(base_type, 4); \
CL_VEC_TYPE(base_type, 8); \
CL_VEC_TYPE(base_type, 16); \
namespace vex { \
    template <> struct cl_scalar_of<cl_##base_type> { typedef cl_##base_type type; }; \
    template <> struct cl_vector_of<cl_##base_type, 1> { typedef cl_##base_type type; }; \
    template <> struct cl_vector_length<cl_##base_type> { enum { value = 1 }; }; \
}

CL_TYPES(float);
CL_TYPES(double);
CL_TYPES(char);  CL_TYPES(uchar);
CL_TYPES(short); CL_TYPES(ushort);
CL_TYPES(int);   CL_TYPES(uint);
CL_TYPES(long);  CL_TYPES(ulong);

#undef BIN_OP
#undef CL_VEC_TYPE
#undef CL_TYPES

#endif
<|endoftext|>


<commit_before>#include "RakPeerInterface.h"
#include "MessageIdentifiers.h"
#include "BitStream.h"
#include "RakNetTypes.h"  // MessageID
#include "packetids.h"
#include <stdio.h>
#include <string.h>

#define PORT 3999
#define MAX_CLIENTS 25

enum PlayerState {
    NONEXISTENT, EXISTENCE_ACKNOWLEDGED,
    AWAITING_CLIENT, PLAYING
};

struct PlayerStatus {
    PlayerState state;
    RakNet::SystemIndex index;
};

int main(int argc, char** argv) {
    PlayerStatus players[100];
    uint32_t colors[] = {
        0xFFFF9900, 0xFF00FF00, 0xFF007BFF, 0xFFFF5EB4, 0xFFFF6100,
        0xFF6F8927, 0xFF323987, 0xFF70374A, 0xFF375B37, 0xFF0000FF
    };

	RakNet::RakPeerInterface* peer = RakNet::RakPeerInterface::GetInstance();
	peer->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS);

    RakNet::Packet* packet;

    {
        RakNet::SocketDescriptor descriptor(PORT, NULL);
        peer->Startup(MAX_CLIENTS, &descriptor, 1);
    }
    peer->SetMaximumIncomingConnections(MAX_CLIENTS);

    printf("up we go!\n");

    while (true) {
        for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive()) {
            switch (packet->data[0]) {
            case ID_REMOTE_DISCONNECTION_NOTIFICATION:
                printf("Another client has disconnected.\n");
                break;
            case ID_REMOTE_CONNECTION_LOST:
                printf("Another client has lost the connection.\n");
                break;
            case ID_REMOTE_NEW_INCOMING_CONNECTION:
                printf("Another client has connected.\n");
                break;
            case ID_CONNECTION_REQUEST_ACCEPTED:
                printf("Our connection request has been accepted.\n");
                break;
            case ID_NEW_INCOMING_CONNECTION:
                printf("A connection is incoming. Index: %i\n", packet->systemAddress.systemIndex);
                players[packet->systemAddress.systemIndex].state = EXISTENCE_ACKNOWLEDGED;
                break;
            case ID_NO_FREE_INCOMING_CONNECTIONS:
                printf("The server is full.\n");
                break;
            case ID_DISCONNECTION_NOTIFICATION:
                printf("A client has disconnected.\n");
                break;
            case ID_CONNECTION_LOST:
                printf("A client lost the connection.\n");
                players[packet->systemAddress.systemIndex].state = NONEXISTENT;
                break;

            case ID_NEW_HOST: {
                uint32_t color = colors[rand() % (sizeof(colors) / sizeof(uint32_t))];
                printf("Dis guy want a color! %s index: %i, sending %x\n", packet->systemAddress.ToString(true, ':'), packet->systemAddress.systemIndex, color);

                RakNet::BitStream color_resp;

                color_resp.Write((RakNet::MessageID)ID_ASSIGNED_COLOR);
                color_resp.Write(color);
                color_resp.Write(packet->systemAddress.systemIndex);

                peer->Send(&color_resp, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);

                players[packet->systemAddress.systemIndex].index = packet->systemAddress.systemIndex;
                players[packet->systemAddress.systemIndex].state = AWAITING_CLIENT;
            } break;

            default:
                printf("Message with identifier %i has arrived.\n", packet->data[0]);
                break;
            }
        }
    }

    return 0;
}<commit_msg>multiplayer games can be hosted and joined!<commit_after>#include "RakPeerInterface.h"
#include "MessageIdentifiers.h"
#include "BitStream.h"
#include "RakNetTypes.h"  // MessageID
#include "packetids.h"
#include <stdio.h>
#include <string.h>

#define PORT 3999
#define MAX_CLIENTS 25

enum PlayerState {
    NONEXISTENT, EXISTENCE_ACKNOWLEDGED,
    AWAITING_CLIENT, ABOUT_TO_PLAY, PLAYING
};

struct PlayerStatus {
    PlayerState state;
    RakNet::SystemIndex index;
    RakNet::SystemIndex playing_with_index;
    RakNet::SystemAddress addr;
    uint32_t color;
};

int main(int argc, char** argv) {
    PlayerStatus players[100];
    uint32_t colors[] = {
        0xFFFF9900, 0xFF00FF00, 0xFF007BFF, 0xFFFF5EB4, 0xFFFF6100,
        0xFF6F8927, 0xFF323987, 0xFF70374A, 0xFF375B37, 0xFF0000FF
    };
    // So that we don't loop through the entire list.
    int highest_index = 0;

	RakNet::RakPeerInterface* peer = RakNet::RakPeerInterface::GetInstance();
	peer->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS);

    RakNet::Packet* packet;

    {
        RakNet::SocketDescriptor descriptor(PORT, NULL);
        peer->Startup(MAX_CLIENTS, &descriptor, 1);
    }
    peer->SetMaximumIncomingConnections(MAX_CLIENTS);

    printf("up we go!\n");

    while (true) {
        for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive()) {
            switch (packet->data[0]) {
            case ID_REMOTE_DISCONNECTION_NOTIFICATION:
                printf("Another client has disconnected.\n");
                break;
            case ID_REMOTE_CONNECTION_LOST:
                printf("Another client has lost the connection.\n");
                break;
            case ID_REMOTE_NEW_INCOMING_CONNECTION:
                printf("Another client has connected.\n");
                break;
            case ID_CONNECTION_REQUEST_ACCEPTED:
                printf("Our connection request has been accepted.\n");
                break;
            case ID_NEW_INCOMING_CONNECTION:
                printf("A connection is incoming. Index: %i\n", packet->systemAddress.systemIndex);
                players[packet->systemAddress.systemIndex].state = EXISTENCE_ACKNOWLEDGED;
                players[packet->systemAddress.systemIndex].addr = packet->systemAddress;
                if (packet->systemAddress.systemIndex > highest_index)
                    highest_index = packet->systemAddress.systemIndex;
                break;
            case ID_NO_FREE_INCOMING_CONNECTIONS:
                printf("The server is full.\n");
                break;
            case ID_DISCONNECTION_NOTIFICATION:
                printf("Player %i has disconnected.\n", packet->systemAddress.systemIndex);
                break;
            case ID_CONNECTION_LOST:
                printf("Player %i lost the connection.\n", packet->systemAddress.systemIndex);
                players[packet->systemAddress.systemIndex].state = NONEXISTENT;
                break;

            // Sent by a player planning to host a game.
            case ID_NEW_HOST: {
                uint32_t color = colors[rand() % (sizeof(colors) / sizeof(uint32_t))];
                printf("Dis guy want a color! %s index: %i, sending %x\n", packet->systemAddress.ToString(true, ':'), packet->systemAddress.systemIndex, color);

                RakNet::BitStream color_resp;

                color_resp.Write((RakNet::MessageID)ID_ASSIGNED_COLOR);
                color_resp.Write(color);
                color_resp.Write(packet->systemAddress.systemIndex);

                peer->Send(&color_resp, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);

                players[packet->systemAddress.systemIndex].index = packet->systemAddress.systemIndex;
                players[packet->systemAddress.systemIndex].color = color;
                players[packet->systemAddress.systemIndex].state = AWAITING_CLIENT;
            } break;

            // Sent by a player who needs the host list so they know who they can join.
            case ID_QUERY_HOSTS: {
                RakNet::BitStream resp;
                resp.Write((RakNet::MessageID)ID_HOST_LIST);

                int indices[100];
                uint32_t size = 0;

                for (int i = 0; i <= highest_index; i++) {
                    if (players[i].state == AWAITING_CLIENT) {
                        indices[size] = i;
                        size += 1;
                    }
                }

                resp.Write(size);

                for (int i = 0; i < size; i++) {
                    PlayerStatus* player = &players[indices[i]];
                    resp.Write(player->index);
                    resp.Write(player->color);
                }

                printf("Sending host list of %i players to player %i\n", size, packet->systemAddress.systemIndex);

                peer->Send(&resp, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
            } break;

            // Sent by a player who just decided to join a host's game.
            case ID_JOIN_GAME: {
                RakNet::BitStream req(packet->data, packet->length, false);
                req.IgnoreBytes(sizeof(RakNet::MessageID));

                RakNet::SystemIndex requested_index;
                if (!req.Read((char*)&requested_index, sizeof(RakNet::SystemIndex))) {
                    printf("Something went wrong reading player %i's requested host to join!\n", packet->systemAddress.systemIndex);
                    break;
                }
                requested_index = ntohs(requested_index);

                players[requested_index].state = ABOUT_TO_PLAY;
                players[requested_index].playing_with_index = packet->systemAddress.systemIndex;
                players[packet->systemAddress.systemIndex].state = ABOUT_TO_PLAY;
                players[packet->systemAddress.systemIndex].playing_with_index = requested_index;

                // We send HOST_STILL_GOOD because the host may have disconnected by the time someone attempts to join them.
                RakNet::BitStream resp;
                resp.Write((RakNet::MessageID)ID_HOST_STILL_GOOD);

                peer->Send(&resp, HIGH_PRIORITY, RELIABLE_ORDERED, 0, players[requested_index].addr, false);

                printf("Player %i joined player %i\n", packet->systemAddress.systemIndex, requested_index);

            } break;

            // Comes from hosts after receiving ID_HOST_STILL_GOOD to indicate that the game shall start.
            case ID_READY_TO_ROLL: {
                PlayerStatus* player1 = &players[packet->systemAddress.systemIndex];
                PlayerStatus* player2 = &players[player1->playing_with_index];

                RakNet::BitStream resp;
                resp.Write((RakNet::MessageID)ID_READY_TO_ROLL);

                player1->state = PLAYING;
                player2->state = PLAYING;

                peer->Send(&resp, HIGH_PRIORITY, RELIABLE_ORDERED, 0, player1->addr, false);
                resp.ResetReadPointer();
                peer->Send(&resp, HIGH_PRIORITY, RELIABLE_ORDERED, 0, player2->addr, false);

                printf("Ready to roll!\n");
            } break;

            default:
                printf("Message with identifier %i has arrived.\n", packet->data[0]);
                break;
            }
        }
    }

    return 0;
}<|endoftext|>


<commit_before>#include <sofa/core/ObjectFactory.h>
#include <sofa/helper/system/PluginManager.h>
#include <sofa/component/init.h>
#ifdef SOFA_DEV
#include <sofa/component/initDev.h>
#endif
#include <sofa/helper/vector.h>

#include <sofa/helper/ArgumentParser.h>
#include <sofa/core/objectmodel/BaseClass.h>
#include <sofa/helper/system/SetDirectory.h>

#include <iostream>
#include <algorithm>

namespace
{
const std::string authors(
    "\
/******************************************************************************\n\
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *\n\
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *\n\
*                                                                             *\n\
* This library is free software; you can redistribute it and/or modify it     *\n\
* under the terms of the GNU Lesser General Public License as published by    *\n\
* the Free Software Foundation; either version 2.1 of the License, or (at     *\n\
* your option) any later version.                                             *\n\
*                                                                             *\n\
* This library is distributed in the hope that it will be useful, but WITHOUT *\n\
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *\n\
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *\n\
* for more details.                                                           *\n\
*                                                                             *\n\
* You should have received a copy of the GNU Lesser General Public License    *\n\
* along with this library; if not, write to the Free Software Foundation,     *\n\
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *\n\
*******************************************************************************\n\
*                               SOFA :: Modules                               *\n\
*                                                                             *\n\
* Authors: The SOFA Team and external contributors (see Authors.txt)          *\n\
*                                                                             *\n\
* Contact information: contact@sofa-framework.org                             *\n\
******************************************************************************/\n\
\n\n\n\
// File automatically generated by \"generateTypedef\"\n\n\
\n"		);
const std::string defaultIncludes(
    "\
//Default files containing the declaration of the vector type\n\
#include <sofa/defaulttype/VecTypes.h>\n\
#include <sofa/defaulttype/RigidTypes.h>\n\
#include <sofa/defaulttype/Mat.h>\n\n\
\n\
#ifdef SOFA_GPU_CUDA\n\
#include <sofa/gpu/cuda/CudaTypesBase.h>\n\
#include <sofa/gpu/cuda/CudaTypes.h>\n\
#endif\n\
#ifdef SOFA_GPU_OPENCL\n\
#include <sofa/gpu/opencl/OpenCLTypes.h>\n\
#endif\n");
    }

    using namespace sofa;
    using namespace sofa::core;
    using namespace sofa::helper::system;

    int main(int argc, char** argv)
    {

    std::vector<std::string> plugins;
    std::vector<std::string> targets;
    sofa::helper::parse("This application generate header files for each SOFA binary.\n\
    Each header file contains includes to the SOFA components belonging to the binary.\n\
    A glorious Sofa.h header is also created which contains includes to all the other headers generated\n\
    by this application.\n\
    Headers are created in $SOFA_DIR/modules/sofa")
    .option(&plugins,'l',"load","load given plugins")
    .option(&targets,'t',"targets","generate typedefs for the given targets only")
        (argc,argv);

        sofa::component::init();
#ifdef SOFA_DEV
        sofa::component::initDev();
#endif
        for (unsigned int i=0; i<plugins.size(); i++)
        sofa::helper::system::PluginManager::getInstance().loadPlugin(plugins[i]);

        sofa::helper::system::PluginManager::getInstance().initRecentlyOpened();
        sofa::helper::system::PluginManager::getInstance().init();

        helper::vector<ObjectFactory::ClassEntry*> registry;
        helper::vector<ObjectFactory::ClassEntry*>::iterator it;

        //std::string outputPath = SetDirectory::GetRelativeFromProcess("../modules/sofa/");
        std::string outputPath = "/modules/sofa/";

        std::string fullPath = SetDirectory::GetParentDir(SetDirectory::GetParentDir(SetDirectory::GetProcessFullPath("").c_str()).c_str());
        int absoluteBasePathSize = fullPath.length();

        // retrieve creators

        typedef std::map< std::string, helper::vector< ObjectFactory::CreatorList::value_type >  > TargetCreatorMap;
        typedef std::map< std::string, helper::vector< ObjectFactory::ClassEntry* >  > TargetClassEntryMap;
        TargetCreatorMap targetCreatorMap;
        TargetClassEntryMap targetClassEntryMap;

        sofa::core::ObjectFactory::getInstance()->getAllEntries(registry);

        for( it = registry.begin(); it != registry.end(); ++it)
    {
        ObjectFactory::ClassEntry* entry = *it;
        ObjectFactory::CreatorList::iterator itc;
        itc = entry->creatorList.begin();
        if( itc != entry->creatorList.end() )
    {
        targetClassEntryMap[itc->second->getTarget()].push_back(entry);
    }

        for(itc = entry->creatorList.begin(); itc != entry->creatorList.end(); ++itc )
    {
        ObjectFactory::Creator* creator = itc->second;
        targetCreatorMap[creator->getTarget()].push_back(*itc);
    }
    }

        std::ostringstream timestamp;
        timestamp << std::string("/*") << std::endl
<< "GENERATED THE " << std::string(__DATE__) << " AT " << std::string(__TIME__) << std::endl
<< std::string("*/\n")
        ;

        // generate target headers

        for( TargetCreatorMap::iterator it_target = targetCreatorMap.begin(); it_target != targetCreatorMap.end(); ++it_target)
    {
        std::ostringstream target_h_location,target_h_guarding_block;
        target_h_location << fullPath << outputPath << it_target->first << ".h";
        std::ofstream target_h(target_h_location.str().c_str());
    {
        std::string target_name(it_target->first);
        std::transform(target_name.begin(),target_name.end(),target_name.begin(),::toupper);
        target_h_guarding_block << "#ifndef " << target_name << "_H" << std::endl;
        target_h_guarding_block << "#define " << target_name << "_H" << std::endl;
    }

        target_h << target_h_guarding_block.str();
        target_h << timestamp.str();
        target_h << authors;
        target_h << defaultIncludes;

        helper::vector< ObjectFactory::CreatorList::value_type > targetCreatorList = it_target->second;
        helper::vector< ObjectFactory::CreatorList::value_type >::iterator it_creatorlist;
        std::pair<TargetClassEntryMap::iterator,TargetClassEntryMap::iterator> range = targetClassEntryMap.equal_range(it_target->first);
        TargetClassEntryMap::iterator it_vecEntry;
        for(it_vecEntry = range.first; it_vecEntry != range.second; ++it_vecEntry)
    {
        helper::vector< ObjectFactory::ClassEntry*> &  vecEntry = it_vecEntry->second;
        helper::vector< ObjectFactory::ClassEntry*>::iterator it_entry;
        for(it_entry = vecEntry.begin(); it_entry != vecEntry.end(); ++it_entry)
    {
        ObjectFactory::ClassEntry* entry = *it_entry;
        if( entry->creatorList.begin() != entry->creatorList.end() )
    {
        ObjectFactory::Creator* creator = entry->creatorList.begin()->second;
        std::string includePath = std::string(creator->getHeaderFileLocation()).substr(absoluteBasePathSize + outputPath.length());
        target_h << "#include <" << includePath << ">" << std::endl;
    }
    }
    }

        target_h << std::endl;

        for(it_creatorlist = targetCreatorList.begin(); it_creatorlist != targetCreatorList.end(); ++it_creatorlist)
    {
        ObjectFactory::Creator* creator = it_creatorlist->second;
        std::string templateName = creator->getClass()->templateName;

    {
        std::string::iterator itEnd;

        itEnd = std::remove(templateName.begin(),templateName.end(),'[');
        templateName.erase(itEnd, templateName.end());

        itEnd = std::remove(templateName.begin(),templateName.end(),']');
        templateName.erase(itEnd, templateName.end());
    }

        std::replace(templateName.begin(),templateName.end(),',','_');
        std::replace(templateName.begin(),templateName.end(),' ','_');
        std::replace(templateName.begin(),templateName.end(),'<','_');
        std::replace(templateName.begin(),templateName.end(),'>','_');

        // trim right underscores
    {
        for(unsigned size = templateName.size(); size != 0; --size)
    {
        if('_' != templateName[size - 1])
    {
        if(templateName.size() != size)
        templateName.resize(size);

        break;
    }
    }
    }

        const std::type_info& type = creator->type();

        size_t curPos = 0;
        size_t oldPos = 0;
        std::string namespaceName = creator->getClass()->namespaceName;
        size_t bracketCount = 0;
        helper::vector<std::string> namespaces;
        while( ( curPos = namespaceName.find(std::string("::"),oldPos) ) != std::string::npos)
    {
        std::string currentNamespace = namespaceName.substr(oldPos,curPos-oldPos);
        namespaces.push_back(currentNamespace);
        oldPos = curPos+2;
        ++bracketCount;
    }
        namespaces.push_back(namespaceName.substr(oldPos));
        helper::vector<std::string>::iterator it_namespace;
        for(it_namespace = namespaces.begin(); it_namespace != namespaces.end(); ++it_namespace)
    {
        target_h << "namespace " << *it_namespace << std::endl;
    target_h << "{" << std::endl;
}

    if(!templateName.empty())
{
    target_h << "typedef " <<  sofa::core::objectmodel::BaseClass::decodeFullName(type)
    << " " << creator->getClass()->className << "_" << templateName << ";";
}
    else
{
    target_h << "typedef " <<  sofa::core::objectmodel::BaseClass::decodeFullName(type)
    << " " << creator->getClass()->className << ";";
}
    target_h << std::endl;
    for( size_t i=0; i<namespaces.size(); ++i)
{
    target_h << "}" << std::endl;
}

target_h << std::endl;
}
target_h << "#endif " << std::endl;
target_h.close();
}

// generate sofa.h header

std::string sofa_name("sofa");
std::ostringstream sofa_h_location,sofa_h_guarding_block;
sofa_h_location << fullPath << outputPath << sofa_name << ".h";
std::ofstream sofa_h(sofa_h_location.str().c_str());
{
std::transform(sofa_name.begin(),sofa_name.end(),sofa_name.begin(),::toupper);
sofa_h_guarding_block << "#ifndef " << sofa_name << "_H" << std::endl;
sofa_h_guarding_block << "#define " << sofa_name << "_H" << std::endl;
}

sofa_h << sofa_h_guarding_block.str();
sofa_h << timestamp.str();
sofa_h << authors << std::endl;

for( TargetCreatorMap::iterator it_target = targetCreatorMap.begin(); it_target != targetCreatorMap.end(); ++it_target)
{
std::ostringstream target_h_location;
target_h_location << it_target->first << ".h";

sofa_h << "#include <" << target_h_location.str().c_str() << ">" << std::endl;
}

sofa_h << std::endl << "#endif " << std::endl;
sofa_h.close();
}
<commit_msg>r12214/sofa-dev : FIX: incorrect include paths<commit_after>#include <sofa/core/ObjectFactory.h>
#include <sofa/helper/system/PluginManager.h>
#include <sofa/component/init.h>
#ifdef SOFA_DEV
#include <sofa/component/initDev.h>
#endif
#include <sofa/helper/vector.h>

#include <sofa/helper/ArgumentParser.h>
#include <sofa/core/objectmodel/BaseClass.h>
#include <sofa/helper/system/SetDirectory.h>

#include <iostream>
#include <algorithm>

namespace
{
const std::string authors(
    "\
/******************************************************************************\n\
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *\n\
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *\n\
*                                                                             *\n\
* This library is free software; you can redistribute it and/or modify it     *\n\
* under the terms of the GNU Lesser General Public License as published by    *\n\
* the Free Software Foundation; either version 2.1 of the License, or (at     *\n\
* your option) any later version.                                             *\n\
*                                                                             *\n\
* This library is distributed in the hope that it will be useful, but WITHOUT *\n\
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *\n\
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *\n\
* for more details.                                                           *\n\
*                                                                             *\n\
* You should have received a copy of the GNU Lesser General Public License    *\n\
* along with this library; if not, write to the Free Software Foundation,     *\n\
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *\n\
*******************************************************************************\n\
*                               SOFA :: Modules                               *\n\
*                                                                             *\n\
* Authors: The SOFA Team and external contributors (see Authors.txt)          *\n\
*                                                                             *\n\
* Contact information: contact@sofa-framework.org                             *\n\
******************************************************************************/\n\
\n\n\n\
// File automatically generated by \"generateTypedef\"\n\n\
\n"		);
const std::string defaultIncludes(
    "\
//Default files containing the declaration of the vector type\n\
#include <sofa/defaulttype/VecTypes.h>\n\
#include <sofa/defaulttype/RigidTypes.h>\n\
#include <sofa/defaulttype/Mat.h>\n\n\
\n\
#ifdef SOFA_GPU_CUDA\n\
#include <sofa/gpu/cuda/CudaTypesBase.h>\n\
#include <sofa/gpu/cuda/CudaTypes.h>\n\
#endif\n\
#ifdef SOFA_GPU_OPENCL\n\
#include <sofa/gpu/opencl/OpenCLTypes.h>\n\
#endif\n");
    }

    using namespace sofa;
    using namespace sofa::core;
    using namespace sofa::helper::system;

    int main(int argc, char** argv)
    {

    std::vector<std::string> plugins;
    std::vector<std::string> targets;
    sofa::helper::parse("This application generate header files for each SOFA binary.\n\
    Each header file contains includes to the SOFA components belonging to the binary.\n\
    A glorious Sofa.h header is also created which contains includes to all the other headers generated\n\
    by this application.\n\
    Headers are created in $SOFA_DIR/modules/sofa")
    .option(&plugins,'l',"load","load given plugins")
    .option(&targets,'t',"targets","generate typedefs for the given targets only")
        (argc,argv);

        sofa::component::init();
#ifdef SOFA_DEV
        sofa::component::initDev();
#endif
        for (unsigned int i=0; i<plugins.size(); i++)
        sofa::helper::system::PluginManager::getInstance().loadPlugin(plugins[i]);

        sofa::helper::system::PluginManager::getInstance().initRecentlyOpened();
        sofa::helper::system::PluginManager::getInstance().init();

        helper::vector<ObjectFactory::ClassEntry*> registry;
        helper::vector<ObjectFactory::ClassEntry*>::iterator it;

        //std::string outputPath = SetDirectory::GetRelativeFromProcess("../modules/sofa/");
        std::string outputPath = "/modules/sofa/";

        std::string fullPath = SetDirectory::GetParentDir(SetDirectory::GetParentDir(SetDirectory::GetProcessFullPath("").c_str()).c_str());
        int absoluteBasePathSize = fullPath.length();

        // retrieve creators

        typedef std::map< std::string, helper::vector< ObjectFactory::CreatorList::value_type >  > TargetCreatorMap;
        typedef std::map< std::string, helper::vector< ObjectFactory::ClassEntry* >  > TargetClassEntryMap;
        TargetCreatorMap targetCreatorMap;
        TargetClassEntryMap targetClassEntryMap;

        sofa::core::ObjectFactory::getInstance()->getAllEntries(registry);

        for( it = registry.begin(); it != registry.end(); ++it)
    {
        ObjectFactory::ClassEntry* entry = *it;
        ObjectFactory::CreatorList::iterator itc;
        itc = entry->creatorList.begin();
        if( itc != entry->creatorList.end() )
    {
        targetClassEntryMap[itc->second->getTarget()].push_back(entry);
    }

        for(itc = entry->creatorList.begin(); itc != entry->creatorList.end(); ++itc )
    {
        ObjectFactory::Creator* creator = itc->second;
        targetCreatorMap[creator->getTarget()].push_back(*itc);
    }
    }

        std::ostringstream timestamp;
        timestamp << std::string("/*") << std::endl
<< "GENERATED THE " << std::string(__DATE__) << " AT " << std::string(__TIME__) << std::endl
<< std::string("*/\n")
        ;

        // generate target headers

        for( TargetCreatorMap::iterator it_target = targetCreatorMap.begin(); it_target != targetCreatorMap.end(); ++it_target)
    {
        std::ostringstream target_h_location,target_h_guarding_block;
        target_h_location << fullPath << outputPath << it_target->first << ".h";
        std::ofstream target_h(target_h_location.str().c_str());
    {
        std::string target_name(it_target->first);
        std::transform(target_name.begin(),target_name.end(),target_name.begin(),::toupper);
        target_h_guarding_block << "#ifndef " << target_name << "_H" << std::endl;
        target_h_guarding_block << "#define " << target_name << "_H" << std::endl;
    }

        target_h << target_h_guarding_block.str();
        target_h << timestamp.str();
        target_h << authors;
        target_h << defaultIncludes;

        helper::vector< ObjectFactory::CreatorList::value_type > targetCreatorList = it_target->second;
        helper::vector< ObjectFactory::CreatorList::value_type >::iterator it_creatorlist;
        std::pair<TargetClassEntryMap::iterator,TargetClassEntryMap::iterator> range = targetClassEntryMap.equal_range(it_target->first);
        TargetClassEntryMap::iterator it_vecEntry;
        for(it_vecEntry = range.first; it_vecEntry != range.second; ++it_vecEntry)
    {
        helper::vector< ObjectFactory::ClassEntry*> &  vecEntry = it_vecEntry->second;
        helper::vector< ObjectFactory::ClassEntry*>::iterator it_entry;
        for(it_entry = vecEntry.begin(); it_entry != vecEntry.end(); ++it_entry)
    {
        ObjectFactory::ClassEntry* entry = *it_entry;
        if( entry->creatorList.begin() != entry->creatorList.end() )
    {
        ObjectFactory::Creator* creator = entry->creatorList.begin()->second;
        std::string includePath = std::string(creator->getHeaderFileLocation()).substr(absoluteBasePathSize + outputPath.length());
        target_h << "#include <sofa/" << includePath << ">" << std::endl;
    }
    }
    }

        target_h << std::endl;

        for(it_creatorlist = targetCreatorList.begin(); it_creatorlist != targetCreatorList.end(); ++it_creatorlist)
    {
        ObjectFactory::Creator* creator = it_creatorlist->second;
        std::string templateName = creator->getClass()->templateName;

    {
        std::string::iterator itEnd;

        itEnd = std::remove(templateName.begin(),templateName.end(),'[');
        templateName.erase(itEnd, templateName.end());

        itEnd = std::remove(templateName.begin(),templateName.end(),']');
        templateName.erase(itEnd, templateName.end());
    }

        std::replace(templateName.begin(),templateName.end(),',','_');
        std::replace(templateName.begin(),templateName.end(),' ','_');
        std::replace(templateName.begin(),templateName.end(),'<','_');
        std::replace(templateName.begin(),templateName.end(),'>','_');

        // trim right underscores
    {
        for(unsigned size = templateName.size(); size != 0; --size)
    {
        if('_' != templateName[size - 1])
    {
        if(templateName.size() != size)
        templateName.resize(size);

        break;
    }
    }
    }

        const std::type_info& type = creator->type();

        size_t curPos = 0;
        size_t oldPos = 0;
        std::string namespaceName = creator->getClass()->namespaceName;
        size_t bracketCount = 0;
        helper::vector<std::string> namespaces;
        while( ( curPos = namespaceName.find(std::string("::"),oldPos) ) != std::string::npos)
    {
        std::string currentNamespace = namespaceName.substr(oldPos,curPos-oldPos);
        namespaces.push_back(currentNamespace);
        oldPos = curPos+2;
        ++bracketCount;
    }
        namespaces.push_back(namespaceName.substr(oldPos));
        helper::vector<std::string>::iterator it_namespace;
        for(it_namespace = namespaces.begin(); it_namespace != namespaces.end(); ++it_namespace)
    {
        target_h << "namespace " << *it_namespace << std::endl;
    target_h << "{" << std::endl;
}

    if(!templateName.empty())
{
    target_h << "typedef " <<  sofa::core::objectmodel::BaseClass::decodeFullName(type)
    << " " << creator->getClass()->className << "_" << templateName << ";";
}
    else
{
    target_h << "typedef " <<  sofa::core::objectmodel::BaseClass::decodeFullName(type)
    << " " << creator->getClass()->className << ";";
}
    target_h << std::endl;
    for( size_t i=0; i<namespaces.size(); ++i)
{
    target_h << "}" << std::endl;
}

target_h << std::endl;
}
target_h << "#endif " << std::endl;
target_h.close();
}

// generate sofa.h header

std::string sofa_name("sofa");
std::ostringstream sofa_h_location,sofa_h_guarding_block;
sofa_h_location << fullPath << outputPath << sofa_name << ".h";
std::ofstream sofa_h(sofa_h_location.str().c_str());
{
std::transform(sofa_name.begin(),sofa_name.end(),sofa_name.begin(),::toupper);
sofa_h_guarding_block << "#ifndef " << sofa_name << "_H" << std::endl;
sofa_h_guarding_block << "#define " << sofa_name << "_H" << std::endl;
}

sofa_h << sofa_h_guarding_block.str();
sofa_h << timestamp.str();
sofa_h << authors << std::endl;

for( TargetCreatorMap::iterator it_target = targetCreatorMap.begin(); it_target != targetCreatorMap.end(); ++it_target)
{
std::ostringstream target_h_location;
target_h_location << it_target->first << ".h";

sofa_h << "#include <sofa/" << target_h_location.str().c_str() << ">" << std::endl;
}

sofa_h << std::endl << "#endif " << std::endl;
sofa_h.close();
}
<|endoftext|>