]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Update movement of a circle
authorazv <azv@opencascade.com>
Tue, 2 Feb 2016 09:19:01 +0000 (12:19 +0300)
committerazv <azv@opencascade.com>
Wed, 3 Feb 2016 10:32:25 +0000 (13:32 +0300)
src/GeomAPI/GeomAPI_Circ2d.cpp
src/GeomAPI/GeomAPI_Circ2d.h
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_Circle.h

index c809e567e843c9b099b546887e4f33c6931df122..a5815140920eb6e6f12a01800c0fe6d6518ec8a0 100644 (file)
@@ -44,6 +44,35 @@ static gp_Circ2d* newCirc2d(const double theCenterX, const double theCenterY,
   return newCirc2d(theCenterX, theCenterY, aDir, aRadius);
 }
 
+static gp_Circ2d* newCirc2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
+                            const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
+                            const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
+{
+  gp_XY aFirstPnt(theFirstPoint->x(), theFirstPoint->y());
+  gp_XY aSecondPnt(theSecondPoint->x(), theSecondPoint->y());
+  gp_XY aThirdPnt(theThirdPoint->x(), theThirdPoint->y());
+
+  gp_XY aVec12 = aSecondPnt - aFirstPnt;
+  gp_XY aVec23 = aThirdPnt - aSecondPnt;
+  gp_XY aVec31 = aFirstPnt - aThirdPnt;
+  // square of parallelogram
+  double aSquare2 = aVec12.Crossed(aVec23);
+  aSquare2 *= aSquare2 * 2.0;
+  if (aSquare2 < 1.e-20)
+    return NULL;
+  // coefficients to calculate center
+  double aCoeff1 = aVec23.Dot(aVec23) / aSquare2 * aVec12.Dot(aVec31.Reversed());
+  double aCoeff2 = aVec31.Dot(aVec31) / aSquare2 * aVec23.Dot(aVec12.Reversed());
+  double aCoeff3 = aVec12.Dot(aVec12) / aSquare2 * aVec31.Dot(aVec23.Reversed());
+  // center
+  gp_XY aCenter = aFirstPnt * aCoeff1 + aSecondPnt * aCoeff2 + aThirdPnt * aCoeff3;
+  // radius
+  double aRadius = (aFirstPnt - aCenter).Modulus();
+
+  gp_Dir2d aDir(aFirstPnt - aCenter);
+  return newCirc2d(aCenter.X(), aCenter.Y(), aDir, aRadius);
+}
+
 GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
                                const std::shared_ptr<GeomAPI_Pnt2d>& theCirclePoint)
     : GeomAPI_Interface(
@@ -56,7 +85,13 @@ GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
     : GeomAPI_Interface(
         newCirc2d(theCenter->x(), theCenter->y(), theDir->impl<gp_Dir2d>(), theRadius))
 {
+}
 
+GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
+                               const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
+                               const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
+    : GeomAPI_Interface(newCirc2d(theFirstPoint, theSecondPoint, theThirdPoint))
+{
 }
 
 const std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Circ2d::project(
@@ -89,12 +124,16 @@ const std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Circ2d::project(
 
 const std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Circ2d::center() const
 {
+  if (!MY_CIRC2D)
+    return std::shared_ptr<GeomAPI_Pnt2d>();
   const gp_Pnt2d& aCenter = MY_CIRC2D->Location();
   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aCenter.X(), aCenter.Y()));
 }
 
 double GeomAPI_Circ2d::radius() const
 {
+  if (!MY_CIRC2D)
+    return 0.0;
   return MY_CIRC2D->Radius();
 }
 
index 478c9986a76e7d3648569f78c7973b71e1c3a4a7..d6ad5c7553a1bb606a88d8bb055e66d9863c9dfc 100644 (file)
@@ -31,6 +31,12 @@ class GeomAPI_Circ2d : public GeomAPI_Interface
   GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
                  const std::shared_ptr<GeomAPI_Dir2d>& theDir, double theRadius);
 
+  /// Creation of circle defined by three points lying on it
+  GEOMAPI_EXPORT
+  GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
+                 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
+                 const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint);
+
   /// Return center of the circle
   GEOMAPI_EXPORT 
   const std::shared_ptr<GeomAPI_Pnt2d> center() const;
index 858c2e7efaf1fd77540610d742acb797bece4351..ea819628e51eae8e7778effaa5f9b71a8169d6e4 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <GeomAPI_Pnt2d.h>
 #include <GeomAPI_Circ.h>
+#include <GeomAPI_Circ2d.h>
 #include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
 #include <GeomDataAPI_Dir.h>
@@ -68,12 +69,6 @@ namespace {
   }
 }
 
-static void calculateCircleOnThreePoints(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPnt,
-                                         const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPnt,
-                                         const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPnt,
-                                               std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
-                                               double&                         theRadius);
-
 
 SketchPlugin_Circle::SketchPlugin_Circle()
     : SketchPlugin_SketchEntity()
