GeomAPI_Ax2.h
GeomAPI_Ax3.h
GeomAPI_Trsf.h
+ GeomAPI_Angle.h
+ GeomAPI_Angle2d.h
)
SET(PROJECT_SOURCES
GeomAPI_Ax3.cpp
GeomAPI_IPresentable.cpp
GeomAPI_Trsf.cpp
+ GeomAPI_Angle.cpp
+ GeomAPI_Angle2d.cpp
)
SET(PROJECT_LIBRARIES
--- /dev/null
+// 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];
+}
--- /dev/null
+// 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
+
--- /dev/null
+// 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];
+}
--- /dev/null
+// 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
+
#include <GeomDataAPI_Point2D.h>
+#include <GeomAPI_Angle2d.h>
#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Lin2d.h>
#include <GeomAPI_Pnt2d.h>
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,
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;
}
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();
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);
}
#include <SketchSolver_Manager.h>
+#include <GeomAPI_Angle2d.h>
#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_XY.h>
#include <SketchPlugin_Line.h>
#include <SketchPlugin_Point.h>
#include <SketchPlugin_IntersectionPoint.h>
+#include <SketchPlugin_ConstraintAngle.h>
#include <math.h>
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;
}
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
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;
}
Events_LongOp::start(this);
- Slvs_Solve(&myEquationsSystem, myGroup);
+ Slvs_Solve(&myEquationsSystem, (Slvs_hGroup)myGroup);
Events_LongOp::end(this);
SketchSolver_SolveStatus aStatus;
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)
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);
}
}
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)