Salome HOME
Update constraint Angle to store directions of the lines
authorazv <azv@opencascade.com>
Tue, 19 Apr 2016 11:18:38 +0000 (14:18 +0300)
committerazv <azv@opencascade.com>
Tue, 19 Apr 2016 13:10:53 +0000 (16:10 +0300)
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI_Angle.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Angle.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Angle2d.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Angle2d.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp
src/SketchPlugin/SketchPlugin_ConstraintAngle.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp

index 6c1307203a5cbbdafa21c5c7707531a4c60fa912..9f5ba706f2e813c5b92542a292709efdadefa0f1 100644 (file)
@@ -35,6 +35,8 @@ SET(PROJECT_HEADERS
     GeomAPI_Ax2.h
     GeomAPI_Ax3.h
     GeomAPI_Trsf.h
+    GeomAPI_Angle.h
+    GeomAPI_Angle2d.h
 )
 
 SET(PROJECT_SOURCES
@@ -66,6 +68,8 @@ SET(PROJECT_SOURCES
     GeomAPI_Ax3.cpp
     GeomAPI_IPresentable.cpp
     GeomAPI_Trsf.cpp
+    GeomAPI_Angle.cpp
+    GeomAPI_Angle2d.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/GeomAPI/GeomAPI_Angle.cpp b/src/GeomAPI/GeomAPI_Angle.cpp
new file mode 100644 (file)
index 0000000..60c3761
--- /dev/null
@@ -0,0 +1,138 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Angle.cpp
+// Created:     19 April 2016
+// Author:      Artem ZHIDKOV
+
+#include <GeomAPI_Angle.h>
+#include <GeomAPI_Dir.h>
+#include <GeomAPI_Lin.h>
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_XYZ.h>
+
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_XYZ.hxx>
+
+struct ThreePoints {
+  gp_Pnt myCenter;
+  gp_Pnt myFirst;
+  gp_Pnt mySecond;
+  bool myReversed[2];
+};
+
+#define MY_ANGLE implPtr<ThreePoints>()
+#define PI 3.1415926535897932
+
+static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
+                             const std::shared_ptr<GeomAPI_Pnt>& theFirst,
+                             const std::shared_ptr<GeomAPI_Pnt>& theSecond)
+{
+  ThreePoints* aResult = new ThreePoints;
+  aResult->myCenter = gp_Pnt(theCenter->x(), theCenter->y(), theCenter->z());
+  aResult->myFirst  = gp_Pnt(theFirst->x(), theFirst->y(), theFirst->z());
+  aResult->mySecond = gp_Pnt(theSecond->x(), theSecond->y(), theSecond->z());
+  aResult->myReversed[0] = aResult->myReversed[1] = false;
+  return aResult;
+}
+
+static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theStart1,
+                             const std::shared_ptr<GeomAPI_Pnt>& theEnd1,
+                             const std::shared_ptr<GeomAPI_Pnt>& theStart2,
+                             const std::shared_ptr<GeomAPI_Pnt>& theEnd2)
+{
+  std::shared_ptr<GeomAPI_Lin> aLine1(new GeomAPI_Lin(theStart1, theEnd1));
+  std::shared_ptr<GeomAPI_Lin> aLine2(new GeomAPI_Lin(theStart2, theEnd2));
+  std::shared_ptr<GeomAPI_Pnt> aCenter = aLine1->intersect(aLine2);
+  bool isParallel = !aCenter;
+  if (isParallel)
+    aCenter = theStart1;
+  std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
+  if (isParallel)
+    aPoint1 = aPoint2 = theEnd1;
+  else {
+    aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
+    aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
+  }
+  ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
+  anAngle->myReversed[0] = aPoint1 == theStart1;
+  anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
+  return anAngle;
+}
+
+static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
+                             const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
+{
+  std::shared_ptr<GeomAPI_Pnt> aCenter = theLine1->intersect(theLine2);
+  if (!aCenter)
+    aCenter = theLine1->location();
+  double aCoeff = theReversed1 ? -1.0 : 1.0;
+  std::shared_ptr<GeomAPI_Pnt> aPoint1(new GeomAPI_Pnt(
+      aCenter->xyz()->added(theLine1->direction()->xyz()->multiplied(aCoeff))));
+  aCoeff = theReversed2 ? -1.0 : 1.0;
+  std::shared_ptr<GeomAPI_Pnt> aPoint2(new GeomAPI_Pnt(
+      aCenter->xyz()->added(theLine2->direction()->xyz()->multiplied(aCoeff))));
+  ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
+  anAngle->myReversed[0] = theReversed1;
+  anAngle->myReversed[1] = theReversed2;
+  return anAngle;
+}
+
+
+
+GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
+                             const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
+                             const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
+                             const std::shared_ptr<GeomAPI_Pnt>& theEndLine2)
+    : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2))
+{
+}
+
+GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
+                             const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
+    : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2))
+{
+}
+
+GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
+                             const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
+                             const std::shared_ptr<GeomAPI_Pnt>& thePoint2)
+    : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2))
+{
+}
+
+std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::center()
+{
+  gp_Pnt aPnt = MY_ANGLE->myCenter;
+  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
+}
+
+std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::firstPoint()
+{
+  gp_Pnt aPnt = MY_ANGLE->myFirst;
+  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
+}
+
+std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::secondPoint()
+{
+  gp_Pnt aPnt = MY_ANGLE->mySecond;
+  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
+}
+
+double GeomAPI_Angle::angleDegree()
+{
+  return angleRadian() * 180.0 / PI;
+}
+
+double GeomAPI_Angle::angleRadian()
+{
+  ThreePoints* anAngle = MY_ANGLE;
+  gp_Dir aDir1(anAngle->myFirst.XYZ() - anAngle->myCenter.XYZ());
+  gp_Dir aDir2(anAngle->mySecond.XYZ() - anAngle->myCenter.XYZ());
+  return aDir1.Angle(aDir2);
+}
+
+bool GeomAPI_Angle::isReversed(int theIndex)
+{
+  return MY_ANGLE->myReversed[theIndex & 0x1];
+}
diff --git a/src/GeomAPI/GeomAPI_Angle.h b/src/GeomAPI/GeomAPI_Angle.h
new file mode 100644 (file)
index 0000000..f926ba9
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Angle.h
+// Created:     19 April 2016
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_Angle_H_
+#define GeomAPI_Angle_H_
+
+#include <GeomAPI_Interface.h>
+
+class GeomAPI_Lin;
+class GeomAPI_Pnt;
+
+/// \class GeomAPI_Angle
+/// \ingroup DataModel
+/// \brief Build an angle in 3D
+class GeomAPI_Angle : public GeomAPI_Interface
+{
+public:
+  /// Creation of an angle defined by two lines' start, end points
+  GEOMAPI_EXPORT
+  GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
+                const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
+                const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
+                const std::shared_ptr<GeomAPI_Pnt>& theEndLine2);
+  /// Creation of an angle defined by two lines taking into account their orientation
+  GEOMAPI_EXPORT
+  GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
+                const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2);
+  /// Creation of an angle defined by three points
+  GEOMAPI_EXPORT
+  GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
+                const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
+                const std::shared_ptr<GeomAPI_Pnt>& thePoint2);
+
+  /// Returns central point of the angle
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> center();
+  /// Returns point on the first edge
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> firstPoint();
+  /// Returns point on the second edge
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> secondPoint();
+
+  /// Returns value of the angle in degrees
+  GEOMAPI_EXPORT double angleDegree();
+  /// Returns value of the angle in radians
+  GEOMAPI_EXPORT double angleRadian();
+
+  /// Returns \c true if the line is reversed during angle calculation.
+  /// If theIndex = 0, the result corresponds to the first line, if theIndex = 1, the to the second line
+  GEOMAPI_EXPORT bool isReversed(int theIndex);
+};
+
+#endif
+
diff --git a/src/GeomAPI/GeomAPI_Angle2d.cpp b/src/GeomAPI/GeomAPI_Angle2d.cpp
new file mode 100644 (file)
index 0000000..2162de5
--- /dev/null
@@ -0,0 +1,140 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Angle2d.cpp
+// Created:     19 April 2016
+// Author:      Artem ZHIDKOV
+
+#include <GeomAPI_Angle2d.h>
+#include <GeomAPI_Dir2d.h>
+#include <GeomAPI_Lin2d.h>
+#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_XY.h>
+
+#include <gp_Dir2d.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_XY.hxx>
+
+struct ThreePoints2d {
+  gp_Pnt2d myCenter;
+  gp_Pnt2d myFirst;
+  gp_Pnt2d mySecond;
+  bool myReversed[2];
+};
+
+#define MY_ANGLE implPtr<ThreePoints2d>()
+#define PI 3.1415926535897932
+
+static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                               const std::shared_ptr<GeomAPI_Pnt2d>& theFirst,
+                               const std::shared_ptr<GeomAPI_Pnt2d>& theSecond)
+{
+  ThreePoints2d* aResult = new ThreePoints2d;
+  aResult->myCenter = gp_Pnt2d(theCenter->x(), theCenter->y());
+  aResult->myFirst  = gp_Pnt2d(theFirst->x(), theFirst->y());
+  aResult->mySecond = gp_Pnt2d(theSecond->x(), theSecond->y());
+  aResult->myReversed[0] = aResult->myReversed[1] = false;
+  return aResult;
+}
+
+static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Pnt2d>& theStart1,
+                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd1,
+                               const std::shared_ptr<GeomAPI_Pnt2d>& theStart2,
+                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd2)
+{
+  std::shared_ptr<GeomAPI_Lin2d> aLine1(new GeomAPI_Lin2d(theStart1, theEnd1));
+  std::shared_ptr<GeomAPI_Lin2d> aLine2(new GeomAPI_Lin2d(theStart2, theEnd2));
+  std::shared_ptr<GeomAPI_Pnt2d> aCenter = aLine1->intersect(aLine2);
+  bool isParallel = !aCenter;
+  if (isParallel)
+    aCenter = theStart1;
+  std::shared_ptr<GeomAPI_Pnt2d> aPoint1, aPoint2;
+  if (isParallel)
+    aPoint1 = aPoint2 = theEnd1;
+  else {
+    aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
+    aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
+  }
+  ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
+  anAngle->myReversed[0] = aPoint1 == theStart1;
+  anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
+  return anAngle;
+}
+
+static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
+                               const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
+{
+  std::shared_ptr<GeomAPI_Pnt2d> aCenter = theLine1->intersect(theLine2);
+  if (!aCenter)
+    aCenter = theLine1->location();
+  double aCoeff = theReversed1 ? -1.0 : 1.0;
+  std::shared_ptr<GeomAPI_Pnt2d> aPoint1(new GeomAPI_Pnt2d(
+      aCenter->xy()->added(theLine1->direction()->xy()->multiplied(aCoeff))));
+  aCoeff = theReversed2 ? -1.0 : 1.0;
+  std::shared_ptr<GeomAPI_Pnt2d> aPoint2(new GeomAPI_Pnt2d(
+      aCenter->xy()->added(theLine2->direction()->xy()->multiplied(aCoeff))));
+  ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
+  anAngle->myReversed[0] = theReversed1;
+  anAngle->myReversed[1] = theReversed2;
+  return anAngle;
+}
+
+
+
+GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine1,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine1,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine2,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine2)
+    : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2))
+{
+}
+
+GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
+                                 const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
+    : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2))
+{
+}
+
+GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2)
+    : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2))
+{
+}
+
+std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::center()
+{
+  gp_Pnt2d aPnt = MY_ANGLE->myCenter;
+  return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
+}
+
+std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::firstPoint()
+{
+  gp_Pnt2d aPnt = MY_ANGLE->myFirst;
+  return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
+}
+
+std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::secondPoint()
+{
+  gp_Pnt2d aPnt = MY_ANGLE->mySecond;
+  return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
+}
+
+double GeomAPI_Angle2d::angleDegree()
+{
+  return angleRadian() * 180.0 / PI;
+}
+
+double GeomAPI_Angle2d::angleRadian()
+{
+  ThreePoints2d* anAngle = MY_ANGLE;
+  gp_Dir2d aDir1(anAngle->myFirst.XY() - anAngle->myCenter.XY());
+  gp_Dir2d aDir2(anAngle->mySecond.XY() - anAngle->myCenter.XY());
+  double aRes = aDir1.Angle(aDir2);
+  if (aRes < 0.0) aRes += 2 * PI;
+  return aRes;
+}
+
+bool GeomAPI_Angle2d::isReversed(int theIndex)
+{
+  return MY_ANGLE->myReversed[theIndex & 0x1];
+}
diff --git a/src/GeomAPI/GeomAPI_Angle2d.h b/src/GeomAPI/GeomAPI_Angle2d.h
new file mode 100644 (file)
index 0000000..eb69856
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Angle2d.h
+// Created:     19 April 2016
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_Angle_H_
+#define GeomAPI_Angle_H_
+
+#include <GeomAPI_Interface.h>
+
+class GeomAPI_Lin2d;
+class GeomAPI_Pnt2d;
+
+/// \class GeomAPI_Angle2d
+/// \ingroup DataModel
+/// \brief Build an angle in plane
+class GeomAPI_Angle2d : public GeomAPI_Interface
+{
+public:
+  /// Creation of an angle defined by two lines' start, end points
+  GEOMAPI_EXPORT
+  GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine1,
+                  const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine1,
+                  const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine2,
+                  const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine2);
+  /// Creation of an angle defined by two lines taking into account their orientation
+  GEOMAPI_EXPORT
+  GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
+                  const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2);
+  /// Creation of an angle defined by three points
+  GEOMAPI_EXPORT
+  GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                  const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
+                  const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2);
+
+  /// Returns central point of the angle
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt2d> center();
+  /// Returns point on the first edge
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt2d> firstPoint();
+  /// Returns point on the second edge
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt2d> secondPoint();
+
+  /// Returns value of the angle in degrees
+  GEOMAPI_EXPORT double angleDegree();
+  /// Returns value of the angle in radians
+  GEOMAPI_EXPORT double angleRadian();
+
+  /// Returns \c true if the line is reversed during angle calculation.
+  /// If theIndex = 0, the result corresponds to the first line, if theIndex = 1, the to the second line
+  GEOMAPI_EXPORT bool isReversed(int theIndex);
+};
+
+#endif
+
index 712d436af2aefdf0ad2f536693d4749a8b0ea45e..27c35724d94065a1863cb6422c255ea1d8bc3a4f 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <GeomDataAPI_Point2D.h>
 
