<commit_before>#include "singleton_edge.h"

void siren_edge_install(mrb_state* mrb, RObject* o)
{
  mrb_define_singleton_method(mrb, o, "sp",        siren_edge_sp,        MRB_ARGS_NONE());
  mrb_define_singleton_method(mrb, o, "tp",        siren_edge_tp,        MRB_ARGS_NONE());
  mrb_define_singleton_method(mrb, o, "to_pts",    siren_edge_to_pts,    MRB_ARGS_OPT(1));
  mrb_define_singleton_method(mrb, o, "param",     siren_edge_param,     MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
  mrb_define_singleton_method(mrb, o, "to_xyz",    siren_edge_to_xyz,    MRB_ARGS_REQ(1));
  mrb_define_singleton_method(mrb, o, "curvature", siren_edge_curvature, MRB_ARGS_REQ(1));
  mrb_define_singleton_method(mrb, o, "tangent",   siren_edge_tangent,   MRB_ARGS_REQ(1));
  mrb_define_singleton_method(mrb, o, "nurbs_def", siren_edge_nurbs_def, MRB_ARGS_NONE());
  return;
}

mrb_value siren_edge_sp(mrb_state* mrb, mrb_value self)
{
  TopoDS_Shape* c = siren_shape_get(mrb, self);
  BRepAdaptor_Curve bracurve(TopoDS::Edge(*c));
  gp_Pnt sp = bracurve.Value(bracurve.FirstParameter());
  return siren_vec_new(mrb, sp.X(), sp.Y(), sp.Z());
}

mrb_value siren_edge_tp(mrb_state* mrb, mrb_value self)
{
  TopoDS_Shape* c = siren_shape_get(mrb, self);
  BRepAdaptor_Curve bracurve(TopoDS::Edge(*c));
  gp_Pnt tp = bracurve.Value(bracurve.LastParameter());
  return siren_vec_new(mrb, tp.X(), tp.Y(), tp.Z());
}

mrb_value siren_edge_to_pts(mrb_state* mrb, mrb_value self)
{
  mrb_float deflect;
  int argc = mrb_get_args(mrb, "|f", &deflect);

  TopoDS_Shape* shape = siren_shape_get(mrb, self);

  if (argc != 2) {
    deflect = 1.0e-1;
  }

  mrb_value result = mrb_ary_new(mrb);
  double first_param, last_param;

  TopExp_Explorer exp(*shape, TopAbs_EDGE);
  for(; exp.More(); exp.Next()) {
    TopoDS_Edge edge = TopoDS::Edge(exp.Current());

    BRepAdaptor_Curve adaptor(edge);
    first_param = adaptor.FirstParameter();
    last_param = adaptor.LastParameter();

    GCPnts_UniformDeflection unidef(adaptor, deflect);
    if (!unidef.IsDone()) {
      continue;
    }

    mrb_value line = mrb_ary_new(mrb);

    // first point
    gp_Pnt p = adaptor.Value(first_param);
    mrb_ary_push(mrb, line, siren_vec_new(mrb, p.X(), p.Y(), p.Z()));

    for (int i=1; i<=unidef.NbPoints(); i++) {
      p = unidef.Value(i);
      mrb_ary_push(mrb, line, siren_vec_new(mrb, p.X(), p.Y(), p.Z()));
    }

    // last point
    p = adaptor.Value(last_param);
    mrb_ary_push(mrb, line, siren_vec_new(mrb, p.X(), p.Y(), p.Z()));

    mrb_ary_push(mrb, result, line);
  }

  return result;
}

mrb_value siren_edge_param(mrb_state* mrb, mrb_value self)
{
  mrb_value xyz;
  mrb_float tol;
  int argc = mrb_get_args(mrb, "A|f", &xyz, &tol);

  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  TopoDS_Edge edge = TopoDS::Edge(*shape);

  ShapeAnalysis_Curve ana;
  BRepAdaptor_Curve gcurve(edge);
  gp_Pnt p = siren_ary_to_pnt(mrb, xyz);
  gp_Pnt pp;
  Standard_Real param;
  Standard_Real distance = ana.Project(gcurve, p, tol, pp, param);

  if (fabs(distance) > tol) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Specified position is not on the edge.");
  }

  return mrb_float_value(mrb, param);
}

mrb_value siren_edge_to_xyz(mrb_state* mrb, mrb_value self)
{
  mrb_float param;
  int argc = mrb_get_args(mrb, "f", &param);
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  BRepAdaptor_Curve C(TopoDS::Edge(*shape));
  gp_Pnt p;
  gp_Vec v1, v2;
  C.D2(param, p, v1, v2);
  return siren_vec_new(mrb, p.X(), p.Y(), p.Z());
}

mrb_value siren_edge_curvature(mrb_state* mrb, mrb_value self)
{
  mrb_float param;
  int argc = mrb_get_args(mrb, "f", &param);
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  BRepAdaptor_Curve C(TopoDS::Edge(*shape));
  gp_Pnt p;
  gp_Vec v1, v2;
  C.D2(param, p, v1, v2);
  return siren_vec_new(mrb, v2.X(), v2.Y(), v2.Z());
}

mrb_value siren_edge_tangent(mrb_state* mrb, mrb_value self)
{
  mrb_float param;
  int argc = mrb_get_args(mrb, "f", &param);
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  BRepAdaptor_Curve C(TopoDS::Edge(*shape));
  gp_Pnt p;
  gp_Vec v1, v2;
  C.D2(param, p, v1, v2);
  return siren_vec_new(mrb, v1.X(), v1.Y(), v1.Z());
}

mrb_value siren_edge_nurbs_def(mrb_state* mrb, mrb_value self)
{
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  TopoDS_Edge edge = TopoDS::Edge(*shape);
  Standard_Real first, last;
  Handle(Geom_Curve) hgcurve = BRep_Tool::Curve(edge, first, last);
#if 0
  Handle(Geom_TrimmedCurve) hgtc = new Geom_TrimmedCurve(hgcurve, first, last);
  Handle(Geom_BSplineCurve) hgbc = Handle(Geom_BSplineCurve)::DownCast(hgtc->BasisCurve());
#else
  Handle(Geom_BSplineCurve) hgbc = Handle(Geom_BSplineCurve)::DownCast(hgcurve);
#endif
  if (hgbc.IsNull()) {
    // Failed to downcast to BSplineCurve
    return mrb_nil_value();
  }
  mrb_value res = mrb_ary_new(mrb);
  // degree
  mrb_ary_push(mrb, res, mrb_fixnum_value((int)hgbc->Degree()));
  // knots
  mrb_value knots = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbKnots(); i++) {
    mrb_ary_push(mrb, knots, mrb_float_value(mrb, hgbc->Knot(i)));
  }
  mrb_ary_push(mrb, res, knots);
  // mults
  mrb_value mults = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbKnots(); i++) {
    mrb_ary_push(mrb, mults, mrb_fixnum_value(hgbc->Multiplicity(i)));
  }
  mrb_ary_push(mrb, res, mults);
  // poles
  mrb_value poles = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbPoles(); i++) {
    mrb_ary_push(mrb, poles, siren_vec_new(mrb, hgbc->Pole(i).X(), hgbc->Pole(i).Y(), hgbc->Pole(i).Z()));
  }
  mrb_ary_push(mrb, res, poles);
  // weights
  mrb_value weights = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbPoles(); i++) {
    mrb_ary_push(mrb, weights, mrb_float_value(mrb, hgbc->Weight(i)));
  }
  mrb_ary_push(mrb, res, weights);
  // params
  mrb_ary_push(mrb, res, mrb_float_value(mrb, first));
  mrb_ary_push(mrb, res, mrb_float_value(mrb, last));
  return res;
}

<commit_msg>Fix bug of argument check.<commit_after>#include "singleton_edge.h"

void siren_edge_install(mrb_state* mrb, RObject* o)
{
  mrb_define_singleton_method(mrb, o, "sp",        siren_edge_sp,        MRB_ARGS_NONE());
  mrb_define_singleton_method(mrb, o, "tp",        siren_edge_tp,        MRB_ARGS_NONE());
  mrb_define_singleton_method(mrb, o, "to_pts",    siren_edge_to_pts,    MRB_ARGS_OPT(1));
  mrb_define_singleton_method(mrb, o, "param",     siren_edge_param,     MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
  mrb_define_singleton_method(mrb, o, "to_xyz",    siren_edge_to_xyz,    MRB_ARGS_REQ(1));
  mrb_define_singleton_method(mrb, o, "curvature", siren_edge_curvature, MRB_ARGS_REQ(1));
  mrb_define_singleton_method(mrb, o, "tangent",   siren_edge_tangent,   MRB_ARGS_REQ(1));
  mrb_define_singleton_method(mrb, o, "nurbs_def", siren_edge_nurbs_def, MRB_ARGS_NONE());
  return;
}

mrb_value siren_edge_sp(mrb_state* mrb, mrb_value self)
{
  TopoDS_Shape* c = siren_shape_get(mrb, self);
  BRepAdaptor_Curve bracurve(TopoDS::Edge(*c));
  gp_Pnt sp = bracurve.Value(bracurve.FirstParameter());
  return siren_vec_new(mrb, sp.X(), sp.Y(), sp.Z());
}

mrb_value siren_edge_tp(mrb_state* mrb, mrb_value self)
{
  TopoDS_Shape* c = siren_shape_get(mrb, self);
  BRepAdaptor_Curve bracurve(TopoDS::Edge(*c));
  gp_Pnt tp = bracurve.Value(bracurve.LastParameter());
  return siren_vec_new(mrb, tp.X(), tp.Y(), tp.Z());
}

mrb_value siren_edge_to_pts(mrb_state* mrb, mrb_value self)
{
  mrb_float deflect;
  int argc = mrb_get_args(mrb, "|f", &deflect);

  TopoDS_Shape* shape = siren_shape_get(mrb, self);

  if (argc != 1) {
    deflect = 1.0e-1;
  }

  mrb_value result = mrb_ary_new(mrb);
  double first_param, last_param;

  TopExp_Explorer exp(*shape, TopAbs_EDGE);
  for(; exp.More(); exp.Next()) {
    TopoDS_Edge edge = TopoDS::Edge(exp.Current());

    BRepAdaptor_Curve adaptor(edge);
    first_param = adaptor.FirstParameter();
    last_param = adaptor.LastParameter();

    GCPnts_UniformDeflection unidef(adaptor, deflect);
    if (!unidef.IsDone()) {
      continue;
    }

    mrb_value line = mrb_ary_new(mrb);

    // first point
    gp_Pnt p = adaptor.Value(first_param);
    mrb_ary_push(mrb, line, siren_vec_new(mrb, p.X(), p.Y(), p.Z()));

    for (int i=1; i<=unidef.NbPoints(); i++) {
      p = unidef.Value(i);
      mrb_ary_push(mrb, line, siren_vec_new(mrb, p.X(), p.Y(), p.Z()));
    }

    // last point
    p = adaptor.Value(last_param);
    mrb_ary_push(mrb, line, siren_vec_new(mrb, p.X(), p.Y(), p.Z()));

    mrb_ary_push(mrb, result, line);
  }

  return result;
}

mrb_value siren_edge_param(mrb_state* mrb, mrb_value self)
{
  mrb_value xyz;
  mrb_float tol;
  int argc = mrb_get_args(mrb, "A|f", &xyz, &tol);

  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  TopoDS_Edge edge = TopoDS::Edge(*shape);

  ShapeAnalysis_Curve ana;
  BRepAdaptor_Curve gcurve(edge);
  gp_Pnt p = siren_ary_to_pnt(mrb, xyz);
  gp_Pnt pp;
  Standard_Real param;
  Standard_Real distance = ana.Project(gcurve, p, tol, pp, param);

  if (fabs(distance) > tol) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Specified position is not on the edge.");
  }

  return mrb_float_value(mrb, param);
}

mrb_value siren_edge_to_xyz(mrb_state* mrb, mrb_value self)
{
  mrb_float param;
  int argc = mrb_get_args(mrb, "f", &param);
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  BRepAdaptor_Curve C(TopoDS::Edge(*shape));
  gp_Pnt p;
  gp_Vec v1, v2;
  C.D2(param, p, v1, v2);
  return siren_vec_new(mrb, p.X(), p.Y(), p.Z());
}

