diff --git a/src/geometry/vdetail.cpp b/src/geometry/vdetail.cpp index 24c7811c8..59dfd3a3a 100644 --- a/src/geometry/vdetail.cpp +++ b/src/geometry/vdetail.cpp @@ -67,6 +67,11 @@ void VDetail::Clear() width = 10; } +void VDetail::ClearNodes() +{ + nodes.clear(); +} + bool VDetail::Containes(const qint64 &id) const { for (ptrdiff_t i = 0; i < nodes.size(); ++i) @@ -92,16 +97,9 @@ const VNodeDetail &VDetail::at(ptrdiff_t indx) const ptrdiff_t VDetail::indexOfNode(const qint64 &id) const { - for (ptrdiff_t i = 0; i < nodes.size(); ++i) - { - VNodeDetail node = nodes[i]; - if (node.getId() == id) - { - return i; - } - } - return -1; + return indexOfNode(nodes, id); } + qint64 VDetail::id() const { return _id; @@ -114,17 +112,23 @@ void VDetail::setId(const qint64 &id) bool VDetail::OnEdge(const qint64 &p1, const qint64 &p2) const { - ptrdiff_t i = indexOfNode(p1); + QVector list = listNodePoint(); + if(list.size() < 3) + { + qWarning()<<"Not enough points."; + return false; + } + ptrdiff_t i = indexOfNode(list, p1); ptrdiff_t j1 = 0, j2 = 0; - if (i == nodes.size() - 1) + if (i == list.size() - 1) { j1 = i-1; j2 = 0; } else if (i == 0) { - j1 = nodes.size() - 1; + j1 = list.size() - 1; j2 = i + 1; } else @@ -133,7 +137,7 @@ bool VDetail::OnEdge(const qint64 &p1, const qint64 &p2) const j2 = i + 1; } - if (nodes.at(j1).getId() == p2 || nodes.at(j2).getId() == p2) + if (list.at(j1).getId() == p2 || list.at(j2).getId() == p2) { return true; } @@ -151,14 +155,15 @@ ptrdiff_t VDetail::Edge(const qint64 &p1, const qint64 &p2) const return -1; } - ptrdiff_t i = indexOfNode(p1); - ptrdiff_t j = indexOfNode(p2); + QVector list = listNodePoint(); + ptrdiff_t i = indexOfNode(list, p1); + ptrdiff_t j = indexOfNode(list, p2); ptrdiff_t min = qMin(i, j); - if (min == 0 && (i == nodes.size() - 1 || j == nodes.size() - 1)) + if (min == 0 && (i == list.size() - 1 || j == list.size() - 1)) { - return nodes.size() - 1; + return list.size() - 1; } else { @@ -168,18 +173,87 @@ ptrdiff_t VDetail::Edge(const qint64 &p1, const qint64 &p2) const void VDetail::NodeOnEdge(const ptrdiff_t &index, VNodeDetail &p1, VNodeDetail &p2) const { - if (index <= 0 || index > nodes.size()) + QVector list = listNodePoint(); + if (index < 0 || index > list.size()) { - qWarning()<<"Wrong edge index"; + qWarning()<<"Wrong edge index index ="< nodes.size() - 1) + p1 = list.at(index); + if (index + 1 > list.size() - 1) { - p2 = nodes.at(0); + p2 = list.at(0); } else { - p2 = nodes.at(index+1); + p2 = list.at(index+1); } } + +VDetail VDetail::RemoveEdge(const ptrdiff_t &index) const +{ + VDetail det(*this); + det.ClearNodes(); + + QVector list = this->listNodePoint(); + qint32 edge = list.size(); + ptrdiff_t k = 0; + for(ptrdiff_t i=0; iat(k)); + ++k; + } + else + { + VNodeDetail p1; + VNodeDetail p2; + this->NodeOnEdge(i, p1, p2); + ptrdiff_t j1 = this->indexOfNode(p1.getId()); + ptrdiff_t j2 = this->indexOfNode(p2.getId()); + if(j2 == 0) + { + j2 = this->CountNode()-1; + if(j1 == j2) + { + det.append(this->at(j1)); + ++k; + continue; + } + } + for(ptrdiff_t j=j1; jat(j)); + ++k; + } + } + } + return det; +} + +QVector VDetail::listNodePoint() const +{ + QVector list; + for (ptrdiff_t i = 0; i < nodes.size(); ++i) + { + if (nodes[i].getTypeTool() == Tool::NodePoint) + { + list.append(nodes[i]); + } + } + return list; +} + +ptrdiff_t VDetail::indexOfNode(const QVector &list, const qint64 &id) const +{ + for (ptrdiff_t i = 0; i < list.size(); ++i) + { + if (list[i].getId() == id) + { + return i; + } + } + qWarning()<<"Can't find node."; + return -1; +} diff --git a/src/geometry/vdetail.h b/src/geometry/vdetail.h index 16411a50a..9edbdfdbf 100644 --- a/src/geometry/vdetail.h +++ b/src/geometry/vdetail.h @@ -87,6 +87,7 @@ public: * @brief Clear */ void Clear(); + void ClearNodes(); /** * @brief CountNode * @return @@ -181,6 +182,7 @@ public: bool OnEdge(const qint64 &p1, const qint64 &p2)const; ptrdiff_t Edge(const qint64 &p1, const qint64 &p2)const; void NodeOnEdge(const ptrdiff_t &index, VNodeDetail &p1, VNodeDetail &p2)const; + VDetail RemoveEdge(const ptrdiff_t &index) const; private: qint64 _id; /** @@ -211,6 +213,8 @@ private: * @brief width */ qreal width; + QVector listNodePoint()const; + ptrdiff_t indexOfNode(const QVector &list, const qint64 &id) const; }; #endif // VDETAIL_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 51c9a6385..aeb341e59 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -477,6 +477,7 @@ void MainWindow::ClosedDialogDetail(int result) VToolDetail::Create(dialogDetail, sceneDetails, doc, pattern); } ArrowTool(); + doc->FullUpdateTree(); } void MainWindow::ToolHeight(bool checked) @@ -875,7 +876,7 @@ void MainWindow::ActionDraw(bool checked) verScrollBar = view->verticalScrollBar(); verScrollBar->setValue(currentScene->getVerScrollBar()); - comboBoxDraws->setCurrentIndex(currentDrawIndex); + comboBoxDraws->setCurrentIndex(currentDrawIndex);//restore current pattern peace mode = Draw::Calculation; SetEnableTool(true); @@ -907,7 +908,7 @@ void MainWindow::ActionDetails(bool checked) verScrollBar = view->verticalScrollBar(); verScrollBar->setValue(currentScene->getVerScrollBar()); - currentDrawIndex = comboBoxDraws->currentIndex(); + currentDrawIndex = comboBoxDraws->currentIndex();//save current pattern peace comboBoxDraws->setCurrentIndex(comboBoxDraws->count()-1); mode = Draw::Modeling; diff --git a/src/tools/vtooluniondetails.cpp b/src/tools/vtooluniondetails.cpp index b7b30cb5e..c1962cf85 100644 --- a/src/tools/vtooluniondetails.cpp +++ b/src/tools/vtooluniondetails.cpp @@ -112,12 +112,12 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VDomDocument *doc, VContai QString().setNum(l2.angle())); Q_ASSERT(arc1 != 0); arc1->setMode(Draw::Modeling); - idObject = data->AddGObject(arc1); + id = data->AddGObject(arc1); VArc *arc2 = new VArc(*arc1); Q_ASSERT(arc2 != 0); arc2->setMode(Draw::Modeling); - id = data->AddGObject(arc2); + idObject = data->AddGObject(arc2); VNodeArc::Create(doc, data, id, idObject, Document::FullParse, Tool::FromGui, idTool, tool); } @@ -152,12 +152,12 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VDomDocument *doc, VContai VSpline *spl = new VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, spline->GetKcurve()); Q_ASSERT(spl != 0); spl->setMode(Draw::Modeling); - id = data->AddGObject(spl); + idObject = data->AddGObject(spl); VSpline *spl1 = new VSpline(*spl); Q_ASSERT(spl1 != 0); spl1->setMode(Draw::Modeling); - idObject = data->AddGObject(spl1); + id = data->AddGObject(spl1); VNodeSpline::Create(doc, data, id, idObject, Document::FullParse, Tool::FromGui, idTool, tool); } } @@ -263,7 +263,8 @@ void VToolUnionDetails::UpdatePoints(const qint64 &idDetail, VContainer *data, c QLineF l1(center->toQPointF(), p1.toQPointF()); QLineF l2(center->toQPointF(), p2.toQPointF()); - qint64 idCenter = data->AddGObject(center); + ++idCount; + data->UpdateGObject(idDetail+idCount, center); VArc *arc1 = new VArc(*center, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle())); Q_ASSERT(arc1); @@ -284,7 +285,8 @@ void VToolUnionDetails::UpdatePoints(const qint64 &idDetail, VContainer *data, c VPointF *p1 = new VPointF(spline->GetP1()); Q_ASSERT(p1 != 0); BiasRotatePoint(p1, dx, dy, data->GeometricObject(pRotate)->toQPointF(), angle); - qint64 idP1 = data->AddGObject(p1); + ++idCount; + data->UpdateGObject(idDetail+idCount, p1); VPointF p2 = VPointF(spline->GetP2()); BiasRotatePoint(&p2, dx, dy, data->GeometricObject(pRotate)->toQPointF(), angle); @@ -295,7 +297,8 @@ void VToolUnionDetails::UpdatePoints(const qint64 &idDetail, VContainer *data, c VPointF *p4 = new VPointF(spline->GetP4()); Q_ASSERT(p4 != 0); BiasRotatePoint(p4, dx, dy, data->GeometricObject(pRotate)->toQPointF(), angle); - qint64 idP4 = data->AddGObject(p4); + ++idCount; + data->UpdateGObject(idDetail+idCount, p4); VSpline *spl = new VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, spline->GetKcurve()); Q_ASSERT(spl != 0); @@ -325,7 +328,8 @@ void VToolUnionDetails::UpdatePoints(const qint64 &idDetail, VContainer *data, c Q_ASSERT(p1 != 0); BiasRotatePoint(p1, dx, dy, data->GeometricObject(pRotate)->toQPointF(), angle); - qint64 idP1 = data->AddGObject(p1); + ++idCount; + data->UpdateGObject(idDetail+idCount, p1); VPointF p2 = VPointF(spline.GetP2()); BiasRotatePoint(&p2, dx, dy, data->GeometricObject(pRotate)->toQPointF(), @@ -339,7 +343,8 @@ void VToolUnionDetails::UpdatePoints(const qint64 &idDetail, VContainer *data, c Q_ASSERT(p4 != 0); BiasRotatePoint(p4, dx, dy, data->GeometricObject(pRotate)->toQPointF(), angle); - qint64 idP4 = data->AddGObject(p4); + ++idCount; + data->UpdateGObject(idDetail+idCount, p4); VSpline spl = VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, spline.GetKcurve()); if (i==1) @@ -423,43 +428,47 @@ void VToolUnionDetails::Create(const qint64 _id, const VDetail &d1, const VDetai if (typeCreation == Tool::FromGui) { + VDetail uD1 = d1.RemoveEdge(indexD1); + VDetail uD2 = d2.RemoveEdge(indexD2); qint32 j = 0, i = 0; - qint32 nD1 = d1.CountNode(); - qint32 nD2 = d2.CountNode(); + qint32 nD1 = uD1.CountNode(); + qint32 nD2 = uD2.CountNode(); qint32 pointsD2 = 0; //Keeps count points second detail, what we already add. VDetail newDetail; + VNodeDetail det1p1; + VNodeDetail det1p2; + d1.NodeOnEdge(indexD1, det1p1, det1p2); + const VPointF *point1 = data->GeometricObject(det1p1.getId()); + const VPointF *point2 = data->GeometricObject(det1p2.getId()); + + VNodeDetail det2p1; + VNodeDetail det2p2; + d2.NodeOnEdge(indexD2, det2p1, det2p2); + VPointF point3 = VPointF(*data->GeometricObject(det2p1.getId())); + VPointF point4 = VPointF(*data->GeometricObject(det2p2.getId())); + + qreal dx = point1->x() - point4.x(); + qreal dy = point1->y() - point4.y(); + + point3.setX(point3.x()+dx); + point3.setY(point3.y()+dy); + + point4.setX(point4.x()+dx); + point4.setY(point4.y()+dy); + + QLineF l1(point1->toQPointF(), point2->toQPointF()); + QLineF l2(point4.toQPointF(), point3.toQPointF()); + qreal angle = l2.angleTo(l1); + + ptrdiff_t iD1 = d1.indexOfNode(det1p1.getId()); + do { - AddToNewDetail(unionDetails, doc, data, newDetail, d1, i, id); + AddToNewDetail(unionDetails, doc, data, newDetail, uD1, i, id); ++i; - if (i > indexD1 && pointsD2 < nD2-2) + if (i > iD1 && pointsD2 < nD2-2) { - VNodeDetail det1p1; - VNodeDetail det1p2; - d1.NodeOnEdge(indexD1, det1p1, det1p2); - const VPointF *point1 = data->GeometricObject(det1p1.getId()); - const VPointF *point2 = data->GeometricObject(det1p2.getId()); - - VNodeDetail det2p1; - VNodeDetail det2p2; - d2.NodeOnEdge(indexD2, det2p1, det2p2); - VPointF point3 = VPointF(*data->GeometricObject(det2p1.getId())); - VPointF point4 = VPointF(*data->GeometricObject(det2p2.getId())); - - qreal dx = point1->x() - point4.x(); - qreal dy = point1->y() - point4.y(); - - point3.setX(point3.x()+dx); - point3.setY(point3.y()+dy); - - point4.setX(point4.x()+dx); - point4.setY(point4.y()+dy); - - QLineF l1(point1->toQPointF(), point2->toQPointF()); - QLineF l2(point4.toQPointF(), point3.toQPointF()); - qreal angle = l2.angleTo(l1); - do { if (pointsD2 == 0) @@ -467,14 +476,14 @@ void VToolUnionDetails::Create(const qint64 _id, const VDetail &d1, const VDetai VNodeDetail node1; VNodeDetail node2; d2.NodeOnEdge(indexD2, node1, node2); - ptrdiff_t k = d2.indexOfNode(node2.getId()); - if (k == d2.CountNode()-1) + ptrdiff_t k = uD2.indexOfNode(node2.getId()); + if (k == uD2.CountNode()-1) { j = 0; } else { - j = d2.indexOfNode(node2.getId())+1; + j = uD2.indexOfNode(node2.getId())+1; } } if (pointsD2 == nD2 -2) @@ -485,7 +494,7 @@ void VToolUnionDetails::Create(const qint64 _id, const VDetail &d1, const VDetai { j=0; } - AddToNewDetail(unionDetails, doc, data, newDetail, d2, j, id, dx, dy, det1p1.getId(), angle); + AddToNewDetail(unionDetails, doc, data, newDetail, uD2, j, id, dx, dy, det1p1.getId(), angle); ++pointsD2; ++j; } while (pointsD2 < nD2); @@ -504,43 +513,47 @@ void VToolUnionDetails::Create(const qint64 _id, const VDetail &d1, const VDetai } else { + VDetail uD1 = d1.RemoveEdge(indexD1); + VDetail uD2 = d2.RemoveEdge(indexD2); qint64 idCount = 0; qint32 j = 0, i = 0; - qint32 nD1 = d1.CountNode(); - qint32 nD2 = d2.CountNode(); + qint32 nD1 = uD1.CountNode(); + qint32 nD2 = uD2.CountNode(); qint32 pointsD2 = 0; //Keeps count points second detail, what we already add. + VNodeDetail det1p1; + VNodeDetail det1p2; + d1.NodeOnEdge(indexD1, det1p1, det1p2); + const VPointF *point1 = data->GeometricObject(det1p1.getId()); + const VPointF *point2 = data->GeometricObject(det1p2.getId()); + + VNodeDetail det2p1; + VNodeDetail det2p2; + d2.NodeOnEdge(indexD2, det2p1, det2p2); + VPointF point3 = VPointF(*data->GeometricObject(det2p1.getId())); + VPointF point4 = VPointF(*data->GeometricObject(det2p2.getId())); + + qreal dx = point1->x() - point4.x(); + qreal dy = point1->y() - point4.y(); + + point3.setX(point3.x()+dx); + point3.setY(point3.y()+dy); + + point4.setX(point4.x()+dx); + point4.setY(point4.y()+dy); + + QLineF l1(point1->toQPointF(), point2->toQPointF()); + QLineF l2(point4.toQPointF(), point3.toQPointF()); + qreal angle = l2.angleTo(l1); + + ptrdiff_t iD1 = d1.indexOfNode(det1p1.getId()); + do { - UpdatePoints(id, data, d1, i, idCount); + UpdatePoints(id, data, uD1, i, idCount); ++i; - if (i > indexD1 && pointsD2 < nD2-2) + if (i > iD1 && pointsD2 < nD2-2) { - VNodeDetail det1p1; - VNodeDetail det1p2; - d1.NodeOnEdge(indexD1, det1p1, det1p2); - const VPointF *point1 = data->GeometricObject(det1p1.getId()); - const VPointF *point2 = data->GeometricObject(det1p2.getId()); - - VNodeDetail det2p1; - VNodeDetail det2p2; - d2.NodeOnEdge(indexD2, det2p1, det2p2); - VPointF point3 = VPointF(*data->GeometricObject(det2p1.getId())); - VPointF point4 = VPointF(*data->GeometricObject(det2p2.getId())); - - qreal dx = point1->x() - point4.x(); - qreal dy = point1->y() - point4.y(); - - point3.setX(point3.x()+dx); - point3.setY(point3.y()+dy); - - point4.setX(point4.x()+dx); - point4.setY(point4.y()+dy); - - QLineF l1(point1->toQPointF(), point2->toQPointF()); - QLineF l2(point4.toQPointF(), point3.toQPointF()); - qreal angle = l2.angleTo(l1); - do { if (pointsD2 == 0) @@ -548,14 +561,14 @@ void VToolUnionDetails::Create(const qint64 _id, const VDetail &d1, const VDetai VNodeDetail node1; VNodeDetail node2; d2.NodeOnEdge(indexD2, node1, node2); - ptrdiff_t k = d2.indexOfNode(node2.getId()); - if (k == d2.CountNode()-1) + ptrdiff_t k = uD2.indexOfNode(node2.getId()); + if (k == uD2.CountNode()-1) { j = 0; } else { - j = d2.indexOfNode(node2.getId())+1; + j = uD2.indexOfNode(node2.getId())+1; } } if (pointsD2 == nD2-2) @@ -566,7 +579,7 @@ void VToolUnionDetails::Create(const qint64 _id, const VDetail &d1, const VDetai { j=0; } - UpdatePoints(id, data, d2, j, idCount, dx, dy, det1p1.getId(), angle); + UpdatePoints(id, data, uD2, j, idCount, dx, dy, det1p1.getId(), angle); ++pointsD2; ++j; } while (pointsD2 < nD2);