%shared_ptr(GeomAPI_Ax2)
%shared_ptr(GeomAPI_Ax3)
%shared_ptr(GeomAPI_Box)
+%shared_ptr(GeomAPI_BSpline)
+%shared_ptr(GeomAPI_BSpline2d)
%shared_ptr(GeomAPI_Circ)
%shared_ptr(GeomAPI_Circ2d)
%shared_ptr(GeomAPI_Cone)
%include "GeomAPI_Ax2.h"
%include "GeomAPI_Ax3.h"
%include "GeomAPI_Box.h"
+%include "GeomAPI_BSpline.h"
+%include "GeomAPI_BSpline2d.h"
%include "GeomAPI_Circ.h"
%include "GeomAPI_Circ2d.h"
%include "GeomAPI_Cone.h"
#define MY_BSPLINE (*(implPtr<Handle_Geom2d_BSplineCurve>()))
+static Handle_Geom2d_BSplineCurve* newBSpline2d(
+ const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
+ const std::list<double>& theWeights,
+ const int theDegree,
+ const bool thePeriodic);
+
+
static Handle_Geom2d_BSplineCurve* newBSpline2d(
const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
const std::list<double>& theWeights,
const int theDegree,
const bool thePeriodic)
{
+ if (theKnots.empty() || theMults.empty())
+ return newBSpline2d(thePoles, theWeights, theDegree, thePeriodic);
+
// collect arrays of poles, weights, knots and multiplicities
TColgp_Array1OfPnt2d aPoles(1, (int)thePoles.size());
TColStd_Array1OfReal aWeights(1, (int)theWeights.size());
return new Handle_Geom2d_BSplineCurve(aCurve);
}
-static Handle_Geom2d_BSplineCurve* newBSpline2d(
+Handle_Geom2d_BSplineCurve* newBSpline2d(
const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& thePoles,
const std::list<double>& theWeights,
const int theDegree,
#include <BRep_Tool.hxx>
#include <ElCLib.hxx>
#include <GCPnts_UniformAbscissa.hxx>
+#include <Geom_BSplineCurve.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Circle.hxx>
return false;
}
+bool GeomAPI_Edge::isBSpline() const
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+ if (aCurve.IsNull()) // degenerative edge
+ return false;
+ while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+ aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+ return aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
+}
+
std::shared_ptr<GeomAPI_Pnt> GeomAPI_Edge::firstPoint()
{
const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
GEOMAPI_EXPORT
bool isEllipse() const;
+ /// Verifies that the edge is based on a B-spline curve
+ GEOMAPI_EXPORT
+ bool isBSpline() const;
+
/// Returns the first vertex coordinates of the edge
GEOMAPI_EXPORT
std::shared_ptr<GeomAPI_Pnt> firstPoint();
#include "GeomAPI_Ax2.h"
#include "GeomAPI_Ax3.h"
#include "GeomAPI_Box.h"
+ #include "GeomAPI_BSpline.h"
+ #include "GeomAPI_BSpline2d.h"
#include "GeomAPI_Circ.h"
#include "GeomAPI_Circ2d.h"
#include "GeomAPI_Cone.h"
%shared_ptr(GeomDataAPI_Point)
%shared_ptr(GeomDataAPI_Dir)
%shared_ptr(GeomDataAPI_Point2D)
+%shared_ptr(GeomDataAPI_Point2DArray)
// all supported interfaces
%include "GeomDataAPI_Point.h"
%include "GeomDataAPI_Dir.h"
%include "GeomDataAPI_Point2D.h"
+%include "GeomDataAPI_Point2DArray.h"
template<class T> std::shared_ptr<T> castTo(std::shared_ptr<ModelAPI_Attribute> theObject);
%template(geomDataAPI_Point) castTo<GeomDataAPI_Point>;
%template(geomDataAPI_Dir) castTo<GeomDataAPI_Dir>;
%template(geomDataAPI_Point2D) castTo<GeomDataAPI_Point2D>;
+%template(geomDataAPI_Point2DArray) castTo<GeomDataAPI_Point2DArray>;
#include "GeomDataAPI_Point.h"
#include "GeomDataAPI_Dir.h"
#include "GeomDataAPI_Point2D.h"
+ #include "GeomDataAPI_Point2DArray.h"
#include <memory>
#include <string>
%typecheck(SWIG_TYPECHECK_POINTER) std::list<ModelHighAPI_Double>, const std::list<ModelHighAPI_Double> & {
if (PySequence_Check($input)) {
+ $1 = 1;
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;
}
+%typemap(in) const std::list<ModelHighAPI_Integer> & (std::list<ModelHighAPI_Integer> temp) {
+ ModelHighAPI_Integer * temp_int;
+ 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(ModelHighAPI_Integer(PyLong_AsLong(item)));
+ } else if (PyUnicode_Check(item)) {
+ temp.push_back(ModelHighAPI_Integer(PyUnicode_AsUTF8(item)));
+ } else if ((SWIG_ConvertPtr(item, (void **)&temp_int, $1_descriptor, SWIG_POINTER_EXCEPTION)) == 0) {
+ temp.push_back(*temp_int);
+ } else {
+ PyErr_SetString(PyExc_ValueError, "argument must be a list of ModelHighAPI_Integer, int or string.");
+ return NULL;
+ }
+ Py_DECREF(item);
+ }
+ $1 = &temp;
+ } else {
+ PyErr_SetString(PyExc_ValueError, "argument must be a list of ModelHighAPI_Integer, int or string.");
+ return NULL;
+ }
+}
+
+%typecheck(SWIG_TYPECHECK_POINTER) std::list<ModelHighAPI_Integer>, const std::list<ModelHighAPI_Integer> & {
+ if (PySequence_Check($input)) {
+ $1 = 1;
+ for (Py_ssize_t i = 0; i < PySequence_Size($input) && $1; ++i) {
+ PyObject * item = PySequence_GetItem($input, i);
+ $1 = ((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"
return *this;
}
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<ModelAPI_AttributeIntArray>& 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_AttributeDouble>& theAttrReal)
{
class ModelAPI_AttributeBoolean;
class ModelAPI_AttributeDouble;
class ModelAPI_AttributeDoubleArray;
+class ModelAPI_AttributeIntArray;
class ModelAPI_AttributeInteger;
class ModelAPI_AttributeRefAttr;
class ModelAPI_AttributeRefAttrList;
/// Dump AttributeInteger
MODELHIGHAPI_EXPORT
ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeInteger>& theAttrInt);
+ /// Dump AttributeIntArray
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeIntArray>& theArray);
/// Dump AttributeDouble
MODELHIGHAPI_EXPORT
ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeDouble>& theAttrReal);
return aMajorAxisEnd ? aMajorAxisEnd->pnt() : std::shared_ptr<GeomAPI_Pnt2d>();
}
-static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject)
+static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnBSpline(const FeaturePtr& theFeature,
+ const CompositeFeaturePtr& theSketch)
+{
+ GeomAPI_Edge anEdge(theFeature->lastResult()->shape());
+ GeomPointPtr aMiddle = anEdge.middlePoint();
+
+ std::shared_ptr<SketchPlugin_Sketch> aSketch =
+ std::dynamic_pointer_cast<SketchPlugin_Sketch>(theSketch);
+ return aSketch->to2D(aMiddle);
+}
+
+static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject,
+ const CompositeFeaturePtr& theSketch)
{
std::shared_ptr<GeomAPI_Pnt2d> aMiddlePoint;
FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
aMiddlePoint = pointOnEllipse(aFeature);
else if (aFeatureKind == SketchPlugin_EllipticArc::ID())
aMiddlePoint = pointOnEllipse(aFeature, false);
+ else if (aFeatureKind == SketchPlugin_BSpline::ID())
+ aMiddlePoint = middlePointOnBSpline(aFeature, theSketch);
}
return aMiddlePoint;
}
if (aMessage->movedAttribute())
anOriginalPosition = pointCoordinates(aMessage->movedAttribute());
else
- anOriginalPosition = middlePoint(aMessage->movedObject());
+ anOriginalPosition = middlePoint(aMessage->movedObject(), compositeFeature());
if (!anOriginalPosition)
return; // something has gone wrong, do not process movement
TestCreateArcByThreePoints.py
TestCreateArcByTransversalLine.py
TestCreateArcChangeType.py
+ TestCreateBSpline.py
TestCreateCircleByCenterAndPassed.py
TestCreateCircleByThreePoints.py
TestCreateCircleChangeType.py
TestMultiTranslation.py
TestPresentation.py
TestProjection.py
+ TestProjectionBSpline.py
TestProjectionEllipse.py
TestProjectionEllipticArc.py
TestProjectionIntoResult.py
TestProjectionUpdate.py
TestRectangle.py
TestRemainingDoF.py
+ TestRemoveBSpline.py
TestRemoveEllipse.py
TestRemoveEllipticArc.py
TestRemoveSketch.py
if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE})
ADD_UNIT_TESTS(
TestMoveArc.py
+ TestMoveBSpline.py
TestMoveCircle.py
TestMoveEllipse.py
TestMoveEllipticArc.py
//// fillCharacteristicPoints();
//// }
}
-//// else if (theID == CENTER_ID() || theID == FIRST_FOCUS_ID() ||
-//// theID == START_POINT_ID() || theID == END_POINT_ID())
-//// fillCharacteristicPoints();
+ else if (theID == POLES_ID()) {
+ AttributePoint2DArrayPtr aPolesArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ attribute(START_ID()))->setValue(aPolesArray->pnt(0));
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ attribute(END_ID()))->setValue(aPolesArray->pnt(aPolesArray->size() - 1));
+ }
//// else if (theID == REVERSED_ID() && myParamDelta == 0.0)
//// myParamDelta = 2.0 * PI;
}
--- /dev/null
+# Copyright (C) 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
+#
+
+"""
+ Test creation of B-spline curve
+"""
+
+import unittest
+from salome.shaper import model
+
+from GeomAPI import *
+from SketchAPI import *
+
+__updated__ = "2020-01-17"
+
+class TestBSpline(unittest.TestCase):
+ def setUp(self):
+ model.begin()
+ self.myDocument = model.moduleDocument()
+ self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
+ self.myPoles = [GeomAPI_Pnt2d(50., 50.), GeomAPI_Pnt2d(70., 70.), GeomAPI_Pnt2d(80., 30.), GeomAPI_Pnt2d(50., 10.), GeomAPI_Pnt2d(10., -30.)]
+ self.myPolesCoordinates = [(50., 50.), (70., 70.), (80., 30.), (50., 10.), (10., -30.)]
+ self.myDegree = 3;
+ self.myDOF = 0
+ self.myNbPoints = 0
+ self.myNbLines = 0
+ self.myNbSplines = 0
+
+ def tearDown(self):
+ self.checkDOF()
+ model.end()
+ model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
+ model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
+ model.testNbSubFeatures(self.mySketch, "SketchBSpline", self.myNbSplines)
+
+
+ def checkDOF(self):
+ self.assertEqual(model.dof(self.mySketch), self.myDOF)
+
+
+ def test_bspline_by_coordinates(self):
+ """ Test 1. Create B-spline curve by coordinates of its poles
+ """
+ self.mySpline = self.mySketch.addSpline(self.myPolesCoordinates)
+ self.myDOF += len(self.myPolesCoordinates) * 2
+ self.myNbSplines += 1
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_by_poles(self):
+ """ Test 2. Create B-spline curve by poles
+ """
+ self.mySpline = self.mySketch.addSpline(self.myPoles)
+ self.myDOF += len(self.myPoles) * 2
+ self.myNbSplines += 1
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_by_degree_and_poles(self):
+ """ Test 3. Create B-spline curve by poles and degree
+ """
+ self.myDegree = 4
+ self.mySpline = self.mySketch.addSpline(self.myDegree, self.myPoles)
+ self.myDOF += len(self.myPoles) * 2
+ self.myNbSplines += 1
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_by_poles_and_weights(self):
+ """ Test 4. Create B-spline curve by poles and weights
+ """
+ self.mySpline = self.mySketch.addSpline(self.myPoles, [1, 2, 3, 2, 1])
+ self.myDOF += len(self.myPoles) * 2
+ self.myNbSplines += 1
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_by_parametric(self):
+ """ Test 5. Create B-spline curve by whole set of parameters
+ """
+ self.myDegree = 5
+ self.myPolesCoordinates = [(-79.8578274581199, 75.5284518447357),
+ (-64.6205376770376, 62.7428476092882),
+ (-49.3832478959552, 49.9572433738407),
+ (-34.1459581148729, 37.1716391383932),
+ (-18.9086683337906, 24.3860349029457),
+ (-3.55842111132817, 11.5056481200973),
+ (-3.37993197286247, 11.42995541724),
+ (-3.1778022626919, 11.4565662984205),
+ (-3.02498570721059, 11.575876223351),
+ (8.46852511720001, 27.9903107977019),
+ (19.8774589601206, 44.2839569245217),
+ (31.2863928030413, 60.5776030513415),
+ (42.6953266459619, 76.8712491781612),
+ (54.1042604888826, 93.164895304981)
+ ]
+ self.mySpline = self.mySketch.addSpline(self.myDegree,
+ self.myPolesCoordinates,
+ [1, 1, 1, 1, 1, 1, 0.957903314642061, 0.95790331464206, 1, 1, 1, 1, 1, 1],
+ [-494.543457494654, 500, 507.372773368102, 1501.91623086297],
+ [6, 4, 4, 6])
+ self.myDOF += len(self.myPolesCoordinates) * 2
+ self.myNbSplines += 1
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_linear(self):
+ """ Test 6. Create B-spline curve by 2 poles
+ """
+ self.myDegree = 1
+ self.mySpline = self.mySketch.addSpline(self.myPoles[:2])
+ self.myDOF += 4
+ self.myNbSplines += 1
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_parabola(self):
+ """ Test 7. Create B-spline curve by 3 poles
+ """
+ self.myDegree = 2
+ self.mySpline = self.mySketch.addSpline(self.myPoles[:3])
+ self.myDOF += 6
+ self.myNbSplines += 1
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_with_poles(self):
+ """ Test 8. Create B-spline curve and points coincident with its poles
+ """
+ self.mySpline = self.mySketch.addSpline(self.myPoles)
+ self.mySpline.controlPoles(regular = [0, 2], auxiliary = [1, 3])
+ self.myDOF += len(self.myPoles) * 2
+ self.myNbSplines += 1
+ self.myNbPoints += 4
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+ def test_bspline_with_polygon(self):
+ """ Test 9. Create B-spline curve and its control polygon
+ """
+ self.mySpline = self.mySketch.addSpline(self.myPoles)
+ self.mySpline.controlPolygon(regular = [0, 2], auxiliary = [1, 3])
+ self.myDOF += len(self.myPoles) * 2
+ self.myNbSplines += 1
+ self.myNbLines += 4
+ model.do()
+
+ assert(self.mySpline.feature())
+ assert(self.mySpline.feature().error() == "")
+ assert(self.mySpline.degree().value() == self.myDegree)
+
+if __name__ == "__main__":
+ test_program = unittest.main(exit=False)
+ assert test_program.result.wasSuccessful(), "Test failed"
+ assert model.checkPythonDump()
--- /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
+#
+
+"""
+ Test movement of the B-spline curve
+"""
+
+import unittest
+import math
+from GeomAPI import *
+from GeomDataAPI import geomDataAPI_Point2DArray
+from SketchAPI import *
+from salome.shaper import model
+
+__updated__ = "2020-01-20"
+
+class TestMoveBSpline(unittest.TestCase):
+ def setUp(self):
+ model.begin()
+ self.myDocument = model.moduleDocument()
+ self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
+ self.myPoles = [GeomAPI_Pnt2d(20., 50.),
+ GeomAPI_Pnt2d(70., 70.),
+ GeomAPI_Pnt2d(80., 30.),
+ GeomAPI_Pnt2d(50., 10.),
+ GeomAPI_Pnt2d(90., -30.)]
+ self.mySpline = self.mySketch.addSpline(self.myPoles)
+ self.myDOF = len(self.myPoles) * 2
+ model.do()
+ self.checkDOF()
+
+ def tearDown(self):
+ self.checkDOF()
+ model.end()
+
+ def checkDOF(self):
+ self.assertEqual(model.dof(self.mySketch), self.myDOF)
+
+ def checkPointCoordinates(self, thePoint, theCoordinates):
+ aCoord = []
+ if issubclass(type(theCoordinates), GeomAPI_Pnt2d):
+ aCoord = [theCoordinates.x(), theCoordinates.y()]
+ else:
+ aCoord = theCoordinates
+ DIGITS = 7 - math.floor(math.log10(math.hypot(aCoord[0], aCoord[1])))
+ self.assertAlmostEqual(thePoint.x(), aCoord[0], DIGITS)
+ self.assertAlmostEqual(thePoint.y(), aCoord[1], DIGITS)
+
+ def checkPoles(self, theBSpline, theCoordinates):
+ poles = theBSpline.poles()
+ for index, point in zip(range(0, len(theCoordinates)), theCoordinates):
+ self.checkPointCoordinates(poles.pnt(index), point)
+
+ def fixPoint(self, thePoint):
+ self.mySketch.setFixed(thePoint)
+ self.myDOF -= 2
+ model.do()
+ self.checkDOF()
+
+
+ def test_move_free_bspline(self):
+ """ Test 1. Movement of a free B-spline dragging the edge
+ """
+ oldPosition = GeomAPI_Edge(self.mySpline.defaultResult().shape()).middlePoint()
+ newPosition = GeomAPI_Pnt2d(120., 90.)
+ self.mySketch.move(self.mySpline.defaultResult(), newPosition)
+ model.do()
+
+ # plane is XOY, no need to project oldPosition point
+ dx = newPosition.x() - oldPosition.x()
+ dy = newPosition.y() - oldPosition.y()
+
+ newPoles = []
+ for pole in self.myPoles:
+ newPoles.append(GeomAPI_Pnt2d(pole.x() + dx, pole.y() + dy))
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_start_point(self):
+ """ Test 2. Movement of start point of a free B-spline curve
+ """
+ newPoles = self.myPoles
+
+ newPoles[0].setX(newPoles[0].x() - 20.)
+ newPoles[0].setY(newPoles[0].y() + 10.)
+ self.mySketch.move(self.mySpline.startPoint(), newPoles[0])
+ model.do()
+
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_end_point(self):
+ """ Test 3. Movement of end point of a free B-spline curve
+ """
+ newPoles = self.myPoles
+
+ newPoles[-1].setX(newPoles[-1].x() + 20.)
+ newPoles[-1].setY(newPoles[-1].y() + 10.)
+ self.mySketch.move(self.mySpline.endPoint(), newPoles[-1])
+ model.do()
+
+ self.checkPoles(self.mySpline, newPoles)
+
+
+ def test_move_bspline_with_start_point_fixed(self):
+ """ Test 4. Movement of a B-spline dragging the edge when start point is fixed
+ """
+ self.fixPoint(self.mySpline.startPoint())
+ model.do()
+
+ oldPosition = GeomAPI_Edge(self.mySpline.defaultResult().shape()).middlePoint()
+ newPosition = GeomAPI_Pnt2d(120., 90.)
+ self.mySketch.move(self.mySpline.defaultResult(), newPosition)
+ model.do()
+
+ # plane is XOY, no need to project oldPosition point
+ dx = newPosition.x() - oldPosition.x()
+ dy = newPosition.y() - oldPosition.y()
+
+ newPoles = [self.myPoles[0]]
+ for pole in self.myPoles[1:]:
+ newPoles.append(GeomAPI_Pnt2d(pole.x() + dx, pole.y() + dy))
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_start_point_with_start_point_fixed(self):
+ """ Test 5. Movement of start point of a free B-spline curve has no result if the first pole is fixed
+ """
+ self.fixPoint(self.mySpline.startPoint())
+ model.do()
+
+ self.mySketch.move(self.mySpline.startPoint(), self.myPoles[0].x() - 10., self.myPoles[0].y() + 10.)
+ model.do()
+
+ self.checkPoles(self.mySpline, self.myPoles)
+
+ def test_move_end_point_with_start_point_fixed(self):
+ """ Test 6. Movement of end point of a free B-spline curve when start point is fixed
+ """
+ self.fixPoint(self.mySpline.startPoint())
+ model.do()
+
+ newPoles = self.myPoles
+
+ newPoles[-1].setX(newPoles[-1].x() + 20.)
+ newPoles[-1].setY(newPoles[-1].y() + 10.)
+ self.mySketch.move(self.mySpline.endPoint(), newPoles[-1])
+ model.do()
+
+ self.checkPoles(self.mySpline, newPoles)
+
+
+ def test_move_bspline_with_end_point_fixed(self):
+ """ Test 7. Movement of a B-spline dragging the edge when end point is fixed
+ """
+ self.fixPoint(self.mySpline.endPoint())
+ model.do()
+
+ oldPosition = GeomAPI_Edge(self.mySpline.defaultResult().shape()).middlePoint()
+ newPosition = GeomAPI_Pnt2d(120., 90.)
+ self.mySketch.move(self.mySpline.defaultResult(), newPosition)
+ model.do()
+
+ # plane is XOY, no need to project oldPosition point
+ dx = newPosition.x() - oldPosition.x()
+ dy = newPosition.y() - oldPosition.y()
+
+ newPoles = []
+ for pole in self.myPoles[:-1]:
+ newPoles.append(GeomAPI_Pnt2d(pole.x() + dx, pole.y() + dy))
+ newPoles.append(self.myPoles[-1])
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_start_point_with_end_point_fixed(self):
+ """ Test 8. Movement of start point of a free B-spline curve when end point is fixed
+ """
+ self.fixPoint(self.mySpline.endPoint())
+ model.do()
+
+ newPoles = self.myPoles
+
+ newPoles[0].setX(newPoles[0].x() + 20.)
+ newPoles[0].setY(newPoles[0].y() + 10.)
+ self.mySketch.move(self.mySpline.startPoint(), self.myPoles[0])
+ model.do()
+
+ self.checkPoles(self.mySpline, self.myPoles)
+
+ def test_move_end_point_with_end_point_fixed(self):
+ """ Test 9. Movement of end point of a free B-spline curve has no result if the last pole is fixed
+ """
+ self.fixPoint(self.mySpline.endPoint())
+ model.do()
+
+ self.mySketch.move(self.mySpline.endPoint(), self.myPoles[-1].x() + 10., self.myPoles[-1].y() + 10.)
+ model.do()
+
+ self.checkPoles(self.mySpline, self.myPoles)
+
+
+ def test_move_fixed_bspline(self):
+ """ Test 10. Movement of a fully fixed B-spline
+ """
+ self.mySketch.setFixed(self.mySpline.defaultResult())
+ self.myDOF = 0
+ model.do()
+
+ newPosition = GeomAPI_Pnt2d(120., 90.)
+ self.mySketch.move(self.mySpline.defaultResult(), newPosition)
+ model.do()
+
+ self.checkPoles(self.mySpline, self.myPoles)
+
+ def test_move_start_point_of_fixed_bspline(self):
+ """ Test 11. Movement of start point of a fully fixed B-spline curve
+ """
+ self.mySketch.setFixed(self.mySpline.defaultResult())
+ self.myDOF = 0
+ model.do()
+
+ self.mySketch.move(self.mySpline.startPoint(), self.myPoles[0].x() + 10., self.myPoles[0].y() + 10.)
+ model.do()
+
+ self.checkPoles(self.mySpline, self.myPoles)
+
+ def test_move_end_point_of_fixed_bspline(self):
+ """ Test 12. Movement of end point of a fully fixed B-spline curve
+ """
+ self.mySketch.setFixed(self.mySpline.defaultResult())
+ self.myDOF = 0
+ model.do()
+
+ self.mySketch.move(self.mySpline.endPoint(), self.myPoles[-1].x() + 10., self.myPoles[-1].y() + 10.)
+ model.do()
+
+ self.checkPoles(self.mySpline, self.myPoles)
+
+
+ def test_move_bspline_with_fixed_pole(self):
+ """ Test 13. Movement of a B-spline curve with fixed pole
+ """
+ [Point_1, Point_2, Point_3, Point_4, Point_5] = self.mySpline.controlPoles(auxiliary = [0, 1, 2, 3, 4])
+ model.do()
+
+ self.fixPoint(Point_2.defaultResult())
+ model.do()
+
+ oldPosition = GeomAPI_Edge(self.mySpline.defaultResult().shape()).middlePoint()
+ newPosition = GeomAPI_Pnt2d(120., 90.)
+ self.mySketch.move(self.mySpline.defaultResult(), newPosition)
+ model.do()
+
+ # plane is XOY, no need to project oldPosition point
+ dx = newPosition.x() - oldPosition.x()
+ dy = newPosition.y() - oldPosition.y()
+
+ newPoles = []
+ for pole in self.myPoles:
+ newPoles.append(GeomAPI_Pnt2d(pole.x() + dx, pole.y() + dy))
+ newPoles[1].setX(newPoles[1].x() - dx)
+ newPoles[1].setY(newPoles[1].y() - dy)
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_start_point_with_fixed_pole(self):
+ """ Test 14. Movement of start point of a B-spline curve with fixed pole
+ """
+ [Point_1, Point_2, Point_3, Point_4, Point_5] = self.mySpline.controlPoles(auxiliary = [0, 1, 2, 3, 4])
+ model.do()
+
+ self.fixPoint(Point_2.defaultResult())
+ model.do()
+
+ newPoles = self.myPoles
+
+ newPoles[0].setX(newPoles[0].x() + 20.)
+ newPoles[0].setY(newPoles[0].y() + 10.)
+ self.mySketch.move(self.mySpline.startPoint(), newPoles[0])
+ model.do()
+
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_end_point_with_fixed_pole(self):
+ """ Test 15. Movement of end point of a B-spline curve with fixed pole
+ """
+ [Point_1, Point_2, Point_3, Point_4, Point_5] = self.mySpline.controlPoles(auxiliary = [0, 1, 2, 3, 4])
+ model.do()
+
+ self.fixPoint(Point_2.defaultResult())
+ model.do()
+
+ newPoles = self.myPoles
+
+ newPoles[-1].setX(newPoles[-1].x() + 20.)
+ newPoles[-1].setY(newPoles[-1].y() + 10.)
+ self.mySketch.move(self.mySpline.endPoint(), newPoles[-1])
+ model.do()
+
+ self.checkPoles(self.mySpline, newPoles)
+
+
+ def test_move_bspline_with_fixed_segment(self):
+ """ Test 16. Movement of a B-spline curve with fixed control segment
+ """
+ [Line_1, Line_2, Line_3, Line_4] = self.mySpline.controlPolygon(auxiliary = [0, 1, 2, 3])
+ model.do()
+
+ self.mySketch.setFixed(Line_1.defaultResult())
+ self.myDOF -= 4
+ model.do()
+
+ oldPosition = GeomAPI_Edge(self.mySpline.defaultResult().shape()).middlePoint()
+ newPosition = GeomAPI_Pnt2d(120., 90.)
+ self.mySketch.move(self.mySpline.defaultResult(), newPosition)
+ model.do()
+
+ # plane is XOY, no need to project oldPosition point
+ dx = newPosition.x() - oldPosition.x()
+ dy = newPosition.y() - oldPosition.y()
+
+ newPoles = [self.myPoles[0], self.myPoles[1]]
+ for pole in self.myPoles[2:]:
+ newPoles.append(GeomAPI_Pnt2d(pole.x() + dx, pole.y() + dy))
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_start_point_with_fixed_segment(self):
+ """ Test 17. Movement of start point of a B-spline curve with fixed control segment
+ """
+ [Line_1, Line_2, Line_3, Line_4] = self.mySpline.controlPolygon(auxiliary = [0, 1, 2, 3])
+ model.do()
+
+ self.mySketch.setFixed(Line_1.defaultResult())
+ self.myDOF -= 4
+ model.do()
+
+ self.mySketch.move(self.mySpline.startPoint(), self.myPoles[0].x() + 10., self.myPoles[0].y() - 20.)
+ model.do()
+
+ self.checkPoles(self.mySpline, self.myPoles)
+
+ def test_move_end_point_with_fixed_segment(self):
+ """ Test 18. Movement of end point of a B-spline curve with fixed control segment
+ """
+ [Line_1, Line_2, Line_3, Line_4] = self.mySpline.controlPolygon(auxiliary = [0, 1, 2, 3])
+ model.do()
+
+ self.mySketch.setFixed(Line_1.defaultResult())
+ self.myDOF -= 4
+ model.do()
+
+ newPoles = self.myPoles
+
+ newPoles[-1].setX(newPoles[-1].x() + 20.)
+ newPoles[-1].setY(newPoles[-1].y() + 10.)
+ self.mySketch.move(self.mySpline.endPoint(), newPoles[-1])
+ model.do()
+
+ self.checkPoles(self.mySpline, newPoles)
+
+
+ def test_move_pole_of_free_bspline(self):
+ """ Test 19. Movement of a pole of a B-spline curve
+ """
+ [Point_1, Point_2, Point_3, Point_4, Point_5] = self.mySpline.controlPoles(auxiliary = [0, 1, 2, 3, 4])
+ [Line_1, Line_2, Line_3, Line_4] = self.mySpline.controlPolygon(auxiliary = [0, 1, 2, 3])
+ model.do()
+
+ newPoles = self.myPoles
+
+ newPoles[2].setX(newPoles[2].x() + 20.)
+ newPoles[2].setY(newPoles[2].y() + 20.)
+ self.mySketch.move(SketchAPI_Point(Point_3).coordinates(), newPoles[2])
+ model.do()
+
+ self.checkPoles(self.mySpline, newPoles)
+
+ def test_move_segment_of_free_bspline(self):
+ """ Test 20. Movement of a control segment of a B-spline curve
+ """
+ [Point_1, Point_2, Point_3, Point_4, Point_5] = self.mySpline.controlPoles(auxiliary = [0, 1, 2, 3, 4])
+ [Line_1, Line_2, Line_3, Line_4] = self.mySpline.controlPolygon(auxiliary = [0, 1, 2, 3])
+ model.do()
+
+ oldPosition = GeomAPI_Pnt2d(0.5 * (self.myPoles[2].x() + self.myPoles[3].x()),
+ 0.5 * (self.myPoles[2].y() + self.myPoles[3].y()))
+ newPosition = GeomAPI_Pnt2d(120., 90.)
+ self.mySketch.move(SketchAPI_Line(Line_3).defaultResult(), newPosition)
+ model.do()
+
+ dx = newPosition.x() - oldPosition.x()
+ dy = newPosition.y() - oldPosition.y()
+
+ newPoles = self.myPoles
+ newPoles[2].setX(newPoles[2].x() + dx)
+ newPoles[2].setY(newPoles[2].y() + dy)
+ newPoles[3].setX(newPoles[3].x() + dx)
+ newPoles[3].setY(newPoles[3].y() + dy)
+
+ self.checkPoles(self.mySpline, newPoles)
+
+
+
+if __name__ == "__main__":
+ test_program = unittest.main(exit=False)
+ assert test_program.result.wasSuccessful(), "Test failed"
+ assert model.checkPythonDump()
anEllipticArcPnt4.setValue(-10, 0)
assert(featureToPresentation(anEllipticArc).getAISObject(None) is not None)
aSession.finishOperation()
+
+# Test presentation for MacroBSpline on low-level
+aSession.startOperation()
+aBSpline = aSketchFeature.addFeature("SketchMacroBSpline")
+aPoles = geomDataAPI_Point2DArray(aBSpline.attribute("poles"))
+aPoles.setSize(4)
+aPoles.setPnt(0, 0, 0)
+aPoles.setPnt(1, 10, 0)
+aPoles.setPnt(2, 10, 10)
+aPoles.setPnt(3, 0, 10)
+aWeights = aBSpline.data().realArray("weights")
+aWeights.setSize(4)
+aWeights.setValue(0, 1)
+aWeights.setValue(1, 2)
+aWeights.setValue(2, 2)
+aWeights.setValue(3, 1)
+aBSpline.boolean("need_control_poly").setValue(True)
+assert(featureToPresentation(aBSpline).getAISObject(None) is not None)
+aSession.finishOperation()
--- /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
+#
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10, 180)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Cylinder_1_1/Face_5"))
+SketchCircle_1 = Sketch_1.addCircle(-0.87355746875896, 7.873567272779828, 3.095312696967586)
+model.do()
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), [model.selection("SOLID", "Cylinder_1_1")])
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "ExtrusionCut_1_1")], model.selection("EDGE", "PartSet/OX"), 45)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "[Rotation_1_1/MF:Rotated&Cylinder_1_1/Face_1][(Rotation_1_1/MF:Rotated&Cylinder_1_1/Face_1)(Rotation_1_1/MF:Rotated&Cylinder_1_1/Face_5)(Rotation_1_1/MF:Rotated&Cylinder_1_1/Face_4)(Rotation_1_1/MF:Rotated&Cylinder_1_1/Face_3)2]")], False)
+
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchProjection_1 = Sketch_2.addProjection(model.selection("EDGE", "Edge_1_1"), True)
+SketchBSpline_1 = SketchProjection_1.createdFeature()
+model.do()
+
+Sketch_3 = model.addSketch(Part_1_doc, model.standardPlane("XOZ"))
+SketchProjection_2 = Sketch_3.addProjection(model.selection("EDGE", "Edge_1_1"), True)
+SketchBSpline_2 = SketchProjection_2.createdFeature()
+model.do()
+
+Sketch_4 = model.addSketch(Part_1_doc, model.standardPlane("YOZ"))
+SketchProjection_3 = Sketch_4.addProjection(model.selection("EDGE", "Edge_1_1"), True)
+SketchBSpline_3 = SketchProjection_3.createdFeature()
+model.do()
+
+model.end()
+
+from GeomAPI import *
+import math
+
+TOLERANCE = 1.e-7
+
+def checkProjection(theBSpline3D, theBSpline2D, theFlags):
+ assert(theBSpline2D.isEdge() and theBSpline2D.edge().isBSpline())
+ poles2D = GeomAPI_BSpline(GeomAPI_Curve(theBSpline2D)).poles()
+ poles3D = theBSpline3D.poles()
+ assert(poles2D.size() == poles3D.size())
+ for p2d, p3d in zip(poles2D, poles3D):
+ assert(math.fabs((p2d.x() - p3d.x()) * theFlags.x()) < TOLERANCE and
+ math.fabs((p2d.y() - p3d.y()) * theFlags.y()) < TOLERANCE and
+ math.fabs((p2d.z() - p3d.z()) * theFlags.z()) < TOLERANCE)
+
+
+bspline0 = GeomAPI_BSpline(GeomAPI_Curve(Edge_1.results()[-1].resultSubShapePair()[0].shape()))
+
+bsplineShape1 = SketchBSpline_1.results()[-1].resultSubShapePair()[0].shape()
+checkProjection(bspline0, bsplineShape1, GeomAPI_Pnt(1, 1, 0))
+
+bsplineShape2 = SketchBSpline_2.results()[-1].resultSubShapePair()[0].shape()
+checkProjection(bspline0, bsplineShape2, GeomAPI_Pnt(1, 0, 1))
+
+bsplineShape3 = SketchBSpline_3.results()[-1].resultSubShapePair()[0].shape()
+checkProjection(bspline0, bsplineShape3, GeomAPI_Pnt(0, 1, 1))
+
+assert(model.checkPythonDump())
--- /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
+#
+
+"""
+ Test removing B-spline curve and its construstion elements
+"""
+
+from salome.shaper import model
+from ModelAPI import *
+
+def assertNbSubs(theSketch, theNbPoints, theNbLines, theNbEllipses, theNbInternalConstraints):
+ model.testNbSubFeatures(theSketch, "SketchPoint", theNbPoints)
+ model.testNbSubFeatures(theSketch, "SketchLine", theNbLines)
+ model.testNbSubFeatures(theSketch, "SketchBSpline", theNbEllipses)
+ model.testNbSubFeatures(theSketch, "SketchConstraintCoincidenceInternal", theNbInternalConstraints)
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchBSpline_1_poles = [(-30, -10), (-15, 20), (0, -10), (15, 20), (30, -10)]
+SketchBSpline_1 = Sketch_1.addSpline(SketchBSpline_1_poles)
+controlPoles = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3, 4])
+controlLines = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+model.do()
+model.end()
+
+DEFAULT_DOF = len(SketchBSpline_1_poles) * 2
+DEFAULT_POINTS = len(SketchBSpline_1_poles)
+DEFAULT_LINES = len(SketchBSpline_1_poles) - 1
+DEFAULT_BSPLINES = 1
+DEAFULT_INTERNALS = len(controlPoles) + len(controlLines) * 2
+
+assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES, DEFAULT_BSPLINES, DEAFULT_INTERNALS)
+assert(model.dof(Sketch_1) == DEFAULT_DOF)
+
+# Test 1. Remove auxiliary points one by one.
+for pnt in controlPoles:
+ model.begin()
+ removeFeaturesAndReferences(FeatureSet([pnt.feature()]))
+ model.end()
+
+ assertNbSubs(Sketch_1, DEFAULT_POINTS - 1, DEFAULT_LINES, DEFAULT_BSPLINES, DEAFULT_INTERNALS - 1)
+ assert(model.dof(Sketch_1) == DEFAULT_DOF)
+ model.undo()
+ assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES, DEFAULT_BSPLINES, DEAFULT_INTERNALS)
+ assert(model.dof(Sketch_1) == DEFAULT_DOF)
+
+# Test 2. Remove auxiliary lines one by one.
+for ln in controlLines:
+ model.begin()
+ removeFeaturesAndReferences(FeatureSet([ln.feature()]))
+ model.end()
+
+ assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES - 1, DEFAULT_BSPLINES, DEAFULT_INTERNALS - 2)
+ assert(model.dof(Sketch_1) == DEFAULT_DOF)
+ model.undo()
+ assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES, DEFAULT_BSPLINES, DEAFULT_INTERNALS)
+ assert(model.dof(Sketch_1) == DEFAULT_DOF)
+
+# Test 3. Remove the B-spline curve.
+model.begin()
+removeFeaturesAndReferences(FeatureSet([SketchBSpline_1.feature()]))
+model.end()
+
+assertNbSubs(Sketch_1, 0, 0, 0, 0)
+assert(model.dof(Sketch_1) == 0)
+model.undo()
+assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES, DEFAULT_BSPLINES, DEAFULT_INTERNALS)
+assert(model.dof(Sketch_1) == DEFAULT_DOF)
+
+# Test 4. Remove some construction elements, make non-auxiliary a couple of the rest and check the dumping.
+model.begin()
+partSet = model.moduleDocument()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchBSpline_2_poles = [(-30, -10), (-15, -40), (0, -10), (15, -40), (30, -10)]
+SketchBSpline_2 = Sketch_2.addSpline(SketchBSpline_2_poles)
+controlPoles2 = SketchBSpline_2.controlPoles(auxiliary = [0, 1, 2, 3, 4])
+controlLines2 = SketchBSpline_2.controlPolygon(auxiliary = [0, 1, 2, 3])
+model.do()
+model.end()
+
+model.begin()
+controlPoles2[1].setAuxiliary(False)
+controlLines2[2].setAuxiliary(False)
+removeFeaturesAndReferences(FeatureSet([controlPoles2[2].feature(), controlLines2[0].feature()]))
+model.end()
+
+assertNbSubs(Sketch_2, DEFAULT_POINTS - 1, DEFAULT_LINES - 1, DEFAULT_BSPLINES, DEAFULT_INTERNALS - 3)
+
+assert(model.checkPythonDump())