<commit_before>#include "include/game/Spaceship.h"
#include "include/game/ProjectileCross.h"
#include "include/game/ProjectileSimple.h"
#include "include/game/ProjectileV.h"
#include "include/game/BonusForceField.h"
#include "include/game/BonusHP.h"
#include "include/game/BonusProjectile.h"
#include "include/game/BonusSpeed.h"
#include "include/engine/DisplayEngine.h"

Spaceship::Spaceship(qreal _dX,qreal _dY,Shooter _player,const QString& _playerName,qreal _dSpeed,qreal _dHealthPoint,qreal _dResistance,GameEngine *_gameEngine)
    :Displayable(_dX,_dY),
      Destroyable(_dHealthPoint,_dResistance),
      player(_player),playerName(_playerName),dSpeed(_dSpeed),dResistanceForceField(RESISTANCE_FORCE_FIELD),gameEngine(_gameEngine)
{
    dHealthForceField = MAX_SPACESHIP_PV;
    type = PROJ_SPACESHIP_DEF;
    bonusSpeed = 0;
    bonusProjectile = 0;
    setPixmap(new QPixmap(":/images/game/spaceship"));

    if(_player == Player2)
    {
        setPixmap(new QPixmap(getPixmap()->transformed(QTransform().rotate(180))));
        setPos(_dX-getPixmap()->size().width(),_dY);
    }
}

Spaceship::~Spaceship()
{
    delete bonusSpeed;
    delete bonusProjectile;
}

QRectF Spaceship::boundingRect() const
{
    return QRectF(getPixmap()->rect());
}

QPainterPath Spaceship::shape() const
{
    QPainterPath l_path;
    l_path.addEllipse(boundingRect());
    return l_path;
}

void Spaceship::paint(QPainter *_painter,const QStyleOptionGraphicsItem *_option, QWidget *_widget)
{
    _painter->drawPixmap(0,0,*getPixmap());
//    _painter->setPen(QPen(QColor(255,0,0)));
//    _painter->drawPath(shape());
}

qreal Spaceship::getPercentageSpeed() const
{
    if(bonusSpeed==0)
        return 100.0;
    else
        return 100+bonusSpeed->getSpeed()/(dSpeed-bonusSpeed->getSpeed())*100;
}

void Spaceship::addBonus(Bonus *_bonus)
{
    if(BonusHP* bhp = dynamic_cast<BonusHP*>(_bonus))
    {
        dHealthPoint+=bhp->getHealthPoint();
        if(dHealthPoint>MAX_SPACESHIP_PV)
            dHealthPoint=MAX_SPACESHIP_PV;
        delete bhp;
    }
    else if(BonusProjectile* bp = dynamic_cast<BonusProjectile*>(_bonus))
    {
        type = bp->getType();
        bonusProjectile = bp;
        QTimer::singleShot(bp->getExpiration(),this,SLOT(removeProjectileBonus()));
    }
    else if(BonusForceField* bff = dynamic_cast<BonusForceField*>(_bonus))
    {
        dHealthForceField = MAX_SPACESHIP_PV;
        delete bff;
    }
    else if(BonusSpeed* bs = dynamic_cast<BonusSpeed*>(_bonus))
    {
        if(bonusSpeed==0)
        {
            bonusSpeed = bs;
            dSpeed+=bs->getSpeed();
            QTimer::singleShot(bs->getExpiration(),this,SLOT(removeSpeedBonus()));
        }
        else
            delete bs;
    }
}

void Spaceship::removeProjectileBonus()
{
    delete bonusProjectile;
    bonusProjectile = 0;
    type = PROJ_SPACESHIP_DEF;
}

void Spaceship::removeSpeedBonus()
{
    dSpeed-=bonusSpeed->getSpeed();
    delete bonusSpeed;
    bonusSpeed = 0;
}

void Spaceship::receiveAttack(qreal _dPower)
{
    double power1 = _dPower * (100.0 - dHealthForceField) / 100.0;
    double power2 = _dPower - power1;

	dHealthPoint -= power1 / dResistance;
    dHealthForceField -= power2 / dResistanceForceField;
    if(dHealthForceField < 0)
        dHealthForceField = 0;

    isDead();
}

void Spaceship::attack()
{
    int l_x = 0;
    int l_y = 0;

    if(player==Player1)
        l_x = pos().x()+getPixmap()->width();
    else
        l_x = pos().x();//Don't need to remove the width of the QPixmap,already done in the constructor

    l_y = pos().y()+getPixmap()->height()/2;

    switch(type)
    {
        case ProjSimple:
            gameEngine->displayEngine()->addProjectile(new ProjectileSimple(l_x,l_y,player));
            break;

        case ProjCross:
            for(int i = 0;i<3;i++)
                gameEngine->displayEngine()->addProjectile(new ProjectileCross(l_x,l_y,player,i-1));
            break;

        case ProjV:
            gameEngine->displayEngine()->addProjectile(new ProjectileV(l_x,l_y,player,AMPLI_SPACESHIP_PROJ_V,OMEGA_SPACESHIP_PROJ_V));
            break;
        case ProjAlien:
            break;

        case Nothing:
            break;
    }
}

void Spaceship::top()
{
    setPos(pos().x(),pos().y()-dSpeed);
}

void Spaceship::bottom()
{
    setPos(pos().x(),pos().y()+dSpeed);
}
<commit_msg>Fix bug healthpoint of the spaceship at the end of the game<commit_after>#include "include/game/Spaceship.h"
#include "include/game/ProjectileCross.h"
#include "include/game/ProjectileSimple.h"
#include "include/game/ProjectileV.h"
#include "include/game/BonusForceField.h"
#include "include/game/BonusHP.h"
#include "include/game/BonusProjectile.h"
#include "include/game/BonusSpeed.h"
#include "include/engine/DisplayEngine.h"

Spaceship::Spaceship(qreal _dX,qreal _dY,Shooter _player,const QString& _playerName,qreal _dSpeed,qreal _dHealthPoint,qreal _dResistance,GameEngine *_gameEngine)
    :Displayable(_dX,_dY),
      Destroyable(_dHealthPoint,_dResistance),
      player(_player),playerName(_playerName),dSpeed(_dSpeed),dResistanceForceField(RESISTANCE_FORCE_FIELD),gameEngine(_gameEngine)
{
    dHealthForceField = MAX_SPACESHIP_PV;
    type = PROJ_SPACESHIP_DEF;
    bonusSpeed = 0;
    bonusProjectile = 0;
    setPixmap(new QPixmap(":/images/game/spaceship"));

    if(_player == Player2)
    {
        setPixmap(new QPixmap(getPixmap()->transformed(QTransform().rotate(180))));
        setPos(_dX-getPixmap()->size().width(),_dY);
    }
}

Spaceship::~Spaceship()
{
    delete bonusSpeed;
    delete bonusProjectile;
}

QRectF Spaceship::boundingRect() const
{
    return QRectF(getPixmap()->rect());
}

QPainterPath Spaceship::shape() const
{
    QPainterPath l_path;
    l_path.addEllipse(boundingRect());
    return l_path;
}

void Spaceship::paint(QPainter *_painter,const QStyleOptionGraphicsItem *_option, QWidget *_widget)
{
    _painter->drawPixmap(0,0,*getPixmap());
//    _painter->setPen(QPen(QColor(255,0,0)));
//    _painter->drawPath(shape());
}

qreal Spaceship::getPercentageSpeed() const
{
    if(bonusSpeed==0)
        return 100.0;
    else
        return 100+bonusSpeed->getSpeed()/(dSpeed-bonusSpeed->getSpeed())*100;
}

void Spaceship::addBonus(Bonus *_bonus)
{
    if(BonusHP* bhp = dynamic_cast<BonusHP*>(_bonus))
    {
        dHealthPoint+=bhp->getHealthPoint();
        if(dHealthPoint>MAX_SPACESHIP_PV)
            dHealthPoint=MAX_SPACESHIP_PV;
        delete bhp;
    }
    else if(BonusProjectile* bp = dynamic_cast<BonusProjectile*>(_bonus))
    {
        type = bp->getType();
        bonusProjectile = bp;
        QTimer::singleShot(bp->getExpiration(),this,SLOT(removeProjectileBonus()));
    }
    else if(BonusForceField* bff = dynamic_cast<BonusForceField*>(_bonus))
    {
        dHealthForceField = MAX_SPACESHIP_PV;
        delete bff;
    }
    else if(BonusSpeed* bs = dynamic_cast<BonusSpeed*>(_bonus))
    {
        if(bonusSpeed==0)
        {
            bonusSpeed = bs;
            dSpeed+=bs->getSpeed();
            QTimer::singleShot(bs->getExpiration(),this,SLOT(removeSpeedBonus()));
        }
        else
            delete bs;
    }
}

void Spaceship::removeProjectileBonus()
{
    delete bonusProjectile;
    bonusProjectile = 0;
    type = PROJ_SPACESHIP_DEF;
}

void Spaceship::removeSpeedBonus()
{
    dSpeed-=bonusSpeed->getSpeed();
    delete bonusSpeed;
    bonusSpeed = 0;
}

void Spaceship::receiveAttack(qreal _dPower)
{
    double power1 = _dPower * (100.0 - dHealthForceField) / 100.0;
    double power2 = _dPower - power1;

	dHealthPoint -= power1 / dResistance;
    dHealthForceField -= power2 / dResistanceForceField;
    if(dHealthForceField < 0)
        dHealthForceField = 0;

    if(dHealthPoint<=0)
        dHealthPoint=0;
    isDead();
}

void Spaceship::attack()
{
    int l_x = 0;
    int l_y = 0;

    if(player==Player1)
        l_x = pos().x()+getPixmap()->width();
    else
        l_x = pos().x();//Don't need to remove the width of the QPixmap,already done in the constructor

    l_y = pos().y()+getPixmap()->height()/2;

    switch(type)
    {
        case ProjSimple:
            gameEngine->displayEngine()->addProjectile(new ProjectileSimple(l_x,l_y,player));
            break;

        case ProjCross:
            for(int i = 0;i<3;i++)
                gameEngine->displayEngine()->addProjectile(new ProjectileCross(l_x,l_y,player,i-1));
            break;

        case ProjV:
            gameEngine->displayEngine()->addProjectile(new ProjectileV(l_x,l_y,player,AMPLI_SPACESHIP_PROJ_V,OMEGA_SPACESHIP_PROJ_V));
            break;
        case ProjAlien:
            break;

        case Nothing:
            break;
    }
}

void Spaceship::top()
{
    setPos(pos().x(),pos().y()-dSpeed);
}

void Spaceship::bottom()
{
    setPos(pos().x(),pos().y()+dSpeed);
}
<|endoftext|>


<commit_before>#include "DotGraphOutput.hh"
#include "EdgeType.hh"

string getEdgeStyle(EdgeType t) {
  switch (t) {
  case EdgeType::Plane:
    return "[color=red]";
  case EdgeType::Train:
    return "[color=blue,style=dotted]";
  default:
    return "";
  }
}

template <typename V>
void DotGraphOutput<V>::output(string path) {

  cout << "Exporting " << this->graph_.name() << " to " << path << endl;

  ofstream st(path, ofstream::out);

  st << "digraph " << this->graph_.name() << " {" << endl;

  for (unsigned int i = 0; i < this->graph_.verticesNb(); i++)
    for (auto e : this->graph_.outgoingEdges(i)) {
      st << "\t" << this->graph_.getVertex(i).name()
	 << " -> " << this->graph_.getVertex(e->getOtherEnd(i)).name()
	 << " " << getEdgeStyle(e->type())
	 << ";" << endl;
    }

  st << "}" << endl;

  st.close();
}

template class DotGraphOutput<double>;
<commit_msg>Add edges values and proper labels to node in Dot output<commit_after>#include "DotGraphOutput.hh"
#include "EdgeType.hh"

#include <sstream>

template <typename V>
string getEdgeStyle(EdgeType t, V val) {

  stringstream ss;
  string end("\"]");

  switch (t) {
  case EdgeType::Plane:
    ss << string("[color=red, label=\"") << val << end;
    break;
  case EdgeType::Train:
    ss << string("[color=blue, style=dotted, label=\"") << val << end ;
    break;
  default:
    ss << string("[label=\"") << val << end;
    break;
  }
  return ss.str();
}

template <typename V>
void DotGraphOutput<V>::output(string path) {

  cout << "Exporting " << this->graph_.name() << " to " << path << endl;

  ofstream st(path, ofstream::out);

  st << "digraph " << this->graph_.name() << " {" << endl;

  for (unsigned int i = 0; i < this->graph_.verticesNb(); i++)
    st << "\t" << i << " [label=\"" << this->graph_.getVertex(i).name() << "\"];" << endl;

  for (unsigned int i = 0; i < this->graph_.verticesNb(); i++)
    for (auto e : this->graph_.outgoingEdges(i)) {
      st << "\t" << i
	 << " -> " << e->getOtherEnd(i)
	 << " " << getEdgeStyle(e->type(), e->distance())
	 << ";" << endl;
    }

  st << "}" << endl;

  st.close();
}

