<commit_before>
// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "openMVG/sfm/sfm_data.hpp"
#include "openMVG/sfm/sfm_data_io.hpp"
#include "openMVG/image/image_io.hpp"
#include "openMVG/stl/stl.hpp"

#include "third_party/progress/progress.hpp"

namespace openMVG {
namespace sfm {

using namespace openMVG::geometry;
using namespace openMVG::cameras;
using namespace openMVG::image;

/// Find the color of the SfM_Data Landmarks/structure
bool ColorizeTracks( SfM_Data & sfm_data )
{
  // Colorize each track
  //  Start with the most representative image
  //    and iterate to provide a color to each 3D point

  std::vector<Vec3> vec_3dPoints;
  std::vector<Vec3> vec_tracksColor;

  C_Progress_display my_progress_bar(sfm_data.GetLandmarks().size(),
                                     std::cout,
                                     "\nCompute scene structure color\n");

  vec_3dPoints.resize(sfm_data.GetLandmarks().size());

  //Build a list of contiguous index for the trackIds
  std::map<IndexT, IndexT> trackIds_to_contiguousIndexes;
  IndexT cpt = 0;
  for (Landmarks::const_iterator it = sfm_data.GetLandmarks().begin();
    it != sfm_data.GetLandmarks().end(); ++it, ++cpt)
  {
    trackIds_to_contiguousIndexes[it->first] = cpt;
    vec_3dPoints[cpt] = it->second.X;
  }

  // The track list that will be colored (point removed during the process)
  std::set<IndexT> remainingTrackToColor;
  std::transform(sfm_data.GetLandmarks().begin(), sfm_data.GetLandmarks().end(),
    std::inserter(remainingTrackToColor, remainingTrackToColor.begin()),
    stl::RetrieveKey());

  while( !remainingTrackToColor.empty() )
  {
    // Find the most representative image (for the remaining 3D points)
    //  a. Count the number of observation per view for each 3Dpoint Index
    //  b. Sort to find the most representative view index

    std::map<IndexT, IndexT> map_IndexCardinal; // ViewId, Cardinal
    for (std::set<IndexT>::const_iterator
      iterT = remainingTrackToColor.begin();
      iterT != remainingTrackToColor.end();
      ++iterT)
    {
      const size_t trackId = *iterT;
      const Observations & obs = sfm_data.GetLandmarks().at(trackId).obs;
      for( Observations::const_iterator iterObs = obs.begin();
        iterObs != obs.end(); ++iterObs)
      {
        const size_t viewId = iterObs->first;
        if (map_IndexCardinal.find(viewId) == map_IndexCardinal.end())
          map_IndexCardinal[viewId] = 1;
        else
          ++map_IndexCardinal[viewId];
      }
    }

    // Find the View index that is the most represented
    std::vector<IndexT> vec_cardinal;
    std::transform(map_IndexCardinal.begin(),
      map_IndexCardinal.end(),
      std::back_inserter(vec_cardinal),
      stl::RetrieveValue());
    using namespace stl::indexed_sort;
    std::vector< sort_index_packet_descend< IndexT, IndexT> > packet_vec(vec_cardinal.size());
    sort_index_helper(packet_vec, &vec_cardinal[0], 1);

    // First image index with the most of occurrence
    std::map<IndexT, IndexT>::const_iterator iterTT = map_IndexCardinal.begin();
    std::advance(iterTT, packet_vec[0].index);
    const size_t view_index = iterTT->first;
    const View * view = sfm_data.GetViews().at(view_index).get();
    const std::string sView_filename = stlplus::create_filespec(sfm_data.s_root_path,
      view->s_Img_path);
    Image<RGBColor> image;
    if(!ReadImage(sView_filename.c_str(), &image))
    {
      std::cerr << "Unable to read image: " << sView_filename << std::endl;
      return false;
    }

    // Iterate through the remaining track to color
    // - look if the current view is present to color the track
    std::set<IndexT> set_toRemove;
    for (std::set<IndexT>::const_iterator
      iterT = remainingTrackToColor.begin();
      iterT != remainingTrackToColor.end();
      ++iterT)
    {
      const size_t trackId = *iterT;
      const Observations & obs = sfm_data.GetLandmarks().at(trackId).obs;
      Observations::const_iterator it = obs.find(view_index);

      if (it != obs.end())
      {
        // Color the track
        const Vec2 & pt = it->second.x;
        sfm_data.structure.at(trackId).rgb = image(pt.y(), pt.x());
        set_toRemove.insert(trackId);
        ++my_progress_bar;
      }
    }
    // Remove colored track
    for (std::set<IndexT>::const_iterator iter = set_toRemove.begin();
      iter != set_toRemove.end(); ++iter)
    {
      remainingTrackToColor.erase(*iter);
    }
  }
  return true;
}

} // namespace sfm
} // namespace openMVG
<commit_msg>[sfm] colorize tracks: clamp pixel coordinates because feature/marker centers could be outside the image<commit_after>
// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "openMVG/sfm/sfm_data.hpp"
#include "openMVG/sfm/sfm_data_io.hpp"
#include "openMVG/image/image_io.hpp"
#include "openMVG/stl/stl.hpp"

#include "third_party/progress/progress.hpp"

namespace openMVG {
namespace sfm {

using namespace openMVG::geometry;
using namespace openMVG::cameras;
using namespace openMVG::image;

/// Find the color of the SfM_Data Landmarks/structure
bool ColorizeTracks( SfM_Data & sfm_data )
{
  // Colorize each track
  //  Start with the most representative image
  //    and iterate to provide a color to each 3D point

  std::vector<Vec3> vec_3dPoints;
  std::vector<Vec3> vec_tracksColor;

  C_Progress_display my_progress_bar(sfm_data.GetLandmarks().size(),
                                     std::cout,
                                     "\nCompute scene structure color\n");

  vec_3dPoints.resize(sfm_data.GetLandmarks().size());

  //Build a list of contiguous index for the trackIds
  std::map<IndexT, IndexT> trackIds_to_contiguousIndexes;
  IndexT cpt = 0;
  for (Landmarks::const_iterator it = sfm_data.GetLandmarks().begin();
    it != sfm_data.GetLandmarks().end(); ++it, ++cpt)
  {
    trackIds_to_contiguousIndexes[it->first] = cpt;
    vec_3dPoints[cpt] = it->second.X;
  }

  // The track list that will be colored (point removed during the process)
  std::set<IndexT> remainingTrackToColor;
  std::transform(sfm_data.GetLandmarks().begin(), sfm_data.GetLandmarks().end(),
    std::inserter(remainingTrackToColor, remainingTrackToColor.begin()),
    stl::RetrieveKey());

  while( !remainingTrackToColor.empty() )
  {
    // Find the most representative image (for the remaining 3D points)
    //  a. Count the number of observation per view for each 3Dpoint Index
    //  b. Sort to find the most representative view index

    std::map<IndexT, IndexT> map_IndexCardinal; // ViewId, Cardinal
    for (std::set<IndexT>::const_iterator
      iterT = remainingTrackToColor.begin();
      iterT != remainingTrackToColor.end();
      ++iterT)
    {
      const size_t trackId = *iterT;
      const Observations & obs = sfm_data.GetLandmarks().at(trackId).obs;
      for( Observations::const_iterator iterObs = obs.begin();
        iterObs != obs.end(); ++iterObs)
      {
        const size_t viewId = iterObs->first;
        if (map_IndexCardinal.find(viewId) == map_IndexCardinal.end())
          map_IndexCardinal[viewId] = 1;
        else
          ++map_IndexCardinal[viewId];
      }
    }

    // Find the View index that is the most represented
    std::vector<IndexT> vec_cardinal;
    std::transform(map_IndexCardinal.begin(),
      map_IndexCardinal.end(),
      std::back_inserter(vec_cardinal),
      stl::RetrieveValue());
    using namespace stl::indexed_sort;
    std::vector< sort_index_packet_descend< IndexT, IndexT> > packet_vec(vec_cardinal.size());
    sort_index_helper(packet_vec, &vec_cardinal[0], 1);

    // First image index with the most of occurrence
    std::map<IndexT, IndexT>::const_iterator iterTT = map_IndexCardinal.begin();
    std::advance(iterTT, packet_vec[0].index);
    const size_t view_index = iterTT->first;
    const View * view = sfm_data.GetViews().at(view_index).get();
    const std::string sView_filename = stlplus::create_filespec(sfm_data.s_root_path,
      view->s_Img_path);
    Image<RGBColor> image;
    if(!ReadImage(sView_filename.c_str(), &image))
    {
      std::cerr << "Unable to read image: " << sView_filename << std::endl;
      return false;
    }

    // Iterate through the remaining track to color
    // - look if the current view is present to color the track
    std::set<IndexT> set_toRemove;
    for (std::set<IndexT>::const_iterator
      iterT = remainingTrackToColor.begin();
      iterT != remainingTrackToColor.end();
      ++iterT)
    {
      const size_t trackId = *iterT;
      const Observations & obs = sfm_data.GetLandmarks().at(trackId).obs;
      Observations::const_iterator it = obs.find(view_index);

      if (it != obs.end())
      {
        // Color the track
        Vec2 pt = it->second.x;
        // Clamp the pixel position if the feature/marker center is outside the image.
        pt.x() = clamp(pt.x(), 0.0, double(image.Width()-1));
        pt.y() = clamp(pt.y(), 0.0, double(image.Height()-1));
        sfm_data.structure.at(trackId).rgb = image(pt.y(), pt.x());
        set_toRemove.insert(trackId);
        ++my_progress_bar;
      }
    }
    // Remove colored track
    for (std::set<IndexT>::const_iterator iter = set_toRemove.begin();
      iter != set_toRemove.end(); ++iter)
    {
      remainingTrackToColor.erase(*iter);
    }
  }
  return true;
}

} // namespace sfm
} // namespace openMVG
<|endoftext|>


<commit_before>#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QFile>
#include <QMenu>
#include <QTreeWidget>

#include "about.h"
#include "settings.h"
#include "ipobjects.h"
#include "messenger.h"
#include "messagedialog.h"
#include "qommunicate.h"

Qommunicate::Qommunicate(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    createTrayIcon();

    MemberUtils::init();
    populateTree();
    firstRun();
    messenger()->login();

    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));

    connect(messenger(), SIGNAL(msg_ansEntry(Message)), this, SLOT(addMember(Message)));
    connect(messenger(), SIGNAL(msg_entry(Message)), this, SLOT(addMemberAndAnswer(Message)));
    connect(messenger(), SIGNAL(msg_exit(Message)), this, SLOT(removeMember(Message)));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(openDialog(Message)));
    connect(messenger(), SIGNAL(msg_getAbsenceInfo(Message)), this, SLOT(sendAbsenceInfo(Message)));
}

void Qommunicate::on_searchEdit_textChanged(const QString &text)
{
    filterModel->setFilterFixedString(text);
    ui.memberTree->expandAll();
}

void Qommunicate::on_action_About_triggered()
{
    AboutDialog(this).exec();
}

void Qommunicate::on_action_Settings_triggered()
{
    SettingsDialog(this).exec();
}

void Qommunicate::on_actionMulticast_triggered()
{
    MessageDialog dlg(this);
    dlg.exec();
}

void Qommunicate::on_actionQuit_triggered()
{
    qApp->quit();
}

void Qommunicate::closeEvent(QCloseEvent * event)
{
    setVisible(false);
    event->ignore();
}

void Qommunicate::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if( reason == QSystemTrayIcon::Trigger )
        setVisible(!isVisible());
}

void Qommunicate::createTrayIcon()
{
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(windowIcon());

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    QMenu *menu = new QMenu;
    menu->addAction(ui.actionMulticast);
    menu->addAction(ui.actionQuit);
    trayIcon->setContextMenu(menu);

    trayIcon->show();
}

void Qommunicate::populateTree()
{
    model = new MemberModel(this);
    filterModel = new MemberFilter(this);

    filterModel->setSourceModel(model);
    filterModel->setDynamicSortFilter(true);

    ui.memberTree->setSelectionMode(ui.memberTree->ExtendedSelection);
    ui.memberTree->setModel(filterModel);
    ui.memberTree->setHeaderHidden(true);
    ui.memberTree->setAcceptDrops(true);
    ui.memberTree->setExpandsOnDoubleClick(false);
    ui.memberTree->expandAll();
}

