myConstraints.erase(aConstraint);
}
+static void removeTangent(GCS::VEC_I& theRedundant, const GCS::SET_I& theTangent)
+{
+ int i = 0;
+ while (i < theRedundant.size()) {
+ if (theTangent.find(theRedundant[i]) == theTangent.end())
+ ++i;
+ else
+ theRedundant.erase(theRedundant.begin() + i);
+ }
+}
+
SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve()
{
// clear list of conflicting constraints
// additionally check redundant constraints
GCS::VEC_I aRedundantID;
myEquationSystem.getRedundant(aRedundantID);
+ // remove redundant constraints relative to tangency
+ removeTangent(aRedundantID, myTangent);
if (!aRedundantID.empty())
aResult = GCS::Failed;
}
void setParameters(const GCS::VEC_pD& theParams)
{ myParameters = theParams; }
+ /// \brief Set list of IDs of tangent constraints
+ ///
+ /// Workaround to avoid incorrect report about redundant constraints
+ /// if an arc is already smoothly connected to a line.
+ void setTangent(const GCS::SET_I& theTangentIDs)
+ { myTangent = theTangentIDs; }
+
/** \brief Solve the set of equations
* \return identifier whether solution succeeded
*/
GCS::VEC_I myConflictingIDs; ///< list of IDs of conflicting constraints
bool myConfCollected; ///< specifies the conflicting constraints are already collected
+
+ GCS::SET_I myTangent; ///< list of tangent IDs to check incorrect redundant constraints
};
#endif
#include <GeomAPI_XY.h>
#include <GeomDataAPI_Point2D.h>
#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_ConstraintTangent.h>
#include <cmath>
// initialize constraints
std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
aCIt = myConstraintMap.begin();
+ GCS::SET_I aTangentIDs;
for (; aCIt != myConstraintMap.end(); ++aCIt) {
std::list<ConstraintWrapperPtr>::const_iterator aCWIt = aCIt->second.begin();
for (; aCWIt != aCIt->second.end(); ++ aCWIt) {
if (!isRedundant(*anIt, aGCS))
aSolver->addConstraint(*anIt);
}
+ // store IDs of tangent constraints to avoid incorrect report of redundant constraints
+ if (aCIt->first && aCIt->first->getKind() == SketchPlugin_ConstraintTangent::ID())
+ for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++ aCWIt) {
+ std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aGCS =
+ std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(*aCWIt);
+ if (aGCS->constraints().front()->getTypeId() == GCS::P2LDistance)
+ aTangentIDs.insert((int)(*aCWIt)->id());
+ }
}
// additional constraints for arcs
std::map<EntityWrapperPtr, std::vector<GCSConstraintPtr> >::const_iterator
for (; aRemIt != myRemovedConstraints.end(); ++aRemIt)
aSolver->removeConstraint(*aRemIt);
myRemovedConstraints.clear();
+ // set list of tangent constraints
+ aSolver->setTangent(aTangentIDs);
// initialize unknowns
aSolver->setParameters(myParameters);
}
ConstraintID myConstraintLastID; ///< identifier of last added constraint
std::map<EntityWrapperPtr, std::vector<GCSConstraintPtr> >
- myArcConstraintMap; ///< additional constraints for correct processing of the arcs
+ myArcConstraintMap; ///< additional constraints for correct processing of the arcs
std::list<GCSConstraintPtr> myRemovedConstraints; ///< list of removed constraints to notify solver
};