mrb_value siren_edge_curvature(mrb_state* mrb, mrb_value self)
{
  mrb_float param;
  int argc = mrb_get_args(mrb, "f", &param);
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  BRepAdaptor_Curve C(TopoDS::Edge(*shape));
  gp_Pnt p;
  gp_Vec v1, v2;
  C.D2(param, p, v1, v2);
  return siren_vec_new(mrb, v2.X(), v2.Y(), v2.Z());
}

mrb_value siren_edge_tangent(mrb_state* mrb, mrb_value self)
{
  mrb_float param;
  int argc = mrb_get_args(mrb, "f", &param);
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  BRepAdaptor_Curve C(TopoDS::Edge(*shape));
  gp_Pnt p;
  gp_Vec v1, v2;
  C.D2(param, p, v1, v2);
  return siren_vec_new(mrb, v1.X(), v1.Y(), v1.Z());
}

mrb_value siren_edge_nurbs_def(mrb_state* mrb, mrb_value self)
{
  TopoDS_Shape* shape = siren_shape_get(mrb, self);
  TopoDS_Edge edge = TopoDS::Edge(*shape);
  Standard_Real first, last;
  Handle(Geom_Curve) hgcurve = BRep_Tool::Curve(edge, first, last);
#if 0
  Handle(Geom_TrimmedCurve) hgtc = new Geom_TrimmedCurve(hgcurve, first, last);
  Handle(Geom_BSplineCurve) hgbc = Handle(Geom_BSplineCurve)::DownCast(hgtc->BasisCurve());
#else
  Handle(Geom_BSplineCurve) hgbc = Handle(Geom_BSplineCurve)::DownCast(hgcurve);
#endif
  if (hgbc.IsNull()) {
    // Failed to downcast to BSplineCurve
    return mrb_nil_value();
  }
  mrb_value res = mrb_ary_new(mrb);
  // degree
  mrb_ary_push(mrb, res, mrb_fixnum_value((int)hgbc->Degree()));
  // knots
  mrb_value knots = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbKnots(); i++) {
    mrb_ary_push(mrb, knots, mrb_float_value(mrb, hgbc->Knot(i)));
  }
  mrb_ary_push(mrb, res, knots);
  // mults
  mrb_value mults = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbKnots(); i++) {
    mrb_ary_push(mrb, mults, mrb_fixnum_value(hgbc->Multiplicity(i)));
  }
  mrb_ary_push(mrb, res, mults);
  // poles
  mrb_value poles = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbPoles(); i++) {
    mrb_ary_push(mrb, poles, siren_vec_new(mrb, hgbc->Pole(i).X(), hgbc->Pole(i).Y(), hgbc->Pole(i).Z()));
  }
  mrb_ary_push(mrb, res, poles);
  // weights
  mrb_value weights = mrb_ary_new(mrb);
  for (int i=1; i <= hgbc->NbPoles(); i++) {
    mrb_ary_push(mrb, weights, mrb_float_value(mrb, hgbc->Weight(i)));
  }
  mrb_ary_push(mrb, res, weights);
  // params
  mrb_ary_push(mrb, res, mrb_float_value(mrb, first));
  mrb_ary_push(mrb, res, mrb_float_value(mrb, last));
  return res;
}

<|endoftext|>


<commit_before>#include <babylon/cameras/arc_rotate_camera.h>
#include <babylon/core/random.h>
#include <babylon/engines/scene.h>
#include <babylon/interfaces/irenderable_scene.h>
#include <babylon/lights/point_light.h>
#include <babylon/materials/standard_material.h>
#include <babylon/maths/vector3.h>
#include <babylon/meshes/builders/mesh_builder_options.h>
#include <babylon/meshes/instanced_mesh.h>
#include <babylon/meshes/mesh.h>
#include <babylon/meshes/mesh_builder.h>
#include <babylon/samples/babylon_register_sample.h>

namespace BABYLON {

class AbstractMesh;
class Mesh;
using AbstractMeshPtr = std::shared_ptr<AbstractMesh>;
using MeshPtr         = std::shared_ptr<Mesh>;

namespace Samples {

/**
 * @brief Bouncing Cube Scene.
 *
 * In this simple example, you've got :
 * - a finite world defined by the big box
 * - some random platforms inside it, built with instances
 * - a Mario player, the tiny red box
 *
 * Mario is given an initial random velocity and applied a constant gravity. You can tweak the
 * energy loss against the box walls with the variable restitution (here : 100% = 1.0)
 *
 * When Mario hits a platform coming downward (he's above the platform), he bounces back with some
 * energy loss (variable platformBounceRestitution), when he hits the platform under it, he's just
 * rejected. This is a very simple and naive physics engine because I don't even test if Mario hits
 * the platform borders here. But it is fast.
 *
 * Note that I also test all the platforms what is not performant at all (well, they aren't very
 * numerous). The use of an octree or any preselection (we know where all the obstacles are in the
 * space before the scene starts !) would be better.
 *
 * @see http://www.babylonjs-playground.com/#PBVEM#17
 */
class BouncingCubeScene : public IRenderableScene {

public:
  BouncingCubeScene(ICanvas* iCanvas)
      : IRenderableScene(iCanvas)
      , _limit{0.f}
      , _restitution{0.f}
      , _platformBounceRestitution{0.f}
      , _k{0.f}
      , _mario{nullptr}
  {
  }
  ~BouncingCubeScene() override = default;

  const char* getName() override
  {
    return "Bouncing Cube Scene";
  }
  void initializeScene(ICanvas* canvas, Scene* scene) override
  {
    scene->clearColor = Color3::Black();
    auto camera       = ArcRotateCamera::New("camera1", 0.f, 0.f, 0.f, Vector3::Zero(), scene);
    camera->setPosition(Vector3(0.f, 10.f, -500.f));
    camera->attachControl(canvas, true);

    auto pl       = PointLight::New("pl", Vector3::Zero(), scene);
    pl->diffuse   = Color3(1.f, 1.f, 1.f);
    pl->intensity = 1.f;
    pl->position  = camera->position;

    auto boxSize               = 300.f;
    auto marioSize             = 5.f;
    auto platformNb            = 25;
    auto platformHeight        = 3.f;
    auto platformMaxWidth      = 40.f;
    auto platformMaxDepth      = 20.f;
    auto platformMinSize       = 20.f;
    _gravity                   = Vector3(0.f, -0.2f, 0.f);
    _platformBounceRestitution = 0.97f;
    auto speed                 = 2.f;
    _restitution               = 0.95f;
    _limit                     = (boxSize - marioSize) * 0.5f;
    auto platformLimit         = boxSize - platformMaxWidth - 10.f;
    _velocity                  = Vector3(Math::random(), Math::random(), Math::random());
    _velocity.scaleInPlace(speed);
    auto initialVel = Vector3(0.5f, 2.f, 0.f);
    _velocity.addInPlace(initialVel);

    BoxOptions boxOptions;
    boxOptions.size            = boxSize;
    boxOptions.sideOrientation = Mesh::BACKSIDE;
    auto box                   = MeshBuilder::CreateBox("b", boxOptions, scene);
    auto boxmat                = StandardMaterial::New("boxmat", scene);
    boxmat->diffuseColor       = Color3(0.4f, 0.6f, 1.f);
    boxmat->specularColor      = Color3::Black();
    box->material              = boxmat;

    BoxOptions marioOptions;
    marioOptions.size       = marioSize;
    _mario                  = MeshBuilder::CreateBox("m", marioOptions, scene);
    auto marioMat           = StandardMaterial::New("marioMat", scene);
    marioMat->diffuseColor  = Color3::Red();
    marioMat->specularColor = Color3::Black();
    _mario->material        = marioMat;

    BoxOptions platformOptions;
    platformOptions.size       = 1.f;
    auto platform              = MeshBuilder::CreateBox("p", platformOptions, scene);
    auto platformMat           = StandardMaterial::New("platform0", scene);
    platformMat->diffuseColor  = Color3::Green();
    platformMat->specularColor = Color3::Black();
    platformMat->alpha         = 0.7f;
    platform->material         = platformMat;
    platform->position
      = Vector3((0.5f - Math::random()) * platformLimit, (0.5f - Math::random()) * platformLimit,
                (0.5f - Math::random()) * platformLimit);
    platform->scaling = Vector3(platformMinSize + platformMaxWidth * Math::random(), platformHeight,
                                platformMinSize + Math::random() * platformMaxDepth);

    _platforms.emplace_back(platform);
    for (int i = 1; i < platformNb; ++i) {
      const auto instance = platform->createInstance("platform" + std::to_string(i));
      instance->position
        = Vector3((0.5f - Math::random()) * platformLimit, (0.5f - Math::random()) * platformLimit,
                  (0.5f - Math::random()) * platformLimit);
      platform->scaling
        = Vector3(platformMinSize + platformMaxWidth * Math::random(), platformHeight,
                  platformMinSize + Math::random() * platformMaxDepth);
      _platforms.emplace_back(instance);
    }

    scene->registerBeforeRender([this](Scene* /*scene*/, EventState& /*es*/) {
      _applyForces();
      _checkCollisions();
      _moveMario();
      _movePlatforms();
      _k += 0.001f;
    });
  }

private:
  void _applyForces();
  void _checkCollisions();
  void _moveMario();
  void _movePlatforms();

private:
  Vector3 _gravity;
  Vector3 _velocity;
  float _limit;
  float _restitution;
  float _platformBounceRestitution;
  float _k;
  MeshPtr _mario;
  std::vector<AbstractMeshPtr> _platforms;

}; // end of class BouncingCubeScene

} // end of namespace Samples
} // end of namespace BABYLON

namespace BABYLON {
namespace Samples {

void BouncingCubeScene::_applyForces()
{
  _velocity.addInPlace(_gravity);
}

void BouncingCubeScene::_checkCollisions()
{
  // Check box walls
  if (std::abs(_mario->position().x) > _limit) {
    _velocity.x *= -1.f;
    _mario->position().x = (_mario->position().x > 0.f) ? _limit : -_limit;
  }
  if (std::abs(_mario->position().y) > _limit) {
    _velocity.y *= -1.f * _restitution;
    _mario->position().y = (_mario->position().y > 0.f) ? _limit : -_limit;
  }
  if (std::abs(_mario->position().z) > _limit) {
    _velocity.z *= -1.f;
    _mario->position().z = (_mario->position().z > 0.f) ? _limit : -_limit;
  }
  // Check platforms
  size_t i = 0;
  for (auto& platform : _platforms) {
    if (_mario->intersectsMesh(*platform)) {
      // naive impact point check
      if (_mario->position().y > platform->position().y) {
        _mario->position().y = platform->position().y + platform->scaling().y * 0.5f;
        _velocity.y *= -_platformBounceRestitution;
      }
      if (_mario->position().y < platform->position().y) {
        _velocity.y *= -1.f;
      }
    }
    ++i;
  }
}

void BouncingCubeScene::_moveMario()
{
  _mario->position().addInPlace(_velocity);
}

void BouncingCubeScene::_movePlatforms()
{
  size_t i = 0;
  for (auto& platform : _platforms) {
    auto p = i % 3;
    switch (p) {
      case 0:
        platform->position().x += 0.1f * std::sin(_k * i);
        break;
      case 1:
        platform->position().y -= 0.2f * std::cos(_k * i);
        break;
      case 2:
        platform->position().z -= 0.03f * std::sin(_k * i);
        break;
    }
    ++i;
  }
}

BABYLON_REGISTER_SAMPLE("Animations", BouncingCubeScene)

} // end of namespace Samples
} // end of namespace BABYLON
<commit_msg>Added lambda return type<commit_after>#include <babylon/cameras/arc_rotate_camera.h>
#include <babylon/core/random.h>
#include <babylon/engines/scene.h>
#include <babylon/interfaces/irenderable_scene.h>
#include <babylon/lights/point_light.h>
#include <babylon/materials/standard_material.h>
#include <babylon/maths/vector3.h>
#include <babylon/meshes/builders/mesh_builder_options.h>
#include <babylon/meshes/instanced_mesh.h>
#include <babylon/meshes/mesh.h>
#include <babylon/meshes/mesh_builder.h>
#include <babylon/samples/babylon_register_sample.h>

