]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge tag 'V_1.3.1' into HEAD
authorspo <sergey.pokhodenko@opencascade.com>
Tue, 4 Aug 2015 12:21:08 +0000 (15:21 +0300)
committerspo <sergey.pokhodenko@opencascade.com>
Tue, 4 Aug 2015 12:21:08 +0000 (15:21 +0300)
78 files changed:
src/Config/CMakeLists.txt
src/Config/Config_DataModelReader.cpp [new file with mode: 0644]
src/Config/Config_DataModelReader.h [new file with mode: 0644]
src/Config/Config_Keywords.h
src/Config/dataModel.xml [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Movement.cpp
src/FeaturesPlugin/FeaturesPlugin_Partition.cpp [new file with mode: 0755]
src/FeaturesPlugin/FeaturesPlugin_Partition.h [new file with mode: 0755]
src/FeaturesPlugin/FeaturesPlugin_Placement.cpp
src/FeaturesPlugin/FeaturesPlugin_Placement.h
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp
src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp
src/FeaturesPlugin/partition_widget.xml [new file with mode: 0755]
src/FeaturesPlugin/placement_widget.xml
src/FeaturesPlugin/plugin-Features.xml
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Transform.h [new file with mode: 0644]
src/Model/CMakeLists.txt
src/Model/Model_BodyBuilder.cpp [new file with mode: 0755]
src/Model/Model_BodyBuilder.h [new file with mode: 0755]
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/Model/Model_ResultBody.cpp
src/Model/Model_ResultBody.h
src/Model/Model_ResultCompSolid.cpp [new file with mode: 0755]
src/Model/Model_ResultCompSolid.h [new file with mode: 0755]
src/ModelAPI/CMakeLists.txt
src/ModelAPI/ModelAPI_BodyBuilder.cpp [new file with mode: 0755]
src/ModelAPI/ModelAPI_BodyBuilder.h [new file with mode: 0755]
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Entity.h [new file with mode: 0644]
src/ModelAPI/ModelAPI_Object.h
src/ModelAPI/ModelAPI_ResultBody.cpp
src/ModelAPI/ModelAPI_ResultBody.h
src/ModelAPI/ModelAPI_ResultCompSolid.cpp [new file with mode: 0755]
src/ModelAPI/ModelAPI_ResultCompSolid.h [new file with mode: 0755]
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_IDocumentDataModel.h
src/ModuleBase/ModuleBase_IconFactory.cpp [new file with mode: 0644]
src/ModuleBase/ModuleBase_IconFactory.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_Tools.cpp
src/ModuleBase/ModuleBase_Tools.h
src/ModuleBase/ModuleBase_WidgetFactory.cpp
src/ParametersPlugin/ParametersPlugin_Parameter.cpp
src/ParametersPlugin/ParametersPlugin_Parameter.h
src/ParametersPlugin/Test/TestParameterChangeValue.py
src/ParametersPlugin/Test/TestParameterRename.py
src/PartSet/CMakeLists.txt
src/PartSet/PartSet_IconFactory.cpp [new file with mode: 0644]
src/PartSet/PartSet_IconFactory.h [new file with mode: 0644]
src/PartSet/PartSet_MenuMgr.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/partition.png [new file with mode: 0755]
src/XGUI/CMakeLists.txt
src/XGUI/XGUI_DataModel.cpp [new file with mode: 0644]
src/XGUI/XGUI_DataModel.h [new file with mode: 0644]
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_ObjectsBrowser.cpp
src/XGUI/XGUI_ObjectsBrowser.h
src/XGUI/XGUI_Tools.cpp
src/XGUI/XGUI_Tools.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 0837555e7350b4e8419e7a660d8f0c6f9879cf46..1dfbae0b13590897a96d831bbb2fbc3be44f8cd3 100644 (file)
@@ -23,6 +23,7 @@ SET(PROJECT_HEADERS
   Config_AttributeMessage.h
   Config_SelectionFilterMessage.h
   Config_ValidatorReader.h
+  Config_DataModelReader.h
  )
  
 SET(PROJECT_SOURCES
@@ -40,10 +41,12 @@ SET(PROJECT_SOURCES
   Config_AttributeMessage.cpp
   Config_SelectionFilterMessage.cpp
   Config_ValidatorReader.cpp
+  Config_DataModelReader.cpp
 )
 
 SET(XML_RESOURCES
   plugins.xml
+  dataModel.xml
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/Config/Config_DataModelReader.cpp b/src/Config/Config_DataModelReader.cpp
new file mode 100644 (file)
index 0000000..e9113e8
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * Config_DataModelReader.cpp
+ *
+ *  Created on: Jul 21, 2015
+ *      Author: vsv
+ */
+
+#include "Config_DataModelReader.h"
+#include <Config_Keywords.h>
+#include "Config_Common.h"
+
+#include <Events_Error.h>
+
+
+Config_DataModelReader::Config_DataModelReader()
+    : Config_XMLReader(DATAMODEL_FILE), isRootReading(true), myIsResultLink(false)
+{
+}
+
+Config_DataModelReader::~Config_DataModelReader()
+{
+}
+
+void Config_DataModelReader::processNode(xmlNodePtr theNode)
+{
+  if (isNode(theNode, NODE_FOLDER, NULL)) {
+    std::string aName = getProperty(theNode, FOLDER_NAME);
+    std::string aGroupType = getProperty(theNode, GROUP_TYPE);
+    if (aName.empty() || aGroupType.empty())
+      Events_Error::send("Reading dataModel.xml: wrong folder definition");
+   
+    std::string aIcon = getProperty(theNode, NODE_ICON);
+    std::string aEmpty = getProperty(theNode, SHOW_EMPTY);
+    std::string::iterator aIt;
+    for (aIt = aEmpty.begin(); aIt != aEmpty.end(); aIt++) {
+      (*aIt) = toupper(*aIt);
+    }
+    bool aIsEmpty = (aEmpty == "FALSE")? false : true;
+
+   if (isRootReading) {
+      myRootFolderNames.push_back(aName);
+      myRootFolderTypes.push_back(aGroupType);
+      myRootFolderIcons.push_back(aIcon);
+      myRootFolderShowEmpty.push_back(aIsEmpty);
+   } else {
+      mySubFolderNames.push_back(aName);
+      mySubFolderTypes.push_back(aGroupType);
+      mySubFolderIcons.push_back(aIcon);
+      mySubFolderShowEmpty.push_back(aIsEmpty);
+   }
+  } else if  (isNode(theNode, ROOT_DOCUMENT, NULL)) {
+    isRootReading = true;
+    myRootTypes = getProperty(theNode, GROUP_TYPE);
+  } else if  (isNode(theNode, SUB_DOCUMENT, NULL)) {
+    isRootReading = false;
+    mySubTypes = getProperty(theNode, GROUP_TYPE);
+    std::string isResult = getProperty(theNode, LINK_ITEM);
+    std::string::iterator aIt;
+    for (aIt = isResult.begin(); aIt != isResult.end(); aIt++) {
+      (*aIt) = toupper(*aIt);
+    }
+    myIsResultLink = (isResult == "TRUE")? true : false;
+  }
+}
+
+int Config_DataModelReader::rootFolderId(std::string theType) const
+{
+  std::vector<std::string>::const_iterator aIt;
+  int aId;
+  for (aIt = myRootFolderTypes.cbegin(), aId = 0; aIt != myRootFolderTypes.cend(); ++aIt, ++aId) {
+    if ((*aIt) == theType)
+      return aId;
+  }
+  return -1;
+}
+
+int Config_DataModelReader::subFolderId(std::string theType) const
+{
+  std::vector<std::string>::const_iterator aIt;
+  int aId;
+  for (aIt = mySubFolderTypes.cbegin(), aId = 0; aIt != mySubFolderTypes.cend(); ++aIt, ++aId) {
+    if ((*aIt) == theType)
+      return aId;
+  }
+  return -1;
+}
diff --git a/src/Config/Config_DataModelReader.h b/src/Config/Config_DataModelReader.h
new file mode 100644 (file)
index 0000000..d17f54e
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * Config_DataModelReader.h
+ *
+ *  Created on: Jul 21, 2015
+ *      Author: vsv
+ */
+
+#ifndef CONFIG_DATAMODELREADER_H_
+#define CONFIG_DATAMODELREADER_H_
+
+#include <Config_def.h>
+#include <Config_XMLReader.h>
+
+#include <vector>
+#include <string>
+
+/*!
+ * \class Config_DataModelReader
+ * \ingroup Config
+ * \brief Class that reads data model definition XML for
+ * further processing in the XGUI_DataModel
+ */
+class Config_DataModelReader : public Config_XMLReader
+{
+ public:
+  /*!
+   * Constructor
+   * \param theXmlFile - full path to the xml file which will be processed by the reader
+   */
+  CONFIG_EXPORT Config_DataModelReader();
+  CONFIG_EXPORT virtual ~Config_DataModelReader();
+
+  // ROOT folders propertiues *****************
+  /// Returns name of type of tree items in root
+  CONFIG_EXPORT std::string rootType() const { return myRootTypes; }
+
+  /// Returns number of folders under root 
+  CONFIG_EXPORT int rootFoldersNumber() const { return myRootFolderNames.size(); }
+
+  /// Returns name of the folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string rootFolderName(int theId) const { return myRootFolderNames[theId]; }
+
+  /// Returns data type in the folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string rootFolderType(int theId) const { return myRootFolderTypes[theId]; }
+
+  /// Returns icon of a folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string rootFolderIcon(int theId) const { return myRootFolderIcons[theId]; }
+
+  /// Returns id of a folder containing the given type
+  /// \param theType type of objects in folder
+  CONFIG_EXPORT int rootFolderId(std::string theType) const;
+
+  /// Returns true if the folder can be shown without items
+  /// \param theId id of the folder
+  CONFIG_EXPORT bool rootShowEmpty(int theId) const { return myRootFolderShowEmpty[theId]; }
+
+
+
+  // SUB folders propertiues ********************
+  /// Returns name of type of tree items in sub document
+  CONFIG_EXPORT std::string subType() const { return mySubTypes; }
+
+  /// Returns number of folders under sub document 
+  CONFIG_EXPORT int subFoldersNumber() const { return mySubFolderNames.size(); }
+
+  /// Returns name of the folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string subFolderName(int theId) const { return mySubFolderNames[theId]; }
+
+  /// Returns data type in the folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string subFolderType(int theId) const { return mySubFolderTypes[theId]; }
+
+  /// Returns icon of a folder by its Id
+  /// \param theId id of the folder
+  CONFIG_EXPORT std::string subFolderIcon(int theId) const { return mySubFolderIcons[theId]; }
+
+  /// Returns true if the folder can be shown without items
+  /// \param theId id of the folder
+  CONFIG_EXPORT bool subShowEmpty(int theId) const { return mySubFolderShowEmpty[theId]; }
+
+  /// Returns id of a folder containing the given type
+  /// \param theType type of objects in folder
+  CONFIG_EXPORT int subFolderId(std::string theType) const;
+
+  /// Returns true if the sub-document data tree has to be attached to Part Result node
+  /// Otherwise it has to be connected to Part feature node
+  CONFIG_EXPORT bool isAttachToResult() const { return myIsResultLink; }
+
+protected:
+  /// Overloaded method. Defines how to process each node
+  virtual void processNode(xmlNodePtr theNode);
+
+private:
+  bool isRootReading;
+
+  /// Root document data
+  std::vector<std::string> myRootFolderNames;
+  std::vector<std::string> myRootFolderTypes;
+  std::vector<std::string> myRootFolderIcons;
+  std::vector<bool> myRootFolderShowEmpty;
+
+  std::string myRootTypes;
+
+  /// Sub document data
+  std::vector<std::string> mySubFolderNames;
+  std::vector<std::string> mySubFolderTypes;
+  std::vector<std::string> mySubFolderIcons;
+  std::vector<bool> mySubFolderShowEmpty;
+
+  bool myIsResultLink;
+  std::string mySubTypes;
+};
+
+
+#endif
\ No newline at end of file
index 96adf95b2f2cb66c55499d41b838a73e88cd415d..f16d08ed57cea9ae83f94654b9a7ac2f2e56d558 100644 (file)
@@ -95,6 +95,17 @@ const static char* PLUGIN_DEPENDENCY = "dependency";
 const static char* PLUGIN_PLATFORM_SALOME = "salome";
 const static char* PLUGIN_PLATFORM_NEWGEOM = "openparts";
 
-
+/*
+ * Hardcoded xml entities of dataModel.xml
+ */
+const static char* DATAMODEL_FILE = "dataModel.xml";
+const static char* NODE_FOLDER = "folder";
+const static char* FOLDER_NAME = "name";
+const static char* GROUP_TYPE = "group_type";
+const static char* ROOT_DOCUMENT = "root_document";
+const static char* SUB_DOCUMENT = "sub_document";
+const static char* NODE_ICON = "icon";
+const static char* SHOW_EMPTY = "show_empty";
+const static char* LINK_ITEM = "from_result";
 
 #endif /* CONFIG_KEYWORDS_H_ */
diff --git a/src/Config/dataModel.xml b/src/Config/dataModel.xml
new file mode 100644 (file)
index 0000000..103879b
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+<data_model>
+    <root_document group_type="Features">
+        <folder name="Parameters" group_type="Parameters" icon=":pictures/params_folder.png"/>
+        <folder name="Constructions" group_type="Construction" icon=":pictures/constr_folder.png"/>
+        <folder name="Parts" group_type="Parts" icon=":pictures/constr_folder.png"/>
+    </root_document>
+    <sub_document group_type="Features" from_result="false">
+        <folder name="Parameters" group_type="Parameters" icon=":pictures/params_folder.png"/>
+        <folder name="Constructions" group_type="Construction" icon=":pictures/constr_folder.png"/>
+        <folder name="Bodies" group_type="Bodies" icon=":pictures/constr_folder.png"/>
+        <folder name="Groups" group_type="Groups" icon=":pictures/constr_folder.png" show_empty="false"/>
+    </sub_document>
+</data_model>
\ No newline at end of file
index e7e9e1b981bd6dbdb76bf94ada1c5e2c1136b4cc..e2d29c9c85ad7b2c8255a96617f8e068d9c1e5b0 100644 (file)
@@ -17,6 +17,7 @@
 #include <Config_PropManager.h>
 
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Object.h>
@@ -112,9 +113,9 @@ void ExchangePlugin_ImportFeature::loadNamingDS(
     std::shared_ptr<ModelAPI_ResultBody> theResultBody)
 {
   //load result
-  theResultBody->store(theGeomShape);
+  theResultBody->getBodyBuilder()->store(theGeomShape);
 
   int aTag(1);
   std::string aNameMS = "Shape";
-  theResultBody->loadFirstLevel(theGeomShape, aNameMS, aTag);
+  theResultBody->getBodyBuilder()->loadFirstLevel(theGeomShape, aNameMS, aTag);
 }
index 77f89e52c6e2c17682c78aba1ec3017b81cfac0d..1fa7948da49c58c12a79e10e47df1c28cad9713b 100644 (file)
@@ -12,6 +12,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_Movement.h
     FeaturesPlugin_Boolean.h
     FeaturesPlugin_Group.h
+    FeaturesPlugin_Partition.h
     FeaturesPlugin_Placement.h
     FeaturesPlugin_CompositeBoolean.h
     FeaturesPlugin_ExtrusionBoolean.h
@@ -30,6 +31,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Movement.cpp
     FeaturesPlugin_Boolean.cpp
     FeaturesPlugin_Group.cpp
+    FeaturesPlugin_Partition.cpp
     FeaturesPlugin_Placement.cpp
     FeaturesPlugin_CompositeBoolean.cpp
     FeaturesPlugin_ExtrusionBoolean.cpp
@@ -52,6 +54,7 @@ SET(XML_RESOURCES
   movement_widget.xml
   boolean_widget.xml
   group_widget.xml
+  partition_widget.xml
   placement_widget.xml
 )
 
index 7fb46f2c998cac3abd103ee68124d04c81f45a1b..7f414c613d81e747b8651f91ce16ee372d16cb9b 100644 (file)
@@ -10,6 +10,7 @@
 #include <ModelAPI_Document.h>
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_Session.h>
@@ -198,23 +199,24 @@ void FeaturesPlugin_Boolean::LoadNamingDS(std::shared_ptr<ModelAPI_ResultBody> t
                                           const ListOfShape& theTools,
                                           const GeomAlgoAPI_Boolean& theAlgo)
 {
+  ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder();
   //load result
   if(theBaseShape->isEqual(theAlgo.shape())) {
-    theResultBody->store(theAlgo.shape());
+    aResultBuilder->store(theAlgo.shape());
   } else {
-    theResultBody->storeModified(theBaseShape, theAlgo.shape(), _SUBSOLIDS_TAG);
+    aResultBuilder->storeModified(theBaseShape, theAlgo.shape(), _SUBSOLIDS_TAG);
 
     GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
 
     std::string aModName = "Modified";
-    theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), theBaseShape, FACE,
+    aResultBuilder->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), theBaseShape, FACE,
                                                _MODIFY_TAG, aModName, *theAlgo.mapOfShapes().get());
-    theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), theBaseShape, FACE, _DELETED_TAG);
+    aResultBuilder->loadDeletedShapes(theAlgo.makeShape().get(), theBaseShape, FACE, _DELETED_TAG);
 
     for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
-      theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), *anIter, FACE,
+      aResultBuilder->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), *anIter, FACE,
                                                  _MODIFY_TAG, aModName, *theAlgo.mapOfShapes().get());
-      theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), *anIter, FACE, _DELETED_TAG);
+      aResultBuilder->loadDeletedShapes(theAlgo.makeShape().get(), *anIter, FACE, _DELETED_TAG);
     }
   }
 }
index 56323a20b7fcef68cf61b5c661473016c5dd4f4e..6bc4ae5d04d19406d8c93891cb7b4fe164f1ba14 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultConstruction.h>
 
@@ -204,9 +205,10 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_Resu
                                                    const ListOfShape& theTools,
                                                    const GeomAlgoAPI_Boolean& theAlgo)
 {
+  ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder();
   //load result
   if(theBaseShape->isEqual(theAlgo.shape())) {
-    theResultBody->store(theAlgo.shape());
+    aResultBuilder->store(theAlgo.shape());
   } else {
     const int aGenTag = 1;
     const int aFrTag = 2;
@@ -220,7 +222,7 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_Resu
     const std::string aFrName = "FromFace";
     const std::string aToName = "ToFace";
 
-    theResultBody->storeModified(theBaseShape, theAlgo.shape(), aSubsolidsTag);
+    aResultBuilder->storeModified(theBaseShape, theAlgo.shape(), aSubsolidsTag);
 
     ListOfShape::const_iterator aFaceIter = theFaces.begin();
     std::list<std::shared_ptr<GeomAPI_Interface>>::const_iterator aSolidsAlgosIter = theSolidsAlgos.begin();
@@ -233,14 +235,14 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_Resu
       if(std::dynamic_pointer_cast<GeomAlgoAPI_Prism>(*aSolidsAlgosIter)) {
         std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo = std::dynamic_pointer_cast<GeomAlgoAPI_Prism>(*aSolidsAlgosIter);
         aSubShapes = aPrismAlgo->mapOfShapes();
-        theResultBody->loadAndOrientGeneratedShapes(aPrismAlgo->makeShape().get(), *aFaceIter, GeomAPI_Shape::EDGE, aGenTag,
+        aResultBuilder->loadAndOrientGeneratedShapes(aPrismAlgo->makeShape().get(), *aFaceIter, GeomAPI_Shape::EDGE, aGenTag,
                                                     aLatName, *aSubShapes.get());
         aFromFace = aPrismAlgo->firstShape();
         aToFace = aPrismAlgo->lastShape();
       } else if(std::dynamic_pointer_cast<GeomAlgoAPI_Revolution>(*aSolidsAlgosIter)) {
         std::shared_ptr<GeomAlgoAPI_Revolution> aRevolAlgo = std::dynamic_pointer_cast<GeomAlgoAPI_Revolution>(*aSolidsAlgosIter);
         aSubShapes = aRevolAlgo->mapOfShapes();
-        theResultBody->loadAndOrientGeneratedShapes(aRevolAlgo->makeShape().get(), *aFaceIter, GeomAPI_Shape::EDGE, aGenTag,
+        aResultBuilder->loadAndOrientGeneratedShapes(aRevolAlgo->makeShape().get(), *aFaceIter, GeomAPI_Shape::EDGE, aGenTag,
                                                     aLatName, *aSubShapes.get());
         aFromFace = aRevolAlgo->firstShape();
         aToFace = aRevolAlgo->lastShape();
@@ -251,7 +253,7 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_Resu
         if(aSubShapes->isBound(aFromFace)) {
           aFromFace = aSubShapes->find(aFromFace);
         }
-        theResultBody->generated(aFromFace, aFrName, aFrTag);
+        aResultBuilder->generated(aFromFace, aFrName, aFrTag);
       }
 
       //Insert top face
@@ -259,18 +261,18 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptr<ModelAPI_Resu
         if (aSubShapes->isBound(aToFace)) {
           aToFace = aSubShapes->find(aToFace);
         }
-        theResultBody->generated(aToFace, aToName, aToTag);
+        aResultBuilder->generated(aToFace, aToName, aToTag);
       }
     }
 
-    theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), theBaseShape, GeomAPI_Shape::FACE,
+    aResultBuilder->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), theBaseShape, GeomAPI_Shape::FACE,
                                                aModTag, aModName, *theAlgo.mapOfShapes().get());
-    theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), theBaseShape, GeomAPI_Shape::FACE, aDelTag);
+    aResultBuilder->loadDeletedShapes(theAlgo.makeShape().get(), theBaseShape, GeomAPI_Shape::FACE, aDelTag);
 
     for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
-      theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), *anIter, GeomAPI_Shape::FACE,
+      aResultBuilder->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), *anIter, GeomAPI_Shape::FACE,
                                                  aModTag, aModName, *theAlgo.mapOfShapes().get());
-      theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), *anIter, GeomAPI_Shape::FACE, aDelTag);
+      aResultBuilder->loadDeletedShapes(theAlgo.makeShape().get(), *anIter, GeomAPI_Shape::FACE, aDelTag);
     }
   }
 }
index d473f00961dfdb21f58c9b9e82398b376b1b1165..26cb739e9ee9c01cb887505c624732b10f35c92a 100644 (file)
@@ -6,11 +6,13 @@
 
 #include <FeaturesPlugin_Extrusion.h>
 
+#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelection.h>
@@ -26,6 +28,9 @@
 #define _LAST_TAG 3
 #define EDGE 6
 
+//#define DEBUG_COMPSOLID
+//#define DEBUG_COMPSOLID_SHAPE
+
 //=================================================================================================
 FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion()
 {
@@ -95,6 +100,16 @@ void FeaturesPlugin_Extrusion::execute()
 
   // for each selected face generate a result
   int anIndex = 0, aResultIndex = 0;
+#ifdef DEBUG_COMPSOLID
+  ResultCompSolidPtr aCompSolidResult = document()->createCompSolid(data(), aResultIndex);
+  setResult(aCompSolidResult, aResultIndex);
+  aResultIndex++;
+#endif
+#ifdef DEBUG_COMPSOLID_SHAPE
+  bool aFirstShapeInCompsolid = aFaceRefs->size() > 0;
+  if (aFirstShapeInCompsolid)
+    aResultIndex--;
+#endif
   for(; anIndex < aFaceRefs->size(); anIndex++) {
     std::shared_ptr<ModelAPI_AttributeSelection> aFaceRef = aFaceRefs->value(anIndex);
     ResultPtr aContextRes = aFaceRef->context();
@@ -118,9 +133,24 @@ void FeaturesPlugin_Extrusion::execute()
         break;
       }
     }
-
     for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
-      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      ResultBodyPtr aResultBody;
+
+#ifdef DEBUG_COMPSOLID_SHAPE
+      if (aFirstShapeInCompsolid && anIndex == 0)
+        aResultBody = aCompSolidResult;
+      else {
+#endif
+
+#ifdef DEBUG_COMPSOLID
+      aResultBody = aCompSolidResult->addResult(aResultIndex);
+#else
+      aResultBody = document()->createBody(data(), aResultIndex);
+#endif
+
+#ifdef DEBUG_COMPSOLID_SHAPE
+      }
+#endif
       std::shared_ptr<GeomAPI_Shape> aBaseShape;
       if (aFacesNum == -1) {
         aBaseShape = aValueFace;
@@ -148,7 +178,6 @@ void FeaturesPlugin_Extrusion::execute()
       }
       //LoadNamingDS
       LoadNamingDS(aFeature, aResultBody, aBaseShape, aContext);
-
       setResult(aResultBody, aResultIndex);
       aResultIndex++;
 
