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()
{
// 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;
}
}
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()));
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)
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);
+}
SketchSolver_Error.h
SketchSolver_Solver.h
SketchSolver_Constraint.h
+ SketchSolver_ConstraintAngle.h
SketchSolver_ConstraintCoincidence.h
SketchSolver_ConstraintDistance.h
SketchSolver_ConstraintEqual.h
SET(PROJECT_SOURCES
SketchSolver_Solver.cpp
SketchSolver_Constraint.cpp
+ SketchSolver_ConstraintAngle.cpp
SketchSolver_ConstraintCoincidence.cpp
SketchSolver_ConstraintDistance.cpp
SketchSolver_ConstraintEqual.cpp
#include "SketchSolver_Builder.h"
#include <SketchPlugin_ConstraintAngle.h>
+#include <SketchSolver_ConstraintAngle.h>
#include <SketchSolver_ConstraintCoincidence.h>
#include <SketchSolver_ConstraintDistance.h>
#include <SketchSolver_ConstraintEqual.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)
- {}
-
- 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
--- /dev/null
+#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);
+}
--- /dev/null
+// 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