diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index ca4d28beeb..504762abea 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -390,6 +390,17 @@ int SketchObject::toggleDriving(int ConstrId) if (!(vals[ConstrId]->First>=0 || vals[ConstrId]->Second>=0 || vals[ConstrId]->Third>=0) && vals[ConstrId]->isDriving==false) return -3; // a constraint that does not have at least one element as not-external-geometry can never be driving. + + const Part::Geometry * geo1 = getGeometry(vals[ConstrId]->First); + const Part::Geometry * geo2 = getGeometry(vals[ConstrId]->Second); + const Part::Geometry * geo3 = getGeometry(vals[ConstrId]->Third); + + bool extorconstructionpoint1 = (vals[ConstrId]->First == Constraint::GeoUndef) || (vals[ConstrId]->First < 0) || (geo1 && geo1->getTypeId() == Part::GeomPoint::getClassTypeId() && geo1->Construction == true); + bool extorconstructionpoint2 = (vals[ConstrId]->Second == Constraint::GeoUndef) || (vals[ConstrId]->Second < 0) || (geo2 && geo2->getTypeId() == Part::GeomPoint::getClassTypeId() && geo2->Construction == true); + bool extorconstructionpoint3 = (vals[ConstrId]->Third == Constraint::GeoUndef) || (vals[ConstrId]->Third < 0) || (geo3 && geo3->getTypeId() == Part::GeomPoint::getClassTypeId() && geo3->Construction == true); + + if (extorconstructionpoint1 && extorconstructionpoint2 && extorconstructionpoint3 && vals[ConstrId]->isDriving==false) + return -4; // copy the list std::vector newVals(vals); diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index 8251967e4b..6ee70b36fe 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -257,6 +257,15 @@ bool SketcherGui::checkBothExternal(int GeoId1, int GeoId2) return (GeoId1 < 0 && GeoId2 < 0); } +bool SketcherGui::checkBothExternalOrConstructionPoints(const Sketcher::SketchObject* Obj,int GeoId1, int GeoId2) +{ + if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) + return false; + else + return (GeoId1 < 0 && GeoId2 < 0) || (isConstructionPoint(Obj,GeoId1) && isConstructionPoint(Obj,GeoId2)) || + (GeoId1 < 0 && isConstructionPoint(Obj,GeoId2)) || (GeoId2 < 0 && isConstructionPoint(Obj,GeoId1)); +} + void SketcherGui::getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, int &GeoId, PointPos &PosId) { @@ -305,6 +314,14 @@ bool SketcherGui::isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, P return false; } +bool SketcherGui::isConstructionPoint(const Sketcher::SketchObject* Obj, int GeoId) +{ + const Part::Geometry * geo = Obj->getGeometry(GeoId); + + return (geo->getTypeId() == Part::GeomPoint::getClassTypeId() && geo->Construction == true); + +} + 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. @@ -1602,7 +1619,7 @@ void CmdSketcherConstrainLock::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%f)) ", selection[0].getFeatName(),GeoId,PosId,pnt.y); - if (GeoId <= Sketcher::GeoEnum::RefExt || constraintCreationMode==Reference) { + if (GeoId <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); @@ -1645,7 +1662,7 @@ void CmdSketcherConstrainLock::applyConstraint(std::vector &selSeq, i Gui::Command::Doc, "App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY', %d, %d, %f)) ", sketchgui->getObject()->getNameInDocument(), selSeq.front().GeoId, selSeq.front().PosId, pnt.y); - if (selSeq.front().GeoId <= Sketcher::GeoEnum::RefExt || constraintCreationMode==Reference) { + if (selSeq.front().GeoId <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,selSeq.front().GeoId) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); @@ -2034,7 +2051,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) if (SubNames.size() == 2) getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - bool bothexternal=checkBothExternal(GeoId1, GeoId2); + bool bothexternalorconstructionpoints=checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2); if (isVertex(GeoId1,PosId1) && (GeoId2 == Sketcher::GeoEnum::VAxis || GeoId2 == Sketcher::GeoEnum::HAxis)) { std::swap(GeoId1,GeoId2); @@ -2069,7 +2086,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,(pnt2-pnt1).Length()); } - if (bothexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (bothexternalorconstructionpoints || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2101,7 +2118,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,GeoId2,ActDist); - if (bothexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (bothexternalorconstructionpoints || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2132,7 +2149,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%f)) ", selection[0].getFeatName(),GeoId1,ActLength); - if (GeoId1 <= Sketcher::GeoEnum::RefExt || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1)|| constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2191,7 +2208,7 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe Obj->getNameInDocument(),GeoId1,PosId1,GeoId2,PosId2,(pnt2-pnt1).Length()); } - if (checkBothExternal(GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2220,7 +2237,7 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%f)) ", Obj->getNameInDocument(),GeoId1,ActLength); - if (GeoId1 <= Sketcher::GeoEnum::RefExt || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2260,7 +2277,7 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%f)) ", Obj->getNameInDocument(),GeoId1,PosId1,GeoId2,ActDist); - if (checkBothExternal(GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2414,7 +2431,7 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg) int cnt = 0; for (std::size_t iPnt = 0; iPnt < points.size(); iPnt++) { for (std::size_t iCrv = 0; iCrv < curves.size(); iCrv++) { - if (checkBothExternal(points[iPnt].GeoId, curves[iCrv].GeoId)){ + if (checkBothExternalOrConstructionPoints(Obj, points[iPnt].GeoId, curves[iCrv].GeoId)){ showNoConstraintBetweenExternal(); continue; } @@ -2483,7 +2500,7 @@ void CmdSketcherConstrainPointOnObject::applyConstraint(std::vector & openCommand("add point on object constraint"); bool allOK = true; - if (checkBothExternal(GeoIdVt, GeoIdCrv)){ + if (checkBothExternalOrConstructionPoints(Obj, GeoIdVt, GeoIdCrv)){ showNoConstraintBetweenExternal(); allOK = false; } @@ -2595,7 +2612,7 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) if (SubNames.size() == 2) getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - bool bothexternal=checkBothExternal(GeoId1, GeoId2); + bool bothexternalorconstructionpoints=checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2); if (GeoId2 == Sketcher::GeoEnum::HAxis || GeoId2 == Sketcher::GeoEnum::VAxis) { std::swap(GeoId1,GeoId2); @@ -2643,7 +2660,7 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,ActLength); - if (bothexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (bothexternalorconstructionpoints || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2671,7 +2688,7 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,ActX); - if (GeoId1 <= Sketcher::GeoEnum::RefExt || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2741,7 +2758,7 @@ void CmdSketcherConstrainDistanceX::applyConstraint(std::vector &selS Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%d,%d,%f)) ", Obj->getNameInDocument(),GeoId1,PosId1,GeoId2,PosId2,ActLength); - if (checkBothExternal(GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2839,7 +2856,7 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) if (SubNames.size() == 2) getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - bool bothexternal=checkBothExternal(GeoId1, GeoId2); + bool bothexternalorconstruction=checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2); if (GeoId2 == Sketcher::GeoEnum::HAxis || GeoId2 == Sketcher::GeoEnum::VAxis) { std::swap(GeoId1,GeoId2); @@ -2886,7 +2903,7 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,ActLength); - if (bothexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (bothexternalorconstruction || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2914,7 +2931,7 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,ActY); - if (GeoId1 <= Sketcher::GeoEnum::RefExt || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -2984,7 +3001,7 @@ void CmdSketcherConstrainDistanceY::applyConstraint(std::vector &selS Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%d,%d,%f)) ", Obj->getNameInDocument(),GeoId1,PosId1,GeoId2,PosId2,ActLength); - if (checkBothExternal(GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.h b/src/Mod/Sketcher/Gui/CommandConstraints.h index 9efb6a6cab..9e7a1be935 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.h +++ b/src/Mod/Sketcher/Gui/CommandConstraints.h @@ -31,6 +31,8 @@ namespace SketcherGui { bool checkBothExternal(int GeoId1, int GeoId2); +bool checkBothExternalOrConstructionPoints(const Sketcher::SketchObject* Obj,int GeoId1, int GeoId2); + void getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, int &GeoId, Sketcher::PointPos &PosId); bool inline isVertex(int GeoId, Sketcher::PointPos PosId); @@ -39,6 +41,8 @@ bool inline isEdge(int GeoId, Sketcher::PointPos PosId); bool isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, Sketcher::PointPos PosId); +bool isConstructionPoint(const Sketcher::SketchObject* Obj, int GeoId); + bool IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index b85855e4e5..cd2e911dad 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -769,6 +769,8 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe if(autoRecompute) Gui::Command::updateActive(); + else + getSketchObject()->solve(); } catch (const Base::Exception& e) { Gui::Command::abortCommand(); @@ -805,6 +807,8 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe if(autoRecompute) Gui::Command::updateActive(); + else + getSketchObject()->solve(); } catch (const Base::Exception& e) { Gui::Command::abortCommand();