<commit_before>// Copyright (c) 2014 Bauhaus-Universitaet Weimar
// This Software is distributed under the Modified BSD License, see license.txt.
//
// Virtual Reality and Visualization Research Group
// Faculty of Media, Bauhaus-Universitaet Weimar
// http://www.uni-weimar.de/medien/vr

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/natural_neighbor_coordinates_2.h>

#include <lamure/pre/bvh.h>
#include <lamure/pre/radius_computation_natural_neighbours.h>
#include <lamure/pre/plane.h>

#include <iostream>

namespace lamure {
namespace pre{

namespace nni {

using K       = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point2  = K::Point_2;
using Vector2 = K::Vector_2;
using Dh2     = CGAL::Delaunay_triangulation_2<K>;

struct nni_sample_t {
    scm::math::vec2f xy_;
    scm::math::vec2f uv_;
};

static void find_natural_neighbours(
    bvh const& tree,
    std::vector<std::pair<surfel_id_t, real>> & nearest_neighbour_ids,
    vec3r const & point_of_interest,
    std::vector<std::pair<surfel, double>>& natural_neighbours) {

    std::srand(613475635);
    std::random_shuffle(nearest_neighbour_ids.begin(), nearest_neighbour_ids.end());

    unsigned int num_neighbours = nearest_neighbour_ids.size();

    //compile points
    double* points = new double[num_neighbours*3];

    auto const& bvh_nodes = tree.nodes();

    std::vector<vec3r> nn_positions;

    nn_positions.reserve(nearest_neighbour_ids.size());

    uint32_t point_counter = 0;

    std::vector<surfel> nearest_neighbour_copies;
    for (auto const& idx_pair : nearest_neighbour_ids) {

        surfel const current_nearest_neighbour_surfel =
            bvh_nodes[idx_pair.first.node_idx].mem_array().read_surfel(idx_pair.first.surfel_idx);
        auto const& neighbour_pos
            = current_nearest_neighbour_surfel.pos();

        nearest_neighbour_copies.push_back(current_nearest_neighbour_surfel);

        nn_positions.push_back( neighbour_pos );

        points[3*point_counter+0] = neighbour_pos[0];
        points[3*point_counter+1] = neighbour_pos[1];
        points[3*point_counter+2] = neighbour_pos[2];

        ++point_counter;
    }

    //compute best fit plane
    plane_t plane;
    plane_t::fit_plane(nn_positions, plane);

    bool is_projection_valid = true;

    //project all points to the plane
    double* coords = new double[2*num_neighbours];
    scm::math::vec3f plane_right = plane.get_right();
    for (unsigned int i = 0; i < num_neighbours; ++i) {
        vec3r v = vec3r(points[3*i+0], points[3*i+1], points[3*i+2]);
        vec2r c = plane_t::project(plane, plane_right, v);
        coords[2*i+0] = c[0];
        coords[2*i+1] = c[1];

        if (c[0] != c[0] || c[1] != c[1]) { //is nan?
            is_projection_valid = false;
        }
    }

    if (!is_projection_valid) {
        natural_neighbours.clear();
        delete[] points;
        delete[] coords;

        return;
    }

    //project point of interest
    vec2r coord_poi = plane_t::project(plane, plane_right, point_of_interest);

    //cgal delaunay triangluation
    Dh2 delaunay_triangulation;

    for (unsigned int i = 0; i < num_neighbours; ++i) {
        nni_sample_t sp;
        sp.xy_ = scm::math::vec2f(coords[2*i+0], coords[2*i+1]);
        Point2 p(sp.xy_.x, sp.xy_.y);
        delaunay_triangulation.insert(p);
    }

    Point2 poi_2d(coord_poi.x, coord_poi.y);

    std::vector<std::pair<K::Point_2, K::FT>> sibson_coords;
    CGAL::Triple<std::back_insert_iterator<std::vector<std::pair<K::Point_2, K::FT>>>, K::FT, bool> result =
        natural_neighbor_coordinates_2(
            delaunay_triangulation,
            poi_2d,
            std::back_inserter(sibson_coords));

    if (!result.third) {
        natural_neighbours.clear();
        delete[] points;
        delete[] coords;
        return;
    }

    std::map<unsigned int, double> nni_weights;

    unsigned nn_counter = 0;
    for (const auto& sibs_coord_instance : sibson_coords) {
        nni_weights[nn_counter++] = (double)sibs_coord_instance.second;
    }

    for (const auto& it : nni_weights) {
        surfel const& curr_surfel = nearest_neighbour_copies[it.first] ;
        natural_neighbours.push_back(std::make_pair(curr_surfel, it.second));
    }

    delete[] points;
    delete[] coords;

    sibson_coords.clear();
    nni_weights.clear();
}

}

real radius_computation_natural_neighbours::
compute_radius(const bvh& tree,
			   const surfel_id_t target_surfel) const {

	// find nearest neighbours
	std::vector<std::pair<surfel_id_t, real>> nearest_neighbours
        = tree.get_nearest_neighbours(target_surfel, desired_num_nearest_neighbours_);

    if (nearest_neighbours.size() < min_num_nearest_neighbours_) {
         return 0.0f;
    }

    auto const& current_node = (tree.nodes()[target_surfel.node_idx]);
    vec3r poi = current_node.mem_array().read_surfel(target_surfel.surfel_idx).pos();

    std::vector<std::pair<surfel, double>> natural_neighbours; //surfel + weight

    nni::find_natural_neighbours(tree,
                                 nearest_neighbours,
                                 poi,
                                 natural_neighbours);

    if (natural_neighbours.size() < min_num_natural_neighbours_) {
        return 0.0;
    }

    //determine most distant natural neighbour
    real max_distance = 0.f;
    for (const auto& nn : natural_neighbours) {

        auto const& surfel_pos = nn.first.pos();
        real new_dist = scm::math::length_sqr( poi-( surfel_pos ) );
        max_distance = std::max(max_distance, new_dist);
    }

    if (max_distance >= std::numeric_limits<real>::min()) {
        max_distance = scm::math::sqrt(max_distance);
        //std::cout << "returning: " << 0.5*max_distance;
        return 0.5 * max_distance;

        //out_surfels[job.job_id_*bvh->surfels_per_node() + splat_id].size = 0.5f*max_distance;
    } else {
        return 0.0;
    }

    natural_neighbours.clear();

	};

}// namespace pre
}// namespace lamure<commit_msg>fix indices for determined natural neighbours<commit_after>// Copyright (c) 2014 Bauhaus-Universitaet Weimar
// This Software is distributed under the Modified BSD License, see license.txt.
//
// Virtual Reality and Visualization Research Group
// Faculty of Media, Bauhaus-Universitaet Weimar
// http://www.uni-weimar.de/medien/vr

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/natural_neighbor_coordinates_2.h>

#include <lamure/pre/bvh.h>
#include <lamure/pre/radius_computation_natural_neighbours.h>
#include <lamure/pre/plane.h>

#include <iostream>

namespace lamure {
namespace pre{

namespace nni {

using K       = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point2  = K::Point_2;
using Vector2 = K::Vector_2;
using Dh2     = CGAL::Delaunay_triangulation_2<K>;

struct nni_sample_t {
    scm::math::vec2f xy_;
    scm::math::vec2f uv_;
};

static void find_natural_neighbours(
    bvh const& tree,
    std::vector<std::pair<surfel_id_t, real>> & nearest_neighbour_ids,
    vec3r const & point_of_interest,
    std::vector<std::pair<surfel, double>>& natural_neighbours) {

    std::srand(613475635);
    std::random_shuffle(nearest_neighbour_ids.begin(), nearest_neighbour_ids.end());

    unsigned int num_neighbours = nearest_neighbour_ids.size();

    //compile points
    double* points = new double[num_neighbours*3];

    auto const& bvh_nodes = tree.nodes();

    std::vector<vec3r> nn_positions;

    nn_positions.reserve(nearest_neighbour_ids.size());

    uint32_t point_counter = 0;

    std::vector<surfel> nearest_neighbour_copies;
    for (auto const& idx_pair : nearest_neighbour_ids) {

        surfel const current_nearest_neighbour_surfel =
            bvh_nodes[idx_pair.first.node_idx].mem_array().read_surfel(idx_pair.first.surfel_idx);
        auto const& neighbour_pos
            = current_nearest_neighbour_surfel.pos();

        nearest_neighbour_copies.push_back(current_nearest_neighbour_surfel);

        nn_positions.push_back( neighbour_pos );

        points[3*point_counter+0] = neighbour_pos[0];
        points[3*point_counter+1] = neighbour_pos[1];
        points[3*point_counter+2] = neighbour_pos[2];

        ++point_counter;
    }

    //compute best fit plane
    plane_t plane;
    plane_t::fit_plane(nn_positions, plane);

    bool is_projection_valid = true;

    //project all points to the plane
    double* coords = new double[2*num_neighbours];
    scm::math::vec3f plane_right = plane.get_right();
    for (unsigned int i = 0; i < num_neighbours; ++i) {
        vec3r v = vec3r(points[3*i+0], points[3*i+1], points[3*i+2]);
        vec2r c = plane_t::project(plane, plane_right, v);
        coords[2*i+0] = c[0];
        coords[2*i+1] = c[1];

        if (c[0] != c[0] || c[1] != c[1]) { //is nan?
            is_projection_valid = false;
        }
    }

    if (!is_projection_valid) {
        natural_neighbours.clear();
        delete[] points;
        delete[] coords;

        return;
    }

    //project point of interest
    vec2r coord_poi = plane_t::project(plane, plane_right, point_of_interest);

    //cgal delaunay triangluation
    Dh2 delaunay_triangulation;

    std::vector<scm::math::vec2f> neighbour_2d_coord_pairs;

    for (unsigned int i = 0; i < num_neighbours; ++i) {
        nni_sample_t sp;
        sp.xy_ = scm::math::vec2f(coords[2*i+0], coords[2*i+1]);
        Point2 p(sp.xy_.x, sp.xy_.y);
        delaunay_triangulation.insert(p);
        neighbour_2d_coord_pairs.emplace_back(coords[2*i+0], coords[2*i+1]);
    }

    Point2 poi_2d(coord_poi.x, coord_poi.y);

    std::vector<std::pair<K::Point_2, K::FT>> sibson_coords;
    CGAL::Triple<std::back_insert_iterator<std::vector<std::pair<K::Point_2, K::FT>>>, K::FT, bool> result =
        natural_neighbor_coordinates_2(
            delaunay_triangulation,
            poi_2d,
            std::back_inserter(sibson_coords));

    if (!result.third) {
        natural_neighbours.clear();
        delete[] points;
        delete[] coords;
        return;
    }

    // first  := nearest_neighbour id
    // second := natural_neighbour weight
    std::vector<std::pair<unsigned int, double> > nni_weights;

    unsigned nn_counter = 0;

    for (const auto& sibs_coord_instance : sibson_coords) {
        uint32_t closest_nearest_neighbour_id = std::numeric_limits<uint32_t>::max();
        double min_distance = std::numeric_limits<double>::max();

        uint32_t current_neighbour_id = 0;
        for( auto const& nearest_neighbour_2d : neighbour_2d_coord_pairs) {
            double current_distance = scm::math::length(nearest_neighbour_2d - scm::math::vec2f(sibs_coord_instance.first.x(),
                                                                                sibs_coord_instance.first.y()) );
            if( current_distance < min_distance ) {
                min_distance = current_distance;
                closest_nearest_neighbour_id = current_neighbour_id;
            }

            ++current_neighbour_id;
        }

        //invalidate the 2d coord pair by putting ridiculously large 2d coords that the model is unlikely to contain
        neighbour_2d_coord_pairs[closest_nearest_neighbour_id] = scm::math::vec2f( std::numeric_limits<float>::max(),
                                                                                std::numeric_limits<float>::lowest() );

        nni_weights.emplace_back( closest_nearest_neighbour_id, (double) sibs_coord_instance.second );
    }

    for (const auto& it : nni_weights) {
        surfel const& curr_surfel = nearest_neighbour_copies[it.first] ;
        natural_neighbours.push_back(std::make_pair(curr_surfel, it.second));
    }

    delete[] points;
    delete[] coords;

    sibson_coords.clear();
    nni_weights.clear();
}

}

real radius_computation_natural_neighbours::
compute_radius(const bvh& tree,
			   const surfel_id_t target_surfel) const {

	// find nearest neighbours
	std::vector<std::pair<surfel_id_t, real>> nearest_neighbours
        = tree.get_nearest_neighbours(target_surfel, desired_num_nearest_neighbours_);

    if (nearest_neighbours.size() < min_num_nearest_neighbours_) {
         return 0.0f;
    }

    auto const& current_node = (tree.nodes()[target_surfel.node_idx]);
    vec3r poi = current_node.mem_array().read_surfel(target_surfel.surfel_idx).pos();

    std::vector<std::pair<surfel, double>> natural_neighbours; //surfel + weight

    nni::find_natural_neighbours(tree,
                                 nearest_neighbours,
                                 poi,
                                 natural_neighbours);

    if (natural_neighbours.size() < min_num_natural_neighbours_) {
        return 0.0;
    }

    //determine most distant natural neighbour
    real max_distance = 0.f;
    for (const auto& nn : natural_neighbours) {

        auto const& surfel_pos = nn.first.pos();
        real new_dist = scm::math::length_sqr( poi-( surfel_pos ) );
        max_distance = std::max(max_distance, new_dist);
    }

    if (max_distance >= std::numeric_limits<real>::min()) {
        max_distance = scm::math::sqrt(max_distance);
        //std::cout << "returning: " << 0.5*max_distance;
        return 0.5 * max_distance;

        //out_surfels[job.job_id_*bvh->surfels_per_node() + splat_id].size = 0.5f*max_distance;
    } else {
        return 0.0;
    }

    natural_neighbours.clear();

	};

}// namespace pre
}// namespace lamure<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    renderArea = ui->renderArea;
    rrt = renderArea->rrt;
}

