<commit_before>/*******************************************************************************
 * c7a/data/serializer.hpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_DATA_SERIALIZER_HEADER
#define C7A_DATA_SERIALIZER_HEADER

#include <string>
#include <cstring>
#include <utility>
#include <cassert>

//TODO DELETE
#include <iostream>

//TODO(ts) this copies data. That is bad and makes me sad.

namespace c7a {
namespace data {

//! internal representation of data elements
typedef std::string Blob;

//! \namespace namespace to hide the implementations of serializers
namespace serializers {

template <class T>
struct Impl;

//! identity serializer from string to string
template <>
struct Impl<std::string>{
    static std::string Serialize(const std::string& x) {
        return x;
    }

    static std::string Deserialize(const std::string& x) {
        return x;
    }
};

//! serializer for int
template <>
struct Impl<int>{
    static std::string Serialize(const int& x) {
        return std::to_string(x);
    }

    static int Deserialize(const std::string& x) {
        return std::stoi(x);
    }
};

//! serializer for long
template <>
struct Impl<long>{
    static std::string Serialize(const long& x) {
        return std::to_string(x);
    }

    static long Deserialize(const std::string& x) {
        return std::stol(x);
    }
};

//! serializer for long long
template <>
struct Impl<long long>{
    static std::string Serialize(const long long& x) {
        return std::to_string(x);
    }

    static long long Deserialize(const std::string& x) {
        return std::stoll(x);
    }
};

//! serializer for unsigned
template <>
struct Impl<unsigned int>{
    static std::string Serialize(const unsigned int& x) {
        return std::to_string(x);
    }

    static unsigned int Deserialize(const std::string& x) {
        return std::stoul(x);
        //TODO: WHY IS THIS WORKING???? I DONT UNDERSTAND
    }
};

//! serializer for unsigned long
template <>
struct Impl<unsigned long>{
    static std::string Serialize(const unsigned long& x) {
        return std::to_string(x);
    }

    static unsigned long Deserialize(const std::string& x) {
        return std::stoul(x);
    }
};

//! serializer for unsigned long long
template <>
struct Impl<unsigned long long>{
    static std::string Serialize(const unsigned long long& x) {
        return std::to_string(x);
    }

    static unsigned long long Deserialize(const std::string& x) {
        return std::stoull(x);
    }
};

//! serializer for float
template <>
struct Impl<float>{
    static std::string Serialize(const float& x) {
        return std::to_string(x);
    }

    static float Deserialize(const std::string& x) {
        return std::stof(x);
    }
};

//! serializer for double
template <>
struct Impl<double>{
    static std::string Serialize(const double& x) {
        return std::to_string(x);
    }

    static double Deserialize(const std::string& x) {
        return std::stod(x);
    }
};

//! serializer for long double
template <>
struct Impl<long double>{
    static std::string Serialize(const long double& x) {
        return std::to_string(x);
    }

    static long double Deserialize(const std::string& x) {
        return std::stold(x);
    }
};

//! serializer for (string, int) tuples
template <>
struct Impl<std::pair<std::string, int> >{
    static std::string Serialize(const std::pair<std::string, int>& x) {
        std::size_t len = sizeof(int) + x.first.size();
        char result[len];
        std::memcpy(result, &(x.second), sizeof(int));
        std::memcpy(result + sizeof(int), x.first.c_str(), x.first.size());
        return std::string(result, len);
    }
    //TODO(tb): What exactly happens with c_string. What is thiiiiiis?
    static std::pair<std::string, int> Deserialize(const std::string& x) {
        int i;
        std::size_t str_len = x.size() - sizeof(int);
        std::memcpy(&i, x.c_str(), sizeof(int));
        std::string s(x, sizeof(int), str_len);
        return std::pair<std::string, int>(s, i);
    }
};

// TODO(cn): do we have clusternodes working on 32 and 64bit systems at the same time??
//! serializer for pairs
template <typename T1, typename T2>
struct Impl<std::pair<T1, T2>> {
    static std::string Serialize(const std::pair<T1, T2>& x) {
        if( x.first.size() > UINT_MAX ) {
            //TODO ERROR
        }
        unsigned int len_t1 = static_cast<unsigned int>(x.first.size());
        std::string t1 = serializers::Impl<T1>::Serialize(x.first);
        std::string t2 = serializers::Impl<T2>::Serialize(x.second);

        std::size_t len = t1.size() + t2.size() + sizeof(unsigned int);
        char result[len];
        std::memcpy(result, &len_t1, sizeof(unsigned int));
        std::memcpy(result + sizeof(unsigned int), t1.c_str(), t1.size());
        std::memcpy(result + sizeof(unsigned int) + x.first.size(), t2.c_str(), t2.size());
        return std::string(result, len);
    }
    static std::pair<T1, T2> Deserialize(const std::string& x) {
        unsigned int len_t1;
        std::memcpy(&len_t1, x.c_str(), sizeof(unsigned int));
        std::size_t len_t2 = x.size() - sizeof(unsigned int) - len_t1;

        std::string t1_str = x.substr(sizeof(unsigned int), len_t1);
        std::string t2_str = x.substr(sizeof(unsigned int) + len_t1, len_t2);

        T1 t1 = serializers::Impl<T1>::Deserialize(t1_str);
        T1 t2 = serializers::Impl<T2>::Deserialize(t2_str);

        return std::pair<T1, T2>(t1, t2);
    }
};

//! binary serializer for any integral type, usable as template.
template <typename Type>
struct GenericImpl {
    static std::string Serialize(const Type& v) {
        return std::string(reinterpret_cast<const char*>(&v), sizeof(v));
    }

    static Type        Deserialize(const std::string& s) {
        assert(s.size() == sizeof(Type));
        return Type(*reinterpret_cast<const Type*>(s.data()));
    }
};

template <>
struct Impl<std::pair<int, int> >: public GenericImpl<std::pair<int, int> >
{ };

} // namespace serializers

//! Serialize the type to std::string
template <class T>
inline std::string Serialize(const T& x) {
    return serializers::Impl<T>::Serialize(x);
}

//! Deserialize the std::string to the given type
template <class T>
inline T Deserialize(const std::string& x) {
    return serializers::Impl<T>::Deserialize(x);
}

} // namespace data
} // namespace c7a

#endif // !C7A_DATA_SERIALIZER_HEADER

/******************************************************************************/
<commit_msg>remove UINT_MAX to fix error<commit_after>/*******************************************************************************
 * c7a/data/serializer.hpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_DATA_SERIALIZER_HEADER
#define C7A_DATA_SERIALIZER_HEADER

#include <string>
#include <cstring>
#include <utility>
#include <cassert>

//TODO DELETE
#include <iostream>

//TODO(ts) this copies data. That is bad and makes me sad.

namespace c7a {
namespace data {

//! internal representation of data elements
typedef std::string Blob;

//! \namespace namespace to hide the implementations of serializers
namespace serializers {

template <class T>
struct Impl;

//! identity serializer from string to string
template <>
struct Impl<std::string>{
    static std::string Serialize(const std::string& x) {
        return x;
    }

    static std::string Deserialize(const std::string& x) {
        return x;
    }
};

//! serializer for int
template <>
struct Impl<int>{
    static std::string Serialize(const int& x) {
        return std::to_string(x);
    }

    static int Deserialize(const std::string& x) {
        return std::stoi(x);
    }
};

//! serializer for long
template <>
struct Impl<long>{
    static std::string Serialize(const long& x) {
        return std::to_string(x);
    }

    static long Deserialize(const std::string& x) {
        return std::stol(x);
    }
};

//! serializer for long long
template <>
struct Impl<long long>{
    static std::string Serialize(const long long& x) {
        return std::to_string(x);
    }

    static long long Deserialize(const std::string& x) {
        return std::stoll(x);
    }
};

//! serializer for unsigned
template <>
struct Impl<unsigned int>{
    static std::string Serialize(const unsigned int& x) {
        return std::to_string(x);
    }

    static unsigned int Deserialize(const std::string& x) {
        return std::stoul(x);
        //TODO: WHY IS THIS WORKING???? I DONT UNDERSTAND
    }
};

//! serializer for unsigned long
template <>
struct Impl<unsigned long>{
    static std::string Serialize(const unsigned long& x) {
        return std::to_string(x);
    }

    static unsigned long Deserialize(const std::string& x) {
        return std::stoul(x);
    }
};

//! serializer for unsigned long long
template <>
struct Impl<unsigned long long>{
    static std::string Serialize(const unsigned long long& x) {
        return std::to_string(x);
    }

    static unsigned long long Deserialize(const std::string& x) {
        return std::stoull(x);
    }
};

//! serializer for float
template <>
struct Impl<float>{
    static std::string Serialize(const float& x) {
        return std::to_string(x);
    }

    static float Deserialize(const std::string& x) {
        return std::stof(x);
    }
};

//! serializer for double
template <>
struct Impl<double>{
    static std::string Serialize(const double& x) {
        return std::to_string(x);
    }

    static double Deserialize(const std::string& x) {
        return std::stod(x);
    }
};

//! serializer for long double
template <>
struct Impl<long double>{
    static std::string Serialize(const long double& x) {
        return std::to_string(x);
    }

    static long double Deserialize(const std::string& x) {
        return std::stold(x);
    }
};

//! serializer for (string, int) tuples
template <>
struct Impl<std::pair<std::string, int> >{
    static std::string Serialize(const std::pair<std::string, int>& x) {
        std::size_t len = sizeof(int) + x.first.size();
        char result[len];
        std::memcpy(result, &(x.second), sizeof(int));
        std::memcpy(result + sizeof(int), x.first.c_str(), x.first.size());
        return std::string(result, len);
    }
    //TODO(tb): What exactly happens with c_string. What is thiiiiiis?
    static std::pair<std::string, int> Deserialize(const std::string& x) {
        int i;
        std::size_t str_len = x.size() - sizeof(int);
        std::memcpy(&i, x.c_str(), sizeof(int));
        std::string s(x, sizeof(int), str_len);
        return std::pair<std::string, int>(s, i);
    }
};

// TODO(cn): do we have clusternodes working on 32 and 64bit systems at the same time??
//! serializer for pairs
template <typename T1, typename T2>
struct Impl<std::pair<T1, T2>> {
    static std::string Serialize(const std::pair<T1, T2>& x) {
        // UINT_MAX not working on Jenkins o.o
        // if( x.first.size() > UINT_MAX ) {
        //     //TODO ERROR
        // }
        unsigned int len_t1 = static_cast<unsigned int>(x.first.size());
        std::string t1 = serializers::Impl<T1>::Serialize(x.first);
        std::string t2 = serializers::Impl<T2>::Serialize(x.second);

        std::size_t len = t1.size() + t2.size() + sizeof(unsigned int);
        char result[len];
        std::memcpy(result, &len_t1, sizeof(unsigned int));
        std::memcpy(result + sizeof(unsigned int), t1.c_str(), t1.size());
        std::memcpy(result + sizeof(unsigned int) + x.first.size(), t2.c_str(), t2.size());
        return std::string(result, len);
    }
    static std::pair<T1, T2> Deserialize(const std::string& x) {
        unsigned int len_t1;
        std::memcpy(&len_t1, x.c_str(), sizeof(unsigned int));
        std::size_t len_t2 = x.size() - sizeof(unsigned int) - len_t1;

        std::string t1_str = x.substr(sizeof(unsigned int), len_t1);
        std::string t2_str = x.substr(sizeof(unsigned int) + len_t1, len_t2);

        T1 t1 = serializers::Impl<T1>::Deserialize(t1_str);
        T1 t2 = serializers::Impl<T2>::Deserialize(t2_str);

        return std::pair<T1, T2>(t1, t2);
    }
};

//! binary serializer for any integral type, usable as template.
template <typename Type>
struct GenericImpl {
    static std::string Serialize(const Type& v) {
        return std::string(reinterpret_cast<const char*>(&v), sizeof(v));
    }

    static Type        Deserialize(const std::string& s) {
        assert(s.size() == sizeof(Type));
        return Type(*reinterpret_cast<const Type*>(s.data()));
    }
};

template <>
struct Impl<std::pair<int, int> >: public GenericImpl<std::pair<int, int> >
{ };

} // namespace serializers

//! Serialize the type to std::string
template <class T>
inline std::string Serialize(const T& x) {
    return serializers::Impl<T>::Serialize(x);
}

//! Deserialize the std::string to the given type
template <class T>
inline T Deserialize(const std::string& x) {
    return serializers::Impl<T>::Deserialize(x);
}

} // namespace data
} // namespace c7a

#endif // !C7A_DATA_SERIALIZER_HEADER

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


<commit_before>/*************************************************************************/
/*  collision_object_2d_sw.cpp                                           */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "collision_object_2d_sw.h"
#include "space_2d_sw.h"

