<commit_before>//=============================================================================================================
/**
 * @file     main.cpp
 * @author   Ruben Dörfel <ruben.doerfel@tu-ilmenau.de>;
 * @version  dev
 * @date     January, 2020
 *
 * @section  LICENSE
 *
 * Copyright (C) 2020, Ruben Dörfel. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
 *       to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief     Example for cHPI fitting on raw data with SSP. The result is written to a .txt file for comparison with MaxFilter's .pos file.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <iostream>
#include <vector>
#include <math.h>

#include <fiff/fiff.h>
#include <fiff/fiff_info.h>
#include <fiff/fiff_dig_point_set.h>
#include <fiff/fiff_cov.h>

#include <inverse/hpiFit/hpifit.h>
#include <inverse/hpiFit/hpifitdata.h>

#include <utils/ioutils.h>
#include <utils/generics/applicationlogger.h>

#include <fwd/fwd_coil_set.h>

//=============================================================================================================
// Qt INCLUDES
//=============================================================================================================

#include <QtCore/QCoreApplication>
#include <QFile>
#include <QCommandLineParser>
#include <QDebug>
#include <QGenericMatrix>
#include <QQuaternion>
#include <QElapsedTimer>

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

using namespace INVERSELIB;
using namespace FIFFLIB;
using namespace Eigen;

//=============================================================================================================
// Member functions
//=============================================================================================================

//=========================================================================================================
/**
 * Store results from dev_Head_t as quaternions in position matrix. The postion matrix is consisten with the MaxFilter output
 *
 * @param[in] time          The corresponding time in the measurement for the fit.
 * @param[in] pFiffInfo     The FiffInfo file from the measurement.
 * @param[in] position      The matrix to store the results
 * @param[in] vGoF          The vector that stores the goodness of fit.
 *
 * ToDo: get correct GoF; vGof that is passed to fitHPI does not represent the actual GoF
 *
 */
void writePos(const float time, QSharedPointer<FiffInfo> pFiffInfo, MatrixXd& position, const QVector<double>& vGoF)
{
    // Write quaternions and time in position matrix. Format is the same like MaxFilter's .pos files.
    QMatrix3x3 rot;

    for(int ir = 0; ir < 3; ir++) {
        for(int ic = 0; ic < 3; ic++) {
            rot(ir,ic) = pFiffInfo->dev_head_t.trans(ir,ic);
        }
    }

    // double error = std::accumulate(vGoF.begin(), vGoF.end(), .0) / vGoF.size();
    QQuaternion quatHPI = QQuaternion::fromRotationMatrix(rot);

    //qDebug() << "quatHPI.x() " << "quatHPI.y() " << "quatHPI.y() " << "trans x " << "trans y " << "trans z " << std::endl;
    //qDebug() << quatHPI.x() << quatHPI.y() << quatHPI.z() << info->dev_head_t.trans(0,3) << info->dev_head_t.trans(1,3) << info->dev_head_t.trans(2,3) << std::endl;

    position.conservativeResize(position.rows()+1, 10);
    position(position.rows()-1,0) = time;
    position(position.rows()-1,1) = quatHPI.x();
    position(position.rows()-1,2) = quatHPI.y();
    position(position.rows()-1,3) = quatHPI.z();
    position(position.rows()-1,4) = pFiffInfo->dev_head_t.trans(0,3);
    position(position.rows()-1,5) = pFiffInfo->dev_head_t.trans(1,3);
    position(position.rows()-1,6) = pFiffInfo->dev_head_t.trans(2,3);
    position(position.rows()-1,7) = 0;
    position(position.rows()-1,8) = 0;
    position(position.rows()-1,9) = 0;
}

//=========================================================================================================
/**
 * Compare new head position with current head position and update dev_head_t if big displacement occured
 *
 * @param[in] devHeadTrans      The device to head transformation matrix to compare to.
 * @param[in] devHeadTransNew   The device to head transformation matrix to be compared.
 * @param[in] treshRot          The threshold for big head rotation in degree
 * @param[in] treshTrans        The threshold for big head movement in m
 *
 * @param[out] state            The status that shows if devHead is updated or not
 *
 */
bool compareResults(FiffCoordTrans& devHeadT, const FiffCoordTrans& devHeadTNew,const float& treshRot,const float& treshTrans, MatrixXd& result)
{
    QMatrix3x3 rot;
    QMatrix3x3 rotNew;

    for(int ir = 0; ir < 3; ir++) {
        for(int ic = 0; ic < 3; ic++) {
            rot(ir,ic) = devHeadT.trans(ir,ic);
            rotNew(ir,ic) = devHeadTNew.trans(ir,ic);
        }
    }

    VectorXf trans = devHeadT.trans.col(3);
    VectorXf transNew = devHeadTNew.trans.col(3);

    QQuaternion quat = QQuaternion::fromRotationMatrix(rot);
    QQuaternion quatNew = QQuaternion::fromRotationMatrix(rotNew);

    // Compare Rotation
    QQuaternion quatCompare;
    float angle;
    QVector3D axis;
    // get rotation between both transformations by multiplying with the inverted quaternion
    quatCompare = quat*quatNew.inverted();
    quatCompare.getAxisAndAngle(&axis,&angle);
    qInfo() << "Displacement angle [degree]: " << angle;

    // Compare translation
    float move = (trans-transNew).norm();
    qInfo() << "Displacement Move [mm]: " << move*1000;

    // write results for debug purpose - quaternions are quatCompare
    result.conservativeResize(result.rows()+1, 10);
    result.conservativeResize(result.rows()+1, 10);
    result(result.rows()-1,0) = 0;
    result(result.rows()-1,1) = quatCompare.x();
    result(result.rows()-1,2) = quatCompare.y();
    result(result.rows()-1,3) = quatCompare.z();
    result(result.rows()-1,4) = (trans-transNew).x();
    result(result.rows()-1,5) = (trans-transNew).y();
    result(result.rows()-1,6) = (trans-transNew).z();
    result(result.rows()-1,7) = angle;
    result(result.rows()-1,8) = move;
    result(result.rows()-1,9) = 0;
    return false;
}

//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
 * The function main marks the entry point of the program.
 * By default, main has the storage class extern.
 *
 * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
 * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
 * @return the value that was set to exit() (which is 0 if exit() is called via quit()).
 */

int main(int argc, char *argv[])
{
    qInstallMessageHandler(UTILSLIB::ApplicationLogger::customLogWriter);
    QElapsedTimer timer;
    QCoreApplication a(argc, argv);

    // Command Line Parser
    QCommandLineParser parser;
    parser.setApplicationDescription("hpiFit Example");
    parser.addHelpOption();
    qInfo() << "Please download the mne-cpp-test-data folder from Github (mne-tools) into mne-cpp/bin.";
    QCommandLineOption inputOption("fileIn", "The input file <in>.", "in", QCoreApplication::applicationDirPath() + "/mne-cpp-test-data/MEG/sample/test_hpiFit_raw.fif");

    parser.addOption(inputOption);

    parser.process(a);

    // Init data loading and writing
    QFile t_fileIn(parser.value(inputOption));

    FiffRawData raw(t_fileIn);
    QSharedPointer<FiffInfo> pFiffInfo = QSharedPointer<FiffInfo>(new FiffInfo(raw.info));
    FiffCoordTrans devHeadTrans = pFiffInfo->dev_head_t;

    // Set up the reading parameters
    RowVectorXi picks = pFiffInfo->pick_types(true, false, false);

    MatrixXd matData;
    MatrixXd times;

    fiff_int_t from;
    fiff_int_t to;
    fiff_int_t first = raw.first_samp;
    fiff_int_t last = raw.last_samp;

    float dT_sec = 0.1;             // time between hpi fits
    float quantum_sec = 0.2f;       // read and write in 200 ms junks
    fiff_int_t quantum = ceil(quantum_sec*pFiffInfo->sfreq);

//    // create time vector that specifies when to fit
//    int N = ceil((last-first)/quantum);
//    RowVectorXf time = RowVectorXf::LinSpaced(N, 0, N-1) * dT_sec;

    // To fit at specific times outcommend the following block
//    // Read Quaternion File
    MatrixXd pos;
    qInfo() << "Specify the path to your position file (.txt)";
    UTILSLIB::IOUtils::read_eigen_matrix(pos, QCoreApplication::applicationDirPath() + "/mne-cpp-test-data/Result/ref_hpiFit_pos.txt");
    RowVectorXd time = pos.col(0);

    MatrixXd position;              // Position matrix to save quaternions etc.
    MatrixXd result;
    float threshRot = 10;           // in degree
    float threshTrans = 5/1000;     // in m

    // setup informations for HPI fit (VectorView)
    QVector<int> vFreqs {166,154,161,158};
    QVector<double> vGof;
    FiffDigPointSet fittedPointSet;

    // Use SSP + SGM + calibration
    MatrixXd matProjectors = MatrixXd::Identity(pFiffInfo->chs.size(), pFiffInfo->chs.size());

    //Do a copy here because we are going to change the activity flags of the SSP's
    FiffInfo infoTemp = *(pFiffInfo.data());

    //Turn on all SSP
    for(int i = 0; i < infoTemp.projs.size(); ++i) {
        infoTemp.projs[i].active = true;
    }

    //Create the projector for all SSP's on
    infoTemp.make_projector(matProjectors);

    //set columns of matrix to zero depending on bad channels indexes
    for(qint32 j = 0; j < infoTemp.bads.size(); ++j) {
        matProjectors.col(infoTemp.ch_names.indexOf(infoTemp.bads.at(j))).setZero();
    }

    // if debugging files are necessary set bDoDebug = true;
    QString sHPIResourceDir = QCoreApplication::applicationDirPath() + "/HPIFittingDebug";
    bool bDoDebug = false;

    // read and fit
    for(int i = 0; i < time.size(); i++) {
        from = first + time(i)*pFiffInfo->sfreq;
        to = from + quantum;
        if (to > last) {
            to = last;
            qWarning() << "Block size < quantum " << quantum;
        }
        // Reading
        if(!raw.read_raw_segment(matData, times, from, to)) {
            qCritical("error during read_raw_segment");
            return -1;
        }
        qInfo() << "[done]";

        qInfo() << "HPI-Fit...";
        timer.start();
        HPIFit::fitHPI(matData,
                       matProjectors,
                       pFiffInfo->dev_head_t,
                       vFreqs,
                       vGof,
                       fittedPointSet,
                       pFiffInfo,
                       bDoDebug,
                       sHPIResourceDir);
        qInfo() << "The HPI-Fit took" << timer.elapsed() << "milliseconds";
        qInfo() << "[done]";

        writePos(time(i),pFiffInfo,position,vGof);
        if(compareResults(devHeadTrans,pFiffInfo->dev_head_t,threshRot,threshTrans,result)){
            qInfo() << "Big head displacement: dev_head_t has been updated";
        }

    }
    UTILSLIB::IOUtils::write_eigen_matrix(position, QCoreApplication::applicationDirPath() + "/MNE-sample-data/position.txt");
    UTILSLIB::IOUtils::write_eigen_matrix(result, QCoreApplication::applicationDirPath() + "/MNE-sample-data/result.txt");
}
<commit_msg>TEMP: change filepaths for evaluation<commit_after>//=============================================================================================================
/**
 * @file     main.cpp
 * @author   Ruben Dörfel <ruben.doerfel@tu-ilmenau.de>;
 * @version  dev
 * @date     January, 2020
 *
 * @section  LICENSE
 *
 * Copyright (C) 2020, Ruben Dörfel. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
 *       to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief     Example for cHPI fitting on raw data with SSP. The result is written to a .txt file for comparison with MaxFilter's .pos file.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <iostream>
#include <vector>
#include <math.h>

#include <fiff/fiff.h>
#include <fiff/fiff_info.h>
#include <fiff/fiff_dig_point_set.h>
#include <fiff/fiff_cov.h>

#include <inverse/hpiFit/hpifit.h>
#include <inverse/hpiFit/hpifitdata.h>

#include <utils/ioutils.h>
#include <utils/generics/applicationlogger.h>

#include <fwd/fwd_coil_set.h>

//=============================================================================================================
// Qt INCLUDES
//=============================================================================================================

#include <QtCore/QCoreApplication>
#include <QFile>
#include <QCommandLineParser>
#include <QDebug>
#include <QGenericMatrix>
#include <QQuaternion>
#include <QElapsedTimer>

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

using namespace INVERSELIB;
using namespace FIFFLIB;
using namespace Eigen;

//=============================================================================================================
// Member functions
//=============================================================================================================

//=========================================================================================================
/**
 * Store results from dev_Head_t as quaternions in position matrix. The postion matrix is consisten with the MaxFilter output
 *
 * @param[in] time          The corresponding time in the measurement for the fit.
 * @param[in] pFiffInfo     The FiffInfo file from the measurement.
 * @param[in] position      The matrix to store the results
 * @param[in] vGoF          The vector that stores the goodness of fit.
 *
 * ToDo: get correct GoF; vGof that is passed to fitHPI does not represent the actual GoF
 *
 */
