<commit_before>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 11/9/2019, 9:10:42 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

int main()
{
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    cin >> B[i];
  }
  vector<int> old_A{A}, old_B{B};
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  for (auto i = 0; i < N; i++)
  {
    if (A[i] > B[i])
    {
      No();
    }
  }
  for (auto i = 0; i < N; i++)
  {
    if (old_A[i] == A[i])
    {
      Yes();
    }
  }
  assert(false);
  vector<bool> C(N, true);
  for (auto i = 1; i < N; i++)
  {
    C[i] = (A[i] <= B[i - 1]);
  }
  for (auto k = 0; k < N; k++)
  {
    int x{old_A[k]};
    int y{old_B[k]};
    if (x > y)
    {
      continue;
    }
    auto it_a{upper_bound(A.begin(), A.end(), x)};
    --it_a;
    assert(*it_a == x);
    auto it_b{lower_bound(B.begin(), B.end(), y)};
    assert(*it_b == y);
    int num_a(it_a - A.begin());
    int num_b(it_b - B.begin());
    if (num_b <= num_a)
    {
      Yes();
    }
    else
    {
      bool ok{true};
      for (auto i = num_a + 1; i <= num_b; i++)
      {
        if (!C[i])
        {
          ok = false;
          break;
        }
      }
      if (ok)
      {
        Yes();
      }
    }
  }

  vector<int> V(N, -1);
  for (auto i = 0; i < N; i++)
  {
    auto it{lower_bound(A.begin(), A.end(), old_A[i])};
    int num(it - A.begin());
    V[num] = i;
  }
  for (auto i = 0; i < N; i++)
  {
    if (V[i] == -1)
    {
      Yes();
    }
  }
  vector<bool> used(N, false);
  int now{0};
  int cnt{0};
  while (cnt < N)
  {
    if (used[now])
    {
      Yes();
    }
    used[now] = true;
    cnt++;
    now = V[now];
  }
  No();
}<commit_msg>submit C.cpp to 'C - Swaps' (nikkei2019-2-qual) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 11/9/2019, 9:10:42 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

using Info = tuple<int, int>;

int main()
{
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    cin >> B[i];
  }
  vector<Info> I(N);
  for (auto i = 0; i < N; i++)
  {
    I[i] = Info(B[i], A[i]);
  }
  sort(I.begin(), I.end());
  for (auto i = 0; i < N; i++)
  {
    A[i] = get<1>(I[i]);
  }
  vector<int> old_A{A}, old_B{B};
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  for (auto i = 0; i < N; i++)
  {
    if (A[i] > B[i])
    {
      No();
    }
  }
  for (auto i = 0; i < N; i++)
  {
    if (old_A[i] == A[i])
    {
      Yes();
    }
  }
  vector<bool> C(N, true);
  for (auto i = 1; i < N; i++)
  {
    C[i] = (A[i] <= B[i - 1]);
  }
  for (auto k = 0; k < N; k++)
  {
    int x{old_A[k]};
    int y{old_B[k]};
    if (x > y)
    {
      continue;
    }
    auto it_a{upper_bound(A.begin(), A.end(), x)};
    --it_a;
    assert(*it_a == x);
    auto it_b{lower_bound(B.begin(), B.end(), y)};
    assert(*it_b == y);
    int num_a(it_a - A.begin());
    int num_b(it_b - B.begin());
    if (num_b <= num_a)
    {
      Yes();
    }
    else
    {
      bool ok{true};
      for (auto i = num_a + 1; i <= num_b; i++)
      {
        if (!C[i])
        {
          ok = false;
          break;
        }
      }
      if (ok)
      {
        Yes();
      }
    }
  }
  vector<int> V(N, -1);
  for (auto i = 0; i < N; i++)
  {
    auto it{lower_bound(A.begin(), A.end(), old_A[i])};
    int num(it - A.begin());
    V[num] = i;
  }
  for (auto i = 0; i < N; i++)
  {
    if (V[i] == -1)
    {
      Yes();
    }
  }
  vector<bool> used(N, false);
  int now{0};
  int cnt{0};
  while (cnt < N)
  {
    if (used[now])
    {
      Yes();
    }
    used[now] = true;
    cnt++;
    now = V[now];
  }
  No();
}<|endoftext|>


<commit_before><commit_msg>`yli_convert`: load the 3D model into `yli::ontology::Symbiosis`.<commit_after><|endoftext|>


<commit_before>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/detail/config/atomic.hpp"
#include "blackhole/detail/config/noncopyable.hpp"
#include "blackhole/detail/config/nullptr.hpp"
#include "blackhole/detail/util/unique.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/thread.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/tracebit.hpp"

#include "blackhole/config.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

template<typename Level>
struct logger_verbosity_traits {
    typedef Level level_type;

    static
    inline
    bool
    passed(level_type logger_verbosity, level_type record_verbosity) {
        typedef typename aux::underlying_type<Level>::type underlying_type;

        return static_cast<underlying_type>(record_verbosity) >=
            static_cast<underlying_type>(logger_verbosity);
    }
};

class logger_base_t {
    friend class scoped_attributes_concept_t;
    friend void swap(logger_base_t& lhs, logger_base_t& rhs) BLACKHOLE_NOEXCEPT;

protected:
    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    struct state_t {
        std::atomic<bool> enabled;
        std::atomic<bool> tracked;

        filter_t filter;
        struct attrbutes_t {
            boost::thread_specific_ptr<scoped_attributes_concept_t> scoped;

            attrbutes_t(void(*deleter)(scoped_attributes_concept_t*)) :
                scoped(deleter)
            {}
        } attributes;

        std::vector<std::unique_ptr<base_frontend_t>> frontends;
        log::exception_handler_t exception;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;

        state_t();
    };

    state_t state;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enabled(bool enable);

    bool tracked() const;
    void tracked(bool enable);

    void set_filter(filter_t&& filter);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    record_t open_record() const;
    record_t open_record(attribute::pair_t attribute) const;
    record_t open_record(attribute::set_t attributes) const;

    void push(record_t&& record) const;

protected:
    record_t open_record(attribute::set_t internal, attribute::set_t external) const;
};

/// Concept form scoped attributes holder.
/*!
 * @note: It's not movable to avoid moving to another thread.
 */
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    virtual ~scoped_attributes_concept_t();

    virtual const attribute::set_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

    typedef std::function<
        bool(level_type, const attribute::combined_view_t&)
    > filter_type;

private:
    level_type level;
    filter_type filter; // TODO: Mutex.

public:
    explicit verbose_logger_t(level_type level) :
        logger_base_t(),
        level(level),
        filter(make_default_filter(level))
    {}

    //! @compat: GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other)),
        level(static_cast<level_type>(other.level)),
        filter(other.filter)
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));
        level = other.level;
        filter = other.filter;
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    /*!
     * Gets the current upper verbosity bound.
     */
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
        this->filter = make_default_filter(level);
    }

    void verbosity(filter_type filter) {
        this->filter = filter;
    }

    /*!
     * Tries to open log record with specific verbosity level.
     *
     * Internally this method compares desired verbosity level with the upper
     * one and checks for tracebit attribute (temporary until filter redesign).
     * Can return invalid log record if some conditions are not met.
     * @param[in] level - Desired verbosity level.
     * @return valid or invalid `record_t` object.
     * @todo: Replace with custom filter once a time.
     * @todo: Decompose.
     */
    record_t
    open_record(level_type level, attribute::set_t local = attribute::set_t()) const {
        bool passed = false;
        reader_lock_type lock(state.lock.open);
        if (auto scoped = state.attributes.scoped.get()) {
            const attribute::combined_view_t view(local, scoped->attributes());
            passed = filter(level, view);
        } else {
            const attribute::combined_view_t view(local);
            passed = filter(level, view);
        }

        if (passed) {
            attribute::set_t internal;
            internal.emplace_back(keyword::severity<Level>() = level);
            return logger_base_t::open_record(std::move(internal), std::move(local));
        }

        return record_t();
    }

private:
    static
    inline
    filter_type
    make_default_filter(level_type level) {
        return std::bind(
            &verbose_logger_t::default_filter,
            std::placeholders::_1,
            level,
            std::placeholders::_2
         );
    }

    static
    inline
    bool
    default_filter(level_type level,
                   level_type threshold,
                   const attribute::combined_view_t&)
    {
        return level >= threshold;
    }
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/logger.ipp"
#endif
<commit_msg>[Planning] Changed description.<commit_after>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/detail/config/atomic.hpp"
#include "blackhole/detail/config/noncopyable.hpp"
#include "blackhole/detail/config/nullptr.hpp"
#include "blackhole/detail/util/unique.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/thread.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/tracebit.hpp"

#include "blackhole/config.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