/**
 * @brief Start the simulator.
 */
void MainWindow::on_startButton_clicked()
{
    // get step size and max iterations from GUI.
    rrt->setMaxIterations(ui->maxIterations->text().toInt());
    rrt->setStepSize(ui->stepSize->text().toInt());

    assert(rrt->step_size != 0);
    assert(rrt->max_iter != 0);

    // RRT Algorithm
    for(int i = 0; i < renderArea->rrt->max_iter; i++) {
        Node *q = rrt->getRandomNode();
        if (q) {
            Node *qNearest = rrt->nearest(q->position);
            if (rrt->distance(q->position, qNearest->position) > rrt->step_size) {
                Vector2f newConfig = rrt->newConfig(q, qNearest);
                if (!rrt->obstacles->isSegmentInObstacle(newConfig, qNearest->position)) {
                    Node *qNew = new Node;
                    qNew->position = newConfig;
                    rrt->add(qNearest, qNew);
                }
            }
        }
        if (rrt->reached()) {
            ui->statusBox->setText(tr("Reached Destination!"));
            break;
        }
    }
    Node *q;
    if (rrt->reached()) {
        q = rrt->lastNode;
    }
    else
    {
        // if not reached yet, then shortestPath will start from the closest node to end point.
        q = rrt->nearest(rrt->endPos);
        ui->statusBox->setText(tr("Exceeded max iterations!"));
    }
    // generate shortest path to destination.
    while (q != NULL) {
        rrt->path.push_back(q);
        q = q->parent;
    }
    renderArea->update();
}

/**
 * @brief Delete all obstacles, nodes and paths from the simulator.
 */
void MainWindow::on_resetButton_clicked()
{
    ui->statusBox->setText(tr(""));
    rrt->obstacles->obstacles.clear();
    rrt->obstacles->obstacles.resize(0);
    rrt->deleteNodes(rrt->root);
    rrt->nodes.clear();
    rrt->nodes.resize(0);
    rrt->path.clear();
    rrt->path.resize(0);
    rrt->initialize();
    renderArea->update();
}

MainWindow::~MainWindow()
{
    delete ui;
}
<commit_msg>Fix minor glitch in assert<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    renderArea = ui->renderArea;
    rrt = renderArea->rrt;
}

/**
 * @brief Start the simulator.
 */
void MainWindow::on_startButton_clicked()
{
    // get step size and max iterations from GUI.
    rrt->setMaxIterations(ui->maxIterations->text().toInt());
    rrt->setStepSize(ui->stepSize->text().toInt());

    assert(rrt->step_size > 0);
    assert(rrt->max_iter > 0);

    // RRT Algorithm
    for(int i = 0; i < renderArea->rrt->max_iter; i++) {
        Node *q = rrt->getRandomNode();
        if (q) {
            Node *qNearest = rrt->nearest(q->position);
            if (rrt->distance(q->position, qNearest->position) > rrt->step_size) {
                Vector2f newConfig = rrt->newConfig(q, qNearest);
                if (!rrt->obstacles->isSegmentInObstacle(newConfig, qNearest->position)) {
                    Node *qNew = new Node;
                    qNew->position = newConfig;
                    rrt->add(qNearest, qNew);
                }
            }
        }
        if (rrt->reached()) {
            ui->statusBox->setText(tr("Reached Destination!"));
            break;
        }
    }
    Node *q;
    if (rrt->reached()) {
        q = rrt->lastNode;
    }
    else
    {
        // if not reached yet, then shortestPath will start from the closest node to end point.
        q = rrt->nearest(rrt->endPos);
        ui->statusBox->setText(tr("Exceeded max iterations!"));
    }
    // generate shortest path to destination.
    while (q != NULL) {
        rrt->path.push_back(q);
        q = q->parent;
    }
    renderArea->update();
}

/**
 * @brief Delete all obstacles, nodes and paths from the simulator.
 */
void MainWindow::on_resetButton_clicked()
{
    ui->statusBox->setText(tr(""));
    rrt->obstacles->obstacles.clear();
    rrt->obstacles->obstacles.resize(0);
    rrt->deleteNodes(rrt->root);
    rrt->nodes.clear();
    rrt->nodes.resize(0);
    rrt->path.clear();
    rrt->path.resize(0);
    rrt->initialize();
    renderArea->update();
}

MainWindow::~MainWindow()
{
    delete ui;
}
<|endoftext|>


<commit_before><commit_msg>IMPALA-1712: Remove "stale metadata" warning<commit_after><|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_VERTEX_CONVERTERS_HPP
#define MAPNIK_VERTEX_CONVERTERS_HPP

// boost
#include <boost/type_traits/is_same.hpp>
// mpl
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/distance.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
// fusion
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/make_vector.hpp>
//#include <boost/fusion/adapted/mpl.hpp>

#include <boost/foreach.hpp>
#include <boost/utility.hpp>
#include <boost/array.hpp>

// mapnik
#include <mapnik/agg_helpers.hpp>

// agg
#include "agg_conv_clip_polygon.h"
#include "agg_conv_clip_polyline.h"
#include "agg_conv_smooth_poly1.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"

namespace mapnik {

struct transform_tag {};
struct clip_line_tag {};
struct clip_poly_tag {};
struct smooth_tag {};
struct stroke_tag {};
struct dash_tag {};

namespace  detail {

template <typename T0, typename T1>
struct converter_traits
{
    typedef T0 geometry_type;
    typedef geometry_type conv_type;
    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        throw "BOOM!";
    }
};

template <typename T>
struct converter_traits<T,mapnik::smooth_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_smooth_poly1_curve<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        geom.smooth_value(boost::fusion::at_c<2>(args).smooth());
    }
};

template <typename T>
struct converter_traits<T, mapnik::clip_line_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_clip_polyline<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<0> >::type const& box = boost::fusion::at_c<0>(args);
        geom.clip_box(box.minx(),box.miny(),box.maxx(),box.maxy());
    }
};

template <typename T>
struct converter_traits<T, mapnik::dash_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_dash<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<2> >::type const& sym = boost::fusion::at_c<2>(args);
        double scale_factor = 1.0; //FIXME
        stroke const& stroke_ = sym.get_stroke();
        dash_array const& d = stroke_.get_dash_array();
        dash_array::const_iterator itr = d.begin();
        dash_array::const_iterator end = d.end();
        for (;itr != end;++itr)
        {
            geom.add_dash(itr->first * scale_factor,
                          itr->second * scale_factor);
        }

    }
};

template <typename T>
struct converter_traits<T, mapnik::stroke_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_stroke<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<2> >::type const& sym = boost::fusion::at_c<2>(args);
        stroke const& stroke_ = sym.get_stroke();
        set_join_caps(stroke_,geom);
        geom.generator().miter_limit(4.0); // FIXME : make configurable
        double scale_factor = 1.0; //FIXME
        geom.generator().width(stroke_.get_width() * scale_factor);
    }
};

template <typename T>
struct converter_traits<T,mapnik::clip_poly_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_clip_polygon<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<0> >::type const& box = boost::fusion::at_c<0>(args);
        geom.clip_box(box.minx(),box.miny(),box.maxx(),box.maxy());
    }
};

template <typename T>
struct converter_traits<T,mapnik::transform_tag>
{
    typedef T geometry_type;
    typedef coord_transform2<CoordTransform, geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<3> >::type const& tr = boost::fusion::at_c<3>(args);
        typename boost::mpl::at<Args,boost::mpl::int_<4> >::type const& prj_trans = boost::fusion::at_c<4>(args);
        geom.set_proj_trans(prj_trans);
        geom.set_trans(tr);
    }
};

template <bool>
struct converter_fwd
{
    template <typename Base, typename T0,typename T1,typename T2, typename Iter,typename End>
    static void forward(Base& base, T0 & geom,T1 & args)
    {
        typedef T0 geometry_type;
        typedef T2 conv_tag;
        typedef typename detail::converter_traits<geometry_type,conv_tag>::conv_type conv_type;
        conv_type conv(geom);
        detail::converter_traits<conv_type,conv_tag>::setup(conv,args);
        base.template dispatch<Iter,End>(conv, typename boost::is_same<Iter,End>::type());
    }
};

template <>
struct converter_fwd<true>
{
    template <typename Base, typename T0,typename T1,typename T2, typename Iter,typename End>
    static void forward(Base& base, T0 & geom,T1 & args)
    {
        base.template dispatch<Iter,End>(geom, typename boost::is_same<Iter,End>::type());
    }
};

template <typename A, typename C>
struct dispatcher
{
    typedef dispatcher this_type;
    typedef A args_type;
    typedef C conv_types;

    dispatcher(args_type args)
        : args_(args)
    {
        std::memset(&vec_[0], 0,  sizeof(unsigned)*vec_.size());
    }

    template <typename Iter, typename End, typename Geometry>
    void dispatch(Geometry & geom, boost::mpl::true_)
    {
        boost::fusion::at_c<1>(args_).add_path(geom);
    }

