<commit_before>/*******************************************************************************
 * thrill/api/read_binary.hpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef THRILL_API_READ_BINARY_HEADER
#define THRILL_API_READ_BINARY_HEADER

#include <thrill/api/dia.hpp>
#include <thrill/api/dop_node.hpp>
#include <thrill/common/item_serialization_tools.hpp>
#include <thrill/common/logger.hpp>
#include <thrill/common/math.hpp>
#include <thrill/core/file_io.hpp>
#include <thrill/net/buffer_builder.hpp>

#include <algorithm>
#include <fcntl.h>
#include <fstream>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>

namespace thrill {
namespace api {

//! \addtogroup api Interface
//! \{

/*!
 * A DIANode which performs a line-based Read operation. Read reads a file from
 * the file system and emits it as a DIA.
 */
template <typename ValueType>
class ReadBinaryNode : public DOpNode<ValueType>
{
public:
    using Super = DOpNode<ValueType>;
    using Super::context_;
    using Super::result_file_;

    using FileSizePair = std::pair<std::string, size_t>;

    static const bool debug = false;

    /*!
     * Constructor for a ReadLinesNode. Sets the Context
     * and file path.
     *
     * \param ctx Reference to Context, which holds references to data and network.
     * \param filepath Path of the input file
     */
    ReadBinaryNode(Context& ctx,
                   const std::string& filepath,
                   StatsNode* stats_node)
        : Super(ctx, { }, "Read", stats_node),
          filepath_(filepath)
    {
        core::FileIO fio;
        filelist_ = fio.ReadFileList(filepath_).first;
        filesize_ = filelist_[context_.my_rank() + 1].second -
                    filelist_[context_.my_rank()].second;

        auto my_start_and_end =
            common::CalculateLocalRange(filelist_[filelist_.size() - 1].second,
                                        context_.num_workers(),
                                        context_.my_rank());

        size_t my_start = std::get<0>(my_start_and_end);
        size_t my_end = std::get<1>(my_start_and_end);
        size_t first_file = 0;
        size_t last_file = 0;

        while (filelist_[first_file + 1].second <= my_start) {
            first_file++;
            last_file++;
        }

        while (filelist_[last_file + 1].second <= my_end && last_file < filelist_.size() - 1) {
            last_file++;
        }

        auto start_iter = filelist_.begin() + first_file;
        auto end_iter = filelist_.begin() + last_file + 1;

        my_files_ = std::vector<FileSizePair>(start_iter, end_iter);
    }

    virtual ~ReadBinaryNode() { }

    //! Executes the read operation. Reads a file line by line
    //! and emmits it after applyung the read function.
    void Execute() final { }

    void PushData() final {
        static const bool debug = false;
        LOG << "READING data " << result_file_.ToString();

        bfr_.SetFileList(my_files_);

        // Hook Read
        while (bfr_.HasNext()) {
            auto item = data::Serialization<BinaryFileReader, ValueType>
                        ::Deserialize(bfr_);
            LOG << item;
            for (auto func : Super::callbacks_) {
                func(item);
            }
        }
        LOG << "DONE!";
    }

    void Dispose() final { }

    /*!
     * Produces an 'empty' function stack, which only contains the identity
     * emitter function.
     *
     * \return Empty function stack
     */
    auto ProduceStack() {
        return FunctionStack<ValueType>();
    }

    /*!
     * Returns "[ReadLinesNode]" as a string.
     * \return "[ReadLinesNode]"
     */
    std::string ToString() final {
        return "[ReadLinesNode] Id: " + result_file_.ToString();
    }

private:
    //! Path of the input file.
    std::string filepath_;

    std::streampos filesize_;

    std::vector<FileSizePair> filelist_;
    std::vector<FileSizePair> my_files_;

    class BinaryFileReader
        : public common::ItemReaderToolsBase<BinaryFileReader>
    {
    public:
        const size_t read_size = 2 * 1024 * 1024;

        BinaryFileReader() { }

        virtual ~BinaryFileReader() { }

        void CloseStream() {
            close(c_file_);
        }

        void SetFileList(std::vector<FileSizePair> path) {
            filelist_ = path;
            if (filelist_.size() > 1) {
                c_file_ = fio.OpenFile(filelist_[0].first);
                buffer_.Reserve(read_size);
                current_size_ = filelist_[1].second - filelist_[0].second;
            }
        }

        bool HasNext() {
            // no input files for this worker
            if (filelist_.size() <= 1) {
                return false;
            }

            if (buffer_.size() == current_) {
                buffer_.set_size(read(c_file_, buffer_.data(), read_size));
                current_ = 0;
                // buffer is empty when file is already finished
                //->go to next file if there is another one in filelist_
                if (buffer_.size()) {
                    return true;
                }
                else if (current_file_ < filelist_.size() - 2) {
                    close(c_file_);
                    current_file_++;
                    current_size_ = filelist_[current_file_ + 1].second - filelist_[current_file_].second;
                    c_file_ = fio.OpenFile(filelist_[current_file_].first);
                    return true;
                }
                else {
                    return false;
                }
            }
            else {
                return true;
            }
        }

        char GetByte() {
            if (current_ == buffer_.size()) {
                buffer_.set_size(read(c_file_, buffer_.data(), read_size));
                current_ = 0;
            }
            current_++;
            return buffer_[current_ - 1];
        }

        template <typename Type>
        Type Get() {
            if (buffer_.size() < current_ + sizeof(Type)) {
                // copy rest of buffer into start of next buffer
                std::copy(buffer_.begin() + current_,
                          buffer_.end(),
                          buffer_.data());
                size_t copied_bytes = buffer_.end() - buffer_.begin() - current_;

                buffer_.set_size(
                    read(c_file_,
                         buffer_.data() + copied_bytes,
                         read_size - copied_bytes) + copied_bytes);
                current_ = 0;
            }

            Type elemc;
            std::copy(buffer_.begin() + current_,
                      buffer_.begin() + current_ + sizeof(Type),
                      reinterpret_cast<char*>(&elemc));
            current_ += sizeof(Type);
            return elemc;
        }

    private:
        int c_file_;
        size_t current_ = 0;
        net::BufferBuilder buffer_;
        std::vector<FileSizePair> filelist_;
        std::streampos current_size_;
        size_t current_file_ = 0;
        core::FileIO fio;
    };

    BinaryFileReader bfr_;
};

/*!
 * ReadBinary is a DOp, which reads a file written by WriteBinary from the file
 * system and  creates an ordered DIA according to a given read function.
 *
 * \param ctx Reference to the context object
 * \param filepath Path of the file in the file system
 */
template <typename ValueType>
DIARef<ValueType> ReadBinary(Context& ctx, const std::string& filepath) {

    StatsNode* stats_node =
        ctx.stats_graph().AddNode("ReadBinary", NodeType::DOP);

    auto shared_node =
        std::make_shared<ReadBinaryNode<ValueType> >(
            ctx, filepath, stats_node);

    auto read_stack = shared_node->ProduceStack();

    return DIARef<ValueType, decltype(read_stack)>(
        shared_node, read_stack, { stats_node });
}

//! \}

} // namespace api
} // namespace thrill

#endif // !THRILL_API_READ_BINARY_HEADER

/******************************************************************************/
<commit_msg>Make ReadBinary work with repeated reads.<commit_after>/*******************************************************************************
 * thrill/api/read_binary.hpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Alexander Noe <aleexnoe@gmail.com>
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef THRILL_API_READ_BINARY_HEADER
#define THRILL_API_READ_BINARY_HEADER

#include <thrill/api/dia.hpp>
#include <thrill/api/dop_node.hpp>
#include <thrill/common/item_serialization_tools.hpp>
#include <thrill/common/logger.hpp>
#include <thrill/common/math.hpp>
#include <thrill/core/file_io.hpp>
#include <thrill/net/buffer_builder.hpp>

#include <algorithm>
#include <fcntl.h>
#include <fstream>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>

namespace thrill {
namespace api {

//! \addtogroup api Interface
//! \{

/*!
 * A DIANode which performs a line-based Read operation. Read reads a file from
 * the file system and emits it as a DIA.
 */
template <typename ValueType>
class ReadBinaryNode : public DOpNode<ValueType>
{
public:
    using Super = DOpNode<ValueType>;
    using Super::context_;
    using Super::result_file_;

    using FileSizePair = std::pair<std::string, size_t>;

    static const bool debug = false;

    /*!
     * Constructor for a ReadLinesNode. Sets the Context
     * and file path.
     *
     * \param ctx Reference to Context, which holds references to data and network.
     * \param filepath Path of the input file
     */
    ReadBinaryNode(Context& ctx,
                   const std::string& filepath,
                   StatsNode* stats_node)
        : Super(ctx, { }, "ReadBinary", stats_node),
          filepath_(filepath)
    {
        core::FileIO fio;
        filelist_ = fio.ReadFileList(filepath_).first;
        filesize_ = filelist_[context_.my_rank() + 1].second -
                    filelist_[context_.my_rank()].second;

        auto my_start_and_end =
            common::CalculateLocalRange(filelist_[filelist_.size() - 1].second,
                                        context_.num_workers(),
                                        context_.my_rank());

        size_t my_start = std::get<0>(my_start_and_end);
        size_t my_end = std::get<1>(my_start_and_end);
        size_t first_file = 0;
        size_t last_file = 0;

        while (filelist_[first_file + 1].second <= my_start) {
            first_file++;
            last_file++;
        }

        while (filelist_[last_file + 1].second <= my_end && last_file < filelist_.size() - 1) {
            last_file++;
        }

        auto start_iter = filelist_.begin() + first_file;
        auto end_iter = filelist_.begin() + last_file + 1;

        my_files_ = std::vector<FileSizePair>(start_iter, end_iter);
    }

    virtual ~ReadBinaryNode() { }

    //! Executes the read operation. Reads a file line by line
    //! and emmits it after applyung the read function.
    void Execute() final { }

    void PushData() final {
        static const bool debug = false;
        LOG << "READING data " << result_file_.ToString();

        BinaryFileReader bfr_;
        bfr_.SetFileList(my_files_);

        // Hook Read
        while (bfr_.HasNext()) {
            auto item = data::Serialization<BinaryFileReader, ValueType>
                        ::Deserialize(bfr_);
            LOG << item;
            for (auto func : Super::callbacks_) {
                func(item);
            }
        }
        LOG << "DONE!";
    }

    void Dispose() final { }

    /*!
     * Produces an 'empty' function stack, which only contains the identity
     * emitter function.
     *
     * \return Empty function stack
     */
    auto ProduceStack() {
        return FunctionStack<ValueType>();
    }

