diff --git a/src/Mod/Sketcher/Gui/CMakeLists.txt b/src/Mod/Sketcher/Gui/CMakeLists.txt index 9e55568413..7aed284e1e 100644 --- a/src/Mod/Sketcher/Gui/CMakeLists.txt +++ b/src/Mod/Sketcher/Gui/CMakeLists.txt @@ -62,6 +62,8 @@ SET(SketcherGui_SRCS AppSketcherGui.cpp GeometryCreationMode.h Command.cpp + Utils.h + Utils.cpp CommandCreateGeo.cpp CommandConstraints.h CommandConstraints.cpp diff --git a/src/Mod/Sketcher/Gui/CommandAlterGeometry.cpp b/src/Mod/Sketcher/Gui/CommandAlterGeometry.cpp index d0b41276a4..ca395b4ab8 100644 --- a/src/Mod/Sketcher/Gui/CommandAlterGeometry.cpp +++ b/src/Mod/Sketcher/Gui/CommandAlterGeometry.cpp @@ -40,7 +40,7 @@ #include "ViewProviderSketch.h" #include "GeometryCreationMode.h" -#include "CommandConstraints.h" +#include "Utils.h" using namespace std; using namespace SketcherGui; diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index ccd25e94a6..d7b45c969a 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -48,6 +48,8 @@ #include #include +#include "Utils.h" + #include "ViewProviderSketch.h" #include "DrawSketchHandler.h" #include "ui_InsertDatum.h" @@ -163,159 +165,6 @@ void showNoConstraintBetweenFixedGeometry() "as B-spline knot points.")); } -bool SketcherGui::checkBothExternal(int GeoId1, int GeoId2) -{ - if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) - return false; - else - return (GeoId1 < 0 && GeoId2 < 0); -} - -bool SketcherGui::checkBothExternalOrBSplinePoints(const Sketcher::SketchObject* Obj,int GeoId1, int GeoId2) -{ - if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) - return false; - else - return (GeoId1 < 0 && GeoId2 < 0) || (isBsplineKnot(Obj,GeoId1) && isBsplineKnot(Obj,GeoId2)) || - (GeoId1 < 0 && isBsplineKnot(Obj,GeoId2)) || (GeoId2 < 0 && isBsplineKnot(Obj,GeoId1)); -} - -bool SketcherGui::isPointOrSegmentFixed(const Sketcher::SketchObject* Obj, int GeoId) -{ - const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); - - if (GeoId == Constraint::GeoUndef) - return false; - else - return checkConstraint(vals, Sketcher::Block, GeoId, Sketcher::none) || GeoId <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId); -} - -bool SketcherGui::areBothPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2) -{ - const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); - - if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) - return false; - else - return ((checkConstraint(vals, Sketcher::Block, GeoId1, Sketcher::none) || GeoId1 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId1)) && - (checkConstraint(vals, Sketcher::Block, GeoId2, Sketcher::none) || GeoId2 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId2))); -} - -bool SketcherGui::areAllPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, int GeoId3) -{ - const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); - - if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef || GeoId3 == Constraint::GeoUndef) - return false; - else - return ((checkConstraint(vals, Sketcher::Block, GeoId1, Sketcher::none) || GeoId1 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId1)) && - (checkConstraint(vals, Sketcher::Block, GeoId2, Sketcher::none) || GeoId2 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId2)) && - (checkConstraint(vals, Sketcher::Block, GeoId3, Sketcher::none) || GeoId3 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId3))); -} - -void SketcherGui::getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, - int &GeoId, PointPos &PosId) -{ - GeoId = Constraint::GeoUndef; - PosId = Sketcher::none; - - if (name.size() > 4 && name.substr(0,4) == "Edge") { - GeoId = std::atoi(name.substr(4,4000).c_str()) - 1; - } - else if (name.size() == 9 && name.substr(0,9) == "RootPoint") { - GeoId = Sketcher::GeoEnum::RtPnt; - PosId = Sketcher::start; - } - else if (name.size() == 6 && name.substr(0,6) == "H_Axis") - GeoId = Sketcher::GeoEnum::HAxis; - else if (name.size() == 6 && name.substr(0,6) == "V_Axis") - GeoId = Sketcher::GeoEnum::VAxis; - else if (name.size() > 12 && name.substr(0,12) == "ExternalEdge") - GeoId = Sketcher::GeoEnum::RefExt + 1 - std::atoi(name.substr(12,4000).c_str()); - else if (name.size() > 6 && name.substr(0,6) == "Vertex") { - int VtId = std::atoi(name.substr(6,4000).c_str()) - 1; - Obj->getGeoVertexIndex(VtId,GeoId,PosId); - } -} - -bool inline SketcherGui::isVertex(int GeoId, PointPos PosId) -{ - return (GeoId != Constraint::GeoUndef && PosId != Sketcher::none); -} - -bool inline SketcherGui::isEdge(int GeoId, PointPos PosId) -{ - return (GeoId != Constraint::GeoUndef && PosId == Sketcher::none); -} - -bool SketcherGui::isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, PointPos PosId) -{ - if (PosId == Sketcher::start && (GeoId == Sketcher::GeoEnum::HAxis || GeoId == Sketcher::GeoEnum::VAxis)) - return true; - const Part::Geometry *geo = Obj->getGeometry(GeoId); - if (geo->getTypeId() == Part::GeomPoint::getClassTypeId()) - return true; - else if (PosId == Sketcher::mid) - return true; - else - return false; -} - -bool SketcherGui::isBsplineKnot(const Sketcher::SketchObject* Obj, int GeoId) -{ - auto gf = Obj->getGeometryFacade(GeoId); - return (gf && gf->getInternalType() == Sketcher::InternalType::BSplineKnotPoint); -} - -bool SketcherGui::IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj) -{ - //This func is a "smartness" behind three-element tangent-, perp.- and angle-via-point. - //We want to find out, if the point supplied by user is already on - // both of the curves. If not, necessary point-on-object constraints - // are to be added automatically. - //Simple geometric test seems to be the best, because a point can be - // constrained to a curve in a number of ways (e.g. it is an endpoint of an - // arc, or is coincident to endpoint of an arc, or it is an endpoint of an - // ellipse's majopr diameter line). Testing all those possibilities is way - // too much trouble, IMO(DeepSOIC). - Base::Vector3d p = Obj->getPoint(GeoIdPoint, PosIdPoint); - return Obj->isPointOnCurve(GeoIdCurve, p.x, p.y); -} - -bool SketcherGui::isBsplinePole(const Part::Geometry * geo) -{ - auto gf = GeometryFacade::getFacade(geo); - - if(gf) - return gf->getInternalType() == InternalType::BSplineControlPoint; - - THROWM(Base::ValueError, "Null geometry in isBsplinePole - please report") -} - -bool SketcherGui::isBsplinePole(const Sketcher::SketchObject* Obj, int GeoId) -{ - - auto geom = Obj->getGeometry(GeoId); - - return isBsplinePole(geom); -} - -bool SketcherGui::ReleaseHandler(Gui::Document* doc) { - if (doc) { - if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) { - SketcherGui::ViewProviderSketch* vp = static_cast (doc->getInEdit()); - - if (static_cast(doc->getInEdit()) - ->getSketchMode() == ViewProviderSketch::STATUS_SKETCH_UseHandler) { - - vp->purgeHandler(); - return true; - } - } - } - return false; -} - /// Makes a simple tangency constraint using extra point + tangent via point /// ellipse => an ellipse /// geom2 => any of an ellipse, an arc of ellipse, a circle, or an arc (of circle) @@ -603,70 +452,6 @@ void SketcherGui::makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* tryAutoRecompute(Obj); } -std::string SketcherGui::getStrippedPythonExceptionString(const Base::Exception& e) -{ - std::string msg = e.what(); - - if( msg.length() > 26 && msg.substr(0,26) == "FreeCAD exception thrown (") { - return msg.substr(26, msg.length()-27); - } - else - return msg; -} - -bool SketcherGui::tryAutoRecompute(Sketcher::SketchObject* obj, bool &autoremoveredundants) -{ - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); - bool autoRecompute = hGrp->GetBool("AutoRecompute",false); - bool autoRemoveRedundants = hGrp->GetBool("AutoRemoveRedundants",false); - - // We need to make sure the solver has right redundancy information before trying to remove the redundants. - // for example if a non-driving constraint has been added. - if(autoRemoveRedundants && autoRecompute) - obj->solve(); - - if(autoRemoveRedundants) - obj->autoRemoveRedundants(); - - if (autoRecompute) - Gui::Command::updateActive(); - - autoremoveredundants = autoRemoveRedundants; - - return autoRecompute; -} - -bool SketcherGui::tryAutoRecompute(Sketcher::SketchObject* obj) -{ - bool autoremoveredundants; - - return tryAutoRecompute(obj,autoremoveredundants); -} - -void SketcherGui::tryAutoRecomputeIfNotSolve(Sketcher::SketchObject* obj) -{ - bool autoremoveredundants; - - if(!tryAutoRecompute(obj,autoremoveredundants)) { - obj->solve(); - - if(autoremoveredundants) { - obj->autoRemoveRedundants(); - } - } -} - -bool SketcherGui::checkConstraint(const std::vector< Sketcher::Constraint * > &vals, ConstraintType type, int geoid, PointPos pos) -{ - for (std::vector< Sketcher::Constraint * >::const_iterator itc= vals.begin(); itc != vals.end(); ++itc) { - if ((*itc)->Type == type && (*itc)->First == geoid && (*itc)->FirstPos == pos){ - return true; - } - } - - return false; -} - void SketcherGui::doEndpointTangency(Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, PointPos PosId1, PointPos PosId2) { diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.h b/src/Mod/Sketcher/Gui/CommandConstraints.h index 14f1aa8cd3..554e8bf40f 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.h +++ b/src/Mod/Sketcher/Gui/CommandConstraints.h @@ -29,35 +29,8 @@ namespace SketcherGui { -bool checkBothExternal(int GeoId1, int GeoId2); -bool checkBothExternalOrBSplinePoints(const Sketcher::SketchObject* Obj,int GeoId1, int GeoId2); -bool isPointOrSegmentFixed(const Sketcher::SketchObject* Obj, int GeoId); - -bool areBothPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2); - -bool areAllPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, int GeoId3); - -void getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, int &GeoId, Sketcher::PointPos &PosId); - -bool inline isVertex(int GeoId, Sketcher::PointPos PosId); - -bool inline isEdge(int GeoId, Sketcher::PointPos PosId); - -bool isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, Sketcher::PointPos PosId); - -bool isBsplineKnot(const Sketcher::SketchObject* Obj, int GeoId); - -bool IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj); - -bool isBsplinePole(const Part::Geometry * geo); - -bool isBsplinePole(const Sketcher::SketchObject* Obj, int GeoId); - -/// Release any currently-active handler for the document. -/// Returns true if a handler was released, and false if not -bool ReleaseHandler(Gui::Document* doc); // These functions are declared here to promote code reuse from other modules @@ -120,22 +93,6 @@ void makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* Obj, int geoId2 ); -std::string getStrippedPythonExceptionString(const Base::Exception&); - -/// This function tries to auto-recompute the active document if the option -/// is set in the user parameter. If the option is not set nothing will be done -/// @return true if a recompute was undertaken, false if not. -bool tryAutoRecompute(Sketcher::SketchObject* obj); -/// Same as the other overload, but also returns whether redundants shall be removed or not -bool tryAutoRecompute(Sketcher::SketchObject* obj, bool &autoremoveredundants); - -/// This function tries to auto-recompute as tryAutoRecompute. If tryAutoRecompute -/// is not enabled, then it solves the SketchObject. -void tryAutoRecomputeIfNotSolve(Sketcher::SketchObject* obj); - -/// Checks whether there is a constraint of the given type with a First element geoid and a FirstPos PosId -bool checkConstraint(const std::vector< Sketcher::Constraint * > &vals, Sketcher::ConstraintType type, int geoid, Sketcher::PointPos pos); - /// Does an endpoint-to-endpoint tangency void doEndpointTangency(Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, Sketcher::PointPos PosId1, Sketcher::PointPos PosId2); @@ -146,5 +103,5 @@ void doEndpointToEdgeTangency( Sketcher::SketchObject* Obj, int GeoId1, Sketcher void notifyConstraintSubstitutions(const QString & message); } -#endif // SKETCHERGUI_DrawSketchHandler_H +#endif // SKETCHERGUI_CommandConstraints_H diff --git a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp index ac64ff6663..550c61917b 100644 --- a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp +++ b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp @@ -55,7 +55,7 @@ #include "ViewProviderSketch.h" #include "DrawSketchHandler.h" -#include "CommandConstraints.h" +#include "Utils.h" #include #include diff --git a/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp b/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp index 2e3b1a148d..47eea14e40 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp @@ -49,7 +49,7 @@ #include #include -#include "CommandConstraints.h" +#include "Utils.h" using namespace std; using namespace SketcherGui; diff --git a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp index 72d9d1f808..11d1de70c5 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp @@ -54,7 +54,7 @@ #include "ViewProviderSketch.h" #include "SketchRectangularArrayDialog.h" -#include "CommandConstraints.h" +#include "Utils.h" using namespace std; using namespace SketcherGui; diff --git a/src/Mod/Sketcher/Gui/CommandSketcherVirtualSpace.cpp b/src/Mod/Sketcher/Gui/CommandSketcherVirtualSpace.cpp index 231dd6be88..7f01efba9b 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherVirtualSpace.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherVirtualSpace.cpp @@ -49,7 +49,7 @@ #include #include -#include "CommandConstraints.h" +#include "Utils.h" using namespace std; using namespace SketcherGui; diff --git a/src/Mod/Sketcher/Gui/EditDatumDialog.cpp b/src/Mod/Sketcher/Gui/EditDatumDialog.cpp index 2f5bf9b583..a00ac02fe6 100644 --- a/src/Mod/Sketcher/Gui/EditDatumDialog.cpp +++ b/src/Mod/Sketcher/Gui/EditDatumDialog.cpp @@ -43,7 +43,7 @@ #include "ViewProviderSketch.h" #include "ui_InsertDatum.h" #include "EditDatumDialog.h" -#include "CommandConstraints.h" +#include "Utils.h" using namespace SketcherGui; diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp index c67fa66a62..1719e1b146 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherConstraints.cpp @@ -57,6 +57,8 @@ #include #include +#include "Utils.h" + #include "ConstraintMultiFilterDialog.h" #include "ConstraintSettingsDialog.h" diff --git a/src/Mod/Sketcher/Gui/Utils.cpp b/src/Mod/Sketcher/Gui/Utils.cpp new file mode 100644 index 0000000000..53f07e8d87 --- /dev/null +++ b/src/Mod/Sketcher/Gui/Utils.cpp @@ -0,0 +1,266 @@ +/*************************************************************************** + * Copyright (c) 2021 Abdullah Tahiri * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +# include +# include +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ViewProviderSketch.h" +#include "DrawSketchHandler.h" +#include "ui_InsertDatum.h" +#include "EditDatumDialog.h" +#include "Utils.h" + +using namespace std; +using namespace SketcherGui; +using namespace Sketcher; + +bool SketcherGui::tryAutoRecompute(Sketcher::SketchObject* obj, bool &autoremoveredundants) +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + bool autoUtils = hGrp->GetBool("AutoUtils",false); + bool autoRemoveRedundants = hGrp->GetBool("AutoRemoveRedundants",false); + + // We need to make sure the solver has right redundancy information before trying to remove the redundants. + // for example if a non-driving constraint has been added. + if(autoRemoveRedundants && autoUtils) + obj->solve(); + + if(autoRemoveRedundants) + obj->autoRemoveRedundants(); + + if (autoUtils) + Gui::Command::updateActive(); + + autoremoveredundants = autoRemoveRedundants; + + return autoUtils; +} + +bool SketcherGui::tryAutoRecompute(Sketcher::SketchObject* obj) +{ + bool autoremoveredundants; + + return tryAutoRecompute(obj,autoremoveredundants); +} + +void SketcherGui::tryAutoRecomputeIfNotSolve(Sketcher::SketchObject* obj) +{ + bool autoremoveredundants; + + if(!tryAutoRecompute(obj,autoremoveredundants)) { + obj->solve(); + + if(autoremoveredundants) { + obj->autoRemoveRedundants(); + } + } +} + +std::string SketcherGui::getStrippedPythonExceptionString(const Base::Exception& e) +{ + std::string msg = e.what(); + + if( msg.length() > 26 && msg.substr(0,26) == "FreeCAD exception thrown (") { + return msg.substr(26, msg.length()-27); + } + else + return msg; +} + +bool SketcherGui::ReleaseHandler(Gui::Document* doc) { + if (doc) { + if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) { + SketcherGui::ViewProviderSketch* vp = static_cast (doc->getInEdit()); + + if (static_cast(doc->getInEdit()) + ->getSketchMode() == ViewProviderSketch::STATUS_SKETCH_UseHandler) { + + vp->purgeHandler(); + return true; + } + } + } + return false; +} + +void SketcherGui::getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, + int &GeoId, PointPos &PosId) +{ + GeoId = Constraint::GeoUndef; + PosId = Sketcher::none; + + if (name.size() > 4 && name.substr(0,4) == "Edge") { + GeoId = std::atoi(name.substr(4,4000).c_str()) - 1; + } + else if (name.size() == 9 && name.substr(0,9) == "RootPoint") { + GeoId = Sketcher::GeoEnum::RtPnt; + PosId = Sketcher::start; + } + else if (name.size() == 6 && name.substr(0,6) == "H_Axis") + GeoId = Sketcher::GeoEnum::HAxis; + else if (name.size() == 6 && name.substr(0,6) == "V_Axis") + GeoId = Sketcher::GeoEnum::VAxis; + else if (name.size() > 12 && name.substr(0,12) == "ExternalEdge") + GeoId = Sketcher::GeoEnum::RefExt + 1 - std::atoi(name.substr(12,4000).c_str()); + else if (name.size() > 6 && name.substr(0,6) == "Vertex") { + int VtId = std::atoi(name.substr(6,4000).c_str()) - 1; + Obj->getGeoVertexIndex(VtId,GeoId,PosId); + } +} + +bool SketcherGui::checkBothExternal(int GeoId1, int GeoId2) +{ + if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) + return false; + else + return (GeoId1 < 0 && GeoId2 < 0); +} + +bool SketcherGui::checkBothExternalOrBSplinePoints(const Sketcher::SketchObject* Obj,int GeoId1, int GeoId2) +{ + if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) + return false; + else + return (GeoId1 < 0 && GeoId2 < 0) || (isBsplineKnot(Obj,GeoId1) && isBsplineKnot(Obj,GeoId2)) || + (GeoId1 < 0 && isBsplineKnot(Obj,GeoId2)) || (GeoId2 < 0 && isBsplineKnot(Obj,GeoId1)); +} + +bool SketcherGui::isPointOrSegmentFixed(const Sketcher::SketchObject* Obj, int GeoId) +{ + const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); + + if (GeoId == Constraint::GeoUndef) + return false; + else + return checkConstraint(vals, Sketcher::Block, GeoId, Sketcher::none) || GeoId <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId); +} + +bool SketcherGui::areBothPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2) +{ + const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); + + if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) + return false; + else + return ((checkConstraint(vals, Sketcher::Block, GeoId1, Sketcher::none) || GeoId1 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId1)) && + (checkConstraint(vals, Sketcher::Block, GeoId2, Sketcher::none) || GeoId2 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId2))); +} + +bool SketcherGui::areAllPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, int GeoId3) +{ + const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); + + if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef || GeoId3 == Constraint::GeoUndef) + return false; + else + return ((checkConstraint(vals, Sketcher::Block, GeoId1, Sketcher::none) || GeoId1 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId1)) && + (checkConstraint(vals, Sketcher::Block, GeoId2, Sketcher::none) || GeoId2 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId2)) && + (checkConstraint(vals, Sketcher::Block, GeoId3, Sketcher::none) || GeoId3 <= Sketcher::GeoEnum::RtPnt || isBsplineKnot(Obj,GeoId3))); +} + +bool SketcherGui::isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, PointPos PosId) +{ + if (PosId == Sketcher::start && (GeoId == Sketcher::GeoEnum::HAxis || GeoId == Sketcher::GeoEnum::VAxis)) + return true; + const Part::Geometry *geo = Obj->getGeometry(GeoId); + if (geo->getTypeId() == Part::GeomPoint::getClassTypeId()) + return true; + else if (PosId == Sketcher::mid) + return true; + else + return false; +} + +bool SketcherGui::isBsplineKnot(const Sketcher::SketchObject* Obj, int GeoId) +{ + auto gf = Obj->getGeometryFacade(GeoId); + return (gf && gf->getInternalType() == Sketcher::InternalType::BSplineKnotPoint); +} + +bool SketcherGui::IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj) +{ + //This func is a "smartness" behind three-element tangent-, perp.- and angle-via-point. + //We want to find out, if the point supplied by user is already on + // both of the curves. If not, necessary point-on-object constraints + // are to be added automatically. + //Simple geometric test seems to be the best, because a point can be + // constrained to a curve in a number of ways (e.g. it is an endpoint of an + // arc, or is coincident to endpoint of an arc, or it is an endpoint of an + // ellipse's majopr diameter line). Testing all those possibilities is way + // too much trouble, IMO(DeepSOIC). + Base::Vector3d p = Obj->getPoint(GeoIdPoint, PosIdPoint); + return Obj->isPointOnCurve(GeoIdCurve, p.x, p.y); +} + +bool SketcherGui::isBsplinePole(const Part::Geometry * geo) +{ + auto gf = GeometryFacade::getFacade(geo); + + if(gf) + return gf->getInternalType() == InternalType::BSplineControlPoint; + + THROWM(Base::ValueError, "Null geometry in isBsplinePole - please report") +} + +bool SketcherGui::isBsplinePole(const Sketcher::SketchObject* Obj, int GeoId) +{ + + auto geom = Obj->getGeometry(GeoId); + + return isBsplinePole(geom); +} + +bool SketcherGui::checkConstraint(const std::vector< Sketcher::Constraint * > &vals, ConstraintType type, int geoid, PointPos pos) +{ + for (std::vector< Sketcher::Constraint * >::const_iterator itc= vals.begin(); itc != vals.end(); ++itc) { + if ((*itc)->Type == type && (*itc)->First == geoid && (*itc)->FirstPos == pos){ + return true; + } + } + + return false; +} diff --git a/src/Mod/Sketcher/Gui/Utils.h b/src/Mod/Sketcher/Gui/Utils.h new file mode 100644 index 0000000000..e3a6b859d9 --- /dev/null +++ b/src/Mod/Sketcher/Gui/Utils.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (c) 2021 Abdullah Tahiri * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef SKETCHERGUI_Recompute_H +#define SKETCHERGUI_Recompute_H + +namespace Sketcher { + enum PointPos : int; + class SketchObject; +} + +namespace SketcherGui { + +/// This function tries to auto-recompute the active document if the option +/// is set in the user parameter. If the option is not set nothing will be done +/// @return true if a recompute was undertaken, false if not. +bool tryAutoRecompute(Sketcher::SketchObject* obj); +/// Same as the other overload, but also returns whether redundants shall be removed or not +bool tryAutoRecompute(Sketcher::SketchObject* obj, bool &autoremoveredundants); + +/// This function tries to auto-recompute as tryAutoRecompute. If tryAutoRecompute +/// is not enabled, then it solves the SketchObject. +void tryAutoRecomputeIfNotSolve(Sketcher::SketchObject* obj); + +/// Release any currently-active handler for the document. +/// Returns true if a handler was released, and false if not +bool ReleaseHandler(Gui::Document* doc); + +std::string getStrippedPythonExceptionString(const Base::Exception&); + +void getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, int &GeoId, Sketcher::PointPos &PosId); + +bool checkBothExternal(int GeoId1, int GeoId2); + +bool checkBothExternalOrBSplinePoints(const Sketcher::SketchObject* Obj,int GeoId1, int GeoId2); + +bool isPointOrSegmentFixed(const Sketcher::SketchObject* Obj, int GeoId); + +bool areBothPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2); + +bool areAllPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, int GeoId3); + +bool inline isVertex(int GeoId, Sketcher::PointPos PosId); + +bool inline isEdge(int GeoId, Sketcher::PointPos PosId); + +bool isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, Sketcher::PointPos PosId); + +bool isBsplineKnot(const Sketcher::SketchObject* Obj, int GeoId); + +bool IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj); + +bool isBsplinePole(const Part::Geometry * geo); + +bool isBsplinePole(const Sketcher::SketchObject* Obj, int GeoId); + +/// Checks whether there is a constraint of the given type with a First element geoid and a FirstPos PosId +bool checkConstraint(const std::vector< Sketcher::Constraint * > &vals, Sketcher::ConstraintType type, int geoid, Sketcher::PointPos pos); + +inline bool isVertex(int GeoId, Sketcher::PointPos PosId) +{ + return (GeoId != Sketcher::Constraint::GeoUndef && PosId != Sketcher::none); +} + +inline bool isEdge(int GeoId, Sketcher::PointPos PosId) +{ + return (GeoId != Sketcher::Constraint::GeoUndef && PosId == Sketcher::none); +} + +} +#endif // SKETCHERGUI_Recompute_H + diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 0dfef57c23..bc7f3e4747 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -116,7 +116,7 @@ #include "DrawSketchHandler.h" #include "TaskDlgEditSketch.h" #include "TaskSketcherValidation.h" -#include "CommandConstraints.h" +#include "Utils.h" #include "ViewProviderSketchGeometryExtension.h" #include