<commit_before>/*
 *  qikfilter.cpp
 *
 *  Copyright (c) 2015 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include <sstream>
#include "Eigen/Dense"

#include "itkImageSource.h"
#include "itkConstNeighborhoodIterator.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkMultiplyImageFilter.h"
#include "itkDivideImageFilter.h"
#include "itkComplexToComplexFFTImageFilter.h"
#include "itkInverseFFTImageFilter.h"
#include "itkFFTShiftImageFilter.h"
#include "itkComplexToModulusImageFilter.h"
#include "itkFFTPadImageFilter.h"
#include "itkExtractImageFilter.h"
#include "itkPasteImageFilter.h"
#include "itkCastImageFilter.h"

#include "QI/Types.h"
#include "QI/Util.h"

using namespace std;
using namespace Eigen;

class FilterKernel {

};

class TukeyKernel : FilterKernel {
protected:
    double m_a = 0.75;
    double m_q = 0.25;
    int m_hx = 0, m_hy = 0, m_hz = 0;

public:
    void setSize(const int sx, const int sy, const int sz) {
        m_hx = sx / 2;  m_hy = sy / 2;  m_hz = sz / 2;
    }
    void setAQ(const double a, const double q) {
        m_a = a;
        m_q = q;
    }

    double operator() (const int x, const int y, const int z) const {
            const double rx = fmod(static_cast<double>(x)/m_hx + 1.0, 2.0) - 1.0;
            const double ry = fmod(static_cast<double>(y)/m_hy + 1.0, 2.0) - 1.0;
            const double rz = fmod(static_cast<double>(z)/m_hz + 1.0, 2.0) - 1.0;
            const double r = sqrt((rx*rx + ry*ry + rz*rz) / 3);
            const double v = (r <= (1 - m_a)) ? 1 : 0.5*((1+m_q)+(1-m_q)*cos((M_PI/m_a)*(r - 1 + m_a)));
            return v;
    }
};

namespace itk {

template<typename ImageType>
class KSpaceFilter : public ImageToImageFilter<ImageType, ImageType> {
public:
    typedef ImageType                          TImage;
    typedef KSpaceFilter                       Self;
    typedef ImageToImageFilter<TImage, TImage> Superclass;
    typedef SmartPointer<Self>                 Pointer;

protected:
    TukeyKernel m_kernel;
    bool m_WriteKernel = false;

    KSpaceFilter(){}
    ~KSpaceFilter(){}

public:
    itkNewMacro(Self);
    itkTypeMacro(KSpaceFilter, ImageSource);
    itkSetMacro(WriteKernel, bool);

    virtual void GenerateOutputInformation() override {
        Superclass::GenerateOutputInformation();
        typename TImage::SizeType size = this->GetOutput()->GetLargestPossibleRegion().GetSize();
        m_kernel.setSize(size[0], size[1], size[2]);
    }

    void SetKernel(const TukeyKernel &k) { m_kernel = k; }

protected:
    virtual void ThreadedGenerateData(const typename TImage::RegionType &region, ThreadIdType threadId) override {
        typename TImage::IndexType startIndex = this->GetInput()->GetLargestPossibleRegion().GetIndex();
        itk::ImageRegionIterator<TImage> outIt(this->GetOutput(),region);
        itk::ImageRegionConstIteratorWithIndex<TImage> inIt(this->GetInput(),region);
        inIt.GoToBegin();
        outIt.GoToBegin();
        while(!inIt.IsAtEnd()) {
            const auto index = inIt.GetIndex() - startIndex; // Might be padded to a negative start
            const typename TImage::PixelType::value_type k = m_kernel(index[0], index[1], index[2]);
            const typename TImage::PixelType v = inIt.Get();
            if (m_WriteKernel) {
                outIt.Set(k);
            } else {
                outIt.Set(v * k);
            }
            ++inIt;
            ++outIt;
        }
    }

private:
    KSpaceFilter(const Self &);
    void operator=(const Self &);
};

} // End namespace itk

template<typename TImage> typename TImage::Pointer FilterVolume(const typename TImage::Pointer invol, const TukeyKernel &kernel, const bool verbose, const bool debug, const string &out_name);

template<> QI::ImageXD::Pointer FilterVolume<QI::ImageXD>(const typename QI::ImageXD::Pointer invol, const TukeyKernel &kernel, const bool verbose, const bool debug, const string &out_name) {
    typedef itk::FFTPadImageFilter<QI::ImageXD> TPad;
    typedef itk::ComplexToComplexFFTImageFilter<QI::ImageXD> FFTType;
    typedef itk::FFTShiftImageFilter<QI::ImageXD, QI::ImageXD> TShift;
    typedef itk::KSpaceFilter<QI::ImageXD> TFilter;

    auto padFFT = TPad::New();
    padFFT->SetInput(invol);
    auto forwardFFT = FFTType::New();
    forwardFFT->SetInput(padFFT->GetOutput());
    auto k_filter = TFilter::New();
    k_filter->SetKernel(kernel);
    k_filter->SetInput(forwardFFT->GetOutput());
    auto inverseFFT = FFTType::New();
    inverseFFT->SetTransformDirection(FFTType::INVERSE);
    inverseFFT->SetInput(k_filter->GetOutput());
    auto extract = itk::ExtractImageFilter<QI::ImageXD, QI::ImageXD>::New();
    extract->InPlaceOn();
    extract->SetInput(inverseFFT->GetOutput());
    extract->SetDirectionCollapseToSubmatrix();
    extract->SetExtractionRegion(invol->GetLargestPossibleRegion());
    extract->Update();
    typename QI::ImageXD::Pointer outvol = extract->GetOutput();
    outvol->DisconnectPipeline();
    return outvol;
}

template<> QI::ImageD::Pointer FilterVolume<QI::ImageD>(const typename QI::ImageD::Pointer invol, const TukeyKernel &kernel, const bool verbose, const bool debug, const string &out_name) {
    typedef itk::CastImageFilter<QI::ImageD, QI::ImageXD> TCast;
    auto caster = TCast::New();
    caster->SetInput(invol);
    caster->Update();
    QI::ImageXD::Pointer filtered = FilterVolume<QI::ImageXD>(caster->GetOutput(), kernel, verbose, debug, out_name);
    if (verbose) cout << "Taking complex modulus" << endl;
    typedef itk::ComplexToModulusImageFilter<QI::ImageXD, QI::ImageD> TMod;
    auto mod = TMod::New();
    mod->SetInput(filtered);
    mod->Update();
    QI::ImageD::Pointer final = mod->GetOutput();
    final->DisconnectPipeline();
    return final;
}

template<typename TPixel>
void run_pipeline(const std::string &in_name, const std::string &out_name, const bool verbose, const bool debug, const TukeyKernel &kernel) {
    typedef itk::Image<TPixel, 4> TSeries;
    typedef itk::Image<TPixel, 3> TVolume;

    if (verbose) cout << "Opening input file: " << in_name << endl;
    typename TSeries::Pointer vols = QI::ReadImage<TSeries>(in_name);
    auto region = vols->GetLargestPossibleRegion();
    const size_t nvols = region.GetSize()[3]; // Save for the loop
    region.GetModifiableSize()[3] = 0;
    auto extract = itk::ExtractImageFilter<TSeries, TVolume>::New();
    extract->SetInput(vols);
    extract->SetDirectionCollapseToSubmatrix();
    extract->InPlaceOn();
    typename itk::PasteImageFilter<TSeries>::Pointer paster = itk::PasteImageFilter<TSeries>::New();
    typename itk::CastImageFilter<TVolume, TSeries>::Pointer caster = itk::CastImageFilter<TVolume, TSeries>::New();
    paster->SetDestinationImage(vols);
    //paster->InPlaceOn();
    for (int i = 0; i < nvols; i++) {
        region.GetModifiableIndex()[3] = i;
        if (verbose) cout << "Processing volume " << i << endl;
        extract->SetExtractionRegion(region);
        extract->Update();
        typename TVolume::Pointer outvol = FilterVolume<TVolume>(extract->GetOutput(), kernel, verbose, debug, out_name);
        caster->SetInput(outvol);
        caster->Update();
        paster->SetSourceImage(caster->GetOutput());
        paster->SetSourceRegion(caster->GetOutput()->GetLargestPossibleRegion());
        paster->SetDestinationImage(vols);
        paster->SetDestinationIndex(region.GetIndex());
        paster->Update();
        vols = paster->GetOutput();
    }
    if (verbose) cout << "Writing output:" << out_name + QI::OutExt() << endl;
    QI::WriteImage(vols, out_name + QI::OutExt());
    if (verbose) cout << "Finished." << endl;
}

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: qikfilter [options] input \n\
\n\
Filter images in k-Space\n\
\n\
Options:\n\
    --help, -h           : Print this message.\n\
    --verbose, -v        : Print more information.\n\
    --out, -o path       : Specify an output filename (default image base).\n\
    --filter, -f \"a q\" : Set Filter a and q values (default 0.75 0.25).\n\
    --debug, -d          : Save all pipeline steps.\n\
    --complex, -x        : Input/output data is complex.\n\
    --threads, -T N      : Use N threads (default=hardware limit).\n"
};

const struct option long_options[] = {
    {"help", no_argument, 0, 'h'},
    {"verbose", no_argument, 0, 'v'},
    {"out", required_argument, 0, 'o'},
    {"filter", required_argument, 0, 'f'},
    {"debug", no_argument, 0, 'd'},
    {"complex", no_argument, 0, 'x'},
    {"threads", required_argument, 0, 'T'},
    {0, 0, 0, 0}
};
const char *short_options = "hvo:m:e:dxT:";

//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv) {
    Eigen::initParallel();

    bool verbose = false, debug = false, is_complex = false;
    double filter_a = 0.75, filter_q = 0.25;
    string out_name;
    int indexptr = 0, c;
    while ((c = getopt_long(argc, argv, short_options, long_options, &indexptr)) != -1) {
        switch (c) {
            case 'v': verbose = true; break;
            case 'o':
                out_name = optarg;
                cout << "Output filename will be: " << out_name << endl;
                break;
            case 'f': {
                stringstream f(optarg);
                f >> filter_a >> filter_q;
            } break;
            case 'd': debug = true; break;
            case 'x': is_complex = true; break;
            case 'T': itk::MultiThreader::SetGlobalMaximumNumberOfThreads(atoi(optarg)); break;
            case 'h':
                cout << QI::GetVersion() << endl << usage << endl;
                return EXIT_SUCCESS;
            case '?': // getopt will print an error message
                return EXIT_FAILURE;
            default:
                cout << "Unhandled option " << string(1, c) << endl;
                return EXIT_FAILURE;
        }
    }
    if ((argc - optind) != 1) {
        cout << "Incorrect number of arguments." << endl << usage << endl;
        return EXIT_FAILURE;
    }

    string in_name(argv[optind++]);
    if (out_name == "")
        out_name = in_name.substr(0, in_name.find(".")) + "_filtered";

    TukeyKernel filter_kernel;
    filter_kernel.setAQ(filter_a, filter_q);
    if (is_complex) {
        if (verbose) cout << "Data is complex." << endl;
        run_pipeline<complex<double>>(in_name, out_name, verbose, debug, filter_kernel);
    } else {
        if (verbose) cout << "Data is real." << endl;
        run_pipeline<double>(in_name, out_name, verbose, debug, filter_kernel);
    }

    return EXIT_SUCCESS;
}
<commit_msg>ENH: Simplified pipeline to always work with complex<float> and write out either complex or real valued data.<commit_after>/*
 *  qikfilter.cpp
 *
 *  Copyright (c) 2015 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include <sstream>
#include "Eigen/Dense"

#include "itkImageSource.h"
#include "itkConstNeighborhoodIterator.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkMultiplyImageFilter.h"
#include "itkDivideImageFilter.h"
#include "itkComplexToComplexFFTImageFilter.h"
#include "itkInverseFFTImageFilter.h"
#include "itkFFTShiftImageFilter.h"
#include "itkComplexToModulusImageFilter.h"
#include "itkFFTPadImageFilter.h"
#include "itkExtractImageFilter.h"
#include "itkPasteImageFilter.h"
#include "itkCastImageFilter.h"

#include "QI/Types.h"
#include "QI/Util.h"

using namespace std;
using namespace Eigen;

class FilterKernel {

};

class TukeyKernel : FilterKernel {
protected:
    double m_a = 0.75;
    double m_q = 0.25;
    int m_hx = 0, m_hy = 0, m_hz = 0;

public:
    void setSize(const int sx, const int sy, const int sz) {
        m_hx = sx / 2;  m_hy = sy / 2;  m_hz = sz / 2;
    }
    void setAQ(const double a, const double q) {
        m_a = a;
        m_q = q;
    }

    double operator() (const int x, const int y, const int z) const {
            const double rx = fmod(static_cast<double>(x)/m_hx + 1.0, 2.0) - 1.0;
            const double ry = fmod(static_cast<double>(y)/m_hy + 1.0, 2.0) - 1.0;
            const double rz = fmod(static_cast<double>(z)/m_hz + 1.0, 2.0) - 1.0;
            const double r = sqrt((rx*rx + ry*ry + rz*rz) / 3);
            const double v = (r <= (1 - m_a)) ? 1 : 0.5*((1+m_q)+(1-m_q)*cos((M_PI/m_a)*(r - 1 + m_a)));
            return v;
    }
};

namespace itk {

template<typename ImageType>
class KSpaceFilter : public ImageToImageFilter<ImageType, ImageType> {
public:
    typedef ImageType                          TImage;
    typedef KSpaceFilter                       Self;
    typedef ImageToImageFilter<TImage, TImage> Superclass;
    typedef SmartPointer<Self>                 Pointer;

protected:
    TukeyKernel m_kernel;
    bool m_WriteKernel = false;

    KSpaceFilter(){}
    ~KSpaceFilter(){}

public:
    itkNewMacro(Self);
    itkTypeMacro(KSpaceFilter, ImageSource);
    itkSetMacro(WriteKernel, bool);

    virtual void GenerateOutputInformation() override {
        Superclass::GenerateOutputInformation();
        typename TImage::SizeType size = this->GetOutput()->GetLargestPossibleRegion().GetSize();
        m_kernel.setSize(size[0], size[1], size[2]);
    }

    void SetKernel(const TukeyKernel &k) { m_kernel = k; }

protected:
    virtual void ThreadedGenerateData(const typename TImage::RegionType &region, ThreadIdType threadId) override {
        typename TImage::IndexType startIndex = this->GetInput()->GetLargestPossibleRegion().GetIndex();
        itk::ImageRegionIterator<TImage> outIt(this->GetOutput(),region);
        itk::ImageRegionConstIteratorWithIndex<TImage> inIt(this->GetInput(),region);
        inIt.GoToBegin();
        outIt.GoToBegin();
        while(!inIt.IsAtEnd()) {
            const auto index = inIt.GetIndex() - startIndex; // Might be padded to a negative start
            const typename TImage::PixelType::value_type k = m_kernel(index[0], index[1], index[2]);
            const typename TImage::PixelType v = inIt.Get();
            if (m_WriteKernel) {
                outIt.Set(k);
            } else {
                outIt.Set(v * k);
            }
            ++inIt;
            ++outIt;
        }
    }

private:
    KSpaceFilter(const Self &);
    void operator=(const Self &);
};

} // End namespace itk

QI::TimeseriesXF::Pointer run_pipeline(const std::string &in_name, const std::string &out_name, const bool verbose, const bool debug, const TukeyKernel &kernel) {
    typedef itk::ExtractImageFilter<QI::TimeseriesXF, QI::ImageXD> TExtract;
    typedef itk::PasteImageFilter<QI::TimeseriesXF>                TPaste;
    typedef itk::CastImageFilter<QI::ImageXD, QI::TimeseriesXF>    TCast;
    typedef itk::FFTPadImageFilter<QI::ImageXD>                    TPad;
    typedef itk::ComplexToComplexFFTImageFilter<QI::ImageXD>       TFFT;
    typedef itk::KSpaceFilter<QI::ImageXD>                         TFilter;

    if (verbose) cout << "Opening input file: " << in_name << endl;
    auto vols = QI::ReadImage<QI::TimeseriesXF>(in_name);
    auto region = vols->GetLargestPossibleRegion();
    const size_t nvols = region.GetSize()[3]; // Save for the loop

    auto extract = TExtract::New();
    auto pad     = TPad::New();
    auto forward = TFFT::New();
    auto inverse = TFFT::New();
    auto k_filter = TFilter::New();
    auto caster = TCast::New();
    auto paster = TPaste::New();

    extract->SetInput(vols);
    extract->SetDirectionCollapseToSubmatrix();
    extract->InPlaceOn();
    pad->SetInput(extract->GetOutput());
    forward->SetInput(pad->GetOutput());
    k_filter->SetInput(forward->GetOutput());
    k_filter->SetKernel(kernel);
    inverse->SetInput(k_filter->GetOutput());
    inverse->SetTransformDirection(TFFT::INVERSE);
    caster->SetInput(inverse->GetOutput());
    paster->SetSourceImage(caster->GetOutput());
    region.GetModifiableSize()[3] = 1;
    paster->SetSourceRegion(region);
    paster->SetDestinationImage(vols);
    //paster->InPlaceOn();
    region.GetModifiableSize()[3] = 0;
    for (int i = 0; i < nvols; i++) {
        region.GetModifiableIndex()[3] = i;
        if (verbose) cout << "Processing volume " << i << endl;
        extract->SetExtractionRegion(region);
        paster->SetDestinationIndex(region.GetIndex());
        paster->Update();
        vols = paster->GetOutput();
    }
    return vols;
    if (verbose) cout << "Finished." << endl;
}

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: qikfilter [options] input \n\
\n\
Filter images in k-Space\n\
\n\
Options:\n\
    --help, -h           : Print this message.\n\
    --verbose, -v        : Print more information.\n\
    --out, -o path       : Specify an output filename (default image base).\n\
    --filter, -f \"a q\" : Set Filter a and q values (default 0.75 0.25).\n\
    --debug, -d          : Save all pipeline steps.\n\
    --complex, -x        : Output complex data.\n\
    --threads, -T N      : Use N threads (default=hardware limit).\n"
};

const struct option long_options[] = {
    {"help", no_argument, 0, 'h'},
    {"verbose", no_argument, 0, 'v'},
    {"out", required_argument, 0, 'o'},
    {"filter", required_argument, 0, 'f'},
    {"debug", no_argument, 0, 'd'},
    {"complex", no_argument, 0, 'x'},
    {"threads", required_argument, 0, 'T'},
    {0, 0, 0, 0}
};
const char *short_options = "hvo:m:e:dxT:";

//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv) {
    Eigen::initParallel();

    bool verbose = false, debug = false, is_complex = false;
    double filter_a = 0.75, filter_q = 0.25;
    string out_name;
    int indexptr = 0, c;
    while ((c = getopt_long(argc, argv, short_options, long_options, &indexptr)) != -1) {
        switch (c) {
            case 'v': verbose = true; break;
            case 'o':
                out_name = optarg;
                cout << "Output filename will be: " << out_name << endl;
                break;
            case 'f': {
                stringstream f(optarg);
                f >> filter_a >> filter_q;
            } break;
            case 'd': debug = true; break;
            case 'x': is_complex = true; break;
            case 'T': itk::MultiThreader::SetGlobalMaximumNumberOfThreads(atoi(optarg)); break;
            case 'h':
                cout << QI::GetVersion() << endl << usage << endl;
                return EXIT_SUCCESS;
            case '?': // getopt will print an error message
                return EXIT_FAILURE;
            default:
                cout << "Unhandled option " << string(1, c) << endl;
                return EXIT_FAILURE;
        }
    }
    if ((argc - optind) != 1) {
        cout << "Incorrect number of arguments." << endl << usage << endl;
        return EXIT_FAILURE;
    }

    string in_name(argv[optind++]);
    if (out_name == "")
        out_name = in_name.substr(0, in_name.find(".")) + "_filtered";

    TukeyKernel filter_kernel;
    filter_kernel.setAQ(filter_a, filter_q);
    QI::TimeseriesXF::Pointer vols = run_pipeline(in_name, out_name, verbose, debug, filter_kernel);
    if (is_complex) {
        if (verbose) cout << "Data is complex." << endl;
        QI::WriteImage(vols, out_name + QI::OutExt());
    } else {
        if (verbose) cout << "Data is real." << endl;
        if (verbose) cout << "Writing output:" << out_name + QI::OutExt() << endl;
        auto mag = itk::ComplexToModulusImageFilter<QI::TimeseriesXF, QI::TimeseriesF>::New();
        mag->SetInput(vols);
        mag->Update();
        QI::WriteImage(mag->GetOutput(), out_name + QI::OutExt());
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*Copyright (c) 2012-2014 Alexander Turkin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <QtGui/QPainter>
#include <QtCore/QTimer>

#include "QtWaitingSpinner.h"

// Defaults
const QColor c_color(Qt::black);
const qreal c_roundness(70.0);
const int c_lines(12);
const int c_length(7);
const int c_width(5);
const int c_radius(10);
const int c_speed(1);
const int c_trail(70);
const int c_opacity(15);

QtWaitingSpinner::QtWaitingSpinner(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags),
    myLinesNumber(c_lines),
    myLength(c_length + c_width),
    myWidth(c_width),
    myRadius(c_radius),
    myRoundness(c_roundness),
    myColor(c_color),
    mySpeed(c_speed),
    myTrail(c_trail),
    myOpacity(c_opacity),
    myTimer(NULL),
    myCurrentCounter(0)
{
    initialise();
}

QtWaitingSpinner::QtWaitingSpinner(int linesNumber, int length, int width, int radius, QWidget *parent) : QWidget(parent),
	myLinesNumber(linesNumber),
	myLength(length + width),
	myWidth(width),
	myRadius(radius),
    myRoundness(c_roundness),
    myColor(c_color),
    mySpeed(c_speed),
    myTrail(c_trail),
    myOpacity(c_opacity),
    myTimer(NULL),
    myCurrentCounter(0)
{
    initialise();
}

void QtWaitingSpinner::initialise() {
    myTimer = new QTimer(this);
    connect(myTimer,SIGNAL(timeout()), this, SLOT(rotate()));
    updateSize();
    updateTimer();
    this->hide();
}

void QtWaitingSpinner::paintEvent(QPaintEvent */*ev*/) {
	QPainter painter(this);
	painter.fillRect(this->rect(), Qt::transparent);
	painter.setRenderHint(QPainter::Antialiasing, true);

	if (myCurrentCounter >= myLinesNumber) {
		myCurrentCounter = 0;
	}
	painter.setPen(Qt::NoPen);
	for (int i = 0; i < myLinesNumber; ++i) {
		painter.save();
		painter.translate(myRadius + myLength, myRadius + myLength);
		qreal rotateAngle = (qreal)360 * qreal(i) / qreal(myLinesNumber);
		painter.rotate(rotateAngle);
		painter.translate(myRadius, 0);
		int distance = lineDistance(i, myCurrentCounter, myLinesNumber);
		QColor color = countTrailColor(distance, myLinesNumber, myTrail, myOpacity, myColor);
		painter.setBrush(color);
		//TODO improve the way rounded rect is painted
		painter.drawRoundedRect(QRect(0, -myWidth/2, myLength, myWidth), myRoundness, myRoundness, Qt::RelativeSize);
		painter.restore();
	}
}

