<commit_before>//example skeleton code
//modified from http://learnopengl.com/

#include "stdafx.h"
#include "CImg.h"

#include "..\glew\glew.h"	// include GL Extension Wrangler
#include "..\glfw\glfw3.h"	// include GLFW helper library
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#include "glm.hpp"
#include "gtc/matrix_transform.hpp"
#include "gtc/type_ptr.hpp"
#include "objloader.hpp"  //include the object loader

using namespace std;

// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;

glm::vec3 camera_position;
glm::vec3 triangle_scale;
glm::mat4 projection_matrix;

// Constant vectors
const glm::vec3 center(0.0f, 0.0f, 0.0f);
const glm::vec3 up(0.0f, 1.0f, 0.0f);
const glm::vec3 eye(0.0f, 0.0f, 3.0f);

// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
	std::cout << key << std::endl;
}

// The MAIN function, from here we start the application and run the game loop
int main()
{
	std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
	// Init GLFW
	glfwInit();
	// Set all the required options for GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	// Create a GLFWwindow object that we can use for GLFW's functions
	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Load one cube", nullptr, nullptr);
	if (window == nullptr)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	// Set the required callback functions
	glfwSetKeyCallback(window, key_callback);

	// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
	glewExperimental = GL_TRUE;
	// Initialize GLEW to setup the OpenGL Function pointers
	if (glewInit() != GLEW_OK)
	{
		std::cout << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	// Define the viewport dimensions
	int width, height;
	glfwGetFramebufferSize(window, &width, &height);

	glViewport(0, 0, width, height);

	projection_matrix = glm::perspective(45.0f, (GLfloat)width / (GLfloat)height, 0.0f, 100.0f);

	// Build and compile our shader program
	// Vertex shader

	// Read the Vertex Shader code from the file
	string vertex_shader_path = "vertex.shader";
	string VertexShaderCode;
	std::ifstream VertexShaderStream(vertex_shader_path, ios::in);

	if (VertexShaderStream.is_open()) {
		string Line = "";
		while (getline(VertexShaderStream, Line))
			VertexShaderCode += "\n" + Line;
		VertexShaderStream.close();
	}
	else {
		printf("Impossible to open %s. Are you in the right directory ?\n", vertex_shader_path.c_str());
		getchar();
		exit(-1);
	}

	// Read the Fragment Shader code from the file
	string fragment_shader_path = "fragment.shader";
	std::string FragmentShaderCode;
	std::ifstream FragmentShaderStream(fragment_shader_path, std::ios::in);

	if (FragmentShaderStream.is_open()) {
		std::string Line = "";
		while (getline(FragmentShaderStream, Line))
			FragmentShaderCode += "\n" + Line;
		FragmentShaderStream.close();
	}
	else {
		printf("Impossible to open %s. Are you in the right directory?\n", fragment_shader_path.c_str());
		getchar();
		exit(-1);
	}

	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	char const * VertexSourcePointer = VertexShaderCode.c_str();
	glShaderSource(vertexShader, 1, &VertexSourcePointer, NULL);
	glCompileShader(vertexShader);
	// Check for compile time errors
	GLint success;
	GLchar infoLog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	// Fragment shader
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	char const * FragmentSourcePointer = FragmentShaderCode.c_str();
	glShaderSource(fragmentShader, 1, &FragmentSourcePointer, NULL);
	glCompileShader(fragmentShader);
	// Check for compile time errors
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	// Link shaders
	GLuint shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	// Check for linking errors
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
	if (!success) {
		glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
	}
	glDeleteShader(vertexShader); //free up memory
	glDeleteShader(fragmentShader);

	glUseProgram(shaderProgram);

	std::vector<glm::vec3> vertices;
	std::vector<glm::vec3> normals;
	std::vector<glm::vec2> UVs;
	loadOBJ("cube.obj", vertices, normals, UVs); //read the vertices from the cube.obj file

	GLuint VAO, VBO,EBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &EBO);
	// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
	GLuint vertices_VBO, normals_VBO;

	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &vertices_VBO);

	// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
	glBindVertexArray(VAO);

	glBindBuffer(GL_ARRAY_BUFFER, vertices_VBO);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices.front(), GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(0);

	glGenBuffers(1, &normals_VBO);
	glBindBuffer(GL_ARRAY_BUFFER, normals_VBO);
	glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals.front(), GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(1);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO

	triangle_scale = glm::vec3(1.0f);

	GLuint projectionLoc = glGetUniformLocation(shaderProgram, "projection_matrix");
	GLuint viewMatrixLoc = glGetUniformLocation(shaderProgram, "view_matrix");
	GLuint transformLoc = glGetUniformLocation(shaderProgram, "model_matrix");

	// Game loop
	while (!glfwWindowShouldClose(window))
	{
		// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
		glfwPollEvents();

		// Render
		// Clear the colorbuffer
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		glm::mat4 view_matrix;
		view_matrix = glm::lookAt(eye, center, up);

		glm::mat4 model_matrix;
		model_matrix = glm::scale(model_matrix, triangle_scale);

		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));
		glUniformMatrix4fv(viewMatrixLoc, 1, GL_FALSE, glm::value_ptr(view_matrix));
		glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection_matrix));

		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, vertices.size());
		glBindVertexArray(0);

		// Swap the screen buffers
		glfwSwapBuffers(window);
	}

	// Terminate GLFW, clearing any resources allocated by GLFW.
	glfwTerminate();
	return 0;
}
<commit_msg>Wrote first line of Cimg code: loading and displaying image<commit_after>//example skeleton code
//modified from http://learnopengl.com/

#include "stdafx.h"
#include "CImg.h"

#include "..\glew\glew.h"	// include GL Extension Wrangler
#include "..\glfw\glfw3.h"	// include GLFW helper library
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#include "glm.hpp"
#include "gtc/matrix_transform.hpp"
#include "gtc/type_ptr.hpp"
#include "objloader.hpp"  //include the object loader

using namespace std;
using namespace cimg_library;

// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;

glm::vec3 camera_position;
glm::vec3 triangle_scale;
glm::mat4 projection_matrix;

// Constant vectors
const glm::vec3 center(0.0f, 0.0f, 0.0f);
const glm::vec3 up(0.0f, 1.0f, 0.0f);
const glm::vec3 eye(0.0f, 0.0f, 3.0f);

// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
	std::cout << key << std::endl;
}

// The MAIN function, from here we start the application and run the game loop
int main()
{
	std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
	// Init GLFW
	glfwInit();
	// Set all the required options for GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	// Create a GLFWwindow object that we can use for GLFW's functions
	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Load one cube", nullptr, nullptr);
	if (window == nullptr)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	// Set the required callback functions
	glfwSetKeyCallback(window, key_callback);

	// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
	glewExperimental = GL_TRUE;
	// Initialize GLEW to setup the OpenGL Function pointers
	if (glewInit() != GLEW_OK)
	{
		std::cout << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	// Define the viewport dimensions
	int width, height;
	glfwGetFramebufferSize(window, &width, &height);

	glViewport(0, 0, width, height);

	projection_matrix = glm::perspective(45.0f, (GLfloat)width / (GLfloat)height, 0.0f, 100.0f);

	// Build and compile our shader program
	// Vertex shader

	// Read the Vertex Shader code from the file
	string vertex_shader_path = "vertex.shader";
	string VertexShaderCode;
	std::ifstream VertexShaderStream(vertex_shader_path, ios::in);

	if (VertexShaderStream.is_open()) {
		string Line = "";
		while (getline(VertexShaderStream, Line))
			VertexShaderCode += "\n" + Line;
		VertexShaderStream.close();
	}
	else {
		printf("Impossible to open %s. Are you in the right directory ?\n", vertex_shader_path.c_str());
		getchar();
		exit(-1);
	}

	// Read the Fragment Shader code from the file
	string fragment_shader_path = "fragment.shader";
	std::string FragmentShaderCode;
	std::ifstream FragmentShaderStream(fragment_shader_path, std::ios::in);

	if (FragmentShaderStream.is_open()) {
		std::string Line = "";
		while (getline(FragmentShaderStream, Line))
			FragmentShaderCode += "\n" + Line;
		FragmentShaderStream.close();
	}
	else {
		printf("Impossible to open %s. Are you in the right directory?\n", fragment_shader_path.c_str());
		getchar();
		exit(-1);
	}

	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	char const * VertexSourcePointer = VertexShaderCode.c_str();
	glShaderSource(vertexShader, 1, &VertexSourcePointer, NULL);
	glCompileShader(vertexShader);
	// Check for compile time errors
	GLint success;
	GLchar infoLog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	// Fragment shader
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	char const * FragmentSourcePointer = FragmentShaderCode.c_str();
	glShaderSource(fragmentShader, 1, &FragmentSourcePointer, NULL);
	glCompileShader(fragmentShader);
	// Check for compile time errors
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	// Link shaders
	GLuint shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	// Check for linking errors
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
	if (!success) {
		glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
	}
	glDeleteShader(vertexShader); //free up memory
	glDeleteShader(fragmentShader);

	glUseProgram(shaderProgram);

	std::vector<glm::vec3> vertices;
	std::vector<glm::vec3> normals;
	std::vector<glm::vec2> UVs;
	loadOBJ("cube.obj", vertices, normals, UVs); //read the vertices from the cube.obj file

	GLuint VAO, VBO,EBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &EBO);
	// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
	GLuint vertices_VBO, normals_VBO;

	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &vertices_VBO);

	// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
	glBindVertexArray(VAO);

	glBindBuffer(GL_ARRAY_BUFFER, vertices_VBO);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices.front(), GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(0);

	glGenBuffers(1, &normals_VBO);
	glBindBuffer(GL_ARRAY_BUFFER, normals_VBO);
	glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals.front(), GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(1);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO

	triangle_scale = glm::vec3(1.0f);

	GLuint projectionLoc = glGetUniformLocation(shaderProgram, "projection_matrix");
	GLuint viewMatrixLoc = glGetUniformLocation(shaderProgram, "view_matrix");
	GLuint transformLoc = glGetUniformLocation(shaderProgram, "model_matrix");

	//CImg stuff
	CImg<unsigned char> image("depth.bmp");
	CImgDisplay main_disp(image, "The image");

	// Game loop
	while (!glfwWindowShouldClose(window))
	{
		// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
		glfwPollEvents();

		// Render
		// Clear the colorbuffer
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		glm::mat4 view_matrix;
		view_matrix = glm::lookAt(eye, center, up);

		glm::mat4 model_matrix;
		model_matrix = glm::scale(model_matrix, triangle_scale);

		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));
		glUniformMatrix4fv(viewMatrixLoc, 1, GL_FALSE, glm::value_ptr(view_matrix));
		glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection_matrix));

		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, vertices.size());
		glBindVertexArray(0);

		// Swap the screen buffers
		glfwSwapBuffers(window);
	}

	// Terminate GLFW, clearing any resources allocated by GLFW.
	glfwTerminate();
	return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2015 Google Inc. All Rights Reserved.

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

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

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