template class DotGraphOutput<double>;
<|endoftext|>


<commit_before>#include <common/buffer.h>
#include <common/endian.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include "wanproxy_config.h"

static void usage(void);

int
main(int argc, char *argv[])
{
	std::string configfile("");
	int ch;

	INFO("/wanproxy") << "WANProxy";
	INFO("/wanproxy") << "Copyright (c) 2008-2010 WANProxy.org.";
	INFO("/wanproxy") << "All rights reserved.";

	while ((ch = getopt(argc, argv, "c:")) != -1) {
		switch (ch) {
		case 'c':
			configfile = optarg;
			break;
		default:
			usage();
		}
	}

	if (configfile == "")
		usage();

	WANProxyConfig config;
	if (!config.configure(configfile))
		HALT("/wanproxy") << "Could not configure proxies.";

	EventSystem::instance()->start();
}

static void
usage(void)
{
	INFO("/wanproxy/usage") << "wanproxy -c configfile";
	exit(1);
}
<commit_msg>Add a verbose flag to tack so wanproxy.conf need not be changed to adjust the log level.<commit_after>#include <common/buffer.h>
#include <common/endian.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include "wanproxy_config.h"

static void usage(void);

int
main(int argc, char *argv[])
{
	std::string configfile("");
	bool verbose;
	int ch;

	INFO("/wanproxy") << "WANProxy";
	INFO("/wanproxy") << "Copyright (c) 2008-2010 WANProxy.org.";
	INFO("/wanproxy") << "All rights reserved.";

	while ((ch = getopt(argc, argv, "c:v")) != -1) {
		switch (ch) {
		case 'c':
			configfile = optarg;
			break;
		case 'v':
			verbose = true;
			break;
		default:
			usage();
		}
	}

	if (configfile == "")
		usage();

	if (verbose) {
		Log::mask(".?", Log::Debug);
	} else {
		Log::mask(".?", Log::Info);
	}

	WANProxyConfig config;
	if (!config.configure(configfile))
		HALT("/wanproxy") << "Could not configure proxies.";

	EventSystem::instance()->start();
}

static void
usage(void)
{
	INFO("/wanproxy/usage") << "wanproxy [-v] -c configfile";
	exit(1);
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/test/fake_port_allocator.h"

#include "remoting/test/fake_network_dispatcher.h"
#include "remoting/test/fake_network_manager.h"
#include "remoting/test/fake_socket_factory.h"

namespace remoting {

namespace {

class FakePortAllocatorSession
    : public cricket::HttpPortAllocatorSessionBase {
 public:
  FakePortAllocatorSession(
      cricket::HttpPortAllocatorBase* allocator,
      const std::string& content_name,
      int component,
      const std::string& ice_username_fragment,
      const std::string& ice_password,
      const std::vector<rtc::SocketAddress>& stun_hosts,
      const std::vector<std::string>& relay_hosts,
      const std::string& relay);
  ~FakePortAllocatorSession() override;

  // cricket::HttpPortAllocatorBase overrides.
  void ConfigReady(cricket::PortConfiguration* config) override;
  void SendSessionRequest(const std::string& host, int port) override;

 private:
  DISALLOW_COPY_AND_ASSIGN(FakePortAllocatorSession);
};

FakePortAllocatorSession::FakePortAllocatorSession(
    cricket::HttpPortAllocatorBase* allocator,
    const std::string& content_name,
    int component,
    const std::string& ice_username_fragment,
    const std::string& ice_password,
    const std::vector<rtc::SocketAddress>& stun_hosts,
    const std::vector<std::string>& relay_hosts,
    const std::string& relay)
    : HttpPortAllocatorSessionBase(allocator,
                                   content_name,
                                   component,
                                   ice_username_fragment,
                                   ice_password,
                                   stun_hosts,
                                   relay_hosts,
                                   relay,
                                   std::string()) {
  set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
            cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
            cricket::PORTALLOCATOR_ENABLE_IPV6 |
            cricket::PORTALLOCATOR_DISABLE_STUN |
            cricket::PORTALLOCATOR_DISABLE_RELAY);
}

FakePortAllocatorSession::~FakePortAllocatorSession() {
}

void FakePortAllocatorSession::ConfigReady(
    cricket::PortConfiguration* config) {
  // Filter out non-UDP relay ports, so that we don't try using TCP.
  for (cricket::PortConfiguration::RelayList::iterator relay =
           config->relays.begin(); relay != config->relays.end(); ++relay) {
    cricket::PortList filtered_ports;
    for (cricket::PortList::iterator port =
             relay->ports.begin(); port != relay->ports.end(); ++port) {
      if (port->proto == cricket::PROTO_UDP) {
        filtered_ports.push_back(*port);
      }
    }
    relay->ports = filtered_ports;
  }
  cricket::BasicPortAllocatorSession::ConfigReady(config);
}

void FakePortAllocatorSession::SendSessionRequest(
    const std::string& host,
    int port) {
  ReceiveSessionResponse(std::string());
}

}  // namespace

// static
scoped_ptr<FakePortAllocator> FakePortAllocator::Create(
    scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher) {
  scoped_ptr<FakePacketSocketFactory> socket_factory(
      new FakePacketSocketFactory(fake_network_dispatcher.get()));
  scoped_ptr<rtc::NetworkManager> network_manager(
      new FakeNetworkManager(socket_factory->GetAddress()));

  return make_scoped_ptr(
      new FakePortAllocator(network_manager.Pass(), socket_factory.Pass()));
}

FakePortAllocator::FakePortAllocator(
    scoped_ptr<rtc::NetworkManager> network_manager,
    scoped_ptr<FakePacketSocketFactory> socket_factory)
    : HttpPortAllocatorBase(network_manager.get(),
                            socket_factory.get(),
                            std::string()),
      network_manager_(network_manager.Pass()),
      socket_factory_(socket_factory.Pass()) {}

FakePortAllocator::~FakePortAllocator() {
}

cricket::PortAllocatorSession* FakePortAllocator::CreateSessionInternal(
    const std::string& content_name,
    int component,
    const std::string& ice_username_fragment,
    const std::string& ice_password) {
  return new FakePortAllocatorSession(
      this, content_name, component, ice_username_fragment, ice_password,
      stun_hosts(), relay_hosts(), relay_token());
}

}  // namespace remoting
<commit_msg>Fix FakePortAllocator to work with standard ICE.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/test/fake_port_allocator.h"

#include "remoting/test/fake_network_dispatcher.h"
#include "remoting/test/fake_network_manager.h"
#include "remoting/test/fake_socket_factory.h"

namespace remoting {

namespace {

class FakePortAllocatorSession
    : public cricket::HttpPortAllocatorSessionBase {
 public:
  FakePortAllocatorSession(
      cricket::HttpPortAllocatorBase* allocator,
      const std::string& content_name,
      int component,
      const std::string& ice_username_fragment,
      const std::string& ice_password,
      const std::vector<rtc::SocketAddress>& stun_hosts,
      const std::vector<std::string>& relay_hosts,
      const std::string& relay);
  ~FakePortAllocatorSession() override;

  // cricket::HttpPortAllocatorBase overrides.
  void ConfigReady(cricket::PortConfiguration* config) override;
  void SendSessionRequest(const std::string& host, int port) override;

 private:
  DISALLOW_COPY_AND_ASSIGN(FakePortAllocatorSession);
};

FakePortAllocatorSession::FakePortAllocatorSession(
    cricket::HttpPortAllocatorBase* allocator,
    const std::string& content_name,
    int component,
    const std::string& ice_username_fragment,
    const std::string& ice_password,
    const std::vector<rtc::SocketAddress>& stun_hosts,
    const std::vector<std::string>& relay_hosts,
    const std::string& relay)
    : HttpPortAllocatorSessionBase(allocator,
                                   content_name,
                                   component,
                                   ice_username_fragment,
                                   ice_password,
                                   stun_hosts,
                                   relay_hosts,
                                   relay,
                                   std::string()) {
}

FakePortAllocatorSession::~FakePortAllocatorSession() {
}

void FakePortAllocatorSession::ConfigReady(
    cricket::PortConfiguration* config) {
  // Filter out non-UDP relay ports, so that we don't try using TCP.
  for (cricket::PortConfiguration::RelayList::iterator relay =
           config->relays.begin(); relay != config->relays.end(); ++relay) {
    cricket::PortList filtered_ports;
    for (cricket::PortList::iterator port =
             relay->ports.begin(); port != relay->ports.end(); ++port) {
      if (port->proto == cricket::PROTO_UDP) {
        filtered_ports.push_back(*port);
      }
    }
    relay->ports = filtered_ports;
  }
  cricket::BasicPortAllocatorSession::ConfigReady(config);
}

void FakePortAllocatorSession::SendSessionRequest(
    const std::string& host,
    int port) {
  ReceiveSessionResponse(std::string());
}

}  // namespace

// static
scoped_ptr<FakePortAllocator> FakePortAllocator::Create(
    scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher) {
  scoped_ptr<FakePacketSocketFactory> socket_factory(
      new FakePacketSocketFactory(fake_network_dispatcher.get()));
  scoped_ptr<rtc::NetworkManager> network_manager(
      new FakeNetworkManager(socket_factory->GetAddress()));

  return make_scoped_ptr(
      new FakePortAllocator(network_manager.Pass(), socket_factory.Pass()));
}

FakePortAllocator::FakePortAllocator(
    scoped_ptr<rtc::NetworkManager> network_manager,
    scoped_ptr<FakePacketSocketFactory> socket_factory)
    : HttpPortAllocatorBase(network_manager.get(),
                            socket_factory.get(),
                            std::string()),
      network_manager_(network_manager.Pass()),
      socket_factory_(socket_factory.Pass()) {
  set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
            cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
            cricket::PORTALLOCATOR_ENABLE_IPV6 |
            cricket::PORTALLOCATOR_DISABLE_STUN |
            cricket::PORTALLOCATOR_DISABLE_RELAY);
}

FakePortAllocator::~FakePortAllocator() {
}

cricket::PortAllocatorSession* FakePortAllocator::CreateSessionInternal(
    const std::string& content_name,
    int component,
    const std::string& ice_username_fragment,
    const std::string& ice_password) {
  return new FakePortAllocatorSession(
      this, content_name, component, ice_username_fragment, ice_password,
      stun_hosts(), relay_hosts(), relay_token());
}

}  // namespace remoting
<|endoftext|>


<commit_before>// @(#)root/proofx:$Id$
// Author: Gerardo Ganis Apr 2008

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TProofMgrLite                                                        //
//                                                                      //
// Basic functionality implementtaion in the case of Lite sessions      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include <errno.h>
#ifdef WIN32
#include <io.h>
#endif

#include "TProofMgrLite.h"

#include "Riostream.h"
#include "TEnv.h"
#include "TError.h"
#include "TObjString.h"
#include "TProofLite.h"
#include "TProofLog.h"
#include "TROOT.h"
#include "TRegexp.h"
#include "TSortedList.h"

ClassImp(TProofMgrLite)

//______________________________________________________________________________
TProofMgrLite::TProofMgrLite(const char *url, Int_t dbg, const char *alias)
          : TProofMgr(url, dbg, alias)
{
   // Create a PROOF manager for the Lite environment.

   // Set the correct servert type
   fServType = kProofLite;
}

//______________________________________________________________________________
TProof *TProofMgrLite::CreateSession(const char *cfg,
                                     const char *, Int_t loglevel)
{
   // Create a new session

   Int_t nwrk = TProofLite::GetNumberOfWorkers(fUrl.GetOptions());
   if (nwrk == 0) return (TProof *)0;

   // Check if we have already a running session
   if (gProof && gProof->IsLite()) {
      if (gProof->IsValid()) {
         if (nwrk > 0 && gProof->GetParallel() != nwrk) {
            delete gProof;
            gProof = 0;
         } else {
            // We have already a running session
            return gProof;
         }
      } else {
         // Remove existing instance
         delete gProof;
         gProof = 0;
      }
   }

   // Create the instance
   TString u("lite");
   if (strlen(fUrl.GetOptions()) > 0) u.Form("lite/?%s", fUrl.GetOptions());
   TProof *p = new TProofLite(u, cfg, 0, loglevel, 0, this);

   if (p && p->IsValid()) {

      // Save record about this session
      Int_t ns = 1;
      if (fSessions) {
         // To avoid ambiguities in case of removal of some elements
         if (fSessions->Last())
            ns = ((TProofDesc *)(fSessions->Last()))->GetLocalId() + 1;
      } else {
         // Create the list
         fSessions = new TList;
      }

      // Create the description class
      Int_t st = (p->IsIdle()) ? TProofDesc::kIdle : TProofDesc::kRunning ;
      TProofDesc *d =
         new TProofDesc(p->GetName(), p->GetTitle(), p->GetUrl(),
                               ns, p->GetSessionID(), st, p);
      fSessions->Add(d);

   } else {
      // Session creation failed
      Error("CreateSession", "creating PROOF session");
      SafeDelete(p);
   }

   // We are done
   return p;
}