/*
If item is a group, adds all submembers to receivers and returns true.
otherwise assumes item is a member, inserts in receivers and returns false
*/
bool Qommunicate::createGroupMemberList(QStandardItem* item, QSet<Member*>& receivers)
{
    if(item->type() == TYPE_GROUP)
    {
        if(!item->hasChildren())
            return true;

        for(int i = 0; i < item->rowCount(); i++)
        {
            receivers << (Member*)item->child(i, 0);
        }
        return true;
    }
    receivers << (Member*)item;
    return false;
}

void Qommunicate::on_memberTree_doubleClicked(const QModelIndex& proxyIndex)
{

    MessageDialog* dlg;
    QSet<Member*> receivers;

    MemberModel* model = (MemberModel*) ( (MemberFilter*) ui.memberTree->model() )->sourceModel();
    QModelIndex index = ((MemberFilter*)ui.memberTree->model())->mapToSource(proxyIndex);

    if(index.isValid())
    {
        // only single item clicked
        createGroupMemberList(model->itemFromIndex(index), receivers);
    }
    else
    {
        QModelIndex i;
        foreach(i, ui.memberTree->selectionModel()->selectedRows())
        {
            QStandardItem* item = model->itemFromIndex(((MemberFilter*)ui.memberTree->model())->mapToSource(i));
            createGroupMemberList(item, receivers);
        }
    }

    if(receivers.isEmpty())
        return;

    QList<Member*> toDialog = receivers.toList();
    if(toDialog.size() == 1 && MemberUtils::contains("open_conversations", toDialog[0]))
        return;

    if(toDialog.size() == 1)
    {
        if(!MemberUtils::contains("open_conversations", toDialog[0]))
            dlg = new MessageDialog( toDialog[0], this );
    }
    else
        dlg = new MessageDialog( toDialog, this );

    dlg->setModal(false);
    dlg->show();
}

void Qommunicate::on_statusCombo_currentIndexChanged(const QString& text)
{
    messenger()->multicast(QOM_BR_ABSENCE, me().name().toAscii()+'\0'+myGroup().name().toAscii());
}

void Qommunicate::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return) {
        event->accept();
        on_memberTree_doubleClicked(QModelIndex());
        return;
    }
    event->ignore();
}

void Qommunicate::firstRun()
{
    QSettings s;
    if( ! s.contains(tr("nick")) )
        ui.action_Settings->trigger();
}

void Qommunicate::dialogOpened(Member* m)
{
    MemberUtils::insert("open_conversations", m);
}

void Qommunicate::dialogClosed(Member *m)
{
    MemberUtils::remove("open_conversations", m);
}

void Qommunicate::cleanup()
{
    messenger()->logout();
    delete messenger();
}

// Message handling slots
void Qommunicate::addMember(Message msg)
{
    if(MemberUtils::contains("members_list", msg.sender()))
        return;

    QList<QByteArray> tokens = msg.payload().split('\a');
    msg.sender()->setName(tokens[0]);

    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    if(groupName.isEmpty())
    {
        model->appendRow(msg.sender());
    }
    else
    {
        QList<QStandardItem*> matches = model->findItems(groupName);
        if(!matches.isEmpty() && matches[0]->type() == TYPE_GROUP)
        {
            matches[0]->appendRow(msg.sender());
        }
        else
        {
            Group * group = new Group(groupName);
            group->appendRow(msg.sender());
            model->appendRow(group);
        }
    }

    MemberUtils::insert("members_list", msg.sender());

}

void Qommunicate::addMemberAndAnswer(Message msg)
{
    addMember(msg);
    messenger()->sendMessage(QOM_ANSENTRY, (me().name()+'\0'+myGroup().name()).toAscii(), msg.sender());
}

void Qommunicate::removeMember(Message msg)
{
    QList<QByteArray> tokens = msg.payload().split('\a');
    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    for(int i = 0; i < model->rowCount(); i++)
    {
        QStandardItem* it = model->item(i, 0);
        if(it->type() == TYPE_MEMBER && ((Member*)it)->name() == msg.sender()->addressString())
        {
            model->removeRow(it->row());
        }
        else
        {
            for(int j = 0; j < it->rowCount(); j++)
            {
                if(((Member*)it->child(j))->addressString() == msg.sender()->addressString())
                    it->removeRow(j);
            }
            if(it->rowCount() == 0)
                model->removeRow(it->row());
        }
    }
    MemberUtils::remove("members_list", msg.sender()->addressString());
}

void Qommunicate::openDialog(Message msg)
{
    if(MemberUtils::contains("open_conversations", msg.sender()))
        return;

    Member* with = MemberUtils::get("members_list", msg.sender());
    if(!with->isValid())
        with = msg.sender();
    MessageDialog *dlg = new MessageDialog(with, this);
    dlg->setModal(false);
    dlg->show();
    dlg->incomingMessage(msg);
}

void Qommunicate::sendAbsenceInfo(Message msg)
{
    QString payload = ui.statusCombo->currentText();
    if(payload == tr("Available"))
        payload = "Not absence mode";
    messenger()->multicast(QOM_SENDABSENCEINFO, payload.toAscii());
}
        <commit_msg>Added ignore feature<commit_after>#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QFile>
#include <QMenu>
#include <QTreeWidget>

#include "about.h"
#include "settings.h"
#include "ipobjects.h"
#include "messenger.h"
#include "messagedialog.h"
#include "qommunicate.h"

Qommunicate::Qommunicate(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    createTrayIcon();

    MemberUtils::init();
    populateTree();
    firstRun();
    messenger()->login();

    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));

    connect(messenger(), SIGNAL(msg_ansEntry(Message)), this, SLOT(addMember(Message)));
    connect(messenger(), SIGNAL(msg_entry(Message)), this, SLOT(addMemberAndAnswer(Message)));
    connect(messenger(), SIGNAL(msg_exit(Message)), this, SLOT(removeMember(Message)));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(openDialog(Message)));
    connect(messenger(), SIGNAL(msg_getAbsenceInfo(Message)), this, SLOT(sendAbsenceInfo(Message)));
}

void Qommunicate::on_searchEdit_textChanged(const QString &text)
{
    filterModel->setFilterFixedString(text);
    ui.memberTree->expandAll();
}

void Qommunicate::on_action_About_triggered()
{
    AboutDialog(this).exec();
}

void Qommunicate::on_action_Settings_triggered()
{
    SettingsDialog(this).exec();
}

void Qommunicate::on_actionMulticast_triggered()
{
    MessageDialog dlg(this);
    dlg.exec();
}

void Qommunicate::on_actionQuit_triggered()
{
    qApp->quit();
}

void Qommunicate::closeEvent(QCloseEvent * event)
{
    setVisible(false);
    event->ignore();
}

void Qommunicate::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if( reason == QSystemTrayIcon::Trigger )
        setVisible(!isVisible());
}

void Qommunicate::createTrayIcon()
{
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(windowIcon());

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    QMenu *menu = new QMenu;
    menu->addAction(ui.actionMulticast);
    menu->addAction(ui.actionQuit);
    trayIcon->setContextMenu(menu);

    trayIcon->show();
}

void Qommunicate::populateTree()
{
    model = new MemberModel(this);
    filterModel = new MemberFilter(this);

    filterModel->setSourceModel(model);
    filterModel->setDynamicSortFilter(true);

    ui.memberTree->setSelectionMode(ui.memberTree->ExtendedSelection);
    ui.memberTree->setModel(filterModel);
    ui.memberTree->setHeaderHidden(true);
    ui.memberTree->setAcceptDrops(true);
    ui.memberTree->setExpandsOnDoubleClick(false);
    ui.memberTree->expandAll();
}

/*
If item is a group, adds all submembers to receivers and returns true.
otherwise assumes item is a member, inserts in receivers and returns false
*/
bool Qommunicate::createGroupMemberList(QStandardItem* item, QSet<Member*>& receivers)
{
    if(item->type() == TYPE_GROUP)
    {
        if(!item->hasChildren())
            return true;

        for(int i = 0; i < item->rowCount(); i++)
        {
            receivers << (Member*)item->child(i, 0);
        }
        return true;
    }
    receivers << (Member*)item;
    return false;
}

void Qommunicate::on_memberTree_doubleClicked(const QModelIndex& proxyIndex)
{

    MessageDialog* dlg;
    QSet<Member*> receivers;

    MemberModel* model = (MemberModel*) ( (MemberFilter*) ui.memberTree->model() )->sourceModel();
    QModelIndex index = ((MemberFilter*)ui.memberTree->model())->mapToSource(proxyIndex);

    if(index.isValid())
    {
        // only single item clicked
        createGroupMemberList(model->itemFromIndex(index), receivers);
    }
    else
    {
        QModelIndex i;
        foreach(i, ui.memberTree->selectionModel()->selectedRows())
        {
            QStandardItem* item = model->itemFromIndex(((MemberFilter*)ui.memberTree->model())->mapToSource(i));
            createGroupMemberList(item, receivers);
        }
    }

    if(receivers.isEmpty())
        return;

    QList<Member*> toDialog = receivers.toList();
    if(toDialog.size() == 1 && MemberUtils::contains("open_conversations", toDialog[0]))
        return;

    if(toDialog.size() == 1)
    {
        if(!MemberUtils::contains("open_conversations", toDialog[0]))
            dlg = new MessageDialog( toDialog[0], this );
    }
    else
        dlg = new MessageDialog( toDialog, this );

    dlg->setModal(false);
    dlg->show();
}

void Qommunicate::on_statusCombo_currentIndexChanged(const QString& text)
{
    messenger()->multicast(QOM_BR_ABSENCE, me().name().toAscii()+'\0'+myGroup().name().toAscii());
}

void Qommunicate::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return) {
        event->accept();
        on_memberTree_doubleClicked(QModelIndex());
        return;
    }
    event->ignore();
}

void Qommunicate::firstRun()
{
    QSettings s;
    if( ! s.contains(tr("nick")) )
        ui.action_Settings->trigger();
}

void Qommunicate::dialogOpened(Member* m)
{
    MemberUtils::insert("open_conversations", m);
}

void Qommunicate::dialogClosed(Member *m)
{
    MemberUtils::remove("open_conversations", m);
}

void Qommunicate::cleanup()
{
    messenger()->logout();
    delete messenger();
}

// Message handling slots
void Qommunicate::addMember(Message msg)
{
    if(MemberUtils::contains("members_list", msg.sender()))
        return;

    QList<QByteArray> tokens = msg.payload().split('\a');
    msg.sender()->setName(tokens[0]);

    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    if(groupName.isEmpty())
    {
        model->appendRow(msg.sender());
    }
    else
    {
        QList<QStandardItem*> matches = model->findItems(groupName);
        if(!matches.isEmpty() && matches[0]->type() == TYPE_GROUP)
        {
            matches[0]->appendRow(msg.sender());
        }
        else
        {
            Group * group = new Group(groupName);
            group->appendRow(msg.sender());
            model->appendRow(group);
        }
    }

    MemberUtils::insert("members_list", msg.sender());

}

void Qommunicate::addMemberAndAnswer(Message msg)
{
    addMember(msg);
    messenger()->sendMessage(QOM_ANSENTRY, (me().name()+'\0'+myGroup().name()).toAscii(), msg.sender());
}

void Qommunicate::removeMember(Message msg)
{
    QList<QByteArray> tokens = msg.payload().split('\a');
    QString groupName;
    if(tokens.size() > 1)
        groupName = tokens[1];

    for(int i = 0; i < model->rowCount(); i++)
    {
        QStandardItem* it = model->item(i, 0);
        if(it->type() == TYPE_MEMBER && ((Member*)it)->name() == msg.sender()->addressString())
        {
            model->removeRow(it->row());
        }
        else
        {
            for(int j = 0; j < it->rowCount(); j++)
            {
                if(((Member*)it->child(j))->addressString() == msg.sender()->addressString())
                    it->removeRow(j);
            }
            if(it->rowCount() == 0)
                model->removeRow(it->row());
        }
    }
    MemberUtils::remove("members_list", msg.sender()->addressString());
}