+#include <GeomAPI_Angle2d.h>
 #include <GeomAPI_Dir2d.h>
 #include <GeomAPI_Lin2d.h>
 #include <GeomAPI_Pnt2d.h>
@@ -43,6 +44,9 @@ void SketchPlugin_ConstraintAngle::initAttributes()
 
   data()->addAttribute(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID(), ModelAPI_AttributeDouble::typeId());
   data()->addAttribute(SketchPlugin_ConstraintAngle::TYPE_ID(), ModelAPI_AttributeInteger::typeId());
+
+  data()->addAttribute(SketchPlugin_ConstraintAngle::ANGLE_REVERSED_FIRST_LINE_ID(), ModelAPI_AttributeBoolean::typeId());
+  data()->addAttribute(SketchPlugin_ConstraintAngle::ANGLE_REVERSED_SECOND_LINE_ID(), ModelAPI_AttributeBoolean::typeId());
 }
 
 void SketchPlugin_ConstraintAngle::colorConfigInfo(std::string& theSection, std::string& theName,
@@ -144,54 +148,37 @@ void SketchPlugin_ConstraintAngle::attributeChanged(const std::string& theID)
 
 double SketchPlugin_ConstraintAngle::calculateAngle()
 {
-  double anAngle = 0.0;
-
   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 anAngle;
-
-  // Start and end points of lines
-  std::shared_ptr<GeomDataAPI_Point2D> aPointA1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+  std::shared_ptr<GeomDataAPI_Point2D> aStartA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aLineA->attribute(SketchPlugin_Line::START_ID()));
-  std::shared_ptr<GeomDataAPI_Point2D> aPointA2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+  std::shared_ptr<GeomDataAPI_Point2D> aEndA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aLineA->attribute(SketchPlugin_Line::END_ID()));
-
-  std::shared_ptr<GeomDataAPI_Point2D> aPointB1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+  std::shared_ptr<GeomDataAPI_Point2D> aStartB = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aLineB->attribute(SketchPlugin_Line::START_ID()));
-  std::shared_ptr<GeomDataAPI_Point2D> aPointB2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+  std::shared_ptr<GeomDataAPI_Point2D> aEndB = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aLineB->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();
-
-  double aDist[2][2] = {
-      { anInter->distance(aStartA), anInter->distance(aEndA) },
-      { anInter->distance(aStartB), anInter->distance(aEndB) }
-  };
-
-  // Directions of lines
-  if (aDist[0][0] > aDist[0][1])
-    aEndA = aStartA;
-  if (aDist[1][0] > aDist[1][1])
-    aEndB = aStartB;
-
-  std::shared_ptr<GeomAPI_Dir2d> aDirA(new GeomAPI_Dir2d(aEndA->xy()->decreased(anInter->xy())));
-  std::shared_ptr<GeomAPI_Dir2d> aDirB(new GeomAPI_Dir2d(aEndB->xy()->decreased(anInter->xy())));
-
-  double aDirAngle = aDirA->angle(aDirB);
-  if (aDirAngle < 0)
-    aDirAngle += 2.0 * PI;
-  anAngle = fabs(aDirAngle) * 180.0 / PI;
+  std::shared_ptr<GeomAPI_Angle2d> anAng;
+  if (!attribute(ANGLE_REVERSED_FIRST_LINE_ID())->isInitialized() ||
+      !attribute(ANGLE_REVERSED_SECOND_LINE_ID())->isInitialized())
+    anAng = std::shared_ptr<GeomAPI_Angle2d>(new GeomAPI_Angle2d(
+        aStartA->pnt(), aEndA->pnt(), aStartB->pnt(), aEndB->pnt()));
+  else {
+    std::shared_ptr<GeomAPI_Lin2d> aLine1(new GeomAPI_Lin2d(aStartA->pnt(), aEndA->pnt()));
+    bool isReversed1 = boolean(ANGLE_REVERSED_FIRST_LINE_ID())->value();
+    std::shared_ptr<GeomAPI_Lin2d> aLine2(new GeomAPI_Lin2d(aStartB->pnt(), aEndB->pnt()));
+    bool isReversed2 = boolean(ANGLE_REVERSED_SECOND_LINE_ID())->value();
+    anAng = std::shared_ptr<GeomAPI_Angle2d>(new GeomAPI_Angle2d(aLine1, isReversed1, aLine2, isReversed2));
+  }
+  double anAngle = anAng->angleDegree();
   /// an angle value should be corrected by the current angle type
   anAngle = getAngleForType(anAngle);