void writePos(const float time, QSharedPointer<FiffInfo> pFiffInfo, MatrixXd& position, const QVector<double>& vGoF)
{
    // Write quaternions and time in position matrix. Format is the same like MaxFilter's .pos files.
    QMatrix3x3 rot;

    for(int ir = 0; ir < 3; ir++) {
        for(int ic = 0; ic < 3; ic++) {
            rot(ir,ic) = pFiffInfo->dev_head_t.trans(ir,ic);
        }
    }

    // double error = std::accumulate(vGoF.begin(), vGoF.end(), .0) / vGoF.size();
    QQuaternion quatHPI = QQuaternion::fromRotationMatrix(rot);

    //qDebug() << "quatHPI.x() " << "quatHPI.y() " << "quatHPI.y() " << "trans x " << "trans y " << "trans z " << std::endl;
    //qDebug() << quatHPI.x() << quatHPI.y() << quatHPI.z() << info->dev_head_t.trans(0,3) << info->dev_head_t.trans(1,3) << info->dev_head_t.trans(2,3) << std::endl;

    position.conservativeResize(position.rows()+1, 10);
    position(position.rows()-1,0) = time;
    position(position.rows()-1,1) = quatHPI.x();
    position(position.rows()-1,2) = quatHPI.y();
    position(position.rows()-1,3) = quatHPI.z();
    position(position.rows()-1,4) = pFiffInfo->dev_head_t.trans(0,3);
    position(position.rows()-1,5) = pFiffInfo->dev_head_t.trans(1,3);
    position(position.rows()-1,6) = pFiffInfo->dev_head_t.trans(2,3);
    position(position.rows()-1,7) = 0;
    position(position.rows()-1,8) = 0;
    position(position.rows()-1,9) = 0;
}

//=========================================================================================================
/**
 * Compare new head position with current head position and update dev_head_t if big displacement occured
 *
 * @param[in] devHeadTrans      The device to head transformation matrix to compare to.
 * @param[in] devHeadTransNew   The device to head transformation matrix to be compared.
 * @param[in] treshRot          The threshold for big head rotation in degree
 * @param[in] treshTrans        The threshold for big head movement in m
 *
 * @param[out] state            The status that shows if devHead is updated or not
 *
 */
bool compareResults(FiffCoordTrans& devHeadT, const FiffCoordTrans& devHeadTNew,const float& treshRot,const float& treshTrans, MatrixXd& result)
{
    QMatrix3x3 rot;
    QMatrix3x3 rotNew;

    for(int ir = 0; ir < 3; ir++) {
        for(int ic = 0; ic < 3; ic++) {
            rot(ir,ic) = devHeadT.trans(ir,ic);
            rotNew(ir,ic) = devHeadTNew.trans(ir,ic);
        }
    }

    VectorXf trans = devHeadT.trans.col(3);
    VectorXf transNew = devHeadTNew.trans.col(3);

    QQuaternion quat = QQuaternion::fromRotationMatrix(rot);
    QQuaternion quatNew = QQuaternion::fromRotationMatrix(rotNew);

    // Compare Rotation
    QQuaternion quatCompare;
    float angle;
    QVector3D axis;
    // get rotation between both transformations by multiplying with the inverted quaternion
    quatCompare = quat*quatNew.inverted();
    quatCompare.getAxisAndAngle(&axis,&angle);
    qInfo() << "Displacement angle [degree]: " << angle;

    // Compare translation
    float move = (trans-transNew).norm();
    qInfo() << "Displacement Move [mm]: " << move*1000;

    // write results for debug purpose - quaternions are quatCompare
    result.conservativeResize(result.rows()+1, 10);
    result.conservativeResize(result.rows()+1, 10);
    result(result.rows()-1,0) = 0;
    result(result.rows()-1,1) = quatCompare.x();
    result(result.rows()-1,2) = quatCompare.y();
    result(result.rows()-1,3) = quatCompare.z();
    result(result.rows()-1,4) = (trans-transNew).x();
    result(result.rows()-1,5) = (trans-transNew).y();
    result(result.rows()-1,6) = (trans-transNew).z();
    result(result.rows()-1,7) = angle;
    result(result.rows()-1,8) = move;
    result(result.rows()-1,9) = 0;
    return false;
}

//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
 * The function main marks the entry point of the program.
 * By default, main has the storage class extern.
 *
 * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
 * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
 * @return the value that was set to exit() (which is 0 if exit() is called via quit()).
 */

int main(int argc, char *argv[])
{
    qInstallMessageHandler(UTILSLIB::ApplicationLogger::customLogWriter);
    QElapsedTimer timer;
    QCoreApplication a(argc, argv);

    // Command Line Parser
    QCommandLineParser parser;
    parser.setApplicationDescription("hpiFit Example");
    parser.addHelpOption();
    qInfo() << "Please download the mne-cpp-test-data folder from Github (mne-tools) into mne-cpp/bin.";
    QCommandLineOption inputOption("fileIn", "The input file <in>.", "in", QCoreApplication::applicationDirPath() + "/MNE-sample-data/chpi/raw/sim_move_y_chpi_raw.fif");

    parser.addOption(inputOption);

    parser.process(a);

    // Init data loading and writing
    QFile t_fileIn(parser.value(inputOption));

    FiffRawData raw(t_fileIn);
    QSharedPointer<FiffInfo> pFiffInfo = QSharedPointer<FiffInfo>(new FiffInfo(raw.info));
    FiffCoordTrans devHeadTrans = pFiffInfo->dev_head_t;

    // Set up the reading parameters
    RowVectorXi picks = pFiffInfo->pick_types(true, false, false);

    MatrixXd matData;
    MatrixXd times;

    fiff_int_t from;
    fiff_int_t to;
    fiff_int_t first = raw.first_samp;
    fiff_int_t last = raw.last_samp;

    float dT_sec = 0.1;             // time between hpi fits
    float quantum_sec = 0.2f;       // read and write in 200 ms junks
    fiff_int_t quantum = ceil(quantum_sec*pFiffInfo->sfreq);

//    // create time vector that specifies when to fit
//    int N = ceil((last-first)/quantum);
//    RowVectorXf time = RowVectorXf::LinSpaced(N, 0, N-1) * dT_sec;

    // To fit at specific times outcommend the following block
//    // Read Quaternion File
    MatrixXd pos;
    qInfo() << "Specify the path to your position file (.txt)";
    UTILSLIB::IOUtils::read_eigen_matrix(pos, QCoreApplication::applicationDirPath() + "/MNE-sample-data/chpi/pos/sim_move_y_chpi_pos.txt");
    RowVectorXd time = pos.col(0);

    MatrixXd position;              // Position matrix to save quaternions etc.
    MatrixXd result;
    float threshRot = 10;           // in degree
    float threshTrans = 5/1000;     // in m

    // setup informations for HPI fit (VectorView)
    QVector<int> vFreqs {166,154,161,158};
    QVector<double> vGof;
    FiffDigPointSet fittedPointSet;

    // Use SSP + SGM + calibration
    MatrixXd matProjectors = MatrixXd::Identity(pFiffInfo->chs.size(), pFiffInfo->chs.size());

    //Do a copy here because we are going to change the activity flags of the SSP's
    FiffInfo infoTemp = *(pFiffInfo.data());

    //Turn on all SSP
    for(int i = 0; i < infoTemp.projs.size(); ++i) {
        infoTemp.projs[i].active = true;
    }

    //Create the projector for all SSP's on
    infoTemp.make_projector(matProjectors);

    //set columns of matrix to zero depending on bad channels indexes
    for(qint32 j = 0; j < infoTemp.bads.size(); ++j) {
        matProjectors.col(infoTemp.ch_names.indexOf(infoTemp.bads.at(j))).setZero();
    }

    // if debugging files are necessary set bDoDebug = true;
    QString sHPIResourceDir = QCoreApplication::applicationDirPath() + "/HPIFittingDebug";
    bool bDoDebug = false;

    // read and fit
    for(int i = 0; i < time.size(); i++) {
        from = first + time(i)*pFiffInfo->sfreq;
        to = from + quantum;
        if (to > last) {
            to = last;
            qWarning() << "Block size < quantum " << quantum;
        }
        // Reading
        if(!raw.read_raw_segment(matData, times, from, to)) {
            qCritical("error during read_raw_segment");
            return -1;
        }
        qInfo() << "[done]";

        qInfo() << "HPI-Fit...";
        timer.start();
        HPIFit::fitHPI(matData,
                       matProjectors,
                       pFiffInfo->dev_head_t,
                       vFreqs,
                       vGof,
                       fittedPointSet,
                       pFiffInfo,
                       bDoDebug,
                       sHPIResourceDir);
        qInfo() << "The HPI-Fit took" << timer.elapsed() << "milliseconds";
        qInfo() << "[done]";

        writePos(time(i),pFiffInfo,position,vGof);
        if(compareResults(devHeadTrans,pFiffInfo->dev_head_t,threshRot,threshTrans,result)){
            qInfo() << "Big head displacement: dev_head_t has been updated";
        }

    }
    UTILSLIB::IOUtils::write_eigen_matrix(position, QCoreApplication::applicationDirPath() + "/MNE-sample-data/position.txt");
    UTILSLIB::IOUtils::write_eigen_matrix(result, QCoreApplication::applicationDirPath() + "/MNE-sample-data/result.txt");
}
<|endoftext|>


<commit_before>// Tests of Linux-specific functionality
#ifdef __linux__

#include <sys/types.h>
#include <sys/timerfd.h>
#include <sys/signalfd.h>
#include <poll.h>
#include <signal.h>

#include "capsicum.h"
#include "syscalls.h"
#include "capsicum-test.h"