    /*!
     * Returns "[ReadLinesNode]" as a string.
     * \return "[ReadLinesNode]"
     */
    std::string ToString() final {
        return "[ReadBinaryNode] Id: " + result_file_.ToString();
    }

private:
    //! Path of the input file.
    std::string filepath_;

    std::streampos filesize_;

    std::vector<FileSizePair> filelist_;
    std::vector<FileSizePair> my_files_;

    class BinaryFileReader
        : public common::ItemReaderToolsBase<BinaryFileReader>
    {
    public:
        const size_t read_size = 2 * 1024 * 1024;

        BinaryFileReader() { }

        virtual ~BinaryFileReader() { }

        void CloseStream() {
            close(c_file_);
        }

        void SetFileList(std::vector<FileSizePair> path) {
            filelist_ = path;
            if (filelist_.size() > 1) {
                c_file_ = fio.OpenFile(filelist_[0].first);
                buffer_.Reserve(read_size);
                current_size_ = filelist_[1].second - filelist_[0].second;
            }
        }

        bool HasNext() {
            // no input files for this worker
            if (filelist_.size() <= 1) {
                return false;
            }

            if (buffer_.size() == current_) {
                buffer_.set_size(read(c_file_, buffer_.data(), read_size));
                current_ = 0;
                // buffer is empty when file is already finished
                //->go to next file if there is another one in filelist_
                if (buffer_.size()) {
                    return true;
                }
                else if (current_file_ < filelist_.size() - 2) {
                    close(c_file_);
                    current_file_++;
                    current_size_ = filelist_[current_file_ + 1].second - filelist_[current_file_].second;
                    c_file_ = fio.OpenFile(filelist_[current_file_].first);
                    return true;
                }
                else {
                    return false;
                }
            }
            else {
                return true;
            }
        }

        char GetByte() {
            if (current_ == buffer_.size()) {
                buffer_.set_size(read(c_file_, buffer_.data(), read_size));
                current_ = 0;
            }
            current_++;
            return buffer_[current_ - 1];
        }

        template <typename Type>
        Type Get() {
            if (buffer_.size() < current_ + sizeof(Type)) {
                // copy rest of buffer into start of next buffer
                std::copy(buffer_.begin() + current_,
                          buffer_.end(),
                          buffer_.data());
                size_t copied_bytes = buffer_.end() - buffer_.begin() - current_;

                buffer_.set_size(
                    read(c_file_,
                         buffer_.data() + copied_bytes,
                         read_size - copied_bytes) + copied_bytes);
                current_ = 0;
            }

            Type elemc;
            std::copy(buffer_.begin() + current_,
                      buffer_.begin() + current_ + sizeof(Type),
                      reinterpret_cast<char*>(&elemc));
            current_ += sizeof(Type);
            return elemc;
        }

    private:
        int c_file_;
        size_t current_ = 0;
        net::BufferBuilder buffer_;
        std::vector<FileSizePair> filelist_;
        std::streampos current_size_;
        size_t current_file_ = 0;
        core::FileIO fio;
    };
};

/*!
 * ReadBinary is a DOp, which reads a file written by WriteBinary from the file
 * system and  creates an ordered DIA according to a given read function.
 *
 * \param ctx Reference to the context object
 * \param filepath Path of the file in the file system
 */
template <typename ValueType>
DIARef<ValueType> ReadBinary(Context& ctx, const std::string& filepath) {

    StatsNode* stats_node =
        ctx.stats_graph().AddNode("ReadBinary", NodeType::DOP);

    auto shared_node =
        std::make_shared<ReadBinaryNode<ValueType> >(
            ctx, filepath, stats_node);

    auto read_stack = shared_node->ProduceStack();

    return DIARef<ValueType, decltype(read_stack)>(
        shared_node, read_stack, { stats_node });
}

//! \}

} // namespace api
} // namespace thrill

#endif // !THRILL_API_READ_BINARY_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "ApplyIMUToState.h"
#include "AngVelTools.h"
#include "SpaceTransformations.h"

// Library/third-party includes
#include <osvr/Kalman/AbsoluteOrientationMeasurement.h>
#include <osvr/Kalman/AngularVelocityMeasurement.h>
#include <osvr/Kalman/FlexibleKalmanFilter.h>
#include <osvr/Util/EigenExtras.h>
#include <osvr/Util/EigenQuatExponentialMap.h>
#include <util/Stride.h>

// Standard includes
#include <iostream>

namespace osvr {

namespace kalman {
#define OSVR_Q_LAST
    /// The measurement here has been split into a base and derived type, so
    /// that the derived type only contains the little bit that depends on a
    /// particular state type.
    class IMUOrientationMeasBase {
      public:
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
        static const types::DimensionType DIMENSION = 3;
        using MeasurementVector = types::Vector<DIMENSION>;
        using MeasurementSquareMatrix = types::SquareMatrix<DIMENSION>;
        static Eigen::Quaterniond
        computeEffectiveIMUToCam(Eigen::Quaterniond const &cameraPose,
                                 util::Angle yawCorrection) {
            return Eigen::Quaterniond(
                Eigen::AngleAxisd(util::getRadians(yawCorrection),
                                  Eigen::Vector3d::UnitY()) *
                cameraPose);
        }
        IMUOrientationMeasBase(Eigen::Quaterniond const &cameraPose,
                               util::Angle yawCorrection,
                               Eigen::Quaterniond const &quat,
                               types::Vector<3> const &emVariance)
            : m_iRc(computeEffectiveIMUToCam(cameraPose, yawCorrection)),
              m_cRi(m_iRc.inverse()), m_quat(quat),
              m_covariance(emVariance.asDiagonal()) {}

        template <typename State>
        MeasurementSquareMatrix const &getCovariance(State const &) {
            return m_covariance;
        }
        /// convenience function for shared implementation between getResidual
        /// and getJacobianBlock
        Eigen::Quaterniond
        getInnovationQuat(Eigen::Quaterniond const &cRb) const {
/// m_quat is iRbm - the body (measured) frame
/// cRb is "current" (predicted) state - body in camera space
#ifdef OSVR_Q_LAST
            return cRb.inverse() * m_cRi * m_quat;
#else
            return util::flipQuatSignToMatch(cRb, m_quat.conjugate() * m_iRc) *
                   cRb;
#endif
        }

        /// Gets the measurement residual, also known as innovation: predicts
        /// the measurement from the predicted state, and returns the
        /// difference.
        ///
        /// State type doesn't matter as long as we can
        /// `.getCombinedQuaternion()`
        template <typename State>
        MeasurementVector getResidual(State const &s) const {
#if 0
            const Eigen::Quaterniond predictionInIMUSpace =
                m_iRc * s.getCombinedQuaternion();

            const Eigen::Quaterniond residualqInIMUSpace = m_quat * predictionInIMUSpace.inverse();
			const Eigen::Quaterniond residualqInCamSpace = m_cRi * residualqInIMUSpace;
#else

            const Eigen::Quaterniond residualq =
                getInnovationQuat(s.getCombinedQuaternion());
#endif
            // Two equivalent quaternions: but their logs are typically
            // different: one is the "short way" and the other is the "long
            // way". We'll compute both and pick the "short way".
            MeasurementVector residual = util::quat_ln(residualq);
            MeasurementVector equivResidual =
                util::quat_ln(Eigen::Quaterniond(-(residualq.coeffs())));
#ifdef OSVR_FLIP_QUATS
            return residual.squaredNorm() < equivResidual.squaredNorm()
                       ? residual
                       : equivResidual;
#else
            return residual;
#endif
        }
        /// Convenience method to be able to store and re-use measurements.
        void setMeasurement(Eigen::Quaterniond const &quat) { m_quat = quat; }

        /// Get the block of jacobian that is non-zero: your subclass will have
        /// to put it where it belongs for each particular state type.
        template <typename State>
        types::Matrix<DIMENSION, 3> getJacobianBlock(State const &s) const {
            /// Compute the innovation quat again.
            Eigen::Quaterniond q = getInnovationQuat(s.getCombinedQuaternion());
            /// pre-compute the manually-extracted subexpressions.
            Eigen::Vector3d q2(q.vec().cwiseProduct(q.vec()));
            auto qvecnorm = std::sqrt(q2.sum());
/// codegen follows
#ifdef OSVR_Q_LAST
            // Quat.QuatToRotVec(g(x) * q)
            auto tmp0 = (1. / 2.) / qvecnorm;
            auto tmp1 = -q.w() * tmp0;
            auto tmp2 = std::pow(qvecnorm, -3);
            auto tmp3 = (1. / 2.) * q.w() * tmp2;
            auto tmp4 = q.z() * tmp0;
            auto tmp5 = (1. / 2.) * q.w() * q.x() * tmp2;
            auto tmp6 = q.y() * tmp5;
            auto tmp7 = q.y() * tmp0;
            auto tmp8 = q.z() * tmp5;
            auto tmp9 = q.x() * tmp0;
            auto tmp10 = q.y() * q.z() * tmp3;
            Eigen::Matrix3d ret;
            ret << q2.x() * tmp3 + tmp1, -tmp4 + tmp6, tmp7 + tmp8, tmp4 + tmp6,
                q2.y() * tmp3 + tmp1, tmp10 - tmp9, -tmp7 + tmp8, tmp10 + tmp9,
                q2.z() * tmp3 + tmp1;
#else
            // Quat.QuatToRotVec(q * g(x))
            auto tmp0 = (1. / 2.) / qvecnorm;
            auto tmp1 = -q.w() * tmp0;
            auto tmp2 = std::pow(qvecnorm, -3);
            auto tmp3 = (1. / 2.) * q.w() * tmp2;
            auto tmp4 = q.z() * tmp0;
            auto tmp5 = (1. / 2.) * q.w() * q.x() * tmp2;
            auto tmp6 = q.y() * tmp5;
            auto tmp7 = q.y() * tmp0;
            auto tmp8 = q.z() * tmp5;
            auto tmp9 = q.x() * tmp0;
            auto tmp10 = q.y() * q.z() * tmp3;
            Eigen::Matrix3d ret;
            ret << q2.x() * tmp3 + tmp1, tmp4 + tmp6, -tmp7 + tmp8,
                -tmp4 + tmp6, q2.y() * tmp3 + tmp1, tmp10 + tmp9, tmp7 + tmp8,
                tmp10 - tmp9, q2.z() * tmp3 + tmp1;
#endif
            static bool printedJacobian = false;
            if (!printedJacobian) {
                printedJacobian = true;
                std::cout << ret << std::endl;
            }
            return ret;
        }

