<commit_before>/*
    Copyright (C) 2014  Sarah Wong

    This file is part of swgetf0.

    swgetf0 is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <QApplication>
#include <QAudioInput> // not final
#include <QAudioDeviceInfo> // not final
#include <QDebug>

#include "mainwindow.h"
#include "inputdevice.h"

////////////////////////////////////////////////////////////////////////////////
//

#include <iostream>
#include <thread>

#include <pulse/simple.h>

#include "GetF0StreamImpl.h"

typedef short DiskSample;

//
////////////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);

  InputDevice* inputDevice = new InputDevice();
  int result = inputDevice->exec();
  if (result == QDialog::Rejected) {
    delete inputDevice;
    return 0;
  }

  QAudioDeviceInfo audioDeviceInfo = inputDevice->getAudioDeviceInfo();
  QAudioFormat audioFormat = inputDevice->getAudioFormat();
  delete inputDevice;

  qDebug() << audioDeviceInfo.deviceName();
  qDebug() << audioFormat;

////////////////////////////////////////////////////////////////////////////////
//
  using GetF0::GetF0StreamImpl;

  class Foo : public GetF0StreamImpl<DiskSample> {
  public:
    struct PulseStream : public IStream {
      PulseStream(pa_simple* s) : s(s) { }

      size_t read(void* ptr, size_t size, size_t nmemb) override {
        pa_simple_read(s, ptr, size * nmemb, NULL);  // TODO this is mess. fix.
        return nmemb;
      }
      int feof() override { return 0; }
      int ferror() override { return 0; }

      pa_simple* s;
    };

    struct QIOStream : public IStream {
      QIOStream(QIODevice* ioDevice) : m_ioDevice(ioDevice) {}

      size_t read(void* ptr, size_t size, size_t nmemb) override
      {
        return m_ioDevice->read(static_cast<char*>(ptr), size * nmemb) / size;
      }

      int feof() override { return 0; }

      int ferror() override
      {
        return 0;  // TODO
      }

      QIODevice* m_ioDevice;
    };

    Foo(pa_simple* s) : GetF0StreamImpl<DiskSample>(new PulseStream(s), 96000)
    {
    }

    Foo(QIODevice* ioDevice)
        : GetF0StreamImpl<DiskSample>(new QIOStream(ioDevice), 96000)
    {
    }

    void setViewer(MainWindow* viewer) { m_viewer = viewer; }

    void write_output_reversed(float* f0p, float* vuvp, float* rms_speech,
                               float* acpkp, int vecsize) override
    {
      std::lock_guard<std::mutex> lockGuard(m_viewer->mutex());

      auto& cb = m_viewer->cb();

      for (int i = vecsize - 1; i >= 0; --i) {
        cb.push_back({f0p[i], rms_speech[i]});
      }
    }

    MainWindow *m_viewer;

  };

  Foo* f0;

  if (std::string(argv[1]) == "q") {
    std::cout << "QT Audio" << std::endl;

    QAudioInput* audio;
    {
      QAudioFormat format;
      // Set up the desired format, for example:
      format.setSampleRate(96000);
      format.setChannelCount(1);
      format.setSampleSize(16);
      format.setCodec("audio/pcm");
      format.setByteOrder(QAudioFormat::LittleEndian);
      format.setSampleType(QAudioFormat::SignedInt);

      audio = new QAudioInput(format);
    }

    f0 = new Foo(audio->start());

  } else if (std::string(argv[1]) == "p") {
    std::cout << "PulseAudio" << std::endl;

    pa_simple* s;
    pa_sample_spec ss;
    ss.format = PA_SAMPLE_S16LE;
    ss.channels = 1;
    ss.rate = 96000;
    s = pa_simple_new(NULL,         // Use the default server.
                      "swpitcher",  // Our application's name.
                      PA_STREAM_RECORD,
                      NULL,      // Use the default device.
                      "Record",  // Description of our stream.
                      &ss,       // Our sample format.
                      NULL,      // Use default channel map
                      NULL,      // Use default buffering attributes.
                      NULL       // Ignore error code.
                      );
    if (s == nullptr) {
      std::cerr << "Pulse failed." << std::endl;
    }

    f0 = new Foo(s);

  } else {
    return 1;
  }

  f0->init();

//
////////////////////////////////////////////////////////////////////////////////

  enum { SECONDS = 5 };

  MainWindow mainWindow(f0->pitchFrameRate() * SECONDS);
  mainWindow.show();

  f0->setViewer(&mainWindow);

  // Run on new thread
  std::thread inputThread(std::bind(&Foo::run, f0));

  return app.exec();
}
<commit_msg>User can now choose sample rate for Qt audio<commit_after>/*
    Copyright (C) 2014  Sarah Wong

    This file is part of swgetf0.

    swgetf0 is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <QApplication>
#include <QAudioInput> // not final
#include <QAudioDeviceInfo> // not final
#include <QDebug>

#include "mainwindow.h"
#include "inputdevice.h"

////////////////////////////////////////////////////////////////////////////////
//

#include <iostream>
#include <thread>

#include <pulse/simple.h>

#include "GetF0StreamImpl.h"

typedef short DiskSample;

//
////////////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);

  InputDevice* inputDevice = new InputDevice();
  int result = inputDevice->exec();
  if (result == QDialog::Rejected) {
    delete inputDevice;
    return 0;
  }

  QAudioDeviceInfo audioDeviceInfo = inputDevice->getAudioDeviceInfo();
  QAudioFormat audioFormat = inputDevice->getAudioFormat();
  delete inputDevice;

  qDebug() << audioDeviceInfo.deviceName();
  qDebug() << audioFormat;

////////////////////////////////////////////////////////////////////////////////
//
  using GetF0::GetF0StreamImpl;

  class Foo : public GetF0StreamImpl<DiskSample> {
  public:
    struct PulseStream : public IStream {
      PulseStream(pa_simple* s) : s(s) { }

      size_t read(void* ptr, size_t size, size_t nmemb) override {
        pa_simple_read(s, ptr, size * nmemb, NULL);  // TODO this is mess. fix.
        return nmemb;
      }
      int feof() override { return 0; }
      int ferror() override { return 0; }

      pa_simple* s;
    };

    struct QIOStream : public IStream {
      QIOStream(QIODevice* ioDevice) : m_ioDevice(ioDevice) {}

      size_t read(void* ptr, size_t size, size_t nmemb) override
      {
        return m_ioDevice->read(static_cast<char*>(ptr), size * nmemb) / size;
      }

      int feof() override { return 0; }

      int ferror() override
      {
        return 0;  // TODO
      }

      QIODevice* m_ioDevice;
    };

    Foo(pa_simple* s) : GetF0StreamImpl<DiskSample>(new PulseStream(s), 96000)
    {
    }

    Foo(QIODevice* ioDevice, int sampleRate)
        : GetF0StreamImpl<DiskSample>(new QIOStream(ioDevice), sampleRate)
    {
    }

    void setViewer(MainWindow* viewer) { m_viewer = viewer; }

    void write_output_reversed(float* f0p, float* vuvp, float* rms_speech,
                               float* acpkp, int vecsize) override
    {
      std::lock_guard<std::mutex> lockGuard(m_viewer->mutex());

      auto& cb = m_viewer->cb();

      for (int i = vecsize - 1; i >= 0; --i) {
        cb.push_back({f0p[i], rms_speech[i]});
      }
    }

    MainWindow *m_viewer;

  };

  Foo* f0;

  if (std::string(argv[1]) == "q") {
    std::cout << "QT Audio" << std::endl;

    QAudioInput* audio = new QAudioInput(audioDeviceInfo, audioFormat);

    f0 = new Foo(audio->start(), audioFormat.sampleRate());

  } else if (std::string(argv[1]) == "p") {
    std::cout << "PulseAudio" << std::endl;

    pa_simple* s;
    pa_sample_spec ss;
    ss.format = PA_SAMPLE_S16LE;
    ss.channels = 1;
    ss.rate = 96000;
    s = pa_simple_new(NULL,         // Use the default server.
                      "swpitcher",  // Our application's name.
                      PA_STREAM_RECORD,
                      NULL,      // Use the default device.
                      "Record",  // Description of our stream.
                      &ss,       // Our sample format.
                      NULL,      // Use default channel map
                      NULL,      // Use default buffering attributes.
                      NULL       // Ignore error code.
                      );
    if (s == nullptr) {
      std::cerr << "Pulse failed." << std::endl;
    }

    f0 = new Foo(s);

  } else {
    return 1;
  }

  f0->init();

//
////////////////////////////////////////////////////////////////////////////////

  enum { SECONDS = 5 };

  MainWindow mainWindow(f0->pitchFrameRate() * SECONDS);
  mainWindow.show();

  f0->setViewer(&mainWindow);

  // Run on new thread
  std::thread inputThread(std::bind(&Foo::run, f0));

  return app.exec();
}
<|endoftext|>


<commit_before>/** \file
 *
 *  Copyright (c) 2012 by Travis Gockel. All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
 *  as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
 *  version.
 *
 *  \author Travis Gockel (travis@gockelhut.com)
**/
#include <json-voorhees/value.hpp>
#include <json-voorhees/array.hpp>
#include <json-voorhees/object.hpp>

#include "char_convert.hpp"
#include "detail.hpp"

#include <algorithm>
#include <cmath>
#include <cstring>
#include <ostream>
#include <sstream>

using namespace jsonv::detail;

