<commit_before>
#include "geometry/cartesian_product.hpp"

#include <algorithm>
#include <type_traits>

#include "quantities/named_quantities.hpp"
#include "quantities/tuples.hpp"

namespace principia {
namespace geometry {
namespace internal_cartesian_product {

using quantities::Apply;
using quantities::Apply2;

template<typename LTuple,
         typename RTuple,
         typename = std::make_integer_sequence<
             int,
             std::max(std::tuple_size_v<LTuple>, std::tuple_size_v<RTuple>)>>
struct CartesianProductAdditiveGroup;

template<typename LTuple, typename RTuple, int... indices>
struct CartesianProductAdditiveGroup<LTuple, RTuple,
                                     std::integer_sequence<int, indices...>> {
  // The types of the result of addition and subtraction, with suitable
  // checks for the void case of Apply2.
  template<typename L, typename R>
  using Sum =
      std::conditional_t<std::is_void_v<L>, R,
                         std::conditional_t<std::is_void_v<R>, L,
                                            quantities::Sum<L, R>>>;
  template<typename L, typename R>
  using Difference =
      std::conditional_t<std::is_void_v<L>, R,
                         std::conditional_t<std::is_void_v<R>, L,
                                            quantities::Difference<L, R>>>;

  static constexpr Apply2<Sum, LTuple, RTuple> Add(
      LTuple const& left,
      RTuple const& right);
  static constexpr Apply2<Difference, LTuple, RTuple> Subtract(
      LTuple const& left,
      RTuple const& right);
};

template<typename LTuple, typename RTuple, int... indices>
constexpr auto CartesianProductAdditiveGroup<
    LTuple, RTuple,
    std::integer_sequence<int, indices...>>::Add(LTuple const& left,
                                                 RTuple const& right)
    -> Apply2<Sum, LTuple, RTuple> {
  return {(
      indices < std::min(std::tuple_size_v<LTuple>, std::tuple_size_v<RTuple>)
          ? std::get<indices>(left) + std::get<indices>(right)
          : indices < std::tuple_size_v<LTuple>
                ? std::get<indices>(left)
                : std::get<indices>(right))...};
}

template<typename LTuple, typename RTuple, int... indices>
constexpr auto CartesianProductAdditiveGroup<
    LTuple, RTuple,
    std::integer_sequence<int, indices...>>::Subtract(LTuple const& left,
                                                      RTuple const& right)
    -> Apply2<Difference, LTuple, RTuple> {
  return {
      (indices < std::min(std::tuple_size_v<LTuple>, std::tuple_size_v<RTuple>)
           ? std::get<indices>(left) - std::get<indices>(right)
           : indices < std::tuple_size_v<LTuple>
                 ? std::get<indices>(left)
                 : -std::get<indices>(right))...};
}

template<typename Scalar,
         typename Tuple,
         typename = std::make_integer_sequence<int, std::tuple_size_v<Tuple>>>
struct CartesianProductVectorSpace;

template<typename Scalar, typename Tuple, int... indices>
struct CartesianProductVectorSpace<Scalar,
                                   Tuple,
                                   std::integer_sequence<int, indices...>> {
  template<typename T>
  using ScalarLeftProduct = quantities::Product<Scalar, T>;
  template<typename T>
  using ScalarRightProduct = quantities::Product<T, Scalar>;
  template<typename T>
  using Quotient = quantities::Quotient<T, Scalar>;

  static constexpr typename Apply<ScalarLeftProduct, Tuple> Multiply(
      Scalar const& left,
      Tuple const& right);
  static constexpr typename Apply<ScalarRightProduct, Tuple> Multiply(
      Tuple const& left,
      Scalar const& right);

  static constexpr typename Apply<Quotient, Tuple> Divide(
      Tuple const& left,
      Scalar const& right);
};

template<typename Scalar, typename Tuple, int... indices>
constexpr auto CartesianProductVectorSpace<
    Scalar, Tuple,
    std::integer_sequence<int, indices...>>::Multiply(Scalar const& left,
                                                      Tuple const& right)
    -> typename Apply<ScalarLeftProduct, Tuple> {
  return {left * std::get<indices>(right)...};
}

template<typename Scalar, typename Tuple, int... indices>
constexpr auto CartesianProductVectorSpace<
    Scalar, Tuple,
    std::integer_sequence<int, indices...>>::Multiply(Tuple const& left,
                                                      Scalar const& right)
    -> typename Apply<ScalarRightProduct, Tuple> {
  return {std::get<indices>(left) * right...};
}

template<typename Scalar, typename Tuple, int... indices>
constexpr auto CartesianProductVectorSpace<
    Scalar, Tuple,
    std::integer_sequence<int, indices...>>::Divide(Tuple const& left,
                                                    Scalar const& right)
    -> typename Apply<Quotient, Tuple> {
  return {std::get<indices>(left) / right...};
}

}  // namespace internal_cartesian_product

namespace cartesian_product {

template<typename LTuple, typename RTuple>
constexpr auto operator+(LTuple const& left, RTuple const& right) {
  return internal_cartesian_product::
      CartesianProductAdditiveGroup<LTuple, RTuple>::Add(left, right);
}

template<typename LTuple, typename RTuple>
constexpr auto operator-(LTuple const& left, RTuple const& right) {
  return internal_cartesian_product::
      CartesianProductAdditiveGroup<LTuple, RTuple>::Subtract(left, right);
}

template<typename Scalar, typename Tuple, typename>
constexpr auto operator*(Scalar const left, Tuple const& right) {
  return internal_cartesian_product::
      CartesianProductVectorSpace<Scalar, Tuple>::Multiply(left, right);
}

template<typename Tuple, typename Scalar, typename>
constexpr auto operator*(Tuple const& left, Scalar const right) {
  return internal_cartesian_product::
      CartesianProductVectorSpace<Scalar, Tuple>::Multiply(left, right);
}

template<typename Scalar, typename Tuple>
constexpr auto operator/(Tuple const& left, Scalar const& right) {
  return internal_cartesian_product::
      CartesianProductVectorSpace<Scalar, Tuple>::Divide(left, right);
}

}  // namespace cartesian_product
}  // namespace geometry
}  // namespace principia
<commit_msg>Cleanup.<commit_after>
#include "geometry/cartesian_product.hpp"

#include <algorithm>
#include <type_traits>

#include "quantities/named_quantities.hpp"
#include "quantities/tuples.hpp"

namespace principia {
namespace geometry {
namespace internal_cartesian_product {

using quantities::Apply;
using quantities::Apply2;

template<typename LTuple, typename RTuple,
         typename = std::make_integer_sequence<
             int,
             std::max(std::tuple_size_v<LTuple>, std::tuple_size_v<RTuple>)>>
struct CartesianProductAdditiveGroup;

template<typename LTuple, typename RTuple, int... indices>
struct CartesianProductAdditiveGroup<LTuple, RTuple,
                                     std::integer_sequence<int, indices...>> {
  // The types of the result of addition and subtraction, with suitable
  // checks for the void case of Apply2.
  template<typename L, typename R>
  using Sum =
      std::conditional_t<std::is_void_v<L>, R,
                         std::conditional_t<std::is_void_v<R>, L,
                                            quantities::Sum<L, R>>>;
  template<typename L, typename R>
  using Difference =
      std::conditional_t<std::is_void_v<L>, R,
                         std::conditional_t<std::is_void_v<R>, L,
                                            quantities::Difference<L, R>>>;

  static constexpr Apply2<Sum, LTuple, RTuple> Add(
      LTuple const& left,
      RTuple const& right);
  static constexpr Apply2<Difference, LTuple, RTuple> Subtract(
      LTuple const& left,
      RTuple const& right);
};

template<typename LTuple, typename RTuple, int... indices>
constexpr auto CartesianProductAdditiveGroup<
    LTuple, RTuple,
    std::integer_sequence<int, indices...>>::Add(LTuple const& left,
                                                 RTuple const& right)
    -> Apply2<Sum, LTuple, RTuple> {
  return {(
      indices < std::min(std::tuple_size_v<LTuple>, std::tuple_size_v<RTuple>)
          ? std::get<indices>(left) + std::get<indices>(right)
          : indices < std::tuple_size_v<LTuple>
                ? std::get<indices>(left)
                : std::get<indices>(right))...};
}

template<typename LTuple, typename RTuple, int... indices>
constexpr auto CartesianProductAdditiveGroup<
    LTuple, RTuple,
    std::integer_sequence<int, indices...>>::Subtract(LTuple const& left,
                                                      RTuple const& right)
    -> Apply2<Difference, LTuple, RTuple> {
  return {
      (indices < std::min(std::tuple_size_v<LTuple>, std::tuple_size_v<RTuple>)
           ? std::get<indices>(left) - std::get<indices>(right)
           : indices < std::tuple_size_v<LTuple>
                 ? std::get<indices>(left)
                 : -std::get<indices>(right))...};
}

template<typename Scalar, typename Tuple,
         typename = std::make_integer_sequence<int, std::tuple_size_v<Tuple>>>
struct CartesianProductVectorSpace;

template<typename Scalar, typename Tuple, int... indices>
struct CartesianProductVectorSpace<Scalar,
                                   Tuple,
                                   std::integer_sequence<int, indices...>> {
  template<typename T>
  using ScalarLeftProduct = quantities::Product<Scalar, T>;
  template<typename T>
  using ScalarRightProduct = quantities::Product<T, Scalar>;
  template<typename T>
  using Quotient = quantities::Quotient<T, Scalar>;

  static constexpr typename Apply<ScalarLeftProduct, Tuple> Multiply(
      Scalar const& left,
      Tuple const& right);
  static constexpr typename Apply<ScalarRightProduct, Tuple> Multiply(
      Tuple const& left,
      Scalar const& right);

  static constexpr typename Apply<Quotient, Tuple> Divide(
      Tuple const& left,
      Scalar const& right);
};

template<typename Scalar, typename Tuple, int... indices>
constexpr auto CartesianProductVectorSpace<
    Scalar, Tuple,
    std::integer_sequence<int, indices...>>::Multiply(Scalar const& left,
                                                      Tuple const& right)
    -> typename Apply<ScalarLeftProduct, Tuple> {
  return {left * std::get<indices>(right)...};
}

template<typename Scalar, typename Tuple, int... indices>
constexpr auto CartesianProductVectorSpace<
    Scalar, Tuple,
    std::integer_sequence<int, indices...>>::Multiply(Tuple const& left,
                                                      Scalar const& right)
    -> typename Apply<ScalarRightProduct, Tuple> {
  return {std::get<indices>(left) * right...};
}

template<typename Scalar, typename Tuple, int... indices>
constexpr auto CartesianProductVectorSpace<
    Scalar, Tuple,
    std::integer_sequence<int, indices...>>::Divide(Tuple const& left,
                                                    Scalar const& right)
    -> typename Apply<Quotient, Tuple> {
  return {std::get<indices>(left) / right...};
}

}  // namespace internal_cartesian_product

namespace cartesian_product {

template<typename LTuple, typename RTuple>
constexpr auto operator+(LTuple const& left, RTuple const& right) {
  return internal_cartesian_product::
      CartesianProductAdditiveGroup<LTuple, RTuple>::Add(left, right);
}

template<typename LTuple, typename RTuple>
constexpr auto operator-(LTuple const& left, RTuple const& right) {
  return internal_cartesian_product::
      CartesianProductAdditiveGroup<LTuple, RTuple>::Subtract(left, right);
}

template<typename Scalar, typename Tuple, typename>
constexpr auto operator*(Scalar const left, Tuple const& right) {
  return internal_cartesian_product::
      CartesianProductVectorSpace<Scalar, Tuple>::Multiply(left, right);
}

template<typename Tuple, typename Scalar, typename>
constexpr auto operator*(Tuple const& left, Scalar const right) {
  return internal_cartesian_product::
      CartesianProductVectorSpace<Scalar, Tuple>::Multiply(left, right);
}

template<typename Scalar, typename Tuple>
constexpr auto operator/(Tuple const& left, Scalar const& right) {
  return internal_cartesian_product::
      CartesianProductVectorSpace<Scalar, Tuple>::Divide(left, right);
}

}  // namespace cartesian_product
}  // namespace geometry
}  // namespace principia
<|endoftext|>


<commit_before>// STL
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

// Boost
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/scoped_ptr.hpp>

// Local
#include "pyp-topics.hh"
#include "corpus.hh"
#include "contexts_corpus.hh"
#include "gzstream.hh"
#include "mt19937ar.h"

