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

  Program:   Visualization Toolkit
  Module:    MultiBlock.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// This example demonstrates how multi-block datasets can be processed
// using the new vtkMultiBlockDataSet class.
//
// The command line arguments are:
// -D <path> => path to the data (VTKData); the data should be in <path>/Data/

#include "vtkActor.h"
#include "vtkCellDataToPointData.h"
#include "vtkContourFilter.h"
#include "vtkDebugLeaks.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkCompositeDataGeometryFilter.h"
#include "vtkOutlineCornerFilter.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkShrinkPolyData.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredGridOutlineFilter.h"
#include "vtkTestUtilities.h"
#include "vtkXMLStructuredGridReader.h"
#include <vtksys/ios/sstream>

int main(int argc, char* argv[])
{
  // Standard rendering classes
  vtkRenderer *ren = vtkRenderer::New();
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren);
  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  // We will read three files and collect them together in one
  // multi-block dataset. I broke the combustor dataset into
  // three pieces and wrote them out separately.
  int i;
  vtkXMLStructuredGridReader* reader = vtkXMLStructuredGridReader::New();

  // vtkMultiBlockDataSet respresents multi-block datasets. See
  // the class documentation for more information.
  vtkMultiBlockDataSet* mb = vtkMultiBlockDataSet::New();

  for (i=0; i<3; i++)
    {
    // Here we load the three separate files (each containing
    // a structured grid dataset)
    vtksys_ios::ostringstream fname;
    fname << "Data/multicomb_" << i << ".vts" << ends;
    char* cfname =
      vtkTestUtilities::ExpandDataFileName(argc, argv, fname.str().c_str());
    reader->SetFileName(cfname);
    // We have to update since we are working without a VTK pipeline.
    // This will read the file and the output of the reader will be
    // a valid structured grid data.
    reader->Update();
    delete[] cfname;

    // We create a copy to avoid adding the same data three
    // times (the output object of the reader does not change
    // when the filename changes)
    vtkStructuredGrid* sg = vtkStructuredGrid::New();
    sg->ShallowCopy(reader->GetOutput());

    // Add the structured grid to the multi-block dataset
    mb->SetBlock(i, sg);
    sg->Delete();
    }
  reader->Delete();

  // Multi-block can be processed with regular VTK filters in two ways:
  // 1. Pass through a multi-block aware consumer. Since a multi-block
  //    aware mapper is not yet available, vtkCompositeDataGeometryFilter
  //    can be used
  // 2. Assign the composite executive (vtkCompositeDataPipeline) to
  //    all "simple" (that work only on simple, non-composite datasets) filters

  // outline
  vtkStructuredGridOutlineFilter* of = vtkStructuredGridOutlineFilter::New();
  of->SetInput(mb);

  // geometry filter
  // This filter is multi-block aware and will request blocks from the
  // input. These blocks will be processed by simple processes as if they
  // are the whole dataset
  vtkCompositeDataGeometryFilter* geom1 =
    vtkCompositeDataGeometryFilter::New();
  geom1->SetInputConnection(0, of->GetOutputPort(0));

  // Rendering objects
  vtkPolyDataMapper* geoMapper = vtkPolyDataMapper::New();
  geoMapper->SetInputConnection(0, geom1->GetOutputPort(0));

  vtkActor* geoActor = vtkActor::New();
  geoActor->SetMapper(geoMapper);
  geoActor->GetProperty()->SetColor(0, 0, 0);
  ren->AddActor(geoActor);

  // cell 2 point and contour
  vtkCellDataToPointData* c2p = vtkCellDataToPointData::New();
  c2p->SetInput(mb);

  vtkContourFilter* contour = vtkContourFilter::New();
  contour->SetInputConnection(0, c2p->GetOutputPort(0));
  contour->SetValue(0, 0.45);

  // geometry filter
  vtkCompositeDataGeometryFilter* geom2 =
    vtkCompositeDataGeometryFilter::New();
  geom2->SetInputConnection(0, contour->GetOutputPort(0));

  // Rendering objects
  vtkPolyDataMapper* contMapper = vtkPolyDataMapper::New();
  contMapper->SetInputConnection(0, geom2->GetOutputPort(0));

  vtkActor* contActor = vtkActor::New();
  contActor->SetMapper(contMapper);
  contActor->GetProperty()->SetColor(1, 0, 0);
  ren->AddActor(contActor);

  ren->SetBackground(1,1,1);
  renWin->SetSize(300,300);
  iren->Start();

  // Cleanup
  of->Delete();
  geom1->Delete();
  geoMapper->Delete();
  geoActor->Delete();
  c2p->Delete();
  contour->Delete();
  geom2->Delete();
  contMapper->Delete();
  contActor->Delete();
  ren->Delete();
  renWin->Delete();
  iren->Delete();
  mb->Delete();

  return 0;
}
<commit_msg>ENH: Changed the example to use the vtkCompositeDataPipeline as the default executive prototype.  Now the example works for the multiblock as expected.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    MultiBlock.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// This example demonstrates how multi-block datasets can be processed
// using the new vtkMultiBlockDataSet class.
//
// The command line arguments are:
// -D <path> => path to the data (VTKData); the data should be in <path>/Data/

#include "vtkActor.h"
#include "vtkCellDataToPointData.h"
#include "vtkCompositeDataGeometryFilter.h"
#include "vtkCompositeDataPipeline.h"
#include "vtkContourFilter.h"
#include "vtkDebugLeaks.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkOutlineCornerFilter.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkShrinkPolyData.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredGridOutlineFilter.h"
#include "vtkTestUtilities.h"
#include "vtkXMLStructuredGridReader.h"
#include <vtksys/ios/sstream>

int main(int argc, char* argv[])
{
  vtkCompositeDataPipeline* exec = vtkCompositeDataPipeline::New();
  vtkAlgorithm::SetDefaultExecutivePrototype(exec);
  exec->Delete();

  // Standard rendering classes
  vtkRenderer *ren = vtkRenderer::New();
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren);
  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  // We will read three files and collect them together in one
  // multi-block dataset. I broke the combustor dataset into
  // three pieces and wrote them out separately.
  int i;
  vtkXMLStructuredGridReader* reader = vtkXMLStructuredGridReader::New();

  // vtkMultiBlockDataSet respresents multi-block datasets. See
  // the class documentation for more information.
  vtkMultiBlockDataSet* mb = vtkMultiBlockDataSet::New();

  for (i=0; i<3; i++)
    {
    // Here we load the three separate files (each containing
    // a structured grid dataset)
    vtksys_ios::ostringstream fname;
    fname << "Data/multicomb_" << i << ".vts" << ends;
    char* cfname =
      vtkTestUtilities::ExpandDataFileName(argc, argv, fname.str().c_str());
    reader->SetFileName(cfname);
    // We have to update since we are working without a VTK pipeline.
    // This will read the file and the output of the reader will be
    // a valid structured grid data.
    reader->Update();
    delete[] cfname;

    // We create a copy to avoid adding the same data three
    // times (the output object of the reader does not change
    // when the filename changes)
    vtkStructuredGrid* sg = vtkStructuredGrid::New();
    sg->ShallowCopy(reader->GetOutput());

    // Add the structured grid to the multi-block dataset
    mb->SetBlock(i, sg);
    sg->Delete();
    }
  reader->Delete();

  // Multi-block can be processed with regular VTK filters in two ways:
  // 1. Pass through a multi-block aware consumer. Since a multi-block
  //    aware mapper is not yet available, vtkCompositeDataGeometryFilter
  //    can be used
  // 2. Assign the composite executive (vtkCompositeDataPipeline) to
  //    all "simple" (that work only on simple, non-composite datasets) filters

  // outline
  vtkStructuredGridOutlineFilter* of = vtkStructuredGridOutlineFilter::New();
  of->SetInput(mb);

  // geometry filter
  // This filter is multi-block aware and will request blocks from the
  // input. These blocks will be processed by simple processes as if they
  // are the whole dataset
  vtkCompositeDataGeometryFilter* geom1 =
    vtkCompositeDataGeometryFilter::New();
  geom1->SetInputConnection(0, of->GetOutputPort(0));

  // Rendering objects
  vtkPolyDataMapper* geoMapper = vtkPolyDataMapper::New();
  geoMapper->SetInputConnection(0, geom1->GetOutputPort(0));

  vtkActor* geoActor = vtkActor::New();
  geoActor->SetMapper(geoMapper);
  geoActor->GetProperty()->SetColor(0, 0, 0);
  ren->AddActor(geoActor);

  // cell 2 point and contour
  vtkCellDataToPointData* c2p = vtkCellDataToPointData::New();
  c2p->SetInput(mb);

  vtkContourFilter* contour = vtkContourFilter::New();
  contour->SetInputConnection(0, c2p->GetOutputPort(0));
  contour->SetValue(0, 0.45);

  // geometry filter
  vtkCompositeDataGeometryFilter* geom2 =
    vtkCompositeDataGeometryFilter::New();
  geom2->SetInputConnection(0, contour->GetOutputPort(0));

  // Rendering objects
  vtkPolyDataMapper* contMapper = vtkPolyDataMapper::New();
  contMapper->SetInputConnection(0, geom2->GetOutputPort(0));

  vtkActor* contActor = vtkActor::New();
  contActor->SetMapper(contMapper);
  contActor->GetProperty()->SetColor(1, 0, 0);
  ren->AddActor(contActor);

  ren->SetBackground(1,1,1);
  renWin->SetSize(300,300);
  iren->Start();

  // Cleanup
  vtkAlgorithm::SetDefaultExecutivePrototype(0);
  of->Delete();
  geom1->Delete();
  geoMapper->Delete();
  geoActor->Delete();
  c2p->Delete();
  contour->Delete();
  geom2->Delete();
  contMapper->Delete();
  contActor->Delete();
  ren->Delete();
  renWin->Delete();
  iren->Delete();
  mb->Delete();

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/accessibility/browser_accessibility_manager_win.h"

