<commit_before>/*-
 * Copyright (c) 2016 Frederic Culot <culot@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <curses.h>

#include "pane.h"

namespace portal {
namespace gfx {

class Pane::Impl {
 public:
  // Need to use both an curses win structure (to be able to draw the border),
  // and a curses pad structure (to display the window contents.
  // If only using a pad, and applying the border directly to it, the bottom
  // line of the border gets overwritten with the pad content.
  WINDOW* win {nullptr};
  WINDOW* pad {nullptr};

  /*
     +------------------------------------------+-  -  -  - v posView.y
     |                                          |           |
     |      +-  +-----------------+ -  -  -  -  |-v -  -  - |- v-  -  -v p
     |      |   |abc              |             | |posPad.y |  | p     | o
     |  s . |   +-----------------+ --+ -  -  - |-^ - - - - ^  | oC    | s
     |  i h |   |def              |   |sizeView |              | su    | P
     |  z e |   |ghi              |   |.height  |              |  r    | r
     |  e i |   |jkl              |   |         |              |  s    | i
     |  P g |   |mno##############| - | -  -  - |-  - - - - - -^  o    | n
     |  a h |   +-----------------+  -+         |                 r    | t
     |  d t |   |pqr              |             |                 .    | .
     |      |   |stu              |             |                 y    | y
     |      |   |                 | -  -  -  -  |-  -  -  -  -  -  -  -^
     |      +-  +-----------------+             |
     |                                          |
     |                                   screen |
     +------------------------------------------+
  */
  Size sizePad;
  Size sizeView;

  Point posPad;
  Point posView;
  Point posCursor;
  Point posPrint;

  bool cursorLineHighlight {true};
  bool cursorLineUnderline {false};
  bool borders             {true};

  void createPane();
  void extendPrintArea();
  void clearPrintArea();
  void drawBorders();
  void drawScrollBar();
  void applyCursorLineStyle() const;
  void resetCursorLineStyle() const;
  void toggleBorders();
  bool isCursorOnFirstLine() const;
  bool isCursorOnLastLine() const;
  bool isCursorOnFirstVisibleLine() const;
  bool isCursorOnLastVisibleLine() const;
  bool canScrollUp() const;
  bool canScrollDown() const;
};

Pane::Pane(const Size& size, const Point& pos) : impl_{new Impl} {
  impl_->sizeView = size;
  impl_->sizePad.setWidth(size.width());
  impl_->sizePad.setHeight(size.height());
  impl_->posView = pos;
  impl_->createPane();
}

Pane::~Pane() {
  delwin(impl_->pad);
  delwin(impl_->win);
}

Size Pane::size() const {
  return impl_->sizeView;
}

void Pane::cursorLineHighlight(bool highlight) {
  impl_->cursorLineHighlight = highlight;
}

void Pane::cursorLineUnderline(bool underline) {
  impl_->cursorLineUnderline = underline;
}

void Pane::borders(bool borders) {
  if (impl_->borders != borders) {
    werase(impl_->win);
    impl_->toggleBorders();
    draw();
  }
}

int Pane::getCursorRowNum() const {
  return impl_->posCursor.y();
}

void Pane::draw() const {
  impl_->applyCursorLineStyle();
  impl_->drawScrollBar();
  pnoutrefresh(impl_->pad,
               impl_->posPad.y(),
               impl_->posPad.x(),
               impl_->posView.y() + (impl_->borders ? 1 : 0),
               impl_->posView.x() + 1,
               impl_->posView.y() + impl_->sizeView.height() - (impl_->borders ? 2 : 0),
               impl_->posView.x() + impl_->sizeView.width() - 2);
  wnoutrefresh(impl_->win);
}

void Pane::clear() {
  impl_->clearPrintArea();
}

void Pane::newline() {
  impl_->extendPrintArea();
  impl_->posPrint.setY(impl_->posPrint.y() + 1);
}

void Pane::print(const std::string& line, Align align) {
  int xpos;
  switch (align) {
  case Align::left:
    xpos = impl_->posPad.x();
    break;
  case Align::center:
    xpos = (impl_->sizeView.width() - line.length()) / 2;
    break;
  case Align::right:
    xpos = impl_->sizeView.width() - line.length() - 2 - (impl_->borders ? 1 : 0);
    break;
  }

  mvwaddstr(impl_->pad, impl_->posPrint.y(), xpos, line.c_str());
}

void Pane::print(int c, int cursesColorNum) {
  waddch(impl_->pad, c | COLOR_PAIR(cursesColorNum));
}

void Pane::printStatus(const std::string& status, int cursesColorNum) const {
  int statusLength = status.length();
  int xpos = impl_->sizeView.width() - statusLength - 8;
  int ypos = impl_->sizeView.height() - 1;
  mvwaddch(impl_->win, ypos, xpos++, ACS_RTEE);
  mvwaddch(impl_->win, ypos, xpos++, ' ');
  wattron(impl_->win, COLOR_PAIR(cursesColorNum));
  mvwaddstr(impl_->win, ypos, xpos, status.c_str());
  wattroff(impl_->win, COLOR_PAIR(cursesColorNum));
  xpos += statusLength;
  mvwaddch(impl_->win, ypos, xpos++, ' ');
  mvwaddch(impl_->win, ypos, xpos, ACS_LTEE);
}

void Pane::clearStatus() const {
  impl_->drawBorders();
}

void Pane::scrollDown() {
  if (impl_->canScrollDown()) {
    impl_->posPad.setY(impl_->posPad.y() + 1);
  }
}

void Pane::scrollUp() {
  if (impl_->canScrollUp()) {
    impl_->posPad.setY(impl_->posPad.y() - 1);
  }
}

void Pane::moveCursor(const Point& pos) {
  impl_->posCursor = pos;
}

void Pane::moveCursorDown() {
  if (!impl_->isCursorOnLastLine()) {
    impl_->resetCursorLineStyle();
    impl_->posCursor.setY(impl_->posCursor.y() + 1);
    if (impl_->isCursorOnLastVisibleLine()) {
      scrollDown();
    }
  }
}

void Pane::moveCursorUp() {
  if (!impl_->isCursorOnFirstLine()) {
    impl_->resetCursorLineStyle();
    impl_->posCursor.setY(impl_->posCursor.y() - 1);
    if (impl_->isCursorOnFirstVisibleLine()) {
      scrollUp();
    }
  }
}

void Pane::resetCursorPosition() {
  impl_->posCursor.setX(0);
  impl_->posCursor.setY(0);
  impl_->posPad.setY(0);
}

void Pane::colorizeCurrentLine(short cursesColorNum) const {
  mvwchgat(impl_->pad,
           impl_->posCursor.y(),
           0,
           impl_->sizePad.width(),
           A_NORMAL,
           cursesColorNum,
           nullptr);
}

void Pane::Impl::createPane() {
  win = newwin(sizeView.height(), sizeView.width(), posView.y(), posView.x());
  pad = newpad(sizePad.height(), sizePad.width());
  drawBorders();
  wnoutrefresh(win);
}

void Pane::Impl::extendPrintArea() {
  if (posPrint.y() == sizePad.height() - 1) {
    sizePad.setHeight(sizePad.height() * 2);
    wresize(pad, sizePad.height(), sizePad.width());
  }
}

void Pane::Impl::clearPrintArea() {
  werase(pad);
  posPrint.setY(0);
}

void Pane::Impl::drawBorders() {
  if (borders) {
    box(win, 0, 0);
    wnoutrefresh(win);
  }
}

void Pane::Impl::drawScrollBar() {
  if (canScrollUp()) {
    mvwaddch(win,
             (borders ? 1 : 0),
             sizeView.width() - 1 - (borders ? 1 : 0),
             ACS_UARROW | A_BOLD);
  }
  if (canScrollDown()) {
    mvwaddch(win,
             sizeView.height() - 1 - (borders ? 1 : 0),
             sizeView.width() - 1 - (borders ? 1 : 0),
             ACS_DARROW | A_BOLD);
  }
}

void Pane::Impl::applyCursorLineStyle() const {
  if (cursorLineHighlight) {
    mvwchgat(pad, posCursor.y(), 0, sizePad.width(), A_REVERSE, 0, nullptr);
  }
  if (cursorLineUnderline) {
    mvwchgat(pad, posCursor.y(), 0, sizePad.width(), A_UNDERLINE, 0, nullptr);
  }
}

void Pane::Impl::resetCursorLineStyle() const {
  mvwchgat(pad, posCursor.y(), 0, sizePad.width(), A_NORMAL, 0, nullptr);
}

void Pane::Impl::toggleBorders() {
  borders = !borders;
}

bool Pane::Impl::isCursorOnFirstLine() const {
  return posCursor.y() == 0;
}

bool Pane::Impl::isCursorOnLastLine() const {
return posCursor.y() == posPrint.y() - (borders ? 1 : 0);
}

bool Pane::Impl::isCursorOnFirstVisibleLine() const {
  return posCursor.y() == posPad.y() - (borders ? 1 : 0);
}

bool Pane::Impl::isCursorOnLastVisibleLine() const {
  return posCursor.y() == sizeView.height() + posPad.y() - (borders ? 2 : 0);
}

bool Pane::Impl::canScrollUp() const {
  return posPad.y() > 0;
}

bool Pane::Impl::canScrollDown() const {
return posPrint.y() - posPad.y() > sizeView.height() - (borders ? 2 : 0);
}

}
}
<commit_msg>Display was not updated often enough<commit_after>/*-
 * Copyright (c) 2016 Frederic Culot <culot@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <curses.h>

#include "pane.h"

namespace portal {
namespace gfx {

class Pane::Impl {
 public:
  // Need to use both an curses win structure (to be able to draw the border),
  // and a curses pad structure (to display the window contents.
  // If only using a pad, and applying the border directly to it, the bottom
  // line of the border gets overwritten with the pad content.
  WINDOW* win {nullptr};
  WINDOW* pad {nullptr};

  /*
     +------------------------------------------+-  -  -  - v posView.y
     |                                          |           |
     |      +-  +-----------------+ -  -  -  -  |-v -  -  - |- v-  -  -v p
     |      |   |abc              |             | |posPad.y |  | p     | o
     |  s . |   +-----------------+ --+ -  -  - |-^ - - - - ^  | oC    | s
     |  i h |   |def              |   |sizeView |              | su    | P
     |  z e |   |ghi              |   |.height  |              |  r    | r
     |  e i |   |jkl              |   |         |              |  s    | i
     |  P g |   |mno##############| - | -  -  - |-  - - - - - -^  o    | n
     |  a h |   +-----------------+  -+         |                 r    | t
     |  d t |   |pqr              |             |                 .    | .
     |      |   |stu              |             |                 y    | y
     |      |   |                 | -  -  -  -  |-  -  -  -  -  -  -  -^
     |      +-  +-----------------+             |
     |                                          |
     |                                   screen |
     +------------------------------------------+
  */
  Size sizePad;
  Size sizeView;

  Point posPad;
  Point posView;
  Point posCursor;
  Point posPrint;

  bool cursorLineHighlight {true};
  bool cursorLineUnderline {false};
  bool borders             {true};

  void createPane();
  void extendPrintArea();
  void clearPrintArea();
  void drawBorders();
  void drawScrollBar();
  void applyCursorLineStyle() const;
  void resetCursorLineStyle() const;
  void toggleBorders();
  bool isCursorOnFirstLine() const;
  bool isCursorOnLastLine() const;
  bool isCursorOnFirstVisibleLine() const;
  bool isCursorOnLastVisibleLine() const;
  bool canScrollUp() const;
  bool canScrollDown() const;
};