@@ -167,16 +196,17 @@ void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Prism& theFeature,
                                             std::shared_ptr<GeomAPI_Shape> theContext)
 {
   //load result
+  ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder();
   if(theBasis->isEqual(theContext))
-    theResultBody->store(theFeature.shape());
+    aResultBuilder->store(theFeature.shape());
   else
-    theResultBody->storeGenerated(theBasis, theFeature.shape());
+    aResultBuilder->storeGenerated(theBasis, theFeature.shape());
 
   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theFeature.mapOfShapes();
 
   //Insert lateral face : Face from Edge
   std::string aLatName = "LateralFace";
-  theResultBody->loadAndOrientGeneratedShapes(theFeature.makeShape().get(), theBasis, EDGE,_LATERAL_TAG, aLatName, *aSubShapes);
+  aResultBuilder->loadAndOrientGeneratedShapes(theFeature.makeShape().get(), theBasis, EDGE,_LATERAL_TAG, aLatName, *aSubShapes);
 
   //Insert bottom face
   std::string aBotName = "BottomFace";
@@ -185,7 +215,7 @@ void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Prism& theFeature,
     if(aSubShapes->isBound(aBottomFace)) {
       aBottomFace = aSubShapes->find(aBottomFace);
     }
-    theResultBody->generated(aBottomFace, aBotName, _FIRST_TAG);
+    aResultBuilder->generated(aBottomFace, aBotName, _FIRST_TAG);
   }
 
   //Insert top face
@@ -195,6 +225,6 @@ void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Prism& theFeature,
     if (aSubShapes->isBound(aTopFace)) {
       aTopFace = aSubShapes->find(aTopFace);
     }
-    theResultBody->generated(aTopFace, aTopName, _LAST_TAG);
+    aResultBuilder->generated(aTopFace, aTopName, _LAST_TAG);
   }
 }
index ca4b8a579b5ec2febefb0378692021732a71d939..bebbcd735c6ee6584d19a427e01de07c98d04628 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Session.h>
@@ -128,15 +129,16 @@ void FeaturesPlugin_Movement::LoadNamingDS(const GeomAlgoAPI_Movement& theMoveme
                                            std::shared_ptr<ModelAPI_ResultBody> theResultBody,
                                            std::shared_ptr<GeomAPI_Shape> theBaseShape)
 {
+  ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder();
   // Store result.
-  theResultBody->storeModified(theBaseShape, theMovementAlgo.shape());
+  aResultBuilder->storeModified(theBaseShape, theMovementAlgo.shape());
 
   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theMovementAlgo.mapOfShapes();
 
   int aMovedTag = 1;
   std::string aMovedName = "Moved";
-  theResultBody->loadAndOrientModifiedShapes(theMovementAlgo.makeShape().get(),
-                                             theBaseShape, GeomAPI_Shape::FACE,
-                                             aMovedTag, aMovedName, *aSubShapes.get());
+  aResultBuilder->loadAndOrientModifiedShapes(theMovementAlgo.makeShape().get(),
+                                              theBaseShape, GeomAPI_Shape::FACE,
+                                              aMovedTag, aMovedName, *aSubShapes.get());
 
 }
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp
new file mode 100755 (executable)
index 0000000..284acd1
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Partition.cpp
+// Created:     31 Jul 2015
+// Author:      Natalia ERMOLAEVA
+
+#include "FeaturesPlugin_Partition.h"
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_BodyBuilder.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+//=================================================================================================
+FeaturesPlugin_Partition::FeaturesPlugin_Partition()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_Partition::initAttributes()
+{
+
+  AttributeSelectionListPtr aSelection = 
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+    FeaturesPlugin_Partition::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+  aSelection->setSelectionType("SOLID");
+
+  aSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+    FeaturesPlugin_Partition::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+  aSelection->setSelectionType("SOLID");
+
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Partition::getShape(const std::string& theAttrName)
+{
+  std::shared_ptr<ModelAPI_AttributeReference> aObjRef = std::dynamic_pointer_cast<
+      ModelAPI_AttributeReference>(data()->attribute(theAttrName));
+  if (aObjRef) {
+    std::shared_ptr<ModelAPI_ResultBody> aConstr = std::dynamic_pointer_cast<
+        ModelAPI_ResultBody>(aObjRef->value());
+    if (aConstr)
+      return aConstr->shape();
+  }
+  return std::shared_ptr<GeomAPI_Shape>();
+}
+
+//=================================================================================================
+void FeaturesPlugin_Partition::execute()
+{
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.h b/src/FeaturesPlugin/FeaturesPlugin_Partition.h
new file mode 100755 (executable)
index 0000000..444d3e8
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Partition.h
+// Created:     31 Jul 2015
+// Author:      Natalia ERMOLAEVA
+
+#ifndef FeaturesPlugin_Partition_H_
+#define FeaturesPlugin_Partition_H_
+
+#include "FeaturesPlugin.h"
+#include <ModelAPI_Feature.h>
+
+/**\class FeaturesPlugin_Partition
+ * \ingroup Plugins
+ * \brief Feature for applying of Partition operations on Solids. Partition makes conjunctional
+ * faces of solids as shared. The result of partitions is a compsolid.
+ * Main objects are solids, tool objects are solids or faces
+ */
+class FeaturesPlugin_Partition : public ModelAPI_Feature
+{
+public:
+  /// Extrusion kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("Partition");
+    return MY_ID;
+  }
+  /// attribute name of referenced object
+  inline static const std::string& OBJECT_LIST_ID()
+  {
+    static const std::string MY_OBJECT_LIST_ID("main_objects");
+    return MY_OBJECT_LIST_ID;
+  }
+  /// attribute name of tool object
+  inline static const std::string& TOOL_LIST_ID()
+  {
+    static const std::string MY_TOOL_LIST_ID("tool_objects");
+    return MY_TOOL_LIST_ID;
+  }
+
+  /// Returns the kind of a feature
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Partition::ID();
+    return MY_KIND;
+  }
+
+  /// Creates a new part document if needed
+  FEATURESPLUGIN_EXPORT virtual void execute();
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Use plugin manager for features creation
+  FeaturesPlugin_Partition();
+
+private:
+  std::shared_ptr<GeomAPI_Shape> getShape(const std::string& theAttrName);
+
+};
+
+#endif
index 28ae8523426fa8ce16914abb94813b0a87359b81..69d3cc4a7240f893056b7c79e940ab474f7b5945 100644 (file)
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeBoolean.h>
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_BodyBuilder.h>
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Face.h>
 #include <GeomAPI_Pln.h>
 #include <GeomAlgoAPI_Placement.h>
+#include <GeomAlgoAPI_Transform.h>
 
 #define _MODIFIEDF_TAG 1
 #define _MODIFIEDE_TAG 2
@@ -28,144 +30,156 @@ FeaturesPlugin_Placement::FeaturesPlugin_Placement()
 
 void FeaturesPlugin_Placement::initAttributes()
 {
-  /* Modification for specification of 1.3.0
+
   AttributeSelectionListPtr aSelection = 
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-    FeaturesPlugin_Placement::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+    OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
   // extrusion works with faces always
   aSelection->setSelectionType("SOLID");
-  */
-  data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
-  data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::typeId());
+
+  data()->addAttribute(START_FACE_ID(), ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(END_FACE_ID(), ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
+  data()->addAttribute(CENTERING_ID(), ModelAPI_AttributeBoolean::typeId());
 }
 
 void FeaturesPlugin_Placement::execute()
 {
-  // Verify the base face
-  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = std::dynamic_pointer_cast<
-    ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Placement::BASE_OBJECT_ID()));
-  if (!anObjRef)
+  // Getting objects.
+  ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
+  AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID());
+  if(anObjectsSelList->size() == 0) {
     return;
+  }
+  for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
+    if(!anObject.get()) {
+      return;
+    }
+    anObjects.push_back(anObject);
+    aContextes.push_back(anObjectAttr->context());
+  }
 
-  std::shared_ptr<GeomAPI_Shape> aBaseShape = 
-    std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-  if (!aBaseShape)
+  // Verify the start face
+  AttributeSelectionPtr anObjRef = selection(START_FACE_ID());
+  if(!anObjRef) {
+    return;
+  }
+  std::shared_ptr<GeomAPI_Shape> aStartFace = anObjRef->value();
+  if(!aStartFace || !GeomAPI_Face(aStartFace).isPlanar()) {
+    static const std::string aSelectionError = "The start face selection is bad";
+    setError(aSelectionError);
     return;
+  }
 
-  std::shared_ptr<GeomAPI_Shape> aBaseObject;
+
+  std::shared_ptr<GeomAPI_Shape> aStartShape;
   ResultPtr aContextRes = anObjRef->context();
   if (aContextRes.get()) {
-    aBaseObject = aContextRes->shape();
+    aStartShape = aContextRes->shape();
   }
-  if (!aBaseObject.get()) {
-    static const std::string aContextError = "The base selection context is bad";
+  if(!aStartShape.get()) {
+    static const std::string aContextError = "The start face selection context is bad";
     setError(aContextError);
     return;
   }
 
-  // Verify the attractive face
-  anObjRef = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(
-      data()->attribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID()));
-
-  std::shared_ptr<GeomAPI_Shape> aSlaveShape = 
-    std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-  if (!aSlaveShape)
+  // Verify the end face
+  anObjRef = selection(END_FACE_ID());
+  std::shared_ptr<GeomAPI_Shape> anEndFace = anObjRef->value();
+  if(!anEndFace || !GeomAPI_Face(anEndFace).isPlanar()) {
+    static const std::string aSelectionError = "The end face selection is bad";
+    setError(aSelectionError);
     return;
+  }
 
-  std::shared_ptr<GeomAPI_Shape> aSlaveObject;
+  std::shared_ptr<GeomAPI_Shape> anEndShape;
   aContextRes = anObjRef->context();
-  if (aContextRes.get()) {
-    aSlaveObject = aContextRes->shape();
+  if(aContextRes.get()) {
+    anEndShape = aContextRes->shape();
   }
-  if (!aSlaveObject.get()) {
-    static const std::string aContextError = "The tool selection context is bad";
+  if(!anEndShape.get()) {
+    static const std::string aContextError = "The end face selection context is bad";
     setError(aContextError);
     return;
   }
 
-  // Verify planarity of faces and linearity of edges
-  std::shared_ptr<GeomAPI_Shape> aShapes[2] = {aBaseShape, aSlaveShape};
-  for (int i = 0; i < 2; i++) {
-    if (aShapes[i]->isFace()) {
-      std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aShapes[i]));
-      if (!aFace->isPlanar()) {
-        static const std::string aPlanarityError = "One of selected faces is not planar";
-        setError(aPlanarityError);
-        return;
-      }
-    }
-    else if (aShapes[i]->isEdge()) {
-      std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aShapes[i]));
-      if (!anEdge->isLine()) {
-        static const std::string aLinearityError = "One of selected endges is not linear";
-        setError(aLinearityError);
-        return;
-      }
-    }
-  }
-
   // Flags of the Placement
-  AttributeBooleanPtr aBoolAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
-      data()->attribute(FeaturesPlugin_Placement::REVERSE_ID()));
-  bool isReverse = aBoolAttr->value();
-  aBoolAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
-      data()->attribute(FeaturesPlugin_Placement::CENTERING_ID()));
-  bool isCentering = aBoolAttr->value();
+  bool isReverse = boolean(REVERSE_ID())->value();
+  bool isCentering = boolean(CENTERING_ID())->value();
 
   bool isPart = aContextRes->groupName() == ModelAPI_ResultPart::group();
 
-  std::shared_ptr<ModelAPI_ResultBody> aResultBody;
-  if (!isPart) 
-    aResultBody = document()->createBody(data());
-  GeomAlgoAPI_Placement aFeature(
-    aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering, isPart);
-  if(!aFeature.isDone()) {
+  // Getting transformation.
+  GeomAlgoAPI_Placement aPlacementAlgo(
+    aStartShape, anEndShape, aStartFace, anEndFace, isReverse, isCentering, true);
+  if(!aPlacementAlgo.isDone()) {
     static const std::string aFeatureError = "Placement algorithm failed";
     setError(aFeatureError);
     return;
   }
+  std::shared_ptr<GeomAPI_Trsf> aTrsf = aPlacementAlgo.transformation();
+
+  // Applying transformation to each object.
+  int aResultIndex = 0;
+  std::list<ResultPtr>::iterator aContext = aContextes.begin();
+  for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
+      anObjectsIt++, aContext++) {
+
+    if (isPart) { // for part results just set transformation
+      ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aContextRes);
+      ResultPartPtr aResultPart = document()->copyPart(firstResult(), anOrigin);
+      aResultPart->setTrsf(aContextRes, aTrsf);
+      setResult(aResultPart);
+    } else {
+      std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
+      GeomAlgoAPI_Transform aTransformAlgo(aBaseShape, aTrsf);
+
+      // Checking that the algorithm worked properly.
+      if(!aTransformAlgo.isDone()) {
+        static const std::string aFeatureError = "Transform algorithm failed";
+        setError(aFeatureError);
+        break;
+      }
+      if(aTransformAlgo.shape()->isNull()) {
+        static const std::string aShapeError = "Resulting shape is Null";
+        setError(aShapeError);
+        break;
+      }
+      if(!aTransformAlgo.isValid()) {
+        std::string aFeatureError = "Warning: resulting shape is not valid";
+        setError(aFeatureError);
+        break;
+      }
 
-  // Check if shape is valid
-  if (aFeature.shape()->isNull()) {
-    static const std::string aShapeError = "Resulting shape is Null";
-    setError(aShapeError);
-    return;
-  }
-  if(!aFeature.isValid()) {
-    std::string aFeatureError = "Warning: resulting shape is not valid";
-    setError(aFeatureError);
-    return;
-  }  
-
-  if (isPart) { // for part results just set transformation
-    ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aContextRes);
-    ResultPartPtr aResultPart = document()->copyPart(firstResult(), anOrigin);
-    aResultPart->setTrsf(aContextRes, aFeature.transformation());
-    setResult(aResultPart);
-  } else {
-    //LoadNamingDS
-    LoadNamingDS(aFeature, aResultBody, aSlaveObject);
-
-    setResult(aResultBody);
+      //LoadNamingDS
+      std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
+      LoadNamingDS(aTransformAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
+    aResultIndex++;
   }
+
+  // Remove the rest results if there were produced in the previous pass.
+  removeResults(aResultIndex);
 }
 
 //============================================================================
-void FeaturesPlugin_Placement::LoadNamingDS(
-    GeomAlgoAPI_Placement& theFeature,
-    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-    std::shared_ptr<GeomAPI_Shape> theSlaveObject)
+void FeaturesPlugin_Placement::LoadNamingDS(GeomAlgoAPI_Transform& theTransformAlgo,
+                                            std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                                            std::shared_ptr<GeomAPI_Shape> theSlaveObject)
 {
+  ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder();
   //load result
-  theResultBody->storeModified(theSlaveObject, theFeature.shape()); // the initial Slave, the resulting Slave
+  aResultBuilder->storeModified(theSlaveObject, theTransformAlgo.shape()); // the initial Slave, the resulting Slave
+
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theTransformAlgo.mapOfShapes();
 
-  GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
-  theFeature.mapOfShapes(*aSubShapes);
-  
     // put modifed faces in DF
   std::string aModName = "Modified";
-  theResultBody->loadAndOrientModifiedShapes(theFeature.makeShape(), theSlaveObject, _FACE, _MODIFIEDF_TAG, aModName, *aSubShapes); 
-
+  aResultBuilder->loadAndOrientModifiedShapes(theTransformAlgo.makeShape().get(),
+                                              theSlaveObject, _FACE,
+                                              _MODIFIEDF_TAG, aModName, *aSubShapes.get());
 }
index b83d07e9593f40e72586cca0a23d2f3c5ef5320b..46acd79e29fe1b3352aac69f0c19db920cac7736 100644 (file)
@@ -10,6 +10,7 @@
 #include "FeaturesPlugin.h"
 #include <ModelAPI_Feature.h>
 #include <GeomAlgoAPI_Placement.h>
+#include <GeomAlgoAPI_Transform.h>
 
 class ModelAPI_ResultBody;
 class GeomAPI_Shape;
@@ -31,25 +32,26 @@ class FeaturesPlugin_Placement : public ModelAPI_Feature
     static const std::string MY_PLACEMENT_ID("Placement");
     return MY_PLACEMENT_ID;
   }
+
   /// attribute name of references sketch entities list, it should contain a sketch result or
   /// a pair a sketch result to sketch face
-  /*Modification for specification of 1.3.0
-  inline static const std::string& LIST_ID()
+  inline static const std::string& OBJECTS_LIST_ID()
   {
-    static const std::string MY_GROUP_LIST_ID("base");
-    return MY_GROUP_LIST_ID;
-  }*/
+    static const std::string MY_OBJECTS_LIST_ID("placement_objects_list");
+    return MY_OBJECTS_LIST_ID;
+  }
+
   /// attribute name of referenced object
-  inline static const std::string& BASE_OBJECT_ID()
+  inline static const std::string& START_FACE_ID()
   {
-    static const std::string MY_BASE_OBJECT_ID("placement_base_object");
-    return MY_BASE_OBJECT_ID;
+    static const std::string MY_START_FACE_ID("placement_start_face");
+    return MY_START_FACE_ID;
   }
   /// attribute name of attractable face
-  inline static const std::string& ATTRACT_OBJECT_ID()
+  inline static const std::string& END_FACE_ID()
   {
-    static const std::string MY_ATTRACT_OBJECT_ID("placement_attractable_object");
-    return MY_ATTRACT_OBJECT_ID;
+    static const std::string MY_END_FACE_ID("placement_end_face");
+    return MY_END_FACE_ID;
   }
   /// attribute name of flag of reverse direction
   inline static const std::string& REVERSE_ID()
@@ -81,7 +83,7 @@ class FeaturesPlugin_Placement : public ModelAPI_Feature
   FeaturesPlugin_Placement();
 private:
   /// Load Naming data structure of the feature to the document
-  void LoadNamingDS(GeomAlgoAPI_Placement& theFeature,
+  void LoadNamingDS(GeomAlgoAPI_Transform& theTransformAlgo,
                     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
                     std::shared_ptr<GeomAPI_Shape> theSlaveObject);
 };
index 12ed913422eaf7541d7e1c7b70be8b03d1b92fbd..d3d243a4ad7d78f8a89b7a1a86ca41266e2ed484 100644 (file)
@@ -8,6 +8,7 @@
 #include <FeaturesPlugin_ExtrusionFuse.h>
 #include <FeaturesPlugin_Group.h>
 #include <FeaturesPlugin_Movement.h>
+#include <FeaturesPlugin_Partition.h>
 #include <FeaturesPlugin_Placement.h>
 #include <FeaturesPlugin_Revolution.h>
 #include <FeaturesPlugin_RevolutionCut.h>