#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/framework/register_types.h"

#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/logging.h"

namespace tensorflow {

bool DeviceType::operator<(const DeviceType& other) const {
  return type_ < other.type_;
}

bool DeviceType::operator==(const DeviceType& other) const {
  return type_ == other.type_;
}

std::ostream& operator<<(std::ostream& os, const DeviceType& d) {
  os << d.type();
  return os;
}

const char* const DEVICE_CPU = "CPU";
const char* const DEVICE_GPU = "GPU";

string DataTypeString(DataType dtype) {
  if (IsRefType(dtype)) {
    DataType non_ref = static_cast<DataType>(dtype - kDataTypeRefOffset);
    return strings::StrCat(DataTypeString(non_ref), "_ref");
  }
  switch (dtype) {
    case DT_INVALID:
      return "INVALID";
    case DT_FLOAT:
      return "float";
    case DT_DOUBLE:
      return "double";
    case DT_INT32:
      return "int32";
    case DT_UINT8:
      return "uint8";
    case DT_UINT16:
      return "uint16";
    case DT_INT16:
      return "int16";
    case DT_INT8:
      return "int8";
    case DT_STRING:
      return "string";
    case DT_COMPLEX64:
      return "complex64";
    case DT_COMPLEX128:
      return "complex128";
    case DT_INT64:
      return "int64";
    case DT_BOOL:
      return "bool";
    case DT_QINT8:
      return "qint8";
    case DT_QUINT8:
      return "quint8";
    case DT_QUINT16:
      return "quint16";
    case DT_QINT16:
      return "qint16";
    case DT_QINT32:
      return "qint32";
    case DT_BFLOAT16:
      return "bfloat16";
    case DT_HALF:
      return "half";
    default:
      LOG(FATAL) << "Unrecognized DataType enum value " << dtype;
      return "";
  }
}

bool DataTypeFromString(StringPiece sp, DataType* dt) {
  if (sp.ends_with("_ref")) {
    sp.remove_suffix(4);
    DataType non_ref;
    if (DataTypeFromString(sp, &non_ref) && !IsRefType(non_ref)) {
      *dt = static_cast<DataType>(non_ref + kDataTypeRefOffset);
      return true;
    } else {
      return false;
    }
  }

  if (sp == "float" || sp == "float32") {
    *dt = DT_FLOAT;
    return true;
  } else if (sp == "double" || sp == "float64") {
    *dt = DT_DOUBLE;
    return true;
  } else if (sp == "int32") {
    *dt = DT_INT32;
    return true;
  } else if (sp == "uint8") {
    *dt = DT_UINT8;
    return true;
  } else if (sp == "uint16") {
    *dt = DT_UINT16;
    return true;
  } else if (sp == "int16") {
    *dt = DT_INT16;
    return true;
  } else if (sp == "int8") {
    *dt = DT_INT8;
    return true;
  } else if (sp == "string") {
    *dt = DT_STRING;
    return true;
  } else if (sp == "complex64") {
    *dt = DT_COMPLEX64;
    return true;
  } else if (sp == "complex128") {
    *dt = DT_COMPLEX128;
    return true;
  } else if (sp == "int64") {
    *dt = DT_INT64;
    return true;
  } else if (sp == "bool") {
    *dt = DT_BOOL;
    return true;
  } else if (sp == "qint8") {
    *dt = DT_QINT8;
    return true;
  } else if (sp == "quint8") {
    *dt = DT_QUINT8;
    return true;
  } else if (sp == "qint16") {
    *dt = DT_QINT16;
    return true;
  } else if (sp == "quint16") {
    *dt = DT_QUINT16;
    return true;
  } else if (sp == "qint32") {
    *dt = DT_QINT32;
    return true;
  } else if (sp == "bfloat16") {
    *dt = DT_BFLOAT16;
    return true;
  } else if (sp == "half" || sp == "float16") {
    *dt = DT_HALF;
    return true;
  }
  return false;
}

string DeviceTypeString(DeviceType device_type) { return device_type.type(); }

string DataTypeSliceString(const DataTypeSlice types) {
  string out;
  for (auto it = types.begin(); it != types.end(); ++it) {
    strings::StrAppend(&out, ((it == types.begin()) ? "" : ", "),
                       DataTypeString(*it));
  }
  return out;
}

DataTypeVector AllTypes() {
  return {DT_FLOAT,   DT_DOUBLE, DT_INT32,  DT_UINT8,     DT_INT16,
          DT_UINT16,  DT_INT8,   DT_STRING, DT_COMPLEX64, DT_COMPLEX128,
          DT_INT64,   DT_BOOL,   DT_QINT8,  DT_QUINT8,    DT_QINT16,
          DT_QUINT16, DT_QINT32, DT_HALF};
}

#if !defined(__ANDROID__)

DataTypeVector RealNumberTypes() {
  return {DT_FLOAT, DT_DOUBLE, DT_INT32,  DT_INT64, DT_UINT8,
          DT_INT16, DT_INT8,   DT_UINT16, DT_HALF};
}

DataTypeVector QuantizedTypes() {
  return {DT_QINT8, DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32};
}

DataTypeVector RealAndQuantizedTypes() {
  return {DT_FLOAT,  DT_DOUBLE,  DT_INT32,  DT_INT64, DT_UINT8,
          DT_UINT16, DT_UINT16,  DT_INT8,   DT_QINT8, DT_QUINT8,
          DT_QINT16, DT_QUINT16, DT_QINT32, DT_HALF};
}

DataTypeVector NumberTypes() {
  return {DT_FLOAT,  DT_DOUBLE, DT_INT64,  DT_INT32,     DT_UINT8,
          DT_UINT16, DT_INT16,  DT_INT8,   DT_COMPLEX64, DT_COMPLEX128,
          DT_QINT8,  DT_QUINT8, DT_QINT32, DT_HALF};
}

#elif defined(__ANDROID_TYPES_FULL__)

DataTypeVector RealNumberTypes() { return {DT_FLOAT, DT_INT32, DT_INT64}; }

DataTypeVector NumberTypes() {
  return {DT_FLOAT, DT_INT32, DT_INT64, DT_QINT8, DT_QUINT8, DT_QINT32};
}

DataTypeVector QuantizedTypes() {
  return {DT_QINT8, DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32};
}

DataTypeVector RealAndQuantizedTypes() {
  return {DT_FLOAT,  DT_INT32,  DT_INT64,   DT_QINT8,
          DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32};
}

#else  // defined(__ANDROID__) && !defined(__ANDROID_TYPES_FULL__)

DataTypeVector RealNumberTypes() { return {DT_FLOAT, DT_INT32}; }

DataTypeVector NumberTypes() {
  return {DT_FLOAT, DT_INT32, DT_QINT8, DT_QUINT8, DT_QINT32};
}

DataTypeVector QuantizedTypes() {
  return {DT_QINT8, DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32};
}

DataTypeVector RealAndQuantizedTypes() {
  return {DT_FLOAT,  DT_INT32,   DT_QINT8, DT_QUINT8,
          DT_QINT16, DT_QUINT16, DT_QINT32};
}

#endif  // defined(__ANDROID__)

// TODO(jeff): Maybe unify this with Tensor::CanUseDMA, or the underlying
// is_simple<T> in tensor.cc (and possible choose a more general name?)
bool DataTypeCanUseMemcpy(DataType dt) {
  switch (dt) {
    case DT_FLOAT:
    case DT_DOUBLE:
    case DT_INT32:
    case DT_UINT8:
    case DT_UINT16:
    case DT_INT16:
    case DT_INT8:
    case DT_COMPLEX64:
    case DT_COMPLEX128:
    case DT_INT64:
    case DT_BOOL:
    case DT_QINT8:
    case DT_QUINT8:
    case DT_QINT16:
    case DT_QUINT16:
    case DT_QINT32:
    case DT_BFLOAT16:
    case DT_HALF:
      return true;
    default:
      return false;
  }
}

bool DataTypeIsQuantized(DataType dt) {
  switch (dt) {
    case DT_QINT8:
    case DT_QUINT8:
    case DT_QINT16:
    case DT_QUINT16:
    case DT_QINT32:
      return true;
    default:
      return false;
  }
}

int DataTypeSize(DataType dt) {
#define CASE(T)                  \
  case DataTypeToEnum<T>::value: \
    return sizeof(T);
  switch (dt) {
    TF_CALL_POD_TYPES(CASE);
    default:
      return 0;
  }
#undef CASE
}

}  // namespace tensorflow
<commit_msg>Fix a case where DT_HALF would not be part of the right type lists for __ANDROID_TYPES_FULL__. Change: 117936401<commit_after>/* Copyright 2015 Google Inc. All Rights Reserved.

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

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

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

#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/framework/register_types.h"

#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/logging.h"

namespace tensorflow {

bool DeviceType::operator<(const DeviceType& other) const {
  return type_ < other.type_;
}

bool DeviceType::operator==(const DeviceType& other) const {
  return type_ == other.type_;
}

std::ostream& operator<<(std::ostream& os, const DeviceType& d) {
  os << d.type();
  return os;
}

const char* const DEVICE_CPU = "CPU";
const char* const DEVICE_GPU = "GPU";

string DataTypeString(DataType dtype) {
  if (IsRefType(dtype)) {
    DataType non_ref = static_cast<DataType>(dtype - kDataTypeRefOffset);
    return strings::StrCat(DataTypeString(non_ref), "_ref");
  }
  switch (dtype) {
    case DT_INVALID:
      return "INVALID";
    case DT_FLOAT:
      return "float";
    case DT_DOUBLE:
      return "double";
    case DT_INT32:
      return "int32";
    case DT_UINT8:
      return "uint8";
    case DT_UINT16:
      return "uint16";
    case DT_INT16:
      return "int16";
    case DT_INT8:
      return "int8";
    case DT_STRING:
      return "string";
    case DT_COMPLEX64:
      return "complex64";
    case DT_COMPLEX128:
      return "complex128";
    case DT_INT64:
      return "int64";
    case DT_BOOL:
      return "bool";
    case DT_QINT8:
      return "qint8";
    case DT_QUINT8:
      return "quint8";
    case DT_QUINT16:
      return "quint16";
    case DT_QINT16:
      return "qint16";
    case DT_QINT32:
      return "qint32";
    case DT_BFLOAT16:
      return "bfloat16";
    case DT_HALF:
      return "half";
    default:
      LOG(FATAL) << "Unrecognized DataType enum value " << dtype;
      return "";
  }
}

bool DataTypeFromString(StringPiece sp, DataType* dt) {
  if (sp.ends_with("_ref")) {
    sp.remove_suffix(4);
    DataType non_ref;
    if (DataTypeFromString(sp, &non_ref) && !IsRefType(non_ref)) {
      *dt = static_cast<DataType>(non_ref + kDataTypeRefOffset);
      return true;
    } else {
      return false;
    }
  }

  if (sp == "float" || sp == "float32") {
    *dt = DT_FLOAT;
    return true;
  } else if (sp == "double" || sp == "float64") {
    *dt = DT_DOUBLE;
    return true;
  } else if (sp == "int32") {
    *dt = DT_INT32;
    return true;
  } else if (sp == "uint8") {
    *dt = DT_UINT8;
    return true;
  } else if (sp == "uint16") {
    *dt = DT_UINT16;
    return true;
  } else if (sp == "int16") {
    *dt = DT_INT16;
    return true;
  } else if (sp == "int8") {
    *dt = DT_INT8;
    return true;
  } else if (sp == "string") {
    *dt = DT_STRING;
    return true;
  } else if (sp == "complex64") {
    *dt = DT_COMPLEX64;
    return true;
  } else if (sp == "complex128") {
    *dt = DT_COMPLEX128;
    return true;
  } else if (sp == "int64") {
    *dt = DT_INT64;
    return true;
  } else if (sp == "bool") {
    *dt = DT_BOOL;
    return true;
  } else if (sp == "qint8") {
    *dt = DT_QINT8;
    return true;
  } else if (sp == "quint8") {
    *dt = DT_QUINT8;
    return true;
  } else if (sp == "qint16") {
    *dt = DT_QINT16;
    return true;
  } else if (sp == "quint16") {
    *dt = DT_QUINT16;
    return true;
  } else if (sp == "qint32") {
    *dt = DT_QINT32;
    return true;
  } else if (sp == "bfloat16") {
    *dt = DT_BFLOAT16;
    return true;
  } else if (sp == "half" || sp == "float16") {
    *dt = DT_HALF;
    return true;
  }
  return false;
}

string DeviceTypeString(DeviceType device_type) { return device_type.type(); }

string DataTypeSliceString(const DataTypeSlice types) {
  string out;
  for (auto it = types.begin(); it != types.end(); ++it) {
    strings::StrAppend(&out, ((it == types.begin()) ? "" : ", "),
                       DataTypeString(*it));
  }
  return out;
}

DataTypeVector AllTypes() {
  return {DT_FLOAT,   DT_DOUBLE, DT_INT32,  DT_UINT8,     DT_INT16,
          DT_UINT16,  DT_INT8,   DT_STRING, DT_COMPLEX64, DT_COMPLEX128,
          DT_INT64,   DT_BOOL,   DT_QINT8,  DT_QUINT8,    DT_QINT16,
          DT_QUINT16, DT_QINT32, DT_HALF};
}

#if !defined(__ANDROID__)

DataTypeVector RealNumberTypes() {
  return {DT_FLOAT, DT_DOUBLE, DT_INT32,  DT_INT64, DT_UINT8,
          DT_INT16, DT_INT8,   DT_UINT16, DT_HALF};
}

DataTypeVector QuantizedTypes() {
  return {DT_QINT8, DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32};
}

DataTypeVector RealAndQuantizedTypes() {
  return {DT_FLOAT,  DT_DOUBLE,  DT_INT32,  DT_INT64, DT_UINT8,
          DT_UINT16, DT_UINT16,  DT_INT8,   DT_QINT8, DT_QUINT8,
          DT_QINT16, DT_QUINT16, DT_QINT32, DT_HALF};
}

DataTypeVector NumberTypes() {
  return {DT_FLOAT,  DT_DOUBLE, DT_INT64,  DT_INT32,     DT_UINT8,
          DT_UINT16, DT_INT16,  DT_INT8,   DT_COMPLEX64, DT_COMPLEX128,
          DT_QINT8,  DT_QUINT8, DT_QINT32, DT_HALF};
}

#elif defined(__ANDROID_TYPES_FULL__)

DataTypeVector RealNumberTypes() { return {DT_FLOAT, DT_INT32, DT_INT64}; }

DataTypeVector NumberTypes() {
  return {DT_FLOAT,  DT_INT32,  DT_INT64, DT_QINT8,
          DT_QUINT8, DT_QINT32, DT_HALF};
}

DataTypeVector QuantizedTypes() {
  return {DT_QINT8, DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32};
}

DataTypeVector RealAndQuantizedTypes() {
  return {DT_FLOAT,  DT_INT32,   DT_INT64,  DT_QINT8, DT_QUINT8,
          DT_QINT16, DT_QUINT16, DT_QINT32, DT_HALF};
}

#else  // defined(__ANDROID__) && !defined(__ANDROID_TYPES_FULL__)

DataTypeVector RealNumberTypes() { return {DT_FLOAT, DT_INT32}; }

DataTypeVector NumberTypes() {
  return {DT_FLOAT, DT_INT32, DT_QINT8, DT_QUINT8, DT_QINT32};
}

DataTypeVector QuantizedTypes() {
  return {DT_QINT8, DT_QUINT8, DT_QINT16, DT_QUINT16, DT_QINT32};
}

DataTypeVector RealAndQuantizedTypes() {
  return {DT_FLOAT,  DT_INT32,   DT_QINT8, DT_QUINT8,
          DT_QINT16, DT_QUINT16, DT_QINT32};
}

#endif  // defined(__ANDROID__)

// TODO(jeff): Maybe unify this with Tensor::CanUseDMA, or the underlying
// is_simple<T> in tensor.cc (and possible choose a more general name?)
bool DataTypeCanUseMemcpy(DataType dt) {
  switch (dt) {
    case DT_FLOAT:
    case DT_DOUBLE:
    case DT_INT32:
    case DT_UINT8:
    case DT_UINT16:
    case DT_INT16:
    case DT_INT8:
    case DT_COMPLEX64:
    case DT_COMPLEX128:
    case DT_INT64:
    case DT_BOOL:
    case DT_QINT8:
    case DT_QUINT8:
    case DT_QINT16:
    case DT_QUINT16:
    case DT_QINT32:
    case DT_BFLOAT16:
    case DT_HALF:
      return true;
    default:
      return false;
  }
}

bool DataTypeIsQuantized(DataType dt) {
  switch (dt) {
    case DT_QINT8:
    case DT_QUINT8:
    case DT_QINT16:
    case DT_QUINT16:
    case DT_QINT32:
      return true;
    default:
      return false;
  }
}

int DataTypeSize(DataType dt) {
#define CASE(T)                  \
  case DataTypeToEnum<T>::value: \
    return sizeof(T);
  switch (dt) {
    TF_CALL_POD_TYPES(CASE);
    default:
      return 0;
  }
#undef CASE
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkProcrustesAlignmentFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Tim Hutton who developed and contributed this class

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkProcrustesAlignmentFilter.h"
#include "vtkObjectFactory.h"
#include "vtkLandmarkTransform.h"
#include "vtkTransformPolyDataFilter.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkProcrustesAlignmentFilter, "1.1");
vtkStandardNewMacro(vtkProcrustesAlignmentFilter);

//----------------------------------------------------------------------------
// protected
vtkProcrustesAlignmentFilter::vtkProcrustesAlignmentFilter()
{
  this->LandmarkTransform = vtkLandmarkTransform::New();
}

//----------------------------------------------------------------------------
// protected
vtkProcrustesAlignmentFilter::~vtkProcrustesAlignmentFilter()
{
  if(this->LandmarkTransform)
    {
    this->LandmarkTransform->Delete();
    }
}

//----------------------------------------------------------------------------
// protected
void vtkProcrustesAlignmentFilter::Execute()
{
  vtkDebugMacro(<<"Execute()");

  if(!this->vtkProcessObject::Inputs)
    {
    vtkErrorMacro(<<"No input!");
    return;
    }

  int i,v;

  const int N_SETS = this->vtkProcessObject::GetNumberOfInputs();

  // copy the inputs across
  // (really actually only the points need to be deep copied since the rest stays the same)
  for(i=0;i<N_SETS;i++)
    {
    this->GetOutput(i)->DeepCopy(this->GetInput(i));
    }

  // the number of points is determined by the first input (they must all be the same)
  const int N_POINTS = this->GetInput(0)->GetNumberOfPoints();

  vtkDebugMacro(<<"N_POINTS is " <<N_POINTS);

  // all the inputs must have the same number of points to consider executing
  for(i=1;i<N_SETS;i++)
    {
    if(this->GetInput(i)->GetNumberOfPoints() != N_POINTS)
      {
      vtkErrorMacro(<<"The inputs have different numbers of points!");
      return;
      }
    }

  vtkPoints *mean_points = vtkPoints::New();
  mean_points->DeepCopy(this->GetInput(0)->GetPoints());
  // we could have just called SetNumberOfPoints here but this way we get a meaningful
  // estimate of the initial difference in the means.

  float point[3],*p;

  this->LandmarkTransform->SetTargetLandmarks(mean_points);

  // compute mean and align all the shapes to it, until convergence
  BOOL converged=false;
  int iterations=0;
  const int MAX_ITERATIONS=5;
  float difference;
  do {

      // compute the average of each point across all the shapes
      difference=0.0F;
      for(v=0;v<N_POINTS;v++)
        {
        point[0]=0.0F;
        point[1]=0.0F;
        point[2]=0.0F;
        for(i=0;i<N_SETS;i++)
          {
          p = this->GetOutput(i)->GetPoint(v);
          point[0]+=p[0];
          point[1]+=p[1];
          point[2]+=p[2];
          }
        point[0]/=(float)N_SETS;
        point[1]/=(float)N_SETS;
        point[2]/=(float)N_SETS;
        p = mean_points->GetPoint(v);
        difference += point[0]-p[0];
        difference += point[1]-p[1];
        difference += point[2]-p[2];
        p[0]=point[0];
        p[1]=point[1];
        p[2]=point[2];
        }

      vtkDebugMacro( << "Difference after " << (iterations+1) << " iteration(s) is: " << difference);

      // align each pointset with the mean
      for(i=0;i<N_SETS;i++) {
        this->LandmarkTransform->SetSourceLandmarks(this->GetOutput(i)->GetPoints());
        this->LandmarkTransform->Update();
        for(v=0;v<N_POINTS;v++) {
          this->LandmarkTransform->InternalTransformPoint(
              this->GetOutput(i)->GetPoint(v),
              this->GetOutput(i)->GetPoint(v));
          }
        }

      // test for convergence
      iterations++;
      if(fabs(difference)<1e-4 || iterations>=MAX_ITERATIONS) {
        converged=true;
        }

      // The convergence test is a simple sum of differences of changing mean.
      // Procrustes shouldn't need more than 2 iterations but with large input sets
      // you can get significant numerical oscillation, so we impose a limit for safety.

  } while(!converged);

  if(iterations>=MAX_ITERATIONS) {
    vtkDebugMacro( << "Procrustes did not converge in  " << MAX_ITERATIONS << " iterations! Objects may not be aligned. Difference = " <<
      difference);
    // we don't throw an Error here since the shapes most probably *are* aligned, but the
    // numerical precision is worse than our convergence test anticipated.
    }
  else {
    vtkDebugMacro( << "Procrustes required " << iterations << " iterations to converge to " <<
      difference);
    }

  // clean up
  mean_points->Delete();
}

//----------------------------------------------------------------------------
// public
void vtkProcrustesAlignmentFilter::SetNumberOfInputs(int n)
{
  this->vtkProcessObject::SetNumberOfInputs(n);
  this->vtkSource::SetNumberOfOutputs(n);

  // initialise the outputs
  for(int i=0;i<n;i++)
    {
    vtkPoints *points = vtkPoints::New();
    vtkPolyData *ps = vtkPolyData::New();
    ps->SetPoints(points);
    points->Delete();
    this->vtkSource::SetNthOutput(i,ps);
    ps->Delete();
    }

  // is this the right thing to be doing here? if we don't initialise the outputs here
  // then the filter crashes but vtkPolyData may not be the type of the inputs
}

//----------------------------------------------------------------------------
// public
void vtkProcrustesAlignmentFilter::SetInput(int idx,vtkPointSet* p)
{
  this->vtkProcessObject::SetNthInput(idx,p);
  // (let vtkProcessObject deal with out of range issues)
}

//----------------------------------------------------------------------------
// protected
vtkPointSet* vtkProcrustesAlignmentFilter::GetInput(int idx)
{
  if(idx<0 || idx>=this->vtkProcessObject::GetNumberOfInputs())
    {
    vtkErrorMacro(<<"Index out of bounds in GetInput!");
    return NULL;
    }

  return static_cast<vtkPointSet*>(this->vtkProcessObject::Inputs[idx]);
}

//----------------------------------------------------------------------------
// public
vtkPointSet* vtkProcrustesAlignmentFilter::GetOutput(int idx)
{
  return static_cast<vtkPointSet*>(this->vtkSource::GetOutput(idx));
  // (let vtkSource deal with out of range issues)
}

//----------------------------------------------------------------------------
// public
void vtkProcrustesAlignmentFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  this->LandmarkTransform->PrintSelf(os,indent);
}

<commit_msg>ERR: Removed use of BOOL, true and false.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkProcrustesAlignmentFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Tim Hutton who developed and contributed this class

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkProcrustesAlignmentFilter.h"
#include "vtkObjectFactory.h"
#include "vtkLandmarkTransform.h"
#include "vtkTransformPolyDataFilter.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkProcrustesAlignmentFilter, "1.2");
vtkStandardNewMacro(vtkProcrustesAlignmentFilter);

//----------------------------------------------------------------------------
// protected
vtkProcrustesAlignmentFilter::vtkProcrustesAlignmentFilter()
{
  this->LandmarkTransform = vtkLandmarkTransform::New();
}

//----------------------------------------------------------------------------
// protected
vtkProcrustesAlignmentFilter::~vtkProcrustesAlignmentFilter()
{
  if(this->LandmarkTransform)
    {
    this->LandmarkTransform->Delete();
    }
}

//----------------------------------------------------------------------------
// protected
void vtkProcrustesAlignmentFilter::Execute()
{
  vtkDebugMacro(<<"Execute()");

  if(!this->vtkProcessObject::Inputs)
    {
    vtkErrorMacro(<<"No input!");
    return;
    }

  int i,v;

  const int N_SETS = this->vtkProcessObject::GetNumberOfInputs();

  // copy the inputs across
  // (really actually only the points need to be deep copied since the rest stays the same)
  for(i=0;i<N_SETS;i++)
    {
    this->GetOutput(i)->DeepCopy(this->GetInput(i));
    }

  // the number of points is determined by the first input (they must all be the same)
  const int N_POINTS = this->GetInput(0)->GetNumberOfPoints();

  vtkDebugMacro(<<"N_POINTS is " <<N_POINTS);

  // all the inputs must have the same number of points to consider executing
  for(i=1;i<N_SETS;i++)
    {
    if(this->GetInput(i)->GetNumberOfPoints() != N_POINTS)
      {
      vtkErrorMacro(<<"The inputs have different numbers of points!");
      return;
      }
    }

  vtkPoints *mean_points = vtkPoints::New();
  mean_points->DeepCopy(this->GetInput(0)->GetPoints());
  // we could have just called SetNumberOfPoints here but this way we get a meaningful
  // estimate of the initial difference in the means.

  float point[3],*p;

  this->LandmarkTransform->SetTargetLandmarks(mean_points);

  // compute mean and align all the shapes to it, until convergence
  int converged=0; // bool converged=false
  int iterations=0;
  const int MAX_ITERATIONS=5;
  float difference;
  do {

      // compute the average of each point across all the shapes
      difference=0.0F;
      for(v=0;v<N_POINTS;v++)
        {
        point[0]=0.0F;
        point[1]=0.0F;
        point[2]=0.0F;
        for(i=0;i<N_SETS;i++)
          {
          p = this->GetOutput(i)->GetPoint(v);
          point[0]+=p[0];
          point[1]+=p[1];
          point[2]+=p[2];
          }
        point[0]/=(float)N_SETS;
        point[1]/=(float)N_SETS;
        point[2]/=(float)N_SETS;
        p = mean_points->GetPoint(v);
        difference += point[0]-p[0];
        difference += point[1]-p[1];
        difference += point[2]-p[2];
        p[0]=point[0];
        p[1]=point[1];
        p[2]=point[2];
        }

      vtkDebugMacro( << "Difference after " << (iterations+1) << " iteration(s) is: " << difference);

      // align each pointset with the mean
      for(i=0;i<N_SETS;i++) {
        this->LandmarkTransform->SetSourceLandmarks(this->GetOutput(i)->GetPoints());
        this->LandmarkTransform->Update();
        for(v=0;v<N_POINTS;v++) {
          this->LandmarkTransform->InternalTransformPoint(
              this->GetOutput(i)->GetPoint(v),
              this->GetOutput(i)->GetPoint(v));
          }
        }

      // test for convergence
      iterations++;
      if(fabs(difference)<1e-4 || iterations>=MAX_ITERATIONS) {
        converged=1; // true
        }

      // The convergence test is a simple sum of differences of changing mean.
      // Procrustes shouldn't need more than 2 iterations but with large input sets
      // you can get significant numerical oscillation, so we impose a limit for safety.

  } while(!converged);

  if(iterations>=MAX_ITERATIONS) {
    vtkDebugMacro( << "Procrustes did not converge in  " << MAX_ITERATIONS << " iterations! Objects may not be aligned. Difference = " <<
      difference);
    // we don't throw an Error here since the shapes most probably *are* aligned, but the
    // numerical precision is worse than our convergence test anticipated.
    }
  else {
    vtkDebugMacro( << "Procrustes required " << iterations << " iterations to converge to " <<
      difference);
    }

  // clean up
  mean_points->Delete();
}

//----------------------------------------------------------------------------
// public
void vtkProcrustesAlignmentFilter::SetNumberOfInputs(int n)
{
  this->vtkProcessObject::SetNumberOfInputs(n);
  this->vtkSource::SetNumberOfOutputs(n);

  // initialise the outputs
  for(int i=0;i<n;i++)
    {
    vtkPoints *points = vtkPoints::New();
    vtkPolyData *ps = vtkPolyData::New();
    ps->SetPoints(points);
    points->Delete();
    this->vtkSource::SetNthOutput(i,ps);
    ps->Delete();
    }

  // is this the right thing to be doing here? if we don't initialise the outputs here
  // then the filter crashes but vtkPolyData may not be the type of the inputs
}

//----------------------------------------------------------------------------
// public
void vtkProcrustesAlignmentFilter::SetInput(int idx,vtkPointSet* p)
{
  this->vtkProcessObject::SetNthInput(idx,p);
  // (let vtkProcessObject deal with out of range issues)
}

//----------------------------------------------------------------------------
// protected
vtkPointSet* vtkProcrustesAlignmentFilter::GetInput(int idx)
{
  if(idx<0 || idx>=this->vtkProcessObject::GetNumberOfInputs())
    {
    vtkErrorMacro(<<"Index out of bounds in GetInput!");
    return NULL;
    }

  return static_cast<vtkPointSet*>(this->vtkProcessObject::Inputs[idx]);
}

//----------------------------------------------------------------------------
// public
vtkPointSet* vtkProcrustesAlignmentFilter::GetOutput(int idx)
{
  return static_cast<vtkPointSet*>(this->vtkSource::GetOutput(idx));
  // (let vtkSource deal with out of range issues)
}

//----------------------------------------------------------------------------
// public
void vtkProcrustesAlignmentFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  this->LandmarkTransform->PrintSelf(os,indent);
}

<|endoftext|>


<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include "src/RSocketServer.h"
#include <folly/io/async/EventBaseManager.h>
#include "src/framing/FrameTransport.h"
#include "src/RSocketErrors.h"
#include "src/RSocketNetworkStats.h"
#include "src/RSocketStats.h"
#include "src/internal/RSocketConnectionManager.h"

namespace rsocket {

RSocketServer::RSocketServer(
    std::unique_ptr<ConnectionAcceptor> connectionAcceptor)
    : duplexConnectionAcceptor_(std::move(connectionAcceptor)),
      setupResumeAcceptors_([]{
        return new rsocket::SetupResumeAcceptor(
            ProtocolVersion::Unknown,
            folly::EventBaseManager::get()->getExistingEventBase());
      }),
      connectionManager_(std::make_unique<RSocketConnectionManager>()) {}

RSocketServer::~RSocketServer() {
  shutdownAndWait();
}

void RSocketServer::shutdownAndWait() {
  if (isShutdown_) {
    return;
  }

  // Will stop forwarding connections from duplexConnectionAcceptor_ to
  // setupResumeAcceptors_
  isShutdown_ = true;

  // Stop accepting new connections.
  if (duplexConnectionAcceptor_) {
    duplexConnectionAcceptor_->stop();
  }

  std::vector<folly::Future<folly::Unit>> closingFutures;
  for (auto& acceptor : setupResumeAcceptors_.accessAllThreads()) {
    // this call will queue up the cleanup on the eventBase
    closingFutures.push_back(acceptor.close());
  }

  folly::collectAll(closingFutures).get();

  connectionManager_.reset(); // will close all existing RSockets and wait

  // All requests are fully finished, worker threads can be safely killed off.
}

void RSocketServer::start(OnRSocketSetup onRSocketSetup) {
  if (started) {
    throw std::runtime_error("RSocketServer::start() already called.");
  }
  started = true;

  LOG(INFO) << "Starting RSocketServer";

  duplexConnectionAcceptor_->start([ this, onRSocketSetup = std::move(onRSocketSetup) ](
      std::unique_ptr<DuplexConnection> connection,
      folly::EventBase & eventBase) {
    acceptConnection(std::move(connection), eventBase, onRSocketSetup);
  }).get(); // block until finished and return or throw
}

void RSocketServer::acceptConnection(
    std::unique_ptr<DuplexConnection> connection,
    folly::EventBase & eventBase,
    OnRSocketSetup onRSocketSetup) {
  CHECK(duplexConnectionAcceptor_); // RSocketServer has to be initialized with the acceptor

  if (isShutdown_) {
    // connection is getting out of scope and terminated
    return;
  }

  auto* acceptor = setupResumeAcceptors_.get();

  VLOG(2) << "Going to accept duplex connection";

  acceptor->accept(
      std::move(connection),
      std::bind(
          &RSocketServer::onRSocketSetup,
          this,
          std::move(onRSocketSetup),
          std::placeholders::_1,
          std::placeholders::_2),
      std::bind(
          &RSocketServer::onRSocketResume,
          this,
          OnRSocketResume(),
          std::placeholders::_1,
          std::placeholders::_2));
}

void RSocketServer::onRSocketSetup(
    OnRSocketSetup onRSocketSetup,
    std::shared_ptr<FrameTransport> frameTransport,
    SetupParameters setupParams) {
  // we don't need to check for isShutdown_ here since all callbacks are
  // processed by this time
  VLOG(1) << "Received new setup payload";

  auto* eventBase = folly::EventBaseManager::get()->getExistingEventBase();
  CHECK(eventBase);

  RSocketSetup setup(std::move(frameTransport), std::move(setupParams), *eventBase, *connectionManager_);
  onRSocketSetup(setup);
}

void RSocketServer::onRSocketResume(
    OnRSocketResume onRSocketResume,
    std::shared_ptr<FrameTransport> frameTransport,
    ResumeParameters setupPayload) {
  // we don't need to check for isShutdown_ here since all callbacks are
  // processed by this time

  CHECK(false) << "not implemented";
}

void RSocketServer::startAndPark(OnRSocketSetup onRSocketSetup) {
  start(std::move(onRSocketSetup));
  waiting_.wait();
}

void RSocketServer::unpark() {
  waiting_.post();
}

} // namespace rsocket
<commit_msg>adding a CHECK to RSocketServer<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include "src/RSocketServer.h"
#include <folly/io/async/EventBaseManager.h>
#include "src/framing/FrameTransport.h"
#include "src/RSocketErrors.h"
#include "src/RSocketNetworkStats.h"
#include "src/RSocketStats.h"
#include "src/internal/RSocketConnectionManager.h"

namespace rsocket {

RSocketServer::RSocketServer(
    std::unique_ptr<ConnectionAcceptor> connectionAcceptor)
    : duplexConnectionAcceptor_(std::move(connectionAcceptor)),
      setupResumeAcceptors_([]{
        return new rsocket::SetupResumeAcceptor(
            ProtocolVersion::Unknown,
            folly::EventBaseManager::get()->getExistingEventBase());
      }),
      connectionManager_(std::make_unique<RSocketConnectionManager>()) {}

RSocketServer::~RSocketServer() {
  shutdownAndWait();
}

void RSocketServer::shutdownAndWait() {
  if (isShutdown_) {
    return;
  }

  // Will stop forwarding connections from duplexConnectionAcceptor_ to
  // setupResumeAcceptors_
  isShutdown_ = true;

  // Stop accepting new connections.
  if (duplexConnectionAcceptor_) {
    duplexConnectionAcceptor_->stop();
  }

  std::vector<folly::Future<folly::Unit>> closingFutures;
  for (auto& acceptor : setupResumeAcceptors_.accessAllThreads()) {
    // this call will queue up the cleanup on the eventBase
    closingFutures.push_back(acceptor.close());
  }

  folly::collectAll(closingFutures).get();

  connectionManager_.reset(); // will close all existing RSockets and wait

  // All requests are fully finished, worker threads can be safely killed off.
}

void RSocketServer::start(OnRSocketSetup onRSocketSetup) {
  CHECK(duplexConnectionAcceptor_); // RSocketServer has to be initialized with the acceptor

  if (started) {
    throw std::runtime_error("RSocketServer::start() already called.");
  }
  started = true;

  LOG(INFO) << "Starting RSocketServer";

  duplexConnectionAcceptor_->start([ this, onRSocketSetup = std::move(onRSocketSetup) ](
      std::unique_ptr<DuplexConnection> connection,
      folly::EventBase & eventBase) {
    acceptConnection(std::move(connection), eventBase, onRSocketSetup);
  }).get(); // block until finished and return or throw
}

void RSocketServer::acceptConnection(
    std::unique_ptr<DuplexConnection> connection,
    folly::EventBase & eventBase,
    OnRSocketSetup onRSocketSetup) {
  if (isShutdown_) {
    // connection is getting out of scope and terminated
    return;
  }

  auto* acceptor = setupResumeAcceptors_.get();

  VLOG(2) << "Going to accept duplex connection";

  acceptor->accept(
      std::move(connection),
      std::bind(
          &RSocketServer::onRSocketSetup,
          this,
          std::move(onRSocketSetup),
          std::placeholders::_1,
          std::placeholders::_2),
      std::bind(
          &RSocketServer::onRSocketResume,
          this,
          OnRSocketResume(),
          std::placeholders::_1,
          std::placeholders::_2));
}

void RSocketServer::onRSocketSetup(
    OnRSocketSetup onRSocketSetup,
    std::shared_ptr<FrameTransport> frameTransport,
    SetupParameters setupParams) {
  // we don't need to check for isShutdown_ here since all callbacks are
  // processed by this time
  VLOG(1) << "Received new setup payload";

  auto* eventBase = folly::EventBaseManager::get()->getExistingEventBase();
  CHECK(eventBase);

  RSocketSetup setup(std::move(frameTransport), std::move(setupParams), *eventBase, *connectionManager_);
  onRSocketSetup(setup);
}

void RSocketServer::onRSocketResume(
    OnRSocketResume onRSocketResume,
    std::shared_ptr<FrameTransport> frameTransport,
    ResumeParameters setupPayload) {
  // we don't need to check for isShutdown_ here since all callbacks are
  // processed by this time

  CHECK(false) << "not implemented";
}

void RSocketServer::startAndPark(OnRSocketSetup onRSocketSetup) {
  start(std::move(onRSocketSetup));
  waiting_.wait();
}

void RSocketServer::unpark() {
  waiting_.post();
}

} // namespace rsocket
<|endoftext|>


<commit_before>/* This file is part of Zanshin Todo.

   Copyright 2008 Kevin Ottens <ervin@kde.org>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "todotreemodel.h"

#include <akonadi/collection.h>
#include <akonadi/item.h>

#include <qmimedata.h>
#include <qstringlist.h>

#include "todoflatmodel.h"

TodoTreeModel::TodoTreeModel(QObject *parent)
    : QAbstractProxyModel(parent)
{
}

TodoTreeModel::~TodoTreeModel()
{

}

QModelIndex TodoTreeModel::index(int row, int column, const QModelIndex &parent) const
{
    if (row < 0 || column < 0
     || row >= rowCount(parent)
     || column >= columnCount(parent)) {
        return QModelIndex();
    }

    Akonadi::Entity::Id parentId = idForIndex(parent);
    Akonadi::Entity::Id id = m_childrenMap[parentId].at(row);

    return createIndex(row, column, (void*)id);
}

QModelIndex TodoTreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid()
     || !m_parentMap.contains(index.internalId())) {
        return QModelIndex();
    }

    Akonadi::Entity::Id id = idForIndex(index);
    Akonadi::Entity::Id parentId = m_parentMap[id];

    if (parentId==-1) {
        return QModelIndex();
    }

    return indexForId(parentId);
}

int TodoTreeModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid()) {
        return m_childrenMap[-1].count();
    } else if (parent.column() == 0) { // Only one set of children per row
        Akonadi::Entity::Id id = idForIndex(parent);
        return m_childrenMap[id].count();
    }

    return 0;
}

int TodoTreeModel::columnCount(const QModelIndex &/*parent*/) const
{
    return TodoFlatModel::LastColumn + 1;
}

