<commit_before>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "ActiveObjects.h"
#include "ModuleManager.h"
#include "Utilities.h"

#include <pqActiveObjects.h>
#include <pqApplicationCore.h>
#include <pqObjectBuilder.h>
#include <pqPipelineSource.h>
#include <pqServer.h>
#include <pqView.h>

#include <vtkNew.h>
#include <vtkSMProxyIterator.h>
#include <vtkSMRenderViewProxy.h>
#include <vtkSMSourceProxy.h>
#include <vtkSMViewProxy.h>

namespace tomviz {

ActiveObjects::ActiveObjects() : QObject()
{
  connect(&pqActiveObjects::instance(), SIGNAL(viewChanged(pqView*)),
          SLOT(viewChanged(pqView*)));
  connect(&ModuleManager::instance(), SIGNAL(dataSourceRemoved(DataSource*)),
          SLOT(dataSourceRemoved(DataSource*)));
  connect(&ModuleManager::instance(), SIGNAL(moduleRemoved(Module*)),
          SLOT(moduleRemoved(Module*)));
}

ActiveObjects::~ActiveObjects()
{
}

ActiveObjects& ActiveObjects::instance()
{
  static ActiveObjects theInstance;
  return theInstance;
}

void ActiveObjects::setActiveView(vtkSMViewProxy* view)
{
  pqActiveObjects::instance().setActiveView(tomviz::convert<pqView*>(view));
}

vtkSMViewProxy* ActiveObjects::activeView() const
{
  pqView* view = pqActiveObjects::instance().activeView();
  return view ? view->getViewProxy() : nullptr;
}

void ActiveObjects::viewChanged(pqView* view)
{
  emit viewChanged(view ? view->getViewProxy() : nullptr);
}

void ActiveObjects::dataSourceRemoved(DataSource* ds)
{
  if (m_activeDataSource == ds) {
    setActiveDataSource(nullptr);
  }
}

void ActiveObjects::moduleRemoved(Module* mdl)
{
  if (m_activeModule == mdl) {
    setActiveModule(nullptr);
  }
}

void ActiveObjects::setActiveDataSource(DataSource* source)
{
  if (m_activeDataSource != source) {
    if (m_activeDataSource) {
      disconnect(m_activeDataSource, SIGNAL(dataChanged()), this,
                 SLOT(dataSourceChanged()));
    }
    if (source) {
      connect(source, SIGNAL(dataChanged()), this, SLOT(dataSourceChanged()));
      m_activeDataSourceType = source->type();
    }
    m_activeDataSource = source;
    emit dataSourceChanged(m_activeDataSource);
  }
  emit dataSourceActivated(m_activeDataSource);
}

void ActiveObjects::dataSourceChanged()
{
  if (m_activeDataSource->type() != m_activeDataSourceType) {
    m_activeDataSourceType = m_activeDataSource->type();
    emit dataSourceChanged(m_activeDataSource);
  }
}

vtkSMSessionProxyManager* ActiveObjects::proxyManager() const
{
  pqServer* server = pqActiveObjects::instance().activeServer();
  return server ? server->proxyManager() : nullptr;
}

void ActiveObjects::setActiveModule(Module* module)
{
  if (m_activeModule != module) {
    m_activeModule = module;
    if (module) {
      setActiveView(module->view());
      setActiveDataSource(module->dataSource());
    }
    emit moduleChanged(module);
  }
  emit moduleActivated(module);
}

void ActiveObjects::setActiveOperator(Operator* op)
{
  if (m_activeOperator != op) {
    m_activeOperator = op;
    emit operatorChanged(op);
  }
  emit operatorActivated(op);
}

void ActiveObjects::createRenderViewIfNeeded()
{
  vtkNew<vtkSMProxyIterator> iter;
  iter->SetSessionProxyManager(proxyManager());
  iter->SetModeToOneGroup();
  for (iter->Begin("views"); !iter->IsAtEnd(); iter->Next()) {
    vtkSMRenderViewProxy* renderView =
      vtkSMRenderViewProxy::SafeDownCast(iter->GetProxy());
    if (renderView) {
      return;
    }
  }

  // If we get here, there was no existing view, so create one.
  pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
  pqServer* server = pqApplicationCore::instance()->getActiveServer();
  builder->createView("RenderView", server);
}

void ActiveObjects::setActiveViewToFirstRenderView()
{
  vtkNew<vtkSMProxyIterator> iter;
  iter->SetSessionProxyManager(proxyManager());
  iter->SetModeToOneGroup();
  for (iter->Begin("views"); !iter->IsAtEnd(); iter->Next()) {
    vtkSMRenderViewProxy* renderView =
      vtkSMRenderViewProxy::SafeDownCast(iter->GetProxy());
    if (renderView) {
      setActiveView(renderView);
      break;
    }
  }
}

void ActiveObjects::setMoveObjectsMode(bool moveObjectsOn)
{
  if (m_moveObjectsEnabled != moveObjectsOn) {
    m_moveObjectsEnabled = moveObjectsOn;
    emit moveObjectsModeChanged(moveObjectsOn);
  }
}

void ActiveObjects::renderAllViews()
{
  pqApplicationCore::instance()->render();
}

} // end of namespace tomviz
<commit_msg>Update active datasource when module or operator is selected<commit_after>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "ActiveObjects.h"
#include "ModuleManager.h"
#include "Utilities.h"

#include <pqActiveObjects.h>
#include <pqApplicationCore.h>
#include <pqObjectBuilder.h>
#include <pqPipelineSource.h>
#include <pqServer.h>
#include <pqView.h>

#include <vtkNew.h>
#include <vtkSMProxyIterator.h>
#include <vtkSMRenderViewProxy.h>
#include <vtkSMSourceProxy.h>
#include <vtkSMViewProxy.h>

namespace tomviz {

ActiveObjects::ActiveObjects() : QObject()
{
  connect(&pqActiveObjects::instance(), SIGNAL(viewChanged(pqView*)),
          SLOT(viewChanged(pqView*)));
  connect(&ModuleManager::instance(), SIGNAL(dataSourceRemoved(DataSource*)),
          SLOT(dataSourceRemoved(DataSource*)));
  connect(&ModuleManager::instance(), SIGNAL(moduleRemoved(Module*)),
          SLOT(moduleRemoved(Module*)));
}

ActiveObjects::~ActiveObjects()
{
}

ActiveObjects& ActiveObjects::instance()
{
  static ActiveObjects theInstance;
  return theInstance;
}

void ActiveObjects::setActiveView(vtkSMViewProxy* view)
{
  pqActiveObjects::instance().setActiveView(tomviz::convert<pqView*>(view));
}

vtkSMViewProxy* ActiveObjects::activeView() const
{
  pqView* view = pqActiveObjects::instance().activeView();
  return view ? view->getViewProxy() : nullptr;
}

void ActiveObjects::viewChanged(pqView* view)
{
  emit viewChanged(view ? view->getViewProxy() : nullptr);
}

void ActiveObjects::dataSourceRemoved(DataSource* ds)
{
  if (m_activeDataSource == ds) {
    setActiveDataSource(nullptr);
  }
}

void ActiveObjects::moduleRemoved(Module* mdl)
{
  if (m_activeModule == mdl) {
    setActiveModule(nullptr);
  }
}

void ActiveObjects::setActiveDataSource(DataSource* source)
{
  if (m_activeDataSource != source) {
    if (m_activeDataSource) {
      disconnect(m_activeDataSource, SIGNAL(dataChanged()), this,
                 SLOT(dataSourceChanged()));
    }
    if (source) {
      connect(source, SIGNAL(dataChanged()), this, SLOT(dataSourceChanged()));
      m_activeDataSourceType = source->type();
    }
    m_activeDataSource = source;
    emit dataSourceChanged(m_activeDataSource);
  }
  emit dataSourceActivated(m_activeDataSource);
}

void ActiveObjects::dataSourceChanged()
{
  if (m_activeDataSource->type() != m_activeDataSourceType) {
    m_activeDataSourceType = m_activeDataSource->type();
    emit dataSourceChanged(m_activeDataSource);
  }
}

vtkSMSessionProxyManager* ActiveObjects::proxyManager() const
{
  pqServer* server = pqActiveObjects::instance().activeServer();
  return server ? server->proxyManager() : nullptr;
}

void ActiveObjects::setActiveModule(Module* module)
{
  if (module) {
    setActiveView(module->view());
    setActiveDataSource(module->dataSource());
  }
  if (m_activeModule != module) {
    m_activeModule = module;
    emit moduleChanged(module);
  }
  emit moduleActivated(module);
}

void ActiveObjects::setActiveOperator(Operator* op)
{
  if (op) {
    setActiveDataSource(op->dataSource());
  }
  if (m_activeOperator != op) {
    m_activeOperator = op;
    emit operatorChanged(op);
  }
  emit operatorActivated(op);
}

void ActiveObjects::createRenderViewIfNeeded()
{
  vtkNew<vtkSMProxyIterator> iter;
  iter->SetSessionProxyManager(proxyManager());
  iter->SetModeToOneGroup();
  for (iter->Begin("views"); !iter->IsAtEnd(); iter->Next()) {
    vtkSMRenderViewProxy* renderView =
      vtkSMRenderViewProxy::SafeDownCast(iter->GetProxy());
    if (renderView) {
      return;
    }
  }

  // If we get here, there was no existing view, so create one.
  pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
  pqServer* server = pqApplicationCore::instance()->getActiveServer();
  builder->createView("RenderView", server);
}

void ActiveObjects::setActiveViewToFirstRenderView()
{
  vtkNew<vtkSMProxyIterator> iter;
  iter->SetSessionProxyManager(proxyManager());
  iter->SetModeToOneGroup();
  for (iter->Begin("views"); !iter->IsAtEnd(); iter->Next()) {
    vtkSMRenderViewProxy* renderView =
      vtkSMRenderViewProxy::SafeDownCast(iter->GetProxy());
    if (renderView) {
      setActiveView(renderView);
      break;
    }
  }
}

void ActiveObjects::setMoveObjectsMode(bool moveObjectsOn)
{
  if (m_moveObjectsEnabled != moveObjectsOn) {
    m_moveObjectsEnabled = moveObjectsOn;
    emit moveObjectsModeChanged(moveObjectsOn);
  }
}

void ActiveObjects::renderAllViews()
{
  pqApplicationCore::instance()->render();
}

} // end of namespace tomviz
<|endoftext|>


