Salome HOME
Change color action for a body object
[modules/shaper.git] / src / Model / Model_ResultBody.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        Model_ResultBody.cpp
4 // Created:     08 Jul 2014
5 // Author:      Mikhail PONIKAROV
6
7 #include <Model_ResultBody.h>
8 #include <Model_Data.h>
9 #include <Model_Document.h>
10 #include <ModelAPI_AttributeColor.h>
11 #include <TNaming_Builder.hxx>
12 #include <TNaming_NamedShape.hxx>
13 #include <TDataStd_Name.hxx>
14 #include <TopoDS.hxx>
15 #include <TopoDS_Shape.hxx>
16 #include <TopoDS_Face.hxx>
17 #include <TDF_ChildIterator.hxx>
18 #include <TopTools_MapOfShape.hxx>
19 #include <TopExp_Explorer.hxx>
20 #include <TopTools_ListOfShape.hxx>
21 #include <TopTools_ListIteratorOfListOfShape.hxx>
22 #include <TopTools_DataMapOfShapeListOfShape.hxx>
23 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
24 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
25 #include <TopTools_MapIteratorOfMapOfShape.hxx>
26 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
27 #include <TopTools_IndexedMapOfShape.hxx>
28 #include <TopTools_DataMapOfShapeShape.hxx>
29 #include <TopExp.hxx>
30 #include <BRepTools.hxx>
31 #include <BRep_Tool.hxx>
32 #include <GeomAPI_Shape.h>
33 #include <GeomAlgoAPI_MakeShape.h>
34 #include <Config_PropManager.h>
35 // DEB
36 //#include <TCollection_AsciiString.hxx>
37 //#include <TDF_Tool.hxx>
38 //#define DEB_IMPORT 1
39
40 #define RESULT_BODY_COLOR "#ff0000"
41
42 Model_ResultBody::Model_ResultBody()
43 {
44   setIsConcealed(false);
45 }
46
47 void Model_ResultBody::initAttributes()
48 {
49   // append the color attribute
50   DataPtr aData = data();
51   aData->addAttribute(COLOR_ID(), ModelAPI_AttributeColor::type());
52   // set the default value
53   bool anIsRandomColor = Config_PropManager::boolean("Visualization", "random_result_color",
54                                                      "false");
55   AttributeColorPtr aColorAttr = std::dynamic_pointer_cast<ModelAPI_AttributeColor>
56                                                              (aData->attribute(COLOR_ID()));
57   if (anIsRandomColor)
58     aColorAttr->setValuesRandom();
59   else {
60     std::vector<int> aRGB;
61     aRGB = Config_PropManager::color("Visualization", "result_body_color", RESULT_BODY_COLOR);
62     aColorAttr->setValues(aRGB[0], aRGB[1], aRGB[2]);
63   }
64 }
65
66 void Model_ResultBody::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
67 {
68   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
69   if (aData) {
70     TDF_Label& aShapeLab = aData->shapeLab();
71     // clean builders
72     clean();   
73     // store the new shape as primitive
74     TNaming_Builder aBuilder(aShapeLab);
75     if (!theShape)
76       return;  // bad shape
77     TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
78     if (aShape.IsNull())
79       return;  // null shape inside
80
81     aBuilder.Generated(aShape); 
82         // register name
83         if(!aBuilder.NamedShape()->IsEmpty()) {
84           Handle(TDataStd_Name) anAttr;
85           if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
86                 std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
87                 if(!aName.empty()) {
88           std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
89           aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
90                 }
91           }
92         }
93   }
94 }
95
96 void Model_ResultBody::storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theFromShape,
97   const std::shared_ptr<GeomAPI_Shape>& theToShape)
98 {
99   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
100   if (aData) {
101     TDF_Label& aShapeLab = aData->shapeLab();
102     // clean builders
103     clean();   
104     // store the new shape as primitive
105     TNaming_Builder aBuilder(aShapeLab);
106     if (!theFromShape || !theToShape)
107       return;  // bad shape
108     TopoDS_Shape aShapeBasis = theFromShape->impl<TopoDS_Shape>();
109     if (aShapeBasis.IsNull())
110       return;  // null shape inside
111     TopoDS_Shape aShapeNew = theToShape->impl<TopoDS_Shape>();
112     if (aShapeNew.IsNull())
113       return;  // null shape inside
114     aBuilder.Generated(aShapeBasis, aShapeNew);
115                 // register name
116         if(!aBuilder.NamedShape()->IsEmpty()) {
117           Handle(TDataStd_Name) anAttr;
118           if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
119                 std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
120                 if(!aName.empty()) {
121           std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
122           aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
123                 }
124           }
125         }
126   }
127 }
128
129 void Model_ResultBody::storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
130   const std::shared_ptr<GeomAPI_Shape>& theNewShape)
131 {
132   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
133   if (aData) {
134     TDF_Label& aShapeLab = aData->shapeLab();
135     // clean builders
136     clean();   
137     // store the new shape as primitive
138     TNaming_Builder aBuilder(aShapeLab);
139     if (!theOldShape || !theNewShape)
140       return;  // bad shape
141     TopoDS_Shape aShapeOld = theOldShape->impl<TopoDS_Shape>();
142     if (aShapeOld.IsNull())
143       return;  // null shape inside
144     TopoDS_Shape aShapeNew = theNewShape->impl<TopoDS_Shape>();
145     if (aShapeNew.IsNull())
146       return;  // null shape inside
147         aBuilder.Modify(aShapeOld, aShapeNew);
148   }
149 }
150
151 std::shared_ptr<GeomAPI_Shape> Model_ResultBody::shape()
152 {
153   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
154   if (aData) {
155     TDF_Label& aShapeLab = aData->shapeLab();
156     Handle(TNaming_NamedShape) aName;
157     if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) {
158       TopoDS_Shape aShape = aName->Get();
159       if (!aShape.IsNull()) {
160         std::shared_ptr<GeomAPI_Shape> aRes(new GeomAPI_Shape);
161         aRes->setImpl(new TopoDS_Shape(aShape));
162         return aRes;
163       }
164     }
165   }
166   return std::shared_ptr<GeomAPI_Shape>();
167 }
168
169 void Model_ResultBody::clean()
170 {
171   std::vector<TNaming_Builder*>::iterator aBuilder = myBuilders.begin();
172   for(; aBuilder != myBuilders.end(); aBuilder++)
173     delete *aBuilder;
174   myBuilders.clear();
175 }
176
177 Model_ResultBody::~Model_ResultBody()
178 {
179   clean();
180 }
181
182 TNaming_Builder* Model_ResultBody::builder(const int theTag)
183 {
184   if (myBuilders.size() <= (unsigned int)theTag) {
185     myBuilders.insert(myBuilders.end(), theTag - myBuilders.size() + 1, NULL);
186   }
187   if (!myBuilders[theTag]) {
188     std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
189     myBuilders[theTag] = new TNaming_Builder(aData->shapeLab().FindChild(theTag));
190     //TCollection_AsciiString entry;//
191     //TDF_Tool::Entry(aData->shapeLab().FindChild(theTag), entry);
192     //cout << "Label = " <<entry.ToCString() <<endl;
193   }
194   return myBuilders[theTag];
195 }
196
197 void Model_ResultBody::buildName(const int theTag, const std::string& theName)
198 {
199   std::string aName = data()->name() + "/" + theName; 
200   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
201   aDoc->addNamingName(builder(theTag)->NamedShape()->Label(), aName);
202   TDataStd_Name::Set(builder(theTag)->NamedShape()->Label(),aName.c_str());
203 }
204 void Model_ResultBody::generated(
205   const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
206 {
207   TopoDS_Shape aShape = theNewShape->impl<TopoDS_Shape>();
208   builder(theTag)->Generated(aShape);
209   if(!theName.empty()) 
210     buildName(theTag, theName);
211 }
212
213 void Model_ResultBody::generated(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
214   const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
215 {
216   TopoDS_Shape anOldShape = theOldShape->impl<TopoDS_Shape>();
217   TopoDS_Shape aNewShape = theNewShape->impl<TopoDS_Shape>();
218   builder(theTag)->Generated(anOldShape, aNewShape);
219   if(!theName.empty()) 
220     buildName(theTag, theName);
221 }
222
223
224 void Model_ResultBody::modified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
225   const std::shared_ptr<GeomAPI_Shape>& theNewShape, const std::string& theName, const int theTag)
226 {
227   TopoDS_Shape anOldShape = theOldShape->impl<TopoDS_Shape>();
228   TopoDS_Shape aNewShape = theNewShape->impl<TopoDS_Shape>();
229   builder(theTag)->Modify(anOldShape, aNewShape);
230   if(!theName.empty()) 
231     buildName(theTag, theName);
232 }
233
234 void Model_ResultBody::deleted(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
235   const int theTag)
236 {
237   TopoDS_Shape aShape = theOldShape->impl<TopoDS_Shape>();
238   builder(theTag)->Delete(aShape);
239 }
240
241 void Model_ResultBody::loadDeletedShapes (GeomAlgoAPI_MakeShape* theMS,
242   std::shared_ptr<GeomAPI_Shape>  theShapeIn,
243   const int  theKindOfShape,
244   const int  theTag)
245 {
246   TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
247   TopTools_MapOfShape aView;
248   TopExp_Explorer ShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
249   for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
250     const TopoDS_Shape& aRoot = ShapeExplorer.Current ();
251     if (!aView.Add(aRoot)) continue;
252     std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
253     aRShape->setImpl((new TopoDS_Shape(aRoot)));
254     if (theMS->isDeleted (aRShape)) {
255       builder(theTag)->Delete(aRoot);
256     }
257   }
258 }
259
260 void Model_ResultBody::loadAndOrientModifiedShapes (
261   GeomAlgoAPI_MakeShape* theMS,
262   std::shared_ptr<GeomAPI_Shape>  theShapeIn,
263   const int  theKindOfShape,
264   const int  theTag,
265   const std::string& theName,
266   GeomAPI_DataMapOfShapeShape& theSubShapes)
267 {
268   TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
269   TopTools_MapOfShape aView;
270   bool isBuilt = theName.empty();
271   TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
272   for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
273     const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
274     if (!aView.Add(aRoot)) continue;
275     ListOfShape aList;
276     std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
277     aRShape->setImpl((new TopoDS_Shape(aRoot)));
278         theMS->modified(aRShape, aList);
279     std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
280     for (; anIt != aLast; anIt++) {
281       TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();     
282       if (theSubShapes.isBound(*anIt)) {
283         std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
284         aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
285       }
286       if (!aRoot.IsSame (aNewShape)) {
287         builder(theTag)->Modify(aRoot,aNewShape);
288                 if(!isBuilt) 
289                   buildName(theTag, theName);           
290           }
291     }
292   }
293 }
294
295 void Model_ResultBody::loadAndOrientGeneratedShapes (
296   GeomAlgoAPI_MakeShape* theMS,
297   std::shared_ptr<GeomAPI_Shape>  theShapeIn,
298   const int  theKindOfShape,
299   const int  theTag,
300   const std::string& theName,
301   GeomAPI_DataMapOfShapeShape& theSubShapes)
302 {
303   TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
304   TopTools_MapOfShape aView;
305   bool isBuilt = theName.empty();
306   TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
307   for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
308     const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
309     if (!aView.Add(aRoot)) continue;
310     ListOfShape aList;
311     std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
312     aRShape->setImpl((new TopoDS_Shape(aRoot)));
313     theMS->generated(aRShape, aList);
314     std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
315     for (; anIt != aLast; anIt++) {
316       TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();     
317       if (theSubShapes.isBound(*anIt)) {
318         std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
319         aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
320       }
321       if (!aRoot.IsSame (aNewShape)) {
322         builder(theTag)->Generated(aRoot,aNewShape);
323                 if(!isBuilt) 
324                   buildName(theTag, theName);   
325           }
326     }
327   }
328 }
329
330 //=======================================================================
331 int getDangleShapes(const TopoDS_Shape&           theShapeIn, 
332                                         const TopAbs_ShapeEnum        theGeneratedFrom,
333                                     TopTools_DataMapOfShapeShape& theDangles) 
334 {
335   theDangles.Clear();
336   TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors;
337   TopAbs_ShapeEnum GeneratedTo;
338   if (theGeneratedFrom == TopAbs_FACE) GeneratedTo = TopAbs_EDGE;
339   else if (theGeneratedFrom == TopAbs_EDGE) GeneratedTo = TopAbs_VERTEX;
340   else return Standard_False;
341   TopExp::MapShapesAndAncestors(theShapeIn, GeneratedTo, theGeneratedFrom, subShapeAndAncestors);
342   for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) {
343     const TopoDS_Shape& mayBeDangle = subShapeAndAncestors.FindKey(i);
344     const TopTools_ListOfShape& ancestors = subShapeAndAncestors.FindFromIndex(i);
345     if (ancestors.Extent() == 1) theDangles.Bind(ancestors.First(), mayBeDangle);
346   }
347   return theDangles.Extent();
348 }
349
350 //=======================================================================
351 void loadGeneratedDangleShapes(
352                                                            const TopoDS_Shape&      theShapeIn,
353                                                const TopAbs_ShapeEnum   theGeneratedFrom,
354                                                TNaming_Builder *        theBuilder)
355 {
356   TopTools_DataMapOfShapeShape dangles;
357   if (!getDangleShapes(theShapeIn, theGeneratedFrom, dangles)) return;
358   TopTools_DataMapIteratorOfDataMapOfShapeShape itr(dangles);
359   for (; itr.More(); itr.Next()) 
360         theBuilder->Generated(itr.Key(), itr.Value());
361 }
362
363 //=======================================================================
364 void Model_ResultBody::loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape, 
365                                           const std::string& theName, int&  theTag)
366 {
367   if(theShape->isNull()) return;
368   TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();    
369   std::string aName;
370   if (aShape.ShapeType() == TopAbs_SOLID) {                 
371     TopExp_Explorer expl(aShape, TopAbs_FACE);
372     for (; expl.More(); expl.Next()) {  
373           builder(theTag)->Generated(expl.Current()); 
374           TCollection_AsciiString aStr(theTag);
375           aName = theName + aStr.ToCString();
376           buildName(theTag, aName);
377           theTag++;
378         }
379   }
380   else if (aShape.ShapeType() == TopAbs_SHELL || aShape.ShapeType() == TopAbs_FACE) {
381     // load faces and all the free edges
382     TopTools_IndexedMapOfShape Faces;
383     TopExp::MapShapes(aShape, TopAbs_FACE, Faces);
384     if (Faces.Extent() > 1 || (aShape.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
385       TopExp_Explorer expl(aShape, TopAbs_FACE);
386       for (; expl.More(); expl.Next()) {
387                   builder(theTag)->Generated(expl.Current());          
388                   TCollection_AsciiString aStr(theTag);
389               aName = theName + aStr.ToCString();
390               buildName(theTag, aName);
391                   theTag++;
392           }
393         }
394     TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
395     TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, anEdgeAndNeighbourFaces);
396     for (Standard_Integer i = 1; i <= anEdgeAndNeighbourFaces.Extent(); i++) 
397         {
398       const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i);
399       if (aLL.Extent() < 2) {
400                   if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeAndNeighbourFaces.FindKey(i))))
401           continue;
402             builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
403                 TCollection_AsciiString aStr(theTag);
404             aName = theName + aStr.ToCString();
405             buildName(theTag, aName);
406                 theTag++;
407       } else {
408           TopTools_ListIteratorOfListOfShape anIter(aLL);
409           const TopoDS_Face& aFace = TopoDS::Face(anIter.Value());
410           anIter.Next();
411           if(aFace.IsEqual(anIter.Value())) {
412                 builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
413                 TCollection_AsciiString aStr(theTag);
414             aName = theName + aStr.ToCString();
415             buildName(theTag, aName);
416             theTag++;
417           }
418           }
419         }
420   } else if (aShape.ShapeType() == TopAbs_WIRE) {
421     TopTools_IndexedMapOfShape Edges;
422     BRepTools::Map3DEdges(aShape, Edges);
423     if (Edges.Extent() == 1) {
424           builder(++theTag)->Generated(Edges.FindKey(1));
425       TopExp_Explorer expl(aShape, TopAbs_VERTEX);
426       for (; expl.More(); expl.Next()) {
427             builder(theTag)->Generated(expl.Current());
428                 TCollection_AsciiString aStr(theTag);
429             aName = theName + aStr.ToCString();
430             buildName(theTag, aName);
431             theTag++;
432           }
433         } else {
434       TopExp_Explorer expl(aShape, TopAbs_EDGE); 
435       for (; expl.More(); expl.Next()) {        
436                 builder(theTag)->Generated(expl.Current());
437                 TCollection_AsciiString aStr(theTag);
438             aName = theName + aStr.ToCString();
439             buildName(theTag, aName);
440                 theTag++;
441           }   
442       // and load generated vertices.
443       TopTools_DataMapOfShapeShape generated;
444       if (getDangleShapes(aShape, TopAbs_EDGE, generated)) 
445           {
446                 TNaming_Builder* pBuilder = builder(theTag++);
447                 loadGeneratedDangleShapes(aShape, TopAbs_EDGE, pBuilder);  
448           }
449         }
450   } else if (aShape.ShapeType() == TopAbs_EDGE) {
451     TopExp_Explorer expl(aShape, TopAbs_VERTEX);
452     for (; expl.More(); expl.Next()) {      
453                 builder(theTag)->Generated(expl.Current());
454                 TCollection_AsciiString aStr(theTag);
455             aName = theName + aStr.ToCString();
456             buildName(theTag, aName);
457                 theTag++;
458         }
459   }
460 }
461
462 //=======================================================================
463 int findAmbiguities(const TopoDS_Shape&           theShapeIn,                                   
464                                           TopTools_ListOfShape&   theList) 
465 {
466   int aNumEdges(0);
467   theList.Clear();
468   TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors;
469   TopAbs_ShapeEnum aTS(TopAbs_EDGE);
470   TopAbs_ShapeEnum aTA(TopAbs_FACE);
471   TopTools_MapOfShape aMap1, aMap2; // map1 - for edge ancestors; map2 - for keys => edges
472   TopTools_ListOfShape aKeyList;
473   TopExp::MapShapesAndAncestors(theShapeIn, aTS, aTA, subShapeAndAncestors);
474   for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) {
475     const TopoDS_Shape& aKeyEdge1 = subShapeAndAncestors.FindKey(i);
476     const TopTools_ListOfShape& ancestors1 = subShapeAndAncestors.FindFromIndex(i);
477         aMap1.Clear();
478     TopTools_ListIteratorOfListOfShape it(ancestors1);
479         for(;it.More();it.Next()) aMap1.Add(it.Value()); // fill map with key ancestors => aKey1
480         for (Standard_Integer j = 1; j <= subShapeAndAncestors.Extent(); j++) {
481           if (i == j) continue;
482       const TopoDS_Shape& aKeyEdge2 = subShapeAndAncestors.FindKey(j);
483       const TopTools_ListOfShape& ancestors2 = subShapeAndAncestors.FindFromIndex(j);
484           if(ancestors1.Extent() == ancestors2.Extent() && ancestors1.Extent() > 1) {
485                 int aNum (ancestors2.Extent());
486             TopTools_ListIteratorOfListOfShape it(ancestors2);
487             for(;it.More();it.Next()) 
488                         if(aMap1.Contains(it.Value())) aNum--;
489                 if(aNum == 0) {
490                   if(aMap2.Add(aKeyEdge1)) 
491                         aKeyList.Append(aKeyEdge1);
492                   if(aMap2.Add(aKeyEdge2))
493                         aKeyList.Append(aKeyEdge2);
494                 }
495           }
496         } // at the end ==> List of edges to be named in addition       
497   }
498   aNumEdges = aKeyList.Extent();
499   if(aNumEdges)
500         theList.Assign(aKeyList);       
501   return aNumEdges; 
502 }
503
504 //=======================================================================
505 void Model_ResultBody::loadFirstLevel(
506                      std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
507 {
508   if(theShape->isNull()) return;
509   TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>(); 
510   std::string aName;
511   if (aShape.ShapeType() == TopAbs_COMPOUND || aShape.ShapeType() == TopAbs_COMPSOLID) {
512     TopoDS_Iterator itr(aShape);
513     for (; itr.More(); itr.Next(),theTag++) {
514           builder(theTag)->Generated(itr.Value());
515           TCollection_AsciiString aStr(theTag);
516           aName = theName + aStr.ToCString();
517           buildName(theTag, aName);
518           if(!theName.empty()) buildName(theTag, aName);
519       if (itr.Value().ShapeType() == TopAbs_COMPOUND || 
520                   itr.Value().ShapeType() == TopAbs_COMPSOLID) 
521           {
522                 std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
523         itrShape->setImpl(new TopoDS_Shape(itr.Value()));
524             loadFirstLevel(itrShape, theName, theTag);
525       } else {
526                 std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
527         itrShape->setImpl(new TopoDS_Shape(itr.Value()));               
528                 loadNextLevels(itrShape, theName, theTag);
529           }
530     }
531   } else {
532     std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
533     itrShape->setImpl(new TopoDS_Shape(aShape));
534         loadNextLevels(itrShape, theName, theTag); 
535   }
536   TopTools_ListOfShape   aList;
537   if(findAmbiguities(aShape, aList)) {
538         TopTools_ListIteratorOfListOfShape it(aList);
539     for (; it.More(); it.Next(),theTag++) {
540           builder(theTag)->Generated(it.Value());
541           TCollection_AsciiString aStr(theTag);
542           aName = theName + aStr.ToCString();
543           buildName(theTag, aName);
544         }
545   }
546 }
547
548 //=======================================================================
549 void Model_ResultBody::loadDisconnectedEdges(
550                      std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
551 {
552   if(theShape->isNull()) return;
553   TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();  
554   TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
555   TopTools_ListOfShape empty;
556   TopExp_Explorer explF(aShape, TopAbs_FACE);
557   for (; explF.More(); explF.Next()) {
558     const TopoDS_Shape& aFace = explF.Current();
559     TopExp_Explorer explV(aFace, TopAbs_EDGE);
560     for (; explV.More(); explV.Next()) {
561       const TopoDS_Shape& anEdge = explV.Current();
562       if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
563       Standard_Boolean faceIsNew = Standard_True;
564       TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
565       for (; itrF.More(); itrF.Next()) {
566             if (itrF.Value().IsSame(aFace)) {
567             faceIsNew = Standard_False;
568             break;
569                 }
570           }
571       if (faceIsNew) 
572             edgeNaborFaces.ChangeFind(anEdge).Append(aFace);      
573         }
574   }
575
576 /*  TopTools_IndexedDataMapOfShapeListOfShape aDM;
577   TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, aDM);
578   for(int i=1; i <= aDM.Extent(); i++) {
579         if(aDM.FindFromIndex(i).Extent() > 1) continue;
580         if (BRep_Tool::Degenerated(TopoDS::Edge(aDM.FindKey(i))))
581      continue;
582         builder(theTag)->Generated(aDM.FindKey(i));
583     TCollection_AsciiString aStr(theTag);
584         std::string aName = theName + aStr.ToCString();
585         buildName(theTag, aName);
586 #ifdef DEB_IMPORT
587         aName +=  + ".brep";
588         BRepTools::Write(aDM.FindKey(i), aName.c_str());
589 #endif
590         theTag++;
591   }
592 */
593   TopTools_MapOfShape anEdgesToDelete;
594   TopExp_Explorer anEx(aShape,TopAbs_EDGE); 
595   std::string aName;
596   for(;anEx.More();anEx.Next()) {
597     Standard_Boolean aC0 = Standard_False;
598     TopoDS_Shape anEdge1 = anEx.Current();
599     if (edgeNaborFaces.IsBound(anEdge1)) {
600       const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
601       if (aList1.Extent()<2) continue;
602       TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
603       for (; itr.More(); itr.Next()) {
604             TopoDS_Shape anEdge2 = itr.Key();
605             if(anEdgesToDelete.Contains(anEdge2)) continue;
606             if (anEdge1.IsSame(anEdge2)) continue;
607             const TopTools_ListOfShape& aList2 = itr.Value();
608             // compare lists of the neighbour faces of edge1 and edge2
609             if (aList1.Extent() == aList2.Extent()) {
610             Standard_Integer aMatches = 0;
611             for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
612               for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
613                 if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
614                 if (aMatches == aList1.Extent()) {
615                   aC0=Standard_True;
616                           builder(theTag)->Generated(anEdge2);
617                   anEdgesToDelete.Add(anEdge2);
618                           TCollection_AsciiString aStr(theTag);
619                           aName = theName + aStr.ToCString();
620                   buildName(theTag, aName);
621                           theTag++;
622                         }
623                 }
624           }      
625       TopTools_MapIteratorOfMapOfShape itDelete(anEdgesToDelete);
626       for(;itDelete.More();itDelete.Next()) 
627             edgeNaborFaces.UnBind(itDelete.Key());      
628       edgeNaborFaces.UnBind(anEdge1);
629         }
630     if (aC0) {
631           builder(theTag)->Generated(anEdge1);
632           TCollection_AsciiString aStr(theTag);
633           aName = theName + aStr.ToCString();
634           buildName(theTag, aName);      
635           theTag++;
636         }
637   }  
638 }
639
640 void Model_ResultBody::loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
641 {
642   if(theShape->isNull()) return;
643   TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();  
644   TopTools_DataMapOfShapeListOfShape vertexNaborEdges;
645   TopTools_ListOfShape empty;
646   TopExp_Explorer explF(aShape, TopAbs_EDGE);
647   for (; explF.More(); explF.Next()) {
648     const TopoDS_Shape& anEdge = explF.Current();
649     TopExp_Explorer explV(anEdge, TopAbs_VERTEX);
650     for (; explV.More(); explV.Next()) {
651       const TopoDS_Shape& aVertex = explV.Current();
652       if (!vertexNaborEdges.IsBound(aVertex)) vertexNaborEdges.Bind(aVertex, empty);
653       Standard_Boolean faceIsNew = Standard_True;
654       TopTools_ListIteratorOfListOfShape itrF(vertexNaborEdges.Find(aVertex));
655       for (; itrF.More(); itrF.Next()) {
656         if (itrF.Value().IsSame(anEdge)) {
657           faceIsNew = Standard_False;
658           break;
659         }
660       }
661       if (faceIsNew) {
662         vertexNaborEdges.ChangeFind(aVertex).Append(anEdge);
663       }
664     }
665   }
666   std::string aName;
667   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborEdges);
668   for (; itr.More(); itr.Next()) {
669     const TopTools_ListOfShape& naborEdges = itr.Value();
670     if (naborEdges.Extent() < 2) {              
671                 builder(theTag)->Generated(itr.Key());
672                 TCollection_AsciiString aStr(theTag);
673             aName = theName + aStr.ToCString();
674             buildName(theTag, aName);    
675                 theTag++;
676         }
677   }
678 }