<commit_before>/** @file
    @brief Implementation

    @date 2015, 2016

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

// Copyright 2015, 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 "PoseEstimator_RANSAC.h"
#include "LED.h"
#include "CameraParameters.h"
#include "cvToEigen.h"

// Library/third-party includes
#include <opencv2/core/core.hpp>
#include <opencv2/calib3d/calib3d.hpp>

// Standard includes
#include <algorithm>

namespace osvr {
namespace vbtracker {
    bool RANSACPoseEstimator::operator()(CameraParameters const &camParams,
                                         LedPtrList const &leds,
                                         BeaconStateVec const &beacons,
                                         std::vector<BeaconData> &beaconDebug,
                                         Eigen::Vector3d &outXlate,
                                         Eigen::Quaterniond &outQuat) {

        // We need to get a pair of matched vectors of points: 2D locations
        // with in the image and 3D locations in model space.  There needs to
        // be a correspondence between the points in these vectors, such that
        // the ith element in one matches the ith element in the other.  We
        // make these by looking up the locations of LEDs with known identifiers
        // and pushing both onto the vectors at the same time.

        std::vector<cv::Point3f> objectPoints;
        std::vector<cv::Point2f> imagePoints;
        std::vector<ZeroBasedBeaconId> beaconIds;
        for (auto const &led : leds) {
            auto id = makeZeroBased(led->getID());
            auto index = asIndex(id);
            beaconDebug[index].variance = -1;
            beaconDebug[index].measurement = led->getLocationForTracking();
            beaconIds.push_back(id);

            /// Effectively invert the image points here so we get the output of
            /// a coordinate system we want.
            imagePoints.push_back(led->getLocationForTracking());
            objectPoints.push_back(
                vec3dToCVPoint3f(beacons[index]->stateVector()));
        }

        // Make sure we have enough points to do our estimation.
        if (objectPoints.size() < m_permittedOutliers + m_requiredInliers) {
            return false;
        }

        // Produce an estimate of the translation and rotation needed to take
        // points from model space into camera space.  We allow for at most
        // m_permittedOutliers outliers. Even in simulation data, we sometimes
        // find duplicate IDs for LEDs, indicating that we are getting
        // mis-identified ones sometimes.
        // We tried using the previous guess to reduce the amount of computation
        // being done, but this got us stuck in infinite locations.  We seem to
        // do okay without using it, so leaving it out.
        // @todo Make number of iterations into a parameter.
        bool usePreviousGuess = false;
        int iterationsCount = 5;
        cv::Mat inlierIndices;

        cv::Mat rvec;
        cv::Mat tvec;
#if CV_MAJOR_VERSION == 2
        cv::solvePnPRansac(
            objectPoints, imagePoints, camParams.cameraMatrix,
            camParams.distortionParameters, rvec, tvec, usePreviousGuess,
            iterationsCount, 8.0f,
            static_cast<int>(objectPoints.size() - m_permittedOutliers),
            inlierIndices);
#elif CV_MAJOR_VERSION == 3
        // parameter added to the OpenCV 3.0 interface in place of the number of
        // inliers
        /// @todo how to determine this requested confidence from the data we're
        /// given?
        double confidence = 0.99;
        auto ransacResult = cv::solvePnPRansac(
            objectPoints, imagePoints, camParams.cameraMatrix,
            camParams.distortionParameters, rvec, tvec, usePreviousGuess,
            iterationsCount, 8.0f, confidence, inlierIndices);
        if (!ransacResult) {
            return false;
        }
#else
#error "Unrecognized OpenCV version!"
#endif

        //==========================================================================
        // Make sure we got all the inliers we needed.  Otherwise, reject this
        // pose.
        if (inlierIndices.rows < static_cast<int>(m_requiredInliers)) {
            return false;
        }

        //==========================================================================
        // Reproject the inliers into the image and make sure they are actually
        // close to the expected location; otherwise, we have a bad pose.
        const double pixelReprojectionErrorForSingleAxisMax = 4;
        if (inlierIndices.rows > 0) {
            std::vector<cv::Point3f> inlierObjectPoints;
            std::vector<cv::Point2f> inlierImagePoints;
            std::vector<ZeroBasedBeaconId> inlierBeaconIds;
            for (int i = 0; i < inlierIndices.rows; i++) {
                inlierObjectPoints.push_back(objectPoints[i]);
                inlierImagePoints.push_back(imagePoints[i]);
                inlierBeaconIds.push_back(beaconIds[i]);
            }
            std::vector<cv::Point2f> reprojectedPoints;
            cv::projectPoints(
                inlierObjectPoints, rvec, tvec, camParams.cameraMatrix,
                camParams.distortionParameters, reprojectedPoints);

            for (size_t i = 0; i < reprojectedPoints.size(); i++) {
                if (reprojectedPoints[i].x - inlierImagePoints[i].x >
                    pixelReprojectionErrorForSingleAxisMax) {
                    return false;
                }
                if (reprojectedPoints[i].y - inlierImagePoints[i].y >
                    pixelReprojectionErrorForSingleAxisMax) {
                    return false;
                }
            }

            /// Now, we will sort that vector of inlier beacon IDs so we can
            /// rapidly binary search it to flag the LEDs we used.

            // Need a custom comparator for the ID type.
            auto idComparator = [](ZeroBasedBeaconId const &lhs,
                                   ZeroBasedBeaconId const &rhs) {
                return lhs.value() < rhs.value();
            };
            std::sort(begin(inlierBeaconIds), end(inlierBeaconIds),
                      idComparator);
            // This lambda wraps binary_search to do what it says: check to see
            // if a given beacon ID is in the list of inlier beacons.
            auto isAnInlierBeacon = [&inlierBeaconIds, &idComparator](
                ZeroBasedBeaconId const &needle) {
                return std::binary_search(begin(inlierBeaconIds),
                                          end(inlierBeaconIds), needle,
                                          idComparator);
            };
            for (auto &led : leds) {
                if (isAnInlierBeacon(led->getID())) {
                    led->markAsUsed();
                }
            }
        }

        //==========================================================================
        // Convert this into an OSVR representation of the transformation that
        // gives the pose of the HDK origin in the camera coordinate system,
        // switching units to meters and encoding the angle in a unit
        // quaternion.
        // The matrix described by rvec and tvec takes points in model space
        // (the space where the LEDs are defined, which is in mm away from an
        // implied origin) into a coordinate system where the center is at the
        // camera's origin, with X to the right, Y down, and Z in the direction
        // that the camera is facing (but still in the original units of mm):
        //  |Xc|   |r11 r12 r13 t1| |Xm|
        //  |Yc| = |r21 r22 r23 t2|*|Ym|
        //  |Zc|   |r31 r32 r33 t3| |Zm|
        //                          |1 |
        //  That is, it rotates into the camera coordinate system and then adds
        // the translation, which is in the camera coordinate system.
        //  This is the transformation we want, since it reports the sensor's
        // position and orientation in camera space, except that we want to
        // convert
        // the units into meters and the orientation into a Quaternion.
        //  NOTE: This is a right-handed coordinate system with X pointing
        // towards the right from the camera center of projection, Y pointing
        // down, and Z pointing along the camera viewing direction, if the input
        // points are not inverted.

        outXlate = cvToVector3d(tvec);
        outQuat = cvRotVecToQuat(rvec);
        return true;
    }

    /// Variance in Meters^2
    static const double InitialPositionStateError = 0.;
    /// Variance in Radians^2
    static const double InitialOrientationStateError = 0.5;
    static const double InitialVelocityStateError = 0.;
    static const double InitialAngVelStateError = 0.;
    static const double InitialStateError[] = {
        InitialPositionStateError,    InitialPositionStateError,
        InitialPositionStateError,    InitialOrientationStateError,
        InitialOrientationStateError, InitialOrientationStateError,
        InitialVelocityStateError,    InitialVelocityStateError,
        InitialVelocityStateError,    InitialAngVelStateError,
        InitialAngVelStateError,      InitialAngVelStateError};
    bool RANSACPoseEstimator::operator()(EstimatorInOutParams const &p,
                                         LedPtrList const &leds) {
        Eigen::Vector3d xlate;
        Eigen::Quaterniond quat;
        /// Call the main pose estimation to get the vector and quat.
        {
            auto ret = (*this)(p.camParams, leds, p.beacons, p.beaconDebug,
                               xlate, quat);
            if (!ret) {
                return false;
            }
        }
        /// OK, so if we're here, estimation succeeded and we have valid data in
        /// xlate and quat.
        p.state.position() = xlate;
        p.state.setQuaternion(quat);
/// Zero things we can't measure.
#if 1
        p.state.incrementalOrientation() = Eigen::Vector3d::Zero();
        p.state.velocity() = Eigen::Vector3d::Zero();
        p.state.angularVelocity() = Eigen::Vector3d::Zero();
#endif
        using StateVec = kalman::types::DimVector<BodyState>;
        using StateSquareMatrix = kalman::types::DimSquareMatrix<BodyState>;

        StateSquareMatrix covariance = StateVec(InitialStateError).asDiagonal();
        /// @todo Copy the existing angular velocity error covariance
        /*
        covariance.bottomRightCorner<3, 3>() =
            p.state.errorCovariance().bottomRightCorner<3, 3>();
            */
        p.state.setErrorCovariance(covariance);
        return true;
    }

} // namespace vbtracker
} // namespace osvr
<commit_msg>Pull out and name the max reprojection error.<commit_after>/** @file
    @brief Implementation

    @date 2015, 2016

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

// Copyright 2015, 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 "PoseEstimator_RANSAC.h"
#include "LED.h"
#include "CameraParameters.h"
#include "cvToEigen.h"

// Library/third-party includes
#include <opencv2/core/core.hpp>
#include <opencv2/calib3d/calib3d.hpp>

// Standard includes
#include <algorithm>

namespace osvr {
namespace vbtracker {
    bool RANSACPoseEstimator::operator()(CameraParameters const &camParams,
                                         LedPtrList const &leds,
                                         BeaconStateVec const &beacons,
                                         std::vector<BeaconData> &beaconDebug,
                                         Eigen::Vector3d &outXlate,
                                         Eigen::Quaterniond &outQuat) {

        // We need to get a pair of matched vectors of points: 2D locations
        // with in the image and 3D locations in model space.  There needs to
        // be a correspondence between the points in these vectors, such that
        // the ith element in one matches the ith element in the other.  We
        // make these by looking up the locations of LEDs with known identifiers
        // and pushing both onto the vectors at the same time.

        std::vector<cv::Point3f> objectPoints;
        std::vector<cv::Point2f> imagePoints;
        std::vector<ZeroBasedBeaconId> beaconIds;
        for (auto const &led : leds) {
            auto id = makeZeroBased(led->getID());
            auto index = asIndex(id);
            beaconDebug[index].variance = -1;
            beaconDebug[index].measurement = led->getLocationForTracking();
            beaconIds.push_back(id);

            /// Effectively invert the image points here so we get the output of
            /// a coordinate system we want.
            imagePoints.push_back(led->getLocationForTracking());
            objectPoints.push_back(
                vec3dToCVPoint3f(beacons[index]->stateVector()));
        }

        // Make sure we have enough points to do our estimation.
        if (objectPoints.size() < m_permittedOutliers + m_requiredInliers) {
            return false;
        }

        // Produce an estimate of the translation and rotation needed to take
        // points from model space into camera space.  We allow for at most
        // m_permittedOutliers outliers. Even in simulation data, we sometimes
        // find duplicate IDs for LEDs, indicating that we are getting
        // mis-identified ones sometimes.
        // We tried using the previous guess to reduce the amount of computation
        // being done, but this got us stuck in infinite locations.  We seem to
        // do okay without using it, so leaving it out.
        // @todo Make number of iterations into a parameter.
        bool usePreviousGuess = false;
        int iterationsCount = 5;
        float maxReprojectionError = 6.f;
        cv::Mat inlierIndices;

        cv::Mat rvec;
        cv::Mat tvec;
#if CV_MAJOR_VERSION == 2
        cv::solvePnPRansac(
            objectPoints, imagePoints, camParams.cameraMatrix,
            camParams.distortionParameters, rvec, tvec, usePreviousGuess,
            iterationsCount, maxReprojectionError,
            static_cast<int>(objectPoints.size() - m_permittedOutliers),
            inlierIndices);
#elif CV_MAJOR_VERSION == 3
        // parameter added to the OpenCV 3.0 interface in place of the number of
        // inliers
        /// @todo how to determine this requested confidence from the data we're
        /// given?
        double confidence = 0.99;
        auto ransacResult = cv::solvePnPRansac(
            objectPoints, imagePoints, camParams.cameraMatrix,
            camParams.distortionParameters, rvec, tvec, usePreviousGuess,
            iterationsCount, maxReprojectionError, confidence, inlierIndices);
        if (!ransacResult) {
            return false;
        }
#else
#error "Unrecognized OpenCV version!"
#endif

        //==========================================================================
        // Make sure we got all the inliers we needed.  Otherwise, reject this
        // pose.
        if (inlierIndices.rows < static_cast<int>(m_requiredInliers)) {
            return false;
        }

        //==========================================================================
        // Reproject the inliers into the image and make sure they are actually
        // close to the expected location; otherwise, we have a bad pose.
        const double pixelReprojectionErrorForSingleAxisMax = 4;
        if (inlierIndices.rows > 0) {
            std::vector<cv::Point3f> inlierObjectPoints;
            std::vector<cv::Point2f> inlierImagePoints;
            std::vector<ZeroBasedBeaconId> inlierBeaconIds;
            for (int i = 0; i < inlierIndices.rows; i++) {
                inlierObjectPoints.push_back(objectPoints[i]);
                inlierImagePoints.push_back(imagePoints[i]);
                inlierBeaconIds.push_back(beaconIds[i]);
            }
            std::vector<cv::Point2f> reprojectedPoints;
            cv::projectPoints(
                inlierObjectPoints, rvec, tvec, camParams.cameraMatrix,
                camParams.distortionParameters, reprojectedPoints);

            for (size_t i = 0; i < reprojectedPoints.size(); i++) {
                if (reprojectedPoints[i].x - inlierImagePoints[i].x >
                    pixelReprojectionErrorForSingleAxisMax) {
                    return false;
                }
                if (reprojectedPoints[i].y - inlierImagePoints[i].y >
                    pixelReprojectionErrorForSingleAxisMax) {
                    return false;
                }
            }

            /// Now, we will sort that vector of inlier beacon IDs so we can
            /// rapidly binary search it to flag the LEDs we used.

            // Need a custom comparator for the ID type.
            auto idComparator = [](ZeroBasedBeaconId const &lhs,
                                   ZeroBasedBeaconId const &rhs) {
                return lhs.value() < rhs.value();
            };
            std::sort(begin(inlierBeaconIds), end(inlierBeaconIds),
                      idComparator);
            // This lambda wraps binary_search to do what it says: check to see
            // if a given beacon ID is in the list of inlier beacons.
            auto isAnInlierBeacon = [&inlierBeaconIds, &idComparator](
                ZeroBasedBeaconId const &needle) {
                return std::binary_search(begin(inlierBeaconIds),
                                          end(inlierBeaconIds), needle,
                                          idComparator);
            };
            for (auto &led : leds) {
                if (isAnInlierBeacon(led->getID())) {
                    led->markAsUsed();
                }
            }
        }

        //==========================================================================
        // Convert this into an OSVR representation of the transformation that
        // gives the pose of the HDK origin in the camera coordinate system,
        // switching units to meters and encoding the angle in a unit
        // quaternion.
        // The matrix described by rvec and tvec takes points in model space
        // (the space where the LEDs are defined, which is in mm away from an
        // implied origin) into a coordinate system where the center is at the
        // camera's origin, with X to the right, Y down, and Z in the direction
        // that the camera is facing (but still in the original units of mm):
        //  |Xc|   |r11 r12 r13 t1| |Xm|
        //  |Yc| = |r21 r22 r23 t2|*|Ym|
        //  |Zc|   |r31 r32 r33 t3| |Zm|
        //                          |1 |
        //  That is, it rotates into the camera coordinate system and then adds
        // the translation, which is in the camera coordinate system.
        //  This is the transformation we want, since it reports the sensor's
        // position and orientation in camera space, except that we want to
        // convert
        // the units into meters and the orientation into a Quaternion.
        //  NOTE: This is a right-handed coordinate system with X pointing
        // towards the right from the camera center of projection, Y pointing
        // down, and Z pointing along the camera viewing direction, if the input
        // points are not inverted.

        outXlate = cvToVector3d(tvec);
        outQuat = cvRotVecToQuat(rvec);
        return true;
    }

    /// Variance in Meters^2
    static const double InitialPositionStateError = 0.;
    /// Variance in Radians^2
    static const double InitialOrientationStateError = 0.5;
    static const double InitialVelocityStateError = 0.;
    static const double InitialAngVelStateError = 0.;
    static const double InitialStateError[] = {
        InitialPositionStateError,    InitialPositionStateError,
        InitialPositionStateError,    InitialOrientationStateError,
        InitialOrientationStateError, InitialOrientationStateError,
        InitialVelocityStateError,    InitialVelocityStateError,
        InitialVelocityStateError,    InitialAngVelStateError,
        InitialAngVelStateError,      InitialAngVelStateError};
    bool RANSACPoseEstimator::operator()(EstimatorInOutParams const &p,
                                         LedPtrList const &leds) {
        Eigen::Vector3d xlate;
        Eigen::Quaterniond quat;
        /// Call the main pose estimation to get the vector and quat.
        {
            auto ret = (*this)(p.camParams, leds, p.beacons, p.beaconDebug,
                               xlate, quat);
            if (!ret) {
                return false;
            }
        }
        /// OK, so if we're here, estimation succeeded and we have valid data in
        /// xlate and quat.
        p.state.position() = xlate;
        p.state.setQuaternion(quat);
/// Zero things we can't measure.
#if 1
        p.state.incrementalOrientation() = Eigen::Vector3d::Zero();
        p.state.velocity() = Eigen::Vector3d::Zero();
        p.state.angularVelocity() = Eigen::Vector3d::Zero();
#endif
        using StateVec = kalman::types::DimVector<BodyState>;
        using StateSquareMatrix = kalman::types::DimSquareMatrix<BodyState>;

        StateSquareMatrix covariance = StateVec(InitialStateError).asDiagonal();
        /// @todo Copy the existing angular velocity error covariance
        /*
        covariance.bottomRightCorner<3, 3>() =
            p.state.errorCovariance().bottomRightCorner<3, 3>();
            */
        p.state.setErrorCovariance(covariance);
        return true;
    }

} // namespace vbtracker
} // namespace osvr
<|endoftext|>