TEST(Linux, TimerFD) {
  int fd = timerfd_create(CLOCK_MONOTONIC, 0);
  int cap_fd_ro = cap_new(fd, CAP_READ);
  int cap_fd_wo = cap_new(fd, CAP_WRITE);
  int cap_fd_rw = cap_new(fd, CAP_READ|CAP_WRITE);
  int cap_fd_all = cap_new(fd, CAP_READ|CAP_WRITE|CAP_POLL_EVENT);

  struct itimerspec old_ispec;
  struct itimerspec ispec;
  ispec.it_interval.tv_sec = 0;
  ispec.it_interval.tv_nsec = 0;
  ispec.it_value.tv_sec = 0;
  ispec.it_value.tv_nsec = 100000000;  // 100ms
  EXPECT_NOTCAPABLE(timerfd_settime(cap_fd_ro, 0, &ispec, NULL));
  EXPECT_NOTCAPABLE(timerfd_settime(cap_fd_wo, 0, &ispec, &old_ispec));
  EXPECT_OK(timerfd_settime(cap_fd_wo, 0, &ispec, NULL));
  EXPECT_OK(timerfd_settime(cap_fd_rw, 0, &ispec, NULL));
  EXPECT_OK(timerfd_settime(cap_fd_all, 0, &ispec, NULL));

  EXPECT_NOTCAPABLE(timerfd_gettime(cap_fd_wo, &old_ispec));
  EXPECT_OK(timerfd_gettime(cap_fd_ro, &old_ispec));
  EXPECT_OK(timerfd_gettime(cap_fd_rw, &old_ispec));
  EXPECT_OK(timerfd_gettime(cap_fd_all, &old_ispec));

  // To be able to poll() for the timer pop, still need CAP_POLL_EVENT.
  struct pollfd poll_fd;
  for (int ii = 0; ii < 3; ii++) {
    poll_fd.revents = 0;
    poll_fd.events = POLLIN;
    switch (ii) {
    case 0: poll_fd.fd = cap_fd_ro; break;
    case 1: poll_fd.fd = cap_fd_wo; break;
    case 2: poll_fd.fd = cap_fd_rw; break;
    }
    // Poll immediately returns with POLLNVAL
    EXPECT_OK(poll(&poll_fd, 1, 400));
    EXPECT_EQ(0, (poll_fd.revents & POLLIN));
    EXPECT_NE(0, (poll_fd.revents & POLLNVAL));
  }

  poll_fd.fd = cap_fd_all;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_NE(0, (poll_fd.revents & POLLIN));
  EXPECT_EQ(0, (poll_fd.revents & POLLNVAL));

  EXPECT_OK(timerfd_gettime(cap_fd_all, &old_ispec));
  EXPECT_EQ(0, old_ispec.it_value.tv_sec);
  EXPECT_EQ(0, old_ispec.it_value.tv_nsec);
  EXPECT_EQ(0, old_ispec.it_interval.tv_sec);
  EXPECT_EQ(0, old_ispec.it_interval.tv_nsec);

  close(cap_fd_all);
  close(cap_fd_rw);
  close(cap_fd_wo);
  close(cap_fd_ro);
  close(fd);
}

FORK_TEST(Linux, SignalFD) {
  pid_t me = getpid();
  sigset_t mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGUSR1);

  // Block signals before registering against a new signal FD.
  EXPECT_OK(sigprocmask(SIG_BLOCK, &mask, NULL));
  int fd = signalfd(-1, &mask, 0);
  EXPECT_OK(fd);

  // Various capability variants.
  int cap_fd_none = cap_new(fd, CAP_WRITE|CAP_SEEK);
  int cap_fd_read = cap_new(fd, CAP_READ|CAP_SEEK);
  int cap_fd_sig = cap_new(fd, CAP_FSIGNAL);
  int cap_fd_sig_read = cap_new(fd, CAP_FSIGNAL|CAP_READ|CAP_SEEK);
  int cap_fd_all = cap_new(fd, CAP_FSIGNAL|CAP_READ|CAP_SEEK|CAP_POLL_EVENT);

  struct signalfd_siginfo fdsi;

  // Need CAP_READ to read the signal information
  kill(me, SIGUSR1);
  EXPECT_NOTCAPABLE(read(cap_fd_none, &fdsi, sizeof(struct signalfd_siginfo)));
  EXPECT_NOTCAPABLE(read(cap_fd_sig, &fdsi, sizeof(struct signalfd_siginfo)));
  int len = read(cap_fd_read, &fdsi, sizeof(struct signalfd_siginfo));
  EXPECT_OK(len);
  EXPECT_EQ(sizeof(struct signalfd_siginfo), (size_t)len);
  EXPECT_EQ(SIGUSR1, (int)fdsi.ssi_signo);

  // Need CAP_FSIGNAL to modify the signal mask.
  sigemptyset(&mask);
  sigaddset(&mask, SIGUSR1);
  sigaddset(&mask, SIGUSR2);
  EXPECT_OK(sigprocmask(SIG_BLOCK, &mask, NULL));
  EXPECT_NOTCAPABLE(signalfd(cap_fd_none, &mask, 0));
  EXPECT_NOTCAPABLE(signalfd(cap_fd_read, &mask, 0));
  EXPECT_EQ(cap_fd_sig, signalfd(cap_fd_sig, &mask, 0));

  // Need CAP_POLL_EVENT to get notification of a signal in poll(2).
  kill(me, SIGUSR2);

  struct pollfd poll_fd;
  poll_fd.revents = 0;
  poll_fd.events = POLLIN;
  poll_fd.fd = cap_fd_sig_read;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_EQ(0, (poll_fd.revents & POLLIN));
  EXPECT_NE(0, (poll_fd.revents & POLLNVAL));

  poll_fd.fd = cap_fd_all;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_NE(0, (poll_fd.revents & POLLIN));
  EXPECT_EQ(0, (poll_fd.revents & POLLNVAL));
}

#else
void noop() {}
#endif
<commit_msg>Add (Linux-specific) simple eventfd test<commit_after>// Tests of Linux-specific functionality
#ifdef __linux__

#include <sys/types.h>
#include <sys/timerfd.h>
#include <sys/signalfd.h>
#include <sys/eventfd.h>
#include <poll.h>
#include <signal.h>

#include "capsicum.h"
#include "syscalls.h"
#include "capsicum-test.h"

TEST(Linux, TimerFD) {
  int fd = timerfd_create(CLOCK_MONOTONIC, 0);
  int cap_fd_ro = cap_new(fd, CAP_READ);
  int cap_fd_wo = cap_new(fd, CAP_WRITE);
  int cap_fd_rw = cap_new(fd, CAP_READ|CAP_WRITE);
  int cap_fd_all = cap_new(fd, CAP_READ|CAP_WRITE|CAP_POLL_EVENT);

  struct itimerspec old_ispec;
  struct itimerspec ispec;
  ispec.it_interval.tv_sec = 0;
  ispec.it_interval.tv_nsec = 0;
  ispec.it_value.tv_sec = 0;
  ispec.it_value.tv_nsec = 100000000;  // 100ms
  EXPECT_NOTCAPABLE(timerfd_settime(cap_fd_ro, 0, &ispec, NULL));
  EXPECT_NOTCAPABLE(timerfd_settime(cap_fd_wo, 0, &ispec, &old_ispec));
  EXPECT_OK(timerfd_settime(cap_fd_wo, 0, &ispec, NULL));
  EXPECT_OK(timerfd_settime(cap_fd_rw, 0, &ispec, NULL));
  EXPECT_OK(timerfd_settime(cap_fd_all, 0, &ispec, NULL));

  EXPECT_NOTCAPABLE(timerfd_gettime(cap_fd_wo, &old_ispec));
  EXPECT_OK(timerfd_gettime(cap_fd_ro, &old_ispec));
  EXPECT_OK(timerfd_gettime(cap_fd_rw, &old_ispec));
  EXPECT_OK(timerfd_gettime(cap_fd_all, &old_ispec));

  // To be able to poll() for the timer pop, still need CAP_POLL_EVENT.
  struct pollfd poll_fd;
  for (int ii = 0; ii < 3; ii++) {
    poll_fd.revents = 0;
    poll_fd.events = POLLIN;
    switch (ii) {
    case 0: poll_fd.fd = cap_fd_ro; break;
    case 1: poll_fd.fd = cap_fd_wo; break;
    case 2: poll_fd.fd = cap_fd_rw; break;
    }
    // Poll immediately returns with POLLNVAL
    EXPECT_OK(poll(&poll_fd, 1, 400));
    EXPECT_EQ(0, (poll_fd.revents & POLLIN));
    EXPECT_NE(0, (poll_fd.revents & POLLNVAL));
  }

  poll_fd.fd = cap_fd_all;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_NE(0, (poll_fd.revents & POLLIN));
  EXPECT_EQ(0, (poll_fd.revents & POLLNVAL));

  EXPECT_OK(timerfd_gettime(cap_fd_all, &old_ispec));
  EXPECT_EQ(0, old_ispec.it_value.tv_sec);
  EXPECT_EQ(0, old_ispec.it_value.tv_nsec);
  EXPECT_EQ(0, old_ispec.it_interval.tv_sec);
  EXPECT_EQ(0, old_ispec.it_interval.tv_nsec);

  close(cap_fd_all);
  close(cap_fd_rw);
  close(cap_fd_wo);
  close(cap_fd_ro);
  close(fd);
}

FORK_TEST(Linux, SignalFD) {
  pid_t me = getpid();
  sigset_t mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGUSR1);

  // Block signals before registering against a new signal FD.
  EXPECT_OK(sigprocmask(SIG_BLOCK, &mask, NULL));
  int fd = signalfd(-1, &mask, 0);
  EXPECT_OK(fd);

  // Various capability variants.
  int cap_fd_none = cap_new(fd, CAP_WRITE|CAP_SEEK);
  int cap_fd_read = cap_new(fd, CAP_READ|CAP_SEEK);
  int cap_fd_sig = cap_new(fd, CAP_FSIGNAL);
  int cap_fd_sig_read = cap_new(fd, CAP_FSIGNAL|CAP_READ|CAP_SEEK);
  int cap_fd_all = cap_new(fd, CAP_FSIGNAL|CAP_READ|CAP_SEEK|CAP_POLL_EVENT);

  struct signalfd_siginfo fdsi;

  // Need CAP_READ to read the signal information
  kill(me, SIGUSR1);
  EXPECT_NOTCAPABLE(read(cap_fd_none, &fdsi, sizeof(struct signalfd_siginfo)));
  EXPECT_NOTCAPABLE(read(cap_fd_sig, &fdsi, sizeof(struct signalfd_siginfo)));
  int len = read(cap_fd_read, &fdsi, sizeof(struct signalfd_siginfo));
  EXPECT_OK(len);
  EXPECT_EQ(sizeof(struct signalfd_siginfo), (size_t)len);
  EXPECT_EQ(SIGUSR1, (int)fdsi.ssi_signo);

  // Need CAP_FSIGNAL to modify the signal mask.
  sigemptyset(&mask);
  sigaddset(&mask, SIGUSR1);
  sigaddset(&mask, SIGUSR2);
  EXPECT_OK(sigprocmask(SIG_BLOCK, &mask, NULL));
  EXPECT_NOTCAPABLE(signalfd(cap_fd_none, &mask, 0));
  EXPECT_NOTCAPABLE(signalfd(cap_fd_read, &mask, 0));
  EXPECT_EQ(cap_fd_sig, signalfd(cap_fd_sig, &mask, 0));

  // Need CAP_POLL_EVENT to get notification of a signal in poll(2).
  kill(me, SIGUSR2);

  struct pollfd poll_fd;
  poll_fd.revents = 0;
  poll_fd.events = POLLIN;
  poll_fd.fd = cap_fd_sig_read;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_EQ(0, (poll_fd.revents & POLLIN));
  EXPECT_NE(0, (poll_fd.revents & POLLNVAL));

  poll_fd.fd = cap_fd_all;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_NE(0, (poll_fd.revents & POLLIN));
  EXPECT_EQ(0, (poll_fd.revents & POLLNVAL));
}

