<commit_before>#include "model.hpp"

/**
 * namespace model
 * defined several Elements
 */
namespace model {
	//////////////////////////
	// Integer

	/**
	 * Convert Integer to String
	 *
	 * @return std::string
	 */
	std::string Integer::to_string() const {
		std::stringstream ss;
		ss << this->data;

		return ss.str();
	}

	/**
	 * Add this data and other data
	 *
	 * @return std::string
	 */
	Element* Integer::add(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data + other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float(static_cast<Float::TYPE>(data) + other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * Sub this data and other data
	 *
	 * @return std::string
	 */
	Element* Integer::sub(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data - other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float(static_cast<Float::TYPE>(data) - other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>) {
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate mutliplication
	 */
	Element* Integer::mul(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data * other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float( data * other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate division
	 */
	Element* Integer::div(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data / other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float( data / other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	//////////////////////////
	// Float

	/**
	 * Convert Float to String
	 */
	std::string Float::to_string() const {
		std::stringstream ss;
		ss << this->data;

		return ss.str();
	}
	/**
	 * applicate addtion
	 */
	Element* Float::add(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data + other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data + other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate subtruction
	 */
	Element* Float::sub(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data - other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data - other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate mutliplication
	 */
	Element* Float::mul(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data * other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data * other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate division
	 */
	Element* Float::div(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data / other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data / other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	//////////////////////////
	// String
	std::string String::to_string() const {
		return "\"" + this->data + "\"";
	}

	/**
	 * Add this data and other data
	 */
	Element* String::add(Element *other) {
		Element* rtn;

		if (other->instance_of<String>()) {
			rtn = new String( data + other->cast<String>()->get_data() );
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	//////////////////////////
	// Nil
	std::string Nil::to_string() const {
		return "nil";
	}

	//////////////////////////
	// Instruction

	/**
	 * applicate instruction
	 */
	Stack& Instruction::applicate(Stack& stack) {
		switch (data) {
			case INST_PLUS:
				add(stack);
				break;
			case INST_MINUS:
				sub(stack);
				break;
			case INST_MULTIPLICATION:
				mul(stack);
				break;
			case INST_DIVISION:
				div(stack);
				break;
			case INST_DROP:
				drop(stack);
				break;
			default:
				throw "No such a instruction";
		}
		return stack;
	}

	/**
	 * applicate addition
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::add(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->add(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->add(arg2);
		} else if (arg1->instance_of<String>()) {
			result = arg1->cast<String>()->add(arg2);
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * applicate substruction
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::sub(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->sub(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->sub(arg2);
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * applicate mutliplication
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::mul(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->mul(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->mul(arg2);
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * applicate divison
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::div(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->div(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->div(arg2);
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * drop element
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::drop(Stack& stack) {
		delete stack.pop();
		return stack;
	}

	//////////////////////////
	// Stack Class

	/**
	 * convert Stack to String
	 *
	 * @return std::string
	 */
	std::string Stack::to_string() const
	{
		std::string str("[ ");

		for (auto iterator : *this) {
			str += iterator->to_string() + " ";
		}
		str += "]";

		return str;
	}

	/**
	 * Push Element
	 *
	 * @param Element* Address of Element which is pushed
	 */
	void Stack::push(Element* data)
	{
		this->push_back(data);
		return;
	}

	/**
	 * Drop Element
	 * Pop and delete Element
	 */
	void Stack::drop()
	{
		Element *data;

		data = this->back();
		delete data;
		this->pop_back();
		return;
	}

	/**
	 * Pop and get Element
	 * Does not delete
	 *
	 * @return Element* Popped Element
	 */
	Element* Stack::pop()
	{
		Element* rtn;

		rtn = this->back();
		this->pop_back();

		return rtn;
	}

	/**
	 * Free Unused Memory
	 */
	void Stack::free_memory()
	{
		Stack swp = *this;
		this->swap(swp);

		return;
	}

	/**
	 * Appends the other Stack to self
	 *
	 * @param Stack& other
	 * @return Stack&
	 */
	Stack& Stack::operator+=(Stack& other)
	{
		this->insert(this->end(), other.begin(), other.end());

		return *this;
	}
} // namespace model
<commit_msg>add instruction: addition of Stack<commit_after>#include "model.hpp"

/**
 * namespace model
 * defined several Elements
 */
namespace model {
	//////////////////////////
	// Integer

	/**
	 * Convert Integer to String
	 *
	 * @return std::string
	 */
	std::string Integer::to_string() const {
		std::stringstream ss;
		ss << this->data;

		return ss.str();
	}

	/**
	 * Add this data and other data
	 *
	 * @return std::string
	 */
	Element* Integer::add(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data + other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float(static_cast<Float::TYPE>(data) + other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * Sub this data and other data
	 *
	 * @return std::string
	 */
	Element* Integer::sub(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data - other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float(static_cast<Float::TYPE>(data) - other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>) {
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate mutliplication
	 */
	Element* Integer::mul(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data * other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float( data * other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate division
	 */
	Element* Integer::div(Element *other) {
		Element* rtn;

		if (other->instance_of<Integer>()) {
			rtn = new Integer( data / other->cast<Integer>()->get_data() );
		} else if (other->instance_of<Float>()) {
			rtn = new Float( data / other->cast<Float>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	//////////////////////////
	// Float

	/**
	 * Convert Float to String
	 */
	std::string Float::to_string() const {
		std::stringstream ss;
		ss << this->data;

		return ss.str();
	}
	/**
	 * applicate addtion
	 */
	Element* Float::add(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data + other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data + other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate subtruction
	 */
	Element* Float::sub(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data - other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data - other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate mutliplication
	 */
	Element* Float::mul(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data * other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data * other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	/**
	 * applicate division
	 */
	Element* Float::div(Element *other) {
		Element* rtn;

		if (other->instance_of<Float>()) {
			rtn = new Float( data / other->cast<Float>()->get_data() );
		} else if (other->instance_of<Integer>()) {
			rtn = new Float( data / other->cast<Integer>()->get_data() );
		// } else if (other.instance_of<>)
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	//////////////////////////
	// String
	std::string String::to_string() const {
		return "\"" + this->data + "\"";
	}

	/**
	 * Add this data and other data
	 */
	Element* String::add(Element *other) {
		Element* rtn;

		if (other->instance_of<String>()) {
			rtn = new String( data + other->cast<String>()->get_data() );
		} else {
			throw "UnexpectedTypeError";
		}

		return rtn;
	}

	//////////////////////////
	// Nil
	std::string Nil::to_string() const {
		return "nil";
	}

	//////////////////////////
	// Instruction

	/**
	 * applicate instruction
	 */
	Stack& Instruction::applicate(Stack& stack) {
		switch (data) {
			case INST_PLUS:
				add(stack);
				break;
			case INST_MINUS:
				sub(stack);
				break;
			case INST_MULTIPLICATION:
				mul(stack);
				break;
			case INST_DIVISION:
				div(stack);
				break;
			case INST_DROP:
				drop(stack);
				break;
			default:
				throw "No such a instruction";
		}
		return stack;
	}

	/**
	 * applicate addition
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::add(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->add(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->add(arg2);
		} else if (arg1->instance_of<String>()) {
			result = arg1->cast<String>()->add(arg2);
		} else if (arg1->instance_of<Stack>()) {
			*arg1->cast<Stack>() += *arg2->cast<Stack>();
			stack.push(arg1);
			delete arg2;
			return stack;
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * applicate substruction
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::sub(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->sub(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->sub(arg2);
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * applicate mutliplication
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::mul(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->mul(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->mul(arg2);
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * applicate divison
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::div(Stack& stack) {
		Element *arg1, *arg2, *result;

		arg2 = stack.pop();
		arg1 = stack.pop();
		result = NULL;

		if (arg1->instance_of<Integer>()) {
			result = arg1->cast<Integer>()->div(arg2);
		} else if (arg1->instance_of<Float>()) {
			result = arg1->cast<Float>()->div(arg2);
		}

		stack.push(result);

		delete arg1;
		delete arg2;

		return stack;
	}

	/**
	 * drop element
	 *
	 * @param  Stack& stack which will be applicated
	 * @return Stack&
	 */
	Stack& Instruction::drop(Stack& stack) {
		delete stack.pop();
		return stack;
	}

	//////////////////////////
	// Stack Class

	/**
	 * convert Stack to String
	 *
	 * @return std::string
	 */
	std::string Stack::to_string() const
	{
		std::string str("[ ");

		for (auto iterator : *this) {
			str += iterator->to_string() + " ";
		}
		str += "]";

		return str;
	}

	/**
	 * Push Element
	 *
	 * @param Element* Address of Element which is pushed
	 */
	void Stack::push(Element* data)
	{
		this->push_back(data);
		return;
	}

	/**
	 * Drop Element
	 * Pop and delete Element
	 */
	void Stack::drop()
	{
		Element *data;

		data = this->back();
		delete data;
		this->pop_back();
		return;
	}

	/**
	 * Pop and get Element
	 * Does not delete
	 *
	 * @return Element* Popped Element
	 */
	Element* Stack::pop()
	{
		Element* rtn;

		rtn = this->back();
		this->pop_back();

		return rtn;
	}

	/**
	 * Free Unused Memory
	 */
	void Stack::free_memory()
	{
		Stack swp = *this;
		this->swap(swp);

		return;
	}

	/**
	 * Appends the other Stack to self
	 *
	 * @param Stack& other
	 * @return Stack&
	 */
	Stack& Stack::operator+=(Stack& other)
	{
		this->insert(this->end(), other.begin(), other.end());

		return *this;
	}
} // namespace model
<|endoftext|>


<commit_before>#include <iostream>
#include "logger.hpp"
#include "config.hpp"
#include "mysql.hpp"
#include "user.hpp"
#include "torrent.hpp"
#include "utility.hpp"

void MySQL::connect() {
	mysql = mysql_init(nullptr);
	if (mysql_real_connect(mysql, Config::get("DB_Host").c_str(), Config::get("DB_User").c_str(), Config::get("DB_Password").c_str(), Config::get("DB_DBName").c_str(), Config::getInt("DB_Port"), nullptr, 0) == nullptr) {
		LOG_ERROR("Couldn't connect to database");
	} else {
		LOG_INFO("Succesfully connected to database");
		std::string query = "TRUNCATE xbt_files_users;";
		if (mysql_real_query(mysql, query.c_str(), query.size()))
			return;
	}
}

void MySQL::disconnect() {
	LOG_WARNING("Disconnecting from database");
	mysql_free_result(result);
	mysql_close(mysql);
}

void MySQL::loadUsers(UserMap& usrMap) {
	std::string query = "SELECT ID, torrent_pass, can_leech, visible FROM users_main";
	if (mysql_real_query(mysql, query.c_str(), query.size()))
		return;
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result)))
		usrMap.emplace(row[1], new User(std::stoul(row[0]), row[2] == std::string("1"), row[3] == std::string("1")));
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " users");

	// load tokens
	query = "SELECT passkey, info_hash FROM users_freeleeches AS uf LEFT JOIN users AS u ON uf.UserID = u.ID JOIN torrents AS t ON uf.TorrentID = t.ID WHERE uf.Expired = '0'";
	if (mysql_real_query(mysql, query.c_str(), query.size()))
		return;
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result))) {
		try {
			usrMap.at(row[0])->addToken(row[1]);
		} catch (const std::exception& e) {}
	}
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " user tokens");
}

void MySQL::loadTorrents(TorrentMap& torMap) {
	std::string query = "SELECT ID, info_hash, freetorrent, Snatched FROM torrents";
	if (mysql_real_query(mysql, query.c_str(), query.size()))
		return;
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result))) {
		// TEMP FIX
		unsigned char free = 0;
		if (row[2] == std::string("1"))
			free = 100;
		else if (row[2] == std::string("2"))
			free = 50;
		//
		torMap.emplace(row[1], Torrent(std::stoul(row[0]), free, std::stoul(row[3])));
	}
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " torrents");
}

void MySQL::loadBannedIps(std::forward_list<std::string> &banned_ips) {
	std::string query = "SELECT FromIP, ToIP FROM ip_bans";
	if (mysql_real_query(mysql, query.c_str(), query.size()))
		return;
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result))) {
		unsigned int from = std::stoul(row[0]);
		unsigned int to = std::stoul(row[1]);

		while (from != to)
			banned_ips.push_front(Utility::long2ip(from++));
		banned_ips.push_front(Utility::long2ip(from));
	}
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " banned ips");
}

void MySQL::record (std::string request) {
	requests.push_front(request);
	if (requests.size() > 10) {
		flush();
		requests.clear();
	}
}

void MySQL::flush() {
	LOG_INFO("flushing sql records");
	for(const auto &it : requests) {
		if (mysql_real_query(mysql, it.c_str(), it.size()))
			return;
	}
}
<commit_msg>sql logging<commit_after>#include <iostream>
#include "logger.hpp"
#include "config.hpp"
#include "mysql.hpp"
#include "user.hpp"
#include "torrent.hpp"
#include "utility.hpp"

void MySQL::connect() {
	mysql = mysql_init(nullptr);
	if (mysql_real_connect(mysql, Config::get("DB_Host").c_str(), Config::get("DB_User").c_str(), Config::get("DB_Password").c_str(), Config::get("DB_DBName").c_str(), Config::getInt("DB_Port"), nullptr, 0) == nullptr) {
		LOG_ERROR("Couldn't connect to database");
	} else {
		LOG_INFO("Succesfully connected to database");
		std::string query = "TRUNCATE xbt_files_users;";
		if (mysql_real_query(mysql, query.c_str(), query.size()))
			return;
	}
}

void MySQL::disconnect() {
	LOG_WARNING("Disconnecting from database");
	mysql_free_result(result);
	mysql_close(mysql);
}

void MySQL::loadUsers(UserMap& usrMap) {
	std::string query = "SELECT ID, torrent_pass, can_leech, visible FROM users_main";
	if (mysql_real_query(mysql, query.c_str(), query.size())) {
		LOG_ERROR("Couldn't load users database");
		return;
	}
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result)))
		usrMap.emplace(row[1], new User(std::stoul(row[0]), row[2] == std::string("1"), row[3] == std::string("1")));
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " users");

	// load tokens
	query = "SELECT passkey, info_hash FROM users_freeleeches AS uf LEFT JOIN users AS u ON uf.UserID = u.ID JOIN torrents AS t ON uf.TorrentID = t.ID WHERE uf.Expired = '0'";
	if (mysql_real_query(mysql, query.c_str(), query.size())) {
		LOG_ERROR("Couldn't load user freeleeches");
		return;
	}
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result))) {
		try {
			usrMap.at(row[0])->addToken(row[1]);
		} catch (const std::exception& e) {
			LOG_WARNING("Couldn't add freeleech token to user " + std::string(row[0]) + " (" + e.what() + ")");
		}
	}
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " user tokens");
}

void MySQL::loadTorrents(TorrentMap& torMap) {
	std::string query = "SELECT ID, info_hash, freetorrent, Snatched FROM torrents";
	if (mysql_real_query(mysql, query.c_str(), query.size())) {
		LOG_ERROR("Couldn't load torrents database");
		return;
	}
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result))) {
		// TEMP FIX
		unsigned char free = 0;
		if (row[2] == std::string("1"))
			free = 100;
		else if (row[2] == std::string("2"))
			free = 50;
		//
		torMap.emplace(row[1], Torrent(std::stoul(row[0]), free, std::stoul(row[3])));
	}
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " torrents");
}

