text:
/* vim:set ts=3 sw=3 sts=3 et: */
/**
 * Copyright © 2008-2013 Last.fm Limited
 *
 * This file is part of libmoost.
 *
 * 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.
 */

#ifndef MOOST_IO_TEMPDIR_HPP
#define MOOST_IO_TEMPDIR_HPP

#include <cstdlib>
#include <string>
#include <vector>
#include <stdexcept>
#include <boost/filesystem.hpp>

/**
 * @brief Creates a unique temporary directory; removed on scope exit.
 *
 * @note
 *
 * Using this is safer than generating a temp filename and then creating
 * the file as this can lead to a race condition situation. By creating
 * a temporary directory (which the OS guarantees will be unique and not
 * used again for as long as it exists) and writing files to this new
 * location you can be sure you won't collide with another process.
 *
 */

namespace moost { namespace io {

   class tempdir : public boost::filesystem::path
   {
      private:
         static std::string mktempdir(std::string const & pattern)
         {
            std::vector<char> buf(pattern.begin(), pattern.end());
            buf.push_back('\0'); // null terminate - thanks sven :)

            char const * path = mkdtemp(&buf[0]);

            if (!path)
            {
               throw std::runtime_error("unable to create tempdir");
            }

            return std::string(path);

         }
      public:
         tempdir(std::string pattern = "lastfm_moost_io_tempdir_XXXXXX")
            : boost::filesystem::path(mktempdir(pattern))
         {
         }

         ~tempdir()
         {
            // wave goodbye to your temporary directory
            boost::filesystem::remove_all(this->string());
         }
   };
}}

#endif

max_stars_repo_name: lastfm/libmoost

max_issues_repo_name: lastfm/libmoost

max_forks_repo_name: lastfm/libmoost


text:
#include "ObjectDetector.h"

#include <iostream>
#include <map>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

std::vector<std::string> get_file_list(const std::string& path)
{
    std::vector<std::string> m_file_list;
    if (fs::is_directory(path)) {
        fs::path apk_path(path);
        fs::directory_iterator end;

        for (fs::directory_iterator i(apk_path); i != end; ++i) {
            const fs::path cp = (*i);
            if (cp.extension() == ".jpg" || cp.extension() == ".jpeg") {
                m_file_list.push_back(cp.string());
            }
        }
    }
    return m_file_list;
}

void preprocessData() {
    std::ofstream fileLabels;
    fileLabels.open("../metrics/train_data.csv");
    fileLabels << "Image_name, Correct label\n";
    fs::create_directory("../images/train");
    fs::create_directory("../images/test");
    const auto &briskData = get_file_list("../images/brisk_dataset");
    const auto &noneData = get_file_list("../images/none_dataset");
    const auto &surfData = get_file_list("../images/surf_dataset");
    int num = 0;
    for (size_t i = 0; i < briskData.size() * 0.8; i++) {
        auto newfilename = "../images/train/" + std::to_string(num++) + ".jpg";
        fs::copy_file(briskData[i], newfilename, fs::copy_option::overwrite_if_exists);
        fileLabels << newfilename << "," << 1 << "\n";
    }
    for (size_t i = 0; i < surfData.size() * 0.8; i++) {
        auto newfilename = "../images/train/" + std::to_string(num++) + ".jpg";
        fs::copy_file(surfData[i], newfilename, fs::copy_option::overwrite_if_exists);
        fileLabels << newfilename << "," << 2 << "\n";
    }
    for (size_t i = 0; i < noneData.size() * 0.8; i++) {
        auto newfilename = "../images/train/" + std::to_string(num++) + ".jpg";
        fs::copy_file(noneData[i], newfilename, fs::copy_option::overwrite_if_exists);
        fileLabels << newfilename << "," << 0 << "\n";
    }
    num = 0;
    for (size_t i = briskData.size() * 0.8 - 1; i < briskData.size(); i++) {
        auto newfilename = "../images/test/" + std::to_string(num++) + ".jpg";
        fs::copy_file(briskData[i], newfilename, fs::copy_option::overwrite_if_exists);
        fileLabels << newfilename << "," << 1 << "\n";
    }
    for (size_t i = surfData.size() * 0.8 - 1; i < surfData.size(); i++) {
        auto newfilename = "../images/test/" + std::to_string(num++) + ".jpg";
        fs::copy_file(surfData[i], newfilename, fs::copy_option::overwrite_if_exists);
        fileLabels << newfilename << "," << 2 << "\n";
    }
    for (size_t i = noneData.size() * 0.8 - 1; i < noneData.size(); i++) {
        auto newfilename = "../images/test/" + std::to_string(num++) + ".jpg";
        fs::copy_file(noneData[i], newfilename, fs::copy_option::overwrite_if_exists);
        fileLabels << newfilename << "," << 0 << "\n";
    }
    fileLabels.close();
}

std::map<std::string, int> read()
{
    std::ifstream fin;
    std::string line;
    std::map<std::string, int> data;
    // Open an existing file
    fin.open("../metrics/train_data.csv");
    std::getline(fin, line, '\n');
    while(std::getline(fin, line, '\n')) {
        auto it = line.find(",");
        auto filename = line.substr(0, it);
        auto type = std::stoi(line.substr(it + 1));

        data[filename] = type;
    }
    fin.close();
    return data;
}

void trainClassificator() {
    std::cout << "Getting train and test files..." << std::endl;
    const auto &trainFileNames = get_file_list("../images/train");
    const auto &testFileNames = get_file_list("../images/test");
    ObjectDetector detectorBrisk(true), detectorSurf(false);
    std::vector<cv::Mat> trainImage;
    std::vector<cv::Mat> testImage;
    std::vector<int> labelsTrain, labelsTest;
    auto data = read();
    for (int i = 0; i < trainFileNames.size(); i++) {
        auto train = cv::imread(trainFileNames[i], cv::IMREAD_GRAYSCALE);

        if (train.empty()) {
            std::cerr << "Warning: Could not train image!" << std::endl;
            continue;
        }
        labelsTrain.push_back(data[trainFileNames[i]]);
        trainImage.push_back(train);
    }

    cv::Ptr<cv::ml::SVM> SVMbrisk, SVMsurf;
    cv::Ptr<cv::ml::DTrees> TREEBrisk, TREESurf;
    detectorBrisk.train(trainImage, labelsTrain, SVMbrisk);
    detectorSurf.train(trainImage, labelsTrain, SVMsurf);
    detectorBrisk.train(trainImage, labelsTrain, TREEBrisk);
    detectorSurf.train(trainImage, labelsTrain, TREESurf);

    for (int i = 0; i < testFileNames.size(); i++) {
        auto test = cv::imread(testFileNames[i], cv::IMREAD_GRAYSCALE);

        if (test.empty()) {
            std::cerr << "Warning: Could not train image!" << std::endl;
            continue;
        }
        labelsTest.push_back(data[testFileNames[i]]);
        testImage.push_back(test);
    }
    std::cout << "\nBrisk and SVM metrics:" << std::endl;
    detectorBrisk.predict(testImage, labelsTest, SVMbrisk);
    std::cout << "\nSURF and SVM metrics:" << std::endl;
    detectorSurf.predict(testImage, labelsTest, SVMsurf);
    std::cout << "\nBrisk and DTREE metrics:" << std::endl;
    detectorBrisk.predict(testImage, labelsTest, TREEBrisk);
    std::cout << "\nSURF and DTREE metrics:" << std::endl;
    detectorSurf.predict(testImage, labelsTest, TREESurf);

    detectorBrisk.predictVideo("../Video/result_money_svm_brisk.avi", cv::VideoCapture("../Video/money.mp4"), SVMbrisk);
    detectorSurf.predictVideo("../Video/result_money_svm_surf.avi", cv::VideoCapture("../Video/money.mp4"), SVMsurf);

    detectorBrisk.predictVideo("../Video/result_money_tree_brisk.avi", cv::VideoCapture("../Video/money.mp4"), TREEBrisk);
    detectorSurf.predictVideo("../Video/result_money_tree_surf.avi", cv::VideoCapture("../Video/money.mp4"), TREESurf);

    detectorBrisk.predictVideo("../Video/result_sneaker_svm_brisk.avi", cv::VideoCapture("../Video/Sneaker.mp4"), SVMbrisk);
    detectorSurf.predictVideo("../Video/result_sneaker_svm_surf.avi", cv::VideoCapture("../Video/Sneaker.mp4"), SVMsurf);

    detectorBrisk.predictVideo("../Video/result_sneaker_tree_brisk.avi", cv::VideoCapture("../Video/Sneaker.mp4"), TREEBrisk);
    detectorSurf.predictVideo("../Video/result_sneaker_tree_surf.avi", cv::VideoCapture("../Video/Sneaker.mp4"), TREESurf);
}

int main() {
    preprocessData();
    trainClassificator();
    return 0;
}

ext: cpp


text:
//  Copyright (c) 2013 Thomas Heller
//
//  Distributed under 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)

#ifndef BENCHMARKS_UTS_WS_STEALSTACK_HPP
#define BENCHMARKS_UTS_WS_STEALSTACK_HPP

#include <benchmarks/uts/params.hpp>
#include <hpx/include/async.hpp>
#include <hpx/include/components.hpp>
#include <hpx/lcos/local/condition_variable.hpp>

#include <boost/ref.hpp>