<commit_before>/******************************************************************************
  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "ModuleOutline.h"

#include "DataSource.h"
#include "Utilities.h"
#include "pqProxiesWidget.h"
#include "vtkNew.h"
#include "vtkSMParaViewPipelineControllerWithRendering.h"
#include "vtkSMProperty.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMSessionProxyManager.h"
#include "vtkSMSourceProxy.h"
#include "vtkSMViewProxy.h"
#include "vtkSmartPointer.h"
#include <pqColorChooserButton.h>
#include <vtkGridAxes3DActor.h>
#include <vtkPVRenderView.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkTextProperty.h>

#include <QCheckBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QVBoxLayout>

namespace tomviz {

using pugi::xml_attribute;
using pugi::xml_node;

ModuleOutline::ModuleOutline(QObject* parentObject) : Superclass(parentObject)
{
}

ModuleOutline::~ModuleOutline()
{
  this->finalize();
}

QIcon ModuleOutline::icon() const
{
  return QIcon(":/icons/pqProbeLocation.png");
}

bool ModuleOutline::initialize(DataSource* data, vtkSMViewProxy* vtkView)
{
  if (!this->Superclass::initialize(data, vtkView)) {
    return false;
  }

  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;

  vtkSMSessionProxyManager* pxm = data->producer()->GetSessionProxyManager();

  // Create the outline filter.
  vtkSmartPointer<vtkSMProxy> proxy;
  proxy.TakeReference(pxm->NewProxy("filters", "OutlineFilter"));

  this->OutlineFilter = vtkSMSourceProxy::SafeDownCast(proxy);
  Q_ASSERT(this->OutlineFilter);
  controller->PreInitializeProxy(this->OutlineFilter);
  vtkSMPropertyHelper(this->OutlineFilter, "Input").Set(data->producer());
  controller->PostInitializeProxy(this->OutlineFilter);
  controller->RegisterPipelineProxy(this->OutlineFilter);

  // Create the representation for it.
  this->OutlineRepresentation =
    controller->Show(this->OutlineFilter, 0, vtkView);
  vtkSMPropertyHelper(this->OutlineRepresentation, "Position")
    .Set(data->displayPosition(), 3);
  vtkSMPropertyHelper(this->OutlineRepresentation, "DiffuseColor")
    .Set(offWhite, 3);
  Q_ASSERT(this->OutlineRepresentation);
  // vtkSMPropertyHelper(this->OutlineRepresentation,
  //                    "Representation").Set("Outline");
  this->OutlineRepresentation->UpdateVTKObjects();

  // Give the proxy a friendly name for the GUI/Python world.
  if (auto p = convert<pqProxy*>(proxy)) {
    p->rename(label());
  }

  // Init the grid axes
  initializeGridAxes(data, vtkView);

  return true;
}

bool ModuleOutline::finalize()
{
  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
  controller->UnRegisterProxy(this->OutlineRepresentation);
  controller->UnRegisterProxy(this->OutlineFilter);

  if (m_view) {
    m_view->GetRenderer()->RemoveActor(m_gridAxes.Get());
  }

  this->OutlineFilter = nullptr;
  this->OutlineRepresentation = nullptr;
  return true;
}

bool ModuleOutline::serialize(pugi::xml_node& ns) const
{
  xml_node rootNode = ns.append_child("properties");

  xml_node visibilityNode = rootNode.append_child("visibility");
  visibilityNode.append_attribute("enabled") = visibility();

  xml_node gridAxesNode = rootNode.append_child("grid_axes");
  gridAxesNode.append_attribute("enabled") = m_gridAxes->GetVisibility() > 0;

  xml_node color = gridAxesNode.append_child("color");
  double rgb[3];
  m_gridAxes->GetProperty()->GetDiffuseColor(rgb);
  color.append_attribute("r") = rgb[0];
  color.append_attribute("g") = rgb[1];
  color.append_attribute("b") = rgb[2];

  return true;
}

bool ModuleOutline::deserialize(const pugi::xml_node& ns)
{
  xml_node rootNode = ns.child("properties");
  if (!rootNode) {
    return false;
  }

  xml_node node = rootNode.child("visibility");
  if (node) {
    xml_attribute att = node.attribute("enabled");
    if (att) {
      setVisibility(att.as_bool());
    }
  }

  node = rootNode.child("grid_axes");
  if (node) {
    xml_attribute att = node.attribute("enabled");
    if (att) {
      m_gridAxes->SetVisibility(att.as_bool() ? 1 : 0);
    }
    xml_node color = node.child("color");
    if (color) {
      double rgb[3];
      att = color.attribute("r");
      if (att) {
        rgb[0] = att.as_double();
      }
      att = color.attribute("g");
      if (att) {
        rgb[1] = att.as_double();
      }
      att = color.attribute("b");
      if (att) {
        rgb[2] = att.as_double();
      }
      updateGridAxesColor(rgb);
    }

  }

  return Module::deserialize(ns);
}

bool ModuleOutline::setVisibility(bool val)
{
  Q_ASSERT(this->OutlineRepresentation);
  vtkSMPropertyHelper(this->OutlineRepresentation, "Visibility")
    .Set(val ? 1 : 0);
  this->OutlineRepresentation->UpdateVTKObjects();
  m_gridAxes->SetVisibility(val ? 1 : 0);
  return true;
}

bool ModuleOutline::visibility() const
{
  if (this->OutlineRepresentation) {
    return vtkSMPropertyHelper(this->OutlineRepresentation, "Visibility")
             .GetAsInt() != 0;
  } else {
    return false;
  }
}

void ModuleOutline::addToPanel(QWidget* panel)
{
  Q_ASSERT(panel && this->OutlineRepresentation);

  if (panel->layout()) {
    delete panel->layout();
  }

  QHBoxLayout* layout = new QHBoxLayout;
  QLabel* label = new QLabel("Color");
  layout->addWidget(label);
  layout->addStretch();
  pqColorChooserButton* colorSelector = new pqColorChooserButton(panel);
  colorSelector->setShowAlphaChannel(false);
  layout->addWidget(colorSelector);

  QHBoxLayout* gridAxesLayout = new QHBoxLayout;
  QCheckBox* showAxesGrid = new QCheckBox(QString("Show Axes Grid"));
  showAxesGrid->setChecked(m_gridAxes->GetVisibility() == 1);

  connect(showAxesGrid, &QCheckBox::stateChanged, this, [this](int state) {
    this->m_gridAxes->SetVisibility(state == Qt::Checked);
    emit this->renderNeeded();
  });

  gridAxesLayout->addWidget(showAxesGrid);

  QVBoxLayout* panelLayout = new QVBoxLayout;
  panelLayout->addItem(layout);
  panelLayout->addItem(gridAxesLayout);
  panelLayout->addStretch();
  panel->setLayout(panelLayout);

  m_links.addPropertyLink(
    colorSelector, "chosenColorRgbF", SIGNAL(chosenColorChanged(const QColor&)),
    this->OutlineRepresentation,
    this->OutlineRepresentation->GetProperty("DiffuseColor"));

  this->connect(colorSelector, &pqColorChooserButton::chosenColorChanged, [this](const QColor& color) {
    double rgb[3];
    rgb[0] = color.redF();
    rgb[1] = color.greenF();
    rgb[2] = color.blueF();
    updateGridAxesColor(rgb);

  });
  this->connect(colorSelector, &pqColorChooserButton::chosenColorChanged, this,
                &ModuleOutline::dataUpdated);
}

void ModuleOutline::dataUpdated()
{
  m_links.accept();
  emit this->renderNeeded();
}

void ModuleOutline::dataSourceMoved(double newX, double newY, double newZ)
{
  double pos[3] = { newX, newY, newZ };
  vtkSMPropertyHelper(this->OutlineRepresentation, "Position").Set(pos, 3);
  this->OutlineRepresentation->UpdateVTKObjects();
}

//-----------------------------------------------------------------------------
bool ModuleOutline::isProxyPartOfModule(vtkSMProxy* proxy)
{
  return (proxy == this->OutlineFilter.Get()) ||
         (proxy == this->OutlineRepresentation.Get());
}

std::string ModuleOutline::getStringForProxy(vtkSMProxy* proxy)
{
  if (proxy == this->OutlineFilter.Get()) {
    return "Outline";
  } else if (proxy == this->OutlineRepresentation.Get()) {
    return "Representation";
  } else {
    qWarning("Unknown proxy passed to module outline in save animation");
    return "";
  }
}

vtkSMProxy* ModuleOutline::getProxyForString(const std::string& str)
{
  if (str == "Outline") {
    return this->OutlineFilter.Get();
  } else if (str == "Representation") {
    return this->OutlineRepresentation.Get();
  } else {
    return nullptr;
  }
}

void ModuleOutline::updateGridAxesBounds(DataSource* dataSource)
{
  Q_ASSERT(dataSource);
  double bounds[6];
  dataSource->getBounds(bounds);
  m_gridAxes->SetGridBounds(bounds);
}
void ModuleOutline::initializeGridAxes(DataSource* data,
                                       vtkSMViewProxy* vtkView)
{

  updateGridAxesBounds(data);
  m_gridAxes->SetVisibility(0);

  // Work around a bug in vtkGridAxes3DActor. GetProperty() returns the
  // vtkProperty associated with a single face, so to get a property associated
  // with all the faces, we need to create a new one and set it.
  vtkNew<vtkProperty> prop;
  prop->DeepCopy(m_gridAxes->GetProperty());
  this->m_gridAxes->SetProperty(prop.Get());

  // Set the titles
  updateGridAxesUnit(data);

  m_view = vtkPVRenderView::SafeDownCast(vtkView->GetClientSideView());
  m_view->GetRenderer()->AddActor(m_gridAxes.Get());

  connect(data, &DataSource::dataPropertiesChanged, this, [this]() {
    auto dataSource = qobject_cast<DataSource*>(sender());
    this->updateGridAxesBounds(dataSource);
    this->updateGridAxesUnit(dataSource);
    dataSource->producer()->MarkModified(nullptr);
    dataSource->producer()->UpdatePipeline();
    emit this->renderNeeded();

  });
}

void ModuleOutline::updateGridAxesColor(double *color)
{
  for (int i = 0; i < 6; i++) {
    vtkNew<vtkTextProperty> prop;
    prop->SetColor(color);
    m_gridAxes->SetTitleTextProperty(i, prop.Get());
    m_gridAxes->SetLabelTextProperty(i, prop.Get());
  }
  m_gridAxes->GetProperty()->SetDiffuseColor(color);
  vtkSMPropertyHelper(this->OutlineRepresentation, "DiffuseColor").Set(color, 3);
  this->OutlineRepresentation->UpdateVTKObjects();
}

void ModuleOutline::updateGridAxesUnit(DataSource* dataSource)
{
  QString xTitle = QString("X (%1)").arg(dataSource->getUnits(0));
  QString yTitle = QString("Y (%1)").arg(dataSource->getUnits(1));
  QString zTitle = QString("Z (%1)").arg(dataSource->getUnits(2));
  m_gridAxes->SetXTitle(xTitle.toUtf8().data());
  m_gridAxes->SetYTitle(yTitle.toUtf8().data());
  m_gridAxes->SetZTitle(zTitle.toUtf8().data());
}

} // end of namespace tomviz
<commit_msg>Ensure axes grid moves with datasource<commit_after>/******************************************************************************
  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "ModuleOutline.h"

#include "DataSource.h"
#include "Utilities.h"
#include "pqProxiesWidget.h"
#include "vtkNew.h"
#include "vtkSMParaViewPipelineControllerWithRendering.h"
#include "vtkSMProperty.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMSessionProxyManager.h"
#include "vtkSMSourceProxy.h"
#include "vtkSMViewProxy.h"
#include "vtkSmartPointer.h"
#include <pqColorChooserButton.h>
#include <vtkGridAxes3DActor.h>
#include <vtkPVRenderView.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkTextProperty.h>

#include <QCheckBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QVBoxLayout>

namespace tomviz {

using pugi::xml_attribute;
using pugi::xml_node;

ModuleOutline::ModuleOutline(QObject* parentObject) : Superclass(parentObject)
{
}

ModuleOutline::~ModuleOutline()
{
  this->finalize();
}

QIcon ModuleOutline::icon() const
{
  return QIcon(":/icons/pqProbeLocation.png");
}

bool ModuleOutline::initialize(DataSource* data, vtkSMViewProxy* vtkView)
{
  if (!this->Superclass::initialize(data, vtkView)) {
    return false;
  }

  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;

  vtkSMSessionProxyManager* pxm = data->producer()->GetSessionProxyManager();

  // Create the outline filter.
  vtkSmartPointer<vtkSMProxy> proxy;
  proxy.TakeReference(pxm->NewProxy("filters", "OutlineFilter"));

  this->OutlineFilter = vtkSMSourceProxy::SafeDownCast(proxy);
  Q_ASSERT(this->OutlineFilter);
  controller->PreInitializeProxy(this->OutlineFilter);
  vtkSMPropertyHelper(this->OutlineFilter, "Input").Set(data->producer());
  controller->PostInitializeProxy(this->OutlineFilter);
  controller->RegisterPipelineProxy(this->OutlineFilter);

  // Create the representation for it.
  this->OutlineRepresentation =
    controller->Show(this->OutlineFilter, 0, vtkView);
  vtkSMPropertyHelper(this->OutlineRepresentation, "Position")
    .Set(data->displayPosition(), 3);
  vtkSMPropertyHelper(this->OutlineRepresentation, "DiffuseColor")
    .Set(offWhite, 3);
  Q_ASSERT(this->OutlineRepresentation);
  // vtkSMPropertyHelper(this->OutlineRepresentation,
  //                    "Representation").Set("Outline");
  this->OutlineRepresentation->UpdateVTKObjects();

  // Give the proxy a friendly name for the GUI/Python world.
  if (auto p = convert<pqProxy*>(proxy)) {
    p->rename(label());
  }

  // Init the grid axes
  initializeGridAxes(data, vtkView);

  return true;
}

bool ModuleOutline::finalize()
{
  vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
  controller->UnRegisterProxy(this->OutlineRepresentation);
  controller->UnRegisterProxy(this->OutlineFilter);

  if (m_view) {
    m_view->GetRenderer()->RemoveActor(m_gridAxes.Get());
  }

  this->OutlineFilter = nullptr;
  this->OutlineRepresentation = nullptr;
  return true;
}

bool ModuleOutline::serialize(pugi::xml_node& ns) const
{
  xml_node rootNode = ns.append_child("properties");

  xml_node visibilityNode = rootNode.append_child("visibility");
  visibilityNode.append_attribute("enabled") = visibility();

  xml_node gridAxesNode = rootNode.append_child("grid_axes");
  gridAxesNode.append_attribute("enabled") = m_gridAxes->GetVisibility() > 0;

  xml_node color = gridAxesNode.append_child("color");
  double rgb[3];
  m_gridAxes->GetProperty()->GetDiffuseColor(rgb);
  color.append_attribute("r") = rgb[0];
  color.append_attribute("g") = rgb[1];
  color.append_attribute("b") = rgb[2];

  return true;
}

bool ModuleOutline::deserialize(const pugi::xml_node& ns)
{
  xml_node rootNode = ns.child("properties");
  if (!rootNode) {
    return false;
  }

  xml_node node = rootNode.child("visibility");
  if (node) {
    xml_attribute att = node.attribute("enabled");
    if (att) {
      setVisibility(att.as_bool());
    }
  }

  node = rootNode.child("grid_axes");
  if (node) {
    xml_attribute att = node.attribute("enabled");
    if (att) {
      m_gridAxes->SetVisibility(att.as_bool() ? 1 : 0);
    }
    xml_node color = node.child("color");
    if (color) {
      double rgb[3];
      att = color.attribute("r");
      if (att) {
        rgb[0] = att.as_double();
      }
      att = color.attribute("g");
      if (att) {
        rgb[1] = att.as_double();
      }
      att = color.attribute("b");
      if (att) {
        rgb[2] = att.as_double();
      }
      updateGridAxesColor(rgb);
    }

  }

  return Module::deserialize(ns);
}

bool ModuleOutline::setVisibility(bool val)
{
  Q_ASSERT(this->OutlineRepresentation);
  vtkSMPropertyHelper(this->OutlineRepresentation, "Visibility")
    .Set(val ? 1 : 0);
  this->OutlineRepresentation->UpdateVTKObjects();
  m_gridAxes->SetVisibility(val ? 1 : 0);
  return true;
}

bool ModuleOutline::visibility() const
{
  if (this->OutlineRepresentation) {
    return vtkSMPropertyHelper(this->OutlineRepresentation, "Visibility")
             .GetAsInt() != 0;
  } else {
    return false;
  }
}

void ModuleOutline::addToPanel(QWidget* panel)
{
  Q_ASSERT(panel && this->OutlineRepresentation);

  if (panel->layout()) {
    delete panel->layout();
  }

  QHBoxLayout* layout = new QHBoxLayout;
  QLabel* label = new QLabel("Color");
  layout->addWidget(label);
  layout->addStretch();
  pqColorChooserButton* colorSelector = new pqColorChooserButton(panel);
  colorSelector->setShowAlphaChannel(false);
  layout->addWidget(colorSelector);

  QHBoxLayout* gridAxesLayout = new QHBoxLayout;
  QCheckBox* showAxesGrid = new QCheckBox(QString("Show Axes Grid"));
  showAxesGrid->setChecked(m_gridAxes->GetVisibility() == 1);

  connect(showAxesGrid, &QCheckBox::stateChanged, this, [this](int state) {
    this->m_gridAxes->SetVisibility(state == Qt::Checked);
    emit this->renderNeeded();
  });

  gridAxesLayout->addWidget(showAxesGrid);

  QVBoxLayout* panelLayout = new QVBoxLayout;
  panelLayout->addItem(layout);
  panelLayout->addItem(gridAxesLayout);
  panelLayout->addStretch();
  panel->setLayout(panelLayout);

  m_links.addPropertyLink(
    colorSelector, "chosenColorRgbF", SIGNAL(chosenColorChanged(const QColor&)),
    this->OutlineRepresentation,
    this->OutlineRepresentation->GetProperty("DiffuseColor"));

  this->connect(colorSelector, &pqColorChooserButton::chosenColorChanged, [this](const QColor& color) {
    double rgb[3];
    rgb[0] = color.redF();
    rgb[1] = color.greenF();
    rgb[2] = color.blueF();
    updateGridAxesColor(rgb);

  });
  this->connect(colorSelector, &pqColorChooserButton::chosenColorChanged, this,
                &ModuleOutline::dataUpdated);
}

void ModuleOutline::dataUpdated()
{
  m_links.accept();
  emit this->renderNeeded();
}

void ModuleOutline::dataSourceMoved(double newX, double newY, double newZ)
{
  double pos[3] = { newX, newY, newZ };
  vtkSMPropertyHelper(this->OutlineRepresentation, "Position").Set(pos, 3);
  this->OutlineRepresentation->UpdateVTKObjects();
  this->m_gridAxes->SetPosition(newX, newY, newZ);
}

//-----------------------------------------------------------------------------
bool ModuleOutline::isProxyPartOfModule(vtkSMProxy* proxy)
{
  return (proxy == this->OutlineFilter.Get()) ||
         (proxy == this->OutlineRepresentation.Get());
}

std::string ModuleOutline::getStringForProxy(vtkSMProxy* proxy)
{
  if (proxy == this->OutlineFilter.Get()) {
    return "Outline";
  } else if (proxy == this->OutlineRepresentation.Get()) {
    return "Representation";
  } else {
    qWarning("Unknown proxy passed to module outline in save animation");
    return "";
  }
}

vtkSMProxy* ModuleOutline::getProxyForString(const std::string& str)
{
  if (str == "Outline") {
    return this->OutlineFilter.Get();
  } else if (str == "Representation") {
    return this->OutlineRepresentation.Get();
  } else {
    return nullptr;
  }
}

void ModuleOutline::updateGridAxesBounds(DataSource* dataSource)
{
  Q_ASSERT(dataSource);
  double bounds[6];
  dataSource->getBounds(bounds);
  m_gridAxes->SetGridBounds(bounds);
}
void ModuleOutline::initializeGridAxes(DataSource* data,
                                       vtkSMViewProxy* vtkView)
{

  updateGridAxesBounds(data);
  m_gridAxes->SetVisibility(0);

  // Work around a bug in vtkGridAxes3DActor. GetProperty() returns the
  // vtkProperty associated with a single face, so to get a property associated
  // with all the faces, we need to create a new one and set it.
  vtkNew<vtkProperty> prop;
  prop->DeepCopy(m_gridAxes->GetProperty());
  this->m_gridAxes->SetProperty(prop.Get());

  // Set the titles
  updateGridAxesUnit(data);

  m_view = vtkPVRenderView::SafeDownCast(vtkView->GetClientSideView());
  m_view->GetRenderer()->AddActor(m_gridAxes.Get());

  connect(data, &DataSource::dataPropertiesChanged, this, [this]() {
    auto dataSource = qobject_cast<DataSource*>(sender());
    this->updateGridAxesBounds(dataSource);
    this->updateGridAxesUnit(dataSource);
    dataSource->producer()->MarkModified(nullptr);
    dataSource->producer()->UpdatePipeline();
    emit this->renderNeeded();

  });
}

void ModuleOutline::updateGridAxesColor(double *color)
{
  for (int i = 0; i < 6; i++) {
    vtkNew<vtkTextProperty> prop;
    prop->SetColor(color);
    m_gridAxes->SetTitleTextProperty(i, prop.Get());
    m_gridAxes->SetLabelTextProperty(i, prop.Get());
  }
  m_gridAxes->GetProperty()->SetDiffuseColor(color);
  vtkSMPropertyHelper(this->OutlineRepresentation, "DiffuseColor").Set(color, 3);
  this->OutlineRepresentation->UpdateVTKObjects();
}

void ModuleOutline::updateGridAxesUnit(DataSource* dataSource)
{
  QString xTitle = QString("X (%1)").arg(dataSource->getUnits(0));
  QString yTitle = QString("Y (%1)").arg(dataSource->getUnits(1));
  QString zTitle = QString("Z (%1)").arg(dataSource->getUnits(2));
  m_gridAxes->SetXTitle(xTitle.toUtf8().data());
  m_gridAxes->SetYTitle(yTitle.toUtf8().data());
  m_gridAxes->SetZTitle(zTitle.toUtf8().data());
}

} // end of namespace tomviz
<|endoftext|>


<commit_before>/*
Copyright (C) 2016 iNuron NV

This file is part of Open vStorage Open Source Edition (OSE), as available from

    http://www.openvstorage.org and
    http://www.openvstorage.com.

This file is free software; you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License v3 (GNU AGPLv3)
as published by the Free Software Foundation, in version 3 as it comes
in the <LICENSE.txt> file of the Open vStorage OSE distribution.

Open vStorage is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY of any kind.
*/

