<commit_before>/* OpenSceneGraph example, osgterrain.
*
*  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 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 <osg/ArgumentParser>
#include <osgDB/ReadFile>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <osgTerrain/Terrain>
#include <osgTerrain/TerrainTile>
#include <osgTerrain/GeometryTechnique>
#include <osgTerrain/Layer>

#include <iostream>

template<class T>
class FindTopMostNodeOfTypeVisitor : public osg::NodeVisitor
{
public:
    FindTopMostNodeOfTypeVisitor():
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
        _foundNode(0)
    {}

    void apply(osg::Node& node)
    {
        T* result = dynamic_cast<T*>(&node);
        if (result)
        {
            _foundNode = result;
        }
        else
        {
            traverse(node);
        }
    }

    T* _foundNode;
};

template<class T>
T* findTopMostNodeOfType(osg::Node* node)
{
    if (!node) return 0;

    FindTopMostNodeOfTypeVisitor<T> fnotv;
    node->accept(fnotv);

    return fnotv._foundNode;
}

int main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc, argv);

    // construct the viewer.
    osgViewer::Viewer viewer(arguments);

    // set up the camera manipulators.
    {
        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );

        std::string pathfile;
        char keyForAnimationPath = '5';
        while (arguments.read("-p",pathfile))
        {
            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
            if (apm || !apm->valid())
            {
                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
                keyswitchManipulator->selectMatrixManipulator(num);
                ++keyForAnimationPath;
            }
        }

        viewer.setCameraManipulator( keyswitchManipulator.get() );
    }

    // add the state manipulator
    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

    // add the stats handler
    viewer.addEventHandler(new osgViewer::StatsHandler);

    // add the record camera path handler
    viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

    // obtain the vertical scale
    float verticalScale = 1.0f;
    while(arguments.read("-v",verticalScale)) {}

    // obtain the sample ratio
    float sampleRatio = 1.0f;
    while(arguments.read("-r",sampleRatio)) {}

    osgTerrain::TerrainTile::BlendingPolicy blendingPolicy = osgTerrain::TerrainTile::INHERIT;
    std::string strBlendingPolicy;
    while(arguments.read("--blending-policy", strBlendingPolicy))
    {
        if (strBlendingPolicy == "INHERIT") blendingPolicy = osgTerrain::TerrainTile::INHERIT;
        else if (strBlendingPolicy == "DO_NOT_SET_BLENDING") blendingPolicy = osgTerrain::TerrainTile::DO_NOT_SET_BLENDING;
        else if (strBlendingPolicy == "ENABLE_BLENDING") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING;
        else if (strBlendingPolicy == "ENABLE_BLENDING_WHEN_ALPHA_PRESENT") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT;
    }

    // load the nodes from the commandline arguments.
    osg::Node* rootnode = osgDB::readNodeFiles(arguments);

    if (!rootnode)
    {
        osg::notify(osg::NOTICE)<<"Warning: no valid data loaded, please specify a database on the command line."<<std::endl;
        return 1;
    }

    osgTerrain::Terrain* terrain = findTopMostNodeOfType<osgTerrain::Terrain>(rootnode);
    if (!terrain)
    {
        terrain = new osgTerrain::Terrain;
        terrain->addChild(rootnode);

        rootnode = terrain;
    }

    terrain->setSampleRatio(sampleRatio);
    terrain->setVerticalScale(verticalScale);
    terrain->setBlendingPolicy(blendingPolicy);

    // add a viewport to the viewer and attach the scene graph.
    viewer.setSceneData( rootnode );

    // run the viewers main loop
    return viewer.run();

}
<commit_msg>Added TerainHandler event handler to provide 'v'/'V' and 'r'/'R' key controls for change vertical scale and sample ratio respectively.<commit_after>/* OpenSceneGraph example, osgterrain.
*
*  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 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 <osg/ArgumentParser>
#include <osgDB/ReadFile>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <osgTerrain/Terrain>
#include <osgTerrain/TerrainTile>
#include <osgTerrain/GeometryTechnique>
#include <osgTerrain/Layer>

#include <iostream>

template<class T>
class FindTopMostNodeOfTypeVisitor : public osg::NodeVisitor
{
public:
    FindTopMostNodeOfTypeVisitor():
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
        _foundNode(0)
    {}

    void apply(osg::Node& node)
    {
        T* result = dynamic_cast<T*>(&node);
        if (result)
        {
            _foundNode = result;
        }
        else
        {
            traverse(node);
        }
    }

    T* _foundNode;
};

template<class T>
T* findTopMostNodeOfType(osg::Node* node)
{
    if (!node) return 0;

    FindTopMostNodeOfTypeVisitor<T> fnotv;
    node->accept(fnotv);

    return fnotv._foundNode;
}

// class to handle events with a pick
class TerrainHandler : public osgGA::GUIEventHandler {
public:

    TerrainHandler(osgTerrain::Terrain* terrain):
        _terrain(terrain) {}

    bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
    {
        switch(ea.getEventType())
        {
            case(osgGA::GUIEventAdapter::KEYDOWN):
            {
                if (ea.getKey()=='r')
                {
                    _terrain->setSampleRatio(_terrain->getSampleRatio()*0.5);
                    osg::notify(osg::NOTICE)<<"Sample ratio "<<_terrain->getSampleRatio()<<std::endl;
                    return true;
                }
                else if (ea.getKey()=='R')
                {
                    _terrain->setSampleRatio(_terrain->getSampleRatio()/0.5);
                    osg::notify(osg::NOTICE)<<"Sample ratio "<<_terrain->getSampleRatio()<<std::endl;
                    return true;
                }
                else if (ea.getKey()=='v')
                {
                    _terrain->setVerticalScale(_terrain->getVerticalScale()*1.25);
                    osg::notify(osg::NOTICE)<<"Vertical scale "<<_terrain->getVerticalScale()<<std::endl;
                    return true;
                }
                else if (ea.getKey()=='V')
                {
                    _terrain->setVerticalScale(_terrain->getVerticalScale()/1.25);
                    osg::notify(osg::NOTICE)<<"Vertical scale "<<_terrain->getVerticalScale()<<std::endl;
                    return true;
                }

                return false;
            }
            default:
                return false;
        }
    }

protected:

    ~TerrainHandler() {}

    osg::ref_ptr<osgTerrain::Terrain>  _terrain;
};

int main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc, argv);

    // construct the viewer.
    osgViewer::Viewer viewer(arguments);

    // set up the camera manipulators.
    {
        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );

        std::string pathfile;
        char keyForAnimationPath = '5';
        while (arguments.read("-p",pathfile))
        {
            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
            if (apm || !apm->valid())
            {
                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
                keyswitchManipulator->selectMatrixManipulator(num);
                ++keyForAnimationPath;
            }
        }

        viewer.setCameraManipulator( keyswitchManipulator.get() );
    }

    // add the state manipulator
    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

    // add the stats handler
    viewer.addEventHandler(new osgViewer::StatsHandler);

    // add the record camera path handler
    viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

    // obtain the vertical scale
    float verticalScale = 1.0f;
    while(arguments.read("-v",verticalScale)) {}

    // obtain the sample ratio
    float sampleRatio = 1.0f;
    while(arguments.read("-r",sampleRatio)) {}

    osgTerrain::TerrainTile::BlendingPolicy blendingPolicy = osgTerrain::TerrainTile::INHERIT;
    std::string strBlendingPolicy;
    while(arguments.read("--blending-policy", strBlendingPolicy))
    {
        if (strBlendingPolicy == "INHERIT") blendingPolicy = osgTerrain::TerrainTile::INHERIT;
        else if (strBlendingPolicy == "DO_NOT_SET_BLENDING") blendingPolicy = osgTerrain::TerrainTile::DO_NOT_SET_BLENDING;
        else if (strBlendingPolicy == "ENABLE_BLENDING") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING;
        else if (strBlendingPolicy == "ENABLE_BLENDING_WHEN_ALPHA_PRESENT") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT;
    }

    // load the nodes from the commandline arguments.
    osg::Node* rootnode = osgDB::readNodeFiles(arguments);

    if (!rootnode)
    {
        osg::notify(osg::NOTICE)<<"Warning: no valid data loaded, please specify a database on the command line."<<std::endl;
        return 1;
    }

    osgTerrain::Terrain* terrain = findTopMostNodeOfType<osgTerrain::Terrain>(rootnode);
    if (!terrain)
    {
        terrain = new osgTerrain::Terrain;
        terrain->addChild(rootnode);

        rootnode = terrain;
    }

    terrain->setSampleRatio(sampleRatio);
    terrain->setVerticalScale(verticalScale);
    terrain->setBlendingPolicy(blendingPolicy);

    // register our custom handler for adjust Terrain settings
    viewer.addEventHandler(new TerrainHandler(terrain));

    // add a viewport to the viewer and attach the scene graph.
    viewer.setSceneData( rootnode );

    // run the viewers main loop
    return viewer.run();

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore>
#include <qambientlightsensor.h>

QTM_USE_NAMESPACE

class AmbientLightFilter : public QAmbientLightFilter
{
public:
    qtimestamp stamp;
    bool filter(QAmbientLightReading *reading)
    {
        int diff = ( reading->timestamp() - stamp );
        stamp = reading->timestamp();
        QString output;
        switch (reading->lightLevel()) {
            case QAmbientLightReading::Dark:      output = "Dark    ";  break;
            case QAmbientLightReading::Twilight:  output = "Twilight";  break;
            case QAmbientLightReading::Light:     output = "Light   ";  break;
            case QAmbientLightReading::Bright:    output = "Bright  ";  break;
            case QAmbientLightReading::Sunny:     output = "Sunny   ";  break;
            case QAmbientLightReading::Undefined: output = "Undefined"; break;
            default: output = "Invalid enum value";
        }
        QTextStream out(stdout);
        out << "Ambient light level: " << output
            << QString(" (%1 ms since last, %2 Hz)").arg(diff / 1000, 5).arg( 1000000.0 / diff, 3, 'f', 1) << endl;
        return false; // don't store the reading in the sensor
    }
};

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    QStringList args = app.arguments();
    int rate_place = args.indexOf("-r");
    int rate_val = 0;
    if (rate_place != -1)
        rate_val = args.at(rate_place + 1).toInt();
    QAmbientLightSensor sensor;
    if (rate_val > 0) {
        sensor.setDataRate(rate_val);
    }
    AmbientLightFilter filter;
    sensor.addFilter(&filter);
    sensor.start();
    if (!sensor.isActive()) {
        qWarning("Ambientlightsensor didn't start!");
        return 1;
    }

    return app.exec();
}
<commit_msg>connectToBackend()<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore>
#include <qambientlightsensor.h>

QTM_USE_NAMESPACE

class AmbientLightFilter : public QAmbientLightFilter
{
public:
    qtimestamp stamp;
    bool filter(QAmbientLightReading *reading)
    {
        int diff = ( reading->timestamp() - stamp );
        stamp = reading->timestamp();
        QString output;
        switch (reading->lightLevel()) {
            case QAmbientLightReading::Dark:      output = "Dark    ";  break;
            case QAmbientLightReading::Twilight:  output = "Twilight";  break;
            case QAmbientLightReading::Light:     output = "Light   ";  break;
            case QAmbientLightReading::Bright:    output = "Bright  ";  break;
            case QAmbientLightReading::Sunny:     output = "Sunny   ";  break;
            case QAmbientLightReading::Undefined: output = "Undefined"; break;
            default: output = "Invalid enum value";
        }
        QTextStream out(stdout);
        out << "Ambient light level: " << output
            << QString(" (%1 ms since last, %2 Hz)").arg(diff / 1000, 5).arg( 1000000.0 / diff, 3, 'f', 1) << endl;
        return false; // don't store the reading in the sensor
    }
};

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    QStringList args = app.arguments();
    int rate_place = args.indexOf("-r");
    int rate_val = 0;
    if (rate_place != -1)
        rate_val = args.at(rate_place + 1).toInt();
    QAmbientLightSensor sensor;
    sensor.connectToBackend();

    if (rate_val > 0) {
        sensor.setDataRate(rate_val);
    }
    AmbientLightFilter filter;
    sensor.addFilter(&filter);
    sensor.start();
    if (!sensor.isActive()) {
        qWarning("Ambientlightsensor didn't start!");
        return 1;
    }

    return app.exec();
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore>
#include <qtapsensor.h>

QTM_USE_NAMESPACE

class TapSensorFilter : public QTapFilter
{
public:
    TapSensorFilter(QTapSensor* sensor): mySensor(sensor){}

    bool filter(QTapReading *reading)
    {
        int diff = ( reading->timestamp() - stamp );
        stamp = reading->timestamp();
        QString output;
        switch (reading->tapDirection()) {
            case QTapReading::X:         output = "X";         break;
            case QTapReading::Y:         output = "Y";         break;
            case QTapReading::Z:         output = "Z";         break;
            case QTapReading::X_Pos:     output = "X pos";     break;
            case QTapReading::Y_Pos:     output = "Y pos";     break;
            case QTapReading::Z_Pos:     output = "Z pos";     break;
            case QTapReading::X_Neg:     output = "X neg";     break;
            case QTapReading::Y_Neg:     output = "Y neg";     break;
            case QTapReading::Z_Neg:     output = "Z neg";     break;
            case QTapReading::Undefined: output = "Undefined"; break;
            default: output = "Invalid enum value";
        }

        QTextStream out(stdout);
        out << "Tap: ";
        if(reading->isDoubleTap()){
            out << "Double ";
            counter++;
            if (counter>2){
                mySensor->stop();
                mySensor->setProperty("returnDoubleTapEvents", false);
                mySensor->start();
            }
        }
        else
            out << "Single ";
        out << output<< QString(" (%1 ms since last, %2 Hz)").arg(diff / 1000, 5).arg( 1000000.0 / diff, 3, 'f', 1) << endl;
        return false; // don't store the reading in the sensor
    }
private:
    QTapSensor* mySensor;
    int counter;
    qtimestamp stamp;
};

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    QStringList args = app.arguments();
    int rate_place = args.indexOf("-r");
    int rate_val = 0;
    if (rate_place != -1)
        rate_val = args.at(rate_place + 1).toInt();

    QTapSensor doublesensor;
    TapSensorFilter filter(&doublesensor);

    doublesensor.setProperty("returnDoubleTapEvents", true);
    if (rate_val > 0) {
        doublesensor.setDataRate(rate_val);
    }
    doublesensor.addFilter(&filter);
    doublesensor.start();
    if (!doublesensor.isActive()) {
        qWarning("Tapsensor (double) didn't start!");
        return 1;
    }

    QTapSensor singlesensor;
    singlesensor.setProperty("returnDoubleTapEvents", false);

    bool isDouble = singlesensor.property("returnDoubleTapEvents").toBool();

    if (rate_val > 0) {
        singlesensor.setDataRate(rate_val);
    }
    singlesensor.addFilter(&filter);
    singlesensor.start();

    isDouble = singlesensor.property("returnDoubleTapEvents").toBool();

    if (!singlesensor.isActive()) {
        qWarning("Tapsensor (single) didn't start!");
        return 1;

    }

    return app.exec();
}
<commit_msg>connectToBackend()<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore>
#include <qtapsensor.h>

QTM_USE_NAMESPACE

class TapSensorFilter : public QTapFilter
{
public:
    TapSensorFilter(QTapSensor* sensor): mySensor(sensor){}

    bool filter(QTapReading *reading)
    {
        int diff = ( reading->timestamp() - stamp );
        stamp = reading->timestamp();
        QString output;
        switch (reading->tapDirection()) {
            case QTapReading::X:         output = "X";         break;
            case QTapReading::Y:         output = "Y";         break;
            case QTapReading::Z:         output = "Z";         break;
            case QTapReading::X_Pos:     output = "X pos";     break;
            case QTapReading::Y_Pos:     output = "Y pos";     break;
            case QTapReading::Z_Pos:     output = "Z pos";     break;
            case QTapReading::X_Neg:     output = "X neg";     break;
            case QTapReading::Y_Neg:     output = "Y neg";     break;
            case QTapReading::Z_Neg:     output = "Z neg";     break;
            case QTapReading::Undefined: output = "Undefined"; break;
            default: output = "Invalid enum value";
        }

        QTextStream out(stdout);
        out << "Tap: ";
        if(reading->isDoubleTap()){
            out << "Double ";
            counter++;
            if (counter>2){
                mySensor->stop();
                mySensor->setProperty("returnDoubleTapEvents", false);
                mySensor->start();
            }
        }
        else
            out << "Single ";
        out << output<< QString(" (%1 ms since last, %2 Hz)").arg(diff / 1000, 5).arg( 1000000.0 / diff, 3, 'f', 1) << endl;
        return false; // don't store the reading in the sensor
    }
private:
    QTapSensor* mySensor;
    int counter;
    qtimestamp stamp;
};

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    QStringList args = app.arguments();
    int rate_place = args.indexOf("-r");
    int rate_val = 0;
    if (rate_place != -1)
        rate_val = args.at(rate_place + 1).toInt();

    QTapSensor doublesensor;
    doublesensor.connectToBackend();
    TapSensorFilter filter(&doublesensor);

    doublesensor.setProperty("returnDoubleTapEvents", true);
    if (rate_val > 0) {
        doublesensor.setDataRate(rate_val);
    }
    doublesensor.addFilter(&filter);
    doublesensor.start();
    if (!doublesensor.isActive()) {
        qWarning("Tapsensor (double) didn't start!");
        return 1;
    }

    QTapSensor singlesensor;
    singlesensor.connectToBackend();
    singlesensor.setProperty("returnDoubleTapEvents", false);

    bool isDouble = singlesensor.property("returnDoubleTapEvents").toBool();

    if (rate_val > 0) {
        singlesensor.setDataRate(rate_val);
    }
    singlesensor.addFilter(&filter);
    singlesensor.start();

    isDouble = singlesensor.property("returnDoubleTapEvents").toBool();

    if (!singlesensor.isActive()) {
        qWarning("Tapsensor (single) didn't start!");
        return 1;

    }

    return app.exec();
}
<|endoftext|>


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

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

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

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

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

******************************************************************************/

