Salome HOME
Edit operation correction.
authornds <natalia.donis@opencascade.com>
Wed, 5 Nov 2014 16:32:22 +0000 (19:32 +0300)
committernds <natalia.donis@opencascade.com>
Wed, 5 Nov 2014 16:32:22 +0000 (19:32 +0300)
Edit and multi edit union finish, restart edit operation from sketch and edit operation only.
Do not perform the commit of edit operation from the module.
The edit operation is commited on mousePress(). This is the temporary modification until the selection(local, global) restore is not realized on setShape() for AIS object.

src/ModuleBase/ModuleBase_Operation.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_OperationFeatureEdit.cpp
src/PartSet/PartSet_OperationFeatureEdit.h
src/PartSet/PartSet_OperationSketch.cpp
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h
src/XGUI/XGUI_Selection.cpp

index fa9183d31914f278f0addce86a44cbab52bbc6db..b3bf0b07572308f26b62a2fc2c177a4ae2eb24dc 100644 (file)
@@ -221,7 +221,13 @@ bool ModuleBase_Operation::commit()
     disconnect(myPropertyPanel, 0, this, 0);
 
     stopOperation();
-    ModelAPI_Session::get()->finishOperation();
+    // check whether there are modifications performed during the current operation
+    // in the model
+    // in case if there are no modifications, do not increase the undo/redo stack
+    if (ModelAPI_Session::get()->isModified())
+      ModelAPI_Session::get()->finishOperation();
+    else
+      ModelAPI_Session::get()->abortOperation();
 
     emit stopped();
 
