diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index 1c5d0b82b..a8756eadc 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -3164,13 +3164,17 @@ void VPattern::ParseToolsElement(VMainGraphicsScene *scene, const QDomElement &d { quint32 id = 0; ToolsCommonAttributes(domElement, id); - const quint32 indexD1 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD1, "-1"); - const quint32 indexD2 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD2, "-1"); - const QVector vector = VToolUnionDetails::GetDetailFromFile(this, domElement); + VToolUnionDetailsInitData initData; + initData.indexD1 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD1, "-1"); + initData.indexD2 = GetParametrUInt(domElement, VToolUnionDetails::AttrIndexD2, "-1"); + initData.scene = scene; + initData.doc = this; + initData.data = data; + initData.parse = parse; + initData.typeCreation = Source::FromFile; - VToolUnionDetails::Create(id, vector[0], vector[1], 0, 0, indexD1, indexD2, scene, this, data, parse, - Source::FromFile); + VToolUnionDetails::Create(id, initData); } catch (const VExceptionBadId &e) { diff --git a/src/libs/vpatterndb/vpiecepath.cpp b/src/libs/vpatterndb/vpiecepath.cpp index 3e9718b76..e0ed91595 100644 --- a/src/libs/vpatterndb/vpiecepath.cpp +++ b/src/libs/vpatterndb/vpiecepath.cpp @@ -361,6 +361,92 @@ int VPiecePath::indexOfNode(quint32 id) const return -1; } +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief NodeOnEdge return nodes located on edge with index. + * @param index index of edge. + * @param p1 first node. + * @param p2 second node. + */ +void VPiecePath::NodeOnEdge(quint32 index, VPieceNode &p1, VPieceNode &p2) const +{ + const QVector list = ListNodePoint(); + if (index > static_cast(list.size())) + { + qDebug()<<"Wrong edge index index ="<(index)); + if (index + 1 > static_cast(list.size()) - 1) + { + p2 = list.at(0); + } + else + { + p2 = list.at(static_cast(index+1)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief listNodePoint return list nodes only with points. + * @return list points node. + */ +QVector VPiecePath::ListNodePoint() const +{ + QVector list; + for (int i = 0; i < d->m_nodes.size(); ++i) //-V807 + { + if (d->m_nodes.at(i).GetTypeTool() == Tool::NodePoint) + { + list.append(d->m_nodes.at(i)); + } + } + return list; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief RemoveEdge return path without edge with index. + * @param index idex of edge. + * @return path without edge with index. + */ +VPiecePath VPiecePath::RemoveEdge(quint32 index) const +{ + VPiecePath path(*this); + path.Clear(); + + // Edge can be only segment. We ignore all curves inside segments. + const quint32 edges = static_cast(ListNodePoint().size()); + quint32 k = 0; + for (quint32 i=0; iat(static_cast(k))); + ++k; + } + else + { + VPieceNode p1; + VPieceNode p2; + this->NodeOnEdge(i, p1, p2); + const int j1 = this->indexOfNode(p1.GetId()); + int j2 = this->indexOfNode(p2.GetId()); + if (j2 == 0) + { + j2 = this->CountNodes(); + } + for (int j=j1; jat(j)); + ++k; + } + } + } + return path; +} + //--------------------------------------------------------------------------------------------------------------------- VSAPoint VPiecePath::StartSegment(const VContainer *data, int i, bool reverse) const { diff --git a/src/libs/vpatterndb/vpiecepath.h b/src/libs/vpatterndb/vpiecepath.h index 1f3dbf901..557d8541d 100644 --- a/src/libs/vpatterndb/vpiecepath.h +++ b/src/libs/vpatterndb/vpiecepath.h @@ -79,7 +79,12 @@ public: QVector MissingNodes(const VPiecePath &path) const; - int indexOfNode(quint32 id) const; + int indexOfNode(quint32 id) const; + void NodeOnEdge(quint32 index, VPieceNode &p1, VPieceNode &p2) const; + + QVector ListNodePoint() const; + + VPiecePath RemoveEdge(quint32 index) const; VSAPoint StartSegment(const VContainer *data, int i, bool reverse) const; VSAPoint EndSegment(const VContainer *data, int i, bool reverse) const; diff --git a/src/libs/vtools/tools/vtooluniondetails.cpp b/src/libs/vtools/tools/vtooluniondetails.cpp index 44773e649..a7ad91eff 100644 --- a/src/libs/vtools/tools/vtooluniondetails.cpp +++ b/src/libs/vtools/tools/vtooluniondetails.cpp @@ -58,6 +58,8 @@ #include "../vmisc/logging.h" #include "../vmisc/vabstractapplication.h" #include "../vpatterndb/vcontainer.h" +#include "../vpatterndb/vpiecepath.h" +#include "../vpatterndb/vpiecenode.h" #include "../dialogs/tools/dialogtool.h" #include "nodeDetails/vnodearc.h" #include "nodeDetails/vnodeellipticalarc.h" @@ -66,7 +68,7 @@ #include "nodeDetails/vnodesplinepath.h" #include "vdatatool.h" #include "vnodedetail.h" -#include "vtooldetail.h" +#include "vtoolseamallowance.h" class QDomElement; class QDomNode; @@ -92,1040 +94,55 @@ Q_LOGGING_CATEGORY(vToolUnion, "v.toolUnion") QT_WARNING_POP -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief VToolUnionDetails costructor. - * @param doc dom document container. - * @param data dom document container. - * @param id object id in container. - * @param d1 first detail. - * @param d2 second detail. - * @param indexD1 index edge in first detail. - * @param indexD2 index edge in second detail. - * @param typeCreation way we create this tool. - * @param parent parent object. - */ -VToolUnionDetails::VToolUnionDetails(VAbstractPattern *doc, VContainer *data, const quint32 &id, const VDetail &d1, - const VDetail &d2, const quint32 &indexD1, const quint32 &indexD2, - const Source &typeCreation, const QString &drawName, QObject *parent) - :VAbstractTool(doc, data, id, parent), d1(d1), d2(d2), indexD1(indexD1), indexD2(indexD2), drawName(drawName) +namespace { - _referens = 0; - ToolCreation(typeCreation); -} - //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddToNewDetail create united detail adding one node per time. - * @param doc dom document container. - * @param data container with variables. - * @param newDetail united detail. - * @param det detail what we union. - * @param i index node in detail. - * @param idTool id tool union details. - * @param children list of children - * @param drawName name of pattern piece - * @param dx bias node x axis. - * @param dy bias node y axis. - * @param pRotate point rotation. - * @param angle angle rotation. - */ -void VToolUnionDetails::AddToNewDetail(VMainGraphicsScene *scene, VAbstractPattern *doc, - VContainer *data, VDetail &newDetail, const VDetail &det, const int &i, - const quint32 &idTool, QVector &children, const QString &drawName, - const qreal &dx, const qreal &dy, const quint32 &pRotate, const qreal &angle) +VPiecePath GetPieceMainPath(int piece, VAbstractPattern *doc, quint32 id) { - quint32 id = 0, idObject = 0; - switch (det.at(i).getTypeTool()) + const QDomElement tool = doc->elementById(id); + if (tool.isNull()) { - case (Tool::NodePoint): + VException e(QString("Can't get tool by id='%1'.").arg(id)); + throw e; + } + + const QDomNodeList nodesList = tool.childNodes(); + for (qint32 i = 0; i < nodesList.size(); ++i) + { + const QDomElement element = nodesList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VToolUnionDetails::TagDetail) { - VPointF *point = new VPointF(*data->GeometricObject(det.at(i).getId())); - point->setMode(Draw::Modeling); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + const QDomNodeList detList = element.childNodes(); + for (qint32 j = 0; j < detList.size(); ++j) { - BiasRotatePoint(point, dx, dy, *data->GeometricObject(pRotate), angle); - } - - idObject = data->AddGObject(point); - children.append(idObject); - VPointF *point1 = new VPointF(*point); - point1->setMode(Draw::Modeling); - id = data->AddGObject(point1); - VNodePoint::Create(doc, data, scene, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeArc): - { - const QSharedPointer arc = data->GeometricObject(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); - VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); - VPointF *center = new VPointF(arc->GetCenter()); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center, dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - center->setMode(Draw::Modeling); - quint32 idCenter = data->AddGObject(center); - Q_UNUSED(idCenter) - VArc *arc1 = new VArc(*center, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), - QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle())); - arc1->setMode(Draw::Modeling); - idObject = data->AddGObject(arc1); - children.append(idObject); - - VArc *arc2 = new VArc(*arc1); - arc2->setMode(Draw::Modeling); - id = data->AddGObject(arc2); - - VNodeArc::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeElArc): - { - const QSharedPointer arc = data->GeometricObject(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); - VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); - VPointF *center = new VPointF(arc->GetCenter()); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center, dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - center->setMode(Draw::Modeling); - quint32 idCenter = data->AddGObject(center); - Q_UNUSED(idCenter) - VEllipticalArc *arc1 = new VEllipticalArc (*center, arc->GetRadius1(), arc->GetRadius2(), - arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), - l1.angle(), QString().setNum(l1.angle()), l2.angle(), - QString().setNum(l2.angle()), 0, "0"); - arc1->setMode(Draw::Modeling); - idObject = data->AddGObject(arc1); - children.append(idObject); - - VEllipticalArc *arc2 = new VEllipticalArc(*arc1); - arc2->setMode(Draw::Modeling); - id = data->AddGObject(arc2); - - VNodeEllipticalArc::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeSpline): - { - const QSharedPointer spline = - data->GeometricObject(det.at(i).getId()); - - QScopedPointer p1(new VPointF(spline->GetP1())); - VPointF p2 = VPointF(spline->GetP2()); - VPointF p3 = VPointF(spline->GetP3()); - QScopedPointer p4(new VPointF(spline->GetP4())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(p1.data(), dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4.data(), dx, dy, p, angle); - } - - VSpline *spl = new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling); - idObject = data->AddGObject(spl); - children.append(idObject); - - VSpline *spl1 = new VSpline(*spl); - spl1->setMode(Draw::Modeling); - id = data->AddGObject(spl1); - VNodeSpline::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - case (Tool::NodeSplinePath): - { - VSplinePath *path = new VSplinePath(); - path->setMode(Draw::Modeling); - const QSharedPointer splinePath = - data->GeometricObject(det.at(i).getId()); - for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) - { - const VSpline spline = splinePath->GetSpline(i); - - VPointF *p1 = new VPointF(spline.GetP1()); - VPointF p2 = VPointF(spline.GetP2()); - VPointF p3 = VPointF(spline.GetP3()); - VPointF *p4 = new VPointF(spline.GetP4()); - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + const QDomElement element = detList.at(j).toElement(); + if (not element.isNull() + && element.tagName() == VAbstractPattern::TagNodes + && j+1 == piece) { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4, dx, dy, p, angle); - } - - VSpline spl = VSpline(*p1, p2, p3, *p4); - if (i==1) - { - const qreal angle1 = spl.GetStartAngle()+180; - const QString angle1F = QString().number(angle1); - - path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), - 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); - } - - const qreal angle2 = spl.GetEndAngle()+180; - const QString angle2F = QString().number(angle2); - qreal pL2 = 0; - QString pL2F("0"); - if (i+1 <= splinePath->CountSubSpl()) - { - const VSpline nextSpline = splinePath->GetSpline(i+1); - pL2 = nextSpline.GetC1Length(); - pL2F = nextSpline.GetC1LengthFormula(); - } - - path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, - spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); - - delete p4; - delete p1; - } - idObject = data->AddGObject(path); - children.append(idObject); - - VSplinePath *path1 = new VSplinePath(*path); - path1->setMode(Draw::Modeling); - id = data->AddGObject(path1); - VNodeSplinePath::Create(doc, data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); - } - break; - default: - qDebug()<<"May be wrong tool type!!! Ignoring."< &children, const qreal &dx, const qreal &dy, - const quint32 &pRotate, - const qreal &angle) -{ - switch (det.at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - VPointF *point = new VPointF(*data->GeometricObject(det.at(i).getId())); - point->setMode(Draw::Modeling); - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - BiasRotatePoint(point, dx, dy, *data->GeometricObject(pRotate), angle); - } - data->UpdateGObject(TakeNextId(children), point); - } - break; - case (Tool::NodeArc): - { - const QSharedPointer arc = data->GeometricObject(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1()); - VPointF p2 = VPointF(arc->GetP2()); - QScopedPointer center(new VPointF(arc->GetCenter())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center.data(), dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - - VArc *arc1 = new VArc(*center, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), - QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle())); - arc1->setMode(Draw::Modeling); - data->UpdateGObject(TakeNextId(children), arc1); - } - break; - case (Tool::NodeElArc): - { - const QSharedPointer arc = data->GeometricObject(det.at(i).getId()); - VPointF p1 = VPointF(arc->GetP1()); - VPointF p2 = VPointF(arc->GetP2()); - QScopedPointer center(new VPointF(arc->GetCenter())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(&p1, dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(center.data(), dx, dy, p, angle); - } - - QLineF l1(*center, p1); - QLineF l2(*center, p2); - - VEllipticalArc *arc1 = new VEllipticalArc (*center, arc->GetRadius1(), arc->GetRadius2(), - arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), - l1.angle(), QString().setNum(l1.angle()), l2.angle(), - QString().setNum(l2.angle()), 0, "0"); - arc1->setMode(Draw::Modeling); - data->UpdateGObject(TakeNextId(children), arc1); - } - break; - case (Tool::NodeSpline): - { - const QSharedPointer spline = - data->GeometricObject(det.at(i).getId()); - - QScopedPointer p1(new VPointF(spline->GetP1())); - VPointF p2 = VPointF(spline->GetP2()); - VPointF p3 = VPointF(spline->GetP3()); - QScopedPointer p4(new VPointF(spline->GetP4())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(p1.data(), dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4.data(), dx, dy, p, angle); - } - - VSpline *spl = new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling); - data->UpdateGObject(TakeNextId(children), spl); - } - break; - case (Tool::NodeSplinePath): - { - VSplinePath *path = new VSplinePath(); - path->setMode(Draw::Modeling); - const QSharedPointer splinePath = - data->GeometricObject(det.at(i).getId()); - SCASSERT(splinePath != nullptr) - for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) - { - const VSpline spline = splinePath->GetSpline(i); - - QScopedPointer p1(new VPointF(spline.GetP1())); - VPointF p2 = VPointF(spline.GetP2()); - VPointF p3 = VPointF(spline.GetP3()); - QScopedPointer p4(new VPointF(spline.GetP4())); - - if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) - { - const QPointF p = *data->GeometricObject(pRotate); - - BiasRotatePoint(p1.data(), dx, dy, p, angle); - BiasRotatePoint(&p2, dx, dy, p, angle); - BiasRotatePoint(&p3, dx, dy, p, angle); - BiasRotatePoint(p4.data(), dx, dy, p, angle); - } - - VSpline spl = VSpline(*p1, p2, p3, *p4); - if (i==1) - { - const qreal angle1 = spl.GetStartAngle()+180; - const QString angle1F = QString().number(angle1); - - path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), - 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); - } - - const qreal angle2 = spl.GetEndAngle()+180; - const QString angle2F = QString().number(angle2); - - qreal pL2 = 0; - QString pL2F("0"); - if (i+1 <= splinePath->CountSubSpl()) - { - const VSpline nextSpline = splinePath->GetSpline(i+1); - pL2 = nextSpline.GetC1Length(); - pL2F = nextSpline.GetC1LengthFormula(); - } - - path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, - spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); - } - data->UpdateGObject(TakeNextId(children), path); - } - break; - default: - qDebug()<<"May be wrong tool type!!! Ignoring."<setX(point->x()+dx); - point->setY(point->y()+dy); - QLineF line(pRotate, *point); - line.setAngle(line.angle()+angle); - point->setX(line.p2().x()); - point->setY(line.p2().y()); -} - -//--------------------------------------------------------------------------------------------------------------------- -QString VToolUnionDetails::getTagName() const -{ - return VAbstractPattern::TagTools; -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::ShowVisualization(bool show) -{ - Q_UNUSED(show) -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::incrementReferens() -{ - ++_referens; - if (_referens == 1) - { - IncrementReferences(d1); - IncrementReferences(d2); - - QDomElement domElement = doc->elementById(id); - if (domElement.isElement()) - { - doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::InUse); - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::decrementReferens() -{ - if (_referens > 0) - { - --_referens; - } - if (_referens == 0) - { - DecrementReferences(d1); - DecrementReferences(d2); - - QDomElement domElement = doc->elementById(id); - if (domElement.isElement()) - { - doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::NotInUse); - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::GroupVisibility(quint32 object, bool visible) -{ - Q_UNUSED(object) - Q_UNUSED(visible) -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Create help create tool from GUI. - * @param dialog dialog. - * @param doc dom document container. - * @param data container with variables. - */ -VToolUnionDetails* VToolUnionDetails::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, - VContainer *data) -{ - SCASSERT(dialog != nullptr) - DialogUnionDetails *dialogTool = qobject_cast(dialog); - SCASSERT(dialogTool != nullptr) - VDetail d1 = data->GetDetail(dialogTool->getD1()); - VDetail d2 = data->GetDetail(dialogTool->getD2()); - quint32 indexD1 = static_cast(dialogTool->getIndexD1()); - quint32 indexD2 = static_cast(dialogTool->getIndexD2()); - const bool retainPieces = dialogTool->RetainPieces(); - qApp->getUndoStack()->beginMacro(tr("union details")); - VToolUnionDetails* tool = Create(0, d1, d2, dialogTool->getD1(), dialogTool->getD2(), indexD1, indexD2, scene, - doc, data, Document::FullParse, Source::FromGui, retainPieces); - qApp->getUndoStack()->endMacro(); - return tool; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief Create help create tool. - * @param _id tool id, 0 if tool doesn't exist yet. - * @param d1 first detail. - * @param d2 second detail. - * @param d1id id first detail. - * @param d2id id second detail. - * @param indexD1 index edge in first detail. - * @param indexD2 index edge in second detail. - * @param scene pointer to scene. - * @param doc dom document container. - * @param data container with variables. - * @param parse parser file mode. - * @param typeCreation way we create this tool. - */ -VToolUnionDetails* VToolUnionDetails::Create(const quint32 _id, const VDetail &d1, const VDetail &d2, - const quint32 &d1id, const quint32 &d2id, const quint32 &indexD1, - const quint32 &indexD2, VMainGraphicsScene *scene, VAbstractPattern *doc, - VContainer *data, const Document &parse, const Source &typeCreation, - bool retainPieces) -{ - VToolUnionDetails *unionDetails = nullptr; - quint32 id = _id; - QString drawName; - if (typeCreation == Source::FromGui) - { - id = data->getNextId(); - drawName = DrawName(doc, d1id, d2id); - SCASSERT(not drawName.isEmpty()) - } - else - { - if (parse != Document::FullParse) - { - doc->UpdateToolData(id, data); - } - } - - //First add tool to file - VAbstractTool::AddRecord(id, Tool::UnionDetails, doc); - if (parse == Document::FullParse) - { - //Scene doesn't show this tool, so doc will destroy this object. - unionDetails = new VToolUnionDetails(doc, data, id, d1, d2, indexD1, indexD2, typeCreation, drawName, doc); - doc->AddTool(id, unionDetails); - // Unfortunatelly doc will destroy all objects only in the end, but we should delete them before each FullParse - doc->AddToolOnRemove(unionDetails); - } - //Then create new details - VNodeDetail det1p1; - VNodeDetail det1p2; - d1.NodeOnEdge(indexD1, det1p1, det1p2); - Q_UNUSED(det1p2) - - VPointF point1; - VPointF point2; - PointsOnEdge(d1, indexD1, point1, point2, data); - - VPointF point3; - VPointF point4; - PointsOnEdge(d2, indexD2, point3, point4, data); - - const qreal dx = point1.x() - point4.x(); - const 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); - - const QLineF p4p3 = QLineF(point4, point3); - const QLineF p1p2 = QLineF(point1, point2); - - const qreal angle = p4p3.angleTo(p1p2); - qint32 pointsD2 = 0; //Keeps number points the second detail, what we have already added. - - const qint32 countNodeD1 = d1.RemoveEdge(indexD1).CountNode(); - const qint32 countNodeD2 = d2.RemoveEdge(indexD2).CountNode(); - - if (typeCreation == Source::FromGui) - { - qint32 i = 0; - VDetail newDetail; - QVector children; - do - { - AddToNewDetail(scene, doc, data, newDetail, d1.RemoveEdge(indexD1), i, id, children, drawName); - ++i; - if (i > d1.indexOfNode(det1p1.getId()) && pointsD2 < countNodeD2-1) - { - qint32 j = 0; - FindIndexJ(pointsD2, d2, indexD2, j); - do - { - if (j >= countNodeD2) - { - j=0; - } - AddToNewDetail(scene, doc, data, newDetail, d2.RemoveEdge(indexD2), j, id, children, drawName, - dx, dy, det1p1.getId(), angle); - ++pointsD2; - ++j; - } while (pointsD2 < countNodeD2-1); - } - } while (i < countNodeD1); - - newDetail.setName(tr("United detail")); - newDetail.setWidth(d1.getWidth()); - newDetail.setMx(d1.getMx()); - newDetail.setMy(d1.getMy()); - VToolDetail::Create(0, newDetail, scene, doc, data, parse, Source::FromTool, drawName); - - auto RemoveDetail = [doc](quint32 id) - { - VToolDetail *toolDet = qobject_cast(doc->getTool(id)); - SCASSERT(toolDet != nullptr); - bool ask = false; - toolDet->Remove(ask); - }; - - if (not retainPieces) - { - RemoveDetail(d1id); - RemoveDetail(d2id); - } - - SCASSERT(not children.isEmpty()) - SaveChildren(doc, id, children); - } - else - { - QVector children = AllChildren(doc, id); - if (not children.isEmpty()) - { - // This check need for backward compatibility - // Remove check and "else" part if min version is 0.3.2 - Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 2), - "Time to refactor the code."); - if (children.size() == countNodeD1 + countNodeD2-1) - { - qint32 i = 0; - do - { - UpdatePoints(data, d1.RemoveEdge(indexD1), i, children); - ++i; - if (i > d1.indexOfNode(det1p1.getId()) && pointsD2 < countNodeD2-1) - { - VDetail d2REdge = d2.RemoveEdge(indexD2); - qint32 j = 0; - FindIndexJ(pointsD2, d2, indexD2, j); - do - { - if (j >= countNodeD2) - { - j=0; - } - UpdatePoints(data, d2REdge, j, children, dx, dy, det1p1.getId(), angle); - ++pointsD2; - ++j; - } while (pointsD2 < countNodeD2-1); - } - } while (i d1.indexOfNode(det1p1.getId())) - { - const int childrenCount = children.size(); - VDetail d2REdge = d2.RemoveEdge(indexD2); - qint32 j = 0; - FindIndexJ(pointsD2, d2, indexD2, j); - do - { - if (j >= countNodeD2) - { - j=0; - } - UpdatePoints(data, d2REdge, j, children, dx, dy, det1p1.getId(), angle); - ++pointsD2; - ++j; - } while (pointsD2 < childrenCount); - break; - } - } while (iGeometricObject(det2p1.getId())); - p2 = VPointF(*data->GeometricObject(det2p2.getId())); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::FindIndexJ(const qint32 &pointsD2, const VDetail &d2, const quint32 &indexD2, qint32 &j) -{ - if (pointsD2 == 0) - { - VNodeDetail node1; - VNodeDetail node2; - d2.NodeOnEdge(indexD2, node1, node2); - const VDetail removedD2 = d2.RemoveEdge(indexD2); - const int k = removedD2.indexOfNode(node2.getId()); - SCASSERT(k != -1) - if (k == removedD2.CountNode()-1) - {//We have last node in detail, we wil begin from 0 - j = 0; - } - else - {// Continue from next node - j = k+1; - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief GetDetailFromFile parse detail from file. - * @param doc dom document container. - * @param domElement tag in xml tree. - * @return detail stored in file. - */ -QVector VToolUnionDetails::GetDetailFromFile(VAbstractPattern *doc, const QDomElement &domElement) -{ - QVector vector; - QDomNodeList detailList = domElement.childNodes(); - qint32 num = detailList.size(); - for (qint32 i = 0; i < num; ++i) - { - QDomElement element = detailList.at(i).toElement(); - if (element.isNull() == false) - { - if (element.tagName() == VToolUnionDetails::TagDetail) - { - VDetail d; - QDomNodeList nodeList = element.childNodes(); - qint32 num = nodeList.size(); - for (qint32 j = 0; j < num; ++j) - { - QDomElement element = nodeList.at(j).toElement(); - if (element.isNull() == false) - { - if (element.tagName() == VToolUnionDetails::TagNode) - { - quint32 id = doc->GetParametrUInt(element, AttrIdObject, NULL_ID_STR); - qreal mx = qApp->toPixel(doc->GetParametrDouble(element, AttrMx, "0.0")); - qreal my = qApp->toPixel(doc->GetParametrDouble(element, AttrMy, "0.0")); - const bool reversed = doc->GetParametrUInt(element, VToolDetail::AttrReverse, "0"); - Tool tool = Tool::NodePoint; - NodeDetail nodeType = NodeDetail::Contour; - QString t = doc->GetParametrString(element, "type", "NodePoint"); - if (t == QLatin1String("NodePoint")) - { - tool = Tool::NodePoint; - } - else if (t == QLatin1String("NodeArc")) - { - tool = Tool::NodeArc; - } - else if (t == QLatin1String("NodeElArc")) - { - tool = Tool::NodeElArc; - } - else if (t == QLatin1String("NodeSpline")) - { - tool = Tool::NodeSpline; - } - else if (t == QLatin1String("NodeSplinePath")) - { - tool = Tool::NodeSplinePath; - } - d.append(VNodeDetail(id, tool, nodeType, mx, my, reversed)); - } - } - } - vector.append(d); - } - } - } - return vector; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddToFile add tag with informations about tool into file. - */ -void VToolUnionDetails::AddToFile() -{ - QDomElement domElement = doc->createElement(getTagName()); - - doc->SetAttribute(domElement, VDomDocument::AttrId, id); - doc->SetAttribute(domElement, AttrType, ToolType); - doc->SetAttribute(domElement, AttrIndexD1, indexD1); - doc->SetAttribute(domElement, AttrIndexD2, indexD2); - - AddDetail(domElement, d1); - AddDetail(domElement, d2); - - AddToModeling(domElement); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief RefreshDataInFile refresh attributes in file. If attributes don't exist create them. - */ -void VToolUnionDetails::RefreshDataInFile() -{ - QDomElement domElement = doc->elementById(id); - if (domElement.isElement()) - { - doc->SetAttribute(domElement, AttrIndexD1, indexD1); - doc->SetAttribute(domElement, AttrIndexD2, indexD2); - - QDomNode domNode = domElement.firstChild(); - domNode = UpdateDetail(domNode, d1); - UpdateDetail(domNode, d2); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddDetail add detail to xml file. - * @param domElement tag in xml tree. - * @param d detail. - */ -void VToolUnionDetails::AddDetail(QDomElement &domElement, VDetail &d) -{ - QDomElement det = doc->createElement(TagDetail); - - for (int i = 0; i < d.CountNode(); ++i) - { - AddNode(det, d.at(i)); - } - - domElement.appendChild(det); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddNode add node to xml file. - * @param domElement tag in xml tree. - * @param node node. - */ -void VToolUnionDetails::AddNode(QDomElement &domElement, const VNodeDetail &node) -{ - //Right now method similar to method in class VToolDetail. - VToolDetail::AddNode(doc, domElement, node); -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief UpdateDetail update detail in xml tree. - * @param domNode dom node. - * @param d detail. - * @return return next detail tag in xml tree if exist. - */ -QDomNode VToolUnionDetails::UpdateDetail(const QDomNode &domNode, const VDetail &d) -{ - //QDomNode domNode = domElement.firstChild(); - while (domNode.isNull() == false) - { - if (domNode.isElement()) - { - QDomElement domElement = domNode.toElement(); - if (domElement.isNull() == false) - { - if (domElement.tagName() == VToolUnionDetails::TagDetail) - { - VDomDocument::RemoveAllChildren(domElement);//delete all nodes in detail - for (int i = 0; i < d.CountNode(); ++i) - { - AddNode(domElement, d.at(i));//rewrite nodes of detail - } - break; + return VAbstractPattern::ParsePieceNodes(element); } } } } - return domNode.nextSibling(); + + return VPiecePath(); } //--------------------------------------------------------------------------------------------------------------------- -/** - * @brief AddToModeling add tool to xml tree. - * @param domElement tag in xml tree. - */ -void VToolUnionDetails::AddToModeling(const QDomElement &domElement) +VPiecePath GetPiece1MainPath(VAbstractPattern *doc, quint32 id) { - QDomElement modeling = doc->GetDraw(drawName).firstChildElement(VAbstractPattern::TagModeling); - if (not modeling.isNull()) - { - modeling.appendChild(domElement); - } - else - { - qCDebug(vToolUnion, "Can't find tag %s.", qUtf8Printable(VAbstractPattern::TagModeling)); - return; - } + return GetPieceMainPath(1, doc, id); } //--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::IncrementReferences(const VDetail &d) const +VPiecePath GetPiece2MainPath(VAbstractPattern *doc, quint32 id) { - for (int i = 0; i < d.CountNode(); ++i) - { - switch (d.at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - const auto point = VAbstractTool::data.GeometricObject(d.at(i).getId()); - doc->IncrementReferens(point->getIdTool()); - break; - } - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - doc->IncrementReferens(d.at(i).getId()); - break; - default: - qDebug()<<"Get wrong tool type. Ignore."; - break; - } - } + return GetPieceMainPath(2, doc, id); } //--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::DecrementReferences(const VDetail &d) const -{ - for (int i = 0; i < d.CountNode(); ++i) - { - switch (d.at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - const auto point = VAbstractTool::data.GeometricObject(d.at(i).getId()); - doc->DecrementReferens(point->getIdTool()); - break; - } - case (Tool::NodeArc): - case (Tool::NodeElArc): - case (Tool::NodeSpline): - case (Tool::NodeSplinePath): - doc->DecrementReferens(d.at(i).getId()); - break; - default: - qDebug()<<"Get wrong tool type. Ignore."; - break; - } - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void VToolUnionDetails::SaveChildren(VAbstractPattern *doc, quint32 id, const QVector &children) -{ - QDomElement toolUnion = doc->elementById(id); - if (toolUnion.isNull()) - { - return; - } - - QDomElement tagChildren = doc->createElement(TagChildren); - - for (int i=0; icreateElement(TagChild); - tagChild.appendChild(doc->createTextNode(QString().setNum(children.at(i)))); - tagChildren.appendChild(tagChild); - } - - toolUnion.appendChild(tagChildren); -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector VToolUnionDetails::AllChildren(VAbstractPattern *doc, quint32 id) -{ - const QDomElement toolUnion = doc->elementById(id); - if (toolUnion.isNull()) - { - return QVector(); - } - - const QDomElement tagChildren = toolUnion.firstChildElement(TagChildren); - if (tagChildren.isNull()) - { - return QVector(); - } - - QVector childrenId; - const QDomNodeList listChildren = tagChildren.elementsByTagName(TagChild); - for (int i=0; i < listChildren.size(); ++i) - { - const QDomElement domElement = listChildren.at(i).toElement(); - if (not domElement.isNull()) - { - childrenId.append(domElement.text().toUInt()); - } - } - return childrenId; -} - -//--------------------------------------------------------------------------------------------------------------------- -quint32 VToolUnionDetails::TakeNextId(QVector &children) -{ - quint32 idChild = NULL_ID; - if (not children.isEmpty()) - { -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) - idChild = children.takeFirst(); -#else - idChild = children.first(); - children.remove(0); -#endif - } - else - { - idChild = NULL_ID; - } - return idChild; -} - -//--------------------------------------------------------------------------------------------------------------------- -QString VToolUnionDetails::DrawName(VAbstractPattern *doc, quint32 d1id, quint32 d2id) +QString DrawName(VAbstractPattern *doc, quint32 d1id, quint32 d2id) { const QDomElement detail1 = doc->elementById(d1id); if (detail1.isNull()) @@ -1191,3 +208,1063 @@ QString VToolUnionDetails::DrawName(VAbstractPattern *doc, quint32 d1id, quint32 return draw2Name; } } + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief BiasRotatePoint bias and rotate point. + * @param point point. + * @param dx bias x axis. + * @param dy bias y axis. + * @param pRotate point rotation. + * @param angle angle rotation. + */ +void BiasRotatePoint(VPointF *point, const qreal &dx, const qreal &dy, const QPointF &pRotate, const qreal &angle) +{ + point->setX(point->x()+dx); + point->setY(point->y()+dy); + QLineF line(pRotate, *point); + line.setAngle(line.angle()+angle); + point->setX(line.p2().x()); + point->setY(line.p2().y()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void PointsOnEdge(const VPiece &d, quint32 index, VPointF &p1, VPointF &p2, VContainer *data) +{ + VPieceNode det2p1; + VPieceNode det2p2; + d.GetPath().NodeOnEdge(index, det2p1, det2p2); + p1 = VPointF(*data->GeometricObject(det2p1.GetId())); + p2 = VPointF(*data->GeometricObject(det2p2.GetId())); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UnionInitParameters(const VToolUnionDetailsInitData &initData, VPieceNode &det1p1, qreal &dx, qreal &dy, + qreal &angle) +{ + const VPiece d1 = initData.data->GetPiece(initData.d1id); + VPieceNode det1p2; + d1.GetPath().NodeOnEdge(initData.indexD1, det1p1, det1p2); + Q_UNUSED(det1p2) + + VPointF point1; + VPointF point2; + PointsOnEdge(d1, initData.indexD1, point1, point2, initData.data); + + VPointF point3; + VPointF point4; + const VPiece d2 = initData.data->GetPiece(initData.d2id); + PointsOnEdge(d2, initData.indexD2, point3, point4, initData.data); + + dx = point1.x() - point4.x(); + 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); + + const QLineF p4p3 = QLineF(point4, point3); + const QLineF p1p2 = QLineF(point1, point2); + + angle = p4p3.angleTo(p1p2); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodePoint(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer point(new VPointF(*initData.data->GeometricObject(node.GetId()))); + point->setMode(Draw::Modeling); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + BiasRotatePoint(point.data(), dx, dy, *initData.data->GeometricObject(pRotate), angle); + } + + QScopedPointer point1(new VPointF(*point)); + + const quint32 idObject = initData.data->AddGObject(point.take()); + children.append(idObject); + point1->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(point1.take()); + VNodePoint::Create(initData.doc, initData.data, initData.scene, id, idObject, Document::FullParse, Source::FromGui, + drawName, idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeArc(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer arc = initData.data->GeometricObject(node.GetId()); + VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); + VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); + QScopedPointer center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + center->setMode(Draw::Modeling); + VPointF *tmpCenter = center.take(); + const quint32 idCenter = initData.data->AddGObject(tmpCenter); + Q_UNUSED(idCenter) + QScopedPointer arc1(new VArc(*tmpCenter, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), + QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle()))); + arc1->setMode(Draw::Modeling); + + QScopedPointerarc2(new VArc(*arc1)); + + const quint32 idObject = initData.data->AddGObject(arc1.take()); + children.append(idObject); + + arc2->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(arc2.take()); + + VNodeArc::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, drawName, idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeElArc(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer arc = initData.data->GeometricObject(node.GetId()); + VPointF p1 = VPointF(arc->GetP1(), "A", 0, 0); + VPointF p2 = VPointF(arc->GetP2(), "A", 0, 0); + QScopedPointer center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + center->setMode(Draw::Modeling); + VPointF *tmpCenter = center.take(); + quint32 idCenter = initData.data->AddGObject(tmpCenter); + Q_UNUSED(idCenter) + QScopedPointer arc1(new VEllipticalArc (*tmpCenter, arc->GetRadius1(), arc->GetRadius2(), + arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), + l1.angle(), QString().setNum(l1.angle()), l2.angle(), + QString().setNum(l2.angle()), 0, "0")); + arc1->setMode(Draw::Modeling); + + QScopedPointer arc2(new VEllipticalArc(*arc1)); + + const quint32 idObject = initData.data->AddGObject(arc1.take()); + children.append(idObject); + + arc2->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(arc2.take()); + + VNodeEllipticalArc::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, + drawName, idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeSpline(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer spline = + initData.data->GeometricObject(node.GetId()); + + QScopedPointer p1(new VPointF(spline->GetP1())); + VPointF p2 = VPointF(spline->GetP2()); + VPointF p3 = VPointF(spline->GetP3()); + QScopedPointer p4(new VPointF(spline->GetP4())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + VSpline *spl = new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling); + const quint32 idObject = initData.data->AddGObject(spl); + children.append(idObject); + + VSpline *spl1 = new VSpline(*spl); + spl1->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(spl1); + VNodeSpline::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, drawName, + idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 AddNodeSplinePath(const VPieceNode &node, const VToolUnionDetailsInitData &initData, quint32 idTool, + QVector &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer path(new VSplinePath()); + path->setMode(Draw::Modeling); + const QSharedPointer splinePath = + initData.data->GeometricObject(node.GetId()); + for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) + { + const VSpline spline = splinePath->GetSpline(i); + + QScopedPointer p1(new VPointF(spline.GetP1())); + VPointF p2 = VPointF(spline.GetP2()); + VPointF p3 = VPointF(spline.GetP3()); + QScopedPointer p4(new VPointF(spline.GetP4())); + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *initData.data->GeometricObject(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + VSpline spl = VSpline(*p1, p2, p3, *p4); + if (i==1) + { + const qreal angle1 = spl.GetStartAngle()+180; + const QString angle1F = QString().number(angle1); + + path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), + 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); + } + + const qreal angle2 = spl.GetEndAngle()+180; + const QString angle2F = QString().number(angle2); + qreal pL2 = 0; + QString pL2F("0"); + if (i+1 <= splinePath->CountSubSpl()) + { + const VSpline nextSpline = splinePath->GetSpline(i+1); + pL2 = nextSpline.GetC1Length(); + pL2F = nextSpline.GetC1LengthFormula(); + } + + path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, + spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); + } + QScopedPointer path1(new VSplinePath(*path)); + + const quint32 idObject = initData.data->AddGObject(path.take()); + children.append(idObject); + + path1->setMode(Draw::Modeling); + const quint32 id = initData.data->AddGObject(path1.take()); + + VNodeSplinePath::Create(initData.doc, initData.data, id, idObject, Document::FullParse, Source::FromGui, drawName, + idTool); + return id; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddToNewDetail create united detail adding one node per time. + */ +void AddNodeToNewDetail(const VToolUnionDetailsInitData &initData, VPiece &newDetail, const VPiecePath &det, int i, + quint32 idTool, QVector &children, const QString &drawName, qreal dx = 0, qreal dy = 0, + quint32 pRotate = NULL_ID, qreal angle = 0); + +void AddNodeToNewDetail(const VToolUnionDetailsInitData &initData, VPiece &newDetail, const VPiecePath &det, int i, + quint32 idTool, QVector &children, const QString &drawName, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const VPieceNode &node = det.at(i); + quint32 id = 0; + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + id = AddNodePoint(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeArc): + id = AddNodeArc(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeElArc): + id = AddNodeElArc(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeSpline): + id = AddNodeSplinePath(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + case (Tool::NodeSplinePath): + id = AddNodeSplinePath(node, initData, idTool, children, drawName, dx, dy, pRotate, angle); + break; + default: + qDebug()<<"May be wrong tool type!!! Ignoring."< &children) +{ + QDomElement toolUnion = doc->elementById(id); + if (toolUnion.isNull()) + { + return; + } + + QDomElement tagChildren = doc->createElement(VToolUnionDetails::TagChildren); + QDomElement tagNodes = doc->createElement(VAbstractPattern::TagNodes); + + for (int i=0; icreateElement(VToolUnionDetails::TagChild); + tagChild.appendChild(doc->createTextNode(QString().setNum(children.at(i)))); + tagNodes.appendChild(tagChild); + } + + tagChildren.appendChild(tagNodes); + toolUnion.appendChild(tagChildren); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector GetNodesChildren(VAbstractPattern *doc, quint32 id) +{ + const QDomElement toolUnion = doc->elementById(id); + if (toolUnion.isNull()) + { + return QVector(); + } + + const QDomElement tagChildren = toolUnion.firstChildElement(VToolUnionDetails::TagChildren); + if (tagChildren.isNull()) + { + return QVector(); + } + + const QDomElement tagNodes = tagChildren.firstChildElement(VAbstractPattern::TagNodes); + if (tagNodes.isNull()) + { + return QVector(); + } + + QVector childrenId; + const QDomNodeList listChildren = tagNodes.elementsByTagName(VToolUnionDetails::TagChild); + for (int i=0; i < listChildren.size(); ++i) + { + const QDomElement domElement = listChildren.at(i).toElement(); + if (not domElement.isNull()) + { + childrenId.append(domElement.text().toUInt()); + } + } + return childrenId; +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 TakeNextId(QVector &children) +{ + quint32 idChild = NULL_ID; + if (not children.isEmpty()) + { +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + idChild = children.takeFirst(); +#else + idChild = children.first(); + children.remove(0); +#endif + } + else + { + idChild = NULL_ID; + } + return idChild; +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodePoint(VContainer *data, const VPieceNode &node, QVector &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer point(new VPointF(*data->GeometricObject(node.GetId()))); + point->setMode(Draw::Modeling); + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + BiasRotatePoint(point.data(), dx, dy, *data->GeometricObject(pRotate), angle); + } + data->UpdateGObject(TakeNextId(children), point.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeArc(VContainer *data, const VPieceNode &node, QVector &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer arc = data->GeometricObject(node.GetId()); + VPointF p1 = VPointF(arc->GetP1()); + VPointF p2 = VPointF(arc->GetP2()); + QScopedPointer center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + + QScopedPointer arc1(new VArc(*center, arc->GetRadius(), arc->GetFormulaRadius(), l1.angle(), + QString().setNum(l1.angle()), l2.angle(), QString().setNum(l2.angle()))); + arc1->setMode(Draw::Modeling); + data->UpdateGObject(TakeNextId(children), arc1.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeElArc(VContainer *data, const VPieceNode &node, QVector &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer arc = data->GeometricObject(node.GetId()); + VPointF p1 = VPointF(arc->GetP1()); + VPointF p2 = VPointF(arc->GetP2()); + QScopedPointer center(new VPointF(arc->GetCenter())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject(pRotate); + + BiasRotatePoint(&p1, dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(center.data(), dx, dy, p, angle); + } + + QLineF l1(*center, p1); + QLineF l2(*center, p2); + + QScopedPointer arc1(new VEllipticalArc (*center, arc->GetRadius1(), arc->GetRadius2(), + arc->GetFormulaRadius1(), arc->GetFormulaRadius2(), + l1.angle(), QString().setNum(l1.angle()), l2.angle(), + QString().setNum(l2.angle()), 0, "0")); + arc1->setMode(Draw::Modeling); + data->UpdateGObject(TakeNextId(children), arc1.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeSpline(VContainer *data, const VPieceNode &node, QVector &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const QSharedPointer spline = + data->GeometricObject(node.GetId()); + + QScopedPointer p1(new VPointF(spline->GetP1())); + VPointF p2 = VPointF(spline->GetP2()); + VPointF p3 = VPointF(spline->GetP3()); + QScopedPointer p4(new VPointF(spline->GetP4())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + QScopedPointer spl(new VSpline(*p1, p2, p3, *p4, 0, Draw::Modeling)); + data->UpdateGObject(TakeNextId(children), spl.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateNodeSplinePath(VContainer *data, const VPieceNode &node, QVector &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + QScopedPointer path(new VSplinePath()); + path->setMode(Draw::Modeling); + const QSharedPointer splinePath = + data->GeometricObject(node.GetId()); + SCASSERT(splinePath != nullptr) + for (qint32 i = 1; i <= splinePath->CountSubSpl(); ++i) + { + const VSpline spline = splinePath->GetSpline(i); + + QScopedPointer p1(new VPointF(spline.GetP1())); + VPointF p2 = VPointF(spline.GetP2()); + VPointF p3 = VPointF(spline.GetP3()); + QScopedPointer p4(new VPointF(spline.GetP4())); + + if (not qFuzzyIsNull(dx) || not qFuzzyIsNull(dy) || pRotate != NULL_ID) + { + const QPointF p = *data->GeometricObject(pRotate); + + BiasRotatePoint(p1.data(), dx, dy, p, angle); + BiasRotatePoint(&p2, dx, dy, p, angle); + BiasRotatePoint(&p3, dx, dy, p, angle); + BiasRotatePoint(p4.data(), dx, dy, p, angle); + } + + VSpline spl = VSpline(*p1, p2, p3, *p4); + if (i==1) + { + const qreal angle1 = spl.GetStartAngle()+180; + const QString angle1F = QString().number(angle1); + + path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(), + 0, "0", spline.GetC1Length(), spline.GetC1LengthFormula())); + } + + const qreal angle2 = spl.GetEndAngle()+180; + const QString angle2F = QString().number(angle2); + + qreal pL2 = 0; + QString pL2F("0"); + if (i+1 <= splinePath->CountSubSpl()) + { + const VSpline nextSpline = splinePath->GetSpline(i+1); + pL2 = nextSpline.GetC1Length(); + pL2F = nextSpline.GetC1LengthFormula(); + } + + path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F, + spline.GetC2Length(), spline.GetC2LengthFormula(), pL2, pL2F)); + } + data->UpdateGObject(TakeNextId(children), path.take()); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief UpdateNodes update nodes of united detail. + * @param data container with variables. + * @param det detail's nodes. + * @param i index node in detail. + * @param children list ids of all children. + * @param dx bias node x axis. + * @param dy bias node y axis. + * @param pRotate point rotation. + * @param angle angle rotation. + */ +void UpdateNodes(VContainer *data, const VPiecePath &det, int i, QVector &children, + qreal dx = 0, qreal dy = 0, quint32 pRotate = NULL_ID, qreal angle = 0); +void UpdateNodes(VContainer *data, const VPiecePath &det, int i, QVector &children, qreal dx, qreal dy, + quint32 pRotate, qreal angle) +{ + const VPieceNode &node = det.at(i); + switch (node.GetTypeTool()) + { + case (Tool::NodePoint): + UpdateNodePoint(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeArc): + UpdateNodeArc(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeElArc): + UpdateNodeElArc(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeSpline): + UpdateNodeSpline(data, node, children, dx, dy, pRotate, angle); + break; + case (Tool::NodeSplinePath): + UpdateNodeSplinePath(data, node, children, dx, dy, pRotate, angle); + break; + default: + qDebug()<<"May be wrong tool type!!! Ignoring."<GetPiece(initData.d1id); + const VPiecePath d1Path = d1.GetPath().RemoveEdge(initData.indexD1); + + const VPiece d2 = initData.data->GetPiece(initData.d2id); + const VPiecePath d2Path = d2.GetPath().RemoveEdge(initData.indexD2); + + const qint32 countNodeD1 = d1Path.CountNodes(); + const qint32 countNodeD2 = d2Path.CountNodes(); + + qint32 i = 0; + VPiece newDetail; + QVector children; + const int det1P1Index = d1.GetPath().indexOfNode(det1p1.GetId()); + do + { + AddNodeToNewDetail(initData, newDetail, d1Path, i, id, children, drawName); + ++i; + if (i > det1P1Index && pointsD2 < countNodeD2-1) + { + qint32 j = 0; + FindIndexJ(pointsD2, d2.GetPath(), initData.indexD2, j); + do + { + if (j >= countNodeD2) + { + j=0; + } + AddNodeToNewDetail(initData, newDetail, d2Path, j, id, children, drawName, dx, dy, det1p1.GetId(), + angle); + ++pointsD2; + ++j; + } while (pointsD2 < countNodeD2-1); + } + } while (i < countNodeD1); + + SCASSERT(not children.isEmpty()) + SaveNodesChildren(initData.doc, id, children); + + newDetail.SetName(QObject::tr("United detail")); + newDetail.SetSAWidth(d1.GetSAWidth()); + newDetail.SetMx(d1.GetMx()); + newDetail.SetMy(d1.GetMy()); + VToolSeamAllowance::Create(0, newDetail, initData.scene, initData.doc, initData.data, initData.parse, + Source::FromTool, drawName); + + auto RemoveDetail = [initData](quint32 id) + { + VToolSeamAllowance *toolDet = qobject_cast(initData.doc->getTool(id)); + SCASSERT(toolDet != nullptr); + bool ask = false; + toolDet->Remove(ask); + }; + + if (not initData.retainPieces) + { + RemoveDetail(initData.d1id); + RemoveDetail(initData.d2id); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void UpdateUnitedDetail(qint32 &pointsD2, quint32 id, const VToolUnionDetailsInitData &initData, + const VPieceNode &det1p1, qreal dx, qreal dy, qreal angle) +{ + const VPiecePath d1Path = GetPiece1MainPath(initData.doc, initData.d1id); + const VPiecePath d1REPath = d1Path.RemoveEdge(initData.indexD1); + + const VPiecePath d2Path = GetPiece2MainPath(initData.doc, initData.d2id); + const VPiecePath d2REPath = d2Path.RemoveEdge(initData.indexD2); + + const qint32 countNodeD1 = d1REPath.CountNodes(); + const qint32 countNodeD2 = d2REPath.CountNodes(); + + QVector children = GetNodesChildren(initData.doc, id); + if (not children.isEmpty()) + { + // This check need for backward compatibility + // Remove check and "else" part if min version is 0.3.2 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 3, 2), + "Time to refactor the code."); + if (children.size() == countNodeD1 + countNodeD2-1) + { + qint32 i = 0; + const int indexOfNode = d1Path.indexOfNode(det1p1.GetId()); + do + { + UpdateNodes(initData.data, d1REPath, i, children); + ++i; + if (i > indexOfNode && pointsD2 < countNodeD2-1) + { + qint32 j = 0; + FindIndexJ(pointsD2, d2Path, initData.indexD2, j); + do + { + if (j >= countNodeD2) + { + j=0; + } + UpdateNodes(initData.data, d2REPath, j, children, dx, dy, det1p1.GetId(), angle); + ++pointsD2; + ++j; + } while (pointsD2 < countNodeD2-1); + } + } while (i indexOfNode) + { + const int childrenCount = children.size(); + qint32 j = 0; + FindIndexJ(pointsD2, d2Path, initData.indexD2, j); + do + { + if (j >= countNodeD2) + { + j=0; + } + UpdateNodes(initData.data, d2REPath, j, children, dx, dy, det1p1.GetId(), angle); + ++pointsD2; + ++j; + } while (pointsD2 < childrenCount); + break; + } + } while (i objects = GetReferenceObjects(); + for(int i = 0; i < objects.size(); ++i) + { + doc->IncrementReferens(objects.at(i)); + } + + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::InUse); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::decrementReferens() +{ + VDataTool::decrementReferens(); + if (_referens == 0) + { + const QVector objects = GetReferenceObjects(); + for(int i = 0; i < objects.size(); ++i) + { + doc->DecrementReferens(objects.at(i)); + } + + QDomElement domElement = doc->elementById(id); + if (domElement.isElement()) + { + doc->SetParametrUsage(domElement, AttrInUse, NodeUsage::NotInUse); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolUnionDetails::GroupVisibility(quint32 object, bool visible) +{ + Q_UNUSED(object) + Q_UNUSED(visible) +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Create help create tool from GUI. + * @param dialog dialog. + * @param doc dom document container. + * @param data container with variables. + */ +VToolUnionDetails* VToolUnionDetails::Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, + VContainer *data) +{ + SCASSERT(dialog != nullptr) + const DialogUnionDetails *dialogTool = qobject_cast(dialog); + SCASSERT(dialogTool != nullptr) + + VToolUnionDetailsInitData initData; + initData.d1id = dialogTool->getD1(); + initData.d2id = dialogTool->getD2(); + initData.indexD1 = static_cast(dialogTool->getIndexD1()); + initData.indexD2 = static_cast(dialogTool->getIndexD2()); + initData.scene = scene; + initData.doc = doc; + initData.data = data; + initData.parse = Document::FullParse; + initData.typeCreation = Source::FromGui; + initData.retainPieces = dialogTool->RetainPieces(); + + qApp->getUndoStack()->beginMacro(tr("union details")); + VToolUnionDetails* tool = Create(0, initData); + qApp->getUndoStack()->endMacro(); + return tool; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Create help create tool. + * @param _id tool id, 0 if tool doesn't exist yet. + * @param d1 first detail. + * @param d2 second detail. + * @param d1id id first detail. + * @param d2id id second detail. + * @param indexD1 index edge in first detail. + * @param indexD2 index edge in second detail. + * @param scene pointer to scene. + * @param doc dom document container. + * @param data container with variables. + * @param parse parser file mode. + * @param typeCreation way we create this tool. + */ +VToolUnionDetails* VToolUnionDetails::Create(const quint32 _id, const VToolUnionDetailsInitData &initData) +{ + VToolUnionDetails *unionDetails = nullptr; + quint32 id = _id; + if (initData.typeCreation == Source::FromGui) + { + id = initData.data->getNextId(); + } + else + { + if (initData.parse != Document::FullParse) + { + initData.doc->UpdateToolData(id, initData.data); + } + } + + //First add tool to file + VAbstractTool::AddRecord(id, Tool::UnionDetails, initData.doc); + if (initData.parse == Document::FullParse) + { + //Scene doesn't show this tool, so doc will destroy this object. + unionDetails = new VToolUnionDetails(id, initData); + initData.doc->AddTool(id, unionDetails); + // Unfortunatelly doc will destroy all objects only in the end, but we should delete them before each FullParse + initData.doc->AddToolOnRemove(unionDetails); + } + UniteDetails(id, initData); + return unionDetails; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddToFile add tag with informations about tool into file. + */ +void VToolUnionDetails::AddToFile() +{ + QDomElement domElement = doc->createElement(getTagName()); + + doc->SetAttribute(domElement, VDomDocument::AttrId, id); + doc->SetAttribute(domElement, AttrType, ToolType); + doc->SetAttribute(domElement, AttrIndexD1, indexD1); + doc->SetAttribute(domElement, AttrIndexD2, indexD2); + + AddDetail(domElement, data.GetPiece(d1id)); + AddDetail(domElement, data.GetPiece(d2id)); + + AddToModeling(domElement); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief RefreshDataInFile refresh attributes in file. If attributes don't exist create them. + */ +void VToolUnionDetails::RefreshDataInFile() +{ + // do nothing +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddDetail add detail to xml file. + * @param domElement tag in xml tree. + * @param d detail. + */ +void VToolUnionDetails::AddDetail(QDomElement &domElement, const VPiece &d) const +{ + QDomElement det = doc->createElement(TagDetail); + + // nodes + VToolSeamAllowance::AddNodes(doc, det, d); + //custom seam allowance + VToolSeamAllowance::AddCSARecords(doc, det, d.GetCustomSARecords()); + VToolSeamAllowance::AddInternalPaths(doc, det, d.GetInternalPaths()); + + domElement.appendChild(det); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AddToModeling add tool to xml tree. + * @param domElement tag in xml tree. + */ +void VToolUnionDetails::AddToModeling(const QDomElement &domElement) +{ + const QString drawName = DrawName(doc, d1id, d2id); + SCASSERT(not drawName.isEmpty()) + + QDomElement modeling = doc->GetDraw(drawName).firstChildElement(VAbstractPattern::TagModeling); + if (not modeling.isNull()) + { + modeling.appendChild(domElement); + } + else + { + qCCritical(vToolUnion, "Can't find tag %s.", qUtf8Printable(VAbstractPattern::TagModeling)); + return; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VToolUnionDetails::GetReferenceObjects() const +{ + QVector list; + const QDomElement tool = doc->elementById(id); + if (tool.isNull()) + { + return list; + } + + const QStringList parts = QStringList() << VAbstractPattern::TagNodes /*0*/ + << VToolSeamAllowance::TagCSA /*1*/ + << VToolSeamAllowance::TagIPaths; /*2*/ + + const QDomNodeList nodesList = tool.childNodes(); + for (qint32 i = 0; i < nodesList.size(); ++i) + { + const QDomElement element = nodesList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VToolUnionDetails::TagDetail) + { + const QDomNodeList detList = element.childNodes(); + for (qint32 j = 0; j < detList.size(); ++j) + { + const QDomElement element = detList.at(j).toElement(); + if (not element.isNull()) + { + switch (parts.indexOf(element.tagName())) + { + case 0://VAbstractPattern::TagNodes + list += NodesReferenceObjects(element); + break; + case 1://VToolSeamAllowance::TagCSA + case 2://VToolSeamAllowance::TagIPaths + { + const quint32 id = doc->GetParametrUInt(element, VToolSeamAllowance::AttrPath, NULL_ID_STR); + if (id > NULL_ID) + { + list.append(id); + } + break; + } + default: + break; + } + } + } + } + } + return list; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VToolUnionDetails::NodesReferenceObjects(const QDomElement &nodes) const +{ + QVector list; + + const QDomNodeList nodeList = nodes.childNodes(); + for (qint32 i = 0; i < nodeList.size(); ++i) + { + const QDomElement element = nodeList.at(i).toElement(); + if (not element.isNull() && element.tagName() == VToolUnionDetails::TagNode) + { + const quint32 id = doc->GetParametrUInt(element, AttrIdObject, NULL_ID_STR); + if (id > NULL_ID) + { + list.append(id); + } + } + } + + return list; +} diff --git a/src/libs/vtools/tools/vtooluniondetails.h b/src/libs/vtools/tools/vtooluniondetails.h index c7b44b6da..2265a0677 100644 --- a/src/libs/vtools/tools/vtooluniondetails.h +++ b/src/libs/vtools/tools/vtooluniondetails.h @@ -43,7 +43,7 @@ #include "../ifc/xml/vabstractpattern.h" #include "../vmisc/def.h" #include "vabstracttool.h" -#include "vdetail.h" +#include "../vpatterndb/vpiece.h" class DialogTool; class QDomElement; @@ -54,6 +54,33 @@ class VMainGraphicsScene; class VNodeDetail; class VPointF; +struct VToolUnionDetailsInitData +{ + VToolUnionDetailsInitData() + : d1id(NULL_ID), + d2id(NULL_ID), + indexD1(NULL_ID), + indexD2(NULL_ID), + scene(nullptr), + doc(nullptr), + data(nullptr), + parse(Document::FullParse), + typeCreation(Source::FromFile), + retainPieces(false) + {} + + quint32 d1id; + quint32 d2id; + quint32 indexD1; + quint32 indexD2; + VMainGraphicsScene *scene; + VAbstractPattern *doc; + VContainer *data; + Document parse; + Source typeCreation; + bool retainPieces; +}; + /** * @brief The VToolUnionDetails class tool union details. */ @@ -67,13 +94,7 @@ public: virtual void setDialog() {} static VToolUnionDetails *Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data); - static VToolUnionDetails *Create(const quint32 _id, const VDetail &d1, const VDetail &d2, const quint32 &d1id, - const quint32 &d2id, const quint32 &indexD1, const quint32 &indexD2, - VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data, - const Document &parse, - const Source &typeCreation, - bool retainPieces = false); - static QVector GetDetailFromFile(VAbstractPattern *doc, const QDomElement &domElement); + static VToolUnionDetails *Create(const quint32 _id, const VToolUnionDetailsInitData &initData); static const QString ToolType; static const QString TagDetail; @@ -105,48 +126,24 @@ protected: virtual void SetVisualization() Q_DECL_OVERRIDE {} private: Q_DISABLE_COPY(VToolUnionDetails) - /** @brief d1 first detail. */ - VDetail d1; + /** @brief d1 first detail id. */ + quint32 d1id; - /** @brief d2 second detail. */ - VDetail d2; + /** @brief d2 second detail id. */ + quint32 d2id; /** @brief indexD1 index edge in first detail. */ - quint32 indexD1; + quint32 indexD1; /** @brief indexD2 index edge in second detail. */ - quint32 indexD2; + quint32 indexD2; - QString drawName; + VToolUnionDetails(quint32 id, const VToolUnionDetailsInitData &initData, QObject *parent = nullptr); - VToolUnionDetails(VAbstractPattern *doc, VContainer *data, const quint32 &id, const VDetail &d1, const VDetail &d2, - const quint32 &indexD1, const quint32 &indexD2, const Source &typeCreation, - const QString &drawName, QObject *parent = nullptr); - - void AddDetail(QDomElement &domElement, VDetail &d); - void AddNode(QDomElement &domElement, const VNodeDetail &node); - QDomNode UpdateDetail(const QDomNode &domNode, const VDetail &d); - void AddToModeling(const QDomElement &domElement); - void IncrementReferences(const VDetail &d) const; - void DecrementReferences(const VDetail &d) const; - - static void SaveChildren(VAbstractPattern *doc, quint32 id, const QVector &children); - static QVector AllChildren(VAbstractPattern *doc, quint32 id); - static quint32 TakeNextId(QVector &children); - static QString DrawName(VAbstractPattern *doc, quint32 d1id, quint32 d2id); - static void PointsOnEdge(const VDetail &d, const quint32 &index, VPointF &p1, VPointF &p2, - VContainer *data); - static void FindIndexJ(const qint32 &pointsD2, const VDetail &d2, const quint32 &indexD2, qint32 &j); - static void AddToNewDetail(VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data, - VDetail &newDetail, const VDetail &det, const int &i, const quint32 &idTool, - QVector &children, const QString &drawName, const qreal &dx = 0, - const qreal &dy = 0, const quint32 &pRotate = NULL_ID, - const qreal &angle = 0); - static void UpdatePoints(VContainer *data, const VDetail &det, const int &i, QVector &children, - const qreal &dx = 0, const qreal &dy = 0, const quint32 &pRotate = NULL_ID, - const qreal &angle = 0); - static void BiasRotatePoint(VPointF *point, const qreal &dx, const qreal &dy, const QPointF &pRotate, - const qreal &angle); + void AddDetail(QDomElement &domElement, const VPiece &d) const; + void AddToModeling(const QDomElement &domElement); + QVector GetReferenceObjects() const; + QVector NodesReferenceObjects(const QDomElement &nodes) const; }; #endif // VTOOLUNIONDETAILS_H