namespace components
{
    struct ws_stealstack
      : hpx::components::managed_component_base<ws_stealstack>
    {
        enum states
        {
            WORK    = 0,
            SEARCH  = 1,
            IDLE    = 2,
            OVH     = 3,
            NSTATES = 4
        };

        struct stats
        {
            stats()
              : n_nodes(0)
              , n_leaves(0)
              , n_release(0)
              , n_acquire(0)
              , n_steal(0)
              , n_fail(0)
              , max_stack_depth(0)
              , max_tree_depth(0)
            {
                time[WORK] = 0.0;
                time[SEARCH] = 0.0;
                time[IDLE] = 0.0;
                time[OVH] = 0.0;
            }

            template <typename Archive>
            void serialize(Archive & ar, unsigned)
            {
                ar & n_nodes;
                ar & n_leaves;
                ar & n_acquire;
                ar & n_release;
                ar & n_steal;
                ar & n_fail;

                ar & max_stack_depth;
                ar & max_tree_depth;

                ar & time;
            }

            std::size_t n_nodes;
            std::size_t n_leaves;
            std::size_t n_release;
            std::size_t n_acquire;
            std::size_t n_steal;
            std::size_t n_fail;

            std::size_t max_stack_depth;
            std::size_t max_tree_depth;

            double time[NSTATES];
        };

        ws_stealstack()
          : local_work(0)
          , work_shared(0)
          , walltime(0)
          , work_time(0)
          , search_time(0)
          , idle_time(0)
          , idle_sessions(0)
          , time_last(0)
          , curState(0)
          , start_time(0)
          , chunks_recvd(0)
          , chunks_sent(0)
          , ctrl_recvd(0)
          , ctrl_sent(0)
          , pollint_adaptive(false)
        {
        }

        typedef hpx::lcos::local::spinlock mutex_type;
        mutex_type local_queue_mtx;

        void init(params p, std::size_t r, std::size_t s)
        {
            rank = r;
            size = s;
            param = p;

            last_steal = rank;
            last_share = rank;

            if(p.polling_interval == 0)
            {
                pollint_adaptive = true;
                p.polling_interval = 1;
            }

            if(rank == 0)
            {
                node n;
                n.init_root(param);
                put_work(n);
            }
        }

        HPX_DEFINE_COMPONENT_ACTION(ws_stealstack, init);

        void resolve_names(std::vector<hpx::id_type> const & idss)
        {
            ids = idss;
        }

        HPX_DEFINE_COMPONENT_ACTION(ws_stealstack, resolve_names);

        void put_work(node const & n)
        {
            {
                mutex_type::scoped_lock lk(local_queue_mtx);
                /* If the stack is empty, push an empty stealstack_node. */
                if(local_queue.empty())
                {
                    stealstack_node node(param.chunk_size);
                    local_queue.push_front(node);
                }

                /* If the current stealstack_node is full, push a new one. */
                if(local_queue.front().work.size() == param.chunk_size)
                {
                    stealstack_node node(param.chunk_size);
                    local_queue.push_front(node);
                }
                else if (local_queue.front().work.size() > param.chunk_size)
                {
                    throw std::logic_error("ss_put_work(): Block has overflowed!");
                }

                stealstack_node & node = local_queue.front();

                node.work.push_back(n);
            }
            local_work++;
            std::size_t local_work_tmp = local_work;
            stat.max_stack_depth = (std::max)(local_work_tmp, stat.max_stack_depth);
        }

        void gen_children(node & parent)
        {
            std::size_t parent_height = parent.height;

            stat.max_tree_depth = (std::max)(stat.max_tree_depth, parent_height);

            int num_children = parent.get_num_children(param);
            int child_type = parent.child_type(param);

            parent.num_children = num_children;

            if(num_children > 0)
            {

                for(int i = 0; i < num_children; ++i)
                {
                    node child;
                    child.type = child_type;
                    child.height = parent_height + 1;
                    for(int j = 0; j < param.compute_granularity; ++j)
                    {
                        rng_spawn(parent.state.state, child.state.state, i);
                    }

                    put_work(child);
                }
            }
            else
            {
                ++stat.n_leaves;
            }
        }

        std::pair<bool, std::vector<stealstack_node> > steal_work()
        {
            std::pair<bool, std::vector<stealstack_node> > res =
                std::make_pair(false, std::vector<stealstack_node>());

            if(local_work > param.chunk_size * param.chunk_size)
            {
                mutex_type::scoped_lock lk(local_queue_mtx);
                std::size_t steal_num = local_queue.size()/2;
                res.second.resize(steal_num);
                for(std::size_t i = 0; i < steal_num; ++i)
                {
                    std::swap(res.second[i], local_queue.back());
                    local_queue.pop_back();

                    if(local_work < res.second[i].work.size())
                    {
                        throw std::logic_error(
                            "ensure_local_work(): local_work count is less than 0!");
                    }
                    local_work -= res.second[i].work.size();
                }
            }

            if(local_work > 0 || work_shared > 0)
            {
                res.first = true;
            }

            return res;
        }

        HPX_DEFINE_COMPONENT_ACTION(ws_stealstack, steal_work);

        bool ensure_local_work()
        {
            while(local_work == 0)
            {
                bool terminate = true;
                for(std::size_t i = 0; i < size -1; ++i)
                {
                    last_steal = (last_steal + 1) % size;
                    if(last_steal == rank) last_steal = (last_steal + 1) % size;

                    ws_stealstack::steal_work_action act;
                    std::pair<bool, std::vector<stealstack_node> > node_pair(boost::move(act(ids[last_steal])));

                    bool break_ = false;
                    BOOST_FOREACH(stealstack_node & ss_node, node_pair.second)
                    {
                        if(ss_node.work.size() > 0)
                        {
                            mutex_type::scoped_lock lk(local_queue_mtx);
                            terminate = false;

                            local_queue.push_back(ss_node);
                            local_work += ss_node.work.size();
                            break_ = true;
                        }
                    }
                    if(break_ || local_work > 0) break;

                    if(node_pair.first)
                    {
                        terminate = false;
                    }
                }

                if(terminate) return false;
            }

            return true;
        }

        bool get_work(std::vector<node> & work)
        {
            if(!ensure_local_work())
            {
                return false;
            }

            {
                mutex_type::scoped_lock lk(local_queue_mtx);
                std::swap(work, local_queue.front().work);
                local_queue.pop_front();
            }

            stat.n_nodes += work.size();
            if (local_work < work.size())
            {
                throw std::logic_error(
                    "ensure_local_work(): local_work count is less than 0!");
            }
            local_work -= work.size();

            if(work.size() == 0)
            {
                hpx::cout << "get_work(): called with work.size() = 0, "
                    << "local_work=" << local_work
                    << " or " << (local_work % param.chunk_size)
                    << " (mod " << param.chunk_size << ")\n" << hpx::flush;
                throw std::logic_error("get_work(): Underflow!");
            }

            return true;
        }

        void tree_search()
        {
            std::vector<node> parents;
            std::vector<hpx::future<void> > gen_children_futures;
            gen_children_futures.reserve(param.chunk_size);
            while(get_work(parents))
            {
                BOOST_FOREACH(node & parent, parents)
                {
                    gen_children_futures.push_back(
                        hpx::async(&ws_stealstack::gen_children, this,
							boost::ref(parent))
                    );
                    /*
                    gen_children(parent);
                    */
                }
                parents.clear();
                //hpx::wait(gen_children_futures);
                hpx::wait_all(gen_children_futures);
                gen_children_futures.clear();
            }
        }

        HPX_DEFINE_COMPONENT_ACTION(ws_stealstack, tree_search);

        stats get_stats()
        {
            return stat;
        }

        HPX_DEFINE_COMPONENT_ACTION(ws_stealstack, get_stats);

    private:
        std::vector<hpx::id_type> ids;
        boost::atomic<std::size_t> local_work;
        boost::atomic<std::size_t> work_shared;

        stats stat;

        double walltime;
        double work_time;
        double search_time;
        double idle_time;
        int idle_sessions;
        double time_last;
        int entries[NSTATES];
        int curState;

        double start_time;

        std::deque<stealstack_node> local_queue;
        std::size_t last_steal;
        std::size_t last_share;
        int chunks_recvd;
        int chunks_sent;
        int ctrl_recvd;
        int ctrl_sent;

        params param;
        bool pollint_adaptive;
        std::size_t rank;
        std::size_t size;
    };
}

#endif

ext: hpp

max_stars_repo_name: vamatya/benchmarks

max_issues_repo_name: vamatya/benchmarks

max_forks_repo_name: vamatya/benchmarks


text:
/// ---------------------------------------------------------------------------
/// @section LICENSE
///
/// Copyright (c) 2016 Georgia Tech Research Institute (GTRI)
///               All Rights Reserved
///
/// 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.
/// ---------------------------------------------------------------------------
/// @file filename.ext
/// @author Kevin DeMarco <kevin.demarco@gtri.gatech.edu>
/// @author Eric Squires <eric.squires@gtri.gatech.edu>
/// @version 1.0
/// ---------------------------------------------------------------------------
/// @brief A brief description.
///
/// @section DESCRIPTION
/// A long description.
/// ---------------------------------------------------------------------------
#include <scrimmage/plugin_manager/RegisterPlugin.h>
#include "SimpleQuadrotorControllerLQR.h"
#include <scrimmage/common/Utilities.h>
#include <scrimmage/parse/ParseUtils.h>
#include <boost/algorithm/clamp.hpp>

REGISTER_PLUGIN(scrimmage::Controller,
                SimpleQuadrotorControllerLQR,
                SimpleQuadrotorControllerLQR_plugin)

namespace sc = scrimmage;

void SimpleQuadrotorControllerLQR::init(std::map<std::string, std::string> &params) {
    double p_gain = sc::get("vel_p_gain", params, 1.0);
    double i_gain = sc::get("vel_i_gain", params, 1.0);
    double d_gain = sc::get("vel_d_gain", params, 1.0);
    double i_lim = sc::get("i_lim", params, 1.0);
    vel_pid_.set_parameters(p_gain, i_gain, d_gain);
    vel_pid_.set_integral_band(i_lim);

    max_vel_ = std::stod(params["max_vel"]);
}

bool SimpleQuadrotorControllerLQR::step(double t, double dt) {
    Eigen::Vector3d &des_pos = desired_state_->pos();
    double des_yaw = desired_state_->quat().yaw();

    Eigen::Vector3d &pos = state_->pos();
    Eigen::Vector3d &vel = state_->vel();
    double yaw = state_->quat().yaw();
    double xy_speed = vel.head<2>().norm();

    double yaw_dot =
        std::isnan(prev_yaw_) ? 0 : sc::Angles::angle_diff_rad(yaw, prev_yaw_) / dt;
    prev_yaw_ = yaw;

    // LQR Altitude Controller:
    double q1 = 1;
    double z_thrust = -1.0 / q1 * (pos(2) - des_pos(2)) - sqrt(2.0/q1) * vel(2);

    // LQR Heading Controller:
    double q2 = 1;
    double turn_force = -1.0 / q2 * sc::Angles::angle_pi(yaw - des_yaw) - sqrt(2.0/q2) * yaw_dot;

    // If not close to x/y position, use forward velocity:
    double dist = (des_pos - pos).head<2>().norm();
    vel_pid_.set_setpoint((dist < 10) ? 0 : dist / 10);

    double ctrl_vel = vel_pid_.step(dt, xy_speed);

    u_(0) = boost::algorithm::clamp(ctrl_vel, -max_vel_, max_vel_);
    u_(1) = 0;
    u_(2) = z_thrust;
    u_(3) = turn_force;

    return true;
}


text:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// Topper Trading Workbench
//
// Copyright (C) 2018 Hat Boy Software, Inc.
//
//  @author Matthew Alan Gray - <mgray@hatboysoftware.com>
//  @author Tony Richards - <trichards@indiezen.com>
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
#pragma once

#include "Entity.hpp"

#include <boost/property_tree/ptree_fwd.hpp>

//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
namespace Topper {
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~

class EntityFactory
{
    /// @name Types
    /// @{
public:
    typedef boost::shared_ptr<Helmet::Workbench::I_Entity>    pEntity_type;
    /// @}

    /// @name EntityFactory implementation
    /// @{
public:
    static pEntity_type createEntity(Helmet::Workbench::I_Model& _parent,
                                     const std::string& _name,
                                     const std::string& _entityInfoPath);
    /// @}

    /// @name 'Structors
    /// @{
public:
             EntityFactory();
    virtual ~EntityFactory();
    /// @}

    /// @name Member Variables
    /// @{
private:
    /// @}

};  // class EntityFactory

//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
}   // namespace Topper
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~

max_stars_repo_name: hatboysoftware/helmet

max_issues_repo_name: hatboysoftware/helmet

max_forks_repo_name: hatboysoftware/helmet


text:
/**
 * This code takes images, extracts keypoints and descriptors and clusters them into a vocabulary tree
 */

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>

#include <cstdio>

// Based on opencv/samples/cpp/bagofwords_classification.cpp
//
/*
using cv::Mat;
using cv::imshow;
using cv::waitKey;
using cv::Ptr;
*/
using namespace cv;
using std::string;

static bool WriteVocabulary(const string& filename, const Mat& vocabulary) {
  printf("Saving vocabulary...\n");
  FileStorage fs(filename, FileStorage::WRITE);
  if (fs.isOpened()) {
    fs << "Vocabulary" << vocabulary;
    return true;
  }
  return false;
}

static cv::Mat TrainVocabulary(const string &vocab_dir, int total_frames,
    float descriptor_proportion) {
//If you have fewer descriptors than kvocab_size, it will crash in kmeans. But, set this appropriately large
  const int kvocab_size = 300; //Should be large enough to create a rich vocab relative to your data
  cv::RNG rng(1234);
  Ptr<FeatureDetector> fdetector(new DynamicAdaptedFeatureDetector(
            AdjusterAdapter::create("SURF"), 100, 130, 5));
  Ptr<DescriptorExtractor> dextractor =
    // DescriptorExtractor::create("SIFT");
    (new SurfDescriptorExtractor(1000, 4, 2, false, true));

  TermCriteria terminate_criterion;
  terminate_criterion.epsilon = FLT_EPSILON;
  BOWKMeansTrainer bow_trainer(kvocab_size, terminate_criterion, 3, KMEANS_PP_CENTERS);

  for (int i = 0; i < total_frames; i++) {
    Mat vocab_frame;
    // TODO: Hardcoded prefix
    string frame_filename = vocab_dir + "vocab_%06d.png";
    vocab_frame = cv::imread(cv::format(frame_filename.c_str(), i));

    std::vector<cv::KeyPoint> image_keypoints;
    fdetector->detect(vocab_frame, image_keypoints);
    Mat image_descriptors;
    dextractor->compute(vocab_frame, image_keypoints, image_descriptors);
#if 1
    // TODO: pull out of the loop. Using it here is inefficient
    CV_Assert( dextractor->descriptorType() == CV_32FC1 );
    const int elem_size = CV_ELEM_SIZE(dextractor->descriptorType());
    const int desc_byte_size = dextractor->descriptorSize() * elem_size;
    const long int bytes_in_MB = 1048576;
    const long int memory_use = 100000;

    // Total number of descs to use for training.
    const long int max_desc_count = (memory_use * bytes_in_MB) / desc_byte_size;
    if (bow_trainer.descripotorsCount() > max_desc_count) {
      printf("Breaking due to full memory ( descriptors count =");
      printf("%d; descriptor size in bytes = %d; all used memory = %d\n",
          bow_trainer.descripotorsCount(), desc_byte_size,
          bow_trainer.descripotorsCount()*desc_byte_size);
      break;
    }

    if (!image_descriptors.empty()) {
      int desc_count = image_descriptors.rows;

      // Extracting desc_proportion descriptors from the image
      int descs_to_extract = static_cast<int>(descriptor_proportion
                               *static_cast<float>(desc_count));
      vector<char> used_mask( desc_count, false );
      fill( used_mask.begin(), used_mask.begin() + descs_to_extract, true );
      for( int i = 0; i < desc_count; i++ ) {
        int i1 = rng(desc_count), i2 = rng(desc_count);
        char tmp = used_mask[i1]; used_mask[i1] = used_mask[i2]; used_mask[i2] = tmp;
      }

      for(int i = 0; i < desc_count; i++) {
        if(used_mask[i] && bow_trainer.descripotorsCount() < max_desc_count)
          bow_trainer.add(image_descriptors.row(i));
      }
    }
#endif
    drawKeypoints(vocab_frame, image_keypoints, vocab_frame);
    cv::imshow("image read in", vocab_frame);
    int keyp = cv::waitKey(0);
    if (keyp == 27) {
      printf("Done building vocabulary tree\n");
      break;
    }
  }

  Mat vocabulary = bow_trainer.cluster();
  printf("Done building vocabulary tree\n");
  return vocabulary;
}

