<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014, 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 <NAME> 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/filesystem.hpp"
#include "boost/algorithm/string/predicate.hpp"

#include "IECore/PreWorldRenderable.h"
#include "IECore/Camera.h"
#include "IECore/MatrixMotionTransform.h"
#include "IECore/WorldBlock.h"
#include "IECore/Light.h"
#include "IECore/AttributeBlock.h"
#include "IECore/Display.h"
#include "IECore/TransformBlock.h"

#include "Gaffer/Context.h"

#include "GafferScene/RendererAlgo.h"
#include "GafferScene/SceneProcedural.h"
#include "GafferScene/PathMatcherData.h"
#include "GafferScene/SceneAlgo.h"

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

namespace GafferScene
{

void outputScene( const ScenePlug *scene, IECore::Renderer *renderer )
{
	ConstCompoundObjectPtr globals = scene->globalsPlug()->getValue();
	outputOptions( globals.get(), renderer );
	outputOutputs( globals.get(), renderer );
	outputCamera( scene, globals.get(), renderer );
	{
		WorldBlock world( renderer );

		outputGlobalAttributes( globals.get(), renderer );
		outputCoordinateSystems( scene, globals.get(), renderer );
		outputLights( scene, globals.get(), renderer );

		SceneProceduralPtr proc = new SceneProcedural( scene, Context::current() );
		renderer->procedural( proc );
	}
}

void outputOutputs( const IECore::CompoundObject *globals, IECore::Renderer *renderer )
{
	CompoundObject::ObjectMap::const_iterator it, eIt;
	for( it = globals->members().begin(), eIt = globals->members().end(); it != eIt; it++ )
	{
		if( !boost::starts_with( it->first.c_str(), "output:" ) )
		{
			continue;
		}
		if( const Display *d = runTimeCast<Display>( it->second.get() ) )
		{
			d->render( renderer );
		}
		else
		{
			throw IECore::Exception( "Global \"" + it->first.string() + "\" is not an IECore::Display" );
		}
	}
}

void outputOptions( const IECore::CompoundObject *globals, IECore::Renderer *renderer )
{
	CompoundObject::ObjectMap::const_iterator it, eIt;
	for( it = globals->members().begin(), eIt = globals->members().end(); it != eIt; it++ )
	{
		if( !boost::starts_with( it->first.c_str(), "option:" ) )
		{
			continue;
		}
		if( const Data *d = runTimeCast<Data>( it->second.get() ) )
		{
			renderer->setOption( it->first.c_str() + 7, d );
		}
		else
		{
			throw IECore::Exception( "Global \"" + it->first.string() + "\" is not IECore::Data" );
		}
	}
}

void outputCamera( const ScenePlug *scene, const IECore::CompoundObject *globals, IECore::Renderer *renderer )
{
	// get the camera from the scene

	const StringData *cameraPathData = globals->member<StringData>( "option:render:camera" );
	IECore::CameraPtr camera = 0;
	if( cameraPathData )
	{
		ScenePlug::ScenePath cameraPath;
		ScenePlug::stringToPath( cameraPathData->readable(), cameraPath );
		if( !exists( scene, cameraPath ) )
		{
			throw IECore::Exception( "Camera \"" + cameraPathData->readable() + "\" does not exist" );
		}

		IECore::ConstCameraPtr constCamera = runTimeCast<const IECore::Camera>( scene->object( cameraPath ) );
		if( !constCamera )
		{
			throw IECore::Exception( "Location \"" + cameraPathData->readable() + "\" is not a camera" );
		}

		camera = constCamera->copy();
		const BoolData *cameraBlurData = globals->member<BoolData>( "option:render:cameraBlur" );
		const bool cameraBlur = cameraBlurData ? cameraBlurData->readable() : false;
		camera->setTransform( transform( scene, cameraPath, shutter( globals ), cameraBlur ) );
	}

	if( !camera )
	{
		camera = new IECore::Camera();
	}

	// apply the resolution, aspect ratio and crop window

	V2i resolution( 640, 480 );
	if( const V2iData *resolutionData = globals->member<V2iData>( "option:render:resolution" ) )
	{
		resolution = resolutionData->readable();
	}

	if( const FloatData *resolutionMultiplierData = globals->member<FloatData>( "option:render:resolutionMultiplier" ) )
	{
		resolution.x = (float)resolution.x * resolutionMultiplierData->readable();
		resolution.y = (float)resolution.y * resolutionMultiplierData->readable();
	}

	camera->parameters()["resolution"] = new V2iData( resolution );

	const FloatData *pixelAspectRatioData = globals->member<FloatData>( "option:render:pixelAspectRatio" );
	if( pixelAspectRatioData )
	{
		camera->parameters()["pixelAspectRatio"] = pixelAspectRatioData->copy();
	}

	const Box2fData *cropWindowData = globals->member<Box2fData>( "option:render:cropWindow" );
	if( cropWindowData )
	{
		camera->parameters()["cropWindow"] = cropWindowData->copy();
	}

	// calculate an appropriate screen window

	camera->addStandardParameters();

	// apply overscan
	
	const BoolData *overscanData = globals->member<BoolData>( "option:render:overscan" );
	if( overscanData && overscanData->readable() )
	{
		
		// get offsets for each corner of image (as a multiplier of the image width)
		V2f minOffset( 0.1 ), maxOffset( 0.1 );
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanLeft" ) )
		{
			minOffset.x = overscanValueData->readable();
		}
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanRight" ) )
		{
			maxOffset.x = overscanValueData->readable();
		}
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanBottom" ) )
		{
			minOffset.y = overscanValueData->readable();
		}
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanTop" ) )
		{
			maxOffset.y = overscanValueData->readable();
		}
				
		// convert those offsets into pixel values
		
		V2i minPixelOffset(
			minOffset.x * (float)resolution.x,
			minOffset.y * (float)resolution.y
		);
		
		V2i maxPixelOffset(
			maxOffset.x * (float)resolution.x,
			maxOffset.y * (float)resolution.y
		);

		// recalculate original offsets to account for the rounding when
		// converting to integer pixel space
		
		minOffset = V2f(
			(float)minPixelOffset.x / (float)resolution.x,
			(float)minPixelOffset.y / (float)resolution.y
		);
		<commit_msg>Casting the resolution back to ints.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014, 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 <NAME> 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/filesystem.hpp"
#include "boost/algorithm/string/predicate.hpp"

#include "IECore/PreWorldRenderable.h"
#include "IECore/Camera.h"
#include "IECore/MatrixMotionTransform.h"
#include "IECore/WorldBlock.h"
#include "IECore/Light.h"
#include "IECore/AttributeBlock.h"
#include "IECore/Display.h"
#include "IECore/TransformBlock.h"

#include "Gaffer/Context.h"

#include "GafferScene/RendererAlgo.h"
#include "GafferScene/SceneProcedural.h"
#include "GafferScene/PathMatcherData.h"
#include "GafferScene/SceneAlgo.h"

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

namespace GafferScene
{

void outputScene( const ScenePlug *scene, IECore::Renderer *renderer )
{
	ConstCompoundObjectPtr globals = scene->globalsPlug()->getValue();
	outputOptions( globals.get(), renderer );
	outputOutputs( globals.get(), renderer );
	outputCamera( scene, globals.get(), renderer );
	{
		WorldBlock world( renderer );

		outputGlobalAttributes( globals.get(), renderer );
		outputCoordinateSystems( scene, globals.get(), renderer );
		outputLights( scene, globals.get(), renderer );

		SceneProceduralPtr proc = new SceneProcedural( scene, Context::current() );
		renderer->procedural( proc );
	}
}

void outputOutputs( const IECore::CompoundObject *globals, IECore::Renderer *renderer )
{
	CompoundObject::ObjectMap::const_iterator it, eIt;
	for( it = globals->members().begin(), eIt = globals->members().end(); it != eIt; it++ )
	{
		if( !boost::starts_with( it->first.c_str(), "output:" ) )
		{
			continue;
		}
		if( const Display *d = runTimeCast<Display>( it->second.get() ) )
		{
			d->render( renderer );
		}
		else
		{
			throw IECore::Exception( "Global \"" + it->first.string() + "\" is not an IECore::Display" );
		}
	}
}

void outputOptions( const IECore::CompoundObject *globals, IECore::Renderer *renderer )
{
	CompoundObject::ObjectMap::const_iterator it, eIt;
	for( it = globals->members().begin(), eIt = globals->members().end(); it != eIt; it++ )
	{
		if( !boost::starts_with( it->first.c_str(), "option:" ) )
		{
			continue;
		}
		if( const Data *d = runTimeCast<Data>( it->second.get() ) )
		{
			renderer->setOption( it->first.c_str() + 7, d );
		}
		else
		{
			throw IECore::Exception( "Global \"" + it->first.string() + "\" is not IECore::Data" );
		}
	}
}

void outputCamera( const ScenePlug *scene, const IECore::CompoundObject *globals, IECore::Renderer *renderer )
{
	// get the camera from the scene

	const StringData *cameraPathData = globals->member<StringData>( "option:render:camera" );
	IECore::CameraPtr camera = 0;
	if( cameraPathData )
	{
		ScenePlug::ScenePath cameraPath;
		ScenePlug::stringToPath( cameraPathData->readable(), cameraPath );
		if( !exists( scene, cameraPath ) )
		{
			throw IECore::Exception( "Camera \"" + cameraPathData->readable() + "\" does not exist" );
		}

		IECore::ConstCameraPtr constCamera = runTimeCast<const IECore::Camera>( scene->object( cameraPath ) );
		if( !constCamera )
		{
			throw IECore::Exception( "Location \"" + cameraPathData->readable() + "\" is not a camera" );
		}

		camera = constCamera->copy();
		const BoolData *cameraBlurData = globals->member<BoolData>( "option:render:cameraBlur" );
		const bool cameraBlur = cameraBlurData ? cameraBlurData->readable() : false;
		camera->setTransform( transform( scene, cameraPath, shutter( globals ), cameraBlur ) );
	}

	if( !camera )
	{
		camera = new IECore::Camera();
	}

	// apply the resolution, aspect ratio and crop window

	V2i resolution( 640, 480 );
	if( const V2iData *resolutionData = globals->member<V2iData>( "option:render:resolution" ) )
	{
		resolution = resolutionData->readable();
	}

	if( const FloatData *resolutionMultiplierData = globals->member<FloatData>( "option:render:resolutionMultiplier" ) )
	{
		resolution.x = int((float)resolution.x * resolutionMultiplierData->readable());
		resolution.y = int((float)resolution.y * resolutionMultiplierData->readable());
	}

	camera->parameters()["resolution"] = new V2iData( resolution );

	const FloatData *pixelAspectRatioData = globals->member<FloatData>( "option:render:pixelAspectRatio" );
	if( pixelAspectRatioData )
	{
		camera->parameters()["pixelAspectRatio"] = pixelAspectRatioData->copy();
	}

	const Box2fData *cropWindowData = globals->member<Box2fData>( "option:render:cropWindow" );
	if( cropWindowData )
	{
		camera->parameters()["cropWindow"] = cropWindowData->copy();
	}

	// calculate an appropriate screen window

	camera->addStandardParameters();

	// apply overscan
	
	const BoolData *overscanData = globals->member<BoolData>( "option:render:overscan" );
	if( overscanData && overscanData->readable() )
	{
		
		// get offsets for each corner of image (as a multiplier of the image width)
		V2f minOffset( 0.1 ), maxOffset( 0.1 );
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanLeft" ) )
		{
			minOffset.x = overscanValueData->readable();
		}
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanRight" ) )
		{
			maxOffset.x = overscanValueData->readable();
		}
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanBottom" ) )
		{
			minOffset.y = overscanValueData->readable();
		}
		if( const FloatData *overscanValueData = globals->member<FloatData>( "option:render:overscanTop" ) )
		{
			maxOffset.y = overscanValueData->readable();
		}
				
		// convert those offsets into pixel values
		
		V2i minPixelOffset(
			int(minOffset.x * (float)resolution.x),
			int(minOffset.y * (float)resolution.y)
		);
		
		V2i maxPixelOffset(
			int(maxOffset.x * (float)resolution.x),
			int(maxOffset.y * (float)resolution.y)
		);

		// recalculate original offsets to account for the rounding when
		// converting to integer pixel space
		
		minOffset = V2f(
			(float)minPixelOffset.x / (float)resolution.x,
			(float)minPixelOffset.y / (float)resolution.y
		);
		
{'fraction_non_alphanumeric': 0.1468836077125104, 'fraction_numerical': 0.003330984562167702, 'mean_word_length': 3.8833281201126058, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 129, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '950601', 'n_tokens_mistral': 5162, 'n_tokens_neox': 4746, 'n_words': 1275}