/* * 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 #include #include #include #include #include #include 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}; 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::iterator curve = document->curves.begin(); while (curve != document->curves.end()) { (*curve)->refresh(zoom/2); curve++; } } return true; } bool OE_display::refresh() { if(document) { std::list::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; glEnd(); 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 (document) { if (forceRefresh) refresh(); //std::cout<<"nb curves "<curves.size()<curves.size(); i++) //{ std::list::iterator curve = document->curves.begin(); while (curve != document->curves.end()) { drawCurve((*curve)); curve++; } 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 "<stitchs.size()<stitchs.size(); i++) //{ std::list::iterator stitch = document->stitchs.begin(); while (stitch != document->stitchs.end()) { drawStitch((*stitch)); stitch++; } stitch = document->selectedStitchs.begin(); //for (unsigned i = 0; i < document->selectedStitchs.size(); i++) while (stitch != document->selectedStitchs.end()) { drawStitchControl((*stitch)); stitch++; } } return true; } /** \brief draw a stitch on screen * * \return true if all is ok * */ bool OE_display::drawStitch(OE_stitchs * stitch) { stitch->refresh(); //return false; if(stitch->check()&&stitch->getNpts()>0) { unsigned i; // Points glPointSize(3.0f); 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(); // 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 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); } glEnd(); //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 (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); } glEnd(); // tangeant end points glPointSize(3.0f); glColor4ubv(controlPointColor); glBegin(GL_POINTS); 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); } glEnd(); // 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 (curve)) { std::list::iterator curve = joincurve->curves.begin(); while (curve != joincurve->curves.end()) { OE_curve * tmpcurve = (*curve); glLineWidth(3); 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); } curve++; } return true; } //if this curve is a subcurve if (OE_subcurve * subcurve = dynamic_cast (curve)) { glColor4ubv(controlPointColor); glPointSize(5.0f); 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 (stitch)) { return true; } if (OE_birailstitch * birailstitch = dynamic_cast (stitch)) { return true; } if (OE_linkstitch * linkstitch = dynamic_cast (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; }