<commit_before>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Stefan Seefeld <seefelds@magellan.umontreal.ca>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include "Prague/Sys/Signal.hh"
#include "Prague/IPC/Dispatcher.hh"
#include <queue>
#include <algorithm>
#include <ctime>
#include <cerrno>
#include <unistd.h>
#include <sys/types.h>

using namespace Prague;

Dispatcher *Dispatcher::dispatcher = 0;
Mutex Dispatcher::singletonMutex;
Dispatcher::Cleaner Dispatcher::cleaner;

struct SignalNotifier : Signal::Notifier
{
  virtual void notify(int signum)
  {
    cerr << Signal::name(signum) << endl;
    exit(1);
  }
};

Dispatcher::Cleaner::~Cleaner()
{
//   MutexGuard guard(singletonMutex);
  delete dispatcher;
}

Dispatcher *Dispatcher::instance()
{
  MutexGuard guard(singletonMutex);
  if (!dispatcher) dispatcher = new Dispatcher;
  return dispatcher;
}

Dispatcher::Dispatcher()
  //. create a queue of up to 64 tasks
  //. and a thread pool with 16 threads
  : notifier(new SignalNotifier),
    tasks(64),
    workers(tasks, acceptor, 4),
    server(&Dispatcher::dispatch, this)
{
  Signal::mask(Signal::pipe);
  Signal::set(Signal::hangup, notifier);
  Signal::set(Signal::interrupt, notifier);
  Signal::set(Signal::quit, notifier);
  Signal::set(Signal::illegal, notifier);
  Signal::set(Signal::abort, notifier);
  Signal::set(Signal::fpe, notifier);
  Signal::set(Signal::bus, notifier);
  //  Signal::set(Signal::segv, notifier);
  Signal::set(Signal::iotrap, notifier);
  Signal::set(Signal::terminate, notifier);
}

Dispatcher::~Dispatcher()
{
}

void Dispatcher::bind(int fd, Agent *agent, Agent::iomask_t mask)
{
  if (server.state() != Thread::running)
    {
      pipe(wakeup);
      rfds.set(wakeup[0]);
      server.start();
    }
//   Signal::Guard sguard(Signal::child);
  MutexGuard guard(mutex);
  if (find(agents.begin(), agents.end(), agent) == agents.end())
    agents.push_back(agent);
  if (mask & Agent::in)
    {
      if (mask & Agent::inready)
	{
	  wfds.set(fd);
	  if (wchannel.find(fd) == wchannel.end()) wchannel[fd] = task(fd, agent, Agent::inready);
	  else cerr << "Dispatcher::bind() : Error : file descriptor already in use" << endl;
	}
      if (mask & Agent::inexc)
	{
	  xfds.set(fd);
	  if (xchannel.find(fd) == xchannel.end()) xchannel[fd] = task(fd, agent, Agent::inexc);
	}
    }
  if (mask & Agent::out)
    {
      if (mask & Agent::outready)
	{
	  rfds.set(fd);
	  if (rchannel.find(fd) == rchannel.end()) rchannel[fd] = task(fd, agent, Agent::outready);
	  else cerr << "Dispatcher::bind() : Error : file descriptor already in use" << endl;
	}
      if (mask & Agent::outexc)
	{
	  xfds.set(fd);
	  if (xchannel.find(fd) == xchannel.end()) xchannel[fd] = task(fd, agent, Agent::outexc);
	}
    }
  if (mask & Agent::err)
    {
      if (mask & Agent::errready)
	{
	  rfds.set(fd);
	  if (rchannel.find(fd) == rchannel.end()) rchannel[fd] = task(fd, agent, Agent::errready);
	  else cerr << "Dispatcher::bind() : Error : file descriptor already in use" << endl;
	}
      if (mask & Agent::errexc)
	{
	  xfds.set(fd);
	  if (xchannel.find(fd) == xchannel.end()) xchannel[fd] = task(fd, agent, Agent::errexc);
	}
    }
}

void Dispatcher::release(int fd)
{
  MutexGuard guard(mutex);
  dictionary_t::iterator c;
  if ((c = rchannel.find(fd)) != rchannel.end())
    {
      rchannel.erase(c);
      rfds.clear(fd);
    }
  if ((c = wchannel.find(fd)) != wchannel.end())
    {
      wchannel.erase(c);
      wfds.clear(fd);
    }
  if ((c = xchannel.find(fd)) != xchannel.end())
    {
      xchannel.erase(c);
      xfds.clear(fd);
    }
}

void Dispatcher::release(Agent *agent)
{
//   Signal::Guard guard(Signal::child);
  MutexGuard guard(mutex);
  for (dictionary_t::iterator i = rchannel.begin(); i != rchannel.end(); i++)
    if ((*i).second.agent == agent) rchannel.erase(i);
  for (dictionary_t::iterator i = wchannel.begin(); i != wchannel.end(); i++)
    if ((*i).second.agent == agent) wchannel.erase(i);
  for (dictionary_t::iterator i = xchannel.begin(); i != xchannel.end(); i++)
    if ((*i).second.agent == agent) xchannel.erase(i);
  alist_t::iterator i = find(agents.begin(), agents.end(), agent);
  if (i != agents.end()) agents.erase(i);
}

void *Dispatcher::dispatch(void *X)
{
  Dispatcher *dispatcher = reinterpret_cast<Dispatcher *>(X);
  dispatcher->workers.start();
  do dispatcher->wait();
  while (true);
  return 0;
};

void Dispatcher::process(const task &t)
{
  if (t.agent->processIO(t.fd, t.mask)) activate(t);
}

void Dispatcher::deactivate(const task &t)
{
  switch (t.mask)
    {
    case Agent::inready: wfds.clear(t.fd); break;
    case Agent::outready:
    case Agent::errready: rfds.clear(t.fd); break;
    case Agent::inexc:
    case Agent::outexc:
    case Agent::errexc: xfds.clear(t.fd); break;
    default: break;
    }
}

void Dispatcher::activate(const task &t)
{
  switch (t.mask)
    {
    case Agent::inready: wfds.set(t.fd); break;
    case Agent::outready:
    case Agent::errready: rfds.set(t.fd); break;
    case Agent::inexc:
    case Agent::outexc:
    case Agent::errexc: xfds.set(t.fd); break;
    default: break;
    }
  char *c = "c";
  write(wakeup[1], c, 1);
}

void Dispatcher::wait()
{
  FdSet tmprfds = rfds;
  FdSet tmpwfds = wfds;
  FdSet tmpxfds = xfds;
  unsigned int fdsize = max(max(tmprfds.max(), tmpwfds.max()), tmpxfds.max()) + 1;
  int nsel = select(fdsize, tmprfds, tmpwfds, tmpxfds, 0);
  if (nsel == -1)
    {
      if (errno == EINTR || errno == EAGAIN) errno = 0;
    }
  else if (nsel > 0 && fdsize)
    {
      tlist_t t;
      for (dictionary_t::iterator i = rchannel.begin(); i != rchannel.end(); i++)
	if (tmprfds.isset((*i).first))
	  {
	    t.push_back((*i).second);
	    deactivate((*i).second);
	  }
      for (dictionary_t::iterator i = wchannel.begin(); i != wchannel.end(); i++)
	if (tmpwfds.isset((*i).first))
	  {
	    t.push_back((*i).second);
	    deactivate((*i).second);
	  }
      for (dictionary_t::iterator i = xchannel.begin(); i != xchannel.end(); i++)
	if (tmpxfds.isset((*i).first))
	  {
	    t.push_back((*i).second);
	    deactivate((*i).second);
	  }
      if (tmprfds.isset(wakeup[0]))
	{
	  char c[1];
	  read(wakeup[0],c,1);
	}
      for (tlist_t::const_iterator i = t.begin(); i != t.end(); i++)
	tasks.push(*i);
    }
};
<commit_msg>added cancelation point (work around linux/thread bug)<commit_after>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Stefan Seefeld <seefelds@magellan.umontreal.ca>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include "Prague/Sys/Signal.hh"
#include "Prague/IPC/Dispatcher.hh"
#include <queue>
#include <algorithm>
#include <ctime>
#include <cerrno>
#include <unistd.h>
#include <sys/types.h>

using namespace Prague;

Dispatcher *Dispatcher::dispatcher = 0;
Mutex Dispatcher::singletonMutex;
Dispatcher::Cleaner Dispatcher::cleaner;

struct SignalNotifier : Signal::Notifier
{
  virtual void notify(int signum)
  {
    cerr << Signal::name(signum) << endl;
    exit(1);
  }
};

Dispatcher::Cleaner::~Cleaner()
{
//   MutexGuard guard(singletonMutex);
  delete dispatcher;
}

Dispatcher *Dispatcher::instance()
{
  MutexGuard guard(singletonMutex);
  if (!dispatcher) dispatcher = new Dispatcher;
  return dispatcher;
}

Dispatcher::Dispatcher()
  //. create a queue of up to 64 tasks
  //. and a thread pool with 16 threads
  : notifier(new SignalNotifier),
    tasks(64),
    workers(tasks, acceptor, 4),
    server(&Dispatcher::dispatch, this)
{
  Signal::mask(Signal::pipe);
  Signal::set(Signal::hangup, notifier);
  Signal::set(Signal::interrupt, notifier);
  Signal::set(Signal::quit, notifier);
  Signal::set(Signal::illegal, notifier);
  Signal::set(Signal::abort, notifier);
  Signal::set(Signal::fpe, notifier);
  Signal::set(Signal::bus, notifier);
  //  Signal::set(Signal::segv, notifier);
  Signal::set(Signal::iotrap, notifier);
  Signal::set(Signal::terminate, notifier);
}

Dispatcher::~Dispatcher()
{
}

