<commit_before>#include "game.hpp"
#include <stdexcept>
#include <iostream>

Game::Game():
  tetromino_{static_cast<Tetromino::Type>(rand() % 7)},
  moveTime_(SDL_GetTicks())
{
  if (SDL_Init(SDL_INIT_VIDEO) != 0)
    throw std::runtime_error("SDL_Init(SDL_INIT_VIDEO)");
  SDL_CreateWindowAndRenderer(720 / 2, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS, &window_, &renderer_);
  SDL_SetWindowPosition(window_, 65, 126);
}

Game::~Game()
{
  SDL_DestroyRenderer(renderer_);
  SDL_DestroyWindow(window_);
  SDL_Quit();
}

bool Game::tick()
{
  SDL_Event e;
  while (SDL_PollEvent(&e))
  {
    switch (e.type)
    {
    case SDL_KEYDOWN:
      {
        switch (e.key.keysym.sym)
        {
        case SDLK_DOWN:
          {
            Tetromino t = tetromino_;
            t.move(0, 1);
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        case SDLK_RIGHT:
          {
            Tetromino t = tetromino_;
            t.move(1, 0);
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        case SDLK_LEFT:
          {
            Tetromino t = tetromino_;
            t.move(-1, 0);
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        case SDLK_UP:
          {
            Tetromino t = tetromino_;
            t.rotate();
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        }
      }
      break;
    case SDL_QUIT:
      return false;
    }
  }
  SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0xff);
  SDL_RenderClear(renderer_);
  well_.draw(renderer_);
  tetromino_.draw(renderer_);
  if (SDL_GetTicks() > moveTime_)
  {
    moveTime_ += 1000;
    Tetromino t = tetromino_;
    t.move(0, 1);
    check(t);
  }
  SDL_RenderPresent(renderer_);
  return true;
};

void Game::check(const Tetromino &t)
{
  if (well_.isCollision(t))
  {
    well_.unite(tetromino_);
    tetromino_ = Tetromino{static_cast<Tetromino::Type>(rand() % 7)};
    if (well_.isCollision(tetromino_))
    {
      well_ = Well();
    }
  }
  else
  {
    tetromino_ = t;
  }
}
<commit_msg>Be friendly with CPU<commit_after>#include "game.hpp"
#include <stdexcept>
#include <iostream>

Game::Game():
  tetromino_{static_cast<Tetromino::Type>(rand() % 7)},
  moveTime_(SDL_GetTicks())
{
  if (SDL_Init(SDL_INIT_VIDEO) != 0)
    throw std::runtime_error("SDL_Init(SDL_INIT_VIDEO)");
  SDL_CreateWindowAndRenderer(720 / 2, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS, &window_, &renderer_);
  SDL_SetWindowPosition(window_, 65, 126);
}

Game::~Game()
{
  SDL_DestroyRenderer(renderer_);
  SDL_DestroyWindow(window_);
  SDL_Quit();
}

bool Game::tick()
{
  SDL_Event e;
  if (SDL_WaitEventTimeout(&e, 250))
  {
    switch (e.type)
    {
    case SDL_KEYDOWN:
      {
        switch (e.key.keysym.sym)
        {
        case SDLK_DOWN:
          {
            Tetromino t = tetromino_;
            t.move(0, 1);
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        case SDLK_RIGHT:
          {
            Tetromino t = tetromino_;
            t.move(1, 0);
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        case SDLK_LEFT:
          {
            Tetromino t = tetromino_;
            t.move(-1, 0);
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        case SDLK_UP:
          {
            Tetromino t = tetromino_;
            t.rotate();
            if (!well_.isCollision(t))
              tetromino_ = t;
          }
          break;
        }
      }
      break;
    case SDL_QUIT:
      return false;
    }
  }
  SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0xff);
  SDL_RenderClear(renderer_);
  well_.draw(renderer_);
  tetromino_.draw(renderer_);
  if (SDL_GetTicks() > moveTime_)
  {
    moveTime_ += 1000;
    Tetromino t = tetromino_;
    t.move(0, 1);
    check(t);
  }
  SDL_RenderPresent(renderer_);
  return true;
};

void Game::check(const Tetromino &t)
{
  if (well_.isCollision(t))
  {
    well_.unite(tetromino_);
    tetromino_ = Tetromino{static_cast<Tetromino::Type>(rand() % 7)};
    if (well_.isCollision(tetromino_))
    {
      well_ = Well();
    }
  }
  else
  {
    tetromino_ = t;
  }
}
<|endoftext|>


<commit_before>#include "DepthImage.hpp"

#include <pcl/range_image/range_image_planar.h>

#include "Utils.hpp"

namespace pcl {
class RangeImageProjective : public RangeImagePlanar {
public:
  RangeImage* getNew() const { return new RangeImageProjective(); }
  Ptr makeShared() { return Ptr(new RangeImageProjective(*this)); }

  void setPose(const Eigen::Isometry3f& iPose) {
    to_world_system_ = iPose;
    to_range_image_system_ = iPose.inverse();
  }
};

class RangeImageOrthographic : public RangeImageProjective {
public:
  RangeImage* getNew() const { return new RangeImageOrthographic(); }
  Ptr makeShared() { return Ptr(new RangeImageOrthographic(*this)); }

  inline void calculate3DPoint(float iX, float iY, float iDepth,
                               Eigen::Vector3f& oPoint) const {
    oPoint = mProjectorInv*Eigen::Vector3f(iX, iY, iDepth);
  }

  inline void getImagePoint(const Eigen::Vector3f& iPoint,
                            float& oX, float& oY, float& oDepth) const {
    Eigen::Vector3f pt = mProjector*iPoint;
    oX = pt[0];
    oY = pt[1];
    oDepth = pt[2];
  }

  void setDepthImage(const float* iDepth, int iWidth, int iHeight,
                     float iCenterX, float iCenterY,
                     float iFocalX, float iFocalY, float iAngRes=-1) {
    RangeImagePlanar::setDepthImage(iDepth, iWidth, iHeight, iCenterX,
                                    iCenterY, iFocalX, iFocalY, iAngRes);
    Eigen::Affine3f calib = Eigen::Affine3f::Identity();
    calib(0,0) = focal_length_x_;
    calib(1,1) = focal_length_y_;
    calib(0,3) = center_x_;
    calib(1,3) = center_y_;
    mProjector = calib*to_range_image_system_;
    mProjectorInv = mProjector.inverse();
  }

protected:
  Eigen::Affine3f mProjector;
  Eigen::Affine3f mProjectorInv;
};

}

using namespace maps;

struct DepthImage::Helper {
  int mWidth;
  int mHeight;
  std::vector<float> mData;
  Eigen::Isometry3f mPose;
  Eigen::Isometry3f mPoseInv;
  Eigen::Matrix3f mCalib;
  Eigen::Matrix3f mCalibInv;
  Eigen::Projective3f mProjector;
  Eigen::Projective3f mProjectorInv;
  bool mIsOrthographic;
  AccumulationMethod mAccumulationMethod;
  std::vector<bool> mDataNeedsUpdate;
  std::vector<std::vector<float> > mDataCache;

  Helper() {
    mWidth = 0;
    mHeight = 0;
    mPose = Eigen::Isometry3f::Identity();
    mCalib = Eigen::Matrix3f::Identity();
    mProjector = Eigen::Projective3f::Identity();
    mIsOrthographic = true;
    mAccumulationMethod = AccumulationMethodClosest;
    mDataCache.resize(3);
    mDataNeedsUpdate.resize(mDataCache.size());
    updateMatrices();
  }

  void updateMatrices() {
    Utils::composeViewMatrix(mProjector, mCalib, mPose, mIsOrthographic);
    mCalibInv = mCalib.inverse();
    mPoseInv = mPose.inverse();
    mProjectorInv = mProjector.inverse();
    invalidateData();
  }

  void invalidateData() {
    for (int i = 0; i < mDataNeedsUpdate.size(); ++i) {
      mDataNeedsUpdate[i] = true;
    }
    mDataNeedsUpdate[TypeDisparity] = false;
  }
};

DepthImage::
DepthImage() {
  mHelper.reset(new Helper());
}

DepthImage::
~DepthImage() {
}

void DepthImage::
setSize(const int iWidth, const int iHeight) {
  mHelper->mWidth = iWidth;
  mHelper->mHeight = iHeight;
  mHelper->mData.resize(mHelper->mWidth * mHelper->mHeight);
  mHelper->invalidateData();
}

int DepthImage::
getWidth() const {
  return mHelper->mWidth;
}

int DepthImage::
getHeight() const {
  return mHelper->mHeight;
}

const float DepthImage::
getInvalidValue(const Type iType) const {
  if (mHelper->mIsOrthographic) return std::numeric_limits<float>::infinity();
  return (iType==TypeDisparity ? 0 : std::numeric_limits<float>::infinity());
}

bool DepthImage::
setData(const std::vector<float>& iData, const Type iType) {
  if (iData.size() != mHelper->mWidth * mHelper->mHeight) return false;

  if (mHelper->mIsOrthographic || (iType == TypeDisparity)) {
    mHelper->mData = iData;
  }
  else {
    if (iType == TypeDepth) {
      for (int i = 0; i < iData.size(); ++i) {
        mHelper->mData[i] = 1/iData[i];
      }
    }
    else if (iType == TypeRange) {
      float invalidValue = getInvalidValue(iType);
      float invalidDisparity = getInvalidValue(TypeDisparity);
      for (int i = 0, idx = 0; i < mHelper->mHeight; ++i) {
        for (int j = 0; j < mHelper->mWidth; ++j, ++idx) {
          Eigen::Vector3f pt = mHelper->mCalibInv*Eigen::Vector3f(j,i,1);
          if (iData[idx] == invalidValue) {
            mHelper->mData[idx] = invalidDisparity;
          } else mHelper->mData[idx] = pt.norm()/(pt[2]*iData[idx]);
        }
      }
    }
  }
  mHelper->invalidateData();
  return true;
}

const std::vector<float>& DepthImage::
getData(const Type iType) const {
  if (mHelper->mIsOrthographic || (iType == TypeDisparity)) {
    return mHelper->mData;
  }

  if (mHelper->mDataNeedsUpdate[iType]) {
    std::vector<float>& data = mHelper->mDataCache[iType];
    int size = mHelper->mData.size();
    data.resize(size);

    if (iType == TypeDepth) {
      for (int i = 0; i < size; ++i) {
        data[i] = 1/mHelper->mData[i];
      }
    }

    else if (iType == TypeRange) {
      float invalidValue = getInvalidValue(iType);
      float invalidDisparity = getInvalidValue(TypeDisparity);
      for (int i = 0, idx = 0; i < mHelper->mHeight; ++i) {
        for (int j = 0; j < mHelper->mWidth; ++j, ++idx) {
          Eigen::Vector3f pt = mHelper->mCalibInv*Eigen::Vector3f(j,i,1);
          if (mHelper->mData[idx] == invalidDisparity) data[idx] = invalidValue;
          else data[idx] = (mHelper->mCalibInv*Eigen::Vector3f(j,i,1) /
                            mHelper->mData[idx]).norm();
        }
      }
    }

    mHelper->mDataNeedsUpdate[iType] = false;
  }

  return mHelper->mDataCache[iType];
}

void DepthImage::
setOrthographic(const bool iVal) {
  mHelper->mIsOrthographic = iVal;
  mHelper->updateMatrices();
}

bool DepthImage::
isOrthographic() const {
  return mHelper->mIsOrthographic;
}

void DepthImage::
setPose(const Eigen::Isometry3f& iPose) {
  mHelper->mPose = iPose;
  mHelper->updateMatrices();
}

Eigen::Isometry3f DepthImage::
getPose() const {
  return mHelper->mPose;
}

void DepthImage::
setCalib(const Eigen::Matrix3f& iCalib) {
  mHelper->mCalib = iCalib;
  mHelper->updateMatrices();
}

Eigen::Matrix3f DepthImage::
getCalib() const {
  return mHelper->mCalib;
}

void DepthImage::
setProjector(const Eigen::Projective3f& iProjector) {
  mHelper->mProjector = iProjector;
  Utils::factorViewMatrix(mHelper->mProjector, mHelper->mCalib,
                          mHelper->mPose, mHelper->mIsOrthographic);
  mHelper->updateMatrices();
}

Eigen::Projective3f DepthImage::
getProjector() const {
  return mHelper->mProjector;
}

void DepthImage::
setAccumulationMethod(const AccumulationMethod iMethod) {
  mHelper->mAccumulationMethod = iMethod;
}

void DepthImage::
create(const maps::PointCloud::Ptr& iCloud) {
  float invalidValue = getInvalidValue(TypeDisparity);
  std::fill(mHelper->mData.begin(), mHelper->mData.end(), invalidValue);

  std::vector<std::vector<float> > lists;
  std::vector<float> sums;
  std::vector<int> counts;
  AccumulationMethod method = mHelper->mAccumulationMethod;
  if ((method == AccumulationMethodMedian) ||
      (method == AccumulationMethodClosestPercentile)) {
    lists.resize(mHelper->mWidth * mHelper->mHeight);
  }
  else if (method == AccumulationMethodMean) {
    sums.resize(mHelper->mWidth * mHelper->mHeight);
    std::fill(sums.begin(), sums.end(), 0);
    counts.resize(sums.size());
    std::fill(counts.begin(), counts.end(), 0);
  }

  for (int i = 0; i < iCloud->size(); ++i) {
    maps::PointCloud::PointType& ptCur = (*iCloud)[i];
    Eigen::Vector4f pt(ptCur.x, ptCur.y, ptCur.z, 1);
    pt = mHelper->mProjector*pt;
    Eigen::Vector3f proj = pt.head<3>()/pt[3];
    int x(proj[0]+0.5f), y(proj[1]+0.5f);
    if ((x < 0) || (x >= mHelper->mWidth) ||
        (y < 0) || (y >= mHelper->mHeight)) continue;
    int idx = y*mHelper->mWidth + x;
    float z = proj[2];
    switch (method) {
    case AccumulationMethodClosest:
      if ((mHelper->mIsOrthographic && (z < mHelper->mData[idx])) ||
          (!mHelper->mIsOrthographic && (z > mHelper->mData[idx]))) {
        mHelper->mData[idx] = z;
      }
      break;
    case AccumulationMethodFurthest:
      if ((mHelper->mData[idx] == invalidValue) ||
          (mHelper->mIsOrthographic && (z > mHelper->mData[idx])) ||
          (!mHelper->mIsOrthographic && (z < mHelper->mData[idx]))) {
        mHelper->mData[idx] = z;
      }
      break;
    case AccumulationMethodMedian:
    case AccumulationMethodClosestPercentile:
      lists[idx].push_back(z);
      break;
    case AccumulationMethodMean:
      sums[idx] += 1/z;
      ++counts[idx];
      break;
    default:
      break;
    }
  }

  if ((method == AccumulationMethodMedian) ||
      (method == AccumulationMethodClosestPercentile)) {
    float percentile = 0.5f;
    if (method == AccumulationMethodClosestPercentile) {
      if (mHelper->mIsOrthographic) percentile = 0.1f;
      else percentile = 0.9f;
    }
    for (int i = 0; i < lists.size(); ++i) {
      int n = lists[i].size();
      if (n == 0) continue;
      std::sort(lists[i].begin(), lists[i].end());
      mHelper->mData[i] = lists[i][(int)(percentile*n)];
    }
  }
  else if (method == AccumulationMethodMean) {
    for (int i = 0; i < sums.size(); ++i) {
      if (counts[i] == 0) continue;
      mHelper->mData[i] = counts[i]/sums[i];
    }
  }

  mHelper->invalidateData();
}

maps::PointCloud::Ptr DepthImage::
getAsPointCloud() const {
  maps::PointCloud::Ptr cloud(new maps::PointCloud());
  cloud->reserve(mHelper->mWidth * mHelper->mHeight);
  float invalidValue = getInvalidValue(TypeDisparity);
  for (int i = 0, idx = 0; i < mHelper->mHeight; ++i) {
    for (int j = 0; j < mHelper->mWidth; ++j, ++idx) {
      float z = mHelper->mData[idx];
      if (z == invalidValue) continue;
      Eigen::Vector3f pt(j,i,z);
      pt = unproject(pt, TypeDisparity);
      maps::PointCloud::PointType p;
      p.getVector3fMap() = pt;
      cloud->push_back(p);
    }
  }
  return cloud;
}

pcl::RangeImage::Ptr DepthImage::
getAsRangeImage() const {
  const std::vector<float> depths = getData(TypeDepth);
  pcl::RangeImageProjective* rangeImage;
  if (mHelper->mIsOrthographic) rangeImage = new pcl::RangeImageOrthographic();
  else rangeImage = new pcl::RangeImageProjective();
  rangeImage->setPose(mHelper->mPose);
  rangeImage->setDepthImage(&depths[0], mHelper->mWidth, mHelper->mHeight,
                            mHelper->mCalib(0,2), mHelper->mCalib(1,2),
                            mHelper->mCalib(0,0), mHelper->mCalib(1,1));
  return pcl::RangeImage::Ptr(rangeImage);
}

Eigen::Vector3f DepthImage::
project(const Eigen::Vector3f& iPoint, const Type iType) const {
  if (mHelper->mIsOrthographic) {
    Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
    return (mHelper->mProjector*pt).head<3>();
  }
  else {
    if (iType == TypeDepth) {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
      pt = mHelper->mProjector*pt;
      float wInv = 1/pt[3];
      return Eigen::Vector3f(pt[0]*wInv, pt[1]*wInv, pt[2]);
    }
    else if (iType == TypeRange) {
      Eigen::Vector3f pt = mHelper->mPoseInv*iPoint;
      float range = pt.norm();
      pt = mHelper->mCalib*pt;
      float wInv = pt[2];
      return Eigen::Vector3f(pt[0]*wInv, pt[1]*wInv, range);
    }
    else {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
      pt = mHelper->mProjector*pt;
      return pt.head<3>()/pt[3];
    }
  }
}

Eigen::Vector3f DepthImage::
unproject(const Eigen::Vector3f& iPoint, const Type iType) const {
  if (mHelper->mIsOrthographic) {
    Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
    return (mHelper->mProjectorInv*pt).head<3>();
  }
  else {
    if (iType == TypeDepth) {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], 1, 1/iPoint[2]);
      pt = mHelper->mProjectorInv*pt;
      return pt.head<3>()/pt[3];
    }
    else if (iType == TypeRange) {
      Eigen::Vector3f pt = mHelper->mCalibInv*iPoint;
      pt *= (iPoint[2]/pt.norm());
      return mHelper->mPose*pt;
    }
    else {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
      pt = mHelper->mProjectorInv*pt;
      return pt.head<3>()/pt[3];
    }
  }
}
<commit_msg>check for points behind sensor in depth projection<commit_after>#include "DepthImage.hpp"

#include <pcl/range_image/range_image_planar.h>

#include "Utils.hpp"

namespace pcl {
class RangeImageProjective : public RangeImagePlanar {
public:
  RangeImage* getNew() const { return new RangeImageProjective(); }
  Ptr makeShared() { return Ptr(new RangeImageProjective(*this)); }

  void setPose(const Eigen::Isometry3f& iPose) {
    to_world_system_ = iPose;
    to_range_image_system_ = iPose.inverse();
  }
};

class RangeImageOrthographic : public RangeImageProjective {
public:
  RangeImage* getNew() const { return new RangeImageOrthographic(); }
  Ptr makeShared() { return Ptr(new RangeImageOrthographic(*this)); }

  inline void calculate3DPoint(float iX, float iY, float iDepth,
                               Eigen::Vector3f& oPoint) const {
    oPoint = mProjectorInv*Eigen::Vector3f(iX, iY, iDepth);
  }

  inline void getImagePoint(const Eigen::Vector3f& iPoint,
                            float& oX, float& oY, float& oDepth) const {
    Eigen::Vector3f pt = mProjector*iPoint;
    oX = pt[0];
    oY = pt[1];
    oDepth = pt[2];
  }

  void setDepthImage(const float* iDepth, int iWidth, int iHeight,
                     float iCenterX, float iCenterY,
                     float iFocalX, float iFocalY, float iAngRes=-1) {
    RangeImagePlanar::setDepthImage(iDepth, iWidth, iHeight, iCenterX,
                                    iCenterY, iFocalX, iFocalY, iAngRes);
    Eigen::Affine3f calib = Eigen::Affine3f::Identity();
    calib(0,0) = focal_length_x_;
    calib(1,1) = focal_length_y_;
    calib(0,3) = center_x_;
    calib(1,3) = center_y_;
    mProjector = calib*to_range_image_system_;
    mProjectorInv = mProjector.inverse();
  }

protected:
  Eigen::Affine3f mProjector;
  Eigen::Affine3f mProjectorInv;
};

}

using namespace maps;

struct DepthImage::Helper {
  int mWidth;
  int mHeight;
  std::vector<float> mData;
  Eigen::Isometry3f mPose;
  Eigen::Isometry3f mPoseInv;
  Eigen::Matrix3f mCalib;
  Eigen::Matrix3f mCalibInv;
  Eigen::Projective3f mProjector;
  Eigen::Projective3f mProjectorInv;
  bool mIsOrthographic;
  AccumulationMethod mAccumulationMethod;
  std::vector<bool> mDataNeedsUpdate;
  std::vector<std::vector<float> > mDataCache;

  Helper() {
    mWidth = 0;
    mHeight = 0;
    mPose = Eigen::Isometry3f::Identity();
    mCalib = Eigen::Matrix3f::Identity();
    mProjector = Eigen::Projective3f::Identity();
    mIsOrthographic = true;
    mAccumulationMethod = AccumulationMethodClosest;
    mDataCache.resize(3);
    mDataNeedsUpdate.resize(mDataCache.size());
    updateMatrices();
  }

  void updateMatrices() {
    Utils::composeViewMatrix(mProjector, mCalib, mPose, mIsOrthographic);
    mCalibInv = mCalib.inverse();
    mPoseInv = mPose.inverse();
    mProjectorInv = mProjector.inverse();
    invalidateData();
  }

  void invalidateData() {
    for (int i = 0; i < mDataNeedsUpdate.size(); ++i) {
      mDataNeedsUpdate[i] = true;
    }
    mDataNeedsUpdate[TypeDisparity] = false;
  }
};

DepthImage::
DepthImage() {
  mHelper.reset(new Helper());
}

DepthImage::
~DepthImage() {
}

void DepthImage::
setSize(const int iWidth, const int iHeight) {
  mHelper->mWidth = iWidth;
  mHelper->mHeight = iHeight;
  mHelper->mData.resize(mHelper->mWidth * mHelper->mHeight);
  mHelper->invalidateData();
}

int DepthImage::
getWidth() const {
  return mHelper->mWidth;
}

int DepthImage::
getHeight() const {
  return mHelper->mHeight;
}

const float DepthImage::
getInvalidValue(const Type iType) const {
  if (mHelper->mIsOrthographic) return std::numeric_limits<float>::infinity();
  return (iType==TypeDisparity ? 0 : std::numeric_limits<float>::infinity());
}

bool DepthImage::
setData(const std::vector<float>& iData, const Type iType) {
  if (iData.size() != mHelper->mWidth * mHelper->mHeight) return false;

  if (mHelper->mIsOrthographic || (iType == TypeDisparity)) {
    mHelper->mData = iData;
  }
  else {
    if (iType == TypeDepth) {
      for (int i = 0; i < iData.size(); ++i) {
        mHelper->mData[i] = 1/iData[i];
      }
    }
    else if (iType == TypeRange) {
      float invalidValue = getInvalidValue(iType);
      float invalidDisparity = getInvalidValue(TypeDisparity);
      for (int i = 0, idx = 0; i < mHelper->mHeight; ++i) {
        for (int j = 0; j < mHelper->mWidth; ++j, ++idx) {
          Eigen::Vector3f pt = mHelper->mCalibInv*Eigen::Vector3f(j,i,1);
          if (iData[idx] == invalidValue) {
            mHelper->mData[idx] = invalidDisparity;
          } else mHelper->mData[idx] = pt.norm()/(pt[2]*iData[idx]);
        }
      }
    }
  }
  mHelper->invalidateData();
  return true;
}

const std::vector<float>& DepthImage::
getData(const Type iType) const {
  if (mHelper->mIsOrthographic || (iType == TypeDisparity)) {
    return mHelper->mData;
  }

  if (mHelper->mDataNeedsUpdate[iType]) {
    std::vector<float>& data = mHelper->mDataCache[iType];
    int size = mHelper->mData.size();
    data.resize(size);

    if (iType == TypeDepth) {
      for (int i = 0; i < size; ++i) {
        data[i] = 1/mHelper->mData[i];
      }
    }

    else if (iType == TypeRange) {
      float invalidValue = getInvalidValue(iType);
      float invalidDisparity = getInvalidValue(TypeDisparity);
      for (int i = 0, idx = 0; i < mHelper->mHeight; ++i) {
        for (int j = 0; j < mHelper->mWidth; ++j, ++idx) {
          Eigen::Vector3f pt = mHelper->mCalibInv*Eigen::Vector3f(j,i,1);
          if (mHelper->mData[idx] == invalidDisparity) data[idx] = invalidValue;
          else data[idx] = (mHelper->mCalibInv*Eigen::Vector3f(j,i,1) /
                            mHelper->mData[idx]).norm();
        }
      }
    }

    mHelper->mDataNeedsUpdate[iType] = false;
  }

  return mHelper->mDataCache[iType];
}

void DepthImage::
setOrthographic(const bool iVal) {
  mHelper->mIsOrthographic = iVal;
  mHelper->updateMatrices();
}

bool DepthImage::
isOrthographic() const {
  return mHelper->mIsOrthographic;
}

void DepthImage::
setPose(const Eigen::Isometry3f& iPose) {
  mHelper->mPose = iPose;
  mHelper->updateMatrices();
}

Eigen::Isometry3f DepthImage::
getPose() const {
  return mHelper->mPose;
}

void DepthImage::
setCalib(const Eigen::Matrix3f& iCalib) {
  mHelper->mCalib = iCalib;
  mHelper->updateMatrices();
}

Eigen::Matrix3f DepthImage::
getCalib() const {
  return mHelper->mCalib;
}

void DepthImage::
setProjector(const Eigen::Projective3f& iProjector) {
  mHelper->mProjector = iProjector;
  Utils::factorViewMatrix(mHelper->mProjector, mHelper->mCalib,
                          mHelper->mPose, mHelper->mIsOrthographic);
  mHelper->updateMatrices();
}

Eigen::Projective3f DepthImage::
getProjector() const {
  return mHelper->mProjector;
}

void DepthImage::
setAccumulationMethod(const AccumulationMethod iMethod) {
  mHelper->mAccumulationMethod = iMethod;
}

void DepthImage::
create(const maps::PointCloud::Ptr& iCloud) {
  float invalidValue = getInvalidValue(TypeDisparity);
  std::fill(mHelper->mData.begin(), mHelper->mData.end(), invalidValue);

  std::vector<std::vector<float> > lists;
  std::vector<float> sums;
  std::vector<int> counts;
  AccumulationMethod method = mHelper->mAccumulationMethod;
  if ((method == AccumulationMethodMedian) ||
      (method == AccumulationMethodClosestPercentile)) {
    lists.resize(mHelper->mWidth * mHelper->mHeight);
  }
  else if (method == AccumulationMethodMean) {
    sums.resize(mHelper->mWidth * mHelper->mHeight);
    std::fill(sums.begin(), sums.end(), 0);
    counts.resize(sums.size());
    std::fill(counts.begin(), counts.end(), 0);
  }

  for (int i = 0; i < iCloud->size(); ++i) {
    maps::PointCloud::PointType& ptCur = (*iCloud)[i];
    Eigen::Vector4f pt(ptCur.x, ptCur.y, ptCur.z, 1);
    pt = mHelper->mProjector*pt;
    Eigen::Vector3f proj = pt.head<3>()/pt[3];
    int x(proj[0]+0.5f), y(proj[1]+0.5f);
    if ((x < 0) || (x >= mHelper->mWidth) ||
        (y < 0) || (y >= mHelper->mHeight)) continue;
    float z = proj[2];
    if (!mHelper->mIsOrthographic && (z <= 0)) continue;
    int idx = y*mHelper->mWidth + x;
    switch (method) {
    case AccumulationMethodClosest:
      if ((mHelper->mIsOrthographic && (z < mHelper->mData[idx])) ||
          (!mHelper->mIsOrthographic && (z > mHelper->mData[idx]))) {
        mHelper->mData[idx] = z;
      }
      break;
    case AccumulationMethodFurthest:
      if ((mHelper->mData[idx] == invalidValue) ||
          (mHelper->mIsOrthographic && (z > mHelper->mData[idx])) ||
          (!mHelper->mIsOrthographic && (z < mHelper->mData[idx]))) {
        mHelper->mData[idx] = z;
      }
      break;
    case AccumulationMethodMedian:
    case AccumulationMethodClosestPercentile:
      lists[idx].push_back(z);
      break;
    case AccumulationMethodMean:
      sums[idx] += 1/z;
      ++counts[idx];
      break;
    default:
      break;
    }
  }

  if ((method == AccumulationMethodMedian) ||
      (method == AccumulationMethodClosestPercentile)) {
    float percentile = 0.5f;
    if (method == AccumulationMethodClosestPercentile) {
      if (mHelper->mIsOrthographic) percentile = 0.1f;
      else percentile = 0.9f;
    }
    for (int i = 0; i < lists.size(); ++i) {
      int n = lists[i].size();
      if (n == 0) continue;
      std::sort(lists[i].begin(), lists[i].end());
      mHelper->mData[i] = lists[i][(int)(percentile*n)];
    }
  }
  else if (method == AccumulationMethodMean) {
    for (int i = 0; i < sums.size(); ++i) {
      if (counts[i] == 0) continue;
      mHelper->mData[i] = counts[i]/sums[i];
    }
  }

  mHelper->invalidateData();
}

maps::PointCloud::Ptr DepthImage::
getAsPointCloud() const {
  maps::PointCloud::Ptr cloud(new maps::PointCloud());
  cloud->reserve(mHelper->mWidth * mHelper->mHeight);
  float invalidValue = getInvalidValue(TypeDisparity);
  for (int i = 0, idx = 0; i < mHelper->mHeight; ++i) {
    for (int j = 0; j < mHelper->mWidth; ++j, ++idx) {
      float z = mHelper->mData[idx];
      if (z == invalidValue) continue;
      Eigen::Vector3f pt(j,i,z);
      pt = unproject(pt, TypeDisparity);
      maps::PointCloud::PointType p;
      p.getVector3fMap() = pt;
      cloud->push_back(p);
    }
  }
  return cloud;
}

pcl::RangeImage::Ptr DepthImage::
getAsRangeImage() const {
  const std::vector<float> depths = getData(TypeDepth);
  pcl::RangeImageProjective* rangeImage;
  if (mHelper->mIsOrthographic) rangeImage = new pcl::RangeImageOrthographic();
  else rangeImage = new pcl::RangeImageProjective();
  rangeImage->setPose(mHelper->mPose);
  rangeImage->setDepthImage(&depths[0], mHelper->mWidth, mHelper->mHeight,
                            mHelper->mCalib(0,2), mHelper->mCalib(1,2),
                            mHelper->mCalib(0,0), mHelper->mCalib(1,1));
  return pcl::RangeImage::Ptr(rangeImage);
}

Eigen::Vector3f DepthImage::
project(const Eigen::Vector3f& iPoint, const Type iType) const {
  if (mHelper->mIsOrthographic) {
    Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
    return (mHelper->mProjector*pt).head<3>();
  }
  else {
    if (iType == TypeDepth) {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
      pt = mHelper->mProjector*pt;
      float wInv = 1/pt[3];
      return Eigen::Vector3f(pt[0]*wInv, pt[1]*wInv, pt[2]);
    }
    else if (iType == TypeRange) {
      Eigen::Vector3f pt = mHelper->mPoseInv*iPoint;
      float range = pt.norm();
      pt = mHelper->mCalib*pt;
      float wInv = pt[2];
      return Eigen::Vector3f(pt[0]*wInv, pt[1]*wInv, range);
    }
    else {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
      pt = mHelper->mProjector*pt;
      return pt.head<3>()/pt[3];
    }
  }
}

Eigen::Vector3f DepthImage::
unproject(const Eigen::Vector3f& iPoint, const Type iType) const {
  if (mHelper->mIsOrthographic) {
    Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
    return (mHelper->mProjectorInv*pt).head<3>();
  }
  else {
    if (iType == TypeDepth) {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], 1, 1/iPoint[2]);
      pt = mHelper->mProjectorInv*pt;
      return pt.head<3>()/pt[3];
    }
    else if (iType == TypeRange) {
      Eigen::Vector3f pt = mHelper->mCalibInv*iPoint;
      pt *= (iPoint[2]/pt.norm());
      return mHelper->mPose*pt;
    }
    else {
      Eigen::Vector4f pt(iPoint[0], iPoint[1], iPoint[2], 1);
      pt = mHelper->mProjectorInv*pt;
      return pt.head<3>()/pt[3];
    }
  }
}
<|endoftext|>


<commit_before>// JsForeignProperty.cpp

#include <Core/Reflection/Reflection.h>
#include "../private/JsForeignObject.h"
#include "../private/JsForeignProperty.h"
#include "../private/Util.h"

namespace sge
{
	template <typename T>
	JsValueRef CALLBACK js_primitive_getter(
		JsValueRef /*callee*/,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short /*argc*/,
		void* callbackState)
	{
		// Get the 'this' argument as a foreign object
		auto* object = JsForeignObject::from_jsref(args[0]);

		// Get the information for the property
		auto* prop = static_cast<const PropertyInfo*>(callbackState);

		// Run the getter
		JsValueRef ret = JS_INVALID_REFERENCE;
		prop->get(object->object(), nullptr, [&ret](Any<> out) {
			ret = from_native_primitive<T>(out);
		});

		return ret;
	}

	template <typename T>
	JsValueRef CALLBACK js_primitive_setter(
		JsValueRef /*callee*/,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short argc,
		void* callbackState)
	{
		// Make sure we have the correct number of arguments
		if (argc < 2)
		{
			return JS_INVALID_REFERENCE;
		}

		// Get the 'this' argument as a foreign object
		auto* object = JsForeignObject::from_jsref(args[0]);

		// Get the 'value' argument as a primitive
		auto value = to_native_primitive<T>(args[1]);

		// Get the information for the property
		auto* prop = static_cast<const PropertyInfo*>(callbackState);

		// Run the setter
		prop->set(object->object(), nullptr, &value);

		return JS_INVALID_REFERENCE;
	}

	template <typename T>
	void create_foreign_primitive_property(
		JsValueRef propertyDescriptor,
		JsPropertyIdRef getPropId,
		JsPropertyIdRef setPropId,
		const PropertyInfo& prop)
	{
		// Create and set the getter
		JsValueRef getter = JS_INVALID_REFERENCE;
		JsCreateFunction(&js_primitive_getter<T>, const_cast<PropertyInfo*>(&prop), &getter);
		JsSetProperty(propertyDescriptor, getPropId, getter, true);

		if (prop.is_read_only())
		{
			return;
		}

		// Create and set the setter
		JsValueRef setter = JS_INVALID_REFERENCE;
		JsCreateFunction(&js_primitive_setter<T>, const_cast<PropertyInfo*>(&prop), &setter);
		JsSetProperty(propertyDescriptor, setPropId, setter, true);
	}

	JsValueRef CALLBACK js_getter_wrapper(
		JsValueRef callee,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short argc,
		void* callbackState)
	{
		// Get the 'this' argument as a foreign object
		auto* self = JsForeignObject::from_jsref(args[0]);

		// Get the property we're getting
		auto* prop = static_cast<const PropertyInfo*>(callbackState);

		// Run the getter for the property
		JsValueRef ret = nullptr;
		prop->get(self->object(), nullptr, [&](Any<> value) {
			//ret = from_native(value);
		});

		return ret;
	}

	JsValueRef CALLBACK js_setter_wrapper(
		JsValueRef /*callee*/,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short argc,
		void* callbackState)
	{
		// Get the 'this' argument as a foreign object
		auto* object = JsForeignObject::from_jsref(args[0]);

		// Get the property we're getting
		auto* prop = static_cast<const PropertyInfo*>(callbackState);

		return nullptr;
	}

	void create_foreign_property(
		JsValueRef propertyDescriptor,
		JsPropertyIdRef getPropId,
		JsPropertyIdRef setPropId,
		const PropertyInfo& prop)
	{
	}

	void register_foreign_property(
		JsValueRef prototype,
		JsValueRef propertyPrototype,
		JsPropertyIdRef getPropId,
		JsPropertyIdRef setPropId,
		const PropertyInfo& prop,
		const std::string& name)
	{
		// Create the propertyDescriptor
		JsValueRef propertyDescriptor = JS_INVALID_REFERENCE;
		JsCreateObject(&propertyDescriptor);
		JsSetPrototype(propertyDescriptor, propertyPrototype);

		if (&prop.type() == &get_type<bool>())
		{
			create_foreign_primitive_property<bool>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int8>())
		{
			create_foreign_primitive_property<int8>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint8>())
		{
			create_foreign_primitive_property<uint8>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int16>())
		{
			create_foreign_primitive_property<int16>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint16>())
		{
			create_foreign_primitive_property<uint16>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int32>())
		{
			create_foreign_primitive_property<int32>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint32>())
		{
			create_foreign_primitive_property<uint32>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int64>())
		{
			create_foreign_primitive_property<int64>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint64>())
		{
			create_foreign_primitive_property<uint64>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<float>())
		{
			create_foreign_primitive_property<float>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<double>())
		{
			create_foreign_primitive_property<double>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else
		{
			create_foreign_property(propertyDescriptor, getPropId, setPropId, prop);
		}

		// Set the property
		bool success = false;
		JsPropertyIdRef propId = JS_INVALID_REFERENCE;
		JsGetPropertyIdFromNameUtf8(name.c_str(), &propId);
		JsDefineProperty(prototype, propId, propertyDescriptor, &success);
	}
}
<commit_msg>Updated 'JsForeignProperty' to support the changes to the property interface<commit_after>// JsForeignProperty.cpp

#include <Core/Reflection/Reflection.h>
#include "../private/JsForeignObject.h"
#include "../private/JsForeignProperty.h"
#include "../private/Util.h"

namespace sge
{
	template <typename T>
	JsValueRef CALLBACK js_primitive_getter(
		JsValueRef /*callee*/,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short /*argc*/,
		void* callbackState)
	{
		// Get the 'this' argument as a foreign object
		auto* object = JsForeignObject::from_jsref(args[0]);

		// Get the information for the property
		auto* prop = static_cast<const PropertyInfo*>(callbackState);

		// Run the getter
		JsValueRef ret = JS_INVALID_REFERENCE;
		prop->get(object->object(), [&ret](Any<> out) {
			ret = from_native_primitive<T>(out);
		});

		return ret;
	}

	template <typename T>
	JsValueRef CALLBACK js_primitive_setter(
		JsValueRef /*callee*/,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short argc,
		void* callbackState)
	{
		// Make sure we have the correct number of arguments
		if (argc < 2)
		{
			return JS_INVALID_REFERENCE;
		}

		// Get the 'this' argument as a foreign object
		auto* object = JsForeignObject::from_jsref(args[0]);

		// Get the 'value' argument as a primitive
		auto value = to_native_primitive<T>(args[1]);

		// Get the information for the property
		auto* prop = static_cast<const PropertyInfo*>(callbackState);

		// Run the setter
		prop->set(object->object(), &value);

		return JS_INVALID_REFERENCE;
	}

	template <typename T>
	void create_foreign_primitive_property(
		JsValueRef propertyDescriptor,
		JsPropertyIdRef getPropId,
		JsPropertyIdRef setPropId,
		const PropertyInfo& prop)
	{
		// Create and set the getter
		JsValueRef getter = JS_INVALID_REFERENCE;
		JsCreateFunction(&js_primitive_getter<T>, const_cast<PropertyInfo*>(&prop), &getter);
		JsSetProperty(propertyDescriptor, getPropId, getter, true);

		if (prop.is_read_only())
		{
			return;
		}

		// Create and set the setter
		JsValueRef setter = JS_INVALID_REFERENCE;
		JsCreateFunction(&js_primitive_setter<T>, const_cast<PropertyInfo*>(&prop), &setter);
		JsSetProperty(propertyDescriptor, setPropId, setter, true);
	}

	static JsValueRef CALLBACK js_getter_wrapper(
		JsValueRef /*callee*/,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short argc,
		void* cbState)
	{
		// Get the 'this' argument as a foreign object
		auto* self = JsForeignObject::from_jsref(args[0]);

		// Get the property we're getting
		auto* prop = static_cast<const PropertyInfo*>(cbState);

		// Run the getter for the property
		JsValueRef ret = JsForeignObject::create_js_foreign_object();
		prop->get(self->object(), [ret](Any<> value) {
			//ret = from_native(value);
		});

		return ret;
	}

	static JsValueRef CALLBACK js_setter_wrapper(
		JsValueRef /*callee*/,
		bool /*isConstructCall*/,
		JsValueRef* args,
		unsigned short argc,
		void* callbackState)
	{
		// Get the 'this' argument as a foreign object
		auto* object = JsForeignObject::from_jsref(args[0]);

		// Get the property we're getting
		auto* prop = static_cast<const PropertyInfo*>(callbackState);

		return nullptr;
	}

	void create_foreign_property(
		JsValueRef propertyDescriptor,
		JsPropertyIdRef getPropId,
		JsPropertyIdRef setPropId,
		const PropertyInfo& prop)
	{
	}

	void register_foreign_property(
		JsValueRef prototype,
		JsValueRef propertyPrototype,
		JsPropertyIdRef getPropId,
		JsPropertyIdRef setPropId,
		const PropertyInfo& prop,
		const std::string& name)
	{
		// Create the propertyDescriptor
		JsValueRef propertyDescriptor = JS_INVALID_REFERENCE;
		JsCreateObject(&propertyDescriptor);
		JsSetPrototype(propertyDescriptor, propertyPrototype);

		if (&prop.type() == &get_type<bool>())
		{
			create_foreign_primitive_property<bool>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int8>())
		{
			create_foreign_primitive_property<int8>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint8>())
		{
			create_foreign_primitive_property<uint8>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int16>())
		{
			create_foreign_primitive_property<int16>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint16>())
		{
			create_foreign_primitive_property<uint16>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int32>())
		{
			create_foreign_primitive_property<int32>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint32>())
		{
			create_foreign_primitive_property<uint32>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<int64>())
		{
			create_foreign_primitive_property<int64>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<uint64>())
		{
			create_foreign_primitive_property<uint64>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<float>())
		{
			create_foreign_primitive_property<float>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else if (&prop.type() == &get_type<double>())
		{
			create_foreign_primitive_property<double>(propertyDescriptor, getPropId, setPropId, prop);
		}
		else
		{
			create_foreign_property(propertyDescriptor, getPropId, setPropId, prop);
		}

		// Set the property
		bool success = false;
		JsPropertyIdRef propId = JS_INVALID_REFERENCE;
		JsGetPropertyIdFromNameUtf8(name.c_str(), &propId);
		JsDefineProperty(prototype, propId, propertyDescriptor, &success);
	}
}
<|endoftext|>


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

#include "otbWrapperChoiceParameter.h"
#include "otbWrapperListViewParameter.h"
#include "otbWrapperBoolParameter.h"
#include "otbWrapperApplicationRegistry.h"

#include <iostream>
#include <cassert>
#include <fstream>

int main(int argc, char* argv[])
{
  if (argc < 3)
    {
    std::cerr << "Usage : " << argv[0] << " name OTB_APPLICATION_PATH [out_dir]" << std::endl;
    return EXIT_FAILURE;
    }

  using namespace otb::Wrapper;

  const std::string module(argv[1]);

  /* TestApplication is removed in CMakeLists.txt */
#if 0
  if (module == "TestApplication")
    return EXIT_SUCCESS;
#endif

  ApplicationRegistry::AddApplicationPath(argv[2]);
  Application::Pointer appli =  ApplicationRegistry::CreateApplicationFaster(module);

  assert(!appli.IsNull());

  const std::string group = appli->GetDocTags().size() > 0 ? appli->GetDocTags()[0] : "";
  assert(!group.empty());

  std::map<ParameterType, std::string> parameterTypeToString;
  parameterTypeToString[ParameterType_Empty] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Bool] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Int] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Float] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_RAM] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Radius] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Choice] = "OTBParameterChoice";
  parameterTypeToString[ParameterType_String] = "QgsProcessingParameterString";
  parameterTypeToString[ParameterType_InputImage] = "QgsProcessingParameterRasterLayer";
  parameterTypeToString[ParameterType_InputFilename] = "QgsProcessingParameterFile";
  parameterTypeToString[ParameterType_InputImageList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorData] = "QgsProcessingParameterVectorLayer";
  parameterTypeToString[ParameterType_InputFilenameList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorDataList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_OutputImage] = "QgsProcessingParameterRasterDestination";
  parameterTypeToString[ParameterType_OutputVectorData] = "QgsProcessingParameterVectorDestination";
  parameterTypeToString[ParameterType_OutputFilename] = "QgsProcessingParameterFileDestination";
  parameterTypeToString[ParameterType_Directory] = "QgsProcessingParameterFile";
  // TODO
  parameterTypeToString[ParameterType_StringList] = "QgsProcessingParameterString";
  // ListView parameters are treated as plain string (QLineEdit) in qgis processing ui.
  // This seems rather unpleasant when comparing Qgis processing with Monteverdi/Mapla in OTB
  // We tried to push something simple with checkboxes but its too risky for this version
  // and clock is ticking...

  parameterTypeToString[ParameterType_ListView] = "QgsProcessingParameterString";

  // For next update of plugin code ListView should use a custom widget wrapper and behave
  // exactly like OTB Mapla. And this #if 0 block is our TODO remainder.
  #if 0
  parameterTypeToString[ParameterType_ListView] = "OTBParameterListView";
  #endif

  const std::vector<std::string> appKeyList = appli->GetParametersKeys(true);
  const unsigned int nbOfParam = appKeyList.size();

  std::string output_file = module + ".txt";
  std::string  algs_txt = "algs.txt";
  if (argc > 3)
    {
    output_file = std::string(argv[3]) + module + ".txt";
    algs_txt = std::string(argv[3])  +  "algs.txt";
    }
  std::ofstream dFile;
  dFile.open (output_file, std::ios::out);

  std::string output_parameter_name;
  bool hasRasterOutput = false;
  {
  for (unsigned int i = 0; i < nbOfParam; i++)
    {
    Parameter::Pointer param = appli->GetParameterByKey(appKeyList[i]);
    if (param->GetMandatory())
      {
	if (appli->GetParameterType(appKeyList[i]) == ParameterType_OutputImage)
	  {
	    output_parameter_name = appKeyList[i];
	    hasRasterOutput = true;
	  }
      }
    }
  }

  if(output_parameter_name.empty())
    dFile << module << std::endl;
  else
    dFile << module << "|" <<  output_parameter_name << std::endl;

  dFile << appli->GetDescription() << std::endl;
  dFile << group << std::endl;

  for (unsigned int i = 0; i < nbOfParam; i++)
    {
    const std::string name = appKeyList[i];
    const Parameter::Pointer param = appli->GetParameterByKey(name);
    const ParameterType type = appli->GetParameterType(name);
    const std::string description = param->GetName();
    if (  type == ParameterType_Group  ||
          type == ParameterType_OutputProcessXML  ||
          type == ParameterType_InputProcessXML  ||
          type == ParameterType_RAM ||
          param->GetRole() == Role_Output )
      {
      // group parameter cannot have any value.
      // outxml and inxml parameters are not relevant for QGIS and is considered a bit noisy
      // ram is added by qgis-otb processing provider plugin as an advanced parameter for all apps
      // parameter role cannot be of type Role_Output
      continue;
      }
    auto it = parameterTypeToString.find(type);
    assert(  it != parameterTypeToString.end() );
    if( it == parameterTypeToString.end() )
      {
      std::cerr << "No mapping found for parameter '" <<name <<"' type=" << type << std::endl;
      return EXIT_FAILURE;
      }
    std::string qgis_type = it->second;
#if 0
      if (type == ParameterType_ListView)
	{
	  ListViewParameter *lv_param = dynamic_cast<ListViewParameter*>(param.GetPointer());
	  std::cerr << "lv_param->GetSingleSelection()" << lv_param->GetSingleSelection() << std::endl;
	  if (lv_param->GetSingleSelection())
	    {

	      qgis_type = "QgsProcessingParameterEnum";
	      std::vector<std::string>  key_list  = appli->GetChoiceKeys(name);
	      std::string values = "";
	      for( auto k : key_list)
		values += k + ";";
	      values.pop_back();
	      dFile << "|" << values ;
	    }
	}
#endif

    bool isDestination = false;
    bool isEpsgCode = false;

    // use QgsProcessingParameterCrs if required.
    // TODO: do a regex on name to match ==epsg || *\.epsg.\*
    if ( name == "epsg"
	      || name == "map.epsg.code"
	      || name == "mapproj.epsg.code"
	      || name == "mode.epsg.code")
        {
        qgis_type = "QgsProcessingParameterCrs";
        isEpsgCode = true;
        }

    dFile << qgis_type << "|" << name << "|" << description;

      std::string default_value = "None";
    if (type == ParameterType_Int)
      {
      if (isEpsgCode)
        {
          if (param->HasValue() && appli->GetParameterInt(name) < 1)
    	default_value =  "EPSG: " + appli->GetParameterAsString(name);
          else
    	default_value =  "ProjectCrs";
        }
      else
        {
        dFile << "|QgsProcessingParameterNumber.Integer";
        default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
        }
      }
    else if (type == ParameterType_Float)
      {
      dFile << "|QgsProcessingParameterNumber.Double";
      default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
      }
    else if (type == ParameterType_Radius)
      {
      dFile << "|QgsProcessingParameterNumber.Integer";
      default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
      }
    else if(type == ParameterType_InputFilename)
      {
      // TODO: if parameter InputFilename can give supported extensions
      // we can use it gitlab #1559
      dFile << "|QgsProcessingParameterFile.File|None";
      }
    else if(type == ParameterType_Directory)
      {
      dFile << "|QgsProcessingParameterFile.Folder|False";
      }
    else if (type == ParameterType_InputImageList)
      {
      dFile << "|3"; //QgsProcessing.TypeRaster
      }
    else if (type == ParameterType_InputVectorDataList)
      {
      dFile << "|-1"; //QgsProcessing.TypeVectorAnyGeometry
      }
    else if (type == ParameterType_InputVectorData)
      {
      dFile << "|-1"; //QgsProcessing.TypeVectorAnyGeometry
      }
    else if(type == ParameterType_InputFilenameList)
      {
      dFile << "|4"; //QgsProcessing.TypeFile"
      }
    else if(type == ParameterType_String)
      {
      // Below line is interpreted in qgis processing as
      // 1. default_value = None
      // 2. multiLine = False
      // For more details,
      // please refer to documetation of QgsProcessingParameterString.
      default_value = "None|False";
      }
    else if(type == ParameterType_StringList)
      {
      // Below line is interpreted in qgis processing as
      // 1. default_value = None
      // 2. multiLine = True
      // For more details,
      // please refer to documetation of QgsProcessingParameterString.
      // setting default_value this way is an exception for ParameterType_StringList and ParameterType_String
      default_value = "None|True";
      }
    else if (type == ParameterType_InputImage)
      {
      // default is None and nothing to add to dFile
      }
    else if(type == ParameterType_ListView)
      {
      // default is None and nothing to add to dFile
      }
    else if(type == ParameterType_Bool)
      {
      default_value = appli->GetParameterAsString(name);
      }
    else if(type == ParameterType_Choice)
      {
      std::vector<std::string>  key_list  = appli->GetChoiceKeys(name);
      std::string values = "";
      for( auto k : key_list)
        values += k + ";";

  	  values.pop_back();
  	  dFile << "|" << values ;
  	  ChoiceParameter *cparam = dynamic_cast<ChoiceParameter*>(param.GetPointer());
  	  default_value = std::to_string(cparam->GetValue());
      }
    else if(type == ParameterType_OutputVectorData ||
	          type == ParameterType_OutputImage ||
	          type == ParameterType_OutputFilename)
      {
      // No need for default_value, optional and extra fields in dFile.
      // If parameter is a destination type. qgis_type|name|description is enough.
      // So we simply set isDestination to true and skip to end to append a new line.
      isDestination =  true;
      }
    else
      {
      std::cout << "ERROR: default_value is empty for '" << name << "' type='" << qgis_type << "'" << std::endl;
      return EXIT_FAILURE;
      }

    if (!isDestination)
      {
      std::string optional;
      if (param->GetMandatory())
        {
        // TODO: avoid workaround for stringlist types (fix appengine)
        // type == ParameterType_StringList check is needed because:
        // If parameter is mandatory it can have no value
        // It is accepted in OTB that, string list could be generated dynamically
        // qgis has no such option to handle dynamic values yet..
        // So mandatory parameters whose type is StringList is considered optional
        optional = param->HasValue() || type == ParameterType_StringList  ? "True" : "False";
        }
      else
        {
        optional = "True";
        }
              #if 0
    	  std::cerr << name;
    	  std::cerr << " mandatory=" << param->GetMandatory();
    	  std::cerr << " HasValue=" << param->HasValue();
    	  std::cerr << " qgis_type=" << qgis_type;
    	  std::cerr << " optional=" << optional << std::endl;
              #endif
    	dFile << "|" << default_value << "|" << optional;
      }
    dFile << std::endl;
    }

  if(hasRasterOutput)
    {
    dFile << "*QgsProcessingParameterEnum|outputpixeltype|Output pixel type|uint8;int;float;double|False|2|True" << std::endl;
    }

  std::cerr << "Writing " << output_file << std::endl;
  dFile.close();

  std::ofstream indexFile;
  indexFile.open (algs_txt, std::ios::out | std::ios::app );
  indexFile << group << "|" << module << std::endl;
  indexFile.close();
  std::cerr << "Updated " << algs_txt << std::endl;

  appli = nullptr;
  ApplicationRegistry::CleanRegistry();

  return EXIT_SUCCESS;
  }

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

