Skip to content
OE_display.cpp 8.18 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 <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};
3dsman's avatar
3dsman committed
unsigned char OE_display::controlEndPointColor[] = {100,60,92,255};

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)
	{
		for (unsigned i = 0; i < document->curves.size(); i++) 
		{
			document->curves.at(i)->refresh(zoom/2);
bool OE_display::refresh()
{
	if(document)
	{
		for (unsigned i = 0; i < document->curves.size(); i++) 
		{
			document->curves.at(i)->refresh(zoom/2);
		}
		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();
		float xMin,yMin,xMax,yMax;
		document->getBound(&xMin,&yMin,&xMax,&yMax);
		 
		std::cout<<xMin<< " "<<yMin<< " "<<xMax<< " "<<yMax<<std::endl;
		//draw lines
		glLineWidth(1.5);
		glBegin(GL_LINE_STRIP);
			glColor4ubv(stitchLineColor);
			glVertex2f(xMin,yMin);
			glVertex2f(xMax,yMin);
			
			glVertex2f(xMax,yMax);
			glVertex2f(xMin,yMax);
			
			glVertex2f(xMin,yMin);
			
		//std::cout<<"nb curves "<<document->curves.size()<<std::endl;
		for (unsigned i = 0; i < document->curves.size(); i++) 
		{
			drawCurve(document->curves.at(i));
		//std::cout<<"nb stitch "<<document->stitchs.size()<<std::endl;
3dsman's avatar
3dsman committed
		for (unsigned i = 0; i < document->stitchs.size(); i++) 
		{
			drawStitchs(document->stitchs.at(i));
3dsman's avatar
3dsman committed
		}
	}
	return true;
}

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

bool OE_display::drawStitchs(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();

	}
	return true;
}


/** \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();
			
		//draw controls
		if (controls)
	   {
			// Tangeant lines
			glLineWidth(1.5);
			glColor4ubv(controlLineColor);
			glBegin(GL_LINES);
			for (i = 0; i < curve->pts.size()-3; i += 3) {
				vector_2d* p = &curve->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 (i = 0; i < curve->pts.size()-3; i += 3) {
				vector_2d* p = &curve->pts[i];
				glVertex2f(p[0].x,p[0].y);
			}
			// tangeant end points
			glPointSize(3.0f);
			glColor4ubv(controlPointColor);

			for (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();
				
				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;
	return false;