0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[occt.git] / src / BOPAlgo / BOPAlgo_Section.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <BOPAlgo_BuilderSolid.hxx>
17 #include <BOPAlgo_PaveFiller.hxx>
18 #include <BOPAlgo_Section.hxx>
19 #include <BOPAlgo_Alerts.hxx>
20 #include <BOPCol_DataMapOfShapeShape.hxx>
21 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
22 #include <BOPCol_IndexedMapOfShape.hxx>
23 #include <BOPCol_ListOfShape.hxx>
24 #include <BOPCol_MapOfShape.hxx>
25 #include <BOPDS_CommonBlock.hxx>
26 #include <BOPDS_DS.hxx>
27 #include <BOPDS_FaceInfo.hxx>
28 #include <BOPDS_ListOfPaveBlock.hxx>
29 #include <BOPDS_MapOfPaveBlock.hxx>
30 #include <BOPDS_PaveBlock.hxx>
31 #include <BOPDS_VectorOfFaceInfo.hxx>
32 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
33 #include <BOPTools.hxx>
34 #include <BOPTools_AlgoTools.hxx>
35 #include <BOPTools_AlgoTools3D.hxx>
36 #include <BRep_Builder.hxx>
37 #include <BRep_Tool.hxx>
38 #include <TopAbs_ShapeEnum.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TopoDS_Compound.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopoDS_Shape.hxx>
44
45 //
46 //
47 //=======================================================================
48 //function : 
49 //purpose  : 
50 //=======================================================================
51 BOPAlgo_Section::BOPAlgo_Section()
52 :
53   BOPAlgo_Builder()
54 {
55   Clear();
56 }
57 //=======================================================================
58 //function : 
59 //purpose  : 
60 //=======================================================================
61 BOPAlgo_Section::BOPAlgo_Section
62   (const Handle(NCollection_BaseAllocator)& theAllocator)
63 :
64   BOPAlgo_Builder(theAllocator)
65 {
66   Clear();
67 }
68 //=======================================================================
69 //function : ~
70 //purpose  : 
71 //=======================================================================
72 BOPAlgo_Section::~BOPAlgo_Section()
73 {
74 }
75 //=======================================================================
76 //function : CheckData
77 //purpose  : 
78 //=======================================================================
79 void BOPAlgo_Section::CheckData()
80 {
81   Standard_Integer aNbArgs;
82   //
83   aNbArgs=myArguments.Extent();
84   if (!aNbArgs) {
85     AddError (new BOPAlgo_AlertTooFewArguments);
86     return;
87   }
88   //
89   CheckFiller();
90 }
91 //=======================================================================
92 //function : PerformInternal1
93 //purpose  : 
94 //=======================================================================
95 void BOPAlgo_Section::PerformInternal1
96   (const BOPAlgo_PaveFiller& theFiller)
97 {
98   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
99   myDS=myPaveFiller->PDS();
100   myContext=myPaveFiller->Context();
101   //
102   // 1. CheckData
103   CheckData();
104   if (HasErrors()) {
105     return;
106   }
107   //
108   // 2. Prepare
109   Prepare();
110   if (HasErrors()) {
111     return;
112   }
113   //
114   // 3. Fill Images
115   // 3.1 Vertices
116   FillImagesVertices();
117   if (HasErrors()) {
118     return;
119   }
120   //
121   BuildResult(TopAbs_VERTEX);
122   if (HasErrors()) {
123     return;
124   }
125   // 3.2 Edges
126   FillImagesEdges();
127   if (HasErrors()) {
128     return;
129   }
130   //
131   BuildResult(TopAbs_EDGE);
132   if (HasErrors()) {
133     return;
134   }
135   // 4. Section
136   BuildSection();
137   //
138   if (HasErrors()) {
139     return;
140   }
141   // 5.History
142   PrepareHistory();
143   //
144   if (HasErrors()) {
145     return;
146   } 
147   // 6. Post-treatment
148   PostTreat();
149 }
150 //=======================================================================
151 //function : BuildSection
152 //purpose  : 
153 //=======================================================================
154 void BOPAlgo_Section::BuildSection()
155 {
156   Standard_Integer i, aNbMS, aNbLE;
157   Standard_Integer j,  nE, nV, aNb, aNbF, aNbPBSc;
158   TopoDS_Shape aRC, aRC1;
159   BRep_Builder aBB;
160   TopExp_Explorer aExp;
161   BOPCol_ListOfShape aLSA, aLS;
162   BOPCol_ListIteratorOfListOfShape aIt, aItIm, aItLS;
163   BOPCol_IndexedDataMapOfShapeInteger aMSI(100, myAllocator);
164   BOPCol_IndexedMapOfShape aMS(100, myAllocator);
165   BOPCol_MapOfShape aMFence(100, myAllocator);
166   BOPCol_MapIteratorOfMapOfInteger aItMI; 
167   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
168   //
169   GetReport()->Clear();
170   //
171   BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC1);
172   //
173   // 1. aRC1
174   aNb=myDS->NbSourceShapes();
175   for (i=0; i<aNb; ++i) {
176     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
177     if (aSI.ShapeType()!=TopAbs_FACE) {
178       continue;
179     }
180     //
181     const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
182     //
183     // 1.1 Vertices that are section vertices 
184     const BOPCol_MapOfInteger& aMVSc=aFI.VerticesSc();
185     aItMI.Initialize(aMVSc);
186     for(; aItMI.More(); aItMI.Next()) {
187       nV=aItMI.Key();
188       const TopoDS_Shape& aV=myDS->Shape(nV);
189       aBB.Add(aRC1, aV);
190     }
191     //
192     // 1.2 Vertices that are in a face 
193     const BOPCol_MapOfInteger& aMI=aFI.VerticesIn();
194     aItMI.Initialize(aMI);
195     for(; aItMI.More(); aItMI.Next()) {
196       nV=aItMI.Key();
197       if (nV<0) {
198         continue;
199       }  
200       if (myDS->IsNewShape(nV) || myDS->HasInterf(nV)) { 
201         const TopoDS_Shape& aV=myDS->Shape(nV);
202         aBB.Add(aRC1, aV);
203       }
204     }
205     //
206     // 1.3 Section edges
207     const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
208     //
209     aNbPBSc=aMPBSc.Extent();
210     for (j=1; j<=aNbPBSc; ++j) {
211       const Handle(BOPDS_PaveBlock)& aPB=aMPBSc(j);
212       nE=aPB->Edge();
213       const TopoDS_Shape& aE=myDS->Shape(nE);
214       aBB.Add(aRC1, aE);
215     }
216   }
217   //
218   // 2. Common blocks between an edge and a face
219   const BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->PaveBlocksPool();
220   //
221   aNb=aPBP.Size();
222   for (i=0; i<aNb; ++i) {
223     const BOPDS_ListOfPaveBlock& aLPB=aPBP(i); 
224     aItPB.Initialize(aLPB);
225     for (; aItPB.More(); aItPB.Next()) {
226       const Handle(BOPDS_PaveBlock)& aPB=aItPB.Value();
227       Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
228       if (!aCB.IsNull()) {
229         const BOPCol_ListOfInteger& aLF=aCB->Faces();
230         aNbF=aLF.Extent();
231         if (aNbF) {
232           const Handle(BOPDS_PaveBlock)& aPBR=aCB->PaveBlock1();
233           nE=aPBR->Edge();
234           const TopoDS_Shape& aE=myDS->Shape(nE);
235           aBB.Add(aRC1, aE);
236         }
237       }
238     }
239   }
240   //
241   aIt.Initialize(myArguments);
242   for (; aIt.More(); aIt.Next()) {
243     const TopoDS_Shape& aSA=aIt.Value();
244     if (aMFence.Add(aSA)) {
245       aLSA.Append(aSA);
246     }
247   }
248   //
249   aMFence.Clear();
250   //
251   // 3. Treatment boundaries of arguments
252   //
253   // 3.1 Set to treat => aLS
254   aIt.Initialize(aLSA);
255   for (; aIt.More(); aIt.Next()) {
256     const TopoDS_Shape& aSA=aIt.Value();
257     //
258     aLS.Clear();
259     aMS.Clear();
260     aMFence.Clear();
261     //
262     aExp.Init (aSA, TopAbs_EDGE);
263     for (; aExp.More(); aExp.Next()) {
264       const TopoDS_Shape& aE=aExp.Current();
265       if (aMFence.Add(aE)) {
266         aLS.Append(aE);
267       }
268     }
269     aExp.Init (aSA, TopAbs_VERTEX);
270     for (; aExp.More(); aExp.Next()) {
271       const TopoDS_Shape& aE=aExp.Current();
272       if (aMFence.Add(aE)) {
273         aLS.Append(aE);
274       }
275     }
276     //
277     // 3.2 aMSI
278     aItLS.Initialize(aLS);
279     for (; aItLS.More(); aItLS.Next()) { 
280       const TopoDS_Shape& aS=aItLS.Value();
281       //
282       if (myImages.IsBound(aS)){
283         const BOPCol_ListOfShape& aLSIm=myImages.Find(aS);
284         aItIm.Initialize(aLSIm);
285         for (; aItIm.More(); aItIm.Next()) {
286           const TopoDS_Shape& aSIm=aItIm.Value();
287           BOPTools::MapShapes(aSIm, TopAbs_VERTEX, aMS);
288           BOPTools::MapShapes(aSIm, TopAbs_EDGE  , aMS);
289         }
290       }// if (myImages.IsBound(aF)){
291       else {
292         BOPTools::MapShapes(aS, TopAbs_VERTEX, aMS);
293         BOPTools::MapShapes(aS, TopAbs_EDGE  , aMS);
294       }
295     }//for (; aItLS.More(); aItLS.Next()) { 
296     //
297     aNbMS=aMS.Extent();
298     for (i=1; i<=aNbMS; ++i) {
299       const TopoDS_Shape& aS=aMS(i);
300       if (aMSI.Contains(aS)) {
301         Standard_Integer& iCnt=aMSI.ChangeFromKey(aS);
302         ++iCnt;
303       }
304       else {
305         aMSI.Add(aS, 1);
306       }
307     }
308   } //for (; aIt.More(); aIt.Next()) {
309   //
310   aMS.Clear();
311   aMFence.Clear();
312   //
313   // 4. Build the result
314   BOPCol_IndexedDataMapOfShapeListOfShape aMVE(100, myAllocator);
315   // 
316   BOPTools::MapShapesAndAncestors(aRC1, 
317                                   TopAbs_VERTEX, 
318                                   TopAbs_EDGE, 
319                                   aMVE);
320   //
321   aNbMS=aMSI.Extent();
322   for (i=1; i<=aNbMS; ++i) {
323     const TopoDS_Shape& aV=aMSI.FindKey(i);
324     const Standard_Integer& iCnt=aMSI.FindFromIndex(i);
325     if (iCnt>1) {
326       BOPTools::MapShapesAndAncestors(aV, 
327                                       TopAbs_VERTEX, 
328                                       TopAbs_EDGE, 
329                                       aMVE);
330     }
331   }
332   //
333   BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);
334   //
335   aNbMS=aMVE.Extent();
336   for (i=1; i<=aNbMS; ++i) {
337     const TopoDS_Shape& aV=aMVE.FindKey(i);
338     const BOPCol_ListOfShape& aLE=aMVE.FindFromIndex(i);
339     aNbLE=aLE.Extent();
340     if (!aNbLE) {
341       // alone vertices
342       if (aMFence.Add(aV)) {
343         aBB.Add(aRC, aV); 
344       }
345     }
346     else {
347       // edges 
348       aIt.Initialize(aLE);
349       for (; aIt.More(); aIt.Next()) {
350         const TopoDS_Shape& aE=aIt.Value();
351         if (aMFence.Add(aE)) {
352           aBB.Add(aRC, aE);
353         }
354       }
355     }
356   }
357   //
358   myShape=aRC;
359 }
360 //=======================================================================
361 //function : Generated
362 //purpose  : 
363 //=======================================================================
364 const TopTools_ListOfShape& BOPAlgo_Section::Generated
365   (const TopoDS_Shape& theS)
366 {
367   myHistShapes.Clear();
368   if (theS.IsNull()) {
369     return myHistShapes;
370   }
371   //
372   TopAbs_ShapeEnum aType = theS.ShapeType();
373   if (aType != TopAbs_FACE) {
374     return myHistShapes;
375   }
376   //
377   Standard_Integer nS = myDS->Index(theS);
378   if (nS < 0) {
379     return myHistShapes;
380   }
381   //
382   if (!myDS->HasFaceInfo(nS)) {
383     return myHistShapes;
384   }
385   //
386   //collect section edges of the face theS
387   Standard_Integer i, aNb, nSp;
388   //
389   const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nS);
390   const BOPDS_IndexedMapOfPaveBlock& aMPBSc = aFI.PaveBlocksSc();
391   aNb = aMPBSc.Extent();
392   for (i = 1; i <= aNb; ++i) {
393     const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i);
394     nSp = aPB->Edge();
395     const TopoDS_Shape& aSp = myDS->Shape(nSp);
396     myHistShapes.Append(aSp);
397   }
398   //
399   return myHistShapes;
400 }