]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1343 Improvement of Extrusion and Revolution operations: delete of inappropria...
authornds <nds@opencascade.com>
Wed, 23 Mar 2016 17:16:46 +0000 (20:16 +0300)
committerdbv <dbv@opencascade.com>
Fri, 25 Mar 2016 15:50:19 +0000 (18:50 +0300)
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Extrusion.h
src/FeaturesPlugin/extrusion_widget.xml
src/GeomValidators/GeomValidators_FeatureKind.cpp
src/ModuleBase/ModuleBase_IModule.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_WidgetSketchCreator.cpp
src/PartSet/PartSet_WidgetSketchCreator.h
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h

index 36ca2939f9802e11e21e1f159d22488b75e7555c..cd843949fcf7149be79c07d12511e2bb879b41b3 100644 (file)
@@ -177,6 +177,14 @@ void FeaturesPlugin_Extrusion::execute()
   removeResults(aResultIndex);
 }
 
+//=================================================================================================
+void FeaturesPlugin_Extrusion::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
+{
+  AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
+  if (aFacesSelectionList.get() && aFacesSelectionList->size() > 0)
+    aFacesSelectionList->clear();
+}
+
 //=================================================================================================
 void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo,
                                             std::shared_ptr<ModelAPI_ResultBody> theResultBody,
@@ -239,3 +247,4 @@ void FeaturesPlugin_Extrusion::setSketchObjectToList()
     }
   }
 }
+
index cc000508123be6cd07f2c2ce7666833e8f946664..a8867530ebcfd4ae193da42a87bff50470676fa0 100644 (file)
@@ -110,6 +110,10 @@ class FeaturesPlugin_Extrusion : public FeaturesPlugin_CompositeSketch
   /// Request for initialization of data model of the feature: adding all attributes
   FEATURESPLUGIN_EXPORT virtual void initAttributes();
 
+  /// This method to inform that sub-feature is removed and must be removed from the internal data
+  /// structures of the owner (the remove from the document will be done outside just after)
+  FEATURESPLUGIN_EXPORT virtual void removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature);
+
   /// Use plugin manager for features creation
   FeaturesPlugin_Extrusion();
 
index 1cf80deb2e69c74f74affc28e89727802476df30..3dc5813d50b45f3d46a6504ef20c82065c3b6709 100644 (file)
@@ -3,9 +3,10 @@
 <source>
   <sketch_launcher id="sketch"
     attribute_list_id="base"
-    label="Select: 1. Planar face of non-sketch object or a plane. Sketch creation will be started.
-2. An existing sketch face or contour. Extrusion will be filled with them. 3.A shape on existing result: wires/edge/vertices.
-Extrusion will be filled with them"
+    label="Select:&lt;br /&gt;
+1. Planar face of non-sketch object or a plane. Sketch creation will be started.&lt;br /&gt;
+2. An existing sketch face or contour. Extrusion will be filled by it.&lt;br /&gt;
+3. An existing result shape of kind: wires/edge/vertices.Extrusion will be filled by it."
     icon=":icons/sketch.png"
     tooltip="Create or edit a sketch"
     shape_types="face objects">
index cdf2ebd7be9981700fa2bc6628016aae1c5e2b51..edf205f05874a1709037a78aaaa53f8be654db91 100755 (executable)
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_Object.h>
 
+//#define DEBUG_EXTRUSION_INVALID_SKETCH
+#ifdef DEBUG_EXTRUSION_INVALID_SKETCH
+  #include <ModelAPI_CompositeFeature.h>
+#endif
+
 bool GeomValidators_FeatureKind::isValid(const AttributePtr& theAttribute,
                                       const std::list<std::string>& theArguments,
                                       std::string& theError) const
@@ -43,6 +48,11 @@ bool GeomValidators_FeatureKind::isValid(const AttributePtr& theAttribute,
       else {
         FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
         isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
+#ifdef DEBUG_EXTRUSION_INVALID_SKETCH
+        CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+        if (aComp.get() && aComp->numberOfSubs() == 1)
+          return false;
+#endif
       }
     }
   }
index 016564178d8f7f2971b9597661091760276d2de8..45d070997c34b9c430a8325891eeba0b5737d2f2 100755 (executable)
@@ -73,6 +73,10 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
   /// \param theFeature feature for editing\r
   virtual void editFeature(FeaturePtr theFeature);\r
 \r
