#include "datafilequi.h" DataFileQui::DataFileQui() { clear(); } void DataFileQui::convertDataToEmbAbs(s16 flag) { m_absData.clear(); getQuiMinMax(); QuiFileHead head; // 图形数据 int i, datasize, idx; BYTE ch1, ch2; WORD tmpls,lsdata; double deltx1, delty1, deltx2, delty2; double threex[4], threey[4]; s16 nmstep; double factorx, factory, unitmuti; memcpy(&head, m_quiFileData.data(), sizeof(QuiFileHead)); unitmuti = getMutiUnit(head.unit); double scanx = head.scanX * unitmuti; // 宽度 double scany = head.scanY * unitmuti; // 长度 if (scanx < 1) { scanx = 1; } if (scany < 1) { scany = 1; } // 计算缩放系数 factorx = (double)((m_maxX-m_minX) / (scanx)); factory = (double)((m_maxY-m_minY) / (scany)); if(factorx == 0){factorx = 1;} if(factory == 0){factory = 1;} // factorx = 1; // factory = 1; if(flag != 1) { factorx = 1; factory = 1; } nmstep = head.normalStep * unitmuti; if(nmstep == 0) { nmstep = 200; //单位0.01mm(2mm) } i = sizeof(QuiFileHead); datasize = m_quiFileData.size(); DsAbsItem absItem; memset(&absItem,0,sizeof(DsAbsItem)); //将第一个点加进来 absItem.ctrl = m_firstPoint.ctrl; absItem.ax = m_firstPoint.x / factorx; absItem.ay = m_firstPoint.y / factory; m_absData.append((char*)&absItem,sizeof(DsAbsItem)); while(i < datasize) { // 图元类型 if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); tmpls = (unsigned short) (ch2 * 256) + ch1; if(tmpls == 0xffff) // 结束 { break; } switch(tmpls) { case QUI_TYPE_LINE: // 直线 case QUI_TYPE_STEP: // 跨步 case QUI_TYPE_HSTEP: // 翻头跨步 { //增加剪线 if(tmpls == QUI_TYPE_STEP || tmpls == QUI_TYPE_HSTEP) { if((u32)m_absData.size() >= sizeof(DsAbsItem)) { memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem)); absItem.ctrl = DATA_CUTTRD; m_absData.append((char*)&absItem,sizeof(DsAbsItem)); } } // 点个数 if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); lsdata = (unsigned short)ch2 * 256 + ch1; if (lsdata > 1) { // 第一个点 if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); deltx2 = (ch2 * 256.0 + ch1)/factorx; if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); delty2 = (ch2 * 256.0 + ch1)/factory; for(idx = 1; idx < lsdata; idx++) // 其余的点 { deltx1 = deltx2; delty1 = delty2; if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); deltx2 = (ch2 * 256.0 + ch1)/factorx; if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); delty2 = (ch2 * 256.0 + ch1)/factory; // 处理直线 calcLine(deltx1, delty1, deltx2, delty2, nmstep, m_absData, tmpls); } if (idx != lsdata) { break; } } break; } case QUI_TYPE_ARC: // 三点圆弧 { for (idx = 0; idx < 3; idx++) { // 点x if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threex[idx] = (ch2 * 256.0 + ch1)/factorx; // 点y if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threey[idx] = (ch2 * 256.0 + ch1)/factory; } calcCurve(threex, threey, nmstep, m_absData); if (idx != 3) { break; } break; } case QUI_TYPE_BES: // 贝塞尔曲线 { for (idx = 0; idx < 4; idx++) { // 点x if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threex[idx] = (ch2 * 256.0 + ch1)/factorx; // 点y if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threey[idx] = (ch2 * 256.0 + ch1)/factory; } // 处理贝塞尔曲线 QList splineListXY;//拟合后的点 splineListXY.clear(); getBezierPointList(threex, threey, nmstep,splineListXY); QList splitListXY;//均分后的点 splitListXY.clear(); if(splineListXY.size() > 0) { getCurvePointFillLine(splineListXY,nmstep,splitListXY,0,OBJECT_STITCHLEN_NEW_SAMALL); } //添加贝塞尔曲线数据点 for(int i = 0; i < splitListXY.size(); i++) { memset(&absItem,0,sizeof(DsAbsItem)); deltx1 = splitListXY[i].x(); delty1 = splitListXY[i].y(); absItem.ctrl = DATA_SEWING; absItem.ax = deltx1; absItem.ay = delty1; m_absData.append((char*)&absItem,sizeof(DsAbsItem)); } //calcBezier(threex, threey, nmstep, m_absData); if (idx != 4) { break; } break; } default: break; } } //生成绝对坐标数据的文件头 creatAbsHeadAndAr(); } void DataFileQui::creatAbsHeadAndAr() { DataDs16FileHead dhead; memset(&dhead, 0, sizeof(DataDs16FileHead)); int stepSize = m_absData.size()/sizeof(DsAbsItem); if(stepSize <= 0) { return; } DsAbsItem * absDataPtr = (DsAbsItem *)(m_absData.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; //取反并求最大最小值 for (int i = 0; i < stepSize; i++) { absDataPtr->ax *= QUI_DATADIRX; absDataPtr->ay *= QUI_DATADIRY; curx = absDataPtr->ax; cury = absDataPtr->ay; if(curx > maxX) { maxX = curx; } if(curx < minX) { minX = curx; } if(cury > maxY) { maxY = cury; } if(cury < minY) { minY = cury; } absDataPtr++; } absDataPtr = (DsAbsItem *)(m_absData.data()); double begX = absDataPtr->ax;//起始点 double begY = absDataPtr->ay; int begR = 0; //求dr并将每点坐标都减去第一点坐标 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; prex = curx; prey = cury; //将每个坐标都减去起始点坐标 absDataPtr->ax -= begX; absDataPtr->ay -= begY; absDataPtr->ar -= begR; absDataPtr++; } //增加结束码 if((u32)m_absData.size() >= sizeof(DsAbsItem)) { DsAbsItem absItem; memset(&absItem,0,sizeof(DsAbsItem)); memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem)); absItem.ctrl = DATA_NULL; m_absData.append((char*)&absItem,sizeof(DsAbsItem)); stepSize++; } m_maxX = maxX-begX; m_minX = minX-begX; m_maxY = maxY-begY; m_minY = minY-begY; //生成文件头 dhead.maxX = maxX; dhead.maxY = maxY; dhead.minX = minX; dhead.minY = minY; dhead.beginX = begX-minX;//起始点减去最小值 dhead.beginY = begY-minY;//起始点减去最小值 dhead.beginR = begR; dhead.anchorX = 0; dhead.anchorY = 0; dhead.itemNums = stepSize; dhead.dataSize = stepSize*sizeof(DsAbsItem); // 数据字节数 dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数 dhead.dataChecksum = calcCheckSum32((u8 *)(m_absData.data()) , dhead.dataSize);; // 数据累加校验和 dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) dhead.fileid = dhead.checkCrc; m_absData.insert(0,(char*)&dhead,sizeof(DataDs16FileHead)); } void DataFileQui::getQuiMinMax() { QuiFileHead head; memcpy(&head, m_quiFileData.data(), sizeof(QuiFileHead)); int i, idx, datasize; unsigned char ch1, ch2; unsigned short tmpls, lsdata; double deltx, delty; double threex[4], threey[4]; int first = 0; double minx, maxx, miny, maxy; minx = S32_MAX; maxx = S32_MIN; miny = S32_MAX; maxy = S32_MIN; i = sizeof(QuiFileHead); datasize = m_quiFileData.size(); while(i < datasize) { // 图元类型 if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); tmpls = (unsigned short) (ch2 * 256) + ch1; if(tmpls == 0xffff) // 结束 { break; } switch(tmpls) { case QUI_TYPE_LINE: // 直线(折线) case QUI_TYPE_STEP: // 跨步 case QUI_TYPE_HSTEP: // 翻头跨步 { // 点个数 if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); lsdata = (unsigned short)ch2 * 256 + ch1; if (lsdata > 1) { for(idx = 0; idx < lsdata; idx++) // 点 { if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); deltx = (ch2 * 256.0 + ch1); if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); delty = (ch2 * 256.0 + ch1); if (first == 0) { m_firstPoint.x = deltx; m_firstPoint.y = delty; if(tmpls == QUI_TYPE_LINE) { m_firstPoint.ctrl = DATA_SEWING; } else { m_firstPoint.ctrl = DATA_OFFSET; } first = 1; } if(deltx > maxx) { maxx = deltx; } if(deltx < minx) { minx = deltx; } if(delty > maxy) { maxy = delty; } if(delty < miny) { miny = delty; } } if (idx != lsdata) { break; } } } break; case QUI_TYPE_ARC: // 三点圆弧 { for (idx = 0; idx < 3; idx++) { // 点x if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threex[idx] = (ch2 * 256.0 + ch1); // 点y if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threey[idx] = (ch2 * 256.0 + ch1); if (first == 0) { m_firstPoint.x = threex[0]; m_firstPoint.y = threey[0]; m_firstPoint.ctrl = DATA_SEWING; first = 1; } } if (idx != 3) { break; } if(isThreePointOnALine(threex, threey) >= 1) // 3点共线 { // printf("three point on a line\n"); if(threex[0] > maxx) maxx = threex[0]; if(threex[1] > maxx) maxx = threex[1]; if(threex[2] > maxx) maxx = threex[2]; if(threex[0] < minx) minx = threex[0]; if(threex[1] < minx) minx = threex[1]; if(threex[2] < minx) minx = threex[2]; if(threey[0] > maxy) maxy = threey[0]; if(threey[1] > maxy) maxy = threey[1]; if(threey[2] > maxy) maxy = threey[2]; if(threey[0] < miny) miny = threey[0]; if(threey[1] < miny) miny = threey[1]; if(threey[2] < miny) miny = threey[2]; } else { // printf("before GetArcMinMax\n"); // printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy); getArcMinMax(threex, threey, &minx, &maxx, &miny, &maxy); // printf("after GetArcMinMax\n"); // printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy); } } break; case QUI_TYPE_BES: // 贝塞尔曲线 { for (idx = 0; idx < 4; idx++) { // 点x if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threex[idx] = (ch2 * 256.0 + ch1); // 点y if (i >= datasize){break;} ch1 = m_quiFileData.at(i++); if (i >= datasize){break;} ch2 = m_quiFileData.at(i++); threey[idx] = (ch2 * 256.0 + ch1); if (first == 0) { m_firstPoint.x = threex[0]; m_firstPoint.y = threey[0]; m_firstPoint.ctrl = DATA_SEWING; first = 1; } } if (idx != 4) { break; } getBezierMinMax(threex, threey, &minx, &maxx, &miny, &maxy); } break; } } if (first == 0) { minx = 0; maxx = 0; miny = 0; maxy = 0; m_firstPoint.x = 0; m_firstPoint.y = 0; m_firstPoint.ctrl = 0; } m_minX = minx; m_maxX = maxx; m_minY = miny; m_maxY = maxy; return; } int DataFileQui::checkFileHead() { if (m_quiFileData.size() >= (int)sizeof(QuiFileHead)) { QuiFileHead * pHead; pHead = (QuiFileHead *)(m_quiFileData.data()); if (pHead->normalStep < 1) { pHead->normalStep = 40; } if (pHead->miniStep < 1) { pHead->miniStep = 40; } if (pHead->scanX < 1) { pHead->scanX = m_maxX - m_minX; } if (pHead->scanY < 1) { pHead->scanY = m_maxY - m_minY; } QFile wrfile(m_fileFullPathName); if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { return -1; } else { wrfile.write(m_quiFileData); wrfile.close(); } } return 0; } double DataFileQui::getMutiUnit(int unit) { double unitmuti; if (unit == 0x00) // 0x00: 0.1mm; { unitmuti = 10; } else if (unit == 0x01) // 0x01: 1/1000inch; { unitmuti = 2.54; } else if (unit == 0x02) // 0x02: 0.04mm { unitmuti = 10; } else { unitmuti = 1; } return unitmuti; } void DataFileQui::initFile(const QString &fullPathName) { clear(); QFileInfo file(fullPathName); if (file.exists() && file.isFile()) { m_fileFullPathName = fullPathName; } else { qDebug() << "Init file failed path =" << m_fileFullPathName; } loadFile(); } void DataFileQui::clear() { m_firstPoint.x = 0; m_firstPoint.y = 0; m_firstPoint.ctrl = 0; m_minX = INT32_MAX; m_maxX = INT32_MIN; m_minY = INT32_MAX; m_maxY = INT32_MIN; m_fileFullPathName.clear(); // 文件路径 m_quiFileData.clear(); // 文件数据内容 m_absData.clear(); // 转换后的数据 } void DataFileQui::loadFile() { QFile rdfile(m_fileFullPathName); if(!rdfile.open(QIODevice::ReadOnly)) { qDebug() << "open file fail when read, path =" << m_fileFullPathName; return; } m_quiFileData = rdfile.readAll(); rdfile.close(); } int DataFileQui::createPreviewImage(QImage *pImg, int saveflag, int penwidth, int reDraw) { #if(1) s16 existFlag = 1; if(reDraw == 0)//图片存在则不重画 { existFlag = 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 = QUI_PREVIEW_WIDTH; height = QUI_PREVIEW_HEIGHT; pImage = new QImage(width, height, IMAGE_TYPE); newimgflag = 1; } else { pImage = pImg; } width = pImage->width(); height = pImage->height(); if (width <= QUI_PREVIEW_SIDE*2 || height <= QUI_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); // 图形 //qDebug()<<"convertDataToAbs defore"; convertDataToEmbAbs(existFlag); // 转换为绝对坐标数据 //qDebug()<<"convertDataToAbs end"; // absdat数据 int size = m_absData.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("2 data less then head size"); return -1; } DataDs16FileHead * pAbsHead = (DataDs16FileHead *)(m_absData.data()); 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_absData.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; //-------- // 图形显示区域 int dpminx = QUI_PREVIEW_SIDE; int dpmaxx = width - QUI_PREVIEW_SIDE; int dpminy = QUI_PREVIEW_SIDE; int dpmaxy = height - QUI_PREVIEW_SIDE; // 计算缩放系数 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); // 按x计算的缩放系数 if (temp >= factor) // 使用较大的缩放系数 { factor = temp; } // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) double dpx = (double)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2); double dpy = (double)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2); // 显示花样图形 u8 ctrlByte; double dx; double dy; double datposx, datposy; double curx, cury, prex, prey; datposx = pAbsHead->beginX; datposy = pAbsHead->beginY; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (QUI_SHOWDIRX == -1) { curx = (width)-curx; } if (QUI_SHOWDIRY == -1) { cury = (height)-cury; } absDataPtr = pData; QColor color = QColor(Qt::green); pen.setColor(color); painter.setPen(pen); for (int i = 0; i < stepsize; i++) { // 读入一个针步数据 ctrlByte = absDataPtr->ctrl; prex = curx; prey = cury; dx = absDataPtr->ax; dy = absDataPtr->ay; datposx = dx; datposy = dy; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (QUI_SHOWDIRX == -1) { curx = (width)-curx; } if (QUI_SHOWDIRY == -1) { cury = (height)-cury; } if(i == 0) { absDataPtr++; continue; } if ( ctrlByte == DATA_SEWING) { painter.drawLine(prex, prey, curx, cury); } else { //qDebug("other type=0x%x", ctrlByte); } absDataPtr++; } // 保存成文件 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; } QuiFileHead *DataFileQui::getQuiHead() { if(m_quiFileData.size() <= 0) { loadFile(); } QuiFileHead *head = NULL; int size = m_quiFileData.size(); if (size <= (int)(sizeof(QuiFileHead))) { return head; } head = (QuiFileHead *)(m_quiFileData.data()); return head; } void DataFileQui::writePatternParaToFile(QuiFileHead *head) { if(m_quiFileData.size() <= 0) { return; } memcpy(m_quiFileData.data(),(char*)head,sizeof(QuiFileHead)); QFile wfile(m_fileFullPathName); if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "open file fail when read, path =" << m_fileFullPathName; return; } wfile.write(m_quiFileData); wfile.close(); } void DataFileQui::moveDataBeginPonit(s32 left, s32 front) { if((u32)m_absData.size() > sizeof(DataDs16FileHead)) { DataDs16FileHead *dhead = (DataDs16FileHead *)( m_absData.data()); dhead->beginX += left; dhead->beginY += front; dhead->maxX += left; dhead->minX += left; dhead->maxY += front; dhead->minY += front; } } int DataFileQui::getStitchNums() { if(m_absData.size() <= 0) { return 0; } DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); return pHead->itemNums; } int DataFileQui::getDatWidth() { if(m_absData.size() <= 0) { return 0; } DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); return (pHead->maxX - pHead->minX); } int DataFileQui::getDatHeight() { if(m_absData.size() <= 0) { return 0; } DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); return (pHead->maxY - pHead->minY); } int DataFileQui::getMaxX() { if(m_absData.size() <= 0) { return 0; } DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); return pHead->maxX; } int DataFileQui::getMinX() { if(m_absData.size() <= 0) { return 0; } DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); return pHead->minX; } int DataFileQui::getMaxY() { if(m_absData.size() <= 0) { return 0; } DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); return pHead->maxY; } int DataFileQui::getMinY() { if(m_absData.size() <= 0) { return 0; } DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); return pHead->minY; }