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
7 // This file is part of Open CASCADE Technology software library.
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.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <BOPAlgo_PaveFiller.ixx>
20 #include <NCollection_IncAllocator.hxx>
22 #include <GeomAPI_ProjectPointOnSurf.hxx>
24 #include <Bnd_Box.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Face.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepBndLib.hxx>
31 #include <BRepAdaptor_Curve.hxx>
32 #include <BRep_Builder.hxx>
34 #include <IntTools_EdgeFace.hxx>
35 #include <IntTools_Range.hxx>
36 #include <IntTools_SequenceOfCommonPrts.hxx>
37 #include <IntTools_CommonPrt.hxx>
39 #include <BOPCol_MapOfInteger.hxx>
40 #include <BOPCol_NCVector.hxx>
41 #include <BOPCol_TBB.hxx>
43 #include <BOPInt_Context.hxx>
44 #include <BOPInt_Tools.hxx>
46 #include <BOPDS_Interf.hxx>
47 #include <BOPDS_Iterator.hxx>
48 #include <BOPDS_PaveBlock.hxx>
49 #include <BOPDS_MapOfPaveBlock.hxx>
50 #include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
51 #include <BOPDS_CommonBlock.hxx>
52 #include <BOPDS_Pave.hxx>
53 #include <BOPDS_CoupleOfPaveBlocks.hxx>
55 #include <BOPTools_AlgoTools.hxx>
57 #include <BOPAlgo_Tools.hxx>
59 //=======================================================================
60 //class : BOPAlgo_EdgeFace
62 //=======================================================================
63 class BOPAlgo_EdgeFace : public IntTools_EdgeFace {
66 : IntTools_EdgeFace(), myIE(-1), myIF(-1) {
72 void SetIndices(const Standard_Integer nE,
73 const Standard_Integer nF) {
78 void Indices(Standard_Integer& nE,
79 Standard_Integer& nF) {
84 void SetNewSR(const IntTools_Range& aR){
88 IntTools_Range& NewSR(){
92 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
96 Handle(BOPDS_PaveBlock)& PaveBlock() {
101 Standard_Integer myIE;
102 Standard_Integer myIF;
103 IntTools_Range myNewSR;
104 Handle(BOPDS_PaveBlock) myPB;
107 //=======================================================================
108 typedef BOPCol_NCVector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace;
110 typedef BOPCol_TBBContextFunctor
112 BOPAlgo_VectorOfEdgeFace,
113 Handle(BOPInt_Context),
114 BOPInt_Context> BOPAlgo_EdgeFaceFunctor;
116 typedef BOPCol_TBBContextCnt
117 <BOPAlgo_EdgeFaceFunctor,
118 BOPAlgo_VectorOfEdgeFace,
119 Handle(BOPInt_Context)> BOPAlgo_EdgeFaceCnt;
121 //=======================================================================
122 //function : PerformEF
124 //=======================================================================
125 void BOPAlgo_PaveFiller::PerformEF()
127 Standard_Integer iSize;
131 FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
133 myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
134 iSize=myIterator->ExpectedLength();
139 Standard_Boolean bJustAdd, bV[2];
140 Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2];
141 Standard_Integer aNbEdgeFace, k;
142 Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
143 Handle(NCollection_IncAllocator) aAllocator;
144 TopAbs_ShapeEnum aType;
145 BOPDS_ListIteratorOfListOfPaveBlock aIt;
146 BOPAlgo_VectorOfEdgeFace aVEdgeFace;
148 //-----------------------------------------------------scope f
150 ////aAllocator=new NCollection_IncAllocator();
152 BOPCol_MapOfInteger aMIEFC(100, aAllocator);
153 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
154 BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
159 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
160 aEFs.SetStartSize(iSize);
161 aEFs.SetIncrement(iSize);
164 for (; myIterator->More(); myIterator->Next()) {
165 myIterator->Value(nE, nF, bJustAdd);
170 const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
171 if (aSIE.HasFlag()){//degenerated
175 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
176 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
177 const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box();
179 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
180 const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
182 aTolE=BRep_Tool::Tolerance(aE);
183 aTolF=BRep_Tool::Tolerance(aF);
185 BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
186 aIt.Initialize(aLPB);
187 for (; aIt.More(); aIt.Next()) {
188 Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
190 const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
191 if (aMPBF.Contains(aPBR)) {
195 if (!aPB->HasShrunkData()) {
200 aPB->ShrunkData(aTS1, aTS2, aBBE);
202 if (aBBF.IsOut (aBBE)) {
206 BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Append1();
208 aEdgeFace.SetIndices(nE, nF);
209 aEdgeFace.SetPaveBlock(aPB);
211 aEdgeFace.SetEdge (aE);
212 aEdgeFace.SetFace (aF);
213 aEdgeFace.SetTolE (aTolE);
214 aEdgeFace.SetTolF (aTolF);
215 aEdgeFace.SetDiscretize (aDiscretize);
216 aEdgeFace.SetDeflection (aDeflection);
218 IntTools_Range aSR(aTS1, aTS2);
219 IntTools_Range anewSR=aSR;
220 BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
221 aEdgeFace.SetNewSR(anewSR);
223 aPB->Range(aT1, aT2);
224 IntTools_Range aPBRange(aT1, aT2);
226 BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
227 aEdgeFace.SetRange (aPBRange);
229 }//for (; aIt.More(); aIt.Next()) {
230 }//for (; myIterator->More(); myIterator->Next()) {
232 aNbEdgeFace=aVEdgeFace.Extent();
233 //=================================================================
234 BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
235 //=================================================================
237 for (k=0; k < aNbEdgeFace; ++k) {
238 BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
239 if (!aEdgeFace.IsDone()) {
243 aEdgeFace.Indices(nE, nF);
245 const TopoDS_Edge& aE=aEdgeFace.Edge();
246 const TopoDS_Face& aF=aEdgeFace.Face();
248 aTolE=aEdgeFace.TolE();
249 aTolF=aEdgeFace.TolF();
250 const IntTools_Range& anewSR=aEdgeFace.NewSR();
251 Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
253 aPB->Range(aT1, aT2);
254 aPB->Indices(nV[0], nV[1]);
256 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
257 ////const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
258 const BOPCol_MapOfInteger& aMIFOn=aFI.VerticesOn();
259 const BOPCol_MapOfInteger& aMIFIn=aFI.VerticesIn();
261 const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
262 aNbCPrts=aCPrts.Length();
263 for (i=1; i<=aNbCPrts; ++i) {
264 const IntTools_CommonPrt& aCPart=aCPrts(i);
267 case TopAbs_VERTEX: {
268 Standard_Boolean bIsOnPave[2];
270 Standard_Real aT, aTolToDecide;
273 BOPInt_Tools::VertexParameter(aCPart, aT);
274 BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
276 const IntTools_Range& aR=aCPart.Range1();
279 IntTools_Range aR1(aT1,anewSR.First()),aR2(anewSR.Last(), aT2);
281 bIsOnPave[0]=BOPInt_Tools::IsInRange(aR1, aR, aTolToDecide);
282 bIsOnPave[1]=BOPInt_Tools::IsInRange(aR2, aR, aTolToDecide);
284 if (bIsOnPave[0] && bIsOnPave[1]) {
285 bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
286 bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
287 if (bV[0] && bV[1]) {
289 IntTools_CommonPrt aCP = aCPart;
290 aCP.SetType(TopAbs_EDGE);
291 BOPDS_InterfEF& aEF=aEFs(iX);
292 aEF.SetIndices(nE, nF);
293 aEF.SetCommonPart(aCP);
294 myDS->AddInterf(nE, nF);
296 BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
300 for (j=0; j<2; ++j) {
302 bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
304 const TopoDS_Vertex& aV=
305 (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
306 BOPTools_AlgoTools::UpdateVertex(aE, aT, aV);
307 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV[j]);
308 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
309 BRepBndLib::Add(aV, aBoxDS);
312 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
317 if (!bIsOnPave[0] && !bIsOnPave[1]) {
318 if (CheckFacePaves(aVnew, aMIFOn)) {
322 const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
323 if (!myContext->IsValidPointForFace(aPnew,
329 aBB.UpdateVertex(aVnew, aTolE);
334 BOPDS_InterfEF& aEF=aEFs(iX);
335 aEF.SetIndices(nE, nF);
336 aEF.SetCommonPart(aCPart);
338 myDS->AddInterf(nE, nF);
340 BOPDS_CoupleOfPaveBlocks aCPB;
342 aCPB.SetPaveBlocks(aPB, aPB);
343 aCPB.SetIndexInterf(iX);
344 aMVCPB.Add(aVnew, aCPB);
353 BOPDS_InterfEF& aEF=aEFs(iX);
354 aEF.SetIndices(nE, nF);
356 bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
357 bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
358 if (!bV[0] || !bV[1]) {
359 myDS->AddInterf(nE, nF);
362 //update tolerance of edge if needed
364 myDS->UpdateEdgeTolerance(nE, aTolF);
367 aEF.SetCommonPart(aCPart);
369 myDS->AddInterf(nE, nF);
371 BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
378 }//for (i=1; i<=aNbCPrts; ++i) {
379 }// for (k=0; k < aNbEdgeEdge; ++k) {
381 //=========================================
383 //=========================================
384 BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
385 PerformVerticesEF(aMVCPB, aAllocator);
387 // Update FaceInfoIn for all faces having EF common parts
388 BOPCol_MapIteratorOfMapOfInteger aItMI;
389 aItMI.Initialize(aMIEFC);
390 for (; aItMI.More(); aItMI.Next()) {
392 myDS->UpdateFaceInfoIn(nF);
394 // Refine FaceInfoOn to remove all formal pave blocks
395 // made during EF processing
396 //myDS->RefineFaceInfoOn();
397 //-----------------------------------------------------scope t
401 ////aAllocator.Nullify();
403 //=======================================================================
404 //function : PerformVertices1
406 //=======================================================================
407 Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
408 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
409 Handle(NCollection_BaseAllocator)& theAllocator)
411 Standard_Integer aNbV, iRet;
414 aNbV=theMVCPB.Extent();
419 Standard_Integer nVx, nVSD, iV, iErr, nE, iFlag, iX, i, aNbPBLI;
422 BOPCol_ListIteratorOfListOfShape aItLS;
423 BOPCol_ListIteratorOfListOfInteger aItLI;
428 BOPCol_ListOfShape aLS(theAllocator);
429 BOPCol_DataMapOfShapeInteger aMVI(100, theAllocator);
430 BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
431 BOPAlgo_PaveFiller aPF(theAllocator);
433 aSI.SetShapeType(TopAbs_VERTEX);
434 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
436 // 1 prepare arguments
437 for (i=1; i<=aNbV; ++i) {
438 const TopoDS_Shape& aS=theMVCPB.FindKey(i);
443 aPF.SetArguments(aLS);
445 iErr=aPF.ErrorStatus();
452 // 3 Add new vertices to theDS;
453 // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
454 aItLS.Initialize(aLS);
455 for (; aItLS.More(); aItLS.Next()) {
456 const TopoDS_Shape& aVx=aItLS.Value();
457 nVx=aPDS->Index(aVx);
459 if (aPDS->HasShapeSD(nVx, nVSD)) {
460 aV=aPDS->Shape(nVSD);
465 // index of new vertex in theDS -> iV
466 if (!aMVI.IsBound(aV)) {
468 iV=myDS->Append(aSI);
470 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
471 Bnd_Box& aBox=aSIDS.ChangeBox();
472 BRepBndLib::Add(aV, aBox);
480 BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
482 // update EF interference
483 iX=aCPB.IndexInterf();
484 BOPDS_InterfEF& aEF=aEFs(iX);
487 const Handle(BOPDS_PaveBlock)& aPB=aCPB.PaveBlock1();
488 if (aMPBLI.Contains(aPB)) {
489 BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
493 BOPCol_ListOfInteger aLI(theAllocator);
495 aMPBLI.Add(aPB, aLI);
500 // 5.1 Compute Extra Paves and
501 // 5.2. Add Extra Paves to the PaveBlocks
502 aNbPBLI=aMPBLI.Extent();
503 for (i=1; i<=aNbPBLI; ++i) {
504 Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
505 const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
506 nE=aPB->OriginalEdge();
507 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
509 aItLI.Initialize(aLI);
510 for (; aItLI.More(); aItLI.Next()) {
512 const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
514 iFlag=myContext->ComputeVE (aVx, aE, aT);
517 aPave.SetParameter(aT);
518 aPB->AppendExtPave(aPave);
522 // 6 Split PaveBlocksa
523 for (i=1; i<=aNbPBLI; ++i) {
524 Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
525 nE=aPB->OriginalEdge();
527 if (!myDS->IsCommonBlock(aPB)) {
528 myDS->UpdatePaveBlock(aPB);
531 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
532 myDS->UpdateCommonBlock(aCB);
534 }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
538 //=======================================================================
539 // function: CheckFacePaves
541 //=======================================================================
542 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
543 (const Standard_Integer nVx,
544 const BOPCol_MapOfInteger& aMIFOn,
545 const BOPCol_MapOfInteger& aMIFIn)
547 Standard_Boolean bRet;
549 BOPCol_MapIteratorOfMapOfInteger aIt;
553 aIt.Initialize(aMIFOn);
554 for (; aIt.More(); aIt.Next()) {
561 aIt.Initialize(aMIFIn);
562 for (; aIt.More(); aIt.Next()) {
572 //=======================================================================
573 // function: CheckFacePaves
575 //=======================================================================
576 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
577 (const TopoDS_Vertex& aVnew,
578 const BOPCol_MapOfInteger& aMIF)
580 Standard_Boolean bRet;
581 Standard_Integer nV, iFlag;
582 BOPCol_MapIteratorOfMapOfInteger aIt;
586 aIt.Initialize(aMIF);
587 for (; aIt.More(); aIt.Next()) {
589 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
590 iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
598 //=======================================================================
599 //function : ForceInterfVF
601 //=======================================================================
602 Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
603 (const Standard_Integer nV,
604 const Standard_Integer nF)
606 Standard_Boolean bRet;
608 bRet = Standard_False;
609 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
610 const TopoDS_Face& aF = *(TopoDS_Face*) &myDS->Shape(nF);
612 GeomAPI_ProjectPointOnSurf& aProj = myContext->ProjPS(aF);
613 const gp_Pnt& aP = BRep_Tool::Pnt(aV);
615 if (!aProj.IsDone()) {
618 Standard_Real aDist, U, V;
620 aDist=aProj.LowerDistance();
621 aProj.LowerDistanceParameters(U, V);
624 bRet = myContext->IsPointInFace (aF, aP2d);
629 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
630 if (aVFs.Extent() == 0) {
635 BOPDS_InterfVF& aVF=aVFs(i);
636 aVF.SetIndices(nV, nF);
639 myDS->AddInterf(nV, nF);
641 aBB.UpdateVertex(aV, aDist);
642 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
643 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
644 BRepBndLib::Add(aV, aBoxDS);
646 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
647 BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();