    template <typename Iter, typename End, typename Geometry>
    void dispatch(Geometry & geom, boost::mpl::false_)
    {
        typedef typename boost::mpl::deref<Iter>::type conv_tag;
        typedef typename detail::converter_traits<Geometry,conv_tag>::conv_type conv_type;
        typedef typename boost::mpl::next<Iter>::type Next;

        std::size_t index = boost::mpl::distance<Iter,End>::value - 1;
        if (vec_[index] == 1)
        {
            converter_fwd<boost::is_same<Geometry,conv_type>::value>::
                template forward<this_type,Geometry,args_type,conv_tag,Next,End>(*this,geom,args_);
        }
        else
        {
            converter_fwd<boost::mpl::true_::value>::
                template forward<this_type,Geometry,args_type,conv_tag,Next,End>(*this,geom,args_);
        }

    }

    template <typename Geometry>
    void apply(Geometry & geom)
    {
        typedef typename boost::mpl::begin<conv_types>::type begin;
        typedef typename boost::mpl::end  <conv_types>::type end;
        dispatch<begin,end,Geometry>(geom, boost::false_type());
    }

    boost::array<unsigned, boost::mpl::size<conv_types>::value> vec_;
    args_type  args_;
};
}

template <typename B, typename R, typename S, typename P, typename T, typename C >
struct vertex_converter : private boost::noncopyable
{
    typedef C conv_types;
    typedef B bbox_type;
    typedef R rasterizer_type;
    typedef S symbolizer_type;
    typedef P proj_trans_type;
    typedef T trans_type;
    typedef typename boost::fusion::vector
    <
    bbox_type const&,
    rasterizer_type&,
    symbolizer_type const&,
    trans_type const&,
    proj_trans_type const&
    > args_type;

    vertex_converter(bbox_type const& b, rasterizer_type & ras,
                     symbolizer_type const& sym, trans_type & tr, proj_trans_type const& prj_trans)
        : disp_(args_type(boost::cref(b),boost::ref(ras),
                          boost::cref(sym),boost::cref(tr),
                          boost::cref(prj_trans))) {}

    template <typename Geometry>
    void apply(Geometry & geom)
    {
        typedef Geometry geometry_type;
        //BOOST_FOREACH(geometry_type & geom, cont)
        {
            disp_.template apply<geometry_type>(geom);
        }
    }

    template <typename Conv>
    void set()
    {
        typedef typename boost::mpl::find<conv_types,Conv>::type iter;
        typedef typename boost::mpl::end<conv_types>::type end;
        std::size_t index = boost::mpl::distance<iter,end>::value - 1;
        if (index < disp_.vec_.size())
            disp_.vec_[index]=1;
    }

    detail::dispatcher<args_type,conv_types> disp_;
};

}

#endif // MAPNIK_VERTEX_CONVERTERS_HPP
<commit_msg>+ fix compilation with i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_VERTEX_CONVERTERS_HPP
#define MAPNIK_VERTEX_CONVERTERS_HPP

// boost
#include <boost/type_traits/is_same.hpp>
// mpl
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/distance.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
// fusion
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/make_vector.hpp>
//#include <boost/fusion/adapted/mpl.hpp>

#include <boost/foreach.hpp>
#include <boost/utility.hpp>
#include <boost/array.hpp>

// mapnik
#include <mapnik/agg_helpers.hpp>

// agg
#include "agg_conv_clip_polygon.h"
#include "agg_conv_clip_polyline.h"
#include "agg_conv_smooth_poly1.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"

namespace mapnik {

struct transform_tag {};
struct clip_line_tag {};
struct clip_poly_tag {};
struct smooth_tag {};
struct stroke_tag {};
struct dash_tag {};

namespace  detail {

template <typename T0, typename T1>
struct converter_traits
{
    typedef T0 geometry_type;
    typedef geometry_type conv_type;
    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        throw "BOOM!";
    }
};

template <typename T>
struct converter_traits<T,mapnik::smooth_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_smooth_poly1_curve<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        geom.smooth_value(boost::fusion::at_c<2>(args).smooth());
    }
};

template <typename T>
struct converter_traits<T, mapnik::clip_line_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_clip_polyline<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<0> >::type box = boost::fusion::at_c<0>(args);
        geom.clip_box(box.minx(),box.miny(),box.maxx(),box.maxy());
    }
};

template <typename T>
struct converter_traits<T, mapnik::dash_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_dash<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args);
        double scale_factor = 1.0; //FIXME
        stroke const& stroke_ = sym.get_stroke();
        dash_array const& d = stroke_.get_dash_array();
        dash_array::const_iterator itr = d.begin();
        dash_array::const_iterator end = d.end();
        for (;itr != end;++itr)
        {
            geom.add_dash(itr->first * scale_factor,
                          itr->second * scale_factor);
        }

    }
};

template <typename T>
struct converter_traits<T, mapnik::stroke_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_stroke<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args);
        stroke const& stroke_ = sym.get_stroke();
        set_join_caps(stroke_,geom);
        geom.generator().miter_limit(4.0); // FIXME : make configurable
        double scale_factor = 1.0; //FIXME
        geom.generator().width(stroke_.get_width() * scale_factor);
    }
};

template <typename T>
struct converter_traits<T,mapnik::clip_poly_tag>
{
    typedef T geometry_type;
    typedef typename agg::conv_clip_polygon<geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<0> >::type box = boost::fusion::at_c<0>(args);
        geom.clip_box(box.minx(),box.miny(),box.maxx(),box.maxy());
    }
};

template <typename T>
struct converter_traits<T,mapnik::transform_tag>
{
    typedef T geometry_type;
    typedef coord_transform2<CoordTransform, geometry_type> conv_type;

    template <typename Args>
    static void setup(geometry_type & geom, Args & args)
    {
        typename boost::mpl::at<Args,boost::mpl::int_<3> >::type tr = boost::fusion::at_c<3>(args);
        typename boost::mpl::at<Args,boost::mpl::int_<4> >::type prj_trans = boost::fusion::at_c<4>(args);
        geom.set_proj_trans(prj_trans);
        geom.set_trans(tr);
    }
};

template <bool>
struct converter_fwd
{
    template <typename Base, typename T0,typename T1,typename T2, typename Iter,typename End>
    static void forward(Base& base, T0 & geom,T1 & args)
    {
        typedef T0 geometry_type;
        typedef T2 conv_tag;
        typedef typename detail::converter_traits<geometry_type,conv_tag>::conv_type conv_type;
        conv_type conv(geom);
        detail::converter_traits<conv_type,conv_tag>::setup(conv,args);
        base.template dispatch<Iter,End>(conv, typename boost::is_same<Iter,End>::type());
    }
};

template <>
struct converter_fwd<true>
{
    template <typename Base, typename T0,typename T1,typename T2, typename Iter,typename End>
    static void forward(Base& base, T0 & geom,T1 & args)
    {
        base.template dispatch<Iter,End>(geom, typename boost::is_same<Iter,End>::type());
    }
};

template <typename A, typename C>
struct dispatcher
{
    typedef dispatcher this_type;
    typedef A args_type;
    typedef C conv_types;

    dispatcher(args_type args)
        : args_(args)
    {
        std::memset(&vec_[0], 0,  sizeof(unsigned)*vec_.size());
    }

    template <typename Iter, typename End, typename Geometry>
    void dispatch(Geometry & geom, boost::mpl::true_)
    {
        boost::fusion::at_c<1>(args_).add_path(geom);
    }

    template <typename Iter, typename End, typename Geometry>
    void dispatch(Geometry & geom, boost::mpl::false_)
    {
        typedef typename boost::mpl::deref<Iter>::type conv_tag;
        typedef typename detail::converter_traits<Geometry,conv_tag>::conv_type conv_type;
        typedef typename boost::mpl::next<Iter>::type Next;

        std::size_t index = boost::mpl::distance<Iter,End>::value - 1;
        if (vec_[index] == 1)
        {
            converter_fwd<boost::is_same<Geometry,conv_type>::value>::
                template forward<this_type,Geometry,args_type,conv_tag,Next,End>(*this,geom,args_);
        }
        else
        {
            converter_fwd<boost::mpl::true_::value>::
                template forward<this_type,Geometry,args_type,conv_tag,Next,End>(*this,geom,args_);
        }

    }

    template <typename Geometry>
    void apply(Geometry & geom)
    {
        typedef typename boost::mpl::begin<conv_types>::type begin;
        typedef typename boost::mpl::end  <conv_types>::type end;
        dispatch<begin,end,Geometry>(geom, boost::false_type());
    }

    boost::array<unsigned, boost::mpl::size<conv_types>::value> vec_;
    args_type  args_;
};
}

template <typename B, typename R, typename S, typename P, typename T, typename C >
struct vertex_converter : private boost::noncopyable
{
    typedef C conv_types;
    typedef B bbox_type;
    typedef R rasterizer_type;
    typedef S symbolizer_type;
    typedef P proj_trans_type;
    typedef T trans_type;
    typedef typename boost::fusion::vector
    <
    bbox_type const&,
    rasterizer_type&,
    symbolizer_type const&,
    trans_type const&,
    proj_trans_type const&
    > args_type;

    vertex_converter(bbox_type const& b, rasterizer_type & ras,
                     symbolizer_type const& sym, trans_type & tr, proj_trans_type const& prj_trans)
        : disp_(args_type(boost::cref(b),boost::ref(ras),
                          boost::cref(sym),boost::cref(tr),
                          boost::cref(prj_trans))) {}

    template <typename Geometry>
    void apply(Geometry & geom)
    {
        typedef Geometry geometry_type;
        //BOOST_FOREACH(geometry_type & geom, cont)
        {
            disp_.template apply<geometry_type>(geom);
        }
    }

    template <typename Conv>
    void set()
    {
        typedef typename boost::mpl::find<conv_types,Conv>::type iter;
        typedef typename boost::mpl::end<conv_types>::type end;
        std::size_t index = boost::mpl::distance<iter,end>::value - 1;
        if (index < disp_.vec_.size())
            disp_.vec_[index]=1;
    }

    detail::dispatcher<args_type,conv_types> disp_;
};

}

#endif // MAPNIK_VERTEX_CONVERTERS_HPP
<|endoftext|>


<commit_before>#pragma once

// MUST be before <algorithm> to keep gcc happy
#include <algorithm>
#include <memory_resource>
#include <string>
#include <vector>

#include <rx/core/optional.h>

namespace rx {
    struct string;
}

namespace nova::renderer {
    /*!
     * \brief Calls the function once for every element in the provided container
     *
     * \param container The container to perform an action for each element in
     * \param thing_to_do The action to perform for each element in the collection
     */
    template <typename Cont, typename Func>
    void foreach(Cont container, Func thing_to_do) {
        std::for_each(std::cbegin(container), std::cend(container), thing_to_do);
    }

    std::pmr::vector<std::string> split(const std::string& s, char delim);

    std::string join(const std::pmr::vector<std::string>& strings, const std::string& joiner);

    std::string print_color(unsigned int color);

    std::string print_array(int* data, int size);

    bool ends_with(const std::string& string, const std::string& ending);

    template<typename Arg>
    uint32_t va_count(const Arg& arg) {
        return 1;
    }

    template<typename Arg, typename... Args>
    uint32_t va_count(const Arg arg, const Args&... args) {
        return 1 + va_count(args);
    }

#define FORMAT(s, ...) fmt::format(fmt(s), __VA_ARGS__)

} // namespace nova::renderer
<commit_msg>Delete bad unused code<commit_after>#pragma once

// MUST be before <algorithm> to keep gcc happy
#include <algorithm>
#include <memory_resource>
#include <string>
#include <vector>

#include <rx/core/optional.h>

namespace rx {
    struct string;
}