@@ -45,6 +46,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_Boolean);
   } else if (theFeatureID == FeaturesPlugin_Group::ID()) {
     return FeaturePtr(new FeaturesPlugin_Group);
+  } else if (theFeatureID == FeaturesPlugin_Partition::ID()) {
+    return FeaturePtr(new FeaturesPlugin_Partition);
   } else if (theFeatureID == FeaturesPlugin_Placement::ID()) {
     return FeaturePtr(new FeaturesPlugin_Placement);
   } else if (theFeatureID == FeaturesPlugin_ExtrusionCut::ID()) {
index 829268839ea7a2f49671dab7a783ad272cc8de26..8b8a93ad8237b489649e03f9cdc92fdf2f2e47e1 100644 (file)
@@ -9,6 +9,7 @@
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_ResultConstruction.h>
@@ -179,15 +180,17 @@ void FeaturesPlugin_Revolution::LoadNamingDS(GeomAlgoAPI_Revolution& theFeature,
                                              std::shared_ptr<GeomAPI_Shape> theContext)
 {
   //load result
+  ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder();
+
   if(theBasis->isEqual(theContext))
-    theResultBody->store(theFeature.shape());
+    aResultBuilder->store(theFeature.shape());
   else
-    theResultBody->storeGenerated(theContext, theFeature.shape());
+    aResultBuilder->storeGenerated(theContext, theFeature.shape());
 
   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theFeature.mapOfShapes();
 
   std::string aGeneratedName = "LateralFace";
-  theResultBody->loadAndOrientGeneratedShapes(theFeature.makeShape().get(), theBasis, EDGE,_LATERAL_TAG, aGeneratedName, *aSubShapes);
+  aResultBuilder->loadAndOrientGeneratedShapes(theFeature.makeShape().get(), theBasis, EDGE,_LATERAL_TAG, aGeneratedName, *aSubShapes);
 
   //Insert from face
   std::string aBotName = "FromFace";
@@ -196,7 +199,7 @@ void FeaturesPlugin_Revolution::LoadNamingDS(GeomAlgoAPI_Revolution& theFeature,
     if(aSubShapes->isBound(aBottomFace)) {
       aBottomFace = aSubShapes->find(aBottomFace);
     }
-    theResultBody->generated(aBottomFace, aBotName, _FROM_TAG);
+    aResultBuilder->generated(aBottomFace, aBotName, _FROM_TAG);
   }
 
   //Insert to face
@@ -206,7 +209,7 @@ void FeaturesPlugin_Revolution::LoadNamingDS(GeomAlgoAPI_Revolution& theFeature,
     if (aSubShapes->isBound(aTopFace)) {
       aTopFace = aSubShapes->find(aTopFace);
     }
-    theResultBody->generated(aTopFace, aTopName, _TO_TAG);
+    aResultBuilder->generated(aTopFace, aTopName, _TO_TAG);
   }
 
 }
index a2229a95d9d7d2dde6b9276184795e7ceb9441cf..aea860dcb5c98830f5b7fed93f74c355d2c348c3 100755 (executable)
@@ -8,6 +8,7 @@
 
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_BodyBuilder.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_ResultPart.h>
@@ -128,15 +129,16 @@ void FeaturesPlugin_Rotation::LoadNamingDS(const GeomAlgoAPI_Rotation& theRotaio
                                            std::shared_ptr<ModelAPI_ResultBody> theResultBody,
                                            std::shared_ptr<GeomAPI_Shape> theBaseShape)
 {
+  ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder();
   // Store result.
-  theResultBody->storeModified(theBaseShape, theRotaionAlgo.shape());
+  aResultBuilder->storeModified(theBaseShape, theRotaionAlgo.shape());
 
   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theRotaionAlgo.mapOfShapes();
 
   int aRotatedTag = 1;
   std::string aRotatedName = "Rotated";
-  theResultBody->loadAndOrientModifiedShapes(theRotaionAlgo.makeShape().get(),
-                                             theBaseShape, GeomAPI_Shape::FACE,
-                                             aRotatedTag, aRotatedName, *aSubShapes.get());
+  aResultBuilder->loadAndOrientModifiedShapes(theRotaionAlgo.makeShape().get(),
+                                              theBaseShape, GeomAPI_Shape::FACE,
+                                              aRotatedTag, aRotatedName, *aSubShapes.get());
 
 }
diff --git a/src/FeaturesPlugin/partition_widget.xml b/src/FeaturesPlugin/partition_widget.xml
new file mode 100755 (executable)
index 0000000..10671d6
--- /dev/null
@@ -0,0 +1,22 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+<source>
+  <multi_selector id="main_objects"
+    label="Main objects"
+    icon=":icons/cut_shape.png"
+    tooltip="Select a solid objects"
+    type_choice="Solids"
+    use_choice="false"
+    concealment="true">
+    <validator id="PartSet_DifferentObjects"/>
+    <validator id="GeomValidators_ShapeType" parameters="empty,solid"/>
+  </multi_selector>
+  <multi_selector id="tool_objects" 
+    label="Tool object" 
+    icon=":icons/cut_tool.png" 
+    tooltip="Select a tool face or solid"
+    type_choice="Faces"
+    concealment="true" >
+    <validator id="PartSet_DifferentObjects"/>
+  </multi_selector>
+</source>
index 2e6b8f2375504eebcc59ac3eeea13eeb9d71e2d4..ec6f228b0d53e17cb32afd1427ee7e5345f27519 100644 (file)
@@ -1,28 +1,23 @@
 <!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 <source>
-  <!--Modification for specification of 1.3.0
-  <multi_selector id="base"
-    label="Select a sketch face"
+  <multi_selector id="placement_objects_list"
+    label="Select a solid objects"
     icon=":icons/cut_shape.png"
-    tooltip="Select a sketch face"
+    tooltip="Select a solid objects"
     type_choice="Solids">
-  </multi_selector>-->
-  <!--Modification for specification of 1.3.0
-    icon=":icons/placement_from.png"-->
-  <shape_selector id="placement_base_object" 
+  </multi_selector>
+  <shape_selector id="placement_start_face"
     label="Select an object" 
-    icon=":icons/cut_shape.png" 
-    tooltip="Select a destination element"
-    shape_types="face edge vertex"
+    icon=":icons/placement_from.png"
+    tooltip="Select a start face"
+    shape_types="face"
   />
-  <!--Modification for specification of 1.3.0
-      icon=":icons/placement_to.png"-->
-  <shape_selector id="placement_attractable_object" 
+  <shape_selector id="placement_end_face"
     label="Select an object" 
-    icon=":icons/cut_shape.png"
-    tooltip="Select an element of moved object" 
-    shape_types="face edge vertex" 
+    icon=":icons/placement_to.png"
+    tooltip="Select an end face"
+    shape_types="face"
     concealment="true" >
     <validator id="PartSet_DifferentObjects"/>
   </shape_selector>
index b5dc47317a03b2f7c34a0e817c5281b4807cdf15..0140d4fca974edd5560a1e76716c925ff0658bee 100644 (file)
@@ -28,6 +28,9 @@
       <feature id="Boolean" title="Boolean" tooltip="Perform boolean operations with solids" icon=":icons/cut.png">
           <source path="boolean_widget.xml"/>
       </feature>
+      <feature id="Partition" title="Partition" tooltip="Perform partition operations with solids" icon=":icons/partition.png">
+          <source path="partition_widget.xml"/>
+      </feature>
     </group>
     <group id="Collections">
       <feature id="Group"
index 3bc40373254e4e79147ef4d5f48ef69212d9e858..6d14a195d8f185caa9012931274b4505609bfb32 100644 (file)
@@ -30,6 +30,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_BREPExport.h
     GeomAlgoAPI_STEPExport.h
     GeomAlgoAPI_IGESExport.h
+    GeomAlgoAPI_Transform.h
 )
 
 SET(PROJECT_SOURCES
@@ -56,6 +57,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_BREPExport.cpp
     GeomAlgoAPI_STEPExport.cpp
     GeomAlgoAPI_IGESExport.cpp
+    GeomAlgoAPI_Transform.cpp
 )
 
 SET(PROJECT_LIBRARIES
index 6a49f1fae2e2ea3e0dd73931f3a0f74706631cea..5d102832a96f9d7ab54b3bf7dd46b770ab55d59d 100644 (file)
@@ -25,6 +25,7 @@
   #include "GeomAlgoAPI_IGESImport.h"
   #include "GeomAlgoAPI_STEPImport.h"
   #include "GeomAlgoAPI_Tools.h"
+  #include "GeomAlgoAPI_Transform.h"
 
   #include <memory>
   #include <string>
@@ -64,6 +65,7 @@
 %include "GeomAlgoAPI_IGESImport.h"
 %include "GeomAlgoAPI_STEPImport.h"
 %include "GeomAlgoAPI_Tools.h"
+%include "GeomAlgoAPI_Transform.h"
 
 %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & {
   $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<GeomAPI_Shape>(*$1)), $descriptor(std::shared_ptr<GeomAPI_Shape> *), SWIG_POINTER_OWN | 0 );
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp
new file mode 100644 (file)
index 0000000..65840c2
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Transform.cpp
+// Created:     29 July 2015
+// Author:      Dmitry Bobylev
+
+#include <GeomAlgoAPI_Transform.h>
+
+#include <GeomAlgoAPI_ShapeProps.h>
+
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <Precision.hxx>
+#include <TopExp_Explorer.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Transform::GeomAlgoAPI_Transform(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                             std::shared_ptr<GeomAPI_Trsf>  theTrsf)
+: myDone(false),
+  myTrsf(theTrsf),
+  myShape(new GeomAPI_Shape()),
+  myMap(new GeomAPI_DataMapOfShapeShape()),
+  myMkShape(new GeomAlgoAPI_MakeShape())
+{
+  build(theSourceShape, theTrsf);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Transform::build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                  std::shared_ptr<GeomAPI_Trsf>  theTrsf)
+{
+  if(!theSourceShape || !theTrsf) {
+    return;
+  }
+
+  const TopoDS_Shape& aSourceShape = theSourceShape->impl<TopoDS_Shape>();
+  const gp_Trsf& aTrsf = theTrsf->impl<gp_Trsf>();
+
+  if(aSourceShape.IsNull()) {
+    return;
+  }
+
+  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
+  if(!aBuilder) {
+    return;
+  }
+
+  myDone = aBuilder->IsDone() == Standard_True;
+  if(!myDone) {
+    return;
+  }
+
+  TopoDS_Shape aResult = aBuilder->Shape();
+
+  // Fill data map to keep correct orientation of sub-shapes.
+  for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) {
+    std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+    aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+    myMap->bind(aCurrentShape, aCurrentShape);
+  }
+
+  myMkShape->setImpl(aBuilder);
+  myShape->setImpl(new TopoDS_Shape(aResult));
+}
+
+//=================================================================================================
+const bool GeomAlgoAPI_Transform::isValid() const
+{
+  BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+  return (aChecker.IsValid() == Standard_True);
+}
+
+//=================================================================================================
+const bool GeomAlgoAPI_Transform::hasVolume() const
+{
+  bool hasVolume(false);
+  if(isValid() && (GeomAlgoAPI_ShapeProps::volume(myShape) > Precision::Confusion())) {
+    hasVolume = true;
+  }
+  return hasVolume;
+}
+
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Transform::shape() const
+{
+  return myShape;
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Transform::mapOfShapes() const
+{
+  return myMap;
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Transform::makeShape() const
+{
+  return myMkShape;
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Trsf> GeomAlgoAPI_Transform::transformation() const
+{
+  return myTrsf;
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.h b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.h
new file mode 100644 (file)
index 0000000..aeb085a
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Transform.h
+// Created:     29 July 2015
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_Transform_H_
+#define GeomAlgoAPI_Transform_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Trsf.h>
+
+/** \class GeomAlgoAPI_Transform
+ *  \ingroup DataAlgo
+ *  \brief Creates a copy of the object by transformating it.
+ */
+class GeomAlgoAPI_Transform : public GeomAPI_Interface
+{
+public:
+  /** \brief Creates an object which is obtained from current object by transformating it.
+   *  \param[in] theSourceShape  a shape to be transformed.
+   *  \param[in] theTrsf         transformation.
+   */
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Transform(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Trsf>  theTrsf);
+
+  /// \return true if algorithm succeed.
+  GEOMALGOAPI_EXPORT const bool isDone() const
+  { return myDone; }
+
+  /// \return true if resulting shape is valid.
+  GEOMALGOAPI_EXPORT const bool isValid() const;
+
+  /// \return true if resulting shape has volume.
+  GEOMALGOAPI_EXPORT const bool hasVolume() const;
+
+  /// \return result of the transformation algorithm.
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& shape() const;
+
+  /// \return map of sub-shapes of the result. To be used for History keeping.
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_DataMapOfShapeShape> mapOfShapes() const;
+
+  /// \return interface for for History processing.
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAlgoAPI_MakeShape> makeShape() const;
+
+  /// \return the transformation.
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Trsf> transformation() const;
+
+private:
+  /// Builds resulting shape.
+  void build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+             std::shared_ptr<GeomAPI_Trsf>  theTrsf);
+
+private:
+  /// Fields.
+  bool myDone;
+  std::shared_ptr<GeomAPI_Trsf> myTrsf;
+  std::shared_ptr<GeomAPI_Shape> myShape;
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> myMap;
+  std::shared_ptr<GeomAlgoAPI_MakeShape> myMkShape;
+};
+
+#endif
index 46c9881a214e6cf2b214b441128f256b31690fdb..1567641253c14c3f88c39588c6c545db7a9f49c5 100644 (file)
@@ -20,10 +20,12 @@ SET(PROJECT_HEADERS
     Model_AttributeInteger.h
     Model_AttributeSelection.h
     Model_AttributeSelectionList.h
+    Model_BodyBuilder.h
     Model_Events.h
     Model_Update.h
     Model_Validator.h
     Model_ResultBody.h
+    Model_ResultCompSolid.h
     Model_ResultConstruction.h
     Model_ResultPart.h
     Model_ResultGroup.h
@@ -48,10 +50,12 @@ SET(PROJECT_SOURCES
     Model_AttributeInteger.cpp
     Model_AttributeSelection.cpp
     Model_AttributeSelectionList.cpp
+    Model_BodyBuilder.cpp
     Model_Events.cpp
     Model_Update.cpp
     Model_Validator.cpp
     Model_ResultBody.cpp
+    Model_ResultCompSolid.cpp
     Model_ResultConstruction.cpp
     Model_ResultPart.cpp
     Model_ResultGroup.cpp
diff --git a/src/Model/Model_BodyBuilder.cpp b/src/Model/Model_BodyBuilder.cpp
new file mode 100755 (executable)
index 0000000..604c99b
--- /dev/null
@@ -0,0 +1,716 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        Model_ResultBody.cpp
+// Created:     08 Jul 2014
+// Author:      Mikhail PONIKAROV
+
+#include <Model_BodyBuilder.h>
+
+#include <Model_Data.h>
+#include <Model_Document.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TNaming_Iterator.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDataStd_Integer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopExp.hxx>
+#include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
+#include <GeomAPI_Shape.h>
+#include <GeomAlgoAPI_MakeShape.h>
+#include <Config_PropManager.h>
+// DEB
+//#include <TCollection_AsciiString.hxx>
+//#include <TDF_Tool.hxx>
+//#define DEB_IMPORT 1
+
+Model_BodyBuilder::Model_BodyBuilder(ModelAPI_Object* theOwner)
+: ModelAPI_BodyBuilder(theOwner)
+{
+}
+
+// Converts evolution of naming shape to selection evelution and back to avoid
+// naming support on the disabled results. Deeply in the labels tree, recursively.
+static void EvolutionToSelection(TDF_Label theLab, const bool theFlag) {
+  std::list<std::pair<TopoDS_Shape, TopoDS_Shape> > aShapePairs; // to store old and new shapes
+  Handle(TNaming_NamedShape) aName;
+  int anEvolution = -1;
+  if (theLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) {
+    TNaming_Evolution aNSEvol = aName->Evolution();
+    if ((aNSEvol == TNaming_SELECTED && theFlag) ||
+        (aNSEvol != TNaming_SELECTED && !theFlag)) { // nothing to do, it is already correct
+      return;
+    }
+    anEvolution = (int)(aNSEvol);
+    if (!theFlag) {
+      Handle(TDataStd_Integer) anAttrEvol;
+      if (theLab.FindAttribute(TDataStd_Integer::GetID(), anAttrEvol)) {
+        anEvolution = anAttrEvol->Get();
+      }
+    } else {
+      TDataStd_Integer::Set(theLab, anEvolution);
+    }
+
+    for(TNaming_Iterator anIter(aName); anIter.More(); anIter.Next()) {
+      aShapePairs.push_back(std::pair<TopoDS_Shape, TopoDS_Shape>
+        (anIter.OldShape(), anIter.NewShape()));
+    }
+  }
+  // create new
+  TNaming_Builder aBuilder(theLab);
+  TNaming_Evolution anEvol = (TNaming_Evolution)(anEvolution);
+  std::list<std::pair<TopoDS_Shape, TopoDS_Shape> >::iterator aPairsIter = aShapePairs.begin();
+  for(; aPairsIter != aShapePairs.end(); aPairsIter++) {
+    if (theFlag) { // disabled => make selection
+      aBuilder.Select(aPairsIter->first, aPairsIter->second);
+    } else if (anEvol == TNaming_GENERATED) {
+      aBuilder.Generated(aPairsIter->first, aPairsIter->second);
+    } else if (anEvol == TNaming_MODIFY) {
+      aBuilder.Modify(aPairsIter->first, aPairsIter->second);
+    } else if (anEvol == TNaming_DELETE) {
+      aBuilder.Delete(aPairsIter->first);
+    } else if (anEvol == TNaming_PRIMITIVE) {
+      aBuilder.Generated(aPairsIter->second);
+    }
+  }
+  // recursive call for all sub-labels
+  TDF_ChildIterator anIter(theLab, Standard_False);
+  for(; anIter.More(); anIter.Next()) {
+    EvolutionToSelection(anIter.Value(), theFlag);
+  }
+}
+
+void Model_BodyBuilder::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
+{
+  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
+  if (aData) {
+    TDF_Label& aShapeLab = aData->shapeLab();
+    // clean builders
+    clean();   
+    // store the new shape as primitive
+    TNaming_Builder aBuilder(aShapeLab);
+    if (!theShape)
+      return;  // bad shape
+    TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+    if (aShape.IsNull())
+      return;  // null shape inside
+
+    aBuilder.Generated(aShape);        
+    // register name
+    if(!aBuilder.NamedShape()->IsEmpty()) {
+      Handle(TDataStd_Name) anAttr;
+      if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+        std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
+        if(!aName.empty()) {
+          std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+        }
+      }
+    }
+  }
+}
+
+void Model_BodyBuilder::storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theFromShape,
+  const std::shared_ptr<GeomAPI_Shape>& theToShape)
+{
+  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
+  if (aData) {
+    TDF_Label& aShapeLab = aData->shapeLab();
+    // clean builders
+    clean();   
+    // store the new shape as primitive
+    TNaming_Builder aBuilder(aShapeLab);
+    if (!theFromShape || !theToShape)
+      return;  // bad shape
+    TopoDS_Shape aShapeBasis = theFromShape->impl<TopoDS_Shape>();
+    if (aShapeBasis.IsNull())
+      return;  // null shape inside
+    TopoDS_Shape aShapeNew = theToShape->impl<TopoDS_Shape>();
+    if (aShapeNew.IsNull())
+      return;  // null shape inside
+    aBuilder.Generated(aShapeBasis, aShapeNew);
+    // register name
+    if(!aBuilder.NamedShape()->IsEmpty()) {
+      Handle(TDataStd_Name) anAttr;
+      if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+        std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
+        if(!aName.empty()) {
+          std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+        }
+      }
+    }
+  }
+}
+
+void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+  const std::shared_ptr<GeomAPI_Shape>& theNewShape, const int theDecomposeSolidsTag)
+{
+  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
+  if (aData) {
+    TDF_Label& aShapeLab = aData->shapeLab();
+    // clean builders
+    clean();   
+    // store the new shape as primitive
+    TNaming_Builder aBuilder(aShapeLab);
+    if (!theOldShape || !theNewShape)
+      return;  // bad shape
+    TopoDS_Shape aShapeOld = theOldShape->impl<TopoDS_Shape>();
+    if (aShapeOld.IsNull())
+      return;  // null shape inside
+    TopoDS_Shape aShapeNew = theNewShape->impl<TopoDS_Shape>();
+    if (aShapeNew.IsNull())
+      return;  // null shape inside
+    aBuilder.Modify(aShapeOld, aShapeNew);
+    if (theDecomposeSolidsTag && aShapeNew.ShapeType() == TopAbs_COMPOUND) { // make sub elements as subs
+
+      // register name if it is possible
+      TCollection_AsciiString aName;
+      if(!aBuilder.NamedShape()->IsEmpty()) {
+        Handle(TDataStd_Name) anAttr;
+        if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+          aName = TCollection_AsciiString(anAttr->Get()).ToCString();
+        }
+      }
+
+      TopoDS_Iterator aSubIter(aShapeNew);
+      for(int aTag = theDecomposeSolidsTag; aSubIter.More(); aSubIter.Next()) {
+        TNaming_Builder aSubBuilder(aShapeLab.FindChild(aTag++));
+        aSubBuilder.Generated(aSubIter.Value());
+        if(!aName.IsEmpty()) {
+          std::string aSolidName = 
+            (aName + "_Solid_" + TCollection_AsciiString(aTag - theDecomposeSolidsTag)).ToCString(); 
+          std::shared_ptr<Model_Document> aDoc = 
+            std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aSubBuilder.NamedShape()->Label(), aSolidName);
+          TDataStd_Name::Set(aSubBuilder.NamedShape()->Label(), aSolidName.c_str());
+        }
+      }
+    }
+  }
+}
+void Model_BodyBuilder::clean()
+{
+  std::vector<TNaming_Builder*>::iterator aBuilder = myBuilders.begin();
+  for(; aBuilder != myBuilders.end(); aBuilder++)
+    delete *aBuilder;
+  myBuilders.clear();
+}
+
+Model_BodyBuilder::~Model_BodyBuilder()
+{
+  clean();
+}
+
+TNaming_Builder* Model_BodyBuilder::builder(const int theTag)
+{
+  if (myBuilders.size() <= (unsigned int)theTag) {
+    myBuilders.insert(myBuilders.end(), theTag - myBuilders.size() + 1, NULL);
+  }
+  if (!myBuilders[theTag]) {
+    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
+    myBuilders[theTag] = new TNaming_Builder(aData->shapeLab().FindChild(theTag));
+    //TCollection_AsciiString entry;//
+    //TDF_Tool::Entry(aData->shapeLab().FindChild(theTag), entry);
+    //cout << "Label = " <<entry.ToCString() <<endl;
+  }
+  return myBuilders[theTag];
+}
+
+void Model_BodyBuilder::buildName(const int theTag, const std::string& theName)
+{
+  std::string aName = data()->name() + "/" + theName; 
+  std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+  aDoc->addNamingName(builder(theTag)->NamedShape()->Label(), aName);
+  TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(),aName.c_str());
+}
+void Model_BodyBuilder::generated(
+  const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
+{
+  TopoDS_Shape aShape = theNewShape->impl<TopoDS_Shape>();
+  builder(theTag)->Generated(aShape);
+  if(!theName.empty()) 
+    buildName(theTag, theName);
+}
+
+void Model_BodyBuilder::generated(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+  const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
+{
+  TopoDS_Shape anOldShape = theOldShape->impl<TopoDS_Shape>();
+  TopoDS_Shape aNewShape = theNewShape->impl<TopoDS_Shape>();
+  builder(theTag)->Generated(anOldShape, aNewShape);
+  if(!theName.empty()) 
+    buildName(theTag, theName);
+}
+
+
+void Model_BodyBuilder::modified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+  const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
+{
+  TopoDS_Shape anOldShape = theOldShape->impl<TopoDS_Shape>();
+  TopoDS_Shape aNewShape = theNewShape->impl<TopoDS_Shape>();
+  builder(theTag)->Modify(anOldShape, aNewShape);
+  if(!theName.empty()) 
+    buildName(theTag, theName);
+}
+
+void Model_BodyBuilder::deleted(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+  const int theTag)
+{
+  TopoDS_Shape aShape = theOldShape->impl<TopoDS_Shape>();
+  builder(theTag)->Delete(aShape);
+}
+
+void Model_BodyBuilder::loadDeletedShapes (GeomAlgoAPI_MakeShape* theMS,
+  std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+  const int  theKindOfShape,
+  const int  theTag)
+{
+  TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
+  TopTools_MapOfShape aView;
+  TopExp_Explorer ShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
+  for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
+    const TopoDS_Shape& aRoot = ShapeExplorer.Current ();
+    if (!aView.Add(aRoot)) continue;
+    std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
+    aRShape->setImpl((new TopoDS_Shape(aRoot)));
+    if (theMS->isDeleted (aRShape)) {
+      builder(theTag)->Delete(aRoot);
+    }
+  }
+}
+
+void Model_BodyBuilder::loadAndOrientModifiedShapes (
+  GeomAlgoAPI_MakeShape* theMS,
+  std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+  const int  theKindOfShape,
+  const int  theTag,
+  const std::string& theName,
+  GeomAPI_DataMapOfShapeShape& theSubShapes)
+{
+  TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
+  TopTools_MapOfShape aView;
+  bool isBuilt = theName.empty();
+  TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
+  for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
+    const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
+    if (!aView.Add(aRoot)) continue;
+    ListOfShape aList;
+    std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
+    aRShape->setImpl((new TopoDS_Shape(aRoot)));
+    theMS->modified(aRShape, aList);
+    std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
+    for (; anIt != aLast; anIt++) {
+      TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();    
+      if (theSubShapes.isBound(*anIt)) {
+        std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
+        aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
+      }
+      if (!aRoot.IsSame (aNewShape)) {
+        builder(theTag)->Modify(aRoot,aNewShape);
+        if(!isBuilt) 
+          buildName(theTag, theName);          
+      }
+    }
+  }
+}
+
+void Model_BodyBuilder::loadAndOrientGeneratedShapes (
+  GeomAlgoAPI_MakeShape* theMS,
+  std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+  const int  theKindOfShape,
+  const int  theTag,
+  const std::string& theName,
+  GeomAPI_DataMapOfShapeShape& theSubShapes)
+{
+  TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
+  TopTools_MapOfShape aView;
+  bool isBuilt = theName.empty();
+  TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
+  for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
+    const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
+    if (!aView.Add(aRoot)) continue;
+    ListOfShape aList;
+    std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
+    aRShape->setImpl((new TopoDS_Shape(aRoot)));
+    theMS->generated(aRShape, aList);
+    std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
+    for (; anIt != aLast; anIt++) {
+      TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();    
+      if (theSubShapes.isBound(*anIt)) {
+        std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
+        aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
+      }
+      if (!aRoot.IsSame (aNewShape)) {
+        builder(theTag)->Generated(aRoot,aNewShape);
+        if(!isBuilt) 
+          buildName(theTag, theName);  
+      }
+    }
+  }
+}
+
+//=======================================================================
+int getDangleShapes(const TopoDS_Shape&           theShapeIn, 
+  const TopAbs_ShapeEnum        theGeneratedFrom,
+  TopTools_DataMapOfShapeShape& theDangles) 
+{
+  theDangles.Clear();
+  TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors;
+  TopAbs_ShapeEnum GeneratedTo;
+  if (theGeneratedFrom == TopAbs_FACE) GeneratedTo = TopAbs_EDGE;
+  else if (theGeneratedFrom == TopAbs_EDGE) GeneratedTo = TopAbs_VERTEX;
+  else return Standard_False;
+  TopExp::MapShapesAndAncestors(theShapeIn, GeneratedTo, theGeneratedFrom, subShapeAndAncestors);
+  for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) {
+    const TopoDS_Shape& mayBeDangle = subShapeAndAncestors.FindKey(i);
+    const TopTools_ListOfShape& ancestors = subShapeAndAncestors.FindFromIndex(i);
+    if (ancestors.Extent() == 1) theDangles.Bind(ancestors.First(), mayBeDangle);
+  }
+  return theDangles.Extent();
+}
+
+//=======================================================================
+void loadGeneratedDangleShapes(
+  const TopoDS_Shape&      theShapeIn,
+  const TopAbs_ShapeEnum   theGeneratedFrom,
+  TNaming_Builder *        theBuilder)
+{
+  TopTools_DataMapOfShapeShape dangles;
+  if (!getDangleShapes(theShapeIn, theGeneratedFrom, dangles)) return;
+  TopTools_DataMapIteratorOfDataMapOfShapeShape itr(dangles);
+  for (; itr.More(); itr.Next()) 
+    theBuilder->Generated(itr.Key(), itr.Value());
+}
+
+//=======================================================================
+void Model_BodyBuilder::loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape, 
+  const std::string& theName, int&  theTag)
+{
+  if(theShape->isNull()) return;
+  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();    
+  std::string aName;
+  if (aShape.ShapeType() == TopAbs_SOLID) {                
+    TopExp_Explorer expl(aShape, TopAbs_FACE);
+    for (; expl.More(); expl.Next()) {  
+      builder(theTag)->Generated(expl.Current()); 
+      TCollection_AsciiString aStr(theTag);
+      aName = theName + aStr.ToCString();
+      buildName(theTag, aName);
+      theTag++;
+    }
+  }
+  else if (aShape.ShapeType() == TopAbs_SHELL || aShape.ShapeType() == TopAbs_FACE) {
+    // load faces and all the free edges
+    TopTools_IndexedMapOfShape Faces;
+    TopExp::MapShapes(aShape, TopAbs_FACE, Faces);
+    if (Faces.Extent() > 1 || (aShape.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
+      TopExp_Explorer expl(aShape, TopAbs_FACE);
+      for (; expl.More(); expl.Next()) {
+        builder(theTag)->Generated(expl.Current());          
+        TCollection_AsciiString aStr(theTag);
+        aName = theName + aStr.ToCString();
+        buildName(theTag, aName);
+        theTag++;
+      }
+    }
+    TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
+    TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, anEdgeAndNeighbourFaces);
+    for (Standard_Integer i = 1; i <= anEdgeAndNeighbourFaces.Extent(); i++) 
+    {
+      const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i);
+      if (aLL.Extent() < 2) {
+        if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeAndNeighbourFaces.FindKey(i))))
+          continue;
+        builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
+        TCollection_AsciiString aStr(theTag);
+        aName = theName + aStr.ToCString();
+        buildName(theTag, aName);
+        theTag++;
+      } else {
+        TopTools_ListIteratorOfListOfShape anIter(aLL);
+        const TopoDS_Face& aFace = TopoDS::Face(anIter.Value());
+        anIter.Next();
+        if(aFace.IsEqual(anIter.Value())) {
+          builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
+          TCollection_AsciiString aStr(theTag);
+          aName = theName + aStr.ToCString();
+          buildName(theTag, aName);
+          theTag++;
+        }
+      }
+    }
+  } else if (aShape.ShapeType() == TopAbs_WIRE) {
+    TopTools_IndexedMapOfShape Edges;
+    BRepTools::Map3DEdges(aShape, Edges);
+    if (Edges.Extent() == 1) {
+      builder(++theTag)->Generated(Edges.FindKey(1));
+      TopExp_Explorer expl(aShape, TopAbs_VERTEX);
+      for (; expl.More(); expl.Next()) {
+        builder(theTag)->Generated(expl.Current());
+        TCollection_AsciiString aStr(theTag);
+        aName = theName + aStr.ToCString();
+        buildName(theTag, aName);
+        theTag++;
+      }
+    } else {
+      TopExp_Explorer expl(aShape, TopAbs_EDGE); 
+      for (; expl.More(); expl.Next()) {       
+        builder(theTag)->Generated(expl.Current());
+        TCollection_AsciiString aStr(theTag);
+        aName = theName + aStr.ToCString();
+        buildName(theTag, aName);
+        theTag++;
+      }   
+      // and load generated vertices.
+      TopTools_DataMapOfShapeShape generated;
+      if (getDangleShapes(aShape, TopAbs_EDGE, generated)) 
+      {
+        TNaming_Builder* pBuilder = builder(theTag++);
+        loadGeneratedDangleShapes(aShape, TopAbs_EDGE, pBuilder);  
+      }
+    }
+  } else if (aShape.ShapeType() == TopAbs_EDGE) {
+    TopExp_Explorer expl(aShape, TopAbs_VERTEX);
+    for (; expl.More(); expl.Next()) {      
+      builder(theTag)->Generated(expl.Current());
+      TCollection_AsciiString aStr(theTag);
+      aName = theName + aStr.ToCString();
+      buildName(theTag, aName);
+      theTag++;
+    }
+  }
+}
+
+//=======================================================================
+int findAmbiguities(const TopoDS_Shape&           theShapeIn,                                  
+  TopTools_ListOfShape&   theList) 
+{
+  int aNumEdges(0);
+  theList.Clear();
+  TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors;
+  TopAbs_ShapeEnum aTS(TopAbs_EDGE);
+  TopAbs_ShapeEnum aTA(TopAbs_FACE);
+  TopTools_MapOfShape aMap1, aMap2; // map1 - for edge ancestors; map2 - for keys => edges
+  TopTools_ListOfShape aKeyList;
+  TopExp::MapShapesAndAncestors(theShapeIn, aTS, aTA, subShapeAndAncestors);
+  for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) {
+    const TopoDS_Shape& aKeyEdge1 = subShapeAndAncestors.FindKey(i);
+    const TopTools_ListOfShape& ancestors1 = subShapeAndAncestors.FindFromIndex(i);
+    aMap1.Clear();
+    TopTools_ListIteratorOfListOfShape it(ancestors1);
+    for(;it.More();it.Next()) aMap1.Add(it.Value()); // fill map with key ancestors => aKey1
+    for (Standard_Integer j = 1; j <= subShapeAndAncestors.Extent(); j++) {
+      if (i == j) continue;
+      const TopoDS_Shape& aKeyEdge2 = subShapeAndAncestors.FindKey(j);
+      const TopTools_ListOfShape& ancestors2 = subShapeAndAncestors.FindFromIndex(j);
+      if(ancestors1.Extent() == ancestors2.Extent() && ancestors1.Extent() > 1) {
+        int aNum (ancestors2.Extent());
+        TopTools_ListIteratorOfListOfShape it(ancestors2);
+        for(;it.More();it.Next()) 
+          if(aMap1.Contains(it.Value())) aNum--;
+        if(aNum == 0) {
+          if(aMap2.Add(aKeyEdge1)) 
+            aKeyList.Append(aKeyEdge1);
+          if(aMap2.Add(aKeyEdge2))
+            aKeyList.Append(aKeyEdge2);
+        }
+      }
+    } // at the end ==> List of edges to be named in addition  
+  }
+  aNumEdges = aKeyList.Extent();
+  if(aNumEdges)
+    theList.Assign(aKeyList);  
+  return aNumEdges; 
+}
+
+//=======================================================================
+void Model_BodyBuilder::loadFirstLevel(
+  std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
+{
+  if(theShape->isNull()) return;
+  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>(); 
+  std::string aName;
+  if (aShape.ShapeType() == TopAbs_COMPOUND || aShape.ShapeType() == TopAbs_COMPSOLID) {
+    TopoDS_Iterator itr(aShape);
+    for (; itr.More(); itr.Next(),theTag++) {
+      builder(theTag)->Generated(itr.Value());
+      TCollection_AsciiString aStr(theTag);
+      aName = theName + aStr.ToCString();
+      buildName(theTag, aName);
+      if(!theName.empty()) buildName(theTag, aName);
+      if (itr.Value().ShapeType() == TopAbs_COMPOUND || 
+        itr.Value().ShapeType() == TopAbs_COMPSOLID) 
+      {
+        std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
+        itrShape->setImpl(new TopoDS_Shape(itr.Value()));
+        loadFirstLevel(itrShape, theName, theTag);
+      } else {
+        std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
+        itrShape->setImpl(new TopoDS_Shape(itr.Value()));              
+        loadNextLevels(itrShape, theName, theTag);
+      }
+    }
+  } else {
+    std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
+    itrShape->setImpl(new TopoDS_Shape(aShape));
+    loadNextLevels(itrShape, theName, theTag); 
+  }
+  TopTools_ListOfShape   aList;
+  if(findAmbiguities(aShape, aList)) {
+    TopTools_ListIteratorOfListOfShape it(aList);
+    for (; it.More(); it.Next(),theTag++) {
+      builder(theTag)->Generated(it.Value());
+      TCollection_AsciiString aStr(theTag);
+      aName = theName + aStr.ToCString();
+      buildName(theTag, aName);
+    }
+  }
+}
+
+//=======================================================================
+void Model_BodyBuilder::loadDisconnectedEdges(
+  std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
+{
+  if(theShape->isNull()) return;
+  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();  
+  TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
+  TopTools_ListOfShape empty;
+  TopExp_Explorer explF(aShape, TopAbs_FACE);
+  for (; explF.More(); explF.Next()) {
+    const TopoDS_Shape& aFace = explF.Current();
+    TopExp_Explorer explV(aFace, TopAbs_EDGE);
+    for (; explV.More(); explV.Next()) {
+      const TopoDS_Shape& anEdge = explV.Current();
+      if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
+      Standard_Boolean faceIsNew = Standard_True;
+      TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
+      for (; itrF.More(); itrF.Next()) {
+        if (itrF.Value().IsSame(aFace)) {
+          faceIsNew = Standard_False;
+          break;
+        }
+      }
+      if (faceIsNew) 
+        edgeNaborFaces.ChangeFind(anEdge).Append(aFace);      
+    }
+  }
+
+  /*  TopTools_IndexedDataMapOfShapeListOfShape aDM;
+  TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, aDM);
+  for(int i=1; i <= aDM.Extent(); i++) {
+  if(aDM.FindFromIndex(i).Extent() > 1) continue;
+  if (BRep_Tool::Degenerated(TopoDS::Edge(aDM.FindKey(i))))
+  continue;
+  builder(theTag)->Generated(aDM.FindKey(i));
+  TCollection_AsciiString aStr(theTag);
+  std::string aName = theName + aStr.ToCString();
+  buildName(theTag, aName);
+  #ifdef DEB_IMPORT
+  aName +=  + ".brep";
+  BRepTools::Write(aDM.FindKey(i), aName.c_str());
+  #endif
+  theTag++;
+  }
+  */
+  TopTools_MapOfShape anEdgesToDelete;
+  TopExp_Explorer anEx(aShape,TopAbs_EDGE); 
+  std::string aName;
+  for(;anEx.More();anEx.Next()) {
+    Standard_Boolean aC0 = Standard_False;
+    TopoDS_Shape anEdge1 = anEx.Current();
+    if (edgeNaborFaces.IsBound(anEdge1)) {
+      const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
+      if (aList1.Extent()<2) continue;
+      TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
+      for (; itr.More(); itr.Next()) {
+        TopoDS_Shape anEdge2 = itr.Key();
+        if(anEdgesToDelete.Contains(anEdge2)) continue;
+        if (anEdge1.IsSame(anEdge2)) continue;
+        const TopTools_ListOfShape& aList2 = itr.Value();
+        // compare lists of the neighbour faces of edge1 and edge2
+        if (aList1.Extent() == aList2.Extent()) {
+          Standard_Integer aMatches = 0;
+          for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
+            for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
+              if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
+          if (aMatches == aList1.Extent()) {
+            aC0=Standard_True;
+            builder(theTag)->Generated(anEdge2);
+            anEdgesToDelete.Add(anEdge2);
+            TCollection_AsciiString aStr(theTag);
+            aName = theName + aStr.ToCString();
+            buildName(theTag, aName);
+            theTag++;
+          }
+        }
+      }      
+      TopTools_MapIteratorOfMapOfShape itDelete(anEdgesToDelete);
+      for(;itDelete.More();itDelete.Next()) 
+        edgeNaborFaces.UnBind(itDelete.Key());      
+      edgeNaborFaces.UnBind(anEdge1);
+    }
+    if (aC0) {
+      builder(theTag)->Generated(anEdge1);
+      TCollection_AsciiString aStr(theTag);
+      aName = theName + aStr.ToCString();
+      buildName(theTag, aName);         
+      theTag++;
+    }
+  }  
+}
+
+void Model_BodyBuilder::loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
+{
+  if(theShape->isNull()) return;
+  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();  
+  TopTools_DataMapOfShapeListOfShape vertexNaborEdges;
+  TopTools_ListOfShape empty;
+  TopExp_Explorer explF(aShape, TopAbs_EDGE);
+  for (; explF.More(); explF.Next()) {
+    const TopoDS_Shape& anEdge = explF.Current();
+    TopExp_Explorer explV(anEdge, TopAbs_VERTEX);
+    for (; explV.More(); explV.Next()) {
+      const TopoDS_Shape& aVertex = explV.Current();
+      if (!vertexNaborEdges.IsBound(aVertex)) vertexNaborEdges.Bind(aVertex, empty);
+      Standard_Boolean faceIsNew = Standard_True;
+      TopTools_ListIteratorOfListOfShape itrF(vertexNaborEdges.Find(aVertex));
+      for (; itrF.More(); itrF.Next()) {
+        if (itrF.Value().IsSame(anEdge)) {
+          faceIsNew = Standard_False;
+          break;
+        }
+      }
+      if (faceIsNew) {
+        vertexNaborEdges.ChangeFind(aVertex).Append(anEdge);
+      }
+    }
+  }
+  std::string aName;
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborEdges);
+  for (; itr.More(); itr.Next()) {
+    const TopTools_ListOfShape& naborEdges = itr.Value();
+    if (naborEdges.Extent() < 2) {             
+      builder(theTag)->Generated(itr.Key());
+      TCollection_AsciiString aStr(theTag);
+      aName = theName + aStr.ToCString();
+      buildName(theTag, aName);         
+      theTag++;
+    }
+  }
+}
diff --git a/src/Model/Model_BodyBuilder.h b/src/Model/Model_BodyBuilder.h
new file mode 100755 (executable)
index 0000000..7548439
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        Model_ResultBody.h
+// Created:     08 Jul 2014
+// Author:      Mikhail PONIKAROV
+
+#ifndef Model_BodyBuilder_H_
+#define Model_BodyBuilder_H_
+
+#include "Model.h"
+#include <ModelAPI_BodyBuilder.h>
+
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <vector>
+
+class TNaming_Builder;
+
+/**\class Model_BodyBuilder
+ * \ingroup DataModel
+ * \brief The body (shape) result of a feature.
+ */
+class Model_BodyBuilder : public ModelAPI_BodyBuilder
+{
+  /// builders that tores the naming history: one per label to allow store several shapes to one 
+  /// label; index in vector corresponds to the label tag
+  std::vector<TNaming_Builder*> myBuilders;
+public:
+  /// Stores the shape (called by the execution method).
+  MODEL_EXPORT virtual void store(const std::shared_ptr<GeomAPI_Shape>& theShape);
+
+  /// Stores the generated shape (called by the execution method).
+  MODEL_EXPORT virtual void storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theFromShape,
+                                              const std::shared_ptr<GeomAPI_Shape>& theToShape);
+
+  /// Stores the modified shape (called by the execution method).
+  /// \param theOldShape shape that produces result
+  /// \param theNewShape resulting shape
+  /// \param theDecomposeSolidsTag tag for starting of solids sub-elements placement in case 
+  ///          theNewShape is compound of solids, if zero it is not used
+  MODEL_EXPORT virtual void storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+                                               const std::shared_ptr<GeomAPI_Shape>& theNewShape,
+                                          const int theDecomposeSolidsTag = 0);
+  /// 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.
+  MODEL_EXPORT virtual void generated(const std::shared_ptr<GeomAPI_Shape>& theNewShape, 
+    const std::string& theName, const int theTag = 1);
+
+  /// Records the shape newShape which was generated from the shape oldShape during a topological 
+  /// construction. As an example, consider the case of a face generated from an edge in 
+  /// construction of a prism.
+  MODEL_EXPORT virtual void generated(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+    const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag = 1);
+
+
+  /// Records the shape newShape which is a modification of the shape oldShape.
+  /// As an example, consider the case of a face split or merged in a Boolean operation.
+  MODEL_EXPORT virtual void modified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+    const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag = 1);
+
+  /// Records the shape oldShape which was deleted from the current label.
+  /// As an example, consider the case of a face removed by a Boolean operation.
+  MODEL_EXPORT virtual void deleted(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+    const int theTag = 1);
+
+  /// load deleted shapes
+  MODEL_EXPORT virtual void loadDeletedShapes (GeomAlgoAPI_MakeShape* theMS,
+                                               std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+                                               const int  theKindOfShape,
+                                               const int  theTag);
+  /// load and orient modified shapes
+  MODEL_EXPORT virtual void loadAndOrientModifiedShapes (
+                                                  GeomAlgoAPI_MakeShape* theMS,
+                                               std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+                                               const int  theKindOfShape,
+                                               const int  theTag,
+                                                                                          const std::string& theName,
+                                               GeomAPI_DataMapOfShapeShape& theSubShapes);
+   /// load and orient generated shapes
+  MODEL_EXPORT virtual void loadAndOrientGeneratedShapes (
+                                                  GeomAlgoAPI_MakeShape* theMS,
+                                               std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+                                               const int  theKindOfShape,
+                                               const int  theTag,
+                                                                                          const std::string& theName,
+                                               GeomAPI_DataMapOfShapeShape& theSubShapes);
+  
+  /// Loads shapes of the first level (to be used during shape import)
+  MODEL_EXPORT virtual void loadFirstLevel(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag);
+  
+  /// Loads disconnected edges
+  MODEL_EXPORT virtual void loadDisconnectedEdges(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag);
+
+  /// Loads disconnected vetexes
+  MODEL_EXPORT virtual void loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag);
+
+  /// Removes the stored builders
+  MODEL_EXPORT virtual ~Model_BodyBuilder();
+
+protected:
+  Model_BodyBuilder(ModelAPI_Object* theOwner);
+
+  /// Removes the stored builders
+  void clean();
+
+  /// Returns (creates if necessary) the builder created on the needed tag of sub-label
+  TNaming_Builder* builder(const int theTag);
+
+private:
+  /// Loads shapes of the next level (to be used during shape import)
+  void loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag);
+
+  /// builds name for the shape kept at the specified tag 
+  void buildName(const int theTag, const std::string& theName);
+
+  friend class Model_ResultBody;
+  friend class Model_ResultCompSolid;
+};
+
+#endif
index 6e9fbf778da1aeca0802669c0e14285f9681ff9c..b160e375259d2b04afbf57cac3d00620ab834600 100644 (file)
@@ -800,6 +800,12 @@ std::shared_ptr<ModelAPI_ResultBody> Model_Document::createBody(
   return myObjs->createBody(theFeatureData, theIndex);
 }
 
