-// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include "SketchPlugin_ConstraintDistance.h"
#include <SketchPlugin_Point.h>
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Tools.h>
#include <SketcherPrs_Tools.h>
#include <SketcherPrs_Factory.h>
#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_XY.h>
#include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Dir.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_Data.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
#include <Config_PropManager.h>
data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+ data()->addAttribute(SIGNED(), ModelAPI_AttributeBoolean::typeId());
+
+ data()->addAttribute(SketchPlugin_ConstraintDistance::LOCATION_TYPE_ID(),
+ ModelAPI_AttributeInteger::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATION_TYPE_ID());
+
+ AttributePtr anAttr = data()->addAttribute(SketchPlugin_ConstraintDistance::DIRECTION_ID(),
+ GeomDataAPI_Dir::typeId());
+ anAttr->setIsArgument(false);
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), DIRECTION_ID());
}
void SketchPlugin_ConstraintDistance::colorConfigInfo(std::string& theSection, std::string& theName,
return thePrevious;
AISObjectPtr anAIS = SketcherPrs_Factory::lengthDimensionConstraint(this,
- sketch()->coordinatePlane(),
+ sketch(),
thePrevious);
+ if (anAIS.get() && !thePrevious.get())
+ SketchPlugin_Tools::setDimensionColor(anAIS);
return anAIS;
}
-//*************************************************************************************
-void SketchPlugin_ConstraintDistance::move(double theDeltaX, double theDeltaY)
+static std::shared_ptr<GeomAPI_Lin2d> getLine(DataPtr theData, const std::string& theAttrName)
{
- std::shared_ptr<ModelAPI_Data> aData = data();
- if (!aData->isValid())
- return;
+ FeaturePtr aLineFeature = SketcherPrs_Tools::getFeatureLine(theData, theAttrName);
+ if (!aLineFeature)
+ return GeomLine2dPtr();
- // 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<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
- std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
- data(), SketchPlugin_Constraint::ENTITY_A(), aPlane);
- std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
- data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
-
- 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> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineFeature->attribute(SketchPlugin_Line::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineFeature->attribute(SketchPlugin_Line::END_ID()));
- std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
- myFlyoutUpdate = true;
- if (aPoint->isInitialized()) {
- aPoint->setValue(aPoint->x() + dX, aPoint->y() + dY);
- } else {
- aPoint->setValue(dX, dY);
- }
- myFlyoutUpdate = false;
+ return GeomLine2dPtr(new GeomAPI_Lin2d(aStart->x(), aStart->y(), aEnd->x(), aEnd->y()));
}
double SketchPlugin_ConstraintDistance::calculateCurrentDistance()
std::shared_ptr<GeomDataAPI_Point2D> aPointB =
SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B(), aPlane);
+ GeomPnt2dPtr aGeomPntA, aGeomPntB;
+ GeomLine2dPtr aLine;
if (aPointA.get() && aPointB.get()) { // both points
- aDistance = aPointA->pnt()->distance(aPointB->pnt());
+ aGeomPntA = aPointA->pnt();
+ aGeomPntB = aPointB->pnt();
} else {
- 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());
- }
+ aLine = getLine(aData, SketchPlugin_Constraint::ENTITY_A());
+ aGeomPntB = aPointB->pnt();
+ aGeomPntA = aLine ? aLine->project(aGeomPntB) : GeomPnt2dPtr();
} 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());
- }
+ aLine = getLine(aData, SketchPlugin_Constraint::ENTITY_B());
+ aGeomPntA = aPointA->pnt();
+ aGeomPntB = aLine ? aLine->project(aGeomPntA) : GeomPnt2dPtr();
}
}
+
+ if (aGeomPntA.get() && aGeomPntB.get()) {
+ aDistance = aGeomPntA->distance(aGeomPntB);
+ if (aDistance < tolerance)
+ aDistance = 0.0;
+ }
+
+ // keep the direction between arguments for processing of the zero distance
+ std::shared_ptr<GeomDataAPI_Dir> aPointPointDir =
+ std::dynamic_pointer_cast<GeomDataAPI_Dir>(attribute(DIRECTION_ID()));
+ if (aDistance > tolerance)
+ aPointPointDir->setValue(aGeomPntB->x() - aGeomPntA->x(), aGeomPntB->y() - aGeomPntA->y(), 0.0);
+ else if (aLine) {
+ GeomDir2dPtr aLineDir = aLine->direction();
+ aPointPointDir->setValue(-aLineDir->y(), aLineDir->x(), 0.0);
+ }
+
return aDistance;
}
if (!aValueAttr->isInitialized()) {
// only if it is not initialized, try to compute the current value
double aDistance = calculateCurrentDistance();
- if (aDistance > 0) { // set as value the length of updated references
+ if (aDistance >= 0) { // set as value the length of updated references
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
} else
return;
- if (aEndPnt->distance(aStartPnt) < tolerance)
- return;
-
- std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
+ myFlyoutUpdate = true;
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);
+ if (aEndPnt->distance(aStartPnt) >= tolerance) {
+ std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
+ double X = aFlyoutDir->dot(aLineDir->xy());
+ double Y = -aFlyoutDir->cross(aLineDir->xy());
+ aFlyoutAttr->setValue(X, Y);
+ }
+ else
+ aFlyoutAttr->setValue(aFlyoutDir->x(), aFlyoutDir->y());
myFlyoutUpdate = false;
}
}