<commit_before>/**
 * @file main.cpp
 *
 * @brief File containing main Q-Learning algorithm and all necessary associated functions to implementing this routine.
 *
 * @author Machine Learning Team 2015-2016
 * @date March, 2016
 */

#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
* @brief Gives a std::string representation of a primitive type.
*
* @remark Can be used to print priority queue contents.
* @param x Primitive type such as int, double, long ...
* @return std::string conversion of param x
*/
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution, computes 'evolution variable' of system.
 *
 * This function computes a normal distribution over the parameterised number of loop iterations in order
 * to provide a function which explores the state space dilligently initially which then decays off to the
 * optimal solution after a large number of loop iterations.
 *
 * The normal distribution used by this function is:
 *
 * \f[ a e^{-\frac{bt^2}{c}} + \epsilon \f]
 *
 * where a, b and c are scaling coefficients (see method body) and \f$\epsilon\f$ is some small offset.
 *
 * @param t Number of loop iterations.
 * @return Value of normal distribution at t loop iterations.
 */
double temperature(unsigned long t);

//function to select next action

/**
 * @brief Selects an action to perform based on experience, iterations and probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @param iterations Number of loop iterations completed.
 * @return integer corresponding to chosen action
 */
int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations);

/**
 * @brief Updates the utility (Q-value) of the system.
 *
 * Utility (Q-Value) of the system is updated via the Temporal Difference Learning Rule given by the following equation,
 *
 * \f[ Q_{i+1} (s,a) = Q_i (s,a) + \alpha [R(s') + \gamma \underset{a}{max} Q(s',a) - Q_i (s,a)] \f]
 *
 * where Q represents the utility of a state-action pair, \f$ \alpha \f$ is the learning rate, \f$ \gamma \f$ is the discount
 * factor and \f$ max_a (Q) \f$ yields the action-maximum of the Q space. The learning rate should be set to a low value for
 * highly stochastic, asymmetric systems or a high value for a lowly stochastic, symmetric system - this value lies between 0 and 1.
 * The discount factor (also in the interval [0,1]) represents the time considerations of the learning algorithm, lower values indicate
 * "living in the moment", whilst higher values indicate "planning for the future".
 *
 * @param space Reference to StateSpace object
 * @param action Integer code to previous performed action
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm (in the interval [0,1])
 * @param gamma Discount factor applied to q-learning equation (in the interval [0,1])
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

/**
 * @brief Program launcher!
 *
 * Contains all initialisations including setting up the StateSpace and connecting to robot via a proxy. Holds main
 * program loop to perform algorithm continuously using calls to selectAction and updateQ sequentially to update
 * utilities and choose most optimal actions to perform based on position and velocity.
 *
 * @return Program exit code
 */
int main() {
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try {
		broker = AL::ALBroker::createBroker(
			brokerName,
			brokerIp,
			brokerPort,
			pip,
			pport,
			0);
	}
	// Throw error and quit if a broker could not be created
	catch (...) {
		std::cerr << "Failed to connect broker to: "
			<< pip
			<< ":"
			<< pport
			<< std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha = 0.5;
	//discount factor
	const double gamma = 0.5;

	//seed rng
	std::srand(static_cast<unsigned int>(std::time(NULL)));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int, double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards, 0);
	initiator_queue.enqueueWithPriority(action_backwards, 0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	//create the state space
	StateSpace space(100, 50, M_PI * 0.25, 1.0, initiator_queue);

	//state objects
	State current_state(0, 0, FORWARD);
	State old_state(0, 0, FORWARD);

	unsigned long i = 0;
	while (true) {
		// set current state angle to angle received from encoder
		// and set current state velocity to difference in new and
		// old state angles over some time difference
		current_state.theta = M_PI * (encoder.GetAngle()) / 180;
		current_state.theta_dot = (current_state.theta - old_state.theta) / 700; //Needs actual time
		current_state.robot_state = static_cast<ROBOT_STATE>(chosen_action);

		// call updateQ function with state space, old and current states
		// and learning rate, discount factor
		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		// set old_state to current_state
		old_state = current_state;

		// determine chosen_action for current state
		chosen_action = selectAction(space[current_state], i);

		// depending upon chosen action, call robot movement tools proxy with either
		// swingForwards or swingBackwards commands.
		(chosen_action) ? movementToolsProxy.callVoid("swingForwards") : movementToolsProxy.callVoid("swingBackwards");

		++i;
	}

	return 1;
}

double temperature(unsigned long t) {
	return 100.0*std::exp((-8.0*t*t) / (2600.0*2600.0)) + 0.1;//0.1 is an offset
}

int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations) {

	typedef std::vector<std::pair<int, double> > VecPair ;

	//turn priority queue into a vector of pairs
	VecPair vec = a_queue.saveOrderedQueueAsVector();

    //sum for partition function
	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}

	// compute Boltzmann factors for action-values and enqueue to vec
	for (VecPair::iterator iter = vec.begin(); iter < vec.end(); ++iter) {
		iter->second = std::exp(iter->second / temperature(iterations)) / sum;
	}

	// calculate cumulative probability distribution
	for (VecPair::iterator iter = vec.begin()++, end = vec.end(); iter < end; ++iter) {
        //second member of pair becomes addition of its current value
        //and that of the index before it
		iter->second += (iter-1)->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}

void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma) {
	//oldQ value reference
	double oldQ = space[old_state].search(action).second;

	//reward given to current state
	double R = new_state.getReward();

	//optimal Q value for new state i.e. first element
	double maxQ = space[new_state].peekFront().second;

	//new Q value determined by Q learning algorithm
	double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

	// change priority of action to new Q value
	space[old_state].changePriority(action, newQ);
}
/* OLD SELECT ACTION
int selectAction(const PriorityQueue<int, double>& a_queue, unsigned long iterations) {
	/*
	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);
	double sum = 0.0;
	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}
	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature(iterations)) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}
	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}
	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;
	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached

	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	return (rand_num > 0.5)?0:1;
}
*/
<commit_msg>sleep added after encoder calibration<commit_after>/**
 * @file main.cpp
 *
 * @brief File containing main Q-Learning algorithm and all necessary associated functions to implementing this routine.
 *
 * @author Machine Learning Team 2015-2016
 * @date March, 2016
 */

#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
* @brief Gives a std::string representation of a primitive type.
*
* @remark Can be used to print priority queue contents.
* @param x Primitive type such as int, double, long ...
* @return std::string conversion of param x
*/
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution, computes 'evolution variable' of system.
 *
 * This function computes a normal distribution over the parameterised number of loop iterations in order
 * to provide a function which explores the state space dilligently initially which then decays off to the
 * optimal solution after a large number of loop iterations.
 *
 * The normal distribution used by this function is:
 *
 * \f[ a e^{-\frac{bt^2}{c}} + \epsilon \f]
 *
 * where a, b and c are scaling coefficients (see method body) and \f$\epsilon\f$ is some small offset.
 *
 * @param t Number of loop iterations.
 * @return Value of normal distribution at t loop iterations.
 */
double temperature(unsigned long t);

//function to select next action

/**
 * @brief Selects an action to perform based on experience, iterations and probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @param iterations Number of loop iterations completed.
 * @return integer corresponding to chosen action
 */
int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations);

/**
 * @brief Updates the utility (Q-value) of the system.
 *
 * Utility (Q-Value) of the system is updated via the Temporal Difference Learning Rule given by the following equation,
 *
 * \f[ Q_{i+1} (s,a) = Q_i (s,a) + \alpha [R(s') + \gamma \underset{a}{max} Q(s',a) - Q_i (s,a)] \f]
 *
 * where Q represents the utility of a state-action pair, \f$ \alpha \f$ is the learning rate, \f$ \gamma \f$ is the discount
 * factor and \f$ max_a (Q) \f$ yields the action-maximum of the Q space. The learning rate should be set to a low value for
 * highly stochastic, asymmetric systems or a high value for a lowly stochastic, symmetric system - this value lies between 0 and 1.
 * The discount factor (also in the interval [0,1]) represents the time considerations of the learning algorithm, lower values indicate
 * "living in the moment", whilst higher values indicate "planning for the future".
 *
 * @param space Reference to StateSpace object
 * @param action Integer code to previous performed action
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm (in the interval [0,1])
 * @param gamma Discount factor applied to q-learning equation (in the interval [0,1])
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

/**
 * @brief Program launcher!
 *
 * Contains all initialisations including setting up the StateSpace and connecting to robot via a proxy. Holds main
 * program loop to perform algorithm continuously using calls to selectAction and updateQ sequentially to update
 * utilities and choose most optimal actions to perform based on position and velocity.
 *
 * @return Program exit code
 */
int main() {
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try {
		broker = AL::ALBroker::createBroker(
			brokerName,
			brokerIp,
			brokerPort,
			pip,
			pport,
			0);
	}
	// Throw error and quit if a broker could not be created
	catch (...) {
		std::cerr << "Failed to connect broker to: "
			<< pip
			<< ":"
			<< pport
			<< std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha = 0.5;
	//discount factor
	const double gamma = 0.5;

	//seed rng
	std::srand(static_cast<unsigned int>(std::time(NULL)));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int, double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards, 0);
	initiator_queue.enqueueWithPriority(action_backwards, 0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	qi::os::msleep(5000);

	//create the state space
	StateSpace space(100, 50, M_PI * 0.25, 1.0, initiator_queue);

	//state objects
	State current_state(0, 0, FORWARD);
	State old_state(0, 0, FORWARD);

	unsigned long i = 0;
	while (true) {
		// set current state angle to angle received from encoder
		// and set current state velocity to difference in new and
		// old state angles over some time difference
		current_state.theta = M_PI * (encoder.GetAngle()) / 180;
		current_state.theta_dot = (current_state.theta - old_state.theta) / 700; //Needs actual time
		current_state.robot_state = static_cast<ROBOT_STATE>(chosen_action);

		// call updateQ function with state space, old and current states
		// and learning rate, discount factor
		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		// set old_state to current_state
		old_state = current_state;

		// determine chosen_action for current state
		chosen_action = selectAction(space[current_state], i);

		// depending upon chosen action, call robot movement tools proxy with either
		// swingForwards or swingBackwards commands.
		(chosen_action) ? movementToolsProxy.callVoid("swingForwards") : movementToolsProxy.callVoid("swingBackwards");

		++i;
	}

	return 1;
}

double temperature(unsigned long t) {
	return 100.0*std::exp((-8.0*t*t) / (2600.0*2600.0)) + 0.1;//0.1 is an offset
}

int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations) {

	typedef std::vector<std::pair<int, double> > VecPair ;

	//turn priority queue into a vector of pairs
	VecPair vec = a_queue.saveOrderedQueueAsVector();

    //sum for partition function
	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}

	// compute Boltzmann factors for action-values and enqueue to vec
	for (VecPair::iterator iter = vec.begin(); iter < vec.end(); ++iter) {
		iter->second = std::exp(iter->second / temperature(iterations)) / sum;
	}

	// calculate cumulative probability distribution
	for (VecPair::iterator iter = vec.begin()++, end = vec.end(); iter < end; ++iter) {
        //second member of pair becomes addition of its current value
        //and that of the index before it
		iter->second += (iter-1)->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}

