X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherMgr.cpp;h=6e5a2d3850ca4651198483d0729182a70ee02be3;hb=b3f7b461d00b6ddf3736c8284498a9f33428577c;hp=aa639e247c9195493ef4968db6d95f3c5c5896ac;hpb=81f7aa2dd35db69a5da6c2698da62af56d79c007;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index aa639e247..6e5a2d385 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2022 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 @@ -60,6 +60,7 @@ #include #include +#include #include @@ -101,9 +102,8 @@ #include #include -//#include #include -#include +#include #include #include @@ -142,7 +142,7 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, const FeaturePtr& theFeature, const FeaturePtr& theSketch, const ResultPtr& theResult, - std::set& theSelectedAttributes, + std::map& theSelectedAttributes, std::set& theSelectedResults, TopTools_MapOfShape& theShapes) { @@ -156,10 +156,10 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, theShapes.Add(aShape); TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); if (aShapeType == TopAbs_VERTEX) { - AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, - aShape, theSketch); - if (aPntAttr.get() != NULL) - theSelectedAttributes.insert(aPntAttr); + std::pair aPntAttrIndex = + PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch); + if (aPntAttrIndex.first.get() != NULL) + theSelectedAttributes[aPntAttrIndex.first] = aPntAttrIndex.second; } else if (aShapeType == TopAbs_EDGE && theSelectedResults.find(theResult) == theSelectedResults.end()) { @@ -169,10 +169,17 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, } 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), myExternalPointsMgr(0), myNoDragMoving(false) + : QObject(theModule), + myModule(theModule), + myIsEditLaunching(false), + myIsDragging(false), + myDragDone(false), + myIsMouseOverWindow(false), + myIsMouseOverViewProcessed(true), + myIsPopupMenuActive(false), + myPreviousUpdateViewerEnabled(true), + myExternalPointsMgr(0), + myNoDragMoving(false) { ModuleBase_IWorkshop* anIWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = anIWorkshop->viewer(); @@ -224,15 +231,17 @@ void PartSet_SketcherMgr::onEnterViewPort() return; #endif - if (canChangeCursor(getCurrentOperation())) { - QCursor* aCurrentCursor = QApplication::overrideCursor(); - if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) { - QApplication::setOverrideCursor(QCursor(Qt::CrossCursor)); -#ifdef DEBUG_CURSOR - qDebug("onEnterViewPort() : Qt::CrossCursor"); -#endif + // It is switched off because of + // Task #3067: 5.2.2 Drawing in the sketcher: change the mouse cursor arrow + if (canChangeCursor(getCurrentOperation())) { + QCursor* aCurrentCursor = QApplication::overrideCursor(); + if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) { + QApplication::setOverrideCursor(PartSet_Tools::getOperationCursor()); + //#ifdef DEBUG_CURSOR + // qDebug("onEnterViewPort() : Qt::CrossCursor"); + //#endif + } } - } if (!isNestedCreateOperation(getCurrentOperation(), activeSketch())) return; @@ -266,9 +275,9 @@ void PartSet_SketcherMgr::onLeaveViewPort() if (canChangeCursor(getCurrentOperation())) { QApplication::restoreOverrideCursor(); -#ifdef DEBUG_CURSOR - qDebug("onLeaveViewPort() : None"); -#endif +//#ifdef DEBUG_CURSOR +// qDebug("onLeaveViewPort() : None"); +//#endif } if (!isNestedCreateOperation(getCurrentOperation(), activeSketch())) @@ -346,11 +355,35 @@ void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel() } */ +bool PartSet_SketcherMgr::isDragModeCreation() const +{ + ModuleBase_Operation* aOp = getCurrentOperation(); + if (!aOp) + return false; + bool aUserPref = Config_PropManager::boolean(SKETCH_TAB_NAME, "create_by_dragging"); + if (!aUserPref) + return false; + QString aId = aOp->id(); + // Acceptable features; + QStringList aList; + aList << "SketchLine" << "SketchMacroCircle" << "SketchMacroArc" << + "SketchMacroEllipse" << "SketchMacroEllipticArc" << "SketchMacroRectangle"; + return aList.contains(aId); +} + +static bool MyModeByDrag = false; +static bool MyMultiselectionState = true; + void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { + MyModeByDrag = isDragModeCreation(); + // Clear dragging mode myIsDragging = false; + myMousePoint.setX(theEvent->x()); + myMousePoint.setY(theEvent->y()); + if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent)) return; //get2dPoint(theWnd, theEvent, myClickedPoint); @@ -396,9 +429,24 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE return; // Ignore creation sketch operation - if ((!isSketcher) && (!isEditing)) + if ((!isSketcher) && (!isEditing)) { + if (MyModeByDrag) { + ModuleBase_ModelWidget* anActiveWidget = getActiveWidget(); + PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWidget); + if (aProcessor) { + MyMultiselectionState = aViewer->isMultiSelectionEnabled(); + aViewer->enableMultiselection(false); + myIsDragging = true; + ModuleBase_ISelection* aSelection = aWorkshop->selection(); + QList aPreSelected = aSelection->getHighlighted(); + if (!aPreSelected.empty()) + aProcessor->setPreSelection(aPreSelected.first(), theWnd, theEvent); + else + aProcessor->mouseReleased(theWnd, theEvent); + } + } return; - + } bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); storeSelection(aHasShift ? ST_SelectAndHighlightType : ST_HighlightType, myCurrentSelection); @@ -411,7 +459,6 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE } // Init flyout point for radius rotation FeaturePtr aFeature = myCurrentSelection.begin().key(); - get2dPoint(theWnd, theEvent, myCurrentPoint); if (isSketcher) { if (aCanDrag) { @@ -420,19 +467,6 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE } myPreviousDrawModeEnabled = aViewer->enableDrawMode(false); launchEditing(); - if (aFeature.get() != NULL) { - std::shared_ptr aSPFeature = - std::dynamic_pointer_cast(aFeature); - if (aSPFeature.get() && - (aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID() || - aSPFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) { - DataPtr aData = aSPFeature->data(); - AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()); - std::shared_ptr aFPAttr = - std::dynamic_pointer_cast(aAttr); - aFPAttr->setValue(myCurrentPoint.myCurX, myCurrentPoint.myCurY); - } - } } else if (isSketchOpe && isEditing) { // If selected another object commit current result bool aPrevLaunchingState = myIsEditLaunching; @@ -441,22 +475,46 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE /// Internal edit should not be stored as editing operation as the result will be a /// creation operation, where previous selection should not be used(and will be cleared) myIsEditLaunching = !myModule->sketchReentranceMgr()->isInternalEditActive(); - aFOperation->commit(); + + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(aFOperation->feature()); + bool isRelaunchEditing = true; + if (aSPFeature->isExternal()) { + foreach(FeaturePtr aF, myCurrentSelection.keys()) { + FeaturePtr aProducerFeature = PartSet_Tools::findRefsToMeFeature(aF, + aSPFeature->getKind()); + if (aProducerFeature == aSPFeature) { + isRelaunchEditing = false; + break; + } + } + } + else { + if (myCurrentSelection.size() > 1) + isRelaunchEditing = !myCurrentSelection.contains(aSPFeature); + } + if (isRelaunchEditing) + aFOperation->commit(); if (aCanDrag) { myIsDragging = true; myDragDone = false; } myPreviousDrawModeEnabled = aViewer->enableDrawMode(false); - launchEditing(); + if (isRelaunchEditing) + launchEditing(); + else { + if (myCurrentSelection.size() > 1) + aFOperation->propertyPanel()->cleanContent(); + } myIsEditLaunching = aPrevLaunchingState; if (aFeature.get() != NULL) { - std::shared_ptr aSPFeature = + std::shared_ptr aSketchFeature = std::dynamic_pointer_cast(aFeature); - if (aSPFeature.get() && - (aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID() || - aSPFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) { - DataPtr aData = aSPFeature->data(); + if (aSketchFeature.get() && + (aSketchFeature->getKind() == SketchPlugin_ConstraintRadius::ID() || + aSketchFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) { + DataPtr aData = aSketchFeature->data(); AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()); std::shared_ptr aFPAttr = std::dynamic_pointer_cast(aAttr); @@ -470,8 +528,9 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); + ModuleBase_IViewer* aViewer = aWorkshop->viewer(); if (myIsDragging) - aWorkshop->viewer()->enableDrawMode(myPreviousDrawModeEnabled); + aViewer->enableDrawMode(myPreviousDrawModeEnabled); bool aWasDragging = myIsDragging; myIsDragging = false; @@ -483,13 +542,13 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse if (!myIsMouseOverViewProcessed) { return; } - ModuleBase_IViewer* aViewer = aWorkshop->viewer(); - //if (!aViewer->canDragByMouse()) - // return; + ModuleBase_OperationFeature* aOp = - dynamic_cast(getCurrentOperation()); + dynamic_cast(getCurrentOperation()); + bool isEditing = false; if (aOp) { - bool aStartNoDragOperation = !aViewer->canDragByMouse() && aOp->isEditOperation(); + isEditing = aOp->isEditOperation(); + bool aStartNoDragOperation = !aViewer->canDragByMouse() && isEditing; if (aStartNoDragOperation || myNoDragMoving) { // Process edit operation without dragging if (myCurrentSelection.size() > 0) @@ -519,11 +578,32 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse } } - ModuleBase_ModelWidget* anActiveWidget = getActiveWidget(); PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWidget); - if (aProcessor) - aProcessor->mouseReleased(theWnd, theEvent); + if (aProcessor) { + ModuleBase_ISelection* aSelection = aWorkshop->selection(); + QList aPreSelected = aSelection->getHighlighted(); + if (MyModeByDrag && !aPreSelected.empty() && !isEditing) + aProcessor->setPreSelection(aPreSelected.first(), theWnd, theEvent); + else + aProcessor->mouseReleased(theWnd, theEvent); + } + if (MyModeByDrag && aOp) { + aViewer->enableMultiselection(true); + QString aOpId = aOp->id(); + if (aOpId == "Sketch") + return; + QPoint aPnt(theEvent->x(), theEvent->y()); + anActiveWidget = getActiveWidget(); + if ((aPnt == myMousePoint) && anActiveWidget) { + aOp->abort(); + return; + } + bool aCanRestart = !anActiveWidget && !isEditing; + if (aCanRestart) { + module()->launchOperation(aOpId, true); + } + } } void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) @@ -541,6 +621,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve qDebug(QString("%1").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str()); } #endif + if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent)) return; @@ -597,7 +678,6 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve #endif Handle(V3d_View) aView = theWnd->v3dView(); - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView); Point aMousePnt; get2dPoint(theWnd, theEvent, aMousePnt); @@ -620,26 +700,26 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve for (; anIt != aLast; anIt++) { FeaturePtr aFeature = anIt.key(); - std::set anAttributes = anIt.value().myAttributes; + std::map anAttributes = anIt.value().myAttributes; // Process selection by attribute: the priority to the attribute if (!anAttributes.empty()) { - std::set::const_iterator anAttIt = anAttributes.begin(), + std::map::const_iterator anAttIt = anAttributes.begin(), anAttLast = anAttributes.end(); for (; anAttIt != anAttLast; anAttIt++) { - AttributePtr anAttr = *anAttIt; + AttributePtr anAttr = anAttIt->first; if (anAttr.get() == NULL) continue; std::string aAttrId = anAttr->id(); DataPtr aData = aFeature->data(); if (aData->isValid()) { - std::shared_ptr aPoint = - std::dynamic_pointer_cast(aData->attribute(aAttrId)); - if (aPoint.get() != NULL) { + AttributePtr aPoint = aData->attribute(aAttrId); + if (aPoint->attributeType() == GeomDataAPI_Point2D::typeId() || + aPoint->attributeType() == GeomDataAPI_Point2DArray::typeId()) { bool isImmutable = aPoint->setImmutable(true); std::shared_ptr aMessage = std::shared_ptr (new ModelAPI_ObjectMovedMessage(this)); - aMessage->setMovedAttribute(aPoint); + aMessage->setMovedAttribute(aPoint, anAttIt->second); aMessage->setOriginalPosition(anOriginalPosition); aMessage->setCurrentPosition(aCurrentPosition); Events_Loop::loop()->send(aMessage); @@ -887,13 +967,15 @@ void PartSet_SketcherMgr::sketchSelectionModes(const CompositeFeaturePtr& theSke theModes.append(TopAbs_EDGE); } -Handle(AIS_InteractiveObject) PartSet_SketcherMgr::createPresentation(const ResultPtr& theResult) +Handle(AIS_InteractiveObject) PartSet_SketcherMgr::createPresentation(const ObjectPtr& theObj) { Handle(AIS_InteractiveObject) aPrs; - FeaturePtr aFeature = ModelAPI_Feature::feature(theResult); + FeaturePtr aFeature = ModelAPI_Feature::feature(theObj); if (aFeature.get() && aFeature->getKind() == SketchPlugin_Sketch::ID()) { - aPrs = new PartSet_ResultSketchPrs(theResult); + ResultPtr aResult = std::dynamic_pointer_cast(theObj); + if (aResult.get()) + aPrs = new PartSet_ResultSketchPrs(aResult); } return aPrs; } @@ -965,6 +1047,8 @@ bool PartSet_SketcherMgr::isEntity(const std::string& theId) (theId == SketchPlugin_Arc::ID()) || (theId == SketchPlugin_Circle::ID()) || (theId == SketchPlugin_Ellipse::ID()) || + (theId == SketchPlugin_Projection::ID()) || + (theId == SketchPlugin_IntersectionPoint::ID()) || (theId == SketchPlugin_EllipticArc::ID()); } @@ -995,6 +1079,9 @@ bool PartSet_SketcherMgr::isDistanceKind(std::string& theKind) void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) { + static Events_ID EVENT_ATTR = Events_Loop::loop()->eventByName(EVENT_VISUAL_ATTRIBUTES); + static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModuleBase_OperationFeature* aFOperation = dynamic_cast (getCurrentOperation()); if (!aFOperation) @@ -1008,6 +1095,8 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) myCurrentSketch = std::dynamic_pointer_cast(aFOperation->feature()); double aSizeOfView = 0; std::shared_ptr aCentralPoint; + // Reset size of view from previous launches + mySketchPlane->setSizeOfView(aSizeOfView, false, aCentralPoint); if (aFOperation->isEditOperation() && mySketchPlane->getDefaultSizeOfView(myCurrentSketch, aSizeOfView, aCentralPoint)) { mySketchPlane->setSizeOfView(aSizeOfView, true, aCentralPoint); @@ -1046,7 +1135,7 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) for (; anIt != aLast; anIt++) { FeaturePtr aFeature = *anIt; if (aFeature.get()) - anInvalidFeatureNames.append(aFeature->name().c_str()); + anInvalidFeatureNames.append(QString::fromStdWString(aFeature->name())); } std::string aPrefixInfo = QString("Invalid features of the sketch will be deleted: %1.\n\n"). arg(anInvalidFeatureNames.join(", ")).toStdString().c_str(); @@ -1067,7 +1156,6 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) myModule->overconstraintListener()->setActive(true); // Display sketcher objects QStringList anInfo; - 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++) { @@ -1075,9 +1163,8 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) #ifdef DEBUG_SKETCHER_ENTITIES anInfo.append(ModuleBase_Tools::objectInfo(aFeature)); #endif - std::list aResults = aFeature->results(); - std::list::const_iterator aIt; - for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + std::list aFeatResults = aFeature->results(); + for (aIt = aFeatResults.begin(); aIt != aFeatResults.end(); ++aIt) { if ((*aIt)->isDisplayed()) // Display object if it was created outside of GUI aECreator->sendUpdated((*aIt), EVENT_DISP); @@ -1088,13 +1175,13 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) aECreator->sendUpdated(aFeature, EVENT_DISP); else aFeature->setDisplayed(true); + aECreator->sendUpdated(aFeature, EVENT_ATTR); } #ifdef DEBUG_SKETCHER_ENTITIES QString anInfoStr = anInfo.join(";\t"); qDebug(QString("startSketch: %1, %2").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str()); #endif - bool aHasPlane = false; std::shared_ptr aPln; aPln = PartSet_Tools::sketchPlane(myCurrentSketch); Handle(SelectMgr_Filter) aFilter = myModule->selectionFilter(SF_SketchPlaneFilter); @@ -1104,7 +1191,8 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) workshop()->selectionActivate()->updateSelectionFilters(); workshop()->selectionActivate()->updateSelectionModes(); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + Events_Loop::loop()->flush(EVENT_ATTR); + Events_Loop::loop()->flush(EVENT_DISP); myExternalPointsMgr = new PartSet_ExternalPointsMgr(myModule->workshop(), myCurrentSketch); @@ -1193,10 +1281,10 @@ void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation) if (canChangeCursor(theOperation) && myIsMouseOverWindow) { QCursor* aCurrentCursor = QApplication::overrideCursor(); if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) { - QApplication::setOverrideCursor(QCursor(Qt::CrossCursor)); -#ifdef DEBUG_CURSOR - qDebug("startNestedSketch() : Qt::CrossCursor"); -#endif + QApplication::setOverrideCursor(PartSet_Tools::getOperationCursor()); +//#ifdef DEBUG_CURSOR +// qDebug("startNestedSketch() : Qt::CrossCursor"); +//#endif } } } @@ -1206,12 +1294,12 @@ void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation) myIsMouseOverViewProcessed = true; operationMgr()->onValidateOperation(); // when sketch nested operation is stopped the cursor should be restored unconditionally - //if (canChangeCursor(theOperation)) { + if (canChangeCursor(theOperation)) { QApplication::restoreOverrideCursor(); #ifdef DEBUG_CURSOR qDebug("stopNestedSketch() : None"); #endif - //} + } /// improvement to deselect automatically all eventual selected objects, when // returning to the neutral point of the Sketcher bool isClearSelectionPossible = true; @@ -1409,8 +1497,6 @@ bool PartSet_SketcherMgr::canDisplayConstraint(const FeaturePtr& theFeature, std::string aKind = theFeature->getKind(); if (aConstrIds.contains(QString(aKind.c_str()))) { - bool isTypedConstraint = false; - switch (theState) { case PartSet_Tools::Dimensional: { bool isDistance = isDistanceKind(aKind); @@ -1546,17 +1632,19 @@ const QMap& PartSet_SketcherMgr::sh bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const { - bool isFoundObject = false; - + if (!myCurrentSketch.get()) + return false; FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject); if (anObjectFeature.get()) { int aSize = myCurrentSketch->numberOfSubs(); - for (int i = 0; i < aSize && !isFoundObject; i++) { - FeaturePtr aCurrentFeature = myCurrentSketch->subFeature(i); - isFoundObject = myCurrentSketch->subFeature(i) == anObjectFeature; + FeaturePtr aCurrentFeature; + for (int i = 0; i < aSize; i++) { + aCurrentFeature = myCurrentSketch->subFeature(i); + if (myCurrentSketch->subFeature(i) == anObjectFeature) + return true; } } - return isFoundObject; + return false; } void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr& thePlane) @@ -1615,10 +1703,10 @@ bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* t anAISIO = anAIS->impl(); } if (anAIS.get() != NULL) { - Handle(AIS_InteractiveObject) anAISIO = anAIS->impl(); + anAISIO = anAIS->impl(); if (!anAISIO.IsNull()) { - Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(anAISIO); + Handle(PrsDim_Dimension) aDim = Handle(PrsDim_Dimension)::DownCast(anAISIO); if (!aDim.IsNull()) { gp_Pnt aPosition = aDim->GetTextPosition(); @@ -1655,11 +1743,9 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature); SelectionInfo anInfo = anIt.value(); - std::set aSelectedAttributes = anInfo.myAttributes; + std::map aSelectedAttributes = anInfo.myAttributes; std::set aSelectedResults = anInfo.myResults; - ModuleBase_IViewer* aViewer = theWorkshop->viewer(); - XGUI_ModuleConnector* aConnector = dynamic_cast(theWorkshop); XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); @@ -1691,10 +1777,10 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, } for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { ResultPtr aResult = *aIt; - AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult); - if (aAISObj.get() == NULL) + AISObjectPtr aResAISObj = aDisplayer->getAISObject(aResult); + if (aResAISObj.get() == NULL) continue; - Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); + Handle(AIS_InteractiveObject) anAISIO = aResAISObj->impl(); SelectMgr_IndexedMapOfOwner aSelectedOwners; aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners); @@ -1707,10 +1793,10 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, const TopoDS_Shape& aShape = anOwner->Shape(); TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); if (aShapeType == TopAbs_VERTEX) { - AttributePtr aPntAttr = + std::pair aPntAttrIndex = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch); - if (aPntAttr.get() != NULL && - aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) + if (aPntAttrIndex.first.get() != NULL && + aSelectedAttributes.find(aPntAttrIndex.first) != aSelectedAttributes.end()) theOwnersToSelect.Add(anOwner); else if (isSameShape && anInfo.myLocalSelectedShapes.Contains(aShape)) { theOwnersToSelect.Add(anOwner); @@ -1730,13 +1816,13 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, // 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++ ) { + 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)) + Handle(StdSelect_BRepOwner)::DownCast(aSelectedOwners(i)); + if (anOwner.IsNull() || !anOwner->HasShape() || theOwnersToSelect.FindIndex(anOwner)) continue; - // select whole result - theOwnersToSelect.Add(anOwner); + // select whole result + theOwnersToSelect.Add(anOwner); } } } @@ -1770,8 +1856,8 @@ void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState) ModuleBase_OperationFeature* aFOperation = dynamic_cast (getCurrentOperation()); if (aFOperation) { - if (PartSet_SketcherMgr::isSketchOperation(aFOperation) || - isNestedSketchOperation(aFOperation) && + if ((PartSet_SketcherMgr::isSketchOperation(aFOperation) || + isNestedSketchOperation(aFOperation)) && thePreviousState == ModuleBase_ModelWidget::ModifiedInPP) { FeaturePtr aFeature = aFOperation->feature(); visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); @@ -1779,26 +1865,26 @@ void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState) } } -void PartSet_SketcherMgr::customizePresentation(const ObjectPtr& theObject) -{ - ModuleBase_OperationFeature* aFOperation = dynamic_cast - (getCurrentOperation()); - if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) || - isNestedSketchOperation(aFOperation))) - SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]); - - // update entities selection priorities - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - if (aFeature.get() && PartSet_SketcherMgr::isEntity(aFeature->getKind())) { - // update priority for feature - updateSelectionPriority(aFeature, aFeature); - // update priority for results of the feature - std::list aResults = aFeature->results(); - std::list::const_iterator anIt = aResults.begin(), aLastIt = aResults.end(); - for (; anIt != aLastIt; anIt++) - updateSelectionPriority(*anIt, aFeature); - } -} +//void PartSet_SketcherMgr::customisePresentation(const ObjectPtr& theObject) +//{ +// ModuleBase_OperationFeature* aFOperation = dynamic_cast +// (getCurrentOperation()); +// if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) || +// isNestedSketchOperation(aFOperation))) +// SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]); +// +// // update entities selection priorities +// FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); +// if (aFeature.get() && PartSet_SketcherMgr::isEntity(aFeature->getKind())) { +// // update priority for feature +// updateSelectionPriority(aFeature, aFeature); +// // update priority for results of the feature +// std::list aResults = aFeature->results(); +// std::list::const_iterator anIt = aResults.begin(), aLastIt = aResults.end(); +// for (; anIt != aLastIt; anIt++) +// updateSelectionPriority(*anIt, aFeature); +// } +//} ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const { @@ -1830,9 +1916,6 @@ void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature, if (isEditOperation || !theFeature.get()) return; - ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); - XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); - // 1. change visibility of the object itself, here the presentable object is processed, // e.g. constraints features //FeaturePtr aFeature = aFOperation->feature(); @@ -1919,8 +2002,8 @@ void PartSet_SketcherMgr::storeSelection(const SelectionType theType, std::list aResults = aFeature->results(); std::list::const_iterator aIt; for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - ResultPtr aResult = *aIt; - getAttributesOrResults(anOwner, aFeature, aSketch, aResult, + ResultPtr aCurResult = *aIt; + getAttributesOrResults(anOwner, aFeature, aSketch, aCurResult, anInfo.myAttributes, anInfo.myResults, anInfo.myLocalSelectedShapes); } } @@ -1954,6 +2037,7 @@ void PartSet_SketcherMgr::onShowConstraintsToggle(int theType, bool theState) PartSet_Tools::ConstraintVisibleState aType = (PartSet_Tools::ConstraintVisibleState)theType; updateBySketchParameters(aType, theState); + myModule->workshop()->viewer()->update(); } void PartSet_SketcherMgr::updateBySketchParameters( @@ -1970,8 +2054,6 @@ void PartSet_SketcherMgr::updateBySketchParameters( case PartSet_Tools::Geometrical: case PartSet_Tools::Dimensional: { if (aPrevState != theState) { - ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); - XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); int aNumberOfSubs = myCurrentSketch->numberOfSubs(); for (int i = 0; i < aNumberOfSubs; i++) { FeaturePtr aSubFeature = myCurrentSketch->subFeature(i); @@ -1988,11 +2070,16 @@ void PartSet_SketcherMgr::updateBySketchParameters( if (aPrevState != theState) { /// call all sketch features redisplay, the expression state will be corrected in customize /// of distance presentation + SketcherPrs_Tools::ParameterStyle aStyle = myIsConstraintsShown[PartSet_Tools::Expressions] + ? SketcherPrs_Tools::ParameterText : SketcherPrs_Tools::ParameterValue; + SketcherPrs_Tools::setParameterStyle(aStyle); Events_ID anEventId = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); PartSet_Tools::sendSubFeaturesEvent(myCurrentSketch, anEventId); } } break; + default: // [to avoid compilation warning] + break; } } @@ -2129,9 +2216,9 @@ void PartSet_SketcherMgr::processEvent(const std::shared_ptr& th FeaturePtr aFeature = std::dynamic_pointer_cast(*aIt); if (aFeature.get()) { std::list aRes = aFeature->results(); - std::list::const_iterator aIt; - for (aIt = aRes.cbegin(); aIt != aRes.cend(); ++aIt) { - ModuleBase_ViewerPrsPtr aPrsPtr(new ModuleBase_ViewerPrs(*aIt)); + std::list::const_iterator aRIt; + for (aRIt = aRes.cbegin(); aRIt != aRes.cend(); ++aRIt) { + ModuleBase_ViewerPrsPtr aPrsPtr(new ModuleBase_ViewerPrs(*aRIt)); aPrsList.append(aPrsPtr); } } @@ -2142,6 +2229,137 @@ void PartSet_SketcherMgr::processEvent(const std::shared_ptr& th } } +bool isExternal(const ObjectPtr& theObject) +{ + AttributeSelectionPtr aAttr = + theObject->data()->selection(SketchPlugin_SketchEntity::EXTERNAL_ID()); + if (aAttr) + return aAttr->context().get() != NULL && !aAttr->isInvalid(); + return false; +} + +bool isCopy(const ObjectPtr& theObject) +{ + AttributeBooleanPtr anAttr = theObject->data()->boolean(SketchPlugin_SketchEntity::COPY_ID()); + if (anAttr.get()) + return anAttr->value(); + return false; +} + +bool isIncludeToResult(const ObjectPtr& theObject) +{ + AttributeBooleanPtr anAttr; + std::set aRefsToMe = theObject->data()->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsToMe.cbegin(); aIt != aRefsToMe.cend(); ++aIt) { + if ((*aIt)->id() == SketchPlugin_Projection::PROJECTED_FEATURE_ID()) { + FeaturePtr aFeature = std::dynamic_pointer_cast((*aIt)->owner()); + if (aFeature.get() && !aFeature->isMacro()) { + anAttr = aFeature->data()->boolean(SketchPlugin_Projection::INCLUDE_INTO_RESULT()); + if (anAttr.get()) + return anAttr->value(); + } + } + } + return true; +} + +//************************************************************************************** +std::vector PartSet_SketcherMgr::colorOfObject(const ObjectPtr& theObject, + const FeaturePtr& theFeature, bool isConstruction) const +{ + PartSet_OverconstraintListener* aOCListener = myModule->overconstraintListener(); + std::string aKind = theFeature->getKind(); + + if (aOCListener->isConflictingObject(theObject)) { + return Config_PropManager::color("Visualization", "sketch_overconstraint_color"); + } + if (isDistanceKind(aKind)) { + return Config_PropManager::color("Visualization", "sketch_dimension_color"); + } + if (isExternal(theFeature)) + return Config_PropManager::color("Visualization", "sketch_external_color"); + + if (aOCListener->isFullyConstrained()) { + return Config_PropManager::color("Visualization", "sketch_fully_constrained_color"); + } + if (aKind == SketchPlugin_ConstraintCoincidence::ID()) + return std::vector(3, 0); + + if (isConstruction) + return Config_PropManager::color("Visualization", "sketch_auxiliary_color"); + + return Config_PropManager::color("Visualization", "sketch_entity_color"); +} + +//************************************************************************************** +void PartSet_SketcherMgr::customizeSketchPresentation(const ObjectPtr& theObject, + const AISObjectPtr& thePrs) const +{ + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + + // set color from preferences + std::shared_ptr anAuxiliaryAttr = + aFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID()); + bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value(); + + std::vector aColor = colorOfObject(theObject, aFeature, isConstruction); + if (!aColor.empty()) { + // The code below causes redisplay again + if (ModelAPI_Session::get()->isOperation()) { + AttributeIntArrayPtr aColorAttr = theObject->data()->intArray(ModelAPI_Result::COLOR_ID()); + if (aColorAttr.get()) { + aColorAttr->setSize(3, false); + // Set the color attribute in order do not use default colors in the presentation object + for (int i = 0; i < 3; i++) + aColorAttr->setValue(i, aColor[i], false); + } + } + thePrs->setColor(aColor[0], aColor[1], aColor[2]); + } + + int aShapeType = thePrs->getShapeType(); + // a compound is processed like the edge because the + // arc feature uses the compound for presentable AIS + if (aShapeType != 6/*an edge*/ && aShapeType != 7/*a vertex*/ && aShapeType != 0/*compound*/) + return; + + int aWidth = Config_PropManager::integer("Visualization", "sketch_line_width"); + if (isExternal(aFeature)) { + thePrs->setWidth(isIncludeToResult(aFeature)? aWidth : 1); + return; + } + std::string aKind = aFeature->getKind(); + if (isDistanceKind(aKind)) + return; + + if (aShapeType == 6 || aShapeType == 0) { // if this is an edge or a compound + if (isConstruction) { + // Set axilliary line + thePrs->setWidth(SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY()); + thePrs->setLineStyle(SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY()); + } + else { + thePrs->setWidth(aWidth); + thePrs->setLineStyle(SketchPlugin_SketchEntity::SKETCH_LINE_STYLE()); + } + } + else if (aShapeType == 7) { // otherwise this is a vertex + // The width value do not have effect on the point presentation. + // It is defined in order to extend selection area of the object. + thePrs->setWidth(17); + // thePrs->setPointMarker(1, 1.); // Set point as a '+' symbol + } + if (isCopy(aFeature) || !isIncludeToResult(aFeature)) { + double aPrsWidth = thePrs->width(); + thePrs->setWidth(aPrsWidth / 2.5); + } + + double aDeflection = Config_PropManager::real("Visualization", "construction_deflection"); + thePrs->setDeflection(aDeflection); +} + +//************************************************************************************* void PartSet_Fitter::fitAll(Handle(V3d_View) theView) { CompositeFeaturePtr aSketch = mySketchMgr->activeSketch(); @@ -2171,10 +2389,10 @@ void PartSet_Fitter::fitAll(Handle(V3d_View) theView) for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { aRes = (*aIt); if (aRes->isDisplayed()) { - FeaturePtr aFeature = ModelAPI_Feature::feature(aRes); - if (aFeature.get()) { + FeaturePtr aCurFeature = ModelAPI_Feature::feature(aRes); + if (aCurFeature.get()) { std::shared_ptr aSPFeature = - std::dynamic_pointer_cast(aFeature); + std::dynamic_pointer_cast(aCurFeature); if (aSPFeature.get()) { bool isAxiliary = aSPFeature->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value();