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

#ifndef METHCLA_UTILITY_MESSAGEQUEUE_HPP_INCLUDED
#define METHCLA_UTILITY_MESSAGEQUEUE_HPP_INCLUDED

#include <array>
#include <atomic>
#include <mutex>
#include <thread>
#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <boost/lockfree/spsc_queue.hpp>
#pragma GCC diagnostic pop
#include <boost/noncopyable.hpp>

#include "Methcla/Utility/Semaphore.hpp"

namespace Methcla { namespace Utility {

//* MWSR queue for sending commands to the engine.
// Request payload lifetime: from request until response callback.
// Caller is responsible for freeing request payload after the response callback has been called.
template <typename T, size_t queueSize> class MessageQueue : boost::noncopyable
{
public:
    inline void send(const T& msg)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        bool success = m_queue.push(msg);
        if (!success) throw std::runtime_error("Message queue overflow");
    }

    inline bool next(T& msg)
    {
        return m_queue.pop(msg);
    }

private:
    typedef boost::lockfree::spsc_queue<T,boost::lockfree::capacity<queueSize>> Queue;
    Queue      m_queue;
    std::mutex m_mutex;
};

template <class Command> class Transport : boost::noncopyable
{
public:
    Transport(size_t queueSize, bool needsLock)
        : m_queue(queueSize)
        , m_needsLock(needsLock)
    { }
    virtual ~Transport()
    { }

    virtual void send(const Command& cmd) = 0;

    virtual bool dequeue(Command& cmd) = 0;

    void performOne()
    {
        Command cmd;
        if (dequeue(cmd)) {
            cmd.perform();
        }
    }

    void performAll()
    {
        Command cmd;
        while (dequeue(cmd)) {
            cmd.perform();
        }
    }

protected:
    typedef boost::lockfree::spsc_queue<Command> Queue;

    Queue& queue()
    {
        return m_queue;
    }

    bool needsLock() const
    {
        return m_needsLock;
    }

    std::mutex& mutex()
    {
        return m_mutex;
    }

    void sendCommand(const Command& cmd)
    {
        bool success = m_queue.push(cmd);
        if (!success) throw std::runtime_error("Channel overflow");
    }

private:
    // typedef boost::lockfree::queue<Command,boost::lockfree::capacity<queueSize>> Queue;
    Queue       m_queue;
    bool        m_needsLock;
    std::mutex  m_mutex;
};

template <class Command> class ToWorker : public Transport<Command>
{
public:
    ToWorker(size_t queueSize, bool needsLock, std::function<void()> signal)
        : Transport<Command>(queueSize, needsLock)
        , m_signal(signal)
    { }

    virtual void send(const Command& cmd) override
    {
        this->sendCommand(cmd);
        if (m_signal) m_signal();
    }

    bool dequeue(Command& cmd)
    {
        if (this->needsLock()) {
            std::lock_guard<std::mutex> lock(this->mutex());
            return this->queue().pop(cmd);
        } else {
            return this->queue().pop(cmd);
        }
    }

private:
    std::function<void()> m_signal;
};

template <class Command> class FromWorker : public Transport<Command>
{
public:
    FromWorker(size_t queueSize, bool needsLock)
        : Transport<Command>(queueSize, needsLock)
    { }

    virtual void send(const Command& cmd) override
    {
        if (this->needsLock()) {
            std::lock_guard<std::mutex> lock(this->mutex());
            this->sendCommand(cmd);
        } else {
            this->sendCommand(cmd);
        }
    }

    bool dequeue(Command& cmd) override
    {
        return this->queue().pop(cmd);
    }
};

template <typename Command> class Worker : boost::noncopyable
{
public:
    Worker(size_t queueSize, bool needsLock)
        : m_queueSize(queueSize)
        , m_toWorker(queueSize, needsLock, [this](){ this->signalWorker(); })
        , m_fromWorker(queueSize, needsLock)
    { }

    size_t maxCapacity() const
    {
        return m_queueSize - 1;
    }

    void sendToWorker(const Command& cmd)
    {
        m_toWorker.send(cmd);
    }

    void sendFromWorker(const Command& cmd)
    {
        m_fromWorker.send(cmd);
    }

    void perform()
    {
        m_fromWorker.performAll();
    }

protected:
    void work()
    {
        m_toWorker.performOne();
    }

    virtual void signalWorker() { }

private:
    size_t              m_queueSize;
    ToWorker<Command>   m_toWorker;
    FromWorker<Command> m_fromWorker;
};

template <typename Command> class WorkerThread : public Worker<Command>
{
public:
    WorkerThread(size_t queueSize, size_t numThreads=1)
        : Worker<Command>(queueSize, numThreads > 1)
        , m_continue(true)
    {
        for (size_t i=0; i < std::max((size_t)1, numThreads); i++) {
            m_threads.emplace_back([this](){ this->process(); });
        }
    }

    ~WorkerThread()
    {
        m_continue.store(false, std::memory_order_relaxed);
        m_sem.post();
        for (auto& t : m_threads) { t.join(); }
    }

private:
    void process()
    {
        for (;;) {
            m_sem.wait();
            bool cont = m_continue.load(std::memory_order_relaxed);
            if (cont) {
                this->work();
            } else {
                break;
            }
        }
    }

    virtual void signalWorker() override
    {
        m_sem.post();
    }

private:
    Semaphore                   m_sem;
    std::atomic<bool>           m_continue;
    std::vector<std::thread>    m_threads;
};

} }

#endif // METHCLA_UTILITY_MESSAGEQUEUE_HPP_INCLUDED
<commit_msg>Signal all threads in WorkerThread destructor<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef METHCLA_UTILITY_MESSAGEQUEUE_HPP_INCLUDED
#define METHCLA_UTILITY_MESSAGEQUEUE_HPP_INCLUDED

#include <array>
#include <atomic>
#include <mutex>
#include <thread>
#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <boost/lockfree/spsc_queue.hpp>
#pragma GCC diagnostic pop
#include <boost/noncopyable.hpp>

#include "Methcla/Utility/Semaphore.hpp"

namespace Methcla { namespace Utility {

//* MWSR queue for sending commands to the engine.
// Request payload lifetime: from request until response callback.
// Caller is responsible for freeing request payload after the response callback has been called.
template <typename T, size_t queueSize> class MessageQueue : boost::noncopyable
{
public:
    inline void send(const T& msg)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        bool success = m_queue.push(msg);
        if (!success) throw std::runtime_error("Message queue overflow");
    }

    inline bool next(T& msg)
    {
        return m_queue.pop(msg);
    }

private:
    typedef boost::lockfree::spsc_queue<T,boost::lockfree::capacity<queueSize>> Queue;
    Queue      m_queue;
    std::mutex m_mutex;
};

template <class Command> class Transport : boost::noncopyable
{
public:
    Transport(size_t queueSize, bool needsLock)
        : m_queue(queueSize)
        , m_needsLock(needsLock)
    { }
    virtual ~Transport()
    { }

    virtual void send(const Command& cmd) = 0;

    virtual bool dequeue(Command& cmd) = 0;

    void performOne()
    {
        Command cmd;
        if (dequeue(cmd)) {
            cmd.perform();
        }
    }

    void performAll()
    {
        Command cmd;
        while (dequeue(cmd)) {
            cmd.perform();
        }
    }

protected:
    typedef boost::lockfree::spsc_queue<Command> Queue;

    Queue& queue()
    {
        return m_queue;
    }

    bool needsLock() const
    {
        return m_needsLock;
    }

    std::mutex& mutex()
    {
        return m_mutex;
    }

    void sendCommand(const Command& cmd)
    {
        bool success = m_queue.push(cmd);
        if (!success) throw std::runtime_error("Channel overflow");
    }

private:
    // typedef boost::lockfree::queue<Command,boost::lockfree::capacity<queueSize>> Queue;
    Queue       m_queue;
    bool        m_needsLock;
    std::mutex  m_mutex;
};

template <class Command> class ToWorker : public Transport<Command>
{
public:
    ToWorker(size_t queueSize, bool needsLock, std::function<void()> signal)
        : Transport<Command>(queueSize, needsLock)
        , m_signal(signal)
    { }

    virtual void send(const Command& cmd) override
    {
        this->sendCommand(cmd);
        if (m_signal) m_signal();
    }

    bool dequeue(Command& cmd)
    {
        if (this->needsLock()) {
            std::lock_guard<std::mutex> lock(this->mutex());
            return this->queue().pop(cmd);
        } else {
            return this->queue().pop(cmd);
        }
    }

private:
    std::function<void()> m_signal;
};

template <class Command> class FromWorker : public Transport<Command>
{
public:
    FromWorker(size_t queueSize, bool needsLock)
        : Transport<Command>(queueSize, needsLock)
    { }

    virtual void send(const Command& cmd) override
    {
        if (this->needsLock()) {
            std::lock_guard<std::mutex> lock(this->mutex());
            this->sendCommand(cmd);
        } else {
            this->sendCommand(cmd);
        }
    }

    bool dequeue(Command& cmd) override
    {
        return this->queue().pop(cmd);
    }
};

template <typename Command> class Worker : boost::noncopyable
{
public:
    Worker(size_t queueSize, bool needsLock)
        : m_queueSize(queueSize)
        , m_toWorker(queueSize, needsLock, [this](){ this->signalWorker(); })
        , m_fromWorker(queueSize, needsLock)
    { }

    size_t maxCapacity() const
    {
        return m_queueSize - 1;
    }

    void sendToWorker(const Command& cmd)
    {
        m_toWorker.send(cmd);
    }

    void sendFromWorker(const Command& cmd)
    {
        m_fromWorker.send(cmd);
    }

    void perform()
    {
        m_fromWorker.performAll();
    }

protected:
    void work()
    {
        m_toWorker.performOne();
    }

    virtual void signalWorker() { }

private:
    size_t              m_queueSize;
    ToWorker<Command>   m_toWorker;
    FromWorker<Command> m_fromWorker;
};

template <typename Command> class WorkerThread : public Worker<Command>
{
public:
    WorkerThread(size_t queueSize, size_t numThreads=1)
        : Worker<Command>(queueSize, numThreads > 1)
        , m_continue(true)
    {
        for (size_t i=0; i < std::max((size_t)1, numThreads); i++) {
            m_threads.emplace_back([this](){ this->process(); });
        }
    }

    ~WorkerThread()
    {
        m_continue.store(false, std::memory_order_relaxed);
        // Signal *all* threads
        for (size_t i=0; i < m_threads.size(); i++) {
            m_sem.post();
        }
        // Wait for threads to exit
        for (auto& t : m_threads) { t.join(); }
    }

private:
    void process()
    {
        for (;;) {
            m_sem.wait();
            bool cont = m_continue.load(std::memory_order_relaxed);
            if (cont) {
                this->work();
            } else {
                break;
            }
        }
    }

    virtual void signalWorker() override
    {
        m_sem.post();
    }

private:
    Semaphore                   m_sem;
    std::atomic<bool>           m_continue;
    std::vector<std::thread>    m_threads;
};

} }