// directory creation utility function
static void make_img_directory(string *img_save_dir) {
  // FIXME: Assumes linux style directory structure
  // need to generalize to windows
  if ((*img_save_dir)[img_save_dir->length() - 1] != '/') {
    *img_save_dir += "/";
  }
  boost::filesystem::path dir(*img_save_dir);
  if (boost::filesystem::exists(dir)) {
    printf("Sequence directory already exists. Change dir name. Aborting. \n");
    exit(-1);
  }
  if (boost::filesystem::create_directory(dir)) {
    printf("Directory '%s' created\n", img_save_dir->c_str());
  }
}

void help()
{
	printf("\n"
" Keyboard controls: <ESC>       - quits image capturing mode and starts\n"
"                                  vocabulary tree building \n"
"                    <SPACE BAR> - saves the image during data collection\n"
"                                - moves to next image while showing\n"
"                                  keypoints and building a vocabulary tree \n"
" Sample usage:\n"
"\n"
" ./build_vocab_tree [<img_save_dir>] [<camera-deviceid>]\n"
"\n"
"arguments:\n"

"   <img_save_dir>    -- directory where vocabulary images are saved\n"
"   <camera-deviceid> -- should be non-negative integer. default camera is 0\n\n"
);
}

//
// Keyboard controls: <ESC>       - quits image capturing mode and starts
//                                  vocabulary tree building
//                    <SPACE BAR> - saves the image during data collection
//                                - moves to next image while showing
//                                   keypoints and building a vocabulary tree
// Sample usage:
//
// ./build_vocab_tree [<img_save_dir>] [<camera-deviceid>]
//
// arguments:
//   <img_save_dir>    -- directory where vocabulary images are saved
//   <camera-deviceid> -- should be non-negative integer. default camera is 0
//
//   TODO: <vocab_file>   -- yml file that stores vocabulary

int main(int argc, char *argv[]) {
  string img_save_dir;
  int cam_deviceid = 0;
  if (argc == 1) {
    help();
    return(0);
  } else if (argc == 2) {
    if (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")) {
      help();
      return(0);
    }
    img_save_dir = string(argv[1]);
    make_img_directory(&img_save_dir);
  } else if (argc == 3) {
    if (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")) {
      help();
      return(0);
    }
    img_save_dir = string(argv[1]);
    make_img_directory(&img_save_dir);
    cam_deviceid = boost::lexical_cast<int>(argv[2]);
  } else {
    //incorrect arguments
    help();
    return -1;
  }

  // read images from camera
  cv::VideoCapture cap(cam_deviceid);
  if (!cap.isOpened()) {
    printf("Opening the default camera did not succeed\n");
    return -1;
  }

  int framenum = 0;
  for (;;) {
    Mat frame;
    cap >> frame;
    imshow("input RGB image", frame);
    int keyp = waitKey(30);
    if(keyp == 'h')
      help();
    else if (keyp == 27) {
      printf("Done capturing.\n");
      break;
    } else if (keyp == 32) {
      printf("Saving frame\n");
      string frame_filename;
      frame_filename = img_save_dir + "vocab_%06d.png";
      cv::imwrite(cv::format(frame_filename.c_str(), framenum), frame);
      framenum++;
    }
  }

  destroyWindow("input RGB image");
  const float kdescriptor_proportion = 0.7;
  cv::Mat vocabulary = TrainVocabulary(img_save_dir, framenum - 1, kdescriptor_proportion);
  string filename = "vocab_big.yml";
  if (!WriteVocabulary(filename, vocabulary)) {
    printf("Error: file %s cannot be opened to write\n", filename.c_str());
    exit(-1);
  }

  return 0;
}

ext: cc


text:
/*
 * Copyright 2017 James De Broeck
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <SwarmSynchro.h>
#include "gtest/gtest.h"
#include <boost/thread/thread.hpp>
#include <boost/chrono.hpp>
#include <unordered_set>
#include <list>

#define BULK_COUNT 50

namespace {

    class AsyncIncrementable {
    public:
        virtual void increment_with_guard() = 0;
        virtual void increment_with_lock() = 0;
    };

    struct async_increment_callable_with_guard {
        AsyncIncrementable& mRef;
        explicit async_increment_callable_with_guard(AsyncIncrementable& pRef) : mRef(pRef) {}
        void operator()() { mRef.increment_with_guard(); }
    };

    struct async_increment_callable_with_lock {
        AsyncIncrementable& mRef;
        explicit async_increment_callable_with_lock(AsyncIncrementable& pRef) : mRef(pRef) {}
        void operator()() { mRef.increment_with_lock(); }
    };

    bool joinThread(boost::thread& call, int milliseconds) {
        bool joinable = call.joinable();
        bool joined = call.try_join_for(boost::chrono::milliseconds(milliseconds));
        return joined || !joinable;
    }

    class LockableTest : public ::testing::Test, public swarm::synchro::Lockable, public AsyncIncrementable {
    protected:
        int mNum = 0;
    public:
        void increment_with_lock() override {
            lockMutex();
            mNum++;
            unlockMutex();
        }
        void increment_with_guard() override {
            swarm::synchro::Lock lock(*this);
            mNum++;
        }
    };

    TEST_F(LockableTest, ExclusiveLockTest) {
        lockMutex();
        boost::thread async_call(async_increment_callable_with_lock(*this));
        EXPECT_EQ(0, mNum);
        unlockMutex();
        EXPECT_TRUE(joinThread(async_call, 500));
        EXPECT_EQ(1, mNum);
        increment_with_lock();
        EXPECT_EQ(2, mNum);
    }

    TEST_F(LockableTest, ExclusiveGuardTest) {
        lockMutex();
        boost::thread async_call(async_increment_callable_with_guard(*this));
        EXPECT_EQ(0, mNum);
        unlockMutex();
        EXPECT_TRUE(joinThread(async_call, 500));
        EXPECT_EQ(1, mNum);
        increment_with_guard();
        EXPECT_EQ(2, mNum);
    }

    TEST_F(LockableTest, BulkLockWriteTest) {
        std::list<boost::thread*> allThreads;
        for(int i = 0; i < BULK_COUNT; i++) {
            allThreads.push_back(new boost::thread(async_increment_callable_with_lock(*this)));
        }
        int threadsNotJoined = 0;
        for(boost::thread* call : allThreads) {
            if(!joinThread(*call, 150))
                threadsNotJoined++;
        }
        EXPECT_EQ(0, threadsNotJoined);
        EXPECT_EQ(BULK_COUNT, mNum);
        for(boost::thread* call : allThreads)
            delete call;
    }

    TEST_F(LockableTest, BulkGuardWriteTest) {
        std::list<boost::thread*> allThreads;
        for(int i = 0; i < BULK_COUNT; i++) {
            allThreads.push_back(new boost::thread(async_increment_callable_with_guard(*this)));
        }
        int threadsNotJoined = 0;
        for(boost::thread* call : allThreads) {
            if(!joinThread(*call, 150))
                threadsNotJoined++;
        }
        EXPECT_EQ(0, threadsNotJoined);
        EXPECT_EQ(BULK_COUNT, mNum);
        for(boost::thread* call : allThreads)
            delete call;
    }

    class AsyncReadable {
    public:
        virtual int get_value_with_lock() = 0;
        virtual int get_value_with_guard() = 0;
        virtual int get_value_unsafe() = 0;
    };

    struct async_read_callable_with_guard {
        AsyncReadable& mRef;
        int& mNum;
        explicit async_read_callable_with_guard(AsyncReadable& pRef, int& pNum) : mRef(pRef), mNum(pNum) {}
        void operator()() { mNum = mRef.get_value_with_guard(); }
    };

    struct async_read_callable_with_lock {
        AsyncReadable& mRef;
        int& mNum;
        explicit async_read_callable_with_lock(AsyncReadable& pRef, int& pNum) : mRef(pRef), mNum(pNum) {}
        void operator()() { mNum = mRef.get_value_with_lock(); }
    };

    class SharedLockableTest :
            public ::testing::Test,
            public swarm::synchro::SharedLockable,
            public AsyncIncrementable,
            public AsyncReadable {
    protected:
        int mNum = 0;
    public:
        void increment_with_lock() override {
            lockMutex();
            mNum++;
            unlockMutex();
        }
        void increment_with_guard() override {
            swarm::synchro::Lock lock(*this);
            mNum++;
        }
        int get_value_with_lock() override {
            lockMutexShared();
            int result = mNum;
            unlockMutexShared();
            return result;
        }
        int get_value_with_guard() override {
            swarm::synchro::SharedLock lock(*this);
            return mNum;
        }
        int get_value_unsafe() override {
            return mNum;
        }
    };

    TEST_F(SharedLockableTest, ExclusiveLockTest) {
        lockMutexShared();
        boost::thread async_call(async_increment_callable_with_lock(*this));
        EXPECT_EQ(0, get_value_unsafe());
        unlockMutexShared();
        EXPECT_TRUE(joinThread(async_call, 500));
        EXPECT_EQ(1, get_value_with_lock());
        increment_with_lock();
        EXPECT_EQ(2, get_value_with_lock());
    }

    TEST_F(SharedLockableTest, ExclusiveGuardTest) {
        lockMutexShared();
        boost::thread async_call(async_increment_callable_with_guard(*this));
        EXPECT_EQ(0, get_value_unsafe());
        unlockMutexShared();
        EXPECT_TRUE(joinThread(async_call, 500));
        EXPECT_EQ(1, get_value_with_guard());
        increment_with_lock();
        EXPECT_EQ(2, get_value_with_guard());
    }

    TEST_F(SharedLockableTest, BulkLockWriteTest) {
        std::list<boost::thread*> allThreads;
        for(int i = 0; i < BULK_COUNT; i++) {
            allThreads.push_back(new boost::thread(async_increment_callable_with_lock(*this)));
        }
        int threadsNotJoined = 0;
        for(boost::thread* call : allThreads) {
            if(!joinThread(*call, 150))
                threadsNotJoined++;
        }
        EXPECT_EQ(0, threadsNotJoined);
        EXPECT_EQ(BULK_COUNT, get_value_with_lock());
        for(boost::thread* call : allThreads)
            delete call;
    }

    TEST_F(SharedLockableTest, BulkGuardWriteTest) {
        std::list<boost::thread*> allThreads;
        for(int i = 0; i < BULK_COUNT; i++) {
            allThreads.push_back(new boost::thread(async_increment_callable_with_guard(*this)));
        }
        int threadsNotJoined = 0;
        for(boost::thread* call : allThreads) {
            if(!joinThread(*call, 150))
                threadsNotJoined++;
        }
        EXPECT_EQ(0, threadsNotJoined);
        EXPECT_EQ(BULK_COUNT, get_value_with_guard());
        for(boost::thread* call : allThreads)
            delete call;
    }

    TEST_F(SharedLockableTest, BulkLockReadTest) {
        std::list<boost::thread*> allThreads;
        int allNums[BULK_COUNT];
        increment_with_lock();
        int expectedVal = get_value_with_lock();
        lockMutexShared();
        for (int &num : allNums) {
            allThreads.push_back(new boost::thread(async_read_callable_with_lock(*this, num)));
        }
        int threadsNotJoined = 0;
        for(boost::thread* call : allThreads) {
            if(!joinThread(*call, 150))
                threadsNotJoined++;
        }
        EXPECT_EQ(0, threadsNotJoined);
        unlockMutexShared();
        int failedReads = 0;
        for (int &num : allNums) {
            if(num != expectedVal)
                failedReads++;
        }
        EXPECT_EQ(0, failedReads);
        for(boost::thread* call : allThreads)
            delete call;
    }

    TEST_F(SharedLockableTest, BulkGuardReadTest) {
        std::list<boost::thread*> allThreads;
        int allNums[BULK_COUNT];
        increment_with_guard();
        int expectedVal = get_value_with_guard();
        swarm::synchro::SharedLock lock(*this);
        for (int &num : allNums) {
            allThreads.push_back(new boost::thread(async_read_callable_with_guard(*this, num)));
        }
        int threadsNotJoined = 0;
        for(boost::thread* call : allThreads) {
            if(!joinThread(*call, 150))
                threadsNotJoined++;
        }
        EXPECT_EQ(0, threadsNotJoined);
        int failedReads = 0;
        for (int &num : allNums) {
            if(num != expectedVal)
                failedReads++;
        }
        EXPECT_EQ(0, failedReads);
        for(boost::thread* call : allThreads)
            delete call;
    }

    TEST_F(SharedLockableTest, UpgradeLockTest) {
        int expectedVal = mNum;
        int val = -1;
        auto lock = new swarm::synchro::UpgradeLock(*this);
        boost::thread async_call_1(async_read_callable_with_guard(*this, val));
        EXPECT_TRUE(joinThread(async_call_1, 500));
        EXPECT_EQ(expectedVal, val);
        lock->upgrade();
        val = -1;
        boost::thread async_call_2(async_read_callable_with_guard(*this, val));
        mNum = 42; expectedVal = mNum;
        EXPECT_FALSE(joinThread(async_call_2, 500));
        delete lock;
        EXPECT_TRUE(joinThread(async_call_2, 500));
        EXPECT_EQ(expectedVal, val);
    }
}

max_stars_repo_name: SwarmEngine/SwarmEngine-Synchro

max_issues_repo_name: SwarmEngine/SwarmEngine-Synchro

max_forks_repo_name: SwarmEngine/SwarmEngine-Synchro


text:
/***************************************************************************
 * Copyright 1998-2017 by authors (see AUTHORS.txt)                        *
 *                                                                         *
 *   This file is part of LuxRender.                                       *
 *                                                                         *
 * Licensed under the Apache License, Version 2.0 (the "License");         *
 * you may not use this file except in compliance with the License.        *
 * You may obtain a copy of the License at                                 *
 *                                                                         *
 *     http://www.apache.org/licenses/LICENSE-2.0                          *
 *                                                                         *
 * Unless required by applicable law or agreed to in writing, software     *
 * distributed under the License is distributed on an "AS IS" BASIS,       *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*
 * See the License for the specific language governing permissions and     *
 * limitations under the License.                                          *
 ***************************************************************************/