namespace jsonv
{

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// kind_error                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

kind_error::kind_error(const std::string& description) :
        std::logic_error(description)
{ }

kind_error::~kind_error() throw()
{ }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// value                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

value::value() :
        _kind(kind::null)
{
    _data.object = nullptr;
}

value::value(std::nullptr_t) :
        value()
{ }

value::value(const std::string& val) :
        _kind(kind::null)
{
    _data.string = new string_impl;
    _kind = kind::string;
    _data.string->_string = val;
}

value::value(const char* val) :
        _kind(kind::null)
{
    _data.string = new string_impl;
    _kind = kind::string;
    _data.string->_string = val;
}

value::value(int64_t val) :
        _kind(kind::integer)
{
    _data.integer = val;
}

value::value(double val) :
        _kind(kind::decimal)
{
    _data.decimal = val;
}

value::value(bool val) :
        _kind(kind::boolean)
{
    _data.boolean = val;
}

value::value(const object& obj) :
        _kind(kind::null)
{
    _data.object = obj._data.object->clone();
    _kind = kind::object;
}

value::value(const array& arr) :
        _kind(kind::null)
{
    _data.array = arr._data.array->clone();
    _kind = kind::array;
}

#define JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_GENERATOR(type_)              \
    value::value(type_ val) :                                              \
            _kind(kind::integer)                                           \
    {                                                                      \
        _data.integer = val;                                               \
    }
JSON_VOORHEES_INTEGER_ALTERNATES_LIST(JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_GENERATOR)

value::~value()
{
    clear();
}

value& value::operator=(const value& other)
{
    clear();

    switch (other.get_kind())
    {
    case kind::object:
        _data.object = other._data.object->clone();
        break;
    case kind::array:
        _data.array = other._data.array->clone();
        break;
    case kind::string:
        _data.string = other._data.string->clone();
        break;
    case kind::integer:
        _data.integer = other._data.integer;
        break;
    case kind::decimal:
        _data.decimal = other._data.decimal;
        break;
    case kind::boolean:
        _data.boolean = other._data.boolean;
        break;
    case kind::null:
        break;
    }

    // it is important that we set our type AFTER we copy the data so we're in a consistent state if the copy throws
    _kind = other._kind;

    return *this;
}

value::value(const value& other) :
        _kind(kind::null)
{
    // just re-use assignment operator
    *this = other;
}

value::value(value&& other) :
        _data(other._data),
        _kind(other._kind)
{
    other._data.object = 0;
    other._kind = kind::null;
}

value& value::operator =(value&& source)
{
    clear();

    _data = source._data;
    _kind = source._kind;
    source._data.object = 0;
    source._kind = kind::null;

    return *this;
}

object value::make_object()
{
    return object();
}

array value::make_array()
{
    return array();
}

void value::clear()
{
    switch (_kind)
    {
    case kind::object:
        delete _data.object;
        break;
    case kind::array:
        delete _data.array;
        break;
    case kind::string:
        delete _data.string;
        break;
    case kind::integer:
    case kind::decimal:
    case kind::boolean:
    case kind::null:
        // do nothing
        break;
    }

    _kind = kind::null;
    _data.object = 0;
}

object& value::as_object()
{
    check_type(kind::object, _kind);
    return *reinterpret_cast<object*>(this);
}

const object& value::as_object() const
{
    check_type(kind::object, _kind);
    return *reinterpret_cast<const object*>(this);
}

array& value::as_array()
{
    check_type(kind::array, _kind);
    return *reinterpret_cast<array*>(this);
}

const array& value::as_array() const
{
    check_type(kind::array, _kind);
    return *reinterpret_cast<const array*>(this);
}

std::string& value::as_string()
{
    check_type(kind::string, _kind);
    return _data.string->_string;
}

const std::string& value::as_string() const
{
    check_type(kind::string, _kind);
    return _data.string->_string;
}

int64_t& value::as_integer()
{
    check_type(kind::integer, _kind);
    return _data.integer;
}

int64_t value::as_integer() const
{
    check_type(kind::integer, _kind);
    return _data.integer;
}

double& value::as_decimal()
{
    if (_kind == kind::integer)
        *this = double(as_integer());
    check_type(kind::decimal, _kind);
    return _data.decimal;
}

double value::as_decimal() const
{
    if (_kind == kind::integer)
        return double(as_integer());
    check_type(kind::decimal, _kind);
    return _data.decimal;
}

bool& value::as_boolean()
{
    check_type(kind::boolean, _kind);
    return _data.boolean;
}

bool value::as_boolean() const
{
    check_type(kind::boolean, _kind);
    return _data.boolean;
}

bool value::operator ==(const value& other) const
{
    if (this == &other && kind_valid(get_kind()))
        return true;
    if (get_kind() != other.get_kind())
        return false;

    switch (get_kind())
    {
    case kind::object:
        return as_object() == other.as_object();
    case kind::array:
        return as_array() == other.as_array();
    case kind::string:
        return as_string() == other.as_string();
    case kind::integer:
        return as_integer() == other.as_integer();
    case kind::decimal:
        return as_decimal() == other.as_decimal();
    case kind::boolean:
        return as_boolean() == other.as_boolean();
    case kind::null:
        return true;
    default:
        return false;
    }
}

bool value::operator !=(const value& other) const
{
    // must be first: an invalid type is not equal to itself
    if (!kind_valid(get_kind()))
        return true;

    if (this == &other)
        return false;
    if (get_kind() != other.get_kind())
        return true;

    switch (get_kind())
    {
    case kind::object:
        return as_object() != other.as_object();
    case kind::array:
        return as_array() != other.as_array();
    case kind::string:
        return as_string() != other.as_string();
    case kind::integer:
        return as_integer() != other.as_integer();
    case kind::decimal:
        return as_decimal() != other.as_decimal();
    case kind::boolean:
        return as_boolean() != other.as_boolean();
    case kind::null:
        return false;
    default:
        return true;
    }
}

static int kindval(kind k)
{
    switch (k)
    {
    case kind::null:
        return 0;
    case kind::boolean:
        return 1;
    case kind::integer:
    case kind::decimal:
        return 2;
    case kind::string:
        return 3;
    case kind::array:
        return 4;
    case kind::object:
        return 5;
    default:
        return -1;
    }
}

static int compare_kinds(kind a, kind b)
{
    int va = kindval(a);
    int vb = kindval(b);
    return va == vb ? 0 : va < vb ? -1 : 1;
}

int value::compare(const value& other) const
{
    if (this == &other)
        return 0;

    if (int kindcmp = compare_kinds(get_kind(), other.get_kind()))
        return kindcmp;

    switch (get_kind())
    {
    case kind::null:
        return 0;
    case kind::boolean:
        return as_boolean() == other.as_boolean() ? 0 : as_boolean() ? 1 : -1;
    case kind::integer:
        // other might be a decimal type, but if they are both integers, compare directly
        if (other.get_kind() == kind::integer)
            return as_integer() == other.as_integer() ? 0 : as_integer() < other.as_integer() ? -1 : 1;
    case kind::decimal:
        return as_decimal() == other.as_decimal() ? 0 : as_decimal() < other.as_decimal() ? -1 : 1;
    case kind::string:
        return as_string().compare(other.as_string());
    case kind::array:
    {
        const array& self = as_array();
        const array& oarr = other.as_array();
        array::const_iterator self_iter = self.begin();
        array::const_iterator othr_iter = oarr.begin();
        for (; self_iter != self.end() && othr_iter != oarr.end(); ++self_iter, ++othr_iter)
            if (int cmp = self_iter->compare(*othr_iter))
                return cmp;
        return self_iter == self.end() ? othr_iter == oarr.end() ? 0 : -1 : 1;
    }
    case kind::object:
    {
        const object& self = as_object();
        const object& oobj = other.as_object();
        object::const_iterator self_iter = self.begin();
        object::const_iterator othr_iter = oobj.begin();
        for (; self_iter != self.end() && othr_iter != oobj.end(); ++self_iter, ++othr_iter)
        {
            if (int cmp = self_iter->first.compare(othr_iter->first))
                return cmp;
            if (int cmp = self_iter->second.compare(othr_iter->second))
                return cmp;
        }
        return self_iter == self.end() ? othr_iter == oobj.end() ? 0 : -1 : 1;
    }
    default:
        return -1;
    }
}

bool value::operator< (const value& other) const
{
    return compare(other) == -1;
}

bool value::operator<=(const value& other) const
{
    return compare(other) != 1;
}

bool value::operator> (const value& other) const
{
    return compare(other) == 1;
}

bool value::operator>=(const value& other) const
{
    return compare(other) != -1;
}

std::ostream& operator <<(std::ostream& stream, const value& val)
{
    switch (val.get_kind())
    {
    case kind::object:
        return stream << val.as_object();
    case kind::array:
        return stream << val.as_array();
    case kind::string:
        return stream_escaped_string(stream, val.as_string());
    case kind::integer:
        return stream << val.as_integer();
    case kind::decimal:
        if (std::isnormal(val.as_decimal()))
            return stream << val.as_decimal();
        // not a number isn't a valid JSON value, so put it as null
        else
            return stream << "null";
    case kind::boolean:
        return stream << (val.as_boolean() ? "true" : "false");
    case kind::null:
    default:
        return stream << "null";
    }
}

}
<commit_msg>Issue #26: Forward value::value(const char* val) constructor to std::string.<commit_after>/** \file
 *
 *  Copyright (c) 2012 by Travis Gockel. All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
 *  as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
 *  version.
 *
 *  \author Travis Gockel (travis@gockelhut.com)
**/
#include <json-voorhees/value.hpp>
#include <json-voorhees/array.hpp>
#include <json-voorhees/object.hpp>

#include "char_convert.hpp"
#include "detail.hpp"

#include <algorithm>
#include <cmath>
#include <cstring>
#include <ostream>
#include <sstream>

using namespace jsonv::detail;

