+FeaturePtr SketchPlugin_Split::splitEllipticArc(FeaturePtr& theSplitFeature,
+ FeaturePtr& theBaseFeatureModified,
+ FeaturePtr& theAfterFeature,
+ std::set<AttributePoint2DPtr>& thePoints,
+ std::set<FeaturePtr>& theCreatedFeatures,
+ std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
+{
+ FeaturePtr anNewFeature;
+
+ std::set<FeaturePtr> aCreatedFeatures;
+ FeaturePtr aConstraintFeature;
+ theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature
+
+ AttributeReferencePtr aBaseObjectAttr = reference(SELECTED_OBJECT());
+ FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
+
+ AttributePoint2DPtr aFirstPointAttrOfSplit = getPointAttribute(true);
+ AttributePoint2DPtr aSecondPointAttrOfSplit = getPointAttribute(false);
+ AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
+ SketchPlugin_SegmentationTools::getFeaturePoints(
+ aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
+ if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) {
+ setError("Error: Feature has no start and end points.");
+ return anNewFeature;
+ }
+
+ arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
+ aFirstPointAttrOfSplit, aSecondPointAttrOfSplit);
+#ifdef DEBUG_SPLIT
+ std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
+ std::cout << "Start point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(aStartPointAttrOfBase) << std::endl;
+ std::cout << "1st point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(aFirstPointAttrOfSplit) << std::endl;
+ std::cout << "2nd point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(aSecondPointAttrOfSplit) << std::endl;
+ std::cout << "End point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl;
+#endif
+
+ // split feature
+ theSplitFeature = SketchPlugin_SegmentationTools::createArcFeature(
+ aBaseFeature, aFirstPointAttrOfSplit->pnt(), aSecondPointAttrOfSplit->pnt());
+ theCreatedFeatures.insert(theSplitFeature);
+
+ // before split feature
+ if (aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) {
+ theModifiedAttributes.insert(std::make_pair(aStartPointAttrOfBase,
+ theSplitFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID())));
+ }
+ else {
+ theBaseFeatureModified = aBaseFeature; // use base feature to store all constraints here
+ // move end arc point to start of split
+ }
+
+ // after split feature
+ if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) {
+ FeaturePtr aFeature;
+ if (!theBaseFeatureModified.get()) {
+ aFeature = aBaseFeature; // use base feature to store all constraints here
+ fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), aSecondPointAttrOfSplit);
+ aFeature->execute(); // to update result
+ }
+ else {
+ aFeature = SketchPlugin_SegmentationTools::createArcFeature(
+ aBaseFeature, aSecondPointAttrOfSplit->pnt(), anEndPointAttrOfBase->pnt());
+ theCreatedFeatures.insert(aFeature);
+ theModifiedAttributes.insert(std::make_pair(
+ anEndPointAttrOfBase, aFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID())));
+ anNewFeature = aFeature;
+ }
+ aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(),
+ SketchPlugin_ConstraintCoincidence::ID(),
+ theSplitFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID()),
+ aFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()));
+ theCreatedFeatures.insert(aConstraintFeature);
+
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID())));
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID())));
+
+ if (!theBaseFeatureModified.get())
+ theBaseFeatureModified = aFeature;
+ else
+ theAfterFeature = aFeature;
+ }
+ else {
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theSplitFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID())));
+ theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase,
+ theSplitFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID())));
+ }
+ // base split, that is defined before split feature should be changed at end
+ // (after the after feature creation). Otherwise modified value will be used in after feature
+ // before split feature
+ if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) {
+ // move end arc point to start of split
+ fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::END_POINT_ID()),
+ aFirstPointAttrOfSplit);
+ theBaseFeatureModified->execute(); // to update result
+ aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(),
+ SketchPlugin_ConstraintCoincidence::ID(),
+ theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::END_POINT_ID()),
+ theSplitFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()));
+ theCreatedFeatures.insert(aConstraintFeature);
+
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::START_POINT_ID())));
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::END_POINT_ID())));
+ }
+ else
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theSplitFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID())));
+
+ // additional constraints between split and base features
+#ifdef CREATE_CONSTRAINTS
+ aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(),
+ SketchPlugin_ConstraintEqual::ID(),
+ aBaseFeature->lastResult(),
+ theSplitFeature->lastResult());
+ theCreatedFeatures.insert(aConstraintFeature);
+ aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(),
+ SketchPlugin_ConstraintTangent::ID(),
+ theSplitFeature->lastResult(),
+ aBaseFeature->lastResult());
+ theCreatedFeatures.insert(aConstraintFeature);
+ if (theAfterFeature.get()) {
+ aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(),
+ SketchPlugin_ConstraintEqual::ID(),
+ aBaseFeature->lastResult(),
+ theAfterFeature->lastResult());
+ theCreatedFeatures.insert(aConstraintFeature);
+ aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(),
+ SketchPlugin_ConstraintTangent::ID(),
+ theSplitFeature->lastResult(),
+ theAfterFeature->lastResult());
+ theCreatedFeatures.insert(aConstraintFeature);
+ }
+#endif
+ return anNewFeature;
+}
+
+FeaturePtr SketchPlugin_Split::splitClosed(FeaturePtr& theSplitFeature,