<commit_before>#include "ModuleAssimp.h"
#include "Globals.h"
#include "Application.h"
#include "ModuleGui.h"
#include "Module.h"
#include"Imgui/imgui_impl_sdl.h"
#include"Imgui\imgui_impl_sdl_gl3.h"
#include"Imgui/imgui.h"
#include"ModuleSceneIntro.h"

ModuleAssimp::ModuleAssimp(bool start_enabled) : Module(start_enabled)
{

}

// Destructor
ModuleAssimp::~ModuleAssimp()
{
}

// Called before render is available
bool ModuleAssimp::Start()
{
	ilutRenderer(ILUT_OPENGL);
	ilInit();
	iluInit();
	ilutInit();
	ilutRenderer(ILUT_OPENGL);

	ilClearColour(255, 255, 255, 000);

	//Check for error
	ILenum ilError = ilGetError();
	if (ilError != IL_NO_ERROR)
	{
		LOG("IlInit error!!");
	}

	struct aiLogStream stream;
	stream = aiGetPredefinedLogStream(aiDefaultLogStream_DEBUGGER, NULL);
	aiAttachLogStream(&stream);

	for (int p = 0; p < meshes_vec.size(); p++) {
		meshes_vec[p]->Initialize();
	}

	return true;
}

update_status ModuleAssimp::PreUpdate(float dt)
{

	return update_status::UPDATE_CONTINUE;
}

update_status ModuleAssimp::Update(float dt)
{

	for (int p = 0; p < meshes_vec.size(); p++) {
		meshes_vec[p]->Draw();
	}

	if (App->input->flie_dropped) {
		if (IsTexture(App->input->dropped_filedir) == false) {
			for (int p = 0; p < meshes_vec.size(); p++) {
				delete meshes_vec[p];
			}

			meshes_vec.clear();
		}
		bool loaded = ImportGeometry(App->input->dropped_filedir);
		for (int p = 0; p < meshes_vec.size(); p++) {
			meshes_vec[p]->Initialize();
		}
<<<<<<< HEAD
		if (loaded == true)
		{
			App->camera->CameraCenter(&meshes_vec.back()->mesh.BoundBox);
		}
		App->input->flie_dropped = false;
=======

			App->input->flie_dropped = false;

>>>>>>> origin/Assigment_1
	}

	return UPDATE_CONTINUE;
}

update_status ModuleAssimp::PostUpdate(float dt)
{

	return UPDATE_CONTINUE;
}

bool ModuleAssimp::Gui_Engine_Modules(float dt)
{

	return false;
}

// Called before quitting
bool ModuleAssimp::CleanUp()
{

	return true;
}

bool ModuleAssimp::ImportGeometry(char* fbx)
{

	//----------------ASSIMP

	std::string full_path;
	full_path = fbx;
	const aiScene* scene = aiImportFile(full_path.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);

	if (scene != nullptr && scene->HasMeshes())
	{
		// Use scene->mNumMeshes to iterate on scene->mMeshes array
		for (int i = 0; i < scene->mNumMeshes; i++) {
			m = new Geometry_Manager(PrimitiveTypes::Primitive_Mesh);
			m->mesh.num_vertices = scene->mMeshes[i]->mNumVertices;
			m->mesh.vertices = new float[m->mesh.num_vertices * 3];
			memcpy(m->mesh.vertices, scene->mMeshes[i]->mVertices, sizeof(float) * m->mesh.num_vertices * 3);
			LOG("New mesh with %d vertices", m->mesh.num_vertices);
			//Generate bounding bax
			m->mesh.BoundBox.SetNegativeInfinity();
			m->mesh.BoundBox.Enclose((float3*)m->mesh.vertices, m->mesh.num_vertices);
			//
			// copy faces
			if (scene->mMeshes[i]->HasFaces())
			{
				m->mesh.num_tris = scene->mMeshes[i]->mNumFaces;
				m->mesh.num_indices = scene->mMeshes[i]->mNumFaces * 3;
				m->mesh.indices = new uint[m->mesh.num_indices]; // assume each face is a triangle

				for (uint k = 0; k < scene->mMeshes[i]->mNumFaces; ++k)
				{
					if (scene->mMeshes[i]->mFaces[k].mNumIndices != 3) {
						LOG("WARNING, geometry face with != 3 indices!");
					}
					else {
						memcpy(&m->mesh.indices[k * 3], scene->mMeshes[i]->mFaces[k].mIndices, 3 * sizeof(uint));
					}
				}
			}

			if (scene->mMeshes[i]->HasNormals()) {
				m->mesh.normals = new float[m->mesh.num_vertices * 3];
				memcpy(m->mesh.normals, scene->mMeshes[i]->mNormals, sizeof(float) * m->mesh.num_vertices * 3);
			}

			aiVector3D translation;
			aiVector3D scaling;
			aiQuaternion rotation;

			/*for (int i = 0; i < scene->mRootNode->mNumChildren; i++) {
				scene->mRootNode->mChildren[i]->mTransformation.Decompose(scaling, rotation, translation);
				m->mesh.translation.Set(translation.x,translation.y, translation.z);
				m->mesh.scaling.Set(scaling.x, scaling.y, scaling.z);
				m->mesh.rotation.Set(rotation.x, rotation.y, rotation.z, rotation.w);
			}*/
			aiNode* nod =Calc_AllGeometry_Childs(scene->mRootNode, i);
			aiMatrix4x4 temp_trans;
			while (nod->mParent!=nullptr) {
				temp_trans*=nod->mTransformation;
				nod = nod->mParent;
			}
			temp_trans.Decompose(scaling, rotation, translation);
			m->mesh.translation.Set(translation.x, translation.y, translation.z);
			m->mesh.scaling.Set(scaling.x, scaling.y, scaling.z);
			m->mesh.rotation.Set(rotation.x, rotation.y, rotation.z, rotation.w);

			// texture coords (only one texture for now)
			if (scene->mMeshes[i]->HasTextureCoords(0))
			{
				m->mesh.textures_coord = new float[m->mesh.num_vertices * 2];

				for (int z = 0; z < scene->mMeshes[i]->mNumVertices; ++z) {

					m->mesh.textures_coord[z*2] = scene->mMeshes[i]->mTextureCoords[0][z].x;
					m->mesh.textures_coord[z * 2+1] = scene->mMeshes[i]->mTextureCoords[0][z].y;

				}

			}

			aiMaterial* material = scene->mMaterials[scene->mMeshes[i]->mMaterialIndex];
			uint numTextures = material->GetTextureCount(aiTextureType_DIFFUSE);
			aiString path;
			material->GetTexture(aiTextureType_DIFFUSE, 0, &path);
			m->mesh.texture_str = path.C_Str();
			meshes_vec.push_back(m);

		}
		return true;
		aiReleaseImport(scene);
	}
	else {

		bool textureLoaded = false;

		//Generate and set current image ID

		if (IsTexture(fbx))
		{
			for (int p = 0; p < meshes_vec.size(); p++) {
				meshes_vec[p]->mesh.texture_str = fbx;
			}
		}
		LOG("Error loading scene %s", full_path);
		return false;
	}
	//aiMesh

}

GLuint ModuleAssimp::LoadImage_devil(const char * theFileName, GLuint *buff)
{

	//Texture loading success
	bool textureLoaded = false;

	//Generate and set current image ID
	uint imgID = 0;
	ilGenImages(1, &imgID);
	ilBindImage(imgID);

	//Load image
	ILboolean success = ilLoadImage(theFileName);

	//Image loaded successfully
	if (success == IL_TRUE)
	{
		ILinfo ImageInfo;
		iluGetImageInfo(&ImageInfo);
		if (ImageInfo.Origin == IL_ORIGIN_UPPER_LEFT)
		{
			iluFlipImage();
		}

		//Convert image to RGBA
		success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

		if (success == IL_TRUE)
		{
			textureLoaded = loadTextureFromPixels32((GLuint*)ilGetData(), (GLuint)ilGetInteger(IL_IMAGE_WIDTH), (GLuint)ilGetInteger(IL_IMAGE_HEIGHT), buff);
			//Create texture from file pixels
			textureLoaded = true;
		}

		//Delete file from memory
		ilDeleteImages(1, &imgID);
	}

	//Report error
	if (!textureLoaded)
	{

	}
	return textureLoaded;

}

bool ModuleAssimp::loadTextureFromPixels32(GLuint * id_pixels, GLuint width_img, GLuint height_img, GLuint *buff)
{

	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(1, buff);
	glBindTexture(GL_TEXTURE_2D, *buff);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_img, height_img,
		0, GL_RGBA, GL_UNSIGNED_BYTE, id_pixels);
	glBindTexture(GL_TEXTURE_2D, NULL);
	//Check for error
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
	{
		printf("Error loading texture from %p pixels! %s\n", id_pixels, gluErrorString(error));
		return false;
	}

	return true;
}

bool ModuleAssimp::IsTexture(char * path)
{
	bool ret = false;

	uint imgID = 0;
	ilGenImages(1, &imgID);
	ilBindImage(imgID);

	//Load image
	ILboolean success = ilLoadImage(path);
	if (success) {
		ret = true;
	}
	ilDeleteImages(1, &imgID);

	return ret;
}