namespace jsonv
{

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// kind_error                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

kind_error::kind_error(const std::string& description) :
        std::logic_error(description)
{ }

kind_error::~kind_error() throw()
{ }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// value                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

value::value() :
        _kind(kind::null)
{
    _data.object = nullptr;
}

value::value(std::nullptr_t) :
        value()
{ }

value::value(const std::string& val) :
        _kind(kind::null)
{
    _data.string = new string_impl;
    _kind = kind::string;
    _data.string->_string = val;
}

value::value(const char* val) :
        value(std::string(val))
{ }

value::value(int64_t val) :
        _kind(kind::integer)
{
    _data.integer = val;
}

value::value(double val) :
        _kind(kind::decimal)
{
    _data.decimal = val;
}

value::value(bool val) :
        _kind(kind::boolean)
{
    _data.boolean = val;
}

value::value(const object& obj) :
        _kind(kind::null)
{
    _data.object = obj._data.object->clone();
    _kind = kind::object;
}

value::value(const array& arr) :
        _kind(kind::null)
{
    _data.array = arr._data.array->clone();
    _kind = kind::array;
}

#define JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_GENERATOR(type_)              \
    value::value(type_ val) :                                              \
            _kind(kind::integer)                                           \
    {                                                                      \
        _data.integer = val;                                               \
    }
JSON_VOORHEES_INTEGER_ALTERNATES_LIST(JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_GENERATOR)

value::~value()
{
    clear();
}

value& value::operator=(const value& other)
{
    clear();

    switch (other.get_kind())
    {
    case kind::object:
        _data.object = other._data.object->clone();
        break;
    case kind::array:
        _data.array = other._data.array->clone();
        break;
    case kind::string:
        _data.string = other._data.string->clone();
        break;
    case kind::integer:
        _data.integer = other._data.integer;
        break;
    case kind::decimal:
        _data.decimal = other._data.decimal;
        break;
    case kind::boolean:
        _data.boolean = other._data.boolean;
        break;
    case kind::null:
        break;
    }

    // it is important that we set our type AFTER we copy the data so we're in a consistent state if the copy throws
    _kind = other._kind;

    return *this;
}

value::value(const value& other) :
        _kind(kind::null)
{
    // just re-use assignment operator
    *this = other;
}

value::value(value&& other) :
        _data(other._data),
        _kind(other._kind)
{
    other._data.object = 0;
    other._kind = kind::null;
}

value& value::operator =(value&& source)
{
    clear();

    _data = source._data;
    _kind = source._kind;
    source._data.object = 0;
    source._kind = kind::null;

    return *this;
}

object value::make_object()
{
    return object();
}

array value::make_array()
{
    return array();
}

void value::clear()
{
    switch (_kind)
    {
    case kind::object:
        delete _data.object;
        break;
    case kind::array:
        delete _data.array;
        break;
    case kind::string:
        delete _data.string;
        break;
    case kind::integer:
    case kind::decimal:
    case kind::boolean:
    case kind::null:
        // do nothing
        break;
    }

    _kind = kind::null;
    _data.object = 0;
}

object& value::as_object()
{
    check_type(kind::object, _kind);
    return *reinterpret_cast<object*>(this);
}

const object& value::as_object() const
{
    check_type(kind::object, _kind);
    return *reinterpret_cast<const object*>(this);
}

array& value::as_array()
{
    check_type(kind::array, _kind);
    return *reinterpret_cast<array*>(this);
}

const array& value::as_array() const
{
    check_type(kind::array, _kind);
    return *reinterpret_cast<const array*>(this);
}

std::string& value::as_string()
{
    check_type(kind::string, _kind);
    return _data.string->_string;
}

const std::string& value::as_string() const
{
    check_type(kind::string, _kind);
    return _data.string->_string;
}

int64_t& value::as_integer()
{
    check_type(kind::integer, _kind);
    return _data.integer;
}

int64_t value::as_integer() const
{
    check_type(kind::integer, _kind);
    return _data.integer;
}

double& value::as_decimal()
{
    if (_kind == kind::integer)
        *this = double(as_integer());
    check_type(kind::decimal, _kind);
    return _data.decimal;
}

double value::as_decimal() const
{
    if (_kind == kind::integer)
        return double(as_integer());
    check_type(kind::decimal, _kind);
    return _data.decimal;
}

bool& value::as_boolean()
{
    check_type(kind::boolean, _kind);
    return _data.boolean;
}

bool value::as_boolean() const
{
    check_type(kind::boolean, _kind);
    return _data.boolean;
}

bool value::operator ==(const value& other) const
{
    if (this == &other && kind_valid(get_kind()))
        return true;
    if (get_kind() != other.get_kind())
        return false;

    switch (get_kind())
    {
    case kind::object:
        return as_object() == other.as_object();
    case kind::array:
        return as_array() == other.as_array();
    case kind::string:
        return as_string() == other.as_string();
    case kind::integer:
        return as_integer() == other.as_integer();
    case kind::decimal:
        return as_decimal() == other.as_decimal();
    case kind::boolean:
        return as_boolean() == other.as_boolean();
    case kind::null:
        return true;
    default:
        return false;
    }
}

bool value::operator !=(const value& other) const
{
    // must be first: an invalid type is not equal to itself
    if (!kind_valid(get_kind()))
        return true;

    if (this == &other)
        return false;
    if (get_kind() != other.get_kind())
        return true;

    switch (get_kind())
    {
    case kind::object:
        return as_object() != other.as_object();
    case kind::array:
        return as_array() != other.as_array();
    case kind::string:
        return as_string() != other.as_string();
    case kind::integer:
        return as_integer() != other.as_integer();
    case kind::decimal:
        return as_decimal() != other.as_decimal();
    case kind::boolean:
        return as_boolean() != other.as_boolean();
    case kind::null:
        return false;
    default:
        return true;
    }
}

static int kindval(kind k)
{
    switch (k)
    {
    case kind::null:
        return 0;
    case kind::boolean:
        return 1;
    case kind::integer:
    case kind::decimal:
        return 2;
    case kind::string:
        return 3;
    case kind::array:
        return 4;
    case kind::object:
        return 5;
    default:
        return -1;
    }
}

static int compare_kinds(kind a, kind b)
{
    int va = kindval(a);
    int vb = kindval(b);
    return va == vb ? 0 : va < vb ? -1 : 1;
}

int value::compare(const value& other) const
{
    if (this == &other)
        return 0;

    if (int kindcmp = compare_kinds(get_kind(), other.get_kind()))
        return kindcmp;

    switch (get_kind())
    {
    case kind::null:
        return 0;
    case kind::boolean:
        return as_boolean() == other.as_boolean() ? 0 : as_boolean() ? 1 : -1;
    case kind::integer:
        // other might be a decimal type, but if they are both integers, compare directly
        if (other.get_kind() == kind::integer)
            return as_integer() == other.as_integer() ? 0 : as_integer() < other.as_integer() ? -1 : 1;
    case kind::decimal:
        return as_decimal() == other.as_decimal() ? 0 : as_decimal() < other.as_decimal() ? -1 : 1;
    case kind::string:
        return as_string().compare(other.as_string());
    case kind::array:
    {
        const array& self = as_array();
        const array& oarr = other.as_array();
        array::const_iterator self_iter = self.begin();
        array::const_iterator othr_iter = oarr.begin();
        for (; self_iter != self.end() && othr_iter != oarr.end(); ++self_iter, ++othr_iter)
            if (int cmp = self_iter->compare(*othr_iter))
                return cmp;
        return self_iter == self.end() ? othr_iter == oarr.end() ? 0 : -1 : 1;
    }
    case kind::object:
    {
        const object& self = as_object();
        const object& oobj = other.as_object();
        object::const_iterator self_iter = self.begin();
        object::const_iterator othr_iter = oobj.begin();
        for (; self_iter != self.end() && othr_iter != oobj.end(); ++self_iter, ++othr_iter)
        {
            if (int cmp = self_iter->first.compare(othr_iter->first))
                return cmp;
            if (int cmp = self_iter->second.compare(othr_iter->second))
                return cmp;
        }
        return self_iter == self.end() ? othr_iter == oobj.end() ? 0 : -1 : 1;
    }
    default:
        return -1;
    }
}

bool value::operator< (const value& other) const
{
    return compare(other) == -1;
}

bool value::operator<=(const value& other) const
{
    return compare(other) != 1;
}

bool value::operator> (const value& other) const
{
    return compare(other) == 1;
}

bool value::operator>=(const value& other) const
{
    return compare(other) != -1;
}

std::ostream& operator <<(std::ostream& stream, const value& val)
{
    switch (val.get_kind())
    {
    case kind::object:
        return stream << val.as_object();
    case kind::array:
        return stream << val.as_array();
    case kind::string:
        return stream_escaped_string(stream, val.as_string());
    case kind::integer:
        return stream << val.as_integer();
    case kind::decimal:
        if (std::isnormal(val.as_decimal()))
            return stream << val.as_decimal();
        // not a number isn't a valid JSON value, so put it as null
        else
            return stream << "null";
    case kind::boolean:
        return stream << (val.as_boolean() ? "true" : "false");
    case kind::null:
    default:
        return stream << "null";
    }
}

}
<|endoftext|>


<commit_before>#include "PhaseSolver.h"
#include "Timer.h"

#include <iostream.h>
#include <fstream.h>
#include <time.h>
#include <stdlib.h>

void
usage()
{
    cerr << "Usage: llps [-d] [-f] [-I init] [-N norm] [-B branch] input-graph flow-output" << endl;
    cerr << "\t -d   dump the final disposition of each node" << endl;
    cerr << "\t -f   write the flow values for each arc" << endl;
    cerr << "\t -I   specify initialization function" << endl;
    cerr << "\t -B   specify strong bucket management" << endl;
    cerr << "\t -M   specify merger function" << endl;
    cerr << "\t -N   specify normalization method" << endl;
}