<commit_before>#include "libpixel/graphics/device/device.h"
#include "libpixel/graphics/render/primitive/primitiveRenderer.h"

namespace libpixel
{

PrimitiveRenderer::PrimitiveRenderer()
{

}

PrimitiveRenderer::~PrimitiveRenderer()
{

}

void PrimitiveRenderer::RenderEllipse(Vec2 position, Vec2 size, Vec3 rotation, Vec4 color, int segments)
{
    glEnable(GL_BLEND);

    glPushMatrix();

    glTranslatef(position[0], position[1], 0.f);
    glScalef(size[0], size[1], 1.f);
    glRotatef(rotation[0], 1, 0, 0);
    glRotatef(rotation[1], 0, 1, 0);
    glRotatef(rotation[2], 0, 0, 1);

    glColor4f(color[0], color[1], color[2], color[3]);

    GLfloat glVertices[segments*2];

    float angle = 0;
    for (int i=0; i<segments*2; i+=2)
    {
        angle += M_PI/(segments/2);

        glVertices[i] = cos(angle);
        glVertices[i+1] = sin(angle);
    }

    glVertexPointer(2, GL_FLOAT, 0, glVertices);

    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_LINE_LOOP, 0, segments);

    glPopMatrix();

    glDisable(GL_BLEND);
}

