#include <SketcherPrs_Tools.h>
#include <SketcherPrs_Factory.h>
+#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Lin2d.h>
#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_XY.h>
#include <GeomDataAPI_Point2D.h>
#include <ModelAPI_AttributeDouble.h>
#include <Config_PropManager.h>
+#include <math.h>
+
const double tolerance = 1e-7;
SketchPlugin_ConstraintDistance::SketchPlugin_ConstraintDistance()
{
+ myFlyoutUpdate = false;
}
//*************************************************************************************
if (!sketch())
return false;
+ std::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(attribute(theAttributeId));
+ if (fabs(aFlyOutAttr->x()) >= tolerance || fabs(aFlyOutAttr->y()) >= tolerance)
+ return false;
+
DataPtr aData = data();
std::shared_ptr<GeomDataAPI_Point2D> aPoint_A = SketcherPrs_Tools::getFeaturePoint(
aData, SketchPlugin_Constraint::ENTITY_A());
aPnt_A = aPoint_A->pnt();
aPnt_B = aPoint_B->pnt();
} else if (!aPoint_A && aPoint_B) {
- //std::shared_ptr<SketchPlugin_Line> aLine = SketcherPrs_Tools::getFeatureLine(
- // aData, SketchPlugin_Constraint::ENTITY_A());
- //if (aLine) {
- // aPnt_B = aPoint_B->pnt();
- // aPnt_A = SketcherPrs_Tools::getProjectionPoint(aLine, aPnt_B);
- //}
+ FeaturePtr aLine = SketcherPrs_Tools::getFeatureLine(
+ aData, SketchPlugin_Constraint::ENTITY_A());
+ if (aLine) {
+ aPnt_B = aPoint_B->pnt();
+ aPnt_A = SketcherPrs_Tools::getProjectionPoint(aLine, aPnt_B);
+ }
} else if (aPoint_A && !aPoint_B) {
- //std::shared_ptr<SketchPlugin_Line> aLine = SketcherPrs_Tools::getFeatureLine(
- // aData, SketchPlugin_Constraint::ENTITY_B());
- //if (aLine) {
- // aPnt_A = aPoint_A->pnt();
- // aPnt_B = SketcherPrs_Tools::getProjectionPoint(aLine, aPnt_A);
- //}
+ FeaturePtr aLine = SketcherPrs_Tools::getFeatureLine(
+ aData, SketchPlugin_Constraint::ENTITY_B());
+ if (aLine) {
+ aPnt_A = aPoint_A->pnt();
+ aPnt_B = SketcherPrs_Tools::getProjectionPoint(aLine, aPnt_A);
+ }
}
if (!aPnt_A || !aPnt_B)
return false;
- std::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = std::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(aData->attribute(theAttributeId));
-
std::shared_ptr<GeomAPI_Pnt> aPoint1 = sketch()->to3D(aPnt_A->x(), aPnt_A->y());
std::shared_ptr<GeomAPI_Pnt> aPoint2 = sketch()->to3D(aPnt_B->x(), aPnt_B->y());
// it is not possible to create lin2d on the points with equal position
if (!aData->isValid())
return;
+ // Recalculate a shift of flyout point in terms of local coordinates
+ std::shared_ptr<GeomAPI_XY> aDir(new GeomAPI_XY(theDeltaX, theDeltaY));
+ std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
+ data(), SketchPlugin_Constraint::ENTITY_A());
+ std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
+ data(), SketchPlugin_Constraint::ENTITY_B());
+
+ std::shared_ptr<GeomAPI_XY> aStartPnt;
+ std::shared_ptr<GeomAPI_XY> aEndPnt;
+ if (aPointA && aPointB) {
+ aStartPnt = aPointA->pnt()->xy();
+ aEndPnt = aPointB->pnt()->xy();
+ } else if (aPointA) {
+ FeaturePtr aLine = SketcherPrs_Tools::getFeatureLine(data(),
+ SketchPlugin_Constraint::ENTITY_B());
+ if (!aLine)
+ return;
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = aPointA->pnt();
+ aStartPnt = aPoint->xy();
+ aEndPnt = SketcherPrs_Tools::getProjectionPoint(aLine, aPoint)->xy();
+ } else if (aPointB) {
+ FeaturePtr aLine = SketcherPrs_Tools::getFeatureLine(data(),
+ SketchPlugin_Constraint::ENTITY_A());
+ if (!aLine)
+ return;
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = aPointB->pnt();
+ aStartPnt = SketcherPrs_Tools::getProjectionPoint(aLine, aPoint)->xy();
+ aEndPnt = aPoint->xy();
+ } else
+ return;
+
+ std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
+ double dX = aDir->dot(aLineDir->xy());
+ double dY = -aDir->cross(aLineDir->xy());
+
std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
- aPoint->move(theDeltaX, theDeltaY);
+ myFlyoutUpdate = true;
+ aPoint->setValue(aPoint->x() + dX, aPoint->y() + dY);
+ myFlyoutUpdate = false;
}
double SketchPlugin_ConstraintDistance::calculateCurrentDistance() const
std::shared_ptr<GeomDataAPI_Point2D> aPointB =
SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B());
- if (aPointA && aPointB) { // both points
+ if (aPointA.get() && aPointB.get()) { // both points
aDistance = aPointA->pnt()->distance(aPointB->pnt());
} else {
-// if (!aPointA && aPointB) { //Line and point
-// std::shared_ptr<SketchPlugin_Line> aLine =
-// SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
-// if (aLine) {
-// aDistance = aLine->distanceToPoint(aPointB->pnt());
-// }
-// } else if (aPointA && !aPointB) { // Point and line
-// std::shared_ptr<SketchPlugin_Line> aLine =
-// SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
-// if (aLine) {
-// aDistance = aLine->distanceToPoint(aPointA->pnt());
-// }
-// }
+ FeaturePtr aLineFeature;
+ std::shared_ptr<SketchPlugin_Line> aLine;
+ if (!aPointA.get() && aPointB.get()) { //Line and point
+ aLineFeature = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
+ aLine = std::dynamic_pointer_cast<SketchPlugin_Line>(aLineFeature);
+ if (aLine.get()) {
+ aDistance = aLine->distanceToPoint(aPointB->pnt());
+ }
+ } else if (aPointA.get() && !aPointB.get()) { // Point and line
+ aLineFeature = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
+ aLine = std::dynamic_pointer_cast<SketchPlugin_Line>(aLineFeature);
+ if (aLine.get()) {
+ aDistance = aLine->distanceToPoint(aPointA->pnt());
+ }
+ }
}
return aDistance;
}
-void SketchPlugin_ConstraintDistance::attributeChanged(const std::string& theID) {
+void SketchPlugin_ConstraintDistance::attributeChanged(const std::string& theID)
+{
if (theID == SketchPlugin_Constraint::ENTITY_A() ||
theID == SketchPlugin_Constraint::ENTITY_B())
{
aValueAttr->setValue(aDistance);
}
}
+ } else if (theID == SketchPlugin_Constraint::FLYOUT_VALUE_PNT() && !myFlyoutUpdate) {
+ myFlyoutUpdate = true;
+ // Recalculate flyout point in local coordinates of the distance constraint:
+ // the X coordinate is a length of projection of the flyout point on the line binding two distanced points
+ // or a line of projection of the distanced point onto the distanced segment
+ // the Y coordinate is a distance from the flyout point to the line
+ std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+ std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
+
+ std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
+ data(), SketchPlugin_Constraint::ENTITY_A());
+ std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
+ data(), SketchPlugin_Constraint::ENTITY_B());
+
+ std::shared_ptr<GeomAPI_XY> aStartPnt;
+ std::shared_ptr<GeomAPI_XY> aEndPnt;
+ if (aPointA && aPointB) {
+ aStartPnt = aPointA->pnt()->xy();
+ aEndPnt = aPointB->pnt()->xy();
+ } else if (aPointA) {
+ FeaturePtr aLine = SketcherPrs_Tools::getFeatureLine(data(),
+ SketchPlugin_Constraint::ENTITY_B());
+ if (!aLine)
+ return;
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = aPointA->pnt();
+ aStartPnt = aPoint->xy();
+ aEndPnt = SketcherPrs_Tools::getProjectionPoint(aLine, aPoint)->xy();
+ } else if (aPointB) {
+ FeaturePtr aLine = SketcherPrs_Tools::getFeatureLine(data(),
+ SketchPlugin_Constraint::ENTITY_A());
+ if (!aLine)
+ return;
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = aPointB->pnt();
+ aStartPnt = SketcherPrs_Tools::getProjectionPoint(aLine, aPoint)->xy();
+ aEndPnt = aPoint->xy();
+ } else
+ return;
+
+ std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
+ std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aStartPnt);
+
+ double X = aFlyoutDir->dot(aLineDir->xy());
+ double Y = -aFlyoutDir->cross(aLineDir->xy());
+ aFlyoutAttr->setValue(X, Y);
+ myFlyoutUpdate = false;
}
}