+
+ // Obtain fillet point
+ AttributeRefAttrPtr aBaseA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ if(!aBaseA->isInitialized() || aBaseA->isObject()) {
+ return;
+ }
+ AttributePtr anAttrBaseA = aBaseA->attr();
+ std::shared_ptr<GeomDataAPI_Point2D> aBasePoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrBaseA);
+ if (!aBasePoint) {
+ return;
+ }
+ std::shared_ptr<GeomAPI_Pnt2d> aFilletPoint = aBasePoint->pnt();
+
+ // Obtain conicident edges
+ const std::set<AttributePtr>& aRefsList = anAttrBaseA->owner()->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aIt;
+ FeaturePtr aCoincident;
+ for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+ std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+ FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+ if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+ AttributeRefAttrPtr anAttrRefA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));
+ AttributeRefAttrPtr anAttrRefB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
+ if(anAttrRefA.get() && !anAttrRefA->isObject()) {
+ AttributePtr anAttrA = anAttrRefA->attr();
+ if(anAttrBaseA == anAttrA) {
+ aCoincident = aConstrFeature;
+ break;
+ }
+ }
+ if(anAttrRefA.get() && !anAttrRefB->isObject()) {
+ AttributePtr anAttrB = anAttrRefB->attr();
+ if(anAttrBaseA == anAttrB) {
+ aCoincident = aConstrFeature;
+ break;
+ }
+ }
+ }
+ }
+
+ if(!aCoincident.get()) {
+ setError("No coincident edges at selected vertex");
+ return;
+ }
+
+ std::set<FeaturePtr> aCoinsides;
+ SketchPlugin_Tools::findCoincidences(aCoincident,
+ SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+ aCoinsides);
+ SketchPlugin_Tools::findCoincidences(aCoincident,
+ SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+ aCoinsides);
+
+ // Remove points
+ std::set<FeaturePtr> aNewLines;
+ for(std::set<FeaturePtr>::iterator anIt = aCoinsides.begin(); anIt != aCoinsides.end(); ++anIt) {
+ if((*anIt)->getKind() != SketchPlugin_Point::ID()) {
+ aNewLines.insert(*anIt);
+ }
+ }
+ aCoinsides = aNewLines;
+
+ // Remove auxilary lines
+ if(aCoinsides.size() > 2) {
+ aNewLines.clear();
+ for(std::set<FeaturePtr>::iterator anIt = aCoinsides.begin(); anIt != aCoinsides.end(); ++anIt) {
+ if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) {
+ aNewLines.insert(*anIt);
+ }
+ }
+ aCoinsides = aNewLines;
+ }
+
+ if(aCoinsides.size() != 2) {
+ setError("At selected vertex should be two coincident lines");
+ return;
+ }
+
+ // Store base lines
+ FeaturePtr anOldFeatureA, anOldFeatureB;
+ std::set<FeaturePtr>::iterator aLinesIt = aCoinsides.begin();
+ anOldFeatureA = *aLinesIt++;
+ anOldFeatureB = *aLinesIt;
+ aRefListOfBaseLines->append(anOldFeatureA);
+ aRefListOfBaseLines->append(anOldFeatureB);
+
+ // Getting points located at 1/3 of edge length from fillet point
+ std::shared_ptr<GeomAPI_Pnt2d> aPntA, aPntB;
+ getPointOnEdge(anOldFeatureA, aFilletPoint, aPntA);
+ getPointOnEdge(anOldFeatureB, aFilletPoint, aPntB);
+
+ /// Getting distances
+ double aRadius = 1;
+ double aDistanceA = getProjectionDistance(anOldFeatureB, aPntA);
+ double aDistanceB = getProjectionDistance(anOldFeatureA, aPntB);
+ aRadius = aDistanceA < aDistanceB ? aDistanceA / 2.0 : aDistanceB / 2.0;
+
+ std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()))->setValue(aRadius);