<commit_before>//
//  Created by everettjf
//  Copyright © 2017 everettjf. All rights reserved.
//
#include "tablecontentview.h"
#include "../../utility/utility.h"
#include <QHBoxLayout>
#include <QDebug>

TableContentView::TableContentView(QWidget *parent) : ContentViewInterface(parent)
{
    controller = nullptr;
    tableView = new QTableView(this);

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setMargin(0);

    layout->addWidget(tableView);
    setLayout(layout);

}

void TableContentView::showViewData(moex::ViewData *data)
{
    moex::TableViewData *node = static_cast<moex::TableViewData*>(data);

    if(controller) delete controller;
    controller = new TableContentController();

    qDebug()<<data;
    qDebug()<<node;
    qDebug()<<controller;

    controller->InitModel(node);

    qDebug()<<"after";

    tableView->setModel(controller->model());
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);

    for(uint32_t idx = 0; idx < node->widths.size(); ++idx){
        tableView->setColumnWidth(idx,node->widths.at(idx));
    }
}
<commit_msg>row height<commit_after>//
//  Created by everettjf
//  Copyright © 2017 everettjf. All rights reserved.
//
#include "tablecontentview.h"
#include "../../utility/utility.h"
#include <QHBoxLayout>
#include <QDebug>
#include <QHeaderView>

TableContentView::TableContentView(QWidget *parent) : ContentViewInterface(parent)
{
    controller = nullptr;
    tableView = new QTableView(this);

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setMargin(0);

    layout->addWidget(tableView);
    setLayout(layout);

    QHeaderView *verticalHeader = tableView->verticalHeader();
    verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
    verticalHeader->setDefaultSectionSize(24);
}

void TableContentView::showViewData(moex::ViewData *data)
{
    moex::TableViewData *node = static_cast<moex::TableViewData*>(data);

    if(controller) delete controller;
    controller = new TableContentController();

    qDebug()<<data;
    qDebug()<<node;
    qDebug()<<controller;

    controller->InitModel(node);

    qDebug()<<"after";

    tableView->setModel(controller->model());
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);

    for(uint32_t idx = 0; idx < node->widths.size(); ++idx){
        tableView->setColumnWidth(idx,node->widths.at(idx));
    }
}
<|endoftext|>


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

  Library:   CTK

  Copyright (c) Kitware Inc.

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

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

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

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

// Qt includes
#include <QSqlQuery>
#include <QSqlRecord>
#include <QVariant>
#include <QDate>
#include <QStringList>
#include <QSet>
#include <QFile>
#include <QDirIterator>
#include <QFileInfo>
#include <QDebug>

// ctkDICOMCore includes
#include "ctkDICOMQuery.h"
#include "ctkLogger.h"

// DCMTK includes
#ifndef WIN32
  #define HAVE_CONFIG_H
#endif
#include "dcmtk/dcmnet/dimse.h"
#include "dcmtk/dcmnet/diutil.h"

#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcdeftag.h>
#include <dcmtk/dcmdata/dcdatset.h>
#include <dcmtk/ofstd/ofcond.h>
#include <dcmtk/ofstd/ofstring.h>
#include <dcmtk/ofstd/ofstd.h>        /* for class OFStandard */
#include <dcmtk/dcmdata/dcddirif.h>   /* for class DicomDirInterface */

#include <dcmtk/dcmnet/scu.h>

static ctkLogger logger ( "org.commontk.dicom.DICOMQuery" );

//------------------------------------------------------------------------------
class ctkDICOMQueryPrivate
{
public:
  ctkDICOMQueryPrivate();
  ~ctkDICOMQueryPrivate();

  /// Add a StudyInstanceUID to be queried
  void addStudyInstanceUID(const QString& StudyInstanceUID );

  QString                 CallingAETitle;
  QString                 CalledAETitle;
  QString                 Host;
  int                     Port;
  QMap<QString,QVariant>  Filters;
  DcmSCU                  SCU;
  DcmDataset*             Query;
  QStringList             StudyInstanceUIDList;
};

//------------------------------------------------------------------------------
// ctkDICOMQueryPrivate methods

//------------------------------------------------------------------------------
ctkDICOMQueryPrivate::ctkDICOMQueryPrivate()
{
  this->Query = new DcmDataset();
  this->Port = 0;
}

//------------------------------------------------------------------------------
ctkDICOMQueryPrivate::~ctkDICOMQueryPrivate()
{
  delete this->Query;
}

//------------------------------------------------------------------------------
void ctkDICOMQueryPrivate::addStudyInstanceUID( const QString& s )
{
  this->StudyInstanceUIDList.append ( s );
}

//------------------------------------------------------------------------------
// ctkDICOMQuery methods

//------------------------------------------------------------------------------
ctkDICOMQuery::ctkDICOMQuery(QObject* parentObject)
  : QObject(parentObject)
  , d_ptr(new ctkDICOMQueryPrivate)
{
}

//------------------------------------------------------------------------------
ctkDICOMQuery::~ctkDICOMQuery()
{
}

/// Set methods for connectivity
//------------------------------------------------------------------------------
void ctkDICOMQuery::setCallingAETitle( const QString& callingAETitle )
{
  Q_D(ctkDICOMQuery);
  d->CallingAETitle = callingAETitle;
}