namespace nova::renderer {
    /*!
     * \brief Calls the function once for every element in the provided container
     *
     * \param container The container to perform an action for each element in
     * \param thing_to_do The action to perform for each element in the collection
     */
    template <typename Cont, typename Func>
    void foreach(Cont container, Func thing_to_do) {
        std::for_each(std::cbegin(container), std::cend(container), thing_to_do);
    }

    std::pmr::vector<std::string> split(const std::string& s, char delim);

    std::string join(const std::pmr::vector<std::string>& strings, const std::string& joiner);

    std::string print_color(unsigned int color);

    std::string print_array(int* data, int size);

    bool ends_with(const std::string& string, const std::string& ending);

#define FORMAT(s, ...) fmt::format(fmt(s), __VA_ARGS__)

} // namespace nova::renderer
<|endoftext|>


<commit_before><commit_msg>am a9473881: am 2435f98d: Merge "Use the same interrupt/resume logic for all functor calls" into jb-mr1.1-dev<commit_after><|endoftext|>


<commit_before>/**
 * @file   ModelParametersLWR.hpp
 * @brief  ModelParametersLWR class header file.
 * @author Freek Stulp
 *
 * This file is part of DmpBbo, a set of libraries and programs for the
 * black-box optimization of dynamical movement primitives.
 * Copyright (C) 2014 Freek Stulp, ENSTA-ParisTech
 *
 * DmpBbo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * DmpBbo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with DmpBbo.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MODELPARAMETERSLWR_H
#define MODELPARAMETERSLWR_H

#include "functionapproximators/ModelParameters.hpp"

#include <iosfwd>
#include <vector>

#include <eigen3/Eigen/Core>

namespace DmpBbo {

/** \brief Model parameters for the Locally Weighted Regression (LWR) function approximator
 * \ingroup FunctionApproximators
 * \ingroup LWR
 */
class ModelParametersLWR : public ModelParameters
{
  friend class FunctionApproximatorLWR;

public:
  /** Constructor for the model parameters of the LWPR function approximator.
   *  \param[in] centers Centers of the basis functions
   *  \param[in] widths  Widths of the basis functions.
   *  \param[in] slopes  Slopes of the line segments.
   *  \param[in] offsets Offsets of the line segments, i.e. the value of the line segment at its intersection with the y-axis.
   * \param[in] asymmetric_kernels Whether to use asymmetric kernels or not, cf MetaParametersLWR::asymmetric_kernels()
   * \param[in] lines_pivot_at_max_activation Whether line models should pivot at x=0 (false), or at the center of the kernel (x=x_c)
   */
  ModelParametersLWR(const Eigen::MatrixXd& centers, const Eigen::MatrixXd& widths, const Eigen::MatrixXd& slopes, const Eigen::MatrixXd& offsets, bool asymmetric_kernels=false, bool lines_pivot_at_max_activation=false);

  std::string toString(void) const;

	ModelParameters* clone(void) const;

  int getExpectedInputDim(void) const  {
    return centers_.cols();
  };

  /** Get the unnormalized kernel activations for given inputs
   * \param[in] inputs The input data (size: n_samples X n_dims)
   * \param[out] kernel_activations The kernel activations, computed for each of the samples in the input data (size: n_samples X n_basis_functions)
   */
  void unnormalizedKernelActivations(const Eigen::MatrixXd& inputs, Eigen::MatrixXd& kernel_activations) const;

  /** Get the normalized kernel activations for given inputs
   * \param[in] inputs The input data (size: n_samples X n_dims)
   * \param[out] kernel_activations The normalized kernel activations, computed for each of the sampels in the input data (size: n_samples X n_basis_functions)
   */
  void kernelActivations(const Eigen::MatrixXd& inputs, Eigen::MatrixXd& kernel_activations) const;

  /** Get the output of each linear model (unweighted) for the given inputs.
   * \param[in] inputs The inputs for which to compute the output of the lines models (size: n_samples X  n_input_dims)
   * \param[out] lines The output of the linear models (size: n_samples X n_basis_functions)
   */
  void getLines(const Eigen::MatrixXd& inputs, Eigen::MatrixXd& lines) const;

  void setParameterVectorModifierPrivate(std::string modifier, bool new_value);

  /** Set whether the offsets should be adapted so that the line segments pivot around the mode of
   * the basis function, rather than the intersection with the y-axis.
   * \param[in] lines_pivot_at_max_activation Whether to pivot around the mode or not.
   *
   */
  void set_lines_pivot_at_max_activation(bool lines_pivot_at_max_activation);

  /** Whether to return slopes as angles or slopes in ModelParametersLWR::getParameterVectorAll()
   * \param[in] slopes_as_angles Whether to return as slopes (true) or angles (false)
   * \todo Implement and document
   */
  void set_slopes_as_angles(bool slopes_as_angles);

  void getSelectableParameters(std::set<std::string>& selected_values_labels) const;
  void getParameterVectorMask(const std::set<std::string> selected_values_labels, Eigen::VectorXi& selected_mask) const;
  void getParameterVectorAll(Eigen::VectorXd& all_values) const;
  inline int getParameterVectorAllSize(void) const
  {
    return all_values_vector_size_;
  }

  UnifiedModel* toUnifiedModel(void) const;

protected:
  void setParameterVectorAll(const Eigen::VectorXd& values);

private:
  Eigen::MatrixXd centers_; // n_centers X n_dims
  Eigen::MatrixXd widths_;  // n_centers X n_dims
  Eigen::MatrixXd slopes_;  // n_centers X n_dims
  Eigen::VectorXd offsets_; // n_centers X 1

  bool asymmetric_kernels_; // should be const
  bool lines_pivot_at_max_activation_;
  bool slopes_as_angles_;
  int  all_values_vector_size_;

public:
	/** Turn caching for the function normalizedKernelActivations() on or off.
	 * Turning this on should lead to substantial improvements in execution time if the centers and
	 * widths of the kernels do not change often AND you call normalizedKernelActivations with the
	 * same inputs over and over again.
	 * \param[in] caching Whether to turn caching on or off
	 * \remarks In the constructor, caching is set to true, so by default it is on.
	 */
	inline void set_caching(bool caching)
	{
	  caching_ = caching;
	  if (!caching_) clearCache();
	}

private:

  mutable Eigen::MatrixXd inputs_cached_;
  mutable Eigen::MatrixXd kernel_activations_cached_;
  bool caching_;
  inline void clearCache(void)
  {
    inputs_cached_.resize(0,0);
    kernel_activations_cached_.resize(0,0);
  }

  /**
   * Default constructor.
   * \remarks This default constuctor is required for boost::serialization to work. Since this
   * constructor should not be called by other classes, it is private (boost::serialization is a
   * friend)
   */
  ModelParametersLWR(void) {};

  /** Give boost serialization access to private members. */
  friend class boost::serialization::access;

  /** Serialize class data members to boost archive.
   * \param[in] ar Boost archive
   * \param[in] version Version of the class
   * See http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/tutorial.html#simplecase
   */
  template<class Archive>
  void serialize(Archive & ar, const unsigned int version);

};

}

#include <boost/serialization/export.hpp>
/** Register this derived class. */
BOOST_CLASS_EXPORT_KEY2(DmpBbo::ModelParametersLWR, "ModelParametersLWR")

/** Don't add version information to archives. */
BOOST_CLASS_IMPLEMENTATION(DmpBbo::ModelParametersLWR,boost::serialization::object_serializable);

#endif        //  #ifndef MODELPARAMETERSLWR_H

<commit_msg>Added inline function to get number of basis functions<commit_after>/**
 * @file   ModelParametersLWR.hpp
 * @brief  ModelParametersLWR class header file.
 * @author Freek Stulp
 *
 * This file is part of DmpBbo, a set of libraries and programs for the
 * black-box optimization of dynamical movement primitives.
 * Copyright (C) 2014 Freek Stulp, ENSTA-ParisTech
 *
 * DmpBbo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * DmpBbo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with DmpBbo.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MODELPARAMETERSLWR_H
#define MODELPARAMETERSLWR_H

#include "functionapproximators/ModelParameters.hpp"

#include <iosfwd>
#include <vector>

#include <eigen3/Eigen/Core>

namespace DmpBbo {

/** \brief Model parameters for the Locally Weighted Regression (LWR) function approximator
 * \ingroup FunctionApproximators
 * \ingroup LWR
 */
class ModelParametersLWR : public ModelParameters
{
  friend class FunctionApproximatorLWR;

public:
  /** Constructor for the model parameters of the LWPR function approximator.
   *  \param[in] centers Centers of the basis functions
   *  \param[in] widths  Widths of the basis functions.
   *  \param[in] slopes  Slopes of the line segments.
   *  \param[in] offsets Offsets of the line segments, i.e. the value of the line segment at its intersection with the y-axis.
   * \param[in] asymmetric_kernels Whether to use asymmetric kernels or not, cf MetaParametersLWR::asymmetric_kernels()
   * \param[in] lines_pivot_at_max_activation Whether line models should pivot at x=0 (false), or at the center of the kernel (x=x_c)
   */
  ModelParametersLWR(const Eigen::MatrixXd& centers, const Eigen::MatrixXd& widths, const Eigen::MatrixXd& slopes, const Eigen::MatrixXd& offsets, bool asymmetric_kernels=false, bool lines_pivot_at_max_activation=false);

  std::string toString(void) const;

	ModelParameters* clone(void) const;

  int getExpectedInputDim(void) const  {
    return centers_.cols();
  };

  /** Get the unnormalized kernel activations for given inputs
   * \param[in] inputs The input data (size: n_samples X n_dims)
   * \param[out] kernel_activations The kernel activations, computed for each of the samples in the input data (size: n_samples X n_basis_functions)
   */
  void unnormalizedKernelActivations(const Eigen::MatrixXd& inputs, Eigen::MatrixXd& kernel_activations) const;

  /** Get the normalized kernel activations for given inputs
   * \param[in] inputs The input data (size: n_samples X n_dims)
   * \param[out] kernel_activations The normalized kernel activations, computed for each of the sampels in the input data (size: n_samples X n_basis_functions)
   */
  void kernelActivations(const Eigen::MatrixXd& inputs, Eigen::MatrixXd& kernel_activations) const;

  /** Get the output of each linear model (unweighted) for the given inputs.
   * \param[in] inputs The inputs for which to compute the output of the lines models (size: n_samples X  n_input_dims)
   * \param[out] lines The output of the linear models (size: n_samples X n_basis_functions)
   */
  void getLines(const Eigen::MatrixXd& inputs, Eigen::MatrixXd& lines) const;

  void setParameterVectorModifierPrivate(std::string modifier, bool new_value);

  /** Set whether the offsets should be adapted so that the line segments pivot around the mode of
   * the basis function, rather than the intersection with the y-axis.
   * \param[in] lines_pivot_at_max_activation Whether to pivot around the mode or not.
   *
   */
  void set_lines_pivot_at_max_activation(bool lines_pivot_at_max_activation);

  /** Whether to return slopes as angles or slopes in ModelParametersLWR::getParameterVectorAll()
   * \param[in] slopes_as_angles Whether to return as slopes (true) or angles (false)
   * \todo Implement and document
   */
  void set_slopes_as_angles(bool slopes_as_angles);

  void getSelectableParameters(std::set<std::string>& selected_values_labels) const;
  void getParameterVectorMask(const std::set<std::string> selected_values_labels, Eigen::VectorXi& selected_mask) const;
  void getParameterVectorAll(Eigen::VectorXd& all_values) const;
  inline int getParameterVectorAllSize(void) const
  {
    return all_values_vector_size_;
  }
  inline unsigned int getNumberOfBasisFunctions() const
  {
    return centers_.rows();
  }