#include <iostream>
#include <limits>
#include <boost/format.hpp>

#include "luxcoreapp.h"
#include "imagewindow.h"

using namespace std;
using namespace luxrays;
using namespace luxcore;

//------------------------------------------------------------------------------
// ImageWindow
//------------------------------------------------------------------------------

ImageWindow::ImageWindow(LuxCoreApp *a, const string &title) :
	ObjectWindow(a, title), imgScale(100.f) {
	glGenTextures(1, &channelTexID);
}

ImageWindow::~ImageWindow() {
	glDeleteTextures(1, &channelTexID);
}

void ImageWindow::Copy1UINT(const unsigned int *filmPixels, float *pixels,
		const unsigned int filmWidth, const unsigned int filmHeight) const {
	for (unsigned int y = 0; y < filmHeight; ++y) {
		for (unsigned int x = 0; x < filmWidth; ++x) {
			const unsigned int index = x + y * filmWidth;
			const unsigned int src = filmPixels[index];
			float *dst = &pixels[index * 3];

			dst[0] = ((src & 0x0000ff)) / 255.f;
			dst[1] = ((src & 0x00ff00) >> 8) / 255.f;
			dst[2] = ((src & 0xff0000) >> 16) / 255.f;
		}
	}
}

void ImageWindow::Copy1(const float *filmPixels, float *pixels,
		const unsigned int filmWidth, const unsigned int filmHeight) const {
	for (unsigned int y = 0; y < filmHeight; ++y) {
		for (unsigned int x = 0; x < filmWidth; ++x) {
			const unsigned int index = x + y * filmWidth;
			const float *src = &filmPixels[index];
			float *dst = &pixels[index * 3];

			const float v = src[0];
			dst[0] = v;
			dst[1] = v;
			dst[2] = v;
		}
	}
}

void ImageWindow::Copy2(const float *filmPixels, float *pixels,
		const unsigned int filmWidth, const unsigned int filmHeight) const {
	for (unsigned int y = 0; y < filmHeight; ++y) {
		for (unsigned int x = 0; x < filmWidth; ++x) {
			const unsigned int index = x + y * filmWidth;
			const float *src = &filmPixels[index * 2];
			float *dst = &pixels[index * 3];

			dst[0] = src[0];
			dst[1] = src[1];
			dst[2] = 0.f;
		}
	}
}

void ImageWindow::Copy3(const float *filmPixels, float *pixels,
		const unsigned int filmWidth, const unsigned int filmHeight) const {
	copy(&filmPixels[0], &filmPixels[filmWidth * filmHeight * 3], pixels);
}

void ImageWindow::Normalize1(const float *filmPixels, float *pixels,
		const unsigned int filmWidth, const unsigned int filmHeight) const {
	for (unsigned int y = 0; y < filmHeight; ++y) {
		for (unsigned int x = 0; x < filmWidth; ++x) {
			const unsigned int index = x + y * filmWidth;
			const float *src = &filmPixels[index * 2];
			float *dst = &pixels[index * 3];

			if (src[1] > 0.f) {
				const float v = src[0] / src[1];
				dst[0] = v;
				dst[1] = v;
				dst[2] = v;
			} else {
				dst[0] = 0.f;
				dst[1] = 0.f;
				dst[2] = 0.f;
			}
		}
	}
}

void ImageWindow::Normalize3(const float *filmPixels, float *pixels,
		const unsigned int filmWidth, const unsigned int filmHeight) const {
	for (unsigned int y = 0; y < filmHeight; ++y) {
		for (unsigned int x = 0; x < filmWidth; ++x) {
			const unsigned int index = x + y * filmWidth;
			const float *src = &filmPixels[index * 4];
			float *dst = &pixels[index * 3];

			if (src[3] > 0.f) {
				const float k = 1.f / src[3];
				dst[0] = src[0] * k;
				dst[1] = src[1] * k;
				dst[2] = src[2] * k;
			} else {
				dst[0] = 0.f;
				dst[1] = 0.f;
				dst[2] = 0.f;
			}
		}
	}
}

void ImageWindow::AutoLinearToneMap(const float *src, float *dst,
		const unsigned int filmWidth, const unsigned int filmHeight) const {
	// In order to work with negative values (i.e. POSITION AOV, etc.)
	float minVal[3] = {
		numeric_limits<float>::min(),
		numeric_limits<float>::min(),
		numeric_limits<float>::min()
	};
	for (unsigned int yy = 0; yy < filmHeight; ++yy) {
		for (unsigned int xx = 0; xx < filmWidth; ++xx) {
			const unsigned int index = xx + yy * filmWidth;
			const float *p = &src[index * 3];

			minVal[0] = Min(minVal[0], p[0]);
			minVal[1] = Min(minVal[1], p[1]);
			minVal[2] = Min(minVal[2], p[2]);
		}
	}

	float Y = 0.f;
	for (unsigned int yy = 0; yy < filmHeight; ++yy) {
		for (unsigned int xx = 0; xx < filmWidth; ++xx) {
			const unsigned int index = (xx + yy * filmWidth) * 3;
			const float *s = &src[index];
			float *d = &dst[index];

			d[0] = s[0] - minVal[0];
			d[1] = s[1] - minVal[1];
			d[2] = s[2] - minVal[2];

			// Spectrum::Y()
			const float y = 0.212671f * d[0] + 0.715160f * d[1] + 0.072169f * d[2];
			if ((y <= 0.f) || isinf(y))
				continue;

			Y += y;
		}
	}

	const unsigned int pixelCount = filmWidth * filmHeight;
	Y /= pixelCount;
	if (Y <= 0.f)
		return;

	const float scale = (1.25f / Y * powf(118.f / 255.f, 2.2f));

	for (unsigned int i = 0; i < pixelCount * 3; ++i)
		dst[i] = scale * src[i];
}

void ImageWindow::UpdateStats(const float *pixels,
		const unsigned int filmWidth, const unsigned int filmHeight) {
	imgMin[0] = imgMin[1] = imgMin[2] = numeric_limits<float>::max();
	imgMax[0] = imgMax[1] = imgMax[2] = numeric_limits<float>::min();
	imgAvg[0] = imgAvg[1] = imgAvg[2] = 0.f;

	for (unsigned int y = 0; y < filmHeight; ++y) {
		for (unsigned int x = 0; x < filmWidth; ++x) {
			const unsigned int index = x + y * filmWidth;
			const float *src = &pixels[index * 3];

			for (unsigned int i = 0; i < 3; ++i) {
				imgMin[i] = Min(imgMin[i], src[i]);
				imgMax[i] = Max(imgMax[i], src[i]);
				imgAvg[i] += src[i];
			}
		}
	}

	const unsigned int pixelCount = filmWidth * filmHeight;
	imgAvg[0] /= pixelCount;
	imgAvg[1] /= pixelCount;
	imgAvg[2] /= pixelCount;
}

void ImageWindow::Open() {
	if (!opened) {
		RefreshTexture();

		ObjectWindow::Open();
	}
}

void ImageWindow::Draw() {
	if (!opened)
		return;

	int frameBufferWidth, frameBufferHeight;
	glfwGetFramebufferSize(app->window, &frameBufferWidth, &frameBufferHeight);

	ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(ImVec2(450.f, 300.f)));
	if (ImGui::Begin(windowTitle.c_str(), &opened)) {
		if (ImGui::Button("Refresh image"))
			RefreshTexture();

		ImGui::SameLine();
		ImGui::SliderFloat("Zoom", &imgScale, 10.f, 1000.f, "%.1f%%");

		LuxCoreApp::ColoredLabelText("Min. value:", "(%f, %f, %f)", imgMin[0], imgMin[1], imgMin[2]);
		LuxCoreApp::ColoredLabelText("Max. value:", "(%f, %f, %f)", imgMax[0], imgMax[1], imgMax[2]);
		LuxCoreApp::ColoredLabelText("Avg. value:", "(%f, %f, %f)", imgAvg[0], imgAvg[1], imgAvg[2]);

		ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 4.f);
		ImGui::BeginChild("Image", ImVec2(0.f, 0.f), true, ImGuiWindowFlags_HorizontalScrollbar);

		const unsigned int filmWidth = app->session->GetFilm().GetWidth();
		const unsigned int filmHeight = app->session->GetFilm().GetHeight();
		ImGui::Image((void *) (intptr_t) channelTexID,
				ImVec2(.01f * imgScale * filmWidth, .01f * imgScale * filmHeight),
				ImVec2(0.f, 1.f), ImVec2(1.f, 0.f));

		ImGui::EndChild();
		ImGui::PopStyleVar();
	}
	ImGui::End();
	ImGui::PopStyleVar();
}

max_stars_repo_name: LuxRender/LuxRays

max_issues_repo_name: LuxRender/LuxRays

max_forks_repo_name: LuxRender/LuxRays