void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform) {

	Shape s;
	s.shape = p_shape;
	s.xform = p_transform;
	s.xform_inv = s.xform.affine_inverse();
	s.bpid = 0; //needs update
	s.disabled = false;
	s.one_way_collision = false;
	shapes.push_back(s);
	p_shape->add_owner(this);
	_update_shapes();
	_shapes_changed();
}

void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {

	ERR_FAIL_INDEX(p_index, shapes.size());
	shapes[p_index].shape->remove_owner(this);
	shapes[p_index].shape = p_shape;

	p_shape->add_owner(this);
	_update_shapes();
	_shapes_changed();
}

void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) {

	ERR_FAIL_INDEX(p_index, shapes.size());
	shapes[p_index].metadata = p_metadata;
}

void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) {

	ERR_FAIL_INDEX(p_index, shapes.size());

	shapes[p_index].xform = p_transform;
	shapes[p_index].xform_inv = p_transform.affine_inverse();
	_update_shapes();
	_shapes_changed();
}

void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) {

	//remove a shape, all the times it appears
	for (int i = 0; i < shapes.size(); i++) {

		if (shapes[i].shape == p_shape) {
			remove_shape(i);
			i--;
		}
	}
}

void CollisionObject2DSW::remove_shape(int p_index) {

	//remove anything from shape to be erased to end, so subindices don't change
	ERR_FAIL_INDEX(p_index, shapes.size());
	for (int i = p_index; i < shapes.size(); i++) {

		if (shapes[i].bpid == 0)
			continue;
		//should never get here with a null owner
		space->get_broadphase()->remove(shapes[i].bpid);
		shapes[i].bpid = 0;
	}
	shapes[p_index].shape->remove_owner(this);
	shapes.remove(p_index);

	_shapes_changed();
}

void CollisionObject2DSW::_set_static(bool p_static) {
	if (_static == p_static)
		return;
	_static = p_static;

	if (!space)
		return;
	for (int i = 0; i < get_shape_count(); i++) {
		Shape &s = shapes[i];
		if (s.bpid > 0) {
			space->get_broadphase()->set_static(s.bpid, _static);
		}
	}
}

void CollisionObject2DSW::_unregister_shapes() {

	for (int i = 0; i < shapes.size(); i++) {

		Shape &s = shapes[i];
		if (s.bpid > 0) {
			space->get_broadphase()->remove(s.bpid);
			s.bpid = 0;
		}
	}
}

void CollisionObject2DSW::_update_shapes() {

	if (!space)
		return;

	for (int i = 0; i < shapes.size(); i++) {

		Shape &s = shapes[i];
		if (s.bpid == 0) {
			s.bpid = space->get_broadphase()->create(this, i);
			space->get_broadphase()->set_static(s.bpid, _static);
		}

		//not quite correct, should compute the next matrix..
		Rect2 shape_aabb = s.shape->get_aabb();
		Transform2D xform = transform * s.xform;
		shape_aabb = xform.xform(shape_aabb);
		s.aabb_cache = shape_aabb;
		s.aabb_cache = s.aabb_cache.grow((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05);

		space->get_broadphase()->move(s.bpid, s.aabb_cache);
	}
}

void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) {

	if (!space)
		return;

	for (int i = 0; i < shapes.size(); i++) {

		Shape &s = shapes[i];
		if (s.bpid == 0) {
			s.bpid = space->get_broadphase()->create(this, i);
			space->get_broadphase()->set_static(s.bpid, _static);
		}

		//not quite correct, should compute the next matrix..
		Rect2 shape_aabb = s.shape->get_aabb();
		Transform2D xform = transform * s.xform;
		shape_aabb = xform.xform(shape_aabb);
		shape_aabb = shape_aabb.merge(Rect2(shape_aabb.position + p_motion, shape_aabb.size)); //use motion
		s.aabb_cache = shape_aabb;

		space->get_broadphase()->move(s.bpid, shape_aabb);
	}
}

void CollisionObject2DSW::_set_space(Space2DSW *p_space) {

	if (space) {

		space->remove_object(this);

		for (int i = 0; i < shapes.size(); i++) {

			Shape &s = shapes[i];
			if (s.bpid) {
				space->get_broadphase()->remove(s.bpid);
				s.bpid = 0;
			}
		}
	}

	space = p_space;

	if (space) {

		space->add_object(this);
		_update_shapes();
	}
}

void CollisionObject2DSW::_shape_changed() {

	_update_shapes();
	_shapes_changed();
}

CollisionObject2DSW::CollisionObject2DSW(Type p_type) {

	_static = true;
	type = p_type;
	space = NULL;
	instance_id = 0;
	collision_mask = 1;
	collision_layer = 1;
	pickable = true;
}
<commit_msg>Fix 2d collision body update on shape remove<commit_after>/*************************************************************************/
/*  collision_object_2d_sw.cpp                                           */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "collision_object_2d_sw.h"
#include "space_2d_sw.h"

void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform) {

	Shape s;
	s.shape = p_shape;
	s.xform = p_transform;
	s.xform_inv = s.xform.affine_inverse();
	s.bpid = 0; //needs update
	s.disabled = false;
	s.one_way_collision = false;
	shapes.push_back(s);
	p_shape->add_owner(this);
	_update_shapes();
	_shapes_changed();
}

void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {

	ERR_FAIL_INDEX(p_index, shapes.size());
	shapes[p_index].shape->remove_owner(this);
	shapes[p_index].shape = p_shape;

	p_shape->add_owner(this);
	_update_shapes();
	_shapes_changed();
}

void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) {

	ERR_FAIL_INDEX(p_index, shapes.size());
	shapes[p_index].metadata = p_metadata;
}

void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) {

	ERR_FAIL_INDEX(p_index, shapes.size());

	shapes[p_index].xform = p_transform;
	shapes[p_index].xform_inv = p_transform.affine_inverse();
	_update_shapes();
	_shapes_changed();
}

void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) {

	//remove a shape, all the times it appears
	for (int i = 0; i < shapes.size(); i++) {

		if (shapes[i].shape == p_shape) {
			remove_shape(i);
			i--;
		}
	}
}

void CollisionObject2DSW::remove_shape(int p_index) {

	//remove anything from shape to be erased to end, so subindices don't change
	ERR_FAIL_INDEX(p_index, shapes.size());
	for (int i = p_index; i < shapes.size(); i++) {

		if (shapes[i].bpid == 0)
			continue;
		//should never get here with a null owner
		space->get_broadphase()->remove(shapes[i].bpid);
		shapes[i].bpid = 0;
	}
	shapes[p_index].shape->remove_owner(this);
	shapes.remove(p_index);

	_update_shapes();
	_shapes_changed();
}

void CollisionObject2DSW::_set_static(bool p_static) {
	if (_static == p_static)
		return;
	_static = p_static;

	if (!space)
		return;
	for (int i = 0; i < get_shape_count(); i++) {
		Shape &s = shapes[i];
		if (s.bpid > 0) {
			space->get_broadphase()->set_static(s.bpid, _static);
		}
	}
}

void CollisionObject2DSW::_unregister_shapes() {

	for (int i = 0; i < shapes.size(); i++) {

		Shape &s = shapes[i];
		if (s.bpid > 0) {
			space->get_broadphase()->remove(s.bpid);
			s.bpid = 0;
		}
	}
}