aiNode* ModuleAssimp::Calc_AllGeometry_Childs(aiNode* Parent_node, uint search_mesh) {

	aiNode* temp;
	if (Parent_node != nullptr) {
		int i;
		for (i = 0; i < Parent_node->mNumChildren; i++) {
			for (int j = 0; j < Parent_node->mChildren[i]->mNumMeshes; j++) {
				if (Parent_node->mChildren[i]->mMeshes[j] == search_mesh) {
					return Parent_node->mChildren[i];
				}
			}
			if (Parent_node->mNumChildren > 0) {
				temp = Calc_AllGeometry_Childs(Parent_node->mChildren[i], search_mesh);
				if (temp != nullptr)
					return temp;
			}
		}

	}
	return nullptr;

}<commit_msg>Fixed merge<commit_after>#include "ModuleAssimp.h"
#include "Globals.h"
#include "Application.h"
#include "ModuleGui.h"
#include "Module.h"
#include"Imgui/imgui_impl_sdl.h"
#include"Imgui\imgui_impl_sdl_gl3.h"
#include"Imgui/imgui.h"
#include"ModuleSceneIntro.h"

ModuleAssimp::ModuleAssimp(bool start_enabled) : Module(start_enabled)
{

}

// Destructor
ModuleAssimp::~ModuleAssimp()
{
}

// Called before render is available
bool ModuleAssimp::Start()
{
	ilutRenderer(ILUT_OPENGL);
	ilInit();
	iluInit();
	ilutInit();
	ilutRenderer(ILUT_OPENGL);

	ilClearColour(255, 255, 255, 000);

	//Check for error
	ILenum ilError = ilGetError();
	if (ilError != IL_NO_ERROR)
	{
		LOG("IlInit error!!");
	}

	struct aiLogStream stream;
	stream = aiGetPredefinedLogStream(aiDefaultLogStream_DEBUGGER, NULL);
	aiAttachLogStream(&stream);

	for (int p = 0; p < meshes_vec.size(); p++) {
		meshes_vec[p]->Initialize();
	}

	return true;
}

update_status ModuleAssimp::PreUpdate(float dt)
{

	return update_status::UPDATE_CONTINUE;
}

update_status ModuleAssimp::Update(float dt)
{

	for (int p = 0; p < meshes_vec.size(); p++) {
		meshes_vec[p]->Draw();
	}

	if (App->input->flie_dropped) {
		if (IsTexture(App->input->dropped_filedir) == false) {
			for (int p = 0; p < meshes_vec.size(); p++) {
				delete meshes_vec[p];
			}

			meshes_vec.clear();
		}
		bool loaded = ImportGeometry(App->input->dropped_filedir);
		for (int p = 0; p < meshes_vec.size(); p++) {
			meshes_vec[p]->Initialize();
		}

		if (loaded == true)
		{
			App->camera->CameraCenter(&meshes_vec.back()->mesh.BoundBox);
		}
		App->input->flie_dropped = false;

			App->input->flie_dropped = false;

	}

	return UPDATE_CONTINUE;
}

update_status ModuleAssimp::PostUpdate(float dt)
{

	return UPDATE_CONTINUE;
}

bool ModuleAssimp::Gui_Engine_Modules(float dt)
{

	return false;
}

// Called before quitting
bool ModuleAssimp::CleanUp()
{

	return true;
}

bool ModuleAssimp::ImportGeometry(char* fbx)
{

	//----------------ASSIMP

	std::string full_path;
	full_path = fbx;
	const aiScene* scene = aiImportFile(full_path.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);

	if (scene != nullptr && scene->HasMeshes())
	{
		// Use scene->mNumMeshes to iterate on scene->mMeshes array
		for (int i = 0; i < scene->mNumMeshes; i++) {
			m = new Geometry_Manager(PrimitiveTypes::Primitive_Mesh);
			m->mesh.num_vertices = scene->mMeshes[i]->mNumVertices;
			m->mesh.vertices = new float[m->mesh.num_vertices * 3];
			memcpy(m->mesh.vertices, scene->mMeshes[i]->mVertices, sizeof(float) * m->mesh.num_vertices * 3);
			LOG("New mesh with %d vertices", m->mesh.num_vertices);
			//Generate bounding bax
			m->mesh.BoundBox.SetNegativeInfinity();
			m->mesh.BoundBox.Enclose((float3*)m->mesh.vertices, m->mesh.num_vertices);
			//
			// copy faces
			if (scene->mMeshes[i]->HasFaces())
			{
				m->mesh.num_tris = scene->mMeshes[i]->mNumFaces;
				m->mesh.num_indices = scene->mMeshes[i]->mNumFaces * 3;
				m->mesh.indices = new uint[m->mesh.num_indices]; // assume each face is a triangle

				for (uint k = 0; k < scene->mMeshes[i]->mNumFaces; ++k)
				{
					if (scene->mMeshes[i]->mFaces[k].mNumIndices != 3) {
						LOG("WARNING, geometry face with != 3 indices!");
					}
					else {
						memcpy(&m->mesh.indices[k * 3], scene->mMeshes[i]->mFaces[k].mIndices, 3 * sizeof(uint));
					}
				}
			}

			if (scene->mMeshes[i]->HasNormals()) {
				m->mesh.normals = new float[m->mesh.num_vertices * 3];
				memcpy(m->mesh.normals, scene->mMeshes[i]->mNormals, sizeof(float) * m->mesh.num_vertices * 3);
			}

			aiVector3D translation;
			aiVector3D scaling;
			aiQuaternion rotation;

			/*for (int i = 0; i < scene->mRootNode->mNumChildren; i++) {
				scene->mRootNode->mChildren[i]->mTransformation.Decompose(scaling, rotation, translation);
				m->mesh.translation.Set(translation.x,translation.y, translation.z);
				m->mesh.scaling.Set(scaling.x, scaling.y, scaling.z);
				m->mesh.rotation.Set(rotation.x, rotation.y, rotation.z, rotation.w);
			}*/
			aiNode* nod =Calc_AllGeometry_Childs(scene->mRootNode, i);
			aiMatrix4x4 temp_trans;
			while (nod->mParent!=nullptr) {
				temp_trans*=nod->mTransformation;
				nod = nod->mParent;
			}
			temp_trans.Decompose(scaling, rotation, translation);
			m->mesh.translation.Set(translation.x, translation.y, translation.z);
			m->mesh.scaling.Set(scaling.x, scaling.y, scaling.z);
			m->mesh.rotation.Set(rotation.x, rotation.y, rotation.z, rotation.w);

			// texture coords (only one texture for now)
			if (scene->mMeshes[i]->HasTextureCoords(0))
			{
				m->mesh.textures_coord = new float[m->mesh.num_vertices * 2];

				for (int z = 0; z < scene->mMeshes[i]->mNumVertices; ++z) {

					m->mesh.textures_coord[z*2] = scene->mMeshes[i]->mTextureCoords[0][z].x;
					m->mesh.textures_coord[z * 2+1] = scene->mMeshes[i]->mTextureCoords[0][z].y;

				}

			}

			aiMaterial* material = scene->mMaterials[scene->mMeshes[i]->mMaterialIndex];
			uint numTextures = material->GetTextureCount(aiTextureType_DIFFUSE);
			aiString path;
			material->GetTexture(aiTextureType_DIFFUSE, 0, &path);
			m->mesh.texture_str = path.C_Str();
			meshes_vec.push_back(m);

		}
		return true;
		aiReleaseImport(scene);
	}
	else {

		bool textureLoaded = false;

		//Generate and set current image ID

		if (IsTexture(fbx))
		{
			for (int p = 0; p < meshes_vec.size(); p++) {
				meshes_vec[p]->mesh.texture_str = fbx;
			}
		}
		LOG("Error loading scene %s", full_path);
		return false;
	}
	//aiMesh

}

GLuint ModuleAssimp::LoadImage_devil(const char * theFileName, GLuint *buff)
{

	//Texture loading success
	bool textureLoaded = false;

	//Generate and set current image ID
	uint imgID = 0;
	ilGenImages(1, &imgID);
	ilBindImage(imgID);

	//Load image
	ILboolean success = ilLoadImage(theFileName);

	//Image loaded successfully
	if (success == IL_TRUE)
	{
		ILinfo ImageInfo;
		iluGetImageInfo(&ImageInfo);
		if (ImageInfo.Origin == IL_ORIGIN_UPPER_LEFT)
		{
			iluFlipImage();
		}

		//Convert image to RGBA
		success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

		if (success == IL_TRUE)
		{
			textureLoaded = loadTextureFromPixels32((GLuint*)ilGetData(), (GLuint)ilGetInteger(IL_IMAGE_WIDTH), (GLuint)ilGetInteger(IL_IMAGE_HEIGHT), buff);
			//Create texture from file pixels
			textureLoaded = true;
		}

		//Delete file from memory
		ilDeleteImages(1, &imgID);
	}

	//Report error
	if (!textureLoaded)
	{

	}
	return textureLoaded;

}

bool ModuleAssimp::loadTextureFromPixels32(GLuint * id_pixels, GLuint width_img, GLuint height_img, GLuint *buff)
{

	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(1, buff);
	glBindTexture(GL_TEXTURE_2D, *buff);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_img, height_img,
		0, GL_RGBA, GL_UNSIGNED_BYTE, id_pixels);
	glBindTexture(GL_TEXTURE_2D, NULL);
	//Check for error
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
	{
		printf("Error loading texture from %p pixels! %s\n", id_pixels, gluErrorString(error));
		return false;
	}

	return true;
}

bool ModuleAssimp::IsTexture(char * path)
{
	bool ret = false;

	uint imgID = 0;
	ilGenImages(1, &imgID);
	ilBindImage(imgID);

	//Load image
	ILboolean success = ilLoadImage(path);
	if (success) {
		ret = true;
	}
	ilDeleteImages(1, &imgID);

	return ret;
}