#include "tcp_transport.h"
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>

namespace alba {
namespace transport {

using std::string;
using std::vector;
using std::tuple;
using boost::optional;
using llio::message;
using llio::message_builder;
using namespace boost::asio;

#define _convert(t)                                                            \
  boost::posix_time::milliseconds(                                             \
      std::chrono::duration_cast<std::chrono::milliseconds>(t).count())
#define _NEVER boost::posix_time::pos_infin

/*
  using boost::asio::ip::tcp::iostream is comfy,
  but results in using (hardcoded buffers of size 512),
  and thus way too many syscalls for reading 4KB.

  So we move to boost::asio::ip::tcp::socket

 */

TCP_transport::TCP_transport(const string &ip, const string &port,
                             const std::chrono::steady_clock::duration &timeout)
    : _io_service{}, _socket(_io_service), _deadline(_io_service),
      _timeout(_convert(timeout)) {
  ALBA_LOG(INFO, "TCP_transport(" << ip << ", " << port << ")");
  _deadline.expires_from_now(_timeout);
  _check_deadline();

  int port_as_int = std::stoi(port);
  auto addr = ip::address::from_string(ip);
  auto sa = ip::tcp::endpoint(addr, port_as_int);

  boost::system::error_code ec = boost::asio::error::would_block;
  auto handler = [&](const boost::system::error_code &x) -> void {
    ALBA_LOG(DEBUG, "connect handler called ec=" << x);
    ec = x;
  };
  _socket.async_connect(sa, handler);

  do
    _io_service.run_one();
  while (ec == boost::asio::error::would_block);

  if (ec || !_socket.is_open())
    throw boost::system::system_error(
        ec ? ec : boost::asio::error::operation_aborted);

  const ip::tcp::no_delay no_delay(true);
  _socket.set_option(no_delay);
  _deadline.expires_at(_NEVER);
}

void TCP_transport::expires_from_now(
    const std::chrono::steady_clock::duration &timeout) {
  ALBA_LOG(DEBUG, "TCP_transport::expires_from_now("
                      << _timeout.total_milliseconds() << " ms)");
  _timeout = _convert(timeout);
}

void TCP_transport::write_exact(const char *buf, int len) {
  boost::asio::const_buffers_1 buffer(buf, len);
  // boost::asio::write(_socket, buffer);

  //_io_service.reset();
  _deadline.expires_from_now(_timeout);
  boost::system::error_code ec = boost::asio::error::would_block;

  auto handler = [&](const boost::system::error_code &x,
                     std::size_t len) -> void {
    ALBA_LOG(DEBUG, "write handler called: " << len << " bytes");
    ec = x;
  };
  boost::asio::async_write(_socket, buffer, handler);

  do {
    _io_service.run_one();
    ALBA_LOG(DEBUG, "ran once (write)");
  } while (ec == boost::asio::error::would_block);

  if (ec)
    throw boost::system::system_error(ec);
}

void TCP_transport::read_exact(char *buf, int len) {
  boost::asio::mutable_buffers_1 buffer(buf, len);
  // boost::asio::read(_socket, buffer);

  //_io_service.reset();
  _deadline.expires_from_now(_timeout);
  ALBA_LOG(DEBUG, "read, timeout is " << _timeout.total_milliseconds()
                                      << " ms");
  boost::system::error_code ec = boost::asio::error::would_block;

  auto handler = [&](const boost::system::error_code &x,
                     std::size_t len) -> void {
    ALBA_LOG(DEBUG, "read handler called: " << len << " bytes");
    ec = x;
  };
  boost::asio::async_read(_socket, buffer, handler);

  // Block until the asynchronous operation has completed.

  do {
    _io_service.run_one();
    ALBA_LOG(DEBUG, "ran once (read)");
  } while (ec == boost::asio::error::would_block);

  if (ec)
    throw boost::system::system_error(ec);
}

void TCP_transport::_check_deadline() {
  if (_deadline.expires_at() <= deadline_timer::traits_type::now()) {
    boost::system::error_code ignored_ec;
    _socket.close(ignored_ec);
    _deadline.expires_at(_NEVER);
  }
  _deadline.async_wait(
      boost::lambda::bind(&TCP_transport::_check_deadline, this));
}

TCP_transport::~TCP_transport() {
    boost::system::error_code ec;
    _socket.close(ec); // does not throw

}
}
}
<commit_msg>removed debug loggin from tcp_transport<commit_after>/*
Copyright (C) 2016 iNuron NV

This file is part of Open vStorage Open Source Edition (OSE), as available from

    http://www.openvstorage.org and
    http://www.openvstorage.com.

This file is free software; you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License v3 (GNU AGPLv3)
as published by the Free Software Foundation, in version 3 as it comes
in the <LICENSE.txt> file of the Open vStorage OSE distribution.

Open vStorage is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY of any kind.
*/