+  boolean(ANGLE_REVERSED_FIRST_LINE_ID())->setValue(anAng->isReversed(0));
+  boolean(ANGLE_REVERSED_SECOND_LINE_ID())->setValue(anAng->isReversed(1));
   return anAngle;
 }
 
index d3dd5c8adab1268f4c73c9e352045893fa71509e..46dc274ffa2f72c951a81f8adc8640e4e1765145 100644 (file)
@@ -48,6 +48,19 @@ class SketchPlugin_ConstraintAngle : public SketchPlugin_ConstraintBase
     return MY_ANGLE_VALUE_ID;
   }
 
+  /// attribute name indicating the first line is reversed
+  inline static const std::string& ANGLE_REVERSED_FIRST_LINE_ID()
+  {
+    static const std::string MY_ANGLE_REVERSED_ID("AngleReversedLine1");
+    return MY_ANGLE_REVERSED_ID;
+  }
+  /// attribute name indicating the second line is reversed
+  inline static const std::string& ANGLE_REVERSED_SECOND_LINE_ID()
+  {
+    static const std::string MY_ANGLE_REVERSED_ID("AngleReversedLine2");
+    return MY_ANGLE_REVERSED_ID;
+  }
+
   /// \brief Creates a new part document if needed
   SKETCHPLUGIN_EXPORT virtual void execute();
 
