-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File: SketchSolver_Group.cpp
-// Created: 27 May 2014
-// Author: Artem ZHIDKOV
+// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
#include "SketchSolver_Group.h"
#include <SketchSolver_Error.h>
// ========================================================
-// ========= SketchSolver_Group ===============
+// ========= SketchSolver_Group ===============
// ========================================================
SketchSolver_Group::SketchSolver_Group(const CompositeFeaturePtr& theWorkplane)
return myStorage->update(theFeature);
}
-bool SketchSolver_Group::moveFeature(FeaturePtr theFeature)
+template <class Type>
+static SolverConstraintPtr move(StoragePtr theStorage,
+ SolverPtr theSketchSolver,
+ int theSketchDOF,
+ bool theEventsBlocked,
+ Type theFeatureOrPoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
{
- if (myDOF == 0) {
+ bool isEntityExists = (theStorage->entity(theFeatureOrPoint).get() != 0);
+ if (theSketchDOF == 0 && isEntityExists) {
// avoid moving elements of fully constrained sketch
- myStorage->refresh();
- return true;
+ theStorage->refresh();
+ return SolverConstraintPtr();
}
// Create temporary Fixed constraint
- SolverConstraintPtr aConstraint = PlaneGCSSolver_Tools::createMovementConstraint(theFeature);
- if (!aConstraint)
- return false;
- aConstraint->process(myStorage, myIsEventsBlocked);
- if (aConstraint->error().empty())
- setTemporary(aConstraint);
- else
- myStorage->notify(theFeature);
+ std::shared_ptr<SketchSolver_ConstraintMovement> aConstraint =
+ PlaneGCSSolver_Tools::createMovementConstraint(theFeatureOrPoint);
+ if (aConstraint) {
+ SolverConstraintPtr(aConstraint)->process(theStorage, theEventsBlocked);
+ if (aConstraint->error().empty()) {
+ aConstraint->startPoint(theFrom);
+ theSketchSolver->initialize();
+ aConstraint->moveTo(theTo);
+ theStorage->setNeedToResolve(true);
+ } else
+ theStorage->notify(aConstraint->movedFeature());
+ }
+
+ return aConstraint;
+}
+bool SketchSolver_Group::moveFeature(FeaturePtr theFeature,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
+{
+ SolverConstraintPtr aConstraint =
+ move(myStorage, mySketchSolver, myDOF, myIsEventsBlocked, theFeature, theFrom, theTo);
+ setTemporary(aConstraint);
+ return true;
+}
+
+bool SketchSolver_Group::movePoint(AttributePtr theAttribute,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
+{
+ SolverConstraintPtr aConstraint =
+ move(myStorage, mySketchSolver, myDOF, myIsEventsBlocked, theAttribute, theFrom, theTo);
+ setTemporary(aConstraint);
return true;
}
// ============================================================================
bool SketchSolver_Group::resolveConstraints()
{
+ static const int MAX_STACK_SIZE = 5;
// check the "Multi" constraints do not drop sketch into infinite loop
- if (myMultiConstraintUpdateStack > 1) {
+ if (myMultiConstraintUpdateStack > MAX_STACK_SIZE) {
+ myMultiConstraintUpdateStack = 0;
myPrevResult = PlaneGCSSolver_Solver::STATUS_FAILED;
// generate error message due to loop update of the sketch
getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())
PlaneGCSSolver_Solver::SolveStatus aResult = PlaneGCSSolver_Solver::STATUS_OK;
try {
- if (!isGroupEmpty && myMultiConstraintUpdateStack <= 1)
+ if (!isGroupEmpty)
+ aResult = mySketchSolver->solve();
+ if (aResult == PlaneGCSSolver_Solver::STATUS_FAILED &&
+ !myTempConstraints.empty()) {
+ mySketchSolver->undo();
+ removeTemporaryConstraints();
aResult = mySketchSolver->solve();
+ }
} catch (...) {
getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())
->setValue(SketchSolver_Error::SOLVESPACE_CRASH());
// additional check that copied entities used in Mirror and other "Multi" constraints
// is not connected with their originals by constraints.
myMultiConstraintUpdateStack += 1;
- updateMultiConstraints();
aResolved = true;
if (myStorage->isNeedToResolve())
aResolved = resolveConstraints();
{
std::ostringstream aDoFMsg;
int aDoF = mySketchSolver->dof();
+ /// "DoF = 0" content of string value is used in PartSet by Sketch edit
+ /// If it is changed, it should be corrected also there
if (aDoF == 0)
aDoFMsg << "Sketch is fully fixed (DoF = 0)";
else
// ============================================================================
void SketchSolver_Group::repairConsistency()
{
- if (!myStorage->isConsistent()) {
+ if (!areConstraintsValid() || !myStorage->areFeaturesValid()) {
// remove invalid constraints
std::set<ConstraintPtr> anInvalidConstraints;
ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
// ============================================================================
void SketchSolver_Group::setTemporary(SolverConstraintPtr theConstraint)
{
- myTempConstraints.insert(theConstraint);
+ if (theConstraint)
+ myTempConstraints.insert(theConstraint);
}
// ============================================================================
myIsEventsBlocked = isBlocked;
}
-// ============================================================================
-// Function: updateMultiConstraints
-// Class: SketchSolver_Group
-// Purpose: update multi constraints
-// ============================================================================
-void SketchSolver_Group::updateMultiConstraints()
+bool SketchSolver_Group::areConstraintsValid() const
{
- ConstraintConstraintMap::iterator anIt = myConstraints.begin();
- for (; anIt != myConstraints.end(); ++anIt) {
- if (anIt->first->getKind() == SketchPlugin_ConstraintMirror::ID() ||
- anIt->first->getKind() == SketchPlugin_MultiRotation::ID() ||
- anIt->first->getKind() == SketchPlugin_MultiTranslation::ID())
- anIt->second->update();
- }
+ // Check the constraints are valid
+ ConstraintConstraintMap::const_iterator aCIter = myConstraints.begin();
+ for (; aCIter != myConstraints.end(); ++aCIter)
+ if (!aCIter->first->data() || !aCIter->first->data()->isValid())
+ return false;
+ return true;
}