#include "base/command_line.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
#include "content/browser/renderer_host/legacy_render_widget_host_win.h"
#include "content/common/accessibility_messages.h"
#include "ui/base/win/atl_module.h"

namespace content {

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    const ui::AXTreeUpdate& initial_tree,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManagerWin(initial_tree, delegate, factory);
}

BrowserAccessibilityManagerWin*
BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() {
  return static_cast<BrowserAccessibilityManagerWin*>(this);
}

BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
    const ui::AXTreeUpdate& initial_tree,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : BrowserAccessibilityManager(delegate, factory),
      tracked_scroll_object_(NULL),
      focus_event_on_root_needed_(false) {
  ui::win::CreateATLModuleIfNeeded();
  Initialize(initial_tree);
}

BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
  if (tracked_scroll_object_) {
    tracked_scroll_object_->Release();
    tracked_scroll_object_ = NULL;
  }
}

// static
ui::AXTreeUpdate BrowserAccessibilityManagerWin::GetEmptyDocument() {
  ui::AXNodeData empty_document;
  empty_document.id = 0;
  empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
  empty_document.state =
      (1 << ui::AX_STATE_ENABLED) |
      (1 << ui::AX_STATE_READ_ONLY) |
      (1 << ui::AX_STATE_BUSY);

  ui::AXTreeUpdate update;
  update.nodes.push_back(empty_document);
  return update;
}

HWND BrowserAccessibilityManagerWin::GetParentHWND() {
  if (!delegate_)
    return NULL;
  return delegate_->AccessibilityGetAcceleratedWidget();
}

IAccessible* BrowserAccessibilityManagerWin::GetParentIAccessible() {
  if (!delegate_)
    return NULL;
  return delegate_->AccessibilityGetNativeViewAccessible();
}

void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
    DWORD event, BrowserAccessibility* node) {
  BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
  if (!delegate)
    return;

  if (!node->IsNative())
    return;

  HWND hwnd = delegate->AccessibilityGetAcceleratedWidget();
  if (!hwnd)
    return;

  // Inline text boxes are an internal implementation detail, we don't
  // expose them to Windows.
  if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
    return;

  // It doesn't make sense to fire a REORDER event on a leaf node; that
  // happens when the node has internal children line inline text boxes.
  if (event == EVENT_OBJECT_REORDER && node->PlatformIsLeaf())
    return;

  // Don't fire focus, or load complete notifications if the
  // window isn't focused, because that can confuse screen readers into
  // entering their "browse" mode.
  if ((event == EVENT_OBJECT_FOCUS ||
       event == IA2_EVENT_DOCUMENT_LOAD_COMPLETE) &&
      (!delegate_->AccessibilityViewHasFocus())) {
    return;
  }

  // NVDA gets confused if we focus the main document element when it hasn't
  // finished loading and it has no children at all, so suppress that event.
  if (event == EVENT_OBJECT_FOCUS &&
      node == GetRoot() &&
      node->PlatformChildCount() == 0 &&
      !node->HasState(ui::AX_STATE_BUSY) &&
      !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) {
    return;
  }

  // If a focus event is needed on the root, fire that first before
  // this event.
  if (event == EVENT_OBJECT_FOCUS && node == GetRoot())
    focus_event_on_root_needed_ = false;
  else if (focus_event_on_root_needed_)
    OnWindowFocused();

  LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win();
  ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id);
}

void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXNode* node) {
  BrowserAccessibilityManager::OnNodeCreated(node);
  BrowserAccessibility* obj = GetFromAXNode(node);
  if (!obj)
    return;
  if (!obj->IsNative())
    return;
  LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win();
  unique_id_to_ax_id_map_[unique_id_win] = obj->GetId();
}

void BrowserAccessibilityManagerWin::OnNodeWillBeDeleted(ui::AXNode* node) {
  BrowserAccessibilityManager::OnNodeWillBeDeleted(node);
  BrowserAccessibility* obj = GetFromAXNode(node);
  if (!obj)
    return;
  if (!obj->IsNative())
    return;
  unique_id_to_ax_id_map_.erase(
      obj->ToBrowserAccessibilityWin()->unique_id_win());
  if (obj == tracked_scroll_object_) {
    tracked_scroll_object_->Release();
    tracked_scroll_object_ = NULL;
  }
}

void BrowserAccessibilityManagerWin::OnWindowFocused() {
  // This is called either when this web frame gets focused, or when
  // the root of the accessibility tree changes. In both cases, we need
  // to fire a focus event on the root and then on the focused element
  // within the page, if different.

  // Set this flag so that we'll keep trying to fire these focus events
  // if they're not successful this time.
  focus_event_on_root_needed_ = true;

  if (!delegate_ || !delegate_->AccessibilityViewHasFocus())
    return;

  // Try to fire a focus event on the root first and then the focused node.
  // This will clear focus_event_on_root_needed_ if successful.
  if (focus_ != tree_->GetRoot())
    NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot());
  BrowserAccessibilityManager::OnWindowFocused();
}

void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
    ui::AXEvent event_type,
    BrowserAccessibility* node) {
  BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
  if (!root_delegate || !root_delegate->AccessibilityGetAcceleratedWidget())
    return;

  // Inline text boxes are an internal implementation detail, we don't
  // expose them to Windows.
  if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
    return;

  // Don't fire focus, blur, or load complete notifications if the
  // window isn't focused, because that can confuse screen readers into
  // entering their "browse" mode.
  if ((event_type == ui::AX_EVENT_FOCUS ||
       event_type == ui::AX_EVENT_BLUR ||
       event_type == ui::AX_EVENT_LOAD_COMPLETE) &&
      !root_delegate->AccessibilityViewHasFocus()) {
    return;
  }

  // NVDA gets confused if we focus the main document element when it hasn't
  // finished loading and it has no children at all, so suppress that event.
  if (event_type == ui::AX_EVENT_FOCUS &&
      node == GetRoot() &&
      node->PlatformChildCount() == 0 &&
      !node->HasState(ui::AX_STATE_BUSY) &&
      !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) {
    return;
  }

  // If a focus event is needed on the root, fire that first before
  // this event.
  if (event_type == ui::AX_EVENT_FOCUS && node == GetRoot())
    focus_event_on_root_needed_ = false;
  else if (focus_event_on_root_needed_)
    OnWindowFocused();

  LONG event_id = EVENT_MIN;
  switch (event_type) {
    case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
      event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
      break;
    case ui::AX_EVENT_ALERT:
      event_id = EVENT_SYSTEM_ALERT;
      break;
    case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
      event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED;
      break;
    case ui::AX_EVENT_BLUR:
      // Equivalent to focus on the root.
      event_id = EVENT_OBJECT_FOCUS;
      node = GetRoot();
      break;
    case ui::AX_EVENT_CHILDREN_CHANGED:
      event_id = EVENT_OBJECT_REORDER;
      break;
    case ui::AX_EVENT_FOCUS:
      event_id = EVENT_OBJECT_FOCUS;
      break;
    case ui::AX_EVENT_LIVE_REGION_CHANGED:
      if (node->GetBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY))
        return;
      event_id = EVENT_OBJECT_LIVEREGIONCHANGED;
      break;
    case ui::AX_EVENT_LOAD_COMPLETE:
      event_id = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
      break;
    case ui::AX_EVENT_MENU_LIST_ITEM_SELECTED:
      event_id = EVENT_OBJECT_FOCUS;
      break;
    case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED:
      event_id = EVENT_OBJECT_VALUECHANGE;
      break;
    case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
      event_id = EVENT_SYSTEM_SCROLLINGEND;
      break;
    case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
      event_id = EVENT_SYSTEM_SCROLLINGSTART;
      break;
    case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
      event_id = EVENT_OBJECT_SELECTIONWITHIN;
      break;
    case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
      event_id = IA2_EVENT_TEXT_CARET_MOVED;
      break;
    default:
      // Not all WebKit accessibility events result in a Windows
      // accessibility notification.
      break;
  }

  if (event_id != EVENT_MIN) {
    // Pass the node's unique id in the |child_id| argument to NotifyWinEvent;
    // the AT client will then call get_accChild on the HWND's accessibility
    // object and pass it that same id, which we can use to retrieve the
    // IAccessible for this node.
    MaybeCallNotifyWinEvent(event_id, node);
  }

  // If this is a layout complete notification (sent when a container scrolls)
  // and there is a descendant tracked object, send a notification on it.
  // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
  if (event_type == ui::AX_EVENT_LAYOUT_COMPLETE &&
      tracked_scroll_object_ &&
      tracked_scroll_object_->IsDescendantOf(node)) {
    MaybeCallNotifyWinEvent(
        IA2_EVENT_VISIBLE_DATA_CHANGED, tracked_scroll_object_);
    tracked_scroll_object_->Release();
    tracked_scroll_object_ = NULL;
  }
}