QMimeData *TodoTreeModel::mimeData(const QModelIndexList &indexes) const
{
    QModelIndexList sourceIndexes;
    foreach (const QModelIndex &proxyIndex, indexes) {
        sourceIndexes << mapToSource(proxyIndex);
    }

    return flatModel()->mimeData(sourceIndexes);
}

bool TodoTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent)
{
    if (action != Qt::MoveAction)
        return false;

    QStringList list = data->text().split(", ");
    Akonadi::Item item = itemForIndex(parent);
    QModelIndex parentIndex = indexForItem(item, TodoFlatModel::RemoteId);
    QString remoteId = flatModel()->data(parentIndex).toString();
    foreach(const QString id, list) {
        QHash<QString, Akonadi::Entity::Id>::iterator it = m_remoteIdReverseMap.find(id);
        if (it == m_remoteIdReverseMap.end())
            return false;
        Akonadi::Entity::Id akoId = it.value();
        QModelIndex proxyIndex = indexForId(akoId, TodoFlatModel::ParentRemoteId);
        if (!setData(proxyIndex, QVariant(remoteId))) {
            return false;
        }
        m_parentMap[akoId] = item.id();
        Akonadi::Item parentItem = itemForIndex(proxyIndex.parent());
        QList<Akonadi::Entity::Id> childList = m_childrenMap[parentItem.id()];
        childList.removeAll(akoId);

        QList<Akonadi::Entity::Id> newChildList = m_childrenMap[item.id()];
        newChildList << akoId;
        m_childrenMap[item.id()] = newChildList;
    }
    return true;
}