index 9f92a1c4dbb7375117b75add97ba2735678e0faf..1dbc5ed4983a932f358cc6b5b8bbf3a2616aeb91 100644 (file)
@@ -1135,59 +1135,14 @@ void adjustAngle(ConstraintWrapperPtr theConstraint)
   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aConstraint =
     std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(theConstraint);
 
-  std::shared_ptr<GeomAPI_Pnt2d> aPoints[2][2]; // start and end points of lines
-  const std::list<EntityWrapperPtr>& aConstrLines = aConstraint->entities();
-  std::list<EntityWrapperPtr>::const_iterator aCLIt = aConstrLines.begin();
-  for (int i = 0; aCLIt != aConstrLines.end(); ++i, ++aCLIt) {
-    const std::list<EntityWrapperPtr>& aLinePoints = (*aCLIt)->subEntities();
-    std::list<EntityWrapperPtr>::const_iterator aLPIt = aLinePoints.begin();
-    for (int j = 0; aLPIt != aLinePoints.end(); ++j, ++aLPIt)
-      aPoints[i][j] = aBuilder->point(*aLPIt);
-  }
-
-  std::shared_ptr<GeomAPI_Lin2d> aLine[2] = {
-    std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aPoints[0][0], aPoints[0][1])),
-    std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aPoints[1][0], aPoints[1][1]))
+  bool isReversed[2] = {
+    aConstraint->baseConstraint()->boolean(
+        SketchPlugin_ConstraintAngle::ANGLE_REVERSED_FIRST_LINE_ID())->value(),
+    aConstraint->baseConstraint()->boolean(
+        SketchPlugin_ConstraintAngle::ANGLE_REVERSED_SECOND_LINE_ID())->value()
   };