  UnifiedModel* toUnifiedModel(void) const;

protected:
  void setParameterVectorAll(const Eigen::VectorXd& values);

private:
  Eigen::MatrixXd centers_; // n_centers X n_dims
  Eigen::MatrixXd widths_;  // n_centers X n_dims
  Eigen::MatrixXd slopes_;  // n_centers X n_dims
  Eigen::VectorXd offsets_; // n_centers X 1

  bool asymmetric_kernels_; // should be const
  bool lines_pivot_at_max_activation_;
  bool slopes_as_angles_;
  int  all_values_vector_size_;

public:
	/** Turn caching for the function normalizedKernelActivations() on or off.
	 * Turning this on should lead to substantial improvements in execution time if the centers and
	 * widths of the kernels do not change often AND you call normalizedKernelActivations with the
	 * same inputs over and over again.
	 * \param[in] caching Whether to turn caching on or off
	 * \remarks In the constructor, caching is set to true, so by default it is on.
	 */
	inline void set_caching(bool caching)
	{
	  caching_ = caching;
	  if (!caching_) clearCache();
	}

private:

  mutable Eigen::MatrixXd inputs_cached_;
  mutable Eigen::MatrixXd kernel_activations_cached_;
  bool caching_;
  inline void clearCache(void)
  {
    inputs_cached_.resize(0,0);
    kernel_activations_cached_.resize(0,0);
  }

  /**
   * Default constructor.
   * \remarks This default constuctor is required for boost::serialization to work. Since this
   * constructor should not be called by other classes, it is private (boost::serialization is a
   * friend)
   */
  ModelParametersLWR(void) {};

  /** Give boost serialization access to private members. */
  friend class boost::serialization::access;

  /** Serialize class data members to boost archive.
   * \param[in] ar Boost archive
   * \param[in] version Version of the class
   * See http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/tutorial.html#simplecase
   */
  template<class Archive>
  void serialize(Archive & ar, const unsigned int version);

};

}

#include <boost/serialization/export.hpp>
/** Register this derived class. */
BOOST_CLASS_EXPORT_KEY2(DmpBbo::ModelParametersLWR, "ModelParametersLWR")

/** Don't add version information to archives. */
BOOST_CLASS_IMPLEMENTATION(DmpBbo::ModelParametersLWR,boost::serialization::object_serializable);

#endif        //  #ifndef MODELPARAMETERSLWR_H

<|endoftext|>


<commit_before>#include "drawer.hpp"
#include "proto_to_styles.hpp"
#include "feature_styler.hpp"

#include "../std/bind.hpp"

#include "../indexer/drawing_rules.hpp"
#include "../indexer/scales.hpp"

#include "../graphics/defines.hpp"
#include "../graphics/screen.hpp"
#include "../graphics/resource_manager.hpp"
#include "../graphics/straight_text_element.hpp"

#ifdef OMIM_PRODUCTION
  #include "../indexer/drules_struct_lite.pb.h"
#else
  #include "../indexer/drules_struct.pb.h"
#endif

#include "../indexer/feature.hpp"

#include "../geometry/screenbase.hpp"

#include "../base/logging.hpp"
#include "../base/buffer_vector.hpp"

Drawer::Params::Params()
  : m_visualScale(1)
{
}

Drawer::Drawer(Params const & params)
  : m_visualScale(params.m_visualScale)
{
  m_pScreen.reset(new graphics::Screen(params));

  for (unsigned i = 0; i < m_pScreen->pipelinesCount(); ++i)
    m_pScreen->addClearPageFn(i, bind(&Drawer::ClearResourceCache, ThreadSlot(), i), 0);
}

namespace
{
  struct DoMakeInvalidRule
  {
    size_t m_threadSlot;
    uint32_t m_pipelineIDMask;

    DoMakeInvalidRule(size_t threadSlot, uint8_t pipelineID)
      : m_threadSlot(threadSlot), m_pipelineIDMask(pipelineID << 24)
    {}

    void operator() (int, int, int, drule::BaseRule * p)
    {
      if ((p->GetID(m_threadSlot) & 0xFF000000) == m_pipelineIDMask)
        p->MakeEmptyID(m_threadSlot);
      if ((p->GetID2(m_threadSlot) & 0xFF000000) == m_pipelineIDMask)
        p->MakeEmptyID2(m_threadSlot);
    }
  };
}

void Drawer::ClearResourceCache(size_t threadSlot, uint8_t pipelineID)
{
  drule::rules().ForEachRule(DoMakeInvalidRule(threadSlot, pipelineID));
}

void Drawer::beginFrame()
{
  m_pScreen->beginFrame();
}

void Drawer::endFrame()
{
  m_pScreen->endFrame();
}

void Drawer::clear(graphics::Color const & c, bool clearRT, float depth, bool clearDepth)
{
  m_pScreen->clear(c, clearRT, depth, clearDepth);
}

void Drawer::onSize(int w, int h)
{
  m_pScreen->onSize(w, h);
}

void Drawer::drawSymbol(m2::PointD const & pt,
                        string const & symbolName,
                        graphics::EPosition pos,
                        double depth)
{
  m_pScreen->drawSymbol(pt, symbolName, pos, depth);
}

void Drawer::drawCircle(m2::PointD const & pt,
                        graphics::EPosition pos,
                        di::DrawRule const & rule,
                        di::FeatureInfo::FeatureID const & id)
{
  graphics::Circle::Info ci;
  ConvertStyle(rule.m_rule->GetCircle(), m_visualScale, ci);

  m_pScreen->drawCircle(pt, ci, pos, rule.m_depth);
}

void Drawer::drawSymbol(m2::PointD const & pt,
                        graphics::EPosition pos,
                        di::DrawRule const & rule,
                        di::FeatureInfo::FeatureID const & id)
{
  graphics::Icon::Info info;
  ConvertStyle(rule.m_rule->GetSymbol(), info);

  graphics::SymbolElement::Params params;
  params.m_depth = rule.m_depth;
  params.m_position = pos;
  params.m_pivot = pt;
  params.m_info = info;
  params.m_renderer = m_pScreen.get();
  params.m_userInfo.m_mwmID = id.first;
  params.m_userInfo.m_offset = id.second;

  m_pScreen->drawSymbol(params);
}

void Drawer::drawPath(di::PathInfo const & path, di::DrawRule const * rules, size_t count)
{
  // if any rule needs caching - cache as a whole vector
  bool flag = false;
  for (size_t i = 0; i < count; ++i)
  {
    if (rules[i].GetID(m_pScreen->threadSlot()) == drule::BaseRule::empty_id)
    {
      flag = true;
      break;
    }
  }

  buffer_vector<graphics::Pen::Info, 8> penInfos(count);
  buffer_vector<graphics::Resource::Info const*, 8> infos(count);
  buffer_vector<uint32_t, 8> resIDs(count);

  if (flag)
  {
    // collect graphics::PenInfo into array and pack them as a whole
    for (size_t i = 0; i < count; ++i)
    {
      ConvertStyle(rules[i].m_rule->GetLine(), m_visualScale, penInfos[i]);

      infos[i] = &penInfos[i];

      if (rules[i].m_transparent)
        penInfos[i].m_color.a = 100;

      resIDs[i] = m_pScreen->invalidHandle();
    }

    // map array of pens
    if (m_pScreen->mapInfo(&infos[0], &resIDs[0], count))
    {
      for (size_t i = 0; i < count; ++i)
        rules[i].SetID(ThreadSlot(), resIDs[i]);
    }
    else
    {
      LOG(LERROR, ("couldn't successfully pack a sequence of path styles as a whole"));
      buffer_vector<m2::PointU, 8> rects;
      for (unsigned i = 0; i < count; ++i)
        rects.push_back(infos[i]->resourceSize());
      LOG(LERROR, (rects));

      return;
    }
  }

  // draw path with array of rules
  for (size_t i = 0; i < count; ++i)
    m_pScreen->drawPath(&path.m_path[0],
                        path.m_path.size(),
                        -path.GetOffset(),
                        rules[i].GetID(ThreadSlot()),
                        rules[i].m_depth);
}

void Drawer::drawArea(di::AreaInfo const & area, di::DrawRule const & rule)
{
  // DO NOT cache 'id' in pRule, because one rule can use in drawPath and drawArea.
  // Leave CBaseRule::m_id for drawPath. mapColor working fast enough.

  graphics::Brush::Info info;
  ConvertStyle(rule.m_rule->GetArea(), info);

  uint32_t const id = m_pScreen->mapInfo(info);
  ASSERT ( id != -1, () );

  m_pScreen->drawTrianglesList(&area.m_path[0], area.m_path.size(), id, rule.m_depth);
}

void Drawer::drawText(m2::PointD const & pt,
                      graphics::EPosition pos,
                      di::FeatureStyler const & fs,
                      di::DrawRule const & rule,
                      di::FeatureInfo::FeatureID const & id)
{
  graphics::FontDesc primaryFont;
  m2::PointD primaryOffset;
  ConvertStyle(rule.m_rule->GetCaption(0), m_visualScale, primaryFont, primaryOffset);
  primaryFont.SetRank(fs.m_popRank);

  graphics::FontDesc secondaryFont;
  m2::PointD secondaryOffset;
  if (rule.m_rule->GetCaption(1))
  {
    ConvertStyle(rule.m_rule->GetCaption(1), m_visualScale, secondaryFont, secondaryOffset);
    secondaryFont.SetRank(fs.m_popRank);
  }

  graphics::StraightTextElement::Params params;
  params.m_depth = rule.m_depth;
  params.m_fontDesc = primaryFont;
  params.m_auxFontDesc = secondaryFont;
  params.m_offset = primaryOffset;
  params.m_log2vis = true;
  params.m_pivot = pt;
  params.m_position = pos;
  params.m_logText = strings::MakeUniString(fs.m_primaryText);
  params.m_auxLogText = strings::MakeUniString(fs.m_secondaryText);
  params.m_doSplit = true;
  params.m_useAllParts = false;
  params.m_userInfo.m_mwmID = id.first;
  params.m_userInfo.m_offset = id.second;

  m_pScreen->drawTextEx(params);
}

void Drawer::drawPathText(di::PathInfo const & path,
                          di::FeatureStyler const & fs,
                          di::DrawRule const & rule)
{
  graphics::FontDesc font;
  m2::PointD offset;
  ConvertStyle(rule.m_rule->GetCaption(0), m_visualScale, font, offset);

  if (fs.m_offsets.empty())
    return;

  m_pScreen->drawPathText(font,
                          &path.m_path[0],
                          path.m_path.size(),
                          fs.GetPathName(),
                          path.GetFullLength(),
                          path.GetOffset(),
                          &fs.m_offsets[0],
                          fs.m_offsets.size(),
                          rule.m_depth);
}

void Drawer::drawPathNumber(di::PathInfo const & path,
                            di::FeatureStyler const & fs)
{
  int const textHeight = static_cast<int>(12 * m_visualScale);
  m2::PointD pt;
  double const length = path.GetFullLength();
  if (length >= (fs.m_refText.size() + 2) * textHeight)
  {
    size_t const count = size_t(length / 1000.0) + 2;

    for (size_t j = 1; j < count; ++j)
    {
      if (path.GetSmPoint(double(j) / double(count), pt))
      {
        graphics::FontDesc fontDesc(
          textHeight,
          graphics::Color(150, 75, 0, 255),   // brown
          true,
          graphics::Color(255, 255, 255, 255));

        m_pScreen->drawText(fontDesc,
                            pt,
                            graphics::EPosCenter,
                            fs.m_refText,
                            graphics::maxDepth - 10,
                            true);
      }
    }
  }
}