TEST(Linux, EventFD) {
  int fd = eventfd(0, 0);
  EXPECT_OK(fd);
  int cap_ro = cap_new(fd, CAP_READ|CAP_SEEK);
  int cap_wo = cap_new(fd, CAP_WRITE|CAP_SEEK);
  int cap_rw = cap_new(fd, CAP_READ|CAP_WRITE|CAP_SEEK);
  int cap_all = cap_new(fd, CAP_READ|CAP_WRITE|CAP_SEEK|CAP_POLL_EVENT);

  pid_t child = fork();
  if (child == 0) {
    // Child: write counter to eventfd
    uint64_t u = 42;
    EXPECT_NOTCAPABLE(write(cap_ro, &u, sizeof(u)));
    EXPECT_OK(write(cap_wo, &u, sizeof(u)));
    exit(HasFailure());
  }

  sleep(1);  // Allow child to write

  struct pollfd poll_fd;
  poll_fd.revents = 0;
  poll_fd.events = POLLIN;
  poll_fd.fd = cap_rw;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_EQ(0, (poll_fd.revents & POLLIN));
  EXPECT_NE(0, (poll_fd.revents & POLLNVAL));

  poll_fd.fd = cap_all;
  EXPECT_OK(poll(&poll_fd, 1, 400));
  EXPECT_NE(0, (poll_fd.revents & POLLIN));
  EXPECT_EQ(0, (poll_fd.revents & POLLNVAL));

  uint64_t u;
  EXPECT_NOTCAPABLE(read(cap_wo, &u, sizeof(u)));
  EXPECT_OK(read(cap_ro, &u, sizeof(u)));
  EXPECT_EQ(42, (int)u);

  // Wait for the child.
  int status;
  EXPECT_EQ(child, waitpid(child, &status, 0));
  int rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
  EXPECT_EQ(0, rc);

  close(cap_all);
  close(cap_rw);
  close(cap_wo);
  close(cap_ro);
  close(fd);
}

#else
void noop() {}
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2017 Jackal Engine, MIT License.
#pragma once

#include "Core/Platform/JTypes.hpp"
#include "Core/Platform/Platform.hpp"
#include "Core/Structure/JString.hpp"

#include <string>
#include <type_traits>

// TODO(): Figure out a better way than to include unecessary headers
// just for windows.
#if JACKAL_PLATFORM == JACKAL_WINDOWS
 #include <locale>
 #include <codecvt>
#endif

namespace jackal {

class JStringUtils {
public:

  // TODO(): Remove heap allocation from these functions!
  static void UTF8To16(const uint8 *input, uint16 *output);
  static void UTF16To8(const uint16 *input, uint8 *output);
  static void UTF16To32(const uint16 *input, uint32 *output);
  static void UTF32To16(const uint32 *input, uint16 *output);

  // Get the string size of the tchar.
  static size_t GetStringSize(const tchar *src);
  static tchar *AllocateStringSize(size_t size);

  static void StringCopy(tchar *dest, const tchar *src);

  template<typename Type>
  static JString ToString(Type n) {
    //static_assert<std::is_same<decltype(Type), tchar>::value, "No need to convert tchar");
    JString str = TO_JSTRING(n);
    return str;
  }

#if JACKAL_PLATFORM == JACKAL_WINDOWS
  template<>
  static JString ToString(char *n) {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring wide = converter.from_bytes(n);
    return wide;
  }
#endif
};
} // jackal
<commit_msg>Another fix for linux char to JString conversion<commit_after>// Copyright (c) 2017 Jackal Engine, MIT License.
#pragma once

#include "Core/Platform/JTypes.hpp"
#include "Core/Platform/Platform.hpp"
#include "Core/Structure/JString.hpp"

#include <string>
#include <type_traits>

// TODO(): Figure out a better way than to include unecessary headers
// just for windows.
#if JACKAL_PLATFORM == JACKAL_WINDOWS
 #include <locale>
 #include <codecvt>
#endif

namespace jackal {

class JStringUtils {
public:

  // TODO(): Remove heap allocation from these functions!
  static void UTF8To16(const uint8 *input, uint16 *output);
  static void UTF16To8(const uint16 *input, uint8 *output);
  static void UTF16To32(const uint16 *input, uint32 *output);
  static void UTF32To16(const uint32 *input, uint16 *output);

  // Get the string size of the tchar.
  static size_t GetStringSize(const tchar *src);
  static tchar *AllocateStringSize(size_t size);

  static void StringCopy(tchar *dest, const tchar *src);

  template<typename Type>
  static JString ToString(Type n) {
    //static_assert<std::is_same<decltype(Type), tchar>::value, "No need to convert tchar");
    JString str = TO_JSTRING(n);
    return str;
  }

#if JACKAL_PLATFORM == JACKAL_WINDOWS
  template<>
  static JString ToString(char *n) {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring wide = converter.from_bytes(n);
    return wide;
  }
#else
  template<>
  static JString ToString(char* n) {
    return std::string(n);
  }
#endif
};
} // jackal
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of the Qt Build Suite
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file.
** Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**************************************************************************/
#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
#include <QtCore/QStringList>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
#include <QtCore/QSettings>

#include <tools/platform.h>

using namespace qbs;

static QString searchPath(const QString &path, const QString &me)
{
    //TODO: use native seperator
    foreach (const QString &ppath, path.split(":")) {
        if (QFileInfo(ppath +  "/"  +  me).exists()) {
            return QDir::cleanPath(ppath +  "/"  +  me);
        }
    }
    return QString();
}

static QString qsystem(const QString &exe, const QStringList &args = QStringList())
{
    QProcess p;
    p.setProcessChannelMode(QProcess::MergedChannels);
    p.start(exe, args);
    p.waitForStarted();
    p.waitForFinished();
    return QString::fromLocal8Bit(p.readAll());
}

static int specific_probe(const QString &settingsPath,
                          QHash<QString, Platform::Ptr> &platforms,
                          QString cc,
                          bool printComfortingMessage = false)
{
    QTextStream qstdout(stdout);

    QString toolchainType;
    if(cc.contains("clang"))
        toolchainType = "clang";
    else if (cc.contains("gcc"))
        toolchainType = "gcc";

    QString path       = QString::fromLocal8Bit(qgetenv("PATH"));
    QString cxx        = QString::fromLocal8Bit(qgetenv("CXX"));
    QString ld         = QString::fromLocal8Bit(qgetenv("LD"));
    QString cflags     = QString::fromLocal8Bit(qgetenv("CFLAGS"));
    QString cxxflags   = QString::fromLocal8Bit(qgetenv("CXXFLAGS"));
    QString ldflags    = QString::fromLocal8Bit(qgetenv("LDFLAGS"));
    QString cross      = QString::fromLocal8Bit(qgetenv("CROSS_COMPILE"));
    QString arch       = QString::fromLocal8Bit(qgetenv("ARCH"));

    QString pathToGcc;
    QString architecture;
    QString endianness;

    QString name;
    QString sysroot;

    QString uname = qsystem("uname", QStringList() << "-m").simplified();

    if (arch.isEmpty())
        arch = uname;

#ifdef Q_OS_MAC
    // HACK: "uname -m" reports "i386" but "gcc -dumpmachine" reports "i686" on MacOS.
    if (arch == "i386")
        arch = "i686";
#endif

    if (ld.isEmpty())
        ld = "ld";
    if (cxx.isEmpty()) {
        if (toolchainType == "gcc")
            cxx = "g++";
        else if(toolchainType == "clang")
            cxx = "clang++";
    }
    if(!cross.isEmpty() && !cc.startsWith("/")) {
        pathToGcc = searchPath(path, cross + cc);
        if (QFileInfo(pathToGcc).exists()) {
            if (!cc.contains(cross))
                cc.prepend(cross);
            if (!cxx.contains(cross))
                cxx.prepend(cross);
            if (!ld.contains(cross))
                ld.prepend(cross);
        }
    }
    if (cc.startsWith("/"))
        pathToGcc = cc;
    else
        pathToGcc = searchPath(path, cc);

    if (!QFileInfo(pathToGcc).exists()) {
        fprintf(stderr, "Cannot find %s.", qPrintable(cc));
        if (printComfortingMessage)
            fprintf(stderr, " But that's not a problem. I've already found other platforms.\n");
        else
            fprintf(stderr, "\n");
        return 1;
    }

    Platform::Ptr s;
    foreach (Platform::Ptr p, platforms.values()) {
        QString path = p->settings.value(Platform::internalKey() + "/completeccpath").toString();
        if (path == pathToGcc) {
            name = p->name;
            s = p;
            name = s->name;
            break;
        }
    }

    QString compilerTriplet = qsystem(pathToGcc, QStringList() << "-dumpmachine").simplified();
    QStringList compilerTripletl = compilerTriplet.split('-');
    if (compilerTripletl.count() < 2 ||
            !(compilerTripletl.at(0).contains(QRegExp(".86")) ||
              compilerTripletl.at(0).contains("arm") )
            ) {
        qDebug("detected %s , but i don't understand it's architecture: %s",
                qPrintable(pathToGcc), qPrintable(compilerTriplet));
                return 12;
    }

    architecture = compilerTripletl.at(0);
    if (architecture.contains("arm")) {
        endianness = "big-endian";
    } else {
        endianness = "little-endian";
    }

    QStringList pathToGccL = pathToGcc.split('/');
    QString compilerName = pathToGccL.takeLast().replace(cc, cxx);

    if (cflags.contains("--sysroot")) {
        QStringList flagl = cflags.split(' ');

        bool nextitis = false;
        foreach (const QString &flag, flagl) {
            if (nextitis) {
                sysroot = flag;
                break;
            }
            if (flag == "--sysroot") {
                nextitis = true;
            }
        }
    }

    qstdout << "==> " << (s?"reconfiguring " + name :"detected")
            << " " << pathToGcc << "\n"
            << "     triplet:  " << compilerTriplet << "\n"
            << "     arch:     " << architecture << "\n"
            << "     bin:      " << pathToGccL.join("/") << "\n"
            << "     cc:       " << cc << "\n"
            ;

    if (!cxx.isEmpty())
       qstdout << "     cxx:      " << cxx << "\n";
    if (!ld.isEmpty())
       qstdout << "     ld:       " << ld << "\n";

    if (!sysroot.isEmpty())
        qstdout << "     sysroot:  " << sysroot << "\n";
    if (!cflags.isEmpty())
            qstdout << "     CFLAGS:   " << cflags << "\n";
    if (!cxxflags.isEmpty())
            qstdout << "     CXXFLAGS: " << cxxflags << "\n";
    if (!ldflags.isEmpty())
            qstdout << "     CXXFLAGS: " << ldflags << "\n";

    qstdout  << flush;

    if (!s) {
        if (name.isEmpty())
            name = toolchainType;
       s = Platform::Ptr(new Platform(name, settingsPath + "/" + name));
    }

    // fixme should be cpp.toolchain
    // also there is no toolchain:clang
    s->settings.setValue("toolchain", "gcc");
    s->settings.setValue(Platform::internalKey() + "/completeccpath", pathToGcc);
    s->settings.setValue(Platform::internalKey() + "/target-triplet", compilerTriplet);
    s->settings.setValue("architecture", architecture);
    s->settings.setValue("endianness", endianness);

#if defined(Q_OS_MAC)
    s->settings.setValue("targetOS", "mac");
#elif defined(Q_OS_LINUX)
    s->settings.setValue("targetOS", "linux");
#else
    s->settings.setValue("targetOS", "unknown"); //fixme
#endif

    if (compilerName.contains('-')) {
        QStringList nl = compilerName.split('-');
        s->settings.setValue("cpp/compilerName", nl.takeLast());
        s->settings.setValue("cpp/toolchainPrefix", nl.join("-") + '-');
    } else {
        s->settings.setValue("cpp/compilerName", compilerName);
    }
    s->settings.setValue("cpp/toolchainInstallPath", pathToGccL.join("/"));

    if (!cross.isEmpty())
        s->settings.setValue("environment/CROSS_COMPILE", cross);
    if (!cflags.isEmpty())
        s->settings.setValue("environment/CFLAGS", cflags);
    if (!cxxflags.isEmpty())
        s->settings.setValue("environment/CXXFLAGS", cxxflags);
    if (!ldflags.isEmpty())
        s->settings.setValue("environment/LDFLAGS", ldflags);

    platforms.insert(s->name, s);
    return 0;
}