@@ -134,7 +129,7 @@ void SketchPlugin_Circle::execute()
 AISObjectPtr SketchPlugin_Circle::getAISObject(AISObjectPtr thePrevious)
 {
   SketchPlugin_Sketch* aSketch = sketch();
-  if (aSketch) {
+  if (aSketch && !isFeatureValid()) {
     // compute a circle point in 3D view
     std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
         GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
@@ -171,15 +166,37 @@ AISObjectPtr SketchPlugin_Circle::getAISObject(AISObjectPtr thePrevious)
   return AISObjectPtr();
 }
 
+bool SketchPlugin_Circle::isFeatureValid()
+{
+  std::shared_ptr<GeomDataAPI_Point2D> aCenter = 
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aFirstPnt =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(FIRST_POINT_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aSecondPnt =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(SECOND_POINT_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aThirdPnt =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(THIRD_POINT_ID()));
+
+  return aCenter->isInitialized() && aFirstPnt->isInitialized() &&
+         aSecondPnt->isInitialized() && aThirdPnt->isInitialized();
+}
+
 void SketchPlugin_Circle::move(double theDeltaX, double theDeltaY)
 {
   std::shared_ptr<ModelAPI_Data> aData = data();
   if (!aData->isValid())
     return;
 
-  std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+  std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aData->attribute(CENTER_ID()));
-  aPoint1->move(theDeltaX, theDeltaY);
+  aPoint->move(theDeltaX, theDeltaY);
+
+  aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(FIRST_POINT_ID()));
+  aPoint->move(theDeltaX, theDeltaY);
+  aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SECOND_POINT_ID()));
+  aPoint->move(theDeltaX, theDeltaY);
+  aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(THIRD_POINT_ID()));
+  aPoint->move(theDeltaX, theDeltaY);
 }
 
 bool SketchPlugin_Circle::isFixed() {
@@ -263,10 +280,12 @@ void SketchPlugin_Circle::attributeChanged(const std::string& theID) {
       aCenterAttr->setValue(aCoord->x(), aCoord->y());
       aRadiusAttr->setValue(aRadius);
     } else {
-      std::shared_ptr<GeomAPI_Pnt2d> aCenter;
-      double aRadius;
-      calculateCircleOnThreePoints(aPoints[0], aPoints[1], aPoints[2], aCenter, aRadius);
+      std::shared_ptr<GeomAPI_Circ2d> aCircle(
+          new GeomAPI_Circ2d(aPoints[0], aPoints[1], aPoints[2]));
+
+      std::shared_ptr<GeomAPI_Pnt2d> aCenter = aCircle->center();
       if (aCenter) {
+        double aRadius = aCircle->radius();
         aCenterAttr->setValue(aCenter->x(), aCenter->y());
         aRadiusAttr->setValue(aRadius);
       }
@@ -275,33 +294,3 @@ void SketchPlugin_Circle::attributeChanged(const std::string& theID) {
     data()->blockSendAttributeUpdated(false);
   }
 }
-
-
-
-
-// ==========   Auxiliary functions   =========================
-void calculateCircleOnThreePoints(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPnt,
-                                  const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPnt,
-                                  const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPnt,
-                                        std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
-                                        double&                         theRadius)
-{
-  std::shared_ptr<GeomAPI_XY> aVec12 = theSecondPnt->xy()->decreased(theFirstPnt->xy());
-  std::shared_ptr<GeomAPI_XY> aVec23 = theThirdPnt->xy()->decreased(theSecondPnt->xy());
-  std::shared_ptr<GeomAPI_XY> aVec31 = theFirstPnt->xy()->decreased(theThirdPnt->xy());
-  // square of parallelogram
-  double aSquare2 = aVec12->cross(aVec23);
-  aSquare2 *= aSquare2 * 2.0;
-  if (aSquare2 < 1.e-20)
-    return;
-  // coefficients to calculate center
-  double aCoeff1 = aVec23->dot(aVec23) / aSquare2 * aVec12->dot(aVec31->multiplied(-1.0));
-  double aCoeff2 = aVec31->dot(aVec31) / aSquare2 * aVec23->dot(aVec12->multiplied(-1.0));
-  double aCoeff3 = aVec12->dot(aVec12) / aSquare2 * aVec31->dot(aVec23->multiplied(-1.0));
-  // center
-  std::shared_ptr<GeomAPI_XY> aCenter = theFirstPnt->xy()->multiplied(aCoeff1)->added(
-      theSecondPnt->xy()->multiplied(aCoeff2))->added(theThirdPnt->xy()->multiplied(aCoeff3));
-  theCenter = std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aCenter));
-  // radius
-  theRadius = theFirstPnt->distance(theCenter);
-}
index fe0ca3a423963dcb39ca593be5b92b54eb57d0af..daf4d2651eacb7d921a8b901271a4757d6331c9f 100644 (file)
@@ -76,6 +76,10 @@ class SketchPlugin_Circle : public SketchPlugin_SketchEntity, public GeomAPI_IPr
 protected:
   /// \brief Initializes attributes of derived class.
   virtual void initDerivedClassAttributes();
+
+private:
+  /// Returns true if all obligatory attributes are initialized
+  bool isFeatureValid();
 };
 
 #endif