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