1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: SketchPlugin_ConstraintDistanceVertical.cpp
4 // Created: 10 May 2017
5 // Author: Artem ZHIDKOV
7 #include <SketchPlugin_ConstraintDistanceVertical.h>
9 #include <SketcherPrs_Tools.h>
10 #include <SketcherPrs_Factory.h>
12 #include <GeomAPI_Dir2d.h>
13 #include <GeomAPI_XY.h>
14 #include <GeomDataAPI_Point2D.h>
16 #include <ModelAPI_AttributeDouble.h>
18 const double tolerance = 1e-7;
21 SketchPlugin_ConstraintDistanceVertical::SketchPlugin_ConstraintDistanceVertical()
22 : SketchPlugin_ConstraintDistance()
26 //*************************************************************************************
27 void SketchPlugin_ConstraintDistanceVertical::initAttributes()
29 data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
30 data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
31 data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
32 data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
35 //*************************************************************************************
36 void SketchPlugin_ConstraintDistanceVertical::execute()
38 AttributeDoublePtr anAttrValue = real(SketchPlugin_Constraint::VALUE());
39 if (anAttrValue->isInitialized() || !areAttributesInitialized())
42 double aDistance = calculateCurrentDistance();
43 anAttrValue->setValue(aDistance);
46 //*************************************************************************************
47 AISObjectPtr SketchPlugin_ConstraintDistanceVertical::getAISObject(AISObjectPtr thePrevious)
52 AISObjectPtr anAIS = SketcherPrs_Factory::lengthDimensionConstraint(this,
53 sketch()->coordinatePlane(),
58 //*************************************************************************************
59 void SketchPlugin_ConstraintDistanceVertical::move(double theDeltaX, double theDeltaY)
61 std::shared_ptr<ModelAPI_Data> aData = data();
62 if (!aData->isValid())
65 // Recalculate a shift of flyout point in terms of local coordinates
66 std::shared_ptr<GeomAPI_XY> aDir(new GeomAPI_XY(theDeltaX, theDeltaY));
67 std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
68 std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
69 data(), SketchPlugin_Constraint::ENTITY_A(), aPlane);
70 std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
71 data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
73 if (!aPointA || !aPointB)
76 std::shared_ptr<GeomAPI_XY> aStartPnt = aPointA->pnt()->xy();
77 std::shared_ptr<GeomAPI_XY> aEndPnt = aPointB->pnt()->xy();
79 std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
80 double dX = aDir->dot(aLineDir->xy());
81 double dY = -aDir->cross(aLineDir->xy());
83 std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
84 aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
85 myFlyoutUpdate = true;
86 if (aPoint->isInitialized()) {
87 aPoint->setValue(aPoint->x() + dX, aPoint->y() + dY);
89 aPoint->setValue(dX, dY);
91 myFlyoutUpdate = false;
94 double SketchPlugin_ConstraintDistanceVertical::calculateCurrentDistance()
96 std::shared_ptr<ModelAPI_Data> aData = data();
97 std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
98 std::shared_ptr<GeomDataAPI_Point2D> aPointA =
99 SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A(), aPlane);
100 std::shared_ptr<GeomDataAPI_Point2D> aPointB =
101 SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B(), aPlane);
103 return aPointB->y() - aPointA->y();
106 void SketchPlugin_ConstraintDistanceVertical::attributeChanged(const std::string& theID)
108 if (theID == SketchPlugin_Constraint::ENTITY_A() ||
109 theID == SketchPlugin_Constraint::ENTITY_B())
111 AttributeDoublePtr aValueAttr = real(SketchPlugin_Constraint::VALUE());
112 if (!aValueAttr->isInitialized() && areAttributesInitialized()) {
113 // only if it is not initialized, try to compute the current value
114 double aDistance = calculateCurrentDistance();
115 aValueAttr->setValue(aDistance);
117 } else if (theID == SketchPlugin_Constraint::FLYOUT_VALUE_PNT() && !myFlyoutUpdate) {
118 myFlyoutUpdate = true;
119 // Recalculate flyout point in local coordinates of the distance constraint:
120 // the X coordinate is a length of projection of the flyout point on the
121 // line binding two distanced points
122 // or a line of projection of the distanced point onto the distanced segment
123 // the Y coordinate is a distance from the flyout point to the line
124 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
125 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
126 attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
127 std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
129 std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
130 std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
131 data(), SketchPlugin_Constraint::ENTITY_A(), aPlane);
132 std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
133 data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
135 std::shared_ptr<GeomAPI_XY> aStartPnt = aPointA->pnt()->xy();
136 std::shared_ptr<GeomAPI_XY> aEndPnt = aPointB->pnt()->xy();
138 if (aEndPnt->distance(aStartPnt) < tolerance)
141 std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
142 std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aStartPnt);
144 double X = aFlyoutDir->dot(aLineDir->xy());
145 double Y = -aFlyoutDir->cross(aLineDir->xy());
146 aFlyoutAttr->setValue(X, Y);
147 myFlyoutUpdate = false;