<commit_before>/*
Copyright (C) 2016 Jakob Sinclair

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "game.hpp"
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include "entity.hpp"
#include "shader.hpp"
#include "input.hpp"
#include "graphics.hpp"
#include "rect2d.hpp"
#include "camera.hpp"
#include "sprite.hpp"
#include "cache.hpp"
#include "luascript.hpp"
#include "iomanager.hpp"

Game::Game()
{
	;
}

Game::~Game()
{
	;
}

bool Game::Init()
{
	//if (Res.CreateModel("nanosuit", "Model/nanosuit.obj") != nullptr)
	//	m_Model = static_cast<Model*>(Res.GetResource("nanosuit")->Data());

	m_EM.AddEntity<Entity>(std::make_unique<Entity>("Camera"));
	m_EM.GetEntity("Camera").AddComponent<Camera>(std::make_unique<Camera>(1280, 720));

	Res.LoadSample("sound.ogg")->Play();
	m_EM.GetSystem<Graphics>().RegisterComponent(std::type_index(typeid(Sprite)));

	m_EM.AddEntity<Entity>(std::make_unique<Entity>("Player"));
	auto &sprite = m_EM.GetEntity("Player").AddComponent<Sprite>(std::make_unique<Sprite>(Res.LoadTex("sprite.png"),
	                                        110, 200,
	                                        std::vector<uint32_t>({25, 29, 135, 229, 150, 29, 260, 229, 287, 29, 397, 229, 438, 29, 548, 229})));

	LuaScript script("player.lua");
	int posX = script.Get<int>("player.pos.X");
	int posY = script.Get<int>("player.pos.Y");

	sprite.SetImageSpeed(0.1f);
	sprite.SetPos(glm::vec3((float)posX, (float)posY, 0.0f));

	return true;
}

void Game::Update(double delta)
{
	/*
	float speed = 3.0f * (float)delta;
	float xoffset = m_Input.GetMousePos().x - m_LastX;
	float yoffset = m_LastY - m_Input.GetMousePos().y;
	m_LastX = m_Input.GetMousePos().x;
	m_LastY = m_Input.GetMousePos().y;

	float sensitivity = 0.05f;
	xoffset *= sensitivity;
	yoffset *= sensitivity;
	m_Yaw += xoffset;
	m_Pitch +=  yoffset;

	if (m_Pitch > 89.0f)
		m_Pitch = 89.0f;
	else if (m_Pitch < -89.0f)
		m_Pitch = -89.0f;

	glm::vec3 front;
	front.x = cos(glm::radians(m_Pitch)) * cos(glm::radians(m_Yaw));
	front.y = sin(glm::radians(m_Pitch));
	front.z = sin(glm::radians(m_Yaw)) * cos(glm::radians(m_Pitch));
	m_Front = glm::normalize(front);
	*/
	if (m_EM.GetSystem<Input>().GetKey(GLFW_KEY_ESCAPE))
		m_Quit = true;
	else if (m_EM.GetSystem<Input>().GetKey(GLFW_KEY_SPACE))
		Res.LoadSample("sound.ogg")->Play();
	/*if (m_Input.GetKey(GLFW_KEY_W))
		m_Pos += speed * m_Front;
	if (m_Input.GetKey(GLFW_KEY_S))
		m_Pos -= speed * m_Front;
	if (m_Input.GetKey(GLFW_KEY_A))
		m_Pos -= glm::normalize(glm::cross(m_Front, m_Up)) * speed;
	if (m_Input.GetKey(GLFW_KEY_D))
		m_Pos += glm::normalize(glm::cross(m_Front, m_Up)) * speed;
	m_EntityManager.GetCamera()->SetPos(m_Pos);
	m_EntityManager.GetCamera()->SetDir(m_Front);*/
}<commit_msg>Update Copyright year to 2018<commit_after>/*
Copyright (C) 2018 Jakob Sinclair

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "game.hpp"
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include "entity.hpp"
#include "shader.hpp"
#include "input.hpp"
#include "graphics.hpp"
#include "rect2d.hpp"
#include "camera.hpp"
#include "sprite.hpp"
#include "cache.hpp"
#include "luascript.hpp"
#include "iomanager.hpp"

Game::Game()
{
	;
}

Game::~Game()
{
	;
}

bool Game::Init()
{
	//if (Res.CreateModel("nanosuit", "Model/nanosuit.obj") != nullptr)
	//	m_Model = static_cast<Model*>(Res.GetResource("nanosuit")->Data());

	m_EM.AddEntity<Entity>(std::make_unique<Entity>("Camera"));
	m_EM.GetEntity("Camera").AddComponent<Camera>(std::make_unique<Camera>(1280, 720));

	Res.LoadSample("sound.ogg")->Play();
	m_EM.GetSystem<Graphics>().RegisterComponent(std::type_index(typeid(Sprite)));

	m_EM.AddEntity<Entity>(std::make_unique<Entity>("Player"));
	auto &sprite = m_EM.GetEntity("Player").AddComponent<Sprite>(std::make_unique<Sprite>(Res.LoadTex("sprite.png"),
	                                        110, 200,
	                                        std::vector<uint32_t>({25, 29, 135, 229, 150, 29, 260, 229, 287, 29, 397, 229, 438, 29, 548, 229})));

	LuaScript script("player.lua");
	int posX = script.Get<int>("player.pos.X");
	int posY = script.Get<int>("player.pos.Y");

	sprite.SetImageSpeed(0.1f);
	sprite.SetPos(glm::vec3((float)posX, (float)posY, 0.0f));

	return true;
}

void Game::Update(double delta)
{
	/*
	float speed = 3.0f * (float)delta;
	float xoffset = m_Input.GetMousePos().x - m_LastX;
	float yoffset = m_LastY - m_Input.GetMousePos().y;
	m_LastX = m_Input.GetMousePos().x;
	m_LastY = m_Input.GetMousePos().y;

	float sensitivity = 0.05f;
	xoffset *= sensitivity;
	yoffset *= sensitivity;
	m_Yaw += xoffset;
	m_Pitch +=  yoffset;

	if (m_Pitch > 89.0f)
		m_Pitch = 89.0f;
	else if (m_Pitch < -89.0f)
		m_Pitch = -89.0f;

	glm::vec3 front;
	front.x = cos(glm::radians(m_Pitch)) * cos(glm::radians(m_Yaw));
	front.y = sin(glm::radians(m_Pitch));
	front.z = sin(glm::radians(m_Yaw)) * cos(glm::radians(m_Pitch));
	m_Front = glm::normalize(front);
	*/
	if (m_EM.GetSystem<Input>().GetKey(GLFW_KEY_ESCAPE))
		m_Quit = true;
	else if (m_EM.GetSystem<Input>().GetKey(GLFW_KEY_SPACE))
		Res.LoadSample("sound.ogg")->Play();
	/*if (m_Input.GetKey(GLFW_KEY_W))
		m_Pos += speed * m_Front;
	if (m_Input.GetKey(GLFW_KEY_S))
		m_Pos -= speed * m_Front;
	if (m_Input.GetKey(GLFW_KEY_A))
		m_Pos -= glm::normalize(glm::cross(m_Front, m_Up)) * speed;
	if (m_Input.GetKey(GLFW_KEY_D))
		m_Pos += glm::normalize(glm::cross(m_Front, m_Up)) * speed;
	m_EntityManager.GetCamera()->SetPos(m_Pos);
	m_EntityManager.GetCamera()->SetDir(m_Front);*/
}<|endoftext|>


<commit_before>#include "Application.h"
#include <iostream>
#include <sstream>

Application::Application()
{
	window = new ModuleWindow(this);
	input = new ModuleInput(this);
	audio = new ModuleAudio(this, true);
	scene_intro = new ModuleSceneIntro(this);
	renderer3D = new ModuleRenderer3D(this);
	camera = new ModuleCamera3D(this);
	physics = new ModulePhysics3D(this);
	player = new ModulePlayer(this);
	imgui = new ModuleImGui(this);

	// The order of calls is very important!
	// Modules will Init() Start() and Update in this order
	// They will CleanUp() in reverse order

	// Main Modules
	AddModule(window);
	AddModule(camera);
	AddModule(input);
	AddModule(audio);
	AddModule(physics);
	AddModule(imgui);

	// Scenes
	AddModule(scene_intro);
	AddModule(player);

	// Renderer last!
	AddModule(renderer3D);
}

Application::~Application()
{
	for (std::list<Module*>::reverse_iterator rit = list_modules.rbegin(); rit != list_modules.rend(); ++rit)
	{
		if ((*rit) != nullptr)
		delete *rit;
	}

	list_modules.clear();

}

bool Application::Init()
{
	bool ret = true;

	// Call Init() in all modules

	EngineName = "PJ Edu Engine";

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->Init();
		}
	}

	// After all Init calls we call Start() in all modules
	//LOG("Application Start --------------");

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->Start();
		}
	}
	ms_timer.Start();
	return ret;
}

// ---------------------------------------------
void Application::PrepareUpdate()
{
	dt = (float)ms_timer.Read() / 1000.0f;
	ms_timer.Start();
}

// ---------------------------------------------
void Application::FinishUpdate()
{
}

// Call PreUpdate, Update and PostUpdate on all modules
update_status Application::Update()
{
	update_status ret = UPDATE_CONTINUE;
	PrepareUpdate();

	fps_container.push_back(ImGui::GetIO().Framerate);
	if (fps_container.size() > 500) {
		fps_container.erase(fps_container.begin(), fps_container.begin()+1);
	}
	ms_container.push_back(1000.f/ImGui::GetIO().Framerate);
	if (ms_container.size() > 500) {
		ms_container.erase(ms_container.begin(), ms_container.begin() + 1);
	}

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->PreUpdate(dt);
		}
	}

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->Update(dt);
		}
	}

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->PostUpdate(dt);
		}
	}
	FinishUpdate();
	return ret;
}

bool Application::CleanUp()
{
	bool ret = true;
	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->CleanUp();
		}
	}
	return ret;
}

void Application::DrawConfigPanel()
{
	if (ImGui::CollapsingHeader("Application")) {
		ImGui::Text("Framerate");
		fps_title = EngineName +  ':' + std::to_string(ImGui::GetIO().Framerate);
		ImGui::PlotHistogram("Framerate", &fps_container[0], fps_container.size(), 0, fps_title.c_str(), 0.0f, 100.0f, { 500, 100 });
		ImGui::Separator();
		ms_title = EngineName + ':' + std::to_string(1000.f /ImGui::GetIO().Framerate);
		ImGui::PlotHistogram("Miliseconds", &ms_container[0], ms_container.size(), 0, ms_title.c_str(), 0.0f, 40.0f, { 500, 100 });
	}
}

void Application::AddModule(Module* mod)
{
	list_modules.push_back(mod);
}<commit_msg>Solved mem_leaks & deleted ms tracking on app<commit_after>#include "Application.h"
#include <iostream>
#include <sstream>

Application::Application()
{
	window = new ModuleWindow(this);
	input = new ModuleInput(this);
	audio = new ModuleAudio(this, true);
	scene_intro = new ModuleSceneIntro(this);
	renderer3D = new ModuleRenderer3D(this);
	camera = new ModuleCamera3D(this);
	physics = new ModulePhysics3D(this);
	player = new ModulePlayer(this);
	imgui = new ModuleImGui(this);

	// The order of calls is very important!
	// Modules will Init() Start() and Update in this order
	// They will CleanUp() in reverse order

	// Main Modules
	AddModule(window);
	AddModule(camera);
	AddModule(input);
	AddModule(audio);
	AddModule(physics);
	AddModule(imgui);

	// Scenes
	AddModule(scene_intro);
	AddModule(player);

	// Renderer last!
	AddModule(renderer3D);
}

Application::~Application()
{
	for (std::list<Module*>::reverse_iterator rit = list_modules.rbegin(); rit != list_modules.rend(); ++rit)
	{
		if ((*rit) != nullptr)
		delete *rit;
	}

	list_modules.clear();

}