      private:
        Eigen::Quaterniond m_iRc;
        Eigen::Quaterniond m_cRi;
        Eigen::Quaterniond m_quat;
        MeasurementSquareMatrix m_covariance;
    };

    /// This is the subclass of AbsoluteOrientationBase: only explicit
    /// specializations, and on state types.
    template <typename StateType> class IMUOrientationMeasurement;

    /// AbsoluteOrientationMeasurement with a pose_externalized_rotation::State
    template <>
    class IMUOrientationMeasurement<pose_externalized_rotation::State>
        : public IMUOrientationMeasBase {
      public:
        using State = pose_externalized_rotation::State;
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
        static const types::DimensionType STATE_DIMENSION =
            types::Dimension<State>::value;
        using Base = IMUOrientationMeasBase;

        IMUOrientationMeasurement(Eigen::Quaterniond const &cameraPose,
                                  util::Angle yawCorrection,
                                  Eigen::Quaterniond const &quat,
                                  types::Vector<3> const &emVariance)
            : Base(cameraPose, yawCorrection, quat, emVariance) {}

        types::Matrix<DIMENSION, STATE_DIMENSION>
        getJacobian(State const &s) const {
            using namespace pose_externalized_rotation;
            using Jacobian = types::Matrix<DIMENSION, STATE_DIMENSION>;
            Jacobian ret = Jacobian::Zero();
            ret.block<DIMENSION, 3>(0, 3) = Base::getJacobianBlock(s);
            return ret;
        }
    };
} // namespace kalman
namespace vbtracker {
    inline void applyOriToState(TrackingSystem const &sys, BodyState &state,
                                BodyProcessModel &processModel,
                                CannedIMUMeasurement const &meas) {
        Eigen::Quaterniond quat;
        meas.restoreQuat(quat);
        Eigen::Vector3d var;
        meas.restoreQuatVariance(var);
        util::Angle yawCorrection = meas.getYawCorrection();

        /// Measurement class will rotate it into camera space
        /// @todo do this without rotating into camera space?

        /// @todo transform variance?

        kalman::IMUOrientationMeasurement<BodyState> kalmanMeas{
            getCameraRotation(sys), yawCorrection, quat, var};
#if 0
        {
            static ::util::Stride s(201);
            if (++s) {
                Eigen::AngleAxisd pred(state.getCombinedQuaternion());
                Eigen::AngleAxisd meas(quat);
                std::cout << "Predicted: " << pred.angle() << " about "
                          << pred.axis().transpose() << "\n";
                std::cout << "Measured: " << meas.angle() << " about "
                          << meas.axis().transpose() << "\n";
                std::cout << "Residual: "
                          << kalmanMeas.getResidual(state).transpose() << "\n";
            }
        }
#endif
        auto correctionInProgress =
            kalman::beginCorrection(state, processModel, kalmanMeas);
        auto outputMeas = [&] {
            std::cout << "state: " << state.getQuaternion().coeffs().transpose()
                      << " and measurement: " << quat.coeffs().transpose();
        };
        if (!correctionInProgress.stateCorrectionFinite) {
            std::cout
                << "Non-finite state correction in applying orientation: ";
            outputMeas();
            std::cout << "\n";
            return;
        }
        if (!correctionInProgress.finishCorrection(true)) {
            std::cout
                << "Non-finite error covariance after applying orientation: ";
            outputMeas();
            std::cout << "\n";
        }
    }

    inline void applyAngVelToState(TrackingSystem const &sys, BodyState &state,
                                   BodyProcessModel &processModel,
                                   CannedIMUMeasurement const &meas) {

        Eigen::Vector3d angVel;
        meas.restoreAngVel(angVel);
        Eigen::Vector3d var;
        meas.restoreAngVelVariance(var);
        static const double dt = 0.02;
        /// Rotate it into camera space - it's bTb and we want cTc
        /// @todo do this without rotating into camera space?
        Eigen::Quaterniond cTb = state.getQuaternion();
        // Eigen::Matrix3d bTc(state.getQuaternion().conjugate());
        /// Turn it into an incremental quat to do the space transformation
        Eigen::Quaterniond incrementalQuat =
            cTb * angVelVecToIncRot(angVel, dt) * cTb.conjugate();
        /// Then turn it back into an angular velocity vector
        angVel = incRotToAngVelVec(incrementalQuat, dt);
        // angVel = (getRotationMatrixToCameraSpace(sys) * angVel).eval();
        /// @todo transform variance?

        kalman::AngularVelocityMeasurement<BodyState> kalmanMeas{angVel, var};
        kalman::correct(state, processModel, kalmanMeas);
    }

    void applyIMUToState(TrackingSystem const &sys,
                         util::time::TimeValue const &initialTime,
                         BodyState &state, BodyProcessModel &processModel,
                         util::time::TimeValue const &newTime,
                         CannedIMUMeasurement const &meas) {
        if (newTime != initialTime) {
            auto dt = osvrTimeValueDurationSeconds(&newTime, &initialTime);
            kalman::predict(state, processModel, dt);
            state.externalizeRotation();
        }
        if (meas.orientationValid()) {
            applyOriToState(sys, state, processModel, meas);
        } else if (meas.angVelValid()) {
            applyAngVelToState(sys, state, processModel, meas);

        } else {
            // unusually, the measurement is totally invalid. Just normalize and
            // go on.
            state.postCorrect();
        }
    }
} // namespace vbtracker
} // namespace osvr
<commit_msg>Fix IMU jacobian and adjust innovation function<commit_after>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "ApplyIMUToState.h"
#include "AngVelTools.h"
#include "CrossProductMatrix.h"
#include "SpaceTransformations.h"

// Library/third-party includes
#include <osvr/Kalman/AbsoluteOrientationMeasurement.h>
#include <osvr/Kalman/AngularVelocityMeasurement.h>
#include <osvr/Kalman/FlexibleKalmanFilter.h>
#include <osvr/Util/EigenExtras.h>
#include <osvr/Util/EigenQuatExponentialMap.h>
#include <util/Stride.h>

// Standard includes
#include <iostream>

namespace osvr {

namespace kalman {
#undef OSVR_Q_LAST
    /// The measurement here has been split into a base and derived type, so
    /// that the derived type only contains the little bit that depends on a
    /// particular state type.
    class IMUOrientationMeasBase {
      public:
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
        static const types::DimensionType DIMENSION = 3;
        using MeasurementVector = types::Vector<DIMENSION>;
        using MeasurementSquareMatrix = types::SquareMatrix<DIMENSION>;
        static Eigen::Quaterniond
        computeEffectiveIMUToCam(Eigen::Quaterniond const &cameraPose,
                                 util::Angle yawCorrection) {
            return Eigen::Quaterniond(
                Eigen::AngleAxisd(util::getRadians(yawCorrection),
                                  Eigen::Vector3d::UnitY()) *
                cameraPose);
        }
        IMUOrientationMeasBase(Eigen::Quaterniond const &cameraPose,
                               util::Angle yawCorrection,
                               Eigen::Quaterniond const &quat,
                               types::Vector<3> const &emVariance)
            : m_iRc(computeEffectiveIMUToCam(cameraPose, yawCorrection)),
              m_cRi(m_iRc.inverse()), m_quat(quat),
              m_covariance(emVariance.asDiagonal()) {}

        template <typename State>
        MeasurementSquareMatrix const &getCovariance(State const &) {
            return m_covariance;
        }

        /// convenience function for shared implementation between getResidual
        /// and getJacobianBlock
        Eigen::Quaterniond
        getInnovationQuat(Eigen::Quaterniond const &cRb) const {
/// m_quat is iRbm - the body (measured) frame
/// cRb is "current" (predicted) state - body in camera space
#ifdef OSVR_Q_LAST
            return cRb.inverse() * m_cRi * m_quat;
#else
            // this is the logical one.
            // return m_quat.conjugate() * m_iRc * cRb;
            // this is the one that matches the original measurement class
            // closer.
            return m_cRi * m_quat * cRb.inverse();
#endif
        }
        /// Gets the measurement residual, also known as innovation: predicts
        /// the measurement from the predicted state, and returns the
        /// difference.
        ///
        /// State type doesn't matter as long as we can
        /// `.getCombinedQuaternion()`
        template <typename State>
        MeasurementVector getResidual(State const &s) const {
#if 0
            const Eigen::Quaterniond predictionInIMUSpace =
                m_iRc * s.getCombinedQuaternion();

            const Eigen::Quaterniond residualqInIMUSpace = m_quat * predictionInIMUSpace.inverse();
			const Eigen::Quaterniond residualqInCamSpace = m_cRi * residualqInIMUSpace;
#else

            const Eigen::Quaterniond residualq =
                getInnovationQuat(s.getCombinedQuaternion());
#endif
            // Two equivalent quaternions: but their logs are typically
            // different: one is the "short way" and the other is the "long
            // way". We'll compute both and pick the "short way".
            MeasurementVector residual = util::quat_ln(residualq);
            MeasurementVector equivResidual =
                util::quat_ln(Eigen::Quaterniond(-(residualq.coeffs())));
#ifdef OSVR_FLIP_QUATS
            return residual.squaredNorm() < equivResidual.squaredNorm()
                       ? residual
                       : equivResidual;
#else
            return residual;
#endif
        }
        /// Convenience method to be able to store and re-use measurements.
        void setMeasurement(Eigen::Quaterniond const &quat) { m_quat = quat; }

