]> 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>
Thu, 19 Sep 2019 11:55:29 +0000 (14:55 +0300)
committerazv <azv@opencascade.com>
Sun, 22 Sep 2019 13:14:09 +0000 (16:14 +0300)
Constraint Equal for ellipses

src/GeomAPI/GeomAPI_Curve.cpp
src/GeomAPI/GeomAPI_Curve.h
src/PartSet/PartSet_Validators.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/Test/TestConstraintEqualEllipse.py [new file with mode: 0644]
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
src/SketchSolver/SketchSolver_ConstraintEqual.cpp
src/SketcherPrs/SketcherPrs_PositionMgr.cpp

index 7276c848597b451c2dca046099d894e6b26ac7aa..46635b0a838e1a8c1c037d20bd5eb3f0259f56c0 100644 (file)
@@ -23,6 +23,7 @@
 #include <TopoDS_Shape.hxx>
 #include <Geom_Circle.hxx>
 #include <Geom_Curve.hxx>
+#include <Geom_Ellipse.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_TrimmedCurve.hxx>
 #include <BRep_Tool.hxx>
@@ -65,6 +66,11 @@ bool GeomAPI_Curve::isCircle() const
   return !isNull() && MY_CURVE->DynamicType() == STANDARD_TYPE(Geom_Circle);
 }
 