bool Application::Init()
{
	bool ret = true;

	// Call Init() in all modules

	EngineName = "PJ Edu Engine";

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->Init();
		}
	}

	// After all Init calls we call Start() in all modules
	//LOG("Application Start --------------");

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->Start();
		}
	}
	ms_timer.Start();
	return ret;
}

// ---------------------------------------------
void Application::PrepareUpdate()
{
	dt = (float)ms_timer.Read() / 1000.0f;
	ms_timer.Start();
}

// ---------------------------------------------
void Application::FinishUpdate()
{
}

// Call PreUpdate, Update and PostUpdate on all modules
update_status Application::Update()
{
	update_status ret = UPDATE_CONTINUE;
	PrepareUpdate();

	fps_container.push_back(ImGui::GetIO().Framerate);
	if (fps_container.size() > 500) {
		fps_container.erase(fps_container.begin(), fps_container.begin()+1);
	}

	/*ms_container.push_back(1000.f/ImGui::GetIO().Framerate);*/

	if (ms_container.size() > 500) {
		ms_container.erase(ms_container.begin(), ms_container.begin() + 1);
	}

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->PreUpdate(dt);
		}
	}

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->Update(dt);
		}
	}

	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->PostUpdate(dt);
		}
	}
	FinishUpdate();
	return ret;
}

bool Application::CleanUp()
{
	bool ret = true;
	fps_container.erase(fps_container.begin(), fps_container.begin() + 500);
	for (list<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); ++it) {
		if ((*it) != nullptr && ret == true) {
			ret = (*it)->CleanUp();
		}
	}
	return ret;
}

void Application::DrawConfigPanel()
{
	if (ImGui::CollapsingHeader("Application")) {
		ImGui::Text("Framerate");
		fps_title = EngineName +  ':' + std::to_string(ImGui::GetIO().Framerate);
		ImGui::PlotHistogram("Framerate", &fps_container[0], fps_container.size(), 0, fps_title.c_str(), 0.0f, 100.0f, { 500, 100 });
		ImGui::Separator();
		ms_title = EngineName + ':' + std::to_string(1000.f /ImGui::GetIO().Framerate);
		/*ImGui::PlotHistogram("Miliseconds", &ms_container[0], ms_container.size(), 0, ms_title.c_str(), 0.0f, 40.0f, { 500, 100 });*/
	}
}

void Application::AddModule(Module* mod)
{
	list_modules.push_back(mod);
}<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <cstdlib>		//for exit()

int main(int argc, char *argv[])
{
	using namespace std;
	if(argc==1)			//quit if no argument
	{
		cerr<<"Usage: "<<argv[0]<<" filename[s]\n";
		exit(EXIT_FAILURE);
	}
	ifstream fin;		//open stream
	long count;
	long total = 0;
	int min=30,max=0,temp=0;

	for(int file=1;file<argc;file++)
	{
		fin.open(argv[file]);
		while(fin>>in)
		{
			if(in>max)
				max=in;
			else if(in<min)
				min=in;

		}
		fin.clear();
		fin.close();
	}
	for(int i=min+1;i<max;i++)
		cout<<i<<" ";
	cout<<endl;
	return 0;
}<commit_msg>修改 ex1_11.cpp<commit_after>#include <iostream>
#include <fstream>
#include <cstdlib>		//for exit()

int main(int argc, char *argv[])
{
	using namespace std;
	if(argc==1)			//quit if no argument
	{
		cerr<<"Usage: "<<argv[0]<<" filename[s]\n";
		exit(EXIT_FAILURE);
	}
	ifstream fin;		//open stream
	long count;
	long total = 0;
	int min=30,max=0,temp=0,in;

	for(int file=1;file<argc;file++)
	{
		fin.open(argv[file]);
		while(fin>>in)
		{
			if(in>max)
				max=in;
			else if(in<min)
				min=in;

		}
		fin.clear();
		fin.close();
	}
	for(int i=min+1;i<max;i++)
		cout<<i<<" ";
	cout<<endl;
	return 0;
}<|endoftext|>


<commit_before>/**
 * Author: derselbst
 * Description: a demo program
 */

#include <iostream>
#include <string>
#include <openssl/sha.h>
#include <mpi.h>

using namespace std;

#include "worker.h"
#include "master.h"

int main(int argc, char** argv)
{
    MPI_Init(&argc, &argv);

    string pwd=">$<GV";

    // initialize the hash buffer for the password
    if(!generateSHA256(pwd.c_str(), pwd.length(), pwdHash))
    {
        cerr << "Error when generating SHA256 from \"" << pwd << "\"" << endl;
        return -2;
    }

    // determine the size of the world and create for every single process a status and request element
    totalProcesses=MPI::COMM_WORLD.Get_size();
    if(totalProcesses < 2)
    {
        cerr << "Insufficient number of workers: " << totalProcesses-1 << endl << "Aborting" << endl;
        MPI_Abort(MPI_COMM_WORLD, -1);
    }

    // determine which process i am
    int worldRank;
    MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);

    if(worldRank == MasterProcess)
    {
        for(int i=1; i<=MaxChars; i++)
        {
            cout << "checking passwords with " << i << " characters..." << endl;
            bruteRecursive(string(""), i-1, i);
        }

        cerr << "Sorry, password not found" << endl;
        // TODO: shutdown a bit more friendly
        MPI_Abort(MPI_COMM_WORLD, -2);
    }
    else
    {
        worker();
    }

    MPI_Finalize();
    return 0;
}
<commit_msg>clean shutdown in case world is too small<commit_after>/**
 * Author: derselbst
 * Description: a demo program
 */

#include <iostream>
#include <string>
#include <openssl/sha.h>
#include <mpi.h>

using namespace std;

#include "worker.h"
#include "master.h"

int main(int argc, char** argv)
{
    MPI_Init(&argc, &argv);

    string pwd=">$<GV";

    // initialize the hash buffer for the password
    if(!generateSHA256(pwd.c_str(), pwd.length(), pwdHash))
    {
        cerr << "Error when generating SHA256 from \"" << pwd << "\"" << endl;
        return -2;
    }

    // determine the size of the world and create for every single process a status and request element
    totalProcesses=MPI::COMM_WORLD.Get_size();
    if(totalProcesses < 2)
    {
        cerr << "Insufficient number of workers: " << totalProcesses-1 << endl << "Aborting" << endl;
        MPI_Finalize();
        return -1;
    }

    // determine which process i am
    int worldRank;
    MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);

    if(worldRank == MasterProcess)
    {
        for(int i=1; i<=MaxChars; i++)
        {
            cout << "checking passwords with " << i << " characters..." << endl;
            bruteRecursive(string(""), i-1, i);
        }

        cerr << "Sorry, password not found" << endl;
        // TODO: shutdown a bit more friendly
        MPI_Abort(MPI_COMM_WORLD, -2);
    }
    else
    {
        worker();
    }

    MPI_Finalize();
    return 0;
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "GraphHandler.h"

#include "NoAlgorithmDrawer.h"
#include "DijkstraDrawer.h"
#include "KruskalDrawer.h"
#include "PrimDrawer.h"
#include "Options.h"

#include "generators.h"
#include <random>

#include <cinder/Perlin.h>
#include <cinder/Rand.h>

GraphHandler::GraphHandler() : forceType(Force::none)
{
}

GraphHandler::~GraphHandler()
{
}

void GraphHandler::setup(ci::app::WindowRef _window)
{
    window = _window;
    cbMouseDown = window->getSignalMouseDown().connect(std::bind(&GraphHandler::mouseDown, this, std::placeholders::_1));
    cbMouseDrag = window->getSignalMouseDrag().connect(std::bind(&GraphHandler::mouseDrag, this, std::placeholders::_1));
    cbMouseUp = window->getSignalMouseUp().connect(std::bind(&GraphHandler::mouseUp, this, std::placeholders::_1));

    windowSize = window->getBounds();
    g = std::make_shared<Graph>(true);
    graphDrawer = std::make_unique<NoAlgorithmDrawer>(g, nodeHandlers, window);
}

void GraphHandler::draw()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex, std::defer_lock);
    if (!guard.try_lock())
        return;
    if (changed)
        graphDrawer->setChanged();

    graphDrawer->draw();
    changed = false;
}

void GraphHandler::animationPrepare()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->prepareAnimation();
}

void GraphHandler::animationPause()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->pause();
}

void GraphHandler::animationResume()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->resume();
}

void GraphHandler::animationNext()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->nextState();
}

void GraphHandler::animationPrevious()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->previousState();
}

void GraphHandler::addNewEdgeIfNodesSelected()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    int start = -1;
    int end = -1;
    for (size_t i = 0; i < nodeHandlers.size(); ++i)
    {
        if (nodeHandlers[i]->getSelection() == GraphNodeHandler::Selection::addEdge)
        {
            if (start == -1)
            {
                start = i;
            }
            else
            {
                end = i;
                break;
            }
        }
    }
    if (start != -1 && end != -1)
    {
        //std::cout << "New edge: " << start << " - " << end << std::endl;
        g->addEdge(start, end);
        nodeHandlers[start]->clearSelection();
        nodeHandlers[end]->clearSelection();
        changed = true;
    }
}

void GraphHandler::updateEdgeWeights()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        auto &node = g->getNode(i);
        auto posStart = nodeHandlers[i]->getPos();
        for (auto &edgePtr: node)
        {
            auto neighbor = edgePtr->otherEnd(i);
            auto posEnd = nodeHandlers[neighbor]->getPos();
            auto newWeight = ((posStart - posEnd).length()) / 100 * Options::instance().edgeWeightScale;
            changed |= (edgePtr->weight != newWeight);
            edgePtr->weight = newWeight;
        }
    }
}

void GraphHandler::update()
{
    static ci::Perlin perlin;
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    if(!Options::instance().animationPlaying)
    {
        addNewEdgeIfNodesSelected();
    }

    if (Options::instance().randomMovement)
    {
        for (auto& nh : nodeHandlers)
        {
            ci::Vec2f v;
            v.x = nh->getOriginalPos().x + float(ci::app::getElapsedSeconds()) * 0.1f;
            v.y = nh->getOriginalPos().y + float(ci::app::getElapsedSeconds()) * 0.01f;
            ci::Vec2f randVec = perlin.dfBm(v);
            //ci::Vec2f newSpeed(sin(angle), cos(angle));
            nh->setSpeed(randVec.x * 3);
            nh->setDirection(randVec.y);
            nh->update();
        }
    }

    if (automaticEdgeWeightUpdate && !Options::instance().animationPlaying)
    {
        updateEdgeWeights();
    }

    if (currentAlgorithm != Options::instance().algorithm)
    {
        Options::instance().animationPlaying = false;
        currentAlgorithm = Options::instance().algorithm;
        switch (Algorithm(currentAlgorithm))
        {
        default:
        case Algorithm::none:
            graphDrawer = std::make_unique<NoAlgorithmDrawer>(g, nodeHandlers, window);
            break;
        case Algorithm::prim:
            graphDrawer = std::make_unique<PrimDrawer>(g, nodeHandlers, window);
            break;
        case Algorithm::kruskal:
            graphDrawer = std::make_unique<KruskalDrawer>(g, nodeHandlers, window);
            break;
        case Algorithm::dijkstra:
            graphDrawer = std::make_unique<DijkstraDrawer>(g, nodeHandlers, window);
            break;
        }
    }

}

void GraphHandler::recreateNodeHandlers()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    nodeHandlers.clear();
    for (const auto &node : *g)
    {
        auto pos = ci::Vec2f(ci::Rand::randFloat() * window->getWidth(), ci::Rand::randFloat() * window->getHeight());
        nodeHandlers.emplace_back(new GraphNodeHandler(window, *this, pos));
    }
    changed = true;
}

void GraphHandler::recreateNodeHandlers(const std::vector<ci::Vec2f> &nodePositions)
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    nodeHandlers.clear();
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        nodeHandlers.emplace_back(new GraphNodeHandler(window, *this, nodePositions[i]));
    }
    changed = true;
}