template<typename Level>
struct logger_verbosity_traits {
    typedef Level level_type;

    static
    inline
    bool
    passed(level_type logger_verbosity, level_type record_verbosity) {
        typedef typename aux::underlying_type<Level>::type underlying_type;

        return static_cast<underlying_type>(record_verbosity) >=
            static_cast<underlying_type>(logger_verbosity);
    }
};

class logger_base_t {
    friend class scoped_attributes_concept_t;
    friend void swap(logger_base_t& lhs, logger_base_t& rhs) BLACKHOLE_NOEXCEPT;

protected:
    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    struct state_t {
        std::atomic<bool> enabled;
        std::atomic<bool> tracked;

        filter_t filter;
        struct attrbutes_t {
            boost::thread_specific_ptr<scoped_attributes_concept_t> scoped;

            attrbutes_t(void(*deleter)(scoped_attributes_concept_t*)) :
                scoped(deleter)
            {}
        } attributes;

        std::vector<std::unique_ptr<base_frontend_t>> frontends;
        log::exception_handler_t exception;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;

        state_t();
    };

    state_t state;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enabled(bool enable);

    bool tracked() const;
    void tracked(bool enable);

    void set_filter(filter_t&& filter);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    record_t open_record() const;
    record_t open_record(attribute::pair_t attribute) const;
    record_t open_record(attribute::set_t attributes) const;

    void push(record_t&& record) const;

protected:
    record_t open_record(attribute::set_t internal, attribute::set_t external) const;
};

/// Concept form scoped attributes holder.
/*!
 * @note: It's not movable to avoid moving to another thread.
 */
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    virtual ~scoped_attributes_concept_t();

    virtual const attribute::set_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

    typedef std::function<
        bool(level_type, const attribute::combined_view_t&)
    > filter_type;

private:
    level_type level;
    filter_type filter;

    // TODO: Thread-safety.

public:
    explicit verbose_logger_t(level_type level) :
        logger_base_t(),
        level(level),
        filter(make_default_filter(level))
    {}

    //! @compat: GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other)),
        level(static_cast<level_type>(other.level)),
        filter(other.filter)
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));
        level = other.level;
        filter = other.filter;
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    /*!
     * Gets the current upper verbosity bound.
     */
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
        this->filter = make_default_filter(level);
    }

    void verbosity(filter_type filter) {
        this->filter = filter;
    }

    /*!
     * Tries to open log record with specific verbosity level.
     *
     * Internally this method compares desired verbosity level with the upper
     * one and checks for tracebit attribute (temporary until filter redesign).
     * Can return invalid log record if some conditions are not met.
     * @param[in] level - Desired verbosity level.
     * @return valid or invalid `record_t` object.
     * @todo: Replace with custom filter once a time.
     * @todo: Decompose.
     */
    record_t
    open_record(level_type level, attribute::set_t local = attribute::set_t()) const {
        bool passed = false;
        reader_lock_type lock(state.lock.open);
        if (auto scoped = state.attributes.scoped.get()) {
            const attribute::combined_view_t view(local, scoped->attributes());
            passed = filter(level, view);
        } else {
            const attribute::combined_view_t view(local);
            passed = filter(level, view);
        }

        if (passed) {
            attribute::set_t internal;
            internal.emplace_back(keyword::severity<Level>() = level);
            return logger_base_t::open_record(std::move(internal), std::move(local));
        }

        return record_t();
    }

private:
    static
    inline
    filter_type
    make_default_filter(level_type level) {
        return std::bind(
            &verbose_logger_t::default_filter,
            std::placeholders::_1,
            level,
            std::placeholders::_2
         );
    }

    static
    inline
    bool
    default_filter(level_type level,
                   level_type threshold,
                   const attribute::combined_view_t&)
    {
        return level >= threshold;
    }
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/logger.ipp"
#endif
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile: QmitkTrackingDeviceWidget.cpp $
Language:  C++
Date:      $Date: 2009-05-12 19:14:45 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 1.12 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html 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 notices for more information.

=========================================================================*/

#include "QmitkNavigationToolManagementWidget.h"

//mitk headers
#include "mitkTrackingTypes.h"
#include <mitkSTLFileReader.h>
#include <mitkSurface.h>
#include <mitkNavigationToolReader.h>
#include <mitkNavigationToolWriter.h>
#include <mitkNavigationToolStorage.h>
#include <mitkNavigationToolStorageDeserializer.h>
#include <mitkNavigationToolStorageSerializer.h>

//qt headers
#include <qfiledialog.h>
#include <qmessagebox.h>

const std::string QmitkNavigationToolManagementWidget::VIEW_ID = "org.mitk.views.navigationtoolmanagementwidget";

QmitkNavigationToolManagementWidget::QmitkNavigationToolManagementWidget(QWidget* parent, Qt::WindowFlags f)
  : QWidget(parent, f)
{
  m_Controls = NULL;
  CreateQtPartControl(this);
  CreateConnections();
  m_NavigationToolStorage = mitk::NavigationToolStorage::New();
  m_Controls->m_SurfaceChooser->SetAutoSelectNewItems(true);
}

QmitkNavigationToolManagementWidget::~QmitkNavigationToolManagementWidget()
{
}

void QmitkNavigationToolManagementWidget::CreateQtPartControl(QWidget *parent)
  {
    if (!m_Controls)
    {
    // create GUI widgets
    m_Controls = new Ui::QmitkNavigationToolManagementWidgetControls;
    m_Controls->setupUi(parent);
    }
  }

void QmitkNavigationToolManagementWidget::CreateConnections()
  {
    if ( m_Controls )
    {
      //main widget page:
      connect( (QObject*)(m_Controls->m_AddTool), SIGNAL(clicked()), this, SLOT(OnAddTool()) );
      connect( (QObject*)(m_Controls->m_DeleteTool), SIGNAL(clicked()), this, SLOT(OnDeleteTool()) );
      connect( (QObject*)(m_Controls->m_EditTool), SIGNAL(clicked()), this, SLOT(OnEditTool()) );
      connect( (QObject*)(m_Controls->m_LoadSingleTool), SIGNAL(clicked()), this, SLOT(OnLoadSingleTool()) );
      connect( (QObject*)(m_Controls->m_SaveSingleTool), SIGNAL(clicked()), this, SLOT(OnSaveSingleTool()) );
      connect( (QObject*)(m_Controls->m_LoadStorage), SIGNAL(clicked()), this, SLOT(OnLoadStorage()) );
      connect( (QObject*)(m_Controls->m_SaveStorage), SIGNAL(clicked()), this, SLOT(OnSaveStorage()) );

      //widget page "add tool":
      connect( (QObject*)(m_Controls->m_AddToolCancel), SIGNAL(clicked()), this, SLOT(OnAddToolCancel()) );
      connect( (QObject*)(m_Controls->m_AddToolSave), SIGNAL(clicked()), this, SLOT(OnAddToolSave()) );
      connect( (QObject*)(m_Controls->m_LoadSurface), SIGNAL(clicked()), this, SLOT(OnLoadSurface()) );
      connect( (QObject*)(m_Controls->m_LoadCalibrationFile), SIGNAL(clicked()), this, SLOT(OnLoadCalibrationFile()) );
    }
  }

void QmitkNavigationToolManagementWidget::Initialize(mitk::DataStorage* dataStorage)
  {
  m_DataStorage = dataStorage;
  }

//##################################################################################
//############################## slots: main widget ################################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddTool()
  {
    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Add Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //reset input fields
    m_Controls->m_ToolNameEdit->setText("");
    m_Controls->m_IdentifierEdit->setText("NavigationTool#"+QString::number(m_NavigationToolStorage->GetToolCount()));
    m_Controls->m_SerialNumberEdit->setText("");
    m_Controls->m_CalibrationFileName->setText("");

    m_edit = false;
  }

void QmitkNavigationToolManagementWidget::OnDeleteTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    m_DataStorage->Remove(m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column())->GetDataTreeNode());
    m_NavigationToolStorage->DeleteTool(m_Controls->m_ToolList->currentIndex().column());
    UpdateToolTable();

  }

void QmitkNavigationToolManagementWidget::OnEditTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Edit Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //fill forms
    mitk::NavigationTool::Pointer selectedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column());
    m_Controls->m_ToolNameEdit->setText(QString(selectedTool->GetDataTreeNode()->GetName().c_str()));
    m_Controls->m_IdentifierEdit->setText(QString(selectedTool->GetIdentifier().c_str()));
    m_Controls->m_SerialNumberEdit->setText(QString(selectedTool->GetSerialNumber().c_str()));
    switch(selectedTool->GetTrackingDeviceType())
      {
      case mitk::NDIAurora:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break;
      case mitk::NDIPolaris:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break;
      case mitk::ClaronMicron:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break;
      }
    m_Controls->m_CalibrationFileName->setText(QString(selectedTool->GetCalibrationFile().c_str()));
    switch(selectedTool->GetType())
      {
      case mitk::NavigationTool::Instrument:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(0); break;
      case mitk::NavigationTool::Fiducial:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(1); break;
      case mitk::NavigationTool::Skinmarker:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(2); break;
      case mitk::NavigationTool::Unknown:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(3); break;
      }
    m_edit = true;
  }