void QtWaitingSpinner::start() {
	this->show();
	if (!myTimer->isActive()) {
		myTimer->start();
		myCurrentCounter = 0;
	}
}

void QtWaitingSpinner::finish() {
	this->hide();
	if (myTimer->isActive()) {
		myTimer->stop();
		myCurrentCounter = 0;
	}
}

void QtWaitingSpinner::setLinesNumber(int linesNumber) {
	myLinesNumber = linesNumber;
	myCurrentCounter = 0;
	updateTimer();
}

void QtWaitingSpinner::setLength(int length){
	myLength = length;
	updateSize();
}

void QtWaitingSpinner::setWidth(int width) {
	myWidth = width;
	updateSize();
}

void QtWaitingSpinner::setRadius(int radius) {
	myRadius = radius;
	updateSize();
}

void QtWaitingSpinner::setRoundness(qreal roundness) {
	myRoundness = std::max(0.0, std::min(100.0, roundness));
}

void QtWaitingSpinner::setColor(QColor color) {
	myColor = color;
}

void QtWaitingSpinner::setSpeed(qreal speed) {
	mySpeed = speed;
	updateTimer();
}

void QtWaitingSpinner::setTrail(int trail) {
	myTrail = trail;
}

void QtWaitingSpinner::setOpacity(int minOpacity) {
	myOpacity = minOpacity;
}