//_____________________________________________________________________________
TProofLog *TProofMgrLite::GetSessionLogs(Int_t isess, const char *stag,
                                         const char *pattern, Bool_t)
{
   // Get logs or log tails from last session associated with this manager
   // instance.
   // The arguments allow to specify a session different from the last one:
   //      isess   specifies a position relative to the last one, i.e. 1
   //              for the next to last session; the absolute value is taken
   //              so -1 and 1 are equivalent.
   //      stag    specifies the unique tag of the wanted session
   // The special value stag = "NR" allows to just initialize the TProofLog
   // object w/o retrieving the files; this may be useful when the number
   // of workers is large and only a subset of logs is required.
   // If 'stag' is specified 'isess' is ignored (unless stag = "NR").
   // If 'pattern' is specified only the lines containing it are retrieved
   // (remote grep functionality); to filter out a pattern 'pat' use
   // pattern = "-v pat".
   // Returns a TProofLog object (to be deleted by the caller) on success,
   // 0 if something wrong happened.

   TProofLog *pl = 0;

   // The absolute value of isess counts
   isess = (isess < 0) ? -isess : isess;

   // Special option in stag
   bool retrieve = 1;
   TString tag(stag);
   if (tag == "NR") {
      retrieve = 0;
      tag = "";
   }

   // The working dir
   TString sandbox(gSystem->WorkingDirectory());
   sandbox.ReplaceAll(gSystem->HomeDirectory(),"");
   sandbox.ReplaceAll("/","-");
   sandbox.Replace(0,1,"/",1);
   if (strlen(gEnv->GetValue("ProofLite.Sandbox", "")) > 0) {
      sandbox.Insert(0, gEnv->GetValue("ProofLite.Sandbox", ""));
   } else if (strlen(gEnv->GetValue("Proof.Sandbox", "")) > 0) {
      sandbox.Insert(0, gEnv->GetValue("Proof.Sandbox", ""));
   } else {
      TString sb;
      sb.Form("~/%s", kPROOF_WorkDir);
      sandbox.Insert(0, sb.Data());
   }
   gSystem->ExpandPathName(sandbox);

   TString sessiondir;
   if (tag.Length() > 0) {
      sessiondir.Form("%s/session-%s", sandbox.Data(), tag.Data());
      if (gSystem->AccessPathName(sessiondir, kReadPermission)) {
         Error("GetSessionLogs", "information for session '%s' not available", tag.Data());
         return (TProofLog *)0;
      }
   } else {
      // Get the list of available dirs
      TSortedList *olddirs = new TSortedList(kFALSE);
      void *dirp = gSystem->OpenDirectory(sandbox);
      if (dirp) {
         const char *e = 0;
         while ((e = gSystem->GetDirEntry(dirp))) {
            if (!strncmp(e, "session-", 8)) {
               TString d(e);
               Int_t i = d.Last('-');
               if (i != kNPOS) d.Remove(i);
               i = d.Last('-');
               if (i != kNPOS) d.Remove(0,i+1);
               TString path = Form("%s/%s", sandbox.Data(), e);
               olddirs->Add(new TNamed(d, path));
            }
         }
         gSystem->FreeDirectory(dirp);
      }

      // Check isess
      if (isess > olddirs->GetSize() - 1) {
         Warning("GetSessionLogs",
                 "session index out of range (%d): take oldest available session", isess);
         isess = olddirs->GetSize() - 1;
      }

      // Locate the session dir
      Int_t isx = isess;
      TNamed *n = (TNamed *) olddirs->First();
      while (isx-- > 0) {
         olddirs->Remove(n);
         delete n;
         n = (TNamed *) olddirs->First();
      }
      if (!n) {
         Error("GetSessionLogs", "cannot locate session dir for index '%d' under '%s':"
                                 " cannot continue!", isess, sandbox.Data());
         return (TProofLog *)0;
      }
      sessiondir = n->GetTitle();
      tag = gSystem->BaseName(sessiondir);
      tag.ReplaceAll("session-", "");

      // Cleanup
      olddirs->SetOwner();
      delete olddirs;
   }
   Info("GetSessionLogs", "analysing session dir %s", sessiondir.Data());

   // Create the instance now
   pl = new TProofLog(tag, "", this);

   void *dirp = gSystem->OpenDirectory(sessiondir);
   if (dirp) {
      TSortedList *logs = new TSortedList;
      const char *e = 0;
      while ((e = gSystem->GetDirEntry(dirp))) {
         TString fn(e);
         if (fn.EndsWith(".log") && fn.CountChar('-') > 0) {
            TString ord, url;
            if (fn.BeginsWith("session-")) {
               ord = "-1";
            } else if (fn.BeginsWith("worker-")) {
               ord = fn;
               ord.ReplaceAll("worker-", "");
               Int_t id = ord.First('-');
               if (id != kNPOS) {
                  ord.Remove(id);
               } else if (ord.Contains(".valgrind")) {
                  // Add to the list (special tag for valgrind outputs)
                  ord.ReplaceAll(".valgrind.log","-valgrind");
               } else {
                  // Not a good path
                  ord = "";
               }
               if (!ord.IsNull()) ord.ReplaceAll("0.", "");
            }
            if (!ord.IsNull()) {
               url = Form("%s/%s", sessiondir.Data(), e);
               // Add to the list
               logs->Add(new TNamed(ord, url));
               // Notify
               if (gDebug > 1)
                  Info("GetSessionLogs", "ord: %s, url: %s", ord.Data(), url.Data());
            }
         }
      }
      gSystem->FreeDirectory(dirp);

      TIter nxl(logs);
      TNamed *n = 0;
      while ((n = (TNamed *) nxl())) {
         TString ord = Form("0.%s", n->GetName());
         if (ord == "0.-1") ord = "0";
         // Add to the list
         pl->Add(ord, n->GetTitle());
      }

      // Cleanup
      logs->SetOwner();
      delete logs;
   }

   // Retrieve the default part
   if (pl && retrieve) {
      const char *pat = pattern ? pattern : "-v \"| SvcMsg\"";
      if (pat && strlen(pat) > 0)
         pl->Retrieve("*", TProofLog::kGrep, 0, pat);
      else
         pl->Retrieve();
   }

   // Done
   return pl;
}

//______________________________________________________________________________
TObjString *TProofMgrLite::ReadBuffer(const char *fin, Long64_t ofs, Int_t len)
{
   // Read 'len' bytes from offset 'ofs' of the local file 'fin'.
   // Returns a TObjString with the content or 0, in case of failure

   if (!fin || strlen(fin) <= 0) {
      Error("ReadBuffer", "undefined path!");
      return (TObjString *)0;
   }

   // Open the file
   TString fn = TUrl(fin).GetFile();
   Int_t fd = open(fn.Data(), O_RDONLY);
   if (fd < 0) {
      Error("ReadBuffer", "problems opening file %s", fn.Data());
      return (TObjString *)0;
   }

   // Total size
   off_t start = 0, end = lseek(fd, (off_t) 0, SEEK_END);

   // Set the offset
   if (ofs > 0 && ofs < end) {
      start = lseek(fd, (off_t) ofs, SEEK_SET);
   } else {
      start = lseek(fd, (off_t) 0, SEEK_SET);
   }
   if (len > (end - start + 1) || len <= 0)
      len = end - start + 1;

   TString outbuf;
   const Int_t kMAXBUF = 32768;
   char buf[kMAXBUF];
   Int_t left = len;
   Int_t wanted = (left > kMAXBUF - 1) ? kMAXBUF - 1 : left;
   do {
      while ((len = read(fd, buf, wanted)) < 0 && TSystem::GetErrno() == EINTR)
         TSystem::ResetErrno();

      if (len < 0) {
         Error("ReadBuffer", "error reading file %s", fn.Data());
         close(fd);
         return (TObjString *)0;
      } else if (len > 0) {
         if (len == wanted)
            buf[len-1] = '\n';
         buf[len] = '\0';
         outbuf += buf;
      }

      // Update counters
      left -= len;
      wanted = (left > kMAXBUF - 1) ? kMAXBUF - 1 : left;

   } while (len > 0 && left > 0);

   // Done
   return new TObjString(outbuf.Data());
}

//______________________________________________________________________________
TObjString *TProofMgrLite::ReadBuffer(const char *fin, const char *pattern)
{
   // Read lines containing 'pattern' in 'file'.
   // Returns a TObjString with the content or 0, in case of failure

   // If no pattern, read everything
   if (!pattern || strlen(pattern) <= 0)
      return (TObjString *)0;

   if (!fin || strlen(fin) <= 0) {
      Error("ReadBuffer", "undefined path!");
      return (TObjString *)0;
   }
   TString fn = TUrl(fin).GetFile();

   TString pat(pattern);
   // Check if "-v"
   Bool_t excl = kFALSE;
   if (pat.Contains("-v ")) {
      pat.ReplaceAll("-v ", "");
      excl = kTRUE;
   }
   pat = pat.Strip(TString::kLeading, ' ');
   pat = pat.Strip(TString::kTrailing, ' ');
   pat = pat.Strip(TString::kLeading, '\"');
   pat = pat.Strip(TString::kTrailing, '\"');

   // Use a regular expression
   TRegexp re(pat);

   // Open file with file info
   ifstream in;
   in.open(fn.Data());

   TString outbuf;

   // Read the input list of files and add them to the chain
   TString line;
   while(in.good()) {

      // Read next line
      line.ReadLine(in);

      // Keep only lines with pattern
      if ((excl && line.Index(re) != kNPOS) ||
          (!excl && line.Index(re) == kNPOS)) continue;

      // Remove trailing '\n', if any
      if (!line.EndsWith("\n")) line.Append('\n');

      // Add to output
      outbuf += line;
   }
   in.close();

   // Done
   return new TObjString(outbuf.Data());
}
<commit_msg>Make sure files are always closed (Coverity)<commit_after>// @(#)root/proofx:$Id$
// Author: Gerardo Ganis Apr 2008

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TProofMgrLite                                                        //
//                                                                      //
// Basic functionality implementtaion in the case of Lite sessions      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include <errno.h>
#ifdef WIN32
#include <io.h>
#endif

#include "TProofMgrLite.h"

#include "Riostream.h"
#include "TEnv.h"
#include "TError.h"
#include "TObjString.h"
#include "TProofLite.h"
#include "TProofLog.h"
#include "TROOT.h"
#include "TRegexp.h"
#include "TSortedList.h"

ClassImp(TProofMgrLite)

//______________________________________________________________________________
TProofMgrLite::TProofMgrLite(const char *url, Int_t dbg, const char *alias)
          : TProofMgr(url, dbg, alias)
{
   // Create a PROOF manager for the Lite environment.

   // Set the correct servert type
   fServType = kProofLite;
}

//______________________________________________________________________________
TProof *TProofMgrLite::CreateSession(const char *cfg,
                                     const char *, Int_t loglevel)
{
   // Create a new session

   Int_t nwrk = TProofLite::GetNumberOfWorkers(fUrl.GetOptions());
   if (nwrk == 0) return (TProof *)0;

   // Check if we have already a running session
   if (gProof && gProof->IsLite()) {
      if (gProof->IsValid()) {
         if (nwrk > 0 && gProof->GetParallel() != nwrk) {
            delete gProof;
            gProof = 0;
         } else {
            // We have already a running session
            return gProof;
         }
      } else {
         // Remove existing instance
         delete gProof;
         gProof = 0;
      }
   }

   // Create the instance
   TString u("lite");
   if (strlen(fUrl.GetOptions()) > 0) u.Form("lite/?%s", fUrl.GetOptions());
   TProof *p = new TProofLite(u, cfg, 0, loglevel, 0, this);

   if (p && p->IsValid()) {

      // Save record about this session
      Int_t ns = 1;
      if (fSessions) {
         // To avoid ambiguities in case of removal of some elements
         if (fSessions->Last())
            ns = ((TProofDesc *)(fSessions->Last()))->GetLocalId() + 1;
      } else {
         // Create the list
         fSessions = new TList;
      }

      // Create the description class
      Int_t st = (p->IsIdle()) ? TProofDesc::kIdle : TProofDesc::kRunning ;
      TProofDesc *d =
         new TProofDesc(p->GetName(), p->GetTitle(), p->GetUrl(),
                               ns, p->GetSessionID(), st, p);
      fSessions->Add(d);

   } else {
      // Session creation failed
      Error("CreateSession", "creating PROOF session");
      SafeDelete(p);
   }

   // We are done
   return p;
}

