<commit_before>/**
 * @file precipitation.cpp
 *
 * @date Jan 28, 2012
 * @author partio
 */

#include "precipitation.h"
#include <iostream>
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "fetcher.h"
#include "writer.h"
#include "neons.h"
#include "pcuda.h"

#undef HIMAN_AUXILIARY_INCLUDE

#ifdef DEBUG
#include "timer_factory.h"
#endif

using namespace std;
using namespace himan::plugin;

precipitation::precipitation() : itsUseCuda(false)
{
	itsClearTextFormula = "RR = RR_cur - RR_prev";

	itsLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("precipitation"));

}

void precipitation::Process(std::shared_ptr<const plugin_configuration> conf)
{

	shared_ptr<plugin::pcuda> c = dynamic_pointer_cast<plugin::pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

	if (c->HaveCuda())
	{
		string msg = "I possess the powers of CUDA";

		if (!conf->UseCuda())
		{
			msg += ", but I won't use them";
		}
		else
		{
			msg += ", and I'm not afraid to use them";
			itsUseCuda = true;
		}

		itsLogger->Info(msg);

	}

	// Get number of threads to use

	unsigned short threadCount = ThreadCount(conf->ThreadCount());

	boost::thread_group g;

	shared_ptr<info> targetInfo = conf->Info();

	/*
	 * Set target parameter to precipitation.
	 *
	 * We need to specify grib and querydata parameter information
	 * since we don't know which one will be the output format.
	 *
	 */

	vector<param> params;

	//param requestedParam ("RR-1-MM", 353);
	param requestedParam ("RR-3-MM", 354);
	//param requestedParam ("RR-6-MM", 355);

	// GRIB 1

	if (conf->OutputFileType() == kGRIB1)
	{
		shared_ptr<neons> n = dynamic_pointer_cast<neons> (plugin_factory::Instance()->Plugin("neons"));

		long parm_id = n->NeonsDB().GetGridParameterId(targetInfo->Producer().TableVersion(), requestedParam.Name());
		requestedParam.GribIndicatorOfParameter(parm_id);
		requestedParam.GribTableVersion(targetInfo->Producer().TableVersion());

	}
	params.push_back(requestedParam);

	targetInfo->Params(params);

	/*
	 * Create data structures.
	 */

	targetInfo->Create();

	/*
	 * Initialize parent class functions for dimension handling
	 */

	Dimension(kLevelDimension);
	FeederInfo(shared_ptr<info> (new info(*targetInfo)));
	FeederInfo()->Param(requestedParam);

	/*
	 * Each thread will have a copy of the target info.
	 */

	vector<shared_ptr<info> > targetInfos;

	targetInfos.resize(threadCount);

	for (size_t i = 0; i < threadCount; i++)
	{

		itsLogger->Info("Thread " + boost::lexical_cast<string> (i + 1) + " starting");

		targetInfos[i] = shared_ptr<info> (new info(*targetInfo));

		boost::thread* t = new boost::thread(&precipitation::Run,
											 this,
											 targetInfos[i],
											 conf,
											 i + 1);

		g.add_thread(t);

	}

	g.join_all();

	if (conf->FileWriteOption() == kSingleFile)
	{

		shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

		string theOutputFile = conf->ConfigurationFile();

		theWriter->ToFile(targetInfo, conf, theOutputFile);

	}
}

