<commit_before>#include <algorithm>
#include <ostream>
#include <iostream>

#include "mjolnir/edgeinfobuilder.h"

namespace valhalla {
namespace mjolnir {

// Constructor
EdgeInfoBuilder::EdgeInfoBuilder() {
}

// Set the reference node (start) of the edge.
void EdgeInfoBuilder::set_nodea(const baldr::GraphId& nodea) {
  nodea_ = nodea;
}

// Set the end node of the edge.
void EdgeInfoBuilder::set_nodeb(const baldr::GraphId& nodeb) {
  nodeb_ = nodeb;
}

// Set the indexes to names used by this edge. TODO - move?
void EdgeInfoBuilder::set_street_name_offset_list(
    const std::vector<size_t>& street_name_offset_list) {
  // TODO - move
  street_name_offset_list_.clear();
  if (!street_name_offset_list.empty()) {
    street_name_offset_list_.insert(street_name_offset_list_.end(),
                                    street_name_offset_list.begin(),
                                    street_name_offset_list.end());
  }

  // Set the street name offset list offset
  item_.fields.street_name_offset_list_offset = sizeof(GraphId)
      + sizeof(GraphId) + sizeof(PackedItem);

  // Set the name count
  item_.fields.name_count = street_name_offset_list_.size();
}

// Set the shape of the edge. TODO - move?
void EdgeInfoBuilder::set_shape(const std::vector<PointLL>& shape) {
  // Set the shape
  shape_.assign(shape.begin(), shape.end());
  // Set the shape count
  item_.fields.shape_count = shape_.size();
}

std::size_t EdgeInfoBuilder::SizeOf() const {
  std::size_t size = 0;
  size += sizeof(GraphId);                                     // nodea_
  size += sizeof(GraphId);                                     // nodeb_
  size += sizeof(PackedItem);                                  // item_
  size += (street_name_offset_list_.size() * sizeof(size_t));  // street_name_offset_list_
  size += (shape_.size() * sizeof(PointLL));                   // shape_
  size += (exit_signs_.size() * sizeof(ExitSign));             // exit_signs_

  return size;
}

void EdgeInfoBuilder::SerializeToOstream(std::ostream& out) const {
  // TODO - rm later
  /*std::cout << "------------------------------------------------------"
            << std::endl;
  std::cout << __FILE__ << ":" << __LINE__ << std::endl;
  std::cout << "nodea=" << nodea_.value() << "  nodea_.tileid="
            << nodea_.tileid() << "  nodea_.level=" << nodea_.level()
            << "  nodea_.id=" << nodea_.id() << std::endl;
  std::cout << "nodeb=" << nodeb_.value() << "  nodeb_.tileid=" << nodeb_.tileid() << "  nodeb_.level="
            << nodeb_.level() << "  nodeb_.id=" << nodeb_.id() << std::endl;
  std::cout << "item_=" << item_.value << std::endl;
  std::cout << "street_name_offset_list_offset="
            << street_name_offset_list_offset() << "  name_count="
            << street_name_offset_list_.size() << std::endl;
  for (auto name_offset : street_name_offset_list_) {
    std::cout << "   name_offset=" << name_offset << std::endl;
  }
  std::cout << "shape_count=" << shape_.size() << std::endl;
  for (const auto& ll : shape_) {
    std::cout << "   ll=" << ll.lat() << "," << ll.lng() << std::endl;
  }
  std::cout << "exit_sign_count=" << exit_signs_.size() << std::endl;
  std::cout << "======================================================="
            << std::endl;*/

  out.write(reinterpret_cast<const char*>(&nodea_), sizeof(GraphId));
  out.write(reinterpret_cast<const char*>(&nodeb_), sizeof(GraphId));
  out.write(reinterpret_cast<const char*>(&item_), sizeof(PackedItem));
  out.write(reinterpret_cast<const char*>(&street_name_offset_list_[0]),
            (street_name_offset_list_.size() * sizeof(size_t)));
  out.write(reinterpret_cast<const char*>(&shape_[0]),
            (shape_.size() * sizeof(PointLL)));
  out.write(reinterpret_cast<const char*>(&exit_signs_[0]),
            (exit_signs_.size() * sizeof(ExitSign)));
}

}
}
<commit_msg>Debug updates<commit_after>#include <algorithm>
#include <ostream>
#include <iostream>

#include "mjolnir/edgeinfobuilder.h"

namespace valhalla {
namespace mjolnir {

// Constructor
EdgeInfoBuilder::EdgeInfoBuilder() {
}

// Set the reference node (start) of the edge.
void EdgeInfoBuilder::set_nodea(const baldr::GraphId& nodea) {
  nodea_ = nodea;
}

// Set the end node of the edge.
void EdgeInfoBuilder::set_nodeb(const baldr::GraphId& nodeb) {
  nodeb_ = nodeb;
}

// Set the indexes to names used by this edge. TODO - move?
void EdgeInfoBuilder::set_street_name_offset_list(
    const std::vector<size_t>& street_name_offset_list) {
  // TODO - move
  street_name_offset_list_.clear();
  if (!street_name_offset_list.empty()) {
    street_name_offset_list_.insert(street_name_offset_list_.end(),
                                    street_name_offset_list.begin(),
                                    street_name_offset_list.end());
  }

  // Set the street name offset list offset
  item_.fields.street_name_offset_list_offset = sizeof(GraphId)
      + sizeof(GraphId) + sizeof(PackedItem);

  // Set the name count
  item_.fields.name_count = street_name_offset_list_.size();
}

// Set the shape of the edge. TODO - move?
void EdgeInfoBuilder::set_shape(const std::vector<PointLL>& shape) {
  // Set the shape
  shape_.assign(shape.begin(), shape.end());
  // Set the shape count
  item_.fields.shape_count = shape_.size();
}

std::size_t EdgeInfoBuilder::SizeOf() const {
  std::size_t size = 0;
  size += sizeof(GraphId);                                     // nodea_
  size += sizeof(GraphId);                                     // nodeb_
  size += sizeof(PackedItem);                                  // item_
  size += (street_name_offset_list_.size() * sizeof(size_t));  // street_name_offset_list_
  size += (shape_.size() * sizeof(PointLL));                   // shape_
  size += (exit_signs_.size() * sizeof(ExitSign));             // exit_signs_

  return size;
}

void EdgeInfoBuilder::SerializeToOstream(std::ostream& out) const {
  // TODO - rm later
  std::cout << "------------------------------------------------------"
            << std::endl;
  std::cout << __FILE__ << ":" << __LINE__ << std::endl;
  std::cout << "EdgeInfoBuilder::SizeOf=" << SizeOf() << std::endl;
  std::cout << "nodea=" << nodea_.value() << "  nodea_.tileid="
            << nodea_.tileid() << "  nodea_.level=" << nodea_.level()
            << "  nodea_.id=" << nodea_.id() << std::endl;
  std::cout << "nodeb=" << nodeb_.value() << "  nodeb_.tileid="
            << nodeb_.tileid() << "  nodeb_.level=" << nodeb_.level()
            << "  nodeb_.id=" << nodeb_.id() << std::endl;
  std::cout << "item_=" << item_.value << std::endl;
  std::cout << "street_name_offset_list_offset="
            << street_name_offset_list_offset() << "  name_count="
            << street_name_offset_list_.size() << std::endl;
  for (auto name_offset : street_name_offset_list_) {
    std::cout << "   name_offset=" << name_offset << std::endl;
  }
  std::cout << "shape_count=" << shape_.size() << std::endl;
  for (const auto& ll : shape_) {
    std::cout << "   ll=" << ll.lat() << "," << ll.lng() << std::endl;
  }
  std::cout << "exit_sign_count=" << exit_signs_.size() << std::endl;
  std::cout << "======================================================="
            << std::endl;

  out.write(reinterpret_cast<const char*>(&nodea_), sizeof(GraphId));
  out.write(reinterpret_cast<const char*>(&nodeb_), sizeof(GraphId));
  out.write(reinterpret_cast<const char*>(&item_), sizeof(PackedItem));
  out.write(reinterpret_cast<const char*>(&street_name_offset_list_[0]),
            (street_name_offset_list_.size() * sizeof(size_t)));
  out.write(reinterpret_cast<const char*>(&shape_[0]),
            (shape_.size() * sizeof(PointLL)));
  out.write(reinterpret_cast<const char*>(&exit_signs_[0]),
            (exit_signs_.size() * sizeof(ExitSign)));
}

}
}
<|endoftext|>


<commit_before>#ifndef VXL_ROTATION_HPP
# define VXL_ROTATION_HPP
# pragma once

#include "cross.hpp"

#include "quat.hpp"

#include "sinf.hpp"