void MySQL::loadBannedIps(std::forward_list<std::string> &banned_ips) {
	std::string query = "SELECT FromIP, ToIP FROM ip_bans";
	if (mysql_real_query(mysql, query.c_str(), query.size())) {
		LOG_ERROR("Couldn't load banned IP addresses database");
		return;
	}
	result = mysql_use_result(mysql);
	while((row = mysql_fetch_row(result))) {
		unsigned int from = std::stoul(row[0]);
		unsigned int to = std::stoul(row[1]);

		while (from != to)
			banned_ips.push_front(Utility::long2ip(from++));
		banned_ips.push_front(Utility::long2ip(from));
	}
	LOG_INFO("Loaded " + std::to_string(mysql_num_rows(result)) + " banned IP addresses");
}

void MySQL::record (std::string request) {
	requests.push_front(request);
	if (requests.size() > 10) {
		flush();
		requests.clear();
	}
}

void MySQL::flush() {
	for(const auto &it : requests) {
		if (mysql_real_query(mysql, it.c_str(), it.size())) {
			LOG_ERROR("Couldn't flush record (" + it + ")");
			return;
		}
	}
	LOG_INFO("Flush sql records");
}
<|endoftext|>


<commit_before>#include "ofApp.h"

void nebulaEye::setup()
{
  roiGuiGrp.setName("ROI");
  roiGuiGrp.add(radius.set("rayon", 250, 1 , ofGetWidth()/2));
  roiGuiGrp.add(center.set("centre", ofPoint(ofGetWidth()/2, ofGetHeight()/2), ofPoint(0,0), ofPoint(ofGetWidth(), ofGetHeight())));

  video.setup();
  flow.setup();
  bgSub.setup();
  contour.setup();

  gui.setup("","settings.xml",660,10);
  gui.add(video.guiGrp);
  gui.add(roiGuiGrp);
  gui.add(bgSub.guiGrp);
  gui.add(flow.guiGrp);
  gui.add(contour.guiGrp);

  ofSetCircleResolution(100);

  ofSetBackgroundColor(0);
}

void nebulaEye::update()
{
  video.update();
  if(video.isFrameNew()){
    auto img = video.getPixels();
    bgSub.update(img);
    flow.update(img);
    contour.update(img);
  }
}

void nebulaEye::draw()
{
  video.draw(0,0,640,480);
  bgSub.draw(640,0,640,480);
  flow.draw(0,480, 640, 480);
  contour.draw(0,0,640,480);

  //ofSetColor(255,255,255,128);
  //ofDrawCircle(center->x, center->y, radius);
  gui.draw();
}

void nebulaEye::exit()
{
}