#endif // METHCLA_UTILITY_MESSAGEQUEUE_HPP_INCLUDED
<|endoftext|>


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

Copyright (c) Kitware Inc.
All rights reserved.

=========================================================================*/
// .SECTION Description
// This program illustrates the use of various filters acting upon hyper
// tree grid data sets. It generates output files in VTK format.
//
// .SECTION Usage
//   --branch-factor opt  Branching factor of hyper tree grid
//   --dimension opt      Dimension of hyper tree grid
//   --grid-size-X opt    Size of hyper tree grid in X direction
//   --grid-size-Y opt    Size of hyper tree grid in Y direction
//   --grid-size-Z opt    Size of hyper tree grid in Z direction
//   --max-level opt      Maximum depth of hyper tree grid
//   --skip-Axis-Cut      Skip axis cut filter
//   --skip-Contour       Skip contour filter
//   --skip-Cut           Skip cut filter
//   --skip-Geometry      Skip geometry filter
//   --skip-Shrink        Skip shrink filter
//
// .SECTION Thanks
// This example was written by Charles Law and Philippe Pebay, Kitware 2012

#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridAxisCut.h"
#include "vtkHyperTreeGridSource.h"
#include "vtkHyperTreeGridGeometry.h"

#include "vtkCellData.h"
#include "vtkContourFilter.h"
#include "vtkCutter.h"
#include "vtkDataSetWriter.h"
#include "vtkNew.h"
#include "vtkPlane.h"
#include "vtkPolyDataWriter.h"
#include "vtkRenderer.h"
#include "vtkShrinkFilter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridWriter.h"
#include "vtkXMLUnstructuredGridWriter.h"

#include "vtksys/CommandLineArguments.hxx"