aiNode* ModuleAssimp::Calc_AllGeometry_Childs(aiNode* Parent_node, uint search_mesh) {

	aiNode* temp;
	if (Parent_node != nullptr) {
		int i;
		for (i = 0; i < Parent_node->mNumChildren; i++) {
			for (int j = 0; j < Parent_node->mChildren[i]->mNumMeshes; j++) {
				if (Parent_node->mChildren[i]->mMeshes[j] == search_mesh) {
					return Parent_node->mChildren[i];
				}
			}
			if (Parent_node->mNumChildren > 0) {
				temp = Calc_AllGeometry_Childs(Parent_node->mChildren[i], search_mesh);
				if (temp != nullptr)
					return temp;
			}
		}

	}
	return nullptr;

}<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * Copyright 2010 VMware, Inc.
 * All Rights Reserved.
 *
 * 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 <string.h>
#include <limits.h> // for CHAR_MAX
#include <getopt.h>

#include "cli.hpp"
#include "cli_pager.hpp"

#include "trace_parser.hpp"
#include "trace_dump.hpp"
#include "trace_callset.hpp"

enum ColorOption {
    COLOR_OPTION_NEVER = 0,
    COLOR_OPTION_ALWAYS = 1,
    COLOR_OPTION_AUTO = -1
};

static ColorOption color = COLOR_OPTION_AUTO;

static bool verbose = false;

static trace::CallSet calls(trace::FREQUENCY_ALL);

static const char *synopsis = "Dump given trace(s) to standard output.";

static void
usage(void)
{
    std::cout
        << "usage: apitrace dump [OPTIONS] TRACE_FILE...\n"
        << synopsis << "\n"
        "\n"
        "    -h, --help           show this help message and exit\n"
        "    -v, --verbose        verbose output\n"
        "    --calls=CALLSET      only dump specified calls\n"
        "    --color[=WHEN]\n"
        "    --colour[=WHEN]      colored syntax highlighting\n"
        "                         WHEN is 'auto', 'always', or 'never'\n"
        "    --thread-ids=[=BOOL] dump thread ids [default: no]\n"
        "    --call-nos[=BOOL]    dump call numbers[default: yes]\n"
        "    --arg-names[=BOOL]   dump argument names [default: yes]\n"
        "\n"
    ;
}

enum {
	CALLS_OPT = CHAR_MAX + 1,
	COLOR_OPT,
    THREAD_IDS_OPT,
    CALL_NOS_OPT,
    ARG_NAMES_OPT,
};

const static char *
shortOptions = "hv";

const static struct option
longOptions[] = {
    {"help", no_argument, 0, 'h'},
    {"verbose", no_argument, 0, 'v'},
    {"calls", required_argument, 0, CALLS_OPT},
    {"colour", optional_argument, 0, COLOR_OPT},
    {"color", optional_argument, 0, COLOR_OPT},
    {"thread-ids", optional_argument, 0, THREAD_IDS_OPT},
    {"call-nos", optional_argument, 0, CALL_NOS_OPT},
    {"arg-names", optional_argument, 0, ARG_NAMES_OPT},
    {0, 0, 0, 0}
};

static bool
boolOption(const char *option, bool default_ = true) {
    if (!option) {
        return default_;
    }
    if (strcmp(option, "0") == 0 ||
        strcmp(option, "no") == 0 ||
        strcmp(option, "false") == 0) {
        return false;
    }
    if (strcmp(option, "0") == 0 ||
        strcmp(option, "yes") == 0 ||
        strcmp(option, "true") == 0) {
        return true;
    }
    std::cerr << "error: unexpected bool " << option << "\n";
    return default_;
}

static int
command(int argc, char *argv[])
{
    trace::DumpFlags dumpFlags = 0;
    bool dumpThreadIds = false;

    int opt;
    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case 'v':
            verbose = true;
            break;
        case CALLS_OPT:
            calls = trace::CallSet(optarg);
            break;
        case COLOR_OPT:
            if (!optarg ||
                !strcmp(optarg, "always")) {
                color = COLOR_OPTION_ALWAYS;
            } else if (!strcmp(optarg, "auto")) {
                color = COLOR_OPTION_AUTO;
            } else if (!strcmp(optarg, "never")) {
                color = COLOR_OPTION_NEVER;
            } else {
                std::cerr << "error: unknown color argument " << optarg << "\n";
                return 1;
            }
            break;
        case THREAD_IDS_OPT:
            dumpThreadIds = boolOption(optarg);
            break;
        case CALL_NOS_OPT:
            if (boolOption(optarg)) {
                dumpFlags &= ~trace::DUMP_FLAG_NO_CALL_NO;
            } else {
                dumpFlags |= trace::DUMP_FLAG_NO_CALL_NO;
            }
            break;
        case ARG_NAMES_OPT:
            if (boolOption(optarg)) {
                dumpFlags &= ~trace::DUMP_FLAG_NO_ARG_NAMES;
            } else {
                dumpFlags |= trace::DUMP_FLAG_NO_ARG_NAMES;
            }
            break;
        default:
            std::cerr << "error: unexpected option `" << opt << "`\n";
            usage();
            return 1;
        }
    }

    if (color == COLOR_OPTION_AUTO) {
#ifdef _WIN32
        color = COLOR_OPTION_ALWAYS;
#else
        color = isatty(1) ? COLOR_OPTION_ALWAYS : COLOR_OPTION_NEVER;
        pipepager();
#endif
    }

    if (color == COLOR_OPTION_NEVER) {
        dumpFlags |= trace::DUMP_FLAG_NO_COLOR;
    }

    for (int i = optind; i < argc; ++i) {
        trace::Parser p;

        if (!p.open(argv[i])) {
            std::cerr << "error: failed to open " << argv[i] << "\n";
            return 1;
        }

        trace::Call *call;
        while ((call = p.parse_call())) {
            if (calls.contains(*call)) {
                if (verbose ||
                    !(call->flags & trace::CALL_FLAG_VERBOSE)) {
                    if (dumpThreadIds) {
                        std::cout << std::hex << call->thread_id << std::dec << " ";
                    }
                    trace::dump(*call, std::cout, dumpFlags);
                }
            }
            delete call;
        }
    }

    return 0;
}

const Command dump_command = {
    "dump",
    synopsis,
    usage,
    command
};
<commit_msg>Fix compile error "isatty was not declared"; missing unistd.h include<commit_after>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * Copyright 2010 VMware, Inc.
 * All Rights Reserved.
 *
 * 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 <string.h>
#include <limits.h> // for CHAR_MAX
#include <getopt.h>
#ifndef _WIN32
#include <unistd.h> // for isatty()
#endif

#include "cli.hpp"
#include "cli_pager.hpp"

#include "trace_parser.hpp"
#include "trace_dump.hpp"
#include "trace_callset.hpp"

enum ColorOption {
    COLOR_OPTION_NEVER = 0,
    COLOR_OPTION_ALWAYS = 1,
    COLOR_OPTION_AUTO = -1
};

static ColorOption color = COLOR_OPTION_AUTO;

static bool verbose = false;

static trace::CallSet calls(trace::FREQUENCY_ALL);

static const char *synopsis = "Dump given trace(s) to standard output.";

static void
usage(void)
{
    std::cout
        << "usage: apitrace dump [OPTIONS] TRACE_FILE...\n"
        << synopsis << "\n"
        "\n"
        "    -h, --help           show this help message and exit\n"
        "    -v, --verbose        verbose output\n"
        "    --calls=CALLSET      only dump specified calls\n"
        "    --color[=WHEN]\n"
        "    --colour[=WHEN]      colored syntax highlighting\n"
        "                         WHEN is 'auto', 'always', or 'never'\n"
        "    --thread-ids=[=BOOL] dump thread ids [default: no]\n"
        "    --call-nos[=BOOL]    dump call numbers[default: yes]\n"
        "    --arg-names[=BOOL]   dump argument names [default: yes]\n"
        "\n"
    ;
}

enum {
	CALLS_OPT = CHAR_MAX + 1,
	COLOR_OPT,
    THREAD_IDS_OPT,
    CALL_NOS_OPT,
    ARG_NAMES_OPT,
};

const static char *
shortOptions = "hv";

const static struct option
longOptions[] = {
    {"help", no_argument, 0, 'h'},
    {"verbose", no_argument, 0, 'v'},
    {"calls", required_argument, 0, CALLS_OPT},
    {"colour", optional_argument, 0, COLOR_OPT},
    {"color", optional_argument, 0, COLOR_OPT},
    {"thread-ids", optional_argument, 0, THREAD_IDS_OPT},
    {"call-nos", optional_argument, 0, CALL_NOS_OPT},
    {"arg-names", optional_argument, 0, ARG_NAMES_OPT},
    {0, 0, 0, 0}
};

static bool
boolOption(const char *option, bool default_ = true) {
    if (!option) {
        return default_;
    }
    if (strcmp(option, "0") == 0 ||
        strcmp(option, "no") == 0 ||
        strcmp(option, "false") == 0) {
        return false;
    }
    if (strcmp(option, "0") == 0 ||
        strcmp(option, "yes") == 0 ||
        strcmp(option, "true") == 0) {
        return true;
    }
    std::cerr << "error: unexpected bool " << option << "\n";
    return default_;
}