void nebulaEye::mouseMoved(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseDragged(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mousePressed(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseReleased(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseScrolled(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseEntered(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseExited(ofMouseEventArgs& mouse)
{
}
<commit_msg>reload settings on start<commit_after>#include "ofApp.h"

void nebulaEye::setup()
{
  roiGuiGrp.setName("ROI");
  roiGuiGrp.add(radius.set("rayon", 250, 1 , ofGetWidth()/2));
  roiGuiGrp.add(center.set("centre", ofPoint(ofGetWidth()/2, ofGetHeight()/2), ofPoint(0,0), ofPoint(ofGetWidth(), ofGetHeight())));

  video.setup();
  flow.setup();
  bgSub.setup();
  contour.setup();

  gui.setup("nebula-eye","settings.xml",660,10);
  gui.add(video.guiGrp);
  gui.add(roiGuiGrp);
  gui.add(bgSub.guiGrp);
  gui.add(flow.guiGrp);
  gui.add(contour.guiGrp);

  gui.loadFromFile("settings.xml");

  ofSetCircleResolution(100);

  ofSetBackgroundColor(0);
}

void nebulaEye::update()
{
  video.update();
  if(video.isFrameNew()){
    auto img = video.getPixels();
    bgSub.update(img);
    flow.update(img);
    contour.update(img);
  }
}

void nebulaEye::draw()
{
  video.draw(0,0,640,480);
  bgSub.draw(640,0,640,480);
  flow.draw(0,480, 640, 480);
  contour.draw(0,0,640,480);

  //ofSetColor(255,255,255,128);
  //ofDrawCircle(center->x, center->y, radius);
  gui.draw();
}

void nebulaEye::exit()
{
}

void nebulaEye::mouseMoved(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseDragged(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mousePressed(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseReleased(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseScrolled(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseEntered(ofMouseEventArgs& mouse)
{
}

void nebulaEye::mouseExited(ofMouseEventArgs& mouse)
{
}
<|endoftext|>


<commit_before>#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0, 0, 0);

    sample_rate_ = 44100;

    // 0 output channels,
    // 2 input channels
    // 44100 samples per second
    // N samples per buffer
    // 4 num buffers (latency)
    ofSoundStreamSetup(0, 2, this, sample_rate_, beat_.getBufferSize(), 4);

    font_.loadFont("Batang.ttf", 160, true, true, true);

    gist_.setUseForOnsetDetection(GIST_PEAK_ENERGY);
    gist_.setThreshold(GIST_PEAK_ENERGY, .05);

    // Volume
    left.assign(beat_.getBufferSize(), 0.0);
    right.assign(beat_.getBufferSize(), 0.0);
    vol_history_.assign(400, 0.0);
    current_vol_ = 0;
    smoothed_vol_     = 0.0;
    scaled_vol_		= 0.0;

    ofAddListener(GistEvent::ON,this,&ofApp::onNoteOn);
    ofAddListener(GistEvent::OFF,this,&ofApp::onNoteOff);

    // onset detection
    onset_decay_rate_ = 0.05;
    onset_minimum_threshold_ = 0.1;
    onset_threshold_ = onset_minimum_threshold_;

    setup_done_ = true;
}

//--------------------------------------------------------------
void ofApp::update(){
    beat_.update(ofGetElapsedTimeMillis());
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(255, 255, 255);
    ofFill();

    ofDrawBitmapString("onset threshold: "+ofToString(onset_threshold_), 10, 20);
    ofDrawBitmapString("kick: "+ofToString(beat_.kick()), 10, 40);
    ofDrawBitmapString("snare: "+ofToString(beat_.snare()), 10, 60);
    ofDrawBitmapString("hihat: "+ofToString(beat_.hihat()), 10, 80);
    ofDrawBitmapString("current vol: "+ofToString(current_vol_), 10, 100);
    ofDrawBitmapString("smoothed vol: "+ofToString(smoothed_vol_), 10, 120);

    const int kNumberOfBands = 32;

    for (int i = 0; i < kNumberOfBands; i++) {
        float selectedBand = beat_.getBand(i);
        float hz = ((i+1) * sample_rate_) / beat_.getBufferSize();
        std::string text = ofToString(i) + ") " + ofToString(hz) + " hz " + ofToString(selectedBand);
        ofDrawBitmapString(text, 10, 140 + (20*i));
    }
}

void ofApp::audioReceived(float* input, int bufferSize, int nChannels) {
    if (!setup_done_) {
        return;
    }

    beat_.audioReceived(input, bufferSize, channel_count_);

    channel_count_ = nChannels;

    //convert float array to vector
    vector<float>buffer;
    buffer.assign(&input[0],&input[bufferSize]);
    gist_.processAudio(buffer, bufferSize, nChannels, sample_rate_);

    calculateVolume(input, bufferSize);

    // detect onset
    onset_threshold_ = ofLerp(onset_threshold_, onset_minimum_threshold_, onset_decay_rate_);
    if (current_vol_ > onset_threshold_) {
        // onset detected!
        onset_threshold_ = current_vol_;
    }
}

void ofApp::calculateVolume(float *input, int bufferSize) {
    // samples are "interleaved"
    int numCounted = 0;

    //lets go through each sample and calculate the root mean square which is a rough way to calculate volume
    for (int i = 0; i < bufferSize; i++){
        left[i]		= input[i*2]*0.5;
        right[i]	= input[i*2+1]*0.5;

        current_vol_ += left[i] * left[i];
        current_vol_ += right[i] * right[i];
        numCounted+=2;
    }

    //this is how we get the mean of rms :)
    current_vol_ /= (float)numCounted;

    // this is how we get the root of rms :)
    current_vol_ = sqrt( current_vol_ );

    smoothed_vol_ *= 0.93;
    smoothed_vol_ += 0.07 * current_vol_;
}

void ofApp::onNoteOn(GistEvent &e){
    //noteOnRadius = 100;
};

void ofApp::onNoteOff(GistEvent &e){
    //noteOnRadius = 0;
};

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}<commit_msg>display volume history and current scaled volume<commit_after>#include "ofApp.h"

#define kVolHistorySize (400)

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0, 0, 0);

    sample_rate_ = 44100;

    // 0 output channels,
    // 2 input channels
    // 44100 samples per second
    // N samples per buffer
    // 4 num buffers (latency)
    ofSoundStreamSetup(0, 2, this, sample_rate_, beat_.getBufferSize(), 4);

    font_.loadFont("Batang.ttf", 160, true, true, true);

    gist_.setUseForOnsetDetection(GIST_PEAK_ENERGY);
    gist_.setThreshold(GIST_PEAK_ENERGY, .05);

    // Volume
    left.assign(beat_.getBufferSize(), 0.0);
    right.assign(beat_.getBufferSize(), 0.0);
    vol_history_.assign(kVolHistorySize, 0.0);
    current_vol_ = 0;
    smoothed_vol_     = 0.0;
    scaled_vol_		= 0.0;

    ofAddListener(GistEvent::ON,this,&ofApp::onNoteOn);
    ofAddListener(GistEvent::OFF,this,&ofApp::onNoteOff);

    // onset detection
    onset_decay_rate_ = 0.05;
    onset_minimum_threshold_ = 0.1;
    onset_threshold_ = onset_minimum_threshold_;

    setup_done_ = true;
}

//--------------------------------------------------------------
void ofApp::update(){
    beat_.update(ofGetElapsedTimeMillis());

    //lets scale the vol up to a 0-1 range
    scaled_vol_ = ofMap(smoothed_vol_, 0.0, 0.17, 0.0, 1.0, true);

    //lets record the volume into an array
    vol_history_.push_back(scaled_vol_);

    //if we are bigger the the size we want to record - lets drop the oldest value
    if( vol_history_.size() >= kVolHistorySize ){
        vol_history_.erase(vol_history_.begin(), vol_history_.begin()+1);
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(255, 255, 255);
    ofFill();

    ofDrawBitmapString("onset threshold: "+ofToString(onset_threshold_), 10, 20);
    ofDrawBitmapString("kick: "+ofToString(beat_.kick()), 10, 40);
    ofDrawBitmapString("snare: "+ofToString(beat_.snare()), 10, 60);
    ofDrawBitmapString("hihat: "+ofToString(beat_.hihat()), 10, 80);
    ofDrawBitmapString("current vol: "+ofToString(current_vol_), 10, 100);
    ofDrawBitmapString("smoothed vol: "+ofToString(smoothed_vol_), 10, 120);

    const int kNumberOfBands = 32;

    for (int i = 0; i < kNumberOfBands; i++) {
        float selectedBand = beat_.getBand(i);
        float hz = ((i+1) * sample_rate_) / beat_.getBufferSize();
        std::string text = ofToString(i) + ") " + ofToString(hz) + " hz " + ofToString(selectedBand);
        ofDrawBitmapString(text, 10, 140 + (20*i));
    }

    // draw the average volume:
    ofPushStyle();
    ofPushMatrix();
    ofTranslate(565, 170, 0);

    ofSetColor(225);
    ofDrawBitmapString("Scaled average vol (0-100): " + ofToString(scaled_vol_ * 100.0, 0), 4, 18);
    ofRect(0, 0, 400, 400);

    ofSetColor(245, 58, 135);
    ofFill();
    ofCircle(200, 200, scaled_vol_ * 190.0f);

    //lets draw the volume history as a graph
    ofBeginShape();
    for (unsigned int i = 0; i < vol_history_.size(); i++){
        if( i == 0 ) ofVertex(i, 400);

        ofVertex(i, 400 - vol_history_[i] * 70);

        if( i == vol_history_.size() -1 ) ofVertex(i, 400);
    }
    ofEndShape(false);

    ofPopMatrix();
    ofPopStyle();
}

void ofApp::audioReceived(float* input, int bufferSize, int nChannels) {
    if (!setup_done_) {
        return;
    }

    beat_.audioReceived(input, bufferSize, channel_count_);

    channel_count_ = nChannels;

    //convert float array to vector
    vector<float>buffer;
    buffer.assign(&input[0],&input[bufferSize]);
    gist_.processAudio(buffer, bufferSize, nChannels, sample_rate_);

    calculateVolume(input, bufferSize);

    // detect onset
    onset_threshold_ = ofLerp(onset_threshold_, onset_minimum_threshold_, onset_decay_rate_);
    if (current_vol_ > onset_threshold_) {
        // onset detected!
        onset_threshold_ = current_vol_;
    }
}

void ofApp::calculateVolume(float *input, int bufferSize) {
    // samples are "interleaved"
    int numCounted = 0;

    //lets go through each sample and calculate the root mean square which is a rough way to calculate volume
    for (int i = 0; i < bufferSize; i++){
        left[i]		= input[i*2]*0.5;
        right[i]	= input[i*2+1]*0.5;

        current_vol_ += left[i] * left[i];
        current_vol_ += right[i] * right[i];
        numCounted+=2;
    }

    //this is how we get the mean of rms :)
    current_vol_ /= (float)numCounted;

    // this is how we get the root of rms :)
    current_vol_ = sqrt( current_vol_ );

    smoothed_vol_ *= 0.93;
    smoothed_vol_ += 0.07 * current_vol_;
}

void ofApp::onNoteOn(GistEvent &e){
    //noteOnRadius = 100;
};

void ofApp::onNoteOff(GistEvent &e){
    //noteOnRadius = 0;
};

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}<|endoftext|>


<commit_before>#include "reader.h"

PNGImageReader::PNGImageReader(unsigned char* src, size_t len) :
        ImageReader(src, len), depth(0), color(-1) {
    // Decode PNG header.
    png = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)this, errorHandler, errorHandler);
    assert(png);
    info = png_create_info_struct(png);
    assert(info);

    if (setjmp(png_jmpbuf(png))) {
        width = 0;
        height = 0;
        return;
    }

    png_set_read_fn(png, this, readCallback);
    png_read_info(png, info);
    png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
    alpha = (color & PNG_COLOR_MASK_ALPHA) || png_get_valid(png, info, PNG_INFO_tRNS);
}

void PNGImageReader::readCallback(png_structp png, png_bytep data, png_size_t length) {
    PNGImageReader* reader = static_cast<PNGImageReader*>(png_get_error_ptr(png));

    // Read `length` bytes into `data`.
    if (reader->pos + length > reader->length) {
        png_error(png, "Read Error");
        return;
    }

    memcpy(data, reader->source + reader->pos, length);
    reader->pos += length;
}

void PNGImageReader::errorHandler(png_structp png, png_const_charp error_msg) {
    PNGImageReader* reader = static_cast<PNGImageReader*>(png_get_io_ptr(png));

    reader->message = error_msg;

    if (png) {
        longjmp(png->jmpbuf, 1);
    }
    exit(1);
}

unsigned char* PNGImageReader::decode() {
    if (setjmp(png_jmpbuf(png))) {
        png_destroy_read_struct(&png, &info, NULL);
        width = 0;
        height = 0;
        return NULL;
    }

    // From http://trac.mapnik.org/browser/trunk/src/png_reader.cpp
    if (color == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(png);
    if (color == PNG_COLOR_TYPE_GRAY)
        png_set_expand(png);
    if (png_get_valid(png, info, PNG_INFO_tRNS))
        png_set_expand(png);
    if (depth == 16)
        png_set_strip_16(png);
    if (depth < 8)
        png_set_packing(png);
    if (color == PNG_COLOR_TYPE_GRAY ||
        color == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png);

    // Always add an alpha channel.
    if (!this->alpha) {
        png_set_add_alpha(png, 0xFF, PNG_FILLER_AFTER);
    }

    double gamma;
    if (png_get_gAMA(png, info, &gamma))
        png_set_gamma(png, 2.2, gamma);

    png_read_update_info(png, info);

    unsigned int rowbytes = png_get_rowbytes(png, info);
    assert(width * 4 == rowbytes);

    unsigned char* surface = (unsigned char*)malloc(width * height * 4);
    assert(surface);

    png_bytep row_pointers[height];
    for (unsigned i = 0; i < height; i++) {
        row_pointers[i] = (unsigned char*)(surface + (i * rowbytes));
    }

    // Read image data
    png_read_image(png, row_pointers);

    png_read_end(png, NULL);

    return surface;
}

PNGImageReader::~PNGImageReader() {
    png_destroy_read_struct(&png, &info, NULL);
    png = NULL;
    info = NULL;
}

JPEGImageReader::JPEGImageReader(unsigned char* src, size_t len) :
        ImageReader(src, len) {
    err.reader = this;
    info.err = jpeg_std_error(&err.pub);
    err.pub.error_exit = errorHandler;
    err.pub.output_message = errorMessage;

    if (setjmp(err.jump)) {
        width = 0;
        height = 0;

        // Error message was set by JPEGImageReader::errorMessage.
        return;
    }
    jpeg_create_decompress(&info);
    jpeg_mem_src(&info, src, len);
    jpeg_read_header(&info, TRUE);
    width = info.image_width;
    height = info.image_height;
    alpha = false;
}

void JPEGImageReader::errorHandler(j_common_ptr cinfo) {
    // libjpeg recommends doing this memory alignment trickery.
    JPEGErrorManager* error = (JPEGErrorManager*)cinfo->err;

    /* Return control to the setjmp point */
    longjmp(error->jump, 1);
}

void JPEGImageReader::errorMessage(j_common_ptr cinfo) {
    // libjpeg recommends doing this memory alignment trickery.
    JPEGErrorManager* error = (JPEGErrorManager*)cinfo->err;

    char buffer[JMSG_LENGTH_MAX];
    (*cinfo->err->format_message) (cinfo, buffer);
    error->reader->message = buffer;
}

unsigned char* JPEGImageReader::decode() {
    if (info.data_precision != 8) return NULL;
    if (info.num_components != 3 && info.num_components != 1) return NULL;

    size_t length = width * height * 4;
    size_t offset = 0;
    unsigned char* surface = (unsigned char*)malloc(length);
    if (surface == NULL) {
        message = "Insufficient memory";
        jpeg_destroy_decompress(&info);
        return NULL;
    }

    if (setjmp(err.jump)) {
        free(surface);

        // Error message was set by JPEGImageReader::errorMessage.
        return NULL;
    }

    info.out_color_space = JCS_RGB;

    jpeg_start_decompress(&info);

    while (info.output_scanline < info.output_height) {
        assert(offset < length);
        unsigned char* destination = surface + offset;
        unsigned int* image = (unsigned int*)destination;
        jpeg_read_scanlines(&info, &destination, 1);

        for (int i = width - 1, j = i * 3; i >= 0; j = --i * 3) {
            image[i] = 0xFF << 24 | destination[j + 2] << 16 |
                destination[j + 1] << 8 | destination[j];
        }

        offset += width * 4;
    }

    jpeg_finish_decompress(&info);

    return surface;
}

JPEGImageReader::~JPEGImageReader() {
    jpeg_destroy_decompress(&info);
}

ImageReader* ImageReader::create(unsigned char* src, size_t len) {
    if (png_sig_cmp((png_bytep)src, 0, 8) == 0) {
        return new PNGImageReader(src, len);
    } else if (src[0] == 255 && src[1] == 216) {
        return new JPEGImageReader(src, len);
    } else {
        return new ImageReader("Unknown image format");
    }
}
<commit_msg>decompress multiple scanlines in one go<commit_after>#include "reader.h"

PNGImageReader::PNGImageReader(unsigned char* src, size_t len) :
        ImageReader(src, len), depth(0), color(-1) {
    // Decode PNG header.
    png = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)this, errorHandler, errorHandler);
    assert(png);
    info = png_create_info_struct(png);
    assert(info);

    if (setjmp(png_jmpbuf(png))) {
        width = 0;
        height = 0;
        return;
    }

    png_set_read_fn(png, this, readCallback);
    png_read_info(png, info);
    png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
    alpha = (color & PNG_COLOR_MASK_ALPHA) || png_get_valid(png, info, PNG_INFO_tRNS);
}

void PNGImageReader::readCallback(png_structp png, png_bytep data, png_size_t length) {
    PNGImageReader* reader = static_cast<PNGImageReader*>(png_get_error_ptr(png));

    // Read `length` bytes into `data`.
    if (reader->pos + length > reader->length) {
        png_error(png, "Read Error");
        return;
    }

    memcpy(data, reader->source + reader->pos, length);
    reader->pos += length;
}

void PNGImageReader::errorHandler(png_structp png, png_const_charp error_msg) {
    PNGImageReader* reader = static_cast<PNGImageReader*>(png_get_io_ptr(png));

    reader->message = error_msg;

    if (png) {
        longjmp(png->jmpbuf, 1);
    }
    exit(1);
}

unsigned char* PNGImageReader::decode() {
    if (setjmp(png_jmpbuf(png))) {
        png_destroy_read_struct(&png, &info, NULL);
        width = 0;
        height = 0;
        return NULL;
    }

    // From http://trac.mapnik.org/browser/trunk/src/png_reader.cpp
    if (color == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(png);
    if (color == PNG_COLOR_TYPE_GRAY)
        png_set_expand(png);
    if (png_get_valid(png, info, PNG_INFO_tRNS))
        png_set_expand(png);
    if (depth == 16)
        png_set_strip_16(png);
    if (depth < 8)
        png_set_packing(png);
    if (color == PNG_COLOR_TYPE_GRAY ||
        color == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png);

    // Always add an alpha channel.
    if (!this->alpha) {
        png_set_add_alpha(png, 0xFF, PNG_FILLER_AFTER);
    }

    double gamma;
    if (png_get_gAMA(png, info, &gamma))
        png_set_gamma(png, 2.2, gamma);

    png_read_update_info(png, info);

    unsigned int rowbytes = png_get_rowbytes(png, info);
    assert(width * 4 == rowbytes);

    unsigned char* surface = (unsigned char*)malloc(width * height * 4);
    assert(surface);

    png_bytep row_pointers[height];
    for (unsigned i = 0; i < height; i++) {
        row_pointers[i] = (unsigned char*)(surface + (i * rowbytes));
    }

    // Read image data
    png_read_image(png, row_pointers);

    png_read_end(png, NULL);

    return surface;
}

PNGImageReader::~PNGImageReader() {
    png_destroy_read_struct(&png, &info, NULL);
    png = NULL;
    info = NULL;
}

JPEGImageReader::JPEGImageReader(unsigned char* src, size_t len) :
        ImageReader(src, len) {
    err.reader = this;
    info.err = jpeg_std_error(&err.pub);
    err.pub.error_exit = errorHandler;
    err.pub.output_message = errorMessage;

    if (setjmp(err.jump)) {
        width = 0;
        height = 0;

        // Error message was set by JPEGImageReader::errorMessage.
        return;
    }
    jpeg_create_decompress(&info);
    jpeg_mem_src(&info, src, len);
    jpeg_read_header(&info, TRUE);
    width = info.image_width;
    height = info.image_height;
    alpha = false;
}

void JPEGImageReader::errorHandler(j_common_ptr cinfo) {
    // libjpeg recommends doing this memory alignment trickery.
    JPEGErrorManager* error = (JPEGErrorManager*)cinfo->err;

    /* Return control to the setjmp point */
    longjmp(error->jump, 1);
}

void JPEGImageReader::errorMessage(j_common_ptr cinfo) {
    // libjpeg recommends doing this memory alignment trickery.
    JPEGErrorManager* error = (JPEGErrorManager*)cinfo->err;

    char buffer[JMSG_LENGTH_MAX];
    (*cinfo->err->format_message) (cinfo, buffer);
    error->reader->message = buffer;
}

unsigned char* JPEGImageReader::decode() {
    if (info.data_precision != 8) return NULL;
    if (info.num_components != 3 && info.num_components != 1) return NULL;

    size_t length = width * height * 4;
    unsigned char* surface = (unsigned char*)malloc(length);
    if (surface == NULL) {
        message = "Insufficient memory";
        jpeg_destroy_decompress(&info);
        return NULL;
    }

    if (setjmp(err.jump)) {
        free(surface);

        // Error message was set by JPEGImageReader::errorMessage.
        return NULL;
    }

    info.out_color_space = JCS_RGB;

    jpeg_start_decompress(&info);

    unsigned char* row_pointers[height];
    for (unsigned i = 0; i < height; i++) {
        row_pointers[i] = (unsigned char*)(surface + (i * width * 4));
    }

    size_t offset = 0;
    while (info.output_scanline < info.output_height) {
        offset += jpeg_read_scanlines(&info, row_pointers + offset, height - offset);
    }

    for (unsigned i = 0; i < height; i++) {
        unsigned char* destination = surface + i * width * 4;
        unsigned int* image = (unsigned int*)destination;
        for (int j = width - 1, k = j * 3; j >= 0; k = --j * 3) {
            image[j] = 0xFF << 24 | destination[k + 2] << 16 |
                destination[k + 1] << 8 | destination[k];
        }
    }

    jpeg_finish_decompress(&info);

    return surface;
}

JPEGImageReader::~JPEGImageReader() {
    jpeg_destroy_decompress(&info);
}

ImageReader* ImageReader::create(unsigned char* src, size_t len) {
    if (png_sig_cmp((png_bytep)src, 0, 8) == 0) {
        return new PNGImageReader(src, len);
    } else if (src[0] == 255 && src[1] == 216) {
        return new JPEGImageReader(src, len);
    } else {
        return new ImageReader("Unknown image format");
    }
}
<|endoftext|>


<commit_before>/*
Copyright libCellML Contributors

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

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

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

#include "libcellml/reset.h"

#include <vector>

#include <libcellml/when.h>

namespace libcellml {

/**
 * @brief The Reset::ResetImpl struct.
 *
 * The private implementation for the Reset class.
 */
struct Reset::ResetImpl
{
    int mOrder; /**< An integer for determining relative order.*/
    std::vector<WhenPtr>::iterator findWhen(const WhenPtr &when);
    std::vector<WhenPtr> mWhens;
};

std::vector<WhenPtr>::iterator Reset::ResetImpl::findWhen(const WhenPtr &when)
{
    return std::find_if(mWhens.begin(), mWhens.end(),
                        [=](const WhenPtr& w) -> bool { return w == when; });
}

Reset::Reset()
    : mPimpl(new ResetImpl())
{
}

Reset::~Reset()
{
    delete mPimpl;
}

Reset::Reset(const Reset& rhs)
    : Entity(rhs)
    , mPimpl(new ResetImpl())
{
    mPimpl->mOrder = rhs.mPimpl->mOrder;
    mPimpl->mWhens = rhs.mPimpl->mWhens;
}

Reset::Reset(Reset &&rhs)
    : Entity(std::move(rhs))
    , mPimpl(rhs.mPimpl)
{
    rhs.mPimpl = nullptr;
}

Reset& Reset::operator=(Reset e)
{
    Entity::operator= (e);
    e.swap(*this);
    return *this;
}

void Reset::swap(Reset &rhs)
{
    std::swap(this->mPimpl, rhs.mPimpl);
}

void Reset::setOrder(int order)
{
    mPimpl->mOrder = order;
}

int Reset::getOrder() const
{
    return mPimpl->mOrder;
}

void Reset::addWhen(const WhenPtr &when)
{
    mPimpl->mWhens.push_back(when);
}

bool Reset::removeWhen(size_t index)
{
    bool status = false;

    if (index < mPimpl->mWhens.size()) {
        mPimpl->mWhens.erase(mPimpl->mWhens.begin() + index);
        status = true;
    }

    return status;
}

bool Reset::removeWhen(const WhenPtr &when)
{
    bool status = false;
    auto result = mPimpl->findWhen(when);
    if (result != mPimpl->mWhens.end()) {
        mPimpl->mWhens.erase(result);
        status = true;
    }

    return status;
}

void Reset::removeAllWhens()
{

}

bool Reset::containsWhen(const WhenPtr &when) const
{
    bool status = false;
    auto result = mPimpl->findWhen(when);
    if (result != mPimpl->mWhens.end()) {
        status = true;
    }

    return status;
}

WhenPtr Reset::getWhen(size_t index) const
{
    WhenPtr when = nullptr;
    if (index < mPimpl->mWhens.size()) {
        when = mPimpl->mWhens.at(index);
    }

    return when;
}

WhenPtr Reset::takeWhen(size_t index)
{
    WhenPtr when = nullptr;
    if (index < mPimpl->mWhens.size()) {
        when = mPimpl->mWhens.at(index);
        mPimpl->mWhens.erase(mPimpl->mWhens.begin() + index);
    }

    return when;
}

bool Reset::replaceWhen(size_t index, const WhenPtr &when)
{
    bool status = false;
    if (removeWhen(index)) {
        mPimpl->mWhens.insert(mPimpl->mWhens.begin() + index, when);
        status = true;
    }

    return status;
}

size_t Reset::whenCount() const
{
    return 1;
}

}

<commit_msg>Add algorithm header for find_if declaration.<commit_after>/*
Copyright libCellML Contributors

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

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

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

#include "libcellml/reset.h"

#include <algorithm>
#include <vector>

#include <libcellml/when.h>

namespace libcellml {

/**
 * @brief The Reset::ResetImpl struct.
 *
 * The private implementation for the Reset class.
 */
struct Reset::ResetImpl
{
    int mOrder; /**< An integer for determining relative order.*/
    std::vector<WhenPtr>::iterator findWhen(const WhenPtr &when);
    std::vector<WhenPtr> mWhens;
};

std::vector<WhenPtr>::iterator Reset::ResetImpl::findWhen(const WhenPtr &when)
{
    return std::find_if(mWhens.begin(), mWhens.end(),
                        [=](const WhenPtr& w) -> bool { return w == when; });
}

Reset::Reset()
    : mPimpl(new ResetImpl())
{
}

Reset::~Reset()
{
    delete mPimpl;
}

Reset::Reset(const Reset& rhs)
    : Entity(rhs)
    , mPimpl(new ResetImpl())
{
    mPimpl->mOrder = rhs.mPimpl->mOrder;
    mPimpl->mWhens = rhs.mPimpl->mWhens;
}

Reset::Reset(Reset &&rhs)
    : Entity(std::move(rhs))
    , mPimpl(rhs.mPimpl)
{
    rhs.mPimpl = nullptr;
}

Reset& Reset::operator=(Reset e)
{
    Entity::operator= (e);
    e.swap(*this);
    return *this;
}

void Reset::swap(Reset &rhs)
{
    std::swap(this->mPimpl, rhs.mPimpl);
}

void Reset::setOrder(int order)
{
    mPimpl->mOrder = order;
}

int Reset::getOrder() const
{
    return mPimpl->mOrder;
}

void Reset::addWhen(const WhenPtr &when)
{
    mPimpl->mWhens.push_back(when);
}

bool Reset::removeWhen(size_t index)
{
    bool status = false;

    if (index < mPimpl->mWhens.size()) {
        mPimpl->mWhens.erase(mPimpl->mWhens.begin() + index);
        status = true;
    }

    return status;
}

bool Reset::removeWhen(const WhenPtr &when)
{
    bool status = false;
    auto result = mPimpl->findWhen(when);
    if (result != mPimpl->mWhens.end()) {
        mPimpl->mWhens.erase(result);
        status = true;
    }

    return status;
}

void Reset::removeAllWhens()
{

}

bool Reset::containsWhen(const WhenPtr &when) const
{
    bool status = false;
    auto result = mPimpl->findWhen(when);
    if (result != mPimpl->mWhens.end()) {
        status = true;
    }

    return status;
}

WhenPtr Reset::getWhen(size_t index) const
{
    WhenPtr when = nullptr;
    if (index < mPimpl->mWhens.size()) {
        when = mPimpl->mWhens.at(index);
    }

    return when;
}

WhenPtr Reset::takeWhen(size_t index)
{
    WhenPtr when = nullptr;
    if (index < mPimpl->mWhens.size()) {
        when = mPimpl->mWhens.at(index);
        mPimpl->mWhens.erase(mPimpl->mWhens.begin() + index);
    }

    return when;
}

bool Reset::replaceWhen(size_t index, const WhenPtr &when)
{
    bool status = false;
    if (removeWhen(index)) {
        mPimpl->mWhens.insert(mPimpl->mWhens.begin() + index, when);
        status = true;
    }

    return status;
}

size_t Reset::whenCount() const
{
    return 1;
}

}

<|endoftext|>


<commit_before>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/to_gray.h"
#include "./placement/distance_transform.h"
#include "./placement/occupancy.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./placement/constraint_updater.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller,
             std::shared_ptr<Placement::Labeller> placementLabeller,
             std::shared_ptr<TextureMapperManager> textureMapperManager)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    placementLabeller(placementLabeller), frustumOptimizer(nodes),
    textureMapperManager(textureMapperManager)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>();
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  screenQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/combineLayers.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  screenQuad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  auto drawer = std::make_shared<Graphics::BufferDrawer>(
      textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize(), gl, managers->getShaderManager());

  auto constraintUpdater = std::make_shared<ConstraintUpdater>(
      drawer, textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize());

  placementLabeller->initialize(
      textureMapperManager->getOccupancyTextureMapper(),
      textureMapperManager->getDistanceTransformTextureMapper(),
      textureMapperManager->getApolloniusTextureMapper(),
      textureMapperManager->getConstraintTextureMapper(), constraintUpdater);
}

void Scene::cleanup()
{
  placementLabeller->cleanup();
  textureMapperManager->cleanup();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  auto camera = getCamera();

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  frustumOptimizer.update(camera->getViewMatrix());
  camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                 frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  /*
  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));
      */
  auto newPositions = placementLabeller->getLastPlacementResult();
  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  if (camera->needsResizing())
    camera->resize(width, height);

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData = createRenderData();

  renderNodesWithHABufferIntoFBO(renderData);

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  textureMapperManager->update();

  constraintBufferObject->bind();

  placementLabeller->update(LabellerFrameData(
      frameTime, camera->getProjectionMatrix(), camera->getViewMatrix()));

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  nodes->renderLabels(gl, managers, renderData);
}

void Scene::renderNodesWithHABufferIntoFBO(const RenderData &renderData)
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  picker->doPick(renderData.projectionMatrix * renderData.viewMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    fbo->bindColorTexture(i, GL_TEXTURE0);
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8 + 0.4 * i, -0.4, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
    renderQuad(quad, transformation.matrix());
  }

  fbo->bindDepthTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindOccupancyTexture();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindDistanceTransform();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  textureMapperManager->bindApollonius();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  if (activeLayerNumber == 0)
  {
    fbo->bindColorTexture(0, GL_TEXTURE0);
    fbo->bindColorTexture(1, GL_TEXTURE1);
    fbo->bindColorTexture(2, GL_TEXTURE2);
    fbo->bindColorTexture(3, GL_TEXTURE3);

    screenQuad->getShaderProgram()->setUniform("layer1", 0);
    screenQuad->getShaderProgram()->setUniform("layer2", 1);
    screenQuad->getShaderProgram()->setUniform("layer3", 2);
    screenQuad->getShaderProgram()->setUniform("layer4", 3);
    renderQuad(screenQuad, Eigen::Matrix4f::Identity());

    gl->glActiveTexture(GL_TEXTURE0);
  }
  else
  {
    fbo->bindColorTexture(activeLayerNumber - 1, GL_TEXTURE0);
    renderQuad(quad, Eigen::Matrix4f::Identity());
  }
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  placementLabeller->resize(width, height);

  shouldResize = true;

  forcesLabeller->resize(width, height);
}