void GraphHandler::loadGraph(std::string fileName)
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    std::ifstream in(fileName);
    if (!in.good())
        throw("Cannot open file");
    in >> *g;
    /*
    int N, M;
    in >> N >> M;
    g->clear();
    g->setDirected(true);
    g->resize(N);
    g->setWeightedEdges(true);
    for (int i = 0; i < M; i++)
    {
        int a, b, w;
        in >> a >> b >> w;
        g->addEdge(a - 1, b - 1, w);
    }
    */
    /*
    int N;
    g->clear();
    in >> N;
    g->resize(N + 1);
    g->setWeightedNodes(true);
    g->setWeightedEdges(false);
    for (int i = 0; i < N + 1; i++)
    {
        int deg;
        in >> deg;
        for (int d = 0; d < deg; d++)
        {
            int to;
            in >> to;
            g->addEdge(to - 1, i); // reverse the edges
        }
        g->getNode(i).setWeight(i+1);
    }

    for (int i = 0; i < N; i++)
    {
        float weight;
        in >> weight;
        g->getNode(i).setWeight(weight);
    }
    */

    recreateNodeHandlers();
    changed = true;
}

void GraphHandler::saveGraph(std::string fileName)
{
    std::ofstream out(fileName);
    if (!out.good())
        throw("Cannot open file");
    out << *g;
}

void GraphHandler::loadGraphPositions(std::string fileName)
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    std::ifstream in(fileName);
    if (!in.good())
        throw("Cannot open file");
    float x, y;
    int idx = 0;
    while (in >> x && idx < int(nodeHandlers.size()))
    {
        in >> y;
        nodeHandlers[idx++]->setPos(ci::Vec2f(x, y));
    }
    changed = true;
}

void GraphHandler::saveGraphPositions(std::string fileName)
{
    std::ofstream out(fileName);
    if (!out.good())
        throw("Cannot open file");
    for (const auto& node : nodeHandlers)
    {
        const auto &pos = node->getPos();
        out << pos.x << " " << pos.y << "\n";
    }
    out << std::flush;
}

void GraphHandler::reorderNodesSquare()
{
    auto gridSize = int(ceil(sqrt(g->getNodeCount())));
    auto nodePositions = generateGridPositions(g->getNodeCount(), gridSize, gridSize);
    repositionNodes(nodePositions);
}

void GraphHandler::repositionNodes(const std::vector<ci::Vec2f>& nodePositions)
{
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        nodeHandlers[i]->setPos(nodePositions[i]);
    }
    changed = true;
}

void GraphHandler::pushNodes(ci::Vec2f position, float force)
{
    for (auto &nh : nodeHandlers)
    {
        auto nodePosition = nh->getPos();
        auto forceVect = (position - nodePosition);
        nodePosition += forceVect.normalized() * (force / forceVect.lengthSquared()) * 10;
        nh->setPos(nodePosition);
    }
    changed = true;
}

void GraphHandler::pushNodes(ci::Vec2f position)
{
    pushNodes(position, Options::instance().force);
}

void GraphHandler::pullNodes(ci::Vec2f position)
{
    pushNodes(position, -Options::instance().force);
}

void GraphHandler::mouseDrag(ci::app::MouseEvent &event)
{
    if (forceType != Force::none)
    {
        std::unique_lock<std::recursive_mutex> guard(updateMutex);
        if (forceType == Force::push)
        {
            pushNodes(event.getPos());
        }
        else if (forceType == Force::pull)
        {
            pullNodes(event.getPos());
        }
    }
}

void GraphHandler::mouseUp(ci::app::MouseEvent &event)
{
    forceType = Force::none;
    //event.setHandled(true);
}

void GraphHandler::mouseDown(ci::app::MouseEvent &event)
{
    if (event.isControlDown() && !Options::instance().animationPlaying)
    {
        std::unique_lock<std::recursive_mutex> guard(updateMutex);
        nodeHandlers.emplace_back(new GraphNodeHandler(window, *this, event.getPos()));
        g->addNode();
        changed = true;
    }

    if (event.isAltDown())
    {
        if (event.isLeftDown())
        {
            forceType = Force::push;
        }
        else if (event.isRightDown())
        {
            forceType = Force::pull;
        }
    }

    event.setHandled(true);
}

void GraphHandler::resize(ci::Area newWindowSize)
{
    float xScale = float(newWindowSize.getWidth()) / windowSize.getWidth();
    float yScale = float(newWindowSize.getHeight()) / windowSize.getHeight();

    for (auto &nh : nodeHandlers)
    {
        auto pos = nh->getPos();
        nh->setPos(ci::Vec2f(pos.x * xScale, pos.y * yScale));
    }

    graphDrawer->resize(newWindowSize);

    windowSize = newWindowSize;
    changed = true;
}

void GraphHandler::fitToWindow()
{
    float minX, maxX, minY, maxY;
    minX = minY = std::numeric_limits<float>::max();
    maxX = maxX = std::numeric_limits<float>::min();

    for (const auto& nh : nodeHandlers)
    {
        auto pos = nh->getPos();
        minX = std::min(minX, pos.x);
        minY = std::min(minY, pos.y);
        maxX = std::max(maxX, pos.x);
        maxY = std::max(maxY, pos.y);
    }

    const float boundingRectWidth = maxX - minX;
    const float boundingRectHeight = maxY - minY;
    const float midX = (maxX + minX) / 2;
    const float midY = (maxY + minY) / 2;

    const float marginX = 0.1f;
    const float marginY = 0.05f;

    float targetHeight = float(window->getHeight());
    float targetWidth = float(window->getWidth());

    targetWidth *= (1 - 2 * marginX);
    targetHeight *= (1 - 2 * marginY);
    for (const auto& nh : nodeHandlers)
    {
        float newX = ((nh->getPos().x) - minX) / boundingRectWidth * window->getWidth() * (1 - 2 * marginX) + window->getWidth() * marginX;
        float newY = ((nh->getPos().y) - minY) / boundingRectHeight * window->getHeight() * (1 - 2 * marginY) + window->getHeight() * marginY;
        nh->setPos(ci::Vec2f(newX, newY));
    }
    changed = true;
}

void GraphHandler::generateSpecialGraph(GraphType type)
{
    std::cout << "GraphHandler::generateSpecialGraph(" << static_cast<int>(type) << ")\n";
    std::unique_lock<std::recursive_mutex> guard(updateMutex, std::defer_lock);
    std::cout << "Start...\n";

    std::vector<ci::Vec2f> nodePositions;
    switch (type)
    {
    case GraphType::grid:
        generateGrid(GraphParamsGrid::instance(), *g, nodePositions);
        break;
    case GraphType::triangleMesh:
        generateTriangleMesh(GraphParamsTriangleMesh::instance(), *g, nodePositions);
        break;
    case GraphType::general:
    default:
        std::cout << "GraphHandler::generateSpecialGraph - SKIP\n";
    }
    recreateNodeHandlers(nodePositions);
    changed = true;
    std::cout << "End\n";
}

void GraphHandler::setRandomEdgeWeights()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dis(int(Options::instance().minRandomEdgeWeight), int(Options::instance().maxRandomEdgeWeight));
    std::unique_lock<std::recursive_mutex> guard(updateMutex, std::defer_lock);
    for (auto node : *g)
    {
        for (auto edgePtr : *node)
        {
            edgePtr->weight = float(dis(gen));
        }
    }
    changed = true;
}<commit_msg>Friendlier error handling during graph load and save<commit_after>#include "stdafx.h"
#include "GraphHandler.h"

#include "NoAlgorithmDrawer.h"
#include "DijkstraDrawer.h"
#include "KruskalDrawer.h"
#include "PrimDrawer.h"
#include "Options.h"

#include "generators.h"
#include <random>

#include <cinder/Perlin.h>
#include <cinder/Rand.h>

GraphHandler::GraphHandler() : forceType(Force::none)
{
}

GraphHandler::~GraphHandler()
{
}

void GraphHandler::setup(ci::app::WindowRef _window)
{
    window = _window;
    cbMouseDown = window->getSignalMouseDown().connect(std::bind(&GraphHandler::mouseDown, this, std::placeholders::_1));
    cbMouseDrag = window->getSignalMouseDrag().connect(std::bind(&GraphHandler::mouseDrag, this, std::placeholders::_1));
    cbMouseUp = window->getSignalMouseUp().connect(std::bind(&GraphHandler::mouseUp, this, std::placeholders::_1));

    windowSize = window->getBounds();
    g = std::make_shared<Graph>(true);
    graphDrawer = std::make_unique<NoAlgorithmDrawer>(g, nodeHandlers, window);
}

void GraphHandler::draw()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex, std::defer_lock);
    if (!guard.try_lock())
        return;
    if (changed)
        graphDrawer->setChanged();

    graphDrawer->draw();
    changed = false;
}

void GraphHandler::animationPrepare()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->prepareAnimation();
}

void GraphHandler::animationPause()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->pause();
}

void GraphHandler::animationResume()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->resume();
}

void GraphHandler::animationNext()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->nextState();
}

void GraphHandler::animationPrevious()
{
    GraphAnimationDrawer* animationDrawer = dynamic_cast<GraphAnimationDrawer*>(graphDrawer.get());
    if (animationDrawer)
        animationDrawer->previousState();
}

void GraphHandler::addNewEdgeIfNodesSelected()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    int start = -1;
    int end = -1;
    for (size_t i = 0; i < nodeHandlers.size(); ++i)
    {
        if (nodeHandlers[i]->getSelection() == GraphNodeHandler::Selection::addEdge)
        {
            if (start == -1)
            {
                start = i;
            }
            else
            {
                end = i;
                break;
            }
        }
    }
    if (start != -1 && end != -1)
    {
        //std::cout << "New edge: " << start << " - " << end << std::endl;
        g->addEdge(start, end);
        nodeHandlers[start]->clearSelection();
        nodeHandlers[end]->clearSelection();
        changed = true;
    }
}

void GraphHandler::updateEdgeWeights()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        auto &node = g->getNode(i);
        auto posStart = nodeHandlers[i]->getPos();
        for (auto &edgePtr: node)
        {
            auto neighbor = edgePtr->otherEnd(i);
            auto posEnd = nodeHandlers[neighbor]->getPos();
            auto newWeight = ((posStart - posEnd).length()) / 100 * Options::instance().edgeWeightScale;
            changed |= (edgePtr->weight != newWeight);
            edgePtr->weight = newWeight;
        }
    }
}

void GraphHandler::update()
{
    static ci::Perlin perlin;
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    if(!Options::instance().animationPlaying)
    {
        addNewEdgeIfNodesSelected();
    }

    if (Options::instance().randomMovement)
    {
        for (auto& nh : nodeHandlers)
        {
            ci::Vec2f v;
            v.x = nh->getOriginalPos().x + float(ci::app::getElapsedSeconds()) * 0.1f;
            v.y = nh->getOriginalPos().y + float(ci::app::getElapsedSeconds()) * 0.01f;
            ci::Vec2f randVec = perlin.dfBm(v);
            //ci::Vec2f newSpeed(sin(angle), cos(angle));
            nh->setSpeed(randVec.x * 3);
            nh->setDirection(randVec.y);
            nh->update();
        }
    }

    if (automaticEdgeWeightUpdate && !Options::instance().animationPlaying)
    {
        updateEdgeWeights();
    }

    if (currentAlgorithm != Options::instance().algorithm)
    {
        Options::instance().animationPlaying = false;
        currentAlgorithm = Options::instance().algorithm;
        switch (Algorithm(currentAlgorithm))
        {
        default:
        case Algorithm::none:
            graphDrawer = std::make_unique<NoAlgorithmDrawer>(g, nodeHandlers, window);
            break;
        case Algorithm::prim:
            graphDrawer = std::make_unique<PrimDrawer>(g, nodeHandlers, window);
            break;
        case Algorithm::kruskal:
            graphDrawer = std::make_unique<KruskalDrawer>(g, nodeHandlers, window);
            break;
        case Algorithm::dijkstra:
            graphDrawer = std::make_unique<DijkstraDrawer>(g, nodeHandlers, window);
            break;
        }
    }

}

