QuiltingHMI/datafile/datafiledst.cpp

935 lines
23 KiB
C++
Raw Permalink Normal View History

2024-02-06 07:10:48 +00:00
#include "datafiledst.h"
DataFileDst::DataFileDst()
{
}
DataFileDst::~DataFileDst()
{
}
void DataFileDst::clear()
{
m_fileFullPathName.clear(); // 文件路径
m_fileData.clear(); // 文件数据内容
m_embAbsData.clear(); // 转换后的数据
}
void DataFileDst::initFile(const QString &fullPathName)
{
clear();
QFileInfo file(fullPathName);
if (file.exists() && file.isFile())
{
m_fileFullPathName = fullPathName;
m_fileName = fullPathName;
qDebug()<<"m_fileFullPathName 1"<<m_fileFullPathName;
}
else
{
qDebug() << "Init file failed path =" << m_fileFullPathName;
}
}
void DataFileDst::loadFile()
{
QFile rdfile(m_fileFullPathName);
if(!rdfile.open(QIODevice::ReadOnly))
{
qDebug() << "open file fail when read, path =" << m_fileFullPathName;
return;
}
m_fileData = rdfile.readAll();
rdfile.close();
return;
}
void DataFileDst::saveFile()
{
QFile wrfile(m_fileFullPathName);
if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qDebug() << "open file fail when wirte, path =" << m_fileFullPathName;
return;
}
else
{
wrfile.write(m_fileData);
wrfile.close();
}
return;
}
// 文件所在目录
QString DataFileDst::getFileFullPath()
{
QFileInfo file(m_fileFullPathName);
return file.absoluteFilePath();
}
// 文件名称(包括扩展名)
QString DataFileDst::getFileFullName()
{
QFileInfo file(m_fileFullPathName);
return file.fileName();
}
// 文件名称(不包括扩展名)
QString DataFileDst::getFileName()
{
QFileInfo file(m_fileFullPathName);
return file.completeBaseName();
}
// 文件扩展名
QString DataFileDst::getFileSuffix()
{
QFileInfo file(m_fileFullPathName);
return file.suffix();
}
int DataFileDst::getStitchNums()
{
if(m_embAbsData.size() <= 0)
{
return 0;
}
DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data()));
return pDstHead->itemNums;
}
int DataFileDst::getDatWidth()
{
if(m_embAbsData.size() <= 0)
{
return 0;
}
DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data()));
return (pDstHead->maxX - pDstHead->minX);
}
int DataFileDst::getDatHeight()
{
if(m_embAbsData.size() <= 0)
{
return 0;
}
DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data()));
return (pDstHead->maxY - pDstHead->minY);
}
int DataFileDst::getMaxX()
{
if(m_embAbsData.size() <= 0)
{
return 0;
}
DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data()));
return pDstHead->maxX;
}
int DataFileDst::getMinX()
{
if(m_embAbsData.size() <= 0)
{
return 0;
}
DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data()));
return pDstHead->minX;
}
int DataFileDst::getMaxY()
{
if(m_embAbsData.size() <= 0)
{
return 0;
}
DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data()));
return pDstHead->maxY;
}
int DataFileDst::getMinY()
{
if(m_embAbsData.size() <= 0)
{
return 0;
}
DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data()));
return pDstHead->minY;
}
int DataFileDst::getBeginXYAndAnchorXY(int &beginX, int &beginY, int &anchorX, int &anchorY)
{
int size = m_fileData.size();
if (size <= (int)(sizeof(DstHead)))
{
return -1;
}
DstHead * pDstHead = (DstHead *)((m_fileData.data()));
beginX = pDstHead->startX;
beginY = pDstHead->startY;
anchorX = pDstHead->anchorX;
anchorY = pDstHead->anchorY;
return 0;
}
// 转换为绝对坐标数据,同时得到最大最小值
void DataFileDst::convertDataToAbs()
{
QByteArray ds4Data;//相对坐标
m_embAbsData.clear();
loadFile(); // 如果数据未读取,重新读取
int size = m_fileData.size();
if (size <= (int)(sizeof(DstHead)))
{
qDebug("dst size less then headsize");
return;
}
// int dstHeadSize = sizeof(DstHead);
// qDebug()<<"dstHeadSize"<<dstHeadSize;
size -= sizeof(DstHead);
int stepsize = size/sizeof(DstStep);
if (stepsize <= 0)
{
qDebug("dst data size err");
return;
}
DstHead * dstHead = (DstHead *)(m_fileData.data());
DstStep * dstDataBeg = (DstStep *)((m_fileData.data() + sizeof(DstHead)));
DstStep * dstDataPtr = dstDataBeg;
//qDebug()<<"Ds4Item begin";
// 绝对坐标数据
DataDs16FileHead dhead;
memset(&dhead, 0, sizeof(DataDs16FileHead));
Ds4Item * pData = new Ds4Item[stepsize];
if (pData == NULL)
{
qDebug("new DsAbsItem failed, size=%d", stepsize);
return;
}
Ds4Item ds4Item;
u8 ctrl, attr;
int dx, dy;
int rslt;
u32 jumpNeedleNum = 0;
//int predr,curdr;
//predr = curdr = 0.0;
// 得到最大最小值, 同时转换为相对坐标数据
int i = 0;
int stepidx = 0;
do
{
if (i < stepsize)
{
rslt = changeDstStep(dstDataPtr, ds4Item);//三字节针步转换
if (rslt >= 0)
{
ctrl = ds4Item.ctrl;
attr = ds4Item.attr;
if ( ctrl == DATA_SEWING ||
ctrl == DATA_OFFSET ||
0 )
{
if(ctrl == DATA_OFFSET)
{
jumpNeedleNum++;
}
dx = ds4Item.dx * DATAFACTOR;
dy = ds4Item.dy * DATAFACTOR;
if ((attr & 0x80) != 0)
{
dx *= -1;
}
if ((attr & 0x40) != 0)
{
dy *= -1;
}
}
memcpy(&(pData[stepidx]), &ds4Item, sizeof(Ds4Item));
stepidx++;
}
dstDataPtr++;
i++;
}
else
{
break;
}
}while(1);
//qDebug()<<"Ds4Item end";
//再将相对坐标转换为绝对坐标---开始
ds4Data.append((char *)pData, stepidx*sizeof(Ds4Item));//相对坐标字节数组
u32 fileID = 0;
fileID = calcCheckSum32((u8 *)(ds4Data.data()) , ds4Data.length()); // 原始数据累加校验和
QByteArray absItemAry;
absItemAry.clear();
DsAbsItem absItem;
memset(&absItem,0,sizeof(DsAbsItem));
u8 ctrlByte;
u8 attrByte;
int ddx, ddy;
m_maxX = S32_MIN;
m_maxY = S32_MIN;
m_minY = S32_MAX;
m_minX = S32_MAX;
Ds4Item * pDs4Data = (Ds4Item *)(ds4Data.data());
Ds4Item * ds4DataPtr = pDs4Data;
int begX = dstHead->startX;//起始点
int begY = dstHead->startY;
int begR = 0;
int anchorX = dstHead->anchorX;//定位点
int anchorY = dstHead->anchorY;
s32 ax = 0;//第一个点
s32 ay = 0;
s32 ar = 0;
Ds4Item * ds4DataTemp = (Ds4Item *)(ds4Data.data()); // ljs
int ds4StepSize = ds4Data.size()/sizeof(Ds4Item);
int runflag = 0;
int delStepNum = 0; // ljs
for (int i = 0; i < ds4StepSize; i++)
{
// 读入一个针步数据
ctrlByte = ds4DataPtr->ctrl;
attrByte = ds4DataPtr->attr;
ddx = ds4DataPtr->dx * DATAFACTOR;
ddy = ds4DataPtr->dy * DATAFACTOR;
if ((attrByte & 0x80) != 0)
{
ddx *= -1;
}
if ((attrByte & 0x40) != 0)
{
ddy *= -1;
}
ddx *= DST_EMB_DATADIRX;
ddy *= DST_EMB_DATADIRY;
ax += ddx;
ay += ddy;
//ar = atan2(ddy,ddx) * 10000;
double tar = atan2(ddy,ddx);
ar = (tar * 10000+0.5*(tar>0?1:-1));
if(ctrlByte == DATA_OFFSET)
{
if (runflag == 0)
{
runflag = 1;
}
runflag++;
}
else if(ctrlByte == DATA_SEWING)//第一针不转换为跳针
{
if ((runflag == 0 || runflag > 3) && (i > 0)) // 第一个运针是入针
{
ctrlByte = DATA_OFFSET;
runflag = 1;
}
//else if (i == 0 && ddx == 0 && ddy == 0) // 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs
else if (i == 0) // 20230511 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs
{
int count = 0;
do
{
ds4DataTemp++;
if (ds4DataTemp->ctrl == DATA_OFFSET)
{
count++;
if (ds4DataTemp->dx == 0 && ds4DataTemp->dy == 0) // 空跳,直接变成跳针
{
count += 2;
}
}
else
{
break;
}
}while(1);
if (count >= 3)
{
ctrlByte = DATA_OFFSET;
runflag = 2;
}
else
{
runflag = 1;
}
}
else
{
runflag = 1;
}
}
else if (ctrlByte == DATA_CHGND) // 换色
{
runflag = 10;
}
else
{
runflag = 0;
}
//中间数据
absItem.ctrl = ctrlByte;
absItem.attr = attrByte & ~(0x80|0x40);
absItem.ax = ax;
absItem.ay = ay;
absItem.ar = ar;
if (ax > m_maxX)
{
m_maxX = ax;
}
if (ax < m_minX)
{
m_minX = ax;
}
if (ay > m_maxY)
{
m_maxY = ay;
}
if (ay < m_minY)
{
m_minY = ay;
}
absItemAry.append((char*)&absItem,sizeof(DsAbsItem));
ds4DataPtr++;
}
//int newstepnum = ds4StepSize; // 转换后的数据长度
int newstepnum = ds4StepSize-delStepNum; // 转换后的数据长度 ljs
//qDebug()<<"DsAbsItem end";
//再将相对坐标转换为绝对坐标---结束
//qDebug()<<"dhead begin";
// 文件头转换
QString name = getFileFullName();
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(dhead.fileName, array, asize); // 文件名称
dhead.dataSize = newstepnum*sizeof(DsAbsItem); // 数据字节数
dhead.itemNums = newstepnum; // 数据项个数
dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数
dhead.bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小
dhead.dataChecksum = calcCheckSum32((u8 *)(absItemAry.data()) , dhead.dataSize); // 数据累加校验和
dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验6个字段分别为文件名称字节数项个数每项字节数每块字节数数据累加和的CRC校验值
dhead.fileid = fileID;
//qDebug()<<"dhead 1";
dhead.anchorX = anchorX; // 定位点坐标X
dhead.anchorY = anchorY; // 定位点坐标Y
dhead.beginX = begX; // 数据起点坐标X
dhead.beginY = begY; // 数据起点坐标Y
dhead.beginR = begR; // 数据起点坐标R
dhead.minX = m_minX-m_minX;
dhead.maxX = m_maxX-m_minX;
dhead.minY = m_minY-m_minY;
dhead.maxY = m_maxY-m_minY; // 轮廓范围,使用重新计算之后的值
//qDebug()<<"m_maxX"<<m_maxX<<"m_minX"<<m_minX;
//qDebug()<<"m_maxY"<<m_maxY<<"m_minY"<<m_minY;
//qDebug()<<"dhead 3";
// 保存文件头到数组中
m_embAbsData.append((char *)(&dhead), sizeof(DataDs16FileHead));
//qDebug()<<"dhead 4";
// 保存数据到数组中
//qDebug()<<"newstepnum"<<newstepnum;
//qDebug()<<"ds4StepSize"<<ds4StepSize;
m_embAbsData.append(absItemAry);
delete []pData;
//qDebug()<<"dhead end";
return;
}
void DataFileDst::writePointToFile(int x, int y, int flag)
{
if(m_fileData.size() <= 0)
{
return;
}
DstHead * pDstHead = (DstHead *)((m_fileData.data()));
if(flag == 0)
{
pDstHead->startX = x;
pDstHead->startY = y;
}
else
{
pDstHead->anchorX = x;
pDstHead->anchorY = y;
}
QFile wfile(m_fileFullPathName);
if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qDebug() << "open file fail when read, path =" << m_fileFullPathName;
return;
}
wfile.write(m_fileData);
wfile.close();
}
void DataFileDst::writePatternParaToFile(DstHead *head)
{
if(m_fileData.size() <= 0)
{
return;
}
memcpy(m_fileData.data(),(char*)head,sizeof(DstHead));
QFile wfile(m_fileFullPathName);
if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qDebug() << "open file fail when read, path =" << m_fileFullPathName;
return;
}
wfile.write(m_fileData);
wfile.close();
}
int DataFileDst::checkDstFile()
{
loadFile(); // 如果数据未读取,重新读取
int size = m_fileData.size();
if (size <= (int)(sizeof(DstHead)))
{
qDebug("dsr size less then headsize");
return -1;
}
size -= sizeof(DstHead);
int stepsize = size/sizeof(DstStep);
if (stepsize <= 0)
{
qDebug("dst data size err");
return -1;
}
if (stepsize > PATTERN_LARGE_NEEDLES)//128万针
{
qDebug("dsr data size big");
return -2;
}
return stepsize;
}
DstHead *DataFileDst::getDstHead()
{
if(m_fileData.size() <= 0)
{
loadFile(); // 如果数据未读取,重新读取
}
DstHead *head = NULL;
int size = m_fileData.size();
if (size <= (int)(sizeof(DstHead)))
{
return head;
}
head = (DstHead *)((m_fileData.data()));
return head;
}
void DataFileDst::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;
}
}
//-----------------------------------------------------------------------
// 生成预览文件
int DataFileDst::createPreviewImage(QImage * pImg, int saveflag, int penwidth, int reDraw)
{
#if(1)
if(reDraw == 0)//图片存在则不重画
{
// 图片是否存在,存在则返回
QString previewPath = getFileFullPathName() + ".preview.png";
QFile imageFile(previewPath);
if (imageFile.exists())
{
return 0;
}
}
#endif
int newimgflag = 0;
QImage * pImage;
int width, height;
if (pImg == NULL)
{
width = DST_PREVIEW_WIDTH;
height = DST_PREVIEW_HEIGHT;
pImage = new QImage(width, height, IMAGE_TYPE);
newimgflag = 1;
}
else
{
pImage = pImg;
}
width = pImage->width();
height = pImage->height();
if (width <= DST_PREVIEW_SIDE*2 || height <= DST_PREVIEW_SIDE*2)
{
if (pImage != NULL && newimgflag == 1)
{
delete pImage;
}
qDebug("preview img too small");
return -1;
}
memset(pImage->bits(), 0x00, pImage->byteCount());
QPainter painter(pImage);
QColor backcolor(255, 255, 255, 0); // 透明背景
// 背景
QPen pen;
pen.setWidth(penwidth);
pen.setColor(backcolor);
painter.setPen(pen);
painter.setBrush(backcolor);
painter.drawRect(0, 0, width, height);
// 图形
//qDebug()<<"convertDataToAbs defore";
convertDataToAbs(); // 转换为绝对坐标数据
//qDebug()<<"convertDataToAbs end";
// absdat数据
int size = m_embAbsData.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("2 data less then head size");
return -1;
}
DataDs16FileHead * pAbsHead = (DataDs16FileHead *)(m_embAbsData.data());
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;
//--------
// 图形显示区域
int dpminx = DST_PREVIEW_SIDE;
int dpmaxx = width - DST_PREVIEW_SIDE;
int dpminy = DST_PREVIEW_SIDE;
int dpmaxy = height - DST_PREVIEW_SIDE;
// 计算缩放系数
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); // 按x计算的缩放系数
if (temp >= factor) // 使用较大的缩放系数
{
factor = temp;
}
// 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心)
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;
int dx;
int dy;
double datposx, datposy;
int curx, cury, prex, prey;
datposx = pAbsHead->beginX;
datposy = pAbsHead->beginY;
curx = (datposx) / factor + dpx;
cury = (datposy) / factor + dpy;
if (DST_SHOWDIRX == -1)
{
curx = (width)-curx;
}
if (DST_SHOWDIRY == -1)
{
cury = (height)-cury;
}
absDataPtr = pData;
QColor embcolor = QColor(Qt::green);
pen.setColor(embcolor);
painter.setPen(pen);
for (int i = 0; i < stepsize; i++)
{
// 读入一个针步数据
ctrlByte = absDataPtr->ctrl;
if ( ctrlByte == DATA_SEWING ||
0 )
{
prex = curx;
prey = cury;
dx = absDataPtr->ax;
dy = absDataPtr->ay;
datposx = dx;
datposy = dy;
curx = (datposx) / factor + dpx;
cury = (datposy) / factor + dpy;
if (DST_SHOWDIRX == -1)
{
curx = (width)-curx;
}
if (DST_SHOWDIRY == -1)
{
cury = (height)-cury;
}
if(i != 0)
{
painter.drawLine(prex, prey, curx, cury);
}
}
//如果连续两步都是跳针,则过滤掉
else if (ctrlByte == DATA_OFFSET)
{
DsAbsItem * JumpAbsDataPtr = pData;
JumpAbsDataPtr = absDataPtr - 1;
u8 beforectrlByte = JumpAbsDataPtr->ctrl;
JumpAbsDataPtr = absDataPtr + 2;
u8 nextctrlByte = JumpAbsDataPtr->ctrl;
prex = curx;
prey = cury;
dx = absDataPtr->ax;
dy = absDataPtr->ay;
datposx = dx;
datposy = dy;
curx = (datposx) / factor + dpx;
cury = (datposy) / factor + dpy;
if (DST_SHOWDIRX == -1)
{
curx = (width)-curx;
}
if (DST_SHOWDIRY == -1)
{
cury = (height)-cury;
}
pen.setColor(embcolor);
painter.setPen(pen);
if(beforectrlByte == DATA_OFFSET || nextctrlByte == DATA_OFFSET)
{
//该针上下两针都是跳针则不画线
}
else
{
if(i != 0)
{
painter.drawLine(prex, prey, curx, cury);
}
}
}
absDataPtr++;
}
// 保存成文件
QString preview = getFileFullPathName();
if (saveflag != 0 && preview.isEmpty() == false)
{
#if (1)
preview += ".preview.png";
pImage->save(preview, "png");
#endif
}
if (pImage != NULL && newimgflag == 1)
{
delete pImage;
}
return 0;
}
#define EMB_DST_DAT_DIRX (-1) // X向DST数据坐标和绝对数据坐标的差异
#define EMB_DST_DAT_DIRY (1) // Y向DST数据坐标和绝对数据坐标的差异
// 针步转换
int DataFileDst::changeDstStep(DstStep * pDststep, Ds4Item & ds4step)
{
int dx, dy;
u8 c1, c2, c3;
u8 ctrl, attr;
if (pDststep == NULL)
{
return -1;
}
c1 = pDststep->c1;
c2 = pDststep->c2;
c3 = pDststep->c3;
dx = 0;
dy = 0;
if ((c1&0x08) != 0) { dx -= 9; }
if ((c1&0x04) != 0) { dx += 9; }
if ((c1&0x02) != 0) { dx -= 1; }
if ((c1&0x01) != 0) { dx += 1; }
if ((c2&0x08) != 0) { dx -= 27; }
if ((c2&0x04) != 0) { dx += 27; }
if ((c2&0x02) != 0) { dx -= 3; }
if ((c2&0x01) != 0) { dx += 3; }
if ((c3&0x08) != 0) { dx -= 81; }
if ((c3&0x04) != 0) { dx += 81; }
if ((c1&0x10) != 0) { dy -= 9; }
if ((c1&0x20) != 0) { dy += 9; }
if ((c1&0x40) != 0) { dy -= 1; }
if ((c1&0x80) != 0) { dy += 1; }
if ((c2&0x10) != 0) { dy -= 27; }
if ((c2&0x20) != 0) { dy += 27; }
if ((c2&0x40) != 0) { dy -= 3; }
if ((c2&0x80) != 0) { dy += 3; }
if ((c3&0x10) != 0) { dy -= 81; }
if ((c3&0x20) != 0) { dy += 81; }
if (c3 == 0xF3 && dx == 0 && dy == 0)
{
ctrl = DATA_END; // 结束
}
else if ((c3&0xc3) == 0x03) // 运针
{
ctrl = DATA_SEWING;
}
else if ((c3&0xc3) == 0x83) // 偏移
{
ctrl = DATA_OFFSET;
}
else if ((c3&0xc3) == 0xC3) // 换色
{
ctrl = DATA_CHGND;
}
else if ((c3&0xc3) == 0x43) // 开关亮片码
{
qDebug("Sequin switch, not support, c1=0x%x, c2=0x%x, c3=0x%x", c1, c2, c3); // 不合法的DST
return -2;
}
else
{
qDebug("not know dst step, c1=0x%x, c2=0x%x, c3=0x%x", c1, c2, c3); // 不合法的DST
return -3;
}
// 添加针步
attr = 0;
dx *= EMB_DST_DAT_DIRX; // X向显示坐标和数据坐标的差异
dy *= EMB_DST_DAT_DIRY; // Y向显示坐标和数据坐标的差异
if (dx < 0) { attr |= 0x80; }
if (dy < 0) { attr |= 0x40; }
ds4step.ctrl = ctrl;
ds4step.attr = attr;
ds4step.dx = abs(dx);
ds4step.dy = abs(dy);
return 0;
}