X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherMgr.cpp;h=40925340bfeae306f3c609731460c9ad00e19e61;hb=ca1ced8be909571c1943ddb2f32d475e9324e30f;hp=81945bbd47f3d1625bacd730172936e98d31d288;hpb=5b6031b015602aa07f5a6fc668c13ac3faf7a8a9;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp old mode 100755 new mode 100644 index 81945bbd4..40925340b --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -1,23 +1,41 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_SketcherMgr.cpp -// Created: 19 Dec 2014 -// Author: Vitaly SMETANNIKOV +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "PartSet_SketcherMgr.h" -#include "PartSet_SketcherReetntrantMgr.h" + +#include "PartSet_Filters.h" +#include "PartSet_SketcherReentrantMgr.h" #include "PartSet_Module.h" #include "PartSet_MouseProcessor.h" #include "PartSet_Tools.h" #include "PartSet_WidgetSketchLabel.h" #include "PartSet_WidgetEditor.h" #include "PartSet_ResultSketchPrs.h" +#include "PartSet_ExternalPointsMgr.h" +#include "PartSet_PreviewSketchPlane.h" #include #include #include #include #include +#include #include #include #include @@ -39,9 +57,12 @@ #include #include #include +#include #include +#include + #include #include @@ -60,7 +81,7 @@ #include #include #include -#include +#include #include #include #include @@ -68,6 +89,10 @@ #include #include #include +#include +#include +#include +#include #include @@ -108,8 +133,9 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, const FeaturePtr& theFeature, const FeaturePtr& theSketch, const ResultPtr& theResult, - std::set& aSelectedAttributes, - std::set& aSelectedResults) + std::set& theSelectedAttributes, + std::set& theSelectedResults, + TopTools_MapOfShape& theShapes) { Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner); if (aBRepOwner.IsNull()) @@ -118,16 +144,17 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, aBRepOwner->Selectable()); if (aBRepOwner->HasShape()) { const TopoDS_Shape& aShape = aBRepOwner->Shape(); + theShapes.Add(aShape); TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); if (aShapeType == TopAbs_VERTEX) { AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch); if (aPntAttr.get() != NULL) - aSelectedAttributes.insert(aPntAttr); + theSelectedAttributes.insert(aPntAttr); } else if (aShapeType == TopAbs_EDGE && - aSelectedResults.find(theResult) == aSelectedResults.end()) { - aSelectedResults.insert(theResult); + theSelectedResults.find(theResult) == theSelectedResults.end()) { + theSelectedResults.insert(theResult); } } } @@ -136,7 +163,7 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule) : QObject(theModule), myModule(theModule), myIsEditLaunching(false), myIsDragging(false), myDragDone(false), myIsMouseOverWindow(false), myIsMouseOverViewProcessed(true), myPreviousUpdateViewerEnabled(true), - myIsPopupMenuActive(false) + myIsPopupMenuActive(false), myExternalPointsMgr(0) { ModuleBase_IWorkshop* anIWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = anIWorkshop->viewer(); @@ -162,12 +189,16 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule) myIsConstraintsShown[PartSet_Tools::Geometrical] = true; myIsConstraintsShown[PartSet_Tools::Dimensional] = true; myIsConstraintsShown[PartSet_Tools::Expressions] = false; + + mySketchPlane = new PartSet_PreviewSketchPlane(); + + registerSelectionFilter(SF_SketchCirclePointFilter, new PartSet_CirclePointFilter(anIWorkshop)); + registerSelectionFilter(SF_SketchPlaneFilter, new ModuleBase_ShapeInPlaneFilter()); } PartSet_SketcherMgr::~PartSet_SketcherMgr() { - if (!myPlaneFilter.IsNull()) - myPlaneFilter.Nullify(); + delete mySketchPlane; } void PartSet_SketcherMgr::onEnterViewPort() @@ -274,7 +305,7 @@ void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel() myModule->sketchReentranceMgr()->isInternalEditActive()) return; // it is necessary to save current selection in order to restore it after the values are modifed - storeSelection(); + storeSelection(ST_SelectAndHighlightType); ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); @@ -306,17 +337,15 @@ void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel() void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { + // Clear dragging mode + myIsDragging = false; + if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent)) return; - //get2dPoint(theWnd, theEvent, myClickedPoint); - if (!(theEvent->buttons() & Qt::LeftButton)) return; - // Clear dragging mode - myIsDragging = false; - ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = aWorkshop->viewer(); if (!aViewer->canDragByMouse()) @@ -358,7 +387,7 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE ModuleBase_ISelection* aSelect = aWorkshop->selection(); bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); - storeSelection(!aHasShift); + storeSelection(aHasShift ? ST_SelectAndHighlightType : ST_HighlightType, myCurrentSelection); if (myCurrentSelection.empty()) { if (isSketchOpe && (!isSketcher)) @@ -425,9 +454,16 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { + bool aWasDragging = myIsDragging; + myIsDragging = false; + if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent)) return; + // if mouse is pressed when it was over view and at release the mouse is out of view, do nothing + if (!myIsMouseOverViewProcessed) + return; + ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = aWorkshop->viewer(); if (!aViewer->canDragByMouse()) @@ -436,8 +472,12 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse if (aOp) { if (isNestedSketchOperation(aOp)) { // Only for sketcher operations - if (myIsDragging) { + if (aWasDragging) { if (myDragDone) { + /// the previous selection is lost by mouse release in the viewer(Select method), but + /// it is still stored in myCurrentSelection. So, it is possible to restore selection + /// It is important for drag(edit with mouse) of sketch entities. + restoreSelection(myCurrentSelection); myCurrentSelection.clear(); } } @@ -445,7 +485,6 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse } aWorkshop->viewer()->enableDrawMode(myPreviousDrawModeEnabled); - myIsDragging = false; ModuleBase_ModelWidget* anActiveWidget = getActiveWidget(); PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWidget); @@ -512,8 +551,11 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView); Point aMousePnt; get2dPoint(theWnd, theEvent, aMousePnt); - double dX = aMousePnt.myCurX - myCurrentPoint.myCurX; - double dY = aMousePnt.myCurY - myCurrentPoint.myCurY; + + std::shared_ptr anOriginalPosition = std::shared_ptr( + new GeomAPI_Pnt2d(myCurrentPoint.myCurX, myCurrentPoint.myCurY)); + std::shared_ptr aCurrentPosition = std::shared_ptr( + new GeomAPI_Pnt2d(aMousePnt.myCurX, aMousePnt.myCurY)); ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); @@ -532,7 +574,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve for (; anIt != aLast; anIt++) { FeaturePtr aFeature = anIt.key(); - std::set anAttributes = anIt.value().first; + std::set anAttributes = anIt.value().myAttributes; // Process selection by attribute: the priority to the attribute if (!anAttributes.empty()) { std::set::const_iterator anAttIt = anAttributes.begin(), @@ -548,9 +590,15 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve std::dynamic_pointer_cast(aData->attribute(aAttrId)); if (aPoint.get() != NULL) { bool isImmutable = aPoint->setImmutable(true); - aPoint->move(dX, dY); + + std::shared_ptr aMessage = std::shared_ptr + (new ModelAPI_ObjectMovedMessage(this)); + aMessage->setMovedAttribute(aPoint); + aMessage->setOriginalPosition(anOriginalPosition); + aMessage->setCurrentPosition(aCurrentPosition); + Events_Loop::loop()->send(aMessage); + isModified = true; - ModelAPI_EventCreator::get()->sendUpdated(aFeature, aMoveEvent); aPoint->setImmutable(isImmutable); } } @@ -560,9 +608,13 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve std::shared_ptr aSketchFeature = std::dynamic_pointer_cast(aFeature); if (aSketchFeature) { - aSketchFeature->move(dX, dY); + std::shared_ptr aMessage = std::shared_ptr + (new ModelAPI_ObjectMovedMessage(this)); + aMessage->setMovedObject(aFeature); + aMessage->setOriginalPosition(anOriginalPosition); + aMessage->setCurrentPosition(aCurrentPosition); + Events_Loop::loop()->send(aMessage); isModified = true; - ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, aMoveEvent); } } } @@ -570,12 +622,12 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve // 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(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 - restoreSelection(); + restoreSelection(myCurrentSelection); // 6. restore the update viewer flag and call this update aDisplayer->enableUpdateViewer(isEnableUpdateViewer); aDisplayer->updateViewer(); @@ -598,8 +650,10 @@ void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMo QList aWidgets = aPanel->modelWidgets(); // Find corresponded widget to activate value editing foreach (ModuleBase_ModelWidget* aWgt, aWidgets) { - if (aWgt->attributeID() == SketchPlugin_Constraint::VALUE() || - aWgt->attributeID() == SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()) { + std::string anId = aWgt->attributeID(); + if (anId == SketchPlugin_Constraint::VALUE() || + anId == SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID() || + anId == SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()) { PartSet_WidgetEditor* anEditor = dynamic_cast(aWgt); if (anEditor) anEditor->showPopupEditor(); @@ -615,7 +669,7 @@ void PartSet_SketcherMgr::onApplicationStarted() ModuleBase_IWorkshop* anIWorkshop = myModule->workshop(); XGUI_ModuleConnector* aConnector = dynamic_cast(anIWorkshop); XGUI_Workshop* aWorkshop = aConnector->workshop(); - PartSet_SketcherReetntrantMgr* aReentranceMgr = myModule->sketchReentranceMgr(); + PartSet_SketcherReentrantMgr* aReentranceMgr = myModule->sketchReentranceMgr(); XGUI_PropertyPanel* aPropertyPanel = aWorkshop->propertyPanel(); if (aPropertyPanel) { @@ -624,8 +678,8 @@ void PartSet_SketcherMgr::onApplicationStarted() connect(aPropertyPanel, SIGNAL(noMoreWidgets(const std::string&)), aReentranceMgr, SLOT(onNoMoreWidgets(const std::string&))); - connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), - aReentranceMgr, SLOT(onWidgetActivated())); + //connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), + // aReentranceMgr, SLOT(onWidgetActivated())); } XGUI_ViewerProxy* aViewerProxy = aWorkshop->viewer(); @@ -681,8 +735,20 @@ void PartSet_SketcherMgr::launchEditing() FeaturePtr aFeature = myCurrentSelection.begin().key(); std::shared_ptr aSPFeature = std::dynamic_pointer_cast(aFeature); - if (aSPFeature && (!aSPFeature->isExternal())) { - myModule->editFeature(aSPFeature); + if (aSPFeature) { + if (!aSPFeature->isExternal()) + myModule->editFeature(aSPFeature); + else { + // need to edit a feature (Projection/IntersectionPoint), + // which produces current External feature + FeaturePtr aProducerFeature = PartSet_Tools::findRefsToMeFeature(aFeature, + SketchPlugin_Projection::ID()); + if (!aProducerFeature.get()) + aProducerFeature = PartSet_Tools::findRefsToMeFeature(aFeature, + SketchPlugin_IntersectionPoint::ID()); + if (aProducerFeature.get()) + myModule->editFeature(aProducerFeature); + } } } } @@ -750,13 +816,18 @@ const QStringList& PartSet_SketcherMgr::constraintsIdList() aConstraintIds << SketchPlugin_ConstraintMirror::ID().c_str(); aConstraintIds << SketchPlugin_MultiTranslation::ID().c_str(); aConstraintIds << SketchPlugin_MultiRotation::ID().c_str(); + aConstraintIds << SketchPlugin_ConstraintDistanceAlongDir::ID().c_str(); + aConstraintIds << SketchPlugin_ConstraintDistanceHorizontal::ID().c_str(); + aConstraintIds << SketchPlugin_ConstraintDistanceVertical::ID().c_str(); } return aConstraintIds; } -void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes) +void PartSet_SketcherMgr::sketchSelectionModes(const CompositeFeaturePtr& theSketch, + QIntList& theModes) { - theModes.clear(); + if (!theSketch.get() || !PartSet_Tools::sketchPlane(theSketch).get()) + return; theModes.append(SketcherPrs_Tools::Sel_Dimension_Text); theModes.append(SketcherPrs_Tools::Sel_Dimension_Line); @@ -802,6 +873,22 @@ bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOpera return aNestedSketch; } +bool PartSet_SketcherMgr::isNestedSketchFeature(const QString& theFeatureKind) const +{ + bool aNestedSketch = false; + + FeaturePtr anActiveSketch = activeSketch(); + if (anActiveSketch.get()) { + ModuleBase_Operation* aSketchOperation = operationMgr()->findOperation( + anActiveSketch->getKind().c_str()); + if (aSketchOperation) { + QStringList aGrantedOpIds = aSketchOperation->grantedOperationIds(); + aNestedSketch = aGrantedOpIds.contains(theFeatureKind); + } + } + return aNestedSketch; +} + bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation, const CompositeFeaturePtr& theSketch) const { @@ -828,6 +915,13 @@ bool PartSet_SketcherMgr::isEntity(const std::string& theId) (theId == SketchPlugin_Circle::ID()); } +bool PartSet_SketcherMgr::isExternalFeature(const FeaturePtr& theFeature) +{ + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(theFeature); + return aSPFeature.get() && aSPFeature->isExternal(); +} + bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation) { std::string anId = theOperation ? theOperation->id().toStdString() : ""; @@ -840,7 +934,10 @@ bool PartSet_SketcherMgr::isDistanceKind(std::string& theKind) return (theKind == SketchPlugin_ConstraintLength::ID()) || (theKind == SketchPlugin_ConstraintDistance::ID()) || (theKind == SketchPlugin_ConstraintRadius::ID()) || - (theKind == SketchPlugin_ConstraintAngle::ID()); + (theKind == SketchPlugin_ConstraintAngle::ID()) || + (theKind == SketchPlugin_ConstraintDistanceHorizontal::ID()) || + (theKind == SketchPlugin_ConstraintDistanceVertical::ID()) || + (theKind == SketchPlugin_ConstraintDistanceAlongDir::ID()); } void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) @@ -854,6 +951,14 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) // Display all sketcher sub-Objects myCurrentSketch = std::dynamic_pointer_cast(aFOperation->feature()); + double aSizeOfView = 0; + std::shared_ptr aCentralPoint; + if (aFOperation->isEditOperation() && + mySketchPlane->getDefaultSizeOfView(myCurrentSketch, aSizeOfView, aCentralPoint)) { + mySketchPlane->setSizeOfView(aSizeOfView, true, aCentralPoint); + } + + mySketchPlane->createSketchPlane(myCurrentSketch, myModule->workshop()); XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); // Hide sketcher result @@ -867,7 +972,8 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) // Remove invalid sketch entities std::set anInvalidFeatures; ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators(); - for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + int aNumberOfSubs = myCurrentSketch->numberOfSubs(); + for (int i = 0; i < aNumberOfSubs; i++) { FeaturePtr aFeature = myCurrentSketch->subFeature(i); if (aFeature.get()) { if (!aFactory->validate(aFeature)) @@ -901,9 +1007,15 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) } } + // update state of overconstraint listener should be done before sketch features/results + // display (as the display will ask custom color from the listener) + myModule->overconstraintListener()->setActive(true); // Display sketcher objects QStringList anInfo; - for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + aNumberOfSubs = myCurrentSketch->numberOfSubs(); + for (int i = 0; i < aNumberOfSubs; i++) { FeaturePtr aFeature = myCurrentSketch->subFeature(i); #ifdef DEBUG_SKETCHER_ENTITIES anInfo.append(ModuleBase_Tools::objectInfo(aFeature)); @@ -911,35 +1023,37 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) std::list aResults = aFeature->results(); std::list::const_iterator aIt; for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - (*aIt)->setDisplayed(true); + if ((*aIt)->isDisplayed()) + // Display object if it was created outside of GUI + aECreator->sendUpdated((*aIt), EVENT_DISP); + else + (*aIt)->setDisplayed(true); } - aFeature->setDisplayed(true); + if (aFeature->isDisplayed()) + aECreator->sendUpdated(aFeature, EVENT_DISP); + else + aFeature->setDisplayed(true); } #ifdef DEBUG_SKETCHER_ENTITIES QString anInfoStr = anInfo.join(";\t"); qDebug(QString("startSketch: %1, %2").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str()); #endif - if(myCirclePointFilter.IsNull()) { - myCirclePointFilter = new PartSet_CirclePointFilter(myModule->workshop()); - } - - myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter); - - if (myPlaneFilter.IsNull()) - myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); - - myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter); bool aHasPlane = false; std::shared_ptr aPln; aPln = PartSet_Tools::sketchPlane(myCurrentSketch); - myPlaneFilter->setPlane(aPln); + Handle(SelectMgr_Filter) aFilter = myModule->selectionFilter(SF_SketchPlaneFilter); + if (!aFilter.IsNull()) + Handle(ModuleBase_ShapeInPlaneFilter)::DownCast(aFilter)->setPlane(aPln); + + workshop()->selectionActivate()->updateSelectionFilters(); + workshop()->selectionActivate()->updateSelectionModes(); Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); - // all displayed objects should be activated in current selection modes according to switched - // plane filter - if (aPln.get()) - aConnector->activateModuleSelectionModes(); + + myExternalPointsMgr = new PartSet_ExternalPointsMgr(myModule->workshop(), myCurrentSketch); + + workshop()->viewer()->set2dMode(true); } void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) @@ -949,6 +1063,12 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) myIsConstraintsShown[PartSet_Tools::Dimensional] = true; myIsConstraintsShown[PartSet_Tools::Expressions] = false; + if (myExternalPointsMgr) { + delete myExternalPointsMgr; + myExternalPointsMgr = 0; + } + onShowPoints(false); + XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); DataPtr aData = myCurrentSketch->data(); @@ -956,9 +1076,7 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); // The sketch was aborted myCurrentSketch = CompositeFeaturePtr(); - // TODO: move this outside of if-else - myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter); - myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); + mySketchPlane->eraseSketchPlane(myModule->workshop()); // Erase all sketcher objects QObjectPtrList aObjects = aDisplayer->displayedObjects(); @@ -970,7 +1088,8 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) } else { // Hide all sketcher sub-Objects - for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + int aNumberOfSubs = myCurrentSketch->numberOfSubs(); + for (int i = 0; i < aNumberOfSubs; i++) { FeaturePtr aFeature = myCurrentSketch->subFeature(i); std::list aResults = aFeature->results(); std::list::const_iterator aIt; @@ -999,14 +1118,13 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) myCurrentSketch->setDisplayed(true); myCurrentSketch = CompositeFeaturePtr(); - - myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter); - myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); + mySketchPlane->eraseSketchPlane(myModule->workshop()); Events_Loop::loop()->flush(aDispEvent); } - // restore the module selection modes, which were changed on startSketch - aConnector->activateModuleSelectionModes(); + workshop()->selectionActivate()->updateSelectionFilters(); + workshop()->selectionActivate()->updateSelectionModes(); + workshop()->viewer()->set2dMode(false); } void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation) @@ -1048,6 +1166,8 @@ void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation) } if (isClearSelectionPossible) workshop()->selector()->clearSelection(); + if (myPointsHighlight.size()) + onShowPoints(true); } void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation) @@ -1066,12 +1186,16 @@ void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation) } } -void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate) +bool PartSet_SketcherMgr::sketchSelectionFilter(const XGUI_SelectionFilterType theFilterType) { - if (toActivate) - myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter); - else - myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); + return mySelectionFilterTypes.find(theFilterType) != mySelectionFilterTypes.end(); +} + +void PartSet_SketcherMgr::registerSelectionFilter(const XGUI_SelectionFilterType theFilterType, + const Handle(SelectMgr_Filter)& theFilter) +{ + mySelectionFilterTypes.insert(theFilterType); + myModule->registerSelectionFilter(theFilterType, theFilter); } bool PartSet_SketcherMgr::operationActivatedByPreselection() @@ -1366,7 +1490,7 @@ bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject); if (anObjectFeature.get()) { int aSize = myCurrentSketch->numberOfSubs(); - for (int i = 0; i < myCurrentSketch->numberOfSubs() && !isFoundObject; i++) { + for (int i = 0; i < aSize && !isFoundObject; i++) { FeaturePtr aCurrentFeature = myCurrentSketch->subFeature(i); isFoundObject = myCurrentSketch->subFeature(i) == anObjectFeature; } @@ -1374,12 +1498,13 @@ bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const return isFoundObject; } -void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr& thePln) +void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr& thePlane) { - if (myPlaneFilter.IsNull()) - myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); + Handle(SelectMgr_Filter) aFilter = myModule->selectionFilter(SF_SketchPlaneFilter); + if (!aFilter.IsNull()) + Handle(ModuleBase_ShapeInPlaneFilter)::DownCast(aFilter)->setPlane(thePlane); - myPlaneFilter->setPlane(thePln); + workshop()->selectionActivate()->updateSelectionModes(); } bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* theOperation, @@ -1468,8 +1593,9 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, return; FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature); - std::set aSelectedAttributes = anIt.value().first; - std::set aSelectedResults = anIt.value().second; + SelectionInfo anInfo = anIt.value(); + std::set aSelectedAttributes = anInfo.myAttributes; + std::set aSelectedResults = anInfo.myResults; ModuleBase_IViewer* aViewer = theWorkshop->viewer(); @@ -1493,8 +1619,16 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, // 2. found the feature results's owners std::list aResults = theFeature->results(); std::list::const_iterator aIt; - for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) - { + + bool isSameShape = false; + if (aResults.size() > 0) { + ResultPtr aFirstResult = theFeature->firstResult(); + if (aFirstResult.get() && aFirstResult->shape().get()) { + TopoDS_Shape aFirstShape = aFirstResult->shape()->impl(); + isSameShape = aFirstShape.IsEqual(anInfo.myFirstResultShape); + } + } + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { ResultPtr aResult = *aIt; AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult); if (aAISObj.get() == NULL) @@ -1503,10 +1637,11 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, SelectMgr_IndexedMapOfOwner aSelectedOwners; aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners); + bool aFoundLocalShape = false; 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() ) + if ( anOwner.IsNull() || !anOwner->HasShape() || theOwnersToSelect.FindIndex(anOwner)) continue; const TopoDS_Shape& aShape = anOwner->Shape(); TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); @@ -1514,15 +1649,34 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch); if (aPntAttr.get() != NULL && - aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) { + aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) + theOwnersToSelect.Add(anOwner); + else if (isSameShape && anInfo.myLocalSelectedShapes.Contains(aShape)) { theOwnersToSelect.Add(anOwner); } } else if (aShapeType == TopAbs_EDGE) { - bool aFound = aSelectedResults.find(aResult) != aSelectedResults.end(); - if (aSelectedResults.find(aResult) != aSelectedResults.end() && - theOwnersToSelect.FindIndex(anOwner) <= 0) + if (isSameShape && anInfo.myLocalSelectedShapes.Contains(aShape)) { + // try to restore local selection on Shape result + // we can do this only if the shape was not changed theOwnersToSelect.Add(anOwner); + aFoundLocalShape = true; + break; + } + } + } + if (!aFoundLocalShape) { + // result owners are put in the list of selection only if local selected shapes were not + // found + if (aSelectedResults.find(aResult) != aSelectedResults.end()) { + 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() || theOwnersToSelect.FindIndex(anOwner)) + continue; + // select whole result + theOwnersToSelect.Add(anOwner); + } } } } @@ -1531,19 +1685,23 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, void PartSet_SketcherMgr::connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect) { - /*Temporary commented as we do not modify values in property panel + //Temporary commented as we do not modify values in property panel if (isToConnect) { - connect(theWidget, SIGNAL(beforeValuesChanged()), - this, SLOT(onBeforeValuesChangedInPropertyPanel())); + //connect(theWidget, SIGNAL(beforeValuesChanged()), + // this, SLOT(onBeforeValuesChangedInPropertyPanel())); + //connect(theWidget, SIGNAL(afterValuesChanged()), + // this, SLOT(onAfterValuesChangedInPropertyPanel())); connect(theWidget, SIGNAL(afterValuesChanged()), - this, SLOT(onAfterValuesChangedInPropertyPanel())); + myModule->sketchReentranceMgr(), SLOT(onAfterValuesChangedInPropertyPanel())); } else { - disconnect(theWidget, SIGNAL(beforeValuesChanged()), - this, SLOT(onBeforeValuesChangedInPropertyPanel())); + //disconnect(theWidget, SIGNAL(beforeValuesChanged()), + // this, SLOT(onBeforeValuesChangedInPropertyPanel())); + //disconnect(theWidget, SIGNAL(afterValuesChanged()), + // this, SLOT(onAfterValuesChangedInPropertyPanel())); disconnect(theWidget, SIGNAL(afterValuesChanged()), - this, SLOT(onAfterValuesChangedInPropertyPanel())); - }*/ + myModule->sketchReentranceMgr(), SLOT(onAfterValuesChangedInPropertyPanel())); + } } void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState) @@ -1637,24 +1795,28 @@ void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature, Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); } -void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly) +void PartSet_SketcherMgr::storeSelection(const SelectionType theType, + PartSet_SketcherMgr::FeatureToSelectionMap& theCurrentSelection) { if (!myCurrentSketch.get()) return; ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_ISelection* aSelect = aWorkshop->selection(); - QList aStoredPrs = aSelect->getHighlighted(); + QList aStoredPrs; + + if (theType == ST_HighlightType || theType == ST_SelectAndHighlightType) + aStoredPrs = aSelect->getHighlighted(); QList aFeatureList; - if (!theHighlightedOnly) { + if (theType == ST_SelectAndHighlightType || theType == ST_SelectType) { QList aSelected = aSelect->getSelected( ModuleBase_ISelection::AllControls); aStoredPrs.append(aSelected); } // 1. it is necessary to save current selection in order to restore it after the features moving - myCurrentSelection.clear(); + theCurrentSelection.clear(); QList::const_iterator anIt = aStoredPrs.begin(), aLast = aStoredPrs.end(); @@ -1673,20 +1835,24 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly) else aFeature = std::dynamic_pointer_cast(anObject); + if (!aFeature.get()) + continue; std::set aSelectedAttributes; std::set aSelectedResults; - if (myCurrentSelection.find(aFeature) != myCurrentSelection.end()) { - std::pair, std::set > aPair = - myCurrentSelection.find(aFeature).value(); - aSelectedAttributes = aPair.first; - aSelectedResults = aPair.second; - } - + SelectionInfo anInfo; + if (theCurrentSelection.find(aFeature) != theCurrentSelection.end()) + anInfo = theCurrentSelection.find(aFeature).value(); + + TopoDS_Shape aFirstShape; + ResultPtr aFirstResult = aFeature->firstResult(); + if (aFirstResult.get() && aFirstResult->shape().get()) + aFirstShape = aFirstResult->shape()->impl(); + anInfo.myFirstResultShape = aFirstShape; Handle(SelectMgr_EntityOwner) anOwner = aPrs->owner(); if (aResult.get()) { getAttributesOrResults(anOwner, aFeature, aSketch, aResult, - aSelectedAttributes, aSelectedResults); + anInfo.myAttributes, anInfo.myResults, anInfo.myLocalSelectedShapes); } else { std::list aResults = aFeature->results(); @@ -1694,29 +1860,30 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly) for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { ResultPtr aResult = *aIt; getAttributesOrResults(anOwner, aFeature, aSketch, aResult, - aSelectedAttributes, aSelectedResults); + anInfo.myAttributes, anInfo.myResults, anInfo.myLocalSelectedShapes); } } - myCurrentSelection[aFeature] = std::make_pair(aSelectedAttributes, aSelectedResults); + theCurrentSelection[aFeature] = anInfo; } - //qDebug(QString(" storeSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str()); + //qDebug(QString(" storeSelection: %1").arg(theCurrentSelection.size()).toStdString().c_str()); } -void PartSet_SketcherMgr::restoreSelection() +void PartSet_SketcherMgr::restoreSelection( + PartSet_SketcherMgr::FeatureToSelectionMap& theCurrentSelection) { if (!myCurrentSketch.get()) return; - //qDebug(QString("restoreSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str()); + //qDebug(QString("restoreSelection: %1").arg(theCurrentSelection.size()).toStdString().c_str()); ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); - FeatureToSelectionMap::const_iterator aSIt = myCurrentSelection.begin(), - aSLast = myCurrentSelection.end(); + FeatureToSelectionMap::const_iterator aSIt = theCurrentSelection.begin(), + aSLast = theCurrentSelection.end(); SelectMgr_IndexedMapOfOwner anOwnersToSelect; anOwnersToSelect.Clear(); for (; aSIt != aSLast; aSIt++) { - getSelectionOwners(aSIt.key(), myCurrentSketch, aWorkshop, myCurrentSelection, - anOwnersToSelect); + getSelectionOwners(aSIt.key(), myCurrentSketch, aWorkshop, theCurrentSelection, + anOwnersToSelect); } aConnector->workshop()->selector()->setSelectedOwners(anOwnersToSelect, false); } @@ -1744,7 +1911,8 @@ void PartSet_SketcherMgr::updateBySketchParameters( if (aPrevState != theState) { ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); - for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + int aNumberOfSubs = myCurrentSketch->numberOfSubs(); + for (int i = 0; i < aNumberOfSubs; i++) { FeaturePtr aSubFeature = myCurrentSketch->subFeature(i); bool aProcessed = false; bool aConstraintDisplayed = canDisplayConstraint(aSubFeature, theType, aProcessed); @@ -1827,3 +1995,63 @@ XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const return workshop()->operationMgr(); } +void PartSet_SketcherMgr::onShowPoints(bool toShow) +{ + if (!myCurrentSketch.get()) + return; + ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); + ModuleBase_IViewer* aViewer = aWorkshop->viewer(); + Handle(AIS_InteractiveContext) aContext = aViewer->AISContext(); + + bool aToUpdate = false; + if (toShow) { + std::list aFreePoints = SketcherPrs_Tools::getFreePoints(myCurrentSketch); + + // Delete obsolete presentations + std::list aDelList; + foreach(ResultPtr aObj, myPointsHighlight.keys()) { + bool aFound = (std::find(aFreePoints.begin(), aFreePoints.end(), aObj) != aFreePoints.end()); + if (!aFound) + aDelList.push_back(aObj); + } + foreach(ResultPtr aObj, aDelList) { + aContext->Remove(myPointsHighlight[aObj], false); + aToUpdate = true; + myPointsHighlight.remove(aObj); + } + + // Display new objects + QList aKeysList = myPointsHighlight.keys(); + std::list::const_iterator aIt; + for (aIt = aFreePoints.cbegin(); aIt != aFreePoints.cend(); aIt++) { + if (!aKeysList.contains(*aIt)) { + GeomShapePtr aShapePtr = (*aIt)->shape(); + TopoDS_Shape aShape = aShapePtr->impl(); + Handle(AIS_Shape) aShapePrs = new AIS_Shape(aShape); + aShapePrs->SetColor(Quantity_NOC_BLUE1); + aShapePrs->SetZLayer(Graphic3d_ZLayerId_Top); + Handle(Prs3d_Drawer) aDrawer = aShapePrs->Attributes(); + if (aDrawer->HasOwnPointAspect()) { + aDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_O_STAR); + aDrawer->PointAspect()->SetColor(Quantity_NOC_BLUE1); + aDrawer->PointAspect()->SetScale(2); + } + else + aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_O_STAR, Quantity_NOC_BLUE1, 2)); + aContext->Display(aShapePrs, false); + aContext->Deactivate(aShapePrs); + myPointsHighlight[*aIt] = aShapePrs; + aToUpdate = true; + } + } + } + else { + foreach(Handle(AIS_Shape) aPrs, myPointsHighlight.values()) { + aContext->Remove(aPrs, false); + aToUpdate = true; + } + myPointsHighlight.clear(); + } + if (aToUpdate) + aViewer->update(); +}