int TestHyperTreeGrid( int argc, char* argv[] )
{
  // Default parameters and options
  int dim = 3;
  int branch = 3;
  int max = 3;
  int nX = 3;
  int nY = 4;
  int nZ = 2;
  bool skipAxisCut = false;
  bool skipContour = false;
  bool skipCut = false;
  bool skipGeometry = false;
  bool skipShrink = false;

  // Initialize command line argument parser
  vtksys::CommandLineArguments clArgs;
  clArgs.Initialize( argc, argv );
  clArgs.StoreUnusedArguments( false );

  // Parse command line parameters and options
  clArgs.AddArgument( "--dimension",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &dim, "Dimension of hyper tree grid" );

  clArgs.AddArgument( "--branch-factor",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &branch, "Branching factor of hyper tree grid" );

  clArgs.AddArgument( "--max-level",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &max, "Maximum depth of hyper tree grid" );

  clArgs.AddArgument( "--grid-size-X",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nX, "Size of hyper tree grid in X direction" );

  clArgs.AddArgument( "--grid-size-Y",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nY, "Size of hyper tree grid in Y direction" );

  clArgs.AddArgument( "--grid-size-Z",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nZ, "Size of hyper tree grid in Z direction" );

  clArgs.AddArgument( "--skip-Axis-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip axis cut filter" );

  clArgs.AddArgument( "--skip-Contour",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip contour filter" );

  clArgs.AddArgument( "--skip-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipCut, "Skip cut filter" );

  clArgs.AddArgument( "--skip-Geometry",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipGeometry, "Skip geometry filter" );

  clArgs.AddArgument( "--skip-Shrink",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipShrink, "Skip shrink filter" );

  // If incorrect arguments were provided, provide some help and terminate in error.
  if ( ! clArgs.Parse() )
    {
    cerr << "Usage: "
         << clArgs.GetHelp()
         << "\n";
    }

  // Ensure that parsed dimensionality makes sense
  if ( dim > 3 )
    {
    dim = 3;
    }
  else if ( dim < 1 )
    {
    dim = 1;
    }

  // Ensure that parsed branch factor makes sense
  if ( branch > 3 )
    {
    branch = 3;
    }
  else if ( branch < 2 )
    {
    branch = 2;
    }

  // Ensure that parsed maximum level makes sense
  if ( max < 1 )
    {
    max = 1;
    }

  // Ensure that parsed grid sizes make sense
  if ( nX < 1 )
    {
    nX = 1;
    }
  if ( nY < 1 )
    {
    nY = 1;
    }
  if ( nZ < 1 )
    {
    nZ = 1;
    }

  // Ensure that parsed grid sizes are consistent with dimensionality
  if ( dim < 3 )
    {
    nZ = 1;
    if ( dim < 2 )
      {
      nY = 1;
      }
    }

  // Initialize return value of test
  int testIntValue = 0;

  // Create hyper tree grid source
  vtkNew<vtkHyperTreeGridSource> fractal;
  fractal->SetMaximumLevel( max );
  fractal->DualOn();
  if ( dim == 3 )
    {
    fractal->SetGridSize( nX, nY, nZ );
    }
  fractal->SetGridSize( nX, nY, nZ );
  fractal->SetDimension( dim );
  fractal->SetAxisBranchFactor( branch );
  fractal->Update();
  vtkHyperTreeGrid* htGrid = fractal->GetOutput();

  if ( ! skipGeometry )
    {
    cerr << "# Geometry" << endl;
    vtkNew<vtkHyperTreeGridGeometry> geometry;
    geometry->SetInputConnection( fractal->GetOutputPort() );
    vtkNew<vtkPolyDataWriter> writer4;
    writer4->SetFileName( "./hyperTreeGridGeometry.vtk" );
    writer4->SetInputConnection( geometry->GetOutputPort() );
    writer4->Write();
    }

  if ( ! skipContour )
    {
    cerr << "# Contour" << endl;
    vtkNew<vtkContourFilter> contour;
    contour->SetInputData( htGrid );
    contour->SetNumberOfContours( 2 );
    contour->SetValue( 0, 4. );
    contour->SetValue( 1, 18. );
    contour->SetInputArrayToProcess( 0, 0, 0,
                                     vtkDataObject::FIELD_ASSOCIATION_POINTS,
                                     "Cell Value" );
    vtkNew<vtkPolyDataWriter> writer0;
    writer0->SetFileName( "./hyperTreeGridContour.vtk" );
    writer0->SetInputConnection( contour->GetOutputPort() );
    writer0->Write();
    }

  if ( ! skipShrink )
    {
    cerr << "# Shrink" << endl;
    vtkNew<vtkShrinkFilter> shrink;
    shrink->SetInputData( htGrid );
    shrink->SetShrinkFactor( 1. );
    vtkNew<vtkUnstructuredGridWriter> writer1;
    writer1->SetFileName( "./hyperTreeGridShrink.vtk" );
    writer1->SetInputConnection( shrink->GetOutputPort() );
    writer1->Write();
    }

  if ( ! skipAxisCut )
    {
    // Axis-aligned cut works only in 3D for now
    if ( dim == 3 )
      {
      cerr << "# HyperTreeGridAxisCut" << endl;
      vtkNew<vtkHyperTreeGridAxisCut> axisCut;
      axisCut->SetInputConnection( fractal->GetOutputPort() );
      axisCut->SetPlaneNormalAxis( 2 );
      axisCut->SetPlanePosition( .1 );
      vtkNew<vtkPolyDataWriter> writer2;
      writer2->SetFileName( "./hyperTreeGridAxisCut.vtk" );
      writer2->SetInputConnection( axisCut->GetOutputPort() );
      writer2->Write();
      }
    }

  if ( ! skipCut )
    {
    cerr << "# Cut" << endl;
    vtkNew<vtkCutter> cut;
    vtkNew<vtkPlane> plane;
    plane->SetOrigin( .5, .5, .15 );
    plane->SetNormal( 0, 0, 1 );
    cut->SetInputData( htGrid );
    cut->SetCutFunction( plane.GetPointer() );
    vtkNew<vtkPolyDataWriter> writer3;
    writer3->SetFileName( "./hyperTreeGridCut.vtk" );
    writer3->SetInputConnection( cut->GetOutputPort() );
    writer3->Write();
    }

  return testIntValue;
}
<commit_msg>Header clean up<commit_after>/*=========================================================================

Copyright (c) Kitware Inc.
All rights reserved.

=========================================================================*/
// .SECTION Description
// This program illustrates the use of various filters acting upon hyper
// tree grid data sets. It generates output files in VTK format.
//
// .SECTION Usage
//   --branch-factor opt  Branching factor of hyper tree grid
//   --dimension opt      Dimension of hyper tree grid
//   --grid-size-X opt    Size of hyper tree grid in X direction
//   --grid-size-Y opt    Size of hyper tree grid in Y direction
//   --grid-size-Z opt    Size of hyper tree grid in Z direction
//   --max-level opt      Maximum depth of hyper tree grid
//   --skip-Axis-Cut      Skip axis cut filter
//   --skip-Contour       Skip contour filter
//   --skip-Cut           Skip cut filter
//   --skip-Geometry      Skip geometry filter
//   --skip-Shrink        Skip shrink filter
//
// .SECTION Thanks
// This example was written by Charles Law and Philippe Pebay, Kitware 2012

#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridAxisCut.h"
#include "vtkHyperTreeGridSource.h"
#include "vtkHyperTreeGridGeometry.h"

#include "vtkCellData.h"
#include "vtkContourFilter.h"
#include "vtkCutter.h"
#include "vtkDataSetWriter.h"
#include "vtkNew.h"
#include "vtkPlane.h"
#include "vtkPolyDataWriter.h"
#include "vtkRenderer.h"
#include "vtkShrinkFilter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridWriter.h"

#include "vtksys/CommandLineArguments.hxx"

int TestHyperTreeGrid( int argc, char* argv[] )
{
  // Default parameters and options
  int dim = 3;
  int branch = 3;
  int max = 3;
  int nX = 3;
  int nY = 4;
  int nZ = 2;
  bool skipAxisCut = false;
  bool skipContour = false;
  bool skipCut = false;
  bool skipGeometry = false;
  bool skipShrink = false;

  // Initialize command line argument parser
  vtksys::CommandLineArguments clArgs;
  clArgs.Initialize( argc, argv );
  clArgs.StoreUnusedArguments( false );

  // Parse command line parameters and options
  clArgs.AddArgument( "--dimension",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &dim, "Dimension of hyper tree grid" );

  clArgs.AddArgument( "--branch-factor",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &branch, "Branching factor of hyper tree grid" );

  clArgs.AddArgument( "--max-level",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &max, "Maximum depth of hyper tree grid" );

  clArgs.AddArgument( "--grid-size-X",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nX, "Size of hyper tree grid in X direction" );

  clArgs.AddArgument( "--grid-size-Y",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nY, "Size of hyper tree grid in Y direction" );

  clArgs.AddArgument( "--grid-size-Z",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nZ, "Size of hyper tree grid in Z direction" );

  clArgs.AddArgument( "--skip-Axis-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip axis cut filter" );

  clArgs.AddArgument( "--skip-Contour",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip contour filter" );

  clArgs.AddArgument( "--skip-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipCut, "Skip cut filter" );

  clArgs.AddArgument( "--skip-Geometry",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipGeometry, "Skip geometry filter" );

  clArgs.AddArgument( "--skip-Shrink",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipShrink, "Skip shrink filter" );

  // If incorrect arguments were provided, provide some help and terminate in error.
  if ( ! clArgs.Parse() )
    {
    cerr << "Usage: "
         << clArgs.GetHelp()
         << "\n";
    }

  // Ensure that parsed dimensionality makes sense
  if ( dim > 3 )
    {
    dim = 3;
    }
  else if ( dim < 1 )
    {
    dim = 1;
    }

  // Ensure that parsed branch factor makes sense
  if ( branch > 3 )
    {
    branch = 3;
    }
  else if ( branch < 2 )
    {
    branch = 2;
    }

  // Ensure that parsed maximum level makes sense
  if ( max < 1 )
    {
    max = 1;
    }

  // Ensure that parsed grid sizes make sense
  if ( nX < 1 )
    {
    nX = 1;
    }
  if ( nY < 1 )
    {
    nY = 1;
    }
  if ( nZ < 1 )
    {
    nZ = 1;
    }

  // Ensure that parsed grid sizes are consistent with dimensionality
  if ( dim < 3 )
    {
    nZ = 1;
    if ( dim < 2 )
      {
      nY = 1;
      }
    }

  // Initialize return value of test
  int testIntValue = 0;

  // Create hyper tree grid source
  vtkNew<vtkHyperTreeGridSource> fractal;
  fractal->SetMaximumLevel( max );
  fractal->DualOn();
  if ( dim == 3 )
    {
    fractal->SetGridSize( nX, nY, nZ );
    }
  fractal->SetGridSize( nX, nY, nZ );
  fractal->SetDimension( dim );
  fractal->SetAxisBranchFactor( branch );
  fractal->Update();
  vtkHyperTreeGrid* htGrid = fractal->GetOutput();

  if ( ! skipGeometry )
    {
    cerr << "# Geometry" << endl;
    vtkNew<vtkHyperTreeGridGeometry> geometry;
    geometry->SetInputConnection( fractal->GetOutputPort() );
    vtkNew<vtkPolyDataWriter> writer4;
    writer4->SetFileName( "./hyperTreeGridGeometry.vtk" );
    writer4->SetInputConnection( geometry->GetOutputPort() );
    writer4->Write();
    }

  if ( ! skipContour )
    {
    cerr << "# Contour" << endl;
    vtkNew<vtkContourFilter> contour;
    contour->SetInputData( htGrid );
    contour->SetNumberOfContours( 2 );
    contour->SetValue( 0, 4. );
    contour->SetValue( 1, 18. );
    contour->SetInputArrayToProcess( 0, 0, 0,
                                     vtkDataObject::FIELD_ASSOCIATION_POINTS,
                                     "Cell Value" );
    vtkNew<vtkPolyDataWriter> writer0;
    writer0->SetFileName( "./hyperTreeGridContour.vtk" );
    writer0->SetInputConnection( contour->GetOutputPort() );
    writer0->Write();
    }

  if ( ! skipShrink )
    {
    cerr << "# Shrink" << endl;
    vtkNew<vtkShrinkFilter> shrink;
    shrink->SetInputData( htGrid );
    shrink->SetShrinkFactor( 1. );
    vtkNew<vtkUnstructuredGridWriter> writer1;
    writer1->SetFileName( "./hyperTreeGridShrink.vtk" );
    writer1->SetInputConnection( shrink->GetOutputPort() );
    writer1->Write();
    }

  if ( ! skipAxisCut )
    {
    // Axis-aligned cut works only in 3D for now
    if ( dim == 3 )
      {
      cerr << "# HyperTreeGridAxisCut" << endl;
      vtkNew<vtkHyperTreeGridAxisCut> axisCut;
      axisCut->SetInputConnection( fractal->GetOutputPort() );
      axisCut->SetPlaneNormalAxis( 2 );
      axisCut->SetPlanePosition( .1 );
      vtkNew<vtkPolyDataWriter> writer2;
      writer2->SetFileName( "./hyperTreeGridAxisCut.vtk" );
      writer2->SetInputConnection( axisCut->GetOutputPort() );
      writer2->Write();
      }
    }

  if ( ! skipCut )
    {
    cerr << "# Cut" << endl;
    vtkNew<vtkCutter> cut;
    vtkNew<vtkPlane> plane;
    plane->SetOrigin( .5, .5, .15 );
    plane->SetNormal( 0, 0, 1 );
    cut->SetInputData( htGrid );
    cut->SetCutFunction( plane.GetPointer() );
    vtkNew<vtkPolyDataWriter> writer3;
    writer3->SetFileName( "./hyperTreeGridCut.vtk" );
    writer3->SetInputConnection( cut->GetOutputPort() );
    writer3->Write();
    }

  return testIntValue;
}
<|endoftext|>


<commit_before>#include "GMSRoomManagementSystem.hpp"

#include "../Events/GMSRoomLoadRequestEvent.hpp"
#include "../AssetResources/TextureInfoResource.hpp"

#include <KEngine/Entity/Components/EntityRenderableComponents.hpp>
#include <KEngine/Events/OtherGraphicsEvents.hpp>
#include <KEngine/App.hpp>
#include <KEngine/Core/EventManager.hpp>
#include <KEngine/Log/Log.hpp>

#include <filesystem>
#include <unordered_set>

namespace
{
    static const auto ProjectForecastExecAssetsRoot = "D:/workspace/ProjectForecastExecAssetsRoot";
}

namespace pf
{

    bool GMSRoomManagementSystem::initialise()
    {
        ke::EventManager::registerListener<pf::GMSRoomLoadRequestEvent>(this, &GMSRoomManagementSystem::handleGMSRoomLoadRequest);
        return true;
    }

    void GMSRoomManagementSystem::shutdown()
    {
        this->unloadCurrentEntities();
        ke::EventManager::deregisterListener<pf::GMSRoomLoadRequestEvent>(this, &GMSRoomManagementSystem::handleGMSRoomLoadRequest);
    }

    void GMSRoomManagementSystem::update(ke::Time elapsedTime)
    {
        KE_UNUSED(elapsedTime);
        auto currentHumanView = ke::App::instance()->getLogic()->getCurrentHumanView();
        if (currentHumanView)
        {
            auto currentCameraNode = dynamic_cast<ke::CameraNode*>(currentHumanView->getScene()->getCameraNode());
            if (currentCameraNode)
            {
                if (this->currentLevelName == "Desolate Forest")
                {
                    this->updateRorLevelBg_DesolateForest(currentCameraNode);
                }
            }
        }
    }

    void GMSRoomManagementSystem::handleGMSRoomLoadRequest(ke::EventSptr event)
    {
        auto request = std::dynamic_pointer_cast<pf::GMSRoomLoadRequestEvent>(event);
        if (nullptr == request)
        {
            ke::Log::instance()->error("GMSRoomManagementSystem received unexpected event: {}", event->getName());
            return;
        }

        if (this->isLoadingRoom)
        {
            ke::Log::instance()->warn("GMSRoomManagementSystem is alreadying loading a room. Ignoring new load request.");
            return;
        }
        this->isLoadingRoom = true;

        this->unloadCurrentEntities();
        if (this->currentRoomResource)
        {
            ke::Log::instance()->info("Unloading GM:S room: {} ...", this->currentRoomResource->getName());
            auto entityManager = ke::App::instance()->getLogic()->getEntityManager();
            for (auto entity : this->currentRoomEntities)
            {
                entityManager->removeEntity(entity->getId());
            }
            this->currentRoomEntities.clear();
            /*for (const auto & bgInfo : this->currentRoomResource->getBackgroundInfos())
            {
                ke::EventManager::enqueue(ke::makeEvent<ke::TextureUnloadRequestEvent>(bgInfo.bg, bgInfo.bg_hash));
            }*/
        }

        ke::Log::instance()->info("Loading GM:S room: {}", request->getRoomName());
        auto resourceManager = ke::App::instance()->getResourceManager();
        this->currentRoomResource = dynamic_cast<GMSRoomResource*>(resourceManager->getResource(request->getRoomName()));
        if (this->currentRoomResource != nullptr)
        {
            for (const auto & bgInfo : this->currentRoomResource->getBackgroundInfos())
            {
                if (bgInfo.bg.length() != 0)
                {
                    auto textureInfo = dynamic_cast<TextureInfoResource*>(resourceManager->getResource(bgInfo.bg));
                    if (textureInfo)
                    {
                        ke::EventManager::enqueue(ke::makeEvent<ke::TextureLoadViaFileRequestEvent>(
                            textureInfo->getName(), textureInfo->getTextureId(), textureInfo->getSourcePath()));
                    }
                }
            }

            ke::EventManager::enqueue(ke::makeEvent<ke::SetClearColourRequestEvent>(this->currentRoomResource->getColour()));

            // Instantiate tile entities.
            std::unordered_set<ke::String> tileTextureNames;
            auto entityManager = ke::App::instance()->getLogic()->getEntityManager();
            for (const auto & tile : this->currentRoomResource->getTiles())
            {
                tileTextureNames.insert(tile.bg);
                auto textureId = tile.bg_hash;
                ke::Transform2D transform;
                transform.x      = static_cast<ke::Transform2D::PointType>(tile.pos.x);
                transform.y      = static_cast<ke::Transform2D::PointType>(tile.pos.y);
                transform.scaleX = tile.scale.x;
                transform.scaleY = tile.scale.y;
                ke::Rect2DInt32 textureRect;
                textureRect.top    = tile.sourcepos.y;
                textureRect.left   = tile.sourcepos.x;
                textureRect.width  = tile.size.width;
                textureRect.height = tile.size.height;
                auto tileEntity    = entityManager->newEntity(tile.instanceid).lock();
                tileEntity->addComponent(ke::makeEntityComponent<ke::SpriteDrawableComponent>(
                    tileEntity, transform, tile.tiledepth, textureId, textureRect, tile.colour));
                this->currentRoomEntities.push_back(tileEntity.get());
            }

            // Load tile textures.
            for (const auto & tileTextureName : tileTextureNames)
            {
                auto textureInfo = dynamic_cast<TextureInfoResource*>(resourceManager->getResource(tileTextureName));
                if (textureInfo)
                {
                    ke::EventManager::enqueue(ke::makeEvent<ke::TextureLoadViaFileRequestEvent>(
                        textureInfo->getName(), textureInfo->getTextureId(), textureInfo->getSourcePath()));
                }
            }

            // Instantiate background entities.
            std::unordered_set<TextureInfoResource*> backgroundTextureInfos;
            ke::graphics::DepthType depth = std::numeric_limits<ke::graphics::DepthType>::min();
            for (const auto & bgInfo : this->currentRoomResource->getBackgroundInfos())
            {
                if (!bgInfo.enabled)
                {
                    continue;
                }

                auto textureId = bgInfo.bg_hash;
                ke::Transform2D transform;
                transform.x = static_cast<ke::Transform2D::PointType>(bgInfo.pos.x);
                transform.y = static_cast<ke::Transform2D::PointType>(bgInfo.pos.y);
                transform.scaleX = 1.0f;
                transform.scaleY = 1.0f;

                auto textureInfo = dynamic_cast<TextureInfoResource*>(resourceManager->getResource(bgInfo.bg));
                if (textureInfo)
                {
                    backgroundTextureInfos.insert(textureInfo);

                    const auto & texWidth  = textureInfo->getTextureSize().width;
                    const auto & texHeight = textureInfo->getTextureSize().height;
                    assert(texWidth);
                    assert(texHeight);
                    ke::Rect2DInt32 textureRect;
                    textureRect.top    = 0;
                    textureRect.left   = 0;
                    textureRect.width  = texWidth;
                    textureRect.height = texHeight;
                    ++depth;

                    auto bgEntity = entityManager->newEntity().lock();
                    auto drawableComponent = ke::makeEntityComponent<ke::TiledSpriteDrawablwComponent>(
                        bgEntity, transform, depth, textureId, textureRect, ke::Color::WHITE, bgInfo.tilex, bgInfo.tiley);
                    bgEntity->addComponent(drawableComponent);
                    this->currentRoomEntities.push_back(bgEntity.get());
                    this->currentRoomBgEntities.push_back(bgEntity.get());
                }

            }

            // Load background textures.
            for (const auto & textureInfo : backgroundTextureInfos)
            {
                ke::EventManager::enqueue(ke::makeEvent<ke::TextureLoadViaFileRequestEvent>(
                    textureInfo->getName(), textureInfo->getTextureId(), textureInfo->getSourcePath()));
            }
        }

        this->isLoadingRoom = false;
    }

    void GMSRoomManagementSystem::unloadCurrentEntities()
    {
        auto entityManager = ke::App::instance()->getLogic()->getEntityManager();
        for (auto entity : this->currentRoomEntities) entityManager->removeEntity(entity->getId());
        this->currentRoomEntities.clear();
        this->currentRoomBgEntities.clear();
    }

    void GMSRoomManagementSystem::updateRorLevelBg_DesolateForest(ke::CameraNode * cameraNode)
    {
        const auto cameraViewDimension = cameraNode->getDimension();
        const auto cameraViewTransform = cameraNode->getGlobalTransform();
        ke::Point2DDouble cameraTopLeftPos;
        cameraTopLeftPos.x = cameraViewTransform.x - cameraViewDimension.width / 2;
        cameraTopLeftPos.y = cameraViewTransform.y + cameraViewDimension.height / 2;
        for (int i = 0; i < this->currentRoomBgEntities.size(); ++i)
        {
            auto entity = this->currentRoomBgEntities[i];
            auto bgComponent = entity->getComponent<ke::TiledSpriteDrawablwComponent>(ke::TiledSpriteDrawablwComponent::TYPE).lock();
            auto node = bgComponent->getSceneNode();
            switch (i)
            {
            case 0: // bStars
            {
                node->setLocalTransform(cameraViewTransform);
                break;
            }
            case 1: // bPlanets
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x + cameraViewDimension.width * 0.666666666666667;
                newTransform.y = cameraTopLeftPos.y - cameraViewDimension.height * 0.142857142857143;
                node->setLocalTransform(newTransform);
                break;
            }
            case 2: // bClouds1
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x / 1.1 + 140;
                newTransform.y = cameraTopLeftPos.y / 1.07 - 60;
                node->setLocalTransform(newTransform);
                break;
            }
            case 3: // bClouds2
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x / 1.2;
                newTransform.y = cameraTopLeftPos.y / 1.1 - 106;
                node->setLocalTransform(newTransform);
                break;
            }
            case 4: // bMountains
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x;
                newTransform.y = cameraTopLeftPos.y - cameraViewDimension.height + 153;
                node->setLocalTransform(newTransform);
                break;
            }
            }
        }
    }

}<commit_msg>use bulk texture load request to reduce event spamming<commit_after>#include "GMSRoomManagementSystem.hpp"