/// \brief nom::SpriteSheet usage example (mostly a stub for now!)

#include <iostream>
#include <string>
#include <cstdlib>
#include <cassert>

#include <nomlib/graphics.hpp>
#include <nomlib/system.hpp>

const std::string APP_NAME = "nom::SpriteSheet";

const nom::Path p;
const std::string APP_RESOURCES_DIR = "Resources";
const std::string RESOURCE_SPRITE_SHEET = APP_RESOURCES_DIR + p.native() + "cursors.json";

const std::string OUTPUT_SHEET_FILENAME = "faces.json";

int main ( int argc, char* argv[] )
{
  // Fatal error; if we are not able to complete this step, it means that
  // we probably cannot rely on our resource paths!
  if ( nom::init ( argc, argv ) == false )
  {
    nom::DialogMessageBox ( APP_NAME, "Could not initialize nomlib." );
    exit ( NOM_EXIT_FAILURE );
  }
  atexit(nom::quit);

  // Existing sprite sheet
  nom::SpriteSheet cursors ( RESOURCE_SPRITE_SHEET );
  cursors.dump();

  if ( cursors.frames() < 1 )
  {
    nom::DialogMessageBox ( APP_NAME, "Error: Sprite sheet " + RESOURCE_SPRITE_SHEET + " appears to be empty!" );
    return NOM_EXIT_FAILURE;
  }

  // Creating a new sprite sheet!
  nom::SpriteSheet faces  (
                            "faces.png",  // meta-data info
                            2082, 262,    // overall sheet size in pixels
                            64, 64,       // sprite width & height in pixels
                            1, 1,         // spacing and padding in pixels
                            111           // total number of sprite frames,
                          );              // always counting from zero

  // Note that you should always be able to reconstruct the parameters specified
  // above with the resulting output file data, using the header info at the
  // bottom
  if ( faces.save ( OUTPUT_SHEET_FILENAME ) == false )
  {
    nom::DialogMessageBox ( APP_NAME, "Could not save sprite sheet file: " + OUTPUT_SHEET_FILENAME );
    return NOM_EXIT_FAILURE;
  }

  nom::DialogMessageBox ( APP_NAME, "Sprite sheet saved at: " + OUTPUT_SHEET_FILENAME );

  return NOM_EXIT_SUCCESS;
}
<commit_msg>examples/sprite_sheets: Use cursors for both input & output tests<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

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

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

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

