#include "embdata.h" #include "main.h" const QColor sewcolorGreen = QColor(0x35,0xC0,0x5C);//绿色 u32 rgbColorGreen = qRgb(sewcolorGreen.red(),sewcolorGreen.green(),sewcolorGreen.blue()); const QColor sewcolorYel = QColor(Qt::darkYellow);//黄色 u32 rgbColorYel = qRgb(sewcolorYel.red(),sewcolorYel.green(),sewcolorYel.blue()); const QColor sewcolorblue = QColor(Qt::blue);//蓝色 u32 rgbColorBlue = qRgb(sewcolorblue.red(),sewcolorblue.green(),sewcolorblue.blue()); const int headNum = 5; // 机头数 EmbData::EmbData() { m_pEmbDs16Head = new DataDs16FileHead(); m_penHeadPix.resize(5); m_penPoint.resize(5); clear(); } EmbData::~EmbData() { clear(); if(m_pEmbDs16Head != NULL) { delete m_pEmbDs16Head; } } void EmbData::clear() { m_maxX = 0; m_minX = 0; m_maxY = 0; m_minY = 0; m_fileid = 0; m_spaceX = 0; m_spaceY = 0; m_penX = 0; m_penY = 0; m_embDs16Data.clear(); m_editedflag = 0; m_filePath.clear(); m_factor = 0; memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead)); } QByteArray & EmbData::getDsDat() { //qDebug()<<"m_editedflag"<fileid = fileid; if((u32)m_embDs16Data.size() > sizeof(DataDs16FileHead)) { memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head, sizeof(DataDs16FileHead)); } } } //得到绝对坐标的maxXY和minXY void EmbData::getAbsDatRangeXY() { m_minX = S32_MAX; m_maxX = S32_MIN; m_minY = S32_MAX; m_maxY = S32_MIN; double ax, ay; int minx, miny, maxx, maxy; const QByteArray & ary = m_embAbsData; int size = ary.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("ary data less then head size"); } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data()); int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("absdat dataBegin err"); return; } int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("absdat data size err"); return; } DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; //----- int begx = pDsHead->beginX; int begy = pDsHead->beginY; minx = S32_MAX; maxx = S32_MIN; miny = S32_MAX; maxy = S32_MIN; // 数据区 for (int j = 0; j < stepsize; j++) { ax = absDataPtr->ax + begx; ay = absDataPtr->ay + begy; // ax = absDataPtr->ax; // ay = absDataPtr->ay; if (minx > ax) { minx = ax; } if (maxx < ax) { maxx = ax; } if (miny > ay) { miny = ay; } if (maxy < ay) { maxy = ay; } absDataPtr++; } if (m_minX > minx) { m_minX = minx; } if (m_minX > maxx) { m_minX = maxx; } if (m_maxX < minx) { m_maxX = minx; } if (m_maxX < maxx) { m_maxX = maxx; } if (m_minY > miny) { m_minY = miny; } if (m_minY > maxy) { m_minY = maxy; } if (m_maxY < miny) { m_maxY = miny; } if (m_maxY < maxy) { m_maxY = maxy; } } // 添加锁针针步 int EmbData::addLockStitchs(u8 mode, u8 needles, u8 num) { if (needles <= 0) { return -1; } int size = m_embAbsData.size(); if (size <= 0) { return -1; } int lockNum = num;//锁针次数 int lockNeedles = needles;//锁针针数 QByteArray tgtdsdat; // 添加后的绝对坐标数据 tgtdsdat.clear(); // 文件头 int datasize = size - sizeof(DataDs16FileHead); int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("dat size err"); return -1; } DataDs16FileHead * pHead = (DataDs16FileHead *)(m_embAbsData.data()); DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; tgtdsdat.append((char*)pHead, sizeof(DataDs16FileHead)); //pHead = (DataDs16FileHead *)(tgtdsdat.data()); int runflag = 0; for (int j = 0; j < stepsize; j++) { if (absDataPtr->ctrl == DATA_SEWING)//包括起针和剪线后加锁针 { if ((runflag == 0 || runflag > 3)) { // 添加锁针 int nst = 0; if(mode == MODE_LOCK)//锁针方式 { if(lockNum%2 == 0)//偶数 { nst = 1; } else//奇数 { nst = needles; } do { if(j+nst < stepsize) { DsAbsItem * nextPtr = absDataPtr+nst; // 要加锁针的点 if (nextPtr->ctrl == DATA_SEWING) { DsAbsItem nitem; memset(&nitem,0,sizeof(DsAbsItem)); u8 ctrl = absDataPtr->ctrl; u8 attr = 0; // absDataPtr->attr; double arbase = absDataPtr->ar; if(lockNum%2 == 0)//偶数锁针 { nextPtr--; for (int k = 0; k < lockNum; k++) { if(k%2 == 0) { for (int s = 0; s < lockNeedles; s++) { nextPtr++; double axbase = nextPtr->ax; double aybase = nextPtr->ay; nitem.ctrl = ctrl; nitem.attr = attr; nitem.ax = axbase; nitem.ay = aybase; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); } } if(k > 0 && k%2 != 0) { for (int s = lockNeedles; s > 0; s--) { nextPtr--; double axbase = nextPtr->ax; double aybase = nextPtr->ay; if(k == lockNum-1 && s == 1) { continue;//最后一次锁针的最后一步不添加 } nitem.ctrl = ctrl; nitem.attr = attr; nitem.ax = axbase; nitem.ay = aybase; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); } } } } else//奇数锁针 { nextPtr++; for (int k = 0; k < lockNum; k++) { if(k%2 == 0) { for (int s = lockNeedles; s > 0; s--) { nextPtr--; double axbase = nextPtr->ax; double aybase = nextPtr->ay; if(k == 0 && s == lockNeedles) { nitem.ctrl = DATA_OFFSET;//第一针步转换为跨步 } else { nitem.ctrl = ctrl; } nitem.attr = attr; nitem.ax = axbase; nitem.ay = aybase; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); } nextPtr--; } if(k > 0 && k%2 != 0) { for (int s = 0; s < lockNeedles; s++) { double axbase = nextPtr->ax; double aybase = nextPtr->ay; nitem.ctrl = ctrl; nitem.attr = attr; nitem.ax = axbase; nitem.ay = aybase; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); nextPtr++; } nextPtr++; } } } break; } else { break; } } }while(1); } else if(mode == MODE_THICKEN)//密针方式 { tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem)); nst = 1; s16 nNum = 0; if(lockNum == 0)//如果锁针次数为0时,第一针锁针次数就是锁针针数 { nNum = lockNeedles+1; } else { nNum = lockNum+1; } do { if(j+nst < stepsize) { DsAbsItem * nextPtr = absDataPtr+nst; // 下一个点 if (nextPtr->ctrl == DATA_SEWING) { DsAbsItem nitem; memset(&nitem,0,sizeof(DsAbsItem)); DsAbsItem * prePtr = absDataPtr; u8 ctrl = absDataPtr->ctrl; u8 attr = 0; // absDataPtr->attr; double arbase = absDataPtr->ar; for (int s = 0; s < lockNeedles; s++) { double dx = nextPtr->ax - prePtr->ax; double dy = nextPtr->ay - prePtr->ay; double len = sqrt(dx*dx + dy*dy); if (len <= 0) { prePtr = nextPtr; nextPtr++; lockNeedles++; continue; } double dLen = len / nNum; double axbase = prePtr->ax; double aybase = prePtr->ay; for (int k = 0; k < nNum; k++) { double nax = dx * dLen / len + axbase; double nay = dy * dLen / len + aybase; nitem.ctrl = ctrl; nitem.attr = attr; nitem.ax = nax; nitem.ay = nay; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); axbase = nax; aybase = nay; } if(lockNum == 0) { nNum--; } prePtr = nextPtr; nextPtr++; } break; } else { break; } } }while(1); for (int s = 0; s <= lockNeedles; s++)//跳到不加锁针的那一针 { absDataPtr++; j++; } } runflag = 1; } } else if (absDataPtr->ctrl == DATA_CUTTRD) { runflag = 10; } else { runflag = 0; } //结束前或剪线前加锁针 if (absDataPtr->ctrl == DATA_END || absDataPtr->ctrl == DATA_NULL || j == stepsize-1 || absDataPtr->ctrl == DATA_CUTTRD) { int m = 1; //结束前或剪线前加锁针 DsAbsItem * prePtr = absDataPtr-1; // 上一个点 u8 ctl = prePtr->ctrl; while(ctl != DATA_SEWING) { prePtr--; m++; ctl = prePtr->ctrl; if(prePtr == pData)//起始地址 { return -1; } } // 添加锁针 int nst = 1; if(mode == MODE_LOCK)//锁针方式 { do { if(j-m-nst > 0) { DsAbsItem * lockPtr = prePtr; // 要加锁针的点 if (lockPtr->ctrl == DATA_SEWING) { DsAbsItem nitem; memset(&nitem,0,sizeof(DsAbsItem)); u8 ctrl = prePtr->ctrl; u8 attr = 0; // absDataPtr->attr; double arbase = prePtr->ar; for (int k = 0; k < lockNum; k++) { if(k%2 == 0) { for (int s = lockNeedles; s > 0; s--) { lockPtr--; double axbase = lockPtr->ax; double aybase = lockPtr->ay; nitem.ctrl = ctrl; nitem.attr = attr; nitem.ax = axbase; nitem.ay = aybase; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); } } if(k > 0 && k%2 != 0) { for (int s = 0; s < lockNeedles; s++) { lockPtr++; double axbase = lockPtr->ax; double aybase = lockPtr->ay; nitem.ctrl = ctrl; nitem.attr = attr; nitem.ax = axbase; nitem.ay = aybase; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); } } } break; } else { break; } } }while(1); } else if(mode == MODE_THICKEN)//密针方式 { nst = needles; //去除要加密针的已添加的针步 tgtdsdat.remove(tgtdsdat.size()-needles*sizeof(DsAbsItem),needles*sizeof(DsAbsItem)); s16 nNum = 0; if(lockNum == 0)//如果锁针次数为0时,第一针锁针次数就是锁针针数 { nNum = lockNeedles+1; } else { nNum = lockNum+1; } do { if(j-m-nst > 0) { DsAbsItem * lockPtr = prePtr-lockNeedles; // 加锁针点 if (lockPtr->ctrl == DATA_SEWING) { DsAbsItem nitem; memset(&nitem,0,sizeof(DsAbsItem)); u8 ctrl = prePtr->ctrl; u8 attr = 0; // absDataPtr->attr; double arbase = prePtr->ar; for (int s = 0; s < lockNeedles; s++) { DsAbsItem * nextPtr = lockPtr+1; double dx = nextPtr->ax - lockPtr->ax; double dy = nextPtr->ay - lockPtr->ay; double len = sqrt(dx*dx + dy*dy); if (len <= 0) { if(lockNum == 0) { nNum--; } lockPtr++; continue; } double dLen = len / nNum; double axbase = lockPtr->ax; double aybase = lockPtr->ay; for (int k = 0; k < nNum; k++) { double nax = dx * dLen / len + axbase; double nay = dy * dLen / len + aybase; nitem.ctrl = ctrl; nitem.attr = attr; nitem.ax = nax; nitem.ay = nay; nitem.ar = arbase; tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem)); axbase = nax; aybase = nay; } if(lockNum == 0) { nNum--; } lockPtr++; } break; } else { break; } } }while(1); } } tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem)); absDataPtr++; } m_embAbsData.clear(); m_embAbsData = tgtdsdat; m_editedflag = 1; return 0; } //角度修正 int EmbData::angleCorrection(s16 oft) { if (oft != 0) { s32 dx, dy, dr; double ax, ay, ar; int bdx, bdy; bdx = bdy = 0; int size = m_embAbsData.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("ary data less then head size"); return -1; } int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("absdat dataBegin err"); return -1; } int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("absdat data size err"); return -1; } DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; //中间数据针步 double addx,addy; addx = addy = 0; double s = 0; // 数据区 for (int j = 0; j < stepsize; j++) { if (j == 0)//第一针 { dx = absDataPtr->ax; dy = absDataPtr->ay; dr = absDataPtr->ar; } else { dx = absDataPtr->ax - ax; dy = absDataPtr->ay - ay; dr = absDataPtr->ar - ar; } //判断夹角是否大于60度 if(dr >= ANGLECORR || dr <= -ANGLECORR) { s = sqrt(bdx*bdx + bdy*bdy); if(s == 0) { addx = 0; addy = 0; } else { addx = bdx*oft/s; addy = bdy*oft/s; } absDataPtr--; if(absDataPtr->ctrl == DATA_SEWING) { absDataPtr->ax += addx; absDataPtr->ay += addy; } absDataPtr++; } ax = absDataPtr->ax; ay = absDataPtr->ay; ar = absDataPtr->ar; bdx = dx; bdy = dy; absDataPtr++; } } return 0; } int EmbData::angleCorrectionXY(s32 px, s32 nx, s32 py, s32 ny) { if(px == 0 && nx == 0 && py == 0 && ny == 0) { return -1; } s32 dx, dy, dr; double ax, ay, ar; int size = m_embAbsData.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("ary data less then head size"); return -1; } int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("absdat dataBegin err"); return -1; } int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("absdat data size err"); return -1; } DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; //中间数据针步 double addx,addy; addx = addy = 0; // 数据区 for (int j = 0; j < stepsize; j++) { if (j == 0)//第一针 { dx = absDataPtr->ax; dy = absDataPtr->ay; dr = absDataPtr->ar; } else { dx = absDataPtr->ax - ax; dy = absDataPtr->ay - ay; dr = absDataPtr->ar - ar; } //判断夹角是否大于60度 if(dr >= ANGLECORR || dr <= -ANGLECORR) { if(dx > 0) { addx = px; } else if(dx == 0) { DsAbsItem * prePtr = absDataPtr-1; double prex = prePtr ->ax; while(prex == absDataPtr->ax) { prePtr--; prex = prePtr->ax; if(prePtr == pData) { break; } } s32 cx = prex - absDataPtr->ax; if(cx < 0) { addx = px; } else { addx = 0 - nx; } } else { addx = 0 - nx; } if(dy > 0) { addy = py; } else if(dy == 0) { DsAbsItem * prePtr = absDataPtr-1; double prey = prePtr ->ay; while(prey == absDataPtr->ay) { prePtr--; prey = prePtr->ay; if(prePtr == pData) { break; } } s32 cy = prey - absDataPtr->ay; if(cy < 0) { addy = py; } else { addy = 0 - ny; } } else { addy = 0 - ny; } absDataPtr--; if(absDataPtr->ctrl == DATA_SEWING) { absDataPtr->ax += addx; absDataPtr->ay += addy; } absDataPtr++; } ax = absDataPtr->ax; ay = absDataPtr->ay; ar = absDataPtr->ar; absDataPtr++; } return 0; } //按固定针步重新拟合(用户可设置的参数,暂未用到) void EmbData::reFitByStep(s32 stepLen) { QList lineList; lineList.clear(); int stepLength = stepLen;//参数(300-800 单位0.01mm) LineItem item; item.absItemList.clear(); int dr = 0; unsigned char ctrl; double prer = 0; double ax, ay, ar; ax = ay = ar = 0; DsAbsItem absItem; memset(&absItem,0,sizeof(DsAbsItem)); //添加线段集合(夹角大于某个值时为新的一段线段) int datasize = m_embAbsData.size() - sizeof(DataDs16FileHead); if (datasize <= 0) { return; } int stepsize = datasize/sizeof(DsAbsItem); DsAbsItem * dataBeg = (DsAbsItem *)(m_embAbsData.data()+sizeof(DataDs16FileHead)); prer = dataBeg->ar; for (int i = 0; i < stepsize; i++) { ctrl = dataBeg->ctrl; dr = dataBeg->ar - prer; unsigned char nctrl,bctrl; if(i == stepsize-1) { nctrl = ctrl; } else { dataBeg++; nctrl = dataBeg->ctrl;//下一针步属性 dataBeg--; } if(i == 0) { bctrl = ctrl; } else { dataBeg--; bctrl = dataBeg->ctrl;//上一针步属性 dataBeg++; } if(ctrl != DATA_SEWING) { item.absItemList.append(*dataBeg); } //上一针非缝纫属性且当前针为缝纫属性 if(bctrl != DATA_SEWING && ctrl == DATA_SEWING) { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*dataBeg); } //下一针非缝纫针步与当前针为缝纫针步 else if(nctrl != DATA_SEWING && ctrl == DATA_SEWING) { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*dataBeg); } //上一针为缝纫针步与当前针非缝纫针步 else if(bctrl == DATA_SEWING && ctrl != DATA_SEWING) { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*dataBeg); } //下一针为缝纫针步与当前针非缝纫针步 else if(nctrl == DATA_SEWING && ctrl != DATA_SEWING) { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*dataBeg); } else if(ctrl == DATA_SEWING) { double angle = dr / 10000.0 * (180.0 / PI); if(angle > 30 || angle < -30)//新的一条线段(30度为分界) { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*dataBeg); } else { item.absItemList.append(*dataBeg); } } prer = dataBeg->ar; dataBeg++; } //开始重置针步(绝对坐标的线段集合) QByteArray nabsData; nabsData.clear(); double cx,cy,cr; cx = cy = cr = 0; int lSize = lineList.size(); for(int j = 0; j < lSize; j++) { int pSize = lineList[j].absItemList.size(); for(int m = 0; m < pSize; m++) { memset(&absItem,0,sizeof(DsAbsItem)); absItem = lineList[j].absItemList[m]; ctrl = absItem.ctrl; //absItem.ax = absItem.ax - minX; //absItem.ay = absItem.ay - minY; ax = absItem.ax; ay = absItem.ay; ar = absItem.ar; if(ctrl != DATA_SEWING) { nabsData.append((char*)&absItem,sizeof(DsAbsItem)); continue; } if(m == 0) { cx = ax; cy = ay; nabsData.append((char*)&absItem,sizeof(DsAbsItem)); } if(m == pSize - 1 && pSize > 1) { //最后一步如果超出长度就均分 int pos = nabsData.size()-sizeof(DsAbsItem); DsAbsItem * litem = (DsAbsItem *)((nabsData.data()+pos)); double curX = absItem.ax; double curY = absItem.ay; double preX = litem->ax; double preY = litem->ay; double ldis = sqrt(((curX-preX)/100.0*(curX-preX)/100.0)*10000.0+((curY-preY)/100.0*(curY-preY)/100.0)*10000.0); if(ldis > stepLength) { DsAbsItem addItem; memset(&addItem,0,sizeof(DsAbsItem)); addItem = absItem; if(litem->ay == absItem.ay)//y相同 { addItem.ay = absItem.ay; addItem.ax = (absItem.ax+litem->ax)/2; nabsData.append((char*)&addItem,sizeof(DsAbsItem)); nabsData.append((char*)&absItem,sizeof(DsAbsItem)); break; } else if(litem->ax == absItem.ax)//x相同 { addItem.ax = absItem.ax; addItem.ay = (absItem.ay+litem->ay)/2; nabsData.append((char*)&addItem,sizeof(DsAbsItem)); nabsData.append((char*)&absItem,sizeof(DsAbsItem)); break; } else { double k = ((double)(absItem.ay-litem->ay))/((double)(absItem.ax-litem->ay)); double cdis = ldis / 2; double r = atan(k); double x = cdis * cos(r); double y = cdis * sin(r); addItem.ax = litem->ax + x; addItem.ay = litem->ay + y; nabsData.append((char*)&addItem,sizeof(DsAbsItem)); nabsData.append((char*)&absItem,sizeof(DsAbsItem)); break; } } else { nabsData.append((char*)&absItem,sizeof(DsAbsItem)); break; } } double dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0); while(dis > stepLength) { QPoint firstPoint(0,0);//直线第一个点 if((m-1) >= 0) { // firstPoint.setX(lineList[j].absItemList[m-1].ax-minX); // firstPoint.setY(lineList[j].absItemList[m-1].ay-minY); firstPoint.setX(lineList[j].absItemList[m-1].ax); firstPoint.setY(lineList[j].absItemList[m-1].ay); } QPoint secondPoint;//直线第二个点 secondPoint.setX(ax); secondPoint.setY(ay); QPoint circlePoint;//圆心 circlePoint.setX(cx); circlePoint.setY(cy); QPoint p; if(secondPoint.x()-firstPoint.x() == 0) { p.setX(secondPoint.x()); //int y = (secondPoint.y()/stepLength)*stepLength; //int y = (secondPoint.y()+firstPoint.y())/2; //取出上一点的坐标 int pos = nabsData.size()-sizeof(DsAbsItem); DsAbsItem * litem = (DsAbsItem *)((nabsData.data()+pos)); int y = 0; if(litem->ay >= secondPoint.y()) { y = litem->ay - stepLength; } else { y = litem->ay + stepLength; } p.setY(y); cx = p.x(); cy = p.y(); if(cx < 0 || cy < 0) { //qDebug()<= (stepLength-10)) { bl3 = true; } if(bl3) { if(bl1 == true && bl2 == true) { double dis1 = sqrt(((ax-x1)/100.0*(ax-x1)/100.0)*10000.0+((ay-y1)/100.0*(ay-y1)/100.0)*10000.0); double dis2 = sqrt(((ax-x2)/100.0*(ax-x2)/100.0)*10000.0+((ay-y2)/100.0*(ay-y2)/100.0)*10000.0); if(dis1 > dis2) { cx = x2; cy = y2; } else { cx = x1; cy = y1; } absItem.ax = cx; absItem.ay = cy; nabsData.append((char*)&absItem,sizeof(DsAbsItem)); dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0); } else { if(bl1) { p.setX(x1); p.setY(y1); } else if(bl2) { p.setX(x2); p.setY(y2); } else { qDebug()<<"bl1&bl2=false"; break; } cx = p.x(); cy = p.y(); if(cx < 0 || cy < 0) { //qDebug()<dataSize = stepsize*sizeof(DsAbsItem); // 数据字节数 m_pEmbDs16Head->itemNums = stepsize; // 数据项个数 m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 数据累加校验和 m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) u32 fileID = 0; fileID = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 原始数据累加校验和 m_pEmbDs16Head->fileid = fileID; //中间数据的 fileid = m_embAbsData.clear(); m_embAbsData.append((char *)(m_pEmbDs16Head), sizeof(DataDs16FileHead)); m_embAbsData.append(nabsData); } #define MERGEANGLE PI/180*70*10000 //70度 void EmbData::reFitLine(s32 stepLen) { QList lineList; lineList.clear(); double stepLength = stepLen;//参数(200-800 单位0.01mm) if(stepLength <= 0) { return; } LineItem item; item.absItemList.clear(); int dr = 0; double prer = 0; DsAbsItem preItem; memset(&preItem,0,sizeof(DsAbsItem)); s16 addOftFlag = 0; s16 addSewFlag = 0; DsAbsItem absItem; memset(&absItem,0,sizeof(DsAbsItem)); //添加线段集合(夹角大于某个值时为新的一段线段) int datasize = m_embAbsData.size() - sizeof(DataDs16FileHead); if (datasize <= 0) { return; } int stepsize = datasize/sizeof(DsAbsItem); memcpy((char*)m_pEmbDs16Head,m_embAbsData.data(),sizeof(DataDs16FileHead)); DsAbsItem * dataBeg = (DsAbsItem *)(m_embAbsData.data()+sizeof(DataDs16FileHead)); prer = dataBeg->ar; for (int i = 0; i < stepsize; i++) { dr = dataBeg->ar - prer; while (dr < -PI10000) { dr += PI20000; } while (dr > PI10000) { dr -= PI20000; } if(dataBeg->ctrl != DATA_SEWING) { if(addSewFlag == 1) { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*(dataBeg-1)); addSewFlag = 0; } item.absItemList.append(*dataBeg); addOftFlag = 1; } else { addSewFlag = 1; if(addOftFlag == 1) { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*(dataBeg-1)); item.absItemList.append(*dataBeg); addOftFlag = 0; } if((abs(dr) > MERGEANGLE))//新的一条线段 { lineList.append(item); item.absItemList.clear(); item.absItemList.append(*(dataBeg-1)); item.absItemList.append(*dataBeg); } else { item.absItemList.append(*dataBeg); } } prer = dataBeg->ar; dataBeg++; } //开始重置针步(绝对坐标的线段集合) QByteArray nabsData; nabsData.clear(); QList outList; int lSize = lineList.size(); for(int i = 0; i < lSize; i++) { outList.clear(); int pSize = lineList[i].absItemList.size(); if(pSize == 1)//只有一个点 { nabsData.append((char*)&lineList[i].absItemList[0],sizeof(DsAbsItem)); } else { getCurvePointFillLine(lineList[i].absItemList,stepLength,outList); //从第二段开始起始点不向绝对坐标中添加,如果添加会出现空针步 int idx = 0; if(i > 0) { idx = 1; } for(int m = idx; m < outList.size(); m++) { nabsData.append((char*)(&outList[m]), sizeof(DsAbsItem)); } } } //重新计算ar stepsize = nabsData.size() / sizeof(DsAbsItem); if(stepsize <= 0) { return; } //最后添加结束码,ax和ay是最后一针的 DsAbsItem dsAbsItem; memcpy(&dsAbsItem,nabsData.data()+(nabsData.size() - sizeof(DsAbsItem)),sizeof(DsAbsItem)); dsAbsItem.ctrl = DATA_END; nabsData.append((char*)(&dsAbsItem), sizeof(DsAbsItem)); stepsize++; DsAbsItem * absDataPtr = (DsAbsItem *)(nabsData.data()); double minX, maxX, minY, maxY; minX = S32_MAX; maxX = S32_MIN; minY = S32_MAX; maxY = S32_MIN; double prex,prey,curx,cury,dx,dy,ar; prex = prey = curx = cury = dx = dy = ar = 0; prex = absDataPtr->ax; prey = absDataPtr->ay; for (int i = 0; i < stepsize; i++) { curx = absDataPtr->ax; cury = absDataPtr->ay; dx = curx - prex; dy = cury - prey; double tar = atan2(dy,dx); ar = (tar*10000+0.5*(tar>0?1:-1)); absDataPtr->ar = ar; if(curx > maxX) { maxX = curx; } if(curx < minX) { minX = curx; } if(cury > maxY) { maxY = cury; } if(cury < minY) { minY = cury; } prex = curx; prey = cury; absDataPtr++; } //修改绝对坐标数据 m_pEmbDs16Head->dataSize = stepsize*sizeof(DsAbsItem); // 数据字节数 m_pEmbDs16Head->itemNums = stepsize; // 数据项个数 m_pEmbDs16Head->maxX = maxX; m_pEmbDs16Head->minX = minX; m_pEmbDs16Head->maxY = maxY; m_pEmbDs16Head->minY = minY; m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 数据累加校验和 m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) u32 fileID = 0; fileID = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length()); // 原始数据累加校验和 m_pEmbDs16Head->fileid = fileID; //中间数据的 fileid = m_embAbsData.clear(); m_embAbsData.append((char *)(m_pEmbDs16Head), sizeof(DataDs16FileHead)); m_embAbsData.append(nabsData); } //移动起始点,左边,前边 int EmbData::moveStartPoint(short left, short front) { if(m_pEmbDs16Head == NULL){return -1;} if(m_embDs16Data.size() <= 0){return -1;} m_pEmbDs16Head->anchorX += left; m_pEmbDs16Head->anchorY += front; m_pEmbDs16Head->beginX += left; m_pEmbDs16Head->beginY += front; //将最大最小值写入文件头 m_pEmbDs16Head->maxX += left; m_pEmbDs16Head->minX += left; m_pEmbDs16Head->maxY += front; m_pEmbDs16Head->minY += front; m_maxX += left; m_minX += left; m_maxY += front; m_minY += front; memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead)); return 0; } void EmbData::moveDataBeginPonit(s32 left, s32 front) { if((u32)m_embAbsData.size() > sizeof(DataDs16FileHead)){ DataDs16FileHead *dhead = (DataDs16FileHead *)(m_embAbsData.data()); dhead->beginX += left; dhead->beginY += front; dhead->maxX += left; dhead->minX += left; dhead->maxY += front; dhead->minY += front; } } void EmbData::appendAEmbAbsFile(QString filePath, QByteArray array, int mirror) { m_filePath = filePath; convertAbsDat(array,mirror);//是否镜像、旋转、缩放的转换 m_embAbsData.clear(); m_embAbsData.append(array); m_editedflag = 1; } void EmbData::setAbsDat(QByteArray & dat) { m_embAbsData = dat; } QByteArray & EmbData::getAbsDat(void) { return m_embAbsData; } int EmbData::getPosInfoFromNeedleIdx(int stitchIdx, int &posx, int &posy, int &colorIdx) { if (m_editedflag != 0) { createEmbDs16FromAbs(); } posx = 0; posy = 0; colorIdx = 0; // 文件头 int size = m_embDs16Data.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("m_embDs16Data data less then head size"); return -1; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data()); int datasize = size - sizeof(DataDs16FileHead); int stepsize = datasize/sizeof(Ds16Item); if (stepsize <= 0) { qDebug("ds16 data size err"); return -1; } Ds16Item * ds16DataPtr; Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead)); ds16DataPtr = pData; posx = pDsHead->beginX; posy = pDsHead->beginY; colorIdx = 1; if (stitchIdx <= 0) { return 0; } if (stitchIdx > datasize) { stitchIdx = datasize; } int dx, dy; u8 ctrl, attr; for (int i = 0; i < stitchIdx; i++) { ctrl = ds16DataPtr->ctrl; attr = ds16DataPtr->attr; dx = ds16DataPtr->dx; dy = ds16DataPtr->dy; if (ctrl == DATA_CHGND) { colorIdx++; } if ((attr&0x80) != 0) { dx *= -1; } if ((attr&0x40) != 0) { dy *= -1; } posx += dx; posy += dy; ds16DataPtr++; } return 0; } //设置起始点 void EmbData::setStartPosition(int x, int y) { if(m_pEmbDs16Head == NULL){return;} if(m_embDs16Data.size() <= 0){return;} //旧的起始点坐标 int oldBeginX = m_pEmbDs16Head->beginX; int oldBeginY = m_pEmbDs16Head->beginY; m_pEmbDs16Head->beginX = x; m_pEmbDs16Head->beginY = y; //新的起始点坐标与旧的起始点坐标的差值 int cx = x - oldBeginX; int cy = y - oldBeginY; //重新计算最大最小XY double maxX = m_pEmbDs16Head->maxX + cx; double minX = m_pEmbDs16Head->minX + cx; double maxY = m_pEmbDs16Head->maxY + cy; double minY = m_pEmbDs16Head->minY + cy; //将最大最小值写入文件头 m_pEmbDs16Head->maxX = maxX; m_pEmbDs16Head->minX = minX; m_pEmbDs16Head->maxY = maxY; m_pEmbDs16Head->minY = minY; //修复偶尔点击中间按钮花样消失的bug m_maxX = maxX; m_minX = minX; m_maxY = maxY; m_minY = minY; memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead)); qDebug()<<"m_maxX"<beginX *= factorx; pDsHead->beginY *= factory; // 数据缩放 for (int j = 0; j < stepsize; j++) { double ax = absDataPtr->ax; double ay = absDataPtr->ay; ax *= factorx; ay *= factory; absDataPtr->ax = ax; absDataPtr->ay = ay; absDataPtr++; } m_editedflag = 1; return 1; } int EmbData::setMirror(int mirror) { if (mirror == 0) // 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像 { return 0; } int mirrorx = 1; //x轴 int mirrory = 1; //y轴 int mirrorr = 0; int mirrorrdir = 0; if(mirror == 1 || mirror == 3) { mirrorx = -1; } if(mirror == 2 || mirror == 3) { mirrory = -1; } if(mirror == 1) { mirrorr = 1*PI*10000; mirrorrdir = -1; } else if (mirror == 2) { mirrorr = 2*PI*10000; mirrorrdir = -1; } else if (mirror == 3) { mirrorr = 1*PI*10000; mirrorrdir = 1; } // 文件头 const QByteArray & ary = m_embAbsData; int size = ary.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("ary data less then head size"); return -1; } int datasize = size - sizeof(DataDs16FileHead); int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("dat data size err"); return -1; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data()); //在最大最小xy中 对起始点进行镜像处理 int bx = pDsHead->beginX; int by = pDsHead->beginY; if(mirrorx == -1) pDsHead->beginX = pDsHead->maxX - (bx - pDsHead->minX); if(mirrory == -1) pDsHead->beginY = pDsHead->maxY - (by - pDsHead->minY); //beginR的旋转 double br = pDsHead->beginR; if (mirrorrdir > 0) { br = br + mirrorr; } else if (mirrorrdir < 0) { br = mirrorr - br; } while (br > 2*PI * 10000) { br -= 2*PI * 10000; } while (br < -2*PI * 10000) { br += 2*PI * 10000; } pDsHead->beginR = br; DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; // 数据镜像 for (int j = 0; j < stepsize; j++) { double ax = absDataPtr->ax; double ay = absDataPtr->ay; double ar = absDataPtr->ar; int rx = ax * mirrorx; //相对坐标 乘负数则数据镜像 int ry = ay * mirrory; if (mirrorrdir > 0) { ar = ar + mirrorr; } else if (mirrorrdir < 0) { ar = mirrorr - ar; } while (ar > 2*PI * 10000) { ar -= 2*PI * 10000; } while (ar < -2*PI * 10000) { ar += 2*PI * 10000; } absDataPtr->ax = rx; absDataPtr->ay = ry; absDataPtr->ar = ar; absDataPtr++; } m_editedflag = 1; return 1; } //flag :true代表顺时针方向 int EmbData::setRotate90(bool flag) { // 文件头 const QByteArray & ary = m_embAbsData; int size = ary.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("ary data less then head size"); return -1; } int datasize = size - sizeof(DataDs16FileHead); int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("dat data size err"); return -1; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data()); int maxX = pDsHead->maxX; int maxY = pDsHead->maxY; int bx = pDsHead->beginX; int by = pDsHead->beginY; if(flag){ //正向旋转90 pDsHead->beginX = maxY - by; pDsHead->beginY = bx; } else{ pDsHead->beginX = by; pDsHead->beginY = maxX - bx; } DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; for (int j = 0; j < stepsize; j++) { double ax = absDataPtr->ax; double ay = absDataPtr->ay; int rx, ry; if(flag){ //正向旋转90 rx = -ay; ry = ax; }else{ rx = ay; ry = -ax; } absDataPtr->ax = rx; absDataPtr->ay = ry; absDataPtr++; } m_editedflag = 1; return 1; } /// /// \brief //获得下一个图元的第一缝纫针步 /// \param curIndex /// \return /// int EmbData::getNextElementIndex(int curIndex) { // ds16数据 int size = m_embDs16Data.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("16 data less then head size"); return -1; } int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("dat dataBegin err"); return -1; } int stepsize = datasize/sizeof(Ds16Item); if (stepsize <= 0) { qDebug("ds16 data size err"); return -1; } Ds16Item * ds16DataPtr = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead)); ds16DataPtr = ds16DataPtr + curIndex; u8 curByte =ds16DataPtr->ctrl; //当前状态 ds16DataPtr ++; curIndex ++; int i = curIndex; for (; i < stepsize; i++) { if(curByte != DATA_SEWING) { if(ds16DataPtr->ctrl == DATA_SEWING) break; }else{ if(ds16DataPtr->ctrl != DATA_SEWING) curByte = ds16DataPtr->ctrl; } ds16DataPtr++; } return i; } /// /// \brief //上一个图元(当前为跨步时)或当前图元(当前为缝纫时)的第一缝纫针步 /// \param curIndex /// \return /// int EmbData::getPreOrThisElementIndex(int curIndex) { // ds16数据 int size = m_embDs16Data.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("16 data less then head size"); return -1; } int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("dat dataBegin err"); return -1; } int stepsize = datasize/sizeof(Ds16Item); if (stepsize <= 0) { qDebug("ds16 data size err"); return -1; } Ds16Item * ds16DataPtr = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead)); ds16DataPtr = ds16DataPtr + curIndex; u8 curByte =ds16DataPtr->ctrl; //当前状态 ds16DataPtr--; curIndex --; int i = curIndex; for (; i > 0; i--) { //如果当前是缝纫数据,找到其他的就返回下一针 if(curByte == DATA_SEWING) { if(ds16DataPtr->ctrl != DATA_SEWING) break; }else{ //找到其他的就返回下一针 if(ds16DataPtr->ctrl == DATA_SEWING) curByte = DATA_SEWING; } ds16DataPtr--; } return ++i; } int EmbData::setRotate(int dr) { double rr = (dr * PI / 180) * 10000; //转换为弧度 if (dr == 0 || dr == 360) { return 0; } double angle, sina, cosa; #if (1) // 因为计算三角函数有问题,现在只支持 1度,10度,90度 switch(dr) { case 1: sina = 0.01745240643728351281941897851632; cosa = 0.99984769515639123915701155881391; break; case 10: sina = 0.17364817766693034885171662676931; cosa = 0.98480775301220805936674302458952; break; case 90: sina = 1; cosa = 0; break; case -1: sina = -0.01745240643728351281941897851632; cosa = 0.99984769515639123915701155881391; break; case -10: sina = -0.17364817766693034885171662676931; cosa = 0.98480775301220805936674302458952; break; case -90: sina = -1; cosa = 0; break; default: angle = (dr * PI) / 180.0; sina = (double)qSin(angle); cosa = (double)qCos(angle); break; } #else angle = (dr * PI) / 180.0; sina = (double)qSin(angle); cosa = (double)qCos(angle); #endif // 文件头 const QByteArray & ary = m_embAbsData; int size = ary.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("ary data less then head size"); return -1; } int datasize = size - sizeof(DataDs16FileHead); int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("dat data size err"); return -1; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data()); //beginR的旋转 double br = pDsHead->beginR + rr; while (br > 2*PI * 10000) { br -= 2*PI * 10000; } while (br < -2*PI * 10000) { br += 2*PI * 10000; } pDsHead->beginR = br; DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; // 数据旋转 for (int j = 0; j < stepsize; j++) { // 变换前点坐标 double ax = absDataPtr->ax; double ay = absDataPtr->ay; double ar = absDataPtr->ar + rr; while (ar > 2*PI * 10000) { ar -= 2*PI * 10000; } while (ar < -2*PI * 10000) { ar += 2*PI * 10000; } // 变换后点的坐标 double rax = (ax*cosa - ay*sina); double ray = (ax*sina + ay*cosa); absDataPtr->ax = rax; absDataPtr->ay = ray; absDataPtr->ar = ar; absDataPtr++; } m_editedflag = 1; return 1; } //此函数转换传入的绝对坐标值,是否取镜像及反复时数据之间的间距 void EmbData::convertAbsDat(QByteArray &dat, int mirror) { //无镜像、xy间距、角度旋转、缩放比例都为0时数据无需转换 if(mirror == 0 && m_spaceX == 0 && m_spaceY == 0 ) { return; } int size = dat.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("data less then head size"); return; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(dat.data()); int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("dat dataBegin err"); return; } int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("dat data size err"); return; } DsAbsItem * pData = (DsAbsItem *)(dat.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; //-------- //镜像数值不为0---开始 // mirror 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像 int mirrorx = 1; int mirrory = 1; int mirrorr = 1; if(mirror == 1 || mirror == 3) { mirrorx = -1; mirrorr = -1; } if(mirror == 2 || mirror == 3) { mirrory = -1; mirrorr = -1; } // 镜像文件头转换 if(mirror != 0) { pDsHead->beginX = pDsHead->beginX * mirrorx; pDsHead->beginY = pDsHead->beginY * mirrory; } // 镜像或列表间距不为0 if(mirror != 0 || m_spaceX != 0 || m_spaceY != 0) { //图形先居中,起始点在加上偏移 int centerx = (m_maxX + m_minX)/2; int centery = (m_maxY + m_minY)/2; int rx = (pDsHead->beginX - centerx) * mirrorx; int ry = (pDsHead->beginY - centery) * mirrory; int beginx = rx + centerx; int beginy = ry + centery; //用下面两行代码,否则反复方式为Y轴对称或XY对称时不对 pDsHead->beginX = beginx + m_spaceX; pDsHead->beginY = beginy + m_spaceY; } //镜像数值不为0---结束 absDataPtr = pData; //镜像有变换时运动步才转换 double dx, dy, dr; if(mirror != 0) { for (int i = 0; i < stepsize; i++) { // 读入一个针步数据 dx = absDataPtr->ax; dy = absDataPtr->ay; dr = absDataPtr->ar; //镜像不为0 if(mirror != 0) { dx = dx * mirrorx; dy = dy * mirrory; dr = dr * mirrorr; } absDataPtr->ax = dx; absDataPtr->ay = dy; absDataPtr->ar = dr; absDataPtr++; } } return; } int EmbData::calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, DsAbsItem item) { DsAbsItem absItem; memcpy(&absItem,&item,sizeof(DsAbsItem)); s32 dx, dy; double length; double tmp; int count; int i; double stepx, stepy; double sx, sy; int actx, acty; double k; if(x0 == x1 && y0 == y1) { return 0; } if(x0 > x1) { sx = -1.0; // x反向 } else { sx = 1.0; } if(y0 > y1) { sy = -1.0; // y反向 } else { sy = 1.0; } // 开始分割针步 length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1)); tmp = length/step; /* 实际针步数 */ count = floor(tmp); /* 最少整针步数 */ if (tmp - count > 0.01) { count += 1; } if (count == 0 && length > 0) // 短直线 { count = 1; } tmp = 0; actx = x0; acty = y0; if (x1 != x0 && y1 == y0) // 横直线 { for (i = 0; i < count; i++) { tmp = ((i+1)*(length)/count)*sx+x0; // 实际针步 stepx = tmp - actx; dx = (s32)(stepx+0.5*sx); dy = 0; actx += dx; absItem.ax = actx; absItem.ay = y0; absAry.append((char*)&absItem,sizeof(DsAbsItem)); } } else if (x1 == x0 && y1 != y0) // 竖直线 { for (i = 0; i < count; i++) { tmp = ((i+1)*(length)/count)*sy + y0; // 实际针步 stepy = tmp - acty; dx = 0; dy = (s32)(stepy+0.5*sy); acty += dy; absItem.ax = x0; absItem.ay = acty; absAry.append((char*)&absItem,sizeof(DsAbsItem)); } } else if(x1 != x0 && y1 != y0) // 任意斜线 { k = (y1-y0)/(x1-x0); for (i = 0; i < count; i++) { tmp = ((i+1)*(length)/count); stepx = fabs(tmp*cos(atan(k)))*sx + x0; // 实际针步x stepy = fabs(tmp*sin(atan(k)))*sy + y0; // 实际针步y dx = (s32)(stepx-actx+0.5*sx); dy = (s32)(stepy-acty+0.5*sy); actx += dx; acty += dy; absItem.ax = actx; absItem.ay = acty; absAry.append((char*)&absItem,sizeof(DsAbsItem)); } } else { printf("what's this?\n"); } return count; } //花版的定位点为绝对坐标数据点,起始点为相对于定位点的相对坐标点,第一针为相对于起始点的坐标点 //有的花版起始点有偏移量,第一针偏移量为0,有的花版起始点偏移量为0,第一针有偏移量 //所以ds16文件头定位点坐标就是花版中的定位点,起始点坐标为花版中的定位点坐标+起始点坐标+第一针的坐标,同时ds16数据的第一针坐标偏移应置为0 //生成DS16数据 int EmbData::createEmbDs16FromAbs() { #if(0) QString ds16FilePath = m_filePath + ".ds16"; QFile file(ds16FilePath); if(file.exists())//存在ds16文件 { if(!file.open(QIODevice::ReadOnly)) { qDebug() << "open file fail when read, path =" << m_filePath; return -1; } m_embDs16Data = file.readAll(); file.close(); if(m_embDs16Data.size() <= 0) { return -1; } memcpy(m_pEmbDs16Head, m_embDs16Data.data(), sizeof(DataDs16FileHead)); // 文件名称 m_minX = m_pEmbDs16Head->minX; m_maxX = m_pEmbDs16Head->maxX; m_minY = m_pEmbDs16Head->minY; m_maxY = m_pEmbDs16Head->maxY; m_beginX = m_pEmbDs16Head->beginX; m_beginY = m_pEmbDs16Head->beginY; m_editedflag = 0; return 0; } #endif if (m_editedflag != 0) { m_minX = S32_MAX; m_maxX = S32_MIN; m_minY = S32_MAX; m_maxY = S32_MIN; m_embDs16Data.clear(); QString name; QByteArray tgtdsdat; tgtdsdat.clear(); u8 ctrlByte; u8 attrByte; WORD actionWord; //附加动作 s32 dx, dy, dr; u16 len; double ax, ay, ar; int actx, acty, actr; int ddx, ddy,ddr; int beginx, beginy, beginr, anchorx, anchory; int minx, miny, maxx, maxy; int colornum = 1; int jumpNeedleNum = 0;//跳针数 actx = 0; acty = 0; actr =0; beginx = 0; beginy = 0; beginr = 0; anchorx = anchory = 0; int totalstepsize = 0; memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead)); const QByteArray & ary = m_embAbsData; int size = ary.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("ary data less then head size"); return -1; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data()); //fileId = pDsHead->fileid; int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("absdat dataBegin err"); return -1; } int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("absdat data size err"); return -1; } DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; //中间数据针步 //----- // 文件名称 QString str = QString::fromLocal8Bit(pDsHead->fileName); name = str; //str.sprintf("%s", pDsHead->fileName); //name += " "; //name += str; minx = absDataPtr->ax; maxx = absDataPtr->ax; miny = absDataPtr->ay; maxy = absDataPtr->ay; // 数据区 qDebug()<<"stepsize:"<ctrl; attrByte = absDataPtr->attr;//绝对数据的属性字节 actionWord = absDataPtr->action; ax = absDataPtr->ax;//绝对数据的X位置 ay = absDataPtr->ay; ar = absDataPtr->ar; // 轮廓 if (minx > ax) { minx = ax; } if (maxx < ax) { maxx = ax; } if (miny > ay) { miny = ay; } if (maxy < ay) { maxy = ay; } if (j == 0)//第一针 { beginx = ax; beginy = ay; beginr = ar; actx = ax; acty = ay; actr = ar; anchorx = pDsHead->anchorX; anchory = pDsHead->anchorY; ddx = 0; ddy = 0; //让ddr等于0,因为在datafiledsr中将beginR置为0而非第一针的角度,所以不应该用 absDataPtr->ar - pDsHead->beginR //如果beginR等于第一针的角度,那么第一针的ddr就应该是0 ddr = 0; //过滤掉空针 if(ddx== 0 && ddy == 0) { actx += ddx; acty += ddy; actr += ddr; absDataPtr++; continue; } } else { ddx = ax - actx; ddy = ay - acty; ddr = ar -actr; } if( ctrlByte == DATA_END || ctrlByte == DATA_PAUSE || ctrlByte == DATA_CHGND || ctrlByte == DATA_CUTTRD || ctrlByte == DATA_ANGLE || 0 ) { ddx = 0; ddy = 0; ddr = 0; } dx = ddx; dy = ddy; dr = ddr; actx += ddx; acty += ddy; actr += ddr; while (dr < -PI10000) { dr += PI20000; } while (dr > PI10000) { dr -= PI20000; } if ( 0 && (ctrlByte == DATA_END || ctrlByte == DATA_NULL)) { qDebug()<< "增加剪线" < maxStep && ctrlByte == DATA_SEWING) if(xyLen > maxStep) { s16 addx,addy; addx = addy = 0; //分割针步 double splitVal = 400.0;//分割针步为400 s32 stepNum = xyLen / splitVal;//拆分几步 double lastStep = (double)((int)xyLen % (int)splitVal); double addStep = lastStep / stepNum; double stepX = 0; double stepY = 0; double stepDr = 0; for(int m = 0; m < stepNum; m++) { stepX = 0; stepY = 0; stepDr = 0; memset(&ds16Item,0,sizeof(Ds16Item));//初始化结构体 stepX = dx * splitVal / xyLen + dx * addStep / xyLen; stepY = dy * splitVal / xyLen + dy * addStep / xyLen; if(m == 0) { stepDr = dr; } ds16Item.dx = qRound(stepX);//四舍五入 ds16Item.dy = qRound(stepY); if (m == stepNum-1) {// 最后一针,消除累计误差 ds16Item.dx = dx - addx; ds16Item.dy = dy - addy; } else { addx += ds16Item.dx; addy += ds16Item.dy; } ds16Item.ctrl = ctrlByte; len = sqrt(ds16Item.dx*ds16Item.dx + ds16Item.dy*ds16Item.dy); ds16Item.attr = attrByte; ds16Item.action[0] = 0; ds16Item.action[1] = 0; ds16Item.dr = stepDr; ds16Item.len = len; memset(ds16Item.rev,0,sizeof(ds16Item.rev)); tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item)); totalstepsize++; } } else { len = sqrt(dx*dx + dy*dy); ds16Item.ctrl = ctrlByte; ds16Item.attr = attrByte; memcpy(ds16Item.action,&actionWord,sizeof(actionWord)); ds16Item.dx = dx; ds16Item.dy = dy; ds16Item.dr = dr; ds16Item.len = len; memset(ds16Item.rev,0,sizeof(ds16Item.rev)); tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));//ds16针步 totalstepsize++; } if (ctrlByte == DATA_CHGND) { colornum++; } if (ctrlByte == DATA_OFFSET) { jumpNeedleNum++;//跨步总数加1 } absDataPtr++; } if (m_minX > minx) { m_minX = minx; } if (m_minX > maxx) { m_minX = maxx; } if (m_maxX < minx) { m_maxX = minx; } if (m_maxX < maxx) { m_maxX = maxx; } if (m_minY > miny) { m_minY = miny; } if (m_minY > maxy) { m_minY = maxy; } if (m_maxY < miny) { m_maxY = miny; } if (m_maxY < maxy) { m_maxY = maxy; } // 针数 int newstepnum = tgtdsdat.size() / sizeof(Ds16Item); qDebug()<< "newstepnum" < 0) { // 修改文件头 int namelen = name.size(); if (namelen > HEAD_NAME_STR_LEN) { namelen = HEAD_NAME_STR_LEN; } QByteArray array = name.toLocal8Bit().data(); int asize = array.length(); memcpy(m_pEmbDs16Head->fileName, array, asize); // 文件名称 m_pEmbDs16Head->dataSize = newstepnum*sizeof(Ds16Item); // 数据字节数 m_pEmbDs16Head->itemNums = newstepnum; // 数据项个数 m_pEmbDs16Head->bytesPerItem = sizeof(Ds16Item); // 每项占的字节数 m_pEmbDs16Head->bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小 m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(tgtdsdat.data()) , m_pEmbDs16Head->dataSize); // 数据累加校验和 m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) m_pEmbDs16Head->fileid = m_pEmbDs16Head->checkCrc; m_pEmbDs16Head->anchorX = anchorx; // 定位点坐标X m_pEmbDs16Head->anchorY = anchory; // 定位点坐标Y, 设置为0,作为基准 m_pEmbDs16Head->beginX = beginx; // 数据起点坐标X m_pEmbDs16Head->beginY = beginy; // 数据起点坐标Y m_pEmbDs16Head->beginR = beginr; // 数据起点坐标R //-rq m_pEmbDs16Head->minX = m_minX; m_pEmbDs16Head->maxX = m_maxX; m_pEmbDs16Head->minY = m_minY; m_pEmbDs16Head->maxY = m_maxY; // 轮廓范围,使用重新计算之后的值 //中间数据的文件头 // 添加文件头 m_embDs16Data.append((char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));//ds16头文件存在ds16中 // 添加文件数据 m_embDs16Data.append(tgtdsdat); } #if(1) //保存成ds16文件 QString ds16FilePath = m_filePath + ".ds16"; QFile file(ds16FilePath); if(file.exists())//存在ds16文件 { QFile::remove(ds16FilePath); } if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "open file fail when wirte, path =" << m_filePath; return -1; } else { file.write(m_embDs16Data); file.close(); } #endif } m_editedflag = 0; return 0; } int EmbData::reCalcDataChecksum() { return 0; } //绘制针数索引的跟踪笔 void EmbData::drawNeedleIdxPen(int x, int y, QPainter &painter) { //贴图的xy和画笔的xy值相同 m_penX = x; m_penY = y; m_penPix = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像 QPen pen; QColor color; //绘制深灰色画笔 pen.setWidth(2); color.setRgb(60,60,60);//深灰色 pen.setColor(color); painter.setPen(pen); painter.drawLine(x-4, y-28, x-4, y-8);//画左"|" painter.drawLine(x+4, y-28, x+4, y-8); //画右"|" painter.drawEllipse(x-1, y-10, 2, 2);//画中心"°" painter.drawLine(x-4, y-8, x, y);//画左"\"(笔尖) painter.drawLine(x+4, y-8, x, y); //画右"/"(笔尖) //绘制深红色画笔 pen.setWidth(1); color.setRgb(174,60,64);//深红色 pen.setColor(color); painter.setPen(pen); painter.drawLine(x-3, y-28, x-3, y-8);//画左"|" painter.drawLine(x+5, y-28, x+5, y-8); //画右"|" painter.drawEllipse(x-2, y-12, 3, 3);//画中心"°" painter.drawLine(x-3, y-8, x, y);//画左"\"(笔尖) painter.drawLine(x+5, y-8, x, y); //画右"/"(笔尖) } void EmbData::drawFork(int x, int y, QPainter &painter) { //贴图的xy和画笔的xy值相同 m_penX = x; m_penY = y; m_penPix = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像 QPen pen; QColor color; //绘制深灰色画笔 pen.setWidth(2); color.setRgb(228,42,48); pen.setColor(color); painter.setPen(pen); painter.drawLine(x-8, y-8, x-3, y-3);// \上一半 painter.drawLine(x+8, y-8, x+3, y-3);// /上一半 painter.drawLine(x+3, y+3, x+8, y+8); painter.drawLine(x-3, y+3, x-8, y+8); } void EmbData::drawFork(int x, int y, QPainter &painter, int index, bool isDraw) { m_penPoint[index].setX(x); m_penPoint[index].setY(y); m_penHeadPix[index] = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像 QPen pen; QColor color; if(isDraw){ //绘制深灰色画笔 pen.setWidth(2); color.setRgb(228,42,48); pen.setColor(color); painter.setPen(pen); painter.drawLine(x-8, y-8, x-3, y-3);// \上一半 painter.drawLine(x+8, y-8, x+3, y-3);// /上一半 painter.drawLine(x+3, y+3, x+8, y+8); painter.drawLine(x-3, y+3, x-8, y+8); } } //擦除针数索引的跟踪笔 void EmbData::eraseNeedleIdxPen(QPainter &painter) { //贴图的xy和画笔的xy值相同 painter.drawPixmap(m_penX-20,m_penY-30,m_penPix); } void EmbData::eraseNeedleIdxPen(QPainter &painter, int index) { painter.drawPixmap(m_penPoint[index].x()-20,m_penPoint[index].y()-30,m_penHeadPix[index]); } void EmbData::getCurvePointFillLine(QList &inList, double indRunLen, QList &outList) { DsAbsItem dPoint1, dPoint2, dPoint3; double dTatol, dLen1, dLen2, dSpace; long lSum, lCount; //计算总的线段长 int iCountPoint = inList.size(); if(iCountPoint <= 0) { return; } getTotalDistanceFillLine(&inList, dTatol); if(dTatol == 0) return; lSum = (long)round(dTatol / indRunLen + 0.1667); dSpace = dTatol / (double)lSum; if(lSum == 0) lSum = 1; dPoint1 = inList[0]; outList.append(dPoint1);//添加第一个点 dPoint2 = dPoint1; dLen1 = dSpace; dLen2 = 0; int i = 0; for(lCount = 0; lCount < lSum; lCount++) { while(i < inList.size()-1 && dLen2 < dLen1) { dLen1 -= dLen2; dPoint1 = dPoint2; i++; dPoint2 = inList[i]; dLen2 = sqrt((dPoint1.ax - dPoint2.ax) * (dPoint1.ax - dPoint2.ax) + (dPoint1.ay - dPoint2.ay) * (dPoint1.ay - dPoint2.ay)); } if(dLen1 < dLen2) { getPointInSectFillLine(dPoint1, dPoint2, dLen1, dPoint3); } else { dPoint3 = dPoint2; } outList.append(dPoint3); dLen2 -= dLen1; dLen1 = dSpace; dPoint1 = dPoint3; } } int EmbData::getTotalDistanceFillLine(QList *pPointList, double &dTotal) { DsAbsItem dPoint, dNext; double d; dTotal = 0; int i = 0; long lSum = (long)pPointList->count(); if(lSum > 1) { while(i < pPointList->size()) { dPoint = pPointList->at(i); i++; if(i < pPointList->size()) { dNext = pPointList->at(i); d = sqrt((dPoint.ax - dNext.ax) * (dPoint.ax - dNext.ax) + (dPoint.ay- dNext.ay) * (dPoint.ay- dNext.ay)); dTotal += d; } else { break; } } } return 0; } bool EmbData::getPointInSectFillLine(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp) { bool bRes; DsAbsItem dpoint[3]; dpoint[0] = p1; dpoint[1] = p2; dpoint[2] = outp; outp = dpoint[1]; bRes = getPointAtSect(dpoint[0], dpoint[1], d, dpoint[2]); outp.ax = dpoint[2].ax; outp.ay = dpoint[2].ay; return bRes; } bool EmbData::getPointAtSect(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp) { double s = sqrt((p1.ax - p2.ax) * (p1.ax - p2.ax) + (p1.ay - p2.ay) * (p1.ay - p2.ay)); if(fabs(s) < ZERO) { if(d < ZERO) { outp.ax = p1.ax; outp.ay = p1.ay; } return false; } outp.ax = (p2.ax - p1.ax) * d / s + p1.ax; outp.ay = (p2.ay - p1.ay) * d / s + p1.ay; return true; } //设置视图尺寸(透明背景) int EmbData::setViewInfo(int width, int height) { // if (m_viewWidth != width || // m_viewHight != height) { if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2) { return -1; } m_viewWidth = width; m_viewHight = height; m_canvas = QPixmap(m_viewWidth, m_viewHight); m_canvas.fill(Qt::transparent);//用透明色填充 //memset(m_canvas.bits(), 0x00, m_canvas.byteCount()); } return 0; } //设置视图(带背景图片背景) void EmbData::setViewInfo(QPixmap pix) { m_canvas = pix; } //重置数据 void EmbData::setEmbData(int type, int redraw) { m_type = type; createDispFromEmbDs16Dat(m_embDs16Data); if (redraw != 0) { drawImageByDispFile(); } } void EmbData::setDispMode(EmbData::DISP_MODE dispmode, int redraw) { m_dispMode = dispmode; if(redraw != 0) { drawImageByDispFile(); } } void EmbData::setDrawMode(EmbData::DRAW_MODE drawmode) { m_drawMode = drawmode; } //设置进度显示数据 void EmbData::setExecIndex(int index) { m_stitchIndex = index; if (m_dispMode == DISP_EXECING) { drawImageByDispFile(); } } void EmbData::reDraw() { drawImageByDispFile(); } //创建显示用的数据(为了快速显示) int EmbData::createDispFromEmbDs16Dat(QByteArray &ds16dat) { if(m_type == MACHINE_FIVEHEADPRECISIONSEWING) return createDispFromEmbDs16DatForHeadInfo(ds16dat); DispItem dispItem; m_dispDat.clear();//显示绘图用的数据(需要转换) // DsAbsItem absItem;//用于轮廓提取的绝对坐标值 // m_ds16ToAbsDat.clear();//用于轮廓提取的绝对坐标值 m_stitchIndex = 0; m_dispIndex = 0; // ds16数据 int size = ds16dat.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("16 data less then head size"); return -1; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data()); int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("dat dataBegin err"); return -1; } int stepsize = datasize/sizeof(Ds16Item); if (stepsize <= 0) { qDebug("ds16 data size err"); return -1; } Ds16Item * ds16DataPtr; Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead)); ds16DataPtr = pData; // 图形显示区域 int width = m_canvas.width();//留4个像素的边 int height = m_canvas.height();//留4个像素的边 if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2) { qDebug("preview img too small"); return -1; } //留边(否则实时跟踪笔会画出界) int viewSide = EMB_PREVIEW_SIDE; if(m_drawMode == DRAW_PREVIEW) { viewSide = 20;//预览模式时整区域留20像素绘制(原色显示) } int dpminx = viewSide; int dpmaxx = width - viewSide; int dpminy = viewSide; int dpmaxy = height - viewSide; //1:1显示无需留边 // int dpminx = 0; // int dpmaxx = width; // int dpminy = 0; // int dpmaxy = height; // 计算缩放系数 double factor, temp; if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0) { return -1; } factor = (double)(fabs(m_maxX-m_minX)) / (dpmaxx - dpminx); // 按框尺寸x计算的缩放系数 temp = (double)(fabs(m_maxY-m_minY)) / (dpmaxy - dpminy); // 按框尺寸y计算的缩放系数 if (temp >= factor) // 使用较大的缩放系数 { factor = temp; } m_factor = factor; // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2); int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2); // 显示花样图形 u8 ctrlByte; u8 attrByte; int dx; int dy; int dr; double datposx, datposy, datposr; int curx, cury, curr, prex, prey; curx = cury = curr = prex = prey = 0; datposx = pDsHead->beginX; datposy = pDsHead->beginY; datposr = pDsHead->beginR; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (EMB_SHOWDIRX == -1) { curx = width - curx; } if (EMB_SHOWDIRY == -1) { cury = height - cury; } for (int i = 0; i < stepsize; i++) { prex = curx; prey = cury; // 读入一个针步数据 ctrlByte = ds16DataPtr->ctrl; attrByte = ds16DataPtr->attr; dx = ds16DataPtr->dx; dy = ds16DataPtr->dy; dr = ds16DataPtr->dr; datposx += dx; datposy += dy; datposr += dr; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (EMB_SHOWDIRX == -1) { curx = width - curx; } if (EMB_SHOWDIRY == -1) { cury = height - cury; } while(datposr >= PI10000) { datposr -= (PI20000-1); } while(datposr <= -PI10000) { datposr += (PI20000-1); } dispItem.ctrl = ctrlByte; dispItem.attr = attrByte; dispItem.bx = prex; dispItem.by = prey; dispItem.ex = curx; dispItem.ey = cury; dispItem.ar = curr; if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示 dispItem.rgb = rgbColorYel; else dispItem.rgb = rgbColorBlue; memcpy(&dispItem.action,ds16DataPtr->action,sizeof(dispItem.action)); m_dispDat.append((char*)(&dispItem), sizeof(DispItem)); ds16DataPtr++; } qDebug("CreateDispFromEmbDs16, stepsize=%d", m_dispDat.size() / sizeof(DispItem)); return 0; } int EmbData::createDispFromEmbDs16DatForHeadInfo(QByteArray &ds16dat) { m_headDispDate.clear(); DataFileDsr dsr;//可能引起栈内存溢出的问题 dsr.initFile(m_filePath); dsr.convertDataToEmbAbs(); DsrHeadEx62 head = dsr.get62ExHead(); int StepNum = dsr.getStepNums(); int maxHSP = findMaxSpHead(head,StepNum); Disp_HeadItem dispItem; m_dispDat.clear();//显示绘图用的数据(需要转换) m_stitchIndex = 0; m_dispIndex = 0; // ds16数据 int size = ds16dat.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("16 data less then head size"); return -1; } DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data()); int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("dat dataBegin err"); return -1; } int stepsize = datasize/sizeof(Ds16Item); if (stepsize <= 0) { qDebug("ds16 data size err"); return -1; } Ds16Item * ds16DataPtr; Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead)); ds16DataPtr = pData; // 图形显示区域 int width = m_canvas.width();//留4个像素的边 int height = m_canvas.height();//留4个像素的边 if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2) { qDebug("preview img too small"); return -1; } //留边(否则实时跟踪笔会画出界) int viewSide = EMB_PREVIEW_SIDE; if(m_drawMode == DRAW_PREVIEW) { viewSide = 20;//预览模式时整区域留20像素绘制(原色显示) } int dpminx = viewSide; int dpmaxx = width - viewSide; int dpminy = viewSide; int dpmaxy = height - viewSide; // 计算缩放系数 double factor, temp; if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0) { return -1; } factor = (double)(fabs(m_maxX+(maxHSP*10)-m_minX)) / (dpmaxx - dpminx); // 按框尺寸x计算的缩放系数 五头机加上一个最大值保证绘图不越界 temp = (double)(fabs(m_maxY-m_minY)) / (dpmaxy - dpminy); // 按框尺寸y计算的缩放系数 // 使用较大的缩放系数 factor = temp >= factor?temp:factor; m_factor = factor; // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX+(maxHSP*10))/factor)/2);//最大x需要 五头机加上一个最大值保证绘图不越界 int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2); // 显示花样图形 double datposx = pDsHead->beginX; double datposy = pDsHead->beginY; int curx = (datposx) / factor + dpx; int cury = (datposy) / factor + dpy; if (EMB_SHOWDIRX == -1) { curx = width - curx; } if (EMB_SHOWDIRY == -1) { cury = height - cury; } for (int i = 0; i < stepsize; i++) { int prex = curx; int prey = cury; // 读入一个针步数据 int dx = ds16DataPtr->dx; int dy = ds16DataPtr->dy; unsigned short int headSpHndex = ds16DataPtr->action[1] & 0xFF; datposx += dx; datposy += dy; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (EMB_SHOWDIRX == -1) { curx = width - curx; } if (EMB_SHOWDIRY == -1) { cury = height - cury; } dispItem.ctrl = ds16DataPtr->ctrl; dispItem.attr = ds16DataPtr->attr; dispItem.bx = prex; dispItem.by = prey; dispItem.ex = curx; dispItem.ey = cury; dispItem.ar = ds16DataPtr->dr; memcpy(&dispItem.action,ds16DataPtr->action,2); dispItem.headtable.iswork = head.headEnableSpacing[headSpHndex].iswork; dispItem.headtable.distance1_2 = head.headEnableSpacing[headSpHndex].distance1_2; dispItem.headtable.distance1_3 = head.headEnableSpacing[headSpHndex].distance1_3; dispItem.headtable.distance1_4 = head.headEnableSpacing[headSpHndex].distance1_4; dispItem.headtable.distance1_5 = head.headEnableSpacing[headSpHndex].distance1_5; dispItem.headtable.distance1_6 = head.headEnableSpacing[headSpHndex].distance1_6; dispItem.headtable.distance1_7 = head.headEnableSpacing[headSpHndex].distance1_7; dispItem.headtable.distance1_8 = head.headEnableSpacing[headSpHndex].distance1_8; if(ds16DataPtr->ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示 dispItem.rgb = rgbColorYel; else dispItem.rgb = rgbColorGreen; m_headDispDate.append(dispItem); ds16DataPtr++; } qDebug("CreateDispFromEmbDs16, stepsize=%d", m_headDispDate.size()); return 0; } #define DRAWDR 0 int EmbData::drawImageByDispFile() { if(m_type == MACHINE_FIVEHEADPRECISIONSEWING) return drawImageByOneStepLotLine(); int bx, by, ex, ey, ar; bx = by = ex = ey = ar = 0; int i; u8 ctrlByte; DispItem * pDispBuff = (DispItem *)m_dispDat.data(); int size = m_dispDat.size(); int stitchCount = size/sizeof(DispItem); if (stitchCount <= 0) { stitchCount = 0; } if (m_stitchIndex >= stitchCount) { m_stitchIndex = stitchCount - 1; } if (m_stitchIndex < 0) { m_stitchIndex = 0; } DISP_MODE dispmode = m_dispMode; QPainter painter(&m_canvas); QRgb rgb; QPen pen; //笔宽 pen.setWidth(1); rgb = 0; if (dispmode == DISP_ALL_NORMAL || // 显示所有线迹(原色显示) dispmode == DISP_ALL_EXEC || // 显示所有线迹(执行过的显示原色,其余显示灰色) 0) { int tenThousand = 0; for (i = 0; i < stitchCount; i++) { tenThousand++; if(tenThousand == TENTHOUSANDNEEDLE) { tenThousand = 0; int idx = i / TENTHOUSANDNEEDLE; //每十万针主界面加载图片的进度条走一格 emit siDrawNeedleIdx(idx); } bx = pDispBuff[i].bx; by = pDispBuff[i].by; ex = pDispBuff[i].ex; ey = pDispBuff[i].ey; rgb = pDispBuff[i].rgb; ctrlByte = pDispBuff[i].ctrl; // 从开始到 m_stitchIndex 显示正常颜色的线迹(执行过),从 m_stitchIndex 结束显示未缝纫颜色线迹(未执行) if ((dispmode == DISP_ALL_EXEC) && (i >= m_stitchIndex)) { if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示 rgb = rgbColorYel; else rgb = rgbColorGreen; } pen.setColor(rgb); painter.setPen(pen); painter.drawLine(bx, by, ex, ey); #if(DRAWDR) double len = sqrt((double)(ex-bx)*(double)(ex-bx)+ (double)(ey-by)*(double)(ey-by)); int mx = len * cos((PI10000-ar)/10000.0); int my = len * sin((PI10000-ar)/10000.0); QColor color = QColor(Qt::green); QPen pen; pen.setColor(color); painter.setPen(pen); painter.drawLine(bx, by, bx+mx, by+my); pen.setColor(QColor(Qt::red)); painter.setPen(pen); painter.drawEllipse(bx+mx, by+my,2,2); #endif } if (dispmode == DISP_ALL_EXEC && m_stitchIndex < stitchCount) { i = m_stitchIndex; bx = pDispBuff[i].bx; by = pDispBuff[i].by; drawFork(bx, by, painter);//绘制准星 m_dispIndex = m_stitchIndex; // 移动显示指针 } } else if (dispmode == DISP_EXECING) // 刷新部分线迹(缝纫中进度显示) { //qDebug()<<"m_stitchIndex"< m_dispIndex && m_stitchIndex < stitchCount) { i = m_dispIndex; while(i < m_stitchIndex) // 显示为原线迹 { bx = pDispBuff[i].bx; by = pDispBuff[i].by; ex = pDispBuff[i].ex; ey = pDispBuff[i].ey; rgb = pDispBuff[i].rgb; pen.setColor(rgb); painter.setPen(pen); painter.drawLine(bx, by, ex, ey); i++; } } else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount) { i = m_stitchIndex; while(i <= m_dispIndex) // 显示为未缝纫颜色线迹 { bx = pDispBuff[i].bx; by = pDispBuff[i].by; ex = pDispBuff[i].ex; ey = pDispBuff[i].ey; rgb = pDispBuff[i].rgb; ctrlByte = pDispBuff[i].ctrl; if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示 rgb = rgbColorYel; else rgb = rgbColorGreen; pen.setColor(rgb); painter.setPen(pen); painter.drawLine(bx, by, ex, ey); i++; } } i = m_stitchIndex; bx = pDispBuff[i].bx; by = pDispBuff[i].by; drawFork(bx, by, painter);//绘制跟踪笔 m_dispIndex = m_stitchIndex; // 移动显示指针 } } return 0; } #include using namespace std; /** * @brief EmbData::drawImageByOneStepLotLine * @return * 五头机绘图函数 根据机头间距表信息单步画多条线 */ int EmbData::drawImageByOneStepLotLine() { int stitchCount = m_headDispDate.size(); //限制针步数 否则访问溢出 if (stitchCount <= 0) { stitchCount = 0; } if (m_stitchIndex >= stitchCount) { m_stitchIndex = stitchCount - 1; } if (m_stitchIndex < 0) { m_stitchIndex = 0; } QPainter painter(&m_canvas); QRgb rgb; QPen pen; //笔宽 pen.setWidth(1); if (m_dispMode == DISP_ALL_NORMAL || // 显示所有线迹(原色显示) m_dispMode == DISP_ALL_EXEC || // 显示所有线迹(执行过的显示原色,其余显示灰色) 0) { int tenThousand = 0; for (int i = 0; i < stitchCount; i++) { tenThousand++; if(tenThousand == TENTHOUSANDNEEDLE) { tenThousand = 0; int idx = i / TENTHOUSANDNEEDLE; //每十万针主界面加载图片的进度条走一格 emit siDrawNeedleIdx(idx); } // 从开始到 m_stitchIndex 显示正常颜色的线迹(执行过),从 m_stitchIndex 结束显示未缝纫颜色线迹(未执行) rgb = m_headDispDate[i].rgb; if ((m_dispMode == DISP_ALL_EXEC) && (i >= m_stitchIndex)) { if(m_headDispDate[i].ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示 rgb = rgbColorYel; else rgb = rgbColorGreen; } drawMultiLine(painter,pen,rgb,i);///多机头绘线 } if (m_dispMode == DISP_ALL_EXEC && m_stitchIndex < stitchCount) { drawMultiTrack(painter);///绘制多机头的跟踪图案 m_dispIndex = m_stitchIndex; // 移动显示指针 } } else if (m_dispMode == DISP_EXECING) // 刷新部分线迹(缝纫中进度显示)前进回退的时候 { //qDebug()<<"m_stitchIndex"< m_dispIndex && m_stitchIndex < stitchCount) { /// 从小针步增加到大针步 int i = m_dispIndex; while(i < m_stitchIndex) // 显示为原线迹 { if(m_headDispDate[i].ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示 rgb = rgbColorYel; else rgb = rgbColorBlue; drawMultiLine(painter,pen,rgb,i);///多机头绘线 i++; } } else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount) { /// 从大针步减少到小针步 int i = m_stitchIndex; while(i <= m_dispIndex) // 显示为未缝纫颜色线迹 { rgb = m_headDispDate[i].rgb; drawMultiLine(painter,pen,rgb,i);///多机头绘线 i++; } } drawMultiTrack(painter);///绘制多机头的跟踪图案 m_dispIndex = m_stitchIndex; // 移动显示指针 } } return 0; } /** * @brief EmbData::findMaxSpHead * @param head 机头间距表 * @param StepNum 跨步数 * @return 返回机头间距表中用到的最大偏移值 */ int EmbData::findMaxSpHead(DsrHeadEx62 &head,int StepNum) { int max = 0; for(int i = 0 ; i < StepNum;i++){ bitset<8> iswork(head.headEnableSpacing[i].iswork); for(int j = 1; j < headNum; j++) { if(!iswork.test(j)) // test(i)为0返回false continue; unsigned short int* row = (unsigned short int*)&head.headEnableSpacing[i]; unsigned short int space = *(row + j); //向后偏移得到具体大小 max = max > space ? max : space; } } return max; } /// /// \brief 根据机头间距表的iswork字段 选择性的绘制跟踪画笔 /// void EmbData::drawMultiTrack(QPainter &painter) { int bx = m_headDispDate[m_stitchIndex].bx; int by = m_headDispDate[m_stitchIndex].by; bitset<8> iswork(m_headDispDate[m_stitchIndex].headtable.iswork); for(int j = 0; j < headNum; j++){ if(j==0)//第一个机头不需要偏移 drawFork(bx, by, painter, j, true);//绘制准星 else { unsigned short int* row = (unsigned short int*)&m_headDispDate[m_stitchIndex].headtable; // 取到结构体的初始地址 unsigned short int space = *(row + j); //向后偏移得到具体大小 space = (space*10)/m_factor; //从实际距离转换为像素,得到最终的偏移像素 drawFork(bx + space, by, painter, j, iswork.test(j));//绘制准星 } } } /// /// \brief 五头机函数,根据机头间距表信息多机头同时画线 /// \param painter /// \param pen /// \param rgb /// \param index /// void EmbData::drawMultiLine(QPainter &painter, QPen &pen, QRgb rgb, int index) { int bx = m_headDispDate[index].bx;//begin int by = m_headDispDate[index].by; int ex = m_headDispDate[index].ex;//end int ey = m_headDispDate[index].ey; pen.setColor(rgb); painter.setPen(pen); bitset<8> iswork(m_headDispDate[index].headtable.iswork); for(int j = 0; j < headNum; j++){ if(!iswork.test(j)) // test(i)为0,表示机头不工作,跳过循环 { if(j == 0){//如果是一机头不工作,那么使用黄色线段画出 painter.save(); painter.setPen(rgbColorYel); painter.drawLine(bx, by, ex, ey); //机头1 缝纫数据 和原数据一致 painter.restore(); } continue; } //缝纫数据 if(m_headDispDate[index].ctrl ==DATA_SEWING) { if(j == 0){//机头1 painter.drawLine(bx, by, ex, ey); //机头1 缝纫数据 和原数据一致 } else { unsigned short int* row = (unsigned short int*)&m_headDispDate[index].headtable; // 取到结构体的初始地址 unsigned short int space = *(row + j); //向后偏移得到具体大小 space = (space*10)/m_factor; //从实际距离转换为像素 painter.drawLine(bx+space, by, ex+space, ey); //不是机头1的画线时需要偏移 } } else{ painter.drawLine(bx, by, ex, ey); } } }