void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
    bool root_changed,
    const std::vector<ui::AXTreeDelegate::Change>& changes) {
  BrowserAccessibilityManager::OnAtomicUpdateFinished(root_changed, changes);

  if (root_changed) {
    // In order to make screen readers aware of the new accessibility root,
    // we need to fire a focus event on it.
    OnWindowFocused();
  }

  // BrowserAccessibilityManager::OnAtomicUpdateFinished calls
  // OnUpdateFinished() on each node in |changes|. However, the
  // IAccessibleText text for a node is a concatenatenation of all of its child
  // text nodes, so we can't compute a node's IAccessibleText in
  // OnUpdateFinished because its children may not have been updated yet.
  //
  // So we make a second pass here to update IAccessibleText.
  for (size_t i = 0; i < changes.size(); ++i) {
    BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
    if (obj && obj->IsNative())
      obj->ToBrowserAccessibilityWin()->UpdateIAccessibleText();
  }
}

void BrowserAccessibilityManagerWin::TrackScrollingObject(
    BrowserAccessibilityWin* node) {
  if (tracked_scroll_object_)
    tracked_scroll_object_->Release();
  tracked_scroll_object_ = node;
  tracked_scroll_object_->AddRef();
}

BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin(
    LONG unique_id_win) {
  base::hash_map<LONG, int32>::iterator iter =
      unique_id_to_ax_id_map_.find(unique_id_win);
  if (iter != unique_id_to_ax_id_map_.end()) {
    BrowserAccessibility* result = GetFromID(iter->second);
    if (result && result->IsNative())
      return result->ToBrowserAccessibilityWin();
  }

  // Also search all child frames, such as out-of-process iframes or
  // guest browser plugins.
  if (delegate()) {
    std::vector<BrowserAccessibilityManager*> child_frames;
    delegate()->AccessibilityGetAllChildFrames(&child_frames);
    for (size_t i = 0; i < child_frames.size(); ++i) {
      BrowserAccessibilityManagerWin* child_manager =
          child_frames[i]->ToBrowserAccessibilityManagerWin();
      BrowserAccessibilityWin* result =
          child_manager->GetFromUniqueIdWin(unique_id_win);
      if (result)
        return result;
    }
  }

  return NULL;
}

}  // namespace content
<commit_msg>Add more logging to debug DumpAccessibilityEvent* test failures<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/accessibility/browser_accessibility_manager_win.h"

#include "base/command_line.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
#include "content/browser/renderer_host/legacy_render_widget_host_win.h"
#include "content/common/accessibility_messages.h"
#include "ui/base/win/atl_module.h"

namespace content {

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    const ui::AXTreeUpdate& initial_tree,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManagerWin(initial_tree, delegate, factory);
}

BrowserAccessibilityManagerWin*
BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() {
  return static_cast<BrowserAccessibilityManagerWin*>(this);
}

BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
    const ui::AXTreeUpdate& initial_tree,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : BrowserAccessibilityManager(delegate, factory),
      tracked_scroll_object_(NULL),
      focus_event_on_root_needed_(false) {
  ui::win::CreateATLModuleIfNeeded();
  Initialize(initial_tree);
}

BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
  if (tracked_scroll_object_) {
    tracked_scroll_object_->Release();
    tracked_scroll_object_ = NULL;
  }
}

// static
ui::AXTreeUpdate BrowserAccessibilityManagerWin::GetEmptyDocument() {
  ui::AXNodeData empty_document;
  empty_document.id = 0;
  empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
  empty_document.state =
      (1 << ui::AX_STATE_ENABLED) |
      (1 << ui::AX_STATE_READ_ONLY) |
      (1 << ui::AX_STATE_BUSY);

  ui::AXTreeUpdate update;
  update.nodes.push_back(empty_document);
  return update;
}

HWND BrowserAccessibilityManagerWin::GetParentHWND() {
  if (!delegate_)
    return NULL;
  return delegate_->AccessibilityGetAcceleratedWidget();
}

IAccessible* BrowserAccessibilityManagerWin::GetParentIAccessible() {
  if (!delegate_)
    return NULL;
  return delegate_->AccessibilityGetNativeViewAccessible();
}

void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
    DWORD event, BrowserAccessibility* node) {
  BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
  if (!delegate) {
    // This line and other LOG(WARNING) lines are temporary, to debug
    // flaky failures in DumpAccessibilityEvent* tests.
    // http://crbug.com/440579
    LOG(WARNING) << "Not firing AX event because of no delegate";
    return;
  }

  if (!node->IsNative())
    return;

  HWND hwnd = delegate->AccessibilityGetAcceleratedWidget();
  if (!hwnd) {
    LOG(WARNING) << "Not firing AX event because of no hwnd";
    return;
  }

  // Inline text boxes are an internal implementation detail, we don't
  // expose them to Windows.
  if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
    return;

  // It doesn't make sense to fire a REORDER event on a leaf node; that
  // happens when the node has internal children line inline text boxes.
  if (event == EVENT_OBJECT_REORDER && node->PlatformIsLeaf())
    return;

  // Don't fire focus, or load complete notifications if the
  // window isn't focused, because that can confuse screen readers into
  // entering their "browse" mode.
  if ((event == EVENT_OBJECT_FOCUS ||
       event == IA2_EVENT_DOCUMENT_LOAD_COMPLETE) &&
      (!delegate_->AccessibilityViewHasFocus())) {
    return;
  }

  // NVDA gets confused if we focus the main document element when it hasn't
  // finished loading and it has no children at all, so suppress that event.
  if (event == EVENT_OBJECT_FOCUS &&
      node == GetRoot() &&
      node->PlatformChildCount() == 0 &&
      !node->HasState(ui::AX_STATE_BUSY) &&
      !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) {
    return;
  }

  // If a focus event is needed on the root, fire that first before
  // this event.
  if (event == EVENT_OBJECT_FOCUS && node == GetRoot())
    focus_event_on_root_needed_ = false;
  else if (focus_event_on_root_needed_)
    OnWindowFocused();

  LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win();
  ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id);
}

void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXNode* node) {
  BrowserAccessibilityManager::OnNodeCreated(node);
  BrowserAccessibility* obj = GetFromAXNode(node);
  if (!obj)
    return;
  if (!obj->IsNative())
    return;
  LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win();
  unique_id_to_ax_id_map_[unique_id_win] = obj->GetId();
}

void BrowserAccessibilityManagerWin::OnNodeWillBeDeleted(ui::AXNode* node) {
  BrowserAccessibilityManager::OnNodeWillBeDeleted(node);
  BrowserAccessibility* obj = GetFromAXNode(node);
  if (!obj)
    return;
  if (!obj->IsNative())
    return;
  unique_id_to_ax_id_map_.erase(
      obj->ToBrowserAccessibilityWin()->unique_id_win());
  if (obj == tracked_scroll_object_) {
    tracked_scroll_object_->Release();
    tracked_scroll_object_ = NULL;
  }
}

void BrowserAccessibilityManagerWin::OnWindowFocused() {
  // This is called either when this web frame gets focused, or when
  // the root of the accessibility tree changes. In both cases, we need
  // to fire a focus event on the root and then on the focused element
  // within the page, if different.

  // Set this flag so that we'll keep trying to fire these focus events
  // if they're not successful this time.
  focus_event_on_root_needed_ = true;

  if (!delegate_ || !delegate_->AccessibilityViewHasFocus())
    return;

  // Try to fire a focus event on the root first and then the focused node.
  // This will clear focus_event_on_root_needed_ if successful.
  if (focus_ != tree_->GetRoot())
    NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot());
  BrowserAccessibilityManager::OnWindowFocused();
}