#include "otbWrapperChoiceParameter.h"
#include "otbWrapperListViewParameter.h"
#include "otbWrapperBoolParameter.h"
#include "otbWrapperApplicationRegistry.h"

#include <iostream>
#include <cassert>
#include <fstream>

int main(int argc, char* argv[])
{
  if (argc < 3)
    {
    std::cerr << "Usage : " << argv[0] << " name OTB_APPLICATION_PATH [out_dir]" << std::endl;
    return EXIT_FAILURE;
    }

  using namespace otb::Wrapper;

  const std::string module(argv[1]);

  /* TestApplication is removed in CMakeLists.txt */
#if 0
  if (module == "TestApplication")
    return EXIT_SUCCESS;
#endif

  ApplicationRegistry::AddApplicationPath(argv[2]);
  Application::Pointer appli =  ApplicationRegistry::CreateApplicationFaster(module);

  assert(!appli.IsNull());

  const std::string group = appli->GetDocTags().size() > 0 ? appli->GetDocTags()[0] : "";
  assert(!group.empty());

  std::map<ParameterType, std::string> parameterTypeToString;
  parameterTypeToString[ParameterType_Empty] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Bool] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Int] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Float] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_RAM] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Radius] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Choice] = "OTBParameterChoice";
  parameterTypeToString[ParameterType_String] = "QgsProcessingParameterString";
  parameterTypeToString[ParameterType_InputImage] = "QgsProcessingParameterRasterLayer";
  parameterTypeToString[ParameterType_InputFilename] = "QgsProcessingParameterFile";
  parameterTypeToString[ParameterType_InputImageList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorData] = "QgsProcessingParameterVectorLayer";
  parameterTypeToString[ParameterType_InputFilenameList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorDataList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_OutputImage] = "QgsProcessingParameterRasterDestination";
  parameterTypeToString[ParameterType_OutputVectorData] = "QgsProcessingParameterVectorDestination";
  parameterTypeToString[ParameterType_OutputFilename] = "QgsProcessingParameterFileDestination";
  parameterTypeToString[ParameterType_Directory] = "QgsProcessingParameterFile";
  parameterTypeToString[ParameterType_ComplexInputImage] = "QgsProcessingParameterRasterLayer";
  parameterTypeToString[ParameterType_ComplexOutputImage] = "QgsProcessingParameterRasterDestination";
  // TODO
  parameterTypeToString[ParameterType_StringList] = "QgsProcessingParameterString";
  // ListView parameters are treated as plain string (QLineEdit) in qgis processing ui.
  // This seems rather unpleasant when comparing Qgis processing with Monteverdi/Mapla in OTB
  // We tried to push something simple with checkboxes but its too risky for this version
  // and clock is ticking...

  parameterTypeToString[ParameterType_ListView] = "QgsProcessingParameterString";

  // For next update of plugin code ListView should use a custom widget wrapper and behave
  // exactly like OTB Mapla. And this #if 0 block is our TODO remainder.
  #if 0
  parameterTypeToString[ParameterType_ListView] = "OTBParameterListView";
  #endif

  const std::vector<std::string> appKeyList = appli->GetParametersKeys(true);
  const unsigned int nbOfParam = appKeyList.size();

  std::string output_file = module + ".txt";
  std::string  algs_txt = "algs.txt";
  if (argc > 3)
    {
    output_file = std::string(argv[3]) + module + ".txt";
    algs_txt = std::string(argv[3])  +  "algs.txt";
    }
  std::ofstream dFile;
  dFile.open (output_file, std::ios::out);

  std::string output_parameter_name;
  bool hasRasterOutput = false;
  {
  for (unsigned int i = 0; i < nbOfParam; i++)
    {
    Parameter::Pointer param = appli->GetParameterByKey(appKeyList[i]);
    if (param->GetMandatory())
      {
	if (appli->GetParameterType(appKeyList[i]) == ParameterType_OutputImage)
	  {
	    output_parameter_name = appKeyList[i];
	    hasRasterOutput = true;
	  }
      }
    }
  }

  if(output_parameter_name.empty())
    dFile << module << std::endl;
  else
    dFile << module << "|" <<  output_parameter_name << std::endl;

  dFile << appli->GetDescription() << std::endl;
  dFile << group << std::endl;

  for (unsigned int i = 0; i < nbOfParam; i++)
    {
    const std::string name = appKeyList[i];
    const Parameter::Pointer param = appli->GetParameterByKey(name);
    const ParameterType type = appli->GetParameterType(name);
    const std::string description = param->GetName();
    if (  type == ParameterType_Group  ||
          type == ParameterType_OutputProcessXML  ||
          type == ParameterType_InputProcessXML  ||
          type == ParameterType_RAM ||
          param->GetRole() == Role_Output )
      {
      // group parameter cannot have any value.
      // outxml and inxml parameters are not relevant for QGIS and is considered a bit noisy
      // ram is added by qgis-otb processing provider plugin as an advanced parameter for all apps
      // parameter role cannot be of type Role_Output
      continue;
      }
    auto it = parameterTypeToString.find(type);
    assert(  it != parameterTypeToString.end() );
    if( it == parameterTypeToString.end() )
      {
      std::cerr << "No mapping found for parameter '" <<name <<"' type=" << type << std::endl;
      return EXIT_FAILURE;
      }
    std::string qgis_type = it->second;
#if 0
      if (type == ParameterType_ListView)
	{
	  ListViewParameter *lv_param = dynamic_cast<ListViewParameter*>(param.GetPointer());
	  std::cerr << "lv_param->GetSingleSelection()" << lv_param->GetSingleSelection() << std::endl;
	  if (lv_param->GetSingleSelection())
	    {

	      qgis_type = "QgsProcessingParameterEnum";
	      std::vector<std::string>  key_list  = appli->GetChoiceKeys(name);
	      std::string values = "";
	      for( auto k : key_list)
		values += k + ";";
	      values.pop_back();
	      dFile << "|" << values ;
	    }
	}
#endif

    bool isDestination = false;
    bool isEpsgCode = false;

    // use QgsProcessingParameterCrs if required.
    // TODO: do a regex on name to match ==epsg || *\.epsg.\*
    if ( name == "epsg"
	      || name == "map.epsg.code"
	      || name == "mapproj.epsg.code"
	      || name == "mode.epsg.code")
        {
        qgis_type = "QgsProcessingParameterCrs";
        isEpsgCode = true;
        }

    dFile << qgis_type << "|" << name << "|" << description;

      std::string default_value = "None";
    if (type == ParameterType_Int)
      {
      if (isEpsgCode)
        {
          if (param->HasValue() && appli->GetParameterInt(name) < 1)
    	default_value =  "EPSG: " + appli->GetParameterAsString(name);
          else
    	default_value =  "ProjectCrs";
        }
      else
        {
        dFile << "|QgsProcessingParameterNumber.Integer";
        default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
        }
      }
    else if (type == ParameterType_Float)
      {
      dFile << "|QgsProcessingParameterNumber.Double";
      default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
      }
    else if (type == ParameterType_Radius)
      {
      dFile << "|QgsProcessingParameterNumber.Integer";
      default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
      }
    else if(type == ParameterType_InputFilename)
      {
      // TODO: if parameter InputFilename can give supported extensions
      // we can use it gitlab #1559
      dFile << "|QgsProcessingParameterFile.File|None";
      }
    else if(type == ParameterType_Directory)
      {
      dFile << "|QgsProcessingParameterFile.Folder|False";
      }
    else if (type == ParameterType_InputImageList)
      {
      dFile << "|3"; //QgsProcessing.TypeRaster
      }
    else if (type == ParameterType_InputVectorDataList)
      {
      dFile << "|-1"; //QgsProcessing.TypeVectorAnyGeometry
      }
    else if (type == ParameterType_InputVectorData)
      {
      dFile << "|-1"; //QgsProcessing.TypeVectorAnyGeometry
      }
    else if(type == ParameterType_InputFilenameList)
      {
      dFile << "|4"; //QgsProcessing.TypeFile"
      }
    else if(type == ParameterType_String)
      {
      // Below line is interpreted in qgis processing as
      // 1. default_value = None
      // 2. multiLine = False
      // For more details,
      // please refer to documetation of QgsProcessingParameterString.
      default_value = "None|False";
      }
    else if(type == ParameterType_StringList)
      {
      // Below line is interpreted in qgis processing as
      // 1. default_value = None
      // 2. multiLine = True
      // For more details,
      // please refer to documetation of QgsProcessingParameterString.
      // setting default_value this way is an exception for ParameterType_StringList and ParameterType_String
      default_value = "None|True";
      }
    else if (type == ParameterType_InputImage)
      {
      // default is None and nothing to add to dFile
      }
    else if(type == ParameterType_ListView)
      {
      // default is None and nothing to add to dFile
      }
    else if(type == ParameterType_Bool)
      {
      default_value = appli->GetParameterAsString(name);
      }
    else if(type == ParameterType_Choice)
      {
      std::vector<std::string>  key_list  = appli->GetChoiceKeys(name);
      std::string values = "";
      for( auto k : key_list)
        values += k + ";";

  	  values.pop_back();
  	  dFile << "|" << values ;
  	  ChoiceParameter *cparam = dynamic_cast<ChoiceParameter*>(param.GetPointer());
  	  default_value = std::to_string(cparam->GetValue());
      }
    else if(type == ParameterType_OutputVectorData ||
	          type == ParameterType_OutputImage ||
	          type == ParameterType_OutputFilename)
      {
      // No need for default_value, optional and extra fields in dFile.
      // If parameter is a destination type. qgis_type|name|description is enough.
      // So we simply set isDestination to true and skip to end to append a new line.
      isDestination =  true;
      }
    else
      {
      std::cout << "ERROR: default_value is empty for '" << name << "' type='" << qgis_type << "'" << std::endl;
      return EXIT_FAILURE;
      }

    if (!isDestination)
      {
      std::string optional;
      if (param->GetMandatory())
        {
        // TODO: avoid workaround for stringlist types (fix appengine)
        // type == ParameterType_StringList check is needed because:
        // If parameter is mandatory it can have no value
        // It is accepted in OTB that, string list could be generated dynamically
        // qgis has no such option to handle dynamic values yet..
        // So mandatory parameters whose type is StringList is considered optional
        optional = param->HasValue() || type == ParameterType_StringList  ? "True" : "False";
        }
      else
        {
        optional = "True";
        }
              #if 0
    	  std::cerr << name;
    	  std::cerr << " mandatory=" << param->GetMandatory();
    	  std::cerr << " HasValue=" << param->HasValue();
    	  std::cerr << " qgis_type=" << qgis_type;
    	  std::cerr << " optional=" << optional << std::endl;
              #endif
    	dFile << "|" << default_value << "|" << optional;
      }
    dFile << std::endl;
    }

  if(hasRasterOutput)
    {
    dFile << "*QgsProcessingParameterEnum|outputpixeltype|Output pixel type|uint8;int;float;double|False|2|True" << std::endl;
    }

  std::cerr << "Writing " << output_file << std::endl;
  dFile.close();

  std::ofstream indexFile;
  indexFile.open (algs_txt, std::ios::out | std::ios::app );
  indexFile << group << "|" << module << std::endl;
  indexFile.close();
  std::cerr << "Updated " << algs_txt << std::endl;

  appli = nullptr;
  ApplicationRegistry::CleanRegistry();

  return EXIT_SUCCESS;
  }

