<commit_before>//Copyright (c) 2020 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <optional>
#include <stack>

#include "VoronoiUtils.h"

#include "linearAlg2D.h"
#include "SVG.h"

namespace arachne
{

Point VoronoiUtils::p(const vd_t::vertex_type* node)
{
    return Point(node->x() + 0, node->y() + 0); // gets rid of negative zero
}

bool VoronoiUtils::isSourcePoint(Point p, const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments, coord_t snap_dist)
{
    if (cell.contains_point())
    {
        return shorterThen(p - getSourcePoint(cell, points, segments), snap_dist);
    }
    else
    {
        const Segment& segment = getSourceSegment(cell, points, segments);
        return shorterThen(p - segment.from(), snap_dist) || shorterThen(p - segment.to(), snap_dist);
    }
}

coord_t VoronoiUtils::getDistance(Point p, const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    if (cell.contains_point())
    {
        return vSize(p - getSourcePoint(cell, points, segments));
    }
    else
    {
        const Segment& segment = getSourceSegment(cell, points, segments);
        return sqrt(LinearAlg2D::getDist2FromLineSegment(segment.from(), p, segment.to()));
    }
}

Point VoronoiUtils::getSourcePoint(const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    assert(cell.contains_point());
    switch (cell.source_category())
    {
        case boost::polygon::SOURCE_CATEGORY_SINGLE_POINT:
            return points[cell.source_index()];
            break;
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT:
            assert(cell.source_index() - points.size() < segments.size());
            return segments[cell.source_index() - points.size()].to();
            break;
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT:
            assert(cell.source_index() - points.size() < segments.size());
            return segments[cell.source_index() - points.size()].from();
            break;
        default:
            assert(false && "getSourcePoint should only be called on point cells!\n");
            break;
    }
    return points[cell.source_index()];
}

PolygonsPointIndex VoronoiUtils::getSourcePointIndex(const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    assert(cell.contains_point());
    assert(cell.source_category() != boost::polygon::SOURCE_CATEGORY_SINGLE_POINT);
    switch (cell.source_category())
    {
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT:
        {
            assert(cell.source_index() - points.size() < segments.size());
            PolygonsPointIndex ret = segments[cell.source_index() - points.size()];
            ++ret;
            return ret;
            break;
        }
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT:
        {
            assert(cell.source_index() - points.size() < segments.size());
            return segments[cell.source_index() - points.size()];
            break;
        }
        default:
            assert(false && "getSourcePoint should only be called on point cells!\n");
            break;
    }
    PolygonsPointIndex ret = segments[cell.source_index() - points.size()];
    return ++ret;
}

const VoronoiUtils::Segment& VoronoiUtils::getSourceSegment(const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    assert(cell.contains_segment());
    return segments[cell.source_index() - points.size()];
}

std::vector<Point> VoronoiUtils::discretizeParabola(const Point& p, const Segment& segment, Point s, Point e, coord_t approximate_step_size, float transitioning_angle)
{
    std::vector<Point> discretized;
    // x is distance of point projected on the segment ab
    // xx is point projected on the segment ab
    const Point a = segment.from();
    const Point b = segment.to();
    const Point ab = b - a;
    const Point as = s - a;
    const Point ae = e - a;
    const coord_t ab_size = vSize(ab);
    const coord_t sx = dot(as, ab) / ab_size;
    const coord_t ex = dot(ae, ab) / ab_size;
    const coord_t sxex = ex - sx;

    const Point ap = p - a;
    const coord_t px = dot(ap, ab) / ab_size;

    const Point pxx = LinearAlg2D::getClosestOnLine(p, a, b);
    const Point ppxx = pxx - p;
    const coord_t d = vSize(ppxx);
    const PointMatrix rot = PointMatrix(turn90CCW(ppxx));

    if (d == 0)
    {
        discretized.emplace_back(s);
        discretized.emplace_back(e);
        return discretized;
    }

    const float marking_bound = atan(transitioning_angle * 0.5);
    coord_t msx = - marking_bound * d; // projected marking_start
    coord_t mex = marking_bound * d; // projected marking_end
    const coord_t marking_start_end_h = msx * msx / (2 * d) + d / 2;
    Point marking_start = rot.unapply(Point(msx, marking_start_end_h)) + pxx;
    Point marking_end = rot.unapply(Point(mex, marking_start_end_h)) + pxx;
    const int dir = (sx > ex) ? -1 : 1;
    if (dir < 0)
    {
        std::swap(marking_start, marking_end);
        std::swap(msx, mex);
    }

    bool add_marking_start = msx * dir > (sx - px) * dir && msx * dir < (ex - px) * dir;
    bool add_marking_end = mex * dir > (sx - px) * dir && mex * dir < (ex - px) * dir;

    const Point apex = rot.unapply(Point(0, d / 2)) + pxx;
    bool add_apex = (sx - px) * dir < 0 && (ex - px) * dir > 0;

    assert(!(add_marking_start && add_marking_end) || add_apex);

    const coord_t step_count = static_cast<coord_t>(static_cast<float>(std::abs(ex - sx)) / approximate_step_size + 0.5);

    discretized.emplace_back(s);
    for (coord_t step = 1; step < step_count; step++)
    {
        const coord_t x = sx + sxex * step / step_count - px;
        const coord_t y = x * x / (2 * d) + d / 2;

        if (add_marking_start && msx * dir < x * dir)
        {
            discretized.emplace_back(marking_start);
            add_marking_start = false;
        }
        if (add_apex && x * dir > 0)
        {
            discretized.emplace_back(apex);
            add_apex = false; // only add the apex just before the
        }
        if (add_marking_end && mex * dir < x * dir)
        {
            discretized.emplace_back(marking_end);
            add_marking_end = false;
        }
        const Point result = rot.unapply(Point(x, y)) + pxx;
        discretized.emplace_back(result);
    }
    if (add_apex)
    {
        discretized.emplace_back(apex);
    }
    if (add_marking_end)
    {
        discretized.emplace_back(marking_end);
    }
    discretized.emplace_back(e);
    return discretized;
}

// adapted from boost::polygon::voronoi_visual_utils.cpp
void VoronoiUtils::discretize(
        const Point& point,
        const Segment& segment,
        const coord_t max_dist,
        std::vector<Point>* discretization) {
    // Apply the linear transformation to move start point of the segment to
    // the point with coordinates (0, 0) and the direction of the segment to
    // coincide the positive direction of the x-axis.
    Point segm_vec = segment.to() - segment.from();
    coord_t sqr_segment_length = vSize2(segm_vec);

    // Compute x-coordinates of the endpoints of the edge
    // in the transformed space.
    coord_t projection_start = sqr_segment_length *
            get_point_projection((*discretization)[0], segment);
    coord_t projection_end = sqr_segment_length *
            get_point_projection((*discretization)[1], segment);

    // Compute parabola parameters in the transformed space.
    // Parabola has next representation:
    // f(x) = ((x-rot_x)^2 + rot_y^2) / (2.0*rot_y).
    Point point_vec = point - segment.from();
    coord_t rot_x = dot(segm_vec, point_vec);
    coord_t rot_y = cross(segm_vec, point_vec);

    // Save the last point.
    Point last_point = (*discretization)[1];
    discretization->pop_back();

    // Use stack to avoid recursion.
    std::stack<coord_t> point_stack;
    point_stack.push(projection_end);
    Point cur(projection_start, parabola_y(projection_start, rot_x, rot_y));

    // Adjust max_dist parameter in the transformed space.
    const coord_t max_dist_transformed = max_dist * max_dist * sqr_segment_length;
    while (!point_stack.empty()) {
        Point new_(point_stack.top(), parabola_y(point_stack.top(), rot_x, rot_y));
        Point new_vec = new_ - cur;

        // Compute coordinates of the point of the parabola that is
        // furthest from the current line segment.
        coord_t mid_x = new_vec.Y * rot_y / new_vec.X + rot_x;
        coord_t mid_y = parabola_y(mid_x, rot_x, rot_y);
        Point mid_vec = Point(mid_x, mid_y) - cur;

        // Compute maximum distance between the given parabolic arc
        // and line segment that discretize it.
        __int128 dist = cross(mid_vec, new_vec);
        dist = dist * dist / vSize2(new_vec); // TODO overflows!!!
        if (dist <= max_dist_transformed) {
            // Distance between parabola and line segment is less than max_dist.
            point_stack.pop();
            coord_t inter_x = (segm_vec.X * new_.X - segm_vec.Y * new_.Y) /
                    sqr_segment_length + segment.from().X;
            coord_t inter_y = (segm_vec.X * new_.Y + segm_vec.Y * new_.X) /
                    sqr_segment_length + segment.from().Y;
            discretization->push_back(Point(inter_x, inter_y));
            cur = new_;
        } else {
            point_stack.push(mid_x);
        }
    }

    // Update last point.
    discretization->back() = last_point;
}

// adapted from boost::polygon::voronoi_visual_utils.cpp
coord_t VoronoiUtils::parabola_y(coord_t x, coord_t a, coord_t b) {
    return ((x - a) * (x - a) + b * b) / (b + b);
}

// adapted from boost::polygon::voronoi_visual_utils.cpp
double VoronoiUtils::get_point_projection(
        const Point& point, const Segment& segment) {
    Point segment_vec = segment.to() - segment.from();
    Point point_vec = point - segment.from();
    coord_t sqr_segment_length = vSize2(segment_vec);
    coord_t vec_dot = dot(segment_vec, point_vec);
    return static_cast<double>(vec_dot) / sqr_segment_length;
}

}//namespace arachne
<commit_msg>Brackets on new line<commit_after>//Copyright (c) 2020 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <optional>
#include <stack>

#include "VoronoiUtils.h"

#include "linearAlg2D.h"
#include "SVG.h"