static int
command(int argc, char *argv[])
{
    trace::DumpFlags dumpFlags = 0;
    bool dumpThreadIds = false;

    int opt;
    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case 'v':
            verbose = true;
            break;
        case CALLS_OPT:
            calls = trace::CallSet(optarg);
            break;
        case COLOR_OPT:
            if (!optarg ||
                !strcmp(optarg, "always")) {
                color = COLOR_OPTION_ALWAYS;
            } else if (!strcmp(optarg, "auto")) {
                color = COLOR_OPTION_AUTO;
            } else if (!strcmp(optarg, "never")) {
                color = COLOR_OPTION_NEVER;
            } else {
                std::cerr << "error: unknown color argument " << optarg << "\n";
                return 1;
            }
            break;
        case THREAD_IDS_OPT:
            dumpThreadIds = boolOption(optarg);
            break;
        case CALL_NOS_OPT:
            if (boolOption(optarg)) {
                dumpFlags &= ~trace::DUMP_FLAG_NO_CALL_NO;
            } else {
                dumpFlags |= trace::DUMP_FLAG_NO_CALL_NO;
            }
            break;
        case ARG_NAMES_OPT:
            if (boolOption(optarg)) {
                dumpFlags &= ~trace::DUMP_FLAG_NO_ARG_NAMES;
            } else {
                dumpFlags |= trace::DUMP_FLAG_NO_ARG_NAMES;
            }
            break;
        default:
            std::cerr << "error: unexpected option `" << opt << "`\n";
            usage();
            return 1;
        }
    }

    if (color == COLOR_OPTION_AUTO) {
#ifdef _WIN32
        color = COLOR_OPTION_ALWAYS;
#else
        color = isatty(1) ? COLOR_OPTION_ALWAYS : COLOR_OPTION_NEVER;
        pipepager();
#endif
    }

    if (color == COLOR_OPTION_NEVER) {
        dumpFlags |= trace::DUMP_FLAG_NO_COLOR;
    }

    for (int i = optind; i < argc; ++i) {
        trace::Parser p;

        if (!p.open(argv[i])) {
            std::cerr << "error: failed to open " << argv[i] << "\n";
            return 1;
        }

        trace::Call *call;
        while ((call = p.parse_call())) {
            if (calls.contains(*call)) {
                if (verbose ||
                    !(call->flags & trace::CALL_FLAG_VERBOSE)) {
                    if (dumpThreadIds) {
                        std::cout << std::hex << call->thread_id << std::dec << " ";
                    }
                    trace::dump(*call, std::cout, dumpFlags);
                }
            }
            delete call;
        }
    }

    return 0;
}

const Command dump_command = {
    "dump",
    synopsis,
    usage,
    command
};
<|endoftext|>


<commit_before>#include "perf_precomp.hpp"

#ifdef HAVE_TBB
#include "tbb/task_scheduler_init.h"
#endif

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP)

typedef std::tr1::tuple<int, pnpAlgo> PointsNum_Algo_t;
typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;

typedef perf::TestBaseWithParam<int> PointsNum;

PERF_TEST_P(PointsNum_Algo, solvePnP,
            testing::Combine(
                testing::Values(4, 3*9, 7*13), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_UPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-4);
    SANITY_CHECK(tvec, 1e-4);
}

PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints,
            testing::Combine(
                testing::Values(4), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_DLS)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-4);
    SANITY_CHECK(tvec, 1e-2);
}

PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(4, 3*9, 7*13))
{
    int count = GetParam();

    Mat object(1, count, CV_32FC3);
    randu(object, -100, 100);

    Mat camera_mat(3, 3, CV_32FC1);
    randu(camera_mat, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));

    vector<cv::Point2f> image_vec;

    Mat rvec_gold(1, 3, CV_32FC1);
    randu(rvec_gold, 0, 1);

    Mat tvec_gold(1, 3, CV_32FC1);
    randu(tvec_gold, 0, 1);
    projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec);

    Mat image(1, count, CV_32FC2, &image_vec[0]);

    Mat rvec;
    Mat tvec;

#ifdef HAVE_TBB
    // limit concurrency to get deterministic result
    tbb::task_scheduler_init one_thread(1);
#endif

    TEST_CYCLE()
    {
        solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}
<commit_msg>Updating sanity check<commit_after>#include "perf_precomp.hpp"

#ifdef HAVE_TBB
#include "tbb/task_scheduler_init.h"
#endif

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP)

typedef std::tr1::tuple<int, pnpAlgo> PointsNum_Algo_t;
typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;

typedef perf::TestBaseWithParam<int> PointsNum;

PERF_TEST_P(PointsNum_Algo, solvePnP,
            testing::Combine(
                testing::Values(4, 3*9, 7*13), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}

PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints,
            testing::Combine(
                testing::Values(4), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_DLS, (int)SOLVEPNP_UPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-4);
    SANITY_CHECK(tvec, 1e-2);
}

PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(4, 3*9, 7*13))
{
    int count = GetParam();

    Mat object(1, count, CV_32FC3);
    randu(object, -100, 100);

    Mat camera_mat(3, 3, CV_32FC1);
    randu(camera_mat, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));

    vector<cv::Point2f> image_vec;

    Mat rvec_gold(1, 3, CV_32FC1);
    randu(rvec_gold, 0, 1);

    Mat tvec_gold(1, 3, CV_32FC1);
    randu(tvec_gold, 0, 1);
    projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec);

    Mat image(1, count, CV_32FC2, &image_vec[0]);

    Mat rvec;
    Mat tvec;

#ifdef HAVE_TBB
    // limit concurrency to get deterministic result
    tbb::task_scheduler_init one_thread(1);
#endif

    TEST_CYCLE()
    {
        solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}
<|endoftext|>


<commit_before>#include "perf_precomp.hpp"

#ifdef HAVE_TBB
#include "tbb/task_scheduler_init.h"
#endif

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP)

typedef std::tr1::tuple<int, pnpAlgo> PointsNum_Algo_t;
typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;

typedef perf::TestBaseWithParam<int> PointsNum;

PERF_TEST_P(PointsNum_Algo, solvePnP,
            testing::Combine(
                testing::Values(5, 3*9, 7*13), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_UPNP, (int)SOLVEPNP_DLS)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}

PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints,
            testing::Combine(
                testing::Values(5),
                testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_DLS, (int)SOLVEPNP_UPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());
    if( algo == SOLVEPNP_P3P )
        pointsNum = 4;

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0f;
    intrinsics.at<float> (1, 1) = 400.0f;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, -0.001, 0.001);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-1);
    SANITY_CHECK(tvec, 1e-2);
}

PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(5, 3*9, 7*13))
{
    int count = GetParam();

    Mat object(1, count, CV_32FC3);
    randu(object, -100, 100);

    Mat camera_mat(3, 3, CV_32FC1);
    randu(camera_mat, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));

    vector<cv::Point2f> image_vec;

    Mat rvec_gold(1, 3, CV_32FC1);
    randu(rvec_gold, 0, 1);

    Mat tvec_gold(1, 3, CV_32FC1);
    randu(tvec_gold, 0, 1);
    projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec);

    Mat image(1, count, CV_32FC2, &image_vec[0]);

    Mat rvec;
    Mat tvec;

#ifdef HAVE_TBB
    // limit concurrency to get deterministic result
    tbb::task_scheduler_init one_thread(1);
#endif

    TEST_CYCLE()
    {
        solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}
<commit_msg>calib3d: normalize Rodrigues vector in perf test<commit_after>#include "perf_precomp.hpp"

#ifdef HAVE_TBB
#include "tbb/task_scheduler_init.h"
#endif

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP)

typedef std::tr1::tuple<int, pnpAlgo> PointsNum_Algo_t;
typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;

typedef perf::TestBaseWithParam<int> PointsNum;

PERF_TEST_P(PointsNum_Algo, solvePnP,
            testing::Combine(
                testing::Values(5, 3*9, 7*13), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_UPNP, (int)SOLVEPNP_DLS)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}

PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints,
            testing::Combine(
                testing::Values(5),
                testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_EPNP, (int)SOLVEPNP_DLS, (int)SOLVEPNP_UPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());
    if( algo == SOLVEPNP_P3P )
        pointsNum = 4;

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0f;
    intrinsics.at<float> (1, 1) = 400.0f;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    // normalize Rodrigues vector
    Mat rvec_tmp = Mat::eye(3, 3, CV_32F);
    Rodrigues(rvec, rvec_tmp);
    Rodrigues(rvec_tmp, rvec);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, -0.001, 0.001);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-1);
    SANITY_CHECK(tvec, 1e-2);
}

PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(5, 3*9, 7*13))
{
    int count = GetParam();

    Mat object(1, count, CV_32FC3);
    randu(object, -100, 100);

    Mat camera_mat(3, 3, CV_32FC1);
    randu(camera_mat, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));

    vector<cv::Point2f> image_vec;

    Mat rvec_gold(1, 3, CV_32FC1);
    randu(rvec_gold, 0, 1);

    Mat tvec_gold(1, 3, CV_32FC1);
    randu(tvec_gold, 0, 1);
    projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec);

    Mat image(1, count, CV_32FC2, &image_vec[0]);

    Mat rvec;
    Mat tvec;

#ifdef HAVE_TBB
    // limit concurrency to get deterministic result
    tbb::task_scheduler_init one_thread(1);
