From: nds Date: Wed, 23 Mar 2016 17:16:46 +0000 (+0300) Subject: Issue #1343 Improvement of Extrusion and Revolution operations: delete of inappropria... X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=13d999348a9c792e06c7771a5ecaed5cf453fa1e;p=modules%2Fshaper.git Issue #1343 Improvement of Extrusion and Revolution operations: delete of inappropriate sketch for extrusion. --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index 36ca2939f..cd843949f 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -177,6 +177,14 @@ void FeaturesPlugin_Extrusion::execute() removeResults(aResultIndex); } +//================================================================================================= +void FeaturesPlugin_Extrusion::removeFeature(std::shared_ptr theFeature) +{ + AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID()); + if (aFacesSelectionList.get() && aFacesSelectionList->size() > 0) + aFacesSelectionList->clear(); +} + //================================================================================================= void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo, std::shared_ptr theResultBody, @@ -239,3 +247,4 @@ void FeaturesPlugin_Extrusion::setSketchObjectToList() } } } + diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h index cc0005081..a8867530e 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h @@ -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 theFeature); + /// Use plugin manager for features creation FeaturesPlugin_Extrusion(); diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index 1cf80deb2..3dc5813d5 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -3,9 +3,10 @@ diff --git a/src/GeomValidators/GeomValidators_FeatureKind.cpp b/src/GeomValidators/GeomValidators_FeatureKind.cpp index cdf2ebd7b..edf205f05 100755 --- a/src/GeomValidators/GeomValidators_FeatureKind.cpp +++ b/src/GeomValidators/GeomValidators_FeatureKind.cpp @@ -11,6 +11,11 @@ #include #include +//#define DEBUG_EXTRUSION_INVALID_SKETCH +#ifdef DEBUG_EXTRUSION_INVALID_SKETCH + #include +#endif + bool GeomValidators_FeatureKind::isValid(const AttributePtr& theAttribute, const std::list& 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(aFeature); + if (aComp.get() && aComp->numberOfSubs() == 1) + return false; +#endif } } } diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index 016564178..45d070997 100755 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -73,6 +73,10 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject /// \param theFeature feature for editing virtual void editFeature(FeaturePtr theFeature); + /// Returns true if the operation can be committed. Result in default implementation is true. + /// \return boolean value + virtual bool canCommitOperation() const { return true; } + /// Creates an operation and send it to loop /// \param theCmdId the operation name virtual void launchOperation(const QString& theCmdId); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 9219dbaf0..925888725 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -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() && diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index cb7d86131..00af4f358 100755 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -91,6 +91,10 @@ public: virtual bool createWidgets(ModuleBase_Operation* theOperation, QList& 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); diff --git a/src/PartSet/PartSet_WidgetSketchCreator.cpp b/src/PartSet/PartSet_WidgetSketchCreator.cpp index bd70b0f0a..24e0f5f50 100644 --- a/src/PartSet/PartSet_WidgetSketchCreator.cpp +++ b/src/PartSet/PartSet_WidgetSketchCreator.cpp @@ -45,6 +45,7 @@ //#include #include #include +#include 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(anOperation); + FeaturePtr aCurrentFeature = aFOperation ? aFOperation->feature() : FeaturePtr(); + + ModuleBase_Operation* aPOperation = anOpMgr->previousOperation(anOperation); + ModuleBase_OperationFeature* aFPOperation = dynamic_cast(aPOperation); + FeaturePtr aParentFeature = aFPOperation ? aFPOperation->feature() : FeaturePtr(); + + CompositeFeaturePtr aCompositeFeature = + std::dynamic_pointer_cast(aCurrentFeature); + CompositeFeaturePtr aPCompositeFeature = + std::dynamic_pointer_cast(aParentFeature); + // check if both features are composite: extrusion and sketch + if (aCompositeFeature.get() && aPCompositeFeature.get()) { + aPCompositeFeature->execute(); // to fill attribute selection list + std::list 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(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& theValues) @@ -258,17 +307,11 @@ bool PartSet_WidgetSketchCreator::startSketchOperation(const QListworkshop()); - 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(myFeature); - CompositeFeaturePtr aSketchFeature = - std::dynamic_pointer_cast(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(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(aCompFeature->subFeature(0)); + + QObjectPtrList anObjects; + anObjects.append(aSketchFeature); + std::set 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& 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(aCompFeature->subFeature(0)); std::list aResults = aSketchFeature->results(); std::list::const_iterator aIt; for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { diff --git a/src/PartSet/PartSet_WidgetSketchCreator.h b/src/PartSet/PartSet_WidgetSketchCreator.h index e0e6276e5..7a341689d 100644 --- a/src/PartSet/PartSet_WidgetSketchCreator.h +++ b/src/PartSet/PartSet_WidgetSketchCreator.h @@ -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); diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 79657c302..0e0e4c1d7 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -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 (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() diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index 3b08ba8b9..c29502925 100755 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -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.