<|endoftext|>


<commit_before>#ifndef GAME_HPP
#define GAME_HPP

#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
#include <ctime>
#include <string>
#include <cstdlib>
#include <random>
#include <thread>
#include <cstdio>
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <stack>
#include <memory.h>
#include "bitboard.hpp"
#include "constants.hpp"
#include "killer.hpp"
#include "hash.hpp"
#include "timer.hpp"
#include "movearray.hpp"
#include "option.hpp"
#include "pv.hpp"

class Game {
private:
	BitBoard game_board;
	unsigned long long nodesCounter = 0;

	const int WHITE_WIN = 100000000;
	const int BLACK_WIN = -100000000;

	int64_t max_depth;
	bool stopped;

	int hash_decrement = 0;

	void initEngine();
	bool uciHandler(std::string str);
	void goFixedDepth();
	void goFixedTime(int time);
	void goTournament();
	void clearCash();
	double whiteUp = BLACK_WIN, blackUp = WHITE_WIN;

  std::vector<BitMove>pv;

	bool inZugzwang(BitBoard & b, uint8_t color);

	double whiteHistorySort[BOARD_SIZE][BOARD_SIZE][BOARD_SIZE][BOARD_SIZE];
	double blackHistorySort[BOARD_SIZE][BOARD_SIZE][BOARD_SIZE][BOARD_SIZE];