void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma) {
	//oldQ value reference
	double oldQ = space[old_state].search(action).second;

	//reward given to current state
	double R = new_state.getReward();

	//optimal Q value for new state i.e. first element
	double maxQ = space[new_state].peekFront().second;

	//new Q value determined by Q learning algorithm
	double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

	// change priority of action to new Q value
	space[old_state].changePriority(action, newQ);
}
/* OLD SELECT ACTION
int selectAction(const PriorityQueue<int, double>& a_queue, unsigned long iterations) {
	/*
	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);
	double sum = 0.0;
	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}
	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature(iterations)) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}
	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}
	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;
	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached

	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	return (rand_num > 0.5)?0:1;
}
*/
<|endoftext|>


<commit_before>#include <papyrus/PapyrusIdentifier.h>

#include <common/CapricaConfig.h>

#include <papyrus/PapyrusFunctionParameter.h>
#include <papyrus/PapyrusObject.h>
#include <papyrus/PapyrusProperty.h>
#include <papyrus/PapyrusStructMember.h>
#include <papyrus/PapyrusVariable.h>
#include <papyrus/statements/PapyrusDeclareStatement.h>

namespace caprica { namespace papyrus {

PapyrusIdentifier PapyrusIdentifier::Property(const CapricaFileLocation& loc, PapyrusProperty* p) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Property, loc);
  id.prop = p;
  id.name = p->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::Variable(const CapricaFileLocation& loc, PapyrusVariable* v) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Variable, loc);
  id.var = v;
  id.name = v->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::FunctionParameter(const CapricaFileLocation& loc, PapyrusFunctionParameter* p) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Parameter, loc);
  id.param = p;
  id.name = p->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::DeclStatement(const CapricaFileLocation& loc, statements::PapyrusDeclareStatement* s) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::DeclareStatement, loc);
  id.declStatement = s;
  id.name = s->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::StructMember(const CapricaFileLocation& loc, PapyrusStructMember* m) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::StructMember, loc);
  id.structMember = m;
  id.name = m->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::Function(const CapricaFileLocation& loc, PapyrusFunction* f) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Function, loc);
  id.func = f;
  id.name = f->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::ArrayFunction(const CapricaFileLocation& loc, PapyrusBuiltinArrayFunctionKind fk, const PapyrusType& elemType) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Unresolved, loc);
  id.arrayFuncKind = fk;
  id.arrayFuncElementType = std::make_shared<PapyrusType>(elemType);
  return id;
}