Pane::Pane(const Size& size, const Point& pos) : impl_{new Impl} {
  impl_->sizeView = size;
  impl_->sizePad.setWidth(size.width());
  impl_->sizePad.setHeight(size.height());
  impl_->posView = pos;
  impl_->createPane();
}

Pane::~Pane() {
  delwin(impl_->pad);
  delwin(impl_->win);
}

Size Pane::size() const {
  return impl_->sizeView;
}

void Pane::cursorLineHighlight(bool highlight) {
  impl_->cursorLineHighlight = highlight;
}

void Pane::cursorLineUnderline(bool underline) {
  impl_->cursorLineUnderline = underline;
}

void Pane::borders(bool borders) {
  if (impl_->borders != borders) {
    werase(impl_->win);
    impl_->toggleBorders();
  }
}

int Pane::getCursorRowNum() const {
  return impl_->posCursor.y();
}

void Pane::draw() const {
  impl_->applyCursorLineStyle();
  impl_->drawScrollBar();
  pnoutrefresh(impl_->pad,
               impl_->posPad.y(),
               impl_->posPad.x(),
               impl_->posView.y() + (impl_->borders ? 1 : 0),
               impl_->posView.x() + 1,
               impl_->posView.y() + impl_->sizeView.height() - (impl_->borders ? 2 : 0),
               impl_->posView.x() + impl_->sizeView.width() - 2);
  wnoutrefresh(impl_->win);
  Gfx::instance().update();
}

void Pane::clear() {
  impl_->clearPrintArea();
}

void Pane::newline() {
  impl_->extendPrintArea();
  impl_->posPrint.setY(impl_->posPrint.y() + 1);
}

void Pane::print(const std::string& line, Align align) {
  int xpos;
  switch (align) {
  case Align::left:
    xpos = impl_->posPad.x();
    break;
  case Align::center:
    xpos = (impl_->sizeView.width() - line.length()) / 2;
    break;
  case Align::right:
    xpos = impl_->sizeView.width() - line.length() - 2 - (impl_->borders ? 1 : 0);
    break;
  }

  mvwaddstr(impl_->pad, impl_->posPrint.y(), xpos, line.c_str());
  draw();
}

void Pane::print(int c, int cursesColorNum) {
  waddch(impl_->pad, c | COLOR_PAIR(cursesColorNum));
  draw();
}

void Pane::printStatus(const std::string& status, int cursesColorNum) const {
  int statusLength = status.length();
  int xpos = impl_->sizeView.width() - statusLength - 8;
  int ypos = impl_->sizeView.height() - 1;
  mvwaddch(impl_->win, ypos, xpos++, ACS_RTEE);
  mvwaddch(impl_->win, ypos, xpos++, ' ');
  wattron(impl_->win, COLOR_PAIR(cursesColorNum));
  mvwaddstr(impl_->win, ypos, xpos, status.c_str());
  wattroff(impl_->win, COLOR_PAIR(cursesColorNum));
  xpos += statusLength;
  mvwaddch(impl_->win, ypos, xpos++, ' ');
  mvwaddch(impl_->win, ypos, xpos, ACS_LTEE);
  draw();
}

void Pane::clearStatus() const {
  impl_->drawBorders();
}

void Pane::scrollDown() {
  if (impl_->canScrollDown()) {
    impl_->posPad.setY(impl_->posPad.y() + 1);
  }
}

void Pane::scrollUp() {
  if (impl_->canScrollUp()) {
    impl_->posPad.setY(impl_->posPad.y() - 1);
  }
}

void Pane::moveCursor(const Point& pos) {
  impl_->posCursor = pos;
}

void Pane::moveCursorDown() {
  if (!impl_->isCursorOnLastLine()) {
    impl_->resetCursorLineStyle();
    impl_->posCursor.setY(impl_->posCursor.y() + 1);
    if (impl_->isCursorOnLastVisibleLine()) {
      scrollDown();
    }
  }
}

void Pane::moveCursorUp() {
  if (!impl_->isCursorOnFirstLine()) {
    impl_->resetCursorLineStyle();
    impl_->posCursor.setY(impl_->posCursor.y() - 1);
    if (impl_->isCursorOnFirstVisibleLine()) {
      scrollUp();
    }
  }
}

void Pane::resetCursorPosition() {
  impl_->posCursor.setX(0);
  impl_->posCursor.setY(0);
  impl_->posPad.setY(0);
}

void Pane::colorizeCurrentLine(short cursesColorNum) const {
  mvwchgat(impl_->pad,
           impl_->posCursor.y(),
           0,
           impl_->sizePad.width(),
           A_NORMAL,
           cursesColorNum,
           nullptr);
}

void Pane::Impl::createPane() {
  win = newwin(sizeView.height(), sizeView.width(), posView.y(), posView.x());
  pad = newpad(sizePad.height(), sizePad.width());
  drawBorders();
  wnoutrefresh(win);
}

void Pane::Impl::extendPrintArea() {
  if (posPrint.y() == sizePad.height() - 1) {
    sizePad.setHeight(sizePad.height() * 2);
    wresize(pad, sizePad.height(), sizePad.width());
  }
}

void Pane::Impl::clearPrintArea() {
  werase(pad);
  posPrint.setY(0);
}

void Pane::Impl::drawBorders() {
  if (borders) {
    box(win, 0, 0);
    wnoutrefresh(win);
  }
}

void Pane::Impl::drawScrollBar() {
  if (canScrollUp()) {
    mvwaddch(win,
             (borders ? 1 : 0),
             sizeView.width() - 1 - (borders ? 1 : 0),
             ACS_UARROW | A_BOLD);
  }
  if (canScrollDown()) {
    mvwaddch(win,
             sizeView.height() - 1 - (borders ? 1 : 0),
             sizeView.width() - 1 - (borders ? 1 : 0),
             ACS_DARROW | A_BOLD);
  }
}

void Pane::Impl::applyCursorLineStyle() const {
  if (cursorLineHighlight) {
    mvwchgat(pad, posCursor.y(), 0, sizePad.width(), A_REVERSE, 0, nullptr);
  }
  if (cursorLineUnderline) {
    mvwchgat(pad, posCursor.y(), 0, sizePad.width(), A_UNDERLINE, 0, nullptr);
  }
}

void Pane::Impl::resetCursorLineStyle() const {
  mvwchgat(pad, posCursor.y(), 0, sizePad.width(), A_NORMAL, 0, nullptr);
}

void Pane::Impl::toggleBorders() {
  borders = !borders;
}

bool Pane::Impl::isCursorOnFirstLine() const {
  return posCursor.y() == 0;
}

bool Pane::Impl::isCursorOnLastLine() const {
return posCursor.y() == posPrint.y() - (borders ? 1 : 0);
}

bool Pane::Impl::isCursorOnFirstVisibleLine() const {
  return posCursor.y() == posPad.y() - (borders ? 1 : 0);
}

bool Pane::Impl::isCursorOnLastVisibleLine() const {
  return posCursor.y() == sizeView.height() + posPad.y() - (borders ? 2 : 0);
}

bool Pane::Impl::canScrollUp() const {
  return posPad.y() > 0;
}

bool Pane::Impl::canScrollDown() const {
return posPrint.y() - posPad.y() > sizeView.height() - (borders ? 2 : 0);
}

}
}
<|endoftext|>


<commit_before>/*
 * \copyright Copyright 2014 Xiang Zhang All Rights Reserved.
 * \license @{
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @}
 */

#ifndef THUNDER_SERIALIZER_TEXT_HPP_
#define THUNDER_SERIALIZER_TEXT_HPP_

#include <memory>
#include <sstream>

namespace thunder {
namespace serializer {

template < typename M = ::std::stringstream >
class Text {
 public:
  typedef M stream_type;
  typedef ::std::shared_ptr< M > stream_pointer;

  template < typename... G >
  explicit Text(G... g);

  stream_pointer stream() const;

  // Save of generic type will call static methods
  template < typename S, typename T >
  void save(S *s, const T &t);
  template < typename S, typename T >
  void load(S *s, T *t);

  // Listing of fundamental C++11 character type serialization
  template < typename S >
  void save(S *s, const char &t);
  template < typename S >
  void load(S *s, char *t);
  template < typename S >
  void save(S *s, const signed char &t);
  template < typename S >
  void load(S *s, signed char *t);
  template < typename S >
  void save(S *s, const unsigned char &t);
  template < typename S >
  void load(S *s, unsigned char *t);
  template < typename S >
  void save(S *s, const wchar_t &t);
  template < typename S >
  void load(S *s, wchar_t *t);
  template < typename S >
  void save(S *s, const char16_t &t);
  template < typename S >
  void load(S *s, char16_t *t);
  template < typename S >
  void save(S *s, const char32_t &t);
  template < typename S >
  void load(S *s, char32_t *t);

  // Listing of fundamental C++11 integer type serialization
  template < typename S >
  void save(S *s, const short &t);
  template < typename S >
  void load(S *s, short *t);
  template < typename S >
  void save(S *s, const unsigned short &t);
  template < typename S >
  void load(S *s, unsigned short *t);
  template < typename S >
  void save(S *s, const int &t);
  template < typename S >
  void load(S *s, int *t);
  template < typename S >
  void save(S *s, const unsigned int &t);
  template < typename S >
  void load(S *s, unsigned int *t);
  template < typename S >
  void save(S *s, const long &t);
  template < typename S >
  void load(S *s, long *t);
  template < typename S >
  void save(S *s, const unsigned long &t);
  template < typename S >
  void load(S *s, unsigned long *t);
  template < typename S >
  void save(S *s, const long long &t);
  template < typename S >
  void load(S *s, long long *t);
    template < typename S >
  void save(S *s, const unsigned long long &t);
  template < typename S >
  void load(S *s, unsigned long long *t);

  // Listing of fundamental C++11 floating point type serialization
  template < typename S >
  void save(S *s, const float &t);
  template < typename S >
  void load(S *s, float *t);
  template < typename S >
  void save(S *s, const double &t);
  template < typename S >
  void load(S *s, double *t);
  template < typename S >
  void save(S *s, const long double &t);
  template < typename S >
  void load(S *s, long double *t);

 private:
  stream_pointer stream_;
};

}  // namespace serializer
}  // namespace thunder

#endif  // THUNDER_SERIALIZER_TEXT_HPP_
<commit_msg>Correct indentation<commit_after>/*
 * \copyright Copyright 2014 Xiang Zhang All Rights Reserved.
 * \license @{
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @}
 */

#ifndef THUNDER_SERIALIZER_TEXT_HPP_
#define THUNDER_SERIALIZER_TEXT_HPP_

#include <memory>
#include <sstream>

namespace thunder {
namespace serializer {

template < typename M = ::std::stringstream >
class Text {
 public:
  typedef M stream_type;
  typedef ::std::shared_ptr< M > stream_pointer;

  template < typename... G >
  explicit Text(G... g);

  stream_pointer stream() const;