static const char *REVISION = "$Rev$";

// Namespaces
using namespace boost;
using namespace boost::program_options;
using namespace std;

int main(int argc, char **argv)
{
  std::cout << "Pitman Yor topic models: Copyright 2010 Phil Blunsom\n";
  std::cout << REVISION << '\n' << std::endl;

  ////////////////////////////////////////////////////////////////////////////////////////////
  // Command line processing
  variables_map vm;

  // Command line processing
  {
    options_description cmdline_options("Allowed options");
    cmdline_options.add_options()
      ("help,h", "print help message")
      ("data,d", value<string>(), "file containing the documents and context terms")
      ("topics,t", value<int>()->default_value(50), "number of topics")
      ("document-topics-out,o", value<string>(), "file to write the document topics to")
      ("default-topics-out", value<string>(), "file to write default term topic assignments.")
      ("topic-words-out,w", value<string>(), "file to write the topic word distribution to")
      ("samples,s", value<int>()->default_value(10), "number of sampling passes through the data")
      ("backoff-type", value<string>(), "backoff type: none|simple")
      ("filter-singleton-contexts", "filter singleton contexts")
      ("hierarchical-topics", "Use a backoff hierarchical PYP as the P0 for the document topics distribution.")
      ;
    store(parse_command_line(argc, argv, cmdline_options), vm);
    notify(vm);

    if (vm.count("help")) {
      cout << cmdline_options << "\n";
      return 1;
    }
  }
  ////////////////////////////////////////////////////////////////////////////////////////////

  if (!vm.count("data")) {
    cerr << "Please specify a file containing the data." << endl;
    return 1;
  }

  // seed the random number generator
  //mt_init_genrand(time(0));

  PYPTopics model(vm["topics"].as<int>(), vm.count("hierarchical-topics"));

  // read the data
  BackoffGenerator* backoff_gen=0;
  if (vm.count("backoff-type")) {
    if (vm["backoff-type"].as<std::string>() == "none") {
      backoff_gen = 0;
    }
    else if (vm["backoff-type"].as<std::string>() == "simple") {
      backoff_gen = new SimpleBackoffGenerator();
    }
    else {
      std::cerr << "Backoff type (--backoff-type) must be one of none|simple." << std::endl;
      return(1);
    }
  }

  ContextsCorpus contexts_corpus;
  contexts_corpus.read_contexts(vm["data"].as<string>(), backoff_gen, vm.count("filter-singleton-contexts"));
  model.set_backoff(contexts_corpus.backoff_index());

  if (backoff_gen)
    delete backoff_gen;

  // train the sampler
  model.sample(contexts_corpus, vm["samples"].as<int>());

  if (vm.count("document-topics-out")) {
    ogzstream documents_out(vm["document-topics-out"].as<string>().c_str());

    int document_id=0;
    std::set<int> all_terms;
    for (Corpus::const_iterator corpusIt=contexts_corpus.begin();
         corpusIt != contexts_corpus.end(); ++corpusIt, ++document_id) {
      std::vector<int> unique_terms;
      for (Document::const_iterator docIt=corpusIt->begin();
           docIt != corpusIt->end(); ++docIt) {
        if (unique_terms.empty() || *docIt != unique_terms.back())
          unique_terms.push_back(*docIt);
      }
      documents_out << contexts_corpus.key(document_id) << '\t';
      for (std::vector<int>::const_iterator termIt=unique_terms.begin();
           termIt != unique_terms.end(); ++termIt) {
        if (termIt != unique_terms.begin())
          documents_out << " ||| ";
        std::vector<std::string> strings = contexts_corpus.context2string(*termIt);
        std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(documents_out, " "));
        documents_out << "||| C=" << model.max(document_id, *termIt);

        all_terms.insert(*termIt);
      }
      documents_out << std::endl;
    }
    documents_out.close();

    std::ofstream default_topics(vm["default-topics-out"].as<string>().c_str());
    default_topics << model.max_topic() << std::endl;
    for (std::set<int>::const_iterator termIt=all_terms.begin(); termIt != all_terms.end(); ++termIt) {
      std::vector<std::string> strings = contexts_corpus.context2string(*termIt);
      std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(documents_out, " "));
      default_topics << model.max(-1, *termIt) << std::endl;
    }
  }

  if (vm.count("topic-words-out")) {
    ogzstream topics_out(vm["topic-words-out"].as<string>().c_str());
    model.print_topic_terms(topics_out);
    topics_out.close();
  }

  std::cout << std::endl;

  return 0;
}
<commit_msg><commit_after>// STL
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

// Boost
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/scoped_ptr.hpp>

// Local
#include "pyp-topics.hh"
#include "corpus.hh"
#include "contexts_corpus.hh"
#include "gzstream.hh"
#include "mt19937ar.h"

static const char *REVISION = "$Rev$";

// Namespaces
using namespace boost;
using namespace boost::program_options;
using namespace std;

int main(int argc, char **argv)
{
  std::cout << "Pitman Yor topic models: Copyright 2010 Phil Blunsom\n";
  std::cout << REVISION << '\n' << std::endl;

  ////////////////////////////////////////////////////////////////////////////////////////////
  // Command line processing
  variables_map vm;

  // Command line processing
  {
    options_description cmdline_options("Allowed options");
    cmdline_options.add_options()
      ("help,h", "print help message")
      ("data,d", value<string>(), "file containing the documents and context terms")
      ("topics,t", value<int>()->default_value(50), "number of topics")
      ("document-topics-out,o", value<string>(), "file to write the document topics to")
      ("default-topics-out", value<string>(), "file to write default term topic assignments.")
      ("topic-words-out,w", value<string>(), "file to write the topic word distribution to")
      ("samples,s", value<int>()->default_value(10), "number of sampling passes through the data")
      ("backoff-type", value<string>(), "backoff type: none|simple")
      ("filter-singleton-contexts", "filter singleton contexts")
      ("hierarchical-topics", "Use a backoff hierarchical PYP as the P0 for the document topics distribution.")
      ;
    store(parse_command_line(argc, argv, cmdline_options), vm);
    notify(vm);

    if (vm.count("help")) {
      cout << cmdline_options << "\n";
      return 1;
    }
  }
  ////////////////////////////////////////////////////////////////////////////////////////////

  if (!vm.count("data")) {
    cerr << "Please specify a file containing the data." << endl;
    return 1;
  }

  // seed the random number generator
  //mt_init_genrand(time(0));

  PYPTopics model(vm["topics"].as<int>(), vm.count("hierarchical-topics"));

  // read the data
  BackoffGenerator* backoff_gen=0;
  if (vm.count("backoff-type")) {
    if (vm["backoff-type"].as<std::string>() == "none") {
      backoff_gen = 0;
    }
    else if (vm["backoff-type"].as<std::string>() == "simple") {
      backoff_gen = new SimpleBackoffGenerator();
    }
    else {
      std::cerr << "Backoff type (--backoff-type) must be one of none|simple." << std::endl;
      return(1);
    }
  }

  ContextsCorpus contexts_corpus;
  contexts_corpus.read_contexts(vm["data"].as<string>(), backoff_gen, vm.count("filter-singleton-contexts"));
  model.set_backoff(contexts_corpus.backoff_index());

  if (backoff_gen)
    delete backoff_gen;

  // train the sampler
  model.sample(contexts_corpus, vm["samples"].as<int>());

  if (vm.count("document-topics-out")) {
    ogzstream documents_out(vm["document-topics-out"].as<string>().c_str());

    int document_id=0;
    std::set<int> all_terms;
    for (Corpus::const_iterator corpusIt=contexts_corpus.begin();
         corpusIt != contexts_corpus.end(); ++corpusIt, ++document_id) {
      std::vector<int> unique_terms;
      for (Document::const_iterator docIt=corpusIt->begin();
           docIt != corpusIt->end(); ++docIt) {
        if (unique_terms.empty() || *docIt != unique_terms.back())
          unique_terms.push_back(*docIt);
      }
      documents_out << contexts_corpus.key(document_id) << '\t';
      for (std::vector<int>::const_iterator termIt=unique_terms.begin();
           termIt != unique_terms.end(); ++termIt) {
        if (termIt != unique_terms.begin())
          documents_out << " ||| ";
        std::vector<std::string> strings = contexts_corpus.context2string(*termIt);
        std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(documents_out, " "));
        documents_out << "||| C=" << model.max(document_id, *termIt);

        all_terms.insert(*termIt);
      }
      documents_out << std::endl;
    }
    documents_out.close();

    std::ofstream default_topics(vm["default-topics-out"].as<string>().c_str());
    default_topics << model.max_topic() << std::endl;
    for (std::set<int>::const_iterator termIt=all_terms.begin(); termIt != all_terms.end(); ++termIt) {
      std::vector<std::string> strings = contexts_corpus.context2string(*termIt);
      std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(default_topics, " "));
      default_topics << "||| " << model.max(-1, *termIt) << std::endl;
    }
  }

  if (vm.count("topic-words-out")) {
    ogzstream topics_out(vm["topic-words-out"].as<string>().c_str());
    model.print_topic_terms(topics_out);
    topics_out.close();
  }

  std::cout << std::endl;

  return 0;
}
<|endoftext|>


<commit_before>/*
Author 		:	manojpandey
Algorithm	:	Kosraju-Sharir Algorithm for
				finding strongly connected components
				in a graph. (Also called: Kosaraju's two-pass algorithm)

1. Perform DFS on grapg G, store finishing times of the vertices.
2. Perform DFS on Grev, where vertices are ordered by decreasing order of finishing time.
3. Each tree in the second DFS is a SCC of the graph.

Time Complexity	:	O(V+E) <-- Optimal
					O(V^2) , if adjacency matrix is used
*/

#include <iostream>
#include <vector>
#include <stack>
#include <cstdio>
#include <cstring>
#include <map>

using namespace std;