	bool hasBestMove = false;

	std::stack<BitMove>pv_line;
	int64_t stress;
	BitMove bestMove;
	int64_t bestScore;

	//фиксированное время
	Timer timer;
	int64_t time;
	double start_timer, end_timer;

	//турнирный режим

	double wtime, btime, winc, binc;
	uint64_t movestogo;
	bool movestogoEnable;
	uint64_t combinations;

	Option option;

public:
	Game();
	int64_t negamax(BitBoard & b, int64_t alpha, int64_t beta, int depth, int real_depth, int rule, bool inNullMove);
	int64_t negamax_elementary(BitBoard & b, int64_t alpha, int64_t beta, int depth, int real_depth, int rule, bool inNullMove);
	uint64_t perft(int depth);
	bool insufficientMaterial(std::vector<uint64_t>figureMask);
  	int64_t quies(BitBoard & b, int64_t alpha, int64_t beta, int rule, int real_depth);
	int startGame();
	void printScore(double score);
	std::string getScore(double score);
	std::vector<std::string> getStringArray(std::string str);
	bool move(std::string mv);
	void printBitBitBoard(uint64_t bit_BitBoard);
	void idPrint();

	std::vector<uint64_t>gameHash;
	std::vector<Hash>boardHash;

	std::vector<std::string>variant;
	std::vector<Killer>whiteKiller;
	std::vector<Killer>blackKiller;