+std::shared_ptr<ModelAPI_ResultCompSolid> Model_Document::createCompSolid(
+    const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
+{
+  return myObjs->createCompSolid(theFeatureData, theIndex);
+}
+
 std::shared_ptr<ModelAPI_ResultPart> Model_Document::createPart(
     const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
 {
index 997765a85fc6e0c738808a8361541e67933ae28d..626e2f4b2a8636abaffb9ab2cbb30236bee3e750 100644 (file)
@@ -151,6 +151,9 @@ class Model_Document : public ModelAPI_Document
   /// Creates a body results
   MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultBody> createBody(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
+  /// Creates a compsolid results
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultCompSolid> createCompSolid(
+      const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
   /// Creates a part results
   MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultPart> createPart(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
index 72544d26ee8e83b0e73d13b1bd3699488dde37f9..bec8764981b61c836d663b56105a010969f0b36f 100644 (file)
@@ -12,6 +12,7 @@
 #include <Model_ResultPart.h>
 #include <Model_ResultConstruction.h>
 #include <Model_ResultBody.h>
+#include <Model_ResultCompSolid.h>
 #include <Model_ResultGroup.h>
 #include <Model_ResultParameter.h>
 #include <ModelAPI_Validator.h>
@@ -763,6 +764,23 @@ std::shared_ptr<ModelAPI_ResultBody> Model_Objects::createBody(
   return aResult;
 }
 
+std::shared_ptr<ModelAPI_ResultCompSolid> Model_Objects::createCompSolid(
+    const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
+{
+  TDF_Label aLab = resultLabel(theFeatureData, theIndex);
+  TDataStd_Comment::Set(aLab, ModelAPI_ResultCompSolid::group().c_str());
+  ObjectPtr anOldObject = object(aLab);
+  std::shared_ptr<ModelAPI_ResultCompSolid> aResult;
+  if (anOldObject) {
+    aResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anOldObject);
+  }
+  if (!aResult) {
+    aResult = std::shared_ptr<ModelAPI_ResultCompSolid>(new Model_ResultCompSolid);
+    storeResult(theFeatureData, aResult, theIndex);
+  }
+  return aResult;
+}
+
 std::shared_ptr<ModelAPI_ResultPart> Model_Objects::createPart(
     const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
 {
index a78ac94185acb12c6cc6f716d0d5e8d22cb05dba..bf6904715014fe90783cbfb906b55e2b6dddfeb9 100644 (file)
@@ -100,6 +100,9 @@ class Model_Objects
   /// Creates a body results
   std::shared_ptr<ModelAPI_ResultBody> createBody(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
+  /// Creates a body results
+  std::shared_ptr<ModelAPI_ResultCompSolid> createCompSolid(
+      const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
   /// Creates a part results
   std::shared_ptr<ModelAPI_ResultPart> createPart(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
index 8cecd4a92d837d8ed336dba3218e673456270b35..cb285aafdb182f4437ee99b790ceb29d94e17a19 100644 (file)
@@ -5,9 +5,11 @@
 // Author:      Mikhail PONIKAROV
 
 #include <Model_ResultBody.h>
+#include <Model_BodyBuilder.h>
 #include <Model_Data.h>
 #include <Model_Document.h>
 #include <ModelAPI_AttributeIntArray.h>
+
 #include <TNaming_Builder.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Iterator.hxx>
@@ -32,6 +34,7 @@
 #include <BRep_Tool.hxx>
 #include <GeomAPI_Shape.h>
 #include <GeomAlgoAPI_MakeShape.h>
+
 #include <Config_PropManager.h>
 // DEB
 //#include <TCollection_AsciiString.hxx>
@@ -40,6 +43,8 @@
 
 Model_ResultBody::Model_ResultBody()
 {
+  myBuilder = new Model_BodyBuilder(this);
+
   myIsDisabled = true; // by default it is not initialized and false to be after created
   setIsConcealed(false);
 }
@@ -123,6 +128,7 @@ bool Model_ResultBody::setDisabled(std::shared_ptr<ModelAPI_Result> theThis, con
   return aChanged;
 }
 
+/*
 void Model_ResultBody::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
 {
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
@@ -232,7 +238,7 @@ void Model_ResultBody::storeModified(const std::shared_ptr<GeomAPI_Shape>& theOl
     }
   }
 }
-
+*/
 std::shared_ptr<GeomAPI_Shape> Model_ResultBody::shape()
 {
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
@@ -250,7 +256,7 @@ std::shared_ptr<GeomAPI_Shape> Model_ResultBody::shape()
   }
   return std::shared_ptr<GeomAPI_Shape>();
 }
-
+/*
 void Model_ResultBody::clean()
 {
   std::vector<TNaming_Builder*>::iterator aBuilder = myBuilders.begin();
@@ -674,7 +680,7 @@ void Model_ResultBody::loadDisconnectedEdges(
   #endif
   theTag++;
   }
-  */
+  *+/
   TopTools_MapOfShape anEdgesToDelete;
   TopExp_Explorer anEx(aShape,TopAbs_EDGE); 
   std::string aName;
@@ -761,3 +767,4 @@ void Model_ResultBody::loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> t
     }
   }
 }
+*/
\ No newline at end of file
index 1bb3f6870aba1633150bc361e5816d4c705a5f46..f8c83a3f87ca8333e8c252c59a37cb735326ccf1 100644 (file)
@@ -9,11 +9,11 @@
 
 #include "Model.h"
 #include <ModelAPI_ResultBody.h>
-#include <GeomAlgoAPI_MakeShape.h>
-#include <GeomAPI_DataMapOfShapeShape.h>
-#include <vector>
+//#include <GeomAlgoAPI_MakeShape.h>
+//#include <GeomAPI_DataMapOfShapeShape.h>
+//#include <vector>
 
-class TNaming_Builder;
+//class TNaming_Builder;
 
 /**\class Model_ResultBody
  * \ingroup DataModel
@@ -27,7 +27,7 @@ class Model_ResultBody : public ModelAPI_ResultBody
 {
   /// builders that tores the naming history: one per label to allow store several shapes to one 
   /// label; index in vector corresponds to the label tag
-  std::vector<TNaming_Builder*> myBuilders;
+  //std::vector<TNaming_Builder*> myBuilders;
 public:
   /// Request for initialization of data model of the result: adding all attributes
   virtual void initAttributes();
@@ -40,7 +40,7 @@ public:
   /// naming data structure if theFlag if false. Or restores everything on theFlag is true.
   MODEL_EXPORT virtual bool setDisabled(std::shared_ptr<ModelAPI_Result> theThis,
     const bool theFlag);
-
+  /*
   /// Stores the shape (called by the execution method).
   MODEL_EXPORT virtual void store(const std::shared_ptr<GeomAPI_Shape>& theShape);
 
@@ -56,10 +56,10 @@ public:
   MODEL_EXPORT virtual void storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
                                                const std::shared_ptr<GeomAPI_Shape>& theNewShape,
                                           const int theDecomposeSolidsTag = 0);
-
+                                          */
   /// Returns the shape-result produced by this feature
   MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shape();
-
+  /*
   /// 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.
   MODEL_EXPORT virtual void generated(const std::shared_ptr<GeomAPI_Shape>& theNewShape, 
@@ -112,14 +112,14 @@ public:
 
   /// Loads disconnected vetexes
   MODEL_EXPORT virtual void loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag);
-
+*/
   /// Removes the stored builders
-  MODEL_EXPORT virtual ~Model_ResultBody();
+  MODEL_EXPORT virtual ~Model_ResultBody() {};
 
 protected:
   /// Makes a body on the given feature
   Model_ResultBody();
-
+/*
   /// Removes the stored builders
   void clean();
 
@@ -132,7 +132,7 @@ private:
 
   /// builds name for the shape kept at the specified tag 
   void buildName(const int theTag, const std::string& theName);
-
+  */
   friend class Model_Objects;
 };
 
diff --git a/src/Model/Model_ResultCompSolid.cpp b/src/Model/Model_ResultCompSolid.cpp
new file mode 100755 (executable)
index 0000000..5cb5055
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        Model_ResultCompSolid.cpp
+// Created:     20 Jul 2015
+// Author:      Natalia ERMOLAEVA
+
+#include <Model_ResultCompSolid.h>
+
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_Object.h>
+
+#include <Model_BodyBuilder.h>
+
+#include <Model_Document.h>
+
+Model_ResultCompSolid::Model_ResultCompSolid()
+{
+  myBuilder = new Model_BodyBuilder(this);
+}
+
+Model_ResultCompSolid::~Model_ResultCompSolid()
+{
+}
+
+void Model_ResultCompSolid::initAttributes()
+{
+  data()->addAttribute(Model_ResultCompSolid::BODIES_ID(), ModelAPI_AttributeRefList::typeId());
+}
+
+std::shared_ptr<ModelAPI_ResultBody> Model_ResultCompSolid::addResult(const int theIndex)
+{
+  std::shared_ptr<ModelAPI_ResultBody> aBody = document()->createBody(data(), theIndex);
+  if (aBody.get()) {
+    data()->reflist(Model_ResultCompSolid::BODIES_ID())->append(aBody);
+  }
+  return aBody;
+}
+
+int Model_ResultCompSolid::numberOfSubs(bool forTree) const
+{
+  if (forTree)
+    return 0;
+  return data()->reflist(Model_ResultCompSolid::BODIES_ID())->size();
+}
+
+std::shared_ptr<ModelAPI_ResultBody> Model_ResultCompSolid::subResult(const int theIndex,
+                                                                      bool forTree) const
+{
+  if (forTree) {
+    std::shared_ptr<ModelAPI_ResultBody> aBody;
+    return aBody;
+  }
+
+  ObjectPtr anObj = data()->reflist(Model_ResultCompSolid::BODIES_ID())->object(theIndex);
+  return std::dynamic_pointer_cast<ModelAPI_ResultBody>(anObj);
+}
+
+/*int Model_ResultCompSolid::subResultId(const int theIndex) const
+{
+  return subResult(theIndex)->data()->featureId();
+}*/
+
+bool Model_ResultCompSolid::isSub(ObjectPtr theObject) const
+{
+  // check is this feature of result
+  ResultBodyPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theObject);
+  /*if (!aFeature) {
+    ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+    if (aRes)
+      aFeature = document()->feature(aRes);
+  }*/
+  if (aResult) {
+    return data()->reflist(Model_ResultCompSolid::BODIES_ID())->isInList(aResult);
+  }
+  return false;
+}
+
+void Model_ResultCompSolid::removeResult(std::shared_ptr<ModelAPI_ResultBody> theResult)
+{
+  if (!data()->isValid()) // sketch is already removed (case on undo of sketch), sync is not needed
+    return;
+
+  std::list<ObjectPtr> aSubs = data()->reflist(Model_ResultCompSolid::BODIES_ID())->list();
+
+  std::list<ObjectPtr>::iterator aSubIt = aSubs.begin(), aLastIt = aSubs.end();
+  bool isRemoved = false;
+  bool aHasEmtpyResult = false;
+  for(; aSubIt != aLastIt && !isRemoved; aSubIt++) {
+    std::shared_ptr<ModelAPI_ResultBody> aResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aSubIt);
+    if (aResult.get() != NULL && aResult == theResult) {
+      data()->reflist(Model_ResultCompSolid::BODIES_ID())->remove(aResult);
+      isRemoved = true;
+    }
+    else if (aResult.get() == NULL)
+      aHasEmtpyResult = true;
+  }
+  // if the object is not found in the sketch sub-elements, that means that the object is removed already.
+  // Find the first empty element and remove it
+  if (!isRemoved && aHasEmtpyResult)
+    data()->reflist(Model_ResultCompSolid::BODIES_ID())->remove(ObjectPtr());
+}
diff --git a/src/Model/Model_ResultCompSolid.h b/src/Model/Model_ResultCompSolid.h
new file mode 100755 (executable)
index 0000000..f1c697e
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        Model_ResultCompSolid.h
+// Created:     20 Jul 2015
+// Author:      Natalia ERMOLAEVA
+
+#ifndef Model_ResultCompSolid_H_
+#define Model_ResultCompSolid_H_
+
+#include "Model.h"
+#include <ModelAPI_ResultCompSolid.h>
+
+/**\class Model_ResultCompSolid
+ * \ingroup DataModel
+ * \brief The compsolid (container of body results) result of a feature.
+ *
+ * Provides a container of shapes that may be displayed in the viewer.
+ */
+class Model_ResultCompSolid : public ModelAPI_ResultCompSolid
+{
+public:
+  /// All features of this sketch (list of references)
+  inline static const std::string& BODIES_ID()
+  {
+    static const std::string MY_BODIES_ID("Bodies");
+    return MY_BODIES_ID;
+  }
+
+  /// Removes the stored builders
+  MODEL_EXPORT virtual ~Model_ResultCompSolid();
+
+  /// Request for initialization of data model of the object: adding all attributes
+  MODEL_EXPORT virtual void initAttributes();
+
+  /// Adds result to the sketch and to its document
+  /// \param theIndex an index of the created body result in the compsolid
+  /// The real index in the document of the result is an incremented given index
+  /// The reason is that the first index is used for the comp solid result on the data
+  virtual std::shared_ptr<ModelAPI_ResultBody> addResult(const int theIndex);
+
+  /// Returns the number of sub-elements
+  virtual int numberOfSubs(bool forTree = false) const;
+
+  /// Returns the sub-result by zero-base index
+  virtual std::shared_ptr<ModelAPI_ResultBody> subResult(const int theIndex,
+                                                         bool forTree = false) const;
+
+  /// Returns the sub-feature unique identifier in this composite feature by zero-base index
+  //virtual int subResultId(const int theIndex) const;
+
+  /// Returns true if feature or reuslt belong to this composite feature as subs
+  virtual bool isSub(ObjectPtr theObject) const;
+
+  /// This method to inform that sub-feature is removed and must be removed from the internal data
+  /// structures of the owner (the remove from the document will be done outside just after)
+  virtual void removeResult(std::shared_ptr<ModelAPI_ResultBody> theResult);
+
+protected:
+  /// Makes a body on the given feature
+  Model_ResultCompSolid();
+
+  friend class Model_Objects;
+};
+
+#endif
index 96a42d7a875d23eb9d6c4776445459f9bd604223..51e7a18ff33bcd1623e2de5cd0c792898635dd27 100644 (file)
@@ -20,6 +20,7 @@ SET(PROJECT_HEADERS
     ModelAPI_AttributeSelectionList.h
     ModelAPI_AttributeString.h
     ModelAPI_AttributeValidator.h
+    ModelAPI_BodyBuilder.h
     ModelAPI_CompositeFeature.h
     ModelAPI_Data.h
     ModelAPI_Document.h
@@ -30,6 +31,7 @@ SET(PROJECT_HEADERS
     ModelAPI_Plugin.h
     ModelAPI_Result.h
     ModelAPI_ResultBody.h
+    ModelAPI_ResultCompSolid.h
     ModelAPI_ResultConstruction.h
     ModelAPI_ResultGroup.h
     ModelAPI_ResultParameter.h
@@ -38,6 +40,7 @@ SET(PROJECT_HEADERS
     ModelAPI_Tools.h
     ModelAPI_ShapeValidator.h
     ModelAPI_Validator.h
+       ModelAPI_Entity.h
 )
 
 SET(PROJECT_SOURCES
@@ -53,6 +56,7 @@ SET(PROJECT_SOURCES
     ModelAPI_AttributeSelection.cpp
     ModelAPI_AttributeSelectionList.cpp
     ModelAPI_AttributeString.cpp
+    ModelAPI_BodyBuilder.cpp
     ModelAPI_CompositeFeature.cpp
     ModelAPI_Data.cpp
     ModelAPI_Document.cpp
@@ -63,6 +67,7 @@ SET(PROJECT_SOURCES
     ModelAPI_Plugin.cpp
     ModelAPI_Result.cpp
     ModelAPI_ResultBody.cpp
+    ModelAPI_ResultCompSolid.cpp
     ModelAPI_ResultConstruction.cpp
     ModelAPI_ResultGroup.cpp
     ModelAPI_ResultPart.cpp
diff --git a/src/ModelAPI/ModelAPI_BodyBuilder.cpp b/src/ModelAPI/ModelAPI_BodyBuilder.cpp
new file mode 100755 (executable)
index 0000000..8535ced
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModelAPI_ResultBody.cpp
+// Created:     07 Jul 2014
+// Author:      Mikhail PONIKAROV
+
+#include "ModelAPI_BodyBuilder.h"
+#include "ModelAPI_Object.h"
+
+ModelAPI_BodyBuilder::ModelAPI_BodyBuilder(ModelAPI_Object* theOwner)
+: myOwner(theOwner)
+{
+}
+
+std::shared_ptr<ModelAPI_Data> ModelAPI_BodyBuilder::data() const
+{
+  return myOwner->data();
+}
+
+std::shared_ptr<ModelAPI_Document> ModelAPI_BodyBuilder::document() const
+{
+  return myOwner->document();
+}
diff --git a/src/ModelAPI/ModelAPI_BodyBuilder.h b/src/ModelAPI/ModelAPI_BodyBuilder.h
new file mode 100755 (executable)
index 0000000..537c4e4
--- /dev/null
@@ -0,0 +1,109 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModelAPI_BodyBuilder.hxx
+// Created:     07 Jul 2014
+// Author:      Mikhail PONIKAROV
+
+#ifndef ModelAPI_BodyBuilder_H_
+#define ModelAPI_BodyBuilder_H_
+
+#include <ModelAPI.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <memory>
+#include <string>
+
+class ModelAPI_Data;
+class ModelAPI_Document;
+class ModelAPI_Object;
+
+/**\class ModelAPI_BodyBuilder
+* \ingroup DataModel
+*/
+class ModelAPI_BodyBuilder
+{
+public:
+  MODELAPI_EXPORT virtual ~ModelAPI_BodyBuilder() {};
+
+  /// Stores the shape (called by the execution method).
+  virtual void store(const std::shared_ptr<GeomAPI_Shape>& theShape) = 0;
+
+  /// Stores the generated shape (called by the execution method).
+  virtual void storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theFromShape,
+                                 const std::shared_ptr<GeomAPI_Shape>& theToShape) = 0;
+
+  /// Stores the modified shape (called by the execution method).
+  virtual void storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+                                 const std::shared_ptr<GeomAPI_Shape>& theNewShape,
+                            const int theDecomposeSolidsTag = 0) = 0;
+
+  /// 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(
+    const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag = 1) = 0;
+
+  /// Records the shape newShape which was generated from the shape oldShape during a topological 
+  /// construction. As an example, consider the case of a face generated from an edge in 
+  /// construction of a prism.
+  virtual void generated(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+    const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag = 1) = 0;
+
+  /// Records the shape newShape which is a modification of the shape oldShape.
+  /// As an example, consider the case of a face split or merged in a Boolean operation.
+  virtual void modified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
+    const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag = 1) = 0;
+
+  /// Records the shape oldShape which was deleted from the current label.
+  /// As an example, consider the case of a face removed by a Boolean operation.
+  virtual void deleted(
+    const std::shared_ptr<GeomAPI_Shape>& theOldShape, const int theTag = 1) = 0;
+  
+  /// load deleted shapes
+  virtual void loadDeletedShapes (GeomAlgoAPI_MakeShape* theMS,
+                                               std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+                                               const int  theKindOfShape,
+                                               const int  theTag) = 0;
+  /// load and orient modified shapes
+  virtual void loadAndOrientModifiedShapes (
+                                                  GeomAlgoAPI_MakeShape* theMS,
+                                               std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+                                               const int  theKindOfShape,
+                                               const int  theTag,
+                                                                                          const std::string& theName,
+                                               GeomAPI_DataMapOfShapeShape& theSubShapes) = 0;
+  /// load and orient generated shapes
+  virtual void loadAndOrientGeneratedShapes (
+                                                  GeomAlgoAPI_MakeShape* theMS,
+                                               std::shared_ptr<GeomAPI_Shape>  theShapeIn,
+                                               const int  theKindOfShape,
+                                               const int  theTag,
+                                                                                          const std::string& theName,
+                                               GeomAPI_DataMapOfShapeShape& theSubShapes) = 0;
+
+  /// load shapes of the first level (to be used during shape import)
+  virtual void loadFirstLevel(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag) = 0;
+  
+  /// load disconnected edges
+  virtual void loadDisconnectedEdges(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag) = 0;
+
+  /// load disconnected vetexes
+  virtual void loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName,int&  theTag) = 0;
+
+protected:
+  /// Returns the data manager of this object: attributes
+  MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_Data> data() const;
+
+  /// Returns document this feature belongs to
+  MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_Document> document() const;
+
+protected:
+  MODELAPI_EXPORT ModelAPI_BodyBuilder(ModelAPI_Object* theOwner);
+
+  ModelAPI_Object* myOwner;
+};
+
+//! Pointer on feature object
+typedef std::shared_ptr<ModelAPI_BodyBuilder> BodyBuilderPtr;
+
+#endif
index 9f9297001404e35710b7202ba6b5be1b1520c385..9557a0851235e1552d27c5cebf82efa864e2cd3e 100644 (file)
@@ -7,7 +7,9 @@
 #ifndef ModelAPI_Document_H_
 #define ModelAPI_Document_H_
 
-#include <ModelAPI.h>
+#include "ModelAPI.h"
+#include "ModelAPI_Entity.h"
+
 #include <string>
 #include <memory>
 #include <vector>
@@ -19,6 +21,7 @@ class ModelAPI_Object;
 class ModelAPI_Result;
 class ModelAPI_ResultConstruction;
 class ModelAPI_ResultBody;
+class ModelAPI_ResultCompSolid;
 class ModelAPI_ResultPart;
 class ModelAPI_ResultGroup;
 class ModelAPI_ResultParameter;
@@ -30,7 +33,7 @@ class ModelAPI_Data;
  * Document contains all data that must be stored/retrived in the file.
  * Also it provides acces to this data: open/save, transactions management etc.
  */
-class ModelAPI_Document
+class ModelAPI_Document: public ModelAPI_Entity
 {
 public:
   //! Returns the kind of the document: "PartSet", "Part", or something else.
@@ -121,6 +124,9 @@ public:
   //! Creates a body results
   virtual std::shared_ptr<ModelAPI_ResultBody> createBody(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0) = 0;
+  /// Creates a compsolid results
+  virtual std::shared_ptr<ModelAPI_ResultCompSolid> createCompSolid(
+      const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0) = 0;
   //! Creates a part results
   virtual std::shared_ptr<ModelAPI_ResultPart> createPart(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0) = 0;
diff --git a/src/ModelAPI/ModelAPI_Entity.h b/src/ModelAPI/ModelAPI_Entity.h
new file mode 100644 (file)
index 0000000..49503c3
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModelAPI_Entity.h
+// Created:     27 July 2015
+// Author:      Vitaly SMETANNIKOV
+
+#ifndef ModelAPI_Entity_H_
+#define ModelAPI_Entity_H_
+
+/**\class ModelAPI_Entity
+ * \ingroup DataModel
+ * \brief Represents a common parent class for Objects and documents.
+ * Provided in order to make possible distingiushing of objects and documents
+ * by downcasting of their pointers.
+ */
+class ModelAPI_Entity
+{
+public:
+  /// Empty function which is added for virtualisation of the interface
+  virtual void emptyFunction() const {}
+};
+
+#endif
\ No newline at end of file
index fd54a5f2d9f8215ccc95e334a39260c404532011..07776479cf194c85bbae1d5bd82807fab11315b1 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "ModelAPI.h"
 #include "ModelAPI_Data.h"
+#include "ModelAPI_Entity.h"
 
 #include <memory>
 
@@ -24,7 +25,7 @@ class ModelAPI_Document;
  * objects related to the features and their results. Contains attributes of this 
  * object in the "Data".
  */
-class ModelAPI_Object
+class ModelAPI_Object: public ModelAPI_Entity
 {
   std::shared_ptr<ModelAPI_Data> myData;  ///< manager of the data model of a feature
   std::shared_ptr<ModelAPI_Document> myDoc;  ///< document this object belongs to
index 9d001619d0922ff39901b3c38c984b677cb9f542..1d5d38824d92622d13d5d6f66deecadde14abe5a 100644 (file)
@@ -6,9 +6,15 @@
 
 #include "ModelAPI_ResultBody.h"
 
+ModelAPI_ResultBody::ModelAPI_ResultBody()
+: myBuilder(0)
+{
+}
+
 ModelAPI_ResultBody::~ModelAPI_ResultBody()
 {
-  
+  if (myBuilder)
+  delete myBuilder;
 }
 
 std::string ModelAPI_ResultBody::groupName()
index 05aeab91c11d215496399b3b091cdc4558faadf6..8c5c9e6b9794186865e254f948606ba551301d1e 100644 (file)
@@ -9,11 +9,13 @@
 
 #include "ModelAPI_Result.h"
 #include <GeomAPI_Shape.h>
-#include <GeomAlgoAPI_MakeShape.h>
-#include <GeomAPI_DataMapOfShapeShape.h>
-#include <memory>
+//#include <GeomAlgoAPI_MakeShape.h>
+//#include <GeomAPI_DataMapOfShapeShape.h>
+//#include <memory>
 #include <string>
 
+class ModelAPI_BodyBuilder;
+
 /**\class ModelAPI_ResultBody
 * \ingroup DataModel
 * \brief The body (shape) result of a feature.
@@ -43,8 +45,11 @@ public:
     return RESULT_BODY_COLOR;
   }
 
+  /// Returns the builder, which processes the shapes
+  ModelAPI_BodyBuilder* getBodyBuilder() { return myBuilder; }
+
   /// Stores the shape (called by the execution method).
-  virtual void store(const std::shared_ptr<GeomAPI_Shape>& theShape) = 0;
+  /*virtual void store(const std::shared_ptr<GeomAPI_Shape>& theShape) = 0;
 
   /// Stores the generated shape (called by the execution method).
   virtual void storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theFromShape,
@@ -106,8 +111,12 @@ public:
 
   /// load disconnected vetexes
   virtual void loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName,int&  theTag) = 0;
+  */
+protected:
+  MODELAPI_EXPORT ModelAPI_ResultBody();
 
 protected:
+  ModelAPI_BodyBuilder* myBuilder; /// provide the body processing in naming shape
 };
 
 //! Pointer on feature object
diff --git a/src/ModelAPI/ModelAPI_ResultCompSolid.cpp b/src/ModelAPI/ModelAPI_ResultCompSolid.cpp
new file mode 100755 (executable)
index 0000000..1942d2c
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModelAPI_ResultCompSolid.cpp
+// Created:     20 Jul 2015
+// Author:      Natalia ERMOLAEVA
+
+#include "ModelAPI_ResultCompSolid.h"
+
+ModelAPI_ResultCompSolid::~ModelAPI_ResultCompSolid()
+{
+}
+
+bool ModelAPI_ResultCompSolid::isDisabled() const
+{
+  return false;
+}
+
+
diff --git a/src/ModelAPI/ModelAPI_ResultCompSolid.h b/src/ModelAPI/ModelAPI_ResultCompSolid.h
new file mode 100755 (executable)
index 0000000..a953aaf
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModelAPI_ResultCompSolid.hxx
+// Created:     20 Jul 2015
+// Author:      Natalia ERMOLAEVA
+
+#ifndef ModelAPI_ResultCompSolid_H_
+#define ModelAPI_ResultCompSolid_H_
+
+#include "ModelAPI_Result.h"
+#include "ModelAPI_ResultBody.h"
+#include <string>
+
+/**\class ModelAPI_ResultCompSolid
+* \ingroup DataModel
+* \brief The comp solid (container of results) result of a feature.
+*
+* Provides a conainer of body result that may be displayed in the viewer.
+*/
+class ModelAPI_ResultCompSolid : public ModelAPI_ResultBody
+{
+public:
+  MODELAPI_EXPORT virtual ~ModelAPI_ResultCompSolid();
+  /// Returns the group identifier of this result
+
+  /// Returns the feature is disabled or not.
+  MODELAPI_EXPORT virtual bool isDisabled() const;
+
+  /// Adds result to the sketch and to its document
+  /// \param theIndex an index of the created body result in the compsolid
+  virtual std::shared_ptr<ModelAPI_ResultBody> addResult(const int theIndex) = 0;
+
+  /// Returns the number of sub-elements
+  virtual int numberOfSubs(bool forTree = false) const = 0;
+
+  /// Returns the sub-result by zero-base index
+  virtual std::shared_ptr<ModelAPI_ResultBody> subResult(const int theIndex,
+                                                         bool forTree = false) const = 0;
+
+  /// Returns the sub-feature unique identifier in this composite feature by zero-base index
+  //virtual int subResultId(const int theIndex) const = 0;
+
+  /// Returns true if feature or reuslt belong to this composite feature as subs
+  virtual bool isSub(ObjectPtr theObject) const = 0;
+
+  /// This method to inform that sub-feature is removed and must be removed from the internal data
+  /// structures of the owner (the remove from the document will be done outside just after)
+  virtual void removeResult(std::shared_ptr<ModelAPI_ResultBody> theResult) = 0;
+
+protected:
+};
+
+//! Pointer on feature object
+typedef std::shared_ptr<ModelAPI_ResultCompSolid> ResultCompSolidPtr;
+
+#endif
index 3ffd15ec47decc84cf994de4df460a061a60915c..09fc2c0bee522fdba7d74eb34378f6a0436c0bbf 100644 (file)
@@ -59,6 +59,18 @@ bool findVariable(const std::string& theName, double& outValue, ResultParameterP
   return false;
 }
 
+bool findVariable(const DocumentPtr& theDocument, const std::string& theName, 
+                  double& outValue, ResultParameterPtr& theParam)
+{
+  ObjectPtr aParamObj = theDocument->objectByName(ModelAPI_ResultParameter::group(), theName);
+  theParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
+  if (!theParam.get())
+    return false;
+  AttributeDoublePtr aValueAttribute = theParam->data()->real(ModelAPI_ResultParameter::VALUE());
+  outValue = aValueAttribute->value();
+  return true;
+}
+
 static std::map<int, std::vector<int> > myColorMap;
 
 void appendValues(std::vector<int>& theRGB, const int theRed, const int theGreen, const int theBlue)
index 67b0427be62dbd1215e0541682346ea30811ed1e..b99b9f87ed738955135c523b752f5d88b3422985 100644 (file)
@@ -29,6 +29,13 @@ MODELAPI_EXPORT std::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult)
 MODELAPI_EXPORT bool findVariable(const std::string& theName, double& outValue, 
   ResultParameterPtr& theParam);
 
+/*!
+ * Searches for variable with name \param theName in the document. 
+ * If found, set it value in the \param outValue and returns true.
+ */
+MODELAPI_EXPORT bool findVariable(const DocumentPtr& theDocument, const std::string& theName, 
+                                  double& outValue, ResultParameterPtr& theParam);
+
 /*!
  * Returns the values of the next random color. The values are in range [0, 255]
  * \param theValues a container of component of RGB value: red, green, blue
index a15c841c52523368acb91153c0ac45bf25dfb921..54fc7c1b1107f81bcb1ac7d5710c9bf8393e9c78 100644 (file)
@@ -5,96 +5,98 @@ SET(CMAKE_AUTOMOC ON)
 
 SET(PROJECT_HEADERS
        ModuleBase.h
-       ModuleBase_Filter.h
-       ModuleBase_FilterFactory.h
-       ModuleBase_FilterValidated.h
-       ModuleBase_Tools.h
-       ModuleBase_IModule.h
-       ModuleBase_Operation.h
-       ModuleBase_OperationDescription.h       
-       ModuleBase_ModelWidget.h
-       ModuleBase_WidgetBoolValue.h
-       ModuleBase_WidgetDoubleValue.h
-       ModuleBase_WidgetEditor.h
-       ModuleBase_WidgetFactory.h
-       ModuleBase_IWorkshop.h
-       ModuleBase_Definitions.h
-       ModuleBase_SelectionValidator.h
-       ModuleBase_ViewerPrs.h
-       ModuleBase_WidgetChoice.h
-       ModuleBase_WidgetFileSelector.h
-       ModuleBase_DoubleSpinBox.h
-       ModuleBase_IPropertyPanel.h
-       ModuleBase_ISelection.h
-       ModuleBase_IViewer.h
-       ModuleBase_WidgetLineEdit.h
-       ModuleBase_WidgetMultiSelector.h
-       ModuleBase_ViewerFilters.h
-       ModuleBase_ResultPrs.h
-       ModuleBase_IViewWindow.h
-       ModuleBase_WidgetLabel.h
-       ModuleBase_IPrefMgr.h
-       ModuleBase_Preferences.h
-       ModuleBase_ActionInfo.h
-       ModuleBase_PageBase.h
-       ModuleBase_PageWidget.h 
-       ModuleBase_PageGroupBox.h
-       ModuleBase_PagedContainer.h
-       ModuleBase_WidgetSelector.h
-       ModuleBase_WidgetShapeSelector.h
-       ModuleBase_WidgetSwitch.h
-       ModuleBase_WidgetToolbox.h
-       ModuleBase_WidgetValidated.h
-       ModuleBase_WidgetExprEditor.h
-       ModuleBase_ParamSpinBox.h
-       ModuleBase_WidgetIntValue.h
+  ModuleBase_ActionInfo.h
+  ModuleBase_Definitions.h
+  ModuleBase_DoubleSpinBox.h
+  ModuleBase_Filter.h
+  ModuleBase_FilterFactory.h
+  ModuleBase_FilterValidated.h
   ModuleBase_IDocumentDataModel.h
+  ModuleBase_IModule.h
+  ModuleBase_IPrefMgr.h
+  ModuleBase_IPropertyPanel.h
+  ModuleBase_ISelection.h
+  ModuleBase_IViewWindow.h
+  ModuleBase_IViewer.h
+  ModuleBase_IWorkshop.h
+  ModuleBase_ModelWidget.h
+  ModuleBase_Operation.h
+  ModuleBase_OperationDescription.h    
+  ModuleBase_PageBase.h
+  ModuleBase_PageGroupBox.h
+  ModuleBase_PageWidget.h      
+  ModuleBase_PagedContainer.h
+  ModuleBase_ParamSpinBox.h
+  ModuleBase_Preferences.h
+  ModuleBase_ResultPrs.h
+  ModuleBase_SelectionValidator.h
+  ModuleBase_Tools.h
+  ModuleBase_ViewerFilters.h
+  ModuleBase_ViewerPrs.h
+  ModuleBase_WidgetBoolValue.h
+  ModuleBase_WidgetChoice.h
+  ModuleBase_WidgetDoubleValue.h
+  ModuleBase_WidgetEditor.h
+  ModuleBase_WidgetExprEditor.h
+  ModuleBase_WidgetFactory.h
+  ModuleBase_WidgetFileSelector.h
+  ModuleBase_WidgetIntValue.h
+  ModuleBase_WidgetLabel.h
+  ModuleBase_WidgetLineEdit.h
+  ModuleBase_WidgetMultiSelector.h
+  ModuleBase_WidgetSelector.h
+  ModuleBase_WidgetShapeSelector.h
+  ModuleBase_WidgetSwitch.h
+  ModuleBase_WidgetToolbox.h
+  ModuleBase_WidgetValidated.h
+  ModuleBase_IconFactory.h
 )
 
 SET(PROJECT_SOURCES
-       ModuleBase_Filter.cpp
-       ModuleBase_FilterFactory.cpp
-       ModuleBase_FilterValidated.cpp
-       ModuleBase_Tools.cpp
-       ModuleBase_IModule.cpp
-       ModuleBase_ISelection.cpp
-       ModuleBase_IViewer.cpp
-       ModuleBase_IWorkshop.cpp
-       ModuleBase_Operation.cpp
-       ModuleBase_OperationDescription.cpp
-       ModuleBase_ModelWidget.cpp
-       ModuleBase_WidgetBoolValue.cpp
-       ModuleBase_WidgetDoubleValue.cpp
-       ModuleBase_WidgetEditor.cpp
-       ModuleBase_WidgetFactory.cpp
-       ModuleBase_WidgetChoice.cpp
-       ModuleBase_WidgetFileSelector.cpp
-       ModuleBase_DoubleSpinBox.cpp
-       ModuleBase_IPropertyPanel.cpp
-       ModuleBase_WidgetLineEdit.cpp
-       ModuleBase_WidgetMultiSelector.cpp
-       ModuleBase_ViewerFilters.cpp
-       ModuleBase_ResultPrs.cpp
-       ModuleBase_IViewWindow.cpp
-       ModuleBase_WidgetLabel.cpp
-       ModuleBase_IPrefMgr.cpp
-       ModuleBase_Preferences.cpp
-       ModuleBase_ActionInfo.cpp
-       ModuleBase_PageBase.cpp
-       ModuleBase_PageWidget.cpp
-       ModuleBase_PageGroupBox.cpp
-       ModuleBase_PagedContainer.cpp
-       ModuleBase_WidgetSelector.cpp
-       ModuleBase_WidgetShapeSelector.cpp
-       ModuleBase_WidgetSwitch.cpp
-       ModuleBase_WidgetToolbox.cpp
-       ModuleBase_WidgetValidated.cpp
-       ModuleBase_WidgetExprEditor.cpp
-       ModuleBase_ParamSpinBox.cpp
-       ModuleBase_SelectionValidator.cpp
-       ModuleBase_ViewerPrs.cpp
-       ModuleBase_WidgetIntValue.cpp
+  ModuleBase_ActionInfo.cpp
+  ModuleBase_DoubleSpinBox.cpp
+  ModuleBase_Filter.cpp
+  ModuleBase_FilterFactory.cpp
+  ModuleBase_FilterValidated.cpp
   ModuleBase_IDocumentDataModel.cpp
+  ModuleBase_IModule.cpp
+  ModuleBase_IPrefMgr.cpp
+  ModuleBase_IPropertyPanel.cpp
+  ModuleBase_ISelection.cpp
+  ModuleBase_IViewWindow.cpp
+  ModuleBase_IViewer.cpp
+  ModuleBase_IWorkshop.cpp
+  ModuleBase_ModelWidget.cpp
+  ModuleBase_Operation.cpp
+  ModuleBase_OperationDescription.cpp
+  ModuleBase_PageBase.cpp
+  ModuleBase_PageGroupBox.cpp
+  ModuleBase_PageWidget.cpp
+  ModuleBase_PagedContainer.cpp
+  ModuleBase_ParamSpinBox.cpp
+  ModuleBase_Preferences.cpp
+  ModuleBase_ResultPrs.cpp
+  ModuleBase_SelectionValidator.cpp
+  ModuleBase_Tools.cpp
+  ModuleBase_ViewerFilters.cpp
+  ModuleBase_ViewerPrs.cpp
+  ModuleBase_WidgetBoolValue.cpp
+  ModuleBase_WidgetChoice.cpp
+  ModuleBase_WidgetDoubleValue.cpp
+  ModuleBase_WidgetEditor.cpp
+  ModuleBase_WidgetExprEditor.cpp
+  ModuleBase_WidgetFactory.cpp
+  ModuleBase_WidgetFileSelector.cpp
+  ModuleBase_WidgetIntValue.cpp
+  ModuleBase_WidgetLabel.cpp
+  ModuleBase_WidgetLineEdit.cpp
+  ModuleBase_WidgetMultiSelector.cpp
+  ModuleBase_WidgetSelector.cpp
+  ModuleBase_WidgetShapeSelector.cpp
+  ModuleBase_WidgetSwitch.cpp
+  ModuleBase_WidgetToolbox.cpp
+  ModuleBase_WidgetValidated.cpp
+  ModuleBase_IconFactory.cpp
 )
 
 SET(PROJECT_LIBRARIES
index a5e3d95c854b3733f5a8555102734aecbf640859..aecb0152f5a183e95e71d003e414058963092176 100644 (file)
@@ -31,6 +31,10 @@ public:
 
   //! Rebuild data tree
   virtual void rebuildDataTree();
+
+  /// Returns last history object index
+  virtual QModelIndex lastHistoryIndex() const { return QModelIndex(); }
+
 };
 
 #endif
\ No newline at end of file
diff --git a/src/ModuleBase/ModuleBase_IconFactory.cpp b/src/ModuleBase/ModuleBase_IconFactory.cpp
new file mode 100644 (file)
index 0000000..f87fa91
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModuleBase_IconFactory.cpp
+// Created:     28 Jul 2015
+// Author:      Vitaly SMETANNIKOV
+
+
+#include "ModuleBase_IconFactory.h"
+
+ModuleBase_IconFactory* MYIconFactory = 0;
+
+
+void ModuleBase_IconFactory::setFactory(ModuleBase_IconFactory* theFactory)
+{
+  if (MYIconFactory)
+    delete MYIconFactory;
+  MYIconFactory = theFactory;
+}
+
+ModuleBase_IconFactory* ModuleBase_IconFactory::get()
+{
+  if (!MYIconFactory) {
+    MYIconFactory = new ModuleBase_IconFactory();
+  }
+  return MYIconFactory;
+}
+
+QIcon ModuleBase_IconFactory::getIcon(ObjectPtr theIcon)
+{
+  return QIcon();
+}
diff --git a/src/ModuleBase/ModuleBase_IconFactory.h b/src/ModuleBase/ModuleBase_IconFactory.h
new file mode 100644 (file)
index 0000000..3a7c99d
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModuleBase_IconFactory.h
+// Created:     28 Jul 2015
+// Author:      Vitaly SMETANNIKOV
+
+#ifndef ModuleBase_IconFactory_H
+#define ModuleBase_IconFactory_H
+
+#include "ModuleBase.h"
+#include <ModelAPI_Object.h>
+#include <QIcon>
+
+/**\class ModuleBase_IconFactory
+ * \ingroup GUI
+ * \brief This is a class which provides icons of objects for object browser 
+ */
+class MODULEBASE_EXPORT ModuleBase_IconFactory
+{
+public:
+  /// Returns icons factory instance
+  static ModuleBase_IconFactory* get();
+
+  /// Returns Icon for the given object
+  /// \param theObj an object
+  virtual QIcon getIcon(ObjectPtr theObj);
+
+protected:
+  /// Set the current icons factory instance
+  /// \param theFactory a new factory
+  static void setFactory(ModuleBase_IconFactory* theFactory);
+};
+
+#endif
\ No newline at end of file
index c1f400ad41e28fef1ba2219d55b4ae51a90f467d..13d1d22d69b7298e9d20e35eef91ef5b4e4f4310 100644 (file)
@@ -12,6 +12,7 @@
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_Tools.h>
 
 #include <GeomDataAPI_Point2D.h>
@@ -221,6 +222,14 @@ TopAbs_ShapeEnum shapeType(const QString& theType)
   return TopAbs_SHAPE;
 }
 
+bool isSubResult(ObjectPtr theObject)
+{
+  bool aSubResult = false;
+
+  //ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
+  return aSubResult;
+}
+
 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature, bool& hasParameter, bool& hasSubFeature)
 {
   hasResult = false;
@@ -232,7 +241,10 @@ void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFe
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
     ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
 
-    hasResult = (aResult.get() != NULL);
+    bool aSubResult = isSubResult(aResult);
+
+    /// results of compsolids are not processed in SHOW/HIDE/WIREFRAME operations
+    hasResult = (aResult.get() != NULL && !aSubResult);
     hasFeature = (aFeature.get() != NULL);
     hasParameter = (aConstruction.get() != NULL);
     if (hasFeature) 
index cc7ced07abde5356555f8011027a4d41666bf57b..e0aa9c6ed5407bdb44dad024e0dcc5adc27883e8 100644 (file)
@@ -83,6 +83,11 @@ MODULEBASE_EXPORT QString objectInfo(const ObjectPtr& theObj, const bool isUseAt
 /// \return TopAbs_ShapeEnum value
 MODULEBASE_EXPORT TopAbs_ShapeEnum shapeType(const QString& theType);
 
+/// Checks whether the object is a sub result. It gets the feature of the object,
+/// obtains all results of the feature and check if the object is a sub result
+/// \return boolean result
+MODULEBASE_EXPORT bool isSubResult(ObjectPtr theObject);
+
 /*!
 Check types of objects which are in the given list
 \param theObjects the list of objects
index 2787b00acf3b0d97fd9921592528380e9a906b5d..2e2290491abe5e78514fd9e0514a5c0fac4fd304 100644 (file)
@@ -152,7 +152,7 @@ ModuleBase_ModelWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::
     result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi, myParentId);
     #ifdef _DEBUG
     if (!result) {
-      qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type");
+      qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type %s", theType.c_str());
     }
     #endif
   }
index 9d64cef324a22e09e892f139bbd54aabded6c348..2ec43200f30894fe74f80e3268379ac19cbf91e7 100644 (file)
@@ -45,50 +45,58 @@ bool ParametersPlugin_Parameter::isInHistory()
 
 void ParametersPlugin_Parameter::attributeChanged(const std::string& theID)
 {
-  if (theID == EXPRESSION_ID()) { // recompute only on change of the expression
-    ResultParameterPtr aParam = document()->createParameter(data());
-
-    std::string anExpression = string(EXPRESSION_ID())->value();
-    if(anExpression.empty()) {
-      // clear error/result if the expression is empty
-      setError("", false);
-      return;
-    }
-    std::string outErrorMessage;
-    double aValue = evaluate(anExpression, outErrorMessage);
-    // Name
-    std::string aName = string(VARIABLE_ID())->value();
-    std::ostringstream sstream;
-    sstream << aValue;
-    std::string aParamValue = sstream.str();
-    data()->setName(aName);
-    aParam->data()->setName(aName);
-    // Error
-    if (!outErrorMessage.empty()) {
-      std::string aStateMsg("Error: " + outErrorMessage);
-      data()->execState(ModelAPI_StateExecFailed);
-      setError(aStateMsg, false);
-    } else {
-      static const std::string anEmptyMsg(""); // it is checked in the validator by the empty message
-      setError(anEmptyMsg, false);
-      data()->execState(ModelAPI_StateDone);
-    }
-    // Value
-    AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
-    aValueAttribute->setValue(aValue);
-    setResult(aParam);
+  if (theID == EXPRESSION_ID())
+    updateExpression();
+}
+
+void ParametersPlugin_Parameter::updateName()
+{
+  std::string aName = string(VARIABLE_ID())->value();
+  data()->setName(aName);
+
+  ResultParameterPtr aParam = document()->createParameter(data());
+  aParam->data()->setName(aName);
+  setResult(aParam);
+}
+
+void ParametersPlugin_Parameter::updateExpression()
+{
+  std::string anExpression = string(EXPRESSION_ID())->value();
+  if(anExpression.empty()) {
+    // clear error/result if the expression is empty
+    setError("", false);
+    return;
   }
+  std::string outErrorMessage;
+  double aValue = evaluate(anExpression, outErrorMessage);
+  std::ostringstream sstream;
+  sstream << aValue;
+  std::string aParamValue = sstream.str();
+  // Error
+  if (!outErrorMessage.empty()) {
+    std::string aStateMsg("Error: " + outErrorMessage);
+    data()->execState(ModelAPI_StateExecFailed);
+    setError(aStateMsg, false);
+  } else {
+    static const std::string anEmptyMsg(""); // it is checked in the validator by the empty message
+    setError(anEmptyMsg, false);
+    data()->execState(ModelAPI_StateDone);
+  }
+
+  ResultParameterPtr aParam = document()->createParameter(data());
+  AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
+  aValueAttribute->setValue(aValue);
+  setResult(aParam);
 }
 
 void ParametersPlugin_Parameter::execute()
 {
-  // just call recompute
-  attributeChanged(EXPRESSION_ID());
+  updateName();
+  updateExpression();
 }
 
 double ParametersPlugin_Parameter::evaluate(const std::string& theExpression, std::string& theError)
 {
-
   std::list<std::string> anExprParams = myInterp->compile(theExpression);
   // find expression's params in the model
   std::list<std::string> aContext;
index c348d0f733d257d7bb1820e2a167b668cd769249..c735c8ee7b4c2b026110ccfdc115998aa28738b8 100644 (file)
@@ -72,6 +72,8 @@ class ParametersPlugin_Parameter : public ModelAPI_Feature
 
  protected:
   double evaluate(const std::string& theExpression, std::string& theError);
+  void updateName();
+  void updateExpression();
 
  private:
   std::shared_ptr<ParametersPlugin_PyInterp> myInterp;
index cfc99c2627f812f39e4b809b33dbb52337017fe4..4e810d765ac3be7cf8b10a32e1b53248e5ceb68e 100644 (file)
@@ -51,15 +51,15 @@ class TestParameterRename(unittest.TestCase):
         ltNames = ["x1", "y1", "x2"]
         ltExpressions = ["150.", "200.", "x1 + y1 + 100.0"]
         self.dtParams = {}
-        self.aSession.startOperation()
         for name, expr in zip(ltNames, ltExpressions):
+            self.aSession.startOperation()
             aParam = self.aDocument.addFeature("Parameter")
             aParamName = aParam.string("variable")
             aParamName.setValue(name)
             aParamExpr = aParam.string("expression")
             aParamExpr.setValue(expr)
             self.dtParams[name] = aParam
-        self.aSession.finishOperation()
+            self.aSession.finishOperation()
         self.assertEqual(len(self.dtParams), len(ltNames))
 
         aParam = self.dtParams["x2"]
index ef8bd2e6bca64c0ba2052ab48fd63fb5bb153729..5521426308a481a6ae59758b712fe18dc300e320 100644 (file)
@@ -53,15 +53,15 @@ class TestParameterRename(unittest.TestCase):
         ltNames = ["x1", "y1", "x2"]
         ltExpressions = ["150.", "200.", "x1 + y1 + 100.0"]
         self.dtParams = {}
-        self.aSession.startOperation()
         for name, expr in zip(ltNames, ltExpressions):
+            self.aSession.startOperation()
             aParam = self.aDocument.addFeature("Parameter")
             aParamName = aParam.string("variable")
             aParamName.setValue(name)
             aParamExpr = aParam.string("expression")
             aParamExpr.setValue(expr)
             self.dtParams[name] = aParam
-        self.aSession.finishOperation()
+            self.aSession.finishOperation()
         self.assertEqual(len(self.dtParams), len(ltNames))
 
         aParam = self.dtParams["x2"]
index eabe491f0f3c372c554bac781c6920f27175ea65..4bc8ebfcd35e5d660cfd1db301bb1b9b18e75f59 100644 (file)
@@ -31,6 +31,7 @@ SET(PROJECT_HEADERS
        PartSet_DataTreeModel.h
        PartSet_WidgetSketchCreator.h
        PartSet_TopDataModel.h
+       PartSet_IconFactory.h
 )
 
 SET(PROJECT_SOURCES
@@ -58,6 +59,7 @@ SET(PROJECT_SOURCES
        PartSet_DataTreeModel.cpp
        PartSet_WidgetSketchCreator.cpp
        PartSet_TopDataModel.cpp
+       PartSet_IconFactory.cpp
 )
 
 SET(PROJECT_RESOURCES 
diff --git a/src/PartSet/PartSet_IconFactory.cpp b/src/PartSet/PartSet_IconFactory.cpp
new file mode 100644 (file)
index 0000000..30fe5aa
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        PartSet_IconFactory.cpp
+// Created:     28 Jul 2015
+// Author:      Vitaly SMETANNIKOV
+
+#include "PartSet_IconFactory.h"
+#include <ModuleBase_ActionInfo.h>
+#include <ModuleBase_Tools.h>
+
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <Config_FeatureMessage.h>
+#include <Events_Loop.h>
+
+QMap<QString, QString> PartSet_IconFactory::myIcons;
+
+PartSet_IconFactory::PartSet_IconFactory():ModuleBase_IconFactory()
+{
+  setFactory(this);
+  Events_Loop::loop()->registerListener(this, 
+    Events_Loop::eventByName(Config_FeatureMessage::GUI_EVENT()));
+}
+
+
+QIcon PartSet_IconFactory::getIcon(ObjectPtr theObj)
+{
+  QIcon anIcon;
+
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
+  if (aFeature.get()) {
+    std::string aKind = aFeature->getKind();
+    QString aId(aKind.c_str());
+    if (!myIcons.contains(aId))
+      return anIcon;
+
+    QString anIconString = myIcons[aId];
+
+    ModelAPI_ExecState aState = aFeature->data()->execState();
+    switch(aState) {
+      case ModelAPI_StateDone:
+      case ModelAPI_StateNothing: {
+        anIcon = QIcon(anIconString);
+      }
+      break;
+      case ModelAPI_StateMustBeUpdated: {
+        anIcon = ModuleBase_Tools::lighter(anIconString);
+      }
+      break;
+      case ModelAPI_StateExecFailed: {
+        anIcon = ModuleBase_Tools::composite(":icons/exec_state_failed.png", anIconString);
+      }
+      break;
+      case ModelAPI_StateInvalidArgument: {
+        anIcon = ModuleBase_Tools::composite(":icons/exec_state_invalid_parameters.png",
+                                             anIconString);
+      }
+      break;
+      default: break;  
+    }
+  } else {
+    std::string aGroup = theObj->groupName();
+    if (aGroup == ModelAPI_ResultPart::group()) {
+      return QIcon(":pictures/part_ico.png");
+    } else {
+      if (theObj && theObj->data() && theObj->data()->execState() == ModelAPI_StateMustBeUpdated)
+        return QIcon(":pictures/constr_object_modified.png");
+      return QIcon(":pictures/constr_object.png");
+    }
+  }
+  return anIcon;  
+}
+
+void PartSet_IconFactory::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) {
+    std::shared_ptr<Config_FeatureMessage> aFeatureMsg =
+       std::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
+    if (!aFeatureMsg->isInternal()) {
+      ActionInfo aFeatureInfo;
+      aFeatureInfo.initFrom(aFeatureMsg);
+      // Remember features icons
+      myIcons[QString::fromStdString(aFeatureMsg->id())] = aFeatureInfo.iconFile;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/PartSet/PartSet_IconFactory.h b/src/PartSet/PartSet_IconFactory.h
new file mode 100644 (file)
index 0000000..a6a51e2
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        PartSet_IconFactory.h
+// Created:     28 Jul 2015
+// Author:      Vitaly SMETANNIKOV
+
+#ifndef PartSet_IconFactory_H
+#define PartSet_IconFactory_H
+
+#include "PartSet.h"
+#include <ModuleBase_IconFactory.h>
+#include <Events_Listener.h>
+
+#include <QMap>
+
+
+/**\class PartSet_IconFactory
+ * \ingroup GUI
+ * \brief This is a class is redefined in order to provide
+ * icons of objects for object browser specific for PartSetModule
+ */
+class PARTSET_EXPORT PartSet_IconFactory : public ModuleBase_IconFactory, public Events_Listener
+{
+public:
+  /// Constructor
+  PartSet_IconFactory();
+
+  /// Returns Icon for the given object
+  /// \param theObj an object
+  virtual QIcon getIcon(ObjectPtr theObj);
+
+  /// Event Listener method
+  /// \param theMessage an event message
+  virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
+private:
+  static QMap<QString, QString> myIcons;
+};
+
+#endif
\ No newline at end of file
index f232b9b4845a5fba8b2a5185f270c073d3c41a4c..c5ad640cbfc728b4feb850051c3a03585ba2b3c0 100644 (file)
@@ -26,6 +26,8 @@
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Workshop.h>
 #include <XGUI_Displayer.h>
+#include <XGUI_DataModel.h>
+#include <XGUI_ObjectsBrowser.h>
 
 #include <Events_Loop.h>
 #include <ModelAPI_Events.h>
index 0d493f7f20f36032d55c98f80cd3e94b0263da21..96083adb9213cff98f7a196af56a0bf18ce5f64c 100644 (file)
@@ -15,7 +15,8 @@
 #include "PartSet_WidgetSketchCreator.h"
 #include "PartSet_SketcherMgr.h"
 #include "PartSet_MenuMgr.h"
-#include <PartSet_CustomPrs.h>
+#include "PartSet_CustomPrs.h"
+#include "PartSet_IconFactory.h"
 
 #include "PartSet_Filters.h"
 #include "PartSet_FilterInfinite.h"
@@ -60,6 +61,7 @@
 #include <XGUI_Tools.h>
 #include <XGUI_ObjectsBrowser.h>
 #include <XGUI_SelectionMgr.h>
+#include <XGUI_DataModel.h>
 
 #include <SketchPlugin_Feature.h>
 #include <SketchPlugin_Sketch.h>
@@ -117,6 +119,8 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
   : ModuleBase_IModule(theWshop),
   myRestartingMode(RM_None), myVisualLayerId(0)
 {
+  new PartSet_IconFactory();
+
   mySketchMgr = new PartSet_SketcherMgr(this);
   myDataModel = new PartSet_DocumentDataModel(this);
 
@@ -761,12 +765,14 @@ void PartSet_Module::customizeObjectBrowser(QWidget* theObjectBrowser)
     aPalet.setColor(QPalette::Text, QColor(0, 72, 140));
     aLabel->setPalette(aPalet);
     aOB->treeView()->setExpandsOnDoubleClick(false);
+#ifdef ModuleDataModel
     connect(aOB->treeView(), SIGNAL(doubleClicked(const QModelIndex&)), 
       SLOT(onTreeViewDoubleClick(const QModelIndex&)));
     connect(aOB, SIGNAL(headerMouseDblClicked(const QModelIndex&)), 
       SLOT(onTreeViewDoubleClick(const QModelIndex&)));
     connect(aOB->treeView(), SIGNAL(doubleClicked(const QModelIndex&)), 
       myDataModel, SLOT(onMouseDoubleClick(const QModelIndex&)));
+#endif
   }
 }
 
@@ -861,8 +867,9 @@ void PartSet_Module::processEvent(const std::shared_ptr<Events_Message>& theMess
 
     SessionPtr aMgr = ModelAPI_Session::get();
     DocumentPtr aActiveDoc = aMgr->activeDocument();
-    DocumentPtr aDoc = aMgr->moduleDocument();
+#ifdef ModuleDataModel
     QModelIndex aOldIndex = myDataModel->activePartTree();
+    DocumentPtr aDoc = aMgr->moduleDocument();
     if (aActiveDoc == aDoc) {
       if (aOldIndex.isValid())
         aTreeView->setExpanded(aOldIndex, false);
@@ -884,6 +891,16 @@ void PartSet_Module::processEvent(const std::shared_ptr<Events_Message>& theMess
         }
       }
     }
+#else
+    // Problem with MPV: At first time on creation it doesn't work because Part feature
+    // creation event will be sent after
+    if (aActivePartIndex.isValid())
+      aTreeView->setExpanded(aActivePartIndex, false);
+    XGUI_DataModel* aDataModel = aWorkshop->objectBrowser()->dataModel();
+    aActivePartIndex = aDataModel->documentRootIndex(aActiveDoc);
+    if (aActivePartIndex.isValid())
+      aTreeView->setExpanded(aActivePartIndex, true);
+#endif
     aLabel->setPalette(aPalet);
     aWorkshop->updateCommandStatus();
 
index a17c8559996a2bc0e8a8b42ccb89522cb8bc25e9..532e874f53465df94c5f9b273a3c26b1c2c1ee8a 100644 (file)
@@ -252,6 +252,8 @@ protected slots:
   int myVisualLayerId;
 
   PartSet_DocumentDataModel* myDataModel;
+
+  QModelIndex aActivePartIndex;
 };
 
 #endif
index 4c83fb774ec9348671923f3cba9804f1ca6c1463..5dd9eaf20a7ff8260d453f40dc5e8437ea1d03b4 100644 (file)
@@ -529,8 +529,13 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     }
     // the modified state of the current operation should be updated if there are features, which
     // were changed here
-    if (isModified)
+    if (isModified) {
       aCurrentOperation->onValuesChanged();
+      ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
+      XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
+      XGUI_Workshop* aWorkshop = aConnector->workshop();
+      aWorkshop->updateCompositeActionState();
+    }
     Events_Loop::loop()->flush(aMoveEvent); // up all move events - to be processed in the solver
     //Events_Loop::loop()->flush(aUpdateEvent); // up update events - to redisplay presentations
 
index b7b7d0f649d64cd94d971a5a40c55ae6ef8b7f36..06706b7cd73fc6bad29897e2e9822e05d56eec1a 100644 (file)
@@ -30,6 +30,7 @@
      <file>icons/radius.png</file>
      <file>icons/perpendicular.png</file>
      <file>icons/parallel.png</file>
+     <file>icons/partition.png</file>
      <file>icons/length.png</file>
      <file>icons/distance.png</file>
      <file>icons/radius_constr.png</file>
diff --git a/src/PartSet/icons/partition.png b/src/PartSet/icons/partition.png
new file mode 100755 (executable)
index 0000000..bc3ce01
Binary files /dev/null and b/src/PartSet/icons/partition.png differ
index 494759b7645d3fced0ddece8d0d85af7d60a84d7..1cc72f76c5c777dfa905e0049c522fd7836893fb 100644 (file)
@@ -9,8 +9,10 @@ SET(PROJECT_HEADERS
        XGUI_ColorDialog.h
        XGUI_ContextMenuMgr.h
        XGUI_CustomPrs.h
+       XGUI_DataModel.h
        XGUI_Displayer.h
        XGUI_ErrorDialog.h
+       XGUI_HistoryMenu.h
        XGUI_ModuleConnector.h
        XGUI_ObjectsBrowser.h
        XGUI_OperationMgr.h
@@ -23,7 +25,6 @@ SET(PROJECT_HEADERS
        XGUI_ViewerProxy.h
        XGUI_Workshop.h
        XGUI_WorkshopListener.h
-       XGUI_HistoryMenu.h
 )
 
 SET(PROJECT_AUTOMOC 
@@ -35,8 +36,10 @@ SET(PROJECT_SOURCES
        XGUI_ColorDialog.cpp
        XGUI_ContextMenuMgr.cpp
        XGUI_CustomPrs.cpp
+       XGUI_DataModel.cpp
        XGUI_Displayer.cpp
        XGUI_ErrorDialog.cpp
+       XGUI_HistoryMenu.cpp
        XGUI_ModuleConnector.cpp
        XGUI_ObjectsBrowser.cpp
        XGUI_OperationMgr.cpp
@@ -49,7 +52,6 @@ SET(PROJECT_SOURCES
        XGUI_ViewerProxy.cpp
        XGUI_Workshop.cpp
        XGUI_WorkshopListener.cpp
-       XGUI_HistoryMenu.cpp
 )
 
 SET(PROJECT_RESOURCES 
diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp
new file mode 100644 (file)
index 0000000..873f394
--- /dev/null
@@ -0,0 +1,681 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        ModuleBase_IDocumentDataModel.cpp
+// Created:     28 Apr 2015
+// Author:      Vitaly SMETANNIKOV
+
+#include "XGUI_DataModel.h"
+
+#include <ModuleBase_IconFactory.h>
+
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Feature.h>
+
+#include <Config_FeatureMessage.h>
+
+#include <Events_Loop.h>
+#include <Events_Error.h>
+
+#include <QIcon>
+#include <QBrush>
+
+#define ACTIVE_COLOR QColor(0,72,140)
+#define PASSIVE_COLOR Qt::black
+
+/// Returns ResultPart object if the given object is a Part feature
+/// Otherwise returns NULL
+ResultPartPtr getPartResult(ModelAPI_Object* theObj)
+{
+  ModelAPI_Feature* aFeature = dynamic_cast<ModelAPI_Feature*>(theObj);
+  if (aFeature) {
+    ResultPtr aRes = aFeature->firstResult();
+    if (aRes.get() && (aRes->groupName() == ModelAPI_ResultPart::group())) {
+      return std::dynamic_pointer_cast<ModelAPI_ResultPart>(aRes);
+    }
+  }
+  return ResultPartPtr();
+}
+
+/// Returns pointer on document if the given object is document object
+ModelAPI_Document* getSubDocument(void* theObj)
+{
+  ModelAPI_Document* aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
+  return aDoc;
+}
+
+
+
+
+// Constructor *************************************************
+XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent)
+{
+  myXMLReader.readAll();
+
+  Events_Loop* aLoop = Events_Loop::loop();
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+}
+
+//******************************************************
+void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+  DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+  std::string aRootType = myXMLReader.rootType();
+  std::string aSubType = myXMLReader.subType();
+  int aNbFolders = foldersCount();
+
+  // Created object event *******************
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
+    std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
+        std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
+    std::set<ObjectPtr> aObjects = aUpdMsg->objects();
+
+    std::set<ObjectPtr>::const_iterator aIt;
+    std::string aObjType;
+    for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
+      ObjectPtr aObject = (*aIt);
+      aObjType = aObject->groupName();
+      DocumentPtr aDoc = aObject->document();
+      if (aDoc == aRootDoc) {
+        // Check that new folders could appear
+        QStringList aNotEmptyFolders = listOfShowNotEmptyFolders();
+        foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
+          if ((aNotEmptyFolder.toStdString() == aObjType) && (aRootDoc->size(aObjType) == 1))
+            // Appears first object in folder which can not be shown empty
+            insertRow(myXMLReader.rootFolderId(aObjType));
+        }
+        // Insert new object
+        int aRow = aRootDoc->size(aObjType) - 1;
+        if (aObjType == aRootType) {
+          insertRow(aRow + aNbFolders + 1);
+        } else {
+          int aFolderId = myXMLReader.rootFolderId(aObjType);
+          if (aFolderId != -1) {
+            insertRow(aRow, createIndex(aFolderId, 0, -1));
+          }
+        } 
+      } else {
+        // Object created in sub-document
+        QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get());
+        if (aDocRoot.isValid()) {
+          // Check that new folders could appear
+          QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false);
+          foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
+            if ((aNotEmptyFolder.toStdString() == aObjType) && (aDoc->size(aObjType) == 1))
+              // Appears first object in folder which can not be shown empty
+              insertRow(myXMLReader.subFolderId(aObjType), aDocRoot);
+          }
+          int aRow = aDoc->size(aObjType) - 1;
+          int aNbSubFolders = foldersCount(aDoc.get());
+          if (aObjType == aSubType) {
+            // List of objects under document root
+            insertRow(aRow + aNbSubFolders, aDocRoot);
+          } else {
+            // List of objects under a folder
+            if (aRow != -1) {
+              int aFolderId = myXMLReader.subFolderId(aObjType);
+              if (aFolderId != -1) {
+                insertRow(aRow, createIndex(aFolderId, 0, aDoc.get()));
+              }
+            }
+          }
+        } 
+#ifdef _DEBUG
+        else {
+          Events_Error::send("Problem with Data Model definition of sub-document");
+        }
+#endif
+      }
+    }
+    // Deleted object event ***********************
+  } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
+    std::shared_ptr<ModelAPI_ObjectDeletedMessage> aUpdMsg =
+        std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
+    DocumentPtr aDoc = aUpdMsg->document();
+    std::set<std::string> aGroups = aUpdMsg->groups();
+    std::set<std::string>::const_iterator aIt;
+    for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) {
+      std::string aGroup = (*aIt);
+      if (aDoc == aRootDoc) {  // If root objects
+        int aRow = aRootDoc->size(aGroup);
+        if (aGroup == aRootType) {
+          removeRow(aRow + aNbFolders);
+        } else {
+          int aFolderId = myXMLReader.rootFolderId(aGroup);
+          if (aFolderId != -1) {
+            QModelIndex aFolderIndex = createIndex(aFolderId, 0, -1);
+            removeRow(aRow, aFolderIndex);
+          }
+        }
+        // Check that some folders could erased
+        QStringList aNotEmptyFolders = listOfShowNotEmptyFolders();
+        foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
+          if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup) == 0))
+            // Appears first object in folder which can not be shown empty
+            removeRow(myXMLReader.rootFolderId(aGroup));
+        }
+      } else {
+        // Remove row for sub-document
+        QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get());
+        if (aDocRoot.isValid()) {
+          int aRow = aDoc->size(aGroup);
+          int aNbSubFolders = foldersCount(aDoc.get());
+          if (aGroup == aSubType) {
+            // List of objects under document root
+            removeRow(aRow + aNbSubFolders, aDocRoot);
+          } else {
+            // List of objects under a folder
+            int aFolderId = myXMLReader.subFolderId(aGroup);
+            if (aFolderId != -1) {
+              removeRow(aRow, createIndex(aFolderId, 0, aDoc.get()));
+            }
+          }
+          // Check that some folders could disappear
+          QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false);
+          foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
+            if ((aNotEmptyFolder.toStdString() == aGroup) && (aDoc->size(aGroup) == 1))
+              // Appears first object in folder which can not be shown empty
+              removeRow(myXMLReader.subFolderId(aGroup), aDocRoot);
+          }
+        } 
+#ifdef _DEBUG
+        else {
+          Events_Error::send("Problem with Data Model definition of sub-document");
+        }
+#endif
+      }
+    }
+  } 
+}
+
+//******************************************************
+void XGUI_DataModel::clear()
+{
+
+}
+
+//******************************************************
+void XGUI_DataModel::rebuildDataTree()
+{
+
+}
+
+//******************************************************
+ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const
+{
+  if (theIndex.internalId() < 0) // this is a folder
+    return ObjectPtr();
+  ModelAPI_Object* aObj = (ModelAPI_Object*)theIndex.internalPointer();
+  if (getSubDocument(aObj)) // the selected index is a folder of sub-document
+    return ObjectPtr();
+
+  // We can not create the ObjectPtr directly because the pointer will be deleted 
+  // with deletion of the ObjectPtr because its counter become to 0.
+  DocumentPtr aDoc = aObj->document();
+  std::string aType = aObj->groupName();
+
+  ObjectPtr aObjPtr;
+  for (int i = 0; i < aDoc->size(aType); i++) {
+    aObjPtr = aDoc->object(aType, i);
+    if (aObjPtr.get() == aObj)
+      return aObjPtr;
+  }
+  return ObjectPtr();
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject) const
+{
+  std::string aType = theObject->groupName();
+  DocumentPtr aDoc = theObject->document();
+  int aRow = aDoc->index(theObject);
+  if (aRow == -1)
+    return QModelIndex();
+
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  if (aDoc == aRootDoc && myXMLReader.rootType() == aType) { 
+    // The object from root document
+    aRow += foldersCount();
+  } else if (myXMLReader.subType() == aType) { 
+    // The object from sub document
+    aRow += foldersCount(aDoc.get());
+  }
+  return createIndex(aRow, 0, theObject.get());
+}
+
+//******************************************************
+QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  int aNbFolders = foldersCount();
+  int theIndexRow = theIndex.row();
+
+  if ((theRole == Qt::DecorationRole) && (theIndex == lastHistoryIndex()))
+    return QIcon(":pictures/arrow.png");
+
+  if (theIndex.column() == 1)
+    return QVariant();
+
+  int aParentId = theIndex.internalId();
+  if (aParentId == -1) { // root folders
+    switch (theRole) {
+      case Qt::DisplayRole:
+        return QString(myXMLReader.rootFolderName(theIndexRow).c_str()) + 
+          QString(" (%1)").arg(rowCount(theIndex));
+      case Qt::DecorationRole:
+        return QIcon(myXMLReader.rootFolderIcon(theIndexRow).c_str());
+      case Qt::ForegroundRole:
+        if (aSession->activeDocument() == aRootDoc)
+          return QBrush(ACTIVE_COLOR);
+        else
+          return QBrush(PASSIVE_COLOR);
+    }
+  } else { // an object or sub-document
+    ModelAPI_Document* aSubDoc = getSubDocument(theIndex.internalPointer());
+
+    if (theRole == Qt::ForegroundRole) {
+      bool aIsActive = false;
+      if (aSubDoc)
+        aIsActive = (aSession->activeDocument().get() == aSubDoc);
+      else {
+        ModelAPI_Object* aObj = (ModelAPI_Object*)theIndex.internalPointer();
+        if (aObj->isDisabled())
+          return QBrush(Qt::lightGray);
+        aIsActive = (aSession->activeDocument() == aObj->document());
+      }
+      if (aIsActive)
+        return QBrush(ACTIVE_COLOR);
+      else
+        return QBrush(PASSIVE_COLOR);
+    }
+
+    if (aSubDoc) { // this is a folder of sub document
+      switch (theRole) {
+        case Qt::DisplayRole:
+          return QString(myXMLReader.subFolderName(theIndexRow).c_str()) + 
+            QString(" (%1)").arg(rowCount(theIndex));
+        case Qt::DecorationRole:
+          return QIcon(myXMLReader.subFolderIcon(theIndexRow).c_str());
+      }
+    } else {
+      ModelAPI_Object* aObj = (ModelAPI_Object*)theIndex.internalPointer();
+      switch (theRole) {
+      case Qt::DisplayRole:
+        if (aObj->groupName() == ModelAPI_ResultParameter::group()) {
+          ModelAPI_ResultParameter* aParam = dynamic_cast<ModelAPI_ResultParameter*>(aObj);
+          AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
+          QString aVal = QString::number(aValueAttribute->value());
+          QString aTitle = QString(aObj->data()->name().c_str());
+          return aTitle + " = " + aVal;
+        }
+        return aObj->data()->name().c_str();
+      case Qt::DecorationRole:
+        return ModuleBase_IconFactory::get()->getIcon(object(theIndex));
+      }
+    }
+  }
+  return QVariant();
+}
+
+//******************************************************
+QVariant XGUI_DataModel::headerData(int theSection, Qt::Orientation theOrient, int theRole) const
+{
+  return QVariant();
+}
+
+//******************************************************
+int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  if (!aSession->hasModuleDocument())
+    return 0;
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+
+  if (!theParent.isValid()) {
+    // Return number of items in root
+    int aNbFolders = foldersCount();
+    int aNbItems = 0;
+    std::string aType = myXMLReader.rootType();
+    if (!aType.empty())
+      aNbItems = aRootDoc->size(aType);
+    return aNbFolders + aNbItems;
+  }
+
+  int aId = theParent.internalId();
+  if (aId == -1) { 
+    // this is a folder under root
+    int aParentPos = theParent.row();
+    std::string aType = myXMLReader.rootFolderType(aParentPos);
+    //qDebug("### %s = %i\n", aType.c_str(), aRootDoc->size(aType));
+    return aRootDoc->size(aType);
+  } else {
+    // It is an object which could have children
+    ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer());
+    if (aDoc) { 
+      // a folder of sub-document
+      std::string aType = myXMLReader.subFolderType(theParent.row());
+      return aDoc->size(aType);
+    } else {
+      // Check for Part feature
+      ModelAPI_Object* aObj = (ModelAPI_Object*)theParent.internalPointer();
+      ResultPartPtr aPartRes = getPartResult(aObj);
+      if (aPartRes.get()) {
+        DocumentPtr aSubDoc = aPartRes->partDoc();
+        int aNbSubFolders = foldersCount(aSubDoc.get());
+        int aNbSubItems = 0;
+        std::string aSubType = myXMLReader.subType();
+        if (!aSubType.empty())
+          aNbSubItems = aSubDoc->size(aSubType);
+        return aNbSubItems + aNbSubFolders;
+      }
+    }
+  }
+  return 0;
+}
+
+//******************************************************
+int XGUI_DataModel::columnCount(const QModelIndex& theParent) const
+{
+  return 2;
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  int aNbFolders = foldersCount();
+
+  if (!theParent.isValid()) {
+    if (theRow < aNbFolders) // Return first level folder index
+      return createIndex(theRow, theColumn, -1);
+    else { // return object under root index
+      std::string aType = myXMLReader.rootType();
+      int aObjId = theRow - aNbFolders;
+      if (aObjId < aRootDoc->size(aType)) {
+        ObjectPtr aObj = aRootDoc->object(aType, aObjId);
+        QModelIndex aIndex = objectIndex(aObj);
+        if (theColumn != 0)
+          return createIndex(aIndex.row(), theColumn, aIndex.internalPointer());
+        return aIndex;
+      }
+      return QModelIndex();
+    }
+  }
+  int aId = theParent.internalId();
+  int aParentPos = theParent.row();
+  if (aId == -1) { // return object index inside of first level of folders
+    std::string aType = myXMLReader.rootFolderType(aParentPos);
+    if (theRow < aRootDoc->size(aType)) {
+      ObjectPtr aObj = aRootDoc->object(aType, theRow);
+      QModelIndex aIndex = objectIndex(aObj);
+      if (theColumn != 0)
+        return createIndex(aIndex.row(), theColumn, aIndex.internalPointer());
+      return aIndex;
+    }
+  } else {
+    // It is an object which could have children
+    ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer());
+    if (aDoc) { 
+      // It is a folder of sub-document
+      std::string aType = myXMLReader.subFolderType(aParentPos);
+      if (theRow < aDoc->size(aType)) {
+        ObjectPtr aObj = aDoc->object(aType, theRow);
+        QModelIndex aIndex = objectIndex(aObj);
+        if (theColumn != 0)
+          return createIndex(aIndex.row(), theColumn, aIndex.internalPointer());
+        return aIndex;
+      }
+    } else {
+      ModelAPI_Object* aParentObj = (ModelAPI_Object*)theParent.internalPointer();
+
+      // Check for Part feature
+      ResultPartPtr aPartRes = getPartResult(aParentObj);
+      if (aPartRes.get()) {
+        DocumentPtr aSubDoc = aPartRes->partDoc();
+        int aNbSubFolders = foldersCount(aSubDoc.get());
+        if (theRow < aNbSubFolders) { // Create a Folder of sub-document
+          return createIndex(theRow, theColumn, aSubDoc.get());
+        } else {
+          // this is an object under sub document root
+          std::string aType = myXMLReader.subType();
+          ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders);
+          QModelIndex aIndex = objectIndex(aObj);
+          if (theColumn != 0)
+            return createIndex(aIndex.row(), theColumn, aIndex.internalPointer());
+          return aIndex;
+        }
+      }
+    }
+  }
+  return QModelIndex();
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
+{
+  int aId = theIndex.internalId();
+  if (aId != -1) { // The object is not a root folder
+    ModelAPI_Document* aDoc = getSubDocument(theIndex.internalPointer());
+    if (aDoc) { 
+      // It is a folder of sub-document
+      return findDocumentRootIndex(aDoc);
+    }
+    ModelAPI_Object* aObj = (ModelAPI_Object*) theIndex.internalPointer();
+    std::string aType = aObj->groupName();
+    SessionPtr aSession = ModelAPI_Session::get();
+    DocumentPtr aRootDoc = aSession->moduleDocument();
+    DocumentPtr aSubDoc = aObj->document();
+    if (aSubDoc == aRootDoc) {
+      if (aType == myXMLReader.rootType())
+        return QModelIndex();
+      else {
+        // return first level of folder index
+        int aFolderId = myXMLReader.rootFolderId(aType);
+        // Items in a one row must have the same parent
+        return createIndex(aFolderId, 0, -1);
+      }
+    } else {
+      if (aType == myXMLReader.subType())
+        return findDocumentRootIndex(aSubDoc.get());
+      else {
+        // return first level of folder index
+        int aFolderId = myXMLReader.subFolderId(aType);
+        // Items in a one row must have the same parent
+        return createIndex(aFolderId, 0, aSubDoc.get());
+      }
+    }
+  } 
+  return QModelIndex();
+}
+
+//******************************************************
+bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const
+{
+  if (!theParent.isValid()) {
+    int aNbFolders = foldersCount();
+    if (aNbFolders > 0)
+      return true;
+    SessionPtr aSession = ModelAPI_Session::get();
+    DocumentPtr aRootDoc = aSession->moduleDocument();
+    return aRootDoc->size(myXMLReader.rootType()) > 0;
+  }
+  if (theParent.internalId() == -1) {
+    std::string aType = myXMLReader.rootFolderType(theParent.row());
+    if (!aType.empty()) {
+      SessionPtr aSession = ModelAPI_Session::get();
+      DocumentPtr aRootDoc = aSession->moduleDocument();
+      return aRootDoc->size(aType) > 0;
+    }
+  } else {
+    ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer());
+    if (aDoc) { 
+      // a folder of sub-document
+      std::string aType = myXMLReader.subFolderType(theParent.row());
+      return aDoc->size(aType) > 0;
+    } else {
+      // Check that it could be an object with children
+      ModelAPI_Object* aObj = (ModelAPI_Object*)theParent.internalPointer();
+
+      // Check for Part feature
+      ResultPartPtr aPartRes = getPartResult(aObj);
+      if (aPartRes.get())
+        return true;
+    }
+  }
+  return false;
+}
+
+//******************************************************
+bool XGUI_DataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
+{
+  beginInsertRows(theParent, theRow, theRow + theCount - 1);
+  endInsertRows();
+
+  return true;
+}
+
+//******************************************************
+bool XGUI_DataModel::removeRows(int theRow, int theCount, const QModelIndex& theParent)
+{
+  beginRemoveRows(theParent, theRow, theRow + theCount - 1);
+  endRemoveRows();
+  return true;
+}
+
+//******************************************************
+Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const
+{
+  Qt::ItemFlags aFlags = Qt::ItemIsSelectable;
+
+  ModelAPI_Object* aObj = 0;
+  if (theIndex.internalId() != -1) {
+    if (!getSubDocument(theIndex.internalPointer()))
+      aObj = (ModelAPI_Object*) theIndex.internalPointer();
+  }
+  if (aObj) {
+    aFlags |= Qt::ItemIsEditable;
+  
+    if (!aObj->isDisabled())
+      aFlags |= Qt::ItemIsEnabled;
+  } else
+    aFlags |= Qt::ItemIsEnabled;
+  return aFlags;
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc) const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  if (myXMLReader.isAttachToResult()) { // If document is attached to result
+    int aNb = aRootDoc->size(ModelAPI_ResultPart::group());
+    ObjectPtr aObj;
+    ResultPartPtr aPartRes;
+    for (int i = 0; i < aNb; i++) {
+      aObj = aRootDoc->object(ModelAPI_ResultPart::group(), i);
+      aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
+      if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
+        int aRow = i;
+        if (myXMLReader.rootType() == ModelAPI_Feature::group())
+          aRow += foldersCount();
+        return createIndex(aRow, 0, aObj.get());
+      }
+    }
+  } else { // If document is attached to feature
+    int aNb = aRootDoc->size(ModelAPI_Feature::group());
+    ObjectPtr aObj;
+    ResultPartPtr aPartRes;
+    for (int i = 0; i < aNb; i++) {
+      aObj = aRootDoc->object(ModelAPI_Feature::group(), i);
+      aPartRes = getPartResult(aObj.get());
+      if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
+        int aRow = i;
+        if (myXMLReader.rootType() == ModelAPI_Feature::group())
+          aRow += foldersCount();
+        return createIndex(aRow, 0, aObj.get());
+      }
+    }
+  }
+  return QModelIndex();
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc) const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  if (theDoc == aRootDoc)
+    return QModelIndex();
+  else 
+    return findDocumentRootIndex(theDoc.get());
+}
+
+//******************************************************
+int XGUI_DataModel::foldersCount(ModelAPI_Document* theDoc) const
+{
+  int aNb = 0;
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aRootDoc = aSession->moduleDocument();
+  if ((theDoc == 0) || (theDoc == aRootDoc.get())) {
+    for (int i = 0; i < myXMLReader.rootFoldersNumber(); i++) {
+      if (myXMLReader.rootShowEmpty(i))
+        aNb++;
+      else {
+        if (aRootDoc->size(myXMLReader.rootFolderType(i)) > 0)
+          aNb++;
+      }
+    }
+  } else {
+    for (int i = 0; i < myXMLReader.subFoldersNumber(); i++) {
+      if (myXMLReader.subShowEmpty(i))
+        aNb++;
+      else {
+        if (theDoc->size(myXMLReader.subFolderType(i)) > 0)
+          aNb++;
+      }
+    }
+  }
+  return aNb;
+}
+
+//******************************************************
+QStringList XGUI_DataModel::listOfShowNotEmptyFolders(bool fromRoot) const
+{
+  QStringList aResult;
+  if (fromRoot) {
+    for (int i = 0; i < myXMLReader.rootFoldersNumber(); i++) {
+      if (!myXMLReader.rootShowEmpty(i))
+        aResult << myXMLReader.rootFolderType(i).c_str();
+    }
+  } else {
+    for (int i = 0; i < myXMLReader.subFoldersNumber(); i++) {
+      if (!myXMLReader.subShowEmpty(i))
+        aResult << myXMLReader.subFolderType(i).c_str();
+    }
+  }
+  return aResult;
+}
+
+//******************************************************
+QModelIndex XGUI_DataModel::lastHistoryIndex() const
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aCurDoc = aSession->activeDocument();
+  FeaturePtr aFeature = aCurDoc->currentFeature(true);
+  if (aFeature.get()) {
+    QModelIndex aInd = objectIndex(aFeature);
+    return createIndex(aInd.row(), 1, aInd.internalPointer());
+  } else {
+    if (aCurDoc == aSession->moduleDocument())
+      return createIndex(foldersCount() - 1, 1, -1);
+    else 
+      return createIndex(foldersCount(aCurDoc.get()) - 1, 1, aCurDoc.get());
+  }
+}
\ No newline at end of file
diff --git a/src/XGUI/XGUI_DataModel.h b/src/XGUI/XGUI_DataModel.h
new file mode 100644 (file)
index 0000000..b1c3935
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        XGUI_DataModel.h
+// Created:     21 Jul 2015
+// Author:      Vitaly SMETANNIKOV
+
+
+#ifndef XGUI_DataModel_H
+#define XGUI_DataModel_H
+
+#include "XGUI.h"
+#include <ModelAPI_Object.h>
+#include <ModelAPI_Document.h>
+#include <Config_DataModelReader.h>
+#include <QAbstractItemModel>
+#include <Events_Listener.h>
+
+
+/**\class XGUI_DataModel
+ * \ingroup GUI
+ * \brief This is a data model for Object Browser (QTreeView).
+ * It uses XML file for definition of data tree.
+ * Some tips about organization of the model:
+ * - Non Valid Index - root index
+ * - An index with internal Id == -1 is a folder of root document
+ * - An index which contains internal pointer as ModelAPI_Object its the object
+ * - An index which contains internal pointer as ModelAPI_Document is a folder which belongs to this document
+ */
+class XGUI_EXPORT XGUI_DataModel : public QAbstractItemModel, public Events_Listener
+{
+Q_OBJECT
+public:
+  XGUI_DataModel(QObject* theParent);
+
+  /// Event Listener method
+  /// \param theMessage an event message
+  virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
+  //! Returns an object by the given Model index.
+  //! Returns 0 if the given index is not index of an object
+  virtual ObjectPtr object(const QModelIndex& theIndex) const;
+
+  //! Returns index of the object
+  //! \param theObject object to find
+  virtual QModelIndex objectIndex(const ObjectPtr theObject) const;
+
+  //! Clear internal data
+  virtual void clear();
+
+  //! Rebuild data tree
+  virtual void rebuildDataTree();
+
+
+  /// Returns the data stored under the given role for the item referred to by the index.
+  /// \param theIndex a model index
+  /// \param theRole a data role (see Qt::ItemDataRole)
+  virtual QVariant data(const QModelIndex& theIndex, int theRole) const;
+
+  /// Returns the data for the given role and section in the header with the specified orientation.
+  /// \param theSection a section
+  /// \param theOrient an orientation
+  /// \param theRole a data role (see Qt::ItemDataRole)
+  virtual QVariant headerData(int theSection, Qt::Orientation theOrient, int theRole =
+                                  Qt::DisplayRole) const;
+
+  /// Returns the number of rows under the given parent. When the parent is valid it means that 
+  /// rowCount is returning the number of children of parent.
+  /// \param theParent a parent model index
+  virtual int rowCount(const QModelIndex& theParent = QModelIndex()) const;
+
+  /// Returns the number of columns for the children of the given parent.
+  /// It has a one column
+  /// \param theParent a parent model index
+  virtual int columnCount(const QModelIndex& theParent = QModelIndex()) const;
+
+  /// Returns the index of the item in the model specified by the given row, column and parent index.
+  /// \param theRow a row
+  /// \param theColumn a column
+  /// \param theParent a parent model index
+  virtual QModelIndex index(int theRow, int theColumn, const QModelIndex &theParent =
+                                QModelIndex()) const;
+
+  /// Returns the parent of the model item with the given index. 
+  /// If the item has no parent, an invalid QModelIndex is returned.
+  /// \param theIndex a model index
+  virtual QModelIndex parent(const QModelIndex& theIndex) const;
+
+  /// Returns true if parent has any children; otherwise returns false.
+  /// \param theParent a parent model index
+  virtual bool hasChildren(const QModelIndex& theParent = QModelIndex()) const;
+
+  /// Inserts count rows into the model before the given row. 
+  /// Items in the new row will be children of the item represented by the parent model index.
+  /// \param theRow a start row
+  /// \param theCount a nember of rows to insert
+  /// \param theParent a parent model index
+  virtual bool insertRows(int theRow, int theCount, const QModelIndex& theParent = QModelIndex());
+
+  /// Removes count rows starting with the given row under parent parent from the model.
+  /// \param theRow a start row
+  /// \param theCount a nember of rows to remove
+  /// \param theParent a parent model index
+  virtual bool removeRows(int theRow, int theCount, const QModelIndex& theParent = QModelIndex());
+
+  /// Returns the item flags for the given index.
+  /// \param theIndex a model index
+  virtual Qt::ItemFlags flags(const QModelIndex& theIndex) const;
+
+  /// Returns an index which is root of the given document
+  /// \param theDoc a document
+  QModelIndex documentRootIndex(DocumentPtr theDoc) const;
+
+  /// Returns last history object index
+  virtual QModelIndex lastHistoryIndex() const;
+
+private:
+  /// Find a root index which contains objects of the given document
+  /// \param theDoc the document object
+  QModelIndex findDocumentRootIndex(const ModelAPI_Document* theDoc) const;
+
+  /// Returns number of folders in document. Considered folders which has to be shown only if they are not empty.
+  /// \param theDoc document which has to be checked. If 0 then Root document will be considered 
+  int foldersCount(ModelAPI_Document* theDoc = 0) const;
+
+  /// Returns list of folders types which can not be shown empty
+  /// \param fromRoot - root document flag
+  QStringList listOfShowNotEmptyFolders(bool fromRoot = true) const;
+
+  Config_DataModelReader myXMLReader;
+};
+
+#endif
\ No newline at end of file
index b76ded07548661491fc5754202c842f5a0ca74ef..78ecbc64119373a88158b81e7b71bf468969b2de 100644 (file)
@@ -18,6 +18,7 @@
 #include <ModelAPI_Object.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_ResultCompSolid.h>
 
 #include <ModuleBase_ResultPrs.h>
 #include <ModuleBase_Tools.h>