#ifdef Q_OS_WIN
static void msvcProbe(const QString &settingsPath, QHash<QString, Platform::Ptr> &platforms)
{
    QTextStream qstdout(stdout);

    QString vcInstallDir = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("VCINSTALLDIR")));
    if (vcInstallDir.endsWith('/'))
        vcInstallDir.chop(1);
    if (vcInstallDir.isEmpty())
        return;
    QString winSDKPath = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("WindowsSdkDir")));
    if (winSDKPath.endsWith('/'))
        winSDKPath.chop(1);
    QString clOutput = qsystem(vcInstallDir + "/bin/cl.exe");
    if (clOutput.isEmpty())
        return;

    QRegExp rex("C/C\\+\\+ Optimizing Compiler Version ((\\d|\\.)+) for ((x|\\d)+)");
    int idx = rex.indexIn(clOutput);
    if (idx < 0)
        return;

    QStringList clVersion = rex.cap(1).split(".");
    if (clVersion.isEmpty())
        return;
    QString clArch = rex.cap(3);
    QString msvcVersion = "msvc";
    switch (clVersion.first().toInt()) {
    case 14:
        msvcVersion += "2005";
        break;
    case 15:
        msvcVersion += "2008";
        break;
    case 16:
        msvcVersion += "2010";
        break;
    default:
        return;
    }

    QString vsInstallDir = vcInstallDir;
    idx = vsInstallDir.lastIndexOf("/");
    if (idx < 0)
        return;
    vsInstallDir.truncate(idx);

    Platform::Ptr platform = platforms.value(msvcVersion);
    if (!platform) {
       platform = Platform::Ptr(new Platform(msvcVersion, settingsPath + "/" + msvcVersion));
       platforms.insert(platform->name, platform);
    }
    platform->settings.setValue("targetOS", "windows");
    platform->settings.setValue("cpp/toolchainInstallPath", vsInstallDir);
    platform->settings.setValue("toolchain", "msvc");
    platform->settings.setValue("cpp/windowsSDKPath", winSDKPath);
    qstdout << "Detected platform " << msvcVersion << " for " << clArch << ".\n";
    qstdout << "When building projects, the architecture can be chosen by passing\narchitecture:x86 or architecture:x86_64 to qbs.\n";
}

static void mingwProbe(const QString &settingsPath, QHash<QString, Platform::Ptr> &platforms)
{
    QString mingwPath;
    QString mingwBinPath;
    QString gccPath;
    QByteArray envPath = qgetenv("PATH");
    foreach (const QByteArray &dir, envPath.split(';')) {
        QFileInfo fi(dir + "/gcc.exe");
        if (fi.exists()) {
            mingwPath = QFileInfo(dir + "/..").canonicalFilePath();
            gccPath = fi.absoluteFilePath();
            mingwBinPath = fi.absolutePath();
            break;
        }
    }
    if (gccPath.isEmpty())
        return;
    QProcess process;
    process.start(gccPath, QStringList() << "-dumpmachine");
    if (!process.waitForStarted()) {
        fprintf(stderr, "Could not start \"gcc -dumpmachine\".\n");
        return;
    }
    process.waitForFinished(-1);
    QByteArray gccMachineName = process.readAll().trimmed();
    if (gccMachineName != "mingw32" && gccMachineName != "mingw64") {
        fprintf(stderr, "Detected gcc platform '%s' is not supported.\n", gccMachineName.data());
        return;
    }

    Platform::Ptr platform = platforms.value(gccMachineName);
    printf("Platform '%s' detected in '%s'.", gccMachineName.data(), qPrintable(QDir::toNativeSeparators(mingwPath)));
    if (!platform) {
       platform = Platform::Ptr(new Platform(gccMachineName, settingsPath + "/" + gccMachineName));
       platforms.insert(platform->name, platform);
    }
    platform->settings.setValue("targetOS", "windows");
    platform->settings.setValue("cpp/toolchainInstallPath", QDir::toNativeSeparators(mingwBinPath));
    platform->settings.setValue("toolchain", "mingw");
}
#endif

int probe(const QString &settingsPath, QHash<QString, Platform::Ptr> &platforms)
{
#ifdef Q_OS_WIN
    msvcProbe(settingsPath, platforms);
    mingwProbe(settingsPath, platforms);
#else
    QString cc = QString::fromLocal8Bit(qgetenv("CC"));
    if (cc.isEmpty()) {
        bool somethingFound = false;
        if (specific_probe(settingsPath, platforms, "gcc") == 0)
            somethingFound = true;
        specific_probe(settingsPath, platforms, "clang", somethingFound);
    } else {
        specific_probe(settingsPath, platforms, cc);
    }
#endif
    if (platforms.isEmpty())
        fprintf(stderr, "Could not detect any platforms.\n");
    return 0;
}
<commit_msg>fix detection of localized MSVC versions<commit_after>/**************************************************************************
**
** This file is part of the Qt Build Suite
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file.
** Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**************************************************************************/
#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
#include <QtCore/QStringList>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
#include <QtCore/QSettings>

#include <tools/platform.h>

using namespace qbs;

static QString searchPath(const QString &path, const QString &me)
{
    //TODO: use native seperator
    foreach (const QString &ppath, path.split(":")) {
        if (QFileInfo(ppath +  "/"  +  me).exists()) {
            return QDir::cleanPath(ppath +  "/"  +  me);
        }
    }
    return QString();
}

static QString qsystem(const QString &exe, const QStringList &args = QStringList())
{
    QProcess p;
    p.setProcessChannelMode(QProcess::MergedChannels);
    p.start(exe, args);
    p.waitForStarted();
    p.waitForFinished();
    return QString::fromLocal8Bit(p.readAll());
}

static int specific_probe(const QString &settingsPath,
                          QHash<QString, Platform::Ptr> &platforms,
                          QString cc,
                          bool printComfortingMessage = false)
{
    QTextStream qstdout(stdout);

    QString toolchainType;
    if(cc.contains("clang"))
        toolchainType = "clang";
    else if (cc.contains("gcc"))
        toolchainType = "gcc";

    QString path       = QString::fromLocal8Bit(qgetenv("PATH"));
    QString cxx        = QString::fromLocal8Bit(qgetenv("CXX"));
    QString ld         = QString::fromLocal8Bit(qgetenv("LD"));
    QString cflags     = QString::fromLocal8Bit(qgetenv("CFLAGS"));
    QString cxxflags   = QString::fromLocal8Bit(qgetenv("CXXFLAGS"));
    QString ldflags    = QString::fromLocal8Bit(qgetenv("LDFLAGS"));
    QString cross      = QString::fromLocal8Bit(qgetenv("CROSS_COMPILE"));
    QString arch       = QString::fromLocal8Bit(qgetenv("ARCH"));

    QString pathToGcc;
    QString architecture;
    QString endianness;

    QString name;
    QString sysroot;

    QString uname = qsystem("uname", QStringList() << "-m").simplified();

    if (arch.isEmpty())
        arch = uname;

#ifdef Q_OS_MAC
    // HACK: "uname -m" reports "i386" but "gcc -dumpmachine" reports "i686" on MacOS.
    if (arch == "i386")
        arch = "i686";
#endif

    if (ld.isEmpty())
        ld = "ld";
    if (cxx.isEmpty()) {
        if (toolchainType == "gcc")
            cxx = "g++";
        else if(toolchainType == "clang")
            cxx = "clang++";
    }
    if(!cross.isEmpty() && !cc.startsWith("/")) {
        pathToGcc = searchPath(path, cross + cc);
        if (QFileInfo(pathToGcc).exists()) {
            if (!cc.contains(cross))
                cc.prepend(cross);
            if (!cxx.contains(cross))
                cxx.prepend(cross);
            if (!ld.contains(cross))
                ld.prepend(cross);
        }
    }
    if (cc.startsWith("/"))
        pathToGcc = cc;
    else
        pathToGcc = searchPath(path, cc);

    if (!QFileInfo(pathToGcc).exists()) {
        fprintf(stderr, "Cannot find %s.", qPrintable(cc));
        if (printComfortingMessage)
            fprintf(stderr, " But that's not a problem. I've already found other platforms.\n");
        else
            fprintf(stderr, "\n");
        return 1;
    }

    Platform::Ptr s;
    foreach (Platform::Ptr p, platforms.values()) {
        QString path = p->settings.value(Platform::internalKey() + "/completeccpath").toString();
        if (path == pathToGcc) {
            name = p->name;
            s = p;
            name = s->name;
            break;
        }
    }

    QString compilerTriplet = qsystem(pathToGcc, QStringList() << "-dumpmachine").simplified();
    QStringList compilerTripletl = compilerTriplet.split('-');
    if (compilerTripletl.count() < 2 ||
            !(compilerTripletl.at(0).contains(QRegExp(".86")) ||
              compilerTripletl.at(0).contains("arm") )
            ) {
        qDebug("detected %s , but i don't understand it's architecture: %s",
                qPrintable(pathToGcc), qPrintable(compilerTriplet));
                return 12;
    }

    architecture = compilerTripletl.at(0);
    if (architecture.contains("arm")) {
        endianness = "big-endian";
    } else {
        endianness = "little-endian";
    }

    QStringList pathToGccL = pathToGcc.split('/');
    QString compilerName = pathToGccL.takeLast().replace(cc, cxx);

    if (cflags.contains("--sysroot")) {
        QStringList flagl = cflags.split(' ');

        bool nextitis = false;
        foreach (const QString &flag, flagl) {
            if (nextitis) {
                sysroot = flag;
                break;
            }
            if (flag == "--sysroot") {
                nextitis = true;
            }
        }
    }

    qstdout << "==> " << (s?"reconfiguring " + name :"detected")
            << " " << pathToGcc << "\n"
            << "     triplet:  " << compilerTriplet << "\n"
            << "     arch:     " << architecture << "\n"
            << "     bin:      " << pathToGccL.join("/") << "\n"
            << "     cc:       " << cc << "\n"
            ;

    if (!cxx.isEmpty())
       qstdout << "     cxx:      " << cxx << "\n";
    if (!ld.isEmpty())
       qstdout << "     ld:       " << ld << "\n";

    if (!sysroot.isEmpty())
        qstdout << "     sysroot:  " << sysroot << "\n";
    if (!cflags.isEmpty())
            qstdout << "     CFLAGS:   " << cflags << "\n";
    if (!cxxflags.isEmpty())
            qstdout << "     CXXFLAGS: " << cxxflags << "\n";
    if (!ldflags.isEmpty())
            qstdout << "     CXXFLAGS: " << ldflags << "\n";

    qstdout  << flush;

    if (!s) {
        if (name.isEmpty())
            name = toolchainType;
       s = Platform::Ptr(new Platform(name, settingsPath + "/" + name));
    }

    // fixme should be cpp.toolchain
    // also there is no toolchain:clang
    s->settings.setValue("toolchain", "gcc");
    s->settings.setValue(Platform::internalKey() + "/completeccpath", pathToGcc);
    s->settings.setValue(Platform::internalKey() + "/target-triplet", compilerTriplet);
    s->settings.setValue("architecture", architecture);
    s->settings.setValue("endianness", endianness);

#if defined(Q_OS_MAC)
    s->settings.setValue("targetOS", "mac");
#elif defined(Q_OS_LINUX)
    s->settings.setValue("targetOS", "linux");
#else
    s->settings.setValue("targetOS", "unknown"); //fixme
#endif

    if (compilerName.contains('-')) {
        QStringList nl = compilerName.split('-');
        s->settings.setValue("cpp/compilerName", nl.takeLast());
        s->settings.setValue("cpp/toolchainPrefix", nl.join("-") + '-');
    } else {
        s->settings.setValue("cpp/compilerName", compilerName);
    }
    s->settings.setValue("cpp/toolchainInstallPath", pathToGccL.join("/"));

    if (!cross.isEmpty())
        s->settings.setValue("environment/CROSS_COMPILE", cross);
    if (!cflags.isEmpty())
        s->settings.setValue("environment/CFLAGS", cflags);
    if (!cxxflags.isEmpty())
        s->settings.setValue("environment/CXXFLAGS", cxxflags);
    if (!ldflags.isEmpty())
        s->settings.setValue("environment/LDFLAGS", ldflags);

    platforms.insert(s->name, s);
    return 0;
}

