<commit_before>#include <UnitsGroup.h>
#include <Position.h>
#include <algorithm>
#include <util.h>
#include <cmath>
#include <assert.h>
using namespace BWAPI;

UnitsGroup::UnitsGroup()
:lastGoal(boost::shared_ptr<Goal>())
{
}

UnitsGroup::~UnitsGroup()
{
}

bool comp_i_dist(const i_dist& l, const i_dist& r) { return (r.dist < l.dist); }

void simple_align(std::vector<Position>& from, std::vector<unsigned int>& alignment)
{
	for(unsigned int i = 0; i < from.size(); i++)
	{
		alignment.push_back(i);
	}
}

/***
dumb O(#units^3) keeping the relative positions w.r.t. the centers
from and to are required to be of the same size()
*/
void mid_based_align(const std::vector<Position>& from, const std::vector<Position>& to, std::vector<unsigned int>& alignment)
{
	assert(to.size() == from.size());
	Position from_center;
	Position to_center;
	for (unsigned int i = 0; i < to.size(); ++i)
	{
		from_center += from[i];
		to_center += to[i];
	}
	from_center.x() /= from.size();
	from_center.y() /= from.size();
	to_center.x() /= to.size();
	to_center.y() /= to.size();
	std::vector<Vec> v_from_center(from.size(), Vec(0, 0));
	std::vector<Vec> v_to_center(to.size(), Vec(0, 0));
	for (unsigned int i = 0; i < to.size(); ++i)
	{
		v_from_center[i] = Vec(from[i] - from_center);
		v_to_center[i] = Vec(to[i] - to_center);
	}

	std::set<unsigned int> done_j;
	if (to.size() < 40) // magic number
	{
		for (unsigned int i = 0; i < to.size(); ++i)
			alignment.push_back(i);
		std::set<unsigned int> done_i;
		while (done_j.size() < to.size())
		{
			double max = -1000000000000000.0; // bad
			unsigned int max_i, max_j;
			for (unsigned int i = 0; i < v_from_center.size(); ++i)
			{
				for (unsigned int j = 0; j < v_to_center.size(); ++j)
				{
					if ((done_i.find(i) == done_i.end()) && (done_j.find(j) == done_j.end())
						&& fabs(v_from_center[i].dot(v_to_center[j])) > max)
					{
						max = v_from_center[i].dot(v_to_center[j]);
						max_i = i;
						max_j = j;
					}
				}
			}
			alignment[max_i] = max_j;
			done_i.insert(max_i);
			done_j.insert(max_j);
		}
	} else
	{
		// non optimal, should have one more loop
		for (unsigned int i = 0; i < v_from_center.size(); ++i)
		{
			double max = -1000000000000000.0; // bad
			unsigned int max_j;
			for (unsigned int j = 0; j < v_to_center.size(); ++j)
			{
				if ((done_j.find(j) == done_j.end()) && fabs(v_from_center[i].dot(v_to_center[j])) > max)
				{
					max = v_from_center[i].dot(v_to_center[j]);
					max_j = j;
				}
			}
			alignment.push_back(max_j);
			done_j.insert(max_j);
		}
	}
}

/***
/!\ dumb O(#units^2) trying (w/o collisions) to minimize the ending time
*/
void align(std::vector<Position>& from, std::vector<Position>& to, std::vector<unsigned int>& alignment)
{
	std::vector<std::vector<i_dist> > distances;
	std::vector<std::set<unsigned int> > attempts;
	std::set<unsigned int> inner_set;
	for(unsigned int i = 0; i < to.size(); i++) inner_set.insert(i);
	for(std::vector<BWAPI::Position>::iterator f = from.begin();
		f != from.end(); f++)
	{
		std::vector<i_dist> temp;
		for(unsigned int ind_to = 0; ind_to < to.size(); ind_to++)
		{
			temp.push_back(i_dist(ind_to, (*f).getDistance(to[ind_to])));
		}
		//temp.sort();
		sort(temp.begin(), temp.end(), comp_i_dist); // [0]: further, [size()-1]: closer

		distances.push_back(temp);
		attempts.push_back(inner_set);
	}
	for(unsigned int i = 0; i < distances.size(); i++)
	{
		for(unsigned int j = 0; j < distances[0].size(); j++)
		{
			// TODO
		}
	}
}

void UnitsGroup::update()
{
	this->totalHP = 0;
	for(std::vector<pBayesianUnit>::iterator it = this->units.begin();
		it != this->units.end(); ++it)
	{
		(*it)->update();
		this->totalHP += (*it)->unit->getHitPoints();
		this->totalPower += (*it)->unit->getType().groundWeapon().damageAmount();
    }

	updateCenter();

	keepDistance(); // Temporary call to test micro tech

	if (!goals.empty())
	{
		if (goals.front()->status == GS_ACHIEVED)
		{
			if (goals.size() == 1) lastGoal = goals.front();
			goals.pop_front();
			if (!goals.empty()) goals.front()->achieve(this);
		}
		else
		{
			goals.front()->checkAchievement(this);
		}

        //debug_goals(goals);
	}
}

void UnitsGroup::attackMove(int x, int y)
{
	attackMove(Position(x, y));
}

void UnitsGroup::attackMove(BWAPI::Position& p)
{
	for(std::vector<pBayesianUnit>::iterator it = this->units.begin(); it != this->units.end(); it++)
	{
		(*it)->target = p;
		(*it)->attackMove(p); // TODO, for the moment, each unit keeps a path, needs to be 1 unit per UnitsGroup + flocking
	}
}

void UnitsGroup::formation(pFormation f)
{
	std::vector<BWAPI::Position> from;
	std::vector<pBayesianUnit> units;
	for(std::vector<pBayesianUnit>::iterator it = this->units.begin(); it != this->units.end(); it++)
	{
		from.push_back((*it)->unit->getPosition());
	}

	f->computeToPositions(this->units);

	const std::vector<BWAPI::Position>& to = f->end_positions;

	std::vector<unsigned int> alignment; // alignment[from_pos] = to_pos
	// align(from, to, alignment);// TODO min crossing || fastest
	// simple_align(from, alignment);
	mid_based_align(from, to, alignment);
	for(unsigned int i = 0; i < this->units.size(); i++)
	{
		(this->units)[i]->target = to[alignment[i]];
		//(this->units)[i]->attackMove(to[alignment[i]]);
	}

}

void UnitsGroup::setGoals(std::list<pGoal>& goals)
{
	this->goals = goals;
	if (lastGoal == boost::shared_ptr<Goal>()) lastGoal = goals.front();
	this->goals.front()->achieve(this);
}

void UnitsGroup::addGoal(pGoal goal)
{
	this->goals.push_back(goal);
	if (lastGoal == boost::shared_ptr<Goal>()) lastGoal = goal;
	if (goals.size() == 1 && !this->units.empty())
		this->goals.front()->achieve(this);
}

const pGoal UnitsGroup::getLastGoal() const
{
	return lastGoal;
}

void UnitsGroup::onUnitDestroy(Unit* u)
{
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
    {
        if ((*it)->unit == u)
            units.erase(it);
        (*it)->onUnitDestroy(u);
    }
}

void UnitsGroup::onUnitShow(Unit* u)
{
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
        (*it)->onUnitShow(u);
}

void UnitsGroup::onUnitHide(Unit* u)
{
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
        (*it)->onUnitHide(u);
}

void UnitsGroup::takeControl(Unit* u)
{
    pBayesianUnit tmp(new BayesianUnit(u, &units));
	this->units.push_back(tmp);
	if (this->goals.empty()) goals.push_back(lastGoal);
    if (this->goals.front() != NULL) this->goals.front()->achieve(this);
}

void UnitsGroup::giveUpControl(Unit* u)
{
	for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
		if ((*it)->unit == u)
		{
			units.erase(it);
			break;
		}
}

void UnitsGroup::keepDistance()
{
	if (units.empty()) return;

	// List all enemy units in a range < 500
	std::set<Unit*>& allUnits = Broodwar->getAllUnits();
	std::set<Unit*> enemies;
	for (std::set< Unit* >::const_iterator itAllUnits = allUnits.begin(); itAllUnits != allUnits.end(); itAllUnits++)
	{
		Unit* u = *itAllUnits;
		if( u->getType().isBuilding() || u->getType().isWorker()) continue;
		if (u->getPlayer()->isEnemy(Broodwar->self()) && u->getPosition().getDistance(center) < 500)
		{
			enemies.insert( u);
			Broodwar->drawTextMap( u->getPosition().x(), u->getPosition().y(), "KD");
		}
	}

	// keep distance
	for (std::vector<pBayesianUnit>::iterator itUnit = units.begin(); itUnit != units.end(); itUnit++)
	{
		Unit* unit = (*itUnit)->unit;
		if ((*itUnit)->timeIdle >= 0) (*itUnit)->timeIdle++;
		if ((*itUnit)->timeIdle > 75)
		{
			(*itUnit)->timeIdle = -1;
			if (!goals.empty()) (*itUnit)->attackMove(goals.front()->formation->center.toPosition());
		}

		if (enemies.empty()) continue;

		// Get the closest unit
		Unit* closestUnit = *enemies.begin();
		for (std::set<Unit*>::iterator itEnemies = enemies.begin(); itEnemies != enemies.end(); itEnemies++)
		{
			if (closestUnit->getPosition().getDistance(unit->getPosition()) >
				(*itEnemies)->getPosition().getDistance(unit->getPosition()))
				closestUnit = (*itEnemies);
		}

		int attackRange = unit->getType().groundWeapon().maxRange();
		if (closestUnit->getType().groundWeapon().maxRange() < attackRange &&
			closestUnit->getDistance(unit) < closestUnit->getType().groundWeapon().maxRange())
		{
			(unit)->rightClick( Broodwar->self()->getStartLocation());
			(*itUnit)->timeIdle = 0;
		}
	}
}

bool UnitsGroup::empty()
{
	return units.empty();
}

unsigned int UnitsGroup::getNbUnits() const
{
	return units.size();
}

const BayesianUnit& UnitsGroup::operator[](int i)
{
	return *(units[i]);
}

void UnitsGroup::display()
{
	Broodwar->drawCircle(CoordinateType::Map, center.x(), center.y(), 8, Colors::Green);
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); it++)
	{
		Unit* unit = (*it)->unit;
		Position target = (*it)->target;

		// Attack range
		Broodwar->drawCircle( CoordinateType::Map, unit->getPosition().x(), unit->getPosition().y(), unit->getType().groundWeapon()->maxRange(), Colors::Red);

		// Target
		if( true)//unit->getPosition().getDistance( target) < 200)
		{
			Broodwar->drawCircle( CoordinateType::Map, unit->getPosition().x(), unit->getPosition().y(), 5, Colors::Cyan, true);
			Broodwar->drawLine( CoordinateType::Map, unit->getPosition().x(), unit->getPosition().y(), target.x(), target.y(), Colors::Cyan);
			Broodwar->drawCircle( CoordinateType::Map, target.x(), target.y(), 5, Colors::Cyan, true);
		}

		// Goal status
		if( goals.empty() || goals.front()->status == GS_ACHIEVED)
			Broodwar->drawTextMap( unit->getPosition().x(), unit->getPosition().y(), "W");
		if( !goals.empty() && goals.front()->status == GS_IN_PROGRESS)
			Broodwar->drawTextMap( unit->getPosition().x(), unit->getPosition().y(), "P");
	}

	for (std::list<pGoal>::iterator it = goals.begin(); it != goals.end(); it++)
	{
		Broodwar->drawCircle( CoordinateType::Map, (int)((*it)->formation->center.x), (int)((*it)->formation->center.y), 5, Colors::White, true);
	}
}

void UnitsGroup::updateCenter()
{
	center = Position(0, 0);
	for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
	{
		center += (*it)->unit->getPosition();
	}
	if( units.size() != 0)
	{
		center.x() /= units.size();
		center.y() /= units.size();
	}
}