// From TopCoder
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define tr(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define rep(i,n) for (i=0; i<n ; i++)
#define rep1(i,n) for (i=1; i<=n ; i++)
#define MAX 11111

// Assuming vertices are labeled 0...V-1
vi G[MAX], Grev[MAX];
bool explored[MAX];
int leader[MAX], finish[MAX], order[MAX], t = -1, parent = 0, V, E;

// running DFS on the reverse graph
void dfs_reverse(int i) {
    explored[i] = true;
    for(vi::iterator it = Grev[i].begin(); it != Grev[i].end(); it++)
        if(!explored[*it])
            dfs_reverse(*it);
    t++;
    finish[i] = t;
}

// running DFS on the actual graph
void dfs(int i) {
    explored[i] = true;
    leader[i] = parent;
    for(vi::iterator it = G[i].begin(); it != G[i].end(); it++) {
        cout << *it << " ";
        if(!explored[*it]) {
            dfs(*it);
        }
    }
    cout << "\n";
}

// Addendum:
// check if u & v are in the same connected component
bool stronglyConnected(int u, int v)    {
    return leader[u] == leader[v];
}

int main()  {
    int i, u, v, countCC, Q;

    //freopen("input.txt", "r", stdin);

    scanf("%d %d", &V, &E); // Enter the number of vertices & edges
    for(i=0; i<E; i++)  {   // Enter E edges : u -> v
        scanf("%d %d", &u, &v);
        G[u].push_back(v);  // Insert into the adjacency list of the graph
        Grev[v].push_back(u);   // and the reverse graph
    }

    printf("Original graph :\n");
    for(i=0; i<V; i++)  {
        if(!G[i].empty())   {
            printf("%d : ", i);
            for(vi::iterator it = G[i].begin(); it != G[i].end(); it++)
                printf("%d ", *it);
            printf("\n");
        }
    }

    printf("Reverse graph :\n");
    for(i=0; i<V; i++)  {
        if(!Grev[i].empty())   {
            printf("%d : ", i);
            for(vi::iterator it = Grev[i].begin(); it != Grev[i].end(); it++)
                printf("%d ", *it);
            printf("\n");
        }
    }

    // run dfs on the reverse graph to get reverse postorder
    memset(explored, false, V*sizeof(bool));
    for(i=0; i<V; i++)  {
        if(!explored[i])
            dfs_reverse(i);
        order[finish[i]] = i;
    }

    printf("Strongly Connected Components: \n");
    // run dfs on the actual graph in reverse postorder
    memset(explored, false, V*sizeof(bool));
    countCC = 0;
    for(i=V-1; i>=0; i--)
        if(!explored[order[i]]) {
            parent = order[i];
            dfs(order[i]);
            countCC++;
        }

    printf("Total no. of strongly connected components : %d\n", countCC);

    return 0;
}

/*
Sample:

5 5	// vertices, edges
1 3
2 1
3 2
1 4
4 5

SCC:
3 SCC's in given graph

{{5}, {4}, {1, 2, 3}}
*/<commit_msg>Kosaraju-Sharir Algorithm for SCC<commit_after>/*
Author 		:	manojpandey
Algorithm	:	Kosraju-Sharir Algorithm for
				finding strongly connected components
				in a graph. (Also called: Kosaraju's two-pass algorithm)

1. Perform DFS on grapg G, store finishing times of the vertices.
2. Perform DFS on Grev, where vertices are ordered by decreasing order of finishing time.
3. Each tree in the second DFS is a SCC of the graph.

Time Complexity	:	O(V+E) <-- Optimal
					O(V^2) , if adjacency matrix is used
*/

#include <iostream>
#include <vector>
#include <stack>
#include <cstdio>
#include <cstring>
#include <map>

using namespace std;

// From TopCoder
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define tr(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define rep(i,n) for (i=0; i<n ; i++)
#define rep1(i,n) for (i=1; i<=n ; i++)
#define MAX 11111

// Assuming vertices are labeled 0...V-1
vi G[MAX], Grev[MAX];
bool explored[MAX];
int leader[MAX], finish[MAX], order[MAX], t = -1, parent = 0, V, E;

// running DFS on the reverse graph
void dfs_reverse(int i) {
    explored[i] = true;
    for(vi::iterator it = Grev[i].begin(); it != Grev[i].end(); it++)
        if(!explored[*it])
            dfs_reverse(*it);
    t++;
    finish[i] = t;
}

// running DFS on the actual graph
void dfs(int i) {
    explored[i] = true;
    leader[i] = parent;
    for(vi::iterator it = G[i].begin(); it != G[i].end(); it++) {
        cout << *it << " ";
        if(!explored[*it]) {
            dfs(*it);
        }
    }
    cout << "\n";
}

// Addendum:
// check if u & v are in the same connected component
bool stronglyConnected (int u, int v)    {
    return leader[u] == leader[v];
}

int main()  {
    int i, u, v, countCC, Q;

    //freopen("input.txt", "r", stdin);

    scanf("%d %d", &V, &E); // Enter the number of vertices & edges
    for(i=0; i<E; i++)  {   // Enter E edges : u -> v
        scanf("%d %d", &u, &v);
        G[u].push_back(v);  // Insert into the adjacency list of the graph
        Grev[v].push_back(u);   // and the reverse graph
    }

    printf("Original graph :\n");
    for(i=0; i<V; i++)  {
        if(!G[i].empty())   {
            printf("%d : ", i);
            for(vi::iterator it = G[i].begin(); it != G[i].end(); it++)
                printf("%d ", *it);
            printf("\n");
        }
    }

    printf("Reverse graph :\n");
    for(i=0; i<V; i++)  {
        if(!Grev[i].empty())   {
            printf("%d : ", i);
            for(vi::iterator it = Grev[i].begin(); it != Grev[i].end(); it++)
                printf("%d ", *it);
            printf("\n");
        }
    }

    // run dfs on the reverse graph to get reverse postorder
    memset(explored, false, V*sizeof(bool));
    for(i=0; i<V; i++)  {
        if(!explored[i])
            dfs_reverse(i);
        order[finish[i]] = i;
    }

    printf("Strongly Connected Components: \n");
    // run dfs on the actual graph in reverse postorder
    memset(explored, false, V*sizeof(bool));
    countCC = 0;
    for(i=V-1; i>=0; i--)
        if(!explored[order[i]]) {
            parent = order[i];
            dfs(order[i]);
            countCC++;
        }

    printf("Total no. of strongly connected components : %d\n", countCC);

    return 0;
}

/*
Sample Input:

5 5	// vertices, edges
1 3
2 1
3 2
1 4
4 5

Output:
SCC:
3 SCC's in given graph

{{5}, {4}, {1, 2, 3}}

 */
<|endoftext|>


<commit_before>#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <sys/mman.h>
#include <stdio.h>
// Physical base address of GPIO
const unsigned gpio_address = 0x400d0000;
// Length of memory-mapped IO window
const unsigned gpio_size = 0xff;
const int gpio_led1_offset = 0x12C; // Offset for LED1
const int gpio_led2_offset = 0x130; // Offset for LED2
const int gpio_led3_offset = 0x134; // Offset for LED3
const int gpio_led4_offset = 0x138; // Offset for LED4
const int gpio_led5_offset = 0x13C; // Offset for LED5
const int gpio_led6_offset = 0x140; // Offset for LED6
const int gpio_led7_offset = 0x144; // Offset for LED7
const int gpio_led8_offset = 0x148; // Offset for LED8
const int gpio_sw1_offset = 0x14C; // Offset for Switch 1
const int gpio_sw2_offset = 0x150; // Offset for Switch 2
const int gpio_sw3_offset = 0x154; // Offset for Switch 3
const int gpio_sw4_offset = 0x158; // Offset for Switch 4
const int gpio_sw5_offset = 0x15C; // Offset for Switch 5
const int gpio_sw6_offset = 0x160; // Offset for Switch 6
const int gpio_sw7_offset = 0x164; // Offset for Switch 7
const int gpio_sw8_offset = 0x168; // Offset for Switch 8
const int gpio_pbtnl_offset = 0x16C; // Offset for left push button
const int gpio_pbtnr_offset = 0x170; // Offset for right push button
const int gpio_pbtnu_offset = 0x174; // Offset for up push button
const int gpio_pbtnd_offset = 0x178; // Offset for down push button
const int gpio_pbtnc_offset = 0x17C; // Offset for center push button

class ZedBoard {
	char *ptr;
	int fd;
public:
	ZedBoard() {
		this->fd = open("/dev/mem", O_RDWR);
		this->ptr = (char *) mmap(
			NULL,
			gpio_size,
			PROT_READ | PROT_WRITE,
			MAP_SHARED,
			this->fd,
			gpio_address);
	}

	~ZedBoard() {
		munmap(this->ptr, gpio_size);
		close(this->fd);
	}

	/**
	 * Write a 4-byte value at the specified general-purpose I/O location.
	 *
	 * @param ptr Base address returned by 'mmap'.
	 * @parem offset Offset where device is mapped.
	 * @param value Value to be written.
	 */
	void registerWrite(int offset, int value) {
		* (int *) (this->ptr + offset) = value;
	}

	/**
	 * Read a 4-byte value from the specified general-purpose I/O location.
	 *
	 * @param ptr Base address returned by 'mmap'.
	 * @param offset Offset where device is mapped.
	 * @return Value read.
	 */
	int registerRead(int offset) {
		return * (int *) (this->ptr + offset);
	}

	/** Set the state of the LED with the given index.
	 *
	 * @param ptr Base address for general-purpose I/O
	 * @parem led_index LED index between 0 and 7
	 * @param state Turn on (1) or off (0)
	 */
	void setLedState(int led_index, int state) {
		int offset;
		switch(led_index) {
			case 0:
				offset = gpio_led1_offset;
				break;
			case 1:
				offset = gpio_led2_offset;
				break;
			case 2:
				offset = gpio_led3_offset;
				break;
			case 3:
				offset = gpio_led4_offset;
				break;
			case 4:
				offset = gpio_led5_offset;
				break;
			case 5:
				offset = gpio_led6_offset;
				break;
			case 6:
				offset = gpio_led7_offset;
				break;
			case 7:
				offset = gpio_led8_offset;
				break;
			default:
				return;
		}
		* (int *) (this->ptr + offset) = state;
	}

	int readSwitch(int switch_index) {
		switch(switch_index) {
			case 0:
				return registerRead(gpio_sw1_offset);
			case 1:
				return registerRead(gpio_sw2_offset);
			case 2:
				return registerRead(gpio_sw3_offset);
			case 3:
				return registerRead(gpio_sw4_offset);
			case 4:
				return registerRead(gpio_sw5_offset);
			case 5:
				return registerRead(gpio_sw6_offset);
			case 6:
				return registerRead(gpio_sw7_offset);
			case 7:
				return registerRead(gpio_sw8_offset);
		}
		return -1;
	}

	int readDirection() {
		if(registerRead(gpio_pbtnu_offset)) {
			return 1;
		}
		if(registerRead(gpio_pbtnd_offset)) {
			return 2;
		}
		if(registerRead(gpio_pbtnl_offset)) {
			return 3;
		}
		if(registerRead(gpio_pbtnr_offset)) {
			return 4;
		}
		if(registerRead(gpio_pbtnc_offset)) {
			return 5;
		}
		return 0;
	}

	int getSwitchState() {
		int state = 0;
		for(int i = 0; i < 8; i++) {
			if(readSwitch(i)) {
				state += 0b1 << i;
			}
		}
		return state;
	}
};

int main() {
	// Initialize
	ZedBoard *z = new ZedBoard();

	int state = z->getSwitchState();

	bool pressed = false;
	while(true) {
		int direction = z->readDirection();
		if(!pressed && direction == 1) {
			pressed = true;
			state += 1;
		}
		else if(!pressed && direction == 2) {
			pressed = true;
			state -= 1;
		}
		else if(!pressed && direction == 3) {
			pressed = true;
			state <<= 1;
		}
		else if(!pressed && direction == 4) {
			pressed = true;
			state >>= 1;
		}
		else if(!pressed && direction == 5) {
			pressed = true;
			state = z->getSwitchState();
		}
		else if(direction == 0) {
			pressed = false;
		}

		for(int i = 0; i < 8; i++) {
			z->setLedState(i, (state >> i) & 1);
		}
		usleep(100 * 1000);
	}

	delete z;
	return 0;
}
<commit_msg>Implement speed<commit_after>#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <sys/mman.h>
#include <stdio.h>
// Physical base address of GPIO
const unsigned gpio_address = 0x400d0000;
// Length of memory-mapped IO window
const unsigned gpio_size = 0xff;
const int gpio_led1_offset = 0x12C; // Offset for LED1
const int gpio_led2_offset = 0x130; // Offset for LED2
const int gpio_led3_offset = 0x134; // Offset for LED3
const int gpio_led4_offset = 0x138; // Offset for LED4
const int gpio_led5_offset = 0x13C; // Offset for LED5
const int gpio_led6_offset = 0x140; // Offset for LED6
const int gpio_led7_offset = 0x144; // Offset for LED7
const int gpio_led8_offset = 0x148; // Offset for LED8
const int gpio_sw1_offset = 0x14C; // Offset for Switch 1
const int gpio_sw2_offset = 0x150; // Offset for Switch 2
const int gpio_sw3_offset = 0x154; // Offset for Switch 3
const int gpio_sw4_offset = 0x158; // Offset for Switch 4
const int gpio_sw5_offset = 0x15C; // Offset for Switch 5
const int gpio_sw6_offset = 0x160; // Offset for Switch 6
const int gpio_sw7_offset = 0x164; // Offset for Switch 7
const int gpio_sw8_offset = 0x168; // Offset for Switch 8
const int gpio_pbtnl_offset = 0x16C; // Offset for left push button
const int gpio_pbtnr_offset = 0x170; // Offset for right push button
const int gpio_pbtnu_offset = 0x174; // Offset for up push button
const int gpio_pbtnd_offset = 0x178; // Offset for down push button
const int gpio_pbtnc_offset = 0x17C; // Offset for center push button

class ZedBoard {
	char *ptr;
	int fd;
public:
	ZedBoard() {
		this->fd = open("/dev/mem", O_RDWR);
		this->ptr = (char *) mmap(
			NULL,
			gpio_size,
			PROT_READ | PROT_WRITE,
			MAP_SHARED,
			this->fd,
			gpio_address);
	}

	~ZedBoard() {
		munmap(this->ptr, gpio_size);
		close(this->fd);
	}

	/**
	 * Write a 4-byte value at the specified general-purpose I/O location.
	 *
	 * @param ptr Base address returned by 'mmap'.
	 * @parem offset Offset where device is mapped.
	 * @param value Value to be written.
	 */
	void registerWrite(int offset, int value) {
		* (int *) (this->ptr + offset) = value;
	}

	/**
	 * Read a 4-byte value from the specified general-purpose I/O location.
	 *
	 * @param ptr Base address returned by 'mmap'.
	 * @param offset Offset where device is mapped.
	 * @return Value read.
	 */
	int registerRead(int offset) {
		return * (int *) (this->ptr + offset);
	}

	/** Set the state of the LED with the given index.
	 *
	 * @param ptr Base address for general-purpose I/O
	 * @parem led_index LED index between 0 and 7
	 * @param state Turn on (1) or off (0)
	 */
	void setLedState(int led_index, int state) {
		int offset;
		switch(led_index) {
			case 0:
				offset = gpio_led1_offset;
				break;
			case 1:
				offset = gpio_led2_offset;
				break;
			case 2:
				offset = gpio_led3_offset;
				break;
			case 3:
				offset = gpio_led4_offset;
				break;
			case 4:
				offset = gpio_led5_offset;
				break;
			case 5:
				offset = gpio_led6_offset;
				break;
			case 6:
				offset = gpio_led7_offset;
				break;
			case 7:
				offset = gpio_led8_offset;
				break;
			default:
				return;
		}
		* (int *) (this->ptr + offset) = state;
	}

	int readSwitch(int switch_index) {
		switch(switch_index) {
			case 0:
				return registerRead(gpio_sw1_offset);
			case 1:
				return registerRead(gpio_sw2_offset);
			case 2:
				return registerRead(gpio_sw3_offset);
			case 3:
				return registerRead(gpio_sw4_offset);
			case 4:
				return registerRead(gpio_sw5_offset);
			case 5:
				return registerRead(gpio_sw6_offset);
			case 6:
				return registerRead(gpio_sw7_offset);
			case 7:
				return registerRead(gpio_sw8_offset);
		}
		return -1;
	}

	int readDirection() {
		if(registerRead(gpio_pbtnu_offset)) {
			return 1;
		}
		if(registerRead(gpio_pbtnd_offset)) {
			return 2;
		}
		if(registerRead(gpio_pbtnl_offset)) {
			return 3;
		}
		if(registerRead(gpio_pbtnr_offset)) {
			return 4;
		}
		if(registerRead(gpio_pbtnc_offset)) {
			return 5;
		}
		return 0;
	}

	int getSwitchState() {
		int state = 0;
		for(int i = 0; i < 8; i++) {
			if(readSwitch(i)) {
				state += 0b1 << i;
			}
		}
		return state;
	}
};

int main() {
	// Initialize
	ZedBoard *z = new ZedBoard();

	int state = z->getSwitchState();

	int c = 0;
	bool pressed = false;
	bool right = false;
	int speed = 0;
	while(true) {
		if(c % 10 == 0) {
			state += right ? speed : -speed;
		}
		int direction = z->readDirection();
		if(!pressed && direction == 1) {
			pressed = true;
			speed += 1;
		}
		else if(!pressed && direction == 2) {
			pressed = true;
			speed -= 1;
		}
		else if(!pressed && direction == 3) {
			pressed = true;
			right = false;
		}
		else if(!pressed && direction == 4) {
			pressed = true;
			right = true;
		}
		else if(!pressed && direction == 5) {
			pressed = true;
			state = z->getSwitchState();
		}
		else if(direction == 0) {
			pressed = false;
		}

		for(int i = 0; i < 8; i++) {
			z->setLedState(i, (state >> i) & 1);
		}
		usleep(100 * 1000);
		c++;
	}

	delete z;
	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <cstring>
#include "util.h"

TestResult vectorTest(int iters, int num_elements, bool sorted,
                      int num_add_remove);
TestResult intrusiveVectorTest(int iters, int num_elements, bool sorted,
                               int num_add_remove);
TestResult intrusiveListTest(int iters, int num_elements, bool sorted,
                             int num_add_remove);
TestResult setTest(int iters, int num_elements, int num_add_remove);
TestResult unordered_setTest(int iters, int num_elements, int num_add_remove);

void printUsage();
int strToInt(const char*);

int main(int argc, char *argv[])
{
  using std::cout;

  int NUM_ITERS = 1000;
  int NUM_ELEMENTS = 100000;
  int NUM_ADD_REMOVE = 100;

  try {
    for (int i = 1; i < argc; i++) {
      if (strcmp(argv[i], "-iters") == 0 && i+1 < argc) {
        NUM_ITERS = strToInt(argv[++i]);
      } else if (strcmp(argv[i], "-elems") == 0 && i+1 < argc) {
        NUM_ELEMENTS = strToInt(argv[++i]);
      } else if (strcmp(argv[i], "-add_rem") == 0 && i+1 < argc) {
        NUM_ADD_REMOVE = strToInt(argv[++i]);
      } else {
        cout << "Error: Invalid option '" << argv[i] << "'\n";
        printUsage();
        return EXIT_FAILURE;
      }
    }
  } catch (std::exception &e) {
    cout << e.what() << "\n";
    printUsage();
    return EXIT_FAILURE;
  }
  if (NUM_ITERS < 0 || NUM_ELEMENTS < 0 || NUM_ADD_REMOVE < 0) {
    cout << "Options -iters, -elems, and -add_rem must all be greater than 0\n";
    printUsage();
    return EXIT_FAILURE;
  }

  cout << "Number times each test is run: " << NUM_ITERS << "\n";
  cout << "Number elements in vectors/lists: " << NUM_ELEMENTS << "\n";
  cout << "Number elements to add/remove in a frame: " << NUM_ADD_REMOVE
        << "\n\n";

  Test tests[] = {
    runTest("vector", vectorTest,
            NUM_ITERS, NUM_ELEMENTS, false, NUM_ADD_REMOVE),
    runTest("vector (sorted)", vectorTest,
            NUM_ITERS, NUM_ELEMENTS, true, NUM_ADD_REMOVE),
    runTest("intrusive vector",
            intrusiveVectorTest, NUM_ITERS, NUM_ELEMENTS,
            false, NUM_ADD_REMOVE),
    runTest("intrusive vector (sorted)",
            intrusiveVectorTest, NUM_ITERS, NUM_ELEMENTS,
            true, NUM_ADD_REMOVE),
    runTest("intrusive list", intrusiveListTest,
            NUM_ITERS, NUM_ELEMENTS, false, NUM_ADD_REMOVE),
    runTest("intrusive list (sorted)", intrusiveListTest,
            NUM_ITERS, NUM_ELEMENTS, true, NUM_ADD_REMOVE),
    runTest("set", setTest, NUM_ITERS, NUM_ELEMENTS, NUM_ADD_REMOVE),
    runTest("unordered_set", setTest, NUM_ITERS, NUM_ELEMENTS, NUM_ADD_REMOVE)
  };

  cout << std::setprecision(2) << std::fixed;
  cout << "\nIteration times(min, max, average) in ms: \n";
  for (auto &test : tests) {
    cout << test.test_name << " test: ("
         << test.result.iterate.min << ", "
         << test.result.iterate.max << ", "
         << test.result.iterate.avg << ")\n";
  }

  cout << "\nAdd element times(min, max, average) in ms: \n";
  for (auto &test : tests) {
    cout << test.test_name << " test: ("
         << test.result.add.min << ", "
         << test.result.add.max << ", "
         << test.result.add.avg << ")\n";
  }

  cout << "\nRemove element times(min, max, average) in ms: \n";
  for (auto &test : tests) {
    cout << test.test_name << " test: ("
         << test.result.remove.min << ", "
         << test.result.remove.max << ", "
         << test.result.remove.avg << ")\n";
  }

  return 0;
}

void printUsage()
{
  std::cout << "Usage: vector_vs_list_test [-iters COUNT] "
               "[-elems NUM] [-add_rem NUM]\n"
               "\tDefaults: -iters 1000 -elems 100000 -add_rem 100\n";
}

int strToInt(const char *str)
{
  char *str_end = nullptr; // for detecting errors in strtol
  int n = strtol(str, &str_end, 10);
  if (errno == ERANGE){
    errno = 0;
    throw std::runtime_error("Error: Number entered is too large.");
  }
  if (str == str_end) {
    throw std::runtime_error("Error converting string to int");
  }
  return n;
}

<commit_msg>Added cstdlib for EXIT_FAILURE define<commit_after>#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include "util.h"

TestResult vectorTest(int iters, int num_elements, bool sorted,
                      int num_add_remove);
TestResult intrusiveVectorTest(int iters, int num_elements, bool sorted,
                               int num_add_remove);
TestResult intrusiveListTest(int iters, int num_elements, bool sorted,
                             int num_add_remove);
TestResult setTest(int iters, int num_elements, int num_add_remove);
TestResult unordered_setTest(int iters, int num_elements, int num_add_remove);

void printUsage();
int strToInt(const char*);

int main(int argc, char *argv[])
{
  using std::cout;

  int NUM_ITERS = 1000;
  int NUM_ELEMENTS = 100000;
  int NUM_ADD_REMOVE = 100;

  try {
    for (int i = 1; i < argc; i++) {
      if (strcmp(argv[i], "-iters") == 0 && i+1 < argc) {
        NUM_ITERS = strToInt(argv[++i]);
      } else if (strcmp(argv[i], "-elems") == 0 && i+1 < argc) {
        NUM_ELEMENTS = strToInt(argv[++i]);
      } else if (strcmp(argv[i], "-add_rem") == 0 && i+1 < argc) {
        NUM_ADD_REMOVE = strToInt(argv[++i]);
      } else {
        cout << "Error: Invalid option '" << argv[i] << "'\n";
        printUsage();
        return EXIT_FAILURE;
      }
    }
  } catch (std::exception &e) {
    cout << e.what() << "\n";
    printUsage();
    return EXIT_FAILURE;
  }
  if (NUM_ITERS < 0 || NUM_ELEMENTS < 0 || NUM_ADD_REMOVE < 0) {
    cout << "Options -iters, -elems, and -add_rem must all be greater than 0\n";
    printUsage();
    return EXIT_FAILURE;
  }

  cout << "Number times each test is run: " << NUM_ITERS << "\n";
  cout << "Number elements in vectors/lists: " << NUM_ELEMENTS << "\n";
  cout << "Number elements to add/remove in a frame: " << NUM_ADD_REMOVE
        << "\n\n";

  Test tests[] = {
    runTest("vector", vectorTest,
            NUM_ITERS, NUM_ELEMENTS, false, NUM_ADD_REMOVE),
    runTest("vector (sorted)", vectorTest,
            NUM_ITERS, NUM_ELEMENTS, true, NUM_ADD_REMOVE),
    runTest("intrusive vector",
            intrusiveVectorTest, NUM_ITERS, NUM_ELEMENTS,
            false, NUM_ADD_REMOVE),
    runTest("intrusive vector (sorted)",
            intrusiveVectorTest, NUM_ITERS, NUM_ELEMENTS,
            true, NUM_ADD_REMOVE),
    runTest("intrusive list", intrusiveListTest,
            NUM_ITERS, NUM_ELEMENTS, false, NUM_ADD_REMOVE),
    runTest("intrusive list (sorted)", intrusiveListTest,
            NUM_ITERS, NUM_ELEMENTS, true, NUM_ADD_REMOVE),
    runTest("set", setTest, NUM_ITERS, NUM_ELEMENTS, NUM_ADD_REMOVE),
    runTest("unordered_set", setTest, NUM_ITERS, NUM_ELEMENTS, NUM_ADD_REMOVE)
  };

  cout << std::setprecision(2) << std::fixed;
  cout << "\nIteration times(min, max, average) in ms: \n";
  for (auto &test : tests) {
    cout << test.test_name << " test: ("
         << test.result.iterate.min << ", "
         << test.result.iterate.max << ", "
         << test.result.iterate.avg << ")\n";
  }

  cout << "\nAdd element times(min, max, average) in ms: \n";
  for (auto &test : tests) {
    cout << test.test_name << " test: ("
         << test.result.add.min << ", "
         << test.result.add.max << ", "
         << test.result.add.avg << ")\n";
  }

  cout << "\nRemove element times(min, max, average) in ms: \n";
  for (auto &test : tests) {
    cout << test.test_name << " test: ("
         << test.result.remove.min << ", "
         << test.result.remove.max << ", "
         << test.result.remove.avg << ")\n";
  }

  return 0;
}

void printUsage()
{
  std::cout << "Usage: vector_vs_list_test [-iters COUNT] "
               "[-elems NUM] [-add_rem NUM]\n"
               "\tDefaults: -iters 1000 -elems 100000 -add_rem 100\n";
}

int strToInt(const char *str)
{
  char *str_end = nullptr; // for detecting errors in strtol
  int n = strtol(str, &str_end, 10);
  if (errno == ERANGE){
    errno = 0;
    throw std::runtime_error("Error: Number entered is too large.");
  }
  if (str == str_end) {
    throw std::runtime_error("Error converting string to int");
  }
  return n;
}

<|endoftext|>


<commit_before><commit_msg>Sphere メンバ関数追加<commit_after><|endoftext|>


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

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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.

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

// CTK includes
#include "ctkDicomAvailableDataHelper.h"
#include "ctkDicomAvailableDataHelper.h"
#include "ctkDicomObjectLocatorCache.h"
#include <ctkDICOMDataset.h>

// DCMTK includes
#include <dcmtk/dcmdata/dcdeftag.h>

namespace ctkDicomAvailableDataHelper {

//------------------------------------------------------------------------------
class ctkDicomAvailableDataAccessorPrivate
{
//  Q_DECLARE_PUBLIC(ctkDicomAvailableDataAccessor);
protected:

public:
  ctkDicomAvailableDataAccessorPrivate(ctkDicomAppHosting::AvailableData& availableData) :
      m_AvailableData(availableData) { };

  ctkDicomAppHosting::AvailableData& m_AvailableData;
};

//----------------------------------------------------------------------------
ctkDicomAvailableDataAccessor::ctkDicomAvailableDataAccessor(ctkDicomAppHosting::AvailableData& ad)
  : d_ptr(new ctkDicomAvailableDataAccessorPrivate(ad))
{
}

ctkDicomAvailableDataAccessor::~ctkDicomAvailableDataAccessor() {};

//----------------------------------------------------------------------------
ctkDicomAppHosting::Patient* ctkDicomAvailableDataAccessor::getPatient(const ctkDicomAppHosting::Patient& patient) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
      if(pit->id==patient.id)
        return &(*pit);
    }
  return NULL;
}

//----------------------------------------------------------------------------
ctkDicomAppHosting::Study* ctkDicomAvailableDataAccessor::getStudy(const QString& studyUID) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
    for (QList<ctkDicomAppHosting::Study>::Iterator sit = pit->studies.begin();
      sit < pit->studies.end(); sit++)
      {
          if(sit->studyUID==studyUID)
            return &(*sit);
      }
    }
  return NULL;
}