text:
/*
 * imu_tk - Inertial Measurement Unit Toolkit
 *
 *  Copyright (c) 2014, Alberto Pretto <pretto@diag.uniroma1.it>
 *  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 HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include <QtOpenGL>
#include <QMutexLocker>

#include <GL/glut.h>

#include <typeinfo>
#include <math.h>
#include <boost/iterator/iterator_concepts.hpp>

#include "imu_tk/vis_extra/opengl_3d_scene.h"

#define OPENGL3DSCENE_DRAW_AXIS_TICKS(val) { \
      glVertex3d(val, -0.02f, 0.0f);\
      glVertex3d(val, 0.02f, 0.0f);\
      glVertex3d(val, 0.0f, -0.02f);\
      glVertex3d(val, 0.0f, 0.012);\
      glVertex3d(-0.02f, val, 0.0f);\
      glVertex3d(0.02f, val, 0.0f);\
      glVertex3d(0.0f, val, -0.02f);\
      glVertex3d(0.0f, val, 0.02f);\
      glVertex3d(-0.01f, 0.0f, val);\
      glVertex3d(0.02f, 0.0f, val);\
      glVertex3d(0.0f, -0.02f, val);\
      glVertex3d(0.0f, 0.02f, val); }

OpenGL3DScene::OpenGL3DScene ( QWidget* parent, QColor background_color,
                               bool global_frame, QColor global_frame_color )
  : QGLWidget ( parent ),
  mutex_ ( QMutex::Recursive ),
  bg_color_ ( background_color ),
  left_mouse_button_pressed_(false),
  right_mouse_button_pressed_(false),
  mouse_init_x_(0),
  mouse_init_y_(0)
{
  fp_view_ = false;
  auto_adjust_ = true;
  auto_adjust_offset_ = 20.0;

  view_angle_ = GLfloat ( M_PI/3.0 );
  form_factor_ = 1.0f;
  max_x_ = max_y_= -std::numeric_limits< float >::max();
  min_x_ = min_y_ =std::numeric_limits< float >::min();

  t_inc_ = 0.6f;
  r_inc_ = 5.0f;

  makeCurrent();
  axis_list_ = glGenLists ( 1 );
  enableGlobalAxes ( global_frame, global_frame_color );
  camera_.reset();

  setFocusPolicy ( Qt::StrongFocus );

  connect( this, SIGNAL( sceneUpdated() ), this, SLOT( updateAllStructure() ));
  //setFocusPolicy ( Qt::NoFocus );//WARNING debug!!
}

OpenGL3DScene::~OpenGL3DScene()
{
  unregisterAllStructures();
}

void OpenGL3DScene::enableGlobalAxes ( bool enable, QColor color )
{
  draw_axes_ = enable;

  if ( enable )
  {
    makeCurrent();
    glNewList ( axis_list_,GL_COMPILE );

    qglColor ( color );
    GLfloat axis_limit = 1.0f;

    glBegin ( GL_LINES );

    glVertex3d ( -axis_limit, 0.0f, 0.0f );
    glVertex3d ( axis_limit, 0.0f, 0.0f );

    glVertex3d ( 0.0f, -axis_limit, 0.0f );
    glVertex3d ( 0.0f, axis_limit, 0.0f );

    glVertex3d ( 0.0f, 0.0f, -axis_limit );
    glVertex3d ( 0.0f, 0.0f, axis_limit );

    for ( GLfloat inc = -1.0f; inc <= 1.0f; inc +=0.1f )
      OPENGL3DSCENE_DRAW_AXIS_TICKS ( inc );

    for ( GLfloat inc = -axis_limit; inc <= axis_limit; inc +=1.0f )
      OPENGL3DSCENE_DRAW_AXIS_TICKS ( inc );

    glEnd();

    glEndList();
  }
}

void OpenGL3DScene::resizeGL ( int width, int height )
{
  /* Specifies the affine transformation of x and y
   from normalized device coordinates to window coordinate */
  glViewport ( 0, 0, ( GLint ) width, ( GLint ) height );

  int side = qMin ( width, height );
  form_factor_ = GLfloat ( width ) /GLfloat ( height );

  GLfloat clipping_planes_hside = GLfloat ( tanf ( view_angle_/2.0f ) );

  glMatrixMode ( GL_PROJECTION );
  glLoadIdentity();

  glFrustum ( -clipping_planes_hside*form_factor_, clipping_planes_hside*form_factor_,
              -clipping_planes_hside, clipping_planes_hside, 0.5, 2001.0 );

  glMatrixMode ( GL_MODELVIEW );

}

void OpenGL3DScene::initializeGL()
{
  //glClearColor(0.0, 0.0, 0.0, 0.0);
  qglClearColor ( bg_color_ );
  //glShadeModel(GL_FLAT);
  glShadeModel ( GL_SMOOTH );
  glEnable ( GL_DEPTH_TEST );
  glEnable ( GL_CULL_FACE );
  glDisable ( GL_LIGHTING );
  glEnable ( GL_NORMALIZE );

  GLfloat mat_shininess[] = { 50.0 };
  GLfloat light_position[] = { 100.0, 100.0, 100.0, 0.0 };
  GLfloat model_ambient[] = { 0.5, 0.5, 0.5, 1.0 };

  glMaterialfv ( GL_FRONT, GL_SHININESS, mat_shininess );
  glLightfv ( GL_LIGHT0, GL_POSITION, light_position );
  glLightModelfv ( GL_LIGHT_MODEL_AMBIENT, model_ambient );

  glEnable ( GL_LIGHT0 );

}

void OpenGL3DScene::paintGL()
{
  glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  glLoadIdentity();
  camera_.render();
  // Call all object lists

  if ( draw_axes_ )
    glCallList ( axis_list_ );

  std::vector< GLuint > lists;

  std::map <std::string, PathItem>::iterator path_iter;
  for ( path_iter = path_items_.begin(); path_iter != path_items_.end(); path_iter++ )
  {
    lists.insert(lists.end(), path_iter->second.lists.begin(), path_iter->second.lists.end());
  }

  std::map <std::string, CloudItem>::iterator cloud_iter;
  for ( cloud_iter = cloud_items_.begin(); cloud_iter != cloud_items_.end(); cloud_iter++ )
  {
    lists.insert(lists.end(), cloud_iter->second.lists.begin(), cloud_iter->second.lists.end());
  }

  if( lists.size() )
  {
    // Execute the list of display lists
    glCallLists ( lists.size(), GL_UNSIGNED_INT, ( const GLvoid * ) lists.data() );
  }

  std::map <std::string, AxesItem>::iterator axes_iter;
  for ( axes_iter = axes_items_.begin(); axes_iter != axes_items_.end(); axes_iter++ )
  {
    if ( axes_iter->second.list != GL_INVALID_VALUE )
    {
      glCallList ( axes_iter->second.list );
    }
  }
}

void OpenGL3DScene::setZoom ( int z )
{

//   if( !fp_view )
//   {
//     zT = float(z);
//     updateGL();
//   }

}

void OpenGL3DScene::updateNow()
{
  sceneUpdated();
}

void OpenGL3DScene::updateStructure( std::string name, bool update_gl )
{
  makeCurrent();

  std::map <std::string, PathItem>::iterator path_iter;
  if( (path_iter = path_items_.find(name)) != path_items_.end() )
  {
    PathItem &p_item = path_iter->second;
    if( p_item.removed )
    {
      for( int i = 0; i < path_iter->second.lists.size(); i++)
        glDeleteLists ( path_iter->second.lists[i], 1 );
      path_items_.erase(path_iter);

    }
    else
    {
      // Create a display list
      GLuint new_list = glGenLists ( 1 );
      p_item.lists.push_back(new_list);
      glNewList ( new_list, GL_COMPILE );
      qglColor ( p_item.color );

      for( int i = 0; i < int(p_item.unprocessed_poses.size()) - 1; i++ )
      {
        Eigen::Vector3d &p0 = p_item.unprocessed_poses[i], &p1 = p_item.unprocessed_poses[i+1];

        // Update 2D boundaries (X,Y) of the current drawn scene
        if ( p0(0) > max_x_ ) max_x_ = p0(0);
        if ( p0(0) < min_x_ ) min_x_ = p0(0);
        if ( p0(1) > max_y_ ) max_y_ = p0(1);
        if ( p0(1) < min_y_ ) min_y_ = p0(1);

        if ( p1(0) > max_x_ ) max_x_ = p1(0);
        if ( p1(0) < min_x_ ) min_x_ = p1(0);
        if ( p1(1) > max_y_ ) max_y_ = p1(1);
        if ( p1(1) < min_y_ ) min_y_ = p1(1);

        glBegin ( GL_LINES );

        glVertex3d ( p0(0), p0(1), p0(2) );
        glVertex3d ( p1(0), p1(1), p1(2) );

        glEnd();
      }

      glEndList();

      Eigen::Vector3d last_pos = p_item.unprocessed_poses.back();
      p_item.unprocessed_poses.clear();
      p_item.unprocessed_poses.push_back(last_pos);
    }
  }

  std::map <std::string, LineItem>::iterator lines_iter;
  if( (lines_iter = line_items_.find(name)) != line_items_.end()  )
  {
    LineItem &l_item = lines_iter->second;

    if(l_item.removed)
    {
      if ( lines_iter->second.list != GL_INVALID_VALUE )
        glDeleteLists ( lines_iter->second.list, 1 );
      line_items_.erase(lines_iter);
    }
    else if( l_item.updated )
    {
      if ( l_item.list != GL_INVALID_VALUE )
        glDeleteLists ( l_item.list, 1 );

      Eigen::Vector3d &p0 = l_item.p0, &p1 = l_item.p1;

      l_item.list = glGenLists ( 1 );

      glNewList ( l_item.list, GL_COMPILE );
      qglColor ( l_item.color );

      glBegin ( GL_LINES );

      glVertex3d ( p0(0), p0(1), p0(2) );
      glVertex3d ( p1(0), p1(1), p1(2) );

      glEnd();

      glEndList();
    }
  }

  std::map <std::string, CloudItem>::iterator cloud_iter;
  if( (cloud_iter = cloud_items_.find(name)) != cloud_items_.end() )
  {
    CloudItem &c_item = cloud_iter->second;

    if( c_item.removed )
    {
      for( int i = 0; i < cloud_iter->second.lists.size(); i++)
        glDeleteLists ( cloud_iter->second.lists[i], 1 );
      cloud_items_.erase(cloud_iter);
    }
    else
    {
      // Create a display list
      GLuint new_list = glGenLists ( 1 );
      c_item.lists.push_back(new_list);
      glNewList ( new_list, GL_COMPILE );
      qglColor ( c_item.color );

      glBegin ( GL_POINTS );
      for( int i = 0; i < int(c_item.unprcessed_cloud.size()); i++ )
      {
        Eigen::Vector3d &p = c_item.unprcessed_cloud[i];
        glVertex3d ( GLfloat(p(0)), GLfloat(p(1)), GLfloat(p(2)) );
      }
      glEnd();
      glEndList();

      c_item.unprcessed_cloud.clear();
    }
  }

  std::map <std::string, AxesItem>::iterator axes_iter;
  if( (axes_iter = axes_items_.find(name)) != axes_items_.end()  )
  {
    AxesItem &a_item = axes_iter->second;

    if(a_item.removed)
    {
      if ( axes_iter->second.list != GL_INVALID_VALUE )
        glDeleteLists ( axes_iter->second.list, 1 );
      for ( int i = 0; i < 7; i++ )
        gluDeleteQuadric ( axes_iter->second.qobjs[i] );
      axes_items_.erase(axes_iter);
    }
    else if( a_item.updated )
    {
      if ( a_item.list != GL_INVALID_VALUE )
        glDeleteLists ( a_item.list, 1 );

      a_item.list = glGenLists ( 1 );

      glNewList ( a_item.list, GL_COMPILE );

      glEnable ( GL_LIGHTING );

      qglColor ( a_item.color );

      GLfloat mat_ambient[] = { a_item.color.redF(), a_item.color.greenF(), a_item.color.blueF(), 1.0f };
      GLfloat mat_diffuse[] = { a_item.color.redF() /2.0f, a_item.color.greenF() /2.0f,
                                a_item.color.blueF() /2.0f, 1.0f };
      glMaterialfv ( GL_FRONT, GL_AMBIENT, mat_ambient );
      glMaterialfv ( GL_FRONT, GL_DIFFUSE, mat_diffuse );

      glPushMatrix();

      glTranslatef ( a_item.t(0), a_item.t(1), a_item.t(2) );

      glRotatef ( 180.0*sqrt ( ( a_item.r(0)*a_item.r(0) ) + ( a_item.r(1)*a_item.r(1) ) + ( a_item.r(2)*a_item.r(2) ) ) /M_PI,
                  a_item.r(0), a_item.r(1), a_item.r(2) );

      // Center
      gluSphere ( a_item.qobjs[0], 0.02, 5, 5 );

      // Z-Axis
      gluCylinder ( a_item.qobjs[1], 0.02, 0.02, 0.5, 10, 5 );
      glPushMatrix();
      glTranslatef ( 0.0, 0.0, 0.45 );

      mat_ambient[0] = 1.0f - mat_ambient[0];
      mat_ambient[1] = 1.0f - mat_ambient[1];
      mat_ambient[2] = 1.0f - mat_ambient[2];
      mat_diffuse[0] = 1.0f - mat_diffuse[0];
      mat_diffuse[1] = 1.0f - mat_diffuse[1];
      mat_diffuse[2] = 1.0f - mat_diffuse[2];

      glMaterialfv ( GL_FRONT, GL_AMBIENT, mat_ambient );
      glMaterialfv ( GL_FRONT, GL_DIFFUSE, mat_diffuse );

      gluCylinder ( a_item.qobjs[2], 0.04, 0.0, 0.1, 15, 5 );

      mat_ambient[0] = 1.0f - mat_ambient[0];
      mat_ambient[1] = 1.0f - mat_ambient[1];
      mat_ambient[2] = 1.0f - mat_ambient[2];
      mat_diffuse[0] = 1.0f - mat_diffuse[0];
      mat_diffuse[1] = 1.0f - mat_diffuse[1];
      mat_diffuse[2] = 1.0f - mat_diffuse[2];
      glMaterialfv ( GL_FRONT, GL_AMBIENT, mat_ambient );
      glMaterialfv ( GL_FRONT, GL_DIFFUSE, mat_diffuse );

      glPopMatrix();

      // Y-Axis
      glPushMatrix();
      glRotatef ( -90.0,1.0,0, 0 );
      gluCylinder ( a_item.qobjs[3], 0.02, 0.02, 0.5, 10, 5 );
      glPushMatrix();
      glTranslatef ( 0.0, 0.0, 0.45 );
      gluCylinder ( a_item.qobjs[4], 0.04, 0.0, 0.1, 15, 5 );
      glPopMatrix();
      glPopMatrix();

      // X-Axis
      glPushMatrix();
      glRotatef ( 90.0,0.0,1.0, 0 );
      gluCylinder ( a_item.qobjs[5], 0.02, 0.02, 0.5, 10, 5 );
      glPushMatrix();
      glTranslatef ( 0.0, 0.0, 0.45 );
      gluCylinder ( a_item.qobjs[6], 0.04, 0.0, 0.1, 15, 5 );
      glPopMatrix();
      glPopMatrix();

      glPopMatrix();

      glDisable ( GL_LIGHTING );
      glEndList();
    }
  }

  if ( auto_adjust_ )
    autoAdjustGView();

  if(update_gl)
    updateGL();
}