void QmitkNavigationToolManagementWidget::OnLoadSingleTool()
  {
    mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New();
    mitk::NavigationTool::Pointer readTool = myReader->DoRead(QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data());
    if (readTool.IsNull()) MessageBox("Error: " + myReader->GetErrorMessage());
    else
      {
      m_NavigationToolStorage->AddTool(readTool);
      UpdateToolTable();
      }
  }

void QmitkNavigationToolManagementWidget::OnSaveSingleTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New();
    if (!myWriter->DoWrite(QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.*").toAscii().data(),m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column())))
      MessageBox("Error: "+ myWriter->GetErrorMessage());
  }

void QmitkNavigationToolManagementWidget::OnLoadStorage()
  {
    mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New();
    mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data());
    if (tempStorage.IsNull()) MessageBox("Error" + myDeserializer->GetErrorMessage());
    else m_NavigationToolStorage = tempStorage;
  }

void QmitkNavigationToolManagementWidget::OnSaveStorage()
  {

  }

//##################################################################################
//############################## slots: add tool widget ############################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddToolSave()
  {
    mitk::NavigationTool::Pointer workTool;

    if (m_edit) //here we edit a existing tool
      {
      workTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column());

      //edit existing DataTreeNode...
      workTool->GetDataTreeNode()->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      workTool->GetDataTreeNode()->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      }
    else //here we create a new tool
      {
      workTool = mitk::NavigationTool::New();

      //create DataTreeNode...
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      newNode->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      m_DataStorage->Add(newNode);
      workTool->SetDataTreeNode(newNode);
      }

    //fill NavigationTool object
    workTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toAscii().data());
    workTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toAscii().data());
    workTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toAscii().data());
    //Tracking Device
    if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Aurora") workTool->SetTrackingDeviceType(mitk::NDIAurora);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Polaris") workTool->SetTrackingDeviceType(mitk::NDIPolaris);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="Claron Technology Micron Tracker") workTool->SetTrackingDeviceType(mitk::ClaronMicron);
    else workTool->SetTrackingDeviceType(mitk::TrackingSystemNotSpecified);
    //ToolType
    if (m_Controls->m_ToolTypeChooser->currentText()=="Instrument") workTool->SetType(mitk::NavigationTool::Instrument);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Fiducial") workTool->SetType(mitk::NavigationTool::Fiducial);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Skinmarker") workTool->SetType(mitk::NavigationTool::Skinmarker);
    else workTool->SetType(mitk::NavigationTool::Unknown);

    if (!m_edit) m_NavigationToolStorage->AddTool(workTool);

    UpdateToolTable();

    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnAddToolCancel()
  {
    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnLoadSurface()
  {
    std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Surface"), "/", "*.stl").toLatin1().data();
    mitk::STLFileReader::Pointer stlReader = mitk::STLFileReader::New();
    try
      {
      stlReader->SetFileName( filename.c_str() );
      stlReader->Update();
      }
    catch (...)
      {
      }

    if ( stlReader->GetOutput() == NULL );
    else
      {
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(filename);
      newNode->SetData(stlReader->GetOutput());
      m_DataStorage->Add(newNode);
      }
  }

void QmitkNavigationToolManagementWidget::OnLoadCalibrationFile()
  {
    m_Controls->m_CalibrationFileName->setText(QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*"));
  }

//##################################################################################
//############################## private help methods ##############################
//##################################################################################
void QmitkNavigationToolManagementWidget::UpdateToolTable()
  {
  m_Controls->m_ToolList->clear();
  for(int i=0; i<m_NavigationToolStorage->GetToolCount(); i++)
    {
      QString currentTool = "Tool" + QString::number(i) + ": " + QString(m_NavigationToolStorage->GetTool(i)->GetDataTreeNode()->GetName().c_str())+ " ";
      switch (m_NavigationToolStorage->GetTool(i)->GetTrackingDeviceType())
        {
        case mitk::ClaronMicron:
              currentTool += "(MicronTracker/"; break;
        case mitk::NDIAurora:
              currentTool += "(NDI Aurora/"; break;
        case mitk::NDIPolaris:
              currentTool += "(NDI Polaris/"; break;
        default:
              currentTool += "(unknown tracking system/"; break;
        }
      switch (m_NavigationToolStorage->GetTool(i)->GetType())
        {
        case mitk::NavigationTool::Instrument:
              currentTool += "Instrument)"; break;
        case mitk::NavigationTool::Fiducial:
              currentTool += "Fiducial)"; break;
        case mitk::NavigationTool::Skinmarker:
              currentTool += "Skinmarker)"; break;
        default:
              currentTool += "Unknown)";
        }
      m_Controls->m_ToolList->addItem(currentTool);
    }

  }

void QmitkNavigationToolManagementWidget::MessageBox(std::string s)
  {
  QMessageBox msgBox;
  msgBox.setText(s.c_str());
  msgBox.exec();
  }<commit_msg>ENH (#3167): Implemented missing methods. NavigationToolManagementWidget is finished. Also fixed a warning. But be careful in using the widget immediately because a few classes which are used by the widget are only stubs, accordingly you'll get some warning messages.<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile: QmitkTrackingDeviceWidget.cpp $
Language:  C++
Date:      $Date: 2009-05-12 19:14:45 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 1.12 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html 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 notices for more information.

=========================================================================*/

#include "QmitkNavigationToolManagementWidget.h"

//mitk headers
#include "mitkTrackingTypes.h"
#include <mitkSTLFileReader.h>
#include <mitkSurface.h>
#include <mitkNavigationToolReader.h>
#include <mitkNavigationToolWriter.h>
#include <mitkNavigationToolStorage.h>
#include <mitkNavigationToolStorageDeserializer.h>
#include <mitkNavigationToolStorageSerializer.h>

//qt headers
#include <qfiledialog.h>
#include <qmessagebox.h>

const std::string QmitkNavigationToolManagementWidget::VIEW_ID = "org.mitk.views.navigationtoolmanagementwidget";

QmitkNavigationToolManagementWidget::QmitkNavigationToolManagementWidget(QWidget* parent, Qt::WindowFlags f)
  : QWidget(parent, f)
{
  m_Controls = NULL;
  CreateQtPartControl(this);
  CreateConnections();
  m_NavigationToolStorage = mitk::NavigationToolStorage::New();
  m_Controls->m_SurfaceChooser->SetAutoSelectNewItems(true);
}

QmitkNavigationToolManagementWidget::~QmitkNavigationToolManagementWidget()
{
}

void QmitkNavigationToolManagementWidget::CreateQtPartControl(QWidget *parent)
  {
    if (!m_Controls)
    {
    // create GUI widgets
    m_Controls = new Ui::QmitkNavigationToolManagementWidgetControls;
    m_Controls->setupUi(parent);
    }
  }

void QmitkNavigationToolManagementWidget::CreateConnections()
  {
    if ( m_Controls )
    {
      //main widget page:
      connect( (QObject*)(m_Controls->m_AddTool), SIGNAL(clicked()), this, SLOT(OnAddTool()) );
      connect( (QObject*)(m_Controls->m_DeleteTool), SIGNAL(clicked()), this, SLOT(OnDeleteTool()) );
      connect( (QObject*)(m_Controls->m_EditTool), SIGNAL(clicked()), this, SLOT(OnEditTool()) );
      connect( (QObject*)(m_Controls->m_LoadSingleTool), SIGNAL(clicked()), this, SLOT(OnLoadSingleTool()) );
      connect( (QObject*)(m_Controls->m_SaveSingleTool), SIGNAL(clicked()), this, SLOT(OnSaveSingleTool()) );
      connect( (QObject*)(m_Controls->m_LoadStorage), SIGNAL(clicked()), this, SLOT(OnLoadStorage()) );
      connect( (QObject*)(m_Controls->m_SaveStorage), SIGNAL(clicked()), this, SLOT(OnSaveStorage()) );

      //widget page "add tool":
      connect( (QObject*)(m_Controls->m_AddToolCancel), SIGNAL(clicked()), this, SLOT(OnAddToolCancel()) );
      connect( (QObject*)(m_Controls->m_AddToolSave), SIGNAL(clicked()), this, SLOT(OnAddToolSave()) );
      connect( (QObject*)(m_Controls->m_LoadSurface), SIGNAL(clicked()), this, SLOT(OnLoadSurface()) );
      connect( (QObject*)(m_Controls->m_LoadCalibrationFile), SIGNAL(clicked()), this, SLOT(OnLoadCalibrationFile()) );
    }
  }

void QmitkNavigationToolManagementWidget::Initialize(mitk::DataStorage* dataStorage)
  {
  m_DataStorage = dataStorage;
  }

//##################################################################################
//############################## slots: main widget ################################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddTool()
  {
    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Add Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //reset input fields
    m_Controls->m_ToolNameEdit->setText("");
    m_Controls->m_IdentifierEdit->setText("NavigationTool#"+QString::number(m_NavigationToolStorage->GetToolCount()));
    m_Controls->m_SerialNumberEdit->setText("");
    m_Controls->m_CalibrationFileName->setText("");

    m_edit = false;
  }

void QmitkNavigationToolManagementWidget::OnDeleteTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    m_DataStorage->Remove(m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column())->GetDataTreeNode());
    m_NavigationToolStorage->DeleteTool(m_Controls->m_ToolList->currentIndex().column());
    UpdateToolTable();

  }

void QmitkNavigationToolManagementWidget::OnEditTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Edit Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //fill forms
    mitk::NavigationTool::Pointer selectedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column());
    m_Controls->m_ToolNameEdit->setText(QString(selectedTool->GetDataTreeNode()->GetName().c_str()));
    m_Controls->m_IdentifierEdit->setText(QString(selectedTool->GetIdentifier().c_str()));
    m_Controls->m_SerialNumberEdit->setText(QString(selectedTool->GetSerialNumber().c_str()));
    switch(selectedTool->GetTrackingDeviceType())
      {
      case mitk::NDIAurora:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break;
      case mitk::NDIPolaris:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break;
      case mitk::ClaronMicron:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break;
      default:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);
      }
    m_Controls->m_CalibrationFileName->setText(QString(selectedTool->GetCalibrationFile().c_str()));
    switch(selectedTool->GetType())
      {
      case mitk::NavigationTool::Instrument:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(0); break;
      case mitk::NavigationTool::Fiducial:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(1); break;
      case mitk::NavigationTool::Skinmarker:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(2); break;
      case mitk::NavigationTool::Unknown:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(3); break;
      }
    m_edit = true;
  }