index ad9210e3fdb37a573d6c2ef9090970bbac241e2e..3916b3d0a0245fa9150f2a89323df5a18e135961 100644 (file)
@@ -590,11 +590,13 @@ void PartSet_Module::onSelectionChanged()
   QList<ModuleBase_ViewerPrs> aSelected = aSelect->getSelected();
   // We need to stop edit operation if selection is cleared
   if (aSelected.size() == 0) {
-    PartSet_OperationFeatureEdit* anEditOp = 
+    // do not perform commit of the current edit operation here, because
+    // this functionality is realized inside this operation
+    /*PartSet_OperationFeatureEdit* anEditOp = 
       dynamic_cast<PartSet_OperationFeatureEdit*>(myWorkshop->currentOperation());
     if (!anEditOp)
       return;
-    anEditOp->commit();
+    anEditOp->commit();*/
   } else {
     PartSet_OperationSketchBase* aSketchOp = 
       dynamic_cast<PartSet_OperationSketchBase*>(myWorkshop->currentOperation());
index c8a2712dbd0bd14df7e150b62c840b72fb5e093b..1a60197995a8a8c22ae815be93c30790e19f703c 100644 (file)
@@ -46,7 +46,7 @@ PartSet_OperationFeatureEdit::PartSet_OperationFeatureEdit(const QString& theId,
                                                            QObject* theParent,
                                                            CompositeFeaturePtr theFeature)
     : PartSet_OperationFeatureBase(theId, theParent, theFeature),
-      myIsBlockedSelection(false), myIsMultiOperation(false)
+      myIsBlockedSelection(false)
 {
   myIsEditing = true;
 }
@@ -58,7 +58,10 @@ PartSet_OperationFeatureEdit::~PartSet_OperationFeatureEdit()
 void PartSet_OperationFeatureEdit::initSelection(ModuleBase_ISelection* theSelection,
                                                       ModuleBase_IViewer* theViewer)
 {
-  PartSet_OperationFeatureBase::initSelection(theSelection, theViewer);
+  // the method of the parent should is useless here because it processes the given
+  // selection in different way
+  //PartSet_OperationFeatureBase::initSelection(theSelection, theViewer);
+
   // 1. unite selected and hightlighted objects in order to have an opportunity to drag
   // by the highlighted object
   QList<ModuleBase_ViewerPrs> aFeatures = theSelection->getSelected();
@@ -68,7 +71,6 @@ void PartSet_OperationFeatureEdit::initSelection(ModuleBase_ISelection* theSelec
     if (!PartSet_Tools::isContainPresentation(aFeatures, aPrs))
       aFeatures.append(aPrs);
   }
-  myIsMultiOperation = aFeatures.size() > 1; 
 
   // 1. find all features with skipping features with selected vertex shapes
   myFeature2Attribute.clear();
@@ -110,9 +112,6 @@ void PartSet_OperationFeatureEdit::initSelection(ModuleBase_ISelection* theSelec
       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;
 
       // append the attribute of the vertex if it is found on the current feature
       gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
@@ -133,67 +132,81 @@ void PartSet_OperationFeatureEdit::initSelection(ModuleBase_ISelection* theSelec
 
 void PartSet_OperationFeatureEdit::mousePressed(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer, ModuleBase_ISelection* theSelection)
 {
-  if (myIsMultiOperation)
-    return;
-
   ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
   if(aActiveWgt && aActiveWgt->isViewerSelector()) {
     // Almost do nothing, all stuff in on PartSet_OperationFeatureBase::mouseReleased
     PartSet_OperationFeatureBase::mousePressed(theEvent, theViewer, theSelection);
     return;
   }
-  QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
-  QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
-  bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
-  if (aHasShift && !aHighlighted.empty()) {
-    foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) {
-      aSelected.append(aPrs);
-    }
-  }
-  ObjectPtr aObject;
-  /*if (!aSelected.empty()) {
-    aObject = aSelected.first().object();
-  } else {   
-    if (!aHighlighted.empty())
-      aObject = aHighlighted.first().object();
-  }*/
-  // the priority to a highlighted object in order to edit it, even if the selected object is
-  // the feature of this operation. Otherwise, the highlighting is ignored and the selected
-  // object is moved
-  if (!aHighlighted.empty()) {
-    aObject = aHighlighted.front().object();
-  }
-  if (!aObject && !aSelected.empty())  // changed for a constrain
-    aObject = aSelected.front().object();
-
-  FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
-  if (!aFeature || aFeature != feature() || (aSelected.size() > 1)) {
-    if (commit()) {
-      theViewer->enableSelection(true);
-      emit featureConstructed(feature(), FM_Deactivation);
-
-      // If we have selection and prehilighting with shift pressed 
-      // Then we have to select all these objects and restart as multi edit operfation
-      //bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
-      //if (aHasShift && !theHighlighted.empty()) {
-      //  QList<ObjectPtr> aSelected;
-      //  std::list<ModuleBase_ViewerPrs>::const_iterator aIt;
-      //  for (aIt = theSelected.cbegin(); aIt != theSelected.cend(); ++aIt)
-      //    aSelected.append((*aIt).object());
-
-      //  for (aIt = theHighlighted.cbegin(); aIt != theHighlighted.cend(); ++aIt) {
-      //    if (!aSelected.contains((*aIt).object()))
-      //      aSelected.append((*aIt).object());
-      //  }
-      //  emit setSelection(aSelected);
-      //} else 
-      if (aFeature) {
-        std::string anOperationType = PartSet_OperationFeatureEdit::Type();
-        restartOperation(anOperationType, aFeature);
-      }
-      //}
+  else {
+    // commit always until the selection restore is realized (for feature and local selection)
+    // TODO: check whether the selection is changed and restart the operation only if it is modified
+    commit();
+    emitFeaturesDeactivation();
+    // find nearest feature and restart the operation for it
+    Handle(V3d_View) aView = theViewer->activeView();
+    QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
+    QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
+
+    ObjectPtr aFeature = PartSet_Tools::nearestFeature(theEvent->pos(), aView, sketch(),
+                                                       aSelected, aHighlighted);
+    if (aFeature) {
+      restartOperation(PartSet_OperationFeatureEdit::Type(), aFeature);
     }
   }
+  // the next code is commented because the new attempt to commit/restart operation implementation:
+  //QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
+  //QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
+  //bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
+  //if (aHasShift && !aHighlighted.empty()) {
+  //  foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) {
+  //    aSelected.append(aPrs);
+  //  }
+  //}
+  //ObjectPtr aObject;
+  ///*if (!aSelected.empty()) {
+  //  aObject = aSelected.first().object();
+  //} else {   
+  //  if (!aHighlighted.empty())
+  //    aObject = aHighlighted.first().object();
+  //}*/
+  //// the priority to a highlighted object in order to edit it, even if the selected object is
+  //// the feature of this operation. Otherwise, the highlighting is ignored and the selected
+  //// object is moved
+  //if (!aHighlighted.empty()) {
+  //  aObject = aHighlighted.front().object();
+  //}
+  //if (!aObject && !aSelected.empty())  // changed for a constrain
+  //  aObject = aSelected.front().object();
+
+  //FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
+  //if (!aFeature || aFeature != feature() || (aSelected.size() > 1)) {
+  //  if (commit()) {
+  //    theViewer->enableSelection(true);
+  //    emit featureConstructed(feature(), FM_Deactivation);
+
+  //    // If we have selection and prehilighting with shift pressed 
+  //    // Then we have to select all these objects and restart as multi edit operfation
+  //    //bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
+  //    //if (aHasShift && !theHighlighted.empty()) {
+  //    //  QList<ObjectPtr> aSelected;
+  //    //  std::list<ModuleBase_ViewerPrs>::const_iterator aIt;
+  //    //  for (aIt = theSelected.cbegin(); aIt != theSelected.cend(); ++aIt)
+  //    //    aSelected.append((*aIt).object());
+
+  //    //  for (aIt = theHighlighted.cbegin(); aIt != theHighlighted.cend(); ++aIt) {
+  //    //    if (!aSelected.contains((*aIt).object()))
+  //    //      aSelected.append((*aIt).object());
+  //    //  }
+  //    //  emit setSelection(aSelected);
+  //    //} else 
+  //    if (aFeature) {
+  //      std::string anOperationType = PartSet_OperationFeatureEdit::Type();
+  //      restartOperation(anOperationType, aFeature);
+  //    }
+  //    //}
+  //  }
+  //}
 }
 
 void PartSet_OperationFeatureEdit::mouseMoved(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer)
@@ -216,56 +229,61 @@ void PartSet_OperationFeatureEdit::mouseMoved(QMouseEvent* theEvent, ModuleBase_
     double aDeltaX = aX - aCurX;
     double aDeltaY = anY - aCurY;
 
-    if (myIsMultiOperation) {
-      std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
-      while (aFeatIter != myFeature2Attribute.end()) {
-        FeaturePtr aFeature = aFeatIter->first;
-        std::list<std::string> anAttributes = aFeatIter->second;
-        // perform edit for the feature
-        if (anAttributes.empty()) {
-          boost::shared_ptr<SketchPlugin_Feature> aSketchFeature =
-                                         boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-          if (aSketchFeature) {
-            aSketchFeature->move(aDeltaX, aDeltaY);
-          }
-        }
-        // perform edit for the feature's attribute
-        else {
-          std::list<std::string>::const_iterator anAttrIter = anAttributes.begin(),
-                                                 anAttrEnd = anAttributes.end();
-          for (; anAttrIter != anAttrEnd; anAttrIter++) {
-            boost::shared_ptr<GeomDataAPI_Point2D> aPointAttr = boost::dynamic_pointer_cast<
-                             GeomDataAPI_Point2D>(aFeature->data()->attribute(*anAttrIter));
-            if (aPointAttr) {
-              aPointAttr->move(aDeltaX, aDeltaY);
-            }
-          }      
-        }
-        aFeatIter++;
-      }
-    }
-    else { // multieditoperation
-
-    boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
-        SketchPlugin_Feature>(feature());
+    // the next code is commented because it is obsolete by the multi edit operation realization here
+    //if (myIsMultiOperation) {
+    //  std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
+    //  while (aFeatIter != myFeature2Attribute.end()) {
+    //    FeaturePtr aFeature = aFeatIter->first;
+    //    std::list<std::string> anAttributes = aFeatIter->second;
+    //    // perform edit for the feature
+    //    if (anAttributes.empty()) {
+    //      boost::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+    //                                     boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+    //      if (aSketchFeature) {
+    //        aSketchFeature->move(aDeltaX, aDeltaY);
+    //      }
+    //    }
+    //    // perform edit for the feature's attribute
+    //    else {
+    //      std::list<std::string>::const_iterator anAttrIter = anAttributes.begin(),
+    //                                             anAttrEnd = anAttributes.end();
+    //      for (; anAttrIter != anAttrEnd; anAttrIter++) {
+    //        boost::shared_ptr<GeomDataAPI_Point2D> aPointAttr = boost::dynamic_pointer_cast<
+    //                         GeomDataAPI_Point2D>(aFeature->data()->attribute(*anAttrIter));
+    //        if (aPointAttr) {
+    //          aPointAttr->move(aDeltaX, aDeltaY);
+    //        }
+    //      }      
+    //    }
+    //    aFeatIter++;
+    //  }
+    //}
+    //else { // multieditoperation
+
+    //boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
+    //    SketchPlugin_Feature>(feature());
 
     bool isMoved = false;
     // the functionality to move the feature attribute if it exists in the internal map
     std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
     while (aFeatIter != myFeature2Attribute.end()) {
       FeaturePtr aFeature = aFeatIter->first;
+      // MPV: added condition because it could be external edge of some object, not sketch
+      if (aFeature && !sketch()->isSub(aFeature))
+        continue;
+
       std::list<std::string> anAttributes = aFeatIter->second;
       // perform edit for the feature
-      /*if (anAttributes.empty()) {
+      if (anAttributes.empty()) {
         boost::shared_ptr<SketchPlugin_Feature> aSketchFeature =
                                        boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
         if (aSketchFeature) {
           aSketchFeature->move(aDeltaX, aDeltaY);
+          isMoved = true;
         }
-      }*/
+      }
       // perform edit for the feature's attribute
-      //else {
-      if (!anAttributes.empty()) {
+      else {
         std::list<std::string>::const_iterator anAttrIter = anAttributes.begin(),
                                                anAttrEnd = anAttributes.end();
         for (; anAttrIter != anAttrEnd; anAttrIter++) {
@@ -279,17 +297,17 @@ void PartSet_OperationFeatureEdit::mouseMoved(QMouseEvent* theEvent, ModuleBase_
       }
       aFeatIter++;
     }
-
+    // the next code is commented because it is obsolete by the multi edit operation realization here
     // the feature is moved only if there is no a local selection on this feature
-    if (!isMoved) {
-      // MPV: added condition because it could be external edge of some object, not sketch
-      if (aSketchFeature && sketch()->isSub(aSketchFeature)) {
-        aSketchFeature->move(aDeltaX, aDeltaY);
-        static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
-        ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent);
-      }
-    }
-    } // multieditoperation
+    //if (!isMoved) {
+    //  // MPV: added condition because it could be external edge of some object, not sketch
+    //  if (aSketchFeature && sketch()->isSub(aSketchFeature)) {
+    //   aSketchFeature->move(aDeltaX, aDeltaY);
+    //    static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
+    //   ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent);
+    //  }
+    // }
+    //} // multieditoperation
   }
   sendFeatures();
 
@@ -301,29 +319,44 @@ void PartSet_OperationFeatureEdit::mouseReleased(
     ModuleBase_ISelection* theSelection)
 {
   theViewer->enableSelection(true);
-  if (myIsMultiOperation) {
-    if (commit()) {
-      std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
-      while (aFeatIter != myFeature2Attribute.end()) {
-        FeaturePtr aFeature = aFeatIter->first;
-        if (aFeature) {
-          emit featureConstructed(aFeature, FM_Deactivation);
-        }
-        aFeatIter++;
-      }
-    }
-  }
-  else { // multieditoperation
+  // the next code is commented because it is obsolete by the multi edit operation realization here
+  //if (myIsMultiOperation) {
+  //  if (commit()) {
+  //    std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
+  //    while (aFeatIter != myFeature2Attribute.end()) {
+  //      FeaturePtr aFeature = aFeatIter->first;
+  //      if (aFeature) {
+  //        emit featureConstructed(aFeature, FM_Deactivation);
+  //      }
+  //      aFeatIter++;
+  //    }
+  //  }
+  //}
+  //else { // multieditoperation
   ModuleBase_ModelWidget* aActiveWgt = 0;
   if (myPropertyPanel)
     aActiveWgt = myPropertyPanel->activeWidget();
   if(aActiveWgt && aActiveWgt->isViewerSelector()) {
     // Almost do nothing, all stuff in on PartSet_OperationFeatureBase::mouseReleased
     PartSet_OperationFeatureBase::mouseReleased(theEvent, theViewer, theSelection);
-  }// else {
-    //blockSelection(false);
-  //}
-  } // multieditoperation
+  //}// else {
+  ////blockSelection(false);
+  ////}
+  //} // multieditoperation
+  }
+  else {
+    theViewer->enableSelection(true);
+
+    // commit operation if there is no selected an highlighted objects anymore
+    Handle(V3d_View) aView = theViewer->activeView();
+    QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
+    QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
+
+    if (aSelected.empty() && aHighlighted.empty()) {
+      commit();
+      emitFeaturesDeactivation();
+    }
+  }
 }
 
 void PartSet_OperationFeatureEdit::mouseDoubleClick(
@@ -410,3 +443,15 @@ void PartSet_OperationFeatureEdit::sendFeatures()
   flushUpdated();
 }
 
+void PartSet_OperationFeatureEdit::emitFeaturesDeactivation()
+{
+  std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
+  while (aFeatIter != myFeature2Attribute.end()) {
+    FeaturePtr aFeature = aFeatIter->first;
+    if (aFeature) {
+      emit featureConstructed(aFeature, FM_Deactivation);
+    }
+    aFeatIter++;
+  }
+}
+
index 682cf91ff71cd8aa44f5aad58f47d04f146fac6a..a4bec4ef755da085c964743590ad3dc2dba96122 100644 (file)
@@ -134,13 +134,15 @@ Q_OBJECT
   /// Sends the features
   void sendFeatures();
 
+  /// Sends signal about the current features are to be deactivated
+  void emitFeaturesDeactivation();
+
  private:
   // the next map should be removed when selection is processed in the move function
   std::map<FeaturePtr, std::list<std::string> > myFeature2Attribute; /// a map of a feature to attributes
 
   Point myCurPoint;  ///< the current 3D point clicked or moved
   bool myIsBlockedSelection;  ///< the state of the last state of selection blocked signal
-  bool myIsMultiOperation; // the state whether the operation is used for some features
 };
 
 #endif
index 29889ab5d4453e1b6144904c1fbf985d6c136289..2a39d0924745159db636cb5e8db4645490349e00 100644 (file)
@@ -62,28 +62,33 @@ void PartSet_OperationSketch::mousePressed(QMouseEvent* theEvent, ModuleBase_IVi
     bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
     QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
     QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
+    // commented: the next code is commented because the nearestFeature check the highlighting
+    // and selection inside
     //if (aHasShift && (aSelected.size() > 0)) {
-      foreach(ModuleBase_ViewerPrs aPrs, aHighlighted)
-        aSelected.append(aPrs);
+    //  foreach(ModuleBase_ViewerPrs aPrs, aHighlighted)
+    //    aSelected.append(aPrs);
     //}
     //if (aHasShift && aSelected.size() > 0)
     //  return;
 
     // there should be a start of operation, which uses the pre-highlighted objects,
     // the selected ones are collected here and are processed by a mouse move
-    if (aHighlighted.size() == 1) {
+    //if (aHighlighted.size() == 1) {
     //if (aSelected.size() > 0) {
-      ObjectPtr aFeature = aSelected.first().object();
-      if (aFeature) {
-        std::string anOperationType = PartSet_OperationFeatureEdit::Type();
-        restartOperation(anOperationType, aFeature);
-      }
-    }
-    else
-      myFeatures = aHighlighted;
+    //  ObjectPtr aFeature = aSelected.first().object();
+    //  if (aFeature) {
+    // commented: end
+        Handle(V3d_View) aView = theViewer->activeView();
+        ObjectPtr aFeature = PartSet_Tools::nearestFeature(theEvent->pos(), aView, feature(),
+                                                           aSelected, aHighlighted);
+        if (aFeature)
+          restartOperation(PartSet_OperationFeatureEdit::Type(), aFeature);
+      //}
+    //}
+    //else
+    //  myFeatures = aHighlighted;
     //else
     //myFeatures = aSelected;
-
   } 
 }
 
@@ -146,13 +151,15 @@ void PartSet_OperationSketch::mouseMoved(QMouseEvent* theEvent, ModuleBase_IView
   if (!hasSketchPlane() || !(theEvent->buttons() & Qt::LeftButton) || myFeatures.empty())
     return;
 
-  if (myFeatures.size() != 1) {
+  // myFeatures are not filled in the previous realization, so, this code is just commented
+  // because has no effect
+  /*if (myFeatures.size() != 1) {
     Handle(V3d_View) aView = theViewer->activeView();
-    FeaturePtr aFeature = PartSet_Tools::nearestFeature(theEvent->pos(), aView, feature(),
-                                                        myFeatures);
+    ObjectPtr aFeature = PartSet_Tools::nearestFeature(theEvent->pos(), aView, feature(),
+                                                       myFeatures);
     if (aFeature)
       restartOperation(PartSet_OperationFeatureEdit::Type(), aFeature);
-  }
+  }*/
 }
 
 std::list<FeaturePtr> PartSet_OperationSketch::subFeatures() const
index dfd39512dfd04867ed34e3b81b158e5a0a81b25a..0344269bb22e4dbf1e31fd6d3b78420619048a79 100644 (file)
@@ -147,33 +147,47 @@ void PartSet_Tools::convertTo3D(const double theX, const double theY, FeaturePtr
   thePoint = gp_Pnt(aPoint->x(), aPoint->y(), aPoint->z());
 }
 
-FeaturePtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView,
-                                         FeaturePtr theSketch,
-                                         const QList<ModuleBase_ViewerPrs>& theFeatures)
+ObjectPtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView,
+                                        FeaturePtr theSketch,
+                                        const QList<ModuleBase_ViewerPrs>& theSelected,
+                                        const QList<ModuleBase_ViewerPrs>& theHighlighted)
 {
-  double aX, anY;
-  gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView);
-  PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, anY);
-
-  FeaturePtr aFeature;
-  FeaturePtr aDeltaFeature;
-  double aMinDelta = -1;
-  ModuleBase_ViewerPrs aPrs;
-  foreach (ModuleBase_ViewerPrs aPrs, theFeatures) {
-    if (!aPrs.object())
-      continue;
-    boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
-        SketchPlugin_Feature>(aPrs.object());
-    if (!aSketchFeature)
-      continue;
-    double aDelta = aSketchFeature->distanceToPoint(
-        boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, anY)));
-    if (aMinDelta < 0 || aMinDelta > aDelta) {
-      aMinDelta = aDelta;
-      // TODO aDeltaFeature = aPrs.result();
+  ObjectPtr aDeltaObject;
+  // 1. find the object in the highlighted list
+  if (theHighlighted.size() > 0) {
+    aDeltaObject = theHighlighted.first().object();
+  }
+  // 2. find it in the selected list by the selected point
+  if (!aDeltaObject) {
+    double aX, anY;
+    gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView);
+    PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, anY);
+
+    FeaturePtr aFeature;
+    double aMinDelta = -1;
+    ModuleBase_ViewerPrs aPrs;
+    foreach (ModuleBase_ViewerPrs aPrs, theSelected) {
+      if (!aPrs.object())
+        continue;
+      FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object());
+      boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
+          SketchPlugin_Feature>(aFeature);
+      if (!aSketchFeature)
+        continue;
+
+      double aDelta = aSketchFeature->distanceToPoint(
+          boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, anY)));
+      if (aMinDelta < 0 || aMinDelta > aDelta) {
+        aMinDelta = aDelta;
+        // TODO aDeltaObject = aPrs.result();
+      }
     }
   }
