<commit_before>#include <opengl/draw_info.hpp>
#include <stlw/algorithm.hpp>

#include <iostream>

using namespace boomhs;
namespace opengl
{

////////////////////////////////////////////////////////////////////////////////////////////////////
// BufferHandles
BufferHandles::BufferHandles()
{
  glGenBuffers(NUM_BUFFERS, &vbo_);
  glGenBuffers(NUM_BUFFERS, &ebo_);
}

BufferHandles::~BufferHandles()
{
  glDeleteBuffers(NUM_BUFFERS, &ebo_);
  glDeleteBuffers(NUM_BUFFERS, &vbo_);
}

  // move-construction OK.
BufferHandles::BufferHandles(BufferHandles &&other)
    : vbo_(other.vbo_)
    , ebo_(other.ebo_)
{
  other.vbo_ = 0;
  other.ebo_ = 0;
}

BufferHandles&
BufferHandles::operator=(BufferHandles &&other)
{
  vbo_ = MOVE(other.vbo_);
  ebo_ = MOVE(other.ebo_);

  other.vbo_ = 0;
  other.ebo_ = 0;
  return *this;
}

std::string
BufferHandles::to_string() const
{
  return fmt::format("vbo: {}, ebo: {}", vbo(), ebo());
}

std::ostream&
operator<<(std::ostream &stream, BufferHandles const& buffers)
{
  stream << buffers.to_string();
  return stream;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// DrawInfo
DrawInfo::DrawInfo(size_t const num_vertexes, GLuint const num_indices)
  : num_vertexes_(num_vertexes)
  , num_indices_(num_indices)
{
}

DrawInfo::DrawInfo(DrawInfo &&other)
  : num_vertexes_(other.num_vertexes_)
  , num_indices_(other.num_indices_)
  , handles_(MOVE(other.handles_))
  , vao_(MOVE(other.vao_))
{
}

DrawInfo&
DrawInfo::operator=(DrawInfo &&other)
{
  num_vertexes_ = other.num_vertexes_;
  num_indices_ = other.num_indices_;
  other.num_vertexes_ = 0;
  other.num_indices_ = 0;

  handles_ = MOVE(other.handles_);
  vao_ = MOVE(other.vao_);
  return *this;
}

std::string
DrawInfo::to_string() const
{
  auto const& dinfo = *this;

  std::string result;
  result += fmt::format("NumIndices: {} ", dinfo.num_indices());
  result += "VAO: " + dinfo.vao_.to_string() + " ";
  result += "BufferHandles: {" + dinfo.handles_.to_string() + "} ";
  //auto const num_indices = dinfo.num_indices();

  // TODO: maybe need to bind the element buffer before calling glMapBuffer?
  /*
  {
    auto const target = GL_ELEMENT_ARRAY_BUFFER;
    GLuint const*const pmem = static_cast<GLuint const*const>(glMapBuffer(target, GL_READ_ONLY));
    assert(pmem);
    ON_SCOPE_EXIT([]() { assert(true == glUnmapBuffer((target))); });

    FOR(i, num_indices) {
      // (void* + GLuint) -> GLuint*
      GLuint const* p_element = pmem + i;
      result += std::to_string(*p_element) + " ";
    }
    result += "\n";
  }
  */

  /*
  auto const stride = va.stride();
  auto const num_vertexes = dinfo.num_vertexes();

  auto const target = GL_ARRAY_BUFFER;
  GLfloat *pmem = static_cast<GLfloat *>(glMapBuffer(target, GL_READ_ONLY));
  assert(pmem);
  ON_SCOPE_EXIT([]() { assert(glUnmapBuffer(target)); });

  result += fmt::format("vbo id: {} VBO contents:\n", dinfo.vbo());
  result += "VBO stride: '" + std::to_string(stride) + "'\n";
  result += "VBO num_vertexes: '" + std::to_string(num_vertexes) + "'\n";
  result += "VBO contents:\n";

  auto count{0};
  for(auto i = 0u; i < num_vertexes; ++i, ++count) {
    if (count == stride) {
      count = 0;
      result += "\n";
    } else if (i > 0) {
      result += " ";
    }
    result += std::to_string(*(pmem + i));
  }
  */
  return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// EntityDrawHandleMap
size_t
EntityDrawHandleMap::add(EntityID const entity, opengl::DrawInfo &&di)
{
  auto const pos = drawinfos_.size();
  drawinfos_.emplace_back(MOVE(di));
  entities_.emplace_back(entity);

  // return the index di was stored in.
  return pos;
}

#define LOOKUP_IMPLEMENTATION                                                                      \
  FOR(i, entities_.size()) {                                                                       \
    if (entities_[i] == entity) {                                                                  \
      return &drawinfos_[i];                                                                       \
    }                                                                                \
  }                                                                                \
  return nullptr;

opengl::DrawInfo*
EntityDrawHandleMap::lookup(stlw::Logger &logger, EntityID const entity)
{
  LOOKUP_IMPLEMENTATION
}

opengl::DrawInfo const*
EntityDrawHandleMap::lookup(stlw::Logger &logger, EntityID const entity) const
{
  LOOKUP_IMPLEMENTATION
}
#undef LOOKUP_IMPLEMENTATION

////////////////////////////////////////////////////////////////////////////////////////////////////
// DrawHandleManager
void
DrawHandleManager::add_entity(EntityID const eid, DrawInfo&& dinfo)
{
  entities_.add(eid, MOVE(dinfo));
}

void
DrawHandleManager::add_bbox(EntityID const eid, DrawInfo&& dinfo)
{
  bboxes_.add(eid, MOVE(dinfo));
}

EntityDrawHandleMap &
DrawHandleManager::entities()
{
  return entities_;
}

EntityDrawHandleMap const&
DrawHandleManager::entities() const
{
  return entities_;
}

EntityDrawHandleMap&
DrawHandleManager::bbox_entities()
{
  return bboxes_;
}

EntityDrawHandleMap const&
DrawHandleManager::bbox_entities() const
{
  return bboxes_;
}

// TODO: When the maps can be indexed by a single identifier (right now they cannot, as the
// EntityID is duplicated in both DrawHandle maps (regular entities and bbox entities).
// Once complete, this macro should look through the various maps for the matching eid.
#define LOOKUP_MANAGER_IMPL(MAP)                                                                   \
  auto *p = MAP.lookup(logger, eid);                                                               \
  if (p) {                                                                                \
    return *p;                                                                                \
  }                                                                                \
  LOG_ERROR_FMT("Error could not find entity drawinfo associated to entity {}", eid);              \
  std::abort();                                                                                \
  return *p;

DrawInfo&
DrawHandleManager::lookup_entity(stlw::Logger& logger, EntityID const eid)
{
  LOOKUP_MANAGER_IMPL(entities());
}

DrawInfo const&
DrawHandleManager::lookup_entity(stlw::Logger& logger, EntityID const eid) const
{
  LOOKUP_MANAGER_IMPL(entities());
}

DrawInfo&
DrawHandleManager::lookup_bbox(stlw::Logger& logger, EntityID const eid)
{
  LOOKUP_MANAGER_IMPL(bbox_entities());
}

DrawInfo const&
DrawHandleManager::lookup_bbox(stlw::Logger& logger, EntityID const eid) const
{
  LOOKUP_MANAGER_IMPL(bbox_entities());
}
#undef LOOKUP_MANAGER_IMPL

} // ns opengl
<commit_msg>cleanup<commit_after>#include <opengl/draw_info.hpp>
#include <stlw/algorithm.hpp>

#include <iostream>

using namespace boomhs;
namespace opengl
{

////////////////////////////////////////////////////////////////////////////////////////////////////
// BufferHandles
BufferHandles::BufferHandles()
{
  glGenBuffers(NUM_BUFFERS, &vbo_);
  glGenBuffers(NUM_BUFFERS, &ebo_);
}

BufferHandles::~BufferHandles()
{
  glDeleteBuffers(NUM_BUFFERS, &ebo_);
  glDeleteBuffers(NUM_BUFFERS, &vbo_);
}

  // move-construction OK.
BufferHandles::BufferHandles(BufferHandles &&other)
    : vbo_(other.vbo_)
    , ebo_(other.ebo_)
{
  assert(this != &other);

  other.vbo_ = 0;
  other.ebo_ = 0;
}

BufferHandles&
BufferHandles::operator=(BufferHandles &&other)
{
  assert(this != &other);

  vbo_ = MOVE(other.vbo_);
  ebo_ = MOVE(other.ebo_);

  other.vbo_ = 0;
  other.ebo_ = 0;
  return *this;
}

std::string
BufferHandles::to_string() const
{
  return fmt::format("vbo: {}, ebo: {}", vbo(), ebo());
}

std::ostream&
operator<<(std::ostream &stream, BufferHandles const& buffers)
{
  stream << buffers.to_string();
  return stream;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// DrawInfo
DrawInfo::DrawInfo(size_t const num_vertexes, GLuint const num_indices)
  : num_vertexes_(num_vertexes)
  , num_indices_(num_indices)
{
}

DrawInfo::DrawInfo(DrawInfo &&other)
  : num_vertexes_(other.num_vertexes_)
  , num_indices_(other.num_indices_)
  , handles_(MOVE(other.handles_))
  , vao_(MOVE(other.vao_))
{
  assert(this != &other);
}

DrawInfo&
DrawInfo::operator=(DrawInfo &&other)
{
  assert(this != &other);

  num_vertexes_ = other.num_vertexes_;
  num_indices_ = other.num_indices_;
  other.num_vertexes_ = 0;
  other.num_indices_ = 0;

  handles_ = MOVE(other.handles_);
  vao_ = MOVE(other.vao_);
  return *this;
}

std::string
DrawInfo::to_string() const
{
  auto const& dinfo = *this;

  std::string result;
  result += fmt::format("NumIndices: {} ", dinfo.num_indices());
  result += "VAO: " + dinfo.vao_.to_string() + " ";
  result += "BufferHandles: {" + dinfo.handles_.to_string() + "} ";
  //auto const num_indices = dinfo.num_indices();

  // TODO: maybe need to bind the element buffer before calling glMapBuffer?
  /*
  {
    auto const target = GL_ELEMENT_ARRAY_BUFFER;
    GLuint const*const pmem = static_cast<GLuint const*const>(glMapBuffer(target, GL_READ_ONLY));
    assert(pmem);
    ON_SCOPE_EXIT([]() { assert(true == glUnmapBuffer((target))); });

    FOR(i, num_indices) {
      // (void* + GLuint) -> GLuint*
      GLuint const* p_element = pmem + i;
      result += std::to_string(*p_element) + " ";
    }
    result += "\n";
  }
  */

  /*
  auto const stride = va.stride();
  auto const num_vertexes = dinfo.num_vertexes();

  auto const target = GL_ARRAY_BUFFER;
  GLfloat *pmem = static_cast<GLfloat *>(glMapBuffer(target, GL_READ_ONLY));
  assert(pmem);
  ON_SCOPE_EXIT([]() { assert(glUnmapBuffer(target)); });

  result += fmt::format("vbo id: {} VBO contents:\n", dinfo.vbo());
  result += "VBO stride: '" + std::to_string(stride) + "'\n";
  result += "VBO num_vertexes: '" + std::to_string(num_vertexes) + "'\n";
  result += "VBO contents:\n";

  auto count{0};
  for(auto i = 0u; i < num_vertexes; ++i, ++count) {
    if (count == stride) {
      count = 0;
      result += "\n";
    } else if (i > 0) {
      result += " ";
    }
    result += std::to_string(*(pmem + i));
  }
  */
  return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// EntityDrawHandleMap
size_t
EntityDrawHandleMap::add(EntityID const eid, opengl::DrawInfo &&di)
{
  auto const pos = drawinfos_.size();
  drawinfos_.emplace_back(MOVE(di));
  entities_.emplace_back(eid);

  // return the index di was stored in.
  return pos;
}

#define LOOKUP_IMPLEMENTATION                                                                      \
  FOR(i, entities_.size()) {                                                                       \
    if (entities_[i] == eid) {                                                                     \
      return &drawinfos_[i];                                                                       \
    }                                                                                \
  }                                                                                \
  return nullptr;

opengl::DrawInfo*
EntityDrawHandleMap::lookup(stlw::Logger &logger, EntityID const eid)
{
  LOOKUP_IMPLEMENTATION
}

opengl::DrawInfo const*
EntityDrawHandleMap::lookup(stlw::Logger &logger, EntityID const eid) const
{
  LOOKUP_IMPLEMENTATION
}
#undef LOOKUP_IMPLEMENTATION

////////////////////////////////////////////////////////////////////////////////////////////////////
// DrawHandleManager
void
DrawHandleManager::add_entity(EntityID const eid, DrawInfo&& dinfo)
{
  entities_.add(eid, MOVE(dinfo));
}

void
DrawHandleManager::add_bbox(EntityID const eid, DrawInfo&& dinfo)
{
  bboxes_.add(eid, MOVE(dinfo));
}

EntityDrawHandleMap &
DrawHandleManager::entities()
{
  return entities_;
}

EntityDrawHandleMap const&
DrawHandleManager::entities() const
{
  return entities_;
}

EntityDrawHandleMap&
DrawHandleManager::bbox_entities()
{
  return bboxes_;
}

EntityDrawHandleMap const&
DrawHandleManager::bbox_entities() const
{
  return bboxes_;
}

// TODO: When the maps can be indexed by a single identifier (right now they cannot, as the
// EntityID is duplicated in both DrawHandle maps (regular entities and bbox entities).
// Once complete, this macro should look through the various maps for the matching eid.
#define LOOKUP_MANAGER_IMPL(MAP)                                                                   \
  auto *p = MAP.lookup(logger, eid);                                                               \
  if (p) {                                                                                \
    return *p;                                                                                \
  }                                                                                \
  LOG_ERROR_FMT("Error could not find entity drawinfo associated to entity {}", eid);              \
  std::abort();                                                                                \
  return *p;

DrawInfo&
DrawHandleManager::lookup_entity(stlw::Logger& logger, EntityID const eid)
{
  LOOKUP_MANAGER_IMPL(entities());
}

DrawInfo const&
DrawHandleManager::lookup_entity(stlw::Logger& logger, EntityID const eid) const
{
  LOOKUP_MANAGER_IMPL(entities());
}

DrawInfo&
DrawHandleManager::lookup_bbox(stlw::Logger& logger, EntityID const eid)
{
  LOOKUP_MANAGER_IMPL(bbox_entities());
}

DrawInfo const&
DrawHandleManager::lookup_bbox(stlw::Logger& logger, EntityID const eid) const
{
  LOOKUP_MANAGER_IMPL(bbox_entities());
}
#undef LOOKUP_MANAGER_IMPL

} // ns opengl
<|endoftext|>


<commit_before>/*
* Copyright (C) 2015 German Aerospace Center (DLR/SC)
*
* This file was created by OpenCASCADE for the German Aerospace Center.
* It will reside in TiGL, until this Algorithm becomes part of
* OpenCASCADE.
*
* For now, the file will be licensed under the Apache License, Version 2.0.
*    http://www.apache.org/licenses/LICENSE-2.0
*/

#ifndef _MakePatches_HeaderFile
#define _MakePatches_HeaderFile

#include <tigl_internal.h>

#include <TopoDS_Shape.hxx>
#include <Standard_Real.hxx>
#include <GeomFill_FillingStyle.hxx>
#include <Handle_Geom_Surface.hxx>
#include <Standard_Integer.hxx>
#include <Standard.hxx>

/**
 * \brief Return code of make patches algorithm
 * MAKEPATCHES_OK : Algorithm successful
 * MAKEPATCHES_FAIL_INTERSECTION : Algorithm failed during intersection of guides and profiles
 * MAKEPATCHES_FAIL_PATCHES : Algorithm failed due to failure in MakeLoops algorithm
 */
enum MakePatchesStatus
{
    MAKEPATCHES_OK                 = 0,
    MAKEPATCHES_FAIL_INTERSECTION  = 1,
    MAKEPATCHES_FAIL_PATCHES       = 2
};

class TopoDS_Shape;
class Handle_Geom_BSplineSurface;
class TColGeom_SequenceOfBoundedCurve;

/**
 * Implementation of algorithm for filling 4-sides closed frames\n
 * of edges with Coons surfaces to get faces.
 * Then faces can be joined in shell
 */

class MakePatches
{

public:

    void* operator new(size_t,void* anAddress)
    {
        return anAddress;
    }
    void* operator new(size_t size)
    {
        return Standard::Allocate(size);
    }
    void  operator delete(void* anAddress)
    {
        if (anAddress) {
            Standard::Free((Standard_Address&)anAddress);
        }
    }
// Methods PUBLIC
//

    /**
     * Empty constructop
     */

    TIGL_EXPORT MakePatches();

    /**
     * Constructor with initialisation of data
     * @param theGuides
     * compound consisting of guide edges or wires.
     * @param theProfiles
     * compound consisting of profile (section) edges or wires
     */
    TIGL_EXPORT MakePatches(const TopoDS_Shape& theGuides, const TopoDS_Shape& theProfiles);

    /**
     * Method for initialisation of data
     * @param theGuides
     * compound consisting of guide edges or wires.
     * @param theProfiles
     * compound consisting of profile (section) edges or wires
     */
    TIGL_EXPORT   void Init(const TopoDS_Shape& theGuides, const TopoDS_Shape& theProfiles) ;

    /**
     * Perform building patches
     * @param theTolConf
     * Absolute tolerance for checking coincidence of ends of curves.\n
     * This tolerance is used also by sewing algorithm
     * @param theTolParam
     * Relative tolerance for comparing knots of opposite curves\n
     * If k1 and k2 are values of corresponding knots of opposite curves C1 and C2 \n
     * then k1 ~= k2 if Abs(k1-k2)/((k1+k2)/2) <= theTolParam
     * @param theStyle
     * The style of filling, to provide C2 continuity between patches it is necessary using\n
     * GeomFill_CoonsC2Style
     * @param theSewing
     * Boolean flag that enable/disable sewing of patches
     */
    TIGL_EXPORT   void Perform(const Standard_Real theTolConf,
                               const Standard_Real theTolParam,
                               const GeomFill_FillingStyle theStyle = GeomFill_CoonsStyle,
                               const Standard_Boolean theSewing = Standard_True);

    TIGL_EXPORT   void Perform2(const Standard_Real theTolConf,
                               const Standard_Real theTolParam,
                               const GeomFill_FillingStyle theStyle = GeomFill_CoonsStyle,
                               const Standard_Boolean theSewing = Standard_True,
                               bool Wing = false);
    /**
     * Returns result
     * Result can be compound pf faces or shell depending on value of theSewing
     */

    TIGL_EXPORT  const TopoDS_Shape& Patches() const;

    /**
     * Method for building surface by filling 4-side closed contour consisting of 4 curves
     * @param theCurves
     * The sequence of curves for storing closed contour of curves
     * @param theTolConf
     * Absolute tolerance for checking coincidence of ends of curves.
     * @param theTolParam
     * Relative tolerance for comparing knots of opposite curves\n
     * If k1 and k2 are values of corresponding knots of opposite curves C1 and C2 \n
     * then k1 ~= k2 if Abs(k1-k2)/((k1+k2)/2) <= theTolParam
     * @param theBaseCurve
     * The index in sequence theCurves, which define first curve in contour\n
     * this index has effect on origin and UV direction of result surface
     * @param theStyle
     * The style of filling, to provide C2 continuity between patches it is necessary using\n
     * GeomFill_CoonsC2Style
     */
    TIGL_EXPORT static  Handle_Geom_BSplineSurface
    BuildSurface(const TColGeom_SequenceOfBoundedCurve& theCurves,
                 const Standard_Real theTolConf,
                 const Standard_Real theTolParam,
                 const Standard_Integer theBaseCurve = 1,
                 const GeomFill_FillingStyle theStyle = GeomFill_CoonsStyle);
    /**
     * Returns status of calculations\n
     */

    TIGL_EXPORT MakePatchesStatus GetStatus() const;

protected:

// Methods PROTECTED
//

// Fields PROTECTED
//

private:

// Methods PRIVATE
//

// Fields PRIVATE
//
    TopoDS_Shape myGuides;
    TopoDS_Shape myProfiles;
    TopoDS_Shape myGrid;
    TopoDS_Shape myPatches;
    MakePatchesStatus myStatus;

};

// other Inline functions and methods (like "C++: function call" methods)
//

#endif
<commit_msg>Removed unused function<commit_after>/*
* Copyright (C) 2015 German Aerospace Center (DLR/SC)
*
* This file was created by OpenCASCADE for the German Aerospace Center.
* It will reside in TiGL, until this Algorithm becomes part of
* OpenCASCADE.
*
* For now, the file will be licensed under the Apache License, Version 2.0.
*    http://www.apache.org/licenses/LICENSE-2.0
*/

#ifndef _MakePatches_HeaderFile
#define _MakePatches_HeaderFile

#include <tigl_internal.h>

#include <TopoDS_Shape.hxx>
#include <Standard_Real.hxx>
#include <GeomFill_FillingStyle.hxx>
#include <Handle_Geom_Surface.hxx>
#include <Standard_Integer.hxx>
#include <Standard.hxx>

/**
 * \brief Return code of make patches algorithm
 * MAKEPATCHES_OK : Algorithm successful
 * MAKEPATCHES_FAIL_INTERSECTION : Algorithm failed during intersection of guides and profiles
 * MAKEPATCHES_FAIL_PATCHES : Algorithm failed due to failure in MakeLoops algorithm
 */
enum MakePatchesStatus
{
    MAKEPATCHES_OK                 = 0,
    MAKEPATCHES_FAIL_INTERSECTION  = 1,
    MAKEPATCHES_FAIL_PATCHES       = 2
};

class TopoDS_Shape;
class Handle_Geom_BSplineSurface;
class TColGeom_SequenceOfBoundedCurve;

/**
 * Implementation of algorithm for filling 4-sides closed frames\n
 * of edges with Coons surfaces to get faces.
 * Then faces can be joined in shell
 */

class MakePatches
{

public:

    void* operator new(size_t,void* anAddress)
    {
        return anAddress;
    }
    void* operator new(size_t size)
    {
        return Standard::Allocate(size);
    }
    void  operator delete(void* anAddress)
    {
        if (anAddress) {
            Standard::Free((Standard_Address&)anAddress);
        }
    }
// Methods PUBLIC
//

    /**
     * Empty constructop
     */

    TIGL_EXPORT MakePatches();

    /**
     * Constructor with initialisation of data
     * @param theGuides
     * compound consisting of guide edges or wires.
     * @param theProfiles
     * compound consisting of profile (section) edges or wires
     */
    TIGL_EXPORT MakePatches(const TopoDS_Shape& theGuides, const TopoDS_Shape& theProfiles);

    /**
     * Method for initialisation of data
     * @param theGuides
     * compound consisting of guide edges or wires.
     * @param theProfiles
     * compound consisting of profile (section) edges or wires
     */
    TIGL_EXPORT   void Init(const TopoDS_Shape& theGuides, const TopoDS_Shape& theProfiles) ;

    /**
     * Perform building patches
     * @param theTolConf
     * Absolute tolerance for checking coincidence of ends of curves.\n
     * This tolerance is used also by sewing algorithm
     * @param theTolParam
     * Relative tolerance for comparing knots of opposite curves\n
     * If k1 and k2 are values of corresponding knots of opposite curves C1 and C2 \n
     * then k1 ~= k2 if Abs(k1-k2)/((k1+k2)/2) <= theTolParam
     * @param theStyle
     * The style of filling, to provide C2 continuity between patches it is necessary using\n
     * GeomFill_CoonsC2Style
     * @param theSewing
     * Boolean flag that enable/disable sewing of patches
     */
    TIGL_EXPORT   void Perform(const Standard_Real theTolConf,
                               const Standard_Real theTolParam,
                               const GeomFill_FillingStyle theStyle = GeomFill_CoonsStyle,
                               const Standard_Boolean theSewing = Standard_True);

    /**
     * Returns result
     * Result can be compound pf faces or shell depending on value of theSewing
     */

    TIGL_EXPORT  const TopoDS_Shape& Patches() const;

    /**
     * Method for building surface by filling 4-side closed contour consisting of 4 curves
     * @param theCurves
     * The sequence of curves for storing closed contour of curves
     * @param theTolConf
     * Absolute tolerance for checking coincidence of ends of curves.
     * @param theTolParam
     * Relative tolerance for comparing knots of opposite curves\n
     * If k1 and k2 are values of corresponding knots of opposite curves C1 and C2 \n
     * then k1 ~= k2 if Abs(k1-k2)/((k1+k2)/2) <= theTolParam
     * @param theBaseCurve
     * The index in sequence theCurves, which define first curve in contour\n
     * this index has effect on origin and UV direction of result surface
     * @param theStyle
     * The style of filling, to provide C2 continuity between patches it is necessary using\n
     * GeomFill_CoonsC2Style
     */
    TIGL_EXPORT static  Handle_Geom_BSplineSurface
    BuildSurface(const TColGeom_SequenceOfBoundedCurve& theCurves,
                 const Standard_Real theTolConf,
                 const Standard_Real theTolParam,
                 const Standard_Integer theBaseCurve = 1,
                 const GeomFill_FillingStyle theStyle = GeomFill_CoonsStyle);
    /**
     * Returns status of calculations\n
     */

    TIGL_EXPORT MakePatchesStatus GetStatus() const;

protected:

// Methods PROTECTED
//

// Fields PROTECTED
//

private:

// Methods PRIVATE
//

// Fields PRIVATE
//
    TopoDS_Shape myGuides;
    TopoDS_Shape myProfiles;
    TopoDS_Shape myGrid;
    TopoDS_Shape myPatches;
    MakePatchesStatus myStatus;

};

// other Inline functions and methods (like "C++: function call" methods)
//

#endif
<|endoftext|>


<commit_before>//============================================================================//
// File:          qcan_network.cpp                                            //
// Description:   QCAN classes - CAN network                                  //
//                                                                            //
// Copyright (C) MicroControl GmbH & Co. KG                                   //
// 53844 Troisdorf - Germany                                                  //
// www.microcontrol.net                                                       //
//                                                                            //
//----------------------------------------------------------------------------//
// Redistribution and use in source and binary forms, with or without         //
// modification, are permitted provided that the following conditions         //
// are met:                                                                   //
// 1. Redistributions of source code must retain the above copyright          //
//    notice, this list of conditions, the following disclaimer and           //
//    the referenced file 'LICENSE'.                                          //
// 2. Redistributions in binary form must reproduce the above copyright       //
//    notice, this list of conditions and the following disclaimer in the     //
//    documentation and/or other materials provided with the distribution.    //
// 3. Neither the name of MicroControl nor the names of its contributors      //
//    may be used to endorse or promote products derived from this software   //
//    without specific prior written permission.                              //
//                                                                            //
// Provided that this notice is retained in full, this software may be        //
// distributed under the terms of the GNU Lesser General Public License       //
// ("LGPL") version 3 as distributed in the 'LICENSE' file.                   //
//                                                                            //
//============================================================================//

/*----------------------------------------------------------------------------*\
** Include files                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

#include <QDebug>

#include "qcan_server.hpp"

/*----------------------------------------------------------------------------*\
** Definitions                                                                **
**                                                                            **
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
** Class methods                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

//----------------------------------------------------------------------------//
// QCanServer()                                                               //
// constructor                                                                //
//----------------------------------------------------------------------------//
QCanServer::QCanServer( QObject * pclParentV,
                        uint16_t  uwPortStartV,
                        uint8_t   ubNetworkNumV)
{
   QCanNetwork *  pclCanNetT;

   //----------------------------------------------------------------
   // set the parent
   //
   this->setParent(pclParentV);

   //----------------------------------------------------------------
   // create CAN networks
   //
   pclListNetsP = new QVector<QCanNetwork *>;
   pclListNetsP->reserve(ubNetworkNumV);

   for(uint8_t ubNetCntT = 0; ubNetCntT < ubNetworkNumV; ubNetCntT++)
   {
      pclCanNetT = new QCanNetwork(pclParentV, uwPortStartV + ubNetCntT);
      pclListNetsP->append(pclCanNetT);

   }

}

//----------------------------------------------------------------------------//
// QCanServer()                                                               //
// destructor                                                                 //
//----------------------------------------------------------------------------//
QCanServer::~QCanServer()
{

}

uint8_t QCanServer::maximumNetwork(void) const
{
   return(pclListNetsP->count());
}

//----------------------------------------------------------------------------//
// network()                                                                  //
//                                                                            //
//----------------------------------------------------------------------------//
QCanNetwork * QCanServer::network(uint8_t ubNetworkIdxV)
{
   return(pclListNetsP->at(ubNetworkIdxV));
}

<commit_msg>Add setHostAddress() function<commit_after>//============================================================================//
// File:          qcan_network.cpp                                            //
// Description:   QCAN classes - CAN network                                  //
//                                                                            //
// Copyright (C) MicroControl GmbH & Co. KG                                   //
// 53844 Troisdorf - Germany                                                  //
// www.microcontrol.net                                                       //
//                                                                            //
//----------------------------------------------------------------------------//
// Redistribution and use in source and binary forms, with or without         //
// modification, are permitted provided that the following conditions         //
// are met:                                                                   //
// 1. Redistributions of source code must retain the above copyright          //
//    notice, this list of conditions, the following disclaimer and           //
//    the referenced file 'LICENSE'.                                          //
// 2. Redistributions in binary form must reproduce the above copyright       //
//    notice, this list of conditions and the following disclaimer in the     //
//    documentation and/or other materials provided with the distribution.    //
// 3. Neither the name of MicroControl nor the names of its contributors      //
//    may be used to endorse or promote products derived from this software   //
//    without specific prior written permission.                              //
//                                                                            //
// Provided that this notice is retained in full, this software may be        //
// distributed under the terms of the GNU Lesser General Public License       //
// ("LGPL") version 3 as distributed in the 'LICENSE' file.                   //
//                                                                            //
//============================================================================//

/*----------------------------------------------------------------------------*\
** Include files                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

#include <QDebug>

#include "qcan_server.hpp"

/*----------------------------------------------------------------------------*\
** Definitions                                                                **
**                                                                            **
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
** Class methods                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

//----------------------------------------------------------------------------//
// QCanServer()                                                               //
// constructor                                                                //
//----------------------------------------------------------------------------//
QCanServer::QCanServer( QObject * pclParentV,
                        uint16_t  uwPortStartV,
                        uint8_t   ubNetworkNumV)
{
   QCanNetwork *  pclCanNetT;

   //----------------------------------------------------------------
   // set the parent
   //
   this->setParent(pclParentV);

   //----------------------------------------------------------------
   // create CAN networks
   //
   pclListNetsP = new QVector<QCanNetwork *>;
   pclListNetsP->reserve(ubNetworkNumV);

   for(uint8_t ubNetCntT = 0; ubNetCntT < ubNetworkNumV; ubNetCntT++)
   {
      pclCanNetT = new QCanNetwork(pclParentV, uwPortStartV + ubNetCntT);
      pclListNetsP->append(pclCanNetT);

   }

}

//----------------------------------------------------------------------------//
// QCanServer()                                                               //
// destructor                                                                 //
//----------------------------------------------------------------------------//
QCanServer::~QCanServer()
{

}

uint8_t QCanServer::maximumNetwork(void) const
{
   return(pclListNetsP->count());
}

//----------------------------------------------------------------------------//
// network()                                                                  //
//                                                                            //
//----------------------------------------------------------------------------//
QCanNetwork * QCanServer::network(uint8_t ubNetworkIdxV)
{
   return(pclListNetsP->at(ubNetworkIdxV));
}

//----------------------------------------------------------------------------//
// setHostAddress()                                                           //
//                                                                            //
//----------------------------------------------------------------------------//
void QCanServer::setHostAddress(QHostAddress clHostAddressV)
{
   QCanNetwork *  pclNetworkT;
   bool           btNetworkStateT;

   for(uint8_t ubNetCntT = 0; ubNetCntT < maximumNetwork(); ubNetCntT++)
   {
      pclNetworkT = network(ubNetCntT);

      //-------------------------------------------------------------
      // check current state of network and disable it here
      //
      if(pclNetworkT->isNetworkEnabled() == true)
      {
         pclNetworkT->setNetworkEnabled(false);
         btNetworkStateT = true;
      }
      else
      {
         btNetworkStateT = true;
      }

      //-------------------------------------------------------------
      // assign new host address
      //
      pclNetworkT->setHostAddress(clHostAddressV);

      //-------------------------------------------------------------
      // set network to old state
      //
      pclNetworkT->setNetworkEnabled(btNetworkStateT);
   }
}
<|endoftext|>


<commit_before>#ifndef QCAN_SERVER_HPP_
#define QCAN_SERVER_HPP_

#include <QObject>

#include "qcan_network.hpp"

class QCanServer : public QObject
{
    Q_OBJECT

public:
    QCanServer( QObject * pclParentV = Q_NULLPTR,
                uint16_t  uwPortStartV = QCAN_TCP_DEFAULT_PORT,
                uint8_t   ubNetworkNumV = QCAN_NETWORK_MAX);

    ~QCanServer();

    QCanNetwork * network(uint8_t ubNetworkIdxV);

    uint8_t maximumNetwork(void) const;

private:

    QVector<QCanNetwork *> *  pclListNetsP;

};

#endif // QCAN_SERVER_HPP_
<commit_msg>Update documentation and add setHostAddress() function<commit_after>//============================================================================//
// File:          qcan_network.hpp                                            //
// Description:   QCAN classes - CAN network                                  //
//                                                                            //
// Copyright (C) MicroControl GmbH & Co. KG                                   //
// 53844 Troisdorf - Germany                                                  //
// www.microcontrol.net                                                       //
//                                                                            //
//----------------------------------------------------------------------------//
// Redistribution and use in source and binary forms, with or without         //
// modification, are permitted provided that the following conditions         //
// are met:                                                                   //
// 1. Redistributions of source code must retain the above copyright          //
//    notice, this list of conditions, the following disclaimer and           //
//    the referenced file 'LICENSE'.                                          //
// 2. Redistributions in binary form must reproduce the above copyright       //
//    notice, this list of conditions and the following disclaimer in the     //
//    documentation and/or other materials provided with the distribution.    //
// 3. Neither the name of MicroControl nor the names of its contributors      //
//    may be used to endorse or promote products derived from this software   //
//    without specific prior written permission.                              //
//                                                                            //
// Provided that this notice is retained in full, this software may be        //
// distributed under the terms of the GNU Lesser General Public License       //
// ("LGPL") version 3 as distributed in the 'LICENSE' file.                   //
//                                                                            //
//============================================================================//

#ifndef QCAN_SERVER_HPP_
#define QCAN_SERVER_HPP_

/*----------------------------------------------------------------------------*\
** Include files                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/
#include <QObject>

#include "qcan_network.hpp"

//-----------------------------------------------------------------------------
/*!
** \class QCanServer
** \brief CAN server
**
** This class represents a CAN server, which incorporates up to
** QCAN_NETWORK_MAX number of CAN networks (QCanNetwork).
**
*/
class QCanServer : public QObject
{
    Q_OBJECT

public:
    QCanServer( QObject * pclParentV = Q_NULLPTR,
                uint16_t  uwPortStartV = QCAN_TCP_DEFAULT_PORT,
                uint8_t   ubNetworkNumV = QCAN_NETWORK_MAX);

    ~QCanServer();

    QCanNetwork * network(uint8_t ubNetworkIdxV);

    uint8_t       maximumNetwork(void) const;

    void          setHostAddress(QHostAddress clHostAddressV);

private:

    QVector<QCanNetwork *> *  pclListNetsP;

};

#endif // QCAN_SERVER_HPP_
<|endoftext|>


<commit_before>/// \file alignment.cpp
///
/// unit tests for Alignments and their utility functions
///

#include <iostream>
#include <string>
#include "../json2pb.h"
#include "../vg.pb.h"
#include "../alignment.hpp"
#include "catch.hpp"

namespace vg {
namespace unittest {
using namespace std;

TEST_CASE("Alignment simplification does not remove deletions on the edges of Mappings", "[alignment]") {

    string alignment_string = R"(
        {
            "sequence": "A",
            "path": {"mapping": [
                {
                    "position": {"node_id": 1},
                    "edit": [
                        {"from_length": 1, "to_length": 1},
                        {"from_length": 1}
                    ]
                },
                {
                    "position": {"node_id": 2},
                    "edit": [
                        {"from_length": 1, "to_length": 1}
                    ]
                }
            ]}
        }
    )";

    Alignment a;
    json2pb(a, alignment_string.c_str(), alignment_string.size());

    auto simple = simplify(a);
    REQUIRE(simple.path().mapping_size() == 2);
    REQUIRE(simple.path().mapping(0).edit_size() == 2);

}

TEST_CASE("Alignment simplification handles unaligned alignments", "[alignment]") {

    string alignment_string = R"(
        {"sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACTGTCACGACACATACTATACTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT", "path": {"mapping": [{"edit": [{"to_length": 793, "sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACT"}, {"to_length": 18, "sequence": "GTCACGACACATACTATA"}, {"to_length": 161, "sequence": "CTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT"}]}]}}
    )";

    Alignment a;
    json2pb(a, alignment_string.c_str(), alignment_string.size());

    auto simple = simplify(a);
    REQUIRE(simple.path().mapping_size() == 1);
    REQUIRE(simple.path().mapping(0).edit_size() == 1);

}

TEST_CASE("Alignment trimming works even on unaligned reads", "[alignment]") {

    string alignment_string = R"(
        {"sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACTGTCACGACACATACTATACTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT", "path": {"mapping": [{"edit": [{"to_length": 793, "sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACT"}, {"to_length": 18, "sequence": "GTCACGACACATACTATA"}, {"to_length": 161, "sequence": "CTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT"}]}]}}
    )";

    Alignment a;
    json2pb(a, alignment_string.c_str(), alignment_string.size());

    auto aln = simplify(a);
    aln = strip_from_start(aln, 50);
    aln = strip_from_end(aln, 50);

    REQUIRE(a.sequence().size() - 100 == aln.sequence().size());

}

}
}
<commit_msg>diversify the unit tests for alignment simplification<commit_after>/// \file alignment.cpp
///
/// unit tests for Alignments and their utility functions
///

#include <iostream>
#include <string>
#include "../json2pb.h"
#include "../vg.pb.h"
#include "../alignment.hpp"
#include "catch.hpp"

namespace vg {
namespace unittest {
using namespace std;

TEST_CASE("Default alignment simplification removes deletions on the edges of Mappings", "[alignment]") {

    string alignment_string = R"(
        {
            "sequence": "A",
            "path": {"mapping": [
                {
                    "position": {"node_id": 1},
                    "edit": [
                        {"from_length": 1, "to_length": 1},
                        {"from_length": 1}
                    ]
                },
                {
                    "position": {"node_id": 2},
                    "edit": [
                        {"from_length": 1, "to_length": 1}
                    ]
                }
            ]}
        }
    )";