******************************************************************************/

/// \brief nom::SpriteSheet usage example (mostly a stub for now!)

#include <iostream>
#include <string>
#include <cstdlib>
#include <cassert>

#include <nomlib/graphics.hpp>
#include <nomlib/system.hpp>

const std::string APP_NAME = "nom::SpriteSheet";

const nom::Path p;
const std::string APP_RESOURCES_DIR = "Resources";
const std::string RESOURCE_SPRITE_SHEET = APP_RESOURCES_DIR + p.native() + "cursors.json";

// const std::string OUTPUT_SHEET_FILENAME = "faces.json";
const std::string OUTPUT_SHEET_FILENAME = "cursors.json";

int main ( int argc, char* argv[] )
{
  // Fatal error; if we are not able to complete this step, it means that
  // we probably cannot rely on our resource paths!
  if ( nom::init ( argc, argv ) == false )
  {
    nom::DialogMessageBox ( APP_NAME, "Could not initialize nomlib." );
    exit ( NOM_EXIT_FAILURE );
  }
  atexit(nom::quit);

  // Existing sprite sheet
  // nom::SpriteSheet cursor ( RESOURCE_SPRITE_SHEET );
  // cursors.dump();

  // Creating a new sprite sheet; "faces.json"
  // nom::SpriteSheet faces  (
  //                           "faces.png",  // meta-data info
  //                           2082, 262,    // overall sheet size in pixels
  //                           64, 64,       // sprite width & height in pixels
  //                           1, 1,         // spacing and padding in pixels
  //                           111           // total number of sprite frames,
  //                         );              // always counting from zero

  // Note that you should always be able to reconstruct the parameters specified
  // above with the resulting output file data, using the header info at the
  // bottom
  // if ( faces.save ( OUTPUT_SHEET_FILENAME ) == false )
  // {
  //   nom::DialogMessageBox ( APP_NAME, "Could not save sprite sheet file: " + OUTPUT_SHEET_FILENAME );
  //   return NOM_EXIT_FAILURE;
  // }

  // Creating a new sprite sheet; "cursors.json"
  nom::SpriteSheet cursors  (
                              "cursors.png",  // meta-data info
                              130, 16,        // overall sheet size in pixels
                              26, 16,         // sprite width & height in pixels
                              0, 0,           // spacing and padding in pixels
                              5               // total number of sprite frames,
                            );                // always counting from zero

  if ( cursors.save ( OUTPUT_SHEET_FILENAME ) == false )
  {
    nom::DialogMessageBox ( APP_NAME, "Could not save sprite sheet file: " + OUTPUT_SHEET_FILENAME );
    return NOM_EXIT_FAILURE;
  }

  if ( cursors.frames() < 1 )
  {
    nom::DialogMessageBox ( APP_NAME, "Error: Sprite sheet " + OUTPUT_SHEET_FILENAME + " appears to be empty!" );
    return NOM_EXIT_FAILURE;
  }

  nom::DialogMessageBox ( APP_NAME, "Sprite sheet saved at: " + OUTPUT_SHEET_FILENAME );

  return NOM_EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * File:   cubicspline.cpp
 * Author: ruehle
 *
 * Created on August 22, 2008, 4:44 PM
 */

#include <cubicspline.h>
#include <gsl/gsl_linalg.h>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
//#include <householderqr.h>
#include <iostream>

using namespace std;

void CubicSpline::Interpolate(ub::vector<double> &x, ub::vector<double> &y)
{
    if(x.size() != y.size())
        throw std::invalid_argument("error in CubicSpline::Fit : size of vector x and y dos not match");

    const int N = x.size();

    // adjust the grid
    _r.resize(N);
    _f.resize(2*N);

    // create vector proxies to individually access f and f''
    ub::vector_range<ub::vector<double> > f (_f, ub::range (0, N));
    ub::vector_range<ub::vector<double> > f2 (_f, ub::range (N, 2*N));

    // copy the grid points into f
    _r = x;
    f = y;
    f2 = ub::zero_vector<double>(N);

    // not calculate the f''
    ub::matrix<double> A(N, N);
    A = ub::zero_matrix<double>(N,N);

    for(int i=0; i<N - 2; ++i) {
            f2(i+1) = -( A_prime_l(i)*f(i)
            + (B_prime_l(i) - A_prime_r(i)) * f(i+1)
            -B_prime_r(i) * f(i+2));

            A(i+1, i) = C_prime_l(i);
            A(i+1, i+1) = D_prime_l(i) - C_prime_r(i);
            A(i+1, i+2) = -D_prime_r(i);
    }

    switch(_boundaries) {
        case splineNormal:
            A(0, 0) = 1;
            A(N - 1, N-1) = 1;
            break;
        case splinePeriodic:
            A(0,0) = 1; A(0,N-1) = -1;
            A(N-1,0) = 1; A(N-1,N-1) = -1;
            break;
    }

    // now A is a tridiagonal system, solve it!
    double* pointer_m = &A(0,0);
    double* pointer_b = &f2(0);

    gsl_matrix_view m
        = gsl_matrix_view_array (pointer_m, N, N);

    gsl_vector_view gb
        = gsl_vector_view_array (pointer_b, N);

    gsl_vector *gx = gsl_vector_alloc (N);
    gsl_vector *tau = gsl_vector_alloc (N);
    gsl_vector *residual = gsl_vector_alloc (N);

    gsl_linalg_QR_decomp (&m.matrix, tau);

    gsl_linalg_QR_lssolve (&m.matrix, tau, &gb.vector, gx, residual);

    for (int i =0 ; i < N; i++) {
        f2(i) = gsl_vector_get(gx, i);
    }

    gsl_vector_free (gx);
    gsl_vector_free (tau);
    gsl_vector_free (residual);
}

void CubicSpline::Fit(ub::vector<double> &x, ub::vector<double> &y)
{
    if(x.size() != y.size())
        throw std::invalid_argument("error in CubicSpline::Fit : size of vector x and y dos not match");

    const int N = x.size();
    const int ngrid = _r.size();

    // construct the equation
    // A*u = b
    // where u = { {f[i]}, {f''[i]} }
    // and b[i] = y[i] for 0<=i<N
    // and b[i]=0 for i>=N (for smoothing condition)
    // A[i,j] contains the data fitting + the spline smoothing conditions

    ub::matrix<double> A(N + ngrid, 2*ngrid);
    A = ub::zero_matrix<double>(N + ngrid, 2*ngrid);
    ub::vector<double> b(N + ngrid);
    b  = ub::zero_vector<double>(N+ngrid);

    // construct the matrix to fit the points
    AddToFitMatrix(A, x, 0);

    ub::vector_range< ub::vector<double> > b1(b, ub::range(0,N));
    b1 = -y;

    // construct the smoothing condition
    // first derivatives have to be continuous:
    //AddBCToFitMatrix(A, N);

    // Solving linear equations system

    // libgsl has problems with solving overdetermined systems by means of
    // QR decomposition if the system doesn't have the full rank.
    // MATLAB can handle this problem easily.

    double* pointer_m = &A(0,0);
    double* pointer_b = & b(0);

    gsl_matrix_view m
        = gsl_matrix_view_array (pointer_m, N + ngrid, 2*ngrid);

    gsl_vector_view gb
        = gsl_vector_view_array (pointer_b, N+ngrid);

    gsl_vector *gx = gsl_vector_alloc (2*ngrid);
    gsl_vector *tau = gsl_vector_alloc (2*ngrid);
    gsl_vector *residual = gsl_vector_alloc (b.size());

    gsl_linalg_QR_decomp (&m.matrix, tau);

    gsl_linalg_QR_lssolve (&m.matrix, tau, &gb.vector, gx, residual);

    for (int i =0 ; i < 2*ngrid; i++) {
        _f(i) = gsl_vector_get(gx, i);
    }

    gsl_vector_free (gx);
    gsl_vector_free (tau);
    gsl_vector_free (residual);

    return;

  /*  using namespace boost::numeric::ublas;
    using namespace std;

    matrix<double> Q(3,3), R(3,3);
    HouseholderQR? (A,Q,R);
    matrix<double> Z = prod(Q,R) - A;
    float f = norm_1 (Z);
    cout << "Q=" << Q <<endl;
    cout << "R=" << R << endl;
    cout << "|Q*R - A|=" << f << endl;*/

}

<commit_msg>CubicSpline::Fit smoothing conditions are treated exactly<commit_after>/*
 * File:   cubicspline.cpp
 * Author: ruehle
 *
 * Created on August 22, 2008, 4:44 PM
 */

#include <cubicspline.h>
#include <gsl/gsl_linalg.h>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
//#include <householderqr.h>
#include <iostream>

using namespace std;

void CubicSpline::Interpolate(ub::vector<double> &x, ub::vector<double> &y)
{
    if(x.size() != y.size())
        throw std::invalid_argument("error in CubicSpline::Fit : size of vector x and y dos not match");

    const int N = x.size();

    // adjust the grid
    _r.resize(N);
    _f.resize(2*N);

    // create vector proxies to individually access f and f''
    ub::vector_range<ub::vector<double> > f (_f, ub::range (0, N));
    ub::vector_range<ub::vector<double> > f2 (_f, ub::range (N, 2*N));

    // copy the grid points into f
    _r = x;
    f = y;
    f2 = ub::zero_vector<double>(N);

    // not calculate the f''
    ub::matrix<double> A(N, N);
    A = ub::zero_matrix<double>(N,N);

    for(int i=0; i<N - 2; ++i) {
            f2(i+1) = -( A_prime_l(i)*f(i)
            + (B_prime_l(i) - A_prime_r(i)) * f(i+1)
            -B_prime_r(i) * f(i+2));

            A(i+1, i) = C_prime_l(i);
            A(i+1, i+1) = D_prime_l(i) - C_prime_r(i);
            A(i+1, i+2) = -D_prime_r(i);
    }

    switch(_boundaries) {
        case splineNormal:
            A(0, 0) = 1;
            A(N - 1, N-1) = 1;
            break;
        case splinePeriodic:
            A(0,0) = 1; A(0,N-1) = -1;
            A(N-1,0) = 1; A(N-1,N-1) = -1;
            break;
    }

    // now A is a tridiagonal system, solve it!
    double* pointer_m = &A(0,0);
    double* pointer_b = &f2(0);

    gsl_matrix_view m
        = gsl_matrix_view_array (pointer_m, N, N);

    gsl_vector_view gb
        = gsl_vector_view_array (pointer_b, N);

    gsl_vector *gx = gsl_vector_alloc (N);
    gsl_vector *tau = gsl_vector_alloc (N);
    gsl_vector *residual = gsl_vector_alloc (N);

    gsl_linalg_QR_decomp (&m.matrix, tau);

    gsl_linalg_QR_lssolve (&m.matrix, tau, &gb.vector, gx, residual);

    for (int i =0 ; i < N; i++) {
        f2(i) = gsl_vector_get(gx, i);
    }

    gsl_vector_free (gx);
    gsl_vector_free (tau);
    gsl_vector_free (residual);
}

void CubicSpline::Fit(ub::vector<double> &x, ub::vector<double> &y)
{
    if(x.size() != y.size())
        throw std::invalid_argument("error in CubicSpline::Fit : size of vector x and y dos not match");

    const int N = x.size();
    const int ngrid = _r.size();

    // construct the equation
    // A*u = b
    // where u = { {f[i]}, {f''[i]} }
    // and b[i] = y[i] for 0<=i<N
    // and b[i]=0 for i>=N (for smoothing condition)
    // A[i,j] contains the data fitting + the spline smoothing conditions

    ub::matrix<double> A(N, 2*ngrid);
    A = ub::zero_matrix<double>(N, 2*ngrid);
    ub::vector<double> b(N);
    b  = ub::zero_vector<double>(N);

    ub::matrix<double> B_constr(ngrid, 2*ngrid);  // Matrix with smoothing conditions
    B_constr = ub::zero_matrix<double>(ngrid, 2*ngrid);

    ub::matrix<double> Q(2*ngrid, 2*ngrid);       // Q matrix: QR decomposition of trans(B)
    Q = ub::zero_matrix<double>(2*ngrid, 2*ngrid);

    ub::matrix<double> A2(N, ngrid);             // Matrix A2 (see manual)
    A2 = ub::zero_matrix<double>(N, ngrid);

    // Construct smoothing matrix
    AddBCToFitMatrix(B_constr, 0);

    // Transpose B_constr:
    B_constr = trans(B_constr);

//================ START QR =============================//
    ub::matrix<double> Q_k(2*ngrid, 2*ngrid);
    Q_k = ub::zero_matrix<double>(2*ngrid, 2*ngrid);

    ub::identity_matrix<double> I (2*ngrid);

    ub::vector<double> v(2*ngrid);
    v = ub::zero_vector<double>(2*ngrid);

    double* pointer_m = & B_constr(0,0);

    gsl_matrix_view B_t
      = gsl_matrix_view_array (pointer_m, 2*ngrid, ngrid);

    gsl_vector *tau_qr = gsl_vector_alloc (ngrid);

    gsl_linalg_QR_decomp (&B_t.matrix, tau_qr);

    Q = I;

    for (int k = ngrid; k > 0 ; k--) {

        for (int icout = 0; icout < k - 1; icout++) {
             v(icout) = 0;
        }
        v(k - 1) = 1.0;

        for (int icout = k; icout < 2*ngrid; icout++) {
             v(icout) = gsl_matrix_get(&B_t.matrix, icout, k - 1 );
        }

        Q_k = I - gsl_vector_get(tau_qr, k - 1 ) * outer_prod ( v, v );
        Q = prec_prod(Q, Q_k);

    }

    Q = trans(Q);
    gsl_vector_free (tau_qr);

//=============== END QR ====================================//

    // construct the matrix to fit the points and the vector b
    AddToFitMatrix(A, x, 0);
    b = -y; // why is it -y?

    // Calculate A * Q and store the result in A
    A = prec_prod(A, Q);

    // A = [A1 A2], so A2 is just a block of A
    for (int iraw = 0; iraw < N; iraw++) {
        for (int icol = ngrid; icol < 2*ngrid; icol++) {
            A2(iraw, icol - ngrid) = A(iraw, icol);
        }
    }

//============== START SOLVE QR-DECOMPOSITION================//
    pointer_m = & A2(0,0);
    double* pointer_b = & b(0);

    gsl_matrix_view m
         = gsl_matrix_view_array (pointer_m, N, ngrid);

    gsl_vector_view gsl_b
         = gsl_vector_view_array (pointer_b, N);

    gsl_vector *z = gsl_vector_alloc (ngrid);
  gsl_vector *tau_solve = gsl_vector_alloc (ngrid);  // already done!
    gsl_vector *residual = gsl_vector_alloc (N);

    gsl_linalg_QR_decomp (&m.matrix, tau_solve);
    gsl_linalg_QR_lssolve (&m.matrix, tau_solve, &gsl_b.vector, z, residual);

    // Next two cycles assemble vector from y (which is zero-vector) and z
    // (which we just got by gsl_linalg_QR_lssolve)

    for (int i = 0; i < ngrid; i++ ) {
           _f[i] = 0.0;
    }

    for (int i = ngrid; i < 2 * ngrid; i++ ) {
           _f[i] = gsl_vector_get(z, i - ngrid);
    }

    // To get the final answer this vector should be multiplied by matrix Q
    _f = prec_prod( Q, _f );

    gsl_vector_free (z);
    gsl_vector_free (tau_solve);
    gsl_vector_free (residual);

//============== END SOLVE QR ===============================//

    for (int i=0; i < N; i++){
    cout << x(i) << '\t' << Calculate(x(i)) << endl;
    }

    // construct the smoothing condition
    // first derivatives have to be continuous:
    //AddBCToFitMatrix(A, N);

    // Solving linear equations system

    // libgsl has problems with solving overdetermined systems by means of
    // QR decomposition if the system doesn't have the full rank.
    // MATLAB can handle this problem easily.

/*    double* pointer_m = &A(0,0);
    double* pointer_b = & b(0);

    gsl_matrix_view m
        = gsl_matrix_view_array (pointer_m, N + ngrid, 2*ngrid);

    gsl_vector_view gb
        = gsl_vector_view_array (pointer_b, N+ngrid);

    gsl_vector *gx = gsl_vector_alloc (2*ngrid);
    gsl_vector *tau = gsl_vector_alloc (2*ngrid);
    gsl_vector *residual = gsl_vector_alloc (b.size());

    gsl_linalg_QR_decomp (&m.matrix, tau);

    gsl_linalg_QR_lssolve (&m.matrix, tau, &gb.vector, gx, residual);

    for (int i =0 ; i < 2*ngrid; i++) {
        _f(i) = gsl_vector_get(gx, i);
    }

    gsl_vector_free (gx);
    gsl_vector_free (tau);
    gsl_vector_free (residual);
  */
    return;

  /*  using namespace boost::numeric::ublas;
    using namespace std;

    matrix<double> Q(3,3), R(3,3);
    HouseholderQR? (A,Q,R);
    matrix<double> Z = prod(Q,R) - A;
    float f = norm_1 (Z);
    cout << "Q=" << Q <<endl;
    cout << "R=" << R << endl;
    cout << "|Q*R - A|=" << f << endl;*/

}

<|endoftext|>


<commit_before>///
/// @file  pi_lmo_parallel.cpp
/// @brief Parallel implementation of the Lagarias-Miller-Odlyzko
///        prime counting algorithm using OpenMP. This implementation
///        uses load balancing and counts the number of unsieved
///        elements using POPCNT without using any special counting
///        tree data structure.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <BitSieve.hpp>
#include <generate.hpp>
#include <generate_phi.hpp>
#include <LoadBalancer.hpp>
#include <min.hpp>
#include <imath.hpp>
#include <PhiTiny.hpp>
#include <PiTable.hpp>
#include <S1.hpp>
#include <Wheel.hpp>

#include <stdint.h>
#include <vector>

#ifdef _OPENMP
  #include <omp.h>
#endif

using namespace std;
using namespace primecount;

namespace {

/// Cross-off the multiples of prime in the sieve array
int64_t cross_off(BitSieve& sieve,
                  int64_t low,
                  int64_t high,
                  int64_t prime,
                  WheelItem& w)
{
  int64_t count = 0;
  int64_t m = w.next_multiple;
  int64_t wheel_index = w.wheel_index;

  for (; m < high; m += prime * Wheel::next_multiple_factor(&wheel_index))
  {
    // +1 if m is unset the first time
    count += sieve[m - low];
    sieve.unset(m - low);
  }

  w.set(m, wheel_index);
  return count;
}

/// Compute the S2 contribution of the interval
/// [low, low + segments * segment_size[
///
int64_t S2_thread(int64_t x,
                  int64_t y,
                  int64_t z,
                  int64_t c,
                  int64_t low,
                  int64_t segments,
                  int64_t segment_size,
                  PiTable& pi,
                  vector<int32_t>& primes,
                  vector<int32_t>& lpf,
                  vector<int32_t>& mu,
                  Runtime& runtime)
{
  int64_t limit = min(low + segments * segment_size, z + 1);
  int64_t size = pi[min(isqrt(x / low), y)] + 1;
  int64_t pi_sqrty = pi[isqrt(y)];
  int64_t pi_y = pi[y];
  int64_t S2_thread = 0;

  if (c >= size - 1)
    return 0;

  runtime.init_start();
  BitSieve sieve(segment_size);
  Wheel wheel(primes, size, low);
  auto phi = generate_phi(low - 1, size - 1, primes, pi);
  runtime.init_stop();

  // segmented sieve of Eratosthenes
  for (; low < limit; low += segment_size)
  {
    // current segment = [low, high[
    int64_t high = min(low + segment_size, limit);
    int64_t b = c + 1;

    // pre-sieve multiples of first c primes
    sieve.pre_sieve(c, low);

    int64_t count_low_high = sieve.count((high - 1) - low);

    // For c + 1 <= b <= pi_sqrty
    // Find all special leaves: n = primes[b] * m
    // which satisfy:  mu[m] != 0 && primes[b] < lpf[m], low <= (x / n) < high
    for (; b <= min(pi_sqrty, size - 1); b++)
    {
      int64_t prime = primes[b];
      int64_t min_m = max(x / (prime * high), y / prime);
      int64_t max_m = min(x / (prime * low), y);
      int64_t count = 0;
      int64_t i = 0;

      if (prime >= max_m)
        goto next_segment;

      for (int64_t m = max_m; m > min_m; m--)
      {
        if (mu[m] != 0 && prime < lpf[m])
        {
          int64_t xn = x / (prime * m);
          int64_t stop = xn - low;
          count += sieve.count(i, stop);
          i = stop + 1;
          int64_t phi_xn = phi[b] + count;
          S2_thread -= mu[m] * phi_xn;
        }
      }

      phi[b] += count_low_high;
      count_low_high -= cross_off(sieve, low, high, prime, wheel[b]);
    }

    // For pi_sqrty < b < pi_y
    // Find all special leaves: n = primes[b] * prime2
    // which satisfy: low <= (x / n) < high
    for (; b < min(pi_y, size); b++)
    {
      int64_t prime = primes[b];
      int64_t l = pi[min(x / (prime * low), y)];
      int64_t min_m = max(x / (prime * high), prime);
      int64_t count = 0;
      int64_t i = 0;

      if (prime >= primes[l])
        goto next_segment;

      for (; primes[l] > min_m; l--)
      {
        int64_t xn = x / (prime * primes[l]);
        int64_t stop = xn - low;
        count += sieve.count(i, stop);
        i = stop + 1;
        int64_t phi_xn = phi[b] + count;
        S2_thread += phi_xn;
      }

      phi[b] += count_low_high;
      count_low_high -= cross_off(sieve, low, high, prime, wheel[b]);
    }

    next_segment:;
  }

  return S2_thread;
}

/// Calculate the contribution of the special leaves.
/// This is a parallel implementation with advanced load balancing.
/// As most special leaves tend to be in the first segments we
/// start off with a small segment size and few segments
/// per thread, after each iteration we dynamically increase
/// the segment size and the number of segments.
///
int64_t S2(int64_t x,
           int64_t y,
           int64_t z,
           int64_t c,
           int64_t s2_approx,
           vector<int32_t>& primes,
           vector<int32_t>& lpf,
           vector<int32_t>& mu,
           int threads)
{
  print("");
  print("=== S2(x, y) ===");
  print("Computation of the special leaves");

  double time = get_wtime();
  threads = ideal_num_threads(threads, z);
  LoadBalancer loadBalancer(x, y, z, s2_approx);
  PiTable pi(y);

  #pragma omp parallel for num_threads(threads)
  for (int i = 0; i < threads; i++)
  {
    int64_t low = 0;
    int64_t segments = 0;
    int64_t segment_size = 0;
    int64_t S2 = 0;
    Runtime runtime;

    while (loadBalancer.get_work(&low, &segments, &segment_size, S2, runtime))
    {
      runtime.start();
      S2 = S2_thread(x, y, z, c, low, segments, segment_size, pi, primes, lpf, mu, runtime);
      runtime.stop();
    }
  }

  int64_t S2 = (int64_t) loadBalancer.get_result();
  print("S2", S2, time);

  return S2;
}

} // namespace

namespace primecount {

/// Calculate the number of primes below x using the
/// Lagarias-Miller-Odlyzko algorithm.
/// Run time: O(x^(2/3) / log x)
/// Memory usage: O(x^(1/3) * (log x)^2)
///
int64_t pi_lmo_parallel(int64_t x, int threads)
{
  if (x < 2)
    return 0;

  double alpha = get_alpha_lmo(x);
  int64_t x13 = iroot<3>(x);
  int64_t y = (int64_t) (x13 * alpha);
  int64_t z = x / y;
  int64_t c = PhiTiny::get_c(y);

  print("");
  print("=== pi_lmo_parallel(x) ===");
  print("pi(x) = S1 + S2 + pi(y) - 1 - P2");
  print(x, y, z, c, alpha, threads);

  int64_t p2 = P2(x, y, threads);
  auto primes = generate_primes<int32_t>(y);
  auto lpf = generate_lpf(y);
  auto mu = generate_moebius(y);

  int64_t pi_y = primes.size() - 1;
  int64_t s1 = S1(x, y, c, threads);
  int64_t s2_approx = S2_approx(x, pi_y, p2, s1);
  int64_t s2 = S2(x, y, z, c, s2_approx, primes, lpf, mu, threads);
  int64_t phi = s1 + s2;
  int64_t sum = phi + pi_y - 1 - p2;

  return sum;
}

} // namespace
<commit_msg>Use Sieve instead of BitSieve<commit_after>///
/// @file  pi_lmo_parallel.cpp
/// @brief Parallel implementation of the Lagarias-Miller-Odlyzko
///        prime counting algorithm using OpenMP. This implementation
///        uses load balancing and counts the number of unsieved
///        elements using POPCNT without using any special counting
///        tree data structure.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <Sieve.hpp>
#include <generate.hpp>
#include <generate_phi.hpp>
#include <LoadBalancer.hpp>
#include <min.hpp>
#include <imath.hpp>
#include <PhiTiny.hpp>
#include <PiTable.hpp>
#include <S1.hpp>

#include <stdint.h>
#include <vector>

#ifdef _OPENMP
  #include <omp.h>
#endif

using namespace std;
using namespace primecount;

namespace {

/// Compute the S2 contribution of the interval
/// [low, low + segments * segment_size[
///
int64_t S2_thread(int64_t x,
                  int64_t y,
                  int64_t z,
                  int64_t c,
                  int64_t low,
                  int64_t segments,
                  int64_t segment_size,
                  PiTable& pi,
                  vector<int32_t>& primes,
                  vector<int32_t>& lpf,
                  vector<int32_t>& mu,
                  Runtime& runtime)
{
  int64_t low1 = max(low, 1);
  int64_t limit = min(low + segments * segment_size, z + 1);
  int64_t size = pi[min(isqrt(x / low1), y)] + 1;
  int64_t pi_sqrty = pi[isqrt(y)];
  int64_t pi_y = pi[y];
  int64_t S2_thread = 0;

  if (c >= size - 1)
    return 0;

  runtime.init_start();
  Sieve sieve(low, segment_size, size - 1);
  auto phi = generate_phi(low, size - 1, primes, pi);
  runtime.init_stop();

  // segmented sieve of Eratosthenes
  for (; low < limit; low += segment_size)
  {
    // current segment = [low, high[
    int64_t high = min(low + segment_size, limit);
    int64_t low1 = max(low, 1);
    int64_t b = 4;

    // reset all bits to 1
    sieve.reset(low, high);

    for (; b <= c; b++)
      sieve.cross_off(b, primes[b]);

    int64_t count_low_high = sieve.count((high - 1) - low);

    // For c + 1 <= b <= pi_sqrty
    // Find all special leaves: n = primes[b] * m
    // which satisfy:  mu[m] != 0 && primes[b] < lpf[m], low <= (x / n) < high
    for (; b <= min(pi_sqrty, size - 1); b++)
    {
      int64_t prime = primes[b];
      int64_t min_m = max(x / (prime * high), y / prime);
      int64_t max_m = min(x / (prime * low1), y);
      int64_t count = 0;
      int64_t i = 0;

      if (prime >= max_m)
        goto next_segment;

      for (int64_t m = max_m; m > min_m; m--)
      {
        if (mu[m] != 0 && prime < lpf[m])
        {
          int64_t xn = x / (prime * m);
          int64_t stop = xn - low;
          count += sieve.count(i, stop);
          i = stop + 1;
          int64_t phi_xn = phi[b] + count;
          S2_thread -= mu[m] * phi_xn;
        }
      }

      phi[b] += count_low_high;
      count_low_high -= sieve.cross_off(b, prime);
    }

    // For pi_sqrty < b < pi_y
    // Find all special leaves: n = primes[b] * prime2
    // which satisfy: low <= (x / n) < high
    for (; b < min(pi_y, size); b++)
    {
      int64_t prime = primes[b];
      int64_t l = pi[min(x / (prime * low1), y)];
      int64_t min_m = max(x / (prime * high), prime);
      int64_t count = 0;
      int64_t i = 0;

      if (prime >= primes[l])
        goto next_segment;

      for (; primes[l] > min_m; l--)
      {
        int64_t xn = x / (prime * primes[l]);
        int64_t stop = xn - low;
        count += sieve.count(i, stop);
        i = stop + 1;
        int64_t phi_xn = phi[b] + count;
        S2_thread += phi_xn;
      }

      phi[b] += count_low_high;
      count_low_high -= sieve.cross_off(b, prime);
    }

    next_segment:;
  }

  return S2_thread;
}

/// Calculate the contribution of the special leaves.
/// This is a parallel implementation with advanced load balancing.
/// As most special leaves tend to be in the first segments we
/// start off with a small segment size and few segments
/// per thread, after each iteration we dynamically increase
/// the segment size and the number of segments.
///
int64_t S2(int64_t x,
           int64_t y,
           int64_t z,
           int64_t c,
           int64_t s2_approx,
           vector<int32_t>& primes,
           vector<int32_t>& lpf,
           vector<int32_t>& mu,
           int threads)
{
  print("");
  print("=== S2(x, y) ===");
  print("Computation of the special leaves");

  double time = get_wtime();
  threads = ideal_num_threads(threads, z);
  LoadBalancer loadBalancer(x, y, z, s2_approx);
  PiTable pi(y);

  #pragma omp parallel for num_threads(threads)
  for (int i = 0; i < threads; i++)
  {
    int64_t low = 0;
    int64_t segments = 0;
    int64_t segment_size = 0;
    int64_t S2 = 0;
    Runtime runtime;

    while (loadBalancer.get_work(&low, &segments, &segment_size, S2, runtime))
    {
      runtime.start();
      S2 = S2_thread(x, y, z, c, low, segments, segment_size, pi, primes, lpf, mu, runtime);
      runtime.stop();
    }
  }

  int64_t S2 = (int64_t) loadBalancer.get_result();
  print("S2", S2, time);

  return S2;
}

} // namespace

namespace primecount {

/// Calculate the number of primes below x using the
/// Lagarias-Miller-Odlyzko algorithm.
/// Run time: O(x^(2/3) / log x)
/// Memory usage: O(x^(1/3) * (log x)^2)
///
int64_t pi_lmo_parallel(int64_t x, int threads)
{
  if (x < 2)
    return 0;

  double alpha = get_alpha_lmo(x);
  int64_t x13 = iroot<3>(x);
  int64_t y = (int64_t) (x13 * alpha);
  int64_t z = x / y;
  int64_t c = PhiTiny::get_c(y);

  print("");
  print("=== pi_lmo_parallel(x) ===");
  print("pi(x) = S1 + S2 + pi(y) - 1 - P2");
  print(x, y, z, c, alpha, threads);

  int64_t p2 = P2(x, y, threads);
  auto primes = generate_primes<int32_t>(y);
  auto lpf = generate_lpf(y);
  auto mu = generate_moebius(y);

  int64_t pi_y = primes.size() - 1;
  int64_t s1 = S1(x, y, c, threads);
  int64_t s2_approx = S2_approx(x, pi_y, p2, s1);
  int64_t s2 = S2(x, y, z, c, s2_approx, primes, lpf, mu, threads);
  int64_t phi = s1 + s2;
  int64_t sum = phi + pi_y - 1 - p2;

  return sum;
}

} // namespace
<|endoftext|>


<commit_before>/****************************************************************************
**
** QtMEL is a Qt Media Encoding Library that allows to encode video and audio streams
** Copyright (C) 2013 Kirill Bukaev(aka KIBSOFT).
** Contact: Kirill Bukaev (support@kibsoft.ru)
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
****************************************************************************/

#include "screengrabber.h"
#include <QElapsedTimer>
#include <QImage>
#include <QEventLoop>
#include <QPixmap>
#include <QPainter>
#include <QTimer>
#include <QApplication>
#include <QDesktopWidget>
#include <QMutexLocker>

#include "../../helpers/mousehelper.h"

ScreenGrabber::ScreenGrabber(QObject *parent)
    : AbstractImageGrabber(parent)
    , m_isCaptureCursor(true)
{
}

ScreenGrabber::~ScreenGrabber()
{
}

void ScreenGrabber::setCaptureRect(const QRect &rect)
{
    QMutexLocker locker(&m_captureRectMutex);
    if (m_captureRect != rect) {
        m_captureRect = rect;

        Q_EMIT captureRectChanged(rect);
    }
}

QRect ScreenGrabber::captureRect() const
{
    QMutexLocker locker(&m_captureRectMutex);
    return m_captureRect;
}

void ScreenGrabber::setCaptureCursor(bool capture)
{
    QMutexLocker locker(&m_captureCursorMutex);
    if (m_isCaptureCursor != capture) {
        m_isCaptureCursor = capture;

        Q_EMIT isCaptureCursorChanged(capture);
    }
}

bool ScreenGrabber::isCaptureCursor() const
{
    QMutexLocker locker(&m_captureCursorMutex);
    return m_isCaptureCursor;
}

bool ScreenGrabber::start()
{
    //emit error signal if the capture rect is wrong
    if (captureRect().isNull() || !captureRect().isValid() || !qApp->desktop()->screen()->rect().contains(captureRect())
            || (captureRect().width() > qApp->desktop()->width() || captureRect().height() > qApp->desktop()->height())) {

        setError(AbstractGrabber::InvalidConfigurationError, tr("Capture rectangle is invalid"));
        return false;
    }

    return AbstractImageGrabber::start();
}

QImage ScreenGrabber::captureFrame()
{
    QImage frame;
    QMetaObject::invokeMethod(this, "currentFrame", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QImage, frame));

    //draw cursor if needed
    if (isCaptureCursor()) {
        int rectLeft = captureRect().left();
        int rectTop = captureRect().top();
        int rectWidth = captureRect().width();
        int rectHeight = captureRect().height();

        int xDiff = QCursor::pos().x() - rectLeft;
        int yDiff = QCursor::pos().y() - rectTop;

        if (xDiff > 0 && xDiff < rectWidth
                && yDiff > 0 && yDiff < rectHeight) {
            QImage cursor;
            QMetaObject::invokeMethod(this, "currentCursor", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QImage, cursor));
            if (!cursor.isNull()) {
                QPainter painter(&frame);
                painter.drawImage(QCursor::pos(), cursor);
            }
        }
    }

    return frame;
}

