0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / QANewModTopOpe / QANewModTopOpe_Glue.cxx
1 // Created on: 2000-12-08
2 // Created by: Michael SAZONOV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <gp_Pnt.hxx>
19 #include <QANewModTopOpe_Glue.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <TopoDS.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Face.hxx>
24 #include <TopoDS_Iterator.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
28 #include <TopTools_ListIteratorOfListOfShape.hxx>
29
30 static TopoDS_Shape RemoveCompounds(const TopoDS_Shape& TheS)
31 {
32
33   if(TheS.IsNull()) return TheS;
34
35   TopAbs_ShapeEnum aType = TheS.ShapeType();
36
37   if(aType != TopAbs_COMPOUND) return TheS;
38
39   TopTools_MapOfShape aMap;
40   TopoDS_Shape aResult;
41
42   BRep_Builder aBld;
43   aBld.MakeCompound(TopoDS::Compound(aResult));
44   Standard_Integer n = 0;
45   TopExp_Explorer anExp;
46
47   anExp.Init(TheS, TopAbs_COMPSOLID);
48   for(; anExp.More(); anExp.Next()) {
49     n++;
50     if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current());
51   }
52
53   anExp.Init(TheS, TopAbs_SOLID, TopAbs_COMPSOLID);
54   for(; anExp.More(); anExp.Next()) {
55     n++;
56     if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current());
57   }
58
59   anExp.Init(TheS, TopAbs_SHELL, TopAbs_SOLID);
60   for(; anExp.More(); anExp.Next()) {
61     n++;
62     if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current());
63   }
64
65   anExp.Init(TheS, TopAbs_FACE, TopAbs_SHELL);
66   for(; anExp.More(); anExp.Next()) {
67     n++;
68     if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current());
69   }
70
71   anExp.Init(TheS, TopAbs_WIRE, TopAbs_FACE);
72   for(; anExp.More(); anExp.Next()) {
73     n++;
74     if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current());
75   }
76
77   anExp.Init(TheS, TopAbs_EDGE, TopAbs_WIRE);
78   for(; anExp.More(); anExp.Next()) {
79     n++;
80     if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current());
81   }
82
83   if(n == 1) {
84     TopoDS_Iterator anIter(aResult);
85     aResult = anIter.Value();
86   }
87
88   if(n == 0) aResult.Nullify();
89
90   return aResult;
91 }
92
93
94 //=======================================================================
95 //function : QANewModTopOpe_Glue
96 //purpose  : 
97 //=======================================================================
98 QANewModTopOpe_Glue::QANewModTopOpe_Glue(const TopoDS_Shape& theS1,
99                                const TopoDS_Shape& theS2,
100                                const Standard_Boolean theAllowCutting,
101                                const Standard_Boolean thePerformNow)
102 : BRepAlgoAPI_BooleanOperation (theS1,theS2, BOPAlgo_FUSE),
103   myCompleted (Standard_False),
104   myAllowCutting (theAllowCutting)
105 {
106   NotDone();
107   myGenerated.Clear();
108   myMapModif.Clear();
109   myMapGener.Clear();
110   if (thePerformNow)
111     Build();
112 }
113 //=======================================================================
114 //function : Build
115 //purpose  : 
116 //=======================================================================
117
118 void QANewModTopOpe_Glue::Build() 
119 {
120   TopoDS_Shape& myS1=myArguments.First();
121   TopoDS_Shape& myS2=myTools.First();
122
123   if (myCompleted) return;
124
125   TopAbs_ShapeEnum aType1, aType2;
126   aType1 = myS1.ShapeType();
127   aType2 = myS2.ShapeType();
128
129   TopoDS_Shape aCopyS1 = myS1;
130   TopoDS_Shape aCopyS2 = myS2;
131   TopoDS_Shape aResult;
132
133   if(aType2 == TopAbs_VERTEX) {
134  
135     PerformVertex();
136
137     myCompleted = Standard_True;
138     return;
139
140   } else if (aType1 == TopAbs_VERTEX) {
141
142     myS2 = aCopyS1;
143     myS1 = aCopyS2;
144
145     PerformVertex();
146
147     myCompleted = Standard_True;
148     myS1 = aCopyS1;
149     myS2 = aCopyS2;
150     return;
151   }
152
153   Standard_Boolean aContains1 = Standard_False;
154   Standard_Boolean aContains2 = Standard_False;
155
156   TopExp_Explorer anExp(myS1, TopAbs_FACE);
157   aContains1 = anExp.More();
158   anExp.Init(myS2, TopAbs_FACE);
159   aContains2 = anExp.More();
160
161   if(aContains1 && aContains2) {
162
163     if(myS1.ShapeType() == TopAbs_FACE) {
164       BRep_Builder aBld;
165       TopoDS_Shape aCmp;
166       aBld.MakeCompound(TopoDS::Compound(aCmp));
167       aBld.Add(aCmp, myS1);
168       myS1 =  aCmp;
169     }
170     if(myS2.ShapeType() == TopAbs_FACE) {
171       BRep_Builder aBld;
172       TopoDS_Shape aCmp;
173       aBld.MakeCompound(TopoDS::Compound(aCmp));
174       aBld.Add(aCmp, myS2);
175       myS2 =  aCmp;
176     }
177
178     mySubst.Clear();
179     PerformSDFaces();
180
181     if(!myShape.IsNull()) {
182
183       TopoDS_Iterator anIter(myShape);
184       if(anIter.More()) {
185         myS1 = anIter.Value();
186         anIter.Next();
187         myS2 = anIter.Value();
188       }
189
190       aResult = myShape;
191       myShape.Nullify();
192
193     }
194     
195     mySubst.Clear();
196     PerformShell();
197  
198     if(!myShape.IsNull()) {
199
200       TopoDS_Iterator anIter(myShape);
201       if(anIter.More()) {
202         myS1 = anIter.Value();
203         anIter.Next();
204         myS2 = anIter.Value();
205       }
206
207       aResult = myShape;
208       myShape.Nullify();
209      
210     }
211     
212   }
213
214   if(aContains1 || aContains2) {
215     BRep_Builder aBld;
216     TopoDS_Shape aS1, aS2;
217     TopoDS_Shape aCpS1 = myS1, aCpS2 = myS2;
218     aBld.MakeCompound(TopoDS::Compound(aS1));
219     aBld.MakeCompound(TopoDS::Compound(aS2));
220
221     anExp.Init(myS1, TopAbs_WIRE, TopAbs_FACE);
222     for(; anExp.More(); anExp.Next()) {
223       aBld.Add(aS1, anExp.Current());
224     }
225   
226     anExp.Init(myS1, TopAbs_EDGE, TopAbs_WIRE);
227     for(; anExp.More(); anExp.Next()) {
228       aBld.Add(aS1, anExp.Current());
229     }
230
231     anExp.Init(myS2, TopAbs_WIRE, TopAbs_FACE);
232     for(; anExp.More(); anExp.Next()) {
233       aBld.Add(aS2, anExp.Current());
234     }
235   
236     anExp.Init(myS2, TopAbs_EDGE, TopAbs_WIRE);
237     for(; anExp.More(); anExp.Next()) {
238       aBld.Add(aS2, anExp.Current());
239     }
240
241     TopoDS_Iterator anIt1(aS1);
242     TopoDS_Iterator anIt2(aS2);
243
244     Standard_Boolean aShellWire = Standard_False;
245
246     if(anIt1.More() && anIt2.More()) {
247       aShellWire = Standard_True;
248       myS1 = aS1;
249       myS2 = aS2;
250       mySubst.Clear();
251
252       PerformWires();
253
254       myS1 = aCpS1;
255       myS2 = aCpS2;
256
257       if(!myShape.IsNull()) {
258         aS2 = myShape;
259         aS1.Nullify();
260         aBld.MakeCompound(TopoDS::Compound(aS1));
261       }
262       else {
263         for(; anIt1.More(); anIt1.Next()) aBld.Add(aS2, anIt1.Value());
264         aS1.Nullify();
265         aBld.MakeCompound(TopoDS::Compound(aS1));
266       }
267     }
268     else if(anIt1.More()) {
269       aShellWire = Standard_True;
270       aS2 = aS1;
271       aS1.Nullify();
272       aBld.MakeCompound(TopoDS::Compound(aS1));
273     }
274     else if(anIt2.More()) {
275       aShellWire = Standard_True;
276     }
277
278     if(aShellWire) {
279
280       if(aContains1) {
281
282         anExp.Init(myS1, TopAbs_COMPSOLID);
283         for(; anExp.More(); anExp.Next()) {
284           aBld.Add(aS1, anExp.Current());
285         }
286
287         anExp.Init(myS1, TopAbs_SOLID, TopAbs_COMPSOLID);
288         for(; anExp.More(); anExp.Next()) {
289           aBld.Add(aS1, anExp.Current());
290         }
291
292         anExp.Init(myS1, TopAbs_SHELL, TopAbs_SOLID);
293         for(; anExp.More(); anExp.Next()) {
294           aBld.Add(aS1, anExp.Current());
295         }
296
297         anExp.Init(myS1, TopAbs_FACE, TopAbs_SHELL);
298         for(; anExp.More(); anExp.Next()) {
299           aBld.Add(aS1, anExp.Current());
300         }
301
302       }
303
304       if(aContains2) {
305   
306         anExp.Init(myS2, TopAbs_COMPSOLID);
307         for(; anExp.More(); anExp.Next()) {
308           aBld.Add(aS1, anExp.Current());
309         }
310         
311         anExp.Init(myS2, TopAbs_SOLID, TopAbs_COMPSOLID);
312         for(; anExp.More(); anExp.Next()) {
313           aBld.Add(aS1, anExp.Current());
314         }
315         
316         anExp.Init(myS2, TopAbs_SHELL, TopAbs_SOLID);
317         for(; anExp.More(); anExp.Next()) {
318           aBld.Add(aS1, anExp.Current());
319         }
320
321         anExp.Init(myS2, TopAbs_FACE, TopAbs_SHELL);
322         for(; anExp.More(); anExp.Next()) {
323           aBld.Add(aS1, anExp.Current());
324         }
325
326       }
327       
328       myS1 = aS1;
329       myS2 = aS2;
330
331       mySubst.Clear();
332       PerformShellWire();
333
334       if(!myShape.IsNull()) {
335         aResult = myShape;
336       }
337       
338     }
339
340   }
341
342   if(!aContains1 && !aContains2) {
343
344     mySubst.Clear();
345     PerformWires();
346
347     if(!myShape.IsNull()) {
348       aResult = myShape;
349     }
350
351   }
352
353   myS1 = aCopyS1;
354   myS2 = aCopyS2;
355   myShape = RemoveCompounds(aResult);
356   if(myShape.IsNull()) NotDone();
357   myCompleted = Standard_True;
358 }
359
360 //=======================================================================
361 //function : Generated
362 //purpose  : 
363 //=======================================================================
364
365 const TopTools_ListOfShape&
366 QANewModTopOpe_Glue::Generated (const TopoDS_Shape& theS)
367 {
368   if (IsDone() && (myMapGener.IsBound(theS) || myMapModif.IsBound(theS))) {
369     TopTools_ListIteratorOfListOfShape anItl;
370     if(myMapGener.IsBound(theS)) anItl.Initialize(myMapGener(theS));
371     TopTools_ListIteratorOfListOfShape anItl1;
372     myGenerated.Clear();
373     Standard_Boolean aNonEmpty = Standard_False;
374     TopTools_ListOfShape aL1, aL;
375
376     for(; anItl.More(); anItl.Next()) aL.Append(anItl.Value());
377
378     TopTools_MapOfShape aMapModif;
379     anItl.Initialize(Modified(theS));
380     for(; anItl.More(); anItl.Next()) aMapModif.Add(anItl.Value());
381     myGenerated.Clear();
382
383     anItl.Initialize(myMapModif(theS));
384     for(; anItl.More(); anItl.Next()) {
385       if(!aMapModif.Contains(anItl.Value())) {
386         aL.Append(anItl.Value());
387       }
388     }
389
390     do 
391       {
392
393         aNonEmpty = Standard_False;
394         anItl.Initialize(aL);
395
396         for(; anItl.More(); anItl.Next()) {
397
398           if(myMapGener.IsBound(anItl.Value())) {
399             aNonEmpty = Standard_True;
400             anItl1.Initialize(myMapGener(anItl.Value()));
401             for(; anItl1.More(); anItl1.Next()) {
402               if(!anItl.Value().IsSame(anItl1.Value()))  aL1.Append(anItl1.Value());
403             }
404           }
405           else {
406             if(myMapModif.IsBound(anItl.Value())) {
407               aNonEmpty = Standard_True;
408               anItl1.Initialize(myMapModif(anItl.Value()));
409               for(; anItl1.More(); anItl1.Next()) {
410                 if(!anItl.Value().IsSame(anItl1.Value())) aL1.Append(anItl1.Value());
411               }
412             }
413             else {
414               if(!aMapModif.Contains(anItl.Value())) myGenerated.Append(anItl.Value());
415             }
416           }
417
418         }
419
420         if(!aL1.IsEmpty()) {
421           aL.Clear();
422           aL.Append(aL1);
423           aL1.Clear();
424         }
425         else aNonEmpty = Standard_False;
426             
427       }
428     while (aNonEmpty);
429
430     return myGenerated;
431
432   }
433
434
435   myGenerated.Clear();
436   return myGenerated;
437 }
438
439 //=======================================================================
440 //function : Modified
441 //purpose  : 
442 //=======================================================================
443
444 const TopTools_ListOfShape&
445 QANewModTopOpe_Glue::Modified (const TopoDS_Shape& theS)
446 {
447   if (IsDone() && myMapModif.IsBound(theS)) {
448     TopTools_ListIteratorOfListOfShape anItl(myMapModif(theS));
449     TopTools_ListIteratorOfListOfShape anItl1;
450     myGenerated.Clear();
451     Standard_Boolean aNonEmpty = Standard_False;
452     TopTools_ListOfShape aL1, aL;
453     for(; anItl.More(); anItl.Next()) aL.Append(anItl.Value());
454
455     myGenerated.Clear();
456
457     do 
458       {
459
460         aNonEmpty = Standard_False;
461         anItl.Initialize(aL);
462
463         for(; anItl.More(); anItl.Next()) {
464           if(myMapModif.IsBound(anItl.Value())) {
465             aNonEmpty = Standard_True;
466             anItl1.Initialize(myMapModif(anItl.Value()));
467             for(; anItl1.More(); anItl1.Next()) {
468               if(!anItl.Value().IsSame(anItl1.Value())) aL1.Append(anItl1.Value());
469             }
470           }
471           else {
472             myGenerated.Append(anItl.Value());
473           }
474         }
475
476         if(!aL1.IsEmpty()) {
477           aL.Clear();
478           aL.Append(aL1);
479           aL1.Clear();
480         }
481         else aNonEmpty = Standard_False;
482             
483       }
484     while (aNonEmpty);
485
486     return myGenerated;
487
488   }
489
490   myGenerated.Clear();
491   return myGenerated;
492 }
493
494 //=======================================================================
495 //function : IsDeleted
496 //purpose  : 
497 //=======================================================================
498
499 Standard_Boolean
500 QANewModTopOpe_Glue::IsDeleted (const TopoDS_Shape& theS)
501 {
502   if (IsDone() && myMapModif.IsBound(theS)) {
503     const TopTools_ListOfShape &aList = myMapModif.Find(theS);
504
505     if (aList.IsEmpty())
506       return Standard_True;
507
508     TopTools_ListIteratorOfListOfShape anIter(aList);
509
510     for (; anIter.More(); anIter.Next()) {
511       const TopoDS_Shape &aSplit = anIter.Value();
512
513       if (!IsDeleted(aSplit))
514         return Standard_False;
515     }
516
517     return Standard_True;
518   }
519
520   return Standard_False;
521 }
522 //=======================================================================
523 //function : HasGenerated
524 //purpose  : 
525 //=======================================================================
526
527 Standard_Boolean
528 QANewModTopOpe_Glue::HasGenerated () const
529 {
530   if (IsDone() && myMapGener.Extent() > 0)
531     return Standard_True;
532   return Standard_False;
533 }
534 //=======================================================================
535 //function : HasModified
536 //purpose  : 
537 //=======================================================================
538
539 Standard_Boolean
540 QANewModTopOpe_Glue::HasModified () const
541 {
542   
543   if (IsDone() && myMapModif.Extent() > 0) {
544     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape anIter(myMapModif);
545     for(; anIter.More(); anIter.Next()) {
546       if(anIter.Value().Extent() > 0) return Standard_True;
547     }
548   }
549   return Standard_False;
550 }
551 //=======================================================================
552 //function : HasDeleted
553 //purpose  : 
554 //=======================================================================
555
556 Standard_Boolean
557 QANewModTopOpe_Glue::HasDeleted () const
558 {
559   if (IsDone() && myMapModif.Extent() > 0) {
560     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape anIter(myMapModif);
561     for(; anIter.More(); anIter.Next()) {
562       if(anIter.Value().Extent() == 0) return Standard_True;
563     }
564   }
565   return Standard_False;
566 }