void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
    ui::AXEvent event_type,
    BrowserAccessibility* node) {
  BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
  if (!root_delegate || !root_delegate->AccessibilityGetAcceleratedWidget()) {
    LOG(WARNING) << "Not firing AX event because of no root_delegate or hwnd";
    return;
  }

  // Inline text boxes are an internal implementation detail, we don't
  // expose them to Windows.
  if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
    return;

  // Don't fire focus, blur, or load complete notifications if the
  // window isn't focused, because that can confuse screen readers into
  // entering their "browse" mode.
  if ((event_type == ui::AX_EVENT_FOCUS ||
       event_type == ui::AX_EVENT_BLUR ||
       event_type == ui::AX_EVENT_LOAD_COMPLETE) &&
      !root_delegate->AccessibilityViewHasFocus()) {
    return;
  }

  // NVDA gets confused if we focus the main document element when it hasn't
  // finished loading and it has no children at all, so suppress that event.
  if (event_type == ui::AX_EVENT_FOCUS &&
      node == GetRoot() &&
      node->PlatformChildCount() == 0 &&
      !node->HasState(ui::AX_STATE_BUSY) &&
      !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) {
    return;
  }

  // If a focus event is needed on the root, fire that first before
  // this event.
  if (event_type == ui::AX_EVENT_FOCUS && node == GetRoot())
    focus_event_on_root_needed_ = false;
  else if (focus_event_on_root_needed_)
    OnWindowFocused();

  LONG event_id = EVENT_MIN;
  switch (event_type) {
    case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
      event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
      break;
    case ui::AX_EVENT_ALERT:
      event_id = EVENT_SYSTEM_ALERT;
      break;
    case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
      event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED;
      break;
    case ui::AX_EVENT_BLUR:
      // Equivalent to focus on the root.
      event_id = EVENT_OBJECT_FOCUS;
      node = GetRoot();
      break;
    case ui::AX_EVENT_CHILDREN_CHANGED:
      event_id = EVENT_OBJECT_REORDER;
      break;
    case ui::AX_EVENT_FOCUS:
      event_id = EVENT_OBJECT_FOCUS;
      break;
    case ui::AX_EVENT_LIVE_REGION_CHANGED:
      if (node->GetBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY))
        return;
      event_id = EVENT_OBJECT_LIVEREGIONCHANGED;
      break;
    case ui::AX_EVENT_LOAD_COMPLETE:
      event_id = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
      break;
    case ui::AX_EVENT_MENU_LIST_ITEM_SELECTED:
      event_id = EVENT_OBJECT_FOCUS;
      break;
    case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED:
      event_id = EVENT_OBJECT_VALUECHANGE;
      break;
    case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
      event_id = EVENT_SYSTEM_SCROLLINGEND;
      break;
    case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
      event_id = EVENT_SYSTEM_SCROLLINGSTART;
      break;
    case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
      event_id = EVENT_OBJECT_SELECTIONWITHIN;
      break;
    case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
      event_id = IA2_EVENT_TEXT_CARET_MOVED;
      break;
    default:
      // Not all WebKit accessibility events result in a Windows
      // accessibility notification.
      break;
  }

  if (event_id != EVENT_MIN) {
    // Pass the node's unique id in the |child_id| argument to NotifyWinEvent;
    // the AT client will then call get_accChild on the HWND's accessibility
    // object and pass it that same id, which we can use to retrieve the
    // IAccessible for this node.
    MaybeCallNotifyWinEvent(event_id, node);
  }

  // If this is a layout complete notification (sent when a container scrolls)
  // and there is a descendant tracked object, send a notification on it.
  // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
  if (event_type == ui::AX_EVENT_LAYOUT_COMPLETE &&
      tracked_scroll_object_ &&
      tracked_scroll_object_->IsDescendantOf(node)) {
    MaybeCallNotifyWinEvent(
        IA2_EVENT_VISIBLE_DATA_CHANGED, tracked_scroll_object_);
    tracked_scroll_object_->Release();
    tracked_scroll_object_ = NULL;
  }
}

void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
    bool root_changed,
    const std::vector<ui::AXTreeDelegate::Change>& changes) {
  BrowserAccessibilityManager::OnAtomicUpdateFinished(root_changed, changes);

  if (root_changed) {
    // In order to make screen readers aware of the new accessibility root,
    // we need to fire a focus event on it.
    OnWindowFocused();
  }

  // BrowserAccessibilityManager::OnAtomicUpdateFinished calls
  // OnUpdateFinished() on each node in |changes|. However, the
  // IAccessibleText text for a node is a concatenatenation of all of its child
  // text nodes, so we can't compute a node's IAccessibleText in
  // OnUpdateFinished because its children may not have been updated yet.
  //
  // So we make a second pass here to update IAccessibleText.
  for (size_t i = 0; i < changes.size(); ++i) {
    BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
    if (obj && obj->IsNative())
      obj->ToBrowserAccessibilityWin()->UpdateIAccessibleText();
  }
}

void BrowserAccessibilityManagerWin::TrackScrollingObject(
    BrowserAccessibilityWin* node) {
  if (tracked_scroll_object_)
    tracked_scroll_object_->Release();
  tracked_scroll_object_ = node;
  tracked_scroll_object_->AddRef();
}

BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin(
    LONG unique_id_win) {
  base::hash_map<LONG, int32>::iterator iter =
      unique_id_to_ax_id_map_.find(unique_id_win);
  if (iter != unique_id_to_ax_id_map_.end()) {
    BrowserAccessibility* result = GetFromID(iter->second);
    if (result && result->IsNative())
      return result->ToBrowserAccessibilityWin();
  }

  // Also search all child frames, such as out-of-process iframes or
  // guest browser plugins.
  if (delegate()) {
    std::vector<BrowserAccessibilityManager*> child_frames;
    delegate()->AccessibilityGetAllChildFrames(&child_frames);
    for (size_t i = 0; i < child_frames.size(); ++i) {
      BrowserAccessibilityManagerWin* child_manager =
          child_frames[i]->ToBrowserAccessibilityManagerWin();
      BrowserAccessibilityWin* result =
          child_manager->GetFromUniqueIdWin(unique_id_win);
      if (result)
        return result;
    }
  }

  return NULL;
}

}  // namespace content
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkPExtractVOI.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkPExtractVOI.h"

// VTK includes
#include "vtkExtractStructuredGridHelper.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMPIController.h"
#include "vtkMPIUtilities.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStructuredImplicitConnectivity.h"

#include <cassert>
#include <sstream>

// Some useful extent macros
#define EMIN(ext, dim) (ext[2*dim])
#define EMAX(ext, dim) (ext[2*dim+1])

// #define DEBUG

#ifdef DEBUG
#define DEBUG_EXTENT(label, extent) \
  if (this->Controller) \
    { \
    vtkMPIUtilities::SynchronizedPrintf( \
        this->Controller, #label "=[%d,%d,%d,%d,%d,%d]\n", \
        extent[0], extent[1], extent[2], extent[3], extent[4], extent[5]); \
    } \
  else \
    { \
    std::cout << label << "=[" \
              << extent[0] << "," << extent[1] << "," \
              << extent[2] << "," << extent[3] << "," \
              << extent[4] << "," << extent[5] << "]\n"; \
    }

#define DEBUG_OUT(out) \
  if (this->Controller) \
    { \
    std::ostringstream tmpStreamOut; \
    tmpStreamOut << out; \
    vtkMPIUtilities::SynchronizedPrintf(this->Controller, \
                                        tmpStreamOut.str().c_str()); \
    } \
  else \
    { \
    std::cout << out; \
    }
#else // DEBUG
#define DEBUG_EXTENT(label, extent)
#define DEBUG_OUT(out)
#endif // DEBUG

vtkStandardNewMacro(vtkPExtractVOI);

//------------------------------------------------------------------------------
vtkPExtractVOI::vtkPExtractVOI()
{
  this->Controller = vtkMPIController::SafeDownCast(
          vtkMultiProcessController::GetGlobalController());
}

//------------------------------------------------------------------------------
vtkPExtractVOI::~vtkPExtractVOI()
{

}

//------------------------------------------------------------------------------
void vtkPExtractVOI::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