#include "tcp_transport.h"
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>

namespace alba {
namespace transport {

using std::string;
using std::vector;
using std::tuple;
using boost::optional;
using llio::message;
using llio::message_builder;
using namespace boost::asio;

#define _convert(t)                                                            \
  boost::posix_time::milliseconds(                                             \
      std::chrono::duration_cast<std::chrono::milliseconds>(t).count())
#define _NEVER boost::posix_time::pos_infin

/*
  using boost::asio::ip::tcp::iostream is comfy,
  but results in using (hardcoded buffers of size 512),
  and thus way too many syscalls for reading 4KB.

  So we move to boost::asio::ip::tcp::socket

 */

TCP_transport::TCP_transport(const string &ip, const string &port,
                             const std::chrono::steady_clock::duration &timeout)
    : _io_service{}, _socket(_io_service), _deadline(_io_service),
      _timeout(_convert(timeout)) {
  ALBA_LOG(INFO, "TCP_transport(" << ip << ", " << port << ")");
  _deadline.expires_from_now(_timeout);
  _check_deadline();

  int port_as_int = std::stoi(port);
  auto addr = ip::address::from_string(ip);
  auto sa = ip::tcp::endpoint(addr, port_as_int);

  boost::system::error_code ec = boost::asio::error::would_block;
  auto handler = [&](const boost::system::error_code &x) -> void {
    ec = x;
  };
  _socket.async_connect(sa, handler);

  do
    _io_service.run_one();
  while (ec == boost::asio::error::would_block);

  if (ec || !_socket.is_open())
    throw boost::system::system_error(
        ec ? ec : boost::asio::error::operation_aborted);

  const ip::tcp::no_delay no_delay(true);
  _socket.set_option(no_delay);
  _deadline.expires_at(_NEVER);
}

void TCP_transport::expires_from_now(
    const std::chrono::steady_clock::duration &timeout) {
  _timeout = _convert(timeout);
}

void TCP_transport::write_exact(const char *buf, int len) {
  boost::asio::const_buffers_1 buffer(buf, len);
  // boost::asio::write(_socket, buffer);

  //_io_service.reset();
  _deadline.expires_from_now(_timeout);
  boost::system::error_code ec = boost::asio::error::would_block;

  auto handler = [&](const boost::system::error_code &x,
                     std::size_t /*len */) -> void {
    ec = x;
  };
  boost::asio::async_write(_socket, buffer, handler);

  do {
    _io_service.run_one();
  } while (ec == boost::asio::error::would_block);

  if (ec)
    throw boost::system::system_error(ec);
}

void TCP_transport::read_exact(char *buf, int len) {
  boost::asio::mutable_buffers_1 buffer(buf, len);
  // boost::asio::read(_socket, buffer);

  //_io_service.reset();
  _deadline.expires_from_now(_timeout);
  boost::system::error_code ec = boost::asio::error::would_block;

  auto handler = [&](const boost::system::error_code &x,
                     std::size_t /* len*/) -> void {
    ec = x;
  };
  boost::asio::async_read(_socket, buffer, handler);

  // Block until the asynchronous operation has completed.

  do {
    _io_service.run_one();
  } while (ec == boost::asio::error::would_block);

  if (ec)
    throw boost::system::system_error(ec);
}

void TCP_transport::_check_deadline() {
  if (_deadline.expires_at() <= deadline_timer::traits_type::now()) {
    boost::system::error_code ignored_ec;
    _socket.close(ignored_ec);
    _deadline.expires_at(_NEVER);
  }
  _deadline.async_wait(
      boost::lambda::bind(&TCP_transport::_check_deadline, this));
}

TCP_transport::~TCP_transport() {
    boost::system::error_code ec;
    _socket.close(ec); // does not throw

}
}
}
<|endoftext|>


<commit_before>#ifndef TOPPRA_ALGORITHM_HPP
#define TOPPRA_ALGORITHM_HPP

#include <stdexcept>
#include <toppra/constraint.hpp>
#include <toppra/geometric_path.hpp>
#include <toppra/solver.hpp>
#include <toppra/toppra.hpp>

namespace toppra {

/// Return code for Path Parametrization algorithm.
enum class ReturnCode {

  /// Success
  OK = 0,

  /// Unknown error
  ERR_UNKNOWN = 1,

  /// Fail during computing controllable sets. Problem might be infeasible.
  ERR_FAIL_CONTROLLABLE = 2,

  /// Fail during forward pass. Numerical error occured.
  ERR_FAIL_FORWARD_PASS = 3,

  /// Problem is not initialized
  ERR_UNINITIALIZED = 4,

  /// Fail to ocmpute feasible sets.
  ERR_FAIL_FEASIBLE = 5,
};

struct ParametrizationData {
  /// \brief Grid-points used for solving the discretized problem.
  /// The number of points must equal m_N + 1.
  Vector gridpoints;

  ///  Output parametrization (squared path velocity)
  Vector parametrization;

  Matrix controllable_sets;
  Matrix feasible_sets;

  ///  Return code of the algorithm.
  ReturnCode ret_code = ReturnCode::ERR_UNINITIALIZED;
};

/** \brief Base class for time parametrization algorithms.
 *
 */
class PathParametrizationAlgorithm {
 public:
  /** Construct the problem instance.
   *
   *  \param  constraints  List of constraints.
   *  \param  path  The geometric path.
   *
   */
  PathParametrizationAlgorithm(LinearConstraintPtrs constraints,
                               const GeometricPathPtr &path);

  /** \brief Set the level of discretization used by the solver.
   *
   * If is zero, will attempt to detect automatically the most suitable grid.
   */
  void setN(int N) { m_N = N; m_initialized = false; };

  /** \brief Set the gridpoints (points with the path intervals)
   *
   * If not set manually, then N equally distributed points is used.
   */
  void setGridpoints(const Vector& gridpoints);

  /** \brief Set the LP/QP solver
   *
   * Default to \ref solver::qpOASESWrapper
   */
  void solver(SolverPtr solver) { m_solver.swap(solver); };

  /** \brief Get output or result of algorithm.
   */
  const ParametrizationData& getParameterizationData() const { return m_data; };

  /** Compute the time parametrization of the given path.
   *
   * \param vel_start
   * \param vel_end
   * \return Return code.
   */
  virtual ReturnCode computePathParametrization(value_type vel_start = 0,
                                                value_type vel_end = 0);

  /** Compute the sets of feasible squared velocities.
   */
  ReturnCode computeFeasibleSets();

  /** Set initial bounds on \f$ \dot{s}^2.
   * This is helpfull when the solver encounters numerical issues.
   */
  void setInitialXBounds (const Bound& xbound)
  {
    m_initXBound = xbound;
  }

  virtual ~PathParametrizationAlgorithm() {}

 protected:
  /** \brief Select solver and gridpoints to use.
   *
   * This method implements a simple way to select gridpoints.
   */
  virtual void initialize();

  /** \brief Compute the forward pass.
   *
   * Derived class should provide a suitable forward pass function,
   * depending on the desired objective.
   */
  virtual ReturnCode computeForwardPass(value_type vel_start) = 0;

  /** Compute the sets of controllable squared path velocities.
   */
  ReturnCode computeControllableSets(const Bound &vel_ends);

  /** To be implemented in child method. */
  LinearConstraintPtrs m_constraints;
  GeometricPathPtr m_path;
  SolverPtr m_solver;

  /// Struct containing algorithm output.
  ParametrizationData m_data;

  /// \brief Number of segments in the discretized problems.
  /// See m_gridpoints for more information.
  int m_N = 100;

