From dac0a1447e65c792b3283ed290976b1634d793a9 Mon Sep 17 00:00:00 2001 From: azv Date: Wed, 2 Oct 2019 15:28:07 +0300 Subject: [PATCH] Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003) Unit tests for constraints Coincidence and Equal for elliptic arcs --- src/SketchAPI/SketchAPI_MacroEllipse.cpp | 32 +-- src/SketchAPI/SketchAPI_MacroEllipse.h | 4 + src/SketchAPI/SketchAPI_MacroEllipticArc.cpp | 1 + src/SketchPlugin/CMakeLists.txt | 1 + .../TestConstraintCoincidenceEllipticArc.py | 264 ++++++++++++++++++ .../Test/TestConstraintEqualEllipse.py | 25 ++ .../SketchSolver_ConstraintEqual.cpp | 17 +- .../SketchSolver_ConstraintEqual.h | 7 +- 8 files changed, 331 insertions(+), 20 deletions(-) create mode 100644 src/SketchPlugin/Test/TestConstraintCoincidenceEllipticArc.py diff --git a/src/SketchAPI/SketchAPI_MacroEllipse.cpp b/src/SketchAPI/SketchAPI_MacroEllipse.cpp index e833775e2..97138d413 100644 --- a/src/SketchAPI/SketchAPI_MacroEllipse.cpp +++ b/src/SketchAPI/SketchAPI_MacroEllipse.cpp @@ -42,26 +42,12 @@ #define PASSED_POINT_REF (feature()->refattr(SketchPlugin_MacroEllipse::PASSED_POINT_REF_ID())) -// find a parent sketch -static CompositeFeaturePtr sketch(FeaturePtr theFeature) -{ - CompositeFeaturePtr aSketch; - const std::set& aRefs = theFeature->data()->refsToMe(); - for (std::set::const_iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt) - if ((*anIt)->id() == SketchPlugin_Sketch::FEATURES_ID()) { - aSketch = std::dynamic_pointer_cast((*anIt)->owner()); - break; - } - return aSketch; -} - - SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr& theFeature, bool callInitialize) : SketchAPI_SketchEntity(theFeature) { if (callInitialize && initialize()) - mySketch = sketch(theFeature); + storeSketch(theFeature); } SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr& theFeature, @@ -140,7 +126,7 @@ void SketchAPI_MacroEllipse::initializePoints(double theX1, double theY1, fillAttribute(MAJOR_AXIS_POSITIVE, theX2, theY2); fillAttribute(PASSED_POINT, theX3, theY3); - mySketch = sketch(feature()); + storeSketch(feature()); execute(); } @@ -152,7 +138,7 @@ void SketchAPI_MacroEllipse::initializePoints(const std::shared_ptr& aRefs = theFeature->data()->refsToMe(); + for (std::set::const_iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt) + if ((*anIt)->id() == SketchPlugin_Sketch::FEATURES_ID()) { + mySketch = std::dynamic_pointer_cast((*anIt)->owner()); + break; + } +} + std::shared_ptr SketchAPI_MacroEllipse::center() { if (!myCenter) diff --git a/src/SketchAPI/SketchAPI_MacroEllipse.h b/src/SketchAPI/SketchAPI_MacroEllipse.h index 7e0103b16..8f0e88d83 100644 --- a/src/SketchAPI/SketchAPI_MacroEllipse.h +++ b/src/SketchAPI/SketchAPI_MacroEllipse.h @@ -94,6 +94,10 @@ public: /// Return created auxiliary minor axis SKETCHAPI_EXPORT std::shared_ptr minorAxis(); +protected: + // find a parent sketch + void storeSketch(const std::shared_ptr& theFeature); + private: /// Set flag of creation by center, major semi-axis and passed point. void setByCenterAndPassedPoints(); diff --git a/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp b/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp index f76f797c5..2955ac530 100644 --- a/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp +++ b/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp @@ -86,6 +86,7 @@ SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc( fillAttribute(theReversed, reversed()); + storeSketch(theFeature); execute(); } } diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index d21085a97..02226a400 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -211,6 +211,7 @@ ADD_UNIT_TESTS( TestConstraintAngleEllipse.py TestConstraintCoincidence.py TestConstraintCoincidenceEllipse.py + TestConstraintCoincidenceEllipticArc.py TestConstraintCollinear.py TestConstraintCollinearEllipse.py TestConstraintDistance.py diff --git a/src/SketchPlugin/Test/TestConstraintCoincidenceEllipticArc.py b/src/SketchPlugin/Test/TestConstraintCoincidenceEllipticArc.py new file mode 100644 index 000000000..c7eb7798f --- /dev/null +++ b/src/SketchPlugin/Test/TestConstraintCoincidenceEllipticArc.py @@ -0,0 +1,264 @@ +# 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 constraint coincidence applied for elliptic arc and its sub-results +""" + +import unittest +import math + +from salome.shaper import model + +from GeomAPI import * +from SketchAPI import * + +__updated__ = "2019-10-02" + +class TestCoincidenceEllipticArc(unittest.TestCase): + def setUp(self): + center = GeomAPI_Pnt2d(-10., 5.) + axisEnd = GeomAPI_Pnt2d(40., -5.) + startPoint = GeomAPI_Pnt2d(20., 5.) + endPoint = GeomAPI_Pnt2d(-40., 5.) + + model.begin() + self.myDocument = model.moduleDocument() + self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY")) + macroEllipticArc = self.mySketch.addEllipticArc(center, axisEnd, startPoint, endPoint, False) + self.myDOF = 7 + self.myOrigin = self.mySketch.addPoint("Origin") + self.myOX = self.mySketch.addLine("OX") + model.do() + self.myEllipticArc = SketchAPI_EllipticArc(model.lastSubFeature(self.mySketch, "SketchEllipticArc")) + self.myCenter = macroEllipticArc.center() + self.myFocus1 = macroEllipticArc.focus1() + self.myFocus2 = macroEllipticArc.focus2() + self.myMajorAxis = macroEllipticArc.majorAxis() + self.myMajorStart = macroEllipticArc.majorAxisStart() + self.myMajorEnd = macroEllipticArc.majorAxisEnd() + self.myMinorAxis = macroEllipticArc.minorAxis() + self.myMinorStart = macroEllipticArc.minorAxisStart() + self.myMinorEnd = macroEllipticArc.minorAxisEnd() + self.myExpectFailure = False + + def tearDown(self): + model.end() + if self.myExpectFailure: + assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly" + model.undo() + else: + self.checkDOF() + self.assertPoints(self.myCenter.coordinates(), self.myEllipticArc.center()) + self.assertPoints(self.myFocus1.coordinates(), self.myEllipticArc.firstFocus()) + self.assertPoints(self.myFocus2.coordinates(), self.myEllipticArc.secondFocus()) + self.assertPoints(self.myMajorStart.coordinates(), self.myEllipticArc.majorAxisNegative()) + self.assertPoints(self.myMajorEnd.coordinates(), self.myEllipticArc.majorAxisPositive()) + self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipticArc.majorAxisNegative()) + self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipticArc.majorAxisPositive()) + self.assertPoints(self.myMinorStart.coordinates(), self.myEllipticArc.minorAxisNegative()) + self.assertPoints(self.myMinorEnd.coordinates(), self.myEllipticArc.minorAxisPositive()) + self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipticArc.minorAxisNegative()) + self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipticArc.minorAxisPositive()) + model.testNbSubFeatures(self.mySketch, "SketchPoint", 8) + model.testNbSubFeatures(self.mySketch, "SketchLine", 3) + model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", 11) + model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1) + + + def checkDOF(self): + self.assertEqual(model.dof(self.mySketch), self.myDOF) + + def checkPointFixing(self, thePoint): + self.mySketch.setCoincident(thePoint, self.myOrigin.coordinates()) + self.myDOF -= 2 + model.do() + if not self.myExpectFailure: + self.assertPoints(thePoint, self.myOrigin.coordinates()) + self.assertGreater(self.myEllipticArc.majorRadius().value(), 0.0) + self.assertGreater(self.myEllipticArc.minorRadius().value(), 0.0) + + def assertPoints(self, thePoint1, thePoint2): + self.assertAlmostEqual(thePoint1.x(), thePoint2.x()) + self.assertAlmostEqual(thePoint1.y(), thePoint2.y()) + + def checkPointOnAxis(self, thePoint): + self.mySketch.setCoincident(thePoint, self.myOX.result()) + self.myDOF -= 1 + model.do() + if not self.myExpectFailure: + self.assertAlmostEqual(thePoint.y(), 0.0) + self.assertGreater(self.myEllipticArc.majorRadius().value(), 0.0) + self.assertGreater(self.myEllipticArc.minorRadius().value(), 0.0) + + def checkPointOnLine(self, thePoint, theLineStart, theLineEnd): + vecP = [thePoint.x() - theLineStart.x(), thePoint.y() - theLineStart.y()] + vecL = [theLineEnd.x() - theLineStart.x(), theLineEnd.y() - theLineStart.y()] + dist = math.fabs(vecP[0] * vecL[1] - vecP[1] * vecL[0]) / math.hypot(vecL[0], vecL[1]) + + self.assertAlmostEqual(dist, 0.0) + self.assertGreater(self.myEllipticArc.majorRadius().value(), 0.0) + self.assertGreater(self.myEllipticArc.minorRadius().value(), 0.0) + + def checkPointOnEllipse(self, thePoint, theEllipse): + firstFocus2d = GeomAPI_Pnt2d(theEllipse.firstFocus().x(), theEllipse.firstFocus().y()) + distPF1 = model.distancePointPoint(firstFocus2d, thePoint) + secondFocus2d = GeomAPI_Pnt2d(theEllipse.secondFocus().x(), theEllipse.secondFocus().y()) + distPF2 = model.distancePointPoint(secondFocus2d, thePoint) + self.assertAlmostEqual(distPF1 + distPF2, 2.0 * theEllipse.majorRadius().value(), 7) + + + def test_concident_center(self): + """ Test 1. Make center of elliptic arc coincident with the Origin + """ + self.checkPointFixing(self.myCenter.coordinates()) + + def test_coincident_first_focus(self): + """ Test 2. Make first focus of elliptic arc coincident with the Origin + """ + self.checkPointFixing(self.myFocus1.coordinates()) + + def test_coincident_second_focus(self): + """ Test 3. Make second focus of elliptic arc coincident with the Origin + """ + self.checkPointFixing(self.myFocus2.coordinates()) + + def test_coincident_major_axis_start(self): + """ Test 4. Make start point on the major axis of elliptic arc coincident with the Origin + """ + self.checkPointFixing(self.myMajorStart.coordinates()) + + def test_coincident_major_axis_end(self): + """ Test 5. Make end point on the major axis of elliptic arc coincident with the Origin + """ + self.checkPointFixing(self.myMajorEnd.coordinates()) + + def test_coincident_minor_axis_start(self): + """ Test 6. Make start point on the minor axis of elliptic arc coincident with the Origin + """ + self.checkPointFixing(self.myMinorStart.coordinates()) + + def test_coincident_minor_axis_end(self): + """ Test 7. Make end point on the minor axis of elliptic arc coincident with the Origin. + Check solver is failed to compute the coincidence. + """ + self.myExpectFailure = True + self.checkPointFixing(self.myMinorEnd.coordinates()) + + def test_coincident_start(self): + """ Test 8. Make start point of elliptic arc coincident with the Origin. + Check solver is failed to compute the coincidence. + """ + self.myExpectFailure = True + self.checkPointFixing(self.myEllipticArc.startPoint()) + + def test_coincident_end(self): + """ Test 9. Make end point of elliptic arc coincident with the Origin + """ + self.checkPointFixing(self.myEllipticArc.endPoint()) + + + def test_center_on_line(self): + """ Test 10. Make center of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myCenter.coordinates()) + + def test_first_focus_on_line(self): + """ Test 11. Make first focus of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myFocus1.coordinates()) + + def test_second_focus_on_line(self): + """ Test 12. Make second focus of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myFocus2.coordinates()) + + def test_major_axis_start_on_line(self): + """ Test 13. Make start point on the major axis of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myMajorStart.coordinates()) + + def test_major_axis_end_on_line(self): + """ Test 14. Make end point on the major axis of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myMajorEnd.coordinates()) + + def test_minor_axis_start_on_line(self): + """ Test 15. Make start point on the minor axis of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myMinorStart.coordinates()) + + def test_minor_axis_end_on_line(self): + """ Test 16. Make end point on the minor axis of elliptic arc coincident with the OX + """ + self.myExpectFailure = True + self.checkPointOnAxis(self.myMinorEnd.coordinates()) + + def test_coincident_start_on_line(self): + """ Test 17. Make start point of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myEllipticArc.startPoint()) + + def test_coincident_end_on_line(self): + """ Test 18. Make end point of elliptic arc coincident with the OX + """ + self.checkPointOnAxis(self.myEllipticArc.endPoint()) + + + def test_origin_on_major_axis(self): + """ Test 19. Make origin coincident with the major axis of the elliptic arc + """ + self.mySketch.setCoincident(self.myMajorAxis.result(), self.myOrigin.coordinates()) + self.myDOF -= 1 + model.do() + self.checkPointOnLine(self.myOrigin.coordinates(), self.myMajorStart.coordinates(), self.myMajorEnd.coordinates()) + + def test_origin_on_minor_axis(self): + """ Test 20. Make origin coincident with the minor axis of the elliptic arc + """ + self.mySketch.setCoincident(self.myMinorAxis.result(), self.myOrigin.coordinates()) + self.myDOF -= 1 + model.end() + # solver shows wrong result + assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly" + model.undo() + + # move elliptic arc and set coincidence once again + model.begin() + self.mySketch.move(self.myMinorStart, 20, 10) + model.do() + self.mySketch.setCoincident(self.myMinorAxis.results()[-1], self.myOrigin.coordinates()) + model.do() + self.checkPointOnLine(self.myOrigin.coordinates(), self.myMinorStart.coordinates(), self.myMinorEnd.coordinates()) + + + def test_origin_on_ellipse(self): + """ Test 21. Make origin coincident with the elliptic arc + """ + self.mySketch.setCoincident(self.myEllipticArc.results()[-1], self.myOrigin.coordinates()) + self.myDOF -= 1 + model.do() + self.checkPointOnEllipse(self.myOrigin.coordinates(), self.myEllipticArc) + + +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/TestConstraintEqualEllipse.py b/src/SketchPlugin/Test/TestConstraintEqualEllipse.py index 006d18d2d..46bf795d2 100644 --- a/src/SketchPlugin/Test/TestConstraintEqualEllipse.py +++ b/src/SketchPlugin/Test/TestConstraintEqualEllipse.py @@ -24,14 +24,29 @@ from salome.shaper import model import math +DOF = 0 + model.begin() partSet = model.moduleDocument() Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY")) SketchEllipse_1 = Sketch_1.addEllipse(-27.88698315421018, 6.197107367602265, -8.725072906579975, 15.87998754592604, 11.10896680773502) [SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux") +DOF += 5 SketchEllipse_2 = Sketch_1.addEllipse(15.14848467636108, -15.95181340919842, 21.12194589112931, -20.27742325437541, 9.877448119278471) [SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11, SketchPoint_12, SketchPoint_13, SketchPoint_14, SketchLine_3, SketchLine_4] = SketchEllipse_2.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux") +DOF += 5 +SketchEllipticArc_1 = Sketch_1.addEllipticArc(49.62123971365138, 13.34935433264426, 64.40153327705804, 5.234651852264014, 68.29270956846837, 8.653290073592997, 32.00833375829566, 14.82599483073829, False) +[SketchPoint_15, SketchPoint_16, SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchLine_5, SketchLine_6] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux") +DOF += 7 +SketchEllipticArc_2 = Sketch_1.addEllipticArc(7.849720447428027, 32.28934430567138, 19.71732573395684, 29.13862828729395, 12.53096585507117, 17.93622281956947, 4.288678376456463, 46.71874313598852, True) +[SketchPoint_22, SketchPoint_23, SketchPoint_24, SketchPoint_25, SketchPoint_26, SketchPoint_27, SketchPoint_28, SketchLine_7, SketchLine_8] = SketchEllipticArc_2.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux") +DOF += 7 SketchConstraintEqual_1 = Sketch_1.setEqual(SketchEllipse_1.result(), SketchEllipse_2.result()) +DOF -= 2 +SketchConstraintEqual_2 = Sketch_1.setEqual(SketchEllipse_1.result(), SketchEllipticArc_1.result()) +DOF -= 2 +SketchConstraintEqual_3 = Sketch_1.setEqual(SketchEllipticArc_1.result(), SketchEllipticArc_2.result()) +DOF -= 2 model.do() model.end() @@ -39,10 +54,20 @@ TOLERANCE = 1.e-7 dist1 = model.distancePointPoint(SketchEllipse_1.majorAxisNegative(), SketchEllipse_1.majorAxisPositive()) dist2 = model.distancePointPoint(SketchEllipse_2.majorAxisNegative(), SketchEllipse_2.majorAxisPositive()) +dist3 = model.distancePointPoint(SketchEllipticArc_1.majorAxisNegative(), SketchEllipticArc_1.majorAxisPositive()) +dist4 = model.distancePointPoint(SketchEllipticArc_2.majorAxisNegative(), SketchEllipticArc_2.majorAxisPositive()) assert(math.fabs(dist1 - dist2) < TOLERANCE) +assert(math.fabs(dist1 - dist3) < TOLERANCE) +assert(math.fabs(dist1 - dist4) < TOLERANCE) dist1 = model.distancePointPoint(SketchEllipse_1.minorAxisNegative(), SketchEllipse_1.minorAxisPositive()) dist2 = model.distancePointPoint(SketchEllipse_2.minorAxisNegative(), SketchEllipse_2.minorAxisPositive()) +dist3 = model.distancePointPoint(SketchEllipticArc_1.minorAxisNegative(), SketchEllipticArc_1.minorAxisPositive()) +dist4 = model.distancePointPoint(SketchEllipticArc_2.minorAxisNegative(), SketchEllipticArc_2.minorAxisPositive()) assert(math.fabs(dist1 - dist2) < TOLERANCE) +assert(math.fabs(dist1 - dist3) < TOLERANCE) +assert(math.fabs(dist1 - dist4) < TOLERANCE) + +assert(model.dof(Sketch_1) == DOF) assert(model.checkPythonDump()) diff --git a/src/SketchSolver/SketchSolver_ConstraintEqual.cpp b/src/SketchSolver/SketchSolver_ConstraintEqual.cpp index 1218c072e..40fa38001 100644 --- a/src/SketchSolver/SketchSolver_ConstraintEqual.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintEqual.cpp @@ -65,7 +65,10 @@ void SketchSolver_ConstraintEqual::getAttributes( case 0: if (aNbEllipses == 2) { myType = CONSTRAINT_EQUAL_ELLIPSES; - theValue = ScalarWrapperPtr(new PlaneGCSSolver_ScalarWrapper(&myAuxValue)); + std::shared_ptr aStorage = + std::dynamic_pointer_cast(myStorage); + myAuxValue = ScalarWrapperPtr(new PlaneGCSSolver_ScalarWrapper(aStorage->createParameter())); + theValue = myAuxValue; } else myType = CONSTRAINT_EQUAL_RADIUS; @@ -93,3 +96,15 @@ void SketchSolver_ConstraintEqual::getAttributes( break; } } + +bool SketchSolver_ConstraintEqual::remove() +{ + if (myAuxValue) { + std::shared_ptr aStorage = + std::dynamic_pointer_cast(myStorage); + GCS::SET_pD aParams; + aParams.insert(myAuxValue->scalar()); + aStorage->removeParameters(aParams); + } + return SketchSolver_Constraint::remove(); +} diff --git a/src/SketchSolver/SketchSolver_ConstraintEqual.h b/src/SketchSolver/SketchSolver_ConstraintEqual.h index a7505be5f..146cf8764 100644 --- a/src/SketchSolver/SketchSolver_ConstraintEqual.h +++ b/src/SketchSolver/SketchSolver_ConstraintEqual.h @@ -34,6 +34,11 @@ public: SketchSolver_Constraint(theConstraint) {} + /// \brief Tries to remove constraint + /// \return \c false, if current constraint contains another SketchPlugin constraints + /// (like for multiple coincidence) + virtual bool remove(); + protected: /// \brief Generate list of attributes of constraint in order useful for constraints /// \param[out] theValue numerical characteristic of constraint (e.g. distance) @@ -42,7 +47,7 @@ protected: std::vector& theAttributes); private: - double myAuxValue; ///< scalar value to store ellipses focus distance + ScalarWrapperPtr myAuxValue; ///< scalar value to store ellipses focus distance }; #endif -- 2.39.2