void PrimitiveRenderer::RenderLine(Vec2 start, Vec2 end, Vec4 color)
{
    glEnable(GL_BLEND);

    glPushMatrix();

    glColor4f(color[0], color[1], color[2], color[3]);

    GLfloat glVertices[] = { start[0], start[1], end[0], end[1] };

    glVertexPointer(2, GL_FLOAT, 0, glVertices);

    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_LINES, 0, 2);

    glColor4f(1.f, 1.f, 1.f, 1.f);

    glPopMatrix();

    glDisable(GL_BLEND);
}

void PrimitiveRenderer::RenderBox(Vec2 position, Vec2 size, Vec4 color)
{
    glEnable(GL_BLEND);

    glColor4f(color[0], color[1], color[2], color[3]);

    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    Vec2 tl(position[0] - size[0]/2.f, position[1] - size[1]/2.f);
    Vec2 br(position[0] + size[0]/2.f, position[1] + size[1]/2.f);

    GLfloat glVertices[8] = { tl[0], br[1], tl[0], tl[1], br[0], tl[1], br[0], br[1] };
    glVertexPointer(2, GL_FLOAT, 0, glVertices);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);

    glDisable(GL_BLEND);
}

}
<commit_msg>Fix alpha blending in primitive renderer<commit_after>#include "libpixel/graphics/device/device.h"
#include "libpixel/graphics/render/primitive/primitiveRenderer.h"

namespace libpixel
{

PrimitiveRenderer::PrimitiveRenderer()
{

}

PrimitiveRenderer::~PrimitiveRenderer()
{

}

void PrimitiveRenderer::RenderEllipse(Vec2 position, Vec2 size, Vec3 rotation, Vec4 color, int segments)
{
    glEnable(GL_BLEND);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glPushMatrix();

    glTranslatef(position[0], position[1], 0.f);
    glScalef(size[0], size[1], 1.f);
    glRotatef(rotation[0], 1, 0, 0);
    glRotatef(rotation[1], 0, 1, 0);
    glRotatef(rotation[2], 0, 0, 1);

    glColor4f(color[0], color[1], color[2], color[3]);

    GLfloat glVertices[segments*2];

    float angle = 0;
    for (int i=0; i<segments*2; i+=2)
    {
        angle += M_PI/(segments/2);

        glVertices[i] = cos(angle);
        glVertices[i+1] = sin(angle);
    }

    glVertexPointer(2, GL_FLOAT, 0, glVertices);

    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_LINE_LOOP, 0, segments);

    glPopMatrix();

    glColor4f(1.f, 1.f, 1.f, 1.f);

    glDisable(GL_BLEND);
}

void PrimitiveRenderer::RenderLine(Vec2 start, Vec2 end, Vec4 color)
{
    glEnable(GL_BLEND);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glPushMatrix();

    glColor4f(color[0], color[1], color[2], color[3]);

    GLfloat glVertices[] = { start[0], start[1], end[0], end[1] };

    glVertexPointer(2, GL_FLOAT, 0, glVertices);

    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_LINES, 0, 2);

    glColor4f(1.f, 1.f, 1.f, 1.f);

    glPopMatrix();

    glDisable(GL_BLEND);
}

void PrimitiveRenderer::RenderBox(Vec2 position, Vec2 size, Vec4 color)
{
    glEnable(GL_BLEND);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glColor4f(color[0], color[1], color[2], color[3]);

    glEnableClientState(GL_VERTEX_ARRAY);

    Vec2 tl(position[0] - size[0]/2.f, position[1] - size[1]/2.f);
    Vec2 br(position[0] + size[0]/2.f, position[1] + size[1]/2.f);

    GLfloat glVertices[8] = { tl[0], br[1], tl[0], tl[1], br[0], tl[1], br[0], br[1] };
    glVertexPointer(2, GL_FLOAT, 0, glVertices);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);

    glColor4f(1.f, 1.f, 1.f, 1.f);

    glDisable(GL_BLEND);
}

}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/framework/executor.h"

#include <algorithm>
#include <iostream>
#include <memory>
#include <set>
#include <vector>

#include "paddle/framework/lod_tensor.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/scope.h"

#include <boost/range/adaptor/reversed.hpp>

namespace paddle {
namespace framework {

const std::string kFeedOpType = "feed";
const std::string kFetchOpType = "fetch";

Executor::Executor(const std::vector<platform::Place>& places) {
  PADDLE_ENFORCE_GT(places.size(), 0);
  device_contexts_.resize(places.size());
  for (size_t i = 0; i < places.size(); i++) {
    if (platform::is_cpu_place(places[i])) {
      device_contexts_[i] = new platform::CPUDeviceContext(
          boost::get<platform::CPUPlace>(places[i]));
    } else if (platform::is_gpu_place(places[i])) {
#ifdef PADDLE_WITH_CUDA
      device_contexts_[i] = new platform::CUDADeviceContext(
          boost::get<platform::GPUPlace>(places[i]));
#else
      PADDLE_THROW(
          "'GPUPlace' is not supported, Please re-compile with WITH_GPU "
          "option");
#endif
    }
  }
}

Executor::~Executor() {
  for (auto& device_context : device_contexts_) {
    delete device_context;
  }
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id) {
  // TODO(tonyyang-svail):
  //    - only runs on the first device (i.e. no interdevice communication)
  //    - will change to use multiple blocks for RNN op and Cond Op
  PADDLE_ENFORCE_GT(pdesc.blocks_size(), block_id);
  auto& block = pdesc.blocks(block_id);
  auto& device = device_contexts_[0];

  // Instantiate all the vars in the global scope
  for (auto& var : block.vars()) {
    scope->NewVar(var.name());
  }

  Scope& local_scope = scope->NewScope();

  std::vector<bool> should_run = Prune(pdesc, block_id);
  PADDLE_ENFORCE_EQ(should_run.size(), static_cast<size_t>(block.ops_size()));
  for (size_t i = 0; i < should_run.size(); ++i) {
    if (should_run[i]) {
      for (auto& var : block.ops(i).outputs()) {
        for (auto& argu : var.arguments()) {
          if (local_scope.FindVar(argu) == nullptr) {
            local_scope.NewVar(argu);
          }
        }
      }
      auto op = paddle::framework::OpRegistry::CreateOp(block.ops(i));
      op->Run(local_scope, *device);
    }
  }

  // TODO(tonyyang-svail):
  //  - Destroy local_scope
}

std::vector<bool> Executor::Prune(const ProgramDesc& pdesc, int block_id) {
  // TODO(tonyyang-svail):
  //    - will change to use multiple blocks for RNN op and Cond Op

  auto& block = pdesc.blocks(block_id);
  auto& ops = block.ops();

  bool expect_feed = true;
  for (auto& op_desc : ops) {
    PADDLE_ENFORCE(op_desc.type() != kFeedOpType || expect_feed,
                   "All FeedOps are at the beginning of the ProgramDesc");
    expect_feed = (op_desc.type() == kFeedOpType);
  }

  bool expect_fetch = true;
  for (auto op_iter = ops.rbegin(); op_iter != ops.rend(); ++op_iter) {
    auto& op_desc = *op_iter;
    PADDLE_ENFORCE(op_desc.type() != kFetchOpType || expect_fetch,
                   "All FetchOps must at the end of the ProgramDesc");
    expect_fetch = (op_desc.type() == kFetchOpType);
  }

  std::set<std::string> dependent_vars;
  std::vector<bool> should_run;
  for (auto op_iter = ops.rbegin(); op_iter != ops.rend(); ++op_iter) {
    auto& op_desc = *op_iter;

    bool found_dependent_vars = false;
    for (auto& var : op_desc.outputs()) {
      for (auto& argu : var.arguments()) {
        if (dependent_vars.count(argu) != 0) {
          found_dependent_vars = true;
        }
      }
    }

    if (op_desc.type() == kFetchOpType || found_dependent_vars) {
      // erase its output to the dependency graph
      for (auto& var : op_desc.outputs()) {
        for (auto& argu : var.arguments()) {
          dependent_vars.erase(argu);
        }
      }

      // insert its input to the dependency graph
      for (auto& var : op_desc.inputs()) {
        for (auto& argu : var.arguments()) {
          dependent_vars.insert(argu);
        }
      }

      should_run.push_back(true);
    } else {
      should_run.push_back(false);
    }
  }

  // TODO(tonyyang-svail):
  //    - check this after integration of Init
  // PADDLE_ENFORCE(dependent_vars.empty());

  // since we are traversing the ProgramDesc in reverse order
  // we reverse the should_run vector
  std::reverse(should_run.begin(), should_run.end());

  return should_run;
}

Executor::Executor(const std::vector<platform::Place>& places) {
  PADDLE_ENFORCE_GT(places.size(), 0);
  device_contexts_.resize(places.size());
  for (size_t i = 0; i < places.size(); i++) {
    if (platform::is_cpu_place(places[i])) {
      device_contexts_[i] = new platform::CPUDeviceContext(
          boost::get<platform::CPUPlace>(places[i]));
    } else if (platform::is_gpu_place(places[i])) {
#ifdef PADDLE_WITH_CUDA
      device_contexts_[i] = new platform::CUDADeviceContext(
          boost::get<platform::GPUPlace>(places[i]));
#else
      PADDLE_THROW("'GPUPlace' is not supported in CPU only device.");
#endif
    }
  }
}

Executor::~Executor() {
  for (auto& device_context : device_contexts_) {
    delete device_context;
  }
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id) {
  // TODO(tonyyang-svail):
  //    - only runs on the first device (i.e. no interdevice communication)
  //    - will change to use multiple blocks for RNN op and Cond Op
  PADDLE_ENFORCE_GT(pdesc.blocks_size(), block_id);
  auto& block = pdesc.blocks(block_id);
  auto& device = device_contexts_[0];

  // Instantiate all the vars in the global scope
  for (auto& var : block.vars()) {
    scope->NewVar(var.name());
  }

  Scope& local_scope = scope->NewScope();

  std::vector<bool> should_run = Prune(pdesc, block_id);
  PADDLE_ENFORCE_EQ(should_run.size(), static_cast<size_t>(block.ops_size()));
  for (size_t i = 0; i < should_run.size(); ++i) {
    if (should_run[i]) {
      for (auto& var : block.ops(i).outputs()) {
        for (auto& argu : var.arguments()) {
          if (local_scope.FindVar(argu) == nullptr) {
            local_scope.NewVar(argu);
          }
        }
      }
      auto op = paddle::framework::OpRegistry::CreateOp(block.ops(i));
      op->Run(local_scope, *device);
    }
  }

  // TODO(tonyyang-svail):
  //  - Destroy local_scope
}

}  // namespace framework
}  // namespace paddle
<commit_msg>clean up for merge<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/framework/executor.h"