    Alignment a;
    json2pb(a, alignment_string.c_str(), alignment_string.size());

    auto simple = simplify(a);
    REQUIRE(simple.path().mapping_size() == 2);
    REQUIRE(simple.path().mapping(0).edit_size() == 1);

}

TEST_CASE("Non-trim alignment simplification does not remove deletions on the edges of Mappings", "[alignment]") {

    string alignment_string = R"(
        {
            "sequence": "A",
            "path": {"mapping": [
                {
                    "position": {"node_id": 1},
                    "edit": [
                        {"from_length": 1, "to_length": 1},
                        {"from_length": 1}
                    ]
                },
                {
                    "position": {"node_id": 2},
                    "edit": [
                        {"from_length": 1, "to_length": 1}
                    ]
                }
            ]}
        }
    )";

    Alignment a;
    json2pb(a, alignment_string.c_str(), alignment_string.size());

    auto simple = simplify(a, false);
    REQUIRE(simple.path().mapping_size() == 2);
    REQUIRE(simple.path().mapping(0).edit_size() == 2);

}

TEST_CASE("Alignment simplification handles unaligned alignments", "[alignment]") {

    string alignment_string = R"(
        {"sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACTGTCACGACACATACTATACTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT", "path": {"mapping": [{"edit": [{"to_length": 793, "sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACT"}, {"to_length": 18, "sequence": "GTCACGACACATACTATA"}, {"to_length": 161, "sequence": "CTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT"}]}]}}
    )";