RenderData Scene::createRenderData()
{
  RenderData renderData;
  auto camera = getCamera();
  renderData.projectionMatrix = camera->getProjectionMatrix();
  renderData.viewMatrix = camera->getViewMatrix();
  renderData.cameraPosition = camera->getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();
  renderData.windowPixelSize = Eigen::Vector2f(width, height);

  return renderData;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

void Scene::setRenderLayer(int layerNumber)
{
  activeLayerNumber = layerNumber;
}

<commit_msg>Show depth textures for debugging.<commit_after>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/to_gray.h"
#include "./placement/distance_transform.h"
#include "./placement/occupancy.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./placement/constraint_updater.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller,
             std::shared_ptr<Placement::Labeller> placementLabeller,
             std::shared_ptr<TextureMapperManager> textureMapperManager)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    placementLabeller(placementLabeller), frustumOptimizer(nodes),
    textureMapperManager(textureMapperManager)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>();
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  screenQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/combineLayers.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  screenQuad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  auto drawer = std::make_shared<Graphics::BufferDrawer>(
      textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize(), gl, managers->getShaderManager());

  auto constraintUpdater = std::make_shared<ConstraintUpdater>(
      drawer, textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize());

  placementLabeller->initialize(
      textureMapperManager->getOccupancyTextureMapper(),
      textureMapperManager->getDistanceTransformTextureMapper(),
      textureMapperManager->getApolloniusTextureMapper(),
      textureMapperManager->getConstraintTextureMapper(), constraintUpdater);
}