+  /// Returns true if the operation can be committed. Result in default implementation is true.\r
+  /// \return boolean value\r
+  virtual bool canCommitOperation() const { return true; }\r
+\r
   /// Creates an operation and send it to loop\r
   /// \param theCmdId the operation name\r
   virtual void launchOperation(const QString& theCmdId);\r
index 9219dbaf07073dca27b8235a10137a74c8945060..9258887258d05096e0f1d717a040c4b14fe1ef5e 100755 (executable)
@@ -49,6 +49,7 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeSelectionList.h>
 
 #include <GeomDataAPI_Point2D.h>
 #include <GeomDataAPI_Point.h>
@@ -796,6 +797,11 @@ void PartSet_Module::onFeatureTriggered()
   ModuleBase_IModule::onFeatureTriggered();
 }
 
+bool PartSet_Module::canCommitOperation() const
+{
+  return PartSet_WidgetSketchCreator::canCommitCurrentSketch(myWorkshop);
+}
+
 void PartSet_Module::launchOperation(const QString& theCmdId)
 {
   if (myWorkshop->currentOperation() && 
index cb7d8613142fc0a937de8a2a61837af54c0f4828..00af4f358882cfad147108cbf247f2aa256173de 100755 (executable)
@@ -91,6 +91,10 @@ public:
   virtual bool createWidgets(ModuleBase_Operation* theOperation,
                              QList<ModuleBase_ModelWidget*>& theWidgets) const;
 
+  /// Returns true if the operation can be committed. Result in default implementation is true.
+  /// \return boolean value
+  virtual bool canCommitOperation() const;
+
   /// Creates an operation and send it to loop
   /// \param theCmdId the operation name
   virtual void launchOperation(const QString& theCmdId);
index bd70b0f0a3bd2c3a92c52b07349fbee30cab7d48..24e0f5f504b6c40171fb39a8f9768de90517c7f7 100644 (file)
@@ -45,6 +45,7 @@
 //#include <QFormLayout>
 #include <QVBoxLayout>
 #include <QMessageBox>
+#include <QMainWindow>
 
 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, 
                                                          PartSet_Module* theModule,
@@ -113,6 +114,17 @@ bool PartSet_WidgetSketchCreator::storeValueCustom() const
   return true;
 }
 
+void PartSet_WidgetSketchCreator::activateSelectionControl()
+{
+  setVisibleSelectionControl(true);
+
+  // we need to call activate here as the widget has no focus accepted controls
+  // if these controls are added here, activate will happens automatically after focusIn()
+  XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
+  XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
+  aPanel->activateWidget(this, false);
+}
+
 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
 {
   // hide current widget, activate the next widget
@@ -162,6 +174,54 @@ void PartSet_WidgetSketchCreator::setEditingMode(bool isEditing)
     setVisibleSelectionControl(false);
 }
 
+bool PartSet_WidgetSketchCreator::canCommitCurrentSketch(ModuleBase_IWorkshop* theWorkshop)
+{
+  bool aCanCommit = true;
+  ModuleBase_Operation* anOperation = theWorkshop->currentOperation();
+  XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(theWorkshop);
+  XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr();
+  // check if the operation is nested
+  if (anOperation && anOpMgr->operationsCount() > 1) {
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(anOperation);
+    FeaturePtr aCurrentFeature = aFOperation ? aFOperation->feature() : FeaturePtr();
+
+    ModuleBase_Operation* aPOperation =  anOpMgr->previousOperation(anOperation);
+    ModuleBase_OperationFeature* aFPOperation = dynamic_cast<ModuleBase_OperationFeature*>(aPOperation);
+    FeaturePtr aParentFeature = aFPOperation ? aFPOperation->feature() : FeaturePtr();
+
+    CompositeFeaturePtr aCompositeFeature = 
+                             std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCurrentFeature);
+    CompositeFeaturePtr aPCompositeFeature = 
+                             std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aParentFeature);
+    // check if both features are composite: extrusion and sketch
+    if (aCompositeFeature.get() && aPCompositeFeature.get()) {
+      aPCompositeFeature->execute(); // to fill attribute selection list
+      std::list<AttributePtr> aSelListAttributes = aParentFeature->data()->attributes(
+                                                        ModelAPI_AttributeSelectionList::typeId());
+      if (aSelListAttributes.size() == 1) {
+        AttributePtr aFirstAttribute = aSelListAttributes.front();
+
+        SessionPtr aMgr = ModelAPI_Session::get();
+        ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+        std::string aValidatorID, anError;
+        bool isValidPComposite = aFactory->validate(aFirstAttribute, aValidatorID, anError);
+        if (!isValidPComposite) {
+          int anAnswer = QMessageBox::question(
+              aWorkshop->desktop(), tr("Apply current feature"),
+                            tr("The current feature can not be used as an argument of the parent feature.\n\
+                               After apply it will be deleted. Would you like to continue?"),
+                            QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
+          if (anAnswer == QMessageBox::Ok)
+            aCanCommit = true;
+          else
+            aCanCommit = false;
+        }
+      }
+    }
+  }
+  return aCanCommit;
+}
+
 bool PartSet_WidgetSketchCreator::isSelectionMode() const
 {
   AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
@@ -197,18 +257,7 @@ void PartSet_WidgetSketchCreator::onSelectionChanged()
 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
                                             GeomShapePtr theShape)
 {
-  std::string anAttributeId = myAttributeListID;
-  DataPtr aData = myFeature->data();
-  AttributePtr anAttribute = aData->attribute(anAttributeId);
-  if (anAttribute.get()) {
-    std::string aType = anAttribute->attributeType();
-    if (aType == ModelAPI_AttributeSelectionList::typeId()) {
-      AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(anAttributeId);
-      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
-      if (!aSelectionListAttr->isInList(aResult, theShape, myIsInValidate))
-        aSelectionListAttr->append(aResult, theShape, myIsInValidate);
-    }
-  }
+  // do nothing because all processing is in onSelectionChanged()
 }
 
 bool PartSet_WidgetSketchCreator::startSketchOperation(const QList<ModuleBase_ViewerPrs>& theValues)