QImage ScreenGrabber::currentCursor()
{
    return MouseHelper::cursorPixmap().toImage();
}

QImage ScreenGrabber::currentFrame()
{
    QPixmap pixmap = QPixmap::grabWindow(qApp->desktop()->winId(), captureRect().left(), captureRect().top(),
                                         captureRect().width(), captureRect().height());

    return pixmap.toImage();
}
<commit_msg>Small fix<commit_after>/****************************************************************************
**
** QtMEL is a Qt Media Encoding Library that allows to encode video and audio streams
** Copyright (C) 2013 Kirill Bukaev(aka KIBSOFT).
** Contact: Kirill Bukaev (support@kibsoft.ru)
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
****************************************************************************/

#include "screengrabber.h"
#include <QElapsedTimer>
#include <QImage>
#include <QEventLoop>
#include <QPixmap>
#include <QPainter>
#include <QTimer>
#include <QApplication>
#include <QDesktopWidget>
#include <QMutexLocker>

#include "../../helpers/mousehelper.h"

ScreenGrabber::ScreenGrabber(QObject *parent)
    : AbstractImageGrabber(parent)
    , m_isCaptureCursor(true)
{
}

ScreenGrabber::~ScreenGrabber()
{
}

void ScreenGrabber::setCaptureRect(const QRect &rect)
{
    QMutexLocker locker(&m_captureRectMutex);
    if (m_captureRect != rect) {
        m_captureRect = rect;

        Q_EMIT captureRectChanged(rect);
    }
}

