#include "datafiledsr.h" #include "main.h" DataFileDsr::DataFileDsr(): m_HeadSpacingIndex(0) { memset(&m_62HeadData, 0, sizeof(DsrHeadEx62)); } DataFileDsr::~DataFileDsr() { } void DataFileDsr::initFile(const QString &fullPathName) { clear(); QFileInfo file(fullPathName); if (file.exists() && file.isFile()) { m_fileFullPathName = fullPathName; m_fileName = fullPathName; if(g_emMacType == MACHINE_FIVEHEADPRECISIONSEWING) { updateFileVersionTo6_2(); // 文件头中新增2048的数据 } } else { qDebug() << "Init file failed path =" << m_fileFullPathName; } } //检查dsr文件版本,非5.2以上版本和错误格式返回-1 int DataFileDsr::checkDsrVersion() { loadFile(); // 如果数据未读取,重新读取 int size = m_fileData.size(); if (size <= (int)(sizeof(DsrHead))) { qDebug("dsr size less then headsize"); return -1; } DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); float ver = *((float*)(&dsrHead->verCode)) + 0.1; if(ver < DSR_VERSION_5) //5.x以下版本 { return -1; } if(ver >= DSR_VERSION_6_3) //6.3版本 { if(size <= (int)(sizeof(DsrHead63))) { qDebug() << "dsr size less then headsize"; return -1; } } size -= dsrHead->dataBegin; if (size <= 0) { qDebug("dsr dataBegin err"); return -1; } int stepsize = size/sizeof(DsrStep); if (stepsize <= 0) { qDebug("dsr data size err"); return -1; } if (stepsize > PATTERN_LARGE_NEEDLES)//128万针 { qDebug("dsr data size big"); return -2; } return stepsize; } // 转换为绝对数据 void DataFileDsr::convertDataToEmbAbs() { m_embAbsData.clear(); getDsrMinMax();//读取dsr源文件 int size = m_fileData.size(); if (size <= (int)(sizeof(DsrHead))) { qDebug("dsr size less then headsize"); return; } DsrHead * dsrHead = (DsrHead *)(m_fileData.data());//头文件的结构体 size -= dsrHead->dataBegin; if (size <= 0) { qDebug("dsr dataBegin err"); return; } int stepsize = size/sizeof(DsrStep); if (stepsize <= 0) { qDebug("dsr data size err"); return; } DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + dsrHead->dataBegin)); // 绝对坐标数据 DataDs16FileHead dhead; memset(&dhead, 0, sizeof(DataDs16FileHead)); QByteArray absData;//绝对坐标 absData.clear(); DsAbsItem absItem; memset(&absItem,0,sizeof(DsAbsItem)); DsrStep * dsrDataPtr = dsrDataBeg; DsrStep * dsrDataPtrTemp = dsrDataBeg; int maxX = S32_MIN; int maxY = S32_MIN; int minY = S32_MAX; int minX = S32_MAX; int stepidx = 0; int runflag = 0; BYTE ctrl,attr; BYTE lastStatus = DATA_END_OLD; //上一针的状态; double xfactor ; double yfactor ; double rfactor ; if (dsrHead->xyUnit == 0) // 0:单位0.1mm; 1: 0.01mm; 2: mm { xfactor = DSR_EMB_DATADIRX*10; yfactor = DSR_EMB_DATADIRY*10; } else if (dsrHead->xyUnit == 2) { xfactor = DSR_EMB_DATADIRX*100; yfactor = DSR_EMB_DATADIRY*100; } else { xfactor = DSR_EMB_DATADIRX; yfactor = DSR_EMB_DATADIRY; } if (dsrHead->rUnit == 0) // 0:单位0.36度; 1: 0.036度; 2: 度; 3, 1/10000弧度; { rfactor = 2*PI*10 * DSR_EMB_DATADIRR; } else if (dsrHead->rUnit == 1) { rfactor = 2*PI * DSR_EMB_DATADIRR; } else { rfactor = DSR_EMB_DATADIRR; } int ax,ay,ar; ax = ay = ar = 0; int headSpacingIndex = 0; //机头间距索引 //都减去第一个点坐标,并转换为中间数据 for (int i = 0; i < stepsize; i++) { ctrl = dsrDataPtr->ctrl; attr = dsrDataPtr->attr; ax = dsrDataPtr->dx; ay = dsrDataPtr->dy; ar = dsrDataPtr->dr; if (ctrl == DATA_PAUSE_OLD) // 暂停 { ctrl = DATA_PAUSE; } if (ctrl == DATA_ANGLE_OLD) // 拐点 { ctrl = DATA_ANGLE; } if (ctrl == DATA_CUT_OLD) // 剪线 { ctrl = DATA_CUTTRD; } if (ctrl == DATA_END_OLD) // 结束码 { ctrl = DATA_END; } if (ctrl == DATA_CHGND_OLD) // 换色功能码 { ctrl = DATA_CHGND; } #if(1) //判断是否要改变第一针的属性 if(ctrl == DSR_JUMP) { if (runflag == 0) { runflag = 1; } runflag++; } else if(ctrl == DSR_SEWING)//第一针不转换为跳针 { if ((runflag == 0 || runflag > 3) && (i > 0)) // 第一个运针是入针 { ctrl = DATA_OFFSET; runflag = 1; } //else if (i == 0 && ddx == 0 && ddy == 0) // 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs else if (i == 0) // 20230511 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs { int count = 0; do { dsrDataPtrTemp++; if (dsrDataPtr->ctrl == DSR_JUMP) { count++; if (dsrDataPtrTemp->dx == 0 && dsrDataPtrTemp->dy == 0) // 空跳,直接变成跳针 { count += 2; } } else { break; } }while(1); if (count >= 3) { ctrl = DATA_OFFSET; runflag = 2; } else { runflag = 1; } } else { runflag = 1; } } else if (ctrl == DATA_CHGND) // 换色 { runflag = 10; } else { runflag = 0; } #endif //附加动作定义 记录每个针步的机头间距索引(机头间距表中对应的位置) //缝纫动作结束,索引增加,起始为0 //上一针为缝纫或剪线,这一针不是缝纫和剪线,则增加索引 if(((lastStatus == DATA_SEWING || lastStatus == DATA_CUT_OLD ||lastStatus ==DATA_CUTTRD) && (ctrl != DATA_SEWING && ctrl != DATA_CUT_OLD && ctrl != DATA_CUTTRD && ctrl != DATA_END_OLD && ctrl != DATA_NULL))) { headSpacingIndex++; // qDebug()<<"index add to ====================:"<action; } lastStatus = ctrl; absItem.ctrl = ctrl; absItem.attr = attr; absItem.ax = ax * xfactor; absItem.ay = ay * yfactor; absItem.ar = ar * rfactor; if (absItem.ax > maxX) { maxX = absItem.ax; } if (absItem.ax < minX) { minX = absItem.ax; } if (absItem.ay > maxY) { maxY = absItem.ay; } if (absItem.ay < minY) { minY = absItem.ay; } absData.append((char*)(&absItem), sizeof(DsAbsItem)); stepidx++; dsrDataPtr++; } m_HeadSpacingIndex = headSpacingIndex; qDebug()<<"m_HeadSpacingCount = headSpacingIndex =" <dx * xfactor - minX; // int begY = dsrDataPtr->dy * yfactor - minY; int begX = dsrHead->startX; int begY = dsrHead->startY; int anchorX = dsrHead->anchorX; int anchorY = dsrHead->anchorY; int newstepnum = stepidx; // 转换后的数据长度 // 文件头转换 QString name = getFileFullName(); int namelen = name.size(); if (namelen > HEAD_NAME_STR_LEN) { namelen = HEAD_NAME_STR_LEN; } memcpy(dhead.fileName, name.data(), namelen); // 文件名称 dhead.dataSize = newstepnum*sizeof(DsAbsItem); // 数据字节数 dhead.itemNums = newstepnum; // 数据项个数 dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数 dhead.bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小 dhead.dataChecksum = calcCheckSum32((u8 *)(absData.data()) , absData.length()); // 数据累加校验和 dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) u32 fileID = 0; fileID = calcCheckSum32((u8 *)(absData.data()) , absData.length()); // 原始数据累加校验和 dhead.fileid = fileID; //中间数据的 fileid = dhead.anchorX = anchorX; // 定位点坐标X dhead.anchorY = anchorY; // 定位点坐标Y dhead.beginX = begX; // 数据起点坐标X dhead.beginY = begY; // 数据起点坐标Y dhead.beginR = 0; dhead.minX = minX-minX; dhead.maxX = maxX-minX; dhead.minY = minY-minY; dhead.maxY = maxY-minY; // 轮廓范围,使用重新计算之后的值 // 保存文件头到数组中 m_embAbsData.append((char *)(&dhead), sizeof(DataDs16FileHead)); // 保存数据到数组中 m_embAbsData.append(absData); } // 生成预览图片 int DataFileDsr::createPreviewImage(QImage *pImg, int saveflag, int penwidth, int reDraw) { #if(1) if(reDraw == 0)//图片存在则不重画 { // 图片是否存在,存在则返回 QString previewPath = getFileFullPathName() + ".preview.png"; QFile imageFile(previewPath); if (imageFile.exists()) { return 0; } } #endif int newimgflag = 0; QImage * pImage; int width, height; if (pImg == NULL) { width = DSR_PREVIEW_WIDTH; height = DSR_PREVIEW_HEIGHT; pImage = new QImage(width, height, IMAGE_TYPE); newimgflag = 1; } else { pImage = pImg; } width = pImage->width(); height = pImage->height(); if (width <= DSR_PREVIEW_SIDE*2 || height <= DSR_PREVIEW_SIDE*2) { if (pImage != NULL && newimgflag == 1) { delete pImage; } qDebug("preview img too small"); return -1; } memset(pImage->bits(), 0x00, pImage->byteCount()); QPainter painter(pImage); QColor backcolor(255, 255, 255, 0); // 透明背景 // 背景 QPen pen; pen.setWidth(penwidth); pen.setColor(backcolor); painter.setPen(pen); painter.setBrush(backcolor); painter.drawRect(0, 0, width, height); getDsrMinMax(); // 图形 int size = m_fileData.size(); if (size <= (int)(sizeof(DsrHead))) { qDebug("dsr size less then headsize"); return -1; } DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); size -= dsrHead->dataBegin; if (size <= 0) { qDebug("dsr dataBegin err"); return -1; } int stepsize = size/sizeof(DsrStep); if (stepsize <= 0) { qDebug("dsr data size err"); return -1; } DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + dsrHead->dataBegin)); // 图形显示区域 int dpminx = DSR_PREVIEW_SIDE; int dpmaxx = width - DSR_PREVIEW_SIDE; int dpminy = DSR_PREVIEW_SIDE + DSR_PREVIEW_SIDE; int dpmaxy = height - DSR_PREVIEW_SIDE; // 计算缩放系数 double factor, temp; factor = (double)(abs(m_maxX - m_minX)) / (dpmaxx - dpminx); // 按x计算的缩放系数 temp = (double)(abs(m_maxY - m_minY)) / (dpmaxy - dpminy); // 按轮廓计算,最小能够放下重复次数个图形 if (temp >= factor) // 使用较大的缩放系数 { factor = temp; } // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) int dpx = (int)((dpminx+dpmaxx)/2 - (((m_maxX+dsrHead->startX)+(m_minX+dsrHead->startX))/factor)/2); int dpy = (int)((dpminy+dpmaxy)/2 - (((m_maxY+dsrHead->startY)+(m_minY+dsrHead->startY))/factor)/2); // 显示花样图形 BYTE ctrlByte; //BYTE attrByte; QColor sewcolor = QColor(Qt::green); pen.setColor(sewcolor); painter.setPen(pen); double datposx, datposy; int curx, cury, prex, prey; curx = cury = prex = prey = 0; DsrStep * dsrDataPtr = dsrDataBeg; for (int i = 0; i < stepsize; i++) { // 读入一个针步数据 ctrlByte = dsrDataPtr->ctrl; //attrByte = dsrDataPtr->attr; prex = curx; prey = cury; datposx = dsrDataPtr->dx + dsrHead->startX; datposy = dsrDataPtr->dy + dsrHead->startY; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (DSR_SHOWDIRX == -1) { curx = (width)-curx; } if (DSR_SHOWDIRY == -1) { cury = (height)-cury; } if(i == 0) { dsrDataPtr++; continue; } if ( ctrlByte == DSR_SEWING || ctrlByte == DSR_EMB || ctrlByte == DSR_CUTTING || ctrlByte == DSR_LASER || ctrlByte == DSR_JUMP) { painter.drawLine(prex, prey, curx, cury); } else { //qDebug("other type=0x%x", ctrlByte); } dsrDataPtr++; } // 保存成文件 QString preview = getFileFullPathName(); if (saveflag != 0 && preview.isEmpty() == false) { #if (1) preview += ".preview.png"; pImage->save(preview, "png"); #endif } if (pImage != NULL && newimgflag == 1) { delete pImage; } return 0; } DsrHead *DataFileDsr::getDsrHead() { if(m_fileData.size() <= 0) { loadFile(); // 如果数据未读取,重新读取 } DsrHead * head = NULL; int size = m_fileData.size(); if (size <= (int)(sizeof(DsrHead))) { return head; } head = (DsrHead *)(m_fileData.data()); return head; } void DataFileDsr::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; } } //dsr文件头中新增2048的拓展 用于存机头间距参数 void DataFileDsr::updateFileVersionTo6_2() { qDebug()<<"exec DataFileDsr::updateFileVersionTo6_2()"; //1 读出数据 //2 判断文件版本 //3 插入数据 //4 修改头文件信息 文件版本 和 数据起始位置 QFile file(m_fileFullPathName); qDebug()<verCode)) + 0.1; DWORD begin = dsrHead->dataBegin; qDebug() << "file Version:" << ver; qDebug()<< "dsr file data beign:" << begin; if(ver < 5.2 && begin != (sizeof(DsrHead) + sizeof(DsrHeadEx62))){ file.remove();//删除文件 QFile newFile(m_fileFullPathName); if(newFile.open(QIODevice::ReadWrite | QIODevice::Truncate)){ QByteArray newFileBuffer; //添加原先的文件头 newFileBuffer.append(oldFile.left(begin)); qDebug()<<"append(oldFile.left(begin))" <dataBegin = sizeof(DsrHead) + sizeof(DsrHeadEx62); //3072 qDebug()<<"newDsrHead:"<dataBegin; //添加数据区 newFileBuffer.append(oldFile.right(oldFile.size() - begin)); qDebug()<<"oldFile.right(oldFile.size() - begin)" <dataBegin; BYTE* pCryFactors = (BYTE*)(&dsrHead->dataBegin); BYTE* pData = (BYTE*)((m_fileData.data() + dsrHead->dataBegin)); DsrCryption cry; cry.InitDsrCryptionCtrl(-1, dsrHead->cryWord, pCryFactors); int rslt = cry.DeCryption(pData, size); if (rslt == 0) { dsrHead->cryWord = 0; } } return; } void DataFileDsr::saveFile() { QFile wrfile(m_fileFullPathName); if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "open file fail when wirte, path =" << m_fileFullPathName; return; } else { wrfile.write(m_fileData); wrfile.close(); } } //写入定位点或起绣点到文件中 void DataFileDsr::writePointToFile(int x, int y, int flag) { if(m_fileData.size() <= 0) { return; } DsrHead * pDsrHead = (DsrHead *)(m_fileData.data()); if(flag == 0) { pDsrHead->startX = x; pDsrHead->startY = y; } else { pDsrHead->anchorX = x; pDsrHead->anchorY = y; } QFile wfile(m_fileFullPathName); if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "open file fail when read, path =" << m_fileFullPathName; return; } wfile.write(m_fileData); wfile.close(); #ifdef Q_OS_LINUX system("sync"); #endif } void DataFileDsr::writePatternParaToFile(DsrHead *head) { if(m_fileData.size() <= 0) { return; } memcpy(m_fileData.data(),(char*)head,sizeof(DsrHead)); QFile wfile(m_fileFullPathName); if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "open file fail when read, path =" << m_fileFullPathName; return; } wfile.write(m_fileData); wfile.close(); } QString DataFileDsr::getFileFullPath() { QFileInfo file(m_fileFullPathName); return file.absoluteFilePath(); } QString DataFileDsr::getFileFullName() { QFileInfo file(m_fileFullPathName); return file.fileName(); } QString DataFileDsr::getFileName() { QFileInfo file(m_fileFullPathName); return file.completeBaseName(); } QString DataFileDsr::getFileSuffix() { QFileInfo file(m_fileFullPathName); return file.suffix(); } int DataFileDsr::getStitchNums() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDsrHead->itemNums; } int DataFileDsr::getDatWidth() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); return (pDsrHead->maxX - pDsrHead->minX); } int DataFileDsr::getDatHeight() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); return (pDsrHead->maxY - pDsrHead->minY); } int DataFileDsr::getMaxX() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDsrHead->maxX; } int DataFileDsr::getMinX() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDsrHead->minX; } int DataFileDsr::getMaxY() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDsrHead->maxY; } int DataFileDsr::getMinY() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDsrHead->minY; } int DataFileDsr::getBeginXYAndAnchorXY(int &beginX, int &beginY, int &anchorX, int &anchorY) { int size = m_fileData.size(); if (size <= (int)(sizeof(DsrHead))) { return -1; } DsrHead * pDsrHead = (DsrHead *)((m_fileData.data())); DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + pDsrHead->dataBegin)); anchorX = pDsrHead->anchorX; anchorY = pDsrHead->anchorY; //起始点坐标等于定位点+起始点+第一针的坐标 beginX = pDsrHead->anchorX+pDsrHead->startX+dsrDataBeg->dx; beginY = pDsrHead->anchorY+pDsrHead->startY+dsrDataBeg->dy; return 0; } int DataFileDsr::getStepNums() { int stepNums = m_HeadSpacingIndex +1; return stepNums;//个数为index加一 } void DataFileDsr::set62ExHead(DsrHeadEx62 data) { m_62HeadData = data; } DsrHeadEx62 &DataFileDsr::get62ExHead() { return m_62HeadData; } int DataFileDsr::checkFileCryption() { int encryption = 0; int size = m_fileData.size(); if (size <= (int)(sizeof(DsrHead))) { qDebug("dsr size less then headsize"); return -1; } DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); size -= dsrHead->dataBegin; if (size <= 0) { qDebug("dsr dataBegin err"); return -1; } int stepsize = size/sizeof(DsrStep); if (stepsize <= 0) { qDebug("dsr data size err"); return -1; } if (dsrHead->cryWord != 0) { encryption = 1; } return encryption; } void DataFileDsr::getDsrMinMax() { loadFile(); // 如果数据未读取,重新读取 int size = m_fileData.size(); if (size <= (int)(sizeof(DsrHead))) { qDebug("dsr size less then headsize"); return; } DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); size -= dsrHead->dataBegin; if (size <= 0) { qDebug("dsr dataBegin err"); return; } int stepsize = size/sizeof(DsrStep); if (stepsize <= 0) { qDebug("dsr data size err"); return; } DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + dsrHead->dataBegin)); DsrStep * dsrDataPtr = dsrDataBeg; m_maxX = S32_MIN; m_maxY = S32_MIN; m_minY = S32_MAX; m_minX = S32_MAX; BYTE ctrlByte; long curPitX = 0; long curPitY = 0; int i = 0; do { if (i < stepsize) { ctrlByte = dsrDataPtr->ctrl; if ( ctrlByte == DATA_EMB || ctrlByte == DSR_SEWING || ctrlByte == DATA_OFFSET || 0 ) { curPitX = dsrDataPtr->dx; curPitY = dsrDataPtr->dy; } dsrDataPtr++; i++; } else { break; } if (curPitX > m_maxX) { m_maxX = curPitX; } if (curPitX < m_minX) { m_minX = curPitX; } if (curPitY > m_maxY) { m_maxY = curPitY; } if (curPitY < m_minY) { m_minY = curPitY; } }while(1); return; }