From f29e6792425a1439471f308d3c011854b9391c48 Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 21 Jun 2016 17:14:16 +0300 Subject: [PATCH] Issue #1578: arc problems * Do not treat as a redundant the PlaneGCS's Equal constraint * Do not put into SketchSolver_Storage features, which are copies in Multi-Rotation or Multi-Translation constraint (performance optimization) --- .../PlaneGCSSolver/PlaneGCSSolver_Solver.cpp | 12 ++++++++++ src/SketchSolver/SketchSolver_Constraint.cpp | 5 ++++ src/SketchSolver/SketchSolver_Storage.cpp | 24 ++++++++++++------- src/SketchSolver/SketchSolver_Storage.h | 9 ++++--- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp index 6cb6f4076..ff8d15150 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp @@ -83,6 +83,18 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve() // additionally check redundant constraints GCS::VEC_I aRedundantID; myEquationSystem.getRedundant(aRedundantID); + // Workaround: remove all constraints "Equal" + if (!aRedundantID.empty()) { + std::set::const_iterator aCIt = myConstraints.begin(); + for (; aCIt != myConstraints.end(); ++aCIt) { + GCS::VEC_I::iterator aRIt = aRedundantID.begin(); + for (; aRIt != aRedundantID.end(); ++aRIt) + if ((*aCIt)->getTag() == *aRIt) { + aRedundantID.erase(aRIt); + break; + } + } + } // The system with tangent constraints may show redundant constraints if the entities are coupled smoothly. // Sometimes tangent constraints are fall to both conflicting and redundant constraints. // Need to check if there are redundant constraints without these tangencies. diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index fcb2a1fc1..c402ec7dd 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -226,6 +226,11 @@ void SketchSolver_Constraint::getAttributes( myStorage->update(*anIter/*, myGroupID*/); EntityWrapperPtr anEntity = myStorage->entity(*anIter); + if (!anEntity) { + // Force creation of an entity + myStorage->update(*anIter, GID_UNKNOWN, true); + anEntity = myStorage->entity(*anIter); + } myAttributes.push_back(anEntity); SketchSolver_EntityType aType = anEntity->type(); diff --git a/src/SketchSolver/SketchSolver_Storage.cpp b/src/SketchSolver/SketchSolver_Storage.cpp index a3b68b087..9c8f3504f 100644 --- a/src/SketchSolver/SketchSolver_Storage.cpp +++ b/src/SketchSolver/SketchSolver_Storage.cpp @@ -149,6 +149,8 @@ void SketchSolver_Storage::addEntity(AttributePtr theAttribute, static bool isCopyInMulti(std::shared_ptr theFeature, const std::map >& theConstraints) { + if (!theFeature) + return false; bool aResult = theFeature->isCopy(); if (aResult) { std::map >::const_iterator @@ -170,11 +172,17 @@ static bool isCopyInMulti(std::shared_ptr theFeature, return aResult; } -bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup) +bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup, bool theForce) { bool isUpdated = false; EntityWrapperPtr aRelated = entity(theFeature); if (!aRelated) { // Feature is not exist, create it + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(theFeature); + bool isCopy = isCopyInMulti(aSketchFeature, myConstraintMap); + if (!theForce && isCopy && myFeatureMap.find(theFeature) == myFeatureMap.end()) + return false; // the feature is a copy in "Multi" constraint and does not used in other constraints + std::list aSubs; // Reserve the feature in the map of features (do not want to add several copies of it) myFeatureMap[theFeature] = aRelated; @@ -182,13 +190,13 @@ bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup std::list anAttrs = pointAttributes(theFeature); std::list::const_iterator anIt = anAttrs.begin(); for (; anIt != anAttrs.end(); ++anIt) { - isUpdated = update(*anIt, theGroup) || isUpdated; + isUpdated = update(*anIt, theGroup, theForce) || isUpdated; aSubs.push_back(entity(*anIt)); } // If the feature is a circle, add its radius as a sub if (theFeature->getKind() == SketchPlugin_Circle::ID()) { AttributePtr aRadius = theFeature->attribute(SketchPlugin_Circle::RADIUS_ID()); - isUpdated = update(aRadius, theGroup) || isUpdated; + isUpdated = update(aRadius, theGroup, theForce) || isUpdated; aSubs.push_back(entity(aRadius)); } // If the feature if circle or arc, we need to add normal of the sketch to the list of subs @@ -201,9 +209,7 @@ bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID; // Check external feature - std::shared_ptr aSketchFeature = - std::dynamic_pointer_cast(theFeature); - if (aSketchFeature && (aSketchFeature->isExternal() || isCopyInMulti(aSketchFeature, myConstraintMap))) + if (aSketchFeature && (aSketchFeature->isExternal() || isCopy)) aGroup = GID_OUTOFGROUP; aRelated = aBuilder->createFeature(theFeature, aSubs, aGroup); if (!aRelated) @@ -214,14 +220,14 @@ bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup return update(aRelated) || isUpdated; } -bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theGroup) +bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theGroup, bool theForce) { AttributePtr anAttribute = theAttribute; AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttribute); if (aRefAttr) { if (aRefAttr->isObject()) { FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); - return update(aFeature, theGroup); + return update(aFeature, theGroup, theForce); } else anAttribute = aRefAttr->attr(); } @@ -237,7 +243,7 @@ bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theG if (aFeature->attribute(SketchPlugin_Arc::CENTER_ID())->isInitialized() && aFeature->attribute(SketchPlugin_Arc::START_ID())->isInitialized() && aFeature->attribute(SketchPlugin_Arc::END_ID())->isInitialized()) { - return SketchSolver_Storage::update(aFeature); + return SketchSolver_Storage::update(aFeature, theGroup, theForce); } else { myFeatureMap[aFeature] = EntityWrapperPtr(); myExistArc = true; diff --git a/src/SketchSolver/SketchSolver_Storage.h b/src/SketchSolver/SketchSolver_Storage.h index 9e2eae02f..9bc6aeadc 100644 --- a/src/SketchSolver/SketchSolver_Storage.h +++ b/src/SketchSolver/SketchSolver_Storage.h @@ -60,12 +60,15 @@ public: /// \brief Convert feature to the form applicable for specific solver and map it /// \param theFeature [in] feature to convert /// \param theGroup [in] id of the group where the feature should be placed + /// \param theForce [in] forced feature creation /// \return \c true if the feature has been created or updated - SKETCHSOLVER_EXPORT bool update(FeaturePtr theFeature, const GroupID& theGroup = GID_UNKNOWN); + SKETCHSOLVER_EXPORT bool update(FeaturePtr theFeature, const GroupID& theGroup = GID_UNKNOWN, bool theForce = false); /// \brief Convert attribute to the form applicable for specific solver and map it - /// \param theFeature [in] feature to convert + /// \param theAttribute [in] attribute to convert + /// \param theGroup [in] id of the group where the feature should be placed + /// \param theForce [in] forced feature creation /// \return \c true if the attribute has been created or updated - SKETCHSOLVER_EXPORT bool update(AttributePtr theAttribute, const GroupID& theGroup = GID_UNKNOWN); + SKETCHSOLVER_EXPORT bool update(AttributePtr theAttribute, const GroupID& theGroup = GID_UNKNOWN, bool theForce = false); /// \brief Returns constraint related to corresponding constraint SKETCHSOLVER_EXPORT -- 2.39.2