#include "../Events/GMSRoomLoadRequestEvent.hpp"
#include "../AssetResources/TextureInfoResource.hpp"

#include <KEngine/Entity/Components/EntityRenderableComponents.hpp>
#include <KEngine/Events/OtherGraphicsEvents.hpp>
#include <KEngine/App.hpp>
#include <KEngine/Core/EventManager.hpp>
#include <KEngine/Log/Log.hpp>

#include <filesystem>
#include <unordered_set>

namespace
{
    static const auto ProjectForecastExecAssetsRoot = "D:/workspace/ProjectForecastExecAssetsRoot";
}

namespace pf
{

    bool GMSRoomManagementSystem::initialise()
    {
        ke::EventManager::registerListener<pf::GMSRoomLoadRequestEvent>(this, &GMSRoomManagementSystem::handleGMSRoomLoadRequest);
        return true;
    }

    void GMSRoomManagementSystem::shutdown()
    {
        this->unloadCurrentEntities();
        ke::EventManager::deregisterListener<pf::GMSRoomLoadRequestEvent>(this, &GMSRoomManagementSystem::handleGMSRoomLoadRequest);
    }

    void GMSRoomManagementSystem::update(ke::Time elapsedTime)
    {
        KE_UNUSED(elapsedTime);
        auto currentHumanView = ke::App::instance()->getLogic()->getCurrentHumanView();
        if (currentHumanView)
        {
            auto currentCameraNode = dynamic_cast<ke::CameraNode*>(currentHumanView->getScene()->getCameraNode());
            if (currentCameraNode)
            {
                if (this->currentLevelName == "Desolate Forest")
                {
                    this->updateRorLevelBg_DesolateForest(currentCameraNode);
                }
            }
        }
    }