namespace BABYLON {

class AbstractMesh;
class Mesh;
using AbstractMeshPtr = std::shared_ptr<AbstractMesh>;
using MeshPtr         = std::shared_ptr<Mesh>;

namespace Samples {

/**
 * @brief Bouncing Cube Scene.
 *
 * In this simple example, you've got :
 * - a finite world defined by the big box
 * - some random platforms inside it, built with instances
 * - a Mario player, the tiny red box
 *
 * Mario is given an initial random velocity and applied a constant gravity. You can tweak the
 * energy loss against the box walls with the variable restitution (here : 100% = 1.0)
 *
 * When Mario hits a platform coming downward (he's above the platform), he bounces back with some
 * energy loss (variable platformBounceRestitution), when he hits the platform under it, he's just
 * rejected. This is a very simple and naive physics engine because I don't even test if Mario hits
 * the platform borders here. But it is fast.
 *
 * Note that I also test all the platforms what is not performant at all (well, they aren't very
 * numerous). The use of an octree or any preselection (we know where all the obstacles are in the
 * space before the scene starts !) would be better.
 *
 * @see http://www.babylonjs-playground.com/#PBVEM#17
 */
class BouncingCubeScene : public IRenderableScene {

public:
  BouncingCubeScene(ICanvas* iCanvas)
      : IRenderableScene(iCanvas)
      , _limit{0.f}
      , _restitution{0.f}
      , _platformBounceRestitution{0.f}
      , _k{0.f}
      , _mario{nullptr}
  {
  }
  ~BouncingCubeScene() override = default;

  const char* getName() override
  {
    return "Bouncing Cube Scene";
  }
  void initializeScene(ICanvas* canvas, Scene* scene) override
  {
    scene->clearColor = Color3::Black();
    auto camera       = ArcRotateCamera::New("camera1", 0.f, 0.f, 0.f, Vector3::Zero(), scene);
    camera->setPosition(Vector3(0.f, 10.f, -500.f));
    camera->attachControl(canvas, true);

    auto pl       = PointLight::New("pl", Vector3::Zero(), scene);
    pl->diffuse   = Color3(1.f, 1.f, 1.f);
    pl->intensity = 1.f;
    pl->position  = camera->position;

    auto boxSize               = 300.f;
    auto marioSize             = 5.f;
    auto platformNb            = 25;
    auto platformHeight        = 3.f;
    auto platformMaxWidth      = 40.f;
    auto platformMaxDepth      = 20.f;
    auto platformMinSize       = 20.f;
    _gravity                   = Vector3(0.f, -0.2f, 0.f);
    _platformBounceRestitution = 0.97f;
    auto speed                 = 2.f;
    _restitution               = 0.95f;
    _limit                     = (boxSize - marioSize) * 0.5f;
    auto platformLimit         = boxSize - platformMaxWidth - 10.f;
    _velocity                  = Vector3(Math::random(), Math::random(), Math::random());
    _velocity.scaleInPlace(speed);
    auto initialVel = Vector3(0.5f, 2.f, 0.f);
    _velocity.addInPlace(initialVel);

    BoxOptions boxOptions;
    boxOptions.size            = boxSize;
    boxOptions.sideOrientation = Mesh::BACKSIDE;
    auto box                   = MeshBuilder::CreateBox("b", boxOptions, scene);
    auto boxmat                = StandardMaterial::New("boxmat", scene);
    boxmat->diffuseColor       = Color3(0.4f, 0.6f, 1.f);
    boxmat->specularColor      = Color3::Black();
    box->material              = boxmat;

    BoxOptions marioOptions;
    marioOptions.size       = marioSize;
    _mario                  = MeshBuilder::CreateBox("m", marioOptions, scene);
    auto marioMat           = StandardMaterial::New("marioMat", scene);
    marioMat->diffuseColor  = Color3::Red();
    marioMat->specularColor = Color3::Black();
    _mario->material        = marioMat;

    BoxOptions platformOptions;
    platformOptions.size       = 1.f;
    auto platform              = MeshBuilder::CreateBox("p", platformOptions, scene);
    auto platformMat           = StandardMaterial::New("platform0", scene);
    platformMat->diffuseColor  = Color3::Green();
    platformMat->specularColor = Color3::Black();
    platformMat->alpha         = 0.7f;
    platform->material         = platformMat;
    platform->position
      = Vector3((0.5f - Math::random()) * platformLimit, (0.5f - Math::random()) * platformLimit,
                (0.5f - Math::random()) * platformLimit);
    platform->scaling = Vector3(platformMinSize + platformMaxWidth * Math::random(), platformHeight,
                                platformMinSize + Math::random() * platformMaxDepth);

    _platforms.emplace_back(platform);
    for (int i = 1; i < platformNb; ++i) {
      const auto instance = platform->createInstance("platform" + std::to_string(i));
      instance->position
        = Vector3((0.5f - Math::random()) * platformLimit, (0.5f - Math::random()) * platformLimit,
                  (0.5f - Math::random()) * platformLimit);
      platform->scaling
        = Vector3(platformMinSize + platformMaxWidth * Math::random(), platformHeight,
                  platformMinSize + Math::random() * platformMaxDepth);
      _platforms.emplace_back(instance);
    }

    scene->registerBeforeRender([this](Scene* /*scene*/, EventState& /*es*/) -> void {
      _applyForces();
      _checkCollisions();
      _moveMario();
      _movePlatforms();
      _k += 0.001f;
    });
  }

private:
  void _applyForces();
  void _checkCollisions();
  void _moveMario();
  void _movePlatforms();

private:
  Vector3 _gravity;
  Vector3 _velocity;
  float _limit;
  float _restitution;
  float _platformBounceRestitution;
  float _k;
  MeshPtr _mario;
  std::vector<AbstractMeshPtr> _platforms;

}; // end of class BouncingCubeScene

} // end of namespace Samples
} // end of namespace BABYLON

namespace BABYLON {
namespace Samples {

void BouncingCubeScene::_applyForces()
{
  _velocity.addInPlace(_gravity);
}

void BouncingCubeScene::_checkCollisions()
{
  // Check box walls
  if (std::abs(_mario->position().x) > _limit) {
    _velocity.x *= -1.f;
    _mario->position().x = (_mario->position().x > 0.f) ? _limit : -_limit;
  }
  if (std::abs(_mario->position().y) > _limit) {
    _velocity.y *= -1.f * _restitution;
    _mario->position().y = (_mario->position().y > 0.f) ? _limit : -_limit;
  }
  if (std::abs(_mario->position().z) > _limit) {
    _velocity.z *= -1.f;
    _mario->position().z = (_mario->position().z > 0.f) ? _limit : -_limit;
  }
  // Check platforms
  size_t i = 0;
  for (auto& platform : _platforms) {
    if (_mario->intersectsMesh(*platform)) {
      // naive impact point check
      if (_mario->position().y > platform->position().y) {
        _mario->position().y = platform->position().y + platform->scaling().y * 0.5f;
        _velocity.y *= -_platformBounceRestitution;
      }
      if (_mario->position().y < platform->position().y) {
        _velocity.y *= -1.f;
      }
    }
    ++i;
  }
}

void BouncingCubeScene::_moveMario()
{
  _mario->position().addInPlace(_velocity);
}

void BouncingCubeScene::_movePlatforms()
{
  size_t i = 0;
  for (auto& platform : _platforms) {
    auto p = i % 3;
    switch (p) {
      case 0:
        platform->position().x += 0.1f * std::sin(_k * i);
        break;
      case 1:
        platform->position().y -= 0.2f * std::cos(_k * i);
        break;
      case 2:
        platform->position().z -= 0.03f * std::sin(_k * i);
        break;
    }
    ++i;
  }
}

BABYLON_REGISTER_SAMPLE("Animations", BouncingCubeScene)

} // end of namespace Samples
} // end of namespace BABYLON
<|endoftext|>


<commit_before>#include <numeric>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <iomanip>
#include <cmath>
#include <algorithm>

#include "sdd/sdd.hh"
#include "sdd/tools/size.hh"

using namespace std;

struct conf
  : public sdd::flat_set_default_configuration
{
  using Identifier = unsigned int;
  using Values     = sdd::values::flat_set<char>;
};
using SDD         = sdd::SDD<conf>;
using values_type = conf::Values;

static const auto sublength = 35;

SDD
build (const string& str){
  if (str.size() == sublength)
  {
    SDD result = sdd::one<conf>();
    for (size_t i = 0; i != str.size(); ++i)
      result = SDD(i, { str[str.size() - i - 1] }, result);
    return result;
  }
  else
  {
    SDD result = sdd::one<conf>();
    const auto subsize = str.size() / sublength;
    for (size_t i = 0; i != sublength; ++i)
    {
      const auto substr = str.substr(subsize * (sublength - i - 1), sublength);
      result = SDD(i, build (substr), result);
    }
    return result;
  }
}

int
main (int argc, const char** argv)
{
  const auto subsize = 1000;
  size_t max_size = 1;
  size_t max_name = 1;
  map<string, size_t> counts;
  vector<SDD> collections;
  vector<SDD> subcollection;
  subcollection.reserve(subsize);

  conf c;
  c.final_cleanup = false; // don't cleanup memory on manager scope exit.
  c.hom_cache_size = 2;
  c.hom_unique_table_size = 2;
  c.sdd_intersection_cache_size = 16000000;
  c.sdd_sum_cache_size = 16000000;
  c.sdd_difference_cache_size = 16000000;
  c.sdd_unique_table_size = 10000000;
  auto manager = sdd::init<conf>(c);

  if (argc == 0)
  {
    cerr << "No arguments" << endl;
    return 1;
  }

  string line;
  line.reserve(256);

  const size_t max_length = [&]
  {
    size_t length = 0;
    for (size_t param = 1; param < argc; ++param)
    {
      const string filename = argv[param];
      max_name = max (max_name, filename.length());
      ifstream dict(filename);
      if (dict.is_open())
      {
        size_t count = 0;
        while (std::getline(dict, line))
        {
          count++;
          length = length > line.size() ? length : line.size();
        }
        counts [filename] = count;
        max_size = max (max_size, count > 0 ? (size_t) log10 ((double) count) + 1 : 1);
      }
      else
      {
        cerr << "Warning, can't open " << filename << endl;
      }
    }
    return length;
  }();

  cout << "Max word length is " << max_length << endl;

  size_t rounded_length = 1;
  while (true)
  {
    if (rounded_length >= max_length)
      break;
    else
      rounded_length *= sublength;
  }
  line.reserve(rounded_length + 1);

  // Construct the SDD order: we need one level per letter.
//  vector<unsigned int> v(max_length);
//  iota(v.begin(), v.end(), 0);
//  sdd::order_builder<conf> ob;
//  const sdd::order<conf> order(sdd::order_builder<conf>(v.begin(), v.end()));

  for (size_t param = 1; param < argc; ++param)
  {
    string filename = argv[param];
    ifstream dict (filename);
    if (dict.is_open())
    {
      size_t count = 0;
      size_t max = counts [filename];
      cout << setw(max_name + 5) << left << filename
           << right << "\033[s"
           << "\033[u"
           << setw(max_size) << count << " / " << setw(max_size) << max
           << flush;
      while (getline(dict, line))
      {
        count++;
        line.insert(line.size(), rounded_length - line.size(), ' ');
        subcollection.push_back (build (line));
        if (count % subsize == 0)
        {
          collections.emplace_back(sdd::sum<conf>(subcollection.cbegin(), subcollection.cend()));
          subcollection.clear();
          cout << "\033[u"
               << setw(max_size) << count << " / " << setw(max_size) << max
               << flush;
        }
      }
      collections.emplace_back(sdd::sum<conf>(subcollection.cbegin(), subcollection.cend()));
      cout << "\033[u"
           << setw(max_size) << count << " / " << setw(max_size) << max
           << flush;
    }
    else
    {
      cerr << "Warning, can't open " << filename << endl;
    }
    dict.close();
    cout << endl;
  }
  cout << "# Collections: " << collections.size() << endl;
  for (auto& c : collections)
  {
    cout << "Size: " << c.size() << endl;
  }
  const auto collection = sdd::sum<conf>(collections.cbegin(), collections.cend());
  cout << "# Words: " << collection.size() << endl;
  cout << "Size: " << sdd::tools::size(collection) << " bytes" << endl;

  return 0;
}
<commit_msg>Show more information.<commit_after>#include <numeric>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <iomanip>
#include <cmath>
#include <algorithm>

