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