void OpenGL3DScene::moveCamera ( GLfloat tx, GLfloat ty, GLfloat tz, GLfloat r1x, GLfloat r2y, GLfloat r3z )
{
  camera_.reset();

  camera_.reset();
  camera_.moveAbs ( tx, ty, tz );
  camera_.rotateX ( r1x );
  camera_.rotateY ( r2y );
  camera_.rotateZ ( r3z );

  updateGL();
}

void OpenGL3DScene::setFirstPersonView ( bool good_pos )
{
  fp_view_ = true;

  if ( good_pos )
    moveCamera ( 0.0f, 0.0f, 1.8f, 90.0, 0.0f, 0.0f );
  updateGL();
}

void OpenGL3DScene::setGlobalView()
{
  fp_view_ = false;

  camera_.reset();
  autoAdjustGView();

  updateGL();
}

void OpenGL3DScene::autoAdjustGView()
{

  makeCurrent();
  GLfloat center_x = 0.0f, center_y = 0.0f;
  GLfloat x_t = 0.0f, y_t = 0.0f, z_t = 1.0f;

  if ( max_x_ != -std::numeric_limits< float >::max() && max_y_ != -std::numeric_limits< float >::max() &&
       min_x_ != std::numeric_limits< float >::min() && min_y_ != std::numeric_limits< float >::min() )
  {
    center_x = min_x_ + ( max_x_ - min_x_ ) / 2.0f;
    center_y = min_y_ + ( max_y_ - min_y_ ) / 2.0f;

    x_t = center_x;
    y_t = center_y;

    GLfloat half_width = qMax ( center_x - min_x_,max_x_ - center_x ) + auto_adjust_offset_;
    GLfloat half_height = qMax ( center_y - min_y_,max_y_ - center_y ) + auto_adjust_offset_;

    GLfloat half_side = qMax ( half_width,half_height );

    GLfloat z_t = half_side/tanf ( view_angle_/2.0 );

    if ( z_t < 1.0f ) z_t = 1.0f;

    camera_.moveAbs ( x_t, y_t, z_t );

  }
//  emit zoomChanged(zT);
}

void OpenGL3DScene::registerPath( std::string name, QColor path_color )
{
  QMutexLocker locker ( &mutex_ );

  if( path_items_.find(name) != path_items_.end() )
    return;

  PathItem new_path;
  new_path.color = path_color;
  path_items_[name] = new_path;
}

void OpenGL3DScene::unregisterPath( std::string name )
{
  QMutexLocker locker ( &mutex_ );

  std::map <std::string, PathItem>::iterator path_iter = path_items_.find(name);
  if( path_iter != path_items_.end() )
    path_iter->second.removed = true;
}

void OpenGL3DScene::pushPosition( std::string name, const Eigen::Vector3d& t )
{
  QMutexLocker locker ( &mutex_ );

  if( path_items_.find(name) == path_items_.end() )
    return;
  path_items_[name].unprocessed_poses.push_back(t);
}

void OpenGL3DScene::registerLine( std::string name, QColor line_color )
{
  QMutexLocker locker ( &mutex_ );

  if( line_items_.find(name) != line_items_.end() )
    return;

  LineItem new_line;
  new_line.color = line_color;
  new_line.list = GL_INVALID_VALUE;
  line_items_[name] = new_line;
}

void OpenGL3DScene::unregisterLine( std::string name )
{
  QMutexLocker locker ( &mutex_ );

  std::map <std::string, LineItem>::iterator lines_iter = line_items_.find(name);
  if( lines_iter != line_items_.end() )
    lines_iter->second.removed = true;
}

void OpenGL3DScene::setLine( std::string name, const Eigen::Vector3d& p0, const Eigen::Vector3d& p1 )
{
  QMutexLocker locker ( &mutex_ );

  if( line_items_.find(name) == line_items_.end() )
    return;

  line_items_[name].p0 = p0;
  line_items_[name].p1 = p1;
  line_items_[name].updated = true;
}

void OpenGL3DScene::registerCloud( std::string name, QColor cloud_color )
{
  QMutexLocker locker ( &mutex_ );

  if( cloud_items_.find(name) != cloud_items_.end() )
    return;

  CloudItem new_cloud;
  new_cloud.color = cloud_color;
  cloud_items_[name] = new_cloud;
}

void OpenGL3DScene::unregisterCloud( std::string name )
{

  QMutexLocker locker ( &mutex_ );

  std::map <std::string, CloudItem>::iterator cloud_iter = cloud_items_.find(name);
  if( cloud_iter != cloud_items_.end() )
    cloud_iter->second.removed = true;
}

void OpenGL3DScene::pushCloud( std::string name, const std::vector< Eigen::Vector3d > &pts )
{
  QMutexLocker locker ( &mutex_ );
  if( cloud_items_.find(name) == cloud_items_.end() )
    return;

  cloud_items_[name].unprcessed_cloud.insert(cloud_items_[name].unprcessed_cloud.end(),
                                             pts.begin(), pts.end());
}

void OpenGL3DScene::registerAxes( std::string name, QColor axes_color )
{
  QMutexLocker locker ( &mutex_ );

  if( axes_items_.find(name) != axes_items_.end() )
    return;

  AxesItem new_axes;
  new_axes.color = axes_color;
  new_axes.list = GL_INVALID_VALUE;

  for ( int i = 0; i < 7; i++ )
  {
    new_axes.qobjs[i] = gluNewQuadric();
    gluQuadricNormals ( new_axes.qobjs[i], GLU_SMOOTH );
  }

  axes_items_[name] = new_axes;
}

void OpenGL3DScene::unregisterAxes( std::string name )
{
  QMutexLocker locker ( &mutex_ );

  std::map <std::string, AxesItem>::iterator axes_iter = axes_items_.find(name);
  if( axes_iter != axes_items_.end() )
    axes_iter->second.removed = true;
}

void OpenGL3DScene::setAxesPos( std::string name, const Eigen::Vector3d& r, const Eigen::Vector3d& t )
{
  QMutexLocker locker ( &mutex_ );

  if( axes_items_.find(name) == axes_items_.end() )
    return;

  axes_items_[name].r = r;
  axes_items_[name].t = t;
  axes_items_[name].updated = true;
}

void OpenGL3DScene::unregisterAllStructures()
{
  // WARNING MAYBE BUG
  QMutexLocker locker ( &mutex_ );

  std::map <std::string, PathItem>::iterator path_iter;
  for ( path_iter = path_items_.begin(); path_iter != path_items_.end(); path_iter++ )
  {
    for( int i = 0; i < path_iter->second.lists.size(); i++)
      glDeleteLists ( path_iter->second.lists[i], 1 );
  }

  path_items_.clear();

  std::map <std::string, LineItem>::iterator lines_iter;
  for ( lines_iter = line_items_.begin(); lines_iter != line_items_.end(); lines_iter++ )
  {
    if ( lines_iter->second.list != GL_INVALID_VALUE )
      glDeleteLists ( lines_iter->second.list, 1 );
  }

  line_items_.clear();

  std::map <std::string, CloudItem>::iterator cloud_iter;
  for ( cloud_iter = cloud_items_.begin(); cloud_iter != cloud_items_.end(); cloud_iter++ )
  {
    for( int i = 0; i < cloud_iter->second.lists.size(); i++)
      glDeleteLists ( cloud_iter->second.lists[i], 1 );
  }

  cloud_items_.clear();

  std::map <std::string, AxesItem>::iterator axes_iter;
  for ( axes_iter = axes_items_.begin(); axes_iter != axes_items_.end(); axes_iter++ )
  {
    if ( axes_iter->second.list != GL_INVALID_VALUE )
      glDeleteLists ( axes_iter->second.list, 1 );
    for ( int i = 0; i < 7; i++ )
      gluDeleteQuadric ( axes_iter->second.qobjs[i] );
  }

  axes_items_.clear();
}

void OpenGL3DScene::updateAllStructure()
{
  QMutexLocker locker ( &mutex_ );
  std::vector< std::string > structure_names;
  std::map <std::string, PathItem>::iterator path_iter;
  for ( path_iter = path_items_.begin(); path_iter != path_items_.end(); path_iter++ )
    structure_names.push_back(path_iter->first);

  std::map <std::string, LineItem>::iterator lines_iter;
  for ( lines_iter = line_items_.begin(); lines_iter != line_items_.end(); lines_iter++ )
    structure_names.push_back(lines_iter->first);

  std::map <std::string, CloudItem>::iterator cloud_iter;
  for ( cloud_iter = cloud_items_.begin(); cloud_iter != cloud_items_.end(); cloud_iter++ )
    structure_names.push_back(cloud_iter->first);

  std::map <std::string, AxesItem>::iterator axes_iter;
  for ( axes_iter = axes_items_.begin(); axes_iter != axes_items_.end(); axes_iter++ )
    structure_names.push_back(axes_iter->first);

  for( int i = 0; i < structure_names.size(); i++)
    updateStructure ( structure_names[i], false );

  updateGL();
}

void OpenGL3DScene::keyPressEvent ( QKeyEvent * event )
{

  QWidget::keyPressEvent ( event );
  makeCurrent();

  switch ( event->key() )
  {
  case Qt::Key_Left:
    moveCameraLeft ( t_inc_ );
    break;
  case Qt::Key_Right:
    moveCameraRight ( t_inc_ );
    break;
  case Qt::Key_Up:
    if ( fp_view_ )
      moveCameraForward ( t_inc_ );
    else
      moveCameraUp ( t_inc_ );
    break;
  case Qt::Key_Down:
    if ( fp_view_ )
      moveCameraBackward ( t_inc_ );
    else
      moveCameraDown ( t_inc_ );
    break;
  case Qt::Key_PageUp :
    if ( fp_view_ )
      moveCameraUp ( t_inc_ );
    else
      moveCameraForward ( t_inc_ );
    break;
  case Qt::Key_PageDown :
    if ( fp_view_ )
      moveCameraDown ( t_inc_ );
    else
      moveCameraBackward ( t_inc_ );
    break;
  case Qt::Key_A:
    if ( fp_view_ )
      turnCameraCCWY ( r_inc_ );
    break;
  case Qt::Key_S:
    if ( fp_view_ )
      turnCameraCWY ( r_inc_ );
    break;
  case Qt::Key_Q:
    if ( !fp_view_ )
      turnCameraCWZ( r_inc_ );
    break;
  case Qt::Key_W:
    if ( !fp_view_ )
      turnCameraCCWZ( r_inc_ );
    break;
  }
}

void OpenGL3DScene::wheelEvent ( QWheelEvent * event )
{
  QWidget::wheelEvent ( event );
  int num_degrees = event->delta() / 8;
  int num_steps = num_degrees / 15;

  ( num_steps > 0 ) ?moveCameraForward ( num_steps*t_inc_ ) :moveCameraBackward ( abs ( num_steps ) *t_inc_ );
  event->accept();
}

void OpenGL3DScene::mousePressEvent ( QMouseEvent* event )
{
  QWidget::mousePressEvent ( event );
  if( event->button() == Qt::LeftButton )
    left_mouse_button_pressed_ = true;
  else if( event->button() == Qt::RightButton )
    right_mouse_button_pressed_ = true;

  mouse_init_x_ =  event->x();
  mouse_init_y_ =  event->y();
}

void OpenGL3DScene::mouseReleaseEvent ( QMouseEvent* event )
{
  QWidget::mouseReleaseEvent( event );
  left_mouse_button_pressed_ = false;
  right_mouse_button_pressed_ = false;
}

void OpenGL3DScene::mouseMoveEvent ( QMouseEvent* event )
{
  QWidget::mouseMoveEvent ( event );
  GLfloat mouse_inc_x = GLfloat(event->x() - mouse_init_x_);
  GLfloat mouse_inc_y = GLfloat(event->y() - mouse_init_y_);
  mouse_inc_x /= GLfloat(this->geometry().width());
  mouse_inc_y /= GLfloat(this->geometry().height());

  if( left_mouse_button_pressed_ )
  {
    moveCameraLeft( 2*mouse_inc_x );
    moveCameraUp( 2*mouse_inc_y );
    mouse_init_x_ = event->x();
    mouse_init_y_ = event->y();
  }
  else if( right_mouse_button_pressed_ )
  {
    if ( fp_view_ )
      turnCameraCCWY( 100*mouse_inc_x );
    else
      turnCameraCCWZ( 100*mouse_inc_x );
    //moveCameraUp( 2*mouse_inc_y );
    mouse_init_x_ = event->x();
    mouse_init_y_ = event->y();
  }
}