void Qommunicate::openDialog(Message msg)
{
    if(MemberUtils::contains("open_conversations", msg.sender()))
        return;

    // if set to ignore received messages
    QSettings s;
    if(s.value(tr("no_receive")).toBool())
    {
        qDebug() << "Ignoring message";
        return;
    }

    Member* with = MemberUtils::get("members_list", msg.sender());
    if(!with->isValid())
        with = msg.sender();
    MessageDialog *dlg = new MessageDialog(with, this);
    dlg->setModal(false);
    dlg->show();
    dlg->incomingMessage(msg);
}

void Qommunicate::sendAbsenceInfo(Message msg)
{
    QString payload = ui.statusCombo->currentText();
    if(payload == tr("Available"))
        payload = "Not absence mode";
    messenger()->multicast(QOM_SENDABSENCEINFO, payload.toAscii());
}
        <|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osgUtil/RenderBin>
#include <osgUtil/RenderStage>

#include <osg/Statistics>
#include <osg/ImpostorSprite>

#include <algorithm>

using namespace osg;
using namespace osgUtil;

class RenderBinPrototypeList : public osg::Referenced, public std::map< std::string, osg::ref_ptr<RenderBin> >
{
    public:
	RenderBinPrototypeList() {}
	~RenderBinPrototypeList() {}
};

// register a RenderStage prototype with the RenderBin prototype list.
RegisterRenderBinProxy s_registerRenderBinProxy("RenderBin",new RenderBin(RenderBin::SORT_BY_STATE));
RegisterRenderBinProxy s_registerDepthSortedBinProxy("DepthSortedBin",new RenderBin(RenderBin::SORT_BACK_TO_FRONT));

RenderBinPrototypeList* renderBinPrototypeList()
{
    static osg::ref_ptr<RenderBinPrototypeList> s_renderBinPrototypeList = new  RenderBinPrototypeList;
    return s_renderBinPrototypeList.get();
}

RenderBin* RenderBin::getRenderBinPrototype(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBinPrototypeList::iterator itr = list->find(binName);
        if (itr != list->end()) return itr->second.get();
    }
    return NULL;
}

RenderBin* RenderBin::createRenderBin(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBin* prototype = getRenderBinPrototype(binName);
        if (prototype) return dynamic_cast<RenderBin*>(prototype->clone(osg::CopyOp::DEEP_COPY_ALL));
    }
    return NULL;
}

void RenderBin::addRenderBinPrototype(const std::string& binName,RenderBin* proto)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        (*list)[binName] = proto;
    }
}

void RenderBin::removeRenderBinPrototype(RenderBin* proto)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        RenderBinPrototypeList::iterator itr = list->find(proto->className());
        if (itr != list->end()) list->erase(itr);
    }
}

RenderBin::RenderBin(SortMode mode)
{
    _binNum = 0;
    _parent = NULL;
    _stage = NULL;
    _sortMode = mode;
}

RenderBin::RenderBin(const RenderBin& rhs,const CopyOp& copyop):
        Object(rhs,copyop),
        _binNum(rhs._binNum),
        _parent(rhs._parent),
        _stage(rhs._stage),
        _bins(rhs._bins),
        _renderGraphList(rhs._renderGraphList),
        _renderLeafList(rhs._renderLeafList),
        _sortMode(rhs._sortMode),
        _sortCallback(rhs._sortCallback),
        _drawCallback(rhs._drawCallback)
{

}

RenderBin::~RenderBin()
{
}

void RenderBin::reset()
{
    _renderGraphList.clear();
    _bins.clear();
}

void RenderBin::sort()
{
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        itr->second->sort();
    }

    if (_sortCallback.valid())
    {
        _sortCallback->sortImplementation(this);
    }
    else sortImplementation();
}

void RenderBin::setSortMode(SortMode mode)
{
    _sortMode = mode;
}

void RenderBin::sortImplementation()
{
    switch(_sortMode)
    {
        case(SORT_BY_STATE):
            sortByState();
            break;
        case(SORT_FRONT_TO_BACK):
            sortFrontToBack();
            break;
        case(SORT_BACK_TO_FRONT):
            sortBackToFront();
            break;
        default:
            break;
    }
}

struct SortByStateFunctor
{
    bool operator() (const RenderGraph* lhs,const RenderGraph* rhs) const
    {
        return (*(lhs->_stateset)<*(rhs->_stateset));
    }
};

void RenderBin::sortByState()
{
    // actually we'll do nothing right now, as fine grained sorting by state
    // appears to cost more to do than it saves in draw.  The contents of
    // the RenderGraph leaves is already coasrse grained sorted, this
    // sorting is as a function of the cull traversal.
    // cout << "doing sortByState "<<this<<endl;
}

struct FrontToBackSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (lhs->_depth<rhs->_depth);
    }
};

void RenderBin::sortFrontToBack()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),FrontToBackSortFunctor());

//    cout << "sort front to back"<<endl;
}

struct BackToFrontSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (rhs->_depth<lhs->_depth);
    }
};

void RenderBin::sortBackToFront()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),BackToFrontSortFunctor());

//    cout << "sort back to front"<<endl;
}

void RenderBin::copyLeavesFromRenderGraphListToRenderLeafList()
{
    _renderLeafList.clear();

    int totalsize=0;
    RenderGraphList::iterator itr;
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        totalsize += (*itr)->_leaves.size();
    }

    _renderLeafList.reserve(totalsize);

    // first copy all the leaves from the render graphs into the leaf list.
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        for(RenderGraph::LeafList::iterator dw_itr = (*itr)->_leaves.begin();
            dw_itr != (*itr)->_leaves.end();
            ++dw_itr)
        {
            _renderLeafList.push_back(dw_itr->get());
        }
    }

    // empty the render graph list to prevent it being drawn along side the render leaf list (see drawImplementation.)
    _renderGraphList.clear();
}

RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName)
{
    // search for appropriate bin.
    RenderBinList::iterator itr = _bins.find(binNum);
    if (itr!=_bins.end()) return itr->second.get();

    // create a renderin bin and insert into bin list.
    RenderBin* rb = RenderBin::createRenderBin(binName);
    if (rb)
    {

        RenderStage* rs = dynamic_cast<RenderStage*>(rb);
        if (rs)
        {
            rs->_binNum = binNum;
            rs->_parent = NULL;
            rs->_stage = rs;
            _stage->addToDependencyList(rs);
        }
        else
        {
            rb->_binNum = binNum;
            rb->_parent = this;
            rb->_stage = _stage;
            _bins[binNum] = rb;
        }
    }
    return rb;
}

void RenderBin::draw(osg::State& state,RenderLeaf*& previous)
{
    if (_drawCallback.valid())
    {
        _drawCallback->drawImplementation(this,state,previous);
    }
    else drawImplementation(state,previous);
}

void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous)
{
    // draw first set of draw bins.
    RenderBinList::iterator rbitr;
    for(rbitr = _bins.begin();
        rbitr!=_bins.end() && rbitr->first<0;
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

    // draw fine grained ordering.
    for(RenderLeafList::iterator rlitr= _renderLeafList.begin();
        rlitr!= _renderLeafList.end();
        ++rlitr)
    {
        RenderLeaf* rl = *rlitr;
        rl->render(state,previous);
        previous = rl;
    }

    // draw coarse grained ordering.
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            rl->render(state,previous);
            previous = rl;

        }
    }

    // draw post bins.
    for(;
        rbitr!=_bins.end();
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

}

// stats
bool RenderBin::getStats(osg::Statistics* primStats)
{ // different by return type - collects the stats in this renderrBin
    bool somestats=false;
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            Drawable* dw= rl->_drawable;
            primStats->addDrawable(); // number of geosets
            if (rl->_modelview.get()) primStats->addMatrix(); // number of matrices
            if (dw)
            {
                // then tot up the primtive types and no vertices.
                dw->accept(*primStats); // use sub-class to find the stats for each drawable
                if (typeid(*dw)==typeid(osg::ImpostorSprite)) primStats->addImpostor(1);
            }
        }
        somestats=true;
    }
    return somestats;
}

void RenderBin::getPrims(osg::Statistics* primStats)
{
    static int ndepth;
    ndepth++;
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        primStats->addBins(1);
        itr->second->getPrims(primStats);
    }
    getStats(primStats);
    ndepth--;

}

bool RenderBin::getPrims(osg::Statistics* primStats, int nbin)
{ // collect stats for array of bins, maximum nbin
    // (which will be modified on next call if array of primStats is too small);
    // return 1 for OK;
    static int ndepth;
    bool ok=false;
    ndepth++;
    int nb=primStats[0].getBins();
    if (nb<nbin)
    { // if statement to protect against writing to bins beyond the maximum seen before
        primStats[nb].setBinNo(nb);
        primStats[nb].setDepth(ndepth);
        getStats(primStats+nb);
    }
    primStats[0].addBins(1);
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        if (itr->second->getPrims(primStats, nbin)) ok = true;
    }
    ok=true;
    ndepth--;
    return ok;
}
<commit_msg>Added fallback in RenderBin::createRenderBin(const std::string& binName) which return a new RenderBin when the no prototype is found with className of binName.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osgUtil/RenderBin>
#include <osgUtil/RenderStage>

#include <osg/Statistics>
#include <osg/ImpostorSprite>
#include <osg/Notify>

#include <algorithm>

using namespace osg;
using namespace osgUtil;

class RenderBinPrototypeList : public osg::Referenced, public std::map< std::string, osg::ref_ptr<RenderBin> >
{
    public:
	RenderBinPrototypeList() {}
	~RenderBinPrototypeList() {}
};

// register a RenderStage prototype with the RenderBin prototype list.
RegisterRenderBinProxy s_registerRenderBinProxy("RenderBin",new RenderBin(RenderBin::SORT_BY_STATE));
RegisterRenderBinProxy s_registerDepthSortedBinProxy("DepthSortedBin",new RenderBin(RenderBin::SORT_BACK_TO_FRONT));

RenderBinPrototypeList* renderBinPrototypeList()
{
    static osg::ref_ptr<RenderBinPrototypeList> s_renderBinPrototypeList = new  RenderBinPrototypeList;
    return s_renderBinPrototypeList.get();
}

RenderBin* RenderBin::getRenderBinPrototype(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBinPrototypeList::iterator itr = list->find(binName);
        if (itr != list->end()) return itr->second.get();
    }
    return NULL;
}

RenderBin* RenderBin::createRenderBin(const std::string& binName)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list)
    {
        RenderBin* prototype = getRenderBinPrototype(binName);
        if (prototype) return dynamic_cast<RenderBin*>(prototype->clone(osg::CopyOp::DEEP_COPY_ALL));
    }

    osg::notify(osg::WARN) <<"Warning: RenderBin \""<<binName<<"\" implemention not found, using default RenderBin as a fallback."<<std::endl;
    return new RenderBin;
}

void RenderBin::addRenderBinPrototype(const std::string& binName,RenderBin* proto)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        (*list)[binName] = proto;
    }
}

void RenderBin::removeRenderBinPrototype(RenderBin* proto)
{
    RenderBinPrototypeList* list = renderBinPrototypeList();
    if (list && proto)
    {
        RenderBinPrototypeList::iterator itr = list->find(proto->className());
        if (itr != list->end()) list->erase(itr);
    }
}

RenderBin::RenderBin(SortMode mode)
{
    _binNum = 0;
    _parent = NULL;
    _stage = NULL;
    _sortMode = mode;
}

RenderBin::RenderBin(const RenderBin& rhs,const CopyOp& copyop):
        Object(rhs,copyop),
        _binNum(rhs._binNum),
        _parent(rhs._parent),
        _stage(rhs._stage),
        _bins(rhs._bins),
        _renderGraphList(rhs._renderGraphList),
        _renderLeafList(rhs._renderLeafList),
        _sortMode(rhs._sortMode),
        _sortCallback(rhs._sortCallback),
        _drawCallback(rhs._drawCallback)
{

}

RenderBin::~RenderBin()
{
}

