<commit_before>/*
    This file is part of Magnum.

    Original authors — credit is appreciated but not required:

        2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 —
            Vladimír Vondruš <mosra@centrum.cz>
        2018 — scturtle <scturtle@gmail.com>

    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or distribute
    this software, either in source code form or as a compiled binary, for any
    purpose, commercial or non-commercial, and by any means.

    In jurisdictions that recognize copyright laws, the author or authors of
    this software dedicate any and all copyright interest in the software to
    the public domain. We make this dedication for the benefit of the public
    at large and to the detriment of our heirs and successors. We intend this
    dedication to be an overt act of relinquishment in perpetuity of all
    present and future rights to this software under copyright law.

    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 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 <Magnum/Image.h>
#include <Magnum/GL/Buffer.h>
#include <Magnum/GL/DefaultFramebuffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/MeshTools/Compile.h>
#include <Magnum/Platform/Sdl2Application.h>
#include <Magnum/Primitives/Grid.h>
#include <Magnum/SceneGraph/Camera.h>
#include <Magnum/SceneGraph/Drawable.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
#include <Magnum/SceneGraph/Object.h>
#include <Magnum/SceneGraph/Scene.h>
#include <Magnum/Shaders/Flat.h>
#include <Magnum/Shaders/VertexColor.h>
#include <Magnum/Trade/MeshData3D.h>

namespace Magnum { namespace Examples {

using Object3D = SceneGraph::Object<SceneGraph::MatrixTransformation3D>;
using Scene3D = SceneGraph::Scene<SceneGraph::MatrixTransformation3D>;

using namespace Math::Literals;

class MouseInteractionExample: public Platform::Application {
    public:
        explicit MouseInteractionExample(const Arguments &arguments);

    private:
        Float depthAt(const Vector2i& position);
        Vector3 unproject(const Vector2i& position, Float depth);

        void mousePressEvent(MouseEvent &event) override;
        void mouseMoveEvent(MouseMoveEvent &event) override;
        void mouseScrollEvent(MouseScrollEvent &event) override;
        void drawEvent() override;

        Shaders::VertexColor3D _vertexColorShader{NoCreate};
        Shaders::Flat3D _flatShader{NoCreate};
        GL::Mesh _mesh{NoCreate}, _grid{NoCreate};

        Scene3D _scene;
        SceneGraph::DrawableGroup3D _drawables;
        Object3D* _cameraObject;
        SceneGraph::Camera3D* _camera;

        Float _lastDepth{0.8f};
        Vector2i _lastPosition{-1};
        Vector3 _rotationPoint, _translationPoint;
};

class VertexColorDrawable: public SceneGraph::Drawable3D {
    public:
        explicit VertexColorDrawable(Object3D& object, Shaders::VertexColor3D& shader, GL::Mesh& mesh, SceneGraph::DrawableGroup3D& drawables): SceneGraph::Drawable3D{object, &drawables}, _shader(shader), _mesh(mesh) {}

        void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) {
            _shader.setTransformationProjectionMatrix(camera.projectionMatrix()*transformation);
            _mesh.draw(_shader);
        }

    private:
        Shaders::VertexColor3D& _shader;
        GL::Mesh& _mesh;
};

class FlatDrawable: public SceneGraph::Drawable3D {
    public:
        explicit FlatDrawable(Object3D& object, Shaders::Flat3D& shader, GL::Mesh& mesh, SceneGraph::DrawableGroup3D& drawables): SceneGraph::Drawable3D{object, &drawables}, _shader(shader), _mesh(mesh) {}

        void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) {
            _shader.setColor(0x747474_rgbf)
                .setTransformationProjectionMatrix(camera.projectionMatrix()*transformation);
            _mesh.draw(_shader);
        }

    private:
        Shaders::Flat3D& _shader;
        GL::Mesh& _mesh;
};

MouseInteractionExample::MouseInteractionExample(const Arguments &arguments): Platform::Application{arguments, NoCreate} {
    /* Try 8x MSAA, fall back to zero samples if not possible. Enable only 2x
       MSAA if we have enough DPI. */
    {
        const Vector2 dpiScaling = this->dpiScaling({});
        Configuration conf;
        conf.setTitle("Magnum Mouse Interaction Example")
            .setSize(conf.size(), dpiScaling);
        GLConfiguration glConf;
        glConf.setSampleCount((Vector2{framebufferSize()}*dpiScaling/Vector2{windowSize()}).max() < 2.0f ? 8 : 2);
        if(!tryCreate(conf, glConf))
            create(conf, glConf.setSampleCount(0));
    }

    /* Shaders, renderer setup */
    _vertexColorShader = Shaders::VertexColor3D{};
    _flatShader = Shaders::Flat3D{};
    GL::Renderer::enable(GL::Renderer::Feature::DepthTest);

    /* Triangle data */
    const struct {
        Vector3 pos;
        Color3 color;
    } data[]{{{-1.0f, -1.0f, 0.0f}, 0xff0000_rgbf},
             {{ 1.0f, -1.0f, 0.0f}, 0x00ff00_rgbf},
             {{ 0.0f,  1.0f, 0.0f}, 0x0000ff_rgbf}};

    /* Triangle mesh */
    GL::Buffer buffer;
    buffer.setData(data);
    _mesh = GL::Mesh{};
    _mesh.setCount(3)
        .addVertexBuffer(std::move(buffer), 0,
            Shaders::VertexColor3D::Position{},
            Shaders::VertexColor3D::Color3{});

    /* Triangle object */
    auto triangle = new Object3D{&_scene};
    new VertexColorDrawable{*triangle, _vertexColorShader, _mesh, _drawables};

    /* Grid */
    _grid = MeshTools::compile(Primitives::grid3DWireframe({15, 15}));
    auto grid = new Object3D{&_scene};
    (*grid)
        .rotateX(90.0_degf)
        .scale(Vector3{8.0f});
    new FlatDrawable{*grid, _flatShader, _grid, _drawables};

    /* Set up the camera */
    _cameraObject = new Object3D{&_scene};
    (*_cameraObject)
        .translate(Vector3::zAxis(5.0f))
        .rotateX(-15.0_degf)
        .rotateY(30.0_degf);
    _camera = new SceneGraph::Camera3D{*_cameraObject};
    _camera->setProjectionMatrix(Matrix4::perspectiveProjection(
        45.0_degf, Vector2{windowSize()}.aspectRatio(), 0.01f, 100.0f));
}

Float MouseInteractionExample::depthAt(const Vector2i& position) {
    const Vector2i fbPosition{position.x(), GL::defaultFramebuffer.viewport().sizeY() - position.y() - 1};

    GL::defaultFramebuffer.mapForRead(GL::DefaultFramebuffer::ReadAttachment::Front);
    Image2D data = GL::defaultFramebuffer.read(
        Range2Di::fromSize(fbPosition, Vector2i{1}).padded(Vector2i{2}),
        {GL::PixelFormat::DepthComponent, GL::PixelType::Float});

    return Math::min(Containers::arrayCast<const Float>(data.data()));
}

Vector3 MouseInteractionExample::unproject(const Vector2i& position, Float depth) {
    const Range2Di view = GL::defaultFramebuffer.viewport();
    const Vector2i fbPosition{position.x(), view.sizeY() - position.y() - 1};
    const Vector3 in{2*Vector2{fbPosition - view.min()}/Vector2{view.size()} - Vector2{1.0f}, depth*2.0f - 1.0f};

    /*
        Use the following to get global coordinates instead of camera-relative:

        (_cameraObject->absoluteTransformationMatrix()*_camera->projectionMatrix().inverted()).transformPoint(in)
    */
    return _camera->projectionMatrix().inverted().transformPoint(in);
}

void MouseInteractionExample::mousePressEvent(MouseEvent& event) {
    const Float currentDepth = depthAt(event.position());
    const Float depth = currentDepth == 1.0f ? _lastDepth : currentDepth;
    _translationPoint = unproject(event.position(), depth);
    if(currentDepth != 1.0f) {
        _rotationPoint = _translationPoint;
        _lastDepth = depth;
    }
}

void MouseInteractionExample::mouseMoveEvent(MouseMoveEvent& event) {
    if(_lastPosition == Vector2i{-1}) _lastPosition = event.position();
    const Vector2i delta = event.position() - _lastPosition;
    _lastPosition = event.position();

    if(!event.buttons()) return;

    /* Translate */
    if(event.modifiers() & MouseMoveEvent::Modifier::Shift) {
        const Vector3 p = unproject(event.position(), _lastDepth);
        _cameraObject->translateLocal(_translationPoint - p); /* is Z always 0? */
        _translationPoint = p;

    /* Rotate around rotation point */
    } else _cameraObject->transformLocal(
        Matrix4::translation(_rotationPoint)*
        Matrix4::rotationX(-0.01_radf*delta.y())*
        Matrix4::rotationY(-0.01_radf*delta.x())*
        Matrix4::translation(-_rotationPoint));

    redraw();
}

void MouseInteractionExample::mouseScrollEvent(MouseScrollEvent &event) {
    const Float currentDepth = depthAt(event.position());
    const Float depth = currentDepth == 1.0f ? _lastDepth : currentDepth;
    const Vector3 p = unproject(event.position(), depth);
    if(currentDepth != 1.0f) {
        _rotationPoint = p;
        _lastDepth = depth;
    }

    const Int direction = event.offset().y();
    if(!direction) return;

    /* Move towards/backwards the rotation point in cam coords */
    _cameraObject->translateLocal(_rotationPoint*(direction < 0 ? -1.0f : 1.0f)*0.1f);

    redraw();
}

void MouseInteractionExample::drawEvent() {
    GL::defaultFramebuffer.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth);

    _camera->draw(_drawables);

    swapBuffers();
}

}}