QRect ScreenGrabber::captureRect() const
{
    QMutexLocker locker(&m_captureRectMutex);
    return m_captureRect;
}

void ScreenGrabber::setCaptureCursor(bool capture)
{
    QMutexLocker locker(&m_captureCursorMutex);
    if (m_isCaptureCursor != capture) {
        m_isCaptureCursor = capture;

        Q_EMIT isCaptureCursorChanged(capture);
    }
}

bool ScreenGrabber::isCaptureCursor() const
{
    QMutexLocker locker(&m_captureCursorMutex);
    return m_isCaptureCursor;
}

bool ScreenGrabber::start()
{
    //emit error signal if the capture rect is wrong
    if (captureRect().isNull() || !captureRect().isValid() || !qApp->desktop()->screen()->rect().contains(captureRect())
            || (captureRect().width() > qApp->desktop()->width() || captureRect().height() > qApp->desktop()->height())) {

        setError(AbstractGrabber::InvalidConfigurationError, tr("Capture rectangle is invalid"));
        return false;
    }

    return AbstractImageGrabber::start();
}

QImage ScreenGrabber::captureFrame()
{
    QImage frame;
    QMetaObject::invokeMethod(this, "currentFrame", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QImage, frame));

    //draw cursor if needed
    if (isCaptureCursor()) {
        int rectLeft = captureRect().left();
        int rectTop = captureRect().top();
        int rectWidth = captureRect().width();
        int rectHeight = captureRect().height();

        int xDiff = QCursor::pos().x() - rectLeft;
        int yDiff = QCursor::pos().y() - rectTop;

        if (xDiff > 0 && xDiff < rectWidth
                && yDiff > 0 && yDiff < rectHeight) {
            QImage cursor;
            QMetaObject::invokeMethod(this, "currentCursor", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QImage, cursor));
            if (!cursor.isNull()) {
                QPainter painter(&frame);
                painter.drawImage(QPoint(xDiff, yDiff), cursor);
            }
        }
    }

    return frame;
}