void RenderBin::reset()
{
    _renderGraphList.clear();
    _bins.clear();
}

void RenderBin::sort()
{
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        itr->second->sort();
    }

    if (_sortCallback.valid())
    {
        _sortCallback->sortImplementation(this);
    }
    else sortImplementation();
}

void RenderBin::setSortMode(SortMode mode)
{
    _sortMode = mode;
}

void RenderBin::sortImplementation()
{
    switch(_sortMode)
    {
        case(SORT_BY_STATE):
            sortByState();
            break;
        case(SORT_FRONT_TO_BACK):
            sortFrontToBack();
            break;
        case(SORT_BACK_TO_FRONT):
            sortBackToFront();
            break;
        default:
            break;
    }
}

struct SortByStateFunctor
{
    bool operator() (const RenderGraph* lhs,const RenderGraph* rhs) const
    {
        return (*(lhs->_stateset)<*(rhs->_stateset));
    }
};

void RenderBin::sortByState()
{
    // actually we'll do nothing right now, as fine grained sorting by state
    // appears to cost more to do than it saves in draw.  The contents of
    // the RenderGraph leaves is already coasrse grained sorted, this
    // sorting is as a function of the cull traversal.
    // cout << "doing sortByState "<<this<<endl;
}

struct FrontToBackSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (lhs->_depth<rhs->_depth);
    }
};

void RenderBin::sortFrontToBack()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),FrontToBackSortFunctor());

//    cout << "sort front to back"<<endl;
}

struct BackToFrontSortFunctor
{
    bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
    {
        return (rhs->_depth<lhs->_depth);
    }
};

void RenderBin::sortBackToFront()
{
    copyLeavesFromRenderGraphListToRenderLeafList();

    // now sort the list into acending depth order.
    std::sort(_renderLeafList.begin(),_renderLeafList.end(),BackToFrontSortFunctor());

//    cout << "sort back to front"<<endl;
}

void RenderBin::copyLeavesFromRenderGraphListToRenderLeafList()
{
    _renderLeafList.clear();

    int totalsize=0;
    RenderGraphList::iterator itr;
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        totalsize += (*itr)->_leaves.size();
    }

    _renderLeafList.reserve(totalsize);

    // first copy all the leaves from the render graphs into the leaf list.
    for(itr=_renderGraphList.begin();
        itr!=_renderGraphList.end();
        ++itr)
    {
        for(RenderGraph::LeafList::iterator dw_itr = (*itr)->_leaves.begin();
            dw_itr != (*itr)->_leaves.end();
            ++dw_itr)
        {
            _renderLeafList.push_back(dw_itr->get());
        }
    }

    // empty the render graph list to prevent it being drawn along side the render leaf list (see drawImplementation.)
    _renderGraphList.clear();
}

RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName)
{
    // search for appropriate bin.
    RenderBinList::iterator itr = _bins.find(binNum);
    if (itr!=_bins.end()) return itr->second.get();

    // create a renderin bin and insert into bin list.
    RenderBin* rb = RenderBin::createRenderBin(binName);
    if (rb)
    {

        RenderStage* rs = dynamic_cast<RenderStage*>(rb);
        if (rs)
        {
            rs->_binNum = binNum;
            rs->_parent = NULL;
            rs->_stage = rs;
            _stage->addToDependencyList(rs);
        }
        else
        {
            rb->_binNum = binNum;
            rb->_parent = this;
            rb->_stage = _stage;
            _bins[binNum] = rb;
        }
    }
    return rb;
}

void RenderBin::draw(osg::State& state,RenderLeaf*& previous)
{
    if (_drawCallback.valid())
    {
        _drawCallback->drawImplementation(this,state,previous);
    }
    else drawImplementation(state,previous);
}

void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous)
{
    // draw first set of draw bins.
    RenderBinList::iterator rbitr;
    for(rbitr = _bins.begin();
        rbitr!=_bins.end() && rbitr->first<0;
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

    // draw fine grained ordering.
    for(RenderLeafList::iterator rlitr= _renderLeafList.begin();
        rlitr!= _renderLeafList.end();
        ++rlitr)
    {
        RenderLeaf* rl = *rlitr;
        rl->render(state,previous);
        previous = rl;
    }

    // draw coarse grained ordering.
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            rl->render(state,previous);
            previous = rl;

        }
    }

    // draw post bins.
    for(;
        rbitr!=_bins.end();
        ++rbitr)
    {
        rbitr->second->draw(state,previous);
    }

}

// stats
bool RenderBin::getStats(osg::Statistics* primStats)
{ // different by return type - collects the stats in this renderrBin
    bool somestats=false;
    for(RenderGraphList::iterator oitr=_renderGraphList.begin();
        oitr!=_renderGraphList.end();
        ++oitr)
    {

        for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
            dw_itr != (*oitr)->_leaves.end();
            ++dw_itr)
        {
            RenderLeaf* rl = dw_itr->get();
            Drawable* dw= rl->_drawable;
            primStats->addDrawable(); // number of geosets
            if (rl->_modelview.get()) primStats->addMatrix(); // number of matrices
            if (dw)
            {
                // then tot up the primtive types and no vertices.
                dw->accept(*primStats); // use sub-class to find the stats for each drawable
                if (typeid(*dw)==typeid(osg::ImpostorSprite)) primStats->addImpostor(1);
            }
        }
        somestats=true;
    }
    return somestats;
}

void RenderBin::getPrims(osg::Statistics* primStats)
{
    static int ndepth;
    ndepth++;
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        primStats->addBins(1);
        itr->second->getPrims(primStats);
    }
    getStats(primStats);
    ndepth--;

}

bool RenderBin::getPrims(osg::Statistics* primStats, int nbin)
{ // collect stats for array of bins, maximum nbin
    // (which will be modified on next call if array of primStats is too small);
    // return 1 for OK;
    static int ndepth;
    bool ok=false;
    ndepth++;
    int nb=primStats[0].getBins();
    if (nb<nbin)
    { // if statement to protect against writing to bins beyond the maximum seen before
        primStats[nb].setBinNo(nb);
        primStats[nb].setDepth(ndepth);
        getStats(primStats+nb);
    }
    primStats[0].addBins(1);
    for(RenderBinList::iterator itr = _bins.begin();
        itr!=_bins.end();
        ++itr)
    {
        if (itr->second->getPrims(primStats, nbin)) ok = true;
    }
    ok=true;
    ndepth--;
    return ok;
}
<|endoftext|>


<commit_before>#include <engpar_support.h>
#include <apfGraph.h>
#include <apfMesh2.h>
#include <apfNumbering.h>
#include <apfMDS.h>
#include <gmi_mesh.h>
#include <apf.h>
#include <engpar.h>
#include <engpar_input.h>
#include <binGraph.h>
#include <parma.h>

int main(int argc, char* argv[]) {
  MPI_Init(&argc,&argv);
  EnGPar_Initialize();
  EnGPar_Open_Log();

  if (argc != 4 && argc!=5) {
    if ( !PCU_Comm_Self() ) {
      printf("Usage: %s <model> <mesh> <tolerance> [multi-edgetypes]\n", argv[0]);
    }
    EnGPar_Finalize();
    assert(false);
  }
  apf::Mesh2* m=NULL;
  agi::Ngraph* g=NULL;
  //Load mesh
  gmi_register_mesh();
  m = apf::loadMdsMesh(argv[1],argv[2]);

  Parma_PrintPtnStats(m,"before");
  //visualize the mesh before balancing
  apf::writeVtkFiles("pre", m);

  double tol = atof(argv[3]);
  if (!PCU_Comm_Self())
    printf("tolerance %f\n", tol);

  double times[10];
  times[0] = PCU_Time();
  times[4] = PCU_Time();
  if (argc==5) {
    int edges[2] = {0,2};
    //balance vtx>edge>elm
    g = agi::createAPFGraph(m,3,edges,2);
  }
  else {
    //balance vtx>elm
    g = agi::createAPFGraph(m,3,0);
  }
  times[0] = PCU_Time()-times[0];
  times[1] = PCU_Time();

  engpar::Input* input = new engpar::Input(g);
  input->priorities.push_back(0);
  input->tolerances.push_back(tol);
  if (argc==5) {
    input->priorities.push_back(1);
    input->tolerances.push_back(tol);
  }
  input->priorities.push_back(-1);
  input->tolerances.push_back(tol);

  input->step_factor=.1;

  input->useDistanceQueue=true;
  //Create the balancer
  agi::Balancer* balancer = engpar::makeBalancer(input);
  balancer->balance(tol);

  engpar::evaluatePartition(g);
  //Destroy balancer
  delete balancer;
  times[1] = PCU_Time() - times[1];

  //Ensure the graph is still valid
  agi::checkValidity(g);

  times[2] = PCU_Time();

  //Migration of original data structure
  //Only implemented for mesh
  agi::PartitionMap* map = g->getPartition();

  //map can be used to migrate the original structure
  apf::Migration* plan = new apf::Migration(m);
  apf::GlobalNumbering* gids = m->findGlobalNumbering("primary_ids_global");
  apf::MeshIterator* mitr = m->begin(3);
  apf::MeshEntity* ent;
  while ((ent = m->iterate(mitr))) {
    agi::gid_t gid = apf::getNumber(gids,ent,0);
    assert(map->find(gid)!=map->end());
    agi::part_t target = map->find(gid)->second;
    if (target!=PCU_Comm_Self())
      plan->send(ent,target);
  }
  m->end(mitr);
  delete map;
  m->migrate(plan);

  times[2] = PCU_Time() - times[2];
  times[4] = PCU_Time() - times[4];
  PCU_Max_Doubles(times,4);

  if (!PCU_Comm_Self()) {
    printf("Total Time: %f\n",times[4]);
    printf("Construct Time: %f\n",times[0]);
    printf("Balancing Time: %f\n",times[1]);
    printf("Repartition Time: %f\n",times[2]);
  }

  //Destroy graph
  agi::destroyGraph(g);

  //visualize the mesh after balancing
  apf::writeVtkFiles("post", m);
  Parma_PrintPtnStats(m,"after");

  //Destroy mesh
  m->destroyNative();
  apf::destroyMesh(m);

  PCU_Barrier();
  if (!PCU_Comm_Self())
    printf("\nAll tests passed\n");

  EnGPar_Finalize();
  MPI_Finalize();
}
<commit_msg>balanceMesh: user controls writing of paraview files<commit_after>#include <engpar_support.h>
#include <apfGraph.h>
#include <apfMesh2.h>
#include <apfNumbering.h>
#include <apfMDS.h>
#include <gmi_mesh.h>
#include <apf.h>
#include <engpar.h>
#include <engpar_input.h>
#include <binGraph.h>
#include <parma.h>