//----------------------------------------------------------------------------
ctkDicomAppHosting::Series* ctkDicomAvailableDataAccessor::getSeries(const QString& seriesUID) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
    for (QList<ctkDicomAppHosting::Study>::Iterator sit = pit->studies.begin();
      sit < pit->studies.end(); sit++)
      {
      for (QList<ctkDicomAppHosting::Series>::Iterator seit = sit->series.begin();
        seit < sit->series.end(); seit++)
        {
          if(seit->seriesUID==seriesUID)
            return &(*seit);
        }
      }
    }
  return NULL;
}

//----------------------------------------------------------------------------
void ctkDicomAvailableDataAccessor::find(const ctkDicomAppHosting::Patient& patient,
                                         const QString& studyUID,
                                         const QString& seriesUID,
                                         ctkDicomAppHosting::Patient*& patientResult,
                                         ctkDicomAppHosting::Study*& studyResult,
                                         ctkDicomAppHosting::Series*& seriesResult) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  patientResult=NULL;
  studyResult=NULL;
  seriesResult=NULL;
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
    if(pit->id==patient.id)
      {
      patientResult = &(*pit);
      for (QList<ctkDicomAppHosting::Study>::Iterator sit = pit->studies.begin();
        sit < pit->studies.end(); sit++)
        {
        if(sit->studyUID==studyUID)
          {
          studyResult = &(*sit);
          for (QList<ctkDicomAppHosting::Series>::Iterator seit = sit->series.begin();
            seit < sit->series.end(); seit++)
            {
            if(seit->seriesUID==seriesUID)
              {
              seriesResult=&(*seit);
              return;
              }
            }
            return;
          }
        }
      return;
      }
    }
}