pex::PexValue PapyrusIdentifier::generateLoad(pex::PexFile* file, pex::PexFunctionBuilder& bldr, pex::PexValue::Identifier base) const {
  namespace op = caprica::pex::op;
  switch (type) {
    case PapyrusIdentifierType::Property:
      if (CapricaConfig::enableCKOptimizations && prop->isAuto() && !prop->isReadOnly() && !base.tmpVar && file->getStringValue(base.name) == "self") {
        // We can only do this for properties on ourselves. (CK does this even on parents)
        return pex::PexValue::Identifier(file->getString(prop->getAutoVarName()));
      } else {
        auto ret = bldr.allocTemp(resultType());
        bldr << op::propget{ file->getString(prop->name), base, ret };
        return ret;
      }
    case PapyrusIdentifierType::Variable:
      return pex::PexValue::Identifier(file->getString(var->name));
    case PapyrusIdentifierType::Parameter:
      return pex::PexValue::Identifier(file->getString(param->name));
    case PapyrusIdentifierType::DeclareStatement:
      return pex::PexValue::Identifier(file->getString(declStatement->name));
    case PapyrusIdentifierType::StructMember:
    {
      auto ret = bldr.allocTemp(resultType());
      bldr << op::structget{ ret, base, file->getString(structMember->name) };
      return ret;
    }
    case PapyrusIdentifierType::BuiltinStateField:
      return pex::PexValue::Identifier(file->getString("::State"));

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to generate a load of an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::generateStore(pex::PexFile* file, pex::PexFunctionBuilder& bldr, pex::PexValue::Identifier base, pex::PexValue val) const {
  namespace op = caprica::pex::op;
  switch (type) {
    case PapyrusIdentifierType::Property:
      if (prop->isReadOnly())
        CapricaError::fatal(location, "Attempted to generate a store to a read-only property!");
      if (CapricaConfig::enableCKOptimizations && prop->isAuto() && !prop->isReadOnly() && !base.tmpVar && file->getStringValue(base.name) == "self") {
        // We can only do this for properties on ourselves. (CK does this even on parents)
        bldr << op::assign{ pex::PexValue::Identifier(file->getString(prop->getAutoVarName())), val };
      } else {
        bldr << op::propset{ file->getString(prop->name), base, val };
      }
      return;
    case PapyrusIdentifierType::Variable:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString(var->name)), val };
      return;
    case PapyrusIdentifierType::Parameter:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString(prop->name)), val };
      return;
    case PapyrusIdentifierType::DeclareStatement:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString(declStatement->name)), val };
      return;
    case PapyrusIdentifierType::StructMember:
      bldr << op::structset{ base, file->getString(structMember->name), val };
      return;
    case PapyrusIdentifierType::BuiltinStateField:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString("::State")), val };
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to generate a store to an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::ensureAssignable() const {
  switch (type) {
    case PapyrusIdentifierType::Property:
      if (prop->isReadOnly())
        return CapricaError::error(location, "You cannot assign to the read-only property '%s'.", prop->name.c_str());
      if (prop->isConst())
        return CapricaError::error(location, "You cannot assign to the const property '%s'.", prop->name.c_str());
      if (prop->parent->isConst())
        return CapricaError::error(location, "You cannot assign to the '%s' property because the parent script '%s' is marked as const.", prop->name.c_str(), prop->parent->name.c_str());
      return;
    case PapyrusIdentifierType::Variable:
      if (var->isConst())
        return CapricaError::error(location, "You cannot assign to the const variable '%s'.", var->name.c_str());
      if (var->parent->isConst())
        return CapricaError::error(location, "You cannot assign to the variable '%s' because the parent script '%s' is marked as const.", var->name.c_str(), var->parent->name.c_str());
      return;
    case PapyrusIdentifierType::StructMember:
      if (structMember->isConst())
        return CapricaError::error(location, "You cannot assign to the '%s' member of a '%s' struct because it is marked as const.", structMember->name.c_str(), structMember->parent->name.c_str());
      return;

    case PapyrusIdentifierType::Parameter:
    case PapyrusIdentifierType::DeclareStatement:
    case PapyrusIdentifierType::BuiltinStateField:
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      return;
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::markRead() {
  switch (type) {
    case PapyrusIdentifierType::Variable:
      var->referenceState.isRead = true;
      return;

    case PapyrusIdentifierType::Property:
    case PapyrusIdentifierType::Parameter:
    case PapyrusIdentifierType::DeclareStatement:
    case PapyrusIdentifierType::StructMember:
    case PapyrusIdentifierType::BuiltinStateField:
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to assign to an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::markWritten() {
  switch (type) {
    case PapyrusIdentifierType::Variable:
      var->referenceState.isWritten = true;
      return;

    case PapyrusIdentifierType::Property:
    case PapyrusIdentifierType::Parameter:
    case PapyrusIdentifierType::DeclareStatement:
    case PapyrusIdentifierType::StructMember:
    case PapyrusIdentifierType::BuiltinStateField:
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to assign to an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

PapyrusType PapyrusIdentifier::resultType() const {
  switch (type) {
    case PapyrusIdentifierType::Property:
      return prop->type;
    case PapyrusIdentifierType::Variable:
      return var->type;
    case PapyrusIdentifierType::Parameter:
      return param->type;
    case PapyrusIdentifierType::DeclareStatement:
      return declStatement->type;
    case PapyrusIdentifierType::StructMember:
      return structMember->type;
    case PapyrusIdentifierType::BuiltinStateField:
      return PapyrusType::String(location);

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to get the result type of an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

}}
<commit_msg>Fix BuiltinArrayFunction identifiers.<commit_after>#include <papyrus/PapyrusIdentifier.h>

#include <common/CapricaConfig.h>

#include <papyrus/PapyrusFunctionParameter.h>
#include <papyrus/PapyrusObject.h>
#include <papyrus/PapyrusProperty.h>
#include <papyrus/PapyrusStructMember.h>
#include <papyrus/PapyrusVariable.h>
#include <papyrus/statements/PapyrusDeclareStatement.h>

namespace caprica { namespace papyrus {

PapyrusIdentifier PapyrusIdentifier::Property(const CapricaFileLocation& loc, PapyrusProperty* p) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Property, loc);
  id.prop = p;
  id.name = p->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::Variable(const CapricaFileLocation& loc, PapyrusVariable* v) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Variable, loc);
  id.var = v;
  id.name = v->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::FunctionParameter(const CapricaFileLocation& loc, PapyrusFunctionParameter* p) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Parameter, loc);
  id.param = p;
  id.name = p->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::DeclStatement(const CapricaFileLocation& loc, statements::PapyrusDeclareStatement* s) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::DeclareStatement, loc);
  id.declStatement = s;
  id.name = s->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::StructMember(const CapricaFileLocation& loc, PapyrusStructMember* m) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::StructMember, loc);
  id.structMember = m;
  id.name = m->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::Function(const CapricaFileLocation& loc, PapyrusFunction* f) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::Function, loc);
  id.func = f;
  id.name = f->name;
  return id;
}
PapyrusIdentifier PapyrusIdentifier::ArrayFunction(const CapricaFileLocation& loc, PapyrusBuiltinArrayFunctionKind fk, const PapyrusType& elemType) {
  auto id = PapyrusIdentifier(PapyrusIdentifierType::BuiltinArrayFunction, loc);
  id.arrayFuncKind = fk;
  id.arrayFuncElementType = std::make_shared<PapyrusType>(elemType);
  return id;
}

pex::PexValue PapyrusIdentifier::generateLoad(pex::PexFile* file, pex::PexFunctionBuilder& bldr, pex::PexValue::Identifier base) const {
  namespace op = caprica::pex::op;
  switch (type) {
    case PapyrusIdentifierType::Property:
      if (CapricaConfig::enableCKOptimizations && prop->isAuto() && !prop->isReadOnly() && !base.tmpVar && file->getStringValue(base.name) == "self") {
        // We can only do this for properties on ourselves. (CK does this even on parents)
        return pex::PexValue::Identifier(file->getString(prop->getAutoVarName()));
      } else {
        auto ret = bldr.allocTemp(resultType());
        bldr << op::propget{ file->getString(prop->name), base, ret };
        return ret;
      }
    case PapyrusIdentifierType::Variable:
      return pex::PexValue::Identifier(file->getString(var->name));
    case PapyrusIdentifierType::Parameter:
      return pex::PexValue::Identifier(file->getString(param->name));
    case PapyrusIdentifierType::DeclareStatement:
      return pex::PexValue::Identifier(file->getString(declStatement->name));
    case PapyrusIdentifierType::StructMember:
    {
      auto ret = bldr.allocTemp(resultType());
      bldr << op::structget{ ret, base, file->getString(structMember->name) };
      return ret;
    }
    case PapyrusIdentifierType::BuiltinStateField:
      return pex::PexValue::Identifier(file->getString("::State"));

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to generate a load of an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::generateStore(pex::PexFile* file, pex::PexFunctionBuilder& bldr, pex::PexValue::Identifier base, pex::PexValue val) const {
  namespace op = caprica::pex::op;
  switch (type) {
    case PapyrusIdentifierType::Property:
      if (prop->isReadOnly())
        CapricaError::fatal(location, "Attempted to generate a store to a read-only property!");
      if (CapricaConfig::enableCKOptimizations && prop->isAuto() && !prop->isReadOnly() && !base.tmpVar && file->getStringValue(base.name) == "self") {
        // We can only do this for properties on ourselves. (CK does this even on parents)
        bldr << op::assign{ pex::PexValue::Identifier(file->getString(prop->getAutoVarName())), val };
      } else {
        bldr << op::propset{ file->getString(prop->name), base, val };
      }
      return;
    case PapyrusIdentifierType::Variable:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString(var->name)), val };
      return;
    case PapyrusIdentifierType::Parameter:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString(prop->name)), val };
      return;
    case PapyrusIdentifierType::DeclareStatement:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString(declStatement->name)), val };
      return;
    case PapyrusIdentifierType::StructMember:
      bldr << op::structset{ base, file->getString(structMember->name), val };
      return;
    case PapyrusIdentifierType::BuiltinStateField:
      bldr << op::assign{ pex::PexValue::Identifier(file->getString("::State")), val };
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to generate a store to an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::ensureAssignable() const {
  switch (type) {
    case PapyrusIdentifierType::Property:
      if (prop->isReadOnly())
        return CapricaError::error(location, "You cannot assign to the read-only property '%s'.", prop->name.c_str());
      if (prop->isConst())
        return CapricaError::error(location, "You cannot assign to the const property '%s'.", prop->name.c_str());
      if (prop->parent->isConst())
        return CapricaError::error(location, "You cannot assign to the '%s' property because the parent script '%s' is marked as const.", prop->name.c_str(), prop->parent->name.c_str());
      return;
    case PapyrusIdentifierType::Variable:
      if (var->isConst())
        return CapricaError::error(location, "You cannot assign to the const variable '%s'.", var->name.c_str());
      if (var->parent->isConst())
        return CapricaError::error(location, "You cannot assign to the variable '%s' because the parent script '%s' is marked as const.", var->name.c_str(), var->parent->name.c_str());
      return;
    case PapyrusIdentifierType::StructMember:
      if (structMember->isConst())
        return CapricaError::error(location, "You cannot assign to the '%s' member of a '%s' struct because it is marked as const.", structMember->name.c_str(), structMember->parent->name.c_str());
      return;

    case PapyrusIdentifierType::Parameter:
    case PapyrusIdentifierType::DeclareStatement:
    case PapyrusIdentifierType::BuiltinStateField:
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      return;
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::markRead() {
  switch (type) {
    case PapyrusIdentifierType::Variable:
      var->referenceState.isRead = true;
      return;

    case PapyrusIdentifierType::Property:
    case PapyrusIdentifierType::Parameter:
    case PapyrusIdentifierType::DeclareStatement:
    case PapyrusIdentifierType::StructMember:
    case PapyrusIdentifierType::BuiltinStateField:
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to assign to an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

void PapyrusIdentifier::markWritten() {
  switch (type) {
    case PapyrusIdentifierType::Variable:
      var->referenceState.isWritten = true;
      return;

    case PapyrusIdentifierType::Property:
    case PapyrusIdentifierType::Parameter:
    case PapyrusIdentifierType::DeclareStatement:
    case PapyrusIdentifierType::StructMember:
    case PapyrusIdentifierType::BuiltinStateField:
      return;

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to assign to an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

PapyrusType PapyrusIdentifier::resultType() const {
  switch (type) {
    case PapyrusIdentifierType::Property:
      return prop->type;
    case PapyrusIdentifierType::Variable:
      return var->type;
    case PapyrusIdentifierType::Parameter:
      return param->type;
    case PapyrusIdentifierType::DeclareStatement:
      return declStatement->type;
    case PapyrusIdentifierType::StructMember:
      return structMember->type;
    case PapyrusIdentifierType::BuiltinStateField:
      return PapyrusType::String(location);

    case PapyrusIdentifierType::Function:
    case PapyrusIdentifierType::BuiltinArrayFunction:
      CapricaError::logicalFatal("Invalid PapyrusIdentifierType!");
    case PapyrusIdentifierType::Unresolved:
      CapricaError::fatal(location, "Attempted to get the result type of an unresolved identifier '%s'!", name.c_str());
  }
  CapricaError::logicalFatal("Unknown PapyrusIdentifierType!");
}

}}
<|endoftext|>


<commit_before>#include <bits/stdc++.h>
using namespace std;

class node{

public:
	int stateNumber;
	map<char,int> transitions;
	bool endState;
	bool startState;
};

class Automaton{
protected:

private:
	vector<node> graph;
	vector<char> alphabet;
public:
	int evaluateLetter(char letter)
	{
		//Revisara la letra y regresara un estado para seguir evaluando

		return 0;
	}

	bool isInAlphabet(char letter)
	{
		//Verificara que la palabra este en el alfabeto
		return false;
	}

	void setGraph(vector<node> g)
	{
		//metodo que copiara el grafo de entrada a esta clase Automata
	}

	void setAlphabet(vector<char> a)
	{
		//metodo que copiara el alfabeto de entrada
	}

};

int main()
{

}<commit_msg>Version preliminar del programa, realizado en 1 hora<commit_after>#include <bits/stdc++.h>
using namespace std;

struct node
{
	map<char,int> transitions;
	bool endState;
	bool startState;
};

class Automaton{
protected:

private:
	vector<node> graph;
	vector<char> alphabet;
	int position;

	bool isInAlphabet(char letter)
	{
		for(int  i=0;i<alphabet.size();i++)
		{
			if(letter==alphabet[i])return true;
		}
		return false;
	}
public:
	Automaton();
	~Automaton();

	bool isAcceptedWord(string word)
	{
		for(int i=0;i<graph.size();i++)
		{
			if(graph[i].startState)
			{
				position=i;
				break;
			}
		}

		for(int i=0;i<word.size();i++)
		{
			if(isInAlphabet(word[i]))
			{

				position=graph[position].transitions[word[i]];
			}
			else return false;
		}

		if(graph[position].endState)return true;
		return false;
	}

	void setGraph(vector<node> g)
	{
		//metodo que copiara el grafo de entrada a esta clase Automata
		for(int i=0;i<g.size();i++)
		{
			this->graph.push_back(g[i]);
		}
	}

	void setAlphabet(string a)
	{
		for(int i=0;i<a.size();i++)
		{
			this->alphabet.push_back(a[i]);
		}
	}

};

int main()
{

}<|endoftext|>


<commit_before>#include "mitkOpenGLRenderer.h"
#include "Mapper.h"
#include "mitkImageMapper2D.h"
#include "BaseVtkMapper2D.h"
#include "BaseVtkMapper3D.h"
#include "LevelWindow.h"
#include "mitkVtkInteractorCameraController.h"
#include "mitkVtkRenderWindow.h"
#include "mitkRenderWindow.h"

#include <vtkRenderer.h>
#include <vtkLight.h>
#include <vtkLightKit.h>
#include <vtkRenderWindow.h>
#include <vtkTransform.h>

#include "PlaneGeometry.h"
#include "mitkProperties.h"
#include <queue>
#include <utility>

//##ModelId=3E33ECF301AD
mitk::OpenGLRenderer::OpenGLRenderer() : m_VtkMapperPresent(false)
{
  m_CameraController=NULL;
  m_CameraController = VtkInteractorCameraController::New();
  m_CameraController->AddRenderer(this);

  m_DataChangedCommand = itk::MemberCommand<mitk::OpenGLRenderer>::New();
  m_DataChangedCommand->SetCallbackFunction(this, DataChangedEvent);
}

//##ModelId=3E3D28AB0018
void mitk::OpenGLRenderer::SetData(mitk::DataTreeIterator* iterator)
{
  if(iterator!=GetData())
  {

    bool geometry_is_set=false;

    if(m_DataTreeIterator!=NULL)
    {
      //remove old connections
      mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
      while(it->hasNext())
      {
        it->next();
        BaseData::Pointer data=it->get()->GetData();
      }
      delete it;
    }

    BaseRenderer::SetData(iterator);

    if (iterator != NULL)
    {
      //initialize world geometry: use first slice of first node containing an image
      mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
      while(it->hasNext())
      {
        it->next();
        BaseData::Pointer data=it->get()->GetData();
        if(data.IsNotNull())
        {
          if(geometry_is_set==false)
          {
            Image::Pointer image = dynamic_cast<Image*>(data.GetPointer());
            if(image.IsNotNull())
            {
              SetWorldGeometry(image->GetGeometry2D(0, 0));
              geometry_is_set=true;
            }
          }
          //@todo add connections
          //data->AddObserver(itk::EndEvent(), m_DataChangedCommand);
        }
      }
      delete it;
    }

    //update the vtk-based mappers
    Update(); //this is only called to check, whether we have vtk-based mappers!
    UpdateVtkActors();

    Modified();
  }
}

//##ModelId=3ED91D060305
void mitk::OpenGLRenderer::UpdateVtkActors()
{
  VtkInteractorCameraController* vicc=dynamic_cast<VtkInteractorCameraController*>(m_CameraController.GetPointer());

  if (m_VtkMapperPresent == false)
  {
    if(vicc!=NULL)
      vicc->GetVtkInteractor()->Disable();
    return;
  }

  if(vicc!=NULL)
    vicc->GetVtkInteractor()->Enable();

  //    m_LightKit->RemoveLightsFromRenderer(this->m_VtkRenderer);

  //    m_MitkVtkRenderWindow->RemoveRenderer(m_VtkRenderer);
  //    m_VtkRenderer->Delete();

  if(m_VtkRenderer==NULL)
  {
    m_VtkRenderer = vtkRenderer::New();
    m_VtkRenderer->SetLayer(0);
    m_MitkVtkRenderWindow->AddRenderer( this->m_VtkRenderer );
  }

  m_VtkRenderer->RemoveAllProps();

  //strange: when using a simple light, the backface of the planes are not shown (regardless of SetNumberOfLayers)
  //m_Light->Delete();
  //m_Light = vtkLight::New();
  //m_VtkRenderer->AddLight( m_Light );
  if(m_LightKit!=NULL)
  {
    m_LightKit = vtkLightKit::New();
    m_LightKit->AddLightsToRenderer(m_VtkRenderer);
  }

  //    try
  if (m_DataTreeIterator != NULL)
  {
    mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
    while(it->hasNext())
    {
      it->next();
      mitk::Mapper::Pointer mapper = it->get()->GetMapper(m_MapperID);
      if(mapper.IsNotNull())
      {
        BaseVtkMapper2D* anVtkMapper2D;
        anVtkMapper2D=dynamic_cast<BaseVtkMapper2D*>(mapper.GetPointer());
        if(anVtkMapper2D != NULL)
        {
          anVtkMapper2D->Update(this);
          m_VtkRenderer->AddProp(anVtkMapper2D->GetProp());
        }
        else
        {
          BaseVtkMapper3D* anVtkMapper3D;
          anVtkMapper3D=dynamic_cast<BaseVtkMapper3D*>(mapper.GetPointer());
          if(anVtkMapper3D != NULL)
          {
            anVtkMapper3D->Update(this);
            m_VtkRenderer->AddProp(anVtkMapper3D->GetProp());
          }
        }
      }
    }
    delete it;
  }

  //    catch( ::itk::ExceptionObject ee)
  //    {
  //        printf("%s\n",ee.what());
  ////        itkGenericOutputMacro(ee->what());
  //    }
  //    catch( ...)
  //    {
  //            printf("test\n");
  //    }
}

//##ModelId=3E330D260255
void mitk::OpenGLRenderer::Update()
{
  if(m_DataTreeIterator == NULL) return;

  m_VtkMapperPresent=false;

  mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
  while(it->hasNext())
  {
    it->next();
    //      mitk::LevelWindow lw;
    unsigned int dummy[] = {10,10,10};
    //Geometry3D geometry(3,dummy);
    mitk::Mapper::Pointer mapper = it->get()->GetMapper(m_MapperID);
    if(mapper.IsNotNull())
    {
      Mapper2D* mapper2d=dynamic_cast<Mapper2D*>(mapper.GetPointer());
      if(mapper2d != NULL)
      {
        BaseVtkMapper2D* vtkmapper2d=dynamic_cast<BaseVtkMapper2D*>(mapper.GetPointer());
        if(vtkmapper2d != NULL)
        {
          vtkmapper2d->Update(this);
          m_VtkMapperPresent=true;
        }
        else
          mapper2d->Update();
        ImageMapper2D* imagemapper2d=dynamic_cast<ImageMapper2D*>(mapper.GetPointer());
      }
      else
      {
        BaseVtkMapper3D* vtkmapper3d=dynamic_cast<BaseVtkMapper3D*>(mapper.GetPointer());
        if(vtkmapper3d != NULL)
        {
          vtkmapper3d->Update(this);
          m_VtkMapperPresent=true;
        }
      }
    }
  }

  delete it;
  Modified();
  m_LastUpdateTime=GetMTime();
}

//##ModelId=3E330D2903CC
void mitk::OpenGLRenderer::Render()
{
  //if we do not have any data, we do nothing else but clearing our window
  if(GetData() == NULL)
  {
    glClear(GL_COLOR_BUFFER_BIT);
    return;
  }

  //has someone transformed our worldgeometry-node? if so, incorporate this transform into
  //the worldgeometry itself and reset the transform of the node to identity
  /*	if(m_WorldGeometryTransformTime<m_WorldGeometryNode->GetVtkTransform()->GetMTime())
  {
  vtkTransform *i;
  m_WorldGeometry->TransformGeometry(m_WorldGeometryNode->GetVtkTransform());
  m_WorldGeometryNode->GetVtkTransform()->Identity();
  m_WorldGeometryTransformTime=GetWorldGeometryNode()->GetVtkTransform()->GetMTime();
  }
  */
  //has the data tree been changed?
  if(dynamic_cast<mitk::DataTree*>(GetData()->getTree()) == NULL ) return;
  //	if(m_LastUpdateTime<((mitk::DataTree*)GetData()->getTree())->GetMTime())
  if(m_LastUpdateTime < dynamic_cast<mitk::DataTree*>(GetData()->getTree())->GetMTime() )
  {
    //yes: update vtk-actors
    Update();
    UpdateVtkActors();
  }
  else
    //has anything else changed (geometry to display, etc.)?
    if (m_LastUpdateTime<GetMTime() ||
      m_LastUpdateTime<GetDisplayGeometry()->GetMTime() ||
      m_LastUpdateTime<GetDisplayGeometry()->GetWorldGeometry()->GetMTime())
    {
      //std::cout << "OpenGLRenderer calling its update..." << std::endl;
      Update();
    }
    else
      if(m_MapperID==2)
      { //@todo in 3D mode wird sonst nix geupdated, da z.Z. weder camera noch nderung des Baums beachtet wird!!!
        Update();
      }

      glClear(GL_COLOR_BUFFER_BIT);

      PlaneGeometry* myPlaneGeom =
        dynamic_cast<PlaneGeometry *>((mitk::Geometry2D*)(GetWorldGeometry()));

      glViewport (0, 0, m_Size[0], m_Size[1]);
      glMatrixMode( GL_PROJECTION );
      glLoadIdentity();
      gluOrtho2D( 0.0, m_Size[0], 0.0, m_Size[1] );
      glMatrixMode( GL_MODELVIEW );

      mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
      mitk::DataTree::Pointer tree = dynamic_cast <mitk::DataTree *> (it->getTree());
      //	std::cout << "Render:: tree: " <<  *tree << std::endl;

      typedef std::pair<int, GLMapper2D*> LayerMapperPair;
      std::priority_queue<LayerMapperPair> layers;
      int mapperNo = 0;
      while(it->hasNext())
      {
        it->next();

        mitk::DataTreeNode::Pointer node = it->get();
        mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID);
        if(mapper.IsNotNull())
        {
          GLMapper2D* mapper2d=dynamic_cast<GLMapper2D*>(mapper.GetPointer());
          if(mapper2d!=NULL)
          {
            // mapper without a layer property are painted first
            int layer=-1;
            node->GetIntProperty("layer", layer, this);
            // pushing negative layer value, since default sort for
            // priority_queue is lessthan
            layers.push(LayerMapperPair(- (layer<<16) - mapperNo ,mapper2d));
            mapperNo++;
          }
        }
      }

      delete it;
      while (!layers.empty()) {
        layers.top().second->Paint(this);
        layers.pop();
      }
      if(m_VtkMapperPresent) {
        m_MitkVtkRenderWindow->MitkRender();
      }
}

/*!
\brief Initialize the OpenGLRenderer

This method is called from the two Constructors
*/
void mitk::OpenGLRenderer::InitRenderer(mitk::RenderWindow* renderwindow)
{
  BaseRenderer::InitRenderer(renderwindow);

  m_InitNeeded = true;
  m_ResizeNeeded = true;

  m_MitkVtkRenderWindow = mitk::VtkRenderWindow::New();
  m_MitkVtkRenderWindow->SetMitkRenderer(this);
  /**@todo SetNumberOfLayers commented out, because otherwise the backface of the planes are not shown (only, when a light is added).
  * But we need SetNumberOfLayers(2) later, when we want to prevent vtk to clear the widget before it renders (i.e., when we render something in the scene before vtk).
  */
  //m_MitkVtkRenderWindow->SetNumberOfLayers(2);

  m_VtkRenderer = vtkRenderer::New();
  m_MitkVtkRenderWindow->AddRenderer( m_VtkRenderer );

  //strange: when using a simple light, the backface of the planes are not shown (regardless of SetNumberOfLayers)
  //m_Light = vtkLight::New();
  //m_VtkRenderer->AddLight( m_Light );
  m_LightKit = vtkLightKit::New();
  m_LightKit->AddLightsToRenderer(m_VtkRenderer);

  if(m_CameraController)
    ((VtkInteractorCameraController*)m_CameraController.GetPointer())->SetRenderWindow(m_MitkVtkRenderWindow);

  //we should disable vtk doublebuffering, but then it doesn't work
  //m_MitkVtkRenderWindow->SwapBuffersOff();
}

/*!
\brief Destructs the OpenGLRenderer.
*/
//##ModelId=3E33ECF301B7
mitk::OpenGLRenderer::~OpenGLRenderer() {
  m_VtkRenderer->Delete();
  m_MitkVtkRenderWindow->Delete();
}

/*!
\brief Initialize the OpenGL Window
*/
//##ModelId=3E33145B0096
void mitk::OpenGLRenderer::Initialize( ) {
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glColor3f(1.0, 0.0, 0.0);
}

/*!
\brief Resize the OpenGL Window
*/
//##ModelId=3E33145B00D2
void mitk::OpenGLRenderer::Resize(int w, int h)
{
  glViewport (0, 0, w, h);
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  gluOrtho2D( 0.0, w, 0.0, h );
  glMatrixMode( GL_MODELVIEW );

  BaseRenderer::Resize(w, h);

  Update();
  //    m_MitkVtkRenderWindow->SetSize(w,h); //FIXME?
}

/*!
\brief Render the scene
*/
//##ModelId=3E33145B005A
void mitk::OpenGLRenderer::Paint( )
{
  Render();
  glFlush();
}

//##ModelId=3E3314B0005C
void mitk::OpenGLRenderer::SetWindowId(void * id)
{
  m_MitkVtkRenderWindow->SetWindowId( id );
}

//##ModelId=3E3799420227
void mitk::OpenGLRenderer::InitSize(int w, int h)
{
  m_MitkVtkRenderWindow->SetSize(w,h);
  GetDisplayGeometry()->Fit();
  Modified();
  Update();
}

//##ModelId=3EF59AD20235
void mitk::OpenGLRenderer::SetMapperID(const MapperSlotId mapperId)
{
  Superclass::SetMapperID(mapperId);
  Update();
  UpdateVtkActors();
}

//##ModelId=3EF162760271
void mitk::OpenGLRenderer::MakeCurrent()
{
  if(m_RenderWindow!=NULL)
  {
    m_RenderWindow->MakeCurrent();
  }
}

void mitk::OpenGLRenderer::DataChangedEvent(const itk::Object *caller, const itk::EventObject &event)
{
  if(m_RenderWindow!=NULL)
  {
    m_RenderWindow->Update();
  }
}<commit_msg>unix compatibility<commit_after>#include "mitkOpenGLRenderer.h"
#include "Mapper.h"
#include "mitkImageMapper2D.h"
#include "BaseVtkMapper2D.h"
#include "BaseVtkMapper3D.h"
#include "LevelWindow.h"
#include "mitkVtkInteractorCameraController.h"
#include "mitkVtkRenderWindow.h"
#include "mitkRenderWindow.h"

#include <vtkRenderer.h>
#include <vtkLight.h>
#include <vtkLightKit.h>
#include <vtkRenderWindow.h>
#include <vtkTransform.h>

#include "PlaneGeometry.h"
#include "mitkProperties.h"
#include <queue>
#include <utility>

//##ModelId=3E33ECF301AD
mitk::OpenGLRenderer::OpenGLRenderer() : m_VtkMapperPresent(false)
{
  m_CameraController=NULL;
  m_CameraController = VtkInteractorCameraController::New();
  m_CameraController->AddRenderer(this);

  m_DataChangedCommand = itk::MemberCommand<mitk::OpenGLRenderer>::New();
#ifndef WIN32
  m_DataChangedCommand->SetCallbackFunction(this, DataChangedEvent);
#else
  m_DataChangedCommand->SetCallbackFunction(this, &DataChangedEvent);
#endif
}

//##ModelId=3E3D28AB0018
void mitk::OpenGLRenderer::SetData(mitk::DataTreeIterator* iterator)
{
  if(iterator!=GetData())
  {

    bool geometry_is_set=false;

    if(m_DataTreeIterator!=NULL)
    {
      //remove old connections
      mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
      while(it->hasNext())
      {
        it->next();
        BaseData::Pointer data=it->get()->GetData();
      }
      delete it;
    }

    BaseRenderer::SetData(iterator);

    if (iterator != NULL)
    {
      //initialize world geometry: use first slice of first node containing an image
      mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
      while(it->hasNext())
      {
        it->next();
        BaseData::Pointer data=it->get()->GetData();
        if(data.IsNotNull())
        {
          if(geometry_is_set==false)
          {
            Image::Pointer image = dynamic_cast<Image*>(data.GetPointer());
            if(image.IsNotNull())
            {
              SetWorldGeometry(image->GetGeometry2D(0, 0));
              geometry_is_set=true;
            }
          }
          //@todo add connections
          //data->AddObserver(itk::EndEvent(), m_DataChangedCommand);
        }
      }
      delete it;
    }

    //update the vtk-based mappers
    Update(); //this is only called to check, whether we have vtk-based mappers!
    UpdateVtkActors();

    Modified();
  }
}

//##ModelId=3ED91D060305
void mitk::OpenGLRenderer::UpdateVtkActors()
{
  VtkInteractorCameraController* vicc=dynamic_cast<VtkInteractorCameraController*>(m_CameraController.GetPointer());

  if (m_VtkMapperPresent == false)
  {
    if(vicc!=NULL)
      vicc->GetVtkInteractor()->Disable();
    return;
  }

  if(vicc!=NULL)
    vicc->GetVtkInteractor()->Enable();

  //    m_LightKit->RemoveLightsFromRenderer(this->m_VtkRenderer);

  //    m_MitkVtkRenderWindow->RemoveRenderer(m_VtkRenderer);
  //    m_VtkRenderer->Delete();

  if(m_VtkRenderer==NULL)
  {
    m_VtkRenderer = vtkRenderer::New();
    m_VtkRenderer->SetLayer(0);
    m_MitkVtkRenderWindow->AddRenderer( this->m_VtkRenderer );
  }

  m_VtkRenderer->RemoveAllProps();

  //strange: when using a simple light, the backface of the planes are not shown (regardless of SetNumberOfLayers)
  //m_Light->Delete();
  //m_Light = vtkLight::New();
  //m_VtkRenderer->AddLight( m_Light );
  if(m_LightKit!=NULL)
  {
    m_LightKit = vtkLightKit::New();
    m_LightKit->AddLightsToRenderer(m_VtkRenderer);
  }

  //    try
  if (m_DataTreeIterator != NULL)
  {
    mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
    while(it->hasNext())
    {
      it->next();
      mitk::Mapper::Pointer mapper = it->get()->GetMapper(m_MapperID);
      if(mapper.IsNotNull())
      {
        BaseVtkMapper2D* anVtkMapper2D;
        anVtkMapper2D=dynamic_cast<BaseVtkMapper2D*>(mapper.GetPointer());
        if(anVtkMapper2D != NULL)
        {
          anVtkMapper2D->Update(this);
          m_VtkRenderer->AddProp(anVtkMapper2D->GetProp());
        }
        else
        {
          BaseVtkMapper3D* anVtkMapper3D;
          anVtkMapper3D=dynamic_cast<BaseVtkMapper3D*>(mapper.GetPointer());
          if(anVtkMapper3D != NULL)
          {
            anVtkMapper3D->Update(this);
            m_VtkRenderer->AddProp(anVtkMapper3D->GetProp());
          }
        }
      }
    }
    delete it;
  }

  //    catch( ::itk::ExceptionObject ee)
  //    {
  //        printf("%s\n",ee.what());
  ////        itkGenericOutputMacro(ee->what());
  //    }
  //    catch( ...)
  //    {
  //            printf("test\n");
  //    }
}

//##ModelId=3E330D260255
void mitk::OpenGLRenderer::Update()
{
  if(m_DataTreeIterator == NULL) return;

  m_VtkMapperPresent=false;

  mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
  while(it->hasNext())
  {
    it->next();
    //      mitk::LevelWindow lw;
    unsigned int dummy[] = {10,10,10};
    //Geometry3D geometry(3,dummy);
    mitk::Mapper::Pointer mapper = it->get()->GetMapper(m_MapperID);
    if(mapper.IsNotNull())
    {
      Mapper2D* mapper2d=dynamic_cast<Mapper2D*>(mapper.GetPointer());
      if(mapper2d != NULL)
      {
        BaseVtkMapper2D* vtkmapper2d=dynamic_cast<BaseVtkMapper2D*>(mapper.GetPointer());
        if(vtkmapper2d != NULL)
        {
          vtkmapper2d->Update(this);
          m_VtkMapperPresent=true;
        }
        else
          mapper2d->Update();
        ImageMapper2D* imagemapper2d=dynamic_cast<ImageMapper2D*>(mapper.GetPointer());
      }
      else
      {
        BaseVtkMapper3D* vtkmapper3d=dynamic_cast<BaseVtkMapper3D*>(mapper.GetPointer());
        if(vtkmapper3d != NULL)
        {
          vtkmapper3d->Update(this);
          m_VtkMapperPresent=true;
        }
      }
    }
  }

  delete it;
  Modified();
  m_LastUpdateTime=GetMTime();
}

//##ModelId=3E330D2903CC
void mitk::OpenGLRenderer::Render()
{
  //if we do not have any data, we do nothing else but clearing our window
  if(GetData() == NULL)
  {
    glClear(GL_COLOR_BUFFER_BIT);
    return;
  }

  //has someone transformed our worldgeometry-node? if so, incorporate this transform into
  //the worldgeometry itself and reset the transform of the node to identity
  /*	if(m_WorldGeometryTransformTime<m_WorldGeometryNode->GetVtkTransform()->GetMTime())
  {
  vtkTransform *i;
  m_WorldGeometry->TransformGeometry(m_WorldGeometryNode->GetVtkTransform());
  m_WorldGeometryNode->GetVtkTransform()->Identity();
  m_WorldGeometryTransformTime=GetWorldGeometryNode()->GetVtkTransform()->GetMTime();
  }
  */
  //has the data tree been changed?
  if(dynamic_cast<mitk::DataTree*>(GetData()->getTree()) == NULL ) return;
  //	if(m_LastUpdateTime<((mitk::DataTree*)GetData()->getTree())->GetMTime())
  if(m_LastUpdateTime < dynamic_cast<mitk::DataTree*>(GetData()->getTree())->GetMTime() )
  {
    //yes: update vtk-actors
    Update();
    UpdateVtkActors();
  }
  else
    //has anything else changed (geometry to display, etc.)?
    if (m_LastUpdateTime<GetMTime() ||
      m_LastUpdateTime<GetDisplayGeometry()->GetMTime() ||
      m_LastUpdateTime<GetDisplayGeometry()->GetWorldGeometry()->GetMTime())
    {
      //std::cout << "OpenGLRenderer calling its update..." << std::endl;
      Update();
    }
    else
      if(m_MapperID==2)
      { //@todo in 3D mode wird sonst nix geupdated, da z.Z. weder camera noch nderung des Baums beachtet wird!!!
        Update();
      }

      glClear(GL_COLOR_BUFFER_BIT);

      PlaneGeometry* myPlaneGeom =
        dynamic_cast<PlaneGeometry *>((mitk::Geometry2D*)(GetWorldGeometry()));

      glViewport (0, 0, m_Size[0], m_Size[1]);
      glMatrixMode( GL_PROJECTION );
      glLoadIdentity();
      gluOrtho2D( 0.0, m_Size[0], 0.0, m_Size[1] );
      glMatrixMode( GL_MODELVIEW );

      mitk::DataTreeIterator* it=m_DataTreeIterator->clone();
      mitk::DataTree::Pointer tree = dynamic_cast <mitk::DataTree *> (it->getTree());
      //	std::cout << "Render:: tree: " <<  *tree << std::endl;

      typedef std::pair<int, GLMapper2D*> LayerMapperPair;
      std::priority_queue<LayerMapperPair> layers;
      int mapperNo = 0;
      while(it->hasNext())
      {
        it->next();

        mitk::DataTreeNode::Pointer node = it->get();
        mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID);
        if(mapper.IsNotNull())
        {
          GLMapper2D* mapper2d=dynamic_cast<GLMapper2D*>(mapper.GetPointer());
          if(mapper2d!=NULL)
          {
            // mapper without a layer property are painted first
            int layer=-1;
            node->GetIntProperty("layer", layer, this);
            // pushing negative layer value, since default sort for
            // priority_queue is lessthan
            layers.push(LayerMapperPair(- (layer<<16) - mapperNo ,mapper2d));
            mapperNo++;
          }
        }
      }

      delete it;
      while (!layers.empty()) {
        layers.top().second->Paint(this);
        layers.pop();
      }
      if(m_VtkMapperPresent) {
        m_MitkVtkRenderWindow->MitkRender();
      }
}

/*!
\brief Initialize the OpenGLRenderer

This method is called from the two Constructors
*/
void mitk::OpenGLRenderer::InitRenderer(mitk::RenderWindow* renderwindow)
{
  BaseRenderer::InitRenderer(renderwindow);

  m_InitNeeded = true;
  m_ResizeNeeded = true;

  m_MitkVtkRenderWindow = mitk::VtkRenderWindow::New();
  m_MitkVtkRenderWindow->SetMitkRenderer(this);
  /**@todo SetNumberOfLayers commented out, because otherwise the backface of the planes are not shown (only, when a light is added).
  * But we need SetNumberOfLayers(2) later, when we want to prevent vtk to clear the widget before it renders (i.e., when we render something in the scene before vtk).
  */
  //m_MitkVtkRenderWindow->SetNumberOfLayers(2);

  m_VtkRenderer = vtkRenderer::New();
  m_MitkVtkRenderWindow->AddRenderer( m_VtkRenderer );

  //strange: when using a simple light, the backface of the planes are not shown (regardless of SetNumberOfLayers)
  //m_Light = vtkLight::New();
  //m_VtkRenderer->AddLight( m_Light );
  m_LightKit = vtkLightKit::New();
  m_LightKit->AddLightsToRenderer(m_VtkRenderer);

  if(m_CameraController)
    ((VtkInteractorCameraController*)m_CameraController.GetPointer())->SetRenderWindow(m_MitkVtkRenderWindow);

  //we should disable vtk doublebuffering, but then it doesn't work
  //m_MitkVtkRenderWindow->SwapBuffersOff();
}

/*!
\brief Destructs the OpenGLRenderer.
*/
//##ModelId=3E33ECF301B7
mitk::OpenGLRenderer::~OpenGLRenderer() {
  m_VtkRenderer->Delete();
  m_MitkVtkRenderWindow->Delete();
}

/*!
\brief Initialize the OpenGL Window
*/
//##ModelId=3E33145B0096
void mitk::OpenGLRenderer::Initialize( ) {
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glColor3f(1.0, 0.0, 0.0);
}

/*!
\brief Resize the OpenGL Window
*/
//##ModelId=3E33145B00D2
void mitk::OpenGLRenderer::Resize(int w, int h)
{
  glViewport (0, 0, w, h);
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  gluOrtho2D( 0.0, w, 0.0, h );
  glMatrixMode( GL_MODELVIEW );

  BaseRenderer::Resize(w, h);

  Update();
  //    m_MitkVtkRenderWindow->SetSize(w,h); //FIXME?
}

/*!
\brief Render the scene
*/
//##ModelId=3E33145B005A
void mitk::OpenGLRenderer::Paint( )
{
  Render();
  glFlush();
}

//##ModelId=3E3314B0005C
void mitk::OpenGLRenderer::SetWindowId(void * id)
{
  m_MitkVtkRenderWindow->SetWindowId( id );
}

//##ModelId=3E3799420227
void mitk::OpenGLRenderer::InitSize(int w, int h)
{
  m_MitkVtkRenderWindow->SetSize(w,h);
  GetDisplayGeometry()->Fit();
  Modified();
  Update();
}

//##ModelId=3EF59AD20235
void mitk::OpenGLRenderer::SetMapperID(const MapperSlotId mapperId)
{
  Superclass::SetMapperID(mapperId);
  Update();
  UpdateVtkActors();
}

//##ModelId=3EF162760271
void mitk::OpenGLRenderer::MakeCurrent()
{
  if(m_RenderWindow!=NULL)
  {
    m_RenderWindow->MakeCurrent();
  }
}

void mitk::OpenGLRenderer::DataChangedEvent(const itk::Object *caller, const itk::EventObject &event)
{
  if(m_RenderWindow!=NULL)
  {
    m_RenderWindow->Update();
  }
}<|endoftext|>


<commit_before>// Ignore unused parameter warnings coming from cppunit headers
#include <libmesh/ignore_warnings.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <libmesh/restore_warnings.h>

#include <libmesh/equation_systems.h>
#include <libmesh/mesh.h>
#include <libmesh/mesh_communication.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/replicated_mesh.h>
#include <libmesh/exodusII_io.h>

#include "test_comm.h"

// THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
// std::auto_ptr, which in turn produces -Wdeprecated-declarations
// warnings.  These can be ignored in GCC as long as we wrap the
// offending code in appropriate pragmas.  We can't get away with a
// single ignore_warnings.h inclusion at the beginning of this file,
// since the libmesh headers pull in a restore_warnings.h at some
// point.  We also don't bother restoring warnings at the end of this
// file since it's not a header.
#include <libmesh/ignore_warnings.h>

using namespace libMesh;

Number x_plus_y (const Point& p,
                 const Parameters&,
                 const std::string&,
                 const std::string&)
{
  const Real & x = p(0);
  const Real & y = p(1);

  return x + y;
}

class MeshInputTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( MeshInputTest );

#ifdef LIBMESH_HAVE_EXODUS_API
  CPPUNIT_TEST( testExodusCopyElementSolution );
#endif

  CPPUNIT_TEST( testMeshMoveConstructor );
  CPPUNIT_TEST_SUITE_END();

private:

public:
  void setUp()
  {}

  void tearDown()
  {}

#ifdef LIBMESH_HAVE_EXODUS_API
  void testExodusCopyElementSolution ()
  {
    {
      Mesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("e", CONSTANT, MONOMIAL);

      MeshTools::Generation::build_square (mesh,
                                           3, 3,
                                           0., 1., 0., 1.);

      es.init();
      sys.project_solution(x_plus_y, nullptr, es.parameters);

      ExodusII_IO exii(mesh);

      // Don't try to write element data as nodal data
      std::set<std::string> sys_list;
      exii.write_equation_systems("mesh_with_soln.e", es, &sys_list);

      // Just write it as element data
      exii.write_element_data(es);
    }

    // copy_elemental_solution currently requires ReplicatedMesh
    {
      ReplicatedMesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("teste", CONSTANT, MONOMIAL);

      ExodusII_IO exii(mesh);

      if (mesh.processor_id() == 0)
        exii.read("mesh_with_soln.e");
      MeshCommunication().broadcast(mesh);
      mesh.prepare_for_use();

      es.init();

      // Read the solution e into variable teste.
      //
      // With complex numbers, we'll only bother reading the real
      // part.
#ifdef LIBMESH_USE_COMPLEX_NUMBERS
      exii.copy_elemental_solution(sys, "teste", "r_e");
#else
      exii.copy_elemental_solution(sys, "teste", "e");
#endif

      for (Real x = 1.L/6.L; x < 1; x += 1.L/3.L)
        for (Real y = 1.L/6.L; y < 1; y += 1.L/3.L)
          {
            Point p(x,y);
            CPPUNIT_ASSERT_DOUBLES_EQUAL(libmesh_real(sys.point_value(0,p)),
                                         libmesh_real(x+y),
                                         TOLERANCE*TOLERANCE);
          }
    }
  }
#endif

  void testMeshMoveConstructor ()
  {
    Mesh mesh(*TestCommWorld);
    MeshTools::Generation::build_square (mesh,
                                         3, 3,
                                         0., 1., 0., 1.);

    // Construct mesh2, stealing the resources of the original.
    Mesh mesh2(std::move(mesh));

    // Make sure mesh2 now has the 9 elements.
    CPPUNIT_ASSERT_EQUAL(mesh2.n_elem(),
                         static_cast<unsigned int>(9));

    // Verify that the moved-from mesh's Partitioner and BoundaryInfo
    // objects were successfully stolen.  Note: moved-from unique_ptrs
    // are guaranteed to compare equal to nullptr, see e.g. Section
    // 20.8.1/4 of the standard.
    // https://stackoverflow.com/questions/24061767/is-unique-ptr-guaranteed-to-store-nullptr-after-move
    CPPUNIT_ASSERT(!mesh.partitioner());
    CPPUNIT_ASSERT(!mesh.boundary_info);
  }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshInputTest );
<commit_msg>Construct Real explicitly<commit_after>// Ignore unused parameter warnings coming from cppunit headers
#include <libmesh/ignore_warnings.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <libmesh/restore_warnings.h>

#include <libmesh/equation_systems.h>
#include <libmesh/mesh.h>
#include <libmesh/mesh_communication.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/replicated_mesh.h>
#include <libmesh/exodusII_io.h>

#include "test_comm.h"

// THE CPPUNIT_TEST_SUITE_END macro expands to code that involves
// std::auto_ptr, which in turn produces -Wdeprecated-declarations
// warnings.  These can be ignored in GCC as long as we wrap the
// offending code in appropriate pragmas.  We can't get away with a
// single ignore_warnings.h inclusion at the beginning of this file,
// since the libmesh headers pull in a restore_warnings.h at some
// point.  We also don't bother restoring warnings at the end of this
// file since it's not a header.
#include <libmesh/ignore_warnings.h>

using namespace libMesh;

Number x_plus_y (const Point& p,
                 const Parameters&,
                 const std::string&,
                 const std::string&)
{
  const Real & x = p(0);
  const Real & y = p(1);

  return x + y;
}

class MeshInputTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( MeshInputTest );

#ifdef LIBMESH_HAVE_EXODUS_API
  CPPUNIT_TEST( testExodusCopyElementSolution );
#endif

  CPPUNIT_TEST( testMeshMoveConstructor );
  CPPUNIT_TEST_SUITE_END();

private:

public:
  void setUp()
  {}

  void tearDown()
  {}

#ifdef LIBMESH_HAVE_EXODUS_API
  void testExodusCopyElementSolution ()
  {
    {
      Mesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("e", CONSTANT, MONOMIAL);

      MeshTools::Generation::build_square (mesh,
                                           3, 3,
                                           0., 1., 0., 1.);

      es.init();
      sys.project_solution(x_plus_y, nullptr, es.parameters);

      ExodusII_IO exii(mesh);

      // Don't try to write element data as nodal data
      std::set<std::string> sys_list;
      exii.write_equation_systems("mesh_with_soln.e", es, &sys_list);

      // Just write it as element data
      exii.write_element_data(es);
    }

    // copy_elemental_solution currently requires ReplicatedMesh
    {
      ReplicatedMesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("teste", CONSTANT, MONOMIAL);

      ExodusII_IO exii(mesh);

      if (mesh.processor_id() == 0)
        exii.read("mesh_with_soln.e");
      MeshCommunication().broadcast(mesh);
      mesh.prepare_for_use();

      es.init();

      // Read the solution e into variable teste.
      //
      // With complex numbers, we'll only bother reading the real
      // part.
#ifdef LIBMESH_USE_COMPLEX_NUMBERS
      exii.copy_elemental_solution(sys, "teste", "r_e");
#else
      exii.copy_elemental_solution(sys, "teste", "e");
#endif

      for (Real x = Real(1.L/6.L); x < 1; x += Real(1.L/3.L))
        for (Real y = Real(1.L/6.L); y < 1; y += Real(1.L/3.L))
          {
            Point p(x,y);
            CPPUNIT_ASSERT_DOUBLES_EQUAL(libmesh_real(sys.point_value(0,p)),
                                         libmesh_real(x+y),
                                         TOLERANCE*TOLERANCE);
          }
    }
  }
#endif

  void testMeshMoveConstructor ()
  {
    Mesh mesh(*TestCommWorld);
    MeshTools::Generation::build_square (mesh,
                                         3, 3,
                                         0., 1., 0., 1.);

    // Construct mesh2, stealing the resources of the original.
    Mesh mesh2(std::move(mesh));

    // Make sure mesh2 now has the 9 elements.
    CPPUNIT_ASSERT_EQUAL(mesh2.n_elem(),
                         static_cast<unsigned int>(9));

    // Verify that the moved-from mesh's Partitioner and BoundaryInfo
    // objects were successfully stolen.  Note: moved-from unique_ptrs
    // are guaranteed to compare equal to nullptr, see e.g. Section
    // 20.8.1/4 of the standard.
    // https://stackoverflow.com/questions/24061767/is-unique-ptr-guaranteed-to-store-nullptr-after-move
    CPPUNIT_ASSERT(!mesh.partitioner());
    CPPUNIT_ASSERT(!mesh.boundary_info);
  }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshInputTest );
<|endoftext|>


<commit_before>/*! \file DebugRenderer.cpp
 *  \author Jared Hoberock
 *  \brief Implementation of DebugRenderer class.
 */

#include "DebugRenderer.h"
#include "../geometry/Point.h"
#include "../geometry/Vector.h"
#include "../geometry/Ray.h"
#include "../primitives/Scene.h"
#include "../records/RenderFilm.h"
#include "../shading/Material.h"
#include "../shading/ScatteringDistributionFunction.h"
#include "../primitives/SurfacePrimitive.h"
#include "../primitives/SurfacePrimitiveList.h"

using namespace boost;
using namespace gpcpu;

DebugRenderer
  ::DebugRenderer(void)
{
  ;
} // end DebugRenderer::DebugRenderer()

DebugRenderer
  ::DebugRenderer(shared_ptr<const Scene> s,
                  shared_ptr<Record> r)
    :Parent(s,r)
{
  ;
} // end DebugRenderer::DebugRenderer()

void DebugRenderer
  ::kernel(ProgressCallback &progress)
{
  // XXX TODO: kill this
  RenderFilm *film = dynamic_cast<RenderFilm*>(mRecord.get());
  float2 step(1.0f / film->getWidth(),
              1.0f / film->getHeight());

  Ray r;
  Point o;
  Vector3 d;
  Normal n;
  float pdf;
  bool delta;
  Primitive::Intersection inter;
  float2 uv(0,0);

  // sample from the list of sensors
  const SurfacePrimitive *sensor = 0;
  float temp;
  mScene->getSensors()->sampleSurfaceArea(0.0f, &sensor, temp);

  progress.restart(film->getWidth() * film->getHeight());
  for(size_t y = 0;
      y < film->getHeight();
      ++y, uv[1] += step[1])
  {
    uv[0] = 0;
    for(size_t x = 0;
        x < film->getWidth();
        ++x, uv[0] += step[0])
    {
      // sample a point on the sensor
      DifferentialGeometry dgSensor;
      sensor->sampleSurfaceArea(0,0,0,dgSensor,pdf);

      // generate a Ray
      ScatteringDistributionFunction &s = *sensor->getMaterial()->evaluateSensor(dgSensor);

      // sample a sensing direction
      s.sample(dgSensor, uv[0], uv[1], 0.5f, d, pdf, delta);
      r = Ray(dgSensor.getPoint(), d);

      Spectrum L(0.0f,0.0f,0.0f);

      // intersect the Scene
      if(mScene->intersect(r, inter))
      {
        const Primitive *prim = inter.getPrimitive();
        const SurfacePrimitive *surface = dynamic_cast<const SurfacePrimitive*>(prim);
        const Material *material = surface->getMaterial();
        ScatteringDistributionFunction *f = static_cast<const SurfacePrimitive*>(prim)->getMaterial()->evaluateScattering(inter.getDifferentialGeometry());
        L = f->evaluate(-d,inter.getDifferentialGeometry(),-d);
      } // end if

      film->deposit(x,y,L);

      // purge all malloc'd memory for this sample
      ScatteringDistributionFunction::mPool.freeAll();

      ++progress;
    } // end for x
  } // end for y
} // end DebugRenderer::kernel()