#include <algorithm>
#include <iostream>
#include <memory>
#include <set>
#include <vector>

#include "paddle/framework/lod_tensor.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/scope.h"

#include <boost/range/adaptor/reversed.hpp>

namespace paddle {
namespace framework {

const std::string kFeedOpType = "feed";
const std::string kFetchOpType = "fetch";

Executor::Executor(const std::vector<platform::Place>& places) {
  PADDLE_ENFORCE_GT(places.size(), 0);
  device_contexts_.resize(places.size());
  for (size_t i = 0; i < places.size(); i++) {
    if (platform::is_cpu_place(places[i])) {
      device_contexts_[i] = new platform::CPUDeviceContext(
          boost::get<platform::CPUPlace>(places[i]));
    } else if (platform::is_gpu_place(places[i])) {
#ifdef PADDLE_WITH_CUDA
      device_contexts_[i] = new platform::CUDADeviceContext(
          boost::get<platform::GPUPlace>(places[i]));
#else
      PADDLE_THROW(
          "'GPUPlace' is not supported, Please re-compile with WITH_GPU "
          "option");
#endif
    }
  }
}

Executor::~Executor() {
  for (auto& device_context : device_contexts_) {
    delete device_context;
  }
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id) {
  // TODO(tonyyang-svail):
  //    - only runs on the first device (i.e. no interdevice communication)
  //    - will change to use multiple blocks for RNN op and Cond Op
  PADDLE_ENFORCE_GT(pdesc.blocks_size(), block_id);
  auto& block = pdesc.blocks(block_id);
  auto& device = device_contexts_[0];

  // Instantiate all the vars in the global scope
  for (auto& var : block.vars()) {
    scope->NewVar(var.name());
  }

  Scope& local_scope = scope->NewScope();

  std::vector<bool> should_run = Prune(pdesc, block_id);
  PADDLE_ENFORCE_EQ(should_run.size(), static_cast<size_t>(block.ops_size()));
  for (size_t i = 0; i < should_run.size(); ++i) {
    if (should_run[i]) {
      for (auto& var : block.ops(i).outputs()) {
        for (auto& argu : var.arguments()) {
          if (local_scope.FindVar(argu) == nullptr) {
            local_scope.NewVar(argu);
          }
        }
      }
      auto op = paddle::framework::OpRegistry::CreateOp(block.ops(i));
      op->Run(local_scope, *device);
    }
  }

  // TODO(tonyyang-svail):
  //  - Destroy local_scope
}

std::vector<bool> Prune(const ProgramDesc& pdesc, int block_id) {
  // TODO(tonyyang-svail):
  //    - will change to use multiple blocks for RNN op and Cond Op

  auto& block = pdesc.blocks(block_id);
  auto& ops = block.ops();

  bool expect_feed = true;
  for (auto& op_desc : ops) {
    PADDLE_ENFORCE(op_desc.type() != kFeedOpType || expect_feed,
                   "All FeedOps are at the beginning of the ProgramDesc");
    expect_feed = (op_desc.type() == kFeedOpType);
  }

  bool expect_fetch = true;
  for (auto op_iter = ops.rbegin(); op_iter != ops.rend(); ++op_iter) {
    auto& op_desc = *op_iter;
    PADDLE_ENFORCE(op_desc.type() != kFetchOpType || expect_fetch,
                   "All FetchOps must at the end of the ProgramDesc");
    expect_fetch = (op_desc.type() == kFetchOpType);
  }

  std::set<std::string> dependent_vars;
  std::vector<bool> should_run;
  for (auto op_iter = ops.rbegin(); op_iter != ops.rend(); ++op_iter) {
    auto& op_desc = *op_iter;

    bool found_dependent_vars = false;
    for (auto& var : op_desc.outputs()) {
      for (auto& argu : var.arguments()) {
        if (dependent_vars.count(argu) != 0) {
          found_dependent_vars = true;
        }
      }
    }

    if (op_desc.type() == kFetchOpType || found_dependent_vars) {
      // erase its output to the dependency graph
      for (auto& var : op_desc.outputs()) {
        for (auto& argu : var.arguments()) {
          dependent_vars.erase(argu);
        }
      }

      // insert its input to the dependency graph
      for (auto& var : op_desc.inputs()) {
        for (auto& argu : var.arguments()) {
          dependent_vars.insert(argu);
        }
      }

      should_run.push_back(true);
    } else {
      should_run.push_back(false);
    }
  }

  // TODO(tonyyang-svail):
  //    - check this after integration of Init
  // PADDLE_ENFORCE(dependent_vars.empty());

  // since we are traversing the ProgramDesc in reverse order
  // we reverse the should_run vector
  std::reverse(should_run.begin(), should_run.end());

  return should_run;
}

}  // namespace framework
}  // namespace paddle
<|endoftext|>


<commit_before>#include "EntityEditor.hpp"

#include <Engine/Component/Animation.hpp>
#include <Engine/Component/Physics.hpp>
#include <Engine/Component/Mesh.hpp>
#include <Engine/Component/Lens.hpp>
#include <Engine/Component/Material.hpp>
#include <Engine/Component/DirectionalLight.hpp>
#include <Engine/Component/PointLight.hpp>
#include <Engine/Component/SpotLight.hpp>
#include <Engine/Component/Listener.hpp>
#include <Engine/Component/Script.hpp>
#include <Engine/Component/SoundSource.hpp>
#include <Engine/Component/ParticleEmitter.hpp>
#include <Engine/Hymn.hpp>
#include <Engine/Geometry/Model.hpp>
#include <Engine/Geometry/RiggedModel.hpp>
#include <Engine/Texture/Texture2D.hpp>
#include <Engine/Audio/SoundBuffer.hpp>
#include <Engine/Script/ScriptFile.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>

#include "../../Util/EditorSettings.hpp"
#include "../FileSelector.hpp"

using namespace GUI;

EntityEditor::EntityEditor() {
    name[0] = '\0';
    AddEditor<Component::Animation>("Animation", std::bind(&EntityEditor::AnimationEditor, this, std::placeholders::_1));
    AddEditor<Component::Physics>("Physics", std::bind(&EntityEditor::PhysicsEditor, this, std::placeholders::_1));
    AddEditor<Component::Mesh>("Mesh", std::bind(&EntityEditor::MeshEditor, this, std::placeholders::_1));
    AddEditor<Component::Lens>("Lens", std::bind(&EntityEditor::LensEditor, this, std::placeholders::_1));
    AddEditor<Component::Material>("Material", std::bind(&EntityEditor::MaterialEditor, this, std::placeholders::_1));
    AddEditor<Component::DirectionalLight>("Directional light", std::bind(&EntityEditor::DirectionalLightEditor, this, std::placeholders::_1));
    AddEditor<Component::PointLight>("Point light", std::bind(&EntityEditor::PointLightEditor, this, std::placeholders::_1));
    AddEditor<Component::SpotLight>("Spot light", std::bind(&EntityEditor::SpotLightEditor, this, std::placeholders::_1));
    AddEditor<Component::Listener>("Listener", std::bind(&EntityEditor::ListenerEditor, this, std::placeholders::_1));
    AddEditor<Component::Script>("Script", std::bind(&EntityEditor::ScriptEditor, this, std::placeholders::_1));
    AddEditor<Component::SoundSource>("Sound source", std::bind(&EntityEditor::SoundSourceEditor, this, std::placeholders::_1));
    AddEditor<Component::ParticleEmitter>("Particle emitter", std::bind(&EntityEditor::ParticleEmitterEditor, this, std::placeholders::_1));
}

EntityEditor::~EntityEditor() {

}

void EntityEditor::Show() {
    if (ImGui::Begin(("Entity: " + entity->name + "###" + std::to_string(reinterpret_cast<uintptr_t>(entity))).c_str(), &visible)) {
        ImGui::InputText("Name", name, 128);
        entity->name = name;
        ImGui::Text("Transform");
        ImGui::Indent();
        ImGui::InputFloat3("Position", &entity->position[0]);
        ImGui::InputFloat3("Rotation", &entity->rotation[0]);
        ImGui::InputFloat3("Scale", &entity->scale[0]);
        ImGui::Unindent();
        if (!entity->IsScene()) {
            if (ImGui::Button("Add component"))
                ImGui::OpenPopup("Add component");

            if (ImGui::BeginPopup("Add component")) {
                ImGui::Text("Components");
                ImGui::Separator();

                for (Editor& editor : editors) {
                    editor.addFunction();
                }

                ImGui::EndPopup();
            }

            for (Editor& editor : editors) {
                editor.editFunction();
            }
        }
    }

    ImGui::End();
}

void EntityEditor::SetEntity(Entity* entity) {
    this->entity = entity;
    strcpy(name, entity->name.c_str());
}

