]> SALOME platform Git repositories - modules/shaper.git/blob - src/ExchangePlugin/ExchangePlugin_ExportPart.cpp
Salome HOME
Task 5.1.7: To be able to export a part to a file and import it into an existing...
[modules/shaper.git] / src / ExchangePlugin / ExchangePlugin_ExportPart.cpp
1 // Copyright (C) 2014-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <ExchangePlugin_ExportPart.h>
21
22 #include <ModelAPI_AttributeSelectionList.h>
23 #include <ModelAPI_AttributeString.h>
24 #include <ModelAPI_ResultConstruction.h>
25 #include <ModelAPI_Session.h>
26 #include <ModelAPI_Validator.h>
27
28 #include <ConstructionPlugin_Axis.h>
29 #include <ConstructionPlugin_Plane.h>
30 #include <ConstructionPlugin_Point.h>
31
32 // Obtain all features to be exported to get the list of selected results.
33 static void collectFeatures(AttributeSelectionListPtr theSelected,
34                             std::list<FeaturePtr>& theExport);
35 // Obtain all constuction elements of the document.
36 static void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport);
37
38
39 ExchangePlugin_ExportPart::ExchangePlugin_ExportPart()
40 {
41 }
42
43 void ExchangePlugin_ExportPart::initAttributes()
44 {
45   data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
46   data()->addAttribute(FILE_FORMAT_ID(), ModelAPI_AttributeString::typeId());
47   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FILE_FORMAT_ID());
48   data()->addAttribute(SELECTION_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
49   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SELECTION_LIST_ID());
50 }
51
52 void ExchangePlugin_ExportPart::execute()
53 {
54   AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
55   std::string aFilename = aFilePathAttr->value();
56   if (aFilename.empty()) {
57     setError("File path is empty.");
58     return;
59   }
60
61   std::list<FeaturePtr> aFeaturesToExport;
62
63   SessionPtr aSession = ModelAPI_Session::get();
64   AttributeSelectionListPtr aSelected = selectionList(SELECTION_LIST_ID());
65   DocumentPtr anExportDoc;
66   if (aSelected && aSelected->size() == 0 &&
67       aSession->activeDocument() == aSession->moduleDocument()) {
68     // no result is selected, thus have to export all features of the current document,
69     // but the document is a PartSet; and it is forbidden to copy results of Parts,
70     // thus copy construction elements only
71     collectConstructions(aSession->moduleDocument(), aFeaturesToExport);
72   }
73   else
74     collectFeatures(aSelected, aFeaturesToExport);
75
76   if (!aFeaturesToExport.empty()) {
77     // remove 'ExportPart' feature is any
78     if (aFeaturesToExport.back()->getKind() == ExchangePlugin_ExportPart::ID())
79       aFeaturesToExport.pop_back();
80     // save the document
81     if (!aSession->activeDocument()->save(aFilename.c_str(), aFeaturesToExport))
82       setError("Cannot save the document.");
83   }
84 }
85
86
87 // ================================     Auxiliary functions     ===================================
88
89 static void allReferencedFeatures(std::set<FeaturePtr>& theFeatures)
90 {
91   std::set<FeaturePtr> aReferences;
92   for (std::set<FeaturePtr>::iterator anIt = theFeatures.begin();
93        anIt != theFeatures.end(); ++anIt) {
94     std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
95     (*anIt)->data()->referencesToObjects(aRefs);
96
97     for (std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRIt = aRefs.begin();
98          aRIt != aRefs.end(); ++aRIt) {
99       for (std::list<ObjectPtr>::iterator anObjIt = aRIt->second.begin();
100            anObjIt != aRIt->second.end(); ++anObjIt) {
101         FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
102         if (aFeature)
103           aReferences.insert(aFeature);
104       }
105     }
106   }
107
108   if (!aReferences.empty()) {
109     allReferencedFeatures(aReferences);
110     theFeatures.insert(aReferences.begin(), aReferences.end());
111   }
112 }
113
114 void collectFeatures(AttributeSelectionListPtr theSelected, std::list<FeaturePtr>& theExport)
115 {
116   theExport = ModelAPI_Session::get()->activeDocument()->allFeatures();
117
118   if (!theSelected || theSelected->size() == 0) {
119     // nothing is selected, return all features of the document
120     return;
121   }
122
123   // collect initial list of features basing on the selected results
124   std::set<FeaturePtr> aFeaturesToExport;
125   for (int anIndex = 0, aSize = theSelected->size(); anIndex < aSize; ++anIndex) {
126     AttributeSelectionPtr aCurrent = theSelected->value(anIndex);
127     FeaturePtr aCurrentFeature = ModelAPI_Feature::feature(aCurrent->context());
128     if (aCurrentFeature)
129       aFeaturesToExport.insert(aCurrentFeature);
130   }
131   // recursively collect all features used for the selected results
132   allReferencedFeatures(aFeaturesToExport);
133
134   // remove the features which are not affect the selected results
135   std::list<FeaturePtr>::iterator anIt = theExport.begin();
136   while (anIt != theExport.end()) {
137     if (aFeaturesToExport.find(*anIt) == aFeaturesToExport.end()) {
138       std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
139       theExport.erase(aRemoveIt);
140     }
141     else
142       ++anIt;
143   }
144 }
145
146 void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport)
147 {
148   theExport = theDocument->allFeatures();
149   // keep constructions only
150   std::list<FeaturePtr>::iterator anIt = theExport.begin();
151   while (anIt != theExport.end()) {
152     FeaturePtr aCurFeature = *anIt;
153     ResultPtr aCurResult = aCurFeature->lastResult();
154
155     bool isApplicable =
156         (!aCurResult || aCurResult->groupName() == ModelAPI_ResultConstruction::group());
157
158     if (isApplicable && !aCurFeature->isInHistory()) {
159       isApplicable = aCurFeature->getKind() != ConstructionPlugin_Point::ID() &&
160                      aCurFeature->getKind() != ConstructionPlugin_Axis::ID() &&
161                      aCurFeature->getKind() != ConstructionPlugin_Plane::ID();
162     }
163
164     if (isApplicable)
165       ++anIt;
166     else {
167       std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
168       theExport.erase(aRemoveIt);
169     }
170   }
171 }