-  std::shared_ptr<GeomAPI_Pnt2d> anIntersection = aLine[0]->intersect(aLine[1]);
-  if (!anIntersection)
-    return;
-  double aDist[2][2];
-  for (int i = 0; i < 2; i++) {
-    for (int j = 0; j < 2; j++) {
-      aDist[i][j] = anIntersection->distance(aPoints[i][j]);
-      if (fabs(aDist[i][j]) <= tolerance)
-        aDist[i][j] = 0.0;
-    }
-    if (aDist[i][0] > tolerance && aDist[i][1] > tolerance &&
-        aDist[i][0] + aDist[i][1] < aPoints[i][0]->distance(aPoints[i][1]) + 2.0 * tolerance) {
-      // the intersection point is an inner point of the line,
-      // we change the sign of distance till start point to calculate correct coordinates
-      // after rotation
-      aDist[i][0] *= -1.0;
-    }
-  }
-  std::shared_ptr<GeomAPI_Dir2d> aDir[2];
-  for (int i = 0; i < 2; i++) {
-    if (aDist[i][1] > fabs(aDist[i][0]))
-      aDir[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(
-          aPoints[i][1]->xy()->decreased(anIntersection->xy())));
-    else {
-      aDir[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(
-          aPoints[i][0]->xy()->decreased(anIntersection->xy())));
-      // main direction is opposite => change signs
-      if (aDist[i][0] < 0.0) {
-        aDist[i][0] *= -1.0;
-        aDist[i][1] *= -1.0;
-      }
-    }
-  }
 
