From: szy Date: Mon, 27 Oct 2014 15:48:46 +0000 (+0300) Subject: Merge branch 'master' of newgeom:newgeom X-Git-Tag: V_0.5~69^2^2~3 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d9db5498b576854aae37ddf8c0bb6fceb264712e;hp=5f2ce61eb2866c9b2d119f0ad4c8301f765304ee;p=modules%2Fshaper.git Merge branch 'master' of newgeom:newgeom Conflicts: src/GeomAPI/GeomAPI_Shape.h --- diff --git a/build_Salome740_deb.bat b/build_Salome740_deb.bat index 130599b4f..77a58f1ed 100644 --- a/build_Salome740_deb.bat +++ b/build_Salome740_deb.bat @@ -14,6 +14,6 @@ call %SRC_DIR%\env_Salome.bat d mkdir %ROOT_DIR%\build cd %ROOT_DIR%\build -cmake %SRC_DIR% -G "Visual Studio 10" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\install +cmake %SRC_DIR% -G "Visual Studio 10" -DPYTHON_EXECUTABLE=%PYTHONHOME%\python_d.exe -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\install start "" %MSVC_EXE% NewGEOM.sln diff --git a/env_Salome.bat b/env_Salome.bat index 9c4291781..98d24b244 100644 --- a/env_Salome.bat +++ b/env_Salome.bat @@ -20,8 +20,8 @@ if "%SALOME_ROOT_DIR%" == "" ( if "%SOLVESPACE_ROOT_DIR%" == "" ( SET SOLVESPACE_ROOT_DIR=%ROOT_DIR%\products\solvespace-2.0 - SET PATH=%SOLVESPACE_ROOT_DIR%\lib;"%PATH%" ) +SET PATH=%SOLVESPACE_ROOT_DIR%\lib;%PATH% cd %SALOME_ROOT_DIR%\WORK call set_env.bat %1 diff --git a/salomeRun.bat b/salomeRun.bat index a2fa7d3dd..e7d3de66c 100644 --- a/salomeRun.bat +++ b/salomeRun.bat @@ -2,4 +2,7 @@ call env_Salome.bat -SuitApp.exe LightApp --modules=NewGeom +@SET NewGEOM_ROOT_DIR=%ROOT_DIR%\install +@SET SalomeAppConfig=%ROOT_DIR%\install\share\salome\resources\newgeom;%GUI_ROOT_DIR%\share\salome\resources\gui + +start %PYTHONBIN% "%KERNEL_ROOT_DIR%\bin\salome\envSalome.py" "%PYTHONBIN%" "%KERNEL_ROOT_DIR%\bin\salome\runSalome.py" %* diff --git a/src/Config/Config_FeatureReader.cpp b/src/Config/Config_FeatureReader.cpp index 1f7a65b2d..5c4ffba8e 100644 --- a/src/Config/Config_FeatureReader.cpp +++ b/src/Config/Config_FeatureReader.cpp @@ -92,7 +92,7 @@ void Config_FeatureReader::fillFeature(xmlNodePtr theNode, bool Config_FeatureReader::isInternalFeature(xmlNodePtr theNode) { - std::string prop = getProperty(theNode, FEATURE_INTERNAL); + std::string prop = getProperty(theNode, ATTRIBUTE_INTERNAL); std::transform(prop.begin(), prop.end(), prop.begin(), ::tolower); if (prop.empty() || prop == "false" || prop == "0") { return false; diff --git a/src/Config/Config_Keywords.h b/src/Config/Config_Keywords.h index 5a4eb4683..46338306b 100644 --- a/src/Config/Config_Keywords.h +++ b/src/Config/Config_Keywords.h @@ -50,8 +50,10 @@ const static char* FEATURE_ICON = "icon"; const static char* FEATURE_TEXT = "title"; const static char* FEATURE_KEYSEQUENCE = "keysequence"; const static char* FEATURE_NESTED = "nested"; -const static char* FEATURE_INTERNAL = "internal"; -const static char* FEATURE_OBLIGATORY = "obligatory"; + +const static char* ATTRIBUTE_INTERNAL = "internal"; +const static char* ATTRIBUTE_OBLIGATORY = "obligatory"; +const static char* ATTRIBUTE_CONCEALMENT = "concealment"; // TODO: Rename const static char* PREVIOUS_FEATURE_PARAM = "previous_feature_param"; const static char* ANY_WDG_TOOLTIP = FEATURE_TOOLTIP; diff --git a/src/Config/Config_Prop.cpp b/src/Config/Config_Prop.cpp index 7904021b6..6de7627b0 100644 --- a/src/Config/Config_Prop.cpp +++ b/src/Config/Config_Prop.cpp @@ -16,3 +16,10 @@ void Config_Prop::setValue(const std::string& theValue) new Events_Message(aChangedEvent, this))); } } + +void Config_Prop::setDefaultValue(const std::string& theValue) +{ + if (theValue != myDefaultValue) { + myDefaultValue = theValue; + } +} diff --git a/src/Config/Config_Prop.h b/src/Config/Config_Prop.h index f4ea0138b..4430bade8 100644 --- a/src/Config/Config_Prop.h +++ b/src/Config/Config_Prop.h @@ -45,16 +45,17 @@ class Config_Prop * \param theSection - name of section (domain of using) of the property. * \param theName - name (title) of the value. * \param theType - type of the value. - * \param theValue - initial value of the property. + * \param theDefaultValue - default value of the property. This is an initial property value */ Config_Prop(const std::string& theSection, const std::string& theName, - const std::string& theTitle, PropType theType, const std::string& theValue) + const std::string& theTitle, PropType theType, const std::string& theDefaultValue) { mySection = theSection; myName = theName; myTitle = theTitle; myType = theType; - myValue = theValue; + myValue = theDefaultValue; + myDefaultValue = theDefaultValue; } std::string section() const @@ -90,6 +91,13 @@ class Config_Prop } CONFIG_EXPORT void setValue(const std::string& theValue); + + std::string defaultValue() const + { + return myDefaultValue; + } + + CONFIG_EXPORT void setDefaultValue(const std::string& theValue); bool operator==(const Config_Prop* theProp) const { @@ -102,6 +110,7 @@ class Config_Prop std::string myTitle; PropType myType; std::string myValue; + std::string myDefaultValue; }; typedef std::list Config_Properties; diff --git a/src/Config/Config_PropManager.cpp b/src/Config/Config_PropManager.cpp index c296cc864..e6f800c27 100644 --- a/src/Config/Config_PropManager.cpp +++ b/src/Config/Config_PropManager.cpp @@ -10,22 +10,29 @@ double stringToDouble(const std::string& theDouble); Config_Properties Config_PropManager::myProps; -bool Config_PropManager::registerProp(const std::string& theSection, const std::string& theName, - const std::string& theTitle, Config_Prop::PropType theType, - const std::string& theValue) +Config_Prop* Config_PropManager::registerProp(const std::string& theSection, const std::string& theName, + const std::string& theTitle, Config_Prop::PropType theType, + const std::string& theDefaultValue) { Config_Prop* aProp = findProp(theSection, theName); + if (aProp) { + if (aProp->value() == "") { + aProp->setValue(theDefaultValue); + } + if (aProp->defaultValue() == "") { + aProp->setDefaultValue(theDefaultValue); + } if (aProp->type() == Config_Prop::Disabled) { aProp->setType(theType); aProp->setTitle(theTitle); - return true; } - return false; } - aProp = new Config_Prop(theSection, theName, theTitle, theType, theValue); - myProps.push_back(aProp); - return true; + else { + aProp = new Config_Prop(theSection, theName, theTitle, theType, theDefaultValue); + myProps.push_back(aProp); + } + return aProp; } Config_Prop* Config_PropManager::findProp(const std::string& theSection, const std::string& theName) diff --git a/src/Config/Config_PropManager.h b/src/Config/Config_PropManager.h index 496cddd6d..444312ebd 100644 --- a/src/Config/Config_PropManager.h +++ b/src/Config/Config_PropManager.h @@ -23,11 +23,11 @@ class Config_PropManager * \param theSection - name of section (domain of using) of the property. * \param theName - name (title) of the value. * \param theType - type of the value. - * \param theValue - initial value of the property + * \param theDefValue - default and initial value of the property * Returns True if the property succesfully registered */ - CONFIG_EXPORT static bool registerProp(const std::string& theSection, const std::string& theName, - const std::string& theTitle, Config_Prop::PropType theType, const std::string& theValue); + CONFIG_EXPORT static Config_Prop* registerProp(const std::string& theSection, const std::string& theName, + const std::string& theTitle, Config_Prop::PropType theType, const std::string& theDefValue = ""); CONFIG_EXPORT static Config_Prop* findProp( const std::string& theSection, const std::string& theName); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index 737a563b3..b49f58854 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -45,6 +45,8 @@ void FeaturesPlugin_Extrusion::execute() boost::shared_ptr aFace = boost::dynamic_pointer_cast(aFaceRef->value()); + if (!aFace) + return; boost::shared_ptr aContext = boost::dynamic_pointer_cast(aFaceRef->context()); @@ -148,4 +150,4 @@ void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Extrusion& theFeature, theResultBody->generated(aTopFace, _FIRST_TAG); } -} \ No newline at end of file +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Group.cpp b/src/FeaturesPlugin/FeaturesPlugin_Group.cpp index 4a5a34bc2..dad22dbf6 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Group.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Group.cpp @@ -8,6 +8,8 @@ #include #include #include +#include + using namespace std; @@ -17,16 +19,16 @@ FeaturesPlugin_Group::FeaturesPlugin_Group() void FeaturesPlugin_Group::initAttributes() { - data()->addAttribute(FeaturesPlugin_Group::NAME_ID(), ModelAPI_AttributeString::type()); - data()->addAttribute(FeaturesPlugin_Group::LIST_ID(), ModelAPI_AttributeString::type()); + //data()->addAttribute(FeaturesPlugin_Group::NAME_ID(), ModelAPI_AttributeString::type()); + data()->addAttribute(FeaturesPlugin_Group::LIST_ID(), ModelAPI_AttributeSelectionList::type()); } void FeaturesPlugin_Group::execute() { - AttributeStringPtr aNameAttr = boost::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Group::NAME_ID())); - if (!aNameAttr) - return; - std::string aName = aNameAttr->value(); - data()->setName(aName); + //AttributeStringPtr aNameAttr = boost::dynamic_pointer_cast( + // data()->attribute(FeaturesPlugin_Group::NAME_ID())); + //if (!aNameAttr) + // return; + //std::string aName = aNameAttr->value(); + //data()->setName(aName); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Group.h b/src/FeaturesPlugin/FeaturesPlugin_Group.h index 34385caab..23078ae67 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Group.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Group.h @@ -19,11 +19,11 @@ class FeaturesPlugin_Group : public ModelAPI_Feature return MY_GROUP_ID; } /// attribute name of group name - inline static const std::string& NAME_ID() - { - static const std::string MY_GROUP_NAME_ID("group_name"); - return MY_GROUP_NAME_ID; - } + //inline static const std::string& NAME_ID() + //{ + // static const std::string MY_GROUP_NAME_ID("group_name"); + // return MY_GROUP_NAME_ID; + //} /// attribute name of selected entities list inline static const std::string& LIST_ID() { diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index fee9e00df..4158caaa9 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -4,10 +4,11 @@ icon=":icons/sketch.png" tooltip="Select a face for extrusion" activate="true" - shape_types="face wire edge" + shape_types="face" use_subshapes="true" + concealment="true" /> - + diff --git a/src/FeaturesPlugin/group_widget.xml b/src/FeaturesPlugin/group_widget.xml index 5d8ad7565..d4288b638 100644 --- a/src/FeaturesPlugin/group_widget.xml +++ b/src/FeaturesPlugin/group_widget.xml @@ -1,8 +1,4 @@ - diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index f2e238051..8700473ee 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -19,7 +19,7 @@ SET(PROJECT_HEADERS GeomAPI_Pln.h GeomAPI_Shape.h GeomAPI_Edge.h - GeomAPI_Wire.h + GeomAPI_PlanarEdges.h GeomAPI_AISObject.h GeomAPI_IPresentable.h GeomAPI_Curve.h @@ -40,7 +40,7 @@ SET(PROJECT_SOURCES GeomAPI_Pln.cpp GeomAPI_Shape.cpp GeomAPI_Edge.cpp - GeomAPI_Wire.cpp + GeomAPI_PlanarEdges.cpp GeomAPI_AISObject.cpp GeomAPI_Curve.cpp ) diff --git a/src/GeomAPI/GeomAPI_AISObject.cpp b/src/GeomAPI/GeomAPI_AISObject.cpp index 22863757e..de00d5a43 100644 --- a/src/GeomAPI/GeomAPI_AISObject.cpp +++ b/src/GeomAPI/GeomAPI_AISObject.cpp @@ -22,6 +22,7 @@ #include #include #include +#include const double tolerance = 1e-7; @@ -219,6 +220,30 @@ void GeomAPI_AISObject::createPerpendicular(boost::shared_ptr the } } + +void GeomAPI_AISObject::createFixed(boost::shared_ptr theShape, + boost::shared_ptr thePlane) +{ + Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl()); + Handle(AIS_InteractiveObject) anAIS = impl(); + if (anAIS.IsNull()) { + Handle(AIS_FixRelation) aFixPrs = + new AIS_FixRelation(theShape->impl(), aPlane); + + setImpl(new Handle(AIS_InteractiveObject)(aFixPrs)); + } else { + Handle(AIS_PerpendicularRelation) aFixPrs = + Handle(AIS_PerpendicularRelation)::DownCast(anAIS); + if (!aFixPrs.IsNull()) { + aFixPrs->SetFirstShape(theShape->impl()); + aFixPrs->SetPlane(aPlane); + aFixPrs->Redisplay(Standard_True); + } + } +} + + + void GeomAPI_AISObject::setColor(const int& theColor) { Handle(AIS_InteractiveObject) anAIS = impl(); diff --git a/src/GeomAPI/GeomAPI_AISObject.h b/src/GeomAPI/GeomAPI_AISObject.h index 574d39f13..0c8034d0d 100644 --- a/src/GeomAPI/GeomAPI_AISObject.h +++ b/src/GeomAPI/GeomAPI_AISObject.h @@ -77,6 +77,13 @@ class GEOMAPI_EXPORT GeomAPI_AISObject : public GeomAPI_Interface boost::shared_ptr theLine2, boost::shared_ptr thePlane); + /** \brief Creates AIS_FixedRelation object for an object + * \param[in] theShape the object + * \param[in] thePlane the plane which contains the lines + */ + void createFixed(boost::shared_ptr theShape, + boost::shared_ptr thePlane); + /** \brief Assigns the color for the shape * \param[in] theColor index of the color */ diff --git a/src/GeomAPI/GeomAPI_PlanarEdges.cpp b/src/GeomAPI/GeomAPI_PlanarEdges.cpp new file mode 100644 index 000000000..f12d62204 --- /dev/null +++ b/src/GeomAPI/GeomAPI_PlanarEdges.cpp @@ -0,0 +1,50 @@ +// File: GeomAPI_PlanarEdges.cpp +// Created: 06 Oct 2014 +// Author: Sergey BELASH + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +GeomAPI_PlanarEdges::GeomAPI_PlanarEdges() : GeomAPI_Shape() +{ + TopoDS_Compound aBigWireImpl; + BRep_Builder aBuilder; + aBuilder.MakeCompound(aBigWireImpl); + this->setImpl(new TopoDS_Shape(aBigWireImpl)); +} + +void GeomAPI_PlanarEdges::addEdge(boost::shared_ptr theEdge) +{ + const TopoDS_Edge& anEdge = theEdge->impl(); + if (anEdge.ShapeType() != TopAbs_EDGE) + return; + TopoDS_Shape& aWire = const_cast(impl()); + BRep_Builder aBuilder; + aBuilder.Add(aWire, anEdge); +} + +std::list > GeomAPI_PlanarEdges::getEdges() +{ + TopoDS_Shape& aShape = const_cast(impl()); + //BRepTools_WireExplorer aWireExp(TopoDS::Wire(aShape)); + TopExp_Explorer aWireExp(aShape, TopAbs_EDGE); + std::list > aResult; + for (; aWireExp.More(); aWireExp.Next()) { + boost::shared_ptr anEdge(new GeomAPI_Shape); + anEdge->setImpl(new TopoDS_Shape(aWireExp.Current())); + aResult.push_back(anEdge); + } + return aResult; +} diff --git a/src/GeomAPI/GeomAPI_PlanarEdges.h b/src/GeomAPI/GeomAPI_PlanarEdges.h new file mode 100644 index 000000000..af8422619 --- /dev/null +++ b/src/GeomAPI/GeomAPI_PlanarEdges.h @@ -0,0 +1,70 @@ +// File: GeomAPI_PlanarEdges.hxx +// Created: 24 Jul 2014 +// Author: Artem ZHIDKOV + +#ifndef GEOMAPI_WIRE_H_ +#define GEOMAPI_WIRE_H_ + +#include "GeomAPI.h" +#include "GeomAPI_Edge.h" +#include "GeomAPI_Pnt.h" +#include "GeomAPI_Dir.h" + +#include + +#include + +/**\class GeomAPI_PlanarEdges + * \ingroup DataModel + * \brief Interface to the edge object + */ + +class GeomAPI_PlanarEdges : public GeomAPI_Shape +{ + public: + /// Creation of empty (null) shape + GEOMAPI_EXPORT GeomAPI_PlanarEdges(); + + GEOMAPI_EXPORT virtual bool isVertex() const + { + return false; + } + + /// Returns whether the shape is an edge + GEOMAPI_EXPORT virtual bool isEdge() const + { + return false; + } + + GEOMAPI_EXPORT void addEdge(boost::shared_ptr theEdge); + GEOMAPI_EXPORT std::list > getEdges(); + + /// Returns True if the wire is defined in a plane + GEOMAPI_EXPORT bool hasPlane() const { return myOrigin && myNorm && myDirX && myDirY; } + + /// Set/Get origin point + GEOMAPI_EXPORT void setOrigin(const boost::shared_ptr& theOrigin) + { myOrigin = theOrigin; } + GEOMAPI_EXPORT boost::shared_ptr origin() const { return myOrigin; } + + /// Set/Get X direction vector + GEOMAPI_EXPORT void setDirX(const boost::shared_ptr& theDirX) { myDirX = theDirX; } + GEOMAPI_EXPORT boost::shared_ptr dirX() const { return myDirX; } + + /// Set/Get Y direction vector + GEOMAPI_EXPORT void setDirY(const boost::shared_ptr& theDirY) { myDirY = theDirY; } + GEOMAPI_EXPORT boost::shared_ptr dirY() const { return myDirY; } + + /// Set/Get Normal direction vector + GEOMAPI_EXPORT void setNorm(const boost::shared_ptr& theNorm) { myNorm = theNorm; } + GEOMAPI_EXPORT boost::shared_ptr norm() const { return myNorm; } + +private: + boost::shared_ptr myOrigin; + boost::shared_ptr myDirX; + boost::shared_ptr myDirY; + boost::shared_ptr myNorm; +}; + +#endif + diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index acd39c6ec..55db3759a 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -32,5 +32,11 @@ class GEOMAPI_EXPORT GeomAPI_Shape : public GeomAPI_Interface }; +<<<<<<< HEAD typedef std::list> ListOfShape; +======= +//! Pointer on attribute object +typedef boost::shared_ptr GeomShapePtr; + +>>>>>>> 01cda8378dd1cff425f88438e8c0085122ed7495 #endif diff --git a/src/GeomAPI/GeomAPI_Wire.cpp b/src/GeomAPI/GeomAPI_Wire.cpp deleted file mode 100644 index 6932444bf..000000000 --- a/src/GeomAPI/GeomAPI_Wire.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// File: GeomAPI_Wire.cpp -// Created: 06 Oct 2014 -// Author: Sergey BELASH - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include - -GeomAPI_Wire::GeomAPI_Wire() : GeomAPI_Shape() -{ - TopoDS_Compound aBigWireImpl; - BRep_Builder aBuilder; - aBuilder.MakeCompound(aBigWireImpl); - this->setImpl(new TopoDS_Shape(aBigWireImpl)); -} - -void GeomAPI_Wire::addEdge(boost::shared_ptr theEdge) -{ - const TopoDS_Edge& anEdge = theEdge->impl(); - if (anEdge.ShapeType() != TopAbs_EDGE) - return; - TopoDS_Shape& aWire = const_cast(impl()); - BRep_Builder aBuilder; - aBuilder.Add(aWire, anEdge); -} - -std::list > GeomAPI_Wire::getEdges() -{ - TopoDS_Shape& aShape = const_cast(impl()); - BRepTools_WireExplorer aWireExp(TopoDS::Wire(aShape)); - std::list > aResult; - for (; aWireExp.More(); aWireExp.Next()) { - boost::shared_ptr anEdge(new GeomAPI_Shape); - anEdge->setImpl(new TopoDS_Shape(aWireExp.Current())); - aResult.push_back(anEdge); - } - return aResult; -} diff --git a/src/GeomAPI/GeomAPI_Wire.h b/src/GeomAPI/GeomAPI_Wire.h deleted file mode 100644 index de849ef93..000000000 --- a/src/GeomAPI/GeomAPI_Wire.h +++ /dev/null @@ -1,43 +0,0 @@ -// File: GeomAPI_Wire.hxx -// Created: 24 Jul 2014 -// Author: Artem ZHIDKOV - -#ifndef GEOMAPI_WIRE_H_ -#define GEOMAPI_WIRE_H_ - -#include -#include - -#include - -#include - -/**\class GeomAPI_Wire - * \ingroup DataModel - * \brief Interface to the edge object - */ - -class GEOMAPI_EXPORT GeomAPI_Wire : public GeomAPI_Shape -{ - public: - /// Creation of empty (null) shape - GeomAPI_Wire(); - - virtual bool isVertex() const - { - return false; - } - - /// Returns whether the shape is an edge - virtual bool isEdge() const - { - return false; - } - - void addEdge(boost::shared_ptr theEdge); - std::list > getEdges(); - -}; - -#endif - diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp index 0d0fc3418..ddd6d3977 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp @@ -3,7 +3,7 @@ // Author: Artem ZHIDKOV #include -#include +#include #include @@ -378,7 +378,7 @@ void GeomAlgoAPI_SketchBuilder::createFaces(const boost::shared_ptr const boost::shared_ptr& theWire, std::list >& theResultFaces) { - boost::shared_ptr aWire = boost::dynamic_pointer_cast(theWire); + boost::shared_ptr aWire = boost::dynamic_pointer_cast(theWire); if(!aWire) return; // Filter wires, return only faces. diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index c9715ebc2..1656a618f 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -15,6 +15,7 @@ SET(PROJECT_HEADERS Model_AttributeString.h Model_AttributeInteger.h Model_AttributeSelection.h + Model_AttributeSelectionList.h Model_Events.h Model_Update.h Model_Validator.h @@ -38,6 +39,7 @@ SET(PROJECT_SOURCES Model_AttributeString.cpp Model_AttributeInteger.cpp Model_AttributeSelection.cpp + Model_AttributeSelectionList.cpp Model_Events.cpp Model_Update.cpp Model_Validator.cpp @@ -53,6 +55,7 @@ SET(PROJECT_LIBRARIES Config GeomData GeomAPI + GeomAlgoAPI ${CAS_OCAF} ${CAS_TKCAF} ${CAS_SHAPE} @@ -71,6 +74,7 @@ INCLUDE_DIRECTORIES( ../Config ../GeomData ../GeomDataAPI + ../GeomAlgoAPI ../GeomAPI ${CAS_INCLUDE_DIRS} ) diff --git a/src/Model/Model_AttributeRefList.cpp b/src/Model/Model_AttributeRefList.cpp index 3d3af3467..014592f0d 100644 --- a/src/Model/Model_AttributeRefList.cpp +++ b/src/Model/Model_AttributeRefList.cpp @@ -26,7 +26,7 @@ void Model_AttributeRefList::remove(ObjectPtr theObject) owner()->data()->sendAttributeUpdated(this); } -int Model_AttributeRefList::size() +int Model_AttributeRefList::size() const { return myRef->Extent(); } @@ -46,6 +46,21 @@ list Model_AttributeRefList::list() return aResult; } +ObjectPtr Model_AttributeRefList::object(const int theIndex) const +{ + boost::shared_ptr aDoc = boost::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + const TDF_LabelList& aList = myRef->List(); + int anIndex = 0; + for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next(), anIndex++) { + if (anIndex == theIndex) + return aDoc->object(aLIter.Value()); + } + } + return ObjectPtr(); +} + Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel) { myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True; diff --git a/src/Model/Model_AttributeRefList.h b/src/Model/Model_AttributeRefList.h index d784769e6..2b0edac1f 100644 --- a/src/Model/Model_AttributeRefList.h +++ b/src/Model/Model_AttributeRefList.h @@ -27,11 +27,14 @@ class Model_AttributeRefList : public ModelAPI_AttributeRefList MODEL_EXPORT virtual void remove(ObjectPtr theObject); /// Returns number of features in the list - MODEL_EXPORT virtual int size(); + MODEL_EXPORT virtual int size() const; /// Returns the list of features MODEL_EXPORT virtual std::list list(); + /// Returns the list of features + MODEL_EXPORT virtual ObjectPtr object(const int theIndex) const; + protected: /// Objects are created for features automatically MODEL_EXPORT Model_AttributeRefList(TDF_Label& theLabel); diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp index 134516972..3781fb2a2 100644 --- a/src/Model/Model_AttributeReference.cpp +++ b/src/Model/Model_AttributeReference.cpp @@ -20,9 +20,7 @@ void Model_AttributeReference::setValue(ObjectPtr theObject) boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); - if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get())); myRef->Set(aData->label().Father()); // references to the feature label - boost::shared_dynamic_cast(owner()->document())->objectIsReferenced(theObject); owner()->data()->sendAttributeUpdated(this); } @@ -51,7 +49,6 @@ Model_AttributeReference::Model_AttributeReference(TDF_Label& theLabel) if (owner()) { boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); - if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get())); } } } @@ -62,7 +59,6 @@ void Model_AttributeReference::setObject(const boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); - if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get())); } } @@ -71,5 +67,4 @@ Model_AttributeReference::~Model_AttributeReference() boost::shared_ptr aDoc = boost::dynamic_pointer_cast(owner()->document()); TDF_Label aLab = myRef->Get(); - if (aDoc && !aLab.IsNull()) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get())); } diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 62659de6c..54a52a22a 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -9,11 +9,25 @@ #include #include #include +#include #include +#include +#include +#include #include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include using namespace std; @@ -29,24 +43,12 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, if (!isOldContext) myRef.setValue(theContext); - // perform the selection - TNaming_Selector aSel(myRef.myRef->Label()); - TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl() : TopoDS_Shape(); - TopoDS_Shape aContext; + if (theContext->groupName() == ModelAPI_ResultBody::group()) + selectBody(theContext, theSubShape); + else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) + selectConstruction(theContext, theSubShape); - ResultBodyPtr aBody = boost::dynamic_pointer_cast(myRef.value()); - if (aBody) - aContext = aBody->shape()->impl(); - else { - ResultConstructionPtr aConstr = boost::dynamic_pointer_cast(myRef.value()); - if (aConstr) - aContext = aConstr->shape()->impl(); - else - throw std::invalid_argument("a result with shape is expected"); - } - aSel.Select(aNewShape, aContext); myIsInitialized = true; - owner()->data()->sendAttributeUpdated(this); } @@ -55,9 +57,10 @@ boost::shared_ptr Model_AttributeSelection::value() boost::shared_ptr aResult; if (myIsInitialized) { Handle(TNaming_NamedShape) aSelection; - if (myRef.myRef->Label().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) { + if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) { TopoDS_Shape aSelShape = aSelection->Get(); - aResult->setImpl(&aSelShape); + aResult = boost::shared_ptr(new GeomAPI_Shape); + aResult->setImpl(new TopoDS_Shape(aSelShape)); } } return aResult; @@ -76,5 +79,181 @@ ResultPtr Model_AttributeSelection::context() { void Model_AttributeSelection::setObject(const boost::shared_ptr& theObject) { + ModelAPI_AttributeSelection::setObject(theObject); myRef.setObject(theObject); } + +bool Model_AttributeSelection::update() +{ + ResultPtr aContext = context(); + if (!aContext) return false; + if (aContext->groupName() == ModelAPI_ResultBody::group()) { + // body: just a named shape, use selection mechanism from OCCT + TNaming_Selector aSelector(selectionLabel()); + TDF_LabelMap aScope; // empty means the whole document + return aSelector.Solve(aScope) == Standard_True; + + } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) { + // construction: identification by the results indexes, recompute faces and + // take the face that more close by the indexes + boost::shared_ptr aWirePtr = boost::dynamic_pointer_cast( + boost::dynamic_pointer_cast(aContext)->shape()); + if (aWirePtr && aWirePtr->hasPlane()) { + // If this is a wire with plane defined thin it is a sketch-like object + std::list > aFaces; + GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(), + aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces); + if (aFaces.empty()) // no faces, update can not work correctly + return false; + // if there is no edges indexes, any face can be used: take the first + boost::shared_ptr aData = + boost::dynamic_pointer_cast(owner()->data()); + TDF_Label aLab = aData->label(); + Handle(TDataStd_IntPackedMap) aSubIds; + boost::shared_ptr aNewSelected; + if (!aLab.FindAttribute(TDataStd_IntPackedMap::GetID(), aSubIds) || aSubIds->Extent() == 0) { + aNewSelected = *(aFaces.begin()); + } else { // searching for most looks-like initial face by the indexes + // prepare edges of the current resut for the fast searching + TColStd_MapOfTransient allCurves; + FeaturePtr aContextFeature = owner()->document()->feature(aContext); + CompositeFeaturePtr aComposite = + boost::dynamic_pointer_cast(aContextFeature); + if (!aComposite) // must be composite at least for the current implementation + return false; + const int aSubNum = aComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + if (aSubIds->Contains(aComposite->subFeatureId(a))) { + FeaturePtr aSub = aComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes = aResults.cbegin(); + for(; aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + boost::dynamic_pointer_cast(*aRes); + if (aConstr->shape() && aConstr->shape()->isEdge()) { + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + allCurves.Add(aCurve); + } + } + } + } + } + // iterate new result faces and searching for these edges + std::list >::iterator aFacesIter = aFaces.begin(); + double aBestFound = 0; // best percentage of found edges + for(; aFacesIter != aFaces.end(); aFacesIter++) { + int aFound = 0, aNotFound = 0; + TopExp_Explorer anEdgesExp((*aFacesIter)->impl(), TopAbs_EDGE); + for(; anEdgesExp.More(); anEdgesExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgesExp.Current()); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (allCurves.Contains(aCurve)) { + aFound++; + } else { + aNotFound++; + } + } + } + if (aFound + aNotFound != 0) { + double aPercentage = double(aFound) / double(aFound + aNotFound); + if (aPercentage > aBestFound) { + aBestFound = aPercentage; + aNewSelected = *aFacesIter; + } + } + } + if (aNewSelected) { // store this new selection + selectConstruction(aContext, aNewSelected); + return true; + } + } + } + } + return false; // unknown case +} + + +void Model_AttributeSelection::selectBody( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape) +{ + // perform the selection + TNaming_Selector aSel(selectionLabel()); + TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl() : TopoDS_Shape(); + TopoDS_Shape aContext; + + ResultBodyPtr aBody = boost::dynamic_pointer_cast(myRef.value()); + if (aBody) + aContext = aBody->shape()->impl(); + else { + ResultConstructionPtr aConstr = boost::dynamic_pointer_cast(myRef.value()); + if (aConstr) { + aContext = aConstr->shape()->impl(); + } else { + Events_Error::send("A result with shape is expected"); + return; + } + } + aSel.Select(aNewShape, aContext); +} + +void Model_AttributeSelection::selectConstruction( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape) +{ + FeaturePtr aContextFeature = owner()->document()->feature(theContext); + CompositeFeaturePtr aComposite = + boost::dynamic_pointer_cast(aContextFeature); + if (!aComposite || aComposite->numberOfSubs() == 0) { + return; // saving of context is enough: result construction contains exactly the needed shape + } + boost::shared_ptr aData = boost::dynamic_pointer_cast(owner()->data()); + TDF_Label aLab = aData->label(); + // identify the reuslts of sub-object of the composite by edges + const TopoDS_Shape& aSubShape = theSubShape->impl(); + TColStd_MapOfTransient allCurves; + for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + allCurves.Add(aCurve); + } + // iterate and store the result ids of sub-elements + Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab); + const int aSubNum = aComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + FeaturePtr aSub = aComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes = aResults.cbegin(); + // there may be many shapes (circle and center): register if at least one is in selection + for(; aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + boost::dynamic_pointer_cast(*aRes); + if (aConstr->shape() && aConstr->shape()->isEdge()) { + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (allCurves.Contains(aCurve)) { + boost::shared_ptr aSubData = boost::dynamic_pointer_cast(aSub->data()); + TDF_Label aSubLab = aSubData->label(); + aRefs->Add(aComposite->subFeatureId(a)); + } + } + } + } + } + // store the selected as primitive + TNaming_Builder aBuilder(selectionLabel()); + aBuilder.Generated(aSubShape); +} + +TDF_Label Model_AttributeSelection::selectionLabel() +{ + return myRef.myRef->Label().FindChild(1); +} diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index b380fef83..150847679 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -28,13 +28,31 @@ public: /// Returns the context of the selection (the whole shape owner) MODEL_EXPORT virtual ResultPtr context(); + /// Sets the feature object MODEL_EXPORT virtual void setObject(const boost::shared_ptr& theObject); + /// Updates the underlied selection due to the changes in the referenced objects + /// \returns false if update is failed + MODEL_EXPORT virtual bool update(); + protected: /// Objects are created for features automatically MODEL_EXPORT Model_AttributeSelection(TDF_Label& theLabel); + /// Performs the selection for the body result (TNaming Selection) + + /// Performs the selection for the body result (TNaming selection) + virtual void selectBody( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape); + /// Performs the selection for the construction result (selection by index) + virtual void selectConstruction( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape); + + /// Returns the label where TNaming_Selection results are stored + /// Note: there must be no attributes stored at the same label because Selector clears this lab + TDF_Label selectionLabel(); friend class Model_Data; + friend class Model_AttributeSelectionList; }; #endif diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp new file mode 100644 index 000000000..a95510118 --- /dev/null +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -0,0 +1,82 @@ +// File: Model_AttributeSelectionList.h +// Created: 22 Oct 2014 +// Author: Mikhail PONIKAROV + +#include "Model_AttributeSelectionList.h" +#include "Model_AttributeSelection.h" +#include "Model_Application.h" +#include "Model_Events.h" +#include "Model_Data.h" + +#include + +using namespace std; + +void Model_AttributeSelectionList::append( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape) +{ + int aNewTag = mySize->Get() + 1; + TDF_Label aNewLab = mySize->Label().FindChild(aNewTag); + + boost::shared_ptr aNewAttr = + boost::shared_ptr(new Model_AttributeSelection(aNewLab)); + if (owner()) { + aNewAttr->setObject(owner()); + } + mySubs.push_back(aNewAttr); + mySize->Set(aNewTag); + aNewAttr->setValue(theContext, theSubShape); + owner()->data()->sendAttributeUpdated(this); +} + +int Model_AttributeSelectionList::size() +{ + return mySize->Get(); +} + +boost::shared_ptr + Model_AttributeSelectionList::value(const int theIndex) +{ + return mySubs[theIndex]; +} + +void Model_AttributeSelectionList::clear() +{ + if (!mySubs.empty()) { + mySize->Set(0); + mySubs.clear(); + TDF_ChildIterator aSubIter(mySize->Label()); + for(; aSubIter.More(); aSubIter.Next()) { + aSubIter.Value().ForgetAllAttributes(Standard_True); + } + owner()->data()->sendAttributeUpdated(this); + } +} + +Model_AttributeSelectionList::Model_AttributeSelectionList(TDF_Label& theLabel) +{ + myIsInitialized = theLabel.FindAttribute(TDataStd_Integer::GetID(), mySize) == Standard_True; + if (!myIsInitialized) { + mySize = TDataStd_Integer::Set(theLabel, 0); + } else { // recollect mySubs + int aNum = mySize->Get(); + TDF_ChildIterator aSubIter(theLabel); + for(; aSubIter.More(), aNum != 0; aSubIter.Next(), aNum--) { + TDF_Label aChildLab = aSubIter.Value(); + boost::shared_ptr aNewAttr = + boost::shared_ptr(new Model_AttributeSelection(aChildLab)); + if (owner()) + aNewAttr->setObject(owner()); + mySubs.push_back(aNewAttr); + } + } +} + +void Model_AttributeSelectionList::setObject(const boost::shared_ptr& theObject) +{ + ModelAPI_AttributeSelectionList::setObject(theObject); + std::vector >::iterator aSubIter = mySubs.begin(); + for(; aSubIter != mySubs.end(); aSubIter++) { + (*aSubIter)->setObject(theObject); + } +} diff --git a/src/Model/Model_AttributeSelectionList.h b/src/Model/Model_AttributeSelectionList.h new file mode 100644 index 000000000..103b213f1 --- /dev/null +++ b/src/Model/Model_AttributeSelectionList.h @@ -0,0 +1,49 @@ +// File: Model_AttributeSelectionList.h +// Created: 22 Oct 2014 +// Author: Mikhail PONIKAROV + +#ifndef Model_AttributeSelectionList_H_ +#define Model_AttributeSelectionList_H_ + +#include "Model.h" +#include "Model_AttributeSelection.h" +#include +#include +#include + +/**\class Model_AttributeSelectionList + * \ingroup DataModel + * \brief Attribute that contains list of references to the sub-shapes with + * possibility to manage them. + */ + +class Model_AttributeSelectionList : public ModelAPI_AttributeSelectionList +{ + Handle(TDataStd_Integer) mySize; ///< Contains size of this list + std::vector > mySubs; /// the selection attributes +public: + /// Adds the new reference to the end of the list + MODEL_EXPORT virtual void append( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape); + + /// Returns the number ofselection attributes in the list + MODEL_EXPORT virtual int size(); + + /// Returns the attribute selection by the index (zero based) + MODEL_EXPORT virtual boost::shared_ptr value(const int theIndex); + + /// Returns all attributes + MODEL_EXPORT virtual void clear(); + + /// Sets the feature object + MODEL_EXPORT virtual void setObject(const boost::shared_ptr& theObject); + +protected: + /// Objects are created for features automatically + MODEL_EXPORT Model_AttributeSelectionList(TDF_Label& theLabel); + /// Performs the selection for the body result (TNaming Selection) + + friend class Model_Data; +}; + +#endif diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index c76a2f26f..cc3ed5ef3 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,8 @@ void Model_Data::addAttribute(const std::string& theID, const std::string theAtt anAttr = new Model_AttributeReference(anAttrLab); } else if (theAttrType == ModelAPI_AttributeSelection::type()) { anAttr = new Model_AttributeSelection(anAttrLab); + } else if (theAttrType == ModelAPI_AttributeSelectionList::type()) { + anAttr = new Model_AttributeSelectionList(anAttrLab); } else if (theAttrType == ModelAPI_AttributeRefAttr::type()) { anAttr = new Model_AttributeRefAttr(anAttrLab); } else if (theAttrType == ModelAPI_AttributeRefList::type()) { @@ -97,7 +100,8 @@ void Model_Data::addAttribute(const std::string& theID, const std::string theAtt boost::shared_ptr Model_Data::document(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -112,7 +116,8 @@ boost::shared_ptr Model_Data::document(const std::stri boost::shared_ptr Model_Data::real(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -127,7 +132,8 @@ boost::shared_ptr Model_Data::real(const std::string& boost::shared_ptr Model_Data::integer(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -142,7 +148,8 @@ boost::shared_ptr Model_Data::integer(const std::stri boost::shared_ptr Model_Data::boolean(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -157,7 +164,8 @@ boost::shared_ptr Model_Data::boolean(const std::stri boost::shared_ptr Model_Data::string(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -173,7 +181,8 @@ boost::shared_ptr Model_Data::string(const std::string boost::shared_ptr Model_Data::reference(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -188,7 +197,8 @@ boost::shared_ptr Model_Data::reference(const std:: boost::shared_ptr Model_Data::selection(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -201,9 +211,27 @@ boost::shared_ptr Model_Data::selection(const std:: return aRes; } +boost::shared_ptr + Model_Data::selectionList(const std::string& theID) +{ + std::map >::iterator aFound = + myAttrs.find(theID); + if (aFound == myAttrs.end()) { + // TODO: generate error on unknown attribute request and/or add mechanism for customization + return boost::shared_ptr(); + } + boost::shared_ptr aRes = + boost::dynamic_pointer_cast(aFound->second); + if (!aRes) { + // TODO: generate error on invalid attribute type request + } + return aRes; +} + boost::shared_ptr Model_Data::refattr(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -218,7 +246,8 @@ boost::shared_ptr Model_Data::refattr(const std::stri boost::shared_ptr Model_Data::reflist(const std::string& theID) { - std::map >::iterator aFound = myAttrs.find(theID); + std::map >::iterator aFound = + myAttrs.find(theID); if (aFound == myAttrs.end()) { // TODO: generate error on unknown attribute request and/or add mechanism for customization return boost::shared_ptr(); @@ -241,7 +270,8 @@ boost::shared_ptr Model_Data::attribute(const std::string& t const std::string& Model_Data::id(const boost::shared_ptr& theAttr) { - std::map >::iterator anAttr = myAttrs.begin(); + std::map >::iterator anAttr = + myAttrs.begin(); for (; anAttr != myAttrs.end(); anAttr++) { if (anAttr->second == theAttr) return anAttr->first; @@ -321,39 +351,52 @@ bool Model_Data::mustBeUpdated() return myLab.IsAttribute(kMustBeUpdatedGUID) == Standard_True; } -bool Model_Data::referencesTo(const boost::shared_ptr& theFeature) +int Model_Data::featureId() const { - // collect results of this feature first to check references quickly in the cycle - std::set aFeatureObjs; - aFeatureObjs.insert(theFeature); - std::list >::const_iterator aRIter = - theFeature->results().cbegin(); - for(; aRIter != theFeature->results().cend(); aRIter++) { - if (*aRIter) - aFeatureObjs.insert(*aRIter); - } + return myLab.Father().Tag(); // tag of the feature label +} - std::map >::iterator anAttrsIter = - myAttrs.begin(); - for (; anAttrsIter != myAttrs.end(); anAttrsIter++) { - if (anAttrsIter->second->attributeType() == ModelAPI_AttributeRefAttr::type()) { - boost::shared_ptr aRefAttr = - boost::dynamic_pointer_cast(anAttrsIter->second); - if (aRefAttr && aRefAttr->isObject()) { // check referenced object - if (aFeatureObjs.find(aRefAttr->object()) != aFeatureObjs.end()) - return true; - } else { // check object of referenced attribute - boost::shared_ptr anAttr = aRefAttr->attr(); - if (anAttr && aFeatureObjs.find(anAttr->owner()) != aFeatureObjs.end()) - return true; - } - } else if (anAttrsIter->second->attributeType() == ModelAPI_AttributeReference::type()) { - boost::shared_ptr aRef = - boost::dynamic_pointer_cast(anAttrsIter->second); - if (aFeatureObjs.find(aRef->value()) != aFeatureObjs.end()) { - return true; +void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID) +{ + // TODO: the concealment state update + myRefsToMe.insert(theFeature->data()->attribute(theAttrID)); +} + +void Model_Data::referencesToObjects( + std::list > >& theRefs) +{ + std::map >::iterator anAttr = myAttrs.begin(); + std::list aReferenced; // not inside of cycle to avoid excess memory menagement + for(; anAttr != myAttrs.end(); anAttr++) { + std::string aType = anAttr->second->attributeType(); + if (aType == ModelAPI_AttributeReference::type()) { // reference to object + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeReference>(anAttr->second); + aReferenced.push_back(aRef->value()); + theRefs.push_back(std::pair >(anAttr->first, aReferenced)); + } else if (aType == ModelAPI_AttributeRefAttr::type()) { // reference to attribute or object + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(anAttr->second); + aReferenced.push_back(aRef->isObject() ? aRef->object() : aRef->attr()->owner()); + } else if (aType == ModelAPI_AttributeRefList::type()) { // list of references + aReferenced = boost::dynamic_pointer_cast(anAttr->second)->list(); + } else if (aType == ModelAPI_AttributeSelection::type()) { // selection attribute + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeSelection>(anAttr->second); + aReferenced.push_back(aRef->context()); + theRefs.push_back(std::pair >(anAttr->first, aReferenced)); + } else if (aType == ModelAPI_AttributeSelectionList::type()) { // list of selection attributes + boost::shared_ptr aRef = boost::dynamic_pointer_cast< + ModelAPI_AttributeSelectionList>(anAttr->second); + for(int a = aRef->size() - 1; a >= 0; a--) { + aReferenced.push_back(aRef->value(a)->context()); } + } else + continue; // nothing to do, not reference + + if (!aReferenced.empty()) { + theRefs.push_back(std::pair >(anAttr->first, aReferenced)); + aReferenced.clear(); } } - return false; } diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 45360d1a8..46d50acc0 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -26,6 +26,7 @@ #include #include #include +#include class ModelAPI_Attribute; @@ -44,6 +45,9 @@ class Model_Data : public ModelAPI_Data /// needed here to emit signal that object changed on change of the attribute ObjectPtr myObject; + /// List of attributes referenced to owner (updated only during the transaction change) + std::set myRefsToMe; + Model_Data(); /// Returns label of this feature @@ -53,9 +57,11 @@ class Model_Data : public ModelAPI_Data } friend class Model_Document; + friend class Model_Update; friend class Model_AttributeReference; friend class Model_AttributeRefAttr; friend class Model_AttributeRefList; + friend class Model_AttributeSelection; public: /// Returns the name of the feature visible by the user in the object browser @@ -75,6 +81,9 @@ class Model_Data : public ModelAPI_Data /// Returns the attribute that contains selection to a shape MODEL_EXPORT virtual boost::shared_ptr selection(const std::string& theID); + /// Returns the attribute that contains selection to a shape + MODEL_EXPORT virtual boost::shared_ptr + selectionList(const std::string& theID); /// Returns the attribute that contains reference to an attribute of a feature MODEL_EXPORT virtual boost::shared_ptr refattr(const std::string& theID); @@ -140,8 +149,19 @@ class Model_Data : public ModelAPI_Data /// Returns true if feature must be updated (re-executed) on rebuild MODEL_EXPORT virtual bool mustBeUpdated(); - /// Returns true if this data attributes are referenced to the given feature or its results - MODEL_EXPORT virtual bool referencesTo(const boost::shared_ptr& theFeature); + /// Returns the identifier of feature-owner, unique in this document + MODEL_EXPORT virtual int featureId() const; + +private: + // removes all information about back references + inline void eraseBackReferences() {myRefsToMe.clear();} + // adds a back reference (with identifier which attribute references to this object + void addBackReference(FeaturePtr theFeature, std::string theAttrID); + // returns all objects referenced to this + const std::set& refsToMe() {return myRefsToMe;} + // returns all references by attributes of this data + // \param the returned list of pairs: id of referenced attribute and list of referenced objects + void referencesToObjects(std::list > >& theRefs); }; #endif diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 59ebd2fb0..05452239c 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -146,7 +147,7 @@ bool Model_Document::load(const char* theFileName) myDoc->SetUndoLimit(UNDO_LIMIT); // to avoid the problem that feature is created in the current, not this, document Model_Session::get()->setActiveDocument(anApp->getDocument(myID)); - synchronizeFeatures(); + synchronizeFeatures(false, true); } return !isError; } @@ -264,10 +265,12 @@ void Model_Document::finishOperation() if (!myDoc->HasOpenCommand() && myNestedNum != -1) boost::static_pointer_cast(Model_Session::get()) ->setCheckTransactions(false); // for nested transaction commit + synchronizeBackRefs(); Events_Loop* aLoop = Events_Loop::loop(); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); if (!myDoc->HasOpenCommand() && myNestedNum != -1) boost::static_pointer_cast(Model_Session::get()) @@ -304,7 +307,7 @@ void Model_Document::abortOperation() myNestedNum = -1; myDoc->AbortCommand(); } - synchronizeFeatures(true); + synchronizeFeatures(true, false); // references were not changed since transaction start // abort for all subs std::set::iterator aSubIter = mySubs.begin(); for (; aSubIter != mySubs.end(); aSubIter++) @@ -343,7 +346,7 @@ void Model_Document::undo() myNestedNum--; if (!myIsEmptyTr[myTransactionsAfterSave]) myDoc->Undo(); - synchronizeFeatures(true); + synchronizeFeatures(true, true); // undo for all subs std::set::iterator aSubIter = mySubs.begin(); for (; aSubIter != mySubs.end(); aSubIter++) @@ -369,7 +372,7 @@ void Model_Document::redo() if (!myIsEmptyTr[myTransactionsAfterSave]) myDoc->Redo(); myTransactionsAfterSave++; - synchronizeFeatures(true); + synchronizeFeatures(true, true); // redo for all subs std::set::iterator aSubIter = mySubs.begin(); for (; aSubIter != mySubs.end(); aSubIter++) @@ -467,16 +470,11 @@ void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck) // check the feature: it must have no depended objects on it std::list::const_iterator aResIter = theFeature->results().cbegin(); for(; aResIter != theFeature->results().cend(); aResIter++) { - if (myConcealedResults.find(*aResIter) != myConcealedResults.end()) { - Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); - return; - } - } - NCollection_DataMap::Iterator anObjIter(myObjs); - for(; anObjIter.More(); anObjIter.Next()) { - DataPtr aData = anObjIter.Value()->data(); - if (aData->referencesTo(theFeature)) { - Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); + boost::shared_ptr aData = + boost::dynamic_pointer_cast((*aResIter)->data()); + if (aData && !aData->refsToMe().empty()) { + Events_Error::send( + "Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); return; } } @@ -493,22 +491,11 @@ void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck) // erase all attributes under the label of feature aFeatureLabel.ForgetAllAttributes(); // remove it from the references array - RemoveFromRefArray(featuresLabel(), aFeatureLabel); - + if (theFeature->isInHistory()) { + RemoveFromRefArray(featuresLabel(), aFeatureLabel); + } // event: feature is deleted ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group()); - /* this is in "erase" - // results of this feature must be redisplayed - static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - const std::list >& aResults = theFeature->results(); - std::list >::const_iterator aRIter = aResults.begin(); - for (; aRIter != aResults.cend(); aRIter++) { - boost::shared_ptr aRes = *aRIter; - aRes->setData(boost::shared_ptr()); // deleted flag - ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP); - ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), aRes->groupName()); - } - */ } FeaturePtr Model_Document::feature(TDF_Label& theLabel) @@ -590,9 +577,9 @@ ObjectPtr Model_Document::object(const std::string& theGroupID, const int theInd std::list >::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { if ((*aRIter)->groupName() != theGroupID) continue; - bool isIn = theHidden; + bool isIn = theHidden && (*aRIter)->isInHistory(); if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result - isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end(); + isIn = !(*aRIter)->isConcealed(); } if (isIn) { if (anIndex == theIndex) @@ -629,7 +616,7 @@ int Model_Document::size(const std::string& theGroupID, const bool theHidden) if ((*aRIter)->groupName() != theGroupID) continue; bool isIn = theHidden; if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result - isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end(); + isIn = !(*aRIter)->isConcealed(); } if (isIn) aResult++; @@ -664,12 +651,12 @@ void Model_Document::setUniqueName(FeaturePtr theFeature) // check this is unique, if not, increase index by 1 for (aFIter.Initialize(myObjs); aFIter.More();) { FeaturePtr aFeature = aFIter.Value(); - bool isSameName = aFeature->isInHistory() && aFeature->data()->name() == aName; + bool isSameName = aFeature->data()->name() == aName; if (!isSameName) { // check also results to avoid same results names (actual for Parts) const std::list >& aResults = aFeature->results(); std::list >::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { - isSameName = (*aRIter)->isInHistory() && (*aRIter)->data()->name() == aName; + isSameName = (*aRIter)->data()->name() == aName; } } if (isSameName) { @@ -701,7 +688,7 @@ void Model_Document::initData(ObjectPtr theObj, TDF_Label theLab, const int theT } } -void Model_Document::synchronizeFeatures(const bool theMarkUpdated) +void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences) { boost::shared_ptr aThis = Model_Application::getApplication()->getDocument(myID); @@ -785,6 +772,10 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated) aFIter.Next(); } + if (theUpdateReferences) { + synchronizeBackRefs(); + } + myExecuteFeatures = false; aLoop->activateFlushes(true); @@ -794,11 +785,58 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated) aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); } aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); boost::static_pointer_cast(Model_Session::get()) ->setCheckTransactions(true); myExecuteFeatures = true; } +void Model_Document::synchronizeBackRefs() +{ + // first cycle: erase all data about back-references + NCollection_DataMap::Iterator aFeatures(myObjs); + for(; aFeatures.More(); aFeatures.Next()) { + FeaturePtr aFeature = aFeatures.Value(); + boost::shared_ptr aFData = + boost::dynamic_pointer_cast(aFeature->data()); + if (aFData) { + aFData->eraseBackReferences(); + } + const std::list >& aResults = aFeature->results(); + std::list >::const_iterator aRIter = aResults.begin(); + for (; aRIter != aResults.cend(); aRIter++) { + boost::shared_ptr aResData = + boost::dynamic_pointer_cast((*aRIter)->data()); + if (aResData) { + aResData->eraseBackReferences(); + } + } + } + + // second cycle: set new back-references: only features may have reference, iterate only them + ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators(); + for(aFeatures.Initialize(myObjs); aFeatures.More(); aFeatures.Next()) { + FeaturePtr aFeature = aFeatures.Value(); + boost::shared_ptr aFData = + boost::dynamic_pointer_cast(aFeature->data()); + if (aFData) { + std::list > > aRefs; + aFData->referencesToObjects(aRefs); + std::list > >::iterator aRefsIter = aRefs.begin(); + for(; aRefsIter != aRefs.end(); aRefsIter++) { + std::list::iterator aRefTo = aRefsIter->second.begin(); + for(; aRefTo != aRefsIter->second.end(); aRefTo++) { + if (*aRefTo) { + boost::shared_ptr aRefData = + boost::dynamic_pointer_cast((*aRefTo)->data()); + aRefData->addBackReference(aFeature, aRefsIter->first); // here the Concealed flag is updated + } + } + } + } + } +} + TDF_Label Model_Document::resultLabel( const boost::shared_ptr& theFeatureData, const int theResultIndex) { @@ -928,48 +966,6 @@ void Model_Document::updateResults(FeaturePtr theFeature) } } -void Model_Document::objectIsReferenced(const ObjectPtr& theObject) -{ - // only bodies are concealed now - ResultBodyPtr aResult = boost::dynamic_pointer_cast(theObject); - if (aResult) { - if (myConcealedResults.find(aResult) != myConcealedResults.end()) { - Events_Error::send(std::string("The object '") + aResult->data()->name() + - "' is already referenced"); - } else { - myConcealedResults.insert(aResult); - boost::shared_ptr aThis = - Model_Application::getApplication()->getDocument(myID); - ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_ResultBody::group()); - - static Events_Loop* aLoop = Events_Loop::loop(); - static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); - aECreator->sendUpdated(aResult, EVENT_DISP); - } - } -} - -void Model_Document::objectIsNotReferenced(const ObjectPtr& theObject) -{ - // only bodies are concealed now - ResultBodyPtr aResult = boost::dynamic_pointer_cast(theObject); - if (aResult) { - std::set::iterator aFind = myConcealedResults.find(aResult); - if (aFind != myConcealedResults.end()) { - ResultPtr aFeature = *aFind; - myConcealedResults.erase(aFind); - boost::shared_ptr aThis = - Model_Application::getApplication()->getDocument(myID); - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); - ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent, false); - } else { - Events_Error::send(std::string("The object '") + aResult->data()->name() + - "' was not referenced '"); - } - } -} - Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper) { return TDF_LabelMapHasher::HashCode(theLab, theUpper); diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 6f813bd23..cbea4a19e 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -130,12 +130,6 @@ class Model_Document : public ModelAPI_Document ///! On abort, undo or redo it is not necessary: results in document are updated automatically bool executeFeatures() {return myExecuteFeatures;} - ///! Reutrns true is result was conecaled because of usage it by other object - virtual bool isConcealed(const boost::shared_ptr& theResult) { - return myConcealedResults.find(boost::dynamic_pointer_cast(theResult)) - != myConcealedResults.end(); - } - protected: //! Returns (creates if needed) the features label @@ -146,7 +140,11 @@ class Model_Document : public ModelAPI_Document void setUniqueName(FeaturePtr theFeature); //! Synchronizes myFeatures list with the updated document - void synchronizeFeatures(const bool theMarkUpdated = false); + //! \param theMarkUpdated causes the "update" event for all features + //! \param theUpdateReferences causes the update of back-references + void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences); + //! Synchronizes the BackReferences list in Data of Features and Results + void synchronizeBackRefs(); //! Creates new document with binary file format Model_Document(const std::string theID, const std::string theKind); @@ -174,11 +172,6 @@ class Model_Document : public ModelAPI_Document //! Updates the results list of the feature basing on the current data tree void updateResults(FeaturePtr theFeature); - //! Stores information that there is a reference to this object - void objectIsReferenced(const ObjectPtr& theObject); - //! Removes information that there is a reference to this object - void objectIsNotReferenced(const ObjectPtr& theObject); - //! Returns all sub documents const std::set& subDocuments() const {return mySubs;} @@ -198,8 +191,6 @@ class Model_Document : public ModelAPI_Document /// All features managed by this document (not only in history of OB) /// For optimization mapped by labels NCollection_DataMap myObjs; - /// Results that are referenced and must be concealed for object browser - std::set myConcealedResults; ///< set of identifiers of sub-documents of this document std::set mySubs; diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 090de2d9e..9b18bc046 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -12,6 +12,7 @@ Model_ResultBody::Model_ResultBody() { + setIsConcealed(false); } void Model_ResultBody::store(const boost::shared_ptr& theShape) diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 0b6d56612..8af38252d 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -17,6 +17,7 @@ boost::shared_ptr& Model_ResultConstruction::shape() Model_ResultConstruction::Model_ResultConstruction() { myIsInHistory = true; + setIsConcealed(false); } void Model_ResultConstruction::setIsInHistory(const bool isInHistory) diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index 98319c474..a1fb09b01 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -19,6 +19,7 @@ boost::shared_ptr Model_ResultPart::owner() Model_ResultPart::Model_ResultPart() { + setIsConcealed(false); } void Model_ResultPart::setData(boost::shared_ptr theData) diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 6a3cf53cc..37b020eee 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -191,7 +191,7 @@ boost::shared_ptr Model_Session::copy( aRT->SetRelocation(aSourceRoot, aTargetRoot); TDF_CopyTool::Copy(aDS, aRT); - aNew->synchronizeFeatures(); + aNew->synchronizeFeatures(false, true); return aNew; } diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 9ddd9f8e6..ccdd45e77 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -11,8 +12,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -89,7 +93,7 @@ void Model_Update::processEvent(const boost::shared_ptr& theMess aDocs = ModelAPI_Session::get()->allOpenedDocuments(); } } - // collect all documents involved into the update + // collect all documents involved into the update process set >::iterator aFIter = myInitial.begin(); for (; aFIter != myInitial.end(); aFIter++) { aDocs.push_back((*aFIter)->document()); @@ -123,49 +127,32 @@ bool Model_Update::updateFeature(FeaturePtr theFeature) bool aMustbeUpdated = myInitial.find(theFeature) != myInitial.end(); if (theFeature) { // only real feature contains references to other objects if (theFeature->data()->mustBeUpdated()) aMustbeUpdated = true; - // references - list > aRefs = theFeature->data()->attributes( - ModelAPI_AttributeReference::type()); - list >::iterator aRefsIter = aRefs.begin(); - for (; aRefsIter != aRefs.end(); aRefsIter++) { - boost::shared_ptr aSub = boost::dynamic_pointer_cast< - ModelAPI_AttributeReference>(*aRefsIter)->value(); - if (updateObject(aSub)) { - aMustbeUpdated = true; - } - } - // reference to attribute or object - list > aRefAttrs = theFeature->data()->attributes( - ModelAPI_AttributeRefAttr::type()); - for (aRefsIter = aRefAttrs.begin(); aRefsIter != aRefAttrs.end(); aRefsIter++) { - boost::shared_ptr aRef = - boost::dynamic_pointer_cast(*aRefsIter); - if (!aRef) continue; - if (aRef->isObject()) { - boost::shared_ptr aSub = aRef->object(); - if (updateObject(aSub)) { - aMustbeUpdated = true; - } - } else if (aRef->attr()) { // reference to the attribute - boost::shared_ptr aSub = aRef->attr()->owner(); - if (updateObject(aSub)) { + + // composite feature must be executed after sub-features execution + CompositeFeaturePtr aComposite = + boost::dynamic_pointer_cast(theFeature); + if (aComposite) { + int aSubsNum = aComposite->numberOfSubs(); + for(int a = 0; a < aSubsNum; a++) { + if (updateFeature(aComposite->subFeature(a))) aMustbeUpdated = true; - } } } - // lists of references - aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type()); - for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { - list aListRef = boost::dynamic_pointer_cast(*aRefsIter) - ->list(); - list::iterator aListIter = aListRef.begin(); - for (; aListIter != aListRef.end(); aListIter++) { - boost::shared_ptr aSub = *aListIter; - if (updateObject(aSub)) { + // check all references: if referenced objects are updated, this object also must be updated + std::list > > aRefs; + boost::shared_ptr aData = + boost::dynamic_pointer_cast(theFeature->data()); + aData->referencesToObjects(aRefs); + std::list > >::iterator aRef = aRefs.begin(); + for(; aRef != aRefs.end(); aRef++) { + std::list::iterator aRefObj = aRef->second.begin(); + for(; aRefObj != aRef->second.end(); aRefObj++) { + if (updateObject(*aRefObj)) { aMustbeUpdated = true; } } } + // execute feature if it must be updated if (aMustbeUpdated) { @@ -174,7 +161,26 @@ bool Model_Update::updateFeature(FeaturePtr theFeature) ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators(); if (aFactory->validate(theFeature)) { if (isAutomatic || (myJustCreatedOrUpdated.find(theFeature) != myJustCreatedOrUpdated.end()) || - !theFeature->isPersistentResult() /* execute quick, not persistent results */) { + !theFeature->isPersistentResult() /* execute quick, not persistent results */) + { + // before execution update the selection attributes if any + list aRefs = + theFeature->data()->attributes(ModelAPI_AttributeSelection::type()); + list::iterator aRefsIter = aRefs.begin(); + for (; aRefsIter != aRefs.end(); aRefsIter++) { + boost::shared_ptr aSel = + boost::dynamic_pointer_cast(*aRefsIter); + aSel->update(); // this must be done on execution since it may be long operation + } + aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelectionList::type()); + for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { + boost::shared_ptr aSel = + boost::dynamic_pointer_cast(*aRefsIter); + for(int a = aSel->size() - 1; a >= 0; a--) { + aSel->value(a)->update(); + } + } + // execute in try-catch to avoid internal problems of the feature try { theFeature->execute(); } catch(...) { @@ -231,6 +237,11 @@ bool Model_Update::updateFeature(FeaturePtr theFeature) bool Model_Update::updateObject(boost::shared_ptr theObject) { + if (myUpdated.find(theObject) != myUpdated.end()) + return myUpdated[theObject]; // already processed + return myInitial.find(theObject) != myInitial.end(); + + /* remove algorithm for update of all features by dependencies tree if (!theObject) return false; FeaturePtr aFeature = boost::dynamic_pointer_cast(theObject); @@ -251,4 +262,5 @@ bool Model_Update::updateObject(boost::shared_ptr theObject) if (myInitial.find(theObject) != myInitial.end()) return true; return false; // nothing is known + */ } diff --git a/src/Model/Model_Validator.cpp b/src/Model/Model_Validator.cpp index 987db716e..d1adbbbe9 100644 --- a/src/Model/Model_Validator.cpp +++ b/src/Model/Model_Validator.cpp @@ -211,8 +211,7 @@ bool Model_ValidatorsFactory::validate(const boost::shared_ptr return true; } -void Model_ValidatorsFactory::registerNotObligatory( - std::string theFeature, std::string theAttribute) +void Model_ValidatorsFactory::registerNotObligatory(std::string theFeature, std::string theAttribute) { std::map::const_iterator it = myIDs.find(kDefaultId); if (it != myIDs.end()) { @@ -222,3 +221,10 @@ void Model_ValidatorsFactory::registerNotObligatory( } } } + +void Model_ValidatorsFactory::registerConcealment(std::string theFeature, std::string theAttribute) +{ + +} + + diff --git a/src/Model/Model_Validator.h b/src/Model/Model_Validator.h index 38d2d7bf5..cfaeb89c5 100644 --- a/src/Model/Model_Validator.h +++ b/src/Model/Model_Validator.h @@ -72,6 +72,10 @@ class Model_ValidatorsFactory : public ModelAPI_ValidatorsFactory /// so, it is not needed for the standard validation mechanism virtual void registerNotObligatory(std::string theFeature, std::string theAttribute); + /// register that this attribute conceals in the object browser + /// all referenced features after execution + virtual void registerConcealment(std::string theFeature, std::string theAttribute); + protected: void addDefaultValidators(std::list& theValidators) const; /// Get instance from Session diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index b0299b5cf..9bebf30fb 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -8,6 +8,7 @@ SET(PROJECT_HEADERS ModelAPI_Session.h ModelAPI_Plugin.h ModelAPI_Feature.h + ModelAPI_CompositeFeature.h ModelAPI_Data.h ModelAPI_Object.h ModelAPI_Document.h @@ -21,6 +22,7 @@ SET(PROJECT_HEADERS ModelAPI_AttributeBoolean.h ModelAPI_AttributeString.h ModelAPI_AttributeSelection.h + ModelAPI_AttributeSelectionList.h ModelAPI_Events.h ModelAPI_Validator.h ModelAPI_FeatureValidator.h diff --git a/src/ModelAPI/ModelAPI.i b/src/ModelAPI/ModelAPI.i index 0eb00bd49..7ff2bfc8e 100644 --- a/src/ModelAPI/ModelAPI.i +++ b/src/ModelAPI/ModelAPI.i @@ -17,6 +17,7 @@ #include "ModelAPI_AttributeReference.h" #include "ModelAPI_AttributeRefAttr.h" #include "ModelAPI_AttributeSelection.h" + #include "ModelAPI_AttributeSelectionList.h" #include "ModelAPI_Validator.h" #include "ModelAPI_AttributeRefList.h" #include "ModelAPI_AttributeBoolean.h" @@ -62,6 +63,7 @@ %shared_ptr(ModelAPI_AttributeRefList) %shared_ptr(ModelAPI_AttributeBoolean) %shared_ptr(ModelAPI_AttributeSelection) +%shared_ptr(ModelAPI_AttributeSelectionList) %shared_ptr(ModelAPI_Result) %shared_ptr(ModelAPI_ResultConstruction) %shared_ptr(ModelAPI_ResultBody) @@ -84,6 +86,7 @@ %include "ModelAPI_AttributeRefAttr.h" %include "ModelAPI_AttributeBoolean.h" %include "ModelAPI_AttributeSelection.h" +%include "ModelAPI_AttributeSelectionList.h" %include "ModelAPI_AttributeRefList.h" %include "ModelAPI_Validator.h" %include "ModelAPI_Result.h" diff --git a/src/ModelAPI/ModelAPI_AttributeRefList.h b/src/ModelAPI/ModelAPI_AttributeRefList.h index b8b5c700b..abb39beb6 100644 --- a/src/ModelAPI/ModelAPI_AttributeRefList.h +++ b/src/ModelAPI/ModelAPI_AttributeRefList.h @@ -36,11 +36,14 @@ class ModelAPI_AttributeRefList : public ModelAPI_Attribute MODELAPI_EXPORT virtual void remove(ObjectPtr theObject) = 0; /// Returns number of features in the list - MODELAPI_EXPORT virtual int size() = 0; + MODELAPI_EXPORT virtual int size() const = 0; /// Returns the list of features MODELAPI_EXPORT virtual std::list list() = 0; + /// Returns the referenced object by the zero-based index + MODELAPI_EXPORT virtual ObjectPtr object(const int theIndex) const = 0; + protected: /// Objects are created for features automatically MODELAPI_EXPORT ModelAPI_AttributeRefList() diff --git a/src/ModelAPI/ModelAPI_AttributeSelection.h b/src/ModelAPI/ModelAPI_AttributeSelection.h index 98d4af7d6..40882dde4 100644 --- a/src/ModelAPI/ModelAPI_AttributeSelection.h +++ b/src/ModelAPI/ModelAPI_AttributeSelection.h @@ -26,6 +26,10 @@ class ModelAPI_AttributeSelection : public ModelAPI_Attribute /// Returns the context of the selection (the whole shape owner) virtual ResultPtr context() = 0; + /// Updates the underlied selection due to the changes in the referenced objects + /// \returns false if update is failed + virtual bool update() = 0; + /// Returns the type of this class of attributes static std::string type() { @@ -50,4 +54,7 @@ class ModelAPI_AttributeSelection : public ModelAPI_Attribute } }; +//! Pointer on double attribute +typedef boost::shared_ptr AttributeSelectionPtr; + #endif diff --git a/src/ModelAPI/ModelAPI_AttributeSelectionList.h b/src/ModelAPI/ModelAPI_AttributeSelectionList.h new file mode 100644 index 000000000..6dc13dd3a --- /dev/null +++ b/src/ModelAPI/ModelAPI_AttributeSelectionList.h @@ -0,0 +1,60 @@ +// File: ModelAPI_AttributeSelectionList.h +// Created: 22 Oct 2014 +// Author: Mikhail PONIKAROV + +#ifndef ModelAPI_AttributeSelectionList_H_ +#define ModelAPI_AttributeSelectionList_H_ + +#include "ModelAPI_AttributeSelection.h" +#include + +/**\class ModelAPI_AttributeSelectionList + * \ingroup DataModel + * \brief Attribute that contains list of references to the sub-shapes with + * possibility to manage them. + */ + +class ModelAPI_AttributeSelectionList : public ModelAPI_Attribute +{ + public: + /// Adds the new reference to the end of the list + virtual void append( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape) = 0; + + /// Returns the number ofselection attributes in the list + virtual int size() = 0; + + /// Returns the attribute selection by the index (zero based) + virtual boost::shared_ptr value(const int theIndex) = 0; + + /// Returns all attributes + virtual void clear() = 0; + + /// Returns the type of this class of attributes + static std::string type() + { + return "SelectionList"; + } + + /// Returns the type of this class of attributes, not static method + virtual std::string attributeType() + { + return type(); + } + + /// To virtually destroy the fields of successors + virtual ~ModelAPI_AttributeSelectionList() + { + } + + protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_AttributeSelectionList() + { + } +}; + +//! Pointer on double attribute +typedef boost::shared_ptr AttributeSelectionListPtr; + +#endif diff --git a/src/ModelAPI/ModelAPI_CompositeFeature.h b/src/ModelAPI/ModelAPI_CompositeFeature.h new file mode 100644 index 000000000..28c4d6d2a --- /dev/null +++ b/src/ModelAPI/ModelAPI_CompositeFeature.h @@ -0,0 +1,35 @@ +// File: ModelAPI_CompositeFeature.hxx +// Created: 20 Oct 2014 +// Author: Mikhail PONIKAROV + +#ifndef ModelAPI_CompositeFeature_H_ +#define ModelAPI_CompositeFeature_H_ + +#include "ModelAPI_Feature.h" + +/**\class ModelAPI_CompositeFeature + * \ingroup DataModel + * \brief Feature that consists of other features: like sketcher + * with edges inside. It just allows t oadd a feature to this feature only + * instead of adding in both document and this feature. + */ +class ModelAPI_CompositeFeature : public ModelAPI_Feature +{ +public: + /// Adds feature to the sketch and to its document + virtual boost::shared_ptr addFeature(std::string theID) = 0; + + /// Returns the number of sub-elements + virtual int numberOfSubs() const = 0; + + /// Returns the sub-feature by zero-base index + virtual boost::shared_ptr subFeature(const int theIndex) const = 0; + + /// Returns the sub-feature unique identifier in this composite feature by zero-base index + virtual int subFeatureId(const int theIndex) const = 0; +}; + +//! Pointer on the composite feature object +typedef boost::shared_ptr CompositeFeaturePtr; + +#endif diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index 1bd01c5b3..2acf4fc6b 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -22,6 +22,7 @@ class ModelAPI_Document; class ModelAPI_Attribute; class ModelAPI_Feature; class ModelAPI_AttributeSelection; +class ModelAPI_AttributeSelectionList; class GeomAPI_Shape; /**\class ModelAPI_Data @@ -50,6 +51,9 @@ class MODELAPI_EXPORT ModelAPI_Data virtual boost::shared_ptr reference(const std::string& theID) = 0; /// Returns the attribute that contains selection to a shape virtual boost::shared_ptr selection(const std::string& theID) = 0; + /// Returns the attribute that contains selection to a shape + virtual boost::shared_ptr + selectionList(const std::string& theID) = 0; /// Returns the attribute that contains reference to an attribute of a feature virtual boost::shared_ptr refattr(const std::string& theID) = 0; /// Returns the attribute that contains list of references to features @@ -102,8 +106,8 @@ class MODELAPI_EXPORT ModelAPI_Data /// Returns true if feature must be updated (re-executed) on rebuild virtual bool mustBeUpdated() = 0; - /// Returns true if this data attributes are referenced to the given feature or its results - virtual bool referencesTo(const boost::shared_ptr& theFeature) = 0; + /// Returns the identifier of feature-owner, unique in this document + virtual int featureId() const = 0; protected: /// Objects are created for features automatically diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 773ec389c..cdfa1d75e 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -81,9 +81,6 @@ public: virtual boost::shared_ptr feature( const boost::shared_ptr& theResult) = 0; - ///! Reutrns true is result was conecaled because of usage it by other object - virtual bool isConcealed(const boost::shared_ptr& theResult) = 0; - protected: /// Only for SWIG wrapping it is here MODELAPI_EXPORT ModelAPI_Document() diff --git a/src/ModelAPI/ModelAPI_Object.h b/src/ModelAPI/ModelAPI_Object.h index a00d6e3b8..f6e3c6c32 100644 --- a/src/ModelAPI/ModelAPI_Object.h +++ b/src/ModelAPI/ModelAPI_Object.h @@ -34,7 +34,7 @@ class ModelAPI_Object } /// Returns the data manager of this object: attributes - virtual boost::shared_ptr data() + virtual boost::shared_ptr data() const { return myData; } @@ -56,6 +56,7 @@ class ModelAPI_Object /// To use virtuality for destructors virtual ~ModelAPI_Object() {} + protected: /// Sets the data manager of an object (document does) virtual void setData(boost::shared_ptr theData) diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index af9e7ce87..eb664ec22 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -17,12 +17,19 @@ class ModelAPI_Feature; */ class ModelAPI_Result : public ModelAPI_Object { + bool myIsConcealed; ///< the result is concealed from the data tree (referenced by other objects) public: - /// Returns the source feature of this result - //virtual boost::shared_ptr owner() = 0; + /// Returns true if the result is concealed from the data tree (referenced by other objects) + inline bool isConcealed() {return myIsConcealed;} + + /// Returns true if the result is concealed from the data tree (referenced by other objects) + inline void setIsConcealed(const bool theValue) {myIsConcealed = theValue;} + + /// To virtually destroy the fields of successors + virtual ~ModelAPI_Result() + { + } - /// Returns the group identifier of this result - //virtual std::string groupName() = 0; }; //! Pointer on feature object diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index 361547441..8942a62f2 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -48,11 +48,6 @@ public: /// Returns the shape-result produced by this feature virtual boost::shared_ptr shape() = 0; - /// To virtually destroy the fields of successors - virtual ~ModelAPI_ResultBody() - { - } - /// Records the subshape newShape which was generated during a topological construction. /// As an example, consider the case of a face generated in construction of a box. virtual void generated( @@ -75,11 +70,6 @@ public: const boost::shared_ptr& theOldShape, const int theTag = 1) = 0; protected: - /// Use plugin manager for features creation: this method is - /// defined here only for SWIG-wrapping - ModelAPI_ResultBody() - { - } }; //! Pointer on feature object diff --git a/src/ModelAPI/ModelAPI_Session.cpp b/src/ModelAPI/ModelAPI_Session.cpp index 137f8f8a5..db8a54ca2 100644 --- a/src/ModelAPI/ModelAPI_Session.cpp +++ b/src/ModelAPI/ModelAPI_Session.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/src/ModelAPI/ModelAPI_Validator.h b/src/ModelAPI/ModelAPI_Validator.h index ea47856f4..940be4c4d 100644 --- a/src/ModelAPI/ModelAPI_Validator.h +++ b/src/ModelAPI/ModelAPI_Validator.h @@ -83,6 +83,10 @@ class MODELAPI_EXPORT ModelAPI_ValidatorsFactory /// so, it is not needed for the standard validation mechanism virtual void registerNotObligatory(std::string theFeature, std::string theAttribute) = 0; + /// register that this attribute conceals in the object browser + /// all referenced features after execution + virtual void registerConcealment(std::string theFeature, std::string theAttribute) = 0; + protected: /// Get instance from Session ModelAPI_ValidatorsFactory() diff --git a/src/ModuleBase/CMakeLists.txt b/src/ModuleBase/CMakeLists.txt index 4a778cb41..ddf454e2c 100644 --- a/src/ModuleBase/CMakeLists.txt +++ b/src/ModuleBase/CMakeLists.txt @@ -32,6 +32,8 @@ SET(PROJECT_HEADERS ModuleBase_IViewer.h ModuleBase_WidgetLineEdit.h ModuleBase_WidgetMultiSelector.h + ModuleBase_ViewerFilters.h + ModuleBase_ResultPrs.h ) SET(PROJECT_SOURCES @@ -57,12 +59,15 @@ SET(PROJECT_SOURCES ModuleBase_DoubleSpinBox.cpp ModuleBase_WidgetLineEdit.cpp ModuleBase_WidgetMultiSelector.cpp + ModuleBase_ViewerFilters.cpp + ModuleBase_ResultPrs.cpp ) SET(PROJECT_LIBRARIES Config ModelAPI GeomAPI + GeomAlgoAPI ${QT_LIBRARIES} ${CAS_VIEWER} ${CAS_KERNEL} @@ -87,6 +92,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/ModelAPI ${CMAKE_SOURCE_DIR}/src/GeomDataAPI ${CMAKE_SOURCE_DIR}/src/GeomAPI + ${CMAKE_SOURCE_DIR}/src/GeomAlgoAPI ) ADD_DEFINITIONS(-DMODULEBASE_EXPORTS ${CAS_DEFINITIONS}) diff --git a/src/ModuleBase/ModuleBase_ISelection.h b/src/ModuleBase/ModuleBase_ISelection.h index 43bd0ea86..72845616b 100644 --- a/src/ModuleBase/ModuleBase_ISelection.h +++ b/src/ModuleBase/ModuleBase_ISelection.h @@ -47,7 +47,8 @@ class ModuleBase_ISelection virtual void selectedAISObjects(AIS_ListOfInteractive& theList) const = 0; //! Returns list of currently selected shapes - virtual void selectedShapes(NCollection_List& theList) const = 0; + virtual void selectedShapes(NCollection_List& theList, + std::list& theOwners) const = 0; }; diff --git a/src/ModuleBase/ModuleBase_IWorkshop.h b/src/ModuleBase/ModuleBase_IWorkshop.h index 700f2baec..d6d3c416b 100644 --- a/src/ModuleBase/ModuleBase_IWorkshop.h +++ b/src/ModuleBase/ModuleBase_IWorkshop.h @@ -9,6 +9,7 @@ #include "ModuleBase_Definitions.h" #include +#include #include @@ -49,6 +50,12 @@ Q_OBJECT //! Returns currently active operation virtual ModuleBase_Operation* currentOperation() const = 0; + //! Returns AIS opbject by data object + virtual AISObjectPtr findPresentation(const ObjectPtr& theObject) const = 0; + + //! Returns data object by AIS + virtual ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const = 0; + signals: void selectionChanged(); diff --git a/src/ModuleBase/ModuleBase_ModelWidget.cpp b/src/ModuleBase/ModuleBase_ModelWidget.cpp index e2b934ee6..5a6ba6e1e 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.cpp +++ b/src/ModuleBase/ModuleBase_ModelWidget.cpp @@ -26,7 +26,6 @@ ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent, const Config_ myParentId(theParentId) { myIsComputedDefault = false; - myIsObligatory = theData ? theData->getBooleanAttribute(FEATURE_OBLIGATORY, true) : true; myAttributeID = theData ? theData->widgetId() : ""; } @@ -39,9 +38,8 @@ void ModuleBase_ModelWidget::enableFocusProcessing() { QList aMyControls = getControls(); foreach(QWidget* eachControl, aMyControls) { - if(!myFocusInWidgets.contains(eachControl)) { - enableFocusProcessing(eachControl); - } + eachControl->setFocusPolicy(Qt::StrongFocus); + eachControl->installEventFilter(this); } } @@ -92,20 +90,15 @@ void ModuleBase_ModelWidget::updateObject(ObjectPtr theObj) const ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent); } -void ModuleBase_ModelWidget::enableFocusProcessing(QWidget* theWidget) -{ - theWidget->setFocusPolicy(Qt::StrongFocus); - theWidget->installEventFilter(this); - myFocusInWidgets.append(theWidget); -} - bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent) { QWidget* aWidget = qobject_cast(theObject); - if (theEvent->type() == QEvent::MouseButtonRelease && - myFocusInWidgets.contains(aWidget)) { - emit focusInWidget(this); + if (theEvent->type() == QEvent::FocusIn) { + if (getControls().contains(aWidget)) { + emit focusInWidget(this); + } } // pass the event on to the parent class + return QObject::eventFilter(theObject, theEvent); } diff --git a/src/ModuleBase/ModuleBase_ModelWidget.h b/src/ModuleBase/ModuleBase_ModelWidget.h index 9f2f6f455..25c0bf246 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.h +++ b/src/ModuleBase/ModuleBase_ModelWidget.h @@ -48,10 +48,6 @@ Q_OBJECT /// on operation's execute, like radius for circle's constraint (can not be zero) bool isComputedDefault() { return myIsComputedDefault; } - /// Returns false for non-obligatory widgets which are - /// valid even if they are not initialized - bool isObligatory() { return myIsObligatory; } - /// Defines if it is supposed that the widget should interact with the viewer. virtual bool isViewerSelector() { return false; } @@ -139,22 +135,13 @@ signals: void updateObject(ObjectPtr theObj) const; - private: - /// Let the widget process FocusIn events - void enableFocusProcessing(QWidget* theWidget); - protected: std::string myAttributeID; /// the attribute name of the model feature std::string myParentId; /// name of parent FeaturePtr myFeature; bool myIsComputedDefault; /// Value should be computed on execute, - /// like radius for circle's constraint (can not be zero) - bool myIsObligatory; /// Non-obligatory widget is valid even if it is not initialized - - private: - /// Contains a list of widgets that may accept focus - QList myFocusInWidgets; + /// like radius for circle's constraint (can not be zero) }; #endif diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index d55bdc3f0..36bc9f6f3 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -121,10 +121,15 @@ void ModuleBase_Operation::flushCreated() Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); } -FeaturePtr ModuleBase_Operation::createFeature(const bool theFlushMessage) +FeaturePtr ModuleBase_Operation::createFeature( + const bool theFlushMessage, CompositeFeaturePtr theCompositeFeature) { - boost::shared_ptr aDoc = document(); - myFeature = aDoc->addFeature(getDescription()->operationId().toStdString()); + if (theCompositeFeature) { + myFeature = theCompositeFeature->addFeature(getDescription()->operationId().toStdString()); + } else { + boost::shared_ptr aDoc = document(); + myFeature = aDoc->addFeature(getDescription()->operationId().toStdString()); + } if (myFeature) { // TODO: generate an error if feature was not created myIsModified = true; // Model update should call "execute" of a feature. @@ -182,8 +187,8 @@ void ModuleBase_Operation::start() void ModuleBase_Operation::resume() { if (myPropertyPanel) - connect(myPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), this, - SLOT(onWidgetActivated(ModuleBase_ModelWidget*))); + connect(myPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), + this, SLOT(onWidgetActivated(ModuleBase_ModelWidget*))); emit resumed(); } diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index dbf2b3406..80cab9e12 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -192,8 +192,10 @@ signals: /// Creates an operation new feature /// \param theFlushMessage the flag whether the create message should be flushed - /// \returns the created feature - virtual FeaturePtr createFeature(const bool theFlushMessage = true); + /// \param theCompositeFeature the feature that must be used for adding the created object or null + /// \returns the created + virtual FeaturePtr createFeature(const bool theFlushMessage = true, + CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr()); /// Verifies whether this operator can be commited. /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp new file mode 100644 index 000000000..b039e9bfd --- /dev/null +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -0,0 +1,75 @@ +// File: ModuleBase_ResultPrs.cpp +// Created: 21 October 2014 +// Author: Vitaly SMETANNIKOV + +#include "ModuleBase_ResultPrs.h" + +#include +#include +#include + +#include +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE(ModuleBase_ResultPrs, AIS_Shape); +IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ResultPrs, AIS_Shape); + +ModuleBase_ResultPrs::ModuleBase_ResultPrs(ResultPtr theResult) + : AIS_Shape(TopoDS_Shape()), myResult(theResult), myIsSketchMode(false) +{ + boost::shared_ptr aShapePtr = ModelAPI_Tools::shape(theResult); + boost::shared_ptr aWirePtr = + boost::dynamic_pointer_cast(aShapePtr); + if (aWirePtr) { + if (aWirePtr->hasPlane() ) { + // If this is a wire with plane defined thin it is a sketch-like object + // It must have invisible faces + GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(), + aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, myFacesList); + + myOriginalShape = aWirePtr->impl(); + Set(myOriginalShape); + myIsSketchMode = true; + } else { + Set(aWirePtr->impl()); + } + } else { + Set(aShapePtr->impl()); + } +} + + +void ModuleBase_ResultPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, + const Handle(Prs3d_Presentation)& thePresentation, + const Standard_Integer theMode) +{ + boost::shared_ptr aShapePtr = ModelAPI_Tools::shape(myResult); + myOriginalShape = aShapePtr->impl(); + Set(aShapePtr->impl()); + AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); +} + + +void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, + const Standard_Integer aMode) +{ + if (myIsSketchMode) { + if (aMode == TopAbs_FACE) { + BRep_Builder aBuilder; + TopoDS_Compound aComp; + aBuilder.MakeCompound(aComp); + aBuilder.Add(aComp, myOriginalShape); + std::list>::const_iterator aIt; + for (aIt = myFacesList.cbegin(); aIt != myFacesList.cend(); ++aIt) { + TopoDS_Shape aFace = (*aIt)->impl(); + aBuilder.Add(aComp, aFace); + } + Set(aComp); + } else { + Set(myOriginalShape); + } + } + AIS_Shape::ComputeSelection(aSelection, aMode); +} \ No newline at end of file diff --git a/src/ModuleBase/ModuleBase_ResultPrs.h b/src/ModuleBase/ModuleBase_ResultPrs.h new file mode 100644 index 000000000..0d2d058ce --- /dev/null +++ b/src/ModuleBase/ModuleBase_ResultPrs.h @@ -0,0 +1,42 @@ +// File: ModuleBase_ResultPrs.h +// Created: 21 October 2014 +// Author: Vitaly SMETANNIKOV + +#ifndef ModuleBase_ResultPrs_H +#define ModuleBase_ResultPrs_H + +#include "ModuleBase.h" + +#include + +#include +#include + +DEFINE_STANDARD_HANDLE(ModuleBase_ResultPrs, AIS_Shape) + +class ModuleBase_ResultPrs: public AIS_Shape +{ +public: + Standard_EXPORT ModuleBase_ResultPrs(ResultPtr theResult); + + Standard_EXPORT ResultPtr getResult() const { return myResult; } + + DEFINE_STANDARD_RTTI(ModuleBase_ResultPrs) +protected: + Standard_EXPORT virtual void Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, + const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode = 0); + + Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, + const Standard_Integer aMode) ; + +private: + ResultPtr myResult; + + bool myIsSketchMode; + + TopoDS_Shape myOriginalShape; + std::list > myFacesList; +}; + + +#endif \ No newline at end of file diff --git a/src/ModuleBase/ModuleBase_ViewerFilters.cpp b/src/ModuleBase/ModuleBase_ViewerFilters.cpp new file mode 100644 index 000000000..6d2209de5 --- /dev/null +++ b/src/ModuleBase/ModuleBase_ViewerFilters.cpp @@ -0,0 +1,80 @@ +// File: ModuleBase_ViewerFilters.cpp +// Created: 07 Okt 2014 +// Author: Vitaly SMETANNIKOV + + +#include "ModuleBase_ViewerFilters.h" +#include "ModuleBase_IWorkshop.h" + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE(ModuleBase_ShapeDocumentFilter, SelectMgr_Filter); +IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ShapeDocumentFilter, SelectMgr_Filter); + + +//TODO (VSV): Check bug in OCCT: Filter result is ignored (bug25340) +Standard_Boolean ModuleBase_ShapeDocumentFilter::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const +{ + if (theOwner->HasSelectable()) { + Handle(AIS_InteractiveObject) aAisObj = + Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable()); + if (!aAisObj.IsNull()) { + boost::shared_ptr aAISObj = AISObjectPtr(new GeomAPI_AISObject()); + aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aAisObj)); + ObjectPtr aObj = myWorkshop->findPresentedObject(aAISObj); + if (aObj) { + DocumentPtr aDoc = aObj->document(); + SessionPtr aMgr = ModelAPI_Session::get(); + return (aDoc == aMgr->activeDocument()) || (aDoc == aMgr->moduleDocument()); + } + } + } + return Standard_False; +} + + +IMPLEMENT_STANDARD_HANDLE(ModuleBase_ShapeInPlaneFilter, SelectMgr_Filter); +IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ShapeInPlaneFilter, SelectMgr_Filter); + +Standard_Boolean ModuleBase_ShapeInPlaneFilter::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const +{ + if (theOwner->HasSelectable()) { + Handle(StdSelect_BRepOwner) aShapeOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner); + if (!aShapeOwner.IsNull()) { + TopoDS_Shape aShape = aShapeOwner->Shape(); + TopAbs_ShapeEnum aType = aShape.ShapeType(); + switch (aType) { + case TopAbs_VERTEX: + { + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape)); + return myPlane.Distance(aPnt) < Precision::Confusion(); + } + case TopAbs_EDGE: + { + TopoDS_Edge aEdge = TopoDS::Edge(aShape); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aFirst, aLast); + gp_Pnt aFirstPnt = aCurve->Value(aFirst); + gp_Pnt aMidPnt = aCurve->Value((aFirst + aLast) / 2.); + gp_Pnt aLastPnt = aCurve->Value(aLast); + bool aD1 = myPlane.Distance(aFirstPnt) < Precision::Confusion(); + bool aD2 = myPlane.Distance(aMidPnt) < Precision::Confusion(); + bool aD3 = myPlane.Distance(aLastPnt) < Precision::Confusion(); + return aD1 && aD2 && aD3; + } + } + } + } + return Standard_False; +} diff --git a/src/ModuleBase/ModuleBase_ViewerFilters.h b/src/ModuleBase/ModuleBase_ViewerFilters.h new file mode 100644 index 000000000..d26d3db3e --- /dev/null +++ b/src/ModuleBase/ModuleBase_ViewerFilters.h @@ -0,0 +1,55 @@ +// File: ModuleBase_ViewerFilters.h +// Created: 07 Okt 2014 +// Author: Vitaly SMETANNIKOV + + +#ifndef ModuleBase_ViewerFilters_H +#define ModuleBase_ViewerFilters_H + +#include +#include +#include + + +class ModuleBase_IWorkshop; + + +/** +* A filter which provides filtering of selection in 3d viewer. +* Installing of this filter lets to select objects which belong to +* currently active document or to global document +*/ +DEFINE_STANDARD_HANDLE(ModuleBase_ShapeDocumentFilter, SelectMgr_Filter); +class ModuleBase_ShapeDocumentFilter: public SelectMgr_Filter +{ +public: + Standard_EXPORT ModuleBase_ShapeDocumentFilter(ModuleBase_IWorkshop* theWorkshop): SelectMgr_Filter(), + myWorkshop(theWorkshop) {} + + Standard_EXPORT virtual Standard_Boolean IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const; + + DEFINE_STANDARD_RTTI(ModuleBase_ShapeDocumentFilter) + +private: + ModuleBase_IWorkshop* myWorkshop; +}; + +/** +* A filter which provides filtering of selection in 3d viewer. +* Installing of this filter lets to select of Vertexes and Edges which belongs to the given plane +*/ +DEFINE_STANDARD_HANDLE(ModuleBase_ShapeInPlaneFilter, SelectMgr_Filter); +class ModuleBase_ShapeInPlaneFilter: public SelectMgr_Filter +{ +public: + Standard_EXPORT ModuleBase_ShapeInPlaneFilter(const gp_Pln& thePane): + SelectMgr_Filter(), myPlane(thePane) {} + + Standard_EXPORT virtual Standard_Boolean IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const; + + DEFINE_STANDARD_RTTI(ModuleBase_ShapeInPlaneFilter) +private: + gp_Pln myPlane; +}; + +#endif \ No newline at end of file diff --git a/src/ModuleBase/ModuleBase_WidgetFactory.cpp b/src/ModuleBase/ModuleBase_WidgetFactory.cpp index 057c4d5d3..cbe7503a8 100644 --- a/src/ModuleBase/ModuleBase_WidgetFactory.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFactory.cpp @@ -71,7 +71,7 @@ void ModuleBase_WidgetFactory::createWidget(QWidget* theParent) //Create a widget (doublevalue, groupbox, toolbox, etc. QWidget* aWidget = createWidgetByType(aWdgType, theParent); if (aWidget) { - if (!myWidgetApi->getBooleanAttribute(FEATURE_INTERNAL, false)) { + if (!myWidgetApi->getBooleanAttribute(ATTRIBUTE_INTERNAL, false)) { aWidgetLay->addWidget(aWidget); } else { aWidget->setVisible(false); @@ -121,6 +121,25 @@ QWidget* ModuleBase_WidgetFactory::labelControl(QWidget* theParent) return result; } +void ModuleBase_WidgetFactory::processAttributes() +{ + // register that this attribute in feature is not obligatory for the feature execution + // so, it is not needed for the standard validation mechanism + bool isObligatory = true; + bool isConcealment = false; + if( myWidgetApi ){ + isObligatory = myWidgetApi->getBooleanAttribute(ATTRIBUTE_OBLIGATORY, true); + isConcealment = myWidgetApi->getBooleanAttribute(ATTRIBUTE_CONCEALMENT, false); + } + boost::shared_ptr aSession = ModelAPI_Session::get(); + if (!isObligatory) { + aSession->validators()->registerNotObligatory(myParentId, myWidgetApi->widgetId()); + } + if(isConcealment) { + aSession->validators()->registerConcealment(myParentId, myWidgetApi->widgetId()); + } +} + QWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType, QWidget* theParent) { @@ -174,14 +193,7 @@ QWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType #endif } if (result) { - // register that this attribute in feature is not obligatory for the feature execution - // so, it is not needed for the standard validation mechanism - bool isObligatory = - myWidgetApi ? myWidgetApi->getBooleanAttribute(FEATURE_OBLIGATORY, true) : true; - if (!isObligatory) { - ModelAPI_Session::get()->validators()->registerNotObligatory( - myParentId, myWidgetApi->widgetId()); - } + processAttributes(); } return result; diff --git a/src/ModuleBase/ModuleBase_WidgetFactory.h b/src/ModuleBase/ModuleBase_WidgetFactory.h index fd267d418..43b8208b6 100644 --- a/src/ModuleBase/ModuleBase_WidgetFactory.h +++ b/src/ModuleBase/ModuleBase_WidgetFactory.h @@ -53,6 +53,7 @@ class MODULEBASE_EXPORT ModuleBase_WidgetFactory QString qs(const std::string& theStdString) const; + void processAttributes(); private: Config_WidgetAPI* myWidgetApi; diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index 189b659c4..ed40ee204 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -11,16 +11,15 @@ #include #include -#include #include #include -#include +#include #include #include #include -#include +#include #include #include #include @@ -39,17 +38,21 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen myMainWidget = new QWidget(theParent); QGridLayout* aMainLay = new QGridLayout(myMainWidget); ModuleBase_Tools::adjustMargins(aMainLay); + QLabel* aTypeLabel = new QLabel(tr("Type"), myMainWidget); aMainLay->addWidget(aTypeLabel, 0, 0); + myTypeCombo = new QComboBox(myMainWidget); - std::string aTypes = theData->getProperty("type_choice"); - myShapeTypes = QString::fromStdString(aTypes).split(' '); + // There is no sence to paramerize list of types while we can not parametrize selection mode + QString aTypesStr("Vertices Edges Faces Solids"); + myShapeTypes = aTypesStr.split(' '); myTypeCombo->addItems(myShapeTypes); aMainLay->addWidget(myTypeCombo, 0, 1); + QLabel* aListLabel = new QLabel(tr("Selected objects:"), myMainWidget); aMainLay->addWidget(aListLabel, 1, 0, 1, -1); - myListControl = new QTextEdit(myMainWidget); - myListControl->setReadOnly(true); + + myListControl = new QListWidget(myMainWidget); aMainLay->addWidget(myListControl, 2, 0, 2, -1); aMainLay->setColumnStretch(1, 1); myMainWidget->setLayout(aMainLay); @@ -66,40 +69,56 @@ ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() activateSelection(false); } +//******************************************************************** bool ModuleBase_WidgetMultiSelector::storeValue() const { // A rare case when plugin was not loaded. if(!myFeature) return false; DataPtr aData = myFeature->data(); - AttributeStringPtr aStringAttr = aData->string(attributeID()); - QString aWidgetValue = myListControl->toPlainText(); - aStringAttr->setValue(aWidgetValue.toStdString()); - updateObject(myFeature); - return true; + AttributeSelectionListPtr aSelectionListAttr = + boost::dynamic_pointer_cast(aData->attribute(attributeID())); + + if (aSelectionListAttr && (mySelection.size() > 0)) { + aSelectionListAttr->clear(); + foreach (GeomSelection aSelec, mySelection) { + aSelectionListAttr->append(aSelec.first, aSelec.second); + } + updateObject(myFeature); + return true; + } + return false; } +//******************************************************************** bool ModuleBase_WidgetMultiSelector::restoreValue() { - return false; // A rare case when plugin was not loaded. if(!myFeature) return false; DataPtr aData = myFeature->data(); - AttributeStringPtr aStringAttr = aData->string(attributeID()); - - bool isBlocked = myListControl->blockSignals(true); - myListControl->setText(QString::fromStdString(aStringAttr->value())); - myListControl->blockSignals(isBlocked); - - return true; + AttributeSelectionListPtr aSelectionListAttr = + boost::dynamic_pointer_cast(aData->attribute(attributeID())); + + if (aSelectionListAttr) { + mySelection.clear(); + for (int i = 0; i < aSelectionListAttr->size(); i++) { + AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i); + mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value())); + } + updateSelectionList(); + return true; + } + return false; } +//******************************************************************** QWidget* ModuleBase_WidgetMultiSelector::getControl() const { return myMainWidget; } +//******************************************************************** QList ModuleBase_WidgetMultiSelector::getControls() const { QList result; @@ -118,19 +137,55 @@ bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEve return ModuleBase_ModelWidget::eventFilter(theObj, theEvent); } +//******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionChanged() { ModuleBase_ISelection* aSelection = myWorkshop->selection(); - NCollection_List aSelectedShapes, aFilteredShapes; - aSelection->selectedShapes(aSelectedShapes); - QString aText; - if (!aSelectedShapes.IsEmpty()) { - filterShapes(aSelectedShapes, aFilteredShapes); - aText = QString("Items selected: %1").arg(aFilteredShapes.Size()); + NCollection_List aSelectedShapes; //, aFilteredShapes; + std::list aOwnersList; + aSelection->selectedShapes(aSelectedShapes, aOwnersList); + + mySelection.clear(); + std::list::const_iterator aIt; + NCollection_List::Iterator aShpIt(aSelectedShapes); + GeomShapePtr aShape; + for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) { + ResultPtr aResult = boost::dynamic_pointer_cast(*aIt); + aShape = boost::shared_ptr(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aShpIt.Value())); + mySelection.append(GeomSelection(aResult, aShape)); } - myListControl->setText(aText); + updateSelectionList(); + storeValue(); + emit valuesChanged(); } + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::updateSelectionList() +{ + QString aType; + if (myTypeCombo->currentText().toLower() == "vertices") + aType = "vertex"; + else if (myTypeCombo->currentText().toLower() == "edges") + aType = "edge"; + else if (myTypeCombo->currentText().toLower() == "faces") + aType = "face"; + else if (myTypeCombo->currentText().toLower() == "solids") + aType = "solid"; + + myListControl->clear(); + int i = 1; + foreach (GeomSelection aSel, mySelection) { + QString aName(aSel.first->data()->name().c_str()); + aName += ":" + aType + QString("_%1").arg(i); + myListControl->addItem(aName); + i++; + } +} + + +//******************************************************************** void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List& theShapesToFilter, NCollection_List& theResult) { @@ -147,6 +202,7 @@ void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_ListcurrentText(); diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h index bc184d5e5..c141c87e9 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h @@ -11,15 +11,19 @@ #include #include +#include +#include + #include #include #include #include #include +#include class QWidget; -class QTextEdit; +class QListWidget; class QComboBox; class ModuleBase_IWorkshop; @@ -59,7 +63,9 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Model NCollection_List& theResult); private: - QTextEdit* myListControl; + void updateSelectionList(); + + QListWidget* myListControl; QComboBox* myTypeCombo; QWidget* myMainWidget; @@ -70,6 +76,9 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Model QStringList myShapeTypes; bool myUseSubShapes; bool myIsActive; + + typedef QPair GeomSelection; + QList mySelection; }; #endif /* MODULEBASE_WIDGETFILESELECTOR_H_ */ diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp index 84cfee206..d7518ef60 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp @@ -46,8 +46,7 @@ #include #include -#include -#include +#include typedef QMap ShapeTypes; static ShapeTypes MyShapeTypes; @@ -130,8 +129,11 @@ bool ModuleBase_WidgetShapeSelector::storeValue() const boost::dynamic_pointer_cast(aData->attribute(attributeID())); ResultPtr aBody = boost::dynamic_pointer_cast(mySelectedObject); - if (aBody) + if (aBody) { aSelect->setValue(aBody, myShape); + updateObject(myFeature); + return true; + } } else { boost::shared_ptr aRef = boost::dynamic_pointer_cast(aData->attribute(attributeID())); @@ -140,9 +142,10 @@ bool ModuleBase_WidgetShapeSelector::storeValue() const if (!(aObject && aObject->isSame(mySelectedObject))) { aRef->setValue(mySelectedObject); updateObject(myFeature); + return true; } } - return true; + return false; } //******************************************************************** @@ -190,7 +193,8 @@ void ModuleBase_WidgetShapeSelector::onSelectionChanged() boost::shared_ptr aShape; if (myUseSubShapes) { NCollection_List aShapeList; - myWorkshop->selection()->selectedShapes(aShapeList); + std::list aOwners; + myWorkshop->selection()->selectedShapes(aShapeList, aOwners); if (aShapeList.Extent() > 0) { aShape = boost::shared_ptr(new GeomAPI_Shape()); aShape->setImpl(new TopoDS_Shape(aShapeList.First())); @@ -222,7 +226,6 @@ void ModuleBase_WidgetShapeSelector::setObject(ObjectPtr theObj, boost::shared_p if (!myUseSubShapes) { static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TOHIDE); ModelAPI_EventCreator::get()->sendUpdated(mySelectedObject, anEvent); - Events_Loop::loop()->flush(anEvent); } } updateSelectionName(); diff --git a/src/NewGeom/NewGeom_Module.cpp b/src/NewGeom/NewGeom_Module.cpp index 831144290..5d614069f 100644 --- a/src/NewGeom/NewGeom_Module.cpp +++ b/src/NewGeom/NewGeom_Module.cpp @@ -87,6 +87,9 @@ void NewGeom_Module::initialize(CAM_Application* theApp) LightApp_Module::initialize(theApp); myWorkshop->startApplication(); + LightApp_Application* anApp = dynamic_cast(theApp); + if (anApp) + connect(anApp, SIGNAL(preferenceResetToDefaults()), this, SLOT(onDefaultPreferences())); } //****************************************************** @@ -176,6 +179,17 @@ void NewGeom_Module::onViewManagerAdded(SUIT_ViewManager* theMgr) } } +//****************************************************** +void NewGeom_Module::onDefaultPreferences() +{ + XGUI_Preferences::resetConfig(); + XGUI_Preferences::updateResourcesByConfig(); + + LightApp_Preferences* pref = preferences(); + if (pref) + pref->retrieve(); +} + //****************************************************** NewGeom_OCCSelector* NewGeom_Module::createSelector(SUIT_ViewManager* theMgr) { @@ -326,7 +340,7 @@ void NewGeom_Module::createPreferences() LightApp_Preferences* pref = preferences(); if (!pref) return; - XGUI_Preferences::updateCustomProps(); + XGUI_Preferences::updateConfigByResources(); QString aModName = moduleName(); QtxPreferenceItem* item = pref->findItem(aModName, true ); @@ -348,8 +362,16 @@ void NewGeom_Module::preferencesChanged(const QString& theSection, const QString { SUIT_ResourceMgr* aResMgr = application()->resourceMgr(); QString aVal = aResMgr->stringValue(theSection, theParam); - if (!aVal.isNull()) { - Config_Prop* aProp = Config_PropManager::findProp(theSection.toStdString(), theParam.toStdString()); - aProp->setValue(aVal.toStdString()); + Config_Prop* aProp = Config_PropManager::findProp(theSection.toStdString(), theParam.toStdString()); + std::string aValue = aVal.toStdString(); + if (aValue.empty()) { + aValue = aProp->defaultValue(); + aResMgr->setValue(theSection, theParam, QString(aValue.c_str())); + + LightApp_Preferences* pref = preferences(); + if (pref) + pref->retrieve(); } + aProp->setValue(aValue); + } diff --git a/src/NewGeom/NewGeom_Module.h b/src/NewGeom/NewGeom_Module.h index 9bda5d276..9da3e31af 100644 --- a/src/NewGeom/NewGeom_Module.h +++ b/src/NewGeom/NewGeom_Module.h @@ -85,6 +85,7 @@ Q_OBJECT protected slots: virtual void onViewManagerAdded(SUIT_ViewManager* theMgr); + void onDefaultPreferences(); protected: CAM_DataModel* createDataModel(); diff --git a/src/NewGeom/resources/SalomeApp.xml b/src/NewGeom/resources/SalomeApp.xml index db530bde7..20536e2a6 100644 --- a/src/NewGeom/resources/SalomeApp.xml +++ b/src/NewGeom/resources/SalomeApp.xml @@ -19,6 +19,10 @@ --> +
+ + +
diff --git a/src/PartSet/PartSet_Listener.cpp b/src/PartSet/PartSet_Listener.cpp index 989b66880..24c78b60f 100644 --- a/src/PartSet/PartSet_Listener.cpp +++ b/src/PartSet/PartSet_Listener.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,7 @@ #include #include +#include #ifdef _DEBUG #include @@ -57,22 +59,36 @@ void PartSet_Listener::processEvent(const boost::shared_ptr& the std::set::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end(); for (; anIt != aLast; anIt++) { ObjectPtr aObj = (*anIt); - aDisplayer->deactivate(aObj); - boost::shared_ptr aFeature = - boost::dynamic_pointer_cast(aObj); - if (aFeature && (aFeature->getKind() == "Sketch")) // Activate sketcher for planes selection - myModule->activateFeature(aFeature, false); // If current operation is Sketch then there is no active sketching operation - // and possible the object was created by Redo operatgion - else if (aSketchOp) { + // and possible the object was created by Redo operation + if (aSketchOp) { XGUI_Displayer* aDisplayer = myModule->xWorkshop()->displayer(); // Very possible it is not displayed aDisplayer->display(aObj, false); - std::list aModes = aSketchOp->getSelectionModes(aObj); - myModule->activateInLocalContext(aObj, aModes, false); } } + } else if (aType == EVENT_OBJECT_TO_REDISPLAY) { + PartSet_OperationFeatureCreate* aCreationOp = + dynamic_cast + (myModule->xWorkshop()->operationMgr()->currentOperation()); + if (aCreationOp) { + // Deactivate currently creating objects for selection + XGUI_Displayer* aDisplayer = myModule->xWorkshop()->displayer(); + FeaturePtr aFeature = aCreationOp->feature(); + const std::list& aResults = aFeature->results(); + boost::shared_ptr aUpdMsg = + boost::dynamic_pointer_cast(theMessage); + std::set aFeatures = aUpdMsg->objects(); + std::set::const_iterator aObjIt, aNoObj = aFeatures.cend(); + std::list::const_iterator anIt = aResults.begin(), aLast = aResults.end(); + for (; anIt != aLast; anIt++) { + aObjIt = aFeatures.find(*anIt); + if (aObjIt != aNoObj) { + aDisplayer->deactivate(*aObjIt); + } + } + } } else if (aType == EVENT_OBJECT_DELETED) { boost::shared_ptr aDelMsg = boost::dynamic_pointer_cast(theMessage); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index fcfc9e903..b2f838d1a 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include @@ -35,6 +37,7 @@ #include #include +#include #include #include @@ -46,8 +49,8 @@ #include #include #include +#include -#include #include #include @@ -94,8 +97,6 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) SLOT(onKeyRelease(QKeyEvent*))); connect(myWorkshop->viewer(), SIGNAL(mouseDoubleClick(QMouseEvent*)), this, SLOT(onMouseDoubleClick(QMouseEvent*))); - - myDocumentShapeFilter = new XGUI_ShapeDocumentFilter(aXWshop->displayer()); } PartSet_Module::~PartSet_Module() @@ -143,20 +144,28 @@ void PartSet_Module::onFeatureTriggered() void PartSet_Module::onOperationStarted(ModuleBase_Operation* theOperation) { + XGUI_Workshop* aXWshp = xWorkshop(); + XGUI_Displayer* aDisplayer = aXWshp->displayer(); PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(theOperation); if (aPreviewOp) { - XGUI_Workshop* aXWshp = xWorkshop(); XGUI_PropertyPanel* aPropPanel = aXWshp->propertyPanel(); connect(aPropPanel, SIGNAL(storedPoint2D(ObjectPtr, const std::string&)), this, SLOT(onStorePoint2D(ObjectPtr, const std::string&)), Qt::UniqueConnection); - XGUI_Displayer* aDisplayer = aXWshp->displayer(); - aDisplayer->openLocalContext(); - aDisplayer->deactivateObjectsOutOfContext(); - } else { - Handle(AIS_InteractiveContext) aAIS = xWorkshop()->viewer()->AISContext(); - //TODO (VSV): We have to open Local context because at neutral point filters don't work (bug 25340) - aAIS->AddFilter(myDocumentShapeFilter); + //aDisplayer->deactivateObjectsOutOfContext(); + PartSet_OperationSketch* aSketchOp = dynamic_cast(aPreviewOp); + if (aSketchOp) { + if (aSketchOp->isEditOperation()) { + setSketchingMode(getSketchPlane(aSketchOp->feature())); + } else { + aDisplayer->openLocalContext(); + aDisplayer->activateObjectsOutOfContext(QIntList()); + myPlaneFilter = new StdSelect_FaceFilter(StdSelect_Plane); + aDisplayer->addSelectionFilter(myPlaneFilter); + QIntList aModes = sketchSelectionModes(aPreviewOp->feature()); + aDisplayer->setSelectionModes(aModes); + } + } } } @@ -165,22 +174,39 @@ void PartSet_Module::onOperationStopped(ModuleBase_Operation* theOperation) if (!theOperation) return; XGUI_Workshop* aXWshp = xWorkshop(); + XGUI_Displayer* aDisplayer = aXWshp->displayer(); PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(theOperation); if (aPreviewOp) { XGUI_PropertyPanel* aPropPanel = aXWshp->propertyPanel(); - } else { - // Activate results of current feature for selection - FeaturePtr aFeature = theOperation->feature(); - XGUI_Displayer* aDisplayer = aXWshp->displayer(); - std::list aResults = aFeature->results(); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - aDisplayer->activate(*aIt); - } - Handle(AIS_InteractiveContext) aAIS = xWorkshop()->viewer()->AISContext(); - aAIS->RemoveFilter(myDocumentShapeFilter); - } + PartSet_OperationSketch* aSketchOp = dynamic_cast(aPreviewOp); + if (aSketchOp) { + aDisplayer->closeLocalContexts(); + } else { + PartSet_OperationFeatureCreate* aCreationOp = + dynamic_cast(aPreviewOp); + if (aCreationOp) { + // Activate just created object for selection + FeaturePtr aFeature = aCreationOp->feature(); + QIntList aModes = sketchSelectionModes(aFeature); + const std::list& aResults = aFeature->results(); + std::list::const_iterator anIt, aLast = aResults.end(); + for (anIt = aResults.begin(); anIt != aLast; anIt++) { + aDisplayer->activate(*anIt, aModes); + } + aDisplayer->activate(aFeature, aModes); + } + } + }// else { + // Activate results of current feature for selection + //FeaturePtr aFeature = theOperation->feature(); + //XGUI_Displayer* aDisplayer = aXWshp->displayer(); + //std::list aResults = aFeature->results(); + //std::list::const_iterator aIt; + //for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { + // aDisplayer->activate(*aIt); + //} + //} } void PartSet_Module::onContextMenuCommand(const QString& theId, bool isChecked) @@ -258,11 +284,12 @@ void PartSet_Module::onMouseDoubleClick(QMouseEvent* theEvent) void PartSet_Module::onPlaneSelected(double theX, double theY, double theZ) { - //erasePlanes(); myWorkshop->viewer()->setViewProjection(theX, theY, theZ); - xWorkshop()->actionsMgr()->update(); - - //PartSet_TestOCC::testSelection(myWorkshop); + xWorkshop()->actionsMgr()->update(); + // Set working plane + ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); + FeaturePtr aSketch = anOperation->feature(); + setSketchingMode(getSketchPlane(aSketch)); } void PartSet_Module::onFitAllView() @@ -290,16 +317,16 @@ void PartSet_Module::onRestartOperation(std::string theName, ObjectPtr theObject std::list aSelected = aSelection->getSelected(); std::list aHighlighted = aSelection->getHighlighted(); aSketchOp->initSelection(aSelected, aHighlighted); - } else if (aFeature) { - anOperation->setFeature(aFeature); - //Deactivate result of current feature in order to avoid its selection - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - std::list aResults = aFeature->results(); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - aDisplayer->deactivate(*aIt); - } - } + } //else if (aFeature) { + //anOperation->setFeature(aFeature); + ////Deactivate result of current feature in order to avoid its selection + //XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); + //std::list aResults = aFeature->results(); + //std::list::const_iterator aIt; + //for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { + // aDisplayer->deactivate(*aIt); + //} + //} sendOperation(anOperation); xWorkshop()->actionsMgr()->updateCheckState(); } @@ -313,12 +340,11 @@ void PartSet_Module::onMultiSelectionEnabled(bool theEnabled) void PartSet_Module::onStopSelection(const QList& theFeatures, const bool isStop) { XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - if (!isStop) { - foreach(ObjectPtr aObject, theFeatures) - { - activateFeature(aObject, false); - } - } + //if (!isStop) { + // foreach(ObjectPtr aObject, theFeatures) { + // activateFeature(aObject); + // } + //} aDisplayer->stopSelection(theFeatures, isStop, false); ModuleBase_IViewer* aViewer = myWorkshop->viewer(); @@ -334,11 +360,24 @@ void PartSet_Module::onSetSelection(const QList& theFeatures) aDisplayer->updateViewer(); } -void PartSet_Module::onCloseLocalContext() +void PartSet_Module::setSketchingMode(const gp_Pln& thePln) { XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - aDisplayer->deactivateObjectsOutOfContext(); - aDisplayer->closeLocalContexts(); + if (!myPlaneFilter.IsNull()) { + aDisplayer->removeSelectionFilter(myPlaneFilter); + myPlaneFilter.Nullify(); + } + QIntList aModes; + // Clear standard selection modes + aDisplayer->setSelectionModes(aModes); + aDisplayer->openLocalContext(); + // Get default selection modes + aModes = sketchSelectionModes(ObjectPtr()); + aDisplayer->activateObjectsOutOfContext(aModes); + + // Set filter + mySketchFilter = new ModuleBase_ShapeInPlaneFilter(thePln); + aDisplayer->addSelectionFilter(mySketchFilter); } void PartSet_Module::onFeatureConstructed(ObjectPtr theFeature, int theMode) @@ -349,21 +388,19 @@ void PartSet_Module::onFeatureConstructed(ObjectPtr theFeature, int theMode) if (aPrevOp) { std::list aList = aPrevOp->subFeatures(); XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - std::list aModes = aPrevOp->getSelectionModes(aPrevOp->feature()); + QIntList aModes = sketchSelectionModes(aPrevOp->feature()); std::list::iterator aSFIt; for (aSFIt = aList.begin(); aSFIt != aList.end(); ++aSFIt) { std::list aResults = (*aSFIt)->results(); std::list::iterator aIt; for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - if (isDisplay) - activateInLocalContext((*aIt), aModes, false); - else + if (!isDisplay) aDisplayer->erase((*aIt), false); } if (!isDisplay) aDisplayer->erase((*aSFIt), false); } - aDisplayer->deactivateObjectsOutOfContext(); + //aDisplayer->deactivateObjectsOutOfContext(); } if (isDisplay) ModelAPI_EventCreator::get()->sendUpdated( @@ -379,7 +416,7 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI anOperation = new PartSet_OperationSketch(theCmdId.c_str(), this); } else { ModuleBase_Operation* aCurOperation = myWorkshop->currentOperation(); - FeaturePtr aSketch; + CompositeFeaturePtr aSketch; PartSet_OperationSketchBase* aPrevOp = dynamic_cast(aCurOperation); if (aPrevOp) { aSketch = aPrevOp->sketch(); @@ -424,8 +461,6 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI connect(aPreviewOp, SIGNAL(setSelection(const QList&)), this, SLOT(onSetSelection(const QList&))); - connect(aPreviewOp, SIGNAL(closeLocalContext()), this, SLOT(onCloseLocalContext())); - PartSet_OperationSketch* aSketchOp = dynamic_cast(aPreviewOp); if (aSketchOp) { connect(aSketchOp, SIGNAL(planeSelected(double, double, double)), this, @@ -437,34 +472,6 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI return anOperation; } -//void PartSet_Module::sendOperation(ModuleBase_Operation* theOperation) -//{ -// static Events_ID aModuleEvent = Events_Loop::eventByName(EVENT_OPERATION_LAUNCHED); -// boost::shared_ptr aMessage = -// boost::shared_ptr(new Config_PointerMessage(aModuleEvent, this)); -// aMessage->setPointer(theOperation); -// Events_Loop::loop()->send(aMessage); -//} - -void PartSet_Module::activateFeature(ObjectPtr theFeature, const bool isUpdateViewer) -{ - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(anOperation); - if (aPreviewOp) { - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - std::list aModes = aPreviewOp->getSelectionModes(theFeature); - activateInLocalContext(theFeature, aModes, isUpdateViewer); - - // If this is a Sketcher then activate objects (planar faces) outside of context - PartSet_OperationSketch* aSketchOp = dynamic_cast(aPreviewOp); - if (aSketchOp) { - Handle(StdSelect_FaceFilter) aFilter = new StdSelect_FaceFilter(StdSelect_Plane); - aDisplayer->activateObjectsOutOfContext(aModes, aFilter); - } else { - aDisplayer->deactivateObjectsOutOfContext(); - } - } -} void PartSet_Module::updateCurrentPreview(const std::string& theCmdId) { @@ -488,7 +495,6 @@ void PartSet_Module::updateCurrentPreview(const std::string& theCmdId) aDisplayer->erase(*aIt, false); std::list aList = aPreviewOp->subFeatures(); - std::list aModes = aPreviewOp->getSelectionModes(aPreviewOp->feature()); std::list::const_iterator anIt = aList.begin(), aLast = aList.end(); for (; anIt != aLast; anIt++) { @@ -500,10 +506,10 @@ void PartSet_Module::updateCurrentPreview(const std::string& theCmdId) std::list::const_iterator aRIt; for (aRIt = aResults.cbegin(); aRIt != aResults.cend(); ++aRIt) { aDisplayer->display((*aRIt), false); - activateInLocalContext((*aRIt), aModes, false); + aDisplayer->activate((*aRIt), sketchSelectionModes((*aRIt))); } aDisplayer->display(aSPFeature, false); - activateInLocalContext(aSPFeature, aModes, false); + aDisplayer->activate(aSPFeature, sketchSelectionModes(aSPFeature)); } aDisplayer->updateViewer(); } @@ -567,36 +573,35 @@ XGUI_Workshop* PartSet_Module::xWorkshop() const } -void PartSet_Module::activateInLocalContext(ObjectPtr theResult, const std::list& theModes, - const bool isUpdateViewer) +QIntList PartSet_Module::sketchSelectionModes(ObjectPtr theFeature) { - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - Handle(AIS_InteractiveContext) aContext = xWorkshop()->viewer()->AISContext(); - if (aContext.IsNull()) - return; - // Open local context if there is no one - if (!aContext->HasOpenedContext()) { - aContext->ClearCurrents(false); - //aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/); - aContext->OpenLocalContext(); - aContext->NotUseDisplayedObjects(); - } - // display or redisplay presentation - boost::shared_ptr anAIS = aDisplayer->getAISObject(theResult); - // Activate selection of objects from prs - if (anAIS) { - Handle(AIS_InteractiveObject) aAISObj = anAIS->impl(); - aContext->ClearSelected(false); // ToCheck - //aContext->upClearSelected(false); // ToCheck - aContext->Load(aAISObj, -1, true/*allow decomposition*/); - aContext->Deactivate(aAISObj); - - std::list::const_iterator anIt = theModes.begin(), aLast = theModes.end(); - for (; anIt != aLast; anIt++) { - aContext->Activate(aAISObj, (*anIt)); + QIntList aModes; + FeaturePtr aFeature = boost::dynamic_pointer_cast(theFeature); + if (aFeature) { + if (aFeature->getKind() == SketchPlugin_Sketch::ID()) { + aModes.append(TopAbs_FACE); + return aModes; + } else if (PartSet_Tools::isConstraintFeature(aFeature->getKind())) { + aModes.append(AIS_DSM_Text); + aModes.append(AIS_DSM_Line); + return aModes; } - } + } + aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_VERTEX)); + aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_EDGE)); + return aModes; +} - if (isUpdateViewer) - aDisplayer->updateViewer(); + +gp_Pln PartSet_Module::getSketchPlane(FeaturePtr theSketch) const +{ + DataPtr aData = theSketch->data(); + boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + boost::shared_ptr aNorm = boost::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); + gp_Pnt aOrig(anOrigin->x(), anOrigin->y(), anOrigin->z()); + gp_Dir aDir(aNorm->x(), aNorm->y(), aNorm->z()); + return gp_Pln(aOrig, aDir); } + diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index 44322b359..79379ffc4 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -5,9 +5,10 @@ #include #include +#include #include -#include #include +#include #include #include @@ -45,11 +46,6 @@ Q_OBJECT /// \param theCmdId the operation name //virtual void launchOperation(const QString& theCmdId); - /// Activates the feature in the displayer - /// \param theFeature the feature instance to be displayed - /// \param isUpdateViewer the flag whether the viewer should be updated - void activateFeature(ObjectPtr theFeature, const bool isUpdateViewer); - /// Updates current operation preview, if it has it. /// \param theCmdId the operation name void updateCurrentPreview(const std::string& theCmdId); @@ -61,13 +57,9 @@ Q_OBJECT XGUI_Workshop* xWorkshop() const; - /// Display the shape and activate selection of sub-shapes - /// \param theFeature a feature instance - /// \param theShape a shape - /// \param theMode a list of local selection modes - /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly - void activateInLocalContext(ObjectPtr theFeature, const std::list& theModes, - const bool isUpdateViewer = true); + + /// Returns list of selection modes for the given object for sketch operation + static QIntList sketchSelectionModes(ObjectPtr theFeature); public slots: void onFeatureTriggered(); @@ -123,8 +115,9 @@ Q_OBJECT /// \param theFeatures a list of features to be selected void onSetSelection(const QList& theFeatures); - /// SLOT, to close the viewer local context - void onCloseLocalContext(); + /// SLOT, Defines Sketch editing mode + /// \param thePln - plane of current sketch + void setSketchingMode(const gp_Pln& thePln); /// SLOT, to visualize the feature in another local context mode /// \param theFeature the feature to be put in another local context mode @@ -148,14 +141,16 @@ Q_OBJECT //! Edits the feature void editFeature(FeaturePtr theFeature); + gp_Pln getSketchPlane(FeaturePtr theSketch) const; + private: //XGUI_Workshop* myWorkshop; PartSet_Listener* myListener; std::map myFeaturesInFiles; - /// A filter which provides selection within a current document or whole PartSet - Handle(XGUI_ShapeDocumentFilter) myDocumentShapeFilter; + Handle(StdSelect_FaceFilter) myPlaneFilter; + Handle(ModuleBase_ShapeInPlaneFilter) mySketchFilter; }; #endif diff --git a/src/PartSet/PartSet_OperationFeatureBase.cpp b/src/PartSet/PartSet_OperationFeatureBase.cpp index 3e0c412ec..9955fa5f0 100644 --- a/src/PartSet/PartSet_OperationFeatureBase.cpp +++ b/src/PartSet/PartSet_OperationFeatureBase.cpp @@ -44,7 +44,7 @@ using namespace std; PartSet_OperationFeatureBase::PartSet_OperationFeatureBase(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationSketchBase(theId, theParent), mySketch(theFeature) { @@ -54,7 +54,7 @@ PartSet_OperationFeatureBase::~PartSet_OperationFeatureBase() { } -FeaturePtr PartSet_OperationFeatureBase::sketch() const +CompositeFeaturePtr PartSet_OperationFeatureBase::sketch() const { return mySketch; } diff --git a/src/PartSet/PartSet_OperationFeatureBase.h b/src/PartSet/PartSet_OperationFeatureBase.h index baef75f9f..a9651e6f8 100644 --- a/src/PartSet/PartSet_OperationFeatureBase.h +++ b/src/PartSet/PartSet_OperationFeatureBase.h @@ -29,13 +29,13 @@ Q_OBJECT /// \param theId the feature identifier /// \param theParent the operation parent /// \param theSketch the parent feature - PartSet_OperationFeatureBase(const QString& theId, QObject* theParent, FeaturePtr theSketch); + PartSet_OperationFeatureBase(const QString& theId, QObject* theParent, CompositeFeaturePtr theSketch); /// Destructor virtual ~PartSet_OperationFeatureBase(); /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const; + virtual CompositeFeaturePtr sketch() const; /// Gives the current selected objects to be processed by the operation /// \param theEvent the mouse event @@ -56,7 +56,7 @@ Q_OBJECT //bool setWidgetValue(ObjectPtr theFeature, double theX, double theY); protected: - FeaturePtr mySketch; ///< the sketch of the feature + CompositeFeaturePtr mySketch; ///< the sketch of the feature }; #endif diff --git a/src/PartSet/PartSet_OperationFeatureCreate.cpp b/src/PartSet/PartSet_OperationFeatureCreate.cpp index 8f4a6930a..0bc2d9238 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.cpp +++ b/src/PartSet/PartSet_OperationFeatureCreate.cpp @@ -46,7 +46,7 @@ using namespace std; PartSet_OperationFeatureCreate::PartSet_OperationFeatureCreate(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationFeatureBase(theId, theParent, theFeature) { } @@ -77,14 +77,6 @@ bool PartSet_OperationFeatureCreate::canBeCommitted() const return false; } -std::list PartSet_OperationFeatureCreate::getSelectionModes(ObjectPtr theFeature) const -{ - std::list aModes; - if (theFeature != feature()) - aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature); - return aModes; -} - void PartSet_OperationFeatureCreate::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView) { double aX, anY; @@ -184,15 +176,10 @@ void PartSet_OperationFeatureCreate::afterCommitOperation() emit featureConstructed(feature(), FM_Deactivation); } -FeaturePtr PartSet_OperationFeatureCreate::createFeature(const bool theFlushMessage) +FeaturePtr PartSet_OperationFeatureCreate::createFeature(const bool theFlushMessage, + CompositeFeaturePtr theCompositeFeature) { - FeaturePtr aNewFeature = ModuleBase_Operation::createFeature(false); - if (sketch()) { - boost::shared_ptr aFeature = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(sketch()); - - aFeature->addSub(aNewFeature); - } + FeaturePtr aNewFeature = ModuleBase_Operation::createFeature(false, sketch()); if (theFlushMessage) flushCreated(); diff --git a/src/PartSet/PartSet_OperationFeatureCreate.h b/src/PartSet/PartSet_OperationFeatureCreate.h index fcd92be95..b13b8ece5 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.h +++ b/src/PartSet/PartSet_OperationFeatureCreate.h @@ -34,15 +34,11 @@ Q_OBJECT /// \param theId the feature identifier /// \param theParent the operation parent /// \param theSketch the parent feature - PartSet_OperationFeatureCreate(const QString& theId, QObject* theParent, FeaturePtr theSketch); + PartSet_OperationFeatureCreate( + const QString& theId, QObject* theParent, CompositeFeaturePtr theSketch); /// Destructor virtual ~PartSet_OperationFeatureCreate(); - /// Returns the operation local selection mode - /// \param theFeature the feature object to get the selection mode - /// \return the selection mode - virtual std::list getSelectionModes(ObjectPtr theFeature) const; - /// Gives the current mouse point in the viewer /// \param thePoint a point clicked in the viewer /// \param theEvent the mouse event @@ -90,7 +86,8 @@ Q_OBJECT /// the sketch feature /// \param theFlushMessage the flag whether the create message should be flushed /// \returns the created feature - virtual FeaturePtr createFeature(const bool theFlushMessage = true); + virtual FeaturePtr createFeature(const bool theFlushMessage = true, + CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr()); /// Verifies whether this operator can be commited. /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled diff --git a/src/PartSet/PartSet_OperationFeatureEdit.cpp b/src/PartSet/PartSet_OperationFeatureEdit.cpp index 1e0932280..16e2b4437 100644 --- a/src/PartSet/PartSet_OperationFeatureEdit.cpp +++ b/src/PartSet/PartSet_OperationFeatureEdit.cpp @@ -40,7 +40,7 @@ using namespace std; PartSet_OperationFeatureEdit::PartSet_OperationFeatureEdit(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationFeatureBase(theId, theParent, theFeature), myIsBlockedSelection(false) { @@ -73,20 +73,21 @@ void PartSet_OperationFeatureEdit::mousePressed(QMouseEvent* theEvent, Handle(V3 if (commit()) { emit featureConstructed(feature(), FM_Deactivation); - bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); - if (aHasShift && !theHighlighted.empty()) { - QList aSelected; - std::list::const_iterator aIt; - for (aIt = theSelected.cbegin(); aIt != theSelected.cend(); ++aIt) - aSelected.append((*aIt).object()); + //bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); + //if (aHasShift && !theHighlighted.empty()) { + // QList aSelected; + // std::list::const_iterator aIt; + // for (aIt = theSelected.cbegin(); aIt != theSelected.cend(); ++aIt) + // aSelected.append((*aIt).object()); /*for (aIt = theHighlighted.cbegin(); aIt != theHighlighted.cend(); ++aIt) { if (!aSelected.contains((*aIt).object())) aSelected.append((*aIt).object()); }*/ //aSelected.push_back(feature()); //aSelected.push_back(theHighlighted.front().object()); - emit setSelection(aSelected); - } else if (aFeature) { + //emit setSelection(aSelected); + //} else + if (aFeature) { restartOperation(PartSet_OperationFeatureEdit::Type(), aFeature); } } @@ -113,9 +114,12 @@ void PartSet_OperationFeatureEdit::mouseMoved(QMouseEvent* theEvent, Handle(V3d_ boost::shared_ptr aSketchFeature = boost::dynamic_pointer_cast< SketchPlugin_Feature>(feature()); - aSketchFeature->move(aDeltaX, aDeltaY); - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY); - ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent); + // MPV: added condition because it could be external edge of some object, not sketch + if (aSketchFeature && aSketchFeature->sketch() == sketch().get()) { + aSketchFeature->move(aDeltaX, aDeltaY); + static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent); + } } sendFeatures(); @@ -196,7 +200,8 @@ void PartSet_OperationFeatureEdit::blockSelection(bool isBlocked, const bool isR } } -FeaturePtr PartSet_OperationFeatureEdit::createFeature(const bool /*theFlushMessage*/) +FeaturePtr PartSet_OperationFeatureEdit::createFeature(const bool theFlushMessage, + CompositeFeaturePtr theCompositeFeature) { // do nothing in order to do not create a new feature return FeaturePtr(); diff --git a/src/PartSet/PartSet_OperationFeatureEdit.h b/src/PartSet/PartSet_OperationFeatureEdit.h index 67223fce6..1b741a56a 100644 --- a/src/PartSet/PartSet_OperationFeatureEdit.h +++ b/src/PartSet/PartSet_OperationFeatureEdit.h @@ -66,7 +66,7 @@ Q_OBJECT /// \param theId the feature identifier /// \param theParent the operation parent /// \param theFeature the parent feature - PartSet_OperationFeatureEdit(const QString& theId, QObject* theParent, FeaturePtr theFeature); + PartSet_OperationFeatureEdit(const QString& theId, QObject* theParent, CompositeFeaturePtr theFeature); /// Destructor virtual ~PartSet_OperationFeatureEdit(); @@ -114,7 +114,8 @@ Q_OBJECT /// Returns NULL feature. This is an operation of edition, not creation. /// \param theFlushMessage the flag whether the create message should be flushed /// \returns the created feature - virtual FeaturePtr createFeature(const bool theFlushMessage = true); + virtual FeaturePtr createFeature(const bool theFlushMessage = true, + CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr()); protected: /// Emits a signal about the selection blocking. Emits a signal to change the selection. diff --git a/src/PartSet/PartSet_OperationFeatureEditMulti.cpp b/src/PartSet/PartSet_OperationFeatureEditMulti.cpp index b36e16ca2..7be21c613 100644 --- a/src/PartSet/PartSet_OperationFeatureEditMulti.cpp +++ b/src/PartSet/PartSet_OperationFeatureEditMulti.cpp @@ -24,17 +24,16 @@ #include +#include #ifdef _DEBUG #include #endif -#include - -using namespace std; +//using namespace std; PartSet_OperationFeatureEditMulti::PartSet_OperationFeatureEditMulti(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationSketchBase(theId, theParent), mySketch(theFeature), myIsBlockedSelection(false) @@ -80,23 +79,22 @@ void PartSet_OperationFeatureEditMulti::initSelection( //} else myFeatures = theSelected; // add highlighted elements if they are not selected - std::list::const_iterator anIt; - for (anIt = theHighlighted.cbegin(); anIt != theHighlighted.cend(); ++anIt) { + std::list::const_iterator anIt = theHighlighted.cbegin(); + for ( ; anIt != theHighlighted.cend(); ++anIt) { if (!isContains(myFeatures, (*anIt))) myFeatures.push_back(*anIt); } // Remove current feature if it is in the list (it will be moved as main feature) - FeaturePtr aFea = feature(); - for (anIt = myFeatures.cbegin(); anIt != myFeatures.cend(); ++anIt) { - FeaturePtr aF = ModelAPI_Feature::feature((*anIt).object()); - if (ModelAPI_Feature::feature((*anIt).object()) == feature()) { - myFeatures.erase(anIt); + std::list::iterator anEraseIt = myFeatures.begin(); + for ( ; anEraseIt != myFeatures.end(); ++anEraseIt) { + if (ModelAPI_Feature::feature((*anEraseIt).object()) == feature()) { + myFeatures.erase(anEraseIt); break; } } } -FeaturePtr PartSet_OperationFeatureEditMulti::sketch() const +CompositeFeaturePtr PartSet_OperationFeatureEditMulti::sketch() const { return mySketch; } diff --git a/src/PartSet/PartSet_OperationFeatureEditMulti.h b/src/PartSet/PartSet_OperationFeatureEditMulti.h index b34b638ad..1008f3deb 100644 --- a/src/PartSet/PartSet_OperationFeatureEditMulti.h +++ b/src/PartSet/PartSet_OperationFeatureEditMulti.h @@ -10,6 +10,8 @@ #include #include +#include + class QMouseEvent; /*! @@ -66,7 +68,7 @@ Q_OBJECT /// \param theParent the operation parent /// \param theFeature the parent feature PartSet_OperationFeatureEditMulti(const QString& theId, QObject* theParent, - FeaturePtr theFeature); + CompositeFeaturePtr theFeature); /// Destructor virtual ~PartSet_OperationFeatureEditMulti(); @@ -78,7 +80,7 @@ Q_OBJECT /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const; + virtual CompositeFeaturePtr sketch() const; /// Processes the mouse pressed in the point /// \param theEvent the mouse event @@ -122,7 +124,7 @@ Q_OBJECT void sendFeatures(); private: - FeaturePtr mySketch; ///< the sketch feature + CompositeFeaturePtr mySketch; ///< the sketch feature std::list myFeatures; ///< the features to apply the edit operation Point myCurPoint; ///< the current 3D point clicked or moved bool myIsBlockedSelection; ///< the state of the last state of selection blocked signal diff --git a/src/PartSet/PartSet_OperationSketch.cpp b/src/PartSet/PartSet_OperationSketch.cpp index 2c8426c04..6deab5b28 100644 --- a/src/PartSet/PartSet_OperationSketch.cpp +++ b/src/PartSet/PartSet_OperationSketch.cpp @@ -48,20 +48,9 @@ PartSet_OperationSketch::~PartSet_OperationSketch() { } -std::list PartSet_OperationSketch::getSelectionModes(ObjectPtr theFeature) const +CompositeFeaturePtr PartSet_OperationSketch::sketch() const { - std::list aModes; - if (!hasSketchPlane()) - aModes.push_back(TopAbs_FACE); - else - aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature); - - return aModes; -} - -FeaturePtr PartSet_OperationSketch::sketch() const -{ - return feature(); + return boost::dynamic_pointer_cast(feature()); } void PartSet_OperationSketch::mousePressed(QMouseEvent* theEvent, Handle_V3d_View theView, @@ -154,7 +143,6 @@ void PartSet_OperationSketch::stopOperation() { PartSet_OperationSketchBase::stopOperation(); emit featureConstructed(feature(), FM_Hide); - emit closeLocalContext(); } void PartSet_OperationSketch::afterCommitOperation() @@ -243,7 +231,6 @@ void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape) flushUpdated(); emit featureConstructed(feature(), FM_Hide); - emit closeLocalContext(); emit planeSelected(aDir->x(), aDir->y(), aDir->z()); } diff --git a/src/PartSet/PartSet_OperationSketch.h b/src/PartSet/PartSet_OperationSketch.h index f885503e3..d3ede8b3d 100644 --- a/src/PartSet/PartSet_OperationSketch.h +++ b/src/PartSet/PartSet_OperationSketch.h @@ -41,14 +41,9 @@ Q_OBJECT virtual bool isGranted(ModuleBase_Operation* theOperation) const; - /// Returns the operation local selection mode - /// \param theFeature the feature object to get the selection mode - /// \return the selection mode - virtual std::list getSelectionModes(ObjectPtr theFeature) const; - /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const; + virtual CompositeFeaturePtr sketch() const; /// Processes the mouse pressed in the point /// \param theEvent the mouse event diff --git a/src/PartSet/PartSet_OperationSketchBase.cpp b/src/PartSet/PartSet_OperationSketchBase.cpp index 2ce61d8ef..d8cd8ec7e 100644 --- a/src/PartSet/PartSet_OperationSketchBase.cpp +++ b/src/PartSet/PartSet_OperationSketchBase.cpp @@ -52,20 +52,6 @@ std::list PartSet_OperationSketchBase::subFeatures() const return std::list(); } -std::list PartSet_OperationSketchBase::getSelectionModes(ObjectPtr theFeature) const -{ - //TODO: Define position of selection modes definition - std::list aModes; - FeaturePtr aFeature = boost::dynamic_pointer_cast(theFeature); - if (aFeature && PartSet_Tools::isConstraintFeature(aFeature->getKind())) { - aModes.push_back(AIS_DSM_Text); - aModes.push_back(AIS_DSM_Line); - } else { - aModes.push_back(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_VERTEX)); - aModes.push_back(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_EDGE)); - } - return aModes; -} FeaturePtr PartSet_OperationSketchBase::createFeature(const bool theFlushMessage) { ModuleBase_Operation::createFeature(theFlushMessage); diff --git a/src/PartSet/PartSet_OperationSketchBase.h b/src/PartSet/PartSet_OperationSketchBase.h index 25f714830..c7d639348 100644 --- a/src/PartSet/PartSet_OperationSketchBase.h +++ b/src/PartSet/PartSet_OperationSketchBase.h @@ -60,14 +60,9 @@ Q_OBJECT /// \return the list of subfeatures virtual std::list subFeatures() const; - /// Returns the operation local selection mode - /// \param theFeature the feature object to get the selection mode - /// \return the selection mode - virtual std::list getSelectionModes(ObjectPtr theFeature) const; - /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const = 0; + virtual CompositeFeaturePtr sketch() const = 0; /// Processes the mouse pressed in the point /// \param theEvent the mouse event @@ -139,9 +134,6 @@ signals: /// \param theFeatures a list of features to be disabled void setSelection(const QList& theFeatures); - /// signal to close the operation local context if it is opened - void closeLocalContext(); - protected: /// Creates an operation new feature /// In addition to the default realization it appends the created line feature to diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index ea47cde21..892f610a0 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -235,17 +235,16 @@ FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theA return aFeature; } -void PartSet_Tools::createConstraint(FeaturePtr theSketch, +void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch, boost::shared_ptr thePoint1, boost::shared_ptr thePoint2) { - boost::shared_ptr aDoc = document(); - FeaturePtr aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID()); - + FeaturePtr aFeature; if (theSketch) { - boost::shared_ptr aSketch = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(theSketch); - aSketch->addSub(aFeature); + aFeature = theSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + } else { + boost::shared_ptr aDoc = document(); + aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID()); } boost::shared_ptr aData = aFeature->data(); @@ -262,7 +261,7 @@ void PartSet_Tools::createConstraint(FeaturePtr theSketch, aFeature->execute(); } -void PartSet_Tools::setConstraints(FeaturePtr theSketch, FeaturePtr theFeature, +void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, const std::string& theAttribute, double theClickedX, double theClickedY) { @@ -302,7 +301,7 @@ void PartSet_Tools::setConstraints(FeaturePtr theSketch, FeaturePtr theFeature, } } -boost::shared_ptr PartSet_Tools::sketchPlane(FeaturePtr theSketch) +boost::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) { boost::shared_ptr aPlane; double aA, aB, aC, aD; @@ -322,7 +321,7 @@ boost::shared_ptr PartSet_Tools::sketchPlane(FeaturePtr theSketch) } boost::shared_ptr PartSet_Tools::point3D(boost::shared_ptr thePoint2D, - FeaturePtr theSketch) + CompositeFeaturePtr theSketch) { boost::shared_ptr aPoint; if (!theSketch || !thePoint2D) diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index d1b5b4d5c..160814747 100644 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -11,7 +11,7 @@ #include -#include +#include #include @@ -97,7 +97,7 @@ class PARTSET_EXPORT PartSet_Tools /// Creates a constraint on two points /// \param thePoint1 the first point /// \param thePoint1 the second point - static void createConstraint(FeaturePtr theSketch, + static void createConstraint(CompositeFeaturePtr theSketch, boost::shared_ptr thePoint1, boost::shared_ptr thePoint2); @@ -107,21 +107,21 @@ class PARTSET_EXPORT PartSet_Tools /// \param theAttribute a name of the requried attribute attribute /// \param theClickedX the horizontal coordnate of the point /// \param theClickedY the vertical coordnate of the point - static void setConstraints(FeaturePtr theSketch, FeaturePtr theFeature, + static void setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, const std::string& theAttribute, double theClickedX, double theClickedY); /// Create a sketch plane instance /// \param theSketch a sketch feature /// \return API object of geom plane - static boost::shared_ptr sketchPlane(FeaturePtr theSketch); + static boost::shared_ptr sketchPlane(CompositeFeaturePtr theSketch); /// Create a point 3D on a basis of point 2D and sketch feature /// \param thePoint2D a point on a sketch /// \param theSketch a sketch feature /// \return API object of point 3D static boost::shared_ptr point3D(boost::shared_ptr thePoint2D, - FeaturePtr theSketch); + CompositeFeaturePtr theSketch); /// Check whether there is a constraint with the feature kind given /// \param theKind a feature kind /// \return the boolean value diff --git a/src/PartSet/PartSet_icons.qrc b/src/PartSet/PartSet_icons.qrc index 63e9b6e5e..d0985d40c 100644 --- a/src/PartSet/PartSet_icons.qrc +++ b/src/PartSet/PartSet_icons.qrc @@ -26,5 +26,6 @@ icons/distance.png icons/radius_constr.png icons/shape_group.png + icons/fixed.png diff --git a/src/PartSet/icons/fixed.png b/src/PartSet/icons/fixed.png new file mode 100644 index 000000000..0a645320c Binary files /dev/null and b/src/PartSet/icons/fixed.png differ diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 21e616aef..ec9d227de 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -6,6 +6,8 @@ #include "SketchPlugin_Sketch.h" #include #include +#include +#include #include #include @@ -24,9 +26,11 @@ SketchPlugin_Arc::SketchPlugin_Arc() void SketchPlugin_Arc::initAttributes() { - data()->addAttribute(SketchPlugin_Arc::CENTER_ID(), GeomDataAPI_Point2D::type()); - data()->addAttribute(SketchPlugin_Arc::START_ID(), GeomDataAPI_Point2D::type()); - data()->addAttribute(SketchPlugin_Arc::END_ID(), GeomDataAPI_Point2D::type()); + data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type()); + data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type()); + data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type()); + data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID()); } void SketchPlugin_Arc::execute() @@ -138,3 +142,7 @@ double SketchPlugin_Arc::distanceToPoint(const boost::shared_ptr& return aDelta; } + +bool SketchPlugin_Arc::isFixed() { + return data()->selection(EXTERNAL_ID())->context(); +} diff --git a/src/SketchPlugin/SketchPlugin_Arc.h b/src/SketchPlugin/SketchPlugin_Arc.h index 00ada99b0..3ee2ba8e7 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.h +++ b/src/SketchPlugin/SketchPlugin_Arc.h @@ -50,6 +50,9 @@ class SketchPlugin_Arc : public SketchPlugin_Feature //, public GeomAPI_IPresen return MY_KIND; } + /// Returns true is sketch element is under the rigid constraint + SKETCHPLUGIN_EXPORT virtual bool isFixed(); + /// Creates an arc-shape SKETCHPLUGIN_EXPORT virtual void execute(); diff --git a/src/SketchPlugin/SketchPlugin_Circle.cpp b/src/SketchPlugin/SketchPlugin_Circle.cpp index 635214f42..4828a0f7b 100644 --- a/src/SketchPlugin/SketchPlugin_Circle.cpp +++ b/src/SketchPlugin/SketchPlugin_Circle.cpp @@ -6,6 +6,8 @@ #include "SketchPlugin_Sketch.h" #include #include +#include +#include #include #include @@ -24,6 +26,8 @@ void SketchPlugin_Circle::initAttributes() { data()->addAttribute(SketchPlugin_Circle::CENTER_ID(), GeomDataAPI_Point2D::type()); data()->addAttribute(SketchPlugin_Circle::RADIUS_ID(), ModelAPI_AttributeDouble::type()); + data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID()); } void SketchPlugin_Circle::execute() @@ -98,3 +102,7 @@ double SketchPlugin_Circle::distanceToPoint(const boost::shared_ptrpnt()->distance(thePoint); } + +bool SketchPlugin_Circle::isFixed() { + return data()->selection(EXTERNAL_ID())->context(); +} diff --git a/src/SketchPlugin/SketchPlugin_Circle.h b/src/SketchPlugin/SketchPlugin_Circle.h index c489f1014..11311dcb0 100644 --- a/src/SketchPlugin/SketchPlugin_Circle.h +++ b/src/SketchPlugin/SketchPlugin_Circle.h @@ -45,6 +45,9 @@ class SketchPlugin_Circle : public SketchPlugin_Feature //, public GeomAPI_IPre return MY_KIND; } + /// Returns true is sketch element is under the rigid constraint + SKETCHPLUGIN_EXPORT virtual bool isFixed(); + /// Creates a new part document if needed SKETCHPLUGIN_EXPORT virtual void execute(); diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp b/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp index b1cd1708b..c9763327e 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp @@ -4,6 +4,8 @@ #include "SketchPlugin_ConstraintRigid.h" +#include + SketchPlugin_ConstraintRigid::SketchPlugin_ConstraintRigid() { } @@ -16,3 +18,37 @@ void SketchPlugin_ConstraintRigid::initAttributes() void SketchPlugin_ConstraintRigid::execute() { } + +AISObjectPtr SketchPlugin_ConstraintRigid::getAISObject(AISObjectPtr thePrevious) +{ + if (!sketch()) + return thePrevious; + + boost::shared_ptr aData = data(); + boost::shared_ptr anAttr = boost::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); + if (!anAttr || !anAttr->isObject()) + return thePrevious; + + boost::shared_ptr aConst = + boost::dynamic_pointer_cast(anAttr->object()); + if (!aConst) + return thePrevious; + + boost::shared_ptr aShape; + aShape = aConst->shape(); + + AISObjectPtr anAIS = thePrevious; + if (!anAIS) + anAIS = AISObjectPtr(new GeomAPI_AISObject); + + boost::shared_ptr aPlane = sketch()->plane(); + anAIS->createFixed(aShape, aPlane); + + // Set color from preferences + //std::vector aRGB = Config_PropManager::color("Visualization", "perpendicular_color", + // PERPENDICULAR_COLOR); + //anAIS->setColor(aRGB[0], aRGB[1], aRGB[2]); + + return anAIS; +} \ No newline at end of file diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRigid.h b/src/SketchPlugin/SketchPlugin_ConstraintRigid.h index dd66a6f63..8816ea4b6 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintRigid.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintRigid.h @@ -33,6 +33,9 @@ class SketchPlugin_ConstraintRigid : public SketchPlugin_ConstraintBase return MY_KIND; } + /// Returns the AIS preview + SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious); + /// \brief Creates a new part document if needed SKETCHPLUGIN_EXPORT virtual void execute(); diff --git a/src/SketchPlugin/SketchPlugin_Feature.cpp b/src/SketchPlugin/SketchPlugin_Feature.cpp index c3c800bd9..da25c0999 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.cpp +++ b/src/SketchPlugin/SketchPlugin_Feature.cpp @@ -11,14 +11,16 @@ SketchPlugin_Feature::SketchPlugin_Feature() mySketch = 0; } +/* SketchPlugin_Sketch* SketchPlugin_Feature::sketch() { if (!mySketch) { // find sketch that references to this feature int aSketches = document()->size(ModelAPI_Feature::group()); for (int a = 0; a < aSketches && !mySketch; a++) { - boost::shared_ptr aSketch = boost::dynamic_pointer_cast< - SketchPlugin_Sketch>(document()->object(ModelAPI_Feature::group(), a)); + ObjectPtr anObj = document()->object(ModelAPI_Feature::group(), a); + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(anObj); if (aSketch) { std::list aList = aSketch->data()->reflist(SketchPlugin_Sketch::FEATURES_ID()) ->list(); @@ -33,7 +35,7 @@ SketchPlugin_Sketch* SketchPlugin_Feature::sketch() } } return mySketch; -} +}*/ AISObjectPtr SketchPlugin_Feature::simpleAISObject(boost::shared_ptr theRes, AISObjectPtr thePrevious) diff --git a/src/SketchPlugin/SketchPlugin_Feature.h b/src/SketchPlugin/SketchPlugin_Feature.h index d51301880..97a2d423b 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.h +++ b/src/SketchPlugin/SketchPlugin_Feature.h @@ -6,7 +6,7 @@ #define SketchPlugin_Feature_H_ #include "SketchPlugin.h" -#include +#include #include #include #include @@ -27,12 +27,12 @@ class SketchPlugin_Feature : public ModelAPI_Feature static AISObjectPtr simpleAISObject(boost::shared_ptr theRes, AISObjectPtr thePrevious); - /// Adds sub-feature of the higher level feature (sub-element of the sketch) - /// \param theFeature sub-feature - SKETCHPLUGIN_EXPORT virtual const void addSub(const FeaturePtr& theFeature) + /// Reference to the external edge or vertex as a AttributeSelection + inline static const std::string& EXTERNAL_ID() { + static const std::string MY_EXTERNAL_ID("External"); + return MY_EXTERNAL_ID; } - ; /// Returns true if this feature must be displayed in the history (top level of Part tree) SKETCHPLUGIN_EXPORT virtual bool isInHistory() @@ -52,14 +52,17 @@ class SketchPlugin_Feature : public ModelAPI_Feature /// Construction result is allways recomuted on the fly SKETCHPLUGIN_EXPORT virtual bool isPersistentResult() {return false;} + /// Returns true is sketch element is under the rigid constraint + SKETCHPLUGIN_EXPORT virtual bool isFixed() {return false;} + + /// Returns the sketch of this feature + inline SketchPlugin_Sketch* sketch() {return mySketch;} protected: /// Sets the higher-level feature for the sub-feature (sketch for line) void setSketch(SketchPlugin_Sketch* theSketch) { mySketch = theSketch; } - /// Returns the sketch of this feature - SketchPlugin_Sketch* sketch(); /// initializes mySketch SketchPlugin_Feature(); diff --git a/src/SketchPlugin/SketchPlugin_Line.cpp b/src/SketchPlugin/SketchPlugin_Line.cpp index 8ae5384bb..72a20f861 100644 --- a/src/SketchPlugin/SketchPlugin_Line.cpp +++ b/src/SketchPlugin/SketchPlugin_Line.cpp @@ -6,6 +6,8 @@ #include "SketchPlugin_Sketch.h" #include #include +#include +#include #include #include @@ -25,6 +27,8 @@ void SketchPlugin_Line::initAttributes() { data()->addAttribute(SketchPlugin_Line::START_ID(), GeomDataAPI_Point2D::type()); data()->addAttribute(SketchPlugin_Line::END_ID(), GeomDataAPI_Point2D::type()); + data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID()); } void SketchPlugin_Line::execute() @@ -88,3 +92,7 @@ double SketchPlugin_Line::distanceToPoint(const boost::shared_ptr return aDelta; } + +bool SketchPlugin_Line::isFixed() { + return data()->selection(EXTERNAL_ID())->context(); +} diff --git a/src/SketchPlugin/SketchPlugin_Line.h b/src/SketchPlugin/SketchPlugin_Line.h index d2656e5d8..d24f1af52 100644 --- a/src/SketchPlugin/SketchPlugin_Line.h +++ b/src/SketchPlugin/SketchPlugin_Line.h @@ -43,6 +43,9 @@ class SketchPlugin_Line : public SketchPlugin_Feature return MY_KIND; } + /// Returns true is sketch element is under the rigid constraint + SKETCHPLUGIN_EXPORT virtual bool isFixed(); + /// Creates a new part document if needed SKETCHPLUGIN_EXPORT virtual void execute(); diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index e3a324300..cf3cf283b 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -29,7 +29,7 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() SessionPtr aMgr = ModelAPI_Session::get(); ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); aFactory->registerValidator("SketchPlugin_DistanceAttr", - new SketchPlugin_DistanceAttrValidator); + new SketchPlugin_DistanceAttrValidator); aFactory->registerValidator("SketchPlugin_DifferentObjects", new SketchPlugin_DifferentObjectsValidator); aFactory->registerValidator("SketchPlugin_ResultPoint", new SketchPlugin_ResultPointValidator); @@ -44,7 +44,7 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() SKETCH_PLANE_COLOR); Config_PropManager::registerProp("Sketch planes", "planes_size", "Size", Config_Prop::Double, PLANE_SIZE); - Config_PropManager::registerProp("Sketch planes", "planes_thikness", "Thickness", + Config_PropManager::registerProp("Sketch planes", "planes_thickness", "Thickness", Config_Prop::Integer, SKETCH_WIDTH); Config_PropManager::registerProp("Visualization", "parallel_color", "Parallel constraint color", diff --git a/src/SketchPlugin/SketchPlugin_Point.cpp b/src/SketchPlugin/SketchPlugin_Point.cpp index 5e8f2a65e..c198e9b90 100644 --- a/src/SketchPlugin/SketchPlugin_Point.cpp +++ b/src/SketchPlugin/SketchPlugin_Point.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include #include @@ -22,6 +24,8 @@ SketchPlugin_Point::SketchPlugin_Point() void SketchPlugin_Point::initAttributes() { data()->addAttribute(SketchPlugin_Point::COORD_ID(), GeomDataAPI_Point2D::type()); + data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID()); } void SketchPlugin_Point::execute() @@ -61,3 +65,7 @@ double SketchPlugin_Point::distanceToPoint(const boost::shared_ptrpnt()->distance(thePoint); } + +bool SketchPlugin_Point::isFixed() { + return data()->selection(EXTERNAL_ID())->context(); +} diff --git a/src/SketchPlugin/SketchPlugin_Point.h b/src/SketchPlugin/SketchPlugin_Point.h index 14f587402..48415b18c 100644 --- a/src/SketchPlugin/SketchPlugin_Point.h +++ b/src/SketchPlugin/SketchPlugin_Point.h @@ -36,6 +36,9 @@ class SketchPlugin_Point : public SketchPlugin_Feature return MY_KIND; } + /// Returns true is sketch element is under the rigid constraint + SKETCHPLUGIN_EXPORT virtual bool isFixed(); + /// Creates a new part document if needed SKETCHPLUGIN_EXPORT virtual void execute(); diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index 0bbcfe2a7..a66bd9ffb 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include @@ -88,11 +88,16 @@ void SketchPlugin_Sketch::execute() return; // Collect all edges as one big wire - boost::shared_ptr aBigWire(new GeomAPI_Wire); + boost::shared_ptr aBigWire(new GeomAPI_PlanarEdges); std::list >::const_iterator aShapeIt = aFeaturesPreview.begin(); for (; aShapeIt != aFeaturesPreview.end(); ++aShapeIt) { aBigWire->addEdge(*aShapeIt); } + aBigWire->setOrigin(anOrigin->pnt()); + aBigWire->setDirX(aDirX->dir()); + aBigWire->setDirY(aDirY->dir()); + aBigWire->setNorm(aNorm->dir()); + // GeomAlgoAPI_SketchBuilder::createFaces(anOrigin->pnt(), aDirX->dir(), aDirY->dir(), aNorm->dir(), // aFeaturesPreview, aLoops, aWires); boost::shared_ptr aConstr = document()->createConstruction(data()); @@ -100,10 +105,30 @@ void SketchPlugin_Sketch::execute() setResult(aConstr); } -const void SketchPlugin_Sketch::addSub(const FeaturePtr& theFeature) +boost::shared_ptr SketchPlugin_Sketch::addFeature(std::string theID) +{ + boost::shared_ptr aNew = document()->addFeature(theID); + if (aNew) { + boost::dynamic_pointer_cast(aNew)->setSketch(this); + data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->append(aNew); + } + return aNew; +} + +int SketchPlugin_Sketch::numberOfSubs() const +{ + return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->size(); +} + +boost::shared_ptr SketchPlugin_Sketch::subFeature(const int theIndex) const +{ + ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex); + return boost::dynamic_pointer_cast(anObj); +} + +int SketchPlugin_Sketch::subFeatureId(const int theIndex) const { - boost::dynamic_pointer_cast(theFeature)->setSketch(this); - data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->append(theFeature); + return subFeature(theIndex)->data()->featureId(); } boost::shared_ptr SketchPlugin_Sketch::to3D(const double theX, const double theY) @@ -174,7 +199,7 @@ AISObjectPtr SketchPlugin_Sketch::getAISObject(AISObjectPtr thePrevious) SKETCH_PLANE_COLOR); aAIS->setColor(aRGB[0], aRGB[1], aRGB[2]); - aAIS->setWidth(Config_PropManager::integer("Sketch planes", "planes_thikness", + aAIS->setWidth(Config_PropManager::integer("Sketch planes", "planes_thickness", SKETCH_WIDTH)); } return aAIS; @@ -195,5 +220,5 @@ void SketchPlugin_Sketch::erase() document()->removeFeature(aFeature, false); } } - SketchPlugin_Feature::erase(); + ModelAPI_CompositeFeature::erase(); } diff --git a/src/SketchPlugin/SketchPlugin_Sketch.h b/src/SketchPlugin/SketchPlugin_Sketch.h index 07f8ae269..79b478f7c 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.h +++ b/src/SketchPlugin/SketchPlugin_Sketch.h @@ -25,7 +25,7 @@ * \ingroup DataModel * \brief Feature for creation of the new part in PartSet. */ -class SketchPlugin_Sketch : public SketchPlugin_Feature, public GeomAPI_IPresentable +class SketchPlugin_Sketch : public ModelAPI_CompositeFeature, public GeomAPI_IPresentable { public: /// Sketch feature kind @@ -78,10 +78,6 @@ class SketchPlugin_Sketch : public SketchPlugin_Feature, public GeomAPI_IPresent /// Request for initialization of data model of the feature: adding all attributes SKETCHPLUGIN_EXPORT virtual void initAttributes(); - /// Adds sub-feature of the higher level feature (sub-element of the sketch) - /// \param theFeature sub-feature - SKETCHPLUGIN_EXPORT virtual const void addSub(const FeaturePtr& theFeature); - /// Moves the feature /// \param theDeltaX the delta for X coordinate is moved /// \param theDeltaY the delta for Y coordinate is moved @@ -118,7 +114,22 @@ class SketchPlugin_Sketch : public SketchPlugin_Feature, public GeomAPI_IPresent /// removes also all sub-sketch elements SKETCHPLUGIN_EXPORT virtual void erase(); - protected: + SKETCHPLUGIN_EXPORT virtual boost::shared_ptr addFeature(std::string theID); + + /// Returns the number of sub-elements + SKETCHPLUGIN_EXPORT virtual int numberOfSubs() const; + + /// Returns the sub-feature by zero-base index + SKETCHPLUGIN_EXPORT virtual boost::shared_ptr + subFeature(const int theIndex) const; + + /// Returns the sub-feature unique identifier in this composite feature by zero-base index + SKETCHPLUGIN_EXPORT virtual int subFeatureId(const int theIndex) const; + + /// Construction result is allways recomuted on the fly + SKETCHPLUGIN_EXPORT virtual bool isPersistentResult() {return false;} + +protected: /// Creates a plane and append it to the list /// \param theX the X normal value /// \param theY the Y normal value diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 9bcc261fd..9e212a4fa 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -93,7 +93,7 @@ - + diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp index 1ef8518dc..bfecae21d 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp @@ -68,7 +68,7 @@ static int Search(const uint32_t& theEntityID, const std::vector& theEntities // ======================================================== SketchSolver_ConstraintGroup::SketchSolver_ConstraintGroup( - boost::shared_ptr theWorkplane) + boost::shared_ptr theWorkplane) : myID(++myGroupIndexer), myParamMaxID(0), myEntityMaxID(0), @@ -116,7 +116,7 @@ SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup() // Purpose: verify the group is based on the given workplane // ============================================================================ bool SketchSolver_ConstraintGroup::isBaseWorkplane( - boost::shared_ptr theWorkplane) const + boost::shared_ptr theWorkplane) const { return theWorkplane == mySketch; } @@ -481,6 +481,9 @@ bool SketchSolver_ConstraintGroup::changeRigidConstraint( // Avoid to create additional "Rigid" constraints for coincident points bool isCoincAlreadyFixed = false; if (!anAlreadyFixed.empty()) { + if (anAlreadyFixed.find(*aPointsPtr) != anAlreadyFixed.end()) + isCoincAlreadyFixed = true; + std::vector >::const_iterator aCoincIter = myCoincidentPoints.begin(); for (; !isCoincAlreadyFixed && aCoincIter != myCoincidentPoints.end(); aCoincIter++) { @@ -651,28 +654,30 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(FeaturePtr theEntity) SketchPlugin_Feature>(theEntity); if (aFeature) { // Verify the feature by its kind const std::string& aFeatureKind = aFeature->getKind(); - - std::list anAttributes = aFeature->data()->attributes(std::string()); - std::list::iterator anAttrIter = anAttributes.begin(); - for ( ; anAttrIter != anAttributes.end(); anAttrIter++) - if (!(*anAttrIter)->isInitialized()) // the entity is not fully initialized, don't add it into solver - return SLVS_E_UNKNOWN; + AttributePtr anAttribute; // Line if (aFeatureKind.compare(SketchPlugin_Line::ID()) == 0) { - Slvs_hEntity aStart = changeEntity( - aFeature->data()->attribute(SketchPlugin_Line::START_ID())); - Slvs_hEntity aEnd = changeEntity(aFeature->data()->attribute(SketchPlugin_Line::END_ID())); + anAttribute = aFeature->data()->attribute(SketchPlugin_Line::START_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aStart = changeEntity(anAttribute); + + anAttribute = aFeature->data()->attribute(SketchPlugin_Line::END_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aEnd = changeEntity(anAttribute); if (!isEntExists) // New entity aNewEntity = Slvs_MakeLineSegment(++myEntityMaxID, myID, myWorkplane.h, aStart, aEnd); } // Circle else if (aFeatureKind.compare(SketchPlugin_Circle::ID()) == 0) { - Slvs_hEntity aCenter = changeEntity( - aFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID())); - Slvs_hEntity aRadius = changeEntity( - aFeature->data()->attribute(SketchPlugin_Circle::RADIUS_ID())); + anAttribute = aFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aCenter = changeEntity(anAttribute); + + anAttribute = aFeature->data()->attribute(SketchPlugin_Circle::RADIUS_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aRadius = changeEntity(anAttribute); if (!isEntExists) // New entity aNewEntity = Slvs_MakeCircle(++myEntityMaxID, myID, myWorkplane.h, aCenter, @@ -680,10 +685,17 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(FeaturePtr theEntity) } // Arc else if (aFeatureKind.compare(SketchPlugin_Arc::ID()) == 0) { - Slvs_hEntity aCenter = changeEntity( - aFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID())); - Slvs_hEntity aStart = changeEntity(aFeature->data()->attribute(SketchPlugin_Arc::START_ID())); - Slvs_hEntity aEnd = changeEntity(aFeature->data()->attribute(SketchPlugin_Arc::END_ID())); + anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aCenter = changeEntity(anAttribute); + + anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::START_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aStart = changeEntity(anAttribute); + + anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::END_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aEnd = changeEntity(anAttribute); if (!isEntExists) aNewEntity = Slvs_MakeArcOfCircle(++myEntityMaxID, myID, myWorkplane.h, @@ -691,8 +703,9 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(FeaturePtr theEntity) } // Point (it has low probability to be an attribute of constraint, so it is checked at the end) else if (aFeatureKind.compare(SketchPlugin_Point::ID()) == 0) { - Slvs_hEntity aPoint = changeEntity( - aFeature->data()->attribute(SketchPlugin_Point::COORD_ID())); + anAttribute = aFeature->data()->attribute(SketchPlugin_Point::COORD_ID()); + if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN; + Slvs_hEntity aPoint = changeEntity(anAttribute); if (isEntExists) return aEntIter->second; @@ -716,7 +729,6 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(FeaturePtr theEntity) return aNewEntity.h; } - // Unsupported or wrong entity type return SLVS_E_UNKNOWN; } @@ -776,7 +788,7 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeNormal( // Class: SketchSolver_ConstraintGroup // Purpose: create workplane for the group // ============================================================================ -bool SketchSolver_ConstraintGroup::addWorkplane(boost::shared_ptr theSketch) +bool SketchSolver_ConstraintGroup::addWorkplane(boost::shared_ptr theSketch) { if (myWorkplane.h || theSketch->getKind().compare(SketchPlugin_Sketch::ID()) != 0) return false; // the workplane already exists or the function parameter is not Sketch diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.h b/src/SketchSolver/SketchSolver_ConstraintGroup.h index 2337f5187..c8a673029 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.h +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.h @@ -30,7 +30,7 @@ class SketchSolver_ConstraintGroup * Throws an exception if theWorkplane is not an object of SketchPlugin_Sketch type * \remark Type of theSketch is not verified inside */ - SketchSolver_ConstraintGroup(boost::shared_ptr theWorkplane); + SketchSolver_ConstraintGroup(boost::shared_ptr theWorkplane); ~SketchSolver_ConstraintGroup(); @@ -69,9 +69,9 @@ class SketchSolver_ConstraintGroup * \param[in] theWorkplane the feature to be compared with base workplane * \return \c true if workplanes are the same */ - bool isBaseWorkplane(boost::shared_ptr theWorkplane) const; + bool isBaseWorkplane(boost::shared_ptr theWorkplane) const; - boost::shared_ptr getWorkplane() const + boost::shared_ptr getWorkplane() const { return mySketch; } @@ -188,7 +188,7 @@ protected: * \param[in] theSketch parameters of workplane are the attributes of this sketch * \return \c true if success, \c false if workplane parameters are not consistent */ - bool addWorkplane(boost::shared_ptr theSketch); + bool addWorkplane(boost::shared_ptr theSketch); /** \brief Add the entities of constraint for points coincidence into the appropriate list * \param[in] thePoint1 identifier of the first point @@ -224,7 +224,7 @@ protected: std::list myTempConstraints; ///< The list of identifiers of temporary constraints (SLVS_C_WHERE_DRAGGED) applied for all other points moved by user // SketchPlugin entities - boost::shared_ptr mySketch; ///< Equivalent to workplane + boost::shared_ptr mySketch; ///< Equivalent to workplane ConstraintMap myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints std::map, Slvs_hEntity> myEntityAttrMap; ///< The map between "attribute" parameters of constraints and their equivalent SolveSpace entities std::map myEntityFeatMap; ///< The map between "feature" parameters of constraints and their equivalent SolveSpace entities diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index c0ade33a7..ebc25b1fa 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -88,8 +88,8 @@ void SketchSolver_ConstraintManager::processEvent( // Only sketches and constraints can be added by Create event const std::string& aFeatureKind = aFeature->getKind(); if (aFeatureKind.compare(SketchPlugin_Sketch::ID()) == 0) { - boost::shared_ptr aSketch = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(aFeature); + boost::shared_ptr aSketch = boost::dynamic_pointer_cast< + ModelAPI_CompositeFeature>(aFeature); if (aSketch) changeWorkplane(aSketch); continue; @@ -144,7 +144,7 @@ void SketchSolver_ConstraintManager::processEvent( // Purpose: update workplane by given parameters of the sketch // ============================================================================ bool SketchSolver_ConstraintManager::changeWorkplane( - boost::shared_ptr theSketch) + boost::shared_ptr theSketch) { bool aResult = true; // changed when a workplane wrongly updated bool isUpdated = false; @@ -189,7 +189,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( // There are no groups applicable for this constraint => create new one // The group will be created only for constraints, not for features if (!aConstraint) return false; - boost::shared_ptr aWP = findWorkplane(aConstraint); + boost::shared_ptr aWP = findWorkplane(aConstraint); if (!aWP) return false; SketchSolver_ConstraintGroup* aGroup = new SketchSolver_ConstraintGroup(aWP); @@ -309,7 +309,7 @@ void SketchSolver_ConstraintManager::findGroups( boost::shared_ptr theFeature, std::set& theGroupIDs) const { - boost::shared_ptr aWP = findWorkplane(theFeature); + boost::shared_ptr aWP = findWorkplane(theFeature); SketchSolver_ConstraintGroup* anEmptyGroup = 0; // appropriate empty group for specified constraint std::vector::const_iterator aGroupIter; @@ -331,15 +331,15 @@ void SketchSolver_ConstraintManager::findGroups( // Class: SketchSolver_Session // Purpose: search workplane containing given feature // ============================================================================ -boost::shared_ptr SketchSolver_ConstraintManager::findWorkplane( +boost::shared_ptr SketchSolver_ConstraintManager::findWorkplane( boost::shared_ptr theFeature) const { // Already verified workplanes - std::set > aVerified; + std::set > aVerified; std::vector::const_iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) { - boost::shared_ptr aWP = (*aGroupIter)->getWorkplane(); + boost::shared_ptr aWP = (*aGroupIter)->getWorkplane(); if (aVerified.find(aWP) != aVerified.end()) continue; @@ -353,7 +353,7 @@ boost::shared_ptr SketchSolver_ConstraintManager::findWork aVerified.insert(aWP); } - return boost::shared_ptr(); + return boost::shared_ptr(); } // ============================================================================ diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.h b/src/SketchSolver/SketchSolver_ConstraintManager.h index b0aefd196..b13a67182 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.h +++ b/src/SketchSolver/SketchSolver_ConstraintManager.h @@ -65,7 +65,7 @@ class SketchSolver_ConstraintManager : public Events_Listener * \return \c true if the workplane changed successfully * \remark Type of theSketch is not verified inside */ - bool changeWorkplane(boost::shared_ptr theSketch); + bool changeWorkplane(boost::shared_ptr theSketch); /** \brief Removes a workplane from the manager. * All groups based on such workplane will be removed too. @@ -95,7 +95,7 @@ class SketchSolver_ConstraintManager : public Events_Listener * \param[in] theFeature object to be found * \return workplane containing the feature */ - boost::shared_ptr findWorkplane( + boost::shared_ptr findWorkplane( boost::shared_ptr theFeature) const; private: diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index ace172c50..0a07539a4 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -33,7 +33,6 @@ SET(PROJECT_HEADERS XGUI_Preferences.h XGUI_IPrefMgr.h XGUI_QtEvents.h - XGUI_ViewerFilters.h ) SET(PROJECT_AUTOMOC @@ -67,7 +66,6 @@ SET(PROJECT_SOURCES XGUI_Selection.cpp XGUI_Preferences.cpp XGUI_QtEvents.cpp - XGUI_ViewerFilters.cpp ) SET(PROJECT_RESOURCES diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index cf39a413f..736de32d2 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include @@ -21,6 +23,8 @@ #include #include #include +#include +#include #include @@ -45,19 +49,20 @@ void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer) if (isVisible(theObject)) { redisplay(theObject, isUpdateViewer); } else { - boost::shared_ptr anAIS; + AISObjectPtr anAIS; GeomPresentablePtr aPrs = boost::dynamic_pointer_cast(theObject); bool isShading = false; if (aPrs) { - anAIS = aPrs->getAISObject(boost::shared_ptr()); + anAIS = aPrs->getAISObject(AISObjectPtr()); } else { ResultPtr aResult = boost::dynamic_pointer_cast(theObject); if (aResult) { boost::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); if (aShapePtr) { - anAIS = boost::shared_ptr(new GeomAPI_AISObject()); - anAIS->createShape(aShapePtr); + anAIS = AISObjectPtr(new GeomAPI_AISObject()); + anAIS->setImpl(new Handle(AIS_InteractiveObject)(new ModuleBase_ResultPrs(aResult))); + //anAIS->createShape(aShapePtr); isShading = true; } } @@ -67,7 +72,7 @@ void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer) } } -void XGUI_Displayer::display(ObjectPtr theObject, boost::shared_ptr theAIS, +void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, bool isShading, bool isUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -90,7 +95,7 @@ void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer) Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; - boost::shared_ptr anObject = myResult2AISObjectMap[theObject]; + AISObjectPtr anObject = myResult2AISObjectMap[theObject]; if (anObject) { Handle(AIS_InteractiveObject) anAIS = anObject->impl(); if (!anAIS.IsNull()) { @@ -105,38 +110,27 @@ void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer) if (!isVisible(theObject)) return; - Handle(AIS_InteractiveObject) aAISIO; - boost::shared_ptr aAISObj = getAISObject(theObject); + AISObjectPtr aAISObj = getAISObject(theObject); + Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl(); + GeomPresentablePtr aPrs = boost::dynamic_pointer_cast(theObject); if (aPrs) { - boost::shared_ptr aAIS_Obj = aPrs->getAISObject(aAISObj); - if (aAISObj && !aAIS_Obj) { + AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj); + if (!aAIS_Obj) { erase(theObject, isUpdateViewer); return; } - aAISIO = aAIS_Obj->impl(); - } else { - ResultPtr aResult = boost::dynamic_pointer_cast(theObject); - if (aResult) { - boost::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); - if (aShapePtr) { - Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast( - aAISObj->impl()); - if (!aAISShape.IsNull()) { - aAISShape->Set(aShapePtr->impl()); - aAISIO = aAISShape; - } - } + if (aAIS_Obj != aAISObj) { + myResult2AISObjectMap[theObject] = aAIS_Obj; } + aAISIO = aAIS_Obj->impl(); } + if (!aAISIO.IsNull()) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; aContext->Redisplay(aAISIO, isUpdateViewer); - //if (aContext->HasOpenedContext()) { - // aContext->Load(aAISIO, -1, true/*allow decomposition*/); - //} } } @@ -147,22 +141,30 @@ void XGUI_Displayer::deactivate(ObjectPtr theObject) if (aContext.IsNull()) return; - boost::shared_ptr anObj = myResult2AISObjectMap[theObject]; + AISObjectPtr anObj = myResult2AISObjectMap[theObject]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); aContext->Deactivate(anAIS); } } -void XGUI_Displayer::activate(ObjectPtr theObject) +void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes) { if (isVisible(theObject)) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; - boost::shared_ptr anObj = myResult2AISObjectMap[theObject]; + AISObjectPtr anObj = myResult2AISObjectMap[theObject]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - aContext->Activate(anAIS); + if (aContext->HasOpenedContext()) { + aContext->Load(anAIS, -1, true); + } + if (theModes.size() > 0) { + foreach(int aMode, theModes) { + aContext->Activate(anAIS, aMode); + } + } else + aContext->Activate(anAIS); } } @@ -174,7 +176,7 @@ bool XGUI_Displayer::isActive(ObjectPtr theObject) const if (!isVisible(theObject)) return false; - boost::shared_ptr anObj = myResult2AISObjectMap.at(theObject); + AISObjectPtr anObj = myResult2AISObjectMap.at(theObject); Handle(AIS_InteractiveObject) anAIS = anObj->impl(); TColStd_ListOfInteger aModes; @@ -233,7 +235,7 @@ void XGUI_Displayer::setSelected(const QList& theResults, const bool if (myResult2AISObjectMap.find(aResult) == myResult2AISObjectMap.end()) continue; - boost::shared_ptr anObj = myResult2AISObjectMap[aResult]; + AISObjectPtr anObj = myResult2AISObjectMap[aResult]; if (anObj) { Handle(AIS_InteractiveObject) anAIS = anObj->impl(); if (!anAIS.IsNull()) @@ -244,6 +246,16 @@ void XGUI_Displayer::setSelected(const QList& theResults, const bool updateViewer(); } + +void XGUI_Displayer::clearSelected() +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext) { + aContext->UnhilightCurrents(false); + aContext->ClearSelected(); + } +} + void XGUI_Displayer::eraseAll(const bool isUpdateViewer) { Handle(AIS_InteractiveContext) ic = AISContext(); @@ -253,7 +265,7 @@ void XGUI_Displayer::eraseAll(const bool isUpdateViewer) ResultToAISMap::iterator aIt; for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) { // erase an object - boost::shared_ptr aAISObj = (*aIt).second; + AISObjectPtr aAISObj = (*aIt).second; Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); if (!anIO.IsNull()) ic->Remove(anIO, false); @@ -275,7 +287,7 @@ void XGUI_Displayer::eraseDeletedResults(const bool isUpdateViewer) for (; aFIt != aFLast; aFIt++) { ObjectPtr aFeature = (*aFIt).first; if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) { - boost::shared_ptr anObj = (*aFIt).second; + AISObjectPtr anObj = (*aFIt).second; if (!anObj) continue; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); @@ -314,21 +326,27 @@ void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer) closeAllContexts(true); } -boost::shared_ptr XGUI_Displayer::getAISObject(ObjectPtr theObject) const +AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const { - boost::shared_ptr anIO; + AISObjectPtr anIO; if (myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end()) anIO = (myResult2AISObjectMap.find(theObject))->second; return anIO; } -ObjectPtr XGUI_Displayer::getObject(Handle(AIS_InteractiveObject) theIO) const +ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const +{ + Handle(AIS_InteractiveObject) aRefAIS = theIO->impl(); + return getObject(aRefAIS); +} + +ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const { ObjectPtr aFeature; ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast = myResult2AISObjectMap.end(); for (; aFIt != aFLast && !aFeature; aFIt++) { - boost::shared_ptr anObj = (*aFIt).second; + AISObjectPtr anObj = (*aFIt).second; if (!anObj) continue; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); @@ -361,7 +379,7 @@ Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const return myWorkshop->viewer()->AISContext(); } -void XGUI_Displayer::display(boost::shared_ptr theAIS, bool isUpdate) +void XGUI_Displayer::display(AISObjectPtr theAIS, bool isUpdate) { Handle(AIS_InteractiveContext) aContext = AISContext(); Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); @@ -369,7 +387,7 @@ void XGUI_Displayer::display(boost::shared_ptr theAIS, bool i aContext->Display(anAISIO, isUpdate); } -void XGUI_Displayer::erase(boost::shared_ptr theAIS, const bool isUpdate) +void XGUI_Displayer::erase(AISObjectPtr theAIS, const bool isUpdate) { Handle(AIS_InteractiveContext) aContext = AISContext(); Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); @@ -378,8 +396,7 @@ void XGUI_Displayer::erase(boost::shared_ptr theAIS, const bo } } -void XGUI_Displayer::activateObjectsOutOfContext(const std::list& theModes, - Handle(SelectMgr_Filter) theFilter) +void XGUI_Displayer::activateObjectsOutOfContext(const QIntList& theModes) { Handle(AIS_InteractiveContext) aContext = AISContext(); // Open local context if there is no one @@ -387,13 +404,19 @@ void XGUI_Displayer::activateObjectsOutOfContext(const std::list& theModes, return; aContext->UseDisplayedObjects(); - std::list::const_iterator anIt = theModes.begin(), aLast = theModes.end(); - for (; anIt != aLast; anIt++) { - aContext->ActivateStandardMode((TopAbs_ShapeEnum)(*anIt)); + ResultToAISMap::iterator aIt; + Handle(AIS_InteractiveObject) anAISIO; + for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) { + anAISIO = (*aIt).second->impl(); + aContext->Load(anAISIO, -1, true); + if (theModes.size() == 0) + aContext->Activate(anAISIO); + else { + foreach(int aMode, theModes) { + aContext->Activate(anAISIO, aMode); + } + } } - - if (!theFilter.IsNull()) - aContext->AddFilter(theFilter); } @@ -404,7 +427,6 @@ void XGUI_Displayer::deactivateObjectsOutOfContext() if (!aContext->HasOpenedContext()) return; - aContext->RemoveFilters(); aContext->NotUseDisplayedObjects(); } @@ -418,7 +440,7 @@ void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bo if (aContext.IsNull()) return; - boost::shared_ptr aAISObj = getAISObject(theObject); + AISObjectPtr aAISObj = getAISObject(theObject); if (!aAISObj) return; @@ -426,6 +448,27 @@ void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bo aContext->SetDisplayMode(aAISIO, theMode, toUpdate); } +void XGUI_Displayer::setSelectionModes(const QIntList& theModes) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; + if (!aContext->HasOpenedContext()) + return; + // Clear previous mode + const TColStd_ListOfInteger& aModes = aContext->ActivatedStandardModes(); + if (!aModes.IsEmpty()) { + TColStd_ListOfInteger aMModes; + aMModes.Assign(aModes); + TColStd_ListIteratorOfListOfInteger it(aMModes); + for(; it.More(); it.Next()) { + aContext->DeactivateStandardMode((TopAbs_ShapeEnum)it.Value()); + } + } + foreach(int aMode, theModes) { + aContext->ActivateStandardMode((TopAbs_ShapeEnum)aMode); + } +} XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const { @@ -433,7 +476,7 @@ XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) con if (aContext.IsNull()) return NoMode; - boost::shared_ptr aAISObj = getAISObject(theObject); + AISObjectPtr aAISObj = getAISObject(theObject); if (!aAISObj) return NoMode; @@ -441,3 +484,18 @@ XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) con return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode(); } +void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; + aContext->AddFilter(theFilter); +} + +void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; + aContext->RemoveFilter(theFilter); +} diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index 4562e6d08..7f117fea5 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -56,7 +56,7 @@ class XGUI_EXPORT XGUI_Displayer void display(ObjectPtr theObject, bool isUpdateViewer = true); /// Display the given AIS object. To hide this object use corresponde erase method - void display(boost::shared_ptr theAIS, bool isUpdate = true); + void display(AISObjectPtr theAIS, bool isUpdate = true); /// Stop the current selection and color the given features to the selection color /// \param theFeatures a list of features to be disabled @@ -72,13 +72,17 @@ class XGUI_EXPORT XGUI_Displayer */ void setSelected(const QList& theFeatures, bool isUpdateViewer = true); + + /// Un select all objects + void clearSelected(); + /// Erase the feature and a shape. /// \param theFeature a feature instance /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly void erase(ObjectPtr theObject, const bool isUpdateViewer = true); /// Erase the given AIS object displayed by corresponded display method - void erase(boost::shared_ptr theAIS, const bool isUpdate = true); + void erase(AISObjectPtr theAIS, const bool isUpdate = true); /// Erase all presentations /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly @@ -88,40 +92,53 @@ class XGUI_EXPORT XGUI_Displayer /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly void eraseDeletedResults(const bool isUpdateViewer = true); + /// Opens local context. Does nothing if it is already opened. void openLocalContext(); /// Deactivates selection of sub-shapes /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly void closeLocalContexts(const bool isUpdateViewer = true); + /* + * Set modes of selections. Selection mode has to be defined by TopAbs_ShapeEnum. + * It doesn't manages a local context + * \param theModes - list of selection modes. If the list is empty then all selectoin modes will be cleared. + */ + void setSelectionModes(const QIntList& theModes); + + void addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter); + + void removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter); + /// Updates the viewer void updateViewer(); /// Searches the interactive object by feature /// \param theFeature the feature or NULL if it not visualized /// \return theIO an interactive object - boost::shared_ptr getAISObject(ObjectPtr theFeature) const; + AISObjectPtr getAISObject(ObjectPtr theFeature) const; /// Searches the feature by interactive object /// \param theIO an interactive object /// \return feature the feature or NULL if it not visualized - ObjectPtr getObject(Handle(AIS_InteractiveObject) theIO) const; + ObjectPtr getObject(const AISObjectPtr& theIO) const; + ObjectPtr getObject(const Handle(AIS_InteractiveObject)& theIO) const; /// Deactivates the given object (not allow selection) void deactivate(ObjectPtr theFeature); /// Activates the given object (it can be selected) - void activate(ObjectPtr theFeature); + /// \param theModes - modes on which it has to be activated (can be empty) + void activate(ObjectPtr theFeature, const QIntList& theModes); /// Returns true if the given object can be selected bool isActive(ObjectPtr theObject) const; /// Activates in local context displayed outside of the context. - /// \param theModes - selection modes to activate - /// \param theFilter - filter for selection - void activateObjectsOutOfContext(const std::list& theModes, - Handle(SelectMgr_Filter) theFilter); + /// \param theModes - modes on which it has to be activated (can be empty) + void activateObjectsOutOfContext(const QIntList& theModes); + /// Activates in local context displayed outside of the context. void deactivateObjectsOutOfContext(); /// Sets display mode for the given object if this object is displayed @@ -147,7 +164,7 @@ class XGUI_EXPORT XGUI_Displayer /// \param theAIS AIS presentation /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly /// Returns true if the Feature succesfully displayed - void display(ObjectPtr theObject, boost::shared_ptr theAIS, bool isShading, + void display(ObjectPtr theObject, AISObjectPtr theAIS, bool isShading, bool isUpdateViewer = true); /// Display the shape and activate selection of sub-shapes @@ -156,7 +173,7 @@ class XGUI_EXPORT XGUI_Displayer /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly /// \returns true if the presentation is created //bool redisplay(ObjectPtr theObject, - // boost::shared_ptr theAIS, + // AISObjectPtr theAIS, // const bool isUpdateViewer = true); /** Redisplay the shape if it was displayed @@ -168,7 +185,7 @@ class XGUI_EXPORT XGUI_Displayer protected: XGUI_Workshop* myWorkshop; - typedef std::map > ResultToAISMap; + typedef std::map ResultToAISMap; ResultToAISMap myResult2AISObjectMap; }; diff --git a/src/XGUI/XGUI_ModuleConnector.cpp b/src/XGUI/XGUI_ModuleConnector.cpp index 8ebed4c15..5bb4445fe 100644 --- a/src/XGUI/XGUI_ModuleConnector.cpp +++ b/src/XGUI/XGUI_ModuleConnector.cpp @@ -8,6 +8,10 @@ #include "XGUI_SelectionMgr.h" #include "XGUI_Selection.h" #include "XGUI_OperationMgr.h" +#include "XGUI_Displayer.h" + +#include + XGUI_ModuleConnector::XGUI_ModuleConnector(XGUI_Workshop* theWorkshop) : ModuleBase_IWorkshop(theWorkshop), @@ -22,10 +26,13 @@ XGUI_ModuleConnector::XGUI_ModuleConnector(XGUI_Workshop* theWorkshop) this, SIGNAL(operationStarted(ModuleBase_Operation*))); connect(anOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), this, SIGNAL(operationStopped(ModuleBase_Operation*))); + + myDocumentShapeFilter = new ModuleBase_ShapeDocumentFilter(this); } XGUI_ModuleConnector::~XGUI_ModuleConnector() { + myDocumentShapeFilter.Nullify(); } ModuleBase_ISelection* XGUI_ModuleConnector::selection() const @@ -51,16 +58,34 @@ ModuleBase_Operation* XGUI_ModuleConnector::currentOperation() const void XGUI_ModuleConnector::activateSubShapesSelection(const QIntList& theTypes) { - Handle(AIS_InteractiveContext) aAIS = myWorkshop->viewer()->AISContext(); - if (!aAIS->HasOpenedContext()) - aAIS->OpenLocalContext(); + XGUI_Displayer* aDisp = myWorkshop->displayer(); + aDisp->openLocalContext(); + // Convert shape types to selection types + QIntList aModes; foreach(int aType, theTypes) { - aAIS->ActivateStandardMode((TopAbs_ShapeEnum)aType); + aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum)aType)); } + aDisp->activateObjectsOutOfContext(aModes); + //TODO: We have to open Local context because at neutral point filters don't work (bug 25340) + aDisp->addSelectionFilter(myDocumentShapeFilter); } void XGUI_ModuleConnector::deactivateSubShapesSelection() { - Handle(AIS_InteractiveContext) aAIS = myWorkshop->viewer()->AISContext(); - aAIS->CloseAllContexts(); + XGUI_Displayer* aDisp = myWorkshop->displayer(); + // The document limitation selection has to be only during operation + aDisp->removeSelectionFilter(myDocumentShapeFilter); + aDisp->closeLocalContexts(false); +} + +AISObjectPtr XGUI_ModuleConnector::findPresentation(const ObjectPtr& theObject) const +{ + XGUI_Displayer* aDisp = myWorkshop->displayer(); + return aDisp->getAISObject(theObject); } + +ObjectPtr XGUI_ModuleConnector::findPresentedObject(const AISObjectPtr& theAIS) const +{ + XGUI_Displayer* aDisp = myWorkshop->displayer(); + return aDisp->getObject(theAIS); +} \ No newline at end of file diff --git a/src/XGUI/XGUI_ModuleConnector.h b/src/XGUI/XGUI_ModuleConnector.h index 054ad0872..f6d071f2a 100644 --- a/src/XGUI/XGUI_ModuleConnector.h +++ b/src/XGUI/XGUI_ModuleConnector.h @@ -8,6 +8,7 @@ #include "XGUI.h" #include #include +#include class Handle_AIS_InteractiveContext; class XGUI_Workshop; @@ -43,10 +44,19 @@ Q_OBJECT //! Returns currently active operation virtual ModuleBase_Operation* currentOperation() const; + //! Returns AIS opbject by data object + virtual AISObjectPtr findPresentation(const ObjectPtr& theObject) const; + + //! Returns data object by AIS + virtual ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const; + XGUI_Workshop* workshop() const { return myWorkshop; } - private: +private: XGUI_Workshop* myWorkshop; + + /// A filter which provides selection within a current document or whole PartSet + Handle(ModuleBase_ShapeDocumentFilter) myDocumentShapeFilter; }; #endif diff --git a/src/XGUI/XGUI_Preferences.cpp b/src/XGUI/XGUI_Preferences.cpp index 81e0282ee..4d91ceb34 100644 --- a/src/XGUI/XGUI_Preferences.cpp +++ b/src/XGUI/XGUI_Preferences.cpp @@ -13,6 +13,7 @@ #include #include #include +#include const QString XGUI_Preferences::VIEWER_SECTION = "Viewer"; const QString XGUI_Preferences::MENU_SECTION = "Menu"; @@ -40,7 +41,7 @@ bool XGUI_Preferences::editPreferences(XGUI_Prefs& theModified) return false; } -void XGUI_Preferences::updateCustomProps() +void XGUI_Preferences::updateConfigByResources() { Config_Properties aProps = Config_PropManager::getProperties(); Config_Properties::iterator aIt; @@ -48,8 +49,30 @@ void XGUI_Preferences::updateCustomProps() Config_Prop* aProp = (*aIt); QString aVal = myResourceMgr->stringValue(QString(aProp->section().c_str()), QString(aProp->name().c_str())); - if (!aVal.isNull()) + if (!aVal.isEmpty()) { aProp->setValue(aVal.toStdString()); + } + } +} + +void XGUI_Preferences::updateResourcesByConfig() +{ + Config_Properties aProps = Config_PropManager::getProperties(); + Config_Properties::iterator aIt; + for (aIt = aProps.begin(); aIt != aProps.end(); ++aIt) { + Config_Prop* aProp = (*aIt); + myResourceMgr->setValue(QString(aProp->section().c_str()), QString(aProp->name().c_str()), + QString(aProp->value().c_str())); + } +} + +void XGUI_Preferences::resetConfig() +{ + Config_Properties aProps = Config_PropManager::getProperties(); + Config_Properties::iterator aIt; + for (aIt = aProps.begin(); aIt != aProps.end(); ++aIt) { + Config_Prop* aProp = (*aIt); + aProp->setValue(aProp->defaultValue()); } } @@ -63,9 +86,9 @@ void XGUI_Preferences::loadCustomProps() QStringList aParams = myResourceMgr->parameters(aSection); foreach (QString aParam, aParams) { - Config_PropManager::registerProp(aSection.toStdString(), aParam.toStdString(), "", - Config_Prop::Disabled, - myResourceMgr->stringValue(aSection, aParam).toStdString()); + Config_Prop* aProp = Config_PropManager::registerProp(aSection.toStdString(), + aParam.toStdString(), "", Config_Prop::Disabled); + aProp->setValue(myResourceMgr->stringValue(aSection, aParam).toStdString()); } } } @@ -150,8 +173,13 @@ XGUI_PreferencesDlg::XGUI_PreferencesDlg(SUIT_ResourceMgr* theResurces, QWidget* setFocusProxy(myPreferences); myPreferences->setFrameStyle(QFrame::Box | QFrame::Sunken); - QDialogButtonBox* aBtnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, + QDialogButtonBox* aBtnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | + QDialogButtonBox::Reset, Qt::Horizontal, this); + QPushButton* aDefaultButton = aBtnBox->button(QDialogButtonBox::Reset); + aDefaultButton->setText(tr("Default")); + connect(aDefaultButton, SIGNAL(clicked()), this, SLOT(onDefault())); + main->addWidget(aBtnBox); connect(aBtnBox, SIGNAL(accepted()), this, SLOT(accept())); connect(aBtnBox, SIGNAL(rejected()), this, SLOT(reject())); @@ -230,7 +258,7 @@ void XGUI_PreferencesDlg::accept() myIsChanged = true; // Save custom properties - XGUI_Preferences::updateCustomProps(); + XGUI_Preferences::updateConfigByResources(); QDialog::accept(); } @@ -239,6 +267,22 @@ void XGUI_PreferencesDlg::modified(XGUI_Prefs& theModified) const theModified = myPreferences->modified(); } +void XGUI_PreferencesDlg::onDefault() +{ + // reset main resources +#ifdef WIN32 + QtxResourceMgr::WorkingMode aPrev = + myPreferences->resourceMgr()->setWorkingMode(QtxResourceMgr::IgnoreUserValues); + myPreferences->retrieve(); + myPreferences->resourceMgr()->setWorkingMode(aPrev); +#endif + // reset plugin's resources + XGUI_Preferences::resetConfig(); + XGUI_Preferences::updateResourcesByConfig(); + + myPreferences->retrieve(); +} + //********************************************************** //********************************************************** //********************************************************** diff --git a/src/XGUI/XGUI_Preferences.h b/src/XGUI/XGUI_Preferences.h index a6fbc8a2b..3241d4142 100644 --- a/src/XGUI/XGUI_Preferences.h +++ b/src/XGUI/XGUI_Preferences.h @@ -35,8 +35,15 @@ class XGUI_EXPORT XGUI_Preferences /// It is used in case of necessity to define external resource manager (not NewGeom) static void setResourceMgr(SUIT_ResourceMgr* theMgr) { myResourceMgr = theMgr; } - /// Updates properties defined by module from SUIT_ResourceMgr to Config_PropManager - static void updateCustomProps(); + /// Updates Config_PropManager properties by module from SUIT_ResourceMgr + static void updateConfigByResources(); + + /// Updates SUIT_ResourceMgr values by Config_PropManager properties + /// \param theUpdateOnlyInvalid flag to update only invalid values, if it is false, all are updated + static void updateResourcesByConfig(); + + /// Set default values to the Config_PropManager properties + static void resetConfig(); /// Loads properties defined by module to Config_PropManager static void loadCustomProps(); @@ -97,6 +104,9 @@ Q_OBJECT public slots: virtual void accept(); +protected slots: + void onDefault(); + private: /// Create editors for aplication properties void createEditors(); diff --git a/src/XGUI/XGUI_PropertyPanel.cpp b/src/XGUI/XGUI_PropertyPanel.cpp index 93a35bdc9..9f6a706cf 100644 --- a/src/XGUI/XGUI_PropertyPanel.cpp +++ b/src/XGUI/XGUI_PropertyPanel.cpp @@ -23,7 +23,8 @@ #endif XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent) - : ModuleBase_IPropertyPanel(theParent), myActiveWidget(0) + : ModuleBase_IPropertyPanel(theParent), + myActiveWidget(NULL) { this->setWindowTitle(tr("Property Panel")); QAction* aViewAct = this->toggleViewAction(); @@ -71,6 +72,7 @@ void XGUI_PropertyPanel::cleanContent() { myWidgets.clear(); qDeleteAll(myCustomWidget->children()); + myActiveWidget = NULL; } void XGUI_PropertyPanel::setModelWidgets(const QList& theWidgets) @@ -87,7 +89,7 @@ void XGUI_PropertyPanel::setModelWidgets(const QList& t connect(*anIt, SIGNAL(focusOutWidget(ModuleBase_ModelWidget*)), this, SLOT(activateNextWidget(ModuleBase_ModelWidget*))); connect(*anIt, SIGNAL(focusInWidget(ModuleBase_ModelWidget*)), - this, SIGNAL(widgetActivated(ModuleBase_ModelWidget*))); + this, SLOT(activateWidget(ModuleBase_ModelWidget*))); ModuleBase_WidgetPoint2D* aPointWidget = dynamic_cast(*anIt); if (aPointWidget) @@ -121,20 +123,17 @@ QWidget* XGUI_PropertyPanel::contentWidget() void XGUI_PropertyPanel::updateContentWidget(FeaturePtr theFeature) { - int aS = myWidgets.size(); foreach(ModuleBase_ModelWidget* eachWidget, myWidgets) { eachWidget->setFeature(theFeature); eachWidget->restoreValue(); } - // the repaint is used here to immediatelly react in GUI to the values change. + // the repaint is used here to immediately react in GUI to the values change. repaint(); } - void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget) { - QObject* aSender = sender(); ModuleBase_ModelWidget* aNextWidget = 0; QList::const_iterator anIt = myWidgets.begin(), aLast = myWidgets.end(); bool isFoundWidget = false; @@ -146,8 +145,11 @@ void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget) } isFoundWidget = (*anIt) == theWidget; } - myActiveWidget = aNextWidget; - emit widgetActivated(myActiveWidget); + // Normaly focusTo is enough to activate widget + // here is a special case on mouse click in the viewer + if(aNextWidget == NULL) { + activateWidget(NULL); + } } void XGUI_PropertyPanel::activateNextWidget() @@ -160,3 +162,15 @@ void XGUI_PropertyPanel::setAcceptEnabled(bool isEnabled) QPushButton* anOkBtn = findChild(XGUI::PROP_PANEL_OK); anOkBtn->setEnabled(isEnabled); } + +void XGUI_PropertyPanel::activateWidget(ModuleBase_ModelWidget* theWidget) +{ + if(myActiveWidget) { + myActiveWidget->setHighlighted(false); + } + if(theWidget) { + theWidget->setHighlighted(true); + } + myActiveWidget = theWidget; + emit widgetActivated(theWidget); +} diff --git a/src/XGUI/XGUI_PropertyPanel.h b/src/XGUI/XGUI_PropertyPanel.h index b29d51579..ebd529d11 100644 --- a/src/XGUI/XGUI_PropertyPanel.h +++ b/src/XGUI/XGUI_PropertyPanel.h @@ -51,12 +51,19 @@ Q_OBJECT // Enables / disables "ok" ("accept") button void setAcceptEnabled(bool); -signals: + protected slots: + // Makes the given widget active, highlights it and removes + // highlighting from the previous active widget + // emits widgetActivated(theWidget) signal + void activateWidget(ModuleBase_ModelWidget* theWidget); + + signals: /// Signal about the point 2d set to the feature /// \param the feature /// \param the attribute of the feature void storedPoint2D(ObjectPtr theFeature, const std::string& theAttribute); + private: QWidget* myCustomWidget; QList myWidgets; diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index d39e31359..1b91cb3dc 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -111,13 +111,20 @@ void XGUI_Selection::selectedAISObjects(AIS_ListOfInteractive& theList) const } //************************************************************** -void XGUI_Selection::selectedShapes(NCollection_List& theList) const +void XGUI_Selection::selectedShapes(NCollection_List& theList, + std::list& theOwners) const { theList.Clear(); Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { TopoDS_Shape aShape = aContext->SelectedShape(); - if (!aShape.IsNull()) + if (!aShape.IsNull()) { theList.Append(aShape); + Handle(SelectMgr_EntityOwner) aEO = aContext->SelectedOwner(); + Handle(AIS_InteractiveObject) anObj = + Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable()); + ObjectPtr anObject = myWorkshop->displayer()->getObject(anObj); + theOwners.push_back(anObject); + } } } diff --git a/src/XGUI/XGUI_Selection.h b/src/XGUI/XGUI_Selection.h index b67adbc52..5f399a7ee 100644 --- a/src/XGUI/XGUI_Selection.h +++ b/src/XGUI/XGUI_Selection.h @@ -52,7 +52,8 @@ class XGUI_EXPORT XGUI_Selection : public ModuleBase_ISelection virtual void selectedAISObjects(AIS_ListOfInteractive& theList) const; //! Returns list of currently selected shapes - virtual void selectedShapes(NCollection_List& theList) const; + virtual void selectedShapes(NCollection_List& theShapes, + std::list& theOwners) const; private: XGUI_Workshop* myWorkshop; diff --git a/src/XGUI/XGUI_Viewer.cpp b/src/XGUI/XGUI_Viewer.cpp index a2864475b..3a8149615 100644 --- a/src/XGUI/XGUI_Viewer.cpp +++ b/src/XGUI/XGUI_Viewer.cpp @@ -551,10 +551,10 @@ void XGUI_Viewer::onMouseReleased(XGUI_ViewWindow* theWindow, QMouseEvent* theEv if (myStartPnt == myEndPnt) { // the MoveTo is necessary for the second click in the same point. Otherwise the selection is lost. - Handle(V3d_View) aView3d = theWindow->viewPort()->getView(); - if (!aView3d.IsNull()) { - myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView3d); - } + //Handle(V3d_View) aView3d = theWindow->viewPort()->getView(); + //if (!aView3d.IsNull()) { + // myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView3d); + //} if (aHasShift && myMultiSelectionEnabled) myAISContext->ShiftSelect(); else diff --git a/src/XGUI/XGUI_ViewerFilters.cpp b/src/XGUI/XGUI_ViewerFilters.cpp deleted file mode 100644 index 6efd9143e..000000000 --- a/src/XGUI/XGUI_ViewerFilters.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// File: XGUI_ViewerFilters.cpp -// Created: 07 Okt 2014 -// Author: Vitaly SMETANNIKOV - - -#include "XGUI_ViewerFilters.h" -#include "XGUI_Displayer.h" - -#include -#include - -#include - -IMPLEMENT_STANDARD_HANDLE(XGUI_ShapeDocumentFilter, SelectMgr_Filter); -IMPLEMENT_STANDARD_RTTIEXT(XGUI_ShapeDocumentFilter, SelectMgr_Filter); - - -//TODO (VSV): Check bug in OCCT: Filter result is ignored (bug25340) -Standard_Boolean XGUI_ShapeDocumentFilter::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const -{ - if (theOwner->HasSelectable()) { - Handle(AIS_InteractiveObject) aAisObj = - Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable()); - if (!aAisObj.IsNull()) { - ObjectPtr aObj = myDisplayer->getObject(aAisObj); - if (aObj) { - DocumentPtr aDoc = aObj->document(); - SessionPtr aMgr = ModelAPI_Session::get(); - return (aDoc == aMgr->activeDocument()) || (aDoc == aMgr->moduleDocument()); - } - } - } - return Standard_False; -} \ No newline at end of file diff --git a/src/XGUI/XGUI_ViewerFilters.h b/src/XGUI/XGUI_ViewerFilters.h deleted file mode 100644 index f30f400ae..000000000 --- a/src/XGUI/XGUI_ViewerFilters.h +++ /dev/null @@ -1,31 +0,0 @@ -// File: XGUI_ViewerFilters.h -// Created: 07 Okt 2014 -// Author: Vitaly SMETANNIKOV - - -#ifndef XGUI_ViewerFilters_H -#define XGUI_ViewerFilters_H - -#include -#include - - -class XGUI_Displayer; - -DEFINE_STANDARD_HANDLE(XGUI_ShapeDocumentFilter, SelectMgr_Filter); - -class XGUI_ShapeDocumentFilter: public SelectMgr_Filter -{ -public: - Standard_EXPORT XGUI_ShapeDocumentFilter(XGUI_Displayer* myDisp): SelectMgr_Filter(), - myDisplayer(myDisp) {} - - Standard_EXPORT virtual Standard_Boolean IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const; - - DEFINE_STANDARD_RTTI(XGUI_ShapeDocumentFilter) - -private: - XGUI_Displayer* myDisplayer; -}; - -#endif \ No newline at end of file diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 6df891cd4..8a60b2e4a 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -416,9 +416,15 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const boost::shared_ptr aObjects = theMsg->objects(); std::set::const_iterator aIt; + QIntList aModes; for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { ObjectPtr aObj = (*aIt); - if (!aObj->data() || !aObj->data()->isValid() || aObj->document()->isConcealed(aObj)) + bool aHide = !aObj->data() || !aObj->data()->isValid(); + if (!aHide) { // check that this is not hidden result + ResultPtr aRes = boost::dynamic_pointer_cast(aObj); + aHide = aRes && aRes->isConcealed(); + } + if (aHide) myDisplayer->erase(aObj, false); else { if (myDisplayer->isVisible(aObj)) { @@ -427,7 +433,7 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const boost::shared_ptrcurrentOperation(); if (!aOperation->hasObject(aObj)) if (!myDisplayer->isActive(aObj)) - myDisplayer->activate(aObj); + myDisplayer->activate(aObj, aModes); } } else { if (myOperationMgr->hasOperation()) { @@ -462,8 +468,7 @@ void XGUI_Workshop::onFeatureCreatedMsg(const boost::shared_ptrhasOperation()) { ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); - if (!(*aIt)->document()->isConcealed(*aIt) && - aOperation->hasObject(*aIt)) { // Display only current operation results + if (aOperation->hasObject(*aIt)) { // Display only current operation results myDisplayer->display(*aIt, false); isDisplayed = true; } @@ -1010,10 +1015,6 @@ void XGUI_Workshop::createDockWidgets() connect(aCancelBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onAbortOperation())); connect(myPropertyPanel, SIGNAL(keyReleased(QKeyEvent*)), myOperationMgr, SLOT(onKeyReleased(QKeyEvent*))); - //connect(myPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), myOperationMgr, - // SLOT(onWidgetActivated(ModuleBase_ModelWidget*))); - //connect(myOperationMgr, SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)), myPropertyPanel, - // SLOT(onActivateNextWidget(ModuleBase_ModelWidget*))); connect(myOperationMgr, SIGNAL(operationValidated(bool)), myPropertyPanel, SLOT(setAcceptEnabled(bool)));