@@ -58,6 +59,7 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse
 //#define DEBUG_FEATURE_REDISPLAY
 //#define DEBUG_SELECTION_FILTERS
 
+//#define DEBUG_COMPOSILID_DISPLAY
 // Workaround for bug #25637
 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
 {
@@ -109,7 +111,20 @@ bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
 void XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
 {
   if (isVisible(theObject)) {
-    redisplay(theObject, theUpdateViewer);
+#ifdef DEBUG_COMPOSILID_DISPLAY
+    ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theObject);
+    if (aCompsolidResult.get()) {
+      for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) {
+        ResultPtr aSubResult = aCompsolidResult->subResult(i);
+        if (aSubResult.get())
+          redisplay(aSubResult, false);
+      }
+      if (theUpdateViewer)
+        updateViewer();
+    }
+    else
+#endif
+      redisplay(theObject, theUpdateViewer);
   } else {
     AISObjectPtr anAIS;
 
@@ -120,6 +135,19 @@ void XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
     } else {
       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
       if (aResult.get() != NULL) {
+#ifdef DEBUG_COMPOSILID_DISPLAY
+        ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theObject);
+        if (aCompsolidResult.get()) {
+          for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) {
+            ResultPtr aSubResult = aCompsolidResult->subResult(i);
+            if (aSubResult.get())
+              display(aSubResult, false);
+          }
+          if (theUpdateViewer)
+            updateViewer();
+        }
+        else {
+#endif
         std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
         if (aShapePtr.get() != NULL) {
           anAIS = AISObjectPtr(new GeomAPI_AISObject());
@@ -127,6 +155,9 @@ void XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
           //anAIS->createShape(aShapePtr);
           isShading = true;
         }
+#ifdef DEBUG_COMPOSILID_DISPLAY
+        } // close else
+#endif
       }
     }
     if (anAIS)
