Salome HOME
5accfa17a46aaf9bf1d5647888123a6e4759a561
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_GetInPlace.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:     GEOMAlgo_GetInPlace.cxx
23 // Created:
24 // Author:   Peter KURNEV
25
26 #include <GEOMAlgo_GetInPlace.hxx>
27
28
29 #include <NCollection_UBTreeFiller.hxx>
30
31 #include <Bnd_Box.hxx>
32 #include <gp_Pnt.hxx>
33
34 #include <TColStd_ListOfInteger.hxx>
35 #include <TColStd_ListIteratorOfListOfInteger.hxx>
36
37 #include <TopAbs_ShapeEnum.hxx>
38
39 #include <TopoDS_Iterator.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Compound.hxx>
45
46 #include <BRep_Tool.hxx>
47 #include <BRep_Builder.hxx>
48
49 #include <BRepBndLib.hxx>
50
51 #include <TopExp.hxx>
52
53 #include <TopTools_IndexedMapOfShape.hxx>
54 #include <TopTools_ListOfShape.hxx>
55 #include <TopTools_DataMapOfShapeListOfShape.hxx>
56 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
57 #include <TopTools_ListIteratorOfListOfShape.hxx>
58 #include <TopTools_MapOfShape.hxx>
59 #include <TopTools_MapIteratorOfMapOfShape.hxx>
60
61 #include <GEOMAlgo_BoxBndTree.hxx>
62 #include <GEOMAlgo_CoupleOfShapes.hxx>
63
64
65 static
66   void MapBRepShapes(const TopoDS_Shape& aS,
67                      TopTools_IndexedMapOfShape& aM);
68
69
70 //=======================================================================
71 //function : GEOMAlgo_GetInPlace
72 //purpose  :
73 //=======================================================================
74 GEOMAlgo_GetInPlace::GEOMAlgo_GetInPlace()
75 :
76   GEOMAlgo_GluerAlgo(),
77   GEOMAlgo_Algo()
78 {
79   myTolerance=0.0001;
80   myTolMass=0.0001;
81   myTolCG=0.0001;
82   myFound=Standard_False;
83   myCheckGeometry=Standard_True;
84 }
85 //=======================================================================
86 //function : ~
87 //purpose  :
88 //=======================================================================
89 GEOMAlgo_GetInPlace::~GEOMAlgo_GetInPlace()
90 {
91 }
92 //=======================================================================
93 //function : SetTolMass
94 //purpose  :
95 //=======================================================================
96 void GEOMAlgo_GetInPlace::SetTolMass(const Standard_Real theTol)
97 {
98   myTolMass=theTol;
99 }
100 //=======================================================================
101 //function : TolMass
102 //purpose  :
103 //=======================================================================
104 Standard_Real GEOMAlgo_GetInPlace::TolMass()const
105 {
106   return myTolMass;
107 }
108 //=======================================================================
109 //function : SetTolCG
110 //purpose  :
111 //=======================================================================
112 void GEOMAlgo_GetInPlace::SetTolCG(const Standard_Real theTol)
113 {
114   myTolCG=theTol;
115 }
116 //=======================================================================
117 //function : TolCG
118 //purpose  :
119 //=======================================================================
120 Standard_Real GEOMAlgo_GetInPlace::TolCG()const
121 {
122   return myTolCG;
123 }
124 //=======================================================================
125 //function : IsFound
126 //purpose  :
127 //=======================================================================
128 Standard_Boolean GEOMAlgo_GetInPlace::IsFound()const
129 {
130   return myFound;
131 }
132 //=======================================================================
133 //function : SetShapeWhere
134 //purpose  :
135 //=======================================================================
136 void GEOMAlgo_GetInPlace::SetShapeWhere(const TopoDS_Shape& theShape)
137 {
138   myShapeWhere=theShape;
139 }
140 //=======================================================================
141 //function : ShapeWhere
142 //purpose  :
143 //=======================================================================
144 const TopoDS_Shape& GEOMAlgo_GetInPlace::ShapeWhere()const
145 {
146   return myShapeWhere;
147 }
148 //=======================================================================
149 //function : ShapesIn
150 //purpose  :
151 //=======================================================================
152 const GEOMAlgo_DataMapOfShapeMapOfShape& GEOMAlgo_GetInPlace::ShapesIn()const
153 {
154   return myShapesIn;
155 }
156 //=======================================================================
157 //function : ShapesOn
158 //purpose  :
159 //=======================================================================
160 const GEOMAlgo_DataMapOfShapeMapOfShape& GEOMAlgo_GetInPlace::ShapesOn()const
161 {
162   return myShapesOn;
163 }
164 //=======================================================================
165 //function : Clear
166 //purpose  :
167 //=======================================================================
168 void GEOMAlgo_GetInPlace::Clear()
169 {
170   TopoDS_Shape aS;
171   //
172   myErrorStatus=0;
173   myWarningStatus=0;
174   //
175   GEOMAlgo_GluerAlgo::Clear();
176   myIterator.Clear();
177   myShapesIn.Clear();
178   myShapesOn.Clear();
179   myShapesInclusive.Clear();
180   myMapShapePnt.Clear();
181   myChecked.Clear();
182   myResult= aS;
183 }
184 //=======================================================================
185 //function : Perform
186 //purpose  :
187 //=======================================================================
188 void GEOMAlgo_GetInPlace::Perform()
189 {
190   myFound=Standard_False;
191   myErrorStatus=0;
192   myWarningStatus=0;
193   //
194   Clear();
195   if (myErrorStatus) {
196     return;
197   }
198   //
199   CheckData();
200   if (myErrorStatus) {
201     return;
202   }
203   //
204   // Initialize the context
205   GEOMAlgo_GluerAlgo::Perform();
206   //
207   Intersect();
208   if (myErrorStatus) {
209     return;
210   }
211   //
212   PerformVV();
213   if (myErrorStatus) {
214     return;
215   }
216   //
217   FillEdgesOn(myArgument);
218   FillEdgesOn(myShapeWhere);
219   if (myErrorStatus) {
220     return;
221   }
222   //
223   PerformVE();
224   if (myErrorStatus) {
225     return;
226   }
227   //
228   PerformEE();
229   if (myErrorStatus) {
230     return;
231   }
232   //
233   PerformVF();
234   if (myErrorStatus) {
235     return;
236   }
237   //
238   FillFacesOn(myArgument);
239   FillFacesOn(myShapeWhere);
240   if (myErrorStatus) {
241     return;
242   }
243   //
244   PerformEF();
245   if (myErrorStatus) {
246     return;
247   }
248   //
249   PerformFF();
250   if (myErrorStatus) {
251     return;
252   }
253   //
254   FillSolidsOn(myArgument);
255   FillSolidsOn(myShapeWhere);
256   if (myErrorStatus) {
257     return;
258   }
259   //
260   PerformZF();
261   if (myErrorStatus) {
262     return;
263   }
264   //
265   PerformZZ();
266   if (myErrorStatus) {
267     return;
268   }
269   //
270   myImages.Clear();
271   FillImages(myShapeWhere, Standard_True);
272   FillImages(myArgument, Standard_False);
273
274   if (myErrorStatus) {
275     return;
276   }
277   //
278   CheckGProps();
279   if (myErrorStatus) {
280     return;
281   }
282 }
283 //=======================================================================
284 //function : CheckData
285 //purpose  :
286 //=======================================================================
287 void GEOMAlgo_GetInPlace::CheckData()
288 {
289   myErrorStatus=0;
290   myWarningStatus=0;
291   //
292   if (myArgument.IsNull()) {
293     myErrorStatus=2;
294     return;
295   }
296   //
297   if (myShapeWhere.IsNull()) {
298     myErrorStatus=3;
299     return;
300   }
301 }
302 //=======================================================================
303 //function : Intersect
304 //purpose  :
305 //=======================================================================
306 void GEOMAlgo_GetInPlace::Intersect()
307 {
308   Standard_Integer i, j, aNbS1, aNbS2, aNbSD;
309   TColStd_ListIteratorOfListOfInteger aItLI;
310   TopTools_IndexedMapOfShape aMS1, aMS2;
311   TopTools_DataMapOfShapeListOfShape aDMSLS;
312   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
313   TopTools_ListIteratorOfListOfShape aItLS;
314   GEOMAlgo_CoupleOfShapes aCS;
315   //
316   GEOMAlgo_BoxBndTreeSelector aSelector;
317   GEOMAlgo_BoxBndTree aBBTree;
318   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
319   //
320   myErrorStatus=0;
321   myWarningStatus=0;
322   //
323   myIterator.Clear();
324   //
325   MapBRepShapes(myArgument, aMS1);
326   aNbS1=aMS1.Extent();
327   for (i=1; i<=aNbS1; ++i) {
328     Bnd_Box aBox1;
329     //
330     const TopoDS_Shape& aS1=aMS1(i);
331     BRepBndLib::Add(aS1, aBox1);
332     aBox1.Enlarge(myTolerance);
333     //
334     aTreeFiller.Add(i, aBox1);
335   }
336   //
337   aTreeFiller.Fill();
338   //
339   MapBRepShapes(myShapeWhere, aMS2);
340   aNbS2=aMS2.Extent();
341   for (j=1; j<=aNbS2; ++j) {
342     Bnd_Box aBox2;
343     //
344     const TopoDS_Shape& aS2=aMS2(j);
345     BRepBndLib::Add(aS2, aBox2);
346     aBox2.Enlarge(myTolerance);
347     //
348     aSelector.Clear();
349     aSelector.SetBox(aBox2);
350     aNbSD=aBBTree.Select(aSelector);
351     if (!aNbSD) {
352       continue;  // it should not be
353     }
354     //
355     const TColStd_ListOfInteger& aLI=aSelector.Indices();
356     aItLI.Initialize(aLI);
357     for (; aItLI.More(); aItLI.Next()) {
358       i=aItLI.Value();
359       const TopoDS_Shape& aS1=aMS1(i);
360       //
361       if (aDMSLS.IsBound(aS1)) {
362         TopTools_ListOfShape& aLS=aDMSLS.ChangeFind(aS1);
363         aLS.Append(aS2);
364       }
365       else {
366         TopTools_ListOfShape aLS;
367         //
368         aLS.Append(aS2);
369         aDMSLS.Bind(aS1, aLS);
370       }
371     }
372   }// for (j=1; j<=aNbS2; ++j) {
373   //
374   aItDMSLS.Initialize(aDMSLS);
375   for (; aItDMSLS.More(); aItDMSLS.Next()) {
376     const TopoDS_Shape& aS1=aItDMSLS.Key();
377     const TopTools_ListOfShape& aLS2=aItDMSLS.Value();
378     aCS.SetShape1(aS1);
379     aItLS.Initialize(aLS2);
380     for (; aItLS.More(); aItLS.Next()) {
381       const TopoDS_Shape& aS2=aItLS.Value();
382       aCS.SetShape2(aS2);
383       myIterator.AppendPair(aCS);
384     }
385   }
386 }
387 //=======================================================================
388 //function : PerformVV
389 //purpose  :
390 //=======================================================================
391 void GEOMAlgo_GetInPlace::PerformVV()
392 {
393   myErrorStatus=0;
394   myWarningStatus=0;
395   //
396   myIterator.Initialize(TopAbs_VERTEX, TopAbs_VERTEX);
397   for (; myIterator.More(); myIterator.Next()) {
398     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
399     const TopoDS_Shape& aV1=aCS.Shape1();
400     const TopoDS_Shape& aV2=aCS.Shape2();
401     //
402     FillShapesOn(aV1, aV2);
403     FillShapesOn(aV2, aV1);
404   }
405 }
406 //=======================================================================
407 //function : FillEdgesOn
408 //purpose  :
409 //=======================================================================
410 void GEOMAlgo_GetInPlace::FillEdgesOn(const TopoDS_Shape &theShape)
411 {
412   Standard_Integer i, aNbE;
413   TopoDS_Iterator aIt;
414   TopTools_IndexedMapOfShape aME;
415   TopTools_MapIteratorOfMapOfShape aItMS;
416   //
417   TopExp::MapShapes(theShape, TopAbs_EDGE, aME);
418   aNbE=aME.Extent();
419   for (i=1; i<=aNbE; ++i) {
420     const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aME(i));
421     if (BRep_Tool::Degenerated(aE1)) {
422       continue;
423     }
424     //
425     aIt.Initialize(aE1);
426     for (; aIt.More(); aIt.Next()) {
427       const TopoDS_Shape& aV1=aIt.Value();
428       if (myShapesOn.IsBound(aV1)) {
429         const TopTools_MapOfShape& aMSOn=myShapesOn.Find(aV1);
430         //aNbSOn=aMSOn.Extent();
431         aItMS.Initialize(aMSOn);
432         for (; aItMS.More(); aItMS.Next()) {
433           const TopoDS_Shape& aV2=aItMS.Key();
434           FillShapesOn(aE1, aV2);
435         }
436       }
437     }
438   }
439 }
440 //=======================================================================
441 //function : PerformVE
442 //purpose  :
443 //=======================================================================
444 void GEOMAlgo_GetInPlace::PerformVE()
445 {
446   Standard_Boolean bFound;
447   //
448   myErrorStatus=0;
449   myWarningStatus=0;
450   //
451   // 2. Fill Shapes In
452   myIterator.Initialize(TopAbs_EDGE, TopAbs_VERTEX);
453   for (; myIterator.More(); myIterator.Next()) {
454     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
455     const TopoDS_Shape& aE1=aCS.Shape1();
456     const TopoDS_Shape& aV2=aCS.Shape2();
457     //
458     if (myShapesOn.IsBound(aE1)) {
459       const TopTools_MapOfShape& aMSOn=myShapesOn.Find(aE1);
460       if (aMSOn.Contains(aV2)) {
461         continue;
462       }
463     }
464     //
465     bFound=CheckCoincidence(aE1, aV2);
466     if (myErrorStatus) {
467       return;
468     }
469     if (bFound) {
470       FillShapesIn(aE1, aV2);
471     }
472   }
473 }
474 //=======================================================================
475 //function : PerformEE
476 //purpose  :
477 //=======================================================================
478 void GEOMAlgo_GetInPlace::PerformEE()
479 {
480   myErrorStatus=0;
481   myWarningStatus=0;
482   //
483   myIterator.Initialize(TopAbs_EDGE, TopAbs_EDGE);
484   for (; myIterator.More(); myIterator.Next()) {
485     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
486     const TopoDS_Shape& aE1=aCS.Shape1();
487     const TopoDS_Shape& aE2=aCS.Shape2();
488
489     PerformEE(aE1, aE2);
490
491     if (myErrorStatus) {
492       return;
493     }
494
495     PerformEE(aE2, aE1);
496
497     if (myErrorStatus) {
498       return;
499     }
500   }
501 }
502 //=======================================================================
503 //function : PerformEE
504 //purpose  :
505 //=======================================================================
506 void GEOMAlgo_GetInPlace::PerformEE(const TopoDS_Shape &theE1,
507                                     const TopoDS_Shape &theE2)
508 {
509   Standard_Boolean bHasOn, bHasIn, bFound;
510   TopoDS_Iterator aIt;
511   TopTools_MapOfShape aMSX;
512   //
513   bHasOn=myShapesOn.IsBound(theE1);
514   bHasIn=myShapesIn.IsBound(theE1);
515   const TopTools_MapOfShape& aMSOn=(bHasOn) ? myShapesOn.Find(theE1) : aMSX;
516   const TopTools_MapOfShape& aMSIn=(bHasIn) ? myShapesIn.Find(theE1) : aMSX;
517   //
518   bFound=Standard_True;
519   aIt.Initialize(theE2);
520   for (; aIt.More(); aIt.Next()) {
521     const TopoDS_Shape& aV2=aIt.Value();
522     if (!(aMSOn.Contains(aV2) || aMSIn.Contains(aV2))) {
523       bFound=!bFound;
524       break;
525     }
526   }
527   if (!bFound) {
528     return;
529   }
530   //
531   bFound=CheckCoincidence(theE1, theE2);
532   if (myErrorStatus) {
533     return;
534   }
535   if (bFound) {
536     FillShapesIn(theE1, theE2);
537   }
538 }
539 //=======================================================================
540 //function : PerformVF
541 //purpose  :
542 //=======================================================================
543 void GEOMAlgo_GetInPlace::PerformVF()
544 {
545   Standard_Boolean bHasOn, bHasIn, bFound;
546   Standard_Integer i, aNbE;
547   TopTools_MapOfShape aMSX;
548   TopTools_IndexedMapOfShape aME;
549   //
550   myErrorStatus=0;
551   myWarningStatus=0;
552   //
553   myIterator.Initialize(TopAbs_FACE, TopAbs_VERTEX);
554   for (; myIterator.More(); myIterator.Next()) {
555     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
556     const TopoDS_Shape& aF1=aCS.Shape1();
557     const TopoDS_Shape& aV2=aCS.Shape2();
558     //
559     aME.Clear();
560     TopExp::MapShapes(aF1, TopAbs_EDGE, aME);
561     //
562     bFound=Standard_False;
563     aNbE=aME.Extent();
564     for (i=1; i<=aNbE; ++i) {
565       const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aME(i));
566       if (BRep_Tool::Degenerated(aE1)) {
567         continue;
568       }
569       //
570       bHasOn=myShapesOn.IsBound(aE1);
571       bHasIn=myShapesIn.IsBound(aE1);
572       const TopTools_MapOfShape& aMSOn=(bHasOn) ? myShapesOn.Find(aE1) : aMSX;
573       const TopTools_MapOfShape& aMSIn=(bHasIn) ? myShapesIn.Find(aE1) : aMSX;
574       bFound= (aMSOn.Contains(aV2) || aMSIn.Contains(aV2));
575       if (bFound) {
576         break;
577       }
578     }
579     //
580     if (bFound) {
581       continue;
582     }
583     //
584     bFound=CheckCoincidence(aF1, aV2);
585     if (myErrorStatus) {
586       return;
587     }
588     if (bFound) {
589       FillShapesIn(aF1, aV2);
590     }
591   }
592 }
593 //=======================================================================
594 //function : FillFacesOn
595 //purpose  :
596 //=======================================================================
597 void GEOMAlgo_GetInPlace::FillFacesOn(const TopoDS_Shape &theShape)
598 {
599   Standard_Integer i, j, aNbF, aNbE;
600   TopoDS_Iterator aIt;
601   TopTools_IndexedMapOfShape aMF, aME;
602   TopTools_MapIteratorOfMapOfShape aItMS;
603   //
604   TopExp::MapShapes(theShape, TopAbs_FACE, aMF);
605   aNbF=aMF.Extent();
606   for (i=1; i<=aNbF; ++i) {
607     const TopoDS_Face& aF1=*((TopoDS_Face*)&aMF(i));
608     //
609     aME.Clear();
610     TopExp::MapShapes(aF1, TopAbs_EDGE, aME);
611     aNbE=aME.Extent();
612     for (j=1; j<=aNbE; ++j) {
613       const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aME(j));
614       if (BRep_Tool::Degenerated(aE1)) {
615         continue;
616       }
617       //
618       if (myShapesOn.IsBound(aE1)) {
619         const TopTools_MapOfShape& aMSOn=myShapesOn.Find(aE1);
620         aItMS.Initialize(aMSOn);
621         for (; aItMS.More(); aItMS.Next()) {
622           const TopoDS_Shape& aS2=aItMS.Key();
623           FillShapesOn(aF1, aS2);
624         }
625       }
626       //
627       if (myShapesIn.IsBound(aE1)) {
628         const TopTools_MapOfShape& aMSIn=myShapesIn.Find(aE1);
629         aItMS.Initialize(aMSIn);
630         for (; aItMS.More(); aItMS.Next()) {
631           const TopoDS_Shape& aS2=aItMS.Key();
632           FillShapesOn(aF1, aS2);
633         }
634       }
635     }//for (j=1; j<=aNbE; ++j) {
636   }//for (i=1; i<=aNbF; ++i) {
637 }
638 //=======================================================================
639 //function : PerformEF
640 //purpose  :
641 //=======================================================================
642 void GEOMAlgo_GetInPlace::PerformEF()
643 {
644   Standard_Boolean  bFound, bHasOnF, bHasInF;
645   TopoDS_Iterator aIt;
646   TopTools_MapOfShape aMSX;
647   //
648   myErrorStatus=0;
649   myWarningStatus=0;
650   //
651   myIterator.Initialize(TopAbs_FACE, TopAbs_EDGE);
652   for (; myIterator.More(); myIterator.Next()) {
653     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
654     const TopoDS_Shape& aF1=aCS.Shape1();
655     const TopoDS_Shape& aE2=aCS.Shape2();
656     //
657     // 1.
658     bHasOnF=myShapesOn.IsBound(aF1);
659     const TopTools_MapOfShape& aMSOnF=(bHasOnF) ? myShapesOn.Find(aF1) : aMSX;
660     bFound=aMSOnF.Contains(aE2);
661     if (bFound) {
662       continue;
663     }
664     //
665     // 2.
666     bHasInF=myShapesIn.IsBound(aF1);
667     const TopTools_MapOfShape& aMSInF=(bHasInF) ? myShapesIn.Find(aF1) : aMSX;
668     //
669     aIt.Initialize(aE2);
670     for (; aIt.More(); aIt.Next()) {
671       const TopoDS_Shape& aV2=aIt.Value();
672       bFound=(aMSOnF.Contains(aV2) || aMSInF.Contains(aV2));
673       if (!bFound) {
674         break;
675       }
676     }
677     if (!bFound) {
678       continue;
679     }
680     //------------------------------
681     bFound=CheckCoincidence(aF1, aE2);
682     if (myErrorStatus) {
683       return;
684     }
685     if (bFound) {
686       FillShapesIn(aF1, aE2);
687     }
688   }
689 }
690 //=======================================================================
691 //function : PerformFF
692 //purpose  :
693 //=======================================================================
694 void GEOMAlgo_GetInPlace::PerformFF()
695 {
696   myErrorStatus=0;
697   myWarningStatus=0;
698   //
699   myIterator.Initialize(TopAbs_FACE, TopAbs_FACE);
700   for (; myIterator.More(); myIterator.Next()) {
701     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
702     const TopoDS_Shape& aF1=aCS.Shape1();
703     const TopoDS_Shape& aF2=aCS.Shape2();
704
705     PerformFF(aF1, aF2);
706
707     if (myErrorStatus) {
708       return;
709     }
710
711     PerformFF(aF2, aF1);
712
713     if (myErrorStatus) {
714       return;
715     }
716   }
717 }
718 //=======================================================================
719 //function : PerformFF
720 //purpose  :
721 //=======================================================================
722 void GEOMAlgo_GetInPlace::PerformFF(const TopoDS_Shape &theF1,
723                                     const TopoDS_Shape &theF2)
724 {
725   Standard_Boolean  bFound, bHasOnF, bHasInF;
726   Standard_Integer i, aNbS2;
727   TopTools_MapOfShape aMSX;
728   TopTools_IndexedMapOfShape aMS2;
729   //
730   bHasOnF=myShapesOn.IsBound(theF1);
731   const TopTools_MapOfShape& aMSOnF=(bHasOnF) ? myShapesOn.Find(theF1) : aMSX;
732   //
733   bHasInF=myShapesIn.IsBound(theF1);
734   const TopTools_MapOfShape& aMSInF=(bHasInF) ? myShapesIn.Find(theF1) : aMSX;
735   //
736   MapBRepShapes(theF2, aMS2);
737   //
738   bFound=Standard_False;
739   aNbS2=aMS2.Extent();
740   for (i=1; i<=aNbS2; ++i) {
741     const TopoDS_Shape& aS2=aMS2(i);
742     if (aS2.IsSame(theF2)) {
743       continue;
744     }
745     bFound=(aMSOnF.Contains(aS2) || aMSInF.Contains(aS2));
746     if (!bFound) {
747       break;
748     }
749   }
750   if (!bFound) {
751     return;
752   }
753   //
754   bFound=CheckCoincidence(theF1, theF2);
755   if (myErrorStatus) {
756     return;
757   }
758   if (bFound) {
759     FillShapesIn(theF1, theF2);
760   }
761 }
762 //=======================================================================
763 //function : FillSolidsOn
764 //purpose  :
765 //=======================================================================
766 void GEOMAlgo_GetInPlace::FillSolidsOn(const TopoDS_Shape &theShape)
767 {
768   Standard_Integer i, j, aNbS, aNbF;
769   TopTools_IndexedMapOfShape aMS, aMF;
770   TopTools_MapIteratorOfMapOfShape aItMS;
771   //
772   TopExp::MapShapes(theShape, TopAbs_SOLID, aMS);
773   //
774   aNbS=aMS.Extent();
775   for (i=1; i<=aNbS; ++i) {
776     const TopoDS_Shape& aSD1=aMS(i);
777     //
778     aMF.Clear();
779     TopExp::MapShapes(aSD1, TopAbs_FACE, aMF);
780     aNbF=aMF.Extent();
781     for (j=1; j<=aNbF; ++j) {
782       const TopoDS_Shape& aF1=aMF(j);
783       //
784       if (myShapesOn.IsBound(aF1)) {
785         const TopTools_MapOfShape& aMSOn=myShapesOn.Find(aF1);
786         aItMS.Initialize(aMSOn);
787         for (; aItMS.More(); aItMS.Next()) {
788           const TopoDS_Shape& aS2=aItMS.Key();
789           FillShapesOn(aSD1, aS2);
790         }
791       }
792       //
793       if (myShapesIn.IsBound(aF1)) {
794         const TopTools_MapOfShape& aMSIn=myShapesIn.Find(aF1);
795         aItMS.Initialize(aMSIn);
796         for (; aItMS.More(); aItMS.Next()) {
797           const TopoDS_Shape& aS2=aItMS.Key();
798           FillShapesOn(aSD1, aS2);
799         }
800       }
801     }//for (j=1; j<=aNbF; ++j) {
802   }//for (i=1; i<=aNbS; ++i) {
803 }
804 //=======================================================================
805 //function : PerformZF
806 //purpose  :
807 //=======================================================================
808 void GEOMAlgo_GetInPlace::PerformZF()
809 {
810   Standard_Boolean  bFound, bHasOnF;
811   TopTools_MapOfShape aMSX;
812   //
813   myErrorStatus=0;
814   myWarningStatus=0;
815   //
816   myIterator.Initialize(TopAbs_SOLID, TopAbs_FACE);
817   for (; myIterator.More(); myIterator.Next()) {
818     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
819     const TopoDS_Shape& aSo1=aCS.Shape1();
820     const TopoDS_Shape& aF2=aCS.Shape2();
821     //
822     bHasOnF=myShapesOn.IsBound(aSo1);
823     const TopTools_MapOfShape& aMSOnF=(bHasOnF) ? myShapesOn.Find(aSo1) : aMSX;
824     bFound=aMSOnF.Contains(aF2);
825     if (bFound) {
826       continue;
827     }
828     //------------------------------
829     bFound=CheckCoincidence(aSo1, aF2);
830     if (myErrorStatus) {
831       return;
832     }
833     if (bFound) {
834       FillShapesIn(aSo1, aF2);
835     }
836   }
837 }
838 //=======================================================================
839 //function : PerformZZ
840 //purpose  :
841 //=======================================================================
842 void GEOMAlgo_GetInPlace::PerformZZ()
843 {
844   myErrorStatus=0;
845   myWarningStatus=0;
846   //
847   myIterator.Initialize(TopAbs_SOLID, TopAbs_SOLID);
848   for (; myIterator.More(); myIterator.Next()) {
849     const GEOMAlgo_CoupleOfShapes& aCS=myIterator.Value();
850     const TopoDS_Shape& aSo1=aCS.Shape1();
851     const TopoDS_Shape& aSo2=aCS.Shape2();
852
853     PerformZZ(aSo1, aSo2);
854
855     if (myErrorStatus) {
856       return;
857     }
858
859     PerformZZ(aSo2, aSo1);
860
861     if (myErrorStatus) {
862       return;
863     }
864   }// for (; myIterator.More(); myIterator.Next()) {
865 }
866 //=======================================================================
867 //function : PerformZZ
868 //purpose  :
869 //=======================================================================
870 void GEOMAlgo_GetInPlace::PerformZZ(const TopoDS_Shape &theSo1,
871                                     const TopoDS_Shape &theSo2)
872 {
873   Standard_Boolean bFound, bHasOn, bHasIn;
874   Standard_Integer i, aNbS2, iCntOn, iCntIn, iCntOut;
875   TopTools_MapOfShape aMSX;
876   TopTools_IndexedMapOfShape aMS2;
877   //
878   bHasOn=myShapesOn.IsBound(theSo1);
879   const TopTools_MapOfShape& aMSOn=(bHasOn) ? myShapesOn.Find(theSo1) : aMSX;
880   //
881   bHasIn=myShapesIn.IsBound(theSo1);
882   const TopTools_MapOfShape& aMSIn=(bHasIn) ? myShapesIn.Find(theSo1) : aMSX;
883   //
884   TopExp::MapShapes(theSo2, TopAbs_FACE, aMS2);
885   //
886   iCntIn=0;
887   iCntOn=0;
888   iCntOut=0;
889   bFound=Standard_False;
890   aNbS2=aMS2.Extent();
891   for (i=1; i<=aNbS2; ++i) {
892     const TopoDS_Shape& aF2=aMS2(i);
893     //
894     if (aMSIn.Contains(aF2)) {
895       ++iCntIn;
896       bFound=Standard_True;
897       break;
898     }
899     else if (!aMSOn.Contains(aF2)) {
900       ++iCntOut;
901       bFound=Standard_False;// out
902       break;
903     }
904     else {
905       ++iCntOn; //on
906     }
907   }
908   //
909   if (!bFound && iCntOut) {
910     return;
911   }
912   //
913   if (!iCntIn) {
914     bFound=CheckCoincidence(theSo1, theSo2);
915     if (myErrorStatus) {
916       return;
917     }
918   }
919   if (bFound) {
920     FillShapesIn(theSo1, theSo2);
921   }
922 }
923 //=======================================================================
924 //function : FillImages
925 //purpose  :
926 //=======================================================================
927 void GEOMAlgo_GetInPlace::FillImages(const TopoDS_Shape &theShape,
928                                      const Standard_Boolean IsWhere)
929 {
930   //
931   myErrorStatus=0;
932   myWarningStatus=0;
933   //
934   // 1. Vertices
935   FillImgSimple(theShape, TopAbs_VERTEX, IsWhere);
936   //
937   // 2. Edges
938   FillImgSimple(theShape, TopAbs_EDGE, IsWhere);
939   //
940   // 3. Wires
941   FillImgComplex(theShape, TopAbs_WIRE, IsWhere);
942   //
943   // 4. Faces
944   FillImgSimple(theShape, TopAbs_FACE, IsWhere);
945   //
946   // 5. Shells
947   FillImgComplex(theShape, TopAbs_SHELL, IsWhere);
948   //
949   // 6. Solids
950   FillImgSimple(theShape, TopAbs_SOLID, IsWhere);
951   //
952   // 7. CompSolids
953   FillImgComplex(theShape, TopAbs_COMPSOLID, IsWhere);
954   //
955   // 8. Compounds
956   const TopAbs_ShapeEnum aType = theShape.ShapeType();
957
958   if (aType == TopAbs_COMPOUND) {
959     FillImgComplex(theShape, IsWhere);
960   }
961 }
962
963 //=======================================================================
964 //function : FillImgSimple
965 //purpose  :
966 //=======================================================================
967 void GEOMAlgo_GetInPlace::FillImgSimple
968                       (const TopoDS_Shape     &theShape,
969                        const TopAbs_ShapeEnum  theSubShapeType,
970                        const Standard_Boolean  IsWhere)
971 {
972   TopTools_IndexedMapOfShape aMS;
973
974   TopExp::MapShapes(theShape, theSubShapeType, aMS);
975
976   Standard_Integer i;
977   const Standard_Integer aNbS = aMS.Extent();
978   const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesInOn =
979     (theSubShapeType == TopAbs_VERTEX ? myShapesOn : myShapesIn);
980
981   for (i = 1; i <= aNbS; i++) {
982     const TopoDS_Shape& aS = aMS(i);
983
984     if (aShapesInOn.IsBound(aS)) {
985       const TopTools_MapOfShape& aMSx = aShapesInOn.Find(aS);
986       TopTools_ListOfShape aLSx;
987       TopTools_MapIteratorOfMapOfShape aItMS(aMSx);
988
989       for (; aItMS.More(); aItMS.Next()) {
990         const TopoDS_Shape& aSx = aItMS.Key();
991         TopAbs_ShapeEnum aType = aSx.ShapeType();
992
993         if (aType == theSubShapeType){
994           aLSx.Append(aSx);
995
996           if (IsWhere) {
997             myShapesInclusive.Bind(aSx, aS);
998           }
999         }
1000       }
1001
1002       myImages.Bind(aS, aLSx);
1003     }
1004   }
1005 }
1006
1007 //=======================================================================
1008 //function : FillImgComplex
1009 //purpose  :
1010 //=======================================================================
1011 void GEOMAlgo_GetInPlace::FillImgComplex(const TopoDS_Shape     &theShape,
1012                                          const Standard_Boolean  IsWhere)
1013 {
1014   TopTools_MapOfShape  aMapRemaining;
1015   TopoDS_Iterator      aIt(theShape);
1016   TopTools_ListOfShape aLSx;
1017   TopTools_MapOfShape  aMSx;
1018
1019   for(; aIt.More(); aIt.Next()) {
1020     const TopoDS_Shape &aSubS = aIt.Value();
1021     TopAbs_ShapeEnum    aType = aSubS.ShapeType();
1022
1023     if (aType == TopAbs_COMPOUND) {
1024       // Recursively treat compounds.
1025       FillImgComplex(aSubS, IsWhere);
1026     }
1027
1028     if (myImages.IsBound(aSubS)) {
1029       const TopTools_ListOfShape& aLSi = myImages.Find(aSubS);
1030       TopTools_ListIteratorOfListOfShape aItLS(aLSi);
1031
1032       for (; aItLS.More(); aItLS.Next()) {
1033         const TopoDS_Shape &aSubSi = aItLS.Value();
1034
1035         if (aMSx.Add(aSubSi)) {
1036           aLSx.Append(aSubSi);
1037         }
1038       }
1039     } else if (!IsWhere) {
1040       aMapRemaining.Add(aSubS);
1041     }
1042   }
1043
1044   if (!(IsWhere || aMapRemaining.IsEmpty())) {
1045     // Find the whole from parts.
1046     while (!aMapRemaining.IsEmpty()) {
1047       TopTools_MapIteratorOfMapOfShape anIter(aMapRemaining);
1048       const TopoDS_Shape &aShape = anIter.Key();
1049
1050       if (myShapesInclusive.IsBound(aShape)) {
1051         // This "what" shape is inclusive to the "where" shape.
1052         // Get the other inclusive shapes.
1053         const TopoDS_Shape &aSWhere = myShapesInclusive.Find(aShape);
1054
1055         if (myImages.IsBound(aSWhere)) {
1056           // Remove inclusive shapes from aMapRemaining.
1057           const TopTools_ListOfShape& aLWhat = myImages.Find(aSWhere);
1058           TopTools_ListIteratorOfListOfShape aItLS(aLWhat);
1059
1060           for (; aItLS.More(); aItLS.Next()) {
1061             const TopoDS_Shape &aSWhat = aItLS.Value();
1062
1063             aMapRemaining.Remove(aSWhat);
1064           }
1065
1066           // Add "whole" shape to the list of images.
1067           if (aMSx.Add(aSWhere)) {
1068             aLSx.Append(aSWhere);
1069           }
1070         }
1071       } else {
1072         // This "what" shape is not inclusive to the "where" shape. Skip it.
1073         aMapRemaining.Remove(aShape);
1074       }
1075     }
1076   }
1077
1078   myImages.Bind(theShape, aLSx);
1079 }
1080
1081 //=======================================================================
1082 //function : FillImgComplex
1083 //purpose  :
1084 //=======================================================================
1085 void GEOMAlgo_GetInPlace::FillImgComplex
1086                            (const TopoDS_Shape     &theShape,
1087                             const TopAbs_ShapeEnum  theSubShapeType,
1088                             const Standard_Boolean  IsWhere)
1089 {
1090   TopTools_IndexedMapOfShape aMS;
1091
1092   TopExp::MapShapes(theShape, theSubShapeType, aMS);
1093
1094   Standard_Integer i;
1095   const Standard_Integer aNbS = aMS.Extent();
1096
1097   for (i=1; i<=aNbS; ++i) {
1098     const TopoDS_Shape &aS = aMS(i);
1099
1100     FillImgComplex(aS, IsWhere);
1101   }
1102 }
1103
1104 //=======================================================================
1105 //function : FillShapesIn
1106 //purpose  :
1107 //=======================================================================
1108 void GEOMAlgo_GetInPlace::FillShapesIn(const TopoDS_Shape& aS1,
1109                                        const TopoDS_Shape& aS2)
1110 {
1111   if (myShapesIn.IsBound(aS1)) {
1112     TopTools_MapOfShape& aMS=myShapesIn.ChangeFind(aS1);
1113     aMS.Add(aS2);
1114   }
1115   else {
1116     TopTools_MapOfShape aMS;
1117     //
1118     aMS.Add(aS2);
1119     myShapesIn.Bind(aS1, aMS);
1120   }
1121 }
1122 //=======================================================================
1123 //function : FillShapesOn
1124 //purpose  :
1125 //=======================================================================
1126 void GEOMAlgo_GetInPlace::FillShapesOn(const TopoDS_Shape& aS1,
1127                                        const TopoDS_Shape& aS2)
1128 {
1129   if (myShapesOn.IsBound(aS1)) {
1130     TopTools_MapOfShape& aMS=myShapesOn.ChangeFind(aS1);
1131     aMS.Add(aS2);
1132   }
1133   else {
1134     TopTools_MapOfShape aMS;
1135     //
1136     aMS.Add(aS2);
1137     myShapesOn.Bind(aS1, aMS);
1138   }
1139 }
1140
1141 //=======================================================================
1142 //function : MapBRepShapes
1143 //purpose  :
1144 //=======================================================================
1145 void MapBRepShapes(const TopoDS_Shape& aS,
1146                    TopTools_IndexedMapOfShape& aM)
1147 {
1148   Standard_Boolean bDegenerated;
1149   TopAbs_ShapeEnum aType;
1150   TopoDS_Iterator aIt;
1151   //
1152   aType=aS.ShapeType();
1153   if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE ||
1154       aType==TopAbs_FACE   || aType==TopAbs_SOLID) {
1155     bDegenerated=Standard_False;
1156     if (aType==TopAbs_EDGE) {
1157       TopoDS_Edge *pE=(TopoDS_Edge*)&aS;
1158       bDegenerated=BRep_Tool::Degenerated(*pE);
1159     }
1160     if (!bDegenerated) {
1161       aM.Add(aS);
1162     }
1163   }
1164   //
1165   aIt.Initialize(aS);
1166   for(; aIt.More(); aIt.Next()) {
1167     const TopoDS_Shape& aSx=aIt.Value();
1168     aType=aSx.ShapeType();
1169     MapBRepShapes(aSx, aM);
1170   }
1171 }
1172 //=======================================================================
1173 //function : Result
1174 //purpose  : 
1175 //=======================================================================
1176 const TopoDS_Shape &GEOMAlgo_GetInPlace::Result()
1177 {
1178   TopoDS_Shape aDummy;
1179   //
1180   myResult = aDummy;
1181   //
1182   Standard_Boolean bFound;
1183   TopoDS_Compound aC;
1184   BRep_Builder aBB;
1185   TopTools_ListIteratorOfListOfShape aItLS;
1186   //
1187   bFound=myImages.IsBound(myArgument);
1188   if (!bFound) {
1189     return myResult;
1190   }
1191   //
1192   aBB.MakeCompound(aC);
1193   //
1194   const TopTools_ListOfShape& aLS=myImages.Find(myArgument);
1195   aItLS.Initialize(aLS);
1196   for (; aItLS.More(); aItLS.Next()) {
1197     const TopoDS_Shape& aSD=aItLS.Value();
1198     aBB.Add(aC, aSD);
1199   }
1200   //
1201   myResult = aC;
1202   return myResult;
1203 }