void GraphHandler::recreateNodeHandlers()
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    nodeHandlers.clear();
    for (const auto &node : *g)
    {
        auto pos = ci::Vec2f(ci::Rand::randFloat() * window->getWidth(), ci::Rand::randFloat() * window->getHeight());
        nodeHandlers.emplace_back(new GraphNodeHandler(window, *this, pos));
    }
    changed = true;
}

void GraphHandler::recreateNodeHandlers(const std::vector<ci::Vec2f> &nodePositions)
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    nodeHandlers.clear();
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        nodeHandlers.emplace_back(new GraphNodeHandler(window, *this, nodePositions[i]));
    }
    changed = true;
}

void GraphHandler::loadGraph(std::string fileName)
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    std::ifstream in(fileName);
    if (!in.good())
        throw("Cannot open file");
    in >> *g;
    /*
    int N, M;
    in >> N >> M;
    g->clear();
    g->setDirected(true);
    g->resize(N);
    g->setWeightedEdges(true);
    for (int i = 0; i < M; i++)
    {
        int a, b, w;
        in >> a >> b >> w;
        g->addEdge(a - 1, b - 1, w);
    }
    */
    /*
    int N;
    g->clear();
    in >> N;
    g->resize(N + 1);
    g->setWeightedNodes(true);
    g->setWeightedEdges(false);
    for (int i = 0; i < N + 1; i++)
    {
        int deg;
        in >> deg;
        for (int d = 0; d < deg; d++)
        {
            int to;
            in >> to;
            g->addEdge(to - 1, i); // reverse the edges
        }
        g->getNode(i).setWeight(i+1);
    }

    for (int i = 0; i < N; i++)
    {
        float weight;
        in >> weight;
        g->getNode(i).setWeight(weight);
    }
    */

    recreateNodeHandlers();
    changed = true;
}

void GraphHandler::saveGraph(std::string fileName)
{
    std::ofstream out(fileName);
    if (!out.good())
    {
        std::cout << "Cannot open graph file: [" << fileName << "]" << std::endl;
        return;
    }
    out << *g;
}

void GraphHandler::loadGraphPositions(std::string fileName)
{
    std::unique_lock<std::recursive_mutex> guard(updateMutex);
    std::ifstream in(fileName);
    if (!in.good())
    {
        std::cout << "Cannot open positions file: [" << fileName << "]" << std::endl;
        return;
    }

    float x, y;
    int idx = 0;
    while (in >> x && idx < int(nodeHandlers.size()))
    {
        in >> y;
        nodeHandlers[idx++]->setPos(ci::Vec2f(x, y));
    }
    changed = true;
}

void GraphHandler::saveGraphPositions(std::string fileName)
{
    std::ofstream out(fileName);
    if (!out.good())
        throw("Cannot open file");
    for (const auto& node : nodeHandlers)
    {
        const auto &pos = node->getPos();
        out << pos.x << " " << pos.y << "\n";
    }
    out << std::flush;
}

void GraphHandler::reorderNodesSquare()
{
    auto gridSize = int(ceil(sqrt(g->getNodeCount())));
    auto nodePositions = generateGridPositions(g->getNodeCount(), gridSize, gridSize);
    repositionNodes(nodePositions);
}

void GraphHandler::repositionNodes(const std::vector<ci::Vec2f>& nodePositions)
{
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        nodeHandlers[i]->setPos(nodePositions[i]);
    }
    changed = true;
}

void GraphHandler::pushNodes(ci::Vec2f position, float force)
{
    for (auto &nh : nodeHandlers)
    {
        auto nodePosition = nh->getPos();
        auto forceVect = (position - nodePosition);
        nodePosition += forceVect.normalized() * (force / forceVect.lengthSquared()) * 10;
        nh->setPos(nodePosition);
    }
    changed = true;
}

void GraphHandler::pushNodes(ci::Vec2f position)
{
    pushNodes(position, Options::instance().force);
}

void GraphHandler::pullNodes(ci::Vec2f position)
{
    pushNodes(position, -Options::instance().force);
}

void GraphHandler::mouseDrag(ci::app::MouseEvent &event)
{
    if (forceType != Force::none)
    {
        std::unique_lock<std::recursive_mutex> guard(updateMutex);
        if (forceType == Force::push)
        {
            pushNodes(event.getPos());
        }
        else if (forceType == Force::pull)
        {
            pullNodes(event.getPos());
        }
    }
}

void GraphHandler::mouseUp(ci::app::MouseEvent &event)
{
    forceType = Force::none;
    //event.setHandled(true);
}

void GraphHandler::mouseDown(ci::app::MouseEvent &event)
{
    if (event.isControlDown() && !Options::instance().animationPlaying)
    {
        std::unique_lock<std::recursive_mutex> guard(updateMutex);
        nodeHandlers.emplace_back(new GraphNodeHandler(window, *this, event.getPos()));
        g->addNode();
        changed = true;
    }

    if (event.isAltDown())
    {
        if (event.isLeftDown())
        {
            forceType = Force::push;
        }
        else if (event.isRightDown())
        {
            forceType = Force::pull;
        }
    }

    event.setHandled(true);
}

void GraphHandler::resize(ci::Area newWindowSize)
{
    float xScale = float(newWindowSize.getWidth()) / windowSize.getWidth();
    float yScale = float(newWindowSize.getHeight()) / windowSize.getHeight();

    for (auto &nh : nodeHandlers)
    {
        auto pos = nh->getPos();
        nh->setPos(ci::Vec2f(pos.x * xScale, pos.y * yScale));
    }

    graphDrawer->resize(newWindowSize);

    windowSize = newWindowSize;
    changed = true;
}

void GraphHandler::fitToWindow()
{
    float minX, maxX, minY, maxY;
    minX = minY = std::numeric_limits<float>::max();
    maxX = maxX = std::numeric_limits<float>::min();

    for (const auto& nh : nodeHandlers)
    {
        auto pos = nh->getPos();
        minX = std::min(minX, pos.x);
        minY = std::min(minY, pos.y);
        maxX = std::max(maxX, pos.x);
        maxY = std::max(maxY, pos.y);
    }

    const float boundingRectWidth = maxX - minX;
    const float boundingRectHeight = maxY - minY;
    const float midX = (maxX + minX) / 2;
    const float midY = (maxY + minY) / 2;

    const float marginX = 0.1f;
    const float marginY = 0.05f;

    float targetHeight = float(window->getHeight());
    float targetWidth = float(window->getWidth());

    targetWidth *= (1 - 2 * marginX);
    targetHeight *= (1 - 2 * marginY);
    for (const auto& nh : nodeHandlers)
    {
        float newX = ((nh->getPos().x) - minX) / boundingRectWidth * window->getWidth() * (1 - 2 * marginX) + window->getWidth() * marginX;
        float newY = ((nh->getPos().y) - minY) / boundingRectHeight * window->getHeight() * (1 - 2 * marginY) + window->getHeight() * marginY;
        nh->setPos(ci::Vec2f(newX, newY));
    }
    changed = true;
}

void GraphHandler::generateSpecialGraph(GraphType type)
{
    std::cout << "GraphHandler::generateSpecialGraph(" << static_cast<int>(type) << ")\n";
    std::unique_lock<std::recursive_mutex> guard(updateMutex, std::defer_lock);
    std::cout << "Start...\n";

    std::vector<ci::Vec2f> nodePositions;
    switch (type)
    {
    case GraphType::grid:
        generateGrid(GraphParamsGrid::instance(), *g, nodePositions);
        break;
    case GraphType::triangleMesh:
        generateTriangleMesh(GraphParamsTriangleMesh::instance(), *g, nodePositions);
        break;
    case GraphType::general:
    default:
        std::cout << "GraphHandler::generateSpecialGraph - SKIP\n";
    }
    recreateNodeHandlers(nodePositions);
    changed = true;
    std::cout << "End\n";
}

void GraphHandler::setRandomEdgeWeights()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dis(int(Options::instance().minRandomEdgeWeight), int(Options::instance().maxRandomEdgeWeight));
    std::unique_lock<std::recursive_mutex> guard(updateMutex, std::defer_lock);
    for (auto node : *g)
    {
        for (auto edgePtr : *node)
        {
            edgePtr->weight = float(dis(gen));
        }
    }
    changed = true;
}<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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 "bvh_builder_twolevel.h"
#include "bvh_statistics.h"
#include "../builders/bvh_builder_sah.h"
#include "../common/scene_line_segments.h"
#include "../common/scene_triangle_mesh.h"
#include "../common/scene_quad_mesh.h"

#define PROFILE 0
#define MAX_OPEN_SIZE 10000

/* new open/merge builder */
#define ENABLE_DIRECT_SAH_MERGE_BUILDER 1

/* sequential opening phase in old code path */
#define ENABLE_OPEN_SEQUENTIAL 0

#define SPLIT_MEMORY_RESERVE_FACTOR 1000
// 500
#define SPLIT_MIN_EXT_SPACE 1000
#undef DBG_PRINT
#define DBG_PRINT(x) PRINT(x)
// for non-opening two-level approach set ENABLE_DIRECT_SAH_MERGE_BUILDER and ENABLE_OPEN_SEQUENTIAL to 0

namespace embree
{
  namespace isa
  {
    template<int N, typename Mesh>
    BVHNBuilderTwoLevel<N,Mesh>::BVHNBuilderTwoLevel (BVH* bvh, Scene* scene, const createMeshAccelTy createMeshAccel, const size_t singleThreadThreshold)
      : bvh(bvh), objects(bvh->objects), scene(scene), createMeshAccel(createMeshAccel), refs(scene->device), prims(scene->device), singleThreadThreshold(singleThreadThreshold) {}

    template<int N, typename Mesh>
    BVHNBuilderTwoLevel<N,Mesh>::~BVHNBuilderTwoLevel ()
    {
      for (size_t i=0; i<builders.size(); i++)
	delete builders[i];
    }

