X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_OperationPrs.cpp;h=0e7db772b3c8ee528d645641b3a37ae1db429a76;hb=88ee9b2b81cf93a6324336b57e30cc8a3a487499;hp=9f52a502d035ba62e4f290737138cb6ee668b189;hpb=c3ae28ba30027cc4a6a757ef623f40adaae96ead;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_OperationPrs.cpp b/src/PartSet/PartSet_OperationPrs.cpp old mode 100755 new mode 100644 index 9f52a502d..0e7db772b --- a/src/PartSet/PartSet_OperationPrs.cpp +++ b/src/PartSet/PartSet_OperationPrs.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_OperationPrs.cpp -// Created: 01 Jul 2015 -// Author: Natalia ERMOLAEVA +// 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 +// 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_OperationPrs.h" #include "PartSet_Tools.h" @@ -10,10 +23,15 @@ #include "XGUI_Workshop.h" #include "XGUI_ModuleConnector.h" #include "XGUI_Displayer.h" +#include "XGUI_Tools.h" #include "ModuleBase_Tools.h" #include "ModuleBase_IModule.h" +#include +#include +#include +#include #include #include #include @@ -23,117 +41,132 @@ #include #include #include -#include +#include +#include + +#include +#include #include -#include +#include #include -IMPLEMENT_STANDARD_HANDLE(PartSet_OperationPrs, ViewerData_AISShape); +#include +#include +#include +#include +#include +#include + +//#define DEBUG_EMPTY_SHAPE +//#define DEBUG_OPERATION_PRS + +// multi-rotation/translation operation +//#define DEBUG_HIDE_COPY_ATTRIBUTE +#ifdef DEBUG_HIDE_COPY_ATTRIBUTE +#include +#include +#endif + IMPLEMENT_STANDARD_RTTIEXT(PartSet_OperationPrs, ViewerData_AISShape); PartSet_OperationPrs::PartSet_OperationPrs(ModuleBase_IWorkshop* theWorkshop) - : ViewerData_AISShape(TopoDS_Shape()), myFeature(FeaturePtr()), myWorkshop(theWorkshop) -{ - myShapeColor = ModuleBase_Tools::color("Visualization", "construction_plane_color", "1,1,0"); - myResultColor = ModuleBase_Tools::color("Visualization", "construction_plane_color", "0,1,0"); -} - -bool PartSet_OperationPrs::canActivate(const FeaturePtr& theFeature) +: ViewerData_AISShape(TopoDS_Shape()), myWorkshop(theWorkshop), myUseAISWidth(false) { - bool aHasSelectionAttribute = false; +#ifdef DEBUG_OPERATION_PRS + qDebug("PartSet_OperationPrs::PartSet_OperationPrs"); +#endif + myShapeColor = Quantity_Color(1, 1, 1, Quantity_TOC_RGB); - std::list anAttributes = theFeature->data()->attributes(""); - std::list::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end(); - for (; anIt != aLast && !aHasSelectionAttribute; anIt++) - aHasSelectionAttribute = isSelectionAttribute(*anIt); + // first presentation for having correct Compute until presentation with shapes are set + gp_Pnt aPnt(0.0, 0.0, 0.0); + BRepBuilderAPI_MakeVertex aMaker(aPnt); + TopoDS_Vertex aVertex = aMaker.Vertex(); + myShapeToPrsMap.Bind(aVertex, NULL); - return aHasSelectionAttribute; + Handle(Prs3d_Drawer) aDrawer = Attributes(); + Handle(Prs3d_IsoAspect) aUIsoAspect = new Prs3d_IsoAspect(myShapeColor, Aspect_TOL_SOLID, 1, 0); + Handle(Prs3d_IsoAspect) aVIsoAspect = new Prs3d_IsoAspect(myShapeColor, Aspect_TOL_SOLID, 1, 0); + aDrawer->SetUIsoAspect(aUIsoAspect); + aDrawer->SetVIsoAspect(aVIsoAspect); + aDrawer->SetIsoOnPlane(false); + //aDrawer->SetTypeOfDeflection(Aspect_TOD_ABSOLUTE); } -void PartSet_OperationPrs::setFeature(const FeaturePtr& theFeature) +bool PartSet_OperationPrs::hasShapes() { - myFeature = theFeature; - updateShapes(); + return !myShapeToPrsMap.IsEmpty(); } -/*bool PartSet_OperationPrs::dependOn(const ObjectPtr& theResult) -{ - return myFeatureShapes.contains(theResult); -}*/ - -void PartSet_OperationPrs::updateShapes() +void PartSet_OperationPrs::setShapeColor(const Quantity_Color& theColor) { - myFeatureShapes.clear(); - getFeatureShapes(myFeatureShapes); - - myFeatureResults.clear(); - if (myFeature) - myFeatureResults = myFeature->results(); + myShapeColor = theColor; } -bool PartSet_OperationPrs::hasShapes() +void PartSet_OperationPrs::useAISWidth() { - return !myFeatureShapes.empty() || !myFeatureResults.empty(); + myUseAISWidth = true; } -void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, - const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer theMode) +void PartSet_OperationPrs::Compute( + const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, + const Handle(Prs3d_Presentation)& thePresentation, + const Standard_Integer theMode) { - if (!hasShapes()) - return; - // when the feature can not be visualized in the module, the operation preview should not - // be visualized also - if (!myWorkshop->module()->canDisplayObject(myFeature)) - return; - - Quantity_Color aColor(1., 1., 0., Quantity_TOC_RGB); // yellow - SetColor(aColor); +#ifdef DEBUG_OPERATION_PRS + qDebug("PartSet_OperationPrs::Compute -- begin"); +#endif + SetColor(myShapeColor); thePresentation->Clear(); - XGUI_Displayer* aDisplayer = workshop()->displayer(); + bool aReadyToDisplay = !myShapeToPrsMap.IsEmpty(); - // create presentations on the base of the shapes Handle(Prs3d_Drawer) aDrawer = Attributes(); - QMap >::const_iterator anIt = myFeatureShapes.begin(), - aLast = myFeatureShapes.end(); - for (; anIt != aLast; anIt++) { - ObjectPtr anObject = anIt.key(); - if (!isVisible(aDisplayer, anObject)) - continue; - QList aShapes = anIt.value(); - QList::const_iterator aShIt = aShapes.begin(), aShLast = aShapes.end(); - for (; aShIt != aShLast; aShIt++) { - GeomShapePtr aGeomShape = *aShIt; - if (!aGeomShape.get()) - continue; - TopoDS_Shape aShape = aGeomShape->impl(); - // change deviation coefficient to provide more precise circle - ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, aDrawer); - StdPrs_WFDeflectionShape::Add(thePresentation, aShape, aDrawer); - } - } - - aColor = Quantity_Color(0., 1., 0., Quantity_TOC_RGB); // green - SetColor(aColor); - - std::list::const_iterator aRIt = myFeatureResults.begin(), - aRLast = myFeatureResults.end(); - for (; aRIt != aRLast; aRIt++) { - ResultPtr aResult = *aRIt; - if (!isVisible(aDisplayer, aResult)) - continue; - GeomShapePtr aGeomShape = aResult->shape(); - if (!aGeomShape.get()) - continue; - TopoDS_Shape aShape = aGeomShape->impl(); + // create presentations on the base of the shapes + BRep_Builder aBuilder; + TopoDS_Compound aComp; + aBuilder.MakeCompound(aComp); + for(NCollection_DataMap::Iterator + anIter(myShapeToPrsMap); anIter.More(); anIter.Next()) { + const TopoDS_Shape& aShape = anIter.Key(); + aBuilder.Add(aComp, aShape); // change deviation coefficient to provide more precise circle + // as there is no result, the shape is processed to correct deviation. To be unified ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, aDrawer); - StdPrs_WFDeflectionShape::Add(thePresentation, aShape, aDrawer); + //This presentation is not used for selection, so it don't need highlighting + //ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, DynamicHilightAttributes()); + + if (myUseAISWidth) { + Handle(AIS_InteractiveObject) anIO = anIter.Value(); + if (!anIO.IsNull()) { + int aWidth = anIO->Width(); + /// workaround for zero width. Else, there will be a crash + if (aWidth == 0) { // width returns of TSolid shape is zero + aWidth = PartSet_Tools::getAISDefaultWidth();// default width value + } + setWidth(aDrawer, aWidth); + } + } + try { + StdPrs_WFShape::Add(thePresentation, aShape, aDrawer); + } + catch (...) { + return; + } + } + Set(aComp); + if (!aReadyToDisplay) { + Events_InfoMessage("PartSet_OperationPrs", + "An empty AIS presentation: PartSet_OperationPrs").send(); + std::shared_ptr aMsg = std::shared_ptr( + new Events_Message(Events_Loop::eventByName(EVENT_EMPTY_OPERATION_PRESENTATION))); + Events_Loop::loop()->send(aMsg); } +#ifdef DEBUG_OPERATION_PRS + qDebug("PartSet_OperationPrs::Compute -- end"); +#endif } void PartSet_OperationPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, @@ -142,24 +175,9 @@ void PartSet_OperationPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a // the presentation is not used in the selection } -bool PartSet_OperationPrs::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& theObject) +NCollection_DataMap& PartSet_OperationPrs::shapesMap() { - bool aVisible = false; - GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - if (aPrs.get() || aResult.get()) - aVisible = theDisplayer->isVisible(theObject); - else { - // check if all results of the feature are visible - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - std::list aResults = aFeature->results(); - std::list::const_iterator aIt; - aVisible = !aResults.empty(); - for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - aVisible = aVisible && theDisplayer->isVisible(*aIt); - } - } - return aVisible; + return myShapeToPrsMap; } bool isSubObject(const ObjectPtr& theObject, const FeaturePtr& theFeature) @@ -172,114 +190,253 @@ bool isSubObject(const ObjectPtr& theObject, const FeaturePtr& theFeature) return isSub; } -void addValue(const ObjectPtr& theObject, const GeomShapePtr& theShape, - const FeaturePtr& theFeature, - QMap >& theObjectShapes) +void PartSet_OperationPrs::addValue(const ObjectPtr& theObject, const GeomShapePtr& theShape, + const FeaturePtr& theFeature, ModuleBase_IWorkshop* theWorkshop, + QMap >& theObjectShapes) { if (theObject.get()) { ResultPtr aResult = std::dynamic_pointer_cast(theObject); if (aResult.get()) { - ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast(theObject); - if (aCompsolidResult.get()) { - for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) { - ResultPtr aSubResult = aCompsolidResult->subResult(i); - if (aSubResult.get()) { - GeomShapePtr aShape; - addValue(aSubResult, aShape, theFeature, theObjectShapes); + ResultBodyPtr aBodyResult = + std::dynamic_pointer_cast(theObject); + if (aBodyResult.get()) { + if (aBodyResult->numberOfSubs() > 0) { + for(int i = 0; i < aBodyResult->numberOfSubs(); i++) { + ResultPtr aSubResult = aBodyResult->subResult(i); + if (aSubResult.get()) { + GeomShapePtr aShape; + addValue(aSubResult, aShape, theFeature, theWorkshop, theObjectShapes); + } + } + return; + } + } +#ifdef DEBUG_HIDE_COPY_ATTRIBUTE + else { + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + if (aFeature.get()) { + AttributeBooleanPtr aCopyAttr = + aFeature->data()->boolean(SketchPlugin_SketchEntity::COPY_ID()); + if (aCopyAttr.get()) { + bool isCopy = aCopyAttr->value(); + if (isCopy) + return; } } - return; } +#endif } - GeomShapePtr aShape = theShape; if (!aShape.get()) { - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - if (aResult.get()) - aShape = aResult->shape(); + ResultPtr aRes = std::dynamic_pointer_cast(theObject); + if (aRes.get()) + aShape = aRes->shape(); } - if (!isSubObject(theObject, theFeature)) { - if (theObjectShapes.contains(theObject)) - theObjectShapes[theObject].append(aShape); - else { - QList aShapes; - aShapes.append(aShape); - theObjectShapes[theObject] = aShapes; - } + if (!isSubObject(theObject, theFeature)) + appendShapeIfVisible(theWorkshop, theObject, aShape, theObjectShapes); + } +} + +void PartSet_OperationPrs::appendShapeIfVisible(ModuleBase_IWorkshop* theWorkshop, + const ObjectPtr& theObject, + GeomShapePtr theGeomShape, + QMap >& theObjectShapes) +{ + if (theGeomShape.get()) { + if (theObjectShapes.contains(theObject)) + theObjectShapes[theObject].append(theGeomShape); + else { + QList aShapes; + aShapes.append(theGeomShape); + theObjectShapes[theObject] = aShapes; } + } else { +#ifdef DEBUG_EMPTY_SHAPE + qDebug(QString("Empty shape in result, result: %1") + .arg(ModuleBase_Tools::objectInfo(theObject)).toStdString().c_str()); +#endif } } -void PartSet_OperationPrs::getFeatureShapes(QMap >& theObjectShapes) +void PartSet_OperationPrs::getFeatureShapes(const FeaturePtr& theFeature, + ModuleBase_IWorkshop* theWorkshop, + QMap >& theObjectShapes) { - if (!myFeature.get()) + theObjectShapes.clear(); + if (!theFeature.get()) return; ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators(); QList aShapes; - std::list anAttributes = myFeature->data()->attributes(""); + std::list anAttributes = theFeature->data()->attributes(""); std::list::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end(); for (; anIt != aLast; anIt++) { AttributePtr anAttribute = *anIt; if (!isSelectionAttribute(anAttribute)) continue; - if (!aValidators->isCase(myFeature, anAttribute->id())) + if (!aValidators->isCase(theFeature, anAttribute->id())) continue; // this attribute is not participated in the current case std::string anAttrType = anAttribute->attributeType(); if (anAttrType == ModelAPI_AttributeSelectionList::typeId()) { - std::shared_ptr aCurSelList = + std::shared_ptr aCurSelList = std::dynamic_pointer_cast(anAttribute); for(int i = 0; i < aCurSelList->size(); i++) { std::shared_ptr aSelAttribute = aCurSelList->value(i); ResultPtr aResult = aSelAttribute->context(); GeomShapePtr aShape = aSelAttribute->value(); - addValue(aResult, aShape, myFeature, theObjectShapes); + addValue(aResult, aShape, theFeature, theWorkshop, theObjectShapes); } } if (anAttrType == ModelAPI_AttributeRefList::typeId()) { std::shared_ptr aCurSelList = std::dynamic_pointer_cast(anAttribute); for (int i = 0; i < aCurSelList->size(); i++) { - GeomShapePtr aShape; - addValue(aCurSelList->object(i), aShape, myFeature, theObjectShapes); + ObjectPtr anObject = aCurSelList->object(i); + FeaturePtr aFeature = std::dynamic_pointer_cast(anObject); + // if a feature is stored in the attribute, we should obtain the feature results + // e.g. feature rectangle uses parameters feature lines in the attribute + if (aFeature.get()) { + getResultShapes(aFeature, theWorkshop, theObjectShapes, false); + } + else { + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get()) { + GeomShapePtr aShape = aResult->shape(); + if (aShape.get()) + addValue(aResult, aShape, theFeature, theWorkshop, theObjectShapes); + } + } } } else { ObjectPtr anObject; GeomShapePtr aShape; if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) { - AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast(anAttribute); - if (anAttr->isObject()) { - anObject = anAttr->object(); + AttributeRefAttrPtr aRefAttr = + std::dynamic_pointer_cast(anAttribute); + if (aRefAttr->isObject()) { + anObject = aRefAttr->object(); } else { - aShape = PartSet_Tools::findShapeBy2DPoint(anAttr, myWorkshop); + AttributePtr anAttr = aRefAttr->attr(); + aShape = PartSet_Tools::findShapeBy2DPoint(anAttr, theWorkshop); // the distance point is not found if the point is selected in the 2nd time // TODO: after debug, this check can be removed if (!aShape.get()) continue; - anObject = anAttr->attr()->owner(); + anObject = anAttr->owner(); } } if (anAttrType == ModelAPI_AttributeSelection::typeId()) { - AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(anAttribute); + AttributeSelectionPtr anAttr = + std::dynamic_pointer_cast(anAttribute); anObject = anAttr->context(); aShape = anAttr->value(); } if (anAttrType == ModelAPI_AttributeReference::typeId()) { - AttributeReferencePtr anAttr = std::dynamic_pointer_cast(anAttribute); + AttributeReferencePtr anAttr = + std::dynamic_pointer_cast(anAttribute); anObject = anAttr->value(); } - addValue(anObject, aShape, myFeature, theObjectShapes); + addValue(anObject, aShape, theFeature, theWorkshop, theObjectShapes); + } + } +} + +void PartSet_OperationPrs::getResultShapes(const FeaturePtr& theFeature, + ModuleBase_IWorkshop* theWorkshop, + QMap >& theObjectShapes, + const bool theListShouldBeCleared) +{ + if (theListShouldBeCleared) + theObjectShapes.clear(); + + if (!theFeature.get()) + return; + + std::list aResults; + ModelAPI_Tools::allResults(theFeature, aResults); + std::list::const_iterator aRIt = aResults.begin(), + aRLast = aResults.end(); + for (; aRIt != aRLast; aRIt++) { + ResultPtr aResult = *aRIt; + if (!aResult->isDisabled()) { + GeomShapePtr aGeomShape = aResult->shape(); + appendShapeIfVisible(theWorkshop, aResult, aGeomShape, theObjectShapes); } } } +void PartSet_OperationPrs::getPresentationShapes(const FeaturePtr& theFeature, + ModuleBase_IWorkshop* theWorkshop, + QMap >& theObjectShapes, + const bool theListShouldBeCleared) +{ + if (theListShouldBeCleared) + theObjectShapes.clear(); + + if (!theFeature.get() || !theFeature->data()->isValid()) // if feature is already removed + return; + + XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer(); + + GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theFeature); + if (!aPrs.get()) + return; + + AISObjectPtr anAIS = aPrs->getAISObject(aDisplayer->getAISObject(theFeature)); + if (!anAIS.get()) + return; + + Handle(AIS_InteractiveObject) anAISPrs = anAIS->impl(); + if (!anAISPrs.IsNull()) { + Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(anAISPrs); + if (!aShapePrs.IsNull()) { + TopoDS_Shape aShape = aShapePrs->Shape(); + if (!aShape.IsNull()) { + std::shared_ptr aGeomShape(new GeomAPI_Shape()); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + appendShapeIfVisible(theWorkshop, theFeature, aGeomShape, theObjectShapes); + } + } + } +} + +void PartSet_OperationPrs::getHighlightedShapes(ModuleBase_IWorkshop* theWorkshop, + QMap >& theObjectShapes) +{ + theObjectShapes.clear(); + + QList aValues; + ModuleBase_ModelWidget* anActiveWidget = theWorkshop->module()->activeWidget(); + if (anActiveWidget) + anActiveWidget->getHighlighted(aValues); + + QList aShapes; + QList::const_iterator anIIt = aValues.begin(), + aILast = aValues.end(); + for (; anIIt != aILast; anIIt++) { + ModuleBase_ViewerPrsPtr aPrs = *anIIt; + ObjectPtr anObject = aPrs->object(); + + GeomShapePtr aGeomShape = aPrs->shape(); + if (!aGeomShape.get() || aGeomShape->isNull()) { + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get()) { + aGeomShape = aResult->shape(); + } + } + appendShapeIfVisible(theWorkshop, anObject, aGeomShape, theObjectShapes); + } +} + + bool PartSet_OperationPrs::isSelectionAttribute(const AttributePtr& theAttribute) { std::string anAttrType = theAttribute->attributeType(); @@ -291,8 +448,39 @@ bool PartSet_OperationPrs::isSelectionAttribute(const AttributePtr& theAttribute anAttrType == ModelAPI_AttributeReference::typeId(); } -XGUI_Workshop* PartSet_OperationPrs::workshop() const +void PartSet_OperationPrs::fillShapeList( + const QMap >& theFeatureShapes, + ModuleBase_IWorkshop* theWorkshop, + NCollection_DataMap& theShapeToPrsMap) { - XGUI_ModuleConnector* aConnector = dynamic_cast(myWorkshop); - return aConnector->workshop(); + theShapeToPrsMap.Clear(); + + XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer(); + + // create presentations on the base of the shapes + QMap >::const_iterator anIt = theFeatureShapes.begin(), + aLast = theFeatureShapes.end(); + for (; anIt != aLast; anIt++) { + ObjectPtr anObject = anIt.key(); + QList aShapes = anIt.value(); + QList::const_iterator aShIt = aShapes.begin(), aShLast = aShapes.end(); + for (; aShIt != aShLast; aShIt++) { + GeomShapePtr aGeomShape = *aShIt; + // the shape should not be checked here on empty value because it should be checked in + // appendShapeIfVisible() on the step of filling theFeatureShapes list + // the reason is to avoid empty AIS object visualized in the viewer + //if (!aGeomShape.get()) continue; + TopoDS_Shape aShape = aGeomShape.get() ? aGeomShape->impl() : TopoDS_Shape(); + if (aShape.IsNull()) + continue; + + // change deviation coefficient to provide more precise circle + Handle(AIS_InteractiveObject) anIO; + AISObjectPtr anAISPtr = aDisplayer->getAISObject(anObject); + if (anAISPtr.get()) + anIO = anAISPtr->impl(); + theShapeToPrsMap.Bind(aShape, anIO); + } + } }