	std::vector<MoveArray> moveArray;

	void sortAttacks(MoveArray& moves);
	void printVariant();

	//flags - begin
	bool nullMoveEnable = false;
	bool hashEnable = true;
	bool print_variant_enable = false;
	//flags - end

	double evalute_cells_size[BOARD_SIZE][BOARD_SIZE][BOARD_SIZE][BOARD_SIZE];
	void cleanWhiteHistory();
	void cleanBlackHistory();
	void flattenHistory();
	void printPV(int depth);

	double margin = PAWN_EV / 2;
	void sortMoves(MoveArray& result, int depth);
	bool recordHash(int depth, int score, int flag, uint64_t key, BitMove move, int real_depth);

	std::vector<BitMove> extractPV(int depth);

	bool testMovePossible(BitMove move);
};

#endif
<commit_msg>last upd.<commit_after>#ifndef GAME_HPP
#define GAME_HPP

#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
#include <ctime>
#include <string>
#include <cstdlib>
#include <random>
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <stack>
#include <memory>
#include "bitboard.hpp"
#include "constants.hpp"
#include "killer.hpp"
#include "hash.hpp"
#include "timer.hpp"
#include "movearray.hpp"
#include "option.hpp"
#include "pv.hpp"

class Game {
private:
	BitBoard game_board;
	unsigned long long nodesCounter = 0;