  // Save of generic type will call static methods
  template < typename S, typename T >
  void save(S *s, const T &t);
  template < typename S, typename T >
  void load(S *s, T *t);

  // Listing of fundamental C++11 character type serialization
  template < typename S >
  void save(S *s, const char &t);
  template < typename S >
  void load(S *s, char *t);
  template < typename S >
  void save(S *s, const signed char &t);
  template < typename S >
  void load(S *s, signed char *t);
  template < typename S >
  void save(S *s, const unsigned char &t);
  template < typename S >
  void load(S *s, unsigned char *t);
  template < typename S >
  void save(S *s, const wchar_t &t);
  template < typename S >
  void load(S *s, wchar_t *t);
  template < typename S >
  void save(S *s, const char16_t &t);
  template < typename S >
  void load(S *s, char16_t *t);
  template < typename S >
  void save(S *s, const char32_t &t);
  template < typename S >
  void load(S *s, char32_t *t);

  // Listing of fundamental C++11 integer type serialization
  template < typename S >
  void save(S *s, const short &t);
  template < typename S >
  void load(S *s, short *t);
  template < typename S >
  void save(S *s, const unsigned short &t);
  template < typename S >
  void load(S *s, unsigned short *t);
  template < typename S >
  void save(S *s, const int &t);
  template < typename S >
  void load(S *s, int *t);
  template < typename S >
  void save(S *s, const unsigned int &t);
  template < typename S >
  void load(S *s, unsigned int *t);
  template < typename S >
  void save(S *s, const long &t);
  template < typename S >
  void load(S *s, long *t);
  template < typename S >
  void save(S *s, const unsigned long &t);
  template < typename S >
  void load(S *s, unsigned long *t);
  template < typename S >
  void save(S *s, const long long &t);
  template < typename S >
  void load(S *s, long long *t);
  template < typename S >
  void save(S *s, const unsigned long long &t);
  template < typename S >
  void load(S *s, unsigned long long *t);

  // Listing of fundamental C++11 floating point type serialization
  template < typename S >
  void save(S *s, const float &t);
  template < typename S >
  void load(S *s, float *t);
  template < typename S >
  void save(S *s, const double &t);
  template < typename S >
  void load(S *s, double *t);
  template < typename S >
  void save(S *s, const long double &t);
  template < typename S >
  void load(S *s, long double *t);

 private:
  stream_pointer stream_;
};

}  // namespace serializer
}  // namespace thunder

#endif  // THUNDER_SERIALIZER_TEXT_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

#include "http_client/video_encoder.h"

#include <new>

#include "glog/logging.h"

namespace webmlive {

VideoFrame::VideoFrame()
    : keyframe_(false),
      width_(0),
      height_(0),
      timestamp_(0),
      duration_(0),
      buffer_capacity_(0),
      buffer_length_(0),
      format_(kVideoFormatI420) {
}

VideoFrame::~VideoFrame() {
}

int32 VideoFrame::Init(VideoFormat format,
                       bool keyframe,
                       int32 width,
                       int32 height,
                       int64 timestamp,
                       int64 duration,
                       const uint8* ptr_data,
                       int32 data_length) {
  if (!ptr_data) {
    LOG(ERROR) << "VideoFrame can't Init with NULL data pointer.";
    return kInvalidArg;
  }
  if (format != kVideoFormatI420 && format != kVideoFormatVP8) {
    LOG(ERROR) << "Unknown VideoFormat.";
    return kInvalidArg;
  }
  if (data_length > buffer_capacity_) {
    buffer_.reset(new (std::nothrow) uint8[data_length]);  // NOLINT
    if (!buffer_) {
      LOG(ERROR) << "VideoFrame Init cannot allocate buffer.";
      return kNoMemory;
    }
    buffer_capacity_ = data_length;
  }
  memcpy(&buffer_[0], ptr_data, data_length);
  buffer_length_ = data_length;
  format_ = format;
  keyframe_ = keyframe;
  width_ = width;
  height_ = height;
  timestamp_ = timestamp;
  duration_ = duration;
  return kSuccess;
}

int32 VideoFrame::Clone(VideoFrame* ptr_frame) const {
  if (!ptr_frame) {
    LOG(ERROR) << "cannot Clone to a NULL VideoFrame.";
    return kInvalidArg;
  }
  if (buffer_.get() && buffer_capacity_ > 0) {
    ptr_frame->buffer_.reset(
        new (std::nothrow) uint8[buffer_capacity_]);  // NOLINT
    if (!ptr_frame->buffer_) {
      LOG(ERROR) << "VideoFrame Clone cannot allocate buffer.";
      return kNoMemory;
    }
    memcpy(&ptr_frame->buffer_[0], &buffer_[0], buffer_length_);
  }
  ptr_frame->buffer_capacity_ = buffer_capacity_;
  ptr_frame->buffer_length_ = buffer_length_;
  ptr_frame->format_ = format_;
  ptr_frame->keyframe_ = keyframe_;
  ptr_frame->width_ = width_;
  ptr_frame->height_ = height_;
  ptr_frame->timestamp_ = timestamp_;
  ptr_frame->duration_ = duration_;
  return kSuccess;
}

void VideoFrame::Swap(VideoFrame* ptr_frame) {
  CHECK_NOTNULL(buffer_.get());
  CHECK_NOTNULL(ptr_frame->buffer_.get());

  const VideoFormat temp_format = format_;
  format_ = ptr_frame->format_;
  ptr_frame->format_ = temp_format;

  const bool temp_keyframe = keyframe_;
  keyframe_ = ptr_frame->keyframe_;
  ptr_frame->keyframe_ = temp_keyframe;

  int32 temp = width_;
  width_ = ptr_frame->width_;
  ptr_frame->width_ = temp;

  temp = height_;
  height_ = ptr_frame->height_;
  ptr_frame->height_ = temp;

  int64 temp_time = timestamp_;
  timestamp_ = ptr_frame->timestamp_;
  ptr_frame->timestamp_ = temp_time;

  temp_time = duration_;
  duration_ = ptr_frame->duration_;
  ptr_frame->duration_ = temp_time;

  buffer_.swap(ptr_frame->buffer_);

  temp = buffer_capacity_;
  buffer_capacity_ = ptr_frame->buffer_capacity_;
  ptr_frame->buffer_capacity_ = temp;

  temp = buffer_length_;
  buffer_length_ = ptr_frame->buffer_length_;
  ptr_frame->buffer_length_ = temp;
}

///////////////////////////////////////////////////////////////////////////////
// VideoFrameQueue
//

VideoFrameQueue::VideoFrameQueue() {
}

VideoFrameQueue::~VideoFrameQueue() {
  boost::mutex::scoped_lock lock(mutex_);
  while (!frame_pool_.empty()) {
    delete frame_pool_.front();
    frame_pool_.pop();
  }
  while (!active_frames_.empty()) {
    delete active_frames_.front();
    active_frames_.pop();
  }
}

// Obtains lock and populates |frame_pool_| with |VideoFrame| pointers.
int32 VideoFrameQueue::Init() {
  boost::mutex::scoped_lock lock(mutex_);
  DCHECK(frame_pool_.empty());
  DCHECK(active_frames_.empty());
  for (int i = 0; i < kQueueLength; ++i) {
    VideoFrame* const ptr_frame = new (std::nothrow) VideoFrame;  // NOLINT
    if (!ptr_frame) {
      LOG(ERROR) << "VideoFrame allocation failed!";
      return kNoMemory;
    }
    frame_pool_.push(ptr_frame);
  }
  return kSuccess;
}

// Obtains lock, copies |ptr_frame| data into |VideoFrame| from |frame_pool_|,
// and moves the frame into |active_frames_|.
int32 VideoFrameQueue::Commit(VideoFrame* ptr_frame) {
  if (!ptr_frame || !ptr_frame->buffer()) {
    LOG(ERROR) << "VideoFrameQueue can't Commit a NULL/empty VideoFrame!";
    return kInvalidArg;
  }
  boost::mutex::scoped_lock lock(mutex_);
  if (frame_pool_.empty()) {
    VLOG(4) << "VideoFrameQueue full.";
    return kFull;
  }

  // Copy user data into front frame from |frame_pool_|.
  VideoFrame* const ptr_pool_frame = frame_pool_.front();
  if (ExchangeFrames(ptr_frame, ptr_pool_frame)) {
    LOG(ERROR) << "VideoFrame Commit ExchangeFrames failed!";
    return kNoMemory;
  }

  // Move the now active frame from the pool into the active queue.
  frame_pool_.pop();
  active_frames_.push(ptr_pool_frame);
  return kSuccess;
}

// Obtains lock, copies front |VideoFrame| from |active_frames_| to
// |ptr_frame|, and moves the consumed |VideoFrame| back into |frame_pool_|.
int32 VideoFrameQueue::Read(VideoFrame* ptr_frame) {
  if (!ptr_frame) {
    LOG(ERROR) << "VideoFrameQueue can't Read into a NULL VideoFrame!";
    return kInvalidArg;
  }
  boost::mutex::scoped_lock lock(mutex_);
  if (active_frames_.empty()) {
    VLOG(4) << "VideoFrameQueue empty.";
    return kEmpty;
  }

  // Copy active frame data to user frame.
  VideoFrame* const ptr_active_frame = active_frames_.front();
  if (ExchangeFrames(ptr_active_frame, ptr_frame)) {
    LOG(ERROR) << "VideoFrame Read ExchangeFrames failed!";
    return kNoMemory;
  }

  // Put the now inactive frame back in the pool.
  active_frames_.pop();
  frame_pool_.push(ptr_active_frame);
  return kSuccess;
}

// Obtains lock and drops any |VideoFrame|s in |active_frames_|.
void VideoFrameQueue::DropFrames() {
  boost::mutex::scoped_lock lock(mutex_);
  while (!active_frames_.empty()) {
    frame_pool_.push(active_frames_.front());
    active_frames_.pop();
  }
}

int32 VideoFrameQueue::ExchangeFrames(VideoFrame* ptr_source,
                                      VideoFrame* ptr_target) {
  if (!ptr_source || !ptr_target) {
    return kInvalidArg;
  }
  if (ptr_target->buffer()) {
    ptr_target->Swap(ptr_source);
  } else {
    const int32 status = ptr_source->Clone(ptr_target);
    if (status) {
      LOG(ERROR) << "VideoFrame Clone failed! " << status;
      return kNoMemory;
    }
  }
  return kSuccess;
}

///////////////////////////////////////////////////////////////////////////////
// VideoEncoder
//

///////////////////////////////////////////////////////////////////////////////
// VideoFrameCallbackInterface
//

VideoFrameCallbackInterface::~VideoFrameCallbackInterface() {
}

}  // namespace webmlive

<commit_msg>video_encoder: Implement VideoEncoder class.<commit_after>// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

#include "http_client/video_encoder.h"

#include <new>

#include "glog/logging.h"

#if defined _MSC_VER
// Disable warning C4505(unreferenced local function has been removed) in MSVC.
// At the time this comment was written the warning is emitted 27 times for
// vp8.h and vp8cx.h (included by vpx_encoder.h).
#pragma warning(disable:4505)
#endif
#include "http_client/vpx_encoder.h"

