<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, 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 Willow Garage, Inc. 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: Suat Gedikli (gedikli@willowgarage.com)
 */

#include <pcl/visualization/image_viewer.h>
#include <pcl/visualization/common/float_image_utils.h>
#include <vtkImageImport.h>
#include <vtkImageViewer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageReslice.h>
#include <vtkTransform.h>
#include <vtkImageChangeInformation.h>
#include <vtkCallbackCommand.h>
#include <vtkObject.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <pcl/visualization/keyboard_event.h>
#include <pcl/visualization/mouse_event.h>
#include <pcl/common/time.h>

/////////////////////////////////////////////////////////////////////////////////////////////
pcl::visualization::ImageViewer::ImageViewer (const std::string& window_title)
  : interactor_ (vtkSmartPointer<vtkRenderWindowInteractor>::New ()),
    mouse_command_ (vtkCallbackCommand::New ()),
    keyboard_command_ (vtkCallbackCommand::New ()),
    image_viewer_ (vtkImageViewer::New ()),
    data_size_ (0)
{
  // Set the mouse/keyboard callbacks
  mouse_command_->SetClientData (this);
  mouse_command_->SetCallback (ImageViewer::MouseCallback);

  keyboard_command_->SetClientData (this);
  keyboard_command_->SetCallback (ImageViewer::KeyboardCallback);

  // Create our own  interactor and set the window title
  image_viewer_->SetupInteractor (interactor_);
  image_viewer_->GetRenderWindow ()->SetWindowName (window_title.c_str ());

  // Initialize and create timer
  interactor_->Initialize ();
  timer_id_ = interactor_->CreateRepeatingTimer (0);

  // Set the exit callbacks
  exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New ();
  exit_main_loop_timer_callback_->window = this;
  exit_main_loop_timer_callback_->right_timer_id = -1;
  interactor_->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_);

  exit_callback_ = vtkSmartPointer<ExitCallback>::New ();
  exit_callback_->window = this;
  interactor_->AddObserver (vtkCommand::ExitEvent, exit_callback_);

  resetStoppedFlag ();
}

/////////////////////////////////////////////////////////////////////////////////////////////
pcl::visualization::ImageViewer::~ImageViewer ()
{
   interactor_->DestroyTimer (timer_id_);
//  interactor_->DestroyTimer (interactor_->timer_id_);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::showRGBImage (const unsigned char* rgb_data, unsigned width, unsigned height)
{
  vtkImageImport* importer = vtkImageImport::New ();
  importer->SetNumberOfScalarComponents (3);
  importer->SetWholeExtent (0, width - 1, 0, height - 1, 0, 0);
  importer->SetDataScalarTypeToUnsignedChar ();
  importer->SetDataExtentToWholeExtent ();

  void* data = const_cast<void*> ((const void*)rgb_data);
  importer->SetImportVoidPointer (data, 1);
  importer->Update ();

  vtkSmartPointer<vtkMatrix4x4> transform = vtkSmartPointer<vtkMatrix4x4>::New ();
  transform->Identity ();
  transform->SetElement (1,1, -1.0);
  transform->SetElement (1,3, height);
  vtkSmartPointer<vtkTransform> imageTransform = vtkSmartPointer<vtkTransform>::New ();
  imageTransform->SetMatrix (transform);
  // Now create filter and set previously created transformation
  vtkSmartPointer<vtkImageReslice> algo = vtkSmartPointer<vtkImageReslice>::New ();
  algo->SetInput (importer->GetOutput ());
  algo->SetInformationInput (importer->GetOutput ());
  algo->SetResliceTransform (imageTransform);
  algo->SetInterpolationModeToCubic ();
  algo->Update ();

  image_viewer_->SetInput (algo->GetOutput ());
  image_viewer_->SetColorLevel (127.5);
  image_viewer_->SetColorWindow (255);
  image_viewer_->SetSize (width, height);

  image_viewer_->Render ();
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::showRGBImage (const pcl::PointCloud<pcl::PointXYZRGB> &cloud)
{
  if (data_size_ < cloud.width * cloud.height)
  {
    data_size_ = cloud.width * cloud.height * 3;
    data_.reset (new unsigned char[data_size_]);
  }

  for (size_t i = 0; i < cloud.points.size (); ++i)
    memcpy (&data_[i * 3], (char*)&cloud.points[i].rgb, sizeof (char) * 3);
  return (showRGBImage (data_.get (), cloud.width, cloud.height));
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::showFloatImage (const float* float_image, unsigned int width, unsigned int height,
                                                float min_value, float max_value, bool grayscale)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualImage (float_image, width, height,
                                                              min_value, max_value, grayscale);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
 }

void
pcl::visualization::ImageViewer::showAngleImage (const float* angle_image, unsigned int width, unsigned int height)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualAngleImage (angle_image, width, height);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
}

void
pcl::visualization::ImageViewer::showHalfAngleImage (const float* angle_image, unsigned int width, unsigned int height)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualHalfAngleImage (angle_image, width, height);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
}