#ifdef Q_OS_WIN
static void msvcProbe(const QString &settingsPath, QHash<QString, Platform::Ptr> &platforms)
{
    QTextStream qstdout(stdout);

    QString vcInstallDir = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("VCINSTALLDIR")));
    if (vcInstallDir.endsWith('/'))
        vcInstallDir.chop(1);
    if (vcInstallDir.isEmpty())
        return;
    QString winSDKPath = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("WindowsSdkDir")));
    if (winSDKPath.endsWith('/'))
        winSDKPath.chop(1);
    QString clOutput = qsystem(vcInstallDir + "/bin/cl.exe");
    if (clOutput.isEmpty())
        return;

    QRegExp rex("C/C\\+\\+ .+ Version ((?:\\d|\\.)+) \\w+ ((?:x|\\d)+)");
    int idx = rex.indexIn(clOutput);
    if (idx < 0)
        return;

    QStringList clVersion = rex.cap(1).split(".");
    if (clVersion.isEmpty())
        return;
    QString clArch = rex.cap(2);
    QString msvcVersion = "msvc";
    switch (clVersion.first().toInt()) {
    case 14:
        msvcVersion += "2005";
        break;
    case 15:
        msvcVersion += "2008";
        break;
    case 16:
        msvcVersion += "2010";
        break;
    default:
        return;
    }

    QString vsInstallDir = vcInstallDir;
    idx = vsInstallDir.lastIndexOf("/");
    if (idx < 0)
        return;
    vsInstallDir.truncate(idx);

    Platform::Ptr platform = platforms.value(msvcVersion);
    if (!platform) {
       platform = Platform::Ptr(new Platform(msvcVersion, settingsPath + "/" + msvcVersion));
       platforms.insert(platform->name, platform);
    }
    platform->settings.setValue("targetOS", "windows");
    platform->settings.setValue("cpp/toolchainInstallPath", vsInstallDir);
    platform->settings.setValue("toolchain", "msvc");
    platform->settings.setValue("cpp/windowsSDKPath", winSDKPath);
    qstdout << "Detected platform " << msvcVersion << " for " << clArch << ".\n";
    qstdout << "When building projects, the architecture can be chosen by passing\narchitecture:x86 or architecture:x86_64 to qbs.\n";
}

static void mingwProbe(const QString &settingsPath, QHash<QString, Platform::Ptr> &platforms)
{
    QString mingwPath;
    QString mingwBinPath;
    QString gccPath;
    QByteArray envPath = qgetenv("PATH");
    foreach (const QByteArray &dir, envPath.split(';')) {
        QFileInfo fi(dir + "/gcc.exe");
        if (fi.exists()) {
            mingwPath = QFileInfo(dir + "/..").canonicalFilePath();
            gccPath = fi.absoluteFilePath();
            mingwBinPath = fi.absolutePath();
            break;
        }
    }
    if (gccPath.isEmpty())
        return;
    QProcess process;
    process.start(gccPath, QStringList() << "-dumpmachine");
    if (!process.waitForStarted()) {
        fprintf(stderr, "Could not start \"gcc -dumpmachine\".\n");
        return;
    }
    process.waitForFinished(-1);
    QByteArray gccMachineName = process.readAll().trimmed();
    if (gccMachineName != "mingw32" && gccMachineName != "mingw64") {
        fprintf(stderr, "Detected gcc platform '%s' is not supported.\n", gccMachineName.data());
        return;
    }

    Platform::Ptr platform = platforms.value(gccMachineName);
    printf("Platform '%s' detected in '%s'.", gccMachineName.data(), qPrintable(QDir::toNativeSeparators(mingwPath)));
    if (!platform) {
       platform = Platform::Ptr(new Platform(gccMachineName, settingsPath + "/" + gccMachineName));
       platforms.insert(platform->name, platform);
    }
    platform->settings.setValue("targetOS", "windows");
    platform->settings.setValue("cpp/toolchainInstallPath", QDir::toNativeSeparators(mingwBinPath));
    platform->settings.setValue("toolchain", "mingw");
}
#endif

int probe(const QString &settingsPath, QHash<QString, Platform::Ptr> &platforms)
{
#ifdef Q_OS_WIN
    msvcProbe(settingsPath, platforms);
    mingwProbe(settingsPath, platforms);
#else
    QString cc = QString::fromLocal8Bit(qgetenv("CC"));
    if (cc.isEmpty()) {
        bool somethingFound = false;
        if (specific_probe(settingsPath, platforms, "gcc") == 0)
            somethingFound = true;
        specific_probe(settingsPath, platforms, "clang", somethingFound);
    } else {
        specific_probe(settingsPath, platforms, cc);
    }
#endif
    if (platforms.isEmpty())
        fprintf(stderr, "Could not detect any platforms.\n");
    return 0;
}
<|endoftext|>


<commit_before>#include "core/narukami.h"
#include "core/geometry.h"
#include "core/transform.h"
#include "core/mesh.h"
#include "core/imageio.h"
using namespace narukami;
int main(){

     Point3f vertices[4]={Point3f(0,1,1),Point3f(0,0,1),Point3f(1,0,1),Point3f(1,1,1)};
     Point2f uvs[4] = {Point2f(0,1),Point2f(0,0),Point2f(1,0),Point2f(1,1)};
     uint32_t indices[6]={0,1,3,1,2,3};
     auto transform = translate(Vector3f(0,0,0));
     auto transform2 = translate(Vector3f(0,0,0));
     auto triangles=create_mesh_triangles(&transform,&transform2,2,indices,4,vertices,nullptr,uvs);

     auto soa_triangles=cast2SoA(triangles,0,2);
    std::cout<<soa_triangles[0];

    std::vector<uint8_t> image;
    float data[128*128*3];
	for (int i = 0; i<128*128; ++i) {
		narukami::Point2f uv;
		float t;
        narukami::SoARay ray(narukami::Point3f((i/128.0f)/128.0f,(i%128)/128.0f,0),narukami::Vector3f(0,0,1));
        int index;
        bool b =intersect(ray,soa_triangles[0],&t,&uv,&index);
       // std::cout<<index;
        // for(int j=0;j<soa_triangles.size();++j){
        //     b=(b||intersect(ray,soa_triangles[j],&t,&uv,&index));
        //     if(b){
        //         break;
        //     }
        // }
        uv=triangles[index]->sample_uv(uv);
        data[i*3] = uv[0];
        data[i*3+1] = uv[1];
        data[i*3+2] = 0;
	}

    narukami::write_image_to_file("mesh.png",data,128,128);
	//unsigned error = lodepng::encode(, image, 128, 128);
}<commit_msg>change to use sampler<commit_after>#include "core/narukami.h"
#include "core/geometry.h"
#include "core/transform.h"
#include "core/mesh.h"
#include "core/imageio.h"
#include "core/sampler.h"
using namespace narukami;
int main()
{

    Sampler sampler(16);

    Point3f vertices[4] = {Point3f(0, 1, 1), Point3f(0, 0, 1), Point3f(1, 0, 1), Point3f(1, 1, 1)};
    Point2f uvs[4] = {Point2f(0, 1), Point2f(0, 0), Point2f(1, 0), Point2f(1, 1)};
    uint32_t indices[6] = {0, 1, 3, 1, 2, 3};
    auto transform = translate(Vector3f(0, 0, 0));
    auto transform2 = translate(Vector3f(0, 0, 0));
    auto triangles = create_mesh_triangles(&transform, &transform2, 2, indices, 4, vertices, nullptr, uvs);

    auto soa_triangles = cast2SoA(triangles, 0, 2);
    std::cout << soa_triangles[0];

    std::vector<uint8_t> image;
    float data[128 * 128 * 3];
    for (int y = 0; y < 128; ++y)
    {
        for (int x = 0; x < 128; ++x)
        {
            data[(y*128+x)* 3] = 0;
            data[(y*128+x)* 3 + 1] = 0;
            sampler.start_pixel(Point2i(0, 0));
            do
            {
                auto sample = sampler.get_2D();
                SoARay ray(Point3f((x+sample.x)/128.0f, (y+sample.y)/128.0f, 0), Vector3f(0, 0, 1));
                Point2f uv;
                float t;
                int index;
                bool b = intersect(ray, soa_triangles[0], &t, &uv, &index);
                if (b)
                {
                    uv = triangles[index]->sample_uv(uv);
                    data[(y*128+x)* 3] += uv[0];
                    data[(y*128+x)* 3 + 1] += uv[1];
                }
                else
                {
                    std::cout << "miss " << ray.o << std::endl;
                }

            } while (sampler.start_next_sample());
            data[(y*128+x)* 3] /= 16;
            data[(y*128+x)* 3 + 1] /= 16;
            data[(y*128+x)* 3 + 2] = 0;
        }
    }

    narukami::write_image_to_file("mesh.png", data, 128, 128);
    //unsigned error = lodepng::encode(, image, 128, 128);
}<|endoftext|>


<commit_before>#include "ManipulationConstraint.h"
#include "PointContactRelation.h"

using namespace action_authoring;
using namespace affordance;
using namespace boost;

ManipulationConstraint::
ManipulationConstraint(AffConstPtr affordance,
                     ManipulatorStateConstPtr manipulator,
                     RelationStatePtr relationState
                     )
    : _affordance(affordance),
      _manipulator(manipulator),
      _relationState(relationState)
{
	_timeLowerBound = 0.0;
	_timeUpperBound = 0.0;
}

ManipulationConstraint::
ManipulationConstraint(AffConstPtr affordance,
                     ManipulatorStateConstPtr manipulator,
                     RelationStatePtr relationState,
                     double timeLowerBound,
                     double timeUpperBound
                     )
    : _affordance(affordance),
      _manipulator(manipulator),
      _relationState(relationState)
{
	_timeLowerBound = timeLowerBound;
	_timeUpperBound = timeUpperBound;
}

