From: nds Date: Mon, 25 Jul 2016 12:13:54 +0000 (+0300) Subject: Correction for restart of point create operation. X-Git-Tag: V_2.5.0~177 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c0a6e5394839f5951f2122370895551b5501dbd4;p=modules%2Fshaper.git Correction for restart of point create operation. --- diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp index adaf45907..e7a360e78 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp @@ -7,6 +7,7 @@ #include "ModelGeomAlgo_Point2D.h" #include +#include #include #include @@ -16,6 +17,8 @@ #include #include #include +#include +#include namespace ModelGeomAlgo_Point2D { std::shared_ptr getPointOfRefAttr(ModelAPI_Feature* theFeature, @@ -32,37 +35,37 @@ namespace ModelGeomAlgo_Point2D { FeaturePtr aFeature; std::shared_ptr anAttr = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute)); - if(!anAttr.get()) { - return std::shared_ptr(); + if(anAttr.get() && anAttr->isInitialized()) { + aFeature = ModelAPI_Feature::feature(anAttr->object()); + if (aFeature.get()) { + bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() && + !theObjectFeatureAttribute.empty() && + aFeature->getKind() == theObjectFeatureKind; + if(aFeatureOfObjectKind) + aPointAttr = std::dynamic_pointer_cast( + aFeature->data()->attribute(theObjectFeatureAttribute)); + else if (anAttr->attr()) + aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); + } } - aFeature = ModelAPI_Feature::feature(anAttr->object()); - - bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() && - !theObjectFeatureAttribute.empty() && - aFeature->getKind() == theObjectFeatureKind; - if (aFeature.get() && aFeatureOfObjectKind) - aPointAttr = std::dynamic_pointer_cast( - aFeature->data()->attribute(theObjectFeatureAttribute)); - else if (anAttr->attr()) - aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); - return aPointAttr; } - void getPointsOfReference(const std::shared_ptr& theFeature, + void getPointsOfReference(const std::shared_ptr& theObject, const std::string& theReferenceFeatureKind, std::set >& theAttributes, const std::string& theObjectFeatureKind, const std::string& theObjectFeatureAttribute) { - const std::set& aRefsList = theFeature->data()->refsToMe(); + // find by feature + const std::set& aRefsList = theObject->data()->refsToMe(); std::set::const_iterator aIt; for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { std::shared_ptr aAttr = (*aIt); FeaturePtr aRefFeature = std::dynamic_pointer_cast(aAttr->owner()); if (aRefFeature->getKind() == theReferenceFeatureKind) { std::list anAttributes = - theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); + aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); std::list::iterator anIter = anAttributes.begin(); // it searches the first point of AttributeRefAtt std::shared_ptr aPointAttr; @@ -78,6 +81,17 @@ namespace ModelGeomAlgo_Point2D { } } } + // find by results + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + if (aFeature.get()) { + const std::list > aResults = aFeature->results(); + std::list >::const_iterator aRIter = aResults.begin(); + for (; aRIter != aResults.cend(); aRIter++) { + ResultPtr aResult = *aRIter; + getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind, + theObjectFeatureAttribute); + } + } } void getPointsInsideShape(const std::shared_ptr theBaseShape, @@ -92,12 +106,28 @@ namespace ModelGeomAlgo_Point2D { for (; anIt != aLast; anIt++) { std::shared_ptr anAttribute = *anIt; std::shared_ptr aPnt2d = anAttribute->pnt(); - std::shared_ptr aPnt = aPnt2d->to3D(theOrigin, theDirX, theDirY); - std::shared_ptr aVertexShape(new GeomAPI_Vertex(aPnt->x(), aPnt->y(), aPnt->z())); - if (GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape)) - thePoints.insert(aPnt); + std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); + std::shared_ptr aProjectedPoint; + if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) + thePoints.insert(aProjectedPoint); } } + bool isPointOnEdge(const std::shared_ptr theBaseShape, + const std::shared_ptr& thePoint, + std::shared_ptr& theProjectedPoint) + { + bool isInside = false; + if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) { + std::shared_ptr aLineEdge(new GeomAPI_Edge(theBaseShape)); + std::shared_ptr aLine = aLineEdge->line(); + theProjectedPoint = aLine->project(thePoint); + + std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), + theProjectedPoint->y(), theProjectedPoint->z())); + isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape); + } + return isInside; + } } // namespace ModelGeomAlgo_Point2D diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h index b79aaff9d..b70ef961e 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h @@ -10,6 +10,7 @@ #include "ModelGeomAlgo.h" class ModelAPI_Feature; +class ModelAPI_Object; class GeomAPI_Shape; class GeomAPI_Pnt; class GeomAPI_Dir; @@ -17,6 +18,7 @@ class GeomAPI_Dir; class GeomDataAPI_Point2D; #include +#include #include @@ -36,13 +38,13 @@ namespace ModelGeomAlgo_Point2D { /// Fills container of point 2D attributes, which refer to the feature through the references /// features with the given kind - /// \param theFeature a feature where references should be searched (e.g. a sketch line) + /// \param theObject an object where references should be searched (e.g. a sketch line or result) /// \param theReferenceFeatureKind a kind of the feature to be processed (e.g. coincidence constraint) /// \param theAttributes a container of found point 2D attributes /// \param theObjectFeatureKind a feature kind in object of attribute that satisfies the search /// \param theObjectFeatureAttribute a feature attribute in object that satisfies the search /// \returns found point attribute or NULL - MODELGEOMALGO_EXPORT void getPointsOfReference(const std::shared_ptr& theFeature, + MODELGEOMALGO_EXPORT void getPointsOfReference(const std::shared_ptr& theObject, const std::string& theReferenceFeatureKind, std::set >& theAttributes, const std::string& theObjectFeatureKind = "", @@ -62,6 +64,14 @@ namespace ModelGeomAlgo_Point2D { const std::shared_ptr& theDirX, const std::shared_ptr& theDirY, std::set >& thePoints); + + /// Finds projected point to the given shape line + /// \param theBaseShape a shape of check + /// \param thePoint [in] a point to project + /// \param theProjectedPoint [out] a projected point + MODELGEOMALGO_EXPORT bool isPointOnEdge(const std::shared_ptr theBaseShape, + const std::shared_ptr& thePoint, + std::shared_ptr& theProjectedPoint); } #endif diff --git a/src/PartSet/PartSet_MenuMgr.cpp b/src/PartSet/PartSet_MenuMgr.cpp index 7b60d802c..676ed3790 100644 --- a/src/PartSet/PartSet_MenuMgr.cpp +++ b/src/PartSet/PartSet_MenuMgr.cpp @@ -112,7 +112,8 @@ bool PartSet_MenuMgr::addViewerMenu(const QMap& theStdActions ModuleBase_Operation* anOperation = myModule->workshop()->currentOperation(); if (!PartSet_SketcherMgr::isSketchOperation(anOperation) && - !PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) + !PartSet_SketcherMgr::isNestedSketchOperation(anOperation, + myModule->sketchMgr()->activeSketch())) return false; myCoinsideLines.clear(); @@ -205,7 +206,8 @@ void PartSet_MenuMgr::updateViewerMenu(const QMap& theStdActi ModuleBase_Operation* anOperation = myModule->workshop()->currentOperation(); bool isActiveSketch = PartSet_SketcherMgr::isSketchOperation(anOperation) || - PartSet_SketcherMgr::isNestedSketchOperation(anOperation); + PartSet_SketcherMgr::isNestedSketchOperation(anOperation, + myModule->sketchMgr()->activeSketch()); if (isActiveSketch) { theStdActions["WIREFRAME_CMD"]->setEnabled(false); theStdActions["SHADING_CMD"]->setEnabled(false); @@ -326,15 +328,16 @@ void PartSet_MenuMgr::setAuxiliary(const bool isChecked) { ModuleBase_Operation* anOperation = myModule->workshop()->currentOperation(); + CompositeFeaturePtr aSketch = myModule->sketchMgr()->activeSketch(); bool isActiveSketch = PartSet_SketcherMgr::isSketchOperation(anOperation) || - PartSet_SketcherMgr::isNestedSketchOperation(anOperation); + PartSet_SketcherMgr::isNestedSketchOperation(anOperation, aSketch); if (!isActiveSketch) return; QObjectPtrList anObjects; bool isUseTransaction = false; // 1. change auxiliary type of a created feature - if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation) && + if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation, aSketch) && PartSet_SketcherMgr::isEntity(anOperation->id().toStdString()) ) { ModuleBase_OperationFeature* aFOperation = dynamic_cast (anOperation); @@ -391,14 +394,15 @@ bool PartSet_MenuMgr::canSetAuxiliary(bool& theValue) const bool anEnabled = false; ModuleBase_Operation* anOperation = myModule->workshop()->currentOperation(); + CompositeFeaturePtr aSketch = myModule->sketchMgr()->activeSketch(); bool isActiveSketch = PartSet_SketcherMgr::isSketchOperation(anOperation) || - PartSet_SketcherMgr::isNestedSketchOperation(anOperation); + PartSet_SketcherMgr::isNestedSketchOperation(anOperation, aSketch); if (!isActiveSketch) return anEnabled; QObjectPtrList anObjects; // 1. change auxiliary type of a created feature - if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation) && + if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation, aSketch) && PartSet_SketcherMgr::isEntity(anOperation->id().toStdString()) ) { ModuleBase_OperationFeature* aFOperation = dynamic_cast(anOperation); if (aFOperation) @@ -407,7 +411,8 @@ bool PartSet_MenuMgr::canSetAuxiliary(bool& theValue) const else { /// The operation should not be aborted here, because the method does not changed /// the auxilliary state, but checks the possibility to perform this - ///if (PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) + ///if (PartSet_SketcherMgr::isNestedSketchOperation(anOperation, + // myModule->sketchMgr()->activeSketch())) /// anOperation->abort(); // 2. change auxiliary type of selected sketch entities ModuleBase_ISelection* aSelection = myModule->workshop()->selection(); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 6ca6ad713..120d4d6ac 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -10,6 +10,7 @@ #include "PartSet_WidgetPoint2DFlyout.h" #include "PartSet_WidgetShapeSelector.h" #include "PartSet_WidgetMultiSelector.h" +#include "PartSet_WidgetSubShapeSelector.h" #include "PartSet_WidgetEditor.h" #include "PartSet_WidgetFileSelector.h" #include "PartSet_WidgetSketchCreator.h" @@ -258,7 +259,7 @@ void PartSet_Module::connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, c void PartSet_Module::operationCommitted(ModuleBase_Operation* theOperation) { - if (PartSet_SketcherMgr::isNestedSketchOperation(theOperation)) { + if (PartSet_SketcherMgr::isNestedSketchOperation(theOperation, sketchMgr()->activeSketch())) { mySketchMgr->commitNestedSketch(theOperation); } @@ -368,7 +369,8 @@ void PartSet_Module::updateSketcherOnStart(ModuleBase_Operation* theOperation) if (PartSet_SketcherMgr::isSketchOperation(theOperation)) { mySketchMgr->startSketch(theOperation); } - else if (PartSet_SketcherMgr::isNestedSketchOperation(theOperation)) { + else if (PartSet_SketcherMgr::isNestedSketchOperation(theOperation, + sketchMgr()->activeSketch())) { mySketchMgr->startNestedSketch(theOperation); } } @@ -399,7 +401,7 @@ void PartSet_Module::operationStopped(ModuleBase_Operation* theOperation) bool isModifiedResults = myCustomPrs->deactivate(ModuleBase_IModule::CustomizeResults, false); bool isModified = isModifiedArgs || isModifiedResults; - if (PartSet_SketcherMgr::isNestedSketchOperation(theOperation)) { + if (PartSet_SketcherMgr::isNestedSketchOperation(theOperation, sketchMgr()->activeSketch())) { mySketchMgr->stopNestedSketch(theOperation); } else if (PartSet_SketcherMgr::isSketchOperation(theOperation)) @@ -488,7 +490,8 @@ bool PartSet_Module::canActivateSelection(const ObjectPtr& theObject) const ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); bool isSketchOp = PartSet_SketcherMgr::isSketchOperation(anOperation), - isNestedOp = PartSet_SketcherMgr::isNestedSketchOperation(anOperation); + isNestedOp = PartSet_SketcherMgr::isNestedSketchOperation(anOperation, + sketchMgr()->activeSketch()); if (isSketchOp || isNestedOp) { // in active sketch operation it is possible to activate operation object in selection // in the edit operation, e.g. points of the line can be moved when the line is edited @@ -722,6 +725,12 @@ ModuleBase_ModelWidget* PartSet_Module::createWidgetByType(const std::string& th aShapeSelectorWgt->setSketcher(mySketchMgr->activeSketch()); aWgt = aShapeSelectorWgt; } + else if (theType == "sketch_sub_shape_selector") { + PartSet_WidgetSubShapeSelector* aSubShapeSelectorWgt = + new PartSet_WidgetSubShapeSelector(theParent, aWorkshop, theWidgetApi); + aSubShapeSelectorWgt->setSketcher(mySketchMgr->activeSketch()); + aWgt = aSubShapeSelectorWgt; + } else if (theType == WDG_DOUBLEVALUE_EDITOR) { aWgt = new PartSet_WidgetEditor(theParent, aWorkshop, theWidgetApi); } else if (theType == "export_file_selector") { @@ -762,7 +771,8 @@ bool PartSet_Module::deleteObjects() // 1. check whether the delete should be processed in the module ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); bool isSketchOp = PartSet_SketcherMgr::isSketchOperation(anOperation), - isNestedOp = PartSet_SketcherMgr::isNestedSketchOperation(anOperation); + isNestedOp = PartSet_SketcherMgr::isNestedSketchOperation(anOperation, + sketchMgr()->activeSketch()); if (isSketchOp || isNestedOp) { isProcessed = true; // 2. find selected presentations @@ -1313,7 +1323,8 @@ GeomShapePtr PartSet_Module::findShape(const AttributePtr& theAttribute) GeomShapePtr aGeomShape; ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - if (anOperation && PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) { + if (anOperation && PartSet_SketcherMgr::isNestedSketchOperation(anOperation, + sketchMgr()->activeSketch())) { aGeomShape = PartSet_Tools::findShapeBy2DPoint(theAttribute, myWorkshop); } return aGeomShape; diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 0974ef4b6..78d9dfa02 100755 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -96,44 +96,6 @@ //#define DEBUG_CURSOR -/// Returns list of unique objects by sum of objects from List1 and List2 -/*QList getSumList(const QList& theList1, - const QList& theList2) -{ - QList aRes; - foreach (ModuleBase_ViewerPrsPtr aPrs, theList1) { - if (!aRes.contains(aPrs)) - aRes.append(aPrs); - } - foreach (ModuleBase_ViewerPrsPtr aPrs, theList2) { - if (!aRes.contains(aPrs)) - aRes.append(aPrs); - } - return aRes; -}*/ - -// Fills the list of features the list of selected presentations. -// \param theList a list of selected presentations -// \param theSketch a sketch to project a vertex shape of a presentation to the plane -// and find the corresponded attribute -// \param theFeatureList an output list of features -void fillFeatureList(const QList& theList, - const FeaturePtr theSketch, - QList& theFeatureList) -{ - QList aRes; - - QList::const_iterator anIt = theList.begin(), - aLast = theList.end(); - for (; anIt != aLast; anIt++) - { - ModuleBase_ViewerPrsPtr aPrs = *anIt; - FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs->object()); - if (aFeature.get() && !theFeatureList.contains(aFeature)) - theFeatureList.append(aFeature); - } -} - /// Fills attribute and result lists by the selected owner. In case if the attribute is found, /// by the owner shape, it is put to the list. Otherwise if type of owner shape is edge, put the function /// result as is to the list of results. @@ -229,7 +191,7 @@ void PartSet_SketcherMgr::onEnterViewPort() } } - if (!isNestedCreateOperation(getCurrentOperation())) + if (!isNestedCreateOperation(getCurrentOperation(), activeSketch())) return; operationMgr()->onValidateOperation(); @@ -266,7 +228,7 @@ void PartSet_SketcherMgr::onLeaveViewPort() #endif } - if (!isNestedCreateOperation(getCurrentOperation())) + if (!isNestedCreateOperation(getCurrentOperation(), activeSketch())) return; // the method should be performed if the popup menu is called, @@ -305,7 +267,7 @@ void PartSet_SketcherMgr::onLeaveViewPort() void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel() { - if (!isNestedEditOperation(getCurrentOperation()) || + if (!isNestedEditOperation(getCurrentOperation(), myModule->sketchMgr()->activeSketch()) || myModule->sketchReentranceMgr()->isInternalEditActive()) return; // it is necessary to save current selection in order to restore it after the values are modifed @@ -319,7 +281,7 @@ void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel() void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel() { - if (!isNestedEditOperation(getCurrentOperation()) || + if (!isNestedEditOperation(getCurrentOperation(), myModule->sketchMgr()->activeSketch()) || myModule->sketchReentranceMgr()->isInternalEditActive()) { myModule->sketchReentranceMgr()->updateInternalEditActiveState(); return; @@ -377,7 +339,7 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE return; bool isSketcher = isSketchOperation(aFOperation); - bool isSketchOpe = isNestedSketchOperation(aFOperation); + bool isSketchOpe = isNestedSketchOperation(aFOperation, activeSketch()); // Avoid non-sketch operations if ((!isSketchOpe) && (!isSketcher)) @@ -412,6 +374,9 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE myDragDone = false; myPreviousDrawModeEnabled = aViewer->enableDrawMode(false); + // selection should be restored before edit operation start to process the + // selected entities, e.g. selection of point(attribute on a line) should edit the point + restoreSelection(); launchEditing(); if (aFeature.get() != NULL) { std::shared_ptr aSPFeature = @@ -433,7 +398,9 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE myDragDone = false; myPreviousDrawModeEnabled = aViewer->enableDrawMode(false); - + // selection should be restored before edit operation start to process the + // selected entities, e.g. selection of point(attribute on a line) should edit the point + restoreSelection(); launchEditing(); restoreSelection(); } @@ -451,7 +418,7 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse return; ModuleBase_Operation* aOp = getCurrentOperation(); if (aOp) { - if (isNestedSketchOperation(aOp)) { + if (isNestedSketchOperation(aOp, activeSketch())) { //get2dPoint(theWnd, theEvent, myClickedPoint); // Only for sketcher operations @@ -487,7 +454,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent)) return; - if (isNestedCreateOperation(getCurrentOperation())) { + if (isNestedCreateOperation(getCurrentOperation(), activeSketch())) { // 1. perform the widget mouse move functionality and display the presentation // the mouse move should be processed in the widget, if it can in order to visualize correct // presentation. These widgets correct the feature attribute according to the mouse position @@ -733,25 +700,6 @@ void PartSet_SketcherMgr::clearClickedFlags() myCurrentPoint.clear(); } -const QStringList& PartSet_SketcherMgr::sketchOperationIdList() -{ - static QStringList aIds; - if (aIds.size() == 0) { - aIds << SketchPlugin_Line::ID().c_str(); - aIds << SketchPlugin_Point::ID().c_str(); - aIds << SketchPlugin_Arc::ID().c_str(); - aIds << SketchPlugin_Circle::ID().c_str(); - aIds << SketchPlugin_ConstraintFillet::ID().c_str(); - aIds << SketchPlugin_IntersectionPoint::ID().c_str(); - // TODO - // SketchRectangle is a python feature, so its ID is passed just as a string - aIds << "SketchRectangle"; - aIds.append(replicationsIdList()); - aIds.append(constraintsIdList()); - } - return aIds; -} - const QStringList& PartSet_SketcherMgr::replicationsIdList() { static QStringList aReplicationIds; @@ -812,24 +760,38 @@ bool PartSet_SketcherMgr::isSketchOperation(ModuleBase_Operation* theOperation) return theOperation && theOperation->id().toStdString() == SketchPlugin_Sketch::ID(); } -bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOperation) +bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOperation, + const CompositeFeaturePtr& theSketch) { - return theOperation && - PartSet_SketcherMgr::sketchOperationIdList().contains(theOperation->id()); + bool aNestedSketch = false; + + if (theOperation && theSketch.get()) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + aNestedSketch = theSketch->isSub(aFeature); + } + } + return aNestedSketch; } -bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation) +bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation, + const CompositeFeaturePtr& theSketch) { ModuleBase_OperationFeature* aFOperation = dynamic_cast (theOperation); - return aFOperation && !aFOperation->isEditOperation() && isNestedSketchOperation(aFOperation); + return aFOperation && !aFOperation->isEditOperation() && + isNestedSketchOperation(aFOperation, theSketch); } -bool PartSet_SketcherMgr::isNestedEditOperation(ModuleBase_Operation* theOperation) +bool PartSet_SketcherMgr::isNestedEditOperation(ModuleBase_Operation* theOperation, + const CompositeFeaturePtr& theSketch) { ModuleBase_OperationFeature* aFOperation = dynamic_cast (theOperation); - return aFOperation && aFOperation->isEditOperation() && isNestedSketchOperation(aFOperation); + return aFOperation && aFOperation->isEditOperation() && + isNestedSketchOperation(aFOperation, theSketch); } bool PartSet_SketcherMgr::isEntity(const std::string& theId) @@ -973,7 +935,6 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); // Erase all sketcher objects - QStringList aSketchIds = sketchOperationIdList(); QObjectPtrList aObjects = aDisplayer->displayedObjects(); foreach (ObjectPtr aObj, aObjects) { DataPtr aObjData = aObj->data(); @@ -1054,7 +1015,7 @@ void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation) void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation) { - if (isNestedCreateOperation(theOperation)) { + if (isNestedCreateOperation(theOperation, activeSketch())) { ModuleBase_OperationFeature* aFOperation = dynamic_cast (theOperation); if (aFOperation) { @@ -1080,7 +1041,7 @@ bool PartSet_SketcherMgr::operationActivatedByPreselection() { bool isOperationStopped = false; ModuleBase_Operation* anOperation = getCurrentOperation(); - if(anOperation && PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) { + if(anOperation && PartSet_SketcherMgr::isNestedSketchOperation(anOperation, activeSketch())) { // Set final definitions if they are necessary //propertyPanelDefined(aOperation); /// Commit sketcher operations automatically @@ -1108,12 +1069,12 @@ bool PartSet_SketcherMgr::operationActivatedByPreselection() bool PartSet_SketcherMgr::canUndo() const { - return isNestedCreateOperation(getCurrentOperation()); + return isNestedCreateOperation(getCurrentOperation(), activeSketch()); } bool PartSet_SketcherMgr::canRedo() const { - return isNestedCreateOperation(getCurrentOperation()); + return isNestedCreateOperation(getCurrentOperation(), activeSketch()); } bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const @@ -1197,7 +1158,7 @@ bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const // b. the popup menu activated // c. widget editor control #ifndef DEBUG_DO_NOT_BY_ENTER - if (isNestedCreateOperation(getCurrentOperation())) { + if (isNestedCreateOperation(getCurrentOperation(), activeSketch())) { ModuleBase_ModelWidget* anActiveWidget = getActiveWidget(); ModuleBase_WidgetEditor* anEditorWdg = anActiveWidget ? dynamic_cast(anActiveWidget) : 0; // the active widget editor should not influence here. The presentation should be visible always @@ -1362,7 +1323,7 @@ bool PartSet_SketcherMgr::canDisplayCurrentCreatedFeature() const bool PartSet_SketcherMgr::canChangeCursor(ModuleBase_Operation* theOperation) const { - return isNestedCreateOperation(theOperation) || + return isNestedCreateOperation(theOperation, activeSketch()) || myModule->sketchReentranceMgr()->isInternalEditActive(); } @@ -1470,54 +1431,6 @@ bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* t return isValueAccepted; } -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(); - if (!aContext.IsNull()) { - 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(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner(); - if (anOwner->Selectable() != anAISIO) - continue; - getAttributesOrResults(anOwner, theFeature, theSketch, aResult, - aSelectedAttributes, aSelectedResults); - } - for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) { - Handle(SelectMgr_EntityOwner) anOwner = aContext->DetectedOwner(); - if (anOwner.IsNull()) - continue; - if (anOwner->Selectable() != anAISIO) - continue; - getAttributesOrResults(anOwner, theFeature, theSketch, aResult, - aSelectedAttributes, aSelectedResults); - } - } - } - theSelection[theFeature] = std::make_pair(aSelectedAttributes, aSelectedResults); -} - void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, const FeaturePtr& theSketch, ModuleBase_IWorkshop* theWorkshop, @@ -1608,7 +1521,7 @@ void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState) (getCurrentOperation()); if (aFOperation) { if (PartSet_SketcherMgr::isSketchOperation(aFOperation) || - PartSet_SketcherMgr::isNestedSketchOperation(aFOperation) && + PartSet_SketcherMgr::isNestedSketchOperation(aFOperation, activeSketch()) && thePreviousState == ModuleBase_ModelWidget::ModifiedInPP) { FeaturePtr aFeature = aFOperation->feature(); visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); @@ -1621,7 +1534,7 @@ void PartSet_SketcherMgr::customizePresentation(const ObjectPtr& theObject) ModuleBase_OperationFeature* aFOperation = dynamic_cast (getCurrentOperation()); if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) || - PartSet_SketcherMgr::isNestedSketchOperation(aFOperation))) + PartSet_SketcherMgr::isNestedSketchOperation(aFOperation, activeSketch()))) SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]); // update entities selection priorities @@ -1700,24 +1613,58 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly) ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_ISelection* aSelect = aWorkshop->selection(); - QList aHighlighted = aSelect->getHighlighted(); + QList aStoredPrs = aSelect->getHighlighted(); QList aFeatureList; - if (theHighlightedOnly) { - fillFeatureList(aHighlighted, myCurrentSketch, aFeatureList); - } - else { - fillFeatureList(aHighlighted, myCurrentSketch, aFeatureList); - - QList aSelected = aSelect->getSelected(ModuleBase_ISelection::AllControls); - fillFeatureList(aSelected, myCurrentSketch, aFeatureList); + if (!theHighlightedOnly) { + 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(); - QList::const_iterator anIt = aFeatureList.begin(), aLast = aFeatureList.end(); + + QList::const_iterator anIt = aStoredPrs.begin(), aLast = aStoredPrs.end(); + + CompositeFeaturePtr aSketch = activeSketch(); for (; anIt != aLast; anIt++) { - getCurrentSelection(*anIt, myCurrentSketch, aWorkshop, myCurrentSelection); + ModuleBase_ViewerPrsPtr aPrs = *anIt; + ObjectPtr anObject = aPrs->object(); + if (!anObject.get()) + continue; + + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + FeaturePtr aFeature; + if (aResult.get()) + aFeature = ModelAPI_Feature::feature(aResult); + else + aFeature = std::dynamic_pointer_cast(anObject); + + + 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; + } + + Handle(SelectMgr_EntityOwner) anOwner = aPrs->owner(); + if (aResult.get()) { + getAttributesOrResults(anOwner, aFeature, aSketch, aResult, + aSelectedAttributes, aSelectedResults); + } + else { + 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, + aSelectedAttributes, aSelectedResults); + } + } + myCurrentSelection[aFeature] = std::make_pair(aSelectedAttributes, aSelectedResults); } //qDebug(QString(" storeSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str()); } diff --git a/src/PartSet/PartSet_SketcherMgr.h b/src/PartSet/PartSet_SketcherMgr.h index f8e85809b..1c8d7302c 100644 --- a/src/PartSet/PartSet_SketcherMgr.h +++ b/src/PartSet/PartSet_SketcherMgr.h @@ -91,20 +91,25 @@ public: /// \return the boolean result static bool isSketchOperation(ModuleBase_Operation* theOperation); - /// Returns true if the operation id is in the sketch operation id list + /// Returns true if the operation feature is a sub in the given sketch /// \param theOperation an operation + /// \param theSketch a sketch feature /// \return the boolean result - static bool isNestedSketchOperation(ModuleBase_Operation* theOperation); + static bool isNestedSketchOperation(ModuleBase_Operation* theOperation, + const CompositeFeaturePtr& theSketch); - /// Returns true if the operation is a create nested feature one + /// Returns true if the operation is a create and nested sketch operationn /// \param theOperation a checked operation + /// \param theSketch a sketch feature //// \return boolean value - static bool isNestedCreateOperation(ModuleBase_Operation* theOperation); + static bool isNestedCreateOperation(ModuleBase_Operation* theOperation, + const CompositeFeaturePtr& theSketch); /// Returns true if the operation is an edit nested feature one /// \param theOperation a checked operation //// \return boolean value - static bool isNestedEditOperation(ModuleBase_Operation* theOperation); + static bool isNestedEditOperation(ModuleBase_Operation* theOperation, + const CompositeFeaturePtr& theSketch); /// Returns whether the current operation is a sketch entity - line, point, arc or circle /// \param theId is an id of object @@ -230,9 +235,6 @@ public: /// It nullify internal flags concerned to clicked mouse event void clearClickedFlags(); - /// Returns list of strings which contains id's of sketch operations - static const QStringList& sketchOperationIdList(); - /// Returns list of strings which contains id's of sketch replication operations static const QStringList& replicationsIdList(); @@ -315,20 +317,6 @@ private: typedef QMap, std::set > > FeatureToSelectionMap; - /// Obtains the current selection of the object in the workshop viewer - /// It includes the selection in all modes of activation, even local context - vertices, edges - /// It gets all results of the feature, find an AIS object in the viewer and takes all BRep - /// selection owners. If the owner is vertex, the corresponded attribute is seached in - /// the feature, if the owner is edge, the current result is added to the container of results. - /// \param theFeature a feature or result object - /// \param theSketch a current sketch feature - /// \param theWorkshop a workshop to have an access to AIS context and displayer - /// \param theSelection a container for the selection, to save results and attributres for a feature - static void getCurrentSelection(const FeaturePtr& theFeature, - const FeaturePtr& theSketch, - ModuleBase_IWorkshop* theWorkshop, - FeatureToSelectionMap& theSelection); - /// Applyes the current selection to the object in the workshop viewer /// It includes the selection in all modes of activation, even local context - vertexes, edges /// It gets all results of the feature, find an AIS object in the viewer and takes all BRep diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp index e11f6d61c..fb8ce49e7 100755 --- a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp @@ -146,7 +146,7 @@ bool PartSet_SketcherReetntrantMgr::processMouseMoved(ModuleBase_IViewWindow* /* bool isLineFeature = false, isArcFeature = false; if (aCurrentFeature->getKind() == SketchPlugin_Line::ID()) isLineFeature = anActiveWidget->attributeID() == SketchPlugin_Line::START_ID(); - else if (isTangentArc(aFOperation)) + else if (isTangentArc(aFOperation, module()->sketchMgr()->activeSketch())) isArcFeature = anActiveWidget->attributeID() == SketchPlugin_Arc::TANGENT_POINT_ID(); bool aCanBeActivatedByMove = isLineFeature || isArcFeature; @@ -254,7 +254,8 @@ void PartSet_SketcherReetntrantMgr::onNoMoreWidgets(const std::string& thePrevio if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) return; - if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { + if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation, + module()->sketchMgr()->activeSketch())) { bool isStarted = false; if (!module()->sketchMgr()->sketchSolverError()) { if (myRestartingMode != RM_Forbided) { @@ -301,7 +302,8 @@ void PartSet_SketcherReetntrantMgr::onVertexSelected() ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); std::string anOperationId = anOperation->id().toStdString(); - if (anOperationId == SketchPlugin_Line::ID() || isTangentArc(anOperation)) { + if (anOperationId == SketchPlugin_Line::ID() || + isTangentArc(anOperation, module()->sketchMgr()->activeSketch())) { /// If last line finished on vertex the lines creation sequence has to be break ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel(); ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget(); @@ -344,7 +346,8 @@ bool PartSet_SketcherReetntrantMgr::isActiveMgr() const bool anActive = PartSet_SketcherMgr::isSketchOperation(aCurrentOperation); if (!anActive) { - anActive = PartSet_SketcherMgr::isNestedSketchOperation(aCurrentOperation); + anActive = PartSet_SketcherMgr::isNestedSketchOperation(aCurrentOperation, + module()->sketchMgr()->activeSketch()); if (anActive) { // the manager is not active when the current operation is a usual Edit ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->currentOperation()); @@ -367,7 +370,8 @@ bool PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePrev ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->currentOperation()); - if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { + if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation, + module()->sketchMgr()->activeSketch())) { aFOperation->setEditOperation(true/*, false*/); createInternalFeature(); @@ -468,7 +472,8 @@ void PartSet_SketcherReetntrantMgr::createInternalFeature() ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->currentOperation()); - if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { + if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation, + module()->sketchMgr()->activeSketch())) { FeaturePtr anOperationFeature = aFOperation->feature(); CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); @@ -598,12 +603,13 @@ bool PartSet_SketcherReetntrantMgr::copyReetntrantAttributes(const FeaturePtr& t return aChanged; } -bool PartSet_SketcherReetntrantMgr::isTangentArc(ModuleBase_Operation* theOperation) +bool PartSet_SketcherReetntrantMgr::isTangentArc(ModuleBase_Operation* theOperation, + const CompositeFeaturePtr& theSketch) { bool aTangentArc = false; ModuleBase_OperationFeature* aFOperation = dynamic_cast (theOperation); - if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { + if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation, theSketch)) { FeaturePtr aFeature = aFOperation->feature(); if (aFeature.get() && aFeature->getKind() == SketchPlugin_Arc::ID()) { AttributeStringPtr aTypeAttr = aFeature->data()->string(SketchPlugin_Arc::ARC_TYPE()); diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.h b/src/PartSet/PartSet_SketcherReetntrantMgr.h index 72921d803..81f3433f8 100755 --- a/src/PartSet/PartSet_SketcherReetntrantMgr.h +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.h @@ -160,7 +160,9 @@ private: const std::shared_ptr& theSketch, const bool isTemporary = false); - static bool isTangentArc(ModuleBase_Operation* theOperation); + /// Checks whethe the feature of the given operation has kind an arc and the arc type is tangent + static bool isTangentArc(ModuleBase_Operation* theOperation, + const std::shared_ptr& theSketch); /// Accept All action is enabled if an internal edit is started. It updates the state of the button void updateAcceptAllAction(); diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index e0e577163..9b58bab81 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -134,10 +134,6 @@ bool PartSet_WidgetPoint2D::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr if (aModule->sketchReentranceMgr()->isInternalEditActive()) return true; /// when internal edit is started a new feature is created. I has not results, AIS - // workaround for feature, where there is no results - //if (myFeature->getKind() == "SketchRectangle") - // return true; - /// the selection is not possible if the current feature has no presentation for the current /// attribute not in AIS not in results. If so, no object in current feature where make /// coincidence, so selection is not necessary @@ -495,6 +491,15 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, aX, aY); } } + else { + // point is taken from mouse event and set in attribute. It should be done before setting + // coinident constraint to the external line. If a point is created, it should be in the mouse + // clicked point + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + double aX, anY; + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, anY); + setPoint(aX, anY); + } } if (aFixedObject.get()) setConstraintWith(aFixedObject); @@ -528,11 +533,13 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY); } else if (aShape.ShapeType() == TopAbs_EDGE) { - if (!setConstraintWith(aObject)) { - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); - PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); - setPoint(aX, aY); - } + // point is taken from mouse event and set in attribute. It should be done before setting + // coinident constraint to the external line. If a point is created, it should be in the mouse + // clicked point + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); + setPoint(aX, aY); + setConstraintWith(aObject); setValueState(Stored); // in case of edge selection, Apply state should also be updated isAuxiliaryFeature = PartSet_Tools::isAuxiliarySketchEntity(aObject); } diff --git a/src/PartSet/PartSet_WidgetSubShapeSelector.cpp b/src/PartSet/PartSet_WidgetSubShapeSelector.cpp index 21b0277bd..fe3f2a609 100755 --- a/src/PartSet/PartSet_WidgetSubShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetSubShapeSelector.cpp @@ -53,7 +53,7 @@ void PartSet_WidgetSubShapeSelector::mouseMoved(ModuleBase_IViewWindow* theWindo ModuleBase_ISelection* aSelect = myWorkshop->selection(); QList aHighlighted = aSelect->getHighlighted(); - if (aHighlighted.empty()) { + if (!aHighlighted.empty()) { ModuleBase_ViewerPrsPtr aPrs = aHighlighted.first(); if (aPrs.get() && aPrs->object().get()) { ObjectPtr anObject = aPrs->object(); @@ -62,12 +62,13 @@ void PartSet_WidgetSubShapeSelector::mouseMoved(ModuleBase_IViewWindow* theWindo const std::set& aShapes = myCashedShapes[anObject]; if (!aShapes.empty()) { gp_Pnt aPnt = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); - std::shared_ptr aVertexShape(new GeomAPI_Vertex(aPnt.X(), aPnt.Y(), aPnt.Z())); + std::shared_ptr aPoint(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z())); std::set::const_iterator anIt = aShapes.begin(), aLast = aShapes.end(); for (; anIt != aLast; anIt++) { GeomShapePtr aBaseShape = *anIt; - if (GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, aBaseShape)) { + std::shared_ptr aProjectedPoint; + if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, aPoint, aProjectedPoint)) { myCurrentSubShape->setObject(anObject); myCurrentSubShape->setShape(aBaseShape); break; diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 3f1db5400..ec8be9d1f 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -132,14 +132,14 @@ - - + diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index 6642e5436..ee6c1971f 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -231,27 +231,35 @@ QList XGUI_Selection::getHighlighted() const QList aSelectedIds; // Remember of selected address in order to avoid duplicates XGUI_Displayer* aDisplayer = myWorkshop->displayer(); for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) { - ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs()); - Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive(); - if (aSelectedIds.contains((long)anIO.Access())) - continue; - - aSelectedIds.append((long)anIO.Access()); - aPrs->setInteractive(anIO); - - ObjectPtr aResult = aDisplayer->getObject(anIO); - // we should not check the appearance of this feature because there can be some selected shapes - // for one feature - aPrs->setObject(aResult); - if (aContext->HasOpenedContext()) { - TopoDS_Shape aShape = aContext->DetectedShape(); - if (!aShape.IsNull()) { - std::shared_ptr aGeomShape = std::shared_ptr(new GeomAPI_Shape()); - aGeomShape->setImpl(new TopoDS_Shape(aShape)); - aPrs->setShape(aGeomShape); + Handle(SelectMgr_EntityOwner) anOwner = aContext->DetectedOwner(); + if (!anOwner.IsNull()) { + if (aSelectedIds.contains((long)anOwner.Access())) + continue; + aSelectedIds.append((long)anOwner.Access()); + + ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs()); + fillPresentation(aPrs, anOwner); + aPresentations.push_back(aPrs); + } + else { // TODO: check why the entity owner is null here, case is selection point on a line + Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive(); + ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs()); + aPrs->setInteractive(anIO); + + ObjectPtr aResult = aDisplayer->getObject(anIO); + // we should not check the appearance of this feature because there can be some selected shapes + // for one feature + aPrs->setObject(aResult); + if (aContext->HasOpenedContext()) { + TopoDS_Shape aShape = aContext->DetectedShape(); + if (!aShape.IsNull()) { + std::shared_ptr aGeomShape = std::shared_ptr(new GeomAPI_Shape()); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + aPrs->setShape(aGeomShape); + } } + aPresentations.push_back(aPrs); } - aPresentations.push_back(aPrs); } return aPresentations; }