Salome HOME
bos#35152 [EDF] (2023-T1) Sketch Circle should allow user to position construction...
[modules/shaper.git] / src / SketchAPI / SketchAPI_Circle.cpp
index 8403b5896bce6a5dcf8ca51dc17dc6c36ffd2a0a..95d48f39706716786722bdf624af1ded13d85140 100644 (file)
@@ -1,8 +1,21 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
-
-// File:        SketchAPI_Circle.cpp
-// Created:     09 June 2016
-// Author:      Dmitry Bobylev
+// Copyright (C) 2014-2023  CEA, EDF
+//
+// 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
+//
 
 #include "SketchAPI_Circle.h"
 
@@ -13,6 +26,9 @@
 #include <ModelHighAPI_Selection.h>
 #include <ModelHighAPI_Tools.h>
 
+#include <SketchAPI_Point.h>
+#include <SketchPlugin_ConstraintCoincidenceInternal.h>
+
 //==================================================================================================
 SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature> & theFeature)
 : SketchAPI_SketchEntity(theFeature)
@@ -24,46 +40,22 @@ SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature> & the
 SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                    double theCenterX,
                                    double theCenterY,
-                                   double theRadius)
+                                   double theRadius, double theAngle)
 : SketchAPI_SketchEntity(theFeature)
 {
   if(initialize()) {
-    setByCenterAndRadius(theCenterX, theCenterY, theRadius);
+    setByCenterAndRadius(theCenterX, theCenterY, theRadius, theAngle);
   }
 }
 
 //==================================================================================================
 SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                    const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
-                                   double theRadius)
+                                   double theRadius, double theAngle)
 : SketchAPI_SketchEntity(theFeature)
 {
   if(initialize()) {
-    setByCenterAndRadius(theCenter, theRadius);
-  }
-}
-
-//==================================================================================================
-SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                   double theX1, double theY1,
-                                   double theX2, double theY2,
-                                   double theX3, double theY3)
-: SketchAPI_SketchEntity(theFeature)
-{
-  if (initialize()) {
-    setByThreePoints(theX1, theY1, theX2, theY2, theX3, theY3);
-  }
-}
-
-//==================================================================================================
-SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                   const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
-                                   const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
-                                   const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
-: SketchAPI_SketchEntity(theFeature)
-{
-  if (initialize()) {
-    setByThreePoints(thePoint1, thePoint2, thePoint3);
+    setByCenterAndRadius(theCenter, theRadius, theAngle);
   }
 }
 
@@ -79,7 +71,7 @@ SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature>& theF
 
 //==================================================================================================
 SketchAPI_Circle::SketchAPI_Circle(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                   const std::string& theExternalName)
+                                   const std::wstring& theExternalName)
 : SketchAPI_SketchEntity(theFeature)
 {
   if (initialize()) {
@@ -93,51 +85,90 @@ SketchAPI_Circle::~SketchAPI_Circle()
 
 }
 
-//==================================================================================================
-void SketchAPI_Circle::setByCenterAndRadius(double theCenterX, double theCenterY, double theRadius)
+// Create point on circle line
+void SketchAPI_Circle::createPoint()
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_CENTER_AND_RADIUS(), mycircleType);
-  fillAttribute(center(), theCenterX, theCenterY);
-  fillAttribute(theRadius, myradius);
+  // Find sketch
+  CompositeFeaturePtr aSketch;
+  const std::set<AttributePtr>& aRefs = feature()->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;
+    }
+  if (!aSketch)
+    return;
 
-  execute();
+  // create point on line
+  FeaturePtr aPointFeature = aSketch->addFeature(SketchPlugin_Point::ID());
+  aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(feature());
+
+  AttributePoint2DPtr aCoord = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+    aPointFeature->attribute(SketchPlugin_Point::COORD_ID()));
+
+  GeomPnt2dPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+    feature()->attribute(SketchPlugin_Circle::ROTATE_ID()))->pnt();
+
+  aCoord->setValue(aPnt);
+  aPointFeature->execute();
+
+  FeaturePtr aConstraint = aSketch->addFeature(SketchPlugin_ConstraintCoincidenceInternal::ID());
+  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+    aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+  aRefAttr->setAttr(feature()->attribute(SketchPlugin_Circle::ROTATE_ID()));
+
+  aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+    aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+  aRefAttr->setAttr(aCoord);
+
+  feature()->reference(SketchPlugin_Circle::ROTATE_REF_ID())->setValue(aPointFeature);
 }
 
 //==================================================================================================