#include "sdd/sdd.hh"
#include "sdd/tools/size.hh"
#include "sdd/tools/nodes.hh"

using namespace std;

struct conf
  : public sdd::flat_set_default_configuration
{
  using Identifier = unsigned int;
  using Values     = sdd::values::flat_set<char>;
};
using SDD         = sdd::SDD<conf>;
using values_type = conf::Values;

static const auto sublength = 35;

SDD
build (const string& str){
  if (str.size() == sublength)
  {
    SDD result = sdd::one<conf>();
    for (size_t i = 0; i != str.size(); ++i)
      result = SDD(i, { str[str.size() - i - 1] }, result);
    return result;
  }
  else
  {
    SDD result = sdd::one<conf>();
    const auto subsize = str.size() / sublength;
    for (size_t i = 0; i != sublength; ++i)
    {
      const auto substr = str.substr(subsize * (sublength - i - 1), sublength);
      result = SDD(i, build (substr), result);
    }
    return result;
  }
}

int
main (int argc, const char** argv)
{
  const auto subsize = 1000;
  size_t max_size = 1;
  size_t max_name = 1;
  map<string, size_t> counts;
  vector<SDD> collections;
  vector<SDD> subcollection;
  subcollection.reserve(subsize);

  conf c;
  c.final_cleanup = false; // don't cleanup memory on manager scope exit.
  c.hom_cache_size = 2;
  c.hom_unique_table_size = 2;
//  c.sdd_intersection_cache_size = 16000000;
//  c.sdd_sum_cache_size = 16000000;
//  c.sdd_difference_cache_size = 16000000;
  c.sdd_unique_table_size = 10000000;
  auto manager = sdd::init<conf>(c);

  if (argc == 0)
  {
    cerr << "No arguments" << endl;
    return 1;
  }

  string line;
  line.reserve(256);

  const size_t max_length = [&]
  {
    size_t length = 0;
    for (size_t param = 1; param < argc; ++param)
    {
      const string filename = argv[param];
      max_name = max (max_name, filename.length());
      ifstream dict(filename);
      if (dict.is_open())
      {
        size_t count = 0;
        while (std::getline(dict, line))
        {
          count++;
          length = length > line.size() ? length : line.size();
        }
        counts [filename] = count;
        max_size = max (max_size, count > 0 ? (size_t) log10 ((double) count) + 1 : 1);
      }
      else
      {
        cerr << "Warning, can't open " << filename << endl;
      }
    }
    return length;
  }();

  cout << "Max word length is " << max_length << endl;

  size_t rounded_length = 1;
  while (true)
  {
    if (rounded_length >= max_length)
      break;
    else
      rounded_length *= sublength;
  }
  line.reserve(rounded_length + 1);

  // Construct the SDD order: we need one level per letter.
//  vector<unsigned int> v(max_length);
//  iota(v.begin(), v.end(), 0);
//  sdd::order_builder<conf> ob;
//  const sdd::order<conf> order(sdd::order_builder<conf>(v.begin(), v.end()));

  for (size_t param = 1; param < argc; ++param)
  {
    string filename = argv[param];
    ifstream dict (filename);
    if (dict.is_open())
    {
      size_t count = 0;
      size_t max = counts [filename];
      cout << setw(max_name + 5) << left << filename
           << right << "\033[s"
           << "\033[u"
           << setw(max_size) << count << " / " << setw(max_size) << max
           << flush;
      while (getline(dict, line))
      {
        count++;
        line.insert(line.size(), rounded_length - line.size(), ' ');
        subcollection.push_back (build (line));
        if (count % subsize == 0)
        {
          collections.emplace_back(sdd::sum<conf>(subcollection.cbegin(), subcollection.cend()));
          subcollection.clear();
          cout << "\033[u"
               << setw(max_size) << count << " / " << setw(max_size) << max
               << flush;
        }
      }
      collections.emplace_back(sdd::sum<conf>(subcollection.cbegin(), subcollection.cend()));
      cout << "\033[u"
           << setw(max_size) << count << " / " << setw(max_size) << max
           << flush;
    }
    else
    {
      cerr << "Warning, can't open " << filename << endl;
    }
    dict.close();
    cout << endl;
  }
  const auto collection = sdd::sum<conf>(collections.cbegin(), collections.cend());
  cout << "# Words: " << collection.size() << endl;
  cout << "# Nodes: " << sdd::tools::nodes(collection).first
       << ", " << sdd::tools::nodes(collection).second
       << endl;
  cout << "Size: " << sdd::tools::size(collection) << " bytes" << endl;

  return 0;
}
<|endoftext|>


<commit_before>/*
 * This is the Calvin mini library for Arduino due
 *
 *Created on: 5 okt. 2015
 *
 */
#include <stdio.h>
#include "CalvinMini.h"
#include <inttypes.h>

#ifdef ARDUINO
#include <SPI.h>
#include <Ethernet.h>
#include <util.h>

//byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0xF5, 0x93 };
IPAddress ip(192,168,0,5);
//IPAddress ip(192,168,1,146);
uint16_t slaveport = 5002;
EthernetServer server(slaveport);
EthernetClient client;

const int messageOutLength = 4;
String messageOut[messageOutLength] = {};
int nextMessage = 0;
#endif

actor globalActor;
fifo actorFifo;

/**
 * Current standard out is the lcd screen connected to arduino due
 */
int8_t StdOut(){
  uint8_t inFifo;
  const char* token;
  token = "null";
  inFifo = lengthOfData(globalActor.inportsFifo[0]);
  if(inFifo > 0)
  {
    token = fifoPop(globalActor.inportsFifo[0]);
  }
  return standardOut(token);
}

/**
 *  What's up with the external C you might wonder,
 *  well thats the only way i could ad a function pointer to a strut,
 *  Apparently c++ handles this different from c.
 */
extern "C"{
rStatus actorInit(){
  rStatus allOk = FAIL;

  globalActor.fireActor = &StdOut;
  /*This sets up the fifo for the actor, not sure
   *if it should be done here but for now it works*/
  allOk = initFifo(&actorFifo);
  globalActor.inportsFifo[0] = &actorFifo;

  return allOk;
}
}

/**
 * Create an new actor.
 * @param msg json list
 * @return return 1 if successful.
 */
rStatus CalvinMini::createActor(JsonObject &msg){
  rStatus allOk = FAIL;
  JsonObject &state = msg.get("state");
  JsonObject &name = state.get("actor_state");
  globalActor.type = state.get("actor_type");
  globalActor.name = name.get("name");
  globalActor.id = name.get("id");

  allOk = SUCCESS;
  actorInit();
  return allOk;
}

extern "C"{
/**
 * This Function initiate the fifo must be
 * called prior to using the fifo.
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 *
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 */
rStatus initFifo(fifo *fif)
{
  fif->size = FIFO_SIZE;
  fif->read = 0;
  fif->write = 0;
  return SUCCESS;
}
/**
 * Used by Add and Pop to determine fifo length.
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 *
 * @return Fifo length
 */
int8_t lengthOfData(fifo *fif)
{
  return ((fif->write - fif->read) & (fif->size -1));
}

/**
 * Adds a new element to the fifo
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 *
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 * @return returns 0 if the fifo is full
 */
rStatus fifoAdd(fifo *fif, const char* element){

  if(lengthOfData(fif) == (fif->size-1))
  {
    return FAIL;      //fifo full;
  }
  fif->element[fif->write] = element;
  fif->write = (fif->write + 1) & (fif->size - 1);

  return SUCCESS;       //all is well
}

/**
 * Return and removes the oldest element in the fifo.
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 *
 * @Return Returns fifo element, returns NULL if fifo is
 * empty.
 */
const char* fifoPop(fifo *fif){

  const char* ret;

  if(lengthOfData(fif) == 0)
  {
    return "Null";    //fifo empty
  }

  ret = fif->element[fif->read];
  fif->read = (fif->read + 1) & (fif->size - 1);

  return ret;
}

}
/**
 * Process an incomming token and add the token data to
 * an actor fifo.
 * @param Token data as a string
 * @return if data vas added to fifo this function returns
 * 1, if something went wrong it returns 0.
 */
rStatus CalvinMini::process(const char* token){
  rStatus allOk;
  allOk = FAIL;
  allOk = fifoAdd(globalActor.inportsFifo[0],token);
  return allOk;
}

/**
 * Function for setting the Json reply back to Calvin-Base when the request message from
 * Calvin-Base is "Token"
 * @param msg is the JsonObject that is message from Calvin-Base
 * @param reply is the JsonObject with the reply message from Calvin-Arduino
 */
void CalvinMini::handleToken(JsonObject &msg, JsonObject &reply)
{
  process(msg.get("token"));
  reply.set("cmd",      "TOKEN_REPLY");
  reply.set("sequencenbr",  msg.get("sequencenbr"));
  reply.set("port_id",    msg.get("port_id"));
  reply.set("peer_port_id",   msg.get("peer_port_id"));
  reply.set("value",      "ACK");
}

/**
 * Method for handle the tunnel data using JSON, JSON is added to the JsonObject reference reply
 * @param &msg JsonObject received from Calvin-Base
 * @param &reply JsonObject that is added to the "reply" list
 *
 * Author: Jesper Hansen
 */
void CalvinMini::handleTunnelData(JsonObject &msg, JsonObject &reply, JsonObject &request)
{
  JsonObject &value = msg.get("value");
  reply.set("to_rt_uuid",   msg.get("from_rt_uuid"));
  reply.set("from_rt_uuid",   msg.get("to_rt_uuid"));
  reply.set("cmd",      "TUNNEL_DATA");
  reply.set("tunnel_id",    "NULL"); // None in python
#ifdef ARDUINO
  handleMsg(value,reply,request);
#endif
}

void CalvinMini::handleActorNew(JsonObject &msg, JsonObject &reply)
{
  createActor(msg);

  reply.set("cmd",      "REPLY");
  reply.set("msg_uuid",   msg.get("msg_uuid"));
  reply.set("value",      "ACK");
  reply.set("from_rt_uuid", "calvin-miniscule");
  reply.set("to_rt_uuid",   msg.get("from_rt_uuid"));
}

/**
 * Handle all different messages
 * @param msg JsonObject
 * @param reply JsonObject
 * @param request JsonObject
 */
int8_t CalvinMini::handleMsg(JsonObject &msg, JsonObject &reply, JsonObject &request)
{
  char replyTemp[512] = {};
  char requestTemp[512] = {};
  if(!strcmp(msg.get("cmd"),"JOIN_REQUEST"))
  {
      // JsonObject for replying a join request
      StaticJsonBuffer<200> jsonBuffer;
      JsonObject &policy = jsonBuffer.createObject();
      handleJoin(msg,reply);
      handleSetupTunnel(msg, request, policy);

      // Print JsonObject and send to Calvin
      #ifdef ARDUINO
      Serial.println("Sending...");

      reply.printTo(replyTemp,512);
      request.printTo(requestTemp,512);

      String str(replyTemp);
      String str2(requestTemp);
      addToMessageOut(str);
      addToMessageOut(str2);
      #endif
      return 1;
  }
  else if(!strcmp(msg.get("cmd"),"ACTOR_NEW"))
  {
      Serial.println("In ACTOR_NEW");
      handleActorNew(msg, reply);
      return 2;
  }
  else if(!strcmp(msg.get("cmd"),"TUNNEL_DATA"))
  {
      handleTunnelData(msg, reply, request);
      return 3;
  }
  else if(!strcmp(msg.get("cmd"),"TOKEN"))
  {
      // reply object
      return 4;
  }
  else if(!strcmp(msg.get("cmd"),"TOKEN_REPLY"))
  {
      // reply array
      return 5;
  }
  else if(!strcmp(msg.get("cmd"),"REPLY"))
  {
      #ifdef ARDUINO
      JsonObject &value = msg["value"];
      if(!strcmp(value.get("status"),"ACK"))
      {
          String test = value.get("status");
          Serial.println(test.c_str());
      }
      else
      {
          Serial.println("NACK");
      }
      #endif
      return 6;
  }
  else
  {
      standardOut("UNKNOWN CMD");
      return 7;
  }
}