        /// Get the block of jacobian that is non-zero: your subclass will have
        /// to put it where it belongs for each particular state type.
        template <typename State>
        types::Matrix<DIMENSION, 3> getJacobianBlock(State const &s) const {
            /// Compute the innovation quat again.
            Eigen::Quaterniond q = getInnovationQuat(s.getCombinedQuaternion());
#ifdef OSVR_USE_CODEGEN
            /// pre-compute the manually-extracted subexpressions.
            Eigen::Vector3d q2(q.vec().cwiseProduct(q.vec()));
            auto qvecnorm = std::sqrt(q2.sum());
            /// codegen follows
            // Quat.QuatToRotVec(g(x) * q)
            auto tmp0 = (1. / 2.) / qvecnorm;
            auto tmp1 = -q.w() * tmp0;
            auto tmp2 = std::pow(qvecnorm, -3);
            auto tmp3 = (1. / 2.) * q.w() * tmp2;
            auto tmp4 = q.z() * tmp0;
            auto tmp5 = (1. / 2.) * q.w() * q.x() * tmp2;
            auto tmp6 = q.y() * tmp5;
            auto tmp7 = q.y() * tmp0;
            auto tmp8 = q.z() * tmp5;
            auto tmp9 = q.x() * tmp0;
            auto tmp10 = q.y() * q.z() * tmp3;
            Eigen::Matrix<double, 3, 3> ret;
            ret << q2.x() * tmp3 + tmp1, tmp4 + tmp6, -tmp7 + tmp8,
                -tmp4 + tmp6, q2.y() * tmp3 + tmp1, tmp10 + tmp9, tmp7 + tmp8,
                tmp10 - tmp9, q2.z() * tmp3 + tmp1;
#else
            auto qvecnorm = q.vec().norm();

            if (qvecnorm < 1e-4) {
                // effectively 0 - must avoid divide by zero.
                // All numerators also go to 0 in this case, so we'll just
                // eliminate them.
                // The exception is the second term of the main diagonal:
                // nominally -qw/2*vecnorm.
                // qw would be 1, but in this form at least, the math goes to
                // -infinity.

                // When the jacobian is computed symbolically specifically for
                // the case that q is the identity quaternion, a zero matrix is
                // returned.
                return Eigen::Matrix3d::Zero();
            }
            Eigen::Matrix3d ret =
                // first term: qw * (qvec outer product with itself), over 2 *
                // vecnorm^3
                (q.w() * q.vec() * q.vec().transpose() /
                 (2 * qvecnorm * qvecnorm * qvecnorm)) +
                // second term of each element: cross-product matrix of the
                // negative vector part of quaternion over 2*vecnorm, minus the
                // identity matrix * qw/2*vecnorm
                ((vbtracker::skewSymmetricCrossProductMatrix3(-q.vec()) -
                  Eigen::Matrix3d::Identity() * q.w()) /
                 (2 * qvecnorm));
            static bool printedJacobian = false;
            if (!printedJacobian) {
                printedJacobian = true;
                std::cout << ret << std::endl;
            }
#endif

#ifdef OSVR_Q_LAST
            return ret;
#else
            // Quat.QuatToRotVec(q * g(x))
            // turns out the output is the same as the above, just transposed,
            // even after the conversion to a rotation vector. (given a fixed q)
            return ret.transpose();
#endif
        }

      private:
        Eigen::Quaterniond m_iRc;
        Eigen::Quaterniond m_cRi;
        Eigen::Quaterniond m_quat;
        MeasurementSquareMatrix m_covariance;
    };

    /// This is the subclass of AbsoluteOrientationBase: only explicit
    /// specializations, and on state types.
    template <typename StateType> class IMUOrientationMeasurement;

    /// AbsoluteOrientationMeasurement with a pose_externalized_rotation::State
    template <>
    class IMUOrientationMeasurement<pose_externalized_rotation::State>
        : public IMUOrientationMeasBase {
      public:
        using State = pose_externalized_rotation::State;
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
        static const types::DimensionType STATE_DIMENSION =
            types::Dimension<State>::value;
        using Base = IMUOrientationMeasBase;

        IMUOrientationMeasurement(Eigen::Quaterniond const &cameraPose,
                                  util::Angle yawCorrection,
                                  Eigen::Quaterniond const &quat,
                                  types::Vector<3> const &emVariance)
            : Base(cameraPose, yawCorrection, quat, emVariance) {}

        types::Matrix<DIMENSION, STATE_DIMENSION>
        getJacobian(State const &s) const {
            using namespace pose_externalized_rotation;
            using Jacobian = types::Matrix<DIMENSION, STATE_DIMENSION>;
            Jacobian ret = Jacobian::Zero();
            ret.block<DIMENSION, 3>(0, 3) = Base::getJacobianBlock(s);
            return ret;
        }
    };
} // namespace kalman
namespace vbtracker {
    inline void applyOriToState(TrackingSystem const &sys, BodyState &state,
                                BodyProcessModel &processModel,
                                CannedIMUMeasurement const &meas) {
        Eigen::Quaterniond quat;
        meas.restoreQuat(quat);
        Eigen::Vector3d var;
        meas.restoreQuatVariance(var);
        util::Angle yawCorrection = meas.getYawCorrection();

        /// Measurement class will rotate it into camera space
        /// @todo do this without rotating into camera space?

        /// @todo transform variance?

        kalman::IMUOrientationMeasurement<BodyState> kalmanMeas{
            getCameraRotation(sys), yawCorrection, quat, var};
#if 0
        {
            static ::util::Stride s(201);
            if (++s) {
                Eigen::AngleAxisd pred(state.getCombinedQuaternion());
                Eigen::AngleAxisd meas(quat);
                std::cout << "Predicted: " << pred.angle() << " about "
                          << pred.axis().transpose() << "\n";
                std::cout << "Measured: " << meas.angle() << " about "
                          << meas.axis().transpose() << "\n";
                std::cout << "Residual: "
                          << kalmanMeas.getResidual(state).transpose() << "\n";
            }
        }
#endif
        auto correctionInProgress =
            kalman::beginCorrection(state, processModel, kalmanMeas);
        auto outputMeas = [&] {
            std::cout << "state: " << state.getQuaternion().coeffs().transpose()
                      << " and measurement: " << quat.coeffs().transpose();
        };
        if (!correctionInProgress.stateCorrectionFinite) {
            std::cout
                << "Non-finite state correction in applying orientation: ";
            outputMeas();
            std::cout << "\n";
            return;
        }
        if (!correctionInProgress.finishCorrection(true)) {
            std::cout
                << "Non-finite error covariance after applying orientation: ";
            outputMeas();
            std::cout << "\n";
        }
    }

    inline void applyAngVelToState(TrackingSystem const &sys, BodyState &state,
                                   BodyProcessModel &processModel,
                                   CannedIMUMeasurement const &meas) {

        Eigen::Vector3d angVel;
        meas.restoreAngVel(angVel);
        Eigen::Vector3d var;
        meas.restoreAngVelVariance(var);
        static const double dt = 0.02;
        /// Rotate it into camera space - it's bTb and we want cTc
        /// @todo do this without rotating into camera space?
        Eigen::Quaterniond cTb = state.getQuaternion();
        // Eigen::Matrix3d bTc(state.getQuaternion().conjugate());
        /// Turn it into an incremental quat to do the space transformation
        Eigen::Quaterniond incrementalQuat =
            cTb * angVelVecToIncRot(angVel, dt) * cTb.conjugate();
        /// Then turn it back into an angular velocity vector
        angVel = incRotToAngVelVec(incrementalQuat, dt);
        // angVel = (getRotationMatrixToCameraSpace(sys) * angVel).eval();
        /// @todo transform variance?

        kalman::AngularVelocityMeasurement<BodyState> kalmanMeas{angVel, var};
        kalman::correct(state, processModel, kalmanMeas);
    }

