0024428: Implementation of LGPL license
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_5.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 OPEN CASCADE SAS
4e57c75e 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//
973c2be1 7// This file is part of Open CASCADE Technology software library.
4e57c75e 8//
973c2be1 9// This library is free software; you can redistribute it and / or modify it
10// under the terms of the GNU Lesser General Public 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.
4e57c75e 14//
973c2be1 15// Alternatively, this file may be used under the terms of Open CASCADE
16// commercial license or contractual agreement.
4e57c75e 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>
b4109929 54#include <GeomAPI_ProjectPointOnSurf.hxx>
4e57c75e 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 //----------------------------------------------------------------------
b4109929 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;
4e57c75e 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 //
5a77460e 125 const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
4e57c75e 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;
4e57c75e 157 BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
b4109929 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);
4e57c75e 165 //
166 aEdgeFace.Perform();
167 if (!aEdgeFace.IsDone()) {
168 continue;
169 }
170 //
b4109929 171 aPB->Indices(nV[0], nV[1]);
172 //
4e57c75e 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: {
b4109929 180 Standard_Boolean bIsOnPave[2];
181 Standard_Integer j;
4e57c75e 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;
4e57c75e 190 //
b4109929 191 IntTools_Range aR1(aT1, anewSR.First()), aR2(anewSR.Last(), aT2);
4e57c75e 192 //
b4109929 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]) {
4e57c75e 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 }
b4109929 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 }
4e57c75e 225 }
4e57c75e 226 }
227 //
b4109929 228 if (!bIsOnPave[0] && !bIsOnPave[1]) {
229 if (CheckFacePaves(aVnew, aMIFOn)) {
4e57c75e 230 continue;
231 }
b4109929 232 //
233 const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
234 if (!myContext->IsValidPointForFace(aPnew, aF, aTolE)) {
4e57c75e 235 continue;
236 }
b4109929 237 //
4e57c75e 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 //
b4109929 265 bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
266 bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
267 if (!bV[0] || !bV[1]) {
4e57c75e 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 //=========================================
5a77460e 295 BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
4e57c75e 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
5a77460e 440 if (!myDS->IsCommonBlock(aPB)) {
4e57c75e 441 myDS->UpdatePaveBlock(aPB);
442 }
443 else {
5a77460e 444 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
4e57c75e 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}
b4109929 509//=======================================================================
510//function : ForceInterfVF
511//purpose :
512//=======================================================================
513Standard_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