<commit_msg>Kill warnings.<commit_after>/*! \file DebugRenderer.cpp
 *  \author Jared Hoberock
 *  \brief Implementation of DebugRenderer class.
 */

#include "DebugRenderer.h"
#include "../geometry/Point.h"
#include "../geometry/Vector.h"
#include "../geometry/Ray.h"
#include "../primitives/Scene.h"
#include "../records/RenderFilm.h"
#include "../shading/Material.h"
#include "../shading/ScatteringDistributionFunction.h"
#include "../primitives/SurfacePrimitive.h"
#include "../primitives/SurfacePrimitiveList.h"

using namespace boost;
using namespace gpcpu;

DebugRenderer
  ::DebugRenderer(void)
{
  ;
} // end DebugRenderer::DebugRenderer()

DebugRenderer
  ::DebugRenderer(shared_ptr<const Scene> s,
                  shared_ptr<Record> r)
    :Parent(s,r)
{
  ;
} // end DebugRenderer::DebugRenderer()

void DebugRenderer
  ::kernel(ProgressCallback &progress)
{
  // XXX TODO: kill this
  RenderFilm *film = dynamic_cast<RenderFilm*>(mRecord.get());
  float2 step(1.0f / film->getWidth(),
              1.0f / film->getHeight());

  Ray r;
  Point o;
  Vector3 d;
  Normal n;
  float pdf;
  bool delta;
  Primitive::Intersection inter;
  float2 uv(0,0);

  // sample from the list of sensors
  const SurfacePrimitive *sensor = 0;
  float temp;
  mScene->getSensors()->sampleSurfaceArea(0.0f, &sensor, temp);

  progress.restart(film->getWidth() * film->getHeight());
  for(size_t y = 0;
      y < film->getHeight();
      ++y, uv[1] += step[1])
  {
    uv[0] = 0;
    for(size_t x = 0;
        x < film->getWidth();
        ++x, uv[0] += step[0])
    {
      // sample a point on the sensor
      DifferentialGeometry dgSensor;
      sensor->sampleSurfaceArea(0,0,0,dgSensor,pdf);

      // generate a Ray
      ScatteringDistributionFunction &s = *sensor->getMaterial()->evaluateSensor(dgSensor);

      // sample a sensing direction
      s.sample(dgSensor, uv[0], uv[1], 0.5f, d, pdf, delta);
      r = Ray(dgSensor.getPoint(), d);

      Spectrum L(0.0f,0.0f,0.0f);

      // intersect the Scene
      if(mScene->intersect(r, inter))
      {
        const Primitive *prim = inter.getPrimitive();
        ScatteringDistributionFunction *f = static_cast<const SurfacePrimitive*>(prim)->getMaterial()->evaluateScattering(inter.getDifferentialGeometry());
        L = f->evaluate(-d,inter.getDifferentialGeometry(),-d);
      } // end if

      film->deposit(x,y,L);

      // purge all malloc'd memory for this sample
      ScatteringDistributionFunction::mPool.freeAll();

      ++progress;
    } // end for x
  } // end for y
} // end DebugRenderer::kernel()