Position UnitsGroup::getCenter() const
{
	return center;
}

#ifdef _UNITS_DEBUG
void UnitsGroup::selectedUnits(std::set<pBayesianUnit>& u)
{
    for (std::vector<pBayesianUnit>::iterator i=this->units.begin(); i!=this->units.end(); ++i)
    {
        if ((*i)->unit->isSelected())
            u.insert(*i);
    }
}
#endif<commit_msg>minor updates2<commit_after>#include <UnitsGroup.h>
#include <Position.h>
#include <algorithm>
#include <util.h>
#include <cmath>
#include <assert.h>
using namespace BWAPI;

UnitsGroup::UnitsGroup()
:lastGoal(boost::shared_ptr<Goal>())
{
}

UnitsGroup::~UnitsGroup()
{
}

bool comp_i_dist(const i_dist& l, const i_dist& r) { return (r.dist < l.dist); }

void simple_align(std::vector<Position>& from, std::vector<unsigned int>& alignment)
{
	for(unsigned int i = 0; i < from.size(); i++)
	{
		alignment.push_back(i);
	}
}

/***
dumb O(#units^3) keeping the relative positions w.r.t. the centers
from and to are required to be of the same size()
*/
void mid_based_align(const std::vector<Position>& from, const std::vector<Position>& to, std::vector<unsigned int>& alignment)
{
	assert(to.size() == from.size());
	Position from_center;
	Position to_center;
	for (unsigned int i = 0; i < to.size(); ++i)
	{
		from_center += from[i];
		to_center += to[i];
	}
	from_center.x() /= from.size();
	from_center.y() /= from.size();
	to_center.x() /= to.size();
	to_center.y() /= to.size();
	std::vector<Vec> v_from_center(from.size(), Vec(0, 0));
	std::vector<Vec> v_to_center(to.size(), Vec(0, 0));
	for (unsigned int i = 0; i < to.size(); ++i)
	{
		v_from_center[i] = Vec(from[i] - from_center);
		v_to_center[i] = Vec(to[i] - to_center);
	}

	std::set<unsigned int> done_j;
	if (to.size() < 40) // magic number
	{
		for (unsigned int i = 0; i < to.size(); ++i)
			alignment.push_back(i);
		std::set<unsigned int> done_i;
		while (done_j.size() < to.size())
		{
			double max = -1000000000000000.0; // bad
			unsigned int max_i, max_j;
			for (unsigned int i = 0; i < v_from_center.size(); ++i)
			{
				for (unsigned int j = 0; j < v_to_center.size(); ++j)
				{
					if ((done_i.find(i) == done_i.end()) && (done_j.find(j) == done_j.end())
						&& fabs(v_from_center[i].dot(v_to_center[j])) > max)
					{
						max = v_from_center[i].dot(v_to_center[j]);
						max_i = i;
						max_j = j;
					}
				}
			}
			alignment[max_i] = max_j;
			done_i.insert(max_i);
			done_j.insert(max_j);
		}
	} else
	{
		// non optimal, should have one more loop
		for (unsigned int i = 0; i < v_from_center.size(); ++i)
		{
			double max = -1000000000000000.0; // bad
			unsigned int max_j;
			for (unsigned int j = 0; j < v_to_center.size(); ++j)
			{
				if ((done_j.find(j) == done_j.end()) && fabs(v_from_center[i].dot(v_to_center[j])) > max)
				{
					max = v_from_center[i].dot(v_to_center[j]);
					max_j = j;
				}
			}
			alignment.push_back(max_j);
			done_j.insert(max_j);
		}
	}
}

/***
/!\ dumb O(#units^2) trying (w/o collisions) to minimize the ending time
*/
void align(std::vector<Position>& from, std::vector<Position>& to, std::vector<unsigned int>& alignment)
{
	std::vector<std::vector<i_dist> > distances;
	std::vector<std::set<unsigned int> > attempts;
	std::set<unsigned int> inner_set;
	for(unsigned int i = 0; i < to.size(); i++) inner_set.insert(i);
	for(std::vector<BWAPI::Position>::iterator f = from.begin();
		f != from.end(); f++)
	{
		std::vector<i_dist> temp;
		for(unsigned int ind_to = 0; ind_to < to.size(); ind_to++)
		{
			temp.push_back(i_dist(ind_to, (*f).getDistance(to[ind_to])));
		}
		//temp.sort();
		sort(temp.begin(), temp.end(), comp_i_dist); // [0]: further, [size()-1]: closer

		distances.push_back(temp);
		attempts.push_back(inner_set);
	}
	for(unsigned int i = 0; i < distances.size(); i++)
	{
		for(unsigned int j = 0; j < distances[0].size(); j++)
		{
			// TODO
		}
	}
}

void UnitsGroup::update()
{
	this->totalHP = 0;
	for(std::vector<pBayesianUnit>::iterator it = this->units.begin();
		it != this->units.end(); ++it)
	{
		(*it)->update();
		this->totalHP += (*it)->unit->getHitPoints();
		this->totalPower += (*it)->unit->getType().groundWeapon().damageAmount();
    }

	updateCenter();

	keepDistance(); // Temporary call to test micro tech

	if (!goals.empty())
	{
		if (goals.front()->status == GS_ACHIEVED)
		{
			if (goals.size() == 1) lastGoal = goals.front();
			goals.pop_front();
			if (!goals.empty()) goals.front()->achieve(this);
		}
		else
		{
			goals.front()->checkAchievement(this);
		}

        //debug_goals(goals);
	}
}

void UnitsGroup::attackMove(int x, int y)
{
	attackMove(Position(x, y));
}

void UnitsGroup::attackMove(BWAPI::Position& p)
{
	for(std::vector<pBayesianUnit>::iterator it = this->units.begin(); it != this->units.end(); it++)
	{
		(*it)->target = p;
		(*it)->attackMove(p); // TODO, for the moment, each unit keeps a path, needs to be 1 unit per UnitsGroup + flocking
	}
}

void UnitsGroup::formation(pFormation f)
{
	std::vector<BWAPI::Position> from;
	std::vector<pBayesianUnit> units;
	for(std::vector<pBayesianUnit>::iterator it = this->units.begin(); it != this->units.end(); it++)
	{
		from.push_back((*it)->unit->getPosition());
	}

	f->computeToPositions(this->units);

	const std::vector<BWAPI::Position>& to = f->end_positions;

	std::vector<unsigned int> alignment; // alignment[from_pos] = to_pos
	// align(from, to, alignment);// TODO min crossing || fastest
	// simple_align(from, alignment);
	mid_based_align(from, to, alignment);
	for(unsigned int i = 0; i < this->units.size(); i++)
	{
		(this->units)[i]->target = to[alignment[i]];
		//(this->units)[i]->attackMove(to[alignment[i]]);
	}

}

void UnitsGroup::setGoals(std::list<pGoal>& goals)
{
	this->goals = goals;
	if (lastGoal == boost::shared_ptr<Goal>()) lastGoal = goals.front();
	this->goals.front()->achieve(this);
}

void UnitsGroup::addGoal(pGoal goal)
{
	this->goals.push_back(goal);
	if (lastGoal == boost::shared_ptr<Goal>()) lastGoal = goal;
	if (goals.size() == 1 && !this->units.empty())
		this->goals.front()->achieve(this);
}

const pGoal UnitsGroup::getLastGoal() const
{
	return lastGoal;
}

void UnitsGroup::onUnitDestroy(Unit* u)
{
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
    {
        if ((*it)->unit == u)
            units.erase(it);
        (*it)->onUnitDestroy(u);
    }
}

void UnitsGroup::onUnitShow(Unit* u)
{
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
        (*it)->onUnitShow(u);
}

void UnitsGroup::onUnitHide(Unit* u)
{
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
        (*it)->onUnitHide(u);
}

void UnitsGroup::takeControl(Unit* u)
{
    pBayesianUnit tmp(new BayesianUnit(u, &units));
	this->units.push_back(tmp);
	if (this->goals.empty()) goals.push_back(lastGoal);
    if (this->goals.front() != NULL) this->goals.front()->achieve(this);
}

void UnitsGroup::giveUpControl(Unit* u)
{
	for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
		if ((*it)->unit == u)
		{
			units.erase(it);
			break;
		}
}

void UnitsGroup::keepDistance()
{
	if (units.empty()) return;

	// List all enemy units in a range < 500
	std::set<Unit*>& allUnits = Broodwar->getAllUnits();
	std::set<Unit*> enemies;
	for (std::set< Unit* >::const_iterator itAllUnits = allUnits.begin(); itAllUnits != allUnits.end(); itAllUnits++)
	{
		Unit* u = *itAllUnits;
		if( u->getType().isBuilding() || u->getType().isWorker()) continue;
		if (u->getPlayer()->isEnemy(Broodwar->self()) && u->getPosition().getDistance(center) < 500)
		{
			enemies.insert( u);
			Broodwar->drawTextMap( u->getPosition().x(), u->getPosition().y(), "KD");
		}
	}

	// keep distance
	for (std::vector<pBayesianUnit>::iterator itUnit = units.begin(); itUnit != units.end(); itUnit++)
	{
		Unit* unit = (*itUnit)->unit;
		if ((*itUnit)->timeIdle >= 0) (*itUnit)->timeIdle++;
		if ((*itUnit)->timeIdle > 75)
		{
			(*itUnit)->timeIdle = -1;
			if (!goals.empty()) (*itUnit)->attackMove(goals.front()->formation->center.toPosition());
		}

		if (enemies.empty()) continue;

		// Get the closest unit
		Unit* closestUnit = *enemies.begin();
		for (std::set<Unit*>::iterator itEnemies = enemies.begin(); itEnemies != enemies.end(); itEnemies++)
		{
			if (closestUnit->getPosition().getDistance(unit->getPosition()) >
				(*itEnemies)->getPosition().getDistance(unit->getPosition()))
				closestUnit = (*itEnemies);
		}

		int attackRange = unit->getType().groundWeapon().maxRange();
		if (closestUnit->getType().groundWeapon().maxRange() < attackRange &&
			closestUnit->getDistance(unit) < closestUnit->getType().groundWeapon().maxRange())
		{
			(unit)->rightClick( Broodwar->self()->getStartLocation());
			(*itUnit)->timeIdle = 0;
		}
	}
}

bool UnitsGroup::empty()
{
	return units.empty();
}

unsigned int UnitsGroup::getNbUnits() const
{
	return units.size();
}

const BayesianUnit& UnitsGroup::operator[](int i)
{
	return *(units[i]);
}

void UnitsGroup::display()
{
	Broodwar->drawCircle(CoordinateType::Map, center.x(), center.y(), 8, Colors::Green);
    for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); it++)
	{
		Unit* unit = (*it)->unit;
		Position target = (*it)->target;

		// Attack range
		//Broodwar->drawCircle( CoordinateType::Map, unit->getPosition().x(), unit->getPosition().y(), unit->getType().groundWeapon()->maxRange(), Colors::Red);

		// Target
		if( true)//unit->getPosition().getDistance( target) < 200)
		{
			Broodwar->drawCircle( CoordinateType::Map, unit->getPosition().x(), unit->getPosition().y(), 5, Colors::Cyan, true);
			Broodwar->drawLine( CoordinateType::Map, unit->getPosition().x(), unit->getPosition().y(), target.x(), target.y(), Colors::Cyan);
			Broodwar->drawCircle( CoordinateType::Map, target.x(), target.y(), 5, Colors::Cyan, true);
		}

		// Goal status
		if( goals.empty() || goals.front()->status == GS_ACHIEVED)
			Broodwar->drawTextMap( unit->getPosition().x(), unit->getPosition().y(), "W");
		if( !goals.empty() && goals.front()->status == GS_IN_PROGRESS)
			Broodwar->drawTextMap( unit->getPosition().x(), unit->getPosition().y(), "P");
	}

	for (std::list<pGoal>::iterator it = goals.begin(); it != goals.end(); it++)
	{
		Broodwar->drawCircle( CoordinateType::Map, (int)((*it)->formation->center.x), (int)((*it)->formation->center.y), 5, Colors::White, true);
	}
}