int main(int argc, char* argv[]) {
  MPI_Init(&argc,&argv);
  EnGPar_Initialize();
  EnGPar_Open_Log();

  if (argc != 5 && argc != 6) {
    if ( !PCU_Comm_Self() ) {
      printf("Usage: %s <model> <mesh> <tolerance> <render=[1:on|0:off]> [multi-edgetypes]\n", argv[0]);
    }
    EnGPar_Finalize();
    assert(false);
  }

  apf::Mesh2* m=NULL;
  agi::Ngraph* g=NULL;
  //Load mesh
  gmi_register_mesh();
  m = apf::loadMdsMesh(argv[1],argv[2]);

  double tol = atof(argv[3]);
  const int render = atoi(argv[4]);
  if (!PCU_Comm_Self())
    printf("render vtk %s\n", render == 0 ? "off" : "on" );

  Parma_PrintPtnStats(m,"before");
  if(render)
    apf::writeVtkFiles("pre", m);

  double times[10];
  times[0] = PCU_Time();
  times[4] = PCU_Time();
  if (argc==6) {
    int edges[2] = {0,2};
    //balance vtx>edge>elm
    g = agi::createAPFGraph(m,3,edges,2);
  }
  else {
    //balance vtx>elm
    g = agi::createAPFGraph(m,3,0);
  }
  times[0] = PCU_Time()-times[0];
  times[1] = PCU_Time();

  engpar::Input* input = new engpar::Input(g);
  input->priorities.push_back(0);
  input->tolerances.push_back(tol);
  if (argc==5) {
    input->priorities.push_back(1);
    input->tolerances.push_back(tol);
  }
  input->priorities.push_back(-1);
  input->tolerances.push_back(tol);

  input->step_factor=.1;

  input->useDistanceQueue=true;
  //Create the balancer
  agi::Balancer* balancer = engpar::makeBalancer(input);
  balancer->balance(tol);

  engpar::evaluatePartition(g);
  //Destroy balancer
  delete balancer;
  times[1] = PCU_Time() - times[1];

  //Ensure the graph is still valid
  agi::checkValidity(g);

  times[2] = PCU_Time();

  //Migration of original data structure
  //Only implemented for mesh
  agi::PartitionMap* map = g->getPartition();

  //map can be used to migrate the original structure
  apf::Migration* plan = new apf::Migration(m);
  apf::GlobalNumbering* gids = m->findGlobalNumbering("primary_ids_global");
  apf::MeshIterator* mitr = m->begin(3);
  apf::MeshEntity* ent;
  while ((ent = m->iterate(mitr))) {
    agi::gid_t gid = apf::getNumber(gids,ent,0);
    assert(map->find(gid)!=map->end());
    agi::part_t target = map->find(gid)->second;
    if (target!=PCU_Comm_Self())
      plan->send(ent,target);
  }
  m->end(mitr);
  delete map;
  m->migrate(plan);

  times[2] = PCU_Time() - times[2];
  times[4] = PCU_Time() - times[4];
  PCU_Max_Doubles(times,4);

  if (!PCU_Comm_Self()) {
    printf("Total Time: %f\n",times[4]);
    printf("Construct Time: %f\n",times[0]);
    printf("Balancing Time: %f\n",times[1]);
    printf("Repartition Time: %f\n",times[2]);
  }

  //Destroy graph
  agi::destroyGraph(g);

  if(render)
    apf::writeVtkFiles("post", m);
  Parma_PrintPtnStats(m,"after");

  //Destroy mesh
  m->destroyNative();
  apf::destroyMesh(m);

  PCU_Barrier();
  if (!PCU_Comm_Self())
    printf("\nAll tests passed\n");

  EnGPar_Finalize();
  MPI_Finalize();
}
<|endoftext|>


<commit_before>/*
 * Author      : Eli Gundry
 * Date        : 11/28/2011
 * Name        : Gradebook Classes
 * Description : Determines the weighted letter grade of a student with classes
 * Link        : http://www.cs.kent.edu/~lucc/ioop/Labs/Lab2/proj-13
 */

#include <iostream>

using namespace std;

class StudentGrade
{
	public:
		void input();
		void output();
	private:
		double final_score();
		char letter_grade();
		double quiz_1,
			   quiz_2,
			   midterm,
			   final;
};

int main()
{
	StudentGrade grade;

	grade.input();
	grade.output();

	return 0;
}

void StudentGrade::input()
{
	cout << "What was the student's grade for quiz 1? (0-10)" << endl;
	cin >> quiz_1;
	cout << "And for quiz 2? (0-10)" << endl;
	cin >> quiz_2;
	cout << "How did they do on the midterm? (0-100)" << endl;
	cin >> midterm;
	cout << "And the final exam? (0-100)" << endl;
	cin >> final;
}

void StudentGrade::output()
{
	cout << endl << "Quiz 1: " << (quiz_1 * 10) << endl
		 << "Quiz 2: " << (quiz_2 * 10) << endl
		 << "Midterm: " << midterm << endl
		 << "Final Exam: " << final << endl << endl;
}

double StudentGrade::final_score()
{
	return ((final * 0.5) + (midterm * 0.25) + (((quiz_1 * 5) + (quiz_1 * 5)) * 0.25));
}

char StudentGrade::letter_grade()
{
	if (grade >= 90)
		return 'A';
	else if (grade >= 80)
		return 'B';
	else if (grade >= 70)
		return 'C';
	else if (grade >= 60)
		return 'D';
	else
		return 'F';
}
<commit_msg>Started add CC Liu grading scale<commit_after>/*
 * Author      : Eli Gundry
 * Date        : 11/28/2011
 * Name        : Gradebook Classes
 * Description : Determines the weighted letter grade of a student with classes
 * Link        : http://www.cs.kent.edu/~lucc/ioop/Labs/Lab2/proj-13
 */

#include <iostream>

using namespace std;

class StudentGrade
{
	public:
	private:
		double final_score();
		char letter_grade();
		char student_name[81];
		double quiz_1,
			   quiz_2,
			   midterm,
			   final;
};

void input(StudentGrade grade);
void output(StudentGrade grade);

int main()
{
	StudentGrade grade;

	input(grade);
	output(grade);

	return 0;
}

void input(StudentGrade grade)
{
	cout << "#### CC Gradebook System ####" << endl;

	do {
		cout << "What is the student's name? (Press Enter to exit)" << endl;

		for (int num_of_students = 0; i < grade.student name; i++) {
			cin >> grade.student_name;
		}

	} while (grade.student_name != '\r')

}

void output(StudentGrade grade)
{
	cout << endl << "Quiz 1: " << (grade.quiz_1 * 10) << endl
		 << "Quiz 2: " << (grade.quiz_2 * 10) << endl
		 << "Midterm: " << grade.midterm << endl
		 << "Final Exam: " << grade.final << endl << endl;

}

double StudentGrade::final_score()
{
	return ((final * 0.5) + (midterm * 0.25) + (((quiz_1 * 5) + (quiz_1 * 5)) * 0.25));
}

char StudentGrade::letter_grade()
{
	if (grade >= 90)
		return 'A';
	else if (grade >= 80)
		return 'B';
	else if (grade >= 70)
		return 'C';
	else if (grade >= 60)
		return 'D';
	else
		return 'F';
}
<|endoftext|>


<commit_before>#include <SDL2/SDL.h>
#include "rotate_triangle.h"

#ifdef USE_GCW0
static const int WIDTH = 320;
static const int HEIGHT = 240;
#else
static const int WIDTH = 800;
static const int HEIGHT = 600;
#endif

SDL_Window *gscreen = nullptr;
SDL_GLContext gcontext;

SDL_Window *init_window(Uint32 subsystems, Uint32 windowFlags)
{
	SDL_Window *window = nullptr;
	if ( SDL_Init(subsystems) >=0 )
	{
		window = SDL_CreateWindow(	"An SDL2 window",
				SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
				WIDTH, HEIGHT,
				windowFlags );
		if(window)
		{
			//
			// Set core profile
			//
			SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
			SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
			SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
			// Enables double buffering
			SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
			// 24 bit depth buffer
			SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
			// Create OpenGL Context
			gcontext = SDL_GL_CreateContext(window);
			if(nullptr == gcontext)
			{
				std::cerr << "Failed  to create gl context.\nError: " <<  SDL_GetError() << std::endl;
				 SDL_DestroyWindow(window);
				 window = nullptr;
			}
			// enable vsync
			SDL_GL_SetSwapInterval(1);
		}
	}
	else
	{
		std::cerr << "Failed to init sdl: " << SDL_GetError() << std::endl;
		exit(1);
	}
	return window;
}

inline bool inputHandler()
{
	SDL_Event event;
	bool rtn = true;
	while(SDL_PollEvent(&event))
	{
		if (event.type==SDL_QUIT) {return false;}
		if (event.type==SDL_KEYDOWN)
		{
			switch(event.key.keysym.sym)
			{
				case SDLK_RETURN:
					std::cout << "Start button pressed" << std::endl;
					break;
				case SDLK_ESCAPE:
					std::cout << "Esc Key pressed" << std::endl;
					rtn = false;
					break;
				case SDLK_LEFT:
					std::cout << "Left Key pressed" << std::endl;
					break;
				case SDLK_RIGHT:
					std::cout << "Right Key pressed" << std::endl;
					break;
				case SDLK_UP:
					std::cout << "Up Key pressed" << std::endl;
					break;
				case SDLK_DOWN:
					std::cout << "Down Key pressed" << std::endl;
					break;
				case SDLK_LCTRL:
					std::cout << "A Key pressed" << std::endl;
					break;
				case SDLK_LALT:
					std::cout << "B Key pressed" << std::endl;
					break;
				case SDLK_LSHIFT:
					std::cout << "X Key pressed" << std::endl;
					break;
				case SDLK_SPACE:
					std::cout << "Y Key pressed" << std::endl;
					break;
				default:
					std::cout << "Unknown Key pressed " << event.key.keysym.sym << std::endl;
			}
		}
	}
	return rtn;
}

void cleanup()
{
	SDL_GL_DeleteContext(gcontext);
	SDL_DestroyWindow(gscreen);
	SDL_Quit();
}

int main(int argc, char *argv[])
{
	Uint32 subsystem = 0;
	Uint32 windowFlags = 0;
	subsystem |= SDL_INIT_VIDEO | SDL_INIT_TIMER;
	windowFlags |= SDL_WINDOW_OPENGL;

	gscreen = init_window(subsystem, windowFlags);
	if (!gscreen)
	{
		std::cerr << "Could not create window " <<  SDL_GetError() << std::endl;
		return EXIT_FAILURE;
	}
	printGLVersion();

	RotateTriangle tri;
	bool running=true;
	glViewport(0,0,WIDTH,HEIGHT);
	while(running)
	{
		glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
		glClear(GL_COLOR_BUFFER_BIT);
		tri.render();
		SDL_GL_SwapWindow(gscreen);
		running = inputHandler();

	}
	cleanup();
	return 0;
}
<commit_msg>Setting GL Attributes before opening the window<commit_after>#include <SDL2/SDL.h>
#include "rotate_triangle.h"

#ifdef USE_GCW0
static const int WIDTH = 320;
static const int HEIGHT = 240;
#else
static const int WIDTH = 800;
static const int HEIGHT = 600;
#endif

SDL_Window *gscreen = nullptr;
SDL_GLContext gcontext;

SDL_Window *init_window(Uint32 subsystems, Uint32 windowFlags)
{
	SDL_Window *window = nullptr;
	if ( SDL_Init(subsystems) >=0 )
	{
		//
		// Set core profile
		//
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
		// Enables double buffering
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
		// 24 bit depth buffer
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

		window = SDL_CreateWindow(	"An SDL2 window",
				SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
				WIDTH, HEIGHT,
				windowFlags );
		if(window)
		{
			// Create OpenGL Context
			gcontext = SDL_GL_CreateContext(window);
			if(nullptr == gcontext)
			{
				std::cerr << "Failed  to create gl context.\nError: " <<  SDL_GetError() << std::endl;
				SDL_DestroyWindow(window);
				window = nullptr;
			}
			// enable vsync
			SDL_GL_SetSwapInterval(1);
		}
	}
	else
	{
		std::cerr << "Failed to init sdl: " << SDL_GetError() << std::endl;
		exit(1);
	}
	return window;
}

inline bool inputHandler()
{
	SDL_Event event;
	bool rtn = true;
	while(SDL_PollEvent(&event))
	{
		if (event.type==SDL_QUIT) {return false;}
		if (event.type==SDL_KEYDOWN)
		{
			switch(event.key.keysym.sym)
			{
				case SDLK_RETURN:
					std::cout << "Start button pressed" << std::endl;
					break;
				case SDLK_ESCAPE:
					std::cout << "Esc Key pressed" << std::endl;
					rtn = false;
					break;
				case SDLK_LEFT:
					std::cout << "Left Key pressed" << std::endl;
					break;
				case SDLK_RIGHT:
					std::cout << "Right Key pressed" << std::endl;
					break;
				case SDLK_UP:
					std::cout << "Up Key pressed" << std::endl;
					break;
				case SDLK_DOWN:
					std::cout << "Down Key pressed" << std::endl;
					break;
				case SDLK_LCTRL:
					std::cout << "A Key pressed" << std::endl;
					break;
				case SDLK_LALT:
					std::cout << "B Key pressed" << std::endl;
					break;
				case SDLK_LSHIFT:
					std::cout << "X Key pressed" << std::endl;
					break;
				case SDLK_SPACE:
					std::cout << "Y Key pressed" << std::endl;
					break;
				default:
					std::cout << "Unknown Key pressed " << event.key.keysym.sym << std::endl;
			}
		}
	}
	return rtn;
}