void CollisionObject2DSW::_update_shapes() {

	if (!space)
		return;

	for (int i = 0; i < shapes.size(); i++) {

		Shape &s = shapes[i];
		if (s.bpid == 0) {
			s.bpid = space->get_broadphase()->create(this, i);
			space->get_broadphase()->set_static(s.bpid, _static);
		}

		//not quite correct, should compute the next matrix..
		Rect2 shape_aabb = s.shape->get_aabb();
		Transform2D xform = transform * s.xform;
		shape_aabb = xform.xform(shape_aabb);
		s.aabb_cache = shape_aabb;
		s.aabb_cache = s.aabb_cache.grow((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05);

		space->get_broadphase()->move(s.bpid, s.aabb_cache);
	}
}

void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) {

	if (!space)
		return;

	for (int i = 0; i < shapes.size(); i++) {

		Shape &s = shapes[i];
		if (s.bpid == 0) {
			s.bpid = space->get_broadphase()->create(this, i);
			space->get_broadphase()->set_static(s.bpid, _static);
		}

		//not quite correct, should compute the next matrix..
		Rect2 shape_aabb = s.shape->get_aabb();
		Transform2D xform = transform * s.xform;
		shape_aabb = xform.xform(shape_aabb);
		shape_aabb = shape_aabb.merge(Rect2(shape_aabb.position + p_motion, shape_aabb.size)); //use motion
		s.aabb_cache = shape_aabb;

		space->get_broadphase()->move(s.bpid, shape_aabb);
	}
}

void CollisionObject2DSW::_set_space(Space2DSW *p_space) {

	if (space) {

		space->remove_object(this);

		for (int i = 0; i < shapes.size(); i++) {

			Shape &s = shapes[i];
			if (s.bpid) {
				space->get_broadphase()->remove(s.bpid);
				s.bpid = 0;
			}
		}
	}

	space = p_space;

	if (space) {

		space->add_object(this);
		_update_shapes();
	}
}

void CollisionObject2DSW::_shape_changed() {

	_update_shapes();
	_shapes_changed();
}

CollisionObject2DSW::CollisionObject2DSW(Type p_type) {

	_static = true;
	type = p_type;
	space = NULL;
	instance_id = 0;
	collision_mask = 1;
	collision_layer = 1;
	pickable = true;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include "ConversionHelper.hxx"
#include "GraphicHelpers.hxx"

#include <ooxml/resourceids.hxx>

#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <com/sun/star/text/WrapTextMode.hpp>

#include "dmapperLoggers.hxx"

#include <iostream>
using namespace std;

namespace writerfilter {
namespace dmapper {

using namespace com::sun::star;

int PositionHandler::savedPositionOffsetV = 0;
int PositionHandler::savedPositionOffsetH = 0;
int PositionHandler::savedAlignV = text::VertOrientation::NONE;
int PositionHandler::savedAlignH = text::HoriOrientation::NONE;

PositionHandler::PositionHandler( bool vertical ) :
LoggedProperties(dmapper_logger, "PositionHandler")
{
    m_nRelation = text::RelOrientation::FRAME;
    if( vertical )
    {
        m_nPosition = savedPositionOffsetV;
        m_nOrient = savedAlignV;
        savedPositionOffsetV = 0;
        savedAlignV = text::VertOrientation::NONE;
    }
    else
    {
        m_nPosition = savedPositionOffsetH;
        m_nOrient = savedAlignH;
        savedPositionOffsetH = 0;
        savedAlignH = text::HoriOrientation::NONE;
    }
}

PositionHandler::~PositionHandler( )
{
}

void PositionHandler::lcl_attribute( Id aName, Value& rVal )
{
    sal_Int32 nIntValue = rVal.getInt( );
    switch ( aName )
    {
        case NS_ooxml::LN_CT_PosV_relativeFrom:
            {
                // TODO There are some other unhandled values
                static Id pVertRelValues[] =
                {
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_margin,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_paragraph,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_line
                };

                static sal_Int16 pVertRelations[] =
                {
                    text::RelOrientation::PAGE_PRINT_AREA,
                    text::RelOrientation::PAGE_FRAME,
                    text::RelOrientation::FRAME,
                    text::RelOrientation::TEXT_LINE
                };

                for ( int i = 0; i < 4; i++ )
                {
                    if ( pVertRelValues[i] == sal_uInt32( nIntValue ) )
                        m_nRelation = pVertRelations[i];
                }
            }
            break;
        case NS_ooxml::LN_CT_PosH_relativeFrom:
            {
                // TODO There are some other unhandled values
                static Id pHoriRelValues[] =
                {
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_margin,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_column,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_character
                };

                static sal_Int16 pHoriRelations[] =
                {
                    text::RelOrientation::PAGE_PRINT_AREA,
                    text::RelOrientation::PAGE_FRAME,
                    text::RelOrientation::FRAME,
                    text::RelOrientation::CHAR,
                };

                for ( int i = 0; i < 4; i++ )
                {
                    if ( pHoriRelValues[i] == sal_uInt32( nIntValue ) )
                        m_nRelation = pHoriRelations[i];
                }
            }
            break;
        default:
#ifdef DEBUG_DOMAINMAPPER
            dmapper_logger->element("unhandled");
#endif
            break;
    }
}

void PositionHandler::lcl_sprm( Sprm& )
{
}

void PositionHandler::setPositionOffset(const ::rtl::OUString & sText, bool vertical)
{
    if( vertical )
        savedPositionOffsetV = ConversionHelper::convertEMUToMM100( sText.toInt32());
    else
        savedPositionOffsetH = ConversionHelper::convertEMUToMM100( sText.toInt32());
}

void PositionHandler::setAlignH(const ::rtl::OUString & sText)
{
    if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "left" )))
        savedAlignH = text::HoriOrientation::LEFT;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "right" )))
        savedAlignH = text::HoriOrientation::RIGHT;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "center" )))
        savedAlignH = text::HoriOrientation::CENTER;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "inside" )))
        savedAlignH = text::HoriOrientation::INSIDE;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "outside" )))
        savedAlignH = text::HoriOrientation::OUTSIDE;
}

void PositionHandler::setAlignV(const ::rtl::OUString & sText)
{
    if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "top" )))
        savedAlignV = text::VertOrientation::TOP;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "bottom" )))
        savedAlignV = text::VertOrientation::BOTTOM;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "center" )))
        savedAlignV = text::VertOrientation::CENTER;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "inside" )))
        savedAlignV = text::VertOrientation::NONE;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "outside" )))
        savedAlignV = text::VertOrientation::NONE;
}

WrapHandler::WrapHandler( ) :
LoggedProperties(dmapper_logger, "WrapHandler"),
    m_nType( 0 ),
    m_nSide( 0 )
{
}

WrapHandler::~WrapHandler( )
{
}

void WrapHandler::lcl_attribute( Id aName, Value& rVal )
{
    switch ( aName )
    {
        case NS_ooxml::LN_CT_Wrap_type:
            m_nType = sal_Int32( rVal.getInt( ) );
            break;
        case NS_ooxml::LN_CT_Wrap_side:
            m_nSide = sal_Int32( rVal.getInt( ) );
            break;
        default:;
    }
}

void WrapHandler::lcl_sprm( Sprm& )
{
}

sal_Int32 WrapHandler::getWrapMode( )
{
    sal_Int32 nMode = com::sun::star::text::WrapTextMode_NONE;

    switch ( m_nType )
    {
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_square:
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_tight:
            {
                switch ( m_nSide )
                {
                    case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_left:
                        nMode = com::sun::star::text::WrapTextMode_LEFT;
                        break;
                    case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_right:
                        nMode = com::sun::star::text::WrapTextMode_RIGHT;
                        break;
                    default:
                        nMode = com::sun::star::text::WrapTextMode_PARALLEL;
                }
            }
            break;
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_through:
            nMode = com::sun::star::text::WrapTextMode_THROUGHT;
            break;
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_topAndBottom:
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_none:
        default:
            nMode = com::sun::star::text::WrapTextMode_NONE;
    }

    return nMode;
}

void GraphicZOrderHelper::addItem( uno::Reference< beans::XPropertySet > props, sal_Int32 relativeHeight )
{
    items[ relativeHeight ] = props;
}

// The relativeHeight value in .docx is an arbitrary number, where only the relative ordering matters.
// But in Writer, the z-order is index in 0..(numitems-1) range, so whenever a new item needs to be
// added in the proper z-order, it is necessary to find the proper index.
sal_Int32 GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight )
{
    Items::const_iterator it = items.begin();
    while( it != items.end())
    {
        // std::map is iterated sorted by key
        if( it->first > relativeHeight )
            break; // this is the first one higher, we belong right before it
        else
            ++it;
    }
    if( it == items.end()) // we're topmost
    {
        if( items.empty())
            return 0;
        sal_Int32 itemZOrder;
        --it;
        if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
            .GetName( PROP_Z_ORDER )) >>= itemZOrder )
            return itemZOrder + 1; // after the topmost
    }
    else
    {
        sal_Int32 itemZOrder;
        if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
            .GetName( PROP_Z_ORDER )) >>= itemZOrder )
            return itemZOrder; // before the item
    }
    SAL_WARN( "writerfilter", "findZOrder() didn't find item z-order" );
    return 0; // this should not(?) happen
}

} }

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>WaE: MacOSX itemZOrder may be unused uninitialized<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include "ConversionHelper.hxx"
#include "GraphicHelpers.hxx"

#include <ooxml/resourceids.hxx>

#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <com/sun/star/text/WrapTextMode.hpp>

#include "dmapperLoggers.hxx"

#include <iostream>
using namespace std;