namespace webmlive {

VideoFrame::VideoFrame()
    : keyframe_(false),
      width_(0),
      height_(0),
      timestamp_(0),
      duration_(0),
      buffer_capacity_(0),
      buffer_length_(0),
      format_(kVideoFormatI420) {
}

VideoFrame::~VideoFrame() {
}

int32 VideoFrame::Init(VideoFormat format,
                       bool keyframe,
                       int32 width,
                       int32 height,
                       int64 timestamp,
                       int64 duration,
                       const uint8* ptr_data,
                       int32 data_length) {
  if (!ptr_data) {
    LOG(ERROR) << "VideoFrame can't Init with NULL data pointer.";
    return kInvalidArg;
  }
  if (format != kVideoFormatI420 && format != kVideoFormatVP8) {
    LOG(ERROR) << "Unknown VideoFormat.";
    return kInvalidArg;
  }
  if (data_length > buffer_capacity_) {
    buffer_.reset(new (std::nothrow) uint8[data_length]);  // NOLINT
    if (!buffer_) {
      LOG(ERROR) << "VideoFrame Init cannot allocate buffer.";
      return kNoMemory;
    }
    buffer_capacity_ = data_length;
  }
  memcpy(&buffer_[0], ptr_data, data_length);
  buffer_length_ = data_length;
  format_ = format;
  keyframe_ = keyframe;
  width_ = width;
  height_ = height;
  timestamp_ = timestamp;
  duration_ = duration;
  return kSuccess;
}

int32 VideoFrame::Clone(VideoFrame* ptr_frame) const {
  if (!ptr_frame) {
    LOG(ERROR) << "cannot Clone to a NULL VideoFrame.";
    return kInvalidArg;
  }
  if (buffer_.get() && buffer_capacity_ > 0) {
    ptr_frame->buffer_.reset(
        new (std::nothrow) uint8[buffer_capacity_]);  // NOLINT
    if (!ptr_frame->buffer_) {
      LOG(ERROR) << "VideoFrame Clone cannot allocate buffer.";
      return kNoMemory;
    }
    memcpy(&ptr_frame->buffer_[0], &buffer_[0], buffer_length_);
  }
  ptr_frame->buffer_capacity_ = buffer_capacity_;
  ptr_frame->buffer_length_ = buffer_length_;
  ptr_frame->format_ = format_;
  ptr_frame->keyframe_ = keyframe_;
  ptr_frame->width_ = width_;
  ptr_frame->height_ = height_;
  ptr_frame->timestamp_ = timestamp_;
  ptr_frame->duration_ = duration_;
  return kSuccess;
}

void VideoFrame::Swap(VideoFrame* ptr_frame) {
  CHECK_NOTNULL(buffer_.get());
  CHECK_NOTNULL(ptr_frame->buffer_.get());

  const VideoFormat temp_format = format_;
  format_ = ptr_frame->format_;
  ptr_frame->format_ = temp_format;

  const bool temp_keyframe = keyframe_;
  keyframe_ = ptr_frame->keyframe_;
  ptr_frame->keyframe_ = temp_keyframe;

  int32 temp = width_;
  width_ = ptr_frame->width_;
  ptr_frame->width_ = temp;

  temp = height_;
  height_ = ptr_frame->height_;
  ptr_frame->height_ = temp;

  int64 temp_time = timestamp_;
  timestamp_ = ptr_frame->timestamp_;
  ptr_frame->timestamp_ = temp_time;

  temp_time = duration_;
  duration_ = ptr_frame->duration_;
  ptr_frame->duration_ = temp_time;

  buffer_.swap(ptr_frame->buffer_);

  temp = buffer_capacity_;
  buffer_capacity_ = ptr_frame->buffer_capacity_;
  ptr_frame->buffer_capacity_ = temp;

  temp = buffer_length_;
  buffer_length_ = ptr_frame->buffer_length_;
  ptr_frame->buffer_length_ = temp;
}

///////////////////////////////////////////////////////////////////////////////
// VideoFrameQueue
//

VideoFrameQueue::VideoFrameQueue() {
}

VideoFrameQueue::~VideoFrameQueue() {
  boost::mutex::scoped_lock lock(mutex_);
  while (!frame_pool_.empty()) {
    delete frame_pool_.front();
    frame_pool_.pop();
  }
  while (!active_frames_.empty()) {
    delete active_frames_.front();
    active_frames_.pop();
  }
}

// Obtains lock and populates |frame_pool_| with |VideoFrame| pointers.
int32 VideoFrameQueue::Init() {
  boost::mutex::scoped_lock lock(mutex_);
  DCHECK(frame_pool_.empty());
  DCHECK(active_frames_.empty());
  for (int i = 0; i < kQueueLength; ++i) {
    VideoFrame* const ptr_frame = new (std::nothrow) VideoFrame;  // NOLINT
    if (!ptr_frame) {
      LOG(ERROR) << "VideoFrame allocation failed!";
      return kNoMemory;
    }
    frame_pool_.push(ptr_frame);
  }
  return kSuccess;
}

// Obtains lock, copies |ptr_frame| data into |VideoFrame| from |frame_pool_|,
// and moves the frame into |active_frames_|.
int32 VideoFrameQueue::Commit(VideoFrame* ptr_frame) {
  if (!ptr_frame || !ptr_frame->buffer()) {
    LOG(ERROR) << "VideoFrameQueue can't Commit a NULL/empty VideoFrame!";
    return kInvalidArg;
  }
  boost::mutex::scoped_lock lock(mutex_);
  if (frame_pool_.empty()) {
    VLOG(4) << "VideoFrameQueue full.";
    return kFull;
  }

  // Copy user data into front frame from |frame_pool_|.
  VideoFrame* const ptr_pool_frame = frame_pool_.front();
  if (ExchangeFrames(ptr_frame, ptr_pool_frame)) {
    LOG(ERROR) << "VideoFrame Commit ExchangeFrames failed!";
    return kNoMemory;
  }

  // Move the now active frame from the pool into the active queue.
  frame_pool_.pop();
  active_frames_.push(ptr_pool_frame);
  return kSuccess;
}

// Obtains lock, copies front |VideoFrame| from |active_frames_| to
// |ptr_frame|, and moves the consumed |VideoFrame| back into |frame_pool_|.
int32 VideoFrameQueue::Read(VideoFrame* ptr_frame) {
  if (!ptr_frame) {
    LOG(ERROR) << "VideoFrameQueue can't Read into a NULL VideoFrame!";
    return kInvalidArg;
  }
  boost::mutex::scoped_lock lock(mutex_);
  if (active_frames_.empty()) {
    VLOG(4) << "VideoFrameQueue empty.";
    return kEmpty;
  }

  // Copy active frame data to user frame.
  VideoFrame* const ptr_active_frame = active_frames_.front();
  if (ExchangeFrames(ptr_active_frame, ptr_frame)) {
    LOG(ERROR) << "VideoFrame Read ExchangeFrames failed!";
    return kNoMemory;
  }

  // Put the now inactive frame back in the pool.
  active_frames_.pop();
  frame_pool_.push(ptr_active_frame);
  return kSuccess;
}

// Obtains lock and drops any |VideoFrame|s in |active_frames_|.
void VideoFrameQueue::DropFrames() {
  boost::mutex::scoped_lock lock(mutex_);
  while (!active_frames_.empty()) {
    frame_pool_.push(active_frames_.front());
    active_frames_.pop();
  }
}

int32 VideoFrameQueue::ExchangeFrames(VideoFrame* ptr_source,
                                      VideoFrame* ptr_target) {
  if (!ptr_source || !ptr_target) {
    return kInvalidArg;
  }
  if (ptr_target->buffer()) {
    ptr_target->Swap(ptr_source);
  } else {
    const int32 status = ptr_source->Clone(ptr_target);
    if (status) {
      LOG(ERROR) << "VideoFrame Clone failed! " << status;
      return kNoMemory;
    }
  }
  return kSuccess;
}

///////////////////////////////////////////////////////////////////////////////
// VideoEncoder
//

VideoEncoder::VideoEncoder() {
}

VideoEncoder::~VideoEncoder() {
}

int32 VideoEncoder::Init(const WebmEncoderConfig& config) {
  ptr_vpx_encoder_.reset(new (std::nothrow) VpxEncoder());
  if (!ptr_vpx_encoder_) {
    return kNoMemory;
  }
  return ptr_vpx_encoder_->Init(config);
}

int32 VideoEncoder::EncodeFrame(const VideoFrame& raw_frame,
                                VideoFrame* ptr_vp8_frame) {
  if (!ptr_vpx_encoder_) {
    LOG(ERROR) << "VideoEncoder has NULL encoder, not Init'd";
    return kEncoderError;
  }
  return ptr_vpx_encoder_->EncodeFrame(raw_frame, ptr_vp8_frame);
}

///////////////////////////////////////////////////////////////////////////////
// VideoFrameCallbackInterface
//

VideoFrameCallbackInterface::~VideoFrameCallbackInterface() {
}

}  // namespace webmlive

<|endoftext|>


<commit_before>#ifndef __CONTROLLER_HPP
#define __CONTROLLER_HPP

#ifndef __ODRIVE_MAIN_H
#error "This file should not be included directly. Include odrive_main.h instead."
#endif

class Controller {
public:
    // Note: these should be sorted from lowest level of control to
    // highest level of control, to allow "<" style comparisons.
    enum ControlMode_t{
        CTRL_MODE_VOLTAGE_CONTROL = 0,
        CTRL_MODE_CURRENT_CONTROL = 1,
        CTRL_MODE_VELOCITY_CONTROL = 2,
        CTRL_MODE_POSITION_CONTROL = 3,
        CTRL_MODE_TRAJECTORY_CONTROL = 4
    };

    struct Config_t {
        ControlMode_t control_mode = CTRL_MODE_POSITION_CONTROL;  //see: Motor_control_mode_t
        float pos_gain = 20.0f;  // [(counts/s) / counts]
        float vel_gain = 5.0f / 10000.0f;  // [A/(counts/s)]
        // float vel_gain = 5.0f / 200.0f, // [A/(rad/s)] <sensorless example>
        float vel_integrator_gain = 10.0f / 10000.0f;  // [A/(counts/s * s)]
        float vel_limit = 20000.0f;           // [counts/s]
    };

    Controller(Config_t& config);
    void reset();

    void set_pos_setpoint(float pos_setpoint, float vel_feed_forward, float current_feed_forward);
    void set_vel_setpoint(float vel_setpoint, float current_feed_forward);
    void set_current_setpoint(float current_setpoint);

    // Trajectory-Planned control
    void move_to_pos(float goal_point);

    // TODO: make this more similar to other calibration loops
    void start_anticogging_calibration();
    bool anticogging_calibration(float pos_estimate, float vel_estimate);

    bool update(float pos_estimate, float vel_estimate, float* current_setpoint);

    Config_t& config_;
    Axis* axis_ = nullptr; // set by Axis constructor

    // TODO: anticogging overhaul:
    // - expose selected (all?) variables on protocol
    // - make calibration user experience similar to motor & encoder calibration
    // - use python tools to Fourier transform and write back the smoothed map or Fourier coefficients
    // - make the calibration persistent

    typedef struct {
        int index;
        float *cogging_map;
        bool use_anticogging;
        bool calib_anticogging;
        float calib_pos_threshold;
        float calib_vel_threshold;
    } Anticogging_t;
    Anticogging_t anticogging_ = {
        .index = 0,
        .cogging_map = nullptr,
        .use_anticogging = false,
        .calib_anticogging = false,
        .calib_pos_threshold = 1.0f,
        .calib_vel_threshold = 1.0f,
    };

