From 731c702af903a0f58a60471125032423f5d7af33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Mon, 27 Mar 2017 17:03:52 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/libs@173 a8b55f48-bf90-11e4-a774-851b48703e85 --- qad_blockview/blockbusitem.cpp | 121 ++++++++++++++++++++++++++------- qad_blockview/blockbusitem.h | 8 ++- qad_blockview/blockview.cpp | 24 +++++-- qad_blockview/blockview.h | 1 + 4 files changed, 123 insertions(+), 31 deletions(-) diff --git a/qad_blockview/blockbusitem.cpp b/qad_blockview/blockbusitem.cpp index 067108e..f82fa8d 100644 --- a/qad_blockview/blockbusitem.cpp +++ b/qad_blockview/blockbusitem.cpp @@ -86,11 +86,18 @@ int BlockBusItem::addPoint(const QPointF & point, bool update) { } -int BlockBusItem::segmentPointPair(int point) const { +int BlockBusItem::segmentPointPair(int point, int * seg) const { for (int i = 0; i < segments.size(); ++i) { - if (segments[i].first == point) return segments[i].second; - if (segments[i].second == point) return segments[i].first; + if (segments[i].first == point) { + if (seg) *seg = i; + return segments[i].second; + } + if (segments[i].second == point) { + if (seg) *seg = i; + return segments[i].first; + } } + if (seg) *seg = -1; return -1; } @@ -186,24 +193,51 @@ void BlockBusItem::unmark() { } -void BlockBusItem::simplify() { +void BlockBusItem::simplify(bool full) { int pcnt = pol.size(); - for (int i = 0; i < pol.size() - 1; ++i) { - if (pol[i] == pol[i + 1]) - pol.remove(i--); + for (int s = 0; s < segments.size(); ++s) { + if (pol[segments[s].first] != pol[segments[s].second]) continue; + int ti = segments[s].first, fi = segments[s].second; + segments.removeAt(s); + pol.remove(fi); + for (int i = 0; i < segments.size(); ++i) { + if (segments[i].first == fi) segments[i].first = ti; + if (segments[i].second == fi) segments[i].second = ti; + if (segments[i].first > fi) segments[i].first--; + if (segments[i].second > fi) segments[i].second--; + } } - if (pol.size() < 3) return; - //PIMathVectorT2d cl, pl; - for (int i = 0; i < pol.size() - 2; ++i) { - //pl = Q2PIVector2(pol[i]) - Q2PIVector2(pol[i + 1]); - //cl = Q2PIVector2(pol[i + 1]) - Q2PIVector2(pol[i + 2]); - //if (pl.turnTo<3, double>() || cl.turnTo<3, double>()) - // pol.remove(i-- + 1); + if (full) { + /*QList segs; + for (int p = 0; p < pol.size(); ++p) { + if (pointSegmentsCount(p, &segs) != 2) continue; + QPointF cp = pol[p], sp[2]; + for (int i = 0; i < 2; ++i) { + if (segments[segs[i]].first == p) sp[i] = pol[segments[segs[i]].second]; + else sp[i] = pol[segments[segs[i]].first]; + } + qDebug() << p << segs; + QLineF l0(sp[0], cp), l1(cp, sp[1]); + if (l0.angle() != l1.angle()) continue; + if (segments[segs[0]].first == p) { + if (segments[segs[1]].first == p) segments[segs[0]].second = segments[segs[1]].second; + else segments[segs[0]].second = segments[segs[1]].first; + } else { + if (segments[segs[1]].first == p) segments[segs[0]].first = segments[segs[1]].second; + else segments[segs[0]].first = segments[segs[1]].first; + } + segments.removeAt(segs[1]); + pol.remove(p); + for (int i = 0; i < segments.size(); ++i) { + if (segments[i].first > p) segments[i].first--; + if (segments[i].second > p) segments[i].second--; + } + p = -1; + }*/ } if (pcnt == pol.size()) return; - //GBFrom->emitAddToHistory(History::ConnectionSimplify, ""); updateGeometry(); - if (scene() != 0) scene()->update(); + //if (scene()) scene()->update(); } @@ -325,13 +359,51 @@ QVector BlockBusItem::endpoints() const { } -int BlockBusItem::pointSegments(int point) const { - int ret = 0; - for (int i = 0; i < segments.size(); ++i) - if (segments[i].first == point || - segments[i].second == point) - ret++; +QVector BlockBusItem::endpointLine(int ep) const { + QVector ret; + int seg = -1; + int np = segmentPointPair(ep, &seg), pp = np; + if (ep < 0 || np < 0) return ret; + if (pol[np] == pol[ep]) return ret; + QPointF sp = pol[np] - pol[ep]; + bool sdir = (qAbs(sp.x()) >= qAbs(sp.y())); + for (int i = 0; i < segments.size(); ++i) { + if (np < 0) break; + if (pointSegmentsCount(np) != 2) break; + if (i > 0) { + sp = pol[np] - pol[pp]; + bool idir = (qAbs(sp.x()) >= qAbs(sp.y())); + if (sdir != idir) break; + } + ret << np; + pp = np; + np = neighborSegmentPoint(np, &seg); + } return ret; + +} + + +int BlockBusItem::pointSegmentsCount(int point, QList * segs) const { + int ret = 0; + if (segs) segs->clear(); + for (int i = 0; i < segments.size(); ++i) + if (segments[i].first == point || segments[i].second == point) { + ret++; + if (segs) segs->append(i); + } + return ret; +} + + +int BlockBusItem::neighborSegmentPoint(int point, int * seg) const { + if (point < 0 || !seg) return -1; + for (int i = 0; i < segments.size(); ++i) { + if (i == *seg) continue; + if (segments[i].first == point) {*seg = i; return segments[i].second;} + if (segments[i].second == point) {*seg = i; return segments[i].first ;} + } + return -1; } @@ -443,7 +515,7 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) { } if (max_ep >= 2) { if (endpointCount() >= max_ep) - if (pointSegments(selPoint) >= 2 || selSegment >= 0) + if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0) return; } QMetaObject::invokeMethod(scene()->views().back(), "newBranch", Q_ARG(BlockBusItem * , this)); @@ -458,11 +530,13 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) { if (e->buttons().testFlag(Qt::RightButton)) { if (selPoint >= 0 && selPoint <= pol.size() - 1) { removePoint(selPoint); + simplify(); emitAction(BlockItemBase::BusPointRemove); return; } if (selSegment >= 0 && selSegment <= segments.size() - 1) { removeSegment(selSegment); + simplify(); emitAction(BlockItemBase::BusSegmentRemove); return; } @@ -527,6 +601,7 @@ void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) { selPoint = selSegment = -1; } if (moved) { + simplify(false); reconnect(); emitAction(lm_point ? BlockItemBase::BusPointMove : BlockItemBase::BusSegmentMove); } diff --git a/qad_blockview/blockbusitem.h b/qad_blockview/blockbusitem.h index 7f60a16..4f337ee 100644 --- a/qad_blockview/blockbusitem.h +++ b/qad_blockview/blockbusitem.h @@ -42,13 +42,13 @@ public: void setWidth(const double & w) {pen_width = w; update();} void setColor(const QColor & c) {pu.setColor(c); bu.setColor(c); update();} int addPoint(const QPointF & point, bool update = true); - int segmentPointPair(int point) const; + int segmentPointPair(int point, int * seg = 0) const; void removePoint(int index); void removeSegment(int index); void markAsInput(); void markAsOutput(); void unmark(); - void simplify(); + void simplify(bool full = true); void adjustLine(); int endpointCount() const; bool isBusSelected() const {return selSegment >= 0 || selPoint >= 0;} @@ -72,7 +72,9 @@ protected: void checkDelete(); void emitAction(BlockItemBase::Action a); QVector endpoints() const; - int pointSegments(int point) const; + QVector endpointLine(int ep) const; + int pointSegmentsCount(int point, QList * segs = 0) const; + int neighborSegmentPoint(int point, int * seg) const; int type() const {return Type;} QRectF boundingRect() const; bool sceneEvent(QEvent * e); diff --git a/qad_blockview/blockview.cpp b/qad_blockview/blockview.cpp index 1d773fa..2f3e959 100644 --- a/qad_blockview/blockview.cpp +++ b/qad_blockview/blockview.cpp @@ -499,6 +499,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { foreach (QGraphicsItem * b, sel_items) if (b->data(1006) == "item") ci << b; + simplifyBuses(); emitActionEvent(BlockItemBase::BlockMove, ci); reconnectAll(); } @@ -1114,16 +1115,16 @@ void BlockView::matchBus() { } } if (sp >= 0) { - if (b->endpointCount() + b->pointSegments(sp) - 2 >= b->max_ep) { + if (b->endpointCount() + b->pointSegmentsCount(sp) - 2 >= b->max_ep) { b->setBusState(false); return; } } } else { int sep = b->endpointCount() + bus_from->endpointCount(); - if (b->pointSegments(sp) == 1) sep--; + if (b->pointSegmentsCount(sp) == 1) sep--; if (bus_from->selPoint >= 0) - if (bus_from->pointSegments(bus_from->selPoint) == 1) sep--; + if (bus_from->pointSegmentsCount(bus_from->selPoint) == 1) sep--; if (sep > b->max_ep) { b->setBusState(false); return; @@ -1205,6 +1206,13 @@ void BlockView::unhoverPins() { } +void BlockView::simplifyBuses() { + QList bl = buses(); + foreach (BlockBusItem * b, bl) + b->simplify(); +} + + void BlockView::moveBuses(const QList & items, QPointF dp) { if (dp.isNull()) return; QList gi = scene_->items(); @@ -1230,7 +1238,7 @@ void BlockView::moveBuses(const QList & items, QPointF dp) { foreach (BlockItemPin * p, pins) { QList ends = b->connections_.keys(p); for (int i = 0; i < ends.size(); ++i) { - int isp = b->segmentPointPair(ends[i]); + /*int isp = b->segmentPointPair(ends[i]); QPointF sdp; if (isp >= 0 && b->pol.size() > 2) { sdp = b->pol[isp] - b->pol[ends[i]]; @@ -1245,7 +1253,13 @@ void BlockView::moveBuses(const QList & items, QPointF dp) { if (p->alignment() == Qt::AlignLeft || p->alignment() == Qt::AlignRight) b->movePoint(isp, QPointF(0., dp.y())); } - } + }*/ + QPointF pdp = dp; + if (p->alignment() == Qt::AlignTop || p->alignment() == Qt::AlignBottom) pdp.setY(0.); + if (p->alignment() == Qt::AlignLeft || p->alignment() == Qt::AlignRight) pdp.setX(0.); + QVector epl = b->endpointLine(ends[i]); + foreach (int e, epl) + b->movePoint(e, pdp); b->movePoint(ends[i], dp); } } diff --git a/qad_blockview/blockview.h b/qad_blockview/blockview.h index 19013fa..cb07e9c 100644 --- a/qad_blockview/blockview.h +++ b/qad_blockview/blockview.h @@ -100,6 +100,7 @@ protected: void unmarkPins(bool to_normal = false); void hoverAcceptedPin(BlockItemPin * pin); void unhoverPins(); + void simplifyBuses(); void moveBuses(const QList & items, QPointF dp); QList internalBuses(const QList & items); QList selectedBlocks() const;