    Alignment a;
    json2pb(a, alignment_string.c_str(), alignment_string.size());

    auto simple = simplify(a);
    REQUIRE(simple.path().mapping_size() == 1);
    REQUIRE(simple.path().mapping(0).edit_size() == 1);

}

TEST_CASE("Alignment trimming works even on unaligned reads", "[alignment]") {

    string alignment_string = R"(
        {"sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACTGTCACGACACATACTATACTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT", "path": {"mapping": [{"edit": [{"to_length": 793, "sequence": "TTGCTTTTTCCATCGCCAATTTCTGCAGCATTAATTTATTCTGGTTGTCATTTACAGTATATCAAGAGTTTAACCAGGAAATATTCCAAAGAAGGTTATTTTACCCATATACAGTACTTCATATGTCCAAAATTGGCCATTTGATGCACCTCTACCATCTATTTTTCCTTTCATGTGGCTTATATAACCATTGCTTGGATATTGATTTTACCAAAAGAGGGCGAATCCATATAATTATCTGGTATCGATGGAATGGTTATGGTAATTCAGAATATTTTTCTTATTATTGGTCGCTAATTGGCTCTTTTTATTTGGAGTTTCAAACAACAAGAAGAAGTCCGAGAATTCGTGCAATCTACTTTTGGAGTATTAAGCCATTTATTAATTTATCTTATAACATGTTGATGGACCATTCATATATGACCGACCCTAGCCCTAAACGAGTTGGTTTGCCTGCCGCCTACCAAATCATGTCATAATGGTAATAGTTGCATGCTTCTTTTTTCTGGTTAGTTTAAATTCGTTTTACTACCTAAATTCTTCATTAATAAAACTTTTACCCAAAATCACTTATTTGCATGATGGGCTCATTGTCCACAGAATGGGTGAAAAAGCCATGTCTGTGTTTTAGTTTTTCCTTTTCCTACATAAATATTTTAATAGACTACTATTGCATTTTTAATAAATAATATTCATGCCTGCATCTTTGAATAAAAGAAAAGAAACATTCGTTATTTCATCCTCTTACTTGATTGCTATAGAGCTATTTGCTTTCAAAGCTCTAGGTCCCACT"}, {"to_length": 18, "sequence": "GTCACGACACATACTATA"}, {"to_length": 161, "sequence": "CTCTCACCGGTTCATTTTTCAACAGTTCATAAGGGCGATCATATTCTTTAACCTCACCGGATCCATCACAAATTATCTGTCGTAATCGATAACAGATCTCAACGATGTGCAATAGTAAGAATTGTGTTTTTATTAAACTCACTTCTTAATAATACCCTGAT"}]}]}}
    )";

    Alignment a;
    json2pb(a, alignment_string.c_str(), alignment_string.size());

    auto aln = simplify(a);
    aln = strip_from_start(aln, 50);
    aln = strip_from_end(aln, 50);

    REQUIRE(a.sequence().size() - 100 == aln.sequence().size());

}

}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Florian Behrens
 *
 * 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 <client_context/client_context.h>