    // variables exposed on protocol
    float pos_setpoint_ = 0.0f;
    float vel_setpoint_ = 0.0f;
    // float vel_setpoint = 800.0f; <sensorless example>
    float vel_integrator_current_ = 0.0f;  // [A]
    float current_setpoint_ = 0.0f;        // [A]

    uint32_t traj_start_loop_count_ = 0;

    // Communication protocol definitions
    auto make_protocol_definitions() {
        return make_protocol_member_list(
            make_protocol_property("pos_setpoint", &pos_setpoint_),
            make_protocol_property("vel_setpoint", &vel_setpoint_),
            make_protocol_property("vel_integrator_current", &vel_integrator_current_),
            make_protocol_property("current_setpoint", &current_setpoint_),
            make_protocol_object("config",
                make_protocol_property("control_mode", &config_.control_mode),
                make_protocol_property("pos_gain", &config_.pos_gain),
                make_protocol_property("vel_gain", &config_.vel_gain),
                make_protocol_property("vel_integrator_gain", &config_.vel_integrator_gain),
                make_protocol_property("vel_limit", &config_.vel_limit)
            ),
            make_protocol_function("set_pos_setpoint", *this, &Controller::set_pos_setpoint,
                "pos_setpoint", "vel_feed_forward", "current_feed_forward"),
            make_protocol_function("set_vel_setpoint", *this, &Controller::set_vel_setpoint,
                "vel_setpoint", "current_feed_forward"),
            make_protocol_function("set_current_setpoint", *this, &Controller::set_current_setpoint,
                "current_setpoint"),
            make_protocol_function("move_to_pos", *this, &Controller::move_to_pos, "pos_setpoint"),
            make_protocol_function("start_anticogging_calibration", *this, &Controller::start_anticogging_calibration)
        );
    }
};

#endif // __CONTROLLER_HPP
<commit_msg>update traj jason to goal_point<commit_after>#ifndef __CONTROLLER_HPP
#define __CONTROLLER_HPP

#ifndef __ODRIVE_MAIN_H
#error "This file should not be included directly. Include odrive_main.h instead."
#endif

class Controller {
public:
    // Note: these should be sorted from lowest level of control to
    // highest level of control, to allow "<" style comparisons.
    enum ControlMode_t{
        CTRL_MODE_VOLTAGE_CONTROL = 0,
        CTRL_MODE_CURRENT_CONTROL = 1,
        CTRL_MODE_VELOCITY_CONTROL = 2,
        CTRL_MODE_POSITION_CONTROL = 3,
        CTRL_MODE_TRAJECTORY_CONTROL = 4
    };

    struct Config_t {
        ControlMode_t control_mode = CTRL_MODE_POSITION_CONTROL;  //see: Motor_control_mode_t
        float pos_gain = 20.0f;  // [(counts/s) / counts]
        float vel_gain = 5.0f / 10000.0f;  // [A/(counts/s)]
        // float vel_gain = 5.0f / 200.0f, // [A/(rad/s)] <sensorless example>
        float vel_integrator_gain = 10.0f / 10000.0f;  // [A/(counts/s * s)]
        float vel_limit = 20000.0f;           // [counts/s]
    };

    Controller(Config_t& config);
    void reset();

    void set_pos_setpoint(float pos_setpoint, float vel_feed_forward, float current_feed_forward);
    void set_vel_setpoint(float vel_setpoint, float current_feed_forward);
    void set_current_setpoint(float current_setpoint);

    // Trajectory-Planned control
    void move_to_pos(float goal_point);

    // TODO: make this more similar to other calibration loops
    void start_anticogging_calibration();
    bool anticogging_calibration(float pos_estimate, float vel_estimate);

    bool update(float pos_estimate, float vel_estimate, float* current_setpoint);

    Config_t& config_;
    Axis* axis_ = nullptr; // set by Axis constructor

    // TODO: anticogging overhaul:
    // - expose selected (all?) variables on protocol
    // - make calibration user experience similar to motor & encoder calibration
    // - use python tools to Fourier transform and write back the smoothed map or Fourier coefficients
    // - make the calibration persistent

    typedef struct {
        int index;
        float *cogging_map;
        bool use_anticogging;
        bool calib_anticogging;
        float calib_pos_threshold;
        float calib_vel_threshold;
    } Anticogging_t;
    Anticogging_t anticogging_ = {
        .index = 0,
        .cogging_map = nullptr,
        .use_anticogging = false,
        .calib_anticogging = false,
        .calib_pos_threshold = 1.0f,
        .calib_vel_threshold = 1.0f,
    };

    // variables exposed on protocol
    float pos_setpoint_ = 0.0f;
    float vel_setpoint_ = 0.0f;
    // float vel_setpoint = 800.0f; <sensorless example>
    float vel_integrator_current_ = 0.0f;  // [A]
    float current_setpoint_ = 0.0f;        // [A]

    uint32_t traj_start_loop_count_ = 0;

    // Communication protocol definitions
    auto make_protocol_definitions() {
        return make_protocol_member_list(
            make_protocol_property("pos_setpoint", &pos_setpoint_),
            make_protocol_property("vel_setpoint", &vel_setpoint_),
            make_protocol_property("vel_integrator_current", &vel_integrator_current_),
            make_protocol_property("current_setpoint", &current_setpoint_),
            make_protocol_object("config",
                make_protocol_property("control_mode", &config_.control_mode),
                make_protocol_property("pos_gain", &config_.pos_gain),
                make_protocol_property("vel_gain", &config_.vel_gain),
                make_protocol_property("vel_integrator_gain", &config_.vel_integrator_gain),
                make_protocol_property("vel_limit", &config_.vel_limit)
            ),
            make_protocol_function("set_pos_setpoint", *this, &Controller::set_pos_setpoint,
                "pos_setpoint", "vel_feed_forward", "current_feed_forward"),
            make_protocol_function("set_vel_setpoint", *this, &Controller::set_vel_setpoint,
                "vel_setpoint", "current_feed_forward"),
            make_protocol_function("set_current_setpoint", *this, &Controller::set_current_setpoint,
                "current_setpoint"),
            make_protocol_function("move_to_pos", *this, &Controller::move_to_pos, "goal_point"),
            make_protocol_function("start_anticogging_calibration", *this, &Controller::start_anticogging_calibration)
        );
    }
};

#endif // __CONTROLLER_HPP
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014-2017 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/math/aabb.h"
#include "foundation/math/bvh.h"
#include "foundation/utility/test.h"

using namespace foundation;
using namespace bvh;
using namespace std;

TEST_SUITE(Foundation_Math_BVH_MiddlePartitioner)
{
    typedef std::vector<AABB2d> AABB2dVector;

    //                 .         |
    //                 .     __  |
    //                 .    |  | |
    //  --10-9---------4----2--1---1--2-----
    //    |__|         .         | |__|
    //                 .         |
    //                 .         |
    //     [0]               [1]    [2]

    TEST_CASE(Partition_BBoxesOrderedAlongLongestDimension_ReturnsFirstElementAfterCenter)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d(-10.0, -1.0 ), Vector2d( -9.0,  0.0 )),
                AABB2d(Vector2d( -2.0,  0.0 ), Vector2d( -1.0,  1.0 )),
                AABB2d(Vector2d(  1.0, -1.0 ), Vector2d(  2.0,  0.0 ))
            };
        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(1, pivot);
    }

    //                 .         |  __
    //                 .     __  | |__|
    //                 .    |  | |
    //  --10-9---------4----2--1---1--2-----
    //    |__|         .         |
    //                 .         |
    //                 .         |
    //     [1]               [0]    [2]

    TEST_CASE(Partition_BBoxesUnorderedAlongAllDimensions_ReturnsFirstElementAfterCenter)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d( -2.0,  0.0 ), Vector2d( -1.0,  1.0 )),
                AABB2d(Vector2d(-10.0, -1.0 ), Vector2d( -9.0,  0.0 )),
                AABB2d(Vector2d(  1.0,  1.0 ), Vector2d(  2.0,  2.0 ))
            };

        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(1, pivot);
    }

    //      [0]    [2]
    //      __  |  __
    //     |__| | |__|
    //          |
    //  ---2--1---1--2---
    //      __  |  __
    //     |__| | |__|
    //          |
    //      [1]    [3]

    TEST_CASE(Partition_BBoxesFormingRectangle_ReturnsFirstElementAfterCenter)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d(-2.0, 1.0 ), Vector2d(-1.0, 2.0 )),
                AABB2d(Vector2d(-2.0,-2.0 ), Vector2d(-1.0,-1.0 )),
                AABB2d(Vector2d( 1.0, 1.0 ), Vector2d( 2.0, 2.0 )),
                AABB2d(Vector2d( 1.0,-2.0 ), Vector2d( 2.0,-1.0 ))
            };

        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(2, pivot);
    }

    TEST_CASE(Partition_BBoxesOverlapping_ReturnElementAfterMiddle)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 )),
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 )),
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 )),
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 ))
            };

        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(2, pivot);
    }
}<commit_msg>Test bboxes set as even triangle.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014-2017 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/math/aabb.h"
#include "foundation/math/bvh.h"
#include "foundation/utility/test.h"

using namespace foundation;
using namespace bvh;
using namespace std;

TEST_SUITE(Foundation_Math_BVH_MiddlePartitioner)
{
    typedef std::vector<AABB2d> AABB2dVector;

    //                 .         |
    //                 .     __  |
    //                 .    |  | |
    //  --10-9---------4----2--1---1--2-----
    //    |__|         .         | |__|
    //                 .         |
    //                 .         |
    //     [0]               [1]    [2]

    TEST_CASE(Partition_BBoxesOrderedAlongLongestDimension_ReturnsFirstElementAfterCenter)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d(-10.0, -1.0 ), Vector2d( -9.0,  0.0 )),
                AABB2d(Vector2d( -2.0,  0.0 ), Vector2d( -1.0,  1.0 )),
                AABB2d(Vector2d(  1.0, -1.0 ), Vector2d(  2.0,  0.0 ))
            };
        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(1, pivot);
    }

    //                 .         |  __
    //                 .     __  | |__|
    //                 .    |  | |
    //  --10-9---------4----2--1---1--2-----
    //    |__|         .         |
    //                 .         |
    //                 .         |
    //     [1]               [0]    [2]

    TEST_CASE(Partition_BBoxesUnorderedAlongAllDimensions_ReturnsFirstElementAfterCenter)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d( -2.0,  0.0 ), Vector2d( -1.0,  1.0 )),
                AABB2d(Vector2d(-10.0, -1.0 ), Vector2d( -9.0,  0.0 )),
                AABB2d(Vector2d(  1.0,  1.0 ), Vector2d(  2.0,  2.0 ))
            };

        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(1, pivot);
    }

    //      [0]    [2]
    //      __  |  __
    //     |__| | |__|
    //          |
    //  ---2--1---1--2---
    //      __  |  __
    //     |__| | |__|
    //          |
    //      [1]    [3]

    TEST_CASE(Partition_BBoxesFormingRectangle_ReturnsFirstElementAfterCenter)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d(-2.0, 1.0 ), Vector2d(-1.0, 2.0 )),
                AABB2d(Vector2d(-2.0,-2.0 ), Vector2d(-1.0,-1.0 )),
                AABB2d(Vector2d( 1.0, 1.0 ), Vector2d( 2.0, 2.0 )),
                AABB2d(Vector2d( 1.0,-2.0 ), Vector2d( 2.0,-1.0 ))
            };

        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(2, pivot);
    }

    //      [0]    [2]
    //      __  |  __
    //     |__| | |__|
    //          |
    //  ---2--1---1--2---
    //         _|_
    //        |_|_|
    //          |
    //         [1]

    TEST_CASE(Partition_BBoxesFormingEvenTriangle_ReturnsMiddleElement)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d(-2.0, 1.0 ), Vector2d(-1.0, 2.0 )),
                AABB2d(Vector2d(-1.0,-2.0 ), Vector2d( 1.0,-1.0 )),
                AABB2d(Vector2d( 1.0, 1.0 ), Vector2d( 2.0, 2.0 ))
            };

        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(1, pivot);
    }

    TEST_CASE(Partition_BBoxesOverlapping_ReturnMiddleElement)
    {
        AABB2dVector bboxes =
            {
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 )),
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 )),
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 )),
                AABB2d(Vector2d(-1.0,-1.0 ), Vector2d( 1.0, 1.0 ))
            };

        MiddlePartitioner<AABB2dVector> partitioner(bboxes, 1);
        const AABB2d root_bbox(partitioner.compute_bbox(0, bboxes.size()));

        size_t pivot = partitioner.partition(0, bboxes.size(), root_bbox);

        EXPECT_EQ(2, pivot);
    }
}<|endoftext|>