//_____________________________________________________________________________
TProofLog *TProofMgrLite::GetSessionLogs(Int_t isess, const char *stag,
                                         const char *pattern, Bool_t)
{
   // Get logs or log tails from last session associated with this manager
   // instance.
   // The arguments allow to specify a session different from the last one:
   //      isess   specifies a position relative to the last one, i.e. 1
   //              for the next to last session; the absolute value is taken
   //              so -1 and 1 are equivalent.
   //      stag    specifies the unique tag of the wanted session
   // The special value stag = "NR" allows to just initialize the TProofLog
   // object w/o retrieving the files; this may be useful when the number
   // of workers is large and only a subset of logs is required.
   // If 'stag' is specified 'isess' is ignored (unless stag = "NR").
   // If 'pattern' is specified only the lines containing it are retrieved
   // (remote grep functionality); to filter out a pattern 'pat' use
   // pattern = "-v pat".
   // Returns a TProofLog object (to be deleted by the caller) on success,
   // 0 if something wrong happened.

   TProofLog *pl = 0;

   // The absolute value of isess counts
   isess = (isess < 0) ? -isess : isess;

   // Special option in stag
   bool retrieve = 1;
   TString tag(stag);
   if (tag == "NR") {
      retrieve = 0;
      tag = "";
   }

   // The working dir
   TString sandbox(gSystem->WorkingDirectory());
   sandbox.ReplaceAll(gSystem->HomeDirectory(),"");
   sandbox.ReplaceAll("/","-");
   sandbox.Replace(0,1,"/",1);
   if (strlen(gEnv->GetValue("ProofLite.Sandbox", "")) > 0) {
      sandbox.Insert(0, gEnv->GetValue("ProofLite.Sandbox", ""));
   } else if (strlen(gEnv->GetValue("Proof.Sandbox", "")) > 0) {
      sandbox.Insert(0, gEnv->GetValue("Proof.Sandbox", ""));
   } else {
      TString sb;
      sb.Form("~/%s", kPROOF_WorkDir);
      sandbox.Insert(0, sb.Data());
   }
   gSystem->ExpandPathName(sandbox);

   TString sessiondir;
   if (tag.Length() > 0) {
      sessiondir.Form("%s/session-%s", sandbox.Data(), tag.Data());
      if (gSystem->AccessPathName(sessiondir, kReadPermission)) {
         Error("GetSessionLogs", "information for session '%s' not available", tag.Data());
         return (TProofLog *)0;
      }
   } else {
      // Get the list of available dirs
      TSortedList *olddirs = new TSortedList(kFALSE);
      void *dirp = gSystem->OpenDirectory(sandbox);
      if (dirp) {
         const char *e = 0;
         while ((e = gSystem->GetDirEntry(dirp))) {
            if (!strncmp(e, "session-", 8)) {
               TString d(e);
               Int_t i = d.Last('-');
               if (i != kNPOS) d.Remove(i);
               i = d.Last('-');
               if (i != kNPOS) d.Remove(0,i+1);
               TString path = Form("%s/%s", sandbox.Data(), e);
               olddirs->Add(new TNamed(d, path));
            }
         }
         gSystem->FreeDirectory(dirp);
      }

      // Check isess
      if (isess > olddirs->GetSize() - 1) {
         Warning("GetSessionLogs",
                 "session index out of range (%d): take oldest available session", isess);
         isess = olddirs->GetSize() - 1;
      }

      // Locate the session dir
      Int_t isx = isess;
      TNamed *n = (TNamed *) olddirs->First();
      while (isx-- > 0) {
         olddirs->Remove(n);
         delete n;
         n = (TNamed *) olddirs->First();
      }
      if (!n) {
         Error("GetSessionLogs", "cannot locate session dir for index '%d' under '%s':"
                                 " cannot continue!", isess, sandbox.Data());
         return (TProofLog *)0;
      }
      sessiondir = n->GetTitle();
      tag = gSystem->BaseName(sessiondir);
      tag.ReplaceAll("session-", "");

      // Cleanup
      olddirs->SetOwner();
      delete olddirs;
   }
   Info("GetSessionLogs", "analysing session dir %s", sessiondir.Data());

   // Create the instance now
   pl = new TProofLog(tag, "", this);

   void *dirp = gSystem->OpenDirectory(sessiondir);
   if (dirp) {
      TSortedList *logs = new TSortedList;
      const char *e = 0;
      while ((e = gSystem->GetDirEntry(dirp))) {
         TString fn(e);
         if (fn.EndsWith(".log") && fn.CountChar('-') > 0) {
            TString ord, url;
            if (fn.BeginsWith("session-")) {
               ord = "-1";
            } else if (fn.BeginsWith("worker-")) {
               ord = fn;
               ord.ReplaceAll("worker-", "");
               Int_t id = ord.First('-');
               if (id != kNPOS) {
                  ord.Remove(id);
               } else if (ord.Contains(".valgrind")) {
                  // Add to the list (special tag for valgrind outputs)
                  ord.ReplaceAll(".valgrind.log","-valgrind");
               } else {
                  // Not a good path
                  ord = "";
               }
               if (!ord.IsNull()) ord.ReplaceAll("0.", "");
            }
            if (!ord.IsNull()) {
               url = Form("%s/%s", sessiondir.Data(), e);
               // Add to the list
               logs->Add(new TNamed(ord, url));
               // Notify
               if (gDebug > 1)
                  Info("GetSessionLogs", "ord: %s, url: %s", ord.Data(), url.Data());
            }
         }
      }
      gSystem->FreeDirectory(dirp);

      TIter nxl(logs);
      TNamed *n = 0;
      while ((n = (TNamed *) nxl())) {
         TString ord = Form("0.%s", n->GetName());
         if (ord == "0.-1") ord = "0";
         // Add to the list
         pl->Add(ord, n->GetTitle());
      }

      // Cleanup
      logs->SetOwner();
      delete logs;
   }

   // Retrieve the default part
   if (pl && retrieve) {
      const char *pat = pattern ? pattern : "-v \"| SvcMsg\"";
      if (pat && strlen(pat) > 0)
         pl->Retrieve("*", TProofLog::kGrep, 0, pat);
      else
         pl->Retrieve();
   }

   // Done
   return pl;
}

//______________________________________________________________________________
TObjString *TProofMgrLite::ReadBuffer(const char *fin, Long64_t ofs, Int_t len)
{
   // Read 'len' bytes from offset 'ofs' of the local file 'fin'.
   // Returns a TObjString with the content or 0, in case of failure

   if (!fin || strlen(fin) <= 0) {
      Error("ReadBuffer", "undefined path!");
      return (TObjString *)0;
   }

   // Open the file
   TString fn = TUrl(fin).GetFile();
   Int_t fd = open(fn.Data(), O_RDONLY);
   if (fd < 0) {
      Error("ReadBuffer", "problems opening file %s", fn.Data());
      return (TObjString *)0;
   }

   // Total size
   off_t start = 0, end = lseek(fd, (off_t) 0, SEEK_END);

   // Set the offset
   if (ofs > 0 && ofs < end) {
      start = lseek(fd, (off_t) ofs, SEEK_SET);
   } else {
      start = lseek(fd, (off_t) 0, SEEK_SET);
   }
   if (len > (end - start + 1) || len <= 0)
      len = end - start + 1;

   TString outbuf;
   const Int_t kMAXBUF = 32768;
   char buf[kMAXBUF];
   Int_t left = len;
   Int_t wanted = (left > kMAXBUF - 1) ? kMAXBUF - 1 : left;
   do {
      while ((len = read(fd, buf, wanted)) < 0 && TSystem::GetErrno() == EINTR)
         TSystem::ResetErrno();

      if (len < 0) {
         Error("ReadBuffer", "error reading file %s", fn.Data());
         close(fd);
         return (TObjString *)0;
      } else if (len > 0) {
         if (len == wanted)
            buf[len-1] = '\n';
         buf[len] = '\0';
         outbuf += buf;
      }

      // Update counters
      left -= len;
      wanted = (left > kMAXBUF - 1) ? kMAXBUF - 1 : left;

   } while (len > 0 && left > 0);

   // Close file
   close(fd);

   // Done
   return new TObjString(outbuf.Data());
}

//______________________________________________________________________________
TObjString *TProofMgrLite::ReadBuffer(const char *fin, const char *pattern)
{
   // Read lines containing 'pattern' in 'file'.
   // Returns a TObjString with the content or 0, in case of failure

   // If no pattern, read everything
   if (!pattern || strlen(pattern) <= 0)
      return (TObjString *)0;

   if (!fin || strlen(fin) <= 0) {
      Error("ReadBuffer", "undefined path!");
      return (TObjString *)0;
   }
   TString fn = TUrl(fin).GetFile();

   TString pat(pattern);
   // Check if "-v"
   Bool_t excl = kFALSE;
   if (pat.Contains("-v ")) {
      pat.ReplaceAll("-v ", "");
      excl = kTRUE;
   }
   pat = pat.Strip(TString::kLeading, ' ');
   pat = pat.Strip(TString::kTrailing, ' ');
   pat = pat.Strip(TString::kLeading, '\"');
   pat = pat.Strip(TString::kTrailing, '\"');

   // Use a regular expression
   TRegexp re(pat);

   // Open file with file info
   ifstream in;
   in.open(fn.Data());

   TString outbuf;

   // Read the input list of files and add them to the chain
   TString line;
   while(in.good()) {

      // Read next line
      line.ReadLine(in);

      // Keep only lines with pattern
      if ((excl && line.Index(re) != kNPOS) ||
          (!excl && line.Index(re) == kNPOS)) continue;

      // Remove trailing '\n', if any
      if (!line.EndsWith("\n")) line.Append('\n');

      // Add to output
      outbuf += line;
   }
   in.close();

   // Done
   return new TObjString(outbuf.Data());
}
<|endoftext|>


<commit_before>

#include "SGRenderNode.h"

#include "omniBoundingVolume.h"
#include "cullBinAttrib.h"
#include "cullableObject.h"
#include "geomVertexFormat.h"
#include "cullHandler.h"
#include "geomVertexWriter.h"
#include "geomTriangles.h"
#include "shaderAttrib.h"
#include "geomVertexData.h"
#include "geom.h"

#include "StaticGeometryHandler.h"
#include "SGRenderCallback.h"

#include "../common.h"

TypeHandle SGRenderNode::_type_handle;