namespace writerfilter {
namespace dmapper {

using namespace com::sun::star;

int PositionHandler::savedPositionOffsetV = 0;
int PositionHandler::savedPositionOffsetH = 0;
int PositionHandler::savedAlignV = text::VertOrientation::NONE;
int PositionHandler::savedAlignH = text::HoriOrientation::NONE;

PositionHandler::PositionHandler( bool vertical ) :
LoggedProperties(dmapper_logger, "PositionHandler")
{
    m_nRelation = text::RelOrientation::FRAME;
    if( vertical )
    {
        m_nPosition = savedPositionOffsetV;
        m_nOrient = savedAlignV;
        savedPositionOffsetV = 0;
        savedAlignV = text::VertOrientation::NONE;
    }
    else
    {
        m_nPosition = savedPositionOffsetH;
        m_nOrient = savedAlignH;
        savedPositionOffsetH = 0;
        savedAlignH = text::HoriOrientation::NONE;
    }
}

PositionHandler::~PositionHandler( )
{
}

void PositionHandler::lcl_attribute( Id aName, Value& rVal )
{
    sal_Int32 nIntValue = rVal.getInt( );
    switch ( aName )
    {
        case NS_ooxml::LN_CT_PosV_relativeFrom:
            {
                // TODO There are some other unhandled values
                static Id pVertRelValues[] =
                {
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_margin,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_paragraph,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_line
                };

                static sal_Int16 pVertRelations[] =
                {
                    text::RelOrientation::PAGE_PRINT_AREA,
                    text::RelOrientation::PAGE_FRAME,
                    text::RelOrientation::FRAME,
                    text::RelOrientation::TEXT_LINE
                };

                for ( int i = 0; i < 4; i++ )
                {
                    if ( pVertRelValues[i] == sal_uInt32( nIntValue ) )
                        m_nRelation = pVertRelations[i];
                }
            }
            break;
        case NS_ooxml::LN_CT_PosH_relativeFrom:
            {
                // TODO There are some other unhandled values
                static Id pHoriRelValues[] =
                {
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_margin,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_column,
                    NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_character
                };

                static sal_Int16 pHoriRelations[] =
                {
                    text::RelOrientation::PAGE_PRINT_AREA,
                    text::RelOrientation::PAGE_FRAME,
                    text::RelOrientation::FRAME,
                    text::RelOrientation::CHAR,
                };

                for ( int i = 0; i < 4; i++ )
                {
                    if ( pHoriRelValues[i] == sal_uInt32( nIntValue ) )
                        m_nRelation = pHoriRelations[i];
                }
            }
            break;
        default:
#ifdef DEBUG_DOMAINMAPPER
            dmapper_logger->element("unhandled");
#endif
            break;
    }
}

void PositionHandler::lcl_sprm( Sprm& )
{
}

void PositionHandler::setPositionOffset(const ::rtl::OUString & sText, bool vertical)
{
    if( vertical )
        savedPositionOffsetV = ConversionHelper::convertEMUToMM100( sText.toInt32());
    else
        savedPositionOffsetH = ConversionHelper::convertEMUToMM100( sText.toInt32());
}

void PositionHandler::setAlignH(const ::rtl::OUString & sText)
{
    if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "left" )))
        savedAlignH = text::HoriOrientation::LEFT;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "right" )))
        savedAlignH = text::HoriOrientation::RIGHT;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "center" )))
        savedAlignH = text::HoriOrientation::CENTER;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "inside" )))
        savedAlignH = text::HoriOrientation::INSIDE;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "outside" )))
        savedAlignH = text::HoriOrientation::OUTSIDE;
}

void PositionHandler::setAlignV(const ::rtl::OUString & sText)
{
    if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "top" )))
        savedAlignV = text::VertOrientation::TOP;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "bottom" )))
        savedAlignV = text::VertOrientation::BOTTOM;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "center" )))
        savedAlignV = text::VertOrientation::CENTER;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "inside" )))
        savedAlignV = text::VertOrientation::NONE;
    else if( sText == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "outside" )))
        savedAlignV = text::VertOrientation::NONE;
}

WrapHandler::WrapHandler( ) :
LoggedProperties(dmapper_logger, "WrapHandler"),
    m_nType( 0 ),
    m_nSide( 0 )
{
}

WrapHandler::~WrapHandler( )
{
}

void WrapHandler::lcl_attribute( Id aName, Value& rVal )
{
    switch ( aName )
    {
        case NS_ooxml::LN_CT_Wrap_type:
            m_nType = sal_Int32( rVal.getInt( ) );
            break;
        case NS_ooxml::LN_CT_Wrap_side:
            m_nSide = sal_Int32( rVal.getInt( ) );
            break;
        default:;
    }
}

void WrapHandler::lcl_sprm( Sprm& )
{
}

sal_Int32 WrapHandler::getWrapMode( )
{
    sal_Int32 nMode = com::sun::star::text::WrapTextMode_NONE;

    switch ( m_nType )
    {
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_square:
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_tight:
            {
                switch ( m_nSide )
                {
                    case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_left:
                        nMode = com::sun::star::text::WrapTextMode_LEFT;
                        break;
                    case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_right:
                        nMode = com::sun::star::text::WrapTextMode_RIGHT;
                        break;
                    default:
                        nMode = com::sun::star::text::WrapTextMode_PARALLEL;
                }
            }
            break;
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_through:
            nMode = com::sun::star::text::WrapTextMode_THROUGHT;
            break;
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_topAndBottom:
        case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_none:
        default:
            nMode = com::sun::star::text::WrapTextMode_NONE;
    }

    return nMode;
}

void GraphicZOrderHelper::addItem( uno::Reference< beans::XPropertySet > props, sal_Int32 relativeHeight )
{
    items[ relativeHeight ] = props;
}

// The relativeHeight value in .docx is an arbitrary number, where only the relative ordering matters.
// But in Writer, the z-order is index in 0..(numitems-1) range, so whenever a new item needs to be
// added in the proper z-order, it is necessary to find the proper index.
sal_Int32 GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight )
{
    Items::const_iterator it = items.begin();
    while( it != items.end())
    {
        // std::map is iterated sorted by key
        if( it->first > relativeHeight )
            break; // this is the first one higher, we belong right before it
        else
            ++it;
    }
    if( it == items.end()) // we're topmost
    {
        if( items.empty())
            return 0;
        sal_Int32 itemZOrder(0);
        --it;
        if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
            .GetName( PROP_Z_ORDER )) >>= itemZOrder )
            return itemZOrder + 1; // after the topmost
    }
    else
    {
        sal_Int32 itemZOrder(0);
        if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier()
            .GetName( PROP_Z_ORDER )) >>= itemZOrder )
            return itemZOrder; // before the item
    }
    SAL_WARN( "writerfilter", "findZOrder() didn't find item z-order" );
    return 0; // this should not(?) happen
}

} }

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#ifndef AMGCL_LEVEL_PARAMS_HPP
#define AMGCL_LEVEL_PARAMS_HPP

/*
The MIT License

Copyright (c) 2012 Denis Demidov <ddemidov@ksu.ru>

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

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

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

/**
 * \file   level_params.hpp
 * \author Denis Demidov <ddemidov@ksu.ru>
 * \brief  Common parameters for level construction/solution.
 */

namespace amgcl {

namespace level {

/// Common parameters for level construction/solution.
struct params {
    /// Number of pre-relaxations.
    unsigned npre;

    /// Number of post-relaxations.
    unsigned npost;

    /// Number of cycles (1 for V-cycle, 2 for W-cycle, etc.).
    unsigned ncycle;

    /// How often to invoke k-cycle instead of just v-cycle.
    /**
     * See \ref Notay_2008 "Notay (2008)". K-cycle employs a Krylov method
     * (here CG) on each level of the grid hierarchy and uses this grid
     * hierarchy for the preconditioning of this Krylov method. The approach is
     * further extended by allowing such inner iterations only at levels of
     * given multiplicity, whereas normal V-cycle formulation is used at all
     * other levels.
     */
    // TODO: Try flexible (generalized) CG method here.
    unsigned kcycle;

    /// Under-relaxation factor.
    float relax_factor;

    /// Maximum number of iterations in standalone solver.
    unsigned maxiter;

    /// The required precision for standalone solver.
    double   tol;

    params()
        : npre(1), npost(1), ncycle(1), kcycle(0), relax_factor(0.72f),
          maxiter(100), tol(1e-8)
    { }
};

} // namespace level
} // namespace amgcl

#endif
<commit_msg>Removed damping factor from general level params<commit_after>#ifndef AMGCL_LEVEL_PARAMS_HPP
#define AMGCL_LEVEL_PARAMS_HPP

/*
The MIT License

Copyright (c) 2012 Denis Demidov <ddemidov@ksu.ru>

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

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

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

/**
 * \file   level_params.hpp
 * \author Denis Demidov <ddemidov@ksu.ru>
 * \brief  Common parameters for level construction/solution.
 */

namespace amgcl {

namespace level {

/// Common parameters for level construction/solution.
struct params {
    /// Number of pre-relaxations.
    unsigned npre;

    /// Number of post-relaxations.
    unsigned npost;

    /// Number of cycles (1 for V-cycle, 2 for W-cycle, etc.).
    unsigned ncycle;

    /// How often to invoke k-cycle instead of just v-cycle.
    /**
     * See \ref Notay_2008 "Notay (2008)". K-cycle employs a Krylov method
     * (here CG) on each level of the grid hierarchy and uses this grid
     * hierarchy for the preconditioning of this Krylov method. The approach is
     * further extended by allowing such inner iterations only at levels of
     * given multiplicity, whereas normal V-cycle formulation is used at all
     * other levels.
     */
    // TODO: Try flexible (generalized) CG method here.
    unsigned kcycle;

    /// Maximum number of iterations in standalone solver.
    unsigned maxiter;

    /// The required precision for standalone solver.
    double   tol;

    params()
        : npre(1), npost(1), ncycle(1), kcycle(0), maxiter(100), tol(1e-8)
    { }
};

} // namespace level
} // namespace amgcl

#endif
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <sal/types.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "rtl/ustring.hxx"
#include <iostream>

namespace test { namespace strings {

class valueX : public CppUnit::TestFixture {
public:
    void testOBoolean();
    void testOUBoolean();
    void testOUInt();
    void testOInt();
    void testOUFloat();
    void testOFloat();

    CPPUNIT_TEST_SUITE(valueX);
    CPPUNIT_TEST(testOBoolean);
    CPPUNIT_TEST(testOUBoolean);
    CPPUNIT_TEST(testOUInt);
    CPPUNIT_TEST(testOInt);
    CPPUNIT_TEST(testOUFloat);
    CPPUNIT_TEST(testOFloat);
    CPPUNIT_TEST_SUITE_END();
};

} }

CPPUNIT_TEST_SUITE_REGISTRATION(test::strings::valueX);

namespace {

template< typename T >
void testBoolean() {
    CPPUNIT_ASSERT_EQUAL( T( "false" ), T::boolean( false ) );
    CPPUNIT_ASSERT_EQUAL( T( "false" ), T::boolean( sal_False ) );
    CPPUNIT_ASSERT_EQUAL( T( "true" ), T::boolean( true ) );
    CPPUNIT_ASSERT_EQUAL( T( "true" ), T::boolean( sal_True ) );
}

}

void test::strings::valueX::testOBoolean() {
    testBoolean<rtl::OString>();
}

void test::strings::valueX::testOUBoolean() {
    testBoolean<rtl::OString>();
}