    // ===========================================================================
    // ===========================================================================
    // ===========================================================================

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::build()
    {
      /* delete some objects */
      size_t num = scene->size();
      if (num < objects.size()) {
        parallel_for(num, objects.size(), [&] (const range<size_t>& r) {
            for (size_t i=r.begin(); i<r.end(); i++) {
              delete builders[i]; builders[i] = nullptr;
              delete objects[i]; objects[i] = nullptr;
            }
          });
      }

#if PROFILE == 1
      while(1)
#endif
      {
      /* reset memory allocator */
      bvh->alloc.reset();

      /* skip build for empty scene */
      const size_t numPrimitives = scene->getNumPrimitives<Mesh,false>();

      if (numPrimitives == 0) {
        prims.resize(0);
        bvh->set(BVH::emptyNode,empty,0);
        return;
      }

      double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "BuilderTwoLevel");

      /* resize object array if scene got larger */
      if (objects.size()  < num) objects.resize(num);
      if (builders.size() < num) builders.resize(num);
      if (refs.size()     < num) refs.resize(num);
      nextRef.store(0);

      /* create of acceleration structures */
      parallel_for(size_t(0), num, [&] (const range<size_t>& r)
      {
        for (size_t objectID=r.begin(); objectID<r.end(); objectID++)
        {
          Mesh* mesh = scene->getSafe<Mesh>(objectID);

          /* verify meshes got deleted properly */
          if (mesh == nullptr || mesh->numTimeSteps != 1) {
            assert(objectID < objects.size () && objects[objectID] == nullptr);
            assert(objectID < builders.size() && builders[objectID] == nullptr);
            continue;
          }

          /* create BVH and builder for new meshes */
          if (objects[objectID] == nullptr)
            createMeshAccel(mesh,(AccelData*&)objects[objectID],builders[objectID]);
        }
      });
      /* parallel build of acceleration structures */
      parallel_for(size_t(0), num, [&] (const range<size_t>& r)
      {
        for (size_t objectID=r.begin(); objectID<r.end(); objectID++)
        {
          /* ignore if no triangle mesh or not enabled */
          Mesh* mesh = scene->getSafe<Mesh>(objectID);
          if (mesh == nullptr || !mesh->isEnabled() || mesh->numTimeSteps != 1)
            continue;

          BVH*     object  = objects [objectID]; assert(object);
          Builder* builder = builders[objectID]; assert(builder);

          /* build object if it got modified */
          if (mesh->isModified())
            builder->build();

          /* create build primitive */
          if (!object->getBounds().empty())
#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 1
            refs[nextRef++] = BVHNBuilderTwoLevel::BuildRef(object->getBounds(),object->root,objectID,mesh->size());
#else
          refs[nextRef++] = BVHNBuilderTwoLevel::BuildRef(object->getBounds(),object->root);
#endif
        }
      });

      PING;
      PRINT(nextRef);

#if PROFILE
      double d0 = getSeconds();
#endif
      /* fast path for single geometry scenes */
      if (nextRef == 1) {
        bvh->set(refs[0].node,LBBox3fa(refs[0].bounds()),numPrimitives);
      }

      else
      {
        /* open all large nodes */
        refs.resize(nextRef);

#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 0

#if ENABLE_OPEN_SEQUENTIAL == 1
        open_sequential(numPrimitives,MAX_OPEN_SIZE);
#endif
        /* compute PrimRefs */
        prims.resize(refs.size());
#else

#endif

        DBG_PRINT(refs.size());

        bvh->alloc.init_estimate(refs.size()*16); // FIXME: increase estimate for opening case

#if defined(TASKING_TBB) && defined(__AVX512ER__) && USE_TASK_ARENA // KNL
        tbb::task_arena limited(min(32,(int)TaskScheduler::threadCount()));
        limited.execute([&]
#endif
        {
#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 1

          const PrimInfo pinfo = parallel_reduce(size_t(0), refs.size(),  PrimInfo(empty), [&] (const range<size_t>& r) -> PrimInfo {

              PrimInfo pinfo(empty);
              for (size_t i=r.begin(); i<r.end(); i++) {
                pinfo.add(refs[i].bounds(),refs[i].bounds().center2());
              }
              return pinfo;
            }, [] (const PrimInfo& a, const PrimInfo& b) { return PrimInfo::merge(a,b); });

#else
          const PrimInfo pinfo = parallel_reduce(size_t(0), refs.size(),  PrimInfo(empty), [&] (const range<size_t>& r) -> PrimInfo {

              PrimInfo pinfo(empty);
              for (size_t i=r.begin(); i<r.end(); i++) {
                pinfo.add(refs[i].bounds());
                prims[i] = PrimRef(refs[i].bounds(),(size_t)refs[i].node);
              }
              return pinfo;
            }, [] (const PrimInfo& a, const PrimInfo& b) { return PrimInfo::merge(a,b); });
#endif

          /* skip if all objects where empty */
          if (pinfo.size() == 0)
            bvh->set(BVH::emptyNode,empty,0);

          /* otherwise build toplevel hierarchy */
          else
          {
            /* settings for BVH build */
            GeneralBVHBuilder::Settings settings;
            settings.branchingFactor = N;
            settings.maxDepth = BVH::maxBuildDepthLeaf;
            settings.logBlockSize = __bsr(N);
            settings.minLeafSize = 1;
            settings.maxLeafSize = 1;
            settings.travCost = 1.0f;
            settings.intCost = 1.0f;
            settings.singleThreadThreshold = singleThreadThreshold;

#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 1

            const size_t extSize = max(max((size_t)SPLIT_MIN_EXT_SPACE,refs.size()*2),size_t((float)numPrimitives / SPLIT_MEMORY_RESERVE_FACTOR));
            DBG_PRINT(refs.size()*2);
            DBG_PRINT(extSize);
            refs.resize(extSize);

            NodeRef root = BVHBuilderBinnedOpenMergeSAH::build<NodeRef,BuildRef>(
              typename BVH::CreateAlloc(bvh),
              typename BVH::AlignedNode::Create2(),
              typename BVH::AlignedNode::Set2(),

              [&] (const BVHBuilderBinnedOpenMergeSAH::BuildRecord& current, FastAllocator::ThreadLocal2* alloc) -> NodeRef  {
                assert(current.prims.size() == 1);
                return (NodeRef) refs[current.prims.begin()].node;
              },
              [&] (BuildRef &bref, BuildRef *refs) -> size_t {
                return openBuildRef(bref,refs);
              },
              [&] (size_t dn) { bvh->scene->progressMonitor(0); },
              refs.data(),extSize,pinfo,settings);

#else
            NodeRef root = BVHBuilderBinnedSAH::build<NodeRef>(
              typename BVH::CreateAlloc(bvh),
              typename BVH::AlignedNode::Create2(),
              typename BVH::AlignedNode::Set2(),

              [&] (const BVHBuilderBinnedSAH::BuildRecord& current, FastAllocator::ThreadLocal2* alloc) -> NodeRef {
                assert(current.prims.size() == 1);
                return (NodeRef) prims[current.prims.begin()].ID();
              },
              [&] (size_t dn) { bvh->scene->progressMonitor(0); },
              prims.data(),pinfo,settings);
#endif

            bvh->set(root,LBBox3fa(pinfo.geomBounds),numPrimitives);
          }
        }
#if defined(TASKING_TBB) && defined(__AVX512ER__) && USE_TASK_ARENA // KNL
          );
#endif

      }

      bvh->alloc.cleanup();
      bvh->postBuild(t0);
#if PROFILE
      double d1 = getSeconds();
      std::cout << "TOP_LEVEL OPENING/REBUILD TIME " << 1000.0*(d1-d0) << " ms" << std::endl;
#endif
      }

    }

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::deleteGeometry(size_t geomID)
    {
      if (geomID >= objects.size()) return;
      delete builders[geomID]; builders[geomID] = nullptr;
      delete objects [geomID]; objects [geomID] = nullptr;
    }

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::clear()
    {
      for (size_t i=0; i<objects.size(); i++)
        if (objects[i]) objects[i]->clear();

      for (size_t i=0; i<builders.size(); i++)
	if (builders[i]) builders[i]->clear();

      refs.clear();
    }

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::open_sequential(const size_t numPrimitives, const size_t maxOpenSize)
    {
      if (refs.size() == 0)
	return;

      size_t num = min(numPrimitives/400,maxOpenSize);
      DBG_PRINT(num);
      refs.reserve(num);

#if 1
      for (size_t i=0;i<refs.size();i++)
      {
        NodeRef ref = refs[i].node;
        if (ref.isAlignedNode())
          ref.prefetch();
      }
#endif

      std::make_heap(refs.begin(),refs.end());
      while (refs.size()+3 <= num)
      {
        std::pop_heap (refs.begin(),refs.end());
        NodeRef ref = refs.back().node;
        if (ref.isLeaf()) break;
        refs.pop_back();

        AlignedNode* node = ref.alignedNode();
        for (size_t i=0; i<N; i++) {
          if (node->child(i) == BVH::emptyNode) continue;
          refs.push_back(BuildRef(node->bounds(i),node->child(i)));

#if 1
          NodeRef ref_pre = node->child(i);
          if (ref_pre.isAlignedNode())
            ref_pre.prefetch();
#endif
          std::push_heap (refs.begin(),refs.end());
        }
      }
      DBG_PRINT(refs.size());
    }

#if defined(EMBREE_GEOMETRY_LINES)
    Builder* BVH4BuilderTwoLevelLineSegmentsSAH (void* bvh, Scene* scene, const createLineSegmentsAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<4,LineSegments>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_TRIANGLES)
    Builder* BVH4BuilderTwoLevelTriangleMeshSAH (void* bvh, Scene* scene, const createTriangleMeshAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<4,TriangleMesh>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_QUADS)
    Builder* BVH4BuilderTwoLevelQuadMeshSAH (void* bvh, Scene* scene, const createQuadMeshAccelTy createMeshAccel) {
    return new BVHNBuilderTwoLevel<4,QuadMesh>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_USER)
    Builder* BVH4BuilderTwoLevelVirtualSAH (void* bvh, Scene* scene, const createAccelSetAccelTy createMeshAccel) {
    return new BVHNBuilderTwoLevel<4,AccelSet>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(__AVX__)
#if defined(EMBREE_GEOMETRY_TRIANGLES)
    Builder* BVH8BuilderTwoLevelTriangleMeshSAH (void* bvh, Scene* scene, const createTriangleMeshAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<8,TriangleMesh>((BVH8*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_QUADS)
    Builder* BVH8BuilderTwoLevelQuadMeshSAH (void* bvh, Scene* scene, const createQuadMeshAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<8,QuadMesh>((BVH8*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_USER)
    Builder* BVH8BuilderTwoLevelVirtualSAH (void* bvh, Scene* scene, const createAccelSetAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<8,AccelSet>((BVH8*)bvh,scene,createMeshAccel);
    }
#endif
#endif
  }
}
<commit_msg>updates<commit_after>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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 "bvh_builder_twolevel.h"
#include "bvh_statistics.h"
#include "../builders/bvh_builder_sah.h"
#include "../common/scene_line_segments.h"
#include "../common/scene_triangle_mesh.h"
#include "../common/scene_quad_mesh.h"

#define PROFILE 0
#define MAX_OPEN_SIZE 10000

/* new open/merge builder */
#define ENABLE_DIRECT_SAH_MERGE_BUILDER 1

/* sequential opening phase in old code path */
#define ENABLE_OPEN_SEQUENTIAL 0

#define SPLIT_MEMORY_RESERVE_FACTOR 1000
#define SPLIT_MEMORY_RESERVE_SCALE 2
// 500
#define SPLIT_MIN_EXT_SPACE 1000
#undef DBG_PRINT
#define DBG_PRINT(x) PRINT(x)
// for non-opening two-level approach set ENABLE_DIRECT_SAH_MERGE_BUILDER and ENABLE_OPEN_SEQUENTIAL to 0

namespace embree
{
  namespace isa
  {
    template<int N, typename Mesh>
    BVHNBuilderTwoLevel<N,Mesh>::BVHNBuilderTwoLevel (BVH* bvh, Scene* scene, const createMeshAccelTy createMeshAccel, const size_t singleThreadThreshold)
      : bvh(bvh), objects(bvh->objects), scene(scene), createMeshAccel(createMeshAccel), refs(scene->device), prims(scene->device), singleThreadThreshold(singleThreadThreshold) {}

    template<int N, typename Mesh>
    BVHNBuilderTwoLevel<N,Mesh>::~BVHNBuilderTwoLevel ()
    {
      for (size_t i=0; i<builders.size(); i++)
	delete builders[i];
    }

    // ===========================================================================
    // ===========================================================================
    // ===========================================================================

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::build()
    {
      /* delete some objects */
      size_t num = scene->size();
      if (num < objects.size()) {
        parallel_for(num, objects.size(), [&] (const range<size_t>& r) {
            for (size_t i=r.begin(); i<r.end(); i++) {
              delete builders[i]; builders[i] = nullptr;
              delete objects[i]; objects[i] = nullptr;
            }
          });
      }

#if PROFILE == 1
      while(1)
#endif
      {
      /* reset memory allocator */
      bvh->alloc.reset();

      /* skip build for empty scene */
      const size_t numPrimitives = scene->getNumPrimitives<Mesh,false>();

      if (numPrimitives == 0) {
        prims.resize(0);
        bvh->set(BVH::emptyNode,empty,0);
        return;
      }

      double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "BuilderTwoLevel");

      /* resize object array if scene got larger */
      if (objects.size()  < num) objects.resize(num);
      if (builders.size() < num) builders.resize(num);
      if (refs.size()     < num) refs.resize(num);
      nextRef.store(0);

      /* create of acceleration structures */
      parallel_for(size_t(0), num, [&] (const range<size_t>& r)
      {
        for (size_t objectID=r.begin(); objectID<r.end(); objectID++)
        {
          Mesh* mesh = scene->getSafe<Mesh>(objectID);

          /* verify meshes got deleted properly */
          if (mesh == nullptr || mesh->numTimeSteps != 1) {
            assert(objectID < objects.size () && objects[objectID] == nullptr);
            assert(objectID < builders.size() && builders[objectID] == nullptr);
            continue;
          }

          /* create BVH and builder for new meshes */
          if (objects[objectID] == nullptr)
            createMeshAccel(mesh,(AccelData*&)objects[objectID],builders[objectID]);
        }
      });
      /* parallel build of acceleration structures */
      parallel_for(size_t(0), num, [&] (const range<size_t>& r)
      {
        for (size_t objectID=r.begin(); objectID<r.end(); objectID++)
        {
          /* ignore if no triangle mesh or not enabled */
          Mesh* mesh = scene->getSafe<Mesh>(objectID);
          if (mesh == nullptr || !mesh->isEnabled() || mesh->numTimeSteps != 1)
            continue;

          BVH*     object  = objects [objectID]; assert(object);
          Builder* builder = builders[objectID]; assert(builder);

          /* build object if it got modified */
          if (mesh->isModified())
            builder->build();

          /* create build primitive */
          if (!object->getBounds().empty())
#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 1
            refs[nextRef++] = BVHNBuilderTwoLevel::BuildRef(object->getBounds(),object->root,objectID,mesh->size());
#else
          refs[nextRef++] = BVHNBuilderTwoLevel::BuildRef(object->getBounds(),object->root);
#endif
        }
      });

      PING;
      PRINT(nextRef);

#if PROFILE
      double d0 = getSeconds();
#endif
      /* fast path for single geometry scenes */
      if (nextRef == 1) {
        bvh->set(refs[0].node,LBBox3fa(refs[0].bounds()),numPrimitives);
      }

      else
      {
        /* open all large nodes */
        refs.resize(nextRef);

#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 0

#if ENABLE_OPEN_SEQUENTIAL == 1
        open_sequential(numPrimitives,MAX_OPEN_SIZE);
#endif
        /* compute PrimRefs */
        prims.resize(refs.size());
#else

#endif

        DBG_PRINT(refs.size());

        bvh->alloc.init_estimate(refs.size()*16); // FIXME: increase estimate for opening case

#if defined(TASKING_TBB) && defined(__AVX512ER__) && USE_TASK_ARENA // KNL
        tbb::task_arena limited(min(32,(int)TaskScheduler::threadCount()));
        limited.execute([&]
#endif
        {
#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 1

          const PrimInfo pinfo = parallel_reduce(size_t(0), refs.size(),  PrimInfo(empty), [&] (const range<size_t>& r) -> PrimInfo {

              PrimInfo pinfo(empty);
              for (size_t i=r.begin(); i<r.end(); i++) {
                pinfo.add(refs[i].bounds(),refs[i].bounds().center2());
              }
              return pinfo;
            }, [] (const PrimInfo& a, const PrimInfo& b) { return PrimInfo::merge(a,b); });

#else
          const PrimInfo pinfo = parallel_reduce(size_t(0), refs.size(),  PrimInfo(empty), [&] (const range<size_t>& r) -> PrimInfo {

              PrimInfo pinfo(empty);
              for (size_t i=r.begin(); i<r.end(); i++) {
                pinfo.add(refs[i].bounds());
                prims[i] = PrimRef(refs[i].bounds(),(size_t)refs[i].node);
              }
              return pinfo;
            }, [] (const PrimInfo& a, const PrimInfo& b) { return PrimInfo::merge(a,b); });
#endif

          /* skip if all objects where empty */
          if (pinfo.size() == 0)
            bvh->set(BVH::emptyNode,empty,0);

          /* otherwise build toplevel hierarchy */
          else
          {
            /* settings for BVH build */
            GeneralBVHBuilder::Settings settings;
            settings.branchingFactor = N;
            settings.maxDepth = BVH::maxBuildDepthLeaf;
            settings.logBlockSize = __bsr(N);
            settings.minLeafSize = 1;
            settings.maxLeafSize = 1;
            settings.travCost = 1.0f;
            settings.intCost = 1.0f;
            settings.singleThreadThreshold = singleThreadThreshold;

#if ENABLE_DIRECT_SAH_MERGE_BUILDER == 1
            DBG_PRINT(numPrimitives);
            const size_t extSize = max(max((size_t)SPLIT_MIN_EXT_SPACE,refs.size()*SPLIT_MEMORY_RESERVE_SCALE),size_t((float)numPrimitives / SPLIT_MEMORY_RESERVE_FACTOR));
            DBG_PRINT(refs.size()*SPLIT_MEMORY_RESERVE_SCALE);
            DBG_PRINT(extSize);
            refs.resize(extSize);

            NodeRef root = BVHBuilderBinnedOpenMergeSAH::build<NodeRef,BuildRef>(
              typename BVH::CreateAlloc(bvh),
              typename BVH::AlignedNode::Create2(),
              typename BVH::AlignedNode::Set2(),

              [&] (const BVHBuilderBinnedOpenMergeSAH::BuildRecord& current, FastAllocator::ThreadLocal2* alloc) -> NodeRef  {
                assert(current.prims.size() == 1);
                return (NodeRef) refs[current.prims.begin()].node;
              },
              [&] (BuildRef &bref, BuildRef *refs) -> size_t {
                return openBuildRef(bref,refs);
              },
              [&] (size_t dn) { bvh->scene->progressMonitor(0); },
              refs.data(),extSize,pinfo,settings);

#else
            NodeRef root = BVHBuilderBinnedSAH::build<NodeRef>(
              typename BVH::CreateAlloc(bvh),
              typename BVH::AlignedNode::Create2(),
              typename BVH::AlignedNode::Set2(),

              [&] (const BVHBuilderBinnedSAH::BuildRecord& current, FastAllocator::ThreadLocal2* alloc) -> NodeRef {
                assert(current.prims.size() == 1);
                return (NodeRef) prims[current.prims.begin()].ID();
              },
              [&] (size_t dn) { bvh->scene->progressMonitor(0); },
              prims.data(),pinfo,settings);
#endif

            bvh->set(root,LBBox3fa(pinfo.geomBounds),numPrimitives);
          }
        }
#if defined(TASKING_TBB) && defined(__AVX512ER__) && USE_TASK_ARENA // KNL
          );
#endif

      }

      bvh->alloc.cleanup();
      bvh->postBuild(t0);
#if PROFILE
      double d1 = getSeconds();
      std::cout << "TOP_LEVEL OPENING/REBUILD TIME " << 1000.0*(d1-d0) << " ms" << std::endl;
#endif
      }

    }

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::deleteGeometry(size_t geomID)
    {
      if (geomID >= objects.size()) return;
      delete builders[geomID]; builders[geomID] = nullptr;
      delete objects [geomID]; objects [geomID] = nullptr;
    }

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::clear()
    {
      for (size_t i=0; i<objects.size(); i++)
        if (objects[i]) objects[i]->clear();

      for (size_t i=0; i<builders.size(); i++)
	if (builders[i]) builders[i]->clear();

      refs.clear();
    }

    template<int N, typename Mesh>
    void BVHNBuilderTwoLevel<N,Mesh>::open_sequential(const size_t numPrimitives, const size_t maxOpenSize)
    {
      if (refs.size() == 0)
	return;

      size_t num = min(numPrimitives/400,maxOpenSize);
      DBG_PRINT(num);
      refs.reserve(num);

#if 1
      for (size_t i=0;i<refs.size();i++)
      {
        NodeRef ref = refs[i].node;
        if (ref.isAlignedNode())
          ref.prefetch();
      }
#endif

      std::make_heap(refs.begin(),refs.end());
      while (refs.size()+3 <= num)
      {
        std::pop_heap (refs.begin(),refs.end());
        NodeRef ref = refs.back().node;
        if (ref.isLeaf()) break;
        refs.pop_back();

        AlignedNode* node = ref.alignedNode();
        for (size_t i=0; i<N; i++) {
          if (node->child(i) == BVH::emptyNode) continue;
          refs.push_back(BuildRef(node->bounds(i),node->child(i)));

#if 1
          NodeRef ref_pre = node->child(i);
          if (ref_pre.isAlignedNode())
            ref_pre.prefetch();
#endif
          std::push_heap (refs.begin(),refs.end());
        }
      }
      DBG_PRINT(refs.size());
    }

#if defined(EMBREE_GEOMETRY_LINES)
    Builder* BVH4BuilderTwoLevelLineSegmentsSAH (void* bvh, Scene* scene, const createLineSegmentsAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<4,LineSegments>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_TRIANGLES)
    Builder* BVH4BuilderTwoLevelTriangleMeshSAH (void* bvh, Scene* scene, const createTriangleMeshAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<4,TriangleMesh>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_QUADS)
    Builder* BVH4BuilderTwoLevelQuadMeshSAH (void* bvh, Scene* scene, const createQuadMeshAccelTy createMeshAccel) {
    return new BVHNBuilderTwoLevel<4,QuadMesh>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_USER)
    Builder* BVH4BuilderTwoLevelVirtualSAH (void* bvh, Scene* scene, const createAccelSetAccelTy createMeshAccel) {
    return new BVHNBuilderTwoLevel<4,AccelSet>((BVH4*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(__AVX__)
#if defined(EMBREE_GEOMETRY_TRIANGLES)
    Builder* BVH8BuilderTwoLevelTriangleMeshSAH (void* bvh, Scene* scene, const createTriangleMeshAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<8,TriangleMesh>((BVH8*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_QUADS)
    Builder* BVH8BuilderTwoLevelQuadMeshSAH (void* bvh, Scene* scene, const createQuadMeshAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<8,QuadMesh>((BVH8*)bvh,scene,createMeshAccel);
    }
#endif

#if defined(EMBREE_GEOMETRY_USER)
    Builder* BVH8BuilderTwoLevelVirtualSAH (void* bvh, Scene* scene, const createAccelSetAccelTy createMeshAccel) {
      return new BVHNBuilderTwoLevel<8,AccelSet>((BVH8*)bvh,scene,createMeshAccel);
    }
#endif
#endif
  }
}
<|endoftext|>


<commit_before>#include "v3dViewFiberInteractor.h"

#include <dtkCore/dtkAbstractData.h>
#include <dtkCore/dtkAbstractDataFactory.h>
#include <dtkCore/dtkAbstractView.h>
#include <dtkCore/dtkAbstractViewFactory.h>

#include <vtkPolyData.h>
#include <vtkFibersManager.h>
#include <vtkImageView.h>

#include "v3dView.h"
#include "v3dFiberBundle.h"

#include <QInputDialog>
#include <QColorDialog>

class v3dViewFiberInteractorPrivate
{
public:
    dtkAbstractData  *data;
    v3dView          *view;
    dtkAbstractData  *projectionData;
    vtkFibersManager *manager;

    QHash<QString, dtkAbstractData*> bundleList;
    QHash<QString, v3dFiberBundle*>  v3dBundleList;
};

v3dViewFiberInteractor::v3dViewFiberInteractor(): dtkAbstractViewInteractor(), d(new v3dViewFiberInteractorPrivate)
{
	d->data = 0;
	d->view = 0;
	d->manager = vtkFibersManager::New();
	d->manager->SetHelpMessageVisibility(0);

	// addProperty here
	this->addProperty("Visibility", QStringList() << "true" << "false");
	this->addProperty("BoxVisibility", QStringList() << "true" << "false");
	this->addProperty("RenderingMode", QStringList() << "lines" << "ribbons" << "tubes");
	this->addProperty("GPUMode", QStringList() << "true" << "false");
	this->addProperty("ColorMode", QStringList() << "local" << "global" << "fa");
	this->addProperty("BoxBooleanOperation", QStringList() << "plus" << "minus");
	this->addProperty("Projection", QStringList() << "true" << "false");
}

v3dViewFiberInteractor::~v3dViewFiberInteractor()
{
    this->disable();
    QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
    while (it!=d->v3dBundleList.end()) {
      (*it)->Delete();
      ++it;
    }
    d->v3dBundleList.clear();
    d->manager->Delete();
}

QString v3dViewFiberInteractor::description(void) const
{
	return "v3dViewFiberInteractor";
}

QStringList v3dViewFiberInteractor::handled(void) const
{
	return QStringList () << "v3dView";
}

bool v3dViewFiberInteractor::registered(void)
{
    return dtkAbstractViewFactory::instance()->registerViewInteractorType("v3dViewFiberInteractor", QStringList() << "v3dView", createV3dViewFiberInteractor);
}

void v3dViewFiberInteractor::setData(dtkAbstractData *data)
{
    if (vtkPolyData *fibers = dynamic_cast<vtkPolyData *>((vtkDataObject *)(data->data()))) {
        d->manager->SetInput(fibers);
	d->data = data;
    }
}

void v3dViewFiberInteractor::setView(dtkAbstractView *view)
{
    if (v3dView *v3dview = dynamic_cast<v3dView*>(view) ) {
        d->view = v3dview;
    }
}

void v3dViewFiberInteractor::enable(void)
{
    if (d->view) {
        d->manager->SetRenderer( d->view->renderer3D() );
	d->manager->SetRenderWindowInteractor( d->view->interactor() );
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    d->view->renderer3D()->AddViewProp ( (*it)->GetActor() );
	}
    }
    dtkAbstractViewInteractor::enable();
}

void v3dViewFiberInteractor::disable(void)
{
    if (d->view) {
        d->manager->SetRenderer( 0 );
	d->manager->SetRenderWindowInteractor( 0 );
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	  d->view->renderer3D()->RemoveViewProp ( (*it)->GetActor() );
	}
    }
    dtkAbstractViewInteractor::disable();
}

void v3dViewFiberInteractor::onPropertySet(QString key, QString value)
{
    if (key=="Visibility")
        this->onVisibilityPropertySet (value);

    if (key=="BoxVisibility")
        this->onBoxVisibilityPropertySet (value);

    if (key=="RenderingMode")
        this->onRenderingModePropertySet (value);

    if (key=="GPUMode")
        this->onGPUModePropertySet (value);

    if (key=="ColorMode")
        this->onColorModePropertySet (value);

    if (key=="BoxBooleanOperation")
        this->onBoxBooleanOperationPropertySet (value);

    if (key=="Projection")
        this->onProjectionPropertySet (value);

    if (d->view)
        d->view->update();
}

void v3dViewFiberInteractor::onVisibilityPropertySet (QString value)
{
    if (value=="true")
        d->manager->SetVisibility(1);
    else
        d->manager->SetVisibility(0);
}

void v3dViewFiberInteractor::onBoxVisibilityPropertySet (QString value)
{
    if (value=="true")
        d->manager->SetBoxWidget(1);
    else
        d->manager->SetBoxWidget(0);
}

void v3dViewFiberInteractor::onRenderingModePropertySet (QString value)
{
    if (value=="lines") {
        d->manager->SetRenderingModeToPolyLines();
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->SetRenderingModeToPolyLines ();
	    ++it;
	}
    }

    if (value=="ribbons") {
	d->manager->SetRenderingModeToRibbons();
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->SetRenderingModeToRibbons ();
	    ++it;
	}
    }

    if (value=="tubes") {
        d->manager->SetRenderingModeToTubes();
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->SetRenderingModeToTubes ();
	    ++it;
	}
    }
}

void v3dViewFiberInteractor::onGPUModePropertySet (QString value)
{
    if (value=="true") {
        vtkFibersManager::UseHardwareShadersOn();
	d->manager->ChangeMapperToUseHardwareShaders();

	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->UseHardwareShadersOn ();
	    ++it;
	}
    }
    else {
        vtkFibersManager::UseHardwareShadersOff();
	d->manager->ChangeMapperToDefault();

	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->UseHardwareShadersOff ();
	    ++it;
	}
    }
}

void v3dViewFiberInteractor::onColorModePropertySet (QString value)
{
    if (value=="local")
        d->manager->SetColorModeToLocalFiberOrientation();

    if (value=="global")
        d->manager->SetColorModelToGlobalFiberOrientation();

    if (value=="fa")
        d->manager->SetColorModeToPointArray(1);
}

void v3dViewFiberInteractor::onBoxBooleanOperationPropertySet (QString value)
{
    if (value=="plus")
        d->manager->GetVOILimiter()->SetBooleanOperationToAND();

    if (value=="minus")
        d->manager->GetVOILimiter()->SetBooleanOperationToNOT();

    d->manager->GetVOILimiter()->Modified();
}

void v3dViewFiberInteractor::onSelectionTagged(void)
{
    d->manager->SwapInputOutput();
}

void v3dViewFiberInteractor::onSelectionReset(void)
{
    d->manager->Reset();
}

void v3dViewFiberInteractor::onSelectionValidated(void)
{
    if (d->manager->GetCallbackOutput()->GetNumberOfLines()==0)
        return;

    bool ok;
    QString text;
    if (d->view)
      text = QInputDialog::getText(d->view->widget(), tr("Enter bundle name"),
				   tr(""), QLineEdit::Normal, tr(""), &ok);
    else
      text = QInputDialog::getText(0, tr("Enter bundle name"),
				   tr(""), QLineEdit::Normal, tr(""), &ok);

    if (ok && !text.isEmpty())
      if (dtkAbstractData *data = dtkAbstractDataFactory::instance()->create ("vtkDataFibers")) {
	  data->setData ( d->manager->GetCallbackOutput() );
	  d->bundleList.insert (text, data);
/*
	  QColorDialog *cdialog = new QColorDialog(Qt::white, d->view->widget());
	  cdialog->exec();
	  QColor color = cdialog->selectedColor();
 */
	  //QColor color = QColorDialog::getColor(Qt::white, d->view->widget()); // buggy on Mac

		  QColor color = QColor::fromHsv(qrand()%360, 255, 210);
	  float color_d[3] = {(float)color.red()/255.0, (float)color.green()/255.0, (float)color.blue()/255.0};
	  //float color_d[3] = {(float)qrand()/(float)RAND_MAX, (float)qrand()/(float)RAND_MAX, (float)qrand()/(float)RAND_MAX};

	  v3dFiberBundle* fiberBundle = v3dFiberBundle::New();
	  fiberBundle->SetName ( text.toAscii().constData() );
	  fiberBundle->SetColor (color_d);
	  fiberBundle->SetFiberColors ( d->manager->GetInput()->GetPointData()->GetScalars() );
	  fiberBundle->SetPoints ( d->manager->GetInput()->GetPoints() );
	  fiberBundle->SetCells ( d->manager->GetSelectedCells() );
	  fiberBundle->SetUseHardwareShaders ( vtkFibersManager::GetUseHardwareShaders() );
	  fiberBundle->SetRenderingMode( vtkFibersManager::GetRenderingMode() );
	  fiberBundle->Create();

	  d->v3dBundleList.insert (text, fiberBundle);

	  if (d->view && d->view->renderer3D())
	      d->view->renderer3D()->AddViewProp ( fiberBundle->GetActor() );

	  emit selectionValidated (text);
      }
}

void v3dViewFiberInteractor::onProjectionPropertySet(QString value)
{
    if (!d->view)
        return;

      if (value=="true") {
	  d->view->viewAxial()->AddDataSet( d->manager->GetCallbackOutput() );
	  d->view->viewSagittal()->AddDataSet( d->manager->GetCallbackOutput() );
	  d->view->viewCoronal()->AddDataSet( d->manager->GetCallbackOutput() );
      }
}

void v3dViewFiberInteractor::onRadiusSet (int value)
{
    d->manager->SetRadius (value);
    QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
    while (it!=d->v3dBundleList.end()) {
        (*it)->SetRadius (value);
	++it;
    }
}

// /////////////////////////////////////////////////////////////////
// Type instanciation
// /////////////////////////////////////////////////////////////////

dtkAbstractViewInteractor *createV3dViewFiberInteractor(void)
{
    return new v3dViewFiberInteractor;
}
<commit_msg>Do not enable interactor if it is already enabled<commit_after>#include "v3dViewFiberInteractor.h"

#include <dtkCore/dtkAbstractData.h>
#include <dtkCore/dtkAbstractDataFactory.h>
#include <dtkCore/dtkAbstractView.h>
#include <dtkCore/dtkAbstractViewFactory.h>

#include <vtkPolyData.h>
#include <vtkFibersManager.h>
#include <vtkImageView.h>

#include "v3dView.h"
#include "v3dFiberBundle.h"

#include <QInputDialog>
#include <QColorDialog>

class v3dViewFiberInteractorPrivate
{
public:
    dtkAbstractData  *data;
    v3dView          *view;
    dtkAbstractData  *projectionData;
    vtkFibersManager *manager;