int
main(int argc, char** argv)
{
    Boolean dumpNodes = FALSE;
    Boolean writeFlow = FALSE;
    void (PhaseSolver::* initFunc)() = &PhaseSolver::buildSimpleTree;
    void (PhaseSolver::* solverFunc)(AddBranchPtr) = &PhaseSolver::solve;
    AddBranchPtr addBranchFunc = &PhaseSolver::addBranchLifo;
    PhaseSolver* solver = new PhaseSolver();

    // parse arguments
    int ch;
    while ((ch = getopt(argc, argv, "dfI:M:N:B:")) != EOF) {
	switch (ch) {
	case 'd':
	    dumpNodes = TRUE;
	    break;
	case 'f':
	    writeFlow = TRUE;
	    break;
	case 'I':
	    if (strcmp(optarg, "simple") == 0) {
		initFunc = &PhaseSolver::buildSimpleTree;
	    } else if (strcmp(optarg, "path") == 0) {
		initFunc = &PhaseSolver::buildBlockingPathTree;
	    } else if (strcmp(optarg, "saturate") == 0) {
		initFunc = &PhaseSolver::saturateAllArcs;
	    } else if (strcmp(optarg, "greedy") == 0) {
		initFunc = &PhaseSolver::buildGreedyPathTree;
	    } else {
		cerr << "Invalid initialization option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	case 'M':
	    if (strcmp(optarg, "simplex") == 0) {
		solver = new SimplexSolver();
	    } else if (strcmp(optarg, "normal") == 0) {
		solver = new PhaseSolver();
	    } else {
		cerr << "Invalid merge function option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	case 'N':
	    if (strcmp(optarg, "delayed") == 0) {
		solverFunc = &PhaseSolver::delayedNormalizeSolve;
	    } else if (strcmp(optarg, "normal") == 0) {
		solverFunc = &PhaseSolver::solve;
	    } else {
		cerr << "Invalid normalization option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	case 'B':
	    if (strcmp(optarg, "fifo") == 0) {
		addBranchFunc = &PhaseSolver::addBranchFifo;
	    } else if (strcmp(optarg, "lifo") == 0) {
		addBranchFunc = &PhaseSolver::addBranchLifo;
	    } else if (strcmp(optarg, "wave") == 0) {
		addBranchFunc = &PhaseSolver::addBranchWave;
	    } else {
		cerr << "Invalid branch-management option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	default:
	    usage();
	    return 1;
	}
    }

    argc -= optind;
    //argv += optind;

    if (argc != 2) {
	usage();
	return 1;
    }

    const char* instanceName = argv[optind];
    const char* outputName = argv[optind + 1];

    ofstream dout(outputName, ios::out);
    if (dout == nil) {
	cerr << "Unable to open output file: " << outputName << endl;
	return 1;
    }

    extern char* buildFlags;
    extern char* buildDate;
    dout << "c" << endl;
    dout << "c  instance: " << instanceName << endl;
    dout << "c  buildFlags: " << buildFlags << endl;
    dout << "c  buildDate: " << buildDate << endl;
    dout << "c  argv: ";
    for (char** ap = argv; *ap != nil; ap++) {
	dout << *ap << " ";
    }
    dout << endl;

    time_t beginTime = time(0);
    Timer initTimer;
    initTimer.start();
    Boolean readOK =  solver->readDimacsInstance(instanceName);
    initTimer.stop();

    if (readOK) {
	cout << "read problem instance OK" << endl;
	Timer totalTimer;
	totalTimer.start();

	// build initial tree
	Timer treeTimer;
	treeTimer.start();
	(solver->*initFunc)();
	treeTimer.stop();

	// solve
	Timer solveTimer;
	solveTimer.start();
	(solver->*solverFunc)(addBranchFunc);
	solveTimer.stop();

	if (dumpNodes) {
	    solver->dumpNodes(dout);
	}

	// convert to flow
	Timer convertTimer;
	convertTimer.start();
	solver->convertToFlow();
	convertTimer.stop();

	totalTimer.stop();

	cout << "time to establish tree: " << treeTimer << endl;
	cout << "done solving: " << solveTimer << endl;
	cout << "time to convert flow: " << convertTimer << endl;
	cout << "total time: " << totalTimer << endl;

	time_t endTime = time(0);
	dout << "c  beginRun: " << ctime(&beginTime);
	dout << "c  endRun: " << ctime(&endTime);

	dout << "c  timeToInitialize: " << initTimer << endl;
	dout << "c  timeToSolve: " << solveTimer << endl;
	dout << "c  timeToFlow: " << convertTimer << endl;
	dout << "c  totalTime: " << totalTimer << endl;

	solver->writeStats(dout);

	if (writeFlow) {
	    solver->writeDimacsFlow(dout);
	}
    }
    dout.close();

    return 0;
}
<commit_msg>Added option to select pre/post order searches<commit_after>#include "PhaseSolver.h"
#include "Timer.h"

#include <iostream.h>
#include <fstream.h>
#include <time.h>
#include <stdlib.h>

void
usage()
{
    cerr << "Usage: llps [-d] [-f] [-I init] [-N norm] [-B branch] input-graph flow-output" << endl;
    cerr << "\t -d   dump the final disposition of each node" << endl;
    cerr << "\t -f   write the flow values for each arc" << endl;
    cerr << "\t -I   specify initialization function" << endl;
    cerr << "\t -s   specify the number of splits for path init" << endl;
    cerr << "\t -B   specify strong bucket management" << endl;
    cerr << "\t -M   specify merger function" << endl;
    cerr << "\t -N   specify normalization method" << endl;
    cerr << "\t -O   specify pre or post order searches" << endl;
}

int
main(int argc, char** argv)
{
    Boolean dumpNodes = FALSE;
    Boolean writeFlow = FALSE;
    void (PhaseSolver::* initFunc)() = &PhaseSolver::buildSimpleTree;
    void (PhaseSolver::* solverFunc)(AddBranchPtr) = &PhaseSolver::solve;
    AddBranchPtr addBranchFunc = &PhaseSolver::addBranchLifo;
    PhaseSolver* solver = new PhaseSolver();
    int numSplits = -1;
    Boolean postOrder = TRUE;

    // parse arguments
    int ch;
    while ((ch = getopt(argc, argv, "dfI:s:M:N:B:O:")) != EOF) {
	switch (ch) {
	case 'd':
	    dumpNodes = TRUE;
	    break;
	case 'f':
	    writeFlow = TRUE;
	    break;
	case 'I':
	    if (strcmp(optarg, "simple") == 0) {
		initFunc = &PhaseSolver::buildSimpleTree;
	    } else if (strcmp(optarg, "path") == 0) {
		initFunc = &PhaseSolver::buildBlockingPathTree;
	    } else if (strcmp(optarg, "saturate") == 0) {
		initFunc = &PhaseSolver::saturateAllArcs;
	    } else if (strcmp(optarg, "greedy") == 0) {
		initFunc = &PhaseSolver::buildGreedyPathTree;
	    } else {
		cerr << "Invalid initialization option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	case 's':
	    numSplits = atoi(optarg);
	    break;

	case 'M':
	    if (strcmp(optarg, "simplex") == 0) {
		solver = new SimplexSolver();
	    } else if (strcmp(optarg, "normal") == 0) {
		solver = new PhaseSolver();
	    } else {
		cerr << "Invalid merge function option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	case 'N':
	    if (strcmp(optarg, "delayed") == 0) {
		solverFunc = &PhaseSolver::delayedNormalizeSolve;
	    } else if (strcmp(optarg, "normal") == 0) {
		solverFunc = &PhaseSolver::solve;
	    } else {
		cerr << "Invalid normalization option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	case 'B':
	    if (strcmp(optarg, "fifo") == 0) {
		addBranchFunc = &PhaseSolver::addBranchFifo;
	    } else if (strcmp(optarg, "lifo") == 0) {
		addBranchFunc = &PhaseSolver::addBranchLifo;
	    } else if (strcmp(optarg, "wave") == 0) {
		addBranchFunc = &PhaseSolver::addBranchWave;
	    } else {
		cerr << "Invalid branch-management option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	case 'O':
	    if (strcmp(optarg, "post") == 0) {
		postOrder = TRUE;
	    } else if (strcmp(optarg, "pre") == 0) {
		postOrder = FALSE;
	    } else {
		cerr << "Invalid pre/post order option " << optarg << endl;
		usage();
		return 1;
	    }
	    break;

	default:
	    usage();
	    return 1;
	}
    }

    argc -= optind;
    //argv += optind;

    if (argc != 2) {
	usage();
	return 1;
    }

    const char* instanceName = argv[optind];
    const char* outputName = argv[optind + 1];

    ofstream dout(outputName, ios::out);
    if (dout == nil) {
	cerr << "Unable to open output file: " << outputName << endl;
	return 1;
    }

    extern char* buildFlags;
    extern char* buildDate;
    dout << "c" << endl;
    dout << "c  instance: " << instanceName << endl;
    dout << "c  buildFlags: " << buildFlags << endl;
    dout << "c  buildDate: " << buildDate << endl;
    dout << "c  argv: ";
    for (char** ap = argv; *ap != nil; ap++) {
	dout << *ap << " ";
    }
    dout << endl;

    if (numSplits >= 0) {
	solver->maxSplits = numSplits;
    }
    solver->postOrderSearch = postOrder;

    time_t beginTime = time(0);
    Timer initTimer;
    initTimer.start();
    Boolean readOK =  solver->readDimacsInstance(instanceName);
    initTimer.stop();

    if (readOK) {
	cout << "read problem instance OK" << endl;
	Timer totalTimer;
	totalTimer.start();

	// build initial tree
	Timer treeTimer;
	treeTimer.start();
	(solver->*initFunc)();
	treeTimer.stop();

	// solve
	Timer solveTimer;
	solveTimer.start();
	(solver->*solverFunc)(addBranchFunc);
	solveTimer.stop();

	if (dumpNodes) {
	    solver->dumpNodes(dout);
	}

	// convert to flow
	Timer convertTimer;
	convertTimer.start();
	solver->convertToFlow();
	convertTimer.stop();

	totalTimer.stop();

	cout << "time to establish tree: " << treeTimer << endl;
	cout << "done solving: " << solveTimer << endl;
	cout << "time to convert flow: " << convertTimer << endl;
	cout << "total time: " << totalTimer << endl;

	time_t endTime = time(0);
	dout << "c  beginRun: " << ctime(&beginTime);
	dout << "c  endRun: " << ctime(&endTime);

	dout << "c  timeToInitialize: " << initTimer << endl;
	dout << "c  timeToSolve: " << solveTimer << endl;
	dout << "c  timeToFlow: " << convertTimer << endl;
	dout << "c  totalTime: " << totalTimer << endl;

	solver->writeStats(dout);

	if (writeFlow) {
	    solver->writeDimacsFlow(dout);
	}
    }
    dout.close();

    return 0;
}
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

#include "scene_subdiv_mesh.h"
#include "scene.h"
#include "subdiv/patch_eval.h"
#include "subdiv/patch_eval_simd.h"

namespace embree
{
  SubdivMeshAVX::SubdivMeshAVX(Scene* parent, RTCGeometryFlags flags, size_t numFaces, size_t numEdges, size_t numVertices,
                               size_t numCreases, size_t numCorners, size_t numHoles, size_t numTimeSteps)
                               : SubdivMesh(parent,flags,numFaces,numEdges,numVertices,numCreases,numCorners,numHoles,numTimeSteps) {}

  void SubdivMeshAVX::interpolate(unsigned primID, float u, float v, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, size_t numFloats)
  {
#if defined(DEBUG) // FIXME: use function pointers and also throw error in release mode
    if ((parent->aflags & RTC_INTERPOLATE) == 0)
      throw_RTCError(RTC_INVALID_OPERATION,"rtcInterpolate can only get called when RTC_INTERPOLATE is enabled for the scene");
#endif

    /* calculate base pointer and stride */
    assert((buffer >= RTC_VERTEX_BUFFER0 && buffer <= RTC_VERTEX_BUFFER1) ||
           (buffer >= RTC_USER_VERTEX_BUFFER0 && buffer <= RTC_USER_VERTEX_BUFFER1));
    const char* src = nullptr;
    size_t stride = 0;
    size_t bufID = buffer&0xFFFF;
    std::vector<SharedLazyTessellationCache::CacheEntry>* baseEntry = nullptr;
    if (buffer >= RTC_USER_VERTEX_BUFFER0) {
      src    = userbuffers[buffer&0xFFFF]->getPtr();
      stride = userbuffers[buffer&0xFFFF]->getStride();
      baseEntry = &user_buffer_tags[bufID];
    } else {
      src    = vertices[buffer&0xFFFF].getPtr();
      stride = vertices[buffer&0xFFFF].getStride();
      baseEntry = &vertex_buffer_tags[bufID];
    }

    auto alloc = [](size_t bytes) { return SharedLazyTessellationCache::malloc(bytes); };

    for (size_t i=0,slot=0; i<numFloats; slot++)
    {
      if (i+4 >= numFloats)
      {
        float4 Pt, dPdut, dPdvt;
        PatchEval<float4>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                getHalfEdge(primID),src+i*sizeof(float),stride,u,v,P ? &Pt : nullptr, dPdu ? &dPdut : nullptr, dPdv ? &dPdvt : nullptr);

        if (P   ) for (size_t j=i; j<min(i+4,numFloats); j++) P[j] = Pt[j-i];
        if (dPdu) for (size_t j=i; j<min(i+4,numFloats); j++) dPdu[j] = dPdut[j-i];
        if (dPdv) for (size_t j=i; j<min(i+4,numFloats); j++) dPdv[j] = dPdvt[j-i];
        i+=4;
      }
      else
      {
        float8 Pt, dPdut, dPdvt;
        PatchEval<float8>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                getHalfEdge(primID),src+i*sizeof(float),stride,u,v,P ? &Pt : nullptr, dPdu ? &dPdut : nullptr, dPdv ? &dPdvt : nullptr);

        if (P   ) for (size_t j=i; j<i+8; j++) P[j] = Pt[j-i];
        if (dPdu) for (size_t j=i; j<i+8; j++) dPdu[j] = dPdut[j-i];
        if (dPdv) for (size_t j=i; j<i+8; j++) dPdv[j] = dPdvt[j-i];
        i+=8;
      }
    }
    AVX_ZERO_UPPER();
  }

  void SubdivMeshAVX::interpolateN(const void* valid_i, const unsigned* primIDs, const float* u, const float* v, size_t numUVs,
                                   RTCBufferType buffer, float* P, float* dPdu, float* dPdv, size_t numFloats)
  {
#if defined(DEBUG) // FIXME: use function pointers and also throw error in release mode
    if ((parent->aflags & RTC_INTERPOLATE) == 0)
      throw_RTCError(RTC_INVALID_OPERATION,"rtcInterpolate can only get called when RTC_INTERPOLATE is enabled for the scene");
#endif

    /* calculate base pointer and stride */
    assert((buffer >= RTC_VERTEX_BUFFER0 && buffer <= RTC_VERTEX_BUFFER1) ||
           (buffer >= RTC_USER_VERTEX_BUFFER0 && buffer <= RTC_USER_VERTEX_BUFFER1));
    const char* src = nullptr;
    size_t stride = 0;
    size_t bufID = buffer&0xFFFF;
    std::vector<SharedLazyTessellationCache::CacheEntry>* baseEntry = nullptr;
    if (buffer >= RTC_USER_VERTEX_BUFFER0) {
      src    = userbuffers[bufID]->getPtr();
      stride = userbuffers[bufID]->getStride();
      baseEntry = &user_buffer_tags[bufID];
    } else {
      src    = vertices[bufID].getPtr();
      stride = vertices[bufID].getStride();
      baseEntry = &vertex_buffer_tags[bufID];
    }

    const int* valid = (const int*) valid_i;

    for (size_t i=0; i<numUVs;)
    {
      if (i+4 >= numUVs)
      {
        const size_t L = min(size_t(4),numUVs-i);
        bool4 valid1 = valid ? int4::loadu(&valid[i]) == int4(-1) : bool4(false);
        valid1 &= int4(i)+int4(step) < int4(numUVs);
        if (none(valid1)) continue;

        const int4 primID = int4::loadu(&primIDs[i]);
        const float4 uu = float4::loadu(&u[i]);
        const float4 vv = float4::loadu(&v[i]);

        foreach_unique(valid1,primID,[&](const bool4& valid1, const int primID)
        {
          for (size_t j=0,slot=0; j<numFloats; slot++)
          {
            if (j+4 >= numFloats)
            {
              const size_t M = min(size_t(4),numFloats-j);
              PatchEvalSimd<bool4,int4,float4,float4>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                            getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                            P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);

            j+=4;
            }
            else
            {
              const size_t M = min(size_t(8),numFloats-j);
              PatchEvalSimd<bool4,int4,float4,float8>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                            getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                            P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);

              j+=8;
            }
          }
        });
        i+=4;
      }
      else
      {
        const size_t L = min(size_t(8),numUVs-i);
        bool8 valid1 = valid ? int8::loadu(&valid[i]) == int8(-1) : bool8(false);
        valid1 &= int8(i)+int8(step) < int8(numUVs);
        if (none(valid1)) continue;

        const int8 primID = int8::loadu(&primIDs[i]);
        const float8 uu = float8::loadu(&u[i]);
        const float8 vv = float8::loadu(&v[i]);

        foreach_unique(valid1,primID,[&](const bool8& valid1, const int primID)
        {
          for (size_t j=0,slot=0; j<numFloats; slot++)
          {
            if (j+4 >= numFloats)
            {
              const size_t M = min(size_t(4),numFloats-j);
              PatchEvalSimd<bool8,int8,float8,float4>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                            getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                            P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);

            j+=4;
            }
            else
            {
              const size_t M = min(size_t(8),numFloats-j);
              PatchEvalSimd<bool8,int8,float8,float8>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                            getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                            P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);

              j+=8;
            }
          }
        });
        i+=8;
      }
    }
    AVX_ZERO_UPPER();
  }
}
<commit_msg>cleanups in scene_subdiv_mesh_avx<commit_after>// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

#include "scene_subdiv_mesh.h"
#include "scene.h"
#include "subdiv/patch_eval.h"
#include "subdiv/patch_eval_simd.h"

namespace embree
{
  SubdivMeshAVX::SubdivMeshAVX(Scene* parent, RTCGeometryFlags flags, size_t numFaces, size_t numEdges, size_t numVertices,
                               size_t numCreases, size_t numCorners, size_t numHoles, size_t numTimeSteps)
                               : SubdivMesh(parent,flags,numFaces,numEdges,numVertices,numCreases,numCorners,numHoles,numTimeSteps) {}

  void SubdivMeshAVX::interpolate(unsigned primID, float u, float v, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, size_t numFloats)
  {
#if defined(DEBUG) // FIXME: use function pointers and also throw error in release mode
    if ((parent->aflags & RTC_INTERPOLATE) == 0)
      throw_RTCError(RTC_INVALID_OPERATION,"rtcInterpolate can only get called when RTC_INTERPOLATE is enabled for the scene");
#endif

    /* calculate base pointer and stride */
    assert((buffer >= RTC_VERTEX_BUFFER0 && buffer <= RTC_VERTEX_BUFFER1) ||
           (buffer >= RTC_USER_VERTEX_BUFFER0 && buffer <= RTC_USER_VERTEX_BUFFER1));
    const char* src = nullptr;
    size_t stride = 0;
    size_t bufID = buffer&0xFFFF;
    std::vector<SharedLazyTessellationCache::CacheEntry>* baseEntry = nullptr;
    if (buffer >= RTC_USER_VERTEX_BUFFER0) {
      src    = userbuffers[buffer&0xFFFF]->getPtr();
      stride = userbuffers[buffer&0xFFFF]->getStride();
      baseEntry = &user_buffer_tags[bufID];
    } else {
      src    = vertices[buffer&0xFFFF].getPtr();
      stride = vertices[buffer&0xFFFF].getStride();
      baseEntry = &vertex_buffer_tags[bufID];
    }

    auto alloc = [](size_t bytes) { return SharedLazyTessellationCache::malloc(bytes); };

    for (size_t i=0,slot=0; i<numFloats; slot++)
    {
      if (i+4 >= numFloats)
      {
        float4 Pt, dPdut, dPdvt;
        PatchEval<float4>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                getHalfEdge(primID),src+i*sizeof(float),stride,u,v,P ? &Pt : nullptr, dPdu ? &dPdut : nullptr, dPdv ? &dPdvt : nullptr);

        if (P   ) for (size_t j=i; j<min(i+4,numFloats); j++) P[j] = Pt[j-i];
        if (dPdu) for (size_t j=i; j<min(i+4,numFloats); j++) dPdu[j] = dPdut[j-i];
        if (dPdv) for (size_t j=i; j<min(i+4,numFloats); j++) dPdv[j] = dPdvt[j-i];
        i+=4;
      }
      else
      {
        float8 Pt, dPdut, dPdvt;
        PatchEval<float8>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                getHalfEdge(primID),src+i*sizeof(float),stride,u,v,P ? &Pt : nullptr, dPdu ? &dPdut : nullptr, dPdv ? &dPdvt : nullptr);

        if (P   ) for (size_t j=i; j<i+8; j++) P[j] = Pt[j-i];
        if (dPdu) for (size_t j=i; j<i+8; j++) dPdu[j] = dPdut[j-i];
        if (dPdv) for (size_t j=i; j<i+8; j++) dPdv[j] = dPdvt[j-i];
        i+=8;
      }
    }
    AVX_ZERO_UPPER();
  }

  void SubdivMeshAVX::interpolateN(const void* valid_i, const unsigned* primIDs, const float* u, const float* v, size_t numUVs,
                                   RTCBufferType buffer, float* P, float* dPdu, float* dPdv, size_t numFloats)
  {
#if defined(DEBUG) // FIXME: use function pointers and also throw error in release mode
    if ((parent->aflags & RTC_INTERPOLATE) == 0)
      throw_RTCError(RTC_INVALID_OPERATION,"rtcInterpolate can only get called when RTC_INTERPOLATE is enabled for the scene");
#endif

    /* calculate base pointer and stride */
    assert((buffer >= RTC_VERTEX_BUFFER0 && buffer <= RTC_VERTEX_BUFFER1) ||
           (buffer >= RTC_USER_VERTEX_BUFFER0 && buffer <= RTC_USER_VERTEX_BUFFER1));
    const char* src = nullptr;
    size_t stride = 0;
    size_t bufID = buffer&0xFFFF;
    std::vector<SharedLazyTessellationCache::CacheEntry>* baseEntry = nullptr;
    if (buffer >= RTC_USER_VERTEX_BUFFER0) {
      src    = userbuffers[bufID]->getPtr();
      stride = userbuffers[bufID]->getStride();
      baseEntry = &user_buffer_tags[bufID];
    } else {
      src    = vertices[bufID].getPtr();
      stride = vertices[bufID].getStride();
      baseEntry = &vertex_buffer_tags[bufID];
    }

    const int* valid = (const int*) valid_i;

    for (size_t i=0; i<numUVs;)
    {
      if (i+4 >= numUVs)
      {
        const size_t L = min(size_t(4),numUVs-i);
        bool4 valid1 = valid ? int4::loadu(&valid[i]) == int4(-1) : bool4(false);
        valid1 &= int4(i)+int4(step) < int4(numUVs);
        if (none(valid1)) continue;

        const int4 primID = int4::loadu(&primIDs[i]);
        const float4 uu = float4::loadu(&u[i]);
        const float4 vv = float4::loadu(&v[i]);

        for (size_t j=0,slot=0; j<numFloats; slot++)
        {
          if (j+4 >= numFloats)
          {
            const size_t M = min(size_t(4),numFloats-j);
            foreach_unique(valid1,primID,[&](const bool4& valid1, const int primID) {
                PatchEvalSimd<bool4,int4,float4,float4>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                              getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                              P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);
              });

            j+=4;
          }
          else
          {
            const size_t M = min(size_t(8),numFloats-j);
            foreach_unique(valid1,primID,[&](const bool4& valid1, const int primID) {
                PatchEvalSimd<bool4,int4,float4,float8>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                              getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                              P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);
              });

            j+=8;
          }
        }
        i+=4;
      }
      else
      {
        const size_t L = min(size_t(8),numUVs-i);
        bool8 valid1 = valid ? int8::loadu(&valid[i]) == int8(-1) : bool8(false);
        valid1 &= int8(i)+int8(step) < int8(numUVs);
        if (none(valid1)) continue;

        const int8 primID = int8::loadu(&primIDs[i]);
        const float8 uu = float8::loadu(&u[i]);
        const float8 vv = float8::loadu(&v[i]);

        for (size_t j=0,slot=0; j<numFloats; slot++)
        {
          if (j+4 >= numFloats)
          {
            const size_t M = min(size_t(4),numFloats-j);
            foreach_unique(valid1,primID,[&](const bool8& valid1, const int primID) {
                PatchEvalSimd<bool8,int8,float8,float4>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                              getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                              P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);
              });

            j+=4;
          }
          else
          {
            const size_t M = min(size_t(8),numFloats-j);
            foreach_unique(valid1,primID,[&](const bool8& valid1, const int primID) {
                PatchEvalSimd<bool8,int8,float8,float8>::eval(baseEntry->at(interpolationSlot8(primID,slot,stride)),parent->commitCounter,
                                                              getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv,
                                                              P ? P+j*numUVs+i : nullptr,dPdu ? dPdu+j*numUVs+i : nullptr,dPdv ? dPdv+j*numUVs+i : nullptr,numUVs,M);
              });
            j+=8;
          }
        }
        i+=8;
      }
    }
    AVX_ZERO_UPPER();
  }
}
<|endoftext|>


