Skip to content
main.cpp 7.5 KiB
Newer Older
3dsman's avatar
3dsman committed
#include <stdio.h>
#include <string.h>
#include <float.h>
#include <GLFW/glfw3.h>
#include <algorithm>

#include "main.h"
3dsman's avatar
3dsman committed
#include "OE_document.h"
#include "OE_svgParser.h"
#include "OE_controller.h"
#include "actions/OE_actionsSelection.h"
3dsman's avatar
3dsman committed
#include <iostream>
#include <chrono>
#include <thread>

// TODO: fix qwerty mapping
// TODO: handlers, qui a besoin de qui et quand, pas de redondance ? chemins les + simples ?
// TODO: lock pour la modif, histoire de péter tout le backend sans que l'ihm explose
raoul's avatar
raoul committed
// TODO: list les features présentes et à venir, disons jusqu'à la v1.0 alpha pour commencer
// TODO MF: intégration/merge avec autre doc, gaffe aux scaling, normalisation générale des coords pour nos fichiers ?
// TODO: stitch de remplissage de formes
// TODO: rotation des selections
// TODO: creation des groupes
// TODO: export des .pes
// TODO: edition des motifs
// TODO: set des motifs des linestitchs avec miniature
3dsman's avatar
3dsman committed
// TODO: echelle dans la vue (cm/mm)
3dsman's avatar
3dsman committed


// liste des bugs identifiés a corriger
// TODO bug dans OE_interfaceDisplay::selectApply la selection ne clear qu'un seul type (curve ou stitch) quand on selection uniquement des objets de l'autre type
// TODO bug dans les selections avec ajout sur les stitchs

3dsman's avatar
3dsman committed
//#include "nanosvg.h"

//NSVGimage* g_image = NULL;
3dsman's avatar
3dsman committed

//static unsigned char bgColor[4] = {205,202,200,255};
3dsman's avatar
3dsman committed

void drawframe(GLFWwindow* window)
{
	//NSVGshape* shape;
	//NSVGpath* path;

	OE_root* root = (OE_root*)glfwGetWindowUserPointer(window);

3dsman's avatar
3dsman committed
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
	if (root->display)
		root->display->draw();
3dsman's avatar
3dsman committed
	glfwSwapBuffers(window);
}

static void OE_Mouse_Pos_Callback(GLFWwindow* window, double x, double y)
3dsman's avatar
3dsman committed
{
	OE_root* root = (OE_root*)glfwGetWindowUserPointer(window);
	if (root->display)
		root->display->mouse_Pos(x, y);
3dsman's avatar
3dsman committed
}

static void OE_Mouse_Button_Callback(GLFWwindow* window, int button, int action, int mods)
3dsman's avatar
3dsman committed
{
	OE_root* root = (OE_root*)glfwGetWindowUserPointer(window);
	if (root->display)
		root->display->mouse_Button(button, action, mods);
3dsman's avatar
3dsman committed
}

static void OE_Mouse_Scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
3dsman's avatar
3dsman committed
{
	OE_root* root = (OE_root*)glfwGetWindowUserPointer(window);
	if (root->display)
		root->display->scroll(xoffset, yoffset);
3dsman's avatar
3dsman committed
}

static void OE_Key_callback(GLFWwindow* window,  int key, int scancode, int action, int mods)
	OE_root* root = (OE_root*)glfwGetWindowUserPointer(window);
	if (root->display)
		root->display->key(key, scancode, action, mods);