    void applyIMUToState(TrackingSystem const &sys,
                         util::time::TimeValue const &initialTime,
                         BodyState &state, BodyProcessModel &processModel,
                         util::time::TimeValue const &newTime,
                         CannedIMUMeasurement const &meas) {
        if (newTime != initialTime) {
            auto dt = osvrTimeValueDurationSeconds(&newTime, &initialTime);
            kalman::predict(state, processModel, dt);
            state.externalizeRotation();
        }
        if (meas.orientationValid()) {
            applyOriToState(sys, state, processModel, meas);
        } else if (meas.angVelValid()) {
            applyAngVelToState(sys, state, processModel, meas);

        } else {
            // unusually, the measurement is totally invalid. Just normalize and
            // go on.
            state.postCorrect();
        }
    }
} // namespace vbtracker
} // namespace osvr
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "sys_net_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Net_NetworkInformation_Wireless80211Configuration::GetWireless82011ConfigurationCount___STATIC__I4,
    Library_sys_net_native_System_Net_NetworkInformation_Wireless80211Configuration::GetWireless82011Configuration___STATIC__SystemNetNetworkInformationWireless80211Configuration__I4,
    Library_sys_net_native_System_Net_NetworkInformation_Wireless80211Configuration::UpdateConfiguration___STATIC__VOID,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::InitializeNetworkInterfaceSettings___VOID,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::UpdateConfiguration___VOID__I4,
    NULL,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterfaceCount___STATIC__I4,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterface___STATIC__SystemNetNetworkInformationNetworkInterface__U4,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::IPAddressFromString___STATIC__U4__STRING,
    Library_sys_net_native_System_Net_Security_SslNative::SecureServerInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate,
    Library_sys_net_native_System_Net_Security_SslNative::SecureClientInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate,
    Library_sys_net_native_System_Net_Security_SslNative::UpdateCertificates___STATIC__VOID__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate,
    Library_sys_net_native_System_Net_Security_SslNative::SecureAccept___STATIC__VOID__I4__OBJECT,
    Library_sys_net_native_System_Net_Security_SslNative::SecureConnect___STATIC__VOID__I4__STRING__OBJECT,
    Library_sys_net_native_System_Net_Security_SslNative::SecureRead___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4,
    Library_sys_net_native_System_Net_Security_SslNative::SecureWrite___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4,
    Library_sys_net_native_System_Net_Security_SslNative::SecureCloseSocket___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Security_SslNative::ExitSecureContext___STATIC__I4__I4,
    Library_sys_net_native_System_Net_Security_SslNative::DataAvailable___STATIC__I4__OBJECT,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::socket___STATIC__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::bind___STATIC__VOID__OBJECT__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::connect___STATIC__VOID__OBJECT__SZARRAY_U1__BOOLEAN,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::send___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::recv___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::close___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::listen___STATIC__VOID__OBJECT__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::accept___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getaddrinfo___STATIC__VOID__STRING__BYREF_STRING__BYREF_SZARRAY_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::shutdown___STATIC__VOID__OBJECT__I4__BYREF_I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::sendto___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::recvfrom___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getpeername___STATIC__VOID__OBJECT__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getsockname___STATIC__VOID__OBJECT__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getsockopt___STATIC__VOID__OBJECT__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::setsockopt___STATIC__VOID__OBJECT__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::poll___STATIC__BOOLEAN__OBJECT__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::ioctl___STATIC__VOID__OBJECT__U4__BYREF_U4,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Security_Cryptography_X509Certificates_X509Certificate::ParseCertificate___STATIC__VOID__SZARRAY_U1__STRING__BYREF_STRING__BYREF_STRING__BYREF_mscorlibSystemDateTime__BYREF_mscorlibSystemDateTime,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Net =
{
    "System.Net",
    0xC58744CD,
    method_lookup,
    { 1, 0, 2, 4 }
};
<commit_msg>Update nanoFramework.System.Net version to 1.0.2-preview-013 ***NO_CI*** (#1003)<commit_after>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "sys_net_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Net_NetworkInformation_Wireless80211Configuration::GetWireless82011ConfigurationCount___STATIC__I4,
    Library_sys_net_native_System_Net_NetworkInformation_Wireless80211Configuration::GetWireless82011Configuration___STATIC__SystemNetNetworkInformationWireless80211Configuration__I4,
    Library_sys_net_native_System_Net_NetworkInformation_Wireless80211Configuration::UpdateConfiguration___STATIC__VOID,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::InitializeNetworkInterfaceSettings___VOID,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::UpdateConfiguration___VOID__I4,
    NULL,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterfaceCount___STATIC__I4,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterface___STATIC__SystemNetNetworkInformationNetworkInterface__U4,
    Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::IPAddressFromString___STATIC__U4__STRING,
    Library_sys_net_native_System_Net_Security_SslNative::SecureServerInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate,
    Library_sys_net_native_System_Net_Security_SslNative::SecureClientInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate,
    Library_sys_net_native_System_Net_Security_SslNative::UpdateCertificates___STATIC__VOID__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate,
    Library_sys_net_native_System_Net_Security_SslNative::SecureAccept___STATIC__VOID__I4__OBJECT,
    Library_sys_net_native_System_Net_Security_SslNative::SecureConnect___STATIC__VOID__I4__STRING__OBJECT,
    Library_sys_net_native_System_Net_Security_SslNative::SecureRead___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4,
    Library_sys_net_native_System_Net_Security_SslNative::SecureWrite___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4,
    Library_sys_net_native_System_Net_Security_SslNative::SecureCloseSocket___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Security_SslNative::ExitSecureContext___STATIC__I4__I4,
    Library_sys_net_native_System_Net_Security_SslNative::DataAvailable___STATIC__I4__OBJECT,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::socket___STATIC__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::bind___STATIC__VOID__OBJECT__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::connect___STATIC__VOID__OBJECT__SZARRAY_U1__BOOLEAN,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::send___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::recv___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::close___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::listen___STATIC__VOID__OBJECT__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::accept___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getaddrinfo___STATIC__VOID__STRING__BYREF_STRING__BYREF_SZARRAY_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::shutdown___STATIC__VOID__OBJECT__I4__BYREF_I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::sendto___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::recvfrom___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getpeername___STATIC__VOID__OBJECT__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getsockname___STATIC__VOID__OBJECT__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getsockopt___STATIC__VOID__OBJECT__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::setsockopt___STATIC__VOID__OBJECT__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::poll___STATIC__BOOLEAN__OBJECT__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::ioctl___STATIC__VOID__OBJECT__U4__BYREF_U4,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Security_Cryptography_X509Certificates_X509Certificate::ParseCertificate___STATIC__VOID__SZARRAY_U1__STRING__BYREF_STRING__BYREF_STRING__BYREF_mscorlibSystemDateTime__BYREF_mscorlibSystemDateTime,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Net =
{
    "System.Net",
    0xC58744CD,
    method_lookup,
    { 1, 0, 2, 13 }
};
<|endoftext|>


<commit_before>/**
    For conditions of distribution and use, see copyright notice in LICENSE

    @file   EC_Highlight.cpp
    @brief  EC_Highlight enables visual highlighting effect for of scene entity. */

#include "DebugOperatorNew.h"
#include "EC_Highlight.h"

#include "Framework.h"
#include "AssetAPI.h"
#include "Entity.h"
#include "Scene/Scene.h"
#include "Renderer.h"
#include "OgreMaterialUtils.h"
#include "OgreMaterialAsset.h"
#include "OgreWorld.h"
#include "EC_Placeable.h"
#include "EC_Mesh.h"
#include "LoggingFunctions.h"
#include "AssetAPI.h"

#include <QTimer>

#include <OgreMaterial.h>
#include <OgreTechnique.h>
#include <OgrePass.h>

#include "MemoryLeakCheck.h"

// Global flag for detecting conflicting applies from multiple highlights / preventing endless loops
static bool inApply = false;

EC_Highlight::EC_Highlight(Scene* scene) :
    IComponent(scene),
    visible(this, "Is visible", false),
    solidColor(this, "Solid color", Color(0.3f, 0.5f, 0.1f, 0.5f)),
    outlineColor(this, "Outline color", Color(1.0f, 1.0f, 1.0f, 0.5f)),
    reapplyPending_(false)
{
    if (scene)
        world_ = scene->GetWorld<OgreWorld>();

    connect(this, SIGNAL(ParentEntitySet()), SLOT(UpdateSignals()));
}

EC_Highlight::~EC_Highlight()
{
    Hide();
}

void  EC_Highlight::Show()
{
    if ((mesh_.expired()) || (world_.expired()))
        return;

    inApply = true;

    // Remove old materials first if they exist
    Hide();

    EC_Mesh* mesh = mesh_.lock().get();
    AssetAPI* assetAPI = framework->Asset();

    originalMaterials_.clear();

    // Clone all valid material assets that we can find from the mesh
    /// \todo Currently will clone the same material several times if used on several submeshes
    /// \todo What if the material is yet pending, or is not an asset (LitTextured)
    AssetReferenceList materialList = mesh->meshMaterial.Get();
    for(int i = 0; i < materialList.Size(); ++i)
    {
        if (!materialList[i].ref.isEmpty())
        {
            QString assetFullName = assetAPI->ResolveAssetRef("", materialList[i].ref);
            AssetPtr asset = assetAPI->GetAsset(assetFullName);
            if ((asset) && (asset->IsLoaded()) && (dynamic_cast<OgreMaterialAsset*>(asset.get())))
            {
                AssetPtr clone = asset->Clone(QString::fromStdString(world_.lock()->GetUniqueObjectName("EC_Highlight_Material")) + ".material");
                if (clone)
                {
                    OgreMaterialAsset* matAsset = dynamic_cast<OgreMaterialAsset*>(clone.get());
                    CreateHighlightToOgreMaterial(matAsset);
                    mesh->SetMaterial(i, clone->Name(), AttributeChange::Disconnected);
                    materials_.push_back(clone);

                    // Store original ref to be restored in Hide()
                    originalMaterials_[i] = materialList[i].ref;
                }
            }
        }
    }
}

void EC_Highlight::Hide()
{
    if (!mesh_.expired())
    {
        // Restore mesh component's original materials to hide highlight effect
        EC_Mesh* mesh = mesh_.lock().get();
        foreach(uint index, originalMaterials_.keys())
            mesh->SetMaterial(index, originalMaterials_[index], AttributeChange::Disconnected);
        originalMaterials_.clear();
    }

    // Destroy all the highlight materials
    AssetAPI* assetAPI = framework->Asset();
    for (unsigned i = 0; i < materials_.size(); ++i)
        assetAPI->ForgetAsset(materials_[i], false);
    materials_.clear();
}

bool EC_Highlight::IsVisible() const
{
    return materials_.size() > 0;
}

void EC_Highlight::UpdateSignals()
{
    Entity* parent = ParentEntity();
    if (parent)
    {
        // Connect to ComponentAdded/Removed signals of the parent entity, so we can check when the mesh component gets added or removed
        connect(parent, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), SLOT(AcquireMesh()));
        connect(parent, SIGNAL(ComponentRemoved(IComponent*, AttributeChange::Type)), SLOT(OnComponentRemoved(IComponent*, AttributeChange::Type)));
        // Also try to acquire the mesh component immediately
        AcquireMesh();
    }
}

void EC_Highlight::OnComponentRemoved(IComponent* component, AttributeChange::Type change)
{
    if (component == mesh_.lock().get())
    {
        Hide();
        mesh_.reset();
    }
}

void EC_Highlight::AcquireMesh()
{
    // Return if already acquired
    if (!mesh_.expired())
        return;

    mesh_ = ParentEntity()->GetComponent<EC_Mesh>();

    EC_Mesh* mesh = mesh_.lock().get();
    if (mesh)
    {
        // Connect to mesh & material change signals so we can reapply the highlight
        connect(mesh, SIGNAL(MeshChanged()), this, SLOT(TriggerReapply()), Qt::UniqueConnection);
        connect(mesh, SIGNAL(MaterialChanged(uint, const QString &)), this, SLOT(TriggerReapply()), Qt::UniqueConnection);

        // Also show right now if highlight active
        if (visible.Get())
            Show();
    }
}

void EC_Highlight::AttributesChanged()
{
    if (visible.ValueChanged())
    {
        if (visible.Get())
            Show();
        else
            Hide();
    }

    if (solidColor.ValueChanged() || outlineColor.ValueChanged())
        ApplyHighlightColors();
}

void EC_Highlight::TriggerReapply()
{
    // Disregard signal if in the middle of applying highlight
    if (inApply)
        return;

    // We might get multiple requests to reapply, but actually execute on the next frame, so that we don't do needless recreation of materials
    if ((!reapplyPending_) && (visible.Get()))
    {
        reapplyPending_ = true;
        QTimer::singleShot(0, this, SLOT(ReapplyHighlight()));
    }
}

void EC_Highlight::ReapplyHighlight()
{
    if (visible.Get())
        Show();
    reapplyPending_ = false;
}

void EC_Highlight::CreateHighlightToOgreMaterial(OgreMaterialAsset* mat)
{
    if (!mat)
        return;

    unsigned numTech = mat->GetNumTechniques();
    for (unsigned i = 0; i < numTech; ++i)
    {
        int pass1 = mat->CreatePass(i);
        int pass2 = mat->CreatePass(i);

        // Setting the shaders requires the SolidAmbient.material to exist in the resource groups, so that the shaders exist
        mat->SetLighting(i, pass1, false);
        mat->SetSceneBlend(i, pass1, Ogre::SBT_TRANSPARENT_ALPHA);
        mat->SetDepthWrite(i, pass1, false);
        mat->SetDepthBias(i, pass1, 1.f);
        mat->SetHardwareCullingMode(i, pass1, Ogre::CULL_NONE);
        mat->SetVertexShader(i, pass1, "SolidAmbientVP");
        mat->SetPixelShader(i, pass1, "SolidAmbientFP");
        mat->SetAmbientColor(i, pass1, solidColor.Get());

        mat->SetLighting(i, pass2, false);
        mat->SetSceneBlend(i, pass2, Ogre::SBT_TRANSPARENT_ALPHA);
        mat->SetDepthWrite(i, pass2, false);
        mat->SetDepthBias(i, pass2, 2.f);
        mat->SetHardwareCullingMode(i, pass2, Ogre::CULL_NONE);
        mat->SetVertexShader(i, pass2, "SolidAmbientVP");
        mat->SetPixelShader(i, pass2, "SolidAmbientFP");
        mat->SetAmbientColor(i, pass2, outlineColor.Get());
        mat->SetPolygonMode(i, pass2, Ogre::PM_WIREFRAME);
    }
}