void Scene::cleanup()
{
  placementLabeller->cleanup();
  textureMapperManager->cleanup();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  auto camera = getCamera();

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  frustumOptimizer.update(camera->getViewMatrix());
  camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                 frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  /*
  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));
      */
  auto newPositions = placementLabeller->getLastPlacementResult();
  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  if (camera->needsResizing())
    camera->resize(width, height);

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData = createRenderData();

  renderNodesWithHABufferIntoFBO(renderData);

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  textureMapperManager->update();

  constraintBufferObject->bind();

  placementLabeller->update(LabellerFrameData(
      frameTime, camera->getProjectionMatrix(), camera->getViewMatrix()));

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  nodes->renderLabels(gl, managers, renderData);
}

void Scene::renderNodesWithHABufferIntoFBO(const RenderData &renderData)
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  picker->doPick(renderData.projectionMatrix * renderData.viewMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    fbo->bindColorTexture(i, GL_TEXTURE0);
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8 + 0.4 * i, -0.4, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
    renderQuad(quad, transformation.matrix());
  }

  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    fbo->bindDepthTexture(i, GL_TEXTURE0);
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8 + 0.4 * i, 0.8, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
    renderQuad(quad, transformation.matrix());
  }

  fbo->bindDepthTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindOccupancyTexture();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindDistanceTransform();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  textureMapperManager->bindApollonius();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  if (activeLayerNumber == 0)
  {
    fbo->bindColorTexture(0, GL_TEXTURE0);
    fbo->bindColorTexture(1, GL_TEXTURE1);
    fbo->bindColorTexture(2, GL_TEXTURE2);
    fbo->bindColorTexture(3, GL_TEXTURE3);

    screenQuad->getShaderProgram()->setUniform("layer1", 0);
    screenQuad->getShaderProgram()->setUniform("layer2", 1);
    screenQuad->getShaderProgram()->setUniform("layer3", 2);
    screenQuad->getShaderProgram()->setUniform("layer4", 3);
    renderQuad(screenQuad, Eigen::Matrix4f::Identity());

    gl->glActiveTexture(GL_TEXTURE0);
  }
  else
  {
    fbo->bindColorTexture(activeLayerNumber - 1, GL_TEXTURE0);
    renderQuad(quad, Eigen::Matrix4f::Identity());
  }
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  placementLabeller->resize(width, height);

  shouldResize = true;

  forcesLabeller->resize(width, height);
}