void QtWaitingSpinner::rotate() {
	++myCurrentCounter;
	if (myCurrentCounter >= myLinesNumber) {
		myCurrentCounter = 0;
	}
	update();
}

void QtWaitingSpinner::updateSize() {
	int size = (myRadius + myLength) * 2;
	setFixedSize(size, size);
}

void QtWaitingSpinner::updateTimer() {
	myTimer->setInterval(countTimeout(myLinesNumber, mySpeed));
}

int QtWaitingSpinner::countTimeout(int lines, qreal speed) {
	return 1000 / (lines * speed);
}

int QtWaitingSpinner::lineDistance(int from, int to, int lines) {
	int result = to - from;
	if (result < 0) {
		result += lines;
	}
	return result;
}

QColor QtWaitingSpinner::countTrailColor(int distance, int lines, int trail, int minOpacity, QColor color) {
	if (distance == 0) {
		return color;
	}
	const qreal minAlphaF = (qreal)minOpacity / 100;
	int distanceThreshold = ceil( (lines - 1) * (qreal)trail / 100);
	if (distance > distanceThreshold) {
		color.setAlphaF(minAlphaF);
		return color;
	}
	qreal alphaDiff = color.alphaF() - (qreal)minAlphaF;
	qreal gradation = alphaDiff / (qreal)(distanceThreshold + 1);
	qreal resultAlpha = color.alphaF() - gradation * distance;
	resultAlpha = std::min(1.0, std::max(0.0, resultAlpha)); //if alpha is out of bound, force it to bounds
	color.setAlphaF(resultAlpha);
    return color;
}

<commit_msg>Although my compiler isn't complaining when I remove the cmath and algorithm #includes, I am suspicious...added them back<commit_after>/*Copyright (c) 2012-2014 Alexander Turkin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <cmath>
#include <algorithm>

#include <QtGui/QPainter>
#include <QtCore/QTimer>

#include "QtWaitingSpinner.h"

// Defaults
const QColor c_color(Qt::black);
const qreal c_roundness(70.0);
const int c_lines(12);
const int c_length(7);
const int c_width(5);
const int c_radius(10);
const int c_speed(1);
const int c_trail(70);
const int c_opacity(15);

QtWaitingSpinner::QtWaitingSpinner(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags),
    myLinesNumber(c_lines),
    myLength(c_length + c_width),
    myWidth(c_width),
    myRadius(c_radius),
    myRoundness(c_roundness),
    myColor(c_color),
    mySpeed(c_speed),
    myTrail(c_trail),
    myOpacity(c_opacity),
    myTimer(NULL),
    myCurrentCounter(0)
{
    initialise();
}

QtWaitingSpinner::QtWaitingSpinner(int linesNumber, int length, int width, int radius, QWidget *parent) : QWidget(parent),
	myLinesNumber(linesNumber),
	myLength(length + width),
	myWidth(width),
	myRadius(radius),
    myRoundness(c_roundness),
    myColor(c_color),
    mySpeed(c_speed),
    myTrail(c_trail),
    myOpacity(c_opacity),
    myTimer(NULL),
    myCurrentCounter(0)
{
    initialise();
}

void QtWaitingSpinner::initialise() {
    myTimer = new QTimer(this);
    connect(myTimer,SIGNAL(timeout()), this, SLOT(rotate()));
    updateSize();
    updateTimer();
    this->hide();
}

void QtWaitingSpinner::paintEvent(QPaintEvent */*ev*/) {
	QPainter painter(this);
	painter.fillRect(this->rect(), Qt::transparent);
	painter.setRenderHint(QPainter::Antialiasing, true);

	if (myCurrentCounter >= myLinesNumber) {
		myCurrentCounter = 0;
	}
	painter.setPen(Qt::NoPen);
	for (int i = 0; i < myLinesNumber; ++i) {
		painter.save();
		painter.translate(myRadius + myLength, myRadius + myLength);
		qreal rotateAngle = (qreal)360 * qreal(i) / qreal(myLinesNumber);
		painter.rotate(rotateAngle);
		painter.translate(myRadius, 0);
		int distance = lineDistance(i, myCurrentCounter, myLinesNumber);
		QColor color = countTrailColor(distance, myLinesNumber, myTrail, myOpacity, myColor);
		painter.setBrush(color);
		//TODO improve the way rounded rect is painted
		painter.drawRoundedRect(QRect(0, -myWidth/2, myLength, myWidth), myRoundness, myRoundness, Qt::RelativeSize);
		painter.restore();
	}
}

void QtWaitingSpinner::start() {
	this->show();
	if (!myTimer->isActive()) {
		myTimer->start();
		myCurrentCounter = 0;
	}
}

void QtWaitingSpinner::finish() {
	this->hide();
	if (myTimer->isActive()) {
		myTimer->stop();
		myCurrentCounter = 0;
	}
}

void QtWaitingSpinner::setLinesNumber(int linesNumber) {
	myLinesNumber = linesNumber;
	myCurrentCounter = 0;
	updateTimer();
}

void QtWaitingSpinner::setLength(int length){
	myLength = length;
	updateSize();
}

void QtWaitingSpinner::setWidth(int width) {
	myWidth = width;
	updateSize();
}

void QtWaitingSpinner::setRadius(int radius) {
	myRadius = radius;
	updateSize();
}

void QtWaitingSpinner::setRoundness(qreal roundness) {
	myRoundness = std::max(0.0, std::min(100.0, roundness));
}

void QtWaitingSpinner::setColor(QColor color) {
	myColor = color;
}

void QtWaitingSpinner::setSpeed(qreal speed) {
	mySpeed = speed;
	updateTimer();
}

void QtWaitingSpinner::setTrail(int trail) {
	myTrail = trail;
}

void QtWaitingSpinner::setOpacity(int minOpacity) {
	myOpacity = minOpacity;
}

void QtWaitingSpinner::rotate() {
	++myCurrentCounter;
	if (myCurrentCounter >= myLinesNumber) {
		myCurrentCounter = 0;
	}
	update();
}

void QtWaitingSpinner::updateSize() {
	int size = (myRadius + myLength) * 2;
	setFixedSize(size, size);
}

void QtWaitingSpinner::updateTimer() {
	myTimer->setInterval(countTimeout(myLinesNumber, mySpeed));
}

int QtWaitingSpinner::countTimeout(int lines, qreal speed) {
	return 1000 / (lines * speed);
}

int QtWaitingSpinner::lineDistance(int from, int to, int lines) {
	int result = to - from;
	if (result < 0) {
		result += lines;
	}
	return result;
}

QColor QtWaitingSpinner::countTrailColor(int distance, int lines, int trail, int minOpacity, QColor color) {
	if (distance == 0) {
		return color;
	}
	const qreal minAlphaF = (qreal)minOpacity / 100;
	int distanceThreshold = ceil( (lines - 1) * (qreal)trail / 100);
	if (distance > distanceThreshold) {
		color.setAlphaF(minAlphaF);
		return color;
	}
	qreal alphaDiff = color.alphaF() - (qreal)minAlphaF;
	qreal gradation = alphaDiff / (qreal)(distanceThreshold + 1);
	qreal resultAlpha = color.alphaF() - gradation * distance;
	resultAlpha = std::min(1.0, std::max(0.0, resultAlpha)); //if alpha is out of bound, force it to bounds
	color.setAlphaF(resultAlpha);
    return color;
}

<|endoftext|>


<commit_before>#include <Eigen/Geometry>
#include <ros/ros.h>
#include <tf/transform_datatypes.h>
#include <tf/transform_listener.h>
#include <geometry_msgs/QuaternionStamped.h>
#include <nav_msgs/Odometry.h>
#include <sensor_msgs/Imu.h>
#include <robot_kf/robot_kf.h>

// TODO: Deal with TF frames.

static boost::shared_ptr<tf::TransformListener> sub_tf;
static ros::Subscriber sub_compass;
static ros::Subscriber sub_encoders;
static ros::Subscriber sub_gps;
static ros::Publisher  pub_fused;
static robot_kf::KalmanFilter kf;
static std::string frame;