void EC_Highlight::ApplyHighlightColors()
{
    for (unsigned i = 0; i < materials_.size(); ++i)
    {
        OgreMaterialAsset* mat = dynamic_cast<OgreMaterialAsset*>(materials_[i].get());
        unsigned numTech = mat->GetNumTechniques();
        for (unsigned i = 0; i < numTech; ++i)
        {
            unsigned numPasses = mat->GetNumPasses(i);
            // Modify the diffuse color of the last 2 passes
            // (this should be a highlight material that we added the 2 passes to)
            if (numPasses >= 2)
            {
                mat->SetAmbientColor(i, numPasses - 2, solidColor.Get());
                mat->SetAmbientColor(i, numPasses - 1, outlineColor.Get());
            }
        }
    }
}
<commit_msg>EC_Highlight: Use LocalOnly when restoring the material refs to ensure all editors show the real ref values when highlight is toggled off/removed.<commit_after>/**
    For conditions of distribution and use, see copyright notice in LICENSE

    @file   EC_Highlight.cpp
    @brief  EC_Highlight enables visual highlighting effect for of scene entity. */

#include "DebugOperatorNew.h"
#include "EC_Highlight.h"

#include "Framework.h"
#include "AssetAPI.h"
#include "Entity.h"
#include "Scene/Scene.h"
#include "Renderer.h"
#include "OgreMaterialUtils.h"
#include "OgreMaterialAsset.h"
#include "OgreWorld.h"
#include "EC_Placeable.h"
#include "EC_Mesh.h"
#include "LoggingFunctions.h"
#include "AssetAPI.h"

#include <QTimer>

#include <OgreMaterial.h>
#include <OgreTechnique.h>
#include <OgrePass.h>

#include "MemoryLeakCheck.h"

// Global flag for detecting conflicting applies from multiple highlights / preventing endless loops
static bool inApply = false;

EC_Highlight::EC_Highlight(Scene* scene) :
    IComponent(scene),
    visible(this, "Is visible", false),
    solidColor(this, "Solid color", Color(0.3f, 0.5f, 0.1f, 0.5f)),
    outlineColor(this, "Outline color", Color(1.0f, 1.0f, 1.0f, 0.5f)),
    reapplyPending_(false)
{
    if (scene)
        world_ = scene->GetWorld<OgreWorld>();

    connect(this, SIGNAL(ParentEntitySet()), SLOT(UpdateSignals()));
}

EC_Highlight::~EC_Highlight()
{
    Hide();
}

void  EC_Highlight::Show()
{
    if ((mesh_.expired()) || (world_.expired()))
        return;

    inApply = true;

    // Remove old materials first if they exist
    Hide();

    EC_Mesh* mesh = mesh_.lock().get();
    AssetAPI* assetAPI = framework->Asset();

    originalMaterials_.clear();

    // Clone all valid material assets that we can find from the mesh
    /// \todo Currently will clone the same material several times if used on several submeshes
    /// \todo What if the material is yet pending, or is not an asset (LitTextured)
    AssetReferenceList materialList = mesh->meshMaterial.Get();
    for(int i = 0; i < materialList.Size(); ++i)
    {
        if (!materialList[i].ref.isEmpty())
        {
            QString assetFullName = assetAPI->ResolveAssetRef("", materialList[i].ref);
            AssetPtr asset = assetAPI->GetAsset(assetFullName);
            if ((asset) && (asset->IsLoaded()) && (dynamic_cast<OgreMaterialAsset*>(asset.get())))
            {
                AssetPtr clone = asset->Clone(QString::fromStdString(world_.lock()->GetUniqueObjectName("EC_Highlight_Material")) + ".material");
                if (clone)
                {
                    OgreMaterialAsset* matAsset = dynamic_cast<OgreMaterialAsset*>(clone.get());
                    CreateHighlightToOgreMaterial(matAsset);
                    mesh->SetMaterial(i, clone->Name(), AttributeChange::Disconnected);
                    materials_.push_back(clone);

                    // Store original ref to be restored in Hide()
                    originalMaterials_[i] = materialList[i].ref;
                }
            }
        }
    }
}

void EC_Highlight::Hide()
{
    if (!mesh_.expired())
    {
        // Restore mesh component's original materials to hide highlight effect.
        // Use AttributeChange::LocalOnly to ensure all editors will show the real refs.
        EC_Mesh* mesh = mesh_.lock().get();
        foreach(uint index, originalMaterials_.keys())
            mesh->SetMaterial(index, originalMaterials_[index], AttributeChange::LocalOnly);
        originalMaterials_.clear();
    }

    // Destroy all the highlight materials
    AssetAPI* assetAPI = framework->Asset();
    for (unsigned i = 0; i < materials_.size(); ++i)
        assetAPI->ForgetAsset(materials_[i], false);
    materials_.clear();
}

bool EC_Highlight::IsVisible() const
{
    return materials_.size() > 0;
}

void EC_Highlight::UpdateSignals()
{
    Entity* parent = ParentEntity();
    if (parent)
    {
        // Connect to ComponentAdded/Removed signals of the parent entity, so we can check when the mesh component gets added or removed
        connect(parent, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), SLOT(AcquireMesh()));
        connect(parent, SIGNAL(ComponentRemoved(IComponent*, AttributeChange::Type)), SLOT(OnComponentRemoved(IComponent*, AttributeChange::Type)));
        // Also try to acquire the mesh component immediately
        AcquireMesh();
    }
}

void EC_Highlight::OnComponentRemoved(IComponent* component, AttributeChange::Type change)
{
    if (component == mesh_.lock().get())
    {
        Hide();
        mesh_.reset();
    }
}

void EC_Highlight::AcquireMesh()
{
    // Return if already acquired
    if (!mesh_.expired())
        return;

    mesh_ = ParentEntity()->GetComponent<EC_Mesh>();

    EC_Mesh* mesh = mesh_.lock().get();
    if (mesh)
    {
        // Connect to mesh & material change signals so we can reapply the highlight
        connect(mesh, SIGNAL(MeshChanged()), this, SLOT(TriggerReapply()), Qt::UniqueConnection);
        connect(mesh, SIGNAL(MaterialChanged(uint, const QString &)), this, SLOT(TriggerReapply()), Qt::UniqueConnection);

        // Also show right now if highlight active
        if (visible.Get())
            Show();
    }
}

void EC_Highlight::AttributesChanged()
{
    if (visible.ValueChanged())
    {
        if (visible.Get())
            Show();
        else
            Hide();
    }

    if (solidColor.ValueChanged() || outlineColor.ValueChanged())
        ApplyHighlightColors();
}

void EC_Highlight::TriggerReapply()
{
    // Disregard signal if in the middle of applying highlight
    if (inApply)
        return;

    // We might get multiple requests to reapply, but actually execute on the next frame, so that we don't do needless recreation of materials
    if ((!reapplyPending_) && (visible.Get()))
    {
        reapplyPending_ = true;
        QTimer::singleShot(0, this, SLOT(ReapplyHighlight()));
    }
}

void EC_Highlight::ReapplyHighlight()
{
    if (visible.Get())
        Show();
    reapplyPending_ = false;
}

void EC_Highlight::CreateHighlightToOgreMaterial(OgreMaterialAsset* mat)
{
    if (!mat)
        return;

    unsigned numTech = mat->GetNumTechniques();
    for (unsigned i = 0; i < numTech; ++i)
    {
        int pass1 = mat->CreatePass(i);
        int pass2 = mat->CreatePass(i);

        // Setting the shaders requires the SolidAmbient.material to exist in the resource groups, so that the shaders exist
        mat->SetLighting(i, pass1, false);
        mat->SetSceneBlend(i, pass1, Ogre::SBT_TRANSPARENT_ALPHA);
        mat->SetDepthWrite(i, pass1, false);
        mat->SetDepthBias(i, pass1, 1.f);
        mat->SetHardwareCullingMode(i, pass1, Ogre::CULL_NONE);
        mat->SetVertexShader(i, pass1, "SolidAmbientVP");
        mat->SetPixelShader(i, pass1, "SolidAmbientFP");
        mat->SetAmbientColor(i, pass1, solidColor.Get());

        mat->SetLighting(i, pass2, false);
        mat->SetSceneBlend(i, pass2, Ogre::SBT_TRANSPARENT_ALPHA);
        mat->SetDepthWrite(i, pass2, false);
        mat->SetDepthBias(i, pass2, 2.f);
        mat->SetHardwareCullingMode(i, pass2, Ogre::CULL_NONE);
        mat->SetVertexShader(i, pass2, "SolidAmbientVP");
        mat->SetPixelShader(i, pass2, "SolidAmbientFP");
        mat->SetAmbientColor(i, pass2, outlineColor.Get());
        mat->SetPolygonMode(i, pass2, Ogre::PM_WIREFRAME);
    }
}

