From c8d61fbcebb393ff8dff2a005729776d4a1b3f59 Mon Sep 17 00:00:00 2001 From: nds Date: Thu, 5 Jun 2014 13:55:33 +0400 Subject: [PATCH] refs #80 - Sketch base GUI: create/draw point, circle and arc Create features step. It splits the operation of sketch line creation to the common operation part and feature presentation part. Common operation part will be applicable for all features created. The feature presentation will contain the specific behavior for a separate feature. --- src/PartSet/CMakeLists.txt | 7 +- src/PartSet/PartSet_Constants.h | 21 + src/PartSet/PartSet_FeaturePrs.cpp | 224 +++++++++ src/PartSet/PartSet_FeaturePrs.h | 102 ++++ src/PartSet/PartSet_Module.cpp | 8 +- .../PartSet_OperationCreateFeature.cpp | 276 +++++++++++ ...ine.h => PartSet_OperationCreateFeature.h} | 73 +-- src/PartSet/PartSet_OperationSketchLine.cpp | 443 ------------------ src/PartSet/PartSet_TestOCC.cpp | 24 +- 9 files changed, 660 insertions(+), 518 deletions(-) create mode 100644 src/PartSet/PartSet_Constants.h create mode 100644 src/PartSet/PartSet_FeaturePrs.cpp create mode 100644 src/PartSet/PartSet_FeaturePrs.h create mode 100644 src/PartSet/PartSet_OperationCreateFeature.cpp rename src/PartSet/{PartSet_OperationSketchLine.h => PartSet_OperationCreateFeature.h} (58%) delete mode 100644 src/PartSet/PartSet_OperationSketchLine.cpp diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index b0006fe5c..fe69c3399 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -4,26 +4,29 @@ SET(CMAKE_AUTOMOC ON) SET(PROJECT_HEADERS PartSet.h + PartSet_Constants.h + PartSet_FeaturePrs.h PartSet_Listener.h PartSet_Module.h PartSet_OperationConstraint.h + PartSet_OperationCreateFeature.h PartSet_OperationEditLine.h PartSet_OperationSketchBase.h PartSet_OperationSketch.h - PartSet_OperationSketchLine.h PartSet_Presentation.h PartSet_TestOCC.h PartSet_Tools.h ) SET(PROJECT_SOURCES + PartSet_FeaturePrs.cpp PartSet_Listener.cpp PartSet_Module.cpp PartSet_OperationConstraint.cpp + PartSet_OperationCreateFeature.cpp PartSet_OperationEditLine.cpp PartSet_OperationSketchBase.cpp PartSet_OperationSketch.cpp - PartSet_OperationSketchLine.cpp PartSet_Presentation.cpp PartSet_TestOCC.cpp PartSet_Tools.cpp diff --git a/src/PartSet/PartSet_Constants.h b/src/PartSet/PartSet_Constants.h new file mode 100644 index 000000000..95b28bd00 --- /dev/null +++ b/src/PartSet/PartSet_Constants.h @@ -0,0 +1,21 @@ +// File: PartSet_Tools.h +// Created: 04 Jun 2014 +// Author: Natalia ERMOLAEVA + +#ifndef PartSet_Constants_H +#define PartSet_Constants_H + +#include + +/// This file contains various constants used in the PartSet module + +/// Types of viewer selection in an operation +enum PartSet_SelectionMode +{ + SM_FirstPoint, + SM_SecondPoint, + SM_DonePoint +}; + + +#endif diff --git a/src/PartSet/PartSet_FeaturePrs.cpp b/src/PartSet/PartSet_FeaturePrs.cpp new file mode 100644 index 000000000..434dd94e4 --- /dev/null +++ b/src/PartSet/PartSet_FeaturePrs.cpp @@ -0,0 +1,224 @@ +// File: PartSet_FeaturePrs.h +// Created: 04 Jun 2014 +// Author: Natalia ERMOLAEVA + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +using namespace std; + +PartSet_FeaturePrs::PartSet_FeaturePrs(FeaturePtr theFeature) +: mySketch(theFeature) +{ +} + +PartSet_FeaturePrs::~PartSet_FeaturePrs() +{ +} + +void PartSet_FeaturePrs::init(FeaturePtr theFeature, FeaturePtr theSourceFeature) +{ + myFeature = theFeature; + if (theSourceFeature) + { + // use the last point of the previous feature as the first of the new one + boost::shared_ptr aData = theSourceFeature->data(); + boost::shared_ptr anInitPoint = boost::dynamic_pointer_cast + (aData->attribute(LINE_ATTR_END)); + setLinePoint(theFeature, anInitPoint->x(), anInitPoint->y(), LINE_ATTR_START); + setLinePoint(theFeature, anInitPoint->x(), anInitPoint->y(), LINE_ATTR_END); + + aData = theFeature->data(); + boost::shared_ptr aPoint = boost::dynamic_pointer_cast + (aData->attribute(LINE_ATTR_START)); + createConstraint(anInitPoint, aPoint); + } +} + +boost::shared_ptr PartSet_FeaturePrs::document() const +{ + return ModelAPI_PluginManager::get()->rootDocument(); +} + +FeaturePtr PartSet_FeaturePrs::sketch() const +{ + return mySketch; +} + +PartSet_SelectionMode PartSet_FeaturePrs::setPoint(double theX, double theY, + const PartSet_SelectionMode& theMode) +{ + PartSet_SelectionMode aMode = theMode; + switch (theMode) + { + case SM_FirstPoint: { + setLinePoint(feature(), theX, theY, LINE_ATTR_START); + setLinePoint(feature(), theX, theY, LINE_ATTR_END); + aMode = SM_SecondPoint; + } + break; + case SM_SecondPoint: { + setLinePoint(feature(), theX, theY, LINE_ATTR_END); + aMode = SM_DonePoint; + } + break; + default: + break; + } + return aMode; +} + +FeaturePtr PartSet_FeaturePrs::feature() const +{ + return myFeature; +} + +void PartSet_FeaturePrs::createConstraint(boost::shared_ptr thePoint1, + boost::shared_ptr thePoint2) +{ + boost::shared_ptr aDoc = document(); + FeaturePtr aFeature = aDoc->addFeature(SKETCH_CONSTRAINT_COINCIDENCE_KIND); + + if (sketch()) { + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(sketch()); + aSketch->addSub(aFeature); + } + + boost::shared_ptr aData = aFeature->data(); + + boost::shared_ptr aRef1 = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_A)); + aRef1->setAttr(thePoint1); + + boost::shared_ptr aRef2 = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_B)); + aRef2->setAttr(thePoint2); + + if (aFeature) // TODO: generate an error if feature was not created + aFeature->execute(); +} + +void PartSet_FeaturePrs::setConstraints(double theX, double theY, + const PartSet_SelectionMode& theMode) +{ + std::string aPointArg; + switch (theMode) + { + case SM_FirstPoint: + aPointArg = LINE_ATTR_START; + break; + case SM_SecondPoint: + aPointArg = LINE_ATTR_END; + break; + default: + break; + } + + FeaturePtr aSkFeature = feature(); + + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aPoint = boost::dynamic_pointer_cast + (aData->attribute(aPointArg)); + aData = sketch()->data(); + boost::shared_ptr aRefList = + boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_FEATURES)); + + std::list aFeatures = aRefList->list(); + std::list::const_iterator anIt = aFeatures.begin(), + aLast = aFeatures.end(); + for (; anIt != aLast; anIt++) { + FeaturePtr aFeature = *anIt; + boost::shared_ptr aFPoint = findLinePoint(aFeature, theX, theY); + if (aFPoint) + createConstraint(aFPoint, aPoint); + } +} + +std::string PartSet_FeaturePrs::getAttribute(const PartSet_SelectionMode& theMode) const +{ + std::string aAttribute; + switch (theMode) + { + case SM_FirstPoint: + aAttribute = LINE_ATTR_START; + break; + case SM_SecondPoint: + aAttribute = LINE_ATTR_END; + break; + default: + break; + } + return aAttribute; +} + +PartSet_SelectionMode PartSet_FeaturePrs::getNextMode(const std::string& theAttribute) const +{ + PartSet_SelectionMode aMode; + + if (theAttribute == LINE_ATTR_START) + aMode = SM_SecondPoint; + else if (theAttribute == LINE_ATTR_END) + aMode = SM_DonePoint; + return aMode; +} + +void PartSet_FeaturePrs::getLinePoint(FeaturePtr theFeature, + const std::string& theAttribute, + double& theX, double& theY) +{ + if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) + return; + boost::shared_ptr aData = theFeature->data(); + boost::shared_ptr aPoint = + boost::dynamic_pointer_cast(aData->attribute(theAttribute)); + theX = aPoint->x(); + theY = aPoint->y(); +} + +boost::shared_ptr PartSet_FeaturePrs::findLinePoint( + FeaturePtr theFeature, + double theX, double theY) +{ + boost::shared_ptr aPoint2D; + if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) + return aPoint2D; + boost::shared_ptr aData = theFeature->data(); + + boost::shared_ptr aPoint = + boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_START)); + if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() ) + aPoint2D = aPoint; + else { + aPoint = boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_END)); + if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() ) + aPoint2D = aPoint; + } + return aPoint2D; +} + +void PartSet_FeaturePrs::setLinePoint(FeaturePtr theFeature, + double theX, double theY, + const std::string& theAttribute) +{ + if (!theFeature) + return; + boost::shared_ptr aData = theFeature->data(); + boost::shared_ptr aPoint = + boost::dynamic_pointer_cast(aData->attribute(theAttribute)); + aPoint->setValue(theX, theY); +} diff --git a/src/PartSet/PartSet_FeaturePrs.h b/src/PartSet/PartSet_FeaturePrs.h new file mode 100644 index 000000000..0a285f522 --- /dev/null +++ b/src/PartSet/PartSet_FeaturePrs.h @@ -0,0 +1,102 @@ +// File: PartSet_FeaturePrs.h +// Created: 04 Jun 2014 +// Author: Natalia ERMOLAEVA + +#ifndef PartSet_FeaturePrs_H +#define PartSet_FeaturePrs_H + +#include "PartSet.h" + +#include "PartSet_Constants.h" + +class GeomDataAPI_Point2D; + +/*! + \class PartSet_FeaturePrs + * \brief The abstract class to define the specific 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_FeaturePrs +{ +public: + /// Constructor + /// \param theSketch the sketch feature + PartSet_FeaturePrs(FeaturePtr theSketch); + /// Destructor + virtual ~PartSet_FeaturePrs(); + + /// Initializes some fields of feature accorging to the source feature + /// Saves the fiature as the presentation internal feature + /// \param theFeature the presentation feature + /// \param theSourceFeature the feature, which attributes are used to initialize the feature + virtual void init(FeaturePtr theFeature, FeaturePtr theSourceFeature); + + /// Returns the operation sketch feature + /// \returns the sketch instance + FeaturePtr sketch() const; + + /// 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 + PartSet_SelectionMode setPoint(double theX, double theY, const PartSet_SelectionMode& theMode); + + /// Creates constrains of the current + /// \param theX the horizontal coordnate of the point + /// \param theY the vertical coordnate of the point + /// \param theMode the current operation selection mode. The feature attribute depends on the mode + void setConstraints(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 + 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 + PartSet_SelectionMode getNextMode(const std::string& theAttribute) const; + + /// \brief Save the point to the line. + /// \param theFeature the line feature + /// \param theX the horizontal coordinate + /// \param theY the vertical coordinate + /// \param theAttribute the start or end attribute of the line + static void setLinePoint(FeaturePtr, double theX, double theY, + const std::string& theAttribute); + +protected: + /// Returns pointer to the root document. + boost::shared_ptr document() const; + + /// Returns the operation feature + /// \return the feature + FeaturePtr feature() const; + + /// Creates a constraint on two points + /// \param thePoint1 the first point + /// \param thePoint1 the second point + void createConstraint(boost::shared_ptr thePoint1, + boost::shared_ptr thePoint2); + + /// \brief Get the line point 2d coordinates. + /// \param theFeature the line feature + /// \param theAttribute the start or end attribute of the line + /// \param theX the horizontal coordinate + /// \param theY the vertical coordinate + void getLinePoint(FeaturePtr theFeature, const std::string& theAttribute, + 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 + boost::shared_ptr findLinePoint(FeaturePtr theFeature, + double theX, double theY); + +private: + FeaturePtr mySketch; ///< the sketch of the feature + FeaturePtr myFeature; ///< the feature +}; + +#endif diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 3de97e8b3..5e223e459 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -309,7 +309,7 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI // get operation xml description std::string aStdCmdId = theCmdId; if (aStdCmdId == PartSet_OperationEditLine::Type()) - aStdCmdId = PartSet_OperationSketchLine::Type(); + aStdCmdId = SKETCH_LINE_KIND; std::string aPluginFileName = featureFile(aStdCmdId); Config_WidgetReader aWdgReader = Config_WidgetReader(aPluginFileName); aWdgReader.readAll(); @@ -327,8 +327,8 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI PartSet_OperationSketchBase* aPrevOp = dynamic_cast(aCurOperation); if (aPrevOp) aSketch = aPrevOp->sketch(); - if (theCmdId == PartSet_OperationSketchLine::Type()) - anOperation = new PartSet_OperationSketchLine(theCmdId.c_str(), this, aSketch); + if (theCmdId == SKETCH_LINE_KIND) + anOperation = new PartSet_OperationCreateFeature(theCmdId.c_str(), this, aSketch); else if (theCmdId == PartSet_OperationEditLine::Type()) anOperation = new PartSet_OperationEditLine(theCmdId.c_str(), this, aSketch); else if (theCmdId == PartSet_OperationConstraint::Type()) diff --git a/src/PartSet/PartSet_OperationCreateFeature.cpp b/src/PartSet/PartSet_OperationCreateFeature.cpp new file mode 100644 index 000000000..1d9044592 --- /dev/null +++ b/src/PartSet/PartSet_OperationCreateFeature.cpp @@ -0,0 +1,276 @@ +// File: PartSet_OperationCreateFeature.h +// Created: 20 Apr 2014 +// Author: Natalia ERMOLAEVA + +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#ifdef _DEBUG +#include +#endif + +#include + +using namespace std; + +PartSet_OperationCreateFeature::PartSet_OperationCreateFeature(const QString& theId, + QObject* theParent, + FeaturePtr theFeature) +: PartSet_OperationSketchBase(theId, theParent), + myPointSelectionMode(SM_FirstPoint) +{ + myFeaturePrs = new PartSet_FeaturePrs(theFeature); +} + +PartSet_OperationCreateFeature::~PartSet_OperationCreateFeature() +{ + delete myFeaturePrs; +} + +bool PartSet_OperationCreateFeature::canBeCommitted() const +{ + return myPointSelectionMode == SM_DonePoint; +} + +bool PartSet_OperationCreateFeature::isGranted(ModuleBase_IOperation* theOperation) const +{ + return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type(); +} + +std::list PartSet_OperationCreateFeature::getSelectionModes(FeaturePtr theFeature) const +{ + std::list aModes; + if (theFeature != feature()) + aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature); + return aModes; +} + +void PartSet_OperationCreateFeature::init(FeaturePtr theFeature, + const std::list& /*theSelected*/, + const std::list& /*theHighlighted*/) +{ + if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) + return; + myInitFeature = theFeature; +} + +FeaturePtr PartSet_OperationCreateFeature::sketch() const +{ + return myFeaturePrs->sketch(); +} + +void PartSet_OperationCreateFeature::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView, + 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(feature()->getKind(), 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(); + 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; + + myFeaturePrs->setConstraints(aX, anY, myPointSelectionMode); + } + } + /*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; + getLinePoint(aFeature, LINE_ATTR_START, X2, Y2); + 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: { + 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: + case SM_SecondPoint: { + PartSet_SelectionMode aMode = myFeaturePrs->setPoint(aX, anY, myPointSelectionMode); + flushUpdated(); + setPointSelectionMode(aMode); + } + break; + default: + break; + } +} + +void PartSet_OperationCreateFeature::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView) +{ + switch (myPointSelectionMode) + { + case SM_FirstPoint: + case SM_SecondPoint: + { + double aX, anY; + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); + PartSet_Tools::convertTo2D(aPoint, sketch(), 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_OperationCreateFeature::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_OperationCreateFeature::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_OperationCreateFeature::startOperation() +{ + PartSet_OperationSketchBase::startOperation(); + setPointSelectionMode(!myInitFeature ? SM_FirstPoint : SM_SecondPoint); + + emit multiSelectionEnabled(false); +} + +void PartSet_OperationCreateFeature::abortOperation() +{ + emit featureConstructed(feature(), FM_Hide); + PartSet_OperationSketchBase::abortOperation(); +} + +void PartSet_OperationCreateFeature::stopOperation() +{ + PartSet_OperationSketchBase::stopOperation(); + emit multiSelectionEnabled(true); +} + +void PartSet_OperationCreateFeature::afterCommitOperation() +{ + PartSet_OperationSketchBase::afterCommitOperation(); + emit featureConstructed(feature(), FM_Deactivation); +} + +FeaturePtr PartSet_OperationCreateFeature::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_OperationCreateFeature::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_OperationSketchLine.h b/src/PartSet/PartSet_OperationCreateFeature.h similarity index 58% rename from src/PartSet/PartSet_OperationSketchLine.h rename to src/PartSet/PartSet_OperationCreateFeature.h index 153bfbb66..e53bf9b84 100644 --- a/src/PartSet/PartSet_OperationSketchLine.h +++ b/src/PartSet/PartSet_OperationCreateFeature.h @@ -1,43 +1,43 @@ -// File: PartSet_OperationSketchLine.h +// File: PartSet_OperationCreateFeature.h // Created: 20 Apr 2014 // Author: Natalia ERMOLAEVA -#ifndef PartSet_OperationSketchLine_H -#define PartSet_OperationSketchLine_H +#ifndef PartSet_OperationCreateFeature_H +#define PartSet_OperationCreateFeature_H #include "PartSet.h" #include +#include #include #include +class PartSet_FeaturePrs; class GeomDataAPI_Point2D; class QMouseEvent; class QKeyEvent; /*! - \class PartSet_OperationSketchLine + \class PartSet_OperationCreateFeature * \brief The operation for the sketch feature creation */ -class PARTSET_EXPORT PartSet_OperationSketchLine : public PartSet_OperationSketchBase +class PARTSET_EXPORT PartSet_OperationCreateFeature : public PartSet_OperationSketchBase { Q_OBJECT public: - /// Returns the operation type key - static std::string Type() { return SKETCH_LINE_KIND; } public: /// Constructor /// \param theId the feature identifier /// \param theParent the operation parent - /// \param theFeature the parent feature - PartSet_OperationSketchLine(const QString& theId, QObject* theParent, - FeaturePtr theSketchFeature); + /// \param theSketch the parent feature + PartSet_OperationCreateFeature(const QString& theId, QObject* theParent, + FeaturePtr theSketch); /// Destructor - virtual ~PartSet_OperationSketchLine(); + virtual ~PartSet_OperationCreateFeature(); /// Verifies whether this operator can be commited. /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled @@ -82,14 +82,6 @@ public: virtual void keyReleased(std::string theName, QKeyEvent* theEvent); - /// \brief Save the point to the line. - /// \param theFeature the line feature - /// \param theX the horizontal coordinate - /// \param theY the vertical coordinate - /// \param theAttribute the start or end attribute of the line - static void setLinePoint(FeaturePtr, double theX, double theY, - const std::string& theAttribute); - protected: /// \brief Virtual method called when operation is started /// Virtual method called when operation started (see start() method for more description) @@ -114,50 +106,17 @@ protected: /// \returns the created feature virtual FeaturePtr createFeature(const bool theFlushMessage = true); - /// Creates a constraint on two points - /// \param thePoint1 the first point - /// \param thePoint1 the second point - void createConstraint(boost::shared_ptr thePoint1, - boost::shared_ptr thePoint2); - - /// Creates constrains of the current - /// \param theX the horizontal coordnate of the point - /// \param theY the vertical coordnate of the point - void setConstraints(double theX, double theY); - protected: - /// \brief Get the line point 2d coordinates. - /// \param theFeature the line feature - /// \param theAttribute the start or end attribute of the line - /// \param theX the horizontal coordinate - /// \param theY the vertical coordinate - void getLinePoint(FeaturePtr theFeature, const std::string& theAttribute, - 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 - boost::shared_ptr findLinePoint(FeaturePtr theFeature, - double theX, double theY); - - /// \brief Save the point to the line. - /// \param thePoint the 3D point in the viewer - /// \param theAttribute the start or end attribute of the line - void setLinePoint(const gp_Pnt& thePoint, Handle(V3d_View) theView, const std::string& theAttribute); - -protected: - ///< Structure to lists the possible types of point selection modes - enum PointSelectionMode {SM_FirstPoint, SM_SecondPoint, SM_DonePoint}; - ///< 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 PointSelectionMode& theMode, const bool isToEmitSignal = true); + void setPointSelectionMode(const PartSet_SelectionMode& theMode, + const bool isToEmitSignal = true); private: - FeaturePtr mySketch; ///< the sketch feature - boost::shared_ptr myInitPoint; ///< the first line point - PointSelectionMode myPointSelectionMode; ///< point selection mode + PartSet_FeaturePrs* myFeaturePrs; ///< the feature presentation + FeaturePtr myInitFeature; ///< the initial feature + PartSet_SelectionMode myPointSelectionMode; ///< point selection mode }; #endif diff --git a/src/PartSet/PartSet_OperationSketchLine.cpp b/src/PartSet/PartSet_OperationSketchLine.cpp deleted file mode 100644 index bd24b954a..000000000 --- a/src/PartSet/PartSet_OperationSketchLine.cpp +++ /dev/null @@ -1,443 +0,0 @@ -// File: PartSet_OperationSketchLine.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 -#include -#include - -#ifdef _DEBUG -#include -#endif - -#include - -using namespace std; - -PartSet_OperationSketchLine::PartSet_OperationSketchLine(const QString& theId, - QObject* theParent, - FeaturePtr theFeature) -: PartSet_OperationSketchBase(theId, theParent), mySketch(theFeature), - myPointSelectionMode(SM_FirstPoint) -{ -} - -PartSet_OperationSketchLine::~PartSet_OperationSketchLine() -{ -} - -bool PartSet_OperationSketchLine::canBeCommitted() const -{ - return myPointSelectionMode == SM_DonePoint; -} - -bool PartSet_OperationSketchLine::isGranted(ModuleBase_IOperation* theOperation) const -{ - return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type(); -} - -std::list PartSet_OperationSketchLine::getSelectionModes(FeaturePtr theFeature) const -{ - std::list aModes; - if (theFeature != feature()) - aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature); - return aModes; -} - -void PartSet_OperationSketchLine::init(FeaturePtr theFeature, - const std::list& /*theSelected*/, - const std::list& /*theHighlighted*/) -{ - if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) - return; - // use the last point of the previous feature as the first of the new one - boost::shared_ptr aData = theFeature->data(); - myInitPoint = boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_END)); -} - -FeaturePtr PartSet_OperationSketchLine::sketch() const -{ - return mySketch; -} - -void PartSet_OperationSketchLine::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView, - 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_OperationSketchLine::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(); - 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; - getLinePoint(aFeature, LINE_ATTR_START, X2, Y2); - 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: { - 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_OperationSketchLine::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_OperationSketchLine::Type(), feature()); - } - default: - break; - } -} - -void PartSet_OperationSketchLine::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*/) { - if (theName == LINE_ATTR_START) { - setPointSelectionMode(SM_SecondPoint, false); - } - else if (theName == LINE_ATTR_END) { - setPointSelectionMode(SM_DonePoint, false); - } - } - keyReleased(theEvent->key()); -} - -void PartSet_OperationSketchLine::keyReleased(const int theKey) -{ - switch (theKey) { - case Qt::Key_Return: { - if (myPointSelectionMode == SM_DonePoint) - { - commit(); - restartOperation(PartSet_OperationSketchLine::Type(), feature()); - } - //else - // abort(); - //emit launchOperation(PartSet_OperationSketchLine::Type(), FeaturePtr()); - } - break; - case Qt::Key_Escape: { - if (myPointSelectionMode == SM_DonePoint) - { - commit(); - } - else - abort(); - } - default: - break; - } -} - -void PartSet_OperationSketchLine::startOperation() -{ - PartSet_OperationSketchBase::startOperation(); - setPointSelectionMode(!myInitPoint ? SM_FirstPoint : SM_SecondPoint); - - emit multiSelectionEnabled(false); -} - -void PartSet_OperationSketchLine::abortOperation() -{ - emit featureConstructed(feature(), FM_Hide); - PartSet_OperationSketchBase::abortOperation(); -} - -void PartSet_OperationSketchLine::stopOperation() -{ - PartSet_OperationSketchBase::stopOperation(); - emit multiSelectionEnabled(true); -} - -void PartSet_OperationSketchLine::afterCommitOperation() -{ - PartSet_OperationSketchBase::afterCommitOperation(); - emit featureConstructed(feature(), FM_Deactivation); -} - -FeaturePtr PartSet_OperationSketchLine::createFeature(const bool theFlushMessage) -{ - FeaturePtr aNewFeature = ModuleBase_Operation::createFeature(false); - if (sketch()) { - boost::shared_ptr aFeature = - boost::dynamic_pointer_cast(sketch()); - - aFeature->addSub(aNewFeature); - } - if (myInitPoint) { - setLinePoint(aNewFeature, myInitPoint->x(), myInitPoint->y(), LINE_ATTR_START); - setLinePoint(aNewFeature, myInitPoint->x(), myInitPoint->y(), LINE_ATTR_END); - - boost::shared_ptr aData = aNewFeature->data(); - boost::shared_ptr aPoint = boost::dynamic_pointer_cast - (aData->attribute(LINE_ATTR_START)); - createConstraint(myInitPoint, aPoint); - } - - emit featureConstructed(aNewFeature, FM_Activation); - if (theFlushMessage) - flushCreated(); - return aNewFeature; -} - -void PartSet_OperationSketchLine::createConstraint(boost::shared_ptr thePoint1, - boost::shared_ptr thePoint2) -{ - boost::shared_ptr aDoc = document(); - FeaturePtr aFeature = aDoc->addFeature(SKETCH_CONSTRAINT_COINCIDENCE_KIND); - - if (sketch()) { - boost::shared_ptr aSketch = - boost::dynamic_pointer_cast(sketch()); - aSketch->addSub(aFeature); - } - - boost::shared_ptr aData = aFeature->data(); - - boost::shared_ptr aRef1 = - boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_A)); - aRef1->setAttr(thePoint1); - - boost::shared_ptr aRef2 = - boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_B)); - aRef2->setAttr(thePoint2); - - if (aFeature) // TODO: generate an error if feature was not created - aFeature->execute(); -} - -void PartSet_OperationSketchLine::setConstraints(double theX, double theY) -{ - std::string aPointArg; - switch (myPointSelectionMode) - { - case SM_FirstPoint: - aPointArg = LINE_ATTR_START; - break; - case SM_SecondPoint: - aPointArg = LINE_ATTR_END; - break; - default: - break; - } - - FeaturePtr aSkFeature = feature(); - - boost::shared_ptr aData = feature()->data(); - boost::shared_ptr aPoint = boost::dynamic_pointer_cast - (aData->attribute(aPointArg)); - aData = sketch()->data(); - boost::shared_ptr aRefList = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_FEATURES)); - - std::list aFeatures = aRefList->list(); - std::list::const_iterator anIt = aFeatures.begin(), - aLast = aFeatures.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = *anIt; - boost::shared_ptr aFPoint = findLinePoint(aFeature, theX, theY); - if (aFPoint) - createConstraint(aFPoint, aPoint); - } -} - -void PartSet_OperationSketchLine::getLinePoint(FeaturePtr theFeature, - const std::string& theAttribute, - double& theX, double& theY) -{ - if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) - return; - boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr aPoint = - boost::dynamic_pointer_cast(aData->attribute(theAttribute)); - theX = aPoint->x(); - theY = aPoint->y(); -} - -boost::shared_ptr PartSet_OperationSketchLine::findLinePoint( - FeaturePtr theFeature, - double theX, double theY) -{ - boost::shared_ptr aPoint2D; - if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) - return aPoint2D; - boost::shared_ptr aData = theFeature->data(); - - boost::shared_ptr aPoint = - boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_START)); - if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() ) - aPoint2D = aPoint; - else { - aPoint = boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_END)); - if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() ) - aPoint2D = aPoint; - } - return aPoint2D; -} - -void PartSet_OperationSketchLine::setLinePoint(FeaturePtr theFeature, - double theX, double theY, - const std::string& theAttribute) -{ - if (!theFeature) - return; - boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr aPoint = - boost::dynamic_pointer_cast(aData->attribute(theAttribute)); - aPoint->setValue(theX, theY); -} - -void PartSet_OperationSketchLine::setLinePoint(const gp_Pnt& thePoint, - Handle(V3d_View) theView, - const std::string& theAttribute) -{ - double aX, anY; - PartSet_Tools::convertTo2D(thePoint, sketch(), theView, aX, anY); - boost::shared_ptr aData = feature()->data(); - boost::shared_ptr aPoint = - boost::dynamic_pointer_cast(aData->attribute(theAttribute)); - aPoint->setValue(aX, anY); -} - -void PartSet_OperationSketchLine::setPointSelectionMode(const PointSelectionMode& theMode, - const bool isToEmitSignal) -{ - myPointSelectionMode = theMode; - if (isToEmitSignal) { - std::string aName; - switch (theMode) { - case SM_FirstPoint: - aName = LINE_ATTR_START; - break; - case SM_SecondPoint: - aName = LINE_ATTR_END; - break; - case SM_DonePoint: - aName = XGUI::PROP_PANEL_OK; - break; - default: - break; - } - emit focusActivated(aName); - } -} diff --git a/src/PartSet/PartSet_TestOCC.cpp b/src/PartSet/PartSet_TestOCC.cpp index dc0295020..ef0ea9a75 100644 --- a/src/PartSet/PartSet_TestOCC.cpp +++ b/src/PartSet/PartSet_TestOCC.cpp @@ -9,8 +9,9 @@ #include #include #include -#include +#include #include +#include #include @@ -132,8 +133,7 @@ void PartSet_TestOCC::createTestLine(XGUI_Workshop* theWorkshop) if (aPreviewOp) { // create a line boost::shared_ptr aDoc = ModelAPI_PluginManager::get()->rootDocument(); - FeaturePtr aFeature = aDoc->addFeature( - PartSet_OperationSketchLine::Type().c_str()); + FeaturePtr aFeature = aDoc->addFeature(SKETCH_LINE_KIND); if (aFeature) // TODO: generate an error if feature was not created aFeature->execute(); @@ -141,10 +141,10 @@ void PartSet_TestOCC::createTestLine(XGUI_Workshop* theWorkshop) boost::dynamic_pointer_cast(aPreviewOp->sketch()); aSketch->addSub(aFeature); - PartSet_OperationSketchLine::setLinePoint(aFeature, 100, 100, LINE_ATTR_START); - PartSet_OperationSketchLine::setLinePoint(aFeature, 150, 300, LINE_ATTR_END); + PartSet_FeaturePrs::setLinePoint(aFeature, 100, 100, LINE_ATTR_START); + PartSet_FeaturePrs::setLinePoint(aFeature, 150, 300, LINE_ATTR_END); - boost::shared_ptr aPreview = PartSet_OperationSketchLine::preview(aFeature); + boost::shared_ptr aPreview = PartSet_OperationSketchBase::preview(aFeature); XGUI_Displayer* aDisplayer = theWorkshop->displayer(); @@ -163,10 +163,10 @@ void PartSet_TestOCC::createTestLine(XGUI_Workshop* theWorkshop) /*double aDelta = -200; for (int i = 0; i < 20; i++) { aDelta = aDelta - i*2; - PartSet_OperationSketchLine::setLinePoint(aFeature, 100+aDelta, 200+aDelta, LINE_ATTR_START); - PartSet_OperationSketchLine::setLinePoint(aFeature, 300+aDelta, 500+aDelta, LINE_ATTR_END); + PartSet_FeaturePrs::setLinePoint(aFeature, 100+aDelta, 200+aDelta, LINE_ATTR_START); + PartSet_FeaturePrs::setLinePoint(aFeature, 300+aDelta, 500+aDelta, LINE_ATTR_END); - boost::shared_ptr aPreview = PartSet_OperationSketchLine::preview(aFeature); + boost::shared_ptr aPreview = PartSet_OperationSketchBase::preview(aFeature); Handle(AIS_InteractiveObject) anAIS = PartSet_Presentation::createPresentation( aFeature, aSketch, aPreview ? aPreview->impl() : TopoDS_Shape(), NULL); @@ -199,9 +199,9 @@ void PartSet_TestOCC::changeTestLine(XGUI_Workshop* theWorkshop) myTestDelta = myTestDelta - 50; double aDelta = myTestDelta; - PartSet_OperationSketchLine::setLinePoint(aFeature, -100/*aDelta*/, -100/*aDelta*/, LINE_ATTR_START); - PartSet_OperationSketchLine::setLinePoint(aFeature, 200/*aDelta*2*/, 200/*aDelta*2*/, LINE_ATTR_END); - boost::shared_ptr aPreview = PartSet_OperationSketchLine::preview(aFeature); + PartSet_FeaturePrs::setLinePoint(aFeature, -100/*aDelta*/, -100/*aDelta*/, LINE_ATTR_START); + PartSet_FeaturePrs::setLinePoint(aFeature, 200/*aDelta*2*/, 200/*aDelta*2*/, LINE_ATTR_END); + boost::shared_ptr aPreview = PartSet_OperationSketchBase::preview(aFeature); Handle(AIS_InteractiveObject) aPrevAIS; FeaturePtr aSketch;//NULL -- 2.39.2