static bool watch_compass;
static bool watch_encoders;
static bool watch_gps;
static std::string frame_id;

static void publish(void)
{
}

static void updateCompass(sensor_msgs::Imu const &msg)
{
    double const yaw = tf::getYaw(msg.orientation);
    double const cov = msg.orientation_covariance[8];

    kf.update_compass(yaw, cov);
    if (watch_compass) publish();
}

static void updateEncoders(nav_msgs::Odometry const &msg)
{
    Eigen::Vector3d const z = (Eigen::Vector3d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y,
        tf::getYaw(msg.pose.pose.orientation)
    ).finished();

    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );

    Eigen::Matrix3d cov_z = Eigen::Matrix3d::Zero();
    cov_z.topLeftCorner<2, 2>() = cov_raw.topLeftCorner<2, 2>();
    cov_z(2, 2) = cov_raw(5, 5);

    kf.update_encoders(z, cov_z);
    if (watch_encoders) publish();
}

static void updateGps(nav_msgs::Odometry const &msg)
{
    Eigen::Vector2d const z = (Eigen::Vector2d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y
    ).finished();

    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );
    Eigen::Matrix2d const cov_z = cov_raw.topLeftCorner<2, 2>();

    kf.update_gps(z, cov_z);
    if (watch_gps) publish();
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "robot_kf_node");

    ros::NodeHandle nh;
    nh.param<bool>("watch_compass",  watch_compass,  true);
    nh.param<bool>("watch_encoders", watch_encoders, true);
    nh.param<bool>("watch_gps",      watch_gps,      true);
    nh.param<std::string>("frame_id", frame_id, "/odom_fused");

    sub_tf = boost::make_shared<tf::TransformListener>();
    sub_compass  = nh.subscribe("compass", 1, &updateCompass);
    sub_encoders = nh.subscribe("odom", 1, &updateEncoders);
    sub_gps      = nh.subscribe("gps", 1, &updateGps);
    pub_fused    = nh.advertise<nav_msgs::Odometry>("odom_fused", 100);

    ros::spin();
    return 0;
}
<commit_msg>published the fused odometry message<commit_after>#include <Eigen/Geometry>
#include <ros/ros.h>
#include <tf/transform_datatypes.h>
#include <tf/transform_listener.h>
#include <geometry_msgs/QuaternionStamped.h>
#include <nav_msgs/Odometry.h>
#include <sensor_msgs/Imu.h>
#include <robot_kf/robot_kf.h>

// TODO: Deal with TF frames.

static double const big = 99999.0;

static boost::shared_ptr<tf::TransformListener> sub_tf;
static ros::Subscriber sub_compass;
static ros::Subscriber sub_encoders;
static ros::Subscriber sub_gps;
static ros::Publisher  pub_fused;
static robot_kf::KalmanFilter kf;

static bool watch_compass;
static bool watch_encoders;
static bool watch_gps;
static std::string frame_id, child_frame_id;

static void publish(void)
{
    Eigen::Vector3d const state = kf.getState();
    Eigen::Matrix3d const cov = kf.getCovariance();

    nav_msgs::Odometry msg;
    msg.header.stamp = ros::Time::now();
    msg.header.frame_id = frame_id;
    msg.child_frame_id = child_frame_id;
    msg.pose.pose.position.x = state[0];
    msg.pose.pose.position.y = state[1];
    tf::quaternionTFToMsg(tf::createQuaternionFromYaw(state[2]),
                          msg.pose.pose.orientation);

    Eigen::Map<Eigen::Matrix<double, 6, 6> > cov_raw(&msg.pose.covariance[0]);
    cov_raw << cov(0,0), cov(0,1), 0.0, 0.0, 0.0, cov(0,2),
               cov(1,0), cov(1,1), 0.0, 0.0, 0.0, cov(1,2),
               0.0,      0.0,      big, 0.0, 0.0, 0.0,
               0.0,      0.0,      0.0, big, 0.0, 0.0,
               0.0,      0.0,      0.0, 0.0, big, 0.0,
               cov(2,0), cov(2,1), 0.0, 0.0, 0.0, cov(2,2);
    msg.twist.covariance[0] = -1;
    pub_fused.publish(msg);
}

static void updateCompass(sensor_msgs::Imu const &msg)
{
    double const yaw = tf::getYaw(msg.orientation);
    double const cov = msg.orientation_covariance[8];

    kf.update_compass(yaw, cov);
    if (watch_compass) publish();
}

static void updateEncoders(nav_msgs::Odometry const &msg)
{
    Eigen::Vector3d const z = (Eigen::Vector3d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y,
        tf::getYaw(msg.pose.pose.orientation)
    ).finished();

    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );

    Eigen::Matrix3d cov_z = Eigen::Matrix3d::Zero();
    cov_z.topLeftCorner<2, 2>() = cov_raw.topLeftCorner<2, 2>();
    cov_z(2, 2) = cov_raw(5, 5);

    kf.update_encoders(z, cov_z);
    if (watch_encoders) publish();
}

static void updateGps(nav_msgs::Odometry const &msg)
{
    Eigen::Vector2d const z = (Eigen::Vector2d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y
    ).finished();

    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );
    Eigen::Matrix2d const cov_z = cov_raw.topLeftCorner<2, 2>();

    kf.update_gps(z, cov_z);
    if (watch_gps) publish();
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "robot_kf_node");

    ros::NodeHandle nh;
    nh.param<bool>("watch_compass",  watch_compass,  true);
    nh.param<bool>("watch_encoders", watch_encoders, true);
    nh.param<bool>("watch_gps",      watch_gps,      true);
    nh.param<std::string>("frame_id", frame_id, "/map");
    nh.param<std::string>("child_frame_id", child_frame_id, "/odom");

    sub_tf = boost::make_shared<tf::TransformListener>();
    sub_compass  = nh.subscribe("compass", 1, &updateCompass);
    sub_encoders = nh.subscribe("odom", 1, &updateEncoders);
    sub_gps      = nh.subscribe("gps", 1, &updateGps);
    pub_fused    = nh.advertise<nav_msgs::Odometry>("odom_fused", 100);

    ros::spin();
    return 0;
}
<|endoftext|>


<commit_before><commit_msg>added reserve handling for doctor<commit_after><|endoftext|>


<commit_before>// Copyright Daniel Wallin, Arvid Norberg 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/session.hpp>
#include <libtorrent/torrent.hpp>
#include <libtorrent/storage.hpp>
#include <libtorrent/ip_filter.hpp>
#include <boost/python.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

extern char const* session_status_doc;
extern char const* session_status_has_incoming_connections_doc;
extern char const* session_status_upload_rate_doc;
extern char const* session_status_download_rate_doc;
extern char const* session_status_payload_upload_rate_doc;
extern char const* session_status_payload_download_rate_doc;
extern char const* session_status_total_download_doc;
extern char const* session_status_total_upload_doc;
extern char const* session_status_total_payload_download_doc;
extern char const* session_status_total_payload_upload_doc;
extern char const* session_status_num_peers_doc;
extern char const* session_status_dht_nodes_doc;
extern char const* session_status_cache_nodes_doc;
extern char const* session_status_dht_torrents_doc;

extern char const* session_doc;
extern char const* session_init_doc;
extern char const* session_listen_on_doc;
extern char const* session_is_listening_doc;
extern char const* session_listen_port_doc;
extern char const* session_status_m_doc;
extern char const* session_start_dht_doc;
extern char const* session_stop_dht_doc;
extern char const* session_dht_state_doc;
extern char const* session_add_dht_router_doc;
extern char const* session_add_torrent_doc;
extern char const* session_remove_torrent_doc;
extern char const* session_set_download_rate_limit_doc;
extern char const* session_download_rate_limit_doc;
extern char const* session_set_upload_rate_limit_doc;
extern char const* session_upload_rate_limit_doc;
extern char const* session_set_max_uploads_doc;
extern char const* session_set_max_connections_doc;
extern char const* session_set_max_half_open_connections_doc;
extern char const* session_num_connections_doc;
extern char const* session_set_settings_doc;
extern char const* session_set_pe_settings_doc;
extern char const* session_get_pe_settings_doc;
extern char const* session_set_severity_level_doc;
extern char const* session_pop_alert_doc;
extern char const* session_start_upnp_doc;
extern char const* session_start_lsd_doc;
extern char const* session_stop_lsd_doc;
extern char const* session_stop_upnp_doc;
extern char const* session_start_natpmp_doc;
extern char const* session_stop_natpmp_doc;
extern char const* session_set_ip_filter_doc;

namespace
{

  bool listen_on(session& s, int min_, int max_, char const* interface)
  {
      allow_threading_guard guard;
      return s.listen_on(std::make_pair(min_, max_), interface);
  }
  void outgoing_ports(session& s, int _min, int _max)
  {
      allow_threading_guard guard;
      session_settings settings = s.settings();
      settings.outgoing_ports = std::make_pair(_min, _max);
      s.set_settings(settings);
      return;
  }
#ifndef TORRENT_DISABLE_DHT
  void add_dht_router(session& s, std::string router_, int port_)
  {
      allow_threading_guard guard;
      return s.add_dht_router(std::make_pair(router_, port_));
  }
#endif

  struct invoke_extension_factory
  {
      invoke_extension_factory(object const& callback)
        : cb(callback)
      {}

      boost::shared_ptr<torrent_plugin> operator()(torrent* t, void*)
      {
          lock_gil lock;
          return extract<boost::shared_ptr<torrent_plugin> >(cb(ptr(t)))();
      }

      object cb;
  };

  void add_extension(session& s, object const& e)
  {
      allow_threading_guard guard;
      s.add_extension(invoke_extension_factory(e));
  }

  torrent_handle add_torrent(session& s, dict params)
  {
    add_torrent_params p;

    if (params.has_key("ti"))
      p.ti = new torrent_info(extract<torrent_info const&>(params["ti"]));

    std::string url;
    if (params.has_key("tracker_url"))
    {
      url = extract<std::string>(params["tracker_url"]);
      p.tracker_url = url.c_str();
    }
    if (params.has_key("info_hash"))
      p.info_hash = extract<sha1_hash>(params["info_hash"]);
    std::string name;
    if (params.has_key("name"))
    {
      name = extract<std::string>(params["name"]);
      p.name = name.c_str();
    }
    p.save_path = fs::path(extract<std::string>(params["save_path"]));

    std::vector<char> resume_buf;
    if (params.has_key("resume_data"))
    {
      std::string resume = extract<std::string>(params["resume_data"]);
      resume_buf.resize(resume.size());
      std::memcpy(&resume_buf[0], &resume[0], resume.size());
      p.resume_data = &resume_buf;
    }
    p.storage_mode = extract<storage_mode_t>(params["storage_mode"]);
    p.paused = params["paused"];
    p.auto_managed = params["auto_managed"];
    p.duplicate_is_error = params["duplicate_is_error"];

    return s.add_torrent(p);
  }

  void start_natpmp(session& s)
  {
      allow_threading_guard guard;
      s.start_natpmp();
      return;
  }