namespace arachne
{

Point VoronoiUtils::p(const vd_t::vertex_type* node)
{
    return Point(node->x() + 0, node->y() + 0); // gets rid of negative zero
}

bool VoronoiUtils::isSourcePoint(Point p, const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments, coord_t snap_dist)
{
    if (cell.contains_point())
    {
        return shorterThen(p - getSourcePoint(cell, points, segments), snap_dist);
    }
    else
    {
        const Segment& segment = getSourceSegment(cell, points, segments);
        return shorterThen(p - segment.from(), snap_dist) || shorterThen(p - segment.to(), snap_dist);
    }
}

coord_t VoronoiUtils::getDistance(Point p, const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    if (cell.contains_point())
    {
        return vSize(p - getSourcePoint(cell, points, segments));
    }
    else
    {
        const Segment& segment = getSourceSegment(cell, points, segments);
        return sqrt(LinearAlg2D::getDist2FromLineSegment(segment.from(), p, segment.to()));
    }
}

Point VoronoiUtils::getSourcePoint(const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    assert(cell.contains_point());
    switch (cell.source_category())
    {
        case boost::polygon::SOURCE_CATEGORY_SINGLE_POINT:
            return points[cell.source_index()];
            break;
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT:
            assert(cell.source_index() - points.size() < segments.size());
            return segments[cell.source_index() - points.size()].to();
            break;
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT:
            assert(cell.source_index() - points.size() < segments.size());
            return segments[cell.source_index() - points.size()].from();
            break;
        default:
            assert(false && "getSourcePoint should only be called on point cells!\n");
            break;
    }
    return points[cell.source_index()];
}

PolygonsPointIndex VoronoiUtils::getSourcePointIndex(const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    assert(cell.contains_point());
    assert(cell.source_category() != boost::polygon::SOURCE_CATEGORY_SINGLE_POINT);
    switch (cell.source_category())
    {
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT:
        {
            assert(cell.source_index() - points.size() < segments.size());
            PolygonsPointIndex ret = segments[cell.source_index() - points.size()];
            ++ret;
            return ret;
            break;
        }
        case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT:
        {
            assert(cell.source_index() - points.size() < segments.size());
            return segments[cell.source_index() - points.size()];
            break;
        }
        default:
            assert(false && "getSourcePoint should only be called on point cells!\n");
            break;
    }
    PolygonsPointIndex ret = segments[cell.source_index() - points.size()];
    return ++ret;
}

const VoronoiUtils::Segment& VoronoiUtils::getSourceSegment(const vd_t::cell_type& cell, const std::vector<Point>& points, const std::vector<Segment>& segments)
{
    assert(cell.contains_segment());
    return segments[cell.source_index() - points.size()];
}

std::vector<Point> VoronoiUtils::discretizeParabola(const Point& p, const Segment& segment, Point s, Point e, coord_t approximate_step_size, float transitioning_angle)
{
    std::vector<Point> discretized;
    // x is distance of point projected on the segment ab
    // xx is point projected on the segment ab
    const Point a = segment.from();
    const Point b = segment.to();
    const Point ab = b - a;
    const Point as = s - a;
    const Point ae = e - a;
    const coord_t ab_size = vSize(ab);
    const coord_t sx = dot(as, ab) / ab_size;
    const coord_t ex = dot(ae, ab) / ab_size;
    const coord_t sxex = ex - sx;

    const Point ap = p - a;
    const coord_t px = dot(ap, ab) / ab_size;

    const Point pxx = LinearAlg2D::getClosestOnLine(p, a, b);
    const Point ppxx = pxx - p;
    const coord_t d = vSize(ppxx);
    const PointMatrix rot = PointMatrix(turn90CCW(ppxx));

    if (d == 0)
    {
        discretized.emplace_back(s);
        discretized.emplace_back(e);
        return discretized;
    }

    const float marking_bound = atan(transitioning_angle * 0.5);
    coord_t msx = - marking_bound * d; // projected marking_start
    coord_t mex = marking_bound * d; // projected marking_end
    const coord_t marking_start_end_h = msx * msx / (2 * d) + d / 2;
    Point marking_start = rot.unapply(Point(msx, marking_start_end_h)) + pxx;
    Point marking_end = rot.unapply(Point(mex, marking_start_end_h)) + pxx;
    const int dir = (sx > ex) ? -1 : 1;
    if (dir < 0)
    {
        std::swap(marking_start, marking_end);
        std::swap(msx, mex);
    }

    bool add_marking_start = msx * dir > (sx - px) * dir && msx * dir < (ex - px) * dir;
    bool add_marking_end = mex * dir > (sx - px) * dir && mex * dir < (ex - px) * dir;

    const Point apex = rot.unapply(Point(0, d / 2)) + pxx;
    bool add_apex = (sx - px) * dir < 0 && (ex - px) * dir > 0;

    assert(!(add_marking_start && add_marking_end) || add_apex);

    const coord_t step_count = static_cast<coord_t>(static_cast<float>(std::abs(ex - sx)) / approximate_step_size + 0.5);

    discretized.emplace_back(s);
    for (coord_t step = 1; step < step_count; step++)
    {
        const coord_t x = sx + sxex * step / step_count - px;
        const coord_t y = x * x / (2 * d) + d / 2;

        if (add_marking_start && msx * dir < x * dir)
        {
            discretized.emplace_back(marking_start);
            add_marking_start = false;
        }
        if (add_apex && x * dir > 0)
        {
            discretized.emplace_back(apex);
            add_apex = false; // only add the apex just before the
        }
        if (add_marking_end && mex * dir < x * dir)
        {
            discretized.emplace_back(marking_end);
            add_marking_end = false;
        }
        const Point result = rot.unapply(Point(x, y)) + pxx;
        discretized.emplace_back(result);
    }
    if (add_apex)
    {
        discretized.emplace_back(apex);
    }
    if (add_marking_end)
    {
        discretized.emplace_back(marking_end);
    }
    discretized.emplace_back(e);
    return discretized;
}

// adapted from boost::polygon::voronoi_visual_utils.cpp
void VoronoiUtils::discretize(
        const Point& point,
        const Segment& segment,
        const coord_t max_dist,
        std::vector<Point>* discretization) {
    // Apply the linear transformation to move start point of the segment to
    // the point with coordinates (0, 0) and the direction of the segment to
    // coincide the positive direction of the x-axis.
    Point segm_vec = segment.to() - segment.from();
    coord_t sqr_segment_length = vSize2(segm_vec);

    // Compute x-coordinates of the endpoints of the edge
    // in the transformed space.
    coord_t projection_start = sqr_segment_length *
            get_point_projection((*discretization)[0], segment);
    coord_t projection_end = sqr_segment_length *
            get_point_projection((*discretization)[1], segment);

    // Compute parabola parameters in the transformed space.
    // Parabola has next representation:
    // f(x) = ((x-rot_x)^2 + rot_y^2) / (2.0*rot_y).
    Point point_vec = point - segment.from();
    coord_t rot_x = dot(segm_vec, point_vec);
    coord_t rot_y = cross(segm_vec, point_vec);

    // Save the last point.
    Point last_point = (*discretization)[1];
    discretization->pop_back();

    // Use stack to avoid recursion.
    std::stack<coord_t> point_stack;
    point_stack.push(projection_end);
    Point cur(projection_start, parabola_y(projection_start, rot_x, rot_y));

    // Adjust max_dist parameter in the transformed space.
    const coord_t max_dist_transformed = max_dist * max_dist * sqr_segment_length;
    while (!point_stack.empty())
    {
        Point new_(point_stack.top(), parabola_y(point_stack.top(), rot_x, rot_y));
        Point new_vec = new_ - cur;

        // Compute coordinates of the point of the parabola that is
        // furthest from the current line segment.
        coord_t mid_x = new_vec.Y * rot_y / new_vec.X + rot_x;
        coord_t mid_y = parabola_y(mid_x, rot_x, rot_y);
        Point mid_vec = Point(mid_x, mid_y) - cur;

        // Compute maximum distance between the given parabolic arc
        // and line segment that discretize it.
        __int128 dist = cross(mid_vec, new_vec);
        dist = dist * dist / vSize2(new_vec); // TODO overflows!!!
        if (dist <= max_dist_transformed) {
            // Distance between parabola and line segment is less than max_dist.
            point_stack.pop();
            coord_t inter_x = (segm_vec.X * new_.X - segm_vec.Y * new_.Y) /
                    sqr_segment_length + segment.from().X;
            coord_t inter_y = (segm_vec.X * new_.Y + segm_vec.Y * new_.X) /
                    sqr_segment_length + segment.from().Y;
            discretization->push_back(Point(inter_x, inter_y));
            cur = new_;
        } else {
            point_stack.push(mid_x);
        }
    }

    // Update last point.
    discretization->back() = last_point;
}

// adapted from boost::polygon::voronoi_visual_utils.cpp
coord_t VoronoiUtils::parabola_y(coord_t x, coord_t a, coord_t b)
{
    return ((x - a) * (x - a) + b * b) / (b + b);
}

// adapted from boost::polygon::voronoi_visual_utils.cpp
double VoronoiUtils::get_point_projection(
        const Point& point, const Segment& segment) {
    Point segment_vec = segment.to() - segment.from();
    Point point_vec = point - segment.from();
    coord_t sqr_segment_length = vSize2(segment_vec);
    coord_t vec_dot = dot(segment_vec, point_vec);
    return static_cast<double>(vec_dot) / sqr_segment_length;
}

}//namespace arachne
<|endoftext|>


<commit_before>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_FUTURE_HPP_
#define _QITYPE_FUTURE_HPP_

#include <vector>
#include <qi/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>
#include <qi/eventloop.hpp>

#ifdef _MSC_VER
#  pragma warning( push )
#  pragma warning( disable: 4251 )
#endif

namespace qi {

  template<typename T> struct FutureType
  {
    typedef T type;
  };

  // Hold a void* for Future<void>
  template<> struct FutureType<void>
  {
    typedef void* type;
  };

  template <typename T> class FutureInterface;
  template <typename T> class Future;
  template <typename T> class FutureSync;
  template <typename T> class Promise;

  namespace detail {
    template <typename T> class FutureState;
  }

  template <typename T>
  class Future {
  public:
    typedef typename FutureType<T>::type ValueType;
    Future()
      : _p(new detail::FutureState<T>())
    {
    }

    Future(const FutureSync<T>& b)
    {
      *this = b;
    }

    inline Future<T>& operator = (const FutureSync<T>& b)
    {
      b._sync = false;
      _p = b._p;
      return *this;
    }

    explicit Future<T>(const ValueType& v)
    {
      Promise<T> promise;
      promise.setValue(v);
      *this = promise.future();
    }

    inline const ValueType &value() const    { return _p->value(); }

    /** Wait for future, and return a default value in case of error.
     * @param defaultVal the value to return in case of Future error
     * @return the future value, or \p defaultVal if hasError() is true.
     */
    inline const ValueType &valueWithDefault(const ValueType& defaultVal = ValueType()) const;

    inline operator const ValueType&() const { return _p->value(); }

    /** Wait for future to contain a value or an error
     @param msecs: Maximum time to wait in milliseconds, 0 means forever and -1 means return immediately.
     @return true if future contains a value or an error, false if timeout was reached
     */
    inline bool wait(int msecs = 30000) const         { return _p->wait(msecs); }
    inline bool isReady() const                       { return _p->isReady(); }
    inline bool hasError(int msecs=30000) const       { return _p->hasError(msecs); }

    inline const std::string &error() const           { return _p->error(); }

    inline FutureSync<T> sync()
    {
      return FutureSync<T>(*this);
    };

  public: //Signals
    typedef boost::signals2::connection Connection;
    typedef typename boost::signals2::signal<void (Future<T>)>::slot_type Slot;
    inline Connection connect(const Slot& s) { return _p->connect(*this, s);}
    inline bool disconnect(Connection i) { return _p->disconnect(i); }
    //qi::Signal<void (qi::Future<T>)> &onResult() { return _p->_onResult; }

  protected:
    // C4251 needs to have dll-interface to be used by clients of class 'qi::Future<T>'
    boost::shared_ptr< detail::FutureState<T> > _p;
    friend class Promise<T>;
    friend class FutureSync<T>;
  };

  template<typename T> class FutureSync: public Future<T>
  {
  public:
    // This future cannot be set, so sync starts at false
    FutureSync() : _sync(false) {}

    FutureSync(const Future<T>& b)
    : _sync(true)
    {
      *this = b;
      this->_p = b._p;
    }

    FutureSync(const FutureSync<T>& b)
    : _sync(true)
    {
      *this = b;
      this->_p = b._p;
      b._sync = false;
    }

    explicit FutureSync<T>(const typename Future<T>::ValueType& v)
    : _sync(false)
    {
      Promise<T> promise;
      promise.setValue(v);
      *this = promise.future();
    }

    inline FutureSync<T>& operator = (const FutureSync<T>& b)
    {
      this->_p = b._p;
      _sync = true;
      b._sync = false;
      return *this;
    }

    inline FutureSync<T>& operator = (const Future<T>& b)
    {
     this->_p = b._p;
      _sync = true;
      return *this;
    }

    ~FutureSync()
    {
      if (_sync)
        this->wait();
    }

    Future<T> async()
    {
      return *this;
    }

  private:
    mutable bool _sync;
    friend class Future<T>;
  };

  template <typename T>
  class Promise {
  public:
    typedef typename FutureType<T>::type ValueType;