-  return aDeltaFeature;
+  // 3. if the object is not found, returns the first selected one
+  if (!aDeltaObject && theSelected.size() > 0)
+    aDeltaObject = theSelected.first().object();
+
+  return aDeltaObject;
 }
 
 boost::shared_ptr<ModelAPI_Document> PartSet_Tools::document()
index 1e5b4b0851eeaf3af63c2a0e7f759762f521f16d..a436f7b0bf372a79a904eabddfa839c11d8bc6cd 100644 (file)
@@ -54,13 +54,18 @@ class PARTSET_EXPORT PartSet_Tools
   static void convertTo3D(const double theX, const double theY, FeaturePtr theSketch,
                           gp_Pnt& thePoint);
 
-  /// Returns a feature that is under the mouse point
+  /// Returns an object that is under the mouse point. Firstly it checks the highlighting,
+  /// if it exists, the first object is returned. Secondly, there is an iteration on
+  /// the selected list to find the point. Thirdly, if the object is not found under the
+  /// the point, the first selected object is returned.
   /// \param thePoint a screen point
   /// \param theView a 3D view
   /// \param theSketch the sketch feature
-  /// \param theFeatures the list of selected presentations
-  static FeaturePtr nearestFeature(QPoint thePoint, Handle_V3d_View theView, FeaturePtr theSketch,
-                                   const QList<ModuleBase_ViewerPrs>& theFeatures);
+  /// \param theSelected the list of selected presentations
+  /// \param theHighlighted the list of highlighted presentations
+  static ObjectPtr nearestFeature(QPoint thePoint, Handle_V3d_View theView, FeaturePtr theSketch,
+                                  const QList<ModuleBase_ViewerPrs>& theSelected,
+                                  const QList<ModuleBase_ViewerPrs>& theHighlighted);
 
   /// Returns pointer to the root document.
   static boost::shared_ptr<ModelAPI_Document> document();