-void SketchAPI_Circle::setByCenterAndRadius(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
-                                            double theRadius)
+void SketchAPI_Circle::setByCenterAndRadius(double theCenterX, double theCenterY,
+                                            double theRadius, double theAngle)
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_CENTER_AND_RADIUS(), mycircleType);
-  fillAttribute(theCenter, mycenter);
+  fillAttribute(center(), theCenterX, theCenterY);
   fillAttribute(theRadius, myradius);
+  fillAttribute(theAngle, myangle);
 
-  execute();
+  bool isNeedPoint =
+    feature()->integer(SketchPlugin_Circle::VERSION_ID())->value() > SketchPlugin_Circle::THE_VERSION_0;
+  if (isNeedPoint)
+  {
+    fillAttribute(theAngle, angle());
+
+    execute();
+    createPoint();
+  }
+  else
+  {
+    execute();
+  }
 }
 
 //==================================================================================================
-void SketchAPI_Circle::setByThreePoints(double theX1, double theY1,
-                                        double theX2, double theY2,
-                                        double theX3, double theY3)
+void SketchAPI_Circle::setByCenterAndRadius(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                                            double theRadius, double theAngle)
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(firstPoint(), theX1, theY1);
-  fillAttribute(secondPoint(), theX2, theY2);
-  fillAttribute(thirdPoint(), theX3, theY3);
+  fillAttribute(theCenter, mycenter);
+  fillAttribute(theRadius, myradius);
 
-  execute();
-}
+  bool isNeedPoint =
+    feature()->integer(SketchPlugin_Circle::VERSION_ID())->value() > SketchPlugin_Circle::THE_VERSION_0;
 
-//==================================================================================================
-void SketchAPI_Circle::setByThreePoints(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
-                                        const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
-                                        const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
-{
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(thePoint1, myfirstPoint);
-  fillAttribute(thePoint2, mysecondPoint);
-  fillAttribute(thePoint3, mythirdPoint);
+  if (isNeedPoint)
+  {
+    fillAttribute(theAngle, angle());
 
-  execute();
+    execute();
+    createPoint();
+  }
+  else
+  {
+    execute();
+  }
 }
 
 //==================================================================================================
@@ -149,7 +180,7 @@ void SketchAPI_Circle::setByExternal(const ModelHighAPI_Selection & theExternal)
 }
 
 //==================================================================================================
-void SketchAPI_Circle::setByExternalName(const std::string & theExternalName)
+void SketchAPI_Circle::setByExternalName(const std::wstring & theExternalName)
 {
   fillAttribute(ModelHighAPI_Selection("EDGE", theExternalName), external());
 
@@ -159,7 +190,6 @@ void SketchAPI_Circle::setByExternalName(const std::string & theExternalName)
 //==================================================================================================
 void SketchAPI_Circle::setCenter(double theX, double theY)
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_CENTER_AND_RADIUS(), mycircleType);
   fillAttribute(center(), theX, theY);
 
   execute();
@@ -168,7 +198,6 @@ void SketchAPI_Circle::setCenter(double theX, double theY)
 //==================================================================================================
 void SketchAPI_Circle::setCenter(const std::shared_ptr<GeomAPI_Pnt2d> & theCenter)
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_CENTER_AND_RADIUS(), mycircleType);
   fillAttribute(theCenter, mycenter);
 
   execute();
@@ -177,64 +206,35 @@ void SketchAPI_Circle::setCenter(const std::shared_ptr<GeomAPI_Pnt2d> & theCente
 //==================================================================================================
 void SketchAPI_Circle::setRadius(double theRadius)
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_CENTER_AND_RADIUS(), mycircleType);
   fillAttribute(ModelHighAPI_Double(theRadius), myradius);
 
   execute();
 }
 
 //==================================================================================================