void Dispatcher::bind(int fd, Agent *agent, Agent::iomask_t mask)
{
  if (server.state() != Thread::running)
    {
      pipe(wakeup);
      rfds.set(wakeup[0]);
      server.start();
    }
//   Signal::Guard sguard(Signal::child);
  MutexGuard guard(mutex);
  if (find(agents.begin(), agents.end(), agent) == agents.end())
    agents.push_back(agent);
  if (mask & Agent::in)
    {
      if (mask & Agent::inready)
	{
	  wfds.set(fd);
	  if (wchannel.find(fd) == wchannel.end()) wchannel[fd] = task(fd, agent, Agent::inready);
	  else cerr << "Dispatcher::bind() : Error : file descriptor already in use" << endl;
	}
      if (mask & Agent::inexc)
	{
	  xfds.set(fd);
	  if (xchannel.find(fd) == xchannel.end()) xchannel[fd] = task(fd, agent, Agent::inexc);
	}
    }
  if (mask & Agent::out)
    {
      if (mask & Agent::outready)
	{
	  rfds.set(fd);
	  if (rchannel.find(fd) == rchannel.end()) rchannel[fd] = task(fd, agent, Agent::outready);
	  else cerr << "Dispatcher::bind() : Error : file descriptor already in use" << endl;
	}
      if (mask & Agent::outexc)
	{
	  xfds.set(fd);
	  if (xchannel.find(fd) == xchannel.end()) xchannel[fd] = task(fd, agent, Agent::outexc);
	}
    }
  if (mask & Agent::err)
    {
      if (mask & Agent::errready)
	{
	  rfds.set(fd);
	  if (rchannel.find(fd) == rchannel.end()) rchannel[fd] = task(fd, agent, Agent::errready);
	  else cerr << "Dispatcher::bind() : Error : file descriptor already in use" << endl;
	}
      if (mask & Agent::errexc)
	{
	  xfds.set(fd);
	  if (xchannel.find(fd) == xchannel.end()) xchannel[fd] = task(fd, agent, Agent::errexc);
	}
    }
}

void Dispatcher::release(int fd)
{
  MutexGuard guard(mutex);
  dictionary_t::iterator c;
  if ((c = rchannel.find(fd)) != rchannel.end())
    {
      rchannel.erase(c);
      rfds.clear(fd);
    }
  if ((c = wchannel.find(fd)) != wchannel.end())
    {
      wchannel.erase(c);
      wfds.clear(fd);
    }
  if ((c = xchannel.find(fd)) != xchannel.end())
    {
      xchannel.erase(c);
      xfds.clear(fd);
    }
}

void Dispatcher::release(Agent *agent)
{
//   Signal::Guard guard(Signal::child);
  MutexGuard guard(mutex);
  for (dictionary_t::iterator i = rchannel.begin(); i != rchannel.end(); i++)
    if ((*i).second.agent == agent) rchannel.erase(i);
  for (dictionary_t::iterator i = wchannel.begin(); i != wchannel.end(); i++)
    if ((*i).second.agent == agent) wchannel.erase(i);
  for (dictionary_t::iterator i = xchannel.begin(); i != xchannel.end(); i++)
    if ((*i).second.agent == agent) xchannel.erase(i);
  alist_t::iterator i = find(agents.begin(), agents.end(), agent);
  if (i != agents.end()) agents.erase(i);
}

void *Dispatcher::dispatch(void *X)
{
  Dispatcher *dispatcher = reinterpret_cast<Dispatcher *>(X);
  dispatcher->workers.start();
  do dispatcher->wait();
  while (true);
  return 0;
};

void Dispatcher::process(const task &t)
{
  if (t.agent->processIO(t.fd, t.mask)) activate(t);
}

void Dispatcher::deactivate(const task &t)
{
  switch (t.mask)
    {
    case Agent::inready: wfds.clear(t.fd); break;
    case Agent::outready:
    case Agent::errready: rfds.clear(t.fd); break;
    case Agent::inexc:
    case Agent::outexc:
    case Agent::errexc: xfds.clear(t.fd); break;
    default: break;
    }
}

void Dispatcher::activate(const task &t)
{
  switch (t.mask)
    {
    case Agent::inready: wfds.set(t.fd); break;
    case Agent::outready:
    case Agent::errready: rfds.set(t.fd); break;
    case Agent::inexc:
    case Agent::outexc:
    case Agent::errexc: xfds.set(t.fd); break;
    default: break;
    }
  char *c = "c";
  write(wakeup[1], c, 1);
}

void Dispatcher::wait()
{
  FdSet tmprfds = rfds;
  FdSet tmpwfds = wfds;
  FdSet tmpxfds = xfds;
  unsigned int fdsize = max(max(tmprfds.max(), tmpwfds.max()), tmpxfds.max()) + 1;
  int nsel = select(fdsize, tmprfds, tmpwfds, tmpxfds, 0);
  pthread_testcancel();
  if (nsel == -1)
    {
      if (errno == EINTR || errno == EAGAIN) errno = 0;
    }
  else if (nsel > 0 && fdsize)
    {
      tlist_t t;
      for (dictionary_t::iterator i = rchannel.begin(); i != rchannel.end(); i++)
	if (tmprfds.isset((*i).first))
	  {
	    t.push_back((*i).second);
	    deactivate((*i).second);
	  }
      for (dictionary_t::iterator i = wchannel.begin(); i != wchannel.end(); i++)
	if (tmpwfds.isset((*i).first))
	  {
	    t.push_back((*i).second);
	    deactivate((*i).second);
	  }
      for (dictionary_t::iterator i = xchannel.begin(); i != xchannel.end(); i++)
	if (tmpxfds.isset((*i).first))
	  {
	    t.push_back((*i).second);
	    deactivate((*i).second);
	  }
      if (tmprfds.isset(wakeup[0]))
	{
	  char c[1];
	  read(wakeup[0],c,1);
	}
      for (tlist_t::const_iterator i = t.begin(); i != t.end(); i++)
	tasks.push(*i);
    }
};
<|endoftext|>


<commit_before>#include "../Flare.h"
#include "FlareSectorInterface.h"
#include "FlareSimulatedSector.h"
#include "../Spacecrafts/FlareSpacecraftInterface.h"

#define LOCTEXT_NAMESPACE "FlareSectorInterface"

/*----------------------------------------------------
	Constructor
----------------------------------------------------*/

UFlareSectorInterface::UFlareSectorInterface(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{
}

FText UFlareSectorInterface::GetSectorName()
{
	if (SectorData.GivenName.ToString().Len())
	{
		return SectorData.GivenName;
	}
	else if (SectorDescription->Name.ToString().Len())
	{
		return SectorDescription->Name;
	}
	else
	{
		return FText::FromString(GetSectorCode());
	}
}

FString UFlareSectorInterface::GetSectorCode()
{
	// TODO cache ?
	return SectorOrbitParameters.CelestialBodyIdentifier.ToString() + "-" + FString::FromInt(SectorOrbitParameters.Altitude) + "-" + FString::FromInt(SectorOrbitParameters.Phase);
}

EFlareSectorFriendlyness::Type UFlareSectorInterface::GetSectorFriendlyness(UFlareCompany* Company)
{
	if (!Company->HasVisitedSector(GetSimulatedSector()))
	{
		return EFlareSectorFriendlyness::NotVisited;
	}

	if (GetSimulatedSector()->GetSectorSpacecrafts().Num() == 0)
	{
		return EFlareSectorFriendlyness::Neutral;
	}

	int HostileSpacecraftCount = 0;
	int NeutralSpacecraftCount = 0;
	int FriendlySpacecraftCount = 0;

	for (int SpacecraftIndex = 0 ; SpacecraftIndex < GetSimulatedSector()->GetSectorSpacecrafts().Num(); SpacecraftIndex++)
	{
		UFlareCompany* OtherCompany = GetSimulatedSector()->GetSectorSpacecrafts()[SpacecraftIndex]->GetCompany();

		if (OtherCompany == Company)
		{
			FriendlySpacecraftCount++;
		}
		else if (OtherCompany->GetWarState(Company) == EFlareHostility::Hostile)
		{
			HostileSpacecraftCount++;
		}
		else
		{
			NeutralSpacecraftCount++;
		}
	}

	if (FriendlySpacecraftCount > 0 && HostileSpacecraftCount > 0)
	{
		return EFlareSectorFriendlyness::Contested;
	}

	if (FriendlySpacecraftCount > 0)
	{
		return EFlareSectorFriendlyness::Friendly;
	}
	else if (HostileSpacecraftCount > 0)
	{
		return EFlareSectorFriendlyness::Hostile;
	}
	else
	{
		return EFlareSectorFriendlyness::Neutral;
	}
}

EFlareSectorBattleState::Type UFlareSectorInterface::GetSectorBattleState(UFlareCompany* Company)
{

	if (GetSectorShipInterfaces().Num() == 0)
	{
		return EFlareSectorBattleState::NoBattle;
	}

	int HostileSpacecraftCount = 0;
	int DangerousHostileSpacecraftCount = 0;

	int FriendlySpacecraftCount = 0;
	int DangerousFriendlySpacecraftCount = 0;
	int CrippledFriendlySpacecraftCount = 0;

	for (int SpacecraftIndex = 0 ; SpacecraftIndex < GetSectorShipInterfaces().Num(); SpacecraftIndex++)
	{

		IFlareSpacecraftInterface* Spacecraft = GetSectorShipInterfaces()[SpacecraftIndex];

		UFlareCompany* OtherCompany = Spacecraft->GetCompany();

		if (!Spacecraft->GetDamageSystem()->IsAlive())
		{
			continue;
		}

		if (OtherCompany == Company)
		{
			FriendlySpacecraftCount++;
			if (Spacecraft->GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Weapon) > 0)
			{
				DangerousFriendlySpacecraftCount++;
			}

			if (Spacecraft->GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Propulsion) == 0)
			{
				CrippledFriendlySpacecraftCount++;
			}
		}
		else if (OtherCompany->GetWarState(Company) == EFlareHostility::Hostile)
		{
			HostileSpacecraftCount++;
			if (Spacecraft->GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Weapon) > 0)
			{
				DangerousHostileSpacecraftCount++;
			}
		}
	}

	// No friendly or no hostile ship
	if (FriendlySpacecraftCount == 0 || HostileSpacecraftCount == 0)
	{
		return EFlareSectorBattleState::NoBattle;
	}

	// No friendly and hostile ship are not dangerous
	if (DangerousFriendlySpacecraftCount == 0 && DangerousHostileSpacecraftCount == 0)
	{
		return EFlareSectorBattleState::NoBattle;
	}

	// No friendly dangerous ship so the enemy have one. Battle is lost
	if (DangerousFriendlySpacecraftCount == 0)
	{
		if (CrippledFriendlySpacecraftCount == FriendlySpacecraftCount)
		{
			return EFlareSectorBattleState::BattleLostNoRetreat;
		}
		else
		{
			return EFlareSectorBattleState::BattleLost;
		}
	}

	if (DangerousHostileSpacecraftCount == 0)
	{
		return EFlareSectorBattleState::BattleWon;
	}

	if (CrippledFriendlySpacecraftCount == FriendlySpacecraftCount)
	{
		return EFlareSectorBattleState::BattleNoRetreat;
	}
	else
	{
		return EFlareSectorBattleState::Battle;
	}
}