#endif

    TEST_CYCLE()
    {
        solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 - 2014 Jolla Ltd.
** Contact: http://jolla.com/
**
** This file is part of Qt Creator.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Digia.
**
****************************************************************************/

#include "merrunconfigurationfactory.h"

#include "merconstants.h"
#include "merdevicefactory.h"
#include "merrunconfiguration.h"

#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
#include <qmakeprojectmanager/qmakeproject.h>
#include <utils/qtcassert.h>

using namespace Mer::Constants;

namespace Mer {
namespace Internal {

namespace {
QString stringFromId(Core::Id id)
{
    const QString idStr = id.toString();
    if (idStr.startsWith(QLatin1String(MER_RUNCONFIGURATION_PREFIX)))
        return idStr.mid(QString::fromLatin1(MER_RUNCONFIGURATION_PREFIX).size());

    return QString();
}
} // Anonymous

MerRunConfigurationFactory::MerRunConfigurationFactory(QObject *parent)
    : ProjectExplorer::IRunConfigurationFactory(parent)
{
}

QList<Core::Id> MerRunConfigurationFactory::availableCreationIds(
        ProjectExplorer::Target *parent, CreationMode mode) const
{
    Q_UNUSED(mode);

    QList<Core::Id>result;
    if (!canHandle(parent))
        return result;

    QmakeProjectManager::QmakeProject *qmakeProject =
            qobject_cast<QmakeProjectManager::QmakeProject *>(parent->project());
    if (!qmakeProject)
        return result;

    const Core::Id base = Core::Id(MER_RUNCONFIGURATION_PREFIX);
    foreach (const ProjectExplorer::BuildTargetInfo &bti, parent->applicationTargets().list)
        result << base.withSuffix(bti.targetName);

    return result;
}

QString MerRunConfigurationFactory::displayNameForId(Core::Id id) const
{
    if (id.toString().startsWith(QLatin1String(MER_RUNCONFIGURATION_PREFIX)))
        return tr("%1 (on Mer Device)").arg(stringFromId(id));

    return QString();
}

bool MerRunConfigurationFactory::canCreate(ProjectExplorer::Target *parent, Core::Id id) const
{
    if (!canHandle(parent))
        return false;

    return parent->applicationTargets().hasTarget(stringFromId(id));
}

ProjectExplorer::RunConfiguration *MerRunConfigurationFactory::doCreate(
        ProjectExplorer::Target *parent, Core::Id id)
{
    if (!canCreate(parent, id))
        return 0;

    if (id.toString().startsWith(QLatin1String(MER_RUNCONFIGURATION_PREFIX))) {
        MerRunConfiguration *config = new MerRunConfiguration(parent, id, stringFromId(id));
        config->setDefaultDisplayName(displayNameForId(id));
        return config;
    }

    return 0;
}

bool MerRunConfigurationFactory::canRestore(ProjectExplorer::Target *parent,
                                            const QVariantMap &map) const
{
    if (!canHandle(parent))
        return false;

    return ProjectExplorer::idFromMap(map).toString().startsWith(
                QLatin1String(MER_RUNCONFIGURATION_PREFIX));
}

ProjectExplorer::RunConfiguration *MerRunConfigurationFactory::doRestore(
        ProjectExplorer::Target *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;

    Core::Id id = ProjectExplorer::idFromMap(map);
    ProjectExplorer::RunConfiguration *rc = new MerRunConfiguration(parent, id, stringFromId(id));
    QTC_ASSERT(rc, return 0);
    if (rc->fromMap(map))
        return rc;

    delete rc;
    return 0;
}

bool MerRunConfigurationFactory::canClone(ProjectExplorer::Target *parent,
                                          ProjectExplorer::RunConfiguration *source) const
{
    return canCreate(parent, source->id());
}

ProjectExplorer::RunConfiguration *MerRunConfigurationFactory::clone(
        ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *source)
{
    if (!canClone(parent, source))
        return 0;

    MerRunConfiguration *old = qobject_cast<MerRunConfiguration *>(source);

    if (!old)
        return 0;

    return new MerRunConfiguration(parent, old);
}

bool MerRunConfigurationFactory::canHandle(ProjectExplorer::Target *t) const
{
    return MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(t->kit()));
}

} // Internal
} // Mer
<commit_msg>Mer: Simplify stringFromId by using Core::Id::suffixAfter<commit_after>/****************************************************************************
**
** Copyright (C) 2012 - 2014 Jolla Ltd.
** Contact: http://jolla.com/
**
** This file is part of Qt Creator.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Digia.
**
****************************************************************************/

#include "merrunconfigurationfactory.h"

#include "merconstants.h"
#include "merdevicefactory.h"
#include "merrunconfiguration.h"

#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
#include <qmakeprojectmanager/qmakeproject.h>
#include <utils/qtcassert.h>

using namespace Mer::Constants;

namespace Mer {
namespace Internal {

namespace {
QString stringFromId(Core::Id id)
{
    return id.suffixAfter(MER_RUNCONFIGURATION_PREFIX);
}
} // Anonymous

MerRunConfigurationFactory::MerRunConfigurationFactory(QObject *parent)
    : ProjectExplorer::IRunConfigurationFactory(parent)
{
}

QList<Core::Id> MerRunConfigurationFactory::availableCreationIds(
        ProjectExplorer::Target *parent, CreationMode mode) const
{
    Q_UNUSED(mode);

    QList<Core::Id>result;
    if (!canHandle(parent))
        return result;

    QmakeProjectManager::QmakeProject *qmakeProject =
            qobject_cast<QmakeProjectManager::QmakeProject *>(parent->project());
    if (!qmakeProject)
        return result;

    const Core::Id base = Core::Id(MER_RUNCONFIGURATION_PREFIX);
    foreach (const ProjectExplorer::BuildTargetInfo &bti, parent->applicationTargets().list)
        result << base.withSuffix(bti.targetName);

    return result;
}

QString MerRunConfigurationFactory::displayNameForId(Core::Id id) const
{
    if (id.toString().startsWith(QLatin1String(MER_RUNCONFIGURATION_PREFIX)))
        return tr("%1 (on Mer Device)").arg(stringFromId(id));

    return QString();
}

bool MerRunConfigurationFactory::canCreate(ProjectExplorer::Target *parent, Core::Id id) const
{
    if (!canHandle(parent))
        return false;

    return parent->applicationTargets().hasTarget(stringFromId(id));
}

ProjectExplorer::RunConfiguration *MerRunConfigurationFactory::doCreate(
        ProjectExplorer::Target *parent, Core::Id id)
{
    if (!canCreate(parent, id))
        return 0;

    if (id.toString().startsWith(QLatin1String(MER_RUNCONFIGURATION_PREFIX))) {
        MerRunConfiguration *config = new MerRunConfiguration(parent, id, stringFromId(id));
        config->setDefaultDisplayName(displayNameForId(id));
        return config;
    }

    return 0;
}

bool MerRunConfigurationFactory::canRestore(ProjectExplorer::Target *parent,
                                            const QVariantMap &map) const
{
    if (!canHandle(parent))
        return false;

    return ProjectExplorer::idFromMap(map).toString().startsWith(
                QLatin1String(MER_RUNCONFIGURATION_PREFIX));
}

ProjectExplorer::RunConfiguration *MerRunConfigurationFactory::doRestore(
        ProjectExplorer::Target *parent, const QVariantMap &map)
{
    if (!canRestore(parent, map))
        return 0;

    Core::Id id = ProjectExplorer::idFromMap(map);
    ProjectExplorer::RunConfiguration *rc = new MerRunConfiguration(parent, id, stringFromId(id));
    QTC_ASSERT(rc, return 0);
    if (rc->fromMap(map))
        return rc;

    delete rc;
    return 0;
}

bool MerRunConfigurationFactory::canClone(ProjectExplorer::Target *parent,
                                          ProjectExplorer::RunConfiguration *source) const
{
    return canCreate(parent, source->id());
}

ProjectExplorer::RunConfiguration *MerRunConfigurationFactory::clone(
        ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *source)
{
    if (!canClone(parent, source))
        return 0;

    MerRunConfiguration *old = qobject_cast<MerRunConfiguration *>(source);

    if (!old)
        return 0;

    return new MerRunConfiguration(parent, old);
}

bool MerRunConfigurationFactory::canHandle(ProjectExplorer::Target *t) const
{
    return MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(t->kit()));
}

} // Internal
} // Mer
<|endoftext|>


<commit_before>#include "perf_precomp.hpp"

#ifdef HAVE_TBB
#include "tbb/task_scheduler_init.h"
#endif

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP)

typedef std::tr1::tuple<int, pnpAlgo> PointsNum_Algo_t;
typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;

typedef perf::TestBaseWithParam<int> PointsNum;

PERF_TEST_P(PointsNum_Algo, solvePnP,
            testing::Combine(
                testing::Values(4, 3*9, 7*13), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}

PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints,
            testing::Combine(
                testing::Values(4), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_DLS, (int)SOLVEPNP_UPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-1);
    SANITY_CHECK(tvec, 1e-2);
}

PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(4, 3*9, 7*13))
{
    int count = GetParam();

    Mat object(1, count, CV_32FC3);
    randu(object, -100, 100);

    Mat camera_mat(3, 3, CV_32FC1);
    randu(camera_mat, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));

    vector<cv::Point2f> image_vec;

    Mat rvec_gold(1, 3, CV_32FC1);
    randu(rvec_gold, 0, 1);

    Mat tvec_gold(1, 3, CV_32FC1);
    randu(tvec_gold, 0, 1);
    projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec);

    Mat image(1, count, CV_32FC2, &image_vec[0]);

    Mat rvec;
    Mat tvec;

#ifdef HAVE_TBB
    // limit concurrency to get deterministic result
    tbb::task_scheduler_init one_thread(1);
#endif

    TEST_CYCLE()
    {
        solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}
<commit_msg>this is trivial change; the main change is in opencv_extra - added regression data for perf tests<commit_after>#include "perf_precomp.hpp"

#ifdef HAVE_TBB
#include "tbb/task_scheduler_init.h"
#endif

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

