+bool SketcherPrs_PositionMgr::isPntConstraint(const std::string& theName)
+{
+ return ((theName == SketchPlugin_ConstraintTangent::ID()) ||
+ (theName == SketchPlugin_ConstraintPerpendicular::ID()));
+}
+
+bool containsPoint(const FeaturePtr& theFeature, GeomPnt2dPtr thePnt2d, GeomPointPtr thePos)
+{
+ if (theFeature->getKind() == SketchPlugin_Line::ID()) {
+ AttributePoint2DPtr aSPnt1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theFeature->data()->attribute(SketchPlugin_Line::START_ID()));
+ AttributePoint2DPtr aSPnt2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theFeature->data()->attribute(SketchPlugin_Line::END_ID()));
+
+ GeomPnt2dPtr aPnt1 = aSPnt1->pnt();
+ GeomPnt2dPtr aPnt2 = aSPnt2->pnt();
+
+ if (aPnt1->isEqual(thePnt2d) || aPnt2->isEqual(thePnt2d))
+ return true;
+ } else if ((theFeature->getKind() == SketchPlugin_Circle::ID()) ||
+ (theFeature->getKind() == SketchPlugin_Arc::ID())) {
+ GeomCurvePtr aCurve;
+ ObjectPtr aResObj;
+ std::list<ResultPtr> aResults = theFeature->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ for (aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) {
+ GeomShapePtr aShp = SketcherPrs_Tools::getShape((*aIt));
+ if (aShp->isEdge()) {
+ aResObj = (*aIt);
+ aCurve = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShp));
+ break;
+ }
+ }
+ if (aCurve.get()) {
+ double aStart = aCurve->startParam();
+ double aEnd = aCurve->endParam();
+ GeomCirclePtr aCircle = GeomCirclePtr(new GeomAPI_Circ(aCurve));
+ double aParam;
+ if (aCircle->parameter(thePos, 1.e-4, aParam) && (aParam >= aStart) && (aParam <= aEnd))
+ return true;
+ }
+ }
+ return false;
+}
+
+const std::array<int, 2>& SketcherPrs_PositionMgr::getPositionIndex(GeomPointPtr thePos,
+ const SketcherPrs_SymbolPrs* thePrs)
+{
+ if (myPntShapes.count(thePrs->feature()) == 0) {
+ // Renumerate positions around the specified constraint point for all constraints
+ GeomAx3Ptr aAx3 = thePrs->plane();
+ ModelAPI_CompositeFeature* aOwner = thePrs->sketcher();
+ GeomPnt2dPtr aPnt2d = thePos->to2D(aAx3->origin(), aAx3->dirX(), aAx3->dirY());
+
+ int aNbSubs = aOwner->numberOfSubs();
+ int aId = 0;
+ std::list<const ModelAPI_Feature*> aFeaList;
+ for (int i = 0; i < aNbSubs; i++) {
+ FeaturePtr aFeature = aOwner->subFeature(i);
+
+ bool aUseFeature = ((myPntShapes.count(aFeature.get()) == 1) ||
+ (isPntConstraint(aFeature->getKind())));
+ if (aUseFeature) {
+ DataPtr aData = aFeature->data();
+ AttributeRefAttrPtr aObjRef = aData->refattr(SketchPlugin_Constraint::ENTITY_A());
+ FeaturePtr aObj;
+ if (aObjRef)
+ aObj = ModelAPI_Feature::feature(aObjRef->object());
+ bool aContains = false;
+ if (aObj && containsPoint(aObj, aPnt2d, thePos)) {
+ aContains = true;
+ } else {
+ aObjRef = aData->refattr(SketchPlugin_Constraint::ENTITY_B());
+ if (aObjRef)
+ aObj = ModelAPI_Feature::feature(aObjRef->object());
+ if (aObj && containsPoint(aObj, aPnt2d, thePos)) {
+ aContains = true;
+ }
+ }
+ if (aContains) {
+ myPntShapes[aFeature.get()][0] = aId;
+ aId++;
+ aFeaList.push_back(aFeature.get());
+ }
+ }
+ }
+ int aSize = (int) aFeaList.size();
+ std::list<const ModelAPI_Feature*>::const_iterator aIt;
+ for (aIt = aFeaList.cbegin(); aIt != aFeaList.cend(); aIt++) {
+ myPntShapes[*aIt][1] = aSize;
+ }
+ }
+ return myPntShapes[thePrs->feature()];
+}
+
+//*****************************************************************