From 2e9a155145c3b05fa1f592edde88489c8521d029 Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 29 Oct 2014 17:43:41 +0300 Subject: [PATCH] refs #156: Behavior of the Sketch during edition Edit Multi operation is correct to modify the feature attribute only. --- src/ModuleBase/ModuleBase_IModule.cpp | 2 +- src/ModuleBase/ModuleBase_Operation.cpp | 3 +- src/ModuleBase/ModuleBase_Operation.h | 5 +- src/PartSet/PartSet_Module.cpp | 2 +- .../PartSet_OperationFeatureEditMulti.cpp | 148 ++++++++++++------ .../PartSet_OperationFeatureEditMulti.h | 11 +- src/PartSet/PartSet_Tools.cpp | 26 +-- src/PartSet/PartSet_Tools.h | 8 +- 8 files changed, 138 insertions(+), 67 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IModule.cpp b/src/ModuleBase/ModuleBase_IModule.cpp index df2502fbb..36e09437e 100644 --- a/src/ModuleBase/ModuleBase_IModule.cpp +++ b/src/ModuleBase/ModuleBase_IModule.cpp @@ -34,7 +34,7 @@ void ModuleBase_IModule::launchOperation(const QString& theCmdId) ModuleBase_Operation* anOperation = createOperation(theCmdId.toStdString()); ModuleBase_ISelection* aSelection = myWorkshop->selection(); // Initialise operation with preliminary selection - anOperation->initSelection(aSelection); + anOperation->initSelection(aSelection, myWorkshop->viewer()); sendOperation(anOperation); } diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index 896da097e..cd728aa7a 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -279,7 +279,8 @@ bool ModuleBase_Operation::activateByPreselection() return false; } -void ModuleBase_Operation::initSelection(ModuleBase_ISelection* theSelection) +void ModuleBase_Operation::initSelection(ModuleBase_ISelection* theSelection, + ModuleBase_IViewer* /*theViewer*/) { myPreSelection.clear(); diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 9d1a1c04a..07b413218 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -22,6 +22,7 @@ class ModuleBase_ModelWidget; class ModuleBase_OperationDescription; class ModuleBase_IPropertyPanel; class ModuleBase_ISelection; +class ModuleBase_IViewer; class QKeyEvent; @@ -117,7 +118,9 @@ Q_OBJECT /// Initialisation of operation with preliminary selection /// \param theSelected the list of selected presentations /// \param theHighlighted the list of highlighted presentations - virtual void initSelection(ModuleBase_ISelection* theSelection); + /// \param theViewer a viewer to have the viewer the eye position + virtual void initSelection(ModuleBase_ISelection* theSelection, + ModuleBase_IViewer* /* theViewer*/); virtual void setPropertyPanel(ModuleBase_IPropertyPanel* theProp); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index f38381ef8..035444ba9 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -311,7 +311,7 @@ void PartSet_Module::onRestartOperation(std::string theName, ObjectPtr theObject } ModuleBase_ISelection* aSelection = workshop()->selection(); // Initialise operation with preliminary selection - aSketchOp->initSelection(aSelection); + aSketchOp->initSelection(aSelection, myWorkshop->viewer()); } //else if (aFeature) { //anOperation->setFeature(aFeature); ////Deactivate result of current feature in order to avoid its selection diff --git a/src/PartSet/PartSet_OperationFeatureEditMulti.cpp b/src/PartSet/PartSet_OperationFeatureEditMulti.cpp index 4b10858a0..c513216ba 100644 --- a/src/PartSet/PartSet_OperationFeatureEditMulti.cpp +++ b/src/PartSet/PartSet_OperationFeatureEditMulti.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include +#include #include #ifdef _DEBUG @@ -58,37 +61,75 @@ bool isContains(const QList& theSelected, const ModuleBase } -void PartSet_OperationFeatureEditMulti::initSelection(ModuleBase_ISelection* theSelection) +void PartSet_OperationFeatureEditMulti::initSelection(ModuleBase_ISelection* theSelection, + ModuleBase_IViewer* theViewer) { - //if (!theHighlighted.empty()) { - // // if there is highlighted object, we check whether it is in the list of selected objects - // // in that case this object is a handle of the moved lines. If there no such object in the selection, - // // the hightlighted object should moved and the selection is skipped. The skipped selection will be - // // deselected in the viewer by blockSelection signal in the startOperation method. - // bool isSelected = false; - // std::list::const_iterator anIt = theSelected.begin(), - // aLast = theSelected.end(); - // for (; anIt != aLast && !isSelected; anIt++) { - // isSelected = ModelAPI_Feature::feature((*anIt).object()) == feature(); - // } - // if (!isSelected) - // myFeatures = theHighlighted; - // else - // myFeatures = theSelected; - //} else - myFeatures = theSelection->getSelected(); + QList aFeatures; + aFeatures = theSelection->getSelected(); QList aHighlighted = theSelection->getHighlighted(); // add highlighted elements if they are not selected foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) { - if (!isContains(myFeatures, aPrs)) - myFeatures.append(aPrs); + if (!isContains(aFeatures, aPrs)) + aFeatures.append(aPrs); } - // Remove current feature if it is in the list (it will be moved as main feature) - foreach (ModuleBase_ViewerPrs aPrs, myFeatures) { - FeaturePtr aF = ModelAPI_Feature::feature(aPrs.object()); - if (ModelAPI_Feature::feature(aPrs.object()) == feature()) { - myFeatures.removeOne(aPrs); - break; + + // firstly iterate the operation presentations and move all features + // if there is no selected vertex shape for it. Create a set of moved features + myFeature2Attribute.clear(); + // firstly, collect the features without local selection + std::set aMovedFeatures; + foreach (ModuleBase_ViewerPrs aPrs, aFeatures) { + const TopoDS_Shape& aShape = aPrs.shape(); + if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected + const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape); + if (!aVertex.IsNull()) { + continue; + } + } + else { + ObjectPtr aObject = aPrs.object(); + if (!aObject) + continue; + FeaturePtr aFeature = ModelAPI_Feature::feature(aObject); + if (aFeature && myFeature2Attribute.find(aFeature) == myFeature2Attribute.end()) { + std::list aList; + myFeature2Attribute[aFeature] = aList; + } + } + } + // secondly, collect the features with a local selection on them + // if the list already has this feature, the local selection is skipped + Handle(V3d_View) aView = theViewer->activeView(); + foreach (ModuleBase_ViewerPrs aPrs, aFeatures) { + const TopoDS_Shape& aShape = aPrs.shape(); + if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected + const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape); + if (aVertex.IsNull()) + continue; + ObjectPtr aObject = aPrs.object(); + if (!aObject) + continue; + FeaturePtr aFeature = ModelAPI_Feature::feature(aObject); + if (!aFeature) + continue; + // if the feature is already moved, do nothing for this feature local selection + + if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end()) + continue; + + gp_Pnt aPoint = BRep_Tool::Pnt(aVertex); + double aVX, aVY; + PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aVX, aVY); + + boost::shared_ptr aPoint2D = PartSet_Tools::getFeaturePoint( + aFeature, aVX, aVY); + std::string anAttribute = aFeature->data()->id(aPoint2D); + std::list aList; + if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end()) + aList = myFeature2Attribute[aFeature]; + + aList.push_back(anAttribute); + myFeature2Attribute[aFeature] = aList; } } } @@ -124,20 +165,29 @@ void PartSet_OperationFeatureEditMulti::mouseMoved(QMouseEvent* theEvent, Module double aDeltaX = aX - aCurX; double aDeltaY = anY - aCurY; - boost::shared_ptr aSketchFeature = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(feature()); - aSketchFeature->move(aDeltaX, aDeltaY); - - foreach (ModuleBase_ViewerPrs aPrs, myFeatures) { - ObjectPtr aObject = aPrs.object(); - if (!aObject || aObject == feature()) - continue; - FeaturePtr aFeature = ModelAPI_Feature::feature(aObject); - if (aFeature) { - aSketchFeature = boost::dynamic_pointer_cast(aFeature); - if (aSketchFeature) + std::map>::iterator aFeatIter = myFeature2Attribute.begin(); + while (aFeatIter != myFeature2Attribute.end()) { + FeaturePtr aFeature = aFeatIter->first; + std::list anAttributes = aFeatIter->second; + if (anAttributes.empty()) { + boost::shared_ptr aSketchFeature = + boost::dynamic_pointer_cast(aFeature); + if (aSketchFeature) { aSketchFeature->move(aDeltaX, aDeltaY); + } + } + else { + std::list::const_iterator anAttrIter = anAttributes.begin(), + anAttrEnd = anAttributes.end(); + for (; anAttrIter != anAttrEnd; anAttrIter++) { + boost::shared_ptr aPointAttr = boost::dynamic_pointer_cast< + GeomDataAPI_Point2D>(aFeature->data()->attribute(*anAttrIter)); + if (aPointAttr) { + aPointAttr->move(aDeltaX, aDeltaY); + } + } } + aFeatIter++; } } sendFeatures(); @@ -151,11 +201,13 @@ void PartSet_OperationFeatureEditMulti::mouseReleased( { theViewer->enableSelection(true); if (commit()) { - foreach (ModuleBase_ViewerPrs aPrs, myFeatures) { - ObjectPtr aFeature = aPrs.object(); + std::map>::iterator aFeatIter = myFeature2Attribute.begin(); + while (aFeatIter != myFeature2Attribute.end()) { + FeaturePtr aFeature = aFeatIter->first; if (aFeature) { emit featureConstructed(aFeature, FM_Deactivation); } + aFeatIter++; } } } @@ -176,7 +228,7 @@ void PartSet_OperationFeatureEditMulti::stopOperation() //blockSelection(false, true); - myFeatures.clear(); + myFeature2Attribute.clear(); } //void PartSet_OperationFeatureEditMulti::blockSelection(bool isBlocked, @@ -206,13 +258,15 @@ void PartSet_OperationFeatureEditMulti::sendFeatures() { static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED); - foreach (ModuleBase_ViewerPrs aPrs, myFeatures) { - ObjectPtr aFeature = aPrs.object(); - if (!aFeature) - continue; - - ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent); + std::map>::iterator aFeatIter = myFeature2Attribute.begin(); + while (aFeatIter != myFeature2Attribute.end()) { + FeaturePtr aFeature = aFeatIter->first; + if (aFeature) { + ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent); + } + aFeatIter++; } + Events_Loop::loop()->flush(anEvent); flushUpdated(); } diff --git a/src/PartSet/PartSet_OperationFeatureEditMulti.h b/src/PartSet/PartSet_OperationFeatureEditMulti.h index 77a9dbb54..5b50a7bd6 100644 --- a/src/PartSet/PartSet_OperationFeatureEditMulti.h +++ b/src/PartSet/PartSet_OperationFeatureEditMulti.h @@ -12,6 +12,7 @@ #include #include +#include class QMouseEvent; @@ -76,7 +77,9 @@ Q_OBJECT /// Initialisation of operation with preliminary selection /// \param theSelected the list of selected presentations /// \param theHighlighted the list of highlighted presentations - virtual void initSelection(ModuleBase_ISelection* theSelection); + /// \param theViewer a viewer to have the viewer the eye position + virtual void initSelection(ModuleBase_ISelection* theSelection, + ModuleBase_IViewer* theViewer); /// Returns the operation sketch feature /// \returns the sketch instance @@ -123,9 +126,11 @@ Q_OBJECT /// Sends the features void sendFeatures(); - private: +private: + // the next map should be removed when selection is processed in the move function + std::map > myFeature2Attribute; /// a map of a feature to attributes + CompositeFeaturePtr mySketch; ///< the sketch feature - QList myFeatures; ///< the features to apply the edit operation Point myCurPoint; ///< the current 3D point clicked or moved bool myIsBlockedSelection; ///< the state of the last state of selection blocked signal }; diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index dc4feb845..a96ba41cb 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -172,16 +172,24 @@ boost::shared_ptr PartSet_Tools::document() return ModelAPI_Session::get()->moduleDocument(); } -void PartSet_Tools::setFeaturePoint(FeaturePtr theFeature, double theX, double theY, - const std::string& theAttribute) +boost::shared_ptr PartSet_Tools::getFeaturePoint(FeaturePtr theFeature, + double theX, double theY) { - if (!theFeature) - return; - boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr aPoint = boost::dynamic_pointer_cast( - aData->attribute(theAttribute)); - if (aPoint) - aPoint->setValue(theX, theY); + boost::shared_ptr aClickedPoint = boost::shared_ptr( + new GeomAPI_Pnt2d(theX, theY)); + std::list > anAttiributes = + theFeature->data()->attributes(GeomDataAPI_Point2D::type()); + std::list >::const_iterator anIt = anAttiributes.begin(), + aLast = anAttiributes.end(); + boost::shared_ptr aFPoint; + for (; anIt != aLast && !aFPoint; anIt++) { + boost::shared_ptr aCurPoint = boost::dynamic_pointer_cast< + GeomDataAPI_Point2D>(*anIt); + if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion()) + aFPoint = aCurPoint; + } + + return aFPoint; } void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index 872102d8b..a09604556 100644 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -63,13 +63,13 @@ class PARTSET_EXPORT PartSet_Tools /// Returns pointer to the root document. static boost::shared_ptr document(); - /// \brief Save the point to the feature. If the attribute is 2D geometry point, it is filled. + + /// Returns a point attribute of the feature by the coordinates if it is /// \param theFeature the feature /// \param theX the horizontal coordinate /// \param theY the vertical coordinate - /// \param theAttribute the feature attribute - static void setFeaturePoint(FeaturePtr theFeature, double theX, double theY, - const std::string& theAttribute); + static boost::shared_ptr getFeaturePoint(FeaturePtr theFeature, + double theX, double theY); /// \brief Save the double to the feature. If the attribute is double, it is filled. /// \param theFeature the feature -- 2.39.2