CV_ENUM(pnpAlgo, SOLVEPNP_ITERATIVE, SOLVEPNP_EPNP, SOLVEPNP_P3P, SOLVEPNP_DLS, SOLVEPNP_UPNP)

typedef std::tr1::tuple<int, pnpAlgo> PointsNum_Algo_t;
typedef perf::TestBaseWithParam<PointsNum_Algo_t> PointsNum_Algo;

typedef perf::TestBaseWithParam<int> PointsNum;

PERF_TEST_P(PointsNum_Algo, solvePnP,
            testing::Combine(
                testing::Values(4, 3*9, 7*13), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_ITERATIVE, (int)SOLVEPNP_EPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0;
    intrinsics.at<float> (1, 1) = 400.0;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}

PERF_TEST_P(PointsNum_Algo, solvePnPSmallPoints,
            testing::Combine(
                testing::Values(4), //TODO: find why results on 4 points are too unstable
                testing::Values((int)SOLVEPNP_P3P, (int)SOLVEPNP_DLS, (int)SOLVEPNP_UPNP)
                )
            )
{
    int pointsNum = get<0>(GetParam());
    pnpAlgo algo = get<1>(GetParam());

    vector<Point2f> points2d(pointsNum);
    vector<Point3f> points3d(pointsNum);
    Mat rvec = Mat::zeros(3, 1, CV_32FC1);
    Mat tvec = Mat::zeros(3, 1, CV_32FC1);

    Mat distortion = Mat::zeros(5, 1, CV_32FC1);
    Mat intrinsics = Mat::eye(3, 3, CV_32FC1);
    intrinsics.at<float> (0, 0) = 400.0f;
    intrinsics.at<float> (1, 1) = 400.0f;
    intrinsics.at<float> (0, 2) = 640 / 2;
    intrinsics.at<float> (1, 2) = 480 / 2;

    warmup(points3d, WARMUP_RNG);
    warmup(rvec, WARMUP_RNG);
    warmup(tvec, WARMUP_RNG);

    projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d);

    //add noise
    Mat noise(1, (int)points2d.size(), CV_32FC2);
    randu(noise, 0, 0.01);
    add(points2d, noise, points2d);

    declare.in(points3d, points2d);
    declare.time(100);

    TEST_CYCLE_N(1000)
    {
        solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo);
    }

    SANITY_CHECK(rvec, 1e-1);
    SANITY_CHECK(tvec, 1e-2);
}

PERF_TEST_P(PointsNum, DISABLED_SolvePnPRansac, testing::Values(4, 3*9, 7*13))
{
    int count = GetParam();

    Mat object(1, count, CV_32FC3);
    randu(object, -100, 100);

    Mat camera_mat(3, 3, CV_32FC1);
    randu(camera_mat, 0.5, 1);
    camera_mat.at<float>(0, 1) = 0.f;
    camera_mat.at<float>(1, 0) = 0.f;
    camera_mat.at<float>(2, 0) = 0.f;
    camera_mat.at<float>(2, 1) = 0.f;

    Mat dist_coef(1, 8, CV_32F, cv::Scalar::all(0));

    vector<cv::Point2f> image_vec;

    Mat rvec_gold(1, 3, CV_32FC1);
    randu(rvec_gold, 0, 1);

    Mat tvec_gold(1, 3, CV_32FC1);
    randu(tvec_gold, 0, 1);
    projectPoints(object, rvec_gold, tvec_gold, camera_mat, dist_coef, image_vec);

    Mat image(1, count, CV_32FC2, &image_vec[0]);

    Mat rvec;
    Mat tvec;

#ifdef HAVE_TBB
    // limit concurrency to get deterministic result
    tbb::task_scheduler_init one_thread(1);
#endif

    TEST_CYCLE()
    {
        solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec);
    }

    SANITY_CHECK(rvec, 1e-6);
    SANITY_CHECK(tvec, 1e-6);
}
<|endoftext|>


<commit_before>#include "FloatEditor.hpp"

#include <exception>

using namespace GUI;

FloatEditor::FloatEditor(Widget* parent, Font* font) : TextField(parent, font) {
    variable = nullptr;
}

void FloatEditor::SetFloat(float* variable) {
    this->variable = variable;

    SetText(std::to_string(*variable));
}

void FloatEditor::TextUpdated() {
    float oldValue = *variable;
    try {
        *variable = std::stof(GetText());
    } catch (std::exception& e) {
        *variable = oldValue;
    }
}
<commit_msg>Removed unnecessary code.<commit_after>#include "FloatEditor.hpp"

#include <exception>

using namespace GUI;

FloatEditor::FloatEditor(Widget* parent, Font* font) : TextField(parent, font) {
    variable = nullptr;
}

void FloatEditor::SetFloat(float* variable) {
    this->variable = variable;

    SetText(std::to_string(*variable));
}

void FloatEditor::TextUpdated() {
    try {
        *variable = std::stof(GetText());
    } catch (std::exception& e) { }
}
<|endoftext|>


<commit_before>#pragma once

#include "KEngine/Interface/IEventManagerImpl.hpp"

#include <deque>
#include <unordered_map>
#include <vector>

namespace ke::priv
{

    class EventManagerImpl : public ke::priv::IEventManagerImpl
    {
    public:
        virtual ~EventManagerImpl();

        virtual bool registerListener(const ke::EventType p_EventType, const ke::EventDelegate & p_Delegate) final;

        virtual bool deregisterAllListeners(const ke::EventType p_EventType) final;

        virtual bool deregisterListener(const ke::EventType p_EventType, const ke::EventDelegate & p_EventDelegate) final;

        virtual void queue(ke::EventSptr p_spNewEvent) final;

        virtual bool dispatchNow(ke::EventSptr p_Event) final;

        virtual bool removeEvent(const ke::EventType p_EventType, const bool p_RemoveAllSame = false) final;

        virtual ke::EventProcessResult update(const ke::Time p_DurationLimit = ke::Time::Zero) final;

    public:
        using DelegateType      = ke::EventDelegate;
        using ListenerList      = std::vector<DelegateType>;
        using EventListenersMap = std::unordered_map<ke::EventType, ListenerList>;
        using EventQueue        = std::deque<ke::EventSptr>;

    private:
        ke::EventQueue              m_ThreadSafeEventQueue;
        EventQueue                  m_EventQueue;
        EventListenersMap           m_Listeners;

    };

}
<commit_msg>change argument name<commit_after>#pragma once

#include "KEngine/Interface/IEventManagerImpl.hpp"

#include <deque>
#include <unordered_map>
#include <vector>

namespace ke::priv
{

    class EventManagerImpl : public ke::priv::IEventManagerImpl
    {
    public:
        virtual ~EventManagerImpl();

        virtual bool registerListener(const ke::EventType p_EventType, const ke::EventDelegate & p_Delegate) final;

        virtual bool deregisterAllListeners(const ke::EventType p_EventType) final;

        virtual bool deregisterListener(const ke::EventType p_EventType, const ke::EventDelegate & p_Delegate) final;

        virtual void queue(ke::EventSptr p_spNewEvent) final;

        virtual bool dispatchNow(ke::EventSptr p_Event) final;

        virtual bool removeEvent(const ke::EventType p_EventType, const bool p_RemoveAllSame = false) final;

        virtual ke::EventProcessResult update(const ke::Time p_DurationLimit = ke::Time::Zero) final;

    public:
        using DelegateType      = ke::EventDelegate;
        using ListenerList      = std::vector<DelegateType>;
        using EventListenersMap = std::unordered_map<ke::EventType, ListenerList>;
        using EventQueue        = std::deque<ke::EventSptr>;

    private:
        ke::EventQueue              m_ThreadSafeEventQueue;
        EventQueue                  m_EventQueue;
        EventListenersMap           m_Listeners;

    };

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 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 COPYRIGHT
 * HOLDER 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 "TreentSample.h"
#include "TreentNode.h"
#include "cinder/gl/gl.h"

#include "treent/LayeredShapeRenderSystem.h"
#include "treent/TextRenderSystem.h"
#include "treent/ShapeComponent.h"
#include "cinder/Rand.h"

#include <memory>

#define USE_SMOOTHED_ROTATION 1

using namespace pockets;
using namespace cinder;
using namespace cinder::app;
using namespace std;

namespace
{

struct RotationComponent : treent::Component<RotationComponent>
{
  RotationComponent() = default;
  RotationComponent( float rate ):
  rate( rate )
  {}

