Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
authorazv <azv@opencascade.com>
Thu, 26 Sep 2019 12:45:19 +0000 (15:45 +0300)
committerazv <azv@opencascade.com>
Thu, 26 Sep 2019 14:01:11 +0000 (17:01 +0300)
Constraint Equal for ellipses and elliptic arcs. This is a workaround for PlaneGCS. It avoids using GCS::ConstraintEqualMajorAxesConic which changes parameters of the curves (updates pointers in curves to own array).

src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp
src/SketchSolver/SketchSolver_ConstraintEqual.cpp
src/SketchSolver/SketchSolver_ConstraintEqual.h

index a889f1068cf658ccc4a8248a981a90efefcddbaf..b8c9de51f21954c6a2ebeb87bdd92136c94ba2a0 100644 (file)
@@ -26,6 +26,7 @@
 #include "SketchPlugin_ConstraintRigid.h"
 #include "SketchPlugin_ConstraintTangent.h"
 #include "SketchPlugin_Ellipse.h"
+#include "SketchPlugin_EllipticArc.h"
 #include "SketchPlugin_Fillet.h"
 #include "SketchPlugin_Line.h"
 #include "SketchPlugin_MacroArc.h"
@@ -307,7 +308,8 @@ bool SketchPlugin_EqualAttrValidator::isValid(const AttributePtr& theAttribute,
     if (aFeature->getKind() != SketchPlugin_Line::ID() &&
         aFeature->getKind() != SketchPlugin_Circle::ID() &&
         aFeature->getKind() != SketchPlugin_Arc::ID() &&
-        aFeature->getKind() != SketchPlugin_Ellipse::ID()) {
+        aFeature->getKind() != SketchPlugin_Ellipse::ID() &&
+        aFeature->getKind() != SketchPlugin_EllipticArc::ID()) {
       theError = "The %1 feature is not supported by the Equal constraint.";
       theError.arg(aFeature->getKind());
       // wrong type of attribute
@@ -323,7 +325,8 @@ bool SketchPlugin_EqualAttrValidator::isValid(const AttributePtr& theAttribute,
   }
   if (!isOk) {
     // ellipse and elliptic arc may be equal
-    // TODO
+    isOk = (aType[0] == SketchPlugin_EllipticArc::ID() && aType[1] == SketchPlugin_Ellipse::ID())
+        || (aType[0] == SketchPlugin_Ellipse::ID() && aType[1] == SketchPlugin_EllipticArc::ID());
   }
   if (!isOk) {
     theError = "Features with kinds %1 and %2 can not be equal.";
index b4e0056e2564c2e9c1c03457fc42c1d3464737ec..fc543f5b053b8cd25ab0185437a480c344ab85c5 100644 (file)
@@ -79,6 +79,7 @@ enum SketchSolver_ConstraintType {
   CONSTRAINT_EQUAL_LINES,
   CONSTRAINT_EQUAL_LINE_ARC,
   CONSTRAINT_EQUAL_RADIUS,
+  CONSTRAINT_EQUAL_ELLIPSES,
   CONSTRAINT_TANGENT,         // base tangency if we don't know the measured objects yet
   CONSTRAINT_TANGENT_CIRCLE_LINE,
   CONSTRAINT_TANGENT_CURVE_CURVE,
index 5aeb10987fe3c5fd56e99bd5eb9ff499a20617e4..35cbb4d722daca0db3431ee468d7bd03919e922f 100644 (file)
@@ -241,6 +241,7 @@ ConstraintWrapperPtr PlaneGCSSolver_Tools::createConstraint(
                                             GCS_EDGE_WRAPPER(theEntity2));
     break;
   case CONSTRAINT_EQUAL_LINES:
+  case CONSTRAINT_EQUAL_ELLIPSES:
     anIntermediate = GCS_SCALAR_WRAPPER(theValue); // parameter is used to store length of lines
   case CONSTRAINT_EQUAL_LINE_ARC:
   case CONSTRAINT_EQUAL_RADIUS:
@@ -654,25 +655,28 @@ ConstraintWrapperPtr createConstraintEqual(
         new GCS::ConstraintP2PDistance(aLine2->p1, aLine2->p2, theIntermed->scalar())));
     // update value of intermediate parameter
     theIntermed->setValue(distance(aLine1->p1, aLine1->p2));
-  } else {
+  }
+  else if (theType == CONSTRAINT_EQUAL_ELLIPSES) {
+    std::shared_ptr<GCS::Ellipse> anEllipse1 =
+        std::dynamic_pointer_cast<GCS::Ellipse>(theEntity1->entity());
+    std::shared_ptr<GCS::Ellipse> anEllipse2 =
+        std::dynamic_pointer_cast<GCS::Ellipse>(theEntity2->entity());
+
+    aConstrList.push_back(GCSConstraintPtr(
+        new GCS::ConstraintEqual(anEllipse1->radmin, anEllipse2->radmin)));
+    aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+        anEllipse1->center, anEllipse1->focus1, theIntermed->scalar())));
+    aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+        anEllipse2->center, anEllipse2->focus1, theIntermed->scalar())));
+    // update value of intermediate parameter
+    theIntermed->setValue(distance(anEllipse1->center, anEllipse1->focus1));
+  }
+  else {
     std::shared_ptr<GCS::Circle> aCirc1 =
         std::dynamic_pointer_cast<GCS::Circle>(theEntity1->entity());
     std::shared_ptr<GCS::Circle> aCirc2 =
         std::dynamic_pointer_cast<GCS::Circle>(theEntity2->entity());
-
-    if (aCirc1 && aCirc2)
-      aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(aCirc1->rad, aCirc2->rad)));
-    else {
-      std::shared_ptr<GCS::Ellipse> anEllipse1 =
-          std::dynamic_pointer_cast<GCS::Ellipse>(theEntity1->entity());
-      std::shared_ptr<GCS::Ellipse> anEllipse2 =
-          std::dynamic_pointer_cast<GCS::Ellipse>(theEntity2->entity());
-
-      aConstrList.push_back(GCSConstraintPtr(
-          new GCS::ConstraintEqual(anEllipse1->radmin, anEllipse2->radmin)));
-      aConstrList.push_back(GCSConstraintPtr(
-          new GCS::ConstraintEqualMajorAxesConic(anEllipse1.get(), anEllipse2.get())));
-    }
+    aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(aCirc1->rad, aCirc2->rad)));
   }
 
   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