drc::contact_goal_t ManipulationConstraint::toLCM()
{
	printf("creating LCM message\n");
	drc::contact_goal_t msg;
  msg.utime = 0.0;

  //TODO change contact type based on affordance
	msg.contact_type = 0;
	msg.object_1_name = _manipulator->getName();
	msg.object_1_contact_grp = _manipulator->getContactGroupName();

    //TODO remove hardcodes here!
  msg.contact_type = msg.ON_GROUND_PLANE;
  msg.ground_plane_pt_radius = .25;

  msg.lower_bound_completion_time = _timeLowerBound;
  msg.upper_bound_completion_time = _timeUpperBound;

	if (_relationState->getRelationType() == RelationState::POINT_CONTACT)
	{
		Eigen::Vector3f v = (boost::static_pointer_cast<PointContactRelation>(_relationState))->getPoint2();
    drc::vector_3d_t pt;
 	 	pt.x = v.x();
  	pt.y = v.y();
  	pt.z = v.z();
		msg.ground_plane_pt = pt;
  }

	return msg;
}
<commit_msg>ManipulationConstraint uses new ManipulationState getLinkName() method for serialization<commit_after>#include "ManipulationConstraint.h"
#include "PointContactRelation.h"

using namespace action_authoring;
using namespace affordance;
using namespace boost;

ManipulationConstraint::
ManipulationConstraint(AffConstPtr affordance,
                     ManipulatorStateConstPtr manipulator,
                     RelationStatePtr relationState
                     )
    : _affordance(affordance),
      _manipulator(manipulator),
      _relationState(relationState)
{
	_timeLowerBound = 0.0;
	_timeUpperBound = 0.0;
}

ManipulationConstraint::
ManipulationConstraint(AffConstPtr affordance,
                     ManipulatorStateConstPtr manipulator,
                     RelationStatePtr relationState,
                     double timeLowerBound,
                     double timeUpperBound
                     )
    : _affordance(affordance),
      _manipulator(manipulator),
      _relationState(relationState)
{
	_timeLowerBound = timeLowerBound;
	_timeUpperBound = timeUpperBound;
}

drc::contact_goal_t ManipulationConstraint::toLCM()
{
	printf("creating LCM message\n");
	drc::contact_goal_t msg;
  msg.utime = 0.0;

  //TODO change contact type based on affordance
	msg.contact_type = 0;
  printf("flag0\n");
	msg.object_1_name = _manipulator->getLinkName();
  printf("flag0.5\n");
	msg.object_1_contact_grp = _manipulator->getContactGroupName();

    //TODO remove hardcodes here!
  msg.contact_type = msg.ON_GROUND_PLANE;
  msg.ground_plane_pt_radius = .25;

  msg.lower_bound_completion_time = _timeLowerBound;
  msg.upper_bound_completion_time = _timeUpperBound;

	if (_relationState->getRelationType() == RelationState::POINT_CONTACT)
	{
    printf("flag1\n");
		Eigen::Vector3f v = (boost::static_pointer_cast<PointContactRelation>(_relationState))->getPoint2();
    printf("flag2\n");
    drc::vector_3d_t pt;
 	 	pt.x = v.x();
  	pt.y = v.y();
  	pt.z = v.z();
		msg.ground_plane_pt = pt;
  }

	return msg;
}
<|endoftext|>


<commit_before>Int_t AliITStestV2(Char_t SlowOrFast='f') {
   Int_t rc=0;

   if (gAlice) {delete gAlice; gAlice=0;}
   TFile *in=TFile::Open("galice.root");
   if (!in->IsOpen()) {
      cerr<<"Can't open galice.root !\n";
      return 1;
   }
   if (!(gAlice=(AliRun*)in->Get("gAlice"))) {
      cerr<<"Can't find gAlice !\n";
      return 2;
   }
   AliKalmanTrack::SetConvConst(1000/0.299792458/gAlice->Field()->SolenoidField());
   delete gAlice; gAlice=0;
   in->Close();

   if (SlowOrFast=='f') {
      cerr<<"Fast AliITSRecPoint(s) !\n";
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSHits2FastRecPoints.C");
      AliITSHits2FastRecPoints();
   } else {
      cerr<<"Slow AliITSRecPoint(s) !\n";
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSHits2SDigits.C");
      AliITSHits2SDigits();
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSSDigits2Digits.C");
      AliITSSDigits2Digits();
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSDigits2RecPoints.C");
      AliITSDigits2RecPoints();
   }
   gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSFindClustersV2.C");
   if (rc=AliITSFindClustersV2(SlowOrFast)) return rc;

   gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSFindTracksV2.C");
   if (rc=AliITSFindTracksV2()) return rc;

   gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSComparisonV2.C");
   if (rc=AliITSComparisonV2()) return rc;

   return rc;
}
<commit_msg>Default ITS simulation reverted to slow<commit_after>Int_t AliITStestV2(Char_t SlowOrFast='s') {
   Int_t rc=0;

   if (gAlice) {delete gAlice; gAlice=0;}
   TFile *in=TFile::Open("galice.root");
   if (!in->IsOpen()) {
      cerr<<"Can't open galice.root !\n";
      return 1;
   }
   if (!(gAlice=(AliRun*)in->Get("gAlice"))) {
      cerr<<"Can't find gAlice !\n";
      return 2;
   }
   AliKalmanTrack::SetConvConst(1000/0.299792458/gAlice->Field()->SolenoidField());
   delete gAlice; gAlice=0;
   in->Close();

   if (SlowOrFast=='f') {
      cerr<<"Fast AliITSRecPoint(s) !\n";
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSHits2FastRecPoints.C");
      AliITSHits2FastRecPoints();
   } else {
      cerr<<"Slow AliITSRecPoint(s) !\n";
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSHits2SDigits.C");
      AliITSHits2SDigits();
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSSDigits2Digits.C");
      AliITSSDigits2Digits();
      gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSDigits2RecPoints.C");
      AliITSDigits2RecPoints();
   }
   gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSFindClustersV2.C");
   if (rc=AliITSFindClustersV2(SlowOrFast)) return rc;

   gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSFindTracksV2.C");
   if (rc=AliITSFindTracksV2()) return rc;

   gROOT->LoadMacro("$(ALICE_ROOT)/ITS/AliITSComparisonV2.C");
   if (rc=AliITSComparisonV2()) return rc;

   return rc;
}
<|endoftext|>


<commit_before><commit_msg>CID#1078757 nOfs <= nPersistPtrAnz<commit_after><|endoftext|>


<commit_before>#include <QGraphicsView>

#include "fish_annotator/common/annotation_scene.h"

namespace fish_annotator {

AnnotationScene::AnnotationScene(QObject *parent)
  : QGraphicsScene(parent)
  , mode_(kDoNothing)
  , type_(kBox)
  , start_pos_()
  , rect_item_(nullptr)
  , line_item_(nullptr)
  , dot_item_(nullptr) {
}

void AnnotationScene::setToolWidget(AnnotationWidget *widget) {
  QObject::connect(widget, &AnnotationWidget::setAnnotation,
      this, &AnnotationScene::setAnnotationType);
}

void AnnotationScene::setMode(Mode mode) {
  mode_ = mode;
  QGraphicsView::DragMode drag;
  if(mode == kDraw) {
    makeItemsControllable(false);
    drag = QGraphicsView::NoDrag;
  }
  else if(mode == kSelect) {
    makeItemsControllable(true);
    drag = QGraphicsView::RubberBandDrag;
  }
  auto view = views().at(0);
  if(view != nullptr) view->setDragMode(drag);
}

void AnnotationScene::setAnnotationType(AnnotationType type) {
  type_ = type;
}

namespace {
// Define pen width in anonymous namespace.
static const int pen_width = 7;
}

void AnnotationScene::mousePressEvent(QGraphicsSceneMouseEvent *event) {
  if(mode_ == kDraw) {
    start_pos_ = event->scenePos();
    switch(type_) {
      case kBox:
        rect_item_ = new QGraphicsRectItem(
              start_pos_.x(), start_pos_.y(), 0, 0);
        rect_item_->setPen(QPen(Qt::black, pen_width, Qt::SolidLine));
        addItem(rect_item_);
        break;
      case kLine:
        line_item_ = new QGraphicsLineItem(QLineF(
              start_pos_, start_pos_));
        line_item_->setPen(QPen(Qt::black, pen_width, Qt::SolidLine));
        addItem(line_item_);
        break;
      case kDot:
        dot_item_ = new QGraphicsEllipseItem(
              start_pos_.x() - pen_width,
              start_pos_.y() - pen_width,
              2 * pen_width, 2 * pen_width);
        dot_item_->setPen(QPen(Qt::black, pen_width, Qt::SolidLine));
        addItem(dot_item_);
        break;
    }
  }
  QGraphicsScene::mousePressEvent(event);
}

void AnnotationScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
  if(mode_ == kDraw) {
    auto update_pos = event->scenePos();
    switch(type_) {
      case kBox:
        if(rect_item_ != nullptr) {
          auto left = qMin(start_pos_.x(), update_pos.x());
          auto top = qMin(start_pos_.y(), update_pos.y());
          auto width = qAbs(start_pos_.x() - update_pos.x());
          auto height = qAbs(start_pos_.y() - update_pos.y());
          rect_item_->setRect(QRectF(left, top, width, height));
        }
        break;
      case kLine:
        if(line_item_ != nullptr) {
          line_item_->setLine(QLineF(start_pos_, update_pos));
        }
        break;
      case kDot:
        if(dot_item_ != nullptr) {
          dot_item_->setRect(QRectF(
                update_pos.x() - pen_width,
                update_pos.y() - pen_width,
                2 * pen_width, 2 * pen_width));
        }
        break;
    }
  }
}

void AnnotationScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
  if(mode_ == kDraw) {
    switch(type_) {
      case kBox:
        if(rect_item_ != nullptr) {
          emit boxFinished(rect_item_->rect());
        }
        break;
      case kLine:
        if(line_item_ != nullptr) {
          emit lineFinished(line_item_->line());
        }
        break;
      case kDot:
        if(dot_item_ != nullptr) {
          emit dotFinished(dot_item_->rect().topLeft());
        }
        break;
    }
  }
}

void AnnotationScene::makeItemsControllable(bool controllable) {
  foreach(QGraphicsItem *item, items()) {
    item->setFlag(QGraphicsItem::ItemIsSelectable, controllable);
    item->setFlag(QGraphicsItem::ItemIsMovable, controllable);
  }
}

} // namespace fish_annotator
<commit_msg>Add moc include<commit_after>#include <QGraphicsView>

#include "fish_annotator/common/annotation_scene.h"

