X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherMgr.cpp;h=7937a60c337249dc43e58308367d78e723b3951f;hb=e6655db718a3c9dad621d3990d9ff4c833ac1532;hp=403fb7b1f7cd7f9db785ca104cdab73d93154c2d;hpb=7b40a96da76a35be80875b1d3f97abb4ca15189a;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 403fb7b1f..7937a60c3 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -6,12 +6,14 @@ #include "PartSet_SketcherMgr.h" #include "PartSet_Module.h" -#include "PartSet_WidgetPoint2D.h" +#include "PartSet_WidgetPoint2d.h" #include "PartSet_Tools.h" #include #include #include +#include +#include #include #include @@ -21,6 +23,8 @@ #include #include +#include + #include #include @@ -35,28 +39,61 @@ #include #include +#include +#include + #include #include #include - - /// Returns list of unique objects by sum of objects from List1 and List2 -QList getSumList(const QList& theList1, +/*QList getSumList(const QList& theList1, const QList& theList2) { - QList aRes; + QList aRes; foreach (ModuleBase_ViewerPrs aPrs, theList1) { - if (!aRes.contains(aPrs.object())) - aRes.append(aPrs.object()); + if (!aRes.contains(aPrs)) + aRes.append(aPrs); } foreach (ModuleBase_ViewerPrs aPrs, theList2) { - if (!aRes.contains(aPrs.object())) - aRes.append(aPrs.object()); + if (!aRes.contains(aPrs)) + aRes.append(aPrs); } return aRes; +}*/ + +void fillFeature2Attribute(const QList& theList, + QMap >& theFeature2AttributeMap, + const FeaturePtr theSketch) +{ + QList aRes; + + QList::const_iterator anIt = theList.begin(), + aLast = theList.end(); + for (; anIt != aLast; anIt++) + { + ModuleBase_ViewerPrs aPrs = *anIt; + FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object()); + if (aFeature.get() == NULL) + continue; + + QList anAttributes; + if (theFeature2AttributeMap.contains(aFeature)) { + anAttributes = theFeature2AttributeMap[aFeature]; + } + AttributePtr anAttr; + TopoDS_Shape aShape = aPrs.shape(); + if (!aShape.IsNull()) { + if (aShape.ShapeType() == TopAbs_VERTEX) { + anAttr = PartSet_Tools::findAttributeBy2dPoint(aFeature, aShape, theSketch); + if (anAttr.get() != NULL && !anAttributes.contains(anAttr)) + anAttributes.push_back(anAttr); + } + } + theFeature2AttributeMap[aFeature] = anAttributes; + } } @@ -68,6 +105,8 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule) ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = aWorkshop->viewer(); + myPreviousSelectionEnabled = true;//aViewer->isSelectionEnabled(); + connect(aViewer, SIGNAL(mousePress(ModuleBase_IViewWindow*, QMouseEvent*)), this, SLOT(onMousePressed(ModuleBase_IViewWindow*, QMouseEvent*))); @@ -113,81 +152,47 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE if ((!isSketcher) && (!isEditing)) return; - if (theEvent->modifiers()) { - // If user performs multiselection - if (isSketchOpe /* && (!isSketcher)*/) - if (!aOperation->commit()) - aOperation->abort(); - return; - } + // MoveTo in order to highlight current object + ModuleBase_IViewer* aViewer = aWorkshop->viewer(); + aViewer->AISContext()->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView()); + // Remember highlighted objects for editing ModuleBase_ISelection* aSelect = aWorkshop->selection(); QList aHighlighted = aSelect->getHighlighted(); QList aSelected = aSelect->getSelected(); - myEditingFeatures.clear(); - myEditingAttr.clear(); + myFeature2AttributeMap.clear(); bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); - QObjectPtrList aSelObjects; - if (aHasShift) - aSelObjects = getSumList(aHighlighted, aSelected); + if (aHasShift) { + fillFeature2Attribute(aHighlighted, myFeature2AttributeMap, myCurrentSketch); + fillFeature2Attribute(aSelected, myFeature2AttributeMap, myCurrentSketch); + } else { - foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) { - aSelObjects.append(aPrs.object()); - } + fillFeature2Attribute(aHighlighted, myFeature2AttributeMap, myCurrentSketch); } - if ((aSelObjects.size() == 0)) { + + if (myFeature2AttributeMap.empty()) { if (isSketchOpe && (!isSketcher)) // commit previous operation if (!aOperation->commit()) aOperation->abort(); return; } - if ((aHighlighted.size() == 1) && (aSelected.size() == 0)) { - // Move by selected shape (vertex). Can be used only for single selection - foreach(ModuleBase_ViewerPrs aPrs, aHighlighted) { - FeaturePtr aFeature = ModelAPI_Feature::feature(aHighlighted.first().object()); - if (aFeature) { - myEditingFeatures.append(aFeature); - TopoDS_Shape aShape = aPrs.shape(); - if (!aShape.IsNull()) { - if (aShape.ShapeType() == TopAbs_VERTEX) { - AttributePtr aAttr = PartSet_Tools::findAttributeBy2dPoint(myEditingFeatures.first(), - aShape, myCurrentSketch); - if (aAttr) - myEditingAttr.append(aAttr); - } - } - } - } - } else { - // Provide multi-selection. Can be used only for features - foreach (ObjectPtr aObj, aSelObjects) { - FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); - if (aFeature && (!myEditingFeatures.contains(aFeature))) - myEditingFeatures.append(aFeature); - } - - } - // If nothing highlighted - return - if (myEditingFeatures.size() == 0) - return; if (isSketcher) { myIsDragging = true; + get2dPoint(theWnd, theEvent, myCurX, myCurY); myDragDone = false; - aWorkshop->viewer()->enableMultiselection(false); launchEditing(); } else if (isSketchOpe && isEditing) { - // If selected another object - aOperation->abort(); + // If selected another object commit current result + aOperation->commit(); myIsDragging = true; get2dPoint(theWnd, theEvent, myCurX, myCurY); myDragDone = false; - aWorkshop->viewer()->enableMultiselection(false); // This is necessary in order to finalize previous operation QApplication::processEvents(); @@ -208,33 +213,42 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse // Only for sketcher operations ModuleBase_IViewer* aViewer = aWorkshop->viewer(); if (myIsDragging) { + aWorkshop->viewer()->enableSelection(myPreviousSelectionEnabled); myIsDragging = false; if (myDragDone) { - aViewer->enableMultiselection(true); - aOp->commit(); - myEditingFeatures.clear(); - myEditingAttr.clear(); + //aOp->commit(); + myFeature2AttributeMap.clear(); + + // Reselect edited object + /*aViewer->AISContext()->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView()); + if (theEvent->modifiers() & Qt::ShiftModifier) + aViewer->AISContext()->ShiftSelect(); + else + aViewer->AISContext()->Select(); + */ return; } } - if (!aViewer->isMultiSelectionEnabled()) { - aViewer->enableMultiselection(true); - } - //aViewer->AISContext()->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView()); - //if (theEvent->modifiers() & Qt::ShiftModifier) - // aViewer->AISContext()->ShiftSelect(); - //else - // aViewer->AISContext()->Select(); } void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { if (myIsDragging) { + ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); + // 1. it is necessary to save current selection in order to restore it after the features moving + FeatureToSelectionMap aCurrentSelection; + getCurrentSelection(myFeature2AttributeMap, myCurrentSketch, aWorkshop, aCurrentSelection); + + // 2. the enable selection in the viewer should be temporary switched off in order to ignore + // mouse press signal in the viewer(it call Select for AIS context and the dragged objects are + // deselected). This flag should be restored in the slot, processed the mouse release signal. + ModuleBase_IViewer* aViewer = myModule->workshop()->viewer(); + aViewer->enableSelection(false); + ModuleBase_Operation* aOperation = myModule->workshop()->currentOperation(); if (aOperation->id().toStdString() == SketchPlugin_Sketch::ID()) return; // No edit operation activated - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED); Handle(V3d_View) aView = theWnd->v3dView(); gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView); double aX, aY; @@ -242,36 +256,70 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve double dX = aX - myCurX; double dY = aY - myCurY; - if ((aOperation->id().toStdString() == SketchPlugin_Line::ID()) && - (myEditingAttr.size() == 1) && - myEditingAttr.first()) { - // probably we have prehighlighted point - AttributePtr aAttr = myEditingAttr.first(); - std::string aAttrId = aAttr->id(); - ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); - QList aWidgets = aPanel->modelWidgets(); - // Find corresponded widget to provide dragging - foreach (ModuleBase_ModelWidget* aWgt, aWidgets) { - if (aWgt->attributeID() == aAttrId) { - PartSet_WidgetPoint2D* aWgt2d = dynamic_cast(aWgt); - if (aWgt2d) { - aWgt2d->setPoint(aWgt2d->x() + dX, aWgt2d->y() + dY); - break; + XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); + // 3. the flag to disable the update viewer should be set in order to avoid blinking in the + // viewer happens by deselect/select the modified objects. The flag should be restored after + // the selection processing. The update viewer should be also called. + bool isEnableUpdateViewer = aDisplayer->enableUpdateViewer(false); + + static Events_ID aMoveEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED); + //static Events_ID aUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + + FeatureToAttributesMap::const_iterator anIt = myFeature2AttributeMap.begin(), + aLast = myFeature2AttributeMap.end(); + // 4. the features and attributes modification(move) + for (; anIt != aLast; anIt++) { + FeaturePtr aFeature = anIt.key(); + + AttributeList anAttributes = anIt.value(); + // Process selection by attribute: the priority to the attribute + if (!anAttributes.empty()) { + AttributeList::const_iterator anAttIt = anAttributes.begin(), anAttLast = anAttributes.end(); + for (; anAttIt != anAttLast; anAttIt++) { + AttributePtr anAttr = *anAttIt; + if (anAttr.get() == NULL) + continue; + std::string aAttrId = anAttr->id(); + DataPtr aData = aFeature->data(); + if (aData.get() != NULL) { + std::shared_ptr aPoint = + std::dynamic_pointer_cast(aData->attribute(aAttrId)); + if (aPoint.get() != NULL) { + bool isImmutable = aPoint->setImmutable(true); + aPoint->move(dX, dY); + ModelAPI_EventCreator::get()->sendUpdated(aFeature, aMoveEvent); + aPoint->setImmutable(isImmutable); + } } } - } - } else { - foreach(FeaturePtr aFeature, myEditingFeatures) { + } else { + // Process selection by feature std::shared_ptr aSketchFeature = std::dynamic_pointer_cast(aFeature); - if (aSketchFeature) { + if (aSketchFeature) { aSketchFeature->move(dX, dY); - ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, anEvent); + ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, aMoveEvent); } } - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_MOVED)); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); } + 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 + + // 5. it is necessary to save current selection in order to restore it after the features moving + FeatureToSelectionMap::const_iterator aSIt = aCurrentSelection.begin(), + aSLast = aCurrentSelection.end(); + SelectMgr_IndexedMapOfOwner anOwnersToSelect; + for (; aSIt != aSLast; aSIt++) { + anOwnersToSelect.Clear(); + getSelectionOwners(aSIt->first, myCurrentSketch, aWorkshop, aCurrentSelection, + anOwnersToSelect); + aConnector->workshop()->selector()->setSelectedOwners(anOwnersToSelect, false); + } + + // 6. restore the update viewer flag and call this update + aDisplayer->enableUpdateViewer(isEnableUpdateViewer); + aDisplayer->updateViewer(); myDragDone = true; myCurX = aX; myCurY = aY; @@ -311,14 +359,22 @@ void PartSet_SketcherMgr::get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent void PartSet_SketcherMgr::launchEditing() { - if (myEditingFeatures.size() > 0) { - FeaturePtr aFeature = myEditingFeatures.first(); + // there should be activate the vertex selection mode because the edit can happens by the selected + // point + QIntList aModes; + aModes << TopAbs_VERTEX << TopAbs_EDGE; + XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); + aConnector->activateSubShapesSelection(aModes); + + if (!myFeature2AttributeMap.empty()) { + FeaturePtr aFeature = myFeature2AttributeMap.begin().key(); std::shared_ptr aSPFeature = std::dynamic_pointer_cast(aFeature); if (aSPFeature) { myModule->editFeature(aSPFeature); } } + } @@ -380,16 +436,26 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) { + XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); + DataPtr aData = myCurrentSketch->data(); if ((!aData) || (!aData->isValid())) { // The sketch was aborted myCurrentSketch = CompositeFeaturePtr(); myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); + + // Erase all sketcher objects + QStringList aSketchIds = sketchOperationIdList(); + QObjectPtrList aObjects = aDisplayer->displayedObjects(); + foreach (ObjectPtr aObj, aObjects) { + DataPtr aObjData = aObj->data(); + if ((!aObjData) || (!aObjData->isValid())) + aDisplayer->erase(aObj); + } return; } // Hide all sketcher sub-Objects - XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); - XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { FeaturePtr aFeature = myCurrentSketch->subFeature(i); std::list aResults = aFeature->results(); @@ -417,3 +483,124 @@ void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr& th { myPlaneFilter->setPlane(thePln->impl()); } + +void PartSet_SketcherMgr::getCurrentSelection(const FeatureToAttributesMap& theFeatureToAttributes, + const FeaturePtr& theSketch, + ModuleBase_IWorkshop* theWorkshop, + FeatureToSelectionMap& theSelection) +{ + FeatureToAttributesMap::const_iterator anIt = theFeatureToAttributes.begin(), + aLast = theFeatureToAttributes.end(); + for (; anIt != aLast; anIt++) { + FeaturePtr aFeature = anIt.key(); + getCurrentSelection(aFeature, theSketch, theWorkshop, theSelection); + } +} + +void PartSet_SketcherMgr::getCurrentSelection(const FeaturePtr& theFeature, + const FeaturePtr& theSketch, + ModuleBase_IWorkshop* theWorkshop, + FeatureToSelectionMap& theSelection) +{ + if (theFeature.get() == NULL) + return; + + std::set aSelectedAttributes; + std::set aSelectedResults; + + ModuleBase_IViewer* aViewer = theWorkshop->viewer(); + Handle(AIS_InteractiveContext) aContext = aViewer->AISContext(); + XGUI_ModuleConnector* aConnector = dynamic_cast(theWorkshop); + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); + + std::list aResults = theFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) + { + ResultPtr aResult = *aIt; + AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult); + if (aAISObj.get() == NULL) + continue; + Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); + for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) + { + Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast( + aContext->SelectedOwner()); + if (aBRepOwner.IsNull()) + continue; + Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast( + aBRepOwner->Selectable()); + if (anIO != anAISIO) + continue; + + if (aBRepOwner->HasShape()) { + const TopoDS_Shape& aShape = aBRepOwner->Shape(); + TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); + if (aShapeType == TopAbs_VERTEX) { + AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, + aShape, theSketch); + if (aPntAttr.get() != NULL) + aSelectedAttributes.insert(aPntAttr); + } + else if (aShapeType == TopAbs_EDGE && + aSelectedResults.find(aResult) == aSelectedResults.end()) { + aSelectedResults.insert(aResult); + } + } + } + } + theSelection[theFeature] = std::make_pair(aSelectedAttributes, aSelectedResults); +} + +void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, + const FeaturePtr& theSketch, + ModuleBase_IWorkshop* theWorkshop, + const FeatureToSelectionMap& theSelection, + SelectMgr_IndexedMapOfOwner& anOwnersToSelect) +{ + if (theFeature.get() == NULL) + return; + + FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature); + std::set aSelectedAttributes = anIt->second.first; + std::set aSelectedResults = anIt->second.second; + + ModuleBase_IViewer* aViewer = theWorkshop->viewer(); + Handle(AIS_InteractiveContext) aContext = aViewer->AISContext(); + XGUI_ModuleConnector* aConnector = dynamic_cast(theWorkshop); + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); + + std::list aResults = theFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) + { + ResultPtr aResult = *aIt; + AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult); + if (aAISObj.get() == NULL) + continue; + Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); + + SelectMgr_IndexedMapOfOwner aSelectedOwners; + aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners); + for ( Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++ ) { + Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(aSelectedOwners(i)); + if ( anOwner.IsNull() || !anOwner->HasShape() ) + continue; + const TopoDS_Shape& aShape = anOwner->Shape(); + TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); + if (aShapeType == TopAbs_VERTEX) { + AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch); + if (aPntAttr.get() != NULL && + aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) { + anOwnersToSelect.Add(anOwner); + } + } + else if (aShapeType == TopAbs_EDGE) { + bool aFound = aSelectedResults.find(aResult) != aSelectedResults.end(); + if (aSelectedResults.find(aResult) != aSelectedResults.end() && + anOwnersToSelect.FindIndex(anOwner) <= 0) + anOwnersToSelect.Add(anOwner); + } + } + } +}