//----------------------------------------------------------------------------
bool addNonDICOMToAvailableData(ctkDicomAppHosting::AvailableData& data,
                        ctkDicomObjectLocatorCache* objectLocatorCache,
                        long length,
                        long offset,
                        const QString& uri)
{
  if(objectLocatorCache == NULL)
    return false;

  ctkDicomAppHosting::ObjectDescriptor objectDescriptor;
  ctkDicomAppHosting::Study study;
  ctkDicomAppHosting::Series series;
  ctkDicomAppHosting::Patient patient;

  QFileInfo fileinfo(uri);
  QString ext = fileinfo.suffix();

  QString uuid = QUuid::createUuid().toString();
  objectDescriptor.descriptorUUID = uuid;
  //objectDescriptor.mimeType = "text/plain";
  objectDescriptor.classUID = "";
  objectDescriptor.transferSyntaxUID = "";
  objectDescriptor.modality = "";

  //the default mime type is set to plain text
  if ( ext.compare("xml") == 0)
	  objectDescriptor.mimeType = "text/xml";
  else if ( ext.compare("txt") == 0)
	  objectDescriptor.mimeType = "text/plain";
  else if ( (ext.compare("jpg") == 0) || (ext.compare("jpeg") == 0))
	  objectDescriptor.mimeType = "image/jpeg";
  else if ( ext.compare("bmp") == 0)
	  objectDescriptor.mimeType = "image/bmp";
  else
	   objectDescriptor.mimeType = "text/plain"; //default

  //ctkDicomAppHosting::Patient* ppatient;
  //ctkDicomAppHosting::Study* pstudy;
  //ctkDicomAppHosting::Series* pseries;

  data.objectDescriptors.append(objectDescriptor);

  ctkDicomAppHosting::ObjectLocator locator;
  locator.locator = objectDescriptor.descriptorUUID;
  locator.source = objectDescriptor.descriptorUUID;
  locator.offset = offset;
  locator.length = length;
  locator.transferSyntax = objectDescriptor.transferSyntaxUID;
  locator.URI = uri;

  objectLocatorCache->insert(objectDescriptor.descriptorUUID, locator);
  return true;
}

bool addToAvailableData(ctkDicomAppHosting::AvailableData& data,
                        ctkDicomObjectLocatorCache* objectLocatorCache,
                        const ctkDICOMDataset& dataset,
                        long length,
                        long offset,
                        const QString& uri)
{
  if(objectLocatorCache == NULL)
    return false;

  ctkDicomAppHosting::ObjectDescriptor objectDescriptor;
  ctkDicomAppHosting::Study study;
  ctkDicomAppHosting::Series series;
  ctkDicomAppHosting::Patient patient;
  patient.name = dataset.GetElementAsString(DCM_PatientName);
  qDebug()<<"Patient:  " << patient.name;
  patient.id = dataset.GetElementAsString(DCM_PatientID);
  patient.assigningAuthority = dataset.GetElementAsString(DCM_IssuerOfPatientID);
  patient.sex = dataset.GetElementAsString(DCM_PatientSex);
  patient.birthDate = dataset.GetElementAsString(DCM_PatientBirthDate);

  study.studyUID = dataset.GetElementAsString(DCM_StudyInstanceUID);
  series.seriesUID = dataset.GetElementAsString(DCM_SeriesInstanceUID);

  QString uuid = QUuid::createUuid().toString();
  objectDescriptor.descriptorUUID = uuid;
  objectDescriptor.mimeType = "application/dicom";
  objectDescriptor.classUID = dataset.GetElementAsString(DCM_SOPClassUID);
  objectDescriptor.transferSyntaxUID = dataset.GetElementAsString(DCM_TransferSyntaxUID);
  objectDescriptor.modality = dataset.GetElementAsString(DCM_Modality);

  ctkDicomAppHosting::Patient* ppatient;
  ctkDicomAppHosting::Study* pstudy;
  ctkDicomAppHosting::Series* pseries;

  ctkDicomAvailableDataAccessor(data).find(patient, study.studyUID, series.seriesUID,
    ppatient, pstudy, pseries);

  if(pseries==NULL)
  {
    series.objectDescriptors.append(objectDescriptor);
    if(pstudy==NULL)
    {
      study.series.append(series);
      if(ppatient==NULL)
      {
        patient.studies.append(study);
        data.patients.append(patient);
      }
      else
      {
        ppatient->studies.append(study);
      }
    }
    else
    {
      pstudy->series.append(series);
    }
  }
  else
  {
    pseries->objectDescriptors.append(objectDescriptor);
  }

  ctkDicomAppHosting::ObjectLocator locator;
  locator.locator = objectDescriptor.descriptorUUID;
  locator.source = objectDescriptor.descriptorUUID;
  locator.offset = offset;
  locator.length = length;
  locator.transferSyntax = objectDescriptor.transferSyntaxUID;
  locator.URI = uri;

  objectLocatorCache->insert(objectDescriptor.descriptorUUID, locator);
  return true;
}

//----------------------------------------------------------------------------
bool addToAvailableData(ctkDicomAppHosting::AvailableData& data,
                        ctkDicomObjectLocatorCache* objectLocatorCache,
                        const QString& filename)
{
  QFileInfo fileinfo(filename);
  qDebug() << filename << " " << fileinfo.exists();

  QString uri("file:///");
  uri.append(fileinfo.absoluteFilePath());

  //first check if its a non-DICOM file, if so add it first.
  QString ext = fileinfo.suffix();
  if ( (ext.compare("txt") == 0) || (ext.compare("xml") ==0) || (ext.compare("jpg") ==0) || (ext.compare("bmp") ==0) || (ext.compare("csv") ==0)|| (ext.compare("nii") ==0))
  {
  	  qDebug() << "adding Non DICOM File";
      return addNonDICOMToAvailableData(data, objectLocatorCache, fileinfo.size(), 0, uri);
  }
  //this could be a DICOM file then
  ctkDICOMDataset ctkdataset;
  ctkdataset.InitializeFromFile(filename, EXS_Unknown, EGL_noChange, 400);

  return addToAvailableData(data, objectLocatorCache, ctkdataset, fileinfo.size(), 0, uri);

}

//----------------------------------------------------------------------------
bool appendToAvailableData(ctkDicomAppHosting::AvailableData& dest,
                        const ctkDicomAppHosting::AvailableData& src)
{
  dest.objectDescriptors.append(src.objectDescriptors);
  dest.patients.append(src.patients);
  return true;
}

//----------------------------------------------------------------------------
void appendAllUuids(const ctkDicomAppHosting::Patient& patient, QList<QUuid> & uuidlist)
{
  // Loop over patient level object descriptors
  foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, patient.objectDescriptors)
    {
    uuidlist.append(objectDescriptor.descriptorUUID);
    }

  // Loop over studies
  foreach(const ctkDicomAppHosting::Study& study, patient.studies)
    {
    // Loop over study level object descriptors
    foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, study.objectDescriptors)
      {
      uuidlist.append(objectDescriptor.descriptorUUID);
      }
    // Loop over series
    foreach(const ctkDicomAppHosting::Series& series, study.series)
      {
      // Loop over series level object descriptors
      foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, series.objectDescriptors)
        {
        uuidlist.append(objectDescriptor.descriptorUUID);
        }
      }
    }
}

//----------------------------------------------------------------------------
QList<QUuid> getAllUuids(const ctkDicomAppHosting::Patient& patient)
{
  QList<QUuid> uuidlist;
  appendAllUuids(patient, uuidlist);
  return uuidlist;
}

//----------------------------------------------------------------------------
QList<QUuid> getAllUuids(const ctkDicomAppHosting::AvailableData& availableData)
{
  QList<QUuid> uuidlist;

  // Loop over top level object descriptors
  foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, availableData.objectDescriptors)
    {
    uuidlist.append(objectDescriptor.descriptorUUID);
    }

   // Loop over patients
  foreach(const ctkDicomAppHosting::Patient& patient, availableData.patients)
    {
    appendAllUuids(patient, uuidlist);
    }
  return uuidlist;
}

} //end namespace ctkDicomAvailableDataHelper
<commit_msg>Allow transfer of nrrd files<commit_after>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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.

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

// CTK includes
#include "ctkDicomAvailableDataHelper.h"
#include "ctkDicomAvailableDataHelper.h"
#include "ctkDicomObjectLocatorCache.h"
#include <ctkDICOMDataset.h>

// DCMTK includes
#include <dcmtk/dcmdata/dcdeftag.h>