void QmitkNavigationToolManagementWidget::OnLoadSingleTool()
  {
    mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New();
    mitk::NavigationTool::Pointer readTool = myReader->DoRead(QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data());
    if (readTool.IsNull()) MessageBox("Error: " + myReader->GetErrorMessage());
    else
      {
      m_NavigationToolStorage->AddTool(readTool);
      UpdateToolTable();
      }
  }

void QmitkNavigationToolManagementWidget::OnSaveSingleTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New();
    if (!myWriter->DoWrite(QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.*").toAscii().data(),m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column())))
      MessageBox("Error: "+ myWriter->GetErrorMessage());
  }

void QmitkNavigationToolManagementWidget::OnLoadStorage()
  {
    mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New();
    mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data());
    if (tempStorage.IsNull()) MessageBox("Error" + myDeserializer->GetErrorMessage());
    else m_NavigationToolStorage = tempStorage;
  }

void QmitkNavigationToolManagementWidget::OnSaveStorage()
  {
    mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New();
    if (!mySerializer->Serialize(QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.*").toAscii().data(),m_NavigationToolStorage)) MessageBox("Error: " + mySerializer->GetErrorMessage());
  }

//##################################################################################
//############################## slots: add tool widget ############################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddToolSave()
  {
    mitk::NavigationTool::Pointer workTool;

    if (m_edit) //here we edit a existing tool
      {
      workTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().column());

      //edit existing DataTreeNode...
      workTool->GetDataTreeNode()->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      workTool->GetDataTreeNode()->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      }
    else //here we create a new tool
      {
      workTool = mitk::NavigationTool::New();

      //create DataTreeNode...
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      newNode->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      m_DataStorage->Add(newNode);
      workTool->SetDataTreeNode(newNode);
      }

    //fill NavigationTool object
    workTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toAscii().data());
    workTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toAscii().data());
    workTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toAscii().data());
    //Tracking Device
    if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Aurora") workTool->SetTrackingDeviceType(mitk::NDIAurora);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Polaris") workTool->SetTrackingDeviceType(mitk::NDIPolaris);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="Claron Technology Micron Tracker") workTool->SetTrackingDeviceType(mitk::ClaronMicron);
    else workTool->SetTrackingDeviceType(mitk::TrackingSystemNotSpecified);
    //ToolType
    if (m_Controls->m_ToolTypeChooser->currentText()=="Instrument") workTool->SetType(mitk::NavigationTool::Instrument);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Fiducial") workTool->SetType(mitk::NavigationTool::Fiducial);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Skinmarker") workTool->SetType(mitk::NavigationTool::Skinmarker);
    else workTool->SetType(mitk::NavigationTool::Unknown);

    if (!m_edit) m_NavigationToolStorage->AddTool(workTool);

    UpdateToolTable();

    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnAddToolCancel()
  {
    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnLoadSurface()
  {
    std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Surface"), "/", "*.stl").toLatin1().data();
    mitk::STLFileReader::Pointer stlReader = mitk::STLFileReader::New();
    try
      {
      stlReader->SetFileName( filename.c_str() );
      stlReader->Update();
      }
    catch (...)
      {
      }

    if ( stlReader->GetOutput() == NULL );
    else
      {
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(filename);
      newNode->SetData(stlReader->GetOutput());
      m_DataStorage->Add(newNode);
      }
  }

void QmitkNavigationToolManagementWidget::OnLoadCalibrationFile()
  {
    m_Controls->m_CalibrationFileName->setText(QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*"));
  }

//##################################################################################
//############################## private help methods ##############################
//##################################################################################
void QmitkNavigationToolManagementWidget::UpdateToolTable()
  {
  m_Controls->m_ToolList->clear();
  for(int i=0; i<m_NavigationToolStorage->GetToolCount(); i++)
    {
      QString currentTool = "Tool" + QString::number(i) + ": " + QString(m_NavigationToolStorage->GetTool(i)->GetDataTreeNode()->GetName().c_str())+ " ";
      switch (m_NavigationToolStorage->GetTool(i)->GetTrackingDeviceType())
        {
        case mitk::ClaronMicron:
              currentTool += "(MicronTracker/"; break;
        case mitk::NDIAurora:
              currentTool += "(NDI Aurora/"; break;
        case mitk::NDIPolaris:
              currentTool += "(NDI Polaris/"; break;
        default:
              currentTool += "(unknown tracking system/"; break;
        }
      switch (m_NavigationToolStorage->GetTool(i)->GetType())
        {
        case mitk::NavigationTool::Instrument:
              currentTool += "Instrument)"; break;
        case mitk::NavigationTool::Fiducial:
              currentTool += "Fiducial)"; break;
        case mitk::NavigationTool::Skinmarker:
              currentTool += "Skinmarker)"; break;
        default:
              currentTool += "Unknown)";
        }
      m_Controls->m_ToolList->addItem(currentTool);
    }

  }

void QmitkNavigationToolManagementWidget::MessageBox(std::string s)
  {
  QMessageBox msgBox;
  msgBox.setText(s.c_str());
  msgBox.exec();
  }<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
#ifndef itkTransformFileReader_hxx
#define itkTransformFileReader_hxx

#include "itkTransformFileReader.h"
#include "itkTransformIOFactory.h"
#include "itkCompositeTransformIOHelper.h"
#include "itkKernelTransform.h"

#include "itksys/SystemTools.hxx"

#ifndef ITK_TRANSFORM_FACTORY_MAX_DIM
#define ITK_TRANSFORM_FACTORY_MAX_DIM 9
#endif

namespace itk
{

namespace
{
// Class to initialize kernel transform for dimension D and lower
template< typename TParameterType, unsigned int Dimension>
struct KernelTransformHelper
{
  static int InitializeWMatrix(const typename TransformBaseTemplate<TParameterType>::Pointer &transform)
    {
    if( transform->GetInputSpaceDimension() == Dimension)
      {
      typedef typename itk::KernelTransform< TParameterType, Dimension > KernelTransformType;
      KernelTransformType* kernelTransform = static_cast<KernelTransformType*>(transform.GetPointer());
      kernelTransform->ComputeWMatrix();
      return 0;
      }
    else
      {
      // try one less dimension
      return KernelTransformHelper<TParameterType, Dimension-1>::InitializeWMatrix(transform);
      }
    }
};

// Template specialized class to stop initializing Kernel Transfoms.
template<typename TParameterType>
struct KernelTransformHelper<TParameterType, 0>
{
  static int InitializeWMatrix(const typename TransformBaseTemplate<TParameterType>::Pointer &itkNotUsed(transform))
    {
    return 1;
    }
};
}

template<typename TParametersValueType>
TransformFileReaderTemplate<TParametersValueType>
::TransformFileReaderTemplate() :
  m_FileName("") /* to be removed soon. See .h */
{
}

template<typename TParametersValueType>
TransformFileReaderTemplate<TParametersValueType>
::~TransformFileReaderTemplate()
{
}

template<typename TParametersValueType>
void TransformFileReaderTemplate<TParametersValueType>
::Update()
{
  if ( m_FileName == "" )
    {
    itkExceptionMacro ("No file name given");
    }

  if( m_TransformIO.IsNull() )
    {
    typedef TransformIOFactoryTemplate< TParametersValueType > TransformFactoryIOType;
    m_TransformIO = TransformFactoryIOType::CreateTransformIO( m_FileName.c_str(), /*TransformIOFactoryTemplate<TParametersValueType>::*/ ReadMode );
    if ( m_TransformIO.IsNull() )
      {
      std::ostringstream msg;
      msg << "Could not create Transform IO object for reading file "  << this->GetFileName() << std::endl;

      if ( !itksys::SystemTools::FileExists( m_FileName.c_str() ) )
        {
        msg << " File does not exists!";
        }

      std::list< LightObject::Pointer > allobjects =  ObjectFactoryBase::CreateAllInstance("itkTransformIOBaseTemplate");

      if (allobjects.size() > 0)
        {
        msg << "  Tried to create one of the following:" << std::endl;
        for ( std::list< LightObject::Pointer >::iterator i = allobjects.begin();
              i != allobjects.end(); ++i )
          {
          const Object *obj = dynamic_cast<Object*>(i->GetPointer());
          msg << "    " << obj->GetNameOfClass() << std::endl;
          }
        msg << "  You probably failed to set a file suffix, or" << std::endl;
        msg << "    set the suffix to an unsupported type." << std::endl;
        }
      else
        {
        msg << "  There are no registered Transform IO factories." << std::endl;
        msg << "  Please visit https://www.itk.org/Wiki/ITK/FAQ#NoFactoryException to diagnose the problem." << std::endl;
        }

      itkExceptionMacro( << msg.str().c_str() );
      }

    }

  typename TransformIOType::TransformListType & ioTransformList = m_TransformIO->GetTransformList();
  // Clear old results.
  ioTransformList.clear();

  m_TransformIO->SetFileName(m_FileName);
  m_TransformIO->Read();

  // Clear old results.
  this->m_TransformList.clear();
  // If the transform is derived from itk::KernelTransform, the internal matrices
  // need to be initialized using the transform parameters.
  // kernelTransform->ComputeWMatrix() has to be called after the transform is read but
  // before the transform is used.
  std::string transformTypeName = ioTransformList.front()->GetNameOfClass();
  const int len = strlen("KernelTransform");// Computed at compile time in most cases
  if (transformTypeName.size() >= len
      && !transformTypeName.compare(transformTypeName.size()-len , len, "KernelTransform"))
    {
    if( KernelTransformHelper<TParametersValueType,
        ITK_TRANSFORM_FACTORY_MAX_DIM>::InitializeWMatrix(ioTransformList.front().GetPointer()))
      {
      itkDebugMacro(<< "KernelTransform with dimension "
                    << ioTransformList.front()->GetInputSpaceDimension()
                    << " is not automatically initialized. \"ComputeWMatrix()\""
                       " method has to be called."
                   );
      }
    }

  // In the case where the first transform in the list is a
  // CompositeTransform, add all the transforms to that first
  // transform. and return a single composite item on the
  // m_TransformList
  const std::string firstTransformName = ioTransformList.front()->GetNameOfClass();
  if(firstTransformName.find("CompositeTransform") != std::string::npos)
    {
    typename TransformListType::const_iterator tit = ioTransformList.begin();
    typename TransformType::Pointer composite = (*tit).GetPointer();

    // CompositeTransformIOHelperTemplate knows how to assign to the composite
    // transform's internal list
    CompositeTransformIOHelperTemplate<TParametersValueType> helper;
    helper.SetTransformList(composite.GetPointer(),ioTransformList);

    this->m_TransformList.push_back( composite.GetPointer() );
    }
  else  //Just return the entire list of elements
    {
    for ( typename TransformListType::iterator it =
         ioTransformList.begin();
         it != ioTransformList.end(); ++it )
      {
      this->m_TransformList.push_back( (*it).GetPointer() );
      }
    }
}

template<typename TParametersValueType>
void TransformFileReaderTemplate<TParametersValueType>
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "FileName: " << m_FileName << std::endl;
}

} // namespace itk

#endif
<commit_msg>COMP: Fix signed/unsigned mismatch warning.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
#ifndef itkTransformFileReader_hxx
#define itkTransformFileReader_hxx

#include "itkTransformFileReader.h"
#include "itkTransformIOFactory.h"
#include "itkCompositeTransformIOHelper.h"
#include "itkKernelTransform.h"

#include "itksys/SystemTools.hxx"

#ifndef ITK_TRANSFORM_FACTORY_MAX_DIM
#define ITK_TRANSFORM_FACTORY_MAX_DIM 9
#endif

namespace itk
{

namespace
{
// Class to initialize kernel transform for dimension D and lower
template< typename TParameterType, unsigned int Dimension>
struct KernelTransformHelper
{
  static int InitializeWMatrix(const typename TransformBaseTemplate<TParameterType>::Pointer &transform)
    {
    if( transform->GetInputSpaceDimension() == Dimension)
      {
      typedef typename itk::KernelTransform< TParameterType, Dimension > KernelTransformType;
      KernelTransformType* kernelTransform = static_cast<KernelTransformType*>(transform.GetPointer());
      kernelTransform->ComputeWMatrix();
      return 0;
      }
    else
      {
      // try one less dimension
      return KernelTransformHelper<TParameterType, Dimension-1>::InitializeWMatrix(transform);
      }
    }
};

// Template specialized class to stop initializing Kernel Transfoms.
template<typename TParameterType>
struct KernelTransformHelper<TParameterType, 0>
{
  static int InitializeWMatrix(const typename TransformBaseTemplate<TParameterType>::Pointer &itkNotUsed(transform))
    {
    return 1;
    }
};
}

template<typename TParametersValueType>
TransformFileReaderTemplate<TParametersValueType>
::TransformFileReaderTemplate() :
  m_FileName("") /* to be removed soon. See .h */
{
}

template<typename TParametersValueType>
TransformFileReaderTemplate<TParametersValueType>
::~TransformFileReaderTemplate()
{
}

template<typename TParametersValueType>
void TransformFileReaderTemplate<TParametersValueType>
::Update()
{
  if ( m_FileName == "" )
    {
    itkExceptionMacro ("No file name given");
    }

  if( m_TransformIO.IsNull() )
    {
    typedef TransformIOFactoryTemplate< TParametersValueType > TransformFactoryIOType;
    m_TransformIO = TransformFactoryIOType::CreateTransformIO( m_FileName.c_str(), /*TransformIOFactoryTemplate<TParametersValueType>::*/ ReadMode );
    if ( m_TransformIO.IsNull() )
      {
      std::ostringstream msg;
      msg << "Could not create Transform IO object for reading file "  << this->GetFileName() << std::endl;

      if ( !itksys::SystemTools::FileExists( m_FileName.c_str() ) )
        {
        msg << " File does not exists!";
        }

      std::list< LightObject::Pointer > allobjects =  ObjectFactoryBase::CreateAllInstance("itkTransformIOBaseTemplate");

      if (allobjects.size() > 0)
        {
        msg << "  Tried to create one of the following:" << std::endl;
        for ( std::list< LightObject::Pointer >::iterator i = allobjects.begin();
              i != allobjects.end(); ++i )
          {
          const Object *obj = dynamic_cast<Object*>(i->GetPointer());
          msg << "    " << obj->GetNameOfClass() << std::endl;
          }
        msg << "  You probably failed to set a file suffix, or" << std::endl;
        msg << "    set the suffix to an unsupported type." << std::endl;
        }
      else
        {
        msg << "  There are no registered Transform IO factories." << std::endl;
        msg << "  Please visit https://www.itk.org/Wiki/ITK/FAQ#NoFactoryException to diagnose the problem." << std::endl;
        }

      itkExceptionMacro( << msg.str().c_str() );
      }

    }

  typename TransformIOType::TransformListType & ioTransformList = m_TransformIO->GetTransformList();
  // Clear old results.
  ioTransformList.clear();

  m_TransformIO->SetFileName(m_FileName);
  m_TransformIO->Read();

  // Clear old results.
  this->m_TransformList.clear();
  // If the transform is derived from itk::KernelTransform, the internal matrices
  // need to be initialized using the transform parameters.
  // kernelTransform->ComputeWMatrix() has to be called after the transform is read but
  // before the transform is used.
  std::string transformTypeName = ioTransformList.front()->GetNameOfClass();
  const size_t len = strlen("KernelTransform");// Computed at compile time in most cases
  if (transformTypeName.size() >= len
      && !transformTypeName.compare(transformTypeName.size()-len , len, "KernelTransform"))
    {
    if( KernelTransformHelper<TParametersValueType,
        ITK_TRANSFORM_FACTORY_MAX_DIM>::InitializeWMatrix(ioTransformList.front().GetPointer()))
      {
      itkDebugMacro(<< "KernelTransform with dimension "
                    << ioTransformList.front()->GetInputSpaceDimension()
                    << " is not automatically initialized. \"ComputeWMatrix()\""
                       " method has to be called."
                   );
      }
    }

  // In the case where the first transform in the list is a
  // CompositeTransform, add all the transforms to that first
  // transform. and return a single composite item on the
  // m_TransformList
  const std::string firstTransformName = ioTransformList.front()->GetNameOfClass();
  if(firstTransformName.find("CompositeTransform") != std::string::npos)
    {
    typename TransformListType::const_iterator tit = ioTransformList.begin();
    typename TransformType::Pointer composite = (*tit).GetPointer();

    // CompositeTransformIOHelperTemplate knows how to assign to the composite
    // transform's internal list
    CompositeTransformIOHelperTemplate<TParametersValueType> helper;
    helper.SetTransformList(composite.GetPointer(),ioTransformList);

    this->m_TransformList.push_back( composite.GetPointer() );
    }
  else  //Just return the entire list of elements
    {
    for ( typename TransformListType::iterator it =
         ioTransformList.begin();
         it != ioTransformList.end(); ++it )
      {
      this->m_TransformList.push_back( (*it).GetPointer() );
      }
    }
}

template<typename TParametersValueType>
void TransformFileReaderTemplate<TParametersValueType>
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "FileName: " << m_FileName << std::endl;
}

} // namespace itk

