Skip to content
Commits on Source (14)
......@@ -49,51 +49,7 @@ class OE_display : public QOpenGLWidget, protected QOpenGLFunctions_2_0
public:
class OE_displayStyle
{
public:
//OE_Color hoopColor = OE_Color(0.0, 0.0, 0.0, .5);
OE_color hoopColor = OE_color(0.0, 0.0, 0.0, .5);
OE_color backgroundColor = OE_color(0.85, 0.85, 0.85, 1.0);
OE_color cursorColor = OE_color(0.0, 0.0, 0.0, 0.3);
OE_color gridColor = OE_color(0.0, 0.0, 0.0, 0.1);
OE_color zeroColor = OE_color(0.0, 0.0, 0.0, 1.0);
float zeroSize = 3;
OE_color curveColor = OE_color(0,.63,.75,1.0);
OE_color curveTangeantColor = OE_color(.39,.235,.36,1.0);
OE_color curvePointColor = OE_color(.39,.235,.36,1.0);
OE_color curveControlsColor = OE_color(.78,0,0,1.0);
float curveWidth = 1.5;
float curveTangeantWidth = 1.5;
float curvePointSize = 3.0;
float curveStartPointSize = 5.0;
OE_color stitchLineBeforeCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color stitchLineAfterCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color stitchPointBeforeCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color stitchPointAfterCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color stitchStartPointColor = OE_color(.39,.235,.36,1.0);
OE_color stitchControlsColor = OE_color(.78,0,0,1.0);
float stitchPointSize = 3.0;
float stitchLineWidth = 1.5;
float stitchStartPointSize = 5.0;
OE_color instLineBeforeCurrentColor = OE_color(0,.63,.75,.3);
OE_color instLineAfterCurrentColor = OE_color(0,.63,.75,1.0);
OE_color instStartPointColor = OE_color(.39,.23,.36,1.0);
OE_color instCurPointColor = OE_color(.78,.2,.2,1.0);
OE_color instColor = OE_color(.39,.23,.36,1.0);
float instPointSize = 3.0;
float instLineWidth = 1.5;
float instStartPointSize = 5.0;
float instCurPointSize = 5.0;
OE_color machineStartPointColor;
OE_color machineCurPointColor;
OE_color transformGizmoColor = OE_color(1,0,0,1);
OE_color selectionBoundColor = OE_color(1,0,0,1);
public:
bool drawHoop = true;
bool drawGrid = true;
......@@ -110,7 +66,6 @@ class OE_display : public QOpenGLWidget, protected QOpenGLFunctions_2_0
bool selectCurves = true;
bool selectStitches = true;
float moveCrossSize = 30;
OE_displayStyle(){}
};
......
......@@ -44,8 +44,6 @@ class OE_document
};
bool saveToFile(std::string path);
bool loadFromFile(std::string path);
bool loadFromPES(std::string path);
static OE_document* newFromSvg(const std::string& path);
/** Default constructor */
OE_document();
......@@ -79,7 +77,6 @@ class OE_document
/** \brief the array of commands to send to the embroideress */
std::vector<OE_instruction*> instCommand;
/** \brief the stack of active actions */
std::list<OE_actions*> activeActionsStack;
......@@ -90,7 +87,7 @@ class OE_document
/** \brief the current points stitched by the embroideress */
unsigned int curPoint = 0;
BoundingBox getBound();
BoundingBox getBound() const;
vector_2d getHoopSize();
unsigned int getPulsePerMm();
......@@ -113,6 +110,9 @@ class OE_document
bool trylock(); // try to lock write, return true on success
void unlock(); // unlock write
static std::string getWriteDialogFilters();
static std::string getReadDialogFilters();
private:
/** \brief Width of the document. */
float width;
......
......@@ -49,6 +49,9 @@ class OE_interfaceDisplay : public OE_display
OE_document* getDocument();
OE_controller* getController();
virtual bool setDisplayStyle(unsigned int displayStyleId);
OE_display::OE_displayStyle* addDisplayStyle();
virtual void showAll();
virtual bool mouse_Pos(double x, double y);
......@@ -70,12 +73,7 @@ class OE_interfaceDisplay : public OE_display
bool selectApply(std::list<OE_pointcurve*> selectedCurves, std::list<OE_stitchs*> selectedStitches);
bool draw();
private:
enum screen
{
edit,
command,
};
private:
enum State
{
......@@ -94,11 +92,7 @@ class OE_interfaceDisplay : public OE_display
ScaleLenLinestitch,
};
OE_display::OE_displayStyle* editStyle = NULL;
OE_display::OE_displayStyle* commandStyle = NULL;
//OE_display* curDisplay = NULL;
screen curScreen = edit;
std::vector<OE_display::OE_displayStyle*> displayStyles;
std::list<OE_pointcurve*> selectedCurves;
std::list<OE_stitchs*> selectedStitches;
......
/*
* 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.
*
*/
#pragma once
#include "xml/tinyxml.h"
#include "OE_utils.h"
#include "OE_document.h"
class OE_svgParser
{
public:
/** Parse a svg file */
static OE_document * fromFile(const std::string filename, const char* units, float dpi);
private:
/** Default constructor */
OE_svgParser();
char id[64]; // Optional 'id' attr of the curve or its group
float opacity; // Opacity of the curve.
float strokeWidth; // Stroke width (scaled).
char strokeLineJoin; // Stroke join type.
char strokeLineCap; // Stroke cap type.
float bounds[4]; // Tight bounding box of the curve [minx,miny,maxx,maxy].
OE_document* document;
static float sqr(float x);
static float vmag(float x, float y);
static float vecrat(float ux, float uy, float vx, float vy);
static float vecang(float ux, float uy, float vx, float vy);
static void xformPoint(float* dx, float* dy, float x, float y, float* t);
static void xformVec(float* dx, float* dy, float x, float y, float* t);
int isspace(char c);
int isdigit(char c);
int isnum(char c);
const char* parseNumber(const char* s, char* it, const int size);
const char* getNextPathItem(const char* s, char* it);
/**return the number of arguments for a specified command**/
int getArgsPerElement(char cmd);
void pathMoveTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
void pathLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
void pathHLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
void pathVLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
void pathCubicBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
void pathCubicBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
void pathQuadBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
void pathQuadBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
void pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
/** Draw the paths */
bool parsePath(TiXmlElement* input);
bool parseSvg(TiXmlElement* input);
bool pushCurve(OE_pointcurve* curve);
OE_Matrix matrix;
};
......@@ -189,10 +189,18 @@ class OE_color
return QColor(rgba[0]*255,rgba[1]*255,rgba[2]*255,rgba[3]*255);
}
inline OE_color operator *( const OE_color color)
inline OE_color operator *( const OE_color& color)
{
return OE_color(rgba[0]*color.rgba[0], rgba[1]*color.rgba[1], rgba[2]*color.rgba[2], rgba[3]*color.rgba[3]);
}
inline bool operator ==( const OE_color& color)
{
return memcmp(&rgba[0], &color.rgba[0], sizeof(rgba)) == 0;
}
inline bool operator !=( const OE_color& color)
{
return !(*this == color);
}
void persist(Pakal::Archive* archive)
{
......
......@@ -3,6 +3,7 @@
#include <cstdint>
#include <QSerialPort>
#include <QByteArray>
#include <QList>
#include <QTimer>
struct OE_document;
......@@ -60,7 +61,7 @@ private:
void handleReadyRead();
void handleError(QSerialPort::SerialPortError serialPortError);
void handleAliveTimeout();
void sendCommand(Command cmd, uint8_t len=1);
void sendCommand(Command cmd, uint8_t len=1, bool async=false);
void onMsg(uint8_t* buffer);
public:
SlaveInfo info;
......@@ -73,6 +74,9 @@ private:
uint8_t sequenceAck;
QByteArray msgBuffer;
QByteArray cmdBuffer;
QList<uint8_t> loadQueue;
int loadAck;
uint32_t loadSize;
unsigned msTimeout;
unsigned retries;
};
......@@ -50,7 +50,7 @@ class OE_stitchs : public OE_base
bool getPoint(uint16_t nb, vector_2d* pt);
/** \brief return a copy of the array of points*/
std::vector<vector_2d> getPoints();
const std::vector<vector_2d>& getPoints();
/** \brief return the number of points in the stitch (control points, without handles) */
int getNpts();
......
#include "src/qt/mainwindow.h"
#include <QApplication>
#include <QCommandLineParser>
#include <QDebug>
#include "main.h"
// TODO: fix qwerty mapping
......@@ -27,7 +29,51 @@
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
QCommandLineParser parser;
parser.setApplicationDescription("OE Designer CLI interface");
parser.addHelpOption();
parser.addOptions({
{"headless", QCoreApplication::translate("main", "Do not start GUI")},
{"export", QCoreApplication::translate("main", "Export active document to file."), QCoreApplication::translate("main", "exportFile")},
});
parser.addPositionalArgument("open", QCoreApplication::translate("main", "Load file as active document."));
parser.process(a);
bool headless = parser.isSet("headless");
QString openFile = parser.positionalArguments().empty() ? "" : parser.positionalArguments().first();
if (!headless)
{
MainWindow w;
w.setWindowState(Qt::WindowMaximized);
w.show();
if (openFile != "")
{
OE_interfaceDisplay* display = w.getCurrentRoot()->interfaceDisplay;
display->loadFile(openFile.toStdString());
display->zoomSelection();
display->update();
}
return a.exec();
}
OE_document doc;
if (openFile != "")
{
if (!doc.loadFromFile(openFile.toStdString()))
{
qDebug() << "Failed to open" << parser.value("open");
return 1;
}
}
if (parser.isSet("export"))
{
if (!doc.saveToFile(parser.value("export").toStdString()))
{
qDebug() << "Failed to save" << parser.value("export");
return 1;
}
}
return 0;
}
......@@ -29,6 +29,9 @@ INCLUDEPATH += include libPakalPersist external/qt-material-widgets/components
SOURCES += \
main.cpp \
src/io/OE_io_JPG.cpp \
src/io/OE_io_OE.cpp \
src/io/OE_io_SVG.cpp \
src/qt/mainwindow.cpp \
src/actions/OE_actions.cpp \
src/actions/OE_actionsBirailStitchs.cpp \
......@@ -63,7 +66,6 @@ SOURCES += \
src/OE_document.cpp \
src/OE_interfaceDisplay.cpp \
src/OE_pattern.cpp \
src/OE_svgParser.cpp \
src/OE_thread.cpp \
src/OE_utils.cpp \
libPakalPersist/Archive.cpp \
......@@ -126,7 +128,8 @@ SOURCES += \
external/qt-material-widgets/components/qtmaterialtooltabs_internal.cpp \
src/qt/OE_ui_toolbox.cpp \
src/qt/OE_ui_stitchlist.cpp \
src/qt/listviewdelegate.cpp
src/qt/listviewdelegate.cpp \
src/OE_preferences.cpp
HEADERS += \
src/qt/mainwindow.h \
......@@ -163,7 +166,6 @@ HEADERS += \
include/OE_interfaceDisplay.h \
include/OE_io.h \
include/OE_pattern.h \
include/OE_svgParser.h \
include/OE_thread.h \
include/OE_utils.h \
libPakalPersist/Archive.h \
......@@ -259,7 +261,8 @@ HEADERS += \
external/qt-material-widgets/components/qtmaterialtooltabs_p.h \
src/qt/OE_ui_toolbox.h \
src/qt/OE_ui_stitchlist.h \
src/qt/listviewdelegate.h
src/qt/listviewdelegate.h \
src/OE_preferences.h
FORMS += \
src/qt/mainwindow.ui
......
......@@ -745,16 +745,14 @@ bool OE_controller::generateInstructions()
instThread = curThread;
document->instCommand.push_back(new OE_waitcolor(document->instPoints.size(), instThread->getColor()));
}
std::vector<vector_2d> points = (*stitch)->getPoints();
const std::vector<vector_2d>& points = (*stitch)->getPoints();
// Start stop
document->instPoints.push_back(points[0]+vector_2d(0.1,0.1)); // TODO fix in firmware instead (nomove bug)
document->instPoints.push_back(points[1]);
document->instPoints.push_back(points[0]+vector_2d(0.1,0.1));
// Points
document->instPoints.insert(document->instPoints.end(), points.begin(), points.end());
// End stop
document->instPoints.push_back(points[points.size()-2]);
document->instPoints.push_back(points[points.size()-1]+vector_2d(-0.1,-0.1)); // TODO fix in firmware instead (nomove bug)
document->instPoints.push_back(points[points.size()-1]+vector_2d(-0.1,-0.1));
}
stitch++;
......
......@@ -21,6 +21,7 @@
#include "OE_display.h"
#include "OE_utils.h"
#include "OE_preferences.h"
#include "OE_controller.h"
......@@ -130,22 +131,12 @@ void OE_display::loadFile(std::string file)
std::transform(fileLower.begin(), fileLower.end(), fileLower.begin(), ::tolower);
OE_document* newDoc = nullptr;
if (endsWith(fileLower, ".oe"))
printf("Importing file from %s\n", file.c_str());
newDoc = new OE_document();
if (!newDoc->loadFromFile(file))
{
printf("Importing oe file from %s\n", file.c_str());
newDoc = new OE_document();
newDoc->loadFromFile(file);
}
else if (endsWith(fileLower, ".pes"))
{
printf("Importing pes file from %s\n", file.c_str());
newDoc = new OE_document();
newDoc->loadFromPES(file);
}
else if (endsWith(fileLower, ".svg"))
{
printf("Importing svg file from %s\n", file.c_str());
newDoc = OE_document::newFromSvg(file);
delete newDoc;
newDoc = nullptr;
}
if (newDoc)
......@@ -261,8 +252,8 @@ 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;
float crossSize = zoom*OE_preferences::moveCrossSize;
float boxOffset = zoom*OE_preferences::moveCrossSize;
min.x -= boxOffset;
min.y -= boxOffset;
......@@ -277,7 +268,7 @@ bool OE_display::drawSelectionTools(bool select)
glPushName(MOVETOOLID); //id of the move tool
glBegin(GL_QUADS);
glColor4fv(style->selectionBoundColor.rgba);
glColor4fv(OE_preferences::selectionBoundColor.rgba);
//glColor4d(1, 0, 0, 1);
glVertex2f(crossSize*1.0f, 0);
glVertex2f(0, crossSize*1.0f);
......@@ -305,7 +296,7 @@ bool OE_display::drawSelectionTools(bool select)
//draw selection bound
glLineWidth(1.5);
glBegin(GL_LINE_LOOP);
glColor4fv(style->selectionBoundColor.rgba);
glColor4fv(OE_preferences::selectionBoundColor.rgba);
glVertex2f(min.x, min.y);
glVertex2f(min.x, max.y);
glVertex2f(max.x, max.y);
......@@ -316,7 +307,7 @@ bool OE_display::drawSelectionTools(bool select)
//draw move cross
glBegin(GL_TRIANGLES);
glColor4fv(style->transformGizmoColor.rgba);
glColor4fv(OE_preferences::transformGizmoColor.rgba);
glVertex2f(-crossSize*0.6f, -crossSize*0.1f);
glVertex2f(-crossSize*0.6f, crossSize*0.1f);
glVertex2f(crossSize*0.6f, crossSize*0.1f);
......@@ -352,7 +343,7 @@ bool OE_display::drawSelectionTools(bool select)
//draw scale icon
glBegin(GL_TRIANGLES);
glColor4fv(style->transformGizmoColor.rgba);
glColor4fv(OE_preferences::transformGizmoColor.rgba);
glVertex2f(-crossSize*1.5f, -crossSize*1.2f);
glVertex2f(-crossSize*0.6f, -crossSize*0.55f);
glVertex2f(-crossSize*0.55f, -crossSize*0.6f);
......@@ -415,33 +406,33 @@ bool OE_display::drawStitch(OE_stitchs* stitch, int curpoint)
return false;
}
std::vector<vector_2d> points = stitch->getPoints();
const std::vector<vector_2d>& points = stitch->getPoints();
unsigned i;
// Points
glPointSize(style->stitchPointSize);
glPointSize(OE_preferences::stitchPointSize);
glBegin(GL_POINTS);
if (curpoint>0)
{
glColor4fv(style->stitchPointBeforeCurrentColor.rgba);
glColor4fv(OE_preferences::stitchPointBeforeCurrentColor.rgba);
}
else
{
glColor4fv(style->stitchPointAfterCurrentColor.rgba);
glColor4fv(OE_preferences::stitchPointAfterCurrentColor.rgba);
}
for (i = 1; i < points.size(); i++)
{
if (curpoint==i)
{
glColor4fv(style->stitchPointAfterCurrentColor.rgba);
glColor4fv(OE_preferences::stitchPointAfterCurrentColor.rgba);
}
glVertex2f(points.at(i).x, points.at(i).y);
glVertex2f(points[i].x, points[i].y);
}
glEnd();
//draw lines
glLineWidth(style->stitchLineWidth);
glLineWidth(OE_preferences::stitchLineWidth);
glBegin(GL_LINE_STRIP);
OE_thread* thread = stitch->getThread();
if (thread)
......@@ -450,7 +441,7 @@ bool OE_display::drawStitch(OE_stitchs* stitch, int curpoint)
}
else
{
glColor4fv(style->stitchLineBeforeCurrentColor.rgba);
glColor4fv(OE_preferences::stitchLineBeforeCurrentColor.rgba);
}
for (i = 0; i < points.size(); i++)
{
......@@ -460,8 +451,8 @@ bool OE_display::drawStitch(OE_stitchs* stitch, int curpoint)
// start point
glColor4fv(style->stitchStartPointColor.rgba);
glPointSize(style->stitchStartPointSize);
glColor4fv(OE_preferences::stitchStartPointColor.rgba);
glPointSize(OE_preferences::stitchStartPointSize);
glBegin(GL_POINTS);
glVertex2f(points.at(0).x, points.at(0).y);
glEnd();
......@@ -489,9 +480,9 @@ bool OE_display::drawCurve(OE_curve* curve)
unsigned i;
//draw curves
glLineWidth(style->curveWidth);
glLineWidth(OE_preferences::curveWidth);
glBegin(GL_LINE_STRIP);
glColor4fv(style->curveColor.rgba);
glColor4fv(OE_preferences::curveColor.rgba);
for (i = 0; i < curve->discPts.size(); i++)
{
......@@ -505,7 +496,7 @@ bool OE_display::drawCurve(OE_curve* curve)
glEnd();
if (!curve->getClosed())
{
glPointSize(style->curveStartPointSize);
glPointSize(OE_preferences::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);
......@@ -522,7 +513,7 @@ bool OE_display::drawCurve(OE_curve* curve)
//draw curve points
if (style->drawCurvePoints)
{
glPointSize(style->curvePointSize);
glPointSize(OE_preferences::curvePointSize);
glBegin(GL_POINTS);
glVertex2f(curve->discPts[0].v.x, curve->discPts[0].v.y);
for (i = 0; i < curve->discPts.size(); i++)
......@@ -580,7 +571,7 @@ bool OE_display::drawCurveControl(OE_curve* curve, bool select)
{
// Tangeant lines
glLineWidth(1.5);
glColor4fv(style->curveTangeantColor.rgba);
glColor4fv(OE_preferences::curveTangeantColor.rgba);
glBegin(GL_LINES);
for (unsigned i = 0; i < tmpcurve->pts.size()-3; i += 3)
{
......@@ -593,12 +584,12 @@ bool OE_display::drawCurveControl(OE_curve* curve, bool select)
glEnd();
// Points
glPointSize(style->curvePointSize);
glPointSize(OE_preferences::curvePointSize);
//glColor4ubv(controlEndPointColor);
glBegin(GL_POINTS);
glColor4fv(style->curvePointColor.rgba);
glColor4fv(OE_preferences::curvePointColor.rgba);
for (unsigned i = 0; i < tmpcurve->pts.size()-3; i += 3)
{
......@@ -609,8 +600,8 @@ bool OE_display::drawCurveControl(OE_curve* curve, bool select)
glEnd();
// tangeant end points
glPointSize(style->curvePointSize);
glColor4fv(style->curvePointColor.rgba);
glPointSize(OE_preferences::curvePointSize);
glColor4fv(OE_preferences::curvePointColor.rgba);
glBegin(GL_POINTS);
for (unsigned i = 0; i < curve->pts.size()-3; i += 3)
......@@ -628,7 +619,7 @@ bool OE_display::drawCurveControl(OE_curve* curve, bool select)
glBegin(GL_POINTS);
glVertex2f(curve->pts[0].x, curve->pts[0].y);
glEnd();*/
glColor4fv(style->curveControlsColor.rgba);
glColor4fv(OE_preferences::curveControlsColor.rgba);
drawTriangle(curve->pts[0], curve->pts[1], 13);
glLineWidth(2);
......@@ -778,7 +769,7 @@ void OE_display::drawJoincurveControl(OE_joincurve* curve, bool select, int inde
// draw the subcurves
glLineWidth(2);
glBegin(GL_LINE_STRIP);
glColor4fv(style->curveTangeantColor.rgba);
glColor4fv(OE_preferences::curveTangeantColor.rgba);
for (unsigned i = 0; i < subcurve->discPts.size(); i++)
{
......@@ -787,7 +778,7 @@ void OE_display::drawJoincurveControl(OE_joincurve* curve, bool select, int inde
glEnd();
// draw the insert subcurve control
glColor4fv(style->curveControlsColor.rgba);
glColor4fv(OE_preferences::curveControlsColor.rgba);
if (i == 0)
{
glBegin(GL_LINES);
......@@ -805,7 +796,7 @@ void OE_display::drawJoincurveControl(OE_joincurve* curve, bool select, int inde
glEnd();
// draw the subcurves controls
glColor4fv(style->curveControlsColor.rgba);
glColor4fv(OE_preferences::curveControlsColor.rgba);
glPointSize(6.0f);
glBegin(GL_POINTS);
glVertex2f(subcurve->pts[0].x, subcurve->pts[0].y);
......@@ -813,7 +804,7 @@ void OE_display::drawJoincurveControl(OE_joincurve* curve, bool select, int inde
glEnd();
// start point & direction
glColor4fv(style->curveControlsColor.rgba);
glColor4fv(OE_preferences::curveControlsColor.rgba);
drawTriangle(subcurve->pts[0], subcurve->pts[1], 13);
}
}
......@@ -837,12 +828,12 @@ void OE_display::drawFillstitchControl(OE_fillstitch* fillstitch, bool select)
}
else
{
glColor4fv(style->curveControlsColor.rgba);
glColor4fv(OE_preferences::curveControlsColor.rgba);
for (unsigned i = 0; i < curves.size(); i++)
{
drawCurve(&curves[i]);
}
glColor4fv(style->curveControlsColor.rgba);
glColor4fv(OE_preferences::curveControlsColor.rgba);
for (unsigned i = 0; i < grid.size(); i++)
{
glBegin(GL_POINTS);
......@@ -935,7 +926,7 @@ bool OE_display::drawStitchControl(OE_stitchs* stitch, bool select)
{
glLineWidth(2);
glBegin(GL_LINE_STRIP);
glColor4fv(style->stitchLineBeforeCurrentColor.rgba);
glColor4fv(OE_preferences::stitchLineBeforeCurrentColor.rgba);
glVertex2f(joinCurve->pts[0].x, joinCurve->pts[0].y);
glVertex2f(dir.x, dir.y);
glEnd();
......@@ -944,7 +935,7 @@ bool OE_display::drawStitchControl(OE_stitchs* stitch, bool select)
//draw stitch width controller
glBegin(GL_TRIANGLES);
glColor4fv(style->stitchControlsColor.rgba);
glColor4fv(OE_preferences::stitchControlsColor.rgba);
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);
......@@ -1028,7 +1019,7 @@ bool OE_display::drawStitchControl(OE_stitchs* stitch, bool select)
glPushName(0); //init the controller points index
glPointSize(4.0f);
std::vector<vector_2d> points = linkstitch->getPoints();
const std::vector<vector_2d>& points = linkstitch->getPoints();
vector_2d prevVert = points.at(0);
vector_2d p;
......@@ -1073,29 +1064,29 @@ bool OE_display::drawStitchControl(OE_stitchs* stitch, bool select)
{
glLineWidth(2.5);
glPointSize(5.0f);
glColor4fv(style->stitchStartPointColor.rgba);
glColor4fv(OE_preferences::stitchStartPointColor.rgba);
for (auto stepPt : linkstitch->stepPts)
{
glColor4fv(style->stitchControlsColor.rgba);
glColor4fv(OE_preferences::stitchControlsColor.rgba);
glBegin(GL_POINTS);
glVertex2f(stepPt.x, stepPt.y);
glEnd();
//style->stitchStartPointColor.gl();
//OE_preferences::stitchStartPointColor.gl();
glBegin(GL_LINES);
glVertex2f(stepPt.x-uiSize+uiDistance, stepPt.y-uiDistance);
glVertex2f(stepPt.x+uiSize+uiDistance, stepPt.y-uiDistance);
glEnd();
}
glColor4fv(style->stitchStartPointColor.rgba);
glColor4fv(OE_preferences::stitchStartPointColor.rgba);
glBegin(GL_LINES);
std::vector<vector_2d> points = linkstitch->getPoints();
const std::vector<vector_2d>& points = linkstitch->getPoints();
vector_2d prevVert = points.at(0);
vector_2d p;
std::list<vector_2d>::iterator stepPt = linkstitch->stepPts.begin();
glColor4fv(style->stitchControlsColor.rgba);
glColor4fv(OE_preferences::stitchControlsColor.rgba);
while (stepPt != linkstitch->stepPts.end())
{
p = (*stepPt + prevVert)/2;
......@@ -1136,14 +1127,14 @@ bool OE_display::drawCommands()
unsigned i;
// Points
glPointSize(style->instPointSize);
glPointSize(OE_preferences::instPointSize);
glBegin(GL_POINTS);
glColor4fv(style->instLineBeforeCurrentColor.rgba);
glColor4fv(OE_preferences::instLineBeforeCurrentColor.rgba);
for (i = 1; i < document->curPoint; i++)
{
glVertex2f(document->instPoints.at(i).x/scaleRatio, document->instPoints.at(i).y/scaleRatio);
}
glColor4fv(style->instLineAfterCurrentColor.rgba);
glColor4fv(OE_preferences::instLineAfterCurrentColor.rgba);
for (i = document->curPoint; i < document->instPoints.size(); i++)
{
glVertex2f(document->instPoints.at(i).x/scaleRatio, document->instPoints.at(i).y/scaleRatio);
......@@ -1155,7 +1146,7 @@ bool OE_display::drawCommands()
unsigned pt = 0;
OE_color curcolor;
glLineWidth(style->instLineWidth);
glLineWidth(OE_preferences::instLineWidth);
glBegin(GL_LINE_STRIP);
for (i = 0; i < document->instCommand.size(); i++)
{
......@@ -1163,7 +1154,7 @@ bool OE_display::drawCommands()
{
if (pt == document->curPoint)
{
glColor4fv((curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.rgba[3])).rgba);
glColor4fv((curcolor*OE_color(1, 1, 1, OE_preferences::instLineBeforeCurrentColor.rgba[3])).rgba);
}
glVertex2f(document->instPoints.at(pt).x/scaleRatio, document->instPoints.at(pt).y/scaleRatio);
}
......@@ -1178,14 +1169,14 @@ bool OE_display::drawCommands()
}
else
{
glColor4fv((curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.rgba[3])).rgba);
glColor4fv((curcolor*OE_color(1, 1, 1, OE_preferences::instLineBeforeCurrentColor.rgba[3])).rgba);
}
}
OE_start* start = dynamic_cast<OE_start*> (document->instCommand.at(i));
if (start)
{
curcolor = start->getThreadColor();
glColor4fv((curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.rgba[3])).rgba);
glColor4fv((curcolor*OE_color(1, 1, 1, OE_preferences::instLineBeforeCurrentColor.rgba[3])).rgba);
}
}
......@@ -1193,7 +1184,7 @@ bool OE_display::drawCommands()
{
if (pt == document->curPoint)
{
glColor4fv((curcolor*OE_color(1, 1, 1, style->instLineBeforeCurrentColor.rgba[3])).rgba);
glColor4fv((curcolor*OE_color(1, 1, 1, OE_preferences::instLineBeforeCurrentColor.rgba[3])).rgba);
}
glVertex2f(document->instPoints.at(pt).x/scaleRatio, document->instPoints.at(pt).y/scaleRatio);
}
......@@ -1201,8 +1192,8 @@ bool OE_display::drawCommands()
glEnd();
// start point
glColor4fv(style->instStartPointColor.rgba);
glPointSize(style->instStartPointSize);
glColor4fv(OE_preferences::instStartPointColor.rgba);
glPointSize(OE_preferences::instStartPointSize);
glBegin(GL_POINTS);
glVertex2f(document->instPoints.at(0).x/scaleRatio, document->instPoints.at(0).y/scaleRatio);
glEnd();
......@@ -1210,8 +1201,8 @@ bool OE_display::drawCommands()
// current point
if (document->curPoint < document->instPoints.size())
{
glColor4fv(style->instCurPointColor.rgba);
glPointSize(style->instCurPointSize);
glColor4fv(OE_preferences::instCurPointColor.rgba);
glPointSize(OE_preferences::instCurPointSize);
glBegin(GL_POINTS);
glVertex2f(document->instPoints.at(document->curPoint).x/scaleRatio, document->instPoints.at(document->curPoint).y/scaleRatio);
glEnd();
......@@ -1235,7 +1226,7 @@ bool OE_display::draw()
float wzoom, hzoom;
glViewport(0, 0, width, height);
glClearColor(style->backgroundColor.rgba[0], style->backgroundColor.rgba[1], style->backgroundColor.rgba[2], 1.0f);
glClearColor(OE_preferences::backgroundColor.rgba[0], OE_preferences::backgroundColor.rgba[1], OE_preferences::backgroundColor.rgba[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
......@@ -1267,7 +1258,7 @@ bool OE_display::draw()
{
glLineWidth(3);
glBegin(GL_LINE_STRIP);
glColor4fv(style->hoopColor.rgba);
glColor4fv(OE_preferences::hoopColor.rgba);
glVertex2f(zero.x-hoopSize.x, zero.y-hoopSize.y);
glVertex2f(zero.x-hoopSize.x, zero.y+hoopSize.y);
......@@ -1282,7 +1273,7 @@ bool OE_display::draw()
{
glLineWidth(1.5);
glBegin(GL_LINES);
glColor4fv((style->gridColor * OE_color(1, 1, 1, std::max(0.0f, 0.2f-zoom*2))).rgba);
glColor4fv((OE_preferences::gridColor * OE_color(1, 1, 1, std::max(0.0f, 0.2f-zoom*2))).rgba);
int offset = (int)-hoopSize.x;
while (offset<hoopSize.x)
......@@ -1300,7 +1291,7 @@ bool OE_display::draw()
offset += 1;
}
glColor4fv(style->gridColor.rgba);
glColor4fv(OE_preferences::gridColor.rgba);
offset = (int)-hoopSize.x+(int)hoopSize.x%10;
while (offset<hoopSize.x)
......@@ -1324,11 +1315,11 @@ bool OE_display::draw()
//draw 0
if (style->drawZero)
{
float zeroSize = style->zeroSize;
float zeroSize = OE_preferences::zeroSize;
glLineWidth(1.5);
glBegin(GL_LINE_STRIP);
glColor4fv(style->zeroColor.rgba);
glColor4fv(OE_preferences::zeroColor.rgba);
glVertex2f(zero.x-zeroSize, zero.y);
glVertex2f(zero.x, zero.y+zeroSize);
......@@ -1338,7 +1329,7 @@ bool OE_display::draw()
glVertex2f(zero.x-zeroSize, zero.y);
glEnd();
glBegin(GL_LINES);
glColor4fv(style->zeroColor.rgba);
glColor4fv(OE_preferences::zeroColor.rgba);
glVertex2f(zero.x-zeroSize, zero.y);
glVertex2f(zero.x+zeroSize, zero.y);
......@@ -1382,7 +1373,7 @@ bool OE_display::draw()
while (stitch != document->stitchs.end())
{
drawStitch(*stitch, curpoint);
curpoint -= (*stitch)->getPoints().size();
curpoint -= (*stitch)->getNpts();
stitch++;
}
......@@ -1508,7 +1499,7 @@ void OE_display::pick(std::list<OE_pointcurve*> selectedCurves, std::list<OE_sti
while (stitch != document->stitchs.end())
{
drawStitch(*stitch, curpoint);
curpoint -= (*stitch)->getPoints().size();
curpoint -= (*stitch)->getNpts();
stitch++;
index++;
glLoadName(index);
......
......@@ -20,7 +20,6 @@
*/
#include "OE_document.h"
#include "OE_svgParser.h"
#include "OE_io.h"
#include "stitchs/OE_linestitch.h"
#include "stitchs/OE_birailstitch.h"
......@@ -38,6 +37,60 @@
#include <limits>
#include <cmath>
extern const OE_io ioOe;
extern const OE_io ioPes;
extern const OE_io ioSvg;
extern const OE_io ioJpg;
static const std::list<const OE_io*> ios = {&ioOe, &ioPes, &ioSvg, &ioJpg};
static bool endsWithExtension (const std::string& str, const std::string& suffix)
{
std::string lstr = str;
std::transform(lstr.begin(), lstr.end(), lstr.begin(), ::tolower);
return lstr.size() >= 1+suffix.size() && lstr[lstr.size()-suffix.size()-1] == '.' && 0 == lstr.compare(lstr.size()-suffix.size(), suffix.size(), suffix);
}
static inline std::string buildDialogFilters(bool isLoad)
{
std::string filterStart = "All supported (";
std::string filterEnd;
bool firstOne = true;
for (const OE_io* io :ios)
{
if ((isLoad && io->loadFromFile) || (!isLoad && io->saveToFile))
{
if (!firstOne)
{
filterStart.append(" *.");
}
else
{
firstOne = false;
filterStart.append("*.");
}
filterStart.append(io->extension);
filterEnd.append(";;");
filterEnd.append(io->description);
filterEnd.append(" (*.");
filterEnd.append(io->extension);
filterEnd.append(")");
}
}
filterStart.append(")");
filterStart.append(filterEnd);
return filterStart;
}
std::string OE_document::getWriteDialogFilters()
{
return buildDialogFilters(false);
}
std::string OE_document::getReadDialogFilters()
{
return buildDialogFilters(true);
}
OE_document::OE_document()
{
std::list<OE_pattern*> standard_patterns = OE_pattern::createStandardPatterns();
......@@ -54,16 +107,15 @@ OE_document::ScopeLock::ScopeLock(OE_document& doc) : std::lock_guard<std::recur
bool OE_document::saveToFile(std::string path)
{
ScopeLock lock(*this);
OE_ofstream out(path);
if (!out.is_open())
for (const OE_io* io :ios)
{
return false;
if (io->saveToFile && endsWithExtension(path, io->extension))
{
ScopeLock lock(*this);
return (*io->saveToFile)(this, path);
}
}
Pakal::JsonWriter json_writer(true);
json_writer.write(out, "document", *this);
out.close();
return true;
return false;
}
void OE_document::persist(Pakal::Archive* archive)
......@@ -74,68 +126,25 @@ void OE_document::persist(Pakal::Archive* archive)
archive->value("stitchs", stitchs);
}
OE_document* OE_document::newFromSvg(const std::string& file)
bool OE_document::loadFromFile(std::string path)
{
OE_document* newDoc = OE_svgParser::fromFile(file, "px", 96.0f);
if (!newDoc)
return nullptr;
// Center document around (0,0)
BoundingBox bb = newDoc->getBound();
for (auto curve : newDoc->curves)
for (const OE_io* io :ios)
{
curve->move(vector_2d(0,0)-bb.getCenter());
}
// Rescale document if larger than hoop
bb = newDoc->getBound();
float docW = bb.getMax().x-bb.getMin().x;
float docH = bb.getMax().y-bb.getMin().y;
float hoopW = newDoc->getHoopSize().x;
float hoopH = newDoc->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)
if (io->loadFromFile && endsWithExtension(path, io->extension))
{
ratio = hoopH / (docH);
}
if (!std::isnan(ratio))
{
for (auto curve : newDoc->curves)
ScopeLock lock(*this);
if ((*io->loadFromFile)(path, this))
{
curve->scale(vector_2d(ratio, ratio), bb.getCenter());
for (auto& stitch : stitchs)
{
stitch->refreshDependency();
}
return true;
}
return false;
}
}
return newDoc;
}
bool OE_document::loadFromFile(std::string path)
{
ScopeLock lock(*this);
OE_ifstream in(path);
if (!in.is_open())
{
return false;
}
Pakal::SimpleFactoyManager manager;
manager.declare_object<OE_birailstitch>("OE_birailstitch", []() { return new OE_birailstitch(nullptr); });
manager.declare_object<OE_linestitch>("OE_linestitch", []() { return new OE_linestitch(); });
manager.declare_object<OE_linkstitch>("OE_linkstitch", []() { return new OE_linkstitch(); });
manager.declare_object<OE_fillstitch>("OE_fillstitch", []() { return new OE_fillstitch(); });
manager.declare_object<OE_staticstitch>("OE_staticstitch", []() { return new OE_staticstitch(); });
Pakal::JsonReader json_reader(&manager);
json_reader.read(in, "document", *this);
in.close();
for (auto& stitch : stitchs)
{
stitch->refreshDependency();
}
return true;
return false;
}
void OE_document::lock()
......@@ -153,44 +162,19 @@ bool OE_document::trylock()
return accessLock.try_lock();
}
BoundingBox OE_document::getBound()
BoundingBox OE_document::getBound() const
{
BoundingBox box;
if (curves.size())
if (!curves.empty() || !stitchs.empty())
{
std::list<OE_pointcurve*>::iterator curve = curves.begin();
box += (*curve)->getBound();
curve++;
while (curve != curves.end())
for (const auto& curve : curves)
{
//for (unsigned i=0; i<curves.size(); i++)
//{
box += (*curve)->getBound();
/*
(*curve)->getBound(&tmpXMin, &tmpYMin, &tmpXMax, &tmpYMax);
*xMin = minf(*xMin,tmpXMin);
*yMin = minf(*yMin,tmpYMin);
*xMax = maxf(*xMax,tmpXMax);
*yMax = maxf(*yMax,tmpYMax);*/
curve++;
box += curve->getBound();
}
std::list<OE_stitchs*>::iterator stitch = stitchs.begin();
while (stitch != stitchs.end())
for (const auto& stitch : stitchs)
{
//for (unsigned i=0; i<stitchs.size(); i++)
//{
box += (*stitch)->getBound();
/*
(*stitch)->getBound(&tmpXMin, &tmpYMin, &tmpXMax, &tmpYMax);
*xMin = minf(*xMin,tmpXMin);
*yMin = minf(*yMin,tmpYMin);
*xMax = maxf(*xMax,tmpXMax);
*yMax = maxf(*yMax,tmpYMax);*/
stitch++;
}
box += stitch->getBound();
}
}
else
{
......@@ -286,16 +270,3 @@ bool OE_document::draw(float dpi)
return true;
}*/
extern const OE_io ioPes;
bool OE_document::loadFromPES(std::string path)
{
ScopeLock lock(*this);
(*ioPes.loadFromFile)(path, this);
for (auto& stitch : stitchs)
{
stitch->refreshDependency();
}
return true;
}
......@@ -21,6 +21,7 @@
#include "OE_interfaceDisplay.h"
#include "OE_utils.h"
#include "OE_preferences.h"
#include "OE_controller.h"
......@@ -45,13 +46,9 @@
OE_interfaceDisplay::OE_interfaceDisplay(QWidget *parent, Qt::WindowFlags f) : OE_display(parent, f)
{
editStyle = new OE_display::OE_displayStyle();
commandStyle = new OE_display::OE_displayStyle();
commandStyle->drawGrid = false;
commandStyle->drawCurves = false;
commandStyle->drawStitches = false;
commandStyle->drawCommands = true;
setDisplayStyle(editStyle);
addDisplayStyle();
setDisplayStyle(0);
setDocument(nullptr);
modState = Qt::KeyboardModifier::NoModifier;
}
......@@ -84,6 +81,23 @@ bool OE_interfaceDisplay::setController(OE_controller* controller)
return true;
}
bool OE_interfaceDisplay::setDisplayStyle(unsigned int displayStyleId)
{
if (displayStyles.size()>displayStyleId)
{
OE_display::setDisplayStyle(displayStyles[displayStyleId]);
return true;
}
return false;
}
OE_display::OE_displayStyle* OE_interfaceDisplay::addDisplayStyle()
{
OE_display::OE_displayStyle* displayStyle = new OE_display::OE_displayStyle();
displayStyles.push_back(displayStyle);
return displayStyle;
}
void OE_interfaceDisplay::showAll()
{
OE_display::showAll();
......@@ -176,7 +190,7 @@ bool OE_interfaceDisplay::mouse_Button(QMouseEvent* event)
{
bool redraw = false;
redraw |= OE_display::mouse_Button(event);
if (curScreen == edit && event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress)
if (event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress)
{
redraw = true;
if (editionState == NewSubcurve)
......@@ -212,7 +226,7 @@ bool OE_interfaceDisplay::mouse_Button(QMouseEvent* event)
return redraw;
}
if (curScreen == edit && event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonRelease)
if (event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonRelease)
{
redraw = true;
selControlCurve = nullptr;
......@@ -270,12 +284,14 @@ void OE_interfaceDisplay::resize(int width, int height)
void OE_interfaceDisplay::key(QKeyEvent* event)
{
static QString writeFilters = QString::fromStdString(OE_document::getWriteDialogFilters());
static QString readFilters = QString::fromStdString(OE_document::getReadDialogFilters());
if (event->type() == QEvent::KeyPress)
modState = event->modifiers();
else
modState = Qt::KeyboardModifier::NoModifier;
if (event->type() == QEvent::KeyPress && curScreen == edit)
if (event->type() == QEvent::KeyPress)
{
if (event->key() == Qt::Key_R && event->modifiers() == Qt::NoModifier)
{
......@@ -307,7 +323,7 @@ void OE_interfaceDisplay::key(QKeyEvent* event)
{
if (document)
{
QString fileName = QFileDialog::getSaveFileName(this, "Save design", "", "OE designer (*.oe)");
QString fileName = QFileDialog::getSaveFileName(this, "Save design", "", writeFilters);
if (!fileName.isEmpty())
{
document->saveToFile(fileName.toStdString());
......@@ -317,7 +333,7 @@ void OE_interfaceDisplay::key(QKeyEvent* event)
else if (event->key() == Qt::Key_O && event->modifiers() == Qt::ControlModifier)
{
QString type;
QString fileName = QFileDialog::getOpenFileName(this, "Open design", "", "All supported (*.oe *.svg *.pes);;OE designer (*.oe);;SVG drawing (*.svg);;PES (*.pes)", &type);
QString fileName = QFileDialog::getOpenFileName(this, "Open design", "", readFilters, &type);
if (!fileName.isEmpty())
{
loadFile(fileName.toStdString());
......@@ -412,27 +428,7 @@ void OE_interfaceDisplay::key(QKeyEvent* event)
}
if(editionState==None)
{
if (curScreen == command && event->key() == Qt::Key_Space)
{
run=true;
update();
}
if (event->key() == Qt::Key_F12)
{
if (curScreen == edit)
{
curScreen = command;
setDisplayStyle(commandStyle);
update();
}
else
{
curScreen = edit;
setDisplayStyle(editStyle);
update();
}
}
else if (event->key() == Qt::Key_L)
if (event->key() == Qt::Key_L)
{
if (controller)
{
......@@ -977,7 +973,7 @@ bool OE_interfaceDisplay::draw()
}
else
{
glColor4fv(style->cursorColor.rgba);
glColor4fv(OE_preferences::cursorColor.rgba);
}
glVertex2f(absMouse.x,-10000);
glVertex2f(absMouse.x,10000);
......@@ -989,7 +985,7 @@ bool OE_interfaceDisplay::draw()
// draw the cursor picking zone
glLineWidth(2);
glBegin(GL_LINE_LOOP);
glColor4fv(style->cursorColor.rgba);
glColor4fv(OE_preferences::cursorColor.rgba);
glVertex2f(absMouse.x-5*zoom,absMouse.y+5*zoom);
glVertex2f(absMouse.x-5*zoom,absMouse.y-5*zoom);
glVertex2f(absMouse.x+5*zoom,absMouse.y-5*zoom);
......@@ -1001,7 +997,7 @@ bool OE_interfaceDisplay::draw()
vector_2d clicAbsMouse = viewPos+(clicOldMouse-vector_2d(width,height)/2)*zoom*2;
glLineWidth(2);
glBegin(GL_LINE_STRIP);
glColor4fv(style->cursorColor.rgba);
glColor4fv(OE_preferences::cursorColor.rgba);
glVertex2f(absMouse.x,clicAbsMouse.y);
glVertex2f(absMouse.x,absMouse.y);
glVertex2f(clicAbsMouse.x,absMouse.y);
......
#include "OE_preferences.h"
OE_preferences::OE_preferences()
{
}
OE_color OE_preferences::hoopColor = OE_color(0.0, 0.0, 0.0, .5);
OE_color OE_preferences::backgroundColor = OE_color(0.85, 0.85, 0.85, 1.0);
OE_color OE_preferences::cursorColor = OE_color(0.0, 0.0, 0.0, 0.3);
OE_color OE_preferences::gridColor = OE_color(0.0, 0.0, 0.0, 0.1);
OE_color OE_preferences::zeroColor = OE_color(0.0, 0.0, 0.0, 1.0);
float OE_preferences::zeroSize = 3;
OE_color OE_preferences::curveColor = OE_color(0,.63,.75,1.0);
OE_color OE_preferences::curveTangeantColor = OE_color(.39,.235,.36,1.0);
OE_color OE_preferences::curvePointColor = OE_color(.39,.235,.36,1.0);
OE_color OE_preferences::curveControlsColor = OE_color(.78,0,0,1.0);
float OE_preferences::curveWidth = 1.5;
float OE_preferences::curveTangeantWidth = 1.5;
float OE_preferences::curvePointSize = 3.0;
float OE_preferences::curveStartPointSize = 5.0;
OE_color OE_preferences::stitchLineBeforeCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color OE_preferences::stitchLineAfterCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color OE_preferences::stitchPointBeforeCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color OE_preferences::stitchPointAfterCurrentColor = OE_color(.08,.08,.08,1.0);
OE_color OE_preferences::stitchStartPointColor = OE_color(.39,.235,.36,1.0);
OE_color OE_preferences::stitchControlsColor = OE_color(.78,0,0,1.0);
float OE_preferences::stitchPointSize = 3.0;
float OE_preferences::stitchLineWidth = 1.5;
float OE_preferences::stitchStartPointSize = 5.0;
OE_color OE_preferences::instLineBeforeCurrentColor = OE_color(0,.63,.75,.3);
OE_color OE_preferences::instLineAfterCurrentColor = OE_color(0,.63,.75,1.0);
OE_color OE_preferences::instStartPointColor = OE_color(.39,.23,.36,1.0);
OE_color OE_preferences::instCurPointColor = OE_color(.78,.2,.2,1.0);
OE_color OE_preferences::instColor = OE_color(.39,.23,.36,1.0);
float OE_preferences::instPointSize = 3.0;
float OE_preferences::instLineWidth = 1.5;
float OE_preferences::instStartPointSize = 5.0;
float OE_preferences::instCurPointSize = 5.0;
OE_color OE_preferences::machineStartPointColor;
OE_color OE_preferences::machineCurPointColor;
float OE_preferences::moveCrossSize = 30;
OE_color OE_preferences::transformGizmoColor = OE_color(1,0,0,1);
OE_color OE_preferences::selectionBoundColor = OE_color(1,0,0,1);
#ifndef OE_PREFERENCES_H
#define OE_PREFERENCES_H
#include "OE_utils.h"
class OE_preferences
{
public:
static OE_color hoopColor;
static OE_color backgroundColor;
static OE_color cursorColor;
static OE_color gridColor;
static OE_color zeroColor;
static float zeroSize;
static OE_color curveColor;
static OE_color curveTangeantColor;
static OE_color curvePointColor;
static OE_color curveControlsColor;
static float curveWidth;
static float curveTangeantWidth;
static float curvePointSize;
static float curveStartPointSize;
static OE_color stitchLineBeforeCurrentColor;
static OE_color stitchLineAfterCurrentColor;
static OE_color stitchPointBeforeCurrentColor;
static OE_color stitchPointAfterCurrentColor;
static OE_color stitchStartPointColor;
static OE_color stitchControlsColor;
static float stitchPointSize;
static float stitchLineWidth;
static float stitchStartPointSize;
static OE_color instLineBeforeCurrentColor;
static OE_color instLineAfterCurrentColor;
static OE_color instStartPointColor;
static OE_color instCurPointColor;
static OE_color instColor;
static float instPointSize;
static float instLineWidth;
static float instStartPointSize;
static float instCurPointSize;
static OE_color machineStartPointColor;
static OE_color machineCurPointColor;
static OE_color transformGizmoColor;
static OE_color selectionBoundColor;
static float moveCrossSize;
OE_preferences();
};
#endif // OE_PREFERENCES_H
/*
* 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_io.h"
#include "OE_document.h"
#include "stitchs/OE_birailstitch.h"
#include "stitchs/OE_linestitch.h"
#include "stitchs/OE_linkstitch.h"
#include "stitchs/OE_fillstitch.h"
#include "stitchs/OE_staticstitch.h"
#include "OE_utils.h"
#include <iostream>
#include <fstream>
#include <QImage>
#include <QPainter>
#include <QPen>
#include <QImageWriter>
static bool saveToJPG(const OE_document* document, std::string path);
extern const OE_io ioJpg;
const OE_io ioJpg = {"jpg",
"Jpg",
nullptr,
saveToJPG};
static inline QPointF transformPoint(const vector_2d& pt, const vector_2d& offset, float scale)
{
vector_2d newPt = (pt - offset) * scale;
return QPointF(newPt.x, newPt.y);
}
static bool saveToJPG(const OE_document* document, std::string path)
{
const int maxsize = 512;
const int quality = 90;
int w,h;
float scale;
BoundingBox bb = document->getBound();
vector_2d ptMin = bb.getMin();
if (bb.getMax().y-bb.getMin().y <= bb.getMax().x-bb.getMin().x)
{
w = maxsize;
h = w * (bb.getMax().y-bb.getMin().y) / (bb.getMax().x-bb.getMin().x) + 0.5f;
scale = maxsize / (bb.getMax().x-bb.getMin().x);
}
else
{
h = maxsize;
w = h * (bb.getMax().x-bb.getMin().x) / (bb.getMax().y-bb.getMin().y) + 0.5f;
scale = maxsize / (bb.getMax().y-bb.getMin().y);
}
QImage image(w, h, QImage::Format_RGB888);
image.fill(Qt::white);
QPainter painter(&image);
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
for (OE_stitchs* stitch : document->stitchs)
{
if (stitch->getPoints().empty() || dynamic_cast<OE_linkstitch*>(stitch))
{
continue;
}
QPointF lastPoint = transformPoint(stitch->getPoints()[0], ptMin, scale);
OE_color oecol = stitch->getThread()->getColor();
QPen pen(QColor(oecol.rgba[0]*255,oecol.rgba[1]*255,oecol.rgba[2]*255,255));
painter.setPen(pen);
if (stitch->getNpts()==1)
{
painter.drawPoint(lastPoint);
}
else
{
for (ssize_t i=1; i<stitch->getNpts(); i++)
{
QPointF newPoint = transformPoint(stitch->getPoints()[i], ptMin, scale);
painter.drawLine(lastPoint, newPoint);
lastPoint = newPoint;
}
}
}
painter.end();
QImageWriter writer(QString::fromStdString(path));
writer.setQuality(quality);
writer.write(image);
return true;
}
/*
* 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_io.h"
#include "OE_document.h"
#include "stitchs/OE_birailstitch.h"
#include "stitchs/OE_linestitch.h"
#include "stitchs/OE_linkstitch.h"
#include "stitchs/OE_fillstitch.h"
#include "stitchs/OE_staticstitch.h"
#include "OE_utils.h"
#include <iostream>
#include <fstream>
#include "Archive.h"
#include "JsonWriter.h"
#include "JsonReader.h"
static bool loadFromOE(std::string path, OE_document* document);
static bool saveToOE(const OE_document* document, std::string path);
extern const OE_io ioOe;
const OE_io ioOe = {"oe",
"OpenEmbroidery",
loadFromOE,
saveToOE};
static bool loadFromOE(std::string path, OE_document* document)
{
OE_document::ScopeLock lock(*document);
OE_ifstream in(path);
if (!in.is_open())
{
return false;
}
Pakal::SimpleFactoyManager manager;
manager.declare_object<OE_birailstitch>("OE_birailstitch", []() { return new OE_birailstitch(nullptr); });
manager.declare_object<OE_linestitch>("OE_linestitch", []() { return new OE_linestitch(); });
manager.declare_object<OE_linkstitch>("OE_linkstitch", []() { return new OE_linkstitch(); });
manager.declare_object<OE_fillstitch>("OE_fillstitch", []() { return new OE_fillstitch(); });
manager.declare_object<OE_staticstitch>("OE_staticstitch", []() { return new OE_staticstitch(); });
Pakal::JsonReader json_reader(&manager);
json_reader.read(in, "document", *document);
in.close();
for (auto& stitch : document->stitchs)
{
stitch->refreshDependency();
}
return true;
}
static bool saveToOE(const OE_document* document, std::string path)
{
OE_ofstream out(path);
if (!out.is_open())
{
return false;
}
Pakal::JsonWriter json_writer(true);
json_writer.write(out, "document", *(OE_document*)document); // drop constness due to pakal structure
out.close();
return true;
}
......@@ -33,7 +33,7 @@ static bool loadFromPES(std::string path, OE_document* document);
extern const OE_io ioPes;
const OE_io ioPes = {"pes",
"Brother PES format",
"Brother",
loadFromPES,
0};
......@@ -113,8 +113,8 @@ static const PESCol pecThreads[] = {
{{255, 200, 200}, "Applique", ""} /* Index 64 */
};
static int getU8(std::ifstream& in)
{
static uint8_t getU8(std::ifstream& in)
{ // TODO throw on error
unsigned char u = 0;
if (in.good())
{
......@@ -123,23 +123,28 @@ static int getU8(std::ifstream& in)
return u;
}
static uint32_t getU32LE(std::ifstream& in)
{ // TODO throw on error
uint32_t u32le = getU8(in);
u32le |= getU8(in)<<8;
u32le |= getU8(in)<<16;
u32le |= getU8(in)<<24;
return u32le;
}
static bool loadFromPES(std::string path, OE_document* document)
{
std::ifstream in(path);
std::ifstream in(path, std::ios_base::in|std::ios_base::binary);
if (!in.is_open())
{
return false;
}
in.seekg(8);
int pecstart = getU8(in);
pecstart |= getU8(in)<<8;
pecstart |= getU8(in)<<16;
pecstart |= getU8(in)<<24;
uint32_t pecstart = getU32LE(in);
std::cout << "PES: " << "pecstart=" << pecstart << std::endl;
std::cout << "PES: " << "jumping to " << (pecstart+48) << std::endl;
in.seekg(pecstart+48);
in.seekg(pecstart+48, std::ios_base::seekdir::_S_beg);
int nThreads = getU8(in)+1;
std::cout << "PES: " << nThreads << " threads" << std::endl;
......@@ -165,7 +170,7 @@ static bool loadFromPES(std::string path, OE_document* document)
OE_staticstitch* stitch = 0;
std::cout << "PES: " << "jumping to " << (pecstart+532) << std::endl;
in.seekg(pecstart+532);
in.seekg(pecstart+532, std::ios_base::seekdir::_S_beg);
int iCol = 0;
auto itThread = document->threads.begin();
......@@ -206,7 +211,7 @@ static bool loadFromPES(std::string path, OE_document* document)
val1 = ((val1 & 0x0F) << 8) + val2;
/* Signed 12-bit arithmetic */
// 12-bit 2's complement
if (val1 & 0x800)
{
val1 -= 0x1000;
......@@ -215,7 +220,7 @@ static bool loadFromPES(std::string path, OE_document* document)
val2 = getU8(in);
}
else if (val1 >= 0x40)
{
{ // 7-bit 2's complement
val1 -= 0x80;
}
if (val2 & 0x80)
......@@ -230,19 +235,19 @@ static bool loadFromPES(std::string path, OE_document* document)
}
val2 = ((val2 & 0x0F) << 8) + getU8(in);
/* Signed 12-bit arithmetic */
// 12-bit 2's complement
if (val2 & 0x800)
{
val2 -= 0x1000;
}
}
else if (val2 >= 0x40)
{
{ // 7-bit 2's complement
val2 -= 0x80;
}
x += val1;
y += val2;
if ((stitchType == 0 && !stitch) || stitchType)
if (!stitch || stitchType)
{
OE_staticstitch* newStitch = new OE_staticstitch(*itThread);
if (stitch)
......
......@@ -19,40 +19,110 @@
*
*/
#include "OE_svgParser.h"
#include "OE_io.h"
#include "OE_utils.h"
#include "OE_document.h"
#include "xml/tinyxml.h"
#include "QString" // For locale free str to float conversion
#include <iostream>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159
#ifndef M_PIf32
#define M_PIf32 3.141592653589793f
#endif
OE_svgParser::OE_svgParser()
static bool loadFromSVG(std::string path, OE_document* document);
extern const OE_io ioSvg;
const OE_io ioSvg = {"svg",
"Scalable Vector Graphics",
loadFromSVG,
nullptr};
struct SVGContext
{
//OE_svgParser::OE_svg_base();
opacity = 0; // Opacity of the curve.
strokeWidth = 0; // Stroke width (scaled).
strokeLineJoin = 0; // Stroke join type.
strokeLineCap = 0; // Stroke cap type.
SVGContext(OE_document* document) : document(document) {}
OE_document* document;
OE_Matrix matrix;
};
static bool parseSvg(SVGContext& context, TiXmlElement *input);
static bool parsePath(SVGContext& context, TiXmlElement *input);
static bool pushCurve(SVGContext& context, OE_pointcurve * curve);
static bool loadFromSVG(std::string path, OE_document* document)
{
// Xml load and parse
TiXmlDocument doc(path.c_str());
if (!doc.LoadFile())
{
std::cerr << "error during loading of the following file :" << std::endl;
std::cerr << "error #" << doc.ErrorId() << " : " << doc.ErrorDesc() << std::endl;
return false;
}
TiXmlHandle hdl(&doc);
TiXmlElement *object = hdl.FirstChildElement("svg").Element();
// Svg parse and extract
SVGContext context(document);
OE_document::ScopeLock lock(*document);
parseSvg(context, object);
// Center document around (0,0)
BoundingBox bb = document->getBound();
for (auto curve : document->curves)
{
curve->move(vector_2d(0,0)-bb.getCenter());
}
// Rescale document if larger than hoop
bb = document->getBound();
float docW = bb.getMax().x-bb.getMin().x;
float docH = bb.getMax().y-bb.getMin().y;
float hoopW = document->getHoopSize().x;
float hoopH = document->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);
}
if (!std::isnan(ratio))
{
for (auto curve : document->curves)
{
curve->scale(vector_2d(ratio, ratio), bb.getCenter());
}
}
}
return true;
}
float OE_svgParser::sqr(float x)
static float sqr(float x)
{
return x*x;
}
float OE_svgParser::vmag(float x, float y)
static float vmag(float x, float y)
{
return sqrtf(x*x + y*y);
}
float OE_svgParser::vecrat(float ux, float uy, float vx, float vy)
static float vecrat(float ux, float uy, float vx, float vy)
{
return (ux*vx + uy*vy) / (vmag(ux,uy) * vmag(vx,vy));
}
float OE_svgParser::vecang(float ux, float uy, float vx, float vy)
static float vecang(float ux, float uy, float vx, float vy)
{
float r = vecrat(ux,uy, vx,vy);
if (r < -1.0f) r = -1.0f;
......@@ -60,34 +130,34 @@ float OE_svgParser::vecang(float ux, float uy, float vx, float vy)
return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r);
}
void OE_svgParser::xformPoint(float* dx, float* dy, float x, float y, float* t)
static void xformPoint(float* dx, float* dy, float x, float y, float* t)
{
*dx = x*t[0] + y*t[2] + t[4];
*dy = x*t[1] + y*t[3] + t[5];
}
void OE_svgParser::xformVec(float* dx, float* dy, float x, float y, float* t)
static void xformVec(float* dx, float* dy, float x, float y, float* t)
{
*dx = x*t[0] + y*t[2];
*dy = x*t[1] + y*t[3];
}
int OE_svgParser::isspace(char c)
static int isspace(char c)
{
return strchr(" \t\n\v\f\r", c) != 0;
return strchr(" \t\n\v\f\r", c) != nullptr;
}
int OE_svgParser::isdigit(char c)
static int isdigit(char c)
{
return strchr("0123456789", c) != 0;
return strchr("0123456789", c) != nullptr;
}
int OE_svgParser::isnum(char c)
static int isnum(char c)
{
return strchr("0123456789+-.eE", c) != 0;
return strchr("0123456789+-.eE", c) != nullptr;
}
const char* OE_svgParser::parseNumber(const char* s, char* it, const int size)
static const char* parseNumber(const char* s, char* it, const int size)
{
const int last = size-1;
int i = 0;
......@@ -157,7 +227,7 @@ const char* OE_svgParser::parseNumber(const char* s, char* it, const int size)
return s;
}
void OE_svgParser::pathMoveTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
static void pathMoveTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
{
if (rel)
{
......@@ -172,7 +242,7 @@ void OE_svgParser::pathMoveTo(OE_pointcurve* curve, float* cpx, float* cpy, floa
curve->addPoint(*cpx, *cpy);
}
void OE_svgParser::pathLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
static void pathLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
{
if (rel)
{
......@@ -187,7 +257,7 @@ void OE_svgParser::pathLineTo(OE_pointcurve* curve, float* cpx, float* cpy, floa
curve->lineTo(*cpx, *cpy);
}
void OE_svgParser::pathHLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
static void pathHLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
{
if (rel)
{
......@@ -200,7 +270,7 @@ void OE_svgParser::pathHLineTo(OE_pointcurve* curve, float* cpx, float* cpy, flo
curve->lineTo(*cpx, *cpy);
}
void OE_svgParser::pathVLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
static void pathVLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
{
if (rel)
{
......@@ -213,7 +283,7 @@ void OE_svgParser::pathVLineTo(OE_pointcurve* curve, float* cpx, float* cpy, flo
curve->lineTo(*cpx, *cpy);
}
void OE_svgParser::pathCubicBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
static void pathCubicBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
{
float x2, y2, cx1, cy1, cx2, cy2;
......@@ -246,7 +316,7 @@ void OE_svgParser::pathCubicBezTo(OE_pointcurve* curve, float* cpx, float* cpy,
*cpy = y2;
}
void OE_svgParser::pathCubicBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
static void pathCubicBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
{
float x1, y1, x2, y2, cx1, cy1, cx2, cy2;
......@@ -278,7 +348,7 @@ void OE_svgParser::pathCubicBezShortTo(OE_pointcurve* curve, float* cpx, float*
*cpy = y2;
}
void OE_svgParser::pathQuadBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
static void pathQuadBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
{
float x1, y1, x2, y2, cx, cy;
float cx1, cy1, cx2, cy2;
......@@ -314,7 +384,7 @@ void OE_svgParser::pathQuadBezTo(OE_pointcurve* curve, float* cpx, float* cpy, f
*cpy = y2;
}
void OE_svgParser::pathQuadBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
static void pathQuadBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel)
{
float x1, y1, x2, y2, cx, cy;
float cx1, cy1, cx2, cy2;
......@@ -349,7 +419,7 @@ void OE_svgParser::pathQuadBezShortTo(OE_pointcurve* curve, float* cpx, float* c
*cpy = y2;
}
void OE_svgParser::pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
static void pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel)
{
// Ported from canvg (https://code.google.com/p/canvg/)
float rx, ry, rotx;
......@@ -364,9 +434,9 @@ void OE_svgParser::pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float
rx = fabsf(args[0]); // y radius
ry = fabsf(args[1]); // x radius
rotx = args[2] / 180.0f * M_PI; // x rotation engle
fa = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc
fs = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction
rotx = args[2] / 180.0f * M_PIf32; // x rotation engle
fa = fabsf(args[3]) > 1e-6f ? 1 : 0;// Large arc
fs = fabsf(args[4]) > 1e-6f ? 1 : 0;// Sweep direction
x1 = *cpx; // start point
y1 = *cpy;
if (rel) // end point
......@@ -446,11 +516,11 @@ void OE_svgParser::pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float
// Choose large arc
if (da > 0.0f)
{
da = da - 2*M_PI;
da = da - 2*M_PIf32;
}
else
{
da = 2*M_PI + da;
da = 2*M_PIf32 + da;
}
}
......@@ -461,7 +531,7 @@ void OE_svgParser::pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float
// Split arc into max 90 degree segments.
// The loop assumes an iteration per end point (including start and end), this +1.
ndivs = (int)(fabsf(da) / (M_PI*0.5f) + 1.0f);
ndivs = (int)(fabsf(da) / (M_PIf32*0.5f) + 1.0f);
hda = (da / (float)ndivs) / 2.0f;
kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
if (da < 0.0f)
......@@ -490,7 +560,7 @@ void OE_svgParser::pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float
*cpy = y2;
}
const char* OE_svgParser::getNextPathItem(const char* s, char* it)
static const char* getNextPathItem(const char* s, char* it)
{
it[0] = '\0';
// Skip white spaces and commas
......@@ -517,7 +587,7 @@ const char* OE_svgParser::getNextPathItem(const char* s, char* it)
return s;
}
int OE_svgParser::getArgsPerElement(char cmd)
static int getArgsPerElement(char cmd)
{
switch (cmd)
{
......@@ -548,35 +618,9 @@ int OE_svgParser::getArgsPerElement(char cmd)
return 0;
}
OE_document* OE_svgParser::fromFile(const std::string filename, const char* /*units*/, float /*dpi*/)
static bool parseSvg(SVGContext& context, TiXmlElement *input)
{
OE_svgParser parser;
// Loading of the SVG file
TiXmlDocument doc(filename.c_str());
if (! doc.LoadFile())
{
std::cerr << "error during loading of the following file :" << std::endl;
std::cerr << "error #" << doc.ErrorId() << " : " << doc.ErrorDesc() << std::endl;
return nullptr;
}
TiXmlHandle hdl(&doc);
TiXmlElement *object = hdl.FirstChildElement("svg").Element();
parser.document = new OE_document();
if (parser.document)
{
parser.parseSvg(object);
}
return parser.document;
}
bool OE_svgParser::parseSvg(TiXmlElement *input)
{
TiXmlElement* element = 0;
TiXmlElement* element = nullptr;
if (input)
{
for( element = input->FirstChildElement(); element; element = element->NextSiblingElement() )
......@@ -587,7 +631,7 @@ bool OE_svgParser::parseSvg(TiXmlElement *input)
{
const char* transform = element->Attribute("transform");
OE_Matrix newTransform;
OE_Matrix oldTransform(matrix);
OE_Matrix oldTransform(context.matrix);
if (transform)
{
char snb[64];
......@@ -641,21 +685,21 @@ bool OE_svgParser::parseSvg(TiXmlElement *input)
printf("Unknown transform \"%s\"\n", transform);
}
}
matrix = matrix * newTransform;
parseSvg(element);
matrix = oldTransform;
context.matrix = context.matrix * newTransform;
parseSvg(context, element);
context.matrix = oldTransform;
}
if((strlen(val)==4)&&(strncmp(val,"path",4) == 0))
{
parsePath(element);
parsePath(context, element);
}
}
}
return true;
}
bool OE_svgParser::parsePath(TiXmlElement *input)
static bool parsePath(SVGContext& context, TiXmlElement *input)
{
if (input)
{
......@@ -772,7 +816,7 @@ bool OE_svgParser::parsePath(TiXmlElement *input)
if (cmd == 'M' || cmd == 'm')
{
// Add the curve to document.
pushCurve(curve);
pushCurve(context, curve);
// Start new curve.
curve = new OE_pointcurve();
......@@ -789,7 +833,7 @@ bool OE_svgParser::parsePath(TiXmlElement *input)
cpx2 = cpx; cpy2 = cpy;
// Add the curve to document.
pushCurve(curve);
pushCurve(context, curve);
// Start new curve.
curve = new OE_pointcurve();
}
......@@ -797,7 +841,7 @@ bool OE_svgParser::parsePath(TiXmlElement *input)
}
}
}
pushCurve(curve);
pushCurve(context, curve);
return true;
}
}
......@@ -805,14 +849,13 @@ bool OE_svgParser::parsePath(TiXmlElement *input)
return false;
}
bool OE_svgParser::pushCurve(OE_pointcurve * curve)
static bool pushCurve(SVGContext& context, OE_pointcurve * curve)
{
if (curve->check())
{
curve->transform(matrix);
return document->addCurve(curve);
curve->transform(context.matrix);
return context.document->addCurve(curve);
}
else
{
......
......@@ -5,7 +5,7 @@
#include "OE_document.h"
Machine::Machine(unsigned msTimeout, unsigned retries) :
connected(false), sequence(0), sequenceAck(0), msTimeout(msTimeout), retries(retries)
connected(false), sequence(0), sequenceAck(0), loadAck(-1),loadSize(0), msTimeout(msTimeout), retries(retries)
{
connect(&serial, &QSerialPort::readyRead, this, &Machine::handleReadyRead);
connect(&serial, &QSerialPort::errorOccurred, this, &Machine::handleError);
......@@ -141,7 +141,7 @@ void Machine::setPos(int16_t x, int16_t y)
sendCommand(Command::kSetPos);
}
void Machine::sendCommand(Command cmd, uint8_t len)
void Machine::sendCommand(Command cmd, uint8_t len, bool async)
{
uint8_t u8 = ++sequence;
cmdBuffer.insert(0, '\x3A'); // SFD
......@@ -160,6 +160,11 @@ void Machine::sendCommand(Command cmd, uint8_t len)
serial.flush();
cmdBuffer.clear();
if (async)
{
return;
}
struct timespec dt;
unsigned ms, tries;
for (tries=0; (tries<retries) && (sequence != sequenceAck); tries++)
......@@ -194,6 +199,33 @@ void Machine::onMsg(uint8_t* buffer)
info.sequence, info.status, info.spaceSize, info.freeSpace, info.posX, info.posY, info.nPoint);
emit stateChanged(info);
}
// Points stream management
if (loadAck >= 0 && loadAck==sequenceAck) // TODOOOOOOOOOOOOOOOO add timeout/error management
{
loadAck = -1;
while (loadSize--)
{
loadQueue.pop_front();
}
}
if (loadAck < 0 && !loadQueue.isEmpty() && info.freeSpace > 50)
{
cmdBuffer.clear();
auto itLoad = loadQueue.begin();
uint8_t u;
while ((cmdBuffer.size()+3 < 37-5) && (cmdBuffer.size() != loadQueue.size()))
{
u = *itLoad++;
cmdBuffer.append(*reinterpret_cast<char*>(&u));
u = *itLoad++;
cmdBuffer.append(*reinterpret_cast<char*>(&u));
u = *itLoad++;
cmdBuffer.append(*reinterpret_cast<char*>(&u));
}
loadSize = static_cast<uint32_t>(cmdBuffer.size());
sendCommand(Command::kAddPoints, static_cast<uint8_t>(cmdBuffer.size()/3), true);
loadAck = sequence;
}
}
void Machine::loadpoints(OE_document* document)
......@@ -202,11 +234,7 @@ void Machine::loadpoints(OE_document* document)
unsigned sndPoint=0;
uint8_t u1, u2, u3;
qDebug() << "sendInstPoint" << document->instPoints.size() << "points";
if (document->instPoints.size()*3+5 > info.freeSpace)
{
qDebug() << "Too much points to fit in ram";
return;
}
loadQueue.clear();
//TODO stopMove();
//TODO setPos(0, 0);
......@@ -222,6 +250,11 @@ void Machine::loadpoints(OE_document* document)
y = static_cast<int>(roundf(-document->instPoints.at(sndPoint).y));
dx = x-oldX;
dy = y-oldY;
if (dx == 0 && dy == 0)
{ // Bug in firmware for the "no move" instruction, skipping point instead. TODO fix firmware and remove.
sndPoint++;
continue;
}
u1 = static_cast<uint8_t>((abs(dx)>>8)<<2) | static_cast<uint8_t>(abs(dy)>>8);
u2 = abs(dx)&0xff;
......@@ -233,11 +266,10 @@ void Machine::loadpoints(OE_document* document)
cmdBuffer.append(*reinterpret_cast<char*>(&u1));
cmdBuffer.append(*reinterpret_cast<char*>(&u2));
cmdBuffer.append(*reinterpret_cast<char*>(&u3));
loadQueue.append(u1);
loadQueue.append(u2);
loadQueue.append(u3);
if ((cmdBuffer.size()+3 >= 37-5) || (sndPoint-1 == document->instPoints.size()))
{
sendCommand(Command::kAddPoints, static_cast<uint8_t>(cmdBuffer.size()/3));
}
sndPoint++;
oldX = x;
oldY = y;
......