void UnitsGroup::updateCenter()
{
	center = Position(0, 0);
	for (std::vector<pBayesianUnit>::const_iterator it = units.begin(); it != units.end(); ++it)
	{
		center += (*it)->unit->getPosition();
	}
	if( units.size() != 0)
	{
		center.x() /= units.size();
		center.y() /= units.size();
	}
}

Position UnitsGroup::getCenter() const
{
	return center;
}

#ifdef _UNITS_DEBUG
void UnitsGroup::selectedUnits(std::set<pBayesianUnit>& u)
{
    for (std::vector<pBayesianUnit>::iterator i=this->units.begin(); i!=this->units.end(); ++i)
    {
        if ((*i)->unit->isSelected())
            u.insert(*i);
    }
}
#endif<|endoftext|>


<commit_before>/*
 * Copyright 2010-2012 Esrille Inc.
 *
 * 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 "FontDatabase.h"
#include "FontManager.h"

namespace {

const char* fontList[] =
{
    // LiberationSans
    LIBERATON_TTF "/LiberationSans-BoldItalic.ttf",
    LIBERATON_TTF "/LiberationSans-Italic.ttf",
    LIBERATON_TTF "/LiberationSans-Regular.ttf",
    LIBERATON_TTF "/LiberationSans-Bold.ttf",
    // LiberationSerif
    LIBERATON_TTF "/LiberationSerif-BoldItalic.ttf",
    LIBERATON_TTF "/LiberationSerif-Italic.ttf",
    LIBERATON_TTF "/LiberationSerif-Regular.ttf",
    LIBERATON_TTF "/LiberationSerif-Bold.ttf",
    // LiberationMono
    LIBERATON_TTF "/LiberationMono-BoldItalic.ttf",
    LIBERATON_TTF "/LiberationMono-Italic.ttf",
    LIBERATON_TTF "/LiberationMono-Regular.ttf",
    LIBERATON_TTF "/LiberationMono-Bold.ttf",
#ifdef HAVE_IPA_PGOTHIC
    // IPAPGothic
    HAVE_IPA_PGOTHIC,
#endif
#ifdef HAVE_IPA_PMINCHO
    // IPAPMincho
    HAVE_IPA_PMINCHO,
#endif
#ifdef HAVE_IPA_GOTHIC
    // IPAGothic
    HAVE_IPA_GOTHIC,
#endif
#ifdef HAVE_IPA_MINCHO
    // IPAMincho
    HAVE_IPA_MINCHO,
#endif
#ifdef DEJAVU_TTF
    DEJAVU_TTF "/DejaVuSans-Bold.ttf",
    DEJAVU_TTF "/DejaVuSans-BoldOblique.ttf",
    DEJAVU_TTF "/DejaVuSans-ExtraLight.ttf",
    DEJAVU_TTF "/DejaVuSans-Oblique.ttf",
    DEJAVU_TTF "/DejaVuSans.ttf",
    DEJAVU_TTF "/DejaVuSansMono-Bold.ttf",
    DEJAVU_TTF "/DejaVuSansMono-BoldOblique.ttf",
    DEJAVU_TTF "/DejaVuSansMono-Oblique.ttf",
    DEJAVU_TTF "/DejaVuSansMono.ttf",
    DEJAVU_TTF "/DejaVuSerif-Bold.ttf",
    DEJAVU_TTF "/DejaVuSerif-BoldItalic.ttf",
    DEJAVU_TTF "/DejaVuSerif-Italic.ttf",
    DEJAVU_TTF "/DejaVuSerif.ttf",
#endif
#ifdef HAVE_AEGEAN
    // Aegean
    HAVE_AEGEAN,
#endif
#ifdef HAVE_AHEM
    // Ahem
    HAVE_AHEM,
#endif
};

// Test fonts for CSS 2.1 test suite
const char* testFontList[] =
{
    // Ahem!
    TEST_FONTS "/AhemExtra/AHEM_Ahem!.TTF",
    // MissingNormal
    TEST_FONTS "/AhemExtra/AHEM_MissingNormal.TTF",
    // SmallCaps
    TEST_FONTS "/AhemExtra/AHEM_SmallCaps.TTF",
    // MissingItalicOblique
    TEST_FONTS "/AhemExtra/AHEM_MissingItalicOblique.TTF",
    // White Space
    TEST_FONTS "/AhemExtra/AHEM_WhiteSpace.TTF",
    // cursive
    TEST_FONTS "/AhemExtra/AHEM_cursive.TTF",
    // default
    TEST_FONTS "/AhemExtra/AHEM_default.TTF",
    // fantasy
    TEST_FONTS "/AhemExtra/AHEM_fantasy.TTF",
    // inherit
    TEST_FONTS "/AhemExtra/AHEM_inherit.TTF",
    // initial
    TEST_FONTS "/AhemExtra/AHEM_initial.TTF",
    // monospace
    TEST_FONTS "/AhemExtra/AHEM_monospace.TTF",
    // serif
    TEST_FONTS "/AhemExtra/AHEM_serif.TTF",
    // sans-serif
    TEST_FONTS "/AhemExtra/AHEM_sans-serif.TTF",
    // CSSTest ASCII
    TEST_FONTS "/CSSTest/csstest-ascii.ttf",
    // CSSTest Basic
    TEST_FONTS "/CSSTest/csstest-basic-bold.ttf",
    TEST_FONTS "/CSSTest/csstest-basic-bolditalic.ttf",
    TEST_FONTS "/CSSTest/csstest-basic-italic.ttf",
    TEST_FONTS "/CSSTest/csstest-basic-regular.ttf",
    // CSSTest Fallback
    TEST_FONTS "/CSSTest/csstest-fallback.ttf",
    // small-caps 1in CSSTest FamilyName Funky
    TEST_FONTS "/CSSTest/csstest-familyname-funkyA.ttf",
    // x-large CSSTest FamilyName Funky
    TEST_FONTS "/CSSTest/csstest-familyname-funkyB.ttf",
    // 12px CSSTest FamilyName Funky
    TEST_FONTS "/CSSTest/csstest-familyname-funkyC.ttf",
    // CSSTest FamilyName
    TEST_FONTS "/CSSTest/csstest-familyname.ttf",
    TEST_FONTS "/CSSTest/csstest-familyname-bold.ttf",
    // CSSTest Verify
    TEST_FONTS "/CSSTest/csstest-verify.ttf",
    // CSSTest Weights
    TEST_FONTS "/CSSTest/csstest-weights-100.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w1.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w7.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-15-w1.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-15-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-200.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-24-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-24-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w6.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-258-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-258-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-258-w8.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-300.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w3.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w8.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-400.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-47-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-47-w7.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-500.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-600.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-700.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-800.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-900.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w1.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w3.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w6.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w7.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w8.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights.ttf",
};

}

void FontDatabase::loadBaseFonts(FontManager* manager)
{
    for (auto i = fontList; i < &fontList[sizeof fontList / sizeof fontList[0]]; ++i)
        manager->loadFont(*i);
}

void FontDatabase::loadTestFonts(FontManager* manager)
{
    for (auto i = testFontList; i < &testFontList[sizeof testFontList / sizeof testFontList[0]]; ++i)
        manager->loadFont(*i);
}
<commit_msg>(FontDatabase::loadBaseFonts) : Do not throw even if a font face is not found.<commit_after>/*
 * Copyright 2010-2012 Esrille Inc.
 *
 * 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 "FontDatabase.h"
#include "FontManager.h"

namespace {

const char* fontList[] =
{
    // LiberationSans
    LIBERATON_TTF "/LiberationSans-BoldItalic.ttf",
    LIBERATON_TTF "/LiberationSans-Italic.ttf",
    LIBERATON_TTF "/LiberationSans-Regular.ttf",
    LIBERATON_TTF "/LiberationSans-Bold.ttf",
    // LiberationSerif
    LIBERATON_TTF "/LiberationSerif-BoldItalic.ttf",
    LIBERATON_TTF "/LiberationSerif-Italic.ttf",
    LIBERATON_TTF "/LiberationSerif-Regular.ttf",
    LIBERATON_TTF "/LiberationSerif-Bold.ttf",
    // LiberationMono
    LIBERATON_TTF "/LiberationMono-BoldItalic.ttf",
    LIBERATON_TTF "/LiberationMono-Italic.ttf",
    LIBERATON_TTF "/LiberationMono-Regular.ttf",
    LIBERATON_TTF "/LiberationMono-Bold.ttf",
#ifdef HAVE_IPA_PGOTHIC
    // IPAPGothic
    HAVE_IPA_PGOTHIC,
#endif
#ifdef HAVE_IPA_PMINCHO
    // IPAPMincho
    HAVE_IPA_PMINCHO,
#endif
#ifdef HAVE_IPA_GOTHIC
    // IPAGothic
    HAVE_IPA_GOTHIC,
#endif
#ifdef HAVE_IPA_MINCHO
    // IPAMincho
    HAVE_IPA_MINCHO,
#endif
#ifdef DEJAVU_TTF
    DEJAVU_TTF "/DejaVuSans-Bold.ttf",
    DEJAVU_TTF "/DejaVuSans-BoldOblique.ttf",
    DEJAVU_TTF "/DejaVuSans-ExtraLight.ttf",
    DEJAVU_TTF "/DejaVuSans-Oblique.ttf",
    DEJAVU_TTF "/DejaVuSans.ttf",
    DEJAVU_TTF "/DejaVuSansMono-Bold.ttf",
    DEJAVU_TTF "/DejaVuSansMono-BoldOblique.ttf",
    DEJAVU_TTF "/DejaVuSansMono-Oblique.ttf",
    DEJAVU_TTF "/DejaVuSansMono.ttf",
    DEJAVU_TTF "/DejaVuSerif-Bold.ttf",
    DEJAVU_TTF "/DejaVuSerif-BoldItalic.ttf",
    DEJAVU_TTF "/DejaVuSerif-Italic.ttf",
    DEJAVU_TTF "/DejaVuSerif.ttf",
#endif
#ifdef HAVE_AEGEAN
    // Aegean
    HAVE_AEGEAN,
#endif
#ifdef HAVE_AHEM
    // Ahem
    HAVE_AHEM,
#endif
};

// Test fonts for CSS 2.1 test suite
const char* testFontList[] =
{
    // Ahem!
    TEST_FONTS "/AhemExtra/AHEM_Ahem!.TTF",
    // MissingNormal
    TEST_FONTS "/AhemExtra/AHEM_MissingNormal.TTF",
    // SmallCaps
    TEST_FONTS "/AhemExtra/AHEM_SmallCaps.TTF",
    // MissingItalicOblique
    TEST_FONTS "/AhemExtra/AHEM_MissingItalicOblique.TTF",
    // White Space
    TEST_FONTS "/AhemExtra/AHEM_WhiteSpace.TTF",
    // cursive
    TEST_FONTS "/AhemExtra/AHEM_cursive.TTF",
    // default
    TEST_FONTS "/AhemExtra/AHEM_default.TTF",
    // fantasy
    TEST_FONTS "/AhemExtra/AHEM_fantasy.TTF",
    // inherit
    TEST_FONTS "/AhemExtra/AHEM_inherit.TTF",
    // initial
    TEST_FONTS "/AhemExtra/AHEM_initial.TTF",
    // monospace
    TEST_FONTS "/AhemExtra/AHEM_monospace.TTF",
    // serif
    TEST_FONTS "/AhemExtra/AHEM_serif.TTF",
    // sans-serif
    TEST_FONTS "/AhemExtra/AHEM_sans-serif.TTF",
    // CSSTest ASCII
    TEST_FONTS "/CSSTest/csstest-ascii.ttf",
    // CSSTest Basic
    TEST_FONTS "/CSSTest/csstest-basic-bold.ttf",
    TEST_FONTS "/CSSTest/csstest-basic-bolditalic.ttf",
    TEST_FONTS "/CSSTest/csstest-basic-italic.ttf",
    TEST_FONTS "/CSSTest/csstest-basic-regular.ttf",
    // CSSTest Fallback
    TEST_FONTS "/CSSTest/csstest-fallback.ttf",
    // small-caps 1in CSSTest FamilyName Funky
    TEST_FONTS "/CSSTest/csstest-familyname-funkyA.ttf",
    // x-large CSSTest FamilyName Funky
    TEST_FONTS "/CSSTest/csstest-familyname-funkyB.ttf",
    // 12px CSSTest FamilyName Funky
    TEST_FONTS "/CSSTest/csstest-familyname-funkyC.ttf",
    // CSSTest FamilyName
    TEST_FONTS "/CSSTest/csstest-familyname.ttf",
    TEST_FONTS "/CSSTest/csstest-familyname-bold.ttf",
    // CSSTest Verify
    TEST_FONTS "/CSSTest/csstest-verify.ttf",
    // CSSTest Weights
    TEST_FONTS "/CSSTest/csstest-weights-100.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w1.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w7.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-1479-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-15-w1.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-15-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-200.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-24-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-24-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w6.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-2569-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-258-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-258-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-258-w8.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-300.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w3.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w8.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-3589-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-400.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-47-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-47-w7.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-500.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-600.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-700.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-800.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-900.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w1.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w2.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w3.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w4.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w5.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w6.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w7.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w8.ttf",
    TEST_FONTS "/CSSTest/csstest-weights-full-w9.ttf",
    TEST_FONTS "/CSSTest/csstest-weights.ttf",
};

}

void FontDatabase::loadBaseFonts(FontManager* manager)
{
    for (auto i = fontList; i < &fontList[sizeof fontList / sizeof fontList[0]]; ++i) {
        try {
            manager->loadFont(*i);
        } catch (...) {
        }
    }
}

void FontDatabase::loadTestFonts(FontManager* manager)
{
    for (auto i = testFontList; i < &testFontList[sizeof testFontList / sizeof testFontList[0]]; ++i) {
        try {
            manager->loadFont(*i);
        } catch (...) {
        }
    }
}
<|endoftext|>


<commit_before>/*=============================================================================

  Library: CTK

  Copyright (c) 2010 German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 <ctkPluginFrameworkFactory.h>
#include <ctkPluginFramework.h>
#include <ctkPluginException.h>

#include "ctkPluginBrowser.h"

#include <QApplication>

int main(int argv, char** argc)
{
  QApplication app(argv, argc);

  ctkPluginFrameworkFactory fwFactory;
  ctkPluginFramework* framework = fwFactory.getFramework();

  try {
    framework->init();
  }
  catch (const ctkPluginException& exc)
  {
    qCritical() << "Failed to initialize the plug-in framework:" << exc;
    exit(1);
  }

  ctkPluginBrowser browser(framework);
  browser.show();

  return app.exec();

}
<commit_msg>ENH: PluginBrowser: Set application info<commit_after>/*=============================================================================

  Library: CTK

  Copyright (c) 2010 German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 <ctkPluginFrameworkFactory.h>
#include <ctkPluginFramework.h>
#include <ctkPluginException.h>

#include "ctkPluginBrowser.h"

#include <QApplication>

int main(int argv, char** argc)
{
  QApplication app(argv, argc);

  app.setOrganizationName("commontk");
  app.setOrganizationDomain("commontk.org");
  app.setApplicationName("ctkPluginBrowser");

  ctkPluginFrameworkFactory fwFactory;
  ctkPluginFramework* framework = fwFactory.getFramework();

  try {
    framework->init();
  }
  catch (const ctkPluginException& exc)
  {
    qCritical() << "Failed to initialize the plug-in framework:" << exc;
    exit(1);
  }

  ctkPluginBrowser browser(framework);
  browser.show();

  return app.exec();

}
<|endoftext|>


<commit_before><commit_msg>Fem3DSolutionComponentsTest.cpp: Removed debug exposed by the linux build<commit_after><|endoftext|>


<commit_before>#pragma once

#include <stdint.h>

/** @file bts/blockchain/fork_blocks.hpp
 *  @brief Defines global constants that hard forks happen
 */