SGRenderNode::SGRenderNode(StaticGeometryHandler *handler, PT(Shader) collector_shader) : PandaNode("SGRender") {
    _handler = handler;
    set_internal_bounds(new OmniBoundingVolume);
    set_final(true);
    create_default_geom();

    CPT(RenderAttrib) sattrib = ShaderAttrib::make_off();
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("DatasetTex", handler->get_dataset_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("MappingTex", handler->get_mapping_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("IndirectTex", handler->get_indirect_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("DrawnObjectsTex", handler->get_drawn_objects_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("DynamicStripsTex", handler->get_dynamic_strips_tex());

    _base_render_state = RenderState::make(
        sattrib
    );

    _collect_render_state = RenderState::make(
        DCAST(ShaderAttrib, sattrib)->set_shader(collector_shader)
    );

}

SGRenderNode::~SGRenderNode() {

}

bool SGRenderNode::is_renderable() const {
  return true;
}

void SGRenderNode::add_for_draw(CullTraverser *trav, CullTraverserData &data) {

    // Execute the collector shader
    CullableObject *collect_obj = new CullableObject(NULL, _collect_render_state, TransformState::make_identity());
    collect_obj->set_draw_callback(new SGRenderCallback(this, 0));
    trav->get_cull_handler()->record_object(collect_obj, trav);

    // Finally render the triangle strip
    CPT(TransformState) internal_transform = data.get_internal_transform(trav);
    CPT(RenderState) state = _base_render_state->compose(data._state);
    CullableObject *object =
      new CullableObject(_geom_strip, state, internal_transform);
    object->set_draw_callback(new SGRenderCallback(this, 1));
    trav->get_cull_handler()->record_object(object, trav);

    _handler->clear_render_list();

}

void SGRenderNode::do_draw_callback(CallbackData* cbdata, int reason) {

    GeomDrawCallbackData *data = (GeomDrawCallbackData *)cbdata;
    CullableObject *obj = data->get_object();
    GraphicsStateGuardianBase *gsg = data->get_gsg();

    if (reason == 0) {
        // Execute collector shader
        gsg->dispatch_compute(1, 1, 1);
    } else if (reason == 1) {
        // Render default object

		Thread *current_thread = Thread::get_current_thread();
		const GeomPipelineReader* geom_reader = new GeomPipelineReader(obj->_geom, current_thread);

		CPT(GeomVertexData) vertex_data = geom_reader->get_vertex_data();
		PT(GeomMunger) munger = gsg->get_geom_munger(obj->_state, current_thread);
		if (!munger->munge_geom(obj->_geom, vertex_data, true, current_thread)) {
			cout << "ERROR: munge geom failed " << endl;
			return;// error
		}

		const GeomVertexDataPipelineReader* data_reader = new GeomVertexDataPipelineReader(vertex_data, current_thread);
		data_reader->check_array_readers();

		// Bind vertex buffer and shit
		if (!gsg->begin_draw_primitives(geom_reader, munger, data_reader, true)) {
		  return;// error
		}

		// Prepare the image buffer texture
		//GLTextureContext *gtc = DCAST(GLTextureContext, texture->prepare_now(gsg));
		//assert(gtc->_buffer != 0);

		//glBindBuffer(GL_WHATEVER_INDIRECT_DRAW_BUFFER, gtc->_buffer);
		//glMultiDrawArraysIndirect(GL_TRIANGLES, 0, 0, 0);

		gsg->end_draw_primitives();

		delete data_reader;
		delete geom_reader;

	}
}

void SGRenderNode::create_default_geom() {

    CPT(GeomVertexFormat) vformat = GeomVertexFormat::get_v3();
    PT(GeomVertexData) vdata = new GeomVertexData("vdata", vformat, Geom::UH_static);
    vdata->set_num_rows(SG_TRI_GROUP_SIZE * 3);

    GeomVertexWriter writer(vdata, "vertex");

    for (size_t i = 0; i < SG_TRI_GROUP_SIZE; ++i) {
        writer.add_data3f(0, 0, 0);
        writer.add_data3f(0, 1, 0);
        writer.add_data3f(1, 1, 0);
    }

    PT(GeomTriangles) triangles = new GeomTriangles(Geom::UH_static);
    triangles->add_next_vertices(SG_TRI_GROUP_SIZE * 3);

    _geom_strip = new Geom(vdata);
    _geom_strip->add_primitive(triangles);
}

<commit_msg>Further progress on the static geometry rendering<commit_after>

#include "SGRenderNode.h"

#include "omniBoundingVolume.h"
#include "cullBinAttrib.h"
#include "cullableObject.h"
#include "geomVertexFormat.h"
#include "cullHandler.h"
#include "geomVertexWriter.h"
#include "geomTriangles.h"
#include "shaderAttrib.h"
#include "geomVertexData.h"
#include "geom.h"

#include "StaticGeometryHandler.h"
#include "SGRenderCallback.h"

#include "glgsg.h"

#include "../common.h"

TypeHandle SGRenderNode::_type_handle;

SGRenderNode::SGRenderNode(StaticGeometryHandler *handler, PT(Shader) collector_shader) : PandaNode("SGRender") {
    _handler = handler;
    set_internal_bounds(new OmniBoundingVolume);
    set_final(true);
    create_default_geom();

    CPT(RenderAttrib) sattrib = ShaderAttrib::make_off();
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("DatasetTex", handler->get_dataset_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("MappingTex", handler->get_mapping_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("IndirectTex", handler->get_indirect_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("DrawnObjectsTex", handler->get_drawn_objects_tex());
    sattrib = DCAST(ShaderAttrib, sattrib)->set_shader_input("DynamicStripsTex", handler->get_dynamic_strips_tex());

    _base_render_state = RenderState::make(
        sattrib
    );

    _collect_render_state = RenderState::make(
        DCAST(ShaderAttrib, sattrib)->set_shader(collector_shader)
    );

}

SGRenderNode::~SGRenderNode() {

}

bool SGRenderNode::is_renderable() const {
  return true;
}

void SGRenderNode::add_for_draw(CullTraverser *trav, CullTraverserData &data) {

    // Execute the collector shader
    CullableObject *collect_obj = new CullableObject(NULL, _collect_render_state, TransformState::make_identity());
    collect_obj->set_draw_callback(new SGRenderCallback(this, 0));
    trav->get_cull_handler()->record_object(collect_obj, trav);

    // Finally render the triangle strip
    CPT(TransformState) internal_transform = data.get_internal_transform(trav);
    CPT(RenderState) state = _base_render_state->compose(data._state);
    CullableObject *object =
      new CullableObject(_geom_strip, state, internal_transform);
    object->set_draw_callback(new SGRenderCallback(this, 1));
    trav->get_cull_handler()->record_object(object, trav);

    _handler->clear_render_list();

}

void SGRenderNode::do_draw_callback(CallbackData* cbdata, int reason) {

    GeomDrawCallbackData *data = (GeomDrawCallbackData *)cbdata;
    CullableObject *obj = data->get_object();
    GraphicsStateGuardianBase *gsg = data->get_gsg();

    if (reason == 0) {
        // Execute collector shader
        gsg->dispatch_compute(1, 1, 1);
    } else if (reason == 1) {
        // Render default object

		Thread *current_thread = Thread::get_current_thread();

		const GeomPipelineReader* geom_reader = new GeomPipelineReader(obj->_geom, current_thread);

		CPT(GeomVertexData) vertex_data = geom_reader->get_vertex_data();
		PT(GeomMunger) munger = gsg->get_geom_munger(obj->_state, current_thread);
		if (!munger->munge_geom(obj->_geom, vertex_data, true, current_thread)) {
			cout << "ERROR: munge geom failed " << endl;
			return;// error
		}

		const GeomVertexDataPipelineReader* data_reader = new GeomVertexDataPipelineReader(vertex_data, current_thread);
		data_reader->check_array_readers();

		// Bind vertex buffer and shit
		if (!gsg->begin_draw_primitives(geom_reader, munger, data_reader, true)) {
		  return;// error
		}

		// Prepare the image buffer texture
		TextureContext* tc = _handler->get_indirect_tex()->prepare_now( 0, gsg->get_prepared_objects(), gsg );
		GLTextureContext *gtc = (GLTextureContext*)tc;
		assert(gtc->_buffer != 0);

		GLGraphicsStateGuardian* glgsg = (GLGraphicsStateGuardian*)gsg;

		glgsg->_glBindBuffer(GL_DRAW_INDIRECT_BUFFER, gtc->_buffer);
		glgsg->_glMultiDrawArraysIndirect(GL_TRIANGLES, 0, 0, 0);

		gsg->end_draw_primitives();

		delete data_reader;
		delete geom_reader;

	}
}

void SGRenderNode::create_default_geom() {

    CPT(GeomVertexFormat) vformat = GeomVertexFormat::get_v3();
    PT(GeomVertexData) vdata = new GeomVertexData("vdata", vformat, Geom::UH_static);
    vdata->set_num_rows(SG_TRI_GROUP_SIZE * 3);

    GeomVertexWriter writer(vdata, "vertex");

    for (size_t i = 0; i < SG_TRI_GROUP_SIZE; ++i) {
        writer.add_data3f(0, 0, 0);
        writer.add_data3f(0, 1, 0);
        writer.add_data3f(1, 1, 0);
    }

    PT(GeomTriangles) triangles = new GeomTriangles(Geom::UH_static);
    triangles->add_next_vertices(SG_TRI_GROUP_SIZE * 3);

    _geom_strip = new Geom(vdata);
    _geom_strip->add_primitive(triangles);
}

<|endoftext|>


<commit_before>#include "MainFrame.hpp"
#include "misc_ui.hpp"
#include <wx/accel.h>
#include <wx/utils.h>

#include "AboutDialog.hpp"
#include "libslic3r.h"

namespace Slic3r { namespace GUI {

wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
wxEND_EVENT_TABLE()

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
        : MainFrame(title, pos, size, nullptr) {}
MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, std::shared_ptr<Settings> _gui_config)
        : wxFrame(NULL, wxID_ANY, title, pos, size), loaded(false),
        tabpanel(nullptr), controller(nullptr), plater(nullptr), gui_config(_gui_config), preset_editor_tabs(std::map<wxWindowID, PresetEditor*>())
{
    // Set icon to either the .ico if windows or png for everything else.
    if (the_os == OS::Windows)
        this->SetIcon(wxIcon(var("Slic3r.ico"), wxBITMAP_TYPE_ICO));
    else
        this->SetIcon(wxIcon(var("Slic3r_128px.png"), wxBITMAP_TYPE_PNG));

    this->init_tabpanel();
    this->init_menubar();

    wxToolTip::SetAutoPop(TOOLTIP_TIMER);

    // initialize status bar
    // we call SetStatusBar() here because MainFrame is the direct owner.
    this->statusbar = new ProgressStatusBar(this, -1);
    wxString welcome_text {_("Version SLIC3R_VERSION_REPLACE - Remember to check for updates at http://slic3r.org/")};
    welcome_text.Replace("SLIC3R_VERSION_REPLACE", wxString(SLIC3R_VERSION));
    this->statusbar->SetStatusText(welcome_text);
    this->SetStatusBar(this->statusbar);

    this->loaded = 1;

    // Initialize layout
    {
        wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        sizer->Add(this->tabpanel, 1, wxEXPAND);
        sizer->SetSizeHints(this);
        this->Fit();
        this->SetMinSize(wxSize(760, 490));
        this->SetSize(this->GetMinSize());
        wxTheApp->SetTopWindow(this);
        this->Show();
        this->Layout();
    }
    // Set up event handlers.
    this->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent& e) {
        if (e.CanVeto()) {
            if (!this->plater->prompt_unsaved_changes()) {
                e.Veto();
                return;
            }
            /*
            if ($self->{controller} && $self->{controller}->printing) {
                my $confirm = Wx::MessageDialog->new($self, "You are currently printing. Do you want to stop printing and continue anyway?",
                    'Unfinished Print', wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
                if ($confirm->ShowModal == wxID_NO) {
                    $event->Veto;
                    return;
                }
            }

            */
            // save window size
            gui_config->save_window_pos(this, "main_frame");

            // Propagate event
            e.Skip();
        }
    });
/*
    # declare events
    EVT_CLOSE($self, sub {
        my (undef, $event) = @_;

        # propagate event
        $event->Skip;
    });
*/
}

/// Private initialization function for the main frame tab panel.
void MainFrame::init_tabpanel()
{
    this->tabpanel = new wxAuiNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP);
    auto panel = this->tabpanel;

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CHANGED, ([=](wxAuiNotebookEvent& e)
    {
        auto tabpanel = this->tabpanel;
        // TODO: trigger processing for activation event
        if (tabpanel->GetSelection() > 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else if (this->gui_config->show_host == false && tabpanel->GetSelection() == 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | ~wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        }
    }), panel->GetId());

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CLOSE, ([=](wxAuiNotebookEvent& e)
    {
        if (typeid(panel) == typeid(Slic3r::GUI::PresetEditor)) {
            wxDELETE(this->preset_editor_tabs[panel->GetId()]);
        }
        wxTheApp->CallAfter([=] { this->tabpanel->SetSelection(0); });
    }), panel->GetId());

    this->plater = new Slic3r::GUI::Plater(panel, _("Plater"), gui_config);
    this->controller = new Slic3r::GUI::Controller(panel, _("Controller"));

    panel->AddPage(this->plater, this->plater->GetName());
    if (this->gui_config->show_host) panel->AddPage(this->controller, this->controller->GetName());

}

void MainFrame::init_menubar()
{

    wxMenu* menuFile = new wxMenu();
    {
        append_menu_item(menuFile, _(L"Open STL/OBJ/AMF/3MF…"), _("Open a model"), [=](wxCommandEvent& e) { if (this->plater != nullptr) this->plater->add();}, wxID_ANY, "brick_add.png", "Ctrl+O");
    }

    wxMenu* menuPlater = new wxMenu();
    {
    }
    wxMenu* menuObject = new wxMenu();
    {
    }
    wxMenu* menuSettings = new wxMenu();
    {
    }
    wxMenu* menuView = new wxMenu();
    {
    }
    wxMenu* menuWindow = new wxMenu();
    {
    }
    wxMenu* menuHelp = new wxMenu();
    {
        // TODO: Reimplement config wizard
        //menuHelp->AppendSeparator();
        append_menu_item(menuHelp, _("Slic3r &Website"), _("Open the Slic3r website in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://www.slic3r.org");
        });
        append_menu_item(menuHelp, _("Check for &Updates..."), _("Check for new Slic3r versions"), [=](wxCommandEvent& e)
        {
            check_version(true);
        });
        append_menu_item(menuHelp, _("Slic3r &Manual"), _("Open the Slic3r manual in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://manual.slic3r.org/");
        });
        append_menu_item(menuHelp, _("&About Slic3r"), _("Show about dialog"), [=](wxCommandEvent& e)
        {
            auto about = new AboutDialog(nullptr);
            about->ShowModal();
            about->Destroy();
        }, wxID_ABOUT);

    }

    wxMenuBar* menubar = new wxMenuBar();
    menubar->Append(menuFile, _("&File"));
    menubar->Append(menuPlater, _("&Plater"));
    menubar->Append(menuObject, _("&Object"));
    menubar->Append(menuSettings, _("&Settings"));
    menubar->Append(menuView, _("&View"));
    menubar->Append(menuWindow, _("&Window"));
    menubar->Append(menuHelp, _("&Help"));

    this->SetMenuBar(menubar);

}

}} // Namespace Slic3r::GUI
<commit_msg>removed commented Perl code from MainFrame<commit_after>#include "MainFrame.hpp"
#include "misc_ui.hpp"
#include <wx/accel.h>
#include <wx/utils.h>

