Newer
Older
/*
* Copyright (c) 2015 Tricoire Sebastien 3dsman@free.fr
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
*/
#include "OE_controller.h"
#include <iostream>
#include <typeinfo>
#include "actions/OE_actionsCurves.h"
#include "actions/OE_actionsStitchs.h"
#include "actions/OE_actionsLineStitchs.h"
#include "actions/OE_actionsBirailStitchs.h"
#include "actions/OE_actionsLinkStitchs.h"
#include "actions/OE_actionsSelection.h"
#include "actions/OE_actionsThreads.h"
// comm("/dev/ttyUSB0", 80, 10)
// comm("/dev/tty", 80, 10)
// comm("20:15:05:11:28:40", 80, 30)
// comm("/dev/rfcomm1", 80, 30)
OE_controller::OE_controller(OE_display* display, OE_document* document) : display(display), document(document)
#ifdef OE_HARDWARE_SUPPORT
,comm(getenv("SERIALPORT")?getenv("SERIALPORT"):"/dev/rfcomm0", 80, 30)
#endif
// TODO remove
if (document && document->threads.empty())
{
document->addThread(new OE_thread(OE_color(.4, .4, .4), 2));
}
}
OE_controller::~OE_controller()
{
}
void OE_controller::setDocument(OE_document* document)
{
OE_document* OE_controller::getDocument()
{
return document;
}
3dsman
committed
/*
void OE_controller::newSubCurve(OE_curve* curve, float curveStart, float curveEnd, bool reverse)
addAction(new OE_actionNewSubCurve(curve, curveStart, curveEnd, reverse));
}
void OE_controller::newSubCurve(int ncurve, float curveStart, float curveEnd, bool reverse)
{
newSubCurve(getCurve(ncurve), curveStart, curveEnd, reverse);
}
3dsman
committed
*/
void OE_controller::newBirailStitch(bool reverse1, bool reverse2, float offset1, float offset2, float len)
addAction(new OE_actionNewBirailStitch(document, reverse1, reverse2, offset1, offset2, len));
void OE_controller::newLineStitch(float len, float width, OE_pattern* pattern, unsigned patternSteps, float xOffset, float yOffset)
addAction(new OE_actionNewLineStitch(document, len, width, pattern, patternSteps, xOffset, yOffset));
void OE_controller::newFillStitch(float len, float width, OE_pattern* pattern)
addAction(new OE_actionNewFillStitch(document, len, width, pattern));
void OE_controller::setStitchThread(OE_stitchs* stitch, OE_thread* thread)
addAction(new OE_actionSetStitchThread(document, stitch, thread));
void OE_controller::setStitchThread(int nstitch, int nthread)
{
setStitchThread(getStitch(nstitch), getThread(nthread));
}
void OE_controller::setCloseCurve(OE_curve* curve, bool closed)
{
addAction(new OE_actionSetCloseCurve(document, curve, closed));
}
void OE_controller::setCloseCurve(int ncurve, bool closed)
{
}
void OE_controller::toggleCloseSelectedCurve()
{
OE_curve* curve = document->selectedCurves.back();
if (curve)
{
setCloseCurve(curve, !curve->getClosed());
}
bool OE_controller::initNewDocument()
{
addAction(new OE_actionNewThread(document, new OE_thread(OE_color(.9, .5, .1), 2)));
bool OE_controller::setDefault()
{
OE_birailstitch::defaultLen = 1;
OE_birailstitch::defaultMaxlen = 0;
return true;
}
index = document->curves.size() + index;
}
if (document && 0<=index && index<document->curves.size())
std::list<OE_pointcurve*>::iterator curve = document->curves.begin();
for (unsigned i=0; i<index; i++)
{
curve++;
return nullptr;
}
OE_pointcurve* OE_controller::getPointcurve(int index)
}
OE_subcurve* OE_controller::getSubcurve(int index)
}
OE_joincurve* OE_controller::getJoincurve(int index)
}
{
index = document->stitchs.size() + index;
}
if (document && 0<=index && index<document->stitchs.size())
{
std::list<OE_stitchs*>::iterator stitch = document->stitchs.begin();
stitch++;
return nullptr;
}
OE_linestitch* OE_controller::getLineStitch(int index)
OE_birailstitch* OE_controller::getBirailStitch(int index)
OE_fillstitch* OE_controller::getFillStitch(int index)
OE_linkstitch* OE_controller::getLinkStitch(int index)
3dsman
committed
{
3dsman
committed
}
{
index = document->threads.size() + index;
}
if (document && 0<=index && index<document->threads.size())
{
std::list<OE_thread*>::iterator thread = document->threads.begin();
thread++;
return nullptr;
}
3dsman
committed
{
if (document)
{
if (index<0)
if (0<=index && index<document->patterns.size())
{
std::list<OE_pattern*>::iterator pattern = document->patterns.begin();
}
}
return nullptr;
}
void OE_controller::clearUndoActionStack()
if (document)
{
OE_document::ScopeLock lock(*document);
//flush the undoActionStack
while (!document->undoActionsStack.empty())
{
delete document->undoActionsStack.back();
document->undoActionsStack.pop_back();
}
}
void OE_controller::addAction(OE_actions* action)
OE_document::ScopeLock lock(*document);
//flush the undoActionStack
while (!(document->undoActionsStack.empty()))
{
delete document->undoActionsStack.back();
document->undoActionsStack.pop_back();
}
//push the new action to the active stack
document->activeActionsStack.push_front(action);
}
if (document)
{
OE_document::ScopeLock lock(*document);
if (document->activeActionsStack.size())
{
// get and undo the last action from active action stack
OE_actions* action = *document->activeActionsStack.begin();
// move the action from active to undo action stack
document->activeActionsStack.pop_front();
document->undoActionsStack.push_front(action);
}
}
}
if (document)
{
OE_document::ScopeLock lock(*document);
if (document->undoActionsStack.size())
{
// get and redo the last action from undo action stack
// move the action from undo to active action stack
document->undoActionsStack.pop_front();
document->activeActionsStack.push_front(action);
}
bool OE_controller::selectCurve(OE_pointcurve* curve, bool replace)
bool OE_controller::selectCurves(std::list<OE_pointcurve*> curves, bool replace)
addAction(new OE_actionSelectionAddCurves(document, curves, replace));
bool OE_controller::unselectCurves(std::list<OE_pointcurve*> curves)
addAction(new OE_actionSelectionRemoveCurves(document, curves));
3dsman
committed
bool OE_controller::clearSelectCurves()
{
addAction(new OE_actionSelectionClearCurves(document));
3dsman
committed
}
bool OE_controller::selectStitch(OE_stitchs* stitch, bool replace)
bool OE_controller::selectStitches(std::list<OE_stitchs*> stitches, bool replace)
addAction(new OE_actionSelectionAddStitches(document, stitches, replace));
bool OE_controller::unselectStitches(std::list<OE_stitchs*> stitches)
addAction(new OE_actionSelectionRemoveStitches(document, stitches));
3dsman
committed
bool OE_controller::clearSelectStitches()
{
addAction(new OE_actionSelectionClearStitches(document));
3dsman
committed
}
bool OE_controller::clearSelection()
{
addAction(new OE_actionSelectionClear(document));
3dsman
committed
}
BoundingBox OE_controller::getSelectionBoundingBox()
{
BoundingBox boundingBox;
for (auto curve : document->selectedCurves)
{
boundingBox += curve->getBound();
}
for (auto stitch : document->selectedStitchs)
{
boundingBox += stitch->getBound();
}
return boundingBox;
}
if (document && document->activeActionsStack.size())
{
return *document->activeActionsStack.begin();
}
return nullptr;
bool OE_controller::editActionMovePointCurve(vector_2d offset)
{
OE_actionMovePointCurve* actionMovePointCurve = dynamic_cast<OE_actionMovePointCurve*>(getLastAction());
if (actionMovePointCurve)
{
actionMovePointCurve->setMove(offset);
return true;
}
return false;
3dsman
committed
bool OE_controller::editActionMovePointLinkStitch(vector_2d offset)
{
OE_actionAddPointLinkStitch* actionAddPointLinkStitch = dynamic_cast<OE_actionAddPointLinkStitch*>(getLastAction());
OE_actionMovePointLinkStitch* actionMovePointLinkStitch = dynamic_cast<OE_actionMovePointLinkStitch*>(getLastAction());
if (actionAddPointLinkStitch)
{
3dsman
committed
return true;
}
else if (actionMovePointLinkStitch)
{
3dsman
committed
return true;
}
return false;
}
bool OE_controller::editActionMoveGridPointFillStitch(vector_2d offset)
{
OE_actionMovePointFillStitch* actionMovePointFillStitch = dynamic_cast<OE_actionMovePointFillStitch*>(getLastAction());
if (actionMovePointFillStitch)
{
actionMovePointFillStitch->setOffset(offset);
return true;
}
return false;
}
bool OE_controller::editActionMoveSelection(vector_2d offset)
{
OE_actionMoveSelection* actionMoveSelection = dynamic_cast<OE_actionMoveSelection*>(getLastAction());
if (actionMoveSelection)
{
bool OE_controller::editActionScaleSelection(vector_2d ratio)
{
OE_actionScaleSelection* actionScaleSelection = dynamic_cast<OE_actionScaleSelection*>(getLastAction());
if (actionScaleSelection)
{
}
return false;
}
bool OE_controller::editActionSetSubcurvePos(float val)
OE_actionSetSubcurvePos* actionSetSubcurvePos = dynamic_cast<OE_actionSetSubcurvePos*>(getLastAction());
if (actionSetSubcurvePos)
{
actionSetSubcurvePos->setPos(val);
return true;
}
return false;
bool OE_controller::editActionSetSubcurvePosSwitchDir()
{
OE_actionSetSubcurvePos* actionJoincurveSetSubcurve = dynamic_cast<OE_actionSetSubcurvePos*>(getLastAction());
if (actionJoincurveSetSubcurve)
{
actionJoincurveSetSubcurve->setInvertDir(!actionJoincurveSetSubcurve->getInvertDir());
return true;
}
return false;
3dsman
committed
bool OE_controller::editActionAddSubcurvePosEnd(float val)
{
OE_actionJoincurveAddSubCurve* actionJoincurveAddSubcurve = dynamic_cast<OE_actionJoincurveAddSubCurve*>(getLastAction());
if (actionJoincurveAddSubcurve)
{
actionJoincurveAddSubcurve->setEnd(val);
return true;
}
return false;
bool OE_controller::editActionAddSubcurvePosSwitchDir()
3dsman
committed
{
OE_actionJoincurveAddSubCurve* actionJoincurveAddSubcurve = dynamic_cast<OE_actionJoincurveAddSubCurve*>(getLastAction());
if (actionJoincurveAddSubcurve)
{
actionJoincurveAddSubcurve->setDir(!actionJoincurveAddSubcurve->getDir());
return true;
}
return false;
3dsman
committed
}
bool OE_controller::editActionSetLinestitchWidth(float val, bool offset)
OE_actionSetLineStitchWidth* actionSetLineStitchWidth = dynamic_cast<OE_actionSetLineStitchWidth*>(getLastAction());
if (actionSetLineStitchWidth)
actionSetLineStitchWidth->offsetWidth(val);
actionSetLineStitchWidth->setWidth(val);
return true;
}
return false;
}
3dsman
committed
{
if (document)
{
std::list<OE_stitchs*>::iterator stitch = document->stitchs.begin();
while (stitch != document->stitchs.end())
(*stitch)->refresh(dpi, force);
stitch++;
}
generateInstructions();
3dsman
committed
}
return true;
}
bool OE_controller::setThreadColor(unsigned index, unsigned char r, unsigned char g, unsigned char b)
{
OE_thread* tmpthread = getThread(index);
if (!tmpthread)
{
return false;
}
tmpthread->setColor(r, g, b);
return true;
}
bool OE_controller::setThreadWidth(unsigned index, float width)
{
OE_thread* tmpthread = getThread(index);
if (!tmpthread)
{
return false;
}
tmpthread->setWidth(width);
return true;
}
bool OE_controller::setsubcurvePos(int index, float start, float end)
OE_subcurve* tmpcurve = getSubcurve(index);
if (!tmpcurve)
{
return false;
}
tmpcurve->setStart(start);
tmpcurve->setEnd(end);
return true;
}
vector_2dt OE_controller::getClosestPoint(OE_curve* curve, vector_2d point)
{
if (curve)
{
return curve->closestPoint(point);
}
return vector_2dt(vector_2d(0, 0), 0);
}
OE_curve* OE_controller::getClosestCurve(vector_2d point, vector_2dt &closestPoint)
{
if (document)
{
std::list<OE_pointcurve*>::iterator curve = document->curves.begin();
vector_2dt tmpPoint;
//vector_2dt minPoint;
double minDistance;
double tmpDistance;
if (curve != document->curves.end())
{
closestPoint = (*curve)->closestPoint(point);
minDistance = (closestPoint.v-point).len();
minCurve = *curve;
curve++;
}
while (curve != document->curves.end())
{
tmpPoint = (*curve)->closestPoint(point);
tmpDistance = (tmpPoint.v-point).len();
if (tmpDistance < minDistance)
{
closestPoint = tmpPoint;
minDistance = tmpDistance;
minCurve = *curve;
}
curve++;
}
return minCurve;
}
return nullptr;
bool OE_controller::generateInstructions()
{
document->instPoints.clear();
for (unsigned i = 0; i < document->instCommand.size(); i++)
{
delete document->instCommand.at(i);
}
document->instCommand.clear();
std::list<OE_stitchs*>::iterator stitch = document->stitchs.begin();
OE_thread* instThread = document->threads.front();
if (stitch != document->stitchs.end() && (*stitch)->getThread())
{
instThread = (*stitch)->getThread();
}
document->instCommand.push_back(new OE_start(document->instPoints.size(), instThread->getColor()));
while (stitch != document->stitchs.end())
//(*stitch)->refresh(0, true);
if (!curThread)
curThread = document->threads.front();
}
{
instThread = curThread;
document->instCommand.push_back(new OE_waitcolor(document->instPoints.size(), instThread->getColor()));
std::vector<vector_2d> points = (*stitch)->getPoints();
document->instPoints.insert(document->instPoints.end(), points.begin(), points.end());
stitch++;
vector_2d zero = document->getZeroPoint();
float size = document->getPulseByMm();
{
document->instPoints.at(i) = (document->instPoints.at(i) - zero)*size;
uint8_t int7(int i) // transform int32 to int7
{
if (i>=0)
void OE_controller::sendInstPoint()
{
#define TEST_COMM_ACK(errmsg) \
if (!comm.ack()) \
{\
std::cerr << errmsg << std::endl;\
}
static bool running = false;
static int oldX, oldY;
static unsigned sndPoint;
static uint8_t dxys[32];
static bool started = false;
if (!running)
{
std::cout << "sendInstPoint x " << document->instPoints.size() <<std::endl;
comm.stopMove();
sndPoint = 0;
running = true;
} else {
document->curPoint = comm.info.nPoint;
int x, y, dx, dy, bigdx, bigdy;
unsigned cmdPoints = 0;
if (!started && comm.info.spaceSize && comm.info.freeSpace<512)
{
if (sndPoint<document->instPoints.size() && comm.info.spaceSize && comm.info.freeSpace>64)
while (sndPoint<document->instPoints.size())
x = roundf(document->instPoints.at(sndPoint).x);
y = roundf(-document->instPoints.at(sndPoint).y);
dx = x-oldX;
dy = y-oldY;
if ((dx<-64)||(63<dx)||(dy<-64)||(63<dy))
bigdx = (dx+(dx>=0?0:1))/64;
bigdy = (dy+(dy>=0?0:1))/64;
dx -= 64*bigdx;
dy -= 64*bigdy;
if (cmdPoints==15)
{
comm.addPoints(dxys, 15);
return;
}
dxys[2*cmdPoints] = 0x80|int7(bigdx);
dxys[2*cmdPoints+1] = int7(bigdy);
cmdPoints++;
dxys[2*cmdPoints] = int7(dx);
dxys[2*cmdPoints+1] = int7(dy);
sndPoint++;
oldX = x;
oldY = y;
if (cmdPoints==16)
{
comm.addPoints(dxys, 16);
comm.addPoints(dxys, cmdPoints);