adjustAngle(theConstraint);
else if (aType == CONSTRAINT_PT_LINE_DISTANCE)
adjustPtLineDistance(theConstraint);
+ else if (aType == CONSTRAINT_SYMMETRIC)
+ adjustMirror(theConstraint);
}
EntityWrapperPtr PlaneGCSSolver_Builder::createFeature(
theConstraint->setValue(theConstraint->value() * (-1.0));
}
+void adjustMirror(ConstraintWrapperPtr theConstraint)
+{
+ std::vector<EntityWrapperPtr> aPoints;
+ EntityWrapperPtr aMirrorLine;
+
+ const std::list<EntityWrapperPtr>& aSubs = theConstraint->entities();
+ std::list<EntityWrapperPtr>::const_iterator anIt = aSubs.begin();
+ for (; anIt != aSubs.end(); ++anIt) {
+ if ((*anIt)->type() == ENTITY_POINT)
+ aPoints.push_back(*anIt);
+ else if ((*anIt)->type() == ENTITY_LINE)
+ aMirrorLine = *anIt;
+ }
+
+ makeMirrorPoints(aPoints[0], aPoints[1], aMirrorLine);
+}
+
}
+bool PlaneGCSSolver_Storage::isRedundant(
+ GCSConstraintPtr theCheckedConstraint,
+ ConstraintWrapperPtr theParentConstraint) const
+{
+ if (theParentConstraint->type() == CONSTRAINT_SYMMETRIC) {
+ if (theCheckedConstraint->getTypeId() == GCS::Perpendicular) {
+ BuilderPtr aBuilder = PlaneGCSSolver_Builder::getInstance();
+ // check the initial point is placed on the mirror line
+ std::list<EntityWrapperPtr> aSubs = theParentConstraint->entities();
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = aBuilder->point(aSubs.front());
+ std::shared_ptr<GeomAPI_Lin2d> aLine = aBuilder->line(aSubs.back());
+ return aLine->distance(aPoint) < tolerance;
+ }
+ }
+
+ return false;
+}
+
void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver)
{
std::shared_ptr<PlaneGCSSolver_Solver> aSolver =
std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(*aCWIt);
std::list<GCSConstraintPtr>::const_iterator anIt = aGCS->constraints().begin();
for (; anIt != aGCS->constraints().end(); ++anIt)
- aSolver->addConstraint(*anIt);
+ if (!isRedundant(*anIt, aGCS))
+ aSolver->addConstraint(*anIt);
}
}
// additional constraints for arcs
/// \brief Adjust parameters of points coincident with the given
void updateCoincident(const EntityWrapperPtr& thePoint);
+ /// \brief Verifies the constraint should not be added into the solver
+ ///
+ /// This is a workaround method to avoid some kinds of conflicting constraints:
+ /// * symmetric of two points placed on the mirror line (do not add perpendicular constraint)
+ bool isRedundant(GCSConstraintPtr theCheckedConstraint, ConstraintWrapperPtr theParentConstraint) const;
+
private:
GCS::VEC_pD myParameters; ///< list of parameters
GCS::VEC_pD myConst; ///< list of constants
{
ConstraintConstraintMap::iterator aCIt = theConstraints.begin();
for (; aCIt != theConstraints.end(); ++aCIt) {
- if ((aCIt->second->getType() == CONSTRAINT_MULTI_ROTATION ||
- aCIt->second->getType() == CONSTRAINT_MULTI_TRANSLATION)
+ SketchSolver_ConstraintType aType = aCIt->second->getType();
+ if ((aType == CONSTRAINT_MULTI_ROTATION ||
+ aType == CONSTRAINT_MULTI_TRANSLATION)
&& aCIt->second->isUsed(theFeature))
std::dynamic_pointer_cast<SketchSolver_ConstraintMulti>(aCIt->second)->update(true);
- else if (aCIt->second->getType() == CONSTRAINT_TANGENT_CIRCLE_LINE
+ else if ((aType == CONSTRAINT_TANGENT_CIRCLE_LINE ||
+ aType == CONSTRAINT_SYMMETRIC)
&& aCIt->second->isUsed(theFeature))
aCIt->second->update();
}