max_stars_repo_name: xloem/xivo

max_issues_repo_name: xloem/xivo

max_forks_repo_name: xloem/xivo


text:
/*
Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt)
*/

#include <type_traits>
#include <functional>
#include <utility>
#include <boost/callable_traits/is_const_member.hpp>
#include "test.hpp"

struct foo {};

template<typename T>
void assert_const_qualified() {
    CT_ASSERT( is_const_member<T>());
}

template<typename T>
void assert_not_const_qualified() {
    CT_ASSERT(! is_const_member<T>());
}

int main() {

    {
        using f   = void(foo::*)();
        using l   = void(foo::*)() LREF;
        using r   = void(foo::*)() RREF ;
        using c   = void(foo::*)() const;
        using cl  = void(foo::*)() const LREF;
        using cr  = void(foo::*)() const RREF;
        using v   = void(foo::*)() volatile;
        using vl  = void(foo::*)() volatile LREF;
        using vr  = void(foo::*)() volatile RREF;
        using cv  = void(foo::*)() const volatile;
        using cvl = void(foo::*)() const volatile LREF;
        using cvr = void(foo::*)() const volatile RREF;

        assert_not_const_qualified<f>();
        assert_not_const_qualified<l>();
        assert_not_const_qualified<r>();
        assert_const_qualified<c>();
        assert_const_qualified<cl>();
        assert_const_qualified<cr>();
        assert_not_const_qualified<v>();
        assert_not_const_qualified<vl>();
        assert_not_const_qualified<vr>();
        assert_const_qualified<cv>();
        assert_const_qualified<cvl>();
        assert_const_qualified<cvr>();
    }

    {
        struct f   { int operator()() { return 0; } };
        struct l   { int operator()() LREF { return 0; } };
        struct r   { int operator()() RREF { return 0; } };
        struct c   { int operator()() const { return 0; } };
        struct cl  { int operator()() const LREF { return 0; } };
        struct cr  { int operator()() const RREF { return 0; } };
        struct v   { int operator()() volatile { return 0; } };
        struct vl  { int operator()() volatile LREF { return 0; } };
        struct vr  { int operator()() volatile RREF { return 0; } };
        struct cv  { int operator()() const volatile { return 0; } };
        struct cvl { int operator()() const volatile LREF { return 0; } };
        struct cvr { int operator()() const volatile RREF { return 0; } };

        assert_not_const_qualified<f>();
        assert_not_const_qualified<l>();
        assert_not_const_qualified<r>();
        assert_const_qualified<c>();
        assert_const_qualified<cl>();
        assert_const_qualified<cr>();
        assert_not_const_qualified<v>();
        assert_not_const_qualified<vl>();
        assert_not_const_qualified<vr>();
        assert_const_qualified<cv>();
        assert_const_qualified<cvl>();
        assert_const_qualified<cvr>();
    }

#ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS

    {
        using f   = void();
        using l   = void() LREF;
        using r   = void() RREF ;
        using c   = void() const;
        using cl  = void() const LREF;
        using cr  = void() const RREF;
        using v   = void() volatile;
        using vl  = void() volatile LREF;
        using vr  = void() volatile RREF;
        using cv  = void() const volatile;
        using cvl = void() const volatile LREF;
        using cvr = void() const volatile RREF;

        CT_ASSERT(! is_const_member<f>());
        CT_ASSERT(! is_const_member<l>());
        CT_ASSERT(! is_const_member<r>());
        CT_ASSERT( is_const_member<c>());
        CT_ASSERT( is_const_member<cl>());
        CT_ASSERT( is_const_member<cr>());
        CT_ASSERT(! is_const_member<v>());
        CT_ASSERT(! is_const_member<vl>());
        CT_ASSERT(! is_const_member<vr>());
        CT_ASSERT( is_const_member<cv>());
        CT_ASSERT( is_const_member<cvl>());
        CT_ASSERT( is_const_member<cvr>());
    }

#endif

    using f_ptr = void(*)();
    assert_not_const_qualified<f_ptr>();
    assert_not_const_qualified<f_ptr foo::*>();
    assert_not_const_qualified<int foo::*>();
    assert_not_const_qualified<void(&)()>();
}


text:
// @@@LICENSE
//
//      Copyright (c) 2010-2013 LG Electronics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// LICENSE@@@

#include "util/StringUtils.h"
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "exceptions/MailException.h"
#include <glib.h>

using namespace std;

const char* const StringUtils::UTF8_REPLACEMENT_CHAR 	= "\xef\xbf\xbd";
const char* const StringUtils::FILE_PREFIX 				= "file://";

void StringUtils::SanitizeASCII(string& text, const char* replacement)
{
	// Replace all unprintable characters
	boost::find_format_all(text, boost::token_finder(!(boost::is_print() || boost::is_space()), boost::token_compress_on), boost::const_formatter(replacement));
}

string StringUtils::GetSanitizedASCII(const string& text, const char* replacement)
{
	string out = text;
	StringUtils::SanitizeASCII(out, replacement);
	return out;
}

void StringUtils::SanitizeUTF8(string& text)
{
	const char* start = text.data();
	const char* end = text.data() + text.length();
	const gchar* endValid = NULL;

	string temp;

	do {
		bool valid = g_utf8_validate(start, end - start, &endValid);

		if(valid && temp.empty()) {
			// string is good as-is
			return;
		}

		// Copy everything up to this point
		temp.append(start, endValid);

		if(!valid) {
			// Add the replacement char
			temp.append(UTF8_REPLACEMENT_CHAR);
		}

		// Find the next valid char
		const char* newStart = g_utf8_find_next_char(endValid, end);

		// Make sure we can't get stuck in a loop; this shouldn't happen though
		if(newStart != NULL && newStart <= start) {
			throw MailException("error sanitizing", __FILE__, __LINE__);
		}

		start = newStart;
	} while(start != NULL && start < end);

	// Replace text
	text.assign(temp);
}

void StringUtils::SanitizeFilePath(string& text)
{
	const int len 		= text.length();
	const int prefixLen	= strlen(FILE_PREFIX);

	// Strip out file://
	if (boost::starts_with(text, FILE_PREFIX) && len > prefixLen) {
		text = text.substr(prefixLen, len-prefixLen);
	}
}

void StringUtils::SanitizeFileCacheName(string& text)
{
	// Replace all '/' and '\'
	boost::find_format_all(text, boost::first_finder("/", boost::is_iequal()), boost::const_formatter("_"));
	boost::find_format_all(text, boost::first_finder("\\", boost::is_iequal()), boost::const_formatter("_"));
}

max_stars_repo_name: webOS-ports/mojomail

max_issues_repo_name: openwebos/app-services

max_forks_repo_name: openwebos/app-services


text:
#include <iostream>
#include <limits>

#include <Eigen/Geometry>
#include <Eigen/Dense>
#include <Eigen/Eigen>
#include <unsupported/Eigen/NonLinearOptimization>

#include <opencv2/calib3d/calib3d.hpp>
#include <sys/stat.h>

#include "Optimization.h"
#include "math.hh"

bool translation_gauss_newton(const std::vector<cv::Point3d>& world_pts, const std::vector<cv::Point2d>& image_pts,
                              const Eigen::Matrix3d &K, const Eigen::Quaterniond& Q, Eigen::Vector3d &T,
                              double& residual, int& iter)
//----------------------------------------------------------------------------------------------------------------------
{
   double tx = T[0], ty = T[1], tz = T[2];
   const Eigen::Matrix3d KI = K.inverse();
   size_t m = std::min(world_pts.size(), image_pts.size());
   std::vector<Eigen::Quaterniond> world_quaternions;
   std::vector<Eigen::Vector3d> image_rays;
   const Eigen::Quaterniond QI = Q.inverse();
   for (size_t row = 0; row < m; row++)
   {
      cv::Point2d &pt = const_cast<cv::Point2d &>(image_pts[row]);
      Eigen::Vector3d pt2d = KI * Eigen::Vector3d(pt.x, pt.y, 1);
      pt2d /= pt2d[2];
      image_rays.push_back(pt2d);
      const cv::Point3d pt3d = world_pts[row];
      const Eigen::Quaterniond QR = Q * Eigen::Quaterniond(0, pt3d.x, pt3d.y, pt3d.z) * QI;
      world_quaternions.push_back(QR);
   }
   iter = 0;
   double prev_min_residual = std::numeric_limits<double>::max();
   double eps = 0.0000001;
   do
   {
      Eigen::MatrixXd J(m, 3);
//      Eigen::MatrixXd r(m, 3);
      Eigen::MatrixXd r(m, 1);
      double min_residual = std::numeric_limits<double>::max();
      for (size_t row = 0; row < m; row++)
      {
         Eigen::Vector3d pt2d = image_rays[row];
         double u = pt2d[0], v = pt2d[1];
         const Eigen::Vector3d Rv = world_quaternions[row].vec();
         //  Eigen::Vector3d Rr = R*Eigen::Vector3d(pt3d.x, pt3d.y, pt3d.z);
         Eigen::Vector3d pt3d = Rv + Eigen::Vector3d(tx, ty, tz);
         pt3d /= pt3d[2];
         Eigen::Vector3d diff = pt3d - pt2d;
         residual = diff.dot(diff);
         if (residual < min_residual)
            min_residual = residual;
//         std::cout << "refine: " << pt3d.transpose() << " " << pt2d.transpose() << " " << diff.transpose() << " " << residual << std::endl;
         Eigen::Vector3d d;
         J.row(row) << 2 * (Rv[0] + tx - u), 2 * (Rv[1] + ty - v), 2 * (Rv[2] + tz - 1);
         r.row(row) << residual;
      }
//      std::cout << "minmax " << min_residual << " " << (min_residual - prev_min_residual) <<  std::endl;
      if (min_residual > prev_min_residual) break;
      prev_min_residual = min_residual;
      auto Jt = J.transpose();
//      std::cout << "JTr: " << std::endl << (Jt * r) << std::endl << "==================== " << std::endl;

      //auto llt = (Jt * J).ldlt();
      auto llt = (Jt * J).llt();
      double dx, dy, dz;
      if (llt.info() == Eigen::Success)
      {
         auto delta =  llt.solve(Jt * r * (-1.0));
         dx = delta(0, 0), dy = delta(1, 0), dz = delta(2, 0);
//         std::cout << delta << std::endl;
      }
      else
      {
         auto JtJI = (Jt*J).inverse();
         auto dd = -(JtJI*Jt);
         auto delta = dd*r;
         dx = delta(0, 0), dy = delta(1, 0), dz = delta(2, 0);
      }
      if ( (mut::near_zero(dx, eps)) && (mut::near_zero(dy, eps)) && (mut::near_zero(dz, eps)) ) break;
      tx += dx;
      ty += dy;
      tz += dz;
   } while (iter++ < 200);
   if ( (iter > 1) && (iter < 100) )
   {
      T[0] = tx; T[1] = ty; T[2] = tz;
      return true;
   }
   return false;
}

bool translation_levenberg_marquardt3d(const std::vector<cv::Point3d>& world_pts, const std::vector<cv::Point2d>& image_pts,
                                     const Eigen::Matrix3d &K, const Eigen::Quaterniond& Q, Eigen::Vector3d &T,
                                     int& iterations)
//-----------------------------------------------------------------------------------------------------------------------
{
   TranslationLevenbergMarquardt3D functor(world_pts, image_pts, K, Q);
   Eigen::LevenbergMarquardt<TranslationLevenbergMarquardt3D, double> lm(functor);
   Eigen::VectorXd x(3);
   x << T[0], T[1], T[2];
   iterations = 0;
   Eigen::LevenbergMarquardtSpace::Status status = lm.minimizeInit(x);
   if (status == Eigen::LevenbergMarquardtSpace::ImproperInputParameters)
      return false;
   do
   {
      status = lm.minimizeOneStep(x);
      if (status == Eigen::LevenbergMarquardtSpace::Running)
         iterations++;
   } while (status == Eigen::LevenbergMarquardtSpace::Running);
   if (iterations > 1)
   {
      T = x;
      return true;
   }
   return false;
}

bool translation_levenberg_marquardt2d_depth(const std::vector<cv::Point3d>& world_pts,
                                             const std::vector<cv::Point3d>& image_pts, const Eigen::Matrix3d &K,
                                             const Eigen::Quaterniond& Q, Eigen::Vector3d &T, const double depth,
                                             int& iterations)