#ifdef ARDUINO
/**
 * Adds messages to a global array and
 * creates the array size for sending
 * @param reply String
 */
void CalvinMini::addToMessageOut(String reply)
{
  messageOut[nextMessage] = reply;
  if(nextMessage < messageOutLength)
    nextMessage = nextMessage+1;
}

/**
 * Receive message from calvin base
 * @return String
 */
String CalvinMini::recvMsg()
{
  Serial.println("Reading...");
  char temp[MAX_LENGTH+1] = {};
  String str = "";
  byte data[4];
  int found = 0;
  int count = 0;
  int sizeOfMsg;
  while(!found)
  {
        client.readBytes(temp, MAX_LENGTH);
        data[count] = *temp;
        count++;
        if(*temp == '{')
        {
            str += temp;
            found = 1;
        }
  }
  sizeOfMsg = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
  for(int i = 0;i < sizeOfMsg-1;i++)
  {
      int size = client.readBytes(temp, MAX_LENGTH);
      temp[size] = '\0';  // Null terminate char
      str += temp;
  }
  Serial.println(temp);
  return str;
}

/**
 * Reply message to calvin base
 * @param str char pointer of String
 * @param length size of String
 */
void CalvinMini::sendMsg(const char *str, size_t length)
{
  byte binary[4] = {};
  binary[0] = (length & 0xFF000000);
  binary[1] = (length & 0x00FF0000);
  binary[2] = (length & 0x0000FF00);
  binary[3] = (length & 0x000000FF);

  for(int i = 0; i< 4;i++)
  {
    server.write(binary[i]);
  }
  server.write(str);
}
#endif
/**
 * Create a reply message
 * @param msg JsonObject
 * @param reply JsonObject
 */
void CalvinMini::handleJoin(JsonObject &msg, JsonObject &reply)
{
  reply["cmd"] = "JOIN_REPLY";
  reply["id"] = "calvin-miniscule";
  reply["sid"] = msg.get("sid");
  reply["serializer"] = "json";
}

/**
 * Method for setting up a tunnel using JSON message back to Calvin-Base,
 * JSON is added to the JsonObject request that is added to the reply list.
 * @param &msg JsonObject received from Calvin-Base
 * @param &request JsonObject that is added to the "reply" list
 * @param &policy JsonObject that is an empty JsonObject
 */
void CalvinMini::handleSetupTunnel(JsonObject &msg, JsonObject &request, JsonObject &policy)
{
  request["msg_uuid"] = "MSG-00531ac3-1d2d-454d-964a-7e9573f6ebb6"; // Should be a unique id
  request["from_rt_uuid"] = "calvin-miniscule";
  request["to_rt_uuid"] = msg.get("id");
  request["cmd"] = "TUNNEL_NEW";
  request["tunnel_id"] = "fake-tunnel";
  request["policy"] = policy; // Unused
  request["type"] = "token";
}

#ifdef ARDUINO
/**
 * Start a server connection
 */
void CalvinMini::setupServer()
{
  //getIPFromRouter(); // Doesn't work with shield
  Ethernet.begin(mac, ip);
  printIp();
  server.begin();
}

/**
 * Prints the IP-address assigned to the Ethernet shield.
 */
void CalvinMini::printIp()
{
    Serial.println(Ethernet.localIP());
}

/**
 * Assign an IP-address to the Ethernet shield.
 */
void CalvinMini::getIPFromRouter()
{
    // Disable SD
    pinMode(4,OUTPUT);
    digitalWrite(4,HIGH);
    if (Ethernet.begin(mac) == 0)
    {
        Serial.println("Failed to configure Ethernet using DHCP");
        // Set static IP-address if fail
        Ethernet.begin(mac, ip);
    }
}

/**
 * Serializes a String to Json syntax.
 * From this: {"sensor":"gps","time":1351824120}
 * To this: {\"sensor\":\"gps\",\"time\":1351824120}
 * @param str char* pointer
 * @return char* pointer
 */
char* CalvinMini::jsonSerialize(const char *str)
{
  const char *json = str;
  char *temp = new char[256];
  int counter = 0;
  for(int i = 0; json[i] != '\0'; i++)
  {
      if(json[i] == '\"')
      {
          temp[counter] = '\\';
          counter++;
      }
      temp[counter] = json[i];
      counter++;
  }
  temp[counter] = '\0';
  return temp;
}

void CalvinMini::loop()
{
  setupServer();
  while(1)
  {
      // 1: Kontrollera anslutna sockets
      client = server.available();
      // 2: Fixa koppling
      if(client) // Wait for client
      {
          // 3: Läs av meddelande
          Serial.println("Connected...");
          String str = recvMsg();

          StaticJsonBuffer<4096> jsonBuffer;
          JsonObject &msg = jsonBuffer.parseObject(str.c_str());
          msg.printTo(Serial);
          JsonObject &reply = jsonBuffer.createObject();
          JsonObject &request = jsonBuffer.createObject();

          // 4: Hantera meddelande
          handleMsg(msg, reply, request);

          // 5: Fire Actors

          // 6: Läs av utlistan
          for(int i = 0;i < nextMessage;i++)
          {
              // 7: Skicka utmeddelande
              sendMsg(messageOut[i].c_str(),messageOut[i].length());
              messageOut[i] = "";
          }
          nextMessage = 0;
      }
  }
}
#endif
<commit_msg>Removed a serial print<commit_after>/*
 * This is the Calvin mini library for Arduino due
 *
 *Created on: 5 okt. 2015
 *
 */
#include <stdio.h>
#include "CalvinMini.h"
#include <inttypes.h>

#ifdef ARDUINO
#include <SPI.h>
#include <Ethernet.h>
#include <util.h>

//byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0xF5, 0x93 };
IPAddress ip(192,168,0,5);
//IPAddress ip(192,168,1,146);
uint16_t slaveport = 5002;
EthernetServer server(slaveport);
EthernetClient client;

const int messageOutLength = 4;
String messageOut[messageOutLength] = {};
int nextMessage = 0;
#endif

actor globalActor;
fifo actorFifo;

/**
 * Current standard out is the lcd screen connected to arduino due
 */
int8_t StdOut(){
  uint8_t inFifo;
  const char* token;
  token = "null";
  inFifo = lengthOfData(globalActor.inportsFifo[0]);
  if(inFifo > 0)
  {
    token = fifoPop(globalActor.inportsFifo[0]);
  }
  return standardOut(token);
}

/**
 *  What's up with the external C you might wonder,
 *  well thats the only way i could ad a function pointer to a strut,
 *  Apparently c++ handles this different from c.
 */
extern "C"{
rStatus actorInit(){
  rStatus allOk = FAIL;

  globalActor.fireActor = &StdOut;
  /*This sets up the fifo for the actor, not sure
   *if it should be done here but for now it works*/
  allOk = initFifo(&actorFifo);
  globalActor.inportsFifo[0] = &actorFifo;

  return allOk;
}
}

/**
 * Create an new actor.
 * @param msg json list
 * @return return 1 if successful.
 */
rStatus CalvinMini::createActor(JsonObject &msg){
  rStatus allOk = FAIL;
  JsonObject &state = msg.get("state");
  JsonObject &name = state.get("actor_state");
  globalActor.type = state.get("actor_type");
  globalActor.name = name.get("name");
  globalActor.id = name.get("id");

  allOk = SUCCESS;
  actorInit();
  return allOk;
}

extern "C"{
/**
 * This Function initiate the fifo must be
 * called prior to using the fifo.
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 *
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 */
rStatus initFifo(fifo *fif)
{
  fif->size = FIFO_SIZE;
  fif->read = 0;
  fif->write = 0;
  return SUCCESS;
}
/**
 * Used by Add and Pop to determine fifo length.
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 *
 * @return Fifo length
 */
int8_t lengthOfData(fifo *fif)
{
  return ((fif->write - fif->read) & (fif->size -1));
}

/**
 * Adds a new element to the fifo
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 *
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 * @return returns 0 if the fifo is full
 */
rStatus fifoAdd(fifo *fif, const char* element){

  if(lengthOfData(fif) == (fif->size-1))
  {
    return FAIL;      //fifo full;
  }
  fif->element[fif->write] = element;
  fif->write = (fif->write + 1) & (fif->size - 1);

  return SUCCESS;       //all is well
}

/**
 * Return and removes the oldest element in the fifo.
 *
 * This fifo implementation is based upon a circular
 * buffert written by Elcia White found in the book
 * "Making Embedded Systems by Elecia White(O'Reilly).
 * Copyright 2012 Elecia White,978-1-449-30214-6"
 *
 * @Return Returns fifo element, returns NULL if fifo is
 * empty.
 */
const char* fifoPop(fifo *fif){

  const char* ret;

  if(lengthOfData(fif) == 0)
  {
    return "Null";    //fifo empty
  }

  ret = fif->element[fif->read];
  fif->read = (fif->read + 1) & (fif->size - 1);

  return ret;
}

}
/**
 * Process an incomming token and add the token data to
 * an actor fifo.
 * @param Token data as a string
 * @return if data vas added to fifo this function returns
 * 1, if something went wrong it returns 0.
 */
rStatus CalvinMini::process(const char* token){
  rStatus allOk;
  allOk = FAIL;
  allOk = fifoAdd(globalActor.inportsFifo[0],token);
  return allOk;
}

/**
 * Function for setting the Json reply back to Calvin-Base when the request message from
 * Calvin-Base is "Token"
 * @param msg is the JsonObject that is message from Calvin-Base
 * @param reply is the JsonObject with the reply message from Calvin-Arduino
 */
void CalvinMini::handleToken(JsonObject &msg, JsonObject &reply)
{
  process(msg.get("token"));
  reply.set("cmd",      "TOKEN_REPLY");
  reply.set("sequencenbr",  msg.get("sequencenbr"));
  reply.set("port_id",    msg.get("port_id"));
  reply.set("peer_port_id",   msg.get("peer_port_id"));
  reply.set("value",      "ACK");
}

/**
 * Method for handle the tunnel data using JSON, JSON is added to the JsonObject reference reply
 * @param &msg JsonObject received from Calvin-Base
 * @param &reply JsonObject that is added to the "reply" list
 *
 * Author: Jesper Hansen
 */
void CalvinMini::handleTunnelData(JsonObject &msg, JsonObject &reply, JsonObject &request)
{
  JsonObject &value = msg.get("value");
  reply.set("to_rt_uuid",   msg.get("from_rt_uuid"));
  reply.set("from_rt_uuid",   msg.get("to_rt_uuid"));
  reply.set("cmd",      "TUNNEL_DATA");
  reply.set("tunnel_id",    "NULL"); // None in python
#ifdef ARDUINO
  handleMsg(value,reply,request);
#endif
}

void CalvinMini::handleActorNew(JsonObject &msg, JsonObject &reply)
{
  createActor(msg);

  reply.set("cmd",      "REPLY");
  reply.set("msg_uuid",   msg.get("msg_uuid"));
  reply.set("value",      "ACK");
  reply.set("from_rt_uuid", "calvin-miniscule");
  reply.set("to_rt_uuid",   msg.get("from_rt_uuid"));
}

/**
 * Handle all different messages
 * @param msg JsonObject
 * @param reply JsonObject
 * @param request JsonObject
 */