#define BTS_BLOCKCHAIN_FORK_MARKET_BLOCK_NUM                  (259000)
<commit_msg>update the fork number<commit_after>#pragma once

#include <stdint.h>

/** @file bts/blockchain/fork_blocks.hpp
 *  @brief Defines global constants that hard forks happen
 */
#define BTS_BLOCKCHAIN_FORK_MARKET_BLOCK_NUM                  (276000)
<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * DataMan.cpp
 *
 *  Created on: Jun 1, 2017
 *      Author: Jason Wang wangr1@ornl.gov
 */

#include <fstream>  //TODO go away
#include <iostream> //TODO go away

#include "DataMan.h"

#include "adios2/ADIOSMacros.h"
#include "adios2/helper/adiosFunctions.h"

#ifdef ADIOS2_HAVE_ZEROMQ
#include "adios2/toolkit/transport/wan/WANZmq.h"
#endif

namespace adios2
{
namespace transportman
{

DataMan::DataMan(MPI_Comm mpiComm, const bool debugMode)
: TransportMan(mpiComm, debugMode)
{
}

DataMan::~DataMan()
{
    for (auto &readThread : m_ReadThreads)
    {
        m_Reading = false;
        readThread.join();
    }
    for (auto &writeThread : m_WriteThreads)
    {
        m_Writing = false;
        writeThread.join();
    }
}

void DataMan::SetMaxReceiveBuffer(size_t size) { m_MaxReceiveBuffer = size; }

void DataMan::OpenWANTransports(const std::vector<std::string> &streamNames,
                                const Mode mode,
                                const std::vector<Params> &paramsVector,
                                const bool profile)
{

    if (streamNames.size() == 0)
    {
        throw("No streams to open from DataMan::OpenWANTransports");
    }

    for (size_t i = 0; i < streamNames.size(); ++i)
    {

        // Get parameters

        std::string library;
        GetStringParameter(paramsVector[i], "Library", library,
                           m_DefaultLibrary);

        std::string ip;
        GetStringParameter(paramsVector[i], "IPAddress", ip);

        std::string port;
        GetStringParameter(paramsVector[i], "Port", port);

        std::string transportMode;
        GetStringParameter(paramsVector[i], "TransportMode", transportMode,
                           m_DefaultTransportMode);

        // Calculate port number
        int mpiRank, mpiSize;
        MPI_Comm_rank(m_MPIComm, &mpiRank);
        MPI_Comm_size(m_MPIComm, &mpiSize);
        if (port.empty())
        {
            port = std::to_string(stoi(port) + i * mpiSize);
        }
        port = std::to_string(stoi(port) + mpiRank);

        // Create transports
        std::shared_ptr<Transport> wanTransport;

        if (library == "zmq" || library == "ZMQ")
        {
#ifdef ADIOS2_HAVE_ZEROMQ

            wanTransport = std::make_shared<transport::WANZmq>(
                ip, port, m_MPIComm, transportMode, m_DebugMode);
            wanTransport->Open(streamNames[i], mode);
            m_Transports.emplace(i, wanTransport);

            if (mode == Mode::Read)
            {
                m_Reading = true;
                m_ReadThreads.emplace_back(
                    std::thread(&DataMan::ReadThread, this, wanTransport));
            }

            else if (mode == Mode::Write)
            {
                m_Writing = true;
                m_WriteThreads.emplace_back(
                    std::thread(&DataMan::WriteThread, this, wanTransport));
            }

#else
            throw std::invalid_argument(
                "ERROR: this version of ADIOS2 didn't compile with "
                "ZMQ library, in call to Open\n");
#endif
        }
        else
        {
            if (m_DebugMode)
            {
                throw std::invalid_argument("ERROR: wan transport " + library +
                                            " not supported or not "
                                            "provided in IO AddTransport, "
                                            "in call to Open\n");
            }
        }
    }
}

void DataMan::WriteWAN(std::shared_ptr<std::vector<char>> buffer)
{
    PushBufferQueue(buffer);
}

void DataMan::WriteWAN(const std::vector<char> &buffer)
{
    if (m_CurrentTransport >= m_Transports.size())
    {
        throw std::runtime_error(
            "ERROR: No valid transports found, from DataMan::WriteWAN()");
    }

    m_Transports[m_CurrentTransport]->Write(
        reinterpret_cast<const char *>(buffer.data()), buffer.size());
}

std::shared_ptr<std::vector<char>> DataMan::ReadWAN()
{
    return PopBufferQueue();
}

void DataMan::PushBufferQueue(std::shared_ptr<std::vector<char>> v)
{
    std::lock_guard<std::mutex> l(m_Mutex);
    m_BufferQueue.push(v);
}

std::shared_ptr<std::vector<char>> DataMan::PopBufferQueue()
{
    std::lock_guard<std::mutex> l(m_Mutex);
    if (m_BufferQueue.size() > 0)
    {
        std::shared_ptr<std::vector<char>> vec = m_BufferQueue.front();
        m_BufferQueue.pop();
        return vec;
    }
    return nullptr;
}

void DataMan::WriteThread(std::shared_ptr<Transport> transport)
{
    while (m_Writing)
    {
        std::shared_ptr<std::vector<char>> buffer = PopBufferQueue();
        if (buffer != nullptr)
        {
            if (buffer->size() > 0)
            {
                transport->Write(buffer->data(), buffer->size());
            }
        }
    }
}

void DataMan::ReadThread(std::shared_ptr<Transport> transport)
{
    std::vector<char> buffer(m_MaxReceiveBuffer);
    while (m_Reading)
    {
        Transport::Status status;
        transport->IRead(buffer.data(), m_MaxReceiveBuffer, status);
        if (status.Bytes > 0)
        {
            std::shared_ptr<std::vector<char>> bufferQ =
                std::make_shared<std::vector<char>>(status.Bytes);
            std::memcpy(bufferQ->data(), buffer.data(), status.Bytes);
            PushBufferQueue(bufferQ);
        }
    }
}

bool DataMan::GetBoolParameter(const Params &params, std::string key)
{
    auto itKey = params.find(key);
    if (itKey != params.end())
    {
        std::string value = itKey->second;
        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
        if (value == "yes" || value == "true")
        {
            return true;
        }
        else if (value == "no" || value == "false")
        {
            return false;
        }
    }
    return false;
}

bool DataMan::GetStringParameter(const Params &params, std::string key,
                                 std::string &value, std::string default_value)
{
    auto it = params.find(key);
    if (it != params.end())
    {
        value = it->second;
        return true;
    }
    value = default_value;
    return false;
}

} // end namespace transportman
} // end namespace adios2
<commit_msg>minor change<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * DataMan.cpp
 *
 *  Created on: Jun 1, 2017
 *      Author: Jason Wang wangr1@ornl.gov
 */

#include <fstream>  //TODO go away
#include <iostream> //TODO go away

#include "DataMan.h"

#include "adios2/ADIOSMacros.h"
#include "adios2/helper/adiosFunctions.h"

#ifdef ADIOS2_HAVE_ZEROMQ
#include "adios2/toolkit/transport/wan/WANZmq.h"
#endif

