1 // Copyright (C) 2014-2023 CEA, EDF
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 <Locale_Convert.h>
25 //--------------------------------------------------------------------------------------
26 #include <ModelHighAPI_Dumper.h>
27 #include <ModelHighAPI_Services.h>
28 #include <ModelHighAPI_Tools.h>
29 //--------------------------------------------------------------------------------------
30 #include <ModelAPI_AttributeStringArray.h>
31 #include <ModelAPI_AttributeImage.h>
32 #include <ModelAPI_Session.h>
33 #include <ModelAPI_Tools.h>
34 #include <GeomAlgoAPI_Tools.h>
35 //--------------------------------------------------------------------------------------
37 //--------------------------------------------------------------------------------------
43 ExchangeAPI_Import::ExchangeAPI_Import(
44 const std::shared_ptr<ModelAPI_Feature> & theFeature)
45 : ModelHighAPI_Interface(theFeature)
50 ExchangeAPI_Import::ExchangeAPI_Import(
51 const std::shared_ptr<ModelAPI_Feature> & theFeature,
52 const std::string & theFilePath)
53 : ModelHighAPI_Interface(theFeature)
56 setFilePath(theFilePath);
59 ExchangeAPI_Import::ExchangeAPI_Import(
60 const std::shared_ptr<ModelAPI_Feature> & theFeature,
61 const std::string & /*theFilePath*/,
62 const std::string & theBuffer)
63 : ModelHighAPI_Interface(theFeature)
66 fillAttribute("XAOMem", myimportType);
67 fillAttribute(theBuffer, mymemoryBuffer);
72 ExchangeAPI_Import::ExchangeAPI_Import(
73 const std::shared_ptr<ModelAPI_Feature> & theFeature,
74 const std::string & theFilePath,
75 const bool theScalInterUnits,
76 const bool theMaterials,
78 : ModelHighAPI_Interface(theFeature)
81 setParameters(theFilePath, theScalInterUnits, theMaterials, theColor);
84 ExchangeAPI_Import::~ExchangeAPI_Import()
89 //--------------------------------------------------------------------------------------
90 void ExchangeAPI_Import::setParameters(const std::string & theFilePath,
91 const bool theScalInterUnits,
92 const bool theMaterials,
95 fillAttribute(theFilePath, mystepFilePath);
96 fillAttribute("STEP", myimportType);
97 fillAttribute(theScalInterUnits, myscalInterUnits);
98 fillAttribute(theMaterials,mymaterials);
99 fillAttribute(theColor,mycolors);
103 //--------------------------------------------------------------------------------------
104 void ExchangeAPI_Import::setFilePath(const std::string & theFilePath)
107 std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFilePath);
108 if (anExtension == "STEP" || anExtension == "STP") {
109 setParameters(theFilePath,true,false,false);
111 fillAttribute(theFilePath, myfilePath);
112 fillAttribute(anExtension, myimportType);
117 //--------------------------------------------------------------------------------------
118 void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const
120 FeaturePtr aBase = feature();
121 std::string aPartName = theDumper.name(aBase->document());
123 AttributeStringPtr aImportTypeAttr =
124 aBase->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID());
125 std::string aFormat = aImportTypeAttr->value();
127 if (aFormat == "XAOMem") {
128 theDumper << aBase << " = model.addImportXAOMem(" << aPartName << ", aXAOBuff";
129 std::string aGeometryNamePy = Locale::Convert::toString(aBase->data()->name());
130 if (! aGeometryNamePy.empty()) {
132 std::replace(aGeometryNamePy.begin(), aGeometryNamePy.end(), ' ', '_');
133 theDumper << "_" << aGeometryNamePy;
135 theDumper << ")" << std::endl;
138 std::string aFilePath;
139 if (aFormat == "STEP" || aFormat == "STP") {
140 aFilePath = aBase->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID())->value();
142 aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value();
145 std::string aFrom = "\\";
146 std::string aTo = "\\\\";
147 for (std::size_t aPos = aFilePath.find(aFrom);
148 aPos != std::string::npos;
149 aPos = aFilePath.find(aFrom, aPos)) {
150 aFilePath.replace(aPos, aFrom.size(), aTo);
153 std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(aFilePath);
154 if (anExtension == "STP" || anExtension == "STEP") {
155 theDumper << aBase << " = model.addImportSTEP(" << aPartName << ", \""
156 << aFilePath << "\"" ;
158 theDumper << ", " << scalInterUnits()->value()
159 << ", " << materials()->value()
160 << ", " << colors()->value() << ")"<< std::endl;
163 theDumper << aBase << " = model.addImport(" << aPartName << ", \""
164 << aFilePath << "\")" << std::endl;
168 // to make import have results
169 theDumper << "model.do()" << std::endl;
171 CompositeFeaturePtr aCompositeFeature =
172 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
173 if (aCompositeFeature.get()) {
174 int aNbOfSubs = aCompositeFeature->numberOfSubs();
175 for(int anIndex = 0; anIndex < aNbOfSubs; ++anIndex) {
176 std::string aSubFeatureGet =
177 theDumper.name(aBase) + ".subFeature(" + std::to_string((long long)anIndex) + ")";
178 theDumper.dumpSubFeatureNameAndColor(aSubFeatureGet, aCompositeFeature->subFeature(anIndex));
183 //--------------------------------------------------------------------------------------
185 const std::shared_ptr<ModelAPI_Document> & thePart,
186 const std::string & theFilePath)
188 std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import::ID());
189 return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath));
192 ImportPtr addImportXAOMem(const std::shared_ptr<ModelAPI_Document> & thePart,
195 std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import::ID());
196 std::string aString (PyBytes_AsString(theBuffer));
197 return ImportPtr(new ExchangeAPI_Import(aFeature, "", aString));
200 ImportPtr addImportSTEP(
201 const std::shared_ptr<ModelAPI_Document> & thePart,
202 const std::string & theFilePath,
203 const bool theScalInterUnits,
204 const bool theMaterials,
205 const bool theColor )
207 std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import::ID());
208 return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath,
209 theScalInterUnits, theMaterials, theColor));
212 void importPart(const std::shared_ptr<ModelAPI_Document> & thePart,
213 const std::string & theFilePath,
214 const ModelHighAPI_Reference & theAfterThis)
216 static const bool THE_VISIBLE_FEATURE = false;
217 FeaturePtr aCurrentFeature;
218 if (theAfterThis.feature()) {
219 aCurrentFeature = thePart->currentFeature(THE_VISIBLE_FEATURE);
220 thePart->setCurrentFeature(theAfterThis.feature(), THE_VISIBLE_FEATURE);
223 FeaturePtr aFeature = thePart->addFeature(ExchangePlugin_ImportPart::ID());
224 aFeature->string(ExchangePlugin_ImportPart::FILE_PATH_ID())->setValue(theFilePath);
226 // specify the ID of selected document
227 int aTargetPartIndex = 0;
228 SessionPtr aSession = ModelAPI_Session::get();
229 if (aSession->moduleDocument() == thePart) {
230 // Importing to PartSet has 2 choices: import directly to PartSet (if possible)
231 // or create a new part. Because then importing to existing part the document
232 // has to be specified explicitly.
233 // As a result, parse the list of possible target documents and generate new part
234 // if the import document is not applicable on PartSet level
235 // (there is no 'PartSet' in the list of applicable documents).
236 AttributeStringArrayPtr aDocsList =
237 aFeature->stringArray(ExchangePlugin_ImportPart::TARGET_PARTS_LIST_ID());
238 if (aDocsList->size() > 1 && aDocsList->value(1) == "PartSet")
239 aTargetPartIndex = 1;
241 aFeature->integer(ExchangePlugin_ImportPart::TARGET_PART_ID())->setValue(aTargetPartIndex);
243 // restart transaction to execute and delete the macro-feature
246 // restore current feature
248 thePart->setCurrentFeature(aCurrentFeature, THE_VISIBLE_FEATURE);
251 //-------------------------------------------------------------------------------------------------
252 //-------------------------------------------------------------------------------------------------
254 ExchangeAPI_Import_Image::ExchangeAPI_Import_Image(
255 const std::shared_ptr<ModelAPI_Feature> & theFeature)
256 : ModelHighAPI_Interface(theFeature)
261 ExchangeAPI_Import_Image::ExchangeAPI_Import_Image(
262 const std::shared_ptr<ModelAPI_Feature> & theFeature,
263 const std::string & theFilePath)
264 : ModelHighAPI_Interface(theFeature)
267 setFilePath(theFilePath);
270 void ExchangeAPI_Import_Image::setFilePath(const std::string & theFilePath)
272 fillAttribute(theFilePath, myfilePath);
276 ImportImagePtr addImportImage(
277 const std::shared_ptr<ModelAPI_Document> & thePart,
278 const std::string & theFilePath)
280 std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import_Image::ID());
281 return ImportImagePtr(new ExchangeAPI_Import_Image(aFeature, theFilePath));
284 void ExchangeAPI_Import_Image::dump(ModelHighAPI_Dumper& theDumper) const
286 FeaturePtr aBase = feature();
287 std::string aPartName = theDumper.name(aBase->document());
289 std::string aFilePath =
290 aBase->string(ExchangePlugin_Import_ImageFeature::FILE_PATH_ID())->value();
292 // store image into a new file near the dumped python script
293 ResultPtr aResult = aBase->firstResult();
294 std::string aNewImageDir = theDumper.getDumpDir();
295 if (aResult.get() && aResult->hasTexture()) {
299 std::list<unsigned char> aByteList;
300 AttributeImagePtr anImageAttr =
301 aResult->data()->image(ModelAPI_ResultBody::IMAGE_ID());
302 anImageAttr->texture(aWidth, aHeight, aByteList, aFormat);
304 // convert image data to QPixmap
305 uchar* arr = new uchar[aByteList.size()];
306 std::copy(aByteList.begin(), aByteList.end(), arr);
307 QImage image (arr, aWidth, aHeight, QImage::Format_ARGB32);
308 QPixmap pixmap = QPixmap::fromImage( image );
311 std::wstring aName = aBase->name();
312 std::string anImageName (aName.begin(), aName.end());
313 std::string aNewImageFile = anImageName + "." + aFormat;
314 QFileInfo aNewFileInfo (QDir(aNewImageDir.c_str()), aNewImageFile.c_str());
315 for (int ii = 1; QFile::exists(aNewFileInfo.absoluteFilePath()); ii++) {
316 // construct the new file name by adding the unique number
317 aNewImageFile = anImageName + "_" + std::to_string(ii) + "." + aFormat;
318 aNewFileInfo.setFile(QDir(aNewImageDir.c_str()), aNewImageFile.c_str());
321 // write image to a new file
322 if (pixmap.save(aNewFileInfo.absoluteFilePath())) {
323 // to dump new file name
324 aFilePath = aNewFileInfo.absoluteFilePath().toStdString();
329 theDumper << aBase << " = model.addImportImage(" << aPartName << ", \""
330 << aFilePath << "\")" << std::endl;
332 // to make import have results
333 theDumper << "model.do()" << std::endl;