    QHash<QString, dtkAbstractData*> bundleList;
    QHash<QString, v3dFiberBundle*>  v3dBundleList;
};

v3dViewFiberInteractor::v3dViewFiberInteractor(): dtkAbstractViewInteractor(), d(new v3dViewFiberInteractorPrivate)
{
	d->data = 0;
	d->view = 0;
	d->manager = vtkFibersManager::New();
	d->manager->SetHelpMessageVisibility(0);

	// addProperty here
	this->addProperty("Visibility", QStringList() << "true" << "false");
	this->addProperty("BoxVisibility", QStringList() << "true" << "false");
	this->addProperty("RenderingMode", QStringList() << "lines" << "ribbons" << "tubes");
	this->addProperty("GPUMode", QStringList() << "true" << "false");
	this->addProperty("ColorMode", QStringList() << "local" << "global" << "fa");
	this->addProperty("BoxBooleanOperation", QStringList() << "plus" << "minus");
	this->addProperty("Projection", QStringList() << "true" << "false");
}

v3dViewFiberInteractor::~v3dViewFiberInteractor()
{
    this->disable();
    QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
    while (it!=d->v3dBundleList.end()) {
      (*it)->Delete();
      ++it;
    }
    d->v3dBundleList.clear();
    d->manager->Delete();
}

QString v3dViewFiberInteractor::description(void) const
{
	return "v3dViewFiberInteractor";
}

QStringList v3dViewFiberInteractor::handled(void) const
{
	return QStringList () << "v3dView";
}

bool v3dViewFiberInteractor::registered(void)
{
    return dtkAbstractViewFactory::instance()->registerViewInteractorType("v3dViewFiberInteractor", QStringList() << "v3dView", createV3dViewFiberInteractor);
}

void v3dViewFiberInteractor::setData(dtkAbstractData *data)
{
    if (vtkPolyData *fibers = dynamic_cast<vtkPolyData *>((vtkDataObject *)(data->data()))) {
        d->manager->SetInput(fibers);
	d->data = data;
    }
}

void v3dViewFiberInteractor::setView(dtkAbstractView *view)
{
    if (v3dView *v3dview = dynamic_cast<v3dView*>(view) ) {
        d->view = v3dview;
    }
}

void v3dViewFiberInteractor::enable(void)
{
	if (this->enabled())
		return;

    if (d->view) {
        d->manager->SetRenderer( d->view->renderer3D() );
	d->manager->SetRenderWindowInteractor( d->view->interactor() );
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    d->view->renderer3D()->AddViewProp ( (*it)->GetActor() );
	}
    }
    dtkAbstractViewInteractor::enable();
}