namespace adios2
{
namespace transportman
{

DataMan::DataMan(MPI_Comm mpiComm, const bool debugMode)
: TransportMan(mpiComm, debugMode)
{
}

DataMan::~DataMan()
{
    for (auto &readThread : m_ReadThreads)
    {
        m_Reading = false;
        readThread.join();
    }
    for (auto &writeThread : m_WriteThreads)
    {
        m_Writing = false;
        writeThread.join();
    }
}

void DataMan::SetMaxReceiveBuffer(size_t size) { m_MaxReceiveBuffer = size; }

void DataMan::OpenWANTransports(const std::vector<std::string> &streamNames,
                                const Mode mode,
                                const std::vector<Params> &paramsVector,
                                const bool profile)
{

    if (streamNames.size() == 0)
    {
        throw("No streams to open from DataMan::OpenWANTransports");
    }

    for (size_t i = 0; i < streamNames.size(); ++i)
    {

        // Get parameters

        std::string library;
        GetStringParameter(paramsVector[i], "Library", library,
                           m_DefaultLibrary);

        std::string ip;
        GetStringParameter(paramsVector[i], "IPAddress", ip);

        std::string port;
        GetStringParameter(paramsVector[i], "Port", port);

        std::string transportMode;
        GetStringParameter(paramsVector[i], "TransportMode", transportMode,
                           m_DefaultTransportMode);

        // Calculate port number
        int mpiRank, mpiSize;
        MPI_Comm_rank(m_MPIComm, &mpiRank);
        MPI_Comm_size(m_MPIComm, &mpiSize);
        if (port.empty())
        {
            port = std::to_string(stoi(port) + i * mpiSize);
        }
        port = std::to_string(stoi(port) + mpiRank);

        // Create transports
        std::shared_ptr<Transport> wanTransport;

        if (library == "zmq" || library == "ZMQ")
        {
#ifdef ADIOS2_HAVE_ZEROMQ

            wanTransport = std::make_shared<transport::WANZmq>(
                ip, port, m_MPIComm, transportMode, m_DebugMode);
            wanTransport->Open(streamNames[i], mode);
            m_Transports.emplace(i, wanTransport);

            if (mode == Mode::Read)
            {
                m_Reading = true;
                m_ReadThreads.emplace_back(
                    std::thread(&DataMan::ReadThread, this, wanTransport));
            }

            else if (mode == Mode::Write)
            {
                m_Writing = true;
                m_WriteThreads.emplace_back(
                    std::thread(&DataMan::WriteThread, this, wanTransport));
            }

#else
            throw std::invalid_argument(
                "ERROR: this version of ADIOS2 didn't compile with "
                "ZMQ library, in call to Open\n");
#endif
        }
        else
        {
            if (m_DebugMode)
            {
                throw std::invalid_argument("ERROR: wan transport " + library +
                                            " not supported or not "
                                            "provided in IO AddTransport, "
                                            "in call to Open\n");
            }
        }
    }
}

void DataMan::WriteWAN(std::shared_ptr<std::vector<char>> buffer)
{
    PushBufferQueue(buffer);
}

void DataMan::WriteWAN(const std::vector<char> &buffer)
{
    if (m_CurrentTransport >= m_Transports.size())
    {
        throw std::runtime_error(
            "ERROR: No valid transports found, from DataMan::WriteWAN()");
    }

    m_Transports[m_CurrentTransport]->Write(
        reinterpret_cast<const char *>(buffer.data()), buffer.size());
}

std::shared_ptr<std::vector<char>> DataMan::ReadWAN()
{
    return PopBufferQueue();
}

void DataMan::PushBufferQueue(std::shared_ptr<std::vector<char>> v)
{
    std::lock_guard<std::mutex> l(m_Mutex);
    m_BufferQueue.push(v);
}

std::shared_ptr<std::vector<char>> DataMan::PopBufferQueue()
{
    std::lock_guard<std::mutex> l(m_Mutex);
    if (m_BufferQueue.size() > 0)
    {
        std::shared_ptr<std::vector<char>> vec = m_BufferQueue.front();
        m_BufferQueue.pop();
        return vec;
    }
    return nullptr;
}

void DataMan::WriteThread(std::shared_ptr<Transport> transport)
{
    while (m_Writing)
    {
        std::shared_ptr<std::vector<char>> buffer = PopBufferQueue();
        if (buffer != nullptr)
        {
            if (buffer->size() > 0)
            {
                transport->Write(buffer->data(), buffer->size());
            }
        }
    }
}

void DataMan::ReadThread(std::shared_ptr<Transport> transport)
{
    std::vector<char> buffer(m_MaxReceiveBuffer);
    while (m_Reading)
    {
        Transport::Status status;
        transport->IRead(buffer.data(), m_MaxReceiveBuffer, status);
        if (status.Bytes > 0)
        {
            std::shared_ptr<std::vector<char>> bufferQ =
                std::make_shared<std::vector<char>>(status.Bytes);
            std::memcpy(bufferQ->data(), buffer.data(), status.Bytes);
            PushBufferQueue(bufferQ);
        }
    }
}

bool DataMan::GetBoolParameter(const Params &params, std::string key)
{
    auto itKey = params.find(key);
    if (itKey != params.end())
    {
        std::string value = itKey->second;
        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
        if (value == "yes" || value == "true")
        {
            return true;
        }
        else if (value == "no" || value == "false")
        {
            return false;
        }
    }
    return false;
}

bool DataMan::GetStringParameter(const Params &params, std::string key,
                                 std::string &value, std::string default_value)
{
    auto it = params.find(key);
    if (it != params.end())
    {
        value = it->second;
        return true;
    }
    value = default_value;
    return false;
}

} // end namespace transportman
} // end namespace adios2
<|endoftext|>


<commit_before>#include "x_client_thumbnail_gl.hpp"

#include <xcb/composite.h>
#include <xcb/xcb_renderutil.h>

x_client_thumbnail::x_client_thumbnail(x_connection & c,
                                       const rectangle & rect,
                                       const xcb_window_t & window,
                                       std::shared_ptr<x_client> xclient)
      : _c(c)
{
  if (window == XCB_NONE && xclient == NULL) {
    throw std::invalid_argument(
        "x_client_thumbnail requires either window or xclient parameter");
  } else if (xclient == NULL) {
    _x_client = x_client_ptr(new x_client(_c, window));
  } else {
    _x_client = xclient;
  }

  update_rectangle(rect);

  _c.register_handler(_c.damage_event_id(), this);
  _c.register_handler(XCB_CONFIGURE_NOTIFY, this);

  _damage = xcb_generate_id(_c());

  configure_parent_pixmap();

  _thumbnail_window = xcb_generate_id(_c());
  xcb_colormap_t colormap = xcb_generate_id(_c());

  unsigned int depth = 32;
  xcb_visualtype_t * const vt = _c.find_visual(depth);

  xcb_create_colormap(_c(), XCB_COLORMAP_ALLOC_NONE, colormap,
                      _c.root_window(), vt->visual_id);

  uint32_t valuemask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL
                     | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_COLORMAP;
  uint32_t valuelist[] = { 0, 0, 1, colormap };
  xcb_create_window(_c(), depth, _thumbnail_window,
                    _c.root_window(), 0, 0,
                    _x_client->rect().width(), _x_client->rect().height(),
                    0, XCB_WINDOW_CLASS_INPUT_OUTPUT, vt->visual_id,
                    valuemask, valuelist);

  xcb_free_colormap(_c(), colormap);

  configure_gl();
  init_gl_shader();

  update();
}

x_client_thumbnail::~x_client_thumbnail(void)
{
  _c.deregister_handler(_c.damage_event_id(), this);
  _c.deregister_handler(XCB_CONFIGURE_NOTIFY, this);
  release_gl();
  xcb_free_pixmap(_c(), _parent_pixmap);
  xcb_destroy_window(_c(), _thumbnail_window);
}

void
x_client_thumbnail::show(void)
{
  _visible = true;
  xcb_damage_create(_c(), _damage, _x_client->window(),
                    XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);

  configure_thumbnail_window();

  if (_purge) {
    purge();
    _purge = false;
  } else {
    update();
  }
}

void
x_client_thumbnail::hide(void)
{
  _visible = false;
  xcb_damage_destroy(_c(), _damage);
  xcb_unmap_window(_c(), _thumbnail_window);
}

void
x_client_thumbnail::select(void)
{
  _c.request_change_current_desktop(_x_client->net_wm_desktop());
  _c.request_change_active_window(_x_client->window());
}

void
x_client_thumbnail::update(void)
{
  update(0, 0, _rectangle.width(), _rectangle.height());
}

void
x_client_thumbnail::purge(void)
{
  configure_parent_pixmap();
  release_gl();
  configure_gl();
  init_gl_shader();
  update();
}

void
x_client_thumbnail::update(int x, int y, unsigned int width, unsigned int height)
{
  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);
  glEnable(GL_SCISSOR_TEST);
  glScissor(x, y, width, height);

  glViewport(0, 0, _rectangle.width(), _rectangle.height());

  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glBegin(GL_QUADS);
  glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0, 0.0);
  glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, 0.0);
  glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 0.0);
  glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0);
  glEnd();

  glXSwapBuffers(_c.dpy(), _thumbnail_window);

  glDisable(GL_SCISSOR_TEST);
  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
}

void
x_client_thumbnail::highlight(bool want_highlight)
{
  _highlight = want_highlight;
  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);
  _c.glXBindTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT, NULL);

  if (want_highlight) {
    _c.glUseProgram(0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
    _c.glGenerateMipmapEXT(GL_TEXTURE_2D);

  } else {
    _c.glUseProgram(_programs["grayscale_shader"]);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  }
  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);

  update();
}

bool
x_client_thumbnail::handle(xcb_generic_event_t * ge)
{
  bool result = false;
  if (_c.damage_event_id() == (ge->response_type & ~0x80)) {
    xcb_damage_notify_event_t * e = (xcb_damage_notify_event_t *)ge;
    xcb_damage_subtract(_c(), e->damage, XCB_NONE, XCB_NONE);

    if (_highlight) {
      glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);

      _c.glXBindTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT, NULL);
      _c.glGenerateMipmapEXT(GL_TEXTURE_2D);

      glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
    }

    update(e->area.x * _scale, e->area.y * _scale,
           e->area.width * _scale, e->area.height * _scale);
    result = true;

  } else if (XCB_CONFIGURE_NOTIFY == (ge->response_type & ~0x80)) {
    xcb_configure_notify_event_t * e = (xcb_configure_notify_event_t *)ge;
    if (e->window == _c.root_window() || e->window == _x_client->window()) {
      if (_visible) {
        purge();
      } else {
        _purge = true;
      }
    }

    result = true;
  }

  return result;
}

void
x_client_thumbnail::update_rectangle(const rectangle & rect)
{
  _scale = std::min((double)rect.width() / _x_client->rect().width(),
                    (double)rect.height() / _x_client->rect().height());
  _scale = std::min(1.0, _scale);

  _rectangle.x() = rect.x();
  _rectangle.y() = rect.y();
  _rectangle.width() = _x_client->rect().width() * _scale;
  _rectangle.height() = _x_client->rect().height() * _scale;
}

void
x_client_thumbnail::configure_thumbnail_window(void)
{
  xcb_xfixes_region_t region = xcb_generate_id(_c());
  xcb_xfixes_create_region_from_window(_c(), region, _x_client->window(),
                                       XCB_SHAPE_SK_BOUNDING);

  xcb_xfixes_fetch_region_cookie_t fetch_region_cookie =
    xcb_xfixes_fetch_region(_c(), region);
  xcb_xfixes_fetch_region_reply_t * fetch_region_reply =
    xcb_xfixes_fetch_region_reply(_c(), fetch_region_cookie, NULL);

  int nrects = xcb_xfixes_fetch_region_rectangles_length(fetch_region_reply);
  xcb_rectangle_t * rects =
    xcb_xfixes_fetch_region_rectangles(fetch_region_reply);

  delete fetch_region_reply;
  xcb_xfixes_destroy_region(_c(), region);

  double ar = (double)_x_client->rect().width() / _x_client->rect().height();
  unsigned int width_cutoff = std::ceil(10.0 * ar * _scale) ;
  unsigned int height_cutoff = std::ceil(10.0 * (1.0/ar) * _scale);
  for (int i = 0; i < nrects; ++i) {
    rects[i].x *= _scale;
    rects[i].y *= _scale;
    if (rects[i].width > width_cutoff) {
      rects[i].width = std::round(_scale * (double)rects[i].width);
    }
    if (rects[i].height > height_cutoff) {
      rects[i].height = std::round(_scale * (double)rects[i].height);
    }
  }

  region = xcb_generate_id(_c());
  xcb_xfixes_create_region(_c(), region, nrects, rects);

  xcb_xfixes_set_window_shape_region(_c(), _thumbnail_window,
                                     XCB_SHAPE_SK_BOUNDING, 0, 0, region);
  xcb_xfixes_destroy_region(_c(), region);

  uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
                | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT
                | XCB_CONFIG_WINDOW_STACK_MODE;

  uint32_t values[] = { (uint32_t)_rectangle.x(),
                        (uint32_t)_rectangle.y(),
                        (uint32_t)_rectangle.width(),
                        (uint32_t)_rectangle.height(),
                        XCB_STACK_MODE_ABOVE };

  xcb_configure_window(_c(), _thumbnail_window, mask, values);
  xcb_map_window(_c(), _thumbnail_window);
}

