0023024: Update headers of OCCT files
[occt.git] / src / BOP / BOP_ShellShell.cxx
1 // Created on: 2001-10-29
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <BOP_ShellShell.ixx>
22
23
24 #include <TopoDS.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopoDS_Face.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Shell.hxx>
29 #include <TopoDS_Compound.hxx>
30
31 #include <BRep_Tool.hxx>
32 #include <BRep_Builder.hxx>
33
34 #include <TopAbs_Orientation.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopExp.hxx>
37
38 #include <TopTools_ListOfShape.hxx>
39 #include <TopTools_ListIteratorOfListOfShape.hxx>
40
41 #include <TopTools_IndexedMapOfShape.hxx>
42
43 #include <TColStd_IndexedMapOfInteger.hxx>
44
45 #include <BOPTColStd_Dump.hxx>
46
47 #include <BooleanOperations_ShapesDataStructure.hxx>
48 #include <BooleanOperations_StateOfShape.hxx>
49
50 #include <BOPTools_PaveFiller.hxx>
51 #include <BOPTools_InterferencePool.hxx>
52 #include <BOPTools_CArray1OfSSInterference.hxx>
53 #include <BOPTools_CArray1OfInterferenceLine.hxx>
54 #include <BOPTools_InterferenceLine.hxx>
55
56 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
57 #include <BOPTools_SSInterference.hxx>
58
59 #include <BOP_WireEdgeSet.hxx>
60 #include <BOP_SDFWESFiller.hxx>
61 #include <BOP_FaceBuilder.hxx>
62 #include <BOP_Draw.hxx>
63 #include <BOP_CorrectTolerances.hxx>
64 #include <BOP_BuilderTools.hxx>
65 #include <BOP_Refiner.hxx>
66 #include <Standard_Failure.hxx>
67 #include <Standard_ErrorHandler.hxx>
68
69
70
71 //=======================================================================
72 // function: BOP_ShellShell::BOP_ShellShell
73 // purpose: 
74 //=======================================================================
75 BOP_ShellShell::BOP_ShellShell()
76 {
77 }
78
79 //=======================================================================
80 // function: Destroy
81 // purpose: 
82 //=======================================================================
83   void BOP_ShellShell::Destroy() {}
84
85 //=======================================================================
86 // function: DoWithFiller
87 // purpose: 
88 //=======================================================================
89   void BOP_ShellShell::DoWithFiller(const BOPTools_DSFiller& aDSFiller) 
90 {
91   myErrorStatus=0;
92   myIsDone=Standard_False;
93   //
94   myResultMap.Clear();
95   myModifiedMap.Clear();
96   //
97   myDSFiller=(BOPTools_DSFiller*) &aDSFiller;
98   //
99   try {
100     OCC_CATCH_SIGNALS
101
102     // modified by NIZHNY-MKK  Fri Sep  3 15:14:17 2004.BEGIN
103     if(!myDSFiller->IsDone()) {
104       myErrorStatus = 1;
105       BOPTColStd_Dump::PrintMessage("DSFiller is invalid: Can not build result\n");
106       return;
107     }
108     // modified by NIZHNY-MKK  Fri Sep  3 15:14:20 2004.END
109
110     Standard_Boolean bIsNewFiller;
111     bIsNewFiller=aDSFiller.IsNewFiller();
112     
113     if (bIsNewFiller) {
114       Prepare();
115       aDSFiller.SetNewFiller(!bIsNewFiller);
116     }
117     //
118     DoNewFaces();
119     //
120     BuildResult();
121     //
122     // Treat of internals
123     CollectInternals();
124     BOP_Refiner aRefiner;
125     aRefiner.SetShape(myResult);
126     aRefiner.SetInternals(myInternals);
127     aRefiner.Do();
128     //
129     BOP_CorrectTolerances::CorrectTolerances(myResult, 0.01);
130     //
131     FillModified();
132     myIsDone=Standard_True;
133   }
134   catch ( Standard_Failure ) {
135     myErrorStatus = 1;
136     BOPTColStd_Dump::PrintMessage("Can not build result\n");
137   }
138 }
139
140 //=================================================================================
141 // function: BuildResult
142 // purpose: 
143 //=================================================================================
144   void BOP_ShellShell::BuildResult()
145 {
146   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
147   
148   Standard_Integer i, j, aNb, iRank, aNbFaces;
149   BooleanOperations_StateOfShape aState, aStateToCompare;
150   BRep_Builder aBB;
151   TopoDS_Compound aFCompound, aRes;
152   //
153   Standard_Boolean bHasInterference;
154   BOPTools_InterferencePool* pInterfPool=
155     (BOPTools_InterferencePool*) &myDSFiller->InterfPool();
156   BOPTools_CArray1OfInterferenceLine* pTable=
157     (BOPTools_CArray1OfInterferenceLine*) &pInterfPool->InterferenceTable();
158   //
159   aBB.MakeCompound(aRes);
160   //
161   // 1. Make aCompound containing all faces for thr Result
162   aBB.MakeCompound(aFCompound);
163   //
164   // 1.1. Old Faces with right 3D-state
165   aNb=aDS.NumberOfSourceShapes();
166   for (i=1; i<=aNb; i++) {
167     const TopoDS_Shape& aS=aDS.Shape(i);
168     if (aS.ShapeType()==TopAbs_FACE){
169       //
170       BOPTools_InterferenceLine& anInterfLine=pTable->ChangeValue(i);
171       bHasInterference=anInterfLine.HasInterference();
172       if (bHasInterference) {
173         continue;
174       }
175       //
176       aState=aDS.GetState(i);
177       if (aState==BooleanOperations_IN ||
178           aState==BooleanOperations_OUT) {
179         iRank=aDS.Rank(i);
180         aStateToCompare=BOP_BuilderTools::StateToCompare(iRank, myOperation);
181         if (aState==aStateToCompare) {
182           aBB.Add(aFCompound, aS);
183         }
184       }
185     }
186   }
187   //
188   // 1.2. aListOfNewFaces
189   TopTools_ListIteratorOfListOfShape anIt(myNewFaces);
190   for(; anIt.More(); anIt.Next()) {
191     aBB.Add(aFCompound, anIt.Value());
192   }
193   //
194   // 2.
195   TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
196   TopTools_IndexedMapOfShape aProcessedEdges;
197   
198   TopExp::MapShapesAndAncestors(aFCompound, TopAbs_EDGE, TopAbs_FACE, aEFMap);
199   aNb=aEFMap.Extent();
200   for (i=1; i<=aNb; i++) {
201     const TopoDS_Shape& aE=aEFMap.FindKey(i);
202     TopTools_IndexedMapOfShape aFaces;
203     Path (aE, aEFMap, aFaces, aProcessedEdges);
204     
205     TopoDS_Shell aShell, aShellNew;
206     aBB.MakeShell(aShell);
207     
208     aNbFaces=aFaces.Extent();
209     if (aNbFaces) {
210       for (j=1; j<=aNbFaces; j++) {
211         const TopoDS_Shape& aF=aFaces(j);
212         aBB.Add(aShell, aF);
213       }
214
215       OrientFacesOnShell(aShell, aShellNew);
216
217       aBB.Add(aRes, aShellNew);
218     }
219   }
220   myResult=aRes;
221
222 //=======================================================================
223 // function: DoNewFaces
224 // purpose: 
225 //=======================================================================
226   void BOP_ShellShell::DoNewFaces() 
227 {
228   const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
229   BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
230   BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
231   //
232   // vars
233   Standard_Boolean bIsTouchCase, bIsTouch;
234   Standard_Integer i, aNb, j, aNbj, iFF, nF1, iRank;
235   TopTools_ListOfShape aListOfNewFaces;
236   TopTools_IndexedMapOfShape anEMap;
237   TopAbs_Orientation anOriF1;
238   //
239   // DoMap
240   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
241   BOP_BuilderTools::DoMap(aFFs, aFFMap);
242   //
243   aNb=aFFMap.Extent();
244   //
245   for (i=1; i<=aNb; i++) {
246     // 
247     // a. Prepare info about the Face nF1 and create WES for nF1
248     nF1=aFFMap.FindKey(i);
249     const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
250     
251     anOriF1=aF1.Orientation();
252     iRank=aDS.Rank(nF1);
253     
254     myFace=aF1;
255     myFace.Orientation(TopAbs_FORWARD);
256     BOP_WireEdgeSet aWES (myFace);
257     
258     const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i);
259     aNbj=aFFIndicesMap.Extent();
260     // 
261     // b. The Switch: Same Domain Faces or Non-Same Domain Faces 
262     bIsTouchCase=Standard_False;
263     for (j=1; j<=aNbj; j++) {
264       iFF=aFFIndicesMap(j);
265       BOPTools_SSInterference& aFF=aFFs(iFF);
266       bIsTouchCase=aFF.IsTangentFaces();
267       if (bIsTouchCase) {
268         break;
269       }
270     }
271     //
272     // c. Filling the WES for nF1
273     if (bIsTouchCase) { 
274       // 1. Add Split Parts having states in accordance with operation
275       AddSplitPartsINOUT (nF1, aWES);
276       // 2. Add Section Edges to the WES 
277       for (j=1; j<=aNbj; j++) {
278         iFF=aFFIndicesMap(j);
279         BOPTools_SSInterference& aFF=aFFs(iFF);
280         bIsTouch=aFF.IsTangentFaces();
281         if (!bIsTouch) {
282           AddSectionPartsSh(nF1, iFF, aWES);
283         }
284       }
285       // 3. Add IN2D, ON2D Parts to the WES 
286       for (j=1; j<=aNbj; j++) {
287         iFF=aFFIndicesMap(j);
288         BOPTools_SSInterference& aFF=aFFs(iFF);
289         bIsTouch=aFF.IsTangentFaces();
290         if (bIsTouch) {
291           Standard_Integer nF2;
292           nF2=aFF.OppositeIndex(nF1);
293           AddINON2DPartsSh(nF1, iFF, aWES);
294         }
295       }
296       // 4. Add EF parts (E (from F2) on F1 ),
297       // where F2 is non-same-domain face to F1
298       anEMap.Clear();
299       //
300       // anEMap will contain all Split parts that has already in aWES
301       const TopTools_ListOfShape& aLE=aWES.StartElements();
302
303       Standard_Integer aNbEdges1 = aLE.Extent();
304
305       TopTools_ListIteratorOfListOfShape anIt;
306       anIt.Initialize (aLE);
307       for (; anIt.More(); anIt.Next()) {
308         TopoDS_Shape& anE=anIt.Value();
309         anEMap.Add(anE);
310       }
311       //
312       // IFV's workaround for occ13538:
313       // It is necessary to avoid building SD faces twice in case if SD faces of object and tool
314       // fully coincide and face of object has adjacent faces along all boundaries.
315       // For such cases WES for second SD faces are built from EE edges.
316       // The sence of workarond is to find such situation by checking of number of EF edges.
317       // If number of EF edges == 0, it means that SD faces fully coincide.
318       Standard_Integer aNbEF;
319       for (j=1; j<=aNbj; j++) {
320         iFF=aFFIndicesMap(j);
321         BOPTools_SSInterference& aFF=aFFs(iFF);
322         bIsTouch=aFF.IsTangentFaces();
323         if (!bIsTouch) {
324           AddPartsEFNonSDSh (nF1, iFF, anEMap, aWES);
325         }
326       }
327       //
328       aNbEF = aWES.StartElements().Extent() - aNbEdges1;
329       //
330       if((aNbEdges1 > 0) && (aNbEF > 0)) {
331         for (j=1; j<=aNbj; j++) {
332           iFF=aFFIndicesMap(j);
333           BOPTools_SSInterference& aFF=aFFs(iFF);
334           bIsTouch=aFF.IsTangentFaces();
335           if (!bIsTouch) {
336             AddPartsEENonSDSh (nF1, iFF, anEMap, aWES);
337           }
338         }
339       }
340       // IFV's workaround for occ13538 - end
341       //
342     }// end of  if (bIsTouchCase)
343     else {
344       // 1. Add Split Parts having states in accordance with operation
345       AddSplitPartsINOUT (nF1, aWES);
346       // 2. Add Split Parts with state ON
347       AddSplitPartsONSh (nF1, aWES);
348       // 3. Add Section Edges to the WES 
349       for (j=1; j<=aNbj; j++) {
350         iFF=aFFIndicesMap(j);
351         AddSectionPartsSh(nF1, iFF, aWES);
352       }
353       // 4. Add EF parts (E (from F2) on F1 )
354       anEMap.Clear();
355       for (j=1; j<=aNbj; j++) {
356         iFF=aFFIndicesMap(j);
357         AddPartsEFSh(nF1, iFF, anEMap, aWES);
358       }
359     }// end of (bIsTouchCase)'s else
360     //
361     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
362     // Display the WES
363     if (myDraw)  {
364       const TopTools_ListOfShape& aWESL=aWES.StartElements();
365       BOP_Draw::DrawListOfEdgesWithPC (myFace, aWESL, i, "ew_"); 
366       BOP_Draw::Wait();
367     }
368     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
369
370     //
371     // d. Build new Faces from myFace
372     BOP_FaceBuilder aFB;
373     aFB.SetTreatment(0); // 0-Do Internal Edges
374     aFB.SetTreatSDScales(1);
375     aFB.Do(aWES);
376
377     const TopTools_ListOfShape& aLF=aFB.NewFaces();
378     // 
379     // e. Do Internal Vertices
380     // 
381     DoInternalVertices(nF1, aLF);
382     //
383     // f. Orient new faces
384     TopTools_ListOfShape aLFx;
385     TopTools_ListIteratorOfListOfShape anIt;
386     anIt.Initialize(aLF);
387     for (; anIt.More(); anIt.Next()) {
388       TopoDS_Shape& aFx=anIt.Value();
389       aFx.Orientation(anOriF1);
390       aListOfNewFaces.Append(aFx);
391       aLFx.Append(aFx);
392     }
393     //
394     // Fill "Modified"
395     FillModified(aF1, aLFx); 
396     //
397   }//  for (i=1; i<=aNb; i++)
398   //
399   //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
400   // Display the new Faces
401   if (myDraw) { 
402     BOP_Draw::DrawListOfShape(aListOfNewFaces, "fn_");
403   }
404   //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
405   myNewFaces.Clear();
406   myNewFaces.Append(aListOfNewFaces);
407 }