	const int WHITE_WIN = 100000000;
	const int BLACK_WIN = -100000000;

	int64_t max_depth;
	bool stopped;

	int hash_decrement = 0;

	void initEngine();
	bool uciHandler(std::string str);
	void goFixedDepth();
	void goFixedTime(int time);
	void goTournament();
	void clearCash();
	double whiteUp = BLACK_WIN, blackUp = WHITE_WIN;

  std::vector<BitMove>pv;

	bool inZugzwang(BitBoard & b, uint8_t color);

	double whiteHistorySort[BOARD_SIZE][BOARD_SIZE][BOARD_SIZE][BOARD_SIZE];
	double blackHistorySort[BOARD_SIZE][BOARD_SIZE][BOARD_SIZE][BOARD_SIZE];

	bool hasBestMove = false;

	std::stack<BitMove>pv_line;
	int64_t stress;
	BitMove bestMove;
	int64_t bestScore;

	//фиксированное время
	Timer timer;
	int64_t time;
	double start_timer, end_timer;

	//турнирный режим

	double wtime, btime, winc, binc;
	uint64_t movestogo;
	bool movestogoEnable;
	uint64_t combinations;

	Option option;

public:
	Game();
	int64_t negamax(BitBoard & b, int64_t alpha, int64_t beta, int depth, int real_depth, int rule, bool inNullMove);
	int64_t negamax_elementary(BitBoard & b, int64_t alpha, int64_t beta, int depth, int real_depth, int rule, bool inNullMove);
	uint64_t perft(int depth);
	bool insufficientMaterial(std::vector<uint64_t>figureMask);
  	int64_t quies(BitBoard & b, int64_t alpha, int64_t beta, int rule, int real_depth);
	int startGame();
	void printScore(double score);
	std::string getScore(double score);
	std::vector<std::string> getStringArray(std::string str);
	bool move(std::string mv);
	void printBitBitBoard(uint64_t bit_BitBoard);
	void idPrint();

	std::vector<uint64_t>gameHash;
	std::vector<Hash>boardHash;

	std::vector<std::string>variant;
	std::vector<Killer>whiteKiller;
	std::vector<Killer>blackKiller;