void EC_Highlight::ApplyHighlightColors()
{
    for (unsigned i = 0; i < materials_.size(); ++i)
    {
        OgreMaterialAsset* mat = dynamic_cast<OgreMaterialAsset*>(materials_[i].get());
        unsigned numTech = mat->GetNumTechniques();
        for (unsigned i = 0; i < numTech; ++i)
        {
            unsigned numPasses = mat->GetNumPasses(i);
            // Modify the diffuse color of the last 2 passes
            // (this should be a highlight material that we added the 2 passes to)
            if (numPasses >= 2)
            {
                mat->SetAmbientColor(i, numPasses - 2, solidColor.Get());
                mat->SetAmbientColor(i, numPasses - 1, outlineColor.Get());
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2015 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <QtGui>
#include <Interface/Application/TriggeredEventsWindow.h>
#include <Interface/Application/NetworkEditor.h>
#include <Core/Application/Preferences/Preferences.h>

using namespace SCIRun::Gui;
//using namespace SCIRun::Dataflow::Networks;
//using namespace SCIRun::Dataflow::Engine;

TriggeredEventsWindow::TriggeredEventsWindow(QWidget* parent /* = 0 */) : QDockWidget(parent)
{
  setupUi(this);
  connect(eventListWidget_, SIGNAL(itemSelectionChanged()), this, SLOT(updateScriptEditor()));
  connect(scriptPlainTextEdit_, SIGNAL(textChanged()), this, SLOT(updateScripts()));
  connect(enabledCheckBox_, SIGNAL(stateChanged(int)), this, SLOT(enableStateChanged(int)));
}

const QMap<QString, QString>& TriggeredEventsWindow::getScripts() const
{
  return scripts_;
}

void TriggeredEventsWindow::setScripts(const QMap<QString, QString>& scripts)
{
  scripts_ = scripts;

  eventListWidget_->setCurrentItem(eventListWidget_->item(1));
  updateScriptEditor();
}

const QMap<QString, bool>& TriggeredEventsWindow::getScriptEnabledFlags() const
{
  return scriptEnabledFlags_;
}

void TriggeredEventsWindow::setScriptEnabledFlags(const QMap<QString, bool>& scriptsEnabled)
{
  scriptEnabledFlags_ = scriptsEnabled;

  eventListWidget_->setCurrentItem(eventListWidget_->item(1));
  updateScriptEditor();
}

namespace
{
  const QString defaultScript = "# Insert Python API calls here.\n"
    "\n"
    "# Examples:\n"
    "\n"
    "# With the \"Post module add\" event, this snippet will change the initial filetype for a specific type of input module :\n"
    "# scirun_set_module_state(scirun_module_ids()[-1], 'FileTypeName', 'Matlab Matrix (*.mat)') if scirun_module_ids()[-1].startswith('ReadMatrix') else None\n"
    "\n"
    "# With the \"On network load\" event, this snippet will open the UIs for all the ViewScenes in the network :\n"
    "# TODO\n";
}

void TriggeredEventsWindow::updateScriptEditor()
{
  auto key = eventListWidget_->currentItem()->text();
  auto scr = scripts_[key];
  scriptPlainTextEdit_->setPlainText(!scr.isEmpty() ? scr : defaultScript);
  enabledCheckBox_->setChecked(scriptEnabledFlags_[key]);
  push();
}

void TriggeredEventsWindow::updateScripts()
{
  auto key = eventListWidget_->currentItem()->text();
  auto script = scriptPlainTextEdit_->toPlainText();
  scripts_[key] = script;

  //TODO: waiting on implementation of #41, see ModuleDialogGeneric.h comment
  push();
}

void TriggeredEventsWindow::enableStateChanged(int state)
{
  auto key = eventListWidget_->currentItem()->text();
  auto enabled = state == Qt::Checked;
  scriptEnabledFlags_[key] = enabled;

  //TODO: waiting on implementation of #41, see ModuleDialogGeneric.h comment
  push();
}

void TriggeredEventsWindow::push()
{
  for (int i = 0; i < eventListWidget_->count(); ++i)
  {
    auto key = eventListWidget_->item(i)->text();
    if (key == "Post module add")
    {
      Core::Preferences::Instance().postModuleAddScript_temporarySolution.setValue(scripts_[key].toStdString());
      Core::Preferences::Instance().postModuleAddScriptEnabled_temporarySolution.setValue(scriptEnabledFlags_[key]);
    }
    else if (key == "On network load")
    {
      Core::Preferences::Instance().onNetworkLoadScript_temporarySolution.setValue(scripts_[key].toStdString());
      Core::Preferences::Instance().onNetworkLoadScriptEnabled_temporarySolution.setValue(scriptEnabledFlags_[key]);
    }
  }
}<commit_msg>Add VS UI example<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2015 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <QtGui>
#include <Interface/Application/TriggeredEventsWindow.h>
#include <Interface/Application/NetworkEditor.h>
#include <Core/Application/Preferences/Preferences.h>

using namespace SCIRun::Gui;
//using namespace SCIRun::Dataflow::Networks;
//using namespace SCIRun::Dataflow::Engine;

TriggeredEventsWindow::TriggeredEventsWindow(QWidget* parent /* = 0 */) : QDockWidget(parent)
{
  setupUi(this);
  connect(eventListWidget_, SIGNAL(itemSelectionChanged()), this, SLOT(updateScriptEditor()));
  connect(scriptPlainTextEdit_, SIGNAL(textChanged()), this, SLOT(updateScripts()));
  connect(enabledCheckBox_, SIGNAL(stateChanged(int)), this, SLOT(enableStateChanged(int)));
}

const QMap<QString, QString>& TriggeredEventsWindow::getScripts() const
{
  return scripts_;
}

void TriggeredEventsWindow::setScripts(const QMap<QString, QString>& scripts)
{
  scripts_ = scripts;

  eventListWidget_->setCurrentItem(eventListWidget_->item(1));
  updateScriptEditor();
}

const QMap<QString, bool>& TriggeredEventsWindow::getScriptEnabledFlags() const
{
  return scriptEnabledFlags_;
}

void TriggeredEventsWindow::setScriptEnabledFlags(const QMap<QString, bool>& scriptsEnabled)
{
  scriptEnabledFlags_ = scriptsEnabled;

  eventListWidget_->setCurrentItem(eventListWidget_->item(1));
  updateScriptEditor();
}

namespace
{
  const QString defaultScript = "# Insert Python API calls here.\n"
    "\n"
    "# Examples:\n"
    "\n"
    "# With the \"Post module add\" event, this snippet will change the initial filetype for a specific type of input module :\n"
    "# scirun_set_module_state(scirun_module_ids()[-1], 'FileTypeName', 'Matlab Matrix (*.mat)') if scirun_module_ids()[-1].startswith('ReadMatrix') else None\n"
    "\n"
    "# With the \"On network load\" event, this snippet will open the UIs for all the ViewScenes in the network :\n"
    "# [scirun_set_module_state(id, '__UI__', True) for id in scirun_module_ids() if id.startswith('ViewScene')]\n";
}

void TriggeredEventsWindow::updateScriptEditor()
{
  auto key = eventListWidget_->currentItem()->text();
  auto scr = scripts_[key];
  scriptPlainTextEdit_->setPlainText(!scr.isEmpty() ? scr : defaultScript);
  enabledCheckBox_->setChecked(scriptEnabledFlags_[key]);
  push();
}

void TriggeredEventsWindow::updateScripts()
{
  auto key = eventListWidget_->currentItem()->text();
  auto script = scriptPlainTextEdit_->toPlainText();
  scripts_[key] = script;

  //TODO: waiting on implementation of #41, see ModuleDialogGeneric.h comment
  push();
}

void TriggeredEventsWindow::enableStateChanged(int state)
{
  auto key = eventListWidget_->currentItem()->text();
  auto enabled = state == Qt::Checked;
  scriptEnabledFlags_[key] = enabled;

  //TODO: waiting on implementation of #41, see ModuleDialogGeneric.h comment
  push();
}

void TriggeredEventsWindow::push()
{
  for (int i = 0; i < eventListWidget_->count(); ++i)
  {
    auto key = eventListWidget_->item(i)->text();
    if (key == "Post module add")
    {
      Core::Preferences::Instance().postModuleAddScript_temporarySolution.setValue(scripts_[key].toStdString());
      Core::Preferences::Instance().postModuleAddScriptEnabled_temporarySolution.setValue(scriptEnabledFlags_[key]);
    }
    else if (key == "On network load")
    {
      Core::Preferences::Instance().onNetworkLoadScript_temporarySolution.setValue(scripts_[key].toStdString());
      Core::Preferences::Instance().onNetworkLoadScriptEnabled_temporarySolution.setValue(scriptEnabledFlags_[key]);
    }
  }
}
<|endoftext|>


<commit_before>// $Log$
// Revision 1.3  2003/10/09 11:19:20  strk
// added convexHull and PrecisionModel
//
//
// This file should document by example usage of the GEOS library.
// It could actually be a live discuss-by-example board for
// architectural design choices.
// 			--strk;
//
// DEBUGGING TIPS:
//  use -D__USE_MALLOC at compile time for gcc 2.91, 2.95, 3.0 and 3.1
//  and GLIBCXX_FORCE_NEW or GLIBCPP_FORCE_NEW at run time with gcc 3.2.2+
//  to force libstdc++ avoid caching memory. This should remove some
//  obscure reports from memory checkers like valgrind.
//
#include <stdio.h>
#include <io.h>
#include <geom.h>
#include <unload.h>

using namespace geos;

// This object will be used to construct our geometries.
// It might be bypassed by directly call geometry constructors,
// but that would be boring because you'd need to specify
// a PrecisionModel and a SRID everytime: those infos are
// cached inside a GeometryFactory object.
GeometryFactory *global_factory;

// This function will print given geometries in WKT
// format to stdout.
void
wkt_print_geoms(int numgeoms, Geometry **geoms)
{
	// WKT-print created geometries
	WKTWriter *wkt = new WKTWriter();
	for (int i=0; i<numgeoms; i++) {
		cout<<wkt->write(geoms[i])<<endl;
	}
	delete wkt;
}

// This function will create a LinearRing
// geometry rapresenting a square with the given origin
// and side
LinearRing *
create_square_linearring(double xoffset, double yoffset, double side)
{
	// We will use a coordinate list to build the linearring
	CoordinateList *cl = new BasicCoordinateList(5);

	// Each coordinate in the list must be created,
	// passed to coordinate list setAt and then deleted.
	// Pretty boring uh ?
	Coordinate *c;
	c = new Coordinate(xoffset, yoffset);
	cl->setAt(*c ,0);
	delete c;
	c = new Coordinate(xoffset+side, yoffset);
	cl->setAt(*c ,1);
	delete c;
	c = new Coordinate(xoffset+side, yoffset+side);
	cl->setAt(*c ,2);
	delete c;
	c = new Coordinate(xoffset, yoffset+side);
	cl->setAt(*c ,3);
	delete c;
	c = new Coordinate(xoffset, yoffset);
	cl->setAt(*c ,4);
	delete c;

	// Now that we have a CoordinateList we can create
	// the linearring.
	LinearRing *lr = (LinearRing*) global_factory->createLinearRing(cl);

	// We don't need our CoordinateList anymore, it has been
	// copied inside the LinearRing object
	delete cl;

	return lr; // our LinearRing
}

// This function will create a Polygon
// geometry rapresenting a square with the given origin
// and side and with a central hole 1/3 sided.
Polygon *
create_square_polygon(double xoffset, double yoffset, double side)
{
	// We need a LinearRing for the polygon shell
	LinearRing *outer = create_square_linearring(xoffset,yoffset,side);

	// And another for the hole
	LinearRing *inner = create_square_linearring(xoffset+(side/3),
			yoffset+(side/3),(side/3));

	// If we need to specify any hole, we do it using
	// a vector of Geometry pointers (I don't know why
	// not LinearRings)
	vector<Geometry *> *holes = new vector<Geometry *>;

	// We add the newly created geometry to the vector
	// of holes.
	holes->push_back(inner);

	// And finally we call the polygon constructor.
	// Both the outer LinearRing and the vector of holes
	// will be referenced by the resulting Polygon object,
	// thus we CANNOT delete them, neither the holes, nor
	// the vector containing their pointers, nor the outer
	// LinearRing. Everything will be deleted at Polygon
	// deletion time (this is inconsistent with LinearRing
	// behaviour... what should we do?).
	Polygon *poly = global_factory->createPolygon(outer, holes);

	return poly;
}

// This function will create a GeoemtryCollection
// containing the two given Geometries.
// Note that given Geometries will be referenced
// by returned object, thus deleted at its destruction
// time.
//
GeometryCollection *
create_simple_collection(Geometry *g1, Geometry *g2)
{
	// We need to construct a <Geometry *> vector
	// to use as argument to the factory function
	vector<Geometry *> *collection = new vector<Geometry *>;

	// Now, we need to make copies of the given args
	// we do it using copy constructor.
	collection->push_back(g1);
	collection->push_back(g2);

	GeometryCollection *ret =
		global_factory->createGeometryCollection(collection);

	// We HAVE to delete the vectore used to store
	// goemetry pointers, but created object will
	// delete pointed geometries, weird uh?
	delete collection;

	return ret;
}

// Start reading here
void do_all()
{
	int numgeoms = 3;
	Geometry *geoms[numgeoms];

	// Define a precision model using 0,0 as the reference origin
	// and 2.0 as coordinates scale.
	// Using 1.0 as scale will segfault, dunno why --strk;
	PrecisionModel *pm = new PrecisionModel(2.0, 0, 0);

	// Initialize global factory with defined PrecisionModel
	// and a SRID of -1 (undefined).
	global_factory = new GeometryFactory(pm, -1);

	// We do not need PrecisionMode object anymore, it has
	// been copied to global_factory private storage
	delete pm;

	/////////////////////////////////////////////
	// BASIC GEOMETRY CREATION
	/////////////////////////////////////////////

	// Read function bodies to see the magic behind them
	geoms[0] = create_square_linearring(0,0,100);
	geoms[1] = create_square_polygon(0,200,300);

	// here we write this bad-looking code to copy
	// geometries before putting them in a collection
	// object, since it will take responsability about
	// passed arguments life.
	geoms[2] = create_simple_collection(
			new LinearRing(*((LinearRing *)geoms[0])),
			new Polygon(*((Polygon *)geoms[1])));

	// Print all geoms.
	cout<<"--------HERE ARE THE BASE GEOMS ----------"<<endl;
	wkt_print_geoms(numgeoms, geoms);

	/////////////////////////////////////////////
	// CONVEX HULL
	/////////////////////////////////////////////

	// Make convex hulls of geometries
	Geometry *hulls[numgeoms];
	for (int i=0; i<numgeoms; i++) {
		hulls[i] = geoms[i]->convexHull();
	}

	// Print all convex hulls
	cout<<"--------HERE COMES THE HULLS----------"<<endl;
	wkt_print_geoms(numgeoms, hulls);

	// Delete created geometries and hulls
	for (int i=0; i<numgeoms; i++) {
		delete geoms[i];
		delete hulls[i];
	}

	delete global_factory;
}

main()
{
	try
	{
		do_all();
	}
	// All exception thrown by GEOS are subclasses of this
	// one, so this is a catch-all
	catch (GEOSException *exc)
	{
		cerr <<"Generic exception: "<<exc->toString()<<"\n";
		exit(1);
	}
	// and this is a catch-all non standard ;)
	catch (...)
	{
		cerr <<"unknown exception trown!\n";
		exit(1);
	}

	// This is not really needed but to make
	// memory checker like valgrind quiet
	// about static heap-allocated data.
	Unload::Release();
}
<commit_msg>moved Log to a better place<commit_after>// This file should document by example usage of the GEOS library.
// It could actually be a live discuss-by-example board for
// architectural design choices.
// 			--strk;
//
// DEBUGGING TIPS:
//  use -D__USE_MALLOC at compile time for gcc 2.91, 2.95, 3.0 and 3.1
//  and GLIBCXX_FORCE_NEW or GLIBCPP_FORCE_NEW at run time with gcc 3.2.2+
//  to force libstdc++ avoid caching memory. This should remove some
//  obscure reports from memory checkers like valgrind.
//
// $Log$
// Revision 1.4  2003/10/09 11:20:12  strk
// moved Log to a better place
//
// Revision 1.3  2003/10/09 11:19:20  strk
// added convexHull and PrecisionModel
//
//
#include <stdio.h>
#include <io.h>
#include <geom.h>
#include <unload.h>

using namespace geos;

// This object will be used to construct our geometries.
// It might be bypassed by directly call geometry constructors,
// but that would be boring because you'd need to specify
// a PrecisionModel and a SRID everytime: those infos are
// cached inside a GeometryFactory object.
GeometryFactory *global_factory;

// This function will print given geometries in WKT
// format to stdout.
void
wkt_print_geoms(int numgeoms, Geometry **geoms)
{
	// WKT-print created geometries
	WKTWriter *wkt = new WKTWriter();
	for (int i=0; i<numgeoms; i++) {
		cout<<wkt->write(geoms[i])<<endl;
	}
	delete wkt;
}

// This function will create a LinearRing
// geometry rapresenting a square with the given origin
// and side
LinearRing *
create_square_linearring(double xoffset, double yoffset, double side)
{
	// We will use a coordinate list to build the linearring
	CoordinateList *cl = new BasicCoordinateList(5);

	// Each coordinate in the list must be created,
	// passed to coordinate list setAt and then deleted.
	// Pretty boring uh ?
	Coordinate *c;
	c = new Coordinate(xoffset, yoffset);
	cl->setAt(*c ,0);
	delete c;
	c = new Coordinate(xoffset+side, yoffset);
	cl->setAt(*c ,1);
	delete c;
	c = new Coordinate(xoffset+side, yoffset+side);
	cl->setAt(*c ,2);
	delete c;
	c = new Coordinate(xoffset, yoffset+side);
	cl->setAt(*c ,3);
	delete c;
	c = new Coordinate(xoffset, yoffset);
	cl->setAt(*c ,4);
	delete c;

	// Now that we have a CoordinateList we can create
	// the linearring.
	LinearRing *lr = (LinearRing*) global_factory->createLinearRing(cl);

	// We don't need our CoordinateList anymore, it has been
	// copied inside the LinearRing object
	delete cl;

	return lr; // our LinearRing
}

// This function will create a Polygon
// geometry rapresenting a square with the given origin
// and side and with a central hole 1/3 sided.
Polygon *
create_square_polygon(double xoffset, double yoffset, double side)
{
	// We need a LinearRing for the polygon shell
	LinearRing *outer = create_square_linearring(xoffset,yoffset,side);

	// And another for the hole
	LinearRing *inner = create_square_linearring(xoffset+(side/3),
			yoffset+(side/3),(side/3));

	// If we need to specify any hole, we do it using
	// a vector of Geometry pointers (I don't know why
	// not LinearRings)
	vector<Geometry *> *holes = new vector<Geometry *>;

	// We add the newly created geometry to the vector
	// of holes.
	holes->push_back(inner);

	// And finally we call the polygon constructor.
	// Both the outer LinearRing and the vector of holes
	// will be referenced by the resulting Polygon object,
	// thus we CANNOT delete them, neither the holes, nor
	// the vector containing their pointers, nor the outer
	// LinearRing. Everything will be deleted at Polygon
	// deletion time (this is inconsistent with LinearRing
	// behaviour... what should we do?).
	Polygon *poly = global_factory->createPolygon(outer, holes);

	return poly;
}

// This function will create a GeoemtryCollection
// containing the two given Geometries.
// Note that given Geometries will be referenced
// by returned object, thus deleted at its destruction
// time.
//
GeometryCollection *
create_simple_collection(Geometry *g1, Geometry *g2)
{
	// We need to construct a <Geometry *> vector
	// to use as argument to the factory function
	vector<Geometry *> *collection = new vector<Geometry *>;

	// Now, we need to make copies of the given args
	// we do it using copy constructor.
	collection->push_back(g1);
	collection->push_back(g2);

	GeometryCollection *ret =
		global_factory->createGeometryCollection(collection);

	// We HAVE to delete the vectore used to store
	// goemetry pointers, but created object will
	// delete pointed geometries, weird uh?
	delete collection;

	return ret;
}

// Start reading here
void do_all()
{
	int numgeoms = 3;
	Geometry *geoms[numgeoms];

	// Define a precision model using 0,0 as the reference origin
	// and 2.0 as coordinates scale.
	// Using 1.0 as scale will segfault, dunno why --strk;
	PrecisionModel *pm = new PrecisionModel(2.0, 0, 0);

	// Initialize global factory with defined PrecisionModel
	// and a SRID of -1 (undefined).
	global_factory = new GeometryFactory(pm, -1);

	// We do not need PrecisionMode object anymore, it has
	// been copied to global_factory private storage
	delete pm;

	/////////////////////////////////////////////
	// BASIC GEOMETRY CREATION
	/////////////////////////////////////////////

	// Read function bodies to see the magic behind them
	geoms[0] = create_square_linearring(0,0,100);
	geoms[1] = create_square_polygon(0,200,300);

	// here we write this bad-looking code to copy
	// geometries before putting them in a collection
	// object, since it will take responsability about
	// passed arguments life.
	geoms[2] = create_simple_collection(
			new LinearRing(*((LinearRing *)geoms[0])),
			new Polygon(*((Polygon *)geoms[1])));

	// Print all geoms.
	cout<<"--------HERE ARE THE BASE GEOMS ----------"<<endl;
	wkt_print_geoms(numgeoms, geoms);

	/////////////////////////////////////////////
	// CONVEX HULL
	/////////////////////////////////////////////

	// Make convex hulls of geometries
	Geometry *hulls[numgeoms];
	for (int i=0; i<numgeoms; i++) {
		hulls[i] = geoms[i]->convexHull();
	}

	// Print all convex hulls
	cout<<"--------HERE COMES THE HULLS----------"<<endl;
	wkt_print_geoms(numgeoms, hulls);

	// Delete created geometries and hulls
	for (int i=0; i<numgeoms; i++) {
		delete geoms[i];
		delete hulls[i];
	}

	delete global_factory;
}

main()
{
	try
	{
		do_all();
	}
	// All exception thrown by GEOS are subclasses of this
	// one, so this is a catch-all
	catch (GEOSException *exc)
	{
		cerr <<"Generic exception: "<<exc->toString()<<"\n";
		exit(1);
	}
	// and this is a catch-all non standard ;)
	catch (...)
	{
		cerr <<"unknown exception trown!\n";
		exit(1);
	}

	// This is not really needed but to make
	// memory checker like valgrind quiet
	// about static heap-allocated data.
	Unload::Release();
}
<|endoftext|>


<commit_before><commit_msg>add security check for data validation in FEM fluid boundary panel<commit_after><|endoftext|>