<commit_before>#include <vtkSmartPointer.h>
#include <vtkPolyDataConnectivityFilter.h>

#include <vtkSphereSource.h>
#include <vtkDataSetMapper.h>

#include <vtkLookupTable.h>
#include <vtkCamera.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAppendPolyData.h>
#include <vtkScalarsToColors.h>
#include <vtkNamedColors.h>

#include <vtkBYUReader.h>
#include <vtkOBJReader.h>
#include <vtkPLYReader.h>
#include <vtkPolyDataReader.h>
#include <vtkSTLReader.h>
#include <vtkXMLPolyDataReader.h>
#include <vtksys/SystemTools.hxx>

#include <random>

namespace
{
vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName);
}

int main(int argc, char*argv[])
{
  vtkSmartPointer<vtkPolyData> polyData =
    ReadPolyData(argc > 1 ? argv[1] : "");

  vtkSmartPointer<vtkPolyDataConnectivityFilter> connectivityFilter =
    vtkSmartPointer<vtkPolyDataConnectivityFilter>::New();
  connectivityFilter->SetInputData(polyData);
  connectivityFilter->SetExtractionModeToAllRegions();
  connectivityFilter->ColorRegionsOn();
  connectivityFilter->Update();

  // Visualize
  int numberOfRegions = connectivityFilter->GetNumberOfExtractedRegions();
  if (argc > 1)
    {
      std::cout << argv[1] << " contains " << numberOfRegions << " regions" << std::endl;
    }
    else
    {
      std::cout << "Generated data" << " contains " << numberOfRegions << " regions" << std::endl;
    }
  vtkSmartPointer<vtkLookupTable> lut =
    vtkSmartPointer<vtkLookupTable>::New();
  lut->SetNumberOfTableValues(std::max(numberOfRegions, 10));
  lut->Build();

  // Fill in a few known colors, the rest will be generated if needed
  vtkSmartPointer<vtkNamedColors> colors =
    vtkSmartPointer<vtkNamedColors>::New();
  lut->SetTableValue(0, colors->GetColor4d("Gold").GetData());
  lut->SetTableValue(1, colors->GetColor4d("Banana").GetData());
  lut->SetTableValue(2, colors->GetColor4d("Tomato").GetData());
  lut->SetTableValue(3, colors->GetColor4d("Wheat").GetData());
  lut->SetTableValue(4, colors->GetColor4d("Lavender").GetData());
  lut->SetTableValue(5, colors->GetColor4d("Flesh").GetData());
  lut->SetTableValue(6, colors->GetColor4d("Raspberry").GetData());
  lut->SetTableValue(7, colors->GetColor4d("Salmon").GetData());
  lut->SetTableValue(8, colors->GetColor4d("Mint").GetData());
  lut->SetTableValue(9, colors->GetColor4d("Peacock").GetData());

  // If the number of regions os larger than the number of specified colors,
  // generate some random colors.
  if (numberOfRegions > 9)
  {
    std::mt19937 mt(4355412); //Standard mersenne_twister_engine
    std::uniform_real_distribution<double> distribution(.6, 1.0);
    for (auto i = 10; i < numberOfRegions; ++i)
    {
      lut->SetTableValue(i, distribution(mt), distribution(mt), distribution(mt), 1.0);
    }
  }
  vtkSmartPointer<vtkDataSetMapper> mapper =
    vtkSmartPointer<vtkDataSetMapper>::New();
  mapper->SetInputConnection(connectivityFilter->GetOutputPort());
  mapper->SetScalarRange(0, connectivityFilter->GetNumberOfExtractedRegions() - 1);
  mapper->SetLookupTable(lut);
  mapper->Update();

  vtkSmartPointer<vtkActor> actor =
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
  renderer->AddActor(actor);
  renderer->UseHiddenLineRemovalOn();
  renderer->SetBackground(colors->GetColor3d("Silver").GetData());

  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  renderWindow->SetSize(640, 480);

  // Pick a good view
  renderer->GetActiveCamera()->SetFocalPoint(0.0, 0.0, 0.0);
  renderer->GetActiveCamera()->SetPosition(0.0, 1.0, 0.0);
  renderer->GetActiveCamera()->SetViewUp(0.0, 0.0, 1.0);
  renderer->GetActiveCamera()->Azimuth(30.0);
  renderer->GetActiveCamera()->Elevation(45.0);
  renderer->ResetCamera();
  renderer->GetActiveCamera()->Dolly(1.25);
  renderer->ResetCameraClippingRange();
  renderWindow->Render();

  vtkSmartPointer<vtkRenderWindowInteractor> interactor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);
  interactor->Initialize();
  interactor->Start();

  return EXIT_SUCCESS;
}
namespace
{
vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName)
{
  vtkSmartPointer<vtkPolyData> polyData;
  std::string extension = vtksys::SystemTools::GetFilenameLastExtension(std::string(fileName));
  if (extension == ".ply")
  {
    vtkSmartPointer<vtkPLYReader> reader =
      vtkSmartPointer<vtkPLYReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".vtp")
  {
    vtkSmartPointer<vtkXMLPolyDataReader> reader =
      vtkSmartPointer<vtkXMLPolyDataReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".obj")
  {
    vtkSmartPointer<vtkOBJReader> reader =
      vtkSmartPointer<vtkOBJReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".stl")
  {
    vtkSmartPointer<vtkSTLReader> reader =
      vtkSmartPointer<vtkSTLReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".vtk")
  {
    vtkSmartPointer<vtkPolyDataReader> reader =
      vtkSmartPointer<vtkPolyDataReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".g")
  {
    vtkSmartPointer<vtkBYUReader> reader =
      vtkSmartPointer<vtkBYUReader>::New();
    reader->SetGeometryFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else
  {
    vtkSmartPointer<vtkSphereSource> sphereSource1 =
      vtkSmartPointer<vtkSphereSource>::New();
    sphereSource1->Update();

    vtkSmartPointer<vtkSphereSource> sphereSource2 =
      vtkSmartPointer<vtkSphereSource>::New();
    sphereSource2->SetCenter(5,0,0);
    sphereSource2->Update();

    vtkSmartPointer<vtkAppendPolyData> appendFilter =
      vtkSmartPointer<vtkAppendPolyData>::New();
    appendFilter->AddInputConnection(sphereSource1->GetOutputPort());
    appendFilter->AddInputConnection(sphereSource2->GetOutputPort());
    appendFilter->Update();
    polyData = appendFilter->GetOutput();
  }
  return polyData;
}
}
<commit_msg>ENH: Modernization<commit_after>#include <vtkSmartPointer.h>
#include <vtkPolyDataConnectivityFilter.h>

#include <vtkSphereSource.h>
#include <vtkDataSetMapper.h>

#include <vtkLookupTable.h>
#include <vtkCamera.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAppendPolyData.h>
#include <vtkScalarsToColors.h>
#include <vtkNamedColors.h>

// Readers
#include <vtkBYUReader.h>
#include <vtkOBJReader.h>
#include <vtkPLYReader.h>
#include <vtkPolyDataReader.h>
#include <vtkSTLReader.h>
#include <vtkXMLPolyDataReader.h>

#include <vtkPolyData.h>
#include <vtkSphereSource.h>

#include <algorithm> // For transform()
#include <string> // For find_last_of()
#include <cctype> // For to_lower

#include <random>

namespace
{
vtkSmartPointer<vtkPolyData> ReadPolyData(std::string const& fileName);
}