    Promise() { }

    void setValue(const ValueType &value) {
      _f._p->setValue(_f, value);
    }

    void setError(const std::string &msg) {
      _f._p->setError(_f, msg);
    }

    void reset() {
      _f._p->reset();
    }

    Future<T> future() { return _f; }

  protected:
    Future<T> _f;
  };

  template <typename T>
  qi::Future<T> makeFutureError(const std::string &value);
}

#ifdef _MSC_VER
#  pragma warning( pop )
#endif

#include <qi/details/future.hxx>

#endif  // _QITYPE_FUTURE_HPP_
<commit_msg>Future, FutureSync: Optimize constructors.<commit_after>#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_FUTURE_HPP_
#define _QITYPE_FUTURE_HPP_

#include <vector>
#include <qi/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>
#include <qi/eventloop.hpp>

#ifdef _MSC_VER
#  pragma warning( push )
#  pragma warning( disable: 4251 )
#endif

namespace qi {

  template<typename T> struct FutureType
  {
    typedef T type;
  };

  // Hold a void* for Future<void>
  template<> struct FutureType<void>
  {
    typedef void* type;
  };

  template <typename T> class FutureInterface;
  template <typename T> class Future;
  template <typename T> class FutureSync;
  template <typename T> class Promise;

  namespace detail {
    template <typename T> class FutureState;
  }

  template <typename T>
  class Future {
  public:
    typedef typename FutureType<T>::type ValueType;
    Future()
      : _p(new detail::FutureState<T>())
    {
    }

    Future(const FutureSync<T>& b)
    : _p(b._p)
    {
      b._sync = false;
    }

    inline Future<T>& operator = (const FutureSync<T>& b)
    {
      b._sync = false;
      _p = b._p;
      return *this;
    }

    explicit Future<T>(const ValueType& v)
    {
      Promise<T> promise;
      promise.setValue(v);
      *this = promise.future();
    }

    inline const ValueType &value() const    { return _p->value(); }

    /** Wait for future, and return a default value in case of error.
     * @param defaultVal the value to return in case of Future error
     * @return the future value, or \p defaultVal if hasError() is true.
     */
    inline const ValueType &valueWithDefault(const ValueType& defaultVal = ValueType()) const;

    inline operator const ValueType&() const { return _p->value(); }

    /** Wait for future to contain a value or an error
     @param msecs: Maximum time to wait in milliseconds, 0 means forever and -1 means return immediately.
     @return true if future contains a value or an error, false if timeout was reached
     */
    inline bool wait(int msecs = 30000) const         { return _p->wait(msecs); }
    inline bool isReady() const                       { return _p->isReady(); }
    inline bool hasError(int msecs=30000) const       { return _p->hasError(msecs); }

    inline const std::string &error() const           { return _p->error(); }

    inline FutureSync<T> sync()
    {
      return FutureSync<T>(*this);
    };

  public: //Signals
    typedef boost::signals2::connection Connection;
    typedef typename boost::signals2::signal<void (Future<T>)>::slot_type Slot;
    inline Connection connect(const Slot& s) { return _p->connect(*this, s);}
    inline bool disconnect(Connection i) { return _p->disconnect(i); }
    //qi::Signal<void (qi::Future<T>)> &onResult() { return _p->_onResult; }

  protected:
    // C4251 needs to have dll-interface to be used by clients of class 'qi::Future<T>'
    boost::shared_ptr< detail::FutureState<T> > _p;
    friend class Promise<T>;
    friend class FutureSync<T>;
  };

  template<typename T> class FutureSync: public Future<T>
  {
  public:
    // This future cannot be set, so sync starts at false
    FutureSync() : _sync(false) {}

    FutureSync(const Future<T>& b)
    : Future<T>(b)
    , _sync(true)
    {
    }

    FutureSync(const FutureSync<T>& b)
    : Future<T>(b)
    , _sync(true)
    {
      b._sync = false;
    }

    explicit FutureSync<T>(const typename Future<T>::ValueType& v)
    : _sync(false)
    {
      Promise<T> promise;
      promise.setValue(v);
      *this = promise.future();
    }

    inline FutureSync<T>& operator = (const FutureSync<T>& b)
    {
      this->_p = b._p;
      _sync = true;
      b._sync = false;
      return *this;
    }

    inline FutureSync<T>& operator = (const Future<T>& b)
    {
     this->_p = b._p;
      _sync = true;
      return *this;
    }

    ~FutureSync()
    {
      if (_sync)
        this->wait();
    }

    Future<T> async()
    {
      return *this;
    }

  private:
    mutable bool _sync;
    friend class Future<T>;
  };

  template <typename T>
  class Promise {
  public:
    typedef typename FutureType<T>::type ValueType;

    Promise() { }

    void setValue(const ValueType &value) {
      _f._p->setValue(_f, value);
    }

    void setError(const std::string &msg) {
      _f._p->setError(_f, msg);
    }

    void reset() {
      _f._p->reset();
    }

    Future<T> future() { return _f; }

  protected:
    Future<T> _f;
  };

  template <typename T>
  qi::Future<T> makeFutureError(const std::string &value);
}

#ifdef _MSC_VER
#  pragma warning( pop )
#endif

#include <qi/details/future.hxx>

#endif  // _QITYPE_FUTURE_HPP_
<|endoftext|>


<commit_before>/*

This file is part of VROOM.

Copyright (c) 2015-2017, Julien Coupey.
All rights reserved (see LICENSE).

*/

#include "./input_parser.h"

// Helper to get optional array of coordinates.
inline optional_coords_t parse_coordinates(const rapidjson::Value& object,
                                           const char* key) {
  if (object.HasMember(key) and object[key].IsArray()) {
    if (object[key].Size() < 2) {
      throw custom_exception("Invalid coordinates array size.");
    }
    return optional_coords_t({object[key][0].GetDouble(),
          object[key][1].GetDouble()});
  }
  else {
    return boost::none;
  }
}

input parse(const cl_args_t& cl_args) {
  BOOST_LOG_TRIVIAL(info) << "[Loading] Parsing input.";

  // Set relevant wrapper to retrieve the matrix and geometry.
  std::unique_ptr<routing_io<distance_t>> routing_wrapper;
  if (!cl_args.use_libosrm) {
    // Use osrm-routed.
    routing_wrapper =
      std::make_unique<routed_wrapper>(cl_args.osrm_address,
                                       cl_args.osrm_port,
                                       cl_args.osrm_profile);
  }
  else {
#if LIBOSRM
    // Use libosrm.
    if (cl_args.osrm_profile.empty()) {
      throw custom_exception("-l flag requires -m.");
    }
    routing_wrapper = std::make_unique<libosrm_wrapper>(cl_args.osrm_profile);
#else
    throw custom_exception("libosrm must be installed to use -l.");
#endif
  }

  // Custom input object embedding jobs, vehicles and matrix.
  input input_data(std::move(routing_wrapper), cl_args.geometry);

  // Input json object.
  rapidjson::Document json_input;

  // Parsing input string to populate the input object.
  if (json_input.Parse(cl_args.input.c_str()).HasParseError()) {
    std::string error_msg =
      std::string(rapidjson::GetParseError_En(json_input.GetParseError())) +
      " (offset: " + std::to_string(json_input.GetErrorOffset()) + ")";
    throw custom_exception(error_msg);
  }

  // Checks required in any case.
  if (!json_input.HasMember("jobs") or !json_input["jobs"].IsArray()) {
    throw custom_exception("Incorrect jobs input.");
  }

  if (!json_input.HasMember("vehicles")
     or !json_input["vehicles"].IsArray()
     or json_input["vehicles"].Empty()) {
    throw custom_exception("Incorrect vehicles input.");
  }
  if (!json_input["vehicles"][0].IsObject()) {
    throw custom_exception("Ill-formed vehicle object.");
  }
  if (!json_input["vehicles"][0].HasMember("id")) {
    throw custom_exception("Missing mandatory vehicle id.");
  }
  if (json_input["vehicles"].Size() > 1) {
    throw custom_exception("Multiple vehicles are not supported (yet).");
  }

  // Switch input type: explicit matrix or using OSRM.
  if (json_input.HasMember("matrix")) {
    // Load custom matrix while checking if it is square.
    rapidjson::SizeType matrix_size = json_input["matrix"].Size();
    matrix<distance_t> matrix_input(matrix_size);
    for (rapidjson::SizeType i = 0; i < matrix_size; ++i) {
      if (json_input["matrix"][i].Size() != matrix_size) {
        throw custom_exception("Input matrix is not square.");
      }
      for (rapidjson::SizeType j = 0; j < matrix_size; ++j) {
        if (!json_input["matrix"][i][j].IsNumber()) {
          throw custom_exception("Input matrix has a non-number entry.");
        }
        matrix_input[i][j] = json_input["matrix"][i][j].GetUint();
      }
    }

    //Identify the necessary columns/rows from the loaded matrix
    std::vector<index_t> necessary_indices;
    index_t index_counter = 0;

    // Check if vehicle has start_index or end_index.
    boost::optional<index_t> start_index;
    if (json_input["vehicles"][0].HasMember("start_index")) {
      if (!json_input["vehicles"][0]["start_index"].IsNumber()) {
        throw custom_exception("Vehicle start_index is not a number.");
      }
      start_index = json_input["vehicles"][0]["start_index"].GetUint();
      if (matrix_size <= start_index.get()) {
        throw custom_exception("Vehicle start_index does not match to matrix size.");
      }
    }
    if (start_index) {
      necessary_indices.push_back( start_index.get() );
      start_index = index_counter++;
    }
    boost::optional<index_t> end_index;
    if (json_input["vehicles"][0].HasMember("end_index")) {
      if (!json_input["vehicles"][0]["end_index"].IsNumber()) {
        throw custom_exception("Vehicle end_index is not a number.");
      }
      end_index = json_input["vehicles"][0]["end_index"].GetUint();
      if (matrix_size <= end_index.get()) {
        throw custom_exception("Vehicle end_index does not match to matrix size.");
      }
    }
    if (end_index) {
      necessary_indices.push_back( end_index.get() );
      end_index = index_counter++;
    }
    // Add vehicle to input
    input_data.add_vehicle(json_input["vehicles"][0]["id"].GetUint(),
                           parse_coordinates(json_input["vehicles"][0],
                                             "start"),
                           parse_coordinates(json_input["vehicles"][0],
                                             "end"),
                           start_index,
                           end_index);
    // Add the jobs
    for (rapidjson::SizeType i = 0; i < json_input["jobs"].Size(); ++i) {
      if (!json_input["jobs"][i].IsObject()){
        throw custom_exception("Ill-formed job object.");
      }
      if (!json_input["jobs"][i].HasMember("id")) {
        throw custom_exception("Missing mandatory job id.");
      }
      if (!json_input["jobs"][i]["id"].IsNumber()) {
        throw custom_exception("Job id is not a number.");
      }
      if (!json_input["jobs"][i].HasMember("location_index")) {
        throw custom_exception("Missing mandatory job location_index.");
      }
      if (!json_input["jobs"][i]["location_index"].IsNumber()) {
        throw custom_exception("Job location_index is not a number.");
      }
      if (matrix_size <= json_input["jobs"][i]["location_index"].GetUint()) {
        throw custom_exception("Job location_index does not match to matrix size.");
      }
      necessary_indices.push_back( json_input["jobs"][i]["location_index"].GetUint() );
      input_data.add_job(json_input["jobs"][i]["id"].GetUint(),
                         parse_coordinates(json_input["jobs"][i],"location"),
                         index_counter++);
    }

    //Extract the necessary columns/rows for the algorithm.
    input_data._matrix = matrix_input.get_sub_matrix( necessary_indices );
  }
  else {
    input_data.add_vehicle(json_input["vehicles"][0]["id"].GetUint(),
                           parse_coordinates(json_input["vehicles"][0],
                                             "start"),
                           parse_coordinates(json_input["vehicles"][0],
                                             "end"));

    // Getting jobs.
    for (rapidjson::SizeType i = 0; i < json_input["jobs"].Size(); ++i) {
      if (!json_input["jobs"][i].IsObject()) {
        throw custom_exception("Ill-formed job object.");
      }
      if (!json_input["jobs"][i].HasMember("location")) {
        throw custom_exception("Missing mandatory job location.");
      }
      if (!json_input["jobs"][i].HasMember("id")) {
        throw custom_exception("Missing mandatory job id.");
      }

      input_data.add_job(json_input["jobs"][i]["id"].GetUint(),
                         parse_coordinates(json_input["jobs"][i], "location"));
    }
  }

  if (input_data._locations.size() <= 1) {
    throw custom_exception("At least two locations required!");
  }

  return input_data;
}
<commit_msg>Add json validity checks. #61<commit_after>/*