void v3dViewFiberInteractor::disable(void)
{
	if (!this->enabled())
		return;

    if (d->view) {
        d->manager->SetRenderer( 0 );
	d->manager->SetRenderWindowInteractor( 0 );
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	  d->view->renderer3D()->RemoveViewProp ( (*it)->GetActor() );
	}
    }
    dtkAbstractViewInteractor::disable();
}

void v3dViewFiberInteractor::onPropertySet(QString key, QString value)
{
    if (key=="Visibility")
        this->onVisibilityPropertySet (value);

    if (key=="BoxVisibility")
        this->onBoxVisibilityPropertySet (value);

    if (key=="RenderingMode")
        this->onRenderingModePropertySet (value);

    if (key=="GPUMode")
        this->onGPUModePropertySet (value);

    if (key=="ColorMode")
        this->onColorModePropertySet (value);

    if (key=="BoxBooleanOperation")
        this->onBoxBooleanOperationPropertySet (value);

    if (key=="Projection")
        this->onProjectionPropertySet (value);

    if (d->view)
        d->view->update();
}

void v3dViewFiberInteractor::onVisibilityPropertySet (QString value)
{
    if (value=="true")
        d->manager->SetVisibility(1);
    else
        d->manager->SetVisibility(0);
}

void v3dViewFiberInteractor::onBoxVisibilityPropertySet (QString value)
{
    if (value=="true")
        d->manager->SetBoxWidget(1);
    else
        d->manager->SetBoxWidget(0);
}

