<commit_before>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "ThumbnailerWorker.h"

#include "Media.h"
#include "File.h"
#include "Folder.h"
#include "logging/Logger.h"
#include "MediaLibrary.h"
#include "utils/ModificationsNotifier.h"
#include "utils/Filename.h"

#include <algorithm>

namespace medialibrary
{

ThumbnailerWorker::ThumbnailerWorker( MediaLibraryPtr ml,
                                      std::shared_ptr<IThumbnailer> thumbnailer )
    : m_ml( ml )
    , m_run( false )
    , m_generator( std::move( thumbnailer ) )
    , m_paused( false )
{
}

ThumbnailerWorker::~ThumbnailerWorker()
{
    stop();
}

void ThumbnailerWorker::requestThumbnail( MediaPtr media )
{
    std::unique_lock<compat::Mutex> lock( m_mutex );

    m_tasks.push( std::move( media ) );
    if ( m_thread.get_id() == compat::Thread::id{} )
    {
        m_run = true;
        m_thread = compat::Thread( &ThumbnailerWorker::run, this );
    }
    else
        m_cond.notify_all();
}

void ThumbnailerWorker::pause()
{
    std::lock_guard<compat::Mutex> lock( m_mutex );
    m_paused = true;
}

void ThumbnailerWorker::resume()
{
    std::lock_guard<compat::Mutex> lock( m_mutex );
    if ( m_paused == false )
        return;
    m_paused = false;
    m_cond.notify_all();
}

void ThumbnailerWorker::run()
{
    LOG_INFO( "Starting thumbnailer thread" );
    while ( m_run == true )
    {
        MediaPtr media;
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            if ( m_tasks.size() == 0 || m_paused == true )
            {
                m_cond.wait( lock, [this]() {
                    return ( m_tasks.size() > 0 && m_paused == false ) ||
                            m_run == false;
                });
                if ( m_run == false )
                    break;
            }
            media = std::move( m_tasks.front() );
            m_tasks.pop();
        }
        if ( media->isThumbnailGenerated() == true )
        {
            LOG_INFO( "Skipping thumbnail generation of a media with a thumbnail ", media->fileName() );
            m_ml->getCb()->onMediaThumbnailReady( media, media->thumbnailMrl().empty() == false );
            continue;
        }
        bool res = generateThumbnail( media );
        if ( res == false )
        {
            auto m = static_cast<Media*>( media.get() );
            m->setThumbnail( "", Thumbnail::Origin::Media, true );
        }
        m_ml->getCb()->onMediaThumbnailReady( media, res );
    }
    LOG_INFO( "Exiting thumbnailer thread" );
}

void ThumbnailerWorker::stop()
{
    bool running = true;
    if ( m_run.compare_exchange_strong( running, false ) )
    {
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            while ( m_tasks.empty() == false )
                m_tasks.pop();
        }
        m_cond.notify_all();
        m_thread.join();
    }
}

bool ThumbnailerWorker::generateThumbnail( MediaPtr media )
{
    assert( media->type() != Media::Type::Audio );

    const auto files = media->files();
    if ( files.empty() == true )
    {
        LOG_WARN( "Can't generate thumbnail for a media without associated files (",
                  media->title() );
        return false;
    }
    auto mainFileIt = std::find_if( files.cbegin(), files.cend(),
                                    [](FilePtr f) {
                                        return f->isMain();
                                   });
    assert( mainFileIt != files.cend() );
    auto file = std::static_pointer_cast<File>( *mainFileIt );
    std::string mrl;
    try
    {
        mrl = file->mrl();
    }
    catch ( const fs::DeviceRemovedException& )
    {
        LOG_WARN( "Aborting file ", file->rawMrl(), " generation due to its "
                  "containing device being missing" );
        return false;
    }

    auto dest = Thumbnail::pathForMedia( m_ml, media->id() );
    LOG_DEBUG( "Generating ", mrl, " thumbnail in ", dest );
    auto m = static_cast<Media*>( media.get() );
    if ( m_generator->generate( media, mrl, dest ) == false )
        return false;

    auto destMrl = utils::file::toMrl( dest );
    if ( m->setThumbnail( destMrl, Thumbnail::Origin::Media, true ) == false )
        return false;

    m_ml->getNotifier()->notifyMediaModification( media );
    return true;
}

}
<commit_msg>Thumbnailer: Don't retry thumbnail generations<commit_after>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "ThumbnailerWorker.h"

#include "Media.h"
#include "File.h"
#include "Folder.h"
#include "logging/Logger.h"
#include "MediaLibrary.h"
#include "utils/ModificationsNotifier.h"
#include "utils/Filename.h"

#include <algorithm>

namespace medialibrary
{

ThumbnailerWorker::ThumbnailerWorker( MediaLibraryPtr ml,
                                      std::shared_ptr<IThumbnailer> thumbnailer )
    : m_ml( ml )
    , m_run( false )
    , m_generator( std::move( thumbnailer ) )
    , m_paused( false )
{
}

ThumbnailerWorker::~ThumbnailerWorker()
{
    stop();
}

void ThumbnailerWorker::requestThumbnail( MediaPtr media )
{
    std::unique_lock<compat::Mutex> lock( m_mutex );

    m_tasks.push( std::move( media ) );
    if ( m_thread.get_id() == compat::Thread::id{} )
    {
        m_run = true;
        m_thread = compat::Thread( &ThumbnailerWorker::run, this );
    }
    else
        m_cond.notify_all();
}

void ThumbnailerWorker::pause()
{
    std::lock_guard<compat::Mutex> lock( m_mutex );
    m_paused = true;
}

void ThumbnailerWorker::resume()
{
    std::lock_guard<compat::Mutex> lock( m_mutex );
    if ( m_paused == false )
        return;
    m_paused = false;
    m_cond.notify_all();
}

void ThumbnailerWorker::run()
{
    LOG_INFO( "Starting thumbnailer thread" );
    while ( m_run == true )
    {
        MediaPtr media;
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            if ( m_tasks.size() == 0 || m_paused == true )
            {
                m_cond.wait( lock, [this]() {
                    return ( m_tasks.size() > 0 && m_paused == false ) ||
                            m_run == false;
                });
                if ( m_run == false )
                    break;
            }
            media = std::move( m_tasks.front() );
            m_tasks.pop();
        }
        if ( media->isThumbnailGenerated() == true )
        {
            LOG_INFO( "Skipping thumbnail generation of a media with a thumbnail ", media->fileName() );
            m_ml->getCb()->onMediaThumbnailReady( media, media->thumbnailMrl().empty() == false );
            continue;
        }
        bool res = generateThumbnail( media );
        m_ml->getCb()->onMediaThumbnailReady( media, res );
    }
    LOG_INFO( "Exiting thumbnailer thread" );
}

void ThumbnailerWorker::stop()
{
    bool running = true;
    if ( m_run.compare_exchange_strong( running, false ) )
    {
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            while ( m_tasks.empty() == false )
                m_tasks.pop();
        }
        m_cond.notify_all();
        m_thread.join();
    }
}

bool ThumbnailerWorker::generateThumbnail( MediaPtr media )
{
    assert( media->type() != Media::Type::Audio );

    const auto files = media->files();
    if ( files.empty() == true )
    {
        LOG_WARN( "Can't generate thumbnail for a media without associated files (",
                  media->title() );
        return false;
    }
    auto mainFileIt = std::find_if( files.cbegin(), files.cend(),
                                    [](FilePtr f) {
                                        return f->isMain();
                                   });
    assert( mainFileIt != files.cend() );
    auto file = std::static_pointer_cast<File>( *mainFileIt );
    std::string mrl;
    try
    {
        mrl = file->mrl();
    }
    catch ( const fs::DeviceRemovedException& )
    {
        LOG_WARN( "Aborting file ", file->rawMrl(), " generation due to its "
                  "containing device being missing" );
        return false;
    }

    auto dest = Thumbnail::pathForMedia( m_ml, media->id() );
    LOG_DEBUG( "Generating ", mrl, " thumbnail in ", dest );
    auto m = static_cast<Media*>( media.get() );
    /*
     * Insert a failure record before computing the thumbnail.
     * If the thumbnailer crashes, we don't want to re-run it. If it succeeds,
     * the thumbnail will be updated right after
     * This is done here instead of from the mainloop as we don't want to prevent
     * the thumbnail generation of a file that has been removed.
     */
    m->setThumbnail( "", Thumbnail::Origin::Media, true );

    if ( m_generator->generate( media, mrl, dest ) == false )
        return false;

    auto destMrl = utils::file::toMrl( dest );
    if ( m->setThumbnail( destMrl, Thumbnail::Origin::Media, true ) == false )
        return false;

    m_ml->getNotifier()->notifyMediaModification( media );
    return true;
}

}
<|endoftext|>


<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "PatternedMesh.h"
#include "Parser.h"
#include "InputParameters.h"

// libMesh includes
#include "libmesh/mesh_modification.h"
#include "libmesh/serial_mesh.h"
#include "libmesh/exodusII_io.h"

template<>
InputParameters validParams<PatternedMesh>()
{
  InputParameters params = validParams<MooseMesh>();
  params.addRequiredParam<std::vector<MeshFileName> >("files", "The name of the mesh files to read.  They are automatically assigned ids starting with zero.");

  params.addRangeCheckedParam<Real>("x_width", 0, "x_width>=0", "The tile width in the x direction");
  params.addRangeCheckedParam<Real>("y_width", 0, "y_width>=0", "The tile width in the y direction");
  params.addRangeCheckedParam<Real>("z_width", 0, "z_width>=0", "The tile width in the z direction");

  // x boundary names
  params.addParam<BoundaryName>("left_boundary", "left_boundary", "name of the left (x) boundary");
  params.addParam<BoundaryName>("right_boundary", "right_boundary", "name of the right (x) boundary");

  // y boundary names
  params.addParam<BoundaryName>("top_boundary", "top_boundary", "name of the top (y) boundary");
  params.addParam<BoundaryName>("bottom_boundary", "bottom_boundary", "name of the bottom (y) boundary");

  // z boundary names
  params.addParam<BoundaryName>("front_boundary", "front_boundary", "name of the front (z) boundary");
  params.addParam<BoundaryName>("back_boundary", "back_boundary", "name of the back (z) boundary");

  params.addRequiredParam<std::vector<std::vector<unsigned int> > >("pattern", "A double-indexed array starting with the upper-left corner");

  params.addClassDescription("Creates a 2D mesh from a specified set of unique 'tiles' meshes and a two-dimensional pattern.");

  return params;
}