#endif
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPlanarCross.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"

mitk::PlanarCross::PlanarCross()
: FEATURE_ID_LONGESTDIAMETER( this->AddFeature( "Longest Axis", "mm" ) ),
  FEATURE_ID_SHORTAXISDIAMETER( this->AddFeature( "Short Axis", "mm" ) )
{
  // Cross has two control points at the beginning
  this->ResetNumberOfControlPoints( 2 );

  // Create property for SingleLineMode (default: false)
  this->SetProperty( "SingleLineMode", mitk::BoolProperty::New( false ) );

  // Create helper polyline object (for drawing the orthogonal orientation line)
  this->SetNumberOfHelperPolyLines( 1 );
  m_HelperPolyLinesToBePainted->InsertElement( 0, false );
}

void mitk::PlanarCross::SetSingleLineMode( bool singleLineMode )
{
  this->SetProperty( "SingleLineMode", mitk::BoolProperty::New( singleLineMode ) );
  this->Modified();
}

bool mitk::PlanarCross::GetSingleLineMode() const
{
  const mitk::BoolProperty* singleLineMode = dynamic_cast< mitk::BoolProperty* >(
    this->GetProperty( "SingleLineMode" ).GetPointer() );

  if ( singleLineMode != nullptr )
  {
    return singleLineMode->GetValue();
  }
  return false;
}

