#include "odbedadataparser.h" #include #include class PcbCamOdbEdaDataParserPrivate { Q_DECLARE_PUBLIC(PcbCamOdbEdaDataParser) public: PcbCamOdbEdaDataParserPrivate(PcbCamOdbEdaDataParser *qptr) : q_ptr(qptr) { } ~PcbCamOdbEdaDataParserPrivate() { } QByteArray edaData; QList> packageList; QStringList errorList; QList tmpFeatureList; PcbCamOdbFeatureInfo lastSurfaceInfo; QPainterPath lastPath; qreal lastSurfacePx {0.0}; qreal lastSurfacePy {0.0}; protected: PcbCamOdbEdaDataParser * const q_ptr; }; PcbCamOdbEdaDataParser::PcbCamOdbEdaDataParser(const QByteArray &iEdaData) : d_ptr(new PcbCamOdbEdaDataParserPrivate(this)) { Q_D(PcbCamOdbEdaDataParser); d->edaData = iEdaData; } PcbCamOdbEdaDataParser::~PcbCamOdbEdaDataParser() { } void PcbCamOdbEdaDataParser::parse() { Q_D(PcbCamOdbEdaDataParser); d->packageList.clear(); d->errorList.clear(); d->tmpFeatureList.clear(); bool isInSurface = false; QTextStream stream(&d->edaData); QString line; int sectionFlag = 0; // 0:未知 1:PKG(Package Record) 2:PIN(Pin Record) 3:FGR(Feature Group Record) 4:FID(Feature ID Record) 5:PRP(Property Record) while (stream.readLineInto(&line)) { if (line.startsWith("#") || line.length() == 0) { // comment continue; } if (line.startsWith("PKG ")) { if (!d->tmpFeatureList.isEmpty()) { d->packageList.append(d->tmpFeatureList); } d->tmpFeatureList.clear(); sectionFlag = 1; } else if (line.startsWith("PIN ")) { sectionFlag = 2; } else if (line.startsWith("FGR ")) { sectionFlag = 3; } else if (line.startsWith("FID ")) { sectionFlag = 4; } else if (line.startsWith("PRP ")) { sectionFlag = 5; } if (sectionFlag >= 1 && sectionFlag <= 4) { if (isInSurface) { if (line.startsWith("CE")) { isInSurface = false; PcbCamOdbFeatureInfo feat; feat.type = PcbCam::PathFeature; feat.path = d->lastPath; feat.widthFactor = sectionFlag == 1 ? 2 : 1; d->tmpFeatureList.append(feat); d->lastPath = QPainterPath(); } else { parseSurfaceLine(line); } continue; } if (line.startsWith("CR")) { // circle record QStringList params = line.split(" ", Qt::SkipEmptyParts); PcbCamOdbFeatureInfo feat; feat.type = PcbCam::PathFeature; QPainterPath path; double xc = params.value(1).toDouble(); double yc = params.value(2).toDouble(); double r = params.value(3).toDouble(); path.addEllipse(QPointF(xc, yc), r*2.0, r*2.0); feat.path = path; feat.widthFactor = sectionFlag == 1 ? 2 : 1; d->tmpFeatureList.append(feat); } else if (line.startsWith("SQ")) { // square record QStringList params = line.split(" ", Qt::SkipEmptyParts); PcbCamOdbFeatureInfo feat; feat.type = PcbCam::PathFeature; QPainterPath path; double xc = params.value(1).toDouble(); double yc = params.value(2).toDouble(); double r = params.value(3).toDouble(); path.addRect(xc-r, yc-r, r*2.0, r*2.0); feat.path = path; feat.widthFactor = sectionFlag == 1 ? 2 : 1; d->tmpFeatureList.append(feat); } else if (line.startsWith("RC")) { // rectangle record QStringList params = line.split(" ", Qt::SkipEmptyParts); PcbCamOdbFeatureInfo feat; feat.type = PcbCam::PathFeature; QPainterPath path; double xs = params.value(1).toDouble(); double ys = params.value(2).toDouble(); double w = params.value(3).toDouble(); double h = params.value(4).toDouble(); path.addRect(xs, ys, w, h); feat.path = path; feat.widthFactor = sectionFlag == 1 ? 2 : 1; d->tmpFeatureList.append(feat); } else if (line.startsWith("CT")) { // start contour record d->lastPath = QPainterPath(); isInSurface = true; } } } if (!d->tmpFeatureList.isEmpty()) { d->packageList.append(d->tmpFeatureList); } } QList > PcbCamOdbEdaDataParser::packageFeatures() { Q_D(const PcbCamOdbEdaDataParser); return d->packageList; } QStringList PcbCamOdbEdaDataParser::errors() { Q_D(const PcbCamOdbEdaDataParser); return d->errorList; } void PcbCamOdbEdaDataParser::parseSurfaceLine(const QString &iLine) { Q_D(PcbCamOdbEdaDataParser); QStringList param = iLine.split(" ", Qt::SkipEmptyParts); if (param.value(0) == "OB") { d->lastSurfacePx = param.value(1).toDouble(); d->lastSurfacePy = param.value(2).toDouble(); d->lastPath.moveTo(d->lastSurfacePx, d->lastSurfacePy); } else if (param.value(0) == "OS") { d->lastSurfacePx = param.value(1).toDouble(); d->lastSurfacePy = param.value(2).toDouble(); d->lastPath.lineTo(d->lastSurfacePx, d->lastSurfacePy); } else if (param.value(0) == "OC") { qreal sx = d->lastSurfacePx, sy = d->lastSurfacePy; qreal ex = param.value(1).toDouble(), ey = param.value(2).toDouble(); qreal cx = param.value(3).toDouble(), cy = param.value(4).toDouble(); bool cw = param.value(5) == "Y" ? true : false; qreal sax = sx - cx, say = sy - cy; qreal eax = ex - cx, eay = ey - cy; qreal r = qSqrt(sax * sax + say * say); qreal sa = qAtan2(-say, sax); qreal ea = qAtan2(-eay, eax); if (cw) { if (ea <= sa) { ea += 2.0 * M_PI; } } else { if (sa <= ea) { sa += 2.0 * M_PI; } } d->lastPath.arcTo(QRectF(cx -r, cy -r, r *2, r *2), sa * (180.0 / M_PI), (ea - sa) * (180.0 / M_PI)); d->lastSurfacePx = ex; d->lastSurfacePy = ey; } else if (param.value(0) == "OE") { d->lastPath.closeSubpath(); } }