- aRefAttr->setObject(aFeature[i]->lastResult());
- myProducedFeatures.push_back(aConstraint);
- }
- // make base features auxiliary
- anOldFeatureA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true);
- anOldFeatureB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true);
- myBaseObjects.clear();
- myBaseObjects.push_back(anOldFeatureA);
- myBaseObjects.push_back(anOldFeatureB);
- // exchange the naming IDs of newly created and old line that become auxiliary
- sketch()->exchangeIDs(anOldFeatureA, aNewFeatureA);
- sketch()->exchangeIDs(anOldFeatureB, aNewFeatureB);
- } else {
- // Update radius value
- int aNbSubs = sketch()->numberOfSubs();
- FeaturePtr aSubFeature;
- for (int aSub = 0; aSub < aNbSubs; aSub++) {
- aSubFeature = sketch()->subFeature(aSub);
- if (aSubFeature->getKind() != SketchPlugin_ConstraintRadius::ID())
- continue;
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aSubFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
- if (!aRefAttr || !aRefAttr->isObject())
- continue;
- FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
- if (aFeature == aNewArc) {
- AttributeDoublePtr aRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
- aSubFeature->attribute(SketchPlugin_Constraint::VALUE()));
- aRadius->setValue(aFilletRadius);
- break;
+ aFeatInd = isReversed ? 0 : 1;
+ anAttrInd = (isReversed ? 0 : 2) + (isStart[isReversed ? 0 : 1] ? 0 : 1);
+ aRefAttr->setAttr(aResultFeatures[aFeatInd]->attribute(aFeatAttributes[anAttrInd]));
+ recalculateAttributes(aResultArc, SketchPlugin_Arc::END_ID(), aResultFeatures[aFeatInd], aFeatAttributes[anAttrInd]);
+ aConstraint->execute();
+ aFilletFeatures.resultConstraints.push_back(aConstraint);
+ ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
+ // 2. Fillet arc radius
+ //aConstraint = sketch()->addFeature(SketchPlugin_ConstraintRadius::ID());
+ //aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ // aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ //aRefAttr->setObject(aNewArc->lastResult());
+ //std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+ // aConstraint->attribute(SketchPlugin_Constraint::VALUE()))->setValue(aFilletRadius);
+ //std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ // aConstraint->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()))->setValue(
+ // isStart[0] ? aStartEndPnt[0] : aStartEndPnt[1]);
+ //aConstraint->execute();
+ //myProducedFeatures.push_back(aConstraint);
+ //ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
+ // 3. Tangency of fillet arc and features
+ for (int i = 0; i < aNbFeatures; i++) {
+ aConstraint = sketch()->addFeature(SketchPlugin_ConstraintTangent::ID());
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ aRefAttr->setObject(aResultArc->lastResult());
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ bool isArc = aResultFeatures[i]->getKind() == SketchPlugin_Arc::ID();
+ aRefAttr->setObject(isArc ? aResultFeatures[i]->lastResult() : aResultFeatures[i]->firstResult());
+ aConstraint->execute();
+ aFilletFeatures.resultConstraints.push_back(aConstraint);
+ ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
+ }
+ // 4. Coincidence of free boundaries of base and copied features
+ for (int i = 0; i < aNbFeatures; i++) {
+ anAttrInd = 2*i + (isStart[i] ? 1 : 0);
+ aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ aRefAttr->setAttr(aBaseFeatures[i]->attribute(aFeatAttributes[anAttrInd]));
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ aRefAttr->setAttr(aResultFeatures[i]->attribute(aFeatAttributes[anAttrInd]));
+ aFilletFeatures.resultConstraints.push_back(aConstraint);
+ }
+ // 4.1. Additional tangency constraints when the fillet is based on arcs.
+ // It is used to verify the created arc will be placed on a source.
+ for (int i = 0; i < aNbFeatures; ++i) {
+ if (aResultFeatures[i]->getKind() != SketchPlugin_Arc::ID())
+ continue;
+ aConstraint = sketch()->addFeature(SketchPlugin_ConstraintTangent::ID());
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ aRefAttr->setObject(aBaseFeatures[i]->lastResult());
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ aRefAttr->setObject(aResultFeatures[i]->lastResult());
+ aConstraint->execute();
+ aFilletFeatures.resultConstraints.push_back(aConstraint);
+ ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
+ }
+ // 5. Tangent points should be placed on the base features
+ for (int i = 0; i < aNbFeatures; i++) {
+ anAttrInd = 2*i + (isStart[i] ? 0 : 1);
+ aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ aRefAttr->setAttr(aResultFeatures[i]->attribute(aFeatAttributes[anAttrInd]));
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ aRefAttr->setObject(aBaseFeatures[i]->lastResult());
+ aFilletFeatures.resultConstraints.push_back(aConstraint);
+ }
+ // make base features auxiliary
+ aBaseEdgeA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true);
+ aBaseEdgeB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true);
+
+ // exchange the naming IDs of newly created and old line that become auxiliary
+ sketch()->exchangeIDs(aBaseEdgeA, aResultEdgeA);
+ sketch()->exchangeIDs(aBaseEdgeB, aResultEdgeB);
+
+ // store point and features in the map.
+ myPointFeaturesMap[aPointAttr] = aFilletFeatures;
+ } else {
+ // Update radius value
+ int aNbSubs = sketch()->numberOfSubs();
+ FeaturePtr aSubFeature;
+ for (int aSub = 0; aSub < aNbSubs; aSub++) {
+ aSubFeature = sketch()->subFeature(aSub);
+ if (aSubFeature->getKind() != SketchPlugin_ConstraintRadius::ID())
+ continue;
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aSubFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ if (!aRefAttr || !aRefAttr->isObject())
+ continue;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+ if (aFeature == aResultArc) {
+ AttributeDoublePtr aRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+ aSubFeature->attribute(SketchPlugin_Constraint::VALUE()));
+ aRadius->setValue(aFilletRadius);
+ break;
+ }