1 // Copyright (C) 2014-2022 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "ExchangeAPI_Import.h"
21 //--------------------------------------------------------------------------------------
22 #include <ExchangePlugin_ImportPart.h>
23 //--------------------------------------------------------------------------------------
24 #include <ModelHighAPI_Dumper.h>
25 #include <ModelHighAPI_Services.h>
26 #include <ModelHighAPI_Tools.h>
27 //--------------------------------------------------------------------------------------
28 #include <ModelAPI_AttributeStringArray.h>
29 #include <ModelAPI_AttributeImage.h>
30 #include <ModelAPI_Session.h>
31 #include <ModelAPI_Tools.h>
32 #include <GeomAlgoAPI_Tools.h>
33 //--------------------------------------------------------------------------------------
35 //--------------------------------------------------------------------------------------
41 ExchangeAPI_Import::ExchangeAPI_Import(
42 const std::shared_ptr<ModelAPI_Feature> & theFeature)
43 : ModelHighAPI_Interface(theFeature)
48 ExchangeAPI_Import::ExchangeAPI_Import(
49 const std::shared_ptr<ModelAPI_Feature> & theFeature,
50 const std::string & theFilePath)
51 : ModelHighAPI_Interface(theFeature)
54 setFilePath(theFilePath);
57 ExchangeAPI_Import::ExchangeAPI_Import(
58 const std::shared_ptr<ModelAPI_Feature> & theFeature,
59 const std::string & theFilePath,
60 const bool theScalInterUnits,
61 const bool theMaterials,
63 : ModelHighAPI_Interface(theFeature)
66 setParameters(theFilePath, theScalInterUnits, theMaterials, theColor);
69 ExchangeAPI_Import::~ExchangeAPI_Import()
74 //--------------------------------------------------------------------------------------
75 void ExchangeAPI_Import::setParameters(const std::string & theFilePath,
76 const bool theScalInterUnits,
77 const bool theMaterials,
80 fillAttribute(theFilePath, mystepFilePath);
81 fillAttribute("STEP", myimportType);
82 fillAttribute(theScalInterUnits, myscalInterUnits);
83 fillAttribute(theMaterials,mymaterials);
84 fillAttribute(theColor,mycolors);
88 //--------------------------------------------------------------------------------------
89 void ExchangeAPI_Import::setFilePath(const std::string & theFilePath)
92 std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFilePath);
93 if (anExtension == "STEP" || anExtension == "STP") {
94 setParameters(theFilePath,true,false,false);
96 fillAttribute(theFilePath, myfilePath);
97 fillAttribute(anExtension, myimportType);
102 //--------------------------------------------------------------------------------------
103 void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const
105 FeaturePtr aBase = feature();
106 std::string aPartName = theDumper.name(aBase->document());
108 AttributeStringPtr aImportTypeAttr =
109 aBase->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID());
110 std::string aFormat = aImportTypeAttr->value();
111 std::string aFilePath;
112 if (aFormat == "STEP" || aFormat == "STP")
114 aFilePath = aBase->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID())->value();
116 aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value();
119 std::string aFrom = "\\";
120 std::string aTo = "\\\\";
121 for(std::size_t aPos = aFilePath.find(aFrom);
122 aPos != std::string::npos;
123 aPos = aFilePath.find(aFrom, aPos)) {
124 aFilePath.replace(aPos, aFrom.size(), aTo);
127 std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(aFilePath);
128 if (anExtension == "STP" || anExtension == "STEP"){
129 theDumper << aBase << " = model.addImportSTEP(" << aPartName << ", \""
130 << aFilePath << "\"" ;
132 theDumper << ", " << scalInterUnits()->value()
133 << ", " << materials()->value()
134 << ", " << colors()->value() << ")"<< std::endl;
136 theDumper << aBase << " = model.addImport(" << aPartName << ", \""
137 << aFilePath << "\")" << std::endl;
140 // to make import have results
141 theDumper << "model.do()" << std::endl;
143 CompositeFeaturePtr aCompositeFeature =
144 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
145 if (aCompositeFeature.get()) {
146 int aNbOfSubs = aCompositeFeature->numberOfSubs();
147 for(int anIndex = 0; anIndex < aNbOfSubs; ++anIndex) {
148 std::string aSubFeatureGet =
149 theDumper.name(aBase) + ".subFeature(" + std::to_string((long long)anIndex) + ")";
150 theDumper.dumpSubFeatureNameAndColor(aSubFeatureGet, aCompositeFeature->subFeature(anIndex));
155 //--------------------------------------------------------------------------------------
157 const std::shared_ptr<ModelAPI_Document> & thePart,
158 const std::string & theFilePath)
160 std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import::ID());
161 return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath));
164 ImportPtr addImportSTEP(
165 const std::shared_ptr<ModelAPI_Document> & thePart,
166 const std::string & theFilePath,
167 const bool theScalInterUnits,
168 const bool theMaterials,
169 const bool theColor )
171 std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import::ID());
172 return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath,
173 theScalInterUnits, theMaterials, theColor));
176 void importPart(const std::shared_ptr<ModelAPI_Document> & thePart,
177 const std::string & theFilePath,
178 const ModelHighAPI_Reference & theAfterThis)
180 static const bool THE_VISIBLE_FEATURE = false;
181 FeaturePtr aCurrentFeature;
182 if (theAfterThis.feature()) {
183 aCurrentFeature = thePart->currentFeature(THE_VISIBLE_FEATURE);
184 thePart->setCurrentFeature(theAfterThis.feature(), THE_VISIBLE_FEATURE);
187 FeaturePtr aFeature = thePart->addFeature(ExchangePlugin_ImportPart::ID());
188 aFeature->string(ExchangePlugin_ImportPart::FILE_PATH_ID())->setValue(theFilePath);
190 // specify the ID of selected document
191 int aTargetPartIndex = 0;
192 SessionPtr aSession = ModelAPI_Session::get();
193 if (aSession->moduleDocument() == thePart) {
194 // Importing to PartSet has 2 choices: import directly to PartSet (if possible)
195 // or create a new part. Because then importing to existing part the document
196 // has to be specified explicitly.
197 // As a result, parse the list of possible target documents and generate new part
198 // if the import document is not applicable on PartSet level
199 // (there is no 'PartSet' in the list of applicable documents).
200 AttributeStringArrayPtr aDocsList =
201 aFeature->stringArray(ExchangePlugin_ImportPart::TARGET_PARTS_LIST_ID());
202 if (aDocsList->size() > 1 && aDocsList->value(1) == "PartSet")
203 aTargetPartIndex = 1;
205 aFeature->integer(ExchangePlugin_ImportPart::TARGET_PART_ID())->setValue(aTargetPartIndex);
207 // restart transaction to execute and delete the macro-feature
210 // restore current feature
212 thePart->setCurrentFeature(aCurrentFeature, THE_VISIBLE_FEATURE);
215 //-------------------------------------------------------------------------------------------------
216 //-------------------------------------------------------------------------------------------------
218 ExchangeAPI_Import_Image::ExchangeAPI_Import_Image(
219 const std::shared_ptr<ModelAPI_Feature> & theFeature)
220 : ModelHighAPI_Interface(theFeature)
225 ExchangeAPI_Import_Image::ExchangeAPI_Import_Image(
226 const std::shared_ptr<ModelAPI_Feature> & theFeature,
227 const std::string & theFilePath)
228 : ModelHighAPI_Interface(theFeature)
231 setFilePath(theFilePath);
234 void ExchangeAPI_Import_Image::setFilePath(const std::string & theFilePath)
236 fillAttribute(theFilePath, myfilePath);
240 ImportImagePtr addImportImage(
241 const std::shared_ptr<ModelAPI_Document> & thePart,
242 const std::string & theFilePath)
244 std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import_Image::ID());
245 return ImportImagePtr(new ExchangeAPI_Import_Image(aFeature, theFilePath));
248 void ExchangeAPI_Import_Image::dump(ModelHighAPI_Dumper& theDumper) const
250 FeaturePtr aBase = feature();
251 std::string aPartName = theDumper.name(aBase->document());
253 std::string aFilePath =
254 aBase->string(ExchangePlugin_Import_ImageFeature::FILE_PATH_ID())->value();
256 // store image into a new file near the dumped python script
257 ResultPtr aResult = aBase->firstResult();
258 std::string aNewImageDir = theDumper.getDumpDir();
259 if (aResult.get() && aResult->hasTexture()) {
263 std::list<unsigned char> aByteList;
264 AttributeImagePtr anImageAttr =
265 aResult->data()->image(ModelAPI_ResultBody::IMAGE_ID());
266 anImageAttr->texture(aWidth, aHeight, aByteList, aFormat);
268 // convert image data to QPixmap
269 uchar* arr = new uchar[aByteList.size()];
270 std::copy(aByteList.begin(), aByteList.end(), arr);
271 QImage image (arr, aWidth, aHeight, QImage::Format_ARGB32);
272 QPixmap pixmap = QPixmap::fromImage( image );
275 std::wstring aName = aBase->name();
276 std::string anImageName (aName.begin(), aName.end());
277 std::string aNewImageFile = anImageName + "." + aFormat;
278 QFileInfo aNewFileInfo (QDir(aNewImageDir.c_str()), aNewImageFile.c_str());
279 for (int ii = 1; QFile::exists(aNewFileInfo.absoluteFilePath()); ii++) {
280 // construct the new file name by adding the unique number
281 aNewImageFile = anImageName + "_" + std::to_string(ii) + "." + aFormat;
282 aNewFileInfo.setFile(QDir(aNewImageDir.c_str()), aNewImageFile.c_str());
285 // write image to a new file
286 if (pixmap.save(aNewFileInfo.absoluteFilePath())) {
287 // to dump new file name
288 aFilePath = aNewFileInfo.absoluteFilePath().toStdString();
293 theDumper << aBase << " = model.addImportImage(" << aPartName << ", \""
294 << aFilePath << "\")" << std::endl;
296 // to make import have results
297 theDumper << "model.do()" << std::endl;