PunchHMI/datafile/embdata.cpp
2024-02-06 14:58:57 +08:00

2877 lines
78 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "embdata.h"
EmbData::EmbData()
{
m_pDs16Head = new DataDs16FileHead();
m_tabelColorNum = 0;
m_pColor = NULL;
memset(m_needleColorTable,0,sizeof(m_needleColorTable));
clear();
}
EmbData::~EmbData()
{
clear();
if(m_pDs16Head != NULL)
{
delete m_pDs16Head;
}
}
void EmbData::clear()
{
m_maxX = 0;
m_minX = 0;
m_maxY = 0;
m_minY = 0;
m_greyColorBeg = 0;
m_greyColorEnd = 0;
m_spaceX = 0;
m_spaceY = 0;
m_factor = 0;
m_penX = 0;
m_penY = 0;
m_stitchSplitLength = 0;
m_dataAbsList.clear();
m_ds16Data.clear();
m_editedflag = 0;
m_filePath.clear();
memset(m_pDs16Head,0,sizeof(DataDs16FileHead));
}
void EmbData::setNeedleColorTable(int colorIdx, int colorvalue)
{
if(colorIdx > TOTAL_NEEDLE_NUM - 1)
{
return;
}
m_needleColorTable[colorIdx] = colorvalue;
}
void EmbData::initColor(int cnum, QRgb *pColor)
{
m_tabelColorNum = cnum;
m_pColor = pColor;
}
QByteArray & EmbData::getDsDat()
{
//qDebug()<<"m_editedflag"<<m_editedflag;
if(m_editedflag != 0)
{
createDs16FromAbs();
}
return m_ds16Data;
}
//设置数据区文件头的fileid 计算完以后的fileid再设置进来
void EmbData::setDsDatHeadFileID(u32 fileid)
{
if(m_pDs16Head != NULL)
{
m_pDs16Head->fileid = fileid;
if((u32)m_ds16Data.size() > sizeof(DataDs16FileHead))
{
memcpy(m_ds16Data.data(),(char*)m_pDs16Head, sizeof(DataDs16FileHead));
}
}
}
// 添加锁针针步
int EmbData::addLockStitchs(int locktimes, int locksteps, int lockstepsize)
{
if (locktimes <= 0 || locksteps <= 0 || lockstepsize <= 0)
{
return -1;
}
int size = m_absData.size();
if (size <= 0)
{
return -1;
}
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_absData.data());
DsAbsItem * pData = (DsAbsItem *)(m_absData.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_CHGND)
{
runflag = 10;
}
else if (absDataPtr->ctrl == DATA_JUMP)
{
runflag++;
}
else if (absDataPtr->ctrl == DATA_EMB || absDataPtr->ctrl == DATA_SEWING)
{
if ((runflag == 0 || runflag > 3))
{
// 添加锁针
int findnext = 0;
if (j > 0)
{
DsAbsItem * prePtr = absDataPtr-1; // 上一个点
if (prePtr->ctrl != DATA_EMB)
{
double dx = absDataPtr->ax - prePtr->ax;
double dy = absDataPtr->ay - prePtr->ay;
double len = sqrt(dx*dx + dy*dy);
if (len <= 0)
{
findnext = 1;
}
else
{
int thislocktimes = locktimes;
int thislocksteps = locksteps;
int thislockstepsize = lockstepsize;
while (thislockstepsize * thislocksteps > len)
{
thislocksteps--;
}
if (thislocksteps == 0)
{
thislocktimes = 1;
thislocksteps = 1;
thislockstepsize = len;
}
DsAbsItem nitem;
memset(&nitem,0,sizeof(DsAbsItem));
u8 ctrl = absDataPtr->ctrl;
u8 attr = 0; // absDataPtr->attr;
double axbase = prePtr->ax;
double aybase = prePtr->ay;
double arbase = absDataPtr->ar;
double adx = thislockstepsize * dx / len;
double ady = thislockstepsize * dy / len;
int addfst = 1;
int addlast = 1;
thislocktimes= (thislocktimes+1) / 2;
for (int k = 0; k < thislocktimes; k++)
{
if (k == thislocktimes-1)
{
addlast = 0;
}
for (int s = addfst; s <= thislocksteps; s++)
{
nitem.ctrl = ctrl;
nitem.attr = attr;
nitem.ax = axbase + adx*s;
nitem.ay = aybase + ady*s;
nitem.ar = arbase;
tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
}
for (int s = thislocksteps-1; s >= addlast; s--)
{
nitem.ctrl = ctrl;
nitem.attr = attr;
nitem.ax = axbase + adx*s;
nitem.ay = aybase + ady*s;
nitem.ar = arbase;
tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
}
addfst = 0;
}
}
}
}
else
{
findnext = 1;
}
if (findnext != 0)
{
int nst = 1;
do
{
if (j+nst < stepsize)
{
DsAbsItem * nextPtr = absDataPtr+nst; // 下一个点
if (nextPtr->ctrl == DATA_EMB)
{
int thislocktimes = locktimes;
int thislocksteps = locksteps;
int thislockstepsize = lockstepsize;
DsAbsItem nitem;
memset(&nitem,0,sizeof(DsAbsItem));
double dx = nextPtr->ax - absDataPtr->ax;
double dy = nextPtr->ay - absDataPtr->ay;
double len = sqrt(dx*dx + dy*dy);
if (len <= 0)
{
nst++;
continue;
}
while (thislockstepsize * thislocksteps > len)
{
thislocksteps--;
}
if (thislocksteps == 0)
{
thislocktimes = 1;
thislocksteps = 1;
thislockstepsize = len;
}
u8 ctrl = absDataPtr->ctrl;
u8 attr = 0; // absDataPtr->attr;
double axbase = absDataPtr->ax;
double aybase = absDataPtr->ay;
double arbase = absDataPtr->ar;
double adx = thislockstepsize * dx / len;
double ady = thislockstepsize * dy / len;
thislocktimes= (thislocktimes+1) / 2;
for (int k = 0; k < thislocktimes; k++)
{
for (int s = 0; s <= thislocksteps; s++)
{
nitem.ctrl = ctrl;
nitem.attr = attr;
nitem.ax = axbase + adx*s;
nitem.ay = aybase + ady*s;
nitem.ar = arbase;
tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
}
for (int s = thislocksteps-1; s > 0; s--)
{
nitem.ctrl = ctrl;
nitem.attr = attr;
nitem.ax = axbase + adx*s;
nitem.ay = aybase + ady*s;
nitem.ar = arbase;
tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
}
}
break;
}
else
{
break;
}
}
}while(1);
}
}
runflag = 1;
}
else if (absDataPtr->ctrl == DATA_CUTTRD)
{
runflag = 10;
}
else
{
runflag = 0;//混合绣时需要改这里
}
tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem));
absDataPtr++;
}
m_absData.clear();
m_absData = tgtdsdat;
m_editedflag = 1;
return 0;
}
int EmbData::addContinuousRunCompensate(int value, int idx)
{
int ptnum = 0;
int index = 0;
int idxend = 0;
if (value == 0)
{
return 0;
}
ptnum = m_dataAbsList.size();
if (ptnum <= 0)
{
return 0;
}
if (idx < 0)
{
index = 0;
idxend = ptnum;
}
else
{
index = idx;
idxend = idx + 1;
}
for (int i = index; i < idxend; i++)
{
// 文件头
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue;
}
int datasize = size - sizeof(DataDs16FileHead);
int stepsize = datasize/sizeof(DsAbsItem);
if (stepsize <= 0)
{
qDebug("dat data size err");
continue;
}
DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
DsAbsItem * absDataPtr = pData;
DsAbsItem preStep, curStep, newStep;
memset(&preStep, 0, sizeof(DsAbsItem));
memset(&curStep, 0, sizeof(DsAbsItem));
memset(&newStep, 0, sizeof(DsAbsItem));
int runflag = 0;
int cdx, cdy;
// 数据镜像
for (int j = 0; j < stepsize; j++)
{
memcpy(&preStep, &curStep, sizeof(DsAbsItem));
memcpy(&curStep, absDataPtr, sizeof(DsAbsItem));
memcpy(&newStep, &curStep, sizeof(DsAbsItem));
if (curStep.ctrl != preStep.ctrl) // 控制字节不同,属于不同的类型,需要停车处理
{
if (runflag == 0) // 停车状态
{
if (curStep.ctrl == DATA_SEWING || // 缝纫数据
curStep.ctrl == DATA_SEWING_R || // 右机头缝纫
curStep.ctrl == DATA_SECF_SEW || // 第二框缝纫
curStep.ctrl == DATA_SECF_SEW_R || // 第二框右机头缝纫
curStep.ctrl == DATA_SYNCSEW || // 同步缝纫数据
0)
{
cdx = 0;
cdy = 0;
runflag = 1;
}
}
else if (runflag != 0)
{
runflag = 0;
}
}
else
{
if (runflag == 1)
{
cdx = curStep.ax - preStep.ax;
cdy = curStep.ay - preStep.ay;
newStep.ax += cdx * value / 1000;
newStep.ay += cdy * value / 1000;
absDataPtr->ax = newStep.ax;
absDataPtr->ay = newStep.ay;
}
}
absDataPtr++;
}
}
return 0;
}
QByteArray EmbData::getColorTable()
{
int colornum = 0;
QByteArray colortab;
colortab.clear();
if (m_editedflag != 0)
{
createDs16FromAbs();
}
if (m_ds16Data.size() > (int)sizeof(DataFileHead))
{
// 文件头
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_ds16Data.data());
colornum = pDsHead->colorNumber;
colortab.append((char*)(pDsHead->switchTable), colornum);
}
return colortab;
}
void EmbData::appendAbsFile(QString filePath, QByteArray array, int mirror)
{
m_filePath = filePath;
convertAbsDat(array,mirror);//是否镜像、旋转、缩放的转换
m_dataAbsList.append(array);
m_editedflag = 1;
}
//得到绝对坐标的maxXY和minXY
void EmbData::getAbsDatRangeXY()
{
m_minX = S32_MAX;
m_maxX = S32_MIN;
m_minY = S32_MAX;
m_maxY = S32_MIN;
int ptnum = m_dataAbsList.size();
double ax, ay;
int minx, miny, maxx, maxy;
for (int i = 0; i < ptnum; i++)
{
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataFileHead))
{
qDebug("ary%d data less then head size", i);
continue; // 下一个
}
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;
//-----
minx = S32_MAX;
maxx = S32_MIN;
miny = S32_MAX;
maxy = S32_MIN;
// 数据区
for (int j = 0; j < stepsize; j++)
{
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++;
}
pDsHead->minX = minx;
pDsHead->maxX = maxx;
pDsHead->minY = miny;
pDsHead->maxY = maxy;
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; }
}
}
void EmbData::setAbsDat(QByteArray & dat)
{
m_absData = dat;
}
QByteArray & EmbData::getAbsDat(void)
{
return m_absData;
}
void EmbData::setDs16ColorOfTable(u8 *table)
{
if(m_pDs16Head != NULL)
{
s16 absNumber = m_dataAbsList.size();
QByteArray ary = m_dataAbsList.at(0);
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
s16 colorNum = pDsHead->colorNumber;
QByteArray ctable;
ctable.resize(sizeof(m_pDs16Head->switchTable));
memset(ctable.data(),0,ctable.size());
for(s16 i = 0; i < absNumber; i++)
{
memcpy(ctable.data()+i*colorNum,table,colorNum);
}
memcpy(m_pDs16Head->switchTable,ctable.data(),ctable.size());//将新的色序表重新写入文件头
if((u32)m_ds16Data.size() > sizeof(m_pDs16Head))
{
memcpy(m_ds16Data.data(),(char*)m_pDs16Head, sizeof(DataDs16FileHead));
}
}
}
int EmbData::getPosInfoFromNeedleIdx(int stitchIdx, int &posx, int &posy, int & posr,int &colorIdx)
{
if (m_editedflag != 0)
{
createDs16FromAbs();
}
posx = 0;
posy = 0;
colorIdx = 0;
// 文件头
int size = m_ds16Data.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("m_embDs16Data data less then head size");
return -1;
}
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_ds16Data.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_ds16Data.data() + sizeof(DataDs16FileHead));
ds16DataPtr = pData;
posx = pDsHead->beginX;
posy = pDsHead->beginY;
posr = pDsHead->beginR;
if (stitchIdx <= 0)
{
return 0;
}
if (stitchIdx > datasize)
{
stitchIdx = datasize;
}
int dx, dy, dr;
u8 ctrl, attr;
for (int i = 0; i < stitchIdx; i++)
{
ctrl = ds16DataPtr->ctrl;
attr = ds16DataPtr->attr;
dx = ds16DataPtr->dx;
dy = ds16DataPtr->dy;
dr = ds16DataPtr->dr;
if (ctrl == DATA_CHGND)
{
colorIdx++;
}
if ((attr&0x80) != 0)
{
dx *= -1;
}
if ((attr&0x40) != 0)
{
dy *= -1;
}
posx += dx;
posy += dy;
posr += dr;
ds16DataPtr++;
}
return 0;
}
int EmbData::getPosInfoFromColorIdx(int &stitchIdx, int &posx, int &posy, int & posr, int colorIdx)
{
if (m_editedflag != 0)
{
createDs16FromAbs();
}
posx = 0;
posy = 0;
stitchIdx = 0;
int cidx = 0;
// 文件头
int size = m_ds16Data.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("m_embDs16Data data less then head size");
return -1;
}
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_ds16Data.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_ds16Data.data() + sizeof(DataDs16FileHead));
ds16DataPtr = pData;
posx = pDsHead->beginX;
posy = pDsHead->beginY;
posr = pDsHead->beginR;
if (colorIdx <= 0)
{
return -1;
}
//当前颜色索引大于总的颜色数时,针数索引等于总针数
if(colorIdx >= ((int)pDsHead->colorNumber))
{
stitchIdx = stepsize;
return 0;
}
int dx, dy, dr;
u8 ctrl, attr;
cidx = 0;
for (int i = 0; i < stepsize; i++)
{
if (cidx == colorIdx)
{
stitchIdx = i;
break;
}
ctrl = ds16DataPtr->ctrl;
attr = ds16DataPtr->attr;
dx = ds16DataPtr->dx;
dy = ds16DataPtr->dy;
dr = ds16DataPtr->dr;
if (ctrl == DATA_CHGND)
{
cidx++;
//最后一针为换色码时针数索引等于总针数减1
if(i == (stepsize - 1))
{
stitchIdx = i;
}
}
if ((attr&0x80) != 0)
{
dx *= -1;
}
if ((attr&0x40) != 0)
{
dy *= -1;
}
posx += dx;
posy += dy;
posr += dr;
ds16DataPtr++;
}
return 0;
}
int EmbData::getNeedleIdxFromColorIdx(int & needleIdx, int colorIdx, u8 & stepCtrl)
{
if (m_editedflag != 0)
{
createDs16FromAbs();
}
needleIdx = 0;
int cidx = 0;
s16 flag = 0;
// 文件头
int size = m_ds16Data.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("m_embDs16Data data less then head size");
return -1;
}
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_ds16Data.data() + sizeof(DataDs16FileHead));
ds16DataPtr = pData;
if (colorIdx <= 0)
{
return -1;
}
u8 ctrl;
cidx = 1;
for (int i = 0; i < stepsize; i++)
{
ctrl = ds16DataPtr->ctrl;
if(i == 0)
{
stepCtrl = ctrl;
}
if (ctrl == DATA_CHGND)
{
cidx++;
}
if (cidx == colorIdx)
{
if(flag == 0)
{
needleIdx = i+1;
}
//针步属性等于缝纫、冲孔或绣花
if(ctrl == DATA_SEWING ||
ctrl == DATA_PUNCH ||
ctrl == DATA_EMB)
{
stepCtrl = ctrl;
break;
}
flag = 1;
}
ds16DataPtr++;
}
return 0;
}
//设置起始点
void EmbData::setStartPosition(int x, int y)
{
if(m_pDs16Head == NULL){return;}
if(m_ds16Data.size() <= 0){return;}
//旧的起始点坐标
int oldBeginX = m_pDs16Head->beginX;
int oldBeginY = m_pDs16Head->beginY;
m_pDs16Head->beginX = x;
m_pDs16Head->beginY = y;
// m_pDs16Head->anchorX = x;
// m_pDs16Head->anchorY = y;
//新的起始点坐标与旧的起始点坐标的差值
int cx = x - oldBeginX;
int cy = y - oldBeginY;
//重新计算最大最小XY
double maxX = m_pDs16Head->maxX + cx;
double minX = m_pDs16Head->minX + cx;
double maxY = m_pDs16Head->maxY + cy;
double minY = m_pDs16Head->minY + cy;
//将最大最小值写入文件头
m_pDs16Head->maxX = maxX;
m_pDs16Head->minX = minX;
m_pDs16Head->maxY = maxY;
m_pDs16Head->minY = minY;
//修复偶尔点击中间按钮花样消失的bug
m_maxX = maxX;
m_minX = minX;
m_maxY = maxY;
m_minY = minY;
memcpy(m_ds16Data.data(),(char*)m_pDs16Head,sizeof(DataDs16FileHead));
#if(0)
QString suffix = ".ds16";
QString dsFilePath = m_filePath + suffix;
QFile file(dsFilePath);
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qDebug() << "open file fail when wirte, path =" << m_filePath;
return;
}
else
{
file.write(m_ds16Data);
file.close();
}
#endif
}
void EmbData::setAnchorPosition(int x, int y)
{
if(m_pDs16Head == NULL){return;}
if(m_ds16Data.size() <= 0){return;}
m_pDs16Head->anchorX = x;
m_pDs16Head->anchorY = y;
memcpy(m_ds16Data.data(),(char*)m_pDs16Head,sizeof(DataDs16FileHead));
#if(0)
QString suffix = ".ds16";
QString dsFilePath = m_filePath + suffix;
QFile file(dsFilePath);
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qDebug() << "open file fail when wirte, path =" << m_filePath;
return;
}
else
{
file.write(m_ds16Data);
file.close();
}
#endif
}
void EmbData::setSplitStitchLength(int length)
{
m_stitchSplitLength = length;
}
int EmbData::setDatSizeChange(int dsx, int dsy, int idx)
{
int ptnum = 0;
int index = 0;
int idxend = 0;
if (dsx == 0 && dsy == 0)
{
return 0;
}
ptnum = m_dataAbsList.size();
if (ptnum <= 0)
{
return 0;
}
if (idx < 0)
{
index = 0;
idxend = ptnum;
}
else
{
index = idx;
idxend = idx + 1;
}
for (int i = index; i < idxend; i++)
{
// 文件头
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue;
}
int datasize = size - sizeof(DataDs16FileHead);
int stepsize = datasize/sizeof(DsAbsItem);
if (stepsize <= 0)
{
qDebug("dat data size err");
continue;
}
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
DsAbsItem * absDataPtr = pData;
int width = 0;
int height = 0;
if(idx == -1) //整体缩放
{
width = m_maxX - m_minX;
height = m_maxY - m_minY;
}
else
{
width = pDsHead->maxX - pDsHead->minX;
height = pDsHead->maxY - pDsHead->minY;
}
double nw = dsx / 100.00 * width;
double nh = dsy / 100.00 * height;
double factorx,factory;
if (width != 0)
{
factorx = (double)(width + nw)/(double)width;
}
else
{
factorx = 1;
}
if (height != 0)
{
factory = (double)(height + nh)/(double)height;
}
else
{
factory = 1;
}
if (idx == -1) //整体缩放,起始点也要缩放
{
double centerx = (m_maxX + m_minX)/2;
double centery = (m_maxY + m_minY)/2;
double rx = (pDsHead->beginX - centerx) * factorx;
double ry = (pDsHead->beginY - centery) * factory;
double beginx = rx + centerx;
double beginy = ry + centery;
beginx += (beginx>0?(beginx!=0?1:0):-1) * (0.500001);
beginy += (beginy>0?(beginy!=0?1:0):-1) * (0.500001);
}
// 数据缩放
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, int idx)
{
int ptnum = 0;
int index = 0;
int idxend = 0;
if (mirror == 0) // 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像
{
return 0;
}
int mirrorx = 1;
int mirrory = 1;
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;
}
ptnum = m_dataAbsList.size();
if (ptnum <= 0)
{
return 0;
}
if (idx < 0)
{
index = 0;
idxend = ptnum;
}
else
{
index = idx;
idxend = idx + 1;
}
for (int i = index; i < idxend; i++)
{
// 文件头
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue;
}
int datasize = size - sizeof(DataDs16FileHead);
int stepsize = datasize/sizeof(DsAbsItem);
if (stepsize <= 0)
{
qDebug("dat data size err");
continue;
}
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
//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;
}
// 旋转机头针尖补偿
// 解决旋转机头缝纫机缝制平行线时,间距不一致的问题.
// 输入:correct 补偿量,单位0.01mm,范围 -2.00mm ~ 2.00mm
int EmbData::setNeedleTipCompensation(s16 correct)
{
int ptnum = 0;
if (correct == 0)
{
return 0;
}
ptnum = m_dataAbsList.size();
if (ptnum <= 0)
{
return 0;
}
for (int i = 0; i < ptnum; i++)
{
// 文件头
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue;
}
int datasize = size - sizeof(DataDs16FileHead);
int stepsize = datasize/sizeof(DsAbsItem);
if (stepsize <= 0)
{
qDebug("dat data size err");
continue;
}
DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
DsAbsItem * absDataPtr = pData;
// 针尖补偿
for (int j = 0; j < stepsize-1; j++)
{
if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
{
break;
}
if ((absDataPtr->ctrl == DATA_SEWING) ||
(absDataPtr->ctrl == DATA_SEWING_R) ||
(absDataPtr->ctrl == DATA_SECF_SEW) ||
(absDataPtr->ctrl == DATA_SECF_SEW_R) ||
(absDataPtr->ctrl == DATA_JUMP) ||
0 )
{// 只补偿缝纫/偏移数据
double len ;
double r = (absDataPtr->ar) / 10000.0; // 弧度制
if (j == 0)
{
r = (absDataPtr->ar) / 10000.0; // 弧度制
}
else
{
absDataPtr--;
if ((absDataPtr->ctrl == DATA_SEWING) ||
(absDataPtr->ctrl == DATA_SEWING_R) ||
(absDataPtr->ctrl == DATA_SECF_SEW) ||
(absDataPtr->ctrl == DATA_SECF_SEW_R) ||
(absDataPtr->ctrl == DATA_JUMP) ||
0 )
{// 如果当前针步的前一个针步也是缝纫数据,则按前一个针步的数据角度计算
r = (absDataPtr->ar) / 10000.0; // 弧度制
}
absDataPtr++;
}
if (correct > 0)
{// 补偿量为当前机头方向逆时针转90°
len = correct;
r += PI/2;
}
else
{// 补偿量为当前机头方向顺时针转90°
len = correct * -1.0;
r -= PI/2;
}
while (r > 2*PI)
{
r -= 2*PI;
}
while (r < -2*PI)
{
r += 2*PI;
}
double cosr = (double)qCos(r);
double sinr = (double)qSin(r);
double tx = cosr * len;
double ty = sinr * len;
absDataPtr->ax += tx;
absDataPtr->ay += ty;
m_editedflag = 1;
}
absDataPtr++;
}
}
return 0;
}
int EmbData::setRotate(int dr, int idx)
{
int ptnum = 0;
int index = 0;
int idxend = 0;
double rr = (dr * PI / 180) * 10000;
if (dr == 0 || dr == 360)
{
return 0;
}
ptnum = m_dataAbsList.size();
if (ptnum <= 0)
{
return 0;
}
if (idx < 0)
{
index = 0;
idxend = ptnum;
}
else
{
index = idx;
idxend = idx + 1;
}
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
for (int i = index; i < idxend; i++)
{
// 文件头
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue;
}
int datasize = size - sizeof(DataDs16FileHead);
int stepsize = datasize/sizeof(DsAbsItem);
if (stepsize <= 0)
{
qDebug("dat data size err");
continue;
}
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;
double cx;
double cy;
int rx, ry; //这里以前是double类型因为有的图形旋转后尺寸会加0.1所以改为int类型
double rcx, rcy;
if (idx == -1) // 整体旋转
{
cx = (m_maxX + m_minX)/2.0;
cy = (m_maxY + m_minY)/2.0;
rx = (pDsHead->beginX - cx);
ry = (pDsHead->beginY - cy);
}
else
{
cx = pDsHead->beginX;
cy = pDsHead->beginY;
rx = 0;
ry = 0;
}
rcx = (rx*cosa - ry*sina);
rcy = (rx*sina + ry*cosa);
double beginx = (rcx + cx);
double beginy = (rcy + cy);
beginx += (beginx>0?(beginx!=0?1:0):-1) * (0.500001);
beginy += (beginy>0?(beginy!=0?1:0):-1) * (0.500001);
DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
DsAbsItem * absDataPtr = pData;
// 数据旋转
for (int j = 0; j < stepsize; j++)
{
// 变换前点坐标
double ax = absDataPtr->ax + rx;
double ay = absDataPtr->ay + ry;
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 - rcx;
absDataPtr->ay = ray - rcy;
absDataPtr->ar = ar;
absDataPtr++;
}
}
m_editedflag = 1;
return 1;
}
int EmbData::setToMiddle(int idx)
{
int ptnum = 0;
int index = 0;
int idxend = 0;
ptnum = m_dataAbsList.size();
if (ptnum <= 0)
{
return 0;
}
if (idx < 0)
{
index = 0;
idxend = ptnum;
}
else
{
index = idx;
idxend = idx + 1;
}
for (int i = index; i < idxend; i++)
{
// 文件头
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue;
}
int datasize = size - sizeof(DataDs16FileHead);
int stepsize = datasize/sizeof(DsAbsItem);
if (stepsize <= 0)
{
qDebug("dat data size err");
continue;
}
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
if(idx == -1)
{
int centerx = 0 - (m_maxX + m_minX)/2;
int centery = 0 - (m_maxY + m_minY)/2;
int beginx = pDsHead->beginX + centerx;
int beginy = pDsHead->beginY + centery;
pDsHead->beginX = beginx;
pDsHead->beginY = beginy;
}
else
{
pDsHead->beginX = 0;
pDsHead->beginY = 0;
}
}
m_editedflag = 1;
return 0;
}
int EmbData::setDatMove(int dx, int dy, int idx)
{
int ptnum = 0;
int index = 0;
int idxend = 0;
if (dx == 0 && dy == 0)
{
return 0;
}
ptnum = m_dataAbsList.size();
if (ptnum <= 0)
{
return 0;
}
if (idx < 0)
{
index = 0;
idxend = ptnum;
}
else
{
index = idx;
idxend = idx + 1;
}
for (int i = index; i < idxend; i++)
{
// 文件头
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue;
}
int datasize = size - sizeof(DataDs16FileHead);
int stepsize = datasize/sizeof(DsAbsItem);
if (stepsize <= 0)
{
qDebug("dat data size err");
continue;
}
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
int beginx = pDsHead->beginX;
int beginy = pDsHead->beginY;
pDsHead->beginX = beginx + dx;
pDsHead->beginY = beginy + dy;
}
m_editedflag = 1;
return 0;
}
//此函数转换传入的绝对坐标值,是否取镜像及反复时数据之间的间距
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;
}
//花版的定位点为绝对坐标数据点,起始点为相对于定位点的相对坐标点,第一针为相对于起始点的坐标点
//有的花版起始点有偏移量第一针偏移量为0有的花版起始点偏移量为0第一针有偏移量
//所以ds16文件头定位点坐标就是花版中的定位点起始点坐标为花版中的定位点坐标+起始点坐标+第一针的坐标同时ds16数据的第一针坐标偏移应置为0
//生成DS16数据
int EmbData::createDs16FromAbs()
{
if (m_editedflag != 0)
{
m_minX = S32_MAX;
m_maxX = S32_MIN;
m_minY = S32_MAX;
m_maxY = S32_MIN;
int ptnum = m_dataAbsList.size();
m_ds16Data.clear();
QString name;
QByteArray tgtdsdat;
tgtdsdat.clear();
u8 ctrlByte;
u8 attrByte;
WORD actionWord; //附加动作
//s16 dx, dy, dr;
s32 dx, dy, dr;
u16 len;
double ax, ay, ar;
int actx, acty, actr;
int ddx, ddy,ddr;
double x1,y1,x2,y2;
x1 = y1 = x2 = y2 = 0;
int beginx, beginy,beginr, anchorx, anchory;
int minx, miny, maxx, maxy;
int colornum = 1;// 颜色数
int punchNum = 0;//冲孔个数
int first = 1;//第一针
actx = 0;
acty = 0;
actr =0;
beginx = 0;
beginy = 0;
beginr = 0;
anchorx = 0;
anchory = 0;
int totalstepsize = 0;
memset(m_pDs16Head,0,sizeof(DataDs16FileHead));
for (int i = 0; i < ptnum; i++)
{
const QByteArray & ary = m_dataAbsList.at(i);
int size = ary.size();
if (size <= (int)sizeof(DataDs16FileHead))
{
qDebug("ary%d data less then head size", i);
continue; // 下一个
}
DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
//dsr,dst的中间数据
//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;
// 数据区
for (int j = 0; j < stepsize; j++)
{
Ds16Item ds16Item;
memset(&ds16Item,0,sizeof(Ds16Item));//清空ds16针步
if(i != 0 && j == 0)//反复时非第一个花样第一针应是偏移
{
// 添加偏移
ctrlByte = DATA_OFFSET;
}
else
{
ctrlByte = absDataPtr->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 (first != 0)//first = 1第一个图元的第一针
{
beginx = ax;
beginy = ay;
beginr = pDsHead->beginR;
anchorx = pDsHead->anchorX;
anchory = pDsHead->anchorY;
actx = ax;
acty = ay;
actr = ar;
ddx = 0;
ddy = 0;
//让ddr等于0因为在datafiledsr中将beginR置为0而非第一针的角度所以不应该用 absDataPtr->ar - pDsHead->beginR
//如果beginR等于第一针的角度那么第一针的ddr就应该是0
ddr = 0;
#if(0)
//过滤掉空针
if(ddx== 0 && ddy == 0)
{
actx += ddx;
acty += ddy;
actr += ddr;
absDataPtr++;
first = 0;//第一个图元的第一针
continue;
}
#endif
}
else
{
ddx = ax - actx;
ddy = ay - acty;
ddr = ar -actr;
}
//画笔转冲孔时冲孔第一针的ddr置为0
if(absDataPtr->ctrl == DATA_PUNCH)
{
if(absDataPtr != pData)
{
absDataPtr--;
if(absDataPtr->ctrl == DATA_DRAWING)
{
ddr = 0;
}
absDataPtr++;
}
}
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)
//过滤掉运针空针
if(ddx== 0 && ddy == 0 && ddr == 0 && (ctrlByte == DATA_PUNCH || ctrlByte == DATA_EMB || ctrlByte == DATA_SEWING))
{
absDataPtr++;
qDebug()<<"This is a empty needle"<<j<<ddr;
continue;
}
#endif
if (ctrlByte == DATA_END || ctrlByte == DATA_NULL)
{
if (i == ptnum - 1) // 最后一个图
{
dx = dy = dr = len = 0;
// 增加剪线
ds16Item.ctrl = DATA_CUTTRD;
ds16Item.attr = 0;
ds16Item.action[0] = 0;
ds16Item.action[1] = 0;
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));
totalstepsize++;
}
else
{
ctrlByte = DATA_CUTTRD; // 改为剪线
}
}
//分割针步 大于2000小于-2000进行分割
//如果dx或dy数值太大时平方会超出double范围所以先都除以100再乘以10000
double xyLen = sqrt(((dx/100.0)*(dx/100.0))*10000.0+ ((dy/100.0)*(dy/100.0))*10000.0);
double maxStep = 2000.0;
double splitVal = 500.0;//分割针步为500
if(m_stitchSplitLength != 0)
{
maxStep = m_stitchSplitLength;
if(m_stitchSplitLength < splitVal)
{
splitVal = m_stitchSplitLength - 100;
}
}
if(xyLen >= maxStep)
{
s16 addx,addy;
x1 = ax;
y1 = ay;
x2 = ax;
y2 = ay;
if(j != 0)
{
absDataPtr--;
x1 = absDataPtr->ax;
y1 = absDataPtr->ay;
absDataPtr++;
}
double tremainder =fmod(xyLen, splitVal);//取余
s16 stepNum = xyLen / splitVal;//拆分几步
if(tremainder != 0)
{
stepNum += 1;
}
double k = (y2-y1)/(x2-x1);
double r = atan(k);
double stepX = 0;
double stepY = 0;
double stepDr = 0;
addx = 0;
addy = 0;
for(int m = 0; m < stepNum; m++)
{
stepX = 0;
stepY = 0;
stepDr = 0;
memset(&ds16Item,0,sizeof(Ds16Item));//初始化结构体
if(m == stepNum-1 && tremainder > 0)//最后一步
{
splitVal = tremainder;
}
stepX = splitVal * cos(r);
stepY = splitVal * sin(r);
//stepX = cos(r) * splitVal;
if((dx < 0 && stepX > 0) || (dx > 0 && stepX < 0))
{
stepX = 0 - stepX;
}
//stepY = sin(r) * splitVal;
if((dy < 0 && stepY > 0) || (dy > 0 && stepY < 0))
{
stepY = 0 - stepY;
}
if(m == 0)
{
//stepDr = temp;
stepDr = dr;
}
//大针步转换为跳针
if(ctrlByte == DATA_PUNCH || ctrlByte == DATA_DRAWING)//功能码等于冲孔数据或画笔数据
{
// if(m == stepNum - 1)
// {
// ds16Item.ctrl = ctrlByte;
// }
// else
{
ds16Item.ctrl = DATA_JUMP;//跳针
}
}
else
{
ds16Item.ctrl = ctrlByte;
}
ds16Item.attr = attrByte;
ds16Item.action[0] = 0;
ds16Item.action[1] = 0;
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;
}
len = sqrt(ds16Item.dx*ds16Item.dx + ds16Item.dy*ds16Item.dy);
ds16Item.dr = stepDr;
ds16Item.len = len;
memset(ds16Item.rev,0,sizeof(ds16Item.rev));
tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
totalstepsize++;
//插入空针
if(m == stepNum - 1)
{
memset(&ds16Item,0,sizeof(ds16Item));
ds16Item.ctrl = ctrlByte;
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(i != 0 && j == 0)//反复时非第一个花样第一针改为偏移后再加换色码和一针正常针步
{
// 添加换色
memset(&ds16Item,0,sizeof(Ds16Item));
ds16Item.ctrl = DATA_CHGND;
tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
totalstepsize++;
colornum++;
// 添加第一针针步
memset(&ds16Item,0,sizeof(Ds16Item));
ds16Item.ctrl = absDataPtr->ctrl;
tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
totalstepsize++;
}
if (ctrlByte == DATA_CHGND)
{
colornum++;
}
if (ds16Item.ctrl == DATA_PUNCH)
{
punchNum++;//冲孔总数加1
}
absDataPtr++;
first = 0;//第一针
}
// 添加色序表
int cidx, cnum;
cnum = colornum;
if (cnum > BF_SW_ND)
{
cnum = BF_SW_ND;
}
cidx = m_pDs16Head->colorNumber;
if (cidx < 0)
{
cidx = 0;
}
if (cidx > BF_SW_ND)
{
cidx = BF_SW_ND;
}
if (cidx + cnum > BF_SW_ND)
{
cnum = BF_SW_ND - cidx;
}
memcpy(&(m_pDs16Head->switchTable[cidx]), pDsHead->switchTable, cnum);
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; }
m_pDs16Head->colorNumber = cnum; // 颜色数增加
}
// 针数
int newstepnum = tgtdsdat.size() / sizeof(Ds16Item);
if (newstepnum > 0)
{
// 修改文件头
int namelen = name.size();
if (namelen > HEAD_NAME_STR_LEN)
{
namelen = HEAD_NAME_STR_LEN;
}
QByteArray array = name.toLocal8Bit().data();
memcpy(m_pDs16Head->fileName, array, namelen); // 文件名称
m_pDs16Head->dataSize = newstepnum*sizeof(Ds16Item); // 数据字节数
m_pDs16Head->itemNums = newstepnum; // 数据项个数
m_pDs16Head->bytesPerItem = sizeof(Ds16Item); // 每项占的字节数
m_pDs16Head->bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小
m_pDs16Head->dataChecksum = calcCheckSum32((u8 *)(tgtdsdat.data()) , m_pDs16Head->dataSize); // 数据累加校验和
m_pDs16Head->checkCrc = calcCrc16((u8 *)(m_pDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验6个字段分别为文件名称字节数项个数每项字节数每块字节数数据累加和的CRC校验值
m_pDs16Head->fileid = m_pDs16Head->checkCrc;
m_pDs16Head->anchorX = anchorx; // 定位点坐标X
m_pDs16Head->anchorY = anchory; // 定位点坐标Y, 设置为0作为基准
m_pDs16Head->beginX = beginx; // 数据起点坐标X
m_pDs16Head->beginY = beginy; // 数据起点坐标Y
m_pDs16Head->beginR = beginr; // 数据起点坐标R //-rq
m_pDs16Head->minX = m_minX;
m_pDs16Head->maxX = m_maxX;
m_pDs16Head->minY = m_minY;
m_pDs16Head->maxY = m_maxY; // 轮廓范围,使用重新计算之后的值
m_pDs16Head->punchNum = punchNum;//冲孔个数
// 添加文件头
m_ds16Data.append((char*)m_pDs16Head, sizeof(DataDs16FileHead));//ds16头文件存在ds16中
// 添加文件数据
m_ds16Data.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_ds16Data);
file.close();
}
#endif
}
m_editedflag = 0;
return 0;
}
int EmbData::reCalcDataChecksum()
{
return 0;
}
QByteArray EmbData::intTo2ByteArray(s16 value)
{
QByteArray ba;
ba.resize(2);
ba[0] = (uchar)(0x000000ff & value);
ba[1] = (uchar)((0x0000ff00 & value) >> 8);
return ba;
}
//绘制针数索引的跟踪笔
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::eraseNeedleIdxPen(QPainter &painter)
{
//贴图的xy和画笔的xy值相同
painter.drawPixmap(m_penX-20,m_penY-30,m_penPix);
}
//设置视图尺寸(透明背景)
int EmbData::setViewInfo(int width, int height)
{
// if (m_viewWidth != width ||
// m_viewHight != height)
{
if (width <= PREVIEW_SIDE*2 || height <= 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;
}
//重新重置ds16数据(换色点击取消后数据会变为单个图元的原数据,
//若图形经过变换数据会不对,主界面保存了最后的数据,
//若点击换色并取消后恢复为主界面最后保存的数据即可)
void EmbData::reSetEmbData(QByteArray ary)
{
if(ary.size() <= 0)
{
return;
}
m_ds16Data.clear();
m_ds16Data.append(ary);
//文件头也恢复为默认
memcpy(m_pDs16Head, m_ds16Data.data(), sizeof(DataDs16FileHead)); // 文件名称
}
void EmbData::reSetEmbDataRange(int maxX, int minX, int maxY, int minY)
{
m_maxX = maxX;
m_minX = minX;
m_maxY = maxY;
m_minY = minY;
}
//重置数据
void EmbData::setEmbData(int redraw)
{
createDispFromDs16Dat(m_ds16Data);
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::setGreyAreaRange(int begin, int end)
{
m_greyColorBeg = begin;
m_greyColorEnd = end;
}
//设置区域显示参数
void EmbData::setDispAreaRange(int begin, int end, int redraw)
{
m_showColorBeg = begin;
m_showColorEnd = end;
if (redraw != 0)
{
drawImageByDispFile();
}
}
//设置进度显示数据
void EmbData::setExecIndex(int index)
{
m_stitchIndex = index;
if (m_dispMode == DISP_EXECING)
{
drawImageByDispFile();
}
}
void EmbData::reDraw()
{
drawImageByDispFile();
}
//创建显示用的数据(为了快速显示)
int EmbData::createDispFromDs16Dat(QByteArray &ds16dat)
{
DispItem 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 <= PREVIEW_SIDE*2 || height <= PREVIEW_SIDE*2)
{
qDebug("preview img too small");
return -1;
}
//留边(否则实时跟踪笔会画出界)
int viewSide = 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;
int colorIdx,oldcolor;
double datposx, datposy, datposr;
int curx, cury, prex, prey;
curx = cury = prex = prey = 0;
//用起始点绘制
datposx = pDsHead->beginX;
datposy = pDsHead->beginY;
datposr = pDsHead->beginR;
curx = (datposx) / factor + dpx;
cury = (datposy) / factor + dpy;
if (SHOWDIRX == -1)
{
curx = width - curx;
}
if (SHOWDIRY == -1)
{
cury = height - cury;
}
colorIdx = 0;
oldcolor = -1;
QRgb embcolor = 0;
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 (SHOWDIRX == -1)
{
curx = width - curx;
}
if (SHOWDIRY == -1)
{
cury = height - cury;
}
if (oldcolor != colorIdx)
{
//int cidx = pDsHead->switchTable[colorIdx % EMB_BF_SW_ND];
int nidx = pDsHead->switchTable[colorIdx];
int cidx;
if(nidx <= 0)
{
cidx = 0;//未设置过色序时颜色索引默认为0
}
else
{
cidx = m_needleColorTable[nidx - 1] % BF_SW_ND;
}
int cnum = m_tabelColorNum;
cnum /= sizeof(QRgb);
if (cnum > BF_SW_ND)
{
cnum = BF_SW_ND;
}
if (cnum != 0)
{
cidx %= cnum;
QRgb * pColor = m_pColor;
if(pColor != NULL)
{
embcolor = (pColor[cidx]);
}
else
{
embcolor = 0;
}
}
else
{
embcolor = 0;
}
oldcolor = colorIdx;
}
if (ctrlByte == DATA_CHGND) // 换色
{
colorIdx++;
}
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.rgb = embcolor;
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;
}
#define DRAWDR 0
int EmbData::drawImageByDispFile()
{
u8 ctrl;
int bx, by, ex, ey;
bx = by = ex = ey = 0;
int i;
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;
}
if (m_showColorBeg < 0)
{
m_showColorBeg = 0;
}
if (m_showColorEnd < 0)
{
m_showColorEnd = 0;
}
DISP_MODE dispmode = m_dispMode;
QPainter painter(&m_canvas);
int gary = 0;
QRgb rgb, oldrgb;
s16 ar;
QPen pen;
QColor color;
//笔宽
pen.setWidth(4);
oldrgb = 0;
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);
}
ctrl = pDispBuff[i].ctrl;
bx = pDispBuff[i].bx;
by = pDispBuff[i].by;
ex = pDispBuff[i].ex;
ey = pDispBuff[i].ey;
ar = pDispBuff[i].ar;
rgb = pDispBuff[i].rgb;
if (dispmode == DISP_ALL_EXEC) // 从开始到 m_stitchIndex 显示正常颜色的线迹(执行过),从 m_stitchIndex 结束显示未缝纫颜色线迹(未执行)
{
if (i >= m_stitchIndex)
{
gary = qGray(rgb);
//gary = gary/3 + 150; // 颜色变淡
gary = COLOR_GREY;//纯灰
rgb = qRgb(gary, gary, gary);
}
}
if (oldrgb != rgb)
{
color.setRgb(rgb);
pen.setColor(color);
painter.setPen(pen);
oldrgb = rgb;
}
if(ctrl == DATA_PUNCH)
{
int cr = PUNCHRADIUS / m_factor;
if(cr <= 0){cr = 1;}
painter.drawEllipse(ex-cr,ey-cr,cr*2,cr*2);
}
else
{
painter.drawLine(bx, by, ex, ey);
}
if(ar == 0){}//为了去掉编译警告
#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;
drawNeedleIdxPen(bx, by, painter);//绘制跟踪笔
m_dispIndex = m_stitchIndex; // 移动显示指针
}
}
else if ( dispmode == DISP_ALL_AREA ) // 显示所有线迹(有效区域内的显示原色,其余显示灰色)
{
//显示为灰色
for(int j = m_greyColorBeg; j < m_greyColorEnd; j++)
{
ctrl = pDispBuff[j].ctrl;
bx = pDispBuff[j].bx;
by = pDispBuff[j].by;
ex = pDispBuff[j].ex;
ey = pDispBuff[j].ey;
rgb = pDispBuff[j].rgb;
gary = qGray(rgb);
//gary = gary/3 + 150; // 颜色变淡
gary = COLOR_GREY;//纯灰
rgb = qRgb(gary, gary, gary);
if (oldrgb != rgb)
{
color.setRgb(rgb);
pen.setColor(color);
painter.setPen(pen);
oldrgb = rgb;
}
if(ctrl == DATA_PUNCH)
{
int cr = PUNCHRADIUS / m_factor;
if(cr <= 0){cr = 1;}
painter.drawEllipse(ex-cr,ey-cr,cr*2,cr*2);
}
else
{
painter.drawLine(bx, by, ex, ey);
}
}
//显示为原色
for(int m = m_showColorBeg; m < m_showColorEnd; m++)
{
ctrl = pDispBuff[m].ctrl;
bx = pDispBuff[m].bx;
by = pDispBuff[m].by;
ex = pDispBuff[m].ex;
ey = pDispBuff[m].ey;
rgb = pDispBuff[m].rgb;
color.setRgb(rgb);
pen.setColor(color);
painter.setPen(pen);
if(ctrl == DATA_PUNCH)
{
int cr = PUNCHRADIUS / m_factor;
if(cr <= 0){cr = 1;}
painter.drawEllipse(ex-cr,ey-cr,cr*2,cr*2);
}
else
{
painter.drawLine(bx, by, ex, ey);
}
}
}
else if (dispmode == DISP_EXECING) // 刷新部分线迹(缝纫中进度显示)
{
//qDebug()<<"m_stitchIndex"<<m_stitchIndex<<"m_dispIndex"<<m_dispIndex;
if (m_stitchIndex != m_dispIndex)
{
eraseNeedleIdxPen(painter);//擦除跟踪笔
// 显示针迹改变
if (m_stitchIndex > m_dispIndex && m_stitchIndex < stitchCount)
{
i = m_dispIndex;
while(i < m_stitchIndex) // 显示为原线迹
{
ctrl = pDispBuff[i].ctrl;
bx = pDispBuff[i].bx;
by = pDispBuff[i].by;
ex = pDispBuff[i].ex;
ey = pDispBuff[i].ey;
rgb = pDispBuff[i].rgb;
if (oldrgb != rgb)
{
color.setRgb(rgb);
pen.setColor(color);
painter.setPen(pen);
oldrgb = rgb;
}
if(ctrl == DATA_PUNCH)
{
int cr = PUNCHRADIUS / m_factor;
if(cr <= 0){cr = 1;}
painter.drawEllipse(ex-cr,ey-cr,cr*2,cr*2);
}
else
{
painter.drawLine(bx, by, ex, ey);
}
i++;
}
}
else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount)
{
i = m_stitchIndex;
while(i <= m_dispIndex) // 显示为未缝纫颜色线迹
{
ctrl = pDispBuff[i].ctrl;
bx = pDispBuff[i].bx;
by = pDispBuff[i].by;
ex = pDispBuff[i].ex;
ey = pDispBuff[i].ey;
rgb = pDispBuff[i].rgb;
gary = qGray(rgb);
//gary = gary/3 + 150; // 颜色变淡
gary = COLOR_GREY;//纯灰
rgb = qRgb(gary, gary, gary);
if (oldrgb != rgb)
{
color.setRgb(rgb);
pen.setColor(color);
painter.setPen(pen);
oldrgb = rgb;
}
if(ctrl == DATA_PUNCH)
{
int cr = PUNCHRADIUS / m_factor;
if(cr <= 0){cr = 1;}
painter.drawEllipse(ex-cr,ey-cr,cr*2,cr*2);
}
else
{
painter.drawLine(bx, by, ex, ey);
}
i++;
}
}
i = m_stitchIndex;
bx = pDispBuff[i].bx;
by = pDispBuff[i].by;
drawNeedleIdxPen(bx, by, painter);//绘制跟踪笔
m_dispIndex = m_stitchIndex; // 移动显示指针
}
}
return 0;
}