void cleanup()
{
	SDL_GL_DeleteContext(gcontext);
	SDL_DestroyWindow(gscreen);
	SDL_Quit();
}

int main(int argc, char *argv[])
{
	Uint32 subsystem = 0;
	Uint32 windowFlags = 0;
	subsystem |= SDL_INIT_VIDEO | SDL_INIT_TIMER;
	windowFlags |= SDL_WINDOW_OPENGL;

	gscreen = init_window(subsystem, windowFlags);
	if (!gscreen)
	{
		std::cerr << "Could not create window " <<  SDL_GetError() << std::endl;
		return EXIT_FAILURE;
	}
	printGLVersion();

	RotateTriangle tri;
	bool running=true;
	glViewport(0,0,WIDTH,HEIGHT);
	while(running)
	{
		glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
		glClear(GL_COLOR_BUFFER_BIT);
		tri.render();
		SDL_GL_SwapWindow(gscreen);
		running = inputHandler();

	}
	cleanup();
	return 0;
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __PROC_UTILS_HPP__
#define __PROC_UTILS_HPP__

#include <string>
#include <vector>

namespace mesos { namespace internal { namespace monitoring {

struct ProcessStats {
  std::string pid;
  std::string ppid;
  std::string pgrp;
  std::string session;
  double cpu_time;  // utime + stime in ticks.
  double starttime; // jiffies since system boot time.
  double mem_usage; // rss in bytes.
};

// Retrieves resource usage and metadata for a process. Takes the PID of the
// process to query and returns a ProcessStats struct containing the retrieved
// info.
ProcessStats getProcessStats(const std::string& pid);

// Retrieves the system boot time (in milliseconds since epoch).
double getBootTime();

// Retrieves the current system time (in milliseconds since epoch).
double getCurrentTime();

// Retrieves the start time (in milliseconds since epoch) of the process with
// the given PID.
double getStartTime(const std::string& pid);

// Reads from proc and returns a vector of all processes running on the system.
std::vector<std::string> getAllPids();

}}} // namespace mesos { namespace internal { namespace monitoring {

#endif // __PROC_UTILS_HPP__
<commit_msg>Fixed style in proc_utils.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __PROC_UTILS_HPP__
#define __PROC_UTILS_HPP__

#include <string>
#include <vector>

namespace mesos {
namespace internal {
namespace monitoring {

struct ProcessStats {
  std::string pid;
  std::string ppid;
  std::string pgrp;
  std::string session;
  double cpu_time;  // utime + stime in ticks.
  double starttime; // jiffies since system boot time.
  double mem_usage; // rss in bytes.
};

// Retrieves resource usage and metadata for a process. Takes the PID of the
// process to query and returns a ProcessStats struct containing the retrieved
// info.
ProcessStats getProcessStats(const std::string& pid);

// Retrieves the system boot time (in milliseconds since epoch).
double getBootTime();

// Retrieves the current system time (in milliseconds since epoch).
double getCurrentTime();

// Retrieves the start time (in milliseconds since epoch) of the process with
// the given PID.
double getStartTime(const std::string& pid);

// Reads from proc and returns a vector of all processes running on the system.
std::vector<std::string> getAllPids();

} // namespace monitoring {
} // namespace internal {
} // namespace mesos {

#endif // __PROC_UTILS_HPP__
<|endoftext|>


<commit_before>#include "fdhandle.h"

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>

void sig_handler(int sig)
{
    int save_errno = errno;
    int msg        = sig;
    send(g_sig_pipe[1], (char*)&msg, 1, 0);
    errno = save_errno;
}

void add_sig(int sig, void (*handler)(int), bool restart)
{
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = handler;
    if (restart) {
        sa.sa_flags |= SA_RESTART;
    }
    sigfillset(&sa.sa_mask);
    if (sigaction(sig, &sa, nullptr) == -1) {
        perror("sigaction");
        exit(EXIT_FAILURE);
    }
}

int set_nonblocking(int fd)
{
    int old_option = fcntl(fd, F_GETFL);
    int new_option = old_option | O_NONBLOCK;
    fcntl(fd, F_SETFL, new_option);
    return old_option;
}

void add_fd(int epollfd, int fd, uint32_t events)
{
    epoll_event event;
    event.data.fd = fd;
    event.events  = events;
    epoll_ctl(epollfd, EPOLL_CTL_ADD, &event);
    set_nonblocking(fd);
}

void remove_fd(int epollfd, int fd)
{
    epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, 0);
    close(fd);
}
<commit_msg>function use error fix<commit_after>#include "fdhandle.h"

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

void sig_handler(int sig)
{
    int save_errno = errno;
    int msg        = sig;
    send(g_sig_pipe[1], (char*)&msg, 1, 0);
    errno = save_errno;
}

void add_sig(int sig, void (*handler)(int), bool restart)
{
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = handler;
    if (restart) {
        sa.sa_flags |= SA_RESTART;
    }
    sigfillset(&sa.sa_mask);
    if (sigaction(sig, &sa, nullptr) == -1) {
        perror("sigaction");
        exit(EXIT_FAILURE);
    }
}

int set_nonblocking(int fd)
{
    int old_option = fcntl(fd, F_GETFL);
    int new_option = old_option | O_NONBLOCK;
    fcntl(fd, F_SETFL, new_option);
    return old_option;
}

void add_fd(int epollfd, int fd, uint32_t events)
{
    epoll_event event;
    event.data.fd = fd;
    event.events  = events;
    epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
    set_nonblocking(fd);
}

void remove_fd(int epollfd, int fd)
{
    epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, 0);
    close(fd);
}
<|endoftext|>