#include "client_write_interface.h"
#include "event.h"
#include "exceptions.h"
#include "object.h"
#include "object_dictionary.h"

namespace decof
{

client_context::client_context(object_dictionary& a_object_dictionary, userlevel_t userlevel)
  : object_dictionary_(a_object_dictionary),
    userlevel_(userlevel)
{}

client_context::~client_context()
{}

userlevel_t client_context::userlevel() const
{
    return userlevel_;
}

userlevel_t client_context::effective_userlevel() const
{
    return (userlevel_ == decof::Readonly ? decof::Normal : userlevel_);
}

void client_context::userlevel(userlevel_t ul)
{
    if (ul < Minimum || ul > Maximum)
        throw invalid_userlevel_error();

    userlevel_ = ul;
}

std::string client_context::connection_type() const
{
    return std::string("undefined");
}

std::string client_context::remote_endpoint() const
{
    return std::string("undefined");
}

void client_context::preload()
{}

void client_context::set_parameter(const std::string &uri, const boost::any &any_value, char separator)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    if (userlevel_ == decof::Readonly)
        throw access_denied_error();

    object *te = object_dictionary_.find_object(uri, separator);
    client_write_interface* param = dynamic_cast<client_write_interface*>(te);

    if (param == nullptr)
        throw invalid_parameter_error();
    if (userlevel_ > te->writelevel())
        throw access_denied_error();