index 448f47dbd0af79320cca73cb1dd202d8f7cef988..acdd5e5fb4806d2b37b0190e62d802d55a60c197 100644 (file)
@@ -2,10 +2,12 @@
 
 #include "XGUI_ObjectsBrowser.h"
 #include "XGUI_Tools.h"
+#include "XGUI_DataModel.h"
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Document.h>
+#include <ModelAPI_Tools.h>
 
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_IDocumentDataModel.h>
@@ -18,7 +20,7 @@
 #include <QMouseEvent>
 #include <QAction>
 #include <QStyledItemDelegate>
-
+#include <QMessageBox>
 
 /// Width of second column (minimum acceptable = 27)
 #define SECOND_COL_WIDTH 30
@@ -66,6 +68,11 @@ XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
   setSelectionMode(QAbstractItemView::ExtendedSelection);
 
   setItemDelegateForColumn(0, new XGUI_TreeViewItemDelegate(this));
+
+#ifndef ModuleDataModel
+  connect(this, SIGNAL(doubleClicked(const QModelIndex&)), 
+    SLOT(onDoubleClick(const QModelIndex&)));
+#endif
 }
 
 XGUI_DataTree::~XGUI_DataTree()
@@ -86,13 +93,19 @@ void XGUI_DataTree::commitData(QWidget* theEditor)
 {
   QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
   if (aEditor) {
-    QString aRes = aEditor->text();
+    QString aName = aEditor->text();
     QModelIndexList aIndexList = selectionModel()->selectedIndexes();
     ModuleBase_IDocumentDataModel* aModel = dataModel();
     ObjectPtr aObj = aModel->object(aIndexList.first());
     SessionPtr aMgr = ModelAPI_Session::get();
     aMgr->startOperation("Rename");
-    aObj->data()->setName(qPrintable(aRes));
+
+    if (!XGUI_Tools::canRename(this, aObj, aName)) {
+      aMgr->abortOperation();
+      return;
+    }
+
+    aObj->data()->setName(qPrintable(aName));
     aMgr->finishOperation();
   }
 }