template< typename T >
void testInt() {
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( 30039062 ));

    // test the overloading resolution

    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< signed char >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< unsigned char >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< short >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< unsigned short >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< int >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< unsigned int >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< long >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< unsigned long >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< long long >( 30039062 )));
    // The highest bit set in unsigned long long may not actually work.
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< unsigned long long >( 30039062 )));

    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< sal_Int8 >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< sal_uInt8 >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< sal_Int16 >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< sal_uInt16 >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_Int32 >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_uInt32 >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_Int64 >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_uInt64 >( 30039062 )));

    // The implementation internally uses sal_Int64 etc. types, so check ranges.
    assert( sizeof( int ) <= sizeof( sal_Int32 ));
    assert( sizeof( long ) <= sizeof( sal_Int64 ));
    assert( sizeof( long long ) <= sizeof( sal_Int64 ));
    assert( sizeof( unsigned int ) < sizeof( sal_Int64 ));
}

void test::strings::valueX::testOUInt() {
    testInt<rtl::OUString>();
}

void test::strings::valueX::testOInt() {
    testInt<rtl::OString>();
}

template< typename T >
void testFloat() {
    CPPUNIT_ASSERT_EQUAL( T( "39062.2" ), T::number( 39062.2f ));
    CPPUNIT_ASSERT_EQUAL( T( "30039062.2" ), T::number( 30039062.2 ));
    // long double not supported
}

void test::strings::valueX::testOUFloat() {
    testFloat<rtl::OUString>();
}

void test::strings::valueX::testOFloat() {
    testFloat<rtl::OString>();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>testOUBoolean should test with OUString, not OString<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <sal/types.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "rtl/ustring.hxx"
#include <iostream>

namespace test { namespace strings {

class valueX : public CppUnit::TestFixture {
public:
    void testOBoolean();
    void testOUBoolean();
    void testOUInt();
    void testOInt();
    void testOUFloat();
    void testOFloat();

    CPPUNIT_TEST_SUITE(valueX);
    CPPUNIT_TEST(testOBoolean);
    CPPUNIT_TEST(testOUBoolean);
    CPPUNIT_TEST(testOUInt);
    CPPUNIT_TEST(testOInt);
    CPPUNIT_TEST(testOUFloat);
    CPPUNIT_TEST(testOFloat);
    CPPUNIT_TEST_SUITE_END();
};

} }

CPPUNIT_TEST_SUITE_REGISTRATION(test::strings::valueX);

namespace {

template< typename T >
void testBoolean() {
    CPPUNIT_ASSERT_EQUAL( T( "false" ), T::boolean( false ) );
    CPPUNIT_ASSERT_EQUAL( T( "false" ), T::boolean( sal_False ) );
    CPPUNIT_ASSERT_EQUAL( T( "true" ), T::boolean( true ) );
    CPPUNIT_ASSERT_EQUAL( T( "true" ), T::boolean( sal_True ) );
}

}

void test::strings::valueX::testOBoolean() {
    testBoolean<rtl::OString>();
}

void test::strings::valueX::testOUBoolean() {
    testBoolean<rtl::OUString>();
}

template< typename T >
void testInt() {
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( 30039062 ));

    // test the overloading resolution

    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< signed char >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< unsigned char >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< short >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< unsigned short >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< int >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< unsigned int >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< long >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< unsigned long >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< long long >( 30039062 )));
    // The highest bit set in unsigned long long may not actually work.
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< unsigned long long >( 30039062 )));

    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< sal_Int8 >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30" ), T::number( static_cast< sal_uInt8 >( 30 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< sal_Int16 >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039" ), T::number( static_cast< sal_uInt16 >( 30039 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_Int32 >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_uInt32 >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_Int64 >( 30039062 )));
    CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T::number( static_cast< sal_uInt64 >( 30039062 )));

    // The implementation internally uses sal_Int64 etc. types, so check ranges.
    assert( sizeof( int ) <= sizeof( sal_Int32 ));
    assert( sizeof( long ) <= sizeof( sal_Int64 ));
    assert( sizeof( long long ) <= sizeof( sal_Int64 ));
    assert( sizeof( unsigned int ) < sizeof( sal_Int64 ));
}

void test::strings::valueX::testOUInt() {
    testInt<rtl::OUString>();
}

void test::strings::valueX::testOInt() {
    testInt<rtl::OString>();
}

template< typename T >
void testFloat() {
    CPPUNIT_ASSERT_EQUAL( T( "39062.2" ), T::number( 39062.2f ));
    CPPUNIT_ASSERT_EQUAL( T( "30039062.2" ), T::number( 30039062.2 ));
    // long double not supported
}

void test::strings::valueX::testOUFloat() {
    testFloat<rtl::OUString>();
}

