IECoreScene::PrimitiveVariable FromMayaMeshConverter::points() const
{
	MFnMesh fnMesh;
	const MDagPath *d = dagPath( true );
	if( d )
	{
		fnMesh.setObject( *d );
	}
	else
	{
		fnMesh.setObject( object() );
	}

	V3fVectorDataPtr points = new V3fVectorData;
	points->setInterpretation( GeometricData::Point );
	int numVerts = fnMesh.numVertices();
	points->writable().resize( numVerts );

	if( space() == MSpace::kObject )
	{
		const V3f* rawPoints = ( const V3f* )fnMesh.getRawPoints(0);
		copy( rawPoints, rawPoints + numVerts, points->writable().begin() );
	}
	else
	{
		MFloatPointArray mPoints;
		fnMesh.getPoints( mPoints, space() );
		std::transform( MArrayIter<MFloatPointArray>::begin( mPoints ), MArrayIter<MFloatPointArray>::end( mPoints ), points->writable().begin(), VecConvert<MFloatPoint, V3f>() );
	}

	return PrimitiveVariable( PrimitiveVariable::Vertex, points );
}
IECoreGL::ConstRenderablePtr StandardLightVisualiser::pointRays()
{
    IECoreGL::GroupPtr group = new IECoreGL::Group();
    addWireframeCurveState( group.get() );

    IECore::CompoundObjectPtr parameters = new CompoundObject;
    parameters->members()["aimType"] = new IntData( 1 );
    group->getState()->add(
        new IECoreGL::ShaderStateComponent( ShaderLoader::defaultShaderLoader(), TextureLoader::defaultTextureLoader(), faceCameraVertexSource(), "", IECoreGL::Shader::constantFragmentSource(), parameters )
    );

    IntVectorDataPtr vertsPerCurve = new IntVectorData;
    V3fVectorDataPtr p = new V3fVectorData;

    const int numRays = 8;
    for( int i = 0; i < numRays; ++i )
    {
        const float angle = M_PI * 2.0f * float(i)/(float)numRays;
        const V2f dir( cos( angle ), sin( angle ) );
        addRay( dir * .5, dir * 1, vertsPerCurve->writable(), p->writable() );
    }

    IECoreGL::CurvesPrimitivePtr curves = new IECoreGL::CurvesPrimitive( IECore::CubicBasisf::linear(), false, vertsPerCurve );
    curves->addPrimitiveVariable( "P", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Vertex, p ) );
    curves->addPrimitiveVariable( "Cs", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new Color3fData( Color3f( 1.0f, 0.835f, 0.07f ) ) ) );

    group->addChild( curves );

    return group;
}
IECore::ObjectPtr FromNukePointsConverter::doConversion( IECore::ConstCompoundObjectPtr operands ) const
{

	// get points
	V3fVectorDataPtr p = new V3fVectorData();
	if( const DD::Image::PointList *pl = m_geo->point_list() )
	{
		p->writable().resize( pl->size() );
		std::transform( pl->begin(), pl->end(), p->writable().begin(), IECore::convert<Imath::V3f, DD::Image::Vector3> );
	}

	PointsPrimitivePtr result = new PointsPrimitive( p );

	// get colour
	const DD::Image::Attribute *colorAttr = m_geo->get_typed_attribute( "Cf", DD::Image::VECTOR4_ATTRIB );
	if( colorAttr && colorAttr->size()==result->getNumPoints() )
	{
		Color3fVectorDataPtr colorData = new Color3fVectorData();
		colorData->writable().resize( result->getNumPoints() );
		std::transform( colorAttr->vector4_list->begin(), colorAttr->vector4_list->end(), colorData->writable().begin(), IECore::convert<Imath::Color3f, DD::Image::Vector4> );
		result->variables["Cs"] = PrimitiveVariable( PrimitiveVariable::Vertex, colorData );
	}

	/// \todo Other primitive variables

	return result;
}
IECoreScene::PrimitiveVariable FromMayaMeshConverter::normals() const
{
	MFnMesh fnMesh;
	const MDagPath *d = dagPath( true );
	if( d )
	{
		fnMesh.setObject( *d );
	}
	else
	{
		fnMesh.setObject( object() );
	}

	V3fVectorDataPtr normalsData = new V3fVectorData;
	normalsData->setInterpretation( GeometricData::Normal );
	vector<V3f> &normals = normalsData->writable();
	normals.reserve( fnMesh.numFaceVertices() );

	int numPolygons = fnMesh.numPolygons();
	V3f blankVector;

	if( space() == MSpace::kObject )
	{
		const float* rawNormals = fnMesh.getRawNormals(0);
		MIntArray normalIds;
		for( int i=0; i<numPolygons; i++ )
		{
			fnMesh.getFaceNormalIds( i, normalIds );
			for( unsigned j=0; j < normalIds.length(); ++j )
			{
				const float* normalIt = rawNormals + 3 * normalIds[j];
				normals.push_back( blankVector );
				V3f& nn = normals.back();
				nn.x = *normalIt++;
				nn.y = *normalIt++;
				nn.z = *normalIt;
			}
		}
	}
	else
	{
		MFloatVectorArray faceNormals;
		for( int i=0; i<numPolygons; i++ )
		{
			fnMesh.getFaceVertexNormals( i, faceNormals, space() );
			for( unsigned j=0; j<faceNormals.length(); j++ )
			{
				MFloatVector& n = faceNormals[j];
				normals.push_back( blankVector );
				V3f& nn = normals.back();
				nn.x = n.x;
				nn.y = n.y;
				nn.z = n.z;
			}
		}
	}

	return PrimitiveVariable( PrimitiveVariable::FaceVarying, normalsData );
}
Example #5
0
MeshPrimitive::MeshPrimitive( ConstIntVectorDataPtr verticesPerFace, ConstIntVectorDataPtr vertexIds,
                              const std::string &interpolation, V3fVectorDataPtr p )
{
    setTopology( verticesPerFace, vertexIds, interpolation );
    if( p )
    {
        V3fVectorDataPtr pData = p->copy();
        pData->setInterpretation( GeometricData::Point );
        variables.insert( PrimitiveVariableMap::value_type("P", PrimitiveVariable(PrimitiveVariable::Vertex, pData)) );
    }
}
Example #6
0
NURBSPrimitive::NURBSPrimitive( int uOrder, ConstFloatVectorDataPtr uKnot, float uMin, float uMax,
	int vOrder, ConstFloatVectorDataPtr vKnot, float vMin, float vMax, ConstV3fVectorDataPtr p )
{
	setTopology( uOrder, uKnot, uMin, uMax, vOrder, vKnot, vMin, vMax );
	if( p )
	{
		V3fVectorDataPtr pData = p->copy();
		pData->setInterpretation( GeometricData::Point );
		variables.insert( PrimitiveVariableMap::value_type( "P", PrimitiveVariable( PrimitiveVariable::Vertex, pData ) ) );
	}
}
Example #7
0
CurvesPrimitive::CurvesPrimitive( ConstIntVectorDataPtr vertsPerCurve, const CubicBasisf &basis, bool periodic, ConstV3fVectorDataPtr p )
	: 	m_basis( CubicBasisf::linear() )
{
	setTopology( vertsPerCurve, basis, periodic );

	if( p )
	{
		V3fVectorDataPtr pData = p->copy();
		pData->setInterpretation( GeometricData::Point );
		variables["P"] = PrimitiveVariable( PrimitiveVariable::Vertex, pData );
	}
}
Example #8
0
ObjectPtr PointNormalsOp::doOperation( const CompoundObject *operands )
{
	const int numNeighbours = m_numNeighboursParameter->getNumericValue();

	const Object * points = pointParameter()->getValue();
	ObjectPtr result = nullptr;
	switch( points->typeId() )
	{
		case V3fVectorDataTypeId :
			{
				V3fVectorDataPtr resultT = new V3fVectorData;
				normals<V3f>( static_cast<const V3fVectorData *>( points )->readable(), numNeighbours, resultT->writable() );
				result = resultT;
			}
			break;
		case V3dVectorDataTypeId :
			{
				V3dVectorDataPtr resultT = new V3dVectorData;
				normals<V3d>( static_cast<const V3dVectorData *>( points )->readable(), numNeighbours, resultT->writable() );
				result = resultT;
			}
			break;
		default :
			// should never get here
			assert( 0 );
	}

	return result;
}
Example #9
0
IECore::ConstObjectPtr OSLObject::computeProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::ConstObjectPtr inputObject ) const
{
	const Primitive *inputPrimitive = runTimeCast<const Primitive>( inputObject.get() );
	if( !inputPrimitive )
	{
		return inputObject;
	}

	if( !inputPrimitive->variableData<V3fVectorData>( "P", PrimitiveVariable::Vertex ) )
	{
		return inputObject;
	}

	OSLRenderer::ConstShadingEnginePtr shadingEngine = OSLImage::shadingEngine( shaderPlug() );
	if( !shadingEngine )
	{
		return inputObject;	
	}
	
	CompoundDataPtr shadingPoints = new CompoundData;
	for( PrimitiveVariableMap::const_iterator it = inputPrimitive->variables.begin(), eIt = inputPrimitive->variables.end(); it != eIt; ++it )
	{
		if( it->second.interpolation == PrimitiveVariable::Vertex )
		{
			// cast is ok - we're only using it to be able to reference the data from the shadingPoints,
			// but nothing will modify the data itself.
			shadingPoints->writable()[it->first] = constPointerCast<Data>( it->second.data );
		}
	}

	PrimitivePtr outputPrimitive = inputPrimitive->copy();

	ConstCompoundDataPtr shadedPoints = shadingEngine->shade( shadingPoints );
	const std::vector<Color3f> &ci = shadedPoints->member<Color3fVectorData>( "Ci" )->readable();
	
	V3fVectorDataPtr p = new V3fVectorData;
	p->writable().reserve( ci.size() );
	std::copy( ci.begin(), ci.end(), back_inserter( p->writable() ) );
	
	outputPrimitive->variables["P"] = PrimitiveVariable( PrimitiveVariable::Vertex, p );

	/// \todo Allow shaders to write arbitrary primitive variables.
			
	return outputPrimitive;
}
IECore::CompoundDataPtr IECoreRI::SXRendererImplementation::shadePlane( const V2i &resolution ) const
{
	IECore::CompoundDataPtr points = new IECore::CompoundData();
	
	V3fVectorDataPtr pData = new IECore::V3fVectorData();
	V3fVectorDataPtr nData = new IECore::V3fVectorData();
	FloatVectorDataPtr sData = new IECore::FloatVectorData();
	FloatVectorDataPtr tData = new IECore::FloatVectorData();

	std::vector<V3f> &p = pData->writable();
	std::vector<V3f> &n = nData->writable();
	std::vector<float> &s = sData->writable();
	std::vector<float> &t = tData->writable();
	
	unsigned numPoints = resolution[0] * resolution[1];
	
	p.resize( numPoints );
	n.resize( numPoints );
	s.resize( numPoints );
	t.resize( numPoints );
	
	unsigned xResMinus1 = resolution[0] - 1;
	unsigned yResMinus1 = resolution[1] - 1;
	
	unsigned i = 0;
	for( int y = 0; y < resolution[1]; y++ )
	{
		for( int x = 0; x < resolution[0]; x++ )
		{
			p[i] = V3f( float(x) / xResMinus1 , float(y) / yResMinus1, 0.0 );	
			s[i] = p[i][0];
			t[i] = p[i][1];
			n[i] = V3f( 0.0f, 0.0f, 1.0f );
			i++;
		}
	}	
	
	points->writable()[ "P" ] = pData;
	points->writable()[ "N" ] = nData;
	points->writable()[ "s" ] = sData;
	points->writable()[ "t" ] = tData;
	
	return shade( points, resolution );
}
IECoreGL::ConstRenderablePtr StandardLightVisualiser::spotlightCone( float innerAngle, float outerAngle, float lensRadius )
{
    IECoreGL::GroupPtr group = new IECoreGL::Group();
    addWireframeCurveState( group.get() );

    group->getState()->add( new IECoreGL::CurvesPrimitive::GLLineWidth( 1.0f ) );

    IECore::CompoundObjectPtr parameters = new CompoundObject;
    parameters->members()["aimType"] = new IntData( 0 );
    group->getState()->add(
        new IECoreGL::ShaderStateComponent( ShaderLoader::defaultShaderLoader(), TextureLoader::defaultTextureLoader(), faceCameraVertexSource(), "", IECoreGL::Shader::constantFragmentSource(), parameters )
    );

    IntVectorDataPtr vertsPerCurve = new IntVectorData;
    V3fVectorDataPtr p = new V3fVectorData;
    addCone( innerAngle, lensRadius, vertsPerCurve->writable(), p->writable() );

    IECoreGL::CurvesPrimitivePtr curves = new IECoreGL::CurvesPrimitive( IECore::CubicBasisf::linear(), false, vertsPerCurve );
    curves->addPrimitiveVariable( "P", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Vertex, p ) );
    curves->addPrimitiveVariable( "Cs", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new Color3fData( Color3f( 1.0f, 0.835f, 0.07f ) ) ) );

    group->addChild( curves );

    if( fabs( innerAngle - outerAngle ) > 0.1 )
    {
        IECoreGL::GroupPtr outerGroup = new Group;
        outerGroup->getState()->add( new IECoreGL::CurvesPrimitive::GLLineWidth( 0.5f ) );

        IntVectorDataPtr vertsPerCurve = new IntVectorData;
        V3fVectorDataPtr p = new V3fVectorData;
        addCone( outerAngle, lensRadius, vertsPerCurve->writable(), p->writable() );

        IECoreGL::CurvesPrimitivePtr curves = new IECoreGL::CurvesPrimitive( IECore::CubicBasisf::linear(), false, vertsPerCurve );
        curves->addPrimitiveVariable( "P", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Vertex, p ) );
        curves->addPrimitiveVariable( "Cs", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new Color3fData( Color3f( 1.0f, 0.835f, 0.07f ) ) ) );

        outerGroup->addChild( curves );

        group->addChild( outerGroup );
    }

    return group;
}
Example #12
0
CurvesPrimitivePtr CurvesPrimitive::createBox( const Imath::Box3f &b )
{
	IntVectorDataPtr vertsPerCurveData = new IntVectorData;
	std::vector<int> &vertsPerCurve = vertsPerCurveData->writable();
	vertsPerCurve.reserve( 6 );

	V3fVectorDataPtr pData = new V3fVectorData;
	std::vector<V3f> &p = pData->writable();
	p.reserve( 18 );

	vertsPerCurve.push_back( 5 );
	p.push_back( b.min );
	p.push_back( V3f( b.max.x, b.min.y, b.min.z ) );
	p.push_back( V3f( b.max.x, b.min.y, b.max.z ) );
	p.push_back( V3f( b.min.x, b.min.y, b.max.z ) );
	p.push_back( b.min );

	vertsPerCurve.push_back( 5 );
	p.push_back( V3f( b.min.x, b.max.y, b.min.z ) );
	p.push_back( V3f( b.max.x, b.max.y, b.min.z ) );
	p.push_back( V3f( b.max.x, b.max.y, b.max.z ) );
	p.push_back( V3f( b.min.x, b.max.y, b.max.z ) );
	p.push_back( V3f( b.min.x, b.max.y, b.min.z ) );

	vertsPerCurve.push_back( 2 );
	p.push_back( b.min );
	p.push_back( V3f( b.min.x, b.max.y, b.min.z ) );

	vertsPerCurve.push_back( 2 );
	p.push_back( V3f( b.max.x, b.min.y, b.min.z ) );
	p.push_back( V3f( b.max.x, b.max.y, b.min.z ) );

	vertsPerCurve.push_back( 2 );
	p.push_back( V3f( b.max.x, b.min.y, b.max.z ) );
	p.push_back( V3f( b.max.x, b.max.y, b.max.z ) );

	vertsPerCurve.push_back( 2 );
	p.push_back( V3f( b.min.x, b.min.y, b.max.z ) );
	p.push_back( V3f( b.min.x, b.max.y, b.max.z ) );

	return new CurvesPrimitive( vertsPerCurveData, CubicBasisf::linear(), false, pData );
}
IECoreGL::ConstRenderablePtr StandardLightVisualiser::ray()
{
    IECoreGL::GroupPtr group = new IECoreGL::Group();
    addWireframeCurveState( group.get() );

    IECore::CompoundObjectPtr parameters = new CompoundObject;
    parameters->members()["aimType"] = new IntData( 0 );
    group->getState()->add(
        new IECoreGL::ShaderStateComponent( ShaderLoader::defaultShaderLoader(), TextureLoader::defaultTextureLoader(), faceCameraVertexSource(), "", IECoreGL::Shader::constantFragmentSource(), parameters )
    );

    IntVectorDataPtr vertsPerCurve = new IntVectorData;
    V3fVectorDataPtr p = new V3fVectorData;
    addRay( V2f( 0 ), V2f( 1, 0 ), vertsPerCurve->writable(), p->writable() );

    IECoreGL::CurvesPrimitivePtr curves = new IECoreGL::CurvesPrimitive( IECore::CubicBasisf::linear(), false, vertsPerCurve );
    curves->addPrimitiveVariable( "P", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Vertex, p ) );
    curves->addPrimitiveVariable( "Cs", IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new Color3fData( Color3f( 1.0f, 0.835f, 0.07f ) ) ) );

    group->addChild( curves );

    return group;
}
Example #14
0
IECore::ConstObjectPtr Grid::computeObject( const SceneNode::ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	if( path.size() == 2 )
	{
		IntVectorDataPtr vertsPerCurveData = new IntVectorData;
		vector<int> &vertsPerCurve = vertsPerCurveData->writable();

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

		bool periodic = false;
		Color3f cs( 1 );

		const V2f halfDimensions = dimensionsPlug()->getValue() / 2.0f;
		if( path.back() == g_gridLinesName )
		{
			const float spacing = spacingPlug()->getValue();
			const V2i n = V2f( halfDimensions / spacing ) - V2f( 0.01 );
			for( int d = 0; d < 2; ++d )
			{
				const int d0 = d;
				const int d1 = d == 0 ? 1 : 0;
				for( int i = -n[d]; i <= n[d]; ++i )
				{
					if( i == 0 )
					{
						continue;
					}
					vertsPerCurve.push_back( 2 );
					V3f e( 0 );
					e[d0] = i * spacing;
					e[d1] = -halfDimensions[d1];
					p.push_back( e );
					e[d1] = halfDimensions[d1];
					p.push_back( e );
				}
			}
			cs = gridColorPlug()->getValue();
		}
		else if( path.back() == g_centerLinesName )
		{
			vertsPerCurve.push_back( 2 );
			p.push_back( V3f( halfDimensions.x, 0, 0 ) );
			p.push_back( V3f( -halfDimensions.x, 0, 0 ) );
			vertsPerCurve.push_back( 2 );
			p.push_back( V3f( 0, halfDimensions.y, 0 ) );
			p.push_back( V3f( 0, -halfDimensions.y, 0 ) );
			cs = centerColorPlug()->getValue();
		}
		else if( path.back() == g_borderLinesName )
		{
			vertsPerCurve.push_back( 4 );
			p.push_back( V3f( -halfDimensions.x, -halfDimensions.y, 0 ) );
			p.push_back( V3f( halfDimensions.x, -halfDimensions.y, 0 ) );
			p.push_back( V3f( halfDimensions.x, halfDimensions.y, 0 ) );
			p.push_back( V3f( -halfDimensions.x, halfDimensions.y, 0 ) );
			periodic = true;
			cs = borderColorPlug()->getValue();
		}

		CurvesPrimitivePtr result = new CurvesPrimitive( vertsPerCurveData, CubicBasisf::linear(), periodic, pData );
		result->variables["Cs"] = PrimitiveVariable( PrimitiveVariable::Constant, new Color3fData( cs ) );
		return result;
	}
	return outPlug()->objectPlug()->defaultValue();
}
Example #15
0
ObjectPtr EnvMapSampler::doOperation( const CompoundObject * operands )
{
	ImagePrimitivePtr image = static_cast<ImagePrimitive *>( imageParameter()->getValue() )->copy();
	Box2i dataWindow = image->getDataWindow();

	// find the rgb channels
	ConstFloatVectorDataPtr redData = image->getChannel<float>( "R" );
	ConstFloatVectorDataPtr greenData = image->getChannel<float>( "G" );
	ConstFloatVectorDataPtr blueData = image->getChannel<float>( "B" );
	if( !(redData && greenData && blueData) )
	{
		throw Exception( "Image does not contain valid RGB float channels." );
	}
	const vector<float> &red = redData->readable();
	const vector<float> &green = greenData->readable();
	const vector<float> &blue = blueData->readable();

	// get a luminance channel
	LuminanceOpPtr luminanceOp = new LuminanceOp();
	luminanceOp->inputParameter()->setValue( image );
	luminanceOp->copyParameter()->getTypedValue() = false;
	luminanceOp->removeColorPrimVarsParameter()->getTypedValue() = false;
	luminanceOp->operate();

	// do the median cut thing to get some samples
	MedianCutSamplerPtr sampler = new MedianCutSampler;
	sampler->imageParameter()->setValue( image );
	sampler->subdivisionDepthParameter()->setNumericValue( subdivisionDepthParameter()->getNumericValue() );
	ConstCompoundObjectPtr samples = boost::static_pointer_cast<CompoundObject>( sampler->operate() );
	const vector<V2f> &centroids = boost::static_pointer_cast<V2fVectorData>( samples->members().find( "centroids" )->second )->readable();
	const vector<Box2i> &areas = boost::static_pointer_cast<Box2iVectorData>( samples->members().find( "areas" )->second )->readable();

	// get light directions and colors from the samples
	V3fVectorDataPtr directionsData = new V3fVectorData;
	Color3fVectorDataPtr colorsData = new Color3fVectorData;
	vector<V3f> &directions = directionsData->writable();
	vector<Color3f> &colors = colorsData->writable();

	float radiansPerPixel = M_PI / (dataWindow.size().y + 1);
	float angleAtTop = ( M_PI - radiansPerPixel ) / 2.0f;

	for( unsigned i=0; i<centroids.size(); i++ )
	{
		const Box2i &area = areas[i];
		Color3f color( 0 );
		for( int y=area.min.y; y<=area.max.y; y++ )
		{
			int yRel = y - dataWindow.min.y;

			float angle = angleAtTop - yRel * radiansPerPixel;
			float weight = cosf( angle );
			int index = (area.min.x - dataWindow.min.x) + (dataWindow.size().x + 1 ) * yRel;
			for( int x=area.min.x; x<=area.max.x; x++ )
			{
				color[0] += weight * red[index];
				color[1] += weight * green[index];
				color[2] += weight * blue[index];
				index++;
			}
		}
		color /= red.size();
		colors.push_back( color );

		float phi = angleAtTop - (centroids[i].y - dataWindow.min.y) * radiansPerPixel;

		V3f direction;
		direction.y = sinf( phi );
		float r = cosf( phi );
		float theta = 2 * M_PI * lerpfactor( (float)centroids[i].x, (float)dataWindow.min.x, (float)dataWindow.max.x );
		direction.x = r * cosf( theta );
		direction.z = r * sinf( theta );

		directions.push_back( -direction ); // negated so we output the direction the light shines in
	}

	// return the result
	CompoundObjectPtr result = new CompoundObject;
	result->members()["directions"] = directionsData;
	result->members()["colors"] = colorsData;
	return result;
}
void YUVImageWriter::writeImage( const vector<string> &names, const ImagePrimitive * image, const Box2i &dataWindow ) const
{
	const V2f &kBkR = m_kBkRParameter->getTypedValue();
	const Box3f &range = m_rangeParameter->getTypedValue();

	if ( range.isEmpty() )
	{
		throw InvalidArgumentException("YUVImageWriter: Empty YUV range specified ");
	}

	const float kB = kBkR.x;
	const float kR = kBkR.y;

	int displayWidth  = 1 + image->getDisplayWindow().size().x;
	int displayHeight = 1 + image->getDisplayWindow().size().y;

	if ( displayWidth % 2 != 0 || displayHeight % 2 != 0 )
	{
		throw IOException("YUVImageWriter: Unsupported resolution");
	}

	vector<string>::const_iterator rIt = std::find( names.begin(), names.end(), "R" );
	vector<string>::const_iterator gIt = std::find( names.begin(), names.end(), "G" );
	vector<string>::const_iterator bIt = std::find( names.begin(), names.end(), "B" );

	if ( rIt == names.end() || gIt == names.end() || bIt == names.end() )
	{
		throw IOException("YUVImageWriter: Unsupported channel names specified");
	}

	std::ofstream outFile( fileName().c_str(), std::ios::trunc | std::ios::binary | std::ios::out );
	if (! outFile.is_open() )
	{
		throw IOException("Could not open '" + fileName() + "' for writing.");
	}

	Color3fVectorDataPtr rgbData = new Color3fVectorData();
	rgbData->writable().resize( displayWidth * displayHeight, Color3f(0,0,0) );

	try
	{
		for ( vector<string>::const_iterator it = names.begin(); it != names.end(); it++ )
		{
			const string &name = *it;

			if (!( name == "R" || name == "G" || name == "B" ) )
			{
				msg( Msg::Warning, "YUVImageWriter", format( "Channel \"%s\" was not encoded." ) % name );
				continue;
			}

			int channelOffset = 0;
			if ( name == "R" )
			{
				channelOffset = 0;
			}
			else if ( name == "G" )
			{
				channelOffset = 1;
			}
			else
			{
				assert( name == "B" );
				channelOffset = 2;
			}

			// get the image channel
			assert( image->variables.find( name ) != image->variables.end() );
			DataPtr dataContainer = image->variables.find( name )->second.data;
			assert( dataContainer );

			ChannelConverter converter( *it, image, dataWindow, channelOffset, rgbData );

			despatchTypedData<
				ChannelConverter,
				TypeTraits::IsNumericVectorTypedData,
				ChannelConverter::ErrorHandler
			>( dataContainer, converter );

		}

		V3fVectorDataPtr yuvData = new V3fVectorData();
		yuvData->writable().resize( displayWidth * displayHeight, V3f(0,0,0) );

		assert( yuvData->readable().size() == rgbData->readable().size() );

		for ( int i = 0; i < displayWidth * displayHeight; i ++ )
		{
			Color3f rgb = rgbData->readable()[i];

			if ( rgb.x < 0.0 ) rgb.x = 0;
			if ( rgb.x > 1.0 ) rgb.x = 1.0;

			if ( rgb.y < 0.0 ) rgb.y = 0;
			if ( rgb.y > 1.0 ) rgb.y = 1.0;

			if ( rgb.z < 0.0 ) rgb.z = 0;
			if ( rgb.z > 1.0 ) rgb.z = 1.0;

			V3f yPbPr;

			float &Y = yPbPr.x;
			float &Pb = yPbPr.y;
			float &Pr = yPbPr.z;

			Y = kR * rgb.x + ( 1.0 - kR - kB ) * rgb.y + kB * rgb.z;
			Pb = 0.5 * ( rgb.z - Y ) / ( 1.0 - kB );
			Pr = 0.5 * ( rgb.x - Y ) / ( 1.0 - kR );

			V3f yCbCr = yPbPr;

			/// Map from 0-1
			yCbCr.y += 0.5;
			yCbCr.z += 0.5;

			/// Apply any scaling for "head-room" and "toe-room"
			yCbCr.x	= ( yCbCr.x * ( range.max.x - range.min.x ) ) + range.min.x;
			yCbCr.y	= ( yCbCr.y * ( range.max.y - range.min.y ) ) + range.min.y;
			yCbCr.z	= ( yCbCr.z * ( range.max.z - range.min.z ) ) + range.min.z;

			yuvData->writable()[i] = yCbCr;
		}

		/// \todo Chroma-filtering. Ideally we should do a proper sampled downsize of the chroma, rather than skipping data
		/// elements. This would avoid any aliasing.

		int lumaStepX = 1;
		int lumaStepY = 1;

		int chromaUStepX = 1;
		int chromaUStepY = 1;

		int chromaVStepX = 1;
		int chromaVStepY = 1;

		switch ( m_formatParameter->getNumericValue() )
		{
			case YUV420P :
				/// Half res in U and V
				chromaUStepX = 2;
				chromaUStepY = 2;
				chromaVStepX = 2;
				chromaVStepY = 2;
				break;
			case YUV422P :
				/// Half horizonal res in U and V
				chromaUStepX = 2;
				chromaUStepY = 1;
				chromaVStepX = 2;
				chromaVStepY = 1;
				break;
			case YUV444P :
				/// Full res in U and V
				break;
			default :
				assert( false );
		}

		ScaledDataConversion<float, unsigned char> converter;
		/// Y-plane
		for ( int y = 0; y < displayHeight; y += lumaStepX )
		{
			for ( int x = 0; x < displayWidth; x += lumaStepY )
			{
				const V3f yCbCr = yuvData->readable()[y*displayWidth + x];

				const unsigned char val = converter( yCbCr.x );

				outFile.write( (const char*)&val, 1 );
			}
		}

		/// U-plane
		for ( int y = 0; y < displayHeight; y+=chromaUStepX )
		{
			for ( int x = 0; x < displayWidth; x+=chromaUStepY )
			{
				const V3f yCbCr = yuvData->readable()[y*displayWidth + x];

				const unsigned char val = converter( yCbCr.y );

				outFile.write( (const char*)&val, 1 );
			}
		}

		/// V-plane
		for ( int y = 0; y < displayHeight; y+=chromaVStepX )
		{
			for ( int x = 0; x < displayWidth; x+=chromaVStepY )
			{
				const V3f yCbCr = yuvData->readable()[y*displayWidth + x];

				const unsigned char val = converter( yCbCr.z );

				outFile.write( (const char*)&val, 1 );
			}
		}
	}
	catch ( std::exception &e )
	{
		throw IOException( ( boost::format( "YUVImageWriter : %s" ) % e.what() ).str() );
	}
	catch ( ... )
	{
		throw IOException( "YUVImageWriter: Unexpected error" );
	}
}
Example #17
0
IECore::ObjectPtr MeshFromNuke::doConversion( IECore::ConstCompoundObjectPtr operands ) const
{
	// topology
	IntVectorDataPtr verticesPerFaceData = new IntVectorData;
	IntVectorDataPtr vertexIdsData = new IntVectorData;
	std::vector<int> &verticesPerFace = verticesPerFaceData->writable();
	std::vector<int> &vertexIds = vertexIdsData->writable();

	unsigned numPrimitives = m_geo->primitives();
	const DD::Image::Primitive **primitives = m_geo->primitive_array();
	std::vector<unsigned> tmpFaceVertices;
	for( unsigned primIndex=0; primIndex<numPrimitives; primIndex++ )
	{
		const DD::Image::Primitive *prim = primitives[primIndex];

		unsigned numFaces = prim->faces();
		for( unsigned faceIndex=0; faceIndex<numFaces; faceIndex++ )
		{
			unsigned numFaceVertices = prim->face_vertices( faceIndex );
			verticesPerFace.push_back( numFaceVertices );
			tmpFaceVertices.resize( numFaceVertices );
			prim->get_face_vertices( faceIndex, &(tmpFaceVertices[0]) );
			for( unsigned i=0; i<numFaceVertices; i++ )
			{
				vertexIds.push_back( prim->vertex( tmpFaceVertices[i] ) );
			}
		}
	}

	MeshPrimitivePtr result = new MeshPrimitive( verticesPerFaceData, vertexIdsData, "linear" );

	// points
	if( const DD::Image::PointList *pl = m_geo->point_list() )
	{
		V3fVectorDataPtr p = new V3fVectorData();
		p->writable().resize( pl->size() );
		std::transform( pl->begin(), pl->end(), p->writable().begin(), IECore::convert<Imath::V3f, DD::Image::Vector3> );
		result->variables["P"] = PrimitiveVariable( PrimitiveVariable::Vertex, p );
	}

	// uvs
	PrimitiveVariable::Interpolation uvInterpolation = PrimitiveVariable::Vertex;
	const DD::Image::Attribute *uvAttr = m_geo->get_typed_group_attribute( DD::Image::Group_Points, "uv", DD::Image::VECTOR4_ATTRIB );
	if( !uvAttr )
	{
		uvAttr = m_geo->get_typed_group_attribute( DD::Image::Group_Vertices, "uv", DD::Image::VECTOR4_ATTRIB );
		uvInterpolation = PrimitiveVariable::FaceVarying;
	}

	if( uvAttr )
	{
		V2fVectorDataPtr uvData = new V2fVectorData();
		uvData->setInterpretation( GeometricData::UV );
		std::vector<Imath::V2f> &uvs = uvData->writable();
		uvs.reserve( uvAttr->size() );
		unsigned numUVs = uvAttr->size();
		for( unsigned i=0; i<numUVs; i++ )
		{
			// as of Cortex 10, we take a UDIM centric approach
			// to UVs, which clashes with Nuke, so we must flip
			// the v values during conversion.
			uvs.emplace_back( uvAttr->vector4( i ).x, 1.0 - uvAttr->vector4( i ).y );
		}
		result->variables["uv"] = PrimitiveVariable( uvInterpolation, uvData );
	}

	// normals
	PrimitiveVariable::Interpolation nInterpolation = PrimitiveVariable::Vertex;
	const DD::Image::Attribute *nAttr = m_geo->get_typed_group_attribute( DD::Image::Group_Points, "N", DD::Image::NORMAL_ATTRIB );
	if( !nAttr )
	{
		nAttr = m_geo->get_typed_group_attribute( DD::Image::Group_Vertices, "N", DD::Image::NORMAL_ATTRIB );
		nInterpolation = PrimitiveVariable::FaceVarying;
	}

	if( nAttr )
	{
		V3fVectorDataPtr nd = new V3fVectorData();
		std::vector<Imath::V3f> &n = nd->writable();
		n.resize( nAttr->size() );
		for( unsigned i=0; i<n.size(); i++ )
		{
			n[i] = IECore::convert<Imath::V3f, DD::Image::Vector3>( nAttr->normal( i ) );
		}
		result->variables["N"] = PrimitiveVariable( nInterpolation, nd );
	}

	return result;
}
Example #18
0
IECore::ConstCompoundDataPtr OSLImage::computeShading( const Gaffer::Context *context ) const
{
	OSLRenderer::ConstShadingEnginePtr shadingEngine;
	if( const OSLShader *shader = runTimeCast<const OSLShader>( shaderPlug()->source<Plug>()->node() ) )
	{
		shadingEngine = shader->shadingEngine();
	}

	if( !shadingEngine )
	{
		return static_cast<const CompoundData *>( shadingPlug()->defaultValue() );
	}

	const V2i tileOrigin = context->get<V2i>( ImagePlug::tileOriginContextName );
	const Format format = inPlug()->formatPlug()->getValue();

	CompoundDataPtr shadingPoints = new CompoundData();

	V3fVectorDataPtr pData = new V3fVectorData;
	FloatVectorDataPtr uData = new FloatVectorData;
	FloatVectorDataPtr vData = new FloatVectorData;

	vector<V3f> &pWritable = pData->writable();
	vector<float> &uWritable = uData->writable();
	vector<float> &vWritable = vData->writable();

	const size_t tileSize = ImagePlug::tileSize();
	pWritable.reserve( tileSize * tileSize );
	uWritable.reserve( tileSize * tileSize );
	vWritable.reserve( tileSize * tileSize );

	/// \todo Non-zero display window origins - do we have those?
	const float uStep = 1.0f / format.width();
	const float uMin = 0.5f * uStep;

	const float vStep = 1.0f / format.height();
	const float vMin = 0.5f * vStep;

	const size_t xMax = tileOrigin.x + tileSize;
	const size_t yMax = tileOrigin.y + tileSize;
	for( size_t y = tileOrigin.y; y < yMax; ++y )
	{
		const float v = vMin + y * vStep;
		for( size_t x = tileOrigin.x; x < xMax; ++x )
		{
			uWritable.push_back( uMin + x * uStep );
			vWritable.push_back( v );
			pWritable.push_back( V3f( x, y, 0.0f ) );
		}
	}

	shadingPoints->writable()["P"] = pData;
	shadingPoints->writable()["u"] = uData;
	shadingPoints->writable()["v"] = vData;

	ConstStringVectorDataPtr channelNamesData = inPlug()->channelNamesPlug()->getValue();
	const vector<string> &channelNames = channelNamesData->readable();
	for( vector<string>::const_iterator it = channelNames.begin(), eIt = channelNames.end(); it != eIt; ++it )
	{
		shadingPoints->writable()[*it] = boost::const_pointer_cast<FloatVectorData>( inPlug()->channelData( *it, tileOrigin ) );
	}

	CompoundDataPtr result = shadingEngine->shade( shadingPoints.get() );

	// remove results that aren't suitable to become channels
	for( CompoundDataMap::iterator it = result->writable().begin(); it != result->writable().end();  )
	{
		CompoundDataMap::iterator nextIt = it; nextIt++;
		if( !runTimeCast<FloatVectorData>( it->second ) )
		{
			result->writable().erase( it );
		}
		it = nextIt;
	}

	return result;
}
Example #19
0
ObjectPtr BINMeshReader::doOperation( const CompoundObject *operands )
{
	const std::string &fileName = m_fileNameParameter->getTypedValue();
	ifstream f( fileName.c_str() );

	f.seekg( 0, ios_base::beg );
	uint32_t magic = 0;
	readLittleEndian( f, magic );

	uint32_t version = 0;
	readLittleEndian( f, version );
	if ( version <= 3 )
	{
		throw IOException(( boost::format( "BINMeshReader: '%s' is of an unsupported version" ) % fileName ).str() );
	}

	MeshPrimitivePtr mesh = new MeshPrimitive();

	uint32_t numVertices = 0;

	bool foundGeometryChunk = false;
	bool done = false;

	uint32_t chunkId = 0;

	while ( !done && !f.fail() )
	{
		readLittleEndian( f, chunkId );
		if ( f.fail() )
		{
			throw IOException(( boost::format( "BINMeshReader: Error encountered while reading '%s'" ) % fileName ).str() );
		}

		if ( chunkId == 0xDEDEDEDE ) /// EOF marker
		{
			if ( !foundGeometryChunk )
			{
				throw IOException(( boost::format( "BINMeshReader: No geometry chunk encountered while reading '%s'" ) % fileName ).str() );
			}
			done = true;
		}
		else if ( chunkId == 0xCCCCCCCC ) /// geometry chunk
		{
			if ( foundGeometryChunk )
			{
				throw IOException(( boost::format( "BINMeshReader: Duplicate geometry chunk encountered while reading '%s'" ) % fileName ).str() );
			}
			foundGeometryChunk = true;

			V3fVectorDataPtr pData = new V3fVectorData();

			readLittleEndian( f, numVertices );

			pData->writable().resize( numVertices );
			for ( uint32_t i = 0; i < numVertices; i ++ )
			{
				V3f p;
				readLittleEndian( f, p.x );
				readLittleEndian( f, p.y );
				readLittleEndian( f, p.z );

				pData->writable()[i] = p;
			}


			uint32_t numFaces = 0;
			readLittleEndian( f, numFaces );

			IntVectorDataPtr vertsPerFaceData = new IntVectorData();

			/// All faces are triangles
			vertsPerFaceData->writable().resize( numFaces, 3 );

			IntVectorDataPtr vertIdsData = new IntVectorData();
			vertIdsData->writable().reserve( numFaces * 3 );

			for ( uint32_t i = 0; i < numFaces; i ++ )
			{
				uint32_t v0 = 0, v1 = 0, v2 = 0;
				readLittleEndian( f, v0 );
				readLittleEndian( f, v1 );
				readLittleEndian( f, v2 );

				vertIdsData->writable().push_back( v0 );
				vertIdsData->writable().push_back( v1 );
				vertIdsData->writable().push_back( v2 );
			}

			mesh->variables[ "P" ] = PrimitiveVariable( PrimitiveVariable::Vertex, pData );
			mesh->setTopology( vertsPerFaceData, vertIdsData, "linear" );

		}
		else if ( chunkId == 0xCCCCCC00 ) /// texture chunk
		{
			if ( !foundGeometryChunk )
			{
				throw IOException(( boost::format( "BINMeshReader: No geometry chunk encountered while reading '%s'" ) % fileName ).str() );
			}

			uint32_t numFluids = 0;
			readLittleEndian( f, numFluids );

			V3fVectorDataPtr uvwData = new V3fVectorData();
			uvwData->writable().resize( numVertices );

			for ( uint32_t v = 0; v < numVertices; v ++ )
			{
				for ( uint32_t fl = 0; fl < numFluids - 1; fl ++ )
				{
					/// Just skip over there for now
					/// \todo Work out what to do with them
					float textureWeight = 0.0f;
					readLittleEndian( f, textureWeight );
				}

				V3f uvw;
				readLittleEndian( f, uvw.x );
				readLittleEndian( f, uvw.y );
				readLittleEndian( f, uvw.z );

				uvwData->writable()[v] = uvw;
			}

			mesh->variables[ "uvw" ] = PrimitiveVariable( PrimitiveVariable::Vertex, uvwData );
		}
		else if ( chunkId == 0xCCCCCC11 ) /// velocity chunk
		{
			if ( !foundGeometryChunk )
			{
				throw IOException(( boost::format( "BINMeshReader: No geometry chunk encountered while reading '%s'" ) % fileName ).str() );
			}

			V3fVectorDataPtr velocityData = new V3fVectorData();
			velocityData->writable().resize( numVertices );
			for ( uint32_t i = 0; i < numVertices; i ++ )
			{
				V3f vel;
				readLittleEndian( f, vel.x );
				readLittleEndian( f, vel.y );
				readLittleEndian( f, vel.z );

				velocityData->writable()[i] = vel;
			}
			mesh->variables[ "velocity" ] = PrimitiveVariable( PrimitiveVariable::Vertex, velocityData );
		}
		else
		{
			throw IOException(( boost::format( "BINMeshReader: Invalid chunk encountered while reading '%s'" ) % fileName ).str() );
		}
	}

	if ( chunkId != 0xDEDEDEDE )
	{
		throw IOException(( boost::format( "BINMeshReader: No end of file chunk encountered while reading '%s'" ) % fileName ).str() );
	}

	assert( mesh );
	return mesh;
}
Example #20
0
ObjectPtr SLOReader::doOperation( const CompoundObject * operands )
{
	tbb::mutex::scoped_lock lock( g_mutex );
	
	if( Slo_SetShader( (char *)fileName().c_str() ) )
	{
		throw Exception( boost::str( boost::format( "Unable to set shader to \"%s\"" ) % fileName() ) );
	}

	string name = Slo_GetName();
	string type = Slo_TypetoStr( Slo_GetType() );
	ShaderPtr result = new Shader( name, type );

	CompoundDataPtr typeHints = new CompoundData;
	result->blindData()->writable().insert( pair<string, DataPtr>( "ri:parameterTypeHints", typeHints ) );

	// we lose the ordering of parameter names when we put them in result->parameters(),
	// so we stick the correct order in the blind data as a workaround for anyone interested
	// in the true ordering.
	StringVectorDataPtr orderedParameterNames = new StringVectorData;
	result->blindData()->writable().insert( pair<string, DataPtr>( "ri:orderedParameterNames", orderedParameterNames ) );	

	// we don't have a way of communicating which parameters are outputs in the Shader::parametersData(),
	// so we work around that using the blind data too.
	StringVectorDataPtr outputParameterNames = new StringVectorData;
	result->blindData()->writable().insert( pair<string, DataPtr>( "ri:outputParameterNames", outputParameterNames ) );	

	int numArgs = Slo_GetNArgs();
	for( int i=1; i<=numArgs; i++ )
	{
		DataPtr data = 0;

		SLO_VISSYMDEF *arg = Slo_GetArgById( i );
		switch( arg->svd_type )
		{
			case SLO_TYPE_POINT :
			case SLO_TYPE_VECTOR :
			case SLO_TYPE_NORMAL :
				{
					if( arg->svd_arraylen==0 )
					{
						const SLO_POINT *p = arg->svd_default.pointval;
						if( p )
						{
							data = new V3fData( V3f( p->xval, p->yval, p->zval ) );
						}
						else
						{
							// 0 length and null value signifies a variable length array
							data = new V3fVectorData();
						}
					}
					else
					{
						V3fVectorDataPtr vData = new V3fVectorData();
						data = vData;
						for( int j=0; j<arg->svd_arraylen; j++ )
						{
							SLO_VISSYMDEF *a = Slo_GetArrayArgElement( arg, j );
							const SLO_POINT *p = a->svd_default.pointval;
							vData->writable().push_back( V3f( p->xval, p->yval, p->zval ) );
						}
					}
					typeHints->writable().insert( pair<string, DataPtr>( arg->svd_name, new StringData( Slo_TypetoStr( arg->svd_type ) ) ) );
					break;
				}

			case SLO_TYPE_COLOR :
				{
					if( arg->svd_arraylen==0 )
					{
						const SLO_POINT *p = arg->svd_default.pointval;
						if( p )
						{
							data = new Color3fData( Color3f( p->xval, p->yval, p->zval ) );
						}
						else
						{
							// 0 length and null value signifies a variable length array
							data = new Color3fVectorData();
						}
					}
					else
					{
						Color3fVectorDataPtr vData = new Color3fVectorData();
						data = vData;
						for( int j=0; j<arg->svd_arraylen; j++ )
						{
							SLO_VISSYMDEF *a = Slo_GetArrayArgElement( arg, j );
							const SLO_POINT *p = a->svd_default.pointval;
							vData->writable().push_back( Color3f( p->xval, p->yval, p->zval ) );
						}
					}
				}
				break;

			case SLO_TYPE_SCALAR :
				{
					if( arg->svd_arraylen==0 )
					{
						const float *value = arg->svd_default.scalarval;
						if( value )
						{
							data = new FloatData( *value );
						}
						else
						{
							// 0 length and null value signifies a variable length array
							data = new FloatVectorData();
						}
					}
					else
					{
						FloatVectorDataPtr vData = new FloatVectorData();
						data = vData;
						for( int j=0; j<arg->svd_arraylen; j++ )
						{
							SLO_VISSYMDEF *a = Slo_GetArrayArgElement( arg, j );
							vData->writable().push_back( *(a->svd_default.scalarval) );
						}
						if( arg->svd_arraylen==3 )
						{
							// allow V3fData and V3fVectorData to be mapped to float[3] parameters.
							typeHints->writable().insert( pair<string, DataPtr>( arg->svd_name, new StringData( "float[3]" ) ) );
						}
					}
				}
				break;

			case SLO_TYPE_STRING :
				{
					if( arg->svd_arraylen==0 )
					{
						const char *defaultValue = arg->svd_default.stringval;
						if( defaultValue )
						{
							data = new StringData( defaultValue );
						}
						else
						{
							// 0 length and null value signifies a variable length array
							data = new StringVectorData();
						}
					}
					else
					{
						StringVectorDataPtr vData = new StringVectorData();
						data = vData;
						for( int j=0; j<arg->svd_arraylen; j++ )
						{
							SLO_VISSYMDEF *a = Slo_GetArrayArgElement( arg, j );
							// sometimes the default value for an element of a string array can be a null pointer.
							// i'm not sure what the meaning of this is. the 3delight shaderinfo utility reports such values
							// as "(null)", so that's what we do too.
							const char *defaultValue = a->svd_default.stringval;
							vData->writable().push_back( defaultValue ? defaultValue : "(null)" );
						}
					}
				}
				break;

			case SLO_TYPE_MATRIX :
				{
					if( arg->svd_arraylen==0 )
					{
						const float *m = arg->svd_default.matrixval;
						if( m )
						{
							M44f mm(	m[0], m[1], m[2], m[3],
										m[4], m[5], m[6], m[7],
										m[8], m[9], m[10], m[11],
										m[12], m[13], m[14], m[15] 	);
							data = new M44fData( mm );
						}
						else
						{
							// 0 length and null value signifies a variable length array
							data = new M44fVectorData();
						}
					}
					else
					{
						M44fVectorDataPtr vData = new M44fVectorData();
						data = vData;
						for( int j=0; j<arg->svd_arraylen; j++ )
						{
							SLO_VISSYMDEF *a = Slo_GetArrayArgElement( arg, j );
							const float *m = a->svd_default.matrixval;
							M44f mm(	m[0], m[1], m[2], m[3],
										m[4], m[5], m[6], m[7],
										m[8], m[9], m[10], m[11],
										m[12], m[13], m[14], m[15] 	);
							vData->writable().push_back( mm );
						}
					}
				}
				break;
				
			case SLO_TYPE_SHADER :
				{
					if( arg->svd_arraylen==0 )
					{
						if( !arg->svd_valisvalid )
						{
							// variable length array
							data = new StringVectorData();
						}
						else
						{
							data = new StringData();
						}
					}
					else
					{
						StringVectorDataPtr sData = new StringVectorData();
						data = sData;
						sData->writable().resize( arg->svd_arraylen );
					}
					typeHints->writable().insert( pair<string, DataPtr>( arg->svd_name, new StringData( Slo_TypetoStr( arg->svd_type ) ) ) );
				}
				break;

			default :

				msg( Msg::Warning, "SLOReader::read", format( "Parameter \"%s\" has unsupported type." ) % arg->svd_name );
		}

		if( data )
		{
			orderedParameterNames->writable().push_back( arg->svd_name );
			result->parameters().insert( CompoundDataMap::value_type( arg->svd_name, data ) );
			if( arg->svd_storage == SLO_STOR_OUTPUTPARAMETER )
			{
				outputParameterNames->writable().push_back( arg->svd_name );
			}
		}

	}

	// shader annotations
	
	CompoundDataPtr annotations = new CompoundData;
	result->blindData()->writable().insert( pair<string, DataPtr>( "ri:annotations", annotations ) );
	
#ifndef PRMANEXPORT
	for( int i=1, n=Slo_GetNAnnotations(); i <= n; i++ )
	{
		const char *key = Slo_GetAnnotationKeyById( i );
		annotations->writable()[key] = new StringData( Slo_GetAnnotationByKey( key ) );
	}
#endif

	Slo_EndShader();
	return result;
}
IECoreGL::ConstRenderablePtr StandardLightVisualiser::colorIndicator( const Imath::Color3f &color, bool faceCamera )
{

    float maxChannel = std::max( color[0], std::max( color[1], color[2] ) );
    float exposure = 0;
    Imath::Color3f indicatorColor = color;
    if( maxChannel > 1 )
    {
        indicatorColor = color / maxChannel;
        exposure = log( maxChannel ) / log( 2 );
    }
    IECoreGL::GroupPtr group = new IECoreGL::Group();
    IECoreGL::GroupPtr wirelessGroup = new IECoreGL::Group();

    IECore::CompoundObjectPtr parameters = new CompoundObject;
    parameters->members()["aimType"] = new IntData( 1 );
    group->getState()->add(
        new IECoreGL::ShaderStateComponent( ShaderLoader::defaultShaderLoader(), TextureLoader::defaultTextureLoader(), faceCamera ? faceCameraVertexSource() : "", "", IECoreGL::Shader::constantFragmentSource(), parameters )
    );

    wirelessGroup->getState()->add( new IECoreGL::Primitive::DrawWireframe( false ) );

    float indicatorRad = 0.3;
    int indicatorAxis = faceCamera ? 0 : 2;

    {
        IntVectorDataPtr vertsPerPoly = new IntVectorData;
        IntVectorDataPtr vertIds = new IntVectorData;
        V3fVectorDataPtr p = new V3fVectorData;

        addSolidArc( indicatorAxis, V3f( 0 ), indicatorRad, indicatorRad * 0.9, 0, 1, vertsPerPoly->writable(), vertIds->writable(), p->writable() );

        IECore::MeshPrimitivePtr mesh = new IECore::MeshPrimitive( vertsPerPoly, vertIds, "linear", p );
        mesh->variables["N"] = IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new V3fData( V3f( 0 ) ) );
        mesh->variables["Cs"] = IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new Color3fData( indicatorColor ) );
        ToGLMeshConverterPtr meshConverter = new ToGLMeshConverter( mesh );
        group->addChild( IECore::runTimeCast<IECoreGL::Renderable>( meshConverter->convert() ) );
    }
    {
        IntVectorDataPtr vertsPerPoly = new IntVectorData;
        IntVectorDataPtr vertIds = new IntVectorData;
        V3fVectorDataPtr p = new V3fVectorData;

        addSolidArc( indicatorAxis, V3f( 0 ), indicatorRad * 0.4, 0.0, 0, 1, vertsPerPoly->writable(), vertIds->writable(), p->writable() );

        for( int i = 0; i < exposure && i < 20; i++ )
        {
            float startAngle = 1 - pow( 0.875, i );
            float endAngle = 1 - pow( 0.875, std::min( i+1.0, (double)exposure ) );
            float maxEndAngle = 1 - pow( 0.875, i+1.0);
            float sectorScale = ( maxEndAngle - startAngle - 0.008 ) / ( maxEndAngle - startAngle );
            addSolidArc( indicatorAxis, V3f( 0 ), indicatorRad * 0.85, indicatorRad * 0.45, startAngle, startAngle + ( endAngle - startAngle ) * sectorScale, vertsPerPoly->writable(), vertIds->writable(), p->writable() );
        }

        IECore::MeshPrimitivePtr mesh = new IECore::MeshPrimitive( vertsPerPoly, vertIds, "linear", p );
        mesh->variables["N"] = IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new V3fData( V3f( 0 ) ) );
        mesh->variables["Cs"] = IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new Color3fData( indicatorColor ) );
        ToGLMeshConverterPtr meshConverter = new ToGLMeshConverter( mesh );
        wirelessGroup->addChild( IECore::runTimeCast<IECoreGL::Renderable>( meshConverter->convert() ) );
    }

    // For exposures greater than 20, draw an additional solid bar of a darker color at the very end, without any segment dividers
    if( exposure > 20 )
    {
        IntVectorDataPtr vertsPerPoly = new IntVectorData;
        IntVectorDataPtr vertIds = new IntVectorData;
        V3fVectorDataPtr p = new V3fVectorData;

        float startAngle = 1 - pow( 0.875, 20 );
        float endAngle = 1 - pow( 0.875, (double)exposure );
        addSolidArc( indicatorAxis, V3f( 0 ), indicatorRad * 0.85, indicatorRad * 0.45, startAngle, endAngle, vertsPerPoly->writable(), vertIds->writable(), p->writable() );

        IECore::MeshPrimitivePtr mesh = new IECore::MeshPrimitive( vertsPerPoly, vertIds, "linear", p );
        mesh->variables["N"] = IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new V3fData( V3f( 0 ) ) );
        mesh->variables["Cs"] = IECore::PrimitiveVariable( IECore::PrimitiveVariable::Constant, new Color3fData( 0.5f * indicatorColor ) );
        ToGLMeshConverterPtr meshConverter = new ToGLMeshConverter( mesh );
        wirelessGroup->addChild( IECore::runTimeCast<IECoreGL::Renderable>( meshConverter->convert() ) );
    }

    group->addChild( wirelessGroup );

    return group;
}
Example #22
0
MeshPrimitivePtr MeshPrimitive::createSphere( float radius, float zMin, float zMax, float thetaMax, const Imath::V2i &divisions )
{
    IntVectorDataPtr vertexIds = new IntVectorData;
    IntVectorDataPtr verticesPerFace = new IntVectorData;
    std::vector<int> &vpf = verticesPerFace->writable();
    std::vector<int> &vIds = vertexIds->writable();

    V3fVectorDataPtr pData = new V3fVectorData;
    V3fVectorDataPtr nData = new V3fVectorData;
    std::vector<V3f> &pVector = pData->writable();
    std::vector<V3f> &nVector = nData->writable();

    FloatVectorDataPtr sData = new FloatVectorData;
    FloatVectorDataPtr tData = new FloatVectorData;
    std::vector<float> &sVector = sData->writable();
    std::vector<float> &tVector = tData->writable();

    float oMin = Math<float>::asin( zMin );
    float oMax = Math<float>::asin( zMax );
    const unsigned int nO = max( 4u, (unsigned int)( ( divisions.x + 1 ) * (oMax - oMin) / M_PI ) );

    float thetaMaxRad = thetaMax / 180.0f * M_PI;
    const unsigned int nT = max( 7u, (unsigned int)( ( divisions.y + 1 ) * thetaMaxRad / (M_PI*2) ) );

    for ( unsigned int i=0; i<nO; i++ )
    {
        float v = (float)i/(float)(nO-1);
        float o = lerp( oMin, oMax, v );
        float z = radius * Math<float>::sin( o );
        float r = radius * Math<float>::cos( o );

        for ( unsigned int j=0; j<nT; j++ )
        {
            float u = (float)j/(float)(nT-1);
            float theta = thetaMaxRad * u;
            V3f p( r * Math<float>::cos( theta ), r * Math<float>::sin( theta ), z );
            sVector.push_back( u );
            tVector.push_back( v );
            pVector.push_back( p );
            nVector.push_back( p );
            if( i < nO - 1 && j < nT - 1 )
            {
                unsigned int i0 = i * nT + j;
                unsigned int i1 = i0 + 1;
                unsigned int i2 = i0 + nT;
                unsigned int i3 = i2 + 1;
                vpf.push_back( 3 );
                vIds.push_back( i0 );
                vIds.push_back( i1 );
                vIds.push_back( i2 );
                vpf.push_back( 3 );
                vIds.push_back( i1 );
                vIds.push_back( i3 );
                vIds.push_back( i2 );
            }
        }
    }

    MeshPrimitivePtr result = new MeshPrimitive( verticesPerFace, vertexIds, "linear", pData );
    result->variables["N"] = PrimitiveVariable( PrimitiveVariable::Vertex, nData );
    result->variables["s"] = PrimitiveVariable( PrimitiveVariable::Vertex, sData );
    result->variables["t"] = PrimitiveVariable( PrimitiveVariable::Vertex, tData );

    return result;
}
Example #23
0
MeshPrimitivePtr MeshPrimitive::createPlane( const Box2f &b, const Imath::V2i &divisions )
{
    V3fVectorDataPtr pData = new V3fVectorData;
    std::vector<V3f> &p = pData->writable();

    // add vertices
    float xStep = b.size().x / (float)divisions.x;
    float yStep = b.size().y / (float)divisions.y;
    for ( int i = 0; i <= divisions.y; ++i )
    {
        for ( int j = 0; j <= divisions.x; ++j )
        {
            p.push_back( V3f( b.min.x + j * xStep, b.min.y + i * yStep, 0 ) );
        }
    }

    IntVectorDataPtr vertexIds = new IntVectorData;
    IntVectorDataPtr verticesPerFace = new IntVectorData;
    std::vector<int> &vpf = verticesPerFace->writable();
    std::vector<int> &vIds = vertexIds->writable();

    FloatVectorDataPtr sData = new FloatVectorData;
    FloatVectorDataPtr tData = new FloatVectorData;
    std::vector<float> &s = sData->writable();
    std::vector<float> &t = tData->writable();

    float sStep = 1.0f / (float)divisions.x;
    float tStep = 1.0f / (float)divisions.y;

    // add faces
    int v0, v1, v2, v3;
    for ( int i = 0; i < divisions.y; ++i )
    {
        for ( int j = 0; j < divisions.x; ++j )
        {
            v0 = j + (divisions.x+1) * i;
            v1 = j + 1 + (divisions.x+1) * i;;
            v2 = j + 1 + (divisions.x+1) * (i+1);
            v3 = j + (divisions.x+1) * (i+1);

            vpf.push_back( 4 );
            vIds.push_back( v0 );
            vIds.push_back( v1 );
            vIds.push_back( v2 );
            vIds.push_back( v3 );

            s.push_back( j * sStep );
            s.push_back( (j+1) * sStep );
            s.push_back( (j+1) * sStep );
            s.push_back( j * sStep );

            t.push_back( 1 - i * tStep );
            t.push_back( 1 - i * tStep );
            t.push_back( 1 - (i+1) * tStep );
            t.push_back( 1 - (i+1) * tStep );
        }
    }

    MeshPrimitivePtr result = new MeshPrimitive( verticesPerFace, vertexIds, "linear", pData );
    result->variables["s"] = PrimitiveVariable( PrimitiveVariable::FaceVarying, sData );
    result->variables["t"] = PrimitiveVariable( PrimitiveVariable::FaceVarying, tData );

    return result;
}
Example #24
0
void SceneProcedural::drawCamera( const IECore::Camera *camera, IECore::Renderer *renderer ) const
{
	CameraPtr fullCamera = camera->copy();
	fullCamera->addStandardParameters();
	
	AttributeBlock attributeBlock( renderer );

	renderer->setAttribute( "gl:primitive:wireframe", new BoolData( true ) );
	renderer->setAttribute( "gl:primitive:solid", new BoolData( false ) );
	renderer->setAttribute( "gl:curvesPrimitive:useGLLines", new BoolData( true ) );
	renderer->setAttribute( "gl:primitive:wireframeColor", new Color4fData( Color4f( 0, 0.25, 0, 1 ) ) );

	CurvesPrimitive::createBox( Box3f(
		V3f( -0.5, -0.5, 0 ),
		V3f( 0.5, 0.5, 2.0 )		
	) )->render( renderer );

	const std::string &projection = fullCamera->parametersData()->member<StringData>( "projection" )->readable();
	const Box2f &screenWindow = fullCamera->parametersData()->member<Box2fData>( "screenWindow" )->readable();
	/// \todo When we're drawing the camera by some means other than creating a primitive for it,
	/// use the actual clippings planes. Right now that's not a good idea as it results in /huge/
	/// framing bounds when the viewer frames a selected camera.
	V2f clippingPlanes( 0, 5 );
	
	Box2f near( screenWindow );
	Box2f far( screenWindow );
	
	if( projection == "perspective" )
	{
		float fov = fullCamera->parametersData()->member<FloatData>( "projection:fov" )->readable();
		float d = tan( degreesToRadians( fov / 2.0f ) );
		near.min *= d * clippingPlanes[0];
		near.max *= d * clippingPlanes[0];
		far.min *= d * clippingPlanes[1];
		far.max *= d * clippingPlanes[1];
	}
			
	V3fVectorDataPtr p = new V3fVectorData;
	IntVectorDataPtr n = new IntVectorData;
	
	n->writable().push_back( 5 );
	p->writable().push_back( V3f( near.min.x, near.min.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( near.max.x, near.min.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( near.max.x, near.max.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( near.min.x, near.max.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( near.min.x, near.min.y, -clippingPlanes[0] ) );

	n->writable().push_back( 5 );
	p->writable().push_back( V3f( far.min.x, far.min.y, -clippingPlanes[1] ) );
	p->writable().push_back( V3f( far.max.x, far.min.y, -clippingPlanes[1] ) );
	p->writable().push_back( V3f( far.max.x, far.max.y, -clippingPlanes[1] ) );
	p->writable().push_back( V3f( far.min.x, far.max.y, -clippingPlanes[1] ) );
	p->writable().push_back( V3f( far.min.x, far.min.y, -clippingPlanes[1] ) );

	n->writable().push_back( 2 );
	p->writable().push_back( V3f( near.min.x, near.min.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( far.min.x, far.min.y, -clippingPlanes[1] ) );

	n->writable().push_back( 2 );
	p->writable().push_back( V3f( near.max.x, near.min.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( far.max.x, far.min.y, -clippingPlanes[1] ) );

	n->writable().push_back( 2 );
	p->writable().push_back( V3f( near.max.x, near.max.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( far.max.x, far.max.y, -clippingPlanes[1] ) );
	
	n->writable().push_back( 2 );
	p->writable().push_back( V3f( near.min.x, near.max.y, -clippingPlanes[0] ) );
	p->writable().push_back( V3f( far.min.x, far.max.y, -clippingPlanes[1] ) );
	
	CurvesPrimitivePtr c = new IECore::CurvesPrimitive( n, CubicBasisf::linear(), false, p );
	c->render( renderer );
}
Example #25
0
std::pair<PrimitiveVariable, PrimitiveVariable> IECoreScene::MeshAlgo::calculateTangents(
	const MeshPrimitive *mesh,
	const std::string &uvSet, /* = "uv" */
	bool orthoTangents, /* = true */
	const std::string &position /* = "P" */
)
{
	if( mesh->minVerticesPerFace() != 3 || mesh->maxVerticesPerFace() != 3 )
	{
		throw InvalidArgumentException( "MeshAlgo::calculateTangents : MeshPrimitive must only contain triangles" );
	}

	const V3fVectorData *positionData = mesh->variableData<V3fVectorData>( position );
	if( !positionData )
	{
		std::string e = boost::str( boost::format( "MeshAlgo::calculateTangents : MeshPrimitive has no Vertex \"%s\" primitive variable." ) % position );
		throw InvalidArgumentException( e );
	}

	const V3fVectorData::ValueType &points = positionData->readable();

	const IntVectorData *vertsPerFaceData = mesh->verticesPerFace();
	const IntVectorData::ValueType &vertsPerFace = vertsPerFaceData->readable();

	const IntVectorData *vertIdsData = mesh->vertexIds();
	const IntVectorData::ValueType &vertIds = vertIdsData->readable();

	const auto uvIt = mesh->variables.find( uvSet );
	if( uvIt == mesh->variables.end() || uvIt->second.interpolation != PrimitiveVariable::FaceVarying || uvIt->second.data->typeId() != V2fVectorDataTypeId )
	{
		throw InvalidArgumentException( ( boost::format( "MeshAlgo::calculateTangents : MeshPrimitive has no FaceVarying V2fVectorData primitive variable named \"%s\"."  ) % ( uvSet ) ).str() );
	}

	const V2fVectorData *uvData = runTimeCast<V2fVectorData>( uvIt->second.data.get() );
	const V2fVectorData::ValueType &uvs = uvData->readable();

	// I'm a little unsure about using the vertIds as a fallback for the stIndices.
	const IntVectorData::ValueType &uvIndices = uvIt->second.indices ? uvIt->second.indices->readable() : vertIds;

	size_t numUVs = uvs.size();

	std::vector<V3f> uTangents( numUVs, V3f( 0 ) );
	std::vector<V3f> vTangents( numUVs, V3f( 0 ) );
	std::vector<V3f> normals( numUVs, V3f( 0 ) );

	for( size_t faceIndex = 0; faceIndex < vertsPerFace.size(); faceIndex++ )
	{
		assert( vertsPerFace[faceIndex] == 3 );

		// indices into the facevarying data for this face
		size_t fvi0 = faceIndex * 3;
		size_t fvi1 = fvi0 + 1;
		size_t fvi2 = fvi1 + 1;
		assert( fvi2 < vertIds.size() );
		assert( fvi2 < uvIndices.size() );

		// positions for each vertex of this face
		const V3f &p0 = points[vertIds[fvi0]];
		const V3f &p1 = points[vertIds[fvi1]];
		const V3f &p2 = points[vertIds[fvi2]];

		// uv coordinates for each vertex of this face
		const V2f &uv0 = uvs[uvIndices[fvi0]];
		const V2f &uv1 = uvs[uvIndices[fvi1]];
		const V2f &uv2 = uvs[uvIndices[fvi2]];

		// compute tangents and normal for this face
		const V3f e0 = p1 - p0;
		const V3f e1 = p2 - p0;

		const V2f e0uv = uv1 - uv0;
		const V2f e1uv = uv2 - uv0;

		V3f tangent = ( e0 * -e1uv.y + e1 * e0uv.y ).normalized();
		V3f bitangent = ( e0 * -e1uv.x + e1 * e0uv.x ).normalized();

		V3f normal = ( p2 - p1 ).cross( p0 - p1 );
		normal.normalize();

		// and accumlate them into the computation so far
		uTangents[uvIndices[fvi0]] += tangent;
		uTangents[uvIndices[fvi1]] += tangent;
		uTangents[uvIndices[fvi2]] += tangent;

		vTangents[uvIndices[fvi0]] += bitangent;
		vTangents[uvIndices[fvi1]] += bitangent;
		vTangents[uvIndices[fvi2]] += bitangent;

		normals[uvIndices[fvi0]] += normal;
		normals[uvIndices[fvi1]] += normal;
		normals[uvIndices[fvi2]] += normal;

	}

	// normalize and orthogonalize everything
	for( size_t i = 0; i < uTangents.size(); i++ )
	{
		normals[i].normalize();

		uTangents[i].normalize();
		vTangents[i].normalize();

		// Make uTangent/vTangent orthogonal to normal
		uTangents[i] -= normals[i] * uTangents[i].dot( normals[i] );
		vTangents[i] -= normals[i] * vTangents[i].dot( normals[i] );

		uTangents[i].normalize();
		vTangents[i].normalize();

		if( orthoTangents )
		{
			vTangents[i] -= uTangents[i] * vTangents[i].dot( uTangents[i] );
			vTangents[i].normalize();
		}

		// Ensure we have set of basis vectors (n, uT, vT) with the correct handedness.
		if( uTangents[i].cross( vTangents[i] ).dot( normals[i] ) < 0.0f )
		{
			uTangents[i] *= -1.0f;
		}
	}

	// convert the tangents back to facevarying data and add that to the mesh
	V3fVectorDataPtr fvUD = new V3fVectorData();
	V3fVectorDataPtr fvVD = new V3fVectorData();

	std::vector<V3f> &fvU = fvUD->writable();
	std::vector<V3f> &fvV = fvVD->writable();
	fvU.resize( uvIndices.size() );
	fvV.resize( uvIndices.size() );

	for( unsigned i = 0; i < uvIndices.size(); i++ )
	{
		fvU[i] = uTangents[uvIndices[i]];
		fvV[i] = vTangents[uvIndices[i]];
	}

	PrimitiveVariable tangentPrimVar( PrimitiveVariable::FaceVarying, fvUD );
	PrimitiveVariable bitangentPrimVar( PrimitiveVariable::FaceVarying, fvVD );

	return std::make_pair( tangentPrimVar, bitangentPrimVar );
}