void v3dViewFiberInteractor::onRenderingModePropertySet (QString value)
{
    if (value=="lines") {
        d->manager->SetRenderingModeToPolyLines();
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->SetRenderingModeToPolyLines ();
	    ++it;
	}
    }

    if (value=="ribbons") {
	d->manager->SetRenderingModeToRibbons();
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->SetRenderingModeToRibbons ();
	    ++it;
	}
    }

    if (value=="tubes") {
        d->manager->SetRenderingModeToTubes();
	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->SetRenderingModeToTubes ();
	    ++it;
	}
    }
}

void v3dViewFiberInteractor::onGPUModePropertySet (QString value)
{
    if (value=="true") {
        vtkFibersManager::UseHardwareShadersOn();
	d->manager->ChangeMapperToUseHardwareShaders();

	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->UseHardwareShadersOn ();
	    ++it;
	}
    }
    else {
        vtkFibersManager::UseHardwareShadersOff();
	d->manager->ChangeMapperToDefault();

	QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
	while (it!=d->v3dBundleList.end()) {
	    (*it)->UseHardwareShadersOff ();
	    ++it;
	}
    }
}

void v3dViewFiberInteractor::onColorModePropertySet (QString value)
{
    if (value=="local")
        d->manager->SetColorModeToLocalFiberOrientation();

    if (value=="global")
        d->manager->SetColorModelToGlobalFiberOrientation();

    if (value=="fa")
        d->manager->SetColorModeToPointArray(1);
}

void v3dViewFiberInteractor::onBoxBooleanOperationPropertySet (QString value)
{
    if (value=="plus")
        d->manager->GetVOILimiter()->SetBooleanOperationToAND();

    if (value=="minus")
        d->manager->GetVOILimiter()->SetBooleanOperationToNOT();

    d->manager->GetVOILimiter()->Modified();
}

void v3dViewFiberInteractor::onSelectionTagged(void)
{
    d->manager->SwapInputOutput();
}

void v3dViewFiberInteractor::onSelectionReset(void)
{
    d->manager->Reset();
}

void v3dViewFiberInteractor::onSelectionValidated(void)
{
    if (d->manager->GetCallbackOutput()->GetNumberOfLines()==0)
        return;

    bool ok;
    QString text;
    if (d->view)
      text = QInputDialog::getText(d->view->widget(), tr("Enter bundle name"),
				   tr(""), QLineEdit::Normal, tr(""), &ok);
    else
      text = QInputDialog::getText(0, tr("Enter bundle name"),
				   tr(""), QLineEdit::Normal, tr(""), &ok);

    if (ok && !text.isEmpty())
      if (dtkAbstractData *data = dtkAbstractDataFactory::instance()->create ("vtkDataFibers")) {
	  data->setData ( d->manager->GetCallbackOutput() );
	  d->bundleList.insert (text, data);
/*
	  QColorDialog *cdialog = new QColorDialog(Qt::white, d->view->widget());
	  cdialog->exec();
	  QColor color = cdialog->selectedColor();
 */
	  //QColor color = QColorDialog::getColor(Qt::white, d->view->widget()); // buggy on Mac

		  QColor color = QColor::fromHsv(qrand()%360, 255, 210);
	  float color_d[3] = {(float)color.red()/255.0, (float)color.green()/255.0, (float)color.blue()/255.0};
	  //float color_d[3] = {(float)qrand()/(float)RAND_MAX, (float)qrand()/(float)RAND_MAX, (float)qrand()/(float)RAND_MAX};

	  v3dFiberBundle* fiberBundle = v3dFiberBundle::New();
	  fiberBundle->SetName ( text.toAscii().constData() );
	  fiberBundle->SetColor (color_d);
	  fiberBundle->SetFiberColors ( d->manager->GetInput()->GetPointData()->GetScalars() );
	  fiberBundle->SetPoints ( d->manager->GetInput()->GetPoints() );
	  fiberBundle->SetCells ( d->manager->GetSelectedCells() );
	  fiberBundle->SetUseHardwareShaders ( vtkFibersManager::GetUseHardwareShaders() );
	  fiberBundle->SetRenderingMode( vtkFibersManager::GetRenderingMode() );
	  fiberBundle->Create();

	  d->v3dBundleList.insert (text, fiberBundle);

	  if (d->view && d->view->renderer3D())
	      d->view->renderer3D()->AddViewProp ( fiberBundle->GetActor() );

	  emit selectionValidated (text);
      }
}

void v3dViewFiberInteractor::onProjectionPropertySet(QString value)
{
    if (!d->view)
        return;

      if (value=="true") {
	  d->view->viewAxial()->AddDataSet( d->manager->GetCallbackOutput() );
	  d->view->viewSagittal()->AddDataSet( d->manager->GetCallbackOutput() );
	  d->view->viewCoronal()->AddDataSet( d->manager->GetCallbackOutput() );
      }
}

void v3dViewFiberInteractor::onRadiusSet (int value)
{
    d->manager->SetRadius (value);
    QHash<QString, v3dFiberBundle*>::iterator it = d->v3dBundleList.begin();
    while (it!=d->v3dBundleList.end()) {
        (*it)->SetRadius (value);
	++it;
    }
}

// /////////////////////////////////////////////////////////////////
// Type instanciation
// /////////////////////////////////////////////////////////////////

dtkAbstractViewInteractor *createV3dViewFiberInteractor(void)
{
    return new v3dViewFiberInteractor;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <string.h>
#include <rtl/ustring.hxx>
#include <sal/macros.h>

#include <windows.h>

#define KEY_ESC         0x10000
#define KEY_BACK        0xE0000
#define KEY_ENTER       0x1C0000
#define KEY_SPACEBAR    0x390000
#define KEY_HOME        0x1470000
#define KEY_UP          0x1480000
#define KEY_PAGEUP      0x1490000
#define KEY_LEFT        0x14B0000
#define KEY_RIGHT       0x14D0000
#define KEY_END         0x14F0000
#define KEY_DOWN        0x1500000
#define KEY_PAGEDOWN    0x1510000
#define KEY_INSERT      0x1520000
#define KEY_DELETE      0x1530000
#define KEY_CONTROL     0x21D0000
#define KEY_SHIFT       0x22A0000
#define KEY_ALT         0x2380000

namespace vcl_sal {

    struct KeysNameReplacement
    {
        LONG            aSymbol;
        const char*     pName;
    };

    struct KeyboardReplacements
    {
        const char*                     pLangName;
        const KeysNameReplacement*      pReplacements;
        int                             nReplacements;
    };

    // ====================================================================
    //
    // CAUTION CAUTION CAUTION
    // every string value in the replacements tables must be in UTF8
    // be careful with your editor !
    //
    // ====================================================================

    static const struct KeysNameReplacement aImplReplacements_Catalan[] =
    {
        { KEY_BACK, "Retrocés" },
        { KEY_ENTER, "Retorn" },
        { KEY_SPACEBAR, "Espai" },
        { KEY_HOME, "Inici" },
        { KEY_UP, "Amunt" },
        { KEY_PAGEUP, "Re Pàg" },
        { KEY_LEFT, "Esquerra" },
        { KEY_RIGHT, "Dreta" },
        { KEY_END, "Fi" },
        { KEY_DOWN, "Avall" },
        { KEY_PAGEDOWN, "Av Pàg" },
        { KEY_INSERT, "Ins" },
        { KEY_DELETE, "Supr" },
        { KEY_SHIFT, "Maj" },
    };

    static const struct KeyboardReplacements aKeyboards[] =
    {
        { "ca", aImplReplacements_Catalan, SAL_N_ELEMENTS(aImplReplacements_Catalan) },
    };

    // translate keycodes, used within the displayed menu shortcuts
    rtl::OUString getKeysReplacementName( rtl::OUString pLang, LONG nSymbol )
    {
        for( unsigned int n = 0; n < SAL_N_ELEMENTS(aKeyboards); n++ )
        {
            if( pLang.equalsAscii( aKeyboards[n].pLangName ) )
            {
                const struct KeysNameReplacement* pRepl = aKeyboards[n].pReplacements;
                for( int m = aKeyboards[n].nReplacements ; m ; )
                {
                    if( nSymbol == pRepl[--m].aSymbol )
                        return rtl::OUString( pRepl[m].pName, strlen(pRepl[m].pName), RTL_TEXTENCODING_UTF8 );
                }
            }
        }

        return rtl::OUString();
    }

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>fdo#54165: Add key replacement names for Estonian (Patch by: Mihkel Tõnnov)<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <string.h>
#include <rtl/ustring.hxx>
#include <sal/macros.h>

#include <windows.h>

#define KEY_ESC         0x10000
#define KEY_BACK        0xE0000
#define KEY_ENTER       0x1C0000
#define KEY_SPACEBAR    0x390000
#define KEY_HOME        0x1470000
#define KEY_UP          0x1480000
#define KEY_PAGEUP      0x1490000
#define KEY_LEFT        0x14B0000
#define KEY_RIGHT       0x14D0000
#define KEY_END         0x14F0000
#define KEY_DOWN        0x1500000
#define KEY_PAGEDOWN    0x1510000
#define KEY_INSERT      0x1520000
#define KEY_DELETE      0x1530000
#define KEY_CONTROL     0x21D0000
#define KEY_SHIFT       0x22A0000
#define KEY_ALT         0x2380000

namespace vcl_sal {

    struct KeysNameReplacement
    {
        LONG            aSymbol;
        const char*     pName;
    };

    struct KeyboardReplacements
    {
        const char*                     pLangName;
        const KeysNameReplacement*      pReplacements;
        int                             nReplacements;
    };

    // ====================================================================
    //
    // CAUTION CAUTION CAUTION
    // every string value in the replacements tables must be in UTF8
    // be careful with your editor !
    //
    // ====================================================================

    static const struct KeysNameReplacement aImplReplacements_Catalan[] =
    {
        { KEY_BACK, "Retrocés" },
        { KEY_ENTER, "Retorn" },
        { KEY_SPACEBAR, "Espai" },
        { KEY_HOME, "Inici" },
        { KEY_UP, "Amunt" },
        { KEY_PAGEUP, "Re Pàg" },
        { KEY_LEFT, "Esquerra" },
        { KEY_RIGHT, "Dreta" },
        { KEY_END, "Fi" },
        { KEY_DOWN, "Avall" },
        { KEY_PAGEDOWN, "Av Pàg" },
        { KEY_INSERT, "Ins" },
        { KEY_DELETE, "Supr" },
        { KEY_SHIFT, "Maj" },
    };

    static const struct KeysNameReplacement aImplReplacements_Estonian[] =
    {
        { KEY_RIGHT, "Nool paremale" },
        { KEY_LEFT, "Nool vasakule" },
        { KEY_UP, "Nool üles" },
        { KEY_DOWN, "Nool alla" },
        { KEY_BACK, "Tagasilüke" },
        { KEY_ENTER, "Enter" },
        { KEY_SPACEBAR, "Tühik" },
    };

    static const struct KeyboardReplacements aKeyboards[] =
    {
        { "ca", aImplReplacements_Catalan, SAL_N_ELEMENTS(aImplReplacements_Catalan) },
        { "et", aImplReplacements_Estonian, SAL_N_ELEMENTS(aImplReplacements_Estonian) },
    };

    // translate keycodes, used within the displayed menu shortcuts
    rtl::OUString getKeysReplacementName( rtl::OUString pLang, LONG nSymbol )
    {
        for( unsigned int n = 0; n < SAL_N_ELEMENTS(aKeyboards); n++ )
        {
            if( pLang.equalsAscii( aKeyboards[n].pLangName ) )
            {
                const struct KeysNameReplacement* pRepl = aKeyboards[n].pReplacements;
                for( int m = aKeyboards[n].nReplacements ; m ; )
                {
                    if( nSymbol == pRepl[--m].aSymbol )
                        return rtl::OUString( pRepl[m].pName, strlen(pRepl[m].pName), RTL_TEXTENCODING_UTF8 );
                }
            }
        }

        return rtl::OUString();
    }

}

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