MAGNUM_APPLICATION_MAIN(Magnum::Examples::MouseInteractionExample)
<commit_msg>mouseinteraction: missing include.<commit_after>/*
    This file is part of Magnum.

    Original authors — credit is appreciated but not required:

        2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 —
            Vladimír Vondruš <mosra@centrum.cz>
        2018 — scturtle <scturtle@gmail.com>

    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or distribute
    this software, either in source code form or as a compiled binary, for any
    purpose, commercial or non-commercial, and by any means.

    In jurisdictions that recognize copyright laws, the author or authors of
    this software dedicate any and all copyright interest in the software to
    the public domain. We make this dedication for the benefit of the public
    at large and to the detriment of our heirs and successors. We intend this
    dedication to be an overt act of relinquishment in perpetuity of all
    present and future rights to this software under copyright law.

    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 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 <Magnum/Image.h>
#include <Magnum/GL/Buffer.h>
#include <Magnum/GL/DefaultFramebuffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/PixelFormat.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/MeshTools/Compile.h>
#include <Magnum/Platform/Sdl2Application.h>
#include <Magnum/Primitives/Grid.h>
#include <Magnum/SceneGraph/Camera.h>
#include <Magnum/SceneGraph/Drawable.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
#include <Magnum/SceneGraph/Object.h>
#include <Magnum/SceneGraph/Scene.h>
#include <Magnum/Shaders/Flat.h>
#include <Magnum/Shaders/VertexColor.h>
#include <Magnum/Trade/MeshData3D.h>

namespace Magnum { namespace Examples {

using Object3D = SceneGraph::Object<SceneGraph::MatrixTransformation3D>;
using Scene3D = SceneGraph::Scene<SceneGraph::MatrixTransformation3D>;

using namespace Math::Literals;

class MouseInteractionExample: public Platform::Application {
    public:
        explicit MouseInteractionExample(const Arguments &arguments);

    private:
        Float depthAt(const Vector2i& position);
        Vector3 unproject(const Vector2i& position, Float depth);

        void mousePressEvent(MouseEvent &event) override;
        void mouseMoveEvent(MouseMoveEvent &event) override;
        void mouseScrollEvent(MouseScrollEvent &event) override;
        void drawEvent() override;

        Shaders::VertexColor3D _vertexColorShader{NoCreate};
        Shaders::Flat3D _flatShader{NoCreate};
        GL::Mesh _mesh{NoCreate}, _grid{NoCreate};

        Scene3D _scene;
        SceneGraph::DrawableGroup3D _drawables;
        Object3D* _cameraObject;
        SceneGraph::Camera3D* _camera;

        Float _lastDepth{0.8f};
        Vector2i _lastPosition{-1};
        Vector3 _rotationPoint, _translationPoint;
};

class VertexColorDrawable: public SceneGraph::Drawable3D {
    public:
        explicit VertexColorDrawable(Object3D& object, Shaders::VertexColor3D& shader, GL::Mesh& mesh, SceneGraph::DrawableGroup3D& drawables): SceneGraph::Drawable3D{object, &drawables}, _shader(shader), _mesh(mesh) {}

        void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) {
            _shader.setTransformationProjectionMatrix(camera.projectionMatrix()*transformation);
            _mesh.draw(_shader);
        }

    private:
        Shaders::VertexColor3D& _shader;
        GL::Mesh& _mesh;
};

class FlatDrawable: public SceneGraph::Drawable3D {
    public:
        explicit FlatDrawable(Object3D& object, Shaders::Flat3D& shader, GL::Mesh& mesh, SceneGraph::DrawableGroup3D& drawables): SceneGraph::Drawable3D{object, &drawables}, _shader(shader), _mesh(mesh) {}

        void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) {
            _shader.setColor(0x747474_rgbf)
                .setTransformationProjectionMatrix(camera.projectionMatrix()*transformation);
            _mesh.draw(_shader);
        }

    private:
        Shaders::Flat3D& _shader;
        GL::Mesh& _mesh;
};

MouseInteractionExample::MouseInteractionExample(const Arguments &arguments): Platform::Application{arguments, NoCreate} {
    /* Try 8x MSAA, fall back to zero samples if not possible. Enable only 2x
       MSAA if we have enough DPI. */
    {
        const Vector2 dpiScaling = this->dpiScaling({});
        Configuration conf;
        conf.setTitle("Magnum Mouse Interaction Example")
            .setSize(conf.size(), dpiScaling);
        GLConfiguration glConf;
        glConf.setSampleCount((Vector2{framebufferSize()}*dpiScaling/Vector2{windowSize()}).max() < 2.0f ? 8 : 2);
        if(!tryCreate(conf, glConf))
            create(conf, glConf.setSampleCount(0));
    }

    /* Shaders, renderer setup */
    _vertexColorShader = Shaders::VertexColor3D{};
    _flatShader = Shaders::Flat3D{};
    GL::Renderer::enable(GL::Renderer::Feature::DepthTest);

    /* Triangle data */
    const struct {
        Vector3 pos;
        Color3 color;
    } data[]{{{-1.0f, -1.0f, 0.0f}, 0xff0000_rgbf},
             {{ 1.0f, -1.0f, 0.0f}, 0x00ff00_rgbf},
             {{ 0.0f,  1.0f, 0.0f}, 0x0000ff_rgbf}};

    /* Triangle mesh */
    GL::Buffer buffer;
    buffer.setData(data);
    _mesh = GL::Mesh{};
    _mesh.setCount(3)
        .addVertexBuffer(std::move(buffer), 0,
            Shaders::VertexColor3D::Position{},
            Shaders::VertexColor3D::Color3{});

    /* Triangle object */
    auto triangle = new Object3D{&_scene};
    new VertexColorDrawable{*triangle, _vertexColorShader, _mesh, _drawables};

    /* Grid */
    _grid = MeshTools::compile(Primitives::grid3DWireframe({15, 15}));
    auto grid = new Object3D{&_scene};
    (*grid)
        .rotateX(90.0_degf)
        .scale(Vector3{8.0f});
    new FlatDrawable{*grid, _flatShader, _grid, _drawables};

    /* Set up the camera */
    _cameraObject = new Object3D{&_scene};
    (*_cameraObject)
        .translate(Vector3::zAxis(5.0f))
        .rotateX(-15.0_degf)
        .rotateY(30.0_degf);
    _camera = new SceneGraph::Camera3D{*_cameraObject};
    _camera->setProjectionMatrix(Matrix4::perspectiveProjection(
        45.0_degf, Vector2{windowSize()}.aspectRatio(), 0.01f, 100.0f));
}

Float MouseInteractionExample::depthAt(const Vector2i& position) {
    const Vector2i fbPosition{position.x(), GL::defaultFramebuffer.viewport().sizeY() - position.y() - 1};

    GL::defaultFramebuffer.mapForRead(GL::DefaultFramebuffer::ReadAttachment::Front);
    Image2D data = GL::defaultFramebuffer.read(
        Range2Di::fromSize(fbPosition, Vector2i{1}).padded(Vector2i{2}),
        {GL::PixelFormat::DepthComponent, GL::PixelType::Float});

    return Math::min(Containers::arrayCast<const Float>(data.data()));
}

Vector3 MouseInteractionExample::unproject(const Vector2i& position, Float depth) {
    const Range2Di view = GL::defaultFramebuffer.viewport();
    const Vector2i fbPosition{position.x(), view.sizeY() - position.y() - 1};
    const Vector3 in{2*Vector2{fbPosition - view.min()}/Vector2{view.size()} - Vector2{1.0f}, depth*2.0f - 1.0f};

    /*
        Use the following to get global coordinates instead of camera-relative:

        (_cameraObject->absoluteTransformationMatrix()*_camera->projectionMatrix().inverted()).transformPoint(in)
    */
    return _camera->projectionMatrix().inverted().transformPoint(in);
}

void MouseInteractionExample::mousePressEvent(MouseEvent& event) {
    const Float currentDepth = depthAt(event.position());
    const Float depth = currentDepth == 1.0f ? _lastDepth : currentDepth;
    _translationPoint = unproject(event.position(), depth);
    if(currentDepth != 1.0f) {
        _rotationPoint = _translationPoint;
        _lastDepth = depth;
    }
}

void MouseInteractionExample::mouseMoveEvent(MouseMoveEvent& event) {
    if(_lastPosition == Vector2i{-1}) _lastPosition = event.position();
    const Vector2i delta = event.position() - _lastPosition;
    _lastPosition = event.position();

    if(!event.buttons()) return;

    /* Translate */
    if(event.modifiers() & MouseMoveEvent::Modifier::Shift) {
        const Vector3 p = unproject(event.position(), _lastDepth);
        _cameraObject->translateLocal(_translationPoint - p); /* is Z always 0? */
        _translationPoint = p;

    /* Rotate around rotation point */
    } else _cameraObject->transformLocal(
        Matrix4::translation(_rotationPoint)*
        Matrix4::rotationX(-0.01_radf*delta.y())*
        Matrix4::rotationY(-0.01_radf*delta.x())*
        Matrix4::translation(-_rotationPoint));

    redraw();
}

void MouseInteractionExample::mouseScrollEvent(MouseScrollEvent &event) {
    const Float currentDepth = depthAt(event.position());
    const Float depth = currentDepth == 1.0f ? _lastDepth : currentDepth;
    const Vector3 p = unproject(event.position(), depth);
    if(currentDepth != 1.0f) {
        _rotationPoint = p;
        _lastDepth = depth;
    }

    const Int direction = event.offset().y();
    if(!direction) return;

    /* Move towards/backwards the rotation point in cam coords */
    _cameraObject->translateLocal(_rotationPoint*(direction < 0 ? -1.0f : 1.0f)*0.1f);

    redraw();
}

void MouseInteractionExample::drawEvent() {
    GL::defaultFramebuffer.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth);

    _camera->draw(_drawables);

    swapBuffers();
}

}}

MAGNUM_APPLICATION_MAIN(Magnum::Examples::MouseInteractionExample)
<|endoftext|>


<commit_before>#include <stdexcept>
#include <vector>
#include <windows.h>
#include <string>
#include <algorithm>

#include "Main.h"
#include "GestureClass.h"
#include "Gesture.h"
#include "Frame.h"
#include "Keypress.h"
#include "Console.h"
#include "Filewriter.h"
#include "Filereader.h"
#include "Model.h"