//------------------------------------------------------------------------------
QString ctkDICOMQuery::callingAETitle() const
{
  Q_D(const ctkDICOMQuery);
  return d->CallingAETitle;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setCalledAETitle( const QString& calledAETitle )
{
  Q_D(ctkDICOMQuery);
  d->CalledAETitle = calledAETitle;
}

//------------------------------------------------------------------------------
QString ctkDICOMQuery::calledAETitle()const
{
  Q_D(const ctkDICOMQuery);
  return d->CalledAETitle;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setHost( const QString& host )
{
  Q_D(ctkDICOMQuery);
  d->Host = host;
}

//------------------------------------------------------------------------------
QString ctkDICOMQuery::host() const
{
  Q_D(const ctkDICOMQuery);
  return d->Host;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setPort ( int port )
{
  Q_D(ctkDICOMQuery);
  d->Port = port;
}

//------------------------------------------------------------------------------
int ctkDICOMQuery::port()const
{
  Q_D(const ctkDICOMQuery);
  return d->Port;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setFilters( const QMap<QString,QVariant>& filters )
{
  Q_D(ctkDICOMQuery);
  d->Filters = filters;
}

//------------------------------------------------------------------------------
QMap<QString,QVariant> ctkDICOMQuery::filters()const
{
  Q_D(const ctkDICOMQuery);
  return d->Filters;
}

//------------------------------------------------------------------------------
QStringList ctkDICOMQuery::studyInstanceUIDQueried()const
{
  Q_D(const ctkDICOMQuery);
  return d->StudyInstanceUIDList;
}

//------------------------------------------------------------------------------
bool ctkDICOMQuery::query(ctkDICOMDatabase& database )
{
  // ctkDICOMDatabase::setDatabase ( database );
  Q_D(ctkDICOMQuery);
  // In the following, we emit progress(int) after progress(QString), this
  // is in case the connected object doesn't refresh its ui when the progress
  // message is updated but only if the progress value is (e.g. QProgressDialog)
  if ( database.database().isOpen() )
    {
    logger.debug ( "DB open in Query" );
    emit progress("DB open in Query");
    }
  else
    {
    logger.debug ( "DB not open in Query" );
    emit progress("DB not open in Query");
    }
  emit progress(0);

  d->StudyInstanceUIDList.clear();
  d->SCU.setAETitle ( OFString(this->callingAETitle().toStdString().c_str()) );
  d->SCU.setPeerAETitle ( OFString(this->calledAETitle().toStdString().c_str()) );
  d->SCU.setPeerHostName ( OFString(this->host().toStdString().c_str()) );
  d->SCU.setPeerPort ( this->port() );

  logger.error ( "Setting Transfer Syntaxes" );
  emit progress("Setting Transfer Syntaxes");
  emit progress(10);

  OFList<OFString> transferSyntaxes;
  transferSyntaxes.push_back ( UID_LittleEndianExplicitTransferSyntax );
  transferSyntaxes.push_back ( UID_BigEndianExplicitTransferSyntax );
  transferSyntaxes.push_back ( UID_LittleEndianImplicitTransferSyntax );

  d->SCU.addPresentationContext ( UID_FINDStudyRootQueryRetrieveInformationModel, transferSyntaxes );
  // d->SCU.addPresentationContext ( UID_VerificationSOPClass, transferSyntaxes );
  if ( !d->SCU.initNetwork().good() )
    {
    logger.error( "Error initializing the network" );
    emit progress("Error initializing the network");
    emit progress(100);
    return false;
    }
  logger.debug ( "Negotiating Association" );
  emit progress("Negatiating Association");
  emit progress(20);

  OFCondition result = d->SCU.negotiateAssociation();
  if (result.bad())
    {
    logger.error( "Error negotiating the association: " + QString(result.text()) );
    emit progress("Error negotiating the association");
    emit progress(100);
    return false;
    }

  // Clear the query
  d->Query->clear();

  // Insert all keys that we like to receive values for
  d->Query->insertEmptyElement ( DCM_PatientID );
  d->Query->insertEmptyElement ( DCM_PatientName );
  d->Query->insertEmptyElement ( DCM_PatientBirthDate );
  d->Query->insertEmptyElement ( DCM_StudyID );
  d->Query->insertEmptyElement ( DCM_StudyInstanceUID );
  d->Query->insertEmptyElement ( DCM_StudyDescription );
  d->Query->insertEmptyElement ( DCM_StudyDate );
  d->Query->insertEmptyElement ( DCM_StudyTime );
  d->Query->insertEmptyElement ( DCM_ModalitiesInStudy );
  d->Query->insertEmptyElement ( DCM_AccessionNumber );
  d->Query->insertEmptyElement ( DCM_NumberOfSeriesRelatedInstances ); // Number of images in the series
  d->Query->insertEmptyElement ( DCM_NumberOfStudyRelatedInstances ); // Number of images in the series
  d->Query->insertEmptyElement ( DCM_NumberOfStudyRelatedSeries ); // Number of images in the series

  // Make clear we define our search values in ISO Latin 1 (default would be ASCII)
  d->Query->putAndInsertOFStringArray(DCM_SpecificCharacterSet, "ISO_IR 100");

  d->Query->putAndInsertString ( DCM_QueryRetrieveLevel, "STUDY" );

  /* Now, for all keys that the user provided for filtering on STUDY level,
   * overwrite empty keys with value. For now, only Patient's Name, Patient ID,
   * Study Description, Modalities in Study, and Study Date are used.
   */
  QString seriesDescription;
  foreach( QString key, d->Filters.keys() )
    {
    if ( key == QString("Name") )
      {
      // make the filter a wildcard in dicom style
      d->Query->putAndInsertString( DCM_PatientName,
        (QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
      }
    else if ( key == QString("Study") )
      {
      // make the filter a wildcard in dicom style
      d->Query->putAndInsertString( DCM_StudyDescription,
        (QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
      }
    else if ( key == QString("ID") )
      {
      // make the filter a wildcard in dicom style
      d->Query->putAndInsertString( DCM_PatientID,
        (QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
      }
    else if ( key == QString("Modalities") )
      {
      // make the filter be an "OR" of modalities using backslash (dicom-style)
      QString modalitySearch("");
      foreach (const QString& modality, d->Filters[key].toStringList())
      {
        modalitySearch += modality + QString("\\");
      }
      modalitySearch.chop(1); // remove final backslash
      logger.debug("modalityInStudySearch " + modalitySearch);
      d->Query->putAndInsertString( DCM_ModalitiesInStudy, modalitySearch.toAscii().data() );
      }
    // Rememer Series Description for later series query if we go through the keys now
    else if ( key == QString("Series") )
      {
      // make the filter a wildcard in dicom style
      seriesDescription = "*" + d->Filters[key].toString() + "*";
      }
    else
      {
      logger.debug("Ignoring unknown search key: " + key);
      }
    }

  if ( d->Filters.keys().contains("StartDate") && d->Filters.keys().contains("EndDate") )
    {
    QString dateRange = d->Filters["StartDate"].toString() +
                        QString("-") +
                        d->Filters["EndDate"].toString();
    d->Query->putAndInsertString ( DCM_StudyDate, dateRange.toAscii().data() );
    logger.debug("Query on study date " + dateRange);
    }
  emit progress(30);

  FINDResponses *responses = new FINDResponses();

  Uint16 presentationContext = 0;
  // Check for any accepted presentation context for FIND in study root (dont care about transfer syntax)
  presentationContext = d->SCU.findPresentationContextID ( UID_FINDStudyRootQueryRetrieveInformationModel, "");
  if ( presentationContext == 0 )
    {
    logger.error ( "Failed to find acceptable presentation context" );
    emit progress("Failed to find acceptable presentation context");
    }
  else
    {
    logger.info ( "Found useful presentation context" );
    emit progress("Found useful presentation context");
    }
  emit progress(40);

  OFCondition status = d->SCU.sendFINDRequest ( presentationContext, d->Query, responses );
  if ( !status.good() )
    {
    logger.error ( "Find failed" );
    emit progress("Find failed");
    d->SCU.closeAssociation ( DCMSCU_RELEASE_ASSOCIATION );
    emit progress(100);
    delete responses;
    return false;
    }
  logger.debug ( "Find succeded");
  emit progress("Find succeded");
  emit progress(50);

  for ( OFListIterator(FINDResponse*) it = responses->begin(); it != responses->end(); it++ )
    {
    DcmDataset *dataset = (*it)->m_dataset;
    if ( dataset != NULL ) // the last response is always empty
      {
      database.insert ( dataset, false /* do not store to disk*/, false /* no thumbnail*/);
      OFString StudyInstanceUID;
      dataset->findAndGetOFString ( DCM_StudyInstanceUID, StudyInstanceUID );
      d->addStudyInstanceUID ( StudyInstanceUID.c_str() );
      }
    }
  delete responses;

  /* Only ask for series attributes now. This requires kicking out the rest of former query. */
  d->Query->clear();
  d->Query->insertEmptyElement ( DCM_SeriesNumber );
  d->Query->insertEmptyElement ( DCM_SeriesDescription );
  d->Query->insertEmptyElement ( DCM_SeriesInstanceUID );
  d->Query->insertEmptyElement ( DCM_SeriesDate );
  d->Query->insertEmptyElement ( DCM_SeriesTime );
  d->Query->insertEmptyElement ( DCM_Modality );

  /* Add user-defined filters */
  d->Query->putAndInsertOFStringArray(DCM_SeriesDescription, seriesDescription.toLatin1().data());

  // Now search each within each Study that was identified
  d->Query->putAndInsertString ( DCM_QueryRetrieveLevel, "SERIES" );
  float progressRatio = 25. / d->StudyInstanceUIDList.count();
  int i = 0;
  foreach ( QString StudyInstanceUID, d->StudyInstanceUIDList )
    {
    logger.debug ( "Starting Series C-FIND for Study: " + StudyInstanceUID );
    emit progress(QString("Starting Series C-FIND for Study: ") + StudyInstanceUID);
    emit progress(50 + (progressRatio * i++));

    d->Query->putAndInsertString ( DCM_StudyInstanceUID, StudyInstanceUID.toStdString().c_str() );
    responses = new FINDResponses();
    status = d->SCU.sendFINDRequest ( presentationContext, d->Query, responses );
    if ( status.good() )
      {
      for ( OFListIterator(FINDResponse*) it = responses->begin(); it != responses->end(); it++ )
        {
        DcmDataset *dataset = (*it)->m_dataset;
        if ( dataset != NULL )
          {
          database.insert ( dataset, false /* do not store */, false /* no thumbnail */ );
          }
        }
      logger.debug ( "Find succeded on Series level for Study: " + StudyInstanceUID );
      emit progress(QString("Find succeded on Series level for Study: ") + StudyInstanceUID);
      }
    else
      {
      logger.error ( "Find on Series level failed for Study: " + StudyInstanceUID );
      emit progress(QString("Find on Series level failed for Study: ") + StudyInstanceUID);
      }
    emit progress(50 + (progressRatio * i++));
    delete responses;
    }
  d->SCU.closeAssociation ( DCMSCU_RELEASE_ASSOCIATION );
  emit progress(100);
  return true;
}
<commit_msg>Fixed assignments of query attributs from study to series level. Prevented empty search fields to be padded with one or more asterisks (*).<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

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

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

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

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

// Qt includes
#include <QSqlQuery>
#include <QSqlRecord>
#include <QVariant>
#include <QDate>
#include <QStringList>
#include <QSet>
#include <QFile>
#include <QDirIterator>
#include <QFileInfo>
#include <QDebug>

// ctkDICOMCore includes
#include "ctkDICOMQuery.h"
#include "ctkLogger.h"

// DCMTK includes
#ifndef WIN32
  #define HAVE_CONFIG_H
#endif
#include "dcmtk/dcmnet/dimse.h"
#include "dcmtk/dcmnet/diutil.h"

#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcdeftag.h>
#include <dcmtk/dcmdata/dcdatset.h>
#include <dcmtk/ofstd/ofcond.h>
#include <dcmtk/ofstd/ofstring.h>
#include <dcmtk/ofstd/ofstd.h>        /* for class OFStandard */
#include <dcmtk/dcmdata/dcddirif.h>   /* for class DicomDirInterface */

#include <dcmtk/dcmnet/scu.h>

static ctkLogger logger ( "org.commontk.dicom.DICOMQuery" );

//------------------------------------------------------------------------------
class ctkDICOMQueryPrivate
{
public:
  ctkDICOMQueryPrivate();
  ~ctkDICOMQueryPrivate();

  /// Add a StudyInstanceUID to be queried
  void addStudyInstanceUID(const QString& StudyInstanceUID );

  QString                 CallingAETitle;
  QString                 CalledAETitle;
  QString                 Host;
  int                     Port;
  QMap<QString,QVariant>  Filters;
  DcmSCU                  SCU;
  DcmDataset*             Query;
  QStringList             StudyInstanceUIDList;
};

//------------------------------------------------------------------------------
// ctkDICOMQueryPrivate methods

//------------------------------------------------------------------------------
ctkDICOMQueryPrivate::ctkDICOMQueryPrivate()
{
  this->Query = new DcmDataset();
  this->Port = 0;
}

//------------------------------------------------------------------------------
ctkDICOMQueryPrivate::~ctkDICOMQueryPrivate()
{
  delete this->Query;
}

//------------------------------------------------------------------------------
void ctkDICOMQueryPrivate::addStudyInstanceUID( const QString& s )
{
  this->StudyInstanceUIDList.append ( s );
}

//------------------------------------------------------------------------------
// ctkDICOMQuery methods

//------------------------------------------------------------------------------
ctkDICOMQuery::ctkDICOMQuery(QObject* parentObject)
  : QObject(parentObject)
  , d_ptr(new ctkDICOMQueryPrivate)
{
}

//------------------------------------------------------------------------------
ctkDICOMQuery::~ctkDICOMQuery()
{
}

/// Set methods for connectivity
//------------------------------------------------------------------------------
void ctkDICOMQuery::setCallingAETitle( const QString& callingAETitle )
{
  Q_D(ctkDICOMQuery);
  d->CallingAETitle = callingAETitle;
}

//------------------------------------------------------------------------------
QString ctkDICOMQuery::callingAETitle() const
{
  Q_D(const ctkDICOMQuery);
  return d->CallingAETitle;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setCalledAETitle( const QString& calledAETitle )
{
  Q_D(ctkDICOMQuery);
  d->CalledAETitle = calledAETitle;
}

//------------------------------------------------------------------------------
QString ctkDICOMQuery::calledAETitle()const
{
  Q_D(const ctkDICOMQuery);
  return d->CalledAETitle;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setHost( const QString& host )
{
  Q_D(ctkDICOMQuery);
  d->Host = host;
}

//------------------------------------------------------------------------------
QString ctkDICOMQuery::host() const
{
  Q_D(const ctkDICOMQuery);
  return d->Host;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setPort ( int port )
{
  Q_D(ctkDICOMQuery);
  d->Port = port;
}

//------------------------------------------------------------------------------
int ctkDICOMQuery::port()const
{
  Q_D(const ctkDICOMQuery);
  return d->Port;
}

//------------------------------------------------------------------------------
void ctkDICOMQuery::setFilters( const QMap<QString,QVariant>& filters )
{
  Q_D(ctkDICOMQuery);
  d->Filters = filters;
}

//------------------------------------------------------------------------------
QMap<QString,QVariant> ctkDICOMQuery::filters()const
{
  Q_D(const ctkDICOMQuery);
  return d->Filters;
}

//------------------------------------------------------------------------------
QStringList ctkDICOMQuery::studyInstanceUIDQueried()const
{
  Q_D(const ctkDICOMQuery);
  return d->StudyInstanceUIDList;
}

//------------------------------------------------------------------------------
bool ctkDICOMQuery::query(ctkDICOMDatabase& database )
{
  // ctkDICOMDatabase::setDatabase ( database );
  Q_D(ctkDICOMQuery);
  // In the following, we emit progress(int) after progress(QString), this
  // is in case the connected object doesn't refresh its ui when the progress
  // message is updated but only if the progress value is (e.g. QProgressDialog)
  if ( database.database().isOpen() )
    {
    logger.debug ( "DB open in Query" );
    emit progress("DB open in Query");
    }
  else
    {
    logger.debug ( "DB not open in Query" );
    emit progress("DB not open in Query");
    }
  emit progress(0);

  d->StudyInstanceUIDList.clear();
  d->SCU.setAETitle ( OFString(this->callingAETitle().toStdString().c_str()) );
  d->SCU.setPeerAETitle ( OFString(this->calledAETitle().toStdString().c_str()) );
  d->SCU.setPeerHostName ( OFString(this->host().toStdString().c_str()) );
  d->SCU.setPeerPort ( this->port() );

  logger.error ( "Setting Transfer Syntaxes" );
  emit progress("Setting Transfer Syntaxes");
  emit progress(10);

  OFList<OFString> transferSyntaxes;
  transferSyntaxes.push_back ( UID_LittleEndianExplicitTransferSyntax );
  transferSyntaxes.push_back ( UID_BigEndianExplicitTransferSyntax );
  transferSyntaxes.push_back ( UID_LittleEndianImplicitTransferSyntax );

  d->SCU.addPresentationContext ( UID_FINDStudyRootQueryRetrieveInformationModel, transferSyntaxes );
  // d->SCU.addPresentationContext ( UID_VerificationSOPClass, transferSyntaxes );
  if ( !d->SCU.initNetwork().good() )
    {
    logger.error( "Error initializing the network" );
    emit progress("Error initializing the network");
    emit progress(100);
    return false;
    }
  logger.debug ( "Negotiating Association" );
  emit progress("Negatiating Association");
  emit progress(20);

  OFCondition result = d->SCU.negotiateAssociation();
  if (result.bad())
    {
    logger.error( "Error negotiating the association: " + QString(result.text()) );
    emit progress("Error negotiating the association");
    emit progress(100);
    return false;
    }

  // Clear the query
  d->Query->clear();

  // Insert all keys that we like to receive values for
  d->Query->insertEmptyElement ( DCM_PatientID );
  d->Query->insertEmptyElement ( DCM_PatientName );
  d->Query->insertEmptyElement ( DCM_PatientBirthDate );
  d->Query->insertEmptyElement ( DCM_StudyID );
  d->Query->insertEmptyElement ( DCM_StudyInstanceUID );
  d->Query->insertEmptyElement ( DCM_StudyDescription );
  d->Query->insertEmptyElement ( DCM_StudyDate );
  d->Query->insertEmptyElement ( DCM_StudyTime );
  d->Query->insertEmptyElement ( DCM_ModalitiesInStudy );
  d->Query->insertEmptyElement ( DCM_AccessionNumber );
  d->Query->insertEmptyElement ( DCM_NumberOfStudyRelatedInstances ); // Number of images in the series
  d->Query->insertEmptyElement ( DCM_NumberOfStudyRelatedSeries ); // Number of series in the study

  // Make clear we define our search values in ISO Latin 1 (default would be ASCII)
  d->Query->putAndInsertOFStringArray(DCM_SpecificCharacterSet, "ISO_IR 100");

  d->Query->putAndInsertString ( DCM_QueryRetrieveLevel, "STUDY" );

  /* Now, for all keys that the user provided for filtering on STUDY level,
   * overwrite empty keys with value. For now, only Patient's Name, Patient ID,
   * Study Description, Modalities in Study, and Study Date are used.
   */
  QString seriesDescription;
  foreach( QString key, d->Filters.keys() )
    {
    if ( key == QString("Name") && !d->Filters[key].toString().isEmpty())
      {
      // make the filter a wildcard in dicom style
      d->Query->putAndInsertString( DCM_PatientName,
        (QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
      }
    else if ( key == QString("Study") && !d->Filters[key].toString().isEmpty())
      {
      // make the filter a wildcard in dicom style
      d->Query->putAndInsertString( DCM_StudyDescription,
        (QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
      }
    else if ( key == QString("ID") && !d->Filters[key].toString().isEmpty())
      {
      // make the filter a wildcard in dicom style
      d->Query->putAndInsertString( DCM_PatientID,
        (QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
      }
    else if ( key == QString("Modalities") && !d->Filters[key].toString().isEmpty())
      {
      // make the filter be an "OR" of modalities using backslash (dicom-style)
      QString modalitySearch("");
      foreach (const QString& modality, d->Filters[key].toStringList())
      {
        modalitySearch += modality + QString("\\");
      }
      modalitySearch.chop(1); // remove final backslash
      logger.debug("modalityInStudySearch " + modalitySearch);
      d->Query->putAndInsertString( DCM_ModalitiesInStudy, modalitySearch.toAscii().data() );
      }
    // Rememer Series Description for later series query if we go through the keys now
    else if ( key == QString("Series") && !d->Filters[key].toString().isEmpty())
      {
      // make the filter a wildcard in dicom style
      seriesDescription = "*" + d->Filters[key].toString() + "*";
      }
    else
      {
      logger.debug("Ignoring unknown search key: " + key);
      }
    }

  if ( d->Filters.keys().contains("StartDate") && d->Filters.keys().contains("EndDate") )
    {
    QString dateRange = d->Filters["StartDate"].toString() +
                        QString("-") +
                        d->Filters["EndDate"].toString();
    d->Query->putAndInsertString ( DCM_StudyDate, dateRange.toAscii().data() );
    logger.debug("Query on study date " + dateRange);
    }
  emit progress(30);

  FINDResponses *responses = new FINDResponses();

  Uint16 presentationContext = 0;
  // Check for any accepted presentation context for FIND in study root (dont care about transfer syntax)
  presentationContext = d->SCU.findPresentationContextID ( UID_FINDStudyRootQueryRetrieveInformationModel, "");
  if ( presentationContext == 0 )
    {
    logger.error ( "Failed to find acceptable presentation context" );
    emit progress("Failed to find acceptable presentation context");
    }
  else
    {
    logger.info ( "Found useful presentation context" );
    emit progress("Found useful presentation context");
    }
  emit progress(40);

  OFCondition status = d->SCU.sendFINDRequest ( presentationContext, d->Query, responses );
  if ( !status.good() )
    {
    logger.error ( "Find failed" );
    emit progress("Find failed");
    d->SCU.closeAssociation ( DCMSCU_RELEASE_ASSOCIATION );
    emit progress(100);
    delete responses;
    return false;
    }
  logger.debug ( "Find succeded");
  emit progress("Find succeded");
  emit progress(50);

  for ( OFListIterator(FINDResponse*) it = responses->begin(); it != responses->end(); it++ )
    {
    DcmDataset *dataset = (*it)->m_dataset;
    if ( dataset != NULL ) // the last response is always empty
      {
      database.insert ( dataset, false /* do not store to disk*/, false /* no thumbnail*/);
      OFString StudyInstanceUID;
      dataset->findAndGetOFString ( DCM_StudyInstanceUID, StudyInstanceUID );
      d->addStudyInstanceUID ( StudyInstanceUID.c_str() );
      }
    }
  delete responses;

  /* Only ask for series attributes now. This requires kicking out the rest of former query. */
  d->Query->clear();
  d->Query->insertEmptyElement ( DCM_SeriesNumber );
  d->Query->insertEmptyElement ( DCM_SeriesDescription );
  d->Query->insertEmptyElement ( DCM_SeriesInstanceUID );
  d->Query->insertEmptyElement ( DCM_SeriesDate );
  d->Query->insertEmptyElement ( DCM_SeriesTime );
  d->Query->insertEmptyElement ( DCM_Modality );
  d->Query->insertEmptyElement ( DCM_NumberOfSeriesRelatedInstances ); // Number of images in the series

  /* Add user-defined filters */
  d->Query->putAndInsertOFStringArray(DCM_SeriesDescription, seriesDescription.toLatin1().data());

  // Now search each within each Study that was identified
  d->Query->putAndInsertString ( DCM_QueryRetrieveLevel, "SERIES" );
  float progressRatio = 25. / d->StudyInstanceUIDList.count();
  int i = 0;
  foreach ( QString StudyInstanceUID, d->StudyInstanceUIDList )
    {
    logger.debug ( "Starting Series C-FIND for Study: " + StudyInstanceUID );
    emit progress(QString("Starting Series C-FIND for Study: ") + StudyInstanceUID);
    emit progress(50 + (progressRatio * i++));

    d->Query->putAndInsertString ( DCM_StudyInstanceUID, StudyInstanceUID.toStdString().c_str() );
    responses = new FINDResponses();
    status = d->SCU.sendFINDRequest ( presentationContext, d->Query, responses );
    if ( status.good() )
      {
      for ( OFListIterator(FINDResponse*) it = responses->begin(); it != responses->end(); it++ )
        {
        DcmDataset *dataset = (*it)->m_dataset;
        if ( dataset != NULL )
          {
          database.insert ( dataset, false /* do not store */, false /* no thumbnail */ );
          }
        }
      logger.debug ( "Find succeded on Series level for Study: " + StudyInstanceUID );
      emit progress(QString("Find succeded on Series level for Study: ") + StudyInstanceUID);
      }
    else
      {
      logger.error ( "Find on Series level failed for Study: " + StudyInstanceUID );
      emit progress(QString("Find on Series level failed for Study: ") + StudyInstanceUID);
      }
    emit progress(50 + (progressRatio * i++));
    delete responses;
    }
  d->SCU.closeAssociation ( DCMSCU_RELEASE_ASSOCIATION );
  emit progress(100);
  return true;
}
<|endoftext|>


<commit_before>#include "voxel_map.h"

VoxelMap::VoxelMap() : _last_accessed_block(NULL) {
	for (unsigned int i = 0; i < VoxelBuffer::MAX_CHANNELS; ++i) {
		_default_voxel[i] = 0;
	}
}

VoxelMap::~VoxelMap() {

}

int VoxelMap::get_voxel(Vector3i pos, unsigned int c) {
	Vector3i bpos = voxel_to_block(pos);
	VoxelBlock * block = get_block(bpos);
	if (block == NULL) {
		return _default_voxel[c];
	}
	return block->voxels->get_voxel(pos - block_to_voxel(bpos), c);
}

MeshInstance * VoxelBlock::get_mesh_instance(const Node & root) {
	if (mesh_instance_path.is_empty())
		return NULL;
	Node * n = root.get_node(mesh_instance_path);
	if (n == NULL)
		return NULL;
	return n->cast_to<MeshInstance>();
}

VoxelBlock::~VoxelBlock() {

}

// Helper
VoxelBlock * VoxelBlock::create(Vector3i bpos, VoxelBuffer * buffer) {
	VoxelBlock * block = memnew(VoxelBlock);
	block->pos = bpos;
	if (buffer) {
		const int bs = VoxelBlock::SIZE;
		ERR_FAIL_COND_V(buffer->get_size() != Vector3i(bs, bs, bs), NULL);
	}
	else {
		buffer = memnew(VoxelBuffer);
	}
	ERR_FAIL_COND_V(buffer == NULL, NULL);
	block->voxels = Ref<VoxelBuffer>(buffer);
	//block->map = ↦
	return block;
}

void VoxelMap::set_voxel(int value, Vector3i pos, unsigned int c) {
	Vector3i bpos = voxel_to_block(pos);
	VoxelBlock * block = get_block(bpos);
	if (block == NULL) {
		block = VoxelBlock::create(bpos);
		set_block(bpos, block);
	}
	block->voxels->set_voxel(value, pos - block_to_voxel(bpos), c);
}

void VoxelMap::set_default_voxel(int value, unsigned int channel) {
	ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
	_default_voxel[channel] = value;
}

int VoxelMap::get_default_voxel(unsigned int channel) {
	ERR_FAIL_INDEX_V(channel, VoxelBuffer::MAX_CHANNELS, 0);
	return _default_voxel[channel];
}

VoxelBlock * VoxelMap::get_block(Vector3i bpos) {
	if (_last_accessed_block && _last_accessed_block->pos == bpos) {
		return _last_accessed_block;
	}
	Ref<VoxelBlock> * p = _blocks.getptr(bpos);
	if (p) {
		_last_accessed_block = p->ptr();
		return _last_accessed_block;
	}
	return NULL;
}

void VoxelMap::set_block(Vector3i bpos, VoxelBlock * block) {
	if (_last_accessed_block == NULL || _last_accessed_block->pos == bpos) {
		_last_accessed_block = block;
	}
	_blocks.set(bpos, block);
}

void VoxelMap::set_block_buffer(Vector3i bpos, Ref<VoxelBuffer> buffer) {
	ERR_FAIL_COND(buffer.is_null());
	VoxelBlock * block = get_block(bpos);
	if (block == NULL) {
		block = VoxelBlock::create(bpos, *buffer);
		set_block(bpos, block);
	}
	else {
		block->voxels = buffer;
	}
}

bool VoxelMap::has_block(Vector3i pos) const {
	return /*(_last_accessed_block != NULL && _last_accessed_block->pos == pos) ||*/ _blocks.has(pos);
}

Vector3i g_moore_neighboring_3d[26] = {
	Vector3i(-1,-1,-1),
	Vector3i(0,-1,-1),
	Vector3i(1,-1,-1),
	Vector3i(-1,-1,0),
	Vector3i(0,-1,0),
	Vector3i(1,-1,0),
	Vector3i(-1,-1,1),
	Vector3i(0,-1,1),
	Vector3i(1,-1,1),

	Vector3i(-1,0,-1),
	Vector3i(0,0,-1),
	Vector3i(1,0,-1),
	Vector3i(-1,0,0),
	//Vector3i(0,0,0),
	Vector3i(1,0,0),
	Vector3i(-1,0,1),
	Vector3i(0,0,1),
	Vector3i(1,0,1),

	Vector3i(-1,1,-1),
	Vector3i(0,1,-1),
	Vector3i(1,1,-1),
	Vector3i(-1,1,0),
	Vector3i(0,1,0),
	Vector3i(1,1,0),
	Vector3i(-1,1,1),
	Vector3i(0,1,1),
	Vector3i(1,1,1),
};

bool VoxelMap::is_block_surrounded(Vector3i pos) const {
	for (unsigned int i = 0; i < 26; ++i) {
		Vector3i bpos = pos + g_moore_neighboring_3d[i];
		if (!has_block(bpos)) {
			return false;
		}
	}
	return true;
}

void VoxelMap::get_buffer_copy(Vector3i min_pos, VoxelBuffer & dst_buffer, unsigned int channel) {
	ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);

	Vector3i max_pos = min_pos + dst_buffer.get_size();

	Vector3i min_block_pos = voxel_to_block(min_pos);
	Vector3i max_block_pos = voxel_to_block(max_pos - Vector3i(1,1,1)) + Vector3i(1,1,1);
	ERR_FAIL_COND((max_block_pos - min_block_pos) != Vector3(3, 3, 3));

	Vector3i bpos;
	for (bpos.z = min_block_pos.z; bpos.z < max_block_pos.z; ++bpos.z) {
		for (bpos.x = min_block_pos.x; bpos.x < max_block_pos.x; ++bpos.x) {
			for (bpos.y = min_block_pos.y; bpos.y < max_block_pos.y; ++bpos.y) {

				VoxelBlock * block = get_block(bpos);
				if (block) {

					VoxelBuffer & src_buffer = **block->voxels;
					Vector3i offset = block_to_voxel(bpos);
					// Note: copy_from takes care of clamping the area if it's on an edge
					dst_buffer.copy_from(src_buffer, min_pos - offset, max_pos - offset, offset - min_pos, channel);
				}
				else {
					Vector3i offset = block_to_voxel(bpos);
					dst_buffer.fill_area(
						_default_voxel[channel],
						offset - min_pos,
						offset - min_pos + Vector3i(VoxelBlock::SIZE,VoxelBlock::SIZE, VoxelBlock::SIZE)
					);
				}

			}
		}
	}
}

void VoxelMap::remove_blocks_not_in_area(Vector3i min, Vector3i max) {

	Vector3i::sort_min_max(min, max);

	Vector<Vector3i> to_remove;
	Vector3i * key = NULL;

	while (_blocks.next(key)) {

		Ref<VoxelBlock> & block_ref = _blocks.get(*key);
		ERR_FAIL_COND(block_ref.is_null()); // Should never trigger
		VoxelBlock & block = **block_ref;

		if (!block.pos.is_contained_in(min, max)) {

			//if (_observer)
			//    _observer->block_removed(block);

			to_remove.push_back(*key);

			if (&block == _last_accessed_block)
				_last_accessed_block = NULL;
		}
	}

	for (unsigned int i = 0; i < to_remove.size(); ++i) {
		_blocks.erase(to_remove[i]);
	}
}

MeshInstance *VoxelMap::_get_block_mesh_instance_binding(Vector3 bpos, Node * root) {
	VoxelBlock* block = get_block(Vector3i(bpos));
	ERR_FAIL_COND_V(!block, NULL);

	return block->get_mesh_instance(*root);
}

void VoxelMap::_set_block_mesh_instance_binding(Vector3 bpos, Node * node) {
	ERR_FAIL_NULL(node);
	MeshInstance * mesh_instance = node->cast_to<MeshInstance>();
	VoxelBlock* block = get_block(Vector3i(bpos));

    if (block == NULL) {
        block = VoxelBlock::create(Vector3i(bpos));
        set_block(bpos, block);
    }

	block->mesh_instance_path = mesh_instance->get_path();
}

Ref<NavigationMesh> VoxelMap::_create_navigation_mesh_binding(Ref<Mesh> mesh) {
	ERR_FAIL_COND_V(mesh.is_null(), Ref<NavigationMesh>());

	Ref<NavigationMesh> navigation_mesh = Ref<NavigationMesh>(memnew(NavigationMesh));
	navigation_mesh->create_from_mesh(mesh);
	return navigation_mesh;
}

void VoxelMap::_bind_methods() {

	ObjectTypeDB::bind_method(_MD("get_voxel", "vector:Vector3", "channel:int"), &VoxelMap::_get_voxel_binding, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("set_voxel", "value:int", "vector:Vector3", "channel:int"), &VoxelMap::_set_voxel_binding, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("get_default_voxel", "channel"), &VoxelMap::get_default_voxel, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("set_default_voxel", "value", "channel"), &VoxelMap::set_default_voxel, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("has_block", "vector:Vector3"), &VoxelMap::_has_block_binding);
    ObjectTypeDB::bind_method(_MD("get_buffer_copy", "min_pos", "out_buffer:VoxelBuffer", "channel"), &VoxelMap::_get_buffer_copy_binding, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("set_block_buffer", "block_pos", "buffer:VoxelBuffer"), &VoxelMap::_set_block_buffer_binding);
    ObjectTypeDB::bind_method(_MD("voxel_to_block", "voxel_pos"), &VoxelMap::_voxel_to_block_binding);
    ObjectTypeDB::bind_method(_MD("block_to_voxel", "block_pos"), &VoxelMap::_block_to_voxel_binding);
    ObjectTypeDB::bind_method(_MD("get_block_size"), &VoxelMap::get_block_size);
	ObjectTypeDB::bind_method(_MD("get_block_mesh_instance:MeshInstance","block_pos:Vector3", "root:Node"),&VoxelMap::_get_block_mesh_instance_binding);
	ObjectTypeDB::bind_method(_MD("set_block_mesh_instance","block_pos:Vector3", "mesh_instance:MeshInstance"),&VoxelMap::_set_block_mesh_instance_binding);
	ObjectTypeDB::bind_method(_MD("create_navigation_mesh","mesh:Mesh"),&VoxelMap::_create_navigation_mesh_binding);

	//ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations"), _SCS("set_iterations"), _SCS("get_iterations"));

}

void VoxelMap::_get_buffer_copy_binding(Vector3 pos, Ref<VoxelBuffer> dst_buffer_ref, unsigned int channel) {
	ERR_FAIL_COND(dst_buffer_ref.is_null());
	get_buffer_copy(Vector3i(pos), **dst_buffer_ref, channel);
}

<commit_msg>Fix: block was not initialized VoxelBlock::create<commit_after>#include "voxel_map.h"

VoxelMap::VoxelMap() : _last_accessed_block(NULL) {
	for (unsigned int i = 0; i < VoxelBuffer::MAX_CHANNELS; ++i) {
		_default_voxel[i] = 0;
	}
}

VoxelMap::~VoxelMap() {

}

int VoxelMap::get_voxel(Vector3i pos, unsigned int c) {
	Vector3i bpos = voxel_to_block(pos);
	VoxelBlock * block = get_block(bpos);
	if (block == NULL) {
		return _default_voxel[c];
	}
	return block->voxels->get_voxel(pos - block_to_voxel(bpos), c);
}

MeshInstance * VoxelBlock::get_mesh_instance(const Node & root) {
	if (mesh_instance_path.is_empty())
		return NULL;
	Node * n = root.get_node(mesh_instance_path);
	if (n == NULL)
		return NULL;
	return n->cast_to<MeshInstance>();
}

VoxelBlock::~VoxelBlock() {

}

// Helper
VoxelBlock * VoxelBlock::create(Vector3i bpos, VoxelBuffer * buffer) {
	VoxelBlock * block = memnew(VoxelBlock);
	block->pos = bpos;
	if (buffer) {
		const int bs = VoxelBlock::SIZE;
		ERR_FAIL_COND_V(buffer->get_size() != Vector3i(bs, bs, bs), NULL);
	}
	else {
		buffer = memnew(VoxelBuffer);
		buffer->create(SIZE, SIZE, SIZE);
	}
	ERR_FAIL_COND_V(buffer == NULL, NULL);
	block->voxels = Ref<VoxelBuffer>(buffer);
	//block->map = ↦
	return block;
}

void VoxelMap::set_voxel(int value, Vector3i pos, unsigned int c) {
	Vector3i bpos = voxel_to_block(pos);
	VoxelBlock * block = get_block(bpos);
	if (block == NULL) {
		block = VoxelBlock::create(bpos);
		set_block(bpos, block);
	}
	block->voxels->set_voxel(value, pos - block_to_voxel(bpos), c);
}

void VoxelMap::set_default_voxel(int value, unsigned int channel) {
	ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
	_default_voxel[channel] = value;
}

int VoxelMap::get_default_voxel(unsigned int channel) {
	ERR_FAIL_INDEX_V(channel, VoxelBuffer::MAX_CHANNELS, 0);
	return _default_voxel[channel];
}

VoxelBlock * VoxelMap::get_block(Vector3i bpos) {
	if (_last_accessed_block && _last_accessed_block->pos == bpos) {
		return _last_accessed_block;
	}
	Ref<VoxelBlock> * p = _blocks.getptr(bpos);
	if (p) {
		_last_accessed_block = p->ptr();
		return _last_accessed_block;
	}
	return NULL;
}

void VoxelMap::set_block(Vector3i bpos, VoxelBlock * block) {
	if (_last_accessed_block == NULL || _last_accessed_block->pos == bpos) {
		_last_accessed_block = block;
	}
	_blocks.set(bpos, block);
}

void VoxelMap::set_block_buffer(Vector3i bpos, Ref<VoxelBuffer> buffer) {
	ERR_FAIL_COND(buffer.is_null());
	VoxelBlock * block = get_block(bpos);
	if (block == NULL) {
		block = VoxelBlock::create(bpos, *buffer);
		set_block(bpos, block);
	}
	else {
		block->voxels = buffer;
	}
}

bool VoxelMap::has_block(Vector3i pos) const {
	return /*(_last_accessed_block != NULL && _last_accessed_block->pos == pos) ||*/ _blocks.has(pos);
}

Vector3i g_moore_neighboring_3d[26] = {
	Vector3i(-1,-1,-1),
	Vector3i(0,-1,-1),
	Vector3i(1,-1,-1),
	Vector3i(-1,-1,0),
	Vector3i(0,-1,0),
	Vector3i(1,-1,0),
	Vector3i(-1,-1,1),
	Vector3i(0,-1,1),
	Vector3i(1,-1,1),

	Vector3i(-1,0,-1),
	Vector3i(0,0,-1),
	Vector3i(1,0,-1),
	Vector3i(-1,0,0),
	//Vector3i(0,0,0),
	Vector3i(1,0,0),
	Vector3i(-1,0,1),
	Vector3i(0,0,1),
	Vector3i(1,0,1),

	Vector3i(-1,1,-1),
	Vector3i(0,1,-1),
	Vector3i(1,1,-1),
	Vector3i(-1,1,0),
	Vector3i(0,1,0),
	Vector3i(1,1,0),
	Vector3i(-1,1,1),
	Vector3i(0,1,1),
	Vector3i(1,1,1),
};

bool VoxelMap::is_block_surrounded(Vector3i pos) const {
	for (unsigned int i = 0; i < 26; ++i) {
		Vector3i bpos = pos + g_moore_neighboring_3d[i];
		if (!has_block(bpos)) {
			return false;
		}
	}
	return true;
}

void VoxelMap::get_buffer_copy(Vector3i min_pos, VoxelBuffer & dst_buffer, unsigned int channel) {
	ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);

	Vector3i max_pos = min_pos + dst_buffer.get_size();

	Vector3i min_block_pos = voxel_to_block(min_pos);
	Vector3i max_block_pos = voxel_to_block(max_pos - Vector3i(1,1,1)) + Vector3i(1,1,1);
	ERR_FAIL_COND((max_block_pos - min_block_pos) != Vector3(3, 3, 3));

	Vector3i bpos;
	for (bpos.z = min_block_pos.z; bpos.z < max_block_pos.z; ++bpos.z) {
		for (bpos.x = min_block_pos.x; bpos.x < max_block_pos.x; ++bpos.x) {
			for (bpos.y = min_block_pos.y; bpos.y < max_block_pos.y; ++bpos.y) {

				VoxelBlock * block = get_block(bpos);
				if (block) {

					VoxelBuffer & src_buffer = **block->voxels;
					Vector3i offset = block_to_voxel(bpos);
					// Note: copy_from takes care of clamping the area if it's on an edge
					dst_buffer.copy_from(src_buffer, min_pos - offset, max_pos - offset, offset - min_pos, channel);
				}
				else {
					Vector3i offset = block_to_voxel(bpos);
					dst_buffer.fill_area(
						_default_voxel[channel],
						offset - min_pos,
						offset - min_pos + Vector3i(VoxelBlock::SIZE,VoxelBlock::SIZE, VoxelBlock::SIZE)
					);
				}

			}
		}
	}
}

void VoxelMap::remove_blocks_not_in_area(Vector3i min, Vector3i max) {

	Vector3i::sort_min_max(min, max);

	Vector<Vector3i> to_remove;
	Vector3i * key = NULL;

	while (_blocks.next(key)) {

		Ref<VoxelBlock> & block_ref = _blocks.get(*key);
		ERR_FAIL_COND(block_ref.is_null()); // Should never trigger
		VoxelBlock & block = **block_ref;

		if (!block.pos.is_contained_in(min, max)) {

			//if (_observer)
			//    _observer->block_removed(block);

			to_remove.push_back(*key);

			if (&block == _last_accessed_block)
				_last_accessed_block = NULL;
		}
	}

	for (unsigned int i = 0; i < to_remove.size(); ++i) {
		_blocks.erase(to_remove[i]);
	}
}

MeshInstance *VoxelMap::_get_block_mesh_instance_binding(Vector3 bpos, Node * root) {
	VoxelBlock* block = get_block(Vector3i(bpos));
	ERR_FAIL_COND_V(!block, NULL);

	return block->get_mesh_instance(*root);
}

void VoxelMap::_set_block_mesh_instance_binding(Vector3 bpos, Node * node) {
	ERR_FAIL_NULL(node);
	MeshInstance * mesh_instance = node->cast_to<MeshInstance>();
	VoxelBlock* block = get_block(Vector3i(bpos));

    if (block == NULL) {
        block = VoxelBlock::create(Vector3i(bpos));
        set_block(bpos, block);
    }

	block->mesh_instance_path = mesh_instance->get_path();
}

Ref<NavigationMesh> VoxelMap::_create_navigation_mesh_binding(Ref<Mesh> mesh) {
	ERR_FAIL_COND_V(mesh.is_null(), Ref<NavigationMesh>());

	Ref<NavigationMesh> navigation_mesh = Ref<NavigationMesh>(memnew(NavigationMesh));
	navigation_mesh->create_from_mesh(mesh);
	return navigation_mesh;
}

void VoxelMap::_bind_methods() {

	ObjectTypeDB::bind_method(_MD("get_voxel", "vector:Vector3", "channel:int"), &VoxelMap::_get_voxel_binding, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("set_voxel", "value:int", "vector:Vector3", "channel:int"), &VoxelMap::_set_voxel_binding, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("get_default_voxel", "channel"), &VoxelMap::get_default_voxel, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("set_default_voxel", "value", "channel"), &VoxelMap::set_default_voxel, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("has_block", "vector:Vector3"), &VoxelMap::_has_block_binding);
    ObjectTypeDB::bind_method(_MD("get_buffer_copy", "min_pos", "out_buffer:VoxelBuffer", "channel"), &VoxelMap::_get_buffer_copy_binding, DEFVAL(0));
    ObjectTypeDB::bind_method(_MD("set_block_buffer", "block_pos", "buffer:VoxelBuffer"), &VoxelMap::_set_block_buffer_binding);
    ObjectTypeDB::bind_method(_MD("voxel_to_block", "voxel_pos"), &VoxelMap::_voxel_to_block_binding);
    ObjectTypeDB::bind_method(_MD("block_to_voxel", "block_pos"), &VoxelMap::_block_to_voxel_binding);
    ObjectTypeDB::bind_method(_MD("get_block_size"), &VoxelMap::get_block_size);
	ObjectTypeDB::bind_method(_MD("get_block_mesh_instance:MeshInstance","block_pos:Vector3", "root:Node"),&VoxelMap::_get_block_mesh_instance_binding);
	ObjectTypeDB::bind_method(_MD("set_block_mesh_instance","block_pos:Vector3", "mesh_instance:MeshInstance"),&VoxelMap::_set_block_mesh_instance_binding);
	ObjectTypeDB::bind_method(_MD("create_navigation_mesh","mesh:Mesh"),&VoxelMap::_create_navigation_mesh_binding);

	//ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations"), _SCS("set_iterations"), _SCS("get_iterations"));

}

void VoxelMap::_get_buffer_copy_binding(Vector3 pos, Ref<VoxelBuffer> dst_buffer_ref, unsigned int channel) {
	ERR_FAIL_COND(dst_buffer_ref.is_null());
	get_buffer_copy(Vector3i(pos), **dst_buffer_ref, channel);
}

<|endoftext|>


<commit_before>/* Copyright (c) 2014 Scott Kuhl. All rights reserved.
 * License: This code is licensed under a 3-clause BSD license. See
 * the file named "LICENSE" for a full copy of the license.
 */

/** @file
 * @author Scott Kuhl
 */
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>

#ifndef MISSING_VRPN
#include <vrpn_Tracker.h>
#include <quat.h>
#endif

#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include "kuhl-util.h"

#ifndef MISSING_VRPN

/** A mapping of object\@tracker strings to vrpn_Tracker_Remote objects
 * so we can quickly find the appropriate object given an
 * object\@tracker string. */
std::map<std::string, vrpn_Tracker_Remote*> nameToTracker;
/** A mapping of object\@tracker strings to the data that the callback
 * functions store the data into. */
std::map<std::string, vrpn_TRACKERCB> nameToCallbackData;

/** A callback function that will get called whenever the tracked
 * point moves. */
static void VRPN_CALLBACK handle_tracker(void *name, const vrpn_TRACKERCB t)
{
    // Store the data in our map so that someone can use it later.
	std::string s = (char*)name;
	nameToCallbackData[s] = t;
}

#endif

extern "C" {
/** Uses the VRPN library to get the position and orientation of a
 * tracked object.
 *
 * @param object The name of the object being tracked.
 *
 * @param hostname The IP address or hostname of the VRPN server or
 * tracking system computer. If hostname is set to NULL, the IP
 * address of the Vicon tracker in the IVS lab is used.
 *
 * @param pos An array to be filled in with the position information
 * for the tracked object. If we are unable to track the object, a
 * message may be printed and pos will be set to a fixed value.
 *
 * @param orient An array to be filled in with the orientation matrix
 * for the tracked object. The orientation matrix is in row-major
 * order can be used with OpenGL. If the tracking system is moving an
 * object around on the screen, this matrix can be used directly. If
 * the tracking system is moving the OpenGL camera, this matrix may
 * need to be inverted. If we are unable to track the object, a
 * message may be printed and orient will be set to the identity
 * matrix.
 *
 * @return 1 if we returned data from the tracker. 0 if there was
 * problems connecting to the tracker.
 */
int vrpn_get(const char *object, const char *hostname, float pos[3], float orient[16])
{

#ifndef MISSING_VRPN
	/* Construct an object@hostname string. */
	std::string hostnamecpp;
	std::string objectcpp;
	if(hostname == NULL)
		hostnamecpp = "tcp://VRPN-SERVER-IP-ADDRESS";
	objectcpp = object;
	std::string fullname = objectcpp + "@" + hostnamecpp;

	/* Check if we have a tracker object for that string in our map. */
	if(nameToTracker.count(fullname))
	{
		/* If we already have a tracker object, ask it to run the main
		 * loop (and therefore call our handle_tracker() function if
		 * there is new data). */
		nameToTracker[fullname]->mainloop();

		/* If our callback has been called, get the callback object
		 * and get the data out of it. */
		if(nameToCallbackData.count(fullname))
		{
			vrpn_TRACKERCB t = nameToCallbackData[fullname];
			float pos4[4];
			for(int i=0; i<3; i++)
				pos4[i] = t.pos[i];
			pos4[3]=1;

			double orientd[16];
			// Convert quaternion into orientation matrix.
			q_to_ogl_matrix(orientd, t.quat);
			for(int i=0; i<16; i++)
				orient[i] = (float) orientd[i];

			/* IMPORTANT NOTE: The Vicon tracking system is normally
			 * calibrated so that:
			 * X = points to the right (while facing screen)
			 * Y = points into the screen
			 * Z = up
			 *
			 * By default, OpenGL assumes that:
			 * X = points to the right (while facing screen)
			 * Y = up
			 * Z = points OUT of the screen (i.e., -Z points into the screen)
			 *
			 * Below, we convert the Vicon position and orientation
			 * information into the OpenGL convention to make it
			 * easier to add Vicon support to an OpenGL program.
			 *
			 * If you are using this file with a different tracking
			 * system, this conversion may be wrong!
			 */

			float zUpToYUp[16] = { 1,0,0,0,  // column major order!
			                       0,0,-1,0,
			                       0,1,0,0,
			                       0,0,0,1 };
			mat4f_mult_mat4f_new(orient, zUpToYUp, orient);
			mat4f_mult_vec4f_new(pos4, zUpToYUp, pos4);
			vec3f_copy(pos,pos4);
			return 1;
		}
		else
		{
			/* If we don't have any data yet, return a position far from the origin. */
			vec3f_set(pos, 10000,10000,10000);
			mat4f_identity(orient);
			return 0;
		}
	}
	else
	{
		/* If this is our first time, create a tracker for the object@hostname string, register the callback handler. */
		printf("vrpn-help: Connecting to VRPN server. If this hangs, VRPN server is not running.\n");
		vrpn_Tracker_Remote *tkr = new vrpn_Tracker_Remote(fullname.c_str());
		nameToTracker[fullname] = tkr;
		tkr->register_change_handler((void*) fullname.c_str(), handle_tracker);
		return 0; // If we connected successfully, the next time this is called we'll return 1
	}
#else
	printf("You are missing VRPN support.\n");
	mat4f_identity(orient);
	vec3f_set(pos, 0,0,0);
	return 0;
#endif
}
} // extern C
<commit_msg>ensure that tracking system data is always initialized to something.<commit_after>/* Copyright (c) 2014 Scott Kuhl. All rights reserved.
 * License: This code is licensed under a 3-clause BSD license. See
 * the file named "LICENSE" for a full copy of the license.
 */

/** @file
 * @author Scott Kuhl
 */
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>

#ifndef MISSING_VRPN
#include <vrpn_Tracker.h>
#include <quat.h>
#endif

#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include "kuhl-util.h"

#ifndef MISSING_VRPN

/** A mapping of object\@tracker strings to vrpn_Tracker_Remote objects
 * so we can quickly find the appropriate object given an
 * object\@tracker string. */
std::map<std::string, vrpn_Tracker_Remote*> nameToTracker;
/** A mapping of object\@tracker strings to the data that the callback
 * functions store the data into. */
std::map<std::string, vrpn_TRACKERCB> nameToCallbackData;

/** A callback function that will get called whenever the tracked
 * point moves. */
static void VRPN_CALLBACK handle_tracker(void *name, const vrpn_TRACKERCB t)
{
    // Store the data in our map so that someone can use it later.
	std::string s = (char*)name;
	nameToCallbackData[s] = t;
}

#endif

extern "C" {
/** Uses the VRPN library to get the position and orientation of a
 * tracked object.
 *
 * @param object The name of the object being tracked.
 *
 * @param hostname The IP address or hostname of the VRPN server or
 * tracking system computer. If hostname is set to NULL, the IP
 * address of the Vicon tracker in the IVS lab is used.
 *
 * @param pos An array to be filled in with the position information
 * for the tracked object. If we are unable to track the object, a
 * message may be printed and pos will be set to a fixed value.
 *
 * @param orient An array to be filled in with the orientation matrix
 * for the tracked object. The orientation matrix is in row-major
 * order can be used with OpenGL. If the tracking system is moving an
 * object around on the screen, this matrix can be used directly. If
 * the tracking system is moving the OpenGL camera, this matrix may
 * need to be inverted. If we are unable to track the object, a
 * message may be printed and orient will be set to the identity
 * matrix.
 *
 * @return 1 if we returned data from the tracker. 0 if there was
 * problems connecting to the tracker.
 */
int vrpn_get(const char *object, const char *hostname, float pos[3], float orient[16])
{
	/* Set to default values */
	vec3f_set(pos, 10000,10000,10000);
	mat4f_identity(orient);
#ifdef MISSING_VRPN
	printf("You are missing VRPN support.\n");
	return 0;
#else
	/* Construct an object@hostname string. */
	std::string hostnamecpp;
	std::string objectcpp;
	if(hostname == NULL)
		hostnamecpp = "tcp://VRPN-SERVER-IP-ADDRESS";
	objectcpp = object;
	std::string fullname = objectcpp + "@" + hostnamecpp;

	/* Check if we have a tracker object for that string in our map. */
	if(nameToTracker.count(fullname))
	{
		/* If we already have a tracker object, ask it to run the main
		 * loop (and therefore call our handle_tracker() function if
		 * there is new data). */
		nameToTracker[fullname]->mainloop();

		/* If our callback has been called, get the callback object
		 * and get the data out of it. */
		if(nameToCallbackData.count(fullname))
		{
			vrpn_TRACKERCB t = nameToCallbackData[fullname];
			float pos4[4];
			for(int i=0; i<3; i++)
				pos4[i] = t.pos[i];
			pos4[3]=1;

			double orientd[16];
			// Convert quaternion into orientation matrix.
			q_to_ogl_matrix(orientd, t.quat);
			for(int i=0; i<16; i++)
				orient[i] = (float) orientd[i];

			/* IMPORTANT NOTE: The Vicon tracking system is normally
			 * calibrated so that:
			 * X = points to the right (while facing screen)
			 * Y = points into the screen
			 * Z = up
			 *
			 * By default, OpenGL assumes that:
			 * X = points to the right (while facing screen)
			 * Y = up
			 * Z = points OUT of the screen (i.e., -Z points into the screen)
			 *
			 * Below, we convert the Vicon position and orientation
			 * information into the OpenGL convention to make it
			 * easier to add Vicon support to an OpenGL program.
			 *
			 * If you are using this file with a different tracking
			 * system, this conversion may be wrong!
			 */

			float zUpToYUp[16] = { 1,0,0,0,  // column major order!
			                       0,0,-1,0,
			                       0,1,0,0,
			                       0,0,0,1 };
			mat4f_mult_mat4f_new(orient, zUpToYUp, orient);
			mat4f_mult_vec4f_new(pos4, zUpToYUp, pos4);
			vec3f_copy(pos,pos4);
			return 1; // we successfully collected some data
		}
	}
	else
	{
		/* If this is our first time, create a tracker for the object@hostname string, register the callback handler. */
		printf("vrpn-help: Connecting to VRPN server. If this hangs, VRPN server is not running.\n");
		vrpn_Tracker_Remote *tkr = new vrpn_Tracker_Remote(fullname.c_str());
		nameToTracker[fullname] = tkr;
		tkr->register_change_handler((void*) fullname.c_str(), handle_tracker);
	}
	return 0;
#endif
}
} // extern C
<|endoftext|>


<commit_before>/* Copyright (c) 2014 Scott Kuhl. All rights reserved.
 * License: This code is licensed under a 3-clause BSD license. See
 * the file named "LICENSE" for a full copy of the license.
 */

/** @file
 * @author Scott Kuhl
 */
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>

#ifndef MISSING_VRPN
#include <vrpn_Tracker.h>
#include <quat.h>
#endif

#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include "kuhl-util.h"
#include "vecmat.h"

#ifndef MISSING_VRPN

/** A mapping of object\@tracker strings to vrpn_Tracker_Remote objects
 * so we can quickly find the appropriate object given an
 * object\@tracker string. */
std::map<std::string, vrpn_Tracker_Remote*> nameToTracker;
/** A mapping of object\@tracker strings to the data that the callback
 * functions store the data into. */
std::map<std::string, vrpn_TRACKERCB> nameToCallbackData;

/** A callback function that will get called whenever the tracked
 * point moves. */
static void VRPN_CALLBACK handle_tracker(void *name, const vrpn_TRACKERCB t)
{
    // Store the data in our map so that someone can use it later.
	std::string s = (char*)name;
	nameToCallbackData[s] = t;
}

#endif

extern "C" {
/** Uses the VRPN library to get the position and orientation of a
 * tracked object.
 *
 * @param object The name of the object being tracked.
 *
 * @param hostname The IP address or hostname of the VRPN server or
 * tracking system computer. If hostname is set to NULL, the IP
 * address of the Vicon tracker in the IVS lab is used.
 *
 * @param pos An array to be filled in with the position information
 * for the tracked object. If we are unable to track the object, a
 * message may be printed and pos will be set to a fixed value.
 *
 * @param orient An array to be filled in with the orientation matrix
 * for the tracked object. The orientation matrix is in row-major
 * order can be used with OpenGL. If the tracking system is moving an
 * object around on the screen, this matrix can be used directly. If
 * the tracking system is moving the OpenGL camera, this matrix may
 * need to be inverted. If we are unable to track the object, a
 * message may be printed and orient will be set to the identity
 * matrix.
 *
 * @return 1 if we returned data from the tracker. 0 if there was
 * problems connecting to the tracker.
 */
int vrpn_get(const char *object, const char *hostname, float pos[3], float orient[16])
{
	/* Set to default values */
	vec3f_set(pos, 10000,10000,10000);
	mat4f_identity(orient);
#ifdef MISSING_VRPN
	printf("You are missing VRPN support.\n");
	return 0;
#else
	/* Construct an object@hostname string. */
	std::string hostnamecpp;
	std::string objectcpp;
	if(hostname == NULL)
		hostnamecpp = "tcp://VRPN-SERVER-IP-ADDRESS";
	objectcpp = object;
	std::string fullname = objectcpp + "@" + hostnamecpp;

	/* Check if we have a tracker object for that string in our map. */
	if(nameToTracker.count(fullname))
	{
		/* If we already have a tracker object, ask it to run the main
		 * loop (and therefore call our handle_tracker() function if
		 * there is new data). */
		nameToTracker[fullname]->mainloop();

		/* If our callback has been called, get the callback object
		 * and get the data out of it. */
		if(nameToCallbackData.count(fullname))
		{
			vrpn_TRACKERCB t = nameToCallbackData[fullname];
			float pos4[4];
			for(int i=0; i<3; i++)
				pos4[i] = t.pos[i];
			pos4[3]=1;

			double orientd[16];
			// Convert quaternion into orientation matrix.
			q_to_ogl_matrix(orientd, t.quat);
			for(int i=0; i<16; i++)
				orient[i] = (float) orientd[i];

			/* IMPORTANT NOTE: The Vicon tracking system is normally
			 * calibrated so that:
			 * X = points to the right (while facing screen)
			 * Y = points into the screen
			 * Z = up
			 *
			 * By default, OpenGL assumes that:
			 * X = points to the right (while facing screen)
			 * Y = up
			 * Z = points OUT of the screen (i.e., -Z points into the screen)
			 *
			 * Below, we convert the Vicon position and orientation
			 * information into the OpenGL convention to make it
			 * easier to add Vicon support to an OpenGL program.
			 *
			 * If you are using this file with a different tracking
			 * system, this conversion may be wrong!
			 */

			float zUpToYUp[16] = { 1,0,0,0,  // column major order!
			                       0,0,-1,0,
			                       0,1,0,0,
			                       0,0,0,1 };
			mat4f_mult_mat4f_new(orient, zUpToYUp, orient);
			mat4f_mult_vec4f_new(pos4, zUpToYUp, pos4);
			vec3f_copy(pos,pos4);
			return 1; // we successfully collected some data
		}
	}
	else
	{
		/* If this is our first time, create a tracker for the object@hostname string, register the callback handler. */
		printf("vrpn-help: Connecting to VRPN server. If this hangs, VRPN server is not running.\n");
		vrpn_Tracker_Remote *tkr = new vrpn_Tracker_Remote(fullname.c_str());
		nameToTracker[fullname] = tkr;
		tkr->register_change_handler((void*) fullname.c_str(), handle_tracker);
	}
	return 0;
#endif
}
} // extern C
<commit_msg>store IP address of VRPN server in a file in the users home directory instead of coded into the source code.<commit_after>/* Copyright (c) 2014 Scott Kuhl. All rights reserved.
 * License: This code is licensed under a 3-clause BSD license. See
 * the file named "LICENSE" for a full copy of the license.
 */

/** @file
 * @author Scott Kuhl
 */
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>

#ifndef MISSING_VRPN
#include <vrpn_Tracker.h>
#include <quat.h>
#endif

#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include "kuhl-util.h"
#include "vecmat.h"

#ifndef MISSING_VRPN

/** A mapping of object\@tracker strings to vrpn_Tracker_Remote objects
 * so we can quickly find the appropriate object given an
 * object\@tracker string. */
std::map<std::string, vrpn_Tracker_Remote*> nameToTracker;
/** A mapping of object\@tracker strings to the data that the callback
 * functions store the data into. */
std::map<std::string, vrpn_TRACKERCB> nameToCallbackData;

/** A callback function that will get called whenever the tracked
 * point moves. */
static void VRPN_CALLBACK handle_tracker(void *name, const vrpn_TRACKERCB t)
{
	// Store the data in our map so that someone can use it later.
	std::string s = (char*)name;
	nameToCallbackData[s] = t;
}

#endif

extern "C" {
/** Uses the VRPN library to get the position and orientation of a
 * tracked object.
 *
 * @param object The name of the object being tracked.
 *
 * @param hostname The IP address or hostname of the VRPN server or
 * tracking system computer. If hostname is set to NULL, the IP
 * address of the Vicon tracker in the IVS lab is used.
 *
 * @param pos An array to be filled in with the position information
 * for the tracked object. If we are unable to track the object, a
 * message may be printed and pos will be set to a fixed value.
 *
 * @param orient An array to be filled in with the orientation matrix
 * for the tracked object. The orientation matrix is in row-major
 * order can be used with OpenGL. If the tracking system is moving an
 * object around on the screen, this matrix can be used directly. If
 * the tracking system is moving the OpenGL camera, this matrix may
 * need to be inverted. If we are unable to track the object, a
 * message may be printed and orient will be set to the identity
 * matrix.
 *
 * @return 1 if we returned data from the tracker. 0 if there was
 * problems connecting to the tracker.
 */
int vrpn_get(const char *object, const char *hostname, float pos[3], float orient[16])
{
	/* Set to default values */
	vec3f_set(pos, 10000,10000,10000);
	mat4f_identity(orient);
#ifdef MISSING_VRPN
	printf("You are missing VRPN support.\n");
	return 0;
#else
	/* Construct an object@hostname string. */
	std::string hostnamecpp;
	std::string objectcpp;
	if(hostname == NULL)
	{
		/* Try reading VRPN server information from ~/.vrpn-server

		   This file should contain a single line that says something like:
		   tcp://VRPN.SERVER.IP.ADDR
		 */
		const char *homedir = getenv("HOME");
		char path[1024];
		snprintf(path, 1024, "%s/.vrpn-server", homedir);
		FILE *f = fopen(path, "r");
		if(f == NULL)
		{
			printf("%s: Can't open file %s to get VRPN server information.\n", __func__, path);
			exit(EXIT_FAILURE);
		}
		char vrpnString[1024];
		if(fscanf(f, "%1023s", vrpnString) != 1)
		{
			printf("%s: Can't read %s to get VRPN server information.\n", __func__, path);
			exit(EXIT_FAILURE);
		}
		// printf("%s: Found in %s: %s\n", __func__, path, vrpnString);
		hostnamecpp = vrpnString;
		exit(EXIT_FAILURE);
	}

	objectcpp = object;
	std::string fullname = objectcpp + "@" + hostnamecpp;

	/* Check if we have a tracker object for that string in our map. */
	if(nameToTracker.count(fullname))
	{
		/* If we already have a tracker object, ask it to run the main
		 * loop (and therefore call our handle_tracker() function if
		 * there is new data). */
		nameToTracker[fullname]->mainloop();

		/* If our callback has been called, get the callback object
		 * and get the data out of it. */
		if(nameToCallbackData.count(fullname))
		{
			vrpn_TRACKERCB t = nameToCallbackData[fullname];
			float pos4[4];
			for(int i=0; i<3; i++)
				pos4[i] = t.pos[i];
			pos4[3]=1;

			double orientd[16];
			// Convert quaternion into orientation matrix.
			q_to_ogl_matrix(orientd, t.quat);
			for(int i=0; i<16; i++)
				orient[i] = (float) orientd[i];

			/* IMPORTANT NOTE: The Vicon tracking system is normally
			 * calibrated so that:
			 * X = points to the right (while facing screen)
			 * Y = points into the screen
			 * Z = up
			 *
			 * By default, OpenGL assumes that:
			 * X = points to the right (while facing screen)
			 * Y = up
			 * Z = points OUT of the screen (i.e., -Z points into the screen)
			 *
			 * Below, we convert the Vicon position and orientation
			 * information into the OpenGL convention to make it
			 * easier to add Vicon support to an OpenGL program.
			 *
			 * If you are using this file with a different tracking
			 * system, this conversion may be wrong!
			 */

			float zUpToYUp[16] = { 1,0,0,0,  // column major order!
			                       0,0,-1,0,
			                       0,1,0,0,
			                       0,0,0,1 };
			mat4f_mult_mat4f_new(orient, zUpToYUp, orient);
			mat4f_mult_vec4f_new(pos4, zUpToYUp, pos4);
			vec3f_copy(pos,pos4);
			return 1; // we successfully collected some data
		}
	}
	else
	{
		/* If this is our first time, create a tracker for the object@hostname string, register the callback handler. */
		printf("vrpn-help: Connecting to VRPN server. If this hangs, VRPN server is not running.\n");
		vrpn_Tracker_Remote *tkr = new vrpn_Tracker_Remote(fullname.c_str());
		nameToTracker[fullname] = tkr;
		tkr->register_change_handler((void*) fullname.c_str(), handle_tracker);
	}
	return 0;
#endif
}
} // extern C
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <boost/asio.hpp>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <qapplication.h>
#include <QtGui>
#include <QtCore>

#ifdef __APPLE__
	#include <QMacStyle>
#endif

#include <curl/curl.h>

#include "session.h"
#include "startwindowimpl.h"
#include "configfile.h"
#include "startsplash.h"
#include "game_defs.h"
#include <net/socket_startup.h>
#include <third_party/qtsingleapplication/qtsingleapplication.h>

#ifdef _MSC_VER
	#ifdef _DEBUG
		#define _CRTDBG_MAP_ALLOC
		#include <crtdbg.h>

		#define ENABLE_LEAK_CHECK() \
			{ \
				int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); \
				tmpFlag |= _CRTDBG_LEAK_CHECK_DF; \
				_CrtSetDbgFlag(tmpFlag); \
			}
	#endif
#endif

#ifndef ENABLE_LEAK_CHECK
	#define ENABLE_LEAK_CHECK()
#endif

//Uncomment this for RELEASE on Linux/Unix/BSD (static Qt only)
//#include <QtPlugin>
//Q_IMPORT_PLUGIN(qjpeg)
//Q_IMPORT_PLUGIN(qgif)

#ifdef _WIN32 // Always use static Qt on Windows.
#include <QtPlugin>
Q_IMPORT_PLUGIN(qjpeg)
Q_IMPORT_PLUGIN(qgif)
#endif

using namespace std;

class startWindowImpl;
class Game;

int main( int argc, char **argv )
{

	//ENABLE_LEAK_CHECK();

	//_CrtSetBreakAlloc(49937);
	socket_startup();
	curl_global_init(CURL_GLOBAL_NOTHING);

	/////// can be removed for non-qt-guis ////////////
	QtSingleApplication a( argc, argv );

	if (a.sendMessage("Wake up!")) {
		return 0;
	 }

#ifdef __APPLE__
	// The following needs to be done directly after the application is created.
	QDir dir(QApplication::applicationDirPath());
	dir.cdUp();
	dir.cd("plugins");
	QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif

	//create defaultconfig
	ConfigFile *myConfig = new ConfigFile(argv[0], false);

	// set PlastiqueStyle even for mac-version to prevent artefacts on styled widgets
        a.setStyle(new QPlastiqueStyle);

	QString	myAppDataPath = QString::fromUtf8(myConfig->readConfigString("AppDataDir").c_str());
	//set QApplication default font

	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/n019003l.pfb");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/VeraBd.ttf");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/c059013l.pfb");

#ifdef _WIN32
        QString font1String("QApplication, QWidget, QDialog { font-family: \"Arial\"; font-size: 12px; }");
#else
        #ifdef __APPLE__
//            QString font1String("font-family: \"Lucida Grande\";");
            QString font1String("QApplication, QWidget, QDialog { font-size: 11px; }");
        #else
            QString font1String("QApplication, QWidget, QDialog { font-family: \"Nimbus Sans L\"; font-size: 12px; }");
        #endif
#endif
        a.setStyleSheet(font1String + " QDialogButtonBox, QMessageBox { dialogbuttonbox-buttons-have-icons: 1; dialog-ok-icon: url(:/gfx/dialog_ok_apply.png); dialog-cancel-icon: url(:/gfx/dialog_close.png); dialog-close-icon: url(:/gfx/dialog_close.png); dialog-yes-icon: url(:/gfx/dialog_ok_apply.png); dialog-no-icon: url(:/gfx/dialog_close.png) }");

	QPixmap *pixmap = new QPixmap(myAppDataPath + "gfx/gui/misc/welcomepokerth.png");
	StartSplash splash(*pixmap);
	if(!myConfig->readConfigInt("DisableSplashScreenOnStartup")) {
		splash.show();
		splash.showMessage(QString("Version %1").arg(POKERTH_BETA_RELEASE_STRING), 0x0042, QColor(153,213,0));
	}

	//Set translations
	QTranslator qtTranslator;
        qtTranslator.load(QString(myAppDataPath +"translations/qt_") + QString::fromStdString(myConfig->readConfigString("Language")));
        a.installTranslator(&qtTranslator);

	QTranslator translator;
	translator.load(QString(myAppDataPath +"translations/pokerth_") + QString::fromStdString(myConfig->readConfigString("Language")));
	a.installTranslator(&translator);

	qRegisterMetaType<unsigned>("unsigned");
	qRegisterMetaType<boost::shared_ptr<Game> >("boost::shared_ptr<Game>");
	qRegisterMetaType<ServerStats>("ServerStats");
        qRegisterMetaType<DenyGameInvitationReason>("DenyGameInvitationReason");
	///////////////////////////////////////////////////

        startWindowImpl mainWin(myConfig);
        a.setActivationWindow(&mainWin, true);

	int retVal = a.exec();

	curl_global_cleanup();
	socket_cleanup();

	return retVal;

}
<commit_msg>windows font fix<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <boost/asio.hpp>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <qapplication.h>
#include <QtGui>
#include <QtCore>

#ifdef __APPLE__
	#include <QMacStyle>
#endif

#include <curl/curl.h>

#include "session.h"
#include "startwindowimpl.h"
#include "configfile.h"
#include "startsplash.h"
#include "game_defs.h"
#include <net/socket_startup.h>
#include <third_party/qtsingleapplication/qtsingleapplication.h>

#ifdef _MSC_VER
	#ifdef _DEBUG
		#define _CRTDBG_MAP_ALLOC
		#include <crtdbg.h>

		#define ENABLE_LEAK_CHECK() \
			{ \
				int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); \
				tmpFlag |= _CRTDBG_LEAK_CHECK_DF; \
				_CrtSetDbgFlag(tmpFlag); \
			}
	#endif
#endif

#ifndef ENABLE_LEAK_CHECK
	#define ENABLE_LEAK_CHECK()
#endif

//Uncomment this for RELEASE on Linux/Unix/BSD (static Qt only)
//#include <QtPlugin>
//Q_IMPORT_PLUGIN(qjpeg)
//Q_IMPORT_PLUGIN(qgif)

#ifdef _WIN32 // Always use static Qt on Windows.
#include <QtPlugin>
Q_IMPORT_PLUGIN(qjpeg)
Q_IMPORT_PLUGIN(qgif)
#endif

using namespace std;

class startWindowImpl;
class Game;

int main( int argc, char **argv )
{

	//ENABLE_LEAK_CHECK();

	//_CrtSetBreakAlloc(49937);
	socket_startup();
	curl_global_init(CURL_GLOBAL_NOTHING);

	/////// can be removed for non-qt-guis ////////////
	QtSingleApplication a( argc, argv );

	if (a.sendMessage("Wake up!")) {
		return 0;
	 }

#ifdef __APPLE__
	// The following needs to be done directly after the application is created.
	QDir dir(QApplication::applicationDirPath());
	dir.cdUp();
	dir.cd("plugins");
	QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif

	//create defaultconfig
	ConfigFile *myConfig = new ConfigFile(argv[0], false);

	// set PlastiqueStyle even for mac-version to prevent artefacts on styled widgets
        a.setStyle(new QPlastiqueStyle);

	QString	myAppDataPath = QString::fromUtf8(myConfig->readConfigString("AppDataDir").c_str());
	//set QApplication default font

	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/n019003l.pfb");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/VeraBd.ttf");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/c059013l.pfb");

#ifdef _WIN32
        QString font1String("QApplication, QWidget, QDialog { font-size: 12px; }");
#else
        #ifdef __APPLE__
//            QString font1String("font-family: \"Lucida Grande\";");
            QString font1String("QApplication, QWidget, QDialog { font-size: 11px; }");
        #else
            QString font1String("QApplication, QWidget, QDialog { font-family: \"Nimbus Sans L\"; font-size: 12px; }");
        #endif
#endif
        a.setStyleSheet(font1String + " QDialogButtonBox, QMessageBox { dialogbuttonbox-buttons-have-icons: 1; dialog-ok-icon: url(:/gfx/dialog_ok_apply.png); dialog-cancel-icon: url(:/gfx/dialog_close.png); dialog-close-icon: url(:/gfx/dialog_close.png); dialog-yes-icon: url(:/gfx/dialog_ok_apply.png); dialog-no-icon: url(:/gfx/dialog_close.png) }");

	QPixmap *pixmap = new QPixmap(myAppDataPath + "gfx/gui/misc/welcomepokerth.png");
	StartSplash splash(*pixmap);
	if(!myConfig->readConfigInt("DisableSplashScreenOnStartup")) {
		splash.show();
		splash.showMessage(QString("Version %1").arg(POKERTH_BETA_RELEASE_STRING), 0x0042, QColor(153,213,0));
	}

	//Set translations
	QTranslator qtTranslator;
        qtTranslator.load(QString(myAppDataPath +"translations/qt_") + QString::fromStdString(myConfig->readConfigString("Language")));
        a.installTranslator(&qtTranslator);

	QTranslator translator;
	translator.load(QString(myAppDataPath +"translations/pokerth_") + QString::fromStdString(myConfig->readConfigString("Language")));
	a.installTranslator(&translator);

	qRegisterMetaType<unsigned>("unsigned");
	qRegisterMetaType<boost::shared_ptr<Game> >("boost::shared_ptr<Game>");
	qRegisterMetaType<ServerStats>("ServerStats");
        qRegisterMetaType<DenyGameInvitationReason>("DenyGameInvitationReason");
	///////////////////////////////////////////////////

        startWindowImpl mainWin(myConfig);
        a.setActivationWindow(&mainWin, true);

	int retVal = a.exec();

	curl_global_cleanup();
	socket_cleanup();

	return retVal;

}
<|endoftext|>