Salome HOME
bos #24513 Dealing with conflicting constraints
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_MacroEllipticArc.cpp
index 768e827134092cc66944132f81bcc90a660240d2..192884dbfb0a7c37d1abe43c22a77eb0f4220ac8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2017-2021  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
 
 #include <SketchPlugin_MacroEllipticArc.h>
 
-////#include <SketchPlugin_ConstraintCoincidenceInternal.h>
 #include <SketchPlugin_EllipticArc.h>
-////#include <SketchPlugin_Line.h>
 #include <SketchPlugin_MacroArcReentrantMessage.h>
-////#include <SketchPlugin_Point.h>
 #include <SketchPlugin_Tools.h>
 #include <SketchPlugin_Sketch.h>
 
@@ -45,6 +42,7 @@
 #include <GeomAlgoAPI_PointBuilder.h>
 
 
+const double TOLERANCE = 1.e-7;
 const double paramTolerance = 1.e-4;
 const double PI = 3.141592653589793238463;
 
@@ -86,6 +84,7 @@ void SketchPlugin_MacroEllipticArc::initAttributes()
 void SketchPlugin_MacroEllipticArc::execute()
 {
   FeaturePtr anEllipse = createEllipticArcFeature();
+  constraintsForEllipticArc(anEllipse);
 
   // message to init reentrant operation
   static Events_ID anId = SketchPlugin_MacroArcReentrantMessage::eventId();
@@ -95,7 +94,7 @@ void SketchPlugin_MacroEllipticArc::execute()
   Events_Loop::loop()->send(aMessage);
 }
 
-void SketchPlugin_MacroEllipticArc::attributeChanged(const std::string& theID)
+void SketchPlugin_MacroEllipticArc::attributeChanged(const std::string& /*theID*/)
 {
   static const int NB_POINTS = 4;
   std::string aPointAttrName[NB_POINTS] = { CENTER_ID(),
@@ -134,6 +133,9 @@ void SketchPlugin_MacroEllipticArc::attributeChanged(const std::string& theID)
   myStartPnt  = anEllipsePoints[2];
   myEndPnt    = anEllipsePoints[3];
 
+  if (myCenter->distance(myMajorAxis) < TOLERANCE)
+    return; // ellipse is not valid
+
   std::shared_ptr<GeomAPI_Ellipse2d> anEllipse;
   if (aNbInitialized == 2) {
     GeomDir2dPtr aXDir(new GeomAPI_Dir2d(anEllipsePoints[1]->x() - anEllipsePoints[0]->x(),
@@ -228,50 +230,6 @@ std::string SketchPlugin_MacroEllipticArc::processEvent(
 }
 // LCOV_EXCL_STOP
 
-////void SketchPlugin_MacroEllipticArc::constraintsForEllipseByCenterAxisAndPassed(
-////    FeaturePtr theEllipseFeature)
-////{
-////  // tangency on-the-fly is not applicable for ellipses
-////  static const bool isTangencyApplicable = false;
-////  // Create constraints.
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, FIRST_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::CENTER_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, SECOND_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  // make coincidence only if PASSED_POINT_REF_ID() refers a point but not an object
-////  if (!refattr(PASSED_POINT_REF_ID())->isObject()) {
-////    SketchPlugin_Tools::createCoincidenceOrTangency(
-////        this, PASSED_POINT_REF_ID(), AttributePtr(),
-////        theEllipseFeature->lastResult(), isTangencyApplicable);
-////  }
-////}
-////
-////void SketchPlugin_MacroEllipticArc::constraintsForEllipseByMajoxAxisAndPassed(
-////    FeaturePtr theEllipseFeature)
-////{
-////  // tangency on-the-fly is not applicable for ellipses
-////  static const bool isTangencyApplicable = false;
-////  // Create constraints.
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, FIRST_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, SECOND_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  // make coincidence only if PASSED_POINT_REF_ID() refers a point but not an object
-////  if (!refattr(PASSED_POINT_REF_ID())->isObject()) {
-////    SketchPlugin_Tools::createCoincidenceOrTangency(
-////        this, PASSED_POINT_REF_ID(), AttributePtr(),
-////        theEllipseFeature->lastResult(), isTangencyApplicable);
-////  }
-////}
-
 FeaturePtr SketchPlugin_MacroEllipticArc::createEllipticArcFeature()
 {
   GeomShapePtr anArc = getArcShape();
@@ -281,6 +239,8 @@ FeaturePtr SketchPlugin_MacroEllipticArc::createEllipticArcFeature()
     GeomEdgePtr anArcEdge = anArc->edge();
     aStartPoint = anArcEdge->firstPoint();
     aEndPoint = anArcEdge->lastPoint();
+    if (boolean(REVERSED_ID())->value())
+      std::swap(aStartPoint, aEndPoint);
 
     if (anArcEdge->isEllipse())
       anEllipse = anArcEdge->ellipse();
@@ -346,6 +306,32 @@ FeaturePtr SketchPlugin_MacroEllipticArc::createEllipticArcFeature()
   return aEllipseFeature;
 }
 
+void SketchPlugin_MacroEllipticArc::constraintsForEllipticArc(FeaturePtr theEllipticArc)
+{
+  // tangency on-the-fly is not applicable for elliptic arcs
+  static const bool isTangencyApplicable = false;
+  // Create constraints.
+  SketchPlugin_Tools::createCoincidenceOrTangency(
+      this, CENTER_REF_ID(),
+      theEllipticArc->attribute(SketchPlugin_EllipticArc::CENTER_ID()),
+      ObjectPtr(), isTangencyApplicable);
+  // make coincidence only if PASSED_POINT_REF_ID() refers a point but not an object
+  if (!refattr(MAJOR_AXIS_POINT_REF_ID())->isObject()) {
+    SketchPlugin_Tools::createCoincidenceOrTangency(
+        this, MAJOR_AXIS_POINT_REF_ID(),
+        AttributePtr(),
+        theEllipticArc->lastResult(), isTangencyApplicable);
+  }
+  SketchPlugin_Tools::createCoincidenceOrTangency(
+      this, START_POINT_REF_ID(),
+      theEllipticArc->attribute(SketchPlugin_EllipticArc::START_POINT_ID()),
+      ObjectPtr(), isTangencyApplicable);
+  SketchPlugin_Tools::createCoincidenceOrTangency(
+      this, END_POINT_REF_ID(),
+      theEllipticArc->attribute(SketchPlugin_EllipticArc::END_POINT_ID()),
+      ObjectPtr(), isTangencyApplicable);
+}
+
 AISObjectPtr SketchPlugin_MacroEllipticArc::getAISObject(AISObjectPtr thePrevious)
 {
   SketchPlugin_Sketch* aSketch = sketch();
@@ -368,6 +354,7 @@ AISObjectPtr SketchPlugin_MacroEllipticArc::getAISObject(AISObjectPtr thePreviou
   if (!anAIS)
     anAIS.reset(new GeomAPI_AISObject());
   anAIS->createShape(aCompound);
+  SketchPlugin_Tools::customizeFeaturePrs(anAIS, boolean(AUXILIARY_ID())->value());
   return anAIS;
 }
 
@@ -377,7 +364,7 @@ GeomShapePtr SketchPlugin_MacroEllipticArc::getArcShape()
     return GeomShapePtr();
 
   SketchPlugin_Sketch* aSketch = sketch();
-  if (!aSketch)
+  if (!aSketch || myCenter->distance(myMajorAxis) < 1.e-7)
     return GeomShapePtr();
 
   GeomPointPtr aCenter(aSketch->to3D(myCenter->x(), myCenter->y()));