bool mitk::PlanarCross::ResetOnPointSelectNeeded() const
{
  return this->GetSingleLineMode() == false || m_SelectedControlPoint >= 0 && m_SelectedControlPoint <= 3;
}

bool mitk::PlanarCross::ResetOnPointSelect()
{
  if ( this->GetSingleLineMode() )
  {
    // In single line mode --> nothing to reset
    return false;
  }

  switch ( m_SelectedControlPoint )
  {
  default:
    // Nothing selected --> nothing to reset
    return false;

  case 0:
    {
      // Control point 0 selected: exchange points 0 and 1
      const Point2D tmpPoint = this->GetControlPoint( 0 );
      this->SetControlPoint( 0, this->GetControlPoint( 1 ) );
      this->SetControlPoint( 1, tmpPoint );
      // FALLS THROUGH!
    }

  case 1:
    {
      // Control point 0 or 1 selected: reset number of control points to two
      this->ResetNumberOfControlPoints( 2 );
      this->SelectControlPoint( 1 );
      return true;
    }

  case 2:
    {
      // Control point 2 selected: replace point 0 with point 3 and point 1 with point 2
      this->SetControlPoint( 0, this->GetControlPoint( 3 ) );
      this->SetControlPoint( 1, this->GetControlPoint( 2 ) );

      // Adjust selected control point, reset number of control points to two
      this->ResetNumberOfControlPoints( 2 );
      this->SelectControlPoint( 1 );
      return true;
    }

  case 3:
    {
      // Control point 3 selected: replace point 0 with point 2 and point 1 with point 3

      this->SetControlPoint( 0, this->GetControlPoint( 2 ) );
      this->SetControlPoint( 1, this->GetControlPoint( 3 ) );

      // Adjust selected control point, reset number of control points to two
      this->ResetNumberOfControlPoints( 2 );
      this->SelectControlPoint( 1 );
      return true;
    }
  }
}

unsigned int mitk::PlanarCross::GetNumberOfFeatures() const
{
  if ( this->GetSingleLineMode() || (this->GetNumberOfControlPoints() < 4) )
  {
    return 1;
  }
  else
  {
    return 2;
  }
}

mitk::Point2D mitk::PlanarCross::ApplyControlPointConstraints( unsigned int index, const Point2D& point )
{
  // Apply spatial constraints from superclass and from this class until the resulting constrained
  // point converges. Although not an optimal implementation, this iterative approach
  // helps to respect both constraints from the superclass and from this class. Without this,
  // situations may occur where control points are constrained by the superclass, but again
  // moved out of the superclass bounds by the subclass, or vice versa.

  unsigned int count = 0; // ensures stop of approach if point does not converge in reasonable time
  Point2D confinedPoint = point;
  Point2D superclassConfinedPoint;
  do
  {
    superclassConfinedPoint = Superclass::ApplyControlPointConstraints( index, confinedPoint );
    confinedPoint = this->InternalApplyControlPointConstraints( index, superclassConfinedPoint );
    ++count;
  } while ( (confinedPoint.EuclideanDistanceTo( superclassConfinedPoint ) > mitk::eps)
         && (count < 32) );

  return confinedPoint;
}

mitk::Point2D mitk::PlanarCross::InternalApplyControlPointConstraints( unsigned int index, const Point2D& point )
{
  // Apply constraints depending on current interaction state
  switch ( index )
  {
  case 2:
    {
      // Check if 3rd control point is outside of the range (2D area) defined by the first
      // line (via the first two control points); if it is outside, clip it to the bounds
      const Point2D p1 = this->GetControlPoint( 0 );
      const Point2D p2 = this->GetControlPoint( 1 );

      Vector2D n1 = p2 - p1;
      n1.Normalize();

      const Vector2D v1 = point - p1;
      const double dotProduct = n1 * v1;
      const Point2D crossPoint = p1 + n1 * dotProduct;;
      const Vector2D crossVector = point - crossPoint;

      if ( dotProduct < 0.0 )
      {
        // Out-of-bounds on the left: clip point to left boundary
        return (p1 + crossVector);
      }
      else if ( dotProduct > p2.EuclideanDistanceTo( p1 ) )
      {
        // Out-of-bounds on the right: clip point to right boundary
        return (p2 + crossVector);
      }
      else
      {
        // Pass back original point
        return point;
      }
    }

  case 3:
    {
      // Constrain 4th control point so that with the 3rd control point it forms
      // a line orthogonal to the first line (constraint 1); the 4th control point
      // must lie on the opposite side of the line defined by the first two control
      // points than the 3rd control point (constraint 2)
      const Point2D p1 = this->GetControlPoint( 0 );
      const Point2D p2 = this->GetControlPoint( 1 );
      const Point2D p3 = this->GetControlPoint( 2 );

      // Calculate distance of original point from orthogonal line the corrected
      // point should lie on to project the point onto this line
      Vector2D n1 = p2 - p1;
      n1.Normalize();

      const Vector2D v1 = point - p3;
      const double dotProduct1 = n1 * v1;

      const Point2D pointOnLine = point - n1 * dotProduct1;

      // Project new point onto line [p1, p2]
      const Vector2D v2 = pointOnLine - p1;
      double dotProduct2 = n1 * v2;

      const Point2D crossingPoint = p1 + n1 * dotProduct2;

      // Determine whether the projected point on the line, or the crossing point should be
      // used (according to the second constraint in the comment above)
      if ( (pointOnLine.SquaredEuclideanDistanceTo( p3 ) > crossingPoint.SquaredEuclideanDistanceTo( p3 ))
        && (pointOnLine.SquaredEuclideanDistanceTo( p3 ) > pointOnLine.SquaredEuclideanDistanceTo( crossingPoint )) )
      {
        return pointOnLine;
      }
      else
      {
        return crossingPoint;
      }
    }

  default:
    return point;
  }
}

