Salome HOME
Update calculation of angle value (issue #788)
authorazv <azv@opencascade.com>
Tue, 25 Aug 2015 05:25:08 +0000 (08:25 +0300)
committerazv <azv@opencascade.com>
Tue, 25 Aug 2015 05:25:58 +0000 (08:25 +0300)
src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp
src/SketchSolver/CMakeLists.txt
src/SketchSolver/SketchSolver_Builder.cpp
src/SketchSolver/SketchSolver_Constraint.h
src/SketchSolver/SketchSolver_ConstraintAngle.cpp [new file with mode: 0644]
src/SketchSolver/SketchSolver_ConstraintAngle.h [new file with mode: 0644]

index 03c840b270a051812c87d0ca455c8427797d05e8..693fa9c848a67fe9c8600f7a22253076b7ca4cde 100644 (file)
@@ -23,6 +23,9 @@
 const double tolerance = 1.e-7;
 #define PI 3.1415926535897932
 
+/// \brief Calculate intersection point of two lines
+static std::shared_ptr<GeomAPI_Pnt2d> intersect(FeaturePtr theLine1, FeaturePtr theLine2);
+
 
 SketchPlugin_ConstraintAngle::SketchPlugin_ConstraintAngle()
 {
@@ -102,6 +105,22 @@ void SketchPlugin_ConstraintAngle::attributeChanged(const std::string& theID)
     // coordinates are calculated according to the center of shapes intersection
     std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+
+    std::shared_ptr<ModelAPI_Data> aData = data();
+    std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
+    FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
+    FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
+
+    // Intersection of lines
+    std::shared_ptr<GeomAPI_Pnt2d> anInter = intersect(aLineA, aLineB);
+    if (!anInter)
+      return;
+
+    myFlyoutUpdate = true;
+    std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutAttr->pnt()->xy()->decreased(anInter->xy());
+    if (aFlyoutDir->dot(aFlyoutDir) < tolerance * tolerance)
+      aFlyoutAttr->setValue(aFlyoutAttr->x() + tolerance, aFlyoutAttr->y());
+    myFlyoutUpdate = false;
   }
 }
 
@@ -114,6 +133,11 @@ double SketchPlugin_ConstraintAngle::calculateAngle()
   FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
   FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
 
+  // Intersection of lines
+  std::shared_ptr<GeomAPI_Pnt2d> anInter = intersect(aLineA, aLineB);
+  if (!anInter)
+    return anAngle;
+
   // Start and end points of lines
   std::shared_ptr<GeomDataAPI_Point2D> aPointA1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aLineA->attribute(SketchPlugin_Line::START_ID()));
@@ -129,15 +153,6 @@ double SketchPlugin_ConstraintAngle::calculateAngle()
   std::shared_ptr<GeomAPI_Pnt2d> aEndA   = aPointA2->pnt();
   std::shared_ptr<GeomAPI_Pnt2d> aStartB = aPointB1->pnt();
   std::shared_ptr<GeomAPI_Pnt2d> aEndB   = aPointB2->pnt();
-  if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance)
-    return anAngle;
-
-  // Lines and their intersection point
-  std::shared_ptr<GeomAPI_Lin2d> aLA(new GeomAPI_Lin2d(aStartA, aEndA));
-  std::shared_ptr<GeomAPI_Lin2d> aLB(new GeomAPI_Lin2d(aStartB, aEndB));
-  std::shared_ptr<GeomAPI_Pnt2d> anInter = aLA->intersect(aLB);
-  if (!anInter)
-    return anAngle;
 
   // Directions of lines
   if (anInter->distance(aEndA) < tolerance)
@@ -204,4 +219,32 @@ bool SketchPlugin_ConstraintAngle::compute(const std::string& theAttributeId)
   myFlyoutUpdate = false;
 
   return true;