QVariant TodoTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    return flatModel()->headerData(section, orientation, role);
}

QModelIndex TodoTreeModel::mapToSource(const QModelIndex &proxyIndex) const
{
    return flatModel()->indexForItem(Akonadi::Item(proxyIndex.internalId()),
                                     proxyIndex.column());
}

QModelIndex TodoTreeModel::mapFromSource(const QModelIndex &sourceIndex) const
{
    Akonadi::Item item = flatModel()->itemForIndex(sourceIndex);
    return indexForId(item.id(), sourceIndex.column());
}

void TodoTreeModel::setSourceModel(QAbstractItemModel *sourceModel)
{
    if (flatModel()) {
        disconnect(flatModel());
    }

    Q_ASSERT(sourceModel == 0 || qobject_cast<TodoFlatModel*>(sourceModel) != 0);
    QAbstractProxyModel::setSourceModel(sourceModel);

    onSourceInsertRows(QModelIndex(), 0, flatModel()->rowCount() - 1);

    connect(flatModel(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
            this, SLOT(onSourceDataChanged(const QModelIndex&, const QModelIndex&)));
    connect(flatModel(), SIGNAL(rowsInserted(const QModelIndex&, int, int)),
            this, SLOT(onSourceInsertRows(const QModelIndex&, int, int)));
    connect(flatModel(), SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
            this, SLOT(onSourceRemoveRows(const QModelIndex&, int, int)));
    connect(flatModel(), SIGNAL(collectionChanged(const Akonadi::Collection&)),
            this, SLOT(onSourceCollectionChanged(const Akonadi::Collection&)));
}

void TodoTreeModel::onSourceInsertRows(const QModelIndex &/*sourceIndex*/, int begin, int end)
{
    QList<Akonadi::Entity::Id> idToEmit;

    // Storing the akonadi id vs remote id mapping
    for (int i = begin; i <= end; i++) {
        // Retrieve the item from the source model
        Akonadi::Item item = flatModel()->itemForIndex(flatModel()->index(i, 0));
        QString remoteId = flatModel()->data(flatModel()->index(i, TodoFlatModel::RemoteId)).toString();
        m_remoteIdMap[item.id()] = remoteId;
        m_remoteIdReverseMap[remoteId] = item.id();
        idToEmit << item.id();
    }

    // Filling the global tree maps, also store a partial one only for this bunch of updates
    QHash<Akonadi::Entity::Id, QList<Akonadi::Entity::Id> > partialChildrenMap;
    QHash<Akonadi::Entity::Id, Akonadi::Entity::Id> partialParentMap;
    QList<Akonadi::Entity::Id> partialRoots;
    for (int i = end; i >= begin; i--) {
        Akonadi::Item item = flatModel()->itemForIndex(flatModel()->index(i, 0));
        QString parentRemoteId = flatModel()->data(flatModel()->index(i, TodoFlatModel::ParentRemoteId)).toString();
        Akonadi::Entity::Id parentId = -1;
        if (!parentRemoteId.isEmpty()) {
            parentId = m_remoteIdReverseMap[parentRemoteId];
        }
        partialChildrenMap[parentId] << item.id();
        partialParentMap[item.id()] = parentId;
        if (parentId==-1 || !idToEmit.contains(parentId)) {
            partialRoots << item.id();
        }
    }

    // Use the partial map and roots list to emit the insertions in the correct order
    idToEmit = partialRoots;
    while (!idToEmit.isEmpty()) {
        Akonadi::Entity::Id id = idToEmit.takeFirst();
        idToEmit+=partialChildrenMap[id];

        Akonadi::Entity::Id parentId = partialParentMap[id];
        int row = m_childrenMap[parentId].count();
        QModelIndex proxyParentIndex;
        if (parentId!=-1) {
            proxyParentIndex = indexForId(parentId);
        }

        beginInsertRows(proxyParentIndex, row, row);
        m_parentMap[id] = parentId;
        m_childrenMap[parentId] << id;
        endInsertRows();
    }
}

void TodoTreeModel::onSourceRemoveRows(const QModelIndex &/*sourceIndex*/, int begin, int end)
{
    for (int i = begin; i <= end; ++i) {
        QModelIndex sourceIndex = flatModel()->index(i, 0);
        QModelIndex proxyIndex = mapFromSource(sourceIndex);
        Akonadi::Item item = flatModel()->itemForIndex(sourceIndex);
        QString remoteId = flatModel()->data(flatModel()->index(i, TodoFlatModel::RemoteId)).toString();

        QHash<Akonadi::Entity::Id, QList<Akonadi::Entity::Id> >::iterator it = m_childrenMap.find(item.id());
        if (it != m_childrenMap.end()) {
            Akonadi::Entity::Id idKey = it.key();
            QList<Akonadi::Entity::Id> idList = it.value();
            while (!idList.isEmpty()) {
                beginRemoveRows(proxyIndex.child(0, 0), 0, 0);
                Akonadi::Entity::Id id = idList.takeFirst();
                endRemoveRows();

                beginInsertRows(QModelIndex(), 0, 0);
                QList<Akonadi::Entity::Id> idEmpty;
                m_childrenMap[id] = idEmpty;
                endInsertRows();
            }
            m_childrenMap[idKey] = idList;
        }

        beginRemoveRows(proxyIndex.parent(), proxyIndex.row(), proxyIndex.row());

        m_remoteIdMap.remove(item.id());
        m_remoteIdReverseMap.remove(remoteId);

        Akonadi::Entity::Id parent = m_parentMap[item.id()];
        QList<Akonadi::Entity::Id> idList = m_childrenMap[parent];
        idList.removeOne(item.id());
        m_childrenMap[parent] = idList;

        m_childrenMap.remove(item.id());
        m_parentMap.remove(item.id());

        endRemoveRows();
    }
}

void TodoTreeModel::onSourceDataChanged(const QModelIndex &begin, const QModelIndex &end)
{
    for (int row = begin.row(); row <= end.row(); ++row) {
        QModelIndex sourceIndex = flatModel()->index(row, TodoFlatModel::RemoteId);

        QModelIndex proxyIndex = mapFromSource(sourceIndex);
        emit dataChanged(index(proxyIndex.row(), 0, proxyIndex.parent()),
                         index(proxyIndex.row(), TodoFlatModel::LastColumn, proxyIndex.parent()));

        QModelIndex parentRemoteIdIndex = flatModel()->index(row, TodoFlatModel::ParentRemoteId);
        QString parentRemoteId = flatModel()->data(parentRemoteIdIndex).toString();
        Akonadi::Entity::Id newParentId = -1;
        if (!parentRemoteId.isEmpty()) {
            newParentId = m_remoteIdReverseMap[parentRemoteId];
        }

        QString itemRemoteId = flatModel()->data(sourceIndex).toString();
        Akonadi::Entity::Id itemId = -1;
        if (!itemRemoteId.isEmpty()) {
            itemId = m_remoteIdReverseMap[itemRemoteId];
        }

        Akonadi::Entity::Id oldParentId = -1;
        if (m_parentMap.contains(itemId)) {
            oldParentId = m_parentMap[itemId];
        }

        if (oldParentId != newParentId) {
            int oldRow = m_childrenMap[oldParentId].indexOf(itemId);
            beginRemoveRows(indexForId(oldParentId), oldRow, oldRow);
            m_childrenMap[oldParentId].removeAll(itemId);
            m_parentMap.remove(itemId);
            endRemoveRows();

            int newRow = m_childrenMap[newParentId].size();
            beginInsertRows(indexForId(newParentId), newRow, newRow);
            m_childrenMap[newParentId] << itemId;
            m_parentMap[itemId] = newParentId;
            endInsertRows();
        }
    }
}

void TodoTreeModel::onSourceCollectionChanged(const Akonadi::Collection &collection)
{
    m_childrenMap.clear();
    m_parentMap.clear();
    m_remoteIdMap.clear();
    m_remoteIdReverseMap.clear();

    reset();

    emit collectionChanged(collection);
}

Akonadi::Entity::Id TodoTreeModel::idForIndex(const QModelIndex &index) const
{
    return index.isValid() ? index.internalId() : -1;
}

QModelIndex TodoTreeModel::indexForId(Akonadi::Entity::Id id, int column) const
{
    if (id==-1) {
        return QModelIndex();
    }

    Q_ASSERT(m_parentMap.contains(id));
    Akonadi::Entity::Id parentId = m_parentMap[id];
    int row = m_childrenMap[parentId].indexOf(id);
    Q_ASSERT(row>=0);

    return createIndex(row, column, (void*)id);
}

Akonadi::Item TodoTreeModel::itemForIndex(const QModelIndex &index) const
{
    return flatModel()->itemForIndex(mapToSource(index));
}

QModelIndex TodoTreeModel::indexForItem(const Akonadi::Item &item, const int column) const
{
    return mapFromSource(flatModel()->indexForItem(item, column));
}

void TodoTreeModel::setCollection(const Akonadi::Collection &collection)
{
    flatModel()->setCollection(collection);
}

Akonadi::Collection TodoTreeModel::collection() const
{
    return flatModel()->collection();
}

TodoFlatModel *TodoTreeModel::flatModel() const
{
    return qobject_cast<TodoFlatModel*>(sourceModel());
}
<commit_msg>Sorry, really should be updated in reaction of the setData(). Should be the result of the onSourceDataChanged() slot triggered by the TodoFlatModel updating itself because we called setData() on it.<commit_after>/* This file is part of Zanshin Todo.

   Copyright 2008 Kevin Ottens <ervin@kde.org>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "todotreemodel.h"

#include <akonadi/collection.h>
#include <akonadi/item.h>

#include <qmimedata.h>
#include <qstringlist.h>

#include "todoflatmodel.h"

TodoTreeModel::TodoTreeModel(QObject *parent)
    : QAbstractProxyModel(parent)
{
}

TodoTreeModel::~TodoTreeModel()
{

}

QModelIndex TodoTreeModel::index(int row, int column, const QModelIndex &parent) const
{
    if (row < 0 || column < 0
     || row >= rowCount(parent)
     || column >= columnCount(parent)) {
        return QModelIndex();
    }

    Akonadi::Entity::Id parentId = idForIndex(parent);
    Akonadi::Entity::Id id = m_childrenMap[parentId].at(row);

    return createIndex(row, column, (void*)id);
}

QModelIndex TodoTreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid()
     || !m_parentMap.contains(index.internalId())) {
        return QModelIndex();
    }

    Akonadi::Entity::Id id = idForIndex(index);
    Akonadi::Entity::Id parentId = m_parentMap[id];

    if (parentId==-1) {
        return QModelIndex();
    }

    return indexForId(parentId);
}

int TodoTreeModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid()) {
        return m_childrenMap[-1].count();
    } else if (parent.column() == 0) { // Only one set of children per row
        Akonadi::Entity::Id id = idForIndex(parent);
        return m_childrenMap[id].count();
    }

    return 0;
}

int TodoTreeModel::columnCount(const QModelIndex &/*parent*/) const
{
    return TodoFlatModel::LastColumn + 1;
}