graphics::Screen * Drawer::screen() const
{
  return m_pScreen.get();
}

double Drawer::VisualScale() const
{
  return m_visualScale;
}

void Drawer::SetScale(int level)
{
  m_level = level;
}

void Drawer::Draw(di::FeatureInfo const & fi)
{
  di::FeatureInfo::FeatureID const & id = fi.m_id;
  buffer_vector<di::DrawRule, 8> const & rules = fi.m_styler.m_rules;
  buffer_vector<di::DrawRule, 8> pathRules;

  bool const isPath = !fi.m_pathes.empty();
  bool const isArea = !fi.m_areas.empty();

  // separating path rules from other
  for (size_t i = 0; i < rules.size(); ++i)
  {
    drule::BaseRule const * pRule = rules[i].m_rule;

    bool const hasSymbol = pRule->GetSymbol() != 0;
    bool const isCaption = pRule->GetCaption(0) != 0;

    if (!isCaption && isPath && !hasSymbol && (pRule->GetLine() != 0))
      pathRules.push_back(rules[i]);
  }

  if (!pathRules.empty())
  {
    for (list<di::PathInfo>::const_iterator i = fi.m_pathes.begin(); i != fi.m_pathes.end(); ++i)
      drawPath(*i, pathRules.data(), pathRules.size());
  }

  for (size_t i = 0; i < rules.size(); ++i)
  {
    drule::BaseRule const * pRule = rules[i].m_rule;
    double const depth = rules[i].m_depth;

    bool const isCaption = pRule->GetCaption(0) != 0;
    bool const hasSymbol = pRule->GetSymbol() != 0;
    bool const isCircle = pRule->GetCircle() != 0;

    if (!isCaption)
    {
      // draw area
      if (isArea)
      {
        bool const isFill = pRule->GetArea() != 0;
        bool const hasSym = hasSymbol && ((pRule->GetType() & drule::way) != 0);

        for (list<di::AreaInfo>::const_iterator i = fi.m_areas.begin(); i != fi.m_areas.end(); ++i)
        {
          if (isFill)
            drawArea(*i, di::DrawRule(pRule, depth, false));
          else if (hasSym)
            drawSymbol(i->GetCenter(), graphics::EPosCenter, di::DrawRule(pRule, depth, false), id);
        }
      }

      // draw point symbol
      if (!isPath && !isArea && ((pRule->GetType() & drule::node) != 0))
      {
        if (hasSymbol)
          drawSymbol(fi.m_point, graphics::EPosCenter, di::DrawRule(pRule, depth, false), id);
        else if (isCircle)
          drawCircle(fi.m_point, graphics::EPosCenter, di::DrawRule(pRule, depth, false), id);
      }
    }
    else
    {
      if (!fi.m_styler.m_primaryText.empty() && (pRule->GetCaption(0) != 0))
      {
        bool isN = ((pRule->GetType() & drule::way) != 0);

        graphics::EPosition textPosition = graphics::EPosCenter;
        if (pRule->GetCaption(0)->has_offset_y())
        {
          if (pRule->GetCaption(0)->offset_y() > 0)
            textPosition = graphics::EPosUnder;
          else
            textPosition = graphics::EPosAbove;
        }
        if (pRule->GetCaption(0)->has_offset_x())
        {
          if (pRule->GetCaption(0)->offset_x() > 0)
            textPosition = graphics::EPosRight;
          else
            textPosition = graphics::EPosLeft;
        }

        // draw area text
        if (isArea/* && isN*/)
        {
          for (list<di::AreaInfo>::const_iterator i = fi.m_areas.begin(); i != fi.m_areas.end(); ++i)
            drawText(i->GetCenter(), textPosition, fi.m_styler, di::DrawRule(pRule, depth, false), id);
        }

        // draw way name
        if (isPath && !isArea && isN && !fi.m_styler.FilterTextSize(pRule))
        {
          for (list<di::PathInfo>::const_iterator i = fi.m_pathes.begin(); i != fi.m_pathes.end(); ++i)
            drawPathText(*i, fi.m_styler, di::DrawRule(pRule, depth, false));
        }

        // draw point text
        isN = ((pRule->GetType() & drule::node) != 0);
        if (!isPath && !isArea && isN)
          drawText(fi.m_point, textPosition, fi.m_styler, di::DrawRule(pRule, depth, false), id);
      }
    }
  }

  // draw road numbers
  if (isPath && !fi.m_styler.m_refText.empty() && m_level >= 12)
  {
    for (list<di::PathInfo>::const_iterator i = fi.m_pathes.begin(); i != fi.m_pathes.end(); ++i)
      drawPathNumber(*i, fi.m_styler);
  }
}

int Drawer::ThreadSlot() const
{
  return m_pScreen->threadSlot();
}
<commit_msg>[map] change priority for road refs<commit_after>#include "drawer.hpp"
#include "proto_to_styles.hpp"
#include "feature_styler.hpp"

#include "../std/bind.hpp"

#include "../indexer/drawing_rules.hpp"
#include "../indexer/scales.hpp"

#include "../graphics/defines.hpp"
#include "../graphics/screen.hpp"
#include "../graphics/resource_manager.hpp"
#include "../graphics/straight_text_element.hpp"

#ifdef OMIM_PRODUCTION
  #include "../indexer/drules_struct_lite.pb.h"
#else
  #include "../indexer/drules_struct.pb.h"
#endif

#include "../indexer/feature.hpp"

#include "../geometry/screenbase.hpp"

#include "../base/logging.hpp"
#include "../base/buffer_vector.hpp"

Drawer::Params::Params()
  : m_visualScale(1)
{
}

Drawer::Drawer(Params const & params)
  : m_visualScale(params.m_visualScale)
{
  m_pScreen.reset(new graphics::Screen(params));

  for (unsigned i = 0; i < m_pScreen->pipelinesCount(); ++i)
    m_pScreen->addClearPageFn(i, bind(&Drawer::ClearResourceCache, ThreadSlot(), i), 0);
}

namespace
{
  struct DoMakeInvalidRule
  {
    size_t m_threadSlot;
    uint32_t m_pipelineIDMask;

    DoMakeInvalidRule(size_t threadSlot, uint8_t pipelineID)
      : m_threadSlot(threadSlot), m_pipelineIDMask(pipelineID << 24)
    {}

    void operator() (int, int, int, drule::BaseRule * p)
    {
      if ((p->GetID(m_threadSlot) & 0xFF000000) == m_pipelineIDMask)
        p->MakeEmptyID(m_threadSlot);
      if ((p->GetID2(m_threadSlot) & 0xFF000000) == m_pipelineIDMask)
        p->MakeEmptyID2(m_threadSlot);
    }
  };
}

void Drawer::ClearResourceCache(size_t threadSlot, uint8_t pipelineID)
{
  drule::rules().ForEachRule(DoMakeInvalidRule(threadSlot, pipelineID));
}

void Drawer::beginFrame()
{
  m_pScreen->beginFrame();
}

void Drawer::endFrame()
{
  m_pScreen->endFrame();
}

void Drawer::clear(graphics::Color const & c, bool clearRT, float depth, bool clearDepth)
{
  m_pScreen->clear(c, clearRT, depth, clearDepth);
}

void Drawer::onSize(int w, int h)
{
  m_pScreen->onSize(w, h);
}

void Drawer::drawSymbol(m2::PointD const & pt,
                        string const & symbolName,
                        graphics::EPosition pos,
                        double depth)
{
  m_pScreen->drawSymbol(pt, symbolName, pos, depth);
}

void Drawer::drawCircle(m2::PointD const & pt,
                        graphics::EPosition pos,
                        di::DrawRule const & rule,
                        di::FeatureInfo::FeatureID const & id)
{
  graphics::Circle::Info ci;
  ConvertStyle(rule.m_rule->GetCircle(), m_visualScale, ci);

  m_pScreen->drawCircle(pt, ci, pos, rule.m_depth);
}

void Drawer::drawSymbol(m2::PointD const & pt,
                        graphics::EPosition pos,
                        di::DrawRule const & rule,
                        di::FeatureInfo::FeatureID const & id)
{
  graphics::Icon::Info info;
  ConvertStyle(rule.m_rule->GetSymbol(), info);

  graphics::SymbolElement::Params params;
  params.m_depth = rule.m_depth;
  params.m_position = pos;
  params.m_pivot = pt;
  params.m_info = info;
  params.m_renderer = m_pScreen.get();
  params.m_userInfo.m_mwmID = id.first;
  params.m_userInfo.m_offset = id.second;

  m_pScreen->drawSymbol(params);
}

void Drawer::drawPath(di::PathInfo const & path, di::DrawRule const * rules, size_t count)
{
  // if any rule needs caching - cache as a whole vector
  bool flag = false;
  for (size_t i = 0; i < count; ++i)
  {
    if (rules[i].GetID(m_pScreen->threadSlot()) == drule::BaseRule::empty_id)
    {
      flag = true;
      break;
    }
  }

  buffer_vector<graphics::Pen::Info, 8> penInfos(count);
  buffer_vector<graphics::Resource::Info const*, 8> infos(count);
  buffer_vector<uint32_t, 8> resIDs(count);

  if (flag)
  {
    // collect graphics::PenInfo into array and pack them as a whole
    for (size_t i = 0; i < count; ++i)
    {
      ConvertStyle(rules[i].m_rule->GetLine(), m_visualScale, penInfos[i]);

      infos[i] = &penInfos[i];

      if (rules[i].m_transparent)
        penInfos[i].m_color.a = 100;

      resIDs[i] = m_pScreen->invalidHandle();
    }

    // map array of pens
    if (m_pScreen->mapInfo(&infos[0], &resIDs[0], count))
    {
      for (size_t i = 0; i < count; ++i)
        rules[i].SetID(ThreadSlot(), resIDs[i]);
    }
    else
    {
      LOG(LERROR, ("couldn't successfully pack a sequence of path styles as a whole"));
      buffer_vector<m2::PointU, 8> rects;
      for (unsigned i = 0; i < count; ++i)
        rects.push_back(infos[i]->resourceSize());
      LOG(LERROR, (rects));

      return;
    }
  }

  // draw path with array of rules
  for (size_t i = 0; i < count; ++i)
    m_pScreen->drawPath(&path.m_path[0],
                        path.m_path.size(),
                        -path.GetOffset(),
                        rules[i].GetID(ThreadSlot()),
                        rules[i].m_depth);
}

void Drawer::drawArea(di::AreaInfo const & area, di::DrawRule const & rule)
{
  // DO NOT cache 'id' in pRule, because one rule can use in drawPath and drawArea.
  // Leave CBaseRule::m_id for drawPath. mapColor working fast enough.

  graphics::Brush::Info info;
  ConvertStyle(rule.m_rule->GetArea(), info);

  uint32_t const id = m_pScreen->mapInfo(info);
  ASSERT ( id != -1, () );

  m_pScreen->drawTrianglesList(&area.m_path[0], area.m_path.size(), id, rule.m_depth);
}

