git-svn-id: svn://db.shs.com.ru/libs@173 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2017-03-27 17:03:52 +00:00
parent 5f66368c7b
commit 731c702af9
4 changed files with 123 additions and 31 deletions

View File

@@ -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<int> 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<int> 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<int> BlockBusItem::endpointLine(int ep) const {
QVector<int> 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<int> * 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);
}