void
pcl::visualization::ImageViewer::showShortImage (const unsigned short* short_image, unsigned int width, unsigned int height,
                                                unsigned short min_value, unsigned short max_value, bool grayscale)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualImage (short_image, width, height,
                                                              min_value, max_value, grayscale);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::spin ()
{
  resetStoppedFlag ();
  // Render the window before we start the interactor
  interactor_->Render ();
  interactor_->Start ();
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::spinOnce (int time, bool force_redraw)
{
  resetStoppedFlag ();

  if (time <= 0)
    time = 1;

  DO_EVERY (1.0 / interactor_->GetDesiredUpdateRate (),
    interactor_->Render ();
    exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer (time);
    interactor_->Start ();
    interactor_->DestroyTimer (exit_main_loop_timer_callback_->right_timer_id);
  );
}

/////////////////////////////////////////////////////////////////////////////////////////////
boost::signals2::connection
pcl::visualization::ImageViewer::registerMouseCallback (
    boost::function<void (const pcl::visualization::MouseEvent&)> callback)
{
  // just add observer at first time when a callback is registered
  if (mouse_signal_.empty ())
  {
    interactor_->AddObserver (vtkCommand::MouseMoveEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MiddleButtonPressEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MiddleButtonReleaseEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MouseWheelBackwardEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MouseWheelForwardEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::LeftButtonPressEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::LeftButtonReleaseEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::RightButtonPressEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::RightButtonReleaseEvent, mouse_command_);
  }
  return (mouse_signal_.connect (callback));
}

/////////////////////////////////////////////////////////////////////////////////////////////
boost::signals2::connection
pcl::visualization::ImageViewer::registerKeyboardCallback (
    boost::function<void (const pcl::visualization::KeyboardEvent&)> callback)
{
  // just add observer at first time when a callback is registered
  if (keyboard_signal_.empty ())
  {
    interactor_->AddObserver (vtkCommand::KeyPressEvent, keyboard_command_);
    interactor_->AddObserver (vtkCommand::KeyReleaseEvent, keyboard_command_);
  }

  return (keyboard_signal_.connect (callback));
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::emitMouseEvent (unsigned long event_id)
{
  int x,y;
  interactor_->GetMousePosition (&x, &y);
  MouseEvent event (MouseEvent::MouseMove, MouseEvent::NoButton, x, y,
                    interactor_->GetAltKey (), interactor_->GetControlKey (), interactor_->GetShiftKey ());
  bool repeat = false;
  switch (event_id)
  {
    case vtkCommand::MouseMoveEvent :
      event.setType(MouseEvent::MouseMove);
      break;

    case vtkCommand::LeftButtonPressEvent :
      event.setButton(MouseEvent::LeftButton);
      if (interactor_->GetRepeatCount () == 0)
        event.setType(MouseEvent::MouseButtonPress);
      else
        event.setType(MouseEvent::MouseDblClick);
      break;

    case vtkCommand::LeftButtonReleaseEvent :
      event.setButton(MouseEvent::LeftButton);
      event.setType(MouseEvent::MouseButtonRelease);
      break;

    case vtkCommand::RightButtonPressEvent :
      event.setButton(MouseEvent::RightButton);
      if (interactor_->GetRepeatCount () == 0)
        event.setType(MouseEvent::MouseButtonPress);
      else
        event.setType(MouseEvent::MouseDblClick);
      break;

    case vtkCommand::RightButtonReleaseEvent :
      event.setButton(MouseEvent::RightButton);
      event.setType(MouseEvent::MouseButtonRelease);
      break;

    case vtkCommand::MiddleButtonPressEvent :
      event.setButton(MouseEvent::MiddleButton);
      if (interactor_->GetRepeatCount () == 0)
        event.setType(MouseEvent::MouseButtonPress);
      else
        event.setType(MouseEvent::MouseDblClick);
      break;

    case vtkCommand::MiddleButtonReleaseEvent :
      event.setButton(MouseEvent::MiddleButton);
      event.setType(MouseEvent::MouseButtonRelease);
      break;

      case vtkCommand::MouseWheelBackwardEvent :
      event.setButton(MouseEvent::VScroll);
      event.setType(MouseEvent::MouseScrollDown);
      if (interactor_->GetRepeatCount () != 0)
        repeat = true;
      break;

    case vtkCommand::MouseWheelForwardEvent :
      event.setButton(MouseEvent::VScroll);
      event.setType(MouseEvent::MouseScrollUp);
      if (interactor_->GetRepeatCount () != 0)
        repeat = true;
      break;
    default:
      return;
  }

  mouse_signal_ (event);
  if (repeat)
    mouse_signal_ (event);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::emitKeyboardEvent (unsigned long event_id)
{
  KeyboardEvent event (bool(event_id == vtkCommand::KeyPressEvent), interactor_->GetKeySym (),  interactor_->GetKeyCode (), interactor_->GetAltKey (), interactor_->GetControlKey (), interactor_->GetShiftKey ());
  keyboard_signal_ (event);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::MouseCallback (vtkObject*, unsigned long eid, void* clientdata, void* calldata)
{
  ImageViewer* window = reinterpret_cast<ImageViewer*> (clientdata);
  window->emitMouseEvent (eid);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::KeyboardCallback (vtkObject*, unsigned long eid, void* clientdata, void* calldata)
{
  ImageViewer* window = reinterpret_cast<ImageViewer*> (clientdata);
  window->emitKeyboardEvent (eid);
}

<commit_msg>markPoint implementation was missing<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, 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 Willow Garage, Inc. 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: Suat Gedikli (gedikli@willowgarage.com)
 */

#include <pcl/visualization/image_viewer.h>
#include <pcl/visualization/common/float_image_utils.h>
#include <vtkImageImport.h>
#include <vtkImageViewer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageReslice.h>
#include <vtkTransform.h>
#include <vtkImageChangeInformation.h>
#include <vtkCallbackCommand.h>
#include <vtkObject.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageBlend.h>
#include <pcl/visualization/keyboard_event.h>
#include <pcl/visualization/mouse_event.h>
#include <pcl/common/time.h>

/////////////////////////////////////////////////////////////////////////////////////////////
pcl::visualization::ImageViewer::ImageViewer (const std::string& window_title)
  : interactor_ (vtkSmartPointer<vtkRenderWindowInteractor>::New ()),
    mouse_command_ (vtkCallbackCommand::New ()),
    keyboard_command_ (vtkCallbackCommand::New ()),
    image_viewer_ (vtkImageViewer::New ()),
    data_size_ (0)
{
  // Set the mouse/keyboard callbacks
  mouse_command_->SetClientData (this);
  mouse_command_->SetCallback (ImageViewer::MouseCallback);

  keyboard_command_->SetClientData (this);
  keyboard_command_->SetCallback (ImageViewer::KeyboardCallback);

  // Create our own  interactor and set the window title
  image_viewer_->SetupInteractor (interactor_);
  image_viewer_->GetRenderWindow ()->SetWindowName (window_title.c_str ());

  // Initialize and create timer
  interactor_->Initialize ();
  timer_id_ = interactor_->CreateRepeatingTimer (0);

  // Set the exit callbacks
  exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New ();
  exit_main_loop_timer_callback_->window = this;
  exit_main_loop_timer_callback_->right_timer_id = -1;
  interactor_->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_);

  exit_callback_ = vtkSmartPointer<ExitCallback>::New ();
  exit_callback_->window = this;
  interactor_->AddObserver (vtkCommand::ExitEvent, exit_callback_);

  resetStoppedFlag ();
}

/////////////////////////////////////////////////////////////////////////////////////////////
pcl::visualization::ImageViewer::~ImageViewer ()
{
   interactor_->DestroyTimer (timer_id_);
//  interactor_->DestroyTimer (interactor_->timer_id_);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::showRGBImage (const unsigned char* rgb_data, unsigned width, unsigned height)
{
  vtkImageImport* importer = vtkImageImport::New ();
  importer->SetNumberOfScalarComponents (3);
  importer->SetWholeExtent (0, width - 1, 0, height - 1, 0, 0);
  importer->SetDataScalarTypeToUnsignedChar ();
  importer->SetDataExtentToWholeExtent ();

  void* data = const_cast<void*> ((const void*)rgb_data);
  importer->SetImportVoidPointer (data, 1);
  importer->Update ();

  vtkSmartPointer<vtkMatrix4x4> transform = vtkSmartPointer<vtkMatrix4x4>::New ();
  transform->Identity ();
  transform->SetElement (1,1, -1.0);
  transform->SetElement (1,3, height);
  vtkSmartPointer<vtkTransform> imageTransform = vtkSmartPointer<vtkTransform>::New ();
  imageTransform->SetMatrix (transform);
  // Now create filter and set previously created transformation
  vtkSmartPointer<vtkImageReslice> algo = vtkSmartPointer<vtkImageReslice>::New ();
  algo->SetInput (importer->GetOutput ());
  algo->SetInformationInput (importer->GetOutput ());
  algo->SetResliceTransform (imageTransform);
  algo->SetInterpolationModeToCubic ();
  algo->Update ();

  image_viewer_->SetInput (algo->GetOutput ());
  image_viewer_->SetColorLevel (127.5);
  image_viewer_->SetColorWindow (255);
  image_viewer_->SetSize (width, height);

  image_viewer_->Render ();
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::showRGBImage (const pcl::PointCloud<pcl::PointXYZRGB> &cloud)
{
  if (data_size_ < cloud.width * cloud.height)
  {
    data_size_ = cloud.width * cloud.height * 3;
    data_.reset (new unsigned char[data_size_]);
  }

  for (size_t i = 0; i < cloud.points.size (); ++i)
    memcpy (&data_[i * 3], (char*)&cloud.points[i].rgb, sizeof (char) * 3);
  return (showRGBImage (data_.get (), cloud.width, cloud.height));
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::showFloatImage (const float* float_image, unsigned int width, unsigned int height,
                                                float min_value, float max_value, bool grayscale)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualImage (float_image, width, height,
                                                              min_value, max_value, grayscale);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
 }

void
pcl::visualization::ImageViewer::showAngleImage (const float* angle_image, unsigned int width, unsigned int height)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualAngleImage (angle_image, width, height);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
}

void
pcl::visualization::ImageViewer::showHalfAngleImage (const float* angle_image, unsigned int width, unsigned int height)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualHalfAngleImage (angle_image, width, height);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
}

void
pcl::visualization::ImageViewer::showShortImage (const unsigned short* short_image, unsigned int width, unsigned int height,
                                                unsigned short min_value, unsigned short max_value, bool grayscale)
{
  unsigned char* rgb_image = FloatImageUtils::getVisualImage (short_image, width, height,
                                                              min_value, max_value, grayscale);
  showRGBImage (rgb_image, width, height);
  delete[] rgb_image;
}

void
pcl::visualization::ImageViewer::markPoint(size_t u, size_t v, Vector3ub fg_color, Vector3ub bg_color, float radius)
{
  vtkSmartPointer<vtkImageCanvasSource2D> drawing =
    vtkSmartPointer<vtkImageCanvasSource2D>::New ();
  drawing->SetNumberOfScalarComponents (3);
  drawing->SetScalarTypeToUnsignedChar ();
  vtkImageData* image_data = image_viewer_->GetInput ();
  drawing->SetExtent (image_data->GetExtent ());
  drawing->SetDrawColor (fg_color[0], fg_color[1], fg_color[2]);
  drawing->DrawPoint (u, v);
  drawing->SetDrawColor (bg_color[0], bg_color[1], bg_color[2]);
  drawing->DrawCircle (u, v, radius);
  vtkSmartPointer<vtkImageBlend> blend = vtkSmartPointer<vtkImageBlend>::New();
  blend->AddInput (image_data);
  blend->AddInput (drawing->GetOutput ());
  blend->SetOpacity (0, 0.6);
  blend->SetOpacity (1, 0.4);
  image_viewer_->SetInput (blend->GetOutput ());
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::spin ()
{
  resetStoppedFlag ();
  // Render the window before we start the interactor
  interactor_->Render ();
  interactor_->Start ();
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::spinOnce (int time, bool force_redraw)
{
  resetStoppedFlag ();

  if (time <= 0)
    time = 1;

  DO_EVERY (1.0 / interactor_->GetDesiredUpdateRate (),
    interactor_->Render ();
    exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer (time);
    interactor_->Start ();
    interactor_->DestroyTimer (exit_main_loop_timer_callback_->right_timer_id);
  );
}

/////////////////////////////////////////////////////////////////////////////////////////////
boost::signals2::connection
pcl::visualization::ImageViewer::registerMouseCallback (
    boost::function<void (const pcl::visualization::MouseEvent&)> callback)
{
  // just add observer at first time when a callback is registered
  if (mouse_signal_.empty ())
  {
    interactor_->AddObserver (vtkCommand::MouseMoveEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MiddleButtonPressEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MiddleButtonReleaseEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MouseWheelBackwardEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::MouseWheelForwardEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::LeftButtonPressEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::LeftButtonReleaseEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::RightButtonPressEvent, mouse_command_);
    interactor_->AddObserver (vtkCommand::RightButtonReleaseEvent, mouse_command_);
  }
  return (mouse_signal_.connect (callback));
}

/////////////////////////////////////////////////////////////////////////////////////////////
boost::signals2::connection
pcl::visualization::ImageViewer::registerKeyboardCallback (
    boost::function<void (const pcl::visualization::KeyboardEvent&)> callback)
{
  // just add observer at first time when a callback is registered
  if (keyboard_signal_.empty ())
  {
    interactor_->AddObserver (vtkCommand::KeyPressEvent, keyboard_command_);
    interactor_->AddObserver (vtkCommand::KeyReleaseEvent, keyboard_command_);
  }

  return (keyboard_signal_.connect (callback));
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::emitMouseEvent (unsigned long event_id)
{
  int x,y;
  interactor_->GetMousePosition (&x, &y);
  MouseEvent event (MouseEvent::MouseMove, MouseEvent::NoButton, x, y,
                    interactor_->GetAltKey (), interactor_->GetControlKey (), interactor_->GetShiftKey ());
  bool repeat = false;
  switch (event_id)
  {
    case vtkCommand::MouseMoveEvent :
      event.setType(MouseEvent::MouseMove);
      break;

    case vtkCommand::LeftButtonPressEvent :
      event.setButton(MouseEvent::LeftButton);
      if (interactor_->GetRepeatCount () == 0)
        event.setType(MouseEvent::MouseButtonPress);
      else
        event.setType(MouseEvent::MouseDblClick);
      break;

    case vtkCommand::LeftButtonReleaseEvent :
      event.setButton(MouseEvent::LeftButton);
      event.setType(MouseEvent::MouseButtonRelease);
      break;

    case vtkCommand::RightButtonPressEvent :
      event.setButton(MouseEvent::RightButton);
      if (interactor_->GetRepeatCount () == 0)
        event.setType(MouseEvent::MouseButtonPress);
      else
        event.setType(MouseEvent::MouseDblClick);
      break;

    case vtkCommand::RightButtonReleaseEvent :
      event.setButton(MouseEvent::RightButton);
      event.setType(MouseEvent::MouseButtonRelease);
      break;

    case vtkCommand::MiddleButtonPressEvent :
      event.setButton(MouseEvent::MiddleButton);
      if (interactor_->GetRepeatCount () == 0)
        event.setType(MouseEvent::MouseButtonPress);
      else
        event.setType(MouseEvent::MouseDblClick);
      break;

    case vtkCommand::MiddleButtonReleaseEvent :
      event.setButton(MouseEvent::MiddleButton);
      event.setType(MouseEvent::MouseButtonRelease);
      break;

      case vtkCommand::MouseWheelBackwardEvent :
      event.setButton(MouseEvent::VScroll);
      event.setType(MouseEvent::MouseScrollDown);
      if (interactor_->GetRepeatCount () != 0)
        repeat = true;
      break;

    case vtkCommand::MouseWheelForwardEvent :
      event.setButton(MouseEvent::VScroll);
      event.setType(MouseEvent::MouseScrollUp);
      if (interactor_->GetRepeatCount () != 0)
        repeat = true;
      break;
    default:
      return;
  }

  mouse_signal_ (event);
  if (repeat)
    mouse_signal_ (event);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::emitKeyboardEvent (unsigned long event_id)
{
  KeyboardEvent event (bool(event_id == vtkCommand::KeyPressEvent), interactor_->GetKeySym (),  interactor_->GetKeyCode (), interactor_->GetAltKey (), interactor_->GetControlKey (), interactor_->GetShiftKey ());
  keyboard_signal_ (event);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::MouseCallback (vtkObject*, unsigned long eid, void* clientdata, void* calldata)
{
  ImageViewer* window = reinterpret_cast<ImageViewer*> (clientdata);
  window->emitMouseEvent (eid);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::ImageViewer::KeyboardCallback (vtkObject*, unsigned long eid, void* clientdata, void* calldata)
{
  ImageViewer* window = reinterpret_cast<ImageViewer*> (clientdata);
  window->emitKeyboardEvent (eid);
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014-2017 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: Pavel Kirienko <pavel.kirienko@zubax.com>
 */

#include <ch.hpp>
#include <cstdlib>
#include <sys/types.h>
#include "sys.hpp"

static std::uint8_t g_operator_new_returns_pointer_to_this;

void* operator new(size_t)
{
    chSysHalt("operator new()");
    return &g_operator_new_returns_pointer_to_this;
}

void* operator new[](size_t)
{
    chSysHalt("operator new[]()");
    return &g_operator_new_returns_pointer_to_this;
}

void operator delete(void*)
{
    chSysHalt("delete");
}

void operator delete[](void*)
{
    chSysHalt("delete");
}

void operator delete(void*, unsigned)
{
    chSysHalt("delete");
}

void operator delete[](void*, unsigned)
{
    chSysHalt("delete");
}

/*
 * stdlibc++ workaround.
 * Default implementations will throw, which causes code size explosion.
 * These definitions override the ones defined in the stdlibc+++.
 */
namespace std
{

void __throw_bad_exception() { chSysHalt("throw"); }

void __throw_bad_alloc() { chSysHalt("throw"); }

void __throw_bad_cast() { chSysHalt("throw"); }

void __throw_bad_typeid() { chSysHalt("throw"); }

void __throw_logic_error(const char*) { chSysHalt("throw"); }

void __throw_domain_error(const char*) { chSysHalt("throw"); }

void __throw_invalid_argument(const char*) { chSysHalt("throw"); }

void __throw_length_error(const char*) { chSysHalt("throw"); }

void __throw_out_of_range(const char*) { chSysHalt("throw"); }

void __throw_out_of_range_fmt(const char*, ...) { chSysHalt("throw"); }

void __throw_runtime_error(const char*) { chSysHalt("throw"); }

void __throw_range_error(const char*) { chSysHalt("throw"); }

void __throw_overflow_error(const char*) { chSysHalt("throw"); }

void __throw_underflow_error(const char*) { chSysHalt("throw"); }

void __throw_ios_failure(const char*) { chSysHalt("throw"); }

void __throw_system_error(int) { chSysHalt("throw"); }

void __throw_future_error(int) { chSysHalt("throw"); }

void __throw_bad_function_call() { chSysHalt("throw"); }

}

namespace __gnu_cxx
{

void __verbose_terminate_handler()
{
    chSysHalt("terminate");
}

}

extern "C"
{

int __aeabi_atexit(void*, void(*)(void*), void*)
{
    return 0;
}

#ifdef __arm__
/**
 * Ref. "Run-time ABI for the ARM Architecture" page 23..24
 * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043d/IHI0043D_rtabi.pdf
 *
 * ChibiOS issue: http://forum.chibios.org/phpbb/viewtopic.php?f=3&t=2404
 *
 * A 32-bit, 4-byte-aligned static data value. The least significant 2 bits
 * must be statically initialized to 0.
 */
typedef int __guard;
#else
# error "Unknown architecture"
#endif

void __cxa_atexit(void(*)(void *), void*, void*)
{
}

int __cxa_guard_acquire(__guard* g)
{
    return !*g;
}

void __cxa_guard_release (__guard* g)
{
    *g = 1;
}

void __cxa_guard_abort (__guard*)
{
}

}

<commit_msg>Aligned operator delete for C++17<commit_after>/*
 * Copyright (c) 2014-2017 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: Pavel Kirienko <pavel.kirienko@zubax.com>
 */

#include <ch.hpp>
#include <cstdlib>
#include <sys/types.h>
#include "sys.hpp"
#include <new>

static std::uint8_t g_operator_new_returns_pointer_to_this;

void* operator new(std::size_t)
{
    chSysHalt("operator new()");
    return &g_operator_new_returns_pointer_to_this;
}

void* operator new[](std::size_t)
{
    chSysHalt("operator new[]()");
    return &g_operator_new_returns_pointer_to_this;
}

void operator delete(void*)
{
    chSysHalt("delete");
}

void operator delete[](void*)
{
    chSysHalt("delete");
}

void operator delete(void*, std::size_t)
{
    chSysHalt("delete");
}

void operator delete[](void*, std::size_t)
{
    chSysHalt("delete");
}

#if __cpp_aligned_new
void operator delete(void*, std::align_val_t)
{
    chSysHalt("delete");
}

void operator delete[](void*, std::align_val_t)
{
    chSysHalt("delete");
}

void operator delete(void*, std::size_t, std::align_val_t)
{
    chSysHalt("delete");
}

void operator delete[](void*, std::size_t, std::align_val_t)
{
    chSysHalt("delete");
}
#endif

/*
 * stdlibc++ workaround.
 * Default implementations will throw, which causes code size explosion.
 * These definitions override the ones defined in the stdlibc+++.
 */
namespace std
{

void __throw_bad_exception() { chSysHalt("throw"); }

void __throw_bad_alloc() { chSysHalt("throw"); }

void __throw_bad_cast() { chSysHalt("throw"); }

void __throw_bad_typeid() { chSysHalt("throw"); }

void __throw_logic_error(const char*) { chSysHalt("throw"); }

void __throw_domain_error(const char*) { chSysHalt("throw"); }

void __throw_invalid_argument(const char*) { chSysHalt("throw"); }

void __throw_length_error(const char*) { chSysHalt("throw"); }

void __throw_out_of_range(const char*) { chSysHalt("throw"); }

void __throw_out_of_range_fmt(const char*, ...) { chSysHalt("throw"); }

void __throw_runtime_error(const char*) { chSysHalt("throw"); }

void __throw_range_error(const char*) { chSysHalt("throw"); }

void __throw_overflow_error(const char*) { chSysHalt("throw"); }

void __throw_underflow_error(const char*) { chSysHalt("throw"); }

void __throw_ios_failure(const char*) { chSysHalt("throw"); }

void __throw_system_error(int) { chSysHalt("throw"); }

void __throw_future_error(int) { chSysHalt("throw"); }

void __throw_bad_function_call() { chSysHalt("throw"); }

}

namespace __gnu_cxx
{

void __verbose_terminate_handler()
{
    chSysHalt("terminate");
}

}

extern "C"
{

int __aeabi_atexit(void*, void(*)(void*), void*)
{
    return 0;
}

#ifdef __arm__
/**
 * Ref. "Run-time ABI for the ARM Architecture" page 23..24
 * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043d/IHI0043D_rtabi.pdf
 *
 * ChibiOS issue: http://forum.chibios.org/phpbb/viewtopic.php?f=3&t=2404
 *
 * A 32-bit, 4-byte-aligned static data value. The least significant 2 bits
 * must be statically initialized to 0.
 */
typedef int __guard;
#else
# error "Unknown architecture"
#endif

void __cxa_atexit(void(*)(void *), void*, void*)
{
}

int __cxa_guard_acquire(__guard* g)
{
    return !*g;
}

void __cxa_guard_release (__guard* g)
{
    *g = 1;
}

void __cxa_guard_abort (__guard*)
{
}

}

<|endoftext|>


<commit_before>
#include "config.h"

// system
#include <iostream>
#include <sstream>

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

// dune-common
#include <dune/common/exceptions.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/timer.hh>

// dune-grid
#include <dune/grid/io/file/vtk/vtkwriter.hh>

// dune-grid-multiscale
#include <dune/grid/part/leaf.hh>

// dune-fem
#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

// dune-stuff
#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/function/expression.hh>

// dune-detailed-discretizations
#include <dune/detailed/discretizations/discretefunctionspace/continuous/lagrange.hh>
#include <dune/detailed/discretizations/discretefunctionspace/sub/linear.hh>
#include <dune/detailed/discretizations/evaluation/local/binary/elliptic.hh>
#include <dune/detailed/discretizations/discreteoperator/local/codim0/integral.hh>
#include <dune/detailed/discretizations/evaluation/local/unary/scale.hh>
#include <dune/detailed/discretizations/discretefunctional/local/codim0/integral.hh>
#include <dune/detailed/discretizations/la/factory/eigen.hh>
#include <dune/detailed/discretizations/assembler/local/codim0/matrix.hh>
#include <dune/detailed/discretizations/assembler/local/codim0/vector.hh>
#include <dune/detailed/discretizations/assembler/system/constrained.hh>
#include <dune/detailed/discretizations/la/backend/solver/eigen.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>

const std::string id = "elliptic.continuousgalerkin";

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(std::string filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[stuff.grid.provider.cube]" << std::endl;
    file << "numElements = 4" << std::endl;
    file << "filename = " << id << ".grid" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "maxIter = 5000"  << std::endl;
    file << "precision = 1e-12"  << std::endl;
    file << "[visualization]" << std::endl;
    file << "filename = " << id << ".solution" << std::endl;
    file << "name = solution" << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

#ifndef POLORDER
const int polOrder = 1;
#else
const int polOrder = POLORDER;
#endif

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".param";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree paramTree(argc, argv, paramFilename);

    // timer
    Dune::Timer timer;

    // grid
    std::cout << "setting up grid:" << std::endl;
    typedef Dune::Stuff::Grid::Provider::Cube<> GridProviderType;
    paramTree.assertSub(GridProviderType::id(), id);
    const GridProviderType gridProvider(paramTree.sub(GridProviderType::id()));
    typedef GridProviderType::GridType GridType;
    const GridType& grid = gridProvider.grid();
    typedef Dune::grid::Part::Leaf::Const< GridType > GridPartType;
    const GridPartType gridPart(grid);
    std::cout << "  took " << timer.elapsed() << " sec, has " << grid.size(0) << " entities" << std::endl;
    std::cout << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider.visualize(paramTree.sub(GridProviderType::id()).get("filename", id + ".grid"));
    std::cout << " done (took " << timer.elapsed() << " sek)" << std::endl;

    // spaces
    std::cout << "initializing spaces... " << std::flush;
    timer.reset();
    const int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const int DUNE_UNUSED(dimRange) = 1;
    typedef double DomainFieldType;
    typedef double RangeFieldType;
    typedef Dune::FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, dimRange > FunctionSpaceType;
    typedef Dune::Detailed::Discretizations::DiscreteFunctionSpace::Continuous::Lagrange< FunctionSpaceType, GridPartType, polOrder > TestSpaceType;
    const TestSpaceType testSpace(gridPart);
    typedef Dune::Detailed::Discretizations::DiscreteFunctionSpace::Sub::Linear::Dirichlet< TestSpaceType > AnsatzSpaceType;
    const AnsatzSpaceType ansatzSpace(testSpace);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // data
    std::cout << "initializing data functions... " << std::flush;
    timer.reset();
    typedef Dune::Stuff::Function::Expression< DomainFieldType, dimDomain, RangeFieldType, dimRange > DiffusionType;
    paramTree.assertSub("diffusion", id);
    const Dune::shared_ptr< const DiffusionType > diffusion(new DiffusionType(paramTree.sub("diffusion")));
    typedef DiffusionType ForceType;
    paramTree.assertSub("force", id);
    const Dune::shared_ptr< const ForceType > force(new ForceType(paramTree.sub("force")));
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // left hand side (operator)
    std::cout << "initializing operator and functional... " << std::flush;
    timer.reset();
    typedef Dune::Detailed::Discretizations::Evaluation::Local::Binary::Elliptic< FunctionSpaceType, DiffusionType > EllipticEvaluationType;
    const EllipticEvaluationType ellipticEvaluation(diffusion, paramTree.sub("diffusion").get("order", 0));
    typedef Dune::Detailed::Discretizations::DiscreteOperator::Local::Codim0::Integral< EllipticEvaluationType > EllipticOperatorType;
    const EllipticOperatorType ellipticOperator(ellipticEvaluation);
    // right hand side (functional)
    typedef Dune::Detailed::Discretizations::Evaluation::Local::Unary::Scale< FunctionSpaceType, ForceType > ProductEvaluationType;
    const ProductEvaluationType productEvaluation(force, paramTree.sub("force").get("order", 0));
    typedef Dune::Detailed::Discretizations::DiscreteFunctional::Local::Codim0::Integral< ProductEvaluationType > L2FunctionalType;
    const L2FunctionalType l2Functional(productEvaluation);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // system matrix and right hand side
    std::cout << "initializing matrix and vector containers..." << std::flush;
    timer.reset();
    typedef AnsatzSpaceType::PatternType PatternType;
    const Dune::shared_ptr< const PatternType > pattern = ansatzSpace.computePattern(testSpace);
    typedef Dune::Detailed::Discretizations::LA::Factory::Eigen< RangeFieldType > ContainerFactory;
    typedef ContainerFactory::SparseMatrixType MatrixBackendType;
    MatrixBackendType systemMatrix = ContainerFactory::createSparseMatrix(ansatzSpace.map().size(), testSpace.map().size(), *pattern);
    typedef ContainerFactory::DenseVectorType VectorBackendType;
    VectorBackendType rhs = ContainerFactory::createDenseVector(testSpace.map().size());
    VectorBackendType ret = ContainerFactory::createDenseVector(testSpace);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // assembler
    std::cout << "assembing system... " << std::flush;
    timer.reset();
    typedef Dune::Detailed::Discretizations::Assembler::Local::Codim0::Matrix< EllipticOperatorType > LocalMatrixAssemblerType;
    const LocalMatrixAssemblerType localmatrixAssembler(ellipticOperator);
    typedef Dune::Detailed::Discretizations::Assembler::Local::Codim0::Vector< L2FunctionalType > LocalVectorAssemblerType;
    const LocalVectorAssemblerType localVectorAssembler(l2Functional);
    typedef Dune::Detailed::Discretizations::Assembler::System::Constrained< AnsatzSpaceType, TestSpaceType > SystemAssemblerType;
    const SystemAssemblerType systemAssembler(ansatzSpace, testSpace);
    systemAssembler.assembleSystem(localmatrixAssembler, systemMatrix, localVectorAssembler, rhs);
    systemAssembler.applyConstraints(systemMatrix, rhs);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // solve system
    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::BicgstabIlut Solver;
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::BicgstabDiagonal Solver;
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::CgDiagonalUpper Solver; // seems to produce strange results
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::CgDiagonalLower Solver; // seems to produce strange results
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::SimplicialcholeskyUpper Solver; // seems to produce strange results
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::SimplicialcholeskyLower Solver; // seems to produce strange results
    std::cout << "solving linear system (of size " << systemMatrix.rows() << "x" << systemMatrix.cols() << ")" << std::endl
              << "  using " << Solver::id << "... " << std::flush;
    paramTree.assertSub("solver", id);
    timer.reset();
    Solver::apply(
      systemMatrix,
      ret,
      rhs,
      paramTree.sub("solver").get("maxIter", 5000),
      paramTree.sub("solver").get("precision", 1e-12));
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // postprocess
    paramTree.assertSub("visualization");
    const std::string solutionName = paramTree.sub("visualization").get("name", "solution");
    const std::string solutionFilename = paramTree.sub("visualization").get("filename", id + ".solution");
    std::cout << "writing '" << solutionName << "' to '" << solutionFilename;
    if (dimDomain == 1)
      std::cout << ".vtp";
    else
      std::cout << ".vtu";
    std::cout << "'... " << std::flush;
    typedef Dune::Detailed::Discretizations::DiscreteFunction::Default< AnsatzSpaceType, VectorBackendType > DiscreteFunctionType;
    Dune::shared_ptr< DiscreteFunctionType > solution(new DiscreteFunctionType(ansatzSpace, ret, solutionName));
    typedef Dune::VTKWriter< AnsatzSpaceType::GridViewType > VTKWriterType;
    VTKWriterType vtkWriter(ansatzSpace.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch(Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch(std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch( ... ) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<commit_msg>[examples.elliptic.continuousgalerkin] some cleanup<commit_after>#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <iostream>
#include <sstream>

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/timer.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/function/expression.hh>

#include <dune/detailed/discretizations/discretefunctionspace/continuous/lagrange.hh>
#include <dune/detailed/discretizations/discretefunctionspace/sub/linear.hh>
#include <dune/detailed/discretizations/evaluation/local/binary/elliptic.hh>
#include <dune/detailed/discretizations/discreteoperator/local/codim0/integral.hh>
#include <dune/detailed/discretizations/evaluation/local/unary/scale.hh>
#include <dune/detailed/discretizations/discretefunctional/local/codim0/integral.hh>
#include <dune/detailed/discretizations/la/factory/eigen.hh>
#include <dune/detailed/discretizations/assembler/local/codim0/matrix.hh>
#include <dune/detailed/discretizations/assembler/local/codim0/vector.hh>
#include <dune/detailed/discretizations/assembler/system/constrained.hh>
#include <dune/detailed/discretizations/la/backend/solver/eigen.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>

const std::string id = "elliptic.continuousgalerkin";

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(std::string filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << ".grid" << std::endl;
    file << "[stuff.grid.provider.cube]" << std::endl;
    file << "numElements = 4" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0"  << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "maxIter = 5000"  << std::endl;
    file << "precision = 1e-12"  << std::endl;
    file << "[visualization]" << std::endl;
    file << "filename = " << id << ".solution" << std::endl;
    file << "name = solution" << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

#ifndef POLORDER
const int polOrder = 1;
#else
const int polOrder = POLORDER;
#endif

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".param";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree paramTree(argc, argv, paramFilename);
    if (!paramTree.hasSub(id))
      DUNE_THROW(Dune::RangeError,
                 "\nError: missing sub " << id << " in the following Dune::ParameterTree:\n" << paramTree.reportString("  "));

    // timer
    Dune::Timer timer;

    // grid
    std::cout << "setting up grid:" << std::endl;
    typedef Dune::Stuff::Grid::Provider::Cube<> GridProviderType;
    const GridProviderType gridProvider = GridProviderType::createFromParamTree(paramTree);
    typedef GridProviderType::GridType GridType;
    const Dune::shared_ptr< const GridType > grid = gridProvider.grid();
    typedef Dune::grid::Part::Leaf::Const< GridType > GridPartType;
    const GridPartType gridPart(*grid);
    std::cout << "  took " << timer.elapsed() << " sec, has " << grid->size(0) << " entities" << std::endl;
    std::cout << "visualizing grid... " << std::flush;
    if (!paramTree.sub(id).hasKey("filename"))
      DUNE_THROW(Dune::RangeError,
                 "\nError: missing key 'filename' in the following Dune::parameterTree:\n" << paramTree.sub(id).reportString("  "););
    timer.reset();
    gridProvider.visualize(paramTree.sub(GridProviderType::id()).get("filename", id + ".grid"));
    std::cout << " done (took " << timer.elapsed() << " sek)" << std::endl;

    // spaces
    std::cout << "initializing spaces... " << std::flush;
    timer.reset();
    const int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const int DUNE_UNUSED(dimRange) = 1;
    typedef double DomainFieldType;
    typedef double RangeFieldType;
    typedef Dune::FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, dimRange > FunctionSpaceType;
    typedef Dune::Detailed::Discretizations::DiscreteFunctionSpace::Continuous::Lagrange< FunctionSpaceType, GridPartType, polOrder > TestSpaceType;
    const TestSpaceType testSpace(gridPart);
    typedef Dune::Detailed::Discretizations::DiscreteFunctionSpace::Sub::Linear::Dirichlet< TestSpaceType > AnsatzSpaceType;
    const AnsatzSpaceType ansatzSpace(testSpace);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // data
    std::cout << "initializing data functions... " << std::flush;
    timer.reset();
    typedef Dune::Stuff::Function::Expression< DomainFieldType, dimDomain, RangeFieldType, dimRange > ExpressionFunctionType;
    if (!paramTree.hasSub("diffusion"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing sub 'diffusion' in the following Dune::ParameterTree:\n" << paramTree.reportString("  "));
    if (!paramTree.sub("diffusion").hasKey("order"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing key 'order' in the following Dune::ParameterTree:\n" << paramTree.sub("order").reportString("  "));
    const Dune::shared_ptr< const ExpressionFunctionType >
        diffusion(new ExpressionFunctionType(ExpressionFunctionType::createFromParamTree(paramTree.sub("diffusion"))));
    if (!paramTree.hasSub("force"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing sub 'force' in the following Dune::ParameterTree:\n" << paramTree.reportString("  "));
    if (!paramTree.sub("force").hasKey("order"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing key 'order' in the following Dune::ParameterTree:\n" << paramTree.sub("force").reportString("  "));
    const Dune::shared_ptr< const ExpressionFunctionType >
        force(new ExpressionFunctionType(ExpressionFunctionType::createFromParamTree(paramTree.sub("force"))));
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // left hand side (operator)
    std::cout << "initializing operator and functional... " << std::flush;
    timer.reset();
    typedef Dune::Detailed::Discretizations
        ::Evaluation
        ::Local
        ::Binary
        ::Elliptic< FunctionSpaceType, ExpressionFunctionType >
      EllipticEvaluationType;
    const EllipticEvaluationType ellipticEvaluation(diffusion, paramTree.sub("diffusion").get("order", 0));
    typedef Dune::Detailed::Discretizations
        ::DiscreteOperator
        ::Local
        ::Codim0
        ::Integral< EllipticEvaluationType >
      EllipticOperatorType;
    const EllipticOperatorType ellipticOperator(ellipticEvaluation);
    // right hand side (functional)
    typedef Dune::Detailed::Discretizations
        ::Evaluation
        ::Local
        ::Unary
        ::Scale< FunctionSpaceType, ExpressionFunctionType >
      ProductEvaluationType;
    const ProductEvaluationType productEvaluation(force, paramTree.sub("force").get("order", 0));
    typedef Dune::Detailed::Discretizations
        ::DiscreteFunctional
        ::Local
        ::Codim0
        ::Integral< ProductEvaluationType >
      L2FunctionalType;
    const L2FunctionalType l2Functional(productEvaluation);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // system matrix and right hand side
    std::cout << "initializing matrix and vector containers..." << std::flush;
    timer.reset();
    typedef AnsatzSpaceType::PatternType PatternType;
    const Dune::shared_ptr< const PatternType > pattern = ansatzSpace.computePattern(testSpace);
    typedef Dune::Detailed::Discretizations::LA::Factory::Eigen< RangeFieldType > ContainerFactory;
    typedef ContainerFactory::SparseMatrixType MatrixBackendType;
    MatrixBackendType systemMatrix = ContainerFactory::createSparseMatrix(ansatzSpace.map().size(), testSpace.map().size(), *pattern);
    typedef ContainerFactory::DenseVectorType VectorBackendType;
    VectorBackendType rhs = ContainerFactory::createDenseVector(testSpace.map().size());
    VectorBackendType ret = ContainerFactory::createDenseVector(testSpace);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // assembler
    std::cout << "assembing system... " << std::flush;
    timer.reset();
    typedef Dune::Detailed::Discretizations::Assembler::Local::Codim0::Matrix< EllipticOperatorType > LocalMatrixAssemblerType;
    const LocalMatrixAssemblerType localmatrixAssembler(ellipticOperator);
    typedef Dune::Detailed::Discretizations::Assembler::Local::Codim0::Vector< L2FunctionalType > LocalVectorAssemblerType;
    const LocalVectorAssemblerType localVectorAssembler(l2Functional);
    typedef Dune::Detailed::Discretizations::Assembler::System::Constrained< AnsatzSpaceType, TestSpaceType > SystemAssemblerType;
    const SystemAssemblerType systemAssembler(ansatzSpace, testSpace);
    systemAssembler.assembleSystem(localmatrixAssembler, systemMatrix, localVectorAssembler, rhs);
    systemAssembler.applyConstraints(systemMatrix, rhs);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // solve system
    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::BicgstabIlut Solver;
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::BicgstabDiagonal Solver;
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::CgDiagonalUpper Solver; // seems to produce strange results
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::CgDiagonalLower Solver; // seems to produce strange results
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::SimplicialcholeskyUpper Solver; // seems to produce strange results
//    typedef Dune::Detailed::Discretizations::LA::Solver::Eigen::SimplicialcholeskyLower Solver; // seems to produce strange results
    std::cout << "solving linear system (of size " << systemMatrix.rows() << "x" << systemMatrix.cols() << ")" << std::endl
              << "  using " << Solver::id << "... " << std::flush;
    if (!paramTree.hasSub("solver"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing sub 'solver' in the following Dune::ParameterTree:\n" << paramTree.reportString("  "));
    if (!paramTree.sub("solver").hasKey("maxIter"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing key 'maxIter' in the following Dune::ParameterTree:\n" << paramTree.sub("solver").reportString("  "));
    if (!paramTree.sub("solver").hasKey("precision"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing key 'precision' in the following Dune::ParameterTree:\n" << paramTree.sub("solver").reportString("  "));
    timer.reset();
    Solver::apply(
      systemMatrix,
      ret,
      rhs,
      paramTree.sub("solver").get("maxIter", 5000),
      paramTree.sub("solver").get("precision", 1e-12));
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // postprocess
    if (!paramTree.hasSub("visualization"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing sub 'visualization' in the following Dune::ParameterTree:\n" << paramTree.reportString("  "));
    if (!paramTree.sub("visualization").hasKey("name"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing key 'name' in the following Dune::ParameterTree:\n" << paramTree.sub("visualization").reportString("  "));
    if (!paramTree.sub("visualization").hasKey("filename"))
      DUNE_THROW(Dune::RangeError,
                 "\Error: missing key 'filename' in the following Dune::ParameterTree:\n" << paramTree.sub("visualization").reportString("  "));
    const std::string solutionName = paramTree.sub("visualization").get("name", "solution");
    const std::string solutionFilename = paramTree.sub("visualization").get("filename", id + ".solution");
    std::cout << "writing '" << solutionName << "' to '" << solutionFilename;
    if (dimDomain == 1)
      std::cout << ".vtp";
    else
      std::cout << ".vtu";
    std::cout << "'... " << std::flush;
    typedef Dune::Detailed::Discretizations::DiscreteFunction::Default< AnsatzSpaceType, VectorBackendType > DiscreteFunctionType;
    Dune::shared_ptr< DiscreteFunctionType > solution(new DiscreteFunctionType(ansatzSpace, ret, solutionName));
    typedef Dune::VTKWriter< AnsatzSpaceType::GridViewType > VTKWriterType;
    VTKWriterType vtkWriter(ansatzSpace.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    std::cout << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch(Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch(std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch( ... ) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<|endoftext|>


<commit_before>#include <event/event_callback.h>

#include <io/pipe/pipe.h>

#include <zlib/inflate_pipe.h>

#define	INFLATE_CHUNK_SIZE	65536

InflatePipe::InflatePipe(void)
: PipeProducer("/zlib/inflate_pipe"),
  stream_()
{
	stream_.zalloc = Z_NULL;
	stream_.zfree = Z_NULL;
	stream_.opaque = Z_NULL;

	stream_.avail_in = 0;
	stream_.next_in = Z_NULL;

	int error = inflateInit(&stream_);
	if (error != Z_OK)
		HALT(log_) << "Could not initialize inflate stream.";
}

InflatePipe::~InflatePipe()
{
	int error = inflateEnd(&stream_);
	if (error != Z_OK)
		ERROR(log_) << "Inflate stream did not end cleanly.";
}

void
InflatePipe::consume(Buffer *in)
{
	Buffer out;
	uint8_t outbuf[INFLATE_CHUNK_SIZE];
	bool first = true;

	stream_.avail_out = sizeof outbuf;
	stream_.next_out = outbuf;

	for (;;) {
		Buffer::SegmentIterator iter = in->segments();
		const BufferSegment *seg;
		int flush;

		if (iter.end()) {
			seg = NULL;
			flush = first ? Z_FINISH : Z_SYNC_FLUSH;

			stream_.avail_in = 0;
			stream_.next_in = Z_NULL;
		} else {
			seg = *iter;
			flush = Z_NO_FLUSH;
			first = false;

			stream_.avail_in = seg->length();
			stream_.next_in = (Bytef *)(uintptr_t)seg->data();
		}

		for (;;) {
			int error = inflate(&stream_, flush);
			if (error == Z_OK && stream_.avail_out > 0 &&
			    flush == Z_NO_FLUSH)
				break;
			if (error == Z_NEED_DICT || error == Z_DATA_ERROR ||
			    error == Z_MEM_ERROR) {
				ERROR(log_) << "inflate(): " << zError(error);
				produce_error();
				return;
			}

			if (flush != Z_NO_FLUSH && error == Z_BUF_ERROR &&
			    stream_.avail_out == sizeof outbuf)
				error = Z_OK;

			if (stream_.avail_out != sizeof outbuf)
				out.append(outbuf, sizeof outbuf - stream_.avail_out);
			stream_.avail_out = sizeof outbuf;
			stream_.next_out = outbuf;

			if (flush == Z_NO_FLUSH)
				break;
			if (error == Z_OK || error == Z_STREAM_END) {
				if (flush == Z_FINISH && error == Z_STREAM_END) {
					produce_eos(&out);
				} else {
					produce(&out);
				}

				if (!in->empty()) {
					ERROR(log_) << "Stream ended but more data follows.";
					produce_error();
				}
				return;
			}
			/* More data to output.  */
		}

		if (seg != NULL)
			in->skip(seg->length() - stream_.avail_in);
	}
	NOTREACHED();
}
<commit_msg>Don't produce EOS unintentially.<commit_after>#include <event/event_callback.h>

#include <io/pipe/pipe.h>

#include <zlib/inflate_pipe.h>

#define	INFLATE_CHUNK_SIZE	65536

InflatePipe::InflatePipe(void)
: PipeProducer("/zlib/inflate_pipe"),
  stream_()
{
	stream_.zalloc = Z_NULL;
	stream_.zfree = Z_NULL;
	stream_.opaque = Z_NULL;

	stream_.avail_in = 0;
	stream_.next_in = Z_NULL;

	int error = inflateInit(&stream_);
	if (error != Z_OK)
		HALT(log_) << "Could not initialize inflate stream.";
}

InflatePipe::~InflatePipe()
{
	int error = inflateEnd(&stream_);
	if (error != Z_OK)
		ERROR(log_) << "Inflate stream did not end cleanly.";
}

void
InflatePipe::consume(Buffer *in)
{
	Buffer out;
	uint8_t outbuf[INFLATE_CHUNK_SIZE];
	bool first = true;

	stream_.avail_out = sizeof outbuf;
	stream_.next_out = outbuf;

	for (;;) {
		Buffer::SegmentIterator iter = in->segments();
		const BufferSegment *seg;
		int flush;

		if (iter.end()) {
			seg = NULL;
			flush = first ? Z_FINISH : Z_SYNC_FLUSH;

			stream_.avail_in = 0;
			stream_.next_in = Z_NULL;
		} else {
			seg = *iter;
			flush = Z_NO_FLUSH;
			first = false;

			stream_.avail_in = seg->length();
			stream_.next_in = (Bytef *)(uintptr_t)seg->data();
		}

		for (;;) {
			int error = inflate(&stream_, flush);
			if (error == Z_OK && stream_.avail_out > 0 &&
			    flush == Z_NO_FLUSH)
				break;
			if (error == Z_NEED_DICT || error == Z_DATA_ERROR ||
			    error == Z_MEM_ERROR) {
				ERROR(log_) << "inflate(): " << zError(error);
				produce_error();
				return;
			}

			if (flush != Z_NO_FLUSH && error == Z_BUF_ERROR &&
			    stream_.avail_out == sizeof outbuf)
				error = Z_OK;

			if (stream_.avail_out != sizeof outbuf)
				out.append(outbuf, sizeof outbuf - stream_.avail_out);
			stream_.avail_out = sizeof outbuf;
			stream_.next_out = outbuf;

			if (flush == Z_NO_FLUSH)
				break;
			if (error == Z_OK || error == Z_STREAM_END) {
				if (flush == Z_FINISH && error == Z_STREAM_END) {
					produce_eos(&out);
				} else {
					/*
					 * XXX
					 * How can it happen that we get nothing
					 * here?
					 */
					if (!out.empty())
						produce(&out);
				}

				if (!in->empty()) {
					ERROR(log_) << "Stream ended but more data follows.";
					produce_error();
				}
				return;
			}
			/* More data to output.  */
		}

		if (seg != NULL)
			in->skip(seg->length() - stream_.avail_in);
	}
	NOTREACHED();
}
<|endoftext|>


<commit_before>// @(#)root/graf:$Id$
// Author: Matthew.Adam.Dobbs   06/09/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <stdio.h>

#include "TLegendEntry.h"
#include "TVirtualPad.h"
#include "TROOT.h"
#include "Riostream.h"

ClassImp(TLegendEntry)

//____________________________________________________________________________
// TLegendEntry   Matthew.Adam.Dobbs@Cern.CH, September 1999
// Storage class for one entry of a TLegend
//

//____________________________________________________________________________
TLegendEntry::TLegendEntry(): TAttText(), TAttLine(), TAttFill(), TAttMarker()
{
   // TLegendEntry do-nothing default constructor

   fObject = 0;
}

//____________________________________________________________________________
TLegendEntry::TLegendEntry(const TObject* obj, const char* label, Option_t* option )
             :TAttText(0,0,0,0,0), TAttLine(1,1,1), TAttFill(0,0), TAttMarker(1,21,1)
{
   // TLegendEntry normal constructor for one entry in a TLegend
   //   obj is the object this entry will represent. If obj has
   //   line/fill/marker attributes, then the TLegendEntry will display
   //   these attributes.
   //   label is the text that will describe the entry, it is displayed using
   //   TLatex, so may have a complex format.
   //   option may have values
   //    L draw line associated w/ TAttLine if obj inherits from TAttLine
   //    P draw polymarker assoc. w/ TAttMarker if obj inherits from TAttMarker
   //    F draw a box with fill associated w/ TAttFill if obj inherits TAttFill
   //   default is object = "LPF"

   fObject = 0;
   if ( !label && obj ) fLabel = obj->GetTitle();
   else                 fLabel = label;
   fOption = option;
   if (obj) SetObject((TObject*)obj);
}

//____________________________________________________________________________
TLegendEntry::TLegendEntry( const TLegendEntry &entry ) : TObject(entry), TAttText(entry), TAttLine(entry), TAttFill(entry), TAttMarker(entry)
{
   // TLegendEntry copy constructor

   ((TLegendEntry&)entry).Copy(*this);
}

//____________________________________________________________________________
TLegendEntry::~TLegendEntry()
{
   // TLegendEntry default destructor

   fObject = 0;
}

//____________________________________________________________________________
void TLegendEntry::Copy( TObject &obj ) const
{
   // copy this TLegendEntry into obj

   TObject::Copy(obj);
   TAttText::Copy((TLegendEntry&)obj);
   TAttLine::Copy((TLegendEntry&)obj);
   TAttFill::Copy((TLegendEntry&)obj);
   TAttMarker::Copy((TLegendEntry&)obj);
   ((TLegendEntry&)obj).fObject = fObject;
   ((TLegendEntry&)obj).fLabel = fLabel;
   ((TLegendEntry&)obj).fOption = fOption;
}

//____________________________________________________________________________
void TLegendEntry::Print( Option_t *) const
{
   // dump this TLegendEntry to cout

   TString output;
   cout << "TLegendEntry: Object ";
   if ( fObject ) output = fObject->GetName();
   else output = "NULL";
   cout << output << " Label ";
   if ( fLabel ) output = fLabel.Data();
   else output = "NULL";
   cout << output << " Option ";
   if (fOption ) output = fOption.Data();
   else output = "NULL";
   cout << output << endl;
}

//____________________________________________________________________________
void TLegendEntry::SaveEntry(ostream &out, const char* name )
{
   // Save this TLegendEntry as C++ statements on output stream out
   //  to be used with the SaveAs .C option

   char quote = '"';
   if ( gROOT->ClassSaved( TLegendEntry::Class() ) ) {
      out << "   entry=";
   } else {
      out << "   TLegendEntry *entry=";
   }
   TString objname = "NULL";
   if ( fObject ) objname = fObject->GetName();
   out << name << "->AddEntry("<<quote<<objname<<quote<<","<<quote<<
      fLabel.Data()<<quote<<","<<quote<<fOption.Data()<<quote<<");"<<endl;
   SaveFillAttributes(out,"entry",0,0);
   SaveLineAttributes(out,"entry",0,0,0);
   SaveMarkerAttributes(out,"entry",0,0,0);
   SaveTextAttributes(out,"entry",0,0,0,0,0);
}

//____________________________________________________________________________
void TLegendEntry::SetObject(TObject* obj )
{
   // (re)set the obj pointed to by this entry

   if ( ( fObject && fLabel == fObject->GetTitle() ) || !fLabel ) {
      fLabel = obj->GetTitle();
   }
   fObject = obj;
}

//____________________________________________________________________________
void TLegendEntry::SetObject( const char* objectName)
{
   // (re)set the obj pointed to by this entry

   TObject* obj = 0;
   TList* padprimitives = gPad->GetListOfPrimitives();
   if (padprimitives) obj = padprimitives->FindObject( objectName );
   if (obj) SetObject( obj );
}
<commit_msg>Protect TlegendEntry::SetObject against obj null<commit_after>// @(#)root/graf:$Id$
// Author: Matthew.Adam.Dobbs   06/09/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <stdio.h>

#include "TLegendEntry.h"
#include "TVirtualPad.h"
#include "TROOT.h"
#include "Riostream.h"

ClassImp(TLegendEntry)

//____________________________________________________________________________
// TLegendEntry   Matthew.Adam.Dobbs@Cern.CH, September 1999
// Storage class for one entry of a TLegend
//

//____________________________________________________________________________
TLegendEntry::TLegendEntry(): TAttText(), TAttLine(), TAttFill(), TAttMarker()
{
   // TLegendEntry do-nothing default constructor

   fObject = 0;
}

//____________________________________________________________________________
TLegendEntry::TLegendEntry(const TObject* obj, const char* label, Option_t* option )
             :TAttText(0,0,0,0,0), TAttLine(1,1,1), TAttFill(0,0), TAttMarker(1,21,1)
{
   // TLegendEntry normal constructor for one entry in a TLegend
   //   obj is the object this entry will represent. If obj has
   //   line/fill/marker attributes, then the TLegendEntry will display
   //   these attributes.
   //   label is the text that will describe the entry, it is displayed using
   //   TLatex, so may have a complex format.
   //   option may have values
   //    L draw line associated w/ TAttLine if obj inherits from TAttLine
   //    P draw polymarker assoc. w/ TAttMarker if obj inherits from TAttMarker
   //    F draw a box with fill associated w/ TAttFill if obj inherits TAttFill
   //   default is object = "LPF"

   fObject = 0;
   if ( !label && obj ) fLabel = obj->GetTitle();
   else                 fLabel = label;
   fOption = option;
   if (obj) SetObject((TObject*)obj);
}

//____________________________________________________________________________
TLegendEntry::TLegendEntry( const TLegendEntry &entry ) : TObject(entry), TAttText(entry), TAttLine(entry), TAttFill(entry), TAttMarker(entry)
{
   // TLegendEntry copy constructor

   ((TLegendEntry&)entry).Copy(*this);
}

//____________________________________________________________________________
TLegendEntry::~TLegendEntry()
{
   // TLegendEntry default destructor

   fObject = 0;
}

//____________________________________________________________________________
void TLegendEntry::Copy( TObject &obj ) const
{
   // copy this TLegendEntry into obj

   TObject::Copy(obj);
   TAttText::Copy((TLegendEntry&)obj);
   TAttLine::Copy((TLegendEntry&)obj);
   TAttFill::Copy((TLegendEntry&)obj);
   TAttMarker::Copy((TLegendEntry&)obj);
   ((TLegendEntry&)obj).fObject = fObject;
   ((TLegendEntry&)obj).fLabel = fLabel;
   ((TLegendEntry&)obj).fOption = fOption;
}

//____________________________________________________________________________
void TLegendEntry::Print( Option_t *) const
{
   // dump this TLegendEntry to cout

   TString output;
   cout << "TLegendEntry: Object ";
   if ( fObject ) output = fObject->GetName();
   else output = "NULL";
   cout << output << " Label ";
   if ( fLabel ) output = fLabel.Data();
   else output = "NULL";
   cout << output << " Option ";
   if (fOption ) output = fOption.Data();
   else output = "NULL";
   cout << output << endl;
}

//____________________________________________________________________________
void TLegendEntry::SaveEntry(ostream &out, const char* name )
{
   // Save this TLegendEntry as C++ statements on output stream out
   //  to be used with the SaveAs .C option

   char quote = '"';
   if ( gROOT->ClassSaved( TLegendEntry::Class() ) ) {
      out << "   entry=";
   } else {
      out << "   TLegendEntry *entry=";
   }
   TString objname = "NULL";
   if ( fObject ) objname = fObject->GetName();
   out << name << "->AddEntry("<<quote<<objname<<quote<<","<<quote<<
      fLabel.Data()<<quote<<","<<quote<<fOption.Data()<<quote<<");"<<endl;
   SaveFillAttributes(out,"entry",0,0);
   SaveLineAttributes(out,"entry",0,0,0);
   SaveMarkerAttributes(out,"entry",0,0,0);
   SaveTextAttributes(out,"entry",0,0,0,0,0);
}

//____________________________________________________________________________
void TLegendEntry::SetObject(TObject* obj )
{
   // (re)set the obj pointed to by this entry

   if ( ( fObject && fLabel == fObject->GetTitle() ) || !fLabel ) {
      if (obj) fLabel = obj->GetTitle();
   }
   fObject = obj;
}

//____________________________________________________________________________
void TLegendEntry::SetObject( const char* objectName)
{
   // (re)set the obj pointed to by this entry

   TObject* obj = 0;
   TList* padprimitives = gPad->GetListOfPrimitives();
   if (padprimitives) obj = padprimitives->FindObject( objectName );
   if (obj) SetObject( obj );
}
<|endoftext|>


<commit_before>// *****************************************************************************
//
//     Copyright (c) 2008, Pleora Technologies Inc., All rights reserved.
//
// *****************************************************************************

#include <PvSampleUtils.h>
#include <PvDeviceFinderWnd.h>
#include <PvDevice.h>
#include <PvPipeline.h>
#include <PvBuffer.h>
#include <PvStream.h>
#include <PvStreamRaw.h>

PV_INIT_SIGNAL_HANDLER();

//
// Shows how to use a PvPipeline object to acquire images from a device
//

bool AcquireImages()
{
    // Create a GEV Device finder dialog
    PvDeviceFinderWnd lDeviceFinderWnd;

    // Prompt the user to select a GEV Device
    lDeviceFinderWnd.ShowModal();

    // Get the connectivity information for the selected GEV Device
    PvDeviceInfo* lDeviceInfo = lDeviceFinderWnd.GetSelected();

    // If no device is selected, abort
    if( lDeviceInfo == NULL )
    {
        printf( "No device selected.\n" );
        return false;
    }

    // Connect to the GEV Device
    PvDevice lDevice;
    printf( "Connecting to %s\n", lDeviceInfo->GetMACAddress().GetAscii() );
    if ( !lDevice.Connect( lDeviceInfo ).IsOK() )
    {
        printf( "Unable to connect to %s\n", lDeviceInfo->GetMACAddress().GetAscii() );
        return false;
    }
    printf( "Successfully connected to %s\n", lDeviceInfo->GetMACAddress().GetAscii() );
    printf( "\n" );

    // Get device parameters need to control streaming
    PvGenParameterArray *lDeviceParams = lDevice.GetGenParameters();

    // Negotiate streaming packet size
    lDevice.NegotiatePacketSize();

    // Create the PvStream object
    PvStream lStream;

    // Open stream - have the PvDevice do it for us
    printf( "Opening stream to device\n" );
    lStream.Open( lDeviceInfo->GetIPAddress() );

    // Create the PvPipeline object
    PvPipeline lPipeline( &lStream );

    // Reading payload size from device
    PvInt64 lSize = 0;
	lDeviceParams->GetIntegerValue( "PayloadSize", lSize );

    // Set the Buffer size and the Buffer count
    lPipeline.SetBufferSize( static_cast<PvUInt32>( lSize ) );
    lPipeline.SetBufferCount( 16 ); // Increase for high frame rate without missing block IDs

    // Have to set the Device IP destination to the Stream
    lDevice.SetStreamDestination( lStream.GetLocalIPAddress(), lStream.GetLocalPort() );

    // IMPORTANT: the pipeline needs to be "armed", or started before
    // we instruct the device to send us images
    printf( "Starting pipeline\n" );
    lPipeline.Start();

    // Get stream parameters/stats
    PvGenParameterArray *lStreamParams = lStream.GetParameters();

    // TLParamsLocked is optional but when present, it MUST be set to 1
    // before sending the AcquisitionStart command
	lDeviceParams->SetIntegerValue( "TLParamsLocked", 1 );

    printf( "Resetting timestamp counter...\n" );
	lDeviceParams->ExecuteCommand( "GevTimestampControlReset" );

    // The pipeline is already "armed", we just have to tell the device
    // to start sending us images
    printf( "Sending StartAcquisition command to device\n" );
	lDeviceParams->ExecuteCommand( "AcquisitionStart" );

    char lDoodle[] = "|\\-|-/";
    int lDoodleIndex = 0;
    PvInt64 lImageCountVal = 0;
    double lFrameRateVal = 0.0;
    double lBandwidthVal = 0.0;

    // Acquire images until the user instructs us to stop
    printf( "\n<press a key to stop streaming>\n" );
    while ( !PvKbHit() )
    {
        // Retrieve next buffer
        PvBuffer *lBuffer = NULL;
        PvResult  lOperationResult;
        PvResult lResult = lPipeline.RetrieveNextBuffer( &lBuffer, 1000, &lOperationResult );

        if ( lResult.IsOK() )
        {
            if ( lOperationResult.IsOK() )
            {
                //
                // We now have a valid buffer. This is where you would typically process the buffer.
                // -----------------------------------------------------------------------------------------
                // ...

				lStreamParams->GetIntegerValue( "ImagesCount", lImageCountVal );
				lStreamParams->GetFloatValue( "AcquisitionRateAverage", lFrameRateVal );
				lStreamParams->GetFloatValue( "BandwidthAverage", lBandwidthVal );

				// If the buffer contains an image, display width and height
				PvUInt32 lWidth = 0, lHeight = 0;
				if ( lBuffer->GetPayloadType() == PvPayloadTypeImage )
				{
					// Get image specific buffer interface
					PvImage *lImage = lBuffer->GetImage();

					// Read width, height
					lWidth = lBuffer->GetImage()->GetWidth();
					lHeight = lBuffer->GetImage()->GetHeight();
				}

				printf( "%c BlockID: %016llX W: %i H: %i %.01f FPS %.01f Mb/s\r",
                    lDoodle[ lDoodleIndex ],
                    lBuffer->GetBlockID(),
					lWidth,
					lHeight,
                    lFrameRateVal,
                    lBandwidthVal / 1000000.0 );
            }
            // We have an image - do some processing (...) and VERY IMPORTANT,
            // release the buffer back to the pipeline
            lPipeline.ReleaseBuffer( lBuffer );
        }
        else
        {
            // Timeout
            printf( "%c Timeout\r", lDoodle[ lDoodleIndex ] );
        }

        ++lDoodleIndex %= 6;
    }

    PvGetChar(); // Flush key buffer for next stop
    printf( "\n\n" );

    // Tell the device to stop sending images
    printf( "Sending AcquisitionStop command to the device\n" );
	lDeviceParams->ExecuteCommand( "AcquisitionStop" );

    // If present reset TLParamsLocked to 0. Must be done AFTER the
    // streaming has been stopped
	lDeviceParams->SetIntegerValue( "TLParamsLocked", 0 );

    // We stop the pipeline - letting the object lapse out of
    // scope would have had the destructor do the same, but we do it anyway
    printf( "Stop pipeline\n" );
    lPipeline.Stop();

    // Now close the stream. Also optionnal but nice to have
    printf( "Closing stream\n" );
    lStream.Close();

    // Finally disconnect the device. Optional, still nice to have
    printf( "Disconnecting device\n" );
    lDevice.Disconnect();

    return true;
}

//
// Main function
//

int main()
{
    // PvPipeline used to acquire images from a device
    printf( "1. PvPipeline sample - image acquisition from a device\n\n" );
    AcquireImages();

    printf( "\n<press a key to exit>\n" );
    PvWaitForKeyPress();

    return 0;
}

<commit_msg>update to stream to find device automatically without using user input<commit_after>// *****************************************************************************
//
//     Copyright (c) 2008, Pleora Technologies Inc., All rights reserved.
//
// *****************************************************************************

#include <PvSampleUtils.h>
#include <PvDeviceFinderWnd.h>
#include <PvDevice.h>
#include <PvPipeline.h>
#include <PvBuffer.h>
#include <PvStream.h>
#include <PvStreamRaw.h>

PV_INIT_SIGNAL_HANDLER();

//
// Shows how to use a PvPipeline object to acquire images from a device
//

bool AcquireImages()
{
    // Create a GEV Device finder dialog
    //PvDeviceFinderWnd lDeviceFinderWnd;

    // Prompt the user to select a GEV Device
    //lDeviceFinderWnd.ShowModal();

    // Get the connectivity information for the selected GEV Device
    //PvDeviceInfo* lDeviceInfo = lDeviceFinderWnd.GetSelected();
    PvSystem lSystem;
    PvDeviceInfo* lDeviceInfo;
    std::cout << "ImperxStream::Connect starting" << std::endl;
    PvResult lResult;

    // Find all GEV Devices on the network.
    lSystem.SetDetectionTimeout( 2000 );
    lResult = lSystem.Find();
    if( !lResult.IsOK() )
    {
        printf( "PvSystem::Find Error: %s", lResult.GetCodeString().GetAscii() );
        return -1;
    }

    // Get the number of GEV Interfaces that were found using GetInterfaceCount.
    PvUInt32 lInterfaceCount = lSystem.GetInterfaceCount();

    // Display information about all found interface
    // For each interface, display information about all devices.
    for( PvUInt32 x = 0; x < lInterfaceCount; x++ )
    {
        // get pointer to each of interface
        PvInterface * lInterface = lSystem.GetInterface( x );

        printf( "Interface %i\nMAC Address: %s\nIP Address: %s\nSubnet Mask: %s\n\n",
                x,
                lInterface->GetMACAddress().GetAscii(),
                lInterface->GetIPAddress().GetAscii(),
                lInterface->GetSubnetMask().GetAscii() );

        // Get the number of GEV devices that were found using GetDeviceCount.
        PvUInt32 lDeviceCount = lInterface->GetDeviceCount();

        for( PvUInt32 y = 0; y < lDeviceCount ; y++ )
        {
            lDeviceInfo = lInterface->GetDeviceInfo( y );
            printf( "Device %i\nMAC Address: %s\nIP Address: %s\nSerial number: %s\n\n",
                    y,
                    lDeviceInfo->GetMACAddress().GetAscii(),
                    lDeviceInfo->GetIPAddress().GetAscii(),
                    lDeviceInfo->GetSerialNumber().GetAscii() );
        }
    }

    // If no device is selected, abort
    if( lDeviceInfo == NULL )
    {
        printf( "No device selected.\n" );
        return false;
    }

    // Connect to the GEV Device
    PvDevice lDevice;
    printf( "Connecting to %s\n", lDeviceInfo->GetMACAddress().GetAscii() );
    if ( !lDevice.Connect( lDeviceInfo ).IsOK() )
    {
        printf( "Unable to connect to %s\n", lDeviceInfo->GetMACAddress().GetAscii() );
        return false;
    }
    printf( "Successfully connected to %s\n", lDeviceInfo->GetMACAddress().GetAscii() );
    printf( "\n" );

    // Get device parameters need to control streaming
    PvGenParameterArray *lDeviceParams = lDevice.GetGenParameters();

    // Negotiate streaming packet size
    lDevice.NegotiatePacketSize();

    // Create the PvStream object
    PvStream lStream;

    // Open stream - have the PvDevice do it for us
    printf( "Opening stream to device\n" );
    lStream.Open( lDeviceInfo->GetIPAddress() );

    // Create the PvPipeline object
    PvPipeline lPipeline( &lStream );

    // Reading payload size from device
    PvInt64 lSize = 0;
	lDeviceParams->GetIntegerValue( "PayloadSize", lSize );

    // Set the Buffer size and the Buffer count
    lPipeline.SetBufferSize( static_cast<PvUInt32>( lSize ) );
    lPipeline.SetBufferCount( 16 ); // Increase for high frame rate without missing block IDs

    // Have to set the Device IP destination to the Stream
    lDevice.SetStreamDestination( lStream.GetLocalIPAddress(), lStream.GetLocalPort() );

    // IMPORTANT: the pipeline needs to be "armed", or started before
    // we instruct the device to send us images
    printf( "Starting pipeline\n" );
    lPipeline.Start();

    // Get stream parameters/stats
    PvGenParameterArray *lStreamParams = lStream.GetParameters();

    // TLParamsLocked is optional but when present, it MUST be set to 1
    // before sending the AcquisitionStart command
	lDeviceParams->SetIntegerValue( "TLParamsLocked", 1 );

    printf( "Resetting timestamp counter...\n" );
	lDeviceParams->ExecuteCommand( "GevTimestampControlReset" );

    // The pipeline is already "armed", we just have to tell the device
    // to start sending us images
    printf( "Sending StartAcquisition command to device\n" );
	lDeviceParams->ExecuteCommand( "AcquisitionStart" );

    char lDoodle[] = "|\\-|-/";
    int lDoodleIndex = 0;
    PvInt64 lImageCountVal = 0;
    double lFrameRateVal = 0.0;
    double lBandwidthVal = 0.0;

    // Acquire images until the user instructs us to stop
    printf( "\n<press a key to stop streaming>\n" );
    while ( !PvKbHit() )
    {
        // Retrieve next buffer
        PvBuffer *lBuffer = NULL;
        PvResult  lOperationResult;
        PvResult lResult = lPipeline.RetrieveNextBuffer( &lBuffer, 1000, &lOperationResult );

        if ( lResult.IsOK() )
        {
            if ( lOperationResult.IsOK() )
            {
                //
                // We now have a valid buffer. This is where you would typically process the buffer.
                // -----------------------------------------------------------------------------------------
                // ...

				lStreamParams->GetIntegerValue( "ImagesCount", lImageCountVal );
				lStreamParams->GetFloatValue( "AcquisitionRateAverage", lFrameRateVal );
				lStreamParams->GetFloatValue( "BandwidthAverage", lBandwidthVal );

				// If the buffer contains an image, display width and height
				PvUInt32 lWidth = 0, lHeight = 0;
				if ( lBuffer->GetPayloadType() == PvPayloadTypeImage )
				{
					// Get image specific buffer interface
					PvImage *lImage = lBuffer->GetImage();

					// Read width, height
					lWidth = lBuffer->GetImage()->GetWidth();
					lHeight = lBuffer->GetImage()->GetHeight();
				}

				printf( "%c BlockID: %016llX W: %i H: %i %.01f FPS %.01f Mb/s\r",
                    lDoodle[ lDoodleIndex ],
                    lBuffer->GetBlockID(),
					lWidth,
					lHeight,
                    lFrameRateVal,
                    lBandwidthVal / 1000000.0 );
            }
            // We have an image - do some processing (...) and VERY IMPORTANT,
            // release the buffer back to the pipeline
            lPipeline.ReleaseBuffer( lBuffer );
        }
        else
        {
            // Timeout
            printf( "%c Timeout\r", lDoodle[ lDoodleIndex ] );
        }

        ++lDoodleIndex %= 6;
    }

    PvGetChar(); // Flush key buffer for next stop
    printf( "\n\n" );

    // Tell the device to stop sending images
    printf( "Sending AcquisitionStop command to the device\n" );
	lDeviceParams->ExecuteCommand( "AcquisitionStop" );

    // If present reset TLParamsLocked to 0. Must be done AFTER the
    // streaming has been stopped
	lDeviceParams->SetIntegerValue( "TLParamsLocked", 0 );

    // We stop the pipeline - letting the object lapse out of
    // scope would have had the destructor do the same, but we do it anyway
    printf( "Stop pipeline\n" );
    lPipeline.Stop();

    // Now close the stream. Also optionnal but nice to have
    printf( "Closing stream\n" );
    lStream.Close();

    // Finally disconnect the device. Optional, still nice to have
    printf( "Disconnecting device\n" );
    lDevice.Disconnect();

    return true;
}

//
// Main function
//

int main()
{
    // PvPipeline used to acquire images from a device
    printf( "1. PvPipeline sample - image acquisition from a device\n\n" );
    AcquireImages();

    printf( "\n<press a key to exit>\n" );
    PvWaitForKeyPress();

    return 0;
}

<|endoftext|>


<commit_before>#include <stack>
#include <vector>

#include <xercesc/sax2/DefaultHandler.hpp>

class SAX2Handler : public xercesc::DefaultHandler {
public:
    SAX2Handler();

    void startElement(
        const XMLCh* const uri,
        const XMLCh* const localname,
        const XMLCh* const qname,
        const xercesc::Attributes& attrs);

    void endElement(
        const XMLCh* const uri,
        const XMLCh* const localname,
        const XMLCh* const qname);

    void characters(const XMLCh* const chars,
        const XMLSize_t length);

private:
    // a stack to track where in the XML document we are since we're using SAX2 parsing
    std::stack<std::string> state;

    // page data we want to collect. we reset this after every page element is parsed.
    std::string title;
    std::vector<std::string> links;

    // is the current page a redirect page? we want to discard those. reset after every page element.
    bool redirect;

    // buffer for text content of current element being parsed. reset after every element.
    std::string text;
};
<commit_msg>use "#pragma once" in headers<commit_after>#pragma once

#include <stack>
#include <vector>

#include <xercesc/sax2/DefaultHandler.hpp>

class SAX2Handler : public xercesc::DefaultHandler {
public:
    SAX2Handler();

    void startElement(
        const XMLCh* const uri,
        const XMLCh* const localname,
        const XMLCh* const qname,
        const xercesc::Attributes& attrs);

    void endElement(
        const XMLCh* const uri,
        const XMLCh* const localname,
        const XMLCh* const qname);

    void characters(const XMLCh* const chars,
        const XMLSize_t length);

private:
    // a stack to track where in the XML document we are since we're using SAX2 parsing
    std::stack<std::string> state;

    // per-page data, reset after every page element is parsed
    std::string title;
    std::vector<std::string> links;
    bool redirect;

    // buffer for text content of current element, reset after every parsed element
    std::string text;
};
<|endoftext|>