#include <SketchPlugin_MacroBSpline.h>
#include <SketchPlugin_BSpline.h>
+#include <SketchPlugin_BSplinePeriodic.h>
#include <SketchPlugin_ConstraintCoincidenceInternal.h>
#include <SketchPlugin_Line.h>
#include <SketchPlugin_Point.h>
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeRefAttrList.h>
#include <ModelAPI_Events.h>
-#include <ModelAPI_EventReentrantMessage.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
#include <sstream>
-// Create Point feature coincident with the B-spline pole
-static FeaturePtr createAuxiliaryPole(FeaturePtr theBSpline,
- AttributePoint2DArrayPtr theBSplinePoles,
- const int thePoleIndex);
-// Create segment between consequtive B-spline poles
-static void createAuxiliarySegment(FeaturePtr theBSpline,
- AttributePoint2DArrayPtr theBSplinePoles,
- const int thePoleIndex1,
- const int thePoleIndex2);
-// Create internal coincidence constraint with B-spline pole
+/// Create internal coincidence constraint with B-spline pole
static void createInternalConstraint(SketchPlugin_Sketch* theSketch,
AttributePtr thePoint,
AttributePtr theBSplinePoles,
{
}
+SketchPlugin_MacroBSpline::SketchPlugin_MacroBSpline(bool isPeriodic)
+ : SketchPlugin_SketchEntity(),
+ myDegree(3),
+ myIsPeriodic(isPeriodic)
+{
+}
+
void SketchPlugin_MacroBSpline::initAttributes()
{
data()->addAttribute(POLES_ID(), GeomDataAPI_Point2DArray::typeId());
std::list<FeaturePtr> aControlPoles;
createControlPolygon(aBSpline, aControlPoles);
constraintsForPoles(aControlPoles);
-
- // message to init reentrant operation
- static Events_ID anId = ModelAPI_EventReentrantMessage::eventId();
- ReentrantMessagePtr aMessage(new ModelAPI_EventReentrantMessage(anId, this));
- // set here the last pole to make coincidence with the start point of the next B-spline curve
- aMessage->setCreatedFeature(aControlPoles.back());
- Events_Loop::loop()->send(aMessage);
- }
-}
-
-// LCOV_EXCL_START
-std::string SketchPlugin_MacroBSpline::processEvent(
- const std::shared_ptr<Events_Message>& theMessage)
-{
- ReentrantMessagePtr aReentrantMessage =
- std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
- if (aReentrantMessage) {
- FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
- ObjectPtr anObject = aReentrantMessage->selectedObject();
- AttributePtr anAttribute = aReentrantMessage->selectedAttribute();
- std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = aReentrantMessage->clickedPoint();
-
- if (aClickedPoint) {
- // fill points list (it consists of 2 points to make editable the second one)
- AttributePoint2DArrayPtr aPointArrayAttr =
- std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
- aPointArrayAttr->setSize(2);
- aPointArrayAttr->setPnt(0, aClickedPoint);
- aPointArrayAttr->setPnt(1, aClickedPoint);
-
- // fill weights
- AttributeDoubleArrayPtr aWeightsArrayAttr = data()->realArray(WEIGHTS_ID());
- aWeightsArrayAttr->setSize(2);
- aWeightsArrayAttr->setValue(0, 1.0);
- aWeightsArrayAttr->setValue(1, 1.0);
-
- // fill reference attribute
- AttributeRefAttrListPtr aRefAttrList =
- std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(attribute(REF_POLES_ID()));
- if (anAttribute) {
- if (!anAttribute->owner() || !anAttribute->owner()->data()->isValid()) {
- if (aCreatedFeature && anAttribute->id() == SketchPlugin_Point::COORD_ID())
- anAttribute = aCreatedFeature->attribute(SketchPlugin_Point::COORD_ID());
- }
- aRefAttrList->append(anAttribute);
- }
- }
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
}
- return std::string();
}
-// LCOV_EXCL_STOP
FeaturePtr SketchPlugin_MacroBSpline::createBSplineFeature()
{
- FeaturePtr aBSpline = sketch()->addFeature(SketchPlugin_BSpline::ID());
+ if (myKnots.empty() || myMultiplicities.empty())
+ getAISObject(AISObjectPtr()); // fill B-spline parameters
+
+ FeaturePtr aBSpline = sketch()->addFeature(
+ myIsPeriodic ? SketchPlugin_BSplinePeriodic::ID() : SketchPlugin_BSpline::ID());
- aBSpline->integer(SketchPlugin_BSpline::DEGREE_ID())->setValue(myDegree);
+ aBSpline->integer(SketchPlugin_BSplineBase::DEGREE_ID())->setValue(myDegree);
AttributePoint2DArrayPtr aPoles = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
- aBSpline->attribute(SketchPlugin_BSpline::POLES_ID()));
+ aBSpline->attribute(SketchPlugin_BSplineBase::POLES_ID()));
AttributePoint2DArrayPtr aPolesMacro =
std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
aPoles->assign(aPolesMacro);
AttributeDoubleArrayPtr aWeights =
- aBSpline->data()->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
+ aBSpline->data()->realArray(SketchPlugin_BSplineBase::WEIGHTS_ID());
AttributeDoubleArrayPtr aWeightsMacro = data()->realArray(WEIGHTS_ID());
int aSize = aWeightsMacro->size();
aWeights->setSize(aSize);
aWeights->setValue(index, aWeightsMacro->value(index));
AttributeDoubleArrayPtr aKnots =
- aBSpline->data()->realArray(SketchPlugin_BSpline::KNOTS_ID());
+ aBSpline->data()->realArray(SketchPlugin_BSplineBase::KNOTS_ID());
aSize = (int)myKnots.size();
aKnots->setSize(aSize);
std::list<double>::iterator aKIt = myKnots.begin();
for (int index = 0; index < aSize; ++index, ++aKIt)
aKnots->setValue(index, *aKIt);
- AttributeIntArrayPtr aMults =
- aBSpline->data()->intArray(SketchPlugin_BSpline::MULTS_ID());
+ AttributeIntArrayPtr aMults = aBSpline->data()->intArray(SketchPlugin_BSplineBase::MULTS_ID());
aSize = (int)myMultiplicities.size();
aMults->setSize(aSize);
std::list<int>::iterator aMIt = myMultiplicities.begin();
for (int index = 0; index < aSize; ++index, ++aMIt)
aMults->setValue(index, *aMIt);
- SketchPlugin_Sketch* aSketch =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aBSpline)->sketch();
+ if (!myIsPeriodic) {
+ AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aBSpline->attribute(SketchPlugin_BSpline::START_ID()));
+ aStartPoint->setValue(aPoles->pnt(0));
- AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aBSpline->attribute(SketchPlugin_BSpline::START_ID()));
- aStartPoint->setValue(aPoles->pnt(0));
-
- AttributePoint2DPtr aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aBSpline->attribute(SketchPlugin_BSpline::END_ID()));
- aEndPoint->setValue(aPoles->pnt(aPoles->size() - 1));
+ AttributePoint2DPtr aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aBSpline->attribute(SketchPlugin_BSpline::END_ID()));
+ aEndPoint->setValue(aPoles->pnt(aPoles->size() - 1));
+ }
- aBSpline->boolean(SketchPlugin_BSpline::AUXILIARY_ID())->setValue(
+ aBSpline->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(
boolean(AUXILIARY_ID())->value());
aBSpline->execute();
int aSize = aPoles->size();
// poles
for (int index = 0; index < aSize; ++index)
- thePoles.push_back(createAuxiliaryPole(theBSpline, aPoles, index));
+ thePoles.push_back(createAuxiliaryPole(aPoles, index));
// segments
for (int index = 1; index < aSize; ++index)
- createAuxiliarySegment(theBSpline, aPoles, index - 1, index);
+ createAuxiliarySegment(aPoles, index - 1, index);
+ if (myIsPeriodic) {
+ // additional segment to close the control polygon
+ createAuxiliarySegment(aPoles, aSize - 1, 0);
+ }
}
void SketchPlugin_MacroBSpline::constraintsForPoles(const std::list<FeaturePtr>& thePoles)
if (!aSketch)
return AISObjectPtr();
- static const bool PERIODIC = false;
-
AttributePoint2DArrayPtr aPolesArray =
std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
AttributeDoubleArrayPtr aWeightsArray = data()->realArray(WEIGHTS_ID());
// create result non-periodic B-spline curve
std::shared_ptr<GeomAPI_BSpline2d> aBSplineCurve;
try {
- aBSplineCurve.reset(new GeomAPI_BSpline2d(aPoles2D, aWeights, PERIODIC));
+ aBSplineCurve.reset(new GeomAPI_BSpline2d(aPoles2D, aWeights, myIsPeriodic));
} catch (...) {
// cannot build a B-spline curve
return AISObjectPtr();
// ========================== Auxiliary functions ===========================================
-FeaturePtr createAuxiliaryPole(FeaturePtr theBSpline,
- AttributePoint2DArrayPtr theBSplinePoles,
- const int thePoleIndex)
+void SketchPlugin_MacroBSpline::assignDefaultNameForAux(FeaturePtr theAuxFeature,
+ AttributePoint2DArrayPtr theBSplinePoles,
+ const int thePoleIndex1,
+ const int thePoleIndex2)
+{
+ FeaturePtr aBSpline = ModelAPI_Feature::feature(theBSplinePoles->owner());
+
+ std::ostringstream aName;
+ aName << aBSpline->name();
+ if (theAuxFeature->getKind() == SketchPlugin_Point::ID())
+ aName << "_" << theBSplinePoles->id() << "_" << thePoleIndex1;
+ else
+ aName << "_segment_" << thePoleIndex1 << "_" << thePoleIndex2;
+
+ theAuxFeature->data()->setName(aName.str());
+ theAuxFeature->lastResult()->data()->setName(aName.str());
+}
+
+FeaturePtr SketchPlugin_MacroBSpline::createAuxiliaryPole(AttributePoint2DArrayPtr theBSplinePoles,
+ const int thePoleIndex)
{
+ FeaturePtr aBSpline = ModelAPI_Feature::feature(theBSplinePoles->owner());
+
SketchPlugin_Sketch* aSketch =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(theBSpline)->sketch();
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aBSpline)->sketch();
// create child point equal to the B-spline's pole
FeaturePtr aPointFeature = aSketch->addFeature(SketchPlugin_Point::ID());
aPointFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
- aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
+ aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(aBSpline);
GeomPnt2dPtr aPole = theBSplinePoles->pnt(thePoleIndex);
aCoord->setValue(aPole);
aPointFeature->execute();
-
- std::ostringstream aName;
- aName << theBSpline->name() << "_" << theBSplinePoles->id() << "_" << thePoleIndex;
- aPointFeature->data()->setName(aName.str());
- aPointFeature->lastResult()->data()->setName(aName.str());
+ assignDefaultNameForAux(aPointFeature, theBSplinePoles, thePoleIndex);
// internal constraint to keep position of the point
createInternalConstraint(aSketch, aCoord, theBSplinePoles, thePoleIndex);
return aPointFeature;
}
-void createAuxiliarySegment(FeaturePtr theBSpline,
- AttributePoint2DArrayPtr theBSplinePoles,
- const int thePoleIndex1,
- const int thePoleIndex2)
+void SketchPlugin_MacroBSpline::createAuxiliarySegment(AttributePoint2DArrayPtr theBSplinePoles,
+ const int thePoleIndex1,
+ const int thePoleIndex2)
{
+ FeaturePtr aBSpline = ModelAPI_Feature::feature(theBSplinePoles->owner());
+
SketchPlugin_Sketch* aSketch =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(theBSpline)->sketch();
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aBSpline)->sketch();
// create child segment between B-spline poles
FeaturePtr aLineFeature = aSketch->addFeature(SketchPlugin_Line::ID());
aLineFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
- aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
+ aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(aBSpline);
AttributePoint2DPtr aLineStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aLineFeature->attribute(SketchPlugin_Line::START_ID()));
aLineEnd->setValue(theBSplinePoles->pnt(thePoleIndex2));
aLineFeature->execute();
-
- std::ostringstream aName;
- aName << theBSpline->name() << "_segment_" << thePoleIndex1 << "_" << thePoleIndex2;
- aLineFeature->data()->setName(aName.str());
- aLineFeature->lastResult()->data()->setName(aName.str());
+ assignDefaultNameForAux(aLineFeature, theBSplinePoles, thePoleIndex1, thePoleIndex2);
// internal constraints to keep the segment position
createInternalConstraint(aSketch, aLineStart, theBSplinePoles, thePoleIndex1);