  int m_initialized = false;

  /** Set initial bounds on \f$ \dot{s}^2.
   * \sa setInitialXBounds
   * \todo The hard-coded bound below avoids numerical issues in LP / QP solvers
   * when \f$ x \f$ becomes too big. This issue should be addressed in the
   * solver wrapper themselfves as numerical behaviors is proper to each
   * individual solver.
   * See https://github.com/hungpham2511/toppra/issues/156
   */
  Bound m_initXBound = {0, 100};
};

}  // namespace toppra

#endif
<commit_msg>[cpp]Add a comment to explain about grid point selection<commit_after>#ifndef TOPPRA_ALGORITHM_HPP
#define TOPPRA_ALGORITHM_HPP

#include <stdexcept>
#include <toppra/constraint.hpp>
#include <toppra/geometric_path.hpp>
#include <toppra/solver.hpp>
#include <toppra/toppra.hpp>

namespace toppra {

/// Return code for Path Parametrization algorithm.
enum class ReturnCode {

  /// Success
  OK = 0,

  /// Unknown error
  ERR_UNKNOWN = 1,

  /// Fail during computing controllable sets. Problem might be infeasible.
  ERR_FAIL_CONTROLLABLE = 2,

  /// Fail during forward pass. Numerical error occured.
  ERR_FAIL_FORWARD_PASS = 3,

  /// Problem is not initialized
  ERR_UNINITIALIZED = 4,

  /// Fail to ocmpute feasible sets.
  ERR_FAIL_FEASIBLE = 5,
};

struct ParametrizationData {
  /// \brief Grid-points used for solving the discretized problem.
  /// The number of points must equal m_N + 1.
  Vector gridpoints;

  ///  Output parametrization (squared path velocity)
  Vector parametrization;

  Matrix controllable_sets;
  Matrix feasible_sets;

  ///  Return code of the algorithm.
  ReturnCode ret_code = ReturnCode::ERR_UNINITIALIZED;
};

/** \brief Base class for time parametrization algorithms.
 *
 */
class PathParametrizationAlgorithm {
 public:
  /** Construct the problem instance.
   *
   *  \param  constraints  List of constraints.
   *  \param  path  The geometric path.
   *
   */
  PathParametrizationAlgorithm(LinearConstraintPtrs constraints,
                               const GeometricPathPtr &path);

  /** \brief Set the level of discretization used by the solver.
   *
   * If is zero, will attempt to detect automatically the most
   * suitable grid.
   *
   * TODO: Automatic gridpoint selection is not implemented in the CPP
   * API.
   */
  void setN(int N) { m_N = N; m_initialized = false; };

  /** \brief Set the gridpoints (points with the path intervals)
   *
   * If not set manually, then N equally distributed points is used.
   */
  void setGridpoints(const Vector& gridpoints);

  /** \brief Set the LP/QP solver
   *
   * Default to \ref solver::qpOASESWrapper
   */
  void solver(SolverPtr solver) { m_solver.swap(solver); };

  /** \brief Get output or result of algorithm.
   */
  const ParametrizationData& getParameterizationData() const { return m_data; };

  /** Compute the time parametrization of the given path.
   *
   * \param vel_start
   * \param vel_end
   * \return Return code.
   */
  virtual ReturnCode computePathParametrization(value_type vel_start = 0,
                                                value_type vel_end = 0);

  /** Compute the sets of feasible squared velocities.
   */
  ReturnCode computeFeasibleSets();

  /** Set initial bounds on \f$ \dot{s}^2.
   * This is helpfull when the solver encounters numerical issues.
   */
  void setInitialXBounds (const Bound& xbound)
  {
    m_initXBound = xbound;
  }

  virtual ~PathParametrizationAlgorithm() {}

 protected:
  /** \brief Select solver and gridpoints to use.
   *
   * This method implements a simple way to select gridpoints.
   */
  virtual void initialize();

  /** \brief Compute the forward pass.
   *
   * Derived class should provide a suitable forward pass function,
   * depending on the desired objective.
   */
  virtual ReturnCode computeForwardPass(value_type vel_start) = 0;

  /** Compute the sets of controllable squared path velocities.
   */
  ReturnCode computeControllableSets(const Bound &vel_ends);

  /** To be implemented in child method. */
  LinearConstraintPtrs m_constraints;
  GeometricPathPtr m_path;
  SolverPtr m_solver;

  /// Struct containing algorithm output.
  ParametrizationData m_data;

  /// \brief Number of segments in the discretized problems.
  /// See m_gridpoints for more information.
  int m_N = 100;

  int m_initialized = false;

  /** Set initial bounds on \f$ \dot{s}^2.
   * \sa setInitialXBounds
   * \todo The hard-coded bound below avoids numerical issues in LP / QP solvers
   * when \f$ x \f$ becomes too big. This issue should be addressed in the
   * solver wrapper themselfves as numerical behaviors is proper to each
   * individual solver.
   * See https://github.com/hungpham2511/toppra/issues/156
   */
  Bound m_initXBound = {0, 100};
};

}  // namespace toppra

#endif
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil c-basic-offset: 3 -*- */
// vim:cindent:ts=3:sw=3:et:tw=80:sta:
/*************************************************************** cppdom-cpr beg
 *
 * cppdom was forked from the original xmlpp version 0.6 under the LGPL. This
 * new, branched xmlpp is under the same LGPL (of course) and is being
 * maintained by:
 *      Kevin Meinert   <subatomic@users.sourceforge.net>
 *      Allen Bierbaum  <allenb@users.sourceforge.net>
 *      Ben Scott       <nonchocoboy@users.sourceforge.net>
 *
 * -----------------------------------------------------------------
 *
 * xmlpp - an xml parser and validator written in C++
 * copyright (c) 2000-2001 Michael Fink
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ************************************************************ cppdom-cpr-end */
#include <stdexcept>

#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/TestResult.h>

#include <cppunit/extensions/MetricRegistry.h>
#include <cppunit/extensions/TestFactoryRegistry.h>

#include <cppunit/ui/text/TestRunner.h>

#include <cppdom/version.h>

#include <Suites.h>

std::string getHostname(void);

int main(int argc, char** argv)
{
   // Commandline parameter is the test path to use
   std::string test_path = (argc > 1) ? std::string(argv[1]) : "noninteractive";

   // Print out what version of GMTL we're testing.
   std::cout << "\nTesting CppDOM Version: " << cppdom::getVersion() << std::endl << std::endl;

   // -------- CONFIGURE METRIC REGISTRY ------- //
   CppUnit::MetricRegistry* metric_reg = CppUnit::MetricRegistry::instance();

   std::string metric_prefix = getHostname() + "/";
#ifdef _DEBUG
   metric_prefix += "Debug/";
#endif
#ifdef _OPT
   metric_prefix += "Opt/";
#endif

   std::cout << "Setting up metrics for host: " << getHostname() << std::endl;
   std::cout << "                     prefix: " << metric_prefix << std::endl;

   metric_reg->setPrefix(metric_prefix);
   metric_reg->setFilename("data/cppdom_metrics.txt");
   metric_reg->setMetric("Main/MetricTest", 1221.75f);

   //------------------------------------
   //  Test suites
   //------------------------------------
   CppUnit::TestFactoryRegistry& global_registry = CppUnit::TestFactoryRegistry::getRegistry();

   // noninteractive
   CppUnit::TestSuite* noninteractive_suite = new CppUnit::TestSuite("noninteractive");
   noninteractive_suite->addTest(global_registry.makeTest());

   // metric
   CppUnit::TestSuite* metric_suite = new CppUnit::TestSuite(cppdomtest::Suites::metric());
   metric_suite->addTest(CppUnit::TestFactoryRegistry::getRegistry(cppdomtest::Suites::metric()).makeTest());

   //------------------------------------
   // Test Runner
   //------------------------------------
   CppUnit::TextUi::TestRunner runner;

   // Make it use a compiler outputter
   CppUnit::Outputter* run_outputter =
      CppUnit::CompilerOutputter::defaultOutputter(&runner.result(), std::cout);
   runner.setOutputter(run_outputter);

   // Add a listener that prints the test names as the tests progress
   CppUnit::TestResult& result_event_manager = runner.eventManager();
   CppUnit::BriefTestProgressListener progress;
   result_event_manager.addListener(&progress);

   runner.addTest(noninteractive_suite);
   runner.addTest(metric_suite);

   //------------------------------------
   // Run Tests
   //------------------------------------
   bool success(false);

   try
   {
      std::cout << "Running " << test_path << std::endl;
      success = runner.run(test_path);
   }
   catch (std::invalid_argument& e)
   {
      // Test path was not resolved
      std::cerr   << std::endl
                  << "ERROR: " << e.what()
                  << std::endl;
      success = false;
   }

   return (success ? 0 : 1);
}

#ifdef WIN32

std::string getHostname(void)
{
   return "WindowBox";
}

#else

#include <sys/utsname.h>

std::string getHostname(void)
{
   struct utsname buffer;

   if ( uname(&buffer) == 0 )
   {
      char* temp;
      temp = strchr(buffer.nodename, '.');

      // If the node name contains the full host, dots and all, truncate it
      // at the first dot.
      if ( temp != NULL )
      {
         *temp = '\0';
      }

      return std::string(buffer.nodename);
   }
   else
   {
      return std::string("<hostname-lookup failed>");
   }
}
#endif
<commit_msg>include needed file<commit_after>/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil c-basic-offset: 3 -*- */
// vim:cindent:ts=3:sw=3:et:tw=80:sta:
/*************************************************************** cppdom-cpr beg
 *
 * cppdom was forked from the original xmlpp version 0.6 under the LGPL. This
 * new, branched xmlpp is under the same LGPL (of course) and is being
 * maintained by:
 *      Kevin Meinert   <subatomic@users.sourceforge.net>
 *      Allen Bierbaum  <allenb@users.sourceforge.net>
 *      Ben Scott       <nonchocoboy@users.sourceforge.net>
 *
 * -----------------------------------------------------------------
 *
 * xmlpp - an xml parser and validator written in C++
 * copyright (c) 2000-2001 Michael Fink
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ************************************************************ cppdom-cpr-end */
#include <stdexcept>

#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/TestResult.h>

#include <extensions/MetricRegistry.h>
#include <cppunit/extensions/TestFactoryRegistry.h>

#include <cppunit/ui/text/TestRunner.h>

#include <cppdom/version.h>

#include <Suites.h>

std::string getHostname(void);