<commit_before>/* Copyright (C) 2011-2013, Benjamin Jemlich <pcgod@users.sourceforge.net>
   Copyright (C) 2013, Mikkel Krautz <mikkel@krautz.dk>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <windows.h>
#include <shlwapi.h>
#include <stdio.h>

#include <string>

#define ENV_BUF_MAX 1024

typedef int (*DLL_MAIN)(HINSTANCE, HINSTANCE, LPSTR, int);
#ifdef DEBUG
typedef int (*DLL_DEBUG_MAIN)(int, char **);
#endif

// Alert shows a fatal error dialog and waits for the user to click OK.
static void Alert(LPCWSTR title, LPCWSTR msg) {
	MessageBox(NULL, msg, title, MB_OK|MB_ICONERROR);
}

// GetExecutableDirPath returns the directory that
// mumble.exe resides in.
static std::wstring GetExecutableDirPath() {
	wchar_t path[MAX_PATH];

	if (GetModuleFileNameW(NULL, path, MAX_PATH) == 0)
		return std::wstring();

	if (!PathRemoveFileSpecW(path))
		return std::wstring();

	std::wstring exe_path(path);
	return exe_path.append(L"\\");
}

// ConfigureEnvironment prepares mumble.exe's environment to
// run mumble_app.dll.
static bool ConfigureEnvironment() {
	std::wstring exe_path = GetExecutableDirPath();

	// Remove the current directory from the DLL search path.
	if (!SetDllDirectoryW(L""))
		return false;

	// Insert mumble.exe's directory as the first entry in the PATH
	// environment variable.
	{
		wchar_t path_env[ENV_BUF_MAX];
		DWORD res = GetEnvironmentVariableW(L"PATH", path_env, ENV_BUF_MAX);
		if (res == 0 || res >= ENV_BUF_MAX) {
			return false;
		}

		std::wstring new_path(exe_path);
		new_path.append(L"\\;");
		new_path.append(path_env);
		if (!SetEnvironmentVariableW(L"PATH", new_path.c_str()))
			return false;
	}

	// Set mumble.exe's directory as the current working directory.
	if (!SetCurrentDirectoryW(exe_path.c_str()))
		return false;

	return true;
}

// GetAbsoluteMumbleAppDllPath returns the absolute path to
// mumble_app.dll - the DLL containing the Mumble client
// application code.
static std::wstring GetAbsoluteMumbleAppDllPath() {
	std::wstring exe_path = GetExecutableDirPath();
	if (exe_path.empty())
		return std::wstring();

	std::wstring abs_dll_path(exe_path);
	abs_dll_path.append(L"\\");
	abs_dll_path.append(L"mumble_app.dll");
	return abs_dll_path;
}

#ifdef DEBUG
int main(int argc, char **argv) {
	if (!ConfigureEnvironment()) {
		Alert(L"Mumble Launcher Error -1", L"Unable to configure environment.");
		return -1;
	}

	std::wstring abs_dll_path = GetAbsoluteMumbleAppDllPath();
	if (abs_dll_path.empty()) {
		Alert(L"Mumble Launcher Error -2", L"Unable to find the absolute path of mumble_app.dll.");
		return -2;
	}

	HMODULE dll = LoadLibraryExW(abs_dll_path.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
	if (!dll) {
		Alert(L"Mumble Launcher Error -3", L"Failed to load mumble_app.dll.");
		return -3;
	}

	DLL_DEBUG_MAIN entry_point = reinterpret_cast<DLL_DEBUG_MAIN>(GetProcAddress(dll, "main"));
	if (!entry_point) {
		Alert(L"Mumble Launcher Error -4", L"Unable to find expected entry point ('main') in mumble_app.dll.");
		return -4;
	}

	int rc = entry_point(argc, argv);

	return rc;
}
#endif  // DEBUG

int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, wchar_t *cmdArg, int cmdShow) {
	if (!ConfigureEnvironment()) {
		Alert(L"Mumble Launcher Error -1", L"Unable to configure environment.");
		return -1;
	}

	std::wstring abs_dll_path = GetAbsoluteMumbleAppDllPath();
	if (abs_dll_path.empty()) {
		Alert(L"Mumble Launcher Error -2", L"Unable to find the absolute path of mumble_app.dll.");
		return -2;
	}

	HMODULE dll = LoadLibraryExW(abs_dll_path.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
	if (!dll) {
		Alert(L"Mumble Launcher Error -3", L"Failed to load mumble_app.dll.");
		return -3;
	}

	DLL_MAIN entry_point = reinterpret_cast<DLL_MAIN>(GetProcAddress(dll, "MumbleMain"));
	if (!entry_point) {
		Alert(L"Mumble Launcher Error -4", L"Unable to find expected entry point ('MumbleMain') in mumble_app.dll.");
		return -4;
	}

	(void) cmdArg;
	int rc = entry_point(instance, prevInstance, NULL, cmdShow);

	return rc;
}
<commit_msg>mumble_exe: do not add mumble.exe's parent directory to PATH.<commit_after>/* Copyright (C) 2011-2013, Benjamin Jemlich <pcgod@users.sourceforge.net>
   Copyright (C) 2013, Mikkel Krautz <mikkel@krautz.dk>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <windows.h>
#include <shlwapi.h>
#include <stdio.h>

#include <string>

typedef int (*DLL_MAIN)(HINSTANCE, HINSTANCE, LPSTR, int);
#ifdef DEBUG
typedef int (*DLL_DEBUG_MAIN)(int, char **);
#endif

// Alert shows a fatal error dialog and waits for the user to click OK.
static void Alert(LPCWSTR title, LPCWSTR msg) {
	MessageBox(NULL, msg, title, MB_OK|MB_ICONERROR);
}

// GetExecutableDirPath returns the directory that
// mumble.exe resides in.
static std::wstring GetExecutableDirPath() {
	wchar_t path[MAX_PATH];

	if (GetModuleFileNameW(NULL, path, MAX_PATH) == 0)
		return std::wstring();

	if (!PathRemoveFileSpecW(path))
		return std::wstring();

	std::wstring exe_path(path);
	return exe_path.append(L"\\");
}

// ConfigureEnvironment prepares mumble.exe's environment to
// run mumble_app.dll.
static bool ConfigureEnvironment() {
	std::wstring exe_path = GetExecutableDirPath();

	// Remove the current directory from the DLL search path.
	if (!SetDllDirectoryW(L""))
		return false;

	// Set mumble.exe's directory as the current working directory.
	if (!SetCurrentDirectoryW(exe_path.c_str()))
		return false;

	return true;
}

// GetAbsoluteMumbleAppDllPath returns the absolute path to
// mumble_app.dll - the DLL containing the Mumble client
// application code.
static std::wstring GetAbsoluteMumbleAppDllPath() {
	std::wstring exe_path = GetExecutableDirPath();
	if (exe_path.empty())
		return std::wstring();

	std::wstring abs_dll_path(exe_path);
	abs_dll_path.append(L"\\");
	abs_dll_path.append(L"mumble_app.dll");
	return abs_dll_path;
}

#ifdef DEBUG
int main(int argc, char **argv) {
	if (!ConfigureEnvironment()) {
		Alert(L"Mumble Launcher Error -1", L"Unable to configure environment.");
		return -1;
	}

	std::wstring abs_dll_path = GetAbsoluteMumbleAppDllPath();
	if (abs_dll_path.empty()) {
		Alert(L"Mumble Launcher Error -2", L"Unable to find the absolute path of mumble_app.dll.");
		return -2;
	}

	HMODULE dll = LoadLibraryExW(abs_dll_path.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
	if (!dll) {
		Alert(L"Mumble Launcher Error -3", L"Failed to load mumble_app.dll.");
		return -3;
	}

	DLL_DEBUG_MAIN entry_point = reinterpret_cast<DLL_DEBUG_MAIN>(GetProcAddress(dll, "main"));
	if (!entry_point) {
		Alert(L"Mumble Launcher Error -4", L"Unable to find expected entry point ('main') in mumble_app.dll.");
		return -4;
	}

	int rc = entry_point(argc, argv);

	return rc;
}
#endif  // DEBUG

int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, wchar_t *cmdArg, int cmdShow) {
	if (!ConfigureEnvironment()) {
		Alert(L"Mumble Launcher Error -1", L"Unable to configure environment.");
		return -1;
	}

	std::wstring abs_dll_path = GetAbsoluteMumbleAppDllPath();
	if (abs_dll_path.empty()) {
		Alert(L"Mumble Launcher Error -2", L"Unable to find the absolute path of mumble_app.dll.");
		return -2;
	}

	HMODULE dll = LoadLibraryExW(abs_dll_path.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
	if (!dll) {
		Alert(L"Mumble Launcher Error -3", L"Failed to load mumble_app.dll.");
		return -3;
	}

	DLL_MAIN entry_point = reinterpret_cast<DLL_MAIN>(GetProcAddress(dll, "MumbleMain"));
	if (!entry_point) {
		Alert(L"Mumble Launcher Error -4", L"Unable to find expected entry point ('MumbleMain') in mumble_app.dll.");
		return -4;
	}

	(void) cmdArg;
	int rc = entry_point(instance, prevInstance, NULL, cmdShow);

	return rc;
}
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "CameraNode.h"
#include "DisplayEngine.h"
#include "OGLSurface.h"
#include "NodeDefinition.h"

#include "../base/TimeSource.h"
#include "../base/Logger.h"
#include "../base/Exception.h"
#include "../base/ScopeTimer.h"
#include "../base/XMLHelper.h"

#include "../graphics/Filterfill.h"

#include "../imaging/Camera.h"
#include "../imaging/FWCamera.h"
#include "../imaging/FakeCamera.h"

#include <iostream>
#include <sstream>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

using namespace std;

namespace avg {

NodeDefinition CameraNode::createDefinition()
{
    return NodeDefinition("camera", VisibleNode::buildNode<CameraNode>)
        .extendDefinition(RasterNode::createDefinition())
        .addArg(Arg<string>("driver", "firewire"))
        .addArg(Arg<string>("device", ""))
        .addArg(Arg<int>("unit", -1))
        .addArg(Arg<bool>("fw800", false))
        .addArg(Arg<double>("framerate", 15))
        .addArg(Arg<int>("capturewidth", 640))
        .addArg(Arg<int>("captureheight", 480))
        .addArg(Arg<string>("pixelformat", "RGB"))
        .addArg(Arg<int>("brightness", -1))
        .addArg(Arg<int>("exposure", -1))
        .addArg(Arg<int>("sharpness", -1))
        .addArg(Arg<int>("saturation", -1))
        .addArg(Arg<int>("gamma", -1))
        .addArg(Arg<int>("shutter", -1))
        .addArg(Arg<int>("gain", -1))
        .addArg(Arg<int>("strobeduration", -1));
}

CameraNode::CameraNode(const ArgList& Args)
    : m_bIsPlaying(false),
      m_FrameNum(0),
      m_bIsAutoUpdateCameraImage(true)
{
    Args.setMembers(this);
    string sDriver = Args.getArgVal<string>("driver");
    string sDevice = Args.getArgVal<string>("device");
    int unit = Args.getArgVal<int>("unit");
    bool bFW800 = Args.getArgVal<bool>("fw800");
    double FrameRate = Args.getArgVal<double>("framerate");
    int Width = Args.getArgVal<int>("capturewidth");
    int Height = Args.getArgVal<int>("captureheight");
    string sPF = Args.getArgVal<string>("pixelformat");

    PixelFormat camPF = Bitmap::stringToPixelFormat(sPF);
    if (camPF == NO_PIXELFORMAT) {
        throw Exception(AVG_ERR_INVALID_ARGS,
                "Unknown camera pixel format "+sPF+".");
    }
    PixelFormat destPF;
    if (Bitmap::pixelFormatIsColored(camPF)) {
        destPF = B8G8R8X8;
    } else {
        destPF = I8;
    }
//    cerr << "CameraNode ctor: " << Bitmap::getPixelFormatString(camPF) << "-->" <<
//            Bitmap::getPixelFormatString(destPF) << endl;

    m_pCamera = createCamera(sDriver, sDevice, unit, bFW800, IntPoint(Width, Height), camPF,
            destPF, FrameRate);
    AVG_TRACE(Logger::CONFIG, "Got Camera " << m_pCamera->getDevice() << " from driver: "
            << m_pCamera->getDriverName());

    m_pCamera->setFeature(CAM_FEATURE_BRIGHTNESS,
            Args.getArgVal<int>("brightness"));
    m_pCamera->setFeature(CAM_FEATURE_EXPOSURE,
            Args.getArgVal<int>("exposure"));
    m_pCamera->setFeature(CAM_FEATURE_SHARPNESS,
            Args.getArgVal<int>("sharpness"));
    m_pCamera->setFeature(CAM_FEATURE_SATURATION,
            Args.getArgVal<int>("saturation"));
    m_pCamera->setFeature(CAM_FEATURE_GAMMA,
            Args.getArgVal<int>("gamma"));
    m_pCamera->setFeature(CAM_FEATURE_SHUTTER,
            Args.getArgVal<int>("shutter"));
    m_pCamera->setFeature(CAM_FEATURE_GAIN,
            Args.getArgVal<int>("gain"));
    m_pCamera->setFeature(CAM_FEATURE_STROBE_DURATION,
            Args.getArgVal<int>("strobeduration"));
}

CameraNode::~CameraNode()
{
    m_pCamera = CameraPtr();
}

void CameraNode::setRenderingEngines(DisplayEngine * pDisplayEngine,
        AudioEngine * pAudioEngine)
{
    RasterNode::setRenderingEngines(pDisplayEngine, pAudioEngine);
    if (m_bIsPlaying) {
        open();
    }
}

void CameraNode::play()
{
    if (getState() == NS_CANRENDER) {
        open();
    }
    m_bIsPlaying = true;
}

void CameraNode::stop()
{
    m_bIsPlaying = false;
}

bool CameraNode::isAvailable()
{
    if (!m_pCamera || boost::dynamic_pointer_cast<FakeCamera>(m_pCamera)) {
        return false;
    } else {
        return true;
    }
}

int CameraNode::getBrightness() const
{
    return getFeature(CAM_FEATURE_BRIGHTNESS);
}

void CameraNode::setBrightness(int Value)
{
    setFeature(CAM_FEATURE_BRIGHTNESS, Value);
}

int CameraNode::getSharpness() const
{
    return getFeature(CAM_FEATURE_SHARPNESS);
}

void CameraNode::setSharpness(int Value)
{
    setFeature(CAM_FEATURE_SHARPNESS, Value);
}

int CameraNode::getSaturation() const
{
    return getFeature(CAM_FEATURE_SATURATION);
}

void CameraNode::setSaturation(int Value)
{
    setFeature(CAM_FEATURE_SATURATION, Value);
}

int CameraNode::getGamma() const
{
    return getFeature(CAM_FEATURE_GAMMA);
}

void CameraNode::setGamma(int Value)
{
    setFeature(CAM_FEATURE_GAMMA, Value);
}

int CameraNode::getShutter() const
{
    return getFeature(CAM_FEATURE_SHUTTER);
}

void CameraNode::setShutter(int Value)
{
    setFeature(CAM_FEATURE_SHUTTER, Value);
}

int CameraNode::getGain() const
{
    return getFeature(CAM_FEATURE_GAIN);
}

void CameraNode::setGain(int Value)
{
    setFeature(CAM_FEATURE_GAIN, Value);
}

int CameraNode::getWhitebalanceU() const
{
    return m_pCamera->getWhitebalanceU();
}

int CameraNode::getWhitebalanceV() const
{
    return m_pCamera->getWhitebalanceV();
}

void CameraNode::setWhitebalance(int u, int v)
{
    m_pCamera->setWhitebalance(u, v);
}

void CameraNode::doOneShotWhitebalance()
{
    // The first line turns off auto white balance.
    m_pCamera->setWhitebalance(m_pCamera->getWhitebalanceU(),
            m_pCamera->getWhitebalanceV());
    m_pCamera->setFeatureOneShot(CAM_FEATURE_WHITE_BALANCE);
}

int CameraNode::getStrobeDuration() const
{
    return getFeature(CAM_FEATURE_STROBE_DURATION);
}

void CameraNode::setStrobeDuration(int Value)
{
    setFeature(CAM_FEATURE_STROBE_DURATION, Value);
}

IntPoint CameraNode::getMediaSize()
{
    return m_pCamera->getImgSize();
}

void CameraNode::dumpCameras()
{
    avg::dumpCameras();
}

void CameraNode::resetFirewireBus()
{
    FWCamera::resetBus();
}

double CameraNode::getFPS() const
{
    return m_pCamera->getFrameRate();
}

void CameraNode::open()
{
    setViewport(-32767, -32767, -32767, -32767);
    PixelFormat pf = getPixelFormat();
    getSurface()->create(getMediaSize(), pf);

    if (pf == B8G8R8X8 || pf == B8G8R8A8) {
        FilterFill<Pixel32> Filter(Pixel32(0,0,0,255));
        Filter.applyInPlace(getSurface()->lockBmp());
        getSurface()->unlockBmps();
    }
}

int CameraNode::getFeature(CameraFeature Feature) const
{
    return m_pCamera->getFeature(Feature);
}

void CameraNode::setFeature(CameraFeature Feature, int Value)
{
    m_pCamera->setFeature(Feature, Value);
}

int CameraNode::getFrameNum() const
{
    return m_FrameNum;
}

static ProfilingZone CameraFetchImage("Camera fetch image");

void CameraNode::preRender()
{
    VisibleNode::preRender();
    ScopeTimer Timer(CameraFetchImage);
    if (isAutoUpdateCameraImage()) {
        updateToLatestCameraImage();
    }
}

static ProfilingZone CameraProfilingZone("Camera::render");
static ProfilingZone CameraDownloadProfilingZone("Camera tex download");

void CameraNode::render(const DRect& Rect)
{
    if (m_bIsPlaying) {
        ScopeTimer Timer(CameraProfilingZone);
        if (m_pCurBmp) {
            m_FrameNum++;
            BitmapPtr pBmp = getSurface()->lockBmp();
            if (pBmp->getPixelFormat() != m_pCurBmp->getPixelFormat()) {
                cerr << "Surface: " << pBmp->getPixelFormatString() << ", CamDest: "
                    << m_pCurBmp->getPixelFormatString() << endl;
            }
            AVG_ASSERT(pBmp->getPixelFormat() == m_pCurBmp->getPixelFormat());
            pBmp->copyPixels(*m_pCurBmp);
            getSurface()->unlockBmps();
            {
                ScopeTimer Timer(CameraDownloadProfilingZone);
                bind();
            }
        }
        blt32(getSize(), getEffectiveOpacity(), getBlendMode());
    }
}

PixelFormat CameraNode::getPixelFormat()
{
    return m_pCamera->getDestPF();
}

void CameraNode::updateToLatestCameraImage()
{
    m_pCurBmp = m_pCamera->getImage(false);
    if (m_pCurBmp) {
       BitmapPtr pTempBmp;
       while (pTempBmp = m_pCamera->getImage(false)) {
           m_pCurBmp = pTempBmp;
       }
    }
}

void CameraNode::updateCameraImage()
{
    if (!isAutoUpdateCameraImage()) {
        m_pTmpBmp = m_pCamera->getImage(false);
        if (m_pTmpBmp) {
            m_pCurBmp = m_pTmpBmp;
        }
    }
}

bool CameraNode::isAutoUpdateCameraImage() const
{
    return m_bIsAutoUpdateCameraImage;
}

void CameraNode::setAutoUpdateCameraImage(bool bVal)
{
    m_bIsAutoUpdateCameraImage = bVal;
}

bool CameraNode::isImageAvailable() const
{
    return m_pTmpBmp.get() != NULL;
}

} // namespace avg
<commit_msg>Workaround for what appears to be an NVidia driver bug: glClear(STENCIL) on an fbo doesn't work. glClear(STENCIL|DEPTH) works.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "CameraNode.h"
#include "DisplayEngine.h"
#include "OGLSurface.h"
#include "NodeDefinition.h"

#include "../base/TimeSource.h"
#include "../base/Logger.h"
#include "../base/Exception.h"
#include "../base/ScopeTimer.h"
#include "../base/XMLHelper.h"

#include "../graphics/Filterfill.h"

#include "../imaging/Camera.h"
#include "../imaging/FWCamera.h"
#include "../imaging/FakeCamera.h"

#include <iostream>
#include <sstream>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

using namespace std;

namespace avg {

NodeDefinition CameraNode::createDefinition()
{
    return NodeDefinition("camera", VisibleNode::buildNode<CameraNode>)
        .extendDefinition(RasterNode::createDefinition())
        .addArg(Arg<string>("driver", "firewire"))
        .addArg(Arg<string>("device", ""))
        .addArg(Arg<int>("unit", -1))
        .addArg(Arg<bool>("fw800", false))
        .addArg(Arg<double>("framerate", 15))
        .addArg(Arg<int>("capturewidth", 640))
        .addArg(Arg<int>("captureheight", 480))
        .addArg(Arg<string>("pixelformat", "RGB"))
        .addArg(Arg<int>("brightness", -1))
        .addArg(Arg<int>("exposure", -1))
        .addArg(Arg<int>("sharpness", -1))
        .addArg(Arg<int>("saturation", -1))
        .addArg(Arg<int>("gamma", -1))
        .addArg(Arg<int>("shutter", -1))
        .addArg(Arg<int>("gain", -1))
        .addArg(Arg<int>("strobeduration", -1));
}

CameraNode::CameraNode(const ArgList& Args)
    : m_bIsPlaying(false),
      m_FrameNum(0),
      m_bIsAutoUpdateCameraImage(true)
{
    Args.setMembers(this);
    string sDriver = Args.getArgVal<string>("driver");
    string sDevice = Args.getArgVal<string>("device");
    int unit = Args.getArgVal<int>("unit");
    bool bFW800 = Args.getArgVal<bool>("fw800");
    double FrameRate = Args.getArgVal<double>("framerate");
    int Width = Args.getArgVal<int>("capturewidth");
    int Height = Args.getArgVal<int>("captureheight");
    string sPF = Args.getArgVal<string>("pixelformat");

    PixelFormat camPF = Bitmap::stringToPixelFormat(sPF);
    if (camPF == NO_PIXELFORMAT) {
        throw Exception(AVG_ERR_INVALID_ARGS,
                "Unknown camera pixel format "+sPF+".");
    }
    PixelFormat destPF;
    if (Bitmap::pixelFormatIsColored(camPF)) {
        destPF = B8G8R8X8;
    } else {
        destPF = I8;
    }
//    cerr << "CameraNode ctor: " << Bitmap::getPixelFormatString(camPF) << "-->" <<
//            Bitmap::getPixelFormatString(destPF) << endl;

    m_pCamera = createCamera(sDriver, sDevice, unit, bFW800, IntPoint(Width, Height), camPF,
            destPF, FrameRate);
    AVG_TRACE(Logger::CONFIG, "Got Camera " << m_pCamera->getDevice() << " from driver: "
            << m_pCamera->getDriverName());

    m_pCamera->setFeature(CAM_FEATURE_BRIGHTNESS,
            Args.getArgVal<int>("brightness"));
    m_pCamera->setFeature(CAM_FEATURE_EXPOSURE,
            Args.getArgVal<int>("exposure"));
    m_pCamera->setFeature(CAM_FEATURE_SHARPNESS,
            Args.getArgVal<int>("sharpness"));
    m_pCamera->setFeature(CAM_FEATURE_SATURATION,
            Args.getArgVal<int>("saturation"));
    m_pCamera->setFeature(CAM_FEATURE_GAMMA,
            Args.getArgVal<int>("gamma"));
    m_pCamera->setFeature(CAM_FEATURE_SHUTTER,
            Args.getArgVal<int>("shutter"));
    m_pCamera->setFeature(CAM_FEATURE_GAIN,
            Args.getArgVal<int>("gain"));
    m_pCamera->setFeature(CAM_FEATURE_STROBE_DURATION,
            Args.getArgVal<int>("strobeduration"));
}

CameraNode::~CameraNode()
{
    m_pCamera = CameraPtr();
}

void CameraNode::setRenderingEngines(DisplayEngine * pDisplayEngine,
        AudioEngine * pAudioEngine)
{
    RasterNode::setRenderingEngines(pDisplayEngine, pAudioEngine);
    if (m_bIsPlaying) {
        open();
    }
}

void CameraNode::play()
{
    if (getState() == NS_CANRENDER) {
        open();
    }
    m_bIsPlaying = true;
}

void CameraNode::stop()
{
    m_bIsPlaying = false;
}

bool CameraNode::isAvailable()
{
    if (!m_pCamera || boost::dynamic_pointer_cast<FakeCamera>(m_pCamera)) {
        return false;
    } else {
        return true;
    }
}

int CameraNode::getBrightness() const
{
    return getFeature(CAM_FEATURE_BRIGHTNESS);
}

void CameraNode::setBrightness(int Value)
{
    setFeature(CAM_FEATURE_BRIGHTNESS, Value);
}

int CameraNode::getSharpness() const
{
    return getFeature(CAM_FEATURE_SHARPNESS);
}

void CameraNode::setSharpness(int Value)
{
    setFeature(CAM_FEATURE_SHARPNESS, Value);
}

int CameraNode::getSaturation() const
{
    return getFeature(CAM_FEATURE_SATURATION);
}

void CameraNode::setSaturation(int Value)
{
    setFeature(CAM_FEATURE_SATURATION, Value);
}

int CameraNode::getGamma() const
{
    return getFeature(CAM_FEATURE_GAMMA);
}

void CameraNode::setGamma(int Value)
{
    setFeature(CAM_FEATURE_GAMMA, Value);
}

int CameraNode::getShutter() const
{
    return getFeature(CAM_FEATURE_SHUTTER);
}

void CameraNode::setShutter(int Value)
{
    setFeature(CAM_FEATURE_SHUTTER, Value);
}

int CameraNode::getGain() const
{
    return getFeature(CAM_FEATURE_GAIN);
}

void CameraNode::setGain(int Value)
{
    setFeature(CAM_FEATURE_GAIN, Value);
}

int CameraNode::getWhitebalanceU() const
{
    return m_pCamera->getWhitebalanceU();
}

int CameraNode::getWhitebalanceV() const
{
    return m_pCamera->getWhitebalanceV();
}

void CameraNode::setWhitebalance(int u, int v)
{
    m_pCamera->setWhitebalance(u, v);
}

void CameraNode::doOneShotWhitebalance()
{
    // The first line turns off auto white balance.
    m_pCamera->setWhitebalance(m_pCamera->getWhitebalanceU(),
            m_pCamera->getWhitebalanceV());
    m_pCamera->setFeatureOneShot(CAM_FEATURE_WHITE_BALANCE);
}

int CameraNode::getStrobeDuration() const
{
    return getFeature(CAM_FEATURE_STROBE_DURATION);
}

void CameraNode::setStrobeDuration(int Value)
{
    setFeature(CAM_FEATURE_STROBE_DURATION, Value);
}

IntPoint CameraNode::getMediaSize()
{
    return m_pCamera->getImgSize();
}

void CameraNode::dumpCameras()
{
    avg::dumpCameras();
}

void CameraNode::resetFirewireBus()
{
    FWCamera::resetBus();
}

double CameraNode::getFPS() const
{
    return m_pCamera->getFrameRate();
}

void CameraNode::open()
{
    setViewport(-32767, -32767, -32767, -32767);
    PixelFormat pf = getPixelFormat();
    getSurface()->create(getMediaSize(), pf);

    if (pf == B8G8R8X8 || pf == B8G8R8A8) {
        FilterFill<Pixel32> Filter(Pixel32(0,0,0,255));
        Filter.applyInPlace(getSurface()->lockBmp());
        getSurface()->unlockBmps();
    }
}

int CameraNode::getFeature(CameraFeature Feature) const
{
    return m_pCamera->getFeature(Feature);
}

void CameraNode::setFeature(CameraFeature Feature, int Value)
{
    m_pCamera->setFeature(Feature, Value);
}

int CameraNode::getFrameNum() const
{
    return m_FrameNum;
}

static ProfilingZone CameraFetchImage("Camera fetch image");

void CameraNode::preRender()
{
    VisibleNode::preRender();
    ScopeTimer Timer(CameraFetchImage);
    if (isAutoUpdateCameraImage()) {
        updateToLatestCameraImage();
    }
}

static ProfilingZone CameraProfilingZone("Camera::render");
static ProfilingZone CameraDownloadProfilingZone("Camera tex download");

void CameraNode::render(const DRect& Rect)
{
    if (m_bIsPlaying) {
        ScopeTimer Timer(CameraProfilingZone);
        if (m_pCurBmp) {
            m_FrameNum++;
            BitmapPtr pBmp = getSurface()->lockBmp();
            if (pBmp->getPixelFormat() != m_pCurBmp->getPixelFormat()) {
                cerr << "Surface: " << pBmp->getPixelFormatString() << ", CamDest: "
                    << m_pCurBmp->getPixelFormatString() << endl;
            }
            AVG_ASSERT(pBmp->getPixelFormat() == m_pCurBmp->getPixelFormat());
            pBmp->copyPixels(*m_pCurBmp);
            getSurface()->unlockBmps();
            {
                ScopeTimer Timer(CameraDownloadProfilingZone);
                bind();
            }
        }
        blt32(getSize(), getEffectiveOpacity(), getBlendMode());
    }
}

PixelFormat CameraNode::getPixelFormat()
{
    return m_pCamera->getDestPF();
}

void CameraNode::updateToLatestCameraImage()
{
    m_pCurBmp = m_pCamera->getImage(false);
    if (m_pCurBmp) {
       BitmapPtr pTempBmp;
       while (pTempBmp = m_pCamera->getImage(false)) {
           m_pCurBmp = pTempBmp;
       }
    }
}

void CameraNode::updateCameraImage()
{
    if (!isAutoUpdateCameraImage()) {
        m_pCurBmp = m_pCamera->getImage(false);
        blt32(getSize(), getEffectiveOpacity(), getBlendMode());
    }
}

bool CameraNode::isAutoUpdateCameraImage() const
{
    return m_bIsAutoUpdateCameraImage;
}

void CameraNode::setAutoUpdateCameraImage(bool bVal)
{
    m_bIsAutoUpdateCameraImage = bVal;
}

bool CameraNode::isImageAvailable() const
{
    return m_pCurBmp.get() != NULL;
}

} // namespace avg
<|endoftext|>