void
x_client_thumbnail::configure_parent_pixmap(void)
{
  xcb_free_pixmap(_c(), _parent_pixmap);
  _parent_pixmap = xcb_generate_id(_c());
  xcb_composite_name_window_pixmap(_c(), _x_client->window(), _parent_pixmap);
}

void
x_client_thumbnail::configure_gl(XVisualInfo * vi)
{
  const int pixmap_config[] = {
    GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
    GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
    GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
    GLX_DOUBLEBUFFER, False,
    GLX_Y_INVERTED_EXT,
    None
  };

  const int pixmap_attr[] = {
    GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
    GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
    None
  };

  auto create_ctx = [this, &vi]()
  {
    _gl_ctx = glXCreateContext(_c.dpy(), vi, NULL, GL_TRUE);
  };

  if (vi == NULL) {
    GLint gl_vi_attr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
    vi = glXChooseVisual(_c.dpy(), DefaultScreen(_c.dpy()), gl_vi_attr);
    create_ctx();
    delete vi;
  } else {
    create_ctx();
  }

  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);

  int config = 0;
  GLXFBConfig * _gl_configs =
    glXChooseFBConfig(_c.dpy(), 0, pixmap_config, &config);
  _thumbnail_gl_pixmap =
      glXCreatePixmap(_c.dpy(), _gl_configs[0], _parent_pixmap, pixmap_attr);
  delete _gl_configs;

  GLuint _thumbnail_gl_texture_id;
  glEnable(GL_TEXTURE_2D);
  glGenTextures(1, &_thumbnail_gl_texture_id);
  glBindTexture(GL_TEXTURE_2D, _thumbnail_gl_texture_id);
  _c.glXBindTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT, NULL);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
}

void
x_client_thumbnail::init_gl_shader(void)
{
  std::string shader_name = "grayscale_shader";
  std::ifstream file("./grayscale.frag");
  std::string shader_source_str((std::istreambuf_iterator<char>(file)),
                                 std::istreambuf_iterator<char>());
  file.close();

  const GLchar * shader_source[]  = { shader_source_str.c_str() };
  const GLint shader_source_len[] = { (GLint)(shader_source_str.length()) };

  GLsizei log_length = 0, max_len = 1024;
  GLchar log_buffer[max_len];

  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);

  GLuint shader = _c.glCreateShader(GL_FRAGMENT_SHADER);
  _c.glShaderSource(shader, 1, shader_source, shader_source_len);
  _c.glCompileShader(shader);

  _c.glGetShaderInfoLog(shader, max_len, &log_length, log_buffer);
  if (log_length > 0) {
    std::cerr << "Shader compilation failed:" << std::endl
              << log_buffer << std::endl;
  }

  _programs[shader_name] = _c.glCreateProgram();
  _c.glAttachShader(_programs[shader_name], shader);
  _c.glLinkProgram(_programs[shader_name]);
  _c.glUseProgram(_programs[shader_name]);

  _c.glGetProgramInfoLog(_programs[shader_name],
                         max_len, &log_length, log_buffer);
  if (log_length > 0) {
    std::cerr << "Program creation failed:" << std::endl
              << log_buffer << std::endl;
  }

  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
}

void
x_client_thumbnail::release_gl(void)
{
  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);
  _c.glXReleaseTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT);
  glXDestroyContext(_c.dpy(), _gl_ctx);
  glXMakeCurrent(_c.dpy(), None, NULL);
}

bool operator==(const x_client_thumbnail & thumbnail, const xcb_window_t & window)
{
  return *(thumbnail._x_client) == window;
}

bool operator==(const xcb_window_t & window, const x_client_thumbnail & thumbnail)
{
  return thumbnail == window;
}
<commit_msg>Fix behaviour for reparenting wms<commit_after>#include "x_client_thumbnail_gl.hpp"

#include <xcb/composite.h>
#include <xcb/xcb_renderutil.h>

x_client_thumbnail::x_client_thumbnail(x_connection & c,
                                       const rectangle & rect,
                                       const xcb_window_t & window,
                                       std::shared_ptr<x_client> xclient)
      : _c(c)
{
  if (window == XCB_NONE && xclient == NULL) {
    throw std::invalid_argument(
        "x_client_thumbnail requires either window or xclient parameter");
  } else if (xclient == NULL) {
    _x_client = x_client_ptr(new x_client(_c, window));
  } else {
    _x_client = xclient;
  }

  update_rectangle(rect);

  _c.register_handler(_c.damage_event_id(), this);
  _c.register_handler(XCB_CONFIGURE_NOTIFY, this);

  _damage = xcb_generate_id(_c());

  configure_parent_pixmap();

  _thumbnail_window = xcb_generate_id(_c());
  xcb_colormap_t colormap = xcb_generate_id(_c());

  unsigned int depth = 32;
  xcb_visualtype_t * const vt = _c.find_visual(depth);

  xcb_create_colormap(_c(), XCB_COLORMAP_ALLOC_NONE, colormap,
                      _c.root_window(), vt->visual_id);

  uint32_t valuemask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL
                     | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_COLORMAP;
  uint32_t valuelist[] = { 0, 0, 1, colormap };
  xcb_create_window(_c(), depth, _thumbnail_window,
                    _c.root_window(), 0, 0,
                    _x_client->rect().width(), _x_client->rect().height(),
                    0, XCB_WINDOW_CLASS_INPUT_OUTPUT, vt->visual_id,
                    valuemask, valuelist);

  xcb_free_colormap(_c(), colormap);

  configure_gl();
  init_gl_shader();

  update();
}

x_client_thumbnail::~x_client_thumbnail(void)
{
  _c.deregister_handler(_c.damage_event_id(), this);
  _c.deregister_handler(XCB_CONFIGURE_NOTIFY, this);
  release_gl();
  xcb_free_pixmap(_c(), _parent_pixmap);
  xcb_destroy_window(_c(), _thumbnail_window);
}

void
x_client_thumbnail::show(void)
{
  _visible = true;
  xcb_damage_create(_c(), _damage, _x_client->window(),
                    XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);

  configure_thumbnail_window();

  if (_purge) {
    purge();
    _purge = false;
  } else {
    update();
  }
}

void
x_client_thumbnail::hide(void)
{
  _visible = false;
  xcb_damage_destroy(_c(), _damage);
  xcb_unmap_window(_c(), _thumbnail_window);
}

void
x_client_thumbnail::select(void)
{
  _c.request_change_current_desktop(_x_client->net_wm_desktop());
  _c.request_change_active_window(_x_client->window());
}

void
x_client_thumbnail::update(void)
{
  update(0, 0, _rectangle.width(), _rectangle.height());
}

void
x_client_thumbnail::purge(void)
{
  configure_parent_pixmap();
  release_gl();
  configure_gl();
  init_gl_shader();
  update();
}

void
x_client_thumbnail::update(int x, int y, unsigned int width, unsigned int height)
{
  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);
  glEnable(GL_SCISSOR_TEST);
  glScissor(x, y, width, height);

  glViewport(0, 0, _rectangle.width(), _rectangle.height());

  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glBegin(GL_QUADS);
  glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0, 0.0);
  glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, 0.0);
  glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 0.0);
  glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0);
  glEnd();

  glXSwapBuffers(_c.dpy(), _thumbnail_window);

  glDisable(GL_SCISSOR_TEST);
  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
}

void
x_client_thumbnail::highlight(bool want_highlight)
{
  _highlight = want_highlight;
  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);
  _c.glXBindTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT, NULL);

  if (want_highlight) {
    _c.glUseProgram(0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
    _c.glGenerateMipmapEXT(GL_TEXTURE_2D);

  } else {
    _c.glUseProgram(_programs["grayscale_shader"]);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  }
  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);

  update();
}

bool
x_client_thumbnail::handle(xcb_generic_event_t * ge)
{
  bool result = false;
  if (_c.damage_event_id() == (ge->response_type & ~0x80)) {
    xcb_damage_notify_event_t * e = (xcb_damage_notify_event_t *)ge;
    xcb_damage_subtract(_c(), e->damage, XCB_NONE, XCB_NONE);

    if (_highlight) {
      glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);

      _c.glXBindTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT, NULL);
      _c.glGenerateMipmapEXT(GL_TEXTURE_2D);

      glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
    }

    update(e->area.x * _scale, e->area.y * _scale,
           e->area.width * _scale, e->area.height * _scale);
    result = true;

  } else if (XCB_CONFIGURE_NOTIFY == (ge->response_type & ~0x80)) {
    xcb_configure_notify_event_t * e = (xcb_configure_notify_event_t *)ge;
    if (e->window == _c.root_window() || e->window == _x_client->window()) {
      if (_visible) {
        purge();
      } else {
        _purge = true;
      }
    }

    result = true;
  }

  return result;
}

void
x_client_thumbnail::update_rectangle(const rectangle & rect)
{
  _scale = std::min((double)rect.width() / _x_client->rect().width(),
                    (double)rect.height() / _x_client->rect().height());
  _scale = std::min(1.0, _scale);

  _rectangle.x() = rect.x();
  _rectangle.y() = rect.y();
  _rectangle.width() = _x_client->rect().width() * _scale;
  _rectangle.height() = _x_client->rect().height() * _scale;
}

void
x_client_thumbnail::configure_thumbnail_window(void)
{
  xcb_xfixes_region_t region = xcb_generate_id(_c());
  xcb_xfixes_create_region_from_window(_c(), region, _x_client->window(),
                                       XCB_SHAPE_SK_BOUNDING);

  xcb_xfixes_fetch_region_cookie_t fetch_region_cookie =
    xcb_xfixes_fetch_region(_c(), region);
  xcb_xfixes_fetch_region_reply_t * fetch_region_reply =
    xcb_xfixes_fetch_region_reply(_c(), fetch_region_cookie, NULL);

  int nrects = xcb_xfixes_fetch_region_rectangles_length(fetch_region_reply);
  xcb_rectangle_t * rects =
    xcb_xfixes_fetch_region_rectangles(fetch_region_reply);

  delete fetch_region_reply;
  xcb_xfixes_destroy_region(_c(), region);

  double ar = (double)_x_client->rect().width() / _x_client->rect().height();
  unsigned int width_cutoff = std::ceil(10.0 * ar * _scale) ;
  unsigned int height_cutoff = std::ceil(10.0 * (1.0/ar) * _scale);
  for (int i = 0; i < nrects; ++i) {
    rects[i].x *= _scale;
    rects[i].y *= _scale;
    if (rects[i].width > width_cutoff) {
      rects[i].width = std::round(_scale * (double)rects[i].width);
    }
    if (rects[i].height > height_cutoff) {
      rects[i].height = std::round(_scale * (double)rects[i].height);
    }
  }

  region = xcb_generate_id(_c());
  xcb_xfixes_create_region(_c(), region, nrects, rects);

  xcb_xfixes_set_window_shape_region(_c(), _thumbnail_window,
                                     XCB_SHAPE_SK_BOUNDING, 0, 0, region);
  xcb_xfixes_destroy_region(_c(), region);

  uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
                | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT
                | XCB_CONFIG_WINDOW_STACK_MODE;

  uint32_t values[] = { (uint32_t)_rectangle.x(),
                        (uint32_t)_rectangle.y(),
                        (uint32_t)_rectangle.width(),
                        (uint32_t)_rectangle.height(),
                        XCB_STACK_MODE_ABOVE };

  xcb_configure_window(_c(), _thumbnail_window, mask, values);
  xcb_map_window(_c(), _thumbnail_window);
}