QImage ScreenGrabber::currentCursor()
{
    return MouseHelper::cursorPixmap().toImage();
}

QImage ScreenGrabber::currentFrame()
{
    QPixmap pixmap = QPixmap::grabWindow(qApp->desktop()->winId(), captureRect().left(), captureRect().top(),
                                         captureRect().width(), captureRect().height());

    return pixmap.toImage();
}
<|endoftext|>


<commit_before>#include "tag.h"

Tag::Tag()
{
    type = TAG;
}

/**
 * @brief Tag::add_frame
 * @param frame
 * Adds the newly tagged frame as a new poi
 * unless it's at the edge of a current poi or that frame already is tagged
 */
bool Tag::add_frame(int frame) {
    add_interval(new AnalysisInterval(frame, frame));
}

void Tag::remove_frame(int frame) {
}
void Tag::add_interval(AnalysisInterval *an_interval){
    BasicAnalysis::add_interval(an_interval);
    merge_intervals();
}
/**
 * @brief Tag::merge_intervals
 * This function assumes m_intervals is sorted
 */
void Tag::merge_intervals(){
    std::set<AnalysisInterval*, interval_cmp> intervals = m_intervals;
    std::set<AnalysisInterval*, interval_cmp> res;
    auto it = intervals.begin();
    AnalysisInterval* current = *it;
    it++;
    while (it != intervals.end()){
       if (current->get_interval().second +1 >= (*it)->get_interval().first){ // you might want to change it to >=
           auto m_end = std::max((*it)->get_interval().second, current->get_interval().second);
           auto m_start = current->get_interval().first;
           AnalysisInterval* merged = new AnalysisInterval(m_end,m_start);
           AnalysisInterval* temp = *it;
           current = merged;
           delete temp;
       } else {
           res.insert(current);
           current = *(it);
       }
       it++;
    }
    res.insert(current);
    m_intervals = res;
}
<commit_msg>swallow 'internal' intervals (#45)<commit_after>#include "tag.h"

Tag::Tag()
{
    type = TAG;
}

/**
 * @brief Tag::add_frame
 * @param frame
 * Adds the newly tagged frame as a new poi
 * unless it's at the edge of a current poi or that frame already is tagged
 */
bool Tag::add_frame(int frame) {
    add_interval(new AnalysisInterval(frame, frame));
}

void Tag::remove_frame(int frame) {
}
void Tag::add_interval(AnalysisInterval *an_interval){
    BasicAnalysis::add_interval(an_interval);
    merge_intervals();
}
/**
 * @brief Tag::merge_intervals
 * This function assumes m_intervals is sorted
 */
void Tag::merge_intervals(){
    std::set<AnalysisInterval*, interval_cmp> intervals = m_intervals;
    std::set<AnalysisInterval*, interval_cmp> res;
    auto it = intervals.begin();
    AnalysisInterval* current = *it;
    it++;
    while (it != intervals.end()){
       if (current->get_interval().second +1 >= (*it)->get_interval().first){ // you might want to change it to >=
           auto m_end = std::max((*it)->get_interval().second, current->get_interval().second);
           auto m_start = std::min((*it)->get_interval().first, current->get_interval().first);
           AnalysisInterval* merged = new AnalysisInterval(m_end,m_start);
           AnalysisInterval* temp = *it;
           current = merged;
           delete temp;
       } else {
           res.insert(current);
           current = *(it);
       }
       it++;
    }
    res.insert(current);
    m_intervals = res;
}
<|endoftext|>