#include "AboutDialog.hpp"
#include "libslic3r.h"

namespace Slic3r { namespace GUI {

wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
wxEND_EVENT_TABLE()

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
        : MainFrame(title, pos, size, nullptr) {}
MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, std::shared_ptr<Settings> _gui_config)
        : wxFrame(NULL, wxID_ANY, title, pos, size), loaded(false),
        tabpanel(nullptr), controller(nullptr), plater(nullptr), gui_config(_gui_config), preset_editor_tabs(std::map<wxWindowID, PresetEditor*>())
{
    // Set icon to either the .ico if windows or png for everything else.
    if (the_os == OS::Windows)
        this->SetIcon(wxIcon(var("Slic3r.ico"), wxBITMAP_TYPE_ICO));
    else
        this->SetIcon(wxIcon(var("Slic3r_128px.png"), wxBITMAP_TYPE_PNG));

    this->init_tabpanel();
    this->init_menubar();

    wxToolTip::SetAutoPop(TOOLTIP_TIMER);

    // initialize status bar
    // we call SetStatusBar() here because MainFrame is the direct owner.
    this->statusbar = new ProgressStatusBar(this, -1);
    wxString welcome_text {_("Version SLIC3R_VERSION_REPLACE - Remember to check for updates at http://slic3r.org/")};
    welcome_text.Replace("SLIC3R_VERSION_REPLACE", wxString(SLIC3R_VERSION));
    this->statusbar->SetStatusText(welcome_text);
    this->SetStatusBar(this->statusbar);

    this->loaded = 1;

    // Initialize layout
    {
        wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        sizer->Add(this->tabpanel, 1, wxEXPAND);
        sizer->SetSizeHints(this);
        this->Fit();
        this->SetMinSize(wxSize(760, 490));
        this->SetSize(this->GetMinSize());
        wxTheApp->SetTopWindow(this);
        this->Show();
        this->Layout();
    }
    // Set up event handlers.
    this->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent& e) {
        if (e.CanVeto()) {
            if (!this->plater->prompt_unsaved_changes()) {
                e.Veto();
                return;
            }
            /*
            if ($self->{controller} && $self->{controller}->printing) {
                my $confirm = Wx::MessageDialog->new($self, "You are currently printing. Do you want to stop printing and continue anyway?",
                    'Unfinished Print', wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
                if ($confirm->ShowModal == wxID_NO) {
                    $event->Veto;
                    return;
                }
            }

            */
            // save window size
            gui_config->save_window_pos(this, "main_frame");

            // Propagate event
            e.Skip();
        }
    });
}

/// Private initialization function for the main frame tab panel.
void MainFrame::init_tabpanel()
{
    this->tabpanel = new wxAuiNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP);
    auto panel = this->tabpanel;

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CHANGED, ([=](wxAuiNotebookEvent& e)
    {
        auto tabpanel = this->tabpanel;
        // TODO: trigger processing for activation event
        if (tabpanel->GetSelection() > 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else if (this->gui_config->show_host == false && tabpanel->GetSelection() == 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | ~wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        }
    }), panel->GetId());

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CLOSE, ([=](wxAuiNotebookEvent& e)
    {
        if (typeid(panel) == typeid(Slic3r::GUI::PresetEditor)) {
            wxDELETE(this->preset_editor_tabs[panel->GetId()]);
        }
        wxTheApp->CallAfter([=] { this->tabpanel->SetSelection(0); });
    }), panel->GetId());

    this->plater = new Slic3r::GUI::Plater(panel, _("Plater"), gui_config);
    this->controller = new Slic3r::GUI::Controller(panel, _("Controller"));

    panel->AddPage(this->plater, this->plater->GetName());
    if (this->gui_config->show_host) panel->AddPage(this->controller, this->controller->GetName());

}

void MainFrame::init_menubar()
{

    wxMenu* menuFile = new wxMenu();
    {
        append_menu_item(menuFile, _(L"Open STL/OBJ/AMF/3MF…"), _("Open a model"), [=](wxCommandEvent& e) { if (this->plater != nullptr) this->plater->add();}, wxID_ANY, "brick_add.png", "Ctrl+O");
    }

    wxMenu* menuPlater = new wxMenu();
    {
    }
    wxMenu* menuObject = new wxMenu();
    {
    }
    wxMenu* menuSettings = new wxMenu();
    {
    }
    wxMenu* menuView = new wxMenu();
    {
    }
    wxMenu* menuWindow = new wxMenu();
    {
    }
    wxMenu* menuHelp = new wxMenu();
    {
        // TODO: Reimplement config wizard
        //menuHelp->AppendSeparator();
        append_menu_item(menuHelp, _("Slic3r &Website"), _("Open the Slic3r website in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://www.slic3r.org");
        });
        append_menu_item(menuHelp, _("Check for &Updates..."), _("Check for new Slic3r versions"), [=](wxCommandEvent& e)
        {
            check_version(true);
        });
        append_menu_item(menuHelp, _("Slic3r &Manual"), _("Open the Slic3r manual in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://manual.slic3r.org/");
        });
        append_menu_item(menuHelp, _("&About Slic3r"), _("Show about dialog"), [=](wxCommandEvent& e)
        {
            auto about = new AboutDialog(nullptr);
            about->ShowModal();
            about->Destroy();
        }, wxID_ABOUT);

    }

    wxMenuBar* menubar = new wxMenuBar();
    menubar->Append(menuFile, _("&File"));
    menubar->Append(menuPlater, _("&Plater"));
    menubar->Append(menuObject, _("&Object"));
    menubar->Append(menuSettings, _("&Settings"));
    menubar->Append(menuView, _("&View"));
    menubar->Append(menuWindow, _("&Window"));
    menubar->Append(menuHelp, _("&Help"));

    this->SetMenuBar(menubar);

}

}} // Namespace Slic3r::GUI
<|endoftext|>


<commit_before>#ifndef BFC_LEXER_HPP
#define BFC_LEXER_HPP

#include "source.hpp"

namespace bfc {

struct position {
  unsigned long pos;
  unsigned long row;
  unsigned long col;
};

struct token {

  enum type {
    INC,
    DEC,
    MOVE_L,
    MOVE_R,
    LOOP_BEGIN,
    LOOP_END,
    PUT_CHAR,
    GET_CHAR
  };

  type kind;
  position pos;

};

template <class Source, class Traits = source_traits<Source>>
class lexer {

  using traits = Traits;

public:

  enum result {
    FAIL = -1,
    OK = 0,
    DONE = 1
  };

  using source_type = typename traits::source_type;

  lexer(source_type source) : source(std::move(source)) {}

  result next(token &tok) noexcept {
    token::type kind;
    for (;;) {
      int ch = traits::next(source);
      advance(ch);
      switch (ch) {
        case EOF: return source.eof() ? DONE : FAIL;
        case '+': kind = token::INC; break;
        case '-': kind = token::DEC; break;
        case '<': kind = token::MOVE_L; break;
        case '>': kind = token::MOVE_R; break;
        case '.': kind = token::PUT_CHAR; break;
        case ',': kind = token::GET_CHAR; break;
        /* ignore unrecognized characters */
        default: continue;
      }
      break;
    }
    tok.pos = pos;
    tok.kind = kind;
    return OK;
  }

private:

  void advance(int ch)
  {
    pos.pos += 1;
    if (ch == '\n') {
      pos.col = 0;
      pos.row += 1;
    } else {
      pos.col += 1;
    }
  }

  position pos;
  source_type source;

};

}

#endif /* !BFC_LEXER_HPP */
<commit_msg>Added loop tokens to lexer<commit_after>#ifndef BFC_LEXER_HPP
#define BFC_LEXER_HPP

#include "source.hpp"

namespace bfc {

struct position {
  unsigned long pos;
  unsigned long row;
  unsigned long col;
};

struct token {

  enum type {
    INC,
    DEC,
    MOVE_L,
    MOVE_R,
    LOOP_BEGIN,
    LOOP_END,
    PUT_CHAR,
    GET_CHAR
  };

  type kind;
  position pos;

};

template <class Source, class Traits = source_traits<Source>>
class lexer {

  using traits = Traits;

public:

  enum result {
    FAIL = -1,
    OK = 0,
    DONE = 1
  };

  using source_type = typename traits::source_type;

  lexer(source_type source) : source(std::move(source)) {}

  result next(token &tok) noexcept {
    token::type kind;
    for (;;) {
      int ch = traits::next(source);
      advance(ch);
      switch (ch) {
        case EOF: return source.eof() ? DONE : FAIL;
        case '+': kind = token::INC; break;
        case '-': kind = token::DEC; break;
        case '<': kind = token::MOVE_L; break;
        case '>': kind = token::MOVE_R; break;
        case '[': kind = token::LOOP_BEGIN; break;
        case ']': kind = token::LOOP_END; break;
        case '.': kind = token::PUT_CHAR; break;
        case ',': kind = token::GET_CHAR; break;
        /* unrecognized characters are comments */
        default: continue;
      }
      break;
    }
    tok.pos = pos;
    tok.kind = kind;
    return OK;
  }

private:

  void advance(int ch)
  {
    pos.pos += 1;
    if (ch == '\n') {
      pos.col = 0;
      pos.row += 1;
    } else {
      pos.col += 1;
    }
  }

  position pos;
  source_type source;

};

}

#endif /* !BFC_LEXER_HPP */
<|endoftext|>