index d4fe690b11e08a4009bf58403d001399b4e74e1e..0dd985f977c8c8c5c7a4aac0b3007b1f0c51079b 100644 (file)
@@ -21,7 +21,7 @@ XGUI_Selection::XGUI_Selection(XGUI_Workshop* theWorkshop)
 
 QList<ModuleBase_ViewerPrs> XGUI_Selection::getSelected(int theShapeTypeToSkip) const
 {
-  std::set<ObjectPtr> aPrsFeatures;
+  //std::set<ObjectPtr> aPrsFeatures;
   QList<ModuleBase_ViewerPrs> aPresentations;
   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
 
@@ -33,10 +33,12 @@ QList<ModuleBase_ViewerPrs> XGUI_Selection::getSelected(int theShapeTypeToSkip)
     aPrs.setInteractive(anIO);
 
     ObjectPtr aFeature = aDisplayer->getObject(anIO);
-    if (aPrsFeatures.find(aFeature) == aPrsFeatures.end()) {
+    // we should not check the appearance of this feature because there can be some selected shapes
+    // for one feature
+    //if (aPrsFeatures.find(aFeature) == aPrsFeatures.end()) {
       aPrs.setFeature(aFeature);
-      aPrsFeatures.insert(aFeature);
-    }
+      //aPrsFeatures.insert(aFeature);
+    //}
     if (aContext->HasOpenedContext()) {
       TopoDS_Shape aShape = aContext->SelectedShape();
       if (!aShape.IsNull() && (aShape.ShapeType() != theShapeTypeToSkip))