FText UFlareSectorInterface::GetSectorFriendlynessText(UFlareCompany* Company)
{
	FText Status;

	switch (GetSectorFriendlyness(Company))
	{
		case EFlareSectorFriendlyness::NotVisited:
			Status = LOCTEXT("Unknown", "UNKNOWN");
			break;
		case EFlareSectorFriendlyness::Neutral:
			Status = LOCTEXT("Neutral", "NEUTRAL");
			break;
		case EFlareSectorFriendlyness::Friendly:
			Status = LOCTEXT("Friendly", "FRIENDLY");
			break;
		case EFlareSectorFriendlyness::Contested:
			Status = LOCTEXT("Contested", "CONTESTED");
			break;
		case EFlareSectorFriendlyness::Hostile:
			Status = LOCTEXT("Hostile", "HOSTILE");
			break;
	}

	return Status;
}

FLinearColor UFlareSectorInterface::GetSectorFriendlynessColor(UFlareCompany* Company)
{
	FLinearColor Color;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	switch (GetSectorFriendlyness(Company))
	{
		case EFlareSectorFriendlyness::NotVisited:
			Color = Theme.UnknownColor;
			break;
		case EFlareSectorFriendlyness::Neutral:
			Color = Theme.NeutralColor;
			break;
		case EFlareSectorFriendlyness::Friendly:
			Color = Theme.FriendlyColor;
			break;
		case EFlareSectorFriendlyness::Contested:
			Color = Theme.DisputedColor;
			break;
		case EFlareSectorFriendlyness::Hostile:
			Color = Theme.EnemyColor;
			break;
	}

	return Color;
}

uint32 UFlareSectorInterface::GetResourcePrice(FFlareResourceDescription* Resource)
{
	// DEBUGInflation
	float Inflation = 1.5;

	// TODO better
	if (Resource->Identifier == "h2")
	{
		return 25 * Inflation;
	}
	else if (Resource->Identifier == "feo")
	{
		return 100 * Inflation;
	}
	else if (Resource->Identifier == "ch4")
	{
		return 50 * Inflation;
	}
	else if (Resource->Identifier == "sio2")
	{
		return 100 * Inflation;
	}
	else if (Resource->Identifier == "he3")
	{
		return 100 * Inflation;
	}
	else if (Resource->Identifier == "h2o")
	{
		return 250 * Inflation;
	}
	else if (Resource->Identifier == "steel")
	{
		return 500 * Inflation;
	}
	else if (Resource->Identifier == "c")
	{
		return 300 * Inflation;
	}
	else if (Resource->Identifier == "plastics")
	{
		return 300 * Inflation;
	}
	else if (Resource->Identifier == "fleet-supply")
	{
		return 1800 * Inflation;
	}
	else if (Resource->Identifier == "food")
	{
		return 600 * Inflation;
	}
	else if (Resource->Identifier == "fuel")
	{
		return 260 * Inflation;
	}
	else if (Resource->Identifier == "tools")
	{
		return 1000 * Inflation;
	}
	else if (Resource->Identifier == "tech")
	{
		return 1300 * Inflation;

	}
	else
	{
		FLOGV("Unknown resource %s", *Resource->Identifier.ToString());
		return 0;
	}

}

bool UFlareSectorInterface::CanUpgrade(UFlareCompany* Company)
{
	EFlareSectorBattleState::Type BattleState = GetSectorBattleState(Company);
	if(BattleState != EFlareSectorBattleState::NoBattle
			&& BattleState != EFlareSectorBattleState::BattleWon)
	{
		return false;
	}

	for(int StationIndex = 0 ; StationIndex < GetSectorStationInterfaces().Num(); StationIndex ++ )
	{
		IFlareSpacecraftInterface* StationInterface = GetSectorStationInterfaces()[StationIndex];
		if (StationInterface->GetCompany()->GetWarState(Company) != EFlareHostility::Hostile)
		{
			return true;
		}
	}

	return false;
}

#undef LOCTEXT_NAMESPACE
<commit_msg>Refactor static prices to ensure positive margins<commit_after>#include "../Flare.h"
#include "FlareSectorInterface.h"
#include "FlareSimulatedSector.h"
#include "../Spacecrafts/FlareSpacecraftInterface.h"

#define LOCTEXT_NAMESPACE "FlareSectorInterface"

/*----------------------------------------------------
	Constructor
----------------------------------------------------*/

UFlareSectorInterface::UFlareSectorInterface(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{
}

FText UFlareSectorInterface::GetSectorName()
{
	if (SectorData.GivenName.ToString().Len())
	{
		return SectorData.GivenName;
	}
	else if (SectorDescription->Name.ToString().Len())
	{
		return SectorDescription->Name;
	}
	else
	{
		return FText::FromString(GetSectorCode());
	}
}

FString UFlareSectorInterface::GetSectorCode()
{
	// TODO cache ?
	return SectorOrbitParameters.CelestialBodyIdentifier.ToString() + "-" + FString::FromInt(SectorOrbitParameters.Altitude) + "-" + FString::FromInt(SectorOrbitParameters.Phase);
}

EFlareSectorFriendlyness::Type UFlareSectorInterface::GetSectorFriendlyness(UFlareCompany* Company)
{
	if (!Company->HasVisitedSector(GetSimulatedSector()))
	{
		return EFlareSectorFriendlyness::NotVisited;
	}

	if (GetSimulatedSector()->GetSectorSpacecrafts().Num() == 0)
	{
		return EFlareSectorFriendlyness::Neutral;
	}

	int HostileSpacecraftCount = 0;
	int NeutralSpacecraftCount = 0;
	int FriendlySpacecraftCount = 0;

	for (int SpacecraftIndex = 0 ; SpacecraftIndex < GetSimulatedSector()->GetSectorSpacecrafts().Num(); SpacecraftIndex++)
	{
		UFlareCompany* OtherCompany = GetSimulatedSector()->GetSectorSpacecrafts()[SpacecraftIndex]->GetCompany();

		if (OtherCompany == Company)
		{
			FriendlySpacecraftCount++;
		}
		else if (OtherCompany->GetWarState(Company) == EFlareHostility::Hostile)
		{
			HostileSpacecraftCount++;
		}
		else
		{
			NeutralSpacecraftCount++;
		}
	}

	if (FriendlySpacecraftCount > 0 && HostileSpacecraftCount > 0)
	{
		return EFlareSectorFriendlyness::Contested;
	}

	if (FriendlySpacecraftCount > 0)
	{
		return EFlareSectorFriendlyness::Friendly;
	}
	else if (HostileSpacecraftCount > 0)
	{
		return EFlareSectorFriendlyness::Hostile;
	}
	else
	{
		return EFlareSectorFriendlyness::Neutral;
	}
}

EFlareSectorBattleState::Type UFlareSectorInterface::GetSectorBattleState(UFlareCompany* Company)
{

	if (GetSectorShipInterfaces().Num() == 0)
	{
		return EFlareSectorBattleState::NoBattle;
	}

	int HostileSpacecraftCount = 0;
	int DangerousHostileSpacecraftCount = 0;

	int FriendlySpacecraftCount = 0;
	int DangerousFriendlySpacecraftCount = 0;
	int CrippledFriendlySpacecraftCount = 0;

	for (int SpacecraftIndex = 0 ; SpacecraftIndex < GetSectorShipInterfaces().Num(); SpacecraftIndex++)
	{

		IFlareSpacecraftInterface* Spacecraft = GetSectorShipInterfaces()[SpacecraftIndex];

		UFlareCompany* OtherCompany = Spacecraft->GetCompany();

		if (!Spacecraft->GetDamageSystem()->IsAlive())
		{
			continue;
		}

		if (OtherCompany == Company)
		{
			FriendlySpacecraftCount++;
			if (Spacecraft->GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Weapon) > 0)
			{
				DangerousFriendlySpacecraftCount++;
			}

			if (Spacecraft->GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Propulsion) == 0)
			{
				CrippledFriendlySpacecraftCount++;
			}
		}
		else if (OtherCompany->GetWarState(Company) == EFlareHostility::Hostile)
		{
			HostileSpacecraftCount++;
			if (Spacecraft->GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Weapon) > 0)
			{
				DangerousHostileSpacecraftCount++;
			}
		}
	}

	// No friendly or no hostile ship
	if (FriendlySpacecraftCount == 0 || HostileSpacecraftCount == 0)
	{
		return EFlareSectorBattleState::NoBattle;
	}

	// No friendly and hostile ship are not dangerous
	if (DangerousFriendlySpacecraftCount == 0 && DangerousHostileSpacecraftCount == 0)
	{
		return EFlareSectorBattleState::NoBattle;
	}

	// No friendly dangerous ship so the enemy have one. Battle is lost
	if (DangerousFriendlySpacecraftCount == 0)
	{
		if (CrippledFriendlySpacecraftCount == FriendlySpacecraftCount)
		{
			return EFlareSectorBattleState::BattleLostNoRetreat;
		}
		else
		{
			return EFlareSectorBattleState::BattleLost;
		}
	}

	if (DangerousHostileSpacecraftCount == 0)
	{
		return EFlareSectorBattleState::BattleWon;
	}

	if (CrippledFriendlySpacecraftCount == FriendlySpacecraftCount)
	{
		return EFlareSectorBattleState::BattleNoRetreat;
	}
	else
	{
		return EFlareSectorBattleState::Battle;
	}
}

