Salome HOME
CMake porting.
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Builder_3.cxx
1 // Copyright (C) 2007-2013  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.
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_Builder_3.cxx
23 //  Created :
24 //  Author  : Peter KURNEV
25
26 #include <GEOMAlgo_Builder.hxx>
27
28 #include <TopAbs_State.hxx>
29
30 #include <TopoDS.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Solid.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Solid.hxx>
36 #include <TopoDS_Iterator.hxx>
37 #include <TopoDS_Shell.hxx>
38 #include <TopoDS_Compound.hxx>
39
40 #include <TopExp.hxx>
41 #include <TopExp_Explorer.hxx>
42
43 #include <BRep_Builder.hxx>
44 #include <BRepTools.hxx>
45 #include <BRepClass3d_SolidClassifier.hxx>
46
47 #include <TopTools_ListOfShape.hxx>
48 #include <TopTools_IndexedMapOfShape.hxx>
49 #include <TopTools_ListIteratorOfListOfShape.hxx>
50 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
51 #include <TopTools_IndexedMapOfShape.hxx>
52 #include <TopTools_MapIteratorOfMapOfShape.hxx>
53 #include <TopTools_DataMapOfShapeShape.hxx>
54 #include <TopTools_DataMapOfShapeInteger.hxx>
55 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
56 #include <TopTools_MapOfShape.hxx>
57
58 #include <IntTools_Context.hxx>
59
60 #include <NMTDS_ShapesDataStructure.hxx>
61 #include <NMTTools_PaveFiller.hxx>
62
63 #include <GEOMAlgo_Tools3D.hxx>
64 #include <GEOMAlgo_BuilderSolid.hxx>
65 #include <GEOMAlgo_ShapeSet.hxx>
66 #include <GEOMAlgo_DataMapOfShapeShapeSet.hxx>
67 #include <GEOMAlgo_DataMapIteratorOfDataMapOfShapeShapeSet.hxx>
68
69
70
71 static
72   void OwnInternalShapes(const TopoDS_Shape& ,
73                          TopTools_IndexedMapOfShape& );
74
75 //=======================================================================
76 //function : FillImagesSolids
77 //purpose  :
78 //=======================================================================
79   void GEOMAlgo_Builder::FillImagesSolids()
80 {
81   myErrorStatus=0;
82   //
83   FillIn3DParts();
84   BuildSplitSolids();
85   FillInternalShapes();
86 }
87 //=======================================================================
88 //function : BuildDraftSolid
89 //purpose  :
90 //=======================================================================
91 void GEOMAlgo_Builder::BuildDraftSolid (const TopoDS_Shape& theSolid,
92                                         TopoDS_Shape& theDraftSolid,
93                                         TopTools_ListOfShape& theLIF)
94 {
95   myErrorStatus=0;
96   //
97   NMTTools_PaveFiller* pPF=myPaveFiller;
98   const Handle(IntTools_Context)& aCtx= pPF->Context();
99   //
100   Standard_Boolean bToReverse;
101   Standard_Integer  iFlag;
102   TopAbs_Orientation aOrF, aOrSh, aOrSd;
103   TopoDS_Iterator aIt1, aIt2;
104   TopTools_ListIteratorOfListOfShape aItS;
105   BRep_Builder aBB;
106   TopoDS_Shell aShD;
107   TopoDS_Shape aFSDx, aFx;
108   //
109   aOrSd=theSolid.Orientation();
110   theDraftSolid.Orientation(aOrSd);
111   //
112   aIt1.Initialize(theSolid);
113   for (; aIt1.More(); aIt1.Next()) {
114     const TopoDS_Shape& aSh=aIt1.Value();
115     if(aSh.ShapeType()!=TopAbs_SHELL) {
116       continue; // mb internal edges,vertices
117     }
118     //
119     aOrSh=aSh.Orientation();
120     aBB.MakeShell(aShD);
121     aShD.Orientation(aOrSh);
122     iFlag=0;
123     //
124     aIt2.Initialize(aSh);
125     for (; aIt2.More(); aIt2.Next()) {
126       const TopoDS_Shape& aF=aIt2.Value();
127       aOrF=aF.Orientation();
128       //
129       if (myImages.HasImage(aF)) {
130         const TopTools_ListOfShape& aLSp=myImages.Image(aF);
131         aItS.Initialize(aLSp);
132         for (; aItS.More(); aItS.Next()) {
133           aFx=aItS.Value();
134           //
135           if (mySameDomainShapes.Contains(aFx)) {
136             aFSDx=mySameDomainShapes.FindFromKey(aFx);
137             //
138             if (aOrF==TopAbs_INTERNAL) {
139               aFSDx.Orientation(aOrF);
140               theLIF.Append(aFSDx);
141             }
142             else {
143               bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aFSDx, aF, aCtx);
144               if (bToReverse) {
145                 aFSDx.Reverse();
146               }
147               //
148               iFlag=1;
149               aBB.Add(aShD, aFSDx);
150             }
151           }// if (mySameDomainShapes.Contains(aFx)) {
152           else {
153             aFx.Orientation(aOrF);
154             if (aOrF==TopAbs_INTERNAL) {
155               theLIF.Append(aFx);
156             }
157             else{
158               iFlag=1;
159               aBB.Add(aShD, aFx);
160             }
161           }
162         }
163       } //if (myImages.HasImage(aF)) {
164       //
165       else {
166         if (aOrF==TopAbs_INTERNAL) {
167           theLIF.Append(aF);
168         }
169         else{
170           iFlag=1;
171           aBB.Add(aShD, aF);
172         }
173       }
174     } //for (; aIt2.More(); aIt2.Next()) {
175     //
176     if (iFlag) {
177       aBB.Add(theDraftSolid, aShD);
178     }
179   } //for (; aIt1.More(); aIt1.Next()) {
180 }
181 //=======================================================================
182 //function : FillIn3DParts
183 //purpose  :
184 //=======================================================================
185   void GEOMAlgo_Builder::FillIn3DParts()
186 {
187   myErrorStatus=0;
188   //
189   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
190   NMTTools_PaveFiller* pPF=myPaveFiller;
191   const Handle(IntTools_Context)& aCtx= pPF->Context();
192   //
193   Standard_Boolean bIsIN, bHasImage;
194   Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF;
195   TopAbs_ShapeEnum aType;
196   TopAbs_State aState;
197   TopTools_IndexedMapOfShape aMSolids, aMS, aMFaces, aMFIN;
198   TopTools_MapOfShape aMFDone;
199   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
200   TopTools_ListIteratorOfListOfShape aItS;
201   TopoDS_Iterator aIt, aItF;
202   BRep_Builder aBB;
203   TopoDS_Solid aSolidSp;
204   TopoDS_Face aFP;
205   //
206   myDraftSolids.Clear();
207   //
208   aNbS=aDS.NumberOfShapesOfTheObject();
209   for (i=1; i<=aNbS; ++i) {
210     const TopoDS_Shape& aS=aDS.Shape(i);
211     //
212     aType=aS.ShapeType();
213     if (aType==TopAbs_SOLID) {
214       // all solids from DS
215       aMSolids.Add(aS);
216     }
217     else if (aType==TopAbs_FACE) {
218       // all faces (originals from DS or theirs images)
219       if (myImages.HasImage(aS)) {
220         const TopTools_ListOfShape& aLS=myImages.Image(aS);
221         aItS.Initialize(aLS);
222         for (; aItS.More(); aItS.Next()) {
223           const TopoDS_Shape& aFx=aItS.Value();
224           //
225           if (mySameDomainShapes.Contains(aFx)) {
226             const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aFx);
227             aMFaces.Add(aFSDx);
228           }
229           else {
230             aMFaces.Add(aFx);
231           }
232         }
233       }
234       else {
235         if (mySameDomainShapes.Contains(aS)) {
236           const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aS);
237           aMFaces.Add(aFSDx);
238         }
239         else {
240           aMFaces.Add(aS);
241         }
242       }
243     }
244   }
245   //
246   aNbFaces=aMFaces.Extent();
247   aNbSolids=aMSolids.Extent();
248   //
249   for (i=1; i<=aNbSolids; ++i) {
250     const TopoDS_Solid& aSolid=TopoDS::Solid(aMSolids(i));
251     aMFDone.Clear();
252     aMFIN.Clear();
253     aMEF.Clear();
254     //
255     aBB.MakeSolid(aSolidSp);
256     //
257     TopTools_ListOfShape aLIF;
258     //
259     BuildDraftSolid(aSolid, aSolidSp, aLIF);
260     aNbLIF=aLIF.Extent();
261     //
262     // 1 all faces/edges from aSolid [ aMS ]
263     bHasImage=Standard_False;
264     aMS.Clear();
265     aIt.Initialize(aSolid);
266     for (; aIt.More(); aIt.Next()) {
267       const TopoDS_Shape& aShell=aIt.Value();
268       //
269       if (myImages.HasImage(aShell)) {
270         bHasImage=Standard_True;
271         //
272         const TopTools_ListOfShape& aLS=myImages.Image(aShell);
273         aItS.Initialize(aLS);
274         for (; aItS.More(); aItS.Next()) {
275           const TopoDS_Shape& aSx=aItS.Value();
276           aMS.Add(aSx);
277           TopExp::MapShapes(aSx, TopAbs_FACE, aMS);
278           TopExp::MapShapes(aSx, TopAbs_EDGE, aMS);
279           TopExp::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
280         }
281       }
282       else {
283         //aMS.Add(aShell);
284         TopExp::MapShapes(aShell, TopAbs_FACE, aMS);
285         TopExp::MapShapes(aShell, TopAbs_EDGE, aMS);
286         TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
287       }
288     }
289     //
290     // 2 all faces that are not from aSolid [ aLFP1 ]
291     Standard_Integer aNbEFP;
292     TopTools_IndexedDataMapOfShapeListOfShape aMEFP;
293     TopTools_ListIteratorOfListOfShape aItFP, aItEx;
294     TopTools_MapOfShape aMFence;
295     TopTools_ListOfShape aLFP1, aLFP2, aLFP, aLCBF, aLFIN, aLEx;//*pLFP,
296     //
297     // for all non-solid faces build EF map [ aMEFP ]
298     for (j=1; j<=aNbFaces; ++j) {
299       const TopoDS_Shape& aFace=aMFaces(j);
300       if (!aMS.Contains(aFace)) {
301         TopExp::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
302       }
303     }
304     //
305     // among all faces from aMEFP select these that have same edges
306     // with the solid (i.e aMEF). These faces will be treated first
307     // to prevent the usage of 3D classifier.
308     // The full list of faces to process is aLFP1.
309     aNbEFP=aMEFP.Extent();
310     for (j=1; j<=aNbEFP; ++j) {
311       const TopoDS_Shape& aE=aMEFP.FindKey(j);
312       //
313       if (aMEF.Contains(aE)) { // !!
314         const TopTools_ListOfShape& aLF=aMEFP(j);
315         aItFP.Initialize(aLF);
316         for (; aItFP.More(); aItFP.Next()) {
317           const TopoDS_Shape& aF=aItFP.Value();
318           if (aMFence.Add(aF)) {
319             aLFP1.Append(aF);
320           }
321         }
322       }
323       else {
324         aLEx.Append(aE);
325       }
326     }
327     //
328     aItEx.Initialize(aLEx);
329     for (; aItEx.More(); aItEx.Next()) {
330       const TopoDS_Shape& aE=aItEx.Value();
331       const TopTools_ListOfShape& aLF=aMEFP.FindFromKey(aE);
332       aItFP.Initialize(aLF);
333       for (; aItFP.More(); aItFP.Next()) {
334         const TopoDS_Shape& aF=aItFP.Value();
335         if (aMFence.Add(aF)) {
336           aLFP2.Append(aF);
337         }
338       }
339     }
340     aLFP1.Append(aLFP2);
341     //==========
342     //
343     // 3 Process faces aLFP1
344     aNbFP=aLFP1.Extent();
345     aItFP.Initialize(aLFP1);
346     for (; aItFP.More(); aItFP.Next()) {
347       const TopoDS_Shape& aSP=aItFP.Value();
348       if (!aMFDone.Add(aSP)) {
349         continue;
350       }
351
352       //
353       // first face to process
354       aFP=TopoDS::Face(aSP);
355       bIsIN= GEOMAlgo_Tools3D::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, aCtx);
356       aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
357       //
358       // collect faces to process [ aFP is the first ]
359       aLFP.Clear();
360       aLFP.Append(aFP);
361       aItS.Initialize(aLFP1);
362       for (; aItS.More(); aItS.Next()) {
363         const TopoDS_Shape& aSk=aItS.Value();
364         if (!aMFDone.Contains(aSk)) {
365           aLFP.Append(aSk);
366         }
367       }
368       //
369       // Connexity Block that spreads from aFP the Bound
370       // or till the end of the block itself
371       aLCBF.Clear();
372       GEOMAlgo_Tools3D::MakeConnexityBlock(aLFP, aMS, aLCBF);
373       //
374       // fill states for the Connexity Block
375       aItS.Initialize(aLCBF);
376       for (; aItS.More(); aItS.Next()) {
377         const TopoDS_Shape& aSx=aItS.Value();
378         aMFDone.Add(aSx);
379         if (aState==TopAbs_IN) {
380           aMFIN.Add(aSx);
381         }
382       }
383       //
384       aNbFPx=aMFDone.Extent();
385       if (aNbFPx==aNbFP) {
386         break;
387       }
388     }//for (; aItFP.More(); aItFP.Next())
389     //
390     // faces Inside aSolid
391     aLFIN.Clear();
392     aNbFIN=aMFIN.Extent();
393     if (aNbFIN || aNbLIF) {
394       for (j=1; j<=aNbFIN; ++j) {
395         const TopoDS_Shape& aFIN=aMFIN(j);
396         aLFIN.Append(aFIN);
397       }
398       //
399       aItS.Initialize(aLIF);
400       for (; aItS.More(); aItS.Next()) {
401         const TopoDS_Shape& aFIN=aItS.Value();
402         aLFIN.Append(aFIN);
403       }
404       //
405       myInParts.Add(aSolid, aLFIN);
406     }
407     if (aNbFIN || bHasImage) {
408       myDraftSolids.Add(aSolid, aSolidSp);
409     }
410   }//for (i=1; i<=aNbSolids; ++i) { // next solid
411 }
412 //=======================================================================
413 //function : BuildSplitSolids
414 //purpose  :
415 //=======================================================================
416   void GEOMAlgo_Builder::BuildSplitSolids()
417 {
418   myErrorStatus=0;
419   //
420   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
421   NMTTools_PaveFiller* pPF=myPaveFiller;
422   const Handle(IntTools_Context)& aCtx= pPF->Context();
423   //
424   Standard_Integer i, aNbS, iErr;
425   TopExp_Explorer aExp;
426   TopTools_ListOfShape aSFS, aLSEmpty;
427   TopTools_MapOfShape aMFence;
428   TopTools_ListIteratorOfListOfShape aIt;
429   GEOMAlgo_BuilderSolid aSB;
430   GEOMAlgo_DataMapIteratorOfDataMapOfShapeShapeSet aItSS;
431   GEOMAlgo_DataMapOfShapeShapeSet aMSS;
432   GEOMAlgo_ShapeSet aSSi;
433   //
434   // 0. Find same domain solids for non-interferred solids
435   aNbS=aDS.NumberOfShapesOfTheObject();
436   for (i=1; i<=aNbS; ++i) {
437     const TopoDS_Shape& aS=aDS.Shape(i);
438     if (aS.ShapeType()!=TopAbs_SOLID) {
439       continue;
440     }
441     if (!aMFence.Add(aS)) {
442       continue;
443     }
444     if(myDraftSolids.Contains(aS)) {
445       continue;
446     }
447     //
448     aSSi.Clear();
449     aSSi.Add(aS, TopAbs_FACE);
450     //
451     aMSS.Bind(aS, aSSi);
452   } //for (i=1; i<=aNbS; ++i)
453   //
454   // 1. Build solids for interferred source solids
455   aSB.SetContext(aCtx);
456   aSB.ComputeInternalShapes(myComputeInternalShapes);
457   aNbS=myDraftSolids.Extent();
458   for (i=1; i<=aNbS; ++i) {
459     const TopoDS_Shape& aS =myDraftSolids.FindKey(i);
460     const TopoDS_Shape& aSD=myDraftSolids.FindFromIndex(i);
461     const TopTools_ListOfShape& aLFIN=
462       (myInParts.Contains(aS)) ? myInParts.FindFromKey(aS) : aLSEmpty;
463     //
464     // 1.1 Fill Shell Faces Set
465     aSFS.Clear();
466
467     aExp.Init(aSD, TopAbs_FACE);
468     for (; aExp.More(); aExp.Next()) {
469       const TopoDS_Shape& aF=aExp.Current();
470       aSFS.Append(aF);
471     }
472     //
473     aIt.Initialize(aLFIN);
474     for (; aIt.More(); aIt.Next()) {
475       TopoDS_Shape aF=aIt.Value();
476       //
477       aF.Orientation(TopAbs_FORWARD);
478       aSFS.Append(aF);
479       aF.Orientation(TopAbs_REVERSED);
480       aSFS.Append(aF);
481     }
482     //
483     Standard_Integer aNbSFS;
484     aNbSFS=aSFS.Extent();
485     //
486     // 1.2
487     // Check whether aSFS contains a subsets of faces
488     // of solids that have been already built.
489     // If yes, shrink aSFS by these subsets.
490     aSSi.Clear();
491     aSSi.Add(aSFS);
492     //
493     aItSS.Initialize(aMSS);
494     for (; aItSS.More(); aItSS.Next()) {
495       const TopoDS_Shape& aSR=aItSS.Key();
496       const GEOMAlgo_ShapeSet& aSSR=aItSS.Value();
497       if (aSSi.Contains(aSSR)) {
498         // the aSR is SD solid for aS
499         aSSi.Subtract(aSSR);
500         // update images
501         if(myImages.HasImage(aS)) {
502           myImages.Add(aS, aSR);
503         }
504         else {
505           myImages.Bind(aS, aSR);
506         }
507         //
508         // update SD Shapes
509         mySameDomainShapes.Add(aSR, aSR);
510       }
511     }
512     const TopTools_ListOfShape& aSFS1=aSSi.GetSet();
513     aNbSFS=aSFS1.Extent();
514     if (!aNbSFS) {
515       continue;
516     }
517     //
518     // 1.3 Build new solids
519     aSB.SetContext(aCtx);
520     aSB.SetShapes(aSFS1);
521     aSB.Perform();
522     iErr=aSB.ErrorStatus();
523     if (iErr) {
524       myErrorStatus=30; // SolidBuilder failed
525       return;
526     }
527     //
528     const TopTools_ListOfShape& aLSR=aSB.Areas();
529     //
530       // 1.4 Collect resulting solids and theirs set of faces
531     aIt.Initialize(aLSR);
532     for (; aIt.More(); aIt.Next()) {
533       const TopoDS_Shape& aSR=aIt.Value();
534       //
535       aSSi.Clear();
536       aExp.Init(aSR, TopAbs_FACE);
537       for (; aExp.More(); aExp.Next()) {
538         const TopoDS_Shape& aF=aExp.Current();
539         aSSi.Add(aF);
540       }
541       aMSS.Bind(aSR, aSSi);
542     }
543     //
544     // Update images
545     if (myImages.HasImage(aS)) {
546       myImages.Add(aS, aLSR);
547     }
548     else {
549       myImages.Bind(aS, aLSR);
550     }
551   } // for (i=1; i<=aNbS; ++i) {
552 }
553 //=======================================================================
554 //function :FillInternalShapes
555 //purpose  :
556 //=======================================================================
557   void GEOMAlgo_Builder::FillInternalShapes()
558 {
559   myErrorStatus=0;
560   //
561   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
562   NMTTools_PaveFiller* pPF=myPaveFiller;
563   const Handle(IntTools_Context)& aCtx= pPF->Context();
564   //
565   //Standard_Boolean bHasImage;
566   Standard_Integer i, j, jT, aNbS, aNbSI, aNbSx, aNbSd;
567   TopAbs_ShapeEnum aType, aT[]={ TopAbs_VERTEX, TopAbs_EDGE };
568   TopAbs_State aState;
569   TopTools_ListIteratorOfListOfShape aIt, aIt1;
570   TopTools_IndexedDataMapOfShapeListOfShape aMSx;
571   TopTools_IndexedMapOfShape aMx;
572   TopTools_MapOfShape aMSI, aMFence, aMSOr;
573   TopTools_MapIteratorOfMapOfShape aItM;
574   TopTools_ListOfShape aLSI, aLSd;
575   TopoDS_Iterator aItS;
576   BRep_Builder aBB;
577   //
578   // 1. Shapes to process
579   //
580   // 1.1 Shapes from pure arguments aMSI
581   // 1.1.1 vertex, edge
582   for (i=0; i<2; ++i) {
583     jT=(Standard_Integer)aT[i];
584     const TopTools_ListOfShape &aLS=myShapes1[jT];
585     aIt.Initialize(aLS);
586     for (; aIt.More(); aIt.Next()) {
587       const TopoDS_Shape& aS=aIt.Value();
588       if (aMFence.Add(aS)) {
589         aLSI.Append(aS);
590       }
591     }
592   }
593   // 1.1.2 wire
594   {
595     jT=(Standard_Integer)TopAbs_WIRE;
596     const TopTools_ListOfShape &aLW=myShapes1[jT];
597     aIt.Initialize(aLW);
598     for (; aIt.More(); aIt.Next()) {
599       const TopoDS_Shape& aW=aIt.Value();
600       aItS.Initialize(aW);
601       for (; aItS.More(); aItS.Next()) {
602         const TopoDS_Shape& aE=aItS.Value();
603         if (aMFence.Add(aE)) {
604           aLSI.Append(aE);
605         }
606       }
607     }
608   }
609   // 1.1.3 theirs images/sources
610   aIt1.Initialize(aLSI);
611   for (; aIt1.More(); aIt1.Next()) {
612     const TopoDS_Shape& aS=aIt1.Value();
613     if (myImages.HasImage(aS)) {
614       const TopTools_ListOfShape &aLSp=myImages.Image(aS);
615       aIt.Initialize(aLSp);
616       for (; aIt.More(); aIt.Next()) {
617         const TopoDS_Shape& aSI=aIt.Value();
618         aMSI.Add(aSI);
619       }
620     }
621     else {
622       aMSI.Add(aS);
623     }
624   }
625   aLSI.Clear();
626   aNbSI=aMSI.Extent();
627   //
628   // 2. Internal vertices, edges from source solids
629   aMFence.Clear();
630   aLSd.Clear();
631   //
632   aNbS=aDS.NumberOfShapesOfTheObject();
633   for (i=1; i<=aNbS; ++i) {
634     const TopoDS_Shape& aS=aDS.Shape(i);
635     aType=aS.ShapeType();
636     if (aType==TopAbs_SOLID) {
637       //
638       aMx.Clear();
639       OwnInternalShapes(aS, aMx);
640       //
641       aNbSx=aMx.Extent();
642       for (j=1; j<=aNbSx; ++j) {
643         const TopoDS_Shape& aSI=aMx(j);
644         if (myImages.HasImage(aSI)) {
645           const TopTools_ListOfShape &aLSp=myImages.Image(aSI);
646           aIt.Initialize(aLSp);
647           for (; aIt.More(); aIt.Next()) {
648             const TopoDS_Shape& aSp=aIt.Value();
649             aMSI.Add(aSp);
650           }
651         }
652         else {
653           aMSI.Add(aSI);
654         }
655       }
656       //
657       // build aux map from splits of solids
658       if (myImages.HasImage(aS)) {
659         const TopTools_ListOfShape &aLSp=myImages.Image(aS);
660         aIt.Initialize(aLSp);
661         for (; aIt.More(); aIt.Next()) {
662           const TopoDS_Shape& aSp=aIt.Value();
663           if (aMFence.Add(aSp)) {
664             TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
665             TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
666             TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE  , TopAbs_FACE, aMSx);
667             aLSd.Append(aSp);
668           }
669         }
670       }
671       else {
672         if (aMFence.Add(aS)) {
673           TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
674           TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
675           TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE  , TopAbs_FACE, aMSx);
676           aLSd.Append(aS);
677           aMSOr.Add(aS);
678         }
679       }
680     }//if (aType==TopAbs_SOLID)
681   }
682   //
683   aNbSd=aLSd.Extent();
684   //
685   // 3. Some shapes of aMSI can be already tied with faces of
686   //    split solids
687   aItM.Initialize(aMSI);
688   for (; aItM.More(); aItM.Next()) {
689     const TopoDS_Shape& aSI=aItM.Key();
690     if (aMSx.Contains(aSI)) {
691       const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
692       aNbSx=aLSx.Extent();
693       if (aNbSx) {
694         //modified by NIZNHY-PKV Wed Mar 27 11:39:15 2013f
695         //aMSI.Remove(aSI);
696         if (aMSI.Remove(aSI)) {
697           aItM.Initialize(aMSI);
698         }
699         //modified by NIZNHY-PKV Wed Mar 27 11:39:18 2013t
700       }
701     }
702   }
703   //
704   // 4. Just check it
705   aNbSI=aMSI.Extent();
706   if (!aNbSI) {
707     return;
708   }
709   //
710   // 5 Settle internal vertices and edges into solids
711   aMx.Clear();
712   aIt.Initialize(aLSd);
713   for (; aIt.More(); aIt.Next()) {
714     TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
715     //
716     aItM.Initialize(aMSI);
717     for (; aItM.More(); /*aItM.Next()*/) {
718       TopoDS_Shape aSI=aItM.Key();
719       aItM.Next(); // to safely call aMSI.Remove(aSI)
720       aSI.Orientation(TopAbs_INTERNAL);
721       //
722       aState=GEOMAlgo_Tools3D::ComputeStateByOnePoint(aSI, aSd, 1.e-11, aCtx);
723       if (aState==TopAbs_IN) {
724         //
725         if(aMSOr.Contains(aSd)) {
726           //
727           TopoDS_Solid aSdx;
728           //
729           aBB.MakeSolid(aSdx);
730           aItS.Initialize(aSd);
731           for (; aItS.More(); aItS.Next()) {
732             const TopoDS_Shape& aSh=aItS.Value();
733             aBB.Add(aSdx, aSh);
734           }
735           //
736           aBB.Add(aSdx, aSI);
737           //
738           myImages.Bind(aSd, aSdx);
739           aMSOr.Remove(aSd);
740           aSd=aSdx;
741         }
742         else {
743           aBB.Add(aSd, aSI);
744         }
745         //
746         aMSI.Remove(aSI);
747       } //if (aState==TopAbs_IN) {
748     }// for (; aItM.More(); aItM.Next()) {
749   }//for (; aIt1.More(); aIt1.Next()) {
750 }
751 //=======================================================================
752 //function : OwnInternalShapes
753 //purpose  :
754 //=======================================================================
755   void OwnInternalShapes(const TopoDS_Shape& theS,
756                          TopTools_IndexedMapOfShape& theMx)
757 {
758   TopoDS_Iterator aIt;
759   //
760   aIt.Initialize(theS);
761   for (; aIt.More(); aIt.Next()) {
762     const TopoDS_Shape& aSx=aIt.Value();
763     if (aSx.ShapeType()!=TopAbs_SHELL) {
764       theMx.Add(aSx);
765     }
766   }
767 }
768 //
769 // ErrorStatus
770 // 30 - SolidBuilder failed