	std::vector<MoveArray> moveArray;

	void sortAttacks(MoveArray& moves);
	void printVariant();

	//flags - begin
	bool nullMoveEnable = false;
	bool hashEnable = true;
	bool print_variant_enable = false;
	//flags - end

	double evalute_cells_size[BOARD_SIZE][BOARD_SIZE][BOARD_SIZE][BOARD_SIZE];
	void cleanWhiteHistory();
	void cleanBlackHistory();
	void flattenHistory();
	void printPV(int depth);

	double margin = PAWN_EV / 2;
	void sortMoves(MoveArray& result, int depth);
	bool recordHash(int depth, int score, int flag, uint64_t key, BitMove move, int real_depth);

	std::vector<BitMove> extractPV(int depth);

	bool testMovePossible(BitMove move);
};

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <stdexcept>

#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

#include <QApplication>
#include <QMainWindow>
#include <QMenu>
#include <QAction>
#include <QKeyEvent>
#include <QHBoxLayout>

#include <dependency_graph/graph.h>
#include <dependency_graph/node_base.inl>
#include <dependency_graph/datablock.inl>
#include <dependency_graph/metadata.inl>
#include <dependency_graph/attr.inl>

#include <qt_node_editor/node.h>
#include <qt_node_editor/connected_edge.h>
#include <qt_node_editor/graph_widget.h>

#include <possumwood_sdk/app.h>
#include <possumwood_sdk/gl.h>

#include "adaptor.h"
#include "main_window.h"
#include "gl_init.h"
#include "common.h"

namespace po = boost::program_options;

using std::cout;
using std::endl;
using std::flush;

int main(int argc, char* argv[]) {
	// // Declare the supported options.
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("scene", po::value<std::string>(), "open a scene file")
	;

	// process the options
	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

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

	///////////////////////////////

	// create the possumwood application
	possumwood::App papp;

	{
		// load all plugins into an RAII container
		PluginsRAII plugins;

		GL_CHECK_ERR;

		{
			QSurfaceFormat format = QSurfaceFormat::defaultFormat();
			// way higher than currently supported - will fall back to highest
			format.setVersion(6, 0);
			format.setProfile(QSurfaceFormat::CoreProfile);

			#ifndef NDEBUG
			format.setOption(QSurfaceFormat::DebugContext);
			#endif

			format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);

			QSurfaceFormat::setDefaultFormat(format);
		}

		// create the application object
		QApplication app(argc, argv);

		// nice scaling on High DPI displays is support in Qt 5.6+
		#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
			QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
			QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
		#endif

		GL_CHECK_ERR;

		// make a main window
		MainWindow win;
		win.setWindowIcon(QIcon(":icons/app.png"));
		win.showMaximized();

		GL_CHECK_ERR;

		std::cout << "OpenGL version supported by this platform is "
		          << glGetString(GL_VERSION) << std::endl;

		GL_CHECK_ERR;

		// open the scene file, if specified on the command line
		if(vm.count("scene"))
			possumwood::App::instance().loadFile(boost::filesystem::path(vm["scene"].as<std::string>()));

		GL_CHECK_ERR;

		// and start the main application loop
		app.exec();

		GL_CHECK_ERR;
	}

	return 0;
}
<commit_msg>Fixed initialisation/destruction order issues between the plugins RAII object and main application<commit_after>#include <iostream>
#include <string>
#include <stdexcept>

#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

#include <QApplication>
#include <QMainWindow>
#include <QMenu>
#include <QAction>
#include <QKeyEvent>
#include <QHBoxLayout>

#include <dependency_graph/graph.h>
#include <dependency_graph/node_base.inl>
#include <dependency_graph/datablock.inl>
#include <dependency_graph/metadata.inl>
#include <dependency_graph/attr.inl>

#include <qt_node_editor/node.h>
#include <qt_node_editor/connected_edge.h>
#include <qt_node_editor/graph_widget.h>

#include <possumwood_sdk/app.h>
#include <possumwood_sdk/gl.h>

#include "adaptor.h"
#include "main_window.h"
#include "gl_init.h"
#include "common.h"

namespace po = boost::program_options;

using std::cout;
using std::endl;
using std::flush;

int main(int argc, char* argv[]) {
	// // Declare the supported options.
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("scene", po::value<std::string>(), "open a scene file")
	;

	// process the options
	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

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

	///////////////////////////////

	// create the possumwood application
	std::unique_ptr<possumwood::App> papp(new possumwood::App());
	// load all plugins into an RAII container - loading of plugins requires path expansion from the main app instance
	std::unique_ptr<PluginsRAII> plugins(new PluginsRAII());

	{
		GL_CHECK_ERR;

		{
			QSurfaceFormat format = QSurfaceFormat::defaultFormat();
			// way higher than currently supported - will fall back to highest
			format.setVersion(6, 0);
			format.setProfile(QSurfaceFormat::CoreProfile);

			#ifndef NDEBUG
			format.setOption(QSurfaceFormat::DebugContext);
			#endif

			format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);

			QSurfaceFormat::setDefaultFormat(format);
		}

		// create the application object
		QApplication app(argc, argv);

		// nice scaling on High DPI displays is support in Qt 5.6+
		#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
			QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
			QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
		#endif

		GL_CHECK_ERR;

		// make a main window
		MainWindow win;
		win.setWindowIcon(QIcon(":icons/app.png"));
		win.showMaximized();

		GL_CHECK_ERR;

		std::cout << "OpenGL version supported by this platform is "
		          << glGetString(GL_VERSION) << std::endl;

		GL_CHECK_ERR;

		// open the scene file, if specified on the command line
		if(vm.count("scene"))
			possumwood::App::instance().loadFile(boost::filesystem::path(vm["scene"].as<std::string>()));

		GL_CHECK_ERR;

		// and start the main application loop
		app.exec();

		GL_CHECK_ERR;
	}

	// delete the application before unloading plugins - app will need metadata from plugins to close cleanly
	papp.reset();
	plugins.reset();

	return 0;
}
<|endoftext|>


<commit_before>// Copyright 2017 Adam Smith
//
// 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 <cctype>
#include "as/serial_value/json.hpp"

void write_value(std::ostream& aStream, const as::serial_value& aValue) {
	switch (aValue.get_type()) {
	case as::serial_value::NULL_T:
		aStream << "null";
		break;
	case as::serial_value::CHAR_T:
		aStream << '"' << aValue.get_char() << "'";
		break;
	case as::serial_value::BOOL_T:
		aStream << aValue.get_bool() ? "true" : "false";
		break;
	case as::serial_value::UNSIGNED_T:
		aStream << aValue.get_unsigned();
		break;
	case as::serial_value::SIGNED_T:
		aStream << aValue.get_signed();
		break;
	case as::serial_value::FLOAT_T:
		aStream << aValue.get_float();
		break;
	case as::serial_value::POINTER_T:
		//! \todo Implement
		aStream << "null";
		break;
	case as::serial_value::STRING_T:
		aStream << '"' << aValue.get_string() << '"';
		break;
	case as::serial_value::ARRAY_T:
		{
			aStream << '[';
			const as::serial_value::array_t& tmp = aValue.get_array();
			const size_t s = tmp.size();
			for(size_t i = 0; i < s; ++i) {
				write_value(aStream, tmp[i]);
				if(i + 1 != s) aStream << ',';
			}
			aStream << ']';
		}
		break;
	case as::serial_value::OBJECT_T:
		{
			aStream << '{';
			const as::serial_value::object_t& tmp = aValue.get_object();
			const auto end = tmp.end();
			for(auto i = tmp.begin(); i != end; ++i) {
				aStream << '"' << i->first << '"' << ':';
				write_value(aStream, i->second);
				auto j = i;
				++j;
				if(j != end) aStream << ',';
			}
			aStream << '}';
		}
		break;
	}
}

void ignore_whitespace(std::istream& aStream) {
	char c = aStream.peek();
	while(std::isspace(c)) {
		aStream >> c;
		c = aStream.peek();
	}
}

as::serial_value read_unknown(std::istream&);

as::serial_value read_null(std::istream& aStream) {
	const auto pos = aStream.tellg();
	char tmp[4];
	aStream.read(tmp, 4);
	if(memcmp(tmp, "null", 4) != 0) {
		aStream.seekg(pos);
		throw std::runtime_error("as::deserialise_json : Expected 'null'");
	}
	return as::serial_value();
}

as::serial_value read_bool(std::istream& aStream) {
	const auto pos = aStream.tellg();
	char tmp[4];
	aStream.read(tmp, 4);
	const bool t = memcmp(tmp, "true", 4) == 0;
	const bool f = memcmp(tmp, "fals", 4) == 0;
	if(t) {
		return as::serial_value(true);
	}else if(f) {
		aStream >> tmp[0];
		if(tmp[0] == 'e') return as::serial_value(false);
	}
	aStream.seekg(pos);
	throw std::runtime_error("as::deserialise_json : Expected 'true' or 'false'");
}

as::serial_value read_number(std::istream& aStream) {
	auto pos = aStream.tellg();
	char c;
	aStream >> c;
	if(c != '"') {
		aStream.seekg(pos);
		throw std::runtime_error("as::deserialise_json : Expected string to begin with '\"'");
	}
	as::serial_value tmp;
	as::serial_value::string_t& str = tmp.set_string();
	aStream >> c;
	while(c != '"') {
		if(aStream.eof()) {
			aStream.seekg(pos);
			throw std::runtime_error("as::deserialise_json : Expected string to end with'\"'");
		}
		str += c;
		aStream >> c;
	}
	return tmp;
}

as::serial_value read_string(std::istream& aStream) {
	const auto pos = aStream.tellg();
	as::serial_value tmp;
	//! \todo Implement
	return tmp;
}

as::serial_value read_array(std::istream& aStream) {
	as::serial_value tmp;
	//! \todo Implement
	return tmp;
}

as::serial_value read_object(std::istream& aStream) {
	as::serial_value tmp;
	//! \todo Implement
	return tmp;
}

as::serial_value read_unknown(std::istream& aStream) {
	ignore_whitespace(aStream);

	switch(aStream.peek())
	{
	case 'n':
		return read_null(aStream);
	case 't':
	case 'f':
		return read_bool(aStream);
	case '-':
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		return read_number(aStream);
	case '"':
		return read_string(aStream);
	case '[':
		return read_array(aStream);
	case '{':
		return read_object(aStream);
	default:
		throw std::runtime_error("as::deserialise_json : Could not determine type of JSON value");
		break;
	}
}

namespace as {
	void serialise_json(std::ostream& aStream, const serial_value& aValue) {
		write_value(aStream, aValue);
	}

	serial_value deserialise_json(std::istream& aStream) {
		return read_unknown(aStream);
	}

}<commit_msg>Fixed code overwrite error<commit_after>// Copyright 2017 Adam Smith
//
// 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 <cctype>
#include "as/serial_value/json.hpp"

void write_value(std::ostream& aStream, const as::serial_value& aValue) {
	switch (aValue.get_type()) {
	case as::serial_value::NULL_T:
		aStream << "null";
		break;
	case as::serial_value::CHAR_T:
		aStream << '"' << aValue.get_char() << "'";
		break;
	case as::serial_value::BOOL_T:
		aStream << aValue.get_bool() ? "true" : "false";
		break;
	case as::serial_value::UNSIGNED_T:
		aStream << aValue.get_unsigned();
		break;
	case as::serial_value::SIGNED_T:
		aStream << aValue.get_signed();
		break;
	case as::serial_value::FLOAT_T:
		aStream << aValue.get_float();
		break;
	case as::serial_value::POINTER_T:
		//! \todo Implement
		aStream << "null";
		break;
	case as::serial_value::STRING_T:
		aStream << '"' << aValue.get_string() << '"';
		break;
	case as::serial_value::ARRAY_T:
		{
			aStream << '[';
			const as::serial_value::array_t& tmp = aValue.get_array();
			const size_t s = tmp.size();
			for(size_t i = 0; i < s; ++i) {
				write_value(aStream, tmp[i]);
				if(i + 1 != s) aStream << ',';
			}
			aStream << ']';
		}
		break;
	case as::serial_value::OBJECT_T:
		{
			aStream << '{';
			const as::serial_value::object_t& tmp = aValue.get_object();
			const auto end = tmp.end();
			for(auto i = tmp.begin(); i != end; ++i) {
				aStream << '"' << i->first << '"' << ':';
				write_value(aStream, i->second);
				auto j = i;
				++j;
				if(j != end) aStream << ',';
			}
			aStream << '}';
		}
		break;
	}
}