FText UFlareSectorInterface::GetSectorFriendlynessText(UFlareCompany* Company)
{
	FText Status;

	switch (GetSectorFriendlyness(Company))
	{
		case EFlareSectorFriendlyness::NotVisited:
			Status = LOCTEXT("Unknown", "UNKNOWN");
			break;
		case EFlareSectorFriendlyness::Neutral:
			Status = LOCTEXT("Neutral", "NEUTRAL");
			break;
		case EFlareSectorFriendlyness::Friendly:
			Status = LOCTEXT("Friendly", "FRIENDLY");
			break;
		case EFlareSectorFriendlyness::Contested:
			Status = LOCTEXT("Contested", "CONTESTED");
			break;
		case EFlareSectorFriendlyness::Hostile:
			Status = LOCTEXT("Hostile", "HOSTILE");
			break;
	}

	return Status;
}

FLinearColor UFlareSectorInterface::GetSectorFriendlynessColor(UFlareCompany* Company)
{
	FLinearColor Color;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	switch (GetSectorFriendlyness(Company))
	{
		case EFlareSectorFriendlyness::NotVisited:
			Color = Theme.UnknownColor;
			break;
		case EFlareSectorFriendlyness::Neutral:
			Color = Theme.NeutralColor;
			break;
		case EFlareSectorFriendlyness::Friendly:
			Color = Theme.FriendlyColor;
			break;
		case EFlareSectorFriendlyness::Contested:
			Color = Theme.DisputedColor;
			break;
		case EFlareSectorFriendlyness::Hostile:
			Color = Theme.EnemyColor;
			break;
	}

	return Color;
}

uint32 UFlareSectorInterface::GetResourcePrice(FFlareResourceDescription* Resource)
{
	// DEBUGInflation
	float Margin = 1.2;

	// Raw
	static float H2Price = 25 * Margin;
	static float FeoPrice = 100 * Margin;
	static float Ch4Price = 50 * Margin;
	static float Sio2Price = 100 * Margin;
	static float He3Price = 100 * Margin;
	static float H2oPrice = 250 * Margin;

	// Product
	static float FuelPrice = (H2oPrice + 10) * Margin;
	static float EnergyPrice = FuelPrice - H2oPrice;
	static float SteelPrice = (2 * FeoPrice + 4 * H2oPrice + EnergyPrice * 2 - 2 * H2oPrice + 100) * Margin;
	static float CPrice = (Ch4Price + 5 * EnergyPrice + 50) * Margin;
	static float PlasticPrice = (Ch4Price + 5 * EnergyPrice + 50) * Margin;
	static float FSPrice = (SteelPrice + 2 * PlasticPrice + FuelPrice + 10 * EnergyPrice + 100) * Margin;
	static float FoodPrice = (5 * CPrice + FuelPrice + 49 * EnergyPrice + 500) / 5.0 * Margin;
	static float ToolsPrice = (SteelPrice + PlasticPrice + 10 * EnergyPrice + 100) * Margin;
	static float TechPrice = (2 * Sio2Price + 4 * H2Price + 50 * EnergyPrice - 2 * H2oPrice + 500) * Margin;

	// TODO better
	if (Resource->Identifier == "h2")
	{
		return H2Price;
	}
	else if (Resource->Identifier == "feo")
	{
		return FeoPrice;
	}
	else if (Resource->Identifier == "ch4")
	{
		return Ch4Price;
	}
	else if (Resource->Identifier == "sio2")
	{
		return Sio2Price;
	}
	else if (Resource->Identifier == "he3")
	{
		return He3Price;
	}
	else if (Resource->Identifier == "h2o")
	{
		return H2oPrice;
	}
	else if (Resource->Identifier == "steel")
	{
		return SteelPrice;
	}
	else if (Resource->Identifier == "c")
	{
		return CPrice;
	}
	else if (Resource->Identifier == "plastics")
	{
		return PlasticPrice;
	}
	else if (Resource->Identifier == "fleet-supply")
	{
		return FSPrice;
	}
	else if (Resource->Identifier == "food")
	{
		return FoodPrice;
	}
	else if (Resource->Identifier == "fuel")
	{
		return FuelPrice;
	}
	else if (Resource->Identifier == "tools")
	{
		return ToolsPrice;
	}
	else if (Resource->Identifier == "tech")
	{
		return TechPrice;

	}
	else
	{
		FLOGV("Unknown resource %s", *Resource->Identifier.ToString());
		return 0;
	}

}

bool UFlareSectorInterface::CanUpgrade(UFlareCompany* Company)
{
	EFlareSectorBattleState::Type BattleState = GetSectorBattleState(Company);
	if(BattleState != EFlareSectorBattleState::NoBattle
			&& BattleState != EFlareSectorBattleState::BattleWon)
	{
		return false;
	}

	for(int StationIndex = 0 ; StationIndex < GetSectorStationInterfaces().Num(); StationIndex ++ )
	{
		IFlareSpacecraftInterface* StationInterface = GetSectorStationInterfaces()[StationIndex];
		if (StationInterface->GetCompany()->GetWarState(Company) != EFlareHostility::Hostile)
		{
			return true;
		}
	}

	return false;
}

#undef LOCTEXT_NAMESPACE
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     frequencyspectrummodel.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     May, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Implementation of the FrequencySpectrumModel Class.
*
*/

#include "frequencyspectrummodel.h"

#include <QDebug>
#include <QBrush>
#include <QThread>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace XDISPLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

FrequencySpectrumModel::FrequencySpectrumModel(QObject *parent)
: QAbstractTableModel(parent)
, m_fSps(1024.0f)
, m_iT(10)
, m_bIsFreezed(false)
{
}

//*************************************************************************************************************
//virtual functions
int FrequencySpectrumModel::rowCount(const QModelIndex & /*parent*/) const
{
    if(!m_qMapIdxRowSelection.empty())
        return m_qMapIdxRowSelection.size();
    else
        return 0;
}

//*************************************************************************************************************

int FrequencySpectrumModel::columnCount(const QModelIndex & /*parent*/) const
{
    return 2;
}

//*************************************************************************************************************

QVariant FrequencySpectrumModel::data(const QModelIndex &index, int role) const
{
    if(role != Qt::DisplayRole && role != Qt::BackgroundRole)
        return QVariant();

    if (index.isValid()) {
        qint32 r = m_qMapIdxRowSelection[index.row()];

        //******** first column (chname) ********
        if(index.column() == 0 && role == Qt::DisplayRole)
            if(m_pFiffInfo)
                return QVariant(m_pFiffInfo->chs[r].ch_name);

        //******** second column (data plot) ********
        if(index.column()==1) {
            QVariant v;

            switch(role) {
                case Qt::DisplayRole: {
                    //pack all adjacent (after reload) RowVectorPairs into a QList
                    RowVectorXd vec;

                    if(m_bIsFreezed)
                    {
                        // data freeze
                        vec = m_dataCurrentFreeze.row(r);
                        v.setValue(vec);
                    }
                    else
                    {
                        // data
                        vec = m_dataCurrent.row(r);
                        v.setValue(vec);
                    }
                    return v;
                    break;
                }
                case Qt::BackgroundRole: {
//                    if(m_fiffInfo.bads.contains(m_chInfolist[row].ch_name)) {
//                        QBrush brush;
//                        brush.setStyle(Qt::SolidPattern);
//    //                    qDebug() << m_chInfolist[row].ch_name << "is marked as bad, index:" << row;
//                        brush.setColor(Qt::red);
//                        return QVariant(brush);
//                    }
//                    else
                        return QVariant();

                    break;
                }
            } // end role switch
        } // end column check

    } // end index.valid() check

    return QVariant();
}

//*************************************************************************************************************

QVariant FrequencySpectrumModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role != Qt::DisplayRole && role != Qt::TextAlignmentRole)
        return QVariant();

    if(orientation == Qt::Horizontal) {
        switch(section) {
        case 0: //chname column
            return QVariant();
        case 1: //data plot column
            return QVariant("data plot");
            switch(role) {
            case Qt::DisplayRole:
                return QVariant("data plot");
            case Qt::TextAlignmentRole:
                return QVariant(Qt::AlignLeft);
            }
        }
    }
    else if(orientation == Qt::Vertical) {
        QModelIndex chname = createIndex(section,0);
        switch(role) {
        case Qt::DisplayRole:
            return QVariant(data(chname).toString());
        }
    }

    return QVariant();
}

//*************************************************************************************************************

void FrequencySpectrumModel::setInfo(FiffInfo::SPtr &info)
{
    beginResetModel();
    m_pFiffInfo = info;
    endResetModel();

    resetSelection();
}

//*************************************************************************************************************

