Salome HOME
refs #156: Behavior of the Sketch during edition
authornds <natalia.donis@opencascade.com>
Wed, 29 Oct 2014 14:43:41 +0000 (17:43 +0300)
committernds <natalia.donis@opencascade.com>
Wed, 29 Oct 2014 14:43:41 +0000 (17:43 +0300)
Edit Multi operation is correct to modify the feature attribute only.

src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_Operation.cpp
src/ModuleBase/ModuleBase_Operation.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_OperationFeatureEditMulti.cpp
src/PartSet/PartSet_OperationFeatureEditMulti.h
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h

index df2502fbbb4af73292b0b998b5d25cd7f405544a..36e09437e72d38564105a63087319edb9d56c07b 100644 (file)
@@ -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);
 }
 
index 896da097e6160d7f73ed867ea9b9c3a5dc48869d..cd728aa7adcb2711218549b172b0062bd6b83df1 100644 (file)
@@ -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();
 
index 9d1a1c04ad2e3310c2040d0ac03ccbedddc93b0d..07b413218a832b294cee888c56e5553b58cbee02 100644 (file)
@@ -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);
 
index f38381ef85160fcedbbb5b29dd2744766a84d947..035444ba936e51e465f3133a1d3495e6ebed6b57 100644 (file)
@@ -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
index 4b10858a0bc40ff31371022d816479a616c610e3..c513216bacae1f0bfa3d72bc709dbeae308778d8 100644 (file)
@@ -25,6 +25,9 @@
 #include <SketchPlugin_Line.h>
 
 #include <V3d_View.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
 
 #include <QMouseEvent>
 #ifdef _DEBUG
@@ -58,37 +61,75 @@ bool isContains(const QList<ModuleBase_ViewerPrs>& 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<ModuleBase_ViewerPrs>::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<ModuleBase_ViewerPrs> aFeatures;
+  aFeatures = theSelection->getSelected();
   QList<ModuleBase_ViewerPrs> 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<FeaturePtr> 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<std::string> 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<GeomDataAPI_Point2D> aPoint2D = PartSet_Tools::getFeaturePoint(
+                                                                    aFeature, aVX, aVY);
+      std::string anAttribute = aFeature->data()->id(aPoint2D);
+      std::list<std::string> 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<SketchPlugin_Feature> 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<SketchPlugin_Feature>(aFeature);
-        if (aSketchFeature)
+    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;
+      if (anAttributes.empty()) {
+        boost::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+                                       boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+        if (aSketchFeature) {
           aSketchFeature->move(aDeltaX, aDeltaY);
+        }
+      }
+      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++;
     }
   }
   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<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++;
     }
   }
 }
@@ -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<FeaturePtr, std::list<std::string>>::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();
 }
index 77a9dbb5408916e6bc38c7300a677213d99f7801..5b50a7bd6aa61956b6ad43a641b18219ba3c26b1 100644 (file)
@@ -12,6 +12,7 @@
 #include <QList>
 
 #include <list>
+#include <map>
 
 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<FeaturePtr, std::list<std::string> > myFeature2Attribute; /// a map of a feature to attributes
+
   CompositeFeaturePtr mySketch;  ///< the sketch feature
-  QList<ModuleBase_ViewerPrs> 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
 };
index dc4feb845df6099a441ecbec50a169b55709155c..a96ba41cbee5623d9b37f75e54b572af71176312 100644 (file)
@@ -172,16 +172,24 @@ boost::shared_ptr<ModelAPI_Document> 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<GeomDataAPI_Point2D> PartSet_Tools::getFeaturePoint(FeaturePtr theFeature,
+                                                                      double theX, double theY)
 {
-  if (!theFeature)
-    return;
-  boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      aData->attribute(theAttribute));
-  if (aPoint)
-    aPoint->setValue(theX, theY);
+  boost::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = boost::shared_ptr<GeomAPI_Pnt2d>(
+                                                                 new GeomAPI_Pnt2d(theX, theY));
+  std::list<boost::shared_ptr<ModelAPI_Attribute> > anAttiributes =
+                                    theFeature->data()->attributes(GeomDataAPI_Point2D::type());
+  std::list<boost::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
+                                                                    aLast = anAttiributes.end();
+  boost::shared_ptr<GeomDataAPI_Point2D> aFPoint;
+  for (; anIt != aLast && !aFPoint; anIt++) {
+    boost::shared_ptr<GeomDataAPI_Point2D> 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,
index 872102d8b6d9022e9beea3a9cada4c2105cf5de3..a09604556fe7d90df822284428ae6f43fb4f904f 100644 (file)
@@ -63,13 +63,13 @@ class PARTSET_EXPORT PartSet_Tools
   /// Returns pointer to the root document.
   static boost::shared_ptr<ModelAPI_Document> 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<GeomDataAPI_Point2D> 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