void Drawer::drawText(m2::PointD const & pt,
                      graphics::EPosition pos,
                      di::FeatureStyler const & fs,
                      di::DrawRule const & rule,
                      di::FeatureInfo::FeatureID const & id)
{
  graphics::FontDesc primaryFont;
  m2::PointD primaryOffset;
  ConvertStyle(rule.m_rule->GetCaption(0), m_visualScale, primaryFont, primaryOffset);
  primaryFont.SetRank(fs.m_popRank);

  graphics::FontDesc secondaryFont;
  m2::PointD secondaryOffset;
  if (rule.m_rule->GetCaption(1))
  {
    ConvertStyle(rule.m_rule->GetCaption(1), m_visualScale, secondaryFont, secondaryOffset);
    secondaryFont.SetRank(fs.m_popRank);
  }

  graphics::StraightTextElement::Params params;
  params.m_depth = rule.m_depth;
  params.m_fontDesc = primaryFont;
  params.m_auxFontDesc = secondaryFont;
  params.m_offset = primaryOffset;
  params.m_log2vis = true;
  params.m_pivot = pt;
  params.m_position = pos;
  params.m_logText = strings::MakeUniString(fs.m_primaryText);
  params.m_auxLogText = strings::MakeUniString(fs.m_secondaryText);
  params.m_doSplit = true;
  params.m_useAllParts = false;
  params.m_userInfo.m_mwmID = id.first;
  params.m_userInfo.m_offset = id.second;

  m_pScreen->drawTextEx(params);
}

void Drawer::drawPathText(di::PathInfo const & path,
                          di::FeatureStyler const & fs,
                          di::DrawRule const & rule)
{
  graphics::FontDesc font;
  m2::PointD offset;
  ConvertStyle(rule.m_rule->GetCaption(0), m_visualScale, font, offset);

  if (fs.m_offsets.empty())
    return;

  m_pScreen->drawPathText(font,
                          &path.m_path[0],
                          path.m_path.size(),
                          fs.GetPathName(),
                          path.GetFullLength(),
                          path.GetOffset(),
                          &fs.m_offsets[0],
                          fs.m_offsets.size(),
                          rule.m_depth);
}

void Drawer::drawPathNumber(di::PathInfo const & path,
                            di::FeatureStyler const & fs)
{
  int const textHeight = static_cast<int>(11 * m_visualScale);
  m2::PointD pt;
  double const length = path.GetFullLength();
  if (length >= (fs.m_refText.size() + 2) * textHeight)
  {
    size_t const count = size_t(length / 1000.0) + 2;

    for (size_t j = 1; j < count; ++j)
    {
      if (path.GetSmPoint(double(j) / double(count), pt))
      {
        graphics::FontDesc fontDesc(
          textHeight,
          graphics::Color(150, 75, 0, 255),   // brown
          true,
          graphics::Color(255, 255, 255, 255));

        m_pScreen->drawText(fontDesc,
                            pt,
                            graphics::EPosCenter,
                            fs.m_refText,
                            0,
                            true);
      }
    }
  }
}

graphics::Screen * Drawer::screen() const
{
  return m_pScreen.get();
}

double Drawer::VisualScale() const
{
  return m_visualScale;
}

void Drawer::SetScale(int level)
{
  m_level = level;
}

void Drawer::Draw(di::FeatureInfo const & fi)
{
  di::FeatureInfo::FeatureID const & id = fi.m_id;
  buffer_vector<di::DrawRule, 8> const & rules = fi.m_styler.m_rules;
  buffer_vector<di::DrawRule, 8> pathRules;

  bool const isPath = !fi.m_pathes.empty();
  bool const isArea = !fi.m_areas.empty();

  // separating path rules from other
  for (size_t i = 0; i < rules.size(); ++i)
  {
    drule::BaseRule const * pRule = rules[i].m_rule;

    bool const hasSymbol = pRule->GetSymbol() != 0;
    bool const isCaption = pRule->GetCaption(0) != 0;

    if (!isCaption && isPath && !hasSymbol && (pRule->GetLine() != 0))
      pathRules.push_back(rules[i]);
  }

  if (!pathRules.empty())
  {
    for (list<di::PathInfo>::const_iterator i = fi.m_pathes.begin(); i != fi.m_pathes.end(); ++i)
      drawPath(*i, pathRules.data(), pathRules.size());
  }

  for (size_t i = 0; i < rules.size(); ++i)
  {
    drule::BaseRule const * pRule = rules[i].m_rule;
    double const depth = rules[i].m_depth;

    bool const isCaption = pRule->GetCaption(0) != 0;
    bool const hasSymbol = pRule->GetSymbol() != 0;
    bool const isCircle = pRule->GetCircle() != 0;

    if (!isCaption)
    {
      // draw area
      if (isArea)
      {
        bool const isFill = pRule->GetArea() != 0;
        bool const hasSym = hasSymbol && ((pRule->GetType() & drule::way) != 0);

        for (list<di::AreaInfo>::const_iterator i = fi.m_areas.begin(); i != fi.m_areas.end(); ++i)
        {
          if (isFill)
            drawArea(*i, di::DrawRule(pRule, depth, false));
          else if (hasSym)
            drawSymbol(i->GetCenter(), graphics::EPosCenter, di::DrawRule(pRule, depth, false), id);
        }
      }

      // draw point symbol
      if (!isPath && !isArea && ((pRule->GetType() & drule::node) != 0))
      {
        if (hasSymbol)
          drawSymbol(fi.m_point, graphics::EPosCenter, di::DrawRule(pRule, depth, false), id);
        else if (isCircle)
          drawCircle(fi.m_point, graphics::EPosCenter, di::DrawRule(pRule, depth, false), id);
      }
    }
    else
    {
      if (!fi.m_styler.m_primaryText.empty() && (pRule->GetCaption(0) != 0))
      {
        bool isN = ((pRule->GetType() & drule::way) != 0);

        graphics::EPosition textPosition = graphics::EPosCenter;
        if (pRule->GetCaption(0)->has_offset_y())
        {
          if (pRule->GetCaption(0)->offset_y() > 0)
            textPosition = graphics::EPosUnder;
          else
            textPosition = graphics::EPosAbove;
        }
        if (pRule->GetCaption(0)->has_offset_x())
        {
          if (pRule->GetCaption(0)->offset_x() > 0)
            textPosition = graphics::EPosRight;
          else
            textPosition = graphics::EPosLeft;
        }

        // draw area text
        if (isArea/* && isN*/)
        {
          for (list<di::AreaInfo>::const_iterator i = fi.m_areas.begin(); i != fi.m_areas.end(); ++i)
            drawText(i->GetCenter(), textPosition, fi.m_styler, di::DrawRule(pRule, depth, false), id);
        }

        // draw way name
        if (isPath && !isArea && isN && !fi.m_styler.FilterTextSize(pRule))
        {
          for (list<di::PathInfo>::const_iterator i = fi.m_pathes.begin(); i != fi.m_pathes.end(); ++i)
            drawPathText(*i, fi.m_styler, di::DrawRule(pRule, depth, false));
        }

        // draw point text
        isN = ((pRule->GetType() & drule::node) != 0);
        if (!isPath && !isArea && isN)
          drawText(fi.m_point, textPosition, fi.m_styler, di::DrawRule(pRule, depth, false), id);
      }
    }
  }

  // draw road numbers
  if (isPath && !fi.m_styler.m_refText.empty() && m_level >= 12)
  {
    for (list<di::PathInfo>::const_iterator i = fi.m_pathes.begin(); i != fi.m_pathes.end(); ++i)
      drawPathNumber(*i, fi.m_styler);
  }
}

int Drawer::ThreadSlot() const
{
  return m_pScreen->threadSlot();
}
<|endoftext|>


<commit_before>#ifndef UTIL_HPP__
#define UTIL_HPP__

#include <iostream>
#include <iomanip>
#include <sstream>
#include <typeinfo>
#include <stdint.h>

#ifndef MAX_ARRAY_DIMENSION
#define MAX_ARRAY_DIMENSION 6
#endif

/*----------------------------------------------------------------------------*/

#define ERROR(INFO) {							\
    std::string file( __FILE__ );						\
    std::string func( __func__ );						\
    std::cerr << " - DEBUG ";						\
    std::cerr << left  << std::setw(30) << file.substr(0,30)			\
	 << ":" << std::setw(15) << func.substr(0,15) << ":";		\
    std::cerr << std::setw(5) << right << __LINE__ << ":";			\
    std::cerr << right << std::setw(5)  << mesgCount++  << " X";		\
    std::cerr << right << std::setw(3)  << std::setfill('0')			\
	 << -99 << std::setfill(' ');					\
    std::cerr << " | " << INFO << "\n" << flush;				\
    exit(-1);								\
  }

/*----------------------------------------------------------------------------*/

enum identify_data_type {
  identify_unknown_t = 0,
  identify_byte_t    = 100,
  identify_char_t    = 300,
  identify_string_t  = 333,
  identify_short_t   = 400,
  identify_int_t     = 500,
  identify_long_t    = 600,
  identify_float_t   = 700,
  identify_double_t  = 800,
};

static std::string dataType2String(const identify_data_type& dataType)
{
  switch(dataType){
  case identify_unknown_t:
    return "unknown";
  case identify_byte_t:
    return "byte";
  case identify_char_t:
    return "char";
  case identify_string_t:
    return "string";
  case identify_short_t:
    return "short";
  case identify_int_t:
    return "int";
  case identify_long_t:
    return "long";
  case identify_float_t:
    return "float";
  case identify_double_t:
    return "double";
  default:
    std::stringstream ss;
    ss << "uknown data type code = << " << dataType
       << ".  Did not even match identify_unknown_t!";
    return ss.str();
  }
}

template<class T> identify_data_type identify(const T& v) {
  const std::type_info& v_type = typeid(T);

  if      ( v_type == typeid(unsigned char) ) { return identify_byte_t;   }
  else if ( v_type == typeid(signed char) )   { return identify_char_t;   }
  else if ( v_type == typeid(char*) )         { return identify_string_t; }
  else if ( v_type == typeid(const char*) )   { return identify_string_t; }
  else if ( v_type == typeid(char[]) )        { return identify_string_t; }
  else if ( v_type == typeid(std::string) )        { return identify_string_t; }
  else if ( v_type == typeid(const std::string) )  { return identify_string_t; }

  else if ( v_type == typeid(int16_t)     )   { return identify_short_t;  }
  else if ( v_type == typeid(int32_t)     )   { return identify_int_t;    }
  else if ( v_type == typeid(int64_t)     )   { return identify_long_t;   }

  else if ( v_type == typeid(float)       )   { return identify_float_t;  }
  else if ( v_type == typeid(double)      )   { return identify_double_t; }

  else {
    std::cerr << "Unknown type for identify" << std::endl;
    return identify_unknown_t;
  }
}

static int identifySize(const identify_data_type& t) {
  switch(t) {
  case identify_byte_t:   return 1;
  case identify_char_t:   return 1;
  case identify_short_t:  return 2;
  case identify_int_t:    return 4;
  case identify_long_t:   return 8;
  case identify_float_t:  return 4;
  case identify_double_t: return 8;
  default:
    return 0;
  }
}

/*----------------------------------------------------------------------------*/

struct array_info_t {
  int nDims, nVars, nAttr, bytes,
    globalDims[MAX_ARRAY_DIMENSION],
    localDims[MAX_ARRAY_DIMENSION],
    offset[MAX_ARRAY_DIMENSION],
    base[MAX_ARRAY_DIMENSION];
  identify_data_type dataType;
};

static void printArrayInfo( array_info_t& info ) {
  std::cout << "   Dims: "  << info.nDims
	    << "   nVars: " << info.nVars
	    << "   nAttr: " << info.nAttr
	    << "   bytes: " << info.bytes
	    << "   type: "  << info.dataType
	    << " (" << dataType2String(info.dataType) << ")"
	    << std::endl;

  for (int i=0; i<info.nDims; i++) {
    std::cout << i << ")  "
	      << info.globalDims[i] << " : "
	      << info.localDims[i] << " : "
	      << info.offset[i] << " : "
	      << info.base[i] << std::endl;
  }
}

/*----------------------------------------------------------------------------*/

