+
+#include "dl_attributes.h"
+#include "dl_codes.h"
+
+
+
+/**
+ * Defines interface for writing low level DXF constructs to
+ * a file. Implementation is defined in derived classes that write
+ * to binary or ASCII files.
+ *
+ * Implements functions that write higher level constructs in terms of
+ * the low level ones.
+ *
+ * @todo Add error checking for string/entry length.
+ */
+class DXFLIB_EXPORT DL_Writer {
+public:
+ /**
+ * @param version DXF version. Defaults to DL_VERSION_2002.
+ */
+ DL_Writer(DL_Codes::version version) : m_handle(0x30) {
+ this->version = version;
+ modelSpaceHandle = 0;
+ paperSpaceHandle = 0;
+ paperSpace0Handle = 0;
+ }
+
+ virtual ~DL_Writer() {}
+ ;
+
+ /** Generic section for section 'name'.
+ *
+ *
+ * 0
+ * SECTION
+ * 2
+ * name
+ *
+ */
+ void section(const char* name) const {
+ dxfString(0, "SECTION");
+ dxfString(2, name);
+ }
+
+ /**
+ * Section HEADER
+ *
+ *
+ * 0
+ * SECTION
+ * 2
+ * HEADER
+ *
+ */
+ void sectionHeader() const {
+ section("HEADER");
+ }
+
+ /**
+ * Section TABLES
+ *
+ *
+ * 0
+ * SECTION
+ * 2
+ * TABLES
+ *
+ */
+ void sectionTables() const {
+ section("TABLES");
+ }
+
+ /**
+ * Section BLOCKS
+ *
+ *
+ * 0
+ * SECTION
+ * 2
+ * BLOCKS
+ *
+ */
+ void sectionBlocks() const {
+ section("BLOCKS");
+ }
+
+ /**
+ * Section ENTITIES
+ *
+ *
+ * 0
+ * SECTION
+ * 2
+ * ENTITIES
+ *
+ */
+ void sectionEntities() const {
+ section("ENTITIES");
+ }
+
+ /**
+ * Section CLASSES
+ *
+ *
+ * 0
+ * SECTION
+ * 2
+ * CLASSES
+ *
+ */
+ void sectionClasses() const {
+ section("CLASSES");
+ }
+
+ /**
+ * Section OBJECTS
+ *
+ *
+ * 0
+ * SECTION
+ * 2
+ * OBJECTS
+ *
+ */
+ void sectionObjects() const {
+ section("OBJECTS");
+ }
+
+ /**
+ * End of a section.
+ *
+ *
+ * 0
+ * ENDSEC
+ *
+ */
+ void sectionEnd() const {
+ dxfString(0, "ENDSEC");
+ }
+
+ /**
+ * Generic table for table 'name' with 'num' entries:
+ *
+ *
+ * 0
+ * TABLE
+ * 2
+ * name
+ * 70
+ * num
+ *
+ */
+ void table(const char* name, int num, int h=0) const {
+ dxfString(0, "TABLE");
+ dxfString(2, name);
+ if (version>=DL_VERSION_2000) {
+ if (h==0) {
+ handle();
+ }
+ else {
+ dxfHex(5, h);
+ }
+ dxfString(100, "AcDbSymbolTable");
+ }
+ dxfInt(70, num);
+ }
+
+ /** Table for layers.
+ *
+ * @param num Number of layers in total.
+ *
+ *
+ * 0
+ * TABLE
+ * 2
+ * LAYER
+ * 70
+ * num
+ *
+ */
+ void tableLayers(int num) const {
+ table("LAYER", num, 2);
+ }
+
+ /** Table for line types.
+ *
+ * @param num Number of line types in total.
+ *
+ *
+ * 0
+ * TABLE
+ * 2
+ * LTYPE
+ * 70
+ * num
+ *
+ */
+ void tableLinetypes(int num) const {
+ //linetypeHandle = 5;
+ table("LTYPE", num, 5);
+ }
+
+ /** Table for application id.
+ *
+ * @param num Number of registered applications in total.
+ *
+ *
+ * 0
+ * TABLE
+ * 2
+ * APPID
+ * 70
+ * num
+ *
+ */
+ void tableAppid(int num) const {
+ table("APPID", num, 9);
+ }
+
+ /** Table for text style.
+ *
+ * @param num Number of text styles.
+ *
+ *
+ * 0
+ * TABLE
+ * 2
+ * STYLE
+ * 70
+ * num
+ *
+ */
+ void tableStyle(int num) const {
+ table("STYLE", num, 3);
+ }
+
+ /**
+ * End of a table.
+ *
+ *
+ * 0
+ * ENDTAB
+ *
+ */
+ void tableEnd() const {
+ dxfString(0, "ENDTAB");
+ }
+
+ /**
+ * End of the DXF file.
+ *
+ *
+ * 0
+ * EOF
+ *
+ */
+ void dxfEOF() const {
+ dxfString(0, "EOF");
+ }
+
+ /**
+ * Comment.
+ *
+ *
+ * 999
+ * text
+ *
+ */
+ void comment(const char* text) const {
+ dxfString(999, text);
+ }
+
+ /**
+ * Entity.
+ *
+ *
+ * 0
+ * entTypeName
+ *
+ *
+ * @return Unique handle or 0.
+ */
+ void entity(const char* entTypeName) const {
+ dxfString(0, entTypeName);
+ if (version>=DL_VERSION_2000) {
+ handle();
+ }
+ }
+
+ /**
+ * Attributes of an entity.
+ *
+ *
+ * 8
+ * layer
+ * 62
+ * color
+ * 39
+ * width
+ * 6
+ * linetype
+ *
+ */
+ void entityAttributes(const DL_Attributes& attrib) const {
+
+ // layer name:
+ dxfString(8, attrib.getLayer());
+
+ // R12 doesn't accept BYLAYER values. The value has to be missing
+ // in that case.
+ if (version>=DL_VERSION_2000 || attrib.getColor()!=256) {
+ dxfInt(62, attrib.getColor());
+ }
+ if (version>=DL_VERSION_2000 && attrib.getColor24()!=-1) {
+ dxfInt(420, attrib.getColor24());
+ }
+ if (version>=DL_VERSION_2000) {
+ dxfInt(370, attrib.getWidth());
+ }
+ if (version>=DL_VERSION_2000) {
+ dxfReal(48, attrib.getLinetypeScale());
+ }
+ std::string linetype = attrib.getLinetype();
+ std::transform(linetype.begin(), linetype.end(), linetype.begin(), ::toupper);
+ if (version>=DL_VERSION_2000 || linetype=="BYLAYER") {
+ dxfString(6, attrib.getLinetype());
+ }
+ }
+
+ /**
+ * Subclass.
+ */
+ void subClass(const char* sub) const {
+ dxfString(100, sub);
+ }
+
+ /**
+ * Layer (must be in the TABLES section LAYER).
+ *
+ *
+ * 0
+ * LAYER
+ *
+ */
+ void tableLayerEntry(unsigned long int h=0) const {
+ dxfString(0, "LAYER");
+ if (version>=DL_VERSION_2000) {
+ if (h==0) {
+ handle();
+ } else {
+ dxfHex(5, h);
+ }
+ dxfString(100, "AcDbSymbolTableRecord");
+ dxfString(100, "AcDbLayerTableRecord");
+ }
+ }
+
+ /**
+ * Line type (must be in the TABLES section LTYPE).
+ *
+ *
+ * 0
+ * LTYPE
+ *
+ */
+ void tableLinetypeEntry(unsigned long int h=0) const {
+ dxfString(0, "LTYPE");
+ if (version>=DL_VERSION_2000) {
+ if (h==0) {
+ handle();
+ } else {
+ dxfHex(5, h);
+ }
+ //dxfHex(330, 0x5);
+ dxfString(100, "AcDbSymbolTableRecord");
+ dxfString(100, "AcDbLinetypeTableRecord");
+ }
+ }
+
+ /**
+ * Appid (must be in the TABLES section APPID).
+ *
+ *
+ * 0
+ * APPID
+ *
+ */
+ void tableAppidEntry(unsigned long int h=0) const {
+ dxfString(0, "APPID");
+ if (version>=DL_VERSION_2000) {
+ if (h==0) {
+ handle();
+ } else {
+ dxfHex(5, h);
+ }
+ //dxfHex(330, 0x9);
+ dxfString(100, "AcDbSymbolTableRecord");
+ dxfString(100, "AcDbRegAppTableRecord");
+ }
+ }
+
+ /**
+ * Block (must be in the section BLOCKS).
+ *
+ *
+ * 0
+ * BLOCK
+ *
+ */
+ void sectionBlockEntry(unsigned long int h=0) const {
+ dxfString(0, "BLOCK");
+ if (version>=DL_VERSION_2000) {
+ if (h==0) {
+ handle();
+ } else {
+ dxfHex(5, h);
+ }
+ //dxfHex(330, blockHandle);
+ dxfString(100, "AcDbEntity");
+ if (h==0x1C) {
+ dxfInt(67, 1);
+ }
+ dxfString(8, "0"); // TODO: Layer for block
+ dxfString(100, "AcDbBlockBegin");
+ }
+ }
+
+ /**
+ * End of Block (must be in the section BLOCKS).
+ *
+ *
+ * 0
+ * ENDBLK
+ *
+ */
+ void sectionBlockEntryEnd(unsigned long int h=0) const {
+ dxfString(0, "ENDBLK");
+ if (version>=DL_VERSION_2000) {
+ if (h==0) {
+ handle();
+ } else {
+ dxfHex(5, h);
+ }
+ //dxfHex(330, blockHandle);
+ dxfString(100, "AcDbEntity");
+ if (h==0x1D) {
+ dxfInt(67, 1);
+ }
+ dxfString(8, "0"); // TODO: Layer for block
+ dxfString(100, "AcDbBlockEnd");
+ }
+ }
+
+ void color(int col=256) const {
+ dxfInt(62, col);
+ }
+ void linetype(const char *lt) const {
+ dxfString(6, lt);
+ }
+ void linetypeScale(double scale) const {
+ dxfReal(48, scale);
+ }
+ void lineWeight(int lw) const {
+ dxfInt(370, lw);
+ }
+
+ void coord(int gc, double x, double y, double z=0) const {
+ dxfReal(gc, x);
+ dxfReal(gc+10, y);
+ dxfReal(gc+20, z);
+ }
+
+ void coordTriplet(int gc, const double* value) const {
+ if (value) {
+ dxfReal(gc, *value++);
+ dxfReal(gc+10, *value++);
+ dxfReal(gc+20, *value++);
+ }
+ }
+
+ void resetHandle() const {
+ m_handle = 1;
+ }
+
+ /**
+ * Writes a unique handle and returns it.
+ */
+ unsigned long handle(int gc=5) const {
+ // handle has to be hex
+ dxfHex(gc, m_handle);
+ return m_handle++;
+ }
+
+ /**
+ * @return Next handle that will be written.
+ */
+ unsigned long getNextHandle() const {
+ return m_handle;
+ }
+
+ /**
+ * Increases handle, so that the handle returned remains available.
+ */
+ unsigned long incHandle() const {
+ return m_handle++;
+ }
+
+ /**
+ * Sets the handle of the model space. Entities refer to
+ * this handle.
+ */
+ void setModelSpaceHandle(unsigned long h) {
+ modelSpaceHandle = h;
+ }
+
+ unsigned long getModelSpaceHandle() {
+ return modelSpaceHandle;
+ }
+
+ /**
+ * Sets the handle of the paper space. Some special blocks refer to
+ * this handle.
+ */
+ void setPaperSpaceHandle(unsigned long h) {
+ paperSpaceHandle = h;
+ }
+
+ unsigned long getPaperSpaceHandle() {
+ return paperSpaceHandle;
+ }
+
+ /**
+ * Sets the handle of the paper space 0. Some special blocks refer to
+ * this handle.
+ */
+ void setPaperSpace0Handle(unsigned long h) {
+ paperSpace0Handle = h;
+ }
+
+ unsigned long getPaperSpace0Handle() {
+ return paperSpace0Handle;
+ }
+
+ /**
+ * Must be overwritten by the implementing class to write a
+ * real value to the file.
+ *
+ * @param gc Group code.
+ * @param value The real value.
+ */
+ virtual void dxfReal(int gc, double value) const = 0;
+
+ /**
+ * Must be overwritten by the implementing class to write an
+ * int value to the file.
+ *
+ * @param gc Group code.
+ * @param value The int value.
+ */
+ virtual void dxfInt(int gc, int value) const = 0;
+
+ /**
+ * Can be overwritten by the implementing class to write a
+ * bool value to the file.
+ *
+ * @param gc Group code.
+ * @param value The bool value.
+ */
+ virtual void dxfBool(int gc, bool value) const {
+ dxfInt(gc, (int)value);
+ }
+
+ /**
+ * Must be overwritten by the implementing class to write an
+ * int value (hex) to the file.
+ *
+ * @param gc Group code.
+ * @param value The int value.
+ */
+ virtual void dxfHex(int gc, int value) const = 0;
+
+ /**
+ * Must be overwritten by the implementing class to write a
+ * string to the file.
+ *
+ * @param gc Group code.
+ * @param value The string.
+ */
+ virtual void dxfString(int gc, const char* value) const = 0;
+
+ /**
+ * Must be overwritten by the implementing class to write a
+ * string to the file.
+ *
+ * @param gc Group code.
+ * @param value The string.
+ */
+ virtual void dxfString(int gc, const std::string& value) const = 0;
+
+protected:
+ mutable unsigned long m_handle;
+ mutable unsigned long modelSpaceHandle;
+ mutable unsigned long paperSpaceHandle;
+ mutable unsigned long paperSpace0Handle;
+
+ /**
+ * DXF version to be created.
+ */
+ DL_Codes::version version;
+private:
+};
+
+#endif
diff --git a/datafile/dxf/dxflib/dl_writer_ascii.cpp b/datafile/dxf/dxflib/dl_writer_ascii.cpp
new file mode 100644
index 0000000..199707a
--- /dev/null
+++ b/datafile/dxf/dxflib/dl_writer_ascii.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
+** Copyright (C) 2001 Robert J. Campbell Jr.
+**
+** This file is part of the dxflib project.
+**
+** This file is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** Licensees holding valid dxflib Professional Edition licenses may use
+** this file in accordance with the dxflib Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.ribbonsoft.com for further details.
+**
+** Contact info@ribbonsoft.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include
+#include
+
+#include "dl_writer_ascii.h"
+#include "dl_exception.h"
+
+
+/**
+ * Closes the output file.
+ */
+void DL_WriterA::close() const {
+ m_ofile.close();
+}
+
+
+/**
+ * @retval true Opening file has failed.
+ * @retval false Otherwise.
+ */
+bool DL_WriterA::openFailed() const {
+ return m_ofile.fail();
+}
+
+
+
+/**
+ * Writes a real (double) variable to the DXF file.
+ *
+ * @param gc Group code.
+ * @param value Double value
+ */
+void DL_WriterA::dxfReal(int gc, double value) const {
+ char str[256];
+ if (version==DL_Codes::AC1009_MIN) {
+ sprintf(str, "%.6lf", value);
+ }
+ else {
+ sprintf(str, "%.16lf", value);
+ }
+
+ // fix for german locale:
+ strReplace(str, ',', '.');
+
+ // Cut away those zeros at the end:
+ bool dot = false;
+ int end = -1;
+ for (unsigned int i=0; i0 && end<(int)strlen(str)) {
+ str[end] = '\0';
+ }
+
+ dxfString(gc, str);
+ m_ofile.flush();
+}
+
+
+
+/**
+ * Writes an int variable to the DXF file.
+ *
+ * @param gc Group code.
+ * @param value Int value
+ */
+void DL_WriterA::dxfInt(int gc, int value) const {
+ m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n" << value << "\n";
+}
+
+
+
+/**
+ * Writes a hex int variable to the DXF file.
+ *
+ * @param gc Group code.
+ * @param value Int value
+ */
+void DL_WriterA::dxfHex(int gc, int value) const {
+ char str[12];
+ sprintf(str, "%0X", value);
+ dxfString(gc, str);
+}
+
+
+
+/**
+ * Writes a string variable to the DXF file.
+ *
+ * @param gc Group code.
+ * @param value String
+ */
+void DL_WriterA::dxfString(int gc, const char* value) const {
+ if (value==NULL) {
+#ifndef __GCC2x__
+ //throw DL_NullStrExc();
+#endif
+ }
+ m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n"
+ << value << "\n";
+}
+
+
+
+void DL_WriterA::dxfString(int gc, const std::string& value) const {
+ m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n"
+ << value << "\n";
+}
+
+
+/**
+ * Replaces every occurence of src with dest in the null terminated str.
+ */
+void DL_WriterA::strReplace(char* str, char src, char dest) {
+ size_t i;
+ for (i=0; i 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "dl_writer.h"
+#include
+#include
+
+/**
+ * Implements functions defined in DL_Writer for writing low
+ * level DXF constructs to an ASCII format DXF file.
+ *
+ * @para fname File name of the file to be created.
+ * @para version DXF version. Defaults to DL_VERSION_2002.
+ *
+ * @todo What if \c fname is NULL? Or \c fname can't be opened for
+ * another reason?
+ */
+class DXFLIB_EXPORT DL_WriterA : public DL_Writer {
+public:
+ DL_WriterA(const char* fname, DL_Codes::version version=DL_VERSION_2000)
+ : DL_Writer(version), m_ofile(fname) {}
+ virtual ~DL_WriterA() {}
+
+ bool openFailed() const;
+ void close() const;
+ void dxfReal(int gc, double value) const;
+ void dxfInt(int gc, int value) const;
+ void dxfHex(int gc, int value) const;
+ void dxfString(int gc, const char* value) const;
+ void dxfString(int gc, const std::string& value) const;
+
+ static void strReplace(char* str, char src, char dest);
+
+private:
+ /**
+ * DXF file to be created.
+ */
+ mutable std::ofstream m_ofile;
+
+};
+
+#endif
+
diff --git a/datafile/dxf/dxfreader.cpp b/datafile/dxf/dxfreader.cpp
new file mode 100644
index 0000000..24db047
--- /dev/null
+++ b/datafile/dxf/dxfreader.cpp
@@ -0,0 +1,379 @@
+#include "dxfreader.h"
+#include
+
+DxfReader::DxfReader(const QString &fileName, QObject *parent)
+ : QObject(parent)
+ , fileName(fileName)
+{
+ //QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
+
+ // 读取 dxf 文件
+ DL_Dxf *dxf = new DL_Dxf;
+ if (!dxf->in(std::string(fileName.toLocal8Bit()), this)) { // if file open failed
+ std::cerr << std::string(fileName.toLocal8Bit()) << " could not be opened.\n";
+ return;
+ }
+ delete dxf;
+ dxf = nullptr;
+}
+
+void DxfReader::addText(const DL_TextData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfText << data;
+}
+
+void DxfReader::addLine(const DL_LineData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfLines << data;
+}
+
+void DxfReader::addArc(const DL_ArcData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfArcs << data;
+}
+
+void DxfReader::addCircle(const DL_CircleData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfCircles << data;
+}
+
+void DxfReader::addEllipse(const DL_EllipseData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfEllipses << data;
+}
+
+void DxfReader::addPolyline(const DL_PolylineData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfPolylines << data;
+}
+
+void DxfReader::addPoint(const DL_PointData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfPoints << data;
+}
+
+void DxfReader::addSpline(const DL_SplineData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfSplines << data;
+}
+
+void DxfReader::addBlock(const DL_BlockData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfBlocks << data;
+}
+
+void DxfReader::endBlock()
+{
+
+}
+
+void DxfReader::addLayer(const DL_LayerData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfLayers << data;
+}
+
+void DxfReader::addLinetype(const DL_LinetypeData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfLinetypes << data;
+}
+
+void DxfReader::addLinetypeDash(double length)
+{
+ if(length < 0){}
+}
+
+void DxfReader::addXLine(const DL_XLineData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfXLines << data;
+}
+
+void DxfReader::addRay(const DL_RayData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfRays << data;
+}
+
+void DxfReader::addVertex(const DL_VertexData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfVertexs << data;
+}
+
+void DxfReader::addControlPoint(const DL_ControlPointData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfControlPoints << data;
+}
+
+void DxfReader::addFitPoint(const DL_FitPointData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfFitPoints << data;
+}
+
+void DxfReader::addKnot(const DL_KnotData &data)
+{
+ if(data.k == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addInsert(const DL_InsertData &data)
+{
+ if(data.angle == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addSolid(const DL_SolidData &data)
+{
+ if(data.x == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addTrace(const DL_TraceData &data)
+{
+ if(data.x == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addTextStyle(const DL_StyleData &data)
+{
+ if(data.flags == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addMTextChunk(const std::string &text)
+{
+ if(text.data() == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addMText(const DL_MTextData &data)
+{
+ if(data.angle == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addArcAlignedText(const DL_ArcAlignedTextData &data)
+{
+ if(data.alignment == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addAttribute(const DL_AttributeData &data)
+{
+ if(data.angle == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDimAlign(const DL_DimensionData &data, const DL_DimAlignedData &edata)
+{
+ if(data.angle == 0){}
+ if(edata.epx1 == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDimLinear(const DL_DimensionData &data, const DL_DimLinearData &edata)
+{
+ if(data.angle == 0){}
+ if(edata.angle == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDimRadial(const DL_DimensionData &data, const DL_DimRadialData &edata)
+{
+ if(data.angle == 0){}
+ if(edata.dpx == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDimDiametric(const DL_DimensionData &data, const DL_DimDiametricData &edata)
+{
+ if(data.angle == 0){}
+ if(edata.dpx == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDimAngular(const DL_DimensionData &data, const DL_DimAngularData &edata)
+{
+ if(data.angle == 0){}
+ if(edata.dpx1 == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDimAngular3P(const DL_DimensionData &data, const DL_DimAngular3PData &edata)
+{
+ if(data.angle == 0){}
+ if(edata.dpx1 == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDimOrdinate(const DL_DimensionData &data, const DL_DimOrdinateData &edata)
+{
+ if(data.angle == 0){}
+ if(edata.dpx1 == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addLeader(const DL_LeaderData &data)
+{
+ if(data.arrowHeadFlag == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addLeaderVertex(const DL_LeaderVertexData &data)
+{
+ if(data.x == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addHatch(const DL_HatchData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfHatchs << data;
+}
+
+void DxfReader::addHatchLoop(const DL_HatchLoopData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfHatchLoops << data;
+}
+
+void DxfReader::addHatchEdge(const DL_HatchEdgeData &data)
+{
+ //qDebug() << Q_FUNC_INFO;
+ dxfHatchEdges << data;
+}
+
+void DxfReader::addImage(const DL_ImageData &data)
+{
+ if(data.brightness == 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::linkImage(const DL_ImageDefData &data)
+{
+ if(data.file == ""){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addXRecord(const std::string &handle)
+{
+ if(handle.length() <= 0){}
+}
+
+void DxfReader::addXRecordString(int code, const std::string &value)
+{
+ if(code <= 0){}
+ if(value.length() <= 0){}
+}
+
+void DxfReader::addXRecordReal(int code, double value)
+{
+ if(code <= 0){}
+ if(value <= 0){}
+}
+
+void DxfReader::addXRecordInt(int code, int value)
+{
+ if(code <= 0){}
+ if(value <= 0){}
+}
+
+void DxfReader::addXRecordBool(int code, bool value)
+{
+ if(code <= 0){}
+ if(value <= 0){}
+}
+
+void DxfReader::addXDataApp(const std::string &appId)
+{
+ if(appId.length() <= 0){}
+}
+
+void DxfReader::addXDataString(int code, const std::string &value)
+{
+ if(code <= 0){}
+ if(value.length() <= 0){}
+}
+
+void DxfReader::addXDataReal(int code, double value)
+{
+ if(code <= 0){}
+ if(value <= 0){}
+}
+
+void DxfReader::addXDataInt(int code, int value)
+{
+ if(code <= 0){}
+ if(value <= 0){}
+}
+
+void DxfReader::addDictionary(const DL_DictionaryData &data)
+{
+ if(data.handle.length() <= 0){}
+// qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addDictionaryEntry(const DL_DictionaryEntryData &data)
+{
+ if(data.handle.length() <= 0){}
+// qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::setVariableVector(const std::string &key, double v1, double v2, double v3, int code)
+{
+ if(key.length() <= 0){}
+ if(v1 <= 0){}
+ if(v2 <= 0){}
+ if(v3 <= 0){}
+ if(code <= 0){}
+}
+
+void DxfReader::setVariableString(const std::string &key, const std::string &value, int code)
+{
+ if(key.length() <= 0){}
+ if(value.length() <= 0){}
+ if(code <= 0){}
+}
+
+void DxfReader::setVariableInt(const std::string &key, int value, int code)
+{
+ if(key.length() <= 0){}
+ if(value <= 0){}
+ if(code <= 0){}
+}
+
+void DxfReader::setVariableDouble(const std::string &key, double value, int code)
+{
+ if(key.length() <= 0){}
+ if(value <= 0){}
+ if(code <= 0){}
+}
+
+void DxfReader::add3dFace(const DL_3dFaceData &data)
+{
+ if(data.thickness <= 0){}
+ //qDebug() << Q_FUNC_INFO;
+}
+
+void DxfReader::addComment(const std::string &comment)
+{
+ if(comment.length() <= 0){}
+}
+
+void DxfReader::endSequence()
+{
+ //qDebug() << Q_FUNC_INFO;
+}
diff --git a/datafile/dxf/dxfreader.h b/datafile/dxf/dxfreader.h
new file mode 100644
index 0000000..cef9f40
--- /dev/null
+++ b/datafile/dxf/dxfreader.h
@@ -0,0 +1,109 @@
+#ifndef DXFREADER_H
+#define DXFREADER_H
+
+#include
+#include
+#include "dxflib/dl_dxf.h"
+#include "dxflib/dl_creationadapter.h"
+
+class DxfReader : public QObject, public DL_CreationAdapter
+{
+ Q_OBJECT
+public:
+ struct DxfText {
+ QString Text;
+ };
+ explicit DxfReader(const QString &fileName, QObject *parent = nullptr);
+
+ virtual void addText(const DL_TextData& data) override;
+ virtual void addLine(const DL_LineData& data) override;
+ virtual void addArc(const DL_ArcData& data) override;
+ virtual void addCircle(const DL_CircleData& data) override;
+ virtual void addEllipse(const DL_EllipseData& data) override;
+ virtual void addPolyline(const DL_PolylineData& data) override;
+ virtual void addPoint(const DL_PointData& data) override;
+ virtual void addSpline(const DL_SplineData& data) override;
+ virtual void addBlock(const DL_BlockData& data) override;
+ virtual void endBlock() override;
+
+ virtual void addLayer(const DL_LayerData& data) override;
+ virtual void addLinetype(const DL_LinetypeData& data) override;
+ virtual void addLinetypeDash(double length) override;
+ virtual void addXLine(const DL_XLineData& data) override;
+ virtual void addRay(const DL_RayData& data) override;
+ virtual void addVertex(const DL_VertexData& data) override;
+ virtual void addControlPoint(const DL_ControlPointData& data) override;
+ virtual void addFitPoint(const DL_FitPointData& data) override;
+ virtual void addKnot(const DL_KnotData& data) override;
+ virtual void addInsert(const DL_InsertData& data) override;
+ virtual void addSolid(const DL_SolidData& data) override;
+ virtual void addTrace(const DL_TraceData& data) override;
+ virtual void addTextStyle(const DL_StyleData& data) override;
+ virtual void addMTextChunk(const std::string& text) override;
+ virtual void addMText(const DL_MTextData& data) override;
+ virtual void addArcAlignedText(const DL_ArcAlignedTextData& data) override;
+ virtual void addAttribute(const DL_AttributeData& data) override;
+ virtual void addDimAlign(const DL_DimensionData& data, const DL_DimAlignedData& edata) override;
+ virtual void addDimLinear(const DL_DimensionData& data, const DL_DimLinearData& edata) override;
+ virtual void addDimRadial(const DL_DimensionData& data, const DL_DimRadialData& edata) override;
+ virtual void addDimDiametric(const DL_DimensionData& data, const DL_DimDiametricData& edata) override;
+ virtual void addDimAngular(const DL_DimensionData& data, const DL_DimAngularData& edata) override;
+ virtual void addDimAngular3P(const DL_DimensionData& data, const DL_DimAngular3PData& edata) override;
+ virtual void addDimOrdinate(const DL_DimensionData& data, const DL_DimOrdinateData& edata) override;
+ virtual void addLeader(const DL_LeaderData &data) override;
+ virtual void addLeaderVertex(const DL_LeaderVertexData &data) override;
+ virtual void addHatch(const DL_HatchData& data) override;
+ virtual void addHatchLoop(const DL_HatchLoopData& data) override;
+ virtual void addHatchEdge(const DL_HatchEdgeData& data) override;
+ virtual void addImage(const DL_ImageData &data) override;
+ virtual void linkImage(const DL_ImageDefData &data) override;
+
+ virtual void addXRecord(const std::string& handle) override;
+ virtual void addXRecordString(int code, const std::string& value) override;
+ virtual void addXRecordReal(int code, double value) override;
+ virtual void addXRecordInt(int code, int value) override;
+ virtual void addXRecordBool(int code, bool value) override;
+
+ virtual void addXDataApp(const std::string& appId) override;
+ virtual void addXDataString(int code, const std::string& value) override;
+ virtual void addXDataReal(int code, double value) override;
+ virtual void addXDataInt(int code, int value) override;
+
+ virtual void addDictionary(const DL_DictionaryData& data) override;
+ virtual void addDictionaryEntry(const DL_DictionaryEntryData& data) override;
+
+ virtual void setVariableVector(const std::string& key, double v1, double v2, double v3, int code) override;
+ virtual void setVariableString(const std::string& key, const std::string& value, int code) override;
+ virtual void setVariableInt(const std::string& key, int value, int code) override;
+ virtual void setVariableDouble(const std::string& key, double value, int code) override;
+
+ virtual void add3dFace(const DL_3dFaceData &data) override;
+ virtual void addComment(const std::string &comment) override;
+ virtual void endSequence() override;
+
+ QList dxfLines;
+ QList dxfText;
+ QList dxfArcs;
+ QList dxfCircles;
+ QList dxfEllipses;
+ QList dxfPolylines;
+ QList dxfPoints;
+ QList dxfSplines;
+ QList dxfBlocks;
+ QList dxfVertexs;
+ QList dxfLayers;
+ QList dxfLinetypes;
+ QList dxfXLines;
+ QList dxfRays;
+ QList dxfControlPoints;
+ QList dxfFitPoints;
+ QList dxfHatchs;
+ QList dxfHatchLoops;
+ QList dxfHatchEdges;
+
+private:
+ QString fileName;
+
+};
+
+#endif // DXFREADER_H
diff --git a/datafile/embdata.cpp b/datafile/embdata.cpp
new file mode 100644
index 0000000..8b79359
--- /dev/null
+++ b/datafile/embdata.cpp
@@ -0,0 +1,3800 @@
+#include "embdata.h"
+#include "main.h"
+const QColor sewcolorGreen = QColor(0x35,0xC0,0x5C);//绿色
+u32 rgbColorGreen = qRgb(sewcolorGreen.red(),sewcolorGreen.green(),sewcolorGreen.blue());
+const QColor sewcolorYel = QColor(Qt::darkYellow);//黄色
+u32 rgbColorYel = qRgb(sewcolorYel.red(),sewcolorYel.green(),sewcolorYel.blue());
+const QColor sewcolorblue = QColor(Qt::blue);//蓝色
+u32 rgbColorBlue = qRgb(sewcolorblue.red(),sewcolorblue.green(),sewcolorblue.blue());
+
+const int headNum = 5; // 机头数
+
+EmbData::EmbData()
+{
+ m_pEmbDs16Head = new DataDs16FileHead();
+ m_penHeadPix.resize(5);
+ m_penPoint.resize(5);
+ clear();
+}
+
+EmbData::~EmbData()
+{
+ clear();
+ if(m_pEmbDs16Head != NULL)
+ {
+ delete m_pEmbDs16Head;
+ }
+}
+
+void EmbData::clear()
+{
+ m_maxX = 0;
+ m_minX = 0;
+ m_maxY = 0;
+ m_minY = 0;
+ m_fileid = 0;
+
+ m_spaceX = 0;
+ m_spaceY = 0;
+
+ m_penX = 0;
+ m_penY = 0;
+
+ m_embDs16Data.clear();
+
+ m_editedflag = 0;
+ m_filePath.clear();
+ m_factor = 0;
+
+ memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead));
+}
+
+QByteArray & EmbData::getDsDat()
+{
+ //qDebug()<<"m_editedflag"<fileid = fileid;
+ if((u32)m_embDs16Data.size() > sizeof(DataDs16FileHead))
+ {
+ memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));
+ }
+ }
+}
+
+//得到绝对坐标的maxXY和minXY
+void EmbData::getAbsDatRangeXY()
+{
+ m_minX = S32_MAX;
+ m_maxX = S32_MIN;
+ m_minY = S32_MAX;
+ m_maxY = S32_MIN;
+
+ double ax, ay;
+ int minx, miny, maxx, maxy;
+
+ const QByteArray & ary = m_embAbsData;
+ int size = ary.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("ary data less then head size");
+ }
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("absdat dataBegin err");
+ return;
+ }
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("absdat data size err");
+ return;
+ }
+ DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData;
+ //-----
+
+ int begx = pDsHead->beginX;
+ int begy = pDsHead->beginY;
+
+ minx = S32_MAX;
+ maxx = S32_MIN;
+ miny = S32_MAX;
+ maxy = S32_MIN;
+
+ // 数据区
+ for (int j = 0; j < stepsize; j++)
+ {
+ ax = absDataPtr->ax + begx;
+ ay = absDataPtr->ay + begy;
+
+// ax = absDataPtr->ax;
+// ay = absDataPtr->ay;
+
+ if (minx > ax) { minx = ax; }
+ if (maxx < ax) { maxx = ax; }
+ if (miny > ay) { miny = ay; }
+ if (maxy < ay) { maxy = ay; }
+
+ absDataPtr++;
+ }
+
+ if (m_minX > minx) { m_minX = minx; }
+ if (m_minX > maxx) { m_minX = maxx; }
+ if (m_maxX < minx) { m_maxX = minx; }
+ if (m_maxX < maxx) { m_maxX = maxx; }
+ if (m_minY > miny) { m_minY = miny; }
+ if (m_minY > maxy) { m_minY = maxy; }
+ if (m_maxY < miny) { m_maxY = miny; }
+ if (m_maxY < maxy) { m_maxY = maxy; }
+}
+
+// 添加锁针针步
+int EmbData::addLockStitchs(u8 mode, u8 needles, u8 num)
+{
+ if (needles <= 0)
+ {
+ return -1;
+ }
+
+ int size = m_embAbsData.size();
+ if (size <= 0)
+ {
+ return -1;
+ }
+
+ int lockNum = num;//锁针次数
+ int lockNeedles = needles;//锁针针数
+
+ QByteArray tgtdsdat; // 添加后的绝对坐标数据
+ tgtdsdat.clear();
+
+ // 文件头
+ int datasize = size - sizeof(DataDs16FileHead);
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("dat size err");
+ return -1;
+ }
+
+ DataDs16FileHead * pHead = (DataDs16FileHead *)(m_embAbsData.data());
+ DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData;
+
+ tgtdsdat.append((char*)pHead, sizeof(DataDs16FileHead));
+ //pHead = (DataDs16FileHead *)(tgtdsdat.data());
+
+ int runflag = 0;
+
+ for (int j = 0; j < stepsize; j++)
+ {
+ if (absDataPtr->ctrl == DATA_SEWING)//包括起针和剪线后加锁针
+ {
+ if ((runflag == 0 || runflag > 3))
+ {
+ // 添加锁针
+ int nst = 0;
+
+ if(mode == MODE_LOCK)//锁针方式
+ {
+ if(lockNum%2 == 0)//偶数
+ {
+ nst = 1;
+ }
+ else//奇数
+ {
+ nst = needles;
+ }
+
+ do
+ {
+ if(j+nst < stepsize)
+ {
+ DsAbsItem * nextPtr = absDataPtr+nst; // 要加锁针的点
+ if (nextPtr->ctrl == DATA_SEWING)
+ {
+ DsAbsItem nitem;
+ memset(&nitem,0,sizeof(DsAbsItem));
+
+ u8 ctrl = absDataPtr->ctrl;
+ u8 attr = 0; // absDataPtr->attr;
+ double arbase = absDataPtr->ar;
+
+ if(lockNum%2 == 0)//偶数锁针
+ {
+ nextPtr--;
+ for (int k = 0; k < lockNum; k++)
+ {
+ if(k%2 == 0)
+ {
+ for (int s = 0; s < lockNeedles; s++)
+ {
+ nextPtr++;
+ double axbase = nextPtr->ax;
+ double aybase = nextPtr->ay;
+
+ nitem.ctrl = ctrl;
+ nitem.attr = attr;
+ nitem.ax = axbase;
+ nitem.ay = aybase;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+ }
+ }
+
+ if(k > 0 && k%2 != 0)
+ {
+ for (int s = lockNeedles; s > 0; s--)
+ {
+ nextPtr--;
+ double axbase = nextPtr->ax;
+ double aybase = nextPtr->ay;
+
+ if(k == lockNum-1 && s == 1)
+ {
+ continue;//最后一次锁针的最后一步不添加
+ }
+
+ nitem.ctrl = ctrl;
+ nitem.attr = attr;
+ nitem.ax = axbase;
+ nitem.ay = aybase;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+ }
+ }
+ }
+ }
+ else//奇数锁针
+ {
+ nextPtr++;
+ for (int k = 0; k < lockNum; k++)
+ {
+ if(k%2 == 0)
+ {
+ for (int s = lockNeedles; s > 0; s--)
+ {
+ nextPtr--;
+ double axbase = nextPtr->ax;
+ double aybase = nextPtr->ay;
+
+ if(k == 0 && s == lockNeedles)
+ {
+ nitem.ctrl = DATA_OFFSET;//第一针步转换为跨步
+ }
+ else
+ {
+ nitem.ctrl = ctrl;
+ }
+
+ nitem.attr = attr;
+ nitem.ax = axbase;
+ nitem.ay = aybase;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+ }
+ nextPtr--;
+ }
+
+ if(k > 0 && k%2 != 0)
+ {
+ for (int s = 0; s < lockNeedles; s++)
+ {
+ double axbase = nextPtr->ax;
+ double aybase = nextPtr->ay;
+
+ nitem.ctrl = ctrl;
+ nitem.attr = attr;
+ nitem.ax = axbase;
+ nitem.ay = aybase;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+ nextPtr++;
+ }
+ nextPtr++;
+ }
+ }
+ }
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }while(1);
+ }
+ else if(mode == MODE_THICKEN)//密针方式
+ {
+ tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem));
+
+ nst = 1;
+
+ s16 nNum = 0;
+ if(lockNum == 0)//如果锁针次数为0时,第一针锁针次数就是锁针针数
+ {
+ nNum = lockNeedles+1;
+ }
+ else
+ {
+ nNum = lockNum+1;
+ }
+
+ do
+ {
+ if(j+nst < stepsize)
+ {
+ DsAbsItem * nextPtr = absDataPtr+nst; // 下一个点
+ if (nextPtr->ctrl == DATA_SEWING)
+ {
+ DsAbsItem nitem;
+ memset(&nitem,0,sizeof(DsAbsItem));
+ DsAbsItem * prePtr = absDataPtr;
+
+ u8 ctrl = absDataPtr->ctrl;
+ u8 attr = 0; // absDataPtr->attr;
+ double arbase = absDataPtr->ar;
+
+ for (int s = 0; s < lockNeedles; s++)
+ {
+ double dx = nextPtr->ax - prePtr->ax;
+ double dy = nextPtr->ay - prePtr->ay;
+ double len = sqrt(dx*dx + dy*dy);
+ if (len <= 0)
+ {
+ prePtr = nextPtr;
+ nextPtr++;
+ lockNeedles++;
+ continue;
+ }
+ double dLen = len / nNum;
+
+ double axbase = prePtr->ax;
+ double aybase = prePtr->ay;
+
+ for (int k = 0; k < nNum; k++)
+ {
+ double nax = dx * dLen / len + axbase;
+ double nay = dy * dLen / len + aybase;
+
+ nitem.ctrl = ctrl;
+ nitem.attr = attr;
+ nitem.ax = nax;
+ nitem.ay = nay;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+
+ axbase = nax;
+ aybase = nay;
+ }
+ if(lockNum == 0)
+ {
+ nNum--;
+ }
+ prePtr = nextPtr;
+ nextPtr++;
+ }
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }while(1);
+
+ for (int s = 0; s <= lockNeedles; s++)//跳到不加锁针的那一针
+ {
+ absDataPtr++;
+ j++;
+ }
+ }
+ runflag = 1;
+ }
+ }
+ else if (absDataPtr->ctrl == DATA_CUTTRD)
+ {
+ runflag = 10;
+ }
+ else
+ {
+ runflag = 0;
+ }
+
+ //结束前或剪线前加锁针
+ if (absDataPtr->ctrl == DATA_END ||
+ absDataPtr->ctrl == DATA_NULL ||
+ j == stepsize-1 ||
+ absDataPtr->ctrl == DATA_CUTTRD)
+ {
+ int m = 1;
+ //结束前或剪线前加锁针
+ DsAbsItem * prePtr = absDataPtr-1; // 上一个点
+ u8 ctl = prePtr->ctrl;
+ while(ctl != DATA_SEWING)
+ {
+ prePtr--;
+ m++;
+ ctl = prePtr->ctrl;
+ if(prePtr == pData)//起始地址
+ {
+ return -1;
+ }
+ }
+
+ // 添加锁针
+ int nst = 1;
+
+ if(mode == MODE_LOCK)//锁针方式
+ {
+ do
+ {
+ if(j-m-nst > 0)
+ {
+ DsAbsItem * lockPtr = prePtr; // 要加锁针的点
+ if (lockPtr->ctrl == DATA_SEWING)
+ {
+ DsAbsItem nitem;
+ memset(&nitem,0,sizeof(DsAbsItem));
+
+ u8 ctrl = prePtr->ctrl;
+ u8 attr = 0; // absDataPtr->attr;
+ double arbase = prePtr->ar;
+
+ for (int k = 0; k < lockNum; k++)
+ {
+ if(k%2 == 0)
+ {
+ for (int s = lockNeedles; s > 0; s--)
+ {
+ lockPtr--;
+ double axbase = lockPtr->ax;
+ double aybase = lockPtr->ay;
+
+ nitem.ctrl = ctrl;
+ nitem.attr = attr;
+ nitem.ax = axbase;
+ nitem.ay = aybase;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+ }
+ }
+
+ if(k > 0 && k%2 != 0)
+ {
+ for (int s = 0; s < lockNeedles; s++)
+ {
+ lockPtr++;
+ double axbase = lockPtr->ax;
+ double aybase = lockPtr->ay;
+
+ nitem.ctrl = ctrl;
+ nitem.attr = attr;
+ nitem.ax = axbase;
+ nitem.ay = aybase;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+ }
+ }
+ }
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }while(1);
+ }
+ else if(mode == MODE_THICKEN)//密针方式
+ {
+ nst = needles;
+ //去除要加密针的已添加的针步
+ tgtdsdat.remove(tgtdsdat.size()-needles*sizeof(DsAbsItem),needles*sizeof(DsAbsItem));
+
+ s16 nNum = 0;
+ if(lockNum == 0)//如果锁针次数为0时,第一针锁针次数就是锁针针数
+ {
+ nNum = lockNeedles+1;
+ }
+ else
+ {
+ nNum = lockNum+1;
+ }
+
+ do
+ {
+ if(j-m-nst > 0)
+ {
+ DsAbsItem * lockPtr = prePtr-lockNeedles; // 加锁针点
+ if (lockPtr->ctrl == DATA_SEWING)
+ {
+ DsAbsItem nitem;
+ memset(&nitem,0,sizeof(DsAbsItem));
+
+ u8 ctrl = prePtr->ctrl;
+ u8 attr = 0; // absDataPtr->attr;
+ double arbase = prePtr->ar;
+
+ for (int s = 0; s < lockNeedles; s++)
+ {
+ DsAbsItem * nextPtr = lockPtr+1;
+ double dx = nextPtr->ax - lockPtr->ax;
+ double dy = nextPtr->ay - lockPtr->ay;
+ double len = sqrt(dx*dx + dy*dy);
+ if (len <= 0)
+ {
+ if(lockNum == 0)
+ {
+ nNum--;
+ }
+
+ lockPtr++;
+ continue;
+ }
+ double dLen = len / nNum;
+
+ double axbase = lockPtr->ax;
+ double aybase = lockPtr->ay;
+
+ for (int k = 0; k < nNum; k++)
+ {
+ double nax = dx * dLen / len + axbase;
+ double nay = dy * dLen / len + aybase;
+
+ nitem.ctrl = ctrl;
+ nitem.attr = attr;
+ nitem.ax = nax;
+ nitem.ay = nay;
+ nitem.ar = arbase;
+ tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
+
+ axbase = nax;
+ aybase = nay;
+ }
+ if(lockNum == 0)
+ {
+ nNum--;
+ }
+ lockPtr++;
+ }
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }while(1);
+ }
+ }
+
+ tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem));
+
+ absDataPtr++;
+ }
+
+ m_embAbsData.clear();
+ m_embAbsData = tgtdsdat;
+
+ m_editedflag = 1;
+ return 0;
+}
+
+//角度修正
+int EmbData::angleCorrection(s16 oft)
+{
+ if (oft != 0)
+ {
+ s32 dx, dy, dr;
+ double ax, ay, ar;
+ int bdx, bdy;
+ bdx = bdy = 0;
+
+ int size = m_embAbsData.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("ary data less then head size");
+ return -1;
+ }
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("absdat dataBegin err");
+ return -1;
+ }
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("absdat data size err");
+ return -1;
+ }
+ DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData; //中间数据针步
+
+ double addx,addy;
+ addx = addy = 0;
+ double s = 0;
+
+ // 数据区
+ for (int j = 0; j < stepsize; j++)
+ {
+ if (j == 0)//第一针
+ {
+ dx = absDataPtr->ax;
+ dy = absDataPtr->ay;
+ dr = absDataPtr->ar;
+ }
+ else
+ {
+ dx = absDataPtr->ax - ax;
+ dy = absDataPtr->ay - ay;
+ dr = absDataPtr->ar - ar;
+ }
+
+ //判断夹角是否大于60度
+ if(dr >= ANGLECORR || dr <= -ANGLECORR)
+ {
+ s = sqrt(bdx*bdx + bdy*bdy);
+ if(s == 0)
+ {
+ addx = 0;
+ addy = 0;
+ }
+ else
+ {
+ addx = bdx*oft/s;
+ addy = bdy*oft/s;
+ }
+
+ absDataPtr--;
+ if(absDataPtr->ctrl == DATA_SEWING)
+ {
+ absDataPtr->ax += addx;
+ absDataPtr->ay += addy;
+ }
+ absDataPtr++;
+ }
+
+ ax = absDataPtr->ax;
+ ay = absDataPtr->ay;
+ ar = absDataPtr->ar;
+
+ bdx = dx;
+ bdy = dy;
+
+ absDataPtr++;
+ }
+ }
+ return 0;
+}
+
+int EmbData::angleCorrectionXY(s32 px, s32 nx, s32 py, s32 ny)
+{
+ if(px == 0 && nx == 0 && py == 0 && ny == 0)
+ {
+ return -1;
+ }
+ s32 dx, dy, dr;
+ double ax, ay, ar;
+
+ int size = m_embAbsData.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("ary data less then head size");
+ return -1;
+ }
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("absdat dataBegin err");
+ return -1;
+ }
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("absdat data size err");
+ return -1;
+ }
+ DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData; //中间数据针步
+
+ double addx,addy;
+ addx = addy = 0;
+
+ // 数据区
+ for (int j = 0; j < stepsize; j++)
+ {
+ if (j == 0)//第一针
+ {
+ dx = absDataPtr->ax;
+ dy = absDataPtr->ay;
+ dr = absDataPtr->ar;
+ }
+ else
+ {
+ dx = absDataPtr->ax - ax;
+ dy = absDataPtr->ay - ay;
+ dr = absDataPtr->ar - ar;
+ }
+
+ //判断夹角是否大于60度
+ if(dr >= ANGLECORR || dr <= -ANGLECORR)
+ {
+ if(dx > 0)
+ {
+ addx = px;
+ }
+ else if(dx == 0)
+ {
+ DsAbsItem * prePtr = absDataPtr-1;
+ double prex = prePtr ->ax;
+ while(prex == absDataPtr->ax)
+ {
+ prePtr--;
+ prex = prePtr->ax;
+ if(prePtr == pData)
+ {
+ break;
+ }
+ }
+ s32 cx = prex - absDataPtr->ax;
+ if(cx < 0)
+ {
+ addx = px;
+ }
+ else
+ {
+ addx = 0 - nx;
+ }
+ }
+ else
+ {
+ addx = 0 - nx;
+ }
+
+ if(dy > 0)
+ {
+ addy = py;
+ }
+ else if(dy == 0)
+ {
+ DsAbsItem * prePtr = absDataPtr-1;
+ double prey = prePtr ->ay;
+ while(prey == absDataPtr->ay)
+ {
+ prePtr--;
+ prey = prePtr->ay;
+ if(prePtr == pData)
+ {
+ break;
+ }
+ }
+ s32 cy = prey - absDataPtr->ay;
+ if(cy < 0)
+ {
+ addy = py;
+ }
+ else
+ {
+ addy = 0 - ny;
+ }
+ }
+ else
+ {
+ addy = 0 - ny;
+ }
+
+ absDataPtr--;
+ if(absDataPtr->ctrl == DATA_SEWING)
+ {
+ absDataPtr->ax += addx;
+ absDataPtr->ay += addy;
+ }
+ absDataPtr++;
+ }
+
+ ax = absDataPtr->ax;
+ ay = absDataPtr->ay;
+ ar = absDataPtr->ar;
+
+ absDataPtr++;
+ }
+
+ return 0;
+}
+
+//按固定针步重新拟合(用户可设置的参数,暂未用到)
+void EmbData::reFitByStep(s32 stepLen)
+{
+ QList lineList;
+ lineList.clear();
+
+ int stepLength = stepLen;//参数(300-800 单位0.01mm)
+
+ LineItem item;
+ item.absItemList.clear();
+
+ int dr = 0;
+ unsigned char ctrl;
+ double prer = 0;
+
+ double ax, ay, ar;
+ ax = ay = ar = 0;
+
+ DsAbsItem absItem;
+ memset(&absItem,0,sizeof(DsAbsItem));
+
+ //添加线段集合(夹角大于某个值时为新的一段线段)
+ int datasize = m_embAbsData.size() - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ return;
+ }
+ int stepsize = datasize/sizeof(DsAbsItem);
+ DsAbsItem * dataBeg = (DsAbsItem *)(m_embAbsData.data()+sizeof(DataDs16FileHead));
+ prer = dataBeg->ar;
+ for (int i = 0; i < stepsize; i++)
+ {
+ ctrl = dataBeg->ctrl;
+ dr = dataBeg->ar - prer;
+
+ unsigned char nctrl,bctrl;
+ if(i == stepsize-1)
+ {
+ nctrl = ctrl;
+ }
+ else
+ {
+ dataBeg++;
+ nctrl = dataBeg->ctrl;//下一针步属性
+ dataBeg--;
+ }
+
+ if(i == 0)
+ {
+ bctrl = ctrl;
+ }
+ else
+ {
+ dataBeg--;
+ bctrl = dataBeg->ctrl;//上一针步属性
+ dataBeg++;
+ }
+
+ if(ctrl != DATA_SEWING)
+ {
+ item.absItemList.append(*dataBeg);
+ }
+
+ //上一针非缝纫属性且当前针为缝纫属性
+ if(bctrl != DATA_SEWING && ctrl == DATA_SEWING)
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*dataBeg);
+ }
+ //下一针非缝纫针步与当前针为缝纫针步
+ else if(nctrl != DATA_SEWING && ctrl == DATA_SEWING)
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*dataBeg);
+ }
+ //上一针为缝纫针步与当前针非缝纫针步
+ else if(bctrl == DATA_SEWING && ctrl != DATA_SEWING)
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*dataBeg);
+ }
+ //下一针为缝纫针步与当前针非缝纫针步
+ else if(nctrl == DATA_SEWING && ctrl != DATA_SEWING)
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*dataBeg);
+ }
+ else if(ctrl == DATA_SEWING)
+ {
+ double angle = dr / 10000.0 * (180.0 / PI);
+ if(angle > 30 || angle < -30)//新的一条线段(30度为分界)
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*dataBeg);
+ }
+ else
+ {
+ item.absItemList.append(*dataBeg);
+ }
+ }
+ prer = dataBeg->ar;
+ dataBeg++;
+ }
+
+ //开始重置针步(绝对坐标的线段集合)
+ QByteArray nabsData;
+ nabsData.clear();
+ double cx,cy,cr;
+ cx = cy = cr = 0;
+ int lSize = lineList.size();
+ for(int j = 0; j < lSize; j++)
+ {
+ int pSize = lineList[j].absItemList.size();
+ for(int m = 0; m < pSize; m++)
+ {
+ memset(&absItem,0,sizeof(DsAbsItem));
+ absItem = lineList[j].absItemList[m];
+
+ ctrl = absItem.ctrl;
+ //absItem.ax = absItem.ax - minX;
+ //absItem.ay = absItem.ay - minY;
+ ax = absItem.ax;
+ ay = absItem.ay;
+ ar = absItem.ar;
+
+ if(ctrl != DATA_SEWING)
+ {
+ nabsData.append((char*)&absItem,sizeof(DsAbsItem));
+ continue;
+ }
+ if(m == 0)
+ {
+ cx = ax;
+ cy = ay;
+ nabsData.append((char*)&absItem,sizeof(DsAbsItem));
+ }
+ if(m == pSize - 1 && pSize > 1)
+ {
+ //最后一步如果超出长度就均分
+ int pos = nabsData.size()-sizeof(DsAbsItem);
+ DsAbsItem * litem = (DsAbsItem *)((nabsData.data()+pos));
+
+ double curX = absItem.ax;
+ double curY = absItem.ay;
+
+ double preX = litem->ax;
+ double preY = litem->ay;
+
+ double ldis = sqrt(((curX-preX)/100.0*(curX-preX)/100.0)*10000.0+((curY-preY)/100.0*(curY-preY)/100.0)*10000.0);
+ if(ldis > stepLength)
+ {
+ DsAbsItem addItem;
+ memset(&addItem,0,sizeof(DsAbsItem));
+ addItem = absItem;
+
+ if(litem->ay == absItem.ay)//y相同
+ {
+ addItem.ay = absItem.ay;
+ addItem.ax = (absItem.ax+litem->ax)/2;
+
+ nabsData.append((char*)&addItem,sizeof(DsAbsItem));
+ nabsData.append((char*)&absItem,sizeof(DsAbsItem));
+ break;
+ }
+ else if(litem->ax == absItem.ax)//x相同
+ {
+ addItem.ax = absItem.ax;
+ addItem.ay = (absItem.ay+litem->ay)/2;
+
+ nabsData.append((char*)&addItem,sizeof(DsAbsItem));
+ nabsData.append((char*)&absItem,sizeof(DsAbsItem));
+ break;
+ }
+ else
+ {
+ double k = ((double)(absItem.ay-litem->ay))/((double)(absItem.ax-litem->ay));
+ double cdis = ldis / 2;
+ double r = atan(k);
+ double x = cdis * cos(r);
+ double y = cdis * sin(r);
+
+ addItem.ax = litem->ax + x;
+ addItem.ay = litem->ay + y;
+ nabsData.append((char*)&addItem,sizeof(DsAbsItem));
+
+ nabsData.append((char*)&absItem,sizeof(DsAbsItem));
+ break;
+ }
+ }
+ else
+ {
+ nabsData.append((char*)&absItem,sizeof(DsAbsItem));
+ break;
+ }
+ }
+ double dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0);
+ while(dis > stepLength)
+ {
+ QPoint firstPoint(0,0);//直线第一个点
+ if((m-1) >= 0)
+ {
+ // firstPoint.setX(lineList[j].absItemList[m-1].ax-minX);
+ // firstPoint.setY(lineList[j].absItemList[m-1].ay-minY);
+ firstPoint.setX(lineList[j].absItemList[m-1].ax);
+ firstPoint.setY(lineList[j].absItemList[m-1].ay);
+ }
+
+ QPoint secondPoint;//直线第二个点
+ secondPoint.setX(ax);
+ secondPoint.setY(ay);
+
+ QPoint circlePoint;//圆心
+ circlePoint.setX(cx);
+ circlePoint.setY(cy);
+
+ QPoint p;
+ if(secondPoint.x()-firstPoint.x() == 0)
+ {
+ p.setX(secondPoint.x());
+ //int y = (secondPoint.y()/stepLength)*stepLength;
+ //int y = (secondPoint.y()+firstPoint.y())/2;
+ //取出上一点的坐标
+ int pos = nabsData.size()-sizeof(DsAbsItem);
+ DsAbsItem * litem = (DsAbsItem *)((nabsData.data()+pos));
+ int y = 0;
+ if(litem->ay >= secondPoint.y())
+ {
+ y = litem->ay - stepLength;
+ }
+ else
+ {
+ y = litem->ay + stepLength;
+ }
+
+ p.setY(y);
+
+ cx = p.x();
+ cy = p.y();
+
+ if(cx < 0 || cy < 0)
+ {
+ //qDebug()<= (stepLength-10))
+ {
+ bl3 = true;
+ }
+
+ if(bl3)
+ {
+ if(bl1 == true && bl2 == true)
+ {
+ double dis1 = sqrt(((ax-x1)/100.0*(ax-x1)/100.0)*10000.0+((ay-y1)/100.0*(ay-y1)/100.0)*10000.0);
+ double dis2 = sqrt(((ax-x2)/100.0*(ax-x2)/100.0)*10000.0+((ay-y2)/100.0*(ay-y2)/100.0)*10000.0);
+ if(dis1 > dis2)
+ {
+ cx = x2;
+ cy = y2;
+ }
+ else
+ {
+ cx = x1;
+ cy = y1;
+ }
+
+ absItem.ax = cx;
+ absItem.ay = cy;
+ nabsData.append((char*)&absItem,sizeof(DsAbsItem));
+
+ dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0);
+ }
+ else
+ {
+ if(bl1)
+ {
+ p.setX(x1);
+ p.setY(y1);
+ }
+ else if(bl2)
+ {
+ p.setX(x2);
+ p.setY(y2);
+ }
+ else
+ {
+ qDebug()<<"bl1&bl2=false";
+ break;
+ }
+
+ cx = p.x();
+ cy = p.y();
+
+ if(cx < 0 || cy < 0)
+ {
+ //qDebug()<dataSize = stepsize*sizeof(DsAbsItem); // 数据字节数
+ m_pEmbDs16Head->itemNums = stepsize; // 数据项个数
+ m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 数据累加校验和
+ m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值)
+ u32 fileID = 0;
+ fileID = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 原始数据累加校验和
+ m_pEmbDs16Head->fileid = fileID; //中间数据的 fileid =
+
+ m_embAbsData.clear();
+ m_embAbsData.append((char *)(m_pEmbDs16Head), sizeof(DataDs16FileHead));
+ m_embAbsData.append(nabsData);
+}
+
+#define MERGEANGLE PI/180*70*10000 //70度
+void EmbData::reFitLine(s32 stepLen)
+{
+ QList lineList;
+ lineList.clear();
+
+ double stepLength = stepLen;//参数(200-800 单位0.01mm)
+ if(stepLength <= 0)
+ {
+ return;
+ }
+
+ LineItem item;
+ item.absItemList.clear();
+
+ int dr = 0;
+ double prer = 0;
+ DsAbsItem preItem;
+ memset(&preItem,0,sizeof(DsAbsItem));
+ s16 addOftFlag = 0;
+ s16 addSewFlag = 0;
+
+ DsAbsItem absItem;
+ memset(&absItem,0,sizeof(DsAbsItem));
+
+ //添加线段集合(夹角大于某个值时为新的一段线段)
+ int datasize = m_embAbsData.size() - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ return;
+ }
+ int stepsize = datasize/sizeof(DsAbsItem);
+ memcpy((char*)m_pEmbDs16Head,m_embAbsData.data(),sizeof(DataDs16FileHead));
+ DsAbsItem * dataBeg = (DsAbsItem *)(m_embAbsData.data()+sizeof(DataDs16FileHead));
+ prer = dataBeg->ar;
+ for (int i = 0; i < stepsize; i++)
+ {
+ dr = dataBeg->ar - prer;
+
+ while (dr < -PI10000)
+ {
+ dr += PI20000;
+ }
+ while (dr > PI10000)
+ {
+ dr -= PI20000;
+ }
+
+ if(dataBeg->ctrl != DATA_SEWING)
+ {
+ if(addSewFlag == 1)
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*(dataBeg-1));
+ addSewFlag = 0;
+ }
+ item.absItemList.append(*dataBeg);
+ addOftFlag = 1;
+ }
+ else
+ {
+ addSewFlag = 1;
+ if(addOftFlag == 1)
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*(dataBeg-1));
+ item.absItemList.append(*dataBeg);
+ addOftFlag = 0;
+ }
+ if((abs(dr) > MERGEANGLE))//新的一条线段
+ {
+ lineList.append(item);
+ item.absItemList.clear();
+ item.absItemList.append(*(dataBeg-1));
+ item.absItemList.append(*dataBeg);
+ }
+ else
+ {
+ item.absItemList.append(*dataBeg);
+ }
+ }
+
+ prer = dataBeg->ar;
+ dataBeg++;
+ }
+
+ //开始重置针步(绝对坐标的线段集合)
+ QByteArray nabsData;
+ nabsData.clear();
+ QList outList;
+
+ int lSize = lineList.size();
+ for(int i = 0; i < lSize; i++)
+ {
+ outList.clear();
+
+ int pSize = lineList[i].absItemList.size();
+ if(pSize == 1)//只有一个点
+ {
+ nabsData.append((char*)&lineList[i].absItemList[0],sizeof(DsAbsItem));
+ }
+ else
+ {
+ getCurvePointFillLine(lineList[i].absItemList,stepLength,outList);
+ //从第二段开始起始点不向绝对坐标中添加,如果添加会出现空针步
+ int idx = 0;
+ if(i > 0)
+ {
+ idx = 1;
+ }
+ for(int m = idx; m < outList.size(); m++)
+ {
+ nabsData.append((char*)(&outList[m]), sizeof(DsAbsItem));
+ }
+ }
+ }
+
+ //重新计算ar
+ stepsize = nabsData.size() / sizeof(DsAbsItem);
+ if(stepsize <= 0)
+ {
+ return;
+ }
+
+ //最后添加结束码,ax和ay是最后一针的
+ DsAbsItem dsAbsItem;
+ memcpy(&dsAbsItem,nabsData.data()+(nabsData.size() - sizeof(DsAbsItem)),sizeof(DsAbsItem));
+ dsAbsItem.ctrl = DATA_END;
+ nabsData.append((char*)(&dsAbsItem), sizeof(DsAbsItem));
+ stepsize++;
+
+ DsAbsItem * absDataPtr = (DsAbsItem *)(nabsData.data());
+
+ double minX, maxX, minY, maxY;
+ minX = S32_MAX;
+ maxX = S32_MIN;
+ minY = S32_MAX;
+ maxY = S32_MIN;
+
+ double prex,prey,curx,cury,dx,dy,ar;
+ prex = prey = curx = cury = dx = dy = ar = 0;
+
+ prex = absDataPtr->ax;
+ prey = absDataPtr->ay;
+
+ for (int i = 0; i < stepsize; i++)
+ {
+ curx = absDataPtr->ax;
+ cury = absDataPtr->ay;
+
+ dx = curx - prex;
+ dy = cury - prey;
+
+ double tar = atan2(dy,dx);
+ ar = (tar*10000+0.5*(tar>0?1:-1));
+ absDataPtr->ar = ar;
+
+ if(curx > maxX)
+ {
+ maxX = curx;
+ }
+ if(curx < minX)
+ {
+ minX = curx;
+ }
+
+ if(cury > maxY)
+ {
+ maxY = cury;
+ }
+ if(cury < minY)
+ {
+ minY = cury;
+ }
+
+ prex = curx;
+ prey = cury;
+
+ absDataPtr++;
+ }
+
+ //修改绝对坐标数据
+ m_pEmbDs16Head->dataSize = stepsize*sizeof(DsAbsItem); // 数据字节数
+ m_pEmbDs16Head->itemNums = stepsize; // 数据项个数
+ m_pEmbDs16Head->maxX = maxX;
+ m_pEmbDs16Head->minX = minX;
+ m_pEmbDs16Head->maxY = maxY;
+ m_pEmbDs16Head->minY = minY;
+ m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 数据累加校验和
+ m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值)
+ u32 fileID = 0;
+ fileID = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 原始数据累加校验和
+ m_pEmbDs16Head->fileid = fileID; //中间数据的 fileid =
+
+ m_embAbsData.clear();
+ m_embAbsData.append((char *)(m_pEmbDs16Head), sizeof(DataDs16FileHead));
+ m_embAbsData.append(nabsData);
+}
+
+//移动起始点,左边,前边
+int EmbData::moveStartPoint(short left, short front)
+{
+ if(m_pEmbDs16Head == NULL){return -1;}
+ if(m_embDs16Data.size() <= 0){return -1;}
+
+ m_pEmbDs16Head->anchorX += left;
+ m_pEmbDs16Head->anchorY += front;
+ m_pEmbDs16Head->beginX += left;
+ m_pEmbDs16Head->beginY += front;
+
+ //将最大最小值写入文件头
+ m_pEmbDs16Head->maxX += left;
+ m_pEmbDs16Head->minX += left;
+ m_pEmbDs16Head->maxY += front;
+ m_pEmbDs16Head->minY += front;
+
+ m_maxX += left;
+ m_minX += left;
+ m_maxY += front;
+ m_minY += front;
+ memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));
+
+ return 0;
+}
+
+void EmbData::moveDataBeginPonit(s32 left, s32 front)
+{
+ if((u32)m_embAbsData.size() > sizeof(DataDs16FileHead)){
+ DataDs16FileHead *dhead = (DataDs16FileHead *)(m_embAbsData.data());
+ dhead->beginX += left;
+ dhead->beginY += front;
+ dhead->maxX += left;
+ dhead->minX += left;
+ dhead->maxY += front;
+ dhead->minY += front;
+ }
+}
+
+void EmbData::appendAEmbAbsFile(QString filePath, QByteArray array, int mirror)
+{
+ m_filePath = filePath;
+ convertAbsDat(array,mirror);//是否镜像、旋转、缩放的转换
+ m_embAbsData.clear();
+ m_embAbsData.append(array);
+ m_editedflag = 1;
+}
+
+void EmbData::setAbsDat(QByteArray & dat)
+{
+ m_embAbsData = dat;
+}
+
+QByteArray & EmbData::getAbsDat(void)
+{
+ return m_embAbsData;
+}
+
+int EmbData::getPosInfoFromNeedleIdx(int stitchIdx, int &posx, int &posy, int &colorIdx)
+{
+ if (m_editedflag != 0)
+ {
+ createEmbDs16FromAbs();
+ }
+
+ posx = 0;
+ posy = 0;
+ colorIdx = 0;
+
+ // 文件头
+ int size = m_embDs16Data.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("m_embDs16Data data less then head size");
+ return -1;
+ }
+
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data());
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ int stepsize = datasize/sizeof(Ds16Item);
+ if (stepsize <= 0)
+ {
+ qDebug("ds16 data size err");
+ return -1;
+ }
+
+ Ds16Item * ds16DataPtr;
+ Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
+ ds16DataPtr = pData;
+
+ posx = pDsHead->beginX;
+ posy = pDsHead->beginY;
+
+ colorIdx = 1;
+
+ if (stitchIdx <= 0)
+ {
+ return 0;
+ }
+
+ if (stitchIdx > datasize)
+ {
+ stitchIdx = datasize;
+ }
+
+ int dx, dy;
+ u8 ctrl, attr;
+
+ for (int i = 0; i < stitchIdx; i++)
+ {
+ ctrl = ds16DataPtr->ctrl;
+ attr = ds16DataPtr->attr;
+ dx = ds16DataPtr->dx;
+ dy = ds16DataPtr->dy;
+
+ if (ctrl == DATA_CHGND)
+ {
+ colorIdx++;
+ }
+
+ if ((attr&0x80) != 0)
+ {
+ dx *= -1;
+ }
+
+ if ((attr&0x40) != 0)
+ {
+ dy *= -1;
+ }
+
+ posx += dx;
+ posy += dy;
+
+ ds16DataPtr++;
+ }
+
+ return 0;
+}
+
+//设置起始点
+void EmbData::setStartPosition(int x, int y)
+{
+ if(m_pEmbDs16Head == NULL){return;}
+ if(m_embDs16Data.size() <= 0){return;}
+
+ //旧的起始点坐标
+ int oldBeginX = m_pEmbDs16Head->beginX;
+ int oldBeginY = m_pEmbDs16Head->beginY;
+
+ m_pEmbDs16Head->beginX = x;
+ m_pEmbDs16Head->beginY = y;
+
+ //新的起始点坐标与旧的起始点坐标的差值
+ int cx = x - oldBeginX;
+ int cy = y - oldBeginY;
+
+ //重新计算最大最小XY
+ double maxX = m_pEmbDs16Head->maxX + cx;
+ double minX = m_pEmbDs16Head->minX + cx;
+ double maxY = m_pEmbDs16Head->maxY + cy;
+ double minY = m_pEmbDs16Head->minY + cy;
+
+ //将最大最小值写入文件头
+ m_pEmbDs16Head->maxX = maxX;
+ m_pEmbDs16Head->minX = minX;
+ m_pEmbDs16Head->maxY = maxY;
+ m_pEmbDs16Head->minY = minY;
+
+ //修复偶尔点击中间按钮花样消失的bug
+ m_maxX = maxX;
+ m_minX = minX;
+ m_maxY = maxY;
+ m_minY = minY;
+ memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));
+
+ qDebug()<<"m_maxX"<beginX *= factorx;
+ pDsHead->beginY *= factory;
+
+ // 数据缩放
+ for (int j = 0; j < stepsize; j++)
+ {
+ double ax = absDataPtr->ax;
+ double ay = absDataPtr->ay;
+
+ ax *= factorx;
+ ay *= factory;
+
+ absDataPtr->ax = ax;
+ absDataPtr->ay = ay;
+
+ absDataPtr++;
+ }
+
+ m_editedflag = 1;
+
+ return 1;
+}
+
+int EmbData::setMirror(int mirror)
+{
+ if (mirror == 0) // 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像
+ {
+ return 0;
+ }
+
+ int mirrorx = 1; //x轴
+ int mirrory = 1; //y轴
+ int mirrorr = 0;
+ int mirrorrdir = 0;
+
+ if(mirror == 1 || mirror == 3)
+ {
+ mirrorx = -1;
+ }
+ if(mirror == 2 || mirror == 3)
+ {
+ mirrory = -1;
+ }
+
+ if(mirror == 1)
+ {
+ mirrorr = 1*PI*10000;
+ mirrorrdir = -1;
+ }
+ else if (mirror == 2)
+ {
+ mirrorr = 2*PI*10000;
+ mirrorrdir = -1;
+ }
+ else if (mirror == 3)
+ {
+ mirrorr = 1*PI*10000;
+ mirrorrdir = 1;
+ }
+
+ // 文件头
+ const QByteArray & ary = m_embAbsData;
+ int size = ary.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("ary data less then head size");
+ return -1;
+ }
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("dat data size err");
+ return -1;
+ }
+
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
+
+ //在最大最小xy中 对起始点进行镜像处理
+
+ int bx = pDsHead->beginX;
+ int by = pDsHead->beginY;
+
+ if(mirrorx == -1)
+ pDsHead->beginX = pDsHead->maxX - (bx - pDsHead->minX);
+ if(mirrory == -1)
+ pDsHead->beginY = pDsHead->maxY - (by - pDsHead->minY);
+
+ //beginR的旋转
+ double br = pDsHead->beginR;
+ if (mirrorrdir > 0)
+ {
+ br = br + mirrorr;
+ }
+ else if (mirrorrdir < 0)
+ {
+ br = mirrorr - br;
+ }
+
+ while (br > 2*PI * 10000)
+ {
+ br -= 2*PI * 10000;
+ }
+ while (br < -2*PI * 10000)
+ {
+ br += 2*PI * 10000;
+ }
+ pDsHead->beginR = br;
+
+ DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData;
+
+ // 数据镜像
+ for (int j = 0; j < stepsize; j++)
+ {
+ double ax = absDataPtr->ax;
+ double ay = absDataPtr->ay;
+ double ar = absDataPtr->ar;
+
+ int rx = ax * mirrorx; //相对坐标 乘负数则数据镜像
+ int ry = ay * mirrory;
+
+ if (mirrorrdir > 0)
+ {
+ ar = ar + mirrorr;
+ }
+ else if (mirrorrdir < 0)
+ {
+ ar = mirrorr - ar;
+ }
+
+ while (ar > 2*PI * 10000)
+ {
+ ar -= 2*PI * 10000;
+ }
+ while (ar < -2*PI * 10000)
+ {
+ ar += 2*PI * 10000;
+ }
+
+ absDataPtr->ax = rx;
+ absDataPtr->ay = ry;
+ absDataPtr->ar = ar;
+
+ absDataPtr++;
+ }
+
+ m_editedflag = 1;
+ return 1;
+}
+
+//flag :true代表顺时针方向
+int EmbData::setRotate90(bool flag)
+{
+
+ // 文件头
+ const QByteArray & ary = m_embAbsData;
+ int size = ary.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("ary data less then head size");
+ return -1;
+ }
+ int datasize = size - sizeof(DataDs16FileHead);
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("dat data size err");
+ return -1;
+ }
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
+
+ int maxX = pDsHead->maxX;
+ int maxY = pDsHead->maxY;
+
+ int bx = pDsHead->beginX;
+ int by = pDsHead->beginY;
+
+ if(flag){ //正向旋转90
+ pDsHead->beginX = maxY - by;
+ pDsHead->beginY = bx;
+ }
+ else{
+ pDsHead->beginX = by;
+ pDsHead->beginY = maxX - bx;
+ }
+
+ DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData;
+
+ for (int j = 0; j < stepsize; j++)
+ {
+ double ax = absDataPtr->ax;
+ double ay = absDataPtr->ay;
+
+ int rx, ry;
+ if(flag){ //正向旋转90
+ rx = -ay;
+ ry = ax;
+ }else{
+ rx = ay;
+ ry = -ax;
+ }
+
+ absDataPtr->ax = rx;
+ absDataPtr->ay = ry;
+
+ absDataPtr++;
+ }
+
+ m_editedflag = 1;
+ return 1;
+
+}
+
+///
+/// \brief //获得下一个图元的第一缝纫针步
+/// \param curIndex
+/// \return
+///
+int EmbData::getNextElementIndex(int curIndex)
+{
+ // ds16数据
+ int size = m_embDs16Data.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("16 data less then head size");
+ return -1;
+ }
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("dat dataBegin err");
+ return -1;
+ }
+ int stepsize = datasize/sizeof(Ds16Item);
+ if (stepsize <= 0)
+ {
+ qDebug("ds16 data size err");
+ return -1;
+ }
+
+ Ds16Item * ds16DataPtr = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
+ ds16DataPtr = ds16DataPtr + curIndex;
+
+ u8 curByte =ds16DataPtr->ctrl; //当前状态
+ ds16DataPtr ++;
+ curIndex ++;
+
+ int i = curIndex;
+ for (; i < stepsize; i++)
+ {
+
+ if(curByte != DATA_SEWING)
+ {
+ if(ds16DataPtr->ctrl == DATA_SEWING)
+ break;
+ }else{
+ if(ds16DataPtr->ctrl != DATA_SEWING)
+ curByte = ds16DataPtr->ctrl;
+ }
+ ds16DataPtr++;
+ }
+ return i;
+}
+
+///
+/// \brief //上一个图元(当前为跨步时)或当前图元(当前为缝纫时)的第一缝纫针步
+/// \param curIndex
+/// \return
+///
+int EmbData::getPreOrThisElementIndex(int curIndex)
+{
+ // ds16数据
+ int size = m_embDs16Data.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("16 data less then head size");
+ return -1;
+ }
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("dat dataBegin err");
+ return -1;
+ }
+ int stepsize = datasize/sizeof(Ds16Item);
+ if (stepsize <= 0)
+ {
+ qDebug("ds16 data size err");
+ return -1;
+ }
+
+ Ds16Item * ds16DataPtr = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
+ ds16DataPtr = ds16DataPtr + curIndex;
+
+ u8 curByte =ds16DataPtr->ctrl; //当前状态
+ ds16DataPtr--;
+ curIndex --;
+
+ int i = curIndex;
+
+ for (; i > 0; i--)
+ {
+ //如果当前是缝纫数据,找到其他的就返回下一针
+ if(curByte == DATA_SEWING)
+ {
+ if(ds16DataPtr->ctrl != DATA_SEWING)
+ break;
+ }else{
+ //找到其他的就返回下一针
+ if(ds16DataPtr->ctrl == DATA_SEWING)
+ curByte = DATA_SEWING;
+ }
+ ds16DataPtr--;
+ }
+ return ++i;
+}
+
+int EmbData::setRotate(int dr)
+{
+ double rr = (dr * PI / 180) * 10000; //转换为弧度
+
+ if (dr == 0 || dr == 360)
+ {
+ return 0;
+ }
+
+ double angle, sina, cosa;
+
+#if (1)
+ // 因为计算三角函数有问题,现在只支持 1度,10度,90度
+ switch(dr)
+ {
+ case 1:
+ sina = 0.01745240643728351281941897851632;
+ cosa = 0.99984769515639123915701155881391;
+ break;
+ case 10:
+ sina = 0.17364817766693034885171662676931;
+ cosa = 0.98480775301220805936674302458952;
+ break;
+ case 90:
+ sina = 1;
+ cosa = 0;
+ break;
+ case -1:
+ sina = -0.01745240643728351281941897851632;
+ cosa = 0.99984769515639123915701155881391;
+ break;
+ case -10:
+ sina = -0.17364817766693034885171662676931;
+ cosa = 0.98480775301220805936674302458952;
+ break;
+ case -90:
+ sina = -1;
+ cosa = 0;
+ break;
+ default:
+ angle = (dr * PI) / 180.0;
+ sina = (double)qSin(angle);
+ cosa = (double)qCos(angle);
+ break;
+ }
+
+#else
+
+ angle = (dr * PI) / 180.0;
+ sina = (double)qSin(angle);
+ cosa = (double)qCos(angle);
+#endif
+
+
+ // 文件头
+ const QByteArray & ary = m_embAbsData;
+ int size = ary.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("ary data less then head size");
+ return -1;
+ }
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("dat data size err");
+ return -1;
+ }
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
+
+ //beginR的旋转
+ double br = pDsHead->beginR + rr;
+ while (br > 2*PI * 10000)
+ {
+ br -= 2*PI * 10000;
+ }
+ while (br < -2*PI * 10000)
+ {
+ br += 2*PI * 10000;
+ }
+ pDsHead->beginR = br;
+
+ DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData;
+
+ // 数据旋转
+ for (int j = 0; j < stepsize; j++)
+ {
+ // 变换前点坐标
+ double ax = absDataPtr->ax;
+ double ay = absDataPtr->ay;
+ double ar = absDataPtr->ar + rr;
+
+ while (ar > 2*PI * 10000)
+ {
+ ar -= 2*PI * 10000;
+ }
+ while (ar < -2*PI * 10000)
+ {
+ ar += 2*PI * 10000;
+ }
+ // 变换后点的坐标
+ double rax = (ax*cosa - ay*sina);
+ double ray = (ax*sina + ay*cosa);
+
+ absDataPtr->ax = rax;
+ absDataPtr->ay = ray;
+ absDataPtr->ar = ar;
+ absDataPtr++;
+ }
+
+ m_editedflag = 1;
+
+ return 1;
+}
+
+//此函数转换传入的绝对坐标值,是否取镜像及反复时数据之间的间距
+void EmbData::convertAbsDat(QByteArray &dat, int mirror)
+{
+ //无镜像、xy间距、角度旋转、缩放比例都为0时数据无需转换
+ if(mirror == 0 &&
+ m_spaceX == 0 &&
+ m_spaceY == 0 )
+ {
+ return;
+ }
+
+ int size = dat.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("data less then head size");
+ return;
+ }
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(dat.data());
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("dat dataBegin err");
+ return;
+ }
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("dat data size err");
+ return;
+ }
+ DsAbsItem * pData = (DsAbsItem *)(dat.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData;
+ //--------
+
+ //镜像数值不为0---开始
+ // mirror 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像
+ int mirrorx = 1;
+ int mirrory = 1;
+ int mirrorr = 1;
+
+ if(mirror == 1 || mirror == 3)
+ {
+ mirrorx = -1;
+ mirrorr = -1;
+ }
+ if(mirror == 2 || mirror == 3)
+ {
+ mirrory = -1;
+ mirrorr = -1;
+ }
+
+ // 镜像文件头转换
+ if(mirror != 0)
+ {
+ pDsHead->beginX = pDsHead->beginX * mirrorx;
+ pDsHead->beginY = pDsHead->beginY * mirrory;
+ }
+
+ // 镜像或列表间距不为0
+ if(mirror != 0 || m_spaceX != 0 || m_spaceY != 0)
+ {
+ //图形先居中,起始点在加上偏移
+ int centerx = (m_maxX + m_minX)/2;
+ int centery = (m_maxY + m_minY)/2;
+
+ int rx = (pDsHead->beginX - centerx) * mirrorx;
+ int ry = (pDsHead->beginY - centery) * mirrory;
+
+ int beginx = rx + centerx;
+ int beginy = ry + centery;
+
+ //用下面两行代码,否则反复方式为Y轴对称或XY对称时不对
+ pDsHead->beginX = beginx + m_spaceX;
+ pDsHead->beginY = beginy + m_spaceY;
+ }
+ //镜像数值不为0---结束
+
+ absDataPtr = pData;
+
+ //镜像有变换时运动步才转换
+ double dx, dy, dr;
+
+ if(mirror != 0)
+ {
+ for (int i = 0; i < stepsize; i++)
+ {
+ // 读入一个针步数据
+ dx = absDataPtr->ax;
+ dy = absDataPtr->ay;
+ dr = absDataPtr->ar;
+
+ //镜像不为0
+ if(mirror != 0)
+ {
+ dx = dx * mirrorx;
+ dy = dy * mirrory;
+ dr = dr * mirrorr;
+ }
+
+ absDataPtr->ax = dx;
+ absDataPtr->ay = dy;
+ absDataPtr->ar = dr;
+
+ absDataPtr++;
+ }
+ }
+
+ return;
+}
+
+int EmbData::calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, DsAbsItem item)
+{
+ DsAbsItem absItem;
+ memcpy(&absItem,&item,sizeof(DsAbsItem));
+
+ s32 dx, dy;
+ double length;
+ double tmp;
+ int count;
+ int i;
+ double stepx, stepy;
+ double sx, sy;
+ int actx, acty;
+ double k;
+
+ if(x0 == x1 && y0 == y1)
+ {
+ return 0;
+ }
+
+ if(x0 > x1)
+ {
+ sx = -1.0; // x反向
+ }
+ else
+ {
+ sx = 1.0;
+ }
+
+ if(y0 > y1)
+ {
+ sy = -1.0; // y反向
+ }
+ else
+ {
+ sy = 1.0;
+ }
+
+ // 开始分割针步
+ length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
+
+ tmp = length/step; /* 实际针步数 */
+ count = floor(tmp); /* 最少整针步数 */
+
+ if (tmp - count > 0.01)
+ {
+ count += 1;
+ }
+
+ if (count == 0 && length > 0) // 短直线
+ {
+ count = 1;
+ }
+
+ tmp = 0;
+ actx = x0;
+ acty = y0;
+
+ if (x1 != x0 && y1 == y0) // 横直线
+ {
+ for (i = 0; i < count; i++)
+ {
+ tmp = ((i+1)*(length)/count)*sx+x0; // 实际针步
+
+ stepx = tmp - actx;
+ dx = (s32)(stepx+0.5*sx);
+ dy = 0;
+ actx += dx;
+
+ absItem.ax = actx;
+ absItem.ay = y0;
+ absAry.append((char*)&absItem,sizeof(DsAbsItem));
+ }
+ }
+ else if (x1 == x0 && y1 != y0) // 竖直线
+ {
+ for (i = 0; i < count; i++)
+ {
+ tmp = ((i+1)*(length)/count)*sy + y0; // 实际针步
+
+ stepy = tmp - acty;
+
+ dx = 0;
+ dy = (s32)(stepy+0.5*sy);
+ acty += dy;
+
+ absItem.ax = x0;
+ absItem.ay = acty;
+ absAry.append((char*)&absItem,sizeof(DsAbsItem));
+ }
+ }
+ else if(x1 != x0 && y1 != y0) // 任意斜线
+ {
+ k = (y1-y0)/(x1-x0);
+ for (i = 0; i < count; i++)
+ {
+ tmp = ((i+1)*(length)/count);
+
+ stepx = fabs(tmp*cos(atan(k)))*sx + x0; // 实际针步x
+ stepy = fabs(tmp*sin(atan(k)))*sy + y0; // 实际针步y
+
+ dx = (s32)(stepx-actx+0.5*sx);
+ dy = (s32)(stepy-acty+0.5*sy);
+
+ actx += dx;
+ acty += dy;
+
+ absItem.ax = actx;
+ absItem.ay = acty;
+ absAry.append((char*)&absItem,sizeof(DsAbsItem));
+ }
+ }
+ else
+ {
+ printf("what's this?\n");
+ }
+
+ return count;
+}
+
+//花版的定位点为绝对坐标数据点,起始点为相对于定位点的相对坐标点,第一针为相对于起始点的坐标点
+//有的花版起始点有偏移量,第一针偏移量为0,有的花版起始点偏移量为0,第一针有偏移量
+//所以ds16文件头定位点坐标就是花版中的定位点,起始点坐标为花版中的定位点坐标+起始点坐标+第一针的坐标,同时ds16数据的第一针坐标偏移应置为0
+//生成DS16数据
+int EmbData::createEmbDs16FromAbs()
+{
+#if(0)
+ QString ds16FilePath = m_filePath + ".ds16";
+ QFile file(ds16FilePath);
+
+ if(file.exists())//存在ds16文件
+ {
+ if(!file.open(QIODevice::ReadOnly))
+ {
+ qDebug() << "open file fail when read, path =" << m_filePath;
+ return -1;
+ }
+
+ m_embDs16Data = file.readAll();
+ file.close();
+
+ if(m_embDs16Data.size() <= 0)
+ {
+ return -1;
+ }
+
+ memcpy(m_pEmbDs16Head, m_embDs16Data.data(), sizeof(DataDs16FileHead)); // 文件名称
+
+ m_minX = m_pEmbDs16Head->minX;
+ m_maxX = m_pEmbDs16Head->maxX;
+ m_minY = m_pEmbDs16Head->minY;
+ m_maxY = m_pEmbDs16Head->maxY;
+ m_beginX = m_pEmbDs16Head->beginX;
+ m_beginY = m_pEmbDs16Head->beginY;
+
+ m_editedflag = 0;
+
+ return 0;
+ }
+#endif
+
+ if (m_editedflag != 0)
+ {
+ m_minX = S32_MAX;
+ m_maxX = S32_MIN;
+ m_minY = S32_MAX;
+ m_maxY = S32_MIN;
+
+ m_embDs16Data.clear();
+
+ QString name;
+
+ QByteArray tgtdsdat;
+ tgtdsdat.clear();
+
+ u8 ctrlByte;
+ u8 attrByte;
+ WORD actionWord; //附加动作
+ s32 dx, dy, dr;
+ u16 len;
+ double ax, ay, ar;
+ int actx, acty, actr;
+ int ddx, ddy,ddr;
+
+ int beginx, beginy, beginr, anchorx, anchory;
+ int minx, miny, maxx, maxy;
+ int colornum = 1;
+ int jumpNeedleNum = 0;//跳针数
+ actx = 0;
+ acty = 0;
+ actr =0;
+ beginx = 0;
+ beginy = 0;
+ beginr = 0;
+ anchorx = anchory = 0;
+
+ int totalstepsize = 0;
+ memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead));
+
+ const QByteArray & ary = m_embAbsData;
+ int size = ary.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("ary data less then head size");
+ return -1;
+ }
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
+ //fileId = pDsHead->fileid;
+
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("absdat dataBegin err");
+ return -1;
+ }
+ int stepsize = datasize/sizeof(DsAbsItem);
+ if (stepsize <= 0)
+ {
+ qDebug("absdat data size err");
+ return -1;
+ }
+ DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
+ DsAbsItem * absDataPtr = pData; //中间数据针步
+ //-----
+
+ // 文件名称
+ QString str = QString::fromLocal8Bit(pDsHead->fileName);
+ name = str;
+ //str.sprintf("%s", pDsHead->fileName);
+ //name += " ";
+ //name += str;
+
+ minx = absDataPtr->ax;
+ maxx = absDataPtr->ax;
+ miny = absDataPtr->ay;
+ maxy = absDataPtr->ay;
+
+ // 数据区
+ qDebug()<<"stepsize:"<ctrl;
+ attrByte = absDataPtr->attr;//绝对数据的属性字节
+ actionWord = absDataPtr->action;
+
+ ax = absDataPtr->ax;//绝对数据的X位置
+ ay = absDataPtr->ay;
+ ar = absDataPtr->ar;
+
+ // 轮廓
+ if (minx > ax) { minx = ax; }
+ if (maxx < ax) { maxx = ax; }
+ if (miny > ay) { miny = ay; }
+ if (maxy < ay) { maxy = ay; }
+
+ if (j == 0)//第一针
+ {
+ beginx = ax;
+ beginy = ay;
+ beginr = ar;
+ actx = ax;
+ acty = ay;
+ actr = ar;
+ anchorx = pDsHead->anchorX;
+ anchory = pDsHead->anchorY;
+
+ ddx = 0;
+ ddy = 0;
+ //让ddr等于0,因为在datafiledsr中将beginR置为0而非第一针的角度,所以不应该用 absDataPtr->ar - pDsHead->beginR
+ //如果beginR等于第一针的角度,那么第一针的ddr就应该是0
+ ddr = 0;
+
+ //过滤掉空针
+ if(ddx== 0 && ddy == 0)
+ {
+ actx += ddx;
+ acty += ddy;
+ actr += ddr;
+ absDataPtr++;
+
+ continue;
+ }
+ }
+ else
+ {
+ ddx = ax - actx;
+ ddy = ay - acty;
+ ddr = ar -actr;
+ }
+
+ if( ctrlByte == DATA_END ||
+ ctrlByte == DATA_PAUSE ||
+ ctrlByte == DATA_CHGND ||
+ ctrlByte == DATA_CUTTRD ||
+ ctrlByte == DATA_ANGLE ||
+ 0 )
+ {
+ ddx = 0;
+ ddy = 0;
+ ddr = 0;
+ }
+
+ dx = ddx;
+ dy = ddy;
+ dr = ddr;
+
+ actx += ddx;
+ acty += ddy;
+ actr += ddr;
+
+ while (dr < -PI10000)
+ {
+ dr += PI20000;
+ }
+ while (dr > PI10000)
+ {
+ dr -= PI20000;
+ }
+
+ if ( 0 && (ctrlByte == DATA_END || ctrlByte == DATA_NULL))
+ {
+ qDebug()<< "增加剪线" < maxStep && ctrlByte == DATA_SEWING)
+ if(xyLen > maxStep)
+ {
+ s16 addx,addy;
+ addx = addy = 0;
+ //分割针步
+ double splitVal = 400.0;//分割针步为400
+ s32 stepNum = xyLen / splitVal;//拆分几步
+ double lastStep = (double)((int)xyLen % (int)splitVal);
+ double addStep = lastStep / stepNum;
+
+ double stepX = 0;
+ double stepY = 0;
+ double stepDr = 0;
+ for(int m = 0; m < stepNum; m++)
+ {
+ stepX = 0;
+ stepY = 0;
+ stepDr = 0;
+ memset(&ds16Item,0,sizeof(Ds16Item));//初始化结构体
+
+ stepX = dx * splitVal / xyLen + dx * addStep / xyLen;
+ stepY = dy * splitVal / xyLen + dy * addStep / xyLen;
+
+ if(m == 0)
+ {
+ stepDr = dr;
+ }
+
+ ds16Item.dx = qRound(stepX);//四舍五入
+ ds16Item.dy = qRound(stepY);
+
+ if (m == stepNum-1)
+ {// 最后一针,消除累计误差
+ ds16Item.dx = dx - addx;
+ ds16Item.dy = dy - addy;
+ }
+ else
+ {
+ addx += ds16Item.dx;
+ addy += ds16Item.dy;
+ }
+
+ ds16Item.ctrl = ctrlByte;
+ len = sqrt(ds16Item.dx*ds16Item.dx + ds16Item.dy*ds16Item.dy);
+ ds16Item.attr = attrByte;
+ ds16Item.action[0] = 0;
+ ds16Item.action[1] = 0;
+ ds16Item.dr = stepDr;
+ ds16Item.len = len;
+ memset(ds16Item.rev,0,sizeof(ds16Item.rev));
+ tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
+ totalstepsize++;
+ }
+ }
+ else
+ {
+ len = sqrt(dx*dx + dy*dy);
+ ds16Item.ctrl = ctrlByte;
+ ds16Item.attr = attrByte;
+
+ memcpy(ds16Item.action,&actionWord,sizeof(actionWord));
+
+ ds16Item.dx = dx;
+ ds16Item.dy = dy;
+ ds16Item.dr = dr;
+ ds16Item.len = len;
+ memset(ds16Item.rev,0,sizeof(ds16Item.rev));
+ tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));//ds16针步
+ totalstepsize++;
+ }
+
+ if (ctrlByte == DATA_CHGND)
+ {
+ colornum++;
+ }
+
+ if (ctrlByte == DATA_OFFSET)
+ {
+ jumpNeedleNum++;//跨步总数加1
+ }
+
+ absDataPtr++;
+ }
+
+ if (m_minX > minx) { m_minX = minx; }
+ if (m_minX > maxx) { m_minX = maxx; }
+ if (m_maxX < minx) { m_maxX = minx; }
+ if (m_maxX < maxx) { m_maxX = maxx; }
+ if (m_minY > miny) { m_minY = miny; }
+ if (m_minY > maxy) { m_minY = maxy; }
+ if (m_maxY < miny) { m_maxY = miny; }
+ if (m_maxY < maxy) { m_maxY = maxy; }
+
+ // 针数
+ int newstepnum = tgtdsdat.size() / sizeof(Ds16Item);
+ qDebug()<< "newstepnum" < 0)
+ {
+ // 修改文件头
+ int namelen = name.size();
+ if (namelen > HEAD_NAME_STR_LEN)
+ {
+ namelen = HEAD_NAME_STR_LEN;
+ }
+
+ QByteArray array = name.toLocal8Bit().data();
+ int asize = array.length();
+ memcpy(m_pEmbDs16Head->fileName, array, asize); // 文件名称
+ m_pEmbDs16Head->dataSize = newstepnum*sizeof(Ds16Item); // 数据字节数
+ m_pEmbDs16Head->itemNums = newstepnum; // 数据项个数
+ m_pEmbDs16Head->bytesPerItem = sizeof(Ds16Item); // 每项占的字节数
+ m_pEmbDs16Head->bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小
+ m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(tgtdsdat.data()) , m_pEmbDs16Head->dataSize); // 数据累加校验和
+ m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值)
+ m_pEmbDs16Head->fileid = m_pEmbDs16Head->checkCrc;
+
+ m_pEmbDs16Head->anchorX = anchorx; // 定位点坐标X
+ m_pEmbDs16Head->anchorY = anchory; // 定位点坐标Y, 设置为0,作为基准
+ m_pEmbDs16Head->beginX = beginx; // 数据起点坐标X
+ m_pEmbDs16Head->beginY = beginy; // 数据起点坐标Y
+ m_pEmbDs16Head->beginR = beginr; // 数据起点坐标R //-rq
+ m_pEmbDs16Head->minX = m_minX;
+ m_pEmbDs16Head->maxX = m_maxX;
+ m_pEmbDs16Head->minY = m_minY;
+ m_pEmbDs16Head->maxY = m_maxY; // 轮廓范围,使用重新计算之后的值
+ //中间数据的文件头
+
+ // 添加文件头
+ m_embDs16Data.append((char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));//ds16头文件存在ds16中
+ // 添加文件数据
+ m_embDs16Data.append(tgtdsdat);
+ }
+
+#if(1)
+ //保存成ds16文件
+ QString ds16FilePath = m_filePath + ".ds16";
+ QFile file(ds16FilePath);
+
+ if(file.exists())//存在ds16文件
+ {
+ QFile::remove(ds16FilePath);
+ }
+
+ if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ {
+ qDebug() << "open file fail when wirte, path =" << m_filePath;
+ return -1;
+ }
+ else
+ {
+ file.write(m_embDs16Data);
+ file.close();
+ }
+#endif
+ }
+
+ m_editedflag = 0;
+
+ return 0;
+}
+
+int EmbData::reCalcDataChecksum()
+{
+ return 0;
+}
+
+//绘制针数索引的跟踪笔
+void EmbData::drawNeedleIdxPen(int x, int y, QPainter &painter)
+{
+ //贴图的xy和画笔的xy值相同
+ m_penX = x;
+ m_penY = y;
+
+ m_penPix = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像
+
+ QPen pen;
+ QColor color;
+
+ //绘制深灰色画笔
+ pen.setWidth(2);
+ color.setRgb(60,60,60);//深灰色
+ pen.setColor(color);
+ painter.setPen(pen);
+
+ painter.drawLine(x-4, y-28, x-4, y-8);//画左"|"
+ painter.drawLine(x+4, y-28, x+4, y-8); //画右"|"
+ painter.drawEllipse(x-1, y-10, 2, 2);//画中心"°"
+ painter.drawLine(x-4, y-8, x, y);//画左"\"(笔尖)
+ painter.drawLine(x+4, y-8, x, y); //画右"/"(笔尖)
+
+ //绘制深红色画笔
+ pen.setWidth(1);
+ color.setRgb(174,60,64);//深红色
+ pen.setColor(color);
+ painter.setPen(pen);
+
+ painter.drawLine(x-3, y-28, x-3, y-8);//画左"|"
+ painter.drawLine(x+5, y-28, x+5, y-8); //画右"|"
+ painter.drawEllipse(x-2, y-12, 3, 3);//画中心"°"
+ painter.drawLine(x-3, y-8, x, y);//画左"\"(笔尖)
+ painter.drawLine(x+5, y-8, x, y); //画右"/"(笔尖)
+}
+
+void EmbData::drawFork(int x, int y, QPainter &painter)
+{
+ //贴图的xy和画笔的xy值相同
+ m_penX = x;
+ m_penY = y;
+
+ m_penPix = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像
+
+ QPen pen;
+ QColor color;
+
+ //绘制深灰色画笔
+ pen.setWidth(2);
+ color.setRgb(228,42,48);
+ pen.setColor(color);
+ painter.setPen(pen);
+
+ painter.drawLine(x-8, y-8, x-3, y-3);// \上一半
+ painter.drawLine(x+8, y-8, x+3, y-3);// /上一半
+
+ painter.drawLine(x+3, y+3, x+8, y+8);
+ painter.drawLine(x-3, y+3, x-8, y+8);
+}
+
+void EmbData::drawFork(int x, int y, QPainter &painter, int index, bool isDraw)
+{
+ m_penPoint[index].setX(x);
+ m_penPoint[index].setY(y);
+
+ m_penHeadPix[index] = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像
+
+ QPen pen;
+ QColor color;
+
+ if(isDraw){
+ //绘制深灰色画笔
+ pen.setWidth(2);
+ color.setRgb(228,42,48);
+ pen.setColor(color);
+ painter.setPen(pen);
+
+ painter.drawLine(x-8, y-8, x-3, y-3);// \上一半
+ painter.drawLine(x+8, y-8, x+3, y-3);// /上一半
+
+ painter.drawLine(x+3, y+3, x+8, y+8);
+ painter.drawLine(x-3, y+3, x-8, y+8);
+ }
+
+}
+
+//擦除针数索引的跟踪笔
+void EmbData::eraseNeedleIdxPen(QPainter &painter)
+{
+ //贴图的xy和画笔的xy值相同
+ painter.drawPixmap(m_penX-20,m_penY-30,m_penPix);
+}
+
+void EmbData::eraseNeedleIdxPen(QPainter &painter, int index)
+{
+ painter.drawPixmap(m_penPoint[index].x()-20,m_penPoint[index].y()-30,m_penHeadPix[index]);
+}
+
+void EmbData::getCurvePointFillLine(QList &inList, double indRunLen, QList &outList)
+{
+ DsAbsItem dPoint1, dPoint2, dPoint3;
+ double dTatol, dLen1, dLen2, dSpace;
+ long lSum, lCount;
+
+ //计算总的线段长
+ int iCountPoint = inList.size();
+ if(iCountPoint <= 0)
+ {
+ return;
+ }
+
+ getTotalDistanceFillLine(&inList, dTatol);
+ if(dTatol == 0)
+ return;
+
+ lSum = (long)round(dTatol / indRunLen + 0.1667);
+ dSpace = dTatol / (double)lSum;
+ if(lSum == 0)
+ lSum = 1;
+
+ dPoint1 = inList[0];
+ outList.append(dPoint1);//添加第一个点
+ dPoint2 = dPoint1;
+
+ dLen1 = dSpace;
+ dLen2 = 0;
+ int i = 0;
+ for(lCount = 0; lCount < lSum; lCount++)
+ {
+ while(i < inList.size()-1 && dLen2 < dLen1)
+ {
+ dLen1 -= dLen2;
+ dPoint1 = dPoint2;
+ i++;
+ dPoint2 = inList[i];
+ dLen2 = sqrt((dPoint1.ax - dPoint2.ax) * (dPoint1.ax - dPoint2.ax) + (dPoint1.ay - dPoint2.ay) * (dPoint1.ay - dPoint2.ay));
+ }
+ if(dLen1 < dLen2)
+ {
+ getPointInSectFillLine(dPoint1, dPoint2, dLen1, dPoint3);
+ }
+ else
+ {
+ dPoint3 = dPoint2;
+ }
+ outList.append(dPoint3);
+ dLen2 -= dLen1;
+ dLen1 = dSpace;
+ dPoint1 = dPoint3;
+ }
+}
+
+int EmbData::getTotalDistanceFillLine(QList *pPointList, double &dTotal)
+{
+ DsAbsItem dPoint, dNext;
+ double d;
+ dTotal = 0;
+ int i = 0;
+ long lSum = (long)pPointList->count();
+ if(lSum > 1)
+ {
+ while(i < pPointList->size())
+ {
+ dPoint = pPointList->at(i);
+ i++;
+ if(i < pPointList->size())
+ {
+ dNext = pPointList->at(i);
+ d = sqrt((dPoint.ax - dNext.ax) * (dPoint.ax - dNext.ax) + (dPoint.ay- dNext.ay) * (dPoint.ay- dNext.ay));
+ dTotal += d;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+bool EmbData::getPointInSectFillLine(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp)
+{
+ bool bRes;
+ DsAbsItem dpoint[3];
+
+ dpoint[0] = p1;
+ dpoint[1] = p2;
+ dpoint[2] = outp;
+ outp = dpoint[1];
+
+ bRes = getPointAtSect(dpoint[0], dpoint[1], d, dpoint[2]);
+ outp.ax = dpoint[2].ax;
+ outp.ay = dpoint[2].ay;
+
+ return bRes;
+}
+
+bool EmbData::getPointAtSect(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp)
+{
+ double s = sqrt((p1.ax - p2.ax) * (p1.ax - p2.ax) + (p1.ay - p2.ay) * (p1.ay - p2.ay));
+ if(fabs(s) < ZERO)
+ {
+ if(d < ZERO)
+ {
+ outp.ax = p1.ax;
+ outp.ay = p1.ay;
+ }
+ return false;
+ }
+ outp.ax = (p2.ax - p1.ax) * d / s + p1.ax;
+ outp.ay = (p2.ay - p1.ay) * d / s + p1.ay;
+
+ return true;
+}
+
+//设置视图尺寸(透明背景)
+int EmbData::setViewInfo(int width, int height)
+{
+ // if (m_viewWidth != width ||
+ // m_viewHight != height)
+ {
+ if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
+ {
+ return -1;
+ }
+ m_viewWidth = width;
+ m_viewHight = height;
+ m_canvas = QPixmap(m_viewWidth, m_viewHight);
+ m_canvas.fill(Qt::transparent);//用透明色填充
+ //memset(m_canvas.bits(), 0x00, m_canvas.byteCount());
+ }
+ return 0;
+}
+
+//设置视图(带背景图片背景)
+void EmbData::setViewInfo(QPixmap pix)
+{
+ m_canvas = pix;
+}
+
+//重置数据
+void EmbData::setEmbData(int type, int redraw)
+{
+ m_type = type;
+ createDispFromEmbDs16Dat(m_embDs16Data);
+ if (redraw != 0)
+ {
+ drawImageByDispFile();
+ }
+}
+
+void EmbData::setDispMode(EmbData::DISP_MODE dispmode, int redraw)
+{
+ m_dispMode = dispmode;
+ if(redraw != 0)
+ {
+ drawImageByDispFile();
+ }
+}
+
+void EmbData::setDrawMode(EmbData::DRAW_MODE drawmode)
+{
+ m_drawMode = drawmode;
+}
+
+//设置进度显示数据
+void EmbData::setExecIndex(int index)
+{
+ m_stitchIndex = index;
+
+ if (m_dispMode == DISP_EXECING)
+ {
+ drawImageByDispFile();
+ }
+}
+
+void EmbData::reDraw()
+{
+ drawImageByDispFile();
+}
+
+//创建显示用的数据(为了快速显示)
+int EmbData::createDispFromEmbDs16Dat(QByteArray &ds16dat)
+{
+ if(m_type == MACHINE_FIVEHEADPRECISIONSEWING)
+ return createDispFromEmbDs16DatForHeadInfo(ds16dat);
+
+ DispItem dispItem;
+ m_dispDat.clear();//显示绘图用的数据(需要转换)
+
+ // DsAbsItem absItem;//用于轮廓提取的绝对坐标值
+ // m_ds16ToAbsDat.clear();//用于轮廓提取的绝对坐标值
+
+ m_stitchIndex = 0;
+ m_dispIndex = 0;
+
+ // ds16数据
+ int size = ds16dat.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("16 data less then head size");
+ return -1;
+ }
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data());
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("dat dataBegin err");
+ return -1;
+ }
+ int stepsize = datasize/sizeof(Ds16Item);
+ if (stepsize <= 0)
+ {
+ qDebug("ds16 data size err");
+ return -1;
+ }
+
+ Ds16Item * ds16DataPtr;
+ Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead));
+ ds16DataPtr = pData;
+
+ // 图形显示区域
+ int width = m_canvas.width();//留4个像素的边
+ int height = m_canvas.height();//留4个像素的边
+ if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
+ {
+ qDebug("preview img too small");
+ return -1;
+ }
+
+ //留边(否则实时跟踪笔会画出界)
+ int viewSide = EMB_PREVIEW_SIDE;
+ if(m_drawMode == DRAW_PREVIEW)
+ {
+ viewSide = 20;//预览模式时整区域留20像素绘制(原色显示)
+ }
+ int dpminx = viewSide;
+ int dpmaxx = width - viewSide;
+ int dpminy = viewSide;
+ int dpmaxy = height - viewSide;
+
+ //1:1显示无需留边
+ // int dpminx = 0;
+ // int dpmaxx = width;
+ // int dpminy = 0;
+ // int dpmaxy = height;
+
+ // 计算缩放系数
+ double factor, temp;
+ if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0)
+ {
+ return -1;
+ }
+
+ factor = (double)(fabs(m_maxX-m_minX)) / (dpmaxx - dpminx); // 按框尺寸x计算的缩放系数
+ temp = (double)(fabs(m_maxY-m_minY)) / (dpmaxy - dpminy); // 按框尺寸y计算的缩放系数
+
+ if (temp >= factor) // 使用较大的缩放系数
+ {
+ factor = temp;
+ }
+
+ m_factor = factor;
+
+ // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心)
+ int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2);
+ int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2);
+
+ // 显示花样图形
+ u8 ctrlByte;
+ u8 attrByte;
+ int dx;
+ int dy;
+ int dr;
+
+ double datposx, datposy, datposr;
+ int curx, cury, curr, prex, prey;
+ curx = cury = curr = prex = prey = 0;
+
+ datposx = pDsHead->beginX;
+ datposy = pDsHead->beginY;
+ datposr = pDsHead->beginR;
+
+ curx = (datposx) / factor + dpx;
+ cury = (datposy) / factor + dpy;
+
+ if (EMB_SHOWDIRX == -1)
+ {
+ curx = width - curx;
+ }
+ if (EMB_SHOWDIRY == -1)
+ {
+ cury = height - cury;
+ }
+
+ for (int i = 0; i < stepsize; i++)
+ {
+ prex = curx;
+ prey = cury;
+
+ // 读入一个针步数据
+ ctrlByte = ds16DataPtr->ctrl;
+ attrByte = ds16DataPtr->attr;
+ dx = ds16DataPtr->dx;
+ dy = ds16DataPtr->dy;
+ dr = ds16DataPtr->dr;
+
+ datposx += dx;
+ datposy += dy;
+ datposr += dr;
+
+ curx = (datposx) / factor + dpx;
+ cury = (datposy) / factor + dpy;
+
+ if (EMB_SHOWDIRX == -1)
+ {
+ curx = width - curx;
+ }
+ if (EMB_SHOWDIRY == -1)
+ {
+ cury = height - cury;
+ }
+
+ while(datposr >= PI10000)
+ {
+ datposr -= (PI20000-1);
+ }
+ while(datposr <= -PI10000)
+ {
+ datposr += (PI20000-1);
+ }
+
+ dispItem.ctrl = ctrlByte;
+ dispItem.attr = attrByte;
+ dispItem.bx = prex;
+ dispItem.by = prey;
+ dispItem.ex = curx;
+ dispItem.ey = cury;
+ dispItem.ar = curr;
+ if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
+ dispItem.rgb = rgbColorYel;
+ else
+ dispItem.rgb = rgbColorBlue;
+
+ memcpy(&dispItem.action,ds16DataPtr->action,sizeof(dispItem.action));
+
+ m_dispDat.append((char*)(&dispItem), sizeof(DispItem));
+
+ ds16DataPtr++;
+ }
+
+ qDebug("CreateDispFromEmbDs16, stepsize=%d", m_dispDat.size() / sizeof(DispItem));
+
+ return 0;
+}
+
+int EmbData::createDispFromEmbDs16DatForHeadInfo(QByteArray &ds16dat)
+{
+ m_headDispDate.clear();
+
+ DataFileDsr dsr;//可能引起栈内存溢出的问题
+ dsr.initFile(m_filePath);
+ dsr.convertDataToEmbAbs();
+ DsrHeadEx62 head = dsr.get62ExHead();
+ int StepNum = dsr.getStepNums();
+ int maxHSP = findMaxSpHead(head,StepNum);
+
+ Disp_HeadItem dispItem;
+ m_dispDat.clear();//显示绘图用的数据(需要转换)
+
+ m_stitchIndex = 0;
+ m_dispIndex = 0;
+
+ // ds16数据
+ int size = ds16dat.size();
+ if (size <= (int)sizeof(DataDs16FileHead))
+ {
+ qDebug("16 data less then head size");
+ return -1;
+ }
+ DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data());
+ int datasize = size - sizeof(DataDs16FileHead);
+ if (datasize <= 0)
+ {
+ qDebug("dat dataBegin err");
+ return -1;
+ }
+ int stepsize = datasize/sizeof(Ds16Item);
+ if (stepsize <= 0)
+ {
+ qDebug("ds16 data size err");
+ return -1;
+ }
+
+ Ds16Item * ds16DataPtr;
+ Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead));
+ ds16DataPtr = pData;
+
+ // 图形显示区域
+ int width = m_canvas.width();//留4个像素的边
+ int height = m_canvas.height();//留4个像素的边
+ if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
+ {
+ qDebug("preview img too small");
+ return -1;
+ }
+
+ //留边(否则实时跟踪笔会画出界)
+ int viewSide = EMB_PREVIEW_SIDE;
+ if(m_drawMode == DRAW_PREVIEW)
+ {
+ viewSide = 20;//预览模式时整区域留20像素绘制(原色显示)
+ }
+ int dpminx = viewSide;
+ int dpmaxx = width - viewSide;
+ int dpminy = viewSide;
+ int dpmaxy = height - viewSide;
+
+ // 计算缩放系数
+ double factor, temp;
+ if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0)
+ {
+ return -1;
+ }
+
+ factor = (double)(fabs(m_maxX+(maxHSP*10)-m_minX)) / (dpmaxx - dpminx); // 按框尺寸x计算的缩放系数 五头机加上一个最大值保证绘图不越界
+ temp = (double)(fabs(m_maxY-m_minY)) / (dpmaxy - dpminy); // 按框尺寸y计算的缩放系数
+ // 使用较大的缩放系数
+ factor = temp >= factor?temp:factor;
+ m_factor = factor;
+
+ // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心)
+ int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX+(maxHSP*10))/factor)/2);//最大x需要 五头机加上一个最大值保证绘图不越界
+ int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2);
+
+ // 显示花样图形
+
+ double datposx = pDsHead->beginX;
+ double datposy = pDsHead->beginY;
+
+ int curx = (datposx) / factor + dpx;
+ int cury = (datposy) / factor + dpy;
+
+ if (EMB_SHOWDIRX == -1)
+ {
+ curx = width - curx;
+ }
+ if (EMB_SHOWDIRY == -1)
+ {
+ cury = height - cury;
+ }
+
+ for (int i = 0; i < stepsize; i++)
+ {
+ int prex = curx;
+ int prey = cury;
+
+ // 读入一个针步数据
+ int dx = ds16DataPtr->dx;
+ int dy = ds16DataPtr->dy;
+ unsigned short int headSpHndex = ds16DataPtr->action[1] & 0xFF;
+
+ datposx += dx;
+ datposy += dy;
+
+ curx = (datposx) / factor + dpx;
+ cury = (datposy) / factor + dpy;
+
+ if (EMB_SHOWDIRX == -1)
+ {
+ curx = width - curx;
+ }
+ if (EMB_SHOWDIRY == -1)
+ {
+ cury = height - cury;
+ }
+
+ dispItem.ctrl = ds16DataPtr->ctrl;
+ dispItem.attr = ds16DataPtr->attr;
+ dispItem.bx = prex;
+ dispItem.by = prey;
+ dispItem.ex = curx;
+ dispItem.ey = cury;
+ dispItem.ar = ds16DataPtr->dr;
+ memcpy(&dispItem.action,ds16DataPtr->action,2);
+ dispItem.headtable.iswork = head.headEnableSpacing[headSpHndex].iswork;
+ dispItem.headtable.distance1_2 = head.headEnableSpacing[headSpHndex].distance1_2;
+ dispItem.headtable.distance1_3 = head.headEnableSpacing[headSpHndex].distance1_3;
+ dispItem.headtable.distance1_4 = head.headEnableSpacing[headSpHndex].distance1_4;
+ dispItem.headtable.distance1_5 = head.headEnableSpacing[headSpHndex].distance1_5;
+ dispItem.headtable.distance1_6 = head.headEnableSpacing[headSpHndex].distance1_6;
+ dispItem.headtable.distance1_7 = head.headEnableSpacing[headSpHndex].distance1_7;
+ dispItem.headtable.distance1_8 = head.headEnableSpacing[headSpHndex].distance1_8;
+ if(ds16DataPtr->ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
+ dispItem.rgb = rgbColorYel;
+ else
+ dispItem.rgb = rgbColorGreen;
+
+ m_headDispDate.append(dispItem);
+
+ ds16DataPtr++;
+ }
+
+ qDebug("CreateDispFromEmbDs16, stepsize=%d", m_headDispDate.size());
+
+ return 0;
+}
+
+#define DRAWDR 0
+
+int EmbData::drawImageByDispFile()
+{
+ if(m_type == MACHINE_FIVEHEADPRECISIONSEWING)
+ return drawImageByOneStepLotLine();
+
+ int bx, by, ex, ey, ar;
+ bx = by = ex = ey = ar = 0;
+ int i;
+ u8 ctrlByte;
+ DispItem * pDispBuff = (DispItem *)m_dispDat.data();
+
+ int size = m_dispDat.size();
+ int stitchCount = size/sizeof(DispItem);
+
+ if (stitchCount <= 0)
+ {
+ stitchCount = 0;
+ }
+ if (m_stitchIndex >= stitchCount)
+ {
+ m_stitchIndex = stitchCount - 1;
+ }
+ if (m_stitchIndex < 0)
+ {
+ m_stitchIndex = 0;
+ }
+
+ DISP_MODE dispmode = m_dispMode;
+
+ QPainter painter(&m_canvas);
+
+ QRgb rgb;
+ QPen pen;
+
+ //笔宽
+ pen.setWidth(1);
+ rgb = 0;
+
+ if (dispmode == DISP_ALL_NORMAL || // 显示所有线迹(原色显示)
+ dispmode == DISP_ALL_EXEC || // 显示所有线迹(执行过的显示原色,其余显示灰色)
+ 0)
+ {
+ int tenThousand = 0;
+ for (i = 0; i < stitchCount; i++)
+ {
+ tenThousand++;
+ if(tenThousand == TENTHOUSANDNEEDLE)
+ {
+ tenThousand = 0;
+ int idx = i / TENTHOUSANDNEEDLE;
+ //每十万针主界面加载图片的进度条走一格
+ emit siDrawNeedleIdx(idx);
+ }
+
+ bx = pDispBuff[i].bx;
+ by = pDispBuff[i].by;
+ ex = pDispBuff[i].ex;
+ ey = pDispBuff[i].ey;
+ rgb = pDispBuff[i].rgb;
+ ctrlByte = pDispBuff[i].ctrl;
+
+ // 从开始到 m_stitchIndex 显示正常颜色的线迹(执行过),从 m_stitchIndex 结束显示未缝纫颜色线迹(未执行)
+ if ((dispmode == DISP_ALL_EXEC) && (i >= m_stitchIndex))
+ {
+ if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
+ rgb = rgbColorYel;
+ else
+ rgb = rgbColorGreen;
+ }
+
+ pen.setColor(rgb);
+ painter.setPen(pen);
+ painter.drawLine(bx, by, ex, ey);
+
+#if(DRAWDR)
+ double len = sqrt((double)(ex-bx)*(double)(ex-bx)+ (double)(ey-by)*(double)(ey-by));
+
+ int mx = len * cos((PI10000-ar)/10000.0);
+ int my = len * sin((PI10000-ar)/10000.0);
+ QColor color = QColor(Qt::green);
+ QPen pen;
+ pen.setColor(color);
+ painter.setPen(pen);
+ painter.drawLine(bx, by, bx+mx, by+my);
+ pen.setColor(QColor(Qt::red));
+ painter.setPen(pen);
+ painter.drawEllipse(bx+mx, by+my,2,2);
+#endif
+ }
+
+ if (dispmode == DISP_ALL_EXEC && m_stitchIndex < stitchCount)
+ {
+ i = m_stitchIndex;
+
+ bx = pDispBuff[i].bx;
+ by = pDispBuff[i].by;
+ drawFork(bx, by, painter);//绘制准星
+ m_dispIndex = m_stitchIndex; // 移动显示指针
+ }
+ }
+ else if (dispmode == DISP_EXECING) // 刷新部分线迹(缝纫中进度显示)
+ {
+ //qDebug()<<"m_stitchIndex"< m_dispIndex && m_stitchIndex < stitchCount)
+ {
+ i = m_dispIndex;
+
+ while(i < m_stitchIndex) // 显示为原线迹
+ {
+ bx = pDispBuff[i].bx;
+ by = pDispBuff[i].by;
+ ex = pDispBuff[i].ex;
+ ey = pDispBuff[i].ey;
+ rgb = pDispBuff[i].rgb;
+
+ pen.setColor(rgb);
+ painter.setPen(pen);
+ painter.drawLine(bx, by, ex, ey);
+ i++;
+ }
+ }
+ else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount)
+ {
+ i = m_stitchIndex;
+
+ while(i <= m_dispIndex) // 显示为未缝纫颜色线迹
+ {
+ bx = pDispBuff[i].bx;
+ by = pDispBuff[i].by;
+ ex = pDispBuff[i].ex;
+ ey = pDispBuff[i].ey;
+ rgb = pDispBuff[i].rgb;
+ ctrlByte = pDispBuff[i].ctrl;
+
+ if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
+ rgb = rgbColorYel;
+ else
+ rgb = rgbColorGreen;
+
+ pen.setColor(rgb);
+ painter.setPen(pen);
+ painter.drawLine(bx, by, ex, ey);
+ i++;
+ }
+ }
+
+ i = m_stitchIndex;
+
+ bx = pDispBuff[i].bx;
+ by = pDispBuff[i].by;
+ drawFork(bx, by, painter);//绘制跟踪笔
+ m_dispIndex = m_stitchIndex; // 移动显示指针
+ }
+ }
+ return 0;
+}
+
+#include
+using namespace std;
+/**
+ * @brief EmbData::drawImageByOneStepLotLine
+ * @return
+ * 五头机绘图函数 根据机头间距表信息单步画多条线
+ */
+int EmbData::drawImageByOneStepLotLine()
+{
+ int stitchCount = m_headDispDate.size();
+ //限制针步数 否则访问溢出
+ if (stitchCount <= 0)
+ {
+ stitchCount = 0;
+ }
+ if (m_stitchIndex >= stitchCount)
+ {
+ m_stitchIndex = stitchCount - 1;
+ }
+ if (m_stitchIndex < 0)
+ {
+ m_stitchIndex = 0;
+ }
+
+ QPainter painter(&m_canvas);
+ QRgb rgb;
+ QPen pen;
+
+ //笔宽
+ pen.setWidth(1);
+
+ if (m_dispMode == DISP_ALL_NORMAL || // 显示所有线迹(原色显示)
+ m_dispMode == DISP_ALL_EXEC || // 显示所有线迹(执行过的显示原色,其余显示灰色)
+ 0)
+ {
+ int tenThousand = 0;
+ for (int i = 0; i < stitchCount; i++)
+ {
+ tenThousand++;
+ if(tenThousand == TENTHOUSANDNEEDLE)
+ {
+ tenThousand = 0;
+ int idx = i / TENTHOUSANDNEEDLE;
+ //每十万针主界面加载图片的进度条走一格
+ emit siDrawNeedleIdx(idx);
+ }
+
+ // 从开始到 m_stitchIndex 显示正常颜色的线迹(执行过),从 m_stitchIndex 结束显示未缝纫颜色线迹(未执行)
+ rgb = m_headDispDate[i].rgb;
+
+ if ((m_dispMode == DISP_ALL_EXEC) && (i >= m_stitchIndex))
+ {
+ if(m_headDispDate[i].ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
+ rgb = rgbColorYel;
+ else
+ rgb = rgbColorGreen;
+ }
+
+ drawMultiLine(painter,pen,rgb,i);///多机头绘线
+ }
+
+ if (m_dispMode == DISP_ALL_EXEC && m_stitchIndex < stitchCount)
+ {
+ drawMultiTrack(painter);///绘制多机头的跟踪图案
+ m_dispIndex = m_stitchIndex; // 移动显示指针
+ }
+ }
+ else if (m_dispMode == DISP_EXECING) // 刷新部分线迹(缝纫中进度显示)前进回退的时候
+ {
+ //qDebug()<<"m_stitchIndex"< m_dispIndex && m_stitchIndex < stitchCount)
+ {
+ /// 从小针步增加到大针步
+ int i = m_dispIndex;
+
+ while(i < m_stitchIndex) // 显示为原线迹
+ {
+ if(m_headDispDate[i].ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
+ rgb = rgbColorYel;
+ else
+ rgb = rgbColorBlue;
+ drawMultiLine(painter,pen,rgb,i);///多机头绘线
+ i++;
+ }
+ }
+ else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount)
+ {
+ /// 从大针步减少到小针步
+ int i = m_stitchIndex;
+
+ while(i <= m_dispIndex) // 显示为未缝纫颜色线迹
+ {
+ rgb = m_headDispDate[i].rgb;
+ drawMultiLine(painter,pen,rgb,i);///多机头绘线
+ i++;
+ }
+ }
+
+ drawMultiTrack(painter);///绘制多机头的跟踪图案
+ m_dispIndex = m_stitchIndex; // 移动显示指针
+ }
+ }
+ return 0;
+}
+
+/**
+ * @brief EmbData::findMaxSpHead
+ * @param head 机头间距表
+ * @param StepNum 跨步数
+ * @return 返回机头间距表中用到的最大偏移值
+ */
+int EmbData::findMaxSpHead(DsrHeadEx62 &head,int StepNum)
+{
+ int max = 0;
+ for(int i = 0 ; i < StepNum;i++){
+ bitset<8> iswork(head.headEnableSpacing[i].iswork);
+ for(int j = 1; j < headNum; j++)
+ {
+ if(!iswork.test(j)) // test(i)为0返回false
+ continue;
+ unsigned short int* row = (unsigned short int*)&head.headEnableSpacing[i];
+ unsigned short int space = *(row + j); //向后偏移得到具体大小
+ max = max > space ? max : space;
+ }
+ }
+ return max;
+}
+
+///
+/// \brief 根据机头间距表的iswork字段 选择性的绘制跟踪画笔
+///
+void EmbData::drawMultiTrack(QPainter &painter)
+{
+ int bx = m_headDispDate[m_stitchIndex].bx;
+ int by = m_headDispDate[m_stitchIndex].by;
+ bitset<8> iswork(m_headDispDate[m_stitchIndex].headtable.iswork);
+
+ for(int j = 0; j < headNum; j++){
+ if(j==0)//第一个机头不需要偏移
+ drawFork(bx, by, painter, j, true);//绘制准星
+ else
+ {
+ unsigned short int* row = (unsigned short int*)&m_headDispDate[m_stitchIndex].headtable; // 取到结构体的初始地址
+ unsigned short int space = *(row + j); //向后偏移得到具体大小
+ space = (space*10)/m_factor; //从实际距离转换为像素,得到最终的偏移像素
+ drawFork(bx + space, by, painter, j, iswork.test(j));//绘制准星
+ }
+ }
+}
+
+///
+/// \brief 五头机函数,根据机头间距表信息多机头同时画线
+/// \param painter
+/// \param pen
+/// \param rgb
+/// \param index
+///
+void EmbData::drawMultiLine(QPainter &painter, QPen &pen, QRgb rgb, int index)
+{
+ int bx = m_headDispDate[index].bx;//begin
+ int by = m_headDispDate[index].by;
+ int ex = m_headDispDate[index].ex;//end
+ int ey = m_headDispDate[index].ey;
+
+ pen.setColor(rgb);
+ painter.setPen(pen);
+ bitset<8> iswork(m_headDispDate[index].headtable.iswork);
+
+
+ for(int j = 0; j < headNum; j++){
+ if(!iswork.test(j)) // test(i)为0,表示机头不工作,跳过循环
+ {
+ if(j == 0){//如果是一机头不工作,那么使用黄色线段画出
+ painter.save();
+ painter.setPen(rgbColorYel);
+ painter.drawLine(bx, by, ex, ey); //机头1 缝纫数据 和原数据一致
+ painter.restore();
+ }
+ continue;
+ }
+
+ //缝纫数据
+ if(m_headDispDate[index].ctrl ==DATA_SEWING)
+ {
+ if(j == 0){//机头1
+ painter.drawLine(bx, by, ex, ey); //机头1 缝纫数据 和原数据一致
+ }
+ else
+ {
+ unsigned short int* row = (unsigned short int*)&m_headDispDate[index].headtable; // 取到结构体的初始地址
+ unsigned short int space = *(row + j); //向后偏移得到具体大小
+ space = (space*10)/m_factor; //从实际距离转换为像素
+ painter.drawLine(bx+space, by, ex+space, ey); //不是机头1的画线时需要偏移
+ }
+ }
+ else{
+ painter.drawLine(bx, by, ex, ey);
+ }
+
+ }
+}
+
+
+
diff --git a/datafile/embdata.h b/datafile/embdata.h
new file mode 100644
index 0000000..c2c1a65
--- /dev/null
+++ b/datafile/embdata.h
@@ -0,0 +1,202 @@
+#ifndef EMBDATA_H
+#define EMBDATA_H
+
+#include
+#include
+#include
+#include