int main(int argc, char*argv[])
{
  vtkSmartPointer<vtkPolyData> polyData =
    ReadPolyData(argc > 1 ? argv[1] : "");

  auto connectivityFilter =
    vtkSmartPointer<vtkPolyDataConnectivityFilter>::New();
  connectivityFilter->SetInputData(polyData);
  connectivityFilter->SetExtractionModeToAllRegions();
  connectivityFilter->ColorRegionsOn();
  connectivityFilter->Update();

  // Visualize
  int numberOfRegions = connectivityFilter->GetNumberOfExtractedRegions();
  if (argc > 1)
    {
      std::cout << argv[1] << " contains " << numberOfRegions << " regions" << std::endl;
    }
    else
    {
      std::cout << "Generated data" << " contains " << numberOfRegions << " regions" << std::endl;
    }
  auto lut =
    vtkSmartPointer<vtkLookupTable>::New();
  lut->SetNumberOfTableValues(std::max(numberOfRegions, 10));
  lut->Build();

  // Fill in a few known colors, the rest will be generated if needed
  auto colors =
    vtkSmartPointer<vtkNamedColors>::New();
  lut->SetTableValue(0, colors->GetColor4d("Gold").GetData());
  lut->SetTableValue(1, colors->GetColor4d("Banana").GetData());
  lut->SetTableValue(2, colors->GetColor4d("Tomato").GetData());
  lut->SetTableValue(3, colors->GetColor4d("Wheat").GetData());
  lut->SetTableValue(4, colors->GetColor4d("Lavender").GetData());
  lut->SetTableValue(5, colors->GetColor4d("Flesh").GetData());
  lut->SetTableValue(6, colors->GetColor4d("Raspberry").GetData());
  lut->SetTableValue(7, colors->GetColor4d("Salmon").GetData());
  lut->SetTableValue(8, colors->GetColor4d("Mint").GetData());
  lut->SetTableValue(9, colors->GetColor4d("Peacock").GetData());

  // If the number of regions os larger than the number of specified colors,
  // generate some random colors.
  if (numberOfRegions > 9)
  {
    std::mt19937 mt(4355412); //Standard mersenne_twister_engine
    std::uniform_real_distribution<double> distribution(.4, 1.0);
    for (auto i = 10; i < numberOfRegions; ++i)
    {
      lut->SetTableValue(i, distribution(mt), distribution(mt), distribution(mt), 1.0);
    }
  }
  auto mapper =
    vtkSmartPointer<vtkDataSetMapper>::New();
  mapper->SetInputConnection(connectivityFilter->GetOutputPort());
  mapper->SetScalarRange(0, connectivityFilter->GetNumberOfExtractedRegions() - 1);
  mapper->SetLookupTable(lut);
  mapper->Update();

  auto  actor =
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  auto  renderer =
    vtkSmartPointer<vtkRenderer>::New();
  renderer->AddActor(actor);
  renderer->UseHiddenLineRemovalOn();
  renderer->SetBackground(colors->GetColor3d("Silver").GetData());

  auto  renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  renderWindow->SetSize(640, 480);

  // Pick a good view
  renderer->GetActiveCamera()->SetFocalPoint(0.0, 0.0, 0.0);
  renderer->GetActiveCamera()->SetPosition(0.0, 1.0, 0.0);
  renderer->GetActiveCamera()->SetViewUp(0.0, 0.0, 1.0);
  renderer->GetActiveCamera()->Azimuth(30.0);
  renderer->GetActiveCamera()->Elevation(45.0);
  renderer->ResetCamera();
  renderer->GetActiveCamera()->Dolly(1.25);
  renderer->ResetCameraClippingRange();
  renderWindow->Render();

  auto  interactor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);
  interactor->Initialize();
  interactor->Start();

  return EXIT_SUCCESS;
}
namespace {
vtkSmartPointer<vtkPolyData> ReadPolyData(std::string const& fileName)
{
  vtkSmartPointer<vtkPolyData> polyData;
  std::string extension = "";
  if (fileName.find_last_of(".") != std::string::npos)
  {
    extension = fileName.substr(fileName.find_last_of("."));
  }
  // Make the extension lowercase
  std::transform(extension.begin(), extension.end(), extension.begin(),
                 ::tolower);
  if (extension == ".ply")
  {
    auto reader = vtkSmartPointer<vtkPLYReader>::New();
    reader->SetFileName(fileName.c_str());
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".vtp")
  {
    auto reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
    reader->SetFileName(fileName.c_str());
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".obj")
  {
    auto reader = vtkSmartPointer<vtkOBJReader>::New();
    reader->SetFileName(fileName.c_str());
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".stl")
  {
    auto reader = vtkSmartPointer<vtkSTLReader>::New();
    reader->SetFileName(fileName.c_str());
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".vtk")
  {
    auto reader = vtkSmartPointer<vtkPolyDataReader>::New();
    reader->SetFileName(fileName.c_str());
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".g")
  {
    auto reader = vtkSmartPointer<vtkBYUReader>::New();
    reader->SetGeometryFileName(fileName.c_str());
    reader->Update();
    polyData = reader->GetOutput();
  }
  else
  {
    // Return a polydata sphere if the extension is unknown.
    auto source = vtkSmartPointer<vtkSphereSource>::New();
    source->SetThetaResolution(20);
    source->SetPhiResolution(11);
    source->Update();
    polyData = source->GetOutput();
  }
  return polyData;
}
} // namespace
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2014 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/math/ec_keys.hpp>

#include <algorithm>
#include <mutex>
#include <secp256k1.h>
#include <bitcoin/bitcoin/math/hash.hpp>
#include <bitcoin/bitcoin/utility/assert.hpp>
#include <bitcoin/bitcoin/utility/endian.hpp>

namespace libbitcoin {

// This class holds no static state but will only initialize its state once for
// the given mutex. This can be assigned to a static or otherwise. It lazily
// inits the context once and destroys the context on destruct as necessary.
class curve
{
private:
    static void set_context(secp256k1_context_t** context, int flags)
    {
        *context = secp256k1_context_create(flags);
    }

public:
    curve(int flags)
        : flags_(flags), context_(nullptr)
    {
    }

    ~curve()
    {
        if (context_ != nullptr)
            secp256k1_context_destroy(context_);
    }

    secp256k1_context_t* context()
    {
        std::call_once(mutex_, set_context, &context_, flags_);
        return context_;
    }

private:
    int flags_;
    std::once_flag mutex_;
    secp256k1_context_t* context_;
};

// We do not share contexts because they may or may not both be required at
// some point and they can't be independently destroyed.
static curve signing(SECP256K1_CONTEXT_SIGN);
static curve verification(SECP256K1_CONTEXT_VERIFY);

ec_point secret_to_public_key(const ec_secret& secret,
    bool compressed)
{
    const auto signing_context = signing.context();
    size_t public_key_size = ec_uncompressed_size;
    if (compressed)
        public_key_size = ec_compressed_size;

    ec_point out(public_key_size);
    int out_size;

    if (secp256k1_ec_pubkey_create(signing_context, out.data(), &out_size,
        secret.data(), compressed) == 1)
    {
        BITCOIN_ASSERT_MSG(public_key_size == static_cast<size_t>(out_size),
            "secp256k1_ec_pubkey_create returned invalid size");
        return out;
    }

    return ec_point();
}

bool verify_public_key(const ec_point& public_key)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_pubkey_verify(verification_context, public_key.data(),
        static_cast<uint32_t>(public_key.size())) == 1;
}

bool verify_public_key_fast(const ec_point& public_key)
{
    if (public_key.size() == ec_compressed_size)
        return public_key[0] == 0x02 || public_key[0] == 0x03;
    if (public_key.size() == ec_uncompressed_size)
        return public_key[0] == 0x04;
    return false;
}

bool verify_private_key(const ec_secret& private_key)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_seckey_verify(verification_context, private_key.data())
        == 1;
}

endorsement sign(ec_secret secret, hash_digest hash)
{
    const auto signing_context = signing.context();
    int out_size = max_endorsement_size;
    endorsement signature(out_size);

    if (secp256k1_ecdsa_sign(signing_context, hash.data(), signature.data(),
        &out_size, secret.data(), secp256k1_nonce_function_rfc6979, nullptr)
        != 1)
    {
        BITCOIN_ASSERT_MSG(false, "secp256k1_ecdsa_sign failed");
        out_size = 0;
    };

    signature.resize(out_size);
    return signature;
}

compact_signature sign_compact(ec_secret secret, hash_digest hash)
{
    const auto signing_context = signing.context();
    compact_signature out;

    if (secp256k1_ecdsa_sign_compact(signing_context, hash.data(),
        out.signature.data(), secret.data(), secp256k1_nonce_function_rfc6979,
        nullptr, &out.recid) != 1)
    {
        BITCOIN_ASSERT_MSG(false, "secp256k1_ecdsa_sign_compact failed");
        return compact_signature();
    }

    return out;
}

bool verify_signature(const ec_point& public_key, hash_digest hash,
    const endorsement& signature)
{
    auto signing_context = verification.context();
    auto result = secp256k1_ecdsa_verify(signing_context, hash.data(),
        signature.data(),
        static_cast<uint32_t>(signature.size()), public_key.data(),
        static_cast<uint32_t>(public_key.size()));

    BITCOIN_ASSERT_MSG(result >= 0, "secp256k1_ecdsa_verify failed");

    return result == 1;
}

ec_point recover_compact(compact_signature signature, hash_digest hash,
    bool compressed)
{
    const auto verification_context = verification.context();
    size_t public_key_size = ec_uncompressed_size;
    if (compressed)
        public_key_size = ec_compressed_size;

    ec_point out(public_key_size);
    int out_size;

    if (secp256k1_ecdsa_recover_compact(verification_context, hash.data(),
        signature.signature.data(), out.data(), &out_size, compressed,
        signature.recid) == 1)
    {
        BITCOIN_ASSERT_MSG(public_key_size == static_cast<size_t>(out_size),
            "secp256k1_ecdsa_recover_compact returned invalid size");
        return out;
    }

    return ec_point();
}

bool ec_add(ec_point& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_pubkey_tweak_add(verification_context, a.data(),
        static_cast<uint32_t>(a.size()), b.data()) == 1;
}

bool ec_add(ec_secret& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_privkey_tweak_add(verification_context, a.data(),
        b.data()) == 1;
}

bool ec_multiply(ec_point& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_pubkey_tweak_mul(verification_context, a.data(),
        static_cast<uint32_t>(a.size()), b.data()) == 1;
}

bool ec_multiply(ec_secret& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_privkey_tweak_mul(verification_context, a.data(),
        b.data()) == 1;
}

///////////////////////////////////////////////////////////////////////////////
// DEPRECATED (now redundant with secp256k1 implementation)
///////////////////////////////////////////////////////////////////////////////
ec_secret create_nonce(ec_secret secret, hash_digest hash, uint32_t index)
{
    hash_digest K
    {{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    }};
    hash_digest V
    {{
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
    }};

    K = hmac_sha256_hash(build_data({V, to_byte(0x00), secret, hash}), K);
    V = hmac_sha256_hash(V, K);
    K = hmac_sha256_hash(build_data({V, to_byte(0x01), secret, hash}), K);
    V = hmac_sha256_hash(V, K);

    while (true)
    {
        V = hmac_sha256_hash(V, K);

        if (0 == index)
            return V;
        --index;

        K = hmac_sha256_hash(build_data({V, to_byte(0x00)}), K);
        V = hmac_sha256_hash(V, K);
    }
}

///////////////////////////////////////////////////////////////////////////////
// DEPRECATED (deterministic signatures are safer)
///////////////////////////////////////////////////////////////////////////////
endorsement sign(ec_secret secret, hash_digest hash, ec_secret /* nonce */)
{
    // THE CALLER'S NONCE IS IGNORED.
    return sign(secret, hash);
}

///////////////////////////////////////////////////////////////////////////////
// DEPRECATED (deterministic signatures are safer)
///////////////////////////////////////////////////////////////////////////////
compact_signature sign_compact(ec_secret secret, hash_digest hash,
    ec_secret /* nonce */)
{
    // THE CALLER'S NONCE IS IGNORED.
    return sign_compact(secret, hash);
}

} // namespace libbitcoin

