Skip to content
OE_display.cpp 11.4 KiB
Newer Older
/*
 * Copyright (c) 2015 Tricoire Sebastien 3dsman@free.fr
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 */

#include "OE_display.h"
#include "OE_utils.h"

#include "OE_controller.h"


#include <iostream>

#include <GL/gl.h>
#include <cstdlib>
#include <math.h>
#include <cstdio>
#include <cstring>
#include <algorithm>

unsigned char OE_display::lineColor[] = {0,160,192,255};
unsigned char OE_display::controlLineColor[] = {100,60,92,255};
unsigned char OE_display::controlPointColor[] = {100,60,92,255};
unsigned char OE_display::controlStartPointColor[] = {200,00,0,255};
3dsman's avatar
3dsman committed

unsigned char OE_display::stitchLineColor[] = {20,20,20,255};
unsigned char OE_display::stitchPointColor[] = {20,20,20,255};
unsigned char OE_display::stitchStartPointColor[] = {100,60,92,255};

OE_display::OE_display()
{
}

OE_display::OE_display(OE_document document)
{
}

OE_display::~OE_display()
{
}

/** \brief draw the document on screen
 *
 * \return true if all is ok
 *
 */

bool OE_display::setDocument(OE_document * document)
{
	this->document = document;
	if(document)
	{
		std::list<OE_curve*>::iterator curve = document->curves.begin();
		
		while (curve != document->curves.end())
			(*curve)->refresh(zoom/2);
			curve++;
bool OE_display::refresh()
{
	if(document)
	{
		std::list<OE_curve*>::iterator curve = document->curves.begin();
		
		while (curve != document->curves.end())
			(*curve)->refresh(zoom/2);
			curve++;
		}
		forceRefresh = false;
		return true;
	}
	return false;
}

void OE_display::mouse_Pos(double x, double y)
{
	if (pan)
	{
		cx = cx + (mouseX-x)*zoom*2;
		cy = cy + (mouseY-y)*zoom*2;
	}
    mouseX = x;
    mouseY = y;
}
void OE_display::mouse_Button(int button, int action, int mods)
{
	if (button == GLFW_MOUSE_BUTTON_MIDDLE)
    {
        if (action == GLFW_PRESS)
            pan = true;
        else
            pan = false;
    }
}
void OE_display::scroll(double xoffset, double yoffset)
{
    if(!pan){
        if (yoffset>0)
        zoom = zoom/1.1;
        else
        zoom = zoom*1.1;
		
		forceRefresh = true;
    }	
}
void OE_display::resize(int width, int height)
{
	this->width = width;
	this->height = height;
}

/** \brief move and zoom to see the entire document
 */

void OE_display::showAll()
{
	if (document)
	{
	
		float xMin,yMin,xMax,yMax;
		document->getBound(&xMin,&yMin,&xMax,&yMax);
		cx = (xMax + xMin)/2;
		cy = (yMax + yMin)/2;
		
        zoom = maxf((xMax - xMin)/width/1.5,(yMax - yMin)/height/1.5);
		
		forceRefresh = true;
	}

}

/** \brief draw the document on screen
 *
 * \return true if all is ok
 *
 */

bool OE_display::draw()
{
	//dpi = zoom/2;
	float wzoom, hzoom;
	
	glViewport(0, 0, width, height);
	glClearColor(220.0f/255.0f, 220.0f/255.0f, 220.0f/255.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glDisable(GL_TEXTURE_2D);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	wzoom = (float)width*zoom;
	hzoom = (float)height*zoom;

	glOrtho(cx-wzoom, cx+wzoom, cy+hzoom, cy-hzoom, -1, 1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glDisable(GL_DEPTH_TEST);
	glColor4ub(255,255,255,255);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

		
	//draw 0
	glLineWidth(1.5);
	glBegin(GL_LINE_STRIP);
		glColor4d(0,0,0,1);
		glVertex2f(-10,0);
		glVertex2f(0,10);
		
		glVertex2f(10,0);
		glVertex2f(0,-10);
		
		glVertex2f(-10,0);
	glEnd();
		glBegin(GL_LINES);
		glColor4d(0,0,0,1);
		glVertex2f(-10,0);
		glVertex2f(10,0);
		
		glVertex2f(0,-10);
		glVertex2f(0,10);
	glEnd();
		
		
		
		if (forceRefresh) 
			refresh();
			
		//std::cout<<"nb curves "<<document->curves.size()<<std::endl;
		//for (unsigned i = 0; i < document->curves.size(); i++) 
		//{
		std::list<OE_curve*>::iterator curve = document->curves.begin();
		
		while (curve != document->curves.end())
		curve = document->selectedCurves.begin();
		while (curve != document->selectedCurves.end())
		//for (unsigned i = 0; i < document->selectedCurves.size(); i++) 
		//{
			drawCurveControl( (*curve));
			curve++;
		//std::cout<<"nb stitch "<<document->stitchs.size()<<std::endl;
		//for (unsigned i = 0; i < document->stitchs.size(); i++) 
		//{
		std::list<OE_stitchs*>::iterator stitch = document->stitchs.begin();
		
		while (stitch != document->stitchs.end())
		stitch = document->selectedStitchs.begin();
		//for (unsigned i = 0; i < document->selectedStitchs.size(); i++) 
		while (stitch != document->selectedStitchs.end())
			drawStitchControl((*stitch));
			stitch++;
3dsman's avatar
3dsman committed
		}
	}
	return true;
}

/** \brief draw a stitch on screen
 *
 * \return true if all is ok
 *
 */

bool OE_display::drawStitch(OE_stitchs * stitch)
	if(stitch->check()&&stitch->getNpts()>0)
3dsman's avatar
3dsman committed
		// Points
3dsman's avatar
3dsman committed
		glColor4ubv(stitchPointColor);
		glBegin(GL_POINTS);

		for (i = 1; i < stitch->pts.size(); i++) {
			glVertex2f(stitch->pts.at(i).x,stitch->pts.at(i).y);
		}
		glEnd();
		
		//draw lines
		glLineWidth(1.5);
		glBegin(GL_LINE_STRIP);
		OE_thread * thread = stitch->getThread();
		if (thread)
			glColor4ubv(thread->getColor());
		else
			glColor4ubv(stitchLineColor);
			for (i = 0; i < stitch->pts.size(); i++) {
				glVertex2f(stitch->pts.at(i).x,stitch->pts.at(i).y);
			}
		glEnd();
3dsman's avatar
3dsman committed
			
		
		// start point

		glColor4ubv(stitchStartPointColor);
		glPointSize(5.0f);
		glBegin(GL_POINTS);
		glVertex2f(stitch->pts[0].x,stitch->pts[0].y);
		glEnd();

/** \brief draw a triangle */
void OE_display::drawTriangle(vector_2d point1, vector_2d point2, float size)
{
	
			glBegin(GL_TRIANGLE_FAN);
			vector_2d dir  = point2 - point1;
			dir.normalize();
			dir = dir*zoom*size;
			
			vector_2d lat  = dir;
			lat.turnRight();
			
			point1 = point1 - dir;
			vector_2d p1 = dir*2+point1;
			glVertex2f(p1.x,p1.y);
			p1 = point1+lat;
			glVertex2f(p1.x,p1.y);
			p1 = point1+dir/2;
			glVertex2f(p1.x,p1.y);
			p1 = point1-lat;
			glVertex2f(p1.x,p1.y);
			glEnd();
}


/** \brief draw a curve on screen
 *
 * \return true if all is ok
 *
 */

bool OE_display::drawCurve(OE_curve * curve)
{
	if (curve->check())
		if (curve->getNeedRefresh()) curve->refresh(zoom/2);
		unsigned i;
		//draw curves
		glLineWidth(1.5);
		glBegin(GL_LINE_STRIP);
		glColor4ubv(lineColor);
		
		for (i = 0; i < curve->discPts.size(); i++) {
				glVertex2f(curve->discPts.at(i).x,curve->discPts.at(i).y);
		if (curve->getClosed()) {
			glVertex2f(curve->discPts.at(0).x, curve->discPts.at(0).y);
		//draw curve points
		if(0)
		{
			glPointSize(3.0f);
			glBegin(GL_POINTS);
			glVertex2f(curve->discPts[0].x, curve->discPts[0].y);
			for (i = 0; i < curve->discPts.size(); i++) {
					glVertex2f(curve->discPts.at(i).x, curve->discPts.at(i).y);
			}
			if (curve->getClosed()) {
				glVertex2f(curve->discPts[0].x, curve->discPts[0].y);
			}
			glEnd();
		return true;
	}
	return false;
}


/** \brief draw the curve controls on screen
 *
 * \return true if all is ok
 *
 */

bool OE_display::drawCurveControl(OE_curve * curve)
{
	if (curve->check())
	{
		if (OE_pointcurve * tmpcurve = dynamic_cast<OE_pointcurve*> (curve))
		{
			// Tangeant lines
			glLineWidth(1.5);
			glColor4ubv(controlLineColor);
			glBegin(GL_LINES);
			for (unsigned i = 0; i < tmpcurve->pts.size()-3; i += 3) {
				vector_2d* p = &tmpcurve->pts[i];
				glVertex2f(p[0].x,p[0].y);
				glVertex2f(p[1].x,p[1].y);
				glVertex2f(p[2].x,p[2].y);
				glVertex2f(p[3].x,p[3].y);
			}
			glEnd();
			
			// Points
			glPointSize(4.0f);
			//glColor4ubv(controlEndPointColor);
			glBegin(GL_POINTS);
			glColor4ubv(controlPointColor);
			for (unsigned i = 0; i < tmpcurve->pts.size()-3; i += 3) {
				vector_2d* p = &tmpcurve->pts[i];
				glVertex2f(p[0].x,p[0].y);
			}
			// tangeant end points
			glPointSize(3.0f);
			glColor4ubv(controlPointColor);
			for (unsigned i = 0; i < curve->pts.size()-3; i += 3) {
				vector_2d* p = &curve->pts[i];
				glVertex2f(p[1].x,p[1].y);
				glVertex2f(p[2].x,p[2].y);
			}
			// start point & direction
			if(1)
			{
				/*glColor4f(1.0,0.0,0.0,1.0);
				glPointSize(2.0f);
				glBegin(GL_POINTS);
				glVertex2f(curve->pts[0].x,curve->pts[0].y);
				glEnd();*/
				glColor4ubv(controlStartPointColor);
				drawTriangle(curve->pts[0], curve->pts[1], 13);
				
				glLineWidth(2);
				glBegin(GL_LINES);
				vector_2d p  = curve->pts[1] - curve->pts[0];
				p.normalize();
				p = p+curve->pts[0];
				glVertex2f(curve->pts[0].x,curve->pts[0].y);
				//glVertex2f(curve->pts[1].x,curve->pts[1].y);
				glVertex2f(p.x,p.y);
				glEnd();
			}
			return true;
		}
		
		//if this curve is a joincurve
		
		if (OE_joincurve * joincurve = dynamic_cast<OE_joincurve*> (curve))
		{
			std::list<OE_curve*>::iterator curve = joincurve->curves.begin();
			while (curve != joincurve->curves.end())
				glBegin(GL_LINE_STRIP);
				glColor4ubv(controlLineColor);
				
				for (unsigned i = 0; i < tmpcurve->discPts.size(); i++) {
						glVertex2f(tmpcurve->discPts.at(i).x,tmpcurve->discPts.at(i).y);
				}
				glEnd();
				if (tmpcurve->discPts.size()>1)
				{
					glColor4ubv(controlStartPointColor);
					drawTriangle(tmpcurve->pts[0], tmpcurve->pts[1], 13);
				}
			
			}
			return true;
		}
		
		//if this curve is a subcurve
		
		if (OE_subcurve * subcurve = dynamic_cast<OE_subcurve*> (curve))
		{
			
			glColor4ubv(controlPointColor);
			glBegin(GL_POINTS);
			glVertex2f(subcurve->pts[0].x,subcurve->pts[0].y);
			glVertex2f(subcurve->pts[subcurve->getNpts()-1].x,subcurve->pts[subcurve->getNpts()-1].y);
			glEnd();
			// start point & direction			
			glColor4ubv(controlStartPointColor);
			drawTriangle(subcurve->pts[0], subcurve->pts[1], 13);
				
				
			return true;
	return false;
}

/** \brief draw the stitchs controls on screen
 *
 * \return true if all is ok
 *
 */

bool OE_display::drawStitchControl(OE_stitchs * stitch)
{
	
	if (stitch->check())
	{
		if (OE_linestitch * linestitch = dynamic_cast<OE_linestitch*> (stitch))
		{
			return true;
		}
		
		if (OE_birailstitch * birailstitch = dynamic_cast<OE_birailstitch*> (stitch))
		{
			return true;
		}
		
		if (OE_linkstitch * linkstitch = dynamic_cast<OE_linkstitch*> (stitch))
		{
			// step stitchs
			glPointSize(3.0f);
			glColor4ubv(controlPointColor);
			glBegin(GL_POINTS);

			for (unsigned i = 0; i < linkstitch->stepPts.size(); i++) {
				vector_2d* p = &linkstitch->stepPts[i];
				glVertex2f(p[1].x,p[1].y);
			}
			glEnd();
			return true;
		}
	}
	return false;
}