void
x_client_thumbnail::configure_parent_pixmap(void)
{
  xcb_free_pixmap(_c(), _parent_pixmap);
  _parent_pixmap = xcb_generate_id(_c());

  xcb_window_t parent = _x_client->window(), next_parent = _x_client->parent();
  while (next_parent != _c.root_window()) {
    parent = next_parent;
    next_parent = std::get<0>(_c.query_tree(next_parent));
  }

  xcb_composite_name_window_pixmap(_c(), parent, _parent_pixmap);
}

void
x_client_thumbnail::configure_gl(XVisualInfo * vi)
{
  const int pixmap_config[] = {
    GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
    GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
    GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
    GLX_DOUBLEBUFFER, False,
    GLX_Y_INVERTED_EXT,
    None
  };

  const int pixmap_attr[] = {
    GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
    GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
    None
  };

  auto create_ctx = [this, &vi]()
  {
    _gl_ctx = glXCreateContext(_c.dpy(), vi, NULL, GL_TRUE);
  };

  if (vi == NULL) {
    GLint gl_vi_attr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
    vi = glXChooseVisual(_c.dpy(), DefaultScreen(_c.dpy()), gl_vi_attr);
    create_ctx();
    delete vi;
  } else {
    create_ctx();
  }

  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);

  int config = 0;
  GLXFBConfig * _gl_configs =
    glXChooseFBConfig(_c.dpy(), 0, pixmap_config, &config);
  _thumbnail_gl_pixmap =
      glXCreatePixmap(_c.dpy(), _gl_configs[0], _parent_pixmap, pixmap_attr);
  delete _gl_configs;

  GLuint _thumbnail_gl_texture_id;
  glEnable(GL_TEXTURE_2D);
  glGenTextures(1, &_thumbnail_gl_texture_id);
  glBindTexture(GL_TEXTURE_2D, _thumbnail_gl_texture_id);
  _c.glXBindTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT, NULL);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
}

void
x_client_thumbnail::init_gl_shader(void)
{
  std::string shader_name = "grayscale_shader";
  std::ifstream file("./grayscale.frag");
  std::string shader_source_str((std::istreambuf_iterator<char>(file)),
                                 std::istreambuf_iterator<char>());
  file.close();

  const GLchar * shader_source[]  = { shader_source_str.c_str() };
  const GLint shader_source_len[] = { (GLint)(shader_source_str.length()) };

  GLsizei log_length = 0, max_len = 1024;
  GLchar log_buffer[max_len];

  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);

  GLuint shader = _c.glCreateShader(GL_FRAGMENT_SHADER);
  _c.glShaderSource(shader, 1, shader_source, shader_source_len);
  _c.glCompileShader(shader);

  _c.glGetShaderInfoLog(shader, max_len, &log_length, log_buffer);
  if (log_length > 0) {
    std::cerr << "Shader compilation failed:" << std::endl
              << log_buffer << std::endl;
  }

  _programs[shader_name] = _c.glCreateProgram();
  _c.glAttachShader(_programs[shader_name], shader);
  _c.glLinkProgram(_programs[shader_name]);
  _c.glUseProgram(_programs[shader_name]);

  _c.glGetProgramInfoLog(_programs[shader_name],
                         max_len, &log_length, log_buffer);
  if (log_length > 0) {
    std::cerr << "Program creation failed:" << std::endl
              << log_buffer << std::endl;
  }

  glXMakeCurrent(_c.dpy(), XCB_NONE, NULL);
}

void
x_client_thumbnail::release_gl(void)
{
  glXMakeCurrent(_c.dpy(), _thumbnail_window, _gl_ctx);
  _c.glXReleaseTexImageEXT(_c.dpy(), _thumbnail_gl_pixmap, GLX_FRONT_EXT);
  glXDestroyContext(_c.dpy(), _gl_ctx);
  glXMakeCurrent(_c.dpy(), None, NULL);
}

bool operator==(const x_client_thumbnail & thumbnail, const xcb_window_t & window)
{
  return *(thumbnail._x_client) == window;
}

bool operator==(const xcb_window_t & window, const x_client_thumbnail & thumbnail)
{
  return thumbnail == window;
}
<|endoftext|>


<commit_before>// [[Rcpp::depends(BH)]]

#include "Random.h"

#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>

#include <boost/math/distributions/normal.hpp>
#include <boost/math/distributions/exponential.hpp>
#include <boost/math/distributions/gamma.hpp>

#include <stdint.h>

#define Q_GAMMA_THRESHOLD 0.000001f
#define Q_GAMMA_MIN_VALUE 0.0

typedef boost::random::mt19937 RNGType;
//typedef boost::random::mt11213b RNGType; // should be faster

static RNGType rng;
static boost::random::uniform_01<RNGType&> u01_dist(rng);

void gaps::random::save(Archive &ar)
{
    ar << rng;
}

void gaps::random::load(Archive &ar)
{
    ar >> rng;
}

void gaps::random::setSeed(uint32_t seed)
{
    rng.seed(seed);
}

float gaps::random::normal(float mean, float var)
{
    boost::random::normal_distribution<float> dist(mean, var);
    return dist(rng);
}

int gaps::random::poisson(float lambda)
{
    boost::random::poisson_distribution<> dist(lambda);
    return dist(rng);
}

float gaps::random::exponential(float lambda)
{
    boost::random::exponential_distribution<> dist(lambda);
    return dist(rng);
}

// open interval
float gaps::random::uniform()
{
    float u = 0.f;
    while (u == 0.f || u == 1.f)
    {
        u = u01_dist();
    }
    return u;
}

float gaps::random::uniform(float a, float b)
{
    return uniform() * (b - a) + a;
}

uint64_t gaps::random::uniform64()
{
    boost::random::uniform_int_distribution<uint64_t> dist(0,
        std::numeric_limits<uint64_t>::max());
    return dist(rng);
}

uint64_t gaps::random::uniform64(uint64_t a, uint64_t b)
{
    if (a == b)
    {
        return a;
    }
    else
    {
        boost::random::uniform_int_distribution<uint64_t> dist(a,b);
        return dist(rng);
    }
}

float gaps::random::d_gamma(float d, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return pdf(gam, d);
}

float gaps::random::p_gamma(float p, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return cdf(gam, p);
}

float gaps::random::q_gamma(float q, float shape, float scale)
{
    if (q < Q_GAMMA_THRESHOLD)
    {
        return Q_GAMMA_MIN_VALUE;
    }
    else
    {
        boost::math::gamma_distribution<> gam(shape, scale);
        return quantile(gam, q);
    }
}

float gaps::random::d_norm(float d, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return pdf(norm, d);
}

float gaps::random::q_norm(float q, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return quantile(norm, q);
}

float gaps::random::p_norm(float p, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return cdf(norm, p);
}
<commit_msg>better uniform fix<commit_after>// [[Rcpp::depends(BH)]]

#include "Random.h"

#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>

#include <boost/math/distributions/normal.hpp>
#include <boost/math/distributions/exponential.hpp>
#include <boost/math/distributions/gamma.hpp>

#include <stdint.h>

#define Q_GAMMA_THRESHOLD 0.000001f
#define Q_GAMMA_MIN_VALUE 0.0

typedef boost::random::mt19937 RNGType;
//typedef boost::random::mt11213b RNGType; // should be faster

static RNGType rng;
static boost::random::uniform_01<RNGType&> u01_dist(rng);

void gaps::random::save(Archive &ar)
{
    ar << rng;
}

void gaps::random::load(Archive &ar)
{
    ar >> rng;
}

void gaps::random::setSeed(uint32_t seed)
{
    rng.seed(seed);
}

float gaps::random::normal(float mean, float var)
{
    boost::random::normal_distribution<float> dist(mean, var);
    return dist(rng);
}

int gaps::random::poisson(float lambda)
{
    boost::random::poisson_distribution<> dist(lambda);
    return dist(rng);
}

float gaps::random::exponential(float lambda)
{
    boost::random::exponential_distribution<> dist(lambda);
    return dist(rng);
}

// open interval
float gaps::random::uniform()
{
    return u01_dist();
}

float gaps::random::uniform(float a, float b)
{
    if (a == b)
    {
        return a;
    }
    else
    {
        boost::random::uniform_real_distribution<> dist(a,b);
        float result = dist(rng);
        while (result == 0.f || result == 1.f) // causes errors with quantile
        {
            result = dist(rng);
        }
        return result;
    }
}

uint64_t gaps::random::uniform64()
{
    boost::random::uniform_int_distribution<uint64_t> dist(0,
        std::numeric_limits<uint64_t>::max());
    return dist(rng);
}

uint64_t gaps::random::uniform64(uint64_t a, uint64_t b)
{
    if (a == b)
    {
        return a;
    }
    else
    {
        boost::random::uniform_int_distribution<uint64_t> dist(a,b);
        return dist(rng);
    }
}

float gaps::random::d_gamma(float d, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return pdf(gam, d);
}

float gaps::random::p_gamma(float p, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return cdf(gam, p);
}

float gaps::random::q_gamma(float q, float shape, float scale)
{
    if (q < Q_GAMMA_THRESHOLD)
    {
        return Q_GAMMA_MIN_VALUE;
    }
    else
    {
        boost::math::gamma_distribution<> gam(shape, scale);
        return quantile(gam, q);
    }
}

float gaps::random::d_norm(float d, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return pdf(norm, d);
}

float gaps::random::q_norm(float q, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return quantile(norm, q);
}

float gaps::random::p_norm(float p, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return cdf(norm, p);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Library
  Module:    SampleF.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include <math.h>
#include "SampleF.hh"
#include "FScalars.hh"
#include "FNormals.hh"

// Description
// Construct with ModelBounds=(-1,1,-1,1,-1,1), SampleDimensions=(50,50,50),
// Capping turned off, and normal generation on.
vlSampleFunction::vlSampleFunction()
{
  this->ModelBounds[0] = -1.0;
  this->ModelBounds[1] = 1.0;
  this->ModelBounds[2] = -1.0;
  this->ModelBounds[3] = 1.0;
  this->ModelBounds[4] = -1.0;
  this->ModelBounds[5] = 1.0;

  this->SampleDimensions[0] = 50;
  this->SampleDimensions[1] = 50;
  this->SampleDimensions[2] = 50;

  this->Capping = 0;
  this->CapValue = LARGE_FLOAT;

  this->ImplicitFunction = NULL;

  this->ComputeNormals = 1;
}

void vlSampleFunction::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlSampleFunction::GetClassName()))
    {
    vlStructuredPointsSource::PrintSelf(os,indent);

    os << indent << "Sample Dimensions: (" << this->SampleDimensions[0] << ", "
                 << this->SampleDimensions[1] << ", "
                 << this->SampleDimensions[2] << ")\n";
    os << indent << "ModelBounds: \n";
    os << indent << "  Xmin,Xmax: (" << this->ModelBounds[0] << ", " << this->ModelBounds[1] << ")\n";
    os << indent << "  Ymin,Ymax: (" << this->ModelBounds[2] << ", " << this->ModelBounds[3] << ")\n";
    os << indent << "  Zmin,Zmax: (" << this->ModelBounds[4] << ", " << this->ModelBounds[5] << ")\n";
    }
}