namespace ctkDicomAvailableDataHelper {

//------------------------------------------------------------------------------
class ctkDicomAvailableDataAccessorPrivate
{
//  Q_DECLARE_PUBLIC(ctkDicomAvailableDataAccessor);
protected:

public:
  ctkDicomAvailableDataAccessorPrivate(ctkDicomAppHosting::AvailableData& availableData) :
      m_AvailableData(availableData) { };

  ctkDicomAppHosting::AvailableData& m_AvailableData;
};

//----------------------------------------------------------------------------
ctkDicomAvailableDataAccessor::ctkDicomAvailableDataAccessor(ctkDicomAppHosting::AvailableData& ad)
  : d_ptr(new ctkDicomAvailableDataAccessorPrivate(ad))
{
}

ctkDicomAvailableDataAccessor::~ctkDicomAvailableDataAccessor() {};

//----------------------------------------------------------------------------
ctkDicomAppHosting::Patient* ctkDicomAvailableDataAccessor::getPatient(const ctkDicomAppHosting::Patient& patient) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
      if(pit->id==patient.id)
        return &(*pit);
    }
  return NULL;
}

//----------------------------------------------------------------------------
ctkDicomAppHosting::Study* ctkDicomAvailableDataAccessor::getStudy(const QString& studyUID) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
    for (QList<ctkDicomAppHosting::Study>::Iterator sit = pit->studies.begin();
      sit < pit->studies.end(); sit++)
      {
          if(sit->studyUID==studyUID)
            return &(*sit);
      }
    }
  return NULL;
}

//----------------------------------------------------------------------------
ctkDicomAppHosting::Series* ctkDicomAvailableDataAccessor::getSeries(const QString& seriesUID) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
    for (QList<ctkDicomAppHosting::Study>::Iterator sit = pit->studies.begin();
      sit < pit->studies.end(); sit++)
      {
      for (QList<ctkDicomAppHosting::Series>::Iterator seit = sit->series.begin();
        seit < sit->series.end(); seit++)
        {
          if(seit->seriesUID==seriesUID)
            return &(*seit);
        }
      }
    }
  return NULL;
}

//----------------------------------------------------------------------------
void ctkDicomAvailableDataAccessor::find(const ctkDicomAppHosting::Patient& patient,
                                         const QString& studyUID,
                                         const QString& seriesUID,
                                         ctkDicomAppHosting::Patient*& patientResult,
                                         ctkDicomAppHosting::Study*& studyResult,
                                         ctkDicomAppHosting::Series*& seriesResult) const
{
  const Q_D(ctkDicomAvailableDataAccessor);
  ctkDicomAppHosting::AvailableData & ad(d->m_AvailableData);
  patientResult=NULL;
  studyResult=NULL;
  seriesResult=NULL;
  for (QList<ctkDicomAppHosting::Patient>::Iterator pit = ad.patients.begin();
    pit < ad.patients.end(); pit++)
    {
    if(pit->id==patient.id)
      {
      patientResult = &(*pit);
      for (QList<ctkDicomAppHosting::Study>::Iterator sit = pit->studies.begin();
        sit < pit->studies.end(); sit++)
        {
        if(sit->studyUID==studyUID)
          {
          studyResult = &(*sit);
          for (QList<ctkDicomAppHosting::Series>::Iterator seit = sit->series.begin();
            seit < sit->series.end(); seit++)
            {
            if(seit->seriesUID==seriesUID)
              {
              seriesResult=&(*seit);
              return;
              }
            }
            return;
          }
        }
      return;
      }
    }
}

//----------------------------------------------------------------------------
bool addNonDICOMToAvailableData(ctkDicomAppHosting::AvailableData& data,
                        ctkDicomObjectLocatorCache* objectLocatorCache,
                        long length,
                        long offset,
                        const QString& uri)
{
  if(objectLocatorCache == NULL)
    return false;

  ctkDicomAppHosting::ObjectDescriptor objectDescriptor;
  ctkDicomAppHosting::Study study;
  ctkDicomAppHosting::Series series;
  ctkDicomAppHosting::Patient patient;

  QFileInfo fileinfo(uri);
  QString ext = fileinfo.suffix();

  QString uuid = QUuid::createUuid().toString();
  objectDescriptor.descriptorUUID = uuid;
  //objectDescriptor.mimeType = "text/plain";
  objectDescriptor.classUID = "";
  objectDescriptor.transferSyntaxUID = "";
  objectDescriptor.modality = "";

  //the default mime type is set to plain text
  if ( ext.compare("xml") == 0)
	  objectDescriptor.mimeType = "text/xml";
  else if ( ext.compare("txt") == 0)
	  objectDescriptor.mimeType = "text/plain";
  else if ( (ext.compare("jpg") == 0) || (ext.compare("jpeg") == 0))
	  objectDescriptor.mimeType = "image/jpeg";
  else if ( ext.compare("bmp") == 0)
	  objectDescriptor.mimeType = "image/bmp";
  else
	   objectDescriptor.mimeType = "text/plain"; //default

  //ctkDicomAppHosting::Patient* ppatient;
  //ctkDicomAppHosting::Study* pstudy;
  //ctkDicomAppHosting::Series* pseries;

  data.objectDescriptors.append(objectDescriptor);

  ctkDicomAppHosting::ObjectLocator locator;
  locator.locator = objectDescriptor.descriptorUUID;
  locator.source = objectDescriptor.descriptorUUID;
  locator.offset = offset;
  locator.length = length;
  locator.transferSyntax = objectDescriptor.transferSyntaxUID;
  locator.URI = uri;

  objectLocatorCache->insert(objectDescriptor.descriptorUUID, locator);
  return true;
}

bool addToAvailableData(ctkDicomAppHosting::AvailableData& data,
                        ctkDicomObjectLocatorCache* objectLocatorCache,
                        const ctkDICOMDataset& dataset,
                        long length,
                        long offset,
                        const QString& uri)
{
  if(objectLocatorCache == NULL)
    return false;

  ctkDicomAppHosting::ObjectDescriptor objectDescriptor;
  ctkDicomAppHosting::Study study;
  ctkDicomAppHosting::Series series;
  ctkDicomAppHosting::Patient patient;
  patient.name = dataset.GetElementAsString(DCM_PatientName);
  qDebug()<<"Patient:  " << patient.name;
  patient.id = dataset.GetElementAsString(DCM_PatientID);
  patient.assigningAuthority = dataset.GetElementAsString(DCM_IssuerOfPatientID);
  patient.sex = dataset.GetElementAsString(DCM_PatientSex);
  patient.birthDate = dataset.GetElementAsString(DCM_PatientBirthDate);

  study.studyUID = dataset.GetElementAsString(DCM_StudyInstanceUID);
  series.seriesUID = dataset.GetElementAsString(DCM_SeriesInstanceUID);

  QString uuid = QUuid::createUuid().toString();
  objectDescriptor.descriptorUUID = uuid;
  objectDescriptor.mimeType = "application/dicom";
  objectDescriptor.classUID = dataset.GetElementAsString(DCM_SOPClassUID);
  objectDescriptor.transferSyntaxUID = dataset.GetElementAsString(DCM_TransferSyntaxUID);
  objectDescriptor.modality = dataset.GetElementAsString(DCM_Modality);

  ctkDicomAppHosting::Patient* ppatient;
  ctkDicomAppHosting::Study* pstudy;
  ctkDicomAppHosting::Series* pseries;

  ctkDicomAvailableDataAccessor(data).find(patient, study.studyUID, series.seriesUID,
    ppatient, pstudy, pseries);

  if(pseries==NULL)
  {
    series.objectDescriptors.append(objectDescriptor);
    if(pstudy==NULL)
    {
      study.series.append(series);
      if(ppatient==NULL)
      {
        patient.studies.append(study);
        data.patients.append(patient);
      }
      else
      {
        ppatient->studies.append(study);
      }
    }
    else
    {
      pstudy->series.append(series);
    }
  }
  else
  {
    pseries->objectDescriptors.append(objectDescriptor);
  }

  ctkDicomAppHosting::ObjectLocator locator;
  locator.locator = objectDescriptor.descriptorUUID;
  locator.source = objectDescriptor.descriptorUUID;
  locator.offset = offset;
  locator.length = length;
  locator.transferSyntax = objectDescriptor.transferSyntaxUID;
  locator.URI = uri;

  objectLocatorCache->insert(objectDescriptor.descriptorUUID, locator);
  return true;
}

//----------------------------------------------------------------------------
bool addToAvailableData(ctkDicomAppHosting::AvailableData& data,
                        ctkDicomObjectLocatorCache* objectLocatorCache,
                        const QString& filename)
{
  QFileInfo fileinfo(filename);
  qDebug() << filename << " " << fileinfo.exists();

  QString uri("file:///");
  uri.append(fileinfo.absoluteFilePath());

  //first check if its a non-DICOM file, if so add it first.
  QString ext = fileinfo.suffix();
  if ( (ext.compare("txt") == 0) || (ext.compare("xml") ==0) || (ext.compare("jpg") ==0) ||
       (ext.compare("bmp") ==0) || (ext.compare("csv") ==0) || (ext.compare("nii") ==0) ||
       (ext.compare("nrrd") ==0) )
  {
  	  qDebug() << "adding Non DICOM File";
      return addNonDICOMToAvailableData(data, objectLocatorCache, fileinfo.size(), 0, uri);
  }
  //this could be a DICOM file then
  ctkDICOMDataset ctkdataset;
  ctkdataset.InitializeFromFile(filename, EXS_Unknown, EGL_noChange, 400);

  return addToAvailableData(data, objectLocatorCache, ctkdataset, fileinfo.size(), 0, uri);

}

//----------------------------------------------------------------------------
bool appendToAvailableData(ctkDicomAppHosting::AvailableData& dest,
                        const ctkDicomAppHosting::AvailableData& src)
{
  dest.objectDescriptors.append(src.objectDescriptors);
  dest.patients.append(src.patients);
  return true;
}

//----------------------------------------------------------------------------
void appendAllUuids(const ctkDicomAppHosting::Patient& patient, QList<QUuid> & uuidlist)
{
  // Loop over patient level object descriptors
  foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, patient.objectDescriptors)
    {
    uuidlist.append(objectDescriptor.descriptorUUID);
    }

  // Loop over studies
  foreach(const ctkDicomAppHosting::Study& study, patient.studies)
    {
    // Loop over study level object descriptors
    foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, study.objectDescriptors)
      {
      uuidlist.append(objectDescriptor.descriptorUUID);
      }
    // Loop over series
    foreach(const ctkDicomAppHosting::Series& series, study.series)
      {
      // Loop over series level object descriptors
      foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, series.objectDescriptors)
        {
        uuidlist.append(objectDescriptor.descriptorUUID);
        }
      }
    }
}

//----------------------------------------------------------------------------
QList<QUuid> getAllUuids(const ctkDicomAppHosting::Patient& patient)
{
  QList<QUuid> uuidlist;
  appendAllUuids(patient, uuidlist);
  return uuidlist;
}

//----------------------------------------------------------------------------
QList<QUuid> getAllUuids(const ctkDicomAppHosting::AvailableData& availableData)
{
  QList<QUuid> uuidlist;

  // Loop over top level object descriptors
  foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, availableData.objectDescriptors)
    {
    uuidlist.append(objectDescriptor.descriptorUUID);
    }

   // Loop over patients
  foreach(const ctkDicomAppHosting::Patient& patient, availableData.patients)
    {
    appendAllUuids(patient, uuidlist);
    }
  return uuidlist;
}

} //end namespace ctkDicomAvailableDataHelper
<|endoftext|>


<commit_before>#include <hydra/system/playersystem.hpp>

#include <imgui/imgui.h>

#include <hydra/ext/openmp.hpp>

#include <hydra/component/playercomponent.hpp>
#include <hydra/component/transformcomponent.hpp>
#include <hydra/component/cameracomponent.hpp>
#include <hydra/component/weaponcomponent.hpp>
#include <hydra/component/lifecomponent.hpp>
#include <hydra/component/movementcomponent.hpp>
#include <hydra/component/soundfxcomponent.hpp>
#include <hydra/component/perkcomponent.hpp>
#include <hydra/component/rigidbodycomponent.hpp>

#include <btBulletDynamicsCommon.h>

#include <hydra/engine.hpp>

using namespace Hydra::System;
using namespace Hydra::Component;

using world = Hydra::World::World;

PlayerSystem::PlayerSystem() {}
PlayerSystem::~PlayerSystem() {}

