QuiltingHMI/datafile/embdata.cpp
2024-02-06 15:10:48 +08:00

3801 lines
108 KiB
C++
Raw Permalink 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"
#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"<<m_editedflag;
if(m_editedflag != 0)
{
createEmbDs16FromAbs();
}
return m_embDs16Data;
}
//设置数据区文件头的fileid计算完以后的fileid再设置进来
void EmbData::setDsDatHeadFileID(u32 fileid)
{
if(m_pEmbDs16Head != NULL)
{
m_pEmbDs16Head->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<LineItem> 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()<<j<<m<<cx<<cy;
}
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
{
//(x - cx )^2 + (y - cy)^2 = r^2
//y = kx +b
// 求得直线方程
double k = ((double)(secondPoint.y()-firstPoint.y()))/(secondPoint.x()-firstPoint.x());
double b = firstPoint.y()-k*firstPoint.x();
// 列方程
//(1 + k^2)*x^2 - x*(2*cx -2*k*(b -cy) ) + cx*cx + ( b - cy)*(b - cy) - r*r = 0
int x1,y1,x2,y2;
double c = (circlePoint.x()/100.0)*(circlePoint.x()/100.0)*10000.0+((b-circlePoint.y())/100.0)*((b-circlePoint.y())/100.0)*10000.0-stepLength*stepLength;
double a = (1+k*k);
double b1 = 2*circlePoint.x()-2*k*(b-circlePoint.y());
// 得到下面的简化方程
// a*x^2 - b1*x + c = 0;
double sval = (b1/100.0)*(b1/100.0)*10000.0-4*a*c;
if(sval < 0)
{
qDebug()<<j<<sval;
//sval = abs(sval);
}
double tmp = sqrt(sval);
x1 = qRound((b1+tmp)/(2*a));
y1 = qRound(k*x1+b);
x2 = qRound((b1-tmp)/(2*a));
y2 = qRound(k*x2+b);
//判断点是否在第一个和第二个点之间
QPoint p1(x1,y1);
QPoint p2(x2,y2);
QRect rect(firstPoint,secondPoint);
bool bl1 = false;
if(rect.contains(p1))
{
bl1 = true;
}
bool bl2 = false;
if(rect.contains(p2))
{
bl2 = true;
}
// 判断求出的点是否在圆上
int res = qRound(sqrt((x1-cx)*(x1-cx)+(y1-cy)*(y1-cy)));
bool bl3 = true;//这里让此条件一直成立
if(res <= (stepLength+10) &&
res >= (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()<<j<<m<<cx<<cy;
}
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
{
qDebug()<<"bl3=false";
break;
}
}
}
}
}
//修改绝对坐标数据
stepsize = nabsData.size() / sizeof(DsAbsItem);
m_pEmbDs16Head->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<LineItem> 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<DsAbsItem> 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"<<m_maxX<<"m_minX"<<m_minX;
qDebug()<<"m_maxY"<<m_maxY<<"m_minY"<<m_minY;
qDebug()<<"beginx"<<x<<"beginy"<<y;
#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_embDs16Data);
file.close();
}
#endif
}
void EmbData::setAnchorPosition(int x, int y)
{
if(m_pEmbDs16Head == NULL){return;}
if(m_embDs16Data.size() <= 0){return;}
m_pEmbDs16Head->anchorX = x;
m_pEmbDs16Head->anchorY = y;
memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,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_embDs16Data);
file.close();
}
#endif
}
double EmbData::getAngle(double x1, double y1, double x2, double y2)
{
double angle;
if(x1 == x2)
{
if(y2 > y1)
{
angle = 90.0;
}
else
{
angle = 270.0;
}
}
else if (y1 == y2)
{
if(x1 > x2)
{
angle = 180.0;
}
else
{
angle = 0.0;
}
}
else
{
angle = atan((y2 - y1)*1.0 / (x2 - x1) *1.0)*180/M_PI;
if(angle < 0)
{
if(x1 > x2)
{
angle = angle + 180.0;
}
else
{
angle = angle + 360.0;
}
}
else
{
if(x1 > x2)
{
angle = angle + 180.0;
}
}
}
return angle;
}
int EmbData::setDatSizeChange(int dsx, int dsy)
{
//因为帽绣机要有100%以下的缩放倍率,所以将 dsx <= 0 && dsy <= 0改为以下 -rq
if (dsx <= 0 && dsy <= 0)
{
return 0;
}
// 文件头
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());
DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
DsAbsItem * absDataPtr = pData;
int width = m_maxX - m_minX;
int height = m_maxY - m_minY;
double nw = dsx * 1.0;
double nh = dsy * 1.0;
double factorx,factory;
if (width != 0)
{
factorx = nw/(double)width;
}
else
{
factorx = 1;
}
if (height != 0)
{
factory = nh/(double)height;
}
else
{
factory = 1;
}
pDsHead->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:"<<stepsize;
for (int j = 0; j < stepsize; j++)
{
Ds16Item ds16Item;
memset(&ds16Item,0,sizeof(Ds16Item));//清空ds16针步
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 (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()<< "增加剪线" <<j;
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++;
}
//分割针步
double maxStep = 800.0;
//如果dx或dy数值太大时平方会超出double范围所以先都除以100再乘以10000
double xyLen = sqrt((dx/100.0*dx/100.0)*10000.0+ (dy/100.0*dy/100.0)*10000.0);
//if( 0 && xyLen > 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" <<newstepnum;
if (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<DsAbsItem> &inList, double indRunLen, QList<DsAbsItem> &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<DsAbsItem> *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_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) // 显示为原线迹
{
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 <bitset>
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_stitchIndex<<"m_dispIndex"<<m_dispIndex;
if (m_stitchIndex != m_dispIndex)
{
for(int j = 0; j < headNum; j++)
eraseNeedleIdxPen(painter,j);///擦除跟踪笔
// 显示针迹改变
if (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);
}
}
}