// Description
// The model bounds is the location in space in which the sampling occurs.
void vlSampleFunction::SetModelBounds(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax)
{
  if (this->ModelBounds[0] != xmin || this->ModelBounds[1] != xmax ||
  this->ModelBounds[2] != ymin || this->ModelBounds[3] != ymax ||
  this->ModelBounds[4] != zmin || this->ModelBounds[5] != zmax )
    {
    float length;

    this->Modified();
    this->ModelBounds[0] = xmin;
    this->ModelBounds[1] = xmax;
    this->ModelBounds[2] = ymin;
    this->ModelBounds[3] = ymax;
    this->ModelBounds[4] = zmin;
    this->ModelBounds[5] = zmax;
    }
}

void vlSampleFunction::SetModelBounds(float *bounds)
{
  vlSampleFunction::SetModelBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
}

void vlSampleFunction::Execute()
{
  int ptId, i;
  vlFloatScalars *newScalars;
  vlFloatNormals *newNormals=NULL;
  int numPts;
  float *p, s;

  vlDebugMacro(<< "Sampling implicit function");
//
// Initialize self; create output objects
//
  this->Initialize();

  if ( !this->ImplicitFunction )
    {
    vlErrorMacro(<<"No implicit function specified");
    return;
    }

  numPts = this->SampleDimensions[0] * this->SampleDimensions[1]
           * this->SampleDimensions[2];
  newScalars = new vlFloatScalars(numPts);

  // Compute origin and aspect ratio
  this->SetDimensions(this->GetSampleDimensions());
  for (i=0; i < 3; i++)
    {
    this->Origin[i] = this->ModelBounds[2*i];
    this->AspectRatio[i] = (this->ModelBounds[2*i+1] - this->ModelBounds[2*i])
                           / (this->SampleDimensions[i] - 1);
    }
//
// Traverse all points evaluating implicit function at each point
//
  for (ptId=0; ptId < numPts; ptId++ )
    {
    p = this->GetPoint(ptId);
    s = this->ImplicitFunction->Evaluate(p[0], p[1], p[2]);
    newScalars->SetScalar(ptId,s);
    }
//
// If normal computation turned on, compute them
//
  if ( this->ComputeNormals )
    {
    float n[3];
    newNormals = new vlFloatNormals(numPts);
    for (ptId=0; ptId < numPts; ptId++ )
      {
      p = this->GetPoint(ptId);
      this->ImplicitFunction->EvaluateNormal(p[0], p[1], p[2], n);
      newNormals->SetNormal(ptId,n);
      }
    }
//
// If capping is turned on, set the distances of the outside of the volume
// to the CapValue.
//
  if ( this->Capping )
    {
    this->Cap(newScalars);
    }
//
// Update self
//
  this->PointData.SetScalars(newScalars);
  this->PointData.SetNormals(newNormals);
}

void vlSampleFunction::SetSampleDimensions(int i, int j, int k)
{
  int dim[3];

  dim[0] = i;
  dim[1] = j;
  dim[2] = k;

  this->SetSampleDimensions(dim);
}

void vlSampleFunction::SetSampleDimensions(int dim[3])
{
  vlDebugMacro(<< " setting SampleDimensions to (" << dim[0] << "," << dim[1] << "," << dim[2] << ")");

  if ( dim[0] != this->SampleDimensions[0] || dim[1] != SampleDimensions[1] ||
  dim[2] != SampleDimensions[2] )
    {
    for ( int i=0; i<3; i++)
      this->SampleDimensions[i] = (dim[i] > 0 ? dim[i] : 1);
    this->Modified();
    }
}

unsigned long vlSampleFunction::GetMTime()
{
  unsigned long mTime=this->MTime.GetMTime();
  unsigned long impFuncMTime;

  if ( this->ImplicitFunction != NULL )
    {
    impFuncMTime = this->ImplicitFunction->GetMTime();
    mTime = ( impFuncMTime > mTime ? impFuncMTime : mTime );
    }

  return mTime;
}

void vlSampleFunction::Cap(vlFloatScalars *s)
{
  int i,j,k;
  int idx;
  int d01=this->SampleDimensions[0]*this->SampleDimensions[1];

// i-j planes
  k = 0;
  for (j=0; j<this->SampleDimensions[1]; j++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(i+j*this->SampleDimensions[1], this->CapValue);

  k = this->SampleDimensions[2] - 1;
  idx = k*d01;
  for (j=0; j<this->SampleDimensions[1]; j++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(idx+i+j*this->SampleDimensions[1], this->CapValue);

// j-k planes
  i = 0;
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (j=0; j<this->SampleDimensions[1]; j++)
      s->SetScalar(j*this->SampleDimensions[0]+k*d01, this->CapValue);

  i = this->SampleDimensions[0] - 1;
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (j=0; j<this->SampleDimensions[1]; j++)
      s->SetScalar(i+j*this->SampleDimensions[0]+k*d01, this->CapValue);

// i-k planes
  j = 0;
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(i+k*d01, this->CapValue);

  j = this->SampleDimensions[1] - 1;
  idx = j*this->SampleDimensions[0];
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(idx+i+k*d01, this->CapValue);

}

<commit_msg>*** empty log message ***<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    SampleF.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include <math.h>
#include "SampleF.hh"
#include "FScalars.hh"
#include "FNormals.hh"

// Description
// Construct with ModelBounds=(-1,1,-1,1,-1,1), SampleDimensions=(50,50,50),
// Capping turned off, and normal generation on.
vlSampleFunction::vlSampleFunction()
{
  this->ModelBounds[0] = -1.0;
  this->ModelBounds[1] = 1.0;
  this->ModelBounds[2] = -1.0;
  this->ModelBounds[3] = 1.0;
  this->ModelBounds[4] = -1.0;
  this->ModelBounds[5] = 1.0;

  this->SampleDimensions[0] = 50;
  this->SampleDimensions[1] = 50;
  this->SampleDimensions[2] = 50;

  this->Capping = 0;
  this->CapValue = LARGE_FLOAT;

  this->ImplicitFunction = NULL;

  this->ComputeNormals = 1;
}

void vlSampleFunction::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlSampleFunction::GetClassName()))
    {
    vlStructuredPointsSource::PrintSelf(os,indent);

    os << indent << "Sample Dimensions: (" << this->SampleDimensions[0] << ", "
                 << this->SampleDimensions[1] << ", "
                 << this->SampleDimensions[2] << ")\n";
    os << indent << "ModelBounds: \n";
    os << indent << "  Xmin,Xmax: (" << this->ModelBounds[0] << ", " << this->ModelBounds[1] << ")\n";
    os << indent << "  Ymin,Ymax: (" << this->ModelBounds[2] << ", " << this->ModelBounds[3] << ")\n";
    os << indent << "  Zmin,Zmax: (" << this->ModelBounds[4] << ", " << this->ModelBounds[5] << ")\n";
    }
}

// Description:
// Specify the model bounds is the location in space in which the
// sampling occurs.
void vlSampleFunction::SetModelBounds(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax)
{
  if (this->ModelBounds[0] != xmin || this->ModelBounds[1] != xmax ||
  this->ModelBounds[2] != ymin || this->ModelBounds[3] != ymax ||
  this->ModelBounds[4] != zmin || this->ModelBounds[5] != zmax )
    {
    float length;

    this->Modified();
    this->ModelBounds[0] = xmin;
    this->ModelBounds[1] = xmax;
    this->ModelBounds[2] = ymin;
    this->ModelBounds[3] = ymax;
    this->ModelBounds[4] = zmin;
    this->ModelBounds[5] = zmax;
    }
}

void vlSampleFunction::SetModelBounds(float *bounds)
{
  vlSampleFunction::SetModelBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
}

void vlSampleFunction::Execute()
{
  int ptId, i;
  vlFloatScalars *newScalars;
  vlFloatNormals *newNormals=NULL;
  int numPts;
  float *p, s;

  vlDebugMacro(<< "Sampling implicit function");
//
// Initialize self; create output objects
//
  this->Initialize();

  if ( !this->ImplicitFunction )
    {
    vlErrorMacro(<<"No implicit function specified");
    return;
    }

  numPts = this->SampleDimensions[0] * this->SampleDimensions[1]
           * this->SampleDimensions[2];
  newScalars = new vlFloatScalars(numPts);

  // Compute origin and aspect ratio
  this->SetDimensions(this->GetSampleDimensions());
  for (i=0; i < 3; i++)
    {
    this->Origin[i] = this->ModelBounds[2*i];
    this->AspectRatio[i] = (this->ModelBounds[2*i+1] - this->ModelBounds[2*i])
                           / (this->SampleDimensions[i] - 1);
    }
//
// Traverse all points evaluating implicit function at each point
//
  for (ptId=0; ptId < numPts; ptId++ )
    {
    p = this->GetPoint(ptId);
    s = this->ImplicitFunction->Evaluate(p[0], p[1], p[2]);
    newScalars->SetScalar(ptId,s);
    }
//
// If normal computation turned on, compute them
//
  if ( this->ComputeNormals )
    {
    float n[3];
    newNormals = new vlFloatNormals(numPts);
    for (ptId=0; ptId < numPts; ptId++ )
      {
      p = this->GetPoint(ptId);
      this->ImplicitFunction->EvaluateNormal(p[0], p[1], p[2], n);
      newNormals->SetNormal(ptId,n);
      }
    }
//
// If capping is turned on, set the distances of the outside of the volume
// to the CapValue.
//
  if ( this->Capping )
    {
    this->Cap(newScalars);
    }
//
// Update self
//
  this->PointData.SetScalars(newScalars);
  this->PointData.SetNormals(newNormals);
}

void vlSampleFunction::SetSampleDimensions(int i, int j, int k)
{
  int dim[3];

  dim[0] = i;
  dim[1] = j;
  dim[2] = k;

  this->SetSampleDimensions(dim);
}

void vlSampleFunction::SetSampleDimensions(int dim[3])
{
  vlDebugMacro(<< " setting SampleDimensions to (" << dim[0] << "," << dim[1] << "," << dim[2] << ")");

  if ( dim[0] != this->SampleDimensions[0] || dim[1] != SampleDimensions[1] ||
  dim[2] != SampleDimensions[2] )
    {
    for ( int i=0; i<3; i++)
      this->SampleDimensions[i] = (dim[i] > 0 ? dim[i] : 1);
    this->Modified();
    }
}

unsigned long vlSampleFunction::GetMTime()
{
  unsigned long mTime=this->MTime.GetMTime();
  unsigned long impFuncMTime;

  if ( this->ImplicitFunction != NULL )
    {
    impFuncMTime = this->ImplicitFunction->GetMTime();
    mTime = ( impFuncMTime > mTime ? impFuncMTime : mTime );
    }

  return mTime;
}

void vlSampleFunction::Cap(vlFloatScalars *s)
{
  int i,j,k;
  int idx;
  int d01=this->SampleDimensions[0]*this->SampleDimensions[1];

// i-j planes
  k = 0;
  for (j=0; j<this->SampleDimensions[1]; j++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(i+j*this->SampleDimensions[1], this->CapValue);

  k = this->SampleDimensions[2] - 1;
  idx = k*d01;
  for (j=0; j<this->SampleDimensions[1]; j++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(idx+i+j*this->SampleDimensions[1], this->CapValue);

// j-k planes
  i = 0;
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (j=0; j<this->SampleDimensions[1]; j++)
      s->SetScalar(j*this->SampleDimensions[0]+k*d01, this->CapValue);

  i = this->SampleDimensions[0] - 1;
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (j=0; j<this->SampleDimensions[1]; j++)
      s->SetScalar(i+j*this->SampleDimensions[0]+k*d01, this->CapValue);

// i-k planes
  j = 0;
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(i+k*d01, this->CapValue);

  j = this->SampleDimensions[1] - 1;
  idx = j*this->SampleDimensions[0];
  for (k=0; k<this->SampleDimensions[2]; k++)
    for (i=0; i<this->SampleDimensions[0]; i++)
      s->SetScalar(idx+i+k*d01, this->CapValue);

}

<|endoftext|>