  float  rate = 1.0f;
};

class RotationSystem : public treent::System<RotationSystem>
{
public:
  void update( treent::EntityManagerRef entities, treent::EventManagerRef events, double dt ) override
  {
    for( auto entity : entities->entities_with_components<RotationComponent, treent::LocationComponent>() )
    {
      treent::LocationComponentRef  location;
      shared_ptr<RotationComponent> rotation;
      entity.unpack( location, rotation );
#if USE_SMOOTHED_ROTATION
      // lerp(curr, target, 1.0-pow(1.0-rate, targetFPS*dt)
      // smoothed step
      float target = location->rotation + rotation->rate / 60.0;
      location->rotation = lerp<float>( location->rotation, target, 1.0 - pow(0.01, 60.0 * dt) );
#else
      location->rotation += rotation->rate * dt;
#endif
    }
  }
};

treent::TreentNodeRef addOrbiter( treent::TreentNodeRef center, bool warm, float max_distance, int depth ) {

  float size = center->getSize().length() / 5.0f;
  auto moon = center->createChild<treent::TreentNode>();
  moon->setSize( vec2( 1.0f ) * size );

  vec2 position = randVec2f() * randFloat( max_distance / 4, max_distance );
  moon->setPosition( position );
  moon->setRegistrationPoint( -position );
  auto shape = moon->assign<treent::ShapeComponent>();
  auto color = warm ? ColorA( CM_HSV, randFloat( 0.02f, 0.18f ), 1.0f, 1.0f, 1.0f ) : ColorA( CM_HSV, randFloat( 0.45f, 0.62f ), 1.0f, 0.7f, 1.0f );

  shape->setAsBox( Rectf( -size, -size, size, size ) );
  shape->setColor( color );
  moon->assign<treent::LayeredShapeRenderData>( shape, moon->getTransform(), depth );
  moon->assign<RotationComponent>( lmap<float>( length( position ), 0.0f, length( vec2(getWindowSize()) ), 1.0f, 0.1f ) );

  if( size > 10.0f && randFloat() < 0.5f ) {
    addOrbiter( moon, !warm, max_distance / 8, depth + 1 );
  }

  return moon;
}

} // anon::

void TreentTest::setup()
{
  _treent.systems->add<treent::LayeredShapeRenderSystem>();
  _treent.systems->add<treent::TextRenderSystem>();
  _treent.systems->add<RotationSystem>();
  _treent.systems->configure();

  _treent_root = _treent.createRoot2D();
  _treent_root->setPosition( getWindowCenter() );
  _treent_root->setSize( getWindowSize() / 4 );
  auto shape = _treent_root->assign<treent::ShapeComponent>();
  shape->setAsCircle( vec2( 1.0f ) * (getWindowWidth() / 6.0f), 0, M_PI * 2, 6 );  // hexagon
  _treent_root->assign<treent::LayeredShapeRenderData>( shape, _treent_root->getTransform(), 0 );

  Font arial( "Arial Bold", 24.0f );
  gl::TextureFontRef font = gl::TextureFont::create( arial, gl::TextureFont::Format().premultiply() );

  for( int i = 0; i < 1000; ++i )
  {
    auto moon = addOrbiter( _treent_root, true, getWindowSize().length(), 0 );
    if( randFloat() < 0.05f ) {
      moon->assign<treent::TextComponent>( font, "I am planet " + to_string( i ) );
    }
  }
}

void TreentTest::connect( app::WindowRef window )
{
  storeConnection( window->getSignalMouseDown().connect( [this]( const MouseEvent &e )
    { mouseDown( e ); } ) );
  storeConnection( window->getSignalMouseDrag().connect( [this]( const MouseEvent &e )
                                                        { mouseDrag( e ); } ) );
  storeConnection( window->getSignalMouseUp().connect( [this]( const MouseEvent &e )
                                                        { mouseUp( e ); } ) );
}

void TreentTest::mouseDown( MouseEvent event )
{
  _mouse_down = true;
  _mouse_position = event.getPos();
  _mouse_start = event.getPos();
  _node_start = _treent_root->getPosition();
}

void TreentTest::mouseDrag( MouseEvent event )
{
  _mouse_position = event.getPos();
}

void TreentTest::mouseUp( MouseEvent event )
{
  _mouse_down = false;
  _mouse_position = event.getPos();
}

void TreentTest::update( double dt )
{
  auto delta = _mouse_position - _mouse_start;
  _treent_root->setPosition( _node_start + delta );

  _treent.systems->update<RotationSystem>( dt );
  _treent_root->updateTree( mat4() );
  _treent.systems->update<treent::LayeredShapeRenderSystem>( dt );
  _treent.systems->update<treent::TextRenderSystem>( dt );
}

void TreentTest::draw()
{
  // clear out the window with black
	gl::clear( Color( 0, 0, 0 ) );

  _treent.systems->system<treent::LayeredShapeRenderSystem>()->draw();

  gl::ScopedAlphaBlend premult( true );
  _treent.systems->system<treent::TextRenderSystem>()->draw();

}

<commit_msg>.length -> length( prop )<commit_after>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 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 COPYRIGHT
 * HOLDER 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 "TreentSample.h"
#include "TreentNode.h"
#include "cinder/gl/gl.h"

#include "treent/LayeredShapeRenderSystem.h"
#include "treent/TextRenderSystem.h"
#include "treent/ShapeComponent.h"
#include "cinder/Rand.h"

#include <memory>

#define USE_SMOOTHED_ROTATION 1

using namespace pockets;
using namespace cinder;
using namespace cinder::app;
using namespace std;

namespace
{

struct RotationComponent : treent::Component<RotationComponent>
{
  RotationComponent() = default;
  RotationComponent( float rate ):
  rate( rate )
  {}

