From 1d56289c79ea1797122d7bdbccb7d32aeb590b44 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Fri, 25 Dec 2020 09:01:21 +0100 Subject: [PATCH] Sketcher: restric ViewProviderSketch access to the solver ========================================================= -> Split read and read/write operations New interface to access the solver object (Sketch) of SketchObject is now read only (const): const Sketcher::Sketch &getSolvedSketch(void) const; -> Encapsulate solver r/w access in SketchObject Rationale: - r/w access (access to non-const functions of the solver) leads to unsynchronised solver status. - Before this commit there was a non-enforceable shared responsibility between ViewProviderSketch and SketchObject. - This commit centralises r/w access in SketchObject and SketchObject takes responsibility for doing whatever necessary so that the solver is synchronised as appropriate. - For read-only access (const functions) it is possible to use at ViewProviderSketch getSolvedSketch() returning a const reference to the solver object. - As it regards the advanced solver configuration dialog, it has been modified to configure by const-casting that reference. This is not optimal, but it is deemed acceptable, because it should be rewritten sooner or later to include only useful information and the configuration probably centralised in an individual configuration object, possibly compatible with several solvers (e.g. DeepSOIC's ConstraintSolver too). --- src/Mod/Sketcher/App/SketchObject.h | 18 ++- .../Gui/TaskSketcherSolverAdvanced.cpp | 103 +++++++++--------- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 90 +++++++-------- src/Mod/Sketcher/Gui/ViewProviderSketch.h | 12 ++ 4 files changed, 128 insertions(+), 95 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index c3386cabda..66050695a0 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -353,9 +353,23 @@ public: inline const std::vector &getLastConflicting(void) const { return lastConflicting; } /// gets the redundant constraints of last solver execution inline const std::vector &getLastRedundant(void) const { return lastRedundant; } - /// gets the solved sketch as a reference - inline Sketch &getSolvedSketch(void) {return solvedSketch;} +public: /* Solver exposed interface */ + /// gets the solved sketch as a reference + inline const Sketch &getSolvedSketch(void) const {return solvedSketch;} + /// enables/disables solver initial solution recalculation when moving point mode (useful for dragging) + inline void setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint) + {solvedSketch.setRecalculateInitialSolutionWhileMovingPoint(recalculateInitialSolutionWhileMovingPoint);} + /// Forwards a request for a temporary initMove to the solver using the current sketch state as a reference (enables dragging) + inline int initTemporaryMove(int geoId, PointPos pos, bool fine=true) + { return solvedSketch.initMove(geoId,pos,fine);} + /// Forwards a request for point or curve temporary movement to the solver using the current state as a reference (enables dragging) + inline int moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative=false) + { return solvedSketch.movePoint(geoId, pos, toPoint, relative);} + inline void updateSolverExtension(int geoId, std::unique_ptr && ext) + { return solvedSketch.updateExtension(geoId, std::move(ext));} + +public: /// returns the geometric elements/vertex which the solver detects as having dependent parameters. /// these parameters relate to not fully constraint edges/vertices. void getGeometryWithDependentParameters(std::vector>& geometrymap); diff --git a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp index cf6769a11a..c5f6b4edb3 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp @@ -132,9 +132,12 @@ void TaskSketcherSolverAdvanced::updateDefaultMethodParameters(void) ui->lineEditSolverParam1->setText(QString::number(eps).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditSolverParam2->setText(QString::number(eps1).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditSolverParam3->setText(QString::number(tau).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); - sketchView->getSketchObject()->getSolvedSketch().setLM_eps(eps); - sketchView->getSketchObject()->getSolvedSketch().setLM_eps1(eps1); - sketchView->getSketchObject()->getSolvedSketch().setLM_tau(tau); + // SketchObject has encapsulated write-access. The current use of const_cast just for configuration is + // deemed acceptable. Eventually this dialog should be rewritten to include only useful information and the configuration + // centralised in an individual configuration object, possibly compatible with several solvers (e.g. DeepSOIC's ConstraintSolver) + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps(eps); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1(eps1); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_tau(tau); break; } case 2: // DogLeg @@ -151,9 +154,9 @@ void TaskSketcherSolverAdvanced::updateDefaultMethodParameters(void) ui->lineEditSolverParam1->setText(QString::number(tolg).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditSolverParam2->setText(QString::number(tolx).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditSolverParam3->setText(QString::number(tolf).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); - sketchView->getSketchObject()->getSolvedSketch().setDL_tolg(tolg); - sketchView->getSketchObject()->getSolvedSketch().setDL_tolf(tolf); - sketchView->getSketchObject()->getSolvedSketch().setDL_tolx(tolx); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolg(tolg); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolf(tolf); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolx(tolx); break; } } @@ -198,9 +201,9 @@ void TaskSketcherSolverAdvanced::updateRedundantMethodParameters(void) ui->lineEditRedundantSolverParam1->setText(QString::number(eps).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditRedundantSolverParam2->setText(QString::number(eps1).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditRedundantSolverParam3->setText(QString::number(tau).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); - sketchView->getSketchObject()->getSolvedSketch().setLM_epsRedundant(eps); - sketchView->getSketchObject()->getSolvedSketch().setLM_eps1Redundant(eps1); - sketchView->getSketchObject()->getSolvedSketch().setLM_tauRedundant(eps1); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_epsRedundant(eps); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1Redundant(eps1); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_tauRedundant(eps1); break; } case 2: // DogLeg @@ -217,9 +220,9 @@ void TaskSketcherSolverAdvanced::updateRedundantMethodParameters(void) ui->lineEditRedundantSolverParam1->setText(QString::number(tolg).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditRedundantSolverParam2->setText(QString::number(tolx).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); ui->lineEditRedundantSolverParam3->setText(QString::number(tolf).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper())); - sketchView->getSketchObject()->getSolvedSketch().setDL_tolgRedundant(tolg); - sketchView->getSketchObject()->getSolvedSketch().setDL_tolfRedundant(tolf); - sketchView->getSketchObject()->getSolvedSketch().setDL_tolxRedundant(tolx); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolgRedundant(tolg); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolfRedundant(tolf); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolxRedundant(tolx); break; } } @@ -238,14 +241,14 @@ void TaskSketcherSolverAdvanced::on_lineEditSolverParam1_editingFinished() { case 1: // LM { - sketchView->getSketchObject()->getSolvedSketch().setLM_eps(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps(val); ui->lineEditSolverParam1->setEntryName("LM_eps"); ui->lineEditSolverParam1->onSave(); break; } case 2: // DogLeg { - sketchView->getSketchObject()->getSolvedSketch().setDL_tolg(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolg(val); ui->lineEditSolverParam1->setEntryName("DL_tolg"); ui->lineEditSolverParam1->onSave(); break; @@ -266,14 +269,14 @@ void TaskSketcherSolverAdvanced::on_lineEditRedundantSolverParam1_editingFinishe { case 1: // LM { - sketchView->getSketchObject()->getSolvedSketch().setLM_epsRedundant(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_epsRedundant(val); ui->lineEditRedundantSolverParam1->setEntryName("Redundant_LM_eps"); ui->lineEditRedundantSolverParam1->onSave(); break; } case 2: // DogLeg { - sketchView->getSketchObject()->getSolvedSketch().setDL_tolgRedundant(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolgRedundant(val); ui->lineEditRedundantSolverParam1->setEntryName("Redundant_DL_tolg"); ui->lineEditRedundantSolverParam1->onSave(); break; @@ -294,14 +297,14 @@ void TaskSketcherSolverAdvanced::on_lineEditSolverParam2_editingFinished() { case 1: // LM { - sketchView->getSketchObject()->getSolvedSketch().setLM_eps1(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1(val); ui->lineEditSolverParam2->setEntryName("LM_eps1"); ui->lineEditSolverParam2->onSave(); break; } case 2: // DogLeg { - sketchView->getSketchObject()->getSolvedSketch().setDL_tolx(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolx(val); ui->lineEditSolverParam2->setEntryName("DL_tolx"); ui->lineEditSolverParam2->onSave(); break; @@ -322,14 +325,14 @@ void TaskSketcherSolverAdvanced::on_lineEditRedundantSolverParam2_editingFinishe { case 1: // LM { - sketchView->getSketchObject()->getSolvedSketch().setLM_eps1Redundant(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1Redundant(val); ui->lineEditRedundantSolverParam2->setEntryName("Redundant_LM_eps1"); ui->lineEditRedundantSolverParam2->onSave(); break; } case 2: // DogLeg { - sketchView->getSketchObject()->getSolvedSketch().setDL_tolxRedundant(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolxRedundant(val); ui->lineEditRedundantSolverParam2->setEntryName("Redundant_DL_tolx"); ui->lineEditRedundantSolverParam2->onSave(); break; @@ -350,14 +353,14 @@ void TaskSketcherSolverAdvanced::on_lineEditSolverParam3_editingFinished() { case 1: // LM { - sketchView->getSketchObject()->getSolvedSketch().setLM_tau(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_tau(val); ui->lineEditSolverParam3->setEntryName("LM_tau"); ui->lineEditSolverParam3->onSave(); break; } case 2: // DogLeg { - sketchView->getSketchObject()->getSolvedSketch().setDL_tolf(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolf(val); ui->lineEditSolverParam3->setEntryName("DL_tolf"); ui->lineEditSolverParam3->onSave(); break; @@ -378,14 +381,14 @@ void TaskSketcherSolverAdvanced::on_lineEditRedundantSolverParam3_editingFinishe { case 1: // LM { - sketchView->getSketchObject()->getSolvedSketch().setLM_tauRedundant(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setLM_tauRedundant(val); ui->lineEditRedundantSolverParam3->setEntryName("Redundant_LM_tau"); ui->lineEditRedundantSolverParam3->onSave(); break; } case 2: // DogLeg { - sketchView->getSketchObject()->getSolvedSketch().setDL_tolfRedundant(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolfRedundant(val); ui->lineEditRedundantSolverParam3->setEntryName("Redundant_DL_tolf"); ui->lineEditRedundantSolverParam3->onSave(); break; @@ -396,32 +399,32 @@ void TaskSketcherSolverAdvanced::on_lineEditRedundantSolverParam3_editingFinishe void TaskSketcherSolverAdvanced::on_comboBoxDefaultSolver_currentIndexChanged(int index) { ui->comboBoxDefaultSolver->onSave(); - sketchView->getSketchObject()->getSolvedSketch().defaultSolver=(GCS::Algorithm) index; + const_cast(sketchView->getSketchObject()->getSolvedSketch()).defaultSolver=(GCS::Algorithm) index; updateDefaultMethodParameters(); } void TaskSketcherSolverAdvanced::on_comboBoxDogLegGaussStep_currentIndexChanged(int index) { ui->comboBoxDogLegGaussStep->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setDogLegGaussStep((GCS::DogLegGaussStep) index); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDogLegGaussStep((GCS::DogLegGaussStep) index); updateDefaultMethodParameters(); } void TaskSketcherSolverAdvanced::on_spinBoxMaxIter_valueChanged(int i) { ui->spinBoxMaxIter->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setMaxIter(i); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setMaxIter(i); } void TaskSketcherSolverAdvanced::on_checkBoxSketchSizeMultiplier_stateChanged(int state) { if(state==Qt::Checked) { ui->checkBoxSketchSizeMultiplier->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setSketchSizeMultiplier(true); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplier(true); } else if (state==Qt::Unchecked) { ui->checkBoxSketchSizeMultiplier->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setSketchSizeMultiplier(false); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplier(false); } } @@ -436,7 +439,7 @@ void TaskSketcherSolverAdvanced::on_lineEditQRPivotThreshold_editingFinished() ui->lineEditQRPivotThreshold->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setQRPivotThreshold(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setQRPivotThreshold(val); } void TaskSketcherSolverAdvanced::on_lineEditConvergence_editingFinished() @@ -450,7 +453,7 @@ void TaskSketcherSolverAdvanced::on_lineEditConvergence_editingFinished() ui->lineEditConvergence->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setConvergence(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setConvergence(val); } void TaskSketcherSolverAdvanced::on_lineEditRedundantConvergence_editingFinished() @@ -464,44 +467,44 @@ void TaskSketcherSolverAdvanced::on_lineEditRedundantConvergence_editingFinished ui->lineEditRedundantConvergence->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setConvergenceRedundant(val); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setConvergenceRedundant(val); } void TaskSketcherSolverAdvanced::on_comboBoxQRMethod_currentIndexChanged(int index) { - sketchView->getSketchObject()->getSolvedSketch().setQRAlgorithm((GCS::QRAlgorithm) index); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setQRAlgorithm((GCS::QRAlgorithm) index); ui->comboBoxQRMethod->onSave(); } void TaskSketcherSolverAdvanced::on_comboBoxRedundantDefaultSolver_currentIndexChanged(int index) { ui->comboBoxRedundantDefaultSolver->onSave(); - sketchView->getSketchObject()->getSolvedSketch().defaultSolverRedundant=(GCS::Algorithm) index; + const_cast(sketchView->getSketchObject()->getSolvedSketch()).defaultSolverRedundant=(GCS::Algorithm) index; updateRedundantMethodParameters(); } void TaskSketcherSolverAdvanced::on_spinBoxRedundantSolverMaxIterations_valueChanged(int i) { ui->spinBoxRedundantSolverMaxIterations->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setMaxIterRedundant(i); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setMaxIterRedundant(i); } void TaskSketcherSolverAdvanced::on_checkBoxRedundantSketchSizeMultiplier_stateChanged(int state) { if(state==Qt::Checked) { ui->checkBoxRedundantSketchSizeMultiplier->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setSketchSizeMultiplierRedundant(true); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplierRedundant(true); } else if (state==Qt::Unchecked) { ui->checkBoxRedundantSketchSizeMultiplier->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setSketchSizeMultiplierRedundant(true); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplierRedundant(true); } } void TaskSketcherSolverAdvanced::on_comboBoxDebugMode_currentIndexChanged(int index) { ui->comboBoxDebugMode->onSave(); - sketchView->getSketchObject()->getSolvedSketch().setDebugMode((GCS::DebugMode) index); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDebugMode((GCS::DebugMode) index); } void TaskSketcherSolverAdvanced::on_pushButtonSolve_clicked(bool checked/* = false*/) @@ -560,18 +563,18 @@ void TaskSketcherSolverAdvanced::on_pushButtonDefaults_clicked(bool checked/* = void TaskSketcherSolverAdvanced::updateSketchObject(void) { - sketchView->getSketchObject()->getSolvedSketch().setDebugMode((GCS::DebugMode) ui->comboBoxDebugMode->currentIndex()); - sketchView->getSketchObject()->getSolvedSketch().setSketchSizeMultiplierRedundant(ui->checkBoxRedundantSketchSizeMultiplier->isChecked()); - sketchView->getSketchObject()->getSolvedSketch().setMaxIterRedundant(ui->spinBoxRedundantSolverMaxIterations->value()); - sketchView->getSketchObject()->getSolvedSketch().defaultSolverRedundant=(GCS::Algorithm) ui->comboBoxRedundantDefaultSolver->currentIndex(); - sketchView->getSketchObject()->getSolvedSketch().setQRAlgorithm((GCS::QRAlgorithm) ui->comboBoxQRMethod->currentIndex()); - sketchView->getSketchObject()->getSolvedSketch().setQRPivotThreshold(ui->lineEditQRPivotThreshold->text().toDouble()); - sketchView->getSketchObject()->getSolvedSketch().setConvergenceRedundant(ui->lineEditRedundantConvergence->text().toDouble()); - sketchView->getSketchObject()->getSolvedSketch().setConvergence(ui->lineEditConvergence->text().toDouble()); - sketchView->getSketchObject()->getSolvedSketch().setSketchSizeMultiplier(ui->checkBoxSketchSizeMultiplier->isChecked()); - sketchView->getSketchObject()->getSolvedSketch().setMaxIter(ui->spinBoxMaxIter->value()); - sketchView->getSketchObject()->getSolvedSketch().defaultSolver=(GCS::Algorithm) ui->comboBoxDefaultSolver->currentIndex(); - sketchView->getSketchObject()->getSolvedSketch().setDogLegGaussStep((GCS::DogLegGaussStep) ui->comboBoxDogLegGaussStep->currentIndex()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDebugMode((GCS::DebugMode) ui->comboBoxDebugMode->currentIndex()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplierRedundant(ui->checkBoxRedundantSketchSizeMultiplier->isChecked()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setMaxIterRedundant(ui->spinBoxRedundantSolverMaxIterations->value()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).defaultSolverRedundant=(GCS::Algorithm) ui->comboBoxRedundantDefaultSolver->currentIndex(); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setQRAlgorithm((GCS::QRAlgorithm) ui->comboBoxQRMethod->currentIndex()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setQRPivotThreshold(ui->lineEditQRPivotThreshold->text().toDouble()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setConvergenceRedundant(ui->lineEditRedundantConvergence->text().toDouble()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setConvergence(ui->lineEditConvergence->text().toDouble()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplier(ui->checkBoxSketchSizeMultiplier->isChecked()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setMaxIter(ui->spinBoxMaxIter->value()); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).defaultSolver=(GCS::Algorithm) ui->comboBoxDefaultSolver->currentIndex(); + const_cast(sketchView->getSketchObject()->getSolvedSketch()).setDogLegGaussStep((GCS::DogLegGaussStep) ui->comboBoxDogLegGaussStep->currentIndex()); updateDefaultMethodParameters(); updateRedundantMethodParameters(); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 1abe2c1608..1b0c49080e 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -189,7 +189,7 @@ struct EditData { MarkerSize(7), blockedPreselection(false), FullyConstrained(false), - //ActSketch(0), // if you are wondering, it went to SketchObject, accessible via getSketchObject()->getSolvedSketch() + //ActSketch(0), // if you are wondering, it went to SketchObject, accessible via getSolvedSketch() and via SketchObject interface as appropriate EditRoot(0), PointsMaterials(0), CurvesMaterials(0), @@ -1139,7 +1139,7 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor } return false; case STATUS_SELECT_Point: - if (!getSketchObject()->getSolvedSketch().hasConflicts() && + if (!getSolvedSketch().hasConflicts() && edit->PreselectPoint != -1 && edit->DragPoint != edit->PreselectPoint) { Mode = STATUS_SKETCH_DragPoint; edit->DragPoint = edit->PreselectPoint; @@ -1147,7 +1147,7 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor Sketcher::PointPos PosId; getSketchObject()->getGeoVertexIndex(edit->DragPoint, GeoId, PosId); if (GeoId != Sketcher::Constraint::GeoUndef && PosId != Sketcher::none) { - getSketchObject()->getSolvedSketch().initMove(GeoId, PosId, false); + getSketchObject()->initTemporaryMove(GeoId, PosId, false); relative = false; xInit = 0; yInit = 0; @@ -1161,7 +1161,7 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor edit->PreselectConstraintSet.clear(); return true; case STATUS_SELECT_Edge: - if (!getSketchObject()->getSolvedSketch().hasConflicts() && + if (!getSolvedSketch().hasConflicts() && edit->PreselectCurve != -1 && edit->DragCurve != edit->PreselectCurve) { Mode = STATUS_SKETCH_DragCurve; edit->DragCurve = edit->PreselectCurve; @@ -1183,7 +1183,7 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor // The B-Spline is constrained to be non-rational (equal weights), moving produces a bad effect // because OCCT will normalize the values of the weights. - auto grp = getSketchObject()->getSolvedSketch().getDependencyGroup(edit->DragCurve, Sketcher::none); + auto grp = getSolvedSketch().getDependencyGroup(edit->DragCurve, Sketcher::none); int bsplinegeoid = -1; @@ -1231,7 +1231,7 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor } - getSketchObject()->getSolvedSketch().initMove(edit->DragCurve, Sketcher::none, false); + getSketchObject()->initTemporaryMove(edit->DragCurve, Sketcher::none, false); if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId() || geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { @@ -1273,12 +1273,12 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor getSketchObject()->getGeoVertexIndex(edit->DragPoint, GeoId, PosId); Base::Vector3d vec(x,y,0); if (GeoId != Sketcher::Constraint::GeoUndef && PosId != Sketcher::none) { - if (getSketchObject()->getSolvedSketch().movePoint(GeoId, PosId, vec, false) == 0) { + if (getSketchObject()->moveTemporaryPoint(GeoId, PosId, vec, false) == 0) { setPositionText(Base::Vector2d(x,y)); draw(true,false); - signalSolved(QString::fromLatin1("Solved in %1 sec").arg(getSketchObject()->getSolvedSketch().getSolveTime())); + signalSolved(QString::fromLatin1("Solved in %1 sec").arg(getSolvedSketch().getSolveTime())); } else { - signalSolved(QString::fromLatin1("Unsolved (%1 sec)").arg(getSketchObject()->getSolvedSketch().getSolveTime())); + signalSolved(QString::fromLatin1("Unsolved (%1 sec)").arg(getSolvedSketch().getSolveTime())); //Base::Console().Log("Error solving:%d\n",ret); } } @@ -1314,12 +1314,12 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor vec = center + dir / scalefactor; } - if (getSketchObject()->getSolvedSketch().movePoint(edit->DragCurve, Sketcher::none, vec, relative) == 0) { + if (getSketchObject()->moveTemporaryPoint(edit->DragCurve, Sketcher::none, vec, relative) == 0) { setPositionText(Base::Vector2d(x,y)); draw(true,false); - signalSolved(QString::fromLatin1("Solved in %1 sec").arg(getSketchObject()->getSolvedSketch().getSolveTime())); + signalSolved(QString::fromLatin1("Solved in %1 sec").arg(getSolvedSketch().getSolveTime())); } else { - signalSolved(QString::fromLatin1("Unsolved (%1 sec)").arg(getSketchObject()->getSolvedSketch().getSolveTime())); + signalSolved(QString::fromLatin1("Unsolved (%1 sec)").arg(getSolvedSketch().getSolveTime())); } } return true; @@ -1380,7 +1380,7 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d &toPo #endif // with memory allocation - const std::vector geomlist = getSketchObject()->getSolvedSketch().extractGeometry(true, true); + const std::vector geomlist = getSolvedSketch().extractGeometry(true, true); #ifdef _DEBUG assert(int(geomlist.size()) == extGeoCount + intGeoCount); @@ -1393,10 +1393,10 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d &toPo Base::Vector3d p1(0.,0.,0.), p2(0.,0.,0.); if (Constr->SecondPos != Sketcher::none) { // point to point distance - p1 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); - p2 = getSketchObject()->getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); + p1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + p2 = getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); } else if (Constr->Second != Constraint::GeoUndef) { // point to line distance - p1 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + p1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); const Part::Geometry *geo = GeoById(geomlist, Constr->Second); if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment *lineSeg = static_cast(geo); @@ -1408,7 +1408,7 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d &toPo } else return; } else if (Constr->FirstPos != Sketcher::none) { - p2 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + p2 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); } else if (Constr->First != Constraint::GeoUndef) { const Part::Geometry *geo = GeoById(geomlist, Constr->First); if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { @@ -1534,11 +1534,11 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d &toPo factor = factor * Base::sgn((dir1+dir2) * vec); } } else {//angle-via-point - Base::Vector3d p = getSketchObject()->getSolvedSketch().getPoint(Constr->Third, Constr->ThirdPos); + Base::Vector3d p = getSolvedSketch().getPoint(Constr->Third, Constr->ThirdPos); p0 = Base::Vector3d(p.x, p.y, 0); - dir1 = getSketchObject()->getSolvedSketch().calculateNormalAtPoint(Constr->First, p.x, p.y); + dir1 = getSolvedSketch().calculateNormalAtPoint(Constr->First, p.x, p.y); dir1.RotateZ(-M_PI/2);//convert to vector of tangency by rotating - dir2 = getSketchObject()->getSolvedSketch().calculateNormalAtPoint(Constr->Second, p.x, p.y); + dir2 = getSolvedSketch().calculateNormalAtPoint(Constr->Second, p.x, p.y); dir2.RotateZ(-M_PI/2); Base::Vector3d vec = Base::Vector3d(toPos.x, toPos.y, 0) - p0; @@ -3032,7 +3032,7 @@ void ViewProviderSketch::updateColor(void) } else if (type == Sketcher::Coincident) { auto selectpoint = [this, pcolor, PtNum](int geoid, Sketcher::PointPos pos){ if(geoid >= 0) { - int index = getSketchObject()->getSolvedSketch().getPointId(geoid, pos) + 1; + int index = getSolvedSketch().getPointId(geoid, pos) + 1; if (index >= 0 && index < PtNum) pcolor[index] = SelectColor; } @@ -3060,7 +3060,7 @@ void ViewProviderSketch::updateColor(void) case EllipseFocus1: case EllipseFocus2: { - int index = getSketchObject()->getSolvedSketch().getPointId(constraint->First, constraint->FirstPos) + 1; + int index = getSolvedSketch().getPointId(constraint->First, constraint->FirstPos) + 1; if (index >= 0 && index < PtNum) pcolor[index] = SelectColor; } break; @@ -3760,7 +3760,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer const std::vector *geomlist; std::vector tempGeo; if (temp) - tempGeo = getSketchObject()->getSolvedSketch().extractGeometry(true, true); // with memory allocation + tempGeo = getSolvedSketch().extractGeometry(true, true); // with memory allocation else tempGeo = getSketchObject()->getCompleteGeometry(); // without memory allocation geomlist = &tempGeo; @@ -3880,7 +3880,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer auto vpext = std::make_unique(); vpext->setRepresentationFactor(scalefactor); - getSketchObject()->getSolvedSketch().updateExtension(GeoId, std::move(vpext)); + getSketchObject()->updateSolverExtension(GeoId, std::move(vpext)); } if(!circle->hasExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId())) @@ -4881,12 +4881,12 @@ Restart: Base::Vector3d midpos2, dir2, norm2; if (temp) - midpos1 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + midpos1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); else midpos1 = getSketchObject()->getPoint(Constr->First, Constr->FirstPos); if (temp) - midpos2 = getSketchObject()->getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); + midpos2 = getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); else midpos2 = getSketchObject()->getPoint(Constr->Second, Constr->SecondPos); @@ -4938,11 +4938,11 @@ Restart: assert(0);//no point found! } while (false); if (temp) - midpos1 = getSketchObject()->getSolvedSketch().getPoint(ptGeoId, ptPosId); + midpos1 = getSolvedSketch().getPoint(ptGeoId, ptPosId); else midpos1 = getSketchObject()->getPoint(ptGeoId, ptPosId); - norm1 = getSketchObject()->getSolvedSketch().calculateNormalAtPoint(Constr->Second, midpos1.x, midpos1.y); + norm1 = getSolvedSketch().calculateNormalAtPoint(Constr->Second, midpos1.x, midpos1.y); norm1.Normalize(); dir1 = norm1; dir1.RotateZ(-M_PI/2.0); @@ -5206,15 +5206,15 @@ Restart: Base::Vector3d pnt1(0.,0.,0.), pnt2(0.,0.,0.); if (Constr->SecondPos != Sketcher::none) { // point to point distance if (temp) { - pnt1 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); - pnt2 = getSketchObject()->getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); + pnt1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + pnt2 = getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); } else { pnt1 = getSketchObject()->getPoint(Constr->First, Constr->FirstPos); pnt2 = getSketchObject()->getPoint(Constr->Second, Constr->SecondPos); } } else if (Constr->Second != Constraint::GeoUndef) { // point to line distance if (temp) { - pnt1 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + pnt1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); } else { pnt1 = getSketchObject()->getPoint(Constr->First, Constr->FirstPos); } @@ -5230,7 +5230,7 @@ Restart: break; } else if (Constr->FirstPos != Sketcher::none) { if (temp) { - pnt2 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + pnt2 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); } else { pnt2 = getSketchObject()->getPoint(Constr->First, Constr->FirstPos); } @@ -5301,9 +5301,9 @@ Restart: if (ptPosId != Sketcher::none) break; assert(0);//no point found! } while (false); - pos = getSketchObject()->getSolvedSketch().getPoint(ptGeoId, ptPosId); + pos = getSolvedSketch().getPoint(ptGeoId, ptPosId); - Base::Vector3d norm = getSketchObject()->getSolvedSketch().calculateNormalAtPoint(Constr->Second, pos.x, pos.y); + Base::Vector3d norm = getSolvedSketch().calculateNormalAtPoint(Constr->Second, pos.x, pos.y); norm.Normalize(); Base::Vector3d dir = norm; dir.RotateZ(-M_PI/2.0); @@ -5429,8 +5429,8 @@ Restart: assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount); assert(Constr->Second >= -extGeoCount && Constr->Second < intGeoCount); - Base::Vector3d pnt1 = getSketchObject()->getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); - Base::Vector3d pnt2 = getSketchObject()->getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); + Base::Vector3d pnt1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + Base::Vector3d pnt2 = getSolvedSketch().getPoint(Constr->Second, Constr->SecondPos); SbVec3f p1(pnt1.x,pnt1.y,zConstr); SbVec3f p2(pnt2.x,pnt2.y,zConstr); @@ -5513,11 +5513,11 @@ Restart: startangle = atan2(dir1.y,dir1.x); } else {//angle-via-point - Base::Vector3d p = getSketchObject()->getSolvedSketch().getPoint(Constr->Third, Constr->ThirdPos); + Base::Vector3d p = getSolvedSketch().getPoint(Constr->Third, Constr->ThirdPos); p0 = SbVec3f(p.x, p.y, 0); - dir1 = getSketchObject()->getSolvedSketch().calculateNormalAtPoint(Constr->First, p.x, p.y); + dir1 = getSolvedSketch().calculateNormalAtPoint(Constr->First, p.x, p.y); dir1.RotateZ(-M_PI/2);//convert to vector of tangency by rotating - dir2 = getSketchObject()->getSolvedSketch().calculateNormalAtPoint(Constr->Second, p.x, p.y); + dir2 = getSolvedSketch().calculateNormalAtPoint(Constr->Second, p.x, p.y); dir2.RotateZ(-M_PI/2); startangle = atan2(dir1.y,dir1.x); @@ -6001,7 +6001,7 @@ void ViewProviderSketch::updateData(const App::Property *prop) UpdateSolverInformation(); // just update the solver window with the last SketchObject solving information if(getSketchObject()->getExternalGeometryCount()+getSketchObject()->getHighestCurveIndex() + 1 == - getSketchObject()->getSolvedSketch().getGeometrySize()) { + getSolvedSketch().getGeometrySize()) { Gui::MDIView *mdi = Gui::Application::Instance->editDocument()->getActiveView(); if (mdi->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) draw(false,true); @@ -6255,8 +6255,7 @@ bool ViewProviderSketch::setEdit(int ModNum) // Enable solver initial solution update while dragging. ParameterGrp::handle hGrp2 = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); - getSketchObject()->getSolvedSketch().setRecalculateInitialSolutionWhileMovingPoint(hGrp2->GetBool("RecalculateInitialSolutionWhileDragging",true)); - + getSketchObject()->setRecalculateInitialSolutionWhileMovingPoint(hGrp2->GetBool("RecalculateInitialSolutionWhileDragging",true)); // intercept del key press from main app listener = new ShortcutListener(this); @@ -6340,7 +6339,7 @@ void ViewProviderSketch::UpdateSolverInformation() if (getSketchObject()->getLastSolverStatus() == 0) { if (dofs == 0) { // color the sketch as fully constrained if it has geometry (other than the axes) - if(getSketchObject()->getSolvedSketch().getGeometrySize()>2) + if(getSolvedSketch().getGeometrySize()>2) edit->FullyConstrained = true; if (!hasRedundancies) { @@ -6826,6 +6825,11 @@ Sketcher::SketchObject *ViewProviderSketch::getSketchObject(void) const return dynamic_cast(pcObject); } +const Sketcher::Sketch &ViewProviderSketch::getSolvedSketch(void) const +{ + return const_cast(getSketchObject())->getSolvedSketch(); +} + void ViewProviderSketch::deleteSelected() { std::vector selection; diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index ab64445c54..6d42806956 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -194,6 +194,18 @@ public: /// get the pointer to the sketch document object Sketcher::SketchObject *getSketchObject(void) const; + /** returns a const reference to the last solved sketch object. It guarantees that + * the solver object does not lose synchronisation with the SketchObject properties. + * + * NOTE: Operations requiring write access to the solver must be done via SketchObject + * interface. See for example functions: + * -> inline void setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint) + * -> inline int initTemporaryMove(int geoId, PointPos pos, bool fine=true) + * -> inline int moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative=false) + * -> inline void updateSolverExtension(int geoId, std::unique_ptr && ext) + */ + const Sketcher::Sketch &getSolvedSketch(void) const; + /// snap points x,y (mouse coordinates) onto grid if enabled void snapToGrid(double &x, double &y);