]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
authorazv <azv@opencascade.com>
Wed, 2 Oct 2019 12:28:07 +0000 (15:28 +0300)
committerazv <azv@opencascade.com>
Wed, 2 Oct 2019 12:28:29 +0000 (15:28 +0300)
Unit tests for constraints Coincidence and Equal for elliptic arcs

src/SketchAPI/SketchAPI_MacroEllipse.cpp
src/SketchAPI/SketchAPI_MacroEllipse.h
src/SketchAPI/SketchAPI_MacroEllipticArc.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/Test/TestConstraintCoincidenceEllipticArc.py [new file with mode: 0644]
src/SketchPlugin/Test/TestConstraintEqualEllipse.py
src/SketchSolver/SketchSolver_ConstraintEqual.cpp
src/SketchSolver/SketchSolver_ConstraintEqual.h

index e833775e204e281e037e7eb4a0e1486f0439d681..97138d4135647401599f5892e60bbf1de1713db3 100644 (file)
 #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<AttributePtr>& aRefs = theFeature->data()->refsToMe();
-  for (std::set<AttributePtr>::const_iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt)
-    if ((*anIt)->id() == SketchPlugin_Sketch::FEATURES_ID()) {
-      aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>((*anIt)->owner());
-      break;
-    }
-  return aSketch;
-}
-
-
 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                bool callInitialize)
 : SketchAPI_SketchEntity(theFeature)
 {
   if (callInitialize && initialize())
-    mySketch = sketch(theFeature);
+    storeSketch(theFeature);
 }
 
 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& 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<GeomAPI_Pnt2
   fillAttribute(thePoint2, MAJOR_AXIS_POSITIVE);
   fillAttribute(thePoint3, PASSED_POINT);
 
-  mySketch = sketch(feature());
+  storeSketch(feature());
   execute();
 }
 
@@ -187,10 +173,20 @@ void SketchAPI_MacroEllipse::initializePoints(
   fillAttribute(thePassedPoint, thePassedPointRef,
                 PASSED_POINT, PASSED_POINT_REF);
 
-  mySketch = sketch(feature());
+  storeSketch(feature());
   execute();
 }
 
+void SketchAPI_MacroEllipse::storeSketch(const FeaturePtr& theFeature)
+{
+  const std::set<AttributePtr>& aRefs = theFeature->data()->refsToMe();
+  for (std::set<AttributePtr>::const_iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt)
+    if ((*anIt)->id() == SketchPlugin_Sketch::FEATURES_ID()) {
+      mySketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>((*anIt)->owner());
+      break;
+    }
+}
+
 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::center()
 {
   if (!myCenter)
index 7e0103b16b7057ee2d6ff4229c9430bcd9bf567b..8f0e88d83d605c03e30172a61b1b19a163f3261b 100644 (file)
@@ -94,6 +94,10 @@ public:
   /// Return created auxiliary minor axis
   SKETCHAPI_EXPORT std::shared_ptr<SketchAPI_Line> minorAxis();
 
+protected:
+  // find a parent sketch
+  void storeSketch(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
 private:
   /// Set flag of creation by center, major semi-axis and passed point.
   void setByCenterAndPassedPoints();
index f76f797c5aec8274bb6a7e5e323a830c337a7bfe..2955ac5308b76392fa433a7fe520577b39ef59e4 100644 (file)
@@ -86,6 +86,7 @@ SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc(
 
     fillAttribute(theReversed, reversed());
 
+    storeSketch(theFeature);
     execute();
   }
 }
index d21085a97d7205ab12fc8795507e921ae69d51b5..02226a400a45a9b3cedbecea5c469bd6db832fa2 100644 (file)
@@ -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 (file)
index 0000000..c7eb779
--- /dev/null
@@ -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()
index 006d18d2df73186bd021dee96f88535a38de0c18..46bf795d23447b188b798f95670f2ca263a759da 100644 (file)
 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())
index 1218c072ede8505941ab47a3e65b426ac690e2d7..40fa3800198cb7844f69da611cf102e6bc27928c 100644 (file)
@@ -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<PlaneGCSSolver_Storage> aStorage =
+          std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(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<PlaneGCSSolver_Storage> aStorage =
+        std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage);
+    GCS::SET_pD aParams;
+    aParams.insert(myAuxValue->scalar());
+    aStorage->removeParameters(aParams);
+  }
+  return SketchSolver_Constraint::remove();
+}
index a7505be5f1dd555d9a5a983afde81a1c14d4ff25..146cf876486fab239e5aa20f2014f147a683b89b 100644 (file)
@@ -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<EntityWrapperPtr>& theAttributes);
 
 private:
-  double myAuxValue; ///< scalar value to store ellipses focus distance
+  ScalarWrapperPtr myAuxValue; ///< scalar value to store ellipses focus distance
 };
 
 #endif