+bool GeomAPI_Curve::isEllipse() const
+{
+  return !isNull() && MY_CURVE->DynamicType() == STANDARD_TYPE(Geom_Ellipse);
+}
+
 std::shared_ptr<GeomAPI_Pnt> GeomAPI_Curve::getPoint(double theParam)
 {
   GeomAdaptor_Curve aAdaptor(MY_CURVE, myStart, myEnd);
index 30b9bd99840b9ebae2cc9637b2f0a055b08e4fd2..65ba0d5b755150c8178be3b69b48d4bc09db87dd 100644 (file)
@@ -57,6 +57,10 @@ class GeomAPI_Curve : public GeomAPI_Interface
   GEOMAPI_EXPORT
   virtual bool isCircle() const;
 
+  /// Returns whether the curve is elliptic
+  GEOMAPI_EXPORT
+  virtual bool isEllipse() const;
+
   /// Returns start parameter of the curve
   GEOMAPI_EXPORT
   double startParam() const { return myStart; }
index 4b72de19888a5286ef2696dc4b2e3c3a50581179..0b5a42bd5e9613775ef46c7f02a74037bec0a1fa 100644 (file)
@@ -335,12 +335,12 @@ bool PartSet_EqualSelection::isValid(const ModuleBase_ISelection* theSelection,
             aType = 1;
           else if (aType != 1)
             return false;
-        } else if (aEdge.isCircle()) {
+        } else if (aEdge.isCircle() || aEdge.isArc()) {
           if (aCount == 1)
             aType = 2;
           else if (aType != 2)
             return false;
-        } else if (aEdge.isArc()) {
+        } else if (aEdge.isEllipse()) {
           if (aCount == 1)
             aType = 3;
           else if (aType != 3)
index 3476cd275104a14e9d4d8063d4a97a7d34ea52ec..55a9aa143553f01ae988ac3df9d5bf3a586db35e 100644 (file)
@@ -214,6 +214,7 @@ ADD_UNIT_TESTS(
   TestConstraintDistanceHorizontal.py
   TestConstraintDistanceVertical.py
   TestConstraintEqual.py
+  TestConstraintEqualEllipse.py
   TestConstraintFixed.py
   TestConstraintHorizontal.py
   TestConstraintHorizontalValidator.py
index c248e7dc77cedef2630bf21aa76b94079b3bf0fc..af85ea6f1da8348d20ab4f2b369a240901549500 100644 (file)
@@ -25,6 +25,7 @@
 #include "SketchPlugin_ConstraintDistance.h"
 #include "SketchPlugin_ConstraintRigid.h"
 #include "SketchPlugin_ConstraintTangent.h"
+#include "SketchPlugin_Ellipse.h"
 #include "SketchPlugin_Fillet.h"
 #include "SketchPlugin_Line.h"
 #include "SketchPlugin_MacroArc.h"
@@ -326,17 +327,28 @@ bool SketchPlugin_EqualAttrValidator::isValid(const AttributePtr& theAttribute,
     aType[i] = aFeature->getKind();
     if (aFeature->getKind() != SketchPlugin_Line::ID() &&
         aFeature->getKind() != SketchPlugin_Circle::ID() &&
-        aFeature->getKind() != SketchPlugin_Arc::ID()) {
-      theError = "The %1 feature kind of attribute is wrong. It should be %2 or %3 or %4";
+        aFeature->getKind() != SketchPlugin_Arc::ID() &&
+        aFeature->getKind() != SketchPlugin_Ellipse::ID()) {
+      theError = "The %1 feature kind of attribute is wrong. It should be %2 or %3 or %4 or %5";
       theError.arg(aFeature->getKind()).arg(SketchPlugin_Line::ID())
-          .arg(SketchPlugin_Circle::ID()).arg(SketchPlugin_Arc::ID());
+          .arg(SketchPlugin_Circle::ID()).arg(SketchPlugin_Arc::ID())
+          .arg(SketchPlugin_Ellipse::ID());
       // wrong type of attribute
       return false;
     }
   }
 
-  if ((aType[0] == SketchPlugin_Line::ID() || aType[1] == SketchPlugin_Line::ID()) &&
-      aType[0] != aType[1]) {
+  bool isOk = aType[0] == aType[1];
+  if (!isOk) {
+    // circle and arc may be equal
+    isOk = (aType[0] == SketchPlugin_Arc::ID() && aType[1] == SketchPlugin_Circle::ID())
+        || (aType[0] == SketchPlugin_Circle::ID() && aType[1] == SketchPlugin_Arc::ID());
+  }
+  if (!isOk) {
+    // ellipse and elliptic arc may be equal
+    // TODO
+  }
+  if (!isOk) {
     theError = "Feature with kinds %1 and %2 can not be equal.";
     theError.arg(aType[0]).arg(aType[1]);
     return false;
diff --git a/src/SketchPlugin/Test/TestConstraintEqualEllipse.py b/src/SketchPlugin/Test/TestConstraintEqualEllipse.py
new file mode 100644 (file)
index 0000000..006d18d
--- /dev/null
@@ -0,0 +1,48 @@
+# 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 "Equal" applied to the pair of ellipses
+"""
+
+from salome.shaper import model
+import math
+
+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")
+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")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchEllipse_1.result(), SketchEllipse_2.result())
+model.do()
+model.end()
+
+TOLERANCE = 1.e-7
+
+dist1 = model.distancePointPoint(SketchEllipse_1.majorAxisNegative(), SketchEllipse_1.majorAxisPositive())
+dist2 = model.distancePointPoint(SketchEllipse_2.majorAxisNegative(), SketchEllipse_2.majorAxisPositive())
+assert(math.fabs(dist1 - dist2) < TOLERANCE)
+
+dist1 = model.distancePointPoint(SketchEllipse_1.minorAxisNegative(), SketchEllipse_1.minorAxisPositive())
+dist2 = model.distancePointPoint(SketchEllipse_2.minorAxisNegative(), SketchEllipse_2.minorAxisPositive())
+assert(math.fabs(dist1 - dist2) < TOLERANCE)
+
+assert(model.checkPythonDump())
index 319ddd2717259dc8fce32b974efedc19d125223a..8b1c3db3113d2535d1d2ea9632cbc7c6e3df93e0 100644 (file)
         icon="icons/Sketch/equal.png"
                helpfile="equalFeature.html">
         <sketch_shape_selector id="ConstraintEntityA"
-            label="First object" tooltip="Select line, circle or arc" shape_types="edge">
+            label="First object" tooltip="Select edge" shape_types="edge">
           <validator id="PartSet_DifferentObjects"/>
           <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
         </sketch_shape_selector>
 
         <sketch_shape_selector id="ConstraintEntityB"
-            label="Second object" tooltip="Select line, circle or arc" shape_types="edge">
+            label="Second object" tooltip="Select edge" shape_types="edge">
           <validator id="SketchPlugin_EqualAttr" parameters="ConstraintEntityA"/>
           <validator id="PartSet_DifferentObjects"/>
           <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
index 37aba1bd8b0c7166afd4fce5998be7e62437f26d..c2893b1f8faf4a5e3c5d39f97dfef3ca2f87e59e 100644 (file)
@@ -39,7 +39,7 @@ typedef int ConstraintID;
 // Predefined values for identifiers
 const ConstraintID CID_UNKNOWN  =  0;
 const ConstraintID CID_MOVEMENT = -1;
-const ConstraintID CID_FICTIVE = 1024;
+const ConstraintID CID_FICTIVE  = 99;
 
 /// Types of entities
 enum SketchSolver_EntityType {
index e3d8f790a4ef7dd4590f198f614384982c1a8098..416b338b05d4dadbedc3a8da7686886c34ece178 100644 (file)
@@ -245,9 +245,12 @@ void PlaneGCSSolver_Solver::diagnose(const GCS::Algorithm& theAlgo)
 
 void PlaneGCSSolver_Solver::addFictiveConstraintIfNecessary()
 {
-  if (!myConstraints.empty() &&
-      myConstraints.find(CID_MOVEMENT) == myConstraints.end())
-    return;
+  bool hasOnlyMovement = true;
+  for (ConstraintMap::iterator anIt = myConstraints.begin();
+       anIt != myConstraints.end() && hasOnlyMovement; ++anIt)
+    hasOnlyMovement = anIt->first == CID_MOVEMENT;
+  if (!hasOnlyMovement)
+    return; // regular constraints are available too
 
   if (myFictiveConstraint)
     return; // no need several fictive constraints
@@ -266,12 +269,14 @@ void PlaneGCSSolver_Solver::addFictiveConstraintIfNecessary()
 void PlaneGCSSolver_Solver::removeFictiveConstraint()
 {
   if (myFictiveConstraint) {
-    myEquationSystem->removeConstraint(myFictiveConstraint);
+    myEquationSystem->clearByTag(myFictiveConstraint->getTag());
     myParameters.pop_back();
 
     GCS::VEC_pD aParams = myFictiveConstraint->params();
-    for (GCS::VEC_pD::iterator anIt = aParams.begin(); anIt != aParams.end(); ++ anIt)
-      delete *anIt;
+    for (GCS::VEC_pD::iterator anIt = aParams.begin(); anIt != aParams.end(); ++anIt) {
+      double* aPar = *anIt;
+      delete aPar;
+    }
     delete myFictiveConstraint;
     myFictiveConstraint = 0;
   }
index 2cb98d4a52ec8bf1ca09e79a4a06e43c0ae423ec..31fcca4a31826cc3d1c0c0f942093da095d9790c 100644 (file)
@@ -38,6 +38,7 @@ void SketchSolver_ConstraintEqual::getAttributes(
   int aNbLines = 0;
   int aNbArcs = 0;
   int aNbCircs = 0;
+  int aNbEllipses = 0;
   bool isArcFirst = false; // in line-arc equivalence, the line should be first
   std::vector<EntityWrapperPtr>::iterator anAttrIt = theAttributes.begin() + 2;
   for (; anAttrIt != theAttributes.end(); ++anAttrIt) {
@@ -50,10 +51,12 @@ void SketchSolver_ConstraintEqual::getAttributes(
       ++aNbArcs;
       isArcFirst = (aNbLines == 0);
     }
+    else if (aType == ENTITY_ELLIPSE || aType == ENTITY_ELLIPTICAL_ARC)
+      ++aNbEllipses;
   }
 
-  if (aNbLines + aNbArcs + aNbCircs != 2 ||
-     (aNbLines == aNbCircs && aNbArcs == 0)) {
+  if (aNbLines + aNbArcs + aNbCircs + aNbEllipses != 2 ||
+     (aNbArcs == 1 && aNbEllipses != 0) || aNbEllipses == 1) {
     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
     return;
   }
index 0a546233d9b33060c9ba1257475d3cd95622f06d..d803256d8baab56e89e6fe17ab1511f25f40cf58 100644 (file)
@@ -189,7 +189,7 @@ gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP)
     std::shared_ptr<GeomAPI_Curve> aCurve =
       std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
 
-    if (aCurve->isCircle()) {
+    if (aCurve->isCircle() || aCurve->isEllipse()) {
       Handle(Geom_Curve) aCurv = aCurve->impl<Handle_Geom_Curve>();
       GeomAPI_ProjectPointOnCurve anExtr(theP, aCurv);
       double aParam = anExtr.LowerDistanceParameter();