PatternedMesh::PatternedMesh(const InputParameters & parameters) :
    MooseMesh(parameters),
    _files(getParam<std::vector<MeshFileName> >("files")),
    _pattern(getParam<std::vector<std::vector<unsigned int> > >("pattern")),
    _x_width(getParam<Real>("x_width")),
    _y_width(getParam<Real>("y_width")),
    _z_width(getParam<Real>("z_width"))
{
  // The PatternedMesh class only works with SerialMesh
  errorIfParallelDistribution("PatternedMesh");

  _meshes.resize(_files.size());

  // Read in all of the meshes
  for (unsigned int i = 0; i < _files.size(); i++)
  {
    SerialMesh * mesh = new SerialMesh(_communicator);
    mesh->read(_files[i]);

    _meshes[i] = mesh;
  }

  _row_meshes.resize(_pattern.size());

  // The zeroth row (which is the top row) will be the real mesh
  _row_meshes[0] = dynamic_cast<SerialMesh*>( &getMesh() );

  // Create a mesh for all the other rows
  for (unsigned int i = 1; i < _pattern.size(); i++)
  {
    SerialMesh * mesh = new SerialMesh(_communicator);
    _row_meshes[i] = mesh;
  }
}

PatternedMesh::PatternedMesh(const PatternedMesh & other_mesh) :
    MooseMesh(other_mesh),
    _files(other_mesh._files),
    _pattern(other_mesh._pattern),
    _x_width(other_mesh._x_width),
    _y_width(other_mesh._y_width),
    _z_width(other_mesh._z_width)
{
}

PatternedMesh::~PatternedMesh()
{
  // Clean up the mesh we made (see what I did there?)
  for (unsigned int i = 0; i < _meshes.size(); i++)
    delete _meshes[i];

  // Don't delete the first row - it is the real mesh - it will be cleaned up later
  for (unsigned int i = 1; i < _meshes.size(); i++)
    delete _row_meshes[i];
}

MooseMesh &
PatternedMesh::clone() const
{
  return *(new PatternedMesh(*this));
}