float lerp(float a, float b, float f) {
	return a + f * (b - a);
}

void PlayerSystem::tick(float delta) {
	const Uint8* keysArray = SDL_GetKeyboardState(nullptr);

	//Process PlayerComponent
	world::getEntitiesWithComponents<PlayerComponent, TransformComponent, CameraComponent>(entities);
	for (int_openmp_t i = 0; i < (int_openmp_t)entities.size(); i++) {
		auto player = entities[i]->getComponent<PlayerComponent>();
		auto transform = entities[i]->getComponent<TransformComponent>();
		auto camera = entities[i]->getComponent<CameraComponent>();
		auto weapon = player->getWeapon()->getComponent<Hydra::Component::WeaponComponent>();
		auto weaponMesh = player->getWeapon()->getComponent<Hydra::Component::MeshComponent>();
		auto life = entities[i]->getComponent<Component::LifeComponent>();
		auto movement = entities[i]->getComponent<Component::MovementComponent>();
		auto soundFx = entities[i]->getComponent<SoundFxComponent>();
		auto perks = entities[i]->getComponent<PerkComponent>();
		auto rbc = static_cast<btRigidBody*>(entities[i]->getComponent<RigidBodyComponent>()->getRigidBody());

		glm::mat4 rotation = glm::mat4_cast(transform->rotation);
		movement->direction = -glm::vec3(glm::vec4{ 0, 0, 1, 0 } *rotation);

		{
			glm::vec3 forward = glm::normalize(glm::vec3(movement->direction.x, 0, movement->direction.z));

			glm::vec3 rightDir = glm::vec3(glm::vec4{ 1, 0, 0, 0 } *rotation);
			glm::vec3 right = glm::normalize(glm::vec3(rightDir.x, 0, rightDir.z));

			if (keysArray[SDL_SCANCODE_W])
				movement->velocity += movement->movementSpeed * forward * delta;

			if (keysArray[SDL_SCANCODE_R])
				weapon->_isReloading = true;

			if (keysArray[SDL_SCANCODE_S]) {
				movement->velocity -= movement->movementSpeed * forward * delta;
			}

			if (keysArray[SDL_SCANCODE_A])
				movement->velocity -= movement->movementSpeed * right * delta;

			if (keysArray[SDL_SCANCODE_D])
				movement->velocity += movement->movementSpeed * right * delta;

			if (keysArray[SDL_SCANCODE_SPACE] && player->onGround) {
				rbc->applyCentralForce(btVector3(0, 20000, 0));
				player->onGround = false;
			}
			if (movement->velocity.x != 0 || movement->velocity.y != 0 || movement->velocity.z != 0)
				weaponMesh->animationIndex = 1;
			else
				weaponMesh->animationIndex = 0;

			if (camera->mouseControl && SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)) {
				//TODO: Make pretty?
				glm::quat bulletOrientation = glm::angleAxis(-camera->cameraYaw, glm::vec3(0, 1, 0)) * (glm::angleAxis(-camera->cameraPitch, glm::vec3(1, 0, 0)));

				float bulletVelocity = 300;
				if(!weapon->_isReloading)
					if (weapon->shoot(transform->position, movement->direction, bulletOrientation, bulletVelocity, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_PLAYER_PROJECTILE)) {
						float rn = 500;//rand() % 1000;
						rn /= 10000;

						rn *= 0.8;
						weapon->_dpitch -= rn;
						rn = rand() % 900 + 100;
						rn /= 10000;
						rn *= 0.8;
						//if (rand() % 2 == 1)
						//	dyaw += rn/3;
						//else
						//	dyaw -= rn/3;
						weaponMesh->animationIndex = 2;
						if (weapon->currmagammo == 0)
							weapon->_isReloading = true;
					}
			}
		}
		if (!keysArray[SDL_SCANCODE_W]
			&& !keysArray[SDL_SCANCODE_S]
			&& !keysArray[SDL_SCANCODE_A]
			&& !keysArray[SDL_SCANCODE_D]) {
			movement->velocity *= delta;
		}

		float speed = glm::length(movement->velocity);
		if (speed > 10)
			movement->velocity *= 10 / speed;

		if (weapon->_isReloading)
			weapon->_isReloading = weapon->reload(delta);

		float& yaw = camera->cameraYaw;
		float& pitch = camera->cameraPitch;
		yaw = lerp(yaw, (yaw + weapon->_dyaw), 0.5);
		pitch = lerp(pitch, (pitch + weapon->_dpitch), 0.5);
		weapon->_dyaw /= 2;
		weapon->_dpitch /= 2;

		btVector3 vel = rbc->getLinearVelocity();
		rbc->setLinearVelocity(btVector3(movement->velocity.x,vel.y(),movement->velocity.z));

		transform->dirty = true;

		auto wt = player->getWeapon()->getComponent<TransformComponent>();
		wt->position = transform->position + glm::vec3(glm::vec4{player->weaponOffset, 0} * rotation);
		wt->rotation = glm::normalize(glm::conjugate(transform->rotation) * glm::quat(glm::vec3(glm::radians(180.0f), 0, glm::radians(180.0f))));
		wt->dirty = true;
	}

	entities.clear();
}

void PlayerSystem::registerUI() {}
<commit_msg>Auto stash before revert of "Still bullets so we can see the weird mesh"<commit_after>#include <hydra/system/playersystem.hpp>

#include <imgui/imgui.h>

#include <hydra/ext/openmp.hpp>

#include <hydra/component/playercomponent.hpp>
#include <hydra/component/transformcomponent.hpp>
#include <hydra/component/cameracomponent.hpp>
#include <hydra/component/weaponcomponent.hpp>
#include <hydra/component/lifecomponent.hpp>
#include <hydra/component/movementcomponent.hpp>
#include <hydra/component/soundfxcomponent.hpp>
#include <hydra/component/perkcomponent.hpp>
#include <hydra/component/rigidbodycomponent.hpp>

#include <btBulletDynamicsCommon.h>

#include <hydra/engine.hpp>

using namespace Hydra::System;
using namespace Hydra::Component;

using world = Hydra::World::World;

PlayerSystem::PlayerSystem() {}
PlayerSystem::~PlayerSystem() {}

float lerp(float a, float b, float f) {
	return a + f * (b - a);
}

void PlayerSystem::tick(float delta) {
	const Uint8* keysArray = SDL_GetKeyboardState(nullptr);

	//Process PlayerComponent
	world::getEntitiesWithComponents<PlayerComponent, TransformComponent, CameraComponent>(entities);
	for (int_openmp_t i = 0; i < (int_openmp_t)entities.size(); i++) {
		auto player = entities[i]->getComponent<PlayerComponent>();
		auto transform = entities[i]->getComponent<TransformComponent>();
		auto camera = entities[i]->getComponent<CameraComponent>();
		auto weapon = player->getWeapon()->getComponent<Hydra::Component::WeaponComponent>();
		auto weaponMesh = player->getWeapon()->getComponent<Hydra::Component::MeshComponent>();
		auto life = entities[i]->getComponent<Component::LifeComponent>();
		auto movement = entities[i]->getComponent<Component::MovementComponent>();
		auto soundFx = entities[i]->getComponent<SoundFxComponent>();
		auto perks = entities[i]->getComponent<PerkComponent>();
		auto rbc = static_cast<btRigidBody*>(entities[i]->getComponent<RigidBodyComponent>()->getRigidBody());

		glm::mat4 rotation = glm::mat4_cast(transform->rotation);
		movement->direction = -glm::vec3(glm::vec4{ 0, 0, 1, 0 } *rotation);

		{
			glm::vec3 forward = glm::normalize(glm::vec3(movement->direction.x, 0, movement->direction.z));

			glm::vec3 rightDir = glm::vec3(glm::vec4{ 1, 0, 0, 0 } *rotation);
			glm::vec3 right = glm::normalize(glm::vec3(rightDir.x, 0, rightDir.z));

			if (keysArray[SDL_SCANCODE_W])
				movement->velocity += movement->movementSpeed * forward * delta;

			if (keysArray[SDL_SCANCODE_R])
				weapon->_isReloading = true;

			if (keysArray[SDL_SCANCODE_S]) {
				movement->velocity -= movement->movementSpeed * forward * delta;
			}

			if (keysArray[SDL_SCANCODE_A])
				movement->velocity -= movement->movementSpeed * right * delta;

			if (keysArray[SDL_SCANCODE_D])
				movement->velocity += movement->movementSpeed * right * delta;

			if (keysArray[SDL_SCANCODE_SPACE] && player->onGround) {
				rbc->applyCentralForce(btVector3(0, 20000, 0));
				player->onGround = false;
			}
			if (movement->velocity.x != 0 || movement->velocity.y != 0 || movement->velocity.z != 0)
				weaponMesh->animationIndex = 1;
			else
				weaponMesh->animationIndex = 0;

			if (camera->mouseControl && SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)) {
				//TODO: Make pretty?
				glm::quat bulletOrientation = glm::angleAxis(-camera->cameraYaw, glm::vec3(0, 1, 0)) * (glm::angleAxis(-camera->cameraPitch, glm::vec3(1, 0, 0)));

				//Changed to see if modell is correct, original bulletVelocity was 300 (A little too fast imo, das me tho)
				float bulletVelocity = 3;
				if(!weapon->_isReloading)
					if (weapon->shoot(transform->position, movement->direction, bulletOrientation, bulletVelocity, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_PLAYER_PROJECTILE)) {
						float rn = 500;//rand() % 1000;
						rn /= 10000;

						rn *= 0.8;
						weapon->_dpitch -= rn;
						rn = rand() % 900 + 100;
						rn /= 10000;
						rn *= 0.8;
						//if (rand() % 2 == 1)
						//	dyaw += rn/3;
						//else
						//	dyaw -= rn/3;
						weaponMesh->animationIndex = 2;
						if (weapon->currmagammo == 0)
							weapon->_isReloading = true;
					}
			}
		}
		if (!keysArray[SDL_SCANCODE_W]
			&& !keysArray[SDL_SCANCODE_S]
			&& !keysArray[SDL_SCANCODE_A]
			&& !keysArray[SDL_SCANCODE_D]) {
			movement->velocity *= delta;
		}

		float speed = glm::length(movement->velocity);
		if (speed > 10)
			movement->velocity *= 10 / speed;

		if (weapon->_isReloading)
			weapon->_isReloading = weapon->reload(delta);

		float& yaw = camera->cameraYaw;
		float& pitch = camera->cameraPitch;
		yaw = lerp(yaw, (yaw + weapon->_dyaw), 0.5);
		pitch = lerp(pitch, (pitch + weapon->_dpitch), 0.5);
		weapon->_dyaw /= 2;
		weapon->_dpitch /= 2;

		btVector3 vel = rbc->getLinearVelocity();
		rbc->setLinearVelocity(btVector3(movement->velocity.x,vel.y(),movement->velocity.z));

		transform->dirty = true;

		auto wt = player->getWeapon()->getComponent<TransformComponent>();
		wt->position = transform->position + glm::vec3(glm::vec4{player->weaponOffset, 0} * rotation);
		wt->rotation = glm::normalize(glm::conjugate(transform->rotation) * glm::quat(glm::vec3(glm::radians(180.0f), 0, glm::radians(180.0f))));
		wt->dirty = true;
	}

	entities.clear();
}

void PlayerSystem::registerUI() {}
<|endoftext|>


<commit_before><commit_msg>Fixed another minor linux build problem<commit_after><|endoftext|>


<commit_before>// This program test the ports by setting up a simple pipeline.

#include "vtkImageReader.h"
#include "vtkSynchronizedTemplates3D.h"
#include "vtkAppendPolyData.h"
#include "vtkOutputPort.h"
#include "vtkInputPort.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkElevationFilter.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTimerLog.h"
#include "vtkMath.h"

#define ISO_START 3500.0
#define ISO_STEP  -500.0
#define ISO_NUM   6

// callback to test streaming / ports by seeing what extents are being read in.
void reader_start_callback(void *arg)
{
  vtkImageReader *reader = (vtkImageReader*)(arg);
  int *e;

  e = reader->GetOutput()->GetUpdateExtent();

  cerr << "Reading: " << e[0] << ", " << e[1] << ", " << e[2] << ", "
       << e[3] << ", " << e[4] << ", " << e[5] << endl;
}