This file is part of VROOM.

Copyright (c) 2015-2017, Julien Coupey.
All rights reserved (see LICENSE).

*/

#include "./input_parser.h"

// Helper to get optional array of coordinates.
inline optional_coords_t parse_coordinates(const rapidjson::Value& object,
                                           const char* key) {
  if (object.HasMember(key) and object[key].IsArray()) {
    if ((object[key].Size() < 2)
        or !object[key][0].IsNumber()
        or !object[key][1].IsNumber()) {
      throw custom_exception("Invalid " + std::string(key) + " array.");
    }
    return optional_coords_t({object[key][0].GetDouble(),
          object[key][1].GetDouble()});
  }
  else {
    return boost::none;
  }
}

input parse(const cl_args_t& cl_args) {
  BOOST_LOG_TRIVIAL(info) << "[Loading] Parsing input.";

  // Set relevant wrapper to retrieve the matrix and geometry.
  std::unique_ptr<routing_io<distance_t>> routing_wrapper;
  if (!cl_args.use_libosrm) {
    // Use osrm-routed.
    routing_wrapper =
      std::make_unique<routed_wrapper>(cl_args.osrm_address,
                                       cl_args.osrm_port,
                                       cl_args.osrm_profile);
  }
  else {
#if LIBOSRM
    // Use libosrm.
    if (cl_args.osrm_profile.empty()) {
      throw custom_exception("-l flag requires -m.");
    }
    routing_wrapper = std::make_unique<libosrm_wrapper>(cl_args.osrm_profile);
#else
    throw custom_exception("libosrm must be installed to use -l.");
#endif
  }

  // Custom input object embedding jobs, vehicles and matrix.
  input input_data(std::move(routing_wrapper), cl_args.geometry);

  // Input json object.
  rapidjson::Document json_input;

  // Parsing input string to populate the input object.
  if (json_input.Parse(cl_args.input.c_str()).HasParseError()) {
    std::string error_msg =
      std::string(rapidjson::GetParseError_En(json_input.GetParseError())) +
      " (offset: " + std::to_string(json_input.GetErrorOffset()) + ")";
    throw custom_exception(error_msg);
  }

  // Main Checks for valid json input.
  if (!json_input.HasMember("jobs") or !json_input["jobs"].IsArray()) {
    throw custom_exception("Incorrect jobs input.");
  }

  if (!json_input.HasMember("vehicles")
     or !json_input["vehicles"].IsArray()
     or json_input["vehicles"].Empty()) {
    throw custom_exception("Incorrect vehicles input.");
  }
  if (!json_input["vehicles"][0].IsObject()) {
    throw custom_exception("Ill-formed vehicle object.");
  }
  if (!json_input["vehicles"][0].HasMember("id")
      or !json_input["vehicles"][0]["id"].IsUint()) {
    throw custom_exception("Invalid vehicle id.");
  }
  if (json_input["vehicles"].Size() > 1) {
    throw custom_exception("Multiple vehicles are not supported (yet).");
  }

  // Switch input type: explicit matrix or using OSRM.
  if (json_input.HasMember("matrix")) {
    if (!json_input["matrix"].IsArray()) {
      throw custom_exception("Invalid matrix.");
    }

    // Load custom matrix while checking if it is square.
    rapidjson::SizeType matrix_size = json_input["matrix"].Size();
    matrix<distance_t> matrix_input(matrix_size);
    for (rapidjson::SizeType i = 0; i < matrix_size; ++i) {
      if (!json_input["matrix"][i].IsArray()
          or (json_input["matrix"][i].Size() != matrix_size)) {
        throw custom_exception("Input matrix is not square.");
      }
      for (rapidjson::SizeType j = 0; j < matrix_size; ++j) {
        if (!json_input["matrix"][i][j].IsUint()) {
          throw custom_exception("Input matrix has a non-number entry.");
        }
        matrix_input[i][j] = json_input["matrix"][i][j].GetUint();
      }
    }

    //Identify the necessary columns/rows from the loaded matrix
    std::vector<index_t> necessary_indices;
    index_t index_counter = 0;

    // Check if vehicle has start_index or end_index.
    boost::optional<index_t> start_index;
    if (json_input["vehicles"][0].HasMember("start_index")) {
      if (!json_input["vehicles"][0]["start_index"].IsUint()) {
        throw custom_exception("Vehicle start_index is not a number.");
      }
      start_index = json_input["vehicles"][0]["start_index"].GetUint();
      if (matrix_size <= start_index.get()) {
        throw custom_exception("Vehicle start_index does not match to matrix size.");
      }
    }
    if (start_index) {
      necessary_indices.push_back( start_index.get() );
      start_index = index_counter++;
    }
    boost::optional<index_t> end_index;
    if (json_input["vehicles"][0].HasMember("end_index")) {
      if (!json_input["vehicles"][0]["end_index"].IsUint()) {
        throw custom_exception("Vehicle end_index is not a number.");
      }
      end_index = json_input["vehicles"][0]["end_index"].GetUint();
      if (matrix_size <= end_index.get()) {
        throw custom_exception("Vehicle end_index does not match to matrix size.");
      }
    }
    if (end_index) {
      necessary_indices.push_back( end_index.get() );
      end_index = index_counter++;
    }
    // Add vehicle to input
    input_data.add_vehicle(json_input["vehicles"][0]["id"].GetUint(),
                           parse_coordinates(json_input["vehicles"][0],
                                             "start"),
                           parse_coordinates(json_input["vehicles"][0],
                                             "end"),
                           start_index,
                           end_index);
    // Add the jobs
    for (rapidjson::SizeType i = 0; i < json_input["jobs"].Size(); ++i) {
      if (!json_input["jobs"][i].IsObject()) {
        throw custom_exception("Ill-formed job object.");
      }
      if (!json_input["jobs"][i].HasMember("id")
          or !json_input["jobs"][i]["id"].IsUint()) {
        throw custom_exception("Invalid job id.");
      }
      if (!json_input["jobs"][i].HasMember("location_index")
          or !json_input["jobs"][i]["location_index"].IsUint()) {
        throw custom_exception("Invalid job location_index.");
      }
      if (matrix_size <= json_input["jobs"][i]["location_index"].GetUint()) {
        throw custom_exception("Job location_index does not match to matrix size.");
      }
      necessary_indices.push_back( json_input["jobs"][i]["location_index"].GetUint() );
      input_data.add_job(json_input["jobs"][i]["id"].GetUint(),
                         parse_coordinates(json_input["jobs"][i],"location"),
                         index_counter++);
    }

    //Extract the necessary columns/rows for the algorithm.
    input_data._matrix = matrix_input.get_sub_matrix( necessary_indices );
  }
  else {
    input_data.add_vehicle(json_input["vehicles"][0]["id"].GetUint(),
                           parse_coordinates(json_input["vehicles"][0],
                                             "start"),
                           parse_coordinates(json_input["vehicles"][0],
                                             "end"));

    // Getting jobs.
    for (rapidjson::SizeType i = 0; i < json_input["jobs"].Size(); ++i) {
      if (!json_input["jobs"][i].IsObject()) {
        throw custom_exception("Ill-formed job object.");
      }
      if (!json_input["jobs"][i].HasMember("location")
          or !json_input["jobs"][i]["location"].IsArray()) {
        throw custom_exception("Invalid job location.");
      }
      if (!json_input["jobs"][i].HasMember("id")
          or !json_input["jobs"][i]["id"].IsUint()) {
        throw custom_exception("Invalid job id.");
      }

      input_data.add_job(json_input["jobs"][i]["id"].GetUint(),
                         parse_coordinates(json_input["jobs"][i], "location"));
    }
  }

  if (input_data._locations.size() <= 1) {
    throw custom_exception("At least two locations required!");
  }

  return input_data;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    TestAreaSelections.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// This tests vtkHardwareSelector, vtkExtractSelectedFrustum,
// vtkRenderedAreaPicker, and vtkInteractorStyleRubberBandPick.
//
// The command line arguments are:
// -I        => run in interactive mode; unless this is used, the program will
//              not allow interaction and exit

#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"

#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkInteractorStyleRubberBandPick.h"
#include "vtkCallbackCommand.h"
#include "vtkHardwareSelector.h"
#include "vtkSelection.h"
#include "vtkExtractSelectedPolyDataIds.h"
#include "vtkIdTypeArray.h"
#include "vtkRenderedAreaPicker.h"
#include "vtkCamera.h"
#include "vtkImageMandelbrotSource.h"
#include "vtkImageActor.h"
#include "vtkExtractSelectedFrustum.h"
#include "vtkDataSetMapper.h"
#include "vtkSmartPointer.h"

#include "vtkDataSetReader.h"

vtkSmartPointer<vtkRenderer> renderer;
vtkSmartPointer<vtkSphereSource> SS1;
vtkSmartPointer<vtkDataSetMapper> sMap;
vtkSmartPointer<vtkPolyData> emptyPD;

#define MY_CREATE_NEW(class, variable)\
  vtkSmartPointer<class> variable = vtkSmartPointer<class>::New();

static void EndPick(vtkObject *vtkNotUsed( caller ),
                    unsigned long vtkNotUsed(eventId),
                    void *, void *)
{
  MY_CREATE_NEW(vtkHardwareSelector, sel);
  sel->SetRenderer(renderer);

  double x0 = renderer->GetPickX1();
  double y0 = renderer->GetPickY1();
  double x1 = renderer->GetPickX2();
  double y1 = renderer->GetPickY2();

  sel->SetArea(static_cast<int>(x0),static_cast<int>(y0),static_cast<int>(x1),
               static_cast<int>(y1));
  vtkSmartPointer<vtkSelection> res;
  res.TakeReference(sel->Select());
  if (!res)
    {
    cerr << "Selection not supported." << endl;
    return;
    }

  /*
  cerr << "x0 " << x0 << " y0 " << y0 << "\t";
  cerr << "x1 " << x1 << " y1 " << y1 << endl;
  vtkIdTypeArray *a = vtkIdTypeArray::New();
  sel->GetSelectedIds(a);
  cerr << "numhits = " << a->GetNumberOfTuples() << endl;
  sel->PrintSelectedIds(a);
  a->Delete();
  */

  vtkSelection *cellids = res->GetChild(0);
  MY_CREATE_NEW(vtkExtractSelectedPolyDataIds, extr);
  if (cellids)
    {
    extr->SetInput(0, SS1->GetOutput());
    extr->SetInput(1, cellids);
    extr->Update();
    sMap->SetInput(extr->GetOutput());
    }
  else
    {
    cerr << "Empty color buffer selection -" << endl;
    cerr << "Check display color depth. Must be at least 24 bit." << endl;
    sMap->SetInput(emptyPD);
    }
}

int TestAreaSelections(int argc, char* argv[])
{
  // Standard rendering classes
  renderer = vtkSmartPointer<vtkRenderer>::New();
  MY_CREATE_NEW(vtkRenderWindow, renWin);
  renWin->AddRenderer(renderer);
  MY_CREATE_NEW(vtkRenderWindowInteractor, iren);
  iren->SetRenderWindow(renWin);

  //set up the view
  renderer->GetActiveCamera()->SetPosition(  1.5, -0.75, 7);
  renderer->GetActiveCamera()->SetFocalPoint(1.5, -0.75, 0);
  renderer->GetActiveCamera()->SetViewUp(     0,   1,   0);
  renderer->SetBackground(0.0,0.0,0.0);
  renWin->SetSize(300,300);

  //use the rubber band pick interactor style
  vtkRenderWindowInteractor* rwi = renWin->GetInteractor();
  MY_CREATE_NEW(vtkInteractorStyleRubberBandPick, rbp);
  rwi->SetInteractorStyle(rbp);

  MY_CREATE_NEW(vtkRenderedAreaPicker, areaPicker);
  rwi->SetPicker(areaPicker);

  ////////////////////////////////////////////////////////////
  //Create a unstructured grid data source to test FrustumExtractor with.
  MY_CREATE_NEW(vtkDataSetReader, reader);
  char *cfname=vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/SampleStructGrid.vtk");
  reader->SetFileName(cfname);

  MY_CREATE_NEW(vtkDataSetMapper, map1);
  map1->SetInput(reader->GetOutput());

  MY_CREATE_NEW(vtkActor, act1);
  act1->SetMapper(map1);
  act1->PickableOff(); //prevents the visible cell selector from trying
  renderer->AddActor(act1);

  //frustum extractor works on geometry and doesn't care about pickability
  MY_CREATE_NEW(vtkExtractSelectedFrustum, extractor);
  extractor->SetInputConnection(reader->GetOutputPort());
  extractor->PreserveTopologyOff();
  extractor->SetFrustum(areaPicker->GetFrustum());

  MY_CREATE_NEW(vtkDataSetMapper, eMap);
  eMap->SetInput(vtkDataSet::SafeDownCast(extractor->GetOutput()));

  MY_CREATE_NEW(vtkActor, eAct);
  eAct->SetPosition(2,0,0);
  eAct->SetMapper(eMap);
  eAct->PickableOff();
  renderer->AddActor(eAct);

  ////////////////////////////////////////////////////////////
  emptyPD = vtkSmartPointer<vtkPolyData>::New();

  int res = 20;
  SS1 = vtkSmartPointer<vtkSphereSource>::New();
  SS1->SetThetaResolution(res);
  SS1->SetPhiResolution(res);
  SS1->SetRadius(0.5);
  SS1->SetCenter(0.5,-1.5,0);
  MY_CREATE_NEW(vtkPolyDataMapper, map2);
  map2->SetInput(SS1->GetOutput());

  MY_CREATE_NEW(vtkActor, act2);
  act2->SetMapper(map2);
  act2->PickableOn(); //lets the HardwareSelector select in it
  renderer->AddActor(act2);

  sMap = vtkSmartPointer<vtkDataSetMapper>::New();
  sMap->SetInput(SS1->GetOutput());

  MY_CREATE_NEW(vtkActor, sAct);
  sAct->SetMapper(sMap);
  sAct->SetPosition(2,0,0);
  sAct->PickableOff();
  renderer->AddActor(sAct);

  //pass pick events to the HardwareSelector
  MY_CREATE_NEW(vtkCallbackCommand, cbc);
  cbc->SetCallback(EndPick);
  cbc->SetClientData(renderer);
  rwi->AddObserver(vtkCommand::EndPickEvent,cbc);

  ////////////////////////////////////////////////////////////

  //run the test

  renWin->Render();
  areaPicker->AreaPick(51,78,82,273,renderer);
  EndPick(NULL, 0, NULL, NULL);
  renWin->Render();

  int retVal = vtkRegressionTestImage( renWin );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    iren->Start();
    }

  // Cleanup
  delete [] cfname;
  return !retVal;
}
<commit_msg>BUG: Pass the test if hardware does not support selection.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestAreaSelections.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// This tests vtkHardwareSelector, vtkExtractSelectedFrustum,
// vtkRenderedAreaPicker, and vtkInteractorStyleRubberBandPick.
//
// The command line arguments are:
// -I        => run in interactive mode; unless this is used, the program will
//              not allow interaction and exit

