X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintTangent.cpp;h=ab4a27ea793b8e15da0c0dbd54cbaefa7086f07c;hb=2982303b80faa9bed2a7715d2778fd10d8cd0465;hp=299ed53fa94356949d8cf004d6be036f5f7f79f8;hpb=a32720fe5e394f888c203b268a6325cb216f87b7;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintTangent.cpp b/src/SketchSolver/SketchSolver_ConstraintTangent.cpp index 299ed53fa..ab4a27ea7 100644 --- a/src/SketchSolver/SketchSolver_ConstraintTangent.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintTangent.cpp @@ -1,46 +1,42 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + #include #include -#include + +#include #include #include +#include #include -/// \brief Check whether the entities has only one shared point -static bool hasSingleCoincidence(EntityWrapperPtr theEntity1, EntityWrapperPtr theEntity2) +/// \brief Check whether the entities has only one shared point or less +static bool hasSingleCoincidence(FeaturePtr theFeature1, FeaturePtr theFeature2) { - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); - - const std::list& aPoints1 = theEntity1->subEntities(); - const std::list& aPoints2 = theEntity2->subEntities(); - - std::list::const_iterator aStartIt1 = aPoints1.begin(); - if (theEntity1->type() == ENTITY_ARC) ++aStartIt1; // skip center of arc - std::list::const_iterator aStartIt2 = aPoints2.begin(); - if (theEntity2->type() == ENTITY_ARC) ++aStartIt2; // skip center of arc - - int aNbCoinc = 0; - std::list::const_iterator anIt1, anIt2; - for (anIt1 = aStartIt1; anIt1 != aPoints1.end(); ++anIt1) { - if ((*anIt1)->type() != ENTITY_POINT) - continue; - std::shared_ptr aPt1 = aBuilder->point(*anIt1); - for (anIt2 = aStartIt2; anIt2 != aPoints2.end(); ++anIt2) { - if ((*anIt2)->type() != ENTITY_POINT) - continue; - std::shared_ptr aPt2 = aBuilder->point(*anIt2); - if (aPt1->distance(aPt2) < tolerance) - ++aNbCoinc; - } + const std::set& aRefs1 = theFeature1->data()->refsToMe(); + const std::set& aRefs2 = theFeature2->data()->refsToMe(); + + // collect all shared coincidendes + std::set aCoincidences; + std::set::const_iterator anIt; + for (anIt = aRefs1.begin(); anIt != aRefs1.end(); ++anIt) { + FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner()); + if (aRef && aRef->getKind() == SketchPlugin_ConstraintCoincidence::ID()) + aCoincidences.insert(aRef); + } + for (anIt = aRefs2.begin(); anIt != aRefs2.end(); ++anIt) { + FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner()); + if (aRef) + aCoincidences.erase(aRef); } - return aNbCoinc == 1; -} + return aCoincidences.size() <= 1; +} void SketchSolver_ConstraintTangent::getAttributes( - double& theValue, + EntityWrapperPtr& theValue, std::vector& theAttributes) { SketchSolver_Constraint::getAttributes(theValue, theAttributes); @@ -78,16 +74,25 @@ void SketchSolver_ConstraintTangent::getAttributes( else if (aNbCircles == 1) myType = CONSTRAINT_TANGENT_CIRCLE_LINE; } - else if (aNbArcs == 2) + else if (aNbArcs == 2) { myType = CONSTRAINT_TANGENT_ARC_ARC; + isArcArcInternal = + PlaneGCSSolver_Tools::isArcArcTangencyInternal(theAttributes[2], theAttributes[3]); + } else { myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); return; } - if (myType == CONSTRAINT_TANGENT_ARC_LINE && - !hasSingleCoincidence(theAttributes[2], theAttributes[3])) - myErrorMsg = SketchSolver_Error::TANGENCY_FAILED(); + if (myType == CONSTRAINT_TANGENT_ARC_LINE) { + AttributeRefAttrPtr aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A()); + FeaturePtr aFeature1 = ModelAPI_Feature::feature(aRefAttr->object()); + aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_B()); + FeaturePtr aFeature2 = ModelAPI_Feature::feature(aRefAttr->object()); + + if (!hasSingleCoincidence(aFeature1, aFeature2)) + myErrorMsg = SketchSolver_Error::TANGENCY_FAILED(); + } if (isSwap) { EntityWrapperPtr aTemp = theAttributes[2]; @@ -98,24 +103,16 @@ void SketchSolver_ConstraintTangent::getAttributes( void SketchSolver_ConstraintTangent::adjustConstraint() { - if (myType != CONSTRAINT_TANGENT_CIRCLE_LINE) - return; - - ConstraintWrapperPtr aConstraint = myStorage->constraint(myBaseConstraint).front(); - AttributePtr aCircleCenter = aConstraint->entities().front()->baseAttribute(); - if (!aCircleCenter) - return; - FeaturePtr aCircle = ModelAPI_Feature::feature(aCircleCenter->owner()); - AttributeDoublePtr aRadius = std::dynamic_pointer_cast( - aCircle->attribute(SketchPlugin_Circle::RADIUS_ID())); - - if (fabs(aRadius->value()) == fabs(aConstraint->value())) - return; - - aConstraint->setValue(aRadius->value()); - - // Adjust the sign of constraint value - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); - aBuilder->adjustConstraint(aConstraint); - myStorage->addConstraint(myBaseConstraint, aConstraint); + if (myType == CONSTRAINT_TANGENT_ARC_ARC) { + EntityWrapperPtr anEntity1 = + myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); + EntityWrapperPtr anEntity2 = + myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); + + if (isArcArcInternal != PlaneGCSSolver_Tools::isArcArcTangencyInternal(anEntity1, anEntity2)) { + // fully rebuld constraint, because it is unable to access attributes of PlaneGCS constraint + remove(); + process(); + } + } }