void test::strings::valueX::testOFloat() {
    testFloat<rtl::OString>();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// -*- c++ -*-
//
// Time-stamp: <2015-04-22 09:59:37 zophos>
//
#define DEBUG

#include <iostream>
#include <fstream>

#include <gdcmImageReader.h>

#include <opencv2/opencv.hpp>

cv::Mat1d read_dcm(const std::string& filename)
{
	// Read DCM
	gdcm::ImageReader ir;
	ir.SetFileName(filename.c_str());
	if (!ir.Read()) {
		return cv::Mat1d();
	}

	std::cout << "Getting image from ImageReader..." << std::endl;

	const gdcm::Image &gimage = ir.GetImage();

	std::vector<short> vbuffer(gimage.GetBufferLength());
	gimage.GetBuffer((char*)&vbuffer[0]);

	//const unsigned int* const dimension = gimage.GetDimensions();
	const unsigned int size_x = gimage.GetDimensions()[0];
	const unsigned int size_y = gimage.GetDimensions()[1];

	cv::Mat1d image(size_y, size_x);

	std::copy(vbuffer.begin(), vbuffer.end(), image.begin());
	return image;
}

int main(int argc, char *argv[])
{
	if (argc < 2) {
		return 1;
	}
	const std::string filename = argv[1];
	const std::string outname = argv[2];

	cv::Mat1d image = read_dcm(filename);

	double vmin, vmax;
	cv::minMaxLoc(image, &vmin, &vmax);
	image = (image - vmin) / (vmax - vmin);

	cv::imshow("", image);
	cv::waitKey(0);

	cv::imwrite(outname, 255*image);

	return 0;
}
<commit_msg>Tool annotate_kv: prints intersection of chamber slices with sax slice<commit_after>// -*- c++ -*-
//
// Time-stamp: <2015-04-22 09:59:37 zophos>
//
#define DEBUG

#include <iostream>
#include <fstream>

#include <gdcmReader.h>
#include <gdcmImageReader.h>
#include <gdcmAttribute.h>

#include <opencv2/opencv.hpp>
#include "annotate_lv.h"

struct Slice
{
	cv::Mat1d image;
	cv::Vec3d row_dc;
	cv::Vec3d col_dc;
	cv::Vec3d position;
	cv::Vec3d pixel_spacing;

	cv::Mat1d rotation_matrix() const
	{
		cv::Mat1d rm;
		rm.push_back(row_dc * pixel_spacing[0]);
		rm.push_back(col_dc * pixel_spacing[0]);
		rm.push_back(normal() * pixel_spacing[0]);
		return rm.reshape(1, 3);
	}
	cv::Vec3d normal() const { return row_dc.cross(col_dc); };
};

Slice read_dcm(const std::string& filename)
{
	// Read Imageimage_position
	gdcm::ImageReader ir;
	ir.SetFileName(filename.c_str());
	if (!ir.Read()) {
		std::cerr << "Could not read: " << filename << std::endl;
		return Slice();
	}

	const gdcm::Image &gimage = ir.GetImage();

	std::vector<short> vbuffer(gimage.GetBufferLength());
	gimage.GetBuffer((char*)&vbuffer[0]);

	//const unsigned int* const dimension = gimage.GetDimensions();
	const unsigned int size_x = gimage.GetDimensions()[0];
	const unsigned int size_y = gimage.GetDimensions()[1];
	cv::Mat1d image(size_y, size_x);
	std::copy(vbuffer.begin(), vbuffer.end(), image.begin());

	return Slice{
				image,
				cv::Vec3d(gimage.GetDirectionCosines()),
				cv::Vec3d(gimage.GetDirectionCosines() + 3),
				cv::Vec3d(gimage.GetOrigin()),
				cv::Vec3d(gimage.GetSpacing())
			};
}

cv::Vec3d slices_intersection(const Slice& s1, const Slice& s2, const Slice& s3)
{
	cv::Mat1d normals;
	normals.push_back(s1.normal());
	normals.push_back(s2.normal());
	normals.push_back(s3.normal());
	normals = normals.reshape(1, 3);

	cv::Mat1d d = (cv::Mat1d(3, 1) <<
		s1.normal().dot(s1.position),
		s2.normal().dot(s2.position),
		s3.normal().dot(s3.position)
		);

	cv::Mat1d intersection;
	cv::solve(normals, d, intersection, cv::DECOMP_SVD);
	return cv::Vec3d(intersection);
}

cv::Point2d point2slice(const cv::Vec3d& p, const Slice& s)
{
	const cv::Mat1d projection = s.rotation_matrix().inv().t() * cv::Mat1d(p - s.position);
	return { projection(0, 0), projection(1,0) };
}

int main(int argc, char *argv[])
{
	if (argc < 4) {
		return EXIT_FAILURE;
	}
	const std::string slicecname_2ch = argv[1];
	const std::string slicecname_4ch = argv[2];
	const std::string slicecname_sax = argv[3];

	Slice slice_2ch = read_dcm(slicecname_2ch);
	Slice slice_4ch = read_dcm(slicecname_4ch);
	Slice slice_sax = read_dcm(slicecname_sax);

	cv::Vec3d intersection = slices_intersection(slice_2ch, slice_4ch, slice_sax);
	cv::Point2d intersection_sax = point2slice(intersection, slice_sax);
	double vmin, vmax;
	cv::minMaxLoc(slice_sax.image, &vmin, &vmax);
	cv::Mat1d image = (slice_sax.image - vmin) / (vmax - vmin);

	std::cout
		<< slicecname_sax << "\t"
		<< intersection_sax.x << "\t"
		<< intersection_sax.y << "\t"
		<< intersection_sax.x / slice_sax.image.rows << "\t"
		<< intersection_sax.y / slice_sax.image.cols << std::endl;

#if _DEBUG || 1
	cv::circle(image, intersection_sax, 2, cv::Scalar(255));
	cv::imshow("image", image);
	cv::waitKey(0);
	cv::imwrite("1.png", 255*image);
#endif

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Masayoshi Mizutani <mizutani@sfc.wide.ad.jp>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sstream>
#include <iostream>
#include <msgpack.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <math.h>
#include <unistd.h>
#include <errno.h>

#include "./fluent/queue.hpp"
#include "./debug.h"

namespace fluent {
  // ----------------------------------------------------------------
  // MsgQueue
  const bool MsgQueue::DBG = false;

  MsgQueue::MsgQueue() :
    msg_head_(nullptr), msg_tail_(nullptr),
    count_(0), limit_(1000) {
  }
  MsgQueue::~MsgQueue() {
  }
  bool MsgQueue::push(Message *msg) {
    bool rc = true;

    if (this->count_ < this->limit_) {
      if (this->msg_head_) {
        assert(this->msg_tail_);
        this->msg_tail_->attach(msg);
      } else {
        this->msg_head_ = msg;
      }
      this->msg_tail_ = msg;
      this->count_++;
    } else {
      // queue is full.
      rc = false;
    }

    return rc;
  }

  Message* MsgQueue::pop() {
    Message *msg;

    if (this->msg_head_ == nullptr) {
      return nullptr;
    }

    assert(this->count_ > 0);
    msg = this->msg_head_;
    this->msg_head_ = this->msg_tail_ = nullptr;
    this->count_ = 0;

    return msg;
  }

  void MsgQueue::set_limit(size_t limit) {
    this->limit_ = limit;
  }

  // ----------------------------------------------
  const bool MsgThreadQueue::DBG = true;

  MsgThreadQueue::MsgThreadQueue() : term_(false) {
    // Setup pthread.
    ::pthread_mutex_init(&(this->mutex_), NULL);
    ::pthread_cond_init(&(this->cond_), NULL);
  }
  MsgThreadQueue::~MsgThreadQueue() {
  }
  bool MsgThreadQueue::push(Message *msg) {
    bool rc = true;

    ::pthread_mutex_lock (&(this->mutex_));
    debug(DBG, "entered lock");

    debug(DBG, "PUSH: count:%lu, limit:%lu", this->count(), this->limit());
    if (this->term_) {
      // do not accept more msg because working thread going to shutdown.
    } else {
      rc = this->MsgQueue::push(msg);
    }
    debug(DBG, "PUSHED: count:%lu, limit:%lu", this->count(), this->limit());

    ::pthread_mutex_unlock (&(this->mutex_));
    debug(DBG, "left lock");

    return rc;
  }
  Message* MsgThreadQueue::pop() {
    Message *msg;

    debug(DBG, "entering lock");
    ::pthread_mutex_lock(&(this->mutex_));
    debug(DBG, "entered lock");

    msg = this->MsgQueue::pop();
    if (msg != nullptr) {
      ::pthread_mutex_unlock(&(this->mutex_));
      return msg;
    }

    if (this->term_) {
      // Going to shutdown the thread.
      ::pthread_mutex_unlock(&(this->mutex_));
      debug(DBG, "going to shutdown, leave");
      return nullptr;
    }

    debug(DBG, "entered wait");
    ::pthread_cond_wait(&(this->cond_), &(this->mutex_));
    debug(DBG, "left wait");

    msg = this->MsgQueue::pop();
    ::pthread_mutex_unlock(&(this->mutex_));
    if (msg) {
      debug(DBG, "poped (%p)", msg);
    } else {
      debug(DBG, "no data");
    }

    debug(DBG, "left lock");

    return msg;
  }

  void MsgThreadQueue::term() {
    // Sending terminate signal to worker thread.
    ::pthread_mutex_lock(&(this->mutex_));
    this->term_ = true;
    ::pthread_cond_signal (&(this->cond_));
    ::pthread_mutex_unlock(&(this->mutex_));
    debug(DBG, "sent terminate");
  }

  bool MsgThreadQueue::is_term() {
    bool rc;
    ::pthread_mutex_lock(&(this->mutex_));
    rc = this->term_;
    ::pthread_mutex_unlock(&(this->mutex_));
    debug(DBG, "checked terminate");
    return rc;
  }

  void MsgThreadQueue::set_limit(size_t limit) {
    ::pthread_mutex_lock(&(this->mutex_));
    this->MsgQueue::set_limit(limit);
    ::pthread_mutex_unlock(&(this->mutex_));
  }

}
<commit_msg>add pthread_cond_signal that was removed by mistake<commit_after>/*
 * Copyright (c) 2015 Masayoshi Mizutani <mizutani@sfc.wide.ad.jp>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sstream>
#include <iostream>
#include <msgpack.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <math.h>
#include <unistd.h>
#include <errno.h>

#include "./fluent/queue.hpp"
#include "./debug.h"

namespace fluent {
  // ----------------------------------------------------------------
  // MsgQueue
  const bool MsgQueue::DBG = false;

  MsgQueue::MsgQueue() :
    msg_head_(nullptr), msg_tail_(nullptr),
    count_(0), limit_(1000) {
  }
  MsgQueue::~MsgQueue() {
  }
  bool MsgQueue::push(Message *msg) {
    bool rc = true;

    if (this->count_ < this->limit_) {
      if (this->msg_head_) {
        assert(this->msg_tail_);
        this->msg_tail_->attach(msg);
      } else {
        this->msg_head_ = msg;
      }
      this->msg_tail_ = msg;
      this->count_++;
    } else {
      // queue is full.
      rc = false;
    }

    return rc;
  }

  Message* MsgQueue::pop() {
    Message *msg;

    if (this->msg_head_ == nullptr) {
      return nullptr;
    }

    assert(this->count_ > 0);
    msg = this->msg_head_;
    this->msg_head_ = this->msg_tail_ = nullptr;
    this->count_ = 0;

    return msg;
  }

  void MsgQueue::set_limit(size_t limit) {
    this->limit_ = limit;
  }

  // ----------------------------------------------
  const bool MsgThreadQueue::DBG = false;

  MsgThreadQueue::MsgThreadQueue() : term_(false) {
    // Setup pthread.
    ::pthread_mutex_init(&(this->mutex_), NULL);
    ::pthread_cond_init(&(this->cond_), NULL);
  }
  MsgThreadQueue::~MsgThreadQueue() {
  }
  bool MsgThreadQueue::push(Message *msg) {
    bool rc = true;

    ::pthread_mutex_lock (&(this->mutex_));
    debug(DBG, "entered lock");

    debug(DBG, "PUSH: count:%lu, limit:%lu", this->count(), this->limit());
    if (this->term_) {
      // do not accept more msg because working thread going to shutdown.
    } else {
      rc = this->MsgQueue::push(msg);
      ::pthread_cond_signal (&(this->cond_));
    }
    debug(DBG, "PUSHED: count:%lu, limit:%lu", this->count(), this->limit());

    ::pthread_mutex_unlock (&(this->mutex_));
    debug(DBG, "left lock");

    return rc;
  }
  Message* MsgThreadQueue::pop() {
    Message *msg;

    debug(DBG, "entering lock");
    ::pthread_mutex_lock(&(this->mutex_));
    debug(DBG, "entered lock");

    msg = this->MsgQueue::pop();
    if (msg != nullptr) {
      debug(DBG, "poped before wait (%p)", msg);
      ::pthread_mutex_unlock(&(this->mutex_));
      return msg;
    }

    if (this->term_) {
      // Going to shutdown the thread.
      ::pthread_mutex_unlock(&(this->mutex_));
      debug(DBG, "going to shutdown, leave");
      return nullptr;
    }

    debug(DBG, "entered wait");
    ::pthread_cond_wait(&(this->cond_), &(this->mutex_));
    debug(DBG, "left wait");

    msg = this->MsgQueue::pop();
    ::pthread_mutex_unlock(&(this->mutex_));
    if (msg) {
      debug(DBG, "poped (%p)", msg);
    } else {
      debug(DBG, "no data");
    }

    debug(DBG, "left lock");

    return msg;
  }

  void MsgThreadQueue::term() {
    // Sending terminate signal to worker thread.
    ::pthread_mutex_lock(&(this->mutex_));
    this->term_ = true;
    ::pthread_cond_signal (&(this->cond_));
    ::pthread_mutex_unlock(&(this->mutex_));
    debug(DBG, "sent terminate");
  }

  bool MsgThreadQueue::is_term() {
    bool rc;
    ::pthread_mutex_lock(&(this->mutex_));
    rc = this->term_;
    ::pthread_mutex_unlock(&(this->mutex_));
    debug(DBG, "checked terminate");
    return rc;
  }

  void MsgThreadQueue::set_limit(size_t limit) {
    ::pthread_mutex_lock(&(this->mutex_));
    this->MsgQueue::set_limit(limit);
    ::pthread_mutex_unlock(&(this->mutex_));
  }

}
<|endoftext|>


<commit_before>/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          http://www.mrpt.org/                          |
   |                                                                        |
   | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file     |
   | See: http://www.mrpt.org/Authors - All rights reserved.                |
   | Released under BSD License. See details in http://www.mrpt.org/License |
   +------------------------------------------------------------------------+ */

/**
 * icp3d
 * Execute an Iterative Closest Point algorithm using two 3D point clouds.
 */

#include <mrpt/slam/CICP.h>

#include <mrpt/poses/CPose3DPDF.h>
#include <mrpt/obs/CObservation2DRangeScan.h>
#include <mrpt/maps/CSimplePointsMap.h>
#include <mrpt/gui/CDisplayWindow3D.h>
#include <mrpt/opengl/CGridPlaneXY.h>
#include <mrpt/opengl/CSphere.h>
#include <mrpt/opengl/CAngularObservationMesh.h>
#include <mrpt/opengl/CDisk.h>
#include <mrpt/opengl/stock_objects.h>
#include <iostream>

using namespace std;
using namespace mrpt;
using namespace mrpt::gui;
using namespace mrpt::opengl;
using namespace mrpt::poses;
using namespace mrpt::slam;
using namespace mrpt::maps;
using namespace mrpt::obs;

// Increase this values to get more precision. It will also increase run time.
const size_t HOW_MANY_YAWS = 120;
const size_t HOW_MANY_PITCHS = 120;

// The scans of the 3D object, taken from 2 different places:
vector<CObservation2DRangeScan> sequence_scans1, sequence_scans2;

// The two origins for the 3D scans
CPose3D viewpoint1(-0.3, 0.7, 3, DEG2RAD(5), DEG2RAD(80), DEG2RAD(3));
CPose3D viewpoint2(0.5, -0.2, 2.6, DEG2RAD(-5), DEG2RAD(100), DEG2RAD(-7));

CPose3D SCAN2_POSE_ERROR(0.15, -0.07, 0.10, -0.03, 0.1, 0.1);

/**
 * Generate 3 objects to work with - 1 sphere, 2 disks
 */
void generateObjects(CSetOfObjects::Ptr& world)
{
	CSphere::Ptr sph = mrpt::make_aligned_shared<CSphere>(0.5);
	sph->setLocation(0, 0, 0);
	sph->setColor(1, 0, 0);
	world->insert(sph);

	CDisk::Ptr pln = mrpt::make_aligned_shared<opengl::CDisk>();
	pln->setDiskRadius(2);
	pln->setPose(CPose3D(0, 0, 0, 0, DEG2RAD(5), DEG2RAD(5)));
	pln->setColor(0.8, 0, 0);
	world->insert(pln);

	{
		CDisk::Ptr pln = mrpt::make_aligned_shared<opengl::CDisk>();
		pln->setDiskRadius(2);
		pln->setPose(CPose3D(0, 0, 0, DEG2RAD(30), DEG2RAD(-20), DEG2RAD(-2)));
		pln->setColor(0.9, 0, 0);
		world->insert(pln);
	}
}

void test_icp3D()
{
	// Create the reference objects:
	COpenGLScene::Ptr scene1 = mrpt::make_aligned_shared<COpenGLScene>();
	COpenGLScene::Ptr scene2 = mrpt::make_aligned_shared<COpenGLScene>();
	COpenGLScene::Ptr scene3 = mrpt::make_aligned_shared<COpenGLScene>();

	opengl::CGridPlaneXY::Ptr plane1 =
		mrpt::make_aligned_shared<CGridPlaneXY>(-20, 20, -20, 20, 0, 1);
	plane1->setColor(0.3, 0.3, 0.3);
	scene1->insert(plane1);
	scene2->insert(plane1);
	scene3->insert(plane1);

	CSetOfObjects::Ptr world = mrpt::make_aligned_shared<CSetOfObjects>();
	generateObjects(world);
	scene1->insert(world);

	// Perform the 3D scans:
	CAngularObservationMesh::Ptr aom1 =
		mrpt::make_aligned_shared<CAngularObservationMesh>();
	CAngularObservationMesh::Ptr aom2 =
		mrpt::make_aligned_shared<CAngularObservationMesh>();

	cout << "Performing ray-tracing..." << endl;
	CAngularObservationMesh::trace2DSetOfRays(
		scene1, viewpoint1, aom1,
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_PITCHS),
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_YAWS));
	CAngularObservationMesh::trace2DSetOfRays(
		scene1, viewpoint2, aom2,
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_PITCHS),
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_YAWS));
	cout << "Ray-tracing done" << endl;

	// Put the viewpoints origins:
	{
		CSetOfObjects::Ptr origin1 = opengl::stock_objects::CornerXYZ();
		origin1->setPose(viewpoint1);
		origin1->setScale(0.6);
		scene1->insert(origin1);
		scene2->insert(origin1);
	}
	{
		CSetOfObjects::Ptr origin2 = opengl::stock_objects::CornerXYZ();
		origin2->setPose(viewpoint2);
		origin2->setScale(0.6);
		scene1->insert(origin2);
		scene2->insert(origin2);
	}

	// Show the scanned points:
	CSimplePointsMap M1, M2;

	aom1->generatePointCloud(&M1);
	aom2->generatePointCloud(&M2);

	// Create the wrongly-localized M2:
	CSimplePointsMap M2_noisy;
	M2_noisy = M2;
	M2_noisy.changeCoordinatesReference(SCAN2_POSE_ERROR);

	CSetOfObjects::Ptr PTNS1 = mrpt::make_aligned_shared<CSetOfObjects>();
	CSetOfObjects::Ptr PTNS2 = mrpt::make_aligned_shared<CSetOfObjects>();

	CPointsMap::COLOR_3DSCENE(mrpt::img::TColorf(1, 0, 0));
	M1.getAs3DObject(PTNS1);

	CPointsMap::COLOR_3DSCENE(mrpt::img::TColorf(0, 0, 1));
	M2_noisy.getAs3DObject(PTNS2);

	scene2->insert(PTNS1);
	scene2->insert(PTNS2);

	// --------------------------------------
	// Do the ICP-3D
	// --------------------------------------
	float run_time;
	CICP icp;
	CICP::TReturnInfo icp_info;

	icp.options.thresholdDist = 0.40;
	icp.options.thresholdAng = 0;

	std::vector<double> xs, ys, zs;
	M1.getAllPoints(xs, ys, ys);
	cout << "Size of  xs in M1: " << xs.size() << endl;
	M2.getAllPoints(xs, ys, ys);
	cout << "Size of  xs in M2: " << xs.size() << endl;

	CPose3DPDF::Ptr pdf = icp.Align3D(
		&M2_noisy,  // Map to align
		&M1,  // Reference map
		CPose3D(),  // Initial gross estimate
		&run_time, &icp_info);

	CPose3D mean = pdf->getMeanVal();

	cout << "ICP run took " << run_time << " secs." << endl;
	cout << "Goodness: " << 100 * icp_info.goodness
		 << "% , # of iterations= " << icp_info.nIterations
		 << " Quality: " << icp_info.quality << endl;
	cout << "ICP output: mean= " << mean << endl;
	cout << "Real displacement: " << SCAN2_POSE_ERROR << endl;

	// Aligned maps:
	CSetOfObjects::Ptr PTNS2_ALIGN = mrpt::make_aligned_shared<CSetOfObjects>();

	M2_noisy.changeCoordinatesReference(CPose3D() - mean);
	M2_noisy.getAs3DObject(PTNS2_ALIGN);

	scene3->insert(PTNS1);
	scene3->insert(PTNS2_ALIGN);

	// Show in Windows:
	CDisplayWindow3D window("ICP-3D demo: scene", 500, 500);
	CDisplayWindow3D window2("ICP-3D demo: UNALIGNED scans", 500, 500);
	CDisplayWindow3D window3("ICP-3D demo: ICP-ALIGNED scans", 500, 500);

	window.setPos(10, 10);
	window2.setPos(530, 10);
	window3.setPos(10, 520);

	window.get3DSceneAndLock() = scene1;
	window.unlockAccess3DScene();

	window2.get3DSceneAndLock() = scene2;
	window2.unlockAccess3DScene();

	window3.get3DSceneAndLock() = scene3;
	window3.unlockAccess3DScene();

	std::this_thread::sleep_for(20ms);
	window.forceRepaint();
	window2.forceRepaint();

	window.setCameraElevationDeg(15);
	window.setCameraAzimuthDeg(90);
	window.setCameraZoom(15);

	window2.setCameraElevationDeg(15);
	window2.setCameraAzimuthDeg(90);
	window2.setCameraZoom(15);

	window3.setCameraElevationDeg(15);
	window3.setCameraAzimuthDeg(90);
	window3.setCameraZoom(15);

	cout << "Press any key to exit..." << endl;
	window.waitForKey();
}