    void GMSRoomManagementSystem::handleGMSRoomLoadRequest(ke::EventSptr event)
    {
        auto request = std::dynamic_pointer_cast<pf::GMSRoomLoadRequestEvent>(event);
        if (nullptr == request)
        {
            ke::Log::instance()->error("GMSRoomManagementSystem received unexpected event: {}", event->getName());
            return;
        }

        if (this->isLoadingRoom)
        {
            ke::Log::instance()->warn("GMSRoomManagementSystem is alreadying loading a room. Ignoring new load request.");
            return;
        }
        this->isLoadingRoom = true;

        this->unloadCurrentEntities();
        if (this->currentRoomResource)
        {
            ke::Log::instance()->info("Unloading GM:S room: {} ...", this->currentRoomResource->getName());
            auto entityManager = ke::App::instance()->getLogic()->getEntityManager();
            for (auto entity : this->currentRoomEntities)
            {
                entityManager->removeEntity(entity->getId());
            }
            this->currentRoomEntities.clear();
            /*for (const auto & bgInfo : this->currentRoomResource->getBackgroundInfos())
            {
                ke::EventManager::enqueue(ke::makeEvent<ke::TextureUnloadRequestEvent>(bgInfo.bg, bgInfo.bg_hash));
            }*/
        }

        ke::Log::instance()->info("Loading GM:S room: {}", request->getRoomName());
        auto resourceManager = ke::App::instance()->getResourceManager();
        this->currentRoomResource = dynamic_cast<GMSRoomResource*>(resourceManager->getResource(request->getRoomName()));
        if (this->currentRoomResource != nullptr)
        {
            auto textureLoadRequestEvent = ke::makeEvent<ke::TexturesBulkLoadViaFilesRequestEvent>();

            for (const auto & bgInfo : this->currentRoomResource->getBackgroundInfos())
            {
                if (bgInfo.bg.length() != 0)
                {
                    auto textureInfo = dynamic_cast<TextureInfoResource*>(resourceManager->getResource(bgInfo.bg));
                    if (textureInfo)
                    {
                        textureLoadRequestEvent->addTextureInfo(textureInfo->getName(), textureInfo->getTextureId(), textureInfo->getSourcePath());
                    }
                }
            }

            ke::EventManager::enqueue(ke::makeEvent<ke::SetClearColourRequestEvent>(this->currentRoomResource->getColour()));

            // Instantiate tile entities.
            std::unordered_set<ke::String> tileTextureNames;
            auto entityManager = ke::App::instance()->getLogic()->getEntityManager();
            for (const auto & tile : this->currentRoomResource->getTiles())
            {
                tileTextureNames.insert(tile.bg);
                auto textureId = tile.bg_hash;
                ke::Transform2D transform;
                transform.x      = static_cast<ke::Transform2D::PointType>(tile.pos.x);
                transform.y      = static_cast<ke::Transform2D::PointType>(tile.pos.y);
                transform.scaleX = tile.scale.x;
                transform.scaleY = tile.scale.y;
                ke::Rect2DInt32 textureRect;
                textureRect.top    = tile.sourcepos.y;
                textureRect.left   = tile.sourcepos.x;
                textureRect.width  = tile.size.width;
                textureRect.height = tile.size.height;
                auto tileEntity    = entityManager->newEntity(tile.instanceid).lock();
                tileEntity->addComponent(ke::makeEntityComponent<ke::SpriteDrawableComponent>(
                    tileEntity, transform, tile.tiledepth, textureId, textureRect, tile.colour));
                this->currentRoomEntities.push_back(tileEntity.get());
            }

            // Load tile textures.
            for (const auto & tileTextureName : tileTextureNames)
            {
                auto textureInfo = dynamic_cast<TextureInfoResource*>(resourceManager->getResource(tileTextureName));
                if (textureInfo)
                {
                    textureLoadRequestEvent->addTextureInfo(textureInfo->getName(), textureInfo->getTextureId(), textureInfo->getSourcePath());
                }
            }

            // Instantiate background entities.
            std::unordered_set<TextureInfoResource*> backgroundTextureInfos;
            ke::graphics::DepthType depth = std::numeric_limits<ke::graphics::DepthType>::min();
            for (const auto & bgInfo : this->currentRoomResource->getBackgroundInfos())
            {
                if (!bgInfo.enabled)
                {
                    continue;
                }

                auto textureId = bgInfo.bg_hash;
                ke::Transform2D transform;
                transform.x = static_cast<ke::Transform2D::PointType>(bgInfo.pos.x);
                transform.y = static_cast<ke::Transform2D::PointType>(bgInfo.pos.y);
                transform.scaleX = 1.0f;
                transform.scaleY = 1.0f;

                auto textureInfo = dynamic_cast<TextureInfoResource*>(resourceManager->getResource(bgInfo.bg));
                if (textureInfo)
                {
                    backgroundTextureInfos.insert(textureInfo);

                    const auto & texWidth  = textureInfo->getTextureSize().width;
                    const auto & texHeight = textureInfo->getTextureSize().height;
                    assert(texWidth);
                    assert(texHeight);
                    ke::Rect2DInt32 textureRect;
                    textureRect.top    = 0;
                    textureRect.left   = 0;
                    textureRect.width  = texWidth;
                    textureRect.height = texHeight;
                    ++depth;

                    auto bgEntity = entityManager->newEntity().lock();
                    auto drawableComponent = ke::makeEntityComponent<ke::TiledSpriteDrawablwComponent>(
                        bgEntity, transform, depth, textureId, textureRect, ke::Color::WHITE, bgInfo.tilex, bgInfo.tiley);
                    bgEntity->addComponent(drawableComponent);
                    this->currentRoomEntities.push_back(bgEntity.get());
                    this->currentRoomBgEntities.push_back(bgEntity.get());
                }

            }

            // Load background textures.
            for (const auto & textureInfo : backgroundTextureInfos)
            {
                textureLoadRequestEvent->addTextureInfo(textureInfo->getName(), textureInfo->getTextureId(), textureInfo->getSourcePath());
            }
            ke::EventManager::enqueue(textureLoadRequestEvent);
        }

        this->isLoadingRoom = false;
    }

    void GMSRoomManagementSystem::unloadCurrentEntities()
    {
        auto entityManager = ke::App::instance()->getLogic()->getEntityManager();
        for (auto entity : this->currentRoomEntities) entityManager->removeEntity(entity->getId());
        this->currentRoomEntities.clear();
        this->currentRoomBgEntities.clear();
    }

    void GMSRoomManagementSystem::updateRorLevelBg_DesolateForest(ke::CameraNode * cameraNode)
    {
        const auto cameraViewDimension = cameraNode->getDimension();
        const auto cameraViewTransform = cameraNode->getGlobalTransform();
        ke::Point2DDouble cameraTopLeftPos;
        cameraTopLeftPos.x = cameraViewTransform.x - cameraViewDimension.width / 2;
        cameraTopLeftPos.y = cameraViewTransform.y + cameraViewDimension.height / 2;
        for (int i = 0; i < this->currentRoomBgEntities.size(); ++i)
        {
            auto entity = this->currentRoomBgEntities[i];
            auto bgComponent = entity->getComponent<ke::TiledSpriteDrawablwComponent>(ke::TiledSpriteDrawablwComponent::TYPE).lock();
            auto node = bgComponent->getSceneNode();
            switch (i)
            {
            case 0: // bStars
            {
                node->setLocalTransform(cameraViewTransform);
                break;
            }
            case 1: // bPlanets
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x + cameraViewDimension.width * 0.666666666666667;
                newTransform.y = cameraTopLeftPos.y - cameraViewDimension.height * 0.142857142857143;
                node->setLocalTransform(newTransform);
                break;
            }
            case 2: // bClouds1
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x / 1.1 + 140;
                newTransform.y = cameraTopLeftPos.y / 1.07 - 60;
                node->setLocalTransform(newTransform);
                break;
            }
            case 3: // bClouds2
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x / 1.2;
                newTransform.y = cameraTopLeftPos.y / 1.1 - 106;
                node->setLocalTransform(newTransform);
                break;
            }
            case 4: // bMountains
            {
                ke::Transform2D newTransform;
                newTransform.x = cameraTopLeftPos.x;
                newTransform.y = cameraTopLeftPos.y - cameraViewDimension.height + 153;
                node->setLocalTransform(newTransform);
                break;
            }
            }
        }
    }

}<|endoftext|>