    param->value(any_value);
}

boost::any client_context::get_parameter(const std::string &uri, char separator)
{
    boost::any retval;
    object_dictionary::context_guard cg(object_dictionary_, this);

    object *obj = object_dictionary_.find_object(uri, separator);
    client_read_interface* param = dynamic_cast<client_read_interface*>(obj);

    if (param == nullptr)
        throw invalid_parameter_error();
    if (effective_userlevel() > obj->readlevel())
        throw access_denied_error();

    return param->any_value();
}

void client_context::signal_event(const std::string &uri, char separator)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    if (userlevel_ == decof::Readonly)
        throw access_denied_error();

    object *te = object_dictionary_.find_object(uri, separator);
    event* ev = dynamic_cast<event*>(te);

    if (ev == nullptr)
        throw invalid_parameter_error();
    if (userlevel_ > te->writelevel())
        throw access_denied_error();

    ev->signal();
}

void client_context::observe(const std::string &uri, client_read_interface::signal_type::slot_type slot, char separator)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    auto obj = object_dictionary_.find_object(uri, separator);

    if (client_read_interface* param = dynamic_cast<client_read_interface*>(obj)) {
        if (effective_userlevel() > obj->readlevel())
            throw access_denied_error();

        if (observables_.count(uri) == 0)
            observables_[uri] = param->observe(slot);
    } else
        throw invalid_parameter_error();
}