static void OE_Drop_callback(GLFWwindow* window,  int nbFiles, const char ** files)
{
	OE_root* root = (OE_root*)glfwGetWindowUserPointer(window);
	if ((!root->document)||(nbFiles<=0)) return;

	std::string path(*files);
	size_t dot = path.find_last_of(".");
	if (dot == std::string::npos) return;

	std::string ext  = path.substr(dot, path.size() - dot);
	if (ext == ".oe")
	{
		printf("Importing oe file from %s\n", path.c_str());
		OE_document* tmp_doc = new OE_document;
		delete root->document;
		root->document = tmp_doc;
		root->document->loadFromFile(path);

	}
	if (ext == ".pes")
	{
		printf("Importing pes file from %s\n", path.c_str());
		OE_document* tmp_doc = new OE_document;
		delete root->document;
		root->document = tmp_doc;
		root->document->loadFromPES(path);
	}
	if (ext == ".svg")
	{
		printf("Importing svg file from %s\n", path.c_str());
		OE_document* tmp_doc = OE_svgParser::fromFile(path, "px", 96.0f);
		// Center document around (0,0)
		BoundingBox bb = tmp_doc->getBound();
		for (auto curve : tmp_doc->curves)
		{
			curve->move(vector_2d(0,0)-bb.getCenter());
		}
		// Rescale document if larger than hoop
		bb = tmp_doc->getBound();
		float docW = bb.getMax().x-bb.getMin().x;
		float docH = bb.getMax().y-bb.getMin().y;
		float hoopW = tmp_doc->getHoopSize().x;
		float hoopH = tmp_doc->getHoopSize().y;
		if (docW > hoopW || docH > hoopH)
		{
			float ratio = nanf("");
			if (docW >= docH && docW != 0.0f)
			{
				ratio = hoopW / (docW);
			}
			else if (docW < docH && docH != 0.0f)
			{
				ratio = hoopH / (docH);
			}
			{
				for (auto curve : tmp_doc->curves)
				{
					curve->scale(vector_2d(ratio, ratio), bb.getCenter());
				}
			}
		}
		if (tmp_doc != NULL) {
			delete root->document;
			root->document = tmp_doc;

		}else{
			printf("Could not open SVG image.\n");
		}
	}

	if (root->controller)
	{
		root->controller->setDocument(root->document);
		root->controller->initNewDocument();
	}

	if (root->display)
	{
		root->display->setDocument(root->document);
		root->display->showAll();
	}
static void OE_Window_Resize_callback(GLFWwindow* window, int, int)
3dsman's avatar
3dsman committed
{
	OE_root* root = (OE_root*)glfwGetWindowUserPointer(window);
	if (root->display)
	{
		int width = 0, height = 0;
		glfwGetFramebufferSize(window, &width, &height);
		root->display->resize(width, height);
3dsman's avatar
3dsman committed
}

raoul's avatar
raoul committed
#include <sstream>
void showFPS(GLFWwindow *pWindow)
{
	static unsigned nbFrames = 0;
	static double lastTime = 0;
	double currentTime = glfwGetTime();
	double delta = currentTime - lastTime;
	nbFrames++;
	if ( delta >= 1.0 ) {
		double fps = double(nbFrames) / delta;

		std::stringstream ss;
		ss << "Open embroider" << " [" << fps << " FPS]";

		glfwSetWindowTitle(pWindow, ss.str().c_str());

		nbFrames = 0;
		lastTime = currentTime;
	}
}

void startMain()
{
#ifdef SWINGING
	int mainIhm();
	std::thread newThread(mainIhm);
	newThread.detach();
#endif
}

#ifdef SWINGING
int mainIhm()
#else
3dsman's avatar
3dsman committed
int main()
3dsman's avatar
3dsman committed
{
	GLFWwindow* window;
	const GLFWvidmode* mode;

	std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();
#define SHOWTIME() printf("%u: %ldms\n",\
                          __LINE__,\
                          std::chrono::duration_cast<std::chrono::milliseconds>(\
                            std::chrono::high_resolution_clock::now()-t0).count())
3dsman's avatar
3dsman committed
	if (!glfwInit())
		return -1;

	//SHOWTIME();
3dsman's avatar
3dsman committed
	mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
	window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Open embroidery", NULL, NULL);
3dsman's avatar
3dsman committed
	if (!window)
	{
		printf("Could not open window : %s\n", strerror(errno));
3dsman's avatar
3dsman committed
		glfwTerminate();
		return -1;
	}
	glfwSetWindowUserPointer(window, &root);
3dsman's avatar
3dsman committed

	//SHOWTIME();
3dsman's avatar
3dsman committed

	glfwSetFramebufferSizeCallback(window, OE_Window_Resize_callback);
	glfwSetCursorPosCallback(window, OE_Mouse_Pos_Callback);
	glfwSetMouseButtonCallback(window, OE_Mouse_Button_Callback);
	glfwSetScrollCallback(window, OE_Mouse_Scroll_callback);
	glfwSetKeyCallback(window, OE_Key_callback);
	glfwSetDropCallback(window, OE_Drop_callback);
	//SHOWTIME();

	// Enable sticky keys
	glfwSetInputMode(window, GLFW_STICKY_KEYS, true);

	// Disable vertical sync (on cards that support it)
	glfwSwapInterval( 1 );
3dsman's avatar
3dsman committed

	glfwMakeContextCurrent(window);
	glEnable(GL_POINT_SMOOTH);
	glEnable(GL_LINE_SMOOTH);

	//SHOWTIME();
	root.document = new OE_document();
	root.interfaceDisplay = new OE_interfaceDisplay();
	root.interfaceDisplay->setDocument(root.document);
	root.display = root.interfaceDisplay;

	root.controller = new OE_controller(root.display, root.document);

	if ((root.controller == NULL)||(root.display == NULL) ) {
		glfwTerminate();
		return -1;
	}
	root.display->setController(root.controller);
	{
		int width = 0, height = 0;
		glfwGetFramebufferSize(window, &width, &height);
		root.display->resize(width, height);
		root.display->draw();
		root.display->showAll();
	//SHOWTIME();
3dsman's avatar
3dsman committed

	while (!glfwWindowShouldClose(window))
	{
		drawframe(window);
		glfwPollEvents();
raoul's avatar
raoul committed
		showFPS(window);
3dsman's avatar
3dsman committed
	}

	glfwTerminate();
	return 0;
}