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