-  bool isReversed = false;
-  for (int i = 0; i < 2; i++)
-    if (aLine[i]->direction()->dot(aDir[i]) < 0.0)
-      isReversed = !isReversed;
-  if (isReversed)
+  if (isReversed[0] != isReversed[1])
     aConstraint->setValue(aConstraint->value() - 180.0);
 }
 
index b277cd70733a06635426ac67e28f6cab89ba7b1d..22d431dc2c91b32d04c90c0f721896ebf0f322af 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <SketchSolver_Manager.h>
 
+#include <GeomAPI_Angle2d.h>
 #include <GeomAPI_Dir2d.h>
 #include <GeomAPI_Pnt2d.h>
 #include <GeomAPI_XY.h>
@@ -28,6 +29,7 @@
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Point.h>
 #include <SketchPlugin_IntersectionPoint.h>
+#include <SketchPlugin_ConstraintAngle.h>
 
 #include <math.h>
 
@@ -687,13 +689,31 @@ void adjustAngle(ConstraintWrapperPtr theConstraint)
     std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aPoints[0][0], aPoints[0][1])),
     std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aPoints[1][0], aPoints[1][1]))
   };
-  std::shared_ptr<GeomAPI_Pnt2d> anIntersection = aLine[0]->intersect(aLine[1]);
-  if (!anIntersection)
-    return;
+  bool isReversed[2] = {
+    aConstraint->baseConstraint()->boolean(
+        SketchPlugin_ConstraintAngle::ANGLE_REVERSED_FIRST_LINE_ID())->value(),
+    aConstraint->baseConstraint()->boolean(
+        SketchPlugin_ConstraintAngle::ANGLE_REVERSED_SECOND_LINE_ID())->value()
+  };
+  std::shared_ptr<GeomAPI_Angle2d> anAngle(new GeomAPI_Angle2d(aLine[0], isReversed[0], aLine[1], isReversed[1]));
+  std::shared_ptr<GeomAPI_Pnt2d> aCenter = anAngle->center();
+
+  std::shared_ptr<GeomAPI_Dir2d> aDir[2];
+
+  Slvs_Constraint& aSlvsConstraint = aConstraint->changeConstraint();
+  aSlvsConstraint.other = false;
+  for (int i = 0; i < 2; i++) {
+    aDir[i] = aLine[i]->direction();
+    if (isReversed[i]) {
+      aSlvsConstraint.other = !aSlvsConstraint.other;
+      aDir[i]->reverse();
+    }
+  }
+
   double aDist[2][2];
   for (int i = 0; i < 2; i++) {
     for (int j = 0; j < 2; j++) {
-      aDist[i][j] = anIntersection->distance(aPoints[i][j]);
+      aDist[i][j] = aCenter->distance(aPoints[i][j]);
       if (fabs(aDist[i][j]) <= tolerance)
         aDist[i][j] = 0.0;
     }
@@ -705,27 +725,6 @@ void adjustAngle(ConstraintWrapperPtr theConstraint)
       aDist[i][0] *= -1.0;
     }
   }