#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"

#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkInteractorStyleRubberBandPick.h"
#include "vtkCallbackCommand.h"
#include "vtkHardwareSelector.h"
#include "vtkSelection.h"
#include "vtkExtractSelectedPolyDataIds.h"
#include "vtkIdTypeArray.h"
#include "vtkRenderedAreaPicker.h"
#include "vtkCamera.h"
#include "vtkImageMandelbrotSource.h"
#include "vtkImageActor.h"
#include "vtkExtractSelectedFrustum.h"
#include "vtkDataSetMapper.h"
#include "vtkSmartPointer.h"

#include "vtkDataSetReader.h"

vtkSmartPointer<vtkRenderer> renderer;
vtkSmartPointer<vtkSphereSource> SS1;
vtkSmartPointer<vtkDataSetMapper> sMap;
vtkSmartPointer<vtkPolyData> emptyPD;

#define MY_CREATE_NEW(class, variable)\
  vtkSmartPointer<class> variable = vtkSmartPointer<class>::New();

static void EndPick(vtkObject *vtkNotUsed( caller ),
                    unsigned long vtkNotUsed(eventId),
                    void *, void *)
{
  MY_CREATE_NEW(vtkHardwareSelector, sel);
  sel->SetRenderer(renderer);

  double x0 = renderer->GetPickX1();
  double y0 = renderer->GetPickY1();
  double x1 = renderer->GetPickX2();
  double y1 = renderer->GetPickY2();

  sel->SetArea(static_cast<int>(x0),static_cast<int>(y0),static_cast<int>(x1),
               static_cast<int>(y1));
  vtkSmartPointer<vtkSelection> res;
  res.TakeReference(sel->Select());
  if (!res)
    {
    cerr << "Selection not supported." << endl;
    return;
    }

  /*
  cerr << "x0 " << x0 << " y0 " << y0 << "\t";
  cerr << "x1 " << x1 << " y1 " << y1 << endl;
  vtkIdTypeArray *a = vtkIdTypeArray::New();
  sel->GetSelectedIds(a);
  cerr << "numhits = " << a->GetNumberOfTuples() << endl;
  sel->PrintSelectedIds(a);
  a->Delete();
  */

  vtkSelection *cellids = res->GetChild(0);
  MY_CREATE_NEW(vtkExtractSelectedPolyDataIds, extr);
  if (cellids)
    {
    extr->SetInput(0, SS1->GetOutput());
    extr->SetInput(1, cellids);
    extr->Update();
    sMap->SetInput(extr->GetOutput());
    }
  else
    {
    cerr << "Empty color buffer selection -" << endl;
    cerr << "Check display color depth. Must be at least 24 bit." << endl;
    sMap->SetInput(emptyPD);
    }
}

int TestAreaSelections(int argc, char* argv[])
{
  // Standard rendering classes
  renderer = vtkSmartPointer<vtkRenderer>::New();
  MY_CREATE_NEW(vtkRenderWindow, renWin);
  renWin->AddRenderer(renderer);
  MY_CREATE_NEW(vtkRenderWindowInteractor, iren);
  iren->SetRenderWindow(renWin);

  //set up the view
  renderer->GetActiveCamera()->SetPosition(  1.5, -0.75, 7);
  renderer->GetActiveCamera()->SetFocalPoint(1.5, -0.75, 0);
  renderer->GetActiveCamera()->SetViewUp(     0,   1,   0);
  renderer->SetBackground(0.0,0.0,0.0);
  renWin->SetSize(300,300);

  //use the rubber band pick interactor style
  vtkRenderWindowInteractor* rwi = renWin->GetInteractor();
  MY_CREATE_NEW(vtkInteractorStyleRubberBandPick, rbp);
  rwi->SetInteractorStyle(rbp);

  MY_CREATE_NEW(vtkRenderedAreaPicker, areaPicker);
  rwi->SetPicker(areaPicker);

  ////////////////////////////////////////////////////////////
  //Create a unstructured grid data source to test FrustumExtractor with.
  MY_CREATE_NEW(vtkDataSetReader, reader);
  char *cfname=vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/SampleStructGrid.vtk");
  reader->SetFileName(cfname);
  delete [] cfname;

  MY_CREATE_NEW(vtkDataSetMapper, map1);
  map1->SetInput(reader->GetOutput());

  MY_CREATE_NEW(vtkActor, act1);
  act1->SetMapper(map1);
  act1->PickableOff(); //prevents the visible cell selector from trying
  renderer->AddActor(act1);

  //frustum extractor works on geometry and doesn't care about pickability
  MY_CREATE_NEW(vtkExtractSelectedFrustum, extractor);
  extractor->SetInputConnection(reader->GetOutputPort());
  extractor->PreserveTopologyOff();
  extractor->SetFrustum(areaPicker->GetFrustum());

  MY_CREATE_NEW(vtkDataSetMapper, eMap);
  eMap->SetInput(vtkDataSet::SafeDownCast(extractor->GetOutput()));

  MY_CREATE_NEW(vtkActor, eAct);
  eAct->SetPosition(2,0,0);
  eAct->SetMapper(eMap);
  eAct->PickableOff();
  renderer->AddActor(eAct);

  ////////////////////////////////////////////////////////////
  emptyPD = vtkSmartPointer<vtkPolyData>::New();

  int res = 20;
  SS1 = vtkSmartPointer<vtkSphereSource>::New();
  SS1->SetThetaResolution(res);
  SS1->SetPhiResolution(res);
  SS1->SetRadius(0.5);
  SS1->SetCenter(0.5,-1.5,0);
  MY_CREATE_NEW(vtkPolyDataMapper, map2);
  map2->SetInput(SS1->GetOutput());

  MY_CREATE_NEW(vtkActor, act2);
  act2->SetMapper(map2);
  act2->PickableOn(); //lets the HardwareSelector select in it
  renderer->AddActor(act2);

  sMap = vtkSmartPointer<vtkDataSetMapper>::New();
  sMap->SetInput(SS1->GetOutput());

  MY_CREATE_NEW(vtkActor, sAct);
  sAct->SetMapper(sMap);
  sAct->SetPosition(2,0,0);
  sAct->PickableOff();
  renderer->AddActor(sAct);

  //pass pick events to the HardwareSelector
  MY_CREATE_NEW(vtkCallbackCommand, cbc);
  cbc->SetCallback(EndPick);
  cbc->SetClientData(renderer);
  rwi->AddObserver(vtkCommand::EndPickEvent,cbc);

  ////////////////////////////////////////////////////////////

  //run the test

  renWin->Render();
  int rgba[4];
  renWin->GetColorBufferSizes(rgba);
  if (rgba[0] < 8 || rgba[1] < 8 || rgba[2] < 8)
    {
    cout <<"Color buffer depth must be atleast 8 bit. Currently: "
      << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << endl;
    return 0;
    }

  areaPicker->AreaPick(51,78,82,273,renderer);
  EndPick(NULL, 0, NULL, NULL);
  renWin->Render();

  int retVal = vtkRegressionTestImage( renWin );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    iren->Start();
    }

  // Cleanup
  return !retVal;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdlib.h>
