}
}
+
+%typemap(in) const std::list<int> & (std::list<int> temp) {
+ int newmem = 0;
+ if (PySequence_Check($input)) {
+ for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+ PyObject * item = PySequence_GetItem($input, i);
+ if (PyLong_Check(item)) {
+ temp.push_back((int)PyLong_AsLong(item));
+ } else {
+ PyErr_SetString(PyExc_TypeError, "argument must integet value.");
+ return NULL;
+ }
+ Py_DECREF(item);
+ }
+ $1 = &temp;
+ } else {
+ PyErr_SetString(PyExc_ValueError, "argument must be a tuple of integer values.");
+ return NULL;
+ }
+}
+
+%typecheck(SWIG_TYPECHECK_POINTER) std::list<int>, const std::list<int>& {
+ int newmem = 0;
+ if (PySequence_Check($input)) {
+ for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+ PyObject * item = PySequence_GetItem($input, i);
+ if (PyLong_Check(item)) {
+ $1 = 1;
+ } else {
+ $1 = 0;
+ break;
+ }
+ Py_DECREF(item);
+ }
+ } else {
+ $1 = 0;
+ }
+}
+
+
%typemap(in) const std::list<double> & (std::list<double> temp) {
- double * temp_attribute;
int newmem = 0;
if (PyTuple_Check($input)) {
for (Py_ssize_t i = 0; i < PyTuple_Size($input); ++i) {
}
%typecheck(SWIG_TYPECHECK_POINTER) std::list<double>, const std::list<double>& {
- double * temp_object;
- std::shared_ptr<ModelHighAPI_Interface> * temp_interface;
int newmem = 0;
if (PyTuple_Check($input)) {
for (Py_ssize_t i = 0; i < PyTuple_Size($input); ++i) {
}
}
+
+%typemap(in) const std::list<ModelHighAPI_Double> & (std::list<ModelHighAPI_Double> temp) {
+ ModelHighAPI_Double * temp_double;
+ if (PySequence_Check($input)) {
+ for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+ PyObject * item = PySequence_GetItem($input, i);
+ if (PyFloat_Check(item) || PyLong_Check(item)) {
+ temp.push_back(ModelHighAPI_Double(PyFloat_AsDouble(item)));
+ } else if (PyUnicode_Check(item)) {
+ temp.push_back(ModelHighAPI_Double(PyUnicode_AsUTF8(item)));
+ } else if ((SWIG_ConvertPtr(item, (void **)&temp_double, $1_descriptor, SWIG_POINTER_EXCEPTION)) == 0) {
+ temp.push_back(*temp_double);
+ } else {
+ PyErr_SetString(PyExc_ValueError, "argument must be a list of ModelHighAPI_Double, float, int or string.");
+ return NULL;
+ }
+ Py_DECREF(item);
+ }
+ $1 = &temp;
+ } else {
+ PyErr_SetString(PyExc_ValueError, "argument must be a list of ModelHighAPI_Double, float, int or string.");
+ return NULL;
+ }
+}
+
+%typecheck(SWIG_TYPECHECK_POINTER) std::list<ModelHighAPI_Double>, const std::list<ModelHighAPI_Double> & {
+ if (PySequence_Check($input)) {
+ for (Py_ssize_t i = 0; i < PySequence_Size($input) && $1; ++i) {
+ PyObject * item = PySequence_GetItem($input, i);
+ $1 = ((PyFloat_Check(item) || PyLong_Check(item) || PyUnicode_Check(item)) && !PyBool_Check(item)) ? 1 : 0;
+ Py_DECREF(item);
+ }
+ } else {
+ $1 = 0;
+ }
+}
+
+
// all supported interfaces
%include "ModelHighAPI_Double.h"
%include "ModelHighAPI_Dumper.h"
{
}
+double ModelHighAPI_Double::value() const
+{
+ // needed for array of double, which supports no text
+ return myDouble;
+}
+
//--------------------------------------------------------------------------------------
void ModelHighAPI_Double::fillAttribute(
const std::shared_ptr<ModelAPI_AttributeDouble> & theAttribute) const
const ModelHighAPI_Double & theY,
const ModelHighAPI_Double & theZ) const;
+ /// Value of the attribute
+ MODELHIGHAPI_EXPORT double value() const;
+
private:
enum VariantType { VT_DOUBLE, VT_STRING } myVariantType;
double myDouble;
#include <Config_PropManager.h>
#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_Dir.h>
#include <GeomAPI_ShapeExplorer.h>
#include <GeomAPI_ShapeIterator.h>
#include <GeomDataAPI_Dir.h>
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeDoubleArray.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeRefAttr.h>
return *this;
}
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<GeomDataAPI_Point2DArray>& thePointArray)
+{
+ static const int aThreshold = 4;
+ static bool aDumpAsIs = false;
+ static std::string aSeparator = "";
+ // if number of elements in the list if greater than a threshold,
+ // dump it in a separate line with specific name
+ int aSize = thePointArray->size();
+ if (aDumpAsIs || aSize <= aThreshold) {
+ *myDumpStorage << "[";
+ GeomPnt2dPtr aPoint = thePointArray->pnt(0);
+ *myDumpStorage << "(" << aPoint->x() << ", " << aPoint->y() << ")";
+ for (int anIndex = 1; anIndex < aSize; ++anIndex) {
+ aPoint = thePointArray->pnt(anIndex);
+ *myDumpStorage << "," << aSeparator << " (" << aPoint->x() << ", " << aPoint->y() << ")";
+ }
+ *myDumpStorage << aSeparator << "]";
+ }
+ else {
+ // name of list
+ FeaturePtr anOwner = ModelAPI_Feature::feature(thePointArray->owner());
+ std::string aListName = name(anOwner) + "_" + thePointArray->id();
+ // reserve dumped buffer and store list "as is"
+ myDumpStorage->reserveBuffer();
+ aDumpAsIs = true;
+ aSeparator = std::string("\n") + std::string(aListName.size() + 3, ' ');
+ *this << aListName << " = " << thePointArray << "\n";
+ aDumpAsIs = false;
+ aSeparator = "";
+ // append reserved data to the end of the current buffer
+ myDumpStorage->restoreReservedBuffer();
+ *myDumpStorage << aListName;
+ }
+ return *this;
+}
+
ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
const std::shared_ptr<ModelAPI_AttributeBoolean>& theAttrBool)
{
return *this;
}
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<ModelAPI_AttributeDoubleArray>& theArray)
+{
+ *myDumpStorage << "[";
+ int aSize = theArray->size();
+ if (aSize > 0) {
+ *myDumpStorage << theArray->value(0);
+ for (int anIndex = 1; anIndex < aSize; ++anIndex)
+ *myDumpStorage << ", " << theArray->value(anIndex);
+ }
+ *myDumpStorage << "]";
+ return *this;
+}
+
ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
const std::shared_ptr<ModelAPI_AttributeString>& theAttrStr)
{
class GeomDataAPI_Dir;
class GeomDataAPI_Point;
class GeomDataAPI_Point2D;
+class GeomDataAPI_Point2DArray;
class ModelAPI_Attribute;
class ModelAPI_AttributeBoolean;
class ModelAPI_AttributeDouble;
+class ModelAPI_AttributeDoubleArray;
class ModelAPI_AttributeInteger;
class ModelAPI_AttributeRefAttr;
class ModelAPI_AttributeRefAttrList;
/// "X, Y"
MODELHIGHAPI_EXPORT
ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Point2D>& thePoint);
+ /// Dump GeomDataAPI_Point2DArray as a list of 2D points
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Point2DArray>& thePointArray);
/// Dump AttributeBoolean
MODELHIGHAPI_EXPORT
/// Dump AttributeDouble
MODELHIGHAPI_EXPORT
ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeDouble>& theAttrReal);
+ /// Dump AttributeDoubleArray
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeDoubleArray>& theArray);
/// Dump AttributeString
MODELHIGHAPI_EXPORT
ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeString>& theAttrStr);
#include <GeomDataAPI_Dir.h>
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
//--------------------------------------------------------------------------------------
#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_AttributeDocRef.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeDoubleArray.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeRefAttr.h>
theAttribute->setValue(anIndex, it->intValue()); // use only values, no text support in array
}
+//--------------------------------------------------------------------------------------
+void fillAttribute(const std::list<ModelHighAPI_Double> & theValue,
+ const std::shared_ptr<ModelAPI_AttributeDoubleArray> & theAttribute)
+{
+ theAttribute->setSize(int(theValue.size()));
+
+ int anIndex = 0;
+ for (auto it = theValue.begin(); it != theValue.end(); ++it, ++anIndex)
+ theAttribute->setValue(anIndex, it->value()); // use only values, no text support in array
+}
+
+//--------------------------------------------------------------------------------------
+void fillAttribute(const std::list<std::shared_ptr<GeomAPI_Pnt2d> > & theValue,
+ const std::shared_ptr<GeomDataAPI_Point2DArray> & theAttribute)
+{
+ theAttribute->setSize(int(theValue.size()));
+
+ int anIndex = 0;
+ for (auto it = theValue.begin(); it != theValue.end(); ++it, ++anIndex)
+ theAttribute->setPnt(anIndex, *it);
+}
+
+//--------------------------------------------------------------------------------------
void fillAttribute(const ModelHighAPI_Double & theX,
const ModelHighAPI_Double & theY,
const ModelHighAPI_Double & theZ,
theX.fillAttribute(theAttribute, theX, theY, theZ);
}
-
//==================================================================================================
GeomAPI_Shape::ShapeType shapeTypeByStr(std::string theShapeTypeStr)
{
class GeomDataAPI_Dir;
class GeomDataAPI_Point;
class GeomDataAPI_Point2D;
+class GeomDataAPI_Point2DArray;
//--------------------------------------------------------------------------------------
class ModelAPI_AttributeBoolean;
class ModelAPI_AttributeDouble;
+class ModelAPI_AttributeDoubleArray;
class ModelAPI_AttributeIntArray;
class ModelAPI_AttributeInteger;
class ModelAPI_AttributeRefAttr;
void fillAttribute(const std::list<ModelHighAPI_Integer> & theValue,
const std::shared_ptr<ModelAPI_AttributeIntArray> & theAttribute);
+MODELHIGHAPI_EXPORT
+void fillAttribute(const std::list<ModelHighAPI_Double> & theValue,
+ const std::shared_ptr<ModelAPI_AttributeDoubleArray> & theAttribute);
+
+MODELHIGHAPI_EXPORT
+void fillAttribute(const std::list<std::shared_ptr<GeomAPI_Pnt2d> > & theValue,
+ const std::shared_ptr<GeomDataAPI_Point2DArray> & theAttribute);
+
MODELHIGHAPI_EXPORT
void fillAttribute(const ModelHighAPI_Double & theX,
const ModelHighAPI_Double & theY,
SET(PROJECT_HEADERS
SketchAPI.h
SketchAPI_Arc.h
+ SketchAPI_BSpline.h
SketchAPI_Circle.h
SketchAPI_Constraint.h
SketchAPI_ConstraintAngle.h
SET(PROJECT_SOURCES
SketchAPI_Arc.cpp
+ SketchAPI_BSpline.cpp
SketchAPI_Circle.cpp
SketchAPI_Constraint.cpp
SketchAPI_ConstraintAngle.cpp
%include "std_shared_ptr.i"
// function with named parameters
+%feature("kwargs") SketchAPI_BSpline::controlPoles;
+%feature("kwargs") SketchAPI_BSpline::controlPolygon;
%feature("kwargs") SketchAPI_Ellipse::construction;
%feature("kwargs") SketchAPI_EllipticArc::construction;
%feature("kwargs") SketchAPI_Sketch::setAngle;
%shared_ptr(SketchAPI_MacroEllipse)
%shared_ptr(SketchAPI_EllipticArc)
%shared_ptr(SketchAPI_MacroEllipticArc)
+%shared_ptr(SketchAPI_BSpline)
%shared_ptr(SketchAPI_Constraint)
%shared_ptr(SketchAPI_ConstraintAngle)
%shared_ptr(SketchAPI_IntersectionPoint)
%template(InterfaceList) std::list<std::shared_ptr<ModelHighAPI_Interface> >;
%template(EntityList) std::list<std::shared_ptr<SketchAPI_SketchEntity> >;
%template(SketchPointList) std::list<std::shared_ptr<SketchAPI_Point> >;
+%template(GeomPnt2dList) std::list<std::shared_ptr<GeomAPI_Pnt2d> >;
// std::pair -> []
%template(PointRefAttrPair) std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>;
// fix compilarion error: 'res*' was not declared in this scope
%typemap(freearg) const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & {}
+
+%typemap(in) const std::list<std::shared_ptr<GeomAPI_Pnt2d> > & (std::list<std::shared_ptr<GeomAPI_Pnt2d> > temp) {
+ std::shared_ptr<GeomAPI_Pnt2d> * temp_point = 0;
+ int newmem = 0;
+ if (PySequence_Check($input)) {
+ for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+ PyObject * item = PySequence_GetItem($input, i);
+ if (PyTuple_Check(item)) {
+ if (PyTuple_Size(item) == 2) {
+ double x = (double)PyFloat_AsDouble(PySequence_GetItem(item, 0));
+ double y = (double)PyFloat_AsDouble(PySequence_GetItem(item, 1));
+ temp.push_back(std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(x, y)));
+ } else {
+ PyErr_SetString(PyExc_TypeError, "argument must a list of 2D points.");
+ return NULL;
+ }
+ } else
+ if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_point, $descriptor(std::shared_ptr<GeomAPI_Pnt2d> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+ temp.push_back(*temp_point);
+ if (temp_point && (newmem & SWIG_CAST_NEW_MEMORY)) {
+ delete temp_point;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "argument must a list of 2D points.");
+ return NULL;
+ }
+ Py_DECREF(item);
+ }
+ $1 = &temp;
+ } else {
+ PyErr_SetString(PyExc_ValueError, "argument must be a tuple of lists.");
+ return NULL;
+ }
+}
+
+%typecheck(SWIG_TYPECHECK_POINTER) std::list<std::shared_ptr<GeomAPI_Pnt2d> >, const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& {
+ std::shared_ptr<GeomAPI_Pnt2d> * temp_point = 0;
+ int newmem = 0;
+ if (PySequence_Check($input)) {
+ for (Py_ssize_t i = 0; i < PySequence_Size($input) && $1; ++i) {
+ PyObject * item = PySequence_GetItem($input, i);
+ if (PyTuple_Check(item)) {
+ if (PyTuple_Size(item) == 2) {
+ if (PyNumber_Check(PySequence_GetItem(item, 0)) && PyNumber_Check(PySequence_GetItem(item, 1))) {
+ $1 = 1;
+ } else {
+ $1 = 0;
+ }
+ } else {
+ $1 = 0;
+ }
+ } else
+ if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_point, $descriptor(std::shared_ptr<GeomAPI_Pnt2d> *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+ if (temp_point) {
+ $1 = 1;
+ } else {
+ $1 = 0;
+ }
+ }
+ Py_DECREF(item);
+ }
+ } else {
+ $1 = 0;
+ }
+}
+
+// fix compilarion error: 'res*' was not declared in this scope
+%typemap(freearg) const std::list<std::shared_ptr<GeomAPI_Pnt2d> > & {}
+
+
// all supported interfaces (the order is very important according dependencies: base class first)
%include "SketchAPI_SketchEntity.h"
%include "SketchAPI_Point.h"
%include "SketchAPI_MacroEllipse.h"
%include "SketchAPI_EllipticArc.h"
%include "SketchAPI_MacroEllipticArc.h"
+%include "SketchAPI_BSpline.h"
%include "SketchAPI_Projection.h"
%include "SketchAPI_Mirror.h"
%include "SketchAPI_Translation.h"
--- /dev/null
+// Copyright (C) 2019-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SketchAPI_BSpline.h"
+
+#include <GeomAPI_BSpline2d.h>
+#include <GeomAPI_Pnt2d.h>
+
+#include <GeomAlgoAPI_EdgeBuilder.h>
+
+#include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Integer.h>
+#include <ModelHighAPI_Selection.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <SketchPlugin_ConstraintCoincidenceInternal.h>
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Point.h>
+
+#include <cmath>
+
+
+SketchAPI_BSpline::SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature> & theFeature)
+ : SketchAPI_SketchEntity(theFeature)
+{
+ initialize();
+}
+
+SketchAPI_BSpline::SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<GeomPnt2dPtr>& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights)
+ : 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);
+ }
+}
+
+SketchAPI_BSpline::~SketchAPI_BSpline()
+{
+}
+
+void SketchAPI_BSpline::setByDegreePolesAndWeights(const ModelHighAPI_Integer& theDegree,
+ const std::list<GeomPnt2dPtr>& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights)
+{
+ std::list<ModelHighAPI_Double> aWeights;
+ if (theWeights.size() <= 1) {
+ // prepare array of equal weights
+ aWeights.assign(thePoles.size(),
+ theWeights.empty() ? ModelHighAPI_Double(1.0) : theWeights.front());
+ }
+ else
+ aWeights = theWeights;
+
+ ModelHighAPI_Integer aDegree = theDegree;
+ std::list<ModelHighAPI_Double> aKnots;
+ std::list<ModelHighAPI_Integer> aMults;
+ getDefaultParameters(thePoles, aWeights, aDegree, aKnots, aMults);
+
+ setByParameters(aDegree, thePoles, aWeights, aKnots, aMults);
+}
+
+void SketchAPI_BSpline::setByParameters(const ModelHighAPI_Integer& theDegree,
+ const std::list<GeomPnt2dPtr>& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights,
+ const std::list<ModelHighAPI_Double>& theKnots,
+ const std::list<ModelHighAPI_Integer>& theMults)
+{
+ fillAttribute(theDegree, degree());
+
+ fillAttribute(thePoles, poles());
+ if (theWeights.size() <= 1) {
+ // prepare array of equal weights
+ std::list<ModelHighAPI_Double> aWeights(thePoles.size(),
+ theWeights.empty() ? ModelHighAPI_Double(1.0) : theWeights.front());
+ fillAttribute(aWeights, weights());
+ }
+ else
+ fillAttribute(theWeights, weights());
+
+ fillAttribute(theKnots, knots());
+ fillAttribute(theMults, multiplicities());
+
+ setStartAndEndPoints();
+ execute();
+}
+
+void SketchAPI_BSpline::setStartAndEndPoints()
+{
+ fillAttribute(poles()->pnt(0), startPoint());
+ fillAttribute(poles()->pnt(poles()->size() - 1), endPoint());
+}
+
+void SketchAPI_BSpline::setByExternal(const ModelHighAPI_Selection & theExternal)
+{
+ fillAttribute(theExternal, external());
+ 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();
+ for (std::set<AttributePtr>::const_iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt)
+ if ((*anIt)->id() == SketchPlugin_Sketch::FEATURES_ID())
+ return std::dynamic_pointer_cast<ModelAPI_CompositeFeature>((*anIt)->owner());
+ return CompositeFeaturePtr();
+}
+
+static void createInternalConstraint(const CompositeFeaturePtr& theSketch,
+ const AttributePoint2DPtr& thePoint,
+ const AttributePoint2DArrayPtr& thePoles,
+ const int thePoleIndex)
+{
+ FeaturePtr aConstraint = theSketch->addFeature(SketchPlugin_ConstraintCoincidenceInternal::ID());
+ aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A())->setAttr(thePoint);
+ aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B())->setAttr(thePoles);
+ aConstraint->integer(SketchPlugin_ConstraintCoincidenceInternal::INDEX_ENTITY_B())
+ ->setValue(thePoleIndex);
+ aConstraint->execute();
+}
+
+static void createPole(const CompositeFeaturePtr& theSketch,
+ const FeaturePtr& theBSpline,
+ const AttributePoint2DArrayPtr& thePoles,
+ const int thePoleIndex,
+ const bool theAuxiliary,
+ std::list<FeaturePtr>& theEntities)
+{
+ GeomPnt2dPtr aPole = thePoles->pnt(thePoleIndex);
+
+ FeaturePtr aPointFeature = theSketch->addFeature(SketchPlugin_Point::ID());
+ AttributePoint2DPtr aCoord = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aPointFeature->attribute(SketchPlugin_Point::COORD_ID()));
+ aCoord->setValue(aPole);
+ aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
+ aPointFeature->execute();
+
+ std::ostringstream aName;
+ aName << theBSpline->name() << "_" << thePoles->id() << "_" << thePoleIndex;
+ aPointFeature->data()->setName(aName.str());
+ aPointFeature->lastResult()->data()->setName(aName.str());
+
+ aPointFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(theAuxiliary);
+
+ createInternalConstraint(theSketch, aCoord, thePoles, thePoleIndex);
+
+ theEntities.push_back(aPointFeature);
+}
+
+static void createSegment(const CompositeFeaturePtr& theSketch,
+ const FeaturePtr& theBSpline,
+ const AttributePoint2DArrayPtr& thePoles,
+ const int theStartPoleIndex,
+ const bool theAuxiliary,
+ std::list<FeaturePtr>& theEntities)
+{
+ GeomPnt2dPtr aStartPoint = thePoles->pnt(theStartPoleIndex);
+ GeomPnt2dPtr aEndPoint = thePoles->pnt(theStartPoleIndex + 1);
+
+ FeaturePtr aLineFeature = theSketch->addFeature(SketchPlugin_Line::ID());
+ AttributePoint2DPtr aLineStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineFeature->attribute(SketchPlugin_Line::START_ID()));
+ aLineStart->setValue(aStartPoint);
+ AttributePoint2DPtr aLineEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineFeature->attribute(SketchPlugin_Line::END_ID()));
+ aLineEnd->setValue(aEndPoint);
+ aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
+ aLineFeature->execute();
+
+ std::ostringstream aName;
+ aName << theBSpline->name() << "_segment_" << theStartPoleIndex << "_" << theStartPoleIndex + 1;
+ 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);
+
+ theEntities.push_back(aLineFeature);
+}
+
+static void toMapOfAuxIndices(const std::list<int>& theRegular,
+ const std::list<int>& theAuxiliary,
+ std::map<int, bool>& theIndices)
+{
+ for (auto it = theRegular.begin(); it != theRegular.end(); ++it)
+ theIndices[*it] = false;
+ for (auto it = theAuxiliary.begin(); it != theAuxiliary.end(); ++it)
+ theIndices[*it] = true;
+}
+
+std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_BSpline::controlPoles(
+ const std::list<int>& regular,
+ const std::list<int>& auxiliary) const
+{
+ std::map<int, bool> anAux;
+ toMapOfAuxIndices(regular, auxiliary, anAux);
+
+ std::list<FeaturePtr> anEntities;
+
+ FeaturePtr aBSpline = feature();
+ CompositeFeaturePtr aSketch = sketchForFeature(aBSpline);
+ AttributePoint2DArrayPtr aPoles = poles();
+
+ for (auto it = anAux.begin(); it != anAux.end(); ++it)
+ createPole(aSketch, aBSpline, aPoles, it->first, it->second, anEntities);
+
+ return SketchAPI_SketchEntity::wrap(anEntities);
+}
+
+std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_BSpline::controlPolygon(
+ const std::list<int>& regular,
+ const std::list<int>& auxiliary) const
+{
+ std::map<int, bool> anAux;
+ toMapOfAuxIndices(regular, auxiliary, anAux);
+
+ std::list<FeaturePtr> anEntities;
+
+ FeaturePtr aBSpline = feature();
+ CompositeFeaturePtr aSketch = sketchForFeature(aBSpline);
+ AttributePoint2DArrayPtr aPoles = poles();
+
+ for (auto it = anAux.begin(); it != anAux.end(); ++it)
+ createSegment(aSketch, aBSpline, aPoles, it->first, it->second, anEntities);
+
+ return SketchAPI_SketchEntity::wrap(anEntities);
+}
+
+
+void SketchAPI_BSpline::getDefaultParameters(
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights,
+ ModelHighAPI_Integer& theDegree,
+ std::list<ModelHighAPI_Double>& theKnots,
+ std::list<ModelHighAPI_Integer>& theMults) const
+{
+ std::shared_ptr<GeomAPI_BSpline2d> aBSplineCurve;
+ try {
+ std::list<double> aWeights;
+ for (std::list<ModelHighAPI_Double>::const_iterator it = theWeights.begin();
+ it != theWeights.end(); ++it)
+ aWeights.push_back(it->value());
+
+ if (theDegree.intValue() < 0)
+ aBSplineCurve.reset(new GeomAPI_BSpline2d(thePoles, aWeights));
+ else
+ aBSplineCurve.reset(new GeomAPI_BSpline2d(theDegree.intValue(), thePoles, aWeights));
+ }
+ catch (...) {
+ // cannot build a B-spline curve
+ return;
+ }
+
+ theDegree = aBSplineCurve->degree();
+ std::list<double> aKnots = aBSplineCurve->knots();
+ std::list<int> aMults = aBSplineCurve->mults();
+ theKnots.assign(aKnots.begin(), aKnots.end());
+ theMults.assign(aMults.begin(), aMults.end());
+}
+
+void SketchAPI_BSpline::checkDefaultParameters(bool& isDefaultDegree,
+ bool& isDefaultWeights,
+ bool& isDefaultKnotsMults) const
+{
+ static const double TOLERANCE = 1.e-7;
+
+ AttributePoint2DArrayPtr aPolesAttr = poles();
+ AttributeDoubleArrayPtr aWeightsAttr = weights();
+ AttributeDoubleArrayPtr aKnotsAttr = knots();
+ AttributeIntArrayPtr aMultsAttr = multiplicities();
+
+ std::list<GeomPnt2dPtr> aPoles;
+ std::list<ModelHighAPI_Double> aWeights;
+ isDefaultWeights = true;
+ for (int anIndex = 0; anIndex < aPolesAttr->size(); ++anIndex) {
+ aPoles.push_back(aPolesAttr->pnt(anIndex));
+ double aCurWeight = aWeightsAttr->value(anIndex);
+ isDefaultWeights = isDefaultWeights && fabs(aCurWeight - 1.0) < TOLERANCE;
+ aWeights.push_back(aCurWeight);
+ }
+
+ ModelHighAPI_Integer aDegree(-1);
+ std::list<ModelHighAPI_Double> aKnots;
+ std::list<ModelHighAPI_Integer> aMults;
+ getDefaultParameters(aPoles, aWeights, aDegree, aKnots, aMults);
+ isDefaultDegree = aDegree.intValue() == degree()->value();
+ if (!isDefaultDegree) {
+ // recalculate knots and multiplicities with the actual degree
+ aDegree = degree()->value();
+ getDefaultParameters(aPoles, aWeights, aDegree, aKnots, aMults);
+ }
+
+ isDefaultKnotsMults = aKnotsAttr->size() == (int)aKnots.size()
+ && aMultsAttr->size() == (int)aMults.size();
+ if (isDefaultKnotsMults) {
+ std::list<ModelHighAPI_Double>::iterator anIt = aKnots.begin();
+ for (int anIndex = 0; isDefaultKnotsMults && anIt != aKnots.end(); ++anIt, ++anIndex)
+ isDefaultKnotsMults = fabs(anIt->value() - aKnotsAttr->value(anIndex)) < TOLERANCE;
+ }
+ if (isDefaultKnotsMults) {
+ std::list<ModelHighAPI_Integer>::iterator anIt = aMults.begin();
+ for (int anIndex = 0; isDefaultKnotsMults && anIt != aMults.end(); ++anIt, ++anIndex)
+ isDefaultKnotsMults = anIt->intValue() == aMultsAttr->value(anIndex);
+ }
+
+ isDefaultDegree = isDefaultDegree && isDefaultKnotsMults;
+ isDefaultWeights = isDefaultWeights && isDefaultKnotsMults;
+}
+
+
+static void bsplineAuxiliaryFeature(const AttributeRefAttrPtr& theReference,
+ FeaturePtr& thePoint,
+ FeaturePtr& theSegment)
+{
+ ObjectPtr anAuxObject;
+ if (theReference->isObject())
+ anAuxObject = theReference->object();
+ else
+ anAuxObject = theReference->attr()->owner();
+
+ FeaturePtr anAuxFeature = ModelAPI_Feature::feature(anAuxObject);
+ if (anAuxFeature->getKind() == SketchPlugin_Point::ID())
+ thePoint = anAuxFeature;
+ else if (anAuxFeature->getKind() == SketchPlugin_Line::ID() &&
+ theReference->attr()->id() == SketchPlugin_Line::START_ID()) {
+ // process only coincidence with start point
+ theSegment = anAuxFeature;
+ }
+}
+
+static void collectAuxiliaryFeatures(FeaturePtr theBSpline,
+ std::map<int, FeaturePtr>& thePoints,
+ std::map<int, FeaturePtr>& theSegments)
+{
+ const std::set<AttributePtr>& aRefs = theBSpline->data()->refsToMe();
+ for (std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
+ aRefIt != aRefs.end(); ++aRefIt) {
+ FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
+ if (anOwner->getKind() == SketchPlugin_ConstraintCoincidenceInternal::ID()) {
+ // process internal constraints only
+ AttributeRefAttrPtr aRefAttrA = anOwner->refattr(SketchPlugin_Constraint::ENTITY_A());
+ AttributeRefAttrPtr aRefAttrB = anOwner->refattr(SketchPlugin_Constraint::ENTITY_B());
+ AttributePtr anAttrA = aRefAttrA->attr();
+ AttributePtr anAttrB = aRefAttrB->attr();
+
+ AttributeIntegerPtr aPoleIndex;
+ FeaturePtr aPoint, aLine;
+ if (anAttrA && anAttrA->attributeType() == GeomDataAPI_Point2DArray::typeId()) {
+ aPoleIndex = anOwner->integer(SketchPlugin_ConstraintCoincidenceInternal::INDEX_ENTITY_A());
+ bsplineAuxiliaryFeature(aRefAttrB, aPoint, aLine);
+ }
+ else if (anAttrB && anAttrB->attributeType() == GeomDataAPI_Point2DArray::typeId()) {
+ aPoleIndex = anOwner->integer(SketchPlugin_ConstraintCoincidenceInternal::INDEX_ENTITY_B());
+ bsplineAuxiliaryFeature(aRefAttrA, aPoint, aLine);
+ }
+
+ if (aPoint)
+ thePoints[aPoleIndex->value()] = aPoint;
+ else if (aLine)
+ theSegments[aPoleIndex->value()] = aLine;
+ }
+ }
+}
+
+void SketchAPI_BSpline::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ if (isCopy())
+ return; // no need to dump copied feature
+
+ FeaturePtr aBase = feature();
+ const std::string& aSketchName = theDumper.parentName(aBase);
+
+ AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+ if (anExternal->context()) {
+ // B-spline is external
+ theDumper << aBase << " = " << aSketchName << ".addSpline(" << anExternal << ")" << std::endl;
+ } else {
+ // check if some B-spline parameters are default and should not be dumped
+ bool isDefaultDegree, isDefaultWeights, isDefaultKnotsMults;
+ checkDefaultParameters(isDefaultDegree, isDefaultWeights, isDefaultKnotsMults);
+
+ theDumper << aBase << " = " << aSketchName << ".addSpline(";
+ if (!isDefaultDegree)
+ theDumper << degree() << ", ";
+ theDumper << poles();
+ if (!isDefaultWeights)
+ theDumper << ", " << weights();
+ if (!isDefaultKnotsMults)
+ theDumper << ", " << knots() << ", " << multiplicities();
+ theDumper << ")" << std::endl;
+ }
+ // dump "auxiliary" flag if necessary
+ SketchAPI_SketchEntity::dump(theDumper);
+
+ // dump control polygon
+ std::map<int, FeaturePtr> anAuxPoles, anAuxSegments;
+ collectAuxiliaryFeatures(aBase, anAuxPoles, anAuxSegments);
+
+ if (!anAuxPoles.empty())
+ dumpControlPolygon(theDumper, aBase, "controlPoles", anAuxPoles);
+ if (!anAuxSegments.empty())
+ dumpControlPolygon(theDumper, aBase, "controlPolygon", anAuxSegments);
+}
+
+static void dumpList(ModelHighAPI_Dumper& theDumper,
+ const std::string& theAttrName,
+ const std::set<int>& theIndices)
+{
+ theDumper << theAttrName << " = [";
+ std::set<int>::const_iterator it = theIndices.begin();
+ theDumper << *it;
+ for (++it; it != theIndices.end(); ++it)
+ theDumper << ", " << *it;
+ theDumper << "]";
+}
+
+void SketchAPI_BSpline::dumpControlPolygon(
+ ModelHighAPI_Dumper& theDumper,
+ const FeaturePtr& theBSpline,
+ const std::string& theMethod,
+ const std::map<int, FeaturePtr>& theAuxFeatures) const
+{
+ theDumper << "[";
+ bool isFirst = true;
+ // dump features and split them to auxiliary and regular
+ std::set<int> aRegular, anAuxiliary;
+ for (std::map<int, FeaturePtr>::const_iterator it = theAuxFeatures.begin();
+ it != theAuxFeatures.end(); ++it) {
+ if (!isFirst)
+ theDumper << ", ";
+ theDumper << theDumper.name(it->second, false);
+ theDumper.doNotDumpFeature(it->second);
+ isFirst = false;
+
+ if (it->second->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value())
+ anAuxiliary.insert(it->first);
+ else
+ aRegular.insert(it->first);
+ }
+ theDumper << "] = " << theDumper.name(theBSpline) << "." << theMethod << "(";
+ if (!aRegular.empty()) {
+ dumpList(theDumper, "regular", aRegular);
+ if (!anAuxiliary.empty())
+ theDumper << ", ";
+ }
+ if (!anAuxiliary.empty())
+ dumpList(theDumper, "auxiliary", anAuxiliary);
+ theDumper << ")" << std::endl;
+}
--- /dev/null
+// Copyright (C) 2019-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef SketchAPI_BSpline_H_
+#define SketchAPI_BSpline_H_
+
+#include "SketchAPI.h"
+#include "SketchAPI_SketchEntity.h"
+
+#include <GeomDataAPI_Point2DArray.h>
+
+#include <ModelAPI_AttributeDoubleArray.h>
+
+#include <SketchPlugin_BSpline.h>
+
+class ModelHighAPI_Double;
+class ModelHighAPI_Integer;
+class ModelHighAPI_Selection;
+
+/// \class SketchAPI_BSpline
+/// \ingroup CPPHighAPI
+/// \brief Interface for BSpline feature.
+class SketchAPI_BSpline : public SketchAPI_SketchEntity
+{
+public:
+ /// Constructor without values.
+ SKETCHAPI_EXPORT
+ explicit SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values.
+ SKETCHAPI_EXPORT SketchAPI_BSpline(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights = std::list<ModelHighAPI_Double>());
+
+ /// Constructor with values.
+ SKETCHAPI_EXPORT SketchAPI_BSpline(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const int theDegree,
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights = std::list<ModelHighAPI_Double>(),
+ const std::list<ModelHighAPI_Double>& theKnots = std::list<ModelHighAPI_Double>(),
+ const std::list<ModelHighAPI_Integer>& theMults = std::list<ModelHighAPI_Integer>());
+
+ /// Constructor with external.
+ SKETCHAPI_EXPORT
+ SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const ModelHighAPI_Selection& theExternal);
+
+ /// Constructor with external.
+ SKETCHAPI_EXPORT
+ SketchAPI_BSpline(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::string& theExternalName);
+
+ /// Destructor.
+ SKETCHAPI_EXPORT
+ virtual ~SketchAPI_BSpline();
+
+ INTERFACE_8(SketchPlugin_BSpline::ID(),
+ poles, SketchPlugin_BSpline::POLES_ID(),
+ GeomDataAPI_Point2DArray, /** B-spline poles */,
+ weights, SketchPlugin_BSpline::WEIGHTS_ID(),
+ ModelAPI_AttributeDoubleArray, /** B-spline weights */,
+ knots, SketchPlugin_BSpline::KNOTS_ID(),
+ ModelAPI_AttributeDoubleArray, /** B-spline knots */,
+ multiplicities, SketchPlugin_BSpline::MULTS_ID(),
+ ModelAPI_AttributeIntArray, /** Knots multiplicities */,
+ degree, SketchPlugin_BSpline::DEGREE_ID(),
+ ModelAPI_AttributeInteger, /** B-spline degree */,
+ startPoint, SketchPlugin_BSpline::START_ID(),
+ GeomDataAPI_Point2D, /** First pole of B-spline */,
+ endPoint, SketchPlugin_BSpline::END_ID(),
+ GeomDataAPI_Point2D, /** Last pole of B-spline */,
+ external, SketchPlugin_BSpline::EXTERNAL_ID(),
+ ModelAPI_AttributeSelection, /** External */)
+
+ /// Set by poles and weights.
+ SKETCHAPI_EXPORT
+ void setByDegreePolesAndWeights(const ModelHighAPI_Integer& theDegree,
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights);
+
+ /// Initialize by full set of B-spline parameters.
+ SKETCHAPI_EXPORT
+ void setByParameters(const ModelHighAPI_Integer& theDegree,
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights,
+ const std::list<ModelHighAPI_Double>& theKnots,
+ const std::list<ModelHighAPI_Integer>& theMults);
+
+ /// Set by external.
+ SKETCHAPI_EXPORT
+ void setByExternal(const ModelHighAPI_Selection& theExternal);
+
+ /// Set by external name.
+ SKETCHAPI_EXPORT
+ void setByExternalName(const std::string& theExternalName);
+
+ /// Generate list of construction points coincident with B-spline poles
+ SKETCHAPI_EXPORT
+ std::list<std::shared_ptr<SketchAPI_SketchEntity> > controlPoles(
+ const std::list<int>& regular = std::list<int>(),
+ const std::list<int>& auxiliary = std::list<int>()) const;
+
+ /// Generate control polygon for B-spline curve
+ SKETCHAPI_EXPORT
+ std::list<std::shared_ptr<SketchAPI_SketchEntity> > controlPolygon(
+ const std::list<int>& regular = std::list<int>(),
+ const std::list<int>& auxiliary = std::list<int>()) const;
+
+ /// Dump wrapped feature
+ SKETCHAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+ /// Initialize start and end points of B-spline and apply internal coincidence
+ /// constraint to keep them on the corresponding pole.
+ void setStartAndEndPoints();
+
+ /// Compute default B-spline parameters (degree, knots and multiplicities)
+ /// basing on hte given poles and weights
+ void getDefaultParameters(const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights,
+ ModelHighAPI_Integer& theDegree,
+ std::list<ModelHighAPI_Double>& theKnots,
+ std::list<ModelHighAPI_Integer>& theMults) const;
+
+ /// Check what parameters of B-spline are default
+ void checkDefaultParameters(bool& isDefaultDegree,
+ bool& isDefaultWeights,
+ bool& isDefaultKnotsMults) const;
+
+ void dumpControlPolygon(ModelHighAPI_Dumper& theDumper,
+ const FeaturePtr& theBSpline,
+ const std::string& theMethod,
+ const std::map<int, FeaturePtr>& theAuxFeatures) const;
+};
+
+/// Pointer on B-spline object.
+typedef std::shared_ptr<SketchAPI_BSpline> BSplinePtr;
+
+#endif // SketchAPI_BSpline_H_
#include "SketchAPI_Projection.h"
#include <SketchPlugin_Line.h>
+#include <SketchPlugin_BSpline.h>
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Ellipse.h>
#include <SketchPlugin_EllipticArc.h>
#include <SketchPlugin_Point.h>
#include <SketchAPI_Arc.h>
+#include <SketchAPI_BSpline.h>
#include <SketchAPI_Circle.h>
#include <SketchAPI_Ellipse.h>
#include <SketchAPI_EllipticArc.h>
anEntity.reset(new SketchAPI_Ellipse(aProjectedFeature));
else if (aProjectedFeature->getKind() == SketchPlugin_EllipticArc::ID())
anEntity.reset(new SketchAPI_EllipticArc(aProjectedFeature));
+ else if (aProjectedFeature->getKind() == SketchPlugin_BSpline::ID())
+ anEntity.reset(new SketchAPI_BSpline(aProjectedFeature));
else if (aProjectedFeature->getKind() == SketchPlugin_Point::ID())
anEntity.reset(new SketchAPI_Point(aProjectedFeature));
#include <ModelHighAPI_Tools.h>
//--------------------------------------------------------------------------------------
#include "SketchAPI_Arc.h"
+#include "SketchAPI_BSpline.h"
#include "SketchAPI_Circle.h"
#include "SketchAPI_Ellipse.h"
#include "SketchAPI_EllipticArc.h"
return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, theExternalName));
}
+//--------------------------------------------------------------------------------------
+std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addSpline(
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights)
+{
+ FeaturePtr aFeature = compositeFeature()->addFeature(SketchPlugin_BSpline::ID());
+ return BSplinePtr(new SketchAPI_BSpline(aFeature, thePoles, theWeights));
+}
+
+std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addSpline(
+ const int theDegree,
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights,
+ const std::list<ModelHighAPI_Double>& theKnots,
+ const std::list<ModelHighAPI_Integer>& theMults)
+{
+ FeaturePtr aFeature = compositeFeature()->addFeature(SketchPlugin_BSpline::ID());
+ return BSplinePtr(new SketchAPI_BSpline(aFeature,
+ theDegree, thePoles, theWeights, theKnots, theMults));
+}
+
+std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addSpline(
+ const ModelHighAPI_Selection & theExternal)
+{
+ FeaturePtr aFeature = compositeFeature()->addFeature(SketchPlugin_BSpline::ID());
+ return BSplinePtr(new SketchAPI_BSpline(aFeature, theExternal));
+}
+
+std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addSpline(const std::string & theExternalName)
+{
+ FeaturePtr aFeature = compositeFeature()->addFeature(SketchPlugin_BSpline::ID());
+ return BSplinePtr(new SketchAPI_BSpline(aFeature, theExternalName));
+}
+
//--------------------------------------------------------------------------------------
std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
const ModelHighAPI_Selection & theExternalFeature,
class SketchAPI_MacroEllipse;
class SketchAPI_EllipticArc;
class SketchAPI_MacroEllipticArc;
+class SketchAPI_BSpline;
class SketchAPI_IntersectionPoint;
class SketchAPI_Line;
class SketchAPI_Mirror;
SKETCHAPI_EXPORT
std::shared_ptr<SketchAPI_EllipticArc> addEllipticArc(const std::string & theExternalName);
+ /// Add B-spline
+ SKETCHAPI_EXPORT
+ std::shared_ptr<SketchAPI_BSpline> addSpline(
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights = std::list<ModelHighAPI_Double>());
+ /// Add B-spline
+ SKETCHAPI_EXPORT
+ std::shared_ptr<SketchAPI_BSpline> addSpline(
+ const int theDegree,
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<ModelHighAPI_Double>& theWeights = std::list<ModelHighAPI_Double>(),
+ const std::list<ModelHighAPI_Double>& theKnots = std::list<ModelHighAPI_Double>(),
+ const std::list<ModelHighAPI_Integer>& theMults = std::list<ModelHighAPI_Integer>());
+ /// Add B-spline
+ SKETCHAPI_EXPORT
+ std::shared_ptr<SketchAPI_BSpline> addSpline(const ModelHighAPI_Selection & theExternal);
+ /// Add B-spline
+ SKETCHAPI_EXPORT
+ std::shared_ptr<SketchAPI_BSpline> addSpline(const std::string & theExternalName);
+
/// Add projection
SKETCHAPI_EXPORT
std::shared_ptr<SketchAPI_Projection> addProjection(
#include "SketchAPI_SketchEntity.h"
#include <SketchAPI_Arc.h>
+#include <SketchAPI_BSpline.h>
#include <SketchAPI_Circle.h>
#include <SketchAPI_Ellipse.h>
#include <SketchAPI_EllipticArc.h>
#include <ModelHighAPI_Tools.h>
#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_BSpline.h>
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Ellipse.h>
#include <SketchPlugin_IntersectionPoint.h>
aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_Ellipse(*anIt)));
else if ((*anIt)->getKind() == SketchPlugin_EllipticArc::ID())
aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_EllipticArc(*anIt)));
+ else if ((*anIt)->getKind() == SketchPlugin_BSpline::ID())
+ aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_BSpline(*anIt)));
else if ((*anIt)->getKind() == SketchPlugin_Point::ID())
aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_Point(*anIt)));
else if ((*anIt)->getKind() == SketchPlugin_IntersectionPoint::ID())
#include "SketchAPI_MacroEllipse.h"
#include "SketchAPI_EllipticArc.h"
#include "SketchAPI_MacroEllipticArc.h"
+ #include "SketchAPI_BSpline.h"
#include "SketchAPI_Constraint.h"
#include "SketchAPI_ConstraintAngle.h"
#include "SketchAPI_IntersectionPoint.h"
AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aBSpline->attribute(SketchPlugin_BSpline::START_ID()));
aStartPoint->setValue(aPoles->pnt(0));
- // internal constraint to keep position of the point
- createInternalConstraint(aSketch, aStartPoint, aPoles, 0);
AttributePoint2DPtr aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aBSpline->attribute(SketchPlugin_BSpline::END_ID()));
aEndPoint->setValue(aPoles->pnt(aPoles->size() - 1));
- // internal constraint to keep position of the point
- createInternalConstraint(aSketch, aEndPoint, aPoles, aPoles->size() - 1);
aBSpline->boolean(SketchPlugin_BSpline::AUXILIARY_ID())->setValue(
boolean(AUXILIARY_ID())->value());
aNewSpline->degree = 3;
aNewSpline->periodic = false;
+ std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
+
AttributeEntityMap::const_iterator anIt = theAttributes.begin();
for (; anIt != theAttributes.end(); ++anIt) {
const std::string& anAttrID = anIt->first->id();
std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
aNewSpline->degree = (int)aScalar->value();
}
+ else if (anAttrID == SketchPlugin_BSpline::START_ID() ||
+ anAttrID == SketchPlugin_BSpline::END_ID()) {
+ anAdditionalAttributes[anAttrID] = anIt->second;
+ }
else {
ScalarArrayWrapperPtr anArray =
std::dynamic_pointer_cast<PlaneGCSSolver_ScalarArrayWrapper>(anIt->second);
}
}
- return EdgeWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewSpline));
+ EdgeWrapperPtr aWrapper(new PlaneGCSSolver_EdgeWrapper(aNewSpline));
+ aWrapper->setAdditionalAttributes(anAdditionalAttributes);
+ return aWrapper;
}
#include <GeomDataAPI_Point2DArray.h>
#include <ModelAPI_AttributeDoubleArray.h>
#include <ModelAPI_AttributeRefAttr.h>
+#include <SketchPlugin_BSpline.h>
#include <SketchPlugin_Ellipse.h>
#include <SketchPlugin_Projection.h>
constraintsToSolver(aConstraint, theSolver);
}
+static void createBSplineConstraints(
+ const EntityWrapperPtr& theCurve,
+ const SolverPtr& theSolver,
+ const ConstraintID theConstraintID,
+ std::map<EntityWrapperPtr, ConstraintWrapperPtr>& theConstraints)
+{
+ // set start and end point of B-spline equal to first and last pole correspondingly
+ EdgeWrapperPtr anEdge = std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theCurve);
+ std::shared_ptr<GCS::BSpline> aBSpline =
+ std::dynamic_pointer_cast<GCS::BSpline>(anEdge->entity());
+
+ std::list<GCSConstraintPtr> aBSplineConstraints;
+
+ const std::map<std::string, EntityWrapperPtr>& anAdditional = anEdge->additionalAttributes();
+ PointWrapperPtr aStartPoint = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(
+ anAdditional.at(SketchPlugin_BSpline::START_ID()));
+
+ const GCS::Point& sp = *aStartPoint->point();
+ const GCS::Point& p0 = aBSpline->poles.front();
+ aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(p0.x, sp.x)));
+ aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(p0.y, sp.y)));
+
+ PointWrapperPtr aEndPoint = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(
+ anAdditional.at(SketchPlugin_BSpline::END_ID()));
+
+ const GCS::Point& ep = *aEndPoint->point();
+ const GCS::Point& pN = aBSpline->poles.back();
+ aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(pN.x, ep.x)));
+ aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(pN.y, ep.y)));
+
+ ConstraintWrapperPtr aWrapper(
+ new PlaneGCSSolver_ConstraintWrapper(aBSplineConstraints, CONSTRAINT_UNKNOWN));
+ aWrapper->setId(theConstraintID);
+ if (theSolver)
+ constraintsToSolver(aWrapper, theSolver);
+
+ theConstraints[theCurve] = aWrapper;
+}
+
void PlaneGCSSolver_Storage::createAuxiliaryConstraints(const EntityWrapperPtr& theEntity)
{
if (!theEntity || theEntity->isExternal())
createEllipticArcConstraints(theEntity, mySketchSolver,
++myConstraintLastID, myAuxConstraintMap);
}
+ else if (theEntity->type() == ENTITY_BSPLINE)
+ createBSplineConstraints(theEntity, mySketchSolver, ++myConstraintLastID, myAuxConstraintMap);
}
void PlaneGCSSolver_Storage::removeAuxiliaryConstraints(const EntityWrapperPtr& theEntity)