void FrequencySpectrumModel::addData(const MatrixXd &data)
{
    m_dataCurrent = data;

    if(m_vecFreqScale.size() != m_dataCurrent.cols() && m_pFiffInfo)
    {
        double freqRes = (m_pFiffInfo->sfreq/2) / m_dataCurrent.cols();
        double k = 1.0;
        m_vecFreqScale.resize(1,m_dataCurrent.cols());

        double currFreq = freqRes;
        for(qint32 i = 0; i < m_dataCurrent.cols(); ++i)
        {
            m_vecFreqScale[i] = log10(currFreq+k);
            currFreq += freqRes;
        }

        double max = m_vecFreqScale.maxCoeff();
        m_vecFreqScale /= max;
    }

    //Update data content
    QModelIndex topLeft = this->index(0,1);
    QModelIndex bottomRight = this->index(m_dataCurrent.rows()-1,1);
    QVector<int> roles; roles << Qt::DisplayRole;
    emit dataChanged(topLeft, bottomRight, roles);
}

//*************************************************************************************************************

void FrequencySpectrumModel::selectRows(const QList<qint32> &selection)
{
    beginResetModel();

    m_qMapIdxRowSelection.clear();

    qint32 count = 0;
    for(qint32 i = 0; i < selection.size(); ++i)
    {
        if(selection[i] < m_pFiffInfo->chs.size())
        {
            m_qMapIdxRowSelection.insert(count,selection[i]);
            ++count;
        }
    }

    emit newSelection(selection);

    endResetModel();
}

//*************************************************************************************************************

void FrequencySpectrumModel::resetSelection()
{
    beginResetModel();

    m_qMapIdxRowSelection.clear();

    for(qint32 i = 0; i < m_pFiffInfo->chs.size(); ++i)
        m_qMapIdxRowSelection.insert(i,i);

    endResetModel();
}

//*************************************************************************************************************

void FrequencySpectrumModel::toggleFreeze(const QModelIndex &)
{
    m_bIsFreezed = !m_bIsFreezed;

    if(m_bIsFreezed)
        m_dataCurrentFreeze = m_dataCurrent;

    //Update data content
    QModelIndex topLeft = this->index(0,1);
    QModelIndex bottomRight = this->index(m_dataCurrent.rows()-1,1);
    QVector<int> roles; roles << Qt::DisplayRole;
    emit dataChanged(topLeft, bottomRight, roles);
}
<commit_msg>frequency fix<commit_after>//=============================================================================================================
/**
* @file     frequencyspectrummodel.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     May, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Implementation of the FrequencySpectrumModel Class.
*
*/

#include "frequencyspectrummodel.h"

#include <QDebug>
#include <QBrush>
#include <QThread>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace XDISPLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

FrequencySpectrumModel::FrequencySpectrumModel(QObject *parent)
: QAbstractTableModel(parent)
, m_fSps(1024.0f)
, m_iT(10)
, m_bIsFreezed(false)
{
}

//*************************************************************************************************************
//virtual functions
int FrequencySpectrumModel::rowCount(const QModelIndex & /*parent*/) const
{
    if(!m_qMapIdxRowSelection.empty())
        return m_qMapIdxRowSelection.size();
    else
        return 0;
}

//*************************************************************************************************************

int FrequencySpectrumModel::columnCount(const QModelIndex & /*parent*/) const
{
    return 2;
}

//*************************************************************************************************************

QVariant FrequencySpectrumModel::data(const QModelIndex &index, int role) const
{
    if(role != Qt::DisplayRole && role != Qt::BackgroundRole)
        return QVariant();

    if (index.isValid()) {
        qint32 r = m_qMapIdxRowSelection[index.row()];

        //******** first column (chname) ********
        if(index.column() == 0 && role == Qt::DisplayRole)
            if(m_pFiffInfo)
                return QVariant(m_pFiffInfo->chs[r].ch_name);

        //******** second column (data plot) ********
        if(index.column()==1) {
            QVariant v;

            switch(role) {
                case Qt::DisplayRole: {
                    //pack all adjacent (after reload) RowVectorPairs into a QList
                    RowVectorXd vec;

                    if(m_bIsFreezed)
                    {
                        // data freeze
                        vec = m_dataCurrentFreeze.row(r);
                        v.setValue(vec);
                    }
                    else
                    {
                        // data
                        vec = m_dataCurrent.row(r);
                        v.setValue(vec);
                    }
                    return v;
                    break;
                }
                case Qt::BackgroundRole: {
//                    if(m_fiffInfo.bads.contains(m_chInfolist[row].ch_name)) {
//                        QBrush brush;
//                        brush.setStyle(Qt::SolidPattern);
//    //                    qDebug() << m_chInfolist[row].ch_name << "is marked as bad, index:" << row;
//                        brush.setColor(Qt::red);
//                        return QVariant(brush);
//                    }
//                    else
                        return QVariant();

                    break;
                }
            } // end role switch
        } // end column check

    } // end index.valid() check

    return QVariant();
}

//*************************************************************************************************************

QVariant FrequencySpectrumModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role != Qt::DisplayRole && role != Qt::TextAlignmentRole)
        return QVariant();

    if(orientation == Qt::Horizontal) {
        switch(section) {
        case 0: //chname column
            return QVariant();
        case 1: //data plot column
            return QVariant("data plot");
            switch(role) {
            case Qt::DisplayRole:
                return QVariant("data plot");
            case Qt::TextAlignmentRole:
                return QVariant(Qt::AlignLeft);
            }
        }
    }
    else if(orientation == Qt::Vertical) {
        QModelIndex chname = createIndex(section,0);
        switch(role) {
        case Qt::DisplayRole:
            return QVariant(data(chname).toString());
        }
    }

    return QVariant();
}

//*************************************************************************************************************

void FrequencySpectrumModel::setInfo(FiffInfo::SPtr &info)
{
    beginResetModel();
    m_pFiffInfo = info;
    endResetModel();

    resetSelection();
}

//*************************************************************************************************************

void FrequencySpectrumModel::addData(const MatrixXd &data)
{
    m_dataCurrent = data;

    if(m_vecFreqScale.size() != m_dataCurrent.cols() && m_pFiffInfo)
    {
        double freqRes = (m_pFiffInfo->sfreq/2) / m_dataCurrent.cols();
        double k = 1.0;
        m_vecFreqScale.resize(1,m_dataCurrent.cols());

        double currFreq = 0;
        for(qint32 i = 0; i < m_dataCurrent.cols(); ++i)
        {
            m_vecFreqScale[i] = log10(currFreq+k);
            currFreq += freqRes;
        }

        double max = m_vecFreqScale.maxCoeff();
        m_vecFreqScale /= max;
    }

    //Update data content
    QModelIndex topLeft = this->index(0,1);
    QModelIndex bottomRight = this->index(m_dataCurrent.rows()-1,1);
    QVector<int> roles; roles << Qt::DisplayRole;
    emit dataChanged(topLeft, bottomRight, roles);
}

//*************************************************************************************************************

void FrequencySpectrumModel::selectRows(const QList<qint32> &selection)
{
    beginResetModel();

    m_qMapIdxRowSelection.clear();

    qint32 count = 0;
    for(qint32 i = 0; i < selection.size(); ++i)
    {
        if(selection[i] < m_pFiffInfo->chs.size())
        {
            m_qMapIdxRowSelection.insert(count,selection[i]);
            ++count;
        }
    }

    emit newSelection(selection);

    endResetModel();
}

//*************************************************************************************************************

void FrequencySpectrumModel::resetSelection()
{
    beginResetModel();

    m_qMapIdxRowSelection.clear();

    for(qint32 i = 0; i < m_pFiffInfo->chs.size(); ++i)
        m_qMapIdxRowSelection.insert(i,i);

    endResetModel();
}

//*************************************************************************************************************

void FrequencySpectrumModel::toggleFreeze(const QModelIndex &)
{
    m_bIsFreezed = !m_bIsFreezed;

    if(m_bIsFreezed)
        m_dataCurrentFreeze = m_dataCurrent;

    //Update data content
    QModelIndex topLeft = this->index(0,1);
    QModelIndex bottomRight = this->index(m_dataCurrent.rows()-1,1);
    QVector<int> roles; roles << Qt::DisplayRole;
    emit dataChanged(topLeft, bottomRight, roles);
}
<|endoftext|>


<commit_before>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2006
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id$"
*
* who       when      what
* --------  --------  ----------------------------------------------
* acaproni  2006-07-12  created
*/

#include "vltPort.h"

#include <iostream>

#include "ConfigPropertyGetter.h"
#include <acsutilORBHelper.h>
#include <cdb.h>
#include <cdbDALaccess.h>
#include <cdbErrType.h>

// The following defines, remeber what we'are parsing
#define NO_TAG		0
#define PROP_TAG	1

typedef struct {
	// The list of the properties
	std::list<Property>* props;
	// The name of the property
	std::string pName;
	// The tag we're parsing (see defines above)
    short actualTag;
} ParserStruct;

ConfigPropertyGetter::ConfigPropertyGetter(maci::Manager_ptr manager):m_properties(NULL)
{
	m_dao = getDAO(manager);
	if (m_dao.size()>0) {
		parseDAO();
	}
}

ConfigPropertyGetter::~ConfigPropertyGetter() {
	if (m_properties!=NULL) {
		m_properties->clear();
		m_properties=NULL;
	}
}

