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