index 8d3bab21b74ccb56d75e2d8dcf4d6a6ef3c3b38d..1218c072ede8505941ab47a3e65b426ac690e2d7 100644 (file)
@@ -63,7 +63,12 @@ void SketchSolver_ConstraintEqual::getAttributes(
 
   switch (aNbLines) {
   case 0:
-    myType = CONSTRAINT_EQUAL_RADIUS;
+    if (aNbEllipses == 2) {
+      myType = CONSTRAINT_EQUAL_ELLIPSES;
+      theValue = ScalarWrapperPtr(new PlaneGCSSolver_ScalarWrapper(&myAuxValue));
+    }
+    else
+      myType = CONSTRAINT_EQUAL_RADIUS;
     break;
   case 1:
     myType = CONSTRAINT_EQUAL_LINE_ARC;
index b7495d2d8d3f111870af70ff2b977c632d346d7f..a7505be5f1dd555d9a5a983afde81a1c14d4ff25 100644 (file)
@@ -40,6 +40,9 @@ protected:
   /// \param[out] theAttributes list of attributes to be filled
   virtual void getAttributes(EntityWrapperPtr&              theValue,
                              std::vector<EntityWrapperPtr>& theAttributes);
+
+private:
+  double myAuxValue; ///< scalar value to store ellipses focus distance
 };
 
 #endif