]> SALOME platform Git repositories - modules/shaper.git/blob - src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp
Salome HOME
Copyright update 2022
[modules/shaper.git] / src / ExchangePlugin / ExchangePlugin_ImportFeature.cpp
1 // Copyright (C) 2014-2022  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_ImportFeature.h>
21
22 #include <algorithm>
23 #include <string>
24
25 #include <Config_Common.h>
26 #include <Config_PropManager.h>
27
28 #include <GeomAlgoAPI_BREPImport.h>
29 #include <GeomAlgoAPI_IGESImport.h>
30 #include <GeomAlgoAPI_STEPImport.h>
31 #include <GeomAlgoAPI_Tools.h>
32 #include <GeomAlgoAPI_XAOImport.h>
33 #include <GeomAlgoAPI_STLImport.h>
34 #include <GeomAlgoAPI_ImageImport.h>
35
36 #include <GeomAPI_Shape.h>
37 #include <GeomAPI_Face.h>
38 #include <GeomAPI_ShapeExplorer.h>
39 #include <GeomAPI_ShapeIterator.h>
40
41 #include <Locale_Convert.h>
42
43 #include <ModelAPI_AttributeRefList.h>
44 #include <ModelAPI_AttributeSelectionList.h>
45 #include <ModelAPI_AttributeString.h>
46 #include <ModelAPI_AttributeStringArray.h>
47 #include <ModelAPI_AttributeIntArray.h>
48 #include <ModelAPI_AttributeImage.h>
49 #include <ModelAPI_AttributeTables.h>
50 #include <ModelAPI_AttributeBoolean.h>
51 #include <ModelAPI_AttributeInteger.h>
52 #include <ModelAPI_BodyBuilder.h>
53 #include <ModelAPI_Data.h>
54 #include <ModelAPI_Document.h>
55 #include <ModelAPI_Events.h>
56 #include <ModelAPI_Object.h>
57 #include <ModelAPI_ResultBody.h>
58 #include <ModelAPI_ResultGroup.h>
59 #include <ModelAPI_Session.h>
60 #include <ModelAPI_Validator.h>
61 #include <ModelAPI_Tools.h>
62
63 #include <XAO_Xao.hxx>
64 #include <XAO_Group.hxx>
65 #include <XAO_Field.hxx>
66 #include <XAO_Step.hxx>
67
68 #include <ExchangePlugin_Tools.h>
69
70 #include <QPixmap>
71
72 /*
73  * Request for initialization of data model of the feature: adding all attributes
74  */
75 void ExchangePlugin_ImportFeatureBase::initAttributes()
76 {
77   data()->addAttribute(ExchangePlugin_ImportFeatureBase::FILE_PATH_ID(),
78                        ModelAPI_AttributeString::typeId());
79   AttributePtr aFeaturesAttribute =
80     data()->addAttribute(ExchangePlugin_ImportFeatureBase::FEATURES_ID(),
81                          ModelAPI_AttributeRefList::typeId());
82   aFeaturesAttribute->setIsArgument(false);
83
84   ModelAPI_Session::get()->validators()->registerNotObligatory(
85       getKind(), ExchangePlugin_ImportFeatureBase::FEATURES_ID());
86 }
87
88 void ExchangePlugin_ImportFeature::initAttributes()
89 {
90   ExchangePlugin_ImportFeatureBase::initAttributes();
91
92   data()->addAttribute(STEP_FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
93   data()->addAttribute(IMPORT_TYPE_ID(), ModelAPI_AttributeString::typeId());
94   data()->addAttribute(STEP_MATERIALS_ID(), ModelAPI_AttributeBoolean::typeId());
95   data()->addAttribute(STEP_COLORS_ID(), ModelAPI_AttributeBoolean::typeId());
96   data()->addAttribute(STEP_SCALE_INTER_UNITS_ID(), ModelAPI_AttributeBoolean::typeId());
97
98   ModelAPI_Session::get()->validators()->registerNotObligatory(
99       getKind(), ExchangePlugin_ImportFeature::STEP_COLORS_ID());
100   ModelAPI_Session::get()->validators()->registerNotObligatory(
101       getKind(), ExchangePlugin_ImportFeature::STEP_MATERIALS_ID());
102   ModelAPI_Session::get()->validators()->registerNotObligatory(
103       getKind(), ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID());
104   ModelAPI_Session::get()->validators()->registerNotObligatory(
105       getKind(), ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID());
106   ModelAPI_Session::get()->validators()->registerNotObligatory(
107       getKind(), ExchangePlugin_ImportFeature::FILE_PATH_ID());
108 }
109 /*
110  * Computes or recomputes the results
111  */
112 void ExchangePlugin_ImportFeature::execute()
113 {
114   AttributeStringPtr aImportTypeAttr = string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID());
115   std::string aFormat = aImportTypeAttr->value();
116   AttributeStringPtr aFilePathAttr;
117   if (aFormat == "STEP" || aFormat == "STP")
118   {
119     aFilePathAttr = string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID());
120   } else {
121     aFilePathAttr = string(ExchangePlugin_ImportFeature::FILE_PATH_ID());
122   }
123   std::string aFilePath = aFilePathAttr->value();
124   if (aFilePath.empty()) {
125     setError("File path is empty.");
126     return;
127   }
128
129   importFile(aFilePath);
130 }
131
132 void ExchangePlugin_Import_ImageFeature::execute()
133 {
134   AttributeStringPtr aFilePathAttr = string(ExchangePlugin_Import_ImageFeature::FILE_PATH_ID());
135   std::string aFilePath = aFilePathAttr->value();
136   if (aFilePath.empty()) {
137     setError("File path is empty.");
138     return;
139   }
140   importFile(aFilePath);
141 }
142
143 std::shared_ptr<ModelAPI_ResultBody> ExchangePlugin_ImportFeatureBase::createResultBody(
144     std::shared_ptr<GeomAPI_Shape> aGeomShape)
145 {
146   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
147   //LoadNamingDS of the imported shape
148   loadNamingDS(aGeomShape, aResultBody);
149   return aResultBody;
150 }
151
152 void ExchangePlugin_ImportFeature::importFile(const std::string& theFileName)
153 {
154   // "*.brep" -> "BREP"
155   std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFileName);
156
157   if (anExtension == "XAO") {
158     importXAO(theFileName);
159     return;
160   }
161
162   // Perform the import
163   std::string anError;
164   std::shared_ptr<GeomAPI_Shape> aGeomShape;
165   std::map<std::wstring, std::list<std::wstring>> theMaterialShape;
166
167   std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName);
168   data()->setName(Locale::Convert::toWString(anObjectName));
169
170   ResultBodyPtr aResult = document()->createBody(data());
171
172   bool anColorGroupSelected = boolean(ExchangePlugin_ImportFeature::STEP_COLORS_ID())->value();
173   bool anMaterialsGroupSelected =
174                         boolean(ExchangePlugin_ImportFeature::STEP_MATERIALS_ID())->value();
175   if (anExtension == "BREP" || anExtension == "BRP") {
176     aGeomShape = BREPImport(theFileName, anExtension, anError);
177   } else if (anExtension == "STEP" || anExtension == "STP") {
178     bool anScalInterUnits =
179             boolean(ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID())->value();
180
181     // Process groups/fields
182     std::shared_ptr<ModelAPI_AttributeRefList> aRefListOfGroups =
183     std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(data()->attribute(FEATURES_ID()));
184
185     // Remove previous groups/fields stored in RefList
186     std::list<ObjectPtr> anGroupList = aRefListOfGroups->list();
187     std::list<ObjectPtr>::iterator anGroupIt = anGroupList.begin();
188     for (; anGroupIt != anGroupList.end(); ++anGroupIt) {
189       std::shared_ptr<ModelAPI_Feature> aFeature = ModelAPI_Feature::feature(*anGroupIt);
190       if (aFeature)
191         document()->removeFeature(aFeature);
192     }
193
194     aGeomShape = STEPImportAttributs(theFileName, aResult, anScalInterUnits,
195                                      anMaterialsGroupSelected, anColorGroupSelected,
196                                      theMaterialShape, anError);
197   } else if (anExtension == "IGES" || anExtension == "IGS") {
198     aGeomShape = IGESImport(theFileName, anExtension, anError);
199   } else if (anExtension == "STL") {
200     aGeomShape = STLImport(theFileName, anError);
201   }  else {
202     anError = "Unsupported format: " + anExtension;
203   }
204
205   // Check if shape is valid
206   if (!anError.empty()) {
207     setError("An error occurred while importing " + theFileName + ": " + anError);
208     return;
209   }
210
211   // Pass the results into the model
212   loadNamingDS(aGeomShape, aResult);
213
214   // create color group
215   if (anColorGroupSelected)
216   {
217     setColorGroups(aResult);
218   }
219
220   // create Materiel group
221   if (anMaterialsGroupSelected){
222     setMaterielGroup(aResult,theMaterialShape);
223   }
224
225   setResult(aResult);
226   aResult->clearShapeNameAndColor();
227
228 }
229
230 void ExchangePlugin_ImportFeature::setColorGroups(
231                                     std::shared_ptr<ModelAPI_ResultBody> theResultBody)
232 {
233   std::vector<int> aColor;
234   int anIndice = 1;
235   std::list<std::vector<int>> aColorsRead;
236
237   ModelAPI_Tools::getColor(theResultBody, aColor);
238   if (!aColor.empty() ){
239     std::wstringstream aColorName;
240     aColorName <<L"Color_"<< anIndice;
241     setColorGroup(theResultBody, aColor, aColorName.str());
242     anIndice++;
243     aColorsRead.push_back(aColor);
244   }
245
246   std::list<ResultPtr> allRes;
247   ModelAPI_Tools::allSubs(theResultBody, allRes);
248   for(std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); ++aRes) {
249     ModelAPI_Tools::getColor(*aRes, aColor);
250     if (!aColor.empty() ){
251       auto it = std::find(aColorsRead.begin(), aColorsRead.end(), aColor);
252       if ( it == aColorsRead.end() ){
253         std::wstringstream aColorName;
254         aColorName<<L"Color_"<< anIndice;
255         setColorGroup(theResultBody, aColor, aColorName.str());
256         anIndice++;
257         aColorsRead.push_back(aColor);
258       }
259     }
260   }
261 }
262
263 void ExchangePlugin_ImportFeature::setColorGroup(
264                                         std::shared_ptr<ModelAPI_ResultBody> theResultBody,
265                                         std::vector<int> &theColor,
266                                         const std::wstring& theName )
267 {
268   std::vector<int> aColor;
269   std::shared_ptr<ModelAPI_Feature> aGroupFeature = addFeature("Group");
270
271    // group name
272   aGroupFeature->data()->setName(theName);
273
274   // fill selection
275   AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list");
276
277   ModelAPI_Tools::getColor(theResultBody, aColor);
278   if (!aColor.empty()){
279     if (aColor == theColor) {
280       GeomShapePtr aShape = theResultBody->shape();
281       aSelectionList->setSelectionType(aShape->shapeTypeStr());
282       aSelectionList->append(theResultBody,aShape);
283     }
284   }
285   // add element with the same color
286   std::list<ResultPtr> allRes;
287   ModelAPI_Tools::allSubs(theResultBody, allRes);
288   for(std::list<ResultPtr>::iterator aRes = allRes.begin();
289       aRes != allRes.end(); ++aRes) {
290     ModelAPI_Tools::getColor(*aRes, aColor);
291     GeomShapePtr aShape = (*aRes)->shape();
292
293     if (!aColor.empty()){
294       if (aRes->get() &&  aColor == theColor) {
295         if (aShape->isCompound() || aShape->isCompSolid()) {
296           GeomAPI_ShapeIterator anIt(aShape);
297           for (; anIt.more(); anIt.next()) {
298             aSelectionList->setSelectionType(anIt.current()->shapeTypeStr());
299             aSelectionList->append(theResultBody,anIt.current());
300           }
301         } else {
302           aSelectionList->setSelectionType(aShape->shapeTypeStr());
303           aSelectionList->append(theResultBody,aShape);
304         }
305       }
306     }
307   }
308
309   // Create the group in the document to be able to set its color
310   ResultPtr aGroup = document()->createGroup(aGroupFeature->data());
311   aGroupFeature->setResult(aGroup);
312
313   ModelAPI_Tools::setColor(aGroupFeature->lastResult(),theColor);
314
315   if (aSelectionList->size() == 0) {
316     document()->removeFeature(aGroupFeature);
317   }
318 }
319
320 void ExchangePlugin_ImportFeature::setMaterielGroup(
321                                 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
322                                 std::map< std::wstring,std::list<std::wstring>>& theMaterialShape)
323 {
324   std::map< std::wstring, std::list<std::wstring>>::iterator anIt;
325   for (anIt = theMaterialShape.begin(); anIt != theMaterialShape.end(); ++anIt) {
326
327     std::shared_ptr<ModelAPI_Feature> aGroupFeature = addFeature("Group");
328     // group name
329     aGroupFeature->data()->setName((*anIt).first);
330
331     // fill selection
332     AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list");
333
334     std::list<ResultPtr> allRes;
335     ModelAPI_Tools::allSubs(theResultBody, allRes);
336     for (std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); ++aRes) {
337
338       GeomShapePtr aShape = (*aRes)->shape();
339       for (std::list<std::wstring>::iterator aResMat = anIt->second.begin();
340                                  aResMat != anIt->second.end(); ++aResMat) {
341         if (aRes->get() && ((*aRes)->data()->name() == (*aResMat)))
342         {
343           if (aShape->isCompound() || aShape->isCompSolid()) {
344             GeomAPI_ShapeIterator aShapeIt(aShape);
345             for (; aShapeIt.more(); aShapeIt.next()) {
346               aSelectionList->setSelectionType(aShapeIt.current()->shapeTypeStr());
347               aSelectionList->append(theResultBody, aShapeIt.current());
348             }
349           } else {
350             aSelectionList->setSelectionType(aShape->shapeTypeStr());
351             aSelectionList->append(theResultBody,aShape);
352           }
353           break;
354         }
355       }
356     }
357     if (aSelectionList->size() == 0){
358       document()->removeFeature(aGroupFeature);
359     }
360   }
361 }
362
363 void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName)
364 {
365   try {
366   std::string anError;
367
368   XAO::Xao aXao;
369   std::shared_ptr<GeomAPI_Shape> aGeomShape = XAOImport(theFileName, anError, &aXao);
370
371   if (!anError.empty()) {
372     setError("An error occurred while importing " + theFileName + ": " + anError);
373     return;
374   }
375
376   XAO::Geometry* aXaoGeometry = aXao.getGeometry();
377
378   // use the geometry name or the file name for the feature
379   std::string aBodyName = aXaoGeometry->getName();
380   if (aBodyName.empty())
381     aBodyName = GeomAlgoAPI_Tools::File_Tools::name(theFileName);
382   data()->setName(Locale::Convert::toWString(aBodyName));
383
384   ResultBodyPtr aResultBody = createResultBody(aGeomShape);
385   setResult(aResultBody);
386
387   // Process groups/fields
388   std::shared_ptr<ModelAPI_AttributeRefList> aRefListOfGroups =
389       std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(data()->attribute(FEATURES_ID()));
390
391   // Remove previous groups/fields stored in RefList
392   std::list<ObjectPtr> anGroupList = aRefListOfGroups->list();
393   std::list<ObjectPtr>::iterator anGroupIt = anGroupList.begin();
394   for (; anGroupIt != anGroupList.end(); ++anGroupIt) {
395     std::shared_ptr<ModelAPI_Feature> aFeature = ModelAPI_Feature::feature(*anGroupIt);
396     if (aFeature)
397       document()->removeFeature(aFeature);
398   }
399
400   // Create new groups
401   for (int aGroupIndex = 0; aGroupIndex < aXao.countGroups(); ++aGroupIndex) {
402     XAO::Group* aXaoGroup = aXao.getGroup(aGroupIndex);
403
404     std::shared_ptr<ModelAPI_Feature> aGroupFeature = addFeature("Group");
405
406     // group name
407     if (!aXaoGroup->getName().empty())
408       aGroupFeature->data()->setName(Locale::Convert::toWString(aXaoGroup->getName()));
409
410     // fill selection
411     AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list");
412
413     // conversion of dimension
414     std::string aDimensionString = XAO::XaoUtils::dimensionToString(aXaoGroup->getDimension());
415     std::string aSelectionType =
416       ExchangePlugin_Tools::xaoDimension2selectionType(aDimensionString);
417
418     aSelectionList->setSelectionType(aSelectionType);
419     for (int anElementIndex = 0; anElementIndex < aXaoGroup->count(); ++anElementIndex) {
420       aSelectionList->append(aResultBody, GeomShapePtr());
421       // complex conversion of element index to reference id
422       int anElementID = aXaoGroup->get(anElementIndex);
423       std::string aReferenceString =
424         aXaoGeometry->getElementReference(aXaoGroup->getDimension(), anElementID);
425       int aReferenceID = XAO::XaoUtils::stringToInt(aReferenceString);
426
427       aSelectionList->value(anElementIndex)->setId(aReferenceID);
428     }
429   }
430   // Create new fields
431   for (int aFieldIndex = 0; aFieldIndex < aXao.countFields(); ++aFieldIndex) {
432     XAO::Field* aXaoField = aXao.getField(aFieldIndex);
433
434     std::shared_ptr<ModelAPI_Feature> aFieldFeature = addFeature("Field");
435
436     // group name
437     if (!aXaoField->getName().empty())
438       aFieldFeature->data()->setName(Locale::Convert::toWString(aXaoField->getName()));
439
440     // fill selection
441     AttributeSelectionListPtr aSelectionList = aFieldFeature->selectionList("selected");
442
443     // conversion of dimension
444     std::string aDimensionString = XAO::XaoUtils::dimensionToString(aXaoField->getDimension());
445     std::string aSelectionType =
446       ExchangePlugin_Tools::xaoDimension2selectionType(aDimensionString);
447     aSelectionList->setSelectionType(aSelectionType);
448     // limitation: now in XAO fields are related to everything, so, iterate all sub-shapes to fill
449     int aCountSelected = aXaoField->countElements();
450     std::list<ResultPtr>::const_iterator aResIter = results().begin();
451     for(; aResIter != results().end() && aCountSelected; aResIter++) {
452       ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aResIter);
453       if (!aBody.get())
454         continue;
455       // check that only results that were created before this field are used
456       FeaturePtr aResultFeature = document()->feature(aBody);
457       if (!aResultFeature.get())
458         continue;
459       GeomShapePtr aShape = aBody->shape();
460       if (!aShape.get() || aShape->isNull())
461         continue;
462       GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::shapeTypeByStr(aSelectionType));
463       for(; anExp.more(); anExp.next()) {
464         aSelectionList->append(aBody, anExp.current());
465         aCountSelected--;
466         if (aCountSelected == 0)
467           break;
468       }
469     }
470
471     // conversion of type
472     XAO::Type aFieldType = aXaoField->getType();
473     std::string aTypeString = XAO::XaoUtils::fieldTypeToString(aFieldType);
474     ModelAPI_AttributeTables::ValueType aType =
475       ExchangePlugin_Tools::xaoType2valuesType(aTypeString);
476     // set components names
477     AttributeStringArrayPtr aComponents = aFieldFeature->stringArray("components_names");
478     aComponents->setSize(aXaoField->countComponents());
479     for(int aComp = 0; aComp < aXaoField->countComponents(); aComp++) {
480       aComponents->setValue(aComp, aXaoField->getComponentName(aComp));
481     }
482
483     AttributeIntArrayPtr aStamps = aFieldFeature->intArray("stamps");
484     aStamps->setSize(aXaoField->countSteps());
485     std::shared_ptr<ModelAPI_AttributeTables> aTables = aFieldFeature->tables("values");
486     aTables->setSize(
487       aXaoField->countElements() + 1, aXaoField->countComponents(), aXaoField->countSteps());
488     aTables->setType(aType);
489     // iterate steps
490     XAO::stepIterator aStepIter = aXaoField->begin();
491     for(int aStepIndex = 0; aStepIter != aXaoField->end(); aStepIter++, aStepIndex++) {
492       aStamps->setValue(aStepIndex, (*aStepIter)->getStamp());
493       for(int aRow = 1; aRow <= aXaoField->countElements(); aRow++) {
494         for(int aCol = 0; aCol < aXaoField->countComponents(); aCol++) {
495           ModelAPI_AttributeTables::Value aVal;
496           std::string aValStr = (*aStepIter)->getStringValue(aRow - 1, aCol);
497           switch(aType) {
498           case ModelAPI_AttributeTables::BOOLEAN:
499             aVal.myBool = aValStr == "true";
500             break;
501           case ModelAPI_AttributeTables::INTEGER:
502             aVal.myInt = atoi(aValStr.c_str());
503             break;
504           case ModelAPI_AttributeTables::DOUBLE:
505             aVal.myDouble = atof(aValStr.c_str());
506             break;
507           case ModelAPI_AttributeTables::STRING:
508             aVal.myStr = aValStr;
509             break;
510           }
511           aTables->setValue(aVal, aRow, aCol, aStepIndex);
512         }
513       }
514     }
515     // remove everything with zero-values: zeroes are treated as defaults
516     std::set<int> aRowsToRemove;
517     for(int aRow = 1; aRow < aTables->rows(); aRow++) {
518       bool isZero = true;
519       for(int aCol = 0; aCol < aTables->columns() && isZero; aCol++) {
520         for(int aStepIndex = 0; aStepIndex != aTables->tables() && isZero; aStepIndex++) {
521           if (aTables->valueStr(aRow, aCol, aStepIndex) != aTables->valueStr(0, aCol, aStepIndex))
522             isZero = false;
523         }
524       }
525       if (isZero)
526         aRowsToRemove.insert(aRow - 1); // -1 to make prepared for remove from SelectionList
527     }
528     if (!aRowsToRemove.empty()) { // move usefull rows on bottom to the up of the tables
529       // number of rows passed during going through: the current rows will
530       // be moved up for this value
531       int aRemovedPassed = 0;
532       for(int aRow = 1; aRow < aTables->rows(); aRow++) {
533         if (aRowsToRemove.find(aRow - 1) != aRowsToRemove.end()) {
534           aRemovedPassed++;
535         } else if (aRemovedPassed != 0) { // copy the line up
536           for(int aCol = 0; aCol < aTables->columns(); aCol++) {
537             for(int aTable = 0; aTable != aTables->tables(); aTable++) {
538               aTables->setValue(
539                 aTables->value(aRow, aCol, aTable), aRow - aRemovedPassed, aCol, aTable);
540             }
541           }
542         }
543       }
544       aTables->setSize(aTables->rows() - aRemovedPassed, aTables->columns(), aTables->tables());
545       aSelectionList->remove(aRowsToRemove); // remove also selected elements
546     }
547   }
548   // Top avoid problems in Object Browser update: issue #1647.
549   ModelAPI_EventCreator::get()->sendReordered(
550     std::dynamic_pointer_cast<ModelAPI_Feature>(aRefListOfGroups->owner()));
551
552 // LCOV_EXCL_START
553   } catch (XAO::XAO_Exception& e) {
554     std::string anError = e.what();
555     setError("An error occurred while importing " + theFileName + ": " + anError);
556     return;
557   }
558 // LCOV_EXCL_STOP
559 }
560
561 //============================================================================
562 std::shared_ptr<ModelAPI_Feature> ExchangePlugin_ImportFeatureBase::addFeature(
563     std::string theID)
564 {
565   std::shared_ptr<ModelAPI_Feature> aNew = document()->addFeature(theID, false);
566   if (aNew)
567     data()->reflist(FEATURES_ID())->append(aNew);
568   // set as current also after it becomes sub to set correctly enabled for other subs
569   //document()->setCurrentFeature(aNew, false);
570   return aNew;
571 }
572
573 // LCOV_EXCL_START
574 void ExchangePlugin_ImportFeatureBase::removeFeature(
575     std::shared_ptr<ModelAPI_Feature> theFeature)
576 {
577   if (!data()->isValid())
578     return;
579   AttributeRefListPtr aList = reflist(FEATURES_ID());
580   aList->remove(theFeature);
581 }
582 // LCOV_EXCL_STOP
583
584 int ExchangePlugin_ImportFeatureBase::numberOfSubs(bool /*forTree*/) const
585 {
586   return data()->reflist(FEATURES_ID())->size(true);
587 }
588
589 std::shared_ptr<ModelAPI_Feature> ExchangePlugin_ImportFeatureBase::subFeature(
590     const int theIndex, bool /*forTree*/)
591 {
592   ObjectPtr anObj = data()->reflist(FEATURES_ID())->object(theIndex, false);
593   FeaturePtr aRes = std::dynamic_pointer_cast<ModelAPI_Feature>(anObj);
594   return aRes;
595 }
596
597 // LCOV_EXCL_START
598 int ExchangePlugin_ImportFeatureBase::subFeatureId(const int theIndex) const
599 {
600   std::shared_ptr<ModelAPI_AttributeRefList> aRefList = std::dynamic_pointer_cast<
601       ModelAPI_AttributeRefList>(data()->attribute(FEATURES_ID()));
602   std::list<ObjectPtr> aFeatures = aRefList->list();
603   std::list<ObjectPtr>::const_iterator anIt = aFeatures.begin();
604   int aResultIndex = 1; // number of the counted (created) features, started from 1
605   int aFeatureIndex = -1; // number of the not-empty features in the list
606   for (; anIt != aFeatures.end(); anIt++) {
607     if (anIt->get())
608       aFeatureIndex++;
609     if (aFeatureIndex == theIndex)
610       break;
611     aResultIndex++;
612   }
613   return aResultIndex;
614 }
615 // LCOV_EXCL_STOP
616
617 bool ExchangePlugin_ImportFeatureBase::isSub(ObjectPtr theObject) const
618 {
619   // check is this feature of result
620   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
621   if (aFeature)
622     return data()->reflist(FEATURES_ID())->isInList(aFeature);
623   return false;
624 }
625
626 //============================================================================
627 void ExchangePlugin_ImportFeatureBase::loadNamingDS(
628     std::shared_ptr<GeomAPI_Shape> theGeomShape,
629     std::shared_ptr<ModelAPI_ResultBody> theResultBody)
630 {
631   //load result
632   theResultBody->store(theGeomShape);
633
634   std::string aNameMS = "Shape";
635   theResultBody->loadFirstLevel(theGeomShape, aNameMS);
636 }
637
638 void ExchangePlugin_Import_ImageFeature::importFile(const std::string& theFileName)
639 {
640   std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFileName);
641   std::string anError;
642
643   if (anExtension == "PNG"  || anExtension == "GIF" ||
644       anExtension == "TIFF" || anExtension == "JPE" ||
645       anExtension == "JPEG" || anExtension == "JPG" ||
646       anExtension == "BMP"  || anExtension == "PPM"
647       ) {
648     // Perform the import
649     QPixmap px (theFileName.c_str());
650     int aWidth  = px.width();
651     int aHeight = px.height();
652     if (aWidth < 1 || aHeight < 1) {
653       setError("An error occurred while importing " + theFileName + ": invalid image");
654       return;
655     }
656
657     std::shared_ptr<GeomAPI_Shape> aGeomShape = ImageImport(aWidth, aHeight, anError);
658
659     // Check if shape is valid
660     if (!anError.empty()) {
661       setError("An error occurred while importing " + theFileName + ": " + anError);
662       return;
663     }
664
665     // Pass the results into the model
666     std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName);
667     data()->setName(Locale::Convert::toWString(anObjectName));
668
669     auto resultBody = createResultBody(aGeomShape);
670
671     // Store image in result body attribute
672     AttributeImagePtr anImageAttr = resultBody->data()->image(ModelAPI_ResultBody::IMAGE_ID());
673     if (anImageAttr.get() != NULL) {
674       QImage aQImage = px.toImage();
675       const uchar* aImageBytes = aQImage.bits();
676       std::list<unsigned char> aByteArray (aImageBytes, aImageBytes + aQImage.sizeInBytes());
677       anImageAttr->setTexture(aWidth, aHeight, aByteArray, anExtension);
678     }
679
680     setResult(resultBody);
681   }
682   else {
683     anError = "Unsupported format: " + anExtension;
684     setError("An error occurred while importing " + theFileName + ": " + anError);
685   }
686 }