<commit_before>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
    Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qimage.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qfile.h>
#include <qlabel.h>
#include <qtextedit.h>
#include <qvbox.h>

#include <dcopclient.h>
#include <dcopref.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kglobalsettings.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kurllabel.h>
#include <kdialogbase.h>
#include <kmessagebox.h>

#include "pilotDaemonDCOP_stub.h"

#include <ktextedit.h>

#include "summarywidget.h"

SummaryWidget::SummaryWidget( QWidget *parent, const char *name )
  : Kontact::Summary( parent, name ),
    DCOPObject( "KPilotSummaryWidget" ),
    mDCOPSuccess( false ),
    mStartedDaemon( false ),
    mShouldStopDaemon( true )
{
  mLayout = new QGridLayout( this, 2, 3, 3, 3 );

  int row=0;
  QPixmap icon = KGlobal::iconLoader()->loadIcon( "kpilot", KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "KPilot Information" ) );
  mLayout->addMultiCellWidget( header, row,row, 0,3 );

  // Last sync information
  row++;
  mSyncTimeTextLabel = new QLabel( i18n( "Last sync:" ), this);
  mLayout->addWidget( mSyncTimeTextLabel, row, 0 );
  mSyncTimeLabel = new QLabel( i18n( "No information available" ), this );
  mLayout->addWidget( mSyncTimeLabel, row, 1 );
  mShowSyncLogLabel = new KURLLabel( "", i18n( "[View Sync Log]" ), this );
  mLayout->addWidget( mShowSyncLogLabel, row, 3 );
  connect( mShowSyncLogLabel, SIGNAL( leftClickedURL( const QString& ) ),
    this, SLOT( showSyncLog( const QString& ) ) );

  // User
  row++;
  mPilotUserTextLabel = new QLabel( i18n( "User:" ), this);
  mLayout->addWidget( mPilotUserTextLabel, row, 0);
  mPilotUserLabel = new QLabel( i18n( "Unknown" ), this );
  mLayout->addMultiCellWidget( mPilotUserLabel, row, row, 1, 3 );

  // Device information
  row++;
  mPilotDeviceTextLabel = new QLabel( i18n( "Device:" ), this);
  mLayout->addWidget( mPilotDeviceTextLabel, row, 0 );
  mPilotDeviceLabel = new QLabel( i18n( "Unknown" ), this );
  mLayout->addMultiCellWidget( mPilotDeviceLabel, row, row, 1, 3 );

  // Status
  row++;
  mDaemonStatusTextLabel = new QLabel( i18n( "Status:" ), this);
  mLayout->addWidget( mDaemonStatusTextLabel, row, 0 );
  mDaemonStatusLabel = new QLabel( i18n( "No communication with the daemon possible" ), this );
  mLayout->addMultiCellWidget( mDaemonStatusLabel, row, row, 1, 3 );

  // Conduits:
  row++;
  mConduitsTextLabel = new QLabel( i18n( "Conduits:" ), this );
  mConduitsTextLabel->setAlignment( AlignAuto | AlignTop | ExpandTabs );
  mLayout->addWidget( mConduitsTextLabel, row, 0 );
  mConduitsLabel = new QLabel( i18n( "No information available" ), this );
  mConduitsLabel->setAlignment( mConduitsLabel->alignment() | Qt::WordBreak );
  mLayout->addMultiCellWidget( mConduitsLabel, row, row, 1, 3 );

  // widgets shown if kpilotDaemon is not running
  row++;
  mNoConnectionLabel = new QLabel( i18n( "KPilot is currently not running." ), this );
  mLayout->addMultiCellWidget( mNoConnectionLabel, row, row, 1, 2 );
  mNoConnectionStartLabel = new KURLLabel( "", i18n( "[Start KPilot]" ), this );
  mLayout->addWidget( mNoConnectionStartLabel, row, 3 );
  connect( mNoConnectionStartLabel, SIGNAL( leftClickedURL( const QString& ) ),
           this, SLOT( startKPilot() ) );

  if ( !kapp->dcopClient()->isApplicationRegistered( "kpilotDaemon" ) ) {
    startKPilot();
  }

  connectDCOPSignal( 0, 0, "kpilotDaemonStatusDetails(QDateTime,QString,QStringList,QString,QString,QString,bool)",
                     "receiveDaemonStatusDetails(QDateTime,QString,QStringList,QString,QString,QString,bool)", false );
	connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString & ) ), SLOT( slotAppRemoved( const QCString& ) ) );
}

