Salome HOME
dbf476c2fe9b2eca08ea2c59042588855e5cdfd8
[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 // Obtain all features to be exported to get the list of selected results.
29 static void collectFeatures(AttributeSelectionListPtr theSelected,
30                             std::list<FeaturePtr>& theExport);
31 // Obtain all constuction elements of the document.
32 static void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport);
33
34
35 ExchangePlugin_ExportPart::ExchangePlugin_ExportPart()
36 {
37 }
38
39 void ExchangePlugin_ExportPart::initAttributes()
40 {
41   data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
42   data()->addAttribute(FILE_FORMAT_ID(), ModelAPI_AttributeString::typeId());
43   data()->addAttribute(SELECTION_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
44   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SELECTION_LIST_ID());
45 }
46
47 void ExchangePlugin_ExportPart::execute()
48 {
49   AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
50   std::string aFilename = aFilePathAttr->value();
51   if (aFilename.empty()) {
52     setError("File path is empty.");
53     return;
54   }
55
56   std::list<FeaturePtr> aFeaturesToExport;
57
58   SessionPtr aSession = ModelAPI_Session::get();
59   AttributeSelectionListPtr aSelected = selectionList(SELECTION_LIST_ID());
60   DocumentPtr anExportDoc;
61   if (aSelected && aSelected->size() == 0 &&
62       aSession->activeDocument() == aSession->moduleDocument()) {
63     // no result is selected, thus have to export all features of the current document,
64     // but the document is a PartSet; and it is forbidden to copy results of Parts,
65     // thus copy construction elements only
66     collectConstructions(aSession->moduleDocument(), aFeaturesToExport);
67   }
68   else
69     collectFeatures(aSelected, aFeaturesToExport);
70
71   if (!aFeaturesToExport.empty()) {
72     // remove 'ExportPart' feature is any
73     if (aFeaturesToExport.back()->getKind() == ExchangePlugin_ExportPart::ID())
74       aFeaturesToExport.pop_back();
75     // save the document
76     if (!aSession->activeDocument()->save(aFilename.c_str(), aFeaturesToExport))
77       setError("Cannot save the document.");
78   }
79 }
80
81
82 // ================================     Auxiliary functions     ===================================
83
84 static void allReferencedFeatures(std::set<FeaturePtr>& theFeatures)
85 {
86   std::set<FeaturePtr> aReferences;
87   for (std::set<FeaturePtr>::iterator anIt = theFeatures.begin();
88        anIt != theFeatures.end(); ++anIt) {
89     std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
90     (*anIt)->data()->referencesToObjects(aRefs);
91
92     for (std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRIt = aRefs.begin();
93          aRIt != aRefs.end(); ++aRIt) {
94       for (std::list<ObjectPtr>::iterator anObjIt = aRIt->second.begin();
95            anObjIt != aRIt->second.end(); ++anObjIt) {
96         FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
97         if (aFeature)
98           aReferences.insert(aFeature);
99       }
100     }
101   }
102
103   if (!aReferences.empty()) {
104     allReferencedFeatures(aReferences);
105     theFeatures.insert(aReferences.begin(), aReferences.end());
106   }
107 }
108
109 void collectFeatures(AttributeSelectionListPtr theSelected, std::list<FeaturePtr>& theExport)
110 {
111   theExport = ModelAPI_Session::get()->activeDocument()->allFeatures();
112
113   if (!theSelected || theSelected->size() == 0) {
114     // nothing is selected, return all features of the document
115     return;
116   }
117
118   // collect initial list of features basing on the selected results
119   std::set<FeaturePtr> aFeaturesToExport;
120   for (int anIndex = 0, aSize = theSelected->size(); anIndex < aSize; ++anIndex) {
121     AttributeSelectionPtr aCurrent = theSelected->value(anIndex);
122     FeaturePtr aCurrentFeature = ModelAPI_Feature::feature(aCurrent->context());
123     if (aCurrentFeature)
124       aFeaturesToExport.insert(aCurrentFeature);
125   }
126   // recursively collect all features used for the selected results
127   allReferencedFeatures(aFeaturesToExport);
128
129   // remove the features which are not affect the selected results
130   std::list<FeaturePtr>::iterator anIt = theExport.begin();
131   while (anIt != theExport.end()) {
132     if (aFeaturesToExport.find(*anIt) == aFeaturesToExport.end()) {
133       std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
134       theExport.erase(aRemoveIt);
135     }
136     else
137       ++anIt;
138   }
139 }
140
141 void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport)
142 {
143   theExport = theDocument->allFeatures();
144   // keep constructions only
145   std::list<FeaturePtr>::iterator anIt = theExport.begin();
146   while (anIt != theExport.end()) {
147     if ((*anIt)->lastResult()->groupName() == ModelAPI_ResultConstruction::group())
148       ++anIt;
149     else {
150       std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
151       theExport.erase(aRemoveIt);
152     }
153   }
154 }