void client_context::unobserve(const std::string &uri)
{
    observables_.erase(uri);
}

void client_context::browse(object_visitor *visitor, const std::string &root_uri)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    std::string uri = root_uri;
    if (uri.empty())
        uri = object_dictionary_.name();

    if (object *te = object_dictionary_.find_object(uri)) {
        // Recursively iterate over all objects beginning from root URI
        browse_object(te, visitor);
    } else
        throw invalid_parameter_error();
}

void client_context::tick()
{
    object_dictionary_.tick();
}

void client_context::browse_object(object *te, object_visitor *visitor)
{
    te->accept(visitor);

    // If node browse children
    if (node *n = dynamic_cast<node*>(te)) {
        for (auto &child : *n) {
            if (effective_userlevel() > child->readlevel())
                browse_object(child, visitor);
        }
    }
}

} // namespace decof
<commit_msg>Fixed userlevel handling in browse requests.<commit_after>/*
 * Copyright (c) 2014 Florian Behrens
 *
 * 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 <client_context/client_context.h>

#include "client_write_interface.h"
#include "event.h"
#include "exceptions.h"
#include "object.h"
#include "object_dictionary.h"

namespace decof
{

client_context::client_context(object_dictionary& a_object_dictionary, userlevel_t userlevel)
  : object_dictionary_(a_object_dictionary),
    userlevel_(userlevel)
{}

client_context::~client_context()
{}

userlevel_t client_context::userlevel() const
{
    return userlevel_;
}

userlevel_t client_context::effective_userlevel() const
{
    return (userlevel_ == decof::Readonly ? decof::Normal : userlevel_);
}

void client_context::userlevel(userlevel_t ul)
{
    if (ul < Minimum || ul > Maximum)
        throw invalid_userlevel_error();

    userlevel_ = ul;
}

std::string client_context::connection_type() const
{
    return std::string("undefined");
}

std::string client_context::remote_endpoint() const
{
    return std::string("undefined");
}

void client_context::preload()
{}

void client_context::set_parameter(const std::string &uri, const boost::any &any_value, char separator)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    if (userlevel_ == decof::Readonly)
        throw access_denied_error();

    object *te = object_dictionary_.find_object(uri, separator);
    client_write_interface* param = dynamic_cast<client_write_interface*>(te);

    if (param == nullptr)
        throw invalid_parameter_error();
    if (userlevel_ > te->writelevel())
        throw access_denied_error();

    param->value(any_value);
}

boost::any client_context::get_parameter(const std::string &uri, char separator)
{
    boost::any retval;
    object_dictionary::context_guard cg(object_dictionary_, this);

    object *obj = object_dictionary_.find_object(uri, separator);
    client_read_interface* param = dynamic_cast<client_read_interface*>(obj);

    if (param == nullptr)
        throw invalid_parameter_error();
    if (effective_userlevel() > obj->readlevel())
        throw access_denied_error();

    return param->any_value();
}

void client_context::signal_event(const std::string &uri, char separator)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    if (userlevel_ == decof::Readonly)
        throw access_denied_error();

    object *te = object_dictionary_.find_object(uri, separator);
    event* ev = dynamic_cast<event*>(te);

    if (ev == nullptr)
        throw invalid_parameter_error();
    if (userlevel_ > te->writelevel())
        throw access_denied_error();

    ev->signal();
}

void client_context::observe(const std::string &uri, client_read_interface::signal_type::slot_type slot, char separator)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    auto obj = object_dictionary_.find_object(uri, separator);

    if (client_read_interface* param = dynamic_cast<client_read_interface*>(obj)) {
        if (effective_userlevel() > obj->readlevel())
            throw access_denied_error();

        if (observables_.count(uri) == 0)
            observables_[uri] = param->observe(slot);
    } else
        throw invalid_parameter_error();
}

void client_context::unobserve(const std::string &uri)
{
    observables_.erase(uri);
}

void client_context::browse(object_visitor *visitor, const std::string &root_uri)
{
    object_dictionary::context_guard cg(object_dictionary_, this);

    std::string uri = root_uri;
    if (uri.empty())
        uri = object_dictionary_.name();

    if (object *te = object_dictionary_.find_object(uri)) {
        // Recursively iterate over all objects beginning from root URI
        browse_object(te, visitor);
    } else
        throw invalid_parameter_error();
}

void client_context::tick()
{
    object_dictionary_.tick();
}

void client_context::browse_object(object *te, object_visitor *visitor)
{
    te->accept(visitor);

    // If node browse children
    if (node *n = dynamic_cast<node*>(te)) {
        for (auto &child : *n) {
            if (effective_userlevel() <= child->readlevel())
                browse_object(child, visitor);
        }
    }
}

} // namespace decof
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include <cassert>
#include <iostream>
#include <list>

#include "base/refcnt.hh"

using namespace std;

namespace {

class TestRC;
typedef list<TestRC *> LiveList;
LiveList liveList;

int
live()
{
    return liveList.size();
}

int
liveChange()
{
    static int oldLive = 0;
    int newLive = live();
    int diff =  newLive - oldLive;
    oldLive = newLive;
    return diff;
}

class TestRC : public RefCounted
{
  protected:
    const char *_tag;
    LiveList::iterator liveIt;

  public:
    TestRC(const char *newTag) : _tag(newTag)
    {
        cout << "  Creating object \"" << _tag << "\"\n";
        liveList.push_front(this);
        liveIt = liveList.begin();
    }

    ~TestRC()
    {
        cout << "  Destroying object \"" << _tag << "\"\n";
        liveList.erase(liveIt);
    }

    const char *
    tag()
    {
        return _tag;
    }

    int testVal;
};

typedef RefCountingPtr<TestRC> Ptr;

}

int
main()
{
    assert(live() == 0);
    assert(liveChange() == 0);

    // Create an empty Ptr and verify it's data pointer is NULL.
    cout << "NULL check.\n";
    Ptr nullCheck;
    assert(nullCheck.get() == NULL);

    assert(liveChange() == 0);

    // Construct a Ptr from a TestRC pointer.
    cout << "Construction from pointer.\n";
    Ptr constFromPointer = new TestRC("construction from pointer");

    assert(liveChange() == 1);

    // Construct a Ptr from an existing Ptr.
    cout << "Construction from a Ptr.\n";
    Ptr constFromPtr = constFromPointer;

    assert(liveChange() == 0);

    // Test a Ptr being destroyed.
    cout << "Destroying a Ptr.\n";
    Ptr *ptrPtr = new Ptr(new TestRC("destroying a ptr"));
    assert(liveChange() == 1);
    delete ptrPtr;
    assert(liveChange() == -1);

    // Test assignment from a pointer and from a Ptr.
    cout << "Assignment operators.\n";
    Ptr assignmentTarget;
    TestRC *assignmentSourcePointer = new TestRC("assignment source 1");
    assert(liveChange() == 1);
    assignmentTarget = assignmentSourcePointer;
    assert(liveChange() == 0);
    assignmentTarget = NULL;
    assert(liveChange() == -1);
    Ptr assignmentSourcePtr(new TestRC("assignment source 2"));
    assert(liveChange() == 1);
    assignmentTarget = assignmentSourcePtr;
    assert(liveChange() == 0);
    assignmentSourcePtr = NULL;
    assert(liveChange() == 0);
    assignmentTarget = NULL;
    assert(liveChange() == -1);

    // Test access to members of the pointed to class and dereferencing.
    cout << "Access to members.\n";
    TestRC *accessTest = new TestRC("access test");
    Ptr accessTestPtr = accessTest;
    accessTest->testVal = 1;
    assert(accessTestPtr->testVal == 1);
    assert((*accessTestPtr).testVal == 1);
    accessTest->testVal = 2;
    assert(accessTestPtr->testVal == 2);
    assert((*accessTestPtr).testVal == 2);
    accessTestPtr->testVal = 3;
    assert(accessTest->testVal == 3);
    (*accessTestPtr).testVal = 4;
    assert(accessTest->testVal == 4);
    accessTestPtr = NULL;
    accessTest = NULL;
    assert(liveChange() == 0);

    // Test bool and ! operator overloads.
    cout << "Conversion to bool and ! overload.\n";
    Ptr boolTest = new TestRC("bool test");
    assert(boolTest == true);
    assert(!boolTest == false);
    boolTest = NULL;
    assert(boolTest == false);
    assert(!boolTest == true);
    assert(liveChange() == 0);

    // Test the equality operators.
    cout << "Equality operators.\n";
    TestRC *equalTestA = new TestRC("equal test a");
    Ptr equalTestAPtr = equalTestA;
    Ptr equalTestAPtr2 = equalTestA;
    TestRC *equalTestB = new TestRC("equal test b");
    Ptr equalTestBPtr = equalTestB;
    assert(equalTestA == equalTestAPtr);
    assert(equalTestAPtr == equalTestA);
    assert(equalTestAPtr == equalTestAPtr2);
    assert(equalTestA != equalTestBPtr);
    assert(equalTestAPtr != equalTestB);
    assert(equalTestAPtr != equalTestBPtr);

    cout << flush;
}
<commit_msg>Unit tests: Convert the refcnttest unit test to use the new EXPECT macros.<commit_after>/*
 * Copyright (c) 2010 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include <cassert>
#include <iostream>
#include <list>

#include "base/cprintf.hh"
#include "base/refcnt.hh"
#include "unittest/unittest.hh"

using namespace std;
using UnitTest::setCase;

namespace {

bool printNewDel = false;

class TestRC;
typedef list<TestRC *> LiveList;
LiveList liveList;

int
live()
{
    return liveList.size();
}

int
liveChange()
{
    static int oldLive = 0;
    int newLive = live();
    int diff =  newLive - oldLive;
    oldLive = newLive;
    return diff;
}

class TestRC : public RefCounted
{
  protected:
    const char *_tag;
    LiveList::iterator liveIt;

  public:
    TestRC(const char *newTag) : _tag(newTag)
    {
        if (printNewDel)
            cprintf("  Creating object \"%s\"\n", _tag);
        liveList.push_front(this);
        liveIt = liveList.begin();
    }

    ~TestRC()
    {
        if (printNewDel)
            cprintf("  Destroying object \"%s\"\n", _tag);
        liveList.erase(liveIt);
    }

    const char *
    tag()
    {
        return _tag;
    }

    int testVal;
};

typedef RefCountingPtr<TestRC> Ptr;

} // anonymous namespace

int
main()
{
    assert(live() == 0);
    assert(liveChange() == 0);

    // Create an empty Ptr and verify it's data pointer is NULL.
    setCase("NULL check");
    Ptr nullCheck;
    EXPECT_EQ(nullCheck.get(), NULL);

    EXPECT_EQ(liveChange(), 0);

    // Construct a Ptr from a TestRC pointer.
    setCase("construction from pointer");
    Ptr constFromPointer = new TestRC("construction from pointer");

    EXPECT_EQ(liveChange(), 1);

    // Construct a Ptr from an existing Ptr.
    setCase("construction from a Ptr");
    Ptr constFromPtr = constFromPointer;

    EXPECT_EQ(liveChange(), 0);

    // Test a Ptr being destroyed.
    setCase("destroying a Ptr");
    Ptr *ptrPtr = new Ptr(new TestRC("destroying a ptr"));
    EXPECT_EQ(liveChange(), 1);
    delete ptrPtr;
    EXPECT_EQ(liveChange(), -1);

    // Test assignment from a pointer and from a Ptr.
    setCase("assignment operators");
    Ptr assignmentTarget;
    TestRC *assignmentSourcePointer = new TestRC("assignment source 1");
    EXPECT_EQ(liveChange(), 1);
    assignmentTarget = assignmentSourcePointer;
    EXPECT_EQ(liveChange(), 0);
    assignmentTarget = NULL;
    EXPECT_EQ(liveChange(), -1);
    Ptr assignmentSourcePtr(new TestRC("assignment source 2"));
    EXPECT_EQ(liveChange(), 1);
    assignmentTarget = assignmentSourcePtr;
    EXPECT_EQ(liveChange(), 0);
    assignmentSourcePtr = NULL;
    EXPECT_EQ(liveChange(), 0);
    assignmentTarget = NULL;
    EXPECT_EQ(liveChange(), -1);

    // Test access to members of the pointed to class and dereferencing.
    setCase("access to members");
    TestRC *accessTest = new TestRC("access test");
    Ptr accessTestPtr = accessTest;
    accessTest->testVal = 1;
    EXPECT_EQ(accessTestPtr->testVal, 1);
    EXPECT_EQ((*accessTestPtr).testVal, 1);
    accessTest->testVal = 2;
    EXPECT_EQ(accessTestPtr->testVal, 2);
    EXPECT_EQ((*accessTestPtr).testVal, 2);
    accessTestPtr->testVal = 3;
    EXPECT_EQ(accessTest->testVal, 3);
    (*accessTestPtr).testVal = 4;
    EXPECT_EQ(accessTest->testVal, 4);
    accessTestPtr = NULL;
    accessTest = NULL;
    EXPECT_EQ(liveChange(), 0);

    // Test bool and ! operator overloads.
    setCase("conversion to bool and ! overload");
    Ptr boolTest = new TestRC("bool test");
    EXPECT_EQ(boolTest, true);
    EXPECT_EQ(!boolTest, false);
    boolTest = NULL;
    EXPECT_EQ(boolTest, false);
    EXPECT_EQ(!boolTest, true);
    EXPECT_EQ(liveChange(), 0);

    // Test the equality operators.
    setCase("equality operators");
    TestRC *equalTestA = new TestRC("equal test a");
    Ptr equalTestAPtr = equalTestA;
    Ptr equalTestAPtr2 = equalTestA;
    TestRC *equalTestB = new TestRC("equal test b");
    Ptr equalTestBPtr = equalTestB;
    EXPECT_TRUE(equalTestA == equalTestAPtr);
    EXPECT_TRUE(equalTestAPtr == equalTestA);
    EXPECT_TRUE(equalTestAPtr == equalTestAPtr2);
    EXPECT_TRUE(equalTestA != equalTestBPtr);
    EXPECT_TRUE(equalTestAPtr != equalTestB);
    EXPECT_TRUE(equalTestAPtr != equalTestBPtr);

    return UnitTest::printResults();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 1999-2011 Insight Software Consortium
 * 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.
 */