void Model::updateCountDown()
{
	if (!countDownInitiated)
	{
		countDownInitiated = true;
		countDownRef = Clock::now();
		//printf("Get ready to record\n");
		countDown = 4;
		updateUI = true;
	}
	else
	{
		auto t2 = Clock::now();
		long time = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - countDownRef).count();

		if (time >= 1000 && countDown > 3)
		{
			//printf("3 after %ld \n", time);
			--countDown;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if (time >= 2000 && countDown > 2)
		{
			//printf("2 after %ld \n", time);
			--countDown;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if (time >= 3000 && countDown > 1)
		{
			//printf("1 after %ld \n", time);
			--countDown;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if ((time >= 4000 && countDown > 0))
		{

			//printf("GO after %ld \n", time);
			--countDown;
			framesBuffer.clear();
			recording = true;
			//refresh = false;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
											//countDownInitiated = false;

		}
		else if (recording == false && countDown == 0)
		{
			//printf(" recording is done \n");
			--countDown;

			countDownRef = Clock::now();

			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if (time >= 500 && countDown == -1)
		{
			//printf(" delete screen \n");
			--countDown;

			refresh = false;
			countDownInitiated = false;
			updateUI = true;
		}

	}
}

Model::Model()
{
	Filereader::loadAllData(&projects, &gestureClasses);
	if (projects.empty())		//If no project is loaded, else do nothing.
	{
		projects.push_back(std::make_shared<Project>());
	}
	activeProject = projects.back();
}

Model::~Model()
{
}

void Model::setView(std::shared_ptr<UI> v)
{
	view = v;
}

std::shared_ptr<Project> Model::getProject()
{
	return activeProject;
}

void Model::train()
{
	activeProject->setSVMModel(*(SVMInterface::train(activeProject->getProjectMap())));
	Console::print("SVM trained");
	Filewriter::save(activeProject);
	Console::printsl(" -- Project saved");
	activeProject->setLongestGestureSize();
}

int Model::test(Frame & frame)
{
	return SVMInterface::test(activeProject->getSVMModel(), frame);
}

void Model::setActiveLabel(int label)
{
	activeGestureClassLabel = label;
}

void Model::setRefresh(bool refresh)
{
	this->refresh = refresh;
}

bool Model::getRefresh()
{
	return refresh;
}

void Model::setPredict(bool refresh)
{
	this->predict = refresh;
}

void Model::setTrained(bool train)
{
	trained = train;
}

void Model::setRecording(bool record)
{
	recording = record;
}

bool Model::getRecording()
{
	return recording;
}

void Model::addActionToActive(WORD keycode, bool hold)
{
	activeProject->addAction(activeGestureClassLabel, keycode, hold);
}

void Model::addGesture(int label, std::shared_ptr<Gesture> gesture)
{
	if (activeProject->containsLabel(label))
	{
		activeProject->addGesture(label, gesture);
	}
	else
	{
		gestureClasses.push_back(std::make_shared<GestureClass>(gesture));
		activeProject->addNew(label, gestureClasses.back());
	}
	updateUI = true;
}

std::vector<Frame> Model::getRelevantFramesFromBuffer(int offset)
{
	return std::vector<Frame>(framesBuffer.begin(), framesBuffer.end() - offset);
}

void Model::addToLabelsBuffer(int label)
{
	labelsBuffer.push_back(label);

	if (labelsBuffer.size() > activeProject->getLongestGestureSize())
	{
		resizeLabelsBuffer();
	}
}

void Model::resizeLabelsBuffer()
{
	labelsBuffer = std::vector<int>(labelsBuffer.end() - activeProject->getLongestGestureSize(), labelsBuffer.end());
}

bool Model::isGestureExecuted(std::shared_ptr<Gesture> & gesture, int posInBuffer, int recursiveCounter)
{
	int labelOrderPosition = SVMInterface::NB_OF_LABEL_DIVISIONS - recursiveCounter;
	int labelToCheck = gesture->getLabelOrder().at(labelOrderPosition);

	for (int i = posInBuffer; i >= 0; i--)
	{
		if (labelsBuffer.at(i) == labelToCheck)
		{
			if (labelOrderPosition <= 0)
			{
				return true;
			}
			return isGestureExecuted(gesture, i - 1, recursiveCounter + 1);
		}
	}

	return false;
}

void Model::predictAndExecute(int label)
{
	/*
	//Find out what base label the given label belongs to.
	int baseLabel = -1;
	if (activeProject->containsLabel(label))
	{
		baseLabel = label;
	}
	else
	{
		for (int i = SVMInterface::NB_OF_LABEL_DIVISIONS; i > 0; i--)
		{
			if (activeProject->containsLabel(label - i))
			{
				baseLabel = label - i;
				break;
			}
		}
	}

	if (isGestureExecuted(label, labelsBuffer.size() - 1, 1, 0))
	{
		previousPredictedLabel = predictedLabel;
		predictedLabel = baseLabel;

		Console::print("Predicted label: ");
		Console::printsl(predictedLabel);
		labelsBuffer.clear();

		if (previousPredictedLabel < 0)
		{
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel != predictedLabel)
		{
			activeProject->deactivate(previousPredictedLabel);
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel == predictedLabel)
		{
			activeProject->activate(predictedLabel);
		}
	}
	*/

	int executedLabel = -1;
	for (const auto & keyValue : activeProject->getProjectMap())
	{
		for (std::shared_ptr<Gesture> gesture : keyValue.second.first->getGestures())
		{
			if (isGestureExecuted(gesture, labelsBuffer.size() - 1, 1))
			{
				executedLabel = keyValue.first;
			}
		}
	}

	if (executedLabel != -1)
	{
		previousPredictedLabel = predictedLabel;
		predictedLabel = executedLabel;

		Console::print("Predicted label: ");
		Console::printsl(predictedLabel);

		labelsBuffer.clear();
		labelsBuffer.push_back(10);

		if (previousPredictedLabel < 0)
		{
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel != predictedLabel)
		{
			activeProject->deactivate(previousPredictedLabel);
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel == predictedLabel)
		{
			activeProject->activate(predictedLabel);
		}
	}
}

std::shared_ptr<GestureClass> Model::getGestureClassByID(const int & ID)
{
	for (int i = 0; i < gestureClasses.size(); ++i)
	{
		if (gestureClasses[i] != nullptr)
		{
			if (gestureClasses[i]->getGestureClassID() == ID)
				return gestureClasses[i];
		}
	}

	//give the last gestureClass back
	//return gestureClasses[gestureClasses.size()-1];
	return nullptr;
}

void Model::displayFrames()
{
	if (view->checkResource())
	{
		view->drawFrames(relFrames, absFrames);
	}

	relFrames.clear();
	absFrames.clear();
}

void Model::processBody(INT64 nTime, int nBodyCount, IBody ** ppBodies)
{
	//Go through all the bodies that are being seen now. If a body is tracked, its frame is made and added to the frames vector
	for (int i = 0; i < nBodyCount; ++i)
	{
		pBody = ppBodies[i];
		if (pBody)
		{
			BOOLEAN bTracked = false;
			HRESULT hr = pBody->get_IsTracked(&bTracked);

			if (currentActiveBody == -1 && SUCCEEDED(hr) && bTracked)	//No body is tracked at the moment
			{
				currentActiveBody = i;
			}

			if (SUCCEEDED(hr) && bTracked && i == currentActiveBody)
			{
				Frame relFrame(pBody);					//Create a frame of every tracked body
				Frame absFrame(pBody, false);

				relFrames.push_back(relFrame);
				absFrames.push_back(absFrame);

				if (recording)
				{
					recordGesture(relFrame);
					break;
				}

				framesBuffer.push_back(relFrame);

				if (refresh && !predict)				//The measure button was pressed last
				{
					updateCountDown();
				}

				if (predict)
				{
					if (!trained)						//If the model is not yet trained, train it
					{
						train();
						trained = true;
					}
					int label = SVMInterface::test(activeProject->getSVMModel(), relFrame);
					addToLabelsBuffer(label);
					predictAndExecute(label);
					view->setPredictedLabel(label);
				}
			}
			else if (i == currentActiveBody)			//If the current tracked body is lost for this frame
			{
				bodyLostCounter++;						//Increment the lostBodyCounter
				if (bodyLostCounter > BODY_LOST_LIMIT)	//If the limit is reached, reset the currentActiveBody
				{
					currentActiveBody = -1;
					bodyLostCounter = 0;
				}
			}
		}
	}

	if (updateUI)
	{
		view->updateHitboxes();
		updateUI = false;
	}

	displayFrames();
}

void Model::recordGesture(Frame & frame)
{
	if (!initialized)
	{
		frameNeutral.setFrame(frame);
		initialized = true;
		Console::print("Initialized recording");
	}

	//relFrames.push_back(frame);
	framesBuffer.push_back(frame);

	if (!startedMoving)
	{
		if (! frame.equals(frameNeutral))
		{
			Console::print("Motion detected -- start recording frames");
			startedMoving = true;
			if (framesBuffer.size() > 20)
			{
				std::vector<Frame> latestFrames = getRelevantFramesFromBuffer(10);
				framesBuffer.clear();
				for (Frame frame : latestFrames)
				{
					framesBuffer.push_back(frame);
				}
			}
		}
		else if (framesBuffer.size() > NOT_MOVING_FRAME_DELAY)
		{
			Console::print("Standing still -- posture recorded");
			addRecordedGesture();
		}
		else
		{
			return;
		}
	}

	if (framesBuffer.size() > NOT_MOVING_FRAME_DELAY &&
		framesBuffer.back().equals(framesBuffer.at(framesBuffer.size() - NOT_MOVING_FRAME_DELAY)) &&
		framesBuffer.back().equals(framesBuffer.at(framesBuffer.size() - NOT_MOVING_FRAME_DELAY/2)))
	{
		addRecordedGesture();
	}
}

bool Model::getCountDownInit()
{
	return countDownInitiated;
}

int Model::getCountDown()
{
	return countDown;
}

void Model::setUpdatUI(bool update)
{
	updateUI = update;
}

bool Model::getUpdateUI()
{
	return updateUI;
}

void Model::addRecordedGesture()
{
	std::shared_ptr<Gesture> gesture = std::make_shared<Gesture>( getRelevantFramesFromBuffer(NOT_MOVING_FRAME_DELAY-20) );
	addGesture(activeGestureClassLabel, gesture);
	recording = false;
	initialized = false;
	startedMoving = false;
	framesBuffer.clear();
	Console::print("Recording stopped");
}
<commit_msg>Updated algorithm<commit_after>#include <stdexcept>
#include <vector>
#include <windows.h>
#include <string>
#include <algorithm>

#include "Main.h"
#include "GestureClass.h"
#include "Gesture.h"
#include "Frame.h"
#include "Keypress.h"
#include "Console.h"
#include "Filewriter.h"
#include "Filereader.h"
#include "Model.h"

void Model::updateCountDown()
{
	if (!countDownInitiated)
	{
		countDownInitiated = true;
		countDownRef = Clock::now();
		//printf("Get ready to record\n");
		countDown = 4;
		updateUI = true;
	}
	else
	{
		auto t2 = Clock::now();
		long time = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - countDownRef).count();

		if (time >= 1000 && countDown > 3)
		{
			//printf("3 after %ld \n", time);
			--countDown;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if (time >= 2000 && countDown > 2)
		{
			//printf("2 after %ld \n", time);
			--countDown;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if (time >= 3000 && countDown > 1)
		{
			//printf("1 after %ld \n", time);
			--countDown;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if ((time >= 4000 && countDown > 0))
		{

			//printf("GO after %ld \n", time);
			--countDown;
			framesBuffer.clear();
			recording = true;
			//refresh = false;
			updateUI = true;				//the UI will update it's state based on the countDown parameter
											//countDownInitiated = false;

		}
		else if (recording == false && countDown == 0)
		{
			//printf(" recording is done \n");
			--countDown;

			countDownRef = Clock::now();

			updateUI = true;				//the UI will update it's state based on the countDown parameter
		}
		else if (time >= 500 && countDown == -1)
		{
			//printf(" delete screen \n");
			--countDown;

			refresh = false;
			countDownInitiated = false;
			updateUI = true;
		}

	}
}

Model::Model()
{
	Filereader::loadAllData(&projects, &gestureClasses);
	if (projects.empty())		//If no project is loaded, else do nothing.
	{
		projects.push_back(std::make_shared<Project>());
	}
	activeProject = projects.back();
}

Model::~Model()
{
}

void Model::setView(std::shared_ptr<UI> v)
{
	view = v;
}

std::shared_ptr<Project> Model::getProject()
{
	return activeProject;
}

void Model::train()
{
	activeProject->setSVMModel(*(SVMInterface::train(activeProject->getProjectMap())));
	Console::print("SVM trained");
	Filewriter::save(activeProject);
	Console::printsl(" -- Project saved");
	activeProject->setLongestGestureSize();
}

int Model::test(Frame & frame)
{
	return SVMInterface::test(activeProject->getSVMModel(), frame);
}

void Model::setActiveLabel(int label)
{
	activeGestureClassLabel = label;
}

void Model::setRefresh(bool refresh)
{
	this->refresh = refresh;
}

bool Model::getRefresh()
{
	return refresh;
}

void Model::setPredict(bool refresh)
{
	this->predict = refresh;
}

void Model::setTrained(bool train)
{
	trained = train;
}

void Model::setRecording(bool record)
{
	recording = record;
}

bool Model::getRecording()
{
	return recording;
}

void Model::addActionToActive(WORD keycode, bool hold)
{
	activeProject->addAction(activeGestureClassLabel, keycode, hold);
}

void Model::addGesture(int label, std::shared_ptr<Gesture> gesture)
{
	if (activeProject->containsLabel(label))
	{
		activeProject->addGesture(label, gesture);
	}
	else
	{
		gestureClasses.push_back(std::make_shared<GestureClass>(gesture));
		activeProject->addNew(label, gestureClasses.back());
	}
	updateUI = true;
}

std::vector<Frame> Model::getRelevantFramesFromBuffer(int offset)
{
	return std::vector<Frame>(framesBuffer.begin(), framesBuffer.end() - offset);
}

void Model::addToLabelsBuffer(int label)
{
	labelsBuffer.push_back(label);

	if (labelsBuffer.size() > activeProject->getLongestGestureSize())
	{
		resizeLabelsBuffer();
	}
}

void Model::resizeLabelsBuffer()
{
	labelsBuffer = std::vector<int>(labelsBuffer.end() - activeProject->getLongestGestureSize(), labelsBuffer.end());
}

bool Model::isGestureExecuted(std::shared_ptr<Gesture> & gesture, int posInBuffer, int recursiveCounter)
{
	int labelOrderPosition = SVMInterface::NB_OF_LABEL_DIVISIONS - recursiveCounter;
	int labelToCheck = gesture->getLabelOrder().at(labelOrderPosition);

	for (int i = posInBuffer; i >= 0; i--)
	{
		if (labelsBuffer.at(i) == labelToCheck)
		{
			if (labelOrderPosition <= 0)
			{
				return true;
			}
			return isGestureExecuted(gesture, i - 1, recursiveCounter + 1);
		}
	}

	return false;
}

void Model::predictAndExecute(int label)
{
	/*
	//Find out what base label the given label belongs to.
	int baseLabel = -1;
	if (activeProject->containsLabel(label))
	{
		baseLabel = label;
	}
	else
	{
		for (int i = SVMInterface::NB_OF_LABEL_DIVISIONS; i > 0; i--)
		{
			if (activeProject->containsLabel(label - i))
			{
				baseLabel = label - i;
				break;
			}
		}
	}

	if (isGestureExecuted(label, labelsBuffer.size() - 1, 1, 0))
	{
		previousPredictedLabel = predictedLabel;
		predictedLabel = baseLabel;

		Console::print("Predicted label: ");
		Console::printsl(predictedLabel);
		labelsBuffer.clear();

		if (previousPredictedLabel < 0)
		{
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel != predictedLabel)
		{
			activeProject->deactivate(previousPredictedLabel);
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel == predictedLabel)
		{
			activeProject->activate(predictedLabel);
		}
	}
	*/

	int executedLabel = -1;
	for (const auto & keyValue : activeProject->getProjectMap())
	{
		for (std::shared_ptr<Gesture> gesture : keyValue.second.first->getGestures())
		{
			if (isGestureExecuted(gesture, labelsBuffer.size() - 1, 1))
			{
				executedLabel = keyValue.first;
			}
		}
	}

	if (executedLabel != -1)
	{
		previousPredictedLabel = predictedLabel;
		predictedLabel = executedLabel;

		Console::print("Predicted label: ");
		Console::printsl(predictedLabel);

		labelsBuffer.clear();
		labelsBuffer.push_back(activeProject->getProjectMap().find(1)->second.first->getGestures().front()->getLabelOrder().front());
		Console::print("Added label: ");
		Console::print(activeProject->getProjectMap().find(1)->second.first->getGestures().front()->getLabelOrder().front());

		if (previousPredictedLabel < 0)
		{
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel != predictedLabel)
		{
			activeProject->deactivate(previousPredictedLabel);
			activeProject->activate(predictedLabel);
		}
		else if (previousPredictedLabel == predictedLabel)
		{
			activeProject->activate(predictedLabel);
		}
	}
}

std::shared_ptr<GestureClass> Model::getGestureClassByID(const int & ID)
{
	for (int i = 0; i < gestureClasses.size(); ++i)
	{
		if (gestureClasses[i] != nullptr)
		{
			if (gestureClasses[i]->getGestureClassID() == ID)
				return gestureClasses[i];
		}
	}

	//give the last gestureClass back
	//return gestureClasses[gestureClasses.size()-1];
	return nullptr;
}

void Model::displayFrames()
{
	if (view->checkResource())
	{
		view->drawFrames(relFrames, absFrames);
	}

	relFrames.clear();
	absFrames.clear();
}

void Model::processBody(INT64 nTime, int nBodyCount, IBody ** ppBodies)
{
	//Go through all the bodies that are being seen now. If a body is tracked, its frame is made and added to the frames vector
	for (int i = 0; i < nBodyCount; ++i)
	{
		pBody = ppBodies[i];
		if (pBody)
		{
			BOOLEAN bTracked = false;
			HRESULT hr = pBody->get_IsTracked(&bTracked);

			if (currentActiveBody == -1 && SUCCEEDED(hr) && bTracked)	//No body is tracked at the moment
			{
				currentActiveBody = i;
			}

			if (SUCCEEDED(hr) && bTracked && i == currentActiveBody)
			{
				Frame relFrame(pBody);					//Create a frame of every tracked body
				Frame absFrame(pBody, false);

				relFrames.push_back(relFrame);
				absFrames.push_back(absFrame);

				if (recording)
				{
					recordGesture(relFrame);
					break;
				}

				framesBuffer.push_back(relFrame);

				if (refresh && !predict)				//The measure button was pressed last
				{
					updateCountDown();
				}

				if (predict)
				{
					if (!trained)						//If the model is not yet trained, train it
					{
						train();
						trained = true;
					}
					int label = SVMInterface::test(activeProject->getSVMModel(), relFrame);
					addToLabelsBuffer(label);
					predictAndExecute(label);
					view->setPredictedLabel(label);
				}
			}
			else if (i == currentActiveBody)			//If the current tracked body is lost for this frame
			{
				bodyLostCounter++;						//Increment the lostBodyCounter
				if (bodyLostCounter > BODY_LOST_LIMIT)	//If the limit is reached, reset the currentActiveBody
				{
					currentActiveBody = -1;
					bodyLostCounter = 0;
				}
			}
		}
	}

	if (updateUI)
	{
		view->updateHitboxes();
		updateUI = false;
	}

	displayFrames();
}

void Model::recordGesture(Frame & frame)
{
	if (!initialized)
	{
		frameNeutral.setFrame(frame);
		initialized = true;
		Console::print("Initialized recording");
	}

	//relFrames.push_back(frame);
	framesBuffer.push_back(frame);

	if (!startedMoving)
	{
		if (! frame.equals(frameNeutral))
		{
			Console::print("Motion detected -- start recording frames");
			startedMoving = true;
			if (framesBuffer.size() > 20)
			{
				std::vector<Frame> latestFrames = getRelevantFramesFromBuffer(10);
				framesBuffer.clear();
				for (Frame frame : latestFrames)
				{
					framesBuffer.push_back(frame);
				}
			}
		}
		else if (framesBuffer.size() > NOT_MOVING_FRAME_DELAY)
		{
			Console::print("Standing still -- posture recorded");
			addRecordedGesture();
		}
		else
		{
			return;
		}
	}

	if (framesBuffer.size() > NOT_MOVING_FRAME_DELAY &&
		framesBuffer.back().equals(framesBuffer.at(framesBuffer.size() - NOT_MOVING_FRAME_DELAY)) &&
		framesBuffer.back().equals(framesBuffer.at(framesBuffer.size() - NOT_MOVING_FRAME_DELAY/2)))
	{
		addRecordedGesture();
	}
}

bool Model::getCountDownInit()
{
	return countDownInitiated;
}

int Model::getCountDown()
{
	return countDown;
}

void Model::setUpdatUI(bool update)
{
	updateUI = update;
}

bool Model::getUpdateUI()
{
	return updateUI;
}

void Model::addRecordedGesture()
{
	std::shared_ptr<Gesture> gesture = std::make_shared<Gesture>( getRelevantFramesFromBuffer(NOT_MOVING_FRAME_DELAY-20) );
	addGesture(activeGestureClassLabel, gesture);
	recording = false;
	initialized = false;
	startedMoving = false;
	framesBuffer.clear();
	Console::print("Recording stopped");
}
<|endoftext|>


<commit_before>/**
 * @file neighbor_search_impl.hpp
 * @author Ryan Curtin
 *
 * Implementation of Neighbor-Search class to perform all-nearest-neighbors on
 * two specified data sets.
 */
#ifndef __MLPACK_METHODS_NEIGHBOR_SEARCH_NEIGHBOR_SEARCH_IMPL_HPP
#define __MLPACK_METHODS_NEIGHBOR_SEARCH_NEIGHBOR_SEARCH_IMPL_HPP

#include <mlpack/core.hpp>

#include "neighbor_search_rules.hpp"

using namespace mlpack::neighbor;

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::
NeighborSearch(const typename TreeType::Mat& referenceSet,
               const typename TreeType::Mat& querySet,
               const bool naive,
               const bool singleMode,
               const size_t leafSize,
               const MetricType metric) :
    referenceCopy(referenceSet),
    queryCopy(querySet),
    referenceSet(referenceCopy),
    querySet(queryCopy),
    referenceTree(NULL),
    queryTree(NULL),
    ownReferenceTree(true), // False if a tree was passed.
    ownQueryTree(true), // False if a tree was passed.
    naive(naive),
    singleMode(!naive && singleMode), // No single mode if naive.
    metric(metric),
    numberOfPrunes(0)
{
  // C++11 will allow us to call out to other constructors so we can avoid this
  // copypasta problem.

  // We'll time tree building, but only if we are building trees.
  if (!referenceTree || !queryTree)
    Timer::Start("tree_building");

  // Construct as a naive object if we need to.
  referenceTree = new TreeType(referenceCopy, oldFromNewReferences,
      (naive ? referenceCopy.n_cols : leafSize));

  queryTree = new TreeType(queryCopy, oldFromNewQueries,
      (naive ? querySet.n_cols : leafSize));

  // Stop the timer we started above (if we need to).
  if (!referenceTree || !queryTree)
    Timer::Stop("tree_building");
}

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::
NeighborSearch(const typename TreeType::Mat& referenceSet,
               const bool naive,
               const bool singleMode,
               const size_t leafSize,
               const MetricType metric) :
    referenceCopy(referenceSet),
    referenceSet(referenceCopy),
    querySet(referenceCopy),
    referenceTree(NULL),
    queryTree(NULL),
    ownReferenceTree(true),
    ownQueryTree(false), // Since it will be the same as referenceTree.
    naive(naive),
    singleMode(!naive && singleMode), // No single mode if naive.
    metric(metric),
    numberOfPrunes(0)
{
  // We'll time tree building, but only if we are building trees.
  Timer::Start("tree_building");

  // Construct as a naive object if we need to.
  referenceTree = new TreeType(referenceCopy, oldFromNewReferences,
      (naive ? referenceSet.n_cols : leafSize));

  // Stop the timer we started above.
  Timer::Stop("tree_building");
}

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::NeighborSearch(
    TreeType* referenceTree,
    TreeType* queryTree,
    const typename TreeType::Mat& referenceSet,
    const typename TreeType::Mat& querySet,
    const bool singleMode,
    const MetricType metric) :
    referenceSet(referenceSet),
    querySet(querySet),
    referenceTree(referenceTree),
    queryTree(queryTree),
    ownReferenceTree(false),
    ownQueryTree(false),
    naive(false),
    singleMode(singleMode),
    metric(metric),
    numberOfPrunes(0)
{
  // Nothing else to initialize.
}

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::NeighborSearch(
    TreeType* referenceTree,
    const typename TreeType::Mat& referenceSet,
    const bool singleMode,
    const MetricType metric) :
    referenceSet(referenceSet),
    querySet(referenceSet),
    referenceTree(referenceTree),
    queryTree(NULL),
    ownReferenceTree(false),
    ownQueryTree(false),
    naive(false),
    singleMode(singleMode),
    metric(metric),
    numberOfPrunes(0)
{
  // Nothing else to initialize.
}

/**
 * The tree is the only member we may be responsible for deleting.  The others
 * will take care of themselves.
 */
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::~NeighborSearch()
{
  if (ownReferenceTree)
    delete referenceTree;
  if (ownQueryTree)
    delete queryTree;
}

/**
 * Computes the best neighbors and stores them in resultingNeighbors and
 * distances.
 */
template<typename SortPolicy, typename MetricType, typename TreeType>
void NeighborSearch<SortPolicy, MetricType, TreeType>::Search(
    const size_t k,
    arma::Mat<size_t>& resultingNeighbors,
    arma::mat& distances)
{
  Timer::Start("computing_neighbors");

  // If we have built the trees ourselves, then we will have to map all the
  // indices back to their original indices when this computation is finished.
  // To avoid an extra copy, we will store the neighbors and distances in a
  // separate matrix.
  arma::Mat<size_t>* neighborPtr = &resultingNeighbors;
  arma::mat* distancePtr = &distances;

  if (ownQueryTree || (ownReferenceTree && !queryTree))
    distancePtr = new arma::mat; // Query indices need to be mapped.
  if (ownReferenceTree || ownQueryTree)
    neighborPtr = new arma::Mat<size_t>; // All indices need mapping.

  // Set the size of the neighbor and distance matrices.
  neighborPtr->set_size(k, querySet.n_cols);
  distancePtr->set_size(k, querySet.n_cols);
  distancePtr->fill(SortPolicy::WorstDistance());

  size_t numPrunes = 0;

  if (singleMode)
  {
    // Create the helper object for the tree traversal.
    typedef NeighborSearchRules<SortPolicy, MetricType, TreeType> RuleType;
    RuleType rules(referenceSet, querySet, *neighborPtr, *distancePtr, metric);

    // Create the traverser.
    typename TreeType::template SingleTreeTraverser<RuleType> traverser(rules);

    // Now have it traverse for each point.
    for (size_t i = 0; i < querySet.n_cols; ++i)
      traverser.Traverse(i, *referenceTree);

    numPrunes = traverser.NumPrunes();
  }
  else // Dual-tree recursion.
  {
    // Create the helper object for the tree traversal.
    typedef NeighborSearchRules<SortPolicy, MetricType, TreeType> RuleType;
    RuleType rules(referenceSet, querySet, *neighborPtr, *distancePtr, metric);

    typename TreeType::template DualTreeTraverser<RuleType> traverser(rules);

    if (queryTree)
      traverser.Traverse(*queryTree, *referenceTree);
    else
      traverser.Traverse(*referenceTree, *referenceTree);

    numPrunes = traverser.NumPrunes();
  }

  Log::Warn << "Pruned " << numPrunes << " nodes." << std::endl;

  Timer::Stop("computing_neighbors");

  // Now, do we need to do mapping of indices?
  if (!ownReferenceTree && !ownQueryTree)
  {
    // No mapping needed.  We are done.
    return;
  }
  else if (ownReferenceTree && ownQueryTree) // Map references and queries.
  {
    // Set size of output matrices correctly.
    resultingNeighbors.set_size(k, querySet.n_cols);
    distances.set_size(k, querySet.n_cols);

    for (size_t i = 0; i < distances.n_cols; i++)
    {
      // Map distances (copy a column).
      distances.col(oldFromNewQueries[i]) = distancePtr->col(i);

      // Map indices of neighbors.
      for (size_t j = 0; j < distances.n_rows; j++)
      {
        resultingNeighbors(j, oldFromNewQueries[i]) =
            oldFromNewReferences[(*neighborPtr)(j, i)];
      }
    }

    // Finished with temporary matrices.
    delete neighborPtr;
    delete distancePtr;
  }
  else if (ownReferenceTree)
  {
    if (!queryTree) // No query tree -- map both references and queries.
    {
      resultingNeighbors.set_size(k, querySet.n_cols);
      distances.set_size(k, querySet.n_cols);

      for (size_t i = 0; i < distances.n_cols; i++)
      {
        // Map distances (copy a column).
        distances.col(oldFromNewReferences[i]) = distancePtr->col(i);

        // Map indices of neighbors.
        for (size_t j = 0; j < distances.n_rows; j++)
        {
          resultingNeighbors(j, oldFromNewReferences[i]) =
              oldFromNewReferences[(*neighborPtr)(j, i)];
        }
      }
    }
    else // Map only references.
    {
      // Set size of neighbor indices matrix correctly.
      resultingNeighbors.set_size(k, querySet.n_cols);

      // Map indices of neighbors.
      for (size_t i = 0; i < resultingNeighbors.n_cols; i++)
      {
        for (size_t j = 0; j < resultingNeighbors.n_rows; j++)
        {
          resultingNeighbors(j, i) = oldFromNewReferences[(*neighborPtr)(j, i)];
        }
      }
    }

    // Finished with temporary matrix.
    delete neighborPtr;
  }
  else if (ownQueryTree)
  {
    // Set size of matrices correctly.
    resultingNeighbors.set_size(k, querySet.n_cols);
    distances.set_size(k, querySet.n_cols);

    for (size_t i = 0; i < distances.n_cols; i++)
    {
      // Map distances (copy a column).
      distances.col(oldFromNewQueries[i]) = distancePtr->col(i);

      // Map indices of neighbors.
      resultingNeighbors.col(oldFromNewQueries[i]) = neighborPtr->col(i);
    }

    // Finished with temporary matrices.
    delete neighborPtr;
    delete distancePtr;
  }
} // Search

#endif
<commit_msg>Debugging output, not warning output.  Oops.<commit_after>/**
 * @file neighbor_search_impl.hpp
 * @author Ryan Curtin
 *
 * Implementation of Neighbor-Search class to perform all-nearest-neighbors on
 * two specified data sets.
 */
#ifndef __MLPACK_METHODS_NEIGHBOR_SEARCH_NEIGHBOR_SEARCH_IMPL_HPP
#define __MLPACK_METHODS_NEIGHBOR_SEARCH_NEIGHBOR_SEARCH_IMPL_HPP

#include <mlpack/core.hpp>

#include "neighbor_search_rules.hpp"

using namespace mlpack::neighbor;

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::
NeighborSearch(const typename TreeType::Mat& referenceSet,
               const typename TreeType::Mat& querySet,
               const bool naive,
               const bool singleMode,
               const size_t leafSize,
               const MetricType metric) :
    referenceCopy(referenceSet),
    queryCopy(querySet),
    referenceSet(referenceCopy),
    querySet(queryCopy),
    referenceTree(NULL),
    queryTree(NULL),
    ownReferenceTree(true), // False if a tree was passed.
    ownQueryTree(true), // False if a tree was passed.
    naive(naive),
    singleMode(!naive && singleMode), // No single mode if naive.
    metric(metric),
    numberOfPrunes(0)
{
  // C++11 will allow us to call out to other constructors so we can avoid this
  // copypasta problem.

  // We'll time tree building, but only if we are building trees.
  if (!referenceTree || !queryTree)
    Timer::Start("tree_building");

  // Construct as a naive object if we need to.
  referenceTree = new TreeType(referenceCopy, oldFromNewReferences,
      (naive ? referenceCopy.n_cols : leafSize));

  queryTree = new TreeType(queryCopy, oldFromNewQueries,
      (naive ? querySet.n_cols : leafSize));

  // Stop the timer we started above (if we need to).
  if (!referenceTree || !queryTree)
    Timer::Stop("tree_building");
}

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::
NeighborSearch(const typename TreeType::Mat& referenceSet,
               const bool naive,
               const bool singleMode,
               const size_t leafSize,
               const MetricType metric) :
    referenceCopy(referenceSet),
    referenceSet(referenceCopy),
    querySet(referenceCopy),
    referenceTree(NULL),
    queryTree(NULL),
    ownReferenceTree(true),
    ownQueryTree(false), // Since it will be the same as referenceTree.
    naive(naive),
    singleMode(!naive && singleMode), // No single mode if naive.
    metric(metric),
    numberOfPrunes(0)
{
  // We'll time tree building, but only if we are building trees.
  Timer::Start("tree_building");

  // Construct as a naive object if we need to.
  referenceTree = new TreeType(referenceCopy, oldFromNewReferences,
      (naive ? referenceSet.n_cols : leafSize));

  // Stop the timer we started above.
  Timer::Stop("tree_building");
}

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::NeighborSearch(
    TreeType* referenceTree,
    TreeType* queryTree,
    const typename TreeType::Mat& referenceSet,
    const typename TreeType::Mat& querySet,
    const bool singleMode,
    const MetricType metric) :
    referenceSet(referenceSet),
    querySet(querySet),
    referenceTree(referenceTree),
    queryTree(queryTree),
    ownReferenceTree(false),
    ownQueryTree(false),
    naive(false),
    singleMode(singleMode),
    metric(metric),
    numberOfPrunes(0)
{
  // Nothing else to initialize.
}

// Construct the object.
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::NeighborSearch(
    TreeType* referenceTree,
    const typename TreeType::Mat& referenceSet,
    const bool singleMode,
    const MetricType metric) :
    referenceSet(referenceSet),
    querySet(referenceSet),
    referenceTree(referenceTree),
    queryTree(NULL),
    ownReferenceTree(false),
    ownQueryTree(false),
    naive(false),
    singleMode(singleMode),
    metric(metric),
    numberOfPrunes(0)
{
  // Nothing else to initialize.
}

/**
 * The tree is the only member we may be responsible for deleting.  The others
 * will take care of themselves.
 */
template<typename SortPolicy, typename MetricType, typename TreeType>
NeighborSearch<SortPolicy, MetricType, TreeType>::~NeighborSearch()
{
  if (ownReferenceTree)
    delete referenceTree;
  if (ownQueryTree)
    delete queryTree;
}

/**
 * Computes the best neighbors and stores them in resultingNeighbors and
 * distances.
 */
template<typename SortPolicy, typename MetricType, typename TreeType>
void NeighborSearch<SortPolicy, MetricType, TreeType>::Search(
    const size_t k,
    arma::Mat<size_t>& resultingNeighbors,
    arma::mat& distances)
{
  Timer::Start("computing_neighbors");

  // If we have built the trees ourselves, then we will have to map all the
  // indices back to their original indices when this computation is finished.
  // To avoid an extra copy, we will store the neighbors and distances in a
  // separate matrix.
  arma::Mat<size_t>* neighborPtr = &resultingNeighbors;
  arma::mat* distancePtr = &distances;

  if (ownQueryTree || (ownReferenceTree && !queryTree))
    distancePtr = new arma::mat; // Query indices need to be mapped.
  if (ownReferenceTree || ownQueryTree)
    neighborPtr = new arma::Mat<size_t>; // All indices need mapping.

  // Set the size of the neighbor and distance matrices.
  neighborPtr->set_size(k, querySet.n_cols);
  distancePtr->set_size(k, querySet.n_cols);
  distancePtr->fill(SortPolicy::WorstDistance());

  size_t numPrunes = 0;

  if (singleMode)
  {
    // Create the helper object for the tree traversal.
    typedef NeighborSearchRules<SortPolicy, MetricType, TreeType> RuleType;
    RuleType rules(referenceSet, querySet, *neighborPtr, *distancePtr, metric);

    // Create the traverser.
    typename TreeType::template SingleTreeTraverser<RuleType> traverser(rules);

    // Now have it traverse for each point.
    for (size_t i = 0; i < querySet.n_cols; ++i)
      traverser.Traverse(i, *referenceTree);

    numPrunes = traverser.NumPrunes();
  }
  else // Dual-tree recursion.
  {
    // Create the helper object for the tree traversal.
    typedef NeighborSearchRules<SortPolicy, MetricType, TreeType> RuleType;
    RuleType rules(referenceSet, querySet, *neighborPtr, *distancePtr, metric);

    typename TreeType::template DualTreeTraverser<RuleType> traverser(rules);

    if (queryTree)
      traverser.Traverse(*queryTree, *referenceTree);
    else
      traverser.Traverse(*referenceTree, *referenceTree);

    numPrunes = traverser.NumPrunes();
  }

  Log::Debug << "Pruned " << numPrunes << " nodes." << std::endl;

  Timer::Stop("computing_neighbors");

  // Now, do we need to do mapping of indices?
  if (!ownReferenceTree && !ownQueryTree)
  {
    // No mapping needed.  We are done.
    return;
  }
  else if (ownReferenceTree && ownQueryTree) // Map references and queries.
  {
    // Set size of output matrices correctly.
    resultingNeighbors.set_size(k, querySet.n_cols);
    distances.set_size(k, querySet.n_cols);

    for (size_t i = 0; i < distances.n_cols; i++)
    {
      // Map distances (copy a column).
      distances.col(oldFromNewQueries[i]) = distancePtr->col(i);

      // Map indices of neighbors.
      for (size_t j = 0; j < distances.n_rows; j++)
      {
        resultingNeighbors(j, oldFromNewQueries[i]) =
            oldFromNewReferences[(*neighborPtr)(j, i)];
      }
    }

    // Finished with temporary matrices.
    delete neighborPtr;
    delete distancePtr;
  }
  else if (ownReferenceTree)
  {
    if (!queryTree) // No query tree -- map both references and queries.
    {
      resultingNeighbors.set_size(k, querySet.n_cols);
      distances.set_size(k, querySet.n_cols);

      for (size_t i = 0; i < distances.n_cols; i++)
      {
        // Map distances (copy a column).
        distances.col(oldFromNewReferences[i]) = distancePtr->col(i);

        // Map indices of neighbors.
        for (size_t j = 0; j < distances.n_rows; j++)
        {
          resultingNeighbors(j, oldFromNewReferences[i]) =
              oldFromNewReferences[(*neighborPtr)(j, i)];
        }
      }
    }
    else // Map only references.
    {
      // Set size of neighbor indices matrix correctly.
      resultingNeighbors.set_size(k, querySet.n_cols);

      // Map indices of neighbors.
      for (size_t i = 0; i < resultingNeighbors.n_cols; i++)
      {
        for (size_t j = 0; j < resultingNeighbors.n_rows; j++)
        {
          resultingNeighbors(j, i) = oldFromNewReferences[(*neighborPtr)(j, i)];
        }
      }
    }

    // Finished with temporary matrix.
    delete neighborPtr;
  }
  else if (ownQueryTree)
  {
    // Set size of matrices correctly.
    resultingNeighbors.set_size(k, querySet.n_cols);
    distances.set_size(k, querySet.n_cols);

    for (size_t i = 0; i < distances.n_cols; i++)
    {
      // Map distances (copy a column).
      distances.col(oldFromNewQueries[i]) = distancePtr->col(i);

      // Map indices of neighbors.
      resultingNeighbors.col(oldFromNewQueries[i]) = neighborPtr->col(i);
    }

    // Finished with temporary matrices.
    delete neighborPtr;
    delete distancePtr;
  }
} // Search

#endif
<|endoftext|>


<commit_before>// Quick and dirty tool to decode GlobalCache (GC) codes
// Copyright 2017 Jorge Cisneros

#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include "IRsend.h"
#include "IRsend_test.h"
#include "IRutils.h"

#define MAX_GC_CODE_LENGTH 10000

void str_to_uint16(char *str, uint16_t *res) {
  char *end;
  errno = 0;
  intmax_t val = strtoimax(str, &end, 10);
  if (errno == ERANGE || val < 0 || val > UINT16_MAX ||
    end == str || *end != '\0')
    return;
  *res = (uint16_t) val;
}

void usage_error(char * name) {
  std::cerr << "Usage: " << name << " [-raw] <global_code>" << std::endl;
}

int main(int argc, char * argv[]) {
  int argv_offset = 1;
  bool dumpraw = false;

  // Check the invocation/calling usage.
  if (argc < 2 || argc > 3) {
    usage_error(argv[0]);
    return 1;
  }
  if (strncmp("-raw", argv[argv_offset], 4) == 0) {
    dumpraw = true;
    argv_offset++;
  }
  if (argc - argv_offset != 1) {
    usage_error(argv[0]);
    return 1;
  }

  uint16_t gc_test[MAX_GC_CODE_LENGTH];
  int index = 0;
  char *pch;
  char *saveptr1;

  pch = strtok_r(argv[argv_offset], ",", &saveptr1);
  while (pch != NULL && index < MAX_GC_CODE_LENGTH) {
    str_to_uint16(pch, &gc_test[index]);
    pch = strtok_r(NULL, ",", &saveptr1);
    index++;
  }

  IRsendTest irsend(4);
  IRrecv irrecv(4);
  irsend.begin();
  irsend.reset();

  irsend.sendGC(gc_test, index);
  irsend.makeDecodeResult();
  irrecv.decode(&irsend.capture);

  std::cout << "Code GC length " << index << std::endl
  << "Code type      " << irsend.capture.decode_type
  << " (" << typeToString(irsend.capture.decode_type) << ")" << std::endl
  << "Code bits      " << irsend.capture.bits << std::endl;
  if (hasACState(irsend.capture.decode_type)) {
    std::cout << "State value    0x";
    for (uint16_t i = 0; i < irsend.capture.bits / 8; i++)
      printf("%02X", irsend.capture.state[i]);
    std::cout << std::endl;
  } else {
    std::cout << "Code value     0x" <<
        std::hex << irsend.capture.value << std::endl <<
        "Code address   0x" << std::hex << irsend.capture.address << std::endl
        << "Code command   0x" << std::hex << irsend.capture.command <<
        std::endl;
  }

  if (dumpraw || irsend.capture.decode_type == UNKNOWN)
    irsend.dumpRawResult();

  return 0;
}
<commit_msg>Added support to decode ProntoHex (#388)<commit_after>// Quick and dirty tool to decode GlobalCache (GC) codes
// and ProntoHex codes
// Copyright 2017 Jorge Cisneros

#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include "IRsend.h"
#include "IRsend_test.h"
#include "IRutils.h"

#define MAX_GC_CODE_LENGTH 10000

void str_to_uint16(char *str, uint16_t *res, uint8_t base) {
  char *end;
  errno = 0;
  intmax_t val = strtoimax(str, &end, base);
  if (errno == ERANGE || val < 0 || val > UINT16_MAX ||
    end == str || *end != '\0')
    return;
  *res = (uint16_t) val;
}

void usage_error(char * name) {
  std::cerr << "Usage: " << name << " [-raw] <global_code>" << std::endl
  << "Usage: " << name << " -prontohex [-raw] <prontohex_code>" << std::endl;
}

int main(int argc, char * argv[]) {
  int argv_offset = 1;
  bool dumpraw = false;
  bool prontohex = false;

  // Check the invocation/calling usage.
  if (argc < 2 || argc > 4) {
    usage_error(argv[0]);
    return 1;
  }
  if (strncmp("-prontohex", argv[argv_offset], 10) == 0) {
    prontohex = true;
    argv_offset++;
  }

  if (strncmp("-raw", argv[argv_offset], 4) == 0) {
    dumpraw = true;
    argv_offset++;
  }
  if (argc - argv_offset != 1) {
    usage_error(argv[0]);
    return 1;
  }

  uint16_t gc_test[MAX_GC_CODE_LENGTH];
  int index = 0;
  char *pch;
  char *saveptr1;
  char *sep = const_cast<char *>(",");
  int codebase = 10;

  if (prontohex) {
      sep = const_cast<char *>(" ");
      codebase = 16;
  }

  pch = strtok_r(argv[argv_offset], sep, &saveptr1);
  while (pch != NULL && index < MAX_GC_CODE_LENGTH) {
    str_to_uint16(pch, &gc_test[index], codebase);
    pch = strtok_r(NULL, sep, &saveptr1);
    index++;
  }

  IRsendTest irsend(4);
  IRrecv irrecv(4);
  irsend.begin();
  irsend.reset();

  if (prontohex) {
      irsend.sendPronto(gc_test, index);
  } else {
      irsend.sendGC(gc_test, index);
  }
  irsend.makeDecodeResult();
  irrecv.decode(&irsend.capture);

  std::cout << "Code length " << index << std::endl
  << "Code type      " << irsend.capture.decode_type
  << " (" << typeToString(irsend.capture.decode_type) << ")" << std::endl
  << "Code bits      " << irsend.capture.bits << std::endl;
  if (hasACState(irsend.capture.decode_type)) {
    std::cout << "State value    0x";
    for (uint16_t i = 0; i < irsend.capture.bits / 8; i++)
      printf("%02X", irsend.capture.state[i]);
    std::cout << std::endl;
  } else {
    std::cout << "Code value     0x" <<
        std::hex << irsend.capture.value << std::endl <<
        "Code address   0x" << std::hex << irsend.capture.address << std::endl
        << "Code command   0x" << std::hex << irsend.capture.command <<
        std::endl;
  }

  if (dumpraw || irsend.capture.decode_type == UNKNOWN)
    irsend.dumpRawResult();

  return 0;
}
<|endoftext|>


<commit_before>#include "formulation/equation/diffusion.h"

namespace bart {

namespace formulation {

namespace equation {

template<int dim>
void Diffusion<dim>::Precalculate(const CellPtr &cell_ptr) {
  SetCell(cell_ptr);

  for (int q = 0; q < cell_quadrature_points_; ++q) {
    Matrix shape_squared(cell_degrees_of_freedom_,
                         cell_degrees_of_freedom_);
    Matrix gradient_squared(cell_degrees_of_freedom_,
                            cell_degrees_of_freedom_);

    for (int i = 0; i < cell_degrees_of_freedom_; ++i) {
      for (int j = 0; j < cell_degrees_of_freedom_; ++j) {
        shape_squared(i,j) = finite_element_->values()->shape_value(i,q) *
            finite_element_->values()->shape_value(j,q);
        gradient_squared(i,j) = finite_element_->values()->shape_grad(i,q) *
            finite_element_->values()->shape_grad(j,q);
      }
    }

    shape_squared_[q] = shape_squared;
    gradient_squared_[q] = gradient_squared;
  }
}

template<int dim>
void Diffusion<dim>::FillCellBilinearTerm(Matrix &to_fill,
                                          const CellPtr &cell_ptr,
                                          const GroupNumber group) const {
  MaterialID material_id = cell_ptr->material_id();

  double sigma_t = cross_sections_->sigma_t.at(material_id)[group];
  double sigma_s = cross_sections_->sigma_s.at(material_id)(group, group);
  double sigma_r = sigma_t - sigma_s;

  double diff_coef = cross_sections_->diffusion_coef.at(material_id)[group];

  for (int q = 0; q < cell_quadrature_points_; ++q) {
    for (int i = 0; i < cell_degrees_of_freedom_; ++i) {
      for (int j = 0; j < cell_degrees_of_freedom_; ++j) {
        to_fill(i,j) += 0;
      }
    }
  }
}

template class Diffusion<1>;
template class Diffusion<2>;
template class Diffusion<3>;

} // namespace equation

} // namespace formulation

} // namespace bart<commit_msg>refactored formulation::equation::Diffusion::FillCellBilinearTerm<commit_after>#include "formulation/equation/diffusion.h"

namespace bart {

namespace formulation {

namespace equation {

template<int dim>
void Diffusion<dim>::Precalculate(const CellPtr &cell_ptr) {
  SetCell(cell_ptr);

  for (int q = 0; q < cell_quadrature_points_; ++q) {
    Matrix shape_squared(cell_degrees_of_freedom_,
                         cell_degrees_of_freedom_);
    Matrix gradient_squared(cell_degrees_of_freedom_,
                            cell_degrees_of_freedom_);

    for (int i = 0; i < cell_degrees_of_freedom_; ++i) {
      for (int j = 0; j < cell_degrees_of_freedom_; ++j) {
        shape_squared(i,j) = finite_element_->values()->shape_value(i,q) *
            finite_element_->values()->shape_value(j,q);
        gradient_squared(i,j) = finite_element_->values()->shape_grad(i,q) *
            finite_element_->values()->shape_grad(j,q);
      }
    }

    shape_squared_[q] = shape_squared;
    gradient_squared_[q] = gradient_squared;
  }
}

template<int dim>
void Diffusion<dim>::FillCellBilinearTerm(Matrix &to_fill,
                                          const CellPtr &cell_ptr,
                                          const GroupNumber group) const {
  SetCell(cell_ptr);
  MaterialID material_id = cell_ptr->material_id();

  double sigma_t = cross_sections_->sigma_t.at(material_id)[group];
  double sigma_s = cross_sections_->sigma_s.at(material_id)(group, group);
  double sigma_r = sigma_t - sigma_s;

  double diff_coef = cross_sections_->diffusion_coef.at(material_id)[group];

  for (int q = 0; q < cell_quadrature_points_; ++q) {
    double gradient = finite_element_->values()->JxW(q);
    to_fill.add(diff_coef*gradient, gradient_squared_[q]);
    to_fill.add(sigma_r*gradient, shape_squared_[q]);
  }
}

template class Diffusion<1>;
template class Diffusion<2>;
template class Diffusion<3>;

} // namespace equation

} // namespace formulation

} // namespace bart<|endoftext|>


<commit_before>
#include "radeon_llvm_emit.h"

#include <llvm/Support/CommandLine.h>
#include <llvm/Support/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <stdio.h>

#include <llvm-c/Core.h>

using namespace llvm;

static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));

int main(int argc, char ** argv)
{
	unsigned char * bytes;
	unsigned byte_count;

	std::auto_ptr<Module> M;
	LLVMContext &Context = getGlobalContext();
	SMDiagnostic Err;
	cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
	M.reset(ParseIRFile(InputFilename, Err, Context));

	Module * mod = M.get();

	radeon_llvm_compile(wrap(mod), &bytes, &byte_count, "redwood", 1);
}
<commit_msg>radeon/llvm/loader: convert hardcoded gpu name to option<commit_after>
#include "radeon_llvm_emit.h"

#include <llvm/Support/CommandLine.h>
#include <llvm/Support/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <stdio.h>

#include <llvm-c/Core.h>

using namespace llvm;

static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));

static cl::opt<std::string>
TargetGPUName("gpu", cl::desc("target gpu name"), cl::value_desc("gpu_name"));

int main(int argc, char ** argv)
{
	unsigned char * bytes;
	unsigned byte_count;

	std::auto_ptr<Module> M;
	LLVMContext &Context = getGlobalContext();
	SMDiagnostic Err;
	cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
	M.reset(ParseIRFile(InputFilename, Err, Context));

	Module * mod = M.get();

	radeon_llvm_compile(wrap(mod), &bytes, &byte_count, TargetGPUName.c_str(), 1);
}
<|endoftext|>


<commit_before>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
 * Copyright (C) 2006 Refractions Research Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: geom/util/GeometryTransformer.java r320 (JTS-1.12)
 *
 **********************************************************************/

#include <geos/geom/util/GeometryTransformer.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/MultiPoint.h>
#include <geos/geom/MultiPolygon.h>
#include <geos/geom/MultiLineString.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/Point.h>
#include <geos/geom/LineString.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/GeometryCollection.h>
#include <geos/util/IllegalArgumentException.h>
#include <geos/util.h>

#include <typeinfo>
#include <cassert>

#ifndef GEOS_DEBUG
#define GEOS_DEBUG 0
#endif

#ifdef GEOS_DEBUG
#include <iostream>
#endif

using namespace std;

namespace geos {
namespace geom { // geos.geom
namespace util { // geos.geom.util

/*public*/
GeometryTransformer::GeometryTransformer()
    :
    factory(nullptr),
    inputGeom(nullptr),
    pruneEmptyGeometry(true),
    preserveGeometryCollectionType(true),
    // preserveCollections(false),
    preserveType(false),
    skipTransformedInvalidInteriorRings(false)
{}

GeometryTransformer::~GeometryTransformer()
{
}

void
GeometryTransformer::setSkipTransformedInvalidInteriorRings(bool b)
{
    skipTransformedInvalidInteriorRings = b;
}

/*public*/
unique_ptr<Geometry>
GeometryTransformer::transform(const Geometry* nInputGeom)
{
    using geos::util::IllegalArgumentException;

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transform(Geometry " << nInputGeom << ");" << std::endl;
#endif

    inputGeom = nInputGeom;
    factory = inputGeom->getFactory();

    if(const Point* p = dynamic_cast<const Point*>(inputGeom)) {
        return transformPoint(p, nullptr);
    }
    if(const MultiPoint* mp = dynamic_cast<const MultiPoint*>(inputGeom)) {
        return transformMultiPoint(mp, nullptr);
    }
    if(const LinearRing* lr = dynamic_cast<const LinearRing*>(inputGeom)) {
        return transformLinearRing(lr, nullptr);
    }
    if(const LineString* ls = dynamic_cast<const LineString*>(inputGeom)) {
        return transformLineString(ls, nullptr);
    }
    if(const MultiLineString* mls = dynamic_cast<const MultiLineString*>(inputGeom)) {
        return transformMultiLineString(mls, nullptr);
    }
    if(const Polygon* p = dynamic_cast<const Polygon*>(inputGeom)) {
        return transformPolygon(p, nullptr);
    }
    if(const MultiPolygon* mp = dynamic_cast<const MultiPolygon*>(inputGeom)) {
        return transformMultiPolygon(mp, nullptr);
    }
    if(const GeometryCollection* gc = dynamic_cast<const GeometryCollection*>(inputGeom)) {
        return transformGeometryCollection(gc, nullptr);
    }

    throw IllegalArgumentException("Unknown Geometry subtype.");
}

std::unique_ptr<CoordinateSequence>
GeometryTransformer::createCoordinateSequence(
    std::unique_ptr< std::vector<Coordinate> > coords)
{
    return std::unique_ptr<CoordinateSequence>(
               factory->getCoordinateSequenceFactory()->create(
                   coords.release())
           );
}

std::unique_ptr<CoordinateSequence>
GeometryTransformer::transformCoordinates(
    const CoordinateSequence* coords,
    const Geometry* parent)
{

    ::geos::ignore_unused_variable_warning(parent);
#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformCoordinates(CoordinateSequence " << coords << ", Geometry " << parent <<
              ");" << std::endl;
#endif

    return std::unique_ptr<CoordinateSequence>(coords->clone());
}

Geometry::Ptr
GeometryTransformer::transformPoint(
    const Point* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformPoint(Point " << geom << ", Geometry " << parent << ");" << std::endl;
#endif

    CoordinateSequence::Ptr cs(transformCoordinates(
                                   geom->getCoordinatesRO(), geom));

    return Geometry::Ptr(factory->createPoint(cs.release()));
}

Geometry::Ptr
GeometryTransformer::transformMultiPoint(
    const MultiPoint* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformMultiPoint(MultiPoint " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    vector<Geometry*>* transGeomList = new vector<Geometry*>();

    for(size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        const Point* p = dynamic_cast<const Point*>(geom->getGeometryN(i));
        assert(p);

        Geometry::Ptr transformGeom = transformPoint(p, geom);
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(transformGeom->isEmpty()) {
            continue;
        }

        // If an exception is thrown we'll leak
        transGeomList->push_back(transformGeom.release());
    }

    return Geometry::Ptr(factory->buildGeometry(transGeomList));

}

Geometry::Ptr
GeometryTransformer::transformLinearRing(
    const LinearRing* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformLinearRing(LinearRing " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    CoordinateSequence::Ptr seq(transformCoordinates(
                                    geom->getCoordinatesRO(), geom));

    auto seqSize = seq->size();

    // ensure a valid LinearRing
    if(seqSize > 0 && seqSize < 4 && ! preserveType) {
        return factory->createLineString(std::move(seq));
    }
    else {
        return factory->createLinearRing(std::move(seq));
    }
}

Geometry::Ptr
GeometryTransformer::transformLineString(
    const LineString* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformLineString(LineString " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    // should check for 1-point sequences and downgrade them to points
    return factory->createLineString(
               transformCoordinates(geom->getCoordinatesRO(), geom));
}

Geometry::Ptr
GeometryTransformer::transformMultiLineString(
    const MultiLineString* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformMultiLineString(MultiLineString " << geom << ", Geometry " << parent << ");"
              << std::endl;
#endif

    vector<Geometry*>* transGeomList = new vector<Geometry*>();

    for(size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        const LineString* l = dynamic_cast<const LineString*>(
                                  geom->getGeometryN(i));
        assert(l);

        Geometry::Ptr transformGeom = transformLineString(l, geom);
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(transformGeom->isEmpty()) {
            continue;
        }

        // If an exception is thrown we'll leak
        transGeomList->push_back(transformGeom.release());
    }

    return Geometry::Ptr(factory->buildGeometry(transGeomList));

}

Geometry::Ptr
GeometryTransformer::transformPolygon(
    const Polygon* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformPolygon(Polygon " << geom << ", Geometry " << parent << ");" << std::endl;
#endif

    bool isAllValidLinearRings = true;

    const LinearRing* lr = dynamic_cast<const LinearRing*>(
                               geom->getExteriorRing());
    assert(lr);

    Geometry::Ptr shell = transformLinearRing(lr, geom);
    if(shell.get() == nullptr
            || ! dynamic_cast<LinearRing*>(shell.get())
            || shell->isEmpty()) {
        isAllValidLinearRings = false;
    }

    vector<LinearRing*>* holes = new vector<LinearRing*>();
    for(size_t i = 0, n = geom->getNumInteriorRing(); i < n; i++) {
        const LinearRing* p_lr = geom->getInteriorRingN(i);
        assert(p_lr);

        Geometry::Ptr hole(transformLinearRing(p_lr, geom));

        if(hole.get() == nullptr || hole->isEmpty()) {
            continue;
        }

        if(! dynamic_cast<LinearRing*>(hole.get())) {
            if(skipTransformedInvalidInteriorRings) {
                continue;
            }
            isAllValidLinearRings = false;
        }

        holes->push_back(dynamic_cast<LinearRing*>(hole.release()));
    }

    if(isAllValidLinearRings) {
        Geometry* sh = shell.release();
        LinearRing* p_lr = dynamic_cast<LinearRing*>(sh);
        assert(p_lr);
        return Geometry::Ptr(factory->createPolygon(p_lr, holes));
    }
    else {
        // would like to use a manager constructor here
        vector<Geometry*>* components = new vector<Geometry*>();
        if(shell.get() != nullptr) {
            components->push_back(shell.release());
        }

        components->insert(components->end(),
                           holes->begin(), holes->end());

        delete holes; // :(

        return Geometry::Ptr(factory->buildGeometry(components));
    }

}

Geometry::Ptr
GeometryTransformer::transformMultiPolygon(
    const MultiPolygon* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformMultiPolygon(MultiPolygon " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    unique_ptr< vector<Geometry*> > transGeomList(new vector<Geometry*>());

    for(std::size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        const Polygon* p = dynamic_cast<const Polygon*>(
                               geom->getGeometryN(i));
        assert(p);

        Geometry::Ptr transformGeom = transformPolygon(p, geom);
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(transformGeom->isEmpty()) {
            continue;
        }

        // If an exception is thrown we'll leak
        transGeomList->push_back(transformGeom.release());
    }

    return Geometry::Ptr(factory->buildGeometry(transGeomList.release()));

}

Geometry::Ptr
GeometryTransformer::transformGeometryCollection(
    const GeometryCollection* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformGeometryCollection(GeometryCollection " << geom << ", Geometry " << parent
              << ");" << std::endl;
#endif

    vector<Geometry*>* transGeomList = new vector<Geometry*>();

    for(std::size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        Geometry::Ptr transformGeom = transform(
                                          geom->getGeometryN(i)); // no parent ?
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(pruneEmptyGeometry && transformGeom->isEmpty()) {
            continue;
        }

        // If an exception is thrown we'll leak
        transGeomList->push_back(transformGeom.release());
    }

    if(preserveGeometryCollectionType) {
        return Geometry::Ptr(factory->createGeometryCollection(
                                 transGeomList));
    }
    else {
        return Geometry::Ptr(factory->buildGeometry(transGeomList));
    }

}

} // namespace geos.geom.util
} // namespace geos.geom
} // namespace geos
<commit_msg>Use simpler GeometryFactory methods in GeometryTransformer<commit_after>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
 * Copyright (C) 2006 Refractions Research Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: geom/util/GeometryTransformer.java r320 (JTS-1.12)
 *
 **********************************************************************/

#include <geos/geom/util/GeometryTransformer.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/MultiPoint.h>
#include <geos/geom/MultiPolygon.h>
#include <geos/geom/MultiLineString.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/Point.h>
#include <geos/geom/LineString.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/GeometryCollection.h>
#include <geos/util/IllegalArgumentException.h>
#include <geos/util.h>

#include <typeinfo>
#include <cassert>

#ifndef GEOS_DEBUG
#define GEOS_DEBUG 0
#endif

#ifdef GEOS_DEBUG
#include <iostream>
#endif

namespace geos {
namespace geom { // geos.geom
namespace util { // geos.geom.util

/*public*/
GeometryTransformer::GeometryTransformer()
    :
    factory(nullptr),
    inputGeom(nullptr),
    pruneEmptyGeometry(true),
    preserveGeometryCollectionType(true),
    // preserveCollections(false),
    preserveType(false),
    skipTransformedInvalidInteriorRings(false)
{}

GeometryTransformer::~GeometryTransformer()
{
}

void
GeometryTransformer::setSkipTransformedInvalidInteriorRings(bool b)
{
    skipTransformedInvalidInteriorRings = b;
}

/*public*/
std::unique_ptr<Geometry>
GeometryTransformer::transform(const Geometry* nInputGeom)
{
    using geos::util::IllegalArgumentException;

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transform(Geometry " << nInputGeom << ");" << std::endl;
#endif

    inputGeom = nInputGeom;
    factory = inputGeom->getFactory();

    if(const Point* p = dynamic_cast<const Point*>(inputGeom)) {
        return transformPoint(p, nullptr);
    }
    if(const MultiPoint* mp = dynamic_cast<const MultiPoint*>(inputGeom)) {
        return transformMultiPoint(mp, nullptr);
    }
    if(const LinearRing* lr = dynamic_cast<const LinearRing*>(inputGeom)) {
        return transformLinearRing(lr, nullptr);
    }
    if(const LineString* ls = dynamic_cast<const LineString*>(inputGeom)) {
        return transformLineString(ls, nullptr);
    }
    if(const MultiLineString* mls = dynamic_cast<const MultiLineString*>(inputGeom)) {
        return transformMultiLineString(mls, nullptr);
    }
    if(const Polygon* p = dynamic_cast<const Polygon*>(inputGeom)) {
        return transformPolygon(p, nullptr);
    }
    if(const MultiPolygon* mp = dynamic_cast<const MultiPolygon*>(inputGeom)) {
        return transformMultiPolygon(mp, nullptr);
    }
    if(const GeometryCollection* gc = dynamic_cast<const GeometryCollection*>(inputGeom)) {
        return transformGeometryCollection(gc, nullptr);
    }

    throw IllegalArgumentException("Unknown Geometry subtype.");
}

std::unique_ptr<CoordinateSequence>
GeometryTransformer::createCoordinateSequence(
    std::unique_ptr< std::vector<Coordinate> > coords)
{
    return std::unique_ptr<CoordinateSequence>(
               factory->getCoordinateSequenceFactory()->create(
                   coords.release())
           );
}

std::unique_ptr<CoordinateSequence>
GeometryTransformer::transformCoordinates(
    const CoordinateSequence* coords,
    const Geometry* parent)
{

    ::geos::ignore_unused_variable_warning(parent);
#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformCoordinates(CoordinateSequence " << coords << ", Geometry " << parent <<
              ");" << std::endl;
#endif

    return std::unique_ptr<CoordinateSequence>(coords->clone());
}

Geometry::Ptr
GeometryTransformer::transformPoint(
    const Point* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformPoint(Point " << geom << ", Geometry " << parent << ");" << std::endl;
#endif

    CoordinateSequence::Ptr cs(transformCoordinates(
                                   geom->getCoordinatesRO(), geom));

    return Geometry::Ptr(factory->createPoint(cs.release()));
}

Geometry::Ptr
GeometryTransformer::transformMultiPoint(
    const MultiPoint* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformMultiPoint(MultiPoint " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    std::vector<std::unique_ptr<Geometry>> transGeomList;

    for(size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        const Point* p = dynamic_cast<const Point*>(geom->getGeometryN(i));
        assert(p);

        Geometry::Ptr transformGeom = transformPoint(p, geom);
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(transformGeom->isEmpty()) {
            continue;
        }

        transGeomList.push_back(std::move(transformGeom));
    }

    return factory->buildGeometry(std::move(transGeomList));

}

Geometry::Ptr
GeometryTransformer::transformLinearRing(
    const LinearRing* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformLinearRing(LinearRing " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    CoordinateSequence::Ptr seq(transformCoordinates(
                                    geom->getCoordinatesRO(), geom));

    auto seqSize = seq->size();

    // ensure a valid LinearRing
    if(seqSize > 0 && seqSize < 4 && ! preserveType) {
        return factory->createLineString(std::move(seq));
    }
    else {
        return factory->createLinearRing(std::move(seq));
    }
}

Geometry::Ptr
GeometryTransformer::transformLineString(
    const LineString* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformLineString(LineString " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    // should check for 1-point sequences and downgrade them to points
    return factory->createLineString(
               transformCoordinates(geom->getCoordinatesRO(), geom));
}

Geometry::Ptr
GeometryTransformer::transformMultiLineString(
    const MultiLineString* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformMultiLineString(MultiLineString " << geom << ", Geometry " << parent << ");"
              << std::endl;
#endif

    std::vector<std::unique_ptr<Geometry>> transGeomList;

    for(size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        const LineString* l = dynamic_cast<const LineString*>(
                                  geom->getGeometryN(i));
        assert(l);

        Geometry::Ptr transformGeom = transformLineString(l, geom);
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(transformGeom->isEmpty()) {
            continue;
        }

        transGeomList.push_back(std::move(transformGeom));
    }

    return factory->buildGeometry(std::move(transGeomList));

}

Geometry::Ptr
GeometryTransformer::transformPolygon(
    const Polygon* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformPolygon(Polygon " << geom << ", Geometry " << parent << ");" << std::endl;
#endif

    bool isAllValidLinearRings = true;

    const LinearRing* lr = dynamic_cast<const LinearRing*>(
                               geom->getExteriorRing());
    assert(lr);

    Geometry::Ptr shell = transformLinearRing(lr, geom);
    if(shell.get() == nullptr
            || ! dynamic_cast<LinearRing*>(shell.get())
            || shell->isEmpty()) {
        isAllValidLinearRings = false;
    }

    std::vector<std::unique_ptr<LinearRing>> holes;
    for(size_t i = 0, n = geom->getNumInteriorRing(); i < n; i++) {
        const LinearRing* p_lr = geom->getInteriorRingN(i);
        assert(p_lr);

        Geometry::Ptr hole(transformLinearRing(p_lr, geom));

        if(hole.get() == nullptr || hole->isEmpty()) {
            continue;
        }

        if(dynamic_cast<LinearRing*>(hole.get())) {
            holes.emplace_back(dynamic_cast<LinearRing*>(hole.release()));
        } else {
            if(skipTransformedInvalidInteriorRings) {
                continue;
            }
            isAllValidLinearRings = false;
        }

    }

    if(isAllValidLinearRings) {
        std::unique_ptr<LinearRing> shell_lr(dynamic_cast<LinearRing*>(shell.release()));
        return factory->createPolygon(std::move(shell_lr), std::move(holes));
    }
    else {
        std::vector<std::unique_ptr<Geometry>> components;
        if(shell.get() != nullptr) {
            components.push_back(std::move(shell));
        }

        for (auto& g : holes) {
            components.push_back(std::move(g));
        }

        return factory->buildGeometry(std::move(components));
    }

}

Geometry::Ptr
GeometryTransformer::transformMultiPolygon(
    const MultiPolygon* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformMultiPolygon(MultiPolygon " << geom << ", Geometry " << parent << ");" <<
              std::endl;
#endif

    std::vector<std::unique_ptr<Geometry>> transGeomList;

    for(std::size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        const Polygon* p = dynamic_cast<const Polygon*>(
                               geom->getGeometryN(i));
        assert(p);

        Geometry::Ptr transformGeom = transformPolygon(p, geom);
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(transformGeom->isEmpty()) {
            continue;
        }

        transGeomList.push_back(std::move(transformGeom));
    }

    return factory->buildGeometry(std::move(transGeomList));

}

Geometry::Ptr
GeometryTransformer::transformGeometryCollection(
    const GeometryCollection* geom,
    const Geometry* parent)
{
    ::geos::ignore_unused_variable_warning(parent);

#if GEOS_DEBUG
    std::cerr << "GeometryTransformer::transformGeometryCollection(GeometryCollection " << geom << ", Geometry " << parent
              << ");" << std::endl;
#endif

    std::vector<std::unique_ptr<Geometry>> transGeomList;

    for(std::size_t i = 0, n = geom->getNumGeometries(); i < n; i++) {
        Geometry::Ptr transformGeom = transform(
                                          geom->getGeometryN(i)); // no parent ?
        if(transformGeom.get() == nullptr) {
            continue;
        }
        if(pruneEmptyGeometry && transformGeom->isEmpty()) {
            continue;
        }

        transGeomList.push_back(std::move(transformGeom));
    }

    if(preserveGeometryCollectionType) {
        return factory->createGeometryCollection(std::move(transGeomList));
    }
    else {
        return factory->buildGeometry(std::move(transGeomList));
    }

}

} // namespace geos.geom.util
} // namespace geos.geom
} // namespace geos
<|endoftext|>