RenderData Scene::createRenderData()
{
  RenderData renderData;
  auto camera = getCamera();
  renderData.projectionMatrix = camera->getProjectionMatrix();
  renderData.viewMatrix = camera->getViewMatrix();
  renderData.cameraPosition = camera->getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();
  renderData.windowPixelSize = Eigen::Vector2f(width, height);

  return renderData;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

void Scene::setRenderLayer(int layerNumber)
{
  activeLayerNumber = layerNumber;
}

<|endoftext|>


<commit_before><commit_msg>Disabled flaky ppapi unittests.<commit_after><|endoftext|>


<commit_before>#include <node.h>
#include <string>

#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#else // !_WIN32
#include <cstdlib>
#include <cerrno>
#include <unistd.h>
#endif // _WIN32

using namespace v8;

#ifdef _WIN32

int exec(const char* command) {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    DWORD exitCode;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // Start the child process.
    if(!CreateProcess(NULL,     // No module name (use command line)
                (LPSTR) command,// Command line
                NULL,           // Process handle not inheritable
                NULL,           // Thread handle not inheritable
                FALSE,          // Set handle inheritance to FALSE
                0,              // No creation flags
                NULL,           // Use parent's environment block
                NULL,           // Use parent's starting directory
                &si,            // Pointer to STARTUPINFO structure
                &pi)            // Pointer to PROCESS_INFORMATION structure
      )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return 1;
    }

    // Wait until child process exits.
    WaitForSingleObject(pi.hProcess, INFINITE);
    GetExitCodeProcess(pi.hProcess, &exitCode);

    // Close process and thread handles.
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return exitCode;
}

#else // *nix