int main()
{
	try
	{
		test_icp3D();
		return 0;
	}
	catch (exception& e)
	{
		cout << "Error: " << e.what() << '.' << endl;
		return -1;
	}
	catch (...)
	{
		cout << "Unknown Error.\n";
		return -1;
	}
}
<commit_msg>Fix slam_icp3d_simple_example<commit_after>/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          http://www.mrpt.org/                          |
   |                                                                        |
   | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file     |
   | See: http://www.mrpt.org/Authors - All rights reserved.                |
   | Released under BSD License. See details in http://www.mrpt.org/License |
   +------------------------------------------------------------------------+ */

/**
 * icp3d
 * Execute an Iterative Closest Point algorithm using two 3D point clouds.
 */

#include <mrpt/slam/CICP.h>

#include <mrpt/poses/CPose3DPDF.h>
#include <mrpt/obs/CObservation2DRangeScan.h>
#include <mrpt/maps/CSimplePointsMap.h>
#include <mrpt/gui/CDisplayWindow3D.h>
#include <mrpt/opengl/CGridPlaneXY.h>
#include <mrpt/opengl/CSphere.h>
#include <mrpt/opengl/CAngularObservationMesh.h>
#include <mrpt/opengl/CDisk.h>
#include <mrpt/opengl/stock_objects.h>
#include <iostream>

using namespace std;
using namespace mrpt;
using namespace mrpt::gui;
using namespace mrpt::opengl;
using namespace mrpt::poses;
using namespace mrpt::slam;
using namespace mrpt::maps;
using namespace mrpt::obs;

// Increase this values to get more precision. It will also increase run time.
const size_t HOW_MANY_YAWS = 120;
const size_t HOW_MANY_PITCHS = 120;

// The scans of the 3D object, taken from 2 different places:
vector<CObservation2DRangeScan> sequence_scans1, sequence_scans2;

// The two origins for the 3D scans
CPose3D viewpoint1(-0.3, 0.7, 3, DEG2RAD(5), DEG2RAD(80), DEG2RAD(3));
CPose3D viewpoint2(0.5, -0.2, 2.6, DEG2RAD(-5), DEG2RAD(100), DEG2RAD(-7));

CPose3D SCAN2_POSE_ERROR(0.15, -0.07, 0.10, -0.03, 0.1, 0.1);

/**
 * Generate 3 objects to work with - 1 sphere, 2 disks
 */
void generateObjects(CSetOfObjects::Ptr& world)
{
	CSphere::Ptr sph = mrpt::make_aligned_shared<CSphere>(0.5);
	sph->setLocation(0, 0, 0);
	sph->setColor(1, 0, 0);
	world->insert(sph);

	CDisk::Ptr pln = mrpt::make_aligned_shared<opengl::CDisk>();
	pln->setDiskRadius(2);
	pln->setPose(CPose3D(0, 0, 0, 0, DEG2RAD(5), DEG2RAD(5)));
	pln->setColor(0.8, 0, 0);
	world->insert(pln);

	{
		CDisk::Ptr pln = mrpt::make_aligned_shared<opengl::CDisk>();
		pln->setDiskRadius(2);
		pln->setPose(CPose3D(0, 0, 0, DEG2RAD(30), DEG2RAD(-20), DEG2RAD(-2)));
		pln->setColor(0.9, 0, 0);
		world->insert(pln);
	}
}