//------------------------------------------------------------------------------
int vtkPExtractVOI::RequestData(
        vtkInformation* request,
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector)
{
  DEBUG_OUT("########### RequestData\n");

  // No MPI? Just run the serial implementation.
  if (!this->Controller)
    {
    return this->Superclass::RequestData(request, inputVector, outputVector);
    }

  // Collect information:
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  int inputWholeExtent[6];
  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               inputWholeExtent);
  int outputWholeExtent[6];
  outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               outputWholeExtent);

  vtkImageData *input = vtkImageData::SafeDownCast(
        inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkImageData *output = vtkImageData::SafeDownCast(
        outInfo->Get(vtkDataObject::DATA_OBJECT()));

  int inputExtent[6];
  input->GetExtent(inputExtent);

  // 1D Example:
  //   InputWholeExtent = [0, 20]
  //   GlobalVOI = [3, 17]
  //   SampleRate = 2
  //   OutputWholeExtent = [0, 7]
  //   Processes = 2
  //
  // Process 0:
  //   PartitionedInputExtent = [0, 10]
  //   PartitionedVOI = [3, 9] (due to sampling)
  //   OutputExtent = [0, 3]
  //   SerialOutputExtent = [0, 3]
  //   FinalOutputExtent = [0, 4] (after gap closing)
  //
  // Process 1:
  //   PartitionedInputExtent = [10, 20]
  //   PartitionedVOI = [11, 17] (offset due to sampling)
  //   OutputExtent = [4, 7]
  //   SerialOutputExtent = [0, 3]
  //   FinalOutputExtent = [4, 7]
  //
  // This filter should:
  // 1) Compute ParititonedVOI that will allow the base class to produce as much
  //    of the output data set as possible from the partitioned piece.
  //
  // 2) Extract PartitionedVOI using the base class's implementation.
  //
  // 3) Update the output dataset's extents to match PartitionedOutputExtent (it
  //    will be [0, L] in each dimension by default).
  //
  // 4) Close gaps using vtkStructuredImplicitConnectivity (e.g. [3, 4] in the
  //    above example).

  bool partitionContainsVOI = true;
  for (int dim = 0; partitionContainsVOI && dim < 3; ++dim)
    {
    partitionContainsVOI = EMAX(inputExtent, dim) >= EMIN(this->VOI, dim) &&
                           EMIN(inputExtent, dim) <= EMAX(this->VOI, dim);
    }

  DEBUG_EXTENT("InputWholeExtent", inputWholeExtent);
  DEBUG_EXTENT("GlobalVOI", this->VOI);
  DEBUG_EXTENT("InputPartitionedExtent", inputExtent);

  int partitionedVOI[6] = {0, -1, 0, -1, 0, -1};
  int partitionedOutputExtent[6] = {0, -1, 0, -1, 0, -1};

  if (partitionContainsVOI)
    {
    ////////////////////////////////////////////////////////////////
    // 1) Compute actual VOI for aligning the partitions outputs: //
    ////////////////////////////////////////////////////////////////
    vtkExtractStructuredGridHelper::GetPartitionedVOI(this->VOI, inputExtent,
                                                      this->SampleRate,
                                                      this->IncludeBoundary,
                                                      partitionedVOI);

    ////////////////////////////////////////////////////////////
    // 2) Extract actual VOI using superclass implementation: //
    ////////////////////////////////////////////////////////////
    if (!this->Superclass::RequestDataImpl(partitionedVOI, inputVector,
                                           outputVector))
      {
      return 0;
      }

    ////////////////////////////////////////////////////////////////
    // 3) Compute and update the output dataset's actual extents. //
    ////////////////////////////////////////////////////////////////

    int partitionedOutputExtent[6];
    vtkExtractStructuredGridHelper::GetPartitionedOutputExtent(
          this->VOI, partitionedVOI, outputWholeExtent, this->SampleRate,
          this->IncludeBoundary, partitionedOutputExtent);

    // For image data, we also need to update the origin, since changing the
    // extent modifies the data location:
    double origin[3];
    output->GetOrigin(origin);
    int serialExtent[6];
    output->GetExtent(serialExtent);
    for (int dim = 0; dim < 3; ++dim)
      {
      origin[dim] +=
          (EMIN(serialExtent, dim) - EMIN(partitionedOutputExtent, dim) *
           this->SampleRate[dim]);
      }
    output->SetOrigin(origin);
    output->SetExtent(partitionedOutputExtent);
    }

  DEBUG_EXTENT("PartitionedVOI", partitionedVOI);
  DEBUG_EXTENT("PartitionedOutputExtent", partitionedOutputExtent);
  DEBUG_EXTENT("OutputWholeExtent", outputWholeExtent);

  //////////////////////////////
  // 4: Detect & resolve gaps //
  //////////////////////////////
  vtkStructuredImplicitConnectivity* gridConnectivity =
      vtkStructuredImplicitConnectivity::New();
  gridConnectivity->SetWholeExtent(outputWholeExtent);

  // Register the grid, grid ID is the same as the process ID
  gridConnectivity->RegisterGrid(
    this->Controller->GetLocalProcessId(),
    output->GetExtent(),
    NULL,
    output->GetPointData()
    );

  // Establish neighbor connectivity & detect any gaps
  gridConnectivity->EstablishConnectivity();

  // Check if there are any gaps, if any close them now
  if( gridConnectivity->HasImplicitConnectivity() )
    {
    DEBUG_OUT("Closing gaps...\n");
    // there are gaps, grow the grid to the right
    gridConnectivity->ExchangeData();

    gridConnectivity->GetOutputImageData(this->Controller->GetLocalProcessId(),
                                         output);
    }

  gridConnectivity->Delete();

#ifdef DEBUG
  int finalOutputExtent[6];
  output->GetExtent(finalOutputExtent);
  DEBUG_EXTENT("FinalOutputExtent", finalOutputExtent);
#endif

  return 1;
}

//------------------------------------------------------------------------------
int vtkPExtractVOI::RequestInformation(
        vtkInformation* request,
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector)
{
  DEBUG_OUT("########### RequestInformation\n");
  return this->Superclass::RequestInformation(request, inputVector,
                                              outputVector);
}

//------------------------------------------------------------------------------
int vtkPExtractVOI::RequestUpdateExtent(
        vtkInformation* request,
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector)
{
  DEBUG_OUT("########### RequestUpdateExtent\n");
  return this->Superclass::RequestUpdateExtent(request, inputVector,
                                               outputVector);
}
<commit_msg>Remove redeclared variable.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPExtractVOI.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkPExtractVOI.h"

// VTK includes
#include "vtkExtractStructuredGridHelper.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMPIController.h"
#include "vtkMPIUtilities.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStructuredImplicitConnectivity.h"

#include <cassert>
#include <sstream>

// Some useful extent macros
#define EMIN(ext, dim) (ext[2*dim])
#define EMAX(ext, dim) (ext[2*dim+1])

// #define DEBUG

#ifdef DEBUG
#define DEBUG_EXTENT(label, extent) \
  if (this->Controller) \
    { \
    vtkMPIUtilities::SynchronizedPrintf( \
        this->Controller, #label "=[%d,%d,%d,%d,%d,%d]\n", \
        extent[0], extent[1], extent[2], extent[3], extent[4], extent[5]); \
    } \
  else \
    { \
    std::cout << label << "=[" \
              << extent[0] << "," << extent[1] << "," \
              << extent[2] << "," << extent[3] << "," \
              << extent[4] << "," << extent[5] << "]\n"; \
    }

#define DEBUG_OUT(out) \
  if (this->Controller) \
    { \
    std::ostringstream tmpStreamOut; \
    tmpStreamOut << out; \
    vtkMPIUtilities::SynchronizedPrintf(this->Controller, \
                                        tmpStreamOut.str().c_str()); \
    } \
  else \
    { \
    std::cout << out; \
    }
#else // DEBUG
#define DEBUG_EXTENT(label, extent)
#define DEBUG_OUT(out)
#endif // DEBUG

vtkStandardNewMacro(vtkPExtractVOI);

//------------------------------------------------------------------------------
vtkPExtractVOI::vtkPExtractVOI()
{
  this->Controller = vtkMPIController::SafeDownCast(
          vtkMultiProcessController::GetGlobalController());
}

//------------------------------------------------------------------------------
vtkPExtractVOI::~vtkPExtractVOI()
{

}

//------------------------------------------------------------------------------
void vtkPExtractVOI::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

//------------------------------------------------------------------------------
int vtkPExtractVOI::RequestData(
        vtkInformation* request,
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector)
{
  DEBUG_OUT("########### RequestData\n");

  // No MPI? Just run the serial implementation.
  if (!this->Controller)
    {
    return this->Superclass::RequestData(request, inputVector, outputVector);
    }

  // Collect information:
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  int inputWholeExtent[6];
  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               inputWholeExtent);
  int outputWholeExtent[6];
  outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
               outputWholeExtent);

  vtkImageData *input = vtkImageData::SafeDownCast(
        inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkImageData *output = vtkImageData::SafeDownCast(
        outInfo->Get(vtkDataObject::DATA_OBJECT()));

  int inputExtent[6];
  input->GetExtent(inputExtent);

  // 1D Example:
  //   InputWholeExtent = [0, 20]
  //   GlobalVOI = [3, 17]
  //   SampleRate = 2
  //   OutputWholeExtent = [0, 7]
  //   Processes = 2
  //
  // Process 0:
  //   PartitionedInputExtent = [0, 10]
  //   PartitionedVOI = [3, 9] (due to sampling)
  //   OutputExtent = [0, 3]
  //   SerialOutputExtent = [0, 3]
  //   FinalOutputExtent = [0, 4] (after gap closing)
  //
  // Process 1:
  //   PartitionedInputExtent = [10, 20]
  //   PartitionedVOI = [11, 17] (offset due to sampling)
  //   OutputExtent = [4, 7]
  //   SerialOutputExtent = [0, 3]
  //   FinalOutputExtent = [4, 7]
  //
  // This filter should:
  // 1) Compute ParititonedVOI that will allow the base class to produce as much
  //    of the output data set as possible from the partitioned piece.
  //
  // 2) Extract PartitionedVOI using the base class's implementation.
  //
  // 3) Update the output dataset's extents to match PartitionedOutputExtent (it
  //    will be [0, L] in each dimension by default).
  //
  // 4) Close gaps using vtkStructuredImplicitConnectivity (e.g. [3, 4] in the
  //    above example).

  bool partitionContainsVOI = true;
  for (int dim = 0; partitionContainsVOI && dim < 3; ++dim)
    {
    partitionContainsVOI = EMAX(inputExtent, dim) >= EMIN(this->VOI, dim) &&
                           EMIN(inputExtent, dim) <= EMAX(this->VOI, dim);
    }

  DEBUG_EXTENT("InputWholeExtent", inputWholeExtent);
  DEBUG_EXTENT("GlobalVOI", this->VOI);
  DEBUG_EXTENT("InputPartitionedExtent", inputExtent);

  int partitionedVOI[6] = {0, -1, 0, -1, 0, -1};
  int partitionedOutputExtent[6] = {0, -1, 0, -1, 0, -1};

  if (partitionContainsVOI)
    {
    ////////////////////////////////////////////////////////////////
    // 1) Compute actual VOI for aligning the partitions outputs: //
    ////////////////////////////////////////////////////////////////
    vtkExtractStructuredGridHelper::GetPartitionedVOI(this->VOI, inputExtent,
                                                      this->SampleRate,
                                                      this->IncludeBoundary,
                                                      partitionedVOI);

    ////////////////////////////////////////////////////////////
    // 2) Extract actual VOI using superclass implementation: //
    ////////////////////////////////////////////////////////////
    if (!this->Superclass::RequestDataImpl(partitionedVOI, inputVector,
                                           outputVector))
      {
      return 0;
      }

    ////////////////////////////////////////////////////////////////
    // 3) Compute and update the output dataset's actual extents. //
    ////////////////////////////////////////////////////////////////

    vtkExtractStructuredGridHelper::GetPartitionedOutputExtent(
          this->VOI, partitionedVOI, outputWholeExtent, this->SampleRate,
          this->IncludeBoundary, partitionedOutputExtent);

    // For image data, we also need to update the origin, since changing the
    // extent modifies the data location:
    double origin[3];
    output->GetOrigin(origin);
    int serialExtent[6];
    output->GetExtent(serialExtent);
    for (int dim = 0; dim < 3; ++dim)
      {
      origin[dim] +=
          (EMIN(serialExtent, dim) - EMIN(partitionedOutputExtent, dim) *
           this->SampleRate[dim]);
      }
    output->SetOrigin(origin);
    output->SetExtent(partitionedOutputExtent);
    }

  DEBUG_EXTENT("PartitionedVOI", partitionedVOI);
  DEBUG_EXTENT("PartitionedOutputExtent", partitionedOutputExtent);
  DEBUG_EXTENT("OutputWholeExtent", outputWholeExtent);

  //////////////////////////////
  // 4: Detect & resolve gaps //
  //////////////////////////////
  vtkStructuredImplicitConnectivity* gridConnectivity =
      vtkStructuredImplicitConnectivity::New();
  gridConnectivity->SetWholeExtent(outputWholeExtent);

  // Register the grid, grid ID is the same as the process ID
  gridConnectivity->RegisterGrid(
    this->Controller->GetLocalProcessId(),
    output->GetExtent(),
    NULL,
    output->GetPointData()
    );

  // Establish neighbor connectivity & detect any gaps
  gridConnectivity->EstablishConnectivity();

  // Check if there are any gaps, if any close them now
  if( gridConnectivity->HasImplicitConnectivity() )
    {
    DEBUG_OUT("Closing gaps...\n");
    // there are gaps, grow the grid to the right
    gridConnectivity->ExchangeData();

    gridConnectivity->GetOutputImageData(this->Controller->GetLocalProcessId(),
                                         output);
    }

  gridConnectivity->Delete();

#ifdef DEBUG
  int finalOutputExtent[6];
  output->GetExtent(finalOutputExtent);
  DEBUG_EXTENT("FinalOutputExtent", finalOutputExtent);
#endif

  return 1;
}