// call back to set the iso surface value.
void set_iso_val_rmi(void *localArg, void *remoteArg,
		     int remoteArgLen, int id)
{
  float val;

  vtkSynchronizedTemplates3D *iso;
  iso = (vtkSynchronizedTemplates3D *)localArg;
  val = iso->GetValue(0);
  iso->SetValue(0, val + ISO_STEP);
}

void process( vtkMultiProcessController *controller,
	      void *vtkNotUsed(arg) )
{
  vtkImageReader *reader;
  vtkSynchronizedTemplates3D *iso;
  vtkElevationFilter *elev;
  int myid, numProcs;
  float val;
  int numTris;

  myid = controller->GetLocalProcessId();
  numProcs = controller->GetNumberOfProcesses();

  reader = vtkImageReader::New();
  reader->SetDataByteOrderToLittleEndian();
  reader->SetDataExtent(0, 127, 0, 127, 1, 93);
  reader->SetFilePrefix("../../../vtkdata/headsq/half");
  reader->SetDataSpacing(1.6, 1.6, 1.5);

  iso = vtkSynchronizedTemplates3D::New();
  iso->SetInput(reader->GetOutput());
  iso->SetValue(0, ISO_START);
  iso->ComputeScalarsOff();
  iso->ComputeGradientsOff();
  // This should be automatically determined by controller.
  iso->SetNumberOfThreads(1);

  // Compute a different color for each process.
  elev = vtkElevationFilter::New();
  elev->SetInput(iso->GetOutput());
  vtkMath::RandomSeed(myid * 100);
  val = vtkMath::Random();
  elev->SetScalarRange(val, val+0.001);

  if (myid != 0)
    {
    // Remote process! Send data throug port.
    vtkOutputPort *upPort = vtkOutputPort::New();

    // last, set up a RMI call back to change the iso surface value.
    controller->AddRMI(set_iso_val_rmi, (void *)iso, 300);

    upPort->SetInput(elev->GetPolyDataOutput());
    // the different process ids differentiate between sources.
    upPort->SetTag(999);
    // wait for the call back to execute.
    upPort->WaitForUpdate();

    // last call never returns, but ...
    upPort->Delete();
    }
  else
    {
    int i, j;
    vtkAppendPolyData *app = vtkAppendPolyData::New();
    vtkInputPort *downPort;
    vtkRenderer *ren = vtkRenderer::New();
    vtkRenderWindow *renWindow = vtkRenderWindow::New();
    vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
    vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
    vtkActor *actor = vtkActor::New();
    vtkTimerLog *timer = vtkTimerLog::New();
    vtkCamera *cam = vtkCamera::New();

    // This is the main thread: Collect the data and render it.
    app->AddInput(elev->GetPolyDataOutput());
    // ###################### important ####################
    // # this tells the append filter to request pieces from
    // # each of its inputs.
    app->ParallelStreamingOn();

    for (i = 1; i < numProcs; ++i)
      {
      downPort = vtkInputPort::New();
      downPort->SetRemoteProcessId(i);
      downPort->SetTag(999);
      app->AddInput(downPort->GetPolyDataOutput());
      // referenced by app ...
      downPort->Delete();
      downPort = NULL;
      }

    //putenv("DISPLAY=:0.0");

    renWindow->AddRenderer(ren);
    iren->SetRenderWindow(renWindow);
    ren->SetBackground(0.9, 0.9, 0.9);
    renWindow->SetSize( 400, 400);

    mapper->SetInput(app->GetOutput());
    actor->SetMapper(mapper);

    // assign our actor to the renderer
    ren->AddActor(actor);

    cam->SetFocalPoint(100, 100, 65);
    cam->SetPosition(100, 450, 65);
    cam->SetViewUp(0, 0, -1);
    cam->SetViewAngle(30);
    // this was causing an update.
    //ren->ResetCameraClippingRange();
    //{
    //double *range = ren->GetActiveCamera()->GetClippingRange();
    //cerr << range[0] << ", " << range[1] << endl;
    //}
    cam->SetClippingRange(177.0, 536.0);
    ren->SetActiveCamera(cam);

    // loop through some iso surface values.
    for (j = 0; j < ISO_NUM; ++j)
      {
      // set the local value
      set_iso_val_rmi((void*)iso, NULL, 0, 0);
      for (i = 1; i < numProcs; ++i)
	{
	// trigger the RMI to change the iso surface value.
	controller->TriggerRMI(i, 300);
	}

      timer->StartTimer();
      app->Update();
      timer->StopTimer();
      numTris = iso->GetOutput()->GetNumberOfCells();
      val = iso->GetValue(0);
      cerr << "Update " << val << " took " << timer->GetElapsedTime()
	   << " seconds to produce " << numTris << " triangles\n";

      // now render the results
      renWindow->Render();
      //sprintf(filename, "iso%d.ppm", (int)(val));
      //renWindow->SetFileName(filename);
      //renWindow->SaveImageAsPPM();
      }

    // just exit
    //for (i = 1; i < numProcs; ++i)
    //  {
    //  // trigger the RMI to exit
    //  controller->TriggerRMI(i, VTK_BREAK_RMI_TAG);
    //  }
    //exit(0);

    //  Begin mouse interaction
    iren->Start();

    // Clean up
    app->Delete();
    ren->Delete();
    renWindow->Delete();
    iren->Delete();
    mapper->Delete();
    actor->Delete();
    }

  // clean up objects in all processes.
  reader->Delete();
  iso->Delete();
  elev->Delete();
}

void main( int argc, char *argv[] )
{
  vtkMultiProcessController *controller;

  controller = vtkMultiProcessController::New();

  controller->Initialize(argc, argv);
  // Needed for threaded controller.
  // controller->SetNumberOfProcesses(2);
  controller->SetSingleMethod(process, NULL);
  controller->SingleMethodExecute();

  controller->Delete();
}

<commit_msg>Better comment<commit_after>// This program test the ports by setting up a simple pipeline.

#include "vtkImageReader.h"
#include "vtkSynchronizedTemplates3D.h"
#include "vtkAppendPolyData.h"
#include "vtkOutputPort.h"
#include "vtkInputPort.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkElevationFilter.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTimerLog.h"
#include "vtkMath.h"

#define ISO_START 3500.0
#define ISO_STEP  -500.0
#define ISO_NUM   6

// callback to test streaming / ports by seeing what extents are being read in.
void reader_start_callback(void *arg)
{
  vtkImageReader *reader = (vtkImageReader*)(arg);
  int *e;

  e = reader->GetOutput()->GetUpdateExtent();

  cerr << "Reading: " << e[0] << ", " << e[1] << ", " << e[2] << ", "
       << e[3] << ", " << e[4] << ", " << e[5] << endl;
}

// call back to set the iso surface value.
void set_iso_val_rmi(void *localArg, void *remoteArg,
		     int remoteArgLen, int id)
{
  float val;

  vtkSynchronizedTemplates3D *iso;
  iso = (vtkSynchronizedTemplates3D *)localArg;
  val = iso->GetValue(0);
  iso->SetValue(0, val + ISO_STEP);
}

void process( vtkMultiProcessController *controller,
	      void *vtkNotUsed(arg) )
{
  vtkImageReader *reader;
  vtkSynchronizedTemplates3D *iso;
  vtkElevationFilter *elev;
  int myid, numProcs;
  float val;
  int numTris;

  myid = controller->GetLocalProcessId();
  numProcs = controller->GetNumberOfProcesses();

  reader = vtkImageReader::New();
  reader->SetDataByteOrderToLittleEndian();
  reader->SetDataExtent(0, 127, 0, 127, 1, 93);
  reader->SetFilePrefix("../../../vtkdata/headsq/half");
  reader->SetDataSpacing(1.6, 1.6, 1.5);

  iso = vtkSynchronizedTemplates3D::New();
  iso->SetInput(reader->GetOutput());
  iso->SetValue(0, ISO_START);
  iso->ComputeScalarsOff();
  iso->ComputeGradientsOff();
  // This should be automatically determined by controller.
  iso->SetNumberOfThreads(1);

  // Compute a different color for each process.
  elev = vtkElevationFilter::New();
  elev->SetInput(iso->GetOutput());
  vtkMath::RandomSeed(myid * 100);
  val = vtkMath::Random();
  elev->SetScalarRange(val, val+0.001);

  if (myid != 0)
    {
    // Remote process! Send data throug port.
    vtkOutputPort *upPort = vtkOutputPort::New();

    // last, set up a RMI call back to change the iso surface value.
    controller->AddRMI(set_iso_val_rmi, (void *)iso, 300);

    upPort->SetInput(elev->GetPolyDataOutput());
    // the different process ids differentiate between sources.
    upPort->SetTag(999);
    // wait for the call back to execute.
    upPort->WaitForUpdate();

    // last call never returns, but ...
    upPort->Delete();
    }
  else
    {
    int i, j;
    vtkAppendPolyData *app = vtkAppendPolyData::New();
    vtkInputPort *downPort;
    vtkRenderer *ren = vtkRenderer::New();
    vtkRenderWindow *renWindow = vtkRenderWindow::New();
    vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
    vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
    vtkActor *actor = vtkActor::New();
    vtkTimerLog *timer = vtkTimerLog::New();
    vtkCamera *cam = vtkCamera::New();

    // This is the main thread: Collect the data and render it.
    app->AddInput(elev->GetPolyDataOutput());
    // ###################### important ####################
    // # This tells the append filter to request pieces from
    // # each of its inputs.  Singe each of its inputs comes from
    // # a different process,  each process generates a separate
    // # piece of the data (data parallelism).
    app->ParallelStreamingOn();

    for (i = 1; i < numProcs; ++i)
      {
      downPort = vtkInputPort::New();
      downPort->SetRemoteProcessId(i);
      downPort->SetTag(999);
      app->AddInput(downPort->GetPolyDataOutput());
      // referenced by app ...
      downPort->Delete();
      downPort = NULL;
      }

    //putenv("DISPLAY=:0.0");

    renWindow->AddRenderer(ren);
    iren->SetRenderWindow(renWindow);
    ren->SetBackground(0.9, 0.9, 0.9);
    renWindow->SetSize( 400, 400);

    mapper->SetInput(app->GetOutput());
    actor->SetMapper(mapper);

    // assign our actor to the renderer
    ren->AddActor(actor);

    cam->SetFocalPoint(100, 100, 65);
    cam->SetPosition(100, 450, 65);
    cam->SetViewUp(0, 0, -1);
    cam->SetViewAngle(30);
    // this was causing an update.
    //ren->ResetCameraClippingRange();
    //{
    //double *range = ren->GetActiveCamera()->GetClippingRange();
    //cerr << range[0] << ", " << range[1] << endl;
    //}
    cam->SetClippingRange(177.0, 536.0);
    ren->SetActiveCamera(cam);

    // loop through some iso surface values.
    for (j = 0; j < ISO_NUM; ++j)
      {
      // set the local value
      set_iso_val_rmi((void*)iso, NULL, 0, 0);
      for (i = 1; i < numProcs; ++i)
	{
	// trigger the RMI to change the iso surface value.
	controller->TriggerRMI(i, 300);
	}

      timer->StartTimer();
      app->Update();
      timer->StopTimer();
      numTris = iso->GetOutput()->GetNumberOfCells();
      val = iso->GetValue(0);
      cerr << "Update " << val << " took " << timer->GetElapsedTime()
	   << " seconds to produce " << numTris << " triangles\n";

      // now render the results
      renWindow->Render();
      //sprintf(filename, "iso%d.ppm", (int)(val));
      //renWindow->SetFileName(filename);
      //renWindow->SaveImageAsPPM();
      }

    // just exit
    //for (i = 1; i < numProcs; ++i)
    //  {
    //  // trigger the RMI to exit
    //  controller->TriggerRMI(i, VTK_BREAK_RMI_TAG);
    //  }
    //exit(0);

    //  Begin mouse interaction
    iren->Start();

    // Clean up
    app->Delete();
    ren->Delete();
    renWindow->Delete();
    iren->Delete();
    mapper->Delete();
    actor->Delete();
    }

  // clean up objects in all processes.
  reader->Delete();
  iso->Delete();
  elev->Delete();
}

void main( int argc, char *argv[] )
{
  vtkMultiProcessController *controller;

  controller = vtkMultiProcessController::New();

  controller->Initialize(argc, argv);
  // Needed for threaded controller.
  // controller->SetNumberOfProcesses(2);
  controller->SetSingleMethod(process, NULL);
  controller->SingleMethodExecute();

  controller->Delete();
}

<|endoftext|>