std::string ConfigPropertyGetter::getDAO(maci::Manager_ptr manager) {
    CDB::DAL_var cdbDAL;
    CORBA::Object_var cdb;

    try
	{
	cdb = manager->get_service(0, "CDB", true);
	if (CORBA::is_nil(cdb.in()))
	    {
	    throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(__FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	    }
	}
    catch(maciErrType::CannotGetComponentEx &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(ex, __FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
    catch(maciErrType::ComponentNotAlreadyActivatedEx &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(ex, __FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
	  catch(maciErrType::ComponentConfigurationNotFoundEx &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(ex, __FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
    catch(CORBA::Exception &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(__FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
    catch(...)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(__FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}//try-catch

    cdbDAL = CDB::DAL::_narrow(cdb.in());

    DALaccess::forceDAL(cdbDAL.in());

    // Get the DAO
    try {
        return cdbDAL->get_DAO("Alarms/AlarmSystemConfiguration");
    } catch (cdbErrType::CDBRecordDoesNotExistEx) {
        return "";
    }
}

void ConfigPropertyGetter::parseDAO() {
	if (m_dao.size()==0) {
		return;
	}
	XML_Parser p = XML_ParserCreate(NULL);
    if (! p)
        {
        return ;
        }

    //Connect to the parser the handler for the end and the start of a tag
    XML_SetElementHandler(p, start_hndl, end_hndl);

	m_properties = new std::list<Property>();
	ParserStruct commonData;
	commonData.props=m_properties;
	commonData.actualTag=NO_TAG;

    // Connect the char handler
    XML_SetCharacterDataHandler(p,char_hndl);

    XML_SetUserData(p,&commonData);

    // We have all the xml in the string so we parse all the document
    // with just one call
    if (XML_Parse(p,m_dao.c_str(),m_dao.size(),TRUE)==0)
        {
		return;
        }
        // Release the memory used by the parser
    XML_ParserFree(p);
    m_properties = commonData.props;
}

std::string ConfigPropertyGetter::getProperty(std::string propName) {
	if (m_properties==NULL || propName.size()==0) {
		return "";
	}
	std::list<Property>::iterator iter;
	for (iter=m_properties->begin(); iter!=m_properties->end(); iter++) {
		Property p = (*iter);
		if (p.key==propName) {
			return p.value;
		}
	}
	return "";
}

void ConfigPropertyGetter::start_hndl(void *data, const XML_Char *el, const XML_Char **attr) {
	ParserStruct* ps = (ParserStruct*)data;
	if (strcmp(el,"configuration-property")==0) {
		ps->actualTag=PROP_TAG;
        ps->pName=(char*)attr[1];
	}
}

void ConfigPropertyGetter::end_hndl(void *data, const XML_Char *el) {
	ParserStruct* ps = (ParserStruct*)data;
	ps->actualTag=NO_TAG;
}

void ConfigPropertyGetter::char_hndl(void *data, const XML_Char *s, int len) {
	ParserStruct* ps = (ParserStruct*)data;

	if (ps->actualTag==PROP_TAG) {
		Property p;
		p.key=ps->pName;
		for (int t=0; t<len; t++) {
			p.value+=s[t];
		}
		ps->props->push_back(p);
	}
}

<commit_msg>The path of the alarm configuration file in the CDB has changed.<commit_after>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2006
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id$"
*
* who       when      what
* --------  --------  ----------------------------------------------
* acaproni  2006-07-12  created
*/

#include "vltPort.h"

#include <iostream>

#include "ConfigPropertyGetter.h"
#include <acsutilORBHelper.h>
#include <cdb.h>
#include <cdbDALaccess.h>
#include <cdbErrType.h>

// The following defines, remeber what we'are parsing
#define NO_TAG		0
#define PROP_TAG	1

typedef struct {
	// The list of the properties
	std::list<Property>* props;
	// The name of the property
	std::string pName;
	// The tag we're parsing (see defines above)
    short actualTag;
} ParserStruct;

ConfigPropertyGetter::ConfigPropertyGetter(maci::Manager_ptr manager):m_properties(NULL)
{
	m_dao = getDAO(manager);
	if (m_dao.size()>0) {
		parseDAO();
	}
}

ConfigPropertyGetter::~ConfigPropertyGetter() {
	if (m_properties!=NULL) {
		m_properties->clear();
		m_properties=NULL;
	}
}

std::string ConfigPropertyGetter::getDAO(maci::Manager_ptr manager) {
    CDB::DAL_var cdbDAL;
    CORBA::Object_var cdb;

    try
	{
	cdb = manager->get_service(0, "CDB", true);
	if (CORBA::is_nil(cdb.in()))
	    {
	    throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(__FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	    }
	}
    catch(maciErrType::CannotGetComponentEx &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(ex, __FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
    catch(maciErrType::ComponentNotAlreadyActivatedEx &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(ex, __FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
	  catch(maciErrType::ComponentConfigurationNotFoundEx &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(ex, __FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
    catch(CORBA::Exception &ex)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(__FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}
    catch(...)
	{
	throw acsErrTypeAlarmSourceFactory::ErrorGettingDALExImpl(__FILE__,__LINE__,"ConfigPropertyGetter::getDAO");
	}//try-catch

    cdbDAL = CDB::DAL::_narrow(cdb.in());

    DALaccess::forceDAL(cdbDAL.in());

    // Get the DAO
    try {
        return cdbDAL->get_DAO("Alarms/Administrative/AlarmSystemConfiguration");
    } catch (cdbErrType::CDBRecordDoesNotExistEx) {
        return "";
    }
}

void ConfigPropertyGetter::parseDAO() {
	if (m_dao.size()==0) {
		return;
	}
	XML_Parser p = XML_ParserCreate(NULL);
    if (! p)
        {
        return ;
        }

    //Connect to the parser the handler for the end and the start of a tag
    XML_SetElementHandler(p, start_hndl, end_hndl);

	m_properties = new std::list<Property>();
	ParserStruct commonData;
	commonData.props=m_properties;
	commonData.actualTag=NO_TAG;

    // Connect the char handler
    XML_SetCharacterDataHandler(p,char_hndl);

    XML_SetUserData(p,&commonData);

    // We have all the xml in the string so we parse all the document
    // with just one call
    if (XML_Parse(p,m_dao.c_str(),m_dao.size(),TRUE)==0)
        {
		return;
        }
        // Release the memory used by the parser
    XML_ParserFree(p);
    m_properties = commonData.props;
}

std::string ConfigPropertyGetter::getProperty(std::string propName) {
	if (m_properties==NULL || propName.size()==0) {
		return "";
	}
	std::list<Property>::iterator iter;
	for (iter=m_properties->begin(); iter!=m_properties->end(); iter++) {
		Property p = (*iter);
		if (p.key==propName) {
			return p.value;
		}
	}
	return "";
}

void ConfigPropertyGetter::start_hndl(void *data, const XML_Char *el, const XML_Char **attr) {
	ParserStruct* ps = (ParserStruct*)data;
	if (strcmp(el,"configuration-property")==0) {
		ps->actualTag=PROP_TAG;
        ps->pName=(char*)attr[1];
	}
}

void ConfigPropertyGetter::end_hndl(void *data, const XML_Char *el) {
	ParserStruct* ps = (ParserStruct*)data;
	ps->actualTag=NO_TAG;
}

void ConfigPropertyGetter::char_hndl(void *data, const XML_Char *s, int len) {
	ParserStruct* ps = (ParserStruct*)data;

	if (ps->actualTag==PROP_TAG) {
		Property p;
		p.key=ps->pName;
		for (int t=0; t<len; t++) {
			p.value+=s[t];
		}
		ps->props->push_back(p);
	}
}

<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include <mitkContourModelUtils.h>

#include <mitkContourModelToSurfaceFilter.h>
#include <mitkLabelSetImage.h>
#include <mitkSurface.h>
#include <vtkImageStencil.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataToImageStencil.h>

mitk::ContourModelUtils::ContourModelUtils()
{
}

mitk::ContourModelUtils::~ContourModelUtils()
{
}

mitk::ContourModel::Pointer mitk::ContourModelUtils::ProjectContourTo2DSlice(
  const Image *slice, const ContourModel *contourIn3D, bool, bool)
{
  if (nullptr == slice || nullptr == contourIn3D)
    return nullptr;

  auto projectedContour = ContourModel::New();
  projectedContour->Initialize(*contourIn3D);

  auto sliceGeometry = slice->GetGeometry();
  auto numberOfTimesteps = static_cast<TimeStepType>(contourIn3D->GetTimeSteps());

  for (decltype(numberOfTimesteps) t = 0; t < numberOfTimesteps; ++t)
  {
    auto iter = contourIn3D->Begin(t);
    auto end = contourIn3D->End(t);

    while (iter != end)
    {
      const auto &currentPointIn3D = (*iter)->Coordinates;

      Point3D projectedPointIn2D;
      projectedPointIn2D.Fill(0.0);

      sliceGeometry->WorldToIndex(currentPointIn3D, projectedPointIn2D);

      projectedContour->AddVertex(projectedPointIn2D, t);
      ++iter;
    }
  }

  return projectedContour;
}

mitk::ContourModel::Pointer mitk::ContourModelUtils::BackProjectContourFrom2DSlice(
  const BaseGeometry *sliceGeometry, const ContourModel *contourIn2D, bool)
{
  if (nullptr == sliceGeometry || nullptr == contourIn2D)
    return nullptr;

  auto worldContour = ContourModel::New();
  worldContour->Initialize(*contourIn2D);

  auto numberOfTimesteps = static_cast<TimeStepType>(contourIn2D->GetTimeSteps());

  for (decltype(numberOfTimesteps) t = 0; t < numberOfTimesteps; ++t)
  {
    auto iter = contourIn2D->Begin(t);
    auto end = contourIn2D->End(t);

    while (iter != end)
    {
      const auto &currentPointIn2D = (*iter)->Coordinates;

      Point3D worldPointIn3D;
      worldPointIn3D.Fill(0.0);

      sliceGeometry->IndexToWorld(currentPointIn2D, worldPointIn3D);

      worldContour->AddVertex(worldPointIn3D, t);
      ++iter;
    }
  }

  return worldContour;
}

void mitk::ContourModelUtils::FillContourInSlice(
  const ContourModel *projectedContour, Image *sliceImage, const Image* workingImage, int paintingPixelValue)
{
  FillContourInSlice(projectedContour, 0, sliceImage, workingImage, paintingPixelValue);
}

void mitk::ContourModelUtils::FillContourInSlice(
  const ContourModel *projectedContour, TimeStepType contourTimeStep, Image *sliceImage, const Image* workingImage, int paintingPixelValue)
{
  if (nullptr == projectedContour)
  {
    mitkThrow() << "Cannot fill contour in slice. Passed contour is invalid";
  }

  if (nullptr == sliceImage)
  {
    mitkThrow() << "Cannot fill contour in slice. Passed slice is invalid";
  }

  auto contourModelFilter = mitk::ContourModelToSurfaceFilter::New();
  contourModelFilter->SetInput(projectedContour);
  contourModelFilter->Update();

  auto surface = mitk::Surface::New();
  surface = contourModelFilter->GetOutput();

  if (nullptr == surface->GetVtkPolyData(contourTimeStep))
  {
    MITK_WARN << "Could not create surface from contour model.";
    return;
  }

  auto surface2D = vtkSmartPointer<vtkPolyData>::New();
  surface2D->SetPoints(surface->GetVtkPolyData(contourTimeStep)->GetPoints());
  surface2D->SetLines(surface->GetVtkPolyData(contourTimeStep)->GetLines());

  auto image = vtkSmartPointer<vtkImageData>::New();
  image->DeepCopy(sliceImage->GetVtkImageData());

  const double FOREGROUND_VALUE = 255.0;
  const double BACKGROUND_VALUE = 0.0;

  vtkIdType count = image->GetNumberOfPoints();
  for (decltype(count) i = 0; i < count; ++i)
    image->GetPointData()->GetScalars()->SetTuple1(i, FOREGROUND_VALUE);

  auto polyDataToImageStencil = vtkSmartPointer<vtkPolyDataToImageStencil>::New();

  // Set a minimal tolerance, so that clipped pixels will be added to contour as well.
  polyDataToImageStencil->SetTolerance(mitk::eps);
  polyDataToImageStencil->SetInputData(surface2D);
  polyDataToImageStencil->Update();

  auto imageStencil = vtkSmartPointer<vtkImageStencil>::New();

  imageStencil->SetInputData(image);
  imageStencil->SetStencilConnection(polyDataToImageStencil->GetOutputPort());
  imageStencil->ReverseStencilOff();
  imageStencil->SetBackgroundValue(BACKGROUND_VALUE);
  imageStencil->Update();

  vtkSmartPointer<vtkImageData> filledImage = imageStencil->GetOutput();
  vtkSmartPointer<vtkImageData> resultImage = sliceImage->GetVtkImageData();
  FillSliceInSlice(filledImage, resultImage, workingImage, paintingPixelValue);

  sliceImage->SetVolume(resultImage->GetScalarPointer());
}

void mitk::ContourModelUtils::FillSliceInSlice(
  vtkSmartPointer<vtkImageData> filledImage, vtkSmartPointer<vtkImageData> resultImage, const Image* image, int paintingPixelValue, double fillForegroundThreshold)
{
  auto labelImage = dynamic_cast<const LabelSetImage *>(image);
  const auto numberOfPoints = filledImage->GetNumberOfPoints();

  if (nullptr == labelImage)
  {
    for (auto i = decltype(numberOfPoints){0}; i < numberOfPoints; ++i)
    {
      if (fillForegroundThreshold <= filledImage->GetPointData()->GetScalars()->GetTuple1(i))
        resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
    }
  }
  else
  {
    const auto backgroundValue = labelImage->GetExteriorLabel()->GetValue();

    if (paintingPixelValue != backgroundValue)
    {
      for (auto i = decltype(numberOfPoints){0}; i < numberOfPoints; ++i)
      {
        const auto filledValue = filledImage->GetPointData()->GetScalars()->GetTuple1(i);
        if (fillForegroundThreshold <= filledValue)
        {
          const auto existingValue = resultImage->GetPointData()->GetScalars()->GetTuple1(i);

          if (!labelImage->GetLabel(existingValue, labelImage->GetActiveLayer())->GetLocked())
            resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
        }
      }
    }
    else
    {
      const auto activePixelValue = labelImage->GetActiveLabel(labelImage->GetActiveLayer())->GetValue();
      for (auto i = decltype(numberOfPoints){0}; i < numberOfPoints; ++i)
      {
        if (fillForegroundThreshold <= filledImage->GetPointData()->GetScalars()->GetTuple1(i))
        {
          if (resultImage->GetPointData()->GetScalars()->GetTuple1(i) == activePixelValue)
            resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
        }
      }
    }
  }
}

mitk::ContourModel::Pointer mitk::ContourModelUtils::MoveZerothContourTimeStep(const ContourModel *contour, TimeStepType t)
{
  if (nullptr == contour)
    return nullptr;

  auto resultContour = ContourModel::New();
  resultContour->Expand(t + 1);

  std::for_each(contour->Begin(), contour->End(), [&resultContour, t](ContourElement::VertexType *vertex) {
    resultContour->AddVertex(*vertex, t);
  });

  return resultContour;
}

int mitk::ContourModelUtils::GetActivePixelValue(const Image* workingImage)
{
  auto labelSetImage = dynamic_cast<const LabelSetImage*>(workingImage);
  int activePixelValue = 1;
  if (nullptr != labelSetImage)
  {
    activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
  }

  return activePixelValue;
}
<commit_msg>Fixed review feedback.<commit_after>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include <mitkContourModelUtils.h>

#include <mitkContourModelToSurfaceFilter.h>
#include <mitkLabelSetImage.h>
#include <mitkSurface.h>
#include <vtkImageStencil.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataToImageStencil.h>

mitk::ContourModelUtils::ContourModelUtils()
{
}

mitk::ContourModelUtils::~ContourModelUtils()
{
}

mitk::ContourModel::Pointer mitk::ContourModelUtils::ProjectContourTo2DSlice(
  const Image *slice, const ContourModel *contourIn3D, bool, bool)
{
  if (nullptr == slice || nullptr == contourIn3D)
    return nullptr;

  auto projectedContour = ContourModel::New();
  projectedContour->Initialize(*contourIn3D);

  auto sliceGeometry = slice->GetGeometry();
  const auto numberOfTimesteps = static_cast<TimeStepType>(contourIn3D->GetTimeSteps());

  for (std::remove_const_t<decltype(numberOfTimesteps)> t = 0; t < numberOfTimesteps; ++t)
  {
    auto iter = contourIn3D->Begin(t);
    auto end = contourIn3D->End(t);

    while (iter != end)
    {
      const auto &currentPointIn3D = (*iter)->Coordinates;

      Point3D projectedPointIn2D;
      projectedPointIn2D.Fill(0.0);

      sliceGeometry->WorldToIndex(currentPointIn3D, projectedPointIn2D);

      projectedContour->AddVertex(projectedPointIn2D, t);
      ++iter;
    }
  }

  return projectedContour;
}

mitk::ContourModel::Pointer mitk::ContourModelUtils::BackProjectContourFrom2DSlice(
  const BaseGeometry *sliceGeometry, const ContourModel *contourIn2D, bool)
{
  if (nullptr == sliceGeometry || nullptr == contourIn2D)
    return nullptr;

  auto worldContour = ContourModel::New();
  worldContour->Initialize(*contourIn2D);

  const auto numberOfTimesteps = static_cast<TimeStepType>(contourIn2D->GetTimeSteps());

  for (std::remove_const_t<decltype(numberOfTimesteps)> t = 0; t < numberOfTimesteps; ++t)
  {
    auto iter = contourIn2D->Begin(t);
    auto end = contourIn2D->End(t);

    while (iter != end)
    {
      const auto &currentPointIn2D = (*iter)->Coordinates;

      Point3D worldPointIn3D;
      worldPointIn3D.Fill(0.0);

      sliceGeometry->IndexToWorld(currentPointIn2D, worldPointIn3D);

      worldContour->AddVertex(worldPointIn3D, t);
      ++iter;
    }
  }

  return worldContour;
}

void mitk::ContourModelUtils::FillContourInSlice(
  const ContourModel *projectedContour, Image *sliceImage, const Image* workingImage, int paintingPixelValue)
{
  FillContourInSlice(projectedContour, 0, sliceImage, workingImage, paintingPixelValue);
}

void mitk::ContourModelUtils::FillContourInSlice(
  const ContourModel *projectedContour, TimeStepType contourTimeStep, Image *sliceImage, const Image* workingImage, int paintingPixelValue)
{
  if (nullptr == projectedContour)
  {
    mitkThrow() << "Cannot fill contour in slice. Passed contour is invalid";
  }

  if (nullptr == sliceImage)
  {
    mitkThrow() << "Cannot fill contour in slice. Passed slice is invalid";
  }

  auto contourModelFilter = mitk::ContourModelToSurfaceFilter::New();
  contourModelFilter->SetInput(projectedContour);
  contourModelFilter->Update();

  auto surface = mitk::Surface::New();
  surface = contourModelFilter->GetOutput();

  if (nullptr == surface->GetVtkPolyData(contourTimeStep))
  {
    MITK_WARN << "Could not create surface from contour model.";
    return;
  }

  auto surface2D = vtkSmartPointer<vtkPolyData>::New();
  surface2D->SetPoints(surface->GetVtkPolyData(contourTimeStep)->GetPoints());
  surface2D->SetLines(surface->GetVtkPolyData(contourTimeStep)->GetLines());

  auto image = vtkSmartPointer<vtkImageData>::New();
  image->DeepCopy(sliceImage->GetVtkImageData());

  const double FOREGROUND_VALUE = 255.0;
  const double BACKGROUND_VALUE = 0.0;

  const vtkIdType count = image->GetNumberOfPoints();
  for (std::remove_const_t<decltype(count)> i = 0; i < count; ++i)
    image->GetPointData()->GetScalars()->SetTuple1(i, FOREGROUND_VALUE);

  auto polyDataToImageStencil = vtkSmartPointer<vtkPolyDataToImageStencil>::New();

  // Set a minimal tolerance, so that clipped pixels will be added to contour as well.
  polyDataToImageStencil->SetTolerance(mitk::eps);
  polyDataToImageStencil->SetInputData(surface2D);
  polyDataToImageStencil->Update();

  auto imageStencil = vtkSmartPointer<vtkImageStencil>::New();

  imageStencil->SetInputData(image);
  imageStencil->SetStencilConnection(polyDataToImageStencil->GetOutputPort());
  imageStencil->ReverseStencilOff();
  imageStencil->SetBackgroundValue(BACKGROUND_VALUE);
  imageStencil->Update();

  vtkSmartPointer<vtkImageData> filledImage = imageStencil->GetOutput();
  vtkSmartPointer<vtkImageData> resultImage = sliceImage->GetVtkImageData();
  FillSliceInSlice(filledImage, resultImage, workingImage, paintingPixelValue);

  sliceImage->SetVolume(resultImage->GetScalarPointer());
}

void mitk::ContourModelUtils::FillSliceInSlice(
  vtkSmartPointer<vtkImageData> filledImage, vtkSmartPointer<vtkImageData> resultImage, const Image* image, int paintingPixelValue, double fillForegroundThreshold)
{
  auto labelImage = dynamic_cast<const LabelSetImage *>(image);
  const auto numberOfPoints = filledImage->GetNumberOfPoints();

  if (nullptr == labelImage)
  {
    for (std::remove_const_t<decltype(numberOfPoints)> i = 0; i < numberOfPoints; ++i)
    {
      if (fillForegroundThreshold <= filledImage->GetPointData()->GetScalars()->GetTuple1(i))
        resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
    }
  }
  else
  {
    const auto backgroundValue = labelImage->GetExteriorLabel()->GetValue();

    if (paintingPixelValue != backgroundValue)
    {
      for (std::remove_const_t<decltype(numberOfPoints)> i = 0; i < numberOfPoints; ++i)
      {
        const auto filledValue = filledImage->GetPointData()->GetScalars()->GetTuple1(i);
        if (fillForegroundThreshold <= filledValue)
        {
          const auto existingValue = resultImage->GetPointData()->GetScalars()->GetTuple1(i);

          if (!labelImage->GetLabel(existingValue, labelImage->GetActiveLayer())->GetLocked())
            resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
        }
      }
    }
    else
    {
      const auto activePixelValue = labelImage->GetActiveLabel(labelImage->GetActiveLayer())->GetValue();
      for (std::remove_const_t<decltype(numberOfPoints)> i = 0; i < numberOfPoints; ++i)
      {
        if (fillForegroundThreshold <= filledImage->GetPointData()->GetScalars()->GetTuple1(i))
        {
          if (resultImage->GetPointData()->GetScalars()->GetTuple1(i) == activePixelValue)
            resultImage->GetPointData()->GetScalars()->SetTuple1(i, paintingPixelValue);
        }
      }
    }
  }
}

mitk::ContourModel::Pointer mitk::ContourModelUtils::MoveZerothContourTimeStep(const ContourModel *contour, TimeStepType t)
{
  if (nullptr == contour)
    return nullptr;

  auto resultContour = ContourModel::New();
  resultContour->Expand(t + 1);

  std::for_each(contour->Begin(), contour->End(), [&resultContour, t](ContourElement::VertexType *vertex) {
    resultContour->AddVertex(*vertex, t);
  });

  return resultContour;
}

int mitk::ContourModelUtils::GetActivePixelValue(const Image* workingImage)
{
  auto labelSetImage = dynamic_cast<const LabelSetImage*>(workingImage);
  int activePixelValue = 1;
  if (nullptr != labelSetImage)
  {
    activePixelValue = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer())->GetValue();
  }

  return activePixelValue;
}
<|endoftext|>


<commit_before>#include "itkArrowSpatialObject.h"

namespace itk
{
// This is the 3D implementation of the ArrowSpatialObject.

/** Update the local transform from the position and the direction */
// Parial specialization for TDimension = 3
template< >
void
ArrowSpatialObject< 3 >
::UpdateTransform()
{
  VectorType offset;

  for ( unsigned int i = 0; i < 3; i++ )
    {
    offset[i] = m_Position[i];
    }
  this->GetObjectToParentTransform()->SetOffset(offset);

  // If the given direction is not normalized we set the length of the vector
  // as the length of the arrow
  m_Length = m_Direction.GetSquaredNorm();

  if ( m_Length != 0.0 )
    {
    m_Length = vcl_sqrt(m_Length);
    }
  else
    {
    this->Modified();
    return;
    }

  m_Direction.Normalize();

  double anglez = 0;
  if ( m_Direction[0] == 0.0 )
    {
    if ( m_Direction[1] > 0.0 )
      {
      anglez = vnl_math::pi / 2;
      }
    else if ( m_Direction[1] < 0.0 )
      {
      anglez = -vnl_math::pi / 2;
      }
    //NOTE: else if m_Direction[1] == 0, anglez = 0;
    }
  else
    {
    if ( m_Direction[0] < 0.0 )
      {
      anglez = vnl_math::pi + vcl_atan(m_Direction[1] / m_Direction[0]);
      }
    else
      {
      anglez = vcl_atan(m_Direction[1] / m_Direction[0]);
      }
    }
  const double angley = -asin(m_Direction[2]);
  typedef itk::Euler3DTransform< double > EulerTransformType;
  EulerTransformType::Pointer euler = EulerTransformType::New();

  euler->SetRotation(0, angley, anglez);
  this->GetObjectToParentTransform()->SetMatrix( euler->GetRotationMatrix() );
  this->Modified();
}

}
<commit_msg>STYLE: Add license header to itkArrowSpatialObject.cxx.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "itkArrowSpatialObject.h"

namespace itk
{
// This is the 3D implementation of the ArrowSpatialObject.

/** Update the local transform from the position and the direction */
// Parial specialization for TDimension = 3
template< >
void
ArrowSpatialObject< 3 >
::UpdateTransform()
{
  VectorType offset;

  for ( unsigned int i = 0; i < 3; i++ )
    {
    offset[i] = m_Position[i];
    }
  this->GetObjectToParentTransform()->SetOffset(offset);

  // If the given direction is not normalized we set the length of the vector
  // as the length of the arrow
  m_Length = m_Direction.GetSquaredNorm();

  if ( m_Length != 0.0 )
    {
    m_Length = vcl_sqrt(m_Length);
    }
  else
    {
    this->Modified();
    return;
    }

  m_Direction.Normalize();

  double anglez = 0;
  if ( m_Direction[0] == 0.0 )
    {
    if ( m_Direction[1] > 0.0 )
      {
      anglez = vnl_math::pi / 2;
      }
    else if ( m_Direction[1] < 0.0 )
      {
      anglez = -vnl_math::pi / 2;
      }
    //NOTE: else if m_Direction[1] == 0, anglez = 0;
    }
  else
    {
    if ( m_Direction[0] < 0.0 )
      {
      anglez = vnl_math::pi + vcl_atan(m_Direction[1] / m_Direction[0]);
      }
    else
      {
      anglez = vcl_atan(m_Direction[1] / m_Direction[0]);
      }
    }
  const double angley = -asin(m_Direction[2]);
  typedef itk::Euler3DTransform< double > EulerTransformType;
  EulerTransformType::Pointer euler = EulerTransformType::New();

  euler->SetRotation(0, angley, anglez);
  this->GetObjectToParentTransform()->SetMatrix( euler->GetRotationMatrix() );
  this->Modified();
}

}
<|endoftext|>


<commit_before>#include "riptide_teleop/ps3_control.h"

int main(int argc, char** argv)
{
  ros::init(argc, argv, "joy_accel");
  Accel accel;
  accel.loop();
}

Accel::Accel()
{
  js = nh.subscribe<sensor_msgs::Joy>("joy", 1, &Accel::joy_callback, this);
  accels = nh.advertise<geometry_msgs::Accel>("command/accel", 1);
}

void Accel::joy_callback(const sensor_msgs::Joy::ConstPtr& joy)
{
  accel.linear.x = 0.75 * joy->axes[1]; // Left joystick vertical
  accel.linear.y = joy->axes[0];  // Left joystick horizontal
  accel.linear.z = 0.25 * (joy->buttons[11] - joy->buttons[10]); // R1 L1

  accel.angular.x = 2.0 * 3.14159 * joy->axes[2] * -1;// Right joystick horizontal
  accel.angular.y = 1.2 * 3.14159 * joy->axes[3]; // Right joystick vertical
  accel.angular.z = 0.25 * 3.14159 * (joy->buttons[9] - joy->buttons[8]); // R2 L2

  accels.publish(accel);
}

void Accel::loop()
{
  ros::Rate rate(10);
  while (ros::ok())
  {
    ros::spinOnce();
    rate.sleep();
  }
}
<commit_msg>Reduce max accel<commit_after>#include "riptide_teleop/ps3_control.h"

int main(int argc, char** argv)
{
  ros::init(argc, argv, "joy_accel");
  Accel accel;
  accel.loop();
}

Accel::Accel()
{
  js = nh.subscribe<sensor_msgs::Joy>("joy", 1, &Accel::joy_callback, this);
  accels = nh.advertise<geometry_msgs::Accel>("command/accel", 1);
}

void Accel::joy_callback(const sensor_msgs::Joy::ConstPtr& joy)
{
  accel.linear.x = 0.75 * joy->axes[1]; // Left joystick vertical
  accel.linear.y = joy->axes[0];  // Left joystick horizontal
  accel.linear.z = 0.175 * (joy->buttons[11] - joy->buttons[10]); // R1 L1

  accel.angular.x = 2.0 * 3.14159 * joy->axes[2] * -1;// Right joystick horizontal
  accel.angular.y = 1.2 * 3.14159 * joy->axes[3]; // Right joystick vertical
  accel.angular.z = 0.25 * 3.14159 * (joy->buttons[9] - joy->buttons[8]); // R2 L2

  accels.publish(accel);
}

void Accel::loop()
{
  ros::Rate rate(10);
  while (ros::ok())
  {
    ros::spinOnce();
    rate.sleep();
  }
}
<|endoftext|>