@@ -113,6 +126,50 @@ void XGUI_DataTree::resizeEvent(QResizeEvent* theEvent)
   }
 }
 
+void XGUI_DataTree::onDoubleClick(const QModelIndex& theIndex)
+{
+  if (theIndex.column() != 1)
+    return;
+  ModuleBase_IDocumentDataModel* aModel = dataModel();
+  if (aModel->flags(theIndex) == 0)
+    return;
+  ObjectPtr aObj = aModel->object(theIndex);
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  DocumentPtr aDoc = aMgr->activeDocument();
+  
+  QModelIndex aOldIndex = aModel->lastHistoryIndex();
+
+  std::string aOpName = tr("History change").toStdString();
+  if (aObj.get()) {
+    if (aObj->document() != aDoc)
+      return;
+    aMgr->startOperation(aOpName);
+    aDoc->setCurrentFeature(std::dynamic_pointer_cast<ModelAPI_Feature>(aObj), true);
+    aMgr->finishOperation();
+  } else {
+    // Ignore clicks on folders outside current document
+    if ((theIndex.internalId() == -1) && (aDoc != aMgr->moduleDocument()))
+      // Clicked folder under root but active document is another
+      return;
+    if ((theIndex.internalId() != -1) && (aDoc.get() != theIndex.internalPointer()))
+      // Cliced not on active document folder
+      return;
+
+    aMgr->startOperation(aOpName);
+    aDoc->setCurrentFeature(FeaturePtr(), true);
+    aMgr->finishOperation();
+  }
+  QModelIndex aNewIndex = aModel->lastHistoryIndex();
+  QModelIndex aParent = theIndex.parent();
+  int aStartRow = std::min(aOldIndex.row(), aNewIndex.row());
+  int aEndRow = std::max(aOldIndex.row(), aNewIndex.row());
+  for (int i = aStartRow; i <= aEndRow; i++) {
+    update(aModel->index(i, 0, aParent));
+  }
+  update(aOldIndex);
+  update(aNewIndex);
+}
 
 //********************************************************************
 //********************************************************************