#include <unistd.h>

#define HEIGHT 50
#define WIDTH 50
#define UPDATELENGTH 150000

int board[HEIGHT][WIDTH];

int weightedarray[10] = {0,0,0,0,0,0,0,0,1};

void genBoard(int (board)[HEIGHT][WIDTH]) {
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {
	    board[x][y] = weightedarray[rand() % 10];
	}
    }
}

void copyBoard(int (newB)[HEIGHT][WIDTH], int (oldB)[HEIGHT][WIDTH]) {
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {
	    newB[x][y] = oldB[x][y];
	}
    }
}

void updateBoard(int (board)[HEIGHT][WIDTH]) {
    int next_board[HEIGHT][WIDTH];
    copyBoard(next_board, board);
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {

	    if ((x == 0 || x == HEIGHT) ||
		(y == 0 || y == WIDTH)) {
		continue;
	    }

	    int aliveN = 0;
	    int deadN = 0;
	    if (!board[x-1][y+1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x][y+1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x+1][y+1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x+1][y]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x+1][y-1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x][y-1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x-1][y-1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x-1][y]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    /*
	      Rules
	      =====

	      1. Any live cell with fewer than two live neighbours
	         dies, as if caused by under-population.

	      2. Any live cell with two or three live neighbours lives
	         on to the next generation.

	      3. Any live cell with more than three live neighbours
	         dies, as if by overcrowding.

	      4. Any dead cell with exactly three live neighbours
	         becomes a live cell, as if by reproduction.
	    */
	    if ((board[x][y] && aliveN < 2)) {
		next_board[x][y] = 0;
		continue;
	    }
	    if ((board[x][y]) && ((aliveN == 2) || (aliveN == 3)))
		continue;
	    if ((board[x][y]) && (aliveN > 3)) {
		next_board[x][y] = 0;
		continue;
	    }
	    if ((!board[x][y]) && (aliveN == 3)) {
		next_board[x][y] = 1;
		continue;
	    }
	}
    }
    copyBoard(board, next_board);
}

void drawBoard(int (board)[HEIGHT][WIDTH]) {
    std::cout << "\033[2J\033[1;1H";
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {
	    if (board[x][y] == 0) {
		std::cout << ".";
	    } else {
		std::cout << "*";
	    }
	}
	std::cout << std::endl;
    }
}

int main() {
    genBoard(board);
    while (1) {
	updateBoard(board);
	drawBoard(board);
	usleep(UPDATELENGTH);
    }
    return 0;
}
<commit_msg>Changed gol weighting<commit_after>#include <iostream>
#include <stdlib.h>
#include <unistd.h>

#define HEIGHT 50
#define WIDTH 50
#define UPDATELENGTH 150000

int board[HEIGHT][WIDTH];

int weightedarray[10] = {0,0,0,0,0,0,0,1,1};

void genBoard(int (board)[HEIGHT][WIDTH]) {
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {
	    board[x][y] = weightedarray[rand() % 10];
	}
    }
}

void copyBoard(int (newB)[HEIGHT][WIDTH], int (oldB)[HEIGHT][WIDTH]) {
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {
	    newB[x][y] = oldB[x][y];
	}
    }
}

void updateBoard(int (board)[HEIGHT][WIDTH]) {
    int next_board[HEIGHT][WIDTH];
    copyBoard(next_board, board);
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {

	    if ((x == 0 || x == HEIGHT) ||
		(y == 0 || y == WIDTH)) {
		continue;
	    }

	    int aliveN = 0;
	    int deadN = 0;
	    if (!board[x-1][y+1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x][y+1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x+1][y+1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x+1][y]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x+1][y-1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x][y-1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x-1][y-1]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    if (!board[x-1][y]) {
		deadN++;
	    } else {
		aliveN++;
	    }
	    /*
	      Rules
	      =====

	      1. Any live cell with fewer than two live neighbours
	         dies, as if caused by under-population.

	      2. Any live cell with two or three live neighbours lives
	         on to the next generation.

	      3. Any live cell with more than three live neighbours
	         dies, as if by overcrowding.

	      4. Any dead cell with exactly three live neighbours
	         becomes a live cell, as if by reproduction.
	    */
	    if ((board[x][y] && aliveN < 2)) {
		next_board[x][y] = 0;
		continue;
	    }
	    if ((board[x][y]) && ((aliveN == 2) || (aliveN == 3)))
		continue;
	    if ((board[x][y]) && (aliveN > 3)) {
		next_board[x][y] = 0;
		continue;
	    }
	    if ((!board[x][y]) && (aliveN == 3)) {
		next_board[x][y] = 1;
		continue;
	    }
	}
    }
    copyBoard(board, next_board);
}

void drawBoard(int (board)[HEIGHT][WIDTH]) {
    std::cout << "\033[2J\033[1;1H";
    for (int x = 0; x < HEIGHT; ++x) {
	for (int y = 0; y < WIDTH; ++y) {
	    if (board[x][y] == 0) {
		std::cout << ".";
	    } else {
		std::cout << "*";
	    }
	}
	std::cout << std::endl;
    }
}

int main() {
    genBoard(board);
    while (1) {
	updateBoard(board);
	drawBoard(board);
	usleep(UPDATELENGTH);
    }
    return 0;
}
<|endoftext|>


<commit_before>// @(#)root/ged:$Name:  $:$Id: TStylePreview.cxx,v 1.0 2005/09/08
// Author: Denis Favre-Miville   08/09/05

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TStylePreview                                                       //
//                                                                      //
//  This class may be used to preview the result of applying a style    //
//       to a canvas. The result is shown on a clone of the object,     //
//       in a different shown over the initial canvas.                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStylePreview.h"
#include "TStyleManager.h"

#include <TCanvas.h>
#include <TRootEmbeddedCanvas.h>
#include <TStyle.h>

ClassImp(TStylePreview)

//______________________________________________________________________________
TStylePreview::TStylePreview(const TGWindow *p, TStyle *style,
                              TVirtualPad *currentPad)
                     : TGTransientFrame(0, p)
{
   //  Constructor. Create a new window and draw a clone of
   // currentPad->GetCanvas() in it, using the style 'style'.
   //  Thanks to that method, one can have a preview of any
   // style with any object.

   fPad = 0;

   // Create the main window.
   SetWindowName("Style Manager's Preview");
   SetCleanup(kNoCleanup);
   DontCallClose();

   // Create the trash lists to have an effective deletion of every object.
   fTrashListLayout = new TList();

   // Create the layouts and add them to the layout trash list.
   TGLayoutHints *layoutXY = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
   fTrashListLayout->Add(layoutXY);

   // Create a canvas for the preview.
   fEcan = new TRootEmbeddedCanvas("TSMPreviewCanvas", this, 10, 10);
   AddFrame(fEcan, layoutXY);

   // Draw the preview.
   Update(style, currentPad);

   // Map main frame.
   MapTheWindow();

   // No modifications allowed in the preview.
   fEcan->GetCanvas()->SetEditable(kFALSE);
   fEcan->GetCanvas()->SetBit(kNoContextMenu);
}

//______________________________________________________________________________
TStylePreview::~TStylePreview()
{
   // Destructor.

   // Delete all the widgets created in this class.
   delete fEcan;

   // Delete all the layouts.
   TObject *obj1;
   TObject *obj2;
   obj1 = fTrashListLayout->First();
   while (obj1) {
      obj2 = fTrashListLayout->After(obj1);
      fTrashListLayout->Remove(obj1);
      delete obj1;
      obj1 = obj2;
   }
   delete fTrashListLayout;
}

//______________________________________________________________________________
void TStylePreview::Update(TStyle *style, TVirtualPad *pad)
{
   //  Update the preview, with possibly another style and another object
   // than previously.

   TCanvas *c;
   if (pad != fPad) {
      delete fEcan->GetCanvas();
      fEcan->AdoptCanvas(new TCanvas("TSMPreviewCanvas", 10, 10,
                                       fEcan->GetCanvasWindowId()));
      c = fEcan->GetCanvas();
      gROOT->SetSelectedPad(c);
      pad->GetCanvas()->DrawClonePad();
      gROOT->SetSelectedPad(pad);
      fPad = pad;
   }

   // Apply the 'style' to the clone of 'pad'.
   c = fEcan->GetCanvas();
   TStyle *tmpStyle = gStyle;
   gStyle = style;
   c->UseCurrentStyle();
   gStyle = tmpStyle;
   c->Modified();
   c->Update();
}

//______________________________________________________________________________
void TStylePreview::MapTheWindow()
{
   // Initialize the layout algorithm.

   MapSubwindows();
   TCanvas *c = fPad->GetCanvas();
   UInt_t w = c->GetWindowWidth();
   UInt_t h = c->GetWindowHeight() - 24;
   UInt_t x = (UInt_t) c->GetWindowTopX() + 60;
   UInt_t y = (UInt_t) c->GetWindowTopY() + 100;

   MoveResize(x, y, w, h);
   SetWMPosition(x, y);

   MapWindow();
}

//______________________________________________________________________________
TCanvas *TStylePreview::GetMainCanvas()
{
   // return pointer to the selected canvas.

   return fEcan->GetCanvas();
}
<commit_msg>From Ilka: - fix of preview window wrong width and height when the user interface around the canvas window were activated (editor, toolbar, status bar).<commit_after>// @(#)root/ged:$Name:  $:$Id: TStylePreview.cxx,v 1.0 2005/09/08
// Author: Denis Favre-Miville   08/09/05

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TStylePreview                                                       //
//                                                                      //
//  This class may be used to preview the result of applying a style    //
//       to a canvas. The result is shown on a clone of the object,     //
//       in a different shown over the initial canvas.                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStylePreview.h"
#include "TStyleManager.h"

#include <TCanvas.h>
#include <TRootEmbeddedCanvas.h>
#include <TStyle.h>

ClassImp(TStylePreview)

//______________________________________________________________________________
TStylePreview::TStylePreview(const TGWindow *p, TStyle *style,
                              TVirtualPad *currentPad)
                     : TGTransientFrame(0, p)
{
   //  Constructor. Create a new window and draw a clone of
   // currentPad->GetCanvas() in it, using the style 'style'.
   //  Thanks to that method, one can have a preview of any
   // style with any object.

   fPad = 0;

   // Create the main window.
   SetWindowName("Style Manager's Preview");
   SetCleanup(kNoCleanup);
   DontCallClose();

   // Create the trash lists to have an effective deletion of every object.
   fTrashListLayout = new TList();

   // Create the layouts and add them to the layout trash list.
   TGLayoutHints *layoutXY = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
   fTrashListLayout->Add(layoutXY);

   // Create a canvas for the preview.
   fEcan = new TRootEmbeddedCanvas("TSMPreviewCanvas", this, 10, 10);
   AddFrame(fEcan, layoutXY);

   // Draw the preview.
   Update(style, currentPad);

   // Map main frame.
   MapTheWindow();

   // No modifications allowed in the preview.
   fEcan->GetCanvas()->SetEditable(kFALSE);
   fEcan->GetCanvas()->SetBit(kNoContextMenu);
}

//______________________________________________________________________________
TStylePreview::~TStylePreview()
{
   // Destructor.

   // Delete all the widgets created in this class.
   delete fEcan;

   // Delete all the layouts.
   TObject *obj1;
   TObject *obj2;
   obj1 = fTrashListLayout->First();
   while (obj1) {
      obj2 = fTrashListLayout->After(obj1);
      fTrashListLayout->Remove(obj1);
      delete obj1;
      obj1 = obj2;
   }
   delete fTrashListLayout;
}