SummaryWidget::~SummaryWidget()
{
  if ( mStartedDaemon && mShouldStopDaemon ) {
    PilotDaemonDCOP_stub dcopToDaemon( "kpilotDaemon", "KPilotDaemonIface" );
    dcopToDaemon.quitNow(); // ASYNC, always succeeds.
  }
}

QStringList SummaryWidget::configModules() const
{
  QStringList modules;
  modules << "kpilot_config.desktop";
  return modules;
}

void SummaryWidget::receiveDaemonStatusDetails(QDateTime lastSyncTime, QString status, QStringList conduits, QString logFileName, QString userName, QString pilotDevice, bool killOnExit )
{
  mDCOPSuccess = true;
  mLastSyncTime = lastSyncTime;
  mDaemonStatus = status;
  mConduits = conduits;
  mSyncLog = logFileName;
  mUserName = userName;
  mPilotDevice = pilotDevice;
  mShouldStopDaemon = killOnExit;
  updateView();
}

void SummaryWidget::updateView()
{
  if ( mDCOPSuccess ) {
    if ( mLastSyncTime.isValid() ) {
      mSyncTimeLabel->setText( mLastSyncTime.toString(Qt::LocalDate) );
    } else {
      mSyncTimeLabel->setText( i18n( "No information available" ) );
    }
    if ( !mSyncLog.isEmpty() ) {
      mShowSyncLogLabel->setEnabled( true );
      mShowSyncLogLabel->setURL( mSyncLog );
    } else {
      mShowSyncLogLabel->setEnabled( false );
    }
    mPilotUserLabel->setText( mUserName.isEmpty() ? i18n( "unknown" ) : mUserName );
    mPilotDeviceLabel->setText( mPilotDevice.isEmpty() ? i18n( "unknown" ) : mPilotDevice );
    mDaemonStatusLabel->setText( mDaemonStatus );
    mConduitsLabel->setText( mConduits.join( ", " ) );
  } else {
    mSyncTimeLabel->setText( i18n( "No information available (Daemon not running?)" ) );
    mShowSyncLogLabel->setEnabled( false );
    mPilotUserLabel->setText( i18n( "unknown" ) );
    mPilotDeviceLabel->setText( i18n( "unknown" ) );
    mDaemonStatusLabel->setText( i18n( "No communication with the daemon possible" ) );
    mConduitsLabel->setText( i18n( "No information available" ) );
  }

  mSyncTimeTextLabel->setShown( mDCOPSuccess );
  mSyncTimeLabel->setShown( mDCOPSuccess );
  mShowSyncLogLabel->setShown( mDCOPSuccess );
  mPilotUserTextLabel->setShown( mDCOPSuccess );
  mPilotUserLabel->setShown( mDCOPSuccess );
  mPilotDeviceTextLabel->setShown( mDCOPSuccess );
  mPilotDeviceLabel->setShown( mDCOPSuccess );
  mDaemonStatusTextLabel->setShown( mDCOPSuccess );
  mDaemonStatusLabel->setShown( mDCOPSuccess );
  mConduitsTextLabel->setShown( mDCOPSuccess );
  mConduitsLabel->setShown( mDCOPSuccess );
  mNoConnectionLabel->setShown( !mDCOPSuccess );
  mNoConnectionStartLabel->setShown( !mDCOPSuccess );
}

void SummaryWidget::showSyncLog( const QString &filename )
{
  KDialogBase dlg( this, 0, true, QString::null, KDialogBase::Ok, KDialogBase::Ok );
  dlg.setCaption( i18n( "KPilot HotSync Log" ) );

  QTextEdit *edit = new QTextEdit( dlg.makeVBoxMainWidget() );
  edit->setReadOnly( true );

  QFile f(filename);
  if ( !f.open( IO_ReadOnly ) ) {
    KMessageBox::error( this, i18n( "Unable to open Hotsync log %1." ).arg( filename ) );
    return;
  }

  QTextStream s( &f );
  while ( !s.eof() )
    edit->append( s.readLine() );

  edit->moveCursor( QTextEdit::MoveHome, false );

  f.close();

  dlg.setInitialSize( QSize( 400, 350 ) );
  dlg.exec();
}

void SummaryWidget::startKPilot()
{
  QString error;
  QCString appID;
  if ( !KApplication::kdeinitExec( "kpilotDaemon", QString( "--fail-silently" ) ) ) {
    kdDebug(5602) << "No service available..." << endl;
    mStartedDaemon = true;
  }
}

void SummaryWidget::slotAppRemoved( const QCString & appId )
{
  if ( appId == "kpilotDaemon" )
  {
    mDCOPSuccess = false;
    pdateView();
  }
}

#include "summarywidget.moc"

<commit_msg>corrected typo<commit_after>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
    Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qimage.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qfile.h>
#include <qlabel.h>
#include <qtextedit.h>
#include <qvbox.h>

#include <dcopclient.h>
#include <dcopref.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kglobalsettings.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kurllabel.h>
#include <kdialogbase.h>
#include <kmessagebox.h>

#include "pilotDaemonDCOP_stub.h"

#include <ktextedit.h>

#include "summarywidget.h"