int8_t CalvinMini::handleMsg(JsonObject &msg, JsonObject &reply, JsonObject &request)
{
  char replyTemp[512] = {};
  char requestTemp[512] = {};
  if(!strcmp(msg.get("cmd"),"JOIN_REQUEST"))
  {
      // JsonObject for replying a join request
      StaticJsonBuffer<200> jsonBuffer;
      JsonObject &policy = jsonBuffer.createObject();
      handleJoin(msg,reply);
      handleSetupTunnel(msg, request, policy);

      // Print JsonObject and send to Calvin
      #ifdef ARDUINO
      Serial.println("Sending...");

      reply.printTo(replyTemp,512);
      request.printTo(requestTemp,512);

      String str(replyTemp);
      String str2(requestTemp);
      addToMessageOut(str);
      addToMessageOut(str2);
      #endif
      return 1;
  }
  else if(!strcmp(msg.get("cmd"),"ACTOR_NEW"))
  {
      handleActorNew(msg, reply);
      return 2;
  }
  else if(!strcmp(msg.get("cmd"),"TUNNEL_DATA"))
  {
      handleTunnelData(msg, reply, request);
      return 3;
  }
  else if(!strcmp(msg.get("cmd"),"TOKEN"))
  {
      // reply object
      return 4;
  }
  else if(!strcmp(msg.get("cmd"),"TOKEN_REPLY"))
  {
      // reply array
      return 5;
  }
  else if(!strcmp(msg.get("cmd"),"REPLY"))
  {
      #ifdef ARDUINO
      JsonObject &value = msg["value"];
      if(!strcmp(value.get("status"),"ACK"))
      {
          String test = value.get("status");
          Serial.println(test.c_str());
      }
      else
      {
          Serial.println("NACK");
      }
      #endif
      return 6;
  }
  else
  {
      standardOut("UNKNOWN CMD");
      return 7;
  }
}

#ifdef ARDUINO
/**
 * Adds messages to a global array and
 * creates the array size for sending
 * @param reply String
 */
void CalvinMini::addToMessageOut(String reply)
{
  messageOut[nextMessage] = reply;
  if(nextMessage < messageOutLength)
    nextMessage = nextMessage+1;
}

/**
 * Receive message from calvin base
 * @return String
 */
String CalvinMini::recvMsg()
{
  Serial.println("Reading...");
  char temp[MAX_LENGTH+1] = {};
  String str = "";
  byte data[4];
  int found = 0;
  int count = 0;
  int sizeOfMsg;
  while(!found)
  {
        client.readBytes(temp, MAX_LENGTH);
        data[count] = *temp;
        count++;
        if(*temp == '{')
        {
            str += temp;
            found = 1;
        }
  }
  sizeOfMsg = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
  for(int i = 0;i < sizeOfMsg-1;i++)
  {
      int size = client.readBytes(temp, MAX_LENGTH);
      temp[size] = '\0';  // Null terminate char
      str += temp;
  }
  Serial.println(temp);
  return str;
}

/**
 * Reply message to calvin base
 * @param str char pointer of String
 * @param length size of String
 */
void CalvinMini::sendMsg(const char *str, size_t length)
{
  byte binary[4] = {};
  binary[0] = (length & 0xFF000000);
  binary[1] = (length & 0x00FF0000);
  binary[2] = (length & 0x0000FF00);
  binary[3] = (length & 0x000000FF);

  for(int i = 0; i< 4;i++)
  {
    server.write(binary[i]);
  }
  server.write(str);
}
#endif
/**
 * Create a reply message
 * @param msg JsonObject
 * @param reply JsonObject
 */
void CalvinMini::handleJoin(JsonObject &msg, JsonObject &reply)
{
  reply["cmd"] = "JOIN_REPLY";
  reply["id"] = "calvin-miniscule";
  reply["sid"] = msg.get("sid");
  reply["serializer"] = "json";
}

/**
 * Method for setting up a tunnel using JSON message back to Calvin-Base,
 * JSON is added to the JsonObject request that is added to the reply list.
 * @param &msg JsonObject received from Calvin-Base
 * @param &request JsonObject that is added to the "reply" list
 * @param &policy JsonObject that is an empty JsonObject
 */
void CalvinMini::handleSetupTunnel(JsonObject &msg, JsonObject &request, JsonObject &policy)
{
  request["msg_uuid"] = "MSG-00531ac3-1d2d-454d-964a-7e9573f6ebb6"; // Should be a unique id
  request["from_rt_uuid"] = "calvin-miniscule";
  request["to_rt_uuid"] = msg.get("id");
  request["cmd"] = "TUNNEL_NEW";
  request["tunnel_id"] = "fake-tunnel";
  request["policy"] = policy; // Unused
  request["type"] = "token";
}

#ifdef ARDUINO
/**
 * Start a server connection
 */
void CalvinMini::setupServer()
{
  //getIPFromRouter(); // Doesn't work with shield
  Ethernet.begin(mac, ip);
  printIp();
  server.begin();
}

/**
 * Prints the IP-address assigned to the Ethernet shield.
 */
void CalvinMini::printIp()
{
    Serial.println(Ethernet.localIP());
}

/**
 * Assign an IP-address to the Ethernet shield.
 */
void CalvinMini::getIPFromRouter()
{
    // Disable SD
    pinMode(4,OUTPUT);
    digitalWrite(4,HIGH);
    if (Ethernet.begin(mac) == 0)
    {
        Serial.println("Failed to configure Ethernet using DHCP");
        // Set static IP-address if fail
        Ethernet.begin(mac, ip);
    }
}

/**
 * Serializes a String to Json syntax.
 * From this: {"sensor":"gps","time":1351824120}
 * To this: {\"sensor\":\"gps\",\"time\":1351824120}
 * @param str char* pointer
 * @return char* pointer
 */
char* CalvinMini::jsonSerialize(const char *str)
{
  const char *json = str;
  char *temp = new char[256];
  int counter = 0;
  for(int i = 0; json[i] != '\0'; i++)
  {
      if(json[i] == '\"')
      {
          temp[counter] = '\\';
          counter++;
      }
      temp[counter] = json[i];
      counter++;
  }
  temp[counter] = '\0';
  return temp;
}

void CalvinMini::loop()
{
  setupServer();
  while(1)
  {
      // 1: Kontrollera anslutna sockets
      client = server.available();
      // 2: Fixa koppling
      if(client) // Wait for client
      {
          // 3: Läs av meddelande
          Serial.println("Connected...");
          String str = recvMsg();

          StaticJsonBuffer<4096> jsonBuffer;
          JsonObject &msg = jsonBuffer.parseObject(str.c_str());
          msg.printTo(Serial);
          JsonObject &reply = jsonBuffer.createObject();
          JsonObject &request = jsonBuffer.createObject();

          // 4: Hantera meddelande
          handleMsg(msg, reply, request);

          // 5: Fire Actors

          // 6: Läs av utlistan
          for(int i = 0;i < nextMessage;i++)
          {
              // 7: Skicka utmeddelande
              sendMsg(messageOut[i].c_str(),messageOut[i].length());
              messageOut[i] = "";
          }
          nextMessage = 0;
      }
  }
}
#endif
<|endoftext|>


<commit_before>#include <cstdlib>
#include <cassert>

#include "api-loader.h"
#include "pointers.h"

#include <string>

//here direct pointers are kept (pointers to entrypoints exposed by underlying OpenGL32 implementation
//use DIRECT_CALL(name) to call one of these pointers
void* g_DirectPointers[Entrypoints_NUM];

HINSTANCE  openGLLibraryHandle;

void * LoadOpenGLPointer(char* name) {
    return GetProcAddress(openGLLibraryHandle, name);
}

void* LoadOpenGLExtPointer(Entrypoint entryp) {
    return g_DirectPointers[entryp] = DIRECT_CALL(wglGetProcAddress)(GetEntryPointName(entryp));
}

#define FUNCTION_LIST_ELEMENT(name, type) POINTER(name) = LoadOpenGLPointer(#name);
void LoadOpenGLPointers () {
    #include "../../dump/codegen/functionList.inl"
}
#undef FUNCTION_LIST_ELEMENT

void LoadOpenGLLibrary() {
    openGLLibraryHandle = LoadLibrary("C:\\Windows\\SysWOW64\\opengl32.dll");
    if (!openGLLibraryHandle) {
        openGLLibraryHandle = LoadLibrary("C:\\Windows\\System32\\opengl32.dll");
    }

    assert(openGLLibraryHandle);
    if (!openGLLibraryHandle) {
        MessageBox(0, "Cannot load library", "Cannot Load library OpenGL32.dll", MB_OK | MB_ICONSTOP);
        exit(EXIT_FAILURE);
    }

    LoadOpenGLPointers();
}

void* EnsurePointer(Entrypoint entryp) {
    if (g_DirectPointers[entryp] || LoadOpenGLExtPointer(entryp)) {
        return g_DirectPointers[entryp];
    } else {
        std::string error = "Operation aborted, because the ";
        error += GetEntryPointName(entryp);
        error += " function is not available on current context. Try updating GPU drivers.";
        throw std::runtime_error(error);
    }
}

<commit_msg>Fixed bug: wglGetProcAddress() called by application on core entrypoint.<commit_after>#include <cstdlib>
#include <cassert>

#include "api-loader.h"
#include "pointers.h"

#include <string>

//here direct pointers are kept (pointers to entrypoints exposed by underlying OpenGL32 implementation
//use DIRECT_CALL(name) to call one of these pointers
void* g_DirectPointers[Entrypoints_NUM];

HINSTANCE  openGLLibraryHandle;

void * LoadOpenGLPointer(char* name) {
    return GetProcAddress(openGLLibraryHandle, name);
}

void* LoadOpenGLExtPointer(Entrypoint entryp) {
    if (!g_DirectPointers[entryp]) {
        return g_DirectPointers[entryp] = DIRECT_CALL(wglGetProcAddress)(GetEntryPointName(entryp));
    } else {
        return g_DirectPointers[entryp];
    }
}

#define FUNCTION_LIST_ELEMENT(name, type) POINTER(name) = LoadOpenGLPointer(#name);
void LoadOpenGLPointers () {
    #include "../../dump/codegen/functionList.inl"
}
#undef FUNCTION_LIST_ELEMENT

void LoadOpenGLLibrary() {
    openGLLibraryHandle = LoadLibrary("C:\\Windows\\SysWOW64\\opengl32.dll");
    if (!openGLLibraryHandle) {
        openGLLibraryHandle = LoadLibrary("C:\\Windows\\System32\\opengl32.dll");
    }

    assert(openGLLibraryHandle);
    if (!openGLLibraryHandle) {
        MessageBox(0, "Cannot load library", "Cannot Load library OpenGL32.dll", MB_OK | MB_ICONSTOP);
        exit(EXIT_FAILURE);
    }

    LoadOpenGLPointers();
}

void* EnsurePointer(Entrypoint entryp) {
    if (g_DirectPointers[entryp] || LoadOpenGLExtPointer(entryp)) {
        return g_DirectPointers[entryp];
    } else {
        std::string error = "Operation aborted, because the ";
        error += GetEntryPointName(entryp);
        error += " function is not available on current context. Try updating GPU drivers.";
        throw std::runtime_error(error);
    }
}

<|endoftext|>


<commit_before>/*==========================================================================
               SeqAn - The Library for Sequence Analysis
                         http://www.seqan.de
  ============================================================================
  Copyright (C) 2007

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 3 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.
  ==========================================================================
  SeqCons -- Read alignment via realignment or MSA.
  ==========================================================================
  Author: Tobias Rausch <rausch@embl.de>
  ==========================================================================
*/

#include <seqan/basic.h>
#include <seqan/consensus.h>
#include <seqan/modifier.h>

#include <iostream>
#include <fstream>

#include <seqan/arg_parse.h>

using namespace seqan;

void
_setVersion(ArgumentParser & parser)
{
	::std::string rev = "$Revision: 4663 $";
	setVersion(parser, "0.23.1 Revision: " + rev.substr(11, 4) + "");
	setDate(parser, "Nov 21, 2012");
}