  void start_upnp(session& s)
  {
      allow_threading_guard guard;
      s.start_upnp();
      return;
  }

  list get_torrents(session& s)
  {
     list ret;
     std::vector<torrent_handle> torrents = s.get_torrents();

     for (std::vector<torrent_handle>::iterator i = torrents.begin(); i != torrents.end(); ++i)
     {
       ret.append(*i);
     }
     return ret;
  }

#ifndef TORRENT_DISABLE_GEO_IP
  bool load_asnum_db(session& s, std::string file)
  {
      allow_threading_guard guard;
      return s.load_asnum_db(file.c_str());
  }

  bool load_country_db(session& s, std::string file)
  {
      allow_threading_guard guard;
      return s.load_country_db(file.c_str());
  }
#endif
} // namespace unnamed

void bind_session()
{
    class_<session_status>("session_status", session_status_doc)
        .def_readonly(
            "has_incoming_connections", &session_status::has_incoming_connections
          , session_status_has_incoming_connections_doc
        )
        .def_readonly(
            "upload_rate", &session_status::upload_rate
          , session_status_upload_rate_doc
        )
        .def_readonly(
            "download_rate", &session_status::download_rate
          , session_status_download_rate_doc
        )
        .def_readonly(
            "payload_upload_rate", &session_status::payload_upload_rate
          , session_status_payload_upload_rate_doc
        )
        .def_readonly(
            "payload_download_rate", &session_status::payload_download_rate
          , session_status_payload_download_rate_doc
        )
        .def_readonly(
            "total_download", &session_status::total_download
          , session_status_total_download_doc
        )
        .def_readonly(
            "total_upload", &session_status::total_upload
          , session_status_total_upload_doc
        )
        .def_readonly(
            "total_payload_download", &session_status::total_payload_download
          , session_status_total_payload_download_doc
        )
        .def_readonly(
            "total_payload_upload", &session_status::total_payload_upload
          , session_status_total_payload_upload_doc
        )
        .def_readonly(
            "num_peers", &session_status::num_peers
          , session_status_num_peers_doc
        )
#ifndef TORRENT_DISABLE_DHT
        .def_readonly(
            "dht_nodes", &session_status::dht_nodes
          , session_status_dht_nodes_doc
        )
        .def_readonly(
            "dht_cache_nodes", &session_status::dht_node_cache
          , session_status_cache_nodes_doc
        )
        .def_readonly(
            "dht_torrents", &session_status::dht_torrents
          , session_status_dht_torrents_doc
        )
#endif
        ;

    enum_<storage_mode_t>("storage_mode_t")
        .value("storage_mode_allocate", storage_mode_allocate)
        .value("storage_mode_sparse", storage_mode_sparse)
        .value("storage_mode_compact", storage_mode_compact)
    ;

    enum_<session::options_t>("options_t")
        .value("none", session::none)
        .value("delete_files", session::delete_files)
    ;

    class_<session, boost::noncopyable>("session", session_doc, no_init)
        .def(
            init<fingerprint>(arg("fingerprint")=fingerprint("LT",0,1,0,0), session_init_doc)
        )
        .def(
            "listen_on", &listen_on
          , (arg("min"), "max", arg("interface") = (char const*)0)
          , session_listen_on_doc
        )
        .def("outgoing_ports", &outgoing_ports)
        .def("is_listening", allow_threads(&session::is_listening), session_is_listening_doc)
        .def("listen_port", allow_threads(&session::listen_port), session_listen_port_doc)
        .def("status", allow_threads(&session::status), session_status_m_doc)
#ifndef TORRENT_DISABLE_DHT
        .def(
            "add_dht_router", &add_dht_router
          , (arg("router"), "port")
          , session_add_dht_router_doc
        )
        .def("start_dht", allow_threads(&session::start_dht), session_start_dht_doc)
        .def("stop_dht", allow_threads(&session::stop_dht), session_stop_dht_doc)
        .def("dht_state", allow_threads(&session::dht_state), session_dht_state_doc)
        .def("set_dht_proxy", allow_threads(&session::set_dht_proxy))
#endif
        .def("add_torrent", &add_torrent, session_add_torrent_doc)
        .def("remove_torrent", allow_threads(&session::remove_torrent), arg("option") = session::none
			  , session_remove_torrent_doc)
        .def(
            "set_download_rate_limit", allow_threads(&session::set_download_rate_limit)
          , session_set_download_rate_limit_doc
        )
        .def(
            "download_rate_limit", allow_threads(&session::download_rate_limit)
          , session_download_rate_limit_doc
        )

        .def(
            "set_upload_rate_limit", allow_threads(&session::set_upload_rate_limit)
          , session_set_upload_rate_limit_doc
        )
        .def(
            "upload_rate_limit", allow_threads(&session::upload_rate_limit)
          , session_upload_rate_limit_doc
        )

        .def(
            "set_max_uploads", allow_threads(&session::set_max_uploads)
          , session_set_max_uploads_doc
        )
        .def(
            "set_max_connections", allow_threads(&session::set_max_connections)
          , session_set_max_connections_doc
        )
        .def(
            "set_max_half_open_connections", allow_threads(&session::set_max_half_open_connections)
          , session_set_max_half_open_connections_doc
        )
        .def(
            "num_connections", allow_threads(&session::num_connections)
          , session_num_connections_doc
        )
        .def("set_settings", allow_threads(&session::set_settings), session_set_settings_doc)
        .def("settings", allow_threads(&session::settings), return_value_policy<copy_const_reference>())
#ifndef TORRENT_DISABLE_ENCRYPTION
        .def("set_pe_settings", allow_threads(&session::set_pe_settings), session_set_pe_settings_doc)
        .def("get_pe_settings", allow_threads(&session::get_pe_settings), return_value_policy<copy_const_reference>())
#endif
#ifndef TORRENT_DISABLE_GEO_IP
        .def("load_asnum_db", &load_asnum_db)
        .def("load_country_db", &load_country_db)
#endif
        .def("load_state", allow_threads(&session::load_state))
        .def("state", allow_threads(&session::state))
        .def(
            "set_severity_level", allow_threads(&session::set_severity_level)
          , session_set_severity_level_doc
        )
        .def("set_alert_mask", allow_threads(&session::set_alert_mask))
        .def("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc)
        .def("add_extension", &add_extension)
        .def("set_peer_proxy", allow_threads(&session::set_peer_proxy))
        .def("set_tracker_proxy", allow_threads(&session::set_tracker_proxy))
        .def("set_web_seed_proxy", allow_threads(&session::set_web_seed_proxy))
        .def("start_upnp", &start_upnp, session_start_upnp_doc)
        .def("stop_upnp", allow_threads(&session::stop_upnp), session_stop_upnp_doc)
        .def("start_lsd", allow_threads(&session::start_lsd), session_start_lsd_doc)
        .def("stop_lsd", allow_threads(&session::stop_lsd), session_stop_lsd_doc)
        .def("start_natpmp", &start_natpmp, session_start_natpmp_doc)
        .def("stop_natpmp", allow_threads(&session::stop_natpmp), session_stop_natpmp_doc)
        .def("set_ip_filter", allow_threads(&session::set_ip_filter), session_set_ip_filter_doc)
        .def("find_torrent", allow_threads(&session::find_torrent))
        .def("get_torrents", &get_torrents)
        .def("pause", allow_threads(&session::pause))
        .def("resume", allow_threads(&session::resume))
        .def("is_paused", allow_threads(&session::is_paused))
        ;

    register_ptr_to_python<std::auto_ptr<alert> >();
}

<commit_msg>update session constructor in python bindings to support 'flags'<commit_after>// Copyright Daniel Wallin, Arvid Norberg 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/session.hpp>
#include <libtorrent/torrent.hpp>
#include <libtorrent/storage.hpp>
#include <libtorrent/ip_filter.hpp>
#include <boost/python.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

extern char const* session_status_doc;
extern char const* session_status_has_incoming_connections_doc;
extern char const* session_status_upload_rate_doc;
extern char const* session_status_download_rate_doc;
extern char const* session_status_payload_upload_rate_doc;
extern char const* session_status_payload_download_rate_doc;
extern char const* session_status_total_download_doc;
extern char const* session_status_total_upload_doc;
extern char const* session_status_total_payload_download_doc;
extern char const* session_status_total_payload_upload_doc;
extern char const* session_status_num_peers_doc;
extern char const* session_status_dht_nodes_doc;
extern char const* session_status_cache_nodes_doc;
extern char const* session_status_dht_torrents_doc;

extern char const* session_doc;
extern char const* session_init_doc;
extern char const* session_listen_on_doc;
extern char const* session_is_listening_doc;
extern char const* session_listen_port_doc;
extern char const* session_status_m_doc;
extern char const* session_start_dht_doc;
extern char const* session_stop_dht_doc;
extern char const* session_dht_state_doc;
extern char const* session_add_dht_router_doc;
extern char const* session_add_torrent_doc;
extern char const* session_remove_torrent_doc;
extern char const* session_set_download_rate_limit_doc;
extern char const* session_download_rate_limit_doc;
extern char const* session_set_upload_rate_limit_doc;
extern char const* session_upload_rate_limit_doc;
extern char const* session_set_max_uploads_doc;
extern char const* session_set_max_connections_doc;
extern char const* session_set_max_half_open_connections_doc;
extern char const* session_num_connections_doc;
extern char const* session_set_settings_doc;
extern char const* session_set_pe_settings_doc;
extern char const* session_get_pe_settings_doc;
extern char const* session_set_severity_level_doc;
extern char const* session_pop_alert_doc;
extern char const* session_start_upnp_doc;
extern char const* session_start_lsd_doc;
extern char const* session_stop_lsd_doc;
extern char const* session_stop_upnp_doc;
extern char const* session_start_natpmp_doc;
extern char const* session_stop_natpmp_doc;
extern char const* session_set_ip_filter_doc;

namespace
{

  bool listen_on(session& s, int min_, int max_, char const* interface)
  {
      allow_threading_guard guard;
      return s.listen_on(std::make_pair(min_, max_), interface);
  }
  void outgoing_ports(session& s, int _min, int _max)
  {
      allow_threading_guard guard;
      session_settings settings = s.settings();
      settings.outgoing_ports = std::make_pair(_min, _max);
      s.set_settings(settings);
      return;
  }
#ifndef TORRENT_DISABLE_DHT
  void add_dht_router(session& s, std::string router_, int port_)
  {
      allow_threading_guard guard;
      return s.add_dht_router(std::make_pair(router_, port_));
  }
#endif

  struct invoke_extension_factory
  {
      invoke_extension_factory(object const& callback)
        : cb(callback)
      {}

      boost::shared_ptr<torrent_plugin> operator()(torrent* t, void*)
      {
          lock_gil lock;
          return extract<boost::shared_ptr<torrent_plugin> >(cb(ptr(t)))();
      }

      object cb;
  };

  void add_extension(session& s, object const& e)
  {
      allow_threading_guard guard;
      s.add_extension(invoke_extension_factory(e));
  }

  torrent_handle add_torrent(session& s, dict params)
  {
    add_torrent_params p;

    if (params.has_key("ti"))
      p.ti = new torrent_info(extract<torrent_info const&>(params["ti"]));

    std::string url;
    if (params.has_key("tracker_url"))
    {
      url = extract<std::string>(params["tracker_url"]);
      p.tracker_url = url.c_str();
    }
    if (params.has_key("info_hash"))
      p.info_hash = extract<sha1_hash>(params["info_hash"]);
    std::string name;
    if (params.has_key("name"))
    {
      name = extract<std::string>(params["name"]);
      p.name = name.c_str();
    }
    p.save_path = fs::path(extract<std::string>(params["save_path"]));

    std::vector<char> resume_buf;
    if (params.has_key("resume_data"))
    {
      std::string resume = extract<std::string>(params["resume_data"]);
      resume_buf.resize(resume.size());
      std::memcpy(&resume_buf[0], &resume[0], resume.size());
      p.resume_data = &resume_buf;
    }
    p.storage_mode = extract<storage_mode_t>(params["storage_mode"]);
    p.paused = params["paused"];
    p.auto_managed = params["auto_managed"];
    p.duplicate_is_error = params["duplicate_is_error"];

    return s.add_torrent(p);
  }

  void start_natpmp(session& s)
  {
      allow_threading_guard guard;
      s.start_natpmp();
      return;
  }

  void start_upnp(session& s)
  {
      allow_threading_guard guard;
      s.start_upnp();
      return;
  }

  list get_torrents(session& s)
  {
     list ret;
     std::vector<torrent_handle> torrents = s.get_torrents();

     for (std::vector<torrent_handle>::iterator i = torrents.begin(); i != torrents.end(); ++i)
     {
       ret.append(*i);
     }
     return ret;
  }

#ifndef TORRENT_DISABLE_GEO_IP
  bool load_asnum_db(session& s, std::string file)
  {
      allow_threading_guard guard;
      return s.load_asnum_db(file.c_str());
  }

  bool load_country_db(session& s, std::string file)
  {
      allow_threading_guard guard;
      return s.load_country_db(file.c_str());
  }
#endif
} // namespace unnamed

void bind_session()
{
    class_<session_status>("session_status", session_status_doc)
        .def_readonly(
            "has_incoming_connections", &session_status::has_incoming_connections
          , session_status_has_incoming_connections_doc
        )
        .def_readonly(
            "upload_rate", &session_status::upload_rate
          , session_status_upload_rate_doc
        )
        .def_readonly(
            "download_rate", &session_status::download_rate
          , session_status_download_rate_doc
        )
        .def_readonly(
            "payload_upload_rate", &session_status::payload_upload_rate
          , session_status_payload_upload_rate_doc
        )
        .def_readonly(
            "payload_download_rate", &session_status::payload_download_rate
          , session_status_payload_download_rate_doc
        )
        .def_readonly(
            "total_download", &session_status::total_download
          , session_status_total_download_doc
        )
        .def_readonly(
            "total_upload", &session_status::total_upload
          , session_status_total_upload_doc
        )
        .def_readonly(
            "total_payload_download", &session_status::total_payload_download
          , session_status_total_payload_download_doc
        )
        .def_readonly(
            "total_payload_upload", &session_status::total_payload_upload
          , session_status_total_payload_upload_doc
        )
        .def_readonly(
            "num_peers", &session_status::num_peers
          , session_status_num_peers_doc
        )
#ifndef TORRENT_DISABLE_DHT
        .def_readonly(
            "dht_nodes", &session_status::dht_nodes
          , session_status_dht_nodes_doc
        )
        .def_readonly(
            "dht_cache_nodes", &session_status::dht_node_cache
          , session_status_cache_nodes_doc
        )
        .def_readonly(
            "dht_torrents", &session_status::dht_torrents
          , session_status_dht_torrents_doc
        )
#endif
        ;

    enum_<storage_mode_t>("storage_mode_t")
        .value("storage_mode_allocate", storage_mode_allocate)
        .value("storage_mode_sparse", storage_mode_sparse)
        .value("storage_mode_compact", storage_mode_compact)
    ;

    enum_<session::options_t>("options_t")
        .value("none", session::none)
        .value("delete_files", session::delete_files)
    ;

    enum_<session::session_flags_t>("session_flags_t")
        .value("add_default_plugins", session::add_default_plugins)
        .value("start_default_features", session::start_default_features)
    ;

    class_<session, boost::noncopyable>("session", session_doc, no_init)
        .def(
            init<fingerprint, int>((
                arg("fingerprint")=fingerprint("LT",0,1,0,0)
                , arg("flags")=session::start_default_features | session::add_default_plugins)
                , session_init_doc)
        )
        .def(
            "listen_on", &listen_on
          , (arg("min"), "max", arg("interface") = (char const*)0)
          , session_listen_on_doc
        )
        .def("outgoing_ports", &outgoing_ports)
        .def("is_listening", allow_threads(&session::is_listening), session_is_listening_doc)
        .def("listen_port", allow_threads(&session::listen_port), session_listen_port_doc)
        .def("status", allow_threads(&session::status), session_status_m_doc)
#ifndef TORRENT_DISABLE_DHT
        .def(
            "add_dht_router", &add_dht_router
          , (arg("router"), "port")
          , session_add_dht_router_doc
        )
        .def("start_dht", allow_threads(&session::start_dht), session_start_dht_doc)
        .def("stop_dht", allow_threads(&session::stop_dht), session_stop_dht_doc)
        .def("dht_state", allow_threads(&session::dht_state), session_dht_state_doc)
        .def("set_dht_proxy", allow_threads(&session::set_dht_proxy))
#endif
        .def("add_torrent", &add_torrent, session_add_torrent_doc)
        .def("remove_torrent", allow_threads(&session::remove_torrent), arg("option") = session::none
			  , session_remove_torrent_doc)
        .def(
            "set_download_rate_limit", allow_threads(&session::set_download_rate_limit)
          , session_set_download_rate_limit_doc
        )
        .def(
            "download_rate_limit", allow_threads(&session::download_rate_limit)
          , session_download_rate_limit_doc
        )

        .def(
            "set_upload_rate_limit", allow_threads(&session::set_upload_rate_limit)
          , session_set_upload_rate_limit_doc
        )
        .def(
            "upload_rate_limit", allow_threads(&session::upload_rate_limit)
          , session_upload_rate_limit_doc
        )

        .def(
            "set_max_uploads", allow_threads(&session::set_max_uploads)
          , session_set_max_uploads_doc
        )
        .def(
            "set_max_connections", allow_threads(&session::set_max_connections)
          , session_set_max_connections_doc
        )
        .def(
            "set_max_half_open_connections", allow_threads(&session::set_max_half_open_connections)
          , session_set_max_half_open_connections_doc
        )
        .def(
            "num_connections", allow_threads(&session::num_connections)
          , session_num_connections_doc
        )
        .def("set_settings", allow_threads(&session::set_settings), session_set_settings_doc)
        .def("settings", allow_threads(&session::settings), return_value_policy<copy_const_reference>())
#ifndef TORRENT_DISABLE_ENCRYPTION
        .def("set_pe_settings", allow_threads(&session::set_pe_settings), session_set_pe_settings_doc)
        .def("get_pe_settings", allow_threads(&session::get_pe_settings), return_value_policy<copy_const_reference>())
#endif
#ifndef TORRENT_DISABLE_GEO_IP
        .def("load_asnum_db", &load_asnum_db)
        .def("load_country_db", &load_country_db)
#endif
        .def("load_state", allow_threads(&session::load_state))
        .def("state", allow_threads(&session::state))
        .def(
            "set_severity_level", allow_threads(&session::set_severity_level)
          , session_set_severity_level_doc
        )
        .def("set_alert_mask", allow_threads(&session::set_alert_mask))
        .def("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc)
        .def("add_extension", &add_extension)
        .def("set_peer_proxy", allow_threads(&session::set_peer_proxy))
        .def("set_tracker_proxy", allow_threads(&session::set_tracker_proxy))
        .def("set_web_seed_proxy", allow_threads(&session::set_web_seed_proxy))
        .def("start_upnp", &start_upnp, session_start_upnp_doc)
        .def("stop_upnp", allow_threads(&session::stop_upnp), session_stop_upnp_doc)
        .def("start_lsd", allow_threads(&session::start_lsd), session_start_lsd_doc)
        .def("stop_lsd", allow_threads(&session::stop_lsd), session_stop_lsd_doc)
        .def("start_natpmp", &start_natpmp, session_start_natpmp_doc)
        .def("stop_natpmp", allow_threads(&session::stop_natpmp), session_stop_natpmp_doc)
        .def("set_ip_filter", allow_threads(&session::set_ip_filter), session_set_ip_filter_doc)
        .def("find_torrent", allow_threads(&session::find_torrent))
        .def("get_torrents", &get_torrents)
        .def("pause", allow_threads(&session::pause))
        .def("resume", allow_threads(&session::resume))
        .def("is_paused", allow_threads(&session::is_paused))
        ;

    register_ptr_to_python<std::auto_ptr<alert> >();
}

<|endoftext|>


<commit_before>#ifndef RAISE_HXX
# define RAISE_HXX

# include <scheduler/scheduler.hh>
# include <kernel/userver.hh>
# include <object/float.hh>
# include <object/global.hh>
# include <object/string.hh>
# include <runner/runner.hh>
# include <runner/call.hh>

namespace runner
{
  LIBPORT_SPEED_INLINE
  void
  raise(const object::rObject& exn)
  {
    ::urbiserver->getCurrentRunner().raise(exn);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_lookup_error(libport::Symbol msg, const object::rObject& obj)
  {
    Runner& r = ::urbiserver->getCurrentRunner();
    object::rObject exn =
      object::urbi_call(r,
                        object::global_class->slot_get(SYMBOL(LookupError)),
                        SYMBOL(new), new object::String(msg), obj);
    r.raise(exn);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_arity_error(unsigned effective,
                    unsigned expected)
  {
    Runner& r = ::urbiserver->getCurrentRunner();
    object::rObject exn =
      object::urbi_call(r, object::global_class->slot_get(SYMBOL(ArityError)),
                        SYMBOL(new),
                        new object::String(r.innermost_call_get()),
                        new object::Float(effective),
                        new object::Float(expected));
    r.raise(exn, true);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_arity_error(unsigned effective,
                    unsigned minimum,
                    unsigned maximum)
  {
    Runner& r = ::urbiserver->getCurrentRunner();
    object::rObject exn =
      object::urbi_call(r, object::global_class->slot_get(SYMBOL(ArityError)),
                        SYMBOL(new),
                        new object::String(r.innermost_call_get()),
                        new object::Float(effective),
                        new object::Float(minimum),
                        new object::Float(maximum));
    r.raise(exn, true);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_argument_type_error(unsigned idx,
                            object::rObject effective,
                            object::rObject expected)
  {
    Runner& r = ::urbiserver->getCurrentRunner();
    r.raise(
      object::urbi_call(r, object::global_class->slot_get(SYMBOL(ArgumentTypeError)),
                        SYMBOL(new),
                        new object::String(r.innermost_call_get()),
                        new object::Float(idx),
                        expected,
                        effective),
      true);
    pabort("Unreachable");
  }

}

#endif
<commit_msg>Abort rather than recursing infinitely when LookupError is required to early.<commit_after>#ifndef RAISE_HXX
# define RAISE_HXX

# include <scheduler/scheduler.hh>
# include <kernel/userver.hh>
# include <object/float.hh>
# include <object/global.hh>
# include <object/string.hh>
# include <runner/runner.hh>
# include <runner/call.hh>

namespace runner
{
  LIBPORT_SPEED_INLINE
  void
  raise(const object::rObject& exn)
  {
    ::urbiserver->getCurrentRunner().raise(exn);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_lookup_error(libport::Symbol msg, const object::rObject& obj)
  {
    assert(object::global_class->slot_has(SYMBOL(LookupError)));
    Runner& r = ::urbiserver->getCurrentRunner();
    object::rObject exn =
      object::urbi_call(r,
                        object::global_class->slot_get(SYMBOL(LookupError)),
                        SYMBOL(new), new object::String(msg), obj);
    r.raise(exn);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_arity_error(unsigned effective,
                    unsigned expected)
  {
    Runner& r = ::urbiserver->getCurrentRunner();
    object::rObject exn =
      object::urbi_call(r, object::global_class->slot_get(SYMBOL(ArityError)),
                        SYMBOL(new),
                        new object::String(r.innermost_call_get()),
                        new object::Float(effective),
                        new object::Float(expected));
    r.raise(exn, true);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_arity_error(unsigned effective,
                    unsigned minimum,
                    unsigned maximum)
  {
    Runner& r = ::urbiserver->getCurrentRunner();
    object::rObject exn =
      object::urbi_call(r, object::global_class->slot_get(SYMBOL(ArityError)),
                        SYMBOL(new),
                        new object::String(r.innermost_call_get()),
                        new object::Float(effective),
                        new object::Float(minimum),
                        new object::Float(maximum));
    r.raise(exn, true);
    pabort("Unreachable");
  }

  LIBPORT_SPEED_INLINE
  void
  raise_argument_type_error(unsigned idx,
                            object::rObject effective,
                            object::rObject expected)
  {
    Runner& r = ::urbiserver->getCurrentRunner();
    r.raise(
      object::urbi_call(r, object::global_class->slot_get(SYMBOL(ArgumentTypeError)),
                        SYMBOL(new),
                        new object::String(r.innermost_call_get()),
                        new object::Float(idx),
                        expected,
                        effective),
      true);
    pabort("Unreachable");
  }

}

#endif
<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "Search.h"

#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarblePlacemarkModel.h"

namespace Marble
{
namespace Declarative
{

Search::Search( QObject* parent ) : QObject( parent ),
    m_marbleWidget( 0 ), m_runnerManager( 0 ),
    m_searchResult( 0 ), m_placemarkDelegate( 0 ),
    m_delegateParent( 0 )
{
    // nothing to do
}

void Search::setMarbleWidget( Marble::MarbleWidget* widget )
{
    m_marbleWidget = widget;
    connect( m_marbleWidget, SIGNAL( visibleLatLonAltBoxChanged( GeoDataLatLonAltBox ) ),
             this, SLOT( updatePlacemarks() ) );
}

QDeclarativeComponent* Search::placemarkDelegate()
{
    return m_placemarkDelegate;
}

void Search::setPlacemarkDelegate( QDeclarativeComponent* delegate )
{
    m_placemarkDelegate = delegate;
    emit placemarkDelegateChanged();
}

void Search::setDelegateParent( QGraphicsItem* parent )
{
    m_delegateParent = parent;
}

void Search::find( const QString &searchTerm )
{
    if ( !m_runnerManager && m_marbleWidget ) {
        m_runnerManager = new Marble::MarbleRunnerManager( m_marbleWidget->model()->pluginManager(), this );
        connect( m_runnerManager, SIGNAL( searchFinished( QString ) ),
                 this, SIGNAL( searchFinished() ) );
        connect( m_runnerManager, SIGNAL( searchResultChanged( QAbstractItemModel* ) ),
                 this, SLOT( updateSearchModel( QAbstractItemModel* ) ) );
    }

    if ( m_runnerManager ) {
        m_runnerManager->findPlacemarks( searchTerm );
    }
}

QObject* Search::searchResultModel()
{
    return m_searchResult;
}

void Search::updateSearchModel( QAbstractItemModel *model )
{
    m_searchResult = static_cast<MarblePlacemarkModel*>( model );
    qDeleteAll( m_placemarks.values() );
    m_placemarks.clear();

    if ( !m_placemarkDelegate ) {
        return;
    }

    for ( int i=1; i<m_searchResult->rowCount(); ++i ) {
        QDeclarativeContext *context = new QDeclarativeContext( qmlContext( m_placemarkDelegate ) );
        QObject* component = m_placemarkDelegate->create( context );
        QGraphicsItem* graphicsItem = qobject_cast<QGraphicsItem*>( component );
        QDeclarativeItem* item = qobject_cast<QDeclarativeItem*>( component );
        if ( graphicsItem && item ) {
            context->setContextProperty( "hit", QVariant( QString::number( i ) ) );
            context->setContextProperty( "name", m_searchResult->data( m_searchResult->index( i ), Qt::DisplayRole ) );
            graphicsItem->setParentItem( m_delegateParent );
            m_placemarks[i] = item;
        } else {
            delete component;
        }
    }
    updatePlacemarks();
}

void Search::updatePlacemarks()
{
    if ( m_marbleWidget ) {
        QMap<int, QDeclarativeItem*>::const_iterator iter = m_placemarks.constBegin();
        while ( iter != m_placemarks.constEnd() ) {
            qreal x(0), y(0);
            QVariant position = m_searchResult->data( m_searchResult->index( iter.key() ), MarblePlacemarkModel::CoordinateRole );
            GeoDataCoordinates const coordinates = qVariantValue<GeoDataCoordinates>( position );
            bool const visible = m_marbleWidget->screenCoordinates( coordinates.longitude( GeoDataCoordinates::Degree ), coordinates.latitude( GeoDataCoordinates::Degree ), x, y );
            QDeclarativeItem* item = iter.value();
            if ( item ) {
                item->setVisible( visible );
                if ( visible ) {
                    item->setPos( x - item->width() / 2.0, y - item->height() / 2.0 );
                }
            }
            ++iter;
        }
    }
}

}
}

#include "Search.moc"
<commit_msg>Fix off-by-one error, make lon/lat available as context properties.<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "Search.h"

#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarblePlacemarkModel.h"

namespace Marble
{
namespace Declarative
{

Search::Search( QObject* parent ) : QObject( parent ),
    m_marbleWidget( 0 ), m_runnerManager( 0 ),
    m_searchResult( 0 ), m_placemarkDelegate( 0 ),
    m_delegateParent( 0 )
{
    // nothing to do
}

void Search::setMarbleWidget( Marble::MarbleWidget* widget )
{
    m_marbleWidget = widget;
    connect( m_marbleWidget, SIGNAL( visibleLatLonAltBoxChanged( GeoDataLatLonAltBox ) ),
             this, SLOT( updatePlacemarks() ) );
}

QDeclarativeComponent* Search::placemarkDelegate()
{
    return m_placemarkDelegate;
}

void Search::setPlacemarkDelegate( QDeclarativeComponent* delegate )
{
    m_placemarkDelegate = delegate;
    emit placemarkDelegateChanged();
}

void Search::setDelegateParent( QGraphicsItem* parent )
{
    m_delegateParent = parent;
}

void Search::find( const QString &searchTerm )
{
    if ( !m_runnerManager && m_marbleWidget ) {
        m_runnerManager = new Marble::MarbleRunnerManager( m_marbleWidget->model()->pluginManager(), this );
        connect( m_runnerManager, SIGNAL( searchFinished( QString ) ),
                 this, SIGNAL( searchFinished() ) );
        connect( m_runnerManager, SIGNAL( searchResultChanged( QAbstractItemModel* ) ),
                 this, SLOT( updateSearchModel( QAbstractItemModel* ) ) );
    }

    if ( m_runnerManager ) {
        m_runnerManager->findPlacemarks( searchTerm );
    }
}

QObject* Search::searchResultModel()
{
    return m_searchResult;
}

void Search::updateSearchModel( QAbstractItemModel *model )
{
    m_searchResult = static_cast<MarblePlacemarkModel*>( model );
    qDeleteAll( m_placemarks.values() );
    m_placemarks.clear();

    if ( !m_placemarkDelegate ) {
        return;
    }

    for ( int i=0; i<m_searchResult->rowCount(); ++i ) {
        QDeclarativeContext *context = new QDeclarativeContext( qmlContext( m_placemarkDelegate ) );
        QObject* component = m_placemarkDelegate->create( context );
        QGraphicsItem* graphicsItem = qobject_cast<QGraphicsItem*>( component );
        QDeclarativeItem* item = qobject_cast<QDeclarativeItem*>( component );
        if ( graphicsItem && item ) {
            QVariant position = m_searchResult->data( m_searchResult->index( i ), MarblePlacemarkModel::CoordinateRole );
            GeoDataCoordinates const coordinates = qVariantValue<GeoDataCoordinates>( position );
            context->setContextProperty( "longitude", QVariant( coordinates.longitude( GeoDataCoordinates::Degree ) ) );
            context->setContextProperty( "latitude", QVariant( coordinates.latitude( GeoDataCoordinates::Degree ) ) );
            context->setContextProperty( "hit", QVariant( QString::number( i+1 ) ) );
            context->setContextProperty( "name", m_searchResult->data( m_searchResult->index( i ), Qt::DisplayRole ) );
            graphicsItem->setParentItem( m_delegateParent );
            m_placemarks[i] = item;
        } else {
            delete component;
        }
    }
    updatePlacemarks();
}

void Search::updatePlacemarks()
{
    if ( m_marbleWidget ) {
        QMap<int, QDeclarativeItem*>::const_iterator iter = m_placemarks.constBegin();
        while ( iter != m_placemarks.constEnd() ) {
            qreal x(0), y(0);
            QVariant position = m_searchResult->data( m_searchResult->index( iter.key() ), MarblePlacemarkModel::CoordinateRole );
            GeoDataCoordinates const coordinates = qVariantValue<GeoDataCoordinates>( position );
            bool const visible = m_marbleWidget->screenCoordinates( coordinates.longitude( GeoDataCoordinates::Degree ), coordinates.latitude( GeoDataCoordinates::Degree ), x, y );
            QDeclarativeItem* item = iter.value();
            if ( item ) {
                item->setVisible( visible );
                if ( visible ) {
                    item->setPos( x - item->width() / 2.0, y - item->height() / 2.0 );
                }
            }
            ++iter;
        }
    }
}

}
}

#include "Search.moc"
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2013 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreVolumeSource.h"

#include "OgreRoot.h"
#include "OgreDeflate.h"
#include "OgreStreamSerialiser.h"
#include "OgreBitwise.h"

namespace Ogre {
namespace Volume {

    const uint32 Source::VOLUME_CHUNK_ID = StreamSerialiser::makeIdentifier("VOLU");
    const uint16 Source::VOLUME_CHUNK_VERSION = 1;
    const size_t Source::SERIALIZATION_CHUNK_SIZE = 1000;

    //-----------------------------------------------------------------------

    Vector3 Source::getIntersectionStart(const Ray &ray, Real maxDistance) const
    {
        return ray.getOrigin();
    }

    //-----------------------------------------------------------------------

    Vector3 Source::getIntersectionEnd(const Ray &ray, Real maxDistance) const
    {
        Vector3 dir = ray.getDirection().normalisedCopy();
        return ray.getOrigin() + dir * maxDistance;
    }

    //-----------------------------------------------------------------------

    Source::~Source(void)
    {
    }

    //-----------------------------------------------------------------------

    void Source::serialize(const Vector3 &from, const Vector3 &to, float voxelWidth, const String &file)
    {
        Real maxClampedAbsoluteDensity = (from - to).length() / (Real)16.0;
        serialize(from, to, voxelWidth, maxClampedAbsoluteDensity, file);
    }

    //-----------------------------------------------------------------------

    void Source::serialize(const Vector3 &from, const Vector3 &to, float voxelWidth, Real maxClampedAbsoluteDensity, const String &file)
    {

        Timer t;

        // Compress
        DataStreamPtr stream = Root::getSingleton().createFileStream(file);
        DataStreamPtr compressStream(OGRE_NEW DeflateStream(file, stream));
        StreamSerialiser ser(compressStream);
        ser.writeChunkBegin(VOLUME_CHUNK_ID, VOLUME_CHUNK_VERSION);

        // Write Metadata
        ser.write(&from);
        ser.write(&to);
        ser.write<float>(&voxelWidth);
        Vector3 diagonal = to - from;
        size_t gridWidth = (size_t)(diagonal.x / voxelWidth);
        size_t gridHeight = (size_t)(diagonal.y / voxelWidth);
        size_t gridDepth = (size_t)(diagonal.z / voxelWidth);
        ser.write<size_t>(&gridWidth);
        ser.write<size_t>(&gridHeight);
        ser.write<size_t>(&gridDepth);

        // Go over the volume and write the density data.
        Vector3 pos;
        Real realVal;
        size_t x;
        size_t y;
        uint16 buffer[SERIALIZATION_CHUNK_SIZE];
        size_t bufferI = 0;
        for (size_t z = 0; z < gridDepth; ++z)
        {
            for (x = 0; x < gridWidth; ++x)
            {
                for (y = 0; y < gridHeight; ++y)
                {
                    pos.x = x * voxelWidth + from.x;
                    pos.y = y * voxelWidth + from.y;
                    pos.z = z * voxelWidth + from.z;
                    realVal = Math::Clamp<Real>(getValue(pos), -maxClampedAbsoluteDensity, maxClampedAbsoluteDensity);
                    buffer[bufferI] = Bitwise::floatToHalf(realVal);
                    bufferI++;
                    if (bufferI == SERIALIZATION_CHUNK_SIZE)
                    {
                        ser.write<uint16>(buffer, SERIALIZATION_CHUNK_SIZE);
                        bufferI = 0;
                    }
                }
            }
        }
        if (bufferI > 0)
        {
            ser.write<uint16>(buffer, bufferI);
        }
        LogManager::getSingleton().stream() << "Time for serialization: " << t.getMilliseconds() << "ms";

        ser.writeChunkEnd(VOLUME_CHUNK_ID);

    }

    //-----------------------------------------------------------------------

    bool Source::getFirstRayIntersection(const Ray &ray, Vector3 &result, size_t maxIterations, Real maxDistance) const
    {
        Vector3 start = getIntersectionStart(ray, maxDistance);
        Vector3 cur = start;
        Vector3 end = getIntersectionEnd(ray, maxDistance);

        Vector4 startVal = getValueAndGradient(start);
        Vector3 scaleSampleGradient(startVal.x, startVal.y, startVal.z);
        Vector3 scaleSampleEnd = start + scaleSampleGradient.normalisedCopy();
        Real scaleSample = getValue(scaleSampleEnd);
        Real scale = (Real)1.0 / Math::Abs(scaleSample - startVal.w) * (Real)2.0;

        Real densityCur = getValue(cur);
        Vector3 dir = ray.getDirection().normalisedCopy();

        int count = 0;
        Vector3 prev, prevPrev;
        bool atEnd = false;
        Real totalLength = (start - end).length();
        while (Math::Abs(densityCur) > (Real)0.01 && !atEnd)
        {
            cur += dir * (Real)-1.0 * (densityCur / scale);

            // Increase the scaling a bit if we jump forth and back due to bad depth data.
            if ((cur - prevPrev).length() < (Real)0.0001)
            {
                scale *= (Real)2.0;
            }
            prevPrev = prev;
            prev = cur;

            densityCur = getValue(cur);

            // Check if we are out of range
            if ((start - cur).length() >= totalLength) {
                atEnd = true;
            }

            // We have a limit here...
            count++;
            if (count > maxIterations)
            {
                break;
            }
        }

        if (Math::Abs(densityCur) <= (Real)0.01)
        {
            result = cur;
            return true;
        }
        return false;
    }

}
}<commit_msg>Volume Rendering: signed / unsigned comparsion removed<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2013 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreVolumeSource.h"

#include "OgreRoot.h"
#include "OgreDeflate.h"
#include "OgreStreamSerialiser.h"
#include "OgreBitwise.h"

namespace Ogre {
namespace Volume {

    const uint32 Source::VOLUME_CHUNK_ID = StreamSerialiser::makeIdentifier("VOLU");
    const uint16 Source::VOLUME_CHUNK_VERSION = 1;
    const size_t Source::SERIALIZATION_CHUNK_SIZE = 1000;

    //-----------------------------------------------------------------------

    Vector3 Source::getIntersectionStart(const Ray &ray, Real maxDistance) const
    {
        return ray.getOrigin();
    }

    //-----------------------------------------------------------------------

    Vector3 Source::getIntersectionEnd(const Ray &ray, Real maxDistance) const
    {
        Vector3 dir = ray.getDirection().normalisedCopy();
        return ray.getOrigin() + dir * maxDistance;
    }

    //-----------------------------------------------------------------------

    Source::~Source(void)
    {
    }

    //-----------------------------------------------------------------------

    void Source::serialize(const Vector3 &from, const Vector3 &to, float voxelWidth, const String &file)
    {
        Real maxClampedAbsoluteDensity = (from - to).length() / (Real)16.0;
        serialize(from, to, voxelWidth, maxClampedAbsoluteDensity, file);
    }

    //-----------------------------------------------------------------------

    void Source::serialize(const Vector3 &from, const Vector3 &to, float voxelWidth, Real maxClampedAbsoluteDensity, const String &file)
    {

        Timer t;

        // Compress
        DataStreamPtr stream = Root::getSingleton().createFileStream(file);
        DataStreamPtr compressStream(OGRE_NEW DeflateStream(file, stream));
        StreamSerialiser ser(compressStream);
        ser.writeChunkBegin(VOLUME_CHUNK_ID, VOLUME_CHUNK_VERSION);

        // Write Metadata
        ser.write(&from);
        ser.write(&to);
        ser.write<float>(&voxelWidth);
        Vector3 diagonal = to - from;
        size_t gridWidth = (size_t)(diagonal.x / voxelWidth);
        size_t gridHeight = (size_t)(diagonal.y / voxelWidth);
        size_t gridDepth = (size_t)(diagonal.z / voxelWidth);
        ser.write<size_t>(&gridWidth);
        ser.write<size_t>(&gridHeight);
        ser.write<size_t>(&gridDepth);

        // Go over the volume and write the density data.
        Vector3 pos;
        Real realVal;
        size_t x;
        size_t y;
        uint16 buffer[SERIALIZATION_CHUNK_SIZE];
        size_t bufferI = 0;
        for (size_t z = 0; z < gridDepth; ++z)
        {
            for (x = 0; x < gridWidth; ++x)
            {
                for (y = 0; y < gridHeight; ++y)
                {
                    pos.x = x * voxelWidth + from.x;
                    pos.y = y * voxelWidth + from.y;
                    pos.z = z * voxelWidth + from.z;
                    realVal = Math::Clamp<Real>(getValue(pos), -maxClampedAbsoluteDensity, maxClampedAbsoluteDensity);
                    buffer[bufferI] = Bitwise::floatToHalf(realVal);
                    bufferI++;
                    if (bufferI == SERIALIZATION_CHUNK_SIZE)
                    {
                        ser.write<uint16>(buffer, SERIALIZATION_CHUNK_SIZE);
                        bufferI = 0;
                    }
                }
            }
        }
        if (bufferI > 0)
        {
            ser.write<uint16>(buffer, bufferI);
        }
        LogManager::getSingleton().stream() << "Time for serialization: " << t.getMilliseconds() << "ms";

        ser.writeChunkEnd(VOLUME_CHUNK_ID);

    }

    //-----------------------------------------------------------------------

    bool Source::getFirstRayIntersection(const Ray &ray, Vector3 &result, size_t maxIterations, Real maxDistance) const
    {
        Vector3 start = getIntersectionStart(ray, maxDistance);
        Vector3 cur = start;
        Vector3 end = getIntersectionEnd(ray, maxDistance);

        Vector4 startVal = getValueAndGradient(start);
        Vector3 scaleSampleGradient(startVal.x, startVal.y, startVal.z);
        Vector3 scaleSampleEnd = start + scaleSampleGradient.normalisedCopy();
        Real scaleSample = getValue(scaleSampleEnd);
        Real scale = (Real)1.0 / Math::Abs(scaleSample - startVal.w) * (Real)2.0;

        Real densityCur = getValue(cur);
        Vector3 dir = ray.getDirection().normalisedCopy();

        size_t count = 0;
        Vector3 prev, prevPrev;
        bool atEnd = false;
        Real totalLength = (start - end).length();
        while (Math::Abs(densityCur) > (Real)0.01 && !atEnd)
        {
            cur += dir * (Real)-1.0 * (densityCur / scale);

            // Increase the scaling a bit if we jump forth and back due to bad depth data.
            if ((cur - prevPrev).length() < (Real)0.0001)
            {
                scale *= (Real)2.0;
            }
            prevPrev = prev;
            prev = cur;

            densityCur = getValue(cur);

            // Check if we are out of range
            if ((start - cur).length() >= totalLength) {
                atEnd = true;
            }

            // We have a limit here...
            count++;
            if (count > maxIterations)
            {
                break;
            }
        }

        if (Math::Abs(densityCur) <= (Real)0.01)
        {
            result = cur;
            return true;
        }
        return false;
    }

}
}<|endoftext|>