int main(int argc, char** argv)
{
   // Commandline parameter is the test path to use
   std::string test_path = (argc > 1) ? std::string(argv[1]) : "noninteractive";

   // Print out what version of GMTL we're testing.
   std::cout << "\nTesting CppDOM Version: " << cppdom::getVersion() << std::endl << std::endl;

   // -------- CONFIGURE METRIC REGISTRY ------- //
   CppUnit::MetricRegistry* metric_reg = CppUnit::MetricRegistry::instance();

   std::string metric_prefix = getHostname() + "/";
#ifdef _DEBUG
   metric_prefix += "Debug/";
#endif
#ifdef _OPT
   metric_prefix += "Opt/";
#endif

   std::cout << "Setting up metrics for host: " << getHostname() << std::endl;
   std::cout << "                     prefix: " << metric_prefix << std::endl;

   metric_reg->setPrefix(metric_prefix);
   metric_reg->setFilename("data/cppdom_metrics.txt");
   metric_reg->setMetric("Main/MetricTest", 1221.75f);

   //------------------------------------
   //  Test suites
   //------------------------------------
   CppUnit::TestFactoryRegistry& global_registry = CppUnit::TestFactoryRegistry::getRegistry();

   // noninteractive
   CppUnit::TestSuite* noninteractive_suite = new CppUnit::TestSuite("noninteractive");
   noninteractive_suite->addTest(global_registry.makeTest());

   // metric
   CppUnit::TestSuite* metric_suite = new CppUnit::TestSuite(cppdomtest::Suites::metric());
   metric_suite->addTest(CppUnit::TestFactoryRegistry::getRegistry(cppdomtest::Suites::metric()).makeTest());

   //------------------------------------
   // Test Runner
   //------------------------------------
   CppUnit::TextUi::TestRunner runner;

   // Make it use a compiler outputter
   CppUnit::Outputter* run_outputter =
      CppUnit::CompilerOutputter::defaultOutputter(&runner.result(), std::cout);
   runner.setOutputter(run_outputter);

   // Add a listener that prints the test names as the tests progress
   CppUnit::TestResult& result_event_manager = runner.eventManager();
   CppUnit::BriefTestProgressListener progress;
   result_event_manager.addListener(&progress);

   runner.addTest(noninteractive_suite);
   runner.addTest(metric_suite);

   //------------------------------------
   // Run Tests
   //------------------------------------
   bool success(false);

   try
   {
      std::cout << "Running " << test_path << std::endl;
      success = runner.run(test_path);
   }
   catch (std::invalid_argument& e)
   {
      // Test path was not resolved
      std::cerr   << std::endl
                  << "ERROR: " << e.what()
                  << std::endl;
      success = false;
   }

   return (success ? 0 : 1);
}

#ifdef WIN32

std::string getHostname(void)
{
   return "WindowBox";
}

#else

#include <sys/utsname.h>

std::string getHostname(void)
{
   struct utsname buffer;

   if ( uname(&buffer) == 0 )
   {
      char* temp;
      temp = strchr(buffer.nodename, '.');

      // If the node name contains the full host, dots and all, truncate it
      // at the first dot.
      if ( temp != NULL )
      {
         *temp = '\0';
      }

      return std::string(buffer.nodename);
   }
   else
   {
      return std::string("<hostname-lookup failed>");
   }
}
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "util/arena.h"
#include <assert.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#define BLOCK_SIZE 65536

namespace leveldb {

struct Arena::Block {
 public:
  Block()
    : next(NULL),
      rem(0),
      next_lower(NULL),
      next_upper(NULL),
      base(NULL),
      size(0) {
  }
  ~Block() throw () {
    uint32_t r = atomic::load_32_acquire(&rem);
    if (base) {
      munmap(base, size);
    }
  }

  Block* next;
  uint32_t rem;
  char* next_lower;
  char* next_upper;
  char* base;
  uint32_t size;
};

Arena::Arena()
  : align_((sizeof(void*) > 8) ? sizeof(void*) : 8),
    page_size_(getpagesize()),
    memory_usage_(),
    blocks_(),
    large_() {
  using namespace atomic;
  assert((align_ & (align_-1)) == 0); // Pointer size should be a power of 2
  store_64_release(&memory_usage_, sizeof(Block));
  Block* nb = NewBlock(1U << 16);
  store_ptr_release(&blocks_, nb);
  store_ptr_nobarrier(&large_, static_cast<Block*>(NULL));
  increment_64_nobarrier(&memory_usage_, sizeof(Block));
}

Arena::~Arena() throw () {
  using namespace atomic;
  memory_barrier();
  Block* list = load_ptr_acquire(&blocks_);
  while (list) {
    Block* tmp = load_ptr_acquire(&list->next);
    delete list;
    list = tmp;
  }
  list = load_ptr_acquire(&large_);
  while (list) {
    Block* tmp = load_ptr_acquire(&list->next);
    delete list;
    list = tmp;
  }
}

char* Arena::Allocate(size_t bytes) {
  using namespace atomic;
  assert(bytes > 0);
  if (bytes > BLOCK_SIZE >> 2) {
    return AllocateLarge(bytes);
  }
  while (true) {
    Block* b = load_ptr_acquire(&blocks_);
    uint32_t rem = load_32_acquire(&b->rem);
    uint32_t witness;
    while (rem >= bytes) {
      witness = compare_and_swap_32_acquire(&b->rem, rem, rem - bytes);
      if (witness == rem) {
        return AllocateFinalize(b, bytes);
      }
      rem = witness;
    }
    Block* nb = NewBlock(BLOCK_SIZE);
    store_ptr_release(&nb->next, b);
    if (compare_and_swap_ptr_fullbarrier(&blocks_, b, nb) != b) {
      delete nb;
    } else {
      increment_64_nobarrier(&memory_usage_, sizeof(Block));
    }
  }
}

char* Arena::AllocateAligned(size_t bytes) {
  uint64_t new_bytes = (bytes + (align_ - 1)) & ~(align_ - 1);
  char* result = Allocate(new_bytes);
  assert((reinterpret_cast<uintptr_t>(result) & (align_ - 1)) == 0);
  return result;
}

Arena::Block* Arena::NewBlock(size_t bytes) {
  using namespace atomic;
  const size_t sz = (bytes + page_size_ - 1) & ~(page_size_ - 1);
  assert(sz / page_size_ * page_size_ == sz);
  Block* nb = new Block();
  void* ptr = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  if (ptr == MAP_FAILED) {
    throw std::bad_alloc();
  }
  store_ptr_nobarrier(&nb->base, reinterpret_cast<char*>(ptr));
  store_ptr_nobarrier(&nb->next_lower, nb->base);
  store_ptr_nobarrier(&nb->next_upper, nb->base + sz);
  store_32_nobarrier(&nb->size, sz);
  store_32_release(&nb->rem, sz);
  return nb;
}

char* Arena::AllocateLarge(size_t bytes) {
  using namespace atomic;
  assert(bytes > 0);
  Block* nb = NewBlock(bytes);
  Block* b = load_ptr_acquire(&large_);
  Block* witness = NULL;
  store_ptr_release(&nb->next, b);
  while ((witness = compare_and_swap_ptr_fullbarrier(&large_, b, nb)) != b) {
    b = witness;
    store_ptr_release(&nb->next, b);
  }
  increment_64_nobarrier(&memory_usage_, sizeof(Block));
  return AllocateFinalize(nb, bytes);
}

char* Arena::AllocateFinalize(Block* b, size_t bytes) {
  using namespace atomic;
  char** p = NULL;
  ssize_t cas_diff = 0;
  ssize_t ret_diff = 0;
  uint64_t aligned = (bytes + (align_ - 1)) & ~(align_ - 1);
  if (bytes == aligned) {
    p = &b->next_upper;
    cas_diff = 0 - bytes;
    ret_diff = 0;
  } else {
    p = &b->next_lower;
    cas_diff = 0 + bytes;
    ret_diff = 0 - bytes;
  }
  char* expected = load_ptr_nobarrier(p);
  char* witness = NULL;
  while ((witness = compare_and_swap_ptr_nobarrier(p, expected, expected + cas_diff)) != expected) {
    expected = witness;
  }
  char* nl = load_ptr_nobarrier(&b->next_lower);
  char* nu = load_ptr_nobarrier(&b->next_upper);
  uint32_t x = load_32_nobarrier(&b->rem);
  assert(nl <= nu);
  assert(load_ptr_nobarrier(&b->next_lower) <=
         load_ptr_nobarrier(&b->next_upper));
  char* ret = expected + cas_diff + ret_diff;
  increment_64_nobarrier(&memory_usage_, bytes);
  return ret;
}

}  // namespace leveldb
<commit_msg>Support contrarian platforms that prefer MAP_ANON<commit_after>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "util/arena.h"
#include <assert.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#define BLOCK_SIZE 65536

#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif

namespace leveldb {

struct Arena::Block {
 public:
  Block()
    : next(NULL),
      rem(0),
      next_lower(NULL),
      next_upper(NULL),
      base(NULL),
      size(0) {
  }
  ~Block() throw () {
    uint32_t r = atomic::load_32_acquire(&rem);
    if (base) {
      munmap(base, size);
    }
  }

  Block* next;
  uint32_t rem;
  char* next_lower;
  char* next_upper;
  char* base;
  uint32_t size;
};

Arena::Arena()
  : align_((sizeof(void*) > 8) ? sizeof(void*) : 8),
    page_size_(getpagesize()),
    memory_usage_(),
    blocks_(),
    large_() {
  using namespace atomic;
  assert((align_ & (align_-1)) == 0); // Pointer size should be a power of 2
  store_64_release(&memory_usage_, sizeof(Block));
  Block* nb = NewBlock(1U << 16);
  store_ptr_release(&blocks_, nb);
  store_ptr_nobarrier(&large_, static_cast<Block*>(NULL));
  increment_64_nobarrier(&memory_usage_, sizeof(Block));
}

Arena::~Arena() throw () {
  using namespace atomic;
  memory_barrier();
  Block* list = load_ptr_acquire(&blocks_);
  while (list) {
    Block* tmp = load_ptr_acquire(&list->next);
    delete list;
    list = tmp;
  }
  list = load_ptr_acquire(&large_);
  while (list) {
    Block* tmp = load_ptr_acquire(&list->next);
    delete list;
    list = tmp;
  }
}

char* Arena::Allocate(size_t bytes) {
  using namespace atomic;
  assert(bytes > 0);
  if (bytes > BLOCK_SIZE >> 2) {
    return AllocateLarge(bytes);
  }
  while (true) {
    Block* b = load_ptr_acquire(&blocks_);
    uint32_t rem = load_32_acquire(&b->rem);
    uint32_t witness;
    while (rem >= bytes) {
      witness = compare_and_swap_32_acquire(&b->rem, rem, rem - bytes);
      if (witness == rem) {
        return AllocateFinalize(b, bytes);
      }
      rem = witness;
    }
    Block* nb = NewBlock(BLOCK_SIZE);
    store_ptr_release(&nb->next, b);
    if (compare_and_swap_ptr_fullbarrier(&blocks_, b, nb) != b) {
      delete nb;
    } else {
      increment_64_nobarrier(&memory_usage_, sizeof(Block));
    }
  }
}

char* Arena::AllocateAligned(size_t bytes) {
  uint64_t new_bytes = (bytes + (align_ - 1)) & ~(align_ - 1);
  char* result = Allocate(new_bytes);
  assert((reinterpret_cast<uintptr_t>(result) & (align_ - 1)) == 0);
  return result;
}

Arena::Block* Arena::NewBlock(size_t bytes) {
  using namespace atomic;
  const size_t sz = (bytes + page_size_ - 1) & ~(page_size_ - 1);
  assert(sz / page_size_ * page_size_ == sz);
  Block* nb = new Block();
  void* ptr = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  if (ptr == MAP_FAILED) {
    throw std::bad_alloc();
  }
  store_ptr_nobarrier(&nb->base, reinterpret_cast<char*>(ptr));
  store_ptr_nobarrier(&nb->next_lower, nb->base);
  store_ptr_nobarrier(&nb->next_upper, nb->base + sz);
  store_32_nobarrier(&nb->size, sz);
  store_32_release(&nb->rem, sz);
  return nb;
}

char* Arena::AllocateLarge(size_t bytes) {
  using namespace atomic;
  assert(bytes > 0);
  Block* nb = NewBlock(bytes);
  Block* b = load_ptr_acquire(&large_);
  Block* witness = NULL;
  store_ptr_release(&nb->next, b);
  while ((witness = compare_and_swap_ptr_fullbarrier(&large_, b, nb)) != b) {
    b = witness;
    store_ptr_release(&nb->next, b);
  }
  increment_64_nobarrier(&memory_usage_, sizeof(Block));
  return AllocateFinalize(nb, bytes);
}

char* Arena::AllocateFinalize(Block* b, size_t bytes) {
  using namespace atomic;
  char** p = NULL;
  ssize_t cas_diff = 0;
  ssize_t ret_diff = 0;
  uint64_t aligned = (bytes + (align_ - 1)) & ~(align_ - 1);
  if (bytes == aligned) {
    p = &b->next_upper;
    cas_diff = 0 - bytes;
    ret_diff = 0;
  } else {
    p = &b->next_lower;
    cas_diff = 0 + bytes;
    ret_diff = 0 - bytes;
  }
  char* expected = load_ptr_nobarrier(p);
  char* witness = NULL;
  while ((witness = compare_and_swap_ptr_nobarrier(p, expected, expected + cas_diff)) != expected) {
    expected = witness;
  }
  char* nl = load_ptr_nobarrier(&b->next_lower);
  char* nu = load_ptr_nobarrier(&b->next_upper);
  uint32_t x = load_32_nobarrier(&b->rem);
  assert(nl <= nu);
  assert(load_ptr_nobarrier(&b->next_lower) <=
         load_ptr_nobarrier(&b->next_upper));
  char* ret = expected + cas_diff + ret_diff;
  increment_64_nobarrier(&memory_usage_, bytes);
  return ret;
}

}  // namespace leveldb
<|endoftext|>


