Quilting-lw/datafile/embdata.h

318 lines
15 KiB
C
Raw Normal View History

2026-01-23 08:37:18 +00:00
#ifndef EMBDATA_H
#define EMBDATA_H
#include <QList>
#include <QByteArray>
#include <QApplication>
#include <QDir>
#include <QImage>
#include <qmath.h>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QPainter>
#include <QTextCodec>
#include <QRgb>
#include <QObject>
#include "machine/comm/datadef.h"
#include "machine/comm/crc16.h"
#include <QVector>
#include "datafile/datafiledsr.h"
#define ZERO 1e-6
#define MAX_EMB_STEP 121//四字节针步最大针步限制
#define DEFAULT_JUMP 70//默认针步大小
#define SEW_NEEDLE_NUM 2 //缝纫2个针杆
#define COLORTABLE_NUM 512//色序表
#define EMB_PREVIEW_SIDE (32) // 留边大小
#define TENTHOUSANDNEEDLE 100000
//#define EMB_SHOWDIRX (1) // X向显示坐标和数据坐标的差异
//#define EMB_SHOWDIRY (1) // Y向显示坐标和数据坐标的差异
#define OUTLINESTEPFACTOR 100 // 生成轮廓花样针步乘以的系数单位是0.01所以乘以100
#define PI10000 31416 //180度
#define PI20000 62832
#define ANGLECORR 10466 //60度对应的弧度值
#define MODE_THICKEN 0 //密针方式
#define MODE_LOCK 1 //锁针方式
#define NEEDLENONE 0 //无针
#define NEEDLELEFT 1 //左针
#define NEEDLERIGHT 2 //右针
#define NEEDLEDOUBLE 3 //双针
#define NEEDLENOTSET 4 //未设置
#define LAYOUTNEEDLENUM 24
typedef union
{
u8 buf8[4];
u32 buf32;
} U32ToU8;
enum MirrorType {
HorizontalMirror = 1, // 1: 水平镜像
VerticalMirror, // 2: 垂直镜像
BothMirror // 3: 水平和垂直镜像
};
class EmbData: public QObject
{
Q_OBJECT
public:
EmbData();
~EmbData();
public:
void clear();
QByteArray & getDsDat();//得到转换后的ds16数据
QByteArray getDispDat(double showWidth,double showHeight);//得到转换后的绘图数据
inline DataDs16FileHead * getDsDatHead(){return m_pEmbDs16Head;}//得到转换后的ds16数据的文件头
void setDsDatHeadFileID(u32 fileid);//设置数据区文件头的fileid
void getAbsDatRangeXY();//得到绝对坐标的maxXY和minXY
void appendAEmbAbsFile(QString filePath,QByteArray array,int mirror = 0);//附加一个绝对坐标的花样文件
int addLockStitchs(u8 mode, u8 needles, u8 num);
QByteArray lockReinforce(u8 needles, u8 num, DsAbsItem * absDataPtr, int datasize);//锁针加固方式
QByteArray thickenReinforce(u8 needles, u8 num, DsAbsItem * absDataPtr, int datasize);//密针加固方式
void addResew(QByteArray& data, DsAbsItem * ptr, u8 ctrl ,bool resewFlag = true);//加回针或者锁针
void evenNumberAddLock(QByteArray& data, DsAbsItem * absDataPtr,int lockNeedles, int num);//偶数次添加锁针加固
void oddNumberAddLock(QByteArray& data, DsAbsItem * absDataPtr,int lockNeedles, int num);//奇数次添加锁针加固
int angleCorrection(s16 oft);//角度修正
int angleCorrectionXY(s32 px, s32 nx, s32 py, s32 ny);//角度修正
void reFitByStep(s32 stepLen);//按固定针步重新拟合(用户可设置的参数,暂未用到)
void reFitLine(s32 stepLen);//按固定针步重新拟合直线(用户可设置的参数)
void reFitLineDoubleHead(s32 stepLen);//按固定针步重新拟合直线(用户可设置的参数),双头组合机型
int moveStartPoint(short left, short front);//移动起始点,左边,前边
QByteArray & lolaComp(s16 valuePos, s16 valueNeg, s16 valueZero);//罗拉补偿
void setLastStepAngle();//设置最后一个针步的角度
public:
inline QString getFileName(){return m_pEmbDs16Head->fileName;}//得到花版名称
inline QString getFilePath(){return m_filePath;}//得到花版路径
inline u32 getStitchNums(){return m_pEmbDs16Head->itemNums;}//得到数据的针数
inline int getDatWidth(){return m_pEmbDs16Head->maxX - m_pEmbDs16Head->minX;}//得到数据的图形宽度
inline int getDatHeight(){return m_pEmbDs16Head->maxY - m_pEmbDs16Head->minY;}//得到数据的图形高度
inline s32 getMaxX(){return m_pEmbDs16Head->maxX;}//得到数据最大X+
inline s32 getMinX(){return m_pEmbDs16Head->minX;}//得到数据最小X-
inline s32 getMaxY(){return m_pEmbDs16Head->maxY;}//得到数据最大Y+
inline s32 getMinY(){return m_pEmbDs16Head->minY;}//得到数据最小Y-
inline s32 getBeginX(){if(m_pEmbDs16Head == NULL){return 0;} return m_pEmbDs16Head->beginX;}
inline s32 getBeginX2(){if(m_pEmbDs16Head == NULL){return 0;} return m_pEmbDs16Head->beginX2;}
inline s32 getBeginY(){if(m_pEmbDs16Head == NULL){return 0;} return m_pEmbDs16Head->beginY;}
inline s32 getBeginY2(){if(m_pEmbDs16Head == NULL){return 0;} return m_pEmbDs16Head->beginY2;}
inline s32 getAnchorX(){return m_pEmbDs16Head->anchorX;}//得到数据定位点
inline s32 getAnchorY(){return m_pEmbDs16Head->anchorY;}//得到数据定位点
inline void setSplitLen(u16 len){m_splitLen = len;}//分割数据长度
// inline int setSplitLen(u16 len){return len;}//分割数据长度
inline void setOftNeedleSize(s32 len){m_oftNeedleSize = len;}//双头组合机型去除偏移针步的针步大小
public:
void moveDataBeginPonit(s32 left, s32 front);
void setAbsDat(QByteArray & dat);
QByteArray & getAbsDat(void);
int getPosInfoFromNeedleIdx(int stitchIdx, int & posx, int & posy, int & colorIdx, int & dr, int & ar, int & dxV, int & dyV);
void setStartPosition(int x, int y);//设置起始点
void setStartPositionDoubleHead(int left,int front);//计算并设置起始点-双头组合机型
void setStartPositionFromLeftFront(int left,int front);//根据左边前边计算并设置起始点
void reCreatDispDat();//重新计算范围并生成绘制数据
void setAnchorPosition(int x, int y);//设置定位点
public:
double getAngle(double x1, double y1, double x2, double y2);
int setDatSizeChange(int dsx, int dsy);//设置尺寸变化(缩放)
int setMirror(MirrorType mirror);//设置镜像
int splittingArc(double posX1, double posY1,double posX2, double posY2,double xc, double yc, double rc,double dr1,double dr2,int step,QByteArray &cutData, DsAbsItem item);// 分割圆弧
int splittingLine(double posX1, double posY1,double posX2, double posY2,int stepMin, int stepMax,QByteArray &cutData, DsAbsItem item); // 分割直线
// 偏心刀平板切割机补偿算法
int setCutcontrastData(); // 增加对比数据
int setCutCornerStep(); // 增加拐点数据
int setCutEccentricCompensation(); // 偏心刀刀尖补偿
int setCutAddCutterComption(); // 增加两端补偿
int setCutRotaryCutterData(); // 增加转刀数据
int setCutDecCornerStep(); // 删除拐点数据
int setCutFitSplitStep(); // 分割切刀数据
int setCutFitStepData(); // 拟合切刀数据
// 飞行切割平板切割机补偿算法
int setCut2CornerStep(); // 增加拐点数据
int setCut2ModifyDataDir(); // 修改数据方向
int setCut2FitSplitStep(); // 分割切刀数据
int setCut2JudgInterval(); // 判断区间
int setCut2AddCutterComption(); // 增加圆刀数据两端补偿
int setCut2AddCutterComption2(); // 增加圆刀数据两端补偿 yct
int setCut2SortNewData(); // 排序&组成新数据
int setCut2AddOffsetData(); // 增加偏移数据
int setCut2CalMaxSpd(); // 计算最大行进速度
void recalculateAngles(); //重新计算角度
//计算角度ar
s32 calculateAngles(double curX, double curY, double lastX, double lastY); //计算绝对角度ar
//切割结尾补偿 移动结尾点
void cutDataEndCompensate(DsAbsItem &curItem,DsAbsItem &preItem,double comDistance);
//切割结尾小横切
void cutDataVertCut(DsAbsItem &curItem,double comDistance, QByteArray & cutAbsData,int &newstepnum);
//切割开头的补偿 移动起始点
void cutDataStartCompensate(DsAbsItem &curItem,DsAbsItem &preItem, DsAbsItem &nextItem, double comDistance);
bool isCutCtrl(u8 &ctrl);
void optimizationOrder(QVector<QVector<QByteArray> > &visited, DsAbsItem &absItem,int winNum,u8 ctrl);//数据优化顺序
u32 CalcDisplacement(u32 pps1, u32 pps2, u32 calcTime);
s16 Rot001ToPitk(s32 ang001);
int setCutMoveParameters(); // 计算切刀移动参数
int setRotate(int dr);//设置旋转
int setRotate90(bool flag);//旋转+-90度 flag :true代表顺时针方向
int getNextElementIndex(int curIndex);//获得下一个图元的第一缝纫针步
int getPreOrThisElementIndex(int curIndex);//上一个图元(当前为跨步时)或当前图元(当前为缝纫时)的第一缝纫针步
int createEmbDs16FromAbs();//生成DS16数据
int createEmbDs16FromAbsDoubleHeadComb();//双头组合机型生成ds16数据
void calRange();//计算边界范围
private:
void splitBorderStitchAndAdd(QByteArray & dat,int bx,int by,int ex,int ey);//分割边框针步并添加
//此函数转换传入的绝对坐标值,是否取镜像及反复时数据之间的间距
void convertAbsDat(QByteArray & dat,int mirror = 0);
int calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, DsAbsItem item);
int reCalcDataChecksum();//重新计算文件CRC
void drawNeedleIdxPen(int x, int y, QPainter &painter);//绘制针数索引的跟踪笔
void drawFork(int x, int y, QPainter &painter);//绘制针数索引的十字
void drawFork(int x, int y, QPainter &painter,int index);//绘制针数索引的十字
void drawForkDoubleHead(int x, int y, int x2, int y2, QPainter &painter);//绘制针数索引的十字(双头组合机型)
void eraseNeedleIdxPen(QPainter &painter);//擦除针数索引的跟踪笔
void eraseNeedleIdxPen(QPainter &painter,int index);//擦除针数索引的跟踪笔
void eraseNeedleIdxPenDoubleHead(QPainter &painter);//擦除针数索引的跟踪笔
bool isFlipDispYMac();//判断是否是Y轴旋转的类型显示数据
bool isFlipDispXMac();//判断是否是X轴旋转的类型显示数据
private:
void getCurvePointFillLine(QList<DsAbsItem> &inList, double indRunLen,QList<DsAbsItem> &outList);
int getTotalDistanceFillLine(QList<DsAbsItem> *pPointList, double &dTotal);
bool getPointInSectFillLine(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp);
//距p1点距离为d的点
// d > s : out_p在p2延长线上
// s >= d >= 0 : out_p在p1、p2线段上
// d < 0 : out_p在p1延长线上
bool getPointAtSect(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp);
bool checkData(int size);
public:
int m_editedflag;//数据被编辑的标志
int m_spaceX;//横向间隙
int m_spaceY;//纵向移动距离
int m_endPosX;//花样最后点坐标
int m_endPosY;//花样最后点坐标
//用于调节颜色
#if(1)
QString m_selfilename;
#endif
double m_minX;
double m_maxX;
double m_minY;
double m_maxY;
private:
QByteArray m_embAbsData; // 转换后的绝对坐标数据
QByteArray m_embDs16Data;//发给下位机的ds16数据需要转换
QByteArray m_oneDispDat; //飞梭机单个绘制数据
int m_totalJumpNeedle;//总跳针数
DataDs16FileHead * m_pEmbDs16Head;//ds16 文件头 //数据转换用的都是DataDs16FileHead
double m_factor;//绘制数据与实际数据的缩放率
u32 m_fileid;
u16 m_splitLen;
s32 m_oftNeedleSize;//双头组合机型去除偏移针步的针步大小
s32 m_ritStepSize;//拟合针步大小
//图形预览、刷新
public:
//显示所有线迹(原色显示)
//显示所有线迹(有效区域内的显示原色,其余显示灰色)
//显示所有线迹(执行过的显示原色,其余显示灰色)
//刷新部分线迹(缝纫中进度显示)
enum DISP_MODE {DISP_ALL_NORMAL = 0, DISP_ALL_AREA, DISP_ALL_EXEC, DISP_EXECING};
enum DRAW_MODE {DRAW_VIEW = 0, DRAW_PREVIEW};//绘制模式(非预览模式、预览模式)
public:
int setViewInfo(int width, int height);//设置视图尺寸(透明背景)
void setViewInfo(QPixmap pix);//设置视图(带背景图片背景)
void setEmbData(int type,int redraw = 0);//重置数据
//是否重绘 //是否为渐变
void setDispMode(DISP_MODE dispmode = DISP_ALL_NORMAL, int redraw = 0);//设置预览模式
void setDrawMode(DRAW_MODE drawmode = DRAW_VIEW);//设置绘制模式
void setExecIndex(int index);//设置进度显示数据
void reDraw();//重新绘图
public:
inline QPixmap& getPreviewImage(){return m_canvas;}//返回预览图片
private:
int createDispFromEmbDs16Dat(QByteArray & ds16dat);//创建显示用的数据(为了快速显示)
int createDispFromEmbDs16DatForHeadInfo(QByteArray & ds16dat);
int createDispFromEmbDs16DatDoubleHeadComb(QByteArray & ds16dat);//双头组合机型创建绘制数据
int drawImageByDispFile();//用显示数据画图(是否渐变显示)
int drawImageByOneStepLotLine();
int drawImageByDispFileDoubleHeadComb();//双头组合机型绘制预览图
int findMaxSpHead(DsrHeadEx62 & head,int headCount);
void drawMultiTrack(QPainter &painter); //绘制多机头的跟踪图案
void drawMultiLine(QPainter &painter, QPen &pen, QRgb rgb, int index); //绘制多机头的线迹
public:
void getOneDispDat(QByteArray &ds16dat); //得到一个绘制数据
void resetLayoutDispDat(unsigned char *arrayNeedle1,unsigned char *arrayNeedle2,unsigned char *arrayNeedle3,int leftRightNeedleSpace,int needlesSpace,int needleLayoutSpace12,int needleLayoutSpace23,int reDat = 0);
int createDispFromEmbDs16DatForFlyShuttle(int initFlag = 0);//飞梭机绘制数据
static bool checkFirstEndNeedle(QByteArray ary);//确认起终点的x值是否一致
QByteArray rotationAngleAdjustment(int flag);//根据flag对数据进行旋转角度调整
private:
int m_type; //机型
int m_penX, m_penY;//执行过程中绘制跟踪笔的坐标索引
QPoint m_penXY2;
QPixmap m_canvas;//预览图片
QPixmap m_penPix;//跟踪笔绘制的临时区域
QPixmap m_penPix2;//跟踪笔绘制的临时区域
QVector<QPixmap> m_penHeadPix;
QVector<QPoint> m_penPoint;
int m_viewWidth;
int m_viewHight;
QString m_filePath;//文件路径
private:
QByteArray m_dispDat;//绘制图形的绝对数据(进行缩放的)
QByteArray m_dispDatFront;//飞梭机前排数据
QByteArray m_dispDatMiddle;//飞梭机中排数据
QByteArray m_dispDatBehind;//飞梭机后排数据
double m_dispMinX;
double m_dispMaxX;
double m_dispMinY;
double m_dispMaxY;
QVector<Disp_HeadItem> m_headDispDate; //五头机绘图针步
int m_stitchIndex; //进度步数
int m_dispIndex; //当前index
DISP_MODE m_dispMode;
DRAW_MODE m_drawMode;
signals:
void siDrawNeedleIdx(int idx);
};
#endif // EMBDATA_H