#include "layer.h" #include "./feature.h" #include "./symbol.h" #include "./job.h" #include "./util.h" #include #include class PcbCamLayerPrivate { Q_DECLARE_PUBLIC(PcbCamLayer) public: PcbCamLayerPrivate(PcbCamLayer *qptr) : q_ptr(qptr) { } ~PcbCamLayerPrivate() { destoryFeatures(); } void destoryFeatures() { qDeleteAll(features); features.clear(); } PcbCamJob *job {nullptr}; //Layer名称 QString layerName; //Step名称 QString stepName; //Layer属性 QVariantMap layerAttrMap; //是否影响层 bool isAffectedLayer {false}; //是否工作层 bool isWorkLayer {false}; //是否已经加载 bool loaded {false}; int maxIndex {0}; QString displayColor; QList features; mutable QRectF boundingRect; protected: PcbCamLayer * const q_ptr; }; PcbCamLayer::PcbCamLayer(PcbCamJob *iJob) : d_ptr(new PcbCamLayerPrivate(this)) { Q_D(PcbCamLayer); d->job = iJob; } PcbCamLayer::~PcbCamLayer() { } PcbCamJob *PcbCamLayer::job() const { Q_D(const PcbCamLayer); return d->job; } QString PcbCamLayer::name() const { Q_D(const PcbCamLayer); return d->layerName; } void PcbCamLayer::setName(const QString &iName) { Q_D(PcbCamLayer); d->layerName = iName.toLower(); } QString PcbCamLayer::step() const { Q_D(const PcbCamLayer); return d->stepName; } void PcbCamLayer::setStep(const QString &iStep) { Q_D(PcbCamLayer); d->stepName = iStep.toLower(); } QVariant PcbCamLayer::attr(const QString &iName) const { Q_D(const PcbCamLayer); return d->layerAttrMap.value(iName.toLower()); } bool PcbCamLayer::hasAttr(const QString &iName) const { Q_D(const PcbCamLayer); return d->layerAttrMap.contains(iName.toLower()); } void PcbCamLayer::initAttr(const QVariantMap &iAttrMap) { Q_D(PcbCamLayer); d->layerAttrMap = iAttrMap; } void PcbCamLayer::setAttr(const QString &iName, const QVariant &iValue) { Q_D(PcbCamLayer); d->layerAttrMap.insert(iName.toLower(), iValue); } void PcbCamLayer::setAffectedLayer(bool iAffected) { Q_D(PcbCamLayer); d->isAffectedLayer = iAffected; } bool PcbCamLayer::isAffectedLayer() const { Q_D(const PcbCamLayer); return d->isAffectedLayer; } void PcbCamLayer::setWorkLayer(bool iBol) { Q_D(PcbCamLayer); d->isWorkLayer = iBol; } bool PcbCamLayer::isWorkLayer() const { Q_D(const PcbCamLayer); return d->isWorkLayer; } void PcbCamLayer::setDisplayColor(const QString &iColor) { Q_D(PcbCamLayer); d->displayColor = iColor; } QString PcbCamLayer::displayColor() const { Q_D(const PcbCamLayer); return d->displayColor; } QList PcbCamLayer::features() const { Q_D(const PcbCamLayer); return d->features; } void PcbCamLayer::clearFeatures() { Q_D(PcbCamLayer); d->destoryFeatures(); d->maxIndex = 0; } void PcbCamLayer::addFeature(PcbCamFeature *iFeature) { Q_D(PcbCamLayer); iFeature->setIndex(++d->maxIndex); d->features.append(iFeature); } void PcbCamLayer::addFeatures(const QList &iFeatures) { for (PcbCamFeature *feat : iFeatures) { addFeature(feat); } } PcbCamFeature *PcbCamLayer::addLine(const QLineF &iLine, const QString &iSymbol, PcbCam::Polarity iPolarity, const QVariantMap &iAttr) { Q_D(PcbCamLayer); if (d->job == nullptr) return nullptr; if (!d->job->isSymbolExists(iSymbol)) { d->job->loadSymbol(iSymbol); } auto sym = d->job->symbol(iSymbol); auto feat = new PcbCamFeatureLine(); feat->setLine(iLine); feat->setPolarity(iPolarity); feat->setSymbol(sym); feat->setAttr(iAttr); addFeature(feat); return feat; } PcbCamFeature *PcbCamLayer::addPad(const QPointF &iPos, const QString &iSymbol, PcbCam::Orient iOrient, PcbCam::Polarity iPolarity, const QVariantMap &iAttr) { Q_D(PcbCamLayer); if (d->job == nullptr) return nullptr; if (!d->job->isSymbolExists(iSymbol)) { d->job->loadSymbol(iSymbol); } auto sym = d->job->symbol(iSymbol); auto feat = new PcbCamFeaturePad(); feat->setPos(iPos); feat->setOrient(iOrient); feat->setPolarity(iPolarity); feat->setSymbol(sym); feat->setAttr(iAttr); addFeature(feat); return feat; } PcbCamFeature *PcbCamLayer::addArc(const QPointF &iPs, const QPointF &iPe, const QPointF &iPc, bool iCw, const QString &iSymbol, PcbCam::Polarity iPolarity, const QVariantMap &iAttr) { Q_D(PcbCamLayer); if (d->job == nullptr) return nullptr; if (!d->job->isSymbolExists(iSymbol)) { d->job->loadSymbol(iSymbol); } auto sym = d->job->symbol(iSymbol); auto feat = new PcbCamFeatureArc(); feat->setData(iPs, iPe, iPc, iCw); feat->setPolarity(iPolarity); feat->setSymbol(sym); feat->setAttr(iAttr); addFeature(feat); return feat; } PcbCamFeature *PcbCamLayer::addText(const QPointF &iPos, const QString &iText, const QSizeF &iSize, PcbCam::Orient iOrient, PcbCam::Polarity iPolarity, const QVariantMap &iAttr, qreal iWidthFactor, const QString &iFont) { Q_D(PcbCamLayer); if (d->job == nullptr) return nullptr; if (!d->job->isSymbolExists(iFont)) { d->job->loadFont(iFont); } auto font = d->job->font(iFont); auto feat = new PcbCamFeatureText(); feat->setData(iPos, font, iOrient, iSize, iWidthFactor, iText); feat->setPolarity(iPolarity); feat->setAttr(iAttr); addFeature(feat); return feat; } PcbCamFeature *PcbCamLayer::addSurface(const QPainterPath &iPath, PcbCam::Polarity iPolarity, const QVariantMap &iAttr) { Q_D(PcbCamLayer); if (d->job == nullptr) return nullptr; auto feat = new PcbCamFeatureSurface(); feat->setPath(iPath); feat->setPolarity(iPolarity); feat->setAttr(iAttr); addFeature(feat); return feat; } PcbCamFeature *PcbCamLayer::addPath(const QPainterPath &iPath, int iWidth, PcbCam::Polarity iPolarity, const QVariantMap &iAttr) { Q_D(PcbCamLayer); if (d->job == nullptr) return nullptr; auto feat = new PcbCamFeaturePath(); feat->setPath(iPath); feat->setWidth(iWidth); feat->setPolarity(iPolarity); feat->setAttr(iAttr); addFeature(feat); return feat; } void PcbCamLayer::deleteFeature(int iIndex) { Q_D(PcbCamLayer); for (int i = 0; i < d->features.count(); ++i) { PcbCamFeature *feat = d->features[i]; if (feat->index() == iIndex) { d->features.removeAt(i); delete feat; return; } } } QList PcbCamLayer::selectFeature(const QPainterPath &iRegionPath, const PcbCam::FeatureSelectionFilter &iFilter, PcbCam::FeatureSelectionOperation iSelOp, PcbCam::FeatureSelectionMode iSelMode) { Q_D(PcbCamLayer); QList result; auto stepProfile = d->job->step(d->stepName)->profile(); bool isFilterRange = !iRegionPath.isEmpty(); bool isFilterProfile = (iFilter.profile != PcbCam::AllProfile && !stepProfile.isEmpty()); bool isFilterInclueSym = !iFilter.includeSymbols.isEmpty(); bool isFilterExcludeSym = !iFilter.excludeSymbols.isEmpty(); bool isFilterIncludeAttr = !iFilter.includeAttributes.isEmpty(); bool isFilterExcludeAttr = !iFilter.excludeAttributes.isEmpty(); QSet includeSymbols; for (auto symname : iFilter.includeSymbols) { auto symbol = d->job->symbol(symname); if (symbol != nullptr) { includeSymbols.insert(symbol); } } QSet excludeSymbols; for (auto symname : iFilter.excludeSymbols) { auto symbol = d->job->symbol(symname); if (symbol != nullptr) { excludeSymbols.insert(symbol); } } QList includeAttrs; for (auto attr : iFilter.includeAttributes) { includeAttrs.append(PcbCam::AttrCompareInfo(attr)); } QList excludeAttrs; for (auto attr : iFilter.excludeAttributes) { excludeAttrs.append(PcbCam::AttrCompareInfo(attr)); } if (iSelOp == PcbCam::ReplaceFeatureSelection) { this->clearSelection(); } for (auto feat : d->features) { //是否满足过滤条件 bool feat_match = PcbCamUtil::isFeatMatchFilter(feat, iFilter.type, iFilter.polarity, isFilterProfile, iFilter.profile, stepProfile, isFilterInclueSym, includeSymbols, isFilterExcludeSym, excludeSymbols, isFilterIncludeAttr, includeAttrs, iFilter.includeAttributesLogic, isFilterExcludeAttr, excludeAttrs, iFilter.excludeAttributesLogic); if (!feat_match) continue; if (isFilterRange) { bool range_match = false; if (iSelMode == PcbCam::ContainsFeatureShape) { if (iRegionPath.contains(feat->boundingRect())) range_match = true; } else if (iSelMode == PcbCam::IntersectsFeatureShape) { if (iRegionPath.intersects(feat->shape())) range_match = true; } if (!range_match) continue; } result.append(feat); if (iSelOp == PcbCam::ReplaceFeatureSelection || iSelOp == PcbCam::AppendFeatureSelection) { feat->setSelected(true); } else if (iSelOp == PcbCam::RemoveFeatureSelection) { feat->setSelected(false); } } return result; } QList PcbCamLayer::selectedFeatures() const { Q_D(const PcbCamLayer); QList result; for ( PcbCamFeature* feat : d->features) { if (feat->isSelected()) result.append(feat); } return result; } void PcbCamLayer::clearSelection() { Q_D(PcbCamLayer); for (PcbCamFeature* feat : d->features) { if (feat->isSelected()) feat->setSelected(false); } } bool PcbCamLayer::hasFeatureSelected() const { Q_D(const PcbCamLayer); for ( PcbCamFeature* feat : d->features) { if (feat->isSelected()) return true; } return false; } QRectF PcbCamLayer::boundingRect() const { Q_D(const PcbCamLayer); if (d->boundingRect.isEmpty()) { for (const PcbCamFeature* feat : d->features) { d->boundingRect = d->boundingRect.united(feat->boundingRect()); } } return d->boundingRect; }