void ignore_whitespace(std::istream& aStream) {
	char c = aStream.peek();
	while(std::isspace(c)) {
		aStream >> c;
		c = aStream.peek();
	}
}

as::serial_value read_unknown(std::istream&);

as::serial_value read_null(std::istream& aStream) {
	const auto pos = aStream.tellg();
	char tmp[4];
	aStream.read(tmp, 4);
	if(memcmp(tmp, "null", 4) != 0) {
		aStream.seekg(pos);
		throw std::runtime_error("as::deserialise_json : Expected 'null'");
	}
	return as::serial_value();
}

as::serial_value read_bool(std::istream& aStream) {
	const auto pos = aStream.tellg();
	char tmp[4];
	aStream.read(tmp, 4);
	const bool t = memcmp(tmp, "true", 4) == 0;
	const bool f = memcmp(tmp, "fals", 4) == 0;
	if(t) {
		return as::serial_value(true);
	}else if(f) {
		aStream >> tmp[0];
		if(tmp[0] == 'e') return as::serial_value(false);
	}
	aStream.seekg(pos);
	throw std::runtime_error("as::deserialise_json : Expected 'true' or 'false'");
}

as::serial_value read_number(std::istream& aStream) {
	as::serial_value::float_t tmp;
	aStream >> tmp;
	return as::serial_value(tmp);
}

as::serial_value read_string(std::istream& aStream) {
	auto pos = aStream.tellg();
	char c;
	aStream >> c;
	if(c != '"') {
		aStream.seekg(pos);
		throw std::runtime_error("as::deserialise_json : Expected string to begin with '\"'");
	}
	as::serial_value tmp;
	as::serial_value::string_t& str = tmp.set_string();
	aStream >> c;
	while(c != '"') {
		if(aStream.eof()) {
			aStream.seekg(pos);
			throw std::runtime_error("as::deserialise_json : Expected string to end with'\"'");
		}
		str += c;
		aStream >> c;
	}
	return tmp;
}

as::serial_value read_array(std::istream& aStream) {
	as::serial_value tmp;
	//! \todo Implement
	return tmp;
}

as::serial_value read_object(std::istream& aStream) {
	as::serial_value tmp;
	//! \todo Implement
	return tmp;
}

as::serial_value read_unknown(std::istream& aStream) {
	ignore_whitespace(aStream);

	switch(aStream.peek())
	{
	case 'n':
		return read_null(aStream);
	case 't':
	case 'f':
		return read_bool(aStream);
	case '-':
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		return read_number(aStream);
	case '"':
		return read_string(aStream);
	case '[':
		return read_array(aStream);
	case '{':
		return read_object(aStream);
	default:
		throw std::runtime_error("as::deserialise_json : Could not determine type of JSON value");
		break;
	}
}

namespace as {
	void serialise_json(std::ostream& aStream, const serial_value& aValue) {
		write_value(aStream, aValue);
	}

	serial_value deserialise_json(std::istream& aStream) {
		return read_unknown(aStream);
	}

}<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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 "SurgSim/Collision/OctreeDcdContact.h"

#include <boost/functional/hash.hpp>

#include "SurgSim/Collision/CollisionPair.h"
#include "SurgSim/Collision/Representation.h"
#include "SurgSim/Collision/ShapeCollisionRepresentation.h"
#include "SurgSim/Math/BoxShape.h"
#include "SurgSim/Math/Shape.h"
#include "SurgSim/Math/Vector.h"

namespace SurgSim
{
namespace Collision
{

size_t OctreeDcdContact::Vector3dHash::operator()(const SurgSim::Math::Vector3d& id) const
{
	return boost::hash_range(id.data(), id.data() + 3);
}

OctreeDcdContact::OctreeDcdContact(std::shared_ptr<ContactCalculation> calculator) :
	m_calculator(calculator)
{
	SURGSIM_ASSERT(m_calculator->getShapeTypes().first == SurgSim::Math::SHAPE_TYPE_BOX) <<
			"OctreeDcdContact needs a contact calculator that works with Boxes";
	m_shapeTypes = m_calculator->getShapeTypes();
	m_shapeTypes.first = SurgSim::Math::SHAPE_TYPE_OCTREE;

	m_nodeCollisionRepresentation = std::make_shared<ShapeCollisionRepresentation>("Octree Node");
}

std::pair<int, int> OctreeDcdContact::getShapeTypes()
{
	return m_shapeTypes;
}

void OctreeDcdContact::doCalculateContact(std::shared_ptr<CollisionPair> pair)
{
	typedef SurgSim::Math::OctreeShape OctreeShapeType;
	std::shared_ptr<OctreeShapeType> shape = std::static_pointer_cast<OctreeShapeType>(pair->getFirst()->getShape());
	calculateContactWithNode(shape->getOctree(), pair, std::make_shared<SurgSim::DataStructures::OctreePath>());
}

void OctreeDcdContact::calculateContactWithNode(
	std::shared_ptr<const SurgSim::Math::OctreeShape::NodeType> node,
	std::shared_ptr<CollisionPair> pair,
	std::shared_ptr<SurgSim::DataStructures::OctreePath> nodePath)
{
	if (! node->isActive())
	{
		return;
	}

	SurgSim::Math::Vector3d nodeSize = node->getBoundingBox().sizes();
	std::shared_ptr<SurgSim::Math::Shape> nodeShape;
	if (m_shapes.count(nodeSize) > 0)
	{
		nodeShape = m_shapes[nodeSize];
	}
	else
	{
		nodeShape = std::make_shared<SurgSim::Math::BoxShape>(nodeSize.x(), nodeSize.y(), nodeSize.z());
		m_shapes[nodeSize] = nodeShape;
	}
	SurgSim::Math::Vector3d nodeCenter = node->getBoundingBox().center();
	SurgSim::Math::RigidTransform3d nodePose = pair->getFirst()->getPose();
	nodePose.translation() += nodePose.linear() * nodeCenter;

	m_nodeCollisionRepresentation->setShape(nodeShape);
	m_nodeCollisionRepresentation->setLocalPose(nodePose);

	std::shared_ptr<CollisionPair> localPair = std::make_shared<CollisionPair>(m_nodeCollisionRepresentation,
			pair->getSecond());
	m_calculator->calculateContact(localPair);

	if (localPair->hasContacts())
	{
		pair->getSecond()->getCollisions().unsafeGet().erase(m_nodeCollisionRepresentation);
		if (node->hasChildren())
		{
			for (size_t i = 0; i < node->getChildren().size(); i++)
			{
				nodePath->push_back(i);
				calculateContactWithNode(node->getChild(i), pair, nodePath);
				nodePath->pop_back();
			}
		}
		else
		{
			const std::list<std::shared_ptr<Contact>>& newContacts = localPair->getContacts();
			SurgSim::Math::Vector3d contactPosition;
			for (auto contact = newContacts.cbegin(); contact != newContacts.cend(); ++contact)
			{
				(*contact)->penetrationPoints.first.octreeNodePath.setValue(*nodePath);

				contactPosition = (*contact)->penetrationPoints.first.rigidLocalPosition.getValue();
				contactPosition += nodeCenter;
				(*contact)->penetrationPoints.first.rigidLocalPosition.setValue(contactPosition);

				pair->addContact(*contact);
			}
		}
	}
}

};
};

<commit_msg>OctreeDcdContact only clears temporary contacts once.<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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 "SurgSim/Collision/OctreeDcdContact.h"

#include <boost/functional/hash.hpp>

#include "SurgSim/Collision/CollisionPair.h"
#include "SurgSim/Collision/Representation.h"
#include "SurgSim/Collision/ShapeCollisionRepresentation.h"
#include "SurgSim/Math/BoxShape.h"
#include "SurgSim/Math/Shape.h"
#include "SurgSim/Math/Vector.h"

namespace SurgSim
{
namespace Collision
{

size_t OctreeDcdContact::Vector3dHash::operator()(const SurgSim::Math::Vector3d& id) const
{
	return boost::hash_range(id.data(), id.data() + 3);
}

OctreeDcdContact::OctreeDcdContact(std::shared_ptr<ContactCalculation> calculator) :
	m_calculator(calculator)
{
	SURGSIM_ASSERT(m_calculator->getShapeTypes().first == SurgSim::Math::SHAPE_TYPE_BOX) <<
			"OctreeDcdContact needs a contact calculator that works with Boxes";
	m_shapeTypes = m_calculator->getShapeTypes();
	m_shapeTypes.first = SurgSim::Math::SHAPE_TYPE_OCTREE;

	m_nodeCollisionRepresentation = std::make_shared<ShapeCollisionRepresentation>("Octree Node");
}

std::pair<int, int> OctreeDcdContact::getShapeTypes()
{
	return m_shapeTypes;
}

void OctreeDcdContact::doCalculateContact(std::shared_ptr<CollisionPair> pair)
{
	typedef SurgSim::Math::OctreeShape OctreeShapeType;
	std::shared_ptr<OctreeShapeType> shape = std::static_pointer_cast<OctreeShapeType>(pair->getFirst()->getShape());
	calculateContactWithNode(shape->getOctree(), pair, std::make_shared<SurgSim::DataStructures::OctreePath>());
	pair->getSecond()->getCollisions().unsafeGet().erase(m_nodeCollisionRepresentation);
}

void OctreeDcdContact::calculateContactWithNode(
	std::shared_ptr<const SurgSim::Math::OctreeShape::NodeType> node,
	std::shared_ptr<CollisionPair> pair,
	std::shared_ptr<SurgSim::DataStructures::OctreePath> nodePath)
{
	if (! node->isActive())
	{
		return;
	}

	SurgSim::Math::Vector3d nodeSize = node->getBoundingBox().sizes();
	std::shared_ptr<SurgSim::Math::Shape> nodeShape;
	if (m_shapes.count(nodeSize) > 0)
	{
		nodeShape = m_shapes[nodeSize];
	}
	else
	{
		nodeShape = std::make_shared<SurgSim::Math::BoxShape>(nodeSize.x(), nodeSize.y(), nodeSize.z());
		m_shapes[nodeSize] = nodeShape;
	}
	SurgSim::Math::Vector3d nodeCenter = node->getBoundingBox().center();
	SurgSim::Math::RigidTransform3d nodePose = pair->getFirst()->getPose();
	nodePose.translation() += nodePose.linear() * nodeCenter;

	m_nodeCollisionRepresentation->setShape(nodeShape);
	m_nodeCollisionRepresentation->setLocalPose(nodePose);

	std::shared_ptr<CollisionPair> localPair = std::make_shared<CollisionPair>(m_nodeCollisionRepresentation,
			pair->getSecond());
	m_calculator->calculateContact(localPair);

	if (localPair->hasContacts())
	{
		if (node->hasChildren())
		{
			for (size_t i = 0; i < node->getChildren().size(); i++)
			{
				nodePath->push_back(i);
				calculateContactWithNode(node->getChild(i), pair, nodePath);
				nodePath->pop_back();
			}
		}
		else
		{
			const std::list<std::shared_ptr<Contact>>& newContacts = localPair->getContacts();
			SurgSim::Math::Vector3d contactPosition;
			for (auto contact = newContacts.cbegin(); contact != newContacts.cend(); ++contact)
			{
				(*contact)->penetrationPoints.first.octreeNodePath.setValue(*nodePath);

				contactPosition = (*contact)->penetrationPoints.first.rigidLocalPosition.getValue();
				contactPosition += nodeCenter;
				(*contact)->penetrationPoints.first.rigidLocalPosition.setValue(contactPosition);

				pair->addContact(*contact);
			}
		}
	}
}

};
};

<|endoftext|>