-  std::shared_ptr<GeomAPI_Dir2d> aDir[2];
-  for (int i = 0; i < 2; i++) {
-    if (aDist[i][1] > fabs(aDist[i][0]))
-      aDir[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(
-          aPoints[i][1]->xy()->decreased(anIntersection->xy())));
-    else {
-      aDir[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(
-          aPoints[i][0]->xy()->decreased(anIntersection->xy())));
-      // main direction is opposite => change signs
-      if (aDist[i][0] < 0.0) {
-        aDist[i][0] *= -1.0;
-        aDist[i][1] *= -1.0;
-      }
-    }
-  }
-
-  Slvs_Constraint& aSlvsConstraint = aConstraint->changeConstraint();
-  aSlvsConstraint.other = false;
-  for (int i = 0; i < 2; i++)
-    if (aLine[i]->direction()->dot(aDir[i]) < 0.0)
-      aSlvsConstraint.other = !aSlvsConstraint.other;
 
   // Recalculate positions of lines to avoid conflicting constraints
   // while changing angle value several times
@@ -744,8 +743,8 @@ void adjustAngle(ConstraintWrapperPtr theConstraint)
   std::shared_ptr<GeomAPI_Pnt2d> aNewPoints[2];
   for (int i = 0; i < 2; i++) {
     aNewPoints[i] = std::shared_ptr<GeomAPI_Pnt2d>(
-        new GeomAPI_Pnt2d(anIntersection->x() + x * aDist[aLineToUpd][i],
-                          anIntersection->y() + y * aDist[aLineToUpd][i]));
+        new GeomAPI_Pnt2d(aCenter->x() + x * aDist[aLineToUpd][i],
+                          aCenter->y() + y * aDist[aLineToUpd][i]));
   }
 
   std::shared_ptr<GeomAPI_XY> aDelta;
