0021762: Integration of new Boolean Operation algorithm to OCCT.
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_5.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
11 //
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 //
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
21
22
23 #include <BOPAlgo_PaveFiller.ixx>
24
25 #include <NCollection_IncAllocator.hxx>
26
27 #include <Bnd_Box.hxx>
28
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <BRep_Tool.hxx>
33
34 #include <IntTools_EdgeFace.hxx>
35 #include <IntTools_Range.hxx>
36 #include <IntTools_SequenceOfCommonPrts.hxx>
37 #include <IntTools_CommonPrt.hxx>
38 #include <BOPTools_AlgoTools.hxx>
39
40 #include <BOPCol_MapOfInteger.hxx>
41
42 #include <BOPInt_Context.hxx>
43
44 #include <BOPDS_Interf.hxx>
45 #include <BOPDS_Iterator.hxx>
46 #include <BOPDS_PaveBlock.hxx>
47 #include <BOPDS_MapOfPaveBlock.hxx>
48 #include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
49 #include <BOPDS_CommonBlock.hxx>
50 #include <BOPDS_Pave.hxx>
51
52 #include <BOPTools_AlgoTools.hxx>
53 #include <BOPDS_CoupleOfPaveBlocks.hxx>
54 #include <BRepBndLib.hxx>
55 #include <BOPAlgo_Tools.hxx>
56 #include <BOPInt_Tools.hxx>
57 #include <BRepAdaptor_Curve.hxx>
58 #include <BRep_Builder.hxx>
59
60
61 //=======================================================================
62 //function : PerformEF
63 //purpose  : 
64 //=======================================================================
65   void BOPAlgo_PaveFiller::PerformEF()
66 {
67   Standard_Integer iSize;
68   //
69   myErrorStatus=0;
70   //
71   myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
72   iSize=myIterator->ExpectedLength();
73   if (!iSize) {
74     return; 
75   }
76   //----------------------------------------------------------------------
77   Standard_Boolean bJustAdd;
78   Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX;
79   Standard_Real aTolE, aTolF, aTS1, aTS2, aDeflection;
80   Handle(NCollection_IncAllocator) aAllocator;
81   TopAbs_ShapeEnum aType;
82   BOPDS_ListIteratorOfListOfPaveBlock aIt;
83   //-----------------------------------------------------scope f
84   //
85   BRep_Builder aBB;
86   //
87   aAllocator=new NCollection_IncAllocator();
88   
89   BOPCol_MapOfInteger aMIEFC(100, aAllocator);
90   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
91   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
92   //
93   aDiscretize=35;
94   aDeflection=0.01;
95   //
96   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
97   aEFs.SetStartSize(iSize);
98   aEFs.SetIncrement(iSize);
99   aEFs.Init();
100   //
101   for (; myIterator->More(); myIterator->Next()) {
102     myIterator->Value(nE, nF, bJustAdd);
103     if(bJustAdd) {
104       continue;
105     }
106     //
107     const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
108     if (aSIE.HasFlag()){//degenerated 
109       continue;
110     }
111     //
112     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
113     const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
114     const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box(); 
115     //
116     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
117     const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
118     const BOPCol_MapOfInteger& aMIFOn=aFI.VerticesOn();
119     const BOPCol_MapOfInteger& aMIFIn=aFI.VerticesIn();
120     //
121     aTolE=BRep_Tool::Tolerance(aE);
122     aTolF=BRep_Tool::Tolerance(aF);
123     //
124     BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
125     aIt.Initialize(aLPB);
126     for (; aIt.More(); aIt.Next()) {
127       Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
128       //
129       const Handle(BOPDS_PaveBlock)& aPBR=aPB->RealPaveBlock();
130       if (aMPBF.Contains(aPBR)) {
131         continue;
132       }
133       //
134       if (!aPB->HasShrunkData()) {
135         FillShrunkData(aPB);
136         if (myWarningStatus) {
137           continue;
138         }
139       }
140       //
141       Bnd_Box aBBE;
142       aPB->ShrunkData(aTS1, aTS2, aBBE);
143       //
144       if (aBBF.IsOut (aBBE)) {
145         continue;
146       }
147       //
148       // -----------f
149       IntTools_EdgeFace aEdgeFace;
150       //
151       aEdgeFace.SetEdge (aE);
152       aEdgeFace.SetFace (aF);
153       aEdgeFace.SetTolE (aTolE);
154       aEdgeFace.SetTolF (aTolF);
155       aEdgeFace.SetDiscretize (aDiscretize);
156       aEdgeFace.SetDeflection (aDeflection);
157       aEdgeFace.SetContext(myContext);
158       //
159       IntTools_Range aSR(aTS1, aTS2);
160       IntTools_Range anewSR=aSR;
161       //
162       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
163       aEdgeFace.SetRange (anewSR);
164       //
165       aEdgeFace.Perform();
166       if (!aEdgeFace.IsDone()) {
167         continue;
168       }
169       //
170       const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
171       aNbCPrts=aCPrts.Length();
172       for (i=1; i<=aNbCPrts; ++i) {
173         const IntTools_CommonPrt& aCPart=aCPrts(i);
174         aType=aCPart.Type();
175         switch (aType) {
176         case TopAbs_VERTEX:  {
177           Standard_Boolean bIsOnPave1, bIsOnPave2, bV1, bV2;
178           Standard_Integer nV1, nV2;
179           Standard_Real aT, aTolToDecide; 
180           TopoDS_Vertex aVnew;
181           
182           BOPInt_Tools::VertexParameter(aCPart, aT);
183           BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
184           //
185           const IntTools_Range& aR=aCPart.Range1();
186           aTolToDecide=5.e-8;
187           bIsOnPave1=BOPInt_Tools::IsOnPave1(anewSR.First(), aR, aTolToDecide); 
188           bIsOnPave2=BOPInt_Tools::IsOnPave1(anewSR.Last() , aR, aTolToDecide); 
189           //
190           aPB->Indices(nV1, nV2);
191           //
192
193           if (bIsOnPave1 && bIsOnPave2) {
194             bV1=CheckFacePaves(nV1, aMIFOn, aMIFIn);
195             bV2=CheckFacePaves(nV2, aMIFOn, aMIFIn);
196             if (bV1 && bV2) {
197               iX=aEFs.Append()-1;
198               IntTools_CommonPrt aCP = aCPart;
199               aCP.SetType(TopAbs_EDGE);
200               BOPDS_InterfEF& aEF=aEFs(iX);
201               aEF.SetIndices(nE, nF);
202               aEF.SetCommonPart(aCP);
203               myDS->AddInterf(nE, nF);
204               // 3          
205               BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
206               break;
207             }
208           }
209           if (bIsOnPave1) {
210             bV1=CheckFacePaves(nV1, aMIFOn, aMIFIn);
211             if (bV1) {
212               const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
213               BOPTools_AlgoTools::UpdateVertex(aE, aT, aV);
214               BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
215               Bnd_Box& aBoxDS=aSIDS.ChangeBox();
216               BRepBndLib::Add(aV, aBoxDS);
217               continue;
218             }
219             bIsOnPave1=!bIsOnPave1;
220           }
221           //
222           if (bIsOnPave2) {
223             bV2=CheckFacePaves(nV2, aMIFOn, aMIFIn);
224             if (bV2) {
225               const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
226               BOPTools_AlgoTools::UpdateVertex(aE, aT, aV);
227               BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV2);
228               Bnd_Box& aBoxDS=aSIDS.ChangeBox();
229               BRepBndLib::Add(aV, aBoxDS);
230               continue;
231             }
232             bIsOnPave2=!bIsOnPave2;
233           }
234           //
235           if (!bIsOnPave1 && !bIsOnPave2) {
236             if (CheckFacePaves(aVnew, aMIFOn)) {
237               continue;
238             }
239             aBB.UpdateVertex(aVnew, aTolE);
240             //
241             aMIEFC.Add(nF);
242             // 1
243             iX=aEFs.Append()-1;
244             BOPDS_InterfEF& aEF=aEFs(iX);
245             aEF.SetIndices(nE, nF);
246             aEF.SetCommonPart(aCPart);
247             // 2
248             myDS->AddInterf(nE, nF);
249             // 3
250             BOPDS_CoupleOfPaveBlocks aCPB;
251             //
252             aCPB.SetPaveBlocks(aPB, aPB);
253             aCPB.SetIndexInterf(iX);
254             aMVCPB.Add(aVnew, aCPB);
255           }
256         }
257           break;
258         case TopAbs_EDGE:  {
259           aMIEFC.Add(nF);
260           //
261           // 1
262           iX=aEFs.Append()-1;
263           BOPDS_InterfEF& aEF=aEFs(iX);
264           aEF.SetIndices(nE, nF);
265           //
266           Standard_Boolean aCoinsideFlag;
267           aCoinsideFlag=BOPTools_AlgoTools::IsBlockInOnFace(anewSR, aF, aE, myContext);
268           if (!aCoinsideFlag) {
269             myDS->AddInterf(nE, nF);
270             break;
271           }
272           //update tolerance of edge if needed
273           if (aTolE < aTolF) {
274             myDS->UpdateEdgeTolerance(nE, aTolF);
275             aTolE = aTolF;
276           }
277           aEF.SetCommonPart(aCPart);
278           // 2
279           myDS->AddInterf(nE, nF);
280           // 3
281           BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
282           
283         }
284           break; 
285         default:
286           break; 
287         }//switch (aType) {
288       }//for (i=1; i<=aNbCPrts; ++i) {
289       // -----------t
290     }//for (; aIt.More(); aIt.Next()) {
291   }//for (; myIterator->More(); myIterator->Next()) {
292   // 
293   //=========================================
294   // post treatment
295   //=========================================
296   BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator);
297   PerformVerticesEF(aMVCPB, aAllocator);
298   //
299   // Update FaceInfoIn for all faces having EF common parts
300   BOPCol_MapIteratorOfMapOfInteger aItMI;
301   aItMI.Initialize(aMIEFC);
302   for (; aItMI.More(); aItMI.Next()) {
303     nF=aItMI.Value();
304     myDS->UpdateFaceInfoIn(nF);
305   }
306   // Refine FaceInfoOn to remove all formal pave blocks 
307   // made during EF processing 
308   //myDS->RefineFaceInfoOn();
309   //-----------------------------------------------------scope t
310   aMIEFC.Clear();
311   aMVCPB.Clear();
312   aMPBLI.Clear();
313   aAllocator.Nullify();
314   //
315   
316 }
317 //=======================================================================
318 //function : PerformVertices1
319 //purpose  : 
320 //=======================================================================
321   Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
322     (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
323      Handle(NCollection_BaseAllocator)& theAllocator)
324 {
325   Standard_Integer aNbV, iRet;
326   //
327   iRet=0;
328   aNbV=theMVCPB.Extent();
329   if (!aNbV) {
330     return iRet;
331   }
332   //
333   Standard_Integer nVx, nVSD, iV, iErr, nE, iFlag, iX, i, aNbPBLI;
334   Standard_Real aT;
335   TopoDS_Shape aV;
336   BOPCol_ListIteratorOfListOfShape aItLS;
337   BOPCol_ListIteratorOfListOfInteger aItLI;
338   BOPDS_PDS aPDS;
339   BOPDS_ShapeInfo aSI;
340   BOPDS_Pave aPave;
341   //
342   BOPCol_ListOfShape aLS(theAllocator);
343   BOPCol_DataMapOfShapeInteger aMVI(100, theAllocator);
344   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
345   BOPAlgo_PaveFiller aPF(theAllocator); 
346   //
347   aSI.SetShapeType(TopAbs_VERTEX);
348   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
349   //
350   // 1 prepare arguments
351   for (i=1; i<=aNbV; ++i) {
352     const TopoDS_Shape& aS=theMVCPB.FindKey(i);
353     aLS.Append(aS);
354   }
355   //
356   // 2 Fuse vertices
357   aPF.SetArguments(aLS);
358   aPF.Perform();
359   iErr=aPF.ErrorStatus();
360   if (iErr) {
361     iRet=1;
362     return iRet;
363   }
364   aPDS=aPF.PDS();
365   //
366   // 3 Add new vertices to theDS; 
367   // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
368   aItLS.Initialize(aLS);
369   for (; aItLS.More(); aItLS.Next()) {
370     const TopoDS_Shape& aVx=aItLS.Value();
371     nVx=aPDS->Index(aVx);
372     //
373     if (aPDS->HasShapeSD(nVx, nVSD)) {
374       aV=aPDS->Shape(nVSD);
375     }
376     else {
377       aV=aVx;
378     }
379     // index of new vertex in theDS -> iV
380     if (!aMVI.IsBound(aV)) {
381       aSI.SetShape(aV);
382       iV=myDS->Append(aSI);
383       //
384       BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
385       Bnd_Box& aBox=aSIDS.ChangeBox();
386       BRepBndLib::Add(aV, aBox);
387       //
388       aMVI.Bind(aV, iV);
389     }
390     else {
391       iV=aMVI.Find(aV);
392     }
393     //
394     BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
395     aCPB.SetIndex(iV);
396     // update EF interference
397     iX=aCPB.IndexInterf();
398     BOPDS_InterfEF& aEF=aEFs(iX);
399     aEF.SetIndexNew(iV);
400     // map aMPBLI
401     const Handle(BOPDS_PaveBlock)& aPB=aCPB.PaveBlock1();
402     if (aMPBLI.Contains(aPB)) {
403       BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
404       aLI.Append(iV);
405     }
406     else {
407       BOPCol_ListOfInteger aLI(theAllocator);
408       aLI.Append(iV);
409       aMPBLI.Add(aPB, aLI);
410     }
411   }
412   //
413   // 5 
414   // 5.1  Compute Extra Paves and 
415   // 5.2. Add Extra Paves to the PaveBlocks
416   aNbPBLI=aMPBLI.Extent();
417   for (i=1; i<=aNbPBLI; ++i) {
418     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
419     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
420     nE=aPB->OriginalEdge();
421     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
422     // 
423     aItLI.Initialize(aLI);
424     for (; aItLI.More(); aItLI.Next()) {
425       nVx=aItLI.Value();
426       const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
427       //
428       iFlag=myContext->ComputeVE (aVx, aE, aT);
429       if (!iFlag) {
430         aPave.SetIndex(nVx);
431         aPave.SetParameter(aT);
432         aPB->AppendExtPave(aPave);
433       }
434     }
435   }
436   // 6  Split PaveBlocksa
437   for (i=1; i<=aNbPBLI; ++i) {
438     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
439     nE=aPB->OriginalEdge();
440     // 3
441     if (!aPB->IsCommonBlock()) {
442       myDS->UpdatePaveBlock(aPB);
443     }
444     else {
445       const Handle(BOPDS_CommonBlock)& aCB=aPB->CommonBlock();
446       myDS->UpdateCommonBlock(aCB);
447     }    
448   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
449   // 
450   return iRet;
451 }
452 //=======================================================================
453 // function: CheckFacePaves
454 // purpose: 
455 //=======================================================================
456   Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves (const Standard_Integer nVx,
457                                                        const BOPCol_MapOfInteger& aMIFOn,
458                                                        const BOPCol_MapOfInteger& aMIFIn)
459 {
460   Standard_Boolean bRet;
461   Standard_Integer nV;
462   BOPCol_MapIteratorOfMapOfInteger aIt;
463   //
464   bRet=Standard_False;
465   //
466   aIt.Initialize(aMIFOn);
467   for (; aIt.More(); aIt.Next()) {
468     nV=aIt.Value();
469     if (nV==nVx) {
470       bRet=!bRet;
471       return bRet;
472     }
473   }
474   aIt.Initialize(aMIFIn);
475   for (; aIt.More(); aIt.Next()) {
476     nV=aIt.Value();
477     if (nV==nVx) {
478       bRet=!bRet;
479       return bRet;
480     }
481   }
482   //
483   return bRet;
484 }
485 //=======================================================================
486 // function: CheckFacePaves
487 // purpose: 
488 //=======================================================================
489   Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves (const TopoDS_Vertex& aVnew,
490                                                        const BOPCol_MapOfInteger& aMIF)
491 {
492   Standard_Boolean bRet;
493   Standard_Integer nV, iFlag;
494   BOPCol_MapIteratorOfMapOfInteger aIt;
495   //
496   bRet=Standard_True;
497   //
498   aIt.Initialize(aMIF);
499   for (; aIt.More(); aIt.Next()) {
500     nV=aIt.Value();
501     const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
502     iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
503     if (!iFlag) {
504       return bRet;
505     }
506   }
507   //
508   return !bRet;
509 }