<commit_before>// Copyright (c) 2011 Sirikata 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 <map>
#include <string>
#include <sirikata/core/util/Standard.hh>
#include <sirikata/core/options/Options.hpp>
#include <sirikata/core/transfer/TransferPool.hpp>
#include <sirikata/core/transfer/TransferHandlers.hpp>
#include <sirikata/core/transfer/RemoteFileMetadata.hpp>
#include <sirikata/core/options/Options.hpp>
#include <sirikata/core/options/CommonOptions.hpp>
#include <boost/bind.hpp>
#include <sirikata/core/transfer/HttpTransferHandler.hpp>
#include <sirikata/core/transfer/URL.hpp>
#include <boost/lexical_cast.hpp>

AUTO_SINGLETON_INSTANCE(Sirikata::Transfer::HttpNameHandler);
AUTO_SINGLETON_INSTANCE(Sirikata::Transfer::HttpChunkHandler);

namespace Sirikata {
namespace Transfer {

HttpNameHandler& HttpNameHandler::getSingleton() {
    return AutoSingleton<HttpNameHandler>::getSingleton();
}
void HttpNameHandler::destroy() {
    AutoSingleton<HttpNameHandler>::destroy();
}

HttpChunkHandler& HttpChunkHandler::getSingleton() {
    return AutoSingleton<HttpChunkHandler>::getSingleton();
}
void HttpChunkHandler::destroy() {
    AutoSingleton<HttpChunkHandler>::destroy();
}

HttpNameHandler::HttpNameHandler()
{
}

HttpNameHandler::~HttpNameHandler() {

}

void HttpNameHandler::resolve(std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {
    URL url(request->getURI());
    assert(!url.empty());

    std::tr1::shared_ptr<RemoteFileMetadata> bad;
    if (url.host() == "") {
        HttpManager::getSingleton().postCallback(std::tr1::bind(callback,bad), "HttpNameHandler::resolve callback");
        return;
    }

    std::string host_name = url.hostname();
    std::string service = url.context().service();
    if (service.empty()) service = "http";
    Network::Address cdn_addr(host_name, service);

    HttpManager::Headers headers;
    headers["Host"] = host_name;
    headers["Accept-Encoding"] = "deflate, gzip";

    HttpManager::getSingleton().get(
        cdn_addr, url.fullpath(),
        std::tr1::bind(&HttpNameHandler::request_finished, this, _1, _2, _3, request, callback),
        headers
    );
}

void HttpNameHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {

    mStats.resolved++;
    mStats.bytesTransferred += (response->getBytesSent() + response->getBytesReceived());

    std::tr1::shared_ptr<RemoteFileMetadata> bad;

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP name lookup (" << request->getURI() << "). Boost error = " << boost_error.message());
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP name lookup. (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (!response->getData()) {
        SILOG(transfer, error, "Body not present during an HTTP 'name lookup' (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    Fingerprint fp = SparseData(response->getData()).computeFingerprint();

    //Just treat everything as a single chunk for now
    Range::length_type file_size = response->getData()->length();
    Range whole(0, file_size, LENGTH, true);
    Chunk chunk(fp, whole);
    ChunkList chunkList;
    chunkList.push_back(chunk);

    SharedChunkCache::getSingleton().getCache()->addToCache(fp, response->getData());
    std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(),
            file_size, chunkList, response->getRawHeaders()));
    callback(met);
}

HttpChunkHandler::HttpChunkHandler()
{
}

HttpChunkHandler::~HttpChunkHandler() {
}

void HttpChunkHandler::get(std::tr1::shared_ptr<RemoteFileMetadata> file,
        std::tr1::shared_ptr<Chunk> chunk, ChunkCallback callback) {

    //Check for null arguments
    std::tr1::shared_ptr<DenseData> bad;
    if (!file) {
        SILOG(transfer, error, "HttpChunkHandler get called with null file parameter");
        callback(bad);
        return;
    }
    if (!chunk) {
        SILOG(transfer, error, "HttpChunkHandler get called with null chunk parameter");
        callback(bad);
        return;
    }

    //Make sure chunk given is part of file
    bool foundIt = false;
    const ChunkList & chunks = file->getChunkList();
    for (ChunkList::const_iterator it = chunks.begin(); it != chunks.end(); it++) {
        if(*chunk == *it) {
            foundIt = true;
        }
    }
    if(!foundIt) {
        SILOG(transfer, error, "HttpChunkHandler get called with chunk not present in file metadata");
        callback(bad);
        return;
    }

    //Check to see if it's in the cache first
    SharedChunkCache::getSingleton().getCache()->getData(file->getFingerprint(), chunk->getRange(), std::tr1::bind(
            &HttpChunkHandler::cache_check_callback, this, _1, file, chunk, callback));
}

void HttpChunkHandler::cache_check_callback(const SparseData* data, std::tr1::shared_ptr<RemoteFileMetadata> file,
            std::tr1::shared_ptr<Chunk> chunk, ChunkCallback callback) {
    if (data) {
        mStats.downloaded++;
        std::tr1::shared_ptr<const DenseData> flattened = data->flatten();
        callback(flattened);
    } else {
        URL url(file->getURI());
        assert(!url.empty());

        std::string host_name = url.hostname();
        std::string service = url.context().service();
        if (service.empty()) service = "http";
        Network::Address cdn_addr(host_name, service);

        HttpManager::Headers headers;
        headers["Host"] = host_name;
        headers["Accept-Encoding"] = "deflate, gzip";

        HttpManager::getSingleton().get(
            cdn_addr, url.fullpath(),
            std::tr1::bind(&HttpChunkHandler::request_finished, this, _1, _2, _3, file, chunk, callback),
            headers
        );
    }
}

void HttpChunkHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        std::tr1::shared_ptr<RemoteFileMetadata> file, std::tr1::shared_ptr<Chunk> chunk,
        ChunkCallback callback) {

    mStats.downloaded++;
    mStats.bytesTransferred += (response->getBytesSent() + response->getBytesReceived());

    std::tr1::shared_ptr<DenseData> bad;
    std::string reqType = "file request";

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP " << reqType << ". Boost error = " << boost_error.message() << " (" << file->getURI() << ")");
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    if (!response->getData()) {
        SILOG(transfer, error, "Body not present during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    SILOG(transfer, detailed, "about to call addToCache with fingerprint ID = " << file->getFingerprint().convertToHexString());
    SharedChunkCache::getSingleton().getCache()->addToCache(file->getFingerprint(), response->getData());

    callback(response->getData());
    SILOG(transfer, detailed, "done http chunk handler request_finished");
}

}
}
<commit_msg>Properly handle stats for failed HTTP requests.<commit_after>// Copyright (c) 2011 Sirikata 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 <map>
#include <string>
#include <sirikata/core/util/Standard.hh>
#include <sirikata/core/options/Options.hpp>
#include <sirikata/core/transfer/TransferPool.hpp>
#include <sirikata/core/transfer/TransferHandlers.hpp>
#include <sirikata/core/transfer/RemoteFileMetadata.hpp>
#include <sirikata/core/options/Options.hpp>
#include <sirikata/core/options/CommonOptions.hpp>
#include <boost/bind.hpp>
#include <sirikata/core/transfer/HttpTransferHandler.hpp>
#include <sirikata/core/transfer/URL.hpp>
#include <boost/lexical_cast.hpp>

AUTO_SINGLETON_INSTANCE(Sirikata::Transfer::HttpNameHandler);
AUTO_SINGLETON_INSTANCE(Sirikata::Transfer::HttpChunkHandler);

namespace Sirikata {
namespace Transfer {

HttpNameHandler& HttpNameHandler::getSingleton() {
    return AutoSingleton<HttpNameHandler>::getSingleton();
}
void HttpNameHandler::destroy() {
    AutoSingleton<HttpNameHandler>::destroy();
}

HttpChunkHandler& HttpChunkHandler::getSingleton() {
    return AutoSingleton<HttpChunkHandler>::getSingleton();
}
void HttpChunkHandler::destroy() {
    AutoSingleton<HttpChunkHandler>::destroy();
}

HttpNameHandler::HttpNameHandler()
{
}

HttpNameHandler::~HttpNameHandler() {

}

void HttpNameHandler::resolve(std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {
    URL url(request->getURI());
    assert(!url.empty());

    std::tr1::shared_ptr<RemoteFileMetadata> bad;
    if (url.host() == "") {
        HttpManager::getSingleton().postCallback(std::tr1::bind(callback,bad), "HttpNameHandler::resolve callback");
        return;
    }

    std::string host_name = url.hostname();
    std::string service = url.context().service();
    if (service.empty()) service = "http";
    Network::Address cdn_addr(host_name, service);

    HttpManager::Headers headers;
    headers["Host"] = host_name;
    headers["Accept-Encoding"] = "deflate, gzip";

    HttpManager::getSingleton().get(
        cdn_addr, url.fullpath(),
        std::tr1::bind(&HttpNameHandler::request_finished, this, _1, _2, _3, request, callback),
        headers
    );
}

void HttpNameHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {

    mStats.resolved++;
    if (response) mStats.bytesTransferred += (response->getBytesSent() + response->getBytesReceived());

    std::tr1::shared_ptr<RemoteFileMetadata> bad;

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP name lookup (" << request->getURI() << "). Boost error = " << boost_error.message());
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP name lookup. (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (!response->getData()) {
        SILOG(transfer, error, "Body not present during an HTTP 'name lookup' (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    Fingerprint fp = SparseData(response->getData()).computeFingerprint();

    //Just treat everything as a single chunk for now
    Range::length_type file_size = response->getData()->length();
    Range whole(0, file_size, LENGTH, true);
    Chunk chunk(fp, whole);
    ChunkList chunkList;
    chunkList.push_back(chunk);

    SharedChunkCache::getSingleton().getCache()->addToCache(fp, response->getData());
    std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(),
            file_size, chunkList, response->getRawHeaders()));
    callback(met);
}

HttpChunkHandler::HttpChunkHandler()
{
}

HttpChunkHandler::~HttpChunkHandler() {
}

void HttpChunkHandler::get(std::tr1::shared_ptr<RemoteFileMetadata> file,
        std::tr1::shared_ptr<Chunk> chunk, ChunkCallback callback) {

    //Check for null arguments
    std::tr1::shared_ptr<DenseData> bad;
    if (!file) {
        SILOG(transfer, error, "HttpChunkHandler get called with null file parameter");
        callback(bad);
        return;
    }
    if (!chunk) {
        SILOG(transfer, error, "HttpChunkHandler get called with null chunk parameter");
        callback(bad);
        return;
    }

    //Make sure chunk given is part of file
    bool foundIt = false;
    const ChunkList & chunks = file->getChunkList();
    for (ChunkList::const_iterator it = chunks.begin(); it != chunks.end(); it++) {
        if(*chunk == *it) {
            foundIt = true;
        }
    }
    if(!foundIt) {
        SILOG(transfer, error, "HttpChunkHandler get called with chunk not present in file metadata");
        callback(bad);
        return;
    }

    //Check to see if it's in the cache first
    SharedChunkCache::getSingleton().getCache()->getData(file->getFingerprint(), chunk->getRange(), std::tr1::bind(
            &HttpChunkHandler::cache_check_callback, this, _1, file, chunk, callback));
}

void HttpChunkHandler::cache_check_callback(const SparseData* data, std::tr1::shared_ptr<RemoteFileMetadata> file,
            std::tr1::shared_ptr<Chunk> chunk, ChunkCallback callback) {
    if (data) {
        mStats.downloaded++;
        std::tr1::shared_ptr<const DenseData> flattened = data->flatten();
        callback(flattened);
    } else {
        URL url(file->getURI());
        assert(!url.empty());

        std::string host_name = url.hostname();
        std::string service = url.context().service();
        if (service.empty()) service = "http";
        Network::Address cdn_addr(host_name, service);

        HttpManager::Headers headers;
        headers["Host"] = host_name;
        headers["Accept-Encoding"] = "deflate, gzip";

        HttpManager::getSingleton().get(
            cdn_addr, url.fullpath(),
            std::tr1::bind(&HttpChunkHandler::request_finished, this, _1, _2, _3, file, chunk, callback),
            headers
        );
    }
}

void HttpChunkHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        std::tr1::shared_ptr<RemoteFileMetadata> file, std::tr1::shared_ptr<Chunk> chunk,
        ChunkCallback callback) {

    mStats.downloaded++;
    if (response) mStats.bytesTransferred += (response->getBytesSent() + response->getBytesReceived());

    std::tr1::shared_ptr<DenseData> bad;
    std::string reqType = "file request";

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP " << reqType << ". Boost error = " << boost_error.message() << " (" << file->getURI() << ")");
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    if (!response->getData()) {
        SILOG(transfer, error, "Body not present during an HTTP " << reqType << " (" << file->getURI() << ")");
        callback(bad);
        return;
    }

    SILOG(transfer, detailed, "about to call addToCache with fingerprint ID = " << file->getFingerprint().convertToHexString());
    SharedChunkCache::getSingleton().getCache()->addToCache(file->getFingerprint(), response->getData());

    callback(response->getData());
    SILOG(transfer, detailed, "done http chunk handler request_finished");
}

}
}
<|endoftext|>


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

Copyright (c) Kitware Inc.
All rights reserved.

=========================================================================*/
// .SECTION Thanks
// This test was written by Charles Law and Philippe Pebay, Kitware 2012

#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridAxisCut.h"
#include "vtkHyperTreeGridSource.h"
#include "vtkHyperTreeGridGeometry.h"

#include "vtkCellData.h"
#include "vtkContourFilter.h"
#include "vtkCutter.h"
#include "vtkDataSetWriter.h"
#include "vtkNew.h"
#include "vtkPlane.h"
#include "vtkPolyDataWriter.h"
#include "vtkRenderer.h"
#include "vtkShrinkFilter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridWriter.h"
#include "vtkXMLUnstructuredGridWriter.h"

#include "vtksys/CommandLineArguments.hxx"

int TestHyperTreeGrid( int argc, char* argv[] )
{
  // Default parameters and options
  int dim = 3;
  int branch = 3;
  int max = 3;
  int nX = 3;
  int nY = 4;
  int nZ = 2;
  bool skipAxisCut = false;
  bool skipContour = false;
  bool skipCut = false;
  bool skipGeometry = false;
  bool skipShrink = false;

  // Initialize command line argument parser
  vtksys::CommandLineArguments clArgs;
  clArgs.Initialize( argc, argv );
  clArgs.StoreUnusedArguments( false );

  // Parse command line parameters and options
  clArgs.AddArgument( "--dimension",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &dim, "Dimension of hyper tree grid" );

  clArgs.AddArgument( "--branch-factor",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &branch, "Branching factor of hyper tree grid" );

  clArgs.AddArgument( "--max-level",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &max, "Maximum depth of hyper tree grid" );

  clArgs.AddArgument( "--grid-size-X",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nX, "Size of hyper tree grid in X direction" );

  clArgs.AddArgument( "--grid-size-Y",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nY, "Size of hyper tree grid in Y direction" );

  clArgs.AddArgument( "--grid-size-Z",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nZ, "Size of hyper tree grid in Z direction" );

  clArgs.AddArgument( "--skip-Axis-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip axis cut filter" );

  clArgs.AddArgument( "--skip-Contour",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip contour filter" );

  clArgs.AddArgument( "--skip-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipCut, "Skip cut filter" );

  clArgs.AddArgument( "--skip-Geometry",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipGeometry, "Skip geometry filter" );

  clArgs.AddArgument( "--skip-Shrink",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipShrink, "Skip shrink filter" );

  // If incorrect arguments were provided, provide some help and terminate in error.
  if ( ! clArgs.Parse() )
    {
    cerr << "Usage: "
         << clArgs.GetHelp()
         << "\n";
    }

  // Ensure that parsed dimensionality makes sense
  if ( dim > 3 )
    {
    dim = 3;
    }
  else if ( dim < 1 )
    {
    dim = 1;
    }

  // Ensure that parsed branch factor makes sense
  if ( branch > 3 )
    {
    branch = 3;
    }
  else if ( branch < 2 )
    {
    branch = 2;
    }

  // Ensure that parsed maximum level makes sense
  if ( max < 1 )
    {
    max = 1;
    }

  // Ensure that parsed grid sizes make sense
  if ( nX < 1 )
    {
    nX = 1;
    }
  if ( nY < 1 )
    {
    nY = 1;
    }
  if ( nZ < 1 )
    {
    nZ = 1;
    }

  // Ensure that parsed grid sizes are consistent with dimensionality
  if ( dim < 3 )
    {
    nZ = 1;
    if ( dim < 2 )
      {
      nY = 1;
      }
    }

  // Initialize return value of test
  int testIntValue = 0;

  // Create hyper tree grid source
  vtkNew<vtkHyperTreeGridSource> fractal;
  fractal->SetMaximumLevel( max );
  fractal->DualOn();
  if ( dim == 3 )
    {
    fractal->SetGridSize( nX, nY, nZ );
    }
  fractal->SetGridSize( nX, nY, nZ );
  fractal->SetDimension( dim );
  fractal->SetAxisBranchFactor( branch );
  fractal->Update();
  vtkHyperTreeGrid* htGrid = fractal->GetOutput();

  if ( ! skipGeometry )
    {
    cerr << "# Geometry" << endl;
    vtkNew<vtkHyperTreeGridGeometry> geometry;
    geometry->SetInputConnection( fractal->GetOutputPort() );
    vtkNew<vtkPolyDataWriter> writer4;
    writer4->SetFileName( "./hyperTreeGridGeometry.vtk" );
    writer4->SetInputConnection( geometry->GetOutputPort() );
    writer4->Write();
    }

  if ( ! skipContour )
    {
    cerr << "# Contour" << endl;
    vtkNew<vtkContourFilter> contour;
    contour->SetInputData( htGrid );
    contour->SetNumberOfContours( 2 );
    contour->SetValue( 0, 4. );
    contour->SetValue( 1, 18. );
    contour->SetInputArrayToProcess( 0, 0, 0,
                                     vtkDataObject::FIELD_ASSOCIATION_POINTS,
                                     "Cell Value" );
    vtkNew<vtkPolyDataWriter> writer0;
    writer0->SetFileName( "./hyperTreeGridContour.vtk" );
    writer0->SetInputConnection( contour->GetOutputPort() );
    writer0->Write();
    }

  if ( ! skipShrink )
    {
    cerr << "# Shrink" << endl;
    vtkNew<vtkShrinkFilter> shrink;
    shrink->SetInputData( htGrid );
    shrink->SetShrinkFactor( 1. );
    vtkNew<vtkUnstructuredGridWriter> writer1;
    writer1->SetFileName( "./hyperTreeGridShrink.vtk" );
    writer1->SetInputConnection( shrink->GetOutputPort() );
    writer1->Write();
    }

  if ( ! skipAxisCut )
    {
    // Axis-aligned cut works only in 3D for now
    if ( dim == 3 )
      {
      cerr << "# HyperTreeGridAxisCut" << endl;
      vtkNew<vtkHyperTreeGridAxisCut> axisCut;
      axisCut->SetInputConnection( fractal->GetOutputPort() );
      axisCut->SetPlaneNormalAxis( 2 );
      axisCut->SetPlanePosition( .1 );
      vtkNew<vtkPolyDataWriter> writer2;
      writer2->SetFileName( "./hyperTreeGridAxisCut.vtk" );
      writer2->SetInputConnection( axisCut->GetOutputPort() );
      writer2->Write();
      }
    }

  if ( ! skipCut )
    {
    cerr << "# Cut" << endl;
    vtkNew<vtkCutter> cut;
    vtkNew<vtkPlane> plane;
    plane->SetOrigin( .5, .5, .15 );
    plane->SetNormal( 0, 0, 1 );
    cut->SetInputData( htGrid );
    cut->SetCutFunction( plane.GetPointer() );
    vtkNew<vtkPolyDataWriter> writer3;
    writer3->SetFileName( "./hyperTreeGridCut.vtk" );
    writer3->SetInputConnection( cut->GetOutputPort() );
    writer3->Write();
    }

  return testIntValue;
}
<commit_msg>Documentation<commit_after>/*=========================================================================

Copyright (c) Kitware Inc.
All rights reserved.

=========================================================================*/
// .SECTION Description
// This program illustrates the use of various filters acting upon hyper
// tree grid data sets. It generates output files in VTK format.
//
// .SECTION Usage
//   --branch-factor opt  Branching factor of hyper tree grid
//   --dimension opt      Dimension of hyper tree grid
//   --grid-size-X opt    Size of hyper tree grid in X direction
//   --grid-size-Y opt    Size of hyper tree grid in Y direction
//   --grid-size-Z opt    Size of hyper tree grid in Z direction
//   --max-level opt      Maximum depth of hyper tree grid
//   --skip-Axis-Cut      Skip axis cut filter
//   --skip-Contour       Skip contour filter
//   --skip-Cut           Skip cut filter
//   --skip-Geometry      Skip geometry filter
//   --skip-Shrink        Skip shrink filter
//
// .SECTION Thanks
// This example was written by Charles Law and Philippe Pebay, Kitware 2012

#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridAxisCut.h"
#include "vtkHyperTreeGridSource.h"
#include "vtkHyperTreeGridGeometry.h"

#include "vtkCellData.h"
#include "vtkContourFilter.h"
#include "vtkCutter.h"
#include "vtkDataSetWriter.h"
#include "vtkNew.h"
#include "vtkPlane.h"
#include "vtkPolyDataWriter.h"
#include "vtkRenderer.h"
#include "vtkShrinkFilter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridWriter.h"
#include "vtkXMLUnstructuredGridWriter.h"

#include "vtksys/CommandLineArguments.hxx"

int TestHyperTreeGrid( int argc, char* argv[] )
{
  // Default parameters and options
  int dim = 3;
  int branch = 3;
  int max = 3;
  int nX = 3;
  int nY = 4;
  int nZ = 2;
  bool skipAxisCut = false;
  bool skipContour = false;
  bool skipCut = false;
  bool skipGeometry = false;
  bool skipShrink = false;

  // Initialize command line argument parser
  vtksys::CommandLineArguments clArgs;
  clArgs.Initialize( argc, argv );
  clArgs.StoreUnusedArguments( false );

  // Parse command line parameters and options
  clArgs.AddArgument( "--dimension",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &dim, "Dimension of hyper tree grid" );

  clArgs.AddArgument( "--branch-factor",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &branch, "Branching factor of hyper tree grid" );

  clArgs.AddArgument( "--max-level",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &max, "Maximum depth of hyper tree grid" );

  clArgs.AddArgument( "--grid-size-X",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nX, "Size of hyper tree grid in X direction" );

  clArgs.AddArgument( "--grid-size-Y",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nY, "Size of hyper tree grid in Y direction" );

  clArgs.AddArgument( "--grid-size-Z",
                      vtksys::CommandLineArguments::SPACE_ARGUMENT,
                      &nZ, "Size of hyper tree grid in Z direction" );

  clArgs.AddArgument( "--skip-Axis-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip axis cut filter" );

  clArgs.AddArgument( "--skip-Contour",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipAxisCut, "Skip contour filter" );

  clArgs.AddArgument( "--skip-Cut",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipCut, "Skip cut filter" );

  clArgs.AddArgument( "--skip-Geometry",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipGeometry, "Skip geometry filter" );

  clArgs.AddArgument( "--skip-Shrink",
                      vtksys::CommandLineArguments::NO_ARGUMENT,
                      &skipShrink, "Skip shrink filter" );

  // If incorrect arguments were provided, provide some help and terminate in error.
  if ( ! clArgs.Parse() )
    {
    cerr << "Usage: "
         << clArgs.GetHelp()
         << "\n";
    }

  // Ensure that parsed dimensionality makes sense
  if ( dim > 3 )
    {
    dim = 3;
    }
  else if ( dim < 1 )
    {
    dim = 1;
    }

  // Ensure that parsed branch factor makes sense
  if ( branch > 3 )
    {
    branch = 3;
    }
  else if ( branch < 2 )
    {
    branch = 2;
    }

  // Ensure that parsed maximum level makes sense
  if ( max < 1 )
    {
    max = 1;
    }

  // Ensure that parsed grid sizes make sense
  if ( nX < 1 )
    {
    nX = 1;
    }
  if ( nY < 1 )
    {
    nY = 1;
    }
  if ( nZ < 1 )
    {
    nZ = 1;
    }

  // Ensure that parsed grid sizes are consistent with dimensionality
  if ( dim < 3 )
    {
    nZ = 1;
    if ( dim < 2 )
      {
      nY = 1;
      }
    }

  // Initialize return value of test
  int testIntValue = 0;

  // Create hyper tree grid source
  vtkNew<vtkHyperTreeGridSource> fractal;
  fractal->SetMaximumLevel( max );
  fractal->DualOn();
  if ( dim == 3 )
    {
    fractal->SetGridSize( nX, nY, nZ );
    }
  fractal->SetGridSize( nX, nY, nZ );
  fractal->SetDimension( dim );
  fractal->SetAxisBranchFactor( branch );
  fractal->Update();
  vtkHyperTreeGrid* htGrid = fractal->GetOutput();

  if ( ! skipGeometry )
    {
    cerr << "# Geometry" << endl;
    vtkNew<vtkHyperTreeGridGeometry> geometry;
    geometry->SetInputConnection( fractal->GetOutputPort() );
    vtkNew<vtkPolyDataWriter> writer4;
    writer4->SetFileName( "./hyperTreeGridGeometry.vtk" );
    writer4->SetInputConnection( geometry->GetOutputPort() );
    writer4->Write();
    }

  if ( ! skipContour )
    {
    cerr << "# Contour" << endl;
    vtkNew<vtkContourFilter> contour;
    contour->SetInputData( htGrid );
    contour->SetNumberOfContours( 2 );
    contour->SetValue( 0, 4. );
    contour->SetValue( 1, 18. );
    contour->SetInputArrayToProcess( 0, 0, 0,
                                     vtkDataObject::FIELD_ASSOCIATION_POINTS,
                                     "Cell Value" );
    vtkNew<vtkPolyDataWriter> writer0;
    writer0->SetFileName( "./hyperTreeGridContour.vtk" );
    writer0->SetInputConnection( contour->GetOutputPort() );
    writer0->Write();
    }

  if ( ! skipShrink )
    {
    cerr << "# Shrink" << endl;
    vtkNew<vtkShrinkFilter> shrink;
    shrink->SetInputData( htGrid );
    shrink->SetShrinkFactor( 1. );
    vtkNew<vtkUnstructuredGridWriter> writer1;
    writer1->SetFileName( "./hyperTreeGridShrink.vtk" );
    writer1->SetInputConnection( shrink->GetOutputPort() );
    writer1->Write();
    }

  if ( ! skipAxisCut )
    {
    // Axis-aligned cut works only in 3D for now
    if ( dim == 3 )
      {
      cerr << "# HyperTreeGridAxisCut" << endl;
      vtkNew<vtkHyperTreeGridAxisCut> axisCut;
      axisCut->SetInputConnection( fractal->GetOutputPort() );
      axisCut->SetPlaneNormalAxis( 2 );
      axisCut->SetPlanePosition( .1 );
      vtkNew<vtkPolyDataWriter> writer2;
      writer2->SetFileName( "./hyperTreeGridAxisCut.vtk" );
      writer2->SetInputConnection( axisCut->GetOutputPort() );
      writer2->Write();
      }
    }

  if ( ! skipCut )
    {
    cerr << "# Cut" << endl;
    vtkNew<vtkCutter> cut;
    vtkNew<vtkPlane> plane;
    plane->SetOrigin( .5, .5, .15 );
    plane->SetNormal( 0, 0, 1 );
    cut->SetInputData( htGrid );
    cut->SetCutFunction( plane.GetPointer() );
    vtkNew<vtkPolyDataWriter> writer3;
    writer3->SetFileName( "./hyperTreeGridCut.vtk" );
    writer3->SetInputConnection( cut->GetOutputPort() );
    writer3->Write();
    }

  return testIntValue;
}
<|endoftext|>