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