- // Obtain constraint coincidence for the fillet point.
- FeaturePtr aConstraintCoincidence;
- const std::set<AttributePtr>& aRefsList = theFilletPoint->owner()->data()->refsToMe();
- for(std::set<AttributePtr>::const_iterator anIt = aRefsList.cbegin();
- anIt != aRefsList.cend();
- ++anIt) {
- std::shared_ptr<ModelAPI_Attribute> anAttr = (*anIt);
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anAttr->owner());
- if(aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
- AttributeRefAttrPtr anAttrRefA =
- aFeature->refattr(SketchPlugin_ConstraintCoincidence::ENTITY_A());
- AttributeRefAttrPtr anAttrRefB =
- aFeature->refattr(SketchPlugin_ConstraintCoincidence::ENTITY_B());
- if(anAttrRefA.get() && !anAttrRefA->isObject()) {
- AttributePtr anAttrA = anAttrRefA->attr();
- if(theFilletPoint == anAttrA) {
- aConstraintCoincidence = aFeature;
- break;
+ // Calculate Fillet parameters if does not yet
+ if (!myBaseFeatures[0] || !myBaseFeatures[1])
+ calculateFilletParameters();
+
+ // fix for issue #2810 (sometimes, myCenterXY is NULL, fillet should report an error)
+ if (!myCenterXY)
+ return FeaturePtr();
+
+ // Create arc feature.
+ FeaturePtr aFilletArc = sketch()->addFeature(SketchPlugin_Arc::ID());
+
+ // Set arc attributes.
+ bool aWasBlocked = aFilletArc->data()->blockSendAttributeUpdated(true);
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aFilletArc->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(myCenterXY->x(),
+ myCenterXY->y());
+ std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aFilletArc->attribute(SketchPlugin_Arc::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aFilletArc->attribute(SketchPlugin_Arc::END_ID()));
+ if(aStartPoint->isInitialized() && aEndPoint->isInitialized()
+ && (aStartPoint->pnt()->xy()->distance(myTangentXY1) > tolerance
+ || aEndPoint->pnt()->xy()->distance(myTangentXY2) > tolerance)) {
+ std::dynamic_pointer_cast<SketchPlugin_Arc>(aFilletArc)->setReversed(false);
+ }
+ aStartPoint->setValue(myTangentXY1->x(), myTangentXY1->y());
+ aEndPoint->setValue(myTangentXY2->x(), myTangentXY2->y());
+ aFilletArc->data()->blockSendAttributeUpdated(aWasBlocked);
+ aFilletArc->execute();
+
+ return aFilletArc;
+}
+
+FeaturePtr SketchPlugin_Fillet::createFilletApex(const GeomPnt2dPtr& theCoordinates)
+{
+ FeaturePtr anApex = sketch()->addFeature(SketchPlugin_Point::ID());
+ AttributePoint2DPtr aCoord = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ anApex->attribute(SketchPlugin_Point::COORD_ID()));
+ aCoord->setValue(theCoordinates);
+ anApex->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
+
+ // additional coincidence constraints
+ static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+ FeaturePtr aConstraint;
+ for (int i = 0; i < 2; i++) {
+ aConstraint = SketchPlugin_Tools::createConstraintAttrObject(sketch(),
+ SketchPlugin_ConstraintCoincidence::ID(),
+ aCoord,
+ myBaseFeatures[i]->lastResult());
+ aConstraint->execute();
+ ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
+ }
+
+ return anApex;
+}
+
+struct Length {
+ AttributePtr myPoints[2];
+ std::string myValueText;
+ double myValueDouble;
+ GeomPnt2dPtr myFlyoutPoint;
+ int myLocationType;
+};
+
+void SketchPlugin_Fillet::removeReferencesButKeepDistances(
+ std::set<FeaturePtr>& theFeaturesToRemove,
+ const AttributePoint2DPtr theFilletPoints[2])
+{
+ FeaturePtr aFilletApex;
+ std::list<Length> aLengthToDistance;
+
+ std::set<FeaturePtr>::iterator aFeat = theFeaturesToRemove.begin();
+ while (aFeat != theFeaturesToRemove.end()) {
+ std::shared_ptr<SketchPlugin_ConstraintDistance> aDistance =
+ std::dynamic_pointer_cast<SketchPlugin_ConstraintDistance>(*aFeat);
+ if (aDistance) {
+ if (!aFilletApex)
+ aFilletApex = createFilletApex(theFilletPoints[0]->pnt());
+ // update attributes of distance constraints
+ bool isUpdated = false;
+ for (int attrInd = 0; attrInd < CONSTRAINT_ATTR_SIZE && !isUpdated; ++attrInd) {
+ AttributeRefAttrPtr aRefAttr =
+ aDistance->refattr(SketchPlugin_Constraint::ATTRIBUTE(attrInd));
+ if (aRefAttr && !aRefAttr->isObject() &&
+ (aRefAttr->attr() == theFilletPoints[0] || aRefAttr->attr() == theFilletPoints[1])) {
+ aRefAttr->setAttr(aFilletApex->attribute(SketchPlugin_Point::COORD_ID()));
+ isUpdated = true;