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.
19 #include <Bnd_Box.hxx>
20 #include <BOPAlgo_PaveFiller.hxx>
21 #include <BOPAlgo_SectionAttribute.hxx>
22 #include <BOPAlgo_Tools.hxx>
23 #include <BOPCol_MapOfInteger.hxx>
24 #include <BOPCol_NCVector.hxx>
25 #include <BOPCol_Parallel.hxx>
26 #include <BOPDS_CommonBlock.hxx>
27 #include <BOPDS_CoupleOfPaveBlocks.hxx>
28 #include <BOPDS_Curve.hxx>
29 #include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
30 #include <BOPDS_DS.hxx>
31 #include <BOPDS_Interf.hxx>
32 #include <BOPDS_Iterator.hxx>
33 #include <BOPDS_MapOfPaveBlock.hxx>
34 #include <BOPDS_Pave.hxx>
35 #include <BOPDS_PaveBlock.hxx>
36 #include <BOPTools_AlgoTools.hxx>
37 #include <BRep_Builder.hxx>
38 #include <BRep_Tool.hxx>
39 #include <BRepAdaptor_Curve.hxx>
40 #include <BRepBndLib.hxx>
41 #include <GeomAPI_ProjectPointOnSurf.hxx>
43 #include <IntTools_CommonPrt.hxx>
44 #include <IntTools_Context.hxx>
45 #include <IntTools_EdgeFace.hxx>
46 #include <IntTools_Range.hxx>
47 #include <IntTools_SequenceOfCommonPrts.hxx>
48 #include <IntTools_Tools.hxx>
49 #include <NCollection_IncAllocator.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Face.hxx>
52 #include <TopoDS_Vertex.hxx>
63 //=======================================================================
64 //class : BOPAlgo_EdgeFace
66 //=======================================================================
67 class BOPAlgo_EdgeFace :
68 public IntTools_EdgeFace,
80 virtual ~BOPAlgo_EdgeFace(){
83 void SetIndices(const Standard_Integer nE,
84 const Standard_Integer nF) {
89 void Indices(Standard_Integer& nE,
90 Standard_Integer& nF) {
95 void SetNewSR(const IntTools_Range& aR){
99 IntTools_Range& NewSR(){
103 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
107 Handle(BOPDS_PaveBlock)& PaveBlock() {
111 virtual void Perform() {
112 BOPAlgo_Algo::UserBreak();
113 IntTools_EdgeFace::Perform();
117 Standard_Integer myIE;
118 Standard_Integer myIF;
119 IntTools_Range myNewSR;
120 Handle(BOPDS_PaveBlock) myPB;
123 //=======================================================================
124 typedef BOPCol_NCVector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace;
126 typedef BOPCol_ContextFunctor
128 BOPAlgo_VectorOfEdgeFace,
129 Handle(IntTools_Context),
130 IntTools_Context> BOPAlgo_EdgeFaceFunctor;
132 typedef BOPCol_ContextCnt
133 <BOPAlgo_EdgeFaceFunctor,
134 BOPAlgo_VectorOfEdgeFace,
135 Handle(IntTools_Context)> BOPAlgo_EdgeFaceCnt;
137 //=======================================================================
138 //function : PerformEF
140 //=======================================================================
141 void BOPAlgo_PaveFiller::PerformEF()
143 Standard_Integer iSize;
147 FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
149 myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
150 iSize=myIterator->ExpectedLength();
155 Standard_Boolean bJustAdd, bV[2];
156 Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2];
157 Standard_Integer aNbEdgeFace, k;
158 Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
159 Handle(NCollection_IncAllocator) aAllocator;
160 TopAbs_ShapeEnum aType;
161 BOPDS_ListIteratorOfListOfPaveBlock aIt;
162 BOPAlgo_VectorOfEdgeFace aVEdgeFace;
164 //-----------------------------------------------------scope f
166 ////aAllocator=new NCollection_IncAllocator();
168 BOPCol_MapOfInteger aMIEFC(100, aAllocator);
169 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
170 BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
175 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
176 aEFs.SetIncrement(iSize);
178 for (; myIterator->More(); myIterator->Next()) {
179 myIterator->Value(nE, nF, bJustAdd);
184 const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
185 if (aSIE.HasFlag()){//degenerated
189 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
190 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
191 const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box();
193 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
194 const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
196 aTolE=BRep_Tool::Tolerance(aE);
197 aTolF=BRep_Tool::Tolerance(aF);
199 BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
200 aIt.Initialize(aLPB);
201 for (; aIt.More(); aIt.Next()) {
202 Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
204 const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
205 if (aMPBF.Contains(aPBR)) {
209 if (!aPB->HasShrunkData()) {
214 aPB->ShrunkData(aTS1, aTS2, aBBE);
216 if (aBBF.IsOut (aBBE)) {
220 BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Append1();
222 aEdgeFace.SetIndices(nE, nF);
223 aEdgeFace.SetPaveBlock(aPB);
225 aEdgeFace.SetEdge (aE);
226 aEdgeFace.SetFace (aF);
227 aEdgeFace.SetTolE (aTolE);
228 aEdgeFace.SetTolF (aTolF);
229 aEdgeFace.SetDiscretize (aDiscretize);
230 aEdgeFace.SetDeflection (aDeflection);
232 IntTools_Range aSR(aTS1, aTS2);
233 IntTools_Range anewSR=aSR;
234 BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
235 aEdgeFace.SetNewSR(anewSR);
237 aPB->Range(aT1, aT2);
238 IntTools_Range aPBRange(aT1, aT2);
240 BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
241 aEdgeFace.SetRange (aPBRange);
242 aEdgeFace.SetProgressIndicator(myProgressIndicator);
244 }//for (; aIt.More(); aIt.Next()) {
245 }//for (; myIterator->More(); myIterator->Next()) {
247 aNbEdgeFace=aVEdgeFace.Extent();
248 //=================================================================
249 BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
250 //=================================================================
252 for (k=0; k < aNbEdgeFace; ++k) {
253 BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
254 if (!aEdgeFace.IsDone()) {
258 aEdgeFace.Indices(nE, nF);
260 const TopoDS_Edge& aE=aEdgeFace.Edge();
261 const TopoDS_Face& aF=aEdgeFace.Face();
263 aTolE=aEdgeFace.TolE();
264 aTolF=aEdgeFace.TolF();
265 const IntTools_Range& anewSR=aEdgeFace.NewSR();
266 Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
268 aPB->Range(aT1, aT2);
269 aPB->Indices(nV[0], nV[1]);
271 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
272 const BOPCol_MapOfInteger& aMIFOn=aFI.VerticesOn();
273 const BOPCol_MapOfInteger& aMIFIn=aFI.VerticesIn();
275 const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
276 aNbCPrts=aCPrts.Length();
277 for (i=1; i<=aNbCPrts; ++i) {
278 const IntTools_CommonPrt& aCPart=aCPrts(i);
281 case TopAbs_VERTEX: {
282 Standard_Boolean bIsOnPave[2];
284 Standard_Real aT, aTolToDecide;
287 IntTools_Tools::VertexParameter(aCPart, aT);
288 BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
290 const IntTools_Range& aR=aCPart.Range1();
293 IntTools_Range aR1(aT1,anewSR.First()),aR2(anewSR.Last(), aT2);
295 bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide);
296 bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide);
298 if (bIsOnPave[0] && bIsOnPave[1]) {
299 bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
300 bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
301 if (bV[0] && bV[1]) {
302 IntTools_CommonPrt aCP = aCPart;
303 aCP.SetType(TopAbs_EDGE);
304 BOPDS_InterfEF& aEF=aEFs.Append1();
306 aEF.SetIndices(nE, nF);
307 aEF.SetCommonPart(aCP);
308 myDS->AddInterf(nE, nF);
312 BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
316 for (j=0; j<2; ++j) {
318 bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
320 const TopoDS_Vertex& aV=
321 (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
322 BOPTools_AlgoTools::UpdateVertex(aE, aT, aV);
323 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV[j]);
324 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
325 BRepBndLib::Add(aV, aBoxDS);
328 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
333 if (!bIsOnPave[0] && !bIsOnPave[1]) {
334 if (CheckFacePaves(aVnew, aMIFOn)) {
338 const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
339 Standard_Real aTolV = BRep_Tool::Tolerance(aVnew);
340 aTolV = Max(aTolV, Max(aTolE, aTolF));
342 if (!myContext->IsPointInFace(aPnew, aF, aTolV)) {
346 aBB.UpdateVertex(aVnew, aTolV);
350 BOPDS_InterfEF& aEF=aEFs.Append1();
352 aEF.SetIndices(nE, nF);
353 aEF.SetCommonPart(aCPart);
355 myDS->AddInterf(nE, nF);
357 BOPDS_CoupleOfPaveBlocks aCPB;
359 aCPB.SetPaveBlocks(aPB, aPB);
360 aCPB.SetIndexInterf(iX);
361 aMVCPB.Add(aVnew, aCPB);
369 BOPDS_InterfEF& aEF=aEFs.Append1();
371 aEF.SetIndices(nE, nF);
373 bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
374 bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
375 if (!bV[0] || !bV[1]) {
376 myDS->AddInterf(nE, nF);
379 //update tolerance of edge if needed
381 myDS->UpdateEdgeTolerance(nE, aTolF);
384 aEF.SetCommonPart(aCPart);
386 myDS->AddInterf(nE, nF);
388 BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
395 }//for (i=1; i<=aNbCPrts; ++i) {
396 }// for (k=0; k < aNbEdgeEdge; ++k) {
398 //=========================================
400 //=========================================
401 BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
402 PerformVerticesEF(aMVCPB, aAllocator);
404 // Update FaceInfoIn for all faces having EF common parts
405 BOPCol_MapIteratorOfMapOfInteger aItMI;
406 aItMI.Initialize(aMIEFC);
407 for (; aItMI.More(); aItMI.Next()) {
409 myDS->UpdateFaceInfoIn(nF);
411 // Refine FaceInfoOn to remove all formal pave blocks
412 // made during EF processing
413 //myDS->RefineFaceInfoOn();
414 //-----------------------------------------------------scope t
418 ////aAllocator.Nullify();
420 //=======================================================================
421 //function : PerformVertices1
423 //=======================================================================
424 Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
425 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
426 Handle(NCollection_BaseAllocator)& theAllocator)
428 Standard_Integer aNbV, iRet;
431 aNbV=theMVCPB.Extent();
436 Standard_Integer nVx, nVSD, iV, iErr, nE, iFlag, iX, i, aNbPBLI;
439 BOPCol_ListIteratorOfListOfShape aItLS;
440 BOPCol_ListIteratorOfListOfInteger aItLI;
445 BOPCol_ListOfShape aLS(theAllocator);
446 BOPCol_DataMapOfShapeInteger aMVI(100, theAllocator);
447 BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
448 BOPAlgo_PaveFiller aPF(theAllocator);
450 aSI.SetShapeType(TopAbs_VERTEX);
451 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
453 // 1 prepare arguments
454 for (i=1; i<=aNbV; ++i) {
455 const TopoDS_Shape& aS=theMVCPB.FindKey(i);
460 aPF.SetArguments(aLS);
462 iErr=aPF.ErrorStatus();
469 // 3 Add new vertices to theDS;
470 // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
471 aItLS.Initialize(aLS);
472 for (; aItLS.More(); aItLS.Next()) {
473 const TopoDS_Shape& aVx=aItLS.Value();
474 nVx=aPDS->Index(aVx);
476 if (aPDS->HasShapeSD(nVx, nVSD)) {
477 aV=aPDS->Shape(nVSD);
482 // index of new vertex in theDS -> iV
483 if (!aMVI.IsBound(aV)) {
485 iV=myDS->Append(aSI);
487 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
488 Bnd_Box& aBox=aSIDS.ChangeBox();
489 BRepBndLib::Add(aV, aBox);
497 BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
499 // update EF interference
500 iX=aCPB.IndexInterf();
501 BOPDS_InterfEF& aEF=aEFs(iX);
504 const Handle(BOPDS_PaveBlock)& aPB=aCPB.PaveBlock1();
505 if (aMPBLI.Contains(aPB)) {
506 BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
510 BOPCol_ListOfInteger aLI(theAllocator);
512 aMPBLI.Add(aPB, aLI);
517 // 5.1 Compute Extra Paves and
518 // 5.2. Add Extra Paves to the PaveBlocks
519 aNbPBLI=aMPBLI.Extent();
520 for (i=1; i<=aNbPBLI; ++i) {
521 Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
522 const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
523 nE=aPB->OriginalEdge();
524 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
526 aItLI.Initialize(aLI);
527 for (; aItLI.More(); aItLI.Next()) {
529 const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
531 iFlag=myContext->ComputeVE (aVx, aE, aT);
534 aPave.SetParameter(aT);
535 aPB->AppendExtPave(aPave);
539 // 6 Split PaveBlocksa
540 for (i=1; i<=aNbPBLI; ++i) {
541 Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
542 nE=aPB->OriginalEdge();
544 if (!myDS->IsCommonBlock(aPB)) {
545 myDS->UpdatePaveBlock(aPB);
548 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
549 myDS->UpdateCommonBlock(aCB);
551 }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
555 //=======================================================================
556 // function: CheckFacePaves
558 //=======================================================================
559 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
560 (const Standard_Integer nVx,
561 const BOPCol_MapOfInteger& aMIFOn,
562 const BOPCol_MapOfInteger& aMIFIn)
564 Standard_Boolean bRet;
566 BOPCol_MapIteratorOfMapOfInteger aIt;
570 aIt.Initialize(aMIFOn);
571 for (; aIt.More(); aIt.Next()) {
578 aIt.Initialize(aMIFIn);
579 for (; aIt.More(); aIt.Next()) {
589 //=======================================================================
590 // function: CheckFacePaves
592 //=======================================================================
593 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
594 (const TopoDS_Vertex& aVnew,
595 const BOPCol_MapOfInteger& aMIF)
597 Standard_Boolean bRet;
598 Standard_Integer nV, iFlag;
599 BOPCol_MapIteratorOfMapOfInteger aIt;
603 aIt.Initialize(aMIF);
604 for (; aIt.More(); aIt.Next()) {
606 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
607 iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
615 //=======================================================================
616 //function : ForceInterfVF
618 //=======================================================================
619 Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
620 (const Standard_Integer nV,
621 const Standard_Integer nF)
623 Standard_Boolean bRet;
625 bRet = Standard_False;
626 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
627 const TopoDS_Face& aF = *(TopoDS_Face*) &myDS->Shape(nF);
629 GeomAPI_ProjectPointOnSurf& aProj = myContext->ProjPS(aF);
630 const gp_Pnt& aP = BRep_Tool::Pnt(aV);
632 if (!aProj.IsDone()) {
635 Standard_Real aDist, U, V;
637 aDist=aProj.LowerDistance();
638 aProj.LowerDistanceParameters(U, V);
641 bRet = myContext->IsPointInFace (aF, aP2d);
643 //Standard_Integer i;
646 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
647 aVFs.SetIncrement(10);
648 BOPDS_InterfVF& aVF=aVFs.Append1();
649 aVF.SetIndices(nV, nF);
652 myDS->AddInterf(nV, nF);
654 aBB.UpdateVertex(aV, aDist);
655 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
656 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
657 BRepBndLib::Add(aV, aBoxDS);
659 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
660 BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();