//------------------------------------------------------------------------------
int vtkPExtractVOI::RequestInformation(
        vtkInformation* request,
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector)
{
  DEBUG_OUT("########### RequestInformation\n");
  return this->Superclass::RequestInformation(request, inputVector,
                                              outputVector);
}

//------------------------------------------------------------------------------
int vtkPExtractVOI::RequestUpdateExtent(
        vtkInformation* request,
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector)
{
  DEBUG_OUT("########### RequestUpdateExtent\n");
  return this->Superclass::RequestUpdateExtent(request, inputVector,
                                               outputVector);
}
<|endoftext|>


<commit_before>/*-
 * Copyright (c) 2008 Michael Marner <michael@20papercups.net>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
 */

// include system headers
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>

// include openGL headers
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <wcl/camera/CameraException.h>
#include <wcl/camera/VirtualCamera.h>
#include <wcl/camera/CameraFactory.h>

#define WIDTH 640

using namespace std;
using namespace wcl;

Camera *cam;
unsigned char* data;

void usage()
{
    printf("Usage: camera [-l|-h|devicenode]\n"
	   "\n"
	   "eg: camera /dev/video0\n"
	   "\n"
	   "Options:\n"
	   "\n"
	   "-h = List this help\n"
	   "-l = List available cameras then exit\n"
	   "If no device node is given the first available camera is used. If no physical camera exists, the virtual camera is used\n"
	  );
}

/**
 * Initialise OpenGL
 */
GLvoid init()
{
	glShadeModel(GL_SMOOTH);
	glClearColor(0,0,0,0);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	data = new unsigned char[cam->getFormatBufferSize(Camera::RGB8)];

	// create a texture for the image...
	glTexImage2D(GL_TEXTURE_2D,             //target
				 0,                         //level of detail
				 3,                         //colour components
				 cam->getActiveConfiguration().width,     //width
				 cam->getActiveConfiguration().height,    //height
				 0,                         //border
				 GL_RGB,                    //image format
				 GL_UNSIGNED_BYTE,
				 data);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

	glEnable(GL_TEXTURE_2D);

	glMatrixMode(GL_PROJECTION);
	gluOrtho2D(0,1,0,1);
	glMatrixMode(GL_MODELVIEW);
}

/**
 * Constantly fetch a new image from the camera to display
 */
GLvoid idle()
{
	glutPostRedisplay();
}

/**
 * Display Loop.
 */
GLvoid display()
{
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

	const unsigned char* frame = cam->getFrame(Camera::RGB8);
	glTexSubImage2D(GL_TEXTURE_2D,
	                0,
					0,
					0,
					cam->getActiveConfiguration().width,
					cam->getActiveConfiguration().height,
					GL_RGB,
					GL_UNSIGNED_BYTE,
					frame);

	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();
		glColor3f(1,0,0);
		glBegin(GL_QUADS);

		glTexCoord2f(0,1);
		glVertex2f(0,0);

		glTexCoord2f(1,1);
		glVertex2f(1,0);

		glTexCoord2f(1,0);
		glVertex2f(1,1);

		glTexCoord2f(0,0);
		glVertex2f(0,1);
	glEnd();

	glFlush();
	glutSwapBuffers();

	// print out any opengl errors to the console
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
	{
		cout << gluErrorString(error) << endl;
	}
}

/**
 * This doesn't do what it is supposed to do!
 */
GLvoid reshape(int width, int height)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,1,0,1);
	glMatrixMode(GL_MODELVIEW);
	glViewport(0,0, (GLsizei)width, (GLsizei)height);
}

void keyboard(unsigned char key, int w, int h)
{
    if(key==27)
	exit(EXIT_SUCCESS);
}

void listCameras()
{
    cout << "Searching for Cameras..." << endl;
    std::vector<Camera *> cameras = CameraFactory::getCameras(CameraFactory::ALL);
    CameraFactory::printDetails(false);
}

int main(int argc, char** argv)
{
    if(argc >= 2){
       if( strcmp(argv[1],"--help") == 0 || strcmp(argv[1],"-h" ) == 0){
	usage();
	return 1;
       }
       if( strcmp(argv[1],"-l") == 0){
	   listCameras();
	   return 1;
       }
    }

    try {

	if( argc == 2 ){
	    cout << "Attempting to use Camera specified:" << argv[1] <<endl;
	    cam = CameraFactory::getCamera(argv[1], CameraFactory::ALL);
	} else {
	    cout << "No Camera Specified, using CameraFactory to find the first camera..." << endl;
	    cout << "Searching for Cameras..." << endl;
	    std::vector<Camera *> cameras = CameraFactory::getCameras(CameraFactory::ALL);
	    CameraFactory::printDetails(false);

	    if( cameras.size() == 0 ){
		cout << "No physical camera's found, using virtual camera" << endl;
		cam = new VirtualCamera();
	    } else {
		cam = CameraFactory::getCamera(CameraFactory::ALL);
	    }
	}
	if (cam == NULL ){
	    std::cout << "No usable cameras found" << std::endl;
	    exit(0);
	}

	/*
	 * Print out camera details
	 */
	cam->printDetails();

	cout << "Setting Camera to a width of " << WIDTH << " pixels" << endl;

	Camera::Configuration c;
	c.width = WIDTH;
	cam->setConfiguration(cam->findConfiguration(c));

	//Set power frequency compensation to 50 Hz
	//this is noncritical so don't stop the program if it fails
	try {
	cam->setControlValue(Camera::POWER_FREQUENCY, 1);
	}catch(CameraException &e){}

	// Create GLUT window
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(cam->getActiveConfiguration().width, cam->getActiveConfiguration().height);
	glutCreateWindow(argv[0]);

	init();

	// register callbacks
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	glutIdleFunc(idle);

	// GO!
	glutMainLoop();

	cout << "Deleting Cam" << endl;

	cam->shutdown();
	delete cam;

    }
    catch (Exception &e)
    {
	cout << "Exception Occured: " << e.what() << endl;
    }

    return 0;
}

<commit_msg>examples: Commonize where the search scope is set<commit_after>/*-
 * Copyright (c) 2008 Michael Marner <michael@20papercups.net>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
 */

// include system headers
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>

// include openGL headers
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <wcl/camera/CameraException.h>
#include <wcl/camera/VirtualCamera.h>
#include <wcl/camera/CameraFactory.h>

#define WIDTH 640
#define SEARCHSCOPE CameraFactory::NETWORK

using namespace std;
using namespace wcl;

Camera *cam;
unsigned char* data;

void usage()
{
    printf("Usage: camera [-l|-h|devicenode]\n"
	   "\n"
	   "eg: camera /dev/video0\n"
	   "\n"
	   "Options:\n"
	   "\n"
	   "-h = List this help\n"
	   "-l = List available cameras then exit\n"
	   "If no device node is given the first available camera is used. If no physical camera exists, the virtual camera is used\n"
	  );
}