void mitk::PlanarCross::GeneratePolyLine()
{
  this->SetNumberOfPolyLines(1);
  this->ClearPolyLines();

  if (this->GetNumberOfControlPoints() > 2)
    this->SetNumberOfPolyLines( 2 );

  for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i)
  {
    if (i < 2)
      this->AppendPointToPolyLine(0, this->GetControlPoint(i));

    if (i > 1)
      this->AppendPointToPolyLine(1, this->GetControlPoint(i));
  }
}

void mitk::PlanarCross::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
  // Generate helper polyline (orientation line orthogonal to first line)
  // if the third control point is currently being set
  if ( this->GetNumberOfControlPoints() != 3 )
  {
    m_HelperPolyLinesToBePainted->SetElement( 0, false );
    return;
  }

  m_HelperPolyLinesToBePainted->SetElement( 0, true );

  this->ClearHelperPolyLines();

  // Calculate cross point of first line (p1 to p2) and orthogonal line through
  // the third control point (p3)
  const Point2D p1 = this->GetControlPoint( 0 );
  const Point2D p2 = this->GetControlPoint( 1 );
  const Point2D p3 = this->GetControlPoint( 2 );

  Vector2D n1 = p2 - p1;
  n1.Normalize();

  const Vector2D v1 = p3 - p1;
  const Point2D crossPoint = p1 + n1 * (n1 * v1);

  const Vector2D v2 = crossPoint - p3;
  if ( v2.GetNorm() < 1.0 )
  {
    // If third point is on the first line, draw orthogonal "infinite" line
    // through cross point on line
    Vector2D v0;
    v0[0] = n1[1];
    v0[1] = -n1[0];
    this->AppendPointToHelperPolyLine(0, Point2D(p3 - v0 * 10000.0));
    this->AppendPointToHelperPolyLine(0, Point2D(p3 + v0 * 10000.0));
  }
  else
  {
    // Else, draw orthogonal line starting from third point and crossing the
    // first line, open-ended only on the other side
    this->AppendPointToHelperPolyLine(0, p3);
    this->AppendPointToHelperPolyLine(0, Point2D(p3 + v2 * 10000.0));
  }
}

void mitk::PlanarCross::EvaluateFeaturesInternal()
{
  // Calculate length of first line
  const Point3D &p0 = this->GetWorldControlPoint( 0 );
  const Point3D &p1 = this->GetWorldControlPoint( 1 );
  double l1 = p0.EuclideanDistanceTo( p1 );

  // Calculate length of second line
  double l2 = 0.0;
  if ( !this->GetSingleLineMode() && (this->GetNumberOfControlPoints() > 3) )
  {
    const Point3D &p2 = this->GetWorldControlPoint( 2 );
    const Point3D &p3 = this->GetWorldControlPoint( 3 );
    l2 = p2.EuclideanDistanceTo( p3 );
  }

  double longestDiameter;
  double shortAxisDiameter;
  if ( l1 > l2 )
  {
    longestDiameter = l1;
    shortAxisDiameter = l2;
  }
  else
  {
    longestDiameter = l2;
    shortAxisDiameter = l1;
  }

  this->SetQuantity( FEATURE_ID_LONGESTDIAMETER, longestDiameter );
  this->SetQuantity( FEATURE_ID_SHORTAXISDIAMETER, shortAxisDiameter );
}

void mitk::PlanarCross::PrintSelf( std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf( os, indent );
}

 bool mitk::PlanarCross::Equals(const mitk::PlanarFigure& other) const
 {
   const mitk::PlanarCross* otherCross = dynamic_cast<const mitk::PlanarCross*>(&other);
   if ( otherCross )
   {
     return Superclass::Equals(other);
   }
   else
   {
     return false;
   }
 }
<commit_msg>fixed warnings treated as error<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPlanarCross.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"

mitk::PlanarCross::PlanarCross()
: FEATURE_ID_LONGESTDIAMETER( this->AddFeature( "Longest Axis", "mm" ) ),
  FEATURE_ID_SHORTAXISDIAMETER( this->AddFeature( "Short Axis", "mm" ) )
{
  // Cross has two control points at the beginning
  this->ResetNumberOfControlPoints( 2 );

  // Create property for SingleLineMode (default: false)
  this->SetProperty( "SingleLineMode", mitk::BoolProperty::New( false ) );

  // Create helper polyline object (for drawing the orthogonal orientation line)
  this->SetNumberOfHelperPolyLines( 1 );
  m_HelperPolyLinesToBePainted->InsertElement( 0, false );
}

void mitk::PlanarCross::SetSingleLineMode( bool singleLineMode )
{
  this->SetProperty( "SingleLineMode", mitk::BoolProperty::New( singleLineMode ) );
  this->Modified();
}

bool mitk::PlanarCross::GetSingleLineMode() const
{
  const mitk::BoolProperty* singleLineMode = dynamic_cast< mitk::BoolProperty* >(
    this->GetProperty( "SingleLineMode" ).GetPointer() );

  if ( singleLineMode != nullptr )
  {
    return singleLineMode->GetValue();
  }
  return false;
}

bool mitk::PlanarCross::ResetOnPointSelectNeeded() const
{
  return this->GetSingleLineMode() == false || ( m_SelectedControlPoint >= 0 && m_SelectedControlPoint <= 3 );
}

bool mitk::PlanarCross::ResetOnPointSelect()
{
  if ( this->GetSingleLineMode() )
  {
    // In single line mode --> nothing to reset
    return false;
  }

  switch ( m_SelectedControlPoint )
  {
  default:
    // Nothing selected --> nothing to reset
    return false;

  case 0:
    {
      // Control point 0 selected: exchange points 0 and 1
      const Point2D tmpPoint = this->GetControlPoint( 0 );
      this->SetControlPoint( 0, this->GetControlPoint( 1 ) );
      this->SetControlPoint( 1, tmpPoint );
      // FALLS THROUGH!
    }

  case 1:
    {
      // Control point 0 or 1 selected: reset number of control points to two
      this->ResetNumberOfControlPoints( 2 );
      this->SelectControlPoint( 1 );
      return true;
    }

  case 2:
    {
      // Control point 2 selected: replace point 0 with point 3 and point 1 with point 2
      this->SetControlPoint( 0, this->GetControlPoint( 3 ) );
      this->SetControlPoint( 1, this->GetControlPoint( 2 ) );

      // Adjust selected control point, reset number of control points to two
      this->ResetNumberOfControlPoints( 2 );
      this->SelectControlPoint( 1 );
      return true;
    }

  case 3:
    {
      // Control point 3 selected: replace point 0 with point 2 and point 1 with point 3

      this->SetControlPoint( 0, this->GetControlPoint( 2 ) );
      this->SetControlPoint( 1, this->GetControlPoint( 3 ) );

      // Adjust selected control point, reset number of control points to two
      this->ResetNumberOfControlPoints( 2 );
      this->SelectControlPoint( 1 );
      return true;
    }
  }
}

unsigned int mitk::PlanarCross::GetNumberOfFeatures() const
{
  if ( this->GetSingleLineMode() || (this->GetNumberOfControlPoints() < 4) )
  {
    return 1;
  }
  else
  {
    return 2;
  }
}

mitk::Point2D mitk::PlanarCross::ApplyControlPointConstraints( unsigned int index, const Point2D& point )
{
  // Apply spatial constraints from superclass and from this class until the resulting constrained
  // point converges. Although not an optimal implementation, this iterative approach
  // helps to respect both constraints from the superclass and from this class. Without this,
  // situations may occur where control points are constrained by the superclass, but again
  // moved out of the superclass bounds by the subclass, or vice versa.

  unsigned int count = 0; // ensures stop of approach if point does not converge in reasonable time
  Point2D confinedPoint = point;
  Point2D superclassConfinedPoint;
  do
  {
    superclassConfinedPoint = Superclass::ApplyControlPointConstraints( index, confinedPoint );
    confinedPoint = this->InternalApplyControlPointConstraints( index, superclassConfinedPoint );
    ++count;
  } while ( (confinedPoint.EuclideanDistanceTo( superclassConfinedPoint ) > mitk::eps)
         && (count < 32) );

  return confinedPoint;
}

