From ed5df03349ef8e7a9ab592a6a52df0a801d5af14 Mon Sep 17 00:00:00 2001 From: azv Date: Wed, 2 Oct 2019 13:55:32 +0300 Subject: [PATCH] Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003) Unit tests for creation and destruction of elliptic arcs. --- src/SketchAPI/SketchAPI_EllipticArc.cpp | 18 +- src/SketchAPI/SketchAPI_MacroEllipse.cpp | 5 +- src/SketchAPI/SketchAPI_MacroEllipse.h | 3 +- src/SketchAPI/SketchAPI_MacroEllipticArc.cpp | 4 +- src/SketchAPI/SketchAPI_Sketch.cpp | 13 - src/SketchAPI/SketchAPI_Sketch.h | 8 - src/SketchPlugin/CMakeLists.txt | 3 + src/SketchPlugin/SketchPlugin_EllipticArc.cpp | 48 ++- .../Test/TestCreateEllipticArc.py | 379 ++++++++++++++++++ .../Test/TestCreateEllipticArcByExternal.py | 142 +++++++ .../Test/TestRemoveEllipticArc.py | 107 +++++ 11 files changed, 681 insertions(+), 49 deletions(-) create mode 100644 src/SketchPlugin/Test/TestCreateEllipticArc.py create mode 100644 src/SketchPlugin/Test/TestCreateEllipticArcByExternal.py create mode 100644 src/SketchPlugin/Test/TestRemoveEllipticArc.py diff --git a/src/SketchAPI/SketchAPI_EllipticArc.cpp b/src/SketchAPI/SketchAPI_EllipticArc.cpp index 27275096c..a3e39a2b6 100644 --- a/src/SketchAPI/SketchAPI_EllipticArc.cpp +++ b/src/SketchAPI/SketchAPI_EllipticArc.cpp @@ -92,11 +92,12 @@ void SketchAPI_EllipticArc::setByCenterFocusAndPoints(double theCenterX, double double theEndX, double theEndY, bool theInversed) { - fillAttribute(center(), theCenterX, theCenterY); - fillAttribute(firstFocus(), theFocusX, theFocusY); - fillAttribute(startPoint(), theStartX, theStartY); - fillAttribute(endPoint(), theEndX, theEndY); + // the order of attribute initialization is reversed to avoid odd recalculation of an elliptic arc fillAttribute(theInversed, reversed()); + fillAttribute(endPoint(), theEndX, theEndY); + fillAttribute(startPoint(), theStartX, theStartY); + fillAttribute(firstFocus(), theFocusX, theFocusY); + fillAttribute(center(), theCenterX, theCenterY); execute(); } @@ -108,11 +109,12 @@ void SketchAPI_EllipticArc::setByCenterFocusAndPoints( const std::shared_ptr& theEnd, bool theInversed) { - fillAttribute(theCenter, center()); - fillAttribute(theFocus, firstFocus()); - fillAttribute(theStart, startPoint()); - fillAttribute(theEnd, endPoint()); + // the order of attribute initialization is reversed to avoid odd recalculation of an elliptic arc fillAttribute(theInversed, reversed()); + fillAttribute(theEnd, endPoint()); + fillAttribute(theStart, startPoint()); + fillAttribute(theFocus, firstFocus()); + fillAttribute(theCenter, center()); execute(); } diff --git a/src/SketchAPI/SketchAPI_MacroEllipse.cpp b/src/SketchAPI/SketchAPI_MacroEllipse.cpp index 3a4ef16d3..e833775e2 100644 --- a/src/SketchAPI/SketchAPI_MacroEllipse.cpp +++ b/src/SketchAPI/SketchAPI_MacroEllipse.cpp @@ -56,10 +56,11 @@ static CompositeFeaturePtr sketch(FeaturePtr theFeature) } -SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr& theFeature) +SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr& theFeature, + bool callInitialize) : SketchAPI_SketchEntity(theFeature) { - if (initialize()) + if (callInitialize && initialize()) mySketch = sketch(theFeature); } diff --git a/src/SketchAPI/SketchAPI_MacroEllipse.h b/src/SketchAPI/SketchAPI_MacroEllipse.h index 596a417e6..7e0103b16 100644 --- a/src/SketchAPI/SketchAPI_MacroEllipse.h +++ b/src/SketchAPI/SketchAPI_MacroEllipse.h @@ -37,7 +37,8 @@ class SketchAPI_MacroEllipse: public SketchAPI_SketchEntity public: /// Constructor without values. SKETCHAPI_EXPORT - explicit SketchAPI_MacroEllipse(const std::shared_ptr& theFeature); + explicit SketchAPI_MacroEllipse(const std::shared_ptr& theFeature, + bool callInitialize = true); /// Constructor with values. SKETCHAPI_EXPORT diff --git a/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp b/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp index bde81dfef..f76f797c5 100644 --- a/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp +++ b/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp @@ -59,7 +59,7 @@ static void fillAttribute(const std::shared_ptr& thePoint, } SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc(const FeaturePtr& theFeature) - : SketchAPI_MacroEllipse(theFeature) + : SketchAPI_MacroEllipse(theFeature, false) { } @@ -74,7 +74,7 @@ SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc( const std::shared_ptr& theArcEnd, const ModelHighAPI_RefAttr& theArcEndRef, const bool theReversed) - : SketchAPI_MacroEllipse(theFeature) + : SketchAPI_MacroEllipse(theFeature, false) { if (initialize()) { fillAttribute(theCenter, theCenterRef, diff --git a/src/SketchAPI/SketchAPI_Sketch.cpp b/src/SketchAPI/SketchAPI_Sketch.cpp index cfcf93b7b..0504e411d 100644 --- a/src/SketchAPI/SketchAPI_Sketch.cpp +++ b/src/SketchAPI/SketchAPI_Sketch.cpp @@ -662,19 +662,6 @@ std::shared_ptr SketchAPI_Sketch::addEllipticArc( theInversed)); } -std::shared_ptr SketchAPI_Sketch::addEllipticArc( - const std::shared_ptr& theCenter, - const std::shared_ptr& theFocus, - const std::shared_ptr& theStart, - const std::shared_ptr& theEnd, - bool theInversed) -{ - std::shared_ptr aFeature = - compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID()); - return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, - theCenter, theFocus, theStart, theEnd, theInversed)); -} - std::shared_ptr SketchAPI_Sketch::addEllipticArc( const std::pair, ModelHighAPI_RefAttr>& theCenter, const std::pair, ModelHighAPI_RefAttr>& theMajorAxisPoint, diff --git a/src/SketchAPI/SketchAPI_Sketch.h b/src/SketchAPI/SketchAPI_Sketch.h index 2f722b5e5..a6ce99720 100644 --- a/src/SketchAPI/SketchAPI_Sketch.h +++ b/src/SketchAPI/SketchAPI_Sketch.h @@ -311,14 +311,6 @@ public: bool theInversed = false); /// Add elliptic arc SKETCHAPI_EXPORT - std::shared_ptr addEllipticArc( - const std::shared_ptr& theCenter, - const std::shared_ptr& theFocus, - const std::shared_ptr& theStart, - const std::shared_ptr& theEnd, - bool theInversed = false); - /// Add elliptic arc - SKETCHAPI_EXPORT std::shared_ptr addEllipticArc( const std::pair, ModelHighAPI_RefAttr>& theCenter, const std::pair, ModelHighAPI_RefAttr>& theMajorAxisPoint, diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index 2d4693a75..d21085a97 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -245,6 +245,8 @@ ADD_UNIT_TESTS( TestCreateEllipseByCenterSemiaxisAndPassed.py TestCreateEllipseByMajorAxisAndPassed.py TestCreateEllipseByExternal.py + TestCreateEllipticArc.py + TestCreateEllipticArcByExternal.py TestDegeneratedGeometry.py TestDistanceDump.py TestDistanceSignedVsUnsigned01.py @@ -277,6 +279,7 @@ ADD_UNIT_TESTS( TestProjectionUpdate.py TestRectangle.py TestRemoveEllipse.py + TestRemoveEllipticArc.py TestRemoveSketch.py TestSignedDistancePointLine.py TestSignedDistancePointPoint.py diff --git a/src/SketchPlugin/SketchPlugin_EllipticArc.cpp b/src/SketchPlugin/SketchPlugin_EllipticArc.cpp index 1c56d27e9..5b8b109e0 100644 --- a/src/SketchPlugin/SketchPlugin_EllipticArc.cpp +++ b/src/SketchPlugin/SketchPlugin_EllipticArc.cpp @@ -110,6 +110,7 @@ void SketchPlugin_EllipticArc::attributeChanged(const std::string& theID) { std::shared_ptr anEdge(new GeomAPI_Edge(aSelection)); std::shared_ptr anEllipse = anEdge->ellipse(); + bool aWasBlocked = data()->blockSendAttributeUpdated(true); std::shared_ptr aCenterAttr = std::dynamic_pointer_cast(attribute(CENTER_ID())); aCenterAttr->setValue(sketch()->to2D(anEllipse->center())); @@ -128,11 +129,27 @@ void SketchPlugin_EllipticArc::attributeChanged(const std::string& theID) { real(MAJOR_RADIUS_ID())->setValue(anEllipse->majorRadius()); real(MINOR_RADIUS_ID())->setValue(anEllipse->minorRadius()); + + double aStartParam, aMidParam, aEndParam; + anEllipse->parameter(anEdge->firstPoint(), tolerance, aStartParam); + anEllipse->parameter(anEdge->middlePoint(), tolerance, aMidParam); + anEllipse->parameter(anEdge->lastPoint(), tolerance, aEndParam); + if (aEndParam < aStartParam) + aEndParam += 2.0 * PI; + if (aMidParam < aStartParam) + aMidParam += 2.0 * PI; + boolean(REVERSED_ID())->setValue(aMidParam > aEndParam); + + data()->blockSendAttributeUpdated(aWasBlocked, false); + + fillCharacteristicPoints(); } } else if (theID == CENTER_ID() || theID == FIRST_FOCUS_ID() || theID == START_POINT_ID() || theID == END_POINT_ID()) fillCharacteristicPoints(); + else if (theID == REVERSED_ID() && myParamDelta == 0.0) + myParamDelta = 2.0 * PI; } static void calculateRadii(const GeomPnt2dPtr& theCenter, @@ -152,29 +169,30 @@ static void calculateRadii(const GeomPnt2dPtr& theCenter, bool SketchPlugin_EllipticArc::fillCharacteristicPoints() { std::shared_ptr aCenterAttr = - std::dynamic_pointer_cast(data()->attribute(CENTER_ID())); + std::dynamic_pointer_cast(data()->attribute(CENTER_ID())); std::shared_ptr aFocusAttr = - std::dynamic_pointer_cast(data()->attribute(FIRST_FOCUS_ID())); + std::dynamic_pointer_cast(data()->attribute(FIRST_FOCUS_ID())); std::shared_ptr aStartPointAttr = - std::dynamic_pointer_cast(data()->attribute(START_POINT_ID())); + std::dynamic_pointer_cast(data()->attribute(START_POINT_ID())); std::shared_ptr aEndPointAttr = - std::dynamic_pointer_cast(data()->attribute(END_POINT_ID())); + std::dynamic_pointer_cast(data()->attribute(END_POINT_ID())); if (!aCenterAttr->isInitialized() || - !aFocusAttr->isInitialized() || - !aStartPointAttr->isInitialized()) { + !aFocusAttr->isInitialized() || + !aStartPointAttr->isInitialized()) { return false; } - data()->blockSendAttributeUpdated(true); GeomPnt2dPtr aCenter2d = aCenterAttr->pnt(); GeomPnt2dPtr aFocus2d = aFocusAttr->pnt(); GeomPnt2dPtr aStart2d = aStartPointAttr->pnt(); double aMajorRadius = 0.0, aMinorRadius = 0.0; calculateRadii(aCenter2d, aFocus2d, aStart2d, aMajorRadius, aMinorRadius); - if (aMinorRadius < tolerance *aMajorRadius) + if (aMinorRadius < tolerance * aMajorRadius) return false; + + bool aWasBlocked = data()->blockSendAttributeUpdated(true); real(MAJOR_RADIUS_ID())->setValue(aMajorRadius); real(MINOR_RADIUS_ID())->setValue(aMinorRadius); @@ -186,16 +204,16 @@ bool SketchPlugin_EllipticArc::fillCharacteristicPoints() ->setValue(2.0 * aCenter2d->x() - aFocus2d->x(), 2.0 * aCenter2d->y() - aFocus2d->y()); std::dynamic_pointer_cast(attribute(MAJOR_AXIS_START_ID())) ->setValue(aCenter2d->x() - aMajorDir2d->x() * aMajorRadius, - aCenter2d->y() - aMajorDir2d->y() * aMajorRadius); + aCenter2d->y() - aMajorDir2d->y() * aMajorRadius); std::dynamic_pointer_cast(attribute(MAJOR_AXIS_END_ID())) ->setValue(aCenter2d->x() + aMajorDir2d->x() * aMajorRadius, - aCenter2d->y() + aMajorDir2d->y() * aMajorRadius); + aCenter2d->y() + aMajorDir2d->y() * aMajorRadius); std::dynamic_pointer_cast(attribute(MINOR_AXIS_START_ID())) ->setValue(aCenter2d->x() - aMinorDir2d->x() * aMinorRadius, - aCenter2d->y() - aMinorDir2d->y() * aMinorRadius); + aCenter2d->y() - aMinorDir2d->y() * aMinorRadius); std::dynamic_pointer_cast(attribute(MINOR_AXIS_END_ID())) ->setValue(aCenter2d->x() + aMinorDir2d->x() * aMinorRadius, - aCenter2d->y() + aMinorDir2d->y() * aMinorRadius); + aCenter2d->y() + aMinorDir2d->y() * aMinorRadius); if (aEndPointAttr->isInitialized()) { // recalculate REVERSED flag @@ -211,17 +229,17 @@ bool SketchPlugin_EllipticArc::fillCharacteristicPoints() aParamEnd -= aParamStart; if (myParamDelta >= 0.0 && myParamDelta <= PI * 0.5 && - aParamEnd < 0 && aParamEnd >= -PI * 0.5) { + aParamEnd < 0.0 && aParamEnd >= -PI * 0.5) { boolean(REVERSED_ID())->setValue(true); } else if (myParamDelta <= 0.0 && myParamDelta >= -PI * 0.5 && aParamEnd > 0.0 && aParamEnd <= PI * 0.5) { boolean(REVERSED_ID())->setValue(false); } + myParamDelta = aParamEnd; } - myParamDelta = aParamEnd; } - data()->blockSendAttributeUpdated(false); + data()->blockSendAttributeUpdated(aWasBlocked, false); return true; } diff --git a/src/SketchPlugin/Test/TestCreateEllipticArc.py b/src/SketchPlugin/Test/TestCreateEllipticArc.py new file mode 100644 index 000000000..fe675da20 --- /dev/null +++ b/src/SketchPlugin/Test/TestCreateEllipticArc.py @@ -0,0 +1,379 @@ +# Copyright (C) 2019 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 elliptic arc by center, semi-axis, start and end points +""" + +import unittest +from salome.shaper import model + +from GeomAPI import * +from SketchAPI import * + +__updated__ = "2019-10-01" + +class TestEllipticArc(unittest.TestCase): + def setUp(self): + model.begin() + self.myDocument = model.moduleDocument() + self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY")) + self.myCenter = GeomAPI_Pnt2d(50., 50.) + self.myFocus = GeomAPI_Pnt2d(70., 60.) + self.myStartPoint = GeomAPI_Pnt2d(60., 65.) + self.myEndPoint = GeomAPI_Pnt2d(60., 42.535751) + self.myDOF = 0 + + def tearDown(self): + self.checkDOF() + model.end() + + + def checkDOF(self): + self.assertEqual(model.dof(self.mySketch), self.myDOF) + + def checkPointsEqual(self, thePoint1, thePoint2): + self.assertAlmostEqual(thePoint1.x(), thePoint2.x(), 5) + self.assertAlmostEqual(thePoint1.y(), thePoint2.y(), 5) + + def checkPointOnLine(self, theCoordinates, theLine): + point = GeomAPI_Pnt2d(theCoordinates.x(), theCoordinates.y()) + dist = model.distancePointLine(point, theLine) + self.assertAlmostEqual(dist, 0, 7) + + def checkPointOnCircle(self, theCoordinates, theCircle): + point = GeomAPI_Pnt2d(theCoordinates.x(), theCoordinates.y()) + dist = model.distancePointPoint(point, theCircle.center()) + self.assertAlmostEqual(dist , theCircle.radius().value(), 7) + + def checkPointOnEllipse(self, theCoordinates, theEllipse): + point = GeomAPI_Pnt2d(theCoordinates.x(), theCoordinates.y()) + firstFocus2d = GeomAPI_Pnt2d(theEllipse.firstFocus().x(), theEllipse.firstFocus().y()) + distPF1 = model.distancePointPoint(firstFocus2d, point) + secondFocus2d = GeomAPI_Pnt2d(theEllipse.secondFocus().x(), theEllipse.secondFocus().y()) + distPF2 = model.distancePointPoint(secondFocus2d, point) + if issubclass(type(theEllipse), SketchAPI_Ellipse): + majorRad = theEllipse.majorRadius().value() + else: + majorRad = theEllipse.majorRadius() + self.assertAlmostEqual(distPF1 + distPF2, 2.0 * majorRad, 7) + + + def test_elliptic_arc_by_coordinates(self): + """ Test 1. Create elliptic arc by coordinates of center, point on the major axis, start and end points + """ + self.myEllipse1 = self.mySketch.addEllipticArc(self.myCenter.x(), self.myCenter.y(), + self.myFocus.x(), self.myFocus.y(), + self.myStartPoint.x(), self.myStartPoint.y(), + self.myEndPoint.x(), self.myEndPoint.y(), False) + self.myDOF += 7 + + self.myEllipse2 = self.mySketch.addEllipticArc(self.myCenter.x(), self.myCenter.y(), + self.myFocus.x(), self.myFocus.y(), + self.myStartPoint.x(), self.myStartPoint.y(), + self.myEndPoint.x(), self.myEndPoint.y(), True) + self.myDOF += 7 + model.do() + + # check both ellipses are equal + anArcEdge1 = self.myEllipse1.defaultResult().shape().edge() + anArcEdge2 = self.myEllipse2.defaultResult().shape().edge() + anEllipse1 = anArcEdge1.ellipse() + anEllipse2 = anArcEdge2.ellipse() + self.checkPointsEqual(anEllipse1.center(), anEllipse2.center()) + self.checkPointsEqual(anEllipse1.firstFocus(), anEllipse2.firstFocus()) + self.checkPointsEqual(anEllipse1.secondFocus(), anEllipse2.secondFocus()) + self.assertAlmostEqual(anEllipse1.minorRadius(), anEllipse2.minorRadius()) + self.assertAlmostEqual(anEllipse1.majorRadius(), anEllipse2.majorRadius()) + self.checkPointsEqual(self.myEllipse1.startPoint(), self.myEllipse2.startPoint()) + self.checkPointsEqual(self.myEllipse1.endPoint(), self.myEllipse2.endPoint()) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 0) + model.testNbSubFeatures(self.mySketch, "SketchLine", 0) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 2) + # check middle points are different + assert(anArcEdge1.middlePoint().x() < self.myStartPoint.x()) + assert(anArcEdge2.middlePoint().x() > self.myStartPoint.x()) + + def test_elliptic_arc_by_points(self): + """ Test 2. Create elliptic arc by points + """ + self.mySketch.addEllipticArc(self.myCenter, self.myFocus, self.myStartPoint, self.myEndPoint, False) + self.myDOF += 7 + model.do() + anEllipseFeature1 = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature1) + + self.mySketch.addEllipticArc(self.myCenter, self.myFocus, self.myStartPoint, self.myEndPoint, True) + self.myDOF += 7 + model.do() + anEllipseFeature2 = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse2 = SketchAPI_EllipticArc(anEllipseFeature2) + + # check both ellipses are equal + anArcEdge1 = anEllipseFeature1.lastResult().shape().edge() + anArcEdge2 = anEllipseFeature2.lastResult().shape().edge() + anEllipse1 = anArcEdge1.ellipse() + anEllipse2 = anArcEdge2.ellipse() + self.checkPointsEqual(anEllipse1.center(), anEllipse2.center()) + self.checkPointsEqual(anEllipse1.firstFocus(), anEllipse2.firstFocus()) + self.checkPointsEqual(anEllipse1.secondFocus(), anEllipse2.secondFocus()) + self.assertAlmostEqual(anEllipse1.minorRadius(), anEllipse2.minorRadius()) + self.assertAlmostEqual(anEllipse1.majorRadius(), anEllipse2.majorRadius()) + self.checkPointsEqual(self.myEllipse1.startPoint(), self.myEllipse2.startPoint()) + self.checkPointsEqual(self.myEllipse1.endPoint(), self.myEllipse2.endPoint()) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 14) + model.testNbSubFeatures(self.mySketch, "SketchLine", 4) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 2) + # check middle points are different + assert(anArcEdge1.middlePoint().x() < self.myStartPoint.x()) + assert(anArcEdge2.middlePoint().x() > self.myStartPoint.x()) + + def test_elliptic_arc_with_fixed_center(self): + """ Test 3. Create elliptic arc which center is coincident with another point + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc(aLine.endPoint(), self.myFocus, self.myStartPoint, self.myEndPoint, True) + self.myDOF += 5 + model.do() + # check ellipse + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + self.checkPointsEqual(anEllipse.center(), aLine.endPoint()) + self.checkPointOnEllipse(self.myStartPoint, anEllipse) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_center_on_line(self): + """ Test 4. Create elliptic arc which center is coincident with a line + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc([self.myCenter, aLine.result()], self.myFocus, self.myStartPoint, self.myEndPoint, False) + self.myDOF += 6 + model.do() + + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + # check center on line + self.checkPointOnLine(anEllipse.center(), aLine) + self.checkPointOnEllipse(self.myEllipse1.startPoint(), anEllipse) + self.checkPointOnEllipse(self.myEllipse1.endPoint(), anEllipse) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_center_on_circle(self): + """ Test 5. Create elliptic arc which center is coincident with a circle + """ + aCircle = self.mySketch.addCircle(10, 10, 20) + self.myDOF += 3 + model.do() + + self.mySketch.addEllipticArc([self.myCenter, aCircle.defaultResult()], self.myFocus, self.myStartPoint, self.myEndPoint, False) + self.myDOF += 6 + model.do() + + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + # check center on circle + self.checkPointOnCircle(anEllipse.center(), aCircle) + self.checkPointOnEllipse(self.myEllipse1.startPoint(), anEllipse) + self.checkPointOnEllipse(self.myEllipse1.endPoint(), anEllipse) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 2) + model.testNbSubFeatures(self.mySketch, "SketchCircle", 1) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_center_on_ellipse(self): + """ Test 6. Create elliptic arc which center is coincident with another ellipse + """ + anOtherEllipse = self.mySketch.addEllipse(10, 10, 30, 20, 10) + self.myDOF += 5 + model.do() + + self.mySketch.addEllipticArc([self.myCenter, anOtherEllipse.defaultResult()], self.myFocus, self.myStartPoint, self.myEndPoint, False) + self.myDOF += 6 + model.do() + + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + # check center on ellipse + self.checkPointOnEllipse(anEllipse.center(), anOtherEllipse) + self.checkPointOnEllipse(self.myEllipse1.startPoint(), anEllipse) + self.checkPointOnEllipse(self.myEllipse1.endPoint(), anEllipse) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 2) + model.testNbSubFeatures(self.mySketch, "SketchEllipse", 1) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_fixed_axis(self): + """ Test 7. Create elliptic arc which point on major semi-axis is coincident with another point + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc(self.myCenter, aLine.endPoint(), self.myStartPoint, self.myEndPoint, False) + self.myDOF += 6 + model.do() + # check ellipse + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + self.checkPointOnEllipse(self.myStartPoint, anEllipse) + self.checkPointOnEllipse(aLine.endPoint(), anEllipse) + # check distance is equal to major semi-axis + dist = model.distancePointPoint(GeomAPI_Pnt2d(anEllipse.center().x(), anEllipse.center().y()), aLine.endPoint()) + self.assertAlmostEqual(dist, anEllipse.majorRadius(), 7) + self.checkPointsEqual(self.myEllipse1.majorAxisPositive(), aLine.endPoint()) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_axis_on_line(self): + """ Test 8. Create elliptic arc which point on major semi-axis is coincident with a line. + Check no coincidence constraint is created. + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc(self.myCenter, [self.myFocus, aLine.result()], self.myStartPoint, self.myEndPoint, True) + self.myDOF += 7 + model.do() + + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 0) + + def test_elliptic_arc_with_fixed_start_point(self): + """ Test 9. Create elliptic arc which start point is coincident with another point + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc(self.myCenter, self.myFocus, aLine.endPoint(), self.myEndPoint, True) + self.myDOF += 5 + model.do() + # check ellipse + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + self.checkPointOnEllipse(aLine.endPoint(), anEllipse) + self.checkPointsEqual(aLine.endPoint(), self.myEllipse1.startPoint()) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_start_point_on_line(self): + """ Test 10. Create elliptic arc which start point is placed on a line. + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc(self.myCenter, self.myFocus, [self.myStartPoint, aLine.result()], self.myEndPoint, False) + self.myDOF += 6 + model.do() + + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + self.checkPointOnLine(self.myEllipse1.startPoint(), aLine) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_fixed_end_point(self): + """ Test 11. Create elliptic arc which end point is coincident with another point + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc(self.myCenter, self.myFocus, self.myStartPoint, aLine.endPoint(), True) + self.myDOF += 5 + model.do() + # check ellipse + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + self.checkPointOnEllipse(aLine.endPoint(), anEllipse) + self.checkPointsEqual(aLine.endPoint(), self.myEllipse1.endPoint()) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + def test_elliptic_arc_with_end_point_on_line(self): + """ Test 12. Create elliptic arc which end point is placed on a line. + """ + aLine = self.mySketch.addLine(10, 10, 30, 40) + self.myDOF += 4 + model.do() + + self.mySketch.addEllipticArc(self.myCenter, self.myFocus, self.myStartPoint, [self.myEndPoint, aLine.result()], False) + self.myDOF += 6 + model.do() + + anEllipseFeature = model.lastSubFeature(self.mySketch, "SketchEllipticArc") + self.myEllipse1 = SketchAPI_EllipticArc(anEllipseFeature) + anEllipse = anEllipseFeature.lastResult().shape().edge().ellipse() + self.checkPointOnLine(self.myEllipse1.endPoint(), aLine) + # check number of features + model.testNbSubFeatures(self.mySketch, "SketchPoint", 7) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + +if __name__ == "__main__": + test_program = unittest.main(exit=False) + assert test_program.result.wasSuccessful(), "Test failed" + assert model.checkPythonDump() diff --git a/src/SketchPlugin/Test/TestCreateEllipticArcByExternal.py b/src/SketchPlugin/Test/TestCreateEllipticArcByExternal.py new file mode 100644 index 000000000..7d83217a6 --- /dev/null +++ b/src/SketchPlugin/Test/TestCreateEllipticArcByExternal.py @@ -0,0 +1,142 @@ +# Copyright (C) 2019 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 elliptic arc by external feature +""" + +import unittest +from salome.shaper import model + +from GeomAPI import * +from SketchAPI import * + +__updated__ = "2019-10-02" + +# reference data +CENTER_POINT = GeomAPI_Pnt2d(50., 50.) +MAJOR_AXIS_POINT = GeomAPI_Pnt2d(70., 60.) +START_POINT = GeomAPI_Pnt2d(60., 65.) +END_POINT = GeomAPI_Pnt2d(60., 42.535751) +ARC_LENGTH_1 = 0 +ARC_LENGTH_2 = 0 + +class TestEllipticArcByExternal(unittest.TestCase): + def setUp(self): + model.begin() + self.myDocument = model.moduleDocument() + self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY")) + self.myDOF = 0 + + def tearDown(self): + self.checkDOF() + model.end() + + + def checkDOF(self): + self.assertEqual(model.dof(self.mySketch), self.myDOF) + + def checkPointsEqual(self, thePoint1, thePoint2): + self.assertAlmostEqual(thePoint1.x(), thePoint2.x(), 5) + self.assertAlmostEqual(thePoint1.y(), thePoint2.y(), 5) + + + def test_elliptic_arc_by_external_name_1(self): + """ Test 1. Create elliptic arc by name of external edge (direct) + """ + self.myEllipse = self.mySketch.addEllipticArc("Sketch_1/SketchEllipticArc_1") + model.do() + + # check ellipse parameters + anArcEdge = self.myEllipse.defaultResult().shape().edge() + anEllipse = anArcEdge.ellipse() + self.checkPointsEqual(anEllipse.center(), CENTER_POINT) + self.checkPointsEqual(self.myEllipse.majorAxisPositive(), MAJOR_AXIS_POINT) + self.checkPointsEqual(self.myEllipse.startPoint(), START_POINT) + self.checkPointsEqual(self.myEllipse.endPoint(), END_POINT) + self.assertAlmostEqual(anArcEdge.length(), ARC_LENGTH_1) + + def test_elliptic_arc_by_external_name_2(self): + """ Test 2. Create elliptic arc by name of external edge (reversed) + """ + self.myEllipse = self.mySketch.addEllipticArc("Sketch_1/SketchEllipticArc_2") + model.do() + + # check ellipse parameters + anArcEdge = self.myEllipse.defaultResult().shape().edge() + anEllipse = anArcEdge.ellipse() + self.checkPointsEqual(anEllipse.center(), CENTER_POINT) + self.checkPointsEqual(self.myEllipse.majorAxisPositive(), MAJOR_AXIS_POINT) + self.checkPointsEqual(anArcEdge.firstPoint(), END_POINT) + self.checkPointsEqual(anArcEdge.lastPoint(), START_POINT) + self.assertAlmostEqual(anArcEdge.length(), ARC_LENGTH_2) + + def test_elliptic_arc_by_external_selection_1(self): + """ Test 3. Create elliptic arc by selected edge (direct) + """ + self.myEllipse = self.mySketch.addEllipticArc(ELLIPTIC_ARC_1.results()[-1]) + model.do() + + # check ellipse parameters + anArcEdge = self.myEllipse.defaultResult().shape().edge() + anEllipse = anArcEdge.ellipse() + self.checkPointsEqual(anEllipse.center(), CENTER_POINT) + self.checkPointsEqual(self.myEllipse.majorAxisPositive(), MAJOR_AXIS_POINT) + self.checkPointsEqual(self.myEllipse.startPoint(), START_POINT) + self.checkPointsEqual(self.myEllipse.endPoint(), END_POINT) + self.assertAlmostEqual(anArcEdge.length(), ARC_LENGTH_1) + + def test_elliptic_arc_by_external_selection_2(self): + """ Test 4. Create elliptic arc by selected edge (reversed) + """ + self.myEllipse = self.mySketch.addEllipticArc(ELLIPTIC_ARC_2.results()[-1]) + model.do() + + # check ellipse parameters + anArcEdge = self.myEllipse.defaultResult().shape().edge() + anEllipse = anArcEdge.ellipse() + self.checkPointsEqual(anEllipse.center(), CENTER_POINT) + self.checkPointsEqual(self.myEllipse.majorAxisPositive(), MAJOR_AXIS_POINT) + self.checkPointsEqual(self.myEllipse.startPoint(), END_POINT) + self.checkPointsEqual(self.myEllipse.endPoint(), START_POINT) + self.assertAlmostEqual(anArcEdge.length(), ARC_LENGTH_2) + + +if __name__ == "__main__": + model.begin() + aDocument = model.moduleDocument() + aSketch = model.addSketch(aDocument, model.defaultPlane("XOY")) + aSketch.addEllipticArc(CENTER_POINT, MAJOR_AXIS_POINT, START_POINT, END_POINT, False) + model.do() + + ELLIPTIC_ARC_1 = SketchAPI_EllipticArc(model.lastSubFeature(aSketch, "SketchEllipticArc")) + ARC_LENGTH_1 = ELLIPTIC_ARC_1.defaultResult().shape().edge().length() + + aSketch.addEllipticArc(CENTER_POINT, MAJOR_AXIS_POINT, START_POINT, END_POINT, True) + model.end() + + ELLIPTIC_ARC_2 = SketchAPI_EllipticArc(model.lastSubFeature(aSketch, "SketchEllipticArc")) + ARC_LENGTH_2 = ELLIPTIC_ARC_2.defaultResult().shape().edge().length() + + # redefine end point + END_POINT = ELLIPTIC_ARC_2.endPoint() + + test_program = unittest.main(exit=False) + assert test_program.result.wasSuccessful(), "Test failed" + assert model.checkPythonDump() diff --git a/src/SketchPlugin/Test/TestRemoveEllipticArc.py b/src/SketchPlugin/Test/TestRemoveEllipticArc.py new file mode 100644 index 000000000..ccea403dc --- /dev/null +++ b/src/SketchPlugin/Test/TestRemoveEllipticArc.py @@ -0,0 +1,107 @@ +# Copyright (C) 2019 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 elliptic arc and its construstion elements +""" + +from salome.shaper import model +from ModelAPI import * + +def assertNbSubs(theSketch, theNbPoints, theNbLines, theNbEllipticArcs, theNbInternalConstraints): + model.testNbSubFeatures(theSketch, "SketchPoint", theNbPoints) + model.testNbSubFeatures(theSketch, "SketchLine", theNbLines) + model.testNbSubFeatures(theSketch, "SketchEllipticArc", theNbEllipticArcs) + 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")) +SketchEllipticArc_1 = Sketch_1.addEllipticArc(40, 30, 70, 60, 60, 65, 60., 23.3257583582, False) +[Center, Focus1, Focus2, MajorAxisStart, MajorAxisEnd, MinorAxisStart, MinorAxisEnd, MajorAxisLine, MinorAxisLine] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux") +model.do() +model.end() + +DEFAULT_DOF = 7 +DEFAULT_POINTS = 7 +DEFAULT_LINES = 2 +DEFAULT_ELLIPTIC_ARCS = 1 +DEAFULT_INTERNALS = 11 + +assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES, DEFAULT_ELLIPTIC_ARCS, DEAFULT_INTERNALS) +assert(model.dof(Sketch_1) == DEFAULT_DOF) + +# Test 1. Remove auxiliary points one by one. +points = [Center, Focus1, Focus2, MajorAxisStart, MajorAxisEnd, MinorAxisStart, MinorAxisEnd] +for pnt in points: + model.begin() + removeFeaturesAndReferences(FeatureSet([pnt.feature()])) + model.end() + + assertNbSubs(Sketch_1, DEFAULT_POINTS - 1, DEFAULT_LINES, DEFAULT_ELLIPTIC_ARCS, DEAFULT_INTERNALS - 1) + assert(model.dof(Sketch_1) == DEFAULT_DOF) + model.undo() + assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES, DEFAULT_ELLIPTIC_ARCS, DEAFULT_INTERNALS) + assert(model.dof(Sketch_1) == DEFAULT_DOF) + +# Test 2. Remove auxiliary axes one by one. +lines = [MajorAxisLine, MinorAxisLine] +for ln in lines: + model.begin() + removeFeaturesAndReferences(FeatureSet([ln.feature()])) + model.end() + + assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES - 1, DEFAULT_ELLIPTIC_ARCS, DEAFULT_INTERNALS - 2) + assert(model.dof(Sketch_1) == DEFAULT_DOF) + model.undo() + assertNbSubs(Sketch_1, DEFAULT_POINTS, DEFAULT_LINES, DEFAULT_ELLIPTIC_ARCS, DEAFULT_INTERNALS) + assert(model.dof(Sketch_1) == DEFAULT_DOF) + +# Test 3. Remove the elliptic arc. +model.begin() +removeFeaturesAndReferences(FeatureSet([SketchEllipticArc_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_ELLIPTIC_ARCS, 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() +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchEllipticArc_2 = Sketch_2.addEllipticArc(40, -30, 70, 0, 30, 10, 0, -20, True) +[Center, Focus1, Focus2, MajorAxisStart, MajorAxisEnd, MinorAxisStart, MinorAxisEnd, MajorAxisLine, MinorAxisLine] = SketchEllipticArc_2.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux") +SketchEllipticArc_2.setAuxiliary(True) +model.do() +model.end() + +model.begin() +removeFeaturesAndReferences(FeatureSet([MajorAxisLine.feature(), Focus2.feature()])) +Focus1.setAuxiliary(False) +MinorAxisLine.setAuxiliary(False) +model.end() + +assertNbSubs(Sketch_2, DEFAULT_POINTS - 1, DEFAULT_LINES - 1, DEFAULT_ELLIPTIC_ARCS, DEAFULT_INTERNALS - 3) +assert(model.dof(Sketch_2) == DEFAULT_DOF) + +assert(model.checkPythonDump()) -- 2.30.2