namespace vxl
{

enum struct ea
{
  XYZ,
  XZY,
  YXZ,
  YZX,
  ZXY,
  ZYX
};

namespace detail
{

template <typename T>
constexpr inline auto rot_x(std::pair<vxl::vector<T, 3>,
  vxl::vector<T, 3>> const& sc) noexcept
{
  return vxl::matrix<T, 4, 4>{
    T(1), T(0), T(0), T(0),
    T(0), sc.second(0), -sc.first(0), T(0),
    T(0), sc.first(0), sc.second(0), T(0),
    T(0), T(0), T(0), T(1)
  };
}

template <typename T>
constexpr inline auto rot_y(std::pair<vxl::vector<T, 3>,
  vxl::vector<T, 3>> const& sc) noexcept
{
  return vxl::matrix<T, 4, 4>{
    sc.second(1), T(0), sc.first(1), T(0),
    T(0), T(1), T(0), T(0),
    -sc.first(1), T(0), sc.second(1), T(0),
    T(0), T(0), T(0), T(1)
  };
}

template <typename T>
constexpr inline auto rot_z(std::pair<vxl::vector<T, 3>,
  vxl::vector<T, 3>> const& sc) noexcept
{
  return vxl::matrix<T, 4, 4>{
    sc.second(2), -sc.first(2), T(0), T(0),
    sc.first(2), sc.second(2), T(0), T(0),
    T(0), T(0), T(1), T(0),
    T(0), T(0), T(0), T(1)
  };
}

}

// Euler angle to rotation matrix conversions. WARNING: Blender XYZ is ZYX
// with angles negated, this is because Blender caters to artists.
//////////////////////////////////////////////////////////////////////////////
template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::XYZ, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_x(sc) * detail::rot_y(sc) * detail::rot_z(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::XZY, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_x(sc) * detail::rot_z(sc) * detail::rot_y(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::YXZ, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_y(sc) * detail::rot_x(sc) * detail::rot_z(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::YZX, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_y(sc) * detail::rot_z(sc) * detail::rot_x(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::ZXY, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_z(sc) * detail::rot_x(sc) * detail::rot_y(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::ZYX, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_z(sc) * detail::rot_y(sc) * detail::rot_x(sc);
}

// convert axis angle to quaternion
//////////////////////////////////////////////////////////////////////////////
template <typename T>
//__attribute__ ((noinline))
inline quat<T> to_quat(vector<T, 3> const a, T const angle) noexcept
{
  using vector_type = typename vector_traits<T, 4>::vector_type;

  auto const p(csincos(vector<T, 1>{T(.5) * angle}));

  return {
    vector_type{p.first.data_, p.first.data_, p.first.data_, p.second.data_} *
    vector_type{a.data_[0], a.data_[1], a.data_[2], T(1)}
  };
}

//////////////////////////////////////////////////////////////////////////////
template <typename T>
//__attribute__ ((noinline))
inline vector<T, 3> rotated(quat<T> const& q, vector<T, 3> const& v) noexcept
{
  auto const vq(vec(q));

  auto const t(ccross(vq, v));

  auto const u(scalar_vector<T, 3>(q) * t.data_ + ccross(vq, t).data_);

  return {v.data_ + u + u};
}

//////////////////////////////////////////////////////////////////////////////
template <typename T>
//__attribute__ ((noinline))
inline vector<T, 3>& rotate(quat<T> const& q, vector<T, 3>& v) noexcept
{
  auto const vq(vec(q));

  auto const t(ccross(vq, v));

  auto const u(scalar_vector<T, 3>(q) * t.data_ + ccross(vq, t).data_);

  v.data_ += u + u;

  return v;
}

}

#endif // VXL_ROTATION_HPP
<commit_msg>some fixes<commit_after>#ifndef VXL_ROTATION_HPP
# define VXL_ROTATION_HPP
# pragma once

#include "cross.hpp"

#include "quat.hpp"

#include "sinf.hpp"

namespace vxl
{

enum struct ea
{
  XYZ,
  XZY,
  YXZ,
  YZX,
  ZXY,
  ZYX
};

struct scale;

namespace detail
{

template <typename T>
constexpr inline auto rot_x(std::pair<vxl::vector<T, 3>,
  vxl::vector<T, 3>> const& sc) noexcept
{
  return vxl::matrix<T, 4, 4>{
    T(1), T(0), T(0), T(0),
    T(0), sc.second(0), -sc.first(0), T(0),
    T(0), sc.first(0), sc.second(0), T(0),
    T(0), T(0), T(0), T(1)
  };
}

template <typename T>
constexpr inline auto rot_y(std::pair<vxl::vector<T, 3>,
  vxl::vector<T, 3>> const& sc) noexcept
{
  return vxl::matrix<T, 4, 4>{
    sc.second(1), T(0), sc.first(1), T(0),
    T(0), T(1), T(0), T(0),
    -sc.first(1), T(0), sc.second(1), T(0),
    T(0), T(0), T(0), T(1)
  };
}

template <typename T>
constexpr inline auto rot_z(std::pair<vxl::vector<T, 3>,
  vxl::vector<T, 3>> const& sc) noexcept
{
  return vxl::matrix<T, 4, 4>{
    sc.second(2), -sc.first(2), T(0), T(0),
    sc.first(2), sc.second(2), T(0), T(0),
    T(0), T(0), T(1), T(0),
    T(0), T(0), T(0), T(1)
  };
}

}

// Euler angle to rotation matrix conversions. WARNING: Blender XYZ is ZYX
// with angles negated, this is because Blender caters to artists.
//////////////////////////////////////////////////////////////////////////////
template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::XYZ, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_x(sc) * detail::rot_y(sc) * detail::rot_z(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::XZY, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_x(sc) * detail::rot_z(sc) * detail::rot_y(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::YXZ, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_y(sc) * detail::rot_x(sc) * detail::rot_z(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::YZX, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_y(sc) * detail::rot_z(sc) * detail::rot_x(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::ZXY, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_z(sc) * detail::rot_x(sc) * detail::rot_y(sc);
}

template <enum ea E, typename T>
constexpr inline std::enable_if_t<E == ea::ZYX, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& a) noexcept
{
  auto const sc(csincos(a));

  return detail::rot_z(sc) * detail::rot_y(sc) * detail::rot_x(sc);
}

template <typename E, typename T>
constexpr inline std::enable_if_t<std::is_same<E, scale>{}, matrix<T, 4, 4>>
to_matrix(vxl::vector<T, 3> const& s) noexcept
{
  matrix<T, 4, 4> r{{}};

  r.set_element(0, 0, s(0));
  r.set_element(1, 1, s(1));
  r.set_element(2, 2, s(2));
  r.set_element(3, 3, T(1));

  return r;
}

// convert axis angle to quaternion
//////////////////////////////////////////////////////////////////////////////
template <typename T>
//__attribute__ ((noinline))
inline quat<T> to_quat(vector<T, 3> const a, T const angle) noexcept
{
  using vector_type = typename vector_traits<T, 4>::vector_type;

  auto const p(csincos(vector<T, 1>{T(.5) * angle}));

  return {
    vector_type{p.first.data_, p.first.data_, p.first.data_, p.second.data_} *
    vector_type{a.data_[0], a.data_[1], a.data_[2], T(1)}
  };
}

//////////////////////////////////////////////////////////////////////////////
template <typename T>
//__attribute__ ((noinline))
inline vector<T, 3> rotated(quat<T> const& q, vector<T, 3> const& v) noexcept
{
  auto const vq(vec(q));

  auto const t(ccross(vq, v));

  auto const u(scalar_vector<T, 3>(q) * t.data_ + ccross(vq, t).data_);

  return {v.data_ + u + u};
}

//////////////////////////////////////////////////////////////////////////////
template <typename T>
//__attribute__ ((noinline))
inline vector<T, 3>& rotate(quat<T> const& q, vector<T, 3>& v) noexcept
{
  auto const vq(vec(q));

  auto const t(ccross(vq, v));

  auto const u(scalar_vector<T, 3>(q) * t.data_ + ccross(vq, t).data_);

  v.data_ += u + u;

  return v;
}

}

#endif // VXL_ROTATION_HPP
<|endoftext|>


<commit_before><commit_msg>bfd_section_vma is not macro<commit_after><|endoftext|>


<commit_before><commit_msg>Work in progress<commit_after><|endoftext|>


<commit_before><commit_msg>Refactorings<commit_after><|endoftext|>


<commit_before><commit_msg>java: constant pool tags<commit_after><|endoftext|>


<commit_before><commit_msg>update r697<commit_after><|endoftext|>


<commit_before>//---------------------------------------------------------------------------//
/*!
 * \file tstMeshContainer.cpp
 * \author Stuart R. Slattery
 * \brief MeshContainer unit tests.
 */
//---------------------------------------------------------------------------//

#include <iostream>
#include <vector>
#include <set>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <cassert>

#include <DTK_MeshContainer.hpp>
#include <DTK_RendezvousMesh.hpp>
#include <DTK_MeshTypes.hpp>
#include <DTK_MeshTraits.hpp>

#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_DefaultMpiComm.hpp>
#include <Teuchos_RCP.hpp>
#include <Teuchos_ArrayRCP.hpp>
#include <Teuchos_TypeTraits.hpp>

#include <MBRange.hpp>

//---------------------------------------------------------------------------//
// MPI Setup
//---------------------------------------------------------------------------//

template<class Ordinal>
Teuchos::RCP<const Teuchos::Comm<Ordinal> > getDefaultComm()
{
#ifdef HAVE_MPI
    return Teuchos::DefaultComm<Ordinal>::getComm();
#else
    return Teuchos::rcp(new Teuchos::SerialComm<Ordinal>() );
#endif
}

//---------------------------------------------------------------------------//
// Mesh contianer creation funciton.
//---------------------------------------------------------------------------//
DataTransferKit::MeshContainer<int> buildMeshContainer()
{
    using namespace DataTransferKit;

    // Make some nodes.
    Teuchos::Array<int> node_handles;
    std::vector<double> coords;

    node_handles.push_back( 0 );
    coords.push_back( 0.0 ); coords.push_back( 0.0 ); coords.push_back( 0.0 );

    node_handles.push_back( 1 );
    coords.push_back( 1.0 ); coords.push_back( 0.0 ); coords.push_back( 0.0 );

    node_handles.push_back( 2 );
    coords.push_back( 1.0 ); coords.push_back( 1.0 ); coords.push_back( 0.0 );

    node_handles.push_back( 3 );
    coords.push_back( 0.0 ); coords.push_back( 1.0 ); coords.push_back( 0.0 );

    node_handles.push_back( 4 );
    coords.push_back( 0.0 ); coords.push_back( 0.0 ); coords.push_back( 1.0 );

    node_handles.push_back( 5 );
    coords.push_back( 1.0 ); coords.push_back( 0.0 ); coords.push_back( 1.0 );

    node_handles.push_back( 6 );
    coords.push_back( 1.0 ); coords.push_back( 1.0 ); coords.push_back( 1.0 );

    node_handles.push_back( 7 );
    coords.push_back( 0.0 ); coords.push_back( 1.0 ); coords.push_back( 1.0 );

    node_handles.push_back( 8 );
    coords.push_back( 0.0 ); coords.push_back( 0.0 ); coords.push_back( 2.0 );

    node_handles.push_back( 9 );
    coords.push_back( 1.0 ); coords.push_back( 0.0 ); coords.push_back( 2.0 );

    node_handles.push_back( 10 );
    coords.push_back( 1.0 ); coords.push_back( 1.0 ); coords.push_back( 2.0 );

    node_handles.push_back( 11 );
    coords.push_back( 0.0 ); coords.push_back( 1.0 ); coords.push_back( 2.0 );

    // Make 2 hexahedrons.
    Teuchos::Array<int> hex_handles;
    std::vector<int> hex_connectivity;

    hex_handles.push_back( 0 );
    hex_connectivity.push_back( 0 ); hex_connectivity.push_back( 1 );
    hex_connectivity.push_back( 2 ); hex_connectivity.push_back( 3 );
    hex_connectivity.push_back( 4 ); hex_connectivity.push_back( 5 );
    hex_connectivity.push_back( 6 ); hex_connectivity.push_back( 7 );

    hex_handles.push_back( 1 );
    hex_connectivity.push_back( 4 ); hex_connectivity.push_back( 5 );
    hex_connectivity.push_back( 6 ); hex_connectivity.push_back( 7 );
    hex_connectivity.push_back( 8 ); hex_connectivity.push_back( 9 );
    hex_connectivity.push_back( 10 ); hex_connectivity.push_back( 11 );

    Teuchos::ArrayRCP<int> node_handle_array( node_handles.size() );
    std::copy( node_handles.begin(), node_handles.end(),
	       node_handle_array.begin() );
    Teuchos::ArrayRCP<double> coords_array( coords.size() );
    std::copy( coords.begin(), coords.end(), coords_array.begin() );
    Teuchos::ArrayRCP<int> hex_handle_array( hex_handles.size() );
    std::copy( hex_handles.begin(), hex_handles.end(),
	       hex_handle_array.begin() );
    Teuchos::ArrayRCP<int> connectivity_array( hex_connectivity.size() );
    std::copy( hex_connectivity.begin(), hex_connectivity.end(),
	       connectivity_array.begin() );

    return MeshContainer<int>( node_handle_array, coords_array,
			       DTK_REGION, DTK_HEXAHEDRON, 8,
			       hex_handle_array, connectivity_array );
}

//---------------------------------------------------------------------------//
// Tests
//---------------------------------------------------------------------------//

TEUCHOS_UNIT_TEST( MeshContainer, mesh_container_test )
{
    using namespace DataTransferKit;

    // Create a mesh container.
    typedef MeshTraits< MeshContainer<int> > MT;
    MeshContainer<int> mesh_container = buildMeshContainer();
    Teuchos::RCP< RendezvousMesh<MT::handle_type> > mesh =
	createRendezvousMesh( mesh_container );

    // Get the moab interface.
    moab::ErrorCode error;
    RendezvousMesh<MT::handle_type>::RCP_Moab moab = mesh->getMoab();

    // Grab the elements.
    moab::Range mesh_elements = mesh->getElements();

    // Check the moab mesh element data.
    moab::Range::const_iterator element_iterator;
    MT::handle_type native_handle = 0;
    for ( element_iterator = mesh_elements.begin();
	  element_iterator != mesh_elements.end();
	  ++element_iterator, ++native_handle )
    {
	TEST_ASSERT( mesh->getNativeHandle( *element_iterator ) ==
		     native_handle );

	TEST_ASSERT( moab->type_from_handle( *element_iterator ) ==
		     moab::MBHEX );
    }

    // Check the moab mesh vertex data.
    moab::Range connectivity;
    error = moab->get_connectivity( mesh_elements, connectivity );
    TEST_ASSERT( moab::MB_SUCCESS == error );

    std::vector<double> vertex_coords( 3 * connectivity.size() );
    error = moab->get_coords( connectivity, &vertex_coords[0] );
    TEST_ASSERT( moab::MB_SUCCESS == error );

    std::vector<double>::const_iterator moab_coord_iterator =
	vertex_coords.begin();
    typename MT::const_coordinate_iterator coord_iterator;

    for ( coord_iterator = MT::coordsBegin( mesh_container );
	  coord_iterator != MT::coordsEnd( mesh_container );
	  ++coord_iterator, ++moab_coord_iterator )
    {
	TEST_ASSERT( *coord_iterator == *moab_coord_iterator );
    }
}

//---------------------------------------------------------------------------//
// end tstMeshContainer.cpp
//---------------------------------------------------------------------------//
<commit_msg>Updated RendezvousMesh test for blocked data interface<commit_after>//---------------------------------------------------------------------------//
/*!
 * \file tstMeshContainer.cpp
 * \author Stuart R. Slattery
 * \brief MeshContainer unit tests.
 */
//---------------------------------------------------------------------------//

#include <iostream>
#include <vector>
#include <set>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <cassert>

#include <DTK_MeshContainer.hpp>
#include <DTK_RendezvousMesh.hpp>
#include <DTK_MeshTypes.hpp>
#include <DTK_MeshTraits.hpp>

#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_DefaultMpiComm.hpp>
#include <Teuchos_RCP.hpp>
#include <Teuchos_ArrayRCP.hpp>
#include <Teuchos_TypeTraits.hpp>

#include <MBRange.hpp>

//---------------------------------------------------------------------------//
// MPI Setup
//---------------------------------------------------------------------------//

template<class Ordinal>
Teuchos::RCP<const Teuchos::Comm<Ordinal> > getDefaultComm()
{
#ifdef HAVE_MPI
    return Teuchos::DefaultComm<Ordinal>::getComm();
#else
    return Teuchos::rcp(new Teuchos::SerialComm<Ordinal>() );
#endif
}

//---------------------------------------------------------------------------//
// Mesh contianer creation funciton.
//---------------------------------------------------------------------------//
DataTransferKit::MeshContainer<int> buildMeshContainer()
{
    using namespace DataTransferKit;

    // Make some nodes.
    Teuchos::Array<int> node_handles;
    Teuchos::Array<double> coords;

    // handles
    for ( int i = 0; i < 12; ++i )
    {
	node_handles.push_back( i );
    }

    // x
    coords.push_back( 0.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 0.0 );

    // y
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );

    // z
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 0.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 1.0 );
    coords.push_back( 2.0 );
    coords.push_back( 2.0 );
    coords.push_back( 2.0 );
    coords.push_back( 2.0 );

    // Make 2 hexahedrons.
    Teuchos::Array<int> hex_handles;
    Teuchos::Array<int> hex_connectivity;

    // handles
    hex_handles.push_back( 0 );
    hex_handles.push_back( 1 );

    // 0
    hex_connectivity.push_back( 0 );
    hex_connectivity.push_back( 4 );

    // 1
    hex_connectivity.push_back( 1 );
    hex_connectivity.push_back( 5 );

    // 2
    hex_connectivity.push_back( 2 );
    hex_connectivity.push_back( 6 );

    // 3
    hex_connectivity.push_back( 3 );
    hex_connectivity.push_back( 7 );

    // 4
    hex_connectivity.push_back( 4 );
    hex_connectivity.push_back( 8 );

    // 5
    hex_connectivity.push_back( 5 );
    hex_connectivity.push_back( 9 );

    // 6
    hex_connectivity.push_back( 6 );
    hex_connectivity.push_back( 10 );

    // 7
    hex_connectivity.push_back( 7 );
    hex_connectivity.push_back( 11 );

    Teuchos::ArrayRCP<int> node_handle_array( node_handles.size() );
    std::copy( node_handles.begin(), node_handles.end(),
	       node_handle_array.begin() );
    Teuchos::ArrayRCP<double> coords_array( coords.size() );
    std::copy( coords.begin(), coords.end(), coords_array.begin() );
    Teuchos::ArrayRCP<int> hex_handle_array( hex_handles.size() );
    std::copy( hex_handles.begin(), hex_handles.end(),
	       hex_handle_array.begin() );
    Teuchos::ArrayRCP<int> connectivity_array( hex_connectivity.size() );
    std::copy( hex_connectivity.begin(), hex_connectivity.end(),
	       connectivity_array.begin() );

    return MeshContainer<int>( node_handle_array, coords_array,
			       DTK_REGION, DTK_HEXAHEDRON, 8,
			       hex_handle_array, connectivity_array );
}

//---------------------------------------------------------------------------//
// Tests
//---------------------------------------------------------------------------//

TEUCHOS_UNIT_TEST( MeshContainer, mesh_container_test )
{
    using namespace DataTransferKit;

    // Create a mesh container.
    typedef MeshTraits< MeshContainer<int> > MT;
    MeshContainer<int> mesh_container = buildMeshContainer();
    Teuchos::RCP< RendezvousMesh<MT::handle_type> > mesh =
	createRendezvousMesh( mesh_container );

    // Get the moab interface.
    moab::ErrorCode error;
    RendezvousMesh<MT::handle_type>::RCP_Moab moab = mesh->getMoab();

    // Grab the elements.
    moab::Range mesh_elements = mesh->getElements();

    // Check the moab mesh element data.
    moab::Range::const_iterator element_iterator;
    MT::handle_type native_handle = 0;
    for ( element_iterator = mesh_elements.begin();
	  element_iterator != mesh_elements.end();
	  ++element_iterator, ++native_handle )
    {
	TEST_ASSERT( mesh->getNativeHandle( *element_iterator ) ==
		     native_handle );

	TEST_ASSERT( moab->type_from_handle( *element_iterator ) ==
		     moab::MBHEX );
    }

    // Check the moab mesh vertex data.
    moab::Range connectivity;
    error = moab->get_connectivity( mesh_elements, connectivity );
    TEST_ASSERT( moab::MB_SUCCESS == error );

    std::vector<double> vertex_coords( 3 * connectivity.size() );
    error = moab->get_coords( connectivity, &vertex_coords[0] );
    TEST_ASSERT( moab::MB_SUCCESS == error );

    int num_nodes = connectivity.size();
    std::vector<double>::const_iterator moab_coord_iterator;
    typename MT::const_coordinate_iterator coord_iterator =
	MT::coordsBegin( mesh_container );
    int i = 0;
    for ( moab_coord_iterator = vertex_coords.begin();
	  moab_coord_iterator != vertex_coords.end(); ++i )
    {
	for ( int d = 0; d < 3; ++d, ++moab_coord_iterator )
	{
	    TEST_ASSERT( coord_iterator[d*num_nodes + i] ==
			 *moab_coord_iterator );
	}
    }
}

//---------------------------------------------------------------------------//
// end tstMeshContainer.cpp
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>//
//  GameplayScene.cpp
//  MasmorraDados
//
//  Created by Marlon Andrade on 16/02/2015.
//
//

#include "GameplayScene.h"

#include "BackgroundLayer.h"
#include "CharacterDiceSprite.h"
#include "RoomPlacement.h"

USING_NS_CC;

#pragma mark - Public Interface

bool GameplayScene::init() {
  if (!Scene::init()) {
    return false;
  }

  this->_enableInteractions();

  auto game = Game::createWithRoomPlacedDelegate([&](Vector<RoomPlacement*> placements) {
    this->_disableInteractions();

    float delayTime = 0;
    int zOrder = placements.size();

    for (auto placement : placements) {
      auto room = placement->getRoom();
      auto position = placement->getPosition();

      auto roomSprite = Sprite::create(room->getImagePath());
      auto name = this->getGame()->getDungeon()->nameForPosition(position);
      roomSprite->setName(name);

      auto size = Director::getInstance()->getVisibleSize();
      auto origin = Director::getInstance()->getVisibleOrigin();

      auto deckPosition = Vec2(origin.x + size.width - TILE_DIMENSION / 2 - 20,
                               origin.y + size.height - TILE_DIMENSION / 2 - 20);
      roomSprite->setPosition(deckPosition);

      this->_getObjectsLayer()->addChild(roomSprite, zOrder);

      auto spritePosition = this->_positionInScene(position);

      auto delay = DelayTime::create(delayTime);
      auto animationStarted = CallFunc::create([=]() {
        this->_disableInteractions();
        roomSprite->setLocalZOrder(DUNGEON_ROOM_Z_ORDER + 10);
      });
      auto easeMove = EaseBackIn::create(MoveTo::create(PLACE_ROOM_DURATION, spritePosition));
      auto animationEnded = CallFunc::create([=]() {
        this->_enableInteractions();
        roomSprite->setLocalZOrder(DUNGEON_ROOM_Z_ORDER);
      });

      roomSprite->runAction(Sequence::create(delay, animationStarted, easeMove,
                                             animationEnded, NULL));

      delayTime += PLACE_ROOM_DURATION;
      zOrder--;
    }
  });

  this->setGame(game);
  this->adjustInitialLayers();

  return true;
}

#pragma mark - Private Interface

void GameplayScene::adjustInitialLayers() {
  auto center = this->_centerOfScene();

  auto backgroundLayer = BackgroundLayer::create();
  this->addChild(backgroundLayer, -2);

  auto objectsLayer = this->_createObjectsLayer();
  this->addChild(objectsLayer, -1);

  auto controlsLayer = this->_createControlsLayer();
  this->addChild(controlsLayer, 1);

  this->getGame()->setCharacterPosition(INITIAL_POSITION);
  this->_adjustCharacterDiceSpritePosition();
}

Layer* GameplayScene::_createObjectsLayer() {
  auto objectsLayer = Layer::create();
  objectsLayer->setTag(OBJECTS_LAYER_TAG);

  auto initialRoom = this->getGame()->getDungeon()->getInitialRoom();
  auto initialPosition = INITIAL_POSITION;

  auto initialSprite = Sprite::create(initialRoom->getImagePath());
  auto name = this->getGame()->getDungeon()->nameForPosition(initialPosition);
  initialSprite->setName(name);
  initialSprite->setPosition(this->_positionInScene(INITIAL_POSITION));
  objectsLayer->addChild(initialSprite, DUNGEON_ROOM_Z_ORDER);

  objectsLayer->addChild(this->_createCharacterDiceSprite(), GAME_OBJECTS_Z_ORDER);

  return objectsLayer;
}

Layer* GameplayScene::_createControlsLayer() {
  auto controlsLayer = Layer::create();
  controlsLayer->setTag(CONTROLS_LAYER_TAG);

  return controlsLayer;
}

Node* GameplayScene::_createCharacterDiceSprite() {
  auto sprite = CharacterDiceSprite::create();
  sprite->setTag(CHARACTER_DICE_SPRITE_TAG);

  auto touchListener = EventListenerTouchOneByOne::create();
  touchListener->onTouchBegan = [&](Touch* touch, Event* event) {
    auto bounds = event->getCurrentTarget()->getBoundingBox();
    auto touchInSprite = bounds.containsPoint(touch->getLocation());
    bool containsBoot = true;
    auto canMove = this->_isInteractionEnabled() && touchInSprite && containsBoot;

    if (canMove) {
      Vector<Node*> visibleNodes;
      visibleNodes.pushBack(this->_getObjectsLayer()->getChildByTag(CHARACTER_DICE_SPRITE_TAG));
      visibleNodes.pushBack(this->_getNodeForCharacterPosition());
      visibleNodes.pushBack(this->_getNodesForAdjacentCharacterPosition());
      this->_addOverlayWithVisibleNodes(visibleNodes);
    }

    return canMove;
  };
  touchListener->onTouchMoved = [=](Touch* touch, Event* event) {
    auto touchLocation = touch->getLocation();

    for (auto adjacentNode : this->_getNodesForAdjacentCharacterPosition()) {
      Color3B color = Color3B::WHITE;

      if (adjacentNode->getBoundingBox().containsPoint(touchLocation)) {
        color = Color3B(170, 255, 170);
      }

      adjacentNode->setColor(color);
    }
    sprite->setPosition(touch->getLocation());
  };
  touchListener->onTouchEnded = [=](Touch* touch, Event* event) {
    bool characterMoved = false;
    auto touchLocation = touch->getLocation();

    auto coordinate = this->getGame()->getCharacterPosition();
    auto scenePosition = this->_positionInScene(coordinate);

    this->_removeOverlay();

    for (auto adjacentNode : this->_getNodesForAdjacentCharacterPosition()) {
      adjacentNode->setColor(Color3B::WHITE);

      if (adjacentNode->getBoundingBox().containsPoint(touchLocation)) {
        characterMoved = true;

        auto newCoordinate = this->_positionInGameCoordinate(touchLocation);
        auto newPosition = this->_positionInScene(newCoordinate);

        auto moveNewPosition = MoveTo::create(RETURN_CHARACTER_DURATION, newPosition);
        auto actionEnded = CallFunc::create([=]() {
          this->getGame()->setCharacterPosition(newCoordinate);
        });
        sprite->runAction(Sequence::create(moveNewPosition, actionEnded, NULL));
      }
    }

    if (!characterMoved) {
      auto moveBack = MoveTo::create(RETURN_CHARACTER_DURATION, scenePosition);
      sprite->runAction(moveBack);
    }
  };

  auto dispatcher = Director::getInstance()->getEventDispatcher();
  dispatcher->addEventListenerWithSceneGraphPriority(touchListener, sprite);

  return sprite;
}

Layer* GameplayScene::_getObjectsLayer() {
  return (Layer*) this->getChildByTag(OBJECTS_LAYER_TAG);
}

Layer* GameplayScene::_getControlsLayer() {
  return (Layer*) this->getChildByTag(CONTROLS_LAYER_TAG);
}

Vec2 GameplayScene::_positionInScene(Vec2 gameCoordinate) {
  auto centerPosition = INITIAL_POSITION;
  auto centerOfScene = this->_centerOfScene();

  auto offsetX = gameCoordinate.x - centerPosition.x;
  auto offsetY = gameCoordinate.y - centerPosition.y;

  return Vec2(centerOfScene.x + offsetX * TILE_DIMENSION,
              centerOfScene.y + offsetY * TILE_DIMENSION);
}

Vec2 GameplayScene::_positionInGameCoordinate(Vec2 scenePosition) {
  auto centerPosition = INITIAL_POSITION;
  auto centerOfScene = this->_centerOfScene();

  auto offsetX = scenePosition.x - centerOfScene.x;
  auto offsetY = scenePosition.y - centerOfScene.y;

  auto halfTileDimension = TILE_DIMENSION / 2;

  offsetX > halfTileDimension ? offsetX += halfTileDimension : offsetX -= halfTileDimension;
  offsetY > halfTileDimension ? offsetY += halfTileDimension : offsetY -= halfTileDimension;

  return Vec2(centerPosition.x + int(offsetX / TILE_DIMENSION),
              centerPosition.y + int(offsetY / TILE_DIMENSION));
}

void GameplayScene::_adjustCharacterDiceSpritePosition() {
  auto sprite = this->_getObjectsLayer()->getChildByTag(CHARACTER_DICE_SPRITE_TAG);
  auto characterPosition = this->getGame()->getCharacterPosition();
  sprite->setPosition(this->_positionInScene(characterPosition));
}

void GameplayScene::_addOverlayWithVisibleNodes(Vector<Node *> visibleNodes) {
  auto overlayLayer = LayerColor::create(Color4B(0, 0, 0, 0));
  overlayLayer->setTag(OVERLAY_LAYER_TAG);
  this->_getObjectsLayer()->addChild(overlayLayer, OVERLAY_Z_ORDER);

  auto fadeIn = FadeTo::create(OVERLAY_DURATION, OVERLAY_OPACITY);
  overlayLayer->runAction(fadeIn);

  for (auto visibleNode : visibleNodes) {
    auto newZOrder = visibleNode->getLocalZOrder() + OVERLAY_Z_ORDER;
    visibleNode->setLocalZOrder(newZOrder);
  }

  this->setInteractableNodes(visibleNodes);
}

void GameplayScene::_removeOverlay() {
  this->_disableInteractions();

  auto overlayLayer = this->_getObjectsLayer()->getChildByTag(OVERLAY_LAYER_TAG);

  auto fadeOut = FadeOut::create(OVERLAY_DURATION);
  auto changeLayer = CallFunc::create([=]() {
    for (auto node : this->getInteractableNodes()) {
      auto oldZOrder = node->getLocalZOrder() - OVERLAY_Z_ORDER;
      node->setLocalZOrder(oldZOrder);
    }
  });
  auto removeSelf = RemoveSelf::create();
  auto animationEnded = CallFunc::create([=]() {
    this->_enableInteractions();
  });

  overlayLayer->runAction(Sequence::create(fadeOut, changeLayer, removeSelf, animationEnded, NULL));
}

Vec2 GameplayScene::_centerOfScene() {
  Vec2 visibleOrigin = Director::getInstance()->getVisibleOrigin();
  Size visibleSize = Director::getInstance()->getVisibleSize();

  return Vec2(visibleSize.width / 2 + visibleOrigin.x,
              visibleSize.height / 2 + visibleOrigin.y);
}

Node* GameplayScene::_getNodeForCharacterPosition() {
  auto position = this->getGame()->getCharacterPosition();
  auto name = this->getGame()->getDungeon()->nameForPosition(position);
  return this->_getObjectsLayer()->getChildByName(name);
}

Vector<Node*> GameplayScene::_getNodesForAdjacentCharacterPosition() {
  Node* activeLayer = this->_getObjectsLayer();
  auto overlayLayer = this->getChildByTag(OVERLAY_LAYER_TAG);
  if (overlayLayer) {
    activeLayer = overlayLayer;
  }

  Vector<Node*> nodes;

  auto position = this->getGame()->getCharacterPosition();
  auto adjacentPositions = this->getGame()->getDungeon()->adjacentPositionsTo(position);
  for (auto adjacentPosition : adjacentPositions) {
    auto name = this->getGame()->getDungeon()->nameForPosition(adjacentPosition);
    nodes.pushBack(activeLayer->getChildByName(name));
  }

  return nodes;
}

bool GameplayScene::_isInteractionEnabled() {
  return _userInteractionEnabled;
}

void GameplayScene::_disableInteractions() {
  _userInteractionEnabled = false;
}

void GameplayScene::_enableInteractions() {
  _userInteractionEnabled = true;
}<commit_msg>Permitindo mover a 'camera' na cena.<commit_after>//
//  GameplayScene.cpp
//  MasmorraDados
//
//  Created by Marlon Andrade on 16/02/2015.
//
//

#include "GameplayScene.h"

#include "BackgroundLayer.h"
#include "CharacterDiceSprite.h"
#include "RoomPlacement.h"

USING_NS_CC;

#pragma mark - Public Interface

bool GameplayScene::init() {
  if (!Scene::init()) {
    return false;
  }

  this->_enableInteractions();

  auto game = Game::createWithRoomPlacedDelegate([&](Vector<RoomPlacement*> placements) {
    if (placements.size() > 0) {
      this->_disableInteractions();
    }

    float delayTime = 0;
    int zOrder = placements.size();

    for (auto placement : placements) {
      auto room = placement->getRoom();
      auto position = placement->getPosition();

      auto roomSprite = Sprite::create(room->getImagePath());
      auto name = this->getGame()->getDungeon()->nameForPosition(position);
      roomSprite->setName(name);

      auto size = Director::getInstance()->getVisibleSize();
      auto origin = Director::getInstance()->getVisibleOrigin();

      auto deckPosition = Vec2(origin.x + size.width - TILE_DIMENSION / 2 - 20,
                               origin.y + size.height - TILE_DIMENSION / 2 - 20);
      roomSprite->setPosition(deckPosition);

      this->_getObjectsLayer()->addChild(roomSprite, zOrder);

      auto spritePosition = this->_positionInScene(position);

      auto delay = DelayTime::create(delayTime);
      auto animationStarted = CallFunc::create([=]() {
        this->_disableInteractions();
        roomSprite->setLocalZOrder(DUNGEON_ROOM_Z_ORDER + 10);
      });
      auto easeMove = EaseBackIn::create(MoveTo::create(PLACE_ROOM_DURATION, spritePosition));
      auto animationEnded = CallFunc::create([=]() {
        this->_enableInteractions();
        roomSprite->setLocalZOrder(DUNGEON_ROOM_Z_ORDER);
      });

      roomSprite->runAction(Sequence::create(delay, animationStarted, easeMove,
                                             animationEnded, NULL));

      delayTime += PLACE_ROOM_DURATION;
      zOrder--;
    }
  });

  this->setGame(game);
  this->adjustInitialLayers();

  return true;
}

#pragma mark - Private Interface

void GameplayScene::adjustInitialLayers() {
  auto center = this->_centerOfScene();

  auto backgroundLayer = BackgroundLayer::create();
  this->addChild(backgroundLayer, -2);

  auto objectsLayer = this->_createObjectsLayer();
  this->addChild(objectsLayer, -1);

  auto touchListener = EventListenerTouchOneByOne::create();
  touchListener->onTouchBegan = [=](Touch* touch, Event* event) {
    return true;
  };
  touchListener->onTouchMoved = [=](Touch* touch, Event* event) {
    auto delta = touch->getDelta();

    auto currentPosition = objectsLayer->getPosition();
    auto newPosition = Vec2(currentPosition.x + delta.x,
                            currentPosition.y + delta.y);

    backgroundLayer->setPosition(newPosition);
    objectsLayer->setPosition(newPosition);
  };

  auto dispatcher = Director::getInstance()->getEventDispatcher();
  dispatcher->addEventListenerWithSceneGraphPriority(touchListener, objectsLayer);

  auto controlsLayer = this->_createControlsLayer();
  this->addChild(controlsLayer, 1);

  this->getGame()->setCharacterPosition(INITIAL_POSITION);
  this->_adjustCharacterDiceSpritePosition();
}

Layer* GameplayScene::_createObjectsLayer() {
  auto objectsLayer = Layer::create();
  objectsLayer->setTag(OBJECTS_LAYER_TAG);

  auto initialRoom = this->getGame()->getDungeon()->getInitialRoom();
  auto initialPosition = INITIAL_POSITION;

  auto initialSprite = Sprite::create(initialRoom->getImagePath());
  auto name = this->getGame()->getDungeon()->nameForPosition(initialPosition);
  initialSprite->setName(name);
  initialSprite->setPosition(this->_positionInScene(INITIAL_POSITION));
  objectsLayer->addChild(initialSprite, DUNGEON_ROOM_Z_ORDER);

  objectsLayer->addChild(this->_createCharacterDiceSprite(), GAME_OBJECTS_Z_ORDER);

  return objectsLayer;
}

Layer* GameplayScene::_createControlsLayer() {
  auto controlsLayer = Layer::create();
  controlsLayer->setTag(CONTROLS_LAYER_TAG);

  return controlsLayer;
}

Node* GameplayScene::_createCharacterDiceSprite() {
  auto sprite = CharacterDiceSprite::create();
  sprite->setTag(CHARACTER_DICE_SPRITE_TAG);

  auto touchListener = EventListenerTouchOneByOne::create();
  touchListener->setSwallowTouches(true);
  touchListener->onTouchBegan = [&](Touch* touch, Event* event) {
    auto target = event->getCurrentTarget();
    auto layer = target->getParent();

    auto bounds = target->getBoundingBox();
    auto touchLocation = layer->convertTouchToNodeSpace(touch);

    auto touchInSprite = bounds.containsPoint(touchLocation);

    log("%d", touchInSprite);

    bool containsBoot = true;
    auto canMove = this->_isInteractionEnabled() && touchInSprite && containsBoot;

    if (canMove) {
      Vector<Node*> visibleNodes;
      visibleNodes.pushBack(this->_getObjectsLayer()->getChildByTag(CHARACTER_DICE_SPRITE_TAG));
      visibleNodes.pushBack(this->_getNodeForCharacterPosition());
      visibleNodes.pushBack(this->_getNodesForAdjacentCharacterPosition());
      this->_addOverlayWithVisibleNodes(visibleNodes);
    }

    return canMove;
  };
  touchListener->onTouchMoved = [=](Touch* touch, Event* event) {
    auto target = event->getCurrentTarget();
    auto layer = target->getParent();

    auto bounds = target->getBoundingBox();
    auto touchLocation = layer->convertTouchToNodeSpace(touch);

    for (auto adjacentNode : this->_getNodesForAdjacentCharacterPosition()) {
      Color3B color = Color3B::WHITE;

      if (adjacentNode->getBoundingBox().containsPoint(touchLocation)) {
        color = Color3B(170, 255, 170);
      }

      adjacentNode->setColor(color);
    }

    sprite->setPosition(touchLocation);
  };
  touchListener->onTouchEnded = [=](Touch* touch, Event* event) {
    auto target = event->getCurrentTarget();
    auto layer = target->getParent();

    auto bounds = target->getBoundingBox();
    auto touchLocation = layer->convertTouchToNodeSpace(touch);

    bool characterMoved = false;

    auto coordinate = this->getGame()->getCharacterPosition();
    auto scenePosition = this->_positionInScene(coordinate);

    this->_removeOverlay();

    for (auto adjacentNode : this->_getNodesForAdjacentCharacterPosition()) {
      adjacentNode->setColor(Color3B::WHITE);

      if (adjacentNode->getBoundingBox().containsPoint(touchLocation)) {
        characterMoved = true;

        auto newCoordinate = this->_positionInGameCoordinate(touchLocation);
        auto newPosition = this->_positionInScene(newCoordinate);

        auto moveNewPosition = MoveTo::create(RETURN_CHARACTER_DURATION, newPosition);
        auto actionEnded = CallFunc::create([=]() {
          this->getGame()->setCharacterPosition(newCoordinate);
        });
        sprite->runAction(Sequence::create(moveNewPosition, actionEnded, NULL));
      }
    }

    if (!characterMoved) {
      auto moveBack = MoveTo::create(RETURN_CHARACTER_DURATION, scenePosition);
      sprite->runAction(moveBack);
    }
  };

  auto dispatcher = Director::getInstance()->getEventDispatcher();
  dispatcher->addEventListenerWithSceneGraphPriority(touchListener, sprite);

  return sprite;
}

Layer* GameplayScene::_getObjectsLayer() {
  return (Layer*) this->getChildByTag(OBJECTS_LAYER_TAG);
}

Layer* GameplayScene::_getControlsLayer() {
  return (Layer*) this->getChildByTag(CONTROLS_LAYER_TAG);
}

Vec2 GameplayScene::_positionInScene(Vec2 gameCoordinate) {
  auto centerPosition = INITIAL_POSITION;
  auto centerOfScene = this->_centerOfScene();

  auto offsetX = gameCoordinate.x - centerPosition.x;
  auto offsetY = gameCoordinate.y - centerPosition.y;

  return Vec2(centerOfScene.x + offsetX * TILE_DIMENSION,
              centerOfScene.y + offsetY * TILE_DIMENSION);
}

Vec2 GameplayScene::_positionInGameCoordinate(Vec2 scenePosition) {
  auto centerPosition = INITIAL_POSITION;
  auto centerOfScene = this->_centerOfScene();

  auto offsetX = scenePosition.x - centerOfScene.x;
  auto offsetY = scenePosition.y - centerOfScene.y;

  auto halfTileDimension = TILE_DIMENSION / 2;

  offsetX > halfTileDimension ? offsetX += halfTileDimension : offsetX -= halfTileDimension;
  offsetY > halfTileDimension ? offsetY += halfTileDimension : offsetY -= halfTileDimension;

  return Vec2(centerPosition.x + int(offsetX / TILE_DIMENSION),
              centerPosition.y + int(offsetY / TILE_DIMENSION));
}

void GameplayScene::_adjustCharacterDiceSpritePosition() {
  auto sprite = this->_getObjectsLayer()->getChildByTag(CHARACTER_DICE_SPRITE_TAG);
  auto characterPosition = this->getGame()->getCharacterPosition();
  sprite->setPosition(this->_positionInScene(characterPosition));
}

void GameplayScene::_addOverlayWithVisibleNodes(Vector<Node *> visibleNodes) {
  auto objectsLayer = this->_getObjectsLayer();

  auto overlayLayer = LayerColor::create(Color4B(0, 0, 0, 0));
  overlayLayer->setTag(OVERLAY_LAYER_TAG);
  overlayLayer->setPosition(Vec2(-objectsLayer->getPosition().x,
                                 -objectsLayer->getPosition().y));

  objectsLayer->addChild(overlayLayer, OVERLAY_Z_ORDER);

  auto fadeIn = FadeTo::create(OVERLAY_DURATION, OVERLAY_OPACITY);
  overlayLayer->runAction(fadeIn);

  for (auto visibleNode : visibleNodes) {
    auto newZOrder = visibleNode->getLocalZOrder() + OVERLAY_Z_ORDER;
    visibleNode->setLocalZOrder(newZOrder);
  }

  this->setInteractableNodes(visibleNodes);
}

void GameplayScene::_removeOverlay() {
  this->_disableInteractions();

  auto overlayLayer = this->_getObjectsLayer()->getChildByTag(OVERLAY_LAYER_TAG);

  auto fadeOut = FadeOut::create(OVERLAY_DURATION);
  auto changeLayer = CallFunc::create([=]() {
    for (auto node : this->getInteractableNodes()) {
      auto oldZOrder = node->getLocalZOrder() - OVERLAY_Z_ORDER;
      node->setLocalZOrder(oldZOrder);
    }
  });
  auto removeSelf = RemoveSelf::create();
  auto animationEnded = CallFunc::create([=]() {
    this->_enableInteractions();
  });

  overlayLayer->runAction(Sequence::create(fadeOut, changeLayer, removeSelf, animationEnded, NULL));
}

Vec2 GameplayScene::_centerOfScene() {
  Vec2 visibleOrigin = Director::getInstance()->getVisibleOrigin();
  Size visibleSize = Director::getInstance()->getVisibleSize();

  return Vec2(visibleSize.width / 2 + visibleOrigin.x,
              visibleSize.height / 2 + visibleOrigin.y);
}

Node* GameplayScene::_getNodeForCharacterPosition() {
  auto position = this->getGame()->getCharacterPosition();
  auto name = this->getGame()->getDungeon()->nameForPosition(position);
  return this->_getObjectsLayer()->getChildByName(name);
}

Vector<Node*> GameplayScene::_getNodesForAdjacentCharacterPosition() {
  Node* activeLayer = this->_getObjectsLayer();
  auto overlayLayer = this->getChildByTag(OVERLAY_LAYER_TAG);
  if (overlayLayer) {
    activeLayer = overlayLayer;
  }

  Vector<Node*> nodes;

  auto position = this->getGame()->getCharacterPosition();
  auto adjacentPositions = this->getGame()->getDungeon()->adjacentPositionsTo(position);
  for (auto adjacentPosition : adjacentPositions) {
    auto name = this->getGame()->getDungeon()->nameForPosition(adjacentPosition);
    nodes.pushBack(activeLayer->getChildByName(name));
  }

  return nodes;
}

bool GameplayScene::_isInteractionEnabled() {
  return _userInteractionEnabled;
}

void GameplayScene::_disableInteractions() {
  _userInteractionEnabled = false;
}

void GameplayScene::_enableInteractions() {
  _userInteractionEnabled = true;
}<|endoftext|>


<commit_before>/*
 * MinimumSpanningTrees.cpp - Main entry point for the program
 *
 * Built for EECS2510 - Nonlinear Data Structures
 *	at The University of Toledo, Spring 2016
 *
 * Copyright (c) 2016 Nathan Lowe
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "stdafx.h"
#include <cassert>
#include <iostream>
#include <fstream>

#include "LinkedList.h"
#include "Options.h"
#include "WeightedGraph.h"
#include "SpanningTree.h"
#include "Verbose.h"
#include "PrimVertex.h"

using namespace std;

// Since the verbose namespace is used multiple times in different files,
// we need to define an implementation of the enable flag in exactly one
// translation unit so that it is shared between all units
namespace verbose
{
	bool enable = false;
}

// Forward-declare these functions so main can be at the top as required by the project spec
void printHelp();
void Kruskal(WeightedGraph& graph);
void Prim(WeightedGraph& graph);

int main(int argc, char* argv[])
{
	// parse the command-line arguments
	auto opts = Options(argc, argv);

	if (opts.help)
	{
		printHelp();
		return 0;
	}

	if(opts.errors)
	{
		cout << "One or more errors occurred while parsing arguments: " << endl;
		cout << opts.errorMessage;
		cout << endl;
		cout << "Call with --help for help" << endl;

		return -1;
	}

	if (opts.verboseEnable) verbose::enable = true;

	ifstream reader;
	reader.open(opts.TestFilePath, std::ios::in);

	if(!reader.good())
	{
		reader.close();
		cout << "Unable to open graph for read: '" << opts.TestFilePath << "'" << endl;
		return -1;
	}

	// Load the graph
	WeightedGraph g(reader);
	reader.close();

	cout << "Finding minimum spanning tree using Kruskal's algorithm..." << endl;
	try
	{
		Kruskal(g);
	}
	catch (exception ex)
	{
		cout << "Unable to calculate minimum spanning tree: " << ex.what() << endl;
	}

	cout << endl << "Finding minimum spanning tree using Prim's algorithm..." << endl;
	try
	{
		Prim(g);
	}
	catch (exception ex)
	{
		cout << "Unable to calculate minimum spanning tree: " << ex.what() << endl;
	}

    return 0;
}

void printHelp()
{
	cout << "MinimumSpanningTrees <-f path> [-q]" << endl;
	cout << "Parameters:" << endl;
	cout << "\t-f, --file\t\tThe input file to test" << endl;
	cout << "\t-v, --verbose\t\tEnable verbose output" << endl;

	cout << endl;

	cout << "At the end of each algorithm, the generated minimum spanning tree in addition to its total" << endl;
	cout << "weight is printed to standard out. To suppress the printing of the tree, specify the -q flag" << endl;
}

// Calculate and print out a minimum weight spanning tree of the specified graph using
// Kruskal's algorithm:
//
// For each edge sorted by edge weight ascending
//    If the edge connects two verticies that are not already in the same group
//        add them to the tree
void Kruskal(WeightedGraph& graph)
{
	auto sets = new LinkedList<Vertex>*[graph.VertexCount]{nullptr};

	for(auto i = 0; i < graph.VertexCount; i++)
	{
		sets[i] = new LinkedList<Vertex>();
		sets[i]->add(graph.Vertices[i]);
	}

	verbose::write("[Kruskal] Obtaining edges...");
	// Get the edges from the graph
	// This is a minimum priority queue sorted on edge weight
	auto edges = graph.Edges();
	auto tree = new SpanningTree();

	while (!edges->isEmpty())
	{
		// Find the set containing A and B from this edge
		LinkedList<Vertex> *a = nullptr, *b = nullptr;
		auto edge = edges->dequeue();

		// Locate the vertex sets that contain the vertices of this edge
		size_t aIndex = 0;
		size_t bIndex = 0;
		for(auto index = 0; index < graph.VertexCount; index++)
		{
			if(sets[index] != nullptr)
			{
				if (sets[index]->Contains(const_cast<Vertex*>(edge->A)))
				{
					a = sets[index];
					aIndex = index;
				}
				if (sets[index]->Contains(const_cast<Vertex*>(edge->B)))
				{
					b = sets[index];
					bIndex = index;
				}

				// If we found the sets that contain this vertex, we can break early
				if (a != nullptr && b != nullptr) break;
			}
		}

		assert(a != nullptr && b != nullptr && edge != nullptr);

		if (aIndex != bIndex)
		{
			// If the edges belong to different sets, take it
			verbose::write("[Kruskal] Picking edge " + edge->A->Name + "-" + edge->B->Name + ": " + std::to_string(edge->EdgeWeight));
			a->addAll(*b);
			sets[bIndex] = nullptr;
			tree->accept(edge);
		}
		else
		{
			// Otherwise, the edge is redundant
			verbose::write("[Kruskal] Edge " + edge->A->Name + "-" + edge->B->Name + ": " + std::to_string(edge->EdgeWeight) + " is redundant");
		}
	}

	// Done! Print out the tree
	verbose::write("[Kruskal] Done");
	tree->print();
}

// Calculate and print out a minimum weight spanning tree of the specified graph using
// Prim's algorithm:
//
// Start at any vertex
// Until all vertices have been considered
//     Take the lowest edge connecting the tree to any unconnected vertex
void Prim(WeightedGraph& graph)
{
	verbose::write("[Prim] Initializing vertices...");

	// We need a queue on a property that gets updated frequently
	// Wrap the vertices in PrimVertex structures and create a queue for this structure
	auto pvs = new PrimVertex*[graph.VertexCount]{ nullptr };
	auto Q = new MinPriorityQueue<PrimVertex>([](PrimVertex* lhs, PrimVertex* rhs) { return lhs->QKey - rhs->QKey; }, graph.VertexCount);

	// Initialize all vertices
	for(auto i = 0; i < graph.VertexCount; i++)
	{
		auto pv = new PrimVertex(graph.Vertices[i]);
		if (i == 0) pv->QKey = 0;
		pvs[i] = pv;
		Q->enqueue(pv);
	}

	auto tree = new SpanningTree();

	// And start taking edges
	while(!Q->isEmpty())
	{
		auto u = Q->dequeue();
		verbose::write("[Prim] Now analyzing connections from " + u->Name + " (local weight: " + to_string(u->QKey) + ")");

		// Look at all vertices reachable from the specified vertex
		for(auto c = 0; c < graph.VertexCount; c++)
		{
			auto w = graph.GetWeight(u->ID, c);
			if (w == 0) continue;
			auto v = pvs[c];

			// Check to see if this is a better way to reach this vertex
			if(Q->contains(v) && w < v->QKey)
			{
				verbose::write(
					"[Prim]     Discovered a better way to get to " + v->Name +
					" (via " + u->Name + " with weight " + to_string(w) +
					(v->QKey == INT64_MAX ? "" : ", previous best was " + to_string(v->QKey) +
					(v->pi == nullptr ? "" : " via " + v->pi->Name)) + ")"
				);

				v->pi = u;
				v->QKey = w;
				Q->notifyPriorityUpdated(v);
			}
		}
	}

	// Now simply work backwards taking the vertex and its parent as an edge
	for(int i = graph.VertexCount - 1; i >= 0; i--)
	{
		auto v = pvs[i];
		if (v->pi != nullptr) tree->accept(new VertexPair(v->pi, v, v->QKey));
	}

	// Done! Print the tree
	verbose::write("[Prim] Done");
	tree->print();
}
<commit_msg>Fix help<commit_after>/*
 * MinimumSpanningTrees.cpp - Main entry point for the program
 *
 * Built for EECS2510 - Nonlinear Data Structures
 *	at The University of Toledo, Spring 2016
 *
 * Copyright (c) 2016 Nathan Lowe
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "stdafx.h"
#include <cassert>
#include <iostream>
#include <fstream>

#include "LinkedList.h"
#include "Options.h"
#include "WeightedGraph.h"
#include "SpanningTree.h"
#include "Verbose.h"
#include "PrimVertex.h"

using namespace std;

// Since the verbose namespace is used multiple times in different files,
// we need to define an implementation of the enable flag in exactly one
// translation unit so that it is shared between all units
namespace verbose
{
	bool enable = false;
}

// Forward-declare these functions so main can be at the top as required by the project spec
void printHelp();
void Kruskal(WeightedGraph& graph);
void Prim(WeightedGraph& graph);

int main(int argc, char* argv[])
{
	// parse the command-line arguments
	auto opts = Options(argc, argv);

	if (opts.help)
	{
		printHelp();
		return 0;
	}

	if(opts.errors)
	{
		cout << "One or more errors occurred while parsing arguments: " << endl;
		cout << opts.errorMessage;
		cout << endl;
		cout << "Call with --help for help" << endl;

		return -1;
	}

	if (opts.verboseEnable) verbose::enable = true;

	ifstream reader;
	reader.open(opts.TestFilePath, std::ios::in);

	if(!reader.good())
	{
		reader.close();
		cout << "Unable to open graph for read: '" << opts.TestFilePath << "'" << endl;
		return -1;
	}

	// Load the graph
	WeightedGraph g(reader);
	reader.close();

	cout << "Finding minimum spanning tree using Kruskal's algorithm..." << endl;
	try
	{
		Kruskal(g);
	}
	catch (exception ex)
	{
		cout << "Unable to calculate minimum spanning tree: " << ex.what() << endl;
	}

	cout << endl << "Finding minimum spanning tree using Prim's algorithm..." << endl;
	try
	{
		Prim(g);
	}
	catch (exception ex)
	{
		cout << "Unable to calculate minimum spanning tree: " << ex.what() << endl;
	}

    return 0;
}

void printHelp()
{
	cout << "MinimumSpanningTrees <-f path> [-v]" << endl;
	cout << "Parameters:" << endl;
	cout << "\t-f, --file\t\tThe input file to test" << endl;
	cout << "\t-v, --verbose\t\tEnable verbose output" << endl;

	cout << endl;

	cout << "At the end of each algorithm, the generated minimum spanning tree in addition to its total" << endl;
	cout << "weight is printed to standard out. To suppress the printing of the tree, specify the -q flag" << endl;
}

// Calculate and print out a minimum weight spanning tree of the specified graph using
// Kruskal's algorithm:
//
// For each edge sorted by edge weight ascending
//    If the edge connects two verticies that are not already in the same group
//        add them to the tree
void Kruskal(WeightedGraph& graph)
{
	auto sets = new LinkedList<Vertex>*[graph.VertexCount]{nullptr};

	for(auto i = 0; i < graph.VertexCount; i++)
	{
		sets[i] = new LinkedList<Vertex>();
		sets[i]->add(graph.Vertices[i]);
	}

	verbose::write("[Kruskal] Obtaining edges...");
	// Get the edges from the graph
	// This is a minimum priority queue sorted on edge weight
	auto edges = graph.Edges();
	auto tree = new SpanningTree();

	while (!edges->isEmpty())
	{
		// Find the set containing A and B from this edge
		LinkedList<Vertex> *a = nullptr, *b = nullptr;
		auto edge = edges->dequeue();

		// Locate the vertex sets that contain the vertices of this edge
		size_t aIndex = 0;
		size_t bIndex = 0;
		for(auto index = 0; index < graph.VertexCount; index++)
		{
			if(sets[index] != nullptr)
			{
				if (sets[index]->Contains(const_cast<Vertex*>(edge->A)))
				{
					a = sets[index];
					aIndex = index;
				}
				if (sets[index]->Contains(const_cast<Vertex*>(edge->B)))
				{
					b = sets[index];
					bIndex = index;
				}

				// If we found the sets that contain this vertex, we can break early
				if (a != nullptr && b != nullptr) break;
			}
		}

		assert(a != nullptr && b != nullptr && edge != nullptr);

		if (aIndex != bIndex)
		{
			// If the edges belong to different sets, take it
			verbose::write("[Kruskal] Picking edge " + edge->A->Name + "-" + edge->B->Name + ": " + std::to_string(edge->EdgeWeight));
			a->addAll(*b);
			sets[bIndex] = nullptr;
			tree->accept(edge);
		}
		else
		{
			// Otherwise, the edge is redundant
			verbose::write("[Kruskal] Edge " + edge->A->Name + "-" + edge->B->Name + ": " + std::to_string(edge->EdgeWeight) + " is redundant");
		}
	}

	// Done! Print out the tree
	verbose::write("[Kruskal] Done");
	tree->print();
}

// Calculate and print out a minimum weight spanning tree of the specified graph using
// Prim's algorithm:
//
// Start at any vertex
// Until all vertices have been considered
//     Take the lowest edge connecting the tree to any unconnected vertex
void Prim(WeightedGraph& graph)
{
	verbose::write("[Prim] Initializing vertices...");

	// We need a queue on a property that gets updated frequently
	// Wrap the vertices in PrimVertex structures and create a queue for this structure
	auto pvs = new PrimVertex*[graph.VertexCount]{ nullptr };
	auto Q = new MinPriorityQueue<PrimVertex>([](PrimVertex* lhs, PrimVertex* rhs) { return lhs->QKey - rhs->QKey; }, graph.VertexCount);

	// Initialize all vertices
	for(auto i = 0; i < graph.VertexCount; i++)
	{
		auto pv = new PrimVertex(graph.Vertices[i]);
		if (i == 0) pv->QKey = 0;
		pvs[i] = pv;
		Q->enqueue(pv);
	}

	auto tree = new SpanningTree();

	// And start taking edges
	while(!Q->isEmpty())
	{
		auto u = Q->dequeue();
		verbose::write("[Prim] Now analyzing connections from " + u->Name + " (local weight: " + to_string(u->QKey) + ")");

		// Look at all vertices reachable from the specified vertex
		for(auto c = 0; c < graph.VertexCount; c++)
		{
			auto w = graph.GetWeight(u->ID, c);
			if (w == 0) continue;
			auto v = pvs[c];

			// Check to see if this is a better way to reach this vertex
			if(Q->contains(v) && w < v->QKey)
			{
				verbose::write(
					"[Prim]     Discovered a better way to get to " + v->Name +
					" (via " + u->Name + " with weight " + to_string(w) +
					(v->QKey == INT64_MAX ? "" : ", previous best was " + to_string(v->QKey) +
					(v->pi == nullptr ? "" : " via " + v->pi->Name)) + ")"
				);

				v->pi = u;
				v->QKey = w;
				Q->notifyPriorityUpdated(v);
			}
		}
	}

	// Now simply work backwards taking the vertex and its parent as an edge
	for(int i = graph.VertexCount - 1; i >= 0; i--)
	{
		auto v = pvs[i];
		if (v->pi != nullptr) tree->accept(new VertexPair(v->pi, v, v->QKey));
	}

	// Done! Print the tree
	verbose::write("[Prim] Done");
	tree->print();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cassert>
#include <iostream>
#include <cstdlib>

#if 0
#include <unistd.h>

#include "itkTimeProbe.h"
#endif

#include "itkMacro.h"
#include "otbStopwatch.h"

int otbStopwatchTest(int itkNotUsed(argc), char * itkNotUsed(argv)[])
{
  otb::Stopwatch sw;

  assert( !sw.IsRunning() );
  assert( sw.GetElapsedMilliseconds() == 0 );

  sw.Start();
  assert( sw.IsRunning() );
  sw.Stop();

  sw.Reset();
  assert( !sw.IsRunning() );
  assert( sw.GetElapsedMilliseconds() == 0 );

  sw = otb::Stopwatch::StartNew();
  assert( sw.IsRunning() );
  sw.Stop();

#if 0
  // We have no portable sleep() and otbThreads is not linked here
  sw.Start();
  usleep(500 * 1000);
  sw.Stop();
  assert( sw.GetElapsedMilliseconds() > 450 && sw.GetElapsedMilliseconds() < 550 );

  sw.Start();
  usleep(500 * 1000);
  sw.Stop();
  assert( sw.GetElapsedMilliseconds() > 900 && sw.GetElapsedMilliseconds() < 1100 );

  sw.Restart();
  usleep(500 * 1000);
  sw.Stop();
  assert( sw.GetElapsedMilliseconds() > 450 && sw.GetElapsedMilliseconds() < 550 );

  const int iterations = 100000;
  sw.Restart();
  for (int i = 0; i < iterations; i++)
    {
    itk::TimeProbe chrono;
    chrono.Start();
    chrono.Stop();
    }
  std::cerr << "itk::TimeProbe time: " << sw.GetElapsedMilliseconds() << std::endl;

  sw.Restart();
  for (int i = 0; i < iterations; i++)
    {
    auto chrono = otb::Stopwatch::StartNew();
    chrono.Stop();
    }
  std::cerr << "otb::Stopwatch time: " << sw.GetElapsedMilliseconds() << std::endl;

  #endif

  return EXIT_SUCCESS;
}
<commit_msg>ENH: Enable otb::Stopwatch tests<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cassert>
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <thread>

#include "itkMacro.h"

#include "otbStopwatch.h"

using namespace std::chrono_literals;

int otbStopwatchTest(int itkNotUsed(argc), char * itkNotUsed(argv)[])
{
  otb::Stopwatch sw;

  assert( !sw.IsRunning() );
  assert( sw.GetElapsedMilliseconds() == 0 );

  sw.Start();
  assert( sw.IsRunning() );
  sw.Stop();

  sw.Reset();
  assert( !sw.IsRunning() );
  assert( sw.GetElapsedMilliseconds() == 0 );

  sw = otb::Stopwatch::StartNew();
  assert( sw.IsRunning() );
  sw.Stop();

  // We have no portable sleep() and otbThreads is not linked here
  sw.Start();
  std::this_thread::sleep_for(500ms);
  sw.Stop();
  assert( sw.GetElapsedMilliseconds() > 450 && sw.GetElapsedMilliseconds() < 550 );

  sw.Start();
  std::this_thread::sleep_for(500ms);
  sw.Stop();
  assert( sw.GetElapsedMilliseconds() > 900 && sw.GetElapsedMilliseconds() < 1100 );

  sw.Restart();
  std::this_thread::sleep_for(500ms);
  sw.Stop();
  assert( sw.GetElapsedMilliseconds() > 450 && sw.GetElapsedMilliseconds() < 550 );

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>
#include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UFile.h>
#include <rtabmap/core/CameraThread.h>
#include <rtabmap/core/CameraRGBD.h>
#include <rtabmap/core/Camera.h>
#include <rtabmap/core/CameraThread.h>
#include <rtabmap/gui/DataRecorder.h>
#include <QtGui/QApplication>
#include <signal.h>

using namespace rtabmap;

void showUsage()
{
	printf("\nUsage:\n"
			"dataRecorder [options] output.db\n"
			"Options:\n"
			"  -hide                    Don't display the current cloud recorded.\n"
			"  -debug                   Set debug level for the logger.\n"
			"  -rate #.#                Input rate Hz (default 0=inf)\n"
			"  -openni                  Use openni camera instead of the usb camera.\n");
	exit(1);
}

rtabmap::CameraThread * cam = 0;
QApplication * app = 0;
// catch ctrl-c
void sighandler(int sig)
{
	printf("\nSignal %d caught...\n", sig);
	if(cam)
	{
		cam->join(true);
	}
	if(app)
	{
		QMetaObject::invokeMethod(app, "quit");
	}
}

int main (int argc, char * argv[])
{
	ULogger::setType(ULogger::kTypeConsole);
	ULogger::setLevel(ULogger::kInfo);

	// parse arguments
	QString fileName;
	bool show = true;
	bool openni = false;
	float rate = 0.0f;

	if(argc < 2)
	{
		showUsage();
	}
	for(int i=1; i<argc-1; ++i)
	{
		if(strcmp(argv[i], "-rate") == 0)
		{
			++i;
			if(i < argc)
			{
				rate = std::atof(argv[i]);
				if(rate < 0.0f)
				{
					showUsage();
				}
			}
			else
			{
				showUsage();
			}
			continue;
		}
		if(strcmp(argv[i], "-debug") == 0)
		{
			ULogger::setLevel(ULogger::kDebug);
			continue;
		}
		if(strcmp(argv[i], "-hide") == 0)
		{
			show = false;
			continue;
		}
		if(strcmp(argv[i], "-openni") == 0)
		{
			openni = true;
			continue;
		}

		printf("Unrecognized option : %s\n", argv[i]);
		showUsage();
	}
	fileName = argv[argc-1]; // the last is the output path

	if(UFile::getExtension(fileName.toStdString()).compare("db") != 0)
	{
		printf("Database names must end with .db extension\n");
		showUsage();
	}

	UINFO("Output = %s", fileName.toStdString().c_str());
	UINFO("Show = %s", show?"true":"false");
	UINFO("Openni = %s", openni?"true":"false");
	UINFO("Rate =%f Hz", rate);

	app = new QApplication(argc, argv);

	// Catch ctrl-c to close the gui
	// (Place this after QApplication's constructor)
	signal(SIGABRT, &sighandler);
	signal(SIGTERM, &sighandler);
	signal(SIGINT, &sighandler);

	if(openni)
	{
		cam = new rtabmap::CameraThread(new rtabmap::CameraOpenni("", rate, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)));
	}
	else
	{
		cam = new rtabmap::CameraThread(new rtabmap::CameraVideo(0, rate));
	}

	DataRecorder recorder;

	if(recorder.init(fileName))
	{
		recorder.registerToEventsManager();
		if(show)
		{
			recorder.setWindowTitle("Cloud viewer");
			recorder.setMinimumWidth(500);
			recorder.setMinimumHeight(300);
			recorder.showNormal();
			app->processEvents();
		}

		if(cam->init())
		{
			cam->start();

			app->exec();

			UINFO("Closing...");

			recorder.close();
		}
		else
		{
			UERROR("Cannot initialize the camera!");
		}
	}
	else
	{
		UERROR("Cannot initialize the recorder! Maybe the path is wrong: \"%s\"", fileName.toStdString().c_str());
	}

	if(cam)
	{
		delete cam;
	}

	return 0;
}
<commit_msg>added openni2 option to dataRecorder app<commit_after>
#include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UFile.h>
#include <rtabmap/core/CameraThread.h>
#include <rtabmap/core/CameraRGBD.h>
#include <rtabmap/core/Camera.h>
#include <rtabmap/core/CameraThread.h>
#include <rtabmap/gui/DataRecorder.h>
#include <QtGui/QApplication>
#include <signal.h>

using namespace rtabmap;

void showUsage()
{
	printf("\nUsage:\n"
			"dataRecorder [options] output.db\n"
			"Options:\n"
			"  -hide                    Don't display the current cloud recorded.\n"
			"  -debug                   Set debug level for the logger.\n"
			"  -rate #.#                Input rate Hz (default 0=inf)\n"
			"  -openni                  Use openni camera instead of the usb camera.\n"
			"  -openni2                 Use openni2 camera instead of the usb camera.\n");
	exit(1);
}

rtabmap::CameraThread * cam = 0;
QApplication * app = 0;
// catch ctrl-c
void sighandler(int sig)
{
	printf("\nSignal %d caught...\n", sig);
	if(cam)
	{
		cam->join(true);
	}
	if(app)
	{
		QMetaObject::invokeMethod(app, "quit");
	}
}

int main (int argc, char * argv[])
{
	ULogger::setType(ULogger::kTypeConsole);
	ULogger::setLevel(ULogger::kInfo);

	// parse arguments
	QString fileName;
	bool show = true;
	bool openni = false;
	bool openni2 = false;
	float rate = 0.0f;

	if(argc < 2)
	{
		showUsage();
	}
	for(int i=1; i<argc-1; ++i)
	{
		if(strcmp(argv[i], "-rate") == 0)
		{
			++i;
			if(i < argc)
			{
				rate = std::atof(argv[i]);
				if(rate < 0.0f)
				{
					showUsage();
				}
			}
			else
			{
				showUsage();
			}
			continue;
		}
		if(strcmp(argv[i], "-debug") == 0)
		{
			ULogger::setLevel(ULogger::kDebug);
			continue;
		}
		if(strcmp(argv[i], "-hide") == 0)
		{
			show = false;
			continue;
		}
		if(strcmp(argv[i], "-openni") == 0)
		{
			openni = true;
			continue;
		}
		if(strcmp(argv[i], "-openni2") == 0)
		{
			openni2 = true;
			continue;
		}

		printf("Unrecognized option : %s\n", argv[i]);
		showUsage();
	}
	fileName = argv[argc-1]; // the last is the output path

	if(UFile::getExtension(fileName.toStdString()).compare("db") != 0)
	{
		printf("Database names must end with .db extension\n");
		showUsage();
	}

	UINFO("Output = %s", fileName.toStdString().c_str());
	UINFO("Show = %s", show?"true":"false");
	UINFO("Openni = %s", openni?"true":"false");
	UINFO("Rate =%f Hz", rate);

	app = new QApplication(argc, argv);

	// Catch ctrl-c to close the gui
	// (Place this after QApplication's constructor)
	signal(SIGABRT, &sighandler);
	signal(SIGTERM, &sighandler);
	signal(SIGINT, &sighandler);

	if(openni2)
	{
		cam = new rtabmap::CameraThread(new rtabmap::CameraOpenNI2(rate, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)));
	}
	else if(openni)
	{
		cam = new rtabmap::CameraThread(new rtabmap::CameraOpenni("", rate, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)));
	}
	else
	{
		cam = new rtabmap::CameraThread(new rtabmap::CameraVideo(0, rate));
	}

	DataRecorder recorder;

	if(recorder.init(fileName))
	{
		recorder.registerToEventsManager();
		if(show)
		{
			recorder.setWindowTitle("Cloud viewer");
			recorder.setMinimumWidth(500);
			recorder.setMinimumHeight(300);
			recorder.showNormal();
			app->processEvents();
		}

		if(cam->init())
		{
			cam->start();

			app->exec();

			UINFO("Closing...");

			recorder.close();
		}
		else
		{
			UERROR("Cannot initialize the camera!");
		}
	}
	else
	{
		UERROR("Cannot initialize the recorder! Maybe the path is wrong: \"%s\"", fileName.toStdString().c_str());
	}

	if(cam)
	{
		delete cam;
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <set>
#include <string>
#include <sstream>

#include <cmath>

#include "filtrations/Data.hh"

#include "geometry/RipsExpander.hh"

#include "persistentHomology/ConnectedComponents.hh"

#include "topology/CliqueGraph.hh"
#include "topology/ConnectedComponents.hh"
#include "topology/Simplex.hh"
#include "topology/SimplicialComplex.hh"

#include "topology/io/EdgeLists.hh"
#include "topology/io/GML.hh"

#include "utilities/Filesystem.hh"

using DataType           = double;
using VertexType         = unsigned;
using Simplex            = aleph::topology::Simplex<DataType, VertexType>;
using SimplicialComplex  = aleph::topology::SimplicialComplex<Simplex>;

template <class Simplex> std::string formatSimplex( const Simplex& s )
{
  std::ostringstream stream;
  stream << "{";

  for( auto it = s.begin(); it != s.end(); ++it )
  {
    if( it != s.begin() )
      stream << ",";
    stream << *it;
  }

  stream << "}";

  return stream.str();
}

int main( int argc, char** argv )
{
  if( argc <= 2 )
  {
    // TODO: Show usage
    return -1;
  }

  std::string filename = argv[1];
  double threshold     = std::stod( argv[2] );

  SimplicialComplex K;

  // Input -------------------------------------------------------------
  //
  // TODO: This is copied from the clique persistence diagram
  // calculation. It would make sense to share some functions
  // between the two applications.

  std::cerr << "* Reading '" << filename << "'...";

  if( aleph::utilities::extension( filename ) == ".gml" )
  {
    aleph::topology::io::GMLReader reader;
    reader( filename, K );
  }
  else
  {
    aleph::io::EdgeListReader reader;
    reader.setReadWeights( true );
    reader.setTrimLines( true );

    reader( filename, K );
  }

  std::cerr << "finished\n";

  // Thresholding ------------------------------------------------------

  {
    std::cerr << "* Filtering input data to threshold epsilon=" << threshold << "...";

    std::vector<Simplex> simplices;

    std::remove_copy_if( K.begin(), K.end(), std::back_inserter( simplices ),
                         [&threshold] ( const Simplex& s )
                         {
                           return s.data() > threshold;
                         } );

    K = SimplicialComplex( simplices.begin(), simplices.end() );

    std::cerr << "finished\n";
  }

  // Expansion ---------------------------------------------------------

  unsigned maxK = 12;

  aleph::geometry::RipsExpander<SimplicialComplex> ripsExpander;
  K = ripsExpander( K, maxK );
  K = ripsExpander.assignMaximumWeight( K );

  K.sort( aleph::filtrations::Data<Simplex>() );

  for( unsigned k = 1; k <= maxK; k++ )
  {
    std::cerr << "* Extracting " << k << "-cliques graph...";

    auto C
        = aleph::topology::getCliqueGraph( K, k );

    C.sort( aleph::filtrations::Data<Simplex>() );

    std::cerr << "finished\n";

    std::cerr << "* " << k << "-cliques graph has " << C.size() << " simplices\n";

    auto uf = aleph::topology::calculateConnectedComponents( C );

    std::set<VertexType> roots;
    uf.roots( std::inserter( roots, roots.begin() ) );

    std::cerr << "* " << k << "-cliques graph has " << roots.size() << " connected components\n";

    for( auto&& root : roots )
    {
      // The vertex IDs stored in the Union--Find data structure
      // correspond to the indices of the simplicial complex. It
      // thus suffices to map them back.
      std::set<VertexType> vertices;
      uf.get( root, std::inserter( vertices, vertices.begin() ) );

      std::vector<Simplex> simplices;

      std::transform( vertices.begin(), vertices.end(), std::back_inserter( simplices ),
                      [&K] ( VertexType v )
                      {
                        return K.at(v);
                      } );

      std::sort( simplices.begin(), simplices.end() );

      std::cout << "[";

      for( auto it = simplices.begin(); it != simplices.end(); ++it )
      {
        if( it != simplices.begin() )
          std::cout << ",";

        std::cout << formatSimplex( *it );
      }

      std::cout << "]\n";
    }

    std::cout << "\n\n";
  }
}
<commit_msg>Added usage information & maximum k parameter<commit_after>#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <set>
#include <string>
#include <sstream>

#include <cmath>

#include "filtrations/Data.hh"

#include "geometry/RipsExpander.hh"

#include "persistentHomology/ConnectedComponents.hh"

#include "topology/CliqueGraph.hh"
#include "topology/ConnectedComponents.hh"
#include "topology/Simplex.hh"
#include "topology/SimplicialComplex.hh"

#include "topology/io/EdgeLists.hh"
#include "topology/io/GML.hh"

#include "utilities/Filesystem.hh"

using DataType           = double;
using VertexType         = unsigned;
using Simplex            = aleph::topology::Simplex<DataType, VertexType>;
using SimplicialComplex  = aleph::topology::SimplicialComplex<Simplex>;

template <class Simplex> std::string formatSimplex( const Simplex& s )
{
  std::ostringstream stream;
  stream << "{";

  for( auto it = s.begin(); it != s.end(); ++it )
  {
    if( it != s.begin() )
      stream << ",";
    stream << *it;
  }

  stream << "}";

  return stream.str();
}

void usage()
{
  std::cerr << "Usage: clique_communities FILE THRESHOLD K\n"
            << "\n"
            << "Extracts clique communities from FILE, which is supposed to be\n"
            << "a weighted graph. In the subsequent calculation, an edge whose\n"
            << "weight is larger than THRESHOLD will be ignored. K denotes the\n"
            << "maximum dimension of a simplex for the clique graph extraction\n"
            << "and the clique community calculation. This does not correspond\n"
            << "to the dimensionality of the clique. Hence, a parameter of K=2\n"
            << "will result in calculating 3-clique communities because all of\n"
            << "the 2-simplices have 3 vertices.\n\n";
}

int main( int argc, char** argv )
{
  if( argc <= 3 )
  {
    usage();
    return -1;
  }

  std::string filename = argv[1];
  double threshold     = std::stod( argv[2] );
  unsigned maxK        = static_cast<unsigned>( std::stoul( argv[3] ) );

  SimplicialComplex K;

  // Input -------------------------------------------------------------
  //
  // TODO: This is copied from the clique persistence diagram
  // calculation. It would make sense to share some functions
  // between the two applications.

  std::cerr << "* Reading '" << filename << "'...";

  if( aleph::utilities::extension( filename ) == ".gml" )
  {
    aleph::topology::io::GMLReader reader;
    reader( filename, K );
  }
  else
  {
    aleph::io::EdgeListReader reader;
    reader.setReadWeights( true );
    reader.setTrimLines( true );

    reader( filename, K );
  }

  std::cerr << "finished\n";

  // Thresholding ------------------------------------------------------

  {
    std::cerr << "* Filtering input data to threshold epsilon=" << threshold << "...";

    std::vector<Simplex> simplices;

    std::remove_copy_if( K.begin(), K.end(), std::back_inserter( simplices ),
                         [&threshold] ( const Simplex& s )
                         {
                           return s.data() > threshold;
                         } );

    K = SimplicialComplex( simplices.begin(), simplices.end() );

    std::cerr << "finished\n";
  }

  // Expansion ---------------------------------------------------------

  aleph::geometry::RipsExpander<SimplicialComplex> ripsExpander;
  K = ripsExpander( K, maxK );
  K = ripsExpander.assignMaximumWeight( K );

  K.sort( aleph::filtrations::Data<Simplex>() );

  for( unsigned k = 1; k <= maxK; k++ )
  {
    std::cerr << "* Extracting " << k << "-cliques graph...";

    auto C
        = aleph::topology::getCliqueGraph( K, k );

    C.sort( aleph::filtrations::Data<Simplex>() );

    std::cerr << "finished\n";

    std::cerr << "* " << k << "-cliques graph has " << C.size() << " simplices\n";

    auto uf = aleph::topology::calculateConnectedComponents( C );

    std::set<VertexType> roots;
    uf.roots( std::inserter( roots, roots.begin() ) );

    std::cerr << "* " << k << "-cliques graph has " << roots.size() << " connected components\n";

    for( auto&& root : roots )
    {
      // The vertex IDs stored in the Union--Find data structure
      // correspond to the indices of the simplicial complex. It
      // thus suffices to map them back.
      std::set<VertexType> vertices;
      uf.get( root, std::inserter( vertices, vertices.begin() ) );

      std::vector<Simplex> simplices;

      std::transform( vertices.begin(), vertices.end(), std::back_inserter( simplices ),
                      [&K] ( VertexType v )
                      {
                        return K.at(v);
                      } );

      std::sort( simplices.begin(), simplices.end() );

      std::cout << "[";

      for( auto it = simplices.begin(); it != simplices.end(); ++it )
      {
        if( it != simplices.begin() )
          std::cout << ",";

        std::cout << formatSimplex( *it );
      }

      std::cout << "]\n";
    }

    std::cout << "\n\n";
  }
}
<|endoftext|>