From 35050fad90899ec079d6bbb1bef79847dfdc58c2 Mon Sep 17 00:00:00 2001 From: Francois CARON Date: Wed, 10 Jul 2024 15:45:22 +0200 Subject: [PATCH 1/9] Use thin material per default --- CutDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/CutDialog.cpp b/CutDialog.cpp index 71c932c3..23de9e84 100644 --- a/CutDialog.cpp +++ b/CutDialog.cpp @@ -4,6 +4,7 @@ CutDialog::CutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CutDialog) { ui->setupUi(this); + ui->mediaCombo->setCurrentIndex(5); // ui->mediaCombo->setCurrentIndex(ProgramOptions::Instance().getMedia()); // ui->speedSlider->setValue(ProgramOptions::Instance().getSpeed()); // ui->pressureSlider->setValue(ProgramOptions::Instance().getPressure()); From 0b076f6d9fea1ebc33fe5afbce0f94e25a3a6230 Mon Sep 17 00:00:00 2001 From: Francois CARON Date: Wed, 10 Jul 2024 15:48:39 +0200 Subject: [PATCH 2/9] Add a setRegMarks function --- CutDialog.cpp | 8 ++++++++ CutDialog.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/CutDialog.cpp b/CutDialog.cpp index 23de9e84..7a915db4 100644 --- a/CutDialog.cpp +++ b/CutDialog.cpp @@ -69,6 +69,14 @@ bool CutDialog::trackEnhancing() const return ui->trackEnhancingCheckbox->isChecked(); } +void CutDialog::setRegMarks(QRectF bounding) const +{ + ui->regMarksGroup->setEnabled(!bounding.isNull()); + ui->regMarksGroup->setChecked(!bounding.isNull()); + ui->regWidthSpinner->setValue(bounding.width()); + ui->regHeightSpinner->setValue(bounding.height()); +} + bool CutDialog::regMark() const { return ui->regMarksGroup->isChecked(); diff --git a/CutDialog.h b/CutDialog.h index 8ac5a41d..86d2a70b 100644 --- a/CutDialog.h +++ b/CutDialog.h @@ -36,6 +36,8 @@ class CutDialog : public QDialog double regWidth() const; double regHeight() const; + void setRegMarks(QRectF bounding) const; + protected: void changeEvent(QEvent* e) override; From dc4cf169f198e81facb24095dba23dec9b95642b Mon Sep 17 00:00:00 2001 From: Francois CARON Date: Wed, 10 Jul 2024 15:49:05 +0200 Subject: [PATCH 3/9] Change default regmarks size --- CutDialog.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CutDialog.ui b/CutDialog.ui index 196b620e..10c81e26 100644 --- a/CutDialog.ui +++ b/CutDialog.ui @@ -403,7 +403,7 @@ 300.000000000000000 - 180.000000000000000 + 190.000000000000000 @@ -435,7 +435,7 @@ 1000.000000000000000 - 240.000000000000000 + 275.000000000000000 From 016d2d240221305249115b89d23515ba8b0930d2 Mon Sep 17 00:00:00 2001 From: Francois CARON Date: Wed, 10 Jul 2024 15:52:02 +0200 Subject: [PATCH 4/9] Extract regMarks characteristics from the SVG - Enable marks support automatically when detected - Show all layers on SVG but only use Cuts layer if found for cutting --- CuttingThread.h | 2 + MainWindow.cpp | 78 +++++++++++++++------------------- MainWindow.h | 10 ++++- Plotter.cpp | 4 ++ SvgRenderer.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++---- SvgRenderer.h | 12 +++++- 6 files changed, 159 insertions(+), 56 deletions(-) diff --git a/CuttingThread.h b/CuttingThread.h index a3c6af5d..47334c83 100644 --- a/CuttingThread.h +++ b/CuttingThread.h @@ -26,6 +26,8 @@ struct CutParams bool regsearch = false; double regwidth = 0.0; double regheight = 0.0; + double regstroke = 0.0; + QPointF regoffset = QPointF(0.0,0.0); }; class CuttingThread : public QThread diff --git a/MainWindow.cpp b/MainWindow.cpp index d7701229..82e8fa42 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -244,20 +244,12 @@ void MainWindow::loadFile(QString filename) QSizeF mediaSize(render.widthMm, render.heightMm); loadedState.mediaSize = mediaSize; - loadedState.paths = std::move(render.paths); + loadedState.showpaths = std::move(render.showpaths); + loadedState.cutpaths = std::move(render.cutpaths); loadedState.filename = filename; - - // Transform the paths from user units to mm. - for (auto& path : loadedState.paths) - { - for (auto& vertex : path) - { - vertex = QPointF( - (vertex.x() - render.viewBox.x()) * render.widthMm / render.viewBox.width(), - (vertex.y() - render.viewBox.y()) * render.heightMm / render.viewBox.height()); - } - } - + loadedState.markPosition = render.markPosition; + loadedState.markOffset = render.markOffset; + loadedState.markStroke = render.markStroke; QPointF startingPoint(0.0, 0.0); // Sort the paths with the following goals: @@ -267,7 +259,8 @@ void MainWindow::loadFile(QString filename) // 3. Try not to travel too much in the Y direction (it can lead to accumulation of // errors due to the vinyl slipping in the rollers). // - loadedState.sortedPaths = sortPaths(loadedState.paths, sortMethod, startingPoint); + loadedState.sortedCutPaths = sortPaths(loadedState.cutpaths, sortMethod, startingPoint); + loadedState.sortedShowPaths = loadedState.showpaths; // Set the default zoom. auto viewSize = ui->centralWidget->size(); @@ -279,7 +272,7 @@ void MainWindow::loadFile(QString filename) // Clear the scene. clearScene(); - QRectF pageRect(0.0, 0.0, mediaSize.width(), mediaSize.height()); + QRectF pageRect(0.0, 0.0, mediaSize.width()*96/90, mediaSize.height()*96/90); // And reset the sceneRect, which it doesn't do by default. scene->setSceneRect(pageRect.adjusted(-20, -20, 20, 20)); @@ -293,7 +286,7 @@ void MainWindow::loadFile(QString filename) dimensionsItem = scene->addText( QString::number(mediaSize.width()) + " × " + QString::number(mediaSize.height()) + " mm", QFont("Helvetica", 10)); - dimensionsItem->setPos(0.0, mediaSize.height()); + dimensionsItem->setPos(0.0, mediaSize.height()*96/90); dimensionsItem->setVisible(dimensionsEnabled); // Add the rulers. @@ -307,22 +300,12 @@ void MainWindow::loadFile(QString filename) QList gridSquares; - // Add the centimetre grid. - for (int x = 0; x < mediaSize.width() / 10; ++x) - { - for (int y = x % 2; y < mediaSize.height() / 10; y += 2) - { - int w = static_cast(std::min(10.0, mediaSize.width() - x * 10.0)); - int h = static_cast(std::min(10.0, mediaSize.height() - y * 10.0)); - gridSquares.append(scene->addRect( - x * 10, - mediaSize.height() - y * 10 - h, - w, - h, - Qt::NoPen, - QBrush(QColor::fromRgb(240, 240, 240)))); - } - } + QPen mmPen = QPen(QBrush(QColor::fromRgb(240, 240, 240)), 0.0); + QPen cmPen = QPen(QBrush(QColor::fromRgb(200, 200, 200)), 0.0); + for (int x=0; x<=mediaSize.width()*96/90; x++) + gridSquares.append(scene->addLine(x,0,x,mediaSize.height()*96/90, (x%10==0)?cmPen:mmPen)); + for (int y=0; y<=mediaSize.height()*96/90; y++) + gridSquares.append(scene->addLine(0,y,mediaSize.width()*96/90,y, (y%10==0)?cmPen:mmPen)); gridItem = scene->createItemGroup(gridSquares); gridItem->setVisible(gridEnabled); @@ -396,6 +379,9 @@ void MainWindow::on_actionCut_triggered() if (!cutDialog) cutDialog = new CutDialog(this); + if (!s->markPosition.isNull()) std::cout << "Found regmarks in SVG!" << std::endl; + cutDialog->setRegMarks(s->markPosition); + if (cutDialog->exec() != QDialog::Accepted) return; @@ -404,7 +390,7 @@ void MainWindow::on_actionCut_triggered() CuttingDialog* cuttingDlg = new CuttingDialog(this); CutParams params; - params.cuts = s->sortedPaths; + params.cuts = s->sortedCutPaths; params.mediawidth = s->mediaSize.width(); params.mediaheight = s->mediaSize.height(); params.media = cutDialog->media(); @@ -412,7 +398,9 @@ void MainWindow::on_actionCut_triggered() params.regwidth = cutDialog->regWidth(); params.regheight = cutDialog->regHeight(); params.regmark = cutDialog->regMark(); + params.regoffset = s->markOffset; params.regsearch = cutDialog->regSearch(); + params.regstroke = s->markStroke; params.speed = cutDialog->speed(); params.trackenhancing = cutDialog->trackEnhancing(); @@ -495,7 +483,7 @@ void MainWindow::animate() auto& m = s->cutMarkerPos; // Make sure the current position is sane. - if (m.poly >= s->sortedPaths.size() * 2 + 1) + if (m.poly >= s->sortedCutPaths.size() * 2 + 1) { // If not, reset it. m.poly = 0; @@ -522,20 +510,20 @@ void MainWindow::animate() if (m.poly == 0) a = startingPoint; else - a = s->sortedPaths[(m.poly / 2) - 1].back(); + a = s->sortedCutPaths[(m.poly / 2) - 1].back(); - if (m.poly >= s->sortedPaths.size() * 2) + if (m.poly >= s->sortedCutPaths.size() * 2) b = startingPoint; else - b = s->sortedPaths[(m.poly / 2)].front(); + b = s->sortedCutPaths[(m.poly / 2)].front(); cutMarker->setOpacity(0.2); } else { auto pathIndex = (m.poly - 1) / 2; - a = s->sortedPaths[pathIndex][m.line]; - b = s->sortedPaths[pathIndex][m.line + 1]; + a = s->sortedCutPaths[pathIndex][m.line]; + b = s->sortedCutPaths[pathIndex][m.line + 1]; cutMarker->setOpacity(1.0); } @@ -546,13 +534,13 @@ void MainWindow::animate() { distanceRemaining -= (ln.length() - m.distance); m.distance = 0.0; - if (m.poly % 2 != 0 && m.line < s->sortedPaths[(m.poly - 1) / 2].size() - 2) + if (m.poly % 2 != 0 && m.line < s->sortedCutPaths[(m.poly - 1) / 2].size() - 2) { ++m.line; } else { - m.poly = (m.poly + 1) % (s->sortedPaths.size() * 2 + 1); + m.poly = (m.poly + 1) % (s->sortedCutPaths.size() * 2 + 1); m.line = 0; } continue; @@ -633,7 +621,7 @@ void MainWindow::addPathItemsToScene() QList pathLines; - for (const auto& path : s->sortedPaths) + for (const auto& path : s->sortedShowPaths) { QPen pen(QColor::fromHsvF(static_cast(hue), 1.0f, 0.7f)); @@ -664,7 +652,7 @@ void MainWindow::addPathItemsToScene() // Don't change the pen width with zoom. pen.setCosmetic(true); pen.setWidthF(3.0); - for (const auto& path : s->sortedPaths) + for (const auto& path : s->sortedShowPaths) { cutterPathLines.append(scene->addLine(QLineF(currentPoint, path.first()), pen)); currentPoint = path.last(); @@ -752,7 +740,7 @@ void MainWindow::onSortMethodTriggered(QAction* action) // Resort the paths. QPointF startingPoint(0.0, 0.0); - s->sortedPaths = sortPaths(s->paths, sortMethod, startingPoint); + s->sortedCutPaths = sortPaths(s->cutpaths, sortMethod, startingPoint); // Remove the path items and re-add them. addPathItemsToScene(); @@ -893,7 +881,7 @@ void MainWindow::on_actionExport_HPGL_triggered() if (filename.isEmpty()) return; - auto hpgl = renderToHPGL2(s->sortedPaths, s->mediaSize.width(), s->mediaSize.height()); + auto hpgl = renderToHPGL2(s->sortedShowPaths, s->mediaSize.width(), s->mediaSize.height()); QSaveFile file(filename); if (!file.open(QIODevice::WriteOnly)) diff --git a/MainWindow.h b/MainWindow.h index 5b2e5087..4ba5b95f 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -48,17 +48,23 @@ struct StateFileLoaded // Filename it was loaded from. QString filename; // The polygons to cut, in mm. - QList paths; + QList cutpaths; + QList showpaths; // The page size in mm. QSizeF mediaSize; // The default zoom for this document, which is based on its size. double defaultZoom = 1.0; // The sorted paths. - QList sortedPaths; + QList sortedCutPaths; + QList sortedShowPaths; // Position of the cut marker for the animate feature. CutMarkerPos cutMarkerPos; + + QRectF markPosition; + QPointF markOffset; + double markStroke; }; class MainWindow : public QMainWindow diff --git a/Plotter.cpp b/Plotter.cpp index ed6983b7..dca1220b 100644 --- a/Plotter.cpp +++ b/Plotter.cpp @@ -8,9 +8,13 @@ #include #include +#include + namespace { +int noPressure = 0; + std::string UsbError(int e) { switch (e) diff --git a/SvgRenderer.cpp b/SvgRenderer.cpp index c4d42fec..863480df 100644 --- a/SvgRenderer.cpp +++ b/SvgRenderer.cpp @@ -7,6 +7,12 @@ #include #include #include +#include +#include + +#include + +#include #include "PathPaintDevice.h" @@ -89,6 +95,9 @@ struct SvgXmlData { QString widthAttribute; QString heightAttribute; + QString cutElementId = QString(); + QString markElementId = QString(); + double markStroke; bool hasTspanPosition = false; @@ -136,7 +145,24 @@ SvgXmlData scanSvgElements(const QByteArray& svgContents, bool searchForTspans) return data; } } - + else if ((xml.name() == u"g") && attr.hasAttribute("id") && attr.value("inkscape:label").contains(QString("cut"),Qt::CaseInsensitive)) + { + data.cutElementId = attr.value("id").toString(); + } + else if ((xml.name() == u"g") && attr.hasAttribute("id") && attr.value("inkscape:label").contains(QString("regmarks"),Qt::CaseInsensitive)) + { + data.markElementId = attr.value("id").toString(); + } + else if ((xml.name() == u"path") && attr.hasAttribute("style") && attr.value("inkscape:label").contains(QString("RightMarkH"),Qt::CaseInsensitive)) + { + std::cout<< "found mark" << std::endl; + auto style = attr.value("style").toString(); + QRegularExpression re("stroke-width:(\\d+(\\.\\d+)?)"); + QRegularExpressionMatch match = re.match(style); + if (match.hasMatch()) { + data.markStroke = match.captured(1).toDouble(); + } + } break; } default: @@ -180,6 +206,9 @@ SResult svgToPaths(const QString& filename, bool searchForTspans) render.widthAttribute = xmlData.widthAttribute; render.heightAttribute = xmlData.heightAttribute; render.hasTspanPosition = xmlData.hasTspanPosition; + render.cutElementId = xmlData.cutElementId; + render.markElementId = xmlData.markElementId; + render.markStroke = xmlData.markStroke; QSvgRenderer renderer; if (!renderer.load(svgContents)) @@ -187,22 +216,86 @@ SResult svgToPaths(const QString& filename, bool searchForTspans) render.viewBox = renderer.viewBoxF(); - // Give the size of the canvas. We just use 1 user unit per pixel and - // then convert later. PathPaintDevice pg(render.viewBox.width(), render.viewBox.height()); QPainter p(&pg); - // Render, this will assume 1 user unit = 1px. - renderer.render(&p, render.viewBox); + if (!render.markElementId.isEmpty()) { + double x0,y0,x1,y1; + PathPaintDevice pgmark(render.viewBox.width(), render.viewBox.height()); + QPainter pmark(&pgmark); + QRectF bound1 = renderer.boundsOnElement(render.markElementId); + QTransform transf = renderer.transformForElement(render.markElementId); + render.markPosition = transf.mapRect(bound1); + renderer.render(&pmark, render.markElementId, render.markPosition); + render.markPosition.getCoords(&x0, &y0, &x1, &y1); + render.markPosition.setCoords(x0* MM_PER_PX, y0* MM_PER_PX, x1* MM_PER_PX, y1* MM_PER_PX); + bool start = true; + for ( auto polygon : pgmark.paths() ) { + for ( QPointF point : polygon ) { + if (start) { + render.markOffset = point; + start = false; + } else { + if ((point.x() >= render.markOffset.x()) && (point.y() <= render.markOffset.y())) + render.markOffset = point; + } + } + } + render.markOffset = QPointF( + (render.markOffset.x()+(render.markStroke/2.0)) * MM_PER_PX, + (render.markOffset.y()+(render.markStroke/2.0)) * MM_PER_PX); + std::cout<<"markOffset " < paths; + QList showpaths; + QList cutpaths; // The view box (the visible portal of the SVG) in user units. QRectF viewBox; @@ -21,6 +22,15 @@ struct SvgRender QString widthAttribute; QString heightAttribute; + //The Cut Layer only + QString cutElementId = QString(); + + //The Registration marks layer only + QString markElementId = QString(); + QRectF markPosition = QRectF(); + QPointF markOffset; + double markStroke; + // The width and height in mm if they have been specified. This is calculated // from the width= and height= attributes, if they have physical units. If they // are in user units then it is assumed to be mm. If they are in % or are not present From db8b2930027feb11daf0c651c92df59d5647f476 Mon Sep 17 00:00:00 2001 From: Francois CARON Date: Wed, 10 Jul 2024 15:52:39 +0200 Subject: [PATCH 5/9] On CC200, there is no pressure management, so assume maximum pressure on CC200 --- Plotter.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Plotter.cpp b/Plotter.cpp index dca1220b..fd9493ea 100644 --- a/Plotter.cpp +++ b/Plotter.cpp @@ -158,6 +158,11 @@ SResult UsbOpen() if (PRODUCT_ID_LIST.count(desc.idProduct) == 0) continue; + if (desc.idProduct == 0x110a) { + std::cout<< "CC200-20 detected - Pressure set to maximum\n"; + noPressure = 1; + } else noPressure = 0; + libusb_device_handle* handle = nullptr; // Currently use the first device found. @@ -315,6 +320,9 @@ SResult<> Cut(CutParams p) if (!handleRes) return handleRes; + if (noPressure != 0) + p.pressure = 33; + auto handle = std::move(handleRes.unwrap()); // TODO: Renable this. From cdb580caa07da89e81bc50f0c8b43c815a45dada Mon Sep 17 00:00:00 2001 From: Francois CARON Date: Wed, 10 Jul 2024 15:55:48 +0200 Subject: [PATCH 6/9] Fix regmarks usage - Need to to use regmarks doc added as starting document. REegmarks and Cuts layer are mandatory to use regmarks --- Plotter.cpp | 73 ++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/Plotter.cpp b/Plotter.cpp index fd9493ea..0d23d85f 100644 --- a/Plotter.cpp +++ b/Plotter.cpp @@ -374,7 +374,7 @@ SResult<> Cut(CutParams p) return Err(std::string("Moving, please try again.")); if (resp == "2\x03") return Err(std::string("Empty tray, please load media.")); // Silhouette Cameo - return Err("Unexpected response from plotter: '" + resp + "' (" + string_to_hex(resp) + ")"); + return Err("1 Unexpected response from plotter: '" + resp + "' (" + string_to_hex(resp) + ") instead "+ string_to_hex("1\x03")); } // Home the cutter. @@ -418,11 +418,6 @@ SResult<> Cut(CutParams p) if (!e) return e; - // Set to portrait. FN1 does landscape but it's easier just to rotate the image. - e = UsbSend(handle, "FN0\x03"); - if (!e) - return e; - e = UsbSend(handle, "FE0\x03"); // No idea what this does. if (!e) return e; @@ -437,14 +432,19 @@ SResult<> Cut(CutParams p) resp = sr.unwrap(); - if (resp != " 0, 0\x03") - return Err("Unexpected response from plotter: '" + resp + "' (" + string_to_hex(resp) + ")"); + if (resp != " 1, 0\x03") + return Err("2 Unexpected response from plotter: '" + resp + "' (" + string_to_hex(resp) + ") instead "+ string_to_hex(" 0, 0\x03")); // Begin page definition. e = UsbSend(handle, "FA\x03"); if (!e) return e; + // Set to portrait. FN1 does landscape but it's easier just to rotate the image. + e = UsbSend(handle, "FN0\x03"); + if (!e) + return e; + // Page size: height,width in 20ths of a mm minus a margin. This is for A4. TODO: Find maximum and use that. std::stringstream page; @@ -461,13 +461,21 @@ SResult<> Cut(CutParams p) if (!e) return e; + //flushing USB for clean pipe state + while (UsbReceive(handle, 500)); + if (p.regmark) { + //Get current position std::stringstream regmarkstr; regmarkstr.precision(0); std::string searchregchar = "23,"; int regw = static_cast(lround(p.regwidth * 20.0)); int regl = static_cast(lround(p.regheight * 20.0)); + + //flushing USB for clean pipe state + while (UsbReceive(handle, 500)); + e = UsbSend(handle, "TB50,381\x03"); // only with registration (it was TB50,1) ??? if (!e) return e; @@ -490,35 +498,23 @@ SResult<> Cut(CutParams p) sr = UsbReceive(handle, 40000); // Allow 40s for reply... if (!sr) return sr; - - resp = sr.unwrap(); - if (resp != " 0, 0\x03") - { - std::cout << resp << "\n"; - return Err(std::string("Couldn't find registration marks.")); - } - // Looks like if the reg marks work it gets 3 messages back (if it fails it times out because it only gets the - // first message) - sr = UsbReceive(handle, 40000); // Allow 40s for reply... - if (!sr) - return sr; - resp = sr.unwrap(); if (resp != " 0\x03") { std::cout << resp << "\n"; - return Err(std::string("Couldn't find registration marks.")); + e = UsbSend(handle, "TT"); + return Err(std::string("Couldn't find registration marks - Back to Home.")); } sr = UsbReceive(handle, 40000); // Allow 40s for reply... if (!sr) return sr; - resp = sr.unwrap(); if (resp != " 1\x03") { std::cout << resp << "\n"; - return Err(std::string("Couldn't find registration marks.")); + e = UsbSend(handle, "TT"); + return Err(std::string("Couldn't find registration marks - Back to Home.")); } } else @@ -538,53 +534,40 @@ SResult<> Cut(CutParams p) // Set the "factor" to 100,100,100, whatever that means. // \0,0 is "write lower left". Z is "write upper right", so I think this sets the bounds in some way. page << "&100,100,100,\\0,0,Z" << ItoS(width) << "," << ItoS(height) << ",L0"; + for (const auto& cut : p.cuts) { if (cut.size() < 2) continue; - for (int i = 0; i < cut.size(); ++i) { - double x = cut[i].x() * 20.0; - double y = cut[i].y() * 20.0; - + std::cout<<"cut " << p.regoffset.x() - cut[i].x() << "," << cut[i].y()-p.regoffset.y() << std::endl; + double x = (p.regoffset.x() - cut[i].x()) * 20.0; + double y = (cut[i].y()-p.regoffset.y()) * 20.0; // double xorigin = 0;//ProgramOptions::Instance().getRegOriginWidthMM(); // double yorigin = 0;//ProgramOptions::Instance().getRegOriginHeightMM(); - // if (p.regmark) - // { - // x -= (xorigin * 20.0); - // y -= (yorigin * 20.0); - // } - // Squash to page boundaries. x = std::min(std::max(x, 0.0), double(width)); y = std::min(std::max(y, 0.0), double(height)); - // Mirror x/y. - x = width - x; - page << (i == 0 ? ",M" : ",D") << x << "," << y; } } // &1,1,1 is "Factor". TB50,0 is something to do with registration. // I suspect this command resets some settings at the end. - page << "&1,1,1,TB50,0\x03"; + // set the regmarks stroke based on svg extract + page << "&1,1,1,TB50,0\x03TB53,"<< static_cast(lround(p.regstroke * 20.0)) <<"\0x3"; // std::cout << page.str() << "\n"; - e = UsbSend(handle, page.str()); if (!e) return e; - // Feed the page out. - e = UsbSend(handle, "FO0\x03"); - if (!e) - return e; - // Home. - e = UsbSend(handle, "H,"); + std::cout<<"Back to origin"< Date: Wed, 10 Jul 2024 16:01:51 +0200 Subject: [PATCH 7/9] Add registration mark for 14 portrait --- examples/Registration marks A4 portrait.svg | 285 ++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 examples/Registration marks A4 portrait.svg diff --git a/examples/Registration marks A4 portrait.svg b/examples/Registration marks A4 portrait.svg new file mode 100644 index 00000000..737e503f --- /dev/null +++ b/examples/Registration marks A4 portrait.svg @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Markus Schulz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7994c8a2cc00803cc3409789733eb952d7949978 Mon Sep 17 00:00:00 2001 From: Francois CARON Date: Wed, 10 Jul 2024 16:11:00 +0200 Subject: [PATCH 8/9] Clean traces --- SvgRenderer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/SvgRenderer.cpp b/SvgRenderer.cpp index 863480df..30418feb 100644 --- a/SvgRenderer.cpp +++ b/SvgRenderer.cpp @@ -269,8 +269,6 @@ SResult svgToPaths(const QString& filename, bool searchForTspans) render.widthMm = sizeAttributeToMm(render.widthAttribute).value_or(render.viewBox.width() * MM_PER_PX); render.heightMm = sizeAttributeToMm(render.heightAttribute).value_or(render.viewBox.height() * MM_PER_PX); - std::cout<<"width "< Date: Wed, 10 Jul 2024 16:54:16 +0200 Subject: [PATCH 9/9] Assume show path and cut apth are the same when there is no dedicated cut layer --- SvgRenderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SvgRenderer.cpp b/SvgRenderer.cpp index 30418feb..565adec4 100644 --- a/SvgRenderer.cpp +++ b/SvgRenderer.cpp @@ -259,6 +259,7 @@ SResult svgToPaths(const QString& filename, bool searchForTspans) else { // //No specific cut layer - Draw all layers - But can ont use regmarks. renderer.render(&p); + render.cutpaths = pg.paths(); // These are the paths in user units. } render.showpaths = pg.paths();