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