@@ -327,7 +384,11 @@ void XGUI_ObjectsBrowser::clearContent()
 
 void XGUI_ObjectsBrowser::setDataModel(ModuleBase_IDocumentDataModel* theModel)
 {
+#ifdef ModuleDataModel
   myDocModel = theModel;
+#else
+  myDocModel = new XGUI_DataModel(this);
+#endif
   myTreeView->setModel(myDocModel);
   QItemSelectionModel* aSelMod = myTreeView->selectionModel();
   connect(aSelMod, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
@@ -344,7 +405,11 @@ QObjectPtrList XGUI_ObjectsBrowser::selectedObjects(QModelIndexList* theIndexes)
 {
   QObjectPtrList aList;
   QModelIndexList aIndexes = selectedIndexes();
+#ifdef ModuleDataModel
   ModuleBase_IDocumentDataModel* aModel = dataModel();
+#else
+  XGUI_DataModel* aModel = dataModel();
+#endif
   QModelIndexList::const_iterator aIt;
   for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
     if ((*aIt).column() == 0) {
index ade333a350bca37f89174408fd64a7d3d9a2a23c..5352ffe585f454ba50c403d626a1cfa9a63dc9ac 100644 (file)
@@ -14,6 +14,9 @@
 
 class ModuleBase_IDocumentDataModel;
 class QLineEdit;
+class XGUI_DataModel;
+
+#define ModuleDataModel
 
 /**
 * \ingroup GUI
@@ -44,6 +47,8 @@ public slots:
   /// Commit modified data (used for renaming of objects)
   virtual void commitData(QWidget* theEditor);
 
+  void onDoubleClick(const QModelIndex&);
+
  protected:
    /// Redefinition of virtual method
   virtual void contextMenuEvent(QContextMenuEvent* theEvent);
@@ -67,10 +72,17 @@ Q_OBJECT
   virtual ~XGUI_ObjectsBrowser();
 
   //! Returns Model which provides access to data objects
+#ifdef ModuleDataModel
   ModuleBase_IDocumentDataModel* dataModel() const
   {
     return myDocModel;
   }
+#else
+  XGUI_DataModel* dataModel() const
+  {
+    return myDocModel;
+  }
+#endif
 
   //! Returns list of currently selected objects
   //! \param theIndexes - output list of corresponded indexes (can be NULL)
@@ -137,8 +149,11 @@ signals:
   void closeDocNameEditing(bool toSave);
 
   //! Internal model
+#ifdef ModuleDataModel
   ModuleBase_IDocumentDataModel* myDocModel;
-
+#else
+  XGUI_DataModel* myDocModel;
+#endif
   QLineEdit* myActiveDocLbl;
   XGUI_DataTree* myTreeView;
 };
index b835629a7e37dbbb877aef8592f488b87741f4e0..5663298017804a0df23d6a3d9e61bfea31f51872 100644 (file)
@@ -11,6 +11,7 @@
 #include <ModelAPI_Document.h>
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Tools.h>
 
 #include <GeomAPI_Shape.h>
 
@@ -104,6 +105,23 @@ bool canRemoveOrRename(QWidget* theParent, const QObjectPtrList& theObjects)
   return aResult;
 }
 
+//******************************************************************
+bool canRename(QWidget* theParent, const ObjectPtr& theObject, const QString& theName)
+{
+  if (std::dynamic_pointer_cast<ModelAPI_ResultParameter>(theObject).get()) {
+    double aValue;
+    ResultParameterPtr aParam;
+    if (ModelAPI_Tools::findVariable(theObject->document(), qPrintable(theName), aValue, aParam)) {
+      QMessageBox::information(theParent, QObject::tr("Rename parameter"),
+          QString(QObject::tr("Selected parameter can not be renamed to: %1. \
+There is a parameter with the same name. Its value is: %2.")).arg(qPrintable(theName)).arg(aValue));
+      return false;
+    }
+  }
+
+  return true;
+}
+
 //******************************************************************
 bool allDocumentsActivated(QString& theNotActivatedNames)
 {
index 4869f30377a394826de75d9436a6837e7592972f..279e08560b6e60116bd8abbabce9c8c37c1bb1e0 100644 (file)
@@ -78,6 +78,11 @@ std::string XGUI_EXPORT featureInfo(FeaturePtr theFeature);
  */
 bool XGUI_EXPORT canRemoveOrRename(QWidget* theParent, const QObjectPtrList& aList);
 
+/*! 
+ Returns true if theObject can be renamed in theName
+ */
+bool canRename(QWidget* theParent, const ObjectPtr& theObject, const QString& theName);
+
 /*!
  Returns true if there are no parts in the document, which are not activated
  \return a boolean value
index 8aa17ceb66c8337496bd9c9ebd2b3d4f5d7706e5..95db6cca3be195be5c7305ad586f47b054b6fe47 100644 (file)
@@ -1,50 +1,48 @@
 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 //#include "XGUI_Constants.h"
-#include "XGUI_Tools.h"
 #include "XGUI_Workshop.h"
-#include "XGUI_SelectionMgr.h"
-#include "XGUI_Selection.h"
-#include "XGUI_ObjectsBrowser.h"
-#include "XGUI_Displayer.h"
-#include "XGUI_OperationMgr.h"
-#include "XGUI_SalomeConnector.h"
+
 #include "XGUI_ActionsMgr.h"
-#include "XGUI_ErrorDialog.h"
 #include "XGUI_ColorDialog.h"
-#include "XGUI_ViewerProxy.h"
-#include "XGUI_PropertyPanel.h"
 #include "XGUI_ContextMenuMgr.h"
+#include "XGUI_Displayer.h"
+#include "XGUI_ErrorDialog.h"
 #include "XGUI_ModuleConnector.h"
+#include "XGUI_ObjectsBrowser.h"
+#include "XGUI_OperationMgr.h"
+#include "XGUI_PropertyPanel.h"
+#include "XGUI_SalomeConnector.h"
+#include "XGUI_Selection.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_Tools.h"
+#include "XGUI_ViewerProxy.h"
 #include "XGUI_WorkshopListener.h"
-
-#include <XGUI_QtEvents.h>
-#include <XGUI_HistoryMenu.h>
 #include <XGUI_CustomPrs.h>
+#include <XGUI_HistoryMenu.h>
+#include <XGUI_QtEvents.h>
 
-#include <AppElements_Workbench.h>
-#include <AppElements_Viewer.h>
+#include <AppElements_Button.h>
 #include <AppElements_Command.h>
 #include <AppElements_MainMenu.h>
 #include <AppElements_MainWindow.h>
 #include <AppElements_MenuGroupPanel.h>
-#include <AppElements_Button.h>
-
-#include <ModuleBase_IModule.h>
-#include <ModuleBase_Preferences.h>
+#include <AppElements_Viewer.h>
+#include <AppElements_Workbench.h>
 
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_Data.h>
 #include <ModelAPI_Events.h>
-#include <ModelAPI_Session.h>
 #include <ModelAPI_Feature.h>
-#include <ModelAPI_Data.h>
-#include <ModelAPI_AttributeDocRef.h>
 #include <ModelAPI_Object.h>
-#include <ModelAPI_Validator.h>
-#include <ModelAPI_ResultGroup.h>
-#include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultBody.h>
-#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultGroup.h>
 #include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_ResultCompSolid.h>
 
 //#include <PartSetPlugin_Part.h>
 
 #include <Events_Error.h>
 #include <Events_LongOp.h>
 
+#include <ModuleBase_FilterFactory.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_IViewer.h>
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_OperationDescription.h>
-#include <ModuleBase_SelectionValidator.h>
-#include <ModuleBase_WidgetFactory.h>
-#include <ModuleBase_Tools.h>
-#include <ModuleBase_IViewer.h>
-#include <ModuleBase_FilterFactory.h>
 #include <ModuleBase_PageBase.h>
+#include <ModuleBase_Preferences.h>
+#include <ModuleBase_SelectionValidator.h>
 #include <ModuleBase_Tools.h>
+#include <ModuleBase_WidgetFactory.h>
 
 #include <Config_Common.h>
 #include <Config_FeatureMessage.h>
-#include <Config_PointerMessage.h>
 #include <Config_ModuleReader.h>
+#include <Config_PointerMessage.h>
 #include <Config_PropManager.h>
 #include <Config_SelectionFilterMessage.h>
 
@@ -857,9 +856,11 @@ void XGUI_Workshop::updateCompositeActionState()
   // e.g. sketch can be applyed only if at least one nested element create is finished
   bool aCanUndo = ModelAPI_Session::get()->canUndo();
   bool aParentValid = operationMgr()->isParentOperationValid();
+  bool aCurrentValid = operationMgr()->currentOperation() &&
+                       operationMgr()->currentOperation()->isValid();
 
   QAction* aAcceptAllAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
-  aAcceptAllAct->setEnabled(aParentValid && aCanUndo);
+  aAcceptAllAct->setEnabled(aParentValid && (aCanUndo || aCurrentValid));
 }
 
 void XGUI_Workshop::updateHistory()
@@ -1019,6 +1020,9 @@ void XGUI_Workshop::deleteObjects()
   if (!isActiveOperationAborted())
     return;
   QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
+  // It is necessary to clear selection in order to avoid selection changed event during
+  // deleteion and negative consequences connected with processing of already deleted items
+  mySelector->clearSelection();
   // check whether the object can be deleted. There should not be parts which are not loaded
   if (!XGUI_Tools::canRemoveOrRename(myMainWindow, anObjects))
     return;
@@ -1324,8 +1328,9 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
   std::vector<int> aColor;
   foreach(ObjectPtr anObject, theObjects) {
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
-    if (aResult.get())
+    if (aResult.get()) {
       XGUI_CustomPrs::getResultColor(aResult, aColor);
+    }
     else {
       // TODO: remove the obtaining a color from the AIS object
       // this does not happen never because:
@@ -1362,10 +1367,18 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
   }
 
   // 4. set the value to all results
+  std::vector<int> aColorResult = aDlg->getColor();
   foreach(ObjectPtr anObj, theObjects) {
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
     if (aResult.get() != NULL) {
-      std::vector<int> aColorResult = aDlg->getColor();
+      ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
+      if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids
+        for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) {
+          ResultPtr aSubResult = aCompsolidResult->subResult(i);
+          if (aSubResult.get())
+            setColor(aSubResult, aColorResult);
+        }
+      }
       setColor(aResult, aColorResult);
     }
   }
index eda29c115794bb86a3c44e329817bad647b6da35..c0ecf8d730bfcf06c163589dc055795764b37563 100644 (file)
@@ -20,23 +20,23 @@ class AppElements_MainWindow;
 class AppElements_Command;
 class AppElements_Workbench;
 
-class XGUI_SelectionMgr;
+class XGUI_ActionsMgr;
+class XGUI_ContextMenuMgr;
 class XGUI_Displayer;
+class XGUI_ErrorDialog;
+class XGUI_ModuleConnector;
+class XGUI_ObjectsBrowser;
 class XGUI_OperationMgr;
+class XGUI_PropertyPanel;
 class XGUI_SalomeConnector;
-class XGUI_ObjectsBrowser;
-class XGUI_ActionsMgr;
-class XGUI_ErrorDialog;
 class XGUI_SalomeViewer;
+class XGUI_SelectionMgr;
 class XGUI_ViewerProxy;
-class XGUI_PropertyPanel;
-class XGUI_ContextMenuMgr;
-class XGUI_ModuleConnector;
 class XGUI_WorkshopListener;
 
-class ModuleBase_Operation;
 class ModuleBase_IModule;
 class ModuleBase_IViewer;
+class ModuleBase_Operation;
 
 class QWidget;
 class QDockWidget;