seqan::ArgumentParser::ParseResult parseCommandLine(ConsensusOptions & consOpt, int argc, const char * argv[])
{
    // Setup ArgumentParser.
    seqan::ArgumentParser parser("seqcons");
    _setVersion(parser);
    setShortDescription(parser, "Multi-read alignment.");
    addDescription(parser, "(c) Copyright 2009 by Tobias Rausch");
    setCategory(parser, "Sequence Alignment");

	addUsageLine(parser, "-r <FASTA file with reads> [Options]");
	addUsageLine(parser, "-a <AMOS message file> [Options]");
	addUsageLine(parser, "-s <Sam file> [-c <FASTA contigs file>] [Options]");

	addSection(parser, "Main Options:");
	addOption(parser, ArgParseOption("r", "reads", "file with reads", ArgParseArgument::INPUTFILE, "<FASTA reads file>"));
    setValidValues(parser, "reads", "fa fasta");
	addOption(parser, ArgParseOption("a", "afg", "message file", ArgParseArgument::INPUTFILE, "<AMOS afg file>"));
    setValidValues(parser, "afg", "afg");
	addOption(parser, ArgParseOption("s", "sam", "Sam file", ArgParseArgument::INPUTFILE, "<Sam file>"));
    setValidValues(parser, "s", "sam");
	addOption(parser, ArgParseOption("c", "contigs", "FASTA file with contigs, ignored if not Sam input", ArgParseArgument::INPUTFILE, "<FASTA contigs file>"));
    setValidValues(parser, "contigs", "fa fasta");
	addOption(parser, ArgParseOption("o", "outfile", "output filename", ArgParseArgument::OUTPUTFILE, "<Filename>"));
	setValidValues(parser, "outfile", "afg seqan cgb sam");
	setDefaultValue(parser, "outfile", "align.sam");

	addOption(parser, ArgParseOption("m", "method", "alignment method", ArgParseArgument::STRING, "realign", "[realign | msa]"));
	setDefaultValue(parser, "method", "realign");
	addOption(parser, ArgParseOption("b", "bandwidth", "bandwidth", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "bandwidth", "8");
    addOption(parser, ArgParseOption("n", "noalign", "no align, only convert input", ArgParseArgument::INTEGER, "<Bool>"));
    setDefaultValue(parser, "noalign", "0");

	addOption(parser, ArgParseOption("ma", "matchlength", "min. overlap length", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "matchlength", "15");
	addOption(parser, ArgParseOption("qu", "quality", "min. overlap precent identity", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "quality", "80");
	addOption(parser, ArgParseOption("ov", "overlaps", "min. number of overlaps per read", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "overlaps", "3");
	addOption(parser, ArgParseOption("wi", "window", "The window size.  If this parameter is greater than 0 then all overlaps within a given window are computed.", ArgParseArgument::INTEGER,"<Int>"));
	setDefaultValue(parser, "window", "0");

	addSection(parser, "ReAlign Method Options:");
	addOption(parser, ArgParseOption("in", "include", "include contig sequence", ArgParseArgument::INTEGER, "<Bool>"));
	setDefaultValue(parser, "include", "0");
	addOption(parser, ArgParseOption("rm", "rmethod", "realign method", ArgParseArgument::STRING, "[nw | gotoh]"));
	setDefaultValue(parser, "rmethod", "gotoh");

    // Parse command line.
    seqan::ArgumentParser::ParseResult res = seqan::parse(parser, argc, argv);

    // If parsing was not successful then exit with code 1 if there were errors.
    // Otherwise, exit with code 0 (e.g. help was printed).
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res;

	// Main options
	getOptionValue(consOpt.readsfile, parser, "reads");
	getOptionValue(consOpt.afgfile, parser, "afg");
	getOptionValue(consOpt.samfile, parser, "sam");
	getOptionValue(consOpt.contigsfile, parser, "contigs");
	getOptionValue(consOpt.outfile, parser, "outfile");

    if (empty(consOpt.samfile) && !empty(consOpt.contigsfile))
        std::cerr << "WARNING: Contigs specified by input is not FASTA, ignoring --contigs parameters." << std::endl;

    // Get lower case of the output file name.  File endings are accepted in both upper and lower case.
    CharString tmp = consOpt.outfile;
    toLower(tmp);

    if (endsWith(tmp, ".seqan"))
        consOpt.output = 0;
    else if (endsWith(tmp, ".afg"))
        consOpt.output = 1;
    else if (endsWith(tmp, ".frg"))
        consOpt.output = 2;
    else if (endsWith(tmp, ".cgb"))
        consOpt.output = 3;
    else if (endsWith(tmp, ".sam"))
        consOpt.output = 4;

    String<char> optionVal;
	getOptionValue(optionVal, parser, "method");
	if (optionVal == "realign")
        consOpt.method = 0;
	else if (optionVal == "msa")
        consOpt.method = 1;

	getOptionValue(consOpt.bandwidth, parser, "bandwidth");
#ifdef CELERA_OFFSET
	if (!isSetLong(parser, "bandwidth")) consOpt.bandwidth = 15;
#endif
    getOptionValue(consOpt.noalign, parser, "noalign");

	// MSA options
	getOptionValue(consOpt.matchlength, parser, "matchlength");
	getOptionValue(consOpt.quality, parser, "quality");
	getOptionValue(consOpt.overlaps, parser, "overlaps");
#ifdef CELERA_OFFSET
	if (!isSetLong(parser, "overlaps")) consOpt.overlaps = 5;
#endif
	getOptionValue(consOpt.window, parser, "window");

	// ReAlign options
	getOptionValue(consOpt.include, parser, "include");
	getOptionValue(optionVal, parser, "rmethod");
	if (optionVal == "nw")
        consOpt.rmethod = 0;
	else if (optionVal == "gotoh")
        consOpt.rmethod = 1;
    return seqan::ArgumentParser::PARSE_OK;

}

// Load the reads and layout positions
template <typename TFragmentStore, typename TSize>
int loadFiles(TFragmentStore & fragStore, TSize & numberOfContigs, ConsensusOptions const & consOpt)
{
//IOREV
    std::cerr << "Reading input..." << std::endl;
	if (!empty(consOpt.readsfile)) {
		// Load simple read file
        std::fstream strmReads(consOpt.readsfile.c_str(), std::fstream::in | std::fstream::binary);
		bool moveToFront = false;
		if (consOpt.noalign) moveToFront = true;
		if (_convertSimpleReadFile(strmReads, fragStore, consOpt.readsfile, moveToFront) != 0)
			return 1;
		numberOfContigs = 1;
	} else if (!empty(consOpt.afgfile)) {
		// Load Amos message file
        std::fstream strmReads(consOpt.afgfile.c_str(), std::fstream::in | std::fstream::binary);
		read(strmReads, fragStore, Amos());
		numberOfContigs = length(fragStore.contigStore);
	} else if (!empty(consOpt.samfile)) {
        // Possibly load contigs into fragment store.
        if (!empty(consOpt.contigsfile)) {
            if (!loadContigs(fragStore, consOpt.contigsfile.c_str())) {
                std::cerr << "Could not load contigs file " << consOpt.contigsfile.c_str() << std::endl;
                return 1;
            }
        }
		// Load Sam message file
        std::fstream strmReads(consOpt.samfile.c_str(), std::fstream::in | std::fstream::binary);
		read(strmReads, fragStore, Sam());
		numberOfContigs = length(fragStore.contigStore);
	} else {
		return 1;
	}

    return 0;
}

// Write resulting alignment.
template <typename TFragmentStore>
int writeOutput(TFragmentStore /*const*/ & fragStore, ConsensusOptions const & consOpt)
{
//IOREV
    std::cerr << "Writing output..." << std::endl;
	if (consOpt.output == 0) {
		// Write old SeqAn multi-read alignment format
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		write(strmWrite, fragStore, FastaReadFormat());
		fclose(strmWrite);
	} else if (consOpt.output == 1) {
		// Write Amos
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		write(strmWrite, fragStore, Amos());
		fclose(strmWrite);
	} else if (consOpt.output == 2) {
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		_writeCeleraFrg(strmWrite, fragStore);
		fclose(strmWrite);
	} else if (consOpt.output == 3) {
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		_writeCeleraCgb(strmWrite, fragStore);
		fclose(strmWrite);
	} else if (consOpt.output == 4) {
		// Write out resulting MSA in a Sam file.
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		write(strmWrite, fragStore, Sam());
		fclose(strmWrite);
		// Write out resulting consensus sequence.
		char buffer[10*1024];
		buffer[0] = '\0';
		strcat(buffer, consOpt.outfile.c_str());
		strcat(buffer, ".consensus.fasta");
		strmWrite = fopen(buffer, "w");
		writeContigs(strmWrite, fragStore, Fasta());
		fclose(strmWrite);
	}
    return 0;
}

int main(int argc, const char *argv[]) {
	// Command line parsing
	ArgumentParser parser;
	ConsensusOptions consOpt;

    seqan::ArgumentParser::ParseResult res = parseCommandLine(consOpt, argc, argv);
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res == seqan::ArgumentParser::PARSE_ERROR;

	// Create a new fragment store
	typedef FragmentStore<> TFragmentStore;
	typedef Size<TFragmentStore>::Type TSize;
	TFragmentStore fragStore;

	// Load the reads and layout positions
	TSize numberOfContigs = 0;
    int ret = loadFiles(fragStore, numberOfContigs, consOpt);

	// Multi-realignment desired or just conversion of the input
	if (!consOpt.noalign) {
		// Iterate over all contigs
        if (consOpt.method == 0)
            std::cerr << "Performing realignment..." << std::endl;
        else
            std::cerr << "Performing consensus alignment..." << std::endl;
		for (TSize currentContig = 0; currentContig < numberOfContigs; ++currentContig) {
            std::cerr << "contig " << (currentContig + 1) << "/" << numberOfContigs << std::endl;
			if (consOpt.method == 0) {
				Score<int, WeightedConsensusScore<Score<int, FractionalScore>, Score<int, ConsensusScore> > > combinedScore;
				reAlign(fragStore, combinedScore, currentContig, consOpt.rmethod, consOpt.bandwidth, consOpt.include);
				if (consOpt.include) reAlign(fragStore, combinedScore, currentContig, consOpt.rmethod, consOpt.bandwidth, false);
			} else {
                std::cerr << "Performing consensus alignment..." << std::endl;
				// Import all reads of the given contig
				typedef TFragmentStore::TReadSeq TReadSeq;
				StringSet<TReadSeq, Owner<> > readSet;
				String<Pair<TSize, TSize> > begEndPos;
				_loadContigReads(readSet, begEndPos, fragStore, currentContig);
				if (!length(readSet)) continue;

				// Align the reads
				typedef StringSet<TReadSeq, Dependent<> > TStringSet;
				typedef Graph<Alignment<TStringSet, void, WithoutEdgeId> > TAlignGraph;
				TAlignGraph gOut(readSet);
				consensusAlignment(gOut, begEndPos, consOpt);

				// Update the contig in the fragment store
				if (!empty(gOut)) updateContig(fragStore, gOut, currentContig);
				clear(gOut);

				//// Debug code for CA
				//mtRandInit();
				//String<char> fileTmp1 = "tmp1";
				//String<char> fileTmp2 = "tmp2";
				//for(int i = 0; i<10; ++i) {
				//	int file = (mtRand() % 20) + 65;
				//	appendValue(fileTmp1, char(file));
				//	appendValue(fileTmp2, char(file));
				//}
				//std::fstream strm3;
				//strm3.open(toCString(fileTmp2), std::ios_base::out | std::ios_base::trunc);
				//for(int i = 0;i<(int) length(origStrSet); ++i) {
				//	std::stringstream name;
				//	name << value(begEndPos, i).i1 << "," << value(begEndPos, i).i2;
				//	String<char> myTitle = name.str();
				//	write(strm3, origStrSet[i], myTitle, Fasta());
				//	if (value(begEndPos, i).i1 > value(begEndPos, i).i2) reverseComplement(origStrSet[i]);
				//}
				//strm3.close();
			}
		} // end loop over all contigs
	}

    // Write result.
    ret = writeOutput(fragStore, consOpt);
    return ret;
}
<commit_msg>[CLI] Fixing CLI arguments with seqcons.<commit_after>/*==========================================================================
               SeqAn - The Library for Sequence Analysis
                         http://www.seqan.de
  ============================================================================
  Copyright (C) 2007

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 3 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.
  ==========================================================================
  SeqCons -- Read alignment via realignment or MSA.
  ==========================================================================
  Author: Tobias Rausch <rausch@embl.de>
  ==========================================================================
*/

#include <seqan/basic.h>
#include <seqan/consensus.h>
#include <seqan/modifier.h>

#include <iostream>
#include <fstream>

#include <seqan/arg_parse.h>

using namespace seqan;

void
_setVersion(ArgumentParser & parser)
{
	::std::string rev = "$Revision: 4663 $";
	setVersion(parser, "0.23.1 Revision: " + rev.substr(11, 4) + "");
	setDate(parser, "Nov 21, 2012");
}

seqan::ArgumentParser::ParseResult parseCommandLine(ConsensusOptions & consOpt, int argc, const char * argv[])
{
    // Setup ArgumentParser.
    seqan::ArgumentParser parser("seqcons");
    _setVersion(parser);
    setShortDescription(parser, "Multi-read alignment.");
    addDescription(parser, "(c) Copyright 2009 by Tobias Rausch");
    setCategory(parser, "Sequence Alignment");

	addUsageLine(parser, "-r <FASTA file with reads> [Options]");
	addUsageLine(parser, "-a <AMOS message file> [Options]");
	addUsageLine(parser, "-s <Sam file> [-c <FASTA contigs file>] [Options]");

	addSection(parser, "Main Options:");
	addOption(parser, ArgParseOption("r", "reads", "file with reads", ArgParseArgument::INPUTFILE, "<FASTA reads file>"));
    setValidValues(parser, "reads", "fa fasta");
	addOption(parser, ArgParseOption("a", "afg", "message file", ArgParseArgument::INPUTFILE, "<AMOS afg file>"));
    setValidValues(parser, "afg", "afg");
	addOption(parser, ArgParseOption("s", "sam", "Sam file", ArgParseArgument::INPUTFILE, "<Sam file>"));
    setValidValues(parser, "s", "sam");
	addOption(parser, ArgParseOption("c", "contigs", "FASTA file with contigs, ignored if not Sam input", ArgParseArgument::INPUTFILE, "<FASTA contigs file>"));
    setValidValues(parser, "contigs", "fa fasta");
	addOption(parser, ArgParseOption("o", "outfile", "output filename", ArgParseArgument::OUTPUTFILE, "<Filename>"));
	setValidValues(parser, "outfile", "afg seqan cgb sam");
	setDefaultValue(parser, "outfile", "align.sam");

	addOption(parser, ArgParseOption("m", "method", "alignment method", ArgParseArgument::STRING, "realign", "[realign | msa]"));
	setDefaultValue(parser, "method", "realign");
	addOption(parser, ArgParseOption("b", "bandwidth", "bandwidth", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "bandwidth", "8");
    addOption(parser, ArgParseOption("n", "noalign", "no align, only convert input"));

	addOption(parser, ArgParseOption("ma", "matchlength", "min. overlap length", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "matchlength", "15");
	addOption(parser, ArgParseOption("qu", "quality", "min. overlap precent identity", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "quality", "80");
	addOption(parser, ArgParseOption("ov", "overlaps", "min. number of overlaps per read", ArgParseArgument::INTEGER, "<Int>"));
	setDefaultValue(parser, "overlaps", "3");
	addOption(parser, ArgParseOption("wi", "window", "The window size.  If this parameter is greater than 0 then all overlaps within a given window are computed.", ArgParseArgument::INTEGER,"<Int>"));
	setDefaultValue(parser, "window", "0");

	addSection(parser, "ReAlign Method Options:");
	addOption(parser, ArgParseOption("in", "include", "include contig sequence"));
	addOption(parser, ArgParseOption("rm", "rmethod", "realign method", ArgParseArgument::STRING, "[nw | gotoh]"));
	setDefaultValue(parser, "rmethod", "gotoh");

    // Parse command line.
    seqan::ArgumentParser::ParseResult res = seqan::parse(parser, argc, argv);

    // If parsing was not successful then exit with code 1 if there were errors.
    // Otherwise, exit with code 0 (e.g. help was printed).
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res;

	// Main options
	getOptionValue(consOpt.readsfile, parser, "reads");
	getOptionValue(consOpt.afgfile, parser, "afg");
	getOptionValue(consOpt.samfile, parser, "sam");
	getOptionValue(consOpt.contigsfile, parser, "contigs");
	getOptionValue(consOpt.outfile, parser, "outfile");

    if (empty(consOpt.samfile) && !empty(consOpt.contigsfile))
        std::cerr << "WARNING: Contigs specified by input is not FASTA, ignoring --contigs parameters." << std::endl;

    // Get lower case of the output file name.  File endings are accepted in both upper and lower case.
    CharString tmp = consOpt.outfile;
    toLower(tmp);

    if (endsWith(tmp, ".seqan"))
        consOpt.output = 0;
    else if (endsWith(tmp, ".afg"))
        consOpt.output = 1;
    else if (endsWith(tmp, ".frg"))
        consOpt.output = 2;
    else if (endsWith(tmp, ".cgb"))
        consOpt.output = 3;
    else if (endsWith(tmp, ".sam"))
        consOpt.output = 4;

    String<char> optionVal;
	getOptionValue(optionVal, parser, "method");
	if (optionVal == "realign")
        consOpt.method = 0;
	else if (optionVal == "msa")
        consOpt.method = 1;

	getOptionValue(consOpt.bandwidth, parser, "bandwidth");
#ifdef CELERA_OFFSET
	if (!isSetLong(parser, "bandwidth")) consOpt.bandwidth = 15;
#endif
    getOptionValue(consOpt.noalign, parser, "noalign");

	// MSA options
	getOptionValue(consOpt.matchlength, parser, "matchlength");
	getOptionValue(consOpt.quality, parser, "quality");
	getOptionValue(consOpt.overlaps, parser, "overlaps");
#ifdef CELERA_OFFSET
	if (!isSetLong(parser, "overlaps")) consOpt.overlaps = 5;
#endif
	getOptionValue(consOpt.window, parser, "window");

	// ReAlign options
	getOptionValue(consOpt.include, parser, "include");
	getOptionValue(optionVal, parser, "rmethod");
	if (optionVal == "nw")
        consOpt.rmethod = 0;
	else if (optionVal == "gotoh")
        consOpt.rmethod = 1;
    return seqan::ArgumentParser::PARSE_OK;

}

// Load the reads and layout positions
template <typename TFragmentStore, typename TSize>
int loadFiles(TFragmentStore & fragStore, TSize & numberOfContigs, ConsensusOptions const & consOpt)
{
//IOREV
    std::cerr << "Reading input..." << std::endl;
	if (!empty(consOpt.readsfile)) {
		// Load simple read file
        std::fstream strmReads(consOpt.readsfile.c_str(), std::fstream::in | std::fstream::binary);
		bool moveToFront = false;
		if (consOpt.noalign) moveToFront = true;
		if (_convertSimpleReadFile(strmReads, fragStore, consOpt.readsfile, moveToFront) != 0)
			return 1;
		numberOfContigs = 1;
	} else if (!empty(consOpt.afgfile)) {
		// Load Amos message file
        std::fstream strmReads(consOpt.afgfile.c_str(), std::fstream::in | std::fstream::binary);
		read(strmReads, fragStore, Amos());
		numberOfContigs = length(fragStore.contigStore);
	} else if (!empty(consOpt.samfile)) {
        // Possibly load contigs into fragment store.
        if (!empty(consOpt.contigsfile)) {
            if (!loadContigs(fragStore, consOpt.contigsfile.c_str())) {
                std::cerr << "Could not load contigs file " << consOpt.contigsfile.c_str() << std::endl;
                return 1;
            }
        }
		// Load Sam message file
        std::fstream strmReads(consOpt.samfile.c_str(), std::fstream::in | std::fstream::binary);
		read(strmReads, fragStore, Sam());
		numberOfContigs = length(fragStore.contigStore);
	} else {
		return 1;
	}

    return 0;
}

// Write resulting alignment.
template <typename TFragmentStore>
int writeOutput(TFragmentStore /*const*/ & fragStore, ConsensusOptions const & consOpt)
{
//IOREV
    std::cerr << "Writing output..." << std::endl;
	if (consOpt.output == 0) {
		// Write old SeqAn multi-read alignment format
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		write(strmWrite, fragStore, FastaReadFormat());
		fclose(strmWrite);
	} else if (consOpt.output == 1) {
		// Write Amos
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		write(strmWrite, fragStore, Amos());
		fclose(strmWrite);
	} else if (consOpt.output == 2) {
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		_writeCeleraFrg(strmWrite, fragStore);
		fclose(strmWrite);
	} else if (consOpt.output == 3) {
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		_writeCeleraCgb(strmWrite, fragStore);
		fclose(strmWrite);
	} else if (consOpt.output == 4) {
		// Write out resulting MSA in a Sam file.
		FILE* strmWrite = fopen(consOpt.outfile.c_str(), "w");
		write(strmWrite, fragStore, Sam());
		fclose(strmWrite);
		// Write out resulting consensus sequence.
		char buffer[10*1024];
		buffer[0] = '\0';
		strcat(buffer, consOpt.outfile.c_str());
		strcat(buffer, ".consensus.fasta");
		strmWrite = fopen(buffer, "w");
		writeContigs(strmWrite, fragStore, Fasta());
		fclose(strmWrite);
	}
    return 0;
}

int main(int argc, const char *argv[]) {
	// Command line parsing
	ArgumentParser parser;
	ConsensusOptions consOpt;

    seqan::ArgumentParser::ParseResult res = parseCommandLine(consOpt, argc, argv);
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res == seqan::ArgumentParser::PARSE_ERROR;

	// Create a new fragment store
	typedef FragmentStore<> TFragmentStore;
	typedef Size<TFragmentStore>::Type TSize;
	TFragmentStore fragStore;

	// Load the reads and layout positions
	TSize numberOfContigs = 0;
    int ret = loadFiles(fragStore, numberOfContigs, consOpt);

	// Multi-realignment desired or just conversion of the input
	if (!consOpt.noalign) {
		// Iterate over all contigs
        if (consOpt.method == 0)
            std::cerr << "Performing realignment..." << std::endl;
        else
            std::cerr << "Performing consensus alignment..." << std::endl;
		for (TSize currentContig = 0; currentContig < numberOfContigs; ++currentContig) {
            std::cerr << "contig " << (currentContig + 1) << "/" << numberOfContigs << std::endl;
			if (consOpt.method == 0) {
				Score<int, WeightedConsensusScore<Score<int, FractionalScore>, Score<int, ConsensusScore> > > combinedScore;
				reAlign(fragStore, combinedScore, currentContig, consOpt.rmethod, consOpt.bandwidth, consOpt.include);
				if (consOpt.include) reAlign(fragStore, combinedScore, currentContig, consOpt.rmethod, consOpt.bandwidth, false);
			} else {
                std::cerr << "Performing consensus alignment..." << std::endl;
				// Import all reads of the given contig
				typedef TFragmentStore::TReadSeq TReadSeq;
				StringSet<TReadSeq, Owner<> > readSet;
				String<Pair<TSize, TSize> > begEndPos;
				_loadContigReads(readSet, begEndPos, fragStore, currentContig);
				if (!length(readSet)) continue;

				// Align the reads
				typedef StringSet<TReadSeq, Dependent<> > TStringSet;
				typedef Graph<Alignment<TStringSet, void, WithoutEdgeId> > TAlignGraph;
				TAlignGraph gOut(readSet);
				consensusAlignment(gOut, begEndPos, consOpt);

				// Update the contig in the fragment store
				if (!empty(gOut)) updateContig(fragStore, gOut, currentContig);
				clear(gOut);

				//// Debug code for CA
				//mtRandInit();
				//String<char> fileTmp1 = "tmp1";
				//String<char> fileTmp2 = "tmp2";
				//for(int i = 0; i<10; ++i) {
				//	int file = (mtRand() % 20) + 65;
				//	appendValue(fileTmp1, char(file));
				//	appendValue(fileTmp2, char(file));
				//}
				//std::fstream strm3;
				//strm3.open(toCString(fileTmp2), std::ios_base::out | std::ios_base::trunc);
				//for(int i = 0;i<(int) length(origStrSet); ++i) {
				//	std::stringstream name;
				//	name << value(begEndPos, i).i1 << "," << value(begEndPos, i).i2;
				//	String<char> myTitle = name.str();
				//	write(strm3, origStrSet[i], myTitle, Fasta());
				//	if (value(begEndPos, i).i1 > value(begEndPos, i).i2) reverseComplement(origStrSet[i]);
				//}
				//strm3.close();
			}
		} // end loop over all contigs
	}

    // Write result.
    ret = writeOutput(fragStore, consOpt);
    return ret;
}
<|endoftext|>