+
+ bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+
+ // add new pole and default weight
+ std::list<GeomPnt2dPtr> aPoles;
+ aPolesArray->setSize(aPolesArray->size() + 1);
+ aPolesArray->setPnt(aPolesArray->size() - 1, aPolesArray->pnt(0)); // for periodic spline
+ for (int i = aPolesArray->size() - 2; i > anAfter; --i) {
+ aPoles.push_front(aPolesArray->pnt(i));
+ aPolesArray->setPnt(i + 1, aPoles.front());
+ }
+
+ GeomPnt2dPtr aCurPole = aPolesArray->pnt(anAfter);
+ GeomPnt2dPtr aNextPole = aPolesArray->pnt(anAfter + 1);
+ aPolesArray->setPnt(anAfter + 1, (aCurPole->x() + aNextPole->x()) * 0.5,
+ (aCurPole->y() + aNextPole->y()) * 0.5);
+ for (int i = anAfter + 1; i >= 0; --i)
+ aPoles.push_front(aPolesArray->pnt(i));
+
+ std::list<double> aWeights;
+ for (int i = 0; i < aWeightsArray->size(); ++i) {
+ aWeights.push_back(aWeightsArray->value(i));
+ if (i == anAfter)
+ aWeights.push_back(1.0); // default weight
+ }
+ aWeightsArray->setSize(aWeightsArray->size() + 1);
+ std::list<double>::iterator aWIt = aWeights.begin();
+ for (int i = 0; i < aWeightsArray->size(); ++i, ++aWIt)
+ aWeightsArray->setValue(i, *aWIt);
+
+ // recalculate knots and multiplicities
+ std::shared_ptr<GeomAPI_BSpline2d> aBSplineCurve(
+ new GeomAPI_BSpline2d(aPoles, aWeights, isPeriodic()));
+
+ integer(DEGREE_ID())->setValue(aBSplineCurve->degree());
+
+ AttributeDoubleArrayPtr aKnotsAttr = data()->realArray(SketchPlugin_BSplineBase::KNOTS_ID());
+ std::list<double> aKnots = aBSplineCurve->knots();
+ int aSize = (int)aKnots.size();
+ aKnotsAttr->setSize(aSize);
+ std::list<double>::iterator aKIt = aKnots.begin();
+ for (int index = 0; index < aSize; ++index, ++aKIt)
+ aKnotsAttr->setValue(index, *aKIt);
+
+ AttributeIntArrayPtr aMultsAttr = data()->intArray(SketchPlugin_BSplineBase::MULTS_ID());
+ std::list<int> aMults = aBSplineCurve->mults();
+ aSize = (int)aMults.size();
+ aMultsAttr->setSize(aSize);
+ std::list<int>::iterator aMIt = aMults.begin();
+ for (int index = 0; index < aSize; ++index, ++aMIt)
+ aMultsAttr->setValue(index, *aMIt);
+
+ data()->blockSendAttributeUpdated(aWasBlocked, true);
+
+ // update indices of internal coincidences
+ for (std::list<AttributeIntegerPtr>::iterator aCIt = aCoincidentPoleIndex.begin();
+ aCIt != aCoincidentPoleIndex.end(); ++aCIt)
+ (*aCIt)->setValue((*aCIt)->value() + 1);
+
+ // create auxiliary segment and pole updating the control polygon
+ SketchPlugin_MacroBSpline::createAuxiliaryPole(aPolesArray, anAfter + 1);
+ if (hasAuxSegment)
+ SketchPlugin_MacroBSpline::createAuxiliarySegment(aPolesArray, anAfter, anAfter + 1);
+
+ // update names of features representing control polygon
+ for (std::map<int, FeaturePtr>::iterator anIt = aControlPoles.begin();
+ anIt != aControlPoles.end(); ++anIt) {
+ SketchPlugin_MacroBSpline::assignDefaultNameForAux(anIt->second, aPolesArray, anIt->first + 1);
+ }
+ for (std::map<int, FeaturePtr>::iterator anIt = aControlSegments.begin();
+ anIt != aControlSegments.end(); ++anIt) {
+ SketchPlugin_MacroBSpline::assignDefaultNameForAux(anIt->second, aPolesArray,
+ anIt->first + 1, (anIt->first + 2) % aPolesArray->size());
+ }
+
+ return true;