template <class T>
inline std::string toString (const T& t, const int width=0, const char fill=' ', const int precision=5 ) {
  std::stringstream ss;
  ss << std::scientific << std::setw(width) << std::setfill(fill) << std::setprecision(precision) << t;
  return ss.str();
}

/*----------------------------------------------------------------------------*/

template <class T>
inline std::string toStringSci (const T& t) {
  return toString(t,16,' ',7);
}

/*----------------------------------------------------------------------------*/

#ifdef BUILD_WITH_APP
template<class PppArray> void displayInfo( const PppArray& data ){
  std::cout << "nDims:"
	    << data.numberOfDimensions() << "\n"
	    << data.getLocalArray().numberOfDimensions() << "\n";
  std::cout << "LocalBase:"
	    << data.getLocalBase(0) << ","
	    << data.getLocalBase(1) << ","
	    << data.getLocalBase(2) << ","
	    << data.getLocalBase(3) << "\n";
  std::cout << "LocalStride:"
	    << data.getLocalStride(0) << ","
	    << data.getLocalStride(1) << ","
	    << data.getLocalStride(2) << ","
	    << data.getLocalStride(3) << "\n";
  std::cout << "LocalBound:"
	    << data.getLocalBound(0) << ","
	    << data.getLocalBound(1) << ","
	    << data.getLocalBound(2) << ","
	    << data.getLocalBound(3) << "\n";
  std::cout << "LocalLength:"
	    << data.getLocalLength(0) << ","
	    << data.getLocalLength(1) << ","
	    << data.getLocalLength(2) << ","
	    << data.getLocalLength(3) << "\n";
  std::cout << "LocalRawBase:"
	    << data.getLocalRawBase(0) << ","
	    << data.getLocalRawBase(1) << ","
	    << data.getLocalRawBase(2) << ","
	    << data.getLocalRawBase(3) << "\n";
  std::cout << "LocalRawStride:"
	    << data.getLocalRawStride(0) << ","
	    << data.getLocalRawStride(1) << ","
	    << data.getLocalRawStride(2) << ","
	    << data.getLocalRawStride(3) << "\n";
  std::cout << "LocalRawBound:"
	    << data.getLocalRawBound(0) << ","
	    << data.getLocalRawBound(1) << ","
	    << data.getLocalRawBound(2) << ","
	    << data.getLocalRawBound(3) << "\n";
  std::cout << "GhostCells:"
	    << data.getGhostBoundaryWidth(0) << ","
	    << data.getGhostBoundaryWidth(1) << ","
	    << data.getGhostBoundaryWidth(2) << ","
	    << data.getGhostBoundaryWidth(3) << "\n";
  std::cout << "InternalGhost:"
	    << data.getInternalGhostCellWidth(0) << ","
	    << data.getInternalGhostCellWidth(1) << ","
	    << data.getInternalGhostCellWidth(2) << ","
	    << data.getInternalGhostCellWidth(3) << "\n";
  std::cout << std::endl;
  std::cout.flush();
}
#endif//BUILD_WITH_APP

/*----------------------------------------------------------------------------*/

#endif //UTIL_HPP__
<commit_msg>Bug fix for error at compile: "error: invalid use of array with unspecified bounds".<commit_after>#ifndef UTIL_HPP__
#define UTIL_HPP__

#include <iostream>
#include <iomanip>
#include <sstream>
#include <typeinfo>
#include <stdint.h>

#ifndef MAX_ARRAY_DIMENSION
#define MAX_ARRAY_DIMENSION 6
#endif

/*----------------------------------------------------------------------------*/

#define ERROR(INFO) {							\
    std::string file( __FILE__ );						\
    std::string func( __func__ );						\
    std::cerr << " - DEBUG ";						\
    std::cerr << left  << std::setw(30) << file.substr(0,30)			\
	 << ":" << std::setw(15) << func.substr(0,15) << ":";		\
    std::cerr << std::setw(5) << right << __LINE__ << ":";			\
    std::cerr << right << std::setw(5)  << mesgCount++  << " X";		\
    std::cerr << right << std::setw(3)  << std::setfill('0')			\
	 << -99 << std::setfill(' ');					\
    std::cerr << " | " << INFO << "\n" << flush;				\
    exit(-1);								\
  }

/*----------------------------------------------------------------------------*/

enum identify_data_type {
  identify_unknown_t = 0,
  identify_byte_t    = 100,
  identify_char_t    = 300,
  identify_string_t  = 333,
  identify_short_t   = 400,
  identify_int_t     = 500,
  identify_long_t    = 600,
  identify_float_t   = 700,
  identify_double_t  = 800,
};

static std::string dataType2String(const identify_data_type& dataType)
{
  switch(dataType){
  case identify_unknown_t:
    return "unknown";
  case identify_byte_t:
    return "byte";
  case identify_char_t:
    return "char";
  case identify_string_t:
    return "string";
  case identify_short_t:
    return "short";
  case identify_int_t:
    return "int";
  case identify_long_t:
    return "long";
  case identify_float_t:
    return "float";
  case identify_double_t:
    return "double";
  default:
    std::stringstream ss;
    ss << "uknown data type code = << " << dataType
       << ".  Did not even match identify_unknown_t!";
    return ss.str();
  }
}

template<class T> identify_data_type identify(const T& v) {
  const std::type_info& v_type = typeid(T);

  if      ( v_type == typeid(unsigned char) ) { return identify_byte_t;   }
  else if ( v_type == typeid(signed char) )   { return identify_char_t;   }
  else if ( v_type == typeid(char*) )         { return identify_string_t; }
  else if ( v_type == typeid(const char*) )   { return identify_string_t; }
  else if ( v_type == typeid(char) )        { return identify_string_t; }
  else if ( v_type == typeid(std::string) )        { return identify_string_t; }
  else if ( v_type == typeid(const std::string) )  { return identify_string_t; }

  else if ( v_type == typeid(int16_t)     )   { return identify_short_t;  }
  else if ( v_type == typeid(int32_t)     )   { return identify_int_t;    }
  else if ( v_type == typeid(int64_t)     )   { return identify_long_t;   }

  else if ( v_type == typeid(float)       )   { return identify_float_t;  }
  else if ( v_type == typeid(double)      )   { return identify_double_t; }

  else {
    std::cerr << "Unknown type for identify" << std::endl;
    return identify_unknown_t;
  }
}

static int identifySize(const identify_data_type& t) {
  switch(t) {
  case identify_byte_t:   return 1;
  case identify_char_t:   return 1;
  case identify_short_t:  return 2;
  case identify_int_t:    return 4;
  case identify_long_t:   return 8;
  case identify_float_t:  return 4;
  case identify_double_t: return 8;
  default:
    return 0;
  }
}

/*----------------------------------------------------------------------------*/

struct array_info_t {
  int nDims, nVars, nAttr, bytes,
    globalDims[MAX_ARRAY_DIMENSION],
    localDims[MAX_ARRAY_DIMENSION],
    offset[MAX_ARRAY_DIMENSION],
    base[MAX_ARRAY_DIMENSION];
  identify_data_type dataType;
};

static void printArrayInfo( array_info_t& info ) {
  std::cout << "   Dims: "  << info.nDims
	    << "   nVars: " << info.nVars
	    << "   nAttr: " << info.nAttr
	    << "   bytes: " << info.bytes
	    << "   type: "  << info.dataType
	    << " (" << dataType2String(info.dataType) << ")"
	    << std::endl;

  for (int i=0; i<info.nDims; i++) {
    std::cout << i << ")  "
	      << info.globalDims[i] << " : "
	      << info.localDims[i] << " : "
	      << info.offset[i] << " : "
	      << info.base[i] << std::endl;
  }
}

/*----------------------------------------------------------------------------*/

template <class T>
inline std::string toString (const T& t, const int width=0, const char fill=' ', const int precision=5 ) {
  std::stringstream ss;
  ss << std::scientific << std::setw(width) << std::setfill(fill) << std::setprecision(precision) << t;
  return ss.str();
}

/*----------------------------------------------------------------------------*/

template <class T>
inline std::string toStringSci (const T& t) {
  return toString(t,16,' ',7);
}

/*----------------------------------------------------------------------------*/

#ifdef BUILD_WITH_APP
template<class PppArray> void displayInfo( const PppArray& data ){
  std::cout << "nDims:"
	    << data.numberOfDimensions() << "\n"
	    << data.getLocalArray().numberOfDimensions() << "\n";
  std::cout << "LocalBase:"
	    << data.getLocalBase(0) << ","
	    << data.getLocalBase(1) << ","
	    << data.getLocalBase(2) << ","
	    << data.getLocalBase(3) << "\n";
  std::cout << "LocalStride:"
	    << data.getLocalStride(0) << ","
	    << data.getLocalStride(1) << ","
	    << data.getLocalStride(2) << ","
	    << data.getLocalStride(3) << "\n";
  std::cout << "LocalBound:"
	    << data.getLocalBound(0) << ","
	    << data.getLocalBound(1) << ","
	    << data.getLocalBound(2) << ","
	    << data.getLocalBound(3) << "\n";
  std::cout << "LocalLength:"
	    << data.getLocalLength(0) << ","
	    << data.getLocalLength(1) << ","
	    << data.getLocalLength(2) << ","
	    << data.getLocalLength(3) << "\n";
  std::cout << "LocalRawBase:"
	    << data.getLocalRawBase(0) << ","
	    << data.getLocalRawBase(1) << ","
	    << data.getLocalRawBase(2) << ","
	    << data.getLocalRawBase(3) << "\n";
  std::cout << "LocalRawStride:"
	    << data.getLocalRawStride(0) << ","
	    << data.getLocalRawStride(1) << ","
	    << data.getLocalRawStride(2) << ","
	    << data.getLocalRawStride(3) << "\n";
  std::cout << "LocalRawBound:"
	    << data.getLocalRawBound(0) << ","
	    << data.getLocalRawBound(1) << ","
	    << data.getLocalRawBound(2) << ","
	    << data.getLocalRawBound(3) << "\n";
  std::cout << "GhostCells:"
	    << data.getGhostBoundaryWidth(0) << ","
	    << data.getGhostBoundaryWidth(1) << ","
	    << data.getGhostBoundaryWidth(2) << ","
	    << data.getGhostBoundaryWidth(3) << "\n";
  std::cout << "InternalGhost:"
	    << data.getInternalGhostCellWidth(0) << ","
	    << data.getInternalGhostCellWidth(1) << ","
	    << data.getInternalGhostCellWidth(2) << ","
	    << data.getInternalGhostCellWidth(3) << "\n";
  std::cout << std::endl;
  std::cout.flush();
}
#endif//BUILD_WITH_APP

/*----------------------------------------------------------------------------*/

#endif //UTIL_HPP__
<|endoftext|>


<commit_before>#ifndef PSEUDO_POWER_SPECTRUM_HEALPIX_IO_HPP
#define PSEUDO_POWER_SPECTRUM_HEALPIX_IO_HPP

namespace pseudo_power_spectrum
{
    /**
     * \class healpix_map_io
     *
     * \brief A class for reading and writing HEALPix maps
     *
     * \tparam _real_matrix_type real matrix type
     *
     * This class contains methods for reading and writing HEALPix maps.
     * The maps are read into a matrix. Each row corresponds to a field in the
     * input fits file.
     */
    template<class _real_matrix_type>
    class healpix_map_io
    {
        typedef _real_matrix_type real_matrix_type;

        real_matrix_type read_mp_from_fits()
        {

        }
    };
}

#endif //PSEUDO_POWER_SPECTRUM_HEALPIX_IO_HPP
<commit_msg>healpix io deleted<commit_after><|endoftext|>