#ifndef otbStreamingStatisticsMapFromLabelImageFilter_hxx
#define otbStreamingStatisticsMapFromLabelImageFilter_hxx
#include "otbStreamingStatisticsMapFromLabelImageFilter.h"

#include "itkInputDataObjectIterator.h"
#include "itkImageRegionIterator.h"
#include "itkProgressReporter.h"
#include "otbMacro.h"
#include <cmath>

namespace otb
{

template<class TInputVectorImage, class TLabelImage>
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::PersistentStreamingStatisticsMapFromLabelImageFilter()
{
  // first output is a copy of the image, DataObject created by
  // superclass
  //
  // allocate the data objects for the outputs which are
  // just decorators around pixel types
  typename PixelValueMapObjectType::Pointer output
      = static_cast<PixelValueMapObjectType*>(this->MakeOutput(1).GetPointer());
  this->itk::ProcessObject::SetNthOutput(1, output.GetPointer());

  this->Reset();

}

template<class TInputVectorImage, class TLabelImage>
typename itk::DataObject::Pointer
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::MakeOutput(DataObjectPointerArraySizeType /* output */)
{
  return static_cast<itk::DataObject*>(PixelValueMapObjectType::New().GetPointer());
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::SetInputLabelImage(const LabelImageType *input)
{
  // Process object is not const-correct so the const_cast is required here
  this->itk::ProcessObject::SetNthInput(1,
                                   const_cast< LabelImageType * >( input ) );

}

template<class TInputVectorImage, class TLabelImage>
const typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::LabelImageType*
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetInputLabelImage()
{
  return static_cast< const TLabelImage * >
    (this->itk::ProcessObject::GetInput(1));
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetMeanValueMap() const
{
  return m_MeanRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetStandardDeviationValueMap() const
{
  return m_StDevRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetMinValueMap() const
{
  return m_MinRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetMaxValueMap() const
{
  return m_MaxRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::LabelPopulationMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetLabelPopulationMap() const
{
  return m_LabelPopulation;
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();

  if (this->GetInput())
    {
    this->GetOutput()->CopyInformation(this->GetInput());
    this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());

    if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
      {
      this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
      }
    }
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::AllocateOutputs()
{
  // This is commented to prevent the streaming of the whole image for the first stream strip
  // It shall not cause any problem because the output image of this filter is not intended to be used.
  //InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
  //this->GraftOutput( image );
  // Nothing that needs to be allocated for the remaining outputs
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::Synthetize()
 {
  // Update temporary accumulator
  AccumulatorMapType outputAcc;

  for (auto const& threadAccMap: m_AccumulatorMaps)
    {
    for(auto const& it: threadAccMap)
      {
      const LabelPixelType label = it.first;
      if (outputAcc.count(label) <= 0)
        {
        AccumulatorType newAcc(it.second);
        outputAcc[label] = newAcc;
        }
      else
        {
        outputAcc[label].Update(it.second);
        }
      }
    }

  // Publish output maps
  for(auto& it: outputAcc)
    {
    const LabelPixelType label = it.first;
    const double count = it.second.GetCount();
    const RealVectorPixelType sum   = it.second.GetSum();
    const RealVectorPixelType sqSum = it.second.GetSqSum();

    // Count
    m_LabelPopulation[label] = count;

    // Mean & stdev
    RealVectorPixelType mean (sum);
    RealVectorPixelType std (sqSum);
    for (unsigned int band = 0 ; band < mean.GetSize() ; band++)
      {
      // Mean
      mean[band] /= count;

      // Unbiased standard deviation (not sure unbiased is usefull here)
      const double variance = (sqSum[band] - (sum[band] * mean[band])) / (count - 1);
      std[band] = std::sqrt(variance);
      }
    m_MeanRadiometricValue[label] = mean;
    m_StDevRadiometricValue[label] = std;

    // Min & max
    m_MinRadiometricValue[label] = it.second.GetMin();
    m_MaxRadiometricValue[label] = it.second.GetMax();
    }

 }

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::Reset()
{
  m_AccumulatorMaps.clear();

  m_MeanRadiometricValue.clear();
  m_StDevRadiometricValue.clear();
  m_MinRadiometricValue.clear();
  m_MaxRadiometricValue.clear();
  m_LabelPopulation.clear();
  m_AccumulatorMaps.resize(this->GetNumberOfThreads());

}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GenerateInputRequestedRegion()
{
  // The Requested Regions of all the inputs are set to their Largest Possible Regions
  this->itk::ProcessObject::GenerateInputRequestedRegion();

  // Iteration over all the inputs of the current filter (this)
  for( itk::InputDataObjectIterator it( this ); !it.IsAtEnd(); it++ )
    {
    // Check whether the input is an image of the appropriate dimension
    // dynamic_cast of all the input images as itk::ImageBase objects
    // in order to pass the if ( input ) test whatever the inputImageType (vectorImage or labelImage)
    ImageBaseType * input = dynamic_cast< ImageBaseType *>( it.GetInput() );

    if ( input )
      {
      // Use the function object RegionCopier to copy the output region
      // to the input.  The default region copier has default implementations
      // to handle the cases where the input and output are the same
      // dimension, the input a higher dimension than the output, and the
      // input a lower dimension than the output.
      InputImageRegionType inputRegion;
      this->CallCopyOutputRegionToInputRegion( inputRegion, this->GetOutput()->GetRequestedRegion() );
      input->SetRequestedRegion(inputRegion);
      }
    }
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId )
{
  /**
   * Grab the input
   */
  InputVectorImagePointer inputPtr =  const_cast<TInputVectorImage *>(this->GetInput());
  LabelImagePointer labelInputPtr =  const_cast<TLabelImage *>(this->GetInputLabelImage());

  itk::ImageRegionConstIterator<TInputVectorImage> inIt(inputPtr, outputRegionForThread);
  itk::ImageRegionConstIterator<TLabelImage> labelIt(labelInputPtr, outputRegionForThread);

  typename VectorImageType::PixelType value;
  typename LabelImageType::PixelType label;

  // do the work
  for (inIt.GoToBegin(), labelIt.GoToBegin();
       !inIt.IsAtEnd() && !labelIt.IsAtEnd();
       ++inIt, ++labelIt)
    {
      value = inIt.Get();
      label = labelIt.Get();

      // Update the accumulator
      if (m_AccumulatorMaps[threadId].count(label) <= 0) //add new element to the map
        {
        AccumulatorType newAcc(value);
        m_AccumulatorMaps[threadId][label] = newAcc;
        }
      else
        {
        m_AccumulatorMaps[threadId][label].Update(value);
        }
    }
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

} // end namespace otb
#endif
<commit_msg>BUG: prefer itkNotUsed<commit_after>/*
 * Copyright (C) 1999-2011 Insight Software Consortium
 * 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.
 */

#ifndef otbStreamingStatisticsMapFromLabelImageFilter_hxx
#define otbStreamingStatisticsMapFromLabelImageFilter_hxx
#include "otbStreamingStatisticsMapFromLabelImageFilter.h"

#include "itkInputDataObjectIterator.h"
#include "itkImageRegionIterator.h"
#include "itkProgressReporter.h"
#include "otbMacro.h"
#include <cmath>

namespace otb
{

template<class TInputVectorImage, class TLabelImage>
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::PersistentStreamingStatisticsMapFromLabelImageFilter()
{
  // first output is a copy of the image, DataObject created by
  // superclass
  //
  // allocate the data objects for the outputs which are
  // just decorators around pixel types
  typename PixelValueMapObjectType::Pointer output
      = static_cast<PixelValueMapObjectType*>(this->MakeOutput(1).GetPointer());
  this->itk::ProcessObject::SetNthOutput(1, output.GetPointer());

  this->Reset();

}

template<class TInputVectorImage, class TLabelImage>
typename itk::DataObject::Pointer
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::MakeOutput(DataObjectPointerArraySizeType itkNotUsed(output))
{
  return static_cast<itk::DataObject*>(PixelValueMapObjectType::New().GetPointer());
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::SetInputLabelImage(const LabelImageType *input)
{
  // Process object is not const-correct so the const_cast is required here
  this->itk::ProcessObject::SetNthInput(1,
                                   const_cast< LabelImageType * >( input ) );

}

template<class TInputVectorImage, class TLabelImage>
const typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::LabelImageType*
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetInputLabelImage()
{
  return static_cast< const TLabelImage * >
    (this->itk::ProcessObject::GetInput(1));
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetMeanValueMap() const
{
  return m_MeanRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetStandardDeviationValueMap() const
{
  return m_StDevRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetMinValueMap() const
{
  return m_MinRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::PixelValueMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetMaxValueMap() const
{
  return m_MaxRadiometricValue;
}

template<class TInputVectorImage, class TLabelImage>
typename PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>::LabelPopulationMapType
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GetLabelPopulationMap() const
{
  return m_LabelPopulation;
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();

  if (this->GetInput())
    {
    this->GetOutput()->CopyInformation(this->GetInput());
    this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());

    if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
      {
      this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
      }
    }
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::AllocateOutputs()
{
  // This is commented to prevent the streaming of the whole image for the first stream strip
  // It shall not cause any problem because the output image of this filter is not intended to be used.
  //InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
  //this->GraftOutput( image );
  // Nothing that needs to be allocated for the remaining outputs
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::Synthetize()
 {
  // Update temporary accumulator
  AccumulatorMapType outputAcc;

  for (auto const& threadAccMap: m_AccumulatorMaps)
    {
    for(auto const& it: threadAccMap)
      {
      const LabelPixelType label = it.first;
      if (outputAcc.count(label) <= 0)
        {
        AccumulatorType newAcc(it.second);
        outputAcc[label] = newAcc;
        }
      else
        {
        outputAcc[label].Update(it.second);
        }
      }
    }

  // Publish output maps
  for(auto& it: outputAcc)
    {
    const LabelPixelType label = it.first;
    const double count = it.second.GetCount();
    const RealVectorPixelType sum   = it.second.GetSum();
    const RealVectorPixelType sqSum = it.second.GetSqSum();

    // Count
    m_LabelPopulation[label] = count;

    // Mean & stdev
    RealVectorPixelType mean (sum);
    RealVectorPixelType std (sqSum);
    for (unsigned int band = 0 ; band < mean.GetSize() ; band++)
      {
      // Mean
      mean[band] /= count;

      // Unbiased standard deviation (not sure unbiased is usefull here)
      const double variance = (sqSum[band] - (sum[band] * mean[band])) / (count - 1);
      std[band] = std::sqrt(variance);
      }
    m_MeanRadiometricValue[label] = mean;
    m_StDevRadiometricValue[label] = std;

    // Min & max
    m_MinRadiometricValue[label] = it.second.GetMin();
    m_MaxRadiometricValue[label] = it.second.GetMax();
    }

 }

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::Reset()
{
  m_AccumulatorMaps.clear();

  m_MeanRadiometricValue.clear();
  m_StDevRadiometricValue.clear();
  m_MinRadiometricValue.clear();
  m_MaxRadiometricValue.clear();
  m_LabelPopulation.clear();
  m_AccumulatorMaps.resize(this->GetNumberOfThreads());

}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::GenerateInputRequestedRegion()
{
  // The Requested Regions of all the inputs are set to their Largest Possible Regions
  this->itk::ProcessObject::GenerateInputRequestedRegion();

  // Iteration over all the inputs of the current filter (this)
  for( itk::InputDataObjectIterator it( this ); !it.IsAtEnd(); it++ )
    {
    // Check whether the input is an image of the appropriate dimension
    // dynamic_cast of all the input images as itk::ImageBase objects
    // in order to pass the if ( input ) test whatever the inputImageType (vectorImage or labelImage)
    ImageBaseType * input = dynamic_cast< ImageBaseType *>( it.GetInput() );

    if ( input )
      {
      // Use the function object RegionCopier to copy the output region
      // to the input.  The default region copier has default implementations
      // to handle the cases where the input and output are the same
      // dimension, the input a higher dimension than the output, and the
      // input a lower dimension than the output.
      InputImageRegionType inputRegion;
      this->CallCopyOutputRegionToInputRegion( inputRegion, this->GetOutput()->GetRequestedRegion() );
      input->SetRequestedRegion(inputRegion);
      }
    }
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId )
{
  /**
   * Grab the input
   */
  InputVectorImagePointer inputPtr =  const_cast<TInputVectorImage *>(this->GetInput());
  LabelImagePointer labelInputPtr =  const_cast<TLabelImage *>(this->GetInputLabelImage());

  itk::ImageRegionConstIterator<TInputVectorImage> inIt(inputPtr, outputRegionForThread);
  itk::ImageRegionConstIterator<TLabelImage> labelIt(labelInputPtr, outputRegionForThread);

  typename VectorImageType::PixelType value;
  typename LabelImageType::PixelType label;

  // do the work
  for (inIt.GoToBegin(), labelIt.GoToBegin();
       !inIt.IsAtEnd() && !labelIt.IsAtEnd();
       ++inIt, ++labelIt)
    {
      value = inIt.Get();
      label = labelIt.Get();

      // Update the accumulator
      if (m_AccumulatorMaps[threadId].count(label) <= 0) //add new element to the map
        {
        AccumulatorType newAcc(value);
        m_AccumulatorMaps[threadId][label] = newAcc;
        }
      else
        {
        m_AccumulatorMaps[threadId][label].Update(value);
        }
    }
}

template<class TInputVectorImage, class TLabelImage>
void
PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

} // end namespace otb
#endif
<|endoftext|>