-void SketchAPI_Circle::setFirstPoint(double theX, double theY)
+void SketchAPI_Circle::setAngle(double theAngle)
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(firstPoint(), theX, theY);
+  fillAttribute(ModelHighAPI_Double(theAngle), myangle);
 
   execute();
 }
 
 //==================================================================================================
-void SketchAPI_Circle::setFirstPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+// Return created point
+std::shared_ptr<SketchAPI_SketchEntity> SketchAPI_Circle::createdPoint() const
 {
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(thePoint, myfirstPoint);
+  std::shared_ptr<SketchAPI_SketchEntity> anEnt;
 
-  execute();
-}
+  AttributeReferencePtr anRef = feature()->reference(SketchPlugin_Circle::ROTATE_REF_ID());
+  if (!anRef->isInitialized())
+    return anEnt;
 
-//==================================================================================================
-void SketchAPI_Circle::setSecondPoint(double theX, double theY)
-{
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(secondPoint(), theX, theY);
-
-  execute();
-}
-
-//==================================================================================================
-void SketchAPI_Circle::setSecondPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
-{
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(thePoint, mysecondPoint);
-
-  execute();
-}
-
-//==================================================================================================
-void SketchAPI_Circle::setThirdPoint(double theX, double theY)
-{
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(thirdPoint(), theX, theY);
-
-  execute();
-}
-
-//==================================================================================================
-void SketchAPI_Circle::setThirdPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
-{
-  fillAttribute(SketchPlugin_Circle::CIRCLE_TYPE_THREE_POINTS(), mycircleType);
-  fillAttribute(thePoint, mythirdPoint);
-
-  execute();
+  FeaturePtr aFeature = ModelAPI_Feature::feature(anRef->value());
+  if (aFeature && aFeature->getKind() == SketchPlugin_Point::ID())
+  {
+    anEnt = std::shared_ptr < SketchAPI_SketchEntity>(new SketchAPI_Point(aFeature));
+  }
+  return anEnt;
 }
 
 //==================================================================================================
@@ -247,19 +247,25 @@ void SketchAPI_Circle::dump(ModelHighAPI_Dumper& theDumper) const
   const std::string& aSketchName = theDumper.parentName(aBase);
 
   AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
-  if (anExternal->value()) {
+  std::string aComName = aBase->integer(SketchPlugin_Circle::VERSION_ID())->value() > SketchPlugin_Circle::THE_VERSION_0 ?
+    "addCircleWithPoint" : "addCircle";
+
+  if (anExternal->context()) {
     // circle is external
-    theDumper << aBase << " = " << aSketchName << ".addCircle(" << anExternal << ")" << std::endl;
-  } else {
-    AttributeStringPtr aType = circleType();
-    if (aType->value() == SketchPlugin_Circle::CIRCLE_TYPE_CENTER_AND_RADIUS()) {
-      // circle given by center and radius
-      theDumper << aBase << " = " << aSketchName << ".addCircle("
-                << center() << ", " << radius() << ")" << std::endl;
-    } else {
-      // circle given by three points
-      theDumper << aBase << " = " << aSketchName << ".addCircle(" << firstPoint() << ", "
-                << secondPoint() << ", " << thirdPoint() << ")" << std::endl;
+    theDumper << aBase << " = " << aSketchName << "." << aComName << "(" << anExternal << ")" << std::endl;
+  }
+  else {// circle given by center and radius
+    theDumper << aBase << " = " << aSketchName << "." << aComName << "(" << center() << ", " << radius();
+    if (aBase->integer(SketchPlugin_Circle::VERSION_ID())->value() > SketchPlugin_Circle::THE_VERSION_0)
+    {
+      theDumper << ", " << angle() << ")" << std::endl;
+      std::shared_ptr<SketchAPI_SketchEntity> aPoint = createdPoint();
+      if (aPoint)
+        theDumper << aPoint->feature() << " = " << theDumper.name(aBase) << ".createdPoint()" << std::endl;
+    }
+    else
+    {
+      theDumper << ")" << std::endl;
     }
   }
   // dump "auxiliary" flag if necessary