-}
\ No newline at end of file
+}
+
+
+// ===============   Auxiliary functions   ==================================
+std::shared_ptr<GeomAPI_Pnt2d> intersect(FeaturePtr theLine1, FeaturePtr theLine2)
+{
+  // Start and end points of lines
+  std::shared_ptr<GeomDataAPI_Point2D> aPointA1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      theLine1->attribute(SketchPlugin_Line::START_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aPointA2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      theLine1->attribute(SketchPlugin_Line::END_ID()));
+
+  std::shared_ptr<GeomDataAPI_Point2D> aPointB1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      theLine2->attribute(SketchPlugin_Line::START_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aPointB2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      theLine2->attribute(SketchPlugin_Line::END_ID()));
+
+  std::shared_ptr<GeomAPI_Pnt2d> aStartA = aPointA1->pnt();
+  std::shared_ptr<GeomAPI_Pnt2d> aEndA   = aPointA2->pnt();
+  std::shared_ptr<GeomAPI_Pnt2d> aStartB = aPointB1->pnt();
+  std::shared_ptr<GeomAPI_Pnt2d> aEndB   = aPointB2->pnt();
+  if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance)
+    std::shared_ptr<GeomAPI_Pnt2d>();
+
+  // Lines and their intersection point
+  std::shared_ptr<GeomAPI_Lin2d> aLA(new GeomAPI_Lin2d(aStartA, aEndA));
+  std::shared_ptr<GeomAPI_Lin2d> aLB(new GeomAPI_Lin2d(aStartB, aEndB));
+  return aLA->intersect(aLB);
+}
index 5b5e1dda566ea089ee383e0e32a092f65e9031a3..eedad7a0f778ed13ff1c3aa0c9c7a7d5a2640f80 100644 (file)
@@ -8,6 +8,7 @@ SET(PROJECT_HEADERS
     SketchSolver_Error.h
     SketchSolver_Solver.h
     SketchSolver_Constraint.h
+    SketchSolver_ConstraintAngle.h
     SketchSolver_ConstraintCoincidence.h
     SketchSolver_ConstraintDistance.h
     SketchSolver_ConstraintEqual.h
@@ -29,6 +30,7 @@ SET(PROJECT_HEADERS
 SET(PROJECT_SOURCES
     SketchSolver_Solver.cpp
     SketchSolver_Constraint.cpp
+    SketchSolver_ConstraintAngle.cpp
     SketchSolver_ConstraintCoincidence.cpp
     SketchSolver_ConstraintDistance.cpp
     SketchSolver_ConstraintEqual.cpp
index 8e27a4b4156d83a5191b8e2fd0cc7c1c751c1b7a..f491471df556b6894f98659fee14ee9a8564e1a4 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "SketchSolver_Builder.h"
 #include <SketchPlugin_ConstraintAngle.h>
+#include <SketchSolver_ConstraintAngle.h>
 #include <SketchSolver_ConstraintCoincidence.h>
 #include <SketchSolver_ConstraintDistance.h>
 #include <SketchSolver_ConstraintEqual.h>
index 6e048ccaf839b2cf053a293000ab834583a33e9a..2a12fc5e95e47b0fb8ee7e21a37cf086bd645f0a 100644 (file)
@@ -223,27 +223,4 @@ public:
   }
 };
 
-
-/** \class   SketchSolver_ConstraintAngle
- *  \ingroup Plugins
- *  \brief   Convert Agnle constraint to SolveSpace structure
- */
-class SketchSolver_ConstraintAngle : public SketchSolver_Constraint
-{
-public:
-  SketchSolver_ConstraintAngle(ConstraintPtr theConstraint) :
-      SketchSolver_Constraint(theConstraint)
-  {}
-
-  virtual int getType() const
-  { return SLVS_C_ANGLE; }
-
-  virtual void adjustConstraint()
-  {
-    Slvs_Constraint aConstraint = myStorage->getConstraint(mySlvsConstraints.front());
-    aConstraint.other = aConstraint.valA >= 0.0;
-    myStorage->updateConstraint(aConstraint);
-  }
-};
-
 #endif
diff --git a/src/SketchSolver/SketchSolver_ConstraintAngle.cpp b/src/SketchSolver/SketchSolver_ConstraintAngle.cpp
new file mode 100644 (file)
index 0000000..cfad93f
--- /dev/null
@@ -0,0 +1,36 @@
+#include <SketchSolver_ConstraintAngle.h>
+
+#include <cmath>
+
+void SketchSolver_ConstraintAngle::getAttributes(
+    double& theValue, std::vector<Slvs_hEntity>& theAttributes)
+{
+  SketchSolver_Constraint::getAttributes(theValue, theAttributes);
+
+  myAngle = theValue;
+}
+
+
+void SketchSolver_ConstraintAngle::adjustConstraint()
+{
+  Slvs_Constraint aConstraint = myStorage->getConstraint(mySlvsConstraints.front());
+
+  double aLineDir[2][2] = { {0.0, 0.0}, {0.0, 0.0} };
+  Slvs_hEntity anEnt[2] = {aConstraint.entityA, aConstraint.entityB};
+  for (int i = 0; i < 2; i++) {
+    const Slvs_Entity& aLine = myStorage->getEntity(anEnt[i]);
+    double aCoef = -1.0;
+    for (int j = 0; j < 2; j++, aCoef += 2.0) {
+      const Slvs_Entity& aPoint = myStorage->getEntity(aLine.point[j]);
+      for (int k = 0; k < 2; k++)
+        aLineDir[i][k] += aCoef * myStorage->getParameter(aPoint.param[k]).val;
+    }
+  }
+  double aDot = aLineDir[0][0] * aLineDir[1][0] + aLineDir[0][1] * aLineDir[1][1];
+
+  aConstraint.other = aDot * (90.0 - fabs(aConstraint.valA)) < 0.0;
+  if ((90.0 - fabs(aConstraint.valA)) * (90.0 - fabs(myAngle)) < 0.0)
+    aConstraint.other = !aConstraint.other;
+  myAngle = aConstraint.valA;
+  myStorage->updateConstraint(aConstraint);
+}
diff --git a/src/SketchSolver/SketchSolver_ConstraintAngle.h b/src/SketchSolver/SketchSolver_ConstraintAngle.h
new file mode 100644 (file)
index 0000000..a4a65a4
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:    SketchSolver_ConstraintAngle.h
+// Created: 24 August 2015
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchSolver_ConstraintAngle_H_
+#define SketchSolver_ConstraintAngle_H_
+
+#include <SketchSolver_Constraint.h>
+
+/** \class   SketchSolver_ConstraintAngle
+ *  \ingroup Plugins
+ *  \brief   Convert Agnle constraint to SolveSpace structure
+ */
+class SketchSolver_ConstraintAngle : public SketchSolver_Constraint
+{
+public:
+  SketchSolver_ConstraintAngle(ConstraintPtr theConstraint) :
+      SketchSolver_Constraint(theConstraint),
+      myAngle(0.0)
+  {}
+
+  virtual int getType() const
+  { return SLVS_C_ANGLE; }
+
+  /// \brief This method is used in derived objects to check consistence of constraint.
+  virtual void adjustConstraint();
+
+protected:
+  /// \brief Generate list of attributes of constraint in order useful for SolveSpace constraints
+  /// \param[out] theValue      numerical characteristic of constraint (e.g. distance)
+  /// \param[out] theAttributes list of attributes to be filled
+  virtual void getAttributes(double& theValue, std::vector<Slvs_hEntity>& theAttributes);
+
+private:
+  double myAngle;
+};
+
+#endif