QMimeData *TodoTreeModel::mimeData(const QModelIndexList &indexes) const
{
    QModelIndexList sourceIndexes;
    foreach (const QModelIndex &proxyIndex, indexes) {
        sourceIndexes << mapToSource(proxyIndex);
    }

    return flatModel()->mimeData(sourceIndexes);
}

bool TodoTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent)
{
    if (action != Qt::MoveAction)
        return false;

    QStringList list = data->text().split(", ");
    Akonadi::Item item = itemForIndex(parent);
    QModelIndex parentIndex = indexForItem(item, TodoFlatModel::RemoteId);
    QString remoteId = flatModel()->data(parentIndex).toString();
    foreach(const QString id, list) {
        QHash<QString, Akonadi::Entity::Id>::iterator it = m_remoteIdReverseMap.find(id);
        if (it == m_remoteIdReverseMap.end())
            return false;
        Akonadi::Entity::Id akoId = it.value();
        QModelIndex proxyIndex = indexForId(akoId, TodoFlatModel::ParentRemoteId);
        if (!setData(proxyIndex, QVariant(remoteId))) {
            return false;
        }
    }
    return true;
}

QVariant TodoTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    return flatModel()->headerData(section, orientation, role);
}

QModelIndex TodoTreeModel::mapToSource(const QModelIndex &proxyIndex) const
{
    return flatModel()->indexForItem(Akonadi::Item(proxyIndex.internalId()),
                                     proxyIndex.column());
}

