From: azv Date: Tue, 19 Apr 2016 11:18:38 +0000 (+0300) Subject: Update constraint Angle to store directions of the lines X-Git-Tag: V_2.3.0~189 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=049e63c33b9c0372a3007166032ead400c788c93;p=modules%2Fshaper.git Update constraint Angle to store directions of the lines --- diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index 6c1307203..9f5ba706f 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -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 index 000000000..60c3761a0 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Angle.cpp @@ -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 +#include +#include +#include +#include + +#include +#include +#include + +struct ThreePoints { + gp_Pnt myCenter; + gp_Pnt myFirst; + gp_Pnt mySecond; + bool myReversed[2]; +}; + +#define MY_ANGLE implPtr() +#define PI 3.1415926535897932 + +static ThreePoints* newAngle(const std::shared_ptr& theCenter, + const std::shared_ptr& theFirst, + const std::shared_ptr& 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& theStart1, + const std::shared_ptr& theEnd1, + const std::shared_ptr& theStart2, + const std::shared_ptr& theEnd2) +{ + std::shared_ptr aLine1(new GeomAPI_Lin(theStart1, theEnd1)); + std::shared_ptr aLine2(new GeomAPI_Lin(theStart2, theEnd2)); + std::shared_ptr aCenter = aLine1->intersect(aLine2); + bool isParallel = !aCenter; + if (isParallel) + aCenter = theStart1; + std::shared_ptr 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& theLine1, bool theReversed1, + const std::shared_ptr& theLine2, bool theReversed2) +{ + std::shared_ptr aCenter = theLine1->intersect(theLine2); + if (!aCenter) + aCenter = theLine1->location(); + double aCoeff = theReversed1 ? -1.0 : 1.0; + std::shared_ptr aPoint1(new GeomAPI_Pnt( + aCenter->xyz()->added(theLine1->direction()->xyz()->multiplied(aCoeff)))); + aCoeff = theReversed2 ? -1.0 : 1.0; + std::shared_ptr 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& theStartLine1, + const std::shared_ptr& theEndLine1, + const std::shared_ptr& theStartLine2, + const std::shared_ptr& theEndLine2) + : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2)) +{ +} + +GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr& theLine1, bool theReversed1, + const std::shared_ptr& theLine2, bool theReversed2) + : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2)) +{ +} + +GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr& theCenter, + const std::shared_ptr& thePoint1, + const std::shared_ptr& thePoint2) + : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2)) +{ +} + +std::shared_ptr GeomAPI_Angle::center() +{ + gp_Pnt aPnt = MY_ANGLE->myCenter; + return std::shared_ptr(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z())); +} + +std::shared_ptr GeomAPI_Angle::firstPoint() +{ + gp_Pnt aPnt = MY_ANGLE->myFirst; + return std::shared_ptr(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z())); +} + +std::shared_ptr GeomAPI_Angle::secondPoint() +{ + gp_Pnt aPnt = MY_ANGLE->mySecond; + return std::shared_ptr(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 index 000000000..f926ba912 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Angle.h @@ -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 + +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& theStartLine1, + const std::shared_ptr& theEndLine1, + const std::shared_ptr& theStartLine2, + const std::shared_ptr& theEndLine2); + /// Creation of an angle defined by two lines taking into account their orientation + GEOMAPI_EXPORT + GeomAPI_Angle(const std::shared_ptr& theLine1, bool theReversed1, + const std::shared_ptr& theLine2, bool theReversed2); + /// Creation of an angle defined by three points + GEOMAPI_EXPORT + GeomAPI_Angle(const std::shared_ptr& theCenter, + const std::shared_ptr& thePoint1, + const std::shared_ptr& thePoint2); + + /// Returns central point of the angle + GEOMAPI_EXPORT std::shared_ptr center(); + /// Returns point on the first edge + GEOMAPI_EXPORT std::shared_ptr firstPoint(); + /// Returns point on the second edge + GEOMAPI_EXPORT std::shared_ptr 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 index 000000000..2162de5d9 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Angle2d.cpp @@ -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 +#include +#include +#include +#include + +#include +#include +#include + +struct ThreePoints2d { + gp_Pnt2d myCenter; + gp_Pnt2d myFirst; + gp_Pnt2d mySecond; + bool myReversed[2]; +}; + +#define MY_ANGLE implPtr() +#define PI 3.1415926535897932 + +static ThreePoints2d* newAngle(const std::shared_ptr& theCenter, + const std::shared_ptr& theFirst, + const std::shared_ptr& 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& theStart1, + const std::shared_ptr& theEnd1, + const std::shared_ptr& theStart2, + const std::shared_ptr& theEnd2) +{ + std::shared_ptr aLine1(new GeomAPI_Lin2d(theStart1, theEnd1)); + std::shared_ptr aLine2(new GeomAPI_Lin2d(theStart2, theEnd2)); + std::shared_ptr aCenter = aLine1->intersect(aLine2); + bool isParallel = !aCenter; + if (isParallel) + aCenter = theStart1; + std::shared_ptr 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& theLine1, bool theReversed1, + const std::shared_ptr& theLine2, bool theReversed2) +{ + std::shared_ptr aCenter = theLine1->intersect(theLine2); + if (!aCenter) + aCenter = theLine1->location(); + double aCoeff = theReversed1 ? -1.0 : 1.0; + std::shared_ptr aPoint1(new GeomAPI_Pnt2d( + aCenter->xy()->added(theLine1->direction()->xy()->multiplied(aCoeff)))); + aCoeff = theReversed2 ? -1.0 : 1.0; + std::shared_ptr 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& theStartLine1, + const std::shared_ptr& theEndLine1, + const std::shared_ptr& theStartLine2, + const std::shared_ptr& theEndLine2) + : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2)) +{ +} + +GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr& theLine1, bool theReversed1, + const std::shared_ptr& theLine2, bool theReversed2) + : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2)) +{ +} + +GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr& theCenter, + const std::shared_ptr& thePoint1, + const std::shared_ptr& thePoint2) + : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2)) +{ +} + +std::shared_ptr GeomAPI_Angle2d::center() +{ + gp_Pnt2d aPnt = MY_ANGLE->myCenter; + return std::shared_ptr(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y())); +} + +std::shared_ptr GeomAPI_Angle2d::firstPoint() +{ + gp_Pnt2d aPnt = MY_ANGLE->myFirst; + return std::shared_ptr(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y())); +} + +std::shared_ptr GeomAPI_Angle2d::secondPoint() +{ + gp_Pnt2d aPnt = MY_ANGLE->mySecond; + return std::shared_ptr(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 index 000000000..eb6985624 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Angle2d.h @@ -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 + +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& theStartLine1, + const std::shared_ptr& theEndLine1, + const std::shared_ptr& theStartLine2, + const std::shared_ptr& theEndLine2); + /// Creation of an angle defined by two lines taking into account their orientation + GEOMAPI_EXPORT + GeomAPI_Angle2d(const std::shared_ptr& theLine1, bool theReversed1, + const std::shared_ptr& theLine2, bool theReversed2); + /// Creation of an angle defined by three points + GEOMAPI_EXPORT + GeomAPI_Angle2d(const std::shared_ptr& theCenter, + const std::shared_ptr& thePoint1, + const std::shared_ptr& thePoint2); + + /// Returns central point of the angle + GEOMAPI_EXPORT std::shared_ptr center(); + /// Returns point on the first edge + GEOMAPI_EXPORT std::shared_ptr firstPoint(); + /// Returns point on the second edge + GEOMAPI_EXPORT std::shared_ptr 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/SketchPlugin/SketchPlugin_ConstraintAngle.cpp b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp index 712d436af..27c35724d 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp @@ -12,6 +12,7 @@ #include +#include #include #include #include @@ -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 aData = data(); std::shared_ptr 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 anInter = intersect(aLineA, aLineB); - if (!anInter) - return anAngle; - - // Start and end points of lines - std::shared_ptr aPointA1 = std::dynamic_pointer_cast( + std::shared_ptr aStartA = std::dynamic_pointer_cast( aLineA->attribute(SketchPlugin_Line::START_ID())); - std::shared_ptr aPointA2 = std::dynamic_pointer_cast( + std::shared_ptr aEndA = std::dynamic_pointer_cast( aLineA->attribute(SketchPlugin_Line::END_ID())); - - std::shared_ptr aPointB1 = std::dynamic_pointer_cast( + std::shared_ptr aStartB = std::dynamic_pointer_cast( aLineB->attribute(SketchPlugin_Line::START_ID())); - std::shared_ptr aPointB2 = std::dynamic_pointer_cast( + std::shared_ptr aEndB = std::dynamic_pointer_cast( aLineB->attribute(SketchPlugin_Line::END_ID())); - std::shared_ptr aStartA = aPointA1->pnt(); - std::shared_ptr aEndA = aPointA2->pnt(); - std::shared_ptr aStartB = aPointB1->pnt(); - std::shared_ptr 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 aDirA(new GeomAPI_Dir2d(aEndA->xy()->decreased(anInter->xy()))); - std::shared_ptr 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 anAng; + if (!attribute(ANGLE_REVERSED_FIRST_LINE_ID())->isInitialized() || + !attribute(ANGLE_REVERSED_SECOND_LINE_ID())->isInitialized()) + anAng = std::shared_ptr(new GeomAPI_Angle2d( + aStartA->pnt(), aEndA->pnt(), aStartB->pnt(), aEndB->pnt())); + else { + std::shared_ptr aLine1(new GeomAPI_Lin2d(aStartA->pnt(), aEndA->pnt())); + bool isReversed1 = boolean(ANGLE_REVERSED_FIRST_LINE_ID())->value(); + std::shared_ptr aLine2(new GeomAPI_Lin2d(aStartB->pnt(), aEndB->pnt())); + bool isReversed2 = boolean(ANGLE_REVERSED_SECOND_LINE_ID())->value(); + anAng = std::shared_ptr(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; } diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.h b/src/SketchPlugin/SketchPlugin_ConstraintAngle.h index d3dd5c8ad..46dc274ff 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintAngle.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.h @@ -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(); diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp index 9f92a1c4d..1dbc5ed49 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp @@ -1135,59 +1135,14 @@ void adjustAngle(ConstraintWrapperPtr theConstraint) std::shared_ptr aConstraint = std::dynamic_pointer_cast(theConstraint); - std::shared_ptr aPoints[2][2]; // start and end points of lines - const std::list& aConstrLines = aConstraint->entities(); - std::list::const_iterator aCLIt = aConstrLines.begin(); - for (int i = 0; aCLIt != aConstrLines.end(); ++i, ++aCLIt) { - const std::list& aLinePoints = (*aCLIt)->subEntities(); - std::list::const_iterator aLPIt = aLinePoints.begin(); - for (int j = 0; aLPIt != aLinePoints.end(); ++j, ++aLPIt) - aPoints[i][j] = aBuilder->point(*aLPIt); - } - - std::shared_ptr aLine[2] = { - std::shared_ptr(new GeomAPI_Lin2d(aPoints[0][0], aPoints[0][1])), - std::shared_ptr(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 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 aDir[2]; - for (int i = 0; i < 2; i++) { - if (aDist[i][1] > fabs(aDist[i][0])) - aDir[i] = std::shared_ptr(new GeomAPI_Dir2d( - aPoints[i][1]->xy()->decreased(anIntersection->xy()))); - else { - aDir[i] = std::shared_ptr(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); } diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp index b277cd707..22d431dc2 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include @@ -687,13 +689,31 @@ void adjustAngle(ConstraintWrapperPtr theConstraint) std::shared_ptr(new GeomAPI_Lin2d(aPoints[0][0], aPoints[0][1])), std::shared_ptr(new GeomAPI_Lin2d(aPoints[1][0], aPoints[1][1])) }; - std::shared_ptr 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 anAngle(new GeomAPI_Angle2d(aLine[0], isReversed[0], aLine[1], isReversed[1])); + std::shared_ptr aCenter = anAngle->center(); + + std::shared_ptr 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 aDir[2]; - for (int i = 0; i < 2; i++) { - if (aDist[i][1] > fabs(aDist[i][0])) - aDir[i] = std::shared_ptr(new GeomAPI_Dir2d( - aPoints[i][1]->xy()->decreased(anIntersection->xy()))); - else { - aDir[i] = std::shared_ptr(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 aNewPoints[2]; for (int i = 0; i < 2; i++) { aNewPoints[i] = std::shared_ptr( - 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 aDelta; diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp index 2adb7dcd6..5b34b1174 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp @@ -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; diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp index d63622683..efbe1ad2d 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp @@ -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 int Search(const uint32_t& theEntityID, const std::vector& 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)