//______________________________________________________________________________
void TStylePreview::Update(TStyle *style, TVirtualPad *pad)
{
   // Update the preview with possibly another style and
   // another object than previously.

   TCanvas *c;
   if (pad != fPad) {
      delete fEcan->GetCanvas();
      fEcan->AdoptCanvas(new TCanvas("TSMPreviewCanvas", 10, 10,
                                       fEcan->GetCanvasWindowId()));
      c = fEcan->GetCanvas();
      gROOT->SetSelectedPad(c);
      pad->GetCanvas()->DrawClonePad();
      gROOT->SetSelectedPad(pad);
      fPad = pad;
   }

   // Apply the 'style' to the clone of 'pad'.
   c = fEcan->GetCanvas();
   TStyle *tmpStyle = gStyle;
   gStyle = style;
   c->UseCurrentStyle();
   gStyle = tmpStyle;
   c->Modified();
   c->Update();
}

//______________________________________________________________________________
void TStylePreview::MapTheWindow()
{
   // Initialize the layout algorithm.

   MapSubwindows();
   TCanvas *c = fPad->GetCanvas();
   UInt_t w = c->GetWw() + 4; //4 pixels of borders
   UInt_t h = c->GetWh() + 4; //4 pixels of borders
   UInt_t x = (UInt_t) c->GetWindowTopX() + 60;
   UInt_t y = (UInt_t) c->GetWindowTopY() + 100;

   MoveResize(x, y, w, h);
   SetWMPosition(x, y);

   MapWindow();
}

//______________________________________________________________________________
TCanvas *TStylePreview::GetMainCanvas()
{
   // Return pointer to the selected canvas.

   return fEcan->GetCanvas();
}
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <visionaray/gl/util.h>
#include <visionaray/math/math.h>

#include "../util.h"

namespace gl = visionaray::gl;

namespace visionaray
{

std::string gl::last_error()
{
    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
    {
#if VSNRAY_HAVE_GLEW
        return std::string(reinterpret_cast<char const*>(glewGetErrorString(err)));
#endif
    }
    return "";
}

void gl::alloc_texture(pixel_format_info info, GLsizei w, GLsizei h)
{
    if (glTexStorage2D)
    {
        glTexStorage2D(GL_TEXTURE_2D, 1, info.internal_format, w, h);
    }
    else
    {
        glTexImage2D(GL_TEXTURE_2D, 0, info.internal_format, w, h, 0, info.format, info.type, 0);
    }
}

void gl::update_texture(
        pixel_format_info   info,
        GLsizei             x,
        GLsizei             y,
        GLsizei             w,
        GLsizei             h,
        GLvoid const*       pixels
        )
{
    glTexSubImage2D(
            GL_TEXTURE_2D,
            0, // TODO
            x,
            y,
            w,
            h,
            info.format,
            info.type,
            pixels
            );
}

void gl::update_texture(
        pixel_format_info   info,
        GLsizei             w,
        GLsizei             h,
        GLvoid const*       pixels
        )
{
    glTexSubImage2D(
            GL_TEXTURE_2D,
            0, // TODO
            0,
            0,
            w,
            h,
            info.format,
            info.type,
            pixels
            );
}

void gl::draw_full_screen_quad()
{
    glPushAttrib(GL_TEXTURE_BIT | GL_TRANSFORM_BIT);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glActiveTexture(GL_TEXTURE0);

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
    glEnd();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glPopAttrib();
}

void gl::blend_texture(GLuint texture, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    glActiveTexture(GL_TEXTURE0);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);

    glDepthMask(GL_FALSE);
    glDisable(GL_LIGHTING);

    draw_full_screen_quad();

    glPopAttrib();
}

#if defined(VSNRAY_OPENGL_LEGACY)
void gl::blend_pixels(GLsizei w, GLsizei h, GLenum format, GLenum type, GLvoid const* pixels, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    recti vp = gl::viewport();
    glWindowPos2i(vp[0], vp[1]);

    GLfloat scalex = vp[2] / static_cast<GLfloat>(w);
    GLfloat scaley = vp[3] / static_cast<GLfloat>(h);

    glPixelZoom(scalex, scaley);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glDrawPixels(w, h, format, type, pixels);

    glPopAttrib();
}
#endif

recti gl::viewport()
{
    GLint vp[4];
    glGetIntegerv(GL_VIEWPORT, &vp[0]);
    return recti(vp[0], vp[1], vp[2], vp[3]);
}

} // visionaray
<commit_msg>More OpenGLES 2.0 compatibility<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <visionaray/gl/util.h>
#include <visionaray/math/math.h>

#include "../util.h"

namespace gl = visionaray::gl;

namespace visionaray
{

std::string gl::last_error()
{
    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
    {
#if VSNRAY_HAVE_GLEW
        return std::string(reinterpret_cast<char const*>(glewGetErrorString(err)));
#endif
    }
    return "";
}

void gl::alloc_texture(pixel_format_info info, GLsizei w, GLsizei h)
{
#if defined(GL_VERSION_4_2) && GL_VERSION_4_2 || defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0
    if (glTexStorage2D)
    {
        glTexStorage2D(GL_TEXTURE_2D, 1, info.internal_format, w, h);
    }
    else
#endif
    {
        glTexImage2D(GL_TEXTURE_2D, 0, info.internal_format, w, h, 0, info.format, info.type, 0);
    }
}

void gl::update_texture(
        pixel_format_info   info,
        GLsizei             x,
        GLsizei             y,
        GLsizei             w,
        GLsizei             h,
        GLvoid const*       pixels
        )
{
    glTexSubImage2D(
            GL_TEXTURE_2D,
            0, // TODO
            x,
            y,
            w,
            h,
            info.format,
            info.type,
            pixels
            );
}

void gl::update_texture(
        pixel_format_info   info,
        GLsizei             w,
        GLsizei             h,
        GLvoid const*       pixels
        )
{
    glTexSubImage2D(
            GL_TEXTURE_2D,
            0, // TODO
            0,
            0,
            w,
            h,
            info.format,
            info.type,
            pixels
            );
}

void gl::draw_full_screen_quad()
{
    glPushAttrib(GL_TEXTURE_BIT | GL_TRANSFORM_BIT);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glActiveTexture(GL_TEXTURE0);

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
    glEnd();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glPopAttrib();
}

void gl::blend_texture(GLuint texture, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    glActiveTexture(GL_TEXTURE0);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);

    glDepthMask(GL_FALSE);
    glDisable(GL_LIGHTING);

    draw_full_screen_quad();

    glPopAttrib();
}

#if defined(VSNRAY_OPENGL_LEGACY)
void gl::blend_pixels(GLsizei w, GLsizei h, GLenum format, GLenum type, GLvoid const* pixels, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    recti vp = gl::viewport();
    glWindowPos2i(vp[0], vp[1]);

    GLfloat scalex = vp[2] / static_cast<GLfloat>(w);
    GLfloat scaley = vp[3] / static_cast<GLfloat>(h);

    glPixelZoom(scalex, scaley);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glDrawPixels(w, h, format, type, pixels);

    glPopAttrib();
}
#endif

recti gl::viewport()
{
    GLint vp[4];
    glGetIntegerv(GL_VIEWPORT, &vp[0]);
    return recti(vp[0], vp[1], vp[2], vp[3]);
}

} // visionaray
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                               Simbody(tm)                                  *
 * -------------------------------------------------------------------------- *
 * This is part of the SimTK biosimulation toolkit originating from           *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
 *                                                                            *
 * Portions copyright (c) 2008-12 Stanford University and the Authors.        *
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

#include "SimTKsimbody.h"

using namespace SimTK;
using namespace std;

const Real TOL = 1e-5;

#define ASSERT(cond) {SimTK_ASSERT_ALWAYS(cond, "Assertion failed");}

template <class T>
void assertEqual(T val1, T val2) {
    ASSERT(abs(val1-val2) < TOL || abs(val1-val2)/max(abs(val1), abs(val2)) < TOL);
}

template <int N>
void assertEqual(Vec<N> val1, Vec<N> val2) {
    for (int i = 0; i < N; ++i)
        assertEqual(val1[i], val2[i]);
}

void testForces() {
    MultibodySystem system;
    SimbodyMatterSubsystem matter(system);
    GeneralContactSubsystem contacts(system);
    GeneralForceSubsystem forces(system);

    // Create a triangle mesh in the shape of a pyramid, with the
    // square base having area 1 (split into two triangles).

    vector<Vec3> vertices;
    vertices.push_back(Vec3(0, 0, 0));
    vertices.push_back(Vec3(1, 0, 0));
    vertices.push_back(Vec3(1, 0, 1));
    vertices.push_back(Vec3(0, 0, 1));
    vertices.push_back(Vec3(0.5, 1, 0.5));
    vector<int> faceIndices;
    int faces[6][3] = {{0, 1, 2}, {0, 2, 3}, {1, 0, 4},
                       {2, 1, 4}, {3, 2, 4}, {0, 3, 4}};
    for (int i = 0; i < 6; i++)
        for (int j = 0; j < 3; j++)
            faceIndices.push_back(faces[i][j]);

    // Create the mobilized bodies and configure the contact model.

    Body::Rigid body(MassProperties(1.0, Vec3(0), Inertia(1)));
    ContactSetIndex setIndex = contacts.createContactSet();
    MobilizedBody::Translation mesh(matter.updGround(), Transform(), body, Transform());
    contacts.addBody(setIndex, mesh, ContactGeometry::TriangleMesh(vertices, faceIndices), Transform());
    contacts.addBody(setIndex, matter.updGround(), ContactGeometry::HalfSpace(), Transform(Rotation(-0.5*Pi, ZAxis), Vec3(0))); // y < 0
    ElasticFoundationForce ef(forces, contacts, setIndex);
    Real stiffness = 1e9, dissipation = 0.01, us = 0.1, ud = 0.05, uv = 0.01, vt = 0.01;
    ef.setBodyParameters(ContactSurfaceIndex(0), stiffness, dissipation, us, ud, uv);
    ef.setTransitionVelocity(vt);
    ASSERT(ef.getTransitionVelocity() == vt);
    State state = system.realizeTopology();

    // Position the pyramid at a variety of positions and check the normal
    // force.

    for (Real depth = -0.1; depth < 0.1; depth += 0.01) {
        mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
        system.realize(state, Stage::Dynamics);
        Real f = 0;
        if (depth > 0)
            f = stiffness*depth;
        assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()][1], Vec3(0, f, 0));
        assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[matter.getGround().getMobilizedBodyIndex()][1], Vec3(0, -f, 0));
    }

    // Now do it with a vertical velocity and see if the dissipation force is correct.

    for (Real depth = -0.105; depth < 0.1; depth += 0.01) {
        mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
        for (Real v = -1.0; v <= 1.0; v += 0.1) {
            mesh.setUToFitLinearVelocity(state, Vec3(0, -v, 0));
            system.realize(state, Stage::Dynamics);
            Real f = (depth > 0 ? stiffness*depth*(1+dissipation*v) : 0);
            if (f < 0)
                f = 0;
            assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()][1], Vec3(0, f, 0));
        }
    }

    // Do it with a horizontal velocity and see if the friction force is correct.

    Vector_<SpatialVec> expectedForce(matter.getNumBodies());
    for (Real depth = -0.105; depth < 0.1; depth += 0.01) {
        mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
        Real fh = 0;
        if (depth > 0)
            fh = stiffness*depth;
        for (Real v = -1.0; v <= 1.0; v += 0.1) {
            mesh.setUToFitLinearVelocity(state, Vec3(v, 0, 0));
            system.realize(state, Stage::Dynamics);
            const Real vrel = std::abs(v/vt);
            Real ff = (v < 0 ? 1 : -1)*fh*(std::min(vrel, 1.0)*(ud+2*(us-ud)/(1+vrel*vrel))+uv*std::fabs(v));
            const Vec3 totalForce = Vec3(ff, fh, 0);
            expectedForce = SpatialVec(Vec3(0), Vec3(0));
            Vec3 contactPoint1 = mesh.findStationAtGroundPoint(state, Vec3(2.0/3.0, 0, 1.0/3.0));
            mesh.applyForceToBodyPoint(state, contactPoint1, 0.5*totalForce, expectedForce);
            Vec3 contactPoint2 = mesh.findStationAtGroundPoint(state, Vec3(1.0/3.0, 0, 2.0/3.0));
            mesh.applyForceToBodyPoint(state, contactPoint2, 0.5*totalForce, expectedForce);
            SpatialVec actualForce = system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()];
            assertEqual(actualForce[0], expectedForce[mesh.getMobilizedBodyIndex()][0]);
            assertEqual(actualForce[1], expectedForce[mesh.getMobilizedBodyIndex()][1]);
        }
    }
}