<|endoftext|>


<commit_before>/*****************************************************************************************[Aiger.C]
Copyright (c) 2007, Niklas Sorensson

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

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

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

#include "ParseUtils.h"
#include "Aiger.h"

static unsigned int readPacked(StreamBuffer& in){
    unsigned int x = 0, i = 0;
    int ch;

    while ((ch = *in) & 0x80){
        if (ch == EOF) fprintf(stderr, "ERROR! Unexpected end of file!\n"), exit(1);
        x |= (ch & 0x7f) << (7 * i++);
        ++in;
    }
    if (ch == EOF) fprintf(stderr, "ERROR! Unexpected end of file!\n"), exit(1);
    ++in;

    return x | (ch << (7 * i));
}

static Sig mapSig(vec<Gate>& id2gate, int aiger_lit) {
    if (aiger_lit == 0)      return sig_False;
    else if (aiger_lit == 1) return sig_True;
    else return mkSig(id2gate[aiger_lit >> 1], bool(aiger_lit & 1));
}

void readAiger (const char* filename, Circ& c, vec<Sig>& inputs, vec<Def>& latch_defs, vec<Sig>& outputs)
{
    gzFile f = gzopen(filename, "rb");

    if (f == NULL)
        fprintf(stderr, "ERROR! Could not open file: %s\n", filename), exit(1);

    StreamBuffer in(f);

    if (!match(in, "aig "))
        fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(1);

    int max_var   = parseInt(in);
    int n_inputs  = parseInt(in);
    int n_latches = parseInt(in);
    int n_outputs = parseInt(in);
    int n_gates   = parseInt(in);

    // fprintf(stderr, "max_var   = %d\n", max_var);
    // fprintf(stderr, "n_inputs  = %d\n", n_inputs);
    // fprintf(stderr, "n_outputs = %d\n", n_outputs);
    // fprintf(stderr, "n_latches = %d\n", n_latches);
    // fprintf(stderr, "n_gates   = %d\n", n_gates);
    // fprintf(stderr, "sum       = %d\n", n_gates + n_latches + n_inputs);

    if (max_var != n_inputs + n_latches + n_gates)
        fprintf(stderr, "ERROR! Header mismatching sizes (M != I + L + A)\n"), exit(1);

    vec<Gate> id2gate(max_var, gate_Undef);

    // Create input gates:
    for (int i = 0; i < n_inputs; i++){
        Sig x = c.mkInp();
        inputs.push(x);
        id2gate[i+1] = gate(x);
    }

    // Create latch gates:
    for (int i = 0; i < n_latches; i++){
        Def d = { c.mkInp(), sig_Undef };
        latch_defs.push(d);
        id2gate[i+n_inputs+1] = gate(d.var);
    }

    vec<unsigned int> aiger_outputs;
    vec<unsigned int> aiger_latch_defs;

    // Read latch definitions:
    for (int i = 0; i < n_latches; i++){
        aiger_latch_defs.push(parseInt(in));
        skipLine(in); }

    // Read outputs:
    for (int i = 0; i < n_outputs; i++){
        aiger_outputs.push(parseInt(in));
        skipLine(in); }

    // Read gates:
    for (int i = n_inputs + n_latches + 1; i < max_var + 1; i++){
        unsigned delta0 = readPacked(in);
        unsigned delta1 = readPacked(in);
        unsigned x      = 2*i - delta0;
        unsigned y      = x   - delta1;
        id2gate[i]      = gate(c.mkAnd(mapSig(id2gate, x), mapSig(id2gate, y)));

        assert   ((int)delta0 < 2*i);
        assert   (delta1 <= 2*i - delta0);
    }
    // printf("Read %d number of gates\n", c.nGates());

    // Map outputs:
    for (int i = 0; i < aiger_outputs.size(); i++)
        outputs.push(mapSig(id2gate, aiger_outputs[i]));

    // Map latches:
    for (int i = 0; i < aiger_latch_defs.size(); i++)
        latch_defs[i].def = mapSig(id2gate, aiger_latch_defs[i]);
}

void writeAiger(const char* filename, Circ& c, const vec<Sig>& inputs, const vec<Def>& latch_defs, const vec<Sig>& outputs)
{
}
<commit_msg>Bugfix to readAiger, first version of writeAiger<commit_after>/*****************************************************************************************[Aiger.C]
Copyright (c) 2007, Niklas Sorensson

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

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

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

#include "ParseUtils.h"
#include "Aiger.h"

static unsigned int readPacked(StreamBuffer& in){
    unsigned int x = 0, i = 0;
    int ch;

    while ((ch = *in) & 0x80){
        if (ch == EOF) fprintf(stderr, "ERROR! Unexpected end of file!\n"), exit(1);
        x |= (ch & 0x7f) << (7 * i++);
        ++in;
    }
    if (ch == EOF) fprintf(stderr, "ERROR! Unexpected end of file!\n"), exit(1);
    ++in;

    return x | (ch << (7 * i));
}

static Sig aigToSig(vec<Sig>& id2sig, int aiger_lit) {
    if (aiger_lit == 0)      return sig_False;
    else if (aiger_lit == 1) return sig_True;
    else return id2sig[aiger_lit >> 1] ^ bool(aiger_lit & 1);
}

void readAiger (const char* filename, Circ& c, vec<Sig>& inputs, vec<Def>& latch_defs, vec<Sig>& outputs)
{
    gzFile f = gzopen(filename, "rb");

    if (f == NULL)
        fprintf(stderr, "ERROR! Could not open file <%s> for reading\n", filename), exit(1);

    StreamBuffer in(f);

    if (!match(in, "aig "))
        fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(1);

    int max_var   = parseInt(in);
    int n_inputs  = parseInt(in);
    int n_latches = parseInt(in);
    int n_outputs = parseInt(in);
    int n_gates   = parseInt(in);

    // fprintf(stderr, "max_var   = %d\n", max_var);
    // fprintf(stderr, "n_inputs  = %d\n", n_inputs);
    // fprintf(stderr, "n_outputs = %d\n", n_outputs);
    // fprintf(stderr, "n_latches = %d\n", n_latches);
    // fprintf(stderr, "n_gates   = %d\n", n_gates);
    // fprintf(stderr, "sum       = %d\n", n_gates + n_latches + n_inputs);

    if (max_var != n_inputs + n_latches + n_gates)
        fprintf(stderr, "ERROR! Header mismatching sizes (M != I + L + A)\n"), exit(1);

    vec<Sig> id2sig(max_var, sig_Undef);

    // Create input gates:
    for (int i = 0; i < n_inputs; i++){
        Sig x = c.mkInp();
        inputs.push(x);
        id2sig[i+1] = x;
    }

    // Create latch gates:
    for (int i = 0; i < n_latches; i++){
        Def d = { c.mkInp(), sig_Undef };
        latch_defs.push(d);
        id2sig[i+n_inputs+1] = d.var;
    }

    vec<unsigned int> aiger_outputs;
    vec<unsigned int> aiger_latch_defs;

    // Read latch definitions:
    for (int i = 0; i < n_latches; i++){
        aiger_latch_defs.push(parseInt(in));
        skipLine(in); }

    // Read outputs:
    for (int i = 0; i < n_outputs; i++){
        aiger_outputs.push(parseInt(in));
        skipLine(in); }

    // Read gates:
    for (int i = n_inputs + n_latches + 1; i < max_var + 1; i++){
        unsigned delta0 = readPacked(in);
        unsigned delta1 = readPacked(in);
        unsigned x      = 2*i - delta0;
        unsigned y      = x   - delta1;

        // fprintf(stderr, "read gate %d = %d & %d\n", 2*i, x, y);

        id2sig[i]       = c.mkAnd(aigToSig(id2sig, x), aigToSig(id2sig, y));

        assert   ((int)delta0 < 2*i);
        assert   (delta1 <= 2*i - delta0);
    }
    // printf("Read %d number of gates\n", c.nGates());

    // Map outputs:
    for (int i = 0; i < aiger_outputs.size(); i++)
        outputs.push(aigToSig(id2sig, aiger_outputs[i]));

    // Map latches:
    for (int i = 0; i < aiger_latch_defs.size(); i++)
        latch_defs[i].def = aigToSig(id2sig, aiger_latch_defs[i]);
}

void writePacked(FILE* file, unsigned int x)
{
    unsigned char ch;

    while (x & ~0x7f){
        ch = (x & 0x7f) | 0x80;
        putc(ch, file);
        x >>= 7;
    }

    ch = x;
    putc(ch, file);
}

static unsigned int sigToAig(GMap<unsigned int>& gate2id, Sig x) {
    if (x == sig_False)      return 0;
    else if (x == sig_True)  return 1;
    else return (gate2id[gate(x)]<<1) + (unsigned int)sign(x);
}

void writeAiger(const char* filename, Circ& c, const vec<Sig>& inputs, const vec<Def>& latch_defs, const vec<Sig>& outputs)
{
    // fprintf(stderr, "aig %u %u %u %d %d\n", c.size(), inputs.size(), latch_defs.size(), outputs.size(), c.nGates());

    // Generate the set of reachable gates:
    GSet reachable; bottomUpOrder(c, outputs, reachable); bottomUpOrder(c, latch_defs, reachable);

    unsigned int n_inputs = 0, n_latches = 0;

    // Generate the same set, but in an order compatible with the AIGER format:
    GSet uporder;
    for (int i = 0; i < inputs.size(); i++)
        if (reachable.has(gate(inputs[i])))
            n_inputs++, uporder.insert(gate(inputs[i]));

    vec<Def> ls;
    for (int i = 0; i < latch_defs.size(); i++)
        if (reachable.has(gate(latch_defs[i].var))){
            n_latches++;
            ls.push(latch_defs[i]);
            uporder.insert(gate(latch_defs[i].var));
        }

    bottomUpOrder(c, outputs, uporder);
    bottomUpOrder(c, latch_defs, uporder);

    unsigned int n_gates = uporder.size() - n_inputs - n_latches;

    GMap<unsigned int> gate2id; gate2id.growTo(c.maxGate());
    for (int i = 0; i < uporder.size(); i++)
        gate2id[uporder[i]] = i + 1;

    FILE* f = fopen(filename, "wb");

    if (f == NULL)
        fprintf(stderr, "ERROR! Could not open file <%s> for writing\n", filename), exit(1);

    // fprintf(stderr, "aig %u %u %u %d %d\n", uporder.size(), n_inputs, n_latches, outputs.size(), n_gates);
    fprintf(f, "aig %u %u %u %d %d\n", uporder.size(), n_inputs, n_latches, outputs.size(), n_gates);

    // Write latch-defs:
    for (int i = 0; i < ls.size(); i++)
        fprintf(f, "%u\n", sigToAig(gate2id, ls[i].def));

    // Write outputs:
    for (int i = 0; i < outputs.size(); i++)
        fprintf(f, "%u\n", sigToAig(gate2id, outputs[i]));

    // Write gates:
    for (int i = 0; i < (int)n_gates; i++){
        Gate         g    = uporder[n_inputs + n_latches + i];     assert(type(g) == gtype_And);
        unsigned int glit = (n_inputs + n_latches + i + 1) << 1;
        unsigned int llit = sigToAig(gate2id, c.lchild(g));
        unsigned int rlit = sigToAig(gate2id, c.rchild(g));

        if (llit < rlit){
            unsigned int tmp = llit; llit = rlit; rlit = tmp; }

        assert(glit > llit);
        assert(llit >= rlit);

        // fprintf(stderr, "%d = %d & %d\n", glit, llit, rlit);
        writePacked(f, glit - llit);
        writePacked(f, llit - rlit);
    }
    fclose(f);
}
<|endoftext|>