void precipitation::Run(shared_ptr<info> myTargetInfo,
			   shared_ptr<const plugin_configuration> conf,
			   unsigned short threadIndex)
{

	while (AdjustLeadingDimension(myTargetInfo))
	{
		Calculate(myTargetInfo, conf, threadIndex);
	}

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void precipitation::Calculate(shared_ptr<info> myTargetInfo,
					 shared_ptr<const plugin_configuration> conf,
					 unsigned short threadIndex)
{

	unique_ptr<logger> myThreadedLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("precipitationThread #" + boost::lexical_cast<string> (threadIndex)));

	ResetNonLeadingDimension(myTargetInfo);

	myTargetInfo->FirstParam();

	long paramStep;

	if (myTargetInfo->Param().Name() == "RR-1-MM")
	{
		paramStep = 1;
	}
	else if (myTargetInfo->Param().Name() == "RR-3-MM")
	{
		paramStep = 3;
	}
	else if (myTargetInfo->Param().Name() == "RR-6-MM")
	{
		paramStep = 6;
	}
	else if (myTargetInfo->Param().Name() == "RR-12-MM")
	{
		paramStep = 12;
	}
	else
	{
		throw runtime_error(ClassName() + ": Unsupported parameter: " + myTargetInfo->Param().Name());
	}

	shared_ptr<info> prevInfo;

	bool dataFoundFromRRParam = true; // Assume that we have parameter RR-KGM2 present

	while (AdjustNonLeadingDimension(myTargetInfo))
	{

		assert(myTargetInfo->Time().StepResolution() == kHour);

		/*
		 * We only calculate data for certain times (based on parameter time step),
		 * but user may have specified time steps that are between parameter time steps.
		 * Those timesteps need to be resized and filled with missing values.
		 */

		myTargetInfo->Data()->Fill(kFloatMissing); // Fill data with missing value

		if (myTargetInfo->Time().Step() % paramStep != 0)
		{
			continue;
		}

		shared_ptr<info> RRInfo;

		try
		{
			if (!prevInfo || myTargetInfo->Time().Step() - prevInfo->Time().Step() != paramStep)
			{

				/*
				 * If this is the first time this loop executed, or if the previous data is not suitable
				 * for calculating against current time step data, fetch source data.
				 */

				forecast_time prevTimeStep = myTargetInfo->Time();

				if (prevTimeStep.Step() >= paramStep)
				{
					prevTimeStep.ValidDateTime()->Adjust(kHourResolution, -paramStep);

					prevInfo = FetchSourcePrecipitation(conf,prevTimeStep,myTargetInfo->Level(),dataFoundFromRRParam);
				}
				else
				{
					continue;
				}
			}

			// Get data for current step

			RRInfo = FetchSourcePrecipitation(conf,myTargetInfo->Time(),myTargetInfo->Level(),dataFoundFromRRParam);

		}
		catch (HPExceptionType e)
		{
			switch (e)
			{
				case kFileDataNotFound:
					itsLogger->Info("Skipping step " + boost::lexical_cast<string> (myTargetInfo->Time().Step()) + ", level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));
					continue;
					break;

				default:
					throw runtime_error(ClassName() + ": Unable to proceed");
					break;
			}
		}

		myThreadedLogger->Debug("Calculating time " + myTargetInfo->Time().ValidDateTime()->String("%Y%m%d%H") +
											  " level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));

		shared_ptr<NFmiGrid> RRGrid(RRInfo->Grid()->ToNewbaseGrid());
		shared_ptr<NFmiGrid> prevGrid(prevInfo->Grid()->ToNewbaseGrid());

		shared_ptr<NFmiGrid> targetGrid(myTargetInfo->Grid()->ToNewbaseGrid());

		int missingCount = 0;
		int count = 0;

		bool equalGrids = (*myTargetInfo->Grid() == *RRInfo->Grid());

		if (true)
		{

			assert(targetGrid->Size() == myTargetInfo->Data()->Size());

			myTargetInfo->ResetLocation();

			targetGrid->Reset();
			prevGrid->Reset();

#ifdef DEBUG
			unique_ptr<timer> t = unique_ptr<timer> (timer_factory::Instance()->GetTimer());
			t->Start();
#endif

			while (myTargetInfo->NextLocation() && targetGrid->Next() && prevGrid->Next())
			{
				count++;

				double RRcur = kFloatMissing;
				double RRprev = kFloatMissing;

				InterpolateToPoint(targetGrid, RRGrid, equalGrids, RRcur);
				InterpolateToPoint(targetGrid, prevGrid, equalGrids, RRprev);

				if (RRcur == kFloatMissing || RRprev == kFloatMissing)
				{
					missingCount++;

					myTargetInfo->Value(kFloatMissing);
					continue;
				}

				double RR = RRcur - RRprev;

				if (RR < 0)
				{
					RR = 0;
				}

				if (!myTargetInfo->Value(RR))
				{
					throw runtime_error(ClassName() + ": Failed to set value to matrix");
				}

			}

			prevInfo = RRInfo;

#ifdef DEBUG
			t->Stop();
			itsLogger->Debug("Calculation took " + boost::lexical_cast<string> (t->GetTime()) + " microseconds on CPU");
#endif
		}

		/*
		 * Now we are done for this level
		 *
		 * Clone info-instance to writer since it might change our descriptor places
		 */

		myThreadedLogger->Info("Missing values: " + boost::lexical_cast<string> (missingCount) + "/" + boost::lexical_cast<string> (count));

		if (conf->FileWriteOption() == kNeons || conf->FileWriteOption() == kMultipleFiles)
		{
			shared_ptr<writer> w = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

			w->ToFile(shared_ptr<info> (new info(*myTargetInfo)), conf);
		}
	}
}

shared_ptr<himan::info> precipitation::FetchSourcePrecipitation(shared_ptr<const plugin_configuration> conf, const forecast_time& wantedTime, const level& wantedLevel, bool& dataFoundFromRRParam)
{

	try
	{
		if (dataFoundFromRRParam)
		{

			return FetchSourceRR(conf,
								wantedTime,
								wantedLevel);

		}
		else
		{
			return FetchSourceConvectiveAndLSRR(conf,
												wantedTime,
												wantedLevel);
		}
	}
	catch (HPExceptionType e)
	{

		if (e == kFileDataNotFound && dataFoundFromRRParam)
		{
			try
			{

				shared_ptr<info> i = FetchSourceConvectiveAndLSRR(conf,
						wantedTime,
						wantedLevel);

				dataFoundFromRRParam = false;

				return i;

			}
			catch (HPExceptionType e)
			{
				throw e;
			}

		}
		else
		{
			throw e;
		}
	}

	throw runtime_error(ClassName() + ": We should never be here but compiler forces this statement");
}

shared_ptr<himan::info> precipitation::FetchSourceRR(shared_ptr<const plugin_configuration> conf, const forecast_time& wantedTime, const level& wantedLevel)
{
	shared_ptr<fetcher> f = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

	try
	{
		return f->Fetch(conf,
						wantedTime,
						wantedLevel,
						param("RR-KGM2"));
   	}
	catch (HPExceptionType e)
	{
		throw e;
	}

}

shared_ptr<himan::info> precipitation::FetchSourceConvectiveAndLSRR(shared_ptr<const plugin_configuration> conf, const forecast_time& wantedTime, const level& wantedLevel)
{
	shared_ptr<fetcher> f = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

	shared_ptr<himan::info> ConvectiveInfo;
	shared_ptr<himan::info> LSInfo;
	shared_ptr<himan::info> RRInfo;

	try
	{

		ConvectiveInfo = f->Fetch(conf,
						wantedTime,
						wantedLevel,
						param("RRC-KGM2"));

		LSInfo = f->Fetch(conf,
						wantedTime,
						wantedLevel,
						param("RRR-KGM2"));
	}
	catch (HPExceptionType e)
	{
		throw e;
	}

	ConvectiveInfo->ResetLocation();
	LSInfo->ResetLocation();

	assert(*ConvectiveInfo->Grid() == *LSInfo->Grid());

	RRInfo->Data()->Resize(ConvectiveInfo->Data()->SizeX(),LSInfo->Data()->SizeY());

	while (ConvectiveInfo->NextLocation() && LSInfo->NextLocation() && RRInfo->NextLocation())
	{
		double C = ConvectiveInfo->Value();
		double LS = LSInfo->Value();

		RRInfo->Value(C+LS);
	}

	return RRInfo;
}
<commit_msg>correct enum value name<commit_after>/**
 * @file precipitation.cpp
 *
 * @date Jan 28, 2012
 * @author partio
 */

#include "precipitation.h"
#include <iostream>
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "fetcher.h"
#include "writer.h"
#include "neons.h"
#include "pcuda.h"

#undef HIMAN_AUXILIARY_INCLUDE

#ifdef DEBUG
#include "timer_factory.h"
#endif

using namespace std;
using namespace himan::plugin;

precipitation::precipitation() : itsUseCuda(false)
{
	itsClearTextFormula = "RR = RR_cur - RR_prev";

	itsLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("precipitation"));

}

void precipitation::Process(std::shared_ptr<const plugin_configuration> conf)
{

	shared_ptr<plugin::pcuda> c = dynamic_pointer_cast<plugin::pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

	if (c->HaveCuda())
	{
		string msg = "I possess the powers of CUDA";

		if (!conf->UseCuda())
		{
			msg += ", but I won't use them";
		}
		else
		{
			msg += ", and I'm not afraid to use them";
			itsUseCuda = true;
		}

		itsLogger->Info(msg);

	}

	// Get number of threads to use

	unsigned short threadCount = ThreadCount(conf->ThreadCount());

	boost::thread_group g;

	shared_ptr<info> targetInfo = conf->Info();

	/*
	 * Set target parameter to precipitation.
	 *
	 * We need to specify grib and querydata parameter information
	 * since we don't know which one will be the output format.
	 *
	 */

	vector<param> params;

	//param requestedParam ("RR-1-MM", 353);
	param requestedParam ("RR-3-MM", 354);
	//param requestedParam ("RR-6-MM", 355);

	// GRIB 1

	if (conf->OutputFileType() == kGRIB1)
	{
		shared_ptr<neons> n = dynamic_pointer_cast<neons> (plugin_factory::Instance()->Plugin("neons"));

		long parm_id = n->NeonsDB().GetGridParameterId(targetInfo->Producer().TableVersion(), requestedParam.Name());
		requestedParam.GribIndicatorOfParameter(parm_id);
		requestedParam.GribTableVersion(targetInfo->Producer().TableVersion());

	}
	params.push_back(requestedParam);

	targetInfo->Params(params);

	/*
	 * Create data structures.
	 */

	targetInfo->Create();

	/*
	 * Initialize parent class functions for dimension handling
	 */

	Dimension(kLevelDimension);
	FeederInfo(shared_ptr<info> (new info(*targetInfo)));
	FeederInfo()->Param(requestedParam);

	/*
	 * Each thread will have a copy of the target info.
	 */

	vector<shared_ptr<info> > targetInfos;

	targetInfos.resize(threadCount);

	for (size_t i = 0; i < threadCount; i++)
	{

		itsLogger->Info("Thread " + boost::lexical_cast<string> (i + 1) + " starting");

		targetInfos[i] = shared_ptr<info> (new info(*targetInfo));

		boost::thread* t = new boost::thread(&precipitation::Run,
											 this,
											 targetInfos[i],
											 conf,
											 i + 1);

		g.add_thread(t);

	}

	g.join_all();

	if (conf->FileWriteOption() == kSingleFile)
	{

		shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

		string theOutputFile = conf->ConfigurationFile();

		theWriter->ToFile(targetInfo, conf, theOutputFile);

	}
}

void precipitation::Run(shared_ptr<info> myTargetInfo,
			   shared_ptr<const plugin_configuration> conf,
			   unsigned short threadIndex)
{

	while (AdjustLeadingDimension(myTargetInfo))
	{
		Calculate(myTargetInfo, conf, threadIndex);
	}

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void precipitation::Calculate(shared_ptr<info> myTargetInfo,
					 shared_ptr<const plugin_configuration> conf,
					 unsigned short threadIndex)
{

	unique_ptr<logger> myThreadedLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("precipitationThread #" + boost::lexical_cast<string> (threadIndex)));

	ResetNonLeadingDimension(myTargetInfo);

	myTargetInfo->FirstParam();

	long paramStep;

	if (myTargetInfo->Param().Name() == "RR-1-MM")
	{
		paramStep = 1;
	}
	else if (myTargetInfo->Param().Name() == "RR-3-MM")
	{
		paramStep = 3;
	}
	else if (myTargetInfo->Param().Name() == "RR-6-MM")
	{
		paramStep = 6;
	}
	else if (myTargetInfo->Param().Name() == "RR-12-MM")
	{
		paramStep = 12;
	}
	else
	{
		throw runtime_error(ClassName() + ": Unsupported parameter: " + myTargetInfo->Param().Name());
	}

	shared_ptr<info> prevInfo;

	bool dataFoundFromRRParam = true; // Assume that we have parameter RR-KGM2 present

	while (AdjustNonLeadingDimension(myTargetInfo))
	{

		assert(myTargetInfo->Time().StepResolution() == kHourResolution);

		/*
		 * We only calculate data for certain times (based on parameter time step),
		 * but user may have specified time steps that are between parameter time steps.
		 * Those timesteps need to be resized and filled with missing values.
		 */

		myTargetInfo->Data()->Fill(kFloatMissing); // Fill data with missing value

		if (myTargetInfo->Time().Step() % paramStep != 0)
		{
			continue;
		}

		shared_ptr<info> RRInfo;

		try
		{
			if (!prevInfo || myTargetInfo->Time().Step() - prevInfo->Time().Step() != paramStep)
			{

				/*
				 * If this is the first time this loop executed, or if the previous data is not suitable
				 * for calculating against current time step data, fetch source data.
				 */

				forecast_time prevTimeStep = myTargetInfo->Time();

				if (prevTimeStep.Step() >= paramStep)
				{
					prevTimeStep.ValidDateTime()->Adjust(kHourResolution, -paramStep);

					prevInfo = FetchSourcePrecipitation(conf,prevTimeStep,myTargetInfo->Level(),dataFoundFromRRParam);
				}
				else
				{
					continue;
				}
			}

			// Get data for current step

			RRInfo = FetchSourcePrecipitation(conf,myTargetInfo->Time(),myTargetInfo->Level(),dataFoundFromRRParam);

		}
		catch (HPExceptionType e)
		{
			switch (e)
			{
				case kFileDataNotFound:
					itsLogger->Info("Skipping step " + boost::lexical_cast<string> (myTargetInfo->Time().Step()) + ", level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));
					continue;
					break;

				default:
					throw runtime_error(ClassName() + ": Unable to proceed");
					break;
			}
		}

		myThreadedLogger->Debug("Calculating time " + myTargetInfo->Time().ValidDateTime()->String("%Y%m%d%H") +
											  " level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));

		shared_ptr<NFmiGrid> RRGrid(RRInfo->Grid()->ToNewbaseGrid());
		shared_ptr<NFmiGrid> prevGrid(prevInfo->Grid()->ToNewbaseGrid());

		shared_ptr<NFmiGrid> targetGrid(myTargetInfo->Grid()->ToNewbaseGrid());

		int missingCount = 0;
		int count = 0;

		bool equalGrids = (*myTargetInfo->Grid() == *RRInfo->Grid());

		if (true)
		{

			assert(targetGrid->Size() == myTargetInfo->Data()->Size());

			myTargetInfo->ResetLocation();

			targetGrid->Reset();
			prevGrid->Reset();

#ifdef DEBUG
			unique_ptr<timer> t = unique_ptr<timer> (timer_factory::Instance()->GetTimer());
			t->Start();
#endif

			while (myTargetInfo->NextLocation() && targetGrid->Next() && prevGrid->Next())
			{
				count++;

				double RRcur = kFloatMissing;
				double RRprev = kFloatMissing;

				InterpolateToPoint(targetGrid, RRGrid, equalGrids, RRcur);
				InterpolateToPoint(targetGrid, prevGrid, equalGrids, RRprev);

				if (RRcur == kFloatMissing || RRprev == kFloatMissing)
				{
					missingCount++;

					myTargetInfo->Value(kFloatMissing);
					continue;
				}

				double RR = RRcur - RRprev;

				if (RR < 0)
				{
					RR = 0;
				}

				if (!myTargetInfo->Value(RR))
				{
					throw runtime_error(ClassName() + ": Failed to set value to matrix");
				}

			}

			prevInfo = RRInfo;

#ifdef DEBUG
			t->Stop();
			itsLogger->Debug("Calculation took " + boost::lexical_cast<string> (t->GetTime()) + " microseconds on CPU");
#endif
		}

		/*
		 * Now we are done for this level
		 *
		 * Clone info-instance to writer since it might change our descriptor places
		 */

		myThreadedLogger->Info("Missing values: " + boost::lexical_cast<string> (missingCount) + "/" + boost::lexical_cast<string> (count));

		if (conf->FileWriteOption() == kNeons || conf->FileWriteOption() == kMultipleFiles)
		{
			shared_ptr<writer> w = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

			w->ToFile(shared_ptr<info> (new info(*myTargetInfo)), conf);
		}
	}
}

shared_ptr<himan::info> precipitation::FetchSourcePrecipitation(shared_ptr<const plugin_configuration> conf, const forecast_time& wantedTime, const level& wantedLevel, bool& dataFoundFromRRParam)
{

	try
	{
		if (dataFoundFromRRParam)
		{

			return FetchSourceRR(conf,
								wantedTime,
								wantedLevel);

		}
		else
		{
			return FetchSourceConvectiveAndLSRR(conf,
												wantedTime,
												wantedLevel);
		}
	}
	catch (HPExceptionType e)
	{

		if (e == kFileDataNotFound && dataFoundFromRRParam)
		{
			try
			{

				shared_ptr<info> i = FetchSourceConvectiveAndLSRR(conf,
						wantedTime,
						wantedLevel);

				dataFoundFromRRParam = false;

				return i;

			}
			catch (HPExceptionType e)
			{
				throw e;
			}

		}
		else
		{
			throw e;
		}
	}

	throw runtime_error(ClassName() + ": We should never be here but compiler forces this statement");
}

shared_ptr<himan::info> precipitation::FetchSourceRR(shared_ptr<const plugin_configuration> conf, const forecast_time& wantedTime, const level& wantedLevel)
{
	shared_ptr<fetcher> f = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

	try
	{
		return f->Fetch(conf,
						wantedTime,
						wantedLevel,
						param("RR-KGM2"));
   	}
	catch (HPExceptionType e)
	{
		throw e;
	}

}

shared_ptr<himan::info> precipitation::FetchSourceConvectiveAndLSRR(shared_ptr<const plugin_configuration> conf, const forecast_time& wantedTime, const level& wantedLevel)
{
	shared_ptr<fetcher> f = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

	shared_ptr<himan::info> ConvectiveInfo;
	shared_ptr<himan::info> LSInfo;
	shared_ptr<himan::info> RRInfo;

	try
	{

		ConvectiveInfo = f->Fetch(conf,
						wantedTime,
						wantedLevel,
						param("RRC-KGM2"));

		LSInfo = f->Fetch(conf,
						wantedTime,
						wantedLevel,
						param("RRR-KGM2"));
	}
	catch (HPExceptionType e)
	{
		throw e;
	}

	ConvectiveInfo->ResetLocation();
	LSInfo->ResetLocation();

	assert(*ConvectiveInfo->Grid() == *LSInfo->Grid());

	RRInfo->Data()->Resize(ConvectiveInfo->Data()->SizeX(),LSInfo->Data()->SizeY());

	while (ConvectiveInfo->NextLocation() && LSInfo->NextLocation() && RRInfo->NextLocation())
	{
		double C = ConvectiveInfo->Value();
		double LS = LSInfo->Value();

		RRInfo->Value(C+LS);
	}

	return RRInfo;
}
<|endoftext|>


<commit_before>// File: btBoostDynamicsDiscreteDynamicsWorld.hpp
#ifndef _btBoostDynamicsDiscreteDynamicsWorld_hpp
#define _btBoostDynamicsDiscreteDynamicsWorld_hpp

#include <boost/python.hpp>
#include <btBulletDynamicsCommon.h>

using namespace boost::python;

btDiscreteDynamicsWorld*
init_btDiscreteDynamicsWorld(
    btDispatcher& dispatcher,
    btBroadphaseInterface& pairCache,
    btConstraintSolver& solver,
    btCollisionConfiguration& config
) {
    return new btDiscreteDynamicsWorld(&dispatcher,
                                       &pairCache,
                                       &solver,
                                       &config);
}

void defineDiscreteDynamicsWorld()
{
    class_<btDiscreteDynamicsWorld, bases<btDynamicsWorld> >
        ("btDiscreteDynamicsWorld", no_init)
        .def("__init__", make_constructor(&init_btDiscreteDynamicsWorld))

    ;
}

#endif // _btBoostDynamicsDiscreteDynamicsWorld_hpp
<commit_msg>Add basic members and mark noncopyable. Define base world class.<commit_after>// File: btBoostDynamicsDiscreteDynamicsWorld.hpp
#ifndef _btBoostDynamicsDiscreteDynamicsWorld_hpp
#define _btBoostDynamicsDiscreteDynamicsWorld_hpp

#include <boost/python.hpp>
#include <btBulletDynamicsCommon.h>

using namespace boost::python;

btDiscreteDynamicsWorld*
init_btDiscreteDynamicsWorld(
    btDispatcher& dispatcher,
    btBroadphaseInterface& pairCache,
    btConstraintSolver& solver,
    btCollisionConfiguration& config
) {
    return new btDiscreteDynamicsWorld(&dispatcher,
                                       &pairCache,
                                       &solver,
                                       &config);
}

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ddw_step_overloads,
                                       stepSimulation,
                                       1, 3);

void defineDiscreteDynamicsWorld()
{
    class_<btDynamicsWorld, boost::noncopyable>("btDynamicsWorld", no_init);

    class_<btDiscreteDynamicsWorld, bases<btDynamicsWorld>, boost::noncopyable>
        ("btDiscreteDynamicsWorld", no_init)
        .def("__init__", make_constructor(&init_btDiscreteDynamicsWorld))
        .def("step_simulation", &btDiscreteDynamicsWorld::stepSimulation,
             ddw_step_overloads())
        .def("synchronize_motion_states",
             &btDiscreteDynamicsWorld::synchronizeMotionStates)
        .def("set_gravity",
             &btDiscreteDynamicsWorld::setGravity)
        .def("get_gravity",
             &btDiscreteDynamicsWorld::getGravity)
        .add_property("gravity",
                      &btDiscreteDynamicsWorld::getGravity,
                      &btDiscreteDynamicsWorld::setGravity)
    ;
}

#endif // _btBoostDynamicsDiscreteDynamicsWorld_hpp
<|endoftext|>


<commit_before>/**
 *
 * Copyright 2018 Google LLC
 *
 * 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
 *
 *     https://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.
 *
 */

#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>

using google::protobuf::Descriptor;
using google::protobuf::FileDescriptor;
using google::protobuf::MethodDescriptor;
using google::protobuf::ServiceDescriptor;
using google::protobuf::compiler::CodeGenerator;
using google::protobuf::compiler::GeneratorContext;
using google::protobuf::compiler::ParseGeneratorParameter;
using google::protobuf::compiler::PluginMain;
using google::protobuf::io::Printer;
using google::protobuf::io::ZeroCopyOutputStream;

namespace grpc {
namespace web {
namespace {

using std::string;

enum Mode {
  OP = 0,          // first party google3 one platform services
  GATEWAY = 1,     // open-source gRPC Gateway, currently nginx
  OPJSPB = 2,      // first party google3 one platform services with JSPB
  FRAMEWORKS = 3,  // first party google3 AF services with AF data add-ons
  GRPCWEB = 4,     // client using the application/grpc-web wire format
};

string GetModeVar(const Mode mode) {
  switch (mode) {
    case OP:
      return "OP";
    case GATEWAY:
      return "Gateway";
    case OPJSPB:
      return "OPJspb";
    case FRAMEWORKS:
      return "Frameworks";
    case GRPCWEB:
      return "GrpcWeb";
  }
}

string GetDeserializeMethodName(const string& mode_var) {
  if (mode_var == GetModeVar(Mode::OPJSPB)) {
    return "deserialize";
  }
  return "deserializeBinary";
}

string GetSerializeMethodName(const string& mode_var) {
  if (mode_var == GetModeVar(Mode::OPJSPB)) {
    return "serialize";
  }
  return "serializeBinary";
}

string LowercaseFirstLetter(string s) {
  if (s.empty()) {
    return s;
  }
  s[0] = ::tolower(s[0]);
  return s;
}

/* Finds all message types used in all services in the file, and returns them
 * as a map of fully qualified message type name to message descriptor */
std::map<string, const Descriptor*> GetAllMessages(const FileDescriptor* file) {
  std::map<string, const Descriptor*> message_types;
  for (int service_index = 0;
       service_index < file->service_count();
       ++service_index) {
    const ServiceDescriptor* service = file->service(service_index);
    for (int method_index = 0;
         method_index < service->method_count();
         ++method_index) {
      const MethodDescriptor *method = service->method(method_index);
      const Descriptor *input_type = method->input_type();
      const Descriptor *output_type = method->output_type();
      message_types[input_type->full_name()] = input_type;
      message_types[output_type->full_name()] = output_type;
    }
  }

  return message_types;
}

void PrintMessagesDeps(Printer* printer, const FileDescriptor* file) {
  std::map<string, const Descriptor*> messages = GetAllMessages(file);
  std::map<string, string> vars;
  for (std::map<string, const Descriptor*>::iterator it = messages.begin();
       it != messages.end(); it++) {
    vars["full_name"] = it->first;
    printer->Print(
        vars,
        "goog.require('proto.$full_name$');\n");
  }
  printer->Print("\n\n\n");
}

void PrintFileHeader(Printer* printer, const std::map<string, string>& vars) {
  printer->Print(
      vars,
      "/**\n"
      " * @fileoverview gRPC Web JS generated client stub for $package$\n"
      " * @enhanceable\n"
      " * @public\n"
      " */\n"
      "// GENERATED CODE -- DO NOT EDIT!\n\n\n");
}

void PrintServiceConstructor(Printer* printer,
                             const std::map<string, string>& vars) {
  printer->Print(
      vars,
      "/**\n"
      " * @param {string} hostname\n"
      " * @param {?Object} credentials\n"
      " * @constructor\n"
      " * @struct\n"
      " * @final\n"
      " */\n"
      "proto.$package_dot$$service_name$Client =\n"
      "    function(hostname, credentials, options) {\n"
      "  /**\n"
      "   * @private @const {!grpc.web.$mode$ClientBase} The client\n"
      "   */\n"
      "  this.client_ = new grpc.web.$mode$ClientBase(options);\n\n"
      "  /**\n"
      "   * @private @const {string} The hostname\n"
      "   */\n"
      "  this.hostname_ = hostname;\n\n"
      "  /**\n"
      "   * @private @const {?Object} The credentials to be used to connect\n"
      "   *    to the server\n"
      "   */\n"
      "  this.credentials_ = credentials;\n\n"
      "  /**\n"
      "   * @private @const {?Object} Options for the client\n"
      "   */\n"
      "  this.options_ = options;\n"
      "};\n\n\n");
}

void PrintMethodInfo(Printer* printer, std::map<string, string> vars) {
  printer->Print(
      vars,
      "/**\n"
      " * @const\n"
      " * @type {!grpc.web.AbstractClientBase.MethodInfo<\n"
      " *   !proto.$in$,\n"
      " *   !proto.$out$>}\n"
      " */\n"
      "const methodInfo_$method_name$ = "
      "new grpc.web.AbstractClientBase.MethodInfo(\n");
  printer->Indent();
  printer->Print(
      vars,
      "proto.$out$,\n"
      "/** @param {!proto.$in$} request */\n"
      "function(request) {\n");
  printer->Print(
      ("  return request." + GetSerializeMethodName(vars["mode"]) +
       "();\n").c_str());
  printer->Print("},\n");
  printer->Print(
      vars,
      ("proto.$out$." + GetDeserializeMethodName(vars["mode"]) +
       "\n").c_str());
  printer->Outdent();
  printer->Print(
      vars,
      ");\n\n\n");
}

void PrintUnaryCall(Printer* printer, std::map<string, string> vars) {
  PrintMethodInfo(printer, vars);
  printer->Print(
      vars,
      "/**\n"
      " * @param {!proto.$in$} request The\n"
      " *     request proto\n"
      " * @param {!Object<string, string>} metadata User defined\n"
      " *     call metadata\n"
      " * @param {function(?grpc.web.Error,"
      " ?proto.$out$)}\n"
      " *     callback The callback function(error, response)\n"
      " * @return {!grpc.web.ClientReadableStream<!proto.$out$>|undefined}\n"
      " *     The XHR Node Readable Stream\n"
      " */\n"
      "proto.$package_dot$$service_name$Client.prototype.$js_method_name$ =\n");
  printer->Indent();
  printer->Print(vars,
                 "  function(request, metadata, callback) {\n"
                 "return this.client_.rpcCall(this.hostname_ +\n");
  printer->Indent();
  printer->Indent();
  if (vars["mode"] == GetModeVar(Mode::OP) ||
      vars["mode"] == GetModeVar(Mode::OPJSPB)) {
    printer->Print(vars,
                   "'/$$rpc/$package_dot$$service_name$/$method_name$',\n");
  } else {
    printer->Print(vars, "'/$package_dot$$service_name$/$method_name$',\n");
  }
  printer->Print(
      vars,
      "request,\n"
      "metadata,\n"
      "methodInfo_$method_name$,\n"
      "callback);\n");
  printer->Outdent();
  printer->Outdent();
  printer->Outdent();
  printer->Print("};\n\n\n");
}

void PrintServerStreamingCall(Printer* printer, std::map<string, string> vars) {
  PrintMethodInfo(printer, vars);
  printer->Print(
      vars,
      "/**\n"
      " * @param {!proto.$in$} request The request proto\n"
      " * @param {!Object<string, string>} metadata User defined\n"
      " *     call metadata\n"
      " * @return {!grpc.web.ClientReadableStream<!proto.$out$>}\n"
      " *     The XHR Node Readable Stream\n"
      " */\n"
      "proto.$package_dot$$service_name$Client.prototype.$js_method_name$ =\n");
  printer->Indent();
  printer->Print(
      "  function(request, metadata) {\n"
      "return this.client_.serverStreaming(this.hostname_ +\n");
  printer->Indent();
  printer->Indent();
  if (vars["mode"] == GetModeVar(Mode::OP) ||
      vars["mode"] == GetModeVar(Mode::OPJSPB)) {
    printer->Print(vars,
                   "'/$$rpc/$package_dot$$service_name$/$method_name$',\n");
  } else {
    printer->Print(vars, "'/$package_dot$$service_name$/$method_name$',\n");
  }
  printer->Print(
      vars,
      "request,\n"
      "metadata,\n"
      "methodInfo_$method_name$);\n");
  printer->Outdent();
  printer->Outdent();
  printer->Outdent();
  printer->Print("};\n\n\n");
}

class GrpcCodeGenerator : public CodeGenerator {
 public:
  GrpcCodeGenerator() {}
  ~GrpcCodeGenerator() override {}

  bool Generate(const FileDescriptor* file, const string& parameter,
                GeneratorContext* context, string* error) const override {
    if (!file->service_count()) {
      // No services, nothing to do.
      return true;
    }

    std::vector<std::pair<string, string> > options;
    ParseGeneratorParameter(parameter, &options);

    string file_name;
    string mode;
    for (int i = 0; i < options.size(); ++i) {
      if (options[i].first == "out") {
        file_name = options[i].second;
      } else if (options[i].first == "mode") {
        mode = options[i].second;
      } else {
        *error = "unsupported options: " + options[i].first;
        return false;
      }
    }
    if (file_name.empty()) {
      *error = "options: out is required";
      return false;
    }
    if (mode.empty()) {
      *error = "options: mode is required";
      return false;
    }

    std::map<string, string> vars;
    std::string package = file->package();
    vars["package"] = package;
    vars["package_dot"] = package.size() > 0 ? package + '.' : "";

    if (mode == "binary") {
      vars["mode"] = GetModeVar(Mode::OP);
    } else if (mode == "base64") {
      vars["mode"] = GetModeVar(Mode::GATEWAY);
    } else if (mode == "grpcweb") {
      vars["mode"] = GetModeVar(Mode::GRPCWEB);
    } else if (mode == "jspb") {
      vars["mode"] = GetModeVar(Mode::OPJSPB);
    } else if (mode == "frameworks") {
      vars["mode"] = GetModeVar(Mode::FRAMEWORKS);
    } else {
      *error = "options: invalid mode - " + mode;
      return false;
    }

    std::unique_ptr<ZeroCopyOutputStream> output(
        context->Open(file_name));
    Printer printer(output.get(), '$');
    PrintFileHeader(&printer, vars);

    for (int i = 0; i < file->service_count(); ++i) {
      const ServiceDescriptor* service = file->service(i);
      vars["service_name"] = service->name();
      printer.Print(
          vars,
          "goog.provide('proto.$package_dot$$service_name$Client');\n");
    }
    printer.Print("\n");

    printer.Print(vars, "goog.require('grpc.web.$mode$ClientBase');\n");
    printer.Print(vars, "goog.require('grpc.web.AbstractClientBase');\n");
    printer.Print(vars, "goog.require('grpc.web.ClientReadableStream');\n");
    printer.Print(vars, "goog.require('grpc.web.Error');\n");
    PrintMessagesDeps(&printer, file);
    printer.Print("goog.scope(function() {\n\n");

    for (int service_index = 0;
         service_index < file->service_count();
         ++service_index) {
      const ServiceDescriptor* service = file->service(service_index);
      vars["service_name"] = service->name();
      PrintServiceConstructor(&printer, vars);

      for (int method_index = 0;
           method_index < service->method_count();
           ++method_index) {
        const MethodDescriptor* method = service->method(method_index);
        vars["js_method_name"] = LowercaseFirstLetter(method->name());
        vars["method_name"] = method->name();
        vars["in"] = method->input_type()->full_name();
        vars["out"] = method->output_type()->full_name();

        // Client streaming is not supported yet
        if (!method->client_streaming()) {
          if (method->server_streaming()) {
            PrintServerStreamingCall(&printer, vars);
          } else {
            PrintUnaryCall(&printer, vars);
          }
        }
      }
    }

    printer.Print("}); // goog.scope\n\n");
    return true;
  }
};

}  // namespace
}  // namespace web
}  // namespace grpc

int main(int argc, char* argv[]) {
  grpc::web::GrpcCodeGenerator generator;
  PluginMain(argc, argv, &generator);
  return 0;
}
<commit_msg>Minor code clean up<commit_after>/**
 *
 * Copyright 2018 Google LLC
 *
 * 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
 *
 *     https://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.
 *
 */

#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>

using google::protobuf::Descriptor;
using google::protobuf::FileDescriptor;
using google::protobuf::MethodDescriptor;
using google::protobuf::ServiceDescriptor;
using google::protobuf::compiler::CodeGenerator;
using google::protobuf::compiler::GeneratorContext;
using google::protobuf::compiler::ParseGeneratorParameter;
using google::protobuf::compiler::PluginMain;
using google::protobuf::io::Printer;
using google::protobuf::io::ZeroCopyOutputStream;

namespace grpc {
namespace web {
namespace {

using std::string;

enum Mode {
  OP = 0,          // first party google3 one platform services
  GATEWAY = 1,     // open-source gRPC Gateway, currently nginx
  OPJSPB = 2,      // first party google3 one platform services with JSPB
  FRAMEWORKS = 3,  // first party google3 AF services with AF data add-ons
  GRPCWEB = 4,     // client using the application/grpc-web wire format
};

string GetModeVar(const Mode mode) {
  switch (mode) {
    case OP:
      return "OP";
    case GATEWAY:
      return "Gateway";
    case OPJSPB:
      return "OPJspb";
    case FRAMEWORKS:
      return "Frameworks";
    case GRPCWEB:
      return "GrpcWeb";
  }
}

string GetDeserializeMethodName(const string& mode_var) {
  if (mode_var == GetModeVar(Mode::OPJSPB)) {
    return "deserialize";
  }
  return "deserializeBinary";
}

string GetSerializeMethodName(const string& mode_var) {
  if (mode_var == GetModeVar(Mode::OPJSPB)) {
    return "serialize";
  }
  return "serializeBinary";
}

string LowercaseFirstLetter(string s) {
  if (s.empty()) {
    return s;
  }
  s[0] = ::tolower(s[0]);
  return s;
}

/* Finds all message types used in all services in the file, and returns them
 * as a map of fully qualified message type name to message descriptor */
std::map<string, const Descriptor*> GetAllMessages(const FileDescriptor* file) {
  std::map<string, const Descriptor*> message_types;
  for (int service_index = 0;
       service_index < file->service_count();
       ++service_index) {
    const ServiceDescriptor* service = file->service(service_index);
    for (int method_index = 0;
         method_index < service->method_count();
         ++method_index) {
      const MethodDescriptor *method = service->method(method_index);
      const Descriptor *input_type = method->input_type();
      const Descriptor *output_type = method->output_type();
      message_types[input_type->full_name()] = input_type;
      message_types[output_type->full_name()] = output_type;
    }
  }

  return message_types;
}

void PrintMessagesDeps(Printer* printer, const FileDescriptor* file) {
  std::map<string, const Descriptor*> messages = GetAllMessages(file);
  std::map<string, string> vars;
  for (std::map<string, const Descriptor*>::iterator it = messages.begin();
       it != messages.end(); it++) {
    vars["full_name"] = it->first;
    printer->Print(
        vars,
        "goog.require('proto.$full_name$');\n");
  }
  printer->Print("\n\n\n");
}

void PrintFileHeader(Printer* printer, const std::map<string, string>& vars) {
  printer->Print(
      vars,
      "/**\n"
      " * @fileoverview gRPC Web JS generated client stub for $package$\n"
      " * @enhanceable\n"
      " * @public\n"
      " */\n"
      "// GENERATED CODE -- DO NOT EDIT!\n\n\n");
}

void PrintServiceConstructor(Printer* printer,
                             const std::map<string, string>& vars) {
  printer->Print(
      vars,
      "/**\n"
      " * @param {string} hostname\n"
      " * @param {?Object} credentials\n"
      " * @constructor\n"
      " * @struct\n"
      " * @final\n"
      " */\n"
      "proto.$package_dot$$service_name$Client =\n"
      "    function(hostname, credentials, options) {\n"
      "  /**\n"
      "   * @private @const {!grpc.web.$mode$ClientBase} The client\n"
      "   */\n"
      "  this.client_ = new grpc.web.$mode$ClientBase(options);\n\n"
      "  /**\n"
      "   * @private @const {string} The hostname\n"
      "   */\n"
      "  this.hostname_ = hostname;\n\n"
      "  /**\n"
      "   * @private @const {?Object} The credentials to be used to connect\n"
      "   *    to the server\n"
      "   */\n"
      "  this.credentials_ = credentials;\n\n"
      "  /**\n"
      "   * @private @const {?Object} Options for the client\n"
      "   */\n"
      "  this.options_ = options;\n"
      "};\n\n\n");
}

void PrintMethodInfo(Printer* printer, std::map<string, string> vars) {
  printer->Print(
      vars,
      "/**\n"
      " * @const\n"
      " * @type {!grpc.web.AbstractClientBase.MethodInfo<\n"
      " *   !proto.$in$,\n"
      " *   !proto.$out$>}\n"
      " */\n"
      "const methodInfo_$method_name$ = "
      "new grpc.web.AbstractClientBase.MethodInfo(\n");
  printer->Indent();
  printer->Print(
      vars,
      "proto.$out$,\n"
      "/** @param {!proto.$in$} request */\n"
      "function(request) {\n");
  printer->Print(
      ("  return request." + GetSerializeMethodName(vars["mode"]) +
       "();\n").c_str());
  printer->Print("},\n");
  printer->Print(
      vars,
      ("proto.$out$." + GetDeserializeMethodName(vars["mode"]) +
       "\n").c_str());
  printer->Outdent();
  printer->Print(
      vars,
      ");\n\n\n");
}

void PrintUnaryCall(Printer* printer, std::map<string, string> vars) {
  PrintMethodInfo(printer, vars);
  printer->Print(
      vars,
      "/**\n"
      " * @param {!proto.$in$} request The\n"
      " *     request proto\n"
      " * @param {!Object<string, string>} metadata User defined\n"
      " *     call metadata\n"
      " * @param {function(?grpc.web.Error,"
      " ?proto.$out$)}\n"
      " *     callback The callback function(error, response)\n"
      " * @return {!grpc.web.ClientReadableStream<!proto.$out$>|undefined}\n"
      " *     The XHR Node Readable Stream\n"
      " */\n"
      "proto.$package_dot$$service_name$Client.prototype.$js_method_name$ =\n");
  printer->Indent();
  printer->Print(vars,
                 "  function(request, metadata, callback) {\n"
                 "return this.client_.rpcCall(this.hostname_ +\n");
  printer->Indent();
  printer->Indent();
  if (vars["mode"] == GetModeVar(Mode::OP) ||
      vars["mode"] == GetModeVar(Mode::OPJSPB)) {
    printer->Print(vars,
                   "'/$$rpc/$package_dot$$service_name$/$method_name$',\n");
  } else {
    printer->Print(vars, "'/$package_dot$$service_name$/$method_name$',\n");
  }
  printer->Print(
      vars,
      "request,\n"
      "metadata,\n"
      "methodInfo_$method_name$,\n"
      "callback);\n");
  printer->Outdent();
  printer->Outdent();
  printer->Outdent();
  printer->Print("};\n\n\n");
}

void PrintServerStreamingCall(Printer* printer, std::map<string, string> vars) {
  PrintMethodInfo(printer, vars);
  printer->Print(
      vars,
      "/**\n"
      " * @param {!proto.$in$} request The request proto\n"
      " * @param {!Object<string, string>} metadata User defined\n"
      " *     call metadata\n"
      " * @return {!grpc.web.ClientReadableStream<!proto.$out$>}\n"
      " *     The XHR Node Readable Stream\n"
      " */\n"
      "proto.$package_dot$$service_name$Client.prototype.$js_method_name$ =\n");
  printer->Indent();
  printer->Print(
      "  function(request, metadata) {\n"
      "return this.client_.serverStreaming(this.hostname_ +\n");
  printer->Indent();
  printer->Indent();
  if (vars["mode"] == GetModeVar(Mode::OP) ||
      vars["mode"] == GetModeVar(Mode::OPJSPB)) {
    printer->Print(vars,
                   "'/$$rpc/$package_dot$$service_name$/$method_name$',\n");
  } else {
    printer->Print(vars, "'/$package_dot$$service_name$/$method_name$',\n");
  }
  printer->Print(
      vars,
      "request,\n"
      "metadata,\n"
      "methodInfo_$method_name$);\n");
  printer->Outdent();
  printer->Outdent();
  printer->Outdent();
  printer->Print("};\n\n\n");
}

class GrpcCodeGenerator : public CodeGenerator {
 public:
  GrpcCodeGenerator() {}
  ~GrpcCodeGenerator() override {}

  bool Generate(const FileDescriptor* file, const string& parameter,
                GeneratorContext* context, string* error) const override {
    if (!file->service_count()) {
      // No services, nothing to do.
      return true;
    }

    std::vector<std::pair<string, string> > options;
    ParseGeneratorParameter(parameter, &options);

    string file_name;
    string mode;
    for (int i = 0; i < options.size(); ++i) {
      if (options[i].first == "out") {
        file_name = options[i].second;
      } else if (options[i].first == "mode") {
        mode = options[i].second;
      } else {
        *error = "unsupported options: " + options[i].first;
        return false;
      }
    }
    if (file_name.empty()) {
      *error = "options: out is required";
      return false;
    }
    if (mode.empty()) {
      *error = "options: mode is required";
      return false;
    }

    std::map<string, string> vars;
    string package = file->package();
    vars["package"] = package;
    vars["package_dot"] = package.empty() ? "" : package + '.';

    if (mode == "binary") {
      vars["mode"] = GetModeVar(Mode::OP);
    } else if (mode == "base64") {
      vars["mode"] = GetModeVar(Mode::GATEWAY);
    } else if (mode == "grpcweb") {
      vars["mode"] = GetModeVar(Mode::GRPCWEB);
    } else if (mode == "jspb") {
      vars["mode"] = GetModeVar(Mode::OPJSPB);
    } else if (mode == "frameworks") {
      vars["mode"] = GetModeVar(Mode::FRAMEWORKS);
    } else {
      *error = "options: invalid mode - " + mode;
      return false;
    }

    std::unique_ptr<ZeroCopyOutputStream> output(
        context->Open(file_name));
    Printer printer(output.get(), '$');
    PrintFileHeader(&printer, vars);

    for (int i = 0; i < file->service_count(); ++i) {
      const ServiceDescriptor* service = file->service(i);
      vars["service_name"] = service->name();
      printer.Print(
          vars,
          "goog.provide('proto.$package_dot$$service_name$Client');\n");
    }
    printer.Print("\n");

    printer.Print(vars, "goog.require('grpc.web.$mode$ClientBase');\n");
    printer.Print(vars, "goog.require('grpc.web.AbstractClientBase');\n");
    printer.Print(vars, "goog.require('grpc.web.ClientReadableStream');\n");
    printer.Print(vars, "goog.require('grpc.web.Error');\n");
    PrintMessagesDeps(&printer, file);
    printer.Print("goog.scope(function() {\n\n");

    for (int service_index = 0;
         service_index < file->service_count();
         ++service_index) {
      const ServiceDescriptor* service = file->service(service_index);
      vars["service_name"] = service->name();
      PrintServiceConstructor(&printer, vars);

      for (int method_index = 0;
           method_index < service->method_count();
           ++method_index) {
        const MethodDescriptor* method = service->method(method_index);
        vars["js_method_name"] = LowercaseFirstLetter(method->name());
        vars["method_name"] = method->name();
        vars["in"] = method->input_type()->full_name();
        vars["out"] = method->output_type()->full_name();

        // Client streaming is not supported yet
        if (!method->client_streaming()) {
          if (method->server_streaming()) {
            PrintServerStreamingCall(&printer, vars);
          } else {
            PrintUnaryCall(&printer, vars);
          }
        }
      }
    }

    printer.Print("}); // goog.scope\n\n");
    return true;
  }
};

}  // namespace
}  // namespace web
}  // namespace grpc

int main(int argc, char* argv[]) {
  grpc::web::GrpcCodeGenerator generator;
  PluginMain(argc, argv, &generator);
  return 0;
}
<|endoftext|>


<commit_before>// =================================================================== //
// Copyright (C) 2016 Kimura Ryo                                       //
//                                                                     //
// This Source Code Form is subject to the terms of the Mozilla Public //
// License, v. 2.0. If a copy of the MPL was not distributed with this //
// file, You can obtain one at http://mozilla.org/MPL/2.0/.            //
// =================================================================== //

#include "ReflectanceModelDockWidget.h"

#include <iostream>

#include <osg/Timer>

#include <libbsdf/Brdf/HalfDifferenceCoordinatesBrdf.h>
#include <libbsdf/Brdf/SpecularCoordinatesBrdf.h>
#include <libbsdf/Brdf/SphericalCoordinatesBrdf.h>

#include <libbsdf/ReflectanceModel/AshikhminShirley.h>
#include <libbsdf/ReflectanceModel/BlinnPhong.h>
#include <libbsdf/ReflectanceModel/CookTorrance.h>
#include <libbsdf/ReflectanceModel/Lambertian.h>
#include <libbsdf/ReflectanceModel/ModifiedPhong.h>
#include <libbsdf/ReflectanceModel/OrenNayar.h>
#include <libbsdf/ReflectanceModel/Phong.h>
#include <libbsdf/ReflectanceModel/ReflectanceModelUtility.h>
#include <libbsdf/ReflectanceModel/SimplifiedOrenNayar.h>
#include <libbsdf/ReflectanceModel/WardAnisotropic.h>
#include <libbsdf/ReflectanceModel/WardIsotropic.h>

#include "ColorButton.h"
#include "Utility.h"

ReflectanceModelDockWidget::ReflectanceModelDockWidget(QWidget* parent)
                                                       : QDockWidget(parent),
                                                         ui_(new Ui::ReflectanceModelDockWidgetBase)
{
    ui_->setupUi(this);

    initializeReflectanceModels();
    updateParameterWidget(0);

    int lambertIndex = ui_->reflectanceModelComboBox->findText("Lambertian");
    ui_->reflectanceModelComboBox->setCurrentIndex(lambertIndex);
    ui_->reflectanceModelComboBox->activated(lambertIndex);

    // Select a specular coordinate system.
    ui_->coordSysComboBox->setCurrentIndex(1);
    ui_->coordSysComboBox->activated(1);

    connect(ui_->generateBrdfPushButton, SIGNAL(clicked()), this, SLOT(generateBrdf()));
}

ReflectanceModelDockWidget::~ReflectanceModelDockWidget()
{
    for (auto it = reflectanceModels_.begin(); it != reflectanceModels_.end(); ++it) {
        delete it->second;
    }

    delete ui_;
}

void ReflectanceModelDockWidget::updateParameterWidget(int index)
{
    // Remove items.
    while (ui_->parameterFormLayout->count() > 0) {
        QLayoutItem* item = ui_->parameterFormLayout->takeAt(0);
        delete item->widget();
        delete item;
    }

    currentParameters_.clear();

    // Add labels and fields.
    QString name = ui_->reflectanceModelComboBox->itemText(index);
    lb::ReflectanceModel* model = reflectanceModels_[name.toLocal8Bit().data()];
    lb::ReflectanceModel::Parameters& params = model->getParameters();
    for (auto it = params.begin(); it != params.end(); ++it) {
        if (it->getType() == lb::ReflectanceModel::Parameter::FLOAT_PARAMETER) {
            QDoubleSpinBox* spinBox = new QDoubleSpinBox(ui_->parameterWidget);
            spinBox->setDecimals(2);
            spinBox->setMinimum(0.01);
            spinBox->setMaximum(999.99);
            spinBox->setSingleStep(0.1);
            spinBox->setValue(*it->getFloat());
            spinBox->setMaximumWidth(75);

            std::string label = it->getName() + ":";
            ui_->parameterFormLayout->addRow(label.c_str(), spinBox);

            currentParameters_[spinBox] = &(*it);

            connect(spinBox, SIGNAL(editingFinished()),
                    this, SLOT(updateParameter()));
        }
        else if (it->getType() == lb::ReflectanceModel::Parameter::VEC3_PARAMETER) {
            ColorButton* colorButton = new ColorButton(ui_->parameterWidget);
            colorButton->setAutoFillBackground(true);
            colorButton->setFlat(false);
            colorButton->setMaximumWidth(40);
            colorButton->setColor(util::lbToQt(*it->getVec3()));

            std::string label = it->getName() + ":";
            ui_->parameterFormLayout->addRow(label.c_str(), colorButton);

            currentParameters_[colorButton] = &(*it);

            connect(colorButton, SIGNAL(colorChanged(QColor)),
                    this, SLOT(updateParameter()));
        }
    }
}

void ReflectanceModelDockWidget::updateCoordSysWidget(int index)
{
    QString name = ui_->reflectanceModelComboBox->itemText(index);
    lb::ReflectanceModel* model = reflectanceModels_[name.toLocal8Bit().data()];

    QLabel* halfLabel = ui_->halfDiffCsNumAngle1Label;
    QLabel* specLabel = ui_->specularCsNumAngle1Label;
    QLabel* spheLabel = ui_->sphericalCsNumAngle1Label;
    QSpinBox* halfSpinBox = ui_->halfDiffCsNumAngle1SpinBox;
    QSpinBox* specSpinBox = ui_->specularCsNumAngle1SpinBox;
    QSpinBox* spheSpinBox = ui_->sphericalCsNumAngle1SpinBox;

    // Hide labels and fields for an anisotropic BRDF if an isotropic reflectance model is selected.
    if (model->isIsotropic()) {
        halfLabel->hide();
        halfSpinBox->hide();
        ui_->halfDiffCoordSysFormLayout->removeWidget(halfLabel);
        ui_->halfDiffCoordSysFormLayout->removeWidget(halfSpinBox);

        specLabel->hide();
        specSpinBox->hide();
        ui_->specularCoordSysFormLayout->removeWidget(specLabel);
        ui_->specularCoordSysFormLayout->removeWidget(specSpinBox);

        spheLabel->hide();
        spheSpinBox->hide();
        ui_->sphericalCoordSysFormLayout->removeWidget(spheLabel);
        ui_->sphericalCoordSysFormLayout->removeWidget(spheSpinBox);
    }
    else {
        ui_->halfDiffCoordSysFormLayout->insertRow(2, halfLabel, halfSpinBox);
        halfLabel->show();
        halfSpinBox->show();

        ui_->specularCoordSysFormLayout->insertRow(2, specLabel, specSpinBox);
        specLabel->show();
        specSpinBox->show();

        ui_->sphericalCoordSysFormLayout->insertRow(2, spheLabel, spheSpinBox);
        spheLabel->show();
        spheSpinBox->show();
    }
}

void ReflectanceModelDockWidget::updateParameter()
{
    for (auto it = currentParameters_.begin(); it != currentParameters_.end(); ++it) {
        if (QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(it->first)) {
            *it->second->getFloat() = spinBox->value();
        }
        else if (ColorButton* colorButton = dynamic_cast<ColorButton*>(it->first)) {
            *it->second->getVec3() = util::qtToLb(colorButton->getColor());
        }
    }
}

void ReflectanceModelDockWidget::generateBrdf()
{
    std::cout << "[ReflectanceModelDockWidget::generateBrdf]" << std::endl;

    osg::Timer_t startTick = osg::Timer::instance()->tick();

    QString name = ui_->reflectanceModelComboBox->currentText();
    lb::ReflectanceModel* model = reflectanceModels_[name.toLocal8Bit().data()];

    lb::Brdf* brdf = initializeBrdf(model->isIsotropic());
    lb::reflectance_model_utility::setupTabularBrdf(*model, brdf);

    osg::Timer_t endTick = osg::Timer::instance()->tick();
    double delta = osg::Timer::instance()->delta_s(startTick, endTick);
    std::cout << "[ReflectanceModelDockWidget::generateBrdf] " << delta << "(s)" << std::endl;

    emit generated(brdf, lb::BRDF_DATA);
}

void ReflectanceModelDockWidget::initializeReflectanceModels()
{
    std::vector<lb::ReflectanceModel*> models;

    lb::Vec3 white(1.0, 1.0, 1.0);
    lb::Vec3 black(0.0, 0.0, 0.0);
    models.push_back(new lb::AshikhminShirley(white, black, 100.0f, 20.0f));
    models.push_back(new lb::BlinnPhong(white, 40.0f));
    models.push_back(new lb::CookTorrance(white, 0.2f, 5.0f));
    models.push_back(new lb::Lambertian(white));
    models.push_back(new lb::ModifiedPhong(white, 10.0f));
    models.push_back(new lb::OrenNayar(white, 30.0f));
    models.push_back(new lb::Phong(white, 10.0f));
    models.push_back(new lb::SimplifiedOrenNayar(white, 30.0f));
    models.push_back(new lb::WardAnisotropic(white, 0.05f, 0.2f));
    models.push_back(new lb::WardIsotropic(white, 0.2f));

    for (auto it = models.begin(); it != models.end(); ++it) {
        reflectanceModels_[(*it)->getName()] = *it;
    }

    for (auto it = reflectanceModels_.begin(); it != reflectanceModels_.end(); ++it) {
        ui_->reflectanceModelComboBox->addItem(it->first.c_str());
    }

    connect(ui_->reflectanceModelComboBox, SIGNAL(activated(int)),
            this, SLOT(updateParameterWidget(int)));

    connect(ui_->reflectanceModelComboBox, SIGNAL(activated(int)),
            this, SLOT(updateCoordSysWidget(int)));
}

lb::Brdf* ReflectanceModelDockWidget::initializeBrdf(bool isotropic)
{
    lb::Brdf* brdf;
    std::string coordinateSystemName(ui_->coordSysComboBox->currentText().toLocal8Bit());
    if (coordinateSystemName == "Half difference") {
        int numAngle1 = isotropic ? 1 : (ui_->halfDiffCsNumAngle1SpinBox->value() + 1);
        brdf = new lb::HalfDifferenceCoordinatesBrdf(ui_->halfDiffCsNumAngle0SpinBox->value(),
                                                     numAngle1,
                                                     ui_->halfDiffCsNumAngle2SpinBox->value(),
                                                     ui_->halfDiffCsNumAngle3SpinBox->value() + 1,
                                                     lb::RGB_MODEL, 3, true);
    }
    else if (coordinateSystemName == "Specular") {
        int numAngle1 = isotropic ? 1 : (ui_->specularCsNumAngle1SpinBox->value() + 1);
        brdf = new lb::SpecularCoordinatesBrdf(ui_->specularCsNumAngle0SpinBox->value(),
                                               numAngle1,
                                               ui_->specularCsNumAngle2SpinBox->value(),
                                               ui_->specularCsNumAngle3SpinBox->value() + 1,
                                               lb::RGB_MODEL, 3, true);
    }
    else if (coordinateSystemName == "Spherical") {
        int numAngle1 = isotropic ? 1 : (ui_->sphericalCsNumAngle1SpinBox->value() + 1);
        brdf = new lb::SphericalCoordinatesBrdf(ui_->sphericalCsNumAngle0SpinBox->value(),
                                                numAngle1,
                                                ui_->sphericalCsNumAngle2SpinBox->value(),
                                                ui_->sphericalCsNumAngle3SpinBox->value() + 1,
                                                lb::RGB_MODEL, 3, true);
    }
    else {
        std::cout
            << "[ReflectanceModelDockWidget::initializeBrdf] Invalid coordinate system: "
            << coordinateSystemName << std::endl;
        return 0;
    }

    return brdf;
}
<commit_msg>Added the Minnaert reflectance model<commit_after>// =================================================================== //
// Copyright (C) 2016 Kimura Ryo                                       //
//                                                                     //
// This Source Code Form is subject to the terms of the Mozilla Public //
// License, v. 2.0. If a copy of the MPL was not distributed with this //
// file, You can obtain one at http://mozilla.org/MPL/2.0/.            //
// =================================================================== //

#include "ReflectanceModelDockWidget.h"

#include <iostream>

#include <osg/Timer>

#include <libbsdf/Brdf/HalfDifferenceCoordinatesBrdf.h>
#include <libbsdf/Brdf/SpecularCoordinatesBrdf.h>
#include <libbsdf/Brdf/SphericalCoordinatesBrdf.h>

#include <libbsdf/ReflectanceModel/AshikhminShirley.h>
#include <libbsdf/ReflectanceModel/BlinnPhong.h>
#include <libbsdf/ReflectanceModel/CookTorrance.h>
#include <libbsdf/ReflectanceModel/Lambertian.h>
#include <libbsdf/ReflectanceModel/Minnaert.h>
#include <libbsdf/ReflectanceModel/ModifiedPhong.h>
#include <libbsdf/ReflectanceModel/OrenNayar.h>
#include <libbsdf/ReflectanceModel/Phong.h>
#include <libbsdf/ReflectanceModel/ReflectanceModelUtility.h>
#include <libbsdf/ReflectanceModel/SimplifiedOrenNayar.h>
#include <libbsdf/ReflectanceModel/WardAnisotropic.h>
#include <libbsdf/ReflectanceModel/WardIsotropic.h>

#include "ColorButton.h"
#include "Utility.h"

ReflectanceModelDockWidget::ReflectanceModelDockWidget(QWidget* parent)
                                                       : QDockWidget(parent),
                                                         ui_(new Ui::ReflectanceModelDockWidgetBase)
{
    ui_->setupUi(this);

    initializeReflectanceModels();
    updateParameterWidget(0);

    int lambertIndex = ui_->reflectanceModelComboBox->findText("Lambertian");
    ui_->reflectanceModelComboBox->setCurrentIndex(lambertIndex);
    ui_->reflectanceModelComboBox->activated(lambertIndex);

    // Select a specular coordinate system.
    ui_->coordSysComboBox->setCurrentIndex(1);
    ui_->coordSysComboBox->activated(1);

    connect(ui_->generateBrdfPushButton, SIGNAL(clicked()), this, SLOT(generateBrdf()));
}

ReflectanceModelDockWidget::~ReflectanceModelDockWidget()
{
    for (auto it = reflectanceModels_.begin(); it != reflectanceModels_.end(); ++it) {
        delete it->second;
    }

    delete ui_;
}

void ReflectanceModelDockWidget::updateParameterWidget(int index)
{
    // Remove items.
    while (ui_->parameterFormLayout->count() > 0) {
        QLayoutItem* item = ui_->parameterFormLayout->takeAt(0);
        delete item->widget();
        delete item;
    }

    currentParameters_.clear();

    // Add labels and fields.
    QString name = ui_->reflectanceModelComboBox->itemText(index);
    lb::ReflectanceModel* model = reflectanceModels_[name.toLocal8Bit().data()];
    lb::ReflectanceModel::Parameters& params = model->getParameters();
    for (auto it = params.begin(); it != params.end(); ++it) {
        if (it->getType() == lb::ReflectanceModel::Parameter::FLOAT_PARAMETER) {
            QDoubleSpinBox* spinBox = new QDoubleSpinBox(ui_->parameterWidget);
            spinBox->setDecimals(2);
            spinBox->setMinimum(0.01);
            spinBox->setMaximum(999.99);
            spinBox->setSingleStep(0.1);
            spinBox->setValue(*it->getFloat());
            spinBox->setMaximumWidth(75);

            std::string label = it->getName() + ":";
            ui_->parameterFormLayout->addRow(label.c_str(), spinBox);

            currentParameters_[spinBox] = &(*it);

            connect(spinBox, SIGNAL(editingFinished()),
                    this, SLOT(updateParameter()));
        }
        else if (it->getType() == lb::ReflectanceModel::Parameter::VEC3_PARAMETER) {
            ColorButton* colorButton = new ColorButton(ui_->parameterWidget);
            colorButton->setAutoFillBackground(true);
            colorButton->setFlat(false);
            colorButton->setMaximumWidth(40);
            colorButton->setColor(util::lbToQt(*it->getVec3()));

            std::string label = it->getName() + ":";
            ui_->parameterFormLayout->addRow(label.c_str(), colorButton);

            currentParameters_[colorButton] = &(*it);

            connect(colorButton, SIGNAL(colorChanged(QColor)),
                    this, SLOT(updateParameter()));
        }
    }
}

void ReflectanceModelDockWidget::updateCoordSysWidget(int index)
{
    QString name = ui_->reflectanceModelComboBox->itemText(index);
    lb::ReflectanceModel* model = reflectanceModels_[name.toLocal8Bit().data()];

    QLabel* halfLabel = ui_->halfDiffCsNumAngle1Label;
    QLabel* specLabel = ui_->specularCsNumAngle1Label;
    QLabel* spheLabel = ui_->sphericalCsNumAngle1Label;
    QSpinBox* halfSpinBox = ui_->halfDiffCsNumAngle1SpinBox;
    QSpinBox* specSpinBox = ui_->specularCsNumAngle1SpinBox;
    QSpinBox* spheSpinBox = ui_->sphericalCsNumAngle1SpinBox;

    // Hide labels and fields for an anisotropic BRDF if an isotropic reflectance model is selected.
    if (model->isIsotropic()) {
        halfLabel->hide();
        halfSpinBox->hide();
        ui_->halfDiffCoordSysFormLayout->removeWidget(halfLabel);
        ui_->halfDiffCoordSysFormLayout->removeWidget(halfSpinBox);

        specLabel->hide();
        specSpinBox->hide();
        ui_->specularCoordSysFormLayout->removeWidget(specLabel);
        ui_->specularCoordSysFormLayout->removeWidget(specSpinBox);

        spheLabel->hide();
        spheSpinBox->hide();
        ui_->sphericalCoordSysFormLayout->removeWidget(spheLabel);
        ui_->sphericalCoordSysFormLayout->removeWidget(spheSpinBox);
    }
    else {
        ui_->halfDiffCoordSysFormLayout->insertRow(2, halfLabel, halfSpinBox);
        halfLabel->show();
        halfSpinBox->show();

        ui_->specularCoordSysFormLayout->insertRow(2, specLabel, specSpinBox);
        specLabel->show();
        specSpinBox->show();

        ui_->sphericalCoordSysFormLayout->insertRow(2, spheLabel, spheSpinBox);
        spheLabel->show();
        spheSpinBox->show();
    }
}

void ReflectanceModelDockWidget::updateParameter()
{
    for (auto it = currentParameters_.begin(); it != currentParameters_.end(); ++it) {
        if (QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(it->first)) {
            *it->second->getFloat() = spinBox->value();
        }
        else if (ColorButton* colorButton = dynamic_cast<ColorButton*>(it->first)) {
            *it->second->getVec3() = util::qtToLb(colorButton->getColor());
        }
    }
}

void ReflectanceModelDockWidget::generateBrdf()
{
    std::cout << "[ReflectanceModelDockWidget::generateBrdf]" << std::endl;

    osg::Timer_t startTick = osg::Timer::instance()->tick();

    QString name = ui_->reflectanceModelComboBox->currentText();
    lb::ReflectanceModel* model = reflectanceModels_[name.toLocal8Bit().data()];

    lb::Brdf* brdf = initializeBrdf(model->isIsotropic());
    lb::reflectance_model_utility::setupTabularBrdf(*model, brdf);

    osg::Timer_t endTick = osg::Timer::instance()->tick();
    double delta = osg::Timer::instance()->delta_s(startTick, endTick);
    std::cout << "[ReflectanceModelDockWidget::generateBrdf] " << delta << "(s)" << std::endl;

    emit generated(brdf, lb::BRDF_DATA);
}

void ReflectanceModelDockWidget::initializeReflectanceModels()
{
    std::vector<lb::ReflectanceModel*> models;

    lb::Vec3 white(1.0, 1.0, 1.0);
    lb::Vec3 black(0.0, 0.0, 0.0);
    models.push_back(new lb::AshikhminShirley(white, black, 100.0f, 20.0f));
    models.push_back(new lb::BlinnPhong(white, 40.0f));
    models.push_back(new lb::CookTorrance(white, 0.2f, 5.0f));
    models.push_back(new lb::Lambertian(white));
    models.push_back(new lb::Minnaert(white, 1.5f));
    models.push_back(new lb::ModifiedPhong(white, 10.0f));
    models.push_back(new lb::OrenNayar(white, 30.0f));
    models.push_back(new lb::Phong(white, 10.0f));
    models.push_back(new lb::SimplifiedOrenNayar(white, 30.0f));
    models.push_back(new lb::WardAnisotropic(white, 0.05f, 0.2f));
    models.push_back(new lb::WardIsotropic(white, 0.2f));

    for (auto it = models.begin(); it != models.end(); ++it) {
        reflectanceModels_[(*it)->getName()] = *it;
    }

    for (auto it = reflectanceModels_.begin(); it != reflectanceModels_.end(); ++it) {
        ui_->reflectanceModelComboBox->addItem(it->first.c_str());
    }

    connect(ui_->reflectanceModelComboBox, SIGNAL(activated(int)),
            this, SLOT(updateParameterWidget(int)));

    connect(ui_->reflectanceModelComboBox, SIGNAL(activated(int)),
            this, SLOT(updateCoordSysWidget(int)));
}

lb::Brdf* ReflectanceModelDockWidget::initializeBrdf(bool isotropic)
{
    lb::Brdf* brdf;
    std::string coordinateSystemName(ui_->coordSysComboBox->currentText().toLocal8Bit());
    if (coordinateSystemName == "Half difference") {
        int numAngle1 = isotropic ? 1 : (ui_->halfDiffCsNumAngle1SpinBox->value() + 1);
        brdf = new lb::HalfDifferenceCoordinatesBrdf(ui_->halfDiffCsNumAngle0SpinBox->value(),
                                                     numAngle1,
                                                     ui_->halfDiffCsNumAngle2SpinBox->value(),
                                                     ui_->halfDiffCsNumAngle3SpinBox->value() + 1,
                                                     lb::RGB_MODEL, 3, true);
    }
    else if (coordinateSystemName == "Specular") {
        int numAngle1 = isotropic ? 1 : (ui_->specularCsNumAngle1SpinBox->value() + 1);
        brdf = new lb::SpecularCoordinatesBrdf(ui_->specularCsNumAngle0SpinBox->value(),
                                               numAngle1,
                                               ui_->specularCsNumAngle2SpinBox->value(),
                                               ui_->specularCsNumAngle3SpinBox->value() + 1,
                                               lb::RGB_MODEL, 3, true);
    }
    else if (coordinateSystemName == "Spherical") {
        int numAngle1 = isotropic ? 1 : (ui_->sphericalCsNumAngle1SpinBox->value() + 1);
        brdf = new lb::SphericalCoordinatesBrdf(ui_->sphericalCsNumAngle0SpinBox->value(),
                                                numAngle1,
                                                ui_->sphericalCsNumAngle2SpinBox->value(),
                                                ui_->sphericalCsNumAngle3SpinBox->value() + 1,
                                                lb::RGB_MODEL, 3, true);
    }
    else {
        std::cout
            << "[ReflectanceModelDockWidget::initializeBrdf] Invalid coordinate system: "
            << coordinateSystemName << std::endl;
        return 0;
    }

    return brdf;
}
<|endoftext|>


<commit_before>/*
 * =====================================================================================
 *
 *       Filename:  sift_utils.cpp
 *
 *    Description:  A collection of helper functions related to sift
 *
 *        Version:  1.0
 *        Created:  12/15/2014 11:37:05 AM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Mohamed Ashraf (m0hamed), Samy Saad (sshihata)
 *   Organization:  GUC
 *
 * =====================================================================================
 */

#include "sift_utils.h"
#include "file_utils.h"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>

using cv::imread;
using cv::Size;
using cv::Rect;

vector<KeyPoint> create_dense_keypoints(int rows, int cols, int grid_size) {
  vector<KeyPoint> points;
  for (int i=0; i<rows; i += grid_size) {
    for (int j=0; j<cols; j += grid_size) {
      points.push_back(KeyPoint(i, j, grid_size));
    }
  }
  return points;
}

vector<Mat> get_category_sift_descriptors(const string prefix, const vector<string>& category_images) {
  vector<Mat> category_sift_descriptors;
  for(string image_path : category_images) {
    cout << "Currently processing " << image_path << endl;
    Mat image = imread(prefix + image_path, 0);
    equalizeHist(image, image);
    Mat image_resized;
    resize(image, image_resized, Size(300, 250));
    cv::SiftDescriptorExtractor extractor;
    Mat sift_descriptors;
    // vector<KeyPoint> keypoints = create_dense_keypoints(300, 250, 5);
    vector<KeyPoint> keypoints;
    cv::DenseFeatureDetector detector(1.0f, 1, 0.1f, 5);
    detector.detect(image_resized, keypoints);
    extractor.compute(image_resized, keypoints, sift_descriptors);
    category_sift_descriptors.push_back(sift_descriptors);
  }
  return category_sift_descriptors;
}

void create_sift_descs(const string im_path, const string desc_path) {
  vector<string> class_paths = get_files_in_directory(im_path);
  for (string class_path : class_paths) {
    vector<string> category_images = get_files_in_directory(im_path + class_path);
    vector<Mat> descs = get_category_sift_descriptors(im_path + class_path + "/",
        category_images);
    for (int i = 0; i < descs.size(); i++) {
      string path_name = desc_path + class_path + "/" + category_images[i];
      path_name.replace(path_name.end() - 3, path_name.end(), "sift");
      write_file(path_name, descs[i], "Dense sift descriptors");
    }
  }
}

void create_bows(const string desc_path, const string bow_path) {
  vector<int> class_size;
  vector<string> im_names;
  int im_rows;
  int num_classes;

  Mat samples = read_descs(desc_path, im_names, class_size, &num_classes, &im_rows);

  Mat vocab = create_vocab(samples, class_size, num_classes, im_rows);
  Mat centers, labels;
  cv::kmeans(vocab, CENTROIDS_COUNT, labels,
      cv::TermCriteria(cv::TermCriteria::COUNT, ITERATIONS, EPSILON), ATTEMPTS,
      cv::KMEANS_RANDOM_CENTERS, centers);
  Mat histograms = get_histograms(samples, centers, im_rows);

  write_bows(desc_path, bow_path, histograms, im_names, class_size);
}

Mat read_descs(const string desc_path, vector<string>& im_names, vector<int>& class_size,
    int* num_classes, int* im_rows) {
  cout << "reading descriptors...";
  vector<string> class_paths = get_files_in_directory(desc_path);
  *num_classes = class_paths.size();
  vector<string> desc_prefix;
  for (string class_path : class_paths) {
    vector<string> tmp = get_files_in_directory(desc_path + class_path);
    vector<string> tmp_prefix(tmp.size(), desc_path + class_path + "/");
    class_size.push_back(tmp.size());
    im_names.insert(im_names.end(), tmp.begin(), tmp.end());
    desc_prefix.insert(desc_prefix.end(), tmp_prefix.begin(), tmp_prefix.end());
  }

  int cols;
  read_meta(desc_prefix[0] + im_names[0], "Dense sift descriptors", im_rows,
      &cols);
  Mat samples(im_names.size() * *im_rows, cols, CV_32FC1);
  for (int i = 0; i < im_names.size(); i++) {
    Mat roi = samples(cv::Rect(0, i * *im_rows, cols, *im_rows));
    read_file(desc_prefix[i] + im_names[i], "Dense sift descriptors", roi);
  }
  cout << "Ok" << endl;
  return samples;
}

Mat create_vocab(const Mat samples, const vector<int> class_size, const int
    num_classes, const int im_rows) {
  int sample = 0, base = 0;
  Mat vocab(num_classes * VOCAB_ITEMS_PER_CATEGORY * im_rows, samples.cols, CV_32FC1);
  cout << "creating vocab...";

  for (int c = 0; c < num_classes; c++) {
    int size = class_size[c];
    vector<int> indeces;
    for (int i = 0; i < size; i++)
      indeces.push_back(i);
    std::random_shuffle(indeces.begin(), indeces.end());
    for (int i = 0; i < VOCAB_ITEMS_PER_CATEGORY; i++) {
      Rect roi_samples(0, (indeces[i] + base) * im_rows, samples.cols, im_rows);
      Rect roi_vocab(0, sample * im_rows, vocab.cols, im_rows);
      samples(roi_samples).copyTo(vocab(roi_vocab));
      sample++;
    }
    base += size;
  }
  cout << "Ok" << endl;
  return vocab;
}

Mat get_histograms(const Mat& samples, const Mat& centers, const int im_rows) {
  cout << "encoding images...";
  Mat histograms = Mat::zeros(samples.rows / im_rows, centers.rows, CV_32SC1);
  for (int sample = 0; sample < samples.rows; sample++) {
      double min_distance = std::numeric_limits<double>::infinity();
      int center_index = -1;
      for (int center = 0; center < centers.rows; center++) {
        double dist = norm(samples.row(sample), centers.row(center), cv::NORM_L2);
        if(dist < min_distance) {
          min_distance = dist;
          center_index = center;
        }
      }
      histograms.at<int>(sample / im_rows, center_index)++;
  }
  cout << "Ok" << endl;
  return histograms;
}

void write_bows(const string desc_path, const string bow_path, const Mat& hist,
    const vector<string>& im_names, const vector<int>& class_size) {
  vector<string> class_paths = get_files_in_directory(desc_path);
  int image = 0;
  for (int c = 0; c < class_size.size(); c++) {
    for (int i = 0; i < class_size[c]; i++) {
      string file_path = bow_path + class_paths[c] + "/" + im_names[image];
      file_path.replace(file_path.end() - 4, file_path.end(), "bow");
      write_file(file_path, hist(Rect(0, image, hist.cols, 1)), "BOW");
      image++;
    }
  }
}

<commit_msg>Added flushing after cout statements with no endl<commit_after>/*
 * =====================================================================================
 *
 *       Filename:  sift_utils.cpp
 *
 *    Description:  A collection of helper functions related to sift
 *
 *        Version:  1.0
 *        Created:  12/15/2014 11:37:05 AM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Mohamed Ashraf (m0hamed), Samy Saad (sshihata)
 *   Organization:  GUC
 *
 * =====================================================================================
 */

#include "sift_utils.h"
#include "file_utils.h"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>

using cv::imread;
using cv::Size;
using cv::Rect;

vector<KeyPoint> create_dense_keypoints(int rows, int cols, int grid_size) {
  vector<KeyPoint> points;
  for (int i=0; i<rows; i += grid_size) {
    for (int j=0; j<cols; j += grid_size) {
      points.push_back(KeyPoint(i, j, grid_size));
    }
  }
  return points;
}

vector<Mat> get_category_sift_descriptors(const string prefix, const vector<string>& category_images) {
  vector<Mat> category_sift_descriptors;
  for(string image_path : category_images) {
    cout << "Currently processing " << image_path << endl;
    Mat image = imread(prefix + image_path, 0);
    equalizeHist(image, image);
    Mat image_resized;
    resize(image, image_resized, Size(300, 250));
    cv::SiftDescriptorExtractor extractor;
    Mat sift_descriptors;
    // vector<KeyPoint> keypoints = create_dense_keypoints(300, 250, 5);
    vector<KeyPoint> keypoints;
    cv::DenseFeatureDetector detector(1.0f, 1, 0.1f, 5);
    detector.detect(image_resized, keypoints);
    extractor.compute(image_resized, keypoints, sift_descriptors);
    category_sift_descriptors.push_back(sift_descriptors);
  }
  return category_sift_descriptors;
}

void create_sift_descs(const string im_path, const string desc_path) {
  vector<string> class_paths = get_files_in_directory(im_path);
  for (string class_path : class_paths) {
    vector<string> category_images = get_files_in_directory(im_path + class_path);
    vector<Mat> descs = get_category_sift_descriptors(im_path + class_path + "/",
        category_images);
    cout << "Writing sift descriptors for " << class_path << " to disk..."
        << flush;
    for (int i = 0; i < descs.size(); i++) {
      string path_name = desc_path + class_path + "/" + category_images[i];
      path_name.replace(path_name.end() - 3, path_name.end(), "sift");
      write_file(path_name, descs[i], "Dense sift descriptors");
    }
    cout << "OK" << endl;
  }
}

void create_bows(const string desc_path, const string bow_path) {
  vector<int> class_size;
  vector<string> im_names;
  int im_rows;
  int num_classes;

  Mat samples = read_descs(desc_path, im_names, class_size, &num_classes, &im_rows);

  Mat vocab = create_vocab(samples, class_size, num_classes, im_rows);
  Mat centers, labels;
  cv::kmeans(vocab, CENTROIDS_COUNT, labels,
      cv::TermCriteria(cv::TermCriteria::COUNT, ITERATIONS, EPSILON), ATTEMPTS,
      cv::KMEANS_RANDOM_CENTERS, centers);
  Mat histograms = get_histograms(samples, centers, im_rows);

  write_bows(desc_path, bow_path, histograms, im_names, class_size);
}

Mat read_descs(const string desc_path, vector<string>& im_names, vector<int>& class_size,
    int* num_classes, int* im_rows) {
  cout << "reading descriptors..." << flush;
  vector<string> class_paths = get_files_in_directory(desc_path);
  *num_classes = class_paths.size();
  vector<string> desc_prefix;
  for (string class_path : class_paths) {
    vector<string> tmp = get_files_in_directory(desc_path + class_path);
    vector<string> tmp_prefix(tmp.size(), desc_path + class_path + "/");
    class_size.push_back(tmp.size());
    im_names.insert(im_names.end(), tmp.begin(), tmp.end());
    desc_prefix.insert(desc_prefix.end(), tmp_prefix.begin(), tmp_prefix.end());
  }

  int cols;
  read_meta(desc_prefix[0] + im_names[0], "Dense sift descriptors", im_rows,
      &cols);
  Mat samples(im_names.size() * (*im_rows), cols, CV_32FC1);
  for (int i = 0; i < im_names.size(); i++) {
    Mat roi = samples(cv::Rect(0, i * *im_rows, cols, *im_rows));
    read_file(desc_prefix[i] + im_names[i], "Dense sift descriptors", roi);
  }
  cout << "Ok" << endl;
  return samples;
}

Mat create_vocab(const Mat samples, const vector<int> class_size, const int
    num_classes, const int im_rows) {
  int sample = 0, base = 0;
  Mat vocab(num_classes * VOCAB_ITEMS_PER_CATEGORY * im_rows, samples.cols, CV_32FC1);
  cout << "creating vocab..." << flush;

  for (int c = 0; c < num_classes; c++) {
    int size = class_size[c];
    vector<int> indeces;
    for (int i = 0; i < size; i++)
      indeces.push_back(i);
    std::random_shuffle(indeces.begin(), indeces.end());
    for (int i = 0; i < VOCAB_ITEMS_PER_CATEGORY; i++) {
      Rect roi_samples(0, (indeces[i] + base) * im_rows, samples.cols, im_rows);
      Rect roi_vocab(0, sample * im_rows, vocab.cols, im_rows);
      samples(roi_samples).copyTo(vocab(roi_vocab));
      sample++;
    }
    base += size;
  }
  cout << "Ok" << endl;
  return vocab;
}

Mat get_histograms(const Mat& samples, const Mat& centers, const int im_rows) {
  cout << "encoding images..." << flush;
  Mat histograms = Mat::zeros(samples.rows / im_rows, centers.rows, CV_32SC1);
  for (int sample = 0; sample < samples.rows; sample++) {
      double min_distance = std::numeric_limits<double>::infinity();
      int center_index = -1;
      for (int center = 0; center < centers.rows; center++) {
        double dist = norm(samples.row(sample), centers.row(center), cv::NORM_L2);
        if(dist < min_distance) {
          min_distance = dist;
          center_index = center;
        }
      }
      histograms.at<int>(sample / im_rows, center_index)++;
  }
  cout << "Ok" << endl;
  return histograms;
}

void write_bows(const string desc_path, const string bow_path, const Mat& hist,
    const vector<string>& im_names, const vector<int>& class_size) {
  vector<string> class_paths = get_files_in_directory(desc_path);
  int image = 0;
  for (int c = 0; c < class_size.size(); c++) {
    for (int i = 0; i < class_size[c]; i++) {
      string file_path = bow_path + class_paths[c] + "/" + im_names[image];
      file_path.replace(file_path.end() - 4, file_path.end(), "bow");
      write_file(file_path, hist(Rect(0, image, hist.cols, 1)), "BOW");
      image++;
    }
  }
}

<|endoftext|>


<commit_before>/*
  Q Light Controller
  hpmprivate-udev.cpp

  Copyright (C) Heikki Junnila

  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.txt

  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.
*/

#include <sys/types.h>
#include <sys/time.h>
#include <libudev.h>
#include <unistd.h>
#include <errno.h>
#include <QDebug>

#include "hpmprivate-udev.h"
#include "hotplugmonitor.h"

#define DEVICE_ACTION_ADD    "add"
#define DEVICE_ACTION_REMOVE "remove"
#define UDEV_NETLINK_SOURCE  "udev"
#define USB_SUBSYSTEM        "usb"
#define USB_DEVICE_TYPE      "usb_device"
#define PROPERTY_VID         "ID_VENDOR_ID"
#define PROPERTY_PID         "ID_MODEL_ID"

broken

HPMPrivate::HPMPrivate(HotPlugMonitor* parent)
    : QThread(parent)
    , m_run(false)
{
    Q_ASSERT(parent != NULL);
}

HPMPrivate::~HPMPrivate()
{
    if (isRunning() == true)
        stop();
}

void HPMPrivate::stop()
{
    if (isRunning() == true)
    {
        m_run = false;
        wait();
    }
}

void HPMPrivate::run()
{
    udev* udev_ctx = udev_new();
    Q_ASSERT(udev_ctx != NULL);

    udev_monitor* mon = udev_monitor_new_from_netlink(udev_ctx, UDEV_NETLINK_SOURCE);
    Q_ASSERT(mon != NULL);

    if (udev_monitor_filter_add_match_subsystem_devtype(mon, USB_SUBSYSTEM, USB_DEVICE_TYPE) < 0)
    {
        qWarning() << Q_FUNC_INFO << "Unable to add match for USB devices";
        udev_monitor_unref(mon);
        udev_unref(udev_ctx);
        return;
    }

    if (udev_monitor_enable_receiving(mon) < 0)
    {
        qWarning() << Q_FUNC_INFO << "Unable to enable udev uevent reception";
        udev_monitor_unref(mon);
        udev_unref(udev_ctx);
        return;
    }

    int fd = udev_monitor_get_fd(mon);
    fd_set readfs;
    FD_ZERO(&readfs);

    m_run = true;
    while (m_run == true)
    {
        struct timeval tv;
        tv.tv_sec = 1;
        tv.tv_usec = 0;

        FD_SET(fd, &readfs);
        int retval = select(fd + 1, &readfs, NULL, NULL, &tv);
        if (retval == -1)
        {
            qWarning() << Q_FUNC_INFO << strerror(errno);
            m_run = false;
        }
        else if (retval > 0 && FD_ISSET(fd, &readfs))
        {
            udev_device* dev = udev_monitor_receive_device(mon);
            if (dev != NULL)
            {
                const char* action = udev_device_get_action(dev);
                const char* vendor = udev_device_get_property_value(dev, PROPERTY_VID);
                const char* product = udev_device_get_property_value(dev, PROPERTY_PID);
                if (action == NULL || vendor == NULL || product == NULL)
                {
                    qWarning() << Q_FUNC_INFO << "Unable to get device properties"
                               << (void*) dev;
                }
                else if (strcmp(action, DEVICE_ACTION_ADD) == 0)
                {
                    uint vid = QString(vendor).toUInt(0, 16);
                    uint pid = QString(product).toUInt(0, 16);
                    HotPlugMonitor* hpm = qobject_cast<HotPlugMonitor*> (parent());
                    Q_ASSERT(hpm != NULL);
                    hpm->emitDeviceAdded(vid, pid);
                }
                else if (strcmp(action, DEVICE_ACTION_REMOVE) == 0)
                {
                    uint vid = QString(vendor).toUInt(0, 16);
                    uint pid = QString(product).toUInt(0, 16);
                    HotPlugMonitor* hpm = qobject_cast<HotPlugMonitor*> (parent());
                    Q_ASSERT(hpm != NULL);
                    hpm->emitDeviceRemoved(vid, pid);
                }
                else
                {
                    qWarning() << Q_FUNC_INFO << "Unhandled udev action:" << action;
                }

                udev_device_unref(dev);
            }
        }
    }

    udev_monitor_unref(mon);
    udev_unref(udev_ctx);
}
<commit_msg>Alright, Travis fails correctly now<commit_after>/*
  Q Light Controller
  hpmprivate-udev.cpp

  Copyright (C) Heikki Junnila

  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.txt

  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.
*/

#include <sys/types.h>
#include <sys/time.h>
#include <libudev.h>
#include <unistd.h>
#include <errno.h>
#include <QDebug>

#include "hpmprivate-udev.h"
#include "hotplugmonitor.h"

#define DEVICE_ACTION_ADD    "add"
#define DEVICE_ACTION_REMOVE "remove"
#define UDEV_NETLINK_SOURCE  "udev"
#define USB_SUBSYSTEM        "usb"
#define USB_DEVICE_TYPE      "usb_device"
#define PROPERTY_VID         "ID_VENDOR_ID"
#define PROPERTY_PID         "ID_MODEL_ID"

HPMPrivate::HPMPrivate(HotPlugMonitor* parent)
    : QThread(parent)
    , m_run(false)
{
    Q_ASSERT(parent != NULL);
}

HPMPrivate::~HPMPrivate()
{
    if (isRunning() == true)
        stop();
}

void HPMPrivate::stop()
{
    if (isRunning() == true)
    {
        m_run = false;
        wait();
    }
}

void HPMPrivate::run()
{
    udev* udev_ctx = udev_new();
    Q_ASSERT(udev_ctx != NULL);

    udev_monitor* mon = udev_monitor_new_from_netlink(udev_ctx, UDEV_NETLINK_SOURCE);
    Q_ASSERT(mon != NULL);

    if (udev_monitor_filter_add_match_subsystem_devtype(mon, USB_SUBSYSTEM, USB_DEVICE_TYPE) < 0)
    {
        qWarning() << Q_FUNC_INFO << "Unable to add match for USB devices";
        udev_monitor_unref(mon);
        udev_unref(udev_ctx);
        return;
    }

    if (udev_monitor_enable_receiving(mon) < 0)
    {
        qWarning() << Q_FUNC_INFO << "Unable to enable udev uevent reception";
        udev_monitor_unref(mon);
        udev_unref(udev_ctx);
        return;
    }

    int fd = udev_monitor_get_fd(mon);
    fd_set readfs;
    FD_ZERO(&readfs);

    m_run = true;
    while (m_run == true)
    {
        struct timeval tv;
        tv.tv_sec = 1;
        tv.tv_usec = 0;

        FD_SET(fd, &readfs);
        int retval = select(fd + 1, &readfs, NULL, NULL, &tv);
        if (retval == -1)
        {
            qWarning() << Q_FUNC_INFO << strerror(errno);
            m_run = false;
        }
        else if (retval > 0 && FD_ISSET(fd, &readfs))
        {
            udev_device* dev = udev_monitor_receive_device(mon);
            if (dev != NULL)
            {
                const char* action = udev_device_get_action(dev);
                const char* vendor = udev_device_get_property_value(dev, PROPERTY_VID);
                const char* product = udev_device_get_property_value(dev, PROPERTY_PID);
                if (action == NULL || vendor == NULL || product == NULL)
                {
                    qWarning() << Q_FUNC_INFO << "Unable to get device properties"
                               << (void*) dev;
                }
                else if (strcmp(action, DEVICE_ACTION_ADD) == 0)
                {
                    uint vid = QString(vendor).toUInt(0, 16);
                    uint pid = QString(product).toUInt(0, 16);
                    HotPlugMonitor* hpm = qobject_cast<HotPlugMonitor*> (parent());
                    Q_ASSERT(hpm != NULL);
                    hpm->emitDeviceAdded(vid, pid);
                }
                else if (strcmp(action, DEVICE_ACTION_REMOVE) == 0)
                {
                    uint vid = QString(vendor).toUInt(0, 16);
                    uint pid = QString(product).toUInt(0, 16);
                    HotPlugMonitor* hpm = qobject_cast<HotPlugMonitor*> (parent());
                    Q_ASSERT(hpm != NULL);
                    hpm->emitDeviceRemoved(vid, pid);
                }
                else
                {
                    qWarning() << Q_FUNC_INFO << "Unhandled udev action:" << action;
                }

                udev_device_unref(dev);
            }
        }
    }

    udev_monitor_unref(mon);
    udev_unref(udev_ctx);
}
<|endoftext|>