From ceebcac17ac262e957107c61a8962d1e8a87c70a Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 17 Jun 2014 18:33:18 +0400 Subject: [PATCH] refs #80 - Sketch base GUI: create/draw point, circle and arc 1. Using the GeomAPI_Lin projection/distance for a line to be used later for a lenght constraint. 2. Correct projection() in the Line 3. Append double flyout value argument to the constraint. 4. Add lenght constraint presentation and operation to create it(may be later it will be join with feature create operation) --- src/GeomAPI/GeomAPI_Lin2d.cpp | 4 +- src/PartSet/CMakeLists.txt | 4 + src/PartSet/PartSet_FeatureLengthPrs.cpp | 174 +++++++++++++ src/PartSet/PartSet_FeatureLengthPrs.h | 78 ++++++ src/PartSet/PartSet_FeatureLinePrs.cpp | 41 ++- src/PartSet/PartSet_Module.cpp | 3 + src/PartSet/PartSet_OperationConstraint.cpp | 105 -------- .../PartSet_OperationCreateConstraint.cpp | 239 ++++++++++++++++++ .../PartSet_OperationCreateConstraint.h | 124 +++++++++ src/PartSet/PartSet_Presentation.cpp | 7 +- src/PartSet/PartSet_Tools.cpp | 46 +--- src/PartSet/PartSet_Tools.h | 26 -- src/SketchPlugin/SketchPlugin_Constraint.h | 2 + .../SketchPlugin_ConstraintLength.cpp | 1 + .../SketchPlugin_ConstraintLength.h | 3 +- 15 files changed, 673 insertions(+), 184 deletions(-) create mode 100644 src/PartSet/PartSet_FeatureLengthPrs.cpp create mode 100644 src/PartSet/PartSet_FeatureLengthPrs.h create mode 100644 src/PartSet/PartSet_OperationCreateConstraint.cpp create mode 100644 src/PartSet/PartSet_OperationCreateConstraint.h diff --git a/src/GeomAPI/GeomAPI_Lin2d.cpp b/src/GeomAPI/GeomAPI_Lin2d.cpp index 2d698c089..8eb102ae5 100644 --- a/src/GeomAPI/GeomAPI_Lin2d.cpp +++ b/src/GeomAPI/GeomAPI_Lin2d.cpp @@ -45,7 +45,7 @@ const boost::shared_ptr GeomAPI_Lin2d::intersect( IntAna2d_AnaIntersection anInter(*MY_LIN2D, theLine->impl()); if (!anInter.IsDone() || anInter.IsEmpty()) return boost::shared_ptr(); - const gp_Pnt2d& aResult = anInter.Point(0).Value(); + const gp_Pnt2d& aResult = anInter.Point(1).Value(); return boost::shared_ptr(new GeomAPI_Pnt2d(aResult.X(), aResult.Y())); } @@ -56,7 +56,7 @@ const boost::shared_ptr GeomAPI_Lin2d::project(const boost::share const gp_XY& aPnt = thePoint->impl().XY(); double aParam = aDir.Dot(aPnt - aLoc); - gp_XY aResult = aPnt + aDir * aParam; + gp_XY aResult = aLoc + aDir * aParam; return boost::shared_ptr(new GeomAPI_Pnt2d(aResult.X(), aResult.Y())); } diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index bb812080d..7c38f2fa0 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -8,11 +8,13 @@ SET(PROJECT_HEADERS PartSet_FeatureArcPrs.h PartSet_FeatureCirclePrs.h PartSet_FeaturePrs.h + PartSet_FeatureLengthPrs.h PartSet_FeatureLinePrs.h PartSet_FeaturePointPrs.h PartSet_Listener.h PartSet_Module.h PartSet_OperationConstraint.h + PartSet_OperationCreateConstraint.h PartSet_OperationCreateFeature.h PartSet_OperationEditFeature.h PartSet_OperationSketchBase.h @@ -26,11 +28,13 @@ SET(PROJECT_SOURCES PartSet_FeaturePrs.cpp PartSet_FeatureArcPrs.cpp PartSet_FeatureCirclePrs.cpp + PartSet_FeatureLengthPrs.cpp PartSet_FeatureLinePrs.cpp PartSet_FeaturePointPrs.cpp PartSet_Listener.cpp PartSet_Module.cpp PartSet_OperationConstraint.cpp + PartSet_OperationCreateConstraint.cpp PartSet_OperationCreateFeature.cpp PartSet_OperationEditFeature.cpp PartSet_OperationSketchBase.cpp diff --git a/src/PartSet/PartSet_FeatureLengthPrs.cpp b/src/PartSet/PartSet_FeatureLengthPrs.cpp new file mode 100644 index 000000000..944e7c51e --- /dev/null +++ b/src/PartSet/PartSet_FeatureLengthPrs.cpp @@ -0,0 +1,174 @@ +// File: PartSet_FeaturePrs.h +// Created: 16 Jun 2014 +// Author: Natalia ERMOLAEVA + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +using namespace std; + +PartSet_FeatureLengthPrs::PartSet_FeatureLengthPrs(FeaturePtr theSketch) +: PartSet_FeaturePrs(theSketch) +{ +} + +std::string PartSet_FeatureLengthPrs::getKind() +{ + return SKETCH_CONSTRAINT_LENGTH_KIND; +} + +PartSet_SelectionMode PartSet_FeatureLengthPrs::setPoint(double theX, double theY, + const PartSet_SelectionMode& theMode) +{ + PartSet_SelectionMode aMode = theMode; + switch (theMode) + { + case SM_FirstPoint: { + //PartSet_Tools::setFeaturePoint(feature(), theX, theY, CIRCLE_ATTR_CENTER); + //aMode = SM_SecondPoint; + } + break; + case SM_SecondPoint: { + /*boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aPoint = boost::dynamic_pointer_cast + (aData->attribute(CIRCLE_ATTR_CENTER)); + boost::shared_ptr aCoordPoint(new GeomAPI_Pnt2d(theX, theY)); + double aRadius = aCoordPoint->distance(aPoint->pnt()); + PartSet_Tools::setFeatureValue(feature(), aRadius, CIRCLE_ATTR_RADIUS); + + aMode = SM_DonePoint;*/ + } + break; + default: + break; + } + return aMode; +} + +std::string PartSet_FeatureLengthPrs::getAttribute(const PartSet_SelectionMode& theMode) const +{ + std::string aAttribute; + switch (theMode) + { + case SM_FirstPoint: + //aAttribute = CIRCLE_ATTR_CENTER; + break; + case SM_SecondPoint: + //aAttribute = CIRCLE_ATTR_RADIUS; + break; + default: + break; + } + return aAttribute; +} + +PartSet_SelectionMode PartSet_FeatureLengthPrs::getNextMode(const std::string& theAttribute) const +{ + PartSet_SelectionMode aMode = SM_SecondPoint; + + /*if (theAttribute == CIRCLE_ATTR_CENTER) + aMode = SM_SecondPoint; + else if (theAttribute == CIRCLE_ATTR_RADIUS) + aMode = SM_DonePoint;*/ + return aMode; +} + +void PartSet_FeatureLengthPrs::move(double theDeltaX, double theDeltaY) +{ + /*boost::shared_ptr aData = feature()->data(); + if (!aData->isValid()) + return; + + boost::shared_ptr aPoint1 = + boost::dynamic_pointer_cast(aData->attribute(CIRCLE_ATTR_CENTER)); + aPoint1->setValue(aPoint1->x() + theDeltaX, aPoint1->y() + theDeltaY);*/ +} + +double PartSet_FeatureLengthPrs::distanceToPoint(FeaturePtr theFeature, + double theX, double theY) +{ + /*double aDelta = 0; + if (!theFeature || theFeature->getKind() != getKind()) + return aDelta; + + boost::shared_ptr aData = theFeature->data(); + boost::shared_ptr aPoint = + boost::dynamic_pointer_cast(aData->attribute(CIRCLE_ATTR_CENTER)); + + boost::shared_ptr aPoint2d(new GeomAPI_Pnt2d(theX, theY)); + return aPoint->pnt()->distance(aPoint2d);*/ + return 0; +} + +boost::shared_ptr PartSet_FeatureLengthPrs::findPoint(FeaturePtr theFeature, + double theX, double theY) +{ + boost::shared_ptr aPoint2D; + /*if (!theFeature || theFeature->getKind() != getKind()) + return aPoint2D; + + boost::shared_ptr aData = theFeature->data(); + boost::shared_ptr aPoint = + boost::dynamic_pointer_cast(aData->attribute(CIRCLE_ATTR_CENTER)); + if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() ) + aPoint2D = aPoint; +*/ + return aPoint2D; +} + +boost::shared_ptr PartSet_FeatureLengthPrs::featurePoint + (const PartSet_SelectionMode& theMode) +{ + /*std::string aPointArg; + switch (theMode) + { + case SM_FirstPoint: + aPointArg = CIRCLE_ATTR_CENTER; + break; + default: + break; + } + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aPoint = boost::dynamic_pointer_cast + (aData->attribute(aPointArg)); + return aPoint; + */ + return boost::shared_ptr(); +} + +void PartSet_FeatureLengthPrs::initFeature(FeaturePtr theSourceFeature) +{ + if (feature() && theSourceFeature && theSourceFeature->getKind() == SKETCH_LINE_KIND) + { + // set length feature + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aRef = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_A)); + aRef->setFeature(theSourceFeature); + + // set length value + aData = theSourceFeature->data(); + boost::shared_ptr aPoint1 = + boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_START)); + boost::shared_ptr aPoint2 = + boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_END)); + + double aLenght = aPoint1->pnt()->distance(aPoint2->pnt()); + PartSet_Tools::setFeatureValue(feature(), aLenght, CONSTRAINT_ATTR_VALUE); + } +} diff --git a/src/PartSet/PartSet_FeatureLengthPrs.h b/src/PartSet/PartSet_FeatureLengthPrs.h new file mode 100644 index 000000000..2c39f38bc --- /dev/null +++ b/src/PartSet/PartSet_FeatureLengthPrs.h @@ -0,0 +1,78 @@ +// File: PartSet_FeatureLengthPrs.h +// Created: 16 Jun 2014 +// Author: Natalia ERMOLAEVA + +#ifndef PartSet_FeatureLengthPrs_H +#define PartSet_FeatureLengthPrs_H + +#include "PartSet.h" + +#include "PartSet_FeaturePrs.h" +#include "PartSet_Constants.h" + +class GeomDataAPI_Point2D; + +/*! + \class PartSet_FeatureLengthPrs + * \brief The class to define the circle feature manipulation. It is created for + * the feature create operation to move out the feature properties set and use one operation + * for any type of features. +*/ +class PARTSET_EXPORT PartSet_FeatureLengthPrs : public PartSet_FeaturePrs +{ +public: + /// Returns the feature type processed by this presentation + /// \return the feature kind + static std::string getKind(); + + /// Constructor + /// \param theSketch the sketch feature + PartSet_FeatureLengthPrs(FeaturePtr theSketch); + /// Destructor + virtual ~PartSet_FeatureLengthPrs() {}; + + /// Sets the point to the feature in an attribute depending on the selection mode + /// \param theX the 2D point horizontal coordinate + /// \param theY the 2D point vertical coordinate + /// \param theMode the selection mode + /// \return the new selection mode + virtual PartSet_SelectionMode setPoint(double theX, double theY, + const PartSet_SelectionMode& theMode); + + /// Returns the feature attribute name for the selection mode + /// \param theMode the current operation selection mode. The feature attribute depends on the mode + virtual std::string getAttribute(const PartSet_SelectionMode& theMode) const; + + /// Returns the next selection mode after the attribute + /// \param theAttribute the feature attribute name + /// \return next attribute selection mode + virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const; + + /// \brief Move the full feature. + /// \param theDeltaX the delta for X coordinate is moved + /// \param theDeltaY the delta for Y coordinate is moved + virtual void move(double theDeltaX, double theDeltaY); + + /// Return the distance between the feature and the point + /// \param theFeature feature object + /// \param theX the horizontal coordinate of the point + /// \param theX the vertical coordinate of the point + virtual double distanceToPoint(FeaturePtr theFeature, double theX, double theY); + + /// Find a point in the line with given coordinates + /// \param theFeature the line feature + /// \param theX the horizontal point coordinate + /// \param theY the vertical point coordinate + virtual boost::shared_ptr findPoint(FeaturePtr theFeature, double theX, + double theY); +protected: + /// Returns the feature point in the selection mode position. + /// \param theMode the current operation selection mode. The feature attribute depends on the mode + virtual boost::shared_ptr featurePoint(const PartSet_SelectionMode& theMode); + + /// Initializes current feature by the given + /// \param theSourceFeature the feature, which attributes are used to initialize the current feature + virtual void initFeature(FeaturePtr theSourceFeature); +}; + +#endif diff --git a/src/PartSet/PartSet_FeatureLinePrs.cpp b/src/PartSet/PartSet_FeatureLinePrs.cpp index 54af4c973..ae85a3d88 100644 --- a/src/PartSet/PartSet_FeatureLinePrs.cpp +++ b/src/PartSet/PartSet_FeatureLinePrs.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include @@ -122,20 +124,36 @@ void PartSet_FeatureLinePrs::projectPointOnLine(FeaturePtr theFeature, const gp_Pnt& thePoint, Handle(V3d_View) theView, double& theX, double& theY) { - if (theFeature) { + if (theFeature && theFeature->getKind() == getKind()) { double X0, X1, X2, X3; double Y0, Y1, Y2, Y3; getLinePoint(theFeature, LINE_ATTR_START, X2, Y2); getLinePoint(theFeature, LINE_ATTR_END, X3, Y3); - PartSet_Tools::convertTo2D(thePoint, sketch(), theView, X1, Y1); + PartSet_Tools::convertTo2D(thePoint, sketch(), theView, X1, Y1); + boost::shared_ptr aPoint = boost::shared_ptr(new GeomAPI_Pnt2d(X1, Y1)); + boost::shared_ptr aFeatureLin = boost::shared_ptr + (new GeomAPI_Lin2d(X2, Y2, X3, Y3)); switch (theMode) { - case SM_FirstPoint: - PartSet_Tools::projectPointOnLine(X2, Y2, X3, Y3, X1, Y1, theX, theY); + case SM_FirstPoint: { + boost::shared_ptr aResult = aFeatureLin->project(aPoint); + theX = aResult->x(); + theY = aResult->y(); + } break; case SM_SecondPoint: { getLinePoint(feature(), LINE_ATTR_START, X0, Y0); - PartSet_Tools::intersectLines(X0, Y0, X1, Y1, X2, Y2, X3, Y3, theX, theY); + boost::shared_ptr aCurrentLin = boost::shared_ptr + (new GeomAPI_Lin2d(X0, Y0, X1, Y1)); + boost::shared_ptr aResult = aFeatureLin->intersect(aCurrentLin); + boost::shared_ptr aPoint0 = boost::shared_ptr(new GeomAPI_Pnt2d(X0, Y0)); + if (aResult->distance(aPoint0) < Precision::Confusion()) { // the start point is nearest to the line + // if the first point of a line belongs to the given line + // we need to project the second point on the same line + aResult = aFeatureLin->project(aPoint); + } + theX = aResult->x(); + theY = aResult->y(); } break; default: @@ -157,9 +175,16 @@ double PartSet_FeatureLinePrs::distanceToPoint(FeaturePtr theFeature, boost::shared_ptr aPoint2 = boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_END)); - double aX, anY; - PartSet_Tools::projectPointOnLine(aPoint1->x(), aPoint1->y(), aPoint2->x(), aPoint2->y(), theX, theY, aX, anY); - aDelta = gp_Pnt(theX, theY, 0).Distance(gp_Pnt(aX, anY, 0)); + GeomAPI_Lin2d aLin2d(aPoint1->x(), aPoint1->y(), aPoint2->x(), aPoint2->y()); + boost::shared_ptr aPoint = boost::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); + + if (false/*projection*/) { // TODO: if it has not been necessary, remove this block + boost::shared_ptr aResult = aLin2d.project(aPoint); + aDelta = aResult->distance(aPoint); + } + else { // distance + aDelta = aLin2d.distance(aPoint); + } return aDelta; } diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index f33b67a13..8b683a169 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -327,6 +328,8 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI anOperation = new PartSet_OperationCreateFeature(theCmdId.c_str(), this, aSketch); else if (theCmdId == PartSet_OperationEditFeature::Type()) anOperation = new PartSet_OperationEditFeature(theCmdId.c_str(), this, aSketch); + else if (PartSet_OperationCreateConstraint::canProcessKind(theCmdId)) + anOperation = new PartSet_OperationCreateConstraint(theCmdId.c_str(), this, aSketch); else if (theCmdId == PartSet_OperationConstraint::Type()) anOperation = new PartSet_OperationConstraint(theCmdId.c_str(), this, aSketch); } diff --git a/src/PartSet/PartSet_OperationConstraint.cpp b/src/PartSet/PartSet_OperationConstraint.cpp index 447f7a4d3..3a96b309a 100644 --- a/src/PartSet/PartSet_OperationConstraint.cpp +++ b/src/PartSet/PartSet_OperationConstraint.cpp @@ -79,23 +79,7 @@ void PartSet_OperationConstraint::mouseReleased(QMouseEvent* theEvent, Handle(V3 const std::list& theSelected, const std::list& /*theHighlighted*/) { - /*if (myPointSelectionMode == SM_DonePoint) - { - // if the point creation is finished, the next mouse release should commit the modification - // the next release can happens by double click in the viewer - commit(); - restartOperation(PartSet_OperationConstraint::Type(), feature()); - return; - } - - double aX, anY; - - bool isFoundPoint = false; - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); -*/ if (theSelected.empty()) { - //PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); - //isFoundPoint = true; } else { XGUI_ViewerPrs aPrs = theSelected.front(); @@ -104,100 +88,11 @@ void PartSet_OperationConstraint::mouseReleased(QMouseEvent* theEvent, Handle(V3 setFeature(aFeature); setValue(120); flushUpdated(); - - /*const TopoDS_Shape& aShape = aPrs.shape(); - if (!aShape.IsNull()) // the point is selected - { - if (aShape.ShapeType() == TopAbs_VERTEX) { - const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape); - if (!aVertex.IsNull()) { - aPoint = BRep_Tool::Pnt(aVertex); - PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); - isFoundPoint = true; - - setConstraints(aX, anY); - } - } - else if (aShape.ShapeType() == TopAbs_EDGE) // the line is selected - { - FeaturePtr aFeature = aPrs.feature(); - if (aFeature) { - double X0, X1, X2, X3; - double Y0, Y1, Y2, Y3; - PartSet_Tools::getLinePoint(aFeature, LINE_ATTR_START, X2, Y2); - PartSet_Tools::getLinePoint(aFeature, LINE_ATTR_END, X3, Y3); - PartSet_Tools::convertTo2D(aPoint, sketch(), theView, X1, Y1); - - switch (myPointSelectionMode) { - case SM_FirstPoint: - PartSet_Tools::projectPointOnLine(X2, Y2, X3, Y3, X1, Y1, aX, anY); - break; - case SM_SecondPoint: { - PartSet_Tools::getLinePoint(feature(), LINE_ATTR_START, X0, Y0); - PartSet_Tools::intersectLines(X0, Y0, X1, Y1, X2, Y2, X3, Y3, aX, anY); - } - break; - default: - break; - } - isFoundPoint = true; - } - } - }*/ } - - /*switch (myPointSelectionMode) - { - case SM_FirstPoint: { - setLinePoint(feature(), aX, anY, LINE_ATTR_START); - setLinePoint(feature(), aX, anY, LINE_ATTR_END); - flushUpdated(); - - //setPointSelectionMode(SM_SecondPoint); - } - break; - case SM_SecondPoint: { - setLinePoint(feature(), aX, anY, LINE_ATTR_END); - flushUpdated(); - - //setPointSelectionMode(SM_DonePoint); - } - break; - default: - break; - }*/ } void PartSet_OperationConstraint::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView) { -/* switch (myPointSelectionMode) - { - case SM_FirstPoint: { - double aX, anY; - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); - PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); - setLinePoint(feature(), aX, anY, LINE_ATTR_START); - setLinePoint(feature(), aX, anY, LINE_ATTR_END); - flushUpdated(); - emit focusActivated(LINE_ATTR_START); - } - break; - case SM_SecondPoint: - { - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); - setLinePoint(aPoint, theView, LINE_ATTR_END); - flushUpdated(); - emit focusActivated(LINE_ATTR_END); - } - break; - case SM_DonePoint: - { - commit(); - restartOperation(PartSet_OperationConstraint::Type(), feature()); - } - default: - break; - }*/ } void PartSet_OperationConstraint::startOperation() diff --git a/src/PartSet/PartSet_OperationCreateConstraint.cpp b/src/PartSet/PartSet_OperationCreateConstraint.cpp new file mode 100644 index 000000000..a648c82a0 --- /dev/null +++ b/src/PartSet/PartSet_OperationCreateConstraint.cpp @@ -0,0 +1,239 @@ +// File: PartSet_OperationCreateConstraint.h +// Created: 20 Apr 2014 +// Author: Natalia ERMOLAEVA + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#ifdef _DEBUG +#include +#endif + +#include + +using namespace std; + +PartSet_OperationCreateConstraint::PartSet_OperationCreateConstraint(const QString& theId, + QObject* theParent, + FeaturePtr theFeature) +: PartSet_OperationSketchBase(theId, theParent), + myPointSelectionMode(SM_FirstPoint) +{ + std::string aKind = theId.toStdString(); + myFeaturePrs = PartSet_Tools::createFeaturePrs(aKind, theFeature); +} + +PartSet_OperationCreateConstraint::~PartSet_OperationCreateConstraint() +{ +} + +bool PartSet_OperationCreateConstraint::canProcessKind(const std::string& theId) +{ + return /*theId == SKETCH_LINE_KIND || theId == SKETCH_POINT_KIND || theId == SKETCH_CIRCLE_KIND || + theId == SKETCH_ARC_KIND || */theId == SKETCH_CONSTRAINT_LENGTH_KIND; +} + +bool PartSet_OperationCreateConstraint::canBeCommitted() const +{ + return myPointSelectionMode == SM_DonePoint; +} + +bool PartSet_OperationCreateConstraint::isGranted(ModuleBase_IOperation* theOperation) const +{ + return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type(); +} + +std::list PartSet_OperationCreateConstraint::getSelectionModes(FeaturePtr theFeature) const +{ + std::list aModes; + if (theFeature != feature()) + aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature); + return aModes; +} + +void PartSet_OperationCreateConstraint::init(FeaturePtr theFeature, + const std::list& /*theSelected*/, + const std::list& /*theHighlighted*/) +{ + if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) + return; + myInitFeature = theFeature; +} + +FeaturePtr PartSet_OperationCreateConstraint::sketch() const +{ + return myFeaturePrs->sketch(); +} + +void PartSet_OperationCreateConstraint::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView, + const std::list& theSelected, + const std::list& /*theHighlighted*/) +{ + if (theSelected.empty()) { + + } + else { + XGUI_ViewerPrs aPrs = theSelected.front(); + FeaturePtr aFeature = aPrs.feature(); + + myFeaturePrs->init(feature(), aFeature); + flushUpdated(); + } +} + +void PartSet_OperationCreateConstraint::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView) +{ + switch (myPointSelectionMode) + { + case SM_FirstPoint: + case SM_SecondPoint: + case SM_ThirdPoint: + { + double aX, anY; + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); + PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); + /*if (myPointSelectionMode == SM_ThirdPoint) { + if (feature()->getKind() == SKETCH_ARC_KIND) { + boost::shared_ptr anArcPrs = + boost::dynamic_pointer_cast(myFeaturePrs); + if (anArcPrs) { + anArcPrs->projectPointOnArc(aPoint, theView, aX, anY); + } + } + }*/ + myFeaturePrs->setPoint(aX, anY, myPointSelectionMode); + + flushUpdated(); + emit focusActivated(myFeaturePrs->getAttribute(myPointSelectionMode)); + } + break; + case SM_DonePoint: + { + commit(); + restartOperation(feature()->getKind(), feature()); + } + default: + break; + } +} + +void PartSet_OperationCreateConstraint::keyReleased(std::string theName, QKeyEvent* theEvent) +{ + int aKeyType = theEvent->key(); + // the second point should be activated by any modification in the property panel + if (!theName.empty() /*&& aKeyType == Qt::Key_Return*/) + { + setPointSelectionMode(myFeaturePrs->getNextMode(theName), false); + } + keyReleased(theEvent->key()); +} + +void PartSet_OperationCreateConstraint::keyReleased(const int theKey) +{ + switch (theKey) { + case Qt::Key_Return: { + if (myPointSelectionMode == SM_DonePoint) + { + commit(); + // it start a new line creation at a free point + restartOperation(feature()->getKind(), FeaturePtr()/*feature()*/); + } + //else + // abort(); + //restartOperation(feature()->getKind(), FeaturePtr()); + } + break; + case Qt::Key_Escape: { + if (myPointSelectionMode == SM_DonePoint) + { + commit(); + } + else + { + abort(); + } + } + default: + break; + } +} + +void PartSet_OperationCreateConstraint::startOperation() +{ + PartSet_OperationSketchBase::startOperation(); + setPointSelectionMode(!myInitFeature ? SM_FirstPoint : SM_SecondPoint); + + emit multiSelectionEnabled(false); +} + +void PartSet_OperationCreateConstraint::abortOperation() +{ + emit featureConstructed(feature(), FM_Hide); + PartSet_OperationSketchBase::abortOperation(); +} + +void PartSet_OperationCreateConstraint::stopOperation() +{ + PartSet_OperationSketchBase::stopOperation(); + emit multiSelectionEnabled(true); +} + +void PartSet_OperationCreateConstraint::afterCommitOperation() +{ + PartSet_OperationSketchBase::afterCommitOperation(); + emit featureConstructed(feature(), FM_Deactivation); +} + +FeaturePtr PartSet_OperationCreateConstraint::createFeature(const bool theFlushMessage) +{ + FeaturePtr aNewFeature = ModuleBase_Operation::createFeature(false); + if (sketch()) { + boost::shared_ptr aFeature = + boost::dynamic_pointer_cast(sketch()); + + aFeature->addSub(aNewFeature); + } + myFeaturePrs->init(aNewFeature, myInitFeature); + + emit featureConstructed(aNewFeature, FM_Activation); + if (theFlushMessage) + flushCreated(); + return aNewFeature; +} + +void PartSet_OperationCreateConstraint::setPointSelectionMode(const PartSet_SelectionMode& theMode, + const bool isToEmitSignal) +{ + myPointSelectionMode = theMode; + if (isToEmitSignal) { + std::string aName = myFeaturePrs->getAttribute(theMode); + if (aName.empty() && theMode == SM_DonePoint) { + aName = XGUI::PROP_PANEL_OK; + } + emit focusActivated(aName); + } +} diff --git a/src/PartSet/PartSet_OperationCreateConstraint.h b/src/PartSet/PartSet_OperationCreateConstraint.h new file mode 100644 index 000000000..9e09ad7df --- /dev/null +++ b/src/PartSet/PartSet_OperationCreateConstraint.h @@ -0,0 +1,124 @@ +// File: PartSet_OperationCreateConstraint.h +// Created: 20 Apr 2014 +// Author: Natalia ERMOLAEVA + +#ifndef PartSet_OperationCreateConstraint_H +#define PartSet_OperationCreateConstraint_H + +#include "PartSet.h" + +#include +#include + +#include + +class PartSet_FeaturePrs; +class GeomDataAPI_Point2D; +class QMouseEvent; +class QKeyEvent; + +/*! + \class PartSet_OperationCreateConstraint + * \brief The operation for the sketch feature creation +*/ +class PARTSET_EXPORT PartSet_OperationCreateConstraint : public PartSet_OperationSketchBase +{ + Q_OBJECT + +public: + /// Returns true if the feature with the given kind can be created by this operation + /// \param theId the feature kind + /// \return the boolean result + static bool canProcessKind(const std::string& theId); + +public: + /// Constructor + /// \param theId the feature identifier + /// \param theParent the operation parent + /// \param theSketch the parent feature + PartSet_OperationCreateConstraint(const QString& theId, QObject* theParent, + FeaturePtr theSketch); + /// Destructor + virtual ~PartSet_OperationCreateConstraint(); + + /// Verifies whether this operator can be commited. + /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled + virtual bool canBeCommitted() const; + + /// Returns that this operator can be started above already running one. + /// The runned operation should be the sketch feature modified operation + /// \param theOperation the previous running operation + virtual bool isGranted(ModuleBase_IOperation* theOperation) const; + + /// Returns the operation local selection mode + /// \param theFeature the feature object to get the selection mode + /// \return the selection mode + virtual std::list getSelectionModes(FeaturePtr theFeature) const; + + /// Initializes some fields accorging to the feature + /// \param theSelected the list of selected presentations + /// \param theHighlighted the list of highlighted presentations + virtual void init(FeaturePtr theFeature, + const std::list& theSelected, + const std::list& theHighlighted); + + /// Returns the operation sketch feature + /// \returns the sketch instance + virtual FeaturePtr sketch() const; + + /// Gives the current selected objects to be processed by the operation + /// \param theEvent the mouse event + /// \param theView a viewer to have the viewer the eye position + /// \param theSelected the list of selected presentations + /// \param theHighlighted the list of highlighted presentations + virtual void mouseReleased(QMouseEvent* theEvent, Handle_V3d_View theView, + const std::list& theSelected, + const std::list& theHighlighted); + /// Gives the current mouse point in the viewer + /// \param thePoint a point clicked in the viewer + /// \param theEvent the mouse event + virtual void mouseMoved(QMouseEvent* theEvent, Handle_V3d_View theView); + /// Processes the key pressed in the view + /// \param theKey a key value + virtual void keyReleased(const int theKey); + + virtual void keyReleased(std::string theName, QKeyEvent* theEvent); + +protected: + /// \brief Virtual method called when operation is started + /// Virtual method called when operation started (see start() method for more description) + /// After the parent operation body perform, set sketch feature to the created line feature + virtual void startOperation(); + + /// Virtual method called when operation aborted (see abort() method for more description) + /// Before the feature is aborted, it should be hidden from the viewer + virtual void abortOperation(); + + /// Virtual method called when operation stopped - committed or aborted. + /// Restore the multi selection state + virtual void stopOperation(); + + /// Virtual method called after operation committed (see commit() method for more description) + virtual void afterCommitOperation(); + + /// Creates an operation new feature + /// In addition to the default realization it appends the created line feature to + /// the sketch feature + /// \param theFlushMessage the flag whether the create message should be flushed + /// \returns the created feature + virtual FeaturePtr createFeature(const bool theFlushMessage = true); + +protected: + ///< Set the point selection mode. Emit signal about focus change if necessary. + /// \param theMode a new selection mode + /// \param isToEmitSignal the neccessity to emit signal + void setPointSelectionMode(const PartSet_SelectionMode& theMode, + const bool isToEmitSignal = true); + +private: + boost::shared_ptr myFeaturePrs; ///< the feature presentation + FeaturePtr myInitFeature; ///< the initial feature + PartSet_SelectionMode myPointSelectionMode; ///< point selection mode +}; + +#endif diff --git a/src/PartSet/PartSet_Presentation.cpp b/src/PartSet/PartSet_Presentation.cpp index 28d9ce3d1..18fcce5f8 100644 --- a/src/PartSet/PartSet_Presentation.cpp +++ b/src/PartSet/PartSet_Presentation.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -101,6 +102,10 @@ Handle(AIS_InteractiveObject) PartSet_Presentation::createSketchConstraintLength if (!aFeature || aFeature->getKind() != SKETCH_LINE_KIND) return thePrevPrs; + boost::shared_ptr aFlyoutAttr = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE)); + double aFlyout = aFlyoutAttr->value(); + aData = aFeature->data(); if (!aData->isValid()) return thePrevPrs; @@ -134,7 +139,7 @@ Handle(AIS_InteractiveObject) PartSet_Presentation::createSketchConstraintLength aLenDim->SetDisplayUnits (aDimDlg->GetUnits ()); }*/ aLenDim->SetDimensionAspect (anAspect); - aLenDim->SetFlyout(12); + aLenDim->SetFlyout(aFlyout); anAIS = aLenDim; } diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 3e965280a..615f79a28 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -25,6 +25,8 @@ #include #include +#include + #include #include @@ -134,47 +136,6 @@ void PartSet_Tools::convertTo3D(const double theX, const double theY, thePoint = gp_Pnt(aPoint->x(), aPoint->y(), aPoint->z()); } -void PartSet_Tools::intersectLines(double theX0, double theY0, double theX1, double theY1, - double theX2, double theY2, double theX3, double theY3, - double& theX, double& theY) -{ - double aV1 = theX1 - theX0, aV2 = theY1 - theY0; - double aW1 = theX3 - theX2, aW2 = theY3 - theY2; - - double aT2 = 0; - if (aV1 != 0 && aV2 != 0) - aT2 = (( theY2 - theY0 )/aV2 - ( theX2 - theX0 )/aV1) / ( aW1/aV1 - aW2/aV2 ); - else - aT2 = DBL_MAX; - - theX = theX2 + aT2*aW1; - theY = theY2 + aT2*aW2; - - // the coordinates of two lines are on the common line - //It is not possible to use Precision::Confusion(), because it is e-0.8, but V is sometimes e-6 - Standard_Real aPrec = PRECISION_TOLERANCE; - if (fabs(theX - theX0) < aPrec && fabs(theY - theY0) < aPrec) { - projectPointOnLine(theX2, theY2, theX3, theY3, theX1, theY1, theX, theY); - } -} - -void PartSet_Tools::projectPointOnLine(double theX1, double theY1, double theX2, double theY2, - double thePointX, double thePointY, double& theX, double& theY) -{ - theX = theY = 0; - - Handle(Geom_Line) aLine = new Geom_Line(gp_Pnt(theX1, theY1, 0), - gp_Dir(gp_Vec(gp_Pnt(theX1, theY1, 0), gp_Pnt(theX2, theY2, 0)))); - GeomAPI_ProjectPointOnCurve aProj(gp_Pnt(thePointX, thePointY, 0), aLine); - - Standard_Integer aNbPoint = aProj.NbPoints(); - if (aNbPoint > 0) { - gp_Pnt aPoint = aProj.Point(1); - theX = aPoint.X(); - theY = aPoint.Y(); - } -} - boost::shared_ptr PartSet_Tools::createFeaturePrs(const std::string& theKind, FeaturePtr theSketch, FeaturePtr theFeature) @@ -193,6 +154,9 @@ boost::shared_ptr PartSet_Tools::createFeaturePrs(const std: else if (theKind == PartSet_FeatureArcPrs::getKind()) { aFeaturePrs = boost::shared_ptr(new PartSet_FeatureArcPrs(theSketch)); } + else if (theKind == PartSet_FeatureLengthPrs::getKind()) { + aFeaturePrs = boost::shared_ptr(new PartSet_FeatureLengthPrs(theSketch)); + } if (theFeature && aFeaturePrs) aFeaturePrs->init(theFeature, FeaturePtr()); diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index fff206b6f..a3de5e0f2 100644 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -50,32 +50,6 @@ public: static void convertTo3D(const double theX, const double theY, FeaturePtr theSketch, gp_Pnt& thePoint); - /// Returns the point of intersection of the two lines, the first is (v0, v1), the second is (v2, v3), - /// where vi - {xi,yi}. If the v0 is on the second line, the result is a projection of the v1 to this line - /// \param theX0 the horizontal coordinate of 0 point - /// \param theY0 the vertical coordinate of 0 point - /// \param theX1 the horizontal coordinate of 1 point - /// \param theY1 the vertical coordinate of 1 point - /// \param theX2 the horizontal coordinate of 2 point - /// \param theY2 the vertical coordinate of 2 point - /// \param theX3 the horizontal coordinate of 3 point - /// \param theY3 the vertical coordinate of 3 point - /// \param theX the output horizontal coordinate of the intersection point - /// \param theY the outpup vertical coordinate of the intersection point - static void intersectLines(double theX0, double theY0, double theX1, double theY1, - double theX2, double theY2, double theX3, double theY3, - double& theX, double& theY); - - /// Returns the coordinates of projection of the point to the line - /// \param thePointX the projected point horizontal coordinate - /// \param thePointY the projected point vertictal coordinate - /// \param theX1 the horizontal coordinate of the first line point - /// \param theY1 the vertical coordinate of the first line point - /// \param theX2 the horizontal coordinate of the second line point - /// \param theY2 the vertical coordinate of the second line point - static void projectPointOnLine(double theX1, double theY1, double theX2, double theY2, - double thePointX, double thePointY, double& theX, double& theY); - /// Creates the feature presentation /// \param theKind a feature kind /// \param theSketch the sketch of the feature diff --git a/src/SketchPlugin/SketchPlugin_Constraint.h b/src/SketchPlugin/SketchPlugin_Constraint.h index b4e8bcca6..08dc621c7 100644 --- a/src/SketchPlugin/SketchPlugin_Constraint.h +++ b/src/SketchPlugin/SketchPlugin_Constraint.h @@ -26,6 +26,8 @@ */ /// The value parameter for the constraint const std::string CONSTRAINT_ATTR_VALUE("ConstraintValue"); +/// The value parameter for the constraint +const std::string CONSTRAINT_ATTR_FLYOUT_VALUE("ConstraintFlyoutValue"); /// First entity for the constraint const std::string CONSTRAINT_ATTR_ENTITY_A("ConstraintEntityA"); /// Second entity for the constraint diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp b/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp index 07a86905e..b5fe8fca3 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp @@ -14,6 +14,7 @@ SketchPlugin_ConstraintLength::SketchPlugin_ConstraintLength() void SketchPlugin_ConstraintLength::initAttributes() { data()->addAttribute(CONSTRAINT_ATTR_VALUE, ModelAPI_AttributeDouble::type()); + data()->addAttribute(CONSTRAINT_ATTR_FLYOUT_VALUE, ModelAPI_AttributeDouble::type()); data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type()); } diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.h b/src/SketchPlugin/SketchPlugin_ConstraintLength.h index bc614e137..57a5dbcc6 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintLength.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintLength.h @@ -18,7 +18,8 @@ const std::string SKETCH_CONSTRAINT_LENGTH_KIND("SketchConstraintLength"); * \brief Feature for creation of a new constraint which defines a length of a line segment * * These constraint has two attributes: - * CONSTRAINT_ATTR_VALUE (length) and CONSTRAINT_ATTR_ENTITY_A (segment) + * CONSTRAINT_ATTR_VALUE (length) and CONSTRAINT_ATTR_ENTITY_A (segment), + * CONSTRAINT_ATTR_FLYOUT_VALUE (distance of a constraints handle) */ class SketchPlugin_ConstraintLength: public SketchPlugin_Constraint { -- 2.39.2