SummaryWidget::SummaryWidget( QWidget *parent, const char *name )
  : Kontact::Summary( parent, name ),
    DCOPObject( "KPilotSummaryWidget" ),
    mDCOPSuccess( false ),
    mStartedDaemon( false ),
    mShouldStopDaemon( true )
{
  mLayout = new QGridLayout( this, 2, 3, 3, 3 );

  int row=0;
  QPixmap icon = KGlobal::iconLoader()->loadIcon( "kpilot", KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "KPilot Information" ) );
  mLayout->addMultiCellWidget( header, row,row, 0,3 );

  // Last sync information
  row++;
  mSyncTimeTextLabel = new QLabel( i18n( "Last sync:" ), this);
  mLayout->addWidget( mSyncTimeTextLabel, row, 0 );
  mSyncTimeLabel = new QLabel( i18n( "No information available" ), this );
  mLayout->addWidget( mSyncTimeLabel, row, 1 );
  mShowSyncLogLabel = new KURLLabel( "", i18n( "[View Sync Log]" ), this );
  mLayout->addWidget( mShowSyncLogLabel, row, 3 );
  connect( mShowSyncLogLabel, SIGNAL( leftClickedURL( const QString& ) ),
    this, SLOT( showSyncLog( const QString& ) ) );

  // User
  row++;
  mPilotUserTextLabel = new QLabel( i18n( "User:" ), this);
  mLayout->addWidget( mPilotUserTextLabel, row, 0);
  mPilotUserLabel = new QLabel( i18n( "Unknown" ), this );
  mLayout->addMultiCellWidget( mPilotUserLabel, row, row, 1, 3 );

  // Device information
  row++;
  mPilotDeviceTextLabel = new QLabel( i18n( "Device:" ), this);
  mLayout->addWidget( mPilotDeviceTextLabel, row, 0 );
  mPilotDeviceLabel = new QLabel( i18n( "Unknown" ), this );
  mLayout->addMultiCellWidget( mPilotDeviceLabel, row, row, 1, 3 );

  // Status
  row++;
  mDaemonStatusTextLabel = new QLabel( i18n( "Status:" ), this);
  mLayout->addWidget( mDaemonStatusTextLabel, row, 0 );
  mDaemonStatusLabel = new QLabel( i18n( "No communication with the daemon possible" ), this );
  mLayout->addMultiCellWidget( mDaemonStatusLabel, row, row, 1, 3 );

  // Conduits:
  row++;
  mConduitsTextLabel = new QLabel( i18n( "Conduits:" ), this );
  mConduitsTextLabel->setAlignment( AlignAuto | AlignTop | ExpandTabs );
  mLayout->addWidget( mConduitsTextLabel, row, 0 );
  mConduitsLabel = new QLabel( i18n( "No information available" ), this );
  mConduitsLabel->setAlignment( mConduitsLabel->alignment() | Qt::WordBreak );
  mLayout->addMultiCellWidget( mConduitsLabel, row, row, 1, 3 );

  // widgets shown if kpilotDaemon is not running
  row++;
  mNoConnectionLabel = new QLabel( i18n( "KPilot is currently not running." ), this );
  mLayout->addMultiCellWidget( mNoConnectionLabel, row, row, 1, 2 );
  mNoConnectionStartLabel = new KURLLabel( "", i18n( "[Start KPilot]" ), this );
  mLayout->addWidget( mNoConnectionStartLabel, row, 3 );
  connect( mNoConnectionStartLabel, SIGNAL( leftClickedURL( const QString& ) ),
           this, SLOT( startKPilot() ) );

  if ( !kapp->dcopClient()->isApplicationRegistered( "kpilotDaemon" ) ) {
    startKPilot();
  }

  connectDCOPSignal( 0, 0, "kpilotDaemonStatusDetails(QDateTime,QString,QStringList,QString,QString,QString,bool)",
                     "receiveDaemonStatusDetails(QDateTime,QString,QStringList,QString,QString,QString,bool)", false );
	connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString & ) ), SLOT( slotAppRemoved( const QCString& ) ) );
}

SummaryWidget::~SummaryWidget()
{
  if ( mStartedDaemon && mShouldStopDaemon ) {
    PilotDaemonDCOP_stub dcopToDaemon( "kpilotDaemon", "KPilotDaemonIface" );
    dcopToDaemon.quitNow(); // ASYNC, always succeeds.
  }
}

QStringList SummaryWidget::configModules() const
{
  QStringList modules;
  modules << "kpilot_config.desktop";
  return modules;
}

void SummaryWidget::receiveDaemonStatusDetails(QDateTime lastSyncTime, QString status, QStringList conduits, QString logFileName, QString userName, QString pilotDevice, bool killOnExit )
{
  mDCOPSuccess = true;
  mLastSyncTime = lastSyncTime;
  mDaemonStatus = status;
  mConduits = conduits;
  mSyncLog = logFileName;
  mUserName = userName;
  mPilotDevice = pilotDevice;
  mShouldStopDaemon = killOnExit;
  updateView();
}

void SummaryWidget::updateView()
{
  if ( mDCOPSuccess ) {
    if ( mLastSyncTime.isValid() ) {
      mSyncTimeLabel->setText( mLastSyncTime.toString(Qt::LocalDate) );
    } else {
      mSyncTimeLabel->setText( i18n( "No information available" ) );
    }
    if ( !mSyncLog.isEmpty() ) {
      mShowSyncLogLabel->setEnabled( true );
      mShowSyncLogLabel->setURL( mSyncLog );
    } else {
      mShowSyncLogLabel->setEnabled( false );
    }
    mPilotUserLabel->setText( mUserName.isEmpty() ? i18n( "unknown" ) : mUserName );
    mPilotDeviceLabel->setText( mPilotDevice.isEmpty() ? i18n( "unknown" ) : mPilotDevice );
    mDaemonStatusLabel->setText( mDaemonStatus );
    mConduitsLabel->setText( mConduits.join( ", " ) );
  } else {
    mSyncTimeLabel->setText( i18n( "No information available (Daemon not running?)" ) );
    mShowSyncLogLabel->setEnabled( false );
    mPilotUserLabel->setText( i18n( "unknown" ) );
    mPilotDeviceLabel->setText( i18n( "unknown" ) );
    mDaemonStatusLabel->setText( i18n( "No communication with the daemon possible" ) );
    mConduitsLabel->setText( i18n( "No information available" ) );
  }

  mSyncTimeTextLabel->setShown( mDCOPSuccess );
  mSyncTimeLabel->setShown( mDCOPSuccess );
  mShowSyncLogLabel->setShown( mDCOPSuccess );
  mPilotUserTextLabel->setShown( mDCOPSuccess );
  mPilotUserLabel->setShown( mDCOPSuccess );
  mPilotDeviceTextLabel->setShown( mDCOPSuccess );
  mPilotDeviceLabel->setShown( mDCOPSuccess );
  mDaemonStatusTextLabel->setShown( mDCOPSuccess );
  mDaemonStatusLabel->setShown( mDCOPSuccess );
  mConduitsTextLabel->setShown( mDCOPSuccess );
  mConduitsLabel->setShown( mDCOPSuccess );
  mNoConnectionLabel->setShown( !mDCOPSuccess );
  mNoConnectionStartLabel->setShown( !mDCOPSuccess );
}

void SummaryWidget::showSyncLog( const QString &filename )
{
  KDialogBase dlg( this, 0, true, QString::null, KDialogBase::Ok, KDialogBase::Ok );
  dlg.setCaption( i18n( "KPilot HotSync Log" ) );

  QTextEdit *edit = new QTextEdit( dlg.makeVBoxMainWidget() );
  edit->setReadOnly( true );

  QFile f(filename);
  if ( !f.open( IO_ReadOnly ) ) {
    KMessageBox::error( this, i18n( "Unable to open Hotsync log %1." ).arg( filename ) );
    return;
  }

  QTextStream s( &f );
  while ( !s.eof() )
    edit->append( s.readLine() );

  edit->moveCursor( QTextEdit::MoveHome, false );

  f.close();

  dlg.setInitialSize( QSize( 400, 350 ) );
  dlg.exec();
}

void SummaryWidget::startKPilot()
{
  QString error;
  QCString appID;
  if ( !KApplication::kdeinitExec( "kpilotDaemon", QString( "--fail-silently" ) ) ) {
    kdDebug(5602) << "No service available..." << endl;
    mStartedDaemon = true;
  }
}

void SummaryWidget::slotAppRemoved( const QCString & appId )
{
  if ( appId == "kpilotDaemon" )
  {
    mDCOPSuccess = false;
    updateView();
  }
}

#include "summarywidget.moc"

<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROISpot5.png}, {ROISpot5Moving.png}
//    OUTPUTS: {SIFTResampling.png}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example demonstrates the use of the
// \doxygen{otb}{KeyPointSetsMatchingFilter} for disparity map
// estimation. The idea here is to match SIFTs extracted from both the
// fixed and the moving images. The use of SIFTs is demonstrated in
// section \ref{sec:SIFTDetector}. The
// \doxygen{itk}{DeformationFieldSource} will be used
// to generate a deformation field by using
// interpolation on the deformation values from the point set. More
// advanced methods for deformation field interpolation are also
// available.
//
// The first step toward the use of these filters is to include the
// appropriate header files.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

#include "otbKeyPointSetsMatchingFilter.h"
#include "otbSiftFastImageFilter.h"
// Disabling deprecation warning if on visual
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
#endif
#include "itkDeformationFieldSource.h"
// Enabling remaining deprecation warning
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "itkWarpImageFilter.h"

// Software Guide : EndCodeSnippet

#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkPointSet.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbLeastSquareAffineTransformEstimator.h"
#include "itkResampleImageFilter.h"