void child(const char* command) {
    char cmd[1024];
    snprintf(cmd, sizeof cmd, "%s", command);

    close(0);
    dup(1);
    close(1);
    dup(2);
    dup2(1, 2);

    execlp("sh", "sh", "-c", command, (char*)0);

    // if we get here, execlp failed
    perror("execlp");
    exit(1);
}

int parent(int pid) {
    int got_pid, status;

    while ((got_pid = wait(&status))) {   /* go to sleep until something happens */
        /* wait woke up */
        if (got_pid == pid)
            break;  /* this is what we were looking for */
        if ((got_pid == -1) && (errno != EINTR)) {
            /* an error other than an interrupted system call */
            perror("waitpid");
            return errno;
        }
    }

    if (WIFEXITED(status))  /* process exited normally */
        //printf("child process exited with value %d\n", WEXITSTATUS(status));
        return WEXITSTATUS(status);
    else if (WIFSIGNALED(status))   /* child exited on a signal */
        // printf("child process exited due to signal %d\n", WTERMSIG(status));
        return WTERMSIG(status);
    else if (WIFSTOPPED(status))    /* child was stopped */
        // printf("child process was stopped by signal %d\n", WIFSTOPPED(status));
        return WIFSTOPPED(status);

    return 1;
}

int exec(const char* command) {
    int pid;    /* process ID */

    switch (pid = fork()) {
        case 0:     /* a fork returns 0 to the child */
            child(command);
            break;

        default:    /* a fork returns a pid to the parent */
            return parent(pid);
            break;

        case -1:    /* something went wrong */
            perror("fork");
            exit(1);
    }
    exit(0);
}

#endif

std::string FlattenString(v8::Handle<v8::String> v8str) {
    v8::String::Utf8Value utf8str(v8str);
    return std::string(*utf8str, utf8str.length());
}

/**
 * Executes a command.
 */

// Returns the Nth number in the fibonacci sequence where N is the first
// argument passed.
Handle<Value> Exec(const Arguments& args) {
    HandleScope scope;

    if (args.Length() < 1) {
        return ThrowException(
            Exception::TypeError(String::New("First argument must be a string"))
        );
    }

    Local<String> str = args[0]->ToString();
    std::string cmd = FlattenString(str);
    int result = exec(cmd.c_str());

    return scope.Close(Integer::New(result));
}

void RegisterModule(Handle<Object> target) {
    target->Set(String::NewSymbol("exec"),
            FunctionTemplate::New(Exec)->GetFunction());
}

NODE_MODULE(shell, RegisterModule);
<commit_msg>remove example comment<commit_after>#include <node.h>
#include <string>

#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#else // !_WIN32
#include <cstdlib>
#include <cerrno>
#include <unistd.h>
#endif // _WIN32

using namespace v8;

#ifdef _WIN32

int exec(const char* command) {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    DWORD exitCode;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // Start the child process.
    if(!CreateProcess(NULL,     // No module name (use command line)
                (LPSTR) command,// Command line
                NULL,           // Process handle not inheritable
                NULL,           // Thread handle not inheritable
                FALSE,          // Set handle inheritance to FALSE
                0,              // No creation flags
                NULL,           // Use parent's environment block
                NULL,           // Use parent's starting directory
                &si,            // Pointer to STARTUPINFO structure
                &pi)            // Pointer to PROCESS_INFORMATION structure
      )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return 1;
    }

    // Wait until child process exits.
    WaitForSingleObject(pi.hProcess, INFINITE);
    GetExitCodeProcess(pi.hProcess, &exitCode);

    // Close process and thread handles.
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return exitCode;
}

#else // *nix

void child(const char* command) {
    char cmd[1024];
    snprintf(cmd, sizeof cmd, "%s", command);

    close(0);
    dup(1);
    close(1);
    dup(2);
    dup2(1, 2);

    execlp("sh", "sh", "-c", command, (char*)0);

    // if we get here, execlp failed
    perror("execlp");
    exit(1);
}

int parent(int pid) {
    int got_pid, status;

    while ((got_pid = wait(&status))) {   /* go to sleep until something happens */
        /* wait woke up */
        if (got_pid == pid)
            break;  /* this is what we were looking for */
        if ((got_pid == -1) && (errno != EINTR)) {
            /* an error other than an interrupted system call */
            perror("waitpid");
            return errno;
        }
    }

    if (WIFEXITED(status))  /* process exited normally */
        //printf("child process exited with value %d\n", WEXITSTATUS(status));
        return WEXITSTATUS(status);
    else if (WIFSIGNALED(status))   /* child exited on a signal */
        // printf("child process exited due to signal %d\n", WTERMSIG(status));
        return WTERMSIG(status);
    else if (WIFSTOPPED(status))    /* child was stopped */
        // printf("child process was stopped by signal %d\n", WIFSTOPPED(status));
        return WIFSTOPPED(status);

    return 1;
}

int exec(const char* command) {
    int pid;    /* process ID */

    switch (pid = fork()) {
        case 0:     /* a fork returns 0 to the child */
            child(command);
            break;

        default:    /* a fork returns a pid to the parent */
            return parent(pid);
            break;

        case -1:    /* something went wrong */
            perror("fork");
            exit(1);
    }
    exit(0);
}

#endif

std::string FlattenString(v8::Handle<v8::String> v8str) {
    v8::String::Utf8Value utf8str(v8str);
    return std::string(*utf8str, utf8str.length());
}

/**
 * Executes a command.
 */
Handle<Value> Exec(const Arguments& args) {
    HandleScope scope;

    if (args.Length() < 1) {
        return ThrowException(
            Exception::TypeError(String::New("First argument must be a string"))
        );
    }

    Local<String> str = args[0]->ToString();
    std::string cmd = FlattenString(str);
    int result = exec(cmd.c_str());

    return scope.Close(Integer::New(result));
}

void RegisterModule(Handle<Object> target) {
    target->Set(String::NewSymbol("exec"),
            FunctionTemplate::New(Exec)->GetFunction());
}

NODE_MODULE(shell, RegisterModule);
<|endoftext|>


<commit_before>/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "skirt.h"
#include "support.h"

namespace cura
{

void generateSkirt(SliceDataStorage& storage, int distance, int count, int minLength)
{
    if (count == 0) return;

    bool externalOnly = (distance > 0); // whether to include holes or not

    const int primary_extruder = storage.getSettingAsIndex("adhesion_extruder_nr");
    const int primary_skirt_line_width = storage.meshgroup->getExtruderTrain(primary_extruder)->getSettingInMicrons("skirt_line_width");

    Polygons& skirt_primary_extruder = storage.skirt[primary_extruder];

    bool get_convex_hull = count == 1 && distance > 0;

    Polygons first_layer_outline = storage.getLayerOutlines(0, true, externalOnly);

    std::vector<Polygons> skirts;
    for(int skirtNr=0; skirtNr<count;skirtNr++)
    {
        const int offsetDistance = distance + primary_skirt_line_width * skirtNr + primary_skirt_line_width / 2;

        skirts.emplace_back(first_layer_outline.offset(offsetDistance, ClipperLib::jtRound));
        Polygons& skirt_polygons = skirts.back();

        //Remove small inner skirt holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
        for(unsigned int n=0; n<skirt_polygons.size(); n++)
        {
            double area = skirt_polygons[n].area();
            if (area < 0 && area > -primary_skirt_line_width * primary_skirt_line_width * 100)
            {
                skirt_polygons.remove(n--);
            }
        }

        if (get_convex_hull)
        {
            skirt_polygons = skirt_polygons.approxConvexHull();
        }

        skirt_primary_extruder.add(skirt_polygons);

        int length = skirt_primary_extruder.polygonLength();
        if (skirtNr + 1 >= count && length > 0 && length < minLength) // make brim have more lines when total length is too small
            count++;
    }

    { // process other extruders' brim/skirt (as one brim line around the old brim)
        int offset_distance = 0;
        int last_width = primary_skirt_line_width;
        for (int extruder = 0; extruder < storage.meshgroup->getExtruderCount(); extruder++)
        {
            if (extruder == primary_extruder) { continue; }
            int width = storage.meshgroup->getExtruderTrain(extruder)->getSettingInMicrons("skirt_line_width");
            offset_distance += last_width / 2 + width/2;
            last_width = width;
            while (storage.skirt[extruder].polygonLength() < minLength)
            {
                storage.skirt[extruder].add(skirts.back().offset(offset_distance, ClipperLib::jtRound));
                offset_distance += width;
            }
        }
    }
}

}//namespace cura
<commit_msg>Rename primary_skirt_line_width to primary_extruder_skirt_line_width<commit_after>/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "skirt.h"
#include "support.h"

