]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1343. Improvement of Extrusion and Revolution operations: filling extrusion...
authornds <nds@opencascade.com>
Wed, 6 Apr 2016 10:17:46 +0000 (13:17 +0300)
committerdbv <dbv@opencascade.com>
Wed, 6 Apr 2016 10:25:54 +0000 (13:25 +0300)
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_WidgetSketchCreator.cpp
src/PartSet/PartSet_WidgetSketchCreator.h
src/XGUI/XGUI_OperationMgr.cpp

index 2230d9eb2458939a525a01b8937d849a06be5e27..9e5a3a3b9f28653e53287d4ab3883396f04ae2ce 100644 (file)
@@ -155,7 +155,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute
     GeomValidators_ShapeType aShapeTypeValidator;
     if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
       theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, \
-                  whole sketch(if it has at least one face), and whole objects with shape types: ";
+whole sketch(if it has at least one face), and whole objects with shape types: ";
       std::list<std::string>::const_iterator anIt = theArguments.cbegin();
       theError += *anIt;
       for(++anIt; anIt != theArguments.cend(); ++anIt) {
index 07934033764ab84aac238efee6b556d6b1132aac..f4984ca051f7cb28ab60abb19b2b6190c4847604 100755 (executable)
@@ -808,7 +808,7 @@ void PartSet_Module::editFeature(FeaturePtr theFeature)
 
 bool PartSet_Module::canCommitOperation() const
 {
-  return PartSet_WidgetSketchCreator::canCommitCurrentSketch(myWorkshop);
+  return true;
 }
 
 void PartSet_Module::launchOperation(const QString& theCmdId)
index 26b7481578766d01e4be63443dd54d0b11df5d99..cc3f93362a60c5d7d613b55cf1a26c5dc5061e26 100644 (file)
@@ -48,6 +48,8 @@
 #include <QMessageBox>
 #include <QMainWindow>
 
+//#define DEBUG_UNDO_INVALID_SKETCH
+
 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, 
                                                          PartSet_Module* theModule,
                                                          const Config_WidgetAPI* theData)
@@ -68,6 +70,7 @@ PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent,
   myLabel = new QLabel(aLabelText, this);
   myLabel->setWordWrap(true);
   aLayout->addWidget(myLabel);