QModelIndex TodoTreeModel::mapFromSource(const QModelIndex &sourceIndex) const
{
    Akonadi::Item item = flatModel()->itemForIndex(sourceIndex);
    return indexForId(item.id(), sourceIndex.column());
}

void TodoTreeModel::setSourceModel(QAbstractItemModel *sourceModel)
{
    if (flatModel()) {
        disconnect(flatModel());
    }

    Q_ASSERT(sourceModel == 0 || qobject_cast<TodoFlatModel*>(sourceModel) != 0);
    QAbstractProxyModel::setSourceModel(sourceModel);

    onSourceInsertRows(QModelIndex(), 0, flatModel()->rowCount() - 1);

    connect(flatModel(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
            this, SLOT(onSourceDataChanged(const QModelIndex&, const QModelIndex&)));
    connect(flatModel(), SIGNAL(rowsInserted(const QModelIndex&, int, int)),
            this, SLOT(onSourceInsertRows(const QModelIndex&, int, int)));
    connect(flatModel(), SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
            this, SLOT(onSourceRemoveRows(const QModelIndex&, int, int)));
    connect(flatModel(), SIGNAL(collectionChanged(const Akonadi::Collection&)),
            this, SLOT(onSourceCollectionChanged(const Akonadi::Collection&)));
}

void TodoTreeModel::onSourceInsertRows(const QModelIndex &/*sourceIndex*/, int begin, int end)
{
    QList<Akonadi::Entity::Id> idToEmit;

    // Storing the akonadi id vs remote id mapping
    for (int i = begin; i <= end; i++) {
        // Retrieve the item from the source model
        Akonadi::Item item = flatModel()->itemForIndex(flatModel()->index(i, 0));
        QString remoteId = flatModel()->data(flatModel()->index(i, TodoFlatModel::RemoteId)).toString();
        m_remoteIdMap[item.id()] = remoteId;
        m_remoteIdReverseMap[remoteId] = item.id();
        idToEmit << item.id();
    }

    // Filling the global tree maps, also store a partial one only for this bunch of updates
    QHash<Akonadi::Entity::Id, QList<Akonadi::Entity::Id> > partialChildrenMap;
    QHash<Akonadi::Entity::Id, Akonadi::Entity::Id> partialParentMap;
    QList<Akonadi::Entity::Id> partialRoots;
    for (int i = end; i >= begin; i--) {
        Akonadi::Item item = flatModel()->itemForIndex(flatModel()->index(i, 0));
        QString parentRemoteId = flatModel()->data(flatModel()->index(i, TodoFlatModel::ParentRemoteId)).toString();
        Akonadi::Entity::Id parentId = -1;
        if (!parentRemoteId.isEmpty()) {
            parentId = m_remoteIdReverseMap[parentRemoteId];
        }
        partialChildrenMap[parentId] << item.id();
        partialParentMap[item.id()] = parentId;
        if (parentId==-1 || !idToEmit.contains(parentId)) {
            partialRoots << item.id();
        }
    }

    // Use the partial map and roots list to emit the insertions in the correct order
    idToEmit = partialRoots;
    while (!idToEmit.isEmpty()) {
        Akonadi::Entity::Id id = idToEmit.takeFirst();
        idToEmit+=partialChildrenMap[id];

        Akonadi::Entity::Id parentId = partialParentMap[id];
        int row = m_childrenMap[parentId].count();
        QModelIndex proxyParentIndex;
        if (parentId!=-1) {
            proxyParentIndex = indexForId(parentId);
        }

        beginInsertRows(proxyParentIndex, row, row);
        m_parentMap[id] = parentId;
        m_childrenMap[parentId] << id;
        endInsertRows();
    }
}

void TodoTreeModel::onSourceRemoveRows(const QModelIndex &/*sourceIndex*/, int begin, int end)
{
    for (int i = begin; i <= end; ++i) {
        QModelIndex sourceIndex = flatModel()->index(i, 0);
        QModelIndex proxyIndex = mapFromSource(sourceIndex);
        Akonadi::Item item = flatModel()->itemForIndex(sourceIndex);
        QString remoteId = flatModel()->data(flatModel()->index(i, TodoFlatModel::RemoteId)).toString();

        QHash<Akonadi::Entity::Id, QList<Akonadi::Entity::Id> >::iterator it = m_childrenMap.find(item.id());
        if (it != m_childrenMap.end()) {
            Akonadi::Entity::Id idKey = it.key();
            QList<Akonadi::Entity::Id> idList = it.value();
            while (!idList.isEmpty()) {
                beginRemoveRows(proxyIndex.child(0, 0), 0, 0);
                Akonadi::Entity::Id id = idList.takeFirst();
                endRemoveRows();

                beginInsertRows(QModelIndex(), 0, 0);
                QList<Akonadi::Entity::Id> idEmpty;
                m_childrenMap[id] = idEmpty;
                endInsertRows();
            }
            m_childrenMap[idKey] = idList;
        }

        beginRemoveRows(proxyIndex.parent(), proxyIndex.row(), proxyIndex.row());

        m_remoteIdMap.remove(item.id());
        m_remoteIdReverseMap.remove(remoteId);

        Akonadi::Entity::Id parent = m_parentMap[item.id()];
        QList<Akonadi::Entity::Id> idList = m_childrenMap[parent];
        idList.removeOne(item.id());
        m_childrenMap[parent] = idList;

        m_childrenMap.remove(item.id());
        m_parentMap.remove(item.id());

        endRemoveRows();
    }
}

void TodoTreeModel::onSourceDataChanged(const QModelIndex &begin, const QModelIndex &end)
{
    for (int row = begin.row(); row <= end.row(); ++row) {
        QModelIndex sourceIndex = flatModel()->index(row, TodoFlatModel::RemoteId);

        QModelIndex proxyIndex = mapFromSource(sourceIndex);
        emit dataChanged(index(proxyIndex.row(), 0, proxyIndex.parent()),
                         index(proxyIndex.row(), TodoFlatModel::LastColumn, proxyIndex.parent()));

        QModelIndex parentRemoteIdIndex = flatModel()->index(row, TodoFlatModel::ParentRemoteId);
        QString parentRemoteId = flatModel()->data(parentRemoteIdIndex).toString();
        Akonadi::Entity::Id newParentId = -1;
        if (!parentRemoteId.isEmpty()) {
            newParentId = m_remoteIdReverseMap[parentRemoteId];
        }

        QString itemRemoteId = flatModel()->data(sourceIndex).toString();
        Akonadi::Entity::Id itemId = -1;
        if (!itemRemoteId.isEmpty()) {
            itemId = m_remoteIdReverseMap[itemRemoteId];
        }

        Akonadi::Entity::Id oldParentId = -1;
        if (m_parentMap.contains(itemId)) {
            oldParentId = m_parentMap[itemId];
        }

        if (oldParentId != newParentId) {
            int oldRow = m_childrenMap[oldParentId].indexOf(itemId);
            beginRemoveRows(indexForId(oldParentId), oldRow, oldRow);
            m_childrenMap[oldParentId].removeAll(itemId);
            m_parentMap.remove(itemId);
            endRemoveRows();

            int newRow = m_childrenMap[newParentId].size();
            beginInsertRows(indexForId(newParentId), newRow, newRow);
            m_childrenMap[newParentId] << itemId;
            m_parentMap[itemId] = newParentId;
            endInsertRows();
        }
    }
}

void TodoTreeModel::onSourceCollectionChanged(const Akonadi::Collection &collection)
{
    m_childrenMap.clear();
    m_parentMap.clear();
    m_remoteIdMap.clear();
    m_remoteIdReverseMap.clear();

    reset();

    emit collectionChanged(collection);
}

Akonadi::Entity::Id TodoTreeModel::idForIndex(const QModelIndex &index) const
{
    return index.isValid() ? index.internalId() : -1;
}

QModelIndex TodoTreeModel::indexForId(Akonadi::Entity::Id id, int column) const
{
    if (id==-1) {
        return QModelIndex();
    }

    Q_ASSERT(m_parentMap.contains(id));
    Akonadi::Entity::Id parentId = m_parentMap[id];
    int row = m_childrenMap[parentId].indexOf(id);
    Q_ASSERT(row>=0);

    return createIndex(row, column, (void*)id);
}

Akonadi::Item TodoTreeModel::itemForIndex(const QModelIndex &index) const
{
    return flatModel()->itemForIndex(mapToSource(index));
}

QModelIndex TodoTreeModel::indexForItem(const Akonadi::Item &item, const int column) const
{
    return mapFromSource(flatModel()->indexForItem(item, column));
}

void TodoTreeModel::setCollection(const Akonadi::Collection &collection)
{
    flatModel()->setCollection(collection);
}

Akonadi::Collection TodoTreeModel::collection() const
{
    return flatModel()->collection();
}

TodoFlatModel *TodoTreeModel::flatModel() const
{
    return qobject_cast<TodoFlatModel*>(sourceModel());
}
<|endoftext|>


<commit_before>// Copyright 2013 Velodyne Acoustics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "vvPacketSender.h"
#include "vtkPacketFileReader.h"

#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>

const int HDL_NUM_ROT_ANGLES = 36001;
const int HDL_LASER_PER_FIRING = 32;
const int HDL_MAX_NUM_LASERS = 64;
const int HDL_FIRING_PER_PKT = 12;

enum HDLBlock
{
  BLOCK_0_TO_31 = 0xeeff,
  BLOCK_32_TO_63 = 0xddff
};

#pragma pack(push, 1)
typedef struct HDLLaserReturn
{
  unsigned short distance;
  unsigned char intensity;
} HDLLaserReturn;

struct HDLFiringData
{
  unsigned short blockIdentifier;
  unsigned short rotationalPosition;
  HDLLaserReturn laserReturns[HDL_LASER_PER_FIRING];
};

struct HDLDataPacket
{
  HDLFiringData firingData[HDL_FIRING_PER_PKT];
  unsigned int gpsTimestamp;
  unsigned char blank1;
  unsigned char blank2;
};

struct HDLLaserCorrection
{
  double azimuthCorrection;
  double verticalCorrection;
  double distanceCorrection;
  double verticalOffsetCorrection;
  double horizontalOffsetCorrection;
  double sinVertCorrection;
  double cosVertCorrection;
  double sinVertOffsetCorrection;
  double cosVertOffsetCorrection;
};

struct HDLRGB
{
  uint8_t r;
  uint8_t g;
  uint8_t b;
};
#pragma pack(pop)

//-----------------------------------------------------------------------------
class vvPacketSender::vvInternal
{
public:
  vvInternal(std::string destinationIp,
             int lidarPort,
             int positionPort) :
    LIDARSocket(0),
    PositionSocket(0),
    PacketReader(0),
    Done(false),
    PacketCount(0),
    lastTimestamp(0),
    LIDAREndpoint(boost::asio::ip::address_v4::from_string(destinationIp), lidarPort),
    PositionEndpoint(boost::asio::ip::address_v4::from_string(destinationIp), positionPort)
  {
  }

  boost::asio::ip::udp::socket* LIDARSocket;
  boost::asio::ip::udp::socket* PositionSocket;

  vtkPacketFileReader* PacketReader;
  bool Done;
  unsigned int lastTimestamp;
  size_t PacketCount;
  boost::asio::ip::udp::endpoint LIDAREndpoint;
  boost::asio::ip::udp::endpoint PositionEndpoint;
  boost::asio::io_service IOService;
  };

//-----------------------------------------------------------------------------
vvPacketSender::vvPacketSender(std::string pcapfile,
                               std::string destinationIp,
                               int lidarPort,
                               int positionPort) :
  Internal(new vvPacketSender::vvInternal(destinationIp, lidarPort, positionPort))
{
  this->Internal->PacketReader = new vtkPacketFileReader;
  this->Internal->PacketReader->Open(pcapfile);
  if(!this->Internal->PacketReader->IsOpen())
    {
    throw std::runtime_error("Unable to open packet file");
    }

  this->Internal->LIDARSocket = new boost::asio::ip::udp::socket(this->Internal->IOService);
  this->Internal->LIDARSocket->open(this->Internal->LIDAREndpoint.protocol());

  this->Internal->PositionSocket = new boost::asio::ip::udp::socket(this->Internal->IOService);
  this->Internal->PositionSocket->open(this->Internal->PositionEndpoint.protocol());
}

//-----------------------------------------------------------------------------
vvPacketSender::~vvPacketSender()
{
  delete this->Internal->LIDARSocket;
  delete this->Internal->PositionSocket;
  delete this->Internal;
}

//-----------------------------------------------------------------------------
int vvPacketSender::pumpPacket()
{
  if(this->Internal->Done)
    {
    return std::numeric_limits<double>::max();
    }

  const unsigned char* data = 0;
  unsigned int dataLength = 0;
  double timeSinceStart = 0;
  int timeDiff = 0;
  if (!this->Internal->PacketReader->NextPacket(data, dataLength, timeSinceStart))
    {
    this->Internal->Done = true;
    return timeSinceStart;
    }

  // Recurse until we get to the right kind of packet
  if (dataLength == 1206)
    {
    const HDLDataPacket* dataPacket = reinterpret_cast<const HDLDataPacket *>(data);
    timeDiff = static_cast<int>(dataPacket->gpsTimestamp) - static_cast<int>(this->Internal->lastTimestamp);
    this->Internal->lastTimestamp = dataPacket->gpsTimestamp;
    ++this->Internal->PacketCount;
    size_t bytesSent = this->Internal->LIDARSocket->send_to(boost::asio::buffer(data, dataLength),
                                                            this->Internal->LIDAREndpoint);
    }

  if( (dataLength == 512) )
    {
    size_t bytesSent = this->Internal->PositionSocket->send_to(boost::asio::buffer(data, dataLength),
                                                               this->Internal->PositionEndpoint);
    }

  return timeDiff;
}

//-----------------------------------------------------------------------------
size_t vvPacketSender::packetCount() const
{
  return this->Internal->PacketCount;
}

//-----------------------------------------------------------------------------
bool vvPacketSender::done() const
{
  return this->Internal->Done;
}
<commit_msg>Send all non-position packets as Lidar packets<commit_after>// Copyright 2013 Velodyne Acoustics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "vvPacketSender.h"
#include "vtkPacketFileReader.h"

#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>

const int HDL_NUM_ROT_ANGLES = 36001;
const int HDL_LASER_PER_FIRING = 32;
const int HDL_MAX_NUM_LASERS = 64;
const int HDL_FIRING_PER_PKT = 12;

enum HDLBlock
{
  BLOCK_0_TO_31 = 0xeeff,
  BLOCK_32_TO_63 = 0xddff
};

#pragma pack(push, 1)
typedef struct HDLLaserReturn
{
  unsigned short distance;
  unsigned char intensity;
} HDLLaserReturn;

struct HDLFiringData
{
  unsigned short blockIdentifier;
  unsigned short rotationalPosition;
  HDLLaserReturn laserReturns[HDL_LASER_PER_FIRING];
};

struct HDLDataPacket
{
  HDLFiringData firingData[HDL_FIRING_PER_PKT];
  unsigned int gpsTimestamp;
  unsigned char blank1;
  unsigned char blank2;
};

struct HDLLaserCorrection
{
  double azimuthCorrection;
  double verticalCorrection;
  double distanceCorrection;
  double verticalOffsetCorrection;
  double horizontalOffsetCorrection;
  double sinVertCorrection;
  double cosVertCorrection;
  double sinVertOffsetCorrection;
  double cosVertOffsetCorrection;
};

struct HDLRGB
{
  uint8_t r;
  uint8_t g;
  uint8_t b;
};
#pragma pack(pop)

//-----------------------------------------------------------------------------
class vvPacketSender::vvInternal
{
public:
  vvInternal(std::string destinationIp,
             int lidarPort,
             int positionPort) :
    LIDARSocket(0),
    PositionSocket(0),
    PacketReader(0),
    Done(false),
    PacketCount(0),
    lastTimestamp(0),
    LIDAREndpoint(boost::asio::ip::address_v4::from_string(destinationIp), lidarPort),
    PositionEndpoint(boost::asio::ip::address_v4::from_string(destinationIp), positionPort)
  {
  }

  boost::asio::ip::udp::socket* LIDARSocket;
  boost::asio::ip::udp::socket* PositionSocket;

  vtkPacketFileReader* PacketReader;
  bool Done;
  unsigned int lastTimestamp;
  size_t PacketCount;
  boost::asio::ip::udp::endpoint LIDAREndpoint;
  boost::asio::ip::udp::endpoint PositionEndpoint;
  boost::asio::io_service IOService;
  };

//-----------------------------------------------------------------------------
vvPacketSender::vvPacketSender(std::string pcapfile,
                               std::string destinationIp,
                               int lidarPort,
                               int positionPort) :
  Internal(new vvPacketSender::vvInternal(destinationIp, lidarPort, positionPort))
{
  this->Internal->PacketReader = new vtkPacketFileReader;
  this->Internal->PacketReader->Open(pcapfile);
  if(!this->Internal->PacketReader->IsOpen())
    {
    throw std::runtime_error("Unable to open packet file");
    }

  this->Internal->LIDARSocket = new boost::asio::ip::udp::socket(this->Internal->IOService);
  this->Internal->LIDARSocket->open(this->Internal->LIDAREndpoint.protocol());

  this->Internal->PositionSocket = new boost::asio::ip::udp::socket(this->Internal->IOService);
  this->Internal->PositionSocket->open(this->Internal->PositionEndpoint.protocol());
}

//-----------------------------------------------------------------------------
vvPacketSender::~vvPacketSender()
{
  delete this->Internal->LIDARSocket;
  delete this->Internal->PositionSocket;
  delete this->Internal;
}

//-----------------------------------------------------------------------------
int vvPacketSender::pumpPacket()
{
  if(this->Internal->Done)
    {
    return std::numeric_limits<double>::max();
    }

  const unsigned char* data = 0;
  unsigned int dataLength = 0;
  double timeSinceStart = 0;
  int timeDiff = 0;
  if (!this->Internal->PacketReader->NextPacket(data, dataLength, timeSinceStart))
    {
    this->Internal->Done = true;
    return timeSinceStart;
    }

  if( (dataLength == 512) )
    {
    size_t bytesSent = this->Internal->PositionSocket->send_to(boost::asio::buffer(data, dataLength),
                                                               this->Internal->PositionEndpoint);
    }

  // Recurse until we get to the right kind of packet
  else
  //if (dataLength == 1206)
    {
    const HDLDataPacket* dataPacket = reinterpret_cast<const HDLDataPacket *>(data);
    timeDiff = static_cast<int>(dataPacket->gpsTimestamp) - static_cast<int>(this->Internal->lastTimestamp);
    this->Internal->lastTimestamp = dataPacket->gpsTimestamp;
    ++this->Internal->PacketCount;
    size_t bytesSent = this->Internal->LIDARSocket->send_to(boost::asio::buffer(data, dataLength),
                                                            this->Internal->LIDAREndpoint);
    }

  return timeDiff;
}

//-----------------------------------------------------------------------------
size_t vvPacketSender::packetCount() const
{
  return this->Internal->PacketCount;
}

//-----------------------------------------------------------------------------
bool vvPacketSender::done() const
{
  return this->Internal->Done;
}
<|endoftext|>