/**
 * Initialise OpenGL
 */
GLvoid init()
{
	glShadeModel(GL_SMOOTH);
	glClearColor(0,0,0,0);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	data = new unsigned char[cam->getFormatBufferSize(Camera::RGB8)];

	// create a texture for the image...
	glTexImage2D(GL_TEXTURE_2D,             //target
				 0,                         //level of detail
				 3,                         //colour components
				 cam->getActiveConfiguration().width,     //width
				 cam->getActiveConfiguration().height,    //height
				 0,                         //border
				 GL_RGB,                    //image format
				 GL_UNSIGNED_BYTE,
				 data);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

	glEnable(GL_TEXTURE_2D);

	glMatrixMode(GL_PROJECTION);
	gluOrtho2D(0,1,0,1);
	glMatrixMode(GL_MODELVIEW);
}

/**
 * Constantly fetch a new image from the camera to display
 */
GLvoid idle()
{
	glutPostRedisplay();
}

/**
 * Display Loop.
 */
GLvoid display()
{
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

	const unsigned char* frame = cam->getFrame(Camera::RGB8);
	glTexSubImage2D(GL_TEXTURE_2D,
	                0,
					0,
					0,
					cam->getActiveConfiguration().width,
					cam->getActiveConfiguration().height,
					GL_RGB,
					GL_UNSIGNED_BYTE,
					frame);

	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();
		glColor3f(1,0,0);
		glBegin(GL_QUADS);

		glTexCoord2f(0,1);
		glVertex2f(0,0);

		glTexCoord2f(1,1);
		glVertex2f(1,0);

		glTexCoord2f(1,0);
		glVertex2f(1,1);

		glTexCoord2f(0,0);
		glVertex2f(0,1);
	glEnd();

	glFlush();
	glutSwapBuffers();

	// print out any opengl errors to the console
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
	{
		cout << gluErrorString(error) << endl;
	}
}

/**
 * This doesn't do what it is supposed to do!
 */
GLvoid reshape(int width, int height)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,1,0,1);
	glMatrixMode(GL_MODELVIEW);
	glViewport(0,0, (GLsizei)width, (GLsizei)height);
}

void keyboard(unsigned char key, int w, int h)
{
    if(key==27)
	exit(EXIT_SUCCESS);
}

void listCameras()
{
    cout << "Searching for Cameras..." << endl;
    std::vector<Camera *> cameras = CameraFactory::getCameras(SEARCHSCOPE);
    CameraFactory::printDetails(false,SEARCHSCOPE);
}

int main(int argc, char** argv)
{
    if(argc >= 2){
       if( strcmp(argv[1],"--help") == 0 || strcmp(argv[1],"-h" ) == 0){
	usage();
	return 1;
       }
       if( strcmp(argv[1],"-l") == 0){
	   listCameras();
	   return 1;
       }
    }

    try {

	if( argc == 2 ){
	    cout << "Attempting to use Camera specified:" << argv[1] <<endl;
	    cam = CameraFactory::getCamera(argv[1], SEARCHSCOPE);
	} else {
	    cout << "No Camera Specified, using CameraFactory to find the first camera..." << endl;
	    cout << "Searching for Cameras..." << endl;
	    std::vector<Camera *> cameras = CameraFactory::getCameras(SEARCHSCOPE);
	    CameraFactory::printDetails(false, SEARCHSCOPE);

	    if( cameras.size() == 0 ){
		cout << "No physical camera's found, using virtual camera" << endl;
		cam = new VirtualCamera();
	    } else {
		cam = CameraFactory::getCamera(SEARCHSCOPE);
	    }
	}
	if (cam == NULL ){
	    std::cout << "No usable cameras found" << std::endl;
	    exit(0);
	}

	/*
	 * Print out camera details
	 */
	cam->printDetails();

	cout << "Setting Camera to a width of " << WIDTH << " pixels" << endl;

	Camera::Configuration c;
	c.width = WIDTH;
	cam->setConfiguration(cam->findConfiguration(c));

	//Set power frequency compensation to 50 Hz
	//this is noncritical so don't stop the program if it fails
	try {
	cam->setControlValue(Camera::POWER_FREQUENCY, 1);
	}catch(CameraException &e){}

	// Create GLUT window
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(cam->getActiveConfiguration().width, cam->getActiveConfiguration().height);
	glutCreateWindow(argv[0]);

	init();

	// register callbacks
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	glutIdleFunc(idle);

	// GO!
	glutMainLoop();

	cout << "Deleting Cam" << endl;

	cam->shutdown();
	delete cam;

    }
    catch (Exception &e)
    {
	cout << "Exception Occured: " << e.what() << endl;
    }

    return 0;
}

<|endoftext|>


