1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 #include <SketchSolver_ConstraintTangent.h>
4 #include <SketchSolver_Error.h>
6 #include <PlaneGCSSolver_Tools.h>
8 #include <GeomAPI_Pnt2d.h>
9 #include <SketchPlugin_Circle.h>
10 #include <SketchPlugin_ConstraintCoincidence.h>
15 /// \brief Check whether the entities has only one shared point or less
16 static bool hasSingleCoincidence(FeaturePtr theFeature1, FeaturePtr theFeature2)
18 const std::set<AttributePtr>& aRefs1 = theFeature1->data()->refsToMe();
19 const std::set<AttributePtr>& aRefs2 = theFeature2->data()->refsToMe();
21 // collect all shared coincidendes
22 std::set<FeaturePtr> aCoincidences;
23 std::set<AttributePtr>::const_iterator anIt;
24 for (anIt = aRefs1.begin(); anIt != aRefs1.end(); ++anIt) {
25 FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
26 if (aRef && aRef->getKind() == SketchPlugin_ConstraintCoincidence::ID())
27 aCoincidences.insert(aRef);
29 int aNbCoinCidentPoints = 0;
30 for (anIt = aRefs2.begin(); anIt != aRefs2.end(); ++anIt) {
31 FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
32 if (aCoincidences.find(aRef) != aCoincidences.end())
33 ++aNbCoinCidentPoints;
36 return aNbCoinCidentPoints <= 1;
39 void SketchSolver_ConstraintTangent::getAttributes(
40 EntityWrapperPtr& theValue,
41 std::vector<EntityWrapperPtr>& theAttributes)
43 SketchSolver_Constraint::getAttributes(theValue, theAttributes);
44 if (!myErrorMsg.empty() || !theAttributes[2] || !theAttributes[3]) {
45 theAttributes.clear();
49 // Check the quantity of entities of each type and their order (arcs first)
52 std::vector<EntityWrapperPtr>::iterator anEntIt = theAttributes.begin() + 2;
53 for (; anEntIt != theAttributes.end(); ++anEntIt) {
54 if ((*anEntIt)->type() == ENTITY_LINE)
56 else if ((*anEntIt)->type() == ENTITY_ARC || (*anEntIt)->type() == ENTITY_CIRCLE)
61 myErrorMsg = SketchSolver_Error::INCORRECT_TANGENCY_ATTRIBUTE();
64 if (aNbLines == 1 && aNbCircles == 1) {
65 myType = CONSTRAINT_TANGENT_CIRCLE_LINE;
67 else if (aNbCircles == 2) {
68 myType = CONSTRAINT_TANGENT_CIRCLE_CIRCLE;
70 PlaneGCSSolver_Tools::isArcArcTangencyInternal(theAttributes[2], theAttributes[3]);
73 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
77 if (myType == CONSTRAINT_TANGENT_CIRCLE_LINE) {
78 AttributeRefAttrPtr aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
79 FeaturePtr aFeature1 = ModelAPI_Feature::feature(aRefAttr->object());
80 aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
81 FeaturePtr aFeature2 = ModelAPI_Feature::feature(aRefAttr->object());
83 if (!hasSingleCoincidence(aFeature1, aFeature2))
84 myErrorMsg = SketchSolver_Error::TANGENCY_FAILED();
88 void SketchSolver_ConstraintTangent::adjustConstraint()
90 if (myType == CONSTRAINT_TANGENT_CIRCLE_CIRCLE) {
91 EntityWrapperPtr anEntity1 =
92 myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
93 EntityWrapperPtr anEntity2 =
94 myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
96 if (isArcArcInternal != PlaneGCSSolver_Tools::isArcArcTangencyInternal(anEntity1, anEntity2)) {
97 // fully rebuld constraint, because it is unable to access attributes of PlaneGCS constraint