int main() {
    try {
        testForces();
    }
    catch(const std::exception& e) {
        cout << "exception: " << e.what() << endl;
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}
<commit_msg>[master] Removed trailing spaces in Simbody/tests/TestElasticFoundationForce.cpp<commit_after>/* -------------------------------------------------------------------------- *
 *                               Simbody(tm)                                  *
 * -------------------------------------------------------------------------- *
 * This is part of the SimTK biosimulation toolkit originating from           *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
 *                                                                            *
 * Portions copyright (c) 2008-12 Stanford University and the Authors.        *
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

#include "SimTKsimbody.h"

using namespace SimTK;
using namespace std;

const Real TOL = 1e-5;

#define ASSERT(cond) {SimTK_ASSERT_ALWAYS(cond, "Assertion failed");}

template <class T>
void assertEqual(T val1, T val2) {
    ASSERT(abs(val1-val2) < TOL || abs(val1-val2)/max(abs(val1), abs(val2)) < TOL);
}

template <int N>
void assertEqual(Vec<N> val1, Vec<N> val2) {
    for (int i = 0; i < N; ++i)
        assertEqual(val1[i], val2[i]);
}

void testForces() {
    MultibodySystem system;
    SimbodyMatterSubsystem matter(system);
    GeneralContactSubsystem contacts(system);
    GeneralForceSubsystem forces(system);

    // Create a triangle mesh in the shape of a pyramid, with the
    // square base having area 1 (split into two triangles).

    vector<Vec3> vertices;
    vertices.push_back(Vec3(0, 0, 0));
    vertices.push_back(Vec3(1, 0, 0));
    vertices.push_back(Vec3(1, 0, 1));
    vertices.push_back(Vec3(0, 0, 1));
    vertices.push_back(Vec3(0.5, 1, 0.5));
    vector<int> faceIndices;
    int faces[6][3] = {{0, 1, 2}, {0, 2, 3}, {1, 0, 4},
                       {2, 1, 4}, {3, 2, 4}, {0, 3, 4}};
    for (int i = 0; i < 6; i++)
        for (int j = 0; j < 3; j++)
            faceIndices.push_back(faces[i][j]);

    // Create the mobilized bodies and configure the contact model.

    Body::Rigid body(MassProperties(1.0, Vec3(0), Inertia(1)));
    ContactSetIndex setIndex = contacts.createContactSet();
    MobilizedBody::Translation mesh(matter.updGround(), Transform(), body, Transform());
    contacts.addBody(setIndex, mesh, ContactGeometry::TriangleMesh(vertices, faceIndices), Transform());
    contacts.addBody(setIndex, matter.updGround(), ContactGeometry::HalfSpace(), Transform(Rotation(-0.5*Pi, ZAxis), Vec3(0))); // y < 0
    ElasticFoundationForce ef(forces, contacts, setIndex);
    Real stiffness = 1e9, dissipation = 0.01, us = 0.1, ud = 0.05, uv = 0.01, vt = 0.01;
    ef.setBodyParameters(ContactSurfaceIndex(0), stiffness, dissipation, us, ud, uv);
    ef.setTransitionVelocity(vt);
    ASSERT(ef.getTransitionVelocity() == vt);
    State state = system.realizeTopology();

    // Position the pyramid at a variety of positions and check the normal
    // force.

    for (Real depth = -0.1; depth < 0.1; depth += 0.01) {
        mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
        system.realize(state, Stage::Dynamics);
        Real f = 0;
        if (depth > 0)
            f = stiffness*depth;
        assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()][1], Vec3(0, f, 0));
        assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[matter.getGround().getMobilizedBodyIndex()][1], Vec3(0, -f, 0));
    }

    // Now do it with a vertical velocity and see if the dissipation force is correct.

    for (Real depth = -0.105; depth < 0.1; depth += 0.01) {
        mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
        for (Real v = -1.0; v <= 1.0; v += 0.1) {
            mesh.setUToFitLinearVelocity(state, Vec3(0, -v, 0));
            system.realize(state, Stage::Dynamics);
            Real f = (depth > 0 ? stiffness*depth*(1+dissipation*v) : 0);
            if (f < 0)
                f = 0;
            assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()][1], Vec3(0, f, 0));
        }
    }

    // Do it with a horizontal velocity and see if the friction force is correct.

    Vector_<SpatialVec> expectedForce(matter.getNumBodies());
    for (Real depth = -0.105; depth < 0.1; depth += 0.01) {
        mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
        Real fh = 0;
        if (depth > 0)
            fh = stiffness*depth;
        for (Real v = -1.0; v <= 1.0; v += 0.1) {
            mesh.setUToFitLinearVelocity(state, Vec3(v, 0, 0));
            system.realize(state, Stage::Dynamics);
            const Real vrel = std::abs(v/vt);
            Real ff = (v < 0 ? 1 : -1)*fh*(std::min(vrel, 1.0)*(ud+2*(us-ud)/(1+vrel*vrel))+uv*std::fabs(v));
            const Vec3 totalForce = Vec3(ff, fh, 0);
            expectedForce = SpatialVec(Vec3(0), Vec3(0));
            Vec3 contactPoint1 = mesh.findStationAtGroundPoint(state, Vec3(2.0/3.0, 0, 1.0/3.0));
            mesh.applyForceToBodyPoint(state, contactPoint1, 0.5*totalForce, expectedForce);
            Vec3 contactPoint2 = mesh.findStationAtGroundPoint(state, Vec3(1.0/3.0, 0, 2.0/3.0));
            mesh.applyForceToBodyPoint(state, contactPoint2, 0.5*totalForce, expectedForce);
            SpatialVec actualForce = system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()];
            assertEqual(actualForce[0], expectedForce[mesh.getMobilizedBodyIndex()][0]);
            assertEqual(actualForce[1], expectedForce[mesh.getMobilizedBodyIndex()][1]);
        }
    }
}

int main() {
    try {
        testForces();
    }
    catch(const std::exception& e) {
        cout << "exception: " << e.what() << endl;
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}
<|endoftext|>


<commit_before>/*
 * test1.cpp
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include <LLGL/LLGL.h>
#include <memory>
#include <iostream>
#include <string>
#include <sstream>

int main()
{
    try
    {
        // Create window
        LLGL::WindowDesc windowDesc;

        windowDesc.title        = L"LLGL Test 1";
        windowDesc.visible      = true;
        windowDesc.centered     = true;
        windowDesc.resizable    = true;
        windowDesc.size         = { 640, 480 };

        auto window = LLGL::Window::Create(windowDesc);

        auto input = std::make_shared<LLGL::Input>();
        window->AddListener(input);

        auto timer = LLGL::Timer::Create();

        int x = 100, y = 100;
        window->SetPosition({ x, y });

        while (window->ProcessEvents() && !input->KeyPressed(LLGL::Key::Escape))
        {
            timer->MeasureTime();

            //std::cout << 1.0 / timer->GetDeltaTime() << std::endl;

            if (input->KeyPressed(LLGL::Key::Num1))
                window->Show(false);
            if (input->KeyPressed(LLGL::Key::Num2))
                window->Show(true);
            if (input->KeyPressed(LLGL::Key::Num3))
                window->SetTitle(L"FOO BAR");
            if (input->KeyPressed(LLGL::Key::Num4))
                window->SetTitle(L"LLGL Test 1");
            if (input->KeyPressed(LLGL::Key::Num5))
                window->SetSize({ 300, 300 });

            auto mousePos = input->GetMousePosition();
            std::wstringstream s;
            s << "X = " << mousePos.x << ", Y = " << mousePos.y;
            window->SetTitle(s.str());

            if (input->KeyPressed(LLGL::Key::Right))
            {
                ++x;
                window->SetPosition({ x, y });
            }
            if (input->KeyPressed(LLGL::Key::Left))
            {
                --x;
                window->SetPosition({ x, y });
            }
            if (input->KeyPressed(LLGL::Key::Up))
            {
                --y;
                window->SetPosition({ x, y });
            }
            if (input->KeyPressed(LLGL::Key::Down))
            {
                ++y;
                window->SetPosition({ x, y });
            }

        }
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}
<commit_msg>Commented out test section for Windows.<commit_after>/*
 * test1.cpp
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include <LLGL/LLGL.h>
#include <memory>
#include <iostream>
#include <string>
#include <sstream>

int main()
{
    try
    {
        // Create window
        LLGL::WindowDesc windowDesc;

        windowDesc.title        = L"LLGL Test 1";
        windowDesc.visible      = true;
        windowDesc.centered     = true;
        windowDesc.resizable    = true;
        windowDesc.size         = { 640, 480 };

        auto window = LLGL::Window::Create(windowDesc);

        auto input = std::make_shared<LLGL::Input>();
        window->AddListener(input);

        auto timer = LLGL::Timer::Create();

        int x = 100, y = 100;
        window->SetPosition({ x, y });

        while (window->ProcessEvents() && !input->KeyPressed(LLGL::Key::Escape))
        {
            timer->MeasureTime();

            //std::cout << 1.0 / timer->GetDeltaTime() << std::endl;

            if (input->KeyPressed(LLGL::Key::Num1))
                window->Show(false);
            if (input->KeyPressed(LLGL::Key::Num2))
                window->Show(true);
            if (input->KeyPressed(LLGL::Key::Num3))
                window->SetTitle(L"FOO BAR");
            if (input->KeyPressed(LLGL::Key::Num4))
                window->SetTitle(L"LLGL Test 1");
            if (input->KeyPressed(LLGL::Key::Num5))
                window->SetSize({ 300, 300 });

            #ifdef __APPLE__
            auto mousePos = input->GetMousePosition();
            std::wstringstream s;
            s << "X = " << mousePos.x << ", Y = " << mousePos.y;
            window->SetTitle(s.str());
            #endif

            if (input->KeyPressed(LLGL::Key::Right))
            {
                ++x;
                window->SetPosition({ x, y });
            }
            if (input->KeyPressed(LLGL::Key::Left))
            {
                --x;
                window->SetPosition({ x, y });
            }
            if (input->KeyPressed(LLGL::Key::Up))
            {
                --y;
                window->SetPosition({ x, y });
            }
            if (input->KeyPressed(LLGL::Key::Down))
            {
                ++y;
                window->SetPosition({ x, y });
            }

        }
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}
<|endoftext|>