-// Copyright (C) 2019-2020 CEA/DEN, EDF R&D
+// Copyright (C) 2019-2023 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
#include <GeomAlgoAPI_EdgeBuilder.h>
+#include <Locale_Convert.h>
+
#include <ModelHighAPI_Double.h>
#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Integer.h>
#include <ModelHighAPI_Selection.h>
#include <ModelHighAPI_Tools.h>
+#include <ModelAPI_Tools.h>
+
#include <SketchPlugin_ConstraintCoincidenceInternal.h>
#include <SketchPlugin_Line.h>
#include <SketchPlugin_Point.h>
}
SketchAPI_BSpline::SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature,
- const std::list<GeomPnt2dPtr>& thePoles,
- const std::list<ModelHighAPI_Double>& theWeights)
+ bool theInitialize)
: SketchAPI_SketchEntity(theFeature)
{
- if (initialize()) {
- setByDegreePolesAndWeights(ModelHighAPI_Integer(-1), thePoles, theWeights);
- }
-}
-
-SketchAPI_BSpline::SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature,
- const int theDegree,
- const std::list<GeomPnt2dPtr>& thePoles,
- const std::list<ModelHighAPI_Double>& theWeights,
- const std::list<ModelHighAPI_Double>& theKnots,
- const std::list<ModelHighAPI_Integer>& theMults)
- : SketchAPI_SketchEntity(theFeature)
-{
- if (initialize()) {
- if (theKnots.empty() || theMults.empty())
- setByDegreePolesAndWeights(theDegree, thePoles, theWeights);
- else
- setByParameters(theDegree, thePoles, theWeights, theKnots, theMults);
- }
-}
-
-SketchAPI_BSpline::SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature,
- const ModelHighAPI_Selection& theExternal)
- : SketchAPI_SketchEntity(theFeature)
-{
- if (initialize()) {
- setByExternal(theExternal);
- }
-}
-
-SketchAPI_BSpline::SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature,
- const std::string& theExternalName)
- : SketchAPI_SketchEntity(theFeature)
-{
- if (initialize()) {
- setByExternalName(theExternalName);
- }
+ if (theInitialize)
+ initialize();
}
SketchAPI_BSpline::~SketchAPI_BSpline()
fillAttribute(theKnots, knots());
fillAttribute(theMults, multiplicities());
- setStartAndEndPoints();
+ if (feature()->getKind() != SketchPlugin_BSplinePeriodic::ID())
+ setStartAndEndPoints();
execute();
}
execute();
}
-void SketchAPI_BSpline::setByExternalName(const std::string & theExternalName)
-{
- fillAttribute(ModelHighAPI_Selection("EDGE", theExternalName), external());
- execute();
-}
-
static CompositeFeaturePtr sketchForFeature(FeaturePtr theFeature)
{
const std::set<AttributePtr>& aRefs = theFeature->data()->refsToMe();
aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
aPointFeature->execute();
- std::ostringstream aName;
- aName << theBSpline->name() << "_" << thePoles->id() << "_" << thePoleIndex;
+ std::wostringstream aName;
+ aName << theBSpline->name() << "_" << Locale::Convert::toWString(thePoles->id())
+ << "_" << thePoleIndex;
aPointFeature->data()->setName(aName.str());
aPointFeature->lastResult()->data()->setName(aName.str());
const bool theAuxiliary,
std::list<FeaturePtr>& theEntities)
{
+ int aEndPoleIndex = (theStartPoleIndex + 1) % thePoles->size();
GeomPnt2dPtr aStartPoint = thePoles->pnt(theStartPoleIndex);
- GeomPnt2dPtr aEndPoint = thePoles->pnt(theStartPoleIndex + 1);
+ GeomPnt2dPtr aEndPoint = thePoles->pnt(aEndPoleIndex);
FeaturePtr aLineFeature = theSketch->addFeature(SketchPlugin_Line::ID());
AttributePoint2DPtr aLineStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
aLineFeature->execute();
- std::ostringstream aName;
- aName << theBSpline->name() << "_segment_" << theStartPoleIndex << "_" << theStartPoleIndex + 1;
+ std::wostringstream aName;
+ aName << theBSpline->name() << "_segment_" << theStartPoleIndex << "_" << aEndPoleIndex;
aLineFeature->data()->setName(aName.str());
aLineFeature->lastResult()->data()->setName(aName.str());
aLineFeature->boolean(SketchPlugin_Line::AUXILIARY_ID())->setValue(theAuxiliary);
createInternalConstraint(theSketch, aLineStart, thePoles, theStartPoleIndex);
- createInternalConstraint(theSketch, aLineEnd, thePoles, theStartPoleIndex + 1);
+ createInternalConstraint(theSketch, aLineEnd, thePoles, aEndPoleIndex);
theEntities.push_back(aLineFeature);
}
it != theWeights.end(); ++it)
aWeights.push_back(it->value());
+ bool isPeriodic = feature()->getKind() == SketchPlugin_BSplinePeriodic::ID();
if (theDegree.intValue() < 0)
- aBSplineCurve.reset(new GeomAPI_BSpline2d(thePoles, aWeights));
- else
- aBSplineCurve.reset(new GeomAPI_BSpline2d(theDegree.intValue(), thePoles, aWeights));
+ aBSplineCurve.reset(new GeomAPI_BSpline2d(thePoles, aWeights, isPeriodic));
+ else {
+ aBSplineCurve.reset(new GeomAPI_BSpline2d(theDegree.intValue(), thePoles, aWeights,
+ std::list<double>(), std::list<int>(), isPeriodic));
+ }
}
catch (...) {
// cannot build a B-spline curve
theDumper << aBase << " = " << aSketchName << ".addSpline(";
if (!isDefaultDegree)
- theDumper << degree() << ", ";
- theDumper << poles();
+ theDumper << "degree = " << degree() << ", ";
+ theDumper << "poles = " << poles();
if (!isDefaultWeights)
- theDumper << ", " << weights();
+ theDumper << ", weights = " << weights();
if (!isDefaultKnotsMults)
- theDumper << ", " << knots() << ", " << multiplicities();
+ theDumper << ", knots = " << knots() << ", multiplicities = " << multiplicities();
+ if (aBase->getKind() == SketchPlugin_BSplinePeriodic::ID())
+ theDumper << ", periodic = True";
theDumper << ")" << std::endl;
}
// dump "auxiliary" flag if necessary
dumpList(theDumper, "auxiliary", anAuxiliary);
theDumper << ")" << std::endl;
}
+
+static void setCoordinates(const FeaturePtr& theFeature,
+ const std::string& theAttrName,
+ const GeomPnt2dPtr& theCoordinates)
+{
+ AttributePoint2DPtr aPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theFeature->attribute(theAttrName));
+ aPoint->setValue(theCoordinates);
+}
+
+bool SketchAPI_BSpline::insertPole(const int theIndex,
+ const GeomPnt2dPtr& theCoordinates,
+ const ModelHighAPI_Double& theWeight)
+{
+ std::ostringstream anActionName;
+ anActionName << SketchPlugin_BSplineBase::ADD_POLE_ACTION_ID() << "#" << theIndex;
+ bool isOk = feature()->customAction(anActionName.str());
+ if (isOk) {
+ int anIndex = theIndex + 1;
+ if (feature()->getKind() == SketchPlugin_BSpline::ID() && anIndex + 1 >= poles()->size())
+ anIndex = poles()->size() - 2;
+ // initialize coordinates and weight of new pole
+ poles()->setPnt(anIndex, theCoordinates);
+ weights()->setValue(anIndex, theWeight.value());
+
+ // update coordinates of points of control polygon
+ std::map<int, FeaturePtr> aPoints, aLines;
+ collectAuxiliaryFeatures(feature(), aPoints, aLines);
+ std::map<int, FeaturePtr>::iterator aFound = aPoints.find(anIndex);
+ if (aFound != aPoints.end())
+ setCoordinates(aFound->second, SketchPlugin_Point::COORD_ID(), theCoordinates);
+ aFound = aLines.find(anIndex);
+ if (aFound != aLines.end())
+ setCoordinates(aFound->second, SketchPlugin_Line::START_ID(), theCoordinates);
+ aFound = aLines.find(anIndex - 1);
+ if (aFound != aLines.end())
+ setCoordinates(aFound->second, SketchPlugin_Line::END_ID(), theCoordinates);
+ }
+ return isOk;
+}
+
+
+
+// =================================================================================================
+SketchAPI_BSplinePeriodic::SketchAPI_BSplinePeriodic(const FeaturePtr& theFeature)
+ : SketchAPI_BSpline(theFeature, false)
+{
+ initialize();
+}