+  aLayout->addStretch(1);
   /*if (!aLabelIcon.isEmpty())
     myLabel->setPixmap(QPixmap(aLabelIcon));
 
@@ -127,7 +130,7 @@ AttributePtr PartSet_WidgetSketchCreator::attribute() const
 }
 
 //********************************************************************
-void PartSet_WidgetSketchCreator::openTransaction()
+void PartSet_WidgetSketchCreator::openExtrusionTransaction()
 {
   SessionPtr aMgr = ModelAPI_Session::get();
   bool aIsOp = aMgr->isOperation();
@@ -233,96 +236,6 @@ 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()) {
-      // selection attribute list is currently filled in execute(), so we need to call it
-      // if there is no opened transaction, it should be started and finished
-      SessionPtr aMgr = ModelAPI_Session::get();
-      bool aIsOp = aMgr->isOperation();
-      if (!aIsOp)
-        aMgr->startOperation();
-
-      std::list<AttributePtr> aSelListAttributes = aParentFeature->data()->attributes(
-                                                        ModelAPI_AttributeSelectionList::typeId());
-      if (aSelListAttributes.size() == 1) {
-        AttributePtr aFirstAttribute = aSelListAttributes.front();
-        /// Sub-feature of the composite should be set in the base list.
-        setSketchObjectToList(aPCompositeFeature, aFirstAttribute);
-
-        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;
-        }
-      }
-      if (!aIsOp) {
-        if (aCanCommit)
-          aMgr->finishOperation();
-        else
-          aMgr->abortOperation();
-      }
-    }
-  }
-  return aCanCommit;
-}
-
-void PartSet_WidgetSketchCreator::setSketchObjectToList(const CompositeFeaturePtr& theCompositeFeature,
-                                                        const AttributePtr& theAttribute)
-{
-  if (!theCompositeFeature.get() || theCompositeFeature->numberOfSubs() != 1)
-    return;
-
-  AttributeSelectionListPtr aBaseObjectsSelectionList =
-                     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
-  if(!aBaseObjectsSelectionList.get() || aBaseObjectsSelectionList->isInitialized()) {
-    return;
-  }
-
-  FeaturePtr aSketchFeature = theCompositeFeature->subFeature(0);
-  if(!aSketchFeature.get() || aSketchFeature->results().empty()) {
-    return;
-  }
-
-  ResultPtr aSketchRes = aSketchFeature->results().front();
-  ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
-  if(!aConstruction.get()) {
-    return;
-  }
-
-  if(aBaseObjectsSelectionList->size() == 0) {
-    aBaseObjectsSelectionList->append(aSketchRes, GeomShapePtr());
-  }
-}
-
 bool PartSet_WidgetSketchCreator::isSelectionMode() const
 {
   AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
@@ -416,18 +329,16 @@ bool PartSet_WidgetSketchCreator::startSketchOperation(const QList<ModuleBase_Vi
 
 bool PartSet_WidgetSketchCreator::focusTo()
 {
-  if (isSelectionMode()) {
+  // this method is called only in creation mode. In Edition mode this widget is hidden
+  CompositeFeaturePtr aCompFeature = 
+      std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
+  if (isSelectionMode() && aCompFeature->numberOfSubs() == 0) {
     activateSelectionControl();
-    // Open transaction that is general for the previous nested one: it will be closed on nested commit
-    openTransaction();
+    openExtrusionTransaction();
     return true;
   }
-  else {
+  else
     connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
-    // Open transaction that is general for the previous nested one: it will be closed on nested commit
-    openTransaction();
-    restoreValue();
-  }
   return false;
 }
 
@@ -444,80 +355,143 @@ void PartSet_WidgetSketchCreator::deactivate()
 
 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
 {
-  XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
+  SessionPtr aMgr = ModelAPI_Session::get();
+  bool aIsOp = aMgr->isOperation();
+  if (aIsOp) {
+    // in current implementation, all transactions are closed when resume happens
+    // so, this is a wrong case, which is not checked.
+    // To provide it, make correction in later rows about abort/undo transactions
+    return;
+  }
+  // Set visible only selection control
+  setVisibleSelectionControl(true);
 
+  // Validate the created sketch. If it is valid, it is set into the composite feature selection
+  // list, otherwise it is removed
   CompositeFeaturePtr aCompFeature = 
     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
-  //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);
-    
+  AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
+  if (aCompFeature->numberOfSubs() > 0) {
+    // set the sub feature to attribute selection list and check whether sketch is valid
     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) {
+    const static std::string aNestedOpID("Set Sketch result into Selection list");
+    aMgr->startOperation(aNestedOpID, false); // false to not attach to Extrusion operation
+    setSketchObjectToList(aCompFeature, anAttrList);
+    aMgr->finishOperation();
+
+    if (!validateSelectionList()) {
+#ifdef DEBUG_UNDO_INVALID_SKETCH
+      aMgr->undo(); // Extrusion modification parameters: setSketchObjectToList()
+      aMgr->undo(); /// Sketch creation
+#else
+      aMgr->startOperation("Delete invalid Sketch feature", false);
+
+      // delete invalid sketch
       CompositeFeaturePtr aSketchFeature = 
-               std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
-
+              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();
+      XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
+      aWorkshop->deleteFeatures(anObjects, std::set<FeaturePtr>());
+
+      aMgr->finishOperation();
+#endif
     }
-    else {
-      setVisibleSelectionControl(false);
-      // Update value in attribute selection list
-      XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
-      const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
-      foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
-        if (aWidget->attributeID() == myAttributeListID)
-          aWidget->restoreValue();
-      }
+  }
+  openExtrusionTransaction();
 
-      // 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) {
-        (*aIt)->setDisplayed(false);
-      }
-      aSketchFeature->setDisplayed(false);
-      static Events_Loop* aLoop = Events_Loop::loop();
-      aLoop->flush(aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY));
-
-      // Add Selected body were created the sketcher to list of selected objects
-      std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::OBJECTS_ID();
-      AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
-      if (aSelList.get()) {
-        DataPtr aData = aSketchFeature->data();
-        AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
-                                      (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
-        ResultPtr aRes = aSelAttr.get() ? aSelAttr->context() : ResultPtr();
-        if (aRes.get()) {
-          SessionPtr aMgr = ModelAPI_Session::get();
-          ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
-          AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
-          std::string aValidatorID, anError;
-          aSelList->append(aRes, GeomShapePtr());
-          if (aFactory->validate(anAttribute, aValidatorID, anError))
-            updateObject(aCompFeature);
-          else
-            aSelList->clear();
-        }
+  if (aCompFeature->numberOfSubs() > 0) {
+    // check if the created sketch is valid. If it is invalid, it will be deleted with warning else
+    /// the attribute selection list will be filled by result of this sketch.
+    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) {
+      if (aWidget->attributeID() == myAttributeListID)
+        aWidget->restoreValue();
+    }
+
+    // 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) {
+      (*aIt)->setDisplayed(false);
+    }
+    aSketchFeature->setDisplayed(false);
+    static Events_Loop* aLoop = Events_Loop::loop();
+    aLoop->flush(aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+
+    // Add Selected body were created the sketcher to list of selected objects
+    std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::OBJECTS_ID();
+    AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
+    if (aSelList.get()) {
+      DataPtr aData = aSketchFeature->data();
+      AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
+                                    (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
+      ResultPtr aRes = aSelAttr.get() ? aSelAttr->context() : ResultPtr();
+      if (aRes.get()) {
+        SessionPtr aMgr = ModelAPI_Session::get();
+        ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+        AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
+        std::string aValidatorID, anError;
+        aSelList->append(aRes, GeomShapePtr());
+        if (aFactory->validate(anAttribute, aValidatorID, anError))
+          updateObject(aCompFeature);
+        else
+          aSelList->clear();
       }
     }
   }
+  restoreValue();
+}
+
+bool PartSet_WidgetSketchCreator::validateSelectionList() const
+{
+  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 (!isValidPComposite) {
+    XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
+    QMessageBox::question(aWorkshop->desktop(), tr("Apply current feature"),
+                  tr("Sketch is invalid and will be deleted.\nError: %1").arg(anError.c_str()),
+                  QMessageBox::Ok);
+  }
+  return isValidPComposite;
+}
+
+void PartSet_WidgetSketchCreator::setSketchObjectToList(const CompositeFeaturePtr& theCompositeFeature,
+                                                        const AttributePtr& theAttribute)
+{
+  if (!theCompositeFeature.get() || theCompositeFeature->numberOfSubs() != 1)
+    return;
+
+  AttributeSelectionListPtr aBaseObjectsSelectionList =
+                     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  if(!aBaseObjectsSelectionList.get() || aBaseObjectsSelectionList->isInitialized()) {
+    return;
+  }
+
+  FeaturePtr aSketchFeature = theCompositeFeature->subFeature(0);
+  if(!aSketchFeature.get() || aSketchFeature->results().empty()) {
+    return;
+  }
+
+  ResultPtr aSketchRes = aSketchFeature->results().front();
+  ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
+  if(!aConstruction.get()) {
+    return;
+  }
+
+  if(aBaseObjectsSelectionList->size() == 0) {
+    aBaseObjectsSelectionList->append(aSketchRes, GeomShapePtr());
+  }
 }
index 1c24c125468b6e2bdb2f0bad2bec3df56bc32218..b7b8b2f40df2969545389fc8c0ef55e198f426a9 100644 (file)
@@ -70,19 +70,10 @@ public:
   /// \return a boolean value
   virtual bool isValidSelection(const ModuleBase_ViewerPrs& theValue);
 
-  /// 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);
-
-  /// Sets the sub-object to list of base.
-  static void setSketchObjectToList(const CompositeFeaturePtr& theFeature,
-                                    const AttributePtr& theAttribute);
-
 protected:
   /// If there is no operation in current session, start operation for modify parameters
-  void openTransaction();
+  /// \return true if the operation was not opened
+  void openExtrusionTransaction();
 
   /// Checks whether the selection presentation contains preview planes
   /// \param theValue a selection information
@@ -135,6 +126,14 @@ private:
   /// \return true if the sketch is started
   bool startSketchOperation(const QList<ModuleBase_ViewerPrs>& theValues);
 
+  /// Sets the sub-object to list of base.
+  static void setSketchObjectToList(const CompositeFeaturePtr& theFeature,
+                                    const AttributePtr& theAttribute);
+
+  /// Calls validator for attribute list and warn if it is not valid
+  /// \return true if validation succeed
+  bool validateSelectionList() const;
+
 private:
   std::string myAttributeListID;
 
index 3ed4d9a5aa511a4ce44cfabff2b812750f19b81b..9f29412ebda7f1d0e7ff34134d0bc996d9c72d05 100644 (file)
@@ -339,7 +339,7 @@ void XGUI_OperationMgr::setCurrentFeature(const FeaturePtr& theFeature)
   DocumentPtr aDoc = aMgr->activeDocument();
   bool aIsOp = aMgr->isOperation();
   if (!aIsOp)
-    aMgr->startOperation();
+    aMgr->startOperation(QString("Set current feature: %1").arg(theFeature->getKind().c_str()).toStdString());
   aDoc->setCurrentFeature(theFeature, false);
   if (!aIsOp)
     aMgr->finishOperation();