bool EntityEditor::ShowsEntity(Entity* entity) {
    return this->entity == entity;
}

bool EntityEditor::IsVisible() const {
    return visible;
}

void EntityEditor::SetVisible(bool visible) {
    this->visible = visible;
}

void EntityEditor::AnimationEditor(Component::Animation* animation) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Animation"))
        ImGui::OpenPopup("Select model##Animation");

    if (ImGui::BeginPopup("Select model##Animation")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                animation->riggedModel = dynamic_cast<Geometry::RiggedModel*>(model);
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::PhysicsEditor(Component::Physics* physics) {
    ImGui::Text("Positional");
    ImGui::Indent();
    ImGui::InputFloat3("Velocity", &physics->velocity[0]);
    ImGui::InputFloat("Max velocity", &physics->maxVelocity);
    ImGui::InputFloat3("Acceleration", &physics->acceleration[0]);
    ImGui::InputFloat("Velocity drag factor", &physics->velocityDragFactor);
    ImGui::InputFloat("Gravity factor", &physics->gravityFactor);
    ImGui::Unindent();
    ImGui::Text("Angular");
    ImGui::Indent();
    ImGui::InputFloat3("Angular velocity", &physics->angularVelocity[0]);
    ImGui::InputFloat("Max angular velocity", &physics->maxAngularVelocity);
    ImGui::InputFloat3("Angular acceleration", &physics->angularAcceleration[0]);
    ImGui::InputFloat("Angular drag factor", &physics->angularDragFactor);
    ImGui::InputFloat3("Moment of inertia", &physics->momentOfInertia[0]);
    ImGui::Unindent();

}

void EntityEditor::MeshEditor(Component::Mesh* mesh) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Mesh"))
        ImGui::OpenPopup("Select model##Mesh");

    if (ImGui::BeginPopup("Select model##Mesh")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                mesh->geometry = model;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::LensEditor(Component::Lens* lens) {
    ImGui::Indent();
    ImGui::InputFloat("Field of view", &lens->fieldOfView);
    ImGui::InputFloat("Z near", &lens->zNear);
    ImGui::InputFloat("Z far", &lens->zFar);
    ImGui::Unindent();
}

void EntityEditor::MaterialEditor(Component::Material* material) {
    // Diffuse
    ImGui::Text("Diffuse");
    ImGui::Indent();
    if (ImGui::Button("Select diffuse texture"))
        ImGui::OpenPopup("Select diffuse texture");

    if (ImGui::BeginPopup("Select diffuse texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->diffuse = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Normal
    ImGui::Text("Normal");
    ImGui::Indent();
    if (ImGui::Button("Select normal texture"))
        ImGui::OpenPopup("Select normal texture");

    if (ImGui::BeginPopup("Select normal texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->normal = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Specular
    ImGui::Text("Specular");
    ImGui::Indent();
    if (ImGui::Button("Select specular texture"))
        ImGui::OpenPopup("Select specular texture");

    if (ImGui::BeginPopup("Select specular texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->specular = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Glow
    ImGui::Text("Glow");
    ImGui::Indent();
    if (ImGui::Button("Select glow texture"))
        ImGui::OpenPopup("Select glow texture");

    if (ImGui::BeginPopup("Select glow texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->glow = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::DirectionalLightEditor(Component::DirectionalLight* directionalLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &directionalLight->color[0]);
    ImGui::InputFloat("Ambient coefficient", &directionalLight->ambientCoefficient);
    ImGui::Unindent();
}

void EntityEditor::PointLightEditor(Component::PointLight* pointLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &pointLight->color[0]);
    ImGui::InputFloat("Ambient coefficient", &pointLight->ambientCoefficient);
    ImGui::InputFloat("Attenuation", &pointLight->attenuation);
    ImGui::InputFloat("Intensity", &pointLight->intensity);
    ImGui::Unindent();
}

void EntityEditor::SpotLightEditor(Component::SpotLight* spotLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &spotLight->color[0]);
    ImGui::InputFloat("Ambient coefficient", &spotLight->ambientCoefficient);
    ImGui::InputFloat("Attenuation", &spotLight->attenuation);
    ImGui::InputFloat("Intensity", &spotLight->intensity);
    ImGui::InputFloat("Cone angle", &spotLight->coneAngle);
    ImGui::Unindent();
}

void EntityEditor::ListenerEditor(Component::Listener* listener) {

}

void EntityEditor::ScriptEditor(Component::Script* script) {
    ImGui::Indent();
    if(script->scriptFile != nullptr)
        ImGui::Text(script->scriptFile->name.c_str());
    else
        ImGui::Text("No script loaded");

    if (ImGui::Button("Select script"))
        ImGui::OpenPopup("Select script");

    if (ImGui::BeginPopup("Select script")) {
        ImGui::Text("Scripts");
        ImGui::Separator();

        for (ScriptFile* scriptFile : Hymn().scripts) {
            if (ImGui::Selectable(scriptFile->name.c_str()))
                script->scriptFile = scriptFile;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::SoundSourceEditor(Component::SoundSource* soundSource) {
    ImGui::Text("Sound");
    ImGui::Indent();
    if (ImGui::Button("Select sound"))
        ImGui::OpenPopup("Select sound");

    if (ImGui::BeginPopup("Select sound")) {
        ImGui::Text("Sounds");
        ImGui::Separator();

        for (Audio::SoundBuffer* sound : Hymn().sounds) {
            if (ImGui::Selectable(sound->name.c_str()))
                soundSource->soundBuffer = sound;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
    ImGui::Text("Sound properties");
    ImGui::Indent();
    ImGui::InputFloat("Pitch", &soundSource->pitch);
    ImGui::InputFloat("Gain", &soundSource->gain);
    ImGui::Checkbox("Loop", &soundSource->loop);
    ImGui::Unindent();
}

void EntityEditor::ParticleEmitterEditor(Component::ParticleEmitter* particleEmitter) {
    ImGui::Text("Particle");
    ImGui::Indent();
    ImGui::InputInt("Texture index", &particleEmitter->particleType.textureIndex);
    ImGui::InputFloat3("Min velocity", &particleEmitter->particleType.minVelocity[0]);
    ImGui::InputFloat3("Max velocity", &particleEmitter->particleType.maxVelocity[0]);
    ImGui::InputFloat("Min lifetime", &particleEmitter->particleType.minLifetime);
    ImGui::InputFloat("Max lifetime", &particleEmitter->particleType.maxLifetime);
    ImGui::InputFloat2("Min size", &particleEmitter->particleType.minSize[0]);
    ImGui::InputFloat2("Max size", &particleEmitter->particleType.maxSize[0]);
    ImGui::Checkbox("Uniform scaling", &particleEmitter->particleType.uniformScaling);
    ImGui::InputFloat("Start alpha", &particleEmitter->particleType.startAlpha);
    ImGui::InputFloat("Mid alpha", &particleEmitter->particleType.midAlpha);
    ImGui::InputFloat("End alpha", &particleEmitter->particleType.endAlpha);
    ImGui::InputFloat3("Color", &particleEmitter->particleType.color[0]);
    ImGui::Unindent();
    ImGui::Text("Emitter");
    ImGui::Indent();
    ImGui::InputFloat3("Size", &particleEmitter->size[0]);
    ImGui::InputFloat("Min emit time", &particleEmitter->minEmitTime);
    ImGui::InputFloat("Max emit time", &particleEmitter->maxEmitTime);

    if (ImGui::Button("Emitter type"))
        ImGui::OpenPopup("Emitter type");

    if (ImGui::BeginPopup("Emitter type")) {
        ImGui::Text("Emitter type");
        ImGui::Separator();

        if (ImGui::Selectable("Point"))
            particleEmitter->emitterType = Component::ParticleEmitter::POINT;

        if (ImGui::Selectable("Cuboid"))
            particleEmitter->emitterType = Component::ParticleEmitter::CUBOID;

        ImGui::EndPopup();
    }
    ImGui::Unindent();
    ImGui::Text("Preview");
    ImGui::Indent();
    ImGui::Unindent();
}
<commit_msg>Preview diffuse<commit_after>#include "EntityEditor.hpp"

#include <Engine/Component/Animation.hpp>
#include <Engine/Component/Physics.hpp>
#include <Engine/Component/Mesh.hpp>
#include <Engine/Component/Lens.hpp>
#include <Engine/Component/Material.hpp>
#include <Engine/Component/DirectionalLight.hpp>
#include <Engine/Component/PointLight.hpp>
#include <Engine/Component/SpotLight.hpp>
#include <Engine/Component/Listener.hpp>
#include <Engine/Component/Script.hpp>
#include <Engine/Component/SoundSource.hpp>
#include <Engine/Component/ParticleEmitter.hpp>
#include <Engine/Hymn.hpp>
#include <Engine/Geometry/Model.hpp>
#include <Engine/Geometry/RiggedModel.hpp>
#include <Engine/Texture/Texture2D.hpp>
#include <Engine/Audio/SoundBuffer.hpp>
#include <Engine/Script/ScriptFile.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>

#include "../../Util/EditorSettings.hpp"
#include "../FileSelector.hpp"

using namespace GUI;

EntityEditor::EntityEditor() {
    name[0] = '\0';
    AddEditor<Component::Animation>("Animation", std::bind(&EntityEditor::AnimationEditor, this, std::placeholders::_1));
    AddEditor<Component::Physics>("Physics", std::bind(&EntityEditor::PhysicsEditor, this, std::placeholders::_1));
    AddEditor<Component::Mesh>("Mesh", std::bind(&EntityEditor::MeshEditor, this, std::placeholders::_1));
    AddEditor<Component::Lens>("Lens", std::bind(&EntityEditor::LensEditor, this, std::placeholders::_1));
    AddEditor<Component::Material>("Material", std::bind(&EntityEditor::MaterialEditor, this, std::placeholders::_1));
    AddEditor<Component::DirectionalLight>("Directional light", std::bind(&EntityEditor::DirectionalLightEditor, this, std::placeholders::_1));
    AddEditor<Component::PointLight>("Point light", std::bind(&EntityEditor::PointLightEditor, this, std::placeholders::_1));
    AddEditor<Component::SpotLight>("Spot light", std::bind(&EntityEditor::SpotLightEditor, this, std::placeholders::_1));
    AddEditor<Component::Listener>("Listener", std::bind(&EntityEditor::ListenerEditor, this, std::placeholders::_1));
    AddEditor<Component::Script>("Script", std::bind(&EntityEditor::ScriptEditor, this, std::placeholders::_1));
    AddEditor<Component::SoundSource>("Sound source", std::bind(&EntityEditor::SoundSourceEditor, this, std::placeholders::_1));
    AddEditor<Component::ParticleEmitter>("Particle emitter", std::bind(&EntityEditor::ParticleEmitterEditor, this, std::placeholders::_1));
}

EntityEditor::~EntityEditor() {

}

void EntityEditor::Show() {
    if (ImGui::Begin(("Entity: " + entity->name + "###" + std::to_string(reinterpret_cast<uintptr_t>(entity))).c_str(), &visible)) {
        ImGui::InputText("Name", name, 128);
        entity->name = name;
        ImGui::Text("Transform");
        ImGui::Indent();
        ImGui::InputFloat3("Position", &entity->position[0]);
        ImGui::InputFloat3("Rotation", &entity->rotation[0]);
        ImGui::InputFloat3("Scale", &entity->scale[0]);
        ImGui::Unindent();
        if (!entity->IsScene()) {
            if (ImGui::Button("Add component"))
                ImGui::OpenPopup("Add component");

            if (ImGui::BeginPopup("Add component")) {
                ImGui::Text("Components");
                ImGui::Separator();

                for (Editor& editor : editors) {
                    editor.addFunction();
                }

                ImGui::EndPopup();
            }

            for (Editor& editor : editors) {
                editor.editFunction();
            }
        }
    }

    ImGui::End();
}

void EntityEditor::SetEntity(Entity* entity) {
    this->entity = entity;
    strcpy(name, entity->name.c_str());
}

bool EntityEditor::ShowsEntity(Entity* entity) {
    return this->entity == entity;
}

bool EntityEditor::IsVisible() const {
    return visible;
}

void EntityEditor::SetVisible(bool visible) {
    this->visible = visible;
}

void EntityEditor::AnimationEditor(Component::Animation* animation) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Animation"))
        ImGui::OpenPopup("Select model##Animation");

    if (ImGui::BeginPopup("Select model##Animation")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                animation->riggedModel = dynamic_cast<Geometry::RiggedModel*>(model);
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::PhysicsEditor(Component::Physics* physics) {
    ImGui::Text("Positional");
    ImGui::Indent();
    ImGui::InputFloat3("Velocity", &physics->velocity[0]);
    ImGui::InputFloat("Max velocity", &physics->maxVelocity);
    ImGui::InputFloat3("Acceleration", &physics->acceleration[0]);
    ImGui::InputFloat("Velocity drag factor", &physics->velocityDragFactor);
    ImGui::InputFloat("Gravity factor", &physics->gravityFactor);
    ImGui::Unindent();
    ImGui::Text("Angular");
    ImGui::Indent();
    ImGui::InputFloat3("Angular velocity", &physics->angularVelocity[0]);
    ImGui::InputFloat("Max angular velocity", &physics->maxAngularVelocity);
    ImGui::InputFloat3("Angular acceleration", &physics->angularAcceleration[0]);
    ImGui::InputFloat("Angular drag factor", &physics->angularDragFactor);
    ImGui::InputFloat3("Moment of inertia", &physics->momentOfInertia[0]);
    ImGui::Unindent();

}

void EntityEditor::MeshEditor(Component::Mesh* mesh) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Mesh"))
        ImGui::OpenPopup("Select model##Mesh");

    if (ImGui::BeginPopup("Select model##Mesh")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                mesh->geometry = model;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::LensEditor(Component::Lens* lens) {
    ImGui::Indent();
    ImGui::InputFloat("Field of view", &lens->fieldOfView);
    ImGui::InputFloat("Z near", &lens->zNear);
    ImGui::InputFloat("Z far", &lens->zFar);
    ImGui::Unindent();
}

void EntityEditor::MaterialEditor(Component::Material* material) {
    // Diffuse
    ImGui::Text("Diffuse");
    ImGui::Indent();
    if (material->diffuse->IsLoaded())
        ImGui::Image((void*) material->diffuse->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select diffuse texture"))
        ImGui::OpenPopup("Select diffuse texture");

    if (ImGui::BeginPopup("Select diffuse texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->diffuse = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Normal
    ImGui::Text("Normal");
    ImGui::Indent();
    if (ImGui::Button("Select normal texture"))
        ImGui::OpenPopup("Select normal texture");

    if (ImGui::BeginPopup("Select normal texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->normal = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Specular
    ImGui::Text("Specular");
    ImGui::Indent();
    if (ImGui::Button("Select specular texture"))
        ImGui::OpenPopup("Select specular texture");

    if (ImGui::BeginPopup("Select specular texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->specular = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Glow
    ImGui::Text("Glow");
    ImGui::Indent();
    if (ImGui::Button("Select glow texture"))
        ImGui::OpenPopup("Select glow texture");

    if (ImGui::BeginPopup("Select glow texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->glow = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::DirectionalLightEditor(Component::DirectionalLight* directionalLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &directionalLight->color[0]);
    ImGui::InputFloat("Ambient coefficient", &directionalLight->ambientCoefficient);
    ImGui::Unindent();
}

void EntityEditor::PointLightEditor(Component::PointLight* pointLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &pointLight->color[0]);
    ImGui::InputFloat("Ambient coefficient", &pointLight->ambientCoefficient);
    ImGui::InputFloat("Attenuation", &pointLight->attenuation);
    ImGui::InputFloat("Intensity", &pointLight->intensity);
    ImGui::Unindent();
}

void EntityEditor::SpotLightEditor(Component::SpotLight* spotLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &spotLight->color[0]);
    ImGui::InputFloat("Ambient coefficient", &spotLight->ambientCoefficient);
    ImGui::InputFloat("Attenuation", &spotLight->attenuation);
    ImGui::InputFloat("Intensity", &spotLight->intensity);
    ImGui::InputFloat("Cone angle", &spotLight->coneAngle);
    ImGui::Unindent();
}

void EntityEditor::ListenerEditor(Component::Listener* listener) {

}

void EntityEditor::ScriptEditor(Component::Script* script) {
    ImGui::Indent();
    if(script->scriptFile != nullptr)
        ImGui::Text(script->scriptFile->name.c_str());
    else
        ImGui::Text("No script loaded");

    if (ImGui::Button("Select script"))
        ImGui::OpenPopup("Select script");

    if (ImGui::BeginPopup("Select script")) {
        ImGui::Text("Scripts");
        ImGui::Separator();

        for (ScriptFile* scriptFile : Hymn().scripts) {
            if (ImGui::Selectable(scriptFile->name.c_str()))
                script->scriptFile = scriptFile;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::SoundSourceEditor(Component::SoundSource* soundSource) {
    ImGui::Text("Sound");
    ImGui::Indent();
    if (ImGui::Button("Select sound"))
        ImGui::OpenPopup("Select sound");

    if (ImGui::BeginPopup("Select sound")) {
        ImGui::Text("Sounds");
        ImGui::Separator();

        for (Audio::SoundBuffer* sound : Hymn().sounds) {
            if (ImGui::Selectable(sound->name.c_str()))
                soundSource->soundBuffer = sound;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
    ImGui::Text("Sound properties");
    ImGui::Indent();
    ImGui::InputFloat("Pitch", &soundSource->pitch);
    ImGui::InputFloat("Gain", &soundSource->gain);
    ImGui::Checkbox("Loop", &soundSource->loop);
    ImGui::Unindent();
}

void EntityEditor::ParticleEmitterEditor(Component::ParticleEmitter* particleEmitter) {
    ImGui::Text("Particle");
    ImGui::Indent();
    ImGui::InputInt("Texture index", &particleEmitter->particleType.textureIndex);
    ImGui::InputFloat3("Min velocity", &particleEmitter->particleType.minVelocity[0]);
    ImGui::InputFloat3("Max velocity", &particleEmitter->particleType.maxVelocity[0]);
    ImGui::InputFloat("Min lifetime", &particleEmitter->particleType.minLifetime);
    ImGui::InputFloat("Max lifetime", &particleEmitter->particleType.maxLifetime);
    ImGui::InputFloat2("Min size", &particleEmitter->particleType.minSize[0]);
    ImGui::InputFloat2("Max size", &particleEmitter->particleType.maxSize[0]);
    ImGui::Checkbox("Uniform scaling", &particleEmitter->particleType.uniformScaling);
    ImGui::InputFloat("Start alpha", &particleEmitter->particleType.startAlpha);
    ImGui::InputFloat("Mid alpha", &particleEmitter->particleType.midAlpha);
    ImGui::InputFloat("End alpha", &particleEmitter->particleType.endAlpha);
    ImGui::InputFloat3("Color", &particleEmitter->particleType.color[0]);
    ImGui::Unindent();
    ImGui::Text("Emitter");
    ImGui::Indent();
    ImGui::InputFloat3("Size", &particleEmitter->size[0]);
    ImGui::InputFloat("Min emit time", &particleEmitter->minEmitTime);
    ImGui::InputFloat("Max emit time", &particleEmitter->maxEmitTime);

    if (ImGui::Button("Emitter type"))
        ImGui::OpenPopup("Emitter type");

    if (ImGui::BeginPopup("Emitter type")) {
        ImGui::Text("Emitter type");
        ImGui::Separator();

        if (ImGui::Selectable("Point"))
            particleEmitter->emitterType = Component::ParticleEmitter::POINT;

        if (ImGui::Selectable("Cuboid"))
            particleEmitter->emitterType = Component::ParticleEmitter::CUBOID;

        ImGui::EndPopup();
    }
    ImGui::Unindent();
    ImGui::Text("Preview");
    ImGui::Indent();
    ImGui::Unindent();
}
<|endoftext|>


<commit_before>/**
 * @file
 *
 * @brief This file contains a basic YAML to `KeySet` converter function.
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

// -- Imports ------------------------------------------------------------------------------------------------------------------------------

#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>

#include <yaep.h>

#include <kdberrors.h>

#include "convert.hpp"
#include "error_listener.hpp"
#include "lexer.hpp"
#include "listener.hpp"
#include "memory.hpp"
#include "walk.hpp"

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::string;
using std::stringstream;

using CppKey = kdb::Key;
using CppKeySet = kdb::KeySet;
using ckdb::keyNew;

namespace
{
// -- Globals ------------------------------------------------------------------------------------------------------------------------------

ErrorListener * errorListenerAdress;
Lexer * lexerAddress;
Memory * parserMemoryAddress;

// -- Functions ----------------------------------------------------------------------------------------------------------------------------

/**
 * @brief This function returns the next token produced by the lexer.
 *
 * If the lexer found the end of the input, then this function returns `-1`.
 *
 * @param attribute The parser uses this parameter to store auxiliary data for
 *                  the returned token.
 *
 * @return A number specifying the type of the first token the parser has not
 *         emitted yet
 */
int nextToken (void ** attribute)
{
	return lexerAddress->nextToken (attribute);
}

/**
 * @brief This function reacts to syntax errors reported by YAEP’s parsing
 *        engine.
 *
 * @param errorToken This number specifies the token where the error occurred.
 * @param errorTokenData This variable stores the data contained in
 *                       `errorToken`.
 * @param ignoredToken This number specifies the first token that was ignored
 *                     during error recovery.
 * @param ignoredTokenData This variable stores the data contained in
 *                         `ignoredToken`.
 * @param recoveredToken This number specifies the first included token after
 *                       the error recovery has taken place.
 * @param recoveredTokenData This variable stores the data contained in
 *                           `recoveredToken`.
 */
void syntaxError (int errorToken, void * errorTokenData, int ignoredToken, void * ignoredTokenData, int recoveredToken,
		  void * recoveredTokenData)
{
	return errorListenerAdress->syntaxError (errorToken, errorTokenData, ignoredToken, ignoredTokenData, recoveredToken,
						 recoveredTokenData);
}

/**
 * This function allocates a memory region of the given size.
 *
 * @param size This variable specifies the amount of data this method should
 *             allocate.
 *
 * @return A pointer to a memory region of the specified size
 */
void * alloc (int size)
{
	return parserMemoryAddress->allocate (size);
}

} // namespace

/**
 * @brief This function converts the given YAML file to keys and adds the
 *        result to `keySet`.
 *
 * @param keySet The function adds the converted keys to this variable.
 * @param parent The function uses this parent key of `keySet` to emit error
 *               information.
 * @param filename This parameter stores the path of the YAML file this
 *                 function converts.
 *
 * @retval -2 if the file could not be opened for reading
 * @retval -1 if there was a error converting the YAML file
 * @retval  0 if parsing was successful and the function did not change the
 *            given key set
 * @retval  1 if parsing was successful and the function did change `keySet`
 */
int addToKeySet (CppKeySet & keySet, CppKey & parent, string const & filename)
{
	string const grammar =
#include "yaml.h"
		;

	yaep parser;
	if (parser.parse_grammar (1, grammar.c_str ()) != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_PARSE, parent.getKey (), "Unable to parse grammar: %s", parser.error_message ());
		return -1;
	}

	Memory memory;
	parserMemoryAddress = &memory;

	ErrorListener errorListener;
	errorListenerAdress = &errorListener;

	ifstream input{ filename };
	if (!input.good ())
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_COULD_NOT_OPEN, parent.getKey (), "Unable to open file “%s”", filename.c_str ());
		return -2;
	}

	Lexer lexer{ input };
	lexerAddress = &lexer;

	int ambiguousOutput;
	struct yaep_tree_node * root = nullptr;

	parser.parse (nextToken, syntaxError, alloc, nullptr, &root, &ambiguousOutput);

	if (ambiguousOutput)
	{
		ELEKTRA_SET_ERRORF (
			ELEKTRA_ERROR_PARSE, parent.getKey (),
			"The content of file “%s” showed that the grammar:\n%s\nproduces ambiguous output!\n"
			"Please fix the grammar, to make sure it produces only one unique syntax tree for every kind of YAML input.",
			filename.c_str (), grammar.c_str ());
		return -1;
	}

	if (errorListener.getNumberOfErrors () > 0)
	{
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_PARSE, parent.getKey (), errorListener.getErrorMessage ().c_str ());
		return -1;
	}

	Listener listener{ parent };
	walk (listener, root);
	keySet.append (listener.getKeySet ());

	return listener.getKeySet ().size () > 0;
}
<commit_msg>YAwn: Split code of function `addToKeySet`<commit_after>/**
 * @file
 *
 * @brief This file contains a basic YAML to `KeySet` converter function.
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

// -- Imports ------------------------------------------------------------------------------------------------------------------------------

#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>

#include <yaep.h>

#include <kdberrors.h>

#include "convert.hpp"
#include "error_listener.hpp"
#include "lexer.hpp"
#include "listener.hpp"
#include "memory.hpp"
#include "walk.hpp"

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::string;
using std::stringstream;

using CppKey = kdb::Key;
using CppKeySet = kdb::KeySet;
using ckdb::keyNew;

namespace
{
// -- Globals ------------------------------------------------------------------------------------------------------------------------------

ErrorListener * errorListenerAdress;
Lexer * lexerAddress;
Memory * parserMemoryAddress;

// -- Functions ----------------------------------------------------------------------------------------------------------------------------

/**
 * @brief This function returns the next token produced by the lexer.
 *
 * If the lexer found the end of the input, then this function returns `-1`.
 *
 * @param attribute The parser uses this parameter to store auxiliary data for
 *                  the returned token.
 *
 * @return A number specifying the type of the first token the parser has not
 *         emitted yet
 */
int nextToken (void ** attribute)
{
	return lexerAddress->nextToken (attribute);
}

/**
 * @brief This function reacts to syntax errors reported by YAEP’s parsing
 *        engine.
 *
 * @param errorToken This number specifies the token where the error occurred.
 * @param errorTokenData This variable stores the data contained in
 *                       `errorToken`.
 * @param ignoredToken This number specifies the first token that was ignored
 *                     during error recovery.
 * @param ignoredTokenData This variable stores the data contained in
 *                         `ignoredToken`.
 * @param recoveredToken This number specifies the first included token after
 *                       the error recovery has taken place.
 * @param recoveredTokenData This variable stores the data contained in
 *                           `recoveredToken`.
 */
void syntaxError (int errorToken, void * errorTokenData, int ignoredToken, void * ignoredTokenData, int recoveredToken,
		  void * recoveredTokenData)
{
	return errorListenerAdress->syntaxError (errorToken, errorTokenData, ignoredToken, ignoredTokenData, recoveredToken,
						 recoveredTokenData);
}

/**
 * This function allocates a memory region of the given size.
 *
 * @param size This variable specifies the amount of data this method should
 *             allocate.
 *
 * @return A pointer to a memory region of the specified size
 */
void * alloc (int size)
{
	return parserMemoryAddress->allocate (size);
}

/**
 * @brief This function parses the YAML grammar contained in `yaml.bnf`.
 *
 * @param parser This variable stores the YAEP parser that uses the YAML grammar contained in `yaml.bnf` to parse input.
 * @param error This function stores error information in this key, if it was unable to parse the grammar.
 *
 * @return A string containing the content of `yaml.bnf`, if parsing of the grammar was successful, or an empty string otherwise
 */
string parseGrammar (yaep & parser, CppKey & error)
{
	string grammar =
#include "yaml.h"
		;

	if (parser.parse_grammar (1, grammar.c_str ()) != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_PARSE, error.getKey (), "Unable to parse grammar: %s", parser.error_message ());
		return "";
	}
	return grammar;
}

/**
 * @brief This function creates a stream containing the content of a given file.
 *
 * @param filename This variable stores location of the file for which this function creates an input stream
 * @param error This function stores an error message in this key, if it was unable to access `filename`.
 *
 * @return A input stream that contains the content of `filename`, if creating the stream was successful
 */
ifstream openFile (string const & filename, CppKey & error)
{
	ifstream input{ filename };
	if (!input.good ())
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_COULD_NOT_OPEN, error.getKey (), "Unable to open file “%s”", filename.c_str ());
	}
	return input;
}

/**
 * @brief This function stores error information in `error`, if parsing was unsuccessful.
 *
 * @param ambiguousOutput This variable is true, when YAEP was unable to create a unique syntax tree from the given input.
 * @param errorListener This object stores information about errors that occurred while YAEP parsed the input.
 * @param filename This variable stores the location of the file YAEP parsed.
 * @param grammar This argument stores the YAML grammar used to parse the input.
 * @param error This function will use this variable to store information about errors that occurred while parsing.
 *
 * @retval -1 If there was an error parsing the last input
 * @retval  0 Otherwise
 */
int handleErrors (int const ambiguousOutput, ErrorListener const & errorListener, string const & filename, string const & grammar,
		  CppKey & error)
{
	if (ambiguousOutput)
	{
		ELEKTRA_SET_ERRORF (
			ELEKTRA_ERROR_PARSE, error.getKey (),
			"The content of file “%s” showed that the grammar:\n%s\nproduces ambiguous output!\n"
			"Please fix the grammar, to make sure it produces only one unique syntax tree for every kind of YAML input.",
			filename.c_str (), grammar.c_str ());
		return -1;
	}

	if (errorListener.getNumberOfErrors () > 0)
	{
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_PARSE, error.getKey (), errorListener.getErrorMessage ().c_str ());
		return -1;
	}
	return 0;
}

} // namespace

/**
 * @brief This function converts the given YAML file to keys and adds the
 *        result to `keySet`.
 *
 * @param keySet The function adds the converted keys to this variable.
 * @param parent The function uses this parent key of `keySet` to emit error
 *               information.
 * @param filename This parameter stores the path of the YAML file this
 *                 function converts.
 *
 * @retval -2 if the file could not be opened for reading
 * @retval -1 if there was a error converting the YAML file
 * @retval  0 if parsing was successful and the function did not change the
 *            given key set
 * @retval  1 if parsing was successful and the function did change `keySet`
 */
int addToKeySet (CppKeySet & keySet, CppKey & parent, string const & filename)
{
	yaep parser;

	auto grammar = parseGrammar (parser, parent);
	if (grammar.size () <= 0) return -1;

	auto input = openFile (filename, parent);
	if (!input.good ()) return -1;

	Memory memory;
	parserMemoryAddress = &memory;

	ErrorListener errorListener;
	errorListenerAdress = &errorListener;

	Lexer lexer{ input };
	lexerAddress = &lexer;

	int ambiguousOutput;
	struct yaep_tree_node * root = nullptr;

	parser.parse (nextToken, syntaxError, alloc, nullptr, &root, &ambiguousOutput);

	if (handleErrors (ambiguousOutput, errorListener, filename, grammar, parent) < 0) return -1;

	Listener listener{ parent };
	walk (listener, root);
	keySet.append (listener.getKeySet ());

	return listener.getKeySet ().size () > 0;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/framework/executor.h"

#include <set>

#include "gflags/gflags.h"
#include "paddle/framework/feed_fetch_type.h"
#include "paddle/framework/lod_rank_table.h"
#include "paddle/framework/lod_tensor_array.h"
#include "paddle/framework/op_registry.h"

DEFINE_bool(check_nan_inf, false,
            "Checking whether operator produce NAN/INF or not. It will be "
            "extremely slow so please use this flag wisely.");

namespace paddle {
namespace framework {

const std::string kFeedOpType = "feed";
const std::string kFetchOpType = "fetch";

Executor::Executor(const platform::Place& place) : place_(place) {}

static void CreateTensor(Variable* var, proto::VarDesc::VarType var_type) {
  if (var_type == proto::VarDesc::LOD_TENSOR) {
    var->GetMutable<LoDTensor>();
  } else if (var_type == proto::VarDesc::SELECTED_ROWS) {
    var->GetMutable<SelectedRows>();
  } else if (var_type == proto::VarDesc::FEED_MINIBATCH) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::FETCH_LIST) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::STEP_SCOPES) {
    var->GetMutable<std::vector<framework::Scope>>();
  } else if (var_type == proto::VarDesc::LOD_RANK_TABLE) {
    var->GetMutable<LoDRankTable>();
  } else if (var_type == proto::VarDesc::LOD_TENSOR_ARRAY) {
    var->GetMutable<LoDTensorArray>();
  } else {
    PADDLE_THROW(
        "Variable type %d is not in "
        "[LoDTensor, SelectedRows, FEED_MINIBATCH, FETCH_LIST, LOD_RANK_TABLE]",
        var_type);
  }
}

static void CheckTensorNANOrInf(const std::string& name,
                                const framework::Tensor& tensor) {
  if (tensor.memory_size() == 0) {
    return;
  }
  if (tensor.type().hash_code() != typeid(float).hash_code() &&
      tensor.type().hash_code() != typeid(double).hash_code()) {
    return;
  }
  PADDLE_ENFORCE(!framework::HasInf(tensor), "Tensor %s has Inf", name);
  PADDLE_ENFORCE(!framework::HasNAN(tensor), "Tensor %s has NAN, %p", name,
                 &tensor);
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id,
                   bool create_local_scope, bool create_vars) {
  // TODO(tonyyang-svail):
  //    - only runs on the first device (i.e. no interdevice communication)
  //    - will change to use multiple blocks for RNN op and Cond Op
  PADDLE_ENFORCE_LT(static_cast<size_t>(block_id), pdesc.Size());
  auto& block = pdesc.Block(block_id);

  Scope* local_scope = scope;
  if (create_vars) {
    if (create_local_scope) {
      local_scope = &scope->NewScope();
      for (auto& var : block.AllVars()) {
        if (var->Name() == framework::kEmptyVarName) {
          continue;
        }

        if (var->Persistable()) {
          auto* ptr = scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " global, which pointer is " << ptr;
        } else {
          auto* ptr = local_scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " locally, which pointer is " << ptr;
        }
      }
    } else {
      for (auto& var : block.AllVars()) {
        auto* ptr = local_scope->Var(var->Name());
        CreateTensor(ptr, var->GetType());
        VLOG(3) << "Create variable " << var->Name() << ", which pointer is "
                << ptr;
      }
    }  // if (create_local_scope)
  }    // if (create_vars)

  for (auto& op_desc : block.AllOps()) {
    auto op = paddle::framework::OpRegistry::CreateOp(*op_desc);
    VLOG(3) << op->DebugString();
    op->Run(*local_scope, place_);
    if (FLAGS_check_nan_inf) {
      for (auto& vname : op->OutputVars(true)) {
        auto* var = local_scope->FindVar(vname);
        if (var == nullptr) continue;
        if (var->IsType<framework::LoDTensor>()) {
          CheckTensorNANOrInf(vname, var->Get<framework::LoDTensor>());
        }
      }
    }
  }
  if (create_vars && create_local_scope) {
    scope->DeleteScope(local_scope);
  }
}

}  // namespace framework
}  // namespace paddle
<commit_msg>Remove debug codes<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/framework/executor.h"

#include <set>

#include "gflags/gflags.h"
#include "paddle/framework/feed_fetch_type.h"
#include "paddle/framework/lod_rank_table.h"
#include "paddle/framework/lod_tensor_array.h"
#include "paddle/framework/op_registry.h"

DEFINE_bool(check_nan_inf, false,
            "Checking whether operator produce NAN/INF or not. It will be "
            "extremely slow so please use this flag wisely.");

namespace paddle {
namespace framework {

const std::string kFeedOpType = "feed";
const std::string kFetchOpType = "fetch";

Executor::Executor(const platform::Place& place) : place_(place) {}

static void CreateTensor(Variable* var, proto::VarDesc::VarType var_type) {
  if (var_type == proto::VarDesc::LOD_TENSOR) {
    var->GetMutable<LoDTensor>();
  } else if (var_type == proto::VarDesc::SELECTED_ROWS) {
    var->GetMutable<SelectedRows>();
  } else if (var_type == proto::VarDesc::FEED_MINIBATCH) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::FETCH_LIST) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::STEP_SCOPES) {
    var->GetMutable<std::vector<framework::Scope>>();
  } else if (var_type == proto::VarDesc::LOD_RANK_TABLE) {
    var->GetMutable<LoDRankTable>();
  } else if (var_type == proto::VarDesc::LOD_TENSOR_ARRAY) {
    var->GetMutable<LoDTensorArray>();
  } else {
    PADDLE_THROW(
        "Variable type %d is not in "
        "[LoDTensor, SelectedRows, FEED_MINIBATCH, FETCH_LIST, LOD_RANK_TABLE]",
        var_type);
  }
}

static void CheckTensorNANOrInf(const std::string& name,
                                const framework::Tensor& tensor) {
  if (tensor.memory_size() == 0) {
    return;
  }
  if (tensor.type().hash_code() != typeid(float).hash_code() &&
      tensor.type().hash_code() != typeid(double).hash_code()) {
    return;
  }
  PADDLE_ENFORCE(!framework::HasInf(tensor), "Tensor %s has Inf", name);
  PADDLE_ENFORCE(!framework::HasNAN(tensor), "Tensor %s has NAN", name);
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id,
                   bool create_local_scope, bool create_vars) {
  // TODO(tonyyang-svail):
  //    - only runs on the first device (i.e. no interdevice communication)
  //    - will change to use multiple blocks for RNN op and Cond Op
  PADDLE_ENFORCE_LT(static_cast<size_t>(block_id), pdesc.Size());
  auto& block = pdesc.Block(block_id);

  Scope* local_scope = scope;
  if (create_vars) {
    if (create_local_scope) {
      local_scope = &scope->NewScope();
      for (auto& var : block.AllVars()) {
        if (var->Name() == framework::kEmptyVarName) {
          continue;
        }

        if (var->Persistable()) {
          auto* ptr = scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " global, which pointer is " << ptr;
        } else {
          auto* ptr = local_scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " locally, which pointer is " << ptr;
        }
      }
    } else {
      for (auto& var : block.AllVars()) {
        auto* ptr = local_scope->Var(var->Name());
        CreateTensor(ptr, var->GetType());
        VLOG(3) << "Create variable " << var->Name() << ", which pointer is "
                << ptr;
      }
    }  // if (create_local_scope)
  }    // if (create_vars)

  for (auto& op_desc : block.AllOps()) {
    auto op = paddle::framework::OpRegistry::CreateOp(*op_desc);
    VLOG(3) << op->DebugString();
    op->Run(*local_scope, place_);
    if (FLAGS_check_nan_inf) {
      for (auto& vname : op->OutputVars(true)) {
        auto* var = local_scope->FindVar(vname);
        if (var == nullptr) continue;
        if (var->IsType<framework::LoDTensor>()) {
          CheckTensorNANOrInf(vname, var->Get<framework::LoDTensor>());
        }
      }
    }
  }
  if (create_vars && create_local_scope) {
    scope->DeleteScope(local_scope);
  }
}

}  // namespace framework
}  // namespace paddle
<|endoftext|>