<commit_before>/**
 * @file obstacle_distance_gradient.cpp
 * @brief This defines a Robot Model for the Stomp Planner.
 *
 * @author Jorge Nicho
 * @date Jul 22, 2016
 * @version TODO
 * @bug No known bugs
 *
 * @copyright Copyright (c) 2016, Southwest Research Institute
 *
 * @license Software License Agreement (Apache License)\n
 * \n
 * 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\n
 * \n
 * http://www.apache.org/licenses/LICENSE-2.0\n
 * \n
 * 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 <stomp_moveit/cost_functions/obstacle_distance_gradient.h>
#include <ros/console.h>
#include <pluginlib/class_list_macros.h>
#include <moveit/robot_state/conversions.h>

PLUGINLIB_EXPORT_CLASS(stomp_moveit::cost_functions::ObstacleDistanceGradient,stomp_moveit::cost_functions::StompCostFunction)

namespace stomp_moveit
{
namespace cost_functions
{

ObstacleDistanceGradient::ObstacleDistanceGradient() :
    name_("ObstacleDistanceGradient"),
    robot_state_()
{

}

ObstacleDistanceGradient::~ObstacleDistanceGradient()
{

}

bool ObstacleDistanceGradient::initialize(moveit::core::RobotModelConstPtr robot_model_ptr,
                                          const std::string& group_name, XmlRpc::XmlRpcValue& config)
{
  robot_model_ptr_ = robot_model_ptr;
  group_name_ = group_name;
  collision_request_.distance = true;
  collision_request_.group_name = group_name;
  return configure(config);
}

bool ObstacleDistanceGradient::configure(const XmlRpc::XmlRpcValue& config)
{

  try
  {
    // check parameter presence
    auto members = {"cost_weight" ,"max_distance"};
    for(auto& m : members)
    {
      if(!config.hasMember(m))
      {
        ROS_ERROR("%s failed to find the '%s' parameter",getName().c_str(),m);
        return false;
      }
    }

    XmlRpc::XmlRpcValue c = config;
    max_distance_ = static_cast<double>(c["max_distance"]);
    cost_weight_ = static_cast<double>(c["cost_weight"]);
  }
  catch(XmlRpc::XmlRpcException& e)
  {
    ROS_ERROR("%s failed to parse configuration parameters",name_.c_str());
    return false;
  }

  return true;
}

bool ObstacleDistanceGradient::setMotionPlanRequest(const planning_scene::PlanningSceneConstPtr& planning_scene,
                                                    const moveit_msgs::MotionPlanRequest &req,
                                                    const stomp_core::StompConfiguration &config,
                                                    moveit_msgs::MoveItErrorCodes& error_code)
{
  using namespace moveit::core;

  planning_scene_ = planning_scene;
  plan_request_ = req;
  error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;

  // storing robot state
  robot_state_.reset(new RobotState(robot_model_ptr_));
  if(!robotStateMsgToRobotState(req.start_state,*robot_state_,true))
  {
    ROS_ERROR("%s Failed to get current robot state from request",getName().c_str());
    return false;
  }

  return true;
}

bool ObstacleDistanceGradient::computeCosts(const Eigen::MatrixXd& parameters, std::size_t start_timestep,
                                            std::size_t num_timesteps, int iteration_number, int rollout_number,
                                            Eigen::VectorXd& costs, bool& validity)
{

  if(!robot_state_)
  {
    ROS_ERROR("%s Robot State has not been updated",getName().c_str());
    return false;
  }

  // allocating
  costs = Eigen::VectorXd::Zero(num_timesteps);
  const moveit::core::JointModelGroup* joint_group = robot_model_ptr_->getJointModelGroup(group_name_);

  if(parameters.cols()<start_timestep + num_timesteps)
  {
    ROS_ERROR_STREAM("Size in the 'parameters' matrix is less than required");
    return false;
  }

  // request the distance at each state
  double cost;
  double dist;
  for (auto t=start_timestep; t<start_timestep + num_timesteps; ++t)
  {
    robot_state_->setJointGroupPositions(joint_group,parameters.col(t));
    robot_state_->update();
    collision_result_.distance = max_distance_;

    planning_scene_->checkSelfCollision(collision_request_,collision_result_,*robot_state_,planning_scene_->getAllowedCollisionMatrix());
    dist = max_distance_ > collision_result_.distance ? max_distance_ : collision_result_.distance;

    if(dist >= max_distance_)
    {
      cost = 0; // away from obstacle
    }
    else if(dist < 0)
    {
      cost = 1.0; // in collision
    }
    else
    {
      cost = (max_distance_ - dist)/max_distance_;
    }

    costs(t) = cost;
  }

  validity = true;
  return true;
}

void ObstacleDistanceGradient::done(bool success,int total_iterations,double final_cost)
{
  robot_state_.reset();
}

} /* namespace cost_functions */
} /* namespace stomp_moveit */
<commit_msg>ObstacleDistanceGradient sets the validity to false if state is found in collision (#148)<commit_after>/**
 * @file obstacle_distance_gradient.cpp
 * @brief This defines a Robot Model for the Stomp Planner.
 *
 * @author Jorge Nicho
 * @date Jul 22, 2016
 * @version TODO
 * @bug No known bugs
 *
 * @copyright Copyright (c) 2016, Southwest Research Institute
 *
 * @license Software License Agreement (Apache License)\n
 * \n
 * 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\n
 * \n
 * http://www.apache.org/licenses/LICENSE-2.0\n
 * \n
 * 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 <stomp_moveit/cost_functions/obstacle_distance_gradient.h>
#include <ros/console.h>
#include <pluginlib/class_list_macros.h>
#include <moveit/robot_state/conversions.h>

PLUGINLIB_EXPORT_CLASS(stomp_moveit::cost_functions::ObstacleDistanceGradient,stomp_moveit::cost_functions::StompCostFunction)

namespace stomp_moveit
{
namespace cost_functions
{

ObstacleDistanceGradient::ObstacleDistanceGradient() :
    name_("ObstacleDistanceGradient"),
    robot_state_()
{

}

ObstacleDistanceGradient::~ObstacleDistanceGradient()
{

}

bool ObstacleDistanceGradient::initialize(moveit::core::RobotModelConstPtr robot_model_ptr,
                                          const std::string& group_name, XmlRpc::XmlRpcValue& config)
{
  robot_model_ptr_ = robot_model_ptr;
  group_name_ = group_name;
  collision_request_.distance = true;
  collision_request_.group_name = group_name;
  collision_request_.cost = false;
  collision_request_.max_contacts = 1;
  collision_request_.max_contacts_per_pair = 1;
  collision_request_.contacts = false;
  collision_request_.verbose = false;
  return configure(config);
}

bool ObstacleDistanceGradient::configure(const XmlRpc::XmlRpcValue& config)
{

  try
  {
    // check parameter presence
    auto members = {"cost_weight" ,"max_distance"};
    for(auto& m : members)
    {
      if(!config.hasMember(m))
      {
        ROS_ERROR("%s failed to find the '%s' parameter",getName().c_str(),m);
        return false;
      }
    }

    XmlRpc::XmlRpcValue c = config;
    max_distance_ = static_cast<double>(c["max_distance"]);
    cost_weight_ = static_cast<double>(c["cost_weight"]);
  }
  catch(XmlRpc::XmlRpcException& e)
  {
    ROS_ERROR("%s failed to parse configuration parameters",name_.c_str());
    return false;
  }

  return true;
}

bool ObstacleDistanceGradient::setMotionPlanRequest(const planning_scene::PlanningSceneConstPtr& planning_scene,
                                                    const moveit_msgs::MotionPlanRequest &req,
                                                    const stomp_core::StompConfiguration &config,
                                                    moveit_msgs::MoveItErrorCodes& error_code)
{
  using namespace moveit::core;

  planning_scene_ = planning_scene;
  plan_request_ = req;
  error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;

  // storing robot state
  robot_state_.reset(new RobotState(robot_model_ptr_));
  if(!robotStateMsgToRobotState(req.start_state,*robot_state_,true))
  {
    ROS_ERROR("%s Failed to get current robot state from request",getName().c_str());
    return false;
  }

  return true;
}

bool ObstacleDistanceGradient::computeCosts(const Eigen::MatrixXd& parameters, std::size_t start_timestep,
                                            std::size_t num_timesteps, int iteration_number, int rollout_number,
                                            Eigen::VectorXd& costs, bool& validity)
{

  if(!robot_state_)
  {
    ROS_ERROR("%s Robot State has not been updated",getName().c_str());
    return false;
  }

  // allocating
  costs = Eigen::VectorXd::Zero(num_timesteps);
  const moveit::core::JointModelGroup* joint_group = robot_model_ptr_->getJointModelGroup(group_name_);

  if(parameters.cols()<start_timestep + num_timesteps)
  {
    ROS_ERROR_STREAM("Size in the 'parameters' matrix is less than required");
    return false;
  }

  // request the distance at each state
  double cost;
  double dist;
  validity = true;
  for (auto t=start_timestep; t<start_timestep + num_timesteps; ++t)
  {
    collision_result_.clear();
    robot_state_->setJointGroupPositions(joint_group,parameters.col(t));
    robot_state_->update();
    collision_result_.distance = max_distance_;

    planning_scene_->checkSelfCollision(collision_request_,collision_result_,*robot_state_,planning_scene_->getAllowedCollisionMatrix());
    dist = collision_result_.collision ? -1.0 :collision_result_.distance ;

    if(dist >= max_distance_)
    {
      cost = 0; // away from obstacle
    }
    else if(dist < 0)
    {
      cost = 1.0; // in collision
      validity = false;
    }
    else
    {
      cost = (max_distance_ - dist)/max_distance_;
    }

    costs(t) = cost;
  }

  return true;
}

void ObstacleDistanceGradient::done(bool success,int total_iterations,double final_cost)
{
  robot_state_.reset();
}

} /* namespace cost_functions */
} /* namespace stomp_moveit */
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2011 Sergey Lisitsyn
 * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
 */

#include <shogun/preprocessor/LocallyLinearEmbedding.h>
#ifdef HAVE_LAPACK
#include <shogun/preprocessor/DimensionReductionPreprocessor.h>
#include <shogun/mathematics/arpack.h>
#include <shogun/mathematics/lapack.h>
#include <shogun/lib/FibonacciHeap.h>
#include <shogun/lib/common.h>
#include <shogun/mathematics/Math.h>
#include <shogun/io/SGIO.h>
#include <shogun/distance/EuclidianDistance.h>
#include <shogun/lib/Signal.h>

using namespace shogun;

CLocallyLinearEmbedding::CLocallyLinearEmbedding() :
		CDimensionReductionPreprocessor(), m_k(3), m_posdef(true)
{
}

CLocallyLinearEmbedding::~CLocallyLinearEmbedding()
{
}

bool CLocallyLinearEmbedding::init(CFeatures* features)
{
	return true;
}

void CLocallyLinearEmbedding::cleanup()
{
}

SGMatrix<float64_t> CLocallyLinearEmbedding::apply_to_feature_matrix(CFeatures* features)
{
	// shorthand for simplefeatures
	CSimpleFeatures<float64_t>* simple_features = (CSimpleFeatures<float64_t>*) features;
	ASSERT(simple_features);

	// get dimensionality and number of vectors of data
	int32_t dim = simple_features->get_num_features();
	ASSERT(m_target_dim<=dim);
	int32_t N = simple_features->get_num_vectors();
	ASSERT(m_k<N);

	// loop variables
	int32_t i,j,k;

	// compute distance matrix
	CDistance* distance = new CEuclidianDistance(simple_features,simple_features);
	SGMatrix<int32_t> neighborhood_matrix = get_neighborhood_matrix(distance);
	delete distance;

	// init W (weight) matrix
	float64_t* W_matrix = SG_CALLOC(float64_t, N*N);

	// init matrices and norm factor to be used
	float64_t* z_matrix = SG_MALLOC(float64_t, m_k*dim);
	float64_t* covariance_matrix = SG_MALLOC(float64_t, m_k*m_k);
	float64_t* id_vector = SG_MALLOC(float64_t, m_k);
	float64_t norming;

	// get feature matrix
	SGMatrix<float64_t> feature_matrix = simple_features->get_feature_matrix();

	for (i=0; i<N && !(CSignal::cancel_computations()); i++)
	{
		// compute local feature matrix containing neighbors of i-th vector
		for (j=0; j<m_k; j++)
		{
			for (k=0; k<dim; k++)
				z_matrix[j*dim+k] = feature_matrix.matrix[neighborhood_matrix.matrix[j*N+i]*dim+k];
		}

		// center features by subtracting i-th feature column
		for (j=0; j<m_k; j++)
		{
			for (k=0; k<dim; k++)
				z_matrix[j*dim+k] -= feature_matrix.matrix[i*dim+k];
		}

		// compute local covariance matrix
		cblas_dgemm(CblasColMajor,CblasTrans,CblasNoTrans,
		            m_k,m_k,dim,
		            1.0,z_matrix,dim,
		            z_matrix,dim,
		            0.0,covariance_matrix,m_k);

		for (j=0; j<m_k; j++)
			id_vector[j] = 1.0;

		// regularize in case of ill-posed system
		if (m_k>dim)
		{
			// compute tr(C)
			float64_t trace = 0.0;
			for (j=0; j<m_k; j++)
				trace += covariance_matrix[j*m_k+j];

			for (j=0; j<m_k; j++)
				covariance_matrix[j*m_k+j] += 1e-3*trace;
		}

		// solve system of linear equations: covariance_matrix * X = 1
		// covariance_matrix is a pos-def matrix
		clapack_dposv(CblasColMajor,CblasLower,m_k,1,covariance_matrix,m_k,id_vector,m_k);

		// normalize weights
		norming=0.0;
		for (j=0; j<m_k; j++)
			norming += id_vector[j];

		for (j=0; j<m_k; j++)
			id_vector[j]/=norming;

		// put weights into W matrix
		for (j=0; j<m_k; j++)
			W_matrix[N*neighborhood_matrix.matrix[j*N+i]+i]=id_vector[j];

	}

	// clean
	SG_FREE(id_vector);
	neighborhood_matrix.destroy_matrix();
	SG_FREE(z_matrix);
	SG_FREE(covariance_matrix);

	// W=I-W
	for (i=0; i<N; i++)
	{
		for (j=0; j<N; j++)
			W_matrix[j*N+i] = (i==j) ? 1.0-W_matrix[j*N+i] : -W_matrix[j*N+i];
	}

	// compute M=(W-I)'*(W-I)
	SGMatrix<float64_t> M_matrix(N,N);
	cblas_dgemm(CblasColMajor,CblasTrans, CblasNoTrans,
	            N,N,N,
	            1.0,W_matrix,N,
	            W_matrix,N,
	            0.0,M_matrix.matrix,N);

	SG_FREE(W_matrix);

	simple_features->set_feature_matrix(find_null_space(M_matrix,m_target_dim,false));
	M_matrix.destroy_matrix();

	return simple_features->get_feature_matrix();
}

SGVector<float64_t> CLocallyLinearEmbedding::apply_to_feature_vector(SGVector<float64_t> vector)
{
	SG_NOTIMPLEMENTED;
	return vector;
}

SGMatrix<float64_t> CLocallyLinearEmbedding::find_null_space(SGMatrix<float64_t> matrix, int dimension, bool force_lapack)
{
	int i,j;
	ASSERT(matrix.num_cols==matrix.num_rows);
	int N = matrix.num_cols;
	// get eigenvectors with ARPACK or LAPACK
	int eigenproblem_status = 0;

	bool arpack = false;

#ifdef HAVE_ARPACK
	arpack = true;
#endif

	if (force_lapack) arpack = false;

	float64_t* eigenvalues_vector;
	float64_t* eigenvectors;
	if (arpack)
	{
		// using ARPACK (faster)
		eigenvalues_vector = SG_MALLOC(float64_t, dimension+1);
		#ifdef HAVE_ARPACK
		arpack_dsaupd(matrix.matrix,NULL,N,dimension+1,"LA",3,m_posdef,0.0,eigenvalues_vector,matrix.matrix,eigenproblem_status);
		#endif
	}
	else
	{
		// using LAPACK (slower)
		eigenvalues_vector = SG_MALLOC(float64_t, N);
		eigenvectors = SG_MALLOC(float64_t,(dimension+1)*N);
		wrap_dsyevr('V','U',N,matrix.matrix,N,2,dimension+2,eigenvalues_vector,eigenvectors,&eigenproblem_status);
	}

	// check if failed
	if (eigenproblem_status)
		SG_ERROR("Eigenproblem failed with code: %d", eigenproblem_status);

	// allocate null space feature matrix
	float64_t* null_space_features = SG_MALLOC(float64_t, N*dimension);

	// construct embedding w.r.t to used solver (prefer ARPACK if available)
	if (arpack)
	{
		// ARPACKed eigenvectors
		for (i=0; i<dimension; i++)
		{
			for (j=0; j<N; j++)
				null_space_features[j*dimension+i] = matrix.matrix[j*(dimension+1)+i+1];
		}
	}
	else
	{
		// LAPACKed eigenvectors
		for (i=0; i<dimension; i++)
		{
			for (j=0; j<N; j++)
				null_space_features[j*dimension+i] = eigenvectors[i*N+j];
		}
	}
	SG_FREE(eigenvectors);
	SG_FREE(eigenvalues_vector);

	return SGMatrix<float64_t>(null_space_features,dimension,N);
}

SGMatrix<int32_t> CLocallyLinearEmbedding::get_neighborhood_matrix(CDistance* distance)
{
	int32_t i,j;
	SGMatrix<float64_t> distance_matrix = distance->get_distance_matrix();
	int32_t N = distance->get_num_vec_lhs();
	// init matrix and heap to be used
	int32_t* neighborhood_matrix = SG_MALLOC(int32_t, N*m_k);
	float64_t tmp;
	CFibonacciHeap* heap = new CFibonacciHeap(N);

	// construct neighborhood matrix (contains idxs of neighbors for
	// i-th object in i-th column)
	for (i=0; i<N; i++)
	{
		for (j=0; j<N; j++)
		{
			heap->insert(j,distance_matrix.matrix[i*N+j]);
		}

		heap->extract_min(tmp);

		for (j=0; j<m_k; j++)
			neighborhood_matrix[j*N+i] = heap->extract_min(tmp);

		heap->clear();
	}

	// cleanup
	delete heap;
	distance_matrix.destroy_matrix();

	return SGMatrix<int32_t>(neighborhood_matrix,m_k,N);
}

#endif /* HAVE_LAPACK */
<commit_msg>Fixed runtime error with LLE<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2011 Sergey Lisitsyn
 * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
 */

#include <shogun/preprocessor/LocallyLinearEmbedding.h>
#ifdef HAVE_LAPACK
#include <shogun/preprocessor/DimensionReductionPreprocessor.h>
#include <shogun/mathematics/arpack.h>
#include <shogun/mathematics/lapack.h>
#include <shogun/lib/FibonacciHeap.h>
#include <shogun/lib/common.h>
#include <shogun/mathematics/Math.h>
#include <shogun/io/SGIO.h>
#include <shogun/distance/EuclidianDistance.h>
#include <shogun/lib/Signal.h>

using namespace shogun;

CLocallyLinearEmbedding::CLocallyLinearEmbedding() :
		CDimensionReductionPreprocessor(), m_k(3), m_posdef(true)
{
}

CLocallyLinearEmbedding::~CLocallyLinearEmbedding()
{
}

bool CLocallyLinearEmbedding::init(CFeatures* features)
{
	return true;
}

void CLocallyLinearEmbedding::cleanup()
{
}

SGMatrix<float64_t> CLocallyLinearEmbedding::apply_to_feature_matrix(CFeatures* features)
{
	// shorthand for simplefeatures
	CSimpleFeatures<float64_t>* simple_features = (CSimpleFeatures<float64_t>*) features;
	ASSERT(simple_features);

	// get dimensionality and number of vectors of data
	int32_t dim = simple_features->get_num_features();
	ASSERT(m_target_dim<=dim);
	int32_t N = simple_features->get_num_vectors();
	ASSERT(m_k<N);

	// loop variables
	int32_t i,j,k;

	// compute distance matrix
	CDistance* distance = new CEuclidianDistance(simple_features,simple_features);
	SGMatrix<int32_t> neighborhood_matrix = get_neighborhood_matrix(distance);
	delete distance;

	// init W (weight) matrix
	float64_t* W_matrix = SG_CALLOC(float64_t, N*N);

	// init matrices and norm factor to be used
	float64_t* z_matrix = SG_MALLOC(float64_t, m_k*dim);
	float64_t* covariance_matrix = SG_MALLOC(float64_t, m_k*m_k);
	float64_t* id_vector = SG_MALLOC(float64_t, m_k);
	float64_t norming;

	// get feature matrix
	SGMatrix<float64_t> feature_matrix = simple_features->get_feature_matrix();

	for (i=0; i<N && !(CSignal::cancel_computations()); i++)
	{
		// compute local feature matrix containing neighbors of i-th vector
		for (j=0; j<m_k; j++)
		{
			for (k=0; k<dim; k++)
				z_matrix[j*dim+k] = feature_matrix.matrix[neighborhood_matrix.matrix[j*N+i]*dim+k];
		}

		// center features by subtracting i-th feature column
		for (j=0; j<m_k; j++)
		{
			for (k=0; k<dim; k++)
				z_matrix[j*dim+k] -= feature_matrix.matrix[i*dim+k];
		}

		// compute local covariance matrix
		cblas_dgemm(CblasColMajor,CblasTrans,CblasNoTrans,
		            m_k,m_k,dim,
		            1.0,z_matrix,dim,
		            z_matrix,dim,
		            0.0,covariance_matrix,m_k);

		for (j=0; j<m_k; j++)
			id_vector[j] = 1.0;

		// regularize in case of ill-posed system
		if (m_k>dim)
		{
			// compute tr(C)
			float64_t trace = 0.0;
			for (j=0; j<m_k; j++)
				trace += covariance_matrix[j*m_k+j];

			for (j=0; j<m_k; j++)
				covariance_matrix[j*m_k+j] += 1e-3*trace;
		}

		// solve system of linear equations: covariance_matrix * X = 1
		// covariance_matrix is a pos-def matrix
		clapack_dposv(CblasColMajor,CblasLower,m_k,1,covariance_matrix,m_k,id_vector,m_k);

		// normalize weights
		norming=0.0;
		for (j=0; j<m_k; j++)
			norming += id_vector[j];

		for (j=0; j<m_k; j++)
			id_vector[j]/=norming;

		// put weights into W matrix
		for (j=0; j<m_k; j++)
			W_matrix[N*neighborhood_matrix.matrix[j*N+i]+i]=id_vector[j];

	}

	// clean
	SG_FREE(id_vector);
	neighborhood_matrix.destroy_matrix();
	SG_FREE(z_matrix);
	SG_FREE(covariance_matrix);

	// W=I-W
	for (i=0; i<N; i++)
	{
		for (j=0; j<N; j++)
			W_matrix[j*N+i] = (i==j) ? 1.0-W_matrix[j*N+i] : -W_matrix[j*N+i];
	}

	// compute M=(W-I)'*(W-I)
	SGMatrix<float64_t> M_matrix(N,N);
	cblas_dgemm(CblasColMajor,CblasTrans, CblasNoTrans,
	            N,N,N,
	            1.0,W_matrix,N,
	            W_matrix,N,
	            0.0,M_matrix.matrix,N);

	SG_FREE(W_matrix);

	simple_features->set_feature_matrix(find_null_space(M_matrix,m_target_dim,false));
	M_matrix.destroy_matrix();

	return simple_features->get_feature_matrix();
}

SGVector<float64_t> CLocallyLinearEmbedding::apply_to_feature_vector(SGVector<float64_t> vector)
{
	SG_NOTIMPLEMENTED;
	return vector;
}

SGMatrix<float64_t> CLocallyLinearEmbedding::find_null_space(SGMatrix<float64_t> matrix, int dimension, bool force_lapack)
{
	int i,j;
	ASSERT(matrix.num_cols==matrix.num_rows);
	int N = matrix.num_cols;
	// get eigenvectors with ARPACK or LAPACK
	int eigenproblem_status = 0;

	bool arpack = false;

#ifdef HAVE_ARPACK
	arpack = true;
#endif

	if (force_lapack) arpack = false;

	float64_t* eigenvalues_vector;
	float64_t* eigenvectors;
	if (arpack)
	{
		// using ARPACK (faster)
		eigenvalues_vector = SG_MALLOC(float64_t, dimension+1);
		#ifdef HAVE_ARPACK
		arpack_dsaupd(matrix.matrix,NULL,N,dimension+1,"LA",3,m_posdef,-1e-6,eigenvalues_vector,matrix.matrix,eigenproblem_status);
		#endif
	}
	else
	{
		// using LAPACK (slower)
		eigenvalues_vector = SG_MALLOC(float64_t, N);
		eigenvectors = SG_MALLOC(float64_t,(dimension+1)*N);
		wrap_dsyevr('V','U',N,matrix.matrix,N,2,dimension+2,eigenvalues_vector,eigenvectors,&eigenproblem_status);
	}

	// check if failed
	if (eigenproblem_status)
		SG_ERROR("Eigenproblem failed with code: %d", eigenproblem_status);

	// allocate null space feature matrix
	float64_t* null_space_features = SG_MALLOC(float64_t, N*dimension);

	// construct embedding w.r.t to used solver (prefer ARPACK if available)
	if (arpack)
	{
		// ARPACKed eigenvectors
		for (i=0; i<dimension; i++)
		{
			for (j=0; j<N; j++)
				null_space_features[j*dimension+i] = matrix.matrix[j*(dimension+1)+i+1];
		}
	}
	else
	{
		// LAPACKed eigenvectors
		for (i=0; i<dimension; i++)
		{
			for (j=0; j<N; j++)
				null_space_features[j*dimension+i] = eigenvectors[i*N+j];
		}
		SG_FREE(eigenvectors);
	}
	SG_FREE(eigenvalues_vector);

	return SGMatrix<float64_t>(null_space_features,dimension,N);
}

SGMatrix<int32_t> CLocallyLinearEmbedding::get_neighborhood_matrix(CDistance* distance)
{
	int32_t i,j;
	SGMatrix<float64_t> distance_matrix = distance->get_distance_matrix();
	int32_t N = distance->get_num_vec_lhs();
	// init matrix and heap to be used
	int32_t* neighborhood_matrix = SG_MALLOC(int32_t, N*m_k);
	float64_t tmp;
	CFibonacciHeap* heap = new CFibonacciHeap(N);

	// construct neighborhood matrix (contains idxs of neighbors for
	// i-th object in i-th column)
	for (i=0; i<N; i++)
	{
		for (j=0; j<N; j++)
		{
			heap->insert(j,distance_matrix.matrix[i*N+j]);
		}

		heap->extract_min(tmp);

		for (j=0; j<m_k; j++)
			neighborhood_matrix[j*N+i] = heap->extract_min(tmp);

		heap->clear();
	}

	// cleanup
	delete heap;
	distance_matrix.destroy_matrix();

	return SGMatrix<int32_t>(neighborhood_matrix,m_k,N);
}

#endif /* HAVE_LAPACK */
<|endoftext|>