0024624: Lost word in license statement in source files
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_5.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 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 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17
18 #include <BOPAlgo_PaveFiller.ixx>
19
20 #include <NCollection_IncAllocator.hxx>
21
22 #include <Bnd_Box.hxx>
23
24 #include <TopoDS_Vertex.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Face.hxx>
27 #include <BRep_Tool.hxx>
28
29 #include <IntTools_EdgeFace.hxx>
30 #include <IntTools_Range.hxx>
31 #include <IntTools_SequenceOfCommonPrts.hxx>
32 #include <IntTools_CommonPrt.hxx>
33 #include <BOPTools_AlgoTools.hxx>
34
35 #include <BOPCol_MapOfInteger.hxx>
36
37 #include <BOPInt_Context.hxx>
38
39 #include <BOPDS_Interf.hxx>
40 #include <BOPDS_Iterator.hxx>
41 #include <BOPDS_PaveBlock.hxx>
42 #include <BOPDS_MapOfPaveBlock.hxx>
43 #include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
44 #include <BOPDS_CommonBlock.hxx>
45 #include <BOPDS_Pave.hxx>
46
47 #include <BOPTools_AlgoTools.hxx>
48 #include <BOPDS_CoupleOfPaveBlocks.hxx>
49 #include <BRepBndLib.hxx>
50 #include <BOPAlgo_Tools.hxx>
51 #include <BOPInt_Tools.hxx>
52 #include <BRepAdaptor_Curve.hxx>
53 #include <BRep_Builder.hxx>
54 #include <GeomAPI_ProjectPointOnSurf.hxx>
55
56
57 //=======================================================================
58 //function : PerformEF
59 //purpose  : 
60 //=======================================================================
61   void BOPAlgo_PaveFiller::PerformEF()
62 {
63   Standard_Integer iSize;
64   //
65   myErrorStatus=0;
66   //
67   myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
68   iSize=myIterator->ExpectedLength();
69   if (!iSize) {
70     return; 
71   }
72   //----------------------------------------------------------------------
73   Standard_Boolean bJustAdd, bV[2];
74   Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2];
75   Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
76   Handle(NCollection_IncAllocator) aAllocator;
77   TopAbs_ShapeEnum aType;
78   BOPDS_ListIteratorOfListOfPaveBlock aIt;
79   //-----------------------------------------------------scope f
80   //
81   BRep_Builder aBB;
82   //
83   aAllocator=new NCollection_IncAllocator();
84   
85   BOPCol_MapOfInteger aMIEFC(100, aAllocator);
86   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
87   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
88   //
89   aDiscretize=35;
90   aDeflection=0.01;
91   //
92   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
93   aEFs.SetStartSize(iSize);
94   aEFs.SetIncrement(iSize);
95   aEFs.Init();
96   //
97   for (; myIterator->More(); myIterator->Next()) {
98     myIterator->Value(nE, nF, bJustAdd);
99     if(bJustAdd) {
100       continue;
101     }
102     //
103     const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
104     if (aSIE.HasFlag()){//degenerated 
105       continue;
106     }
107     //
108     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
109     const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
110     const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box(); 
111     //
112     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
113     const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
114     const BOPCol_MapOfInteger& aMIFOn=aFI.VerticesOn();
115     const BOPCol_MapOfInteger& aMIFIn=aFI.VerticesIn();
116     //
117     aTolE=BRep_Tool::Tolerance(aE);
118     aTolF=BRep_Tool::Tolerance(aF);
119     //
120     BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
121     aIt.Initialize(aLPB);
122     for (; aIt.More(); aIt.Next()) {
123       Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
124       //
125       const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
126       if (aMPBF.Contains(aPBR)) {
127         continue;
128       }
129       //
130       if (!aPB->HasShrunkData()) {
131         FillShrunkData(aPB);
132         if (myWarningStatus) {
133           continue;
134         }
135       }
136       //
137       Bnd_Box aBBE;
138       aPB->ShrunkData(aTS1, aTS2, aBBE);
139       //
140       if (aBBF.IsOut (aBBE)) {
141         continue;
142       }
143       //
144       // -----------f
145       IntTools_EdgeFace aEdgeFace;
146       //
147       aEdgeFace.SetEdge (aE);
148       aEdgeFace.SetFace (aF);
149       aEdgeFace.SetTolE (aTolE);
150       aEdgeFace.SetTolF (aTolF);
151       aEdgeFace.SetDiscretize (aDiscretize);
152       aEdgeFace.SetDeflection (aDeflection);
153       aEdgeFace.SetContext(myContext);
154       //
155       IntTools_Range aSR(aTS1, aTS2);
156       IntTools_Range anewSR=aSR;
157       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
158       //
159       aPB->Range(aT1, aT2);
160       IntTools_Range aPBRange(aT1, aT2);
161       aSR = aPBRange;
162       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
163       //
164       aEdgeFace.SetRange (aPBRange);
165       //
166       aEdgeFace.Perform();
167       if (!aEdgeFace.IsDone()) {
168         continue;
169       }
170       //
171       aPB->Indices(nV[0], nV[1]);
172       //
173       const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
174       aNbCPrts=aCPrts.Length();
175       for (i=1; i<=aNbCPrts; ++i) {
176         const IntTools_CommonPrt& aCPart=aCPrts(i);
177         aType=aCPart.Type();
178         switch (aType) {
179         case TopAbs_VERTEX:  {
180           Standard_Boolean bIsOnPave[2];
181           Standard_Integer j;
182           Standard_Real aT, aTolToDecide; 
183           TopoDS_Vertex aVnew;
184           
185           BOPInt_Tools::VertexParameter(aCPart, aT);
186           BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
187           //
188           const IntTools_Range& aR=aCPart.Range1();
189           aTolToDecide=5.e-8;
190           //
191           IntTools_Range aR1(aT1, anewSR.First()), aR2(anewSR.Last(), aT2);
192           //
193           bIsOnPave[0]=BOPInt_Tools::IsInRange(aR1, aR, aTolToDecide); 
194           bIsOnPave[1]=BOPInt_Tools::IsInRange(aR2, aR, aTolToDecide); 
195           //
196           if (bIsOnPave[0] && bIsOnPave[1]) {
197             bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
198             bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
199             if (bV[0] && bV[1]) {
200               iX=aEFs.Append()-1;
201               IntTools_CommonPrt aCP = aCPart;
202               aCP.SetType(TopAbs_EDGE);
203               BOPDS_InterfEF& aEF=aEFs(iX);
204               aEF.SetIndices(nE, nF);
205               aEF.SetCommonPart(aCP);
206               myDS->AddInterf(nE, nF);
207               // 3          
208               BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
209               break;
210             }
211           }
212           for (j=0; j<2; ++j) {
213             if (bIsOnPave[j]) {
214               bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
215               if (bV[j]) {
216                 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
217                 BOPTools_AlgoTools::UpdateVertex(aE, aT, aV);
218                 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV[j]);
219                 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
220                 BRepBndLib::Add(aV, aBoxDS);
221               }
222               else {
223                 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
224               }
225             }
226           }
227           //
228           if (!bIsOnPave[0] && !bIsOnPave[1]) {
229             if (CheckFacePaves(aVnew, aMIFOn)) {
230               continue;
231             }
232             //
233             const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
234             if (!myContext->IsValidPointForFace(aPnew, aF, aTolE+aTolF)) {
235               continue;
236             }
237             //
238             aBB.UpdateVertex(aVnew, aTolE);
239             //
240             aMIEFC.Add(nF);
241             // 1
242             iX=aEFs.Append()-1;
243             BOPDS_InterfEF& aEF=aEFs(iX);
244             aEF.SetIndices(nE, nF);
245             aEF.SetCommonPart(aCPart);
246             // 2
247             myDS->AddInterf(nE, nF);
248             // 3
249             BOPDS_CoupleOfPaveBlocks aCPB;
250             //
251             aCPB.SetPaveBlocks(aPB, aPB);
252             aCPB.SetIndexInterf(iX);
253             aMVCPB.Add(aVnew, aCPB);
254           }
255         }
256           break;
257         case TopAbs_EDGE:  {
258           aMIEFC.Add(nF);
259           //
260           // 1
261           iX=aEFs.Append()-1;
262           BOPDS_InterfEF& aEF=aEFs(iX);
263           aEF.SetIndices(nE, nF);
264           //
265           bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
266           bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
267           if (!bV[0] || !bV[1]) {
268             myDS->AddInterf(nE, nF);
269             break;
270           }
271           //update tolerance of edge if needed
272           if (aTolE < aTolF) {
273             myDS->UpdateEdgeTolerance(nE, aTolF);
274             aTolE = aTolF;
275           }
276           aEF.SetCommonPart(aCPart);
277           // 2
278           myDS->AddInterf(nE, nF);
279           // 3
280           BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
281           
282         }
283           break; 
284         default:
285           break; 
286         }//switch (aType) {
287       }//for (i=1; i<=aNbCPrts; ++i) {
288       // -----------t
289     }//for (; aIt.More(); aIt.Next()) {
290   }//for (; myIterator->More(); myIterator->Next()) {
291   // 
292   //=========================================
293   // post treatment
294   //=========================================
295   BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
296   PerformVerticesEF(aMVCPB, aAllocator);
297   //
298   // Update FaceInfoIn for all faces having EF common parts
299   BOPCol_MapIteratorOfMapOfInteger aItMI;
300   aItMI.Initialize(aMIEFC);
301   for (; aItMI.More(); aItMI.Next()) {
302     nF=aItMI.Value();
303     myDS->UpdateFaceInfoIn(nF);
304   }
305   // Refine FaceInfoOn to remove all formal pave blocks 
306   // made during EF processing 
307   //myDS->RefineFaceInfoOn();
308   //-----------------------------------------------------scope t
309   aMIEFC.Clear();
310   aMVCPB.Clear();
311   aMPBLI.Clear();
312   aAllocator.Nullify();
313   //
314   
315 }
316 //=======================================================================
317 //function : PerformVertices1
318 //purpose  : 
319 //=======================================================================
320   Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
321     (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
322      Handle(NCollection_BaseAllocator)& theAllocator)
323 {
324   Standard_Integer aNbV, iRet;
325   //
326   iRet=0;
327   aNbV=theMVCPB.Extent();
328   if (!aNbV) {
329     return iRet;
330   }
331   //
332   Standard_Integer nVx, nVSD, iV, iErr, nE, iFlag, iX, i, aNbPBLI;
333   Standard_Real aT;
334   TopoDS_Shape aV;
335   BOPCol_ListIteratorOfListOfShape aItLS;
336   BOPCol_ListIteratorOfListOfInteger aItLI;
337   BOPDS_PDS aPDS;
338   BOPDS_ShapeInfo aSI;
339   BOPDS_Pave aPave;
340   //
341   BOPCol_ListOfShape aLS(theAllocator);
342   BOPCol_DataMapOfShapeInteger aMVI(100, theAllocator);
343   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
344   BOPAlgo_PaveFiller aPF(theAllocator); 
345   //
346   aSI.SetShapeType(TopAbs_VERTEX);
347   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
348   //
349   // 1 prepare arguments
350   for (i=1; i<=aNbV; ++i) {
351     const TopoDS_Shape& aS=theMVCPB.FindKey(i);
352     aLS.Append(aS);
353   }
354   //
355   // 2 Fuse vertices
356   aPF.SetArguments(aLS);
357   aPF.Perform();
358   iErr=aPF.ErrorStatus();
359   if (iErr) {
360     iRet=1;
361     return iRet;
362   }
363   aPDS=aPF.PDS();
364   //
365   // 3 Add new vertices to theDS; 
366   // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
367   aItLS.Initialize(aLS);
368   for (; aItLS.More(); aItLS.Next()) {
369     const TopoDS_Shape& aVx=aItLS.Value();
370     nVx=aPDS->Index(aVx);
371     //
372     if (aPDS->HasShapeSD(nVx, nVSD)) {
373       aV=aPDS->Shape(nVSD);
374     }
375     else {
376       aV=aVx;
377     }
378     // index of new vertex in theDS -> iV
379     if (!aMVI.IsBound(aV)) {
380       aSI.SetShape(aV);
381       iV=myDS->Append(aSI);
382       //
383       BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
384       Bnd_Box& aBox=aSIDS.ChangeBox();
385       BRepBndLib::Add(aV, aBox);
386       //
387       aMVI.Bind(aV, iV);
388     }
389     else {
390       iV=aMVI.Find(aV);
391     }
392     //
393     BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
394     aCPB.SetIndex(iV);
395     // update EF interference
396     iX=aCPB.IndexInterf();
397     BOPDS_InterfEF& aEF=aEFs(iX);
398     aEF.SetIndexNew(iV);
399     // map aMPBLI
400     const Handle(BOPDS_PaveBlock)& aPB=aCPB.PaveBlock1();
401     if (aMPBLI.Contains(aPB)) {
402       BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
403       aLI.Append(iV);
404     }
405     else {
406       BOPCol_ListOfInteger aLI(theAllocator);
407       aLI.Append(iV);
408       aMPBLI.Add(aPB, aLI);
409     }
410   }
411   //
412   // 5 
413   // 5.1  Compute Extra Paves and 
414   // 5.2. Add Extra Paves to the PaveBlocks
415   aNbPBLI=aMPBLI.Extent();
416   for (i=1; i<=aNbPBLI; ++i) {
417     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
418     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
419     nE=aPB->OriginalEdge();
420     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
421     // 
422     aItLI.Initialize(aLI);
423     for (; aItLI.More(); aItLI.Next()) {
424       nVx=aItLI.Value();
425       const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
426       //
427       iFlag=myContext->ComputeVE (aVx, aE, aT);
428       if (!iFlag) {
429         aPave.SetIndex(nVx);
430         aPave.SetParameter(aT);
431         aPB->AppendExtPave(aPave);
432       }
433     }
434   }
435   // 6  Split PaveBlocksa
436   for (i=1; i<=aNbPBLI; ++i) {
437     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
438     nE=aPB->OriginalEdge();
439     // 3
440     if (!myDS->IsCommonBlock(aPB)) {
441       myDS->UpdatePaveBlock(aPB);
442     }
443     else {
444       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
445       myDS->UpdateCommonBlock(aCB);
446     }    
447   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
448   // 
449   return iRet;
450 }
451 //=======================================================================
452 // function: CheckFacePaves
453 // purpose: 
454 //=======================================================================
455   Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves (const Standard_Integer nVx,
456                                                        const BOPCol_MapOfInteger& aMIFOn,
457                                                        const BOPCol_MapOfInteger& aMIFIn)
458 {
459   Standard_Boolean bRet;
460   Standard_Integer nV;
461   BOPCol_MapIteratorOfMapOfInteger aIt;
462   //
463   bRet=Standard_False;
464   //
465   aIt.Initialize(aMIFOn);
466   for (; aIt.More(); aIt.Next()) {
467     nV=aIt.Value();
468     if (nV==nVx) {
469       bRet=!bRet;
470       return bRet;
471     }
472   }
473   aIt.Initialize(aMIFIn);
474   for (; aIt.More(); aIt.Next()) {
475     nV=aIt.Value();
476     if (nV==nVx) {
477       bRet=!bRet;
478       return bRet;
479     }
480   }
481   //
482   return bRet;
483 }
484 //=======================================================================
485 // function: CheckFacePaves
486 // purpose: 
487 //=======================================================================
488   Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves (const TopoDS_Vertex& aVnew,
489                                                        const BOPCol_MapOfInteger& aMIF)
490 {
491   Standard_Boolean bRet;
492   Standard_Integer nV, iFlag;
493   BOPCol_MapIteratorOfMapOfInteger aIt;
494   //
495   bRet=Standard_True;
496   //
497   aIt.Initialize(aMIF);
498   for (; aIt.More(); aIt.Next()) {
499     nV=aIt.Value();
500     const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
501     iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
502     if (!iFlag) {
503       return bRet;
504     }
505   }
506   //
507   return !bRet;
508 }
509 //=======================================================================
510 //function : ForceInterfVF
511 //purpose  : 
512 //=======================================================================
513 Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF(const Standard_Integer nV, 
514                                                    const Standard_Integer nF)
515 {
516   Standard_Boolean bRet;
517   //
518   bRet = Standard_False;
519   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
520   const TopoDS_Face&   aF = *(TopoDS_Face*)  &myDS->Shape(nF);
521   //
522   GeomAPI_ProjectPointOnSurf& aProj = myContext->ProjPS(aF);
523   const gp_Pnt& aP = BRep_Tool::Pnt(aV);
524   aProj.Perform(aP);
525   if (!aProj.IsDone()) {
526     return bRet;
527   }
528   Standard_Real aDist, U, V;
529   //
530   aDist=aProj.LowerDistance();
531   aProj.LowerDistanceParameters(U, V);
532   //
533   gp_Pnt2d aP2d(U, V);
534   bRet = myContext->IsPointInFace (aF, aP2d);
535   if (bRet) {
536     Standard_Integer i;
537     BRep_Builder aBB;
538     //
539     BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
540     i=aVFs.Append()-1;
541     BOPDS_InterfVF& aVF=aVFs(i);
542     aVF.SetIndices(nV, nF);
543     aVF.SetUV(U, V);
544     //
545     myDS->AddInterf(nV, nF);
546     //
547     aBB.UpdateVertex(aV, aDist);
548     BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
549     Bnd_Box& aBoxDS=aSIDS.ChangeBox();
550     BRepBndLib::Add(aV, aBoxDS);
551     //
552     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
553     BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
554     aMVIn.Add(nV);
555   }
556   //
557   return bRet;
558 }
559