/* * 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 //float OE_display::cx, OE_display::cy = 0.0; vector_2d OE_display::viewPos; float OE_display::zoom = 1.0; //int OE_display::mouseX, OE_display::mouseY, OE_display::mouseXInit, OE_display::mouseYInit = -1; bool OE_display::pan = false; int OE_display::width, OE_display::height = 0; OE_display::OE_display() { } OE_display::OE_display(OE_document* document, OE_controller* controller, OE_displayStyle* style) { this->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++; } }*/ refreshAll(); return true; } bool OE_display::setController(OE_controller* controller) { this->controller = controller; return true; } bool OE_display::setDisplayStyle(OE_displayStyle* style) { this->style = style; return true; } bool OE_display::refreshAll() { if (document) { std::list::iterator curve = document->curves.begin(); while (curve != document->curves.end()) { (*curve)->refresh(zoom/2, !changeDpi); curve++; } std::list::iterator stitch = document->stitchs.begin(); while (stitch != document->stitchs.end()) { (*stitch)->refresh(zoom/2, !changeDpi); stitch++; } if (controller) controller->generateInstructions(); changeDpi = false; return true; } return false; } /** \brief draw the move gizmo * * \return true if all is ok * */ bool OE_display::drawSelectionTools(bool select) { vector_2d min = selectionBounds.getMin(); vector_2d max = selectionBounds.getMax(); float crossSize = zoom*style->moveCrossSize; float boxOffset = zoom*style->moveCrossSize; min.x -= boxOffset; min.y -= boxOffset; max.x += boxOffset; max.y += boxOffset; if (selectionBounds.init) { if (select) { glTranslatef(min.x, min.y, 0); glPushName(0); //id of the move tool glBegin(GL_QUADS); style->selectionBoundColor.gl(); //glColor4d(1, 0, 0, 1); glVertex2f(crossSize*1.0f, 0); glVertex2f(0, crossSize*1.0f); glVertex2f(-crossSize*1.0f, 0); glVertex2f(0, -crossSize*1.0f); glEnd(); glPopName(); glPushName(1); //id of the scale tool glBegin(GL_QUADS); glVertex2f(-crossSize*0.5f, -crossSize*0.5f); glVertex2f(-crossSize*0.5f, -crossSize*1.5f); glVertex2f(-crossSize*1.5f, -crossSize*1.5f); glVertex2f(-crossSize*1.5f, -crossSize*0.5f); glEnd(); glPopName(); glTranslatef(-min.x, -min.y, 0); } else { //draw selection bound glLineWidth(1.5); glBegin(GL_LINE_LOOP); style->selectionBoundColor.gl(); glVertex2f(min.x, min.y); glVertex2f(min.x, max.y); glVertex2f(max.x, max.y); glVertex2f(max.x, min.y); glEnd(); glTranslatef(min.x, min.y, 0); //draw move cross glBegin(GL_TRIANGLES); style->transformGizmoColor.gl(); glVertex2f(-crossSize*0.6f, -crossSize*0.1f); glVertex2f(-crossSize*0.6f, crossSize*0.1f); glVertex2f(crossSize*0.6f, crossSize*0.1f); glVertex2f(crossSize*0.6f, crossSize*0.1f); glVertex2f(-crossSize*0.6f, -crossSize*0.1f); glVertex2f(crossSize*0.6f, -crossSize*0.1f); glVertex2f(crossSize*0.6f, crossSize*0.3f); glVertex2f(crossSize*1.0f, 0); glVertex2f(crossSize*0.6f, -crossSize*0.3f); glVertex2f(-crossSize*0.6f, crossSize*0.3f); glVertex2f(-crossSize*1.0f, 0); glVertex2f(-crossSize*0.6f, -crossSize*0.3f); glVertex2f(-crossSize*0.1f, -crossSize*0.6f); glVertex2f(crossSize*0.1f, -crossSize*0.6f); glVertex2f(crossSize*0.1f, crossSize*0.6f); glVertex2f(crossSize*0.1f, crossSize*0.6f); glVertex2f(-crossSize*0.1f, -crossSize*0.6f); glVertex2f(-crossSize*0.1f, crossSize*0.6f); glVertex2f(crossSize*0.3f, crossSize*0.6f); glVertex2f(0, crossSize*1.0f); glVertex2f(-crossSize*0.3f, crossSize*0.6f); glVertex2f(crossSize*0.3f, -crossSize*0.6f); glVertex2f(0, -crossSize*1.0f); glVertex2f(-crossSize*0.3f, -crossSize*0.6f); glEnd(); //draw scale icon glBegin(GL_TRIANGLES); style->transformGizmoColor.gl(); glVertex2f(-crossSize*1.5f, -crossSize*1.2f); glVertex2f(-crossSize*0.6f, -crossSize*0.55f); glVertex2f(-crossSize*0.55f, -crossSize*0.6f); glVertex2f(-crossSize*1.5f, -crossSize*1.2f); glVertex2f(-crossSize*0.5f, -crossSize*0.55f); glVertex2f(-crossSize*1.2f, -crossSize*1.5f); glVertex2f(-crossSize*0.5f, -crossSize*0.5f); glVertex2f(-crossSize*0.85f, -crossSize*0.5f); glVertex2f(-crossSize*0.5f, -crossSize*0.85f); glVertex2f(-crossSize*1.5f, -crossSize*1.5f); glVertex2f(-crossSize*1.5f, -crossSize*0.9f); glVertex2f(-crossSize*0.9f, -crossSize*1.5f); glEnd(); glTranslatef(-min.x, -min.y, 0); } return true; } return false; } /** \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 stitch on screen * * \return true if all is ok * */ bool OE_display::drawStitch(OE_stitchs* stitch, int curpoint) { //stitch->refresh(zoom/2); if (!stitch->check() || !style->drawStitches || stitch->getNpts()==0) { return false; } std::vector points = stitch->getPoints(); unsigned i; // Points glPointSize(style->stitchPointSize); glBegin(GL_POINTS); if (curpoint>0) { style->stitchPointBeforeCurrentColor.gl(); } else { style->stitchPointAfterCurrentColor.gl(); } for (i = 1; i < points.size(); i++) { if (curpoint==i) { style->stitchPointAfterCurrentColor.gl(); } glVertex2f(points.at(i).x, points.at(i).y); } glEnd(); //draw lines glLineWidth(style->stitchLineWidth); glBegin(GL_LINE_STRIP); OE_thread* thread = stitch->getThread(); if (thread) { thread->getColor().gl(); } else { style->stitchLineBeforeCurrentColor.gl(); } for (i = 0; i < points.size(); i++) { glVertex2f(points.at(i).x, points.at(i).y); } glEnd(); // start point style->stitchStartPointColor.gl(); glPointSize(style->stitchStartPointSize); glBegin(GL_POINTS); glVertex2f(points.at(0).x, points.at(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() || !style->drawCurves) { return false; } /*if (curve->getNeedRefresh()) { curve->refresh(zoom/2); }*/ unsigned i; //draw curves glLineWidth(style->curveWidth); glBegin(GL_LINE_STRIP); style->curveColor.gl(); for (i = 0; i < curve->discPts.size(); i++) { glVertex2f(curve->discPts.at(i).v.x, curve->discPts.at(i).v.y); } if (curve->getClosed()) { glVertex2f(curve->discPts.at(0).v.x, curve->discPts.at(0).v.y); } glEnd(); if (!curve->getClosed()) { glPointSize(style->curveStartPointSize); glBegin(GL_POINTS); glVertex2f(curve->discPts.at(0).v.x, curve->discPts.at(0).v.y); glVertex2f(curve->discPts.at(curve->discPts.size()-1).v.x, curve->discPts.at(curve->discPts.size()-1).v.y); glEnd(); } /* glPointSize(5.0f); glColor3d(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); vector_2dt point = curve->closestPoint(vector_2d (absMouseX, absMouseY)); glVertex2f(point.v.x, point.v.y); glEnd(); */ //draw curve points if (style->drawCurvePoints) { glPointSize(style->curvePointSize); glBegin(GL_POINTS); glVertex2f(curve->discPts[0].v.x, curve->discPts[0].v.y); for (i = 0; i < curve->discPts.size(); i++) { glColor3d(curve->discPts.at(i).t/((double)curve->pts.size()/3.0f), 0.0f, 0.0f); glVertex2f(curve->discPts.at(i).v.x, curve->discPts.at(i).v.y); } if (curve->getClosed()) { glVertex2f(curve->discPts[0].v.x, curve->discPts[0].v.y); } glEnd(); } return true; } /** \brief draw the curve controls on screen * * \return true if all is ok * */ bool OE_display::drawCurveControl(OE_curve* curve, bool select) { if (!curve->check() || !style->drawCurves || !style->drawCurveControls) { return false; } OE_pointcurve* tmpcurve = dynamic_cast (curve); if (tmpcurve) { if (select) { // Points glPointSize(4.0f); glPushName(0); //init the controller type index glPushName(0); //init the controller points index for (unsigned i = 0; i < tmpcurve->pts.size(); i++) { glLoadName(i); //vector_2d* p = &tmpcurve->pts[i]; glBegin(GL_POINTS); glVertex2f(tmpcurve->pts[i].x, tmpcurve->pts[i].y); glEnd(); } glPopName(); glPopName(); } else { // Tangeant lines glLineWidth(1.5); style->curveTangeantColor.gl(); 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(style->curvePointSize); //glColor4ubv(controlEndPointColor); glBegin(GL_POINTS); style->curvePointColor.gl(); 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(style->curvePointSize); style->curvePointColor.gl(); 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 /*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();*/ style->curveStartPointColor.gl(); 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 OE_joincurve* joincurve = dynamic_cast (curve); if (joincurve) { std::list::iterator curve = joincurve->curves.begin(); if (!select) { while (curve != joincurve->curves.end()) { OE_curve* tmpcurve = (*curve); glLineWidth(3); glBegin(GL_LINE_STRIP); style->curveTangeantColor.gl(); for (unsigned i = 0; i < tmpcurve->discPts.size(); i++) { glVertex2f(tmpcurve->discPts.at(i).v.x, tmpcurve->discPts.at(i).v.y); } glEnd(); if (tmpcurve->discPts.size()>1) { style->curveStartPointColor.gl(); drawTriangle(tmpcurve->pts[0], tmpcurve->pts[1], 13); } curve++; } } return true; } //if this curve is a subcurve OE_subcurve* subcurve = dynamic_cast (curve); if (subcurve) { if (select) { // Points glPointSize(4.0f); glPushName(0); //init the controller type index glPushName(0); //init the controller points index glBegin(GL_POINTS); glVertex2f(subcurve->pts[0].x, subcurve->pts[0].y); glEnd(); glLoadName(1); glBegin(GL_POINTS); glVertex2f(subcurve->pts[subcurve->getNpts()-1].x, subcurve->pts[subcurve->getNpts()-1].y); glEnd(); glPopName(); glPopName(); } else { style->curvePointColor.gl(); 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 style->curveStartPointColor.gl(); drawTriangle(subcurve->pts[0], subcurve->pts[1], 13); } return true; } } bool OE_display::drawJoincurveControl(OE_joincurve* curve, bool select) { if (select) { for (unsigned i = 0; i < curve->curves.size(); i++) { OE_subcurve* subcurve = curve->getCurve(i); glLoadName(i*2+1); glBegin(GL_POINTS); glVertex2f(subcurve->pts[0].x, subcurve->pts[0].y); glEnd(); glLoadName(i*2); glBegin(GL_POINTS); glVertex2f(subcurve->pts[subcurve->getNpts()-1].x, subcurve->pts[subcurve->getNpts()-1].y); glEnd(); } } else { for (unsigned i = 0; i < curve->curves.size(); i++) { OE_subcurve* subcurve = curve->getCurve(i); // draw the subcurves glLineWidth(2); glBegin(GL_LINE_STRIP); style->curveTangeantColor.gl(); for (unsigned i = 0; i < subcurve->discPts.size(); i++) { glVertex2f(subcurve->discPts.at(i).v.x, subcurve->discPts.at(i).v.y); } glEnd(); // draw the subcurves controls style->curveStartPointColor.gl(); glPointSize(6.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 style->curveStartPointColor.gl(); drawTriangle(subcurve->pts[0], subcurve->pts[1], 13); } } } /** \brief draw the stitchs controls on screen * * \return true if all is ok * */ bool OE_display::drawStitchControl(OE_stitchs* stitch, bool select) { if (!stitch->check() || !style->drawStitches || !style->drawStitchControl) { return false; } OE_linestitch* linestitch = dynamic_cast (stitch); if (linestitch) { OE_joincurve* joinCurve = linestitch->getJoincurve(); vector_2d dir = joinCurve->pts[1] - joinCurve->pts[0]; dir.normalize(); dir.turnRight(); vector_2d scaleDir = dir*zoom*10; dir = scaleDir * 10+ joinCurve->pts[0]; if (select) { // Points glPointSize(4.0f); glPushName(0); //init the controller type index glPushName(0); //init the controller points index if (linestitch->getJoincurve()) { drawJoincurveControl(linestitch->getJoincurve(), true); } glPopName(); glLoadName(1); glPushName(0); //init the controller points index glBegin(GL_TRIANGLES); glVertex2f(dir.x-scaleDir.y+scaleDir.x/3, dir.y+scaleDir.x+scaleDir.y/3); glVertex2f(dir.x+scaleDir.x*2, dir.y+scaleDir.y*2); glVertex2f(dir.x+scaleDir.y+scaleDir.x/3, dir.y-scaleDir.x+scaleDir.y/3); glVertex2f(dir.x+scaleDir.y-scaleDir.x/3, dir.y-scaleDir.x-scaleDir.y/3); glVertex2f(dir.x-scaleDir.x*2, dir.y-scaleDir.y*2); glVertex2f(dir.x-scaleDir.y-scaleDir.x/3, dir.y+scaleDir.x-scaleDir.y/3); glEnd(); glPopName(); glPopName(); } else { glLineWidth(2); glBegin(GL_LINE_STRIP); style->stitchLineBeforeCurrentColor.gl(); glVertex2f(joinCurve->pts[0].x, joinCurve->pts[0].y); glVertex2f(dir.x, dir.y); glEnd(); drawJoincurveControl(joinCurve, false); glBegin(GL_TRIANGLES); style->stitchStartPointColor.gl(); glVertex2f(dir.x-scaleDir.y+scaleDir.x/3, dir.y+scaleDir.x+scaleDir.y/3); glVertex2f(dir.x+scaleDir.x*2, dir.y+scaleDir.y*2); glVertex2f(dir.x+scaleDir.y+scaleDir.x/3, dir.y-scaleDir.x+scaleDir.y/3); glVertex2f(dir.x+scaleDir.y-scaleDir.x/3, dir.y-scaleDir.x-scaleDir.y/3); glVertex2f(dir.x-scaleDir.x*2, dir.y-scaleDir.y*2); glVertex2f(dir.x-scaleDir.y-scaleDir.x/3, dir.y+scaleDir.x-scaleDir.y/3); glEnd(); } return true; } OE_birailstitch* birailstitch = dynamic_cast (stitch); if (birailstitch) { if (select) { // Points glPointSize(4.0f); glPushName(0); //init the controller type index glPushName(0); //init the controller points index drawJoincurveControl(birailstitch->getJoincurve1(), true); glPopName(); glLoadName(1); glPushName(0); //init the controller points index drawJoincurveControl(birailstitch->getJoincurve2(), true); glPopName(); glPopName(); } else { drawJoincurveControl(birailstitch->getJoincurve1(), false); drawJoincurveControl(birailstitch->getJoincurve2(), false); } return true; } OE_linkstitch* linkstitch = dynamic_cast (stitch); if (linkstitch) { const float uiSize = zoom * 7; const float uiDistance = zoom * 17; if (select) { glPushName(0); //init the controller type index as points glPushName(0); //init the controller points index glPointSize(4.0f); int index = 0; for (auto stepPt : linkstitch->stepPts) { glBegin(GL_POINTS); glVertex2f(stepPt.x, stepPt.y); glEnd(); glLoadName(++index); } glPopName(); glLoadName(1); //init the controller type index as add glPushName(0); //init the controller points index glPointSize(4.0f); std::vector points = linkstitch->getPoints(); vector_2d prevVert = points.at(0); vector_2d p; index = 0; std::list::iterator stepPt = linkstitch->stepPts.begin(); while (stepPt != linkstitch->stepPts.end()) { p = (*stepPt + prevVert)/2; glBegin(GL_POINTS); glVertex2f(p.x, p.y); glEnd(); prevVert = *stepPt; stepPt++; glLoadName(++index); } glLoadName(index); p = (points.at(points.size()-1) + prevVert)/2; glBegin(GL_POINTS); glVertex2f(p.x, p.y); glEnd(); glPopName(); glLoadName(2); //init the controller type index as delete glPushName(0); //init the controller points index index = 0; for (auto stepPt : linkstitch->stepPts) { glBegin(GL_LINES); glVertex2f(stepPt.x-uiSize+uiDistance, stepPt.y-uiDistance); glVertex2f(stepPt.x+uiSize+uiDistance, stepPt.y-uiDistance); glEnd(); glLoadName(++index); } glPopName(); glPopName(); } else { glLineWidth(2.5); glPointSize(5.0f); style->stitchStartPointColor.gl(); for (auto stepPt : linkstitch->stepPts) { glBegin(GL_POINTS); glVertex2f(stepPt.x, stepPt.y); glEnd(); style->stitchStartPointColor.gl(); glBegin(GL_LINES); glVertex2f(stepPt.x-uiSize+uiDistance, stepPt.y-uiDistance); glVertex2f(stepPt.x+uiSize+uiDistance, stepPt.y-uiDistance); glEnd(); } style->stitchStartPointColor.gl(); glBegin(GL_LINES); std::vector points = linkstitch->getPoints(); vector_2d prevVert = points.at(0); vector_2d p; std::list::iterator stepPt = linkstitch->stepPts.begin(); while (stepPt != linkstitch->stepPts.end()) { p = (*stepPt + prevVert)/2; glVertex2f(p.x-uiSize, p.y); glVertex2f(p.x+uiSize, p.y); glVertex2f(p.x, p.y+uiSize); glVertex2f(p.x, p.y-uiSize); prevVert = *stepPt; stepPt++; } p = (points.at(points.size()-1) + prevVert)/2; glVertex2f(p.x-uiSize, p.y); glVertex2f(p.x+uiSize, p.y); glVertex2f(p.x, p.y+uiSize); glVertex2f(p.x, p.y-uiSize); glEnd(); } return true; } } /** \brief draw the instruction points * * \return true if all is ok * */ bool OE_display::drawCommands() { float scaleRatio = document->getPulseByMm(); if (document->instPoints.size() == 0) { return false; } unsigned i; // Points glPointSize(style->instPointSize); glBegin(GL_POINTS); style->instLineBeforeCurrentColor.gl(); for (i = 1; i < document->curPoint; i++) { glVertex2f(document->instPoints.at(i).x/scaleRatio, document->instPoints.at(i).y/scaleRatio); } style->instLineAfterCurrentColor.gl(); for (i = document->curPoint; i < document->instPoints.size(); i++) { glVertex2f(document->instPoints.at(i).x/scaleRatio, document->instPoints.at(i).y/scaleRatio); } glEnd(); //draw lines unsigned pt = 0; OE_color curcolor; glLineWidth(style->instLineWidth); glBegin(GL_LINE_STRIP); for (i = 0; i < document->instCommand.size(); i++) { for (; pt < document->instCommand.at(i)->getIdPoint(); pt++) { if (pt == document->curPoint) { (curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.a)).gl(); } glVertex2f(document->instPoints.at(pt).x/scaleRatio, document->instPoints.at(pt).y/scaleRatio); } OE_waitcolor* color = dynamic_cast (document->instCommand.at(i)); if (color) { curcolor = color->getThreadColor(); if (pt > document->curPoint) { curcolor.gl(); } else { (curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.a)).gl(); } } OE_start* start = dynamic_cast (document->instCommand.at(i)); if (start) { curcolor = start->getThreadColor(); (curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.a)).gl(); } } for (; pt < document->instPoints.size(); pt++) { if (pt == document->curPoint) { (curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.a)).gl(); } glVertex2f(document->instPoints.at(pt).x/scaleRatio, document->instPoints.at(pt).y/scaleRatio); } glEnd(); // start point style->instStartPointColor.gl(); glPointSize(style->instStartPointSize); glBegin(GL_POINTS); glVertex2f(document->instPoints.at(0).x/scaleRatio, document->instPoints.at(0).y/scaleRatio); glEnd(); // current point if (document->curPoint < document->instPoints.size()) { style->instCurPointColor.gl(); glPointSize(style->instCurPointSize); glBegin(GL_POINTS); glVertex2f(document->instPoints.at(document->curPoint).x/scaleRatio, document->instPoints.at(document->curPoint).y/scaleRatio); glEnd(); } return true; } /** \brief draw the document on screen * * \return true if all is ok * */ bool OE_display::draw() { if (!document) { return false; } float wzoom, hzoom; glViewport(0, 0, width, height); glClearColor(style->backgroundColor.r, style->backgroundColor.g, style->backgroundColor.b, 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(); glEnd(); wzoom = (float)width*zoom; hzoom = (float)height*zoom; glOrtho(viewPos.x-wzoom, viewPos.x+wzoom, viewPos.y+hzoom, viewPos.y-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); vector_2d hoopSize = document->getHoopSize()/2; vector_2d zero = document->getZeroPoint(); //draw hoop if (style->drawHoop) { glLineWidth(3); glBegin(GL_LINE_STRIP); style->hoopColor.gl(); glVertex2f(zero.x-hoopSize.x, zero.y-hoopSize.y); glVertex2f(zero.x-hoopSize.x, zero.y+hoopSize.y); glVertex2f(zero.x+hoopSize.x, zero.y+hoopSize.y); glVertex2f(zero.x+hoopSize.x, zero.y-hoopSize.y); glVertex2f(zero.x-hoopSize.x, zero.y-hoopSize.y); glEnd(); } //draw grid if (style->drawGrid) { glLineWidth(1.5); glBegin(GL_LINES); (style->gridColor * OE_color(1, 1, 1, maxf(0.0f, 0.2f-zoom*2))).gl(); int offset = (int)-hoopSize.x; while (offsetgridColor.gl(); offset = (int)-hoopSize.x+(int)hoopSize.x%10; while (offsetdrawZero) { float zeroSize = style->zeroSize; glLineWidth(1.5); glBegin(GL_LINE_STRIP); style->zeroColor.gl(); glVertex2f(zero.x-zeroSize, zero.y); glVertex2f(zero.x, zero.y+zeroSize); glVertex2f(zero.x+zeroSize, zero.y); glVertex2f(zero.x, zero.y-zeroSize); glVertex2f(zero.x-zeroSize, zero.y); glEnd(); glBegin(GL_LINES); style->zeroColor.gl(); glVertex2f(zero.x-zeroSize, zero.y); glVertex2f(zero.x+zeroSize, zero.y); glVertex2f(zero.x, zero.y-zeroSize); glVertex2f(zero.x, zero.y+zeroSize); glEnd(); } refreshAll(); document->lock(); /*if (changeDpi) { refreshAll(); }*/ selectionBounds.init = false; if (style->drawCurves) { std::list::iterator curve = document->curves.begin(); while (curve != document->curves.end()) { drawCurve(*curve); curve++; } curve = document->selectedCurves.begin(); while (curve != document->selectedCurves.end()) { drawCurveControl(*curve); selectionBounds += (*curve)->getBound(); curve++; } } if (style->drawStitches) { std::list::iterator stitch = document->stitchs.begin(); int curpoint = document->curPoint; while (stitch != document->stitchs.end()) { drawStitch(*stitch, curpoint); curpoint -= (*stitch)->getPoints().size(); stitch++; } stitch = document->selectedStitchs.begin(); while (stitch != document->selectedStitchs.end()) { drawStitchControl(*stitch); selectionBounds += (*stitch)->getBound(); stitch++; } } if (style->drawCommands) { drawCommands(); } document->unlock(); drawSelectionTools(); return true; } bool OE_display::pick(std::list selectedCurves, std::list selectedStitches) { std::list::iterator curve; std::list::iterator stitch; int index; glViewport(0, 0, width, height); glClearColor(0.85f, 0.85f, 0.85f, 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(); glEnd(); glOrtho(absMouse.x-7*zoom, absMouse.x+7*zoom, absMouse.y+7*zoom, absMouse.y-7*zoom, -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); glRenderMode(GL_SELECT); //Init of name stack glInitNames(); glPushName(0); //id of the tools /* glPushName(0); //id of the zero tool //draw 0 vector_2d zero = document->getZeroPoint(); glPointSize(6); glBegin(GL_POINT); glVertex2f(zero.x, zero.y); glEnd(); glPopName(); */ glPushName(1); //id of the move tool drawSelectionTools(true); glPopName(); //if (changeDpi) refreshAll(); if (style->selectStitches) { glLoadName(1); //id of the stitches index = 0; glPushName(index); //init the stitches index stitch = selectedStitches.begin(); while (stitch != selectedStitches.end()) { drawStitchControl(*stitch, true); stitch++; index++; glLoadName(index); } glPopName(); } if (style->selectCurves) { glLoadName(2); //id of the curves index = 0; glPushName(index); //init the curves index curve = selectedCurves.begin(); while (curve != selectedCurves.end()) { drawCurveControl(*curve, true); curve++; index++; glLoadName(index); } glPopName(); } if (style->selectStitches) { glLoadName(1); //id of the stitches index = 0; glPushName(index); //init the stitches index int curpoint = document->curPoint; stitch = document->stitchs.begin(); while (stitch != document->stitchs.end()) { drawStitch(*stitch, curpoint); curpoint -= (*stitch)->getPoints().size(); stitch++; index++; glLoadName(index); } glPopName(); } if (style->selectCurves) { glLoadName(2); //id of the curves index = 0; glPushName(index); //init the curves index curve = document->curves.begin(); while (curve != document->curves.end()) { drawCurve(*curve); curve++; index++; glLoadName(index); } glPopName(); } } /** \brief move and zoom to see the entire document */ void OE_display::showAll() { if (document) { float xMin, yMin, xMax, yMax; BoundingBox bound = document->getBound(); viewPos.x = (bound.getMax().x + bound.getMin().x)/2; viewPos.y = (bound.getMax().y + bound.getMin().y)/2; zoom = maxf((bound.getMax().x - bound.getMin().x)/width/1.5, (bound.getMax().y - bound.getMin().y)/height/1.5); changeDpi = true; } } void OE_display::zoomSelection() { if (document&&controller) { float xMin, yMin, xMax, yMax; BoundingBox bound = controller->getSelectionBoundingBox(); viewPos.x = (bound.getMax().x + bound.getMin().x)/2; viewPos.y = (bound.getMax().y + bound.getMin().y)/2; zoom = maxf((bound.getMax().x - bound.getMin().x)/width/1.5, (bound.getMax().y - bound.getMin().y)/height/1.5); changeDpi = true; } } void OE_display::mouse_Pos(double x, double y) { if (pan) { viewPos = viewPos + (mouse-vector_2d(x, y))*zoom*2; } mouse.x = x; mouse.y = y; absMouse = viewPos+(mouse-vector_2d(width, height)/2)*zoom*2; } void OE_display::mouse_Button(int button, int action, int mods) { if (button == GLFW_MOUSE_BUTTON_MIDDLE) { pan = action == GLFW_PRESS; } } void OE_display::scroll(double xoffset, double yoffset) { if (!pan) { if (yoffset>0) { zoom = zoom/1.1; } else { zoom = zoom*1.1; } changeDpi = true; } } void OE_display::resize(int width, int height) { this->width = width; this->height = height; } void OE_display::key(int key, int scancode, int action, int mods) { } vector_2d OE_display::screenToDocument(vector_2d pos) { return viewPos+(pos-vector_2d(width, height)/2)*zoom*2; }