diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index a12cdbfb14..9d36ddc088 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -228,6 +228,12 @@ void showNoConstraintBetweenExternal() QObject::tr("Cannot add a constraint between two external geometries!")); } +void showNoConstraintBetweenFixedGeometry() +{ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Cannot add a constraint between two fixed geometries! Fixed geometries involve external geometry, blocked geometry or special points as B-Spline knot points.")); +} + bool SketcherGui::checkBothExternal(int GeoId1, int GeoId2) { if (GeoId1 == Constraint::GeoUndef || GeoId2 == Constraint::GeoUndef) @@ -245,6 +251,39 @@ bool SketcherGui::checkBothExternalOrConstructionPoints(const Sketcher::SketchOb (GeoId1 < 0 && isConstructionPoint(Obj,GeoId2)) || (GeoId2 < 0 && isConstructionPoint(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::Blocked, GeoId, Sketcher::none) || GeoId <= Sketcher::GeoEnum::RefExt || isConstructionPoint(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::Blocked, GeoId1, Sketcher::none) || GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1)) && + (checkConstraint(vals, Sketcher::Blocked, GeoId2, Sketcher::none) || GeoId2 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(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::Blocked, GeoId1, Sketcher::none) || GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1)) && + (checkConstraint(vals, Sketcher::Blocked, GeoId2, Sketcher::none) || GeoId2 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId2)) && + (checkConstraint(vals, Sketcher::Blocked, GeoId3, Sketcher::none) || GeoId3 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId3))); +} + void SketcherGui::getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, int &GeoId, PointPos &PosId) { @@ -642,6 +681,17 @@ void SketcherGui::tryAutoRecomputeIfNotSolve(Sketcher::SketchObject* obj) obj->solve(); } +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; +} + namespace SketcherGui { @@ -1155,7 +1205,7 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg) return; } - // check if the edge has already a Horizontal or Vertical constraint + // check if the edge has already a Horizontal/Vertical/Block constraint for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); it != vals.end(); ++it) { if ((*it)->Type == Sketcher::Horizontal && (*it)->First == GeoId && (*it)->FirstPos == Sketcher::none){ @@ -1168,13 +1218,19 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg) QObject::tr("The selected edge has already a vertical constraint!")); return; } + // check if the edge has already a Blocked constraint + if ((*it)->Type == Sketcher::Blocked && (*it)->First == GeoId && (*it)->FirstPos == Sketcher::none) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("The selected edge has already a Block constraint!")); + return; + } } edgegeoids.push_back(GeoId); } else if(isVertex(GeoId,PosId)) { // can be a point, a construction point, an external point or root - if(GeoId < 0 || isConstructionPoint(Obj,GeoId)) + if(isPointOrSegmentFixed(Obj, GeoId)) fixedpoints++; pointgeoids.push_back(GeoId); @@ -1209,6 +1265,11 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg) ,selection[0].getFeatName(),*it,*itp,*std::next(it),*std::next(itp)); } } + else { // vertex mode, fixedpoints > 1 + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("There are more than one fixed point selected. Select a maximum of one fixed point!")); + return; + } // finish the transaction and update commitCommand(); @@ -1237,7 +1298,7 @@ void CmdSketcherConstrainHorizontal::applyConstraint(std::vector &sel return; } - // check if the edge has already a Horizontal or Vertical constraint + // check if the edge has already a Horizontal/Vertical/Blocked constraint for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); it != vals.end(); ++it) { if ((*it)->Type == Sketcher::Horizontal && (*it)->First == CrvId){ @@ -1250,6 +1311,12 @@ void CmdSketcherConstrainHorizontal::applyConstraint(std::vector &sel QObject::tr("The selected edge has already a vertical constraint!")); return; } + // check if the edge has already a Blocked constraint + if ((*it)->Type == Sketcher::Blocked && (*it)->First == CrvId && (*it)->FirstPos == Sketcher::none) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("The selected edge has already a Block constraint!")); + return; + } } // undo command open @@ -1385,7 +1452,7 @@ void CmdSketcherConstrainVertical::activated(int iMsg) return; } - // check if the edge has already a Horizontal or Vertical constraint + // check if the edge has already a Horizontal/Vertical/Block constraint for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); it != vals.end(); ++it) { if ((*it)->Type == Sketcher::Vertical && (*it)->First == GeoId && (*it)->FirstPos == Sketcher::none){ @@ -1398,13 +1465,19 @@ void CmdSketcherConstrainVertical::activated(int iMsg) QObject::tr("The selected edge has already a horizontral constraint!")); return; } - } - edgegeoids.push_back(GeoId); + // check if the edge has already a Blocked constraint + if ((*it)->Type == Sketcher::Blocked && (*it)->First == GeoId && (*it)->FirstPos == Sketcher::none) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("The selected edge has already a Block constraint!")); + return; + } + } + edgegeoids.push_back(GeoId); } else if(isVertex(GeoId,PosId)) { - // can be a point, a construction point, an external point or root - - if(GeoId < 0 || isConstructionPoint(Obj,GeoId)) + // can be a point, a construction point, an external point, root or a blocked geometry + + if(isPointOrSegmentFixed(Obj, GeoId)) fixedpoints++; pointgeoids.push_back(GeoId); @@ -1428,7 +1501,7 @@ void CmdSketcherConstrainVertical::activated(int iMsg) ,selection[0].getFeatName(),*it); } } - else if (fixedpoints <= 1) { // pointgeoids + else if (fixedpoints <= 1) { // vertex mode, maximum one fixed point // undo command open openCommand("add vertical alignment"); std::vector::iterator it; @@ -1439,6 +1512,11 @@ void CmdSketcherConstrainVertical::activated(int iMsg) ,selection[0].getFeatName(),*it,*itp,*std::next(it),*std::next(itp)); } } + else { // vertex mode, fixedpoints > 1 + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("There are more than one fixed point selected. Select a maximum of one fixed point!")); + return; + } // finish the transaction and update commitCommand(); @@ -1480,6 +1558,12 @@ void CmdSketcherConstrainVertical::applyConstraint(std::vector &selSe QObject::tr("The selected edge has already a vertical constraint!")); return; } + // check if the edge has already a Blocked constraint + if ((*it)->Type == Sketcher::Blocked && (*it)->First == CrvId && (*it)->FirstPos == Sketcher::none) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("The selected edge has already a Block constraint!")); + return; + } } // undo command open @@ -1622,6 +1706,13 @@ void CmdSketcherConstrainLock::activated(int iMsg) int lastconstraintindex = Obj->Constraints.getSize()-1; if( GeoId.size() == 1 ) { // absolute mode + + // check if the edge has already a Blocked constraint + bool edgeisblocked = false; + + if ( isPointOrSegmentFixed(Obj, GeoId[0])) { + edgeisblocked = true; + } Base::Vector3d pnt = Obj->getPoint(GeoId[0],PosId[0]); @@ -1636,7 +1727,7 @@ void CmdSketcherConstrainLock::activated(int iMsg) lastconstraintindex+=2; - if (GeoId[0] <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId[0]) || constraintCreationMode==Reference) { + if (edgeisblocked || GeoId[0] <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId[0]) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -1651,9 +1742,20 @@ void CmdSketcherConstrainLock::activated(int iMsg) std::vector::const_iterator itp; Base::Vector3d pntr = Obj->getPoint(GeoId.back(),PosId.back()); + + // check if the edge has already a Blocked constraint + bool refpointfixed = false; + + if ( isPointOrSegmentFixed(Obj, GeoId.back())) + refpointfixed = true; for (itg = GeoId.begin(), itp = PosId.begin(); itg != std::prev(GeoId.end()) && itp != std::prev(PosId.end()); ++itp, ++itg) { + bool pointfixed = false; + + if ( isPointOrSegmentFixed(Obj, *itg)) + pointfixed = true; + Base::Vector3d pnt = Obj->getPoint(*itg,*itp); // undo command open @@ -1667,7 +1769,7 @@ void CmdSketcherConstrainLock::activated(int iMsg) selection[0].getFeatName(),*itg,*itp,GeoId.back(),PosId.back(),pntr.y-pnt.y); lastconstraintindex+=2; - if (*itg <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,*itg) || constraintCreationMode==Reference) { + if ( (refpointfixed && pointfixed) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", @@ -1694,6 +1796,12 @@ void CmdSketcherConstrainLock::applyConstraint(std::vector &selSeq, i // Create the constraints SketcherGui::ViewProviderSketch* sketchgui = static_cast(getActiveGuiDocument()->getInEdit()); Sketcher::SketchObject* Obj = sketchgui->getSketchObject(); + + // check if the edge has already a Blocked constraint + bool pointfixed = false; + + if ( isPointOrSegmentFixed(Obj, selSeq.front().GeoId)) + pointfixed = true; Base::Vector3d pnt = Obj->getPoint(selSeq.front().GeoId, selSeq.front().PosId); @@ -1706,7 +1814,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 || isConstructionPoint(Obj,selSeq.front().GeoId) || constraintCreationMode==Reference) { + if (pointfixed || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving const std::vector &ConStr = Obj->Constraints.getValues(); @@ -1847,12 +1955,12 @@ void CmdSketcherConstrainBlocked::activated(int iMsg) } std::vector GeoId; + const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); for (std::vector::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) { int GeoIdt; Sketcher::PointPos PosIdt; getIdsFromName((*it), Obj, GeoIdt, PosIdt); - GeoId.push_back(GeoIdt); if ( isVertex(GeoIdt,PosIdt) || GeoIdt < 0 ) { if(selection.size() == 1) { @@ -1866,7 +1974,16 @@ void CmdSketcherConstrainBlocked::activated(int iMsg) // clear the selection getSelection().clearSelection(); return; - } + } + + // check if the edge has already a Blocked constraint + if ( checkConstraint(vals, Sketcher::Blocked, GeoIdt, Sketcher::none)) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Double constraint"), + QObject::tr("The selected edge has already a Block constraint!")); + return; + } + + GeoId.push_back(GeoIdt); } for (std::vector::iterator itg = GeoId.begin(); itg != GeoId.end(); ++itg) { @@ -1906,6 +2023,15 @@ void CmdSketcherConstrainBlocked::applyConstraint(std::vector &selSeq // Create the constraints SketcherGui::ViewProviderSketch* sketchgui = static_cast(getActiveGuiDocument()->getInEdit()); + // check if the edge has already a Blocked constraint + const std::vector< Sketcher::Constraint * > &vals = static_cast(sketchgui->getObject())->Constraints.getValues(); + + if ( checkConstraint(vals, Sketcher::Blocked, selSeq.front().GeoId, Sketcher::none)) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Double constraint"), + QObject::tr("The selected edge has already a Block constraint!")); + return; + } + // undo command open openCommand("add blocked constraint"); @@ -2149,13 +2275,19 @@ void CmdSketcherConstrainCoincident::activated(int iMsg) int GeoId1, GeoId2; Sketcher::PointPos PosId1, PosId2; getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); - + // undo command open bool constraintsAdded = false; openCommand("add coincident constraint"); for (std::size_t i=1; iarePointsCoincident(GeoId1,PosId1,GeoId2,PosId2); @@ -2190,6 +2322,12 @@ void CmdSketcherConstrainCoincident::applyConstraint(std::vector &sel int GeoId1 = selSeq.at(0).GeoId, GeoId2 = selSeq.at(1).GeoId; Sketcher::PointPos PosId1 = selSeq.at(0).PosId, PosId2 = selSeq.at(1).PosId; + + // check if the edge has already a Blocked constraint + if ( areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } // undo command open Gui::Command::openCommand("add coincident constraint"); @@ -2257,9 +2395,10 @@ void CmdSketcherConstrainDistance::activated(int iMsg) bool constraintMode = hGrp->GetBool("ContinuousConstraintMode", true); if (constraintMode) { - ActivateHandler(getActiveGuiDocument(), - new DrawSketchHandlerGenConstraint(constraintCursor, this)); - getSelection().clearSelection(); + ActivateHandler(getActiveGuiDocument(), + new DrawSketchHandlerGenConstraint(constraintCursor, this)); + + getSelection().clearSelection(); } else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select vertexes from the sketch.")); @@ -2283,7 +2422,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) if (SubNames.size() == 2) getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - bool bothexternalorconstructionpoints=checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2); + bool arebothpointsorsegmentsfixed=areBothPointsOrSegmentsFixed(Obj,GeoId1, GeoId2); if (isVertex(GeoId1,PosId1) && (GeoId2 == Sketcher::GeoEnum::VAxis || GeoId2 == Sketcher::GeoEnum::HAxis)) { std::swap(GeoId1,GeoId2); @@ -2297,6 +2436,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) if (GeoId1 == Sketcher::GeoEnum::HAxis && PosId1 == Sketcher::none) { PosId1 = Sketcher::start; + openCommand("add distance from horizontal axis constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%d,%d,%f)) ", @@ -2304,6 +2444,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) } else if (GeoId1 == Sketcher::GeoEnum::VAxis && PosId1 == Sketcher::none) { PosId1 = Sketcher::start; + openCommand("add distance from vertical axis constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%d,%d,%f)) ", @@ -2311,14 +2452,14 @@ void CmdSketcherConstrainDistance::activated(int iMsg) } else { Base::Vector3d pnt1 = Obj->getPoint(GeoId1,PosId1); - + openCommand("add point to point distance constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,(pnt2-pnt1).Length()); } - if (bothexternalorconstructionpoints || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -2350,7 +2491,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 (bothexternalorconstructionpoints || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -2369,19 +2510,21 @@ void CmdSketcherConstrainDistance::activated(int iMsg) QObject::tr("Cannot add a length constraint on an axis!")); return; } + + arebothpointsorsegmentsfixed=isPointOrSegmentFixed(Obj,GeoId1); const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment *lineSeg; lineSeg = static_cast(geom); - double ActLength = (lineSeg->getEndPoint()-lineSeg->getStartPoint()).Length(); + double ActLength = (lineSeg->getEndPoint()-lineSeg->getStartPoint()).Length(); openCommand("add length constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%f)) ", selection[0].getFeatName(),GeoId1,ActLength); - if (GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1)|| constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -2407,6 +2550,8 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe int GeoId1 = Constraint::GeoUndef, GeoId2 = Constraint::GeoUndef; Sketcher::PointPos PosId1 = Sketcher::none, PosId2 = Sketcher::none; + + bool arebothpointsorsegmentsfixed=areBothPointsOrSegmentsFixed(Obj,GeoId1, GeoId2); switch (seqIndex) { case 0: // {SelVertex, SelVertexOrRoot} @@ -2419,6 +2564,7 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe if (GeoId1 == Sketcher::GeoEnum::HAxis && PosId1 == Sketcher::none) { PosId1 = Sketcher::start; + openCommand("add distance from horizontal axis constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%d,%d,%f)) ", @@ -2426,6 +2572,7 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe } else if (GeoId1 == Sketcher::GeoEnum::VAxis && PosId1 == Sketcher::none) { PosId1 = Sketcher::start; + openCommand("add distance from vertical axis constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%d,%d,%f)) ", @@ -2440,7 +2587,7 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe Obj->getNameInDocument(),GeoId1,PosId1,GeoId2,PosId2,(pnt2-pnt1).Length()); } - if (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -2457,6 +2604,8 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe { GeoId1 = GeoId2 = selSeq.at(0).GeoId; PosId1 = Sketcher::start; PosId2 = Sketcher::end; + + arebothpointsorsegmentsfixed=isPointOrSegmentFixed(Obj,GeoId1); const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { @@ -2469,7 +2618,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 || isConstructionPoint(Obj,GeoId1) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -2493,7 +2642,7 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector &selSe { GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(1).GeoId; PosId1 = selSeq.at(0).PosId; PosId2 = selSeq.at(1).PosId; - + Base::Vector3d pnt = Obj->getPoint(GeoId1,PosId1); const Part::Geometry *geom = Obj->getGeometry(GeoId2); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { @@ -2509,7 +2658,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 (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -2663,8 +2812,8 @@ 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 (checkBothExternalOrConstructionPoints(Obj, points[iPnt].GeoId, curves[iCrv].GeoId)){ - showNoConstraintBetweenExternal(); + if (areBothPointsOrSegmentsFixed(Obj, points[iPnt].GeoId, curves[iCrv].GeoId)){ + showNoConstraintBetweenFixedGeometry(); continue; } if (points[iPnt].GeoId == curves[iCrv].GeoId) @@ -2732,8 +2881,9 @@ void CmdSketcherConstrainPointOnObject::applyConstraint(std::vector & openCommand("add point on object constraint"); bool allOK = true; - if (checkBothExternalOrConstructionPoints(Obj, GeoIdVt, GeoIdCrv)){ - showNoConstraintBetweenExternal(); + + if (areBothPointsOrSegmentsFixed(Obj, GeoIdVt, GeoIdCrv)){ + showNoConstraintBetweenFixedGeometry(); allOK = false; } if (GeoIdVt == GeoIdCrv) @@ -2750,7 +2900,6 @@ void CmdSketcherConstrainPointOnObject::applyConstraint(std::vector & return; } - if (allOK) { Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ", @@ -2840,7 +2989,7 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) if (SubNames.size() == 2) getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - bool bothexternalorconstructionpoints=checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2); + bool arebothpointsorsegmentsfixed=areBothPointsOrSegmentsFixed(Obj,GeoId1, GeoId2); if (GeoId2 == Sketcher::GeoEnum::HAxis || GeoId2 == Sketcher::GeoEnum::VAxis) { std::swap(GeoId1,GeoId2); @@ -2860,6 +3009,8 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) QObject::tr("Cannot add a horizontal length constraint on an axis!")); return; } + + arebothpointsorsegmentsfixed = isPointOrSegmentFixed(Obj,GeoId1); const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { @@ -2888,7 +3039,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 (bothexternalorconstructionpoints || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -2910,13 +3061,16 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) Base::Vector3d pnt = Obj->getPoint(GeoId1,PosId1); double ActX = pnt.x; + + arebothpointsorsegmentsfixed=isPointOrSegmentFixed(Obj,GeoId1); openCommand("add fixed x-coordinate constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,ActX); - if (GeoId1 <= Sketcher::GeoEnum::RefExt || isConstructionPoint(Obj,GeoId1) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + + if (arebothpointsorsegmentsfixed || 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)", @@ -2986,7 +3140,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 (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (areBothPointsOrSegmentsFixed(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)", @@ -3084,7 +3238,7 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) if (SubNames.size() == 2) getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - bool bothexternalorconstruction=checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2); + bool arebothpointsorsegmentsfixed=areBothPointsOrSegmentsFixed(Obj,GeoId1, GeoId2); if (GeoId2 == Sketcher::GeoEnum::HAxis || GeoId2 == Sketcher::GeoEnum::VAxis) { std::swap(GeoId1,GeoId2); @@ -3102,6 +3256,8 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) QObject::tr("Cannot add a vertical length constraint on an axis!")); return; } + + arebothpointsorsegmentsfixed = isPointOrSegmentFixed(Obj,GeoId1); const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { @@ -3131,7 +3287,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 (bothexternalorconstruction || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (arebothpointsorsegmentsfixed || 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)", @@ -3153,6 +3309,8 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) Base::Vector3d pnt = Obj->getPoint(GeoId1,PosId1); double ActY = pnt.y; + + arebothpointsorsegmentsfixed=isPointOrSegmentFixed(Obj,GeoId1); openCommand("add fixed y-coordinate constraint"); Gui::Command::doCommand( @@ -3229,7 +3387,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 (checkBothExternalOrConstructionPoints(Obj,GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (areBothPointsOrSegmentsFixed(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)", @@ -3374,9 +3532,9 @@ void CmdSketcherConstrainParallel::activated(int iMsg) QObject::tr("Select a valid line")); return; } - else if (GeoId < 0) { + else if (isPointOrSegmentFixed(Obj,GeoId)) { if (hasAlreadyExternal) { - showNoConstraintBetweenExternal(); + showNoConstraintBetweenFixedGeometry(); return; } else @@ -3429,6 +3587,11 @@ void CmdSketcherConstrainParallel::applyConstraint(std::vector &selSe QObject::tr("The selected edge is not a valid line")); return; } + + if( areBothPointsOrSegmentsFixed(Obj,GeoId1, GeoId2)) { + showNoConstraintBetweenFixedGeometry(); + return; + } // undo command open openCommand("add parallel constraint"); @@ -3571,8 +3734,8 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - if (checkBothExternal(GeoId1, GeoId2)) { //checkBothExternal displays error message - showNoConstraintBetweenExternal(); + if (areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2)) { //checkBothExternal displays error message + showNoConstraintBetweenFixedGeometry(); return; } @@ -3869,6 +4032,12 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector & int GeoId1 = Constraint::GeoUndef, GeoId2 = Constraint::GeoUndef, GeoId3 = Constraint::GeoUndef; Sketcher::PointPos PosId1 = Sketcher::none, PosId2 = Sketcher::none, PosId3 = Sketcher::none; + // check if the edge has already a Blocked constraint + if ( areBothPointsOrSegmentsFixed(Obj,GeoId1,GeoId2) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } + switch (seqIndex) { case 0: // {SelEdge, SelEdgeOrAxis} case 1: // {SelEdgeOrAxis, SelEdge} @@ -4185,8 +4354,8 @@ void CmdSketcherConstrainTangent::activated(int iMsg) getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - if (checkBothExternal(GeoId1, GeoId2)){ //checkBothExternal displays error message - showNoConstraintBetweenExternal(); + if (areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2)){ //checkBothExternal displays error message + showNoConstraintBetweenFixedGeometry(); return; } if (SubNames.size() == 3) { //tangent via point @@ -4449,6 +4618,12 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector &selSeq int GeoId1 = Constraint::GeoUndef, GeoId2 = Constraint::GeoUndef, GeoId3 = Constraint::GeoUndef; Sketcher::PointPos PosId1 = Sketcher::none, PosId2 = Sketcher::none, PosId3 = Sketcher::none; + // check if the edge has already a Blocked constraint + if ( areBothPointsOrSegmentsFixed(Obj,GeoId1,GeoId2) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } + switch (seqIndex) { case 0: // {SelEdge, SelEdgeOrAxis} case 1: // {SelEdgeOrAxis, SelEdge} @@ -4750,34 +4925,44 @@ void CmdSketcherConstrainRadius::activated(int iMsg) std::vector< std::pair > externalGeoIdRadiusMap; for (std::vector::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) { + bool issegmentfixed = false; + int GeoId; + if (it->size() > 4 && it->substr(0,4) == "Edge") { - int GeoId = std::atoi(it->substr(4,4000).c_str()) - 1; - const Part::Geometry *geom = Obj->getGeometry(GeoId); - if (geom && geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { - const Part::GeomArcOfCircle *arc = static_cast(geom); - double radius = arc->getRadius(); - geoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); - } - else if (geom && geom->getTypeId() == Part::GeomCircle::getClassTypeId()) { - const Part::GeomCircle *circle = static_cast(geom); - double radius = circle->getRadius(); - geoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); - } + GeoId = std::atoi(it->substr(4,4000).c_str()) - 1; + issegmentfixed = isPointOrSegmentFixed(Obj,GeoId); } - if (it->size() > 4 && it->substr(0,12) == "ExternalEdge") { - int GeoId = -std::atoi(it->substr(12,4000).c_str()) - 2; - const Part::Geometry *geom = Obj->getGeometry(GeoId); - if (geom && geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { - const Part::GeomArcOfCircle *arc = static_cast(geom); - double radius = arc->getRadius(); - externalGeoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); - } - else if (geom && geom->getTypeId() == Part::GeomCircle::getClassTypeId()) { - const Part::GeomCircle *circle = static_cast(geom); - double radius = circle->getRadius(); - externalGeoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); - } + else if (it->size() > 4 && it->substr(0,12) == "ExternalEdge") { + GeoId = -std::atoi(it->substr(12,4000).c_str()) - 2; + issegmentfixed = true; } + else + continue; + + const Part::Geometry *geom = Obj->getGeometry(GeoId); + + if (geom && geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { + const Part::GeomArcOfCircle *arc = static_cast(geom); + double radius = arc->getRadius(); + + if(issegmentfixed) { + externalGeoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); + } + else { + geoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); + } + } + else if (geom && geom->getTypeId() == Part::GeomCircle::getClassTypeId()) { + const Part::GeomCircle *circle = static_cast(geom); + double radius = circle->getRadius(); + + if(issegmentfixed) { + externalGeoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); + } + else { + geoIdRadiusMap.push_back(std::make_pair(GeoId, radius)); + } + } } if (geoIdRadiusMap.empty() && externalGeoIdRadiusMap.empty()) { @@ -5031,8 +5216,8 @@ void CmdSketcherConstrainRadius::applyConstraint(std::vector &selSeq, const std::vector &ConStr = Obj->Constraints.getValues(); int indexConstr = ConStr.size() - 1; - - if(GeoId <= Sketcher::GeoEnum::RefExt || constraintCreationMode==Reference) { + bool fixed = isPointOrSegmentFixed(Obj,GeoId); + if(fixed || constraintCreationMode==Reference) { Gui::Command::doCommand(Doc, "App.ActiveDocument.%s.setDriving(%i,%s)", Obj->getNameInDocument(), ConStr.size()-1, "False"); } @@ -5052,7 +5237,7 @@ void CmdSketcherConstrainRadius::applyConstraint(std::vector &selSeq, ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); bool show = hGrp->GetBool("ShowDialogOnDistanceConstraint", true); // Ask for the value of the radius immediately - if (show && constraintCreationMode==Driving && GeoId >= 0) { + if (show && constraintCreationMode==Driving && !fixed) { QDialog dlg(Gui::getMainWindow()); Ui::InsertDatum ui_Datum; ui_Datum.setupUi(&dlg); @@ -5241,7 +5426,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg) std::swap(PosId2,PosId3); }; - bool bothexternal=checkBothExternal(GeoId1, GeoId2); + bool bothexternal=areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2); if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) { double ActAngle = 0.0; @@ -5296,7 +5481,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg) } else if (SubNames.size() < 3) { - bool bothexternal = checkBothExternal(GeoId1, GeoId2); + bool bothexternal = areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2); if (isVertex(GeoId1,PosId1) && isEdge(GeoId2,PosId2)) { std::swap(GeoId1,GeoId2); @@ -5549,7 +5734,7 @@ void CmdSketcherConstrainAngle::applyConstraint(std::vector &selSeq, Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Angle',%d,%d,%d,%d,%f)) ", Obj->getNameInDocument(),GeoId1,PosId1,GeoId2,PosId2,ActAngle); - if (checkBothExternal(GeoId1, GeoId2) || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving + if (areBothPointsOrSegmentsFixed(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)", @@ -5586,7 +5771,7 @@ void CmdSketcherConstrainAngle::applyConstraint(std::vector &selSeq, } - bool bothexternal=checkBothExternal(GeoId1, GeoId2); + bool bothexternal=areBothPointsOrSegmentsFixed(Obj,GeoId1, GeoId2); if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) { double ActAngle = 0.0; @@ -5735,14 +5920,14 @@ void CmdSketcherConstrainEqual::activated(int iMsg) QObject::tr("Select two or more compatible edges")); return; } - else if (GeoId < 0) { + else if (isPointOrSegmentFixed(Obj,GeoId)) { if (GeoId == Sketcher::GeoEnum::HAxis || GeoId == Sketcher::GeoEnum::VAxis) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Sketch axes cannot be used in equality constraints")); return; } else if (hasAlreadyExternal) { - showNoConstraintBetweenExternal(); + showNoConstraintBetweenFixedGeometry(); return; } else @@ -5811,6 +5996,12 @@ void CmdSketcherConstrainEqual::applyConstraint(std::vector &selSeq, case 2: // {SelExternalEdge, SelEdge} { GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(1).GeoId; + + // check if the edge has already a Blocked constraint + if ( areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } // undo command open openCommand("add equality constraint"); @@ -5907,7 +6098,10 @@ void CmdSketcherConstrainSymmetric::activated(int iMsg) getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); if (SubNames.size() == 2) { - //checkBothExternal(GeoId1, GeoId2); + if ( areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } if (isVertex(GeoId1,PosId1) && isEdge(GeoId2,PosId2)) { std::swap(GeoId1,GeoId2); std::swap(PosId1,PosId2); @@ -5954,10 +6148,9 @@ void CmdSketcherConstrainSymmetric::activated(int iMsg) std::swap(PosId2,PosId3); } - if ((GeoId1 < 0 && GeoId2 < 0 && GeoId3 < 0)) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Cannot add a constraint between external geometries!")); - return; + if ( areAllPointsOrSegmentsFixed(Obj, GeoId1, GeoId2, GeoId3) ) { + showNoConstraintBetweenFixedGeometry(); + return; } if (isVertex(GeoId1,PosId1) && @@ -6029,6 +6222,11 @@ void CmdSketcherConstrainSymmetric::applyConstraint(std::vector &selS QObject::tr("Cannot add a symmetry constraint between a line and its end points!")); return; } + + if ( areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } break; } case 2: // {SelVertex, SelEdge, SelVertexOrRoot} @@ -6040,6 +6238,10 @@ void CmdSketcherConstrainSymmetric::applyConstraint(std::vector &selS GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(2).GeoId; GeoId3 = selSeq.at(1).GeoId; PosId1 = selSeq.at(0).PosId; PosId2 = selSeq.at(2).PosId; + if ( areAllPointsOrSegmentsFixed(Obj, GeoId1, GeoId2, GeoId3) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } const Part::Geometry *geom = Obj->getGeometry(GeoId3); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { if (GeoId1 == GeoId2 && GeoId2 == GeoId3) { @@ -6073,6 +6275,10 @@ void CmdSketcherConstrainSymmetric::applyConstraint(std::vector &selS GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(2).GeoId; GeoId3 = selSeq.at(1).GeoId; PosId1 = selSeq.at(0).PosId; PosId2 = selSeq.at(2).PosId; PosId3 = selSeq.at(1).PosId; + if ( areAllPointsOrSegmentsFixed(Obj, GeoId1, GeoId2, GeoId3) ) { + showNoConstraintBetweenFixedGeometry(); + return; + } break; } default: @@ -6160,8 +6366,8 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) std::swap(PosId2,PosId3); } - //a bunch of validity checks - if ((GeoId1 < 0 && GeoId2 < 0 && GeoId3 < 0)) { + //a bunch of validity checks + if (areAllPointsOrSegmentsFixed(Obj, GeoId1, GeoId2, GeoId3) ) { strError = QObject::tr("Can not create constraint with external geometry only!!", dmbg); throw(Base::Exception("")); } @@ -6303,7 +6509,7 @@ void CmdSketcherConstrainInternalAlignment::activated(int iMsg) Sketcher::PointPos PosId; getIdsFromName(*it, Obj, GeoId, PosId); - if (GeoId < 0) { + if (isPointOrSegmentFixed(Obj,GeoId)) { if (GeoId == Sketcher::GeoEnum::HAxis || GeoId == Sketcher::GeoEnum::VAxis) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Sketch axes cannot be used in internal alignment constraint")); diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.h b/src/Mod/Sketcher/Gui/CommandConstraints.h index 13aebca913..2c7ea14477 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.h +++ b/src/Mod/Sketcher/Gui/CommandConstraints.h @@ -33,6 +33,12 @@ bool checkBothExternal(int GeoId1, int GeoId2); bool checkBothExternalOrConstructionPoints(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); @@ -109,6 +115,9 @@ bool tryAutoRecompute(); /// 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); } #endif // SKETCHERGUI_DrawSketchHandler_H