  float  rate = 1.0f;
};

class RotationSystem : public treent::System<RotationSystem>
{
public:
  void update( treent::EntityManagerRef entities, treent::EventManagerRef events, double dt ) override
  {
    for( auto entity : entities->entities_with_components<RotationComponent, treent::LocationComponent>() )
    {
      treent::LocationComponentRef  location;
      shared_ptr<RotationComponent> rotation;
      entity.unpack( location, rotation );
#if USE_SMOOTHED_ROTATION
      // lerp(curr, target, 1.0-pow(1.0-rate, targetFPS*dt)
      // smoothed step
      float target = location->rotation + rotation->rate / 60.0;
      location->rotation = lerp<float>( location->rotation, target, 1.0 - pow(0.01, 60.0 * dt) );
#else
      location->rotation += rotation->rate * dt;
#endif
    }
  }
};

treent::TreentNodeRef addOrbiter( treent::TreentNodeRef center, bool warm, float max_distance, int depth ) {

  float size = length( center->getSize() ) / 5.0f;
  auto moon = center->createChild<treent::TreentNode>();
  moon->setSize( vec2( 1.0f ) * size );

  vec2 position = randVec2f() * randFloat( max_distance / 4, max_distance );
  moon->setPosition( position );
  moon->setRegistrationPoint( -position );
  auto shape = moon->assign<treent::ShapeComponent>();
  auto color = warm ? ColorA( CM_HSV, randFloat( 0.02f, 0.18f ), 1.0f, 1.0f, 1.0f ) : ColorA( CM_HSV, randFloat( 0.45f, 0.62f ), 1.0f, 0.7f, 1.0f );

  shape->setAsBox( Rectf( -size, -size, size, size ) );
  shape->setColor( color );
  moon->assign<treent::LayeredShapeRenderData>( shape, moon->getTransform(), depth );
  moon->assign<RotationComponent>( lmap<float>( length( position ), 0.0f, length( vec2(getWindowSize()) ), 1.0f, 0.1f ) );

  if( size > 10.0f && randFloat() < 0.5f ) {
    addOrbiter( moon, !warm, max_distance / 8, depth + 1 );
  }

  return moon;
}

} // anon::

void TreentTest::setup()
{
  _treent.systems->add<treent::LayeredShapeRenderSystem>();
  _treent.systems->add<treent::TextRenderSystem>();
  _treent.systems->add<RotationSystem>();
  _treent.systems->configure();

  _treent_root = _treent.createRoot2D();
  _treent_root->setPosition( getWindowCenter() );
  _treent_root->setSize( getWindowSize() / 4 );
  auto shape = _treent_root->assign<treent::ShapeComponent>();
  shape->setAsCircle( vec2( 1.0f ) * (getWindowWidth() / 6.0f), 0, M_PI * 2, 6 );  // hexagon
  _treent_root->assign<treent::LayeredShapeRenderData>( shape, _treent_root->getTransform(), 0 );

  Font arial( "Arial Bold", 24.0f );
  gl::TextureFontRef font = gl::TextureFont::create( arial, gl::TextureFont::Format().premultiply() );

  for( int i = 0; i < 1000; ++i )
  {
    auto moon = addOrbiter( _treent_root, true, length( vec2( getWindowSize() ) ), 0 );
    if( randFloat() < 0.05f ) {
      moon->assign<treent::TextComponent>( font, "I am planet " + to_string( i ) );
    }
  }
}

void TreentTest::connect( app::WindowRef window )
{
  storeConnection( window->getSignalMouseDown().connect( [this]( const MouseEvent &e )
    { mouseDown( e ); } ) );
  storeConnection( window->getSignalMouseDrag().connect( [this]( const MouseEvent &e )
                                                        { mouseDrag( e ); } ) );
  storeConnection( window->getSignalMouseUp().connect( [this]( const MouseEvent &e )
                                                        { mouseUp( e ); } ) );
}

void TreentTest::mouseDown( MouseEvent event )
{
  _mouse_down = true;
  _mouse_position = event.getPos();
  _mouse_start = event.getPos();
  _node_start = _treent_root->getPosition();
}

void TreentTest::mouseDrag( MouseEvent event )
{
  _mouse_position = event.getPos();
}

void TreentTest::mouseUp( MouseEvent event )
{
  _mouse_down = false;
  _mouse_position = event.getPos();
}

void TreentTest::update( double dt )
{
  auto delta = _mouse_position - _mouse_start;
  _treent_root->setPosition( _node_start + delta );

  _treent.systems->update<RotationSystem>( dt );
  _treent_root->updateTree( mat4() );
  _treent.systems->update<treent::LayeredShapeRenderSystem>( dt );
  _treent.systems->update<treent::TextRenderSystem>( dt );
}

void TreentTest::draw()
{
  // clear out the window with black
	gl::clear( Color( 0, 0, 0 ) );

  _treent.systems->system<treent::LayeredShapeRenderSystem>()->draw();

  gl::ScopedAlphaBlend premult( true );
  _treent.systems->system<treent::TextRenderSystem>()->draw();

}

<|endoftext|>


<commit_before>#include "PendingOperation.hpp"

#include <QLoggingCategory>

namespace Telegram {

PendingOperation::PendingOperation(QObject *parent) :
    QObject(parent),
    m_finished(false),
    m_succeeded(true)
{
}

bool PendingOperation::isFinished() const
{
    return m_finished;
}

bool PendingOperation::isSucceeded() const
{
    return m_finished && m_succeeded;
}

QString PendingOperation::c_text()
{
    return QStringLiteral("text");
}

QVariantHash PendingOperation::errorDetails() const
{
    return m_errorDetails;
}

void PendingOperation::startLater()
{
    QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
}

void PendingOperation::runAfter(PendingOperation *operation)
{
    connect(operation, &PendingOperation::succeeded, this, &PendingOperation::start);
    connect(operation, &PendingOperation::failed, this, &PendingOperation::onPreviousFailed);
    if (operation->isFinished()) {
        if (operation->isSucceeded()) {
            startLater();
        } else {
            setDelayedFinishedWithError(operation->errorDetails());
        }
    }
}

void PendingOperation::setFinished()
{
    qDebug() << "finished" << this;
    if (m_finished) {
        qWarning() << "Operation is already finished" << this;
        return;
    }
    m_finished = true;
    if (m_succeeded) {
        emit succeeded(this);
    }
    emit finished(this);
}

void PendingOperation::setFinishedWithError(const QVariantHash &details)
{
    qDebug() << "finished with error" << this << details;
    m_succeeded = false;
    m_errorDetails = details;
    emit failed(this, details);
    setFinished();
}

void PendingOperation::setDelayedFinishedWithError(const QVariantHash &details)
{
    QMetaObject::invokeMethod(this, "setFinishedWithError", Qt::QueuedConnection, Q_ARG(QVariantHash, details)); // Invoke after return
}

void PendingOperation::clearResult()
{
    m_finished = false;
    m_succeeded = true;
    m_errorDetails.clear();
}

void PendingOperation::onPreviousFailed(PendingOperation *operation, const QVariantHash &details)
{
    Q_UNUSED(operation)
    setFinishedWithError(details);
}

} // Telegram namespace
<commit_msg>PendingOperation: Emit failed() only after operation is marked as finished<commit_after>#include "PendingOperation.hpp"

#include <QLoggingCategory>

namespace Telegram {

PendingOperation::PendingOperation(QObject *parent) :
    QObject(parent),
    m_finished(false),
    m_succeeded(true)
{
}

bool PendingOperation::isFinished() const
{
    return m_finished;
}

bool PendingOperation::isSucceeded() const
{
    return m_finished && m_succeeded;
}

QString PendingOperation::c_text()
{
    return QStringLiteral("text");
}

QVariantHash PendingOperation::errorDetails() const
{
    return m_errorDetails;
}

void PendingOperation::startLater()
{
    QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
}

void PendingOperation::runAfter(PendingOperation *operation)
{
    connect(operation, &PendingOperation::succeeded, this, &PendingOperation::start);
    connect(operation, &PendingOperation::failed, this, &PendingOperation::onPreviousFailed);
    if (operation->isFinished()) {
        if (operation->isSucceeded()) {
            startLater();
        } else {
            setDelayedFinishedWithError(operation->errorDetails());
        }
    }
}

void PendingOperation::setFinished()
{
    qDebug() << "finished" << this;
    if (m_finished) {
        qWarning() << "Operation is already finished" << this;
        return;
    }
    m_finished = true;
    if (m_succeeded) {
        emit succeeded(this);
    } else {
        emit failed(this, m_errorDetails);
    }
    emit finished(this);
}

void PendingOperation::setFinishedWithError(const QVariantHash &details)
{
    qDebug() << "finished with error" << this << details;
    m_succeeded = false;
    m_errorDetails = details;
    setFinished();
}

void PendingOperation::setDelayedFinishedWithError(const QVariantHash &details)
{
    QMetaObject::invokeMethod(this, "setFinishedWithError", Qt::QueuedConnection, Q_ARG(QVariantHash, details)); // Invoke after return
}

void PendingOperation::clearResult()
{
    m_finished = false;
    m_succeeded = true;
    m_errorDetails.clear();
}

void PendingOperation::onPreviousFailed(PendingOperation *operation, const QVariantHash &details)
{
    Q_UNUSED(operation)
    setFinishedWithError(details);
}

} // Telegram namespace
<|endoftext|>


<commit_before>#include <Arduino.h>
#include <MD5Builder.h>

uint8_t hex_char_to_byte(uint8_t c){
    return  (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
            (c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) :
            (c >= '0' &&  c<= '9') ? (c - (uint8_t)'0') : 0;
}

void MD5Builder::begin(void){
    memset(_buf, 0x00, 16);
    MD5Init(&_ctx);
}

void MD5Builder::add(const uint8_t * data, const uint16_t len){
    MD5Update(&_ctx, data, len);
}

void MD5Builder::addHexString(const char * data){
    uint16_t i, len = strlen(data);
    uint8_t * tmp = (uint8_t*)malloc(len/2);
    if(tmp == NULL) {
        return;
    }
    for(i=0; i<len; i+=2) {
        uint8_t high = hex_char_to_byte(data[i]);
        uint8_t low = hex_char_to_byte(data[i+1]);
        tmp[i/2] = (high & 0x0F) << 4 | (low & 0x0F);
    }
    add(tmp, len/2);
    free(tmp);
}

bool MD5Builder::addStream(Stream & stream, const size_t maxLen){
    const int buf_size = 512;
    int maxLengthLeft = maxLen;
    uint8_t * buf = (uint8_t*) malloc(buf_size);

    if(!buf) {
        return false;
    }

    int bytesAvailable = stream.available();
    while((bytesAvailable > 0) && (maxLengthLeft > 0)) {

        // determine number of bytes to read
        int readBytes = bytesAvailable;
        if(readBytes > maxLengthLeft) {
            readBytes = maxLengthLeft ;    // read only until max_len
        }
        if(readBytes > buf_size) {
            readBytes = buf_size;    // not read more the buffer can handle
        }

        // read data and check if we got something
        int numBytesRead = stream.readBytes(buf, readBytes);
        if(numBytesRead< 1) {
            return false;
        }

        // Update MD5 with buffer payload
        MD5Update(&_ctx, buf, numBytesRead);

        yield();      // time for network streams

        // update available number of bytes
        maxLengthLeft -= numBytesRead;
        bytesAvailable = stream.available();
    }
    free(buf);
    return true;
}

void MD5Builder::calculate(void){
    MD5Final(_buf, &_ctx);
}

void MD5Builder::getBytes(uint8_t * output){
    memcpy(output, _buf, 16);
}

void MD5Builder::getChars(char * output){
    for(uint8_t i = 0; i < 16; i++) {
        sprintf(output + (i * 2), "%02x", _buf[i]);
    }
}

String MD5Builder::toString(void){
    char out[33];
    getChars(out);
    return String(out);
}
<commit_msg>Fix for MD5 leak bug, issue #7195 (#7197)<commit_after>#include <Arduino.h>
#include <MD5Builder.h>

uint8_t hex_char_to_byte(uint8_t c){
    return  (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
            (c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) :
            (c >= '0' &&  c<= '9') ? (c - (uint8_t)'0') : 0;
}

void MD5Builder::begin(void){
    memset(_buf, 0x00, 16);
    MD5Init(&_ctx);
}

void MD5Builder::add(const uint8_t * data, const uint16_t len){
    MD5Update(&_ctx, data, len);
}

void MD5Builder::addHexString(const char * data){
    uint16_t i, len = strlen(data);
    uint8_t * tmp = (uint8_t*)malloc(len/2);
    if(tmp == NULL) {
        return;
    }
    for(i=0; i<len; i+=2) {
        uint8_t high = hex_char_to_byte(data[i]);
        uint8_t low = hex_char_to_byte(data[i+1]);
        tmp[i/2] = (high & 0x0F) << 4 | (low & 0x0F);
    }
    add(tmp, len/2);
    free(tmp);
}

bool MD5Builder::addStream(Stream & stream, const size_t maxLen){
    const int buf_size = 512;
    int maxLengthLeft = maxLen;
    uint8_t * buf = (uint8_t*) malloc(buf_size);

    if(!buf) {
        return false;
    }

    int bytesAvailable = stream.available();
    while((bytesAvailable > 0) && (maxLengthLeft > 0)) {

        // determine number of bytes to read
        int readBytes = bytesAvailable;
        if(readBytes > maxLengthLeft) {
            readBytes = maxLengthLeft ;    // read only until max_len
        }
        if(readBytes > buf_size) {
            readBytes = buf_size;    // not read more the buffer can handle
        }

        // read data and check if we got something
        int numBytesRead = stream.readBytes(buf, readBytes);
        if(numBytesRead< 1) {
            free(buf); // release the buffer
            return false;
        }

        // Update MD5 with buffer payload
        MD5Update(&_ctx, buf, numBytesRead);

        yield();      // time for network streams

        // update available number of bytes
        maxLengthLeft -= numBytesRead;
        bytesAvailable = stream.available();
    }
    free(buf);
    return true;
}

void MD5Builder::calculate(void){
    MD5Final(_buf, &_ctx);
}

void MD5Builder::getBytes(uint8_t * output){
    memcpy(output, _buf, 16);
}

void MD5Builder::getChars(char * output){
    for(uint8_t i = 0; i < 16; i++) {
        sprintf(output + (i * 2), "%02x", _buf[i]);
    }
}

String MD5Builder::toString(void){
    char out[33];
    getChars(out);
    return String(out);
}
<|endoftext|>