<commit_before>/*
 * opencog/visualizer/src/AtomTypes.cpp
 *
 * Copyright (C) 2012 OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Erwin Joosten <eni247@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "AtomTypes.h"
#include <opencog/util/macros.h>

AtomTypes::AtomTypes()
{
    char buffer[500];
    ssize_t i = readlink("/proc/self/exe", buffer, 500);
    OC_UNUSED(i);
    string path = buffer;
    size_t positionLastSlash = path.find_last_of('/');

    // XXX this is wrong, there are in fact 5 or 6 different atom types script files
    // Each one contains types for each of the different subsystems ...
    atomTypesScriptPath = path.substr(0,positionLastSlash) + "/../../../../opencog/atomspace/atom_types.script";
}

AtomTypes::~AtomTypes()
{
}

void AtomTypes::LoadAtomTypeScript()
{
    ifstream typesfile (atomTypesScriptPath.c_str());
    if (!typesfile.is_open())
    {
        throw runtime_error("File '"+atomTypesScriptPath+"' not found. Copy the atom_types.script file to the application folder or specify location on command line.");
    }

    string line;
    getline (typesfile,line);
    while ( typesfile.good() )
    {
        std::size_t comment = line.find_first_of("/");
        if (comment != string::npos)
            line = line.substr(0, comment);

		Trim(line);

        if (line.length()>0)
        {
        	string specialTypeName="";
            std::size_t quote = line.find("\"");
            if (quote != string::npos)
            {
            	int quote2 = line.find("\"", quote+1);
            	specialTypeName = line.substr(quote+1, quote2-quote-1);
            	line.erase(quote, quote2-quote+1);
            }

    		Trim(line);

    		std::size_t arrow = line.find(" <- ");
            string typeName;
            string parentTypes;
            if (arrow == string::npos)
            {
                typeName = line;
                parentTypes = "";
            }
            else
            {
                typeName = line.substr(0, arrow);
                parentTypes = line.substr(arrow+4);
            }

            string prettyTypeName;
            if(specialTypeName.length()>0)
            	prettyTypeName=specialTypeName;
            else
            	prettyTypeName = MakeMixedCase(typeName);

            atomTypeNames.push_back(prettyTypeName);
            if (typeName.find("NODE")!=string::npos)
                nodeTypeNames.push_back(prettyTypeName);
            if (typeName.find("LINK")!=string::npos)
                linkTypeNames.push_back(prettyTypeName);

            AddSymbol(prettyTypeName);

            AddSubTypes(parentTypes);
        }
        getline (typesfile,line);
    }
    typesfile.close();
}

void AtomTypes::AddSymbol(string typeName)
{
    string symbol = typeName.substr(0, 2);

    if(typeName.compare("AndLink")==0)
        symbol="∧";
    if(typeName.compare("OrLink")==0)
        symbol="∨";
    if(typeName.compare("NotLink")==0)
        symbol="¬";
    if(typeName.compare("SetLink")==0)
        symbol="{}";
    if(typeName.compare("MemberLink")==0)
        symbol="∈";
    if(typeName.compare("SubsetLink")==0)
        symbol="⊂";
    if(typeName.compare("ListLink")==0)
        symbol="()";
    if(typeName.compare("ForallLink")==0)
        symbol="∀";
    if(typeName.compare("ExistsLink")==0)
        symbol="∃";
    if(typeName.compare("TypeNode")==0)
        symbol="T";
    if(typeName.compare("ImplicationLink")==0)
        symbol="⇒";
    if(typeName.compare("EvaluationLink")==0)
        symbol="=";
    if(typeName.compare("InheritanceLink")==0)
        symbol="is";

    atomTypeSymbols.push_back(symbol);
}

void split(const string &s, char delim, vector<string> &elems) {
    stringstream ss(s);
    string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
}

void AtomTypes::AddSubTypes(string parentTypes)
{
    int typeNumber=atomTypeSubTypes.size();
    set<int>* subTypeSet=new set<int>();
    subTypeSet->insert(typeNumber);
    atomTypeSubTypes.push_back(subTypeSet);
    if (parentTypes.length()>0)
    {
        vector<string> parentTypeNames;
        split(parentTypes, ',', parentTypeNames);
        for (std::size_t p = 0; p < parentTypeNames.size(); p++)
        {
            string parentTypeName = MakeMixedCase(parentTypeNames[p]);
            int parentTypeNumber = ConvertTypeNameToNumber(parentTypeName);
            for (std::size_t t = 0; t < atomTypeSubTypes.size(); t++)
                if(atomTypeSubTypes[t]->count(parentTypeNumber)>0)
                    atomTypeSubTypes[t]->insert(typeNumber);
        }
    }
}

int AtomTypes::ConvertTypeNameToNumber(string typeName)
{
    for (std::size_t i = 0; i < atomTypeNames.size(); i++)
    {
        if (atomTypeNames[i].compare(typeName) == 0)
            return (int)i;
    }

    throw runtime_error("Invalid atomtype " + typeName + ". Make sure the atom_types.script file in the application directory is up to date.");
}

string AtomTypes::MakeMixedCase(string typeName)
{
    string s = typeName.substr(0, 1);
    for (std::size_t i = 1; i < typeName.length(); i++)
    {
        if (typeName[i] == '_')
        {
            i++;
            s += typeName[i];
        }
        else
            s += tolower(typeName[i]);
    }
    return s;
}

int AtomTypes::ConvertNodeTypeToAtomType(int nodeType)
{
    string type = nodeTypeNames[nodeType];
    for (std::size_t i = 0; i < atomTypeNames.size(); i++)
        if (atomTypeNames[i].compare(type) == 0)
            return (int)i;
    return -1;
}

int AtomTypes::ConvertLinkTypeToAtomType(int linkType)
{
    string type = linkTypeNames[linkType];
    for (std::size_t i = 0; i < atomTypeNames.size(); i++)
        if (atomTypeNames[i].compare(type) == 0)
            return (int)i;
    return -1;
}

bool AtomTypes::CheckAtomType(Vertex* vertex, int type, bool includeSubtypes)
{
    if (vertex->type < 0 || (std::size_t)vertex->type >= atomTypeNames.size())
    {
        throw runtime_error("Invalid atomtype. Make sure the atom_types.script file in the application directory is up to date.");
    }

    if (includeSubtypes)
        return atomTypeSubTypes[type]->count(vertex->type)>0;
    else
        return vertex->type == type;
}

bool AtomTypes::IsNode(string &typeName)
{
	for(std::size_t i=0;i<nodeTypeNames.size();i++)
		if(nodeTypeNames[i]==typeName)
			return true;

	return false;
}

void AtomTypes::Trim(string& line)
{
	int i;
	for (i = line.length() - 1; i >= 0; i--)
		if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r')
			break;
	line.erase(i + 1);
}

void AtomTypes::Split(const string &s, char delim, vector<string> &elems)
{
    stringstream ss(s);
    string item;
    while(std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
}

<commit_msg>Fix bug, use turnstile<commit_after>/*
 * opencog/visualizer/src/AtomTypes.cpp
 *
 * Copyright (C) 2012 OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Erwin Joosten <eni247@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "AtomTypes.h"
#include <opencog/util/macros.h>

AtomTypes::AtomTypes()
{
    char buffer[500];
    ssize_t i = readlink("/proc/self/exe", buffer, 500);
    OC_UNUSED(i);
    string path = buffer;
    size_t positionLastSlash = path.find_last_of('/');

    // XXX this is wrong, there are in fact 5 or 6 different atom types script files
    // Each one contains types for each of the different subsystems ...
    atomTypesScriptPath = path.substr(0,positionLastSlash) + "/../../../../opencog/atomspace/atom_types.script";
}

AtomTypes::~AtomTypes()
{
}

void AtomTypes::LoadAtomTypeScript()
{
    ifstream typesfile (atomTypesScriptPath.c_str());
    if (!typesfile.is_open())
    {
        throw runtime_error("File '"+atomTypesScriptPath+"' not found. Copy the atom_types.script file to the application folder or specify location on command line.");
    }

    string line;
    getline (typesfile,line);
    while ( typesfile.good() )
    {
        std::size_t comment = line.find_first_of("/");
        if (comment != string::npos)
            line = line.substr(0, comment);

		Trim(line);

        if (line.length()>0)
        {
        	string specialTypeName="";
            std::size_t quote = line.find("\"");
            if (quote != string::npos)
            {
            	int quote2 = line.find("\"", quote+1);
            	specialTypeName = line.substr(quote+1, quote2-quote-1);
            	line.erase(quote, quote2-quote+1);
            }

    		Trim(line);

    		std::size_t arrow = line.find(" <- ");
            string typeName;
            string parentTypes;
            if (arrow == string::npos)
            {
                typeName = line;
                parentTypes = "";
            }
            else
            {
                typeName = line.substr(0, arrow);
                parentTypes = line.substr(arrow+4);
            }

            string prettyTypeName;
            if(specialTypeName.length()>0)
            	prettyTypeName=specialTypeName;
            else
            	prettyTypeName = MakeMixedCase(typeName);

            atomTypeNames.push_back(prettyTypeName);
            if (typeName.find("NODE")!=string::npos)
                nodeTypeNames.push_back(prettyTypeName);
            if (typeName.find("LINK")!=string::npos)
                linkTypeNames.push_back(prettyTypeName);

            AddSymbol(prettyTypeName);

            AddSubTypes(parentTypes);
        }
        getline (typesfile,line);
    }
    typesfile.close();
}

void AtomTypes::AddSymbol(string typeName)
{
    string symbol = typeName.substr(0, 2);

    if(typeName.compare("AndLink")==0)
        symbol="∧";
    if(typeName.compare("OrLink")==0)
        symbol="∨";
    if(typeName.compare("NotLink")==0)
        symbol="¬";
    if(typeName.compare("SetLink")==0)
        symbol="{}";
    if(typeName.compare("MemberLink")==0)
        symbol="∈";
    if(typeName.compare("SubsetLink")==0)
        symbol="⊂";
    if(typeName.compare("ListLink")==0)
        symbol="()";
    if(typeName.compare("ForallLink")==0)
        symbol="∀";
    if(typeName.compare("ExistsLink")==0)
        symbol="∃";
    if(typeName.compare("TypeNode")==0)
        symbol="T";
    if(typeName.compare("ImplicationLink")==0)
        symbol="⇒";
    if(typeName.compare("EquivalenceLink")==0)
        symbol="=";
    if(typeName.compare("EvaluationLink")==0)
        symbol="⊢";
    if(typeName.compare("InheritanceLink")==0)
        symbol="is";

    atomTypeSymbols.push_back(symbol);
}

void split(const string &s, char delim, vector<string> &elems) {
    stringstream ss(s);
    string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
}

void AtomTypes::AddSubTypes(string parentTypes)
{
    int typeNumber=atomTypeSubTypes.size();
    set<int>* subTypeSet=new set<int>();
    subTypeSet->insert(typeNumber);
    atomTypeSubTypes.push_back(subTypeSet);
    if (parentTypes.length()>0)
    {
        vector<string> parentTypeNames;
        split(parentTypes, ',', parentTypeNames);
        for (std::size_t p = 0; p < parentTypeNames.size(); p++)
        {
            string parentTypeName = MakeMixedCase(parentTypeNames[p]);
            int parentTypeNumber = ConvertTypeNameToNumber(parentTypeName);
            for (std::size_t t = 0; t < atomTypeSubTypes.size(); t++)
                if(atomTypeSubTypes[t]->count(parentTypeNumber)>0)
                    atomTypeSubTypes[t]->insert(typeNumber);
        }
    }
}

int AtomTypes::ConvertTypeNameToNumber(string typeName)
{
    for (std::size_t i = 0; i < atomTypeNames.size(); i++)
    {
        if (atomTypeNames[i].compare(typeName) == 0)
            return (int)i;
    }

    throw runtime_error("Invalid atomtype " + typeName + ". Make sure the atom_types.script file in the application directory is up to date.");
}

string AtomTypes::MakeMixedCase(string typeName)
{
    string s = typeName.substr(0, 1);
    for (std::size_t i = 1; i < typeName.length(); i++)
    {
        if (typeName[i] == '_')
        {
            i++;
            s += typeName[i];
        }
        else
            s += tolower(typeName[i]);
    }
    return s;
}

int AtomTypes::ConvertNodeTypeToAtomType(int nodeType)
{
    string type = nodeTypeNames[nodeType];
    for (std::size_t i = 0; i < atomTypeNames.size(); i++)
        if (atomTypeNames[i].compare(type) == 0)
            return (int)i;
    return -1;
}

int AtomTypes::ConvertLinkTypeToAtomType(int linkType)
{
    string type = linkTypeNames[linkType];
    for (std::size_t i = 0; i < atomTypeNames.size(); i++)
        if (atomTypeNames[i].compare(type) == 0)
            return (int)i;
    return -1;
}

bool AtomTypes::CheckAtomType(Vertex* vertex, int type, bool includeSubtypes)
{
    if (vertex->type < 0 || (std::size_t)vertex->type >= atomTypeNames.size())
    {
        throw runtime_error("Invalid atomtype. Make sure the atom_types.script file in the application directory is up to date.");
    }

    if (includeSubtypes)
        return atomTypeSubTypes[type]->count(vertex->type)>0;
    else
        return vertex->type == type;
}

bool AtomTypes::IsNode(string &typeName)
{
	for(std::size_t i=0;i<nodeTypeNames.size();i++)
		if(nodeTypeNames[i]==typeName)
			return true;

	return false;
}

void AtomTypes::Trim(string& line)
{
	int i;
	for (i = line.length() - 1; i >= 0; i--)
		if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r')
			break;
	line.erase(i + 1);
}

void AtomTypes::Split(const string &s, char delim, vector<string> &elems)
{
    stringstream ss(s);
    string item;
    while(std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
}

<|endoftext|>