X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherMgr.cpp;h=b4cf246eac2e7827d57f60dcd9e7cbe781d99850;hb=857b1f72d9703c46c6c8c9bb239821d314344c86;hp=1385c097030fa9f7895880d1167e75811f4ce912;hpb=9ddba1caf0817c1e95c55d4c5b8ae6de23cbe6d5;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 1385c0970..b4cf246ea 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -11,9 +11,6 @@ #include "PartSet_Tools.h" #include "PartSet_WidgetSketchLabel.h" -#include -#include - #include #include #include @@ -25,13 +22,16 @@ #include #include +#include +#include #include #include #include +#include #include -#include -#include +#include #include +#include #include @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,7 @@ #include #include +#include #include #include @@ -190,7 +192,9 @@ void PartSet_SketcherMgr::onEnterViewPort() // redisplayed before this update, the feature presentation jumps from reset value to current. myIsMouseOverWindow = true; myIsResetCurrentValue = false; - operationMgr()->onValidateOperation(); + // it is important to validate operation here only if sketch entity create operation is active + // because at this operation we reacts to the mouse leave/enter view port + //operationMgr()->onValidateOperation(); #ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS qDebug(QString("onEnterViewPort: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str()); #endif @@ -201,16 +205,20 @@ void PartSet_SketcherMgr::onEnterViewPort() if (!isNestedCreateOperation(getCurrentOperation())) return; + operationMgr()->onValidateOperation(); + // we need change displayed state of the current operation feature // if the feature is presentable, e.g. distance construction. It has no results, so workshop does // not accept a signal about the result created. Nothing is shown until mouse is moved out/in view // port. If the isDisplayed flag is true, the presentable feature is displayed as soon as the // presentation becomes valid and redisplay happens - ModuleBase_Operation* aOperation = getCurrentOperation(); - if (aOperation) { - FeaturePtr aFeature = aOperation->feature(); + //ModuleBase_Operation* aOperation = getCurrentOperation(); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); if (aFeature.get() && aFeature->data()->isValid()) { - visualizeFeature(aOperation, canDisplayObject(aFeature), false); + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature), false); } } } @@ -219,7 +227,9 @@ void PartSet_SketcherMgr::onLeaveViewPort() { myIsMouseOverViewProcessed = false; myIsMouseOverWindow = false; - operationMgr()->onValidateOperation(); + // it is important to validate operation here only if sketch entity create operation is active + // because at this operation we reacts to the mouse leave/enter view port + //operationMgr()->onValidateOperation(); #ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS qDebug(QString("onLeaveViewPort: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str()); #endif @@ -235,6 +245,8 @@ void PartSet_SketcherMgr::onLeaveViewPort() if (myIsPopupMenuActive) return; + operationMgr()->onValidateOperation(); + // 2. if the mouse IS NOT over window, reset the active widget value and hide the presentation ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); @@ -253,12 +265,18 @@ void PartSet_SketcherMgr::onLeaveViewPort() // hides the presentation of the current operation feature // the feature is to be erased here, but it is correct to call canDisplayObject because // there can be additional check (e.g. editor widget in distance constraint) - FeaturePtr aFeature = getCurrentOperation()->feature(); - visualizeFeature(aOperation, canDisplayObject(aFeature)); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); + } } void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel() { + myIsResetCurrentValue = false; + if (isNestedCreateOperation(getCurrentOperation())) return; // it is necessary to save current selection in order to restore it after the values are modifed @@ -294,13 +312,16 @@ void PartSet_SketcherMgr::onValuesChangedInPropertyPanel() return; // visualize the current operation feature - myIsResetCurrentValue = false; + //myIsResetCurrentValue = false; operationMgr()->onValidateOperation(); - ModuleBase_Operation* aOperation = getCurrentOperation(); // the feature is to be erased here, but it is correct to call canDisplayObject because // there can be additional check (e.g. editor widget in distance constraint) - FeaturePtr aFeature = getCurrentOperation()->feature(); - visualizeFeature(aOperation, canDisplayObject(aFeature)); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); + } } void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) @@ -319,9 +340,13 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE if (!aViewer->canDragByMouse()) return; - ModuleBase_Operation* aOperation = getCurrentOperation(); - if (aOperation && aOperation->isEditOperation()) { - ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (!aFOperation) + return; + + if (aFOperation->isEditOperation()) { + ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget(); // If the current widget is a selector, do nothing, it processes the mouse press if(aActiveWgt && aActiveWgt->isViewerSelector()) { @@ -330,18 +355,18 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE } // Use only for sketch operations - if (aOperation && myCurrentSketch) { + if (myCurrentSketch) { if (!PartSet_Tools::sketchPlane(myCurrentSketch)) return; - bool isSketcher = isSketchOperation(aOperation); - bool isSketchOpe = isNestedSketchOperation(aOperation); + bool isSketcher = isSketchOperation(aFOperation); + bool isSketchOpe = isNestedSketchOperation(aFOperation); // Avoid non-sketch operations if ((!isSketchOpe) && (!isSketcher)) return; - bool isEditing = aOperation->isEditOperation(); + bool isEditing = aFOperation->isEditOperation(); // Ignore creation sketch operation if ((!isSketcher) && (!isEditing)) @@ -359,8 +384,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE if (myCurrentSelection.empty()) { if (isSketchOpe && (!isSketcher)) // commit previous operation - if (!aOperation->commit()) - aOperation->abort(); + if (!aFOperation->commit()) + aFOperation->abort(); return; } // Init flyout point for radius rotation @@ -384,7 +409,7 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE } } else if (isSketchOpe && isEditing) { // If selected another object commit current result - aOperation->commit(); + aFOperation->commit(); myIsDragging = true; get2dPoint(theWnd, theEvent, myCurrentPoint); @@ -449,8 +474,12 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve } // the feature is to be erased here, but it is correct to call canDisplayObject because // there can be additional check (e.g. editor widget in distance constraint) - FeaturePtr aFeature = getCurrentOperation()->feature(); - visualizeFeature(aOperation, canDisplayObject(aFeature)); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); + } } myClickedPoint.clear(); @@ -463,10 +492,10 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve ModuleBase_IViewer* aViewer = myModule->workshop()->viewer(); aViewer->enableSelection(false); - ModuleBase_Operation* aOperation = getCurrentOperation(); - if (!aOperation) + ModuleBase_Operation* aCurrentOperation = getCurrentOperation(); + if (!aCurrentOperation) return; - if (isSketchOperation(aOperation)) + if (isSketchOperation(aCurrentOperation)) return; // No edit operation activated Handle(V3d_View) aView = theWnd->v3dView(); @@ -489,6 +518,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve FeatureToSelectionMap::const_iterator anIt = myCurrentSelection.begin(), aLast = myCurrentSelection.end(); // 4. the features and attributes modification(move) + bool isModified = false; for (; anIt != aLast; anIt++) { FeaturePtr aFeature = anIt.key(); @@ -509,6 +539,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve if (aPoint.get() != NULL) { bool isImmutable = aPoint->setImmutable(true); aPoint->move(dX, dY); + isModified = true; ModelAPI_EventCreator::get()->sendUpdated(aFeature, aMoveEvent); aPoint->setImmutable(isImmutable); } @@ -520,10 +551,16 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve std::dynamic_pointer_cast(aFeature); if (aSketchFeature) { aSketchFeature->move(dX, dY); + isModified = true; ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, aMoveEvent); } } } + // the modified state of the current operation should be updated if there are features, which + // were changed here + if (isModified) { + aCurrentOperation->onValuesChanged(); + } Events_Loop::loop()->flush(aMoveEvent); // up all move events - to be processed in the solver //Events_Loop::loop()->flush(aUpdateEvent); // up update events - to redisplay presentations @@ -540,13 +577,14 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { - ModuleBase_Operation* aOperation = getCurrentOperation(); - if (aOperation && aOperation->isEditOperation()) { - std::string aId = aOperation->id().toStdString(); - if (isDistanceOperation(aOperation)) + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation && aFOperation->isEditOperation()) { + std::string aId = aFOperation->id().toStdString(); + if (isDistanceOperation(aFOperation)) { // Activate dimension value editing on double click - ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); QList aWidgets = aPanel->modelWidgets(); // Find corresponded widget to activate value editing foreach (ModuleBase_ModelWidget* aWgt, aWidgets) { @@ -629,6 +667,17 @@ void PartSet_SketcherMgr::launchEditing() } } +bool PartSet_SketcherMgr::sketchSolverError() +{ + bool anError = false; + CompositeFeaturePtr aSketch = activeSketch(); + if (aSketch.get()) { + AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR()); + anError = !aAttributeString->value().empty(); + } + return anError; +} + const QStringList& PartSet_SketcherMgr::sketchOperationIdList() { @@ -660,6 +709,7 @@ const QStringList& PartSet_SketcherMgr::constraintsIdList() aIds << SketchPlugin_ConstraintTangent::ID().c_str(); aIds << SketchPlugin_ConstraintCoincidence::ID().c_str(); aIds << SketchPlugin_ConstraintMirror::ID().c_str(); + aIds << SketchPlugin_ConstraintAngle::ID().c_str(); aIds << SketchPlugin_MultiRotation::ID().c_str(); aIds << SketchPlugin_MultiTranslation::ID().c_str(); } @@ -690,7 +740,9 @@ bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOpera bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation) { - return theOperation && !theOperation->isEditOperation() && isNestedSketchOperation(theOperation); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + return aFOperation && !aFOperation->isEditOperation() && isNestedSketchOperation(aFOperation); } bool PartSet_SketcherMgr::isEntity(const std::string& theId) @@ -707,15 +759,21 @@ bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation return (aId == SketchPlugin_ConstraintLength::ID()) || (aId == SketchPlugin_ConstraintDistance::ID()) || - (aId == SketchPlugin_ConstraintRadius::ID()); + (aId == SketchPlugin_ConstraintRadius::ID()) || + (aId == SketchPlugin_ConstraintAngle::ID()); } void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (!aFOperation) + return; + myModule->onViewTransformed(); // Display all sketcher sub-Objects - myCurrentSketch = std::dynamic_pointer_cast(theOperation->feature()); + myCurrentSketch = std::dynamic_pointer_cast(aFOperation->feature()); XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); // Hide sketcher result @@ -743,22 +801,23 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter); bool aHasPlane = false; - if (theOperation->isEditOperation()) { + std::shared_ptr aPln; + if (aFOperation->isEditOperation()) { // If it is editing of sketch then it means that plane is already defined - std::shared_ptr aPln = PartSet_Tools::sketchPlane(myCurrentSketch); - if (aPln.get()) { - myPlaneFilter->setPlane(aPln->impl()); + aPln = PartSet_Tools::sketchPlane(myCurrentSketch); + if (aPln.get()) aHasPlane = true; - } } + myPlaneFilter->setPlane(aPln); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); // all sketch objects should be activated in the sketch selection modes by edit operation start // in case of creation operation, there is an active widget, which activates own selection mode - if (theOperation->isEditOperation() && aHasPlane) + if (aFOperation->isEditOperation() && aHasPlane) aConnector->activateModuleSelectionModes(); } -void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) +void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* /* theOperation*/) { myIsMouseOverWindow = false; myIsConstraintsShown = true; @@ -784,28 +843,33 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) } } else { - // Hide all sketcher sub-Objects - for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = myCurrentSketch->subFeature(i); - std::list aResults = aFeature->results(); + // Hide all sketcher sub-Objects + for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + FeaturePtr aFeature = myCurrentSketch->subFeature(i); + std::list aResults = aFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + (*aIt)->setDisplayed(false); + } + aFeature->setDisplayed(false); + } + // Display sketcher result + std::list aResults = myCurrentSketch->results(); std::list::const_iterator aIt; + Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID aDispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - (*aIt)->setDisplayed(false); + (*aIt)->setDisplayed(true); + // this display event is needed because sketch already may have "displayed" state, + // but not displayed while it is still active (issue 613, abort of existing sketch) + ModelAPI_EventCreator::get()->sendUpdated(*aIt, aDispEvent); } - aFeature->setDisplayed(false); - } - // Display sketcher result - std::list aResults = myCurrentSketch->results(); - std::list::const_iterator aIt; - for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - (*aIt)->setDisplayed(true); - } - myCurrentSketch->setDisplayed(true); + myCurrentSketch->setDisplayed(true); - myCurrentSketch = CompositeFeaturePtr(); - myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); + myCurrentSketch = CompositeFeaturePtr(); + myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + Events_Loop::loop()->flush(aDispEvent); } // restore the module selection modes, which were changed on startSketch aConnector->activateModuleSelectionModes(); @@ -831,11 +895,15 @@ void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOp) void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation) { if (isNestedCreateOperation(theOperation)) { - FeaturePtr aFeature = theOperation->feature(); - // it is necessary to check the the feature data validity because - // some kind of features are removed by an operation commit(the macro state of a feature) - if (aFeature.get() && aFeature->data()->isValid()) { - visualizeFeature(theOperation, true); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + // it is necessary to check the the feature data validity because + // some kind of features are removed by an operation commit(the macro state of a feature) + if (aFeature.get() && aFeature->data()->isValid()) { + visualizeFeature(aFeature, aFOperation->isEditOperation(), true); + } } } } @@ -860,6 +928,28 @@ bool PartSet_SketcherMgr::canCommitOperation() const return aCanCommit; } +bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const +{ + bool aCanErase = true; + // when the sketch operation is active, results of sketch sub-feature can not be hidden + if (myCurrentSketch.get()) { + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) { + // Display sketcher objects + for (int i = 0; i < myCurrentSketch->numberOfSubs() && aCanErase; i++) { + + FeaturePtr aFeature = myCurrentSketch->subFeature(i); + std::list aResults = aFeature->results(); + std::list::const_iterator anIt; + for (anIt = aResults.begin(); anIt != aResults.end() && aCanErase; ++anIt) { + aCanErase = *anIt != aResult; + } + } + } + } + return aCanErase; +} + bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const { bool aCanDisplay = true; @@ -889,9 +979,10 @@ bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const // 3. the method should not filter the objects, which are not related to the current operation. // The object is filtered just if it is a current operation feature or this feature result bool isObjectFound = false; - ModuleBase_Operation* anOperation = getCurrentOperation(); - if (anOperation) { - FeaturePtr aFeature = anOperation->feature(); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); if (aFeature.get()) { std::list aResults = aFeature->results(); if (theObject == aFeature) @@ -956,7 +1047,10 @@ bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr& thePln) { - myPlaneFilter->setPlane(thePln->impl()); + if (myPlaneFilter.IsNull()) + myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); + + myPlaneFilter->setPlane(thePln); } void PartSet_SketcherMgr::getCurrentSelection(const FeaturePtr& theFeature, @@ -1105,7 +1199,8 @@ ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const return myModule->workshop()->currentOperation(); } -void PartSet_SketcherMgr::visualizeFeature(ModuleBase_Operation* theOperation, +void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature, + const bool isEditOperation, const bool isToDisplay, const bool isFlushRedisplay) { @@ -1113,7 +1208,7 @@ void PartSet_SketcherMgr::visualizeFeature(ModuleBase_Operation* theOperation, return; #endif - if (!theOperation || theOperation->isEditOperation()) + if (isEditOperation || !theFeature.get()) return; ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); @@ -1121,12 +1216,12 @@ void PartSet_SketcherMgr::visualizeFeature(ModuleBase_Operation* theOperation, // 1. change visibility of the object itself, here the presentable object is processed, // e.g. constraints features - FeaturePtr aFeature = theOperation->feature(); - std::list aResults = aFeature->results(); + //FeaturePtr aFeature = aFOperation->feature(); + std::list aResults = theFeature->results(); if (isToDisplay) - aFeature->setDisplayed(true); + theFeature->setDisplayed(true); else - aFeature->setDisplayed(false); + theFeature->setDisplayed(false); // change visibility of the object results, e.g. non-constraint features std::list::const_iterator aIt;