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