<commit_msg>Refactor ec_keys init to hide libsecp256k1 internal flags.<commit_after>/*
 * Copyright (c) 2011-2014 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/math/ec_keys.hpp>

#include <algorithm>
#include <mutex>
#include <secp256k1.h>
#include <bitcoin/bitcoin/math/hash.hpp>
#include <bitcoin/bitcoin/utility/assert.hpp>
#include <bitcoin/bitcoin/utility/endian.hpp>

namespace libbitcoin {

// This class holds no static state but will only initialize its state once for
// the given mutex. This can be assigned to a static or otherwise. It lazily
// inits the context once and destroys the context on destruct as necessary.
class secp256k1_signing
{
private:
    static void set_context(secp256k1_context_t** context, bool signing)
    {
        int flag = signing ? SECP256K1_CONTEXT_SIGN : SECP256K1_CONTEXT_VERIFY;
        *context = secp256k1_context_create(flag);
    }

protected:
    bool signing_;

public:
    secp256k1_signing()
        : signing_(true), context_(nullptr)
    {
    }

    ~secp256k1_signing()
    {
        if (context_ != nullptr)
            secp256k1_context_destroy(context_);
    }

    secp256k1_context_t* context()
    {
        std::call_once(mutex_, set_context, &context_, signing_);
        return context_;
    }

private:
    std::once_flag mutex_;
    secp256k1_context_t* context_;
};

class secp256k1_verification
    : public secp256k1_signing
{
public:
    secp256k1_verification()
    {
        signing_ = false;
    }
};

// We do not share contexts because they may or may not both be required at
// some point and they can't be independently destroyed.
static secp256k1_signing signing;
static secp256k1_verification verification;

ec_point secret_to_public_key(const ec_secret& secret,
    bool compressed)
{
    const auto signing_context = signing.context();
    size_t public_key_size = ec_uncompressed_size;
    if (compressed)
        public_key_size = ec_compressed_size;

    ec_point out(public_key_size);
    int out_size;

    if (secp256k1_ec_pubkey_create(signing_context, out.data(), &out_size,
        secret.data(), compressed) == 1)
    {
        BITCOIN_ASSERT_MSG(public_key_size == static_cast<size_t>(out_size),
            "secp256k1_ec_pubkey_create returned invalid size");
        return out;
    }

    return ec_point();
}

bool verify_public_key(const ec_point& public_key)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_pubkey_verify(verification_context, public_key.data(),
        static_cast<uint32_t>(public_key.size())) == 1;
}

bool verify_public_key_fast(const ec_point& public_key)
{
    if (public_key.size() == ec_compressed_size)
        return public_key[0] == 0x02 || public_key[0] == 0x03;
    if (public_key.size() == ec_uncompressed_size)
        return public_key[0] == 0x04;
    return false;
}

bool verify_private_key(const ec_secret& private_key)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_seckey_verify(verification_context, private_key.data())
        == 1;
}

endorsement sign(ec_secret secret, hash_digest hash)
{
    const auto signing_context = signing.context();
    int out_size = max_endorsement_size;
    endorsement signature(out_size);

    if (secp256k1_ecdsa_sign(signing_context, hash.data(), signature.data(),
        &out_size, secret.data(), secp256k1_nonce_function_rfc6979, nullptr)
        != 1)
    {
        BITCOIN_ASSERT_MSG(false, "secp256k1_ecdsa_sign failed");
        out_size = 0;
    };

    signature.resize(out_size);
    return signature;
}

compact_signature sign_compact(ec_secret secret, hash_digest hash)
{
    const auto signing_context = signing.context();
    compact_signature out;

    if (secp256k1_ecdsa_sign_compact(signing_context, hash.data(),
        out.signature.data(), secret.data(), secp256k1_nonce_function_rfc6979,
        nullptr, &out.recid) != 1)
    {
        BITCOIN_ASSERT_MSG(false, "secp256k1_ecdsa_sign_compact failed");
        return compact_signature();
    }

    return out;
}

bool verify_signature(const ec_point& public_key, hash_digest hash,
    const endorsement& signature)
{
    auto signing_context = verification.context();
    auto result = secp256k1_ecdsa_verify(signing_context, hash.data(),
        signature.data(),
        static_cast<uint32_t>(signature.size()), public_key.data(),
        static_cast<uint32_t>(public_key.size()));

    BITCOIN_ASSERT_MSG(result >= 0, "secp256k1_ecdsa_verify failed");

    return result == 1;
}

ec_point recover_compact(compact_signature signature, hash_digest hash,
    bool compressed)
{
    const auto verification_context = verification.context();
    size_t public_key_size = ec_uncompressed_size;
    if (compressed)
        public_key_size = ec_compressed_size;

    ec_point out(public_key_size);
    int out_size;

    if (secp256k1_ecdsa_recover_compact(verification_context, hash.data(),
        signature.signature.data(), out.data(), &out_size, compressed,
        signature.recid) == 1)
    {
        BITCOIN_ASSERT_MSG(public_key_size == static_cast<size_t>(out_size),
            "secp256k1_ecdsa_recover_compact returned invalid size");
        return out;
    }

    return ec_point();
}

bool ec_add(ec_point& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_pubkey_tweak_add(verification_context, a.data(),
        static_cast<uint32_t>(a.size()), b.data()) == 1;
}

bool ec_add(ec_secret& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_privkey_tweak_add(verification_context, a.data(),
        b.data()) == 1;
}

bool ec_multiply(ec_point& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_pubkey_tweak_mul(verification_context, a.data(),
        static_cast<uint32_t>(a.size()), b.data()) == 1;
}

bool ec_multiply(ec_secret& a, const ec_secret& b)
{
    const auto verification_context = verification.context();
    return secp256k1_ec_privkey_tweak_mul(verification_context, a.data(),
        b.data()) == 1;
}

///////////////////////////////////////////////////////////////////////////////
// DEPRECATED (now redundant with secp256k1 implementation)
///////////////////////////////////////////////////////////////////////////////
ec_secret create_nonce(ec_secret secret, hash_digest hash, uint32_t index)
{
    hash_digest K
    {{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    }};
    hash_digest V
    {{
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
    }};

    K = hmac_sha256_hash(build_data({V, to_byte(0x00), secret, hash}), K);
    V = hmac_sha256_hash(V, K);
    K = hmac_sha256_hash(build_data({V, to_byte(0x01), secret, hash}), K);
    V = hmac_sha256_hash(V, K);

    while (true)
    {
        V = hmac_sha256_hash(V, K);

        if (0 == index)
            return V;
        --index;

        K = hmac_sha256_hash(build_data({V, to_byte(0x00)}), K);
        V = hmac_sha256_hash(V, K);
    }
}

///////////////////////////////////////////////////////////////////////////////
// DEPRECATED (deterministic signatures are safer)
///////////////////////////////////////////////////////////////////////////////
endorsement sign(ec_secret secret, hash_digest hash, ec_secret /* nonce */)
{
    // THE CALLER'S NONCE IS IGNORED.
    return sign(secret, hash);
}

///////////////////////////////////////////////////////////////////////////////
// DEPRECATED (deterministic signatures are safer)
///////////////////////////////////////////////////////////////////////////////
compact_signature sign_compact(ec_secret secret, hash_digest hash,
    ec_secret /* nonce */)
{
    // THE CALLER'S NONCE IS IGNORED.
    return sign_compact(secret, hash);
}

} // namespace libbitcoin

<|endoftext|>


<commit_before>// convex_hull_node.cpp
// Copyright 2014 Naohiro Hayashi <kaminuno@kaminuno-ThinkPad-T440p>
//ros
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <sensor_msgs/PointCloud2.h>
// PCL specific includes
#include <pcl/ros/conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
//std
#include <iostream>
#include <cmath>
//lis
#include <lis_msgs/PosesArray.h>
using namespace std;

class Convex_hull{
    private:
    ros::NodeHandle n;
    ros::Publisher pub;
    ros::Subscriber sub;

    public:
    Convex_hull(){
        pub = n.advertise<sensor_msgs::PointCloud2> ("output", 1);
        sub = n.subscribe("camera/depth/points", 1, &Convex_hull::cloud_cb, this);
    }

    void cloud_cb (const sensor_msgs::PointCloud2ConstPtr& cloud)
    {
          sensor_msgs::PointCloud2 cloud_filtered;

          // Perform the actual filtering
          pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
          sor.setInputCloud (cloud);
          sor.setLeafSize (0.03, 0.03, 0.03);
          sor.filter (cloud_filtered);

          // Publish the data
          pub.publish (cloud_filtered);
    }
};

int main(int argc, char **argv)
{
    ros::init(argc, argv, "convex_hull_node");

    cout << "Initializing node... " << endl;
    Convex_hull convex_hull;
    ros::spin();

    return 0;
}
<commit_msg>pcl_enjoy勢<commit_after>// convex_hull_node.cpp
// Copyright 2014 Naohiro Hayashi <kaminuno@kaminuno-ThinkPad-T440p>
//ros
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <sensor_msgs/PointCloud2.h>
// PCL specific includes
#include <pcl/ros/conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/project_inliers.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/surface/concave_hull.h>
//std
#include <iostream>
#include <cmath>
//lis
#include <lis_msgs/PosesArray.h>
using namespace std;

class Convex_hull{
    private:
    ros::NodeHandle n;
    ros::Publisher pub, pub2, pub3;
    ros::Subscriber sub;

    public:
    Convex_hull(){
        pub = n.advertise<sensor_msgs::PointCloud2> ("output", 1);
        pub2 = n.advertise<sensor_msgs::PointCloud2> ("output2", 1);
        pub3 = n.advertise<sensor_msgs::PointCloud2> ("output3", 1);
        sub = n.subscribe("camera/depth/points", 1, &Convex_hull::cloud_cb, this);

    }

    void cloud_cb (const sensor_msgs::PointCloud2ConstPtr& cloud)
    {
            sensor_msgs::PointCloud2 cloud_box, pub_data, pub_data3;
            pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected (new pcl::PointCloud<pcl::PointXYZ>);
            pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
            pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull (new pcl::PointCloud<pcl::PointXYZ>);
            pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_data (new pcl::PointCloud<pcl::PointXYZ>);
            pcl::ConcaveHull<pcl::PointXYZ> chull;
            //pcl::PointCloud<pcl::PointXYZ> cloud_data;
            // Perform the actual filtering
            pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
            sor.setInputCloud (cloud);
            sor.setLeafSize (0.1, 0.1, 0.1);
            sor.filter (cloud_box);
            pcl::fromROSMsg (cloud_box, *cloud_data);
            pub2.publish (cloud_box);

            pcl::PassThrough<pcl::PointXYZ> pass;
            pass.setInputCloud (cloud_data);
            pass.setFilterFieldName ("z");
            pass.setFilterLimits (0, 7.0);
            pass.filter (*cloud_filtered);
            std::cerr << "PointCloud after filtering has: " << cloud_filtered->points.size () << " data points." << std::endl;
            pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
            pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
            // Create the segmentation object
            pcl::SACSegmentation<pcl::PointXYZ> seg;
            // Optional
            seg.setOptimizeCoefficients (true);
            // Mandatory
            seg.setModelType (pcl::SACMODEL_PLANE);
            seg.setMethodType (pcl::SAC_RANSAC);
            seg.setDistanceThreshold (0.01);

            seg.setInputCloud (cloud_filtered);
            seg.segment (*inliers, *coefficients);
            std::cerr << "PointCloud after segmentation has: " << inliers->indices.size () << " inliers." << std::endl;

            // Project the model inliers
            pcl::ProjectInliers<pcl::PointXYZ> proj;
            proj.setModelType (pcl::SACMODEL_PLANE);
            proj.setIndices (inliers);
            proj.setInputCloud (cloud_filtered);
            proj.setModelCoefficients (coefficients);
            proj.filter (*cloud_projected);
            std::cerr << "PointCloud after projection has: " << cloud_projected->points.size () << " data points." << std::endl;
            pcl::toROSMsg (*cloud_projected, pub_data3);
            pub3.publish (pub_data3);

            // Create a Concave Hull representation of the projected inliers
            chull.setInputCloud (cloud_projected);
            chull.setAlpha (0.1);
            chull.reconstruct (*cloud_hull);
            pcl::toROSMsg (*cloud_hull, pub_data);
            // Publish the data
            pub.publish (pub_data);
    }
};

int main(int argc, char **argv)
{
    ros::init(argc, argv, "convex_hull_node");

    cout << "Initializing node... " << endl;
    Convex_hull convex_hull;
    ros::spin();

    return 0;
}
<|endoftext|>