index 2adb7dcd62fa79332c9d0737f716e5116ffc2c2b..5b34b1174cc6047e6b64170cfbf4a8bac9f45d1d 100644 (file)
@@ -97,7 +97,7 @@ SketchSolver_SolveStatus SolveSpaceSolver_Solver::solve()
   }
 
   Events_LongOp::start(this);
-  Slvs_Solve(&myEquationsSystem, myGroup);
+  Slvs_Solve(&myEquationsSystem, (Slvs_hGroup)myGroup);
   Events_LongOp::end(this);
 
   SketchSolver_SolveStatus aStatus;
index d63622683115195836f410da652ec0d5e4e3b8b1..efbe1ad2de25721e7d63ef7a0544a995c2fb0ac7 100644 (file)
@@ -422,7 +422,7 @@ void SolveSpaceSolver_Storage::replaceInConstraints(
             aConstr.entityC == aSlvsCIt->entityC && aConstr.entityD == aSlvsCIt->entityD) {
           Slvs_hConstraint anIDToRemove = aConstr.h;
           aConstr = *aSlvsCIt;
-          int aShift = aSlvsCIt - myConstraints.begin();
+          int aShift = (int)(aSlvsCIt - myConstraints.begin());
           removeConstraint(anIDToRemove);
           aSlvsCIt = myConstraints.begin() + aShift - 1;
           for (; aSlvsCIt != myConstraints.end(); ++aSlvsCIt)
@@ -810,13 +810,13 @@ Slvs_hConstraint SolveSpaceSolver_Storage::updateConstraint(const Slvs_Constrain
     if (anIt != myConstraints.end()) {
       // change the constraint to the lengths equality to avoid conflicts
       Slvs_Entity aLine = getEntity(aConstraint.entityA);
-      Slvs_Entity aNewLine1 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroupID,
+      Slvs_Entity aNewLine1 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, (Slvs_hGroup)myGroupID,
           myWorkplaneID, aLine.point[0], aConstraint.ptA);
       aNewLine1.h = addEntity(aNewLine1);
-      Slvs_Entity aNewLine2 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroupID,
+      Slvs_Entity aNewLine2 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, (Slvs_hGroup)myGroupID,
           myWorkplaneID, aLine.point[1], aConstraint.ptA);
       aNewLine2.h = addEntity(aNewLine2);
-      aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroupID, SLVS_C_EQUAL_LENGTH_LINES,
+      aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, (Slvs_hGroup)myGroupID, SLVS_C_EQUAL_LENGTH_LINES,
           myWorkplaneID, 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aNewLine1.h, aNewLine2.h);
     }
   }
@@ -1240,7 +1240,7 @@ template<typename T>
 int Search(const uint32_t& theEntityID, const std::vector<T>& theEntities)
 {
   int aResIndex = theEntityID <= theEntities.size() ? theEntityID - 1 : 0;
-  int aVecSize = theEntities.size();
+  int aVecSize = (int)theEntities.size();
   if (theEntities.empty())
     return 1;
   while (aResIndex >= 0 && theEntities[aResIndex].h > theEntityID)