int main (int argc, char* argv[])
{
  if (argc!= 4)
  {
    std::cerr <<"Usage: "<<argv[0];
    std::cerr<<"fixedFileName movingFileName resamplingImageFileName" << std::endl;
    return EXIT_FAILURE;
  }

  const unsigned int Dimension = 2;

  // Software Guide : BeginLatex
  //
  // Then we must decide what pixel type to use for the image. We choose to do
  // all the computations in floating point precision and rescale the results
  // between 0 and 255 in order to export PNG images.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef double        RealType;
  typedef unsigned char OutputPixelType;

  typedef otb::Image<RealType,Dimension> ImageType;
  typedef otb::Image<OutputPixelType,Dimension> OutputImageType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The SIFTs obtained for the matching will be stored in vector
  // form inside a point set. So we need the following types:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::VariableLengthVector<RealType> RealVectorType;
  typedef itk::PointSet<RealVectorType,Dimension> PointSetType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The filter for computing the SIFTs has a type defined as follows:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::SiftFastImageFilter<ImageType,PointSetType>
  ImageToSIFTKeyPointSetFilterType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // Although many choices for evaluating the distances during the
  // matching procedure exist, we choose here to use a simple
  // Euclidean distance. We can then define the type for the matching filter.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::Statistics::EuclideanDistance<RealVectorType> DistanceType;
  typedef otb::KeyPointSetsMatchingFilter<PointSetType, DistanceType>
  EuclideanDistanceMatchingFilterType;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The following types are needed for dealing with the matched points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef PointSetType::PointType PointType;
  typedef std::pair<PointType,PointType> MatchType;
  typedef std::vector<MatchType> MatchVectorType;
  typedef EuclideanDistanceMatchingFilterType::LandmarkListType
  LandmarkListType;

  typedef PointSetType::PointsContainer PointsContainerType;
  typedef PointsContainerType::Iterator PointsIteratorType;
  typedef PointSetType::PointDataContainer PointDataContainerType;
  typedef PointDataContainerType::Iterator PointDataIteratorType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We define the type for the image reader.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::ImageFileReader<ImageType> ReaderType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Two readers are instantiated : one for the fixed image, and one
  // for the moving image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ReaderType::Pointer fixedReader = ReaderType::New();
  ReaderType::Pointer movingReader = ReaderType::New();

  fixedReader->SetFileName(argv[1]);
  movingReader->SetFileName(argv[2]);
  fixedReader->UpdateOutputInformation();
  movingReader->UpdateOutputInformation();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We will now instantiate the 2 SIFT filters and the filter used
  // for the matching of the points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ImageToSIFTKeyPointSetFilterType::Pointer filter1 =
    ImageToSIFTKeyPointSetFilterType::New();
  ImageToSIFTKeyPointSetFilterType::Pointer filter2 =
    ImageToSIFTKeyPointSetFilterType::New();
  EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher =
    EuclideanDistanceMatchingFilterType::New();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We plug the pipeline and set the parameters.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  double secondOrderThreshold = 0.5;
  bool useBackMatching = 0;

  filter1->SetInput(0, fixedReader->GetOutput() );
  filter1->SetScalesNumber(3);
  filter2->SetInput(0, movingReader->GetOutput() );
  filter2->SetScalesNumber(3);

  euclideanMatcher->SetInput1(filter1->GetOutput());
  euclideanMatcher->SetInput2(filter2->GetOutput());
  euclideanMatcher->SetDistanceThreshold(secondOrderThreshold);
  euclideanMatcher->SetUseBackMatching(useBackMatching);
  euclideanMatcher->Update();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The matched points will be stored into a landmark list.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  LandmarkListType::Pointer landmarkList;
  landmarkList = euclideanMatcher->GetOutput();

  // Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Apply Mean square algorithm
  //
  // Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  //typedef itk::Point<float,3>                                 PointType;
  typedef otb::LeastSquareAffineTransformEstimator<PointType> EstimatorType;

  // instantiation
  EstimatorType::Pointer estimator = EstimatorType::New();

  for (LandmarkListType::Iterator it = landmarkList->Begin();
     it != landmarkList->End(); ++it)
  {
          estimator->AddTiePoints(it.Get()->GetPoint1(),it.Get()->GetPoint2());
  }

  // Trigger computation
  estimator->Compute();
  // meanSquarestimator->SetInput(euclideanMatcher->GetOutput());
// Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Resample the initial image with the transformation evaluated
  //
  // Software Guide : EndLatex
//  Software Guide : BeginLatex
  //
  //  It is common, as the last step of a registration task, to use
  //  the resulting transform to map the moving image into the fixed
  //  image space.  This is easily done with the
  //  \doxygen{itk}{ResampleImageFilter}. First, a ResampleImageFilter
  //  type is instantiated using the image types. It is convenient to
  //  use the fixed image type as the output type since it is likely
  //  that the transformed moving image will be compared with the
  //  fixed image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::ResampleImageFilter<
  ImageType,
  OutputImageType, EstimatorType::AffineTransformPointerType >    ResampleFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  A resampling filter is created and the moving image is connected as
  //  its input.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
  resampler->SetInput( fixedReader->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The Transform that is produced as output need to be inversed to
  //  We apply here the resampling algorithm to the "fixed" image
  // to produce the moving image. Or apply to the moving image
  //
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  // Get the output transform
  //EstimatorType::AffineTransformPointerType transform = estimator->GetAffineTransform();
  resampler->SetTransform( estimator->GetAffineTransform() );
  // Software Guide : EndCodeSnippet

  typedef otb::ImageFileWriter< OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput( resampler->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();

  return EXIT_SUCCESS;
}

<commit_msg>DOC: add example of afgine transformation estimation wird template float-double<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROISpot5.png}, {ROISpot5Moving.png}
//    OUTPUTS: {SIFTResampling.png}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example demonstrates the use of the
// \doxygen{otb}{KeyPointSetsMatchingFilter} for disparity map
// estimation. The idea here is to match SIFTs extracted from both the
// fixed and the moving images. The use of SIFTs is demonstrated in
// section \ref{sec:SIFTDetector}. The
// \doxygen{itk}{DeformationFieldSource} will be used
// to generate a deformation field by using
// interpolation on the deformation values from the point set. More
// advanced methods for deformation field interpolation are also
// available.
//
// The first step toward the use of these filters is to include the
// appropriate header files.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

#include "otbKeyPointSetsMatchingFilter.h"
#include "otbSiftFastImageFilter.h"
// Disabling deprecation warning if on visual
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
#endif
#include "itkDeformationFieldSource.h"
// Enabling remaining deprecation warning
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "itkWarpImageFilter.h"

// Software Guide : EndCodeSnippet

#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkPointSet.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbLeastSquareAffineTransformEstimator.h"
#include "itkResampleImageFilter.h"

int main (int argc, char* argv[])
{
  if (argc!= 4)
  {
    std::cerr <<"Usage: "<<argv[0];
    std::cerr<<"fixedFileName movingFileName resamplingImageFileName" << std::endl;
    return EXIT_FAILURE;
  }

  const unsigned int Dimension = 2;

  // Software Guide : BeginLatex
  //
  // Then we must decide what pixel type to use for the image. We choose to do
  // all the computations in floating point precision and rescale the results
  // between 0 and 255 in order to export PNG images.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef double        RealType;
//typedef float        RealType;
  typedef unsigned char OutputPixelType;

  typedef otb::Image<RealType,Dimension> ImageType;
  typedef otb::Image<OutputPixelType,Dimension> OutputImageType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The SIFTs obtained for the matching will be stored in vector
  // form inside a point set. So we need the following types:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::VariableLengthVector<RealType> RealVectorType;
  typedef itk::PointSet<RealVectorType,Dimension> PointSetType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The filter for computing the SIFTs has a type defined as follows:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::SiftFastImageFilter<ImageType,PointSetType>
  ImageToSIFTKeyPointSetFilterType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // Although many choices for evaluating the distances during the
  // matching procedure exist, we choose here to use a simple
  // Euclidean distance. We can then define the type for the matching filter.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::Statistics::EuclideanDistance<RealVectorType> DistanceType;
  typedef otb::KeyPointSetsMatchingFilter<PointSetType, DistanceType>
  EuclideanDistanceMatchingFilterType;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The following types are needed for dealing with the matched points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef PointSetType::PointType PointType;
  typedef std::pair<PointType,PointType> MatchType;
  typedef std::vector<MatchType> MatchVectorType;
  typedef EuclideanDistanceMatchingFilterType::LandmarkListType
  LandmarkListType;

  typedef PointSetType::PointsContainer PointsContainerType;
  typedef PointsContainerType::Iterator PointsIteratorType;
  typedef PointSetType::PointDataContainer PointDataContainerType;
  typedef PointDataContainerType::Iterator PointDataIteratorType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We define the type for the image reader.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::ImageFileReader<ImageType> ReaderType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Two readers are instantiated : one for the fixed image, and one
  // for the moving image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ReaderType::Pointer fixedReader = ReaderType::New();
  ReaderType::Pointer movingReader = ReaderType::New();

  fixedReader->SetFileName(argv[1]);
  movingReader->SetFileName(argv[2]);
  fixedReader->UpdateOutputInformation();
  movingReader->UpdateOutputInformation();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We will now instantiate the 2 SIFT filters and the filter used
  // for the matching of the points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ImageToSIFTKeyPointSetFilterType::Pointer filter1 =
    ImageToSIFTKeyPointSetFilterType::New();
  ImageToSIFTKeyPointSetFilterType::Pointer filter2 =
    ImageToSIFTKeyPointSetFilterType::New();
  EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher =
    EuclideanDistanceMatchingFilterType::New();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We plug the pipeline and set the parameters.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  double secondOrderThreshold = 0.5;
  bool useBackMatching = 0;

  filter1->SetInput(0, fixedReader->GetOutput() );
  filter1->SetScalesNumber(3);
  filter2->SetInput(0, movingReader->GetOutput() );
  filter2->SetScalesNumber(3);

  euclideanMatcher->SetInput1(filter1->GetOutput());
  euclideanMatcher->SetInput2(filter2->GetOutput());
  euclideanMatcher->SetDistanceThreshold(secondOrderThreshold);
  euclideanMatcher->SetUseBackMatching(useBackMatching);
  euclideanMatcher->Update();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The matched points will be stored into a landmark list.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  LandmarkListType::Pointer landmarkList;
  landmarkList = euclideanMatcher->GetOutput();

  // Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Apply Mean square algorithm
  //
  // Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  typedef itk::Point<double,2>                                 MyPointType;
  typedef otb::LeastSquareAffineTransformEstimator<MyPointType> EstimatorType;

  // instantiation
  EstimatorType::Pointer estimator = EstimatorType::New();

  for (LandmarkListType::Iterator it = landmarkList->Begin();
     it != landmarkList->End(); ++it)
  {
          estimator->AddTiePoints(it.Get()->GetPoint1(),it.Get()->GetPoint2());
  }

  // Trigger computation
  estimator->Compute();
  // meanSquarestimator->SetInput(euclideanMatcher->GetOutput());
// Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Resample the initial image with the transformation evaluated
  //
  // Software Guide : EndLatex
//  Software Guide : BeginLatex
  //
  //  It is common, as the last step of a registration task, to use
  //  the resulting transform to map the moving image into the fixed
  //  image space.  This is easily done with the
  //  \doxygen{itk}{ResampleImageFilter}. First, a ResampleImageFilter
  //  type is instantiated using the image types. It is convenient to
  //  use the fixed image type as the output type since it is likely
  //  that the transformed moving image will be compared with the
  //  fixed image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::ResampleImageFilter<
  ImageType,
  OutputImageType >    ResampleFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  A resampling filter is created and the moving image is connected as
  //  its input.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
  resampler->SetInput( movingReader->GetOutput() );

  //typedef itk::ImageRegistrationMethod<
  //ImageType,
  //ImageType >    RegistrationType;

  //RegistrationType::Pointer   registration  = RegistrationType::New();

  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The Transform that is produced as output need to be inversed to
  //  We apply here the resampling algorithm to the "fixed" image
  // to produce the moving image. Or apply to the moving image
  //
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  // Get the output transform
  //EstimatorType::AffineTransformPointerType transform = estimator->GetAffineTransform();
  resampler->SetTransform( estimator->GetAffineTransform() );
  resampler->SetSize( fixedReader->GetOutput()->GetLargestPossibleRegion().GetSize() );
  resampler->SetOutputOrigin( fixedReader->GetOutput()->GetOrigin() );
  resampler->SetOutputSpacing( fixedReader->GetOutput()->GetSpacing() );
  resampler->SetDefaultPixelValue( 100 );

  // Software Guide : EndCodeSnippet

  typedef otb::ImageFileWriter< OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput( resampler->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();

  return EXIT_SUCCESS;
}

<|endoftext|>