<commit_before>//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "util/arena.h"
#include <sys/mman.h>
#include <algorithm>
#include "rocksdb/env.h"

namespace rocksdb {

const size_t Arena::kMinBlockSize = 4096;
const size_t Arena::kMaxBlockSize = 2 << 30;
static const int kAlignUnit = sizeof(void*);

size_t OptimizeBlockSize(size_t block_size) {
  // Make sure block_size is in optimal range
  block_size = std::max(Arena::kMinBlockSize, block_size);
  block_size = std::min(Arena::kMaxBlockSize, block_size);

  // make sure block_size is the multiple of kAlignUnit
  if (block_size % kAlignUnit != 0) {
    block_size = (1 + block_size / kAlignUnit) * kAlignUnit;
  }

  return block_size;
}

Arena::Arena(size_t block_size) : kBlockSize(OptimizeBlockSize(block_size)) {
  assert(kBlockSize >= kMinBlockSize && kBlockSize <= kMaxBlockSize &&
         kBlockSize % kAlignUnit == 0);
}

Arena::~Arena() {
  for (const auto& block : blocks_) {
    delete[] block;
  }
  for (const auto& mmap_info : huge_blocks_) {
    auto ret = munmap(mmap_info.addr_, mmap_info.length_);
    if (ret != 0) {
      // TODO(sdong): Better handling
    }
  }
}

char* Arena::AllocateFallback(size_t bytes, bool aligned) {
  if (bytes > kBlockSize / 4) {
    ++irregular_block_num;
    // Object is more than a quarter of our block size.  Allocate it separately
    // to avoid wasting too much space in leftover bytes.
    return AllocateNewBlock(bytes);
  }

  // We waste the remaining space in the current block.
  auto block_head = AllocateNewBlock(kBlockSize);
  alloc_bytes_remaining_ = kBlockSize - bytes;

  if (aligned) {
    aligned_alloc_ptr_ = block_head + bytes;
    unaligned_alloc_ptr_ = block_head + kBlockSize;
    return block_head;
  } else {
    aligned_alloc_ptr_ = block_head;
    unaligned_alloc_ptr_ = block_head + kBlockSize - bytes;
    return unaligned_alloc_ptr_;
  }
}

char* Arena::AllocateAligned(size_t bytes, size_t huge_page_tlb_size,
                             Logger* logger) {
  assert((kAlignUnit & (kAlignUnit - 1)) ==
         0);  // Pointer size should be a power of 2

#ifdef OS_LINUX
  if (huge_page_tlb_size > 0 && bytes > 0) {
    // Allocate from a huge page TBL table.
    assert(logger != nullptr);  // logger need to be passed in.
    size_t reserved_size =
        ((bytes - 1U) / huge_page_tlb_size + 1U) * huge_page_tlb_size;
    assert(reserved_size >= bytes);

#ifdef MAP_HUGETLB
    void* addr = mmap(nullptr, reserved_size, (PROT_READ | PROT_WRITE),
                       (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB), 0, 0);
#else
    void* addr = mmap(nullptr, reserved_size, (PROT_READ | PROT_WRITE),
                      (MAP_PRIVATE | MAP_ANONYMOUS), 0, 0);
#endif

    if (addr == MAP_FAILED) {
      Warn(logger, "AllocateAligned fail to allocate huge TLB pages: %s",
           strerror(errno));
      // fail back to malloc
    } else {
      blocks_memory_ += reserved_size;
      huge_blocks_.push_back(MmapInfo(addr, reserved_size));
      return reinterpret_cast<char*>(addr);
    }
  }
#endif

  size_t current_mod =
      reinterpret_cast<uintptr_t>(aligned_alloc_ptr_) & (kAlignUnit - 1);
  size_t slop = (current_mod == 0 ? 0 : kAlignUnit - current_mod);
  size_t needed = bytes + slop;
  char* result;
  if (needed <= alloc_bytes_remaining_) {
    result = aligned_alloc_ptr_ + slop;
    aligned_alloc_ptr_ += needed;
    alloc_bytes_remaining_ -= needed;
  } else {
    // AllocateFallback always returned aligned memory
    result = AllocateFallback(bytes, true /* aligned */);
  }
  assert((reinterpret_cast<uintptr_t>(result) & (kAlignUnit - 1)) == 0);
  return result;
}

char* Arena::AllocateNewBlock(size_t block_bytes) {
  char* block = new char[block_bytes];
  blocks_memory_ += block_bytes;
  blocks_.push_back(block);
  return block;
}

}  // namespace rocksdb
<commit_msg>testing<commit_after>//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "util/arena.h"
#include <sys/mman.h>
#include <algorithm>
#include "rocksdb/env.h"

namespace rocksdb {

const size_t Arena::kMinBlockSize = 4096;
const size_t Arena::kMaxBlockSize = 2 << 30;
static const int kAlignUnit = sizeof(void*);

size_t OptimizeBlockSize(size_t block_size) {
  // Make sure block_size is in optimal range
  block_size = std::max(Arena::kMinBlockSize, block_size);
  block_size = std::min(Arena::kMaxBlockSize, block_size);

  // make sure block_size is the multiple of kAlignUnit
  if (block_size % kAlignUnit != 0) {
    block_size = (1 + block_size / kAlignUnit) * kAlignUnit;
  }

  return block_size;
}

Arena::Arena(size_t block_size) : kBlockSize(OptimizeBlockSize(block_size)) {
  assert(kBlockSize >= kMinBlockSize && kBlockSize <= kMaxBlockSize &&
         kBlockSize % kAlignUnit == 0);
}

Arena::~Arena() {
  for (const auto& block : blocks_) {
    delete[] block;
  }
  for (const auto& mmap_info : huge_blocks_) {
    auto ret = munmap(mmap_info.addr_, mmap_info.length_);
    if (ret != 0) {
      // TODO(sdong): Better handling
    }
  }
}

char* Arena::AllocateFallback(size_t bytes, bool aligned) {
  if (bytes > kBlockSize / 4) {
    ++irregular_block_num;
    // Object is more than a quarter of our block size.  Allocate it separately
    // to avoid wasting too much space in leftover bytes.
    return AllocateNewBlock(bytes);
  }

  // We waste the remaining space in the current block.
  auto block_head = AllocateNewBlock(kBlockSize);
  alloc_bytes_remaining_ = kBlockSize - bytes;

  if (aligned) {
    aligned_alloc_ptr_ = block_head + bytes;
    unaligned_alloc_ptr_ = block_head + kBlockSize;
    return block_head;
  } else {
    aligned_alloc_ptr_ = block_head;
    unaligned_alloc_ptr_ = block_head + kBlockSize - bytes;
    return unaligned_alloc_ptr_;
  }
}

char* Arena::AllocateAligned(size_t bytes, size_t huge_page_tlb_size,
                             Logger* logger) {
  assert((kAlignUnit & (kAlignUnit - 1)) ==
         0);  // Pointer size should be a power of 2

#ifdef MAP_HUGETLB
  if (huge_page_tlb_size > 0 && bytes > 0) {
    // Allocate from a huge page TBL table.
    assert(logger != nullptr);  // logger need to be passed in.
    size_t reserved_size =
        ((bytes - 1U) / huge_page_tlb_size + 1U) * huge_page_tlb_size;
    assert(reserved_size >= bytes);

    void* addr = mmap(nullptr, reserved_size, (PROT_READ | PROT_WRITE),
                       (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB), 0, 0);

    if (addr == MAP_FAILED) {
      Warn(logger, "AllocateAligned fail to allocate huge TLB pages: %s",
           strerror(errno));
      // fail back to malloc
    } else {
      blocks_memory_ += reserved_size;
      huge_blocks_.push_back(MmapInfo(addr, reserved_size));
      return reinterpret_cast<char*>(addr);
    }
  }
#endif

  size_t current_mod =
      reinterpret_cast<uintptr_t>(aligned_alloc_ptr_) & (kAlignUnit - 1);
  size_t slop = (current_mod == 0 ? 0 : kAlignUnit - current_mod);
  size_t needed = bytes + slop;
  char* result;
  if (needed <= alloc_bytes_remaining_) {
    result = aligned_alloc_ptr_ + slop;
    aligned_alloc_ptr_ += needed;
    alloc_bytes_remaining_ -= needed;
  } else {
    // AllocateFallback always returned aligned memory
    result = AllocateFallback(bytes, true /* aligned */);
  }
  assert((reinterpret_cast<uintptr_t>(result) & (kAlignUnit - 1)) == 0);
  return result;
}

char* Arena::AllocateNewBlock(size_t block_bytes) {
  char* block = new char[block_bytes];
  blocks_memory_ += block_bytes;
  blocks_.push_back(block);
  return block;
}

}  // namespace rocksdb
<|endoftext|>


<commit_before><commit_msg>callcatcher: SvxHtmlExportModeConfigItem_Impl unused now<commit_after><|endoftext|>


<commit_before><commit_msg>Typo: with->width<commit_after><|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "AprioriFilter.h"
#include "TestDataSets.h"

#include <iostream>
#include <string>

using namespace std;

// aExpected is itemsets, space delimted, and item inside the set ',' delimited.
bool CheckSet(string aExpected, set<ItemSet> aObserved) {
  vector<string> itemsets;
  Tokenize(aExpected, itemsets, " ");

  ASSERT(itemsets.size() == aObserved.size());
  if (itemsets.size() != aObserved.size()) {
    return false;
  }

  set<ItemSet>::const_iterator itr = aObserved.begin();
  set<ItemSet>::const_iterator end = aObserved.end();
  int i = 0;
  for (itr; itr != end; itr++, i++) {
    vector<string> items;
    Tokenize(itemsets[i], items, ",");
    ItemSet item1;
    for (unsigned i = 0; i < items.size(); i++) {
      item1 += Item(items[i]);
    }
    ItemSet item2(*itr);
    ASSERT(item1 == item2);
    if (!(item1 == item2)) {
      return false;
    }
  }
  return true;
}