//--------------------------------------------------------------------------------------------------------------
{
   TranslationLevenbergMarquardt2DDepth functor(world_pts, image_pts, K, Q, depth);
   Eigen::LevenbergMarquardt<TranslationLevenbergMarquardt2DDepth, double> lm(functor);
   Eigen::VectorXd x(3);
   x << T[0], T[1], T[2];
   iterations = 0;
   Eigen::LevenbergMarquardtSpace::Status status = lm.minimizeInit(x);
   if (status == Eigen::LevenbergMarquardtSpace::ImproperInputParameters)
      return false;
   do
   {
      status = lm.minimizeOneStep(x);
      if (status == Eigen::LevenbergMarquardtSpace::Running)
         iterations++;
   } while (status == Eigen::LevenbergMarquardtSpace::Running);
   if (iterations > 1)
   {
      T = x;
      return true;
   }
   return false;
}

max_stars_repo_name: donaldmunro/PlanarTrainer

max_issues_repo_name: donaldmunro/PlanarTrainer

max_forks_repo_name: donaldmunro/PlanarTrainer


text:
/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author 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.

*/

#include "libtorrent/session.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/thread.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/file.hpp"
#include <boost/tuple/tuple.hpp>
#include <boost/bind.hpp>

#include "test.hpp"
#include "setup_transfer.hpp"
#include <fstream>
#include <iostream>

using namespace libtorrent;
namespace lt = libtorrent;

using boost::tuples::ignore;

const int mask = alert::all_categories & ~(alert::performance_warning | alert::stats_notification);

int peer_disconnects = 0;

int tracker_responses = 0;

bool on_alert(alert const* a)
{
	if (alert_cast<tracker_reply_alert>(a))
		++tracker_responses;
	else if (alert_cast<peer_disconnected_alert>(a))
		++peer_disconnects;
	else if (alert_cast<peer_error_alert>(a))
		++peer_disconnects;

	return false;
}

// simulate a full disk
struct test_storage : default_storage
{
	test_storage(storage_params const& params)
		: default_storage(params)
  		, m_written(0)
		, m_limit(16 * 1024 * 2)
	{}

	virtual void set_file_priority(std::vector<boost::uint8_t> const& p
		, storage_error& ec) {}

	void set_limit(int lim)
	{
		mutex::scoped_lock l(m_mutex);
		m_limit = lim;
	}

	int writev(
		file::iovec_t const* bufs
		, int num_bufs
		, int piece_index
		, int offset
		, int flags
		, storage_error& se)
	{
		mutex::scoped_lock l(m_mutex);
		if (m_written >= m_limit)
		{
			std::cerr << "storage written: " << m_written << " limit: " << m_limit << std::endl;
			error_code ec;
#if BOOST_VERSION == 103500
			ec = error_code(boost::system::posix_error::no_space_on_device, get_posix_category());
#elif BOOST_VERSION > 103500
			ec = error_code(boost::system::errc::no_space_on_device, get_posix_category());
#else
			ec = error_code(ENOSPC, get_posix_category());
#endif
			se.ec = ec;
			return 0;
		}

		for (int i = 0; i < num_bufs; ++i)
			m_written += bufs[i].iov_len;
		l.unlock();
		return default_storage::writev(bufs, num_bufs, piece_index, offset, flags, se);
	}

	virtual ~test_storage() {}

	int m_written;
	int m_limit;
	mutex m_mutex;
};

storage_interface* test_storage_constructor(storage_params const& params)
{
	return new test_storage(params);
}

void test_transfer(int proxy_type, settings_pack const& sett
	, bool test_disk_full = false
	, storage_mode_t storage_mode = storage_mode_sparse)
{
	static int listen_port = 0;

	char const* test_name[] = {"no", "SOCKS4", "SOCKS5", "SOCKS5 password", "HTTP", "HTTP password"};

	fprintf(stderr, "\n\n  ==== TESTING %s proxy ==== disk-full: %s\n\n\n"
		, test_name[proxy_type], test_disk_full ? "true": "false");

	// in case the previous run was terminated
	error_code ec;
	remove_all("tmp1_transfer", ec);
	remove_all("tmp2_transfer", ec);
	remove_all("tmp1_transfer_moved", ec);
	remove_all("tmp2_transfer_moved", ec);

	// these are declared before the session objects
	// so that they are destructed last. This enables
	// the sessions to destruct in parallel
	session_proxy p1;
	session_proxy p2;

	lt::session ses1(fingerprint("LT", 0, 1, 0, 0)
		, std::make_pair(48075 + listen_port, 49000), "0.0.0.0", 0, mask);
	lt::session ses2(fingerprint("LT", 0, 1, 0, 0)
		, std::make_pair(49075 + listen_port, 50000), "0.0.0.0", 0, mask);
	listen_port += 10;

	int proxy_port = 0;
	if (proxy_type)
	{
		proxy_port = start_proxy(proxy_type);

		settings_pack pack;
		pack.set_str(settings_pack::proxy_username, "testuser");
		pack.set_str(settings_pack::proxy_password, "testpass");
		pack.set_int(settings_pack::proxy_type, (settings_pack::proxy_type_t)proxy_type);
		pack.set_int(settings_pack::proxy_port, proxy_port);

		// test resetting the proxy in quick succession.
		// specifically the udp_socket connecting to a new
		// socks5 proxy while having one connection attempt
		// in progress.
		pack.set_str(settings_pack::proxy_hostname, "5.6.7.8");
		ses1.apply_settings(pack);

		pack.set_str(settings_pack::proxy_hostname, "127.0.0.1");
		ses1.apply_settings(pack);
		ses2.apply_settings(pack);
	}

	settings_pack pack = sett;
	// we need a short reconnect time since we
	// finish the torrent and then restart it
	// immediately to complete the second half.
	// using a reconnect time > 0 will just add
	// to the time it will take to complete the test
	pack.set_int(settings_pack::min_reconnect_time, 0);
	pack.set_int(settings_pack::stop_tracker_timeout, 1);
	pack.set_bool(settings_pack::announce_to_all_trackers, true);
	pack.set_bool(settings_pack::announce_to_all_tiers, true);

	// make sure we announce to both http and udp trackers
	pack.set_bool(settings_pack::prefer_udp_trackers, false);
	pack.set_bool(settings_pack::enable_outgoing_utp, false);
	pack.set_bool(settings_pack::enable_incoming_utp, false);
	pack.set_bool(settings_pack::enable_lsd, false);
	pack.set_bool(settings_pack::enable_natpmp, false);
	pack.set_bool(settings_pack::enable_upnp, false);
	pack.set_bool(settings_pack::enable_dht, false);
	pack.set_int(settings_pack::alert_mask, mask);

	pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_disabled);
	pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_disabled);

	pack.set_bool(settings_pack::allow_multiple_connections_per_ip, false);

	pack.set_int(settings_pack::unchoke_slots_limit, 0);
	ses1.apply_settings(pack);
	TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == 0);

	pack.set_int(settings_pack::unchoke_slots_limit, -1);
	ses1.apply_settings(pack);
	TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == -1);

	pack.set_int(settings_pack::unchoke_slots_limit, 8);
	ses1.apply_settings(pack);
	TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == 8);

	ses2.apply_settings(pack);

	torrent_handle tor1;
	torrent_handle tor2;

	create_directory("tmp1_transfer", ec);
	std::ofstream file("tmp1_transfer/temporary");
	boost::shared_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024, 13, false);
	file.close();

	TEST_CHECK(exists(combine_path("tmp1_transfer", "temporary")));

	add_torrent_params addp(&test_storage_constructor);
	addp.flags &= ~add_torrent_params::flag_paused;
	addp.flags &= ~add_torrent_params::flag_auto_managed;

	add_torrent_params params;
	params.storage_mode = storage_mode;

	wait_for_listen(ses1, "ses1");
	wait_for_listen(ses2, "ses2");

	peer_disconnects = 0;

	// test using piece sizes smaller than 16kB
	boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0
		, true, false, true, "_transfer", 8 * 1024, &t, false, test_disk_full?&addp:&params);

	int num_pieces = tor2.torrent_file()->num_pieces();
	std::vector<int> priorities(num_pieces, 1);

	// also test to move the storage of the downloader and the uploader
	// to make sure it can handle switching paths
	bool test_move_storage = false;

	tracker_responses = 0;
	int upload_mode_timer = 0;

	wait_for_downloading(ses2, "ses2");

	for (int i = 0; i < 200; ++i)
	{
		torrent_status st1 = tor1.status();
		torrent_status st2 = tor2.status();

		print_alerts(ses1, "ses1", true, true, true, &on_alert);
		print_alerts(ses2, "ses2", true, true, true, &on_alert);

		if (i % 10 == 0)
		{
			print_ses_rate(i / 10.f, &st1, &st2);
		}

		if (!test_move_storage && st2.progress > 0.25f)
		{
			test_move_storage = true;
			tor1.move_storage("tmp1_transfer_moved");
			tor2.move_storage("tmp2_transfer_moved");
			std::cerr << "moving storage" << std::endl;
		}

		// wait 10 loops before we restart the torrent. This lets
		// us catch all events that failed (and would put the torrent
		// back into upload mode) before we restart it.

		// TODO: factor out the disk-full test into its own unit test
		if (test_disk_full && st2.upload_mode && ++upload_mode_timer > 10)
		{
			test_disk_full = false;
			((test_storage*)tor2.get_storage_impl())->set_limit(16 * 1024 * 1024);

			// if we reset the upload mode too soon, there may be more disk
			// jobs failing right after, putting us back in upload mode. So,
			// give the disk some time to fail all disk jobs before resetting
			// upload mode to false
			test_sleep(500);

			// then we need to drain the alert queue, so the peer_disconnects
			// counter doesn't get incremented by old alerts
			print_alerts(ses1, "ses1", true, true, true, &on_alert);
			print_alerts(ses2, "ses2", true, true, true, &on_alert);

			tor2.set_upload_mode(false);

			// at this point we probably disconnected the seed
			// so we need to reconnect as well
			fprintf(stderr, "%s: reconnecting peer\n", aux::time_now_string());
			error_code ec;
			tor2.connect_peer(tcp::endpoint(address::from_string("127.0.0.1", ec)
				, ses1.listen_port()));

			TEST_CHECK(tor2.status().is_finished == false);
			fprintf(stderr, "disconnects: %d\n", peer_disconnects);
			TEST_CHECK(peer_disconnects >= 2);
			fprintf(stderr, "%s: discovered disk full mode. Raise limit and disable upload-mode\n", aux::time_now_string());
			peer_disconnects = 0;
			continue;
		}

		if (!test_disk_full && st2.is_seeding) break;

		TEST_CHECK(st1.state == torrent_status::seeding
			|| st1.state == torrent_status::checking_files);
		TEST_CHECK(st2.state == torrent_status::downloading
			|| st2.state == torrent_status::checking_resume_data
			|| (test_disk_full && !st2.error.empty()));

		if (!test_disk_full && peer_disconnects >= 2) break;

		// if nothing is being transferred after 2 seconds, we're failing the test
//		if (!test_disk_full && st1.upload_payload_rate == 0 && i > 20) break;

		test_sleep(100);
	}

	TEST_CHECK(tor2.status().is_seeding);

	// this allows shutting down the sessions in parallel
	p1 = ses1.abort();
	p2 = ses2.abort();

	if (proxy_type) stop_proxy(proxy_port);
}

int test_main()
{
	using namespace libtorrent;

	settings_pack p;

	// test no contiguous_recv_buffers
	p = settings_pack();
	p.set_bool(settings_pack::contiguous_recv_buffer, false);
	test_transfer(0, p);

	// test with all kinds of proxies
	p = settings_pack();
	for (int i = 0; i < 6; ++i)
		test_transfer(i, p);

	// test with a (simulated) full disk
	test_transfer(0, p, true);

	// test allowed fast
	p = settings_pack();
	p.set_int(settings_pack::allowed_fast_set_size, 2000);
	test_transfer(0, p, false);

	test_transfer(0, p, false);

	// test storage_mode_allocate
	fprintf(stderr, "full allocation mode\n");
	test_transfer(0, p, false, storage_mode_allocate);

#ifndef TORRENT_NO_DEPRECATE
	fprintf(stderr, "compact mode\n");
	test_transfer(0, p, false, storage_mode_compact);
#endif

	error_code ec;
	remove_all("tmp1_transfer", ec);
	remove_all("tmp2_transfer", ec);
	remove_all("tmp1_transfer_moved", ec);
	remove_all("tmp2_transfer_moved", ec);

	return 0;
}

max_stars_repo_name: TeoTwawki/libtorrent

max_issues_repo_name: TeoTwawki/libtorrent

max_forks_repo_name: TeoTwawki/libtorrent