namespace fish_annotator {

AnnotationScene::AnnotationScene(QObject *parent)
  : QGraphicsScene(parent)
  , mode_(kDoNothing)
  , type_(kBox)
  , start_pos_()
  , rect_item_(nullptr)
  , line_item_(nullptr)
  , dot_item_(nullptr) {
}

void AnnotationScene::setToolWidget(AnnotationWidget *widget) {
  QObject::connect(widget, &AnnotationWidget::setAnnotation,
      this, &AnnotationScene::setAnnotationType);
}

void AnnotationScene::setMode(Mode mode) {
  mode_ = mode;
  QGraphicsView::DragMode drag;
  if(mode == kDraw) {
    makeItemsControllable(false);
    drag = QGraphicsView::NoDrag;
  }
  else if(mode == kSelect) {
    makeItemsControllable(true);
    drag = QGraphicsView::RubberBandDrag;
  }
  auto view = views().at(0);
  if(view != nullptr) view->setDragMode(drag);
}

void AnnotationScene::setAnnotationType(AnnotationType type) {
  type_ = type;
}

namespace {
// Define pen width in anonymous namespace.
static const int pen_width = 7;
}

void AnnotationScene::mousePressEvent(QGraphicsSceneMouseEvent *event) {
  if(mode_ == kDraw) {
    start_pos_ = event->scenePos();
    switch(type_) {
      case kBox:
        rect_item_ = new QGraphicsRectItem(
              start_pos_.x(), start_pos_.y(), 0, 0);
        rect_item_->setPen(QPen(Qt::black, pen_width, Qt::SolidLine));
        addItem(rect_item_);
        break;
      case kLine:
        line_item_ = new QGraphicsLineItem(QLineF(
              start_pos_, start_pos_));
        line_item_->setPen(QPen(Qt::black, pen_width, Qt::SolidLine));
        addItem(line_item_);
        break;
      case kDot:
        dot_item_ = new QGraphicsEllipseItem(
              start_pos_.x() - pen_width,
              start_pos_.y() - pen_width,
              2 * pen_width, 2 * pen_width);
        dot_item_->setPen(QPen(Qt::black, pen_width, Qt::SolidLine));
        addItem(dot_item_);
        break;
    }
  }
  QGraphicsScene::mousePressEvent(event);
}

void AnnotationScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
  if(mode_ == kDraw) {
    auto update_pos = event->scenePos();
    switch(type_) {
      case kBox:
        if(rect_item_ != nullptr) {
          auto left = qMin(start_pos_.x(), update_pos.x());
          auto top = qMin(start_pos_.y(), update_pos.y());
          auto width = qAbs(start_pos_.x() - update_pos.x());
          auto height = qAbs(start_pos_.y() - update_pos.y());
          rect_item_->setRect(QRectF(left, top, width, height));
        }
        break;
      case kLine:
        if(line_item_ != nullptr) {
          line_item_->setLine(QLineF(start_pos_, update_pos));
        }
        break;
      case kDot:
        if(dot_item_ != nullptr) {
          dot_item_->setRect(QRectF(
                update_pos.x() - pen_width,
                update_pos.y() - pen_width,
                2 * pen_width, 2 * pen_width));
        }
        break;
    }
  }
}

void AnnotationScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
  if(mode_ == kDraw) {
    switch(type_) {
      case kBox:
        if(rect_item_ != nullptr) {
          emit boxFinished(rect_item_->rect());
        }
        break;
      case kLine:
        if(line_item_ != nullptr) {
          emit lineFinished(line_item_->line());
        }
        break;
      case kDot:
        if(dot_item_ != nullptr) {
          emit dotFinished(dot_item_->rect().topLeft());
        }
        break;
    }
  }
}

void AnnotationScene::makeItemsControllable(bool controllable) {
  foreach(QGraphicsItem *item, items()) {
    item->setFlag(QGraphicsItem::ItemIsSelectable, controllable);
    item->setFlag(QGraphicsItem::ItemIsMovable, controllable);
  }
}

#include "../../include/fish_annotator/common/moc_annotation_scene.cpp"
} // namespace fish_annotator
<|endoftext|>


<commit_before>#include "./scene.h"

#include <QDebug>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./gl.h"
#include "./input/invoke_manager.h"
#include "./mesh.h"
#include "./mesh_node.h"
#include "./label_node.h"
#include "./render_data.h"
#include "./importer.h"
#include "./camera_controller.h"
#include "./camera_rotation_controller.h"
#include "./camera_zoom_controller.h"
#include "./camera_move_controller.h"
#include "./nodes.h"
#include "./quad.h"
#include "./frame_buffer_object.h"
#include "./utils/persister.h"
#include "./forces/labeller_frame_data.h"

BOOST_CLASS_EXPORT_GUID(LabelNode, "LabelNode")
BOOST_CLASS_EXPORT_GUID(MeshNode, "MeshNode")

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes,
             std::shared_ptr<Forces::Labeller> labeller)

  : nodes(nodes), labeller(labeller)
{
  cameraController = std::make_shared<CameraController>(camera);
  cameraRotationController = std::make_shared<CameraRotationController>(camera);
  cameraZoomController = std::make_shared<CameraZoomController>(camera);
  cameraMoveController = std::make_shared<CameraMoveController>(camera);

  invokeManager->addHandler("cam", cameraController.get());
  invokeManager->addHandler("cameraRotation", cameraRotationController.get());
  invokeManager->addHandler("cameraZoom", cameraZoomController.get());
  invokeManager->addHandler("cameraMove", cameraMoveController.get());

  fbo = std::unique_ptr<FrameBufferObject>(new FrameBufferObject());
}

Scene::~Scene()
{
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  const std::string filename = "assets/assets.dae";
  Importer importer;

  std::vector<std::shared_ptr<Node>> meshNodes;
  for (unsigned int meshIndex = 0; meshIndex < 2; ++meshIndex)
  {
    auto mesh = importer.import(filename, meshIndex);
    auto node =
        new MeshNode(filename, meshIndex, mesh, Eigen::Matrix4f::Identity());
    meshNodes.push_back(std::unique_ptr<MeshNode>(node));
  }
  auto label = Label(1, "Shoulder", Eigen::Vector3f(0.174f, 0.553f, 0.02f));
  meshNodes.push_back(std::make_shared<LabelNode>(label));

  auto label2 = Label(2, "Ellbow", Eigen::Vector3f(0.334f, 0.317f, -0.013f));
  meshNodes.push_back(std::make_shared<LabelNode>(label2));

  auto label3 = Label(3, "Wound", Eigen::Vector3f(0.262f, 0.422f, 0.058f),
                      Eigen::Vector2f(0.14f, 0.14f));
  meshNodes.push_back(std::make_shared<LabelNode>(label3));

  auto label4 = Label(4, "Wound 2", Eigen::Vector3f(0.034f, 0.373f, 0.141f));
  meshNodes.push_back(std::make_shared<LabelNode>(label4));

  Persister::save(meshNodes, "config/scene.xml");

  nodes->addSceneNodesFrom("config/scene.xml");

  for (auto &labelNode : nodes->getLabelNodes())
  {
    auto label = labelNode->getLabel();
    labeller->addLabel(label.id, label.text, label.anchorPosition, label.size);
  }

  quad = std::make_shared<Quad>();

  fbo->initialize(gl, width, height);
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  this->frameTime = frameTime;
  cameraController->setFrameTime(frameTime);
  cameraRotationController->setFrameTime(frameTime);
  cameraZoomController->setFrameTime(frameTime);
  cameraMoveController->setFrameTime(frameTime);

  auto newPositions = labeller->update(Forces::LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));

  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->getLabel().id];
  }
}

void Scene::render()
{
  if (shouldResize)
  {
    camera.resize(width, height);
    fbo->resize(gl, width, height);
    shouldResize = false;
  }
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData;
  renderData.projectionMatrix = camera.getProjectionMatrix();
  renderData.viewMatrix = camera.getViewMatrix();
  renderData.cameraPosition = camera.getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();

  nodes->render(gl, renderData);

  fbo->unbind();

  renderScreenQuad();
}

void Scene::renderScreenQuad()
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix =
      Eigen::Affine3f(Eigen::AlignedScaling3f(1, -1, 1)).matrix();

  fbo->bindColorTexture(GL_TEXTURE0);
  // fbo->bindDepthTexture(GL_TEXTURE0);

  quad->render(gl, renderData);
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;
}

<commit_msg>Picking every frame for center position.<commit_after>#include "./scene.h"

#include <QDebug>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./gl.h"
#include "./input/invoke_manager.h"
#include "./mesh.h"
#include "./mesh_node.h"
#include "./label_node.h"
#include "./render_data.h"
#include "./importer.h"
#include "./camera_controller.h"
#include "./camera_rotation_controller.h"
#include "./camera_zoom_controller.h"
#include "./camera_move_controller.h"
#include "./nodes.h"
#include "./quad.h"
#include "./frame_buffer_object.h"
#include "./utils/persister.h"
#include "./forces/labeller_frame_data.h"

BOOST_CLASS_EXPORT_GUID(LabelNode, "LabelNode")
BOOST_CLASS_EXPORT_GUID(MeshNode, "MeshNode")

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes,
             std::shared_ptr<Forces::Labeller> labeller)

  : nodes(nodes), labeller(labeller)
{
  cameraController = std::make_shared<CameraController>(camera);
  cameraRotationController = std::make_shared<CameraRotationController>(camera);
  cameraZoomController = std::make_shared<CameraZoomController>(camera);
  cameraMoveController = std::make_shared<CameraMoveController>(camera);

  invokeManager->addHandler("cam", cameraController.get());
  invokeManager->addHandler("cameraRotation", cameraRotationController.get());
  invokeManager->addHandler("cameraZoom", cameraZoomController.get());
  invokeManager->addHandler("cameraMove", cameraMoveController.get());

  fbo = std::unique_ptr<FrameBufferObject>(new FrameBufferObject());
}

Scene::~Scene()
{
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  const std::string filename = "assets/assets.dae";
  Importer importer;

  std::vector<std::shared_ptr<Node>> meshNodes;
  for (unsigned int meshIndex = 0; meshIndex < 2; ++meshIndex)
  {
    auto mesh = importer.import(filename, meshIndex);
    auto node =
        new MeshNode(filename, meshIndex, mesh, Eigen::Matrix4f::Identity());
    meshNodes.push_back(std::unique_ptr<MeshNode>(node));
  }
  auto label = Label(1, "Shoulder", Eigen::Vector3f(0.174f, 0.553f, 0.02f));
  meshNodes.push_back(std::make_shared<LabelNode>(label));

  auto label2 = Label(2, "Ellbow", Eigen::Vector3f(0.334f, 0.317f, -0.013f));
  meshNodes.push_back(std::make_shared<LabelNode>(label2));

  auto label3 = Label(3, "Wound", Eigen::Vector3f(0.262f, 0.422f, 0.058f),
                      Eigen::Vector2f(0.14f, 0.14f));
  meshNodes.push_back(std::make_shared<LabelNode>(label3));

  auto label4 = Label(4, "Wound 2", Eigen::Vector3f(0.034f, 0.373f, 0.141f));
  meshNodes.push_back(std::make_shared<LabelNode>(label4));

  Persister::save(meshNodes, "config/scene.xml");

  nodes->addSceneNodesFrom("config/scene.xml");

  for (auto &labelNode : nodes->getLabelNodes())
  {
    auto label = labelNode->getLabel();
    labeller->addLabel(label.id, label.text, label.anchorPosition, label.size);
  }

  quad = std::make_shared<Quad>();

  fbo->initialize(gl, width, height);
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  this->frameTime = frameTime;
  cameraController->setFrameTime(frameTime);
  cameraRotationController->setFrameTime(frameTime);
  cameraZoomController->setFrameTime(frameTime);
  cameraMoveController->setFrameTime(frameTime);

  auto newPositions = labeller->update(Forces::LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));

  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->getLabel().id];
  }
}

void Scene::render()
{
  if (shouldResize)
  {
    camera.resize(width, height);
    fbo->resize(gl, width, height);
    shouldResize = false;
  }
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData;
  renderData.projectionMatrix = camera.getProjectionMatrix();
  renderData.viewMatrix = camera.getViewMatrix();
  renderData.cameraPosition = camera.getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();

  nodes->render(gl, renderData);

  int x = 640;
  int y = 360;
  float depth = -1.0f;
  glAssert(gl->glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth));

  qWarning() << depth;

  fbo->unbind();

  renderScreenQuad();
}

void Scene::renderScreenQuad()
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix =
      Eigen::Affine3f(Eigen::AlignedScaling3f(1, -1, 1)).matrix();

  fbo->bindColorTexture(GL_TEXTURE0);
  //fbo->bindDepthTexture(GL_TEXTURE0);

  quad->render(gl, renderData);
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;
}

<|endoftext|>