void
PatternedMesh::buildMesh()
{
  // stitch_meshes() is only implemented for SerialMesh.  So make sure
  // we have one here before continuing.
  SerialMesh* the_mesh = dynamic_cast<SerialMesh*>( &getMesh() );

  if (!the_mesh)
    mooseError("Error, PatternedMesh calls stitch_meshes() which only works on SerialMesh.");
  else
  {
    BoundaryID left = getBoundaryID(getParam<BoundaryName>("left_boundary"));
    BoundaryID right = getBoundaryID(getParam<BoundaryName>("right_boundary"));
    BoundaryID top = getBoundaryID(getParam<BoundaryName>("top_boundary"));
    BoundaryID bottom = getBoundaryID(getParam<BoundaryName>("bottom_boundary"));
    BoundaryID front = getBoundaryID(getParam<BoundaryName>("front_boundary"));
    BoundaryID back = getBoundaryID(getParam<BoundaryName>("back_boundary"));

    // Build each row mesh
    for (int i = 0; i < _pattern.size(); i++)
    {
      for (int j = 0; j < _pattern[i].size(); j++)
      {
        // If this is the first cell of the row initialize the row mesh
        if (j == 0)
        {
          _row_meshes[i]->read(_files[_pattern[i][j]]);

          MeshTools::Modification::translate(*_row_meshes[i], j*_x_width, -i*_y_width, 0);

          continue;
        }

        SerialMesh & cell_mesh = *_meshes[_pattern[i][j]];

        // Move the mesh into the right spot.  -i because we are starting at the top
        MeshTools::Modification::translate(cell_mesh, j*_x_width, -i*_y_width, 0);

        _row_meshes[i]->stitch_meshes(dynamic_cast<SerialMesh &>(cell_mesh), right, left, TOLERANCE, /*clear_stitched_boundary_ids=*/true);

        // Undo the translation
        MeshTools::Modification::translate(cell_mesh, -j*_x_width, i*_y_width, 0);
      }
    }

    // Now stitch together the rows
    // We're going to stitch them all to row 0 (which is the real mesh)
    for (int i = 1; i < _pattern.size(); i++)
      _row_meshes[0]->stitch_meshes(*_row_meshes[i], bottom, top, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
  }
}
<commit_msg>Make sure all _row_meshes are deleted.<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "PatternedMesh.h"
#include "Parser.h"
#include "InputParameters.h"

// libMesh includes
#include "libmesh/mesh_modification.h"
#include "libmesh/serial_mesh.h"
#include "libmesh/exodusII_io.h"

template<>
InputParameters validParams<PatternedMesh>()
{
  InputParameters params = validParams<MooseMesh>();
  params.addRequiredParam<std::vector<MeshFileName> >("files", "The name of the mesh files to read.  They are automatically assigned ids starting with zero.");

  params.addRangeCheckedParam<Real>("x_width", 0, "x_width>=0", "The tile width in the x direction");
  params.addRangeCheckedParam<Real>("y_width", 0, "y_width>=0", "The tile width in the y direction");
  params.addRangeCheckedParam<Real>("z_width", 0, "z_width>=0", "The tile width in the z direction");

  // x boundary names
  params.addParam<BoundaryName>("left_boundary", "left_boundary", "name of the left (x) boundary");
  params.addParam<BoundaryName>("right_boundary", "right_boundary", "name of the right (x) boundary");

  // y boundary names
  params.addParam<BoundaryName>("top_boundary", "top_boundary", "name of the top (y) boundary");
  params.addParam<BoundaryName>("bottom_boundary", "bottom_boundary", "name of the bottom (y) boundary");

  // z boundary names
  params.addParam<BoundaryName>("front_boundary", "front_boundary", "name of the front (z) boundary");
  params.addParam<BoundaryName>("back_boundary", "back_boundary", "name of the back (z) boundary");

  params.addRequiredParam<std::vector<std::vector<unsigned int> > >("pattern", "A double-indexed array starting with the upper-left corner");

  params.addClassDescription("Creates a 2D mesh from a specified set of unique 'tiles' meshes and a two-dimensional pattern.");

  return params;
}

PatternedMesh::PatternedMesh(const InputParameters & parameters) :
    MooseMesh(parameters),
    _files(getParam<std::vector<MeshFileName> >("files")),
    _pattern(getParam<std::vector<std::vector<unsigned int> > >("pattern")),
    _x_width(getParam<Real>("x_width")),
    _y_width(getParam<Real>("y_width")),
    _z_width(getParam<Real>("z_width"))
{
  // The PatternedMesh class only works with SerialMesh
  errorIfParallelDistribution("PatternedMesh");

  _meshes.resize(_files.size());

  // Read in all of the meshes
  for (unsigned int i = 0; i < _files.size(); i++)
  {
    SerialMesh * mesh = new SerialMesh(_communicator);
    mesh->read(_files[i]);

    _meshes[i] = mesh;
  }

  _row_meshes.resize(_pattern.size());

  // The zeroth row (which is the top row) will be the real mesh
  _row_meshes[0] = dynamic_cast<SerialMesh*>( &getMesh() );

  // Create a mesh for all the other rows
  for (unsigned int i = 1; i < _pattern.size(); i++)
  {
    SerialMesh * mesh = new SerialMesh(_communicator);
    _row_meshes[i] = mesh;
  }
}

PatternedMesh::PatternedMesh(const PatternedMesh & other_mesh) :
    MooseMesh(other_mesh),
    _files(other_mesh._files),
    _pattern(other_mesh._pattern),
    _x_width(other_mesh._x_width),
    _y_width(other_mesh._y_width),
    _z_width(other_mesh._z_width)
{
}

PatternedMesh::~PatternedMesh()
{
  // Clean up the mesh we made (see what I did there?)
  for (unsigned int i = 0; i < _meshes.size(); i++)
    delete _meshes[i];

  // Don't delete the first row - it is the real mesh - it will be cleaned up later
  for (unsigned int i = 1; i < _row_meshes.size(); i++)
    delete _row_meshes[i];
}

MooseMesh &
PatternedMesh::clone() const
{
  return *(new PatternedMesh(*this));
}

void
PatternedMesh::buildMesh()
{
  // stitch_meshes() is only implemented for SerialMesh.  So make sure
  // we have one here before continuing.
  SerialMesh* the_mesh = dynamic_cast<SerialMesh*>( &getMesh() );

  if (!the_mesh)
    mooseError("Error, PatternedMesh calls stitch_meshes() which only works on SerialMesh.");
  else
  {
    BoundaryID left = getBoundaryID(getParam<BoundaryName>("left_boundary"));
    BoundaryID right = getBoundaryID(getParam<BoundaryName>("right_boundary"));
    BoundaryID top = getBoundaryID(getParam<BoundaryName>("top_boundary"));
    BoundaryID bottom = getBoundaryID(getParam<BoundaryName>("bottom_boundary"));
    BoundaryID front = getBoundaryID(getParam<BoundaryName>("front_boundary"));
    BoundaryID back = getBoundaryID(getParam<BoundaryName>("back_boundary"));

    // Build each row mesh
    for (int i = 0; i < _pattern.size(); i++)
    {
      for (int j = 0; j < _pattern[i].size(); j++)
      {
        // If this is the first cell of the row initialize the row mesh
        if (j == 0)
        {
          _row_meshes[i]->read(_files[_pattern[i][j]]);

          MeshTools::Modification::translate(*_row_meshes[i], j*_x_width, -i*_y_width, 0);

          continue;
        }

        SerialMesh & cell_mesh = *_meshes[_pattern[i][j]];

        // Move the mesh into the right spot.  -i because we are starting at the top
        MeshTools::Modification::translate(cell_mesh, j*_x_width, -i*_y_width, 0);

        _row_meshes[i]->stitch_meshes(dynamic_cast<SerialMesh &>(cell_mesh), right, left, TOLERANCE, /*clear_stitched_boundary_ids=*/true);

        // Undo the translation
        MeshTools::Modification::translate(cell_mesh, -j*_x_width, i*_y_width, 0);
      }
    }

    // Now stitch together the rows
    // We're going to stitch them all to row 0 (which is the real mesh)
    for (int i = 1; i < _pattern.size(); i++)
      _row_meshes[0]->stitch_meshes(*_row_meshes[i], bottom, top, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
  }
}
<|endoftext|>


<commit_before>/****************************************************************************
** Meta object code from reading C++ file 'multilauemain.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.7.0)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#include "../MultiLaueGUI/multilauemain.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'multilauemain.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.7.0. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

QT_BEGIN_MOC_NAMESPACE
struct qt_meta_stringdata_MultiLaueMain_t {
    QByteArrayData data[1];
    char stringdata0[14];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
    qptrdiff(offsetof(qt_meta_stringdata_MultiLaueMain_t, stringdata0) + ofs \
        - idx * sizeof(QByteArrayData)) \
    )
static const qt_meta_stringdata_MultiLaueMain_t qt_meta_stringdata_MultiLaueMain = {
    {
QT_MOC_LITERAL(0, 0, 13) // "MultiLaueMain"

    },
    "MultiLaueMain"
};
#undef QT_MOC_LITERAL

static const uint qt_meta_data_MultiLaueMain[] = {

 // content:
       7,       // revision
       0,       // classname
       0,    0, // classinfo
       0,    0, // methods
       0,    0, // properties
       0,    0, // enums/sets
       0,    0, // constructors
       0,       // flags
       0,       // signalCount

       0        // eod
};

void MultiLaueMain::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    Q_UNUSED(_o);
    Q_UNUSED(_id);
    Q_UNUSED(_c);
    Q_UNUSED(_a);
}

const QMetaObject MultiLaueMain::staticMetaObject = {
    { &QMainWindow::staticMetaObject, qt_meta_stringdata_MultiLaueMain.data,
      qt_meta_data_MultiLaueMain,  qt_static_metacall, Q_NULLPTR, Q_NULLPTR}
};

const QMetaObject *MultiLaueMain::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}

void *MultiLaueMain::qt_metacast(const char *_clname)
{
    if (!_clname) return Q_NULLPTR;
    if (!strcmp(_clname, qt_meta_stringdata_MultiLaueMain.stringdata0))
        return static_cast<void*>(const_cast< MultiLaueMain*>(this));
    return QMainWindow::qt_metacast(_clname);
}

int MultiLaueMain::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QMainWindow::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    return _id;
}
QT_END_MOC_NAMESPACE
<commit_msg>Delete moc_multilauemain.cpp<commit_after><|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#if     qPlatform_Windows
#include    <Windows.h>
#endif

#include    "../../../Foundation/Characters/Format.h"
#include    "../../../Foundation/Characters/Tokenize.h"
#include    "../../../Foundation/Containers/Sequence.h"
#include    "../../../Foundation/Debug/Assertions.h"
#include    "../../../Foundation/Execution/ProcessRunner.h"
#include    "../../../Foundation/Streams/BasicBinaryInputOutputStream.h"
#include    "../../../Foundation/Streams/TextInputStreamBinaryAdapter.h"

#include    "../CommonMeasurementTypes.h"

#include    "MountedFilesystemUsage.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::SystemPerformance;

namespace {
    struct VolumeInfo_ {
        String  fFileSystemType;
        String  fDeviceOrVolumeName;
        String  fVolumeID;
        String  fMountedOnName;
        Optional<double>    fDiskSizeInBytes;
        Optional<double>    fUsedSizeInBytes;
    };
}

namespace {
#if     qPlatform_Windows
    Sequence<VolumeInfo_> capture_ ()
    {
        Sequence<VolumeInfo_>   result;
        TCHAR volumeNameBuf[1024];
        for (HANDLE hVol = FindFirstVolume (volumeNameBuf, NEltsOf(volumeNameBuf)); hVol != INVALID_HANDLE_VALUE; ) {
            DWORD lpMaximumComponentLength;
            DWORD dwSysFlags;
            TCHAR FileSysNameBuf[1024];
            if (::GetVolumeInformation( volumeNameBuf, NULL, NEltsOf(volumeNameBuf), NULL, &lpMaximumComponentLength, &dwSysFlags, FileSysNameBuf, NEltsOf(FileSysNameBuf))) {
                VolumeInfo_ v;
                v.fFileSystemType = String::FromSDKString (FileSysNameBuf);
                v.fVolumeID = String::FromSDKString (volumeNameBuf);
                {
                    // @todo - use
                    //      http://msdn.microsoft.com/en-us/library/windows/desktop/cc542456(v=vs.85).aspx
                    //      CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));
                    //      to get DEVICENAME
                    //
                    TCHAR volPathsBuf[1024];
                    DWORD retLen = 0;
                    DWORD x = GetVolumePathNamesForVolumeName (volumeNameBuf, volPathsBuf, NEltsOf(volPathsBuf), &retLen);
                    if (volPathsBuf[0] == 0) {
                        v.fMountedOnName.clear ();
                        result.push_back (v);
                    }
                    else {
                        for (const TCHAR* NameIdx = volPathsBuf; NameIdx[0] != L'\0'; NameIdx += wcslen(NameIdx) + 1) {
                            v.fMountedOnName = String::FromSDKString (NameIdx);
                            {
                                ULARGE_INTEGER freeBytesAvailable;
                                ULARGE_INTEGER totalNumberOfBytes;
                                ULARGE_INTEGER totalNumberOfFreeBytes;
                                memset (&freeBytesAvailable, 0, sizeof (freeBytesAvailable));
                                memset (&totalNumberOfBytes, 0, sizeof (totalNumberOfBytes));
                                memset (&totalNumberOfFreeBytes, 0, sizeof (totalNumberOfFreeBytes));
                                DWORD xxx = GetDiskFreeSpaceEx (v.fMountedOnName.c_str (), &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes);
                                v.fDiskSizeInBytes = static_cast<double> (totalNumberOfBytes.QuadPart);
                                v.fUsedSizeInBytes = *v.fDiskSizeInBytes  - freeBytesAvailable.QuadPart;
                            }
                            result.push_back (v);
                        }
                    }
                }
            }
            else {
                // warning...
            }

            // find next
            if (not ::FindNextVolume (hVol, volumeNameBuf, NEltsOf(volumeNameBuf))) {
                FindVolumeClose (hVol);
                hVol = INVALID_HANDLE_VALUE;
            }
        }
        return result;
    }
#elif   qPlatform_POSIX
    Sequence<VolumeInfo_> capture_ ()
    {
        // I looked through the /proc filesystem stuff and didnt see anything obvious to retrive this info...
        // run def with ProcessRunner
        Sequence<VolumeInfo_>   result;
        ProcessRunner pr (SDKSTR ("/bin/df"));
#if 1
        Streams::BasicBinaryInputOutputStream   useStdOut;
        pr.SetStdOut (useStdOut);
        pr.Run ();
        String out;
        Streams::TextInputStreamBinaryAdapter   stdOut  =   Streams::TextInputStreamBinaryAdapter (useStdOut);
        bool skippedHeader = false;
        for (String i = stdOut.ReadLine (); not i.empty (); i = stdOut.ReadLine ()) {
            if (not skippedHeader) {
                skippedHeader = true;
                continue;
            }
            Sequence<String>    l    =  Characters::Tokenize<String> (i, L" ");
            if (l.size () < 6) {
                DbgTrace ("skipping line cuz len=%d", l.size ());
                continue;
            }
            VolumeInfo_ v;
            v.fMountedOnName = l[5];
            v.fDeviceOrVolumeName = l[0];
            v.fDiskSizeInBytes = Characters::String2Float (l[1]) * 1024;
            v.fUsedSizeInBytes = Characters::String2Float (l[2]) * 1024;
            result.Append (v);
        }

        //String out =  stdOut.ReadAll ();
        // redo with a bunch of readlines
#else
        String out = pr.Run (L"");
#endif
#if 0
        VolumeInfo_ foo;
        foo.fMountedOnName = out;
        result.Append (foo);    //tmphack to test
#endif
        return result;
    }
#endif
}

/*
 ********************************************************************************
 ***************** Instruments::GetMountedFilesystemUsage ***********************
 ********************************************************************************
 */
Instrument  SystemPerformance::Instruments::GetMountedFilesystemUsage ()
{
    static  Instrument  kInstrument_    = Instrument (
            InstrumentNameType (L"Mounted-Filesystem-Usage"),
    [] () -> Measurements {
        Measurements    results;
        DateTime    before = DateTime::Now ();
        Sequence<VolumeInfo_> volumes   =   capture_ ();
        results.fMeasuredAt = DateTimeRange (before, DateTime::Now ());
        Sequence<VariantValue>  volumnesAsVariants;
        for (VolumeInfo_ v : volumes)
        {
            Mapping<String, VariantValue> vv;
            vv.Add (L"Filesystem-Type", v.fFileSystemType);
            if (not v.fDeviceOrVolumeName.empty ()) {
                vv.Add (L"Device-Name", v.fDeviceOrVolumeName);
            }
            vv.Add (L"Volume-ID", v.fVolumeID);
            vv.Add (L"Mounted-On", v.fMountedOnName);
            if (v.fDiskSizeInBytes.IsPresent ()) {
                vv.Add (L"Disk-Size", *v.fDiskSizeInBytes);
            }
            if (v.fUsedSizeInBytes.IsPresent ()) {
                vv.Add (L"Disk-Used-Size", *v.fUsedSizeInBytes);
            }
            volumnesAsVariants.Append (VariantValue (vv));
        }
        Measurement m;
        m.fValue = volumnesAsVariants;
        m.fType = kMountedVolumeUsage;
        results.fMeasurements.Add (m);
        return results;
    },
    {kMountedVolumeUsage}
                                          );
    return kInstrument_;
}
<commit_msg>cleanups to /SystemPerformance/Instruments/MountedFilesystemUsage<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#if     qPlatform_Windows
#include    <Windows.h>
#endif

#include    "../../../Foundation/Characters/Format.h"
#include    "../../../Foundation/Characters/Tokenize.h"
#include    "../../../Foundation/Containers/Sequence.h"
#include    "../../../Foundation/Debug/Assertions.h"
#include    "../../../Foundation/Execution/ProcessRunner.h"
#include    "../../../Foundation/Streams/BasicBinaryInputOutputStream.h"
#include    "../../../Foundation/Streams/TextInputStreamBinaryAdapter.h"

#include    "../CommonMeasurementTypes.h"

#include    "MountedFilesystemUsage.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::SystemPerformance;

namespace {
    struct VolumeInfo_ {
        String  fFileSystemType;
        String  fDeviceOrVolumeName;
        String  fVolumeID;
        String  fMountedOnName;
        Optional<double>    fDiskSizeInBytes;
        Optional<double>    fUsedSizeInBytes;
    };
}

namespace {
#if     qPlatform_Windows
    Sequence<VolumeInfo_> capture_ ()
    {
        Sequence<VolumeInfo_>   result;
        TCHAR volumeNameBuf[1024];
        for (HANDLE hVol = FindFirstVolume (volumeNameBuf, NEltsOf(volumeNameBuf)); hVol != INVALID_HANDLE_VALUE; ) {
            DWORD lpMaximumComponentLength;
            DWORD dwSysFlags;
            TCHAR FileSysNameBuf[1024];
            if (::GetVolumeInformation( volumeNameBuf, NULL, NEltsOf(volumeNameBuf), NULL, &lpMaximumComponentLength, &dwSysFlags, FileSysNameBuf, NEltsOf(FileSysNameBuf))) {
                VolumeInfo_ v;
                v.fFileSystemType = String::FromSDKString (FileSysNameBuf);
                v.fVolumeID = String::FromSDKString (volumeNameBuf);
                {
                    // @todo - use
                    //      http://msdn.microsoft.com/en-us/library/windows/desktop/cc542456(v=vs.85).aspx
                    //      CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));
                    //      to get DEVICENAME
                    //
                    TCHAR volPathsBuf[1024];
                    DWORD retLen = 0;
                    DWORD x = GetVolumePathNamesForVolumeName (volumeNameBuf, volPathsBuf, NEltsOf(volPathsBuf), &retLen);
                    if (volPathsBuf[0] == 0) {
                        v.fMountedOnName.clear ();
                        result.push_back (v);
                    }
                    else {
                        for (const TCHAR* NameIdx = volPathsBuf; NameIdx[0] != L'\0'; NameIdx += wcslen(NameIdx) + 1) {
                            v.fMountedOnName = String::FromSDKString (NameIdx);
                            {
                                ULARGE_INTEGER freeBytesAvailable;
                                ULARGE_INTEGER totalNumberOfBytes;
                                ULARGE_INTEGER totalNumberOfFreeBytes;
                                memset (&freeBytesAvailable, 0, sizeof (freeBytesAvailable));
                                memset (&totalNumberOfBytes, 0, sizeof (totalNumberOfBytes));
                                memset (&totalNumberOfFreeBytes, 0, sizeof (totalNumberOfFreeBytes));
                                DWORD xxx = GetDiskFreeSpaceEx (v.fMountedOnName.c_str (), &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes);
                                v.fDiskSizeInBytes = static_cast<double> (totalNumberOfBytes.QuadPart);
                                v.fUsedSizeInBytes = *v.fDiskSizeInBytes  - freeBytesAvailable.QuadPart;
                            }
                            result.push_back (v);
                        }
                    }
                }
            }
            else {
                // warning...
            }

            // find next
            if (not ::FindNextVolume (hVol, volumeNameBuf, NEltsOf(volumeNameBuf))) {
                FindVolumeClose (hVol);
                hVol = INVALID_HANDLE_VALUE;
            }
        }
        return result;
    }
#elif   qPlatform_POSIX
    Sequence<VolumeInfo_> capture_ ()
    {
        // I looked through the /proc filesystem stuff and didnt see anything obvious to retrive this info...
        // run def with ProcessRunner
        Sequence<VolumeInfo_>   result;
        ProcessRunner pr (SDKSTR ("/bin/df"));
        Streams::BasicBinaryInputOutputStream   useStdOut;
        pr.SetStdOut (useStdOut);
        pr.Run ();
        String out;
        Streams::TextInputStreamBinaryAdapter   stdOut  =   Streams::TextInputStreamBinaryAdapter (useStdOut);
        bool skippedHeader = false;
        for (String i = stdOut.ReadLine (); not i.empty (); i = stdOut.ReadLine ()) {
            if (not skippedHeader) {
                skippedHeader = true;
                continue;
            }
            Sequence<String>    l    =  Characters::Tokenize<String> (i, L" ");
            if (l.size () < 6) {
                DbgTrace ("skipping line cuz len=%d", l.size ());
                continue;
            }
            VolumeInfo_ v;
            v.fMountedOnName = l[5];
            v.fDeviceOrVolumeName = l[0];
            v.fDiskSizeInBytes = Characters::String2Float<double> (l[1]) * 1024;
            v.fUsedSizeInBytes = Characters::String2Float<double> (l[2]) * 1024;
            result.Append (v);
        }
        return result;
    }
#endif
}

/*
 ********************************************************************************
 ***************** Instruments::GetMountedFilesystemUsage ***********************
 ********************************************************************************
 */
Instrument  SystemPerformance::Instruments::GetMountedFilesystemUsage ()
{
    static  Instrument  kInstrument_    = Instrument (
            InstrumentNameType (L"Mounted-Filesystem-Usage"),
    [] () -> Measurements {
        Measurements    results;
        DateTime    before = DateTime::Now ();
        Sequence<VolumeInfo_> volumes   =   capture_ ();
        results.fMeasuredAt = DateTimeRange (before, DateTime::Now ());
        Sequence<VariantValue>  volumnesAsVariants;
        for (VolumeInfo_ v : volumes)
        {
            Mapping<String, VariantValue> vv;
            vv.Add (L"Filesystem-Type", v.fFileSystemType);
            if (not v.fDeviceOrVolumeName.empty ()) {
                vv.Add (L"Device-Name", v.fDeviceOrVolumeName);
            }
            vv.Add (L"Volume-ID", v.fVolumeID);
            vv.Add (L"Mounted-On", v.fMountedOnName);
            if (v.fDiskSizeInBytes.IsPresent ()) {
                vv.Add (L"Disk-Size", *v.fDiskSizeInBytes);
            }
            if (v.fUsedSizeInBytes.IsPresent ()) {
                vv.Add (L"Disk-Used-Size", *v.fUsedSizeInBytes);
            }
            volumnesAsVariants.Append (VariantValue (vv));
        }
        Measurement m;
        m.fValue = volumnesAsVariants;
        m.fType = kMountedVolumeUsage;
        results.fMeasurements.Add (m);
        return results;
    },
    {kMountedVolumeUsage}
                                          );
    return kInstrument_;
}
<|endoftext|>


<commit_before>#pragma once

#include <windows.h>
#include <boost/asio.hpp>
#include <stdexcept>

#include "GenericTransport.hpp"

namespace Ethereum{namespace Connector{

typedef boost::asio::windows::stream_handle NamedPipeSocket;

class NamedPipeConnector
{
    public:
        bool connect(NamedPipeSocket &, const char *);
};

typedef GenericTransport<NamedPipeSocket, NamedPipeConnector> NamedPipeTransport;

}}

<commit_msg>fixed asio conflict on windows<commit_after>#pragma once

#include <boost/asio.hpp>
#include <stdexcept>

#include "GenericTransport.hpp"

namespace Ethereum{namespace Connector{

typedef boost::asio::windows::stream_handle NamedPipeSocket;

class NamedPipeConnector
{
    public:
        bool connect(NamedPipeSocket &, const char *);
};

typedef GenericTransport<NamedPipeSocket, NamedPipeConnector> NamedPipeTransport;

}}

<|endoftext|>


<commit_before>//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

//
// Based on Poly2Tri algorithm.
// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
// http://code.google.com/p/poly2tri/
//

#include "Triangulate.h"
#include "Sweep.h"
#include "SweepContext.h"

#include "Shapes.h"

using namespace std;

namespace avg {

std::vector<int> triangulatePolygon(const Vec2Vector& points,
        const std::vector<int>& holeIndexes)
{
    std::vector<Point*> polyline;
    std::vector<Point*> holeLine;
    unsigned int contourEnd;

    if (holeIndexes.size() > 0) {
    contourEnd = holeIndexes[0];
    } else {
    contourEnd = points.size();
    }

    for (unsigned int i = 0; i < contourEnd; i++) {
        polyline.push_back(new Point(points[i].x, points[i].y, i));
    }

    SweepContext* sweepContext = new SweepContext(polyline);
    Sweep* sweep = new Sweep;

    if (holeIndexes.size() > 0) {
        for (unsigned int i = 0; i < holeIndexes.size(); i++) {
            if ( i < holeIndexes.size()-1) {
                for (unsigned int j = holeIndexes[i]; j < points.size() && j <
                        holeIndexes[i+1]; j++)
                {
                    holeLine.push_back(new Point(points[j].x, points[j].y, j));
                }
            } else {
                for (unsigned int j = holeIndexes[i]; j < points.size(); j++) {
                    holeLine.push_back(new Point(points[j].x, points[j].y, j));
                }
            }
            sweepContext->addHole(holeLine);
            holeLine.clear();
    }
    }

    sweep->Triangulate(*sweepContext);

    std::vector<int> result;
    std::vector<avg::TriangulationTriangle*> triangles =  sweepContext->getTriangles();
    for (unsigned int i = 0; i < triangles.size(); ++i) {
        result.push_back(triangles[i]->getPoint(0)->m_Index);
        result.push_back(triangles[i]->getPoint(1)->m_Index);
        result.push_back(triangles[i]->getPoint(2)->m_Index);
    }

    delete sweep;
    delete sweepContext;

    for (unsigned int i = 0; i < polyline.size(); i++) {
        delete polyline[i];
    }

    return result;
}

}
<commit_msg>Indentation fix.<commit_after>//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

//
// Based on Poly2Tri algorithm.
// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
// http://code.google.com/p/poly2tri/
//

#include "Triangulate.h"
#include "Sweep.h"
#include "SweepContext.h"

#include "Shapes.h"

using namespace std;

namespace avg {

std::vector<int> triangulatePolygon(const Vec2Vector& points,
        const std::vector<int>& holeIndexes)
{
    std::vector<Point*> polyline;
    std::vector<Point*> holeLine;
    unsigned int contourEnd;

    if (holeIndexes.size() > 0) {
        contourEnd = holeIndexes[0];
    } else {
        contourEnd = points.size();
    }

    for (unsigned int i = 0; i < contourEnd; i++) {
        polyline.push_back(new Point(points[i].x, points[i].y, i));
    }

    SweepContext* sweepContext = new SweepContext(polyline);
    Sweep* sweep = new Sweep;

    if (holeIndexes.size() > 0) {
        for (unsigned int i = 0; i < holeIndexes.size(); i++) {
            if ( i < holeIndexes.size()-1) {
                for (unsigned int j = holeIndexes[i]; j < points.size() && j <
                        holeIndexes[i+1]; j++)
                {
                    holeLine.push_back(new Point(points[j].x, points[j].y, j));
                }
            } else {
                for (unsigned int j = holeIndexes[i]; j < points.size(); j++) {
                    holeLine.push_back(new Point(points[j].x, points[j].y, j));
                }
            }
            sweepContext->addHole(holeLine);
            holeLine.clear();
        }
    }

    sweep->Triangulate(*sweepContext);

    std::vector<int> result;
    std::vector<avg::TriangulationTriangle*> triangles =  sweepContext->getTriangles();
    for (unsigned int i = 0; i < triangles.size(); ++i) {
        result.push_back(triangles[i]->getPoint(0)->m_Index);
        result.push_back(triangles[i]->getPoint(1)->m_Index);
        result.push_back(triangles[i]->getPoint(2)->m_Index);
    }

    delete sweep;
    delete sweepContext;

    for (unsigned int i = 0; i < polyline.size(); i++) {
        delete polyline[i];
    }

    return result;
}

}
<|endoftext|>


<commit_before>#include "ScanGridProvider.h"

ScanGridProvider::ScanGridProvider()
:
  cameraID(CameraInfo::Top)
{
  DEBUG_REQUEST_REGISTER("Vision:ScanGridProvider:draw_verticals", "draw vertical scanlines", false);
  DEBUG_REQUEST_REGISTER("Vision:ScanGridProvider:draw_horizontals", "draw horizontal scanlines", false);
  DEBUG_REQUEST_REGISTER("Vision:ScanGridProvider:draw_vertical_min_y", "", false);
  getDebugParameterList().add(&parameters);
}

ScanGridProvider::~ScanGridProvider()
{
  getDebugParameterList().remove(&parameters);
}

void ScanGridProvider::execute(CameraInfo::CameraID id)
{
  if(!getCameraMatrix().valid) {
      return;
  }
  this->cameraID = id;
  getScanGrid().reset();

  const int width = getImage().width();
  const int height = getImage().height();

  // calculate horizon
  int horizon_offset = 2;
  int max_horizon = std::max((int) (getArtificialHorizon().begin().y + horizon_offset), 0);
  int min_horizon = std::max((int) (getArtificialHorizon().end().y + horizon_offset), 0);
  if (min_horizon > max_horizon) {
    std::swap(min_horizon, max_horizon);
  }
  if (max_horizon >= height) {
    // camera doesn't point to the ground
    return;
  }

  Vector2i pointInImage;
  int min_scan_y;
  // project max_scan_distance_mm on the image plain to obtain the upper limit of vertical scanlines
  Vector3d cameraMatrixOffset = Vector3d(getCameraMatrix().translation.x, getCameraMatrix().translation.y, 0);
  if(CameraGeometry::relativePointToImage(
       getCameraMatrix(), getCameraInfo(),
       (RotationMatrix::getRotationZ(getCameraMatrix().rotation.getZAngle()) * Vector3d(parameters.max_scan_distance_mm, 0, 0))
        + cameraMatrixOffset,
       pointInImage)
    )
  {
    min_scan_y = std::max(pointInImage.y, 0);
    if(min_scan_y >= height-1) {
      return;
    }
  } else {
    return;
  }
  min_scan_y = std::max(min_scan_y, max_horizon);

  DEBUG_REQUEST("Vision:ScanGridProvider:draw_vertical_min_y",
    LINE_PX(ColorClasses::black, 0, min_scan_y, width-1, min_scan_y);
  );

  double fieldWidthCovered = calculateMaxFieldWidth(min_scan_y);
  if (fieldWidthCovered <= 0) {
    return;
  }
  // calculate number of vertical scanlines with a vertical_gap_mm
  int numberOfVerticals = std::min((int) (fieldWidthCovered / parameters.vertical_gap_mm), parameters.max_vertical_scanlines);

  double minGap = width / (double) numberOfVerticals;
  double gapRatio = parameters.horizontal_gap_mm / parameters.vertical_gap_mm;

  int max_scan_y;
  double y = min_scan_y;
  double distance;
  std::vector<ScanGrid::VScanLine> linesIncreasingLength;

  for(double gap=2*minGap; gap < width; gap*=2)
  {
    // determine the lower bound of the vertical scanline
    // distance of gap if it would be the size of vertical_gap_mm
    distance = parameters.vertical_gap_mm * getCameraInfo().getFocalLength() / gap;
    if(distance < getCameraMatrix().translation.z) {
      max_scan_y = height-1;
    } else {
      distance = std::sqrt(distance*distance - getCameraMatrix().translation.z*getCameraMatrix().translation.z);
      Vector3d pointOnField = (RotationMatrix::getRotationZ(getCameraMatrix().rotation.getZAngle())
                              * Vector3d(distance, 0, 0))
                              + cameraMatrixOffset;
      if(!CameraGeometry::relativePointToImage(
        getCameraMatrix(), getCameraInfo(),
        pointOnField,
        pointInImage)) {
        break;
      }
      max_scan_y = std::min(pointInImage.y, height-1);
      if (max_scan_y <= min_scan_y) {
        continue;
      }
    }
    // fill vertical scan pattern
    double ySkip = std::max(gapRatio * gap/2, parameters.min_horizontal_gap_px);
    for(;y <= max_scan_y; y+=ySkip)
    {
      getScanGrid().vScanPattern.push_back((int) y);
    }

    // scanline with vScanPattern index
    ScanGrid::VScanLine scanline;
    scanline.top = 0;
    scanline.bottom = getScanGrid().vScanPattern.size()-1;
    linesIncreasingLength.push_back(scanline);
    if(max_scan_y >= height-1) {
      break;
    }
  }
  if(linesIncreasingLength.empty() || getScanGrid().vScanPattern.empty()) {
    return;
  }

  getScanGrid().vertical.resize(numberOfVerticals);
  std::vector<ScanGrid::VScanLine>::iterator line = linesIncreasingLength.begin();
  int frequency;
  for(int i=1; i<=numberOfVerticals; i*=2) {
    frequency = i*2;

    for(int j=i-1; j<numberOfVerticals; j+=frequency) {
      int x = (int) (j*minGap);
      ScanGrid::VScanLine scanline;
      scanline.x = x;
      scanline.bottom = line->bottom;
      scanline.top = 0;

      getScanGrid().vertical[j] = scanline;

      if(next(line) == linesIncreasingLength.end()) {
        getScanGrid().longverticals.push_back(j);
      }
    }
    if(next(line) != linesIncreasingLength.end()){
      ++line;
    }
  }

  // fill horizontal scan pattern
  for (const ScanGrid::VScanLine& vertical : getScanGrid().vertical) {
    getScanGrid().hScanPattern.push_back(vertical.x);
  }

  // create horizontal scanlines
  getScanGrid().horizontal.resize(getScanGrid().vScanPattern.size());
  line = linesIncreasingLength.begin();
  int hSkip = 1;
  int i=0;
  for(const int& y : getScanGrid().vScanPattern) {
    if(y > getScanGrid().vScanPattern[line->bottom]) {
      ++line;
      hSkip *= 2;
    }
    ScanGrid::HScanLine horizontal;
    horizontal.left = 0;
    horizontal.right = getScanGrid().hScanPattern.size()-1;
    horizontal.y = y;
    horizontal.skip = hSkip;

    getScanGrid().horizontal[i] = horizontal;
    ++i;
  }

  DEBUG_REQUEST("Vision:ScanGridProvider:draw_verticals",
    for(const ScanGrid::VScanLine& scanline: getScanGrid().vertical)
    {
      LINE_PX(ColorClasses::blue, scanline.x, getScanGrid().vScanPattern.at(scanline.bottom), scanline.x, getScanGrid().vScanPattern.at(scanline.top));
      for(size_t i=scanline.top; i<=scanline.bottom; ++i)
      {
        POINT_PX(ColorClasses::red, scanline.x, getScanGrid().vScanPattern.at(i));

        //Test
        const int xx = scanline.x;
        const int yy = getScanGrid().vScanPattern.at(i);
        getImage().getY(xx, yy);
      }
    }
  );

  DEBUG_REQUEST("Vision:ScanGridProvider:draw_horizontals",
    for(const ScanGrid::HScanLine& scanline: getScanGrid().horizontal)
    {
      LINE_PX(ColorClasses::blue, getScanGrid().hScanPattern.at(scanline.left), scanline.y, getScanGrid().hScanPattern.at(scanline.right), scanline.y);
      for(size_t i=scanline.left; i<=scanline.right; i+=scanline.skip)
      {
        POINT_PX(ColorClasses::red, getScanGrid().hScanPattern.at(i), scanline.y);

        //Test
        const int xx = getScanGrid().hScanPattern.at(i);
        const int yy = scanline.y;
        getImage().getY(xx, yy);
      }
    }
  );

}//end execute

double ScanGridProvider::calculateMaxFieldWidth(int y) {
  Vector2d projectedLeftCorner;
  if(!CameraGeometry::imagePixelToFieldCoord(
    getCameraMatrix(), getCameraInfo(),
    0,
    y,
    0.0,
    projectedLeftCorner))
  {
    return -1.;
  }
  Vector2d projectedRightCorner;
  if(!CameraGeometry::imagePixelToFieldCoord(
    getCameraMatrix(), getCameraInfo(),
    getImage().width()-1,
    y,
    0.0,
    projectedRightCorner))
  {
    return -1.;
  }
  return (projectedLeftCorner - projectedRightCorner).abs();
}
<commit_msg>small fixes, comments and cleanup<commit_after>#include "ScanGridProvider.h"

ScanGridProvider::ScanGridProvider()
:
  cameraID(CameraInfo::Top)
{
  DEBUG_REQUEST_REGISTER("Vision:ScanGridProvider:draw_verticals", "draw vertical scanlines", false);
  DEBUG_REQUEST_REGISTER("Vision:ScanGridProvider:draw_horizontals", "draw horizontal scanlines", false);
  DEBUG_REQUEST_REGISTER("Vision:ScanGridProvider:draw_vertical_min_y", "", false);
  getDebugParameterList().add(&parameters);
}

ScanGridProvider::~ScanGridProvider()
{
  getDebugParameterList().remove(&parameters);
}

void ScanGridProvider::execute(CameraInfo::CameraID id)
{
  this->cameraID = id;

  if(!getCameraMatrix().valid) {
      return;
  }
  getScanGrid().reset();

  const int width = getImage().width();
  const int height = getImage().height();

  // calculate horizon
  int horizon_offset = 2;
  int max_horizon =
      std::max((int) (getArtificialHorizon().begin().y + horizon_offset), 0);
  int min_horizon =
      std::max((int) (getArtificialHorizon().end().y + horizon_offset), 0);

  if (min_horizon > max_horizon) {
    std::swap(min_horizon, max_horizon);
  }

  if (max_horizon >= height) {
    // camera doesn't point to the ground
    return;
  }

  Vector2i pointInImage;

  // project max_scan_distance_mm on the image plain
  // to obtain the upper limit of vertical scanlines
  Vector3d cameraMatrixOffset = Vector3d(getCameraMatrix().translation.x,
                                         getCameraMatrix().translation.y,
                                         0);
  Vector3d farthestPoint = cameraMatrixOffset +
      (RotationMatrix::getRotationZ(getCameraMatrix().rotation.getZAngle()) *
       Vector3d(parameters.max_scan_distance_mm, 0, 0));

  bool projectionSucces = CameraGeometry::relativePointToImage(
        getCameraMatrix(), getCameraInfo(), farthestPoint, pointInImage);

  int min_scan_y;
  if(projectionSucces)
  {
    // should not be heigher than the top of the image
    min_scan_y = std::max(pointInImage.y, 0);
    // should not be lower than the bottom of the image
    if(min_scan_y >= height) {
      return;
    }
  } else {
    return;
  }
  // should not be over the horizon
  min_scan_y = std::max(min_scan_y, max_horizon);

  DEBUG_REQUEST("Vision:ScanGridProvider:draw_vertical_min_y",
    LINE_PX(ColorClasses::black, 0, min_scan_y, width-1, min_scan_y);
  );

  double fieldWidthCovered = calculateMaxFieldWidth(min_scan_y);
  if (fieldWidthCovered <= 0) {
    return;
  }
  // calculate number of vertical scanlines with a vertical_gap_mm
  int numberOfVerticals = std::min(
        (int) (fieldWidthCovered / parameters.vertical_gap_mm),
        parameters.max_vertical_scanlines);

  double minGap = width / (double) numberOfVerticals;
  // transforms verticle gap sizes into horizontal gap sizes
  double gapRatio = parameters.horizontal_gap_mm / parameters.vertical_gap_mm;

  double focalLength = getCameraInfo().getFocalLength();
  double cameraHeight = getCameraMatrix().translation.z;

  int max_scan_y;
  double y = min_scan_y;
  double distance;
  std::vector<ScanGrid::VScanLine> linesIncreasingLength;

  for(double gap = 2 * minGap; gap < width; gap *= 2)
  {
    // distance of the gap if it would have a field size of vertical_gap_mm
    distance = parameters.vertical_gap_mm * focalLength / gap;

    // determine the start of the vertical scanline
    if(distance < cameraHeight) {
      max_scan_y = height-1;
    } else {
      distance = std::sqrt(distance * distance - cameraHeight * cameraHeight);
      // project gap distance onto the image to obtain the start of the scanline
      Vector3d pointOnField = cameraMatrixOffset +
          (RotationMatrix::getRotationZ(getCameraMatrix().rotation.getZAngle())
           * Vector3d(distance, 0, 0));

      bool projectionSucces = CameraGeometry::relativePointToImage(
            getCameraMatrix(), getCameraInfo(),
            pointOnField,
            pointInImage);
      if(!projectionSucces) {
        break;
      }
      max_scan_y = std::min(pointInImage.y, height-1);
      if (max_scan_y <= min_scan_y) {
        continue;
      }
    }
    // fill vertical scan pattern
    double ySkip = std::max(gapRatio * gap/2, parameters.min_horizontal_gap_px);
    for(;y <= max_scan_y; y+=ySkip)
    {
      getScanGrid().vScanPattern.push_back((int) y);
    }

    // scanline with vScanPattern index
    ScanGrid::VScanLine scanline;
    scanline.top = 0;
    scanline.bottom = getScanGrid().vScanPattern.size()-1;

    linesIncreasingLength.push_back(scanline);

    if(max_scan_y >= height-1) {
      // bottom of the image reached
      break;
    }
  }

  if(linesIncreasingLength.empty() || getScanGrid().vScanPattern.empty()) {
    return;
  }

  // fill the image with vertical scanlines
  getScanGrid().vertical.resize(numberOfVerticals);
  std::vector<ScanGrid::VScanLine>::iterator line = linesIncreasingLength.begin();
  int frequency;
  for(int i=1; i<=numberOfVerticals; i*=2) {
    frequency = i*2;

    for(int j=i-1; j<numberOfVerticals; j+=frequency) {
      int x = (int) (j*minGap);
      ScanGrid::VScanLine scanline;
      scanline.x = x;
      scanline.bottom = line->bottom;
      scanline.top = 0;

      getScanGrid().vertical[j] = scanline;

      if(next(line) == linesIncreasingLength.end()) {
        getScanGrid().longverticals.push_back(j);
      }
    }
    if(next(line) != linesIncreasingLength.end()){
      ++line;
    }
  }

  // fill horizontal scan pattern
  for (const ScanGrid::VScanLine& vertical : getScanGrid().vertical) {
    getScanGrid().hScanPattern.push_back(vertical.x);
  }

  // fill the image with horizontal scanlines
  getScanGrid().horizontal.resize(getScanGrid().vScanPattern.size());
  line = linesIncreasingLength.begin();
  int hSkip = 1;
  int i=0;
  for(const int& y : getScanGrid().vScanPattern) {
    if(y > getScanGrid().vScanPattern[line->bottom]) {
      ++line;
      hSkip *= 2;
    }
    ScanGrid::HScanLine horizontal;
    horizontal.left = 0;
    horizontal.right = getScanGrid().hScanPattern.size()-1;
    horizontal.y = y;
    horizontal.skip = hSkip;

    getScanGrid().horizontal[i] = horizontal;
    ++i;
  }

  DEBUG_REQUEST("Vision:ScanGridProvider:draw_verticals",
    for(const ScanGrid::VScanLine& scanline: getScanGrid().vertical)
    {
      LINE_PX(ColorClasses::blue, scanline.x, getScanGrid().vScanPattern.at(scanline.bottom), scanline.x, getScanGrid().vScanPattern.at(scanline.top));
      for(size_t i=scanline.top; i<=scanline.bottom; ++i)
      {
        POINT_PX(ColorClasses::red, scanline.x, getScanGrid().vScanPattern.at(i));

        //Test
        const int xx = scanline.x;
        const int yy = getScanGrid().vScanPattern.at(i);
        getImage().getY(xx, yy);
      }
    }
  );

  DEBUG_REQUEST("Vision:ScanGridProvider:draw_horizontals",
    for(const ScanGrid::HScanLine& scanline: getScanGrid().horizontal)
    {
      LINE_PX(ColorClasses::blue, getScanGrid().hScanPattern.at(scanline.left), scanline.y, getScanGrid().hScanPattern.at(scanline.right), scanline.y);
      for(size_t i=scanline.left; i<=scanline.right; i+=scanline.skip)
      {
        POINT_PX(ColorClasses::red, getScanGrid().hScanPattern.at(i), scanline.y);

        //Test
        const int xx = getScanGrid().hScanPattern.at(i);
        const int yy = scanline.y;
        getImage().getY(xx, yy);
      }
    }
  );

}//end execute

double ScanGridProvider::calculateMaxFieldWidth(int y) {
  // project the left and right image corner onto the field
  // and caluclate the distance between thems
  Vector2d projectedLeftCorner;
  if(!CameraGeometry::imagePixelToFieldCoord(
    getCameraMatrix(), getCameraInfo(),
    0,
    y,
    0.0,
    projectedLeftCorner))
  {
    return -1.;
  }
  Vector2d projectedRightCorner;
  if(!CameraGeometry::imagePixelToFieldCoord(
    getCameraMatrix(), getCameraInfo(),
    getImage().width()-1,
    y,
    0.0,
    projectedRightCorner))
  {
    return -1.;
  }
  return (projectedLeftCorner - projectedRightCorner).abs();
}
<|endoftext|>


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

/* Author: Ioan Sucan */

#include "ompl/geometric/planners/ryodo_sbl/RyodoSBL.h"
#include "ompl/base/goals/GoalSampleableRegion.h"
#include "ompl/base/samplers/ProbablicUniformValidStateSampler.h"
#include "ompl/tools/config/SelfConfig.h"
#include <limits>
#include <cassert>

ompl::base::ValidStateSamplerPtr allocProbablicUniformValidStateSampler(const ompl::base::SpaceInformation *si)
{
  return ompl::base::ValidStateSamplerPtr(new ompl::base::ProbablicUniformValidStateSampler(si));
}

ompl::geometric::RyodoSBL::RyodoSBL(const base::SpaceInformationPtr &si) : base::Planner(si, "SBL")
{
    specs_.recognizedGoal = base::GOAL_SAMPLEABLE_REGION;
    maxDistance_ = 0.0;
    connectionPoint_ = std::make_pair<base::State*, base::State*>(NULL, NULL);

    Planner::declareParam<double>("range", this, &RyodoSBL::setRange, &RyodoSBL::getRange, "0.:1.:10000.");
}

ompl::geometric::RyodoSBL::~RyodoSBL()
{
    freeMemory();
}

void ompl::geometric::RyodoSBL::setup()
{
    Planner::setup();
    tools::SelfConfig sc(si_, getName());
    sc.configureProjectionEvaluator(projectionEvaluator_);
    sc.configurePlannerRange(maxDistance_);

    tStart_.grid.setDimension(projectionEvaluator_->getDimension());
    tGoal_.grid.setDimension(projectionEvaluator_->getDimension());
}

void ompl::geometric::RyodoSBL::freeGridMotions(Grid<MotionInfo> &grid)
{
    for (Grid<MotionInfo>::iterator it = grid.begin(); it != grid.end() ; ++it)
    {
        for (unsigned int i = 0 ; i < it->second->data.size() ; ++i)
        {
            if (it->second->data[i]->state)
                si_->freeState(it->second->data[i]->state);
            delete it->second->data[i];
        }
    }
}

ompl::base::PlannerStatus ompl::geometric::RyodoSBL::solve(const base::PlannerTerminationCondition &ptc)
{
  checkValidity();
  base::GoalSampleableRegion *goal = dynamic_cast<base::GoalSampleableRegion*>(pdef_->getGoal().get());

  if (!goal)
    {
      OMPL_ERROR("%s: Unknown type of goal", getName().c_str());
      return base::PlannerStatus::UNRECOGNIZED_GOAL_TYPE;
    }

  while (const base::State *st = pis_.nextStart())
    {
      Motion *motion = new Motion(si_);
      si_->copyState(motion->state, st);
      motion->valid = true;
      motion->root = motion->state;
      addMotion(tStart_, motion);
    }

  if (tStart_.size == 0)
    {
      OMPL_ERROR("%s: Motion planning start tree could not be initialized!", getName().c_str());
      return base::PlannerStatus::INVALID_START;
    }

  if (!goal->couldSample())
    {
      OMPL_ERROR("%s: Insufficient states in sampleable goal region", getName().c_str());
      return base::PlannerStatus::INVALID_GOAL;
    }

  if (!sampler_){
    si_->setValidStateSamplerAllocator(boost::bind(&allocProbablicUniformValidStateSampler, _1));
    sampler_ = si_->allocValidStateSampler();
  }

  OMPL_INFORM("%s: Starting planning with %d states already in datastructure", getName().c_str(), (int)(tStart_.size + tGoal_.size));

  std::vector<Motion*> solution;
  base::State *xstate = si_->allocState();

  bool      startTree = true;
  bool         solved = false;

  while (ptc == false)
    {
      TreeData &tree      = startTree ? tStart_ : tGoal_;
      startTree = !startTree;
      TreeData &otherTree = startTree ? tStart_ : tGoal_;

      // if we have not sampled too many goals already
      if (tGoal_.size == 0 || pis_.getSampledGoalsCount() < tGoal_.size / 2)
        {
          const base::State *st = tGoal_.size == 0 ? pis_.nextGoal(ptc) : pis_.nextGoal();
          if (st)
            {
              Motion *motion = new Motion(si_);
              si_->copyState(motion->state, st);
              motion->root = motion->state;
              motion->valid = true;
              addMotion(tGoal_, motion);
            }
          if (tGoal_.size == 0)
            {
              OMPL_ERROR("%s: Unable to sample any valid states for goal tree", getName().c_str());
              break;
            }
        }

      Motion *existing = selectMotion(tree);
      assert(existing);
      if (!sampler_->sampleNear(xstate, existing->state, maxDistance_))
        continue;

      /* create a motion */
      Motion *motion = new Motion(si_);
      si_->copyState(motion->state, xstate);
      motion->parent = existing;
      motion->root = existing->root;
      existing->children.push_back(motion);

      addMotion(tree, motion);

      if (checkSolution(!startTree, tree, otherTree, motion, solution))
        {
          PathGeometric *path = new PathGeometric(si_);
          for (unsigned int i = 0 ; i < solution.size() ; ++i)
            path->append(solution[i]->state);

          pdef_->addSolutionPath(base::PathPtr(path), false, 0.0, getName());
          solved = true;
          break;
        }
    }

  si_->freeState(xstate);

  OMPL_INFORM("%s: Created %u (%u start + %u goal) states in %u cells (%u start + %u goal)",
              getName().c_str(), tStart_.size + tGoal_.size, tStart_.size, tGoal_.size,
              tStart_.grid.size() + tGoal_.grid.size(), tStart_.grid.size(), tGoal_.grid.size());

  return solved ? base::PlannerStatus::EXACT_SOLUTION : base::PlannerStatus::TIMEOUT;
}

bool ompl::geometric::RyodoSBL::checkSolution(bool start, TreeData &tree, TreeData &otherTree, Motion *motion, std::vector<Motion*> &solution)
{
    Grid<MotionInfo>::Coord coord;
    projectionEvaluator_->computeCoordinates(motion->state, coord);
    Grid<MotionInfo>::Cell* cell = otherTree.grid.getCell(coord);

    if (cell && !cell->data.empty())
    {
        Motion *connectOther = cell->data[rng_.uniformInt(0, cell->data.size() - 1)];

        if (pdef_->getGoal()->isStartGoalPairValid(start ? motion->root : connectOther->root, start ? connectOther->root : motion->root))
        {
            Motion *connect = new Motion(si_);

            si_->copyState(connect->state, connectOther->state);
            connect->parent = motion;
            connect->root = motion->root;            motion->children.push_back(connect);
            addMotion(tree, connect);

            if (isPathValid(tree, connect) && isPathValid(otherTree, connectOther))
            {
                if (start)
                    connectionPoint_ = std::make_pair(motion->state, connectOther->state);
                else
                    connectionPoint_ = std::make_pair(connectOther->state, motion->state);

                /* extract the motions and put them in solution vector */

                std::vector<Motion*> mpath1;
                while (motion != NULL)
                {
                    mpath1.push_back(motion);
                    motion = motion->parent;
                }

                std::vector<Motion*> mpath2;
                while (connectOther != NULL)
                {
                    mpath2.push_back(connectOther);
                    connectOther = connectOther->parent;
                }

                if (!start)
                    mpath1.swap(mpath2);

                for (int i = mpath1.size() - 1 ; i >= 0 ; --i)
                    solution.push_back(mpath1[i]);
                solution.insert(solution.end(), mpath2.begin(), mpath2.end());

                return true;
            }
        }
    }
    return false;
}

bool ompl::geometric::RyodoSBL::isPathValid(TreeData &tree, Motion *motion)
{
    std::vector<Motion*> mpath;

    /* construct the solution path */
    while (motion != NULL)
    {
        mpath.push_back(motion);
        motion = motion->parent;
    }

    /* check the path */
    for (int i = mpath.size() - 1 ; i >= 0 ; --i)
        if (!mpath[i]->valid)
        {
            if (si_->checkMotion(mpath[i]->parent->state, mpath[i]->state))
                mpath[i]->valid = true;
            else
            {
                removeMotion(tree, mpath[i]);
                return false;
            }
        }
    return true;
}

ompl::geometric::RyodoSBL::Motion* ompl::geometric::RyodoSBL::selectMotion(TreeData &tree)
{
    GridCell* cell = tree.pdf.sample(rng_.uniform01());
    return cell && !cell->data.empty() ? cell->data[rng_.uniformInt(0, cell->data.size() - 1)] : NULL;
}

void ompl::geometric::RyodoSBL::removeMotion(TreeData &tree, Motion *motion)
{
    /* remove from grid */

    Grid<MotionInfo>::Coord coord;
    projectionEvaluator_->computeCoordinates(motion->state, coord);
    Grid<MotionInfo>::Cell* cell = tree.grid.getCell(coord);
    if (cell)
    {
        for (unsigned int i = 0 ; i < cell->data.size(); ++i)
        {
            if (cell->data[i] == motion)
            {
                cell->data.erase(cell->data.begin() + i);
                tree.size--;
                break;
            }
        }
        if (cell->data.empty())
        {
            tree.pdf.remove(cell->data.elem_);
            tree.grid.remove(cell);
            tree.grid.destroyCell(cell);
        }
        else
        {
            tree.pdf.update(cell->data.elem_, 1.0/cell->data.size());
        }
    }

    /* remove self from parent list */

    if (motion->parent)
    {
        for (unsigned int i = 0 ; i < motion->parent->children.size() ; ++i)
        {
            if (motion->parent->children[i] == motion)
            {
                motion->parent->children.erase(motion->parent->children.begin() + i);
                break;
            }
        }
    }

    /* remove children */
    for (unsigned int i = 0 ; i < motion->children.size() ; ++i)
    {
        motion->children[i]->parent = NULL;
        removeMotion(tree, motion->children[i]);
    }

    if (motion->state)
        si_->freeState(motion->state);
    delete motion;
}

void ompl::geometric::RyodoSBL::addMotion(TreeData &tree, Motion *motion)
{
    Grid<MotionInfo>::Coord coord;
    projectionEvaluator_->computeCoordinates(motion->state, coord);
    Grid<MotionInfo>::Cell* cell = tree.grid.getCell(coord);
    if (cell)
    {
        cell->data.push_back(motion);
        tree.pdf.update(cell->data.elem_, 1.0/cell->data.size());
    }
    else
    {
        cell = tree.grid.createCell(coord);
        cell->data.push_back(motion);
        tree.grid.add(cell);
        cell->data.elem_ = tree.pdf.add(cell, 1.0);
    }
    tree.size++;
}

void ompl::geometric::RyodoSBL::clear()
{
    Planner::clear();

    sampler_.reset();

    freeMemory();

    tStart_.grid.clear();
    tStart_.size = 0;
    tStart_.pdf.clear();

    tGoal_.grid.clear();
    tGoal_.size = 0;
    tGoal_.pdf.clear();
    connectionPoint_ = std::make_pair<base::State*, base::State*>(NULL, NULL);
}

void ompl::geometric::RyodoSBL::getPlannerData(base::PlannerData &data) const
{
    Planner::getPlannerData(data);

    std::vector<MotionInfo> motions;
    tStart_.grid.getContent(motions);

    for (unsigned int i = 0 ; i < motions.size() ; ++i)
        for (unsigned int j = 0 ; j < motions[i].size() ; ++j)
            if (motions[i][j]->parent == NULL)
                data.addStartVertex(base::PlannerDataVertex(motions[i][j]->state, 1));
            else
                data.addEdge(base::PlannerDataVertex(motions[i][j]->parent->state, 1),
                             base::PlannerDataVertex(motions[i][j]->state, 1));

    motions.clear();
    tGoal_.grid.getContent(motions);
    for (unsigned int i = 0 ; i < motions.size() ; ++i)
        for (unsigned int j = 0 ; j < motions[i].size() ; ++j)
            if (motions[i][j]->parent == NULL)
                data.addGoalVertex(base::PlannerDataVertex(motions[i][j]->state, 2));
            else
                // The edges in the goal tree are reversed so that they are in the same direction as start tree
                data.addEdge(base::PlannerDataVertex(motions[i][j]->state, 2),
                             base::PlannerDataVertex(motions[i][j]->parent->state, 2));

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

/* Author: Ioan Sucan */

#include "ompl/geometric/planners/ryodo_sbl/RyodoSBL.h"
#include "ompl/base/goals/GoalSampleableRegion.h"
#include "ompl/base/samplers/ObstacleEstimationSampler.h"
#include "ompl/tools/config/SelfConfig.h"
#include <limits>
#include <cassert>

ompl::base::ValidStateSamplerPtr allocObstacleEstimationSampler(const ompl::base::SpaceInformation *si)
{
  return ompl::base::ValidStateSamplerPtr(new ompl::base::ObstacleEstimationSampler(si));
}

ompl::geometric::RyodoSBL::RyodoSBL(const base::SpaceInformationPtr &si) : base::Planner(si, "SBL")
{
    specs_.recognizedGoal = base::GOAL_SAMPLEABLE_REGION;
    maxDistance_ = 0.0;
    connectionPoint_ = std::make_pair<base::State*, base::State*>(NULL, NULL);

    Planner::declareParam<double>("range", this, &RyodoSBL::setRange, &RyodoSBL::getRange, "0.:1.:10000.");
}

ompl::geometric::RyodoSBL::~RyodoSBL()
{
    freeMemory();
}

void ompl::geometric::RyodoSBL::setup()
{
    Planner::setup();
    tools::SelfConfig sc(si_, getName());
    sc.configureProjectionEvaluator(projectionEvaluator_);
    sc.configurePlannerRange(maxDistance_);

    tStart_.grid.setDimension(projectionEvaluator_->getDimension());
    tGoal_.grid.setDimension(projectionEvaluator_->getDimension());
}

void ompl::geometric::RyodoSBL::freeGridMotions(Grid<MotionInfo> &grid)
{
    for (Grid<MotionInfo>::iterator it = grid.begin(); it != grid.end() ; ++it)
    {
        for (unsigned int i = 0 ; i < it->second->data.size() ; ++i)
        {
            if (it->second->data[i]->state)
                si_->freeState(it->second->data[i]->state);
            delete it->second->data[i];
        }
    }
}

ompl::base::PlannerStatus ompl::geometric::RyodoSBL::solve(const base::PlannerTerminationCondition &ptc)
{
  checkValidity();
  base::GoalSampleableRegion *goal = dynamic_cast<base::GoalSampleableRegion*>(pdef_->getGoal().get());

  if (!goal)
    {
      OMPL_ERROR("%s: Unknown type of goal", getName().c_str());
      return base::PlannerStatus::UNRECOGNIZED_GOAL_TYPE;
    }

  while (const base::State *st = pis_.nextStart())
    {
      Motion *motion = new Motion(si_);
      si_->copyState(motion->state, st);
      motion->valid = true;
      motion->root = motion->state;
      addMotion(tStart_, motion);
    }

  if (tStart_.size == 0)
    {
      OMPL_ERROR("%s: Motion planning start tree could not be initialized!", getName().c_str());
      return base::PlannerStatus::INVALID_START;
    }

  if (!goal->couldSample())
    {
      OMPL_ERROR("%s: Insufficient states in sampleable goal region", getName().c_str());
      return base::PlannerStatus::INVALID_GOAL;
    }

  if (!sampler_){
    si_->setValidStateSamplerAllocator(boost::bind(&allocObstacleEstimationSampler, _1));
    sampler_ = si_->allocValidStateSampler();
  }

  OMPL_INFORM("%s: Starting planning with %d states already in datastructure", getName().c_str(), (int)(tStart_.size + tGoal_.size));

  std::vector<Motion*> solution;
  base::State *xstate = si_->allocState();

  bool      startTree = true;
  bool         solved = false;

  while (ptc == false)
    {
      TreeData &tree      = startTree ? tStart_ : tGoal_;
      startTree = !startTree;
      TreeData &otherTree = startTree ? tStart_ : tGoal_;

      // if we have not sampled too many goals already
      if (tGoal_.size == 0 || pis_.getSampledGoalsCount() < tGoal_.size / 2)
        {
          const base::State *st = tGoal_.size == 0 ? pis_.nextGoal(ptc) : pis_.nextGoal();
          if (st)
            {
              Motion *motion = new Motion(si_);
              si_->copyState(motion->state, st);
              motion->root = motion->state;
              motion->valid = true;
              addMotion(tGoal_, motion);
            }
          if (tGoal_.size == 0)
            {
              OMPL_ERROR("%s: Unable to sample any valid states for goal tree", getName().c_str());
              break;
            }
        }

      Motion *existing = selectMotion(tree);
      assert(existing);
      if (!sampler_->sampleNear(xstate, existing->state, maxDistance_))
        continue;

      /* create a motion */
      Motion *motion = new Motion(si_);
      si_->copyState(motion->state, xstate);
      motion->parent = existing;
      motion->root = existing->root;
      existing->children.push_back(motion);

      addMotion(tree, motion);

      if (checkSolution(!startTree, tree, otherTree, motion, solution))
        {
          PathGeometric *path = new PathGeometric(si_);
          for (unsigned int i = 0 ; i < solution.size() ; ++i)
            path->append(solution[i]->state);

          pdef_->addSolutionPath(base::PathPtr(path), false, 0.0, getName());
          solved = true;
          break;
        }
    }

  si_->freeState(xstate);

  OMPL_INFORM("%s: Created %u (%u start + %u goal) states in %u cells (%u start + %u goal)",
              getName().c_str(), tStart_.size + tGoal_.size, tStart_.size, tGoal_.size,
              tStart_.grid.size() + tGoal_.grid.size(), tStart_.grid.size(), tGoal_.grid.size());

  return solved ? base::PlannerStatus::EXACT_SOLUTION : base::PlannerStatus::TIMEOUT;
}

bool ompl::geometric::RyodoSBL::checkSolution(bool start, TreeData &tree, TreeData &otherTree, Motion *motion, std::vector<Motion*> &solution)
{
    Grid<MotionInfo>::Coord coord;
    projectionEvaluator_->computeCoordinates(motion->state, coord);
    Grid<MotionInfo>::Cell* cell = otherTree.grid.getCell(coord);

    if (cell && !cell->data.empty())
    {
        Motion *connectOther = cell->data[rng_.uniformInt(0, cell->data.size() - 1)];

        if (pdef_->getGoal()->isStartGoalPairValid(start ? motion->root : connectOther->root, start ? connectOther->root : motion->root))
        {
            Motion *connect = new Motion(si_);

            si_->copyState(connect->state, connectOther->state);
            connect->parent = motion;
            connect->root = motion->root;            motion->children.push_back(connect);
            addMotion(tree, connect);

            if (isPathValid(tree, connect) && isPathValid(otherTree, connectOther))
            {
                if (start)
                    connectionPoint_ = std::make_pair(motion->state, connectOther->state);
                else
                    connectionPoint_ = std::make_pair(connectOther->state, motion->state);

                /* extract the motions and put them in solution vector */

                std::vector<Motion*> mpath1;
                while (motion != NULL)
                {
                    mpath1.push_back(motion);
                    motion = motion->parent;
                }

                std::vector<Motion*> mpath2;
                while (connectOther != NULL)
                {
                    mpath2.push_back(connectOther);
                    connectOther = connectOther->parent;
                }

                if (!start)
                    mpath1.swap(mpath2);

                for (int i = mpath1.size() - 1 ; i >= 0 ; --i)
                    solution.push_back(mpath1[i]);
                solution.insert(solution.end(), mpath2.begin(), mpath2.end());

                return true;
            }
        }
    }
    return false;
}

bool ompl::geometric::RyodoSBL::isPathValid(TreeData &tree, Motion *motion)
{
    std::vector<Motion*> mpath;

    /* construct the solution path */
    while (motion != NULL)
    {
        mpath.push_back(motion);
        motion = motion->parent;
    }

    /* check the path */
    for (int i = mpath.size() - 1 ; i >= 0 ; --i)
        if (!mpath[i]->valid)
        {
            if (si_->checkMotion(mpath[i]->parent->state, mpath[i]->state))
                mpath[i]->valid = true;
            else
            {
                removeMotion(tree, mpath[i]);
                return false;
            }
        }
    return true;
}

ompl::geometric::RyodoSBL::Motion* ompl::geometric::RyodoSBL::selectMotion(TreeData &tree)
{
    GridCell* cell = tree.pdf.sample(rng_.uniform01());
    return cell && !cell->data.empty() ? cell->data[rng_.uniformInt(0, cell->data.size() - 1)] : NULL;
}

void ompl::geometric::RyodoSBL::removeMotion(TreeData &tree, Motion *motion)
{
    /* remove from grid */

    Grid<MotionInfo>::Coord coord;
    projectionEvaluator_->computeCoordinates(motion->state, coord);
    Grid<MotionInfo>::Cell* cell = tree.grid.getCell(coord);
    if (cell)
    {
        for (unsigned int i = 0 ; i < cell->data.size(); ++i)
        {
            if (cell->data[i] == motion)
            {
                cell->data.erase(cell->data.begin() + i);
                tree.size--;
                break;
            }
        }
        if (cell->data.empty())
        {
            tree.pdf.remove(cell->data.elem_);
            tree.grid.remove(cell);
            tree.grid.destroyCell(cell);
        }
        else
        {
            tree.pdf.update(cell->data.elem_, 1.0/cell->data.size());
        }
    }

    /* remove self from parent list */

    if (motion->parent)
    {
        for (unsigned int i = 0 ; i < motion->parent->children.size() ; ++i)
        {
            if (motion->parent->children[i] == motion)
            {
                motion->parent->children.erase(motion->parent->children.begin() + i);
                break;
            }
        }
    }

    /* remove children */
    for (unsigned int i = 0 ; i < motion->children.size() ; ++i)
    {
        motion->children[i]->parent = NULL;
        removeMotion(tree, motion->children[i]);
    }

    if (motion->state)
        si_->freeState(motion->state);
    delete motion;
}

void ompl::geometric::RyodoSBL::addMotion(TreeData &tree, Motion *motion)
{
    Grid<MotionInfo>::Coord coord;
    projectionEvaluator_->computeCoordinates(motion->state, coord);
    Grid<MotionInfo>::Cell* cell = tree.grid.getCell(coord);
    if (cell)
    {
        cell->data.push_back(motion);
        tree.pdf.update(cell->data.elem_, 1.0/cell->data.size());
    }
    else
    {
        cell = tree.grid.createCell(coord);
        cell->data.push_back(motion);
        tree.grid.add(cell);
        cell->data.elem_ = tree.pdf.add(cell, 1.0);
    }
    tree.size++;
}

void ompl::geometric::RyodoSBL::clear()
{
    Planner::clear();

    sampler_.reset();

    freeMemory();

    tStart_.grid.clear();
    tStart_.size = 0;
    tStart_.pdf.clear();

    tGoal_.grid.clear();
    tGoal_.size = 0;
    tGoal_.pdf.clear();
    connectionPoint_ = std::make_pair<base::State*, base::State*>(NULL, NULL);
}

void ompl::geometric::RyodoSBL::getPlannerData(base::PlannerData &data) const
{
    Planner::getPlannerData(data);

    std::vector<MotionInfo> motions;
    tStart_.grid.getContent(motions);

    for (unsigned int i = 0 ; i < motions.size() ; ++i)
        for (unsigned int j = 0 ; j < motions[i].size() ; ++j)
            if (motions[i][j]->parent == NULL)
                data.addStartVertex(base::PlannerDataVertex(motions[i][j]->state, 1));
            else
                data.addEdge(base::PlannerDataVertex(motions[i][j]->parent->state, 1),
                             base::PlannerDataVertex(motions[i][j]->state, 1));

    motions.clear();
    tGoal_.grid.getContent(motions);
    for (unsigned int i = 0 ; i < motions.size() ; ++i)
        for (unsigned int j = 0 ; j < motions[i].size() ; ++j)
            if (motions[i][j]->parent == NULL)
                data.addGoalVertex(base::PlannerDataVertex(motions[i][j]->state, 2));
            else
                // The edges in the goal tree are reversed so that they are in the same direction as start tree
                data.addEdge(base::PlannerDataVertex(motions[i][j]->state, 2),
                             base::PlannerDataVertex(motions[i][j]->parent->state, 2));

    data.addEdge(data.vertexIndex(connectionPoint_.first), data.vertexIndex(connectionPoint_.second));
}
<|endoftext|>