extern set<ItemSet>
GenerateCandidates(const set<ItemSet>& aCandidates,
                   int aItemSetSize,
                   shared_ptr<AprioriFilter> aFilter,
                   int numThreads);

extern set<ItemSet>
GenerateInitialCandidates(const InvertedDataSetIndex& aIndex,
                          shared_ptr<AprioriFilter> aFilter);

extern bool ContainsAllSubSets(const set<ItemSet>& aContainer,
                               const ItemSet& aItemSet);

TEST(Apriori_Test, main) {
  Item::SetCompareMode(Item::ALPHABETIC_COMPARE);
  Item::ResetBaseId();

  {
    InvertedDataSetIndex index(Test3DataSet());
    ASSERT_TRUE(index.Load());
    ASSERT_TRUE(index.GetNumItems() == 20);

    // Test GenerateInitialCandidates().
    {
      shared_ptr<AprioriFilter> msf = make_shared<MinSupportFilter>(0.6, index);
      set<ItemSet> candidates = GenerateInitialCandidates(index, msf);
      ASSERT_TRUE(CheckSet("a s u", candidates));
    }
    {
      shared_ptr<AprioriFilter> msf = make_shared<MinSupportFilter>(0.3, index);
      set<ItemSet> candidates = GenerateInitialCandidates(index, msf);
      // Candidates are: {a,c,d,e,f,g,r,s,t,u,w,y}
      CheckSet("a c d e f g r s t u w y", candidates);
    }

    // Test bool ContainsAllSubSets(const set<ItemSet> &aContainer, const ItemSet &aItemSet)
    {
      set<ItemSet> container;
      container.insert(ItemSet("a", "b"));
      container.insert(ItemSet("a", "c"));
      container.insert(ItemSet("b", "c"));

      ItemSet abc("a", "b", "c");
      ASSERT_TRUE(ContainsAllSubSets(container, abc));
    }
    // Test GenerateCandidates()...
    {
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "2", "3"), ItemSet("1", "2", "4")) == 2);
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "2", "4"), ItemSet("1", "3", "4")) == 2);
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "3", "4"), ItemSet("1", "3", "5")) == 2);
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "2", "3"), ItemSet("2", "3", "4")) == 2);

      set<ItemSet> P;
      P.insert(ItemSet("1", "2", "3"));
      P.insert(ItemSet("1", "2", "4"));
      P.insert(ItemSet("1", "3", "4"));
      P.insert(ItemSet("1", "3", "5"));
      P.insert(ItemSet("2", "3", "4"));

      shared_ptr<AprioriFilter> F = make_shared<AlwaysAcceptFilter>();
      set<ItemSet> R = GenerateCandidates(P, 4, F, 1);

      ASSERT_TRUE(R.size() == 1);
      ASSERT_TRUE(*R.begin() == ItemSet("1", "2", "3", "4"));
    }
  }
  {
    // Test a simulation of Apriori, with the data set given by Agrual's paper.
    InvertedDataSetIndex index(Test4DataSet());
    ASSERT_TRUE(index.Load());

    /*
      Data set:
      1 3 4
      2 3 5
      1 2 3 5
      2 5

      Initial candidates / Support
      1/2
      2/3
      3/3
      5/3
    */
    int c = 0;
    ASSERT_TRUE((c = index.Count(ItemSet("1"))) == 2);
    ASSERT_TRUE((c = index.Count(ItemSet("2"))) == 3);
    ASSERT_TRUE((c = index.Count(ItemSet("3"))) == 3);
    ASSERT_TRUE((c = index.Count(ItemSet("5"))) == 3);

    shared_ptr<AprioriFilter> filter = make_shared<MinCountFilter>(2, index);
    set<ItemSet> initialCandidates = GenerateInitialCandidates(index, filter);
    ASSERT_TRUE(CheckSet("1 2 3 5", initialCandidates));

    // Test next generation...
    set<ItemSet> candidates = GenerateCandidates(initialCandidates, 2, filter, 1);
    ASSERT_TRUE(CheckSet("1,3 2,3 2,5 3,5", candidates));

    candidates = GenerateCandidates(candidates, 3, filter, 1);
    ASSERT_TRUE(CheckSet("2,3,5", candidates));

  }
}

extern int MinAbsSup(int A, int B, int N, double E);

TEST(MinAbsSupFilter, main) {
  EXPECT_EQ(MinAbsSup(250, 250, 1000, 0.999), 81);
  EXPECT_EQ(MinAbsSup(250, 500, 1000, 0.999), 146);
  EXPECT_EQ(MinAbsSup(600, 500, 1000, 0.999), 324);
  EXPECT_EQ(MinAbsSup(500, 500, 1000, 0.999), 274);
  EXPECT_EQ(MinAbsSup(500, 1000, 1000, 0.999), 500);
  EXPECT_EQ(MinAbsSup(500, 1000, 10000, 0.999), 71);
  EXPECT_EQ(MinAbsSup(50, 1000, 10000, 0.999), 12);
  EXPECT_EQ(MinAbsSup(50, 5000, 10000, 0.999), 36);
}
<commit_msg>Silence clang expression result unused warning in Test_Apriori.cpp.<commit_after>#include "gtest/gtest.h"
#include "AprioriFilter.h"
#include "TestDataSets.h"

#include <iostream>
#include <string>

using namespace std;

// aExpected is itemsets, space delimted, and item inside the set ',' delimited.
bool CheckSet(string aExpected, set<ItemSet> aObserved) {
  vector<string> itemsets;
  Tokenize(aExpected, itemsets, " ");

  ASSERT(itemsets.size() == aObserved.size());
  if (itemsets.size() != aObserved.size()) {
    return false;
  }

  set<ItemSet>::const_iterator itr = aObserved.begin();
  set<ItemSet>::const_iterator end = aObserved.end();
  int i = 0;
  for (; itr != end; itr++, i++) {
    vector<string> items;
    Tokenize(itemsets[i], items, ",");
    ItemSet item1;
    for (unsigned i = 0; i < items.size(); i++) {
      item1 += Item(items[i]);
    }
    ItemSet item2(*itr);
    ASSERT(item1 == item2);
    if (!(item1 == item2)) {
      return false;
    }
  }
  return true;
}

extern set<ItemSet>
GenerateCandidates(const set<ItemSet>& aCandidates,
                   int aItemSetSize,
                   shared_ptr<AprioriFilter> aFilter,
                   int numThreads);

extern set<ItemSet>
GenerateInitialCandidates(const InvertedDataSetIndex& aIndex,
                          shared_ptr<AprioriFilter> aFilter);

extern bool ContainsAllSubSets(const set<ItemSet>& aContainer,
                               const ItemSet& aItemSet);

TEST(Apriori_Test, main) {
  Item::SetCompareMode(Item::ALPHABETIC_COMPARE);
  Item::ResetBaseId();

  {
    InvertedDataSetIndex index(Test3DataSet());
    ASSERT_TRUE(index.Load());
    ASSERT_TRUE(index.GetNumItems() == 20);

    // Test GenerateInitialCandidates().
    {
      shared_ptr<AprioriFilter> msf = make_shared<MinSupportFilter>(0.6, index);
      set<ItemSet> candidates = GenerateInitialCandidates(index, msf);
      ASSERT_TRUE(CheckSet("a s u", candidates));
    }
    {
      shared_ptr<AprioriFilter> msf = make_shared<MinSupportFilter>(0.3, index);
      set<ItemSet> candidates = GenerateInitialCandidates(index, msf);
      // Candidates are: {a,c,d,e,f,g,r,s,t,u,w,y}
      CheckSet("a c d e f g r s t u w y", candidates);
    }

    // Test bool ContainsAllSubSets(const set<ItemSet> &aContainer, const ItemSet &aItemSet)
    {
      set<ItemSet> container;
      container.insert(ItemSet("a", "b"));
      container.insert(ItemSet("a", "c"));
      container.insert(ItemSet("b", "c"));

      ItemSet abc("a", "b", "c");
      ASSERT_TRUE(ContainsAllSubSets(container, abc));
    }
    // Test GenerateCandidates()...
    {
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "2", "3"), ItemSet("1", "2", "4")) == 2);
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "2", "4"), ItemSet("1", "3", "4")) == 2);
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "3", "4"), ItemSet("1", "3", "5")) == 2);
      ASSERT_TRUE(IntersectionSize(ItemSet("1", "2", "3"), ItemSet("2", "3", "4")) == 2);

      set<ItemSet> P;
      P.insert(ItemSet("1", "2", "3"));
      P.insert(ItemSet("1", "2", "4"));
      P.insert(ItemSet("1", "3", "4"));
      P.insert(ItemSet("1", "3", "5"));
      P.insert(ItemSet("2", "3", "4"));

      shared_ptr<AprioriFilter> F = make_shared<AlwaysAcceptFilter>();
      set<ItemSet> R = GenerateCandidates(P, 4, F, 1);

      ASSERT_TRUE(R.size() == 1);
      ASSERT_TRUE(*R.begin() == ItemSet("1", "2", "3", "4"));
    }
  }
  {
    // Test a simulation of Apriori, with the data set given by Agrual's paper.
    InvertedDataSetIndex index(Test4DataSet());
    ASSERT_TRUE(index.Load());

    /*
      Data set:
      1 3 4
      2 3 5
      1 2 3 5
      2 5

      Initial candidates / Support
      1/2
      2/3
      3/3
      5/3
    */
    int c = 0;
    ASSERT_TRUE((c = index.Count(ItemSet("1"))) == 2);
    ASSERT_TRUE((c = index.Count(ItemSet("2"))) == 3);
    ASSERT_TRUE((c = index.Count(ItemSet("3"))) == 3);
    ASSERT_TRUE((c = index.Count(ItemSet("5"))) == 3);

    shared_ptr<AprioriFilter> filter = make_shared<MinCountFilter>(2, index);
    set<ItemSet> initialCandidates = GenerateInitialCandidates(index, filter);
    ASSERT_TRUE(CheckSet("1 2 3 5", initialCandidates));

    // Test next generation...
    set<ItemSet> candidates = GenerateCandidates(initialCandidates, 2, filter, 1);
    ASSERT_TRUE(CheckSet("1,3 2,3 2,5 3,5", candidates));

    candidates = GenerateCandidates(candidates, 3, filter, 1);
    ASSERT_TRUE(CheckSet("2,3,5", candidates));

  }
}

extern int MinAbsSup(int A, int B, int N, double E);

TEST(MinAbsSupFilter, main) {
  EXPECT_EQ(MinAbsSup(250, 250, 1000, 0.999), 81);
  EXPECT_EQ(MinAbsSup(250, 500, 1000, 0.999), 146);
  EXPECT_EQ(MinAbsSup(600, 500, 1000, 0.999), 324);
  EXPECT_EQ(MinAbsSup(500, 500, 1000, 0.999), 274);
  EXPECT_EQ(MinAbsSup(500, 1000, 1000, 0.999), 500);
  EXPECT_EQ(MinAbsSup(500, 1000, 10000, 0.999), 71);
  EXPECT_EQ(MinAbsSup(50, 1000, 10000, 0.999), 12);
  EXPECT_EQ(MinAbsSup(50, 5000, 10000, 0.999), 36);
}
<|endoftext|>