namespace cura
{

void generateSkirt(SliceDataStorage& storage, int distance, int count, int minLength)
{
    if (count == 0) return;

    bool externalOnly = (distance > 0); // whether to include holes or not

    const int primary_extruder = storage.getSettingAsIndex("adhesion_extruder_nr");
    const int primary_extruder_skirt_line_width = storage.meshgroup->getExtruderTrain(primary_extruder)->getSettingInMicrons("skirt_line_width");

    Polygons& skirt_primary_extruder = storage.skirt[primary_extruder];

    bool get_convex_hull = count == 1 && distance > 0;

    Polygons first_layer_outline = storage.getLayerOutlines(0, true, externalOnly);

    std::vector<Polygons> skirts;
    for(int skirtNr=0; skirtNr<count;skirtNr++)
    {
        const int offsetDistance = distance + primary_extruder_skirt_line_width * skirtNr + primary_extruder_skirt_line_width / 2;

        skirts.emplace_back(first_layer_outline.offset(offsetDistance, ClipperLib::jtRound));
        Polygons& skirt_polygons = skirts.back();

        //Remove small inner skirt holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
        for(unsigned int n=0; n<skirt_polygons.size(); n++)
        {
            double area = skirt_polygons[n].area();
            if (area < 0 && area > -primary_extruder_skirt_line_width * primary_extruder_skirt_line_width * 100)
            {
                skirt_polygons.remove(n--);
            }
        }

        if (get_convex_hull)
        {
            skirt_polygons = skirt_polygons.approxConvexHull();
        }

        skirt_primary_extruder.add(skirt_polygons);

        int length = skirt_primary_extruder.polygonLength();
        if (skirtNr + 1 >= count && length > 0 && length < minLength) // make brim have more lines when total length is too small
            count++;
    }

    { // process other extruders' brim/skirt (as one brim line around the old brim)
        int offset_distance = 0;
        int last_width = primary_extruder_skirt_line_width;
        for (int extruder = 0; extruder < storage.meshgroup->getExtruderCount(); extruder++)
        {
            if (extruder == primary_extruder) { continue; }
            int width = storage.meshgroup->getExtruderTrain(extruder)->getSettingInMicrons("skirt_line_width");
            offset_distance += last_width / 2 + width/2;
            last_width = width;
            while (storage.skirt[extruder].polygonLength() < minLength)
            {
                storage.skirt[extruder].add(skirts.back().offset(offset_distance, ClipperLib::jtRound));
                offset_distance += width;
            }
        }
    }
}

}//namespace cura
<|endoftext|>


<commit_before>/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "skirt.h"
#include "support.h"

#include <queue>

namespace cura
{

void generateSkirt(SliceDataStorage& storage, int distance, int extrusionWidth, int count, int minLength)
{
    if (count == 0) return;

    bool externalOnly = (distance > 0);

    Polygons support;
    if (storage.support.generated)
        support = storage.support.supportLayers[0].supportAreas;
    { // get support polygons
        for(SliceMeshStorage& mesh : storage.meshes)
        {
            if (mesh.layers.size() < 1) continue;
            SliceLayer* layer = &mesh.layers[0];
            for(unsigned int i=0; i<layer->parts.size(); i++)
                support = support.difference(layer->parts[i].outline);
        }

        // expand and contract to smooth the final polygon
        if (count == 1 && distance > 0)
        {
            int dist = extrusionWidth * 5;
            support = support.offset(dist).offset(-dist);
        }
    }

    for(int skirtNr=0; skirtNr<count;skirtNr++)
    {
        int offsetDistance = distance + extrusionWidth * skirtNr + extrusionWidth / 2;

        Polygons skirtPolygons(storage.wipeTower.offset(offsetDistance));
        for(SliceMeshStorage& mesh : storage.meshes)
        {
            if (mesh.layers.size() < 1) continue;
            for(SliceLayerPart& part : mesh.layers[0].parts)
            {
                if (externalOnly)
                {
                    Polygons p;
                    p.add(part.outline.outerPolygon());
                    skirtPolygons = skirtPolygons.unionPolygons(p.offset(offsetDistance, ClipperLib::jtRound));
                }
                else
                {
                    skirtPolygons = skirtPolygons.unionPolygons(part.outline.offset(offsetDistance, ClipperLib::jtRound));
                }
            }
        }

        skirtPolygons = skirtPolygons.unionPolygons(support.offset(offsetDistance, ClipperLib::jtRound));
        //Remove small inner skirt holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
        for(unsigned int n=0; n<skirtPolygons.size(); n++)
        {
            double area = skirtPolygons[n].area();
            if (area < 0 && area > -extrusionWidth * extrusionWidth * 100)
                skirtPolygons.remove(n--);
        }

        storage.skirt.add(skirtPolygons);

        int lenght = storage.skirt.polygonLength();
        if (skirtNr + 1 >= count && lenght > 0 && lenght < minLength) // make brim have more lines when total length is too small
            count++;
    }

    //Add a skirt under the wipetower to make it stick better.
    Polygons wipe_tower = storage.wipeTower.offset(-extrusionWidth / 2);
    std::queue<Polygons> wipe_tower_insets;
    while(wipe_tower.size() > 0)
    {
        wipe_tower_insets.emplace(wipe_tower);
        wipe_tower = wipe_tower.offset(-extrusionWidth);
    }
    while (wipe_tower_insets.empty())
    {
        Polygons& inset = wipe_tower_insets.back();
        storage.skirt.add(inset);
        wipe_tower_insets.pop();
    }

    if (count == 1 && distance > 0)
    {
        storage.skirt = storage.skirt.convexHull();
    }
}

}//namespace cura
<commit_msg>bugfix: wipe_tower inverse order on first layer<commit_after>/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "skirt.h"
#include "support.h"

#include <queue>

namespace cura
{

void generateSkirt(SliceDataStorage& storage, int distance, int extrusionWidth, int count, int minLength)
{
    if (count == 0) return;

    bool externalOnly = (distance > 0);

    Polygons support;
    if (storage.support.generated)
        support = storage.support.supportLayers[0].supportAreas;
    { // get support polygons
        for(SliceMeshStorage& mesh : storage.meshes)
        {
            if (mesh.layers.size() < 1) continue;
            SliceLayer* layer = &mesh.layers[0];
            for(unsigned int i=0; i<layer->parts.size(); i++)
                support = support.difference(layer->parts[i].outline);
        }

        // expand and contract to smooth the final polygon
        if (count == 1 && distance > 0)
        {
            int dist = extrusionWidth * 5;
            support = support.offset(dist).offset(-dist);
        }
    }

    for(int skirtNr=0; skirtNr<count;skirtNr++)
    {
        int offsetDistance = distance + extrusionWidth * skirtNr + extrusionWidth / 2;

        Polygons skirtPolygons(storage.wipeTower.offset(offsetDistance));
        for(SliceMeshStorage& mesh : storage.meshes)
        {
            if (mesh.layers.size() < 1) continue;
            for(SliceLayerPart& part : mesh.layers[0].parts)
            {
                if (externalOnly)
                {
                    Polygons p;
                    p.add(part.outline.outerPolygon());
                    skirtPolygons = skirtPolygons.unionPolygons(p.offset(offsetDistance, ClipperLib::jtRound));
                }
                else
                {
                    skirtPolygons = skirtPolygons.unionPolygons(part.outline.offset(offsetDistance, ClipperLib::jtRound));
                }
            }
        }

        skirtPolygons = skirtPolygons.unionPolygons(support.offset(offsetDistance, ClipperLib::jtRound));
        //Remove small inner skirt holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
        for(unsigned int n=0; n<skirtPolygons.size(); n++)
        {
            double area = skirtPolygons[n].area();
            if (area < 0 && area > -extrusionWidth * extrusionWidth * 100)
                skirtPolygons.remove(n--);
        }

        storage.skirt.add(skirtPolygons);

        int lenght = storage.skirt.polygonLength();
        if (skirtNr + 1 >= count && lenght > 0 && lenght < minLength) // make brim have more lines when total length is too small
            count++;
    }

    //Add a skirt under the wipetower to make it stick better.
    Polygons wipe_tower = storage.wipeTower.offset(-extrusionWidth / 2);
    std::queue<Polygons> wipe_tower_insets;
    while(wipe_tower.size() > 0)
    {
        wipe_tower_insets.emplace(wipe_tower);
        wipe_tower = wipe_tower.offset(-extrusionWidth);
    }
    while (!wipe_tower_insets.empty())
    {
        Polygons& inset = wipe_tower_insets.back();
        storage.skirt.add(inset);
        wipe_tower_insets.pop();
    }

    if (count == 1 && distance > 0)
    {
        storage.skirt = storage.skirt.convexHull();
    }
}

}//namespace cura
<|endoftext|>


<commit_before>#include <boost/algorithm/string.hpp>
#include <iostream>
using namespace std;

const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

string encrypt(const string& plaintext, const string& keyword)
{
  /* Returns the plaintext encrypted using the given keyword and the Vigenere
   * Cipher (http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher).
   */

  string cap_keyword = to_upper(keyword);
  string keyphrase = "";

  for (int i = 0; i < plaintext.length() / keyword.length() + 1; i++)
  {
    keyphrase += cap_keyword;
  }

  keyphrase.resize(plaintext.length());

  string ciphertext = "";
  for (int i = 0; i < plaintext.length(); i++)
  {
    start_index = alphabet.find(to_upper(plaintext[i]));
    advance_by = alphabet.find(keyphrase[i]);
    ciphertext += alphabet[(start_index + advance_by) % alphabet.length()];
  }

  return ciphertext;
}

string decrypt(const string& plaintext, const string& keyword)
{
  return "XXXX: Write me!";
}
<commit_msg>Another missing semicolon.<commit_after>#include <boost/algorithm/string.hpp>
#include <iostream>
using namespace std;

const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

string encrypt(const string& plaintext, const string& keyword)
{
  /* Returns the plaintext encrypted using the given keyword and the Vigenere
   * Cipher (http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher).
   */

  string cap_keyword = to_upper(keyword);
  string keyphrase = "";

  for (int i = 0; i < plaintext.length() / keyword.length() + 1; i++)
  {
    keyphrase += cap_keyword;
  }

  keyphrase.resize(plaintext.length());

  string ciphertext = "";
  for (int i = 0; i < plaintext.length(); i++)
  {
    start_index = alphabet.find(to_upper(plaintext[i]));
    advance_by = alphabet.find(keyphrase[i]);
    ciphertext += alphabet[(start_index + advance_by) % alphabet.length()];
  }

  return ciphertext;
}

string decrypt(const string& plaintext, const string& keyword)
{
  return "XXXX: Write me!";
}
<|endoftext|>