void test_icp3D()
{
	// Create the reference objects:
	COpenGLScene::Ptr scene1 = mrpt::make_aligned_shared<COpenGLScene>();
	COpenGLScene::Ptr scene2 = mrpt::make_aligned_shared<COpenGLScene>();
	COpenGLScene::Ptr scene3 = mrpt::make_aligned_shared<COpenGLScene>();

	opengl::CGridPlaneXY::Ptr plane1 =
		mrpt::make_aligned_shared<CGridPlaneXY>(-20, 20, -20, 20, 0, 1);
	plane1->setColor(0.3, 0.3, 0.3);
	scene1->insert(plane1);
	scene2->insert(plane1);
	scene3->insert(plane1);

	CSetOfObjects::Ptr world = mrpt::make_aligned_shared<CSetOfObjects>();
	generateObjects(world);
	scene1->insert(world);

	// Perform the 3D scans:
	CAngularObservationMesh::Ptr aom1 =
		mrpt::make_aligned_shared<CAngularObservationMesh>();
	CAngularObservationMesh::Ptr aom2 =
		mrpt::make_aligned_shared<CAngularObservationMesh>();

	cout << "Performing ray-tracing..." << endl;
	CAngularObservationMesh::trace2DSetOfRays(
		scene1, viewpoint1, aom1,
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_PITCHS),
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_YAWS));
	CAngularObservationMesh::trace2DSetOfRays(
		scene1, viewpoint2, aom2,
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_PITCHS),
		CAngularObservationMesh::TDoubleRange::CreateFromAperture(
			M_PI, HOW_MANY_YAWS));
	cout << "Ray-tracing done" << endl;

	// Put the viewpoints origins:
	{
		CSetOfObjects::Ptr origin1 = opengl::stock_objects::CornerXYZ();
		origin1->setPose(viewpoint1);
		origin1->setScale(0.6);
		scene1->insert(origin1);
		scene2->insert(origin1);
	}
	{
		CSetOfObjects::Ptr origin2 = opengl::stock_objects::CornerXYZ();
		origin2->setPose(viewpoint2);
		origin2->setScale(0.6);
		scene1->insert(origin2);
		scene2->insert(origin2);
	}

	// Show the scanned points:
	CSimplePointsMap M1, M2;

	aom1->generatePointCloud(&M1);
	aom2->generatePointCloud(&M2);

	// Create the wrongly-localized M2:
	CSimplePointsMap M2_noisy;
	M2_noisy = M2;
	M2_noisy.changeCoordinatesReference(SCAN2_POSE_ERROR);

	CSetOfObjects::Ptr PTNS1 = mrpt::make_aligned_shared<CSetOfObjects>();
	CSetOfObjects::Ptr PTNS2 = mrpt::make_aligned_shared<CSetOfObjects>();

	M1.renderOptions.color = mrpt::img::TColorf(1, 0, 0);
	M1.getAs3DObject(PTNS1);

	M2_noisy.renderOptions.color = mrpt::img::TColorf(0, 0, 1);
	M2_noisy.getAs3DObject(PTNS2);

	scene2->insert(PTNS1);
	scene2->insert(PTNS2);

	// --------------------------------------
	// Do the ICP-3D
	// --------------------------------------
	float run_time;
	CICP icp;
	CICP::TReturnInfo icp_info;

	icp.options.thresholdDist = 0.40;
	icp.options.thresholdAng = 0;

	std::vector<double> xs, ys, zs;
	M1.getAllPoints(xs, ys, ys);
	cout << "Size of  xs in M1: " << xs.size() << endl;
	M2.getAllPoints(xs, ys, ys);
	cout << "Size of  xs in M2: " << xs.size() << endl;

	CPose3DPDF::Ptr pdf = icp.Align3D(
		&M2_noisy,  // Map to align
		&M1,  // Reference map
		CPose3D(),  // Initial gross estimate
		&run_time, &icp_info);

	CPose3D mean = pdf->getMeanVal();

	cout << "ICP run took " << run_time << " secs." << endl;
	cout << "Goodness: " << 100 * icp_info.goodness
		 << "% , # of iterations= " << icp_info.nIterations
		 << " Quality: " << icp_info.quality << endl;
	cout << "ICP output: mean= " << mean << endl;
	cout << "Real displacement: " << SCAN2_POSE_ERROR << endl;

	// Aligned maps:
	CSetOfObjects::Ptr PTNS2_ALIGN = mrpt::make_aligned_shared<CSetOfObjects>();

	M2_noisy.changeCoordinatesReference(CPose3D() - mean);
	M2_noisy.getAs3DObject(PTNS2_ALIGN);

	scene3->insert(PTNS1);
	scene3->insert(PTNS2_ALIGN);

	// Show in Windows:
	CDisplayWindow3D window("ICP-3D demo: scene", 500, 500);
	CDisplayWindow3D window2("ICP-3D demo: UNALIGNED scans", 500, 500);
	CDisplayWindow3D window3("ICP-3D demo: ICP-ALIGNED scans", 500, 500);

	window.setPos(10, 10);
	window2.setPos(530, 10);
	window3.setPos(10, 520);

	window.get3DSceneAndLock() = scene1;
	window.unlockAccess3DScene();

	window2.get3DSceneAndLock() = scene2;
	window2.unlockAccess3DScene();

	window3.get3DSceneAndLock() = scene3;
	window3.unlockAccess3DScene();

	std::this_thread::sleep_for(20ms);
	window.forceRepaint();
	window2.forceRepaint();

	window.setCameraElevationDeg(15);
	window.setCameraAzimuthDeg(90);
	window.setCameraZoom(15);

	window2.setCameraElevationDeg(15);
	window2.setCameraAzimuthDeg(90);
	window2.setCameraZoom(15);

	window3.setCameraElevationDeg(15);
	window3.setCameraAzimuthDeg(90);
	window3.setCameraZoom(15);

	cout << "Press any key to exit..." << endl;
	window.waitForKey();
}

int main()
{
	try
	{
		test_icp3D();
		return 0;
	}
	catch (exception& e)
	{
		cout << "Error: " << e.what() << '.' << endl;
		return -1;
	}
	catch (...)
	{
		cout << "Unknown Error.\n";
		return -1;
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sandbox/win/sandbox_poc/pocdll/exports.h"
#include "sandbox/win/sandbox_poc/pocdll/utils.h"

// This file contains the tests used to verify the security of the registry.

// Converts an HKEY to a string. This is using the lazy way and works only
// for the main hives.
// "key" is the hive to convert to string.
// The return value is the string corresponding to the hive or "unknown"
const wchar_t *HKEYToString(const HKEY key) {
  switch (reinterpret_cast<LONG_PTR>(key)) {
    case reinterpret_cast<LONG_PTR>(HKEY_CLASSES_ROOT):
      return L"HKEY_CLASSES_ROOT";
    case reinterpret_cast<LONG_PTR>(HKEY_CURRENT_CONFIG):
      return L"HKEY_CURRENT_CONFIG";
    case reinterpret_cast<LONG_PTR>(HKEY_CURRENT_USER):
      return L"HKEY_CURRENT_USER";
    case reinterpret_cast<LONG_PTR>(HKEY_LOCAL_MACHINE):
      return L"HKEY_LOCAL_MACHINE";
    case reinterpret_cast<LONG_PTR>(HKEY_USERS):
      return L"HKEY_USERS";
  }
  return L"unknown";
}

// Tries to open the key hive\path and outputs the result.
// "output" is the stream used for logging.
void TryOpenKey(const HKEY hive, const wchar_t *path, FILE *output) {
  HKEY key;
  LONG err_code = ::RegOpenKeyEx(hive,
                                 path,
                                 0,  // Reserved, must be 0.
                                 MAXIMUM_ALLOWED,
                                 &key);
  if (ERROR_SUCCESS == err_code) {
    fprintf(output, "[GRANTED] Opening key \"%S\\%S\". Handle 0x%p\r\n",
            HKEYToString(hive),
            path,
            key);
    ::RegCloseKey(key);
  } else {
    fprintf(output, "[BLOCKED] Opening key \"%S\\%S\". Error %ld\r\n",
            HKEYToString(hive),
            path,
            err_code);
  }
}

void POCDLL_API TestRegistry(HANDLE log) {
  HandleToFile handle2file;
  FILE *output = handle2file.Translate(log, "w");

  TryOpenKey(HKEY_LOCAL_MACHINE, NULL, output);
  TryOpenKey(HKEY_CURRENT_USER, NULL, output);
  TryOpenKey(HKEY_USERS, NULL, output);
  TryOpenKey(HKEY_LOCAL_MACHINE,
             L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
             output);
}
<commit_msg>More compiler whack-a-mole.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sandbox/win/sandbox_poc/pocdll/exports.h"
#include "sandbox/win/sandbox_poc/pocdll/utils.h"

// This file contains the tests used to verify the security of the registry.

// Tries to open the key hive\path and outputs the result.
// "output" is the stream used for logging.
void TryOpenKey(const HKEY hive,
                const wchar_t* hive_name,
                const wchar_t* path,
                FILE* output) {
  HKEY key;
  LONG err_code = ::RegOpenKeyEx(hive,
                                 path,
                                 0,  // Reserved, must be 0.
                                 MAXIMUM_ALLOWED,
                                 &key);
  if (ERROR_SUCCESS == err_code) {
    fprintf(output,
            "[GRANTED] Opening key \"%S\\%S\". Handle 0x%p\r\n",
            hive_name,
            path,
            key);
    ::RegCloseKey(key);
  } else {
    fprintf(output,
            "[BLOCKED] Opening key \"%S\\%S\". Error %ld\r\n",
            hive_name,
            path,
            err_code);
  }
}

void POCDLL_API TestRegistry(HANDLE log) {
  HandleToFile handle2file;
  FILE *output = handle2file.Translate(log, "w");

  TryOpenKey(HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE", NULL, output);
  TryOpenKey(HKEY_CURRENT_USER, L"HKEY_CURRENT_USER", NULL, output);
  TryOpenKey(HKEY_USERS, L"HKEY_USERS", NULL, output);
  TryOpenKey(HKEY_LOCAL_MACHINE,
             L"HKEY_LOCAL_MACHINE",
             L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
             output);
}
<|endoftext|>