mitk::Point2D mitk::PlanarCross::InternalApplyControlPointConstraints( unsigned int index, const Point2D& point )
{
  // Apply constraints depending on current interaction state
  switch ( index )
  {
  case 2:
    {
      // Check if 3rd control point is outside of the range (2D area) defined by the first
      // line (via the first two control points); if it is outside, clip it to the bounds
      const Point2D p1 = this->GetControlPoint( 0 );
      const Point2D p2 = this->GetControlPoint( 1 );

      Vector2D n1 = p2 - p1;
      n1.Normalize();

      const Vector2D v1 = point - p1;
      const double dotProduct = n1 * v1;
      const Point2D crossPoint = p1 + n1 * dotProduct;;
      const Vector2D crossVector = point - crossPoint;

      if ( dotProduct < 0.0 )
      {
        // Out-of-bounds on the left: clip point to left boundary
        return (p1 + crossVector);
      }
      else if ( dotProduct > p2.EuclideanDistanceTo( p1 ) )
      {
        // Out-of-bounds on the right: clip point to right boundary
        return (p2 + crossVector);
      }
      else
      {
        // Pass back original point
        return point;
      }
    }

  case 3:
    {
      // Constrain 4th control point so that with the 3rd control point it forms
      // a line orthogonal to the first line (constraint 1); the 4th control point
      // must lie on the opposite side of the line defined by the first two control
      // points than the 3rd control point (constraint 2)
      const Point2D p1 = this->GetControlPoint( 0 );
      const Point2D p2 = this->GetControlPoint( 1 );
      const Point2D p3 = this->GetControlPoint( 2 );

      // Calculate distance of original point from orthogonal line the corrected
      // point should lie on to project the point onto this line
      Vector2D n1 = p2 - p1;
      n1.Normalize();

      const Vector2D v1 = point - p3;
      const double dotProduct1 = n1 * v1;

      const Point2D pointOnLine = point - n1 * dotProduct1;

      // Project new point onto line [p1, p2]
      const Vector2D v2 = pointOnLine - p1;
      double dotProduct2 = n1 * v2;

      const Point2D crossingPoint = p1 + n1 * dotProduct2;

      // Determine whether the projected point on the line, or the crossing point should be
      // used (according to the second constraint in the comment above)
      if ( (pointOnLine.SquaredEuclideanDistanceTo( p3 ) > crossingPoint.SquaredEuclideanDistanceTo( p3 ))
        && (pointOnLine.SquaredEuclideanDistanceTo( p3 ) > pointOnLine.SquaredEuclideanDistanceTo( crossingPoint )) )
      {
        return pointOnLine;
      }
      else
      {
        return crossingPoint;
      }
    }

  default:
    return point;
  }
}

void mitk::PlanarCross::GeneratePolyLine()
{
  this->SetNumberOfPolyLines(1);
  this->ClearPolyLines();

  if (this->GetNumberOfControlPoints() > 2)
    this->SetNumberOfPolyLines( 2 );

  for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i)
  {
    if (i < 2)
      this->AppendPointToPolyLine(0, this->GetControlPoint(i));

    if (i > 1)
      this->AppendPointToPolyLine(1, this->GetControlPoint(i));
  }
}

void mitk::PlanarCross::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
{
  // Generate helper polyline (orientation line orthogonal to first line)
  // if the third control point is currently being set
  if ( this->GetNumberOfControlPoints() != 3 )
  {
    m_HelperPolyLinesToBePainted->SetElement( 0, false );
    return;
  }

  m_HelperPolyLinesToBePainted->SetElement( 0, true );

  this->ClearHelperPolyLines();

  // Calculate cross point of first line (p1 to p2) and orthogonal line through
  // the third control point (p3)
  const Point2D p1 = this->GetControlPoint( 0 );
  const Point2D p2 = this->GetControlPoint( 1 );
  const Point2D p3 = this->GetControlPoint( 2 );

  Vector2D n1 = p2 - p1;
  n1.Normalize();

  const Vector2D v1 = p3 - p1;
  const Point2D crossPoint = p1 + n1 * (n1 * v1);

  const Vector2D v2 = crossPoint - p3;
  if ( v2.GetNorm() < 1.0 )
  {
    // If third point is on the first line, draw orthogonal "infinite" line
    // through cross point on line
    Vector2D v0;
    v0[0] = n1[1];
    v0[1] = -n1[0];
    this->AppendPointToHelperPolyLine(0, Point2D(p3 - v0 * 10000.0));
    this->AppendPointToHelperPolyLine(0, Point2D(p3 + v0 * 10000.0));
  }
  else
  {
    // Else, draw orthogonal line starting from third point and crossing the
    // first line, open-ended only on the other side
    this->AppendPointToHelperPolyLine(0, p3);
    this->AppendPointToHelperPolyLine(0, Point2D(p3 + v2 * 10000.0));
  }
}

void mitk::PlanarCross::EvaluateFeaturesInternal()
{
  // Calculate length of first line
  const Point3D &p0 = this->GetWorldControlPoint( 0 );
  const Point3D &p1 = this->GetWorldControlPoint( 1 );
  double l1 = p0.EuclideanDistanceTo( p1 );

  // Calculate length of second line
  double l2 = 0.0;
  if ( !this->GetSingleLineMode() && (this->GetNumberOfControlPoints() > 3) )
  {
    const Point3D &p2 = this->GetWorldControlPoint( 2 );
    const Point3D &p3 = this->GetWorldControlPoint( 3 );
    l2 = p2.EuclideanDistanceTo( p3 );
  }

  double longestDiameter;
  double shortAxisDiameter;
  if ( l1 > l2 )
  {
    longestDiameter = l1;
    shortAxisDiameter = l2;
  }
  else
  {
    longestDiameter = l2;
    shortAxisDiameter = l1;
  }

  this->SetQuantity( FEATURE_ID_LONGESTDIAMETER, longestDiameter );
  this->SetQuantity( FEATURE_ID_SHORTAXISDIAMETER, shortAxisDiameter );
}

void mitk::PlanarCross::PrintSelf( std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf( os, indent );
}

 bool mitk::PlanarCross::Equals(const mitk::PlanarFigure& other) const
 {
   const mitk::PlanarCross* otherCross = dynamic_cast<const mitk::PlanarCross*>(&other);
   if ( otherCross )
   {
     return Superclass::Equals(other);
   }
   else
   {
     return false;
   }
 }
<|endoftext|>


<commit_before>#include <propagators/ApportioningPropagator.hpp>

int ApportioningPropagator::getIndividualCount(Individual ** population, int populationSize, Individual * target) {
	int numUses=0, i, *useCounts;
	useCounts = this->getUseCount(population, populationSize, target);

	for (i = 0; i < populationSize; i++) if (useCounts[i] > 0) numUses++;

	return numUses;
}

int * ApportioningPropagator::getUseCount(Individual ** population, int populationSize, Individual * target) {
	int i, k;
	Genome * genome;
	GenePool ** pools;
	int genomeLength;
	int * indexes;

	int * numUses = (int*)malloc(sizeof(int)*populationSize);

	for (i = 0; i < populationSize; i++) {
		numUses[i] = 0;
		genome = population[i]->getGenome();
		pools = genome->getGenePools();
		genomeLength = genome->getGenomeLength();
		indexes = genome->getGenome();

		for (k = 0; k < genomeLength; k++) {
			if (target == (Individual*)pools[k]->getIndex(indexes[k])) {
				numUses[i]++;
			}
		}
	}

	return numUses;
}
<commit_msg>[ApportioningPropagator]: Clean up memory leak<commit_after>#include <propagators/ApportioningPropagator.hpp>

int ApportioningPropagator::getIndividualCount(Individual ** population, int populationSize, Individual * target) {
	int numUses=0, i, *useCounts;
	useCounts = this->getUseCount(population, populationSize, target);

	for (i = 0; i < populationSize; i++) if (useCounts[i] > 0) numUses++;
	free(useCounts);

	return numUses;
}

int * ApportioningPropagator::getUseCount(Individual ** population, int populationSize, Individual * target) {
	int i, k;
	Genome * genome;
	GenePool ** pools;
	int genomeLength;
	int * indexes;

	int * numUses = (int*)malloc(sizeof(int)*populationSize);

	for (i = 0; i < populationSize; i++) {
		numUses[i] = 0;
		genome = population[i]->getGenome();
		pools = genome->getGenePools();
		genomeLength = genome->getGenomeLength();
		indexes = genome->getGenome();

		for (k = 0; k < genomeLength; k++) {
			if (target == (Individual*)pools[k]->getIndex(indexes[k])) {
				numUses[i]++;
			}
		}
	}

	return numUses;
}
<|endoftext|>