@@ -258,17 +307,11 @@ bool PartSet_WidgetSketchCreator::startSketchOperation(const QList<ModuleBase_Vi
 bool PartSet_WidgetSketchCreator::focusTo()
 {
   if (isSelectionMode()) {
-    setVisibleSelectionControl(true);
-
-    // we need to call activate here as the widget has no focus accepted controls
-    // if these controls are added here, activate will happens automatically after focusIn()
-    XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
-    XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
-    aPanel->activateWidget(this, false);
+    activateSelectionControl();
     return true;
   }
   else {
-    setVisibleSelectionControl(false);
+    //setVisibleSelectionControl(false);
 
     connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
     SessionPtr aMgr = ModelAPI_Session::get();
@@ -296,27 +339,42 @@ void PartSet_WidgetSketchCreator::deactivate()
 
 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
 {
+  XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
+
   CompositeFeaturePtr aCompFeature = 
     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
-  CompositeFeaturePtr aSketchFeature = 
-    std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
-  if (aSketchFeature->numberOfSubs() == 0) {
-    // do nothing, selection control should be shown
-
-    // Abort operation
-    //SessionPtr aMgr = ModelAPI_Session::get();
-    // Close transaction
-    /*
-    bool aIsOp = aMgr->isOperation();
-    if (aIsOp) {
-      const static std::string aNestedOpID("Parameters cancelation");
-      aMgr->startOperation(aNestedOpID, true);
-    }
-    */
-    //theOp->abort();
+  //CompositeFeaturePtr aSketchFeature = 
+  //  std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
+  if (aCompFeature->numberOfSubs() == 0) {
+    // do nothing, selection control should be hidden
+    setVisibleSelectionControl(false);
   } else {
+    // check if the created sketch is invalid. Validate attribute selection list
+    // Shetch should be deleted if the attribute is invalid.
+    AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
+    
+    SessionPtr aMgr = ModelAPI_Session::get();
+    ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+    std::string aValidatorID, anError;
+    bool isValidPComposite = aFactory->validate(anAttrList, aValidatorID, anError);
+    /// if the sketch is not appropriate fro extrusion, it should be deleted and
+    /// the selection control should be activated again
+    if (!isValidPComposite) {
+      CompositeFeaturePtr aSketchFeature = 
+               std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
+
+      QObjectPtrList anObjects;
+      anObjects.append(aSketchFeature);
+      std::set<FeaturePtr> anIgnoredFeatures;
+      aWorkshop->deleteFeatures(anObjects, anIgnoredFeatures);
+
+      // do nothing, selection control should be shown
+      activateSelectionControl();
+      return;
+    }
+    // do nothing, selection control should be hidden
+    setVisibleSelectionControl(false);
     // Update value in attribute selection list
-    XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
     XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
     const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
     foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
@@ -325,6 +383,8 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
     }
 
     // Hide sketcher result
+    CompositeFeaturePtr aSketchFeature = 
+      std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
     std::list<ResultPtr> aResults = aSketchFeature->results();
     std::list<ResultPtr>::const_iterator aIt;
     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
index e0e6276e573238a91967ccace2fca29a2b65bd99..7a341689d179dc21a371d3993e9958cfc4c1830f 100644 (file)
@@ -15,6 +15,7 @@ class QLabel;
 class QLineEdit;
 class PartSet_Module;
 class ModuleBase_Operation;
+class ModuleBase_IWorkshop;
 class PartSet_PreviewPlanes;
 
 /**
@@ -53,6 +54,12 @@ public:
   /// Editing mode depends on mode of current operation. This value is defined by it.
   virtual void setEditingMode(bool isEditing);
 
+  /// Check if the current and the parent operations are a composite. If the parent operation contains
+  /// attribute selection list, the method returns false if it is invalid in this attibute validator
+  /// \param theWorkshop a current workshop
+  /// \return boolean value
+  static bool canCommitCurrentSketch(ModuleBase_IWorkshop* theWorkshop);
+
 protected:
   /// Saves the internal parameters to the given feature
   /// \return True in success
@@ -60,6 +67,10 @@ protected:
 
   virtual bool restoreValueCustom();
 
+  /// Sets the selection control visible and set the current widget as active in property panel
+  /// It leads to connect to onSelectionChanged slot
+  void activateSelectionControl();
+
   /// Visualization of the current control or others in PP
   /// \param theSelectionControl state whether the control should be shown/hidden
   void setVisibleSelectionControl(const bool theSelectionControl);
index 79657c302066b6109deb83407bc486d189983e67..0e0e4c1d7676a600700f7f6f345d45ba947145b2 100644 (file)
@@ -230,13 +230,14 @@ bool XGUI_OperationMgr::abortAllOperations()
 
 bool XGUI_OperationMgr::commitAllOperations()
 {
-  bool isCompositeCommitted = false;
+  bool isCompositeCommitted = false, anOperationProcessed = false;
   while (hasOperation()) {
     ModuleBase_Operation* anOperation = currentOperation();
     if (workshop()->errorMgr()->isApplyEnabled()) {
-      onCommitOperation();
+      anOperationProcessed = onCommitOperation();
     } else {
       abortOperation(anOperation);
+      anOperationProcessed = true;
     }
     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
                                                                             (anOperation);
@@ -248,6 +249,12 @@ bool XGUI_OperationMgr::commitAllOperations()
       if (isCompositeCommitted)
         break;
     }
+    // not processed[committed] operation might be used in composite feature,
+    // so the while will be stopped by the previous check.
+    // this code is not necessary, but logically should be done when the processing will not
+    // be done for not composite feature by some reasons
+    if (!anOperationProcessed)
+      break;
   }
   return true;
 }
@@ -297,11 +304,12 @@ bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
 
 bool XGUI_OperationMgr::commitOperation()
 {
-  if (hasOperation() && currentOperation()->isValid()) {
-    onCommitOperation();
-    return true;
-  }
-  return false;
+  //if (hasOperation() && currentOperation()->isValid()) {
+  //  onCommitOperation();
+  //  return true;
+  //}
+  //return false;
+  return onCommitOperation();
 }
 
 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
@@ -386,11 +394,13 @@ void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation)
   }
 }
 
-void XGUI_OperationMgr::onCommitOperation()
+bool XGUI_OperationMgr::onCommitOperation()
 {
+  bool isCommitted = false;
   ModuleBase_Operation* anOperation = currentOperation();
-  if (anOperation)
-    anOperation->commit();
+  if (anOperation && myWorkshop->module()->canCommitOperation())
+    isCommitted = anOperation->commit();
+  return isCommitted;
 }
 
 void XGUI_OperationMgr::onAbortOperation()
index 3b08ba8b9ef7b72b82cc3fa270dbfd8dd90209cf..c295029258eead138a72f03e9f54361499af174f 100755 (executable)
@@ -105,9 +105,10 @@ Q_OBJECT
   /// \param theOperation an aborted operation
   void abortOperation(ModuleBase_Operation* theOperation);
 
-public slots:
   /// Slot that commits the current operation.
-  void onCommitOperation();
+  bool onCommitOperation();
+
+public slots:
   /// Slot that aborts the current operation.
   void onAbortOperation();
   /// Slot that validates the current operation using the validateOperation method.