0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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//
d5f74e42 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
973c2be1 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
4e57c75e 18
4e57c75e 19#include <Bnd_Box.hxx>
9324aa2d 20#include <Bnd_Tools.hxx>
42cf5bc1 21#include <BOPAlgo_PaveFiller.hxx>
33ba8565 22#include <BOPAlgo_Alerts.hxx>
42cf5bc1 23#include <BOPAlgo_Tools.hxx>
42cf5bc1 24#include <BOPDS_CoupleOfPaveBlocks.hxx>
42cf5bc1 25#include <BOPDS_DS.hxx>
26#include <BOPDS_Interf.hxx>
27#include <BOPDS_Iterator.hxx>
28#include <BOPDS_MapOfPaveBlock.hxx>
29#include <BOPDS_Pave.hxx>
30#include <BOPDS_PaveBlock.hxx>
31#include <BOPTools_AlgoTools.hxx>
d3578357 32#include <BOPTools_AlgoTools2D.hxx>
1155d05a 33#include <BOPTools_Parallel.hxx>
42cf5bc1 34#include <BRep_Builder.hxx>
4e57c75e 35#include <BRep_Tool.hxx>
d3578357 36#include <GeomAPI_ProjectPointOnSurf.hxx>
42cf5bc1 37#include <gp_Pnt.hxx>
38#include <IntTools_CommonPrt.hxx>
39#include <IntTools_Context.hxx>
4e57c75e 40#include <IntTools_EdgeFace.hxx>
41#include <IntTools_Range.hxx>
42#include <IntTools_SequenceOfCommonPrts.hxx>
42cf5bc1 43#include <IntTools_Tools.hxx>
d3578357 44#include <NCollection_IncAllocator.hxx>
1155d05a 45#include <NCollection_Vector.hxx>
8ae442a8 46#include <Precision.hxx>
1155d05a 47#include <TColStd_MapOfInteger.hxx>
3510db62 48#include <TopoDS.hxx>
42cf5bc1 49#include <TopoDS_Edge.hxx>
50#include <TopoDS_Face.hxx>
51#include <TopoDS_Vertex.hxx>
52
e30616a7 53//=======================================================================
54//class : BOPAlgo_EdgeFace
55//purpose :
56//=======================================================================
36f4947b 57class BOPAlgo_EdgeFace :
58 public IntTools_EdgeFace,
d03c0898 59 public BOPAlgo_ParallelAlgo {
36f4947b 60
e30616a7 61 public:
36f4947b 62 DEFINE_STANDARD_ALLOC
63
64 BOPAlgo_EdgeFace() :
65 IntTools_EdgeFace(),
d03c0898 66 BOPAlgo_ParallelAlgo(),
36f4947b 67 myIE(-1), myIF(-1) {
e30616a7 68 };
69 //
36f4947b 70 virtual ~BOPAlgo_EdgeFace(){
e30616a7 71 };
72 //
73 void SetIndices(const Standard_Integer nE,
74 const Standard_Integer nF) {
75 myIE=nE;
76 myIF=nF;
77 }
78 //
79 void Indices(Standard_Integer& nE,
80 Standard_Integer& nF) {
81 nE=myIE;
82 nF=myIF;
83 }
84 //
85 void SetNewSR(const IntTools_Range& aR){
86 myNewSR=aR;
87 }
88 //
89 IntTools_Range& NewSR(){
90 return myNewSR;
91 }
92 //
93 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
94 myPB=aPB;
95 }
96 //
97 Handle(BOPDS_PaveBlock)& PaveBlock() {
98 return myPB;
99 }
100 //
0d0481c7 101 void SetFuzzyValue(const Standard_Real theFuzz) {
102 IntTools_EdgeFace::SetFuzzyValue(theFuzz);
103 }
104 //
c08fd127 105 void SetBoxes (const Bnd_Box& theBox1,
106 const Bnd_Box& theBox2)
107 {
108 myBox1 = theBox1;
109 myBox2 = theBox2;
110 }
111 //
36f4947b 112 virtual void Perform() {
d03c0898 113 Message_ProgressScope aPS(myProgressRange, NULL, 1);
114 if (UserBreak(aPS))
115 {
116 return;
117 }
c08fd127 118 TopoDS_Face aFace = myFace;
119 TopoDS_Edge anEdge = myEdge;
120 Standard_Boolean hasTrsf = false;
ad8b073e 121 try
122 {
123 OCC_CATCH_SIGNALS
124
c08fd127 125 gp_Trsf aTrsf;
126 if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
127 {
128 // Shapes are located far from origin, move the shapes to the origin,
129 // to increase the accuracy of intersection.
130 TopLoc_Location aLoc (aTrsf);
131 myEdge.Move (aLoc);
132 myFace.Move (aLoc);
133 hasTrsf = Standard_True;
134 }
135
ad8b073e 136 IntTools_EdgeFace::Perform();
137 }
a738b534 138 catch (Standard_Failure const&)
ad8b073e 139 {
140 AddError(new BOPAlgo_AlertIntersectionFailed);
141 }
c08fd127 142 myFace = aFace;
143 myEdge = anEdge;
144
145 if (hasTrsf)
146 {
147 for (Standard_Integer i = 1; i <= mySeqOfCommonPrts.Length(); ++i)
148 {
149 IntTools_CommonPrt& aCPart = mySeqOfCommonPrts (i);
150 aCPart.SetEdge1 (myEdge);
151 }
152 }
36f4947b 153 }
154 //
e30616a7 155 protected:
156 Standard_Integer myIE;
157 Standard_Integer myIF;
158 IntTools_Range myNewSR;
159 Handle(BOPDS_PaveBlock) myPB;
c08fd127 160 Bnd_Box myBox1;
161 Bnd_Box myBox2;
e30616a7 162};
163//
164//=======================================================================
1155d05a 165typedef NCollection_Vector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace;
fc867b96 166
4e57c75e 167//=======================================================================
168//function : PerformEF
169//purpose :
170//=======================================================================
d03c0898 171void BOPAlgo_PaveFiller::PerformEF(const Message_ProgressRange& theRange)
4e57c75e 172{
e30616a7 173 FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
174 //
4e57c75e 175 myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
d03c0898 176 Message_ProgressScope aPSOuter(theRange, NULL, 10);
483ce1bd 177 Standard_Integer iSize = myIterator->ExpectedLength();
4e57c75e 178 if (!iSize) {
179 return;
180 }
e30616a7 181 //
483ce1bd 182 Standard_Integer nE, nF;
183 //
184 if (myGlue == BOPAlgo_GlueFull) {
185 // there is no need to intersect edges with faces in this mode
186 // just initialize FaceInfo for faces
187 for (; myIterator->More(); myIterator->Next()) {
25dfc507 188 myIterator->Value(nE, nF);
189 if (!myDS->ShapeInfo(nE).HasFlag()) {
483ce1bd 190 myDS->ChangeFaceInfo(nF);
191 }
192 }
193 return;
194 }
195 //
196 Standard_Boolean bV[2], bIsPBSplittable;
6dc83e21 197 Standard_Boolean bV1, bV2, bExpressCompute;
198 Standard_Integer nV1, nV2;
03cca6f7 199 Standard_Integer i, aNbCPrts, iX, nV[2];
e30616a7 200 Standard_Integer aNbEdgeFace, k;
03cca6f7 201 Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2;
488e5b9d 202 Handle(NCollection_BaseAllocator) aAllocator;
4e57c75e 203 TopAbs_ShapeEnum aType;
204 BOPDS_ListIteratorOfListOfPaveBlock aIt;
e30616a7 205 BOPAlgo_VectorOfEdgeFace aVEdgeFace;
e30616a7 206 //-----------------------------------------------------scope f
4e57c75e 207 //
488e5b9d 208 aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
209 //
1155d05a 210 TColStd_MapOfInteger aMIEFC(100, aAllocator);
4e57c75e 211 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
212 BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
01b5b3df 213 BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
4e57c75e 214 //
4e57c75e 215 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
4e57c75e 216 aEFs.SetIncrement(iSize);
4e57c75e 217 //
218 for (; myIterator->More(); myIterator->Next()) {
d03c0898 219 if (UserBreak(aPSOuter))
220 {
221 return;
222 }
25dfc507 223 myIterator->Value(nE, nF);
4e57c75e 224 //
225 const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
226 if (aSIE.HasFlag()){//degenerated
227 continue;
228 }
229 //
230 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
231 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
232 const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box();
233 //
234 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
235 const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
4e57c75e 236 //
1155d05a 237 const TColStd_MapOfInteger& aMVIn=aFI.VerticesIn();
238 const TColStd_MapOfInteger& aMVOn=aFI.VerticesOn();
6dc83e21 239 //
4e57c75e 240 aTolE=BRep_Tool::Tolerance(aE);
241 aTolF=BRep_Tool::Tolerance(aF);
242 //
243 BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
244 aIt.Initialize(aLPB);
245 for (; aIt.More(); aIt.Next()) {
d03c0898 246 if (UserBreak(aPSOuter))
247 {
248 return;
249 }
4e57c75e 250 Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
251 //
5a77460e 252 const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
4e57c75e 253 if (aMPBF.Contains(aPBR)) {
254 continue;
255 }
256 //
01b5b3df 257 Bnd_Box aBBE;
258 if (!GetPBBox(aE, aPB, aDMPBBox, aT1, aT2, aTS1, aTS2, aBBE)) {
e30616a7 259 continue;
4e57c75e 260 }
261 //
4e57c75e 262 if (aBBF.IsOut (aBBE)) {
263 continue;
264 }
265 //
6dc83e21 266 aPBR->Indices(nV1, nV2);
267 bV1=aMVIn.Contains(nV1) || aMVOn.Contains(nV1);
268 bV2=aMVIn.Contains(nV2) || aMVOn.Contains(nV2);
269 bExpressCompute=bV1 && bV2;
270 //
1155d05a 271 BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Appended();
e30616a7 272 //
273 aEdgeFace.SetIndices(nE, nF);
274 aEdgeFace.SetPaveBlock(aPB);
4e57c75e 275 //
276 aEdgeFace.SetEdge (aE);
277 aEdgeFace.SetFace (aF);
c08fd127 278 aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
0d0481c7 279 aEdgeFace.SetFuzzyValue(myFuzzyValue);
6dc83e21 280 aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
d03c0898 281
4e57c75e 282 IntTools_Range aSR(aTS1, aTS2);
d03c0898 283 IntTools_Range anewSR = aSR;
4e57c75e 284 BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
e30616a7 285 aEdgeFace.SetNewSR(anewSR);
b4109929 286 //
b4109929 287 IntTools_Range aPBRange(aT1, aT2);
288 aSR = aPBRange;
289 BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
d03c0898 290 aEdgeFace.SetRange(aPBRange);
291 //
d3578357 292 // Save the pair to avoid their forced intersection
293 BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF);
294 if (!pMPB)
295 pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock());
296 pMPB->Add(aPB);
e30616a7 297 }//for (; aIt.More(); aIt.Next()) {
298 }//for (; myIterator->More(); myIterator->Next()) {
299 //
1155d05a 300 aNbEdgeFace=aVEdgeFace.Length();
d03c0898 301 Message_ProgressScope aPS(aPSOuter.Next(9), "Performing Edge-Face intersection", aNbEdgeFace);
302 for (Standard_Integer index = 0; index < aNbEdgeFace; index++)
303 {
304 BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.ChangeValue(index);
305 aEdgeFace.SetProgressRange(aPS.Next());
306 }
e30616a7 307 //=================================================================
fc867b96 308 BOPTools_Parallel::Perform (myRunParallel, aVEdgeFace, myContext);
e30616a7 309 //=================================================================
d03c0898 310 if (UserBreak(aPSOuter))
311 {
312 return;
313 }
e30616a7 314 //
315 for (k=0; k < aNbEdgeFace; ++k) {
d03c0898 316 if (UserBreak(aPSOuter))
317 {
318 return;
319 }
e30616a7 320 BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
ad8b073e 321 if (!aEdgeFace.IsDone() || aEdgeFace.HasErrors()) {
322 // Warn about failed intersection of sub-shapes
323 AddIntersectionFailedWarning(aEdgeFace.Edge(), aEdgeFace.Face());
e30616a7 324 continue;
325 }
51db0179 326 //
e30616a7 327 aEdgeFace.Indices(nE, nF);
328 //
329 const TopoDS_Edge& aE=aEdgeFace.Edge();
330 const TopoDS_Face& aF=aEdgeFace.Face();
331 //
0d0481c7 332 aTolE=BRep_Tool::Tolerance(aE);
333 aTolF=BRep_Tool::Tolerance(aF);
cd0705f6 334 //
335 const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
336 aNbCPrts = aCPrts.Length();
337 if (!aNbCPrts) {
338 if (aEdgeFace.MinimalDistance() < RealLast() &&
339 aEdgeFace.MinimalDistance() > aTolE + aTolF)
340 {
341 const Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
342 aPB->Range(aT1, aT2);
343 NCollection_List<EdgeRangeDistance>* pList = myDistances.ChangeSeek (BOPDS_Pair (nE, nF));
344 if (!pList)
345 pList = myDistances.Bound (BOPDS_Pair (nE, nF), NCollection_List<EdgeRangeDistance>());
346 pList->Append (EdgeRangeDistance (aT1, aT2, aEdgeFace.MinimalDistance()));
347 }
348 continue;
349 }
350 //
e30616a7 351 const IntTools_Range& anewSR=aEdgeFace.NewSR();
352 Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
353 //
354 aPB->Range(aT1, aT2);
355 aPB->Indices(nV[0], nV[1]);
01b5b3df 356 bIsPBSplittable = aPB->IsSplittable();
357 //
01b5b3df 358 anewSR.Range(aTS1, aTS2);
359 //
51db0179 360 if (aCPrts(1).Type() == TopAbs_VERTEX) {
361 // for the intersection type VERTEX
362 // extend vertices ranges using Edge/Edge intersections
363 // between the edge aE and the edges of the face aF.
364 // thereby the edge's intersection range is reduced
365 ReduceIntersectionRange(nV[0], nV[1], nE, nF, aTS1, aTS2);
366 }
01b5b3df 367 //
368 IntTools_Range aR1(aT1, aTS1), aR2(aTS2, aT2);
e30616a7 369 //
370 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
1155d05a 371 const TColStd_MapOfInteger& aMIFOn=aFI.VerticesOn();
372 const TColStd_MapOfInteger& aMIFIn=aFI.VerticesIn();
3510db62 373 //
374 Standard_Boolean bLinePlane = Standard_False;
375 if (aNbCPrts) {
376 BRepAdaptor_Curve aBAC(aE);
3510db62 377 bLinePlane = (aBAC.GetType() == GeomAbs_Line &&
51db0179 378 myContext->SurfaceAdaptor(aF).GetType() == GeomAbs_Plane);
3510db62 379 }
51db0179 380 //
e30616a7 381 for (i=1; i<=aNbCPrts; ++i) {
d03c0898 382 if (UserBreak(aPSOuter))
383 {
384 return;
385 }
e30616a7 386 const IntTools_CommonPrt& aCPart=aCPrts(i);
387 aType=aCPart.Type();
388 switch (aType) {
01b5b3df 389 case TopAbs_VERTEX: {
b4109929 390 Standard_Boolean bIsOnPave[2];
391 Standard_Integer j;
4e57c75e 392 Standard_Real aT, aTolToDecide;
393 TopoDS_Vertex aVnew;
e30616a7 394 //
1e143abb 395 IntTools_Tools::VertexParameter(aCPart, aT);
4e57c75e 396 BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
397 //
398 const IntTools_Range& aR=aCPart.Range1();
399 aTolToDecide=5.e-8;
4e57c75e 400 //
1e143abb 401 bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide);
402 bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide);
b4109929 403 //
3510db62 404 if ((bIsOnPave[0] && bIsOnPave[1]) ||
405 (bLinePlane && (bIsOnPave[0] || bIsOnPave[1]))) {
b4109929 406 bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
407 bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
408 if (bV[0] && bV[1]) {
4e57c75e 409 IntTools_CommonPrt aCP = aCPart;
410 aCP.SetType(TopAbs_EDGE);
1155d05a 411 BOPDS_InterfEF& aEF=aEFs.Appended();
412 iX=aEFs.Length()-1;
4e57c75e 413 aEF.SetIndices(nE, nF);
414 aEF.SetCommonPart(aCP);
415 myDS->AddInterf(nE, nF);
ceb31c61 416 //
417 aMIEFC.Add(nF);
418 //
4e57c75e 419 BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
420 break;
421 }
422 }
01b5b3df 423 //
424 if (!bIsPBSplittable) {
425 continue;
426 }
427 //
d3578357 428 for (j = 0; j < 2; ++j)
429 {
430 if (bIsOnPave[j])
431 {
432 bV[j] = CheckFacePaves(nV[j], aMIFOn, aMIFIn);
433 if (!bV[j])
b4109929 434 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
4e57c75e 435 }
4e57c75e 436 }
d3578357 437
438 if (bIsOnPave[0] || bIsOnPave[1])
439 {
440 // The found intersection point is located closely to one of the pave block's
441 // bounds. So, do not create the new vertex in this point.
442 // Check if this point is a real intersection, or just a touching point.
443 // If it is a touching point, do nothing.
444 // If it is an intersection point, update the existing vertex to cover the
445 // intersection point.
446 GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
447 const gp_Pnt aPnew = BRep_Tool::Pnt(aVnew);
448 aProjPS.Perform(aPnew);
449 Standard_Real aMinDistEF = (aProjPS.IsDone() && aProjPS.NbPoints()) ?
450 aProjPS.LowerDistance() : Precision::Infinite();
451 Standard_Boolean hasRealIntersection = aMinDistEF < Precision::Intersection();
452
453 if (!hasRealIntersection)
454 // no intersection point
4e57c75e 455 continue;
d3578357 456
457 // Real intersection is present.
458 // Update the existing vertex to cover the intersection point.
459 for (j = 0; j < 2; ++j)
460 {
461 if (bIsOnPave[j])
462 {
463 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[j]));
464 const gp_Pnt aP = BRep_Tool::Pnt(aV);
465 Standard_Real aDistPP = aP.Distance(aPnew);
e8e8b273 466 Standard_Real aTol = BRep_Tool::Tolerance(aV);
467 Standard_Real aMaxDist = 1.e4 * aTol;
468 if (aTol < .01)
469 {
470 aMaxDist = Min(aMaxDist, 0.1);
471 }
472 if (aDistPP < aMaxDist)
473 {
474 UpdateVertex(nV[j], aDistPP);
475 myVertsToAvoidExtension.Add(nV[j]);
476 }
d3578357 477 }
4e57c75e 478 }
d3578357 479 continue;
480 }
481
482 if (CheckFacePaves(aVnew, aMIFOn)) {
483 continue;
484 }
485 //
486 Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
487 aTolVnew = Max(aTolVnew, Max(aTolE, aTolF));
488 BRep_Builder().UpdateVertex(aVnew, aTolVnew);
489 if (bLinePlane) {
490 // increase tolerance for Line/Plane intersection, but do not update
491 // the vertex till its intersection with some other shape
492 IntTools_Range aCR = aCPart.Range1();
493 aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.);
4e57c75e 494 }
d3578357 495 //
496 const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
497 //
498 if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) {
499 continue;
500 }
501 //
502 aMIEFC.Add(nF);
503 // 1
504 BOPDS_InterfEF& aEF = aEFs.Appended();
505 iX = aEFs.Length() - 1;
506 aEF.SetIndices(nE, nF);
507 aEF.SetCommonPart(aCPart);
508 // 2
509 myDS->AddInterf(nE, nF);
510 // 3
511 BOPDS_CoupleOfPaveBlocks aCPB;
512 //
513 aCPB.SetPaveBlocks(aPB, aPB);
514 aCPB.SetIndexInterf(iX);
515 aCPB.SetTolerance(aTolVnew);
516 aMVCPB.Add(aVnew, aCPB);
4e57c75e 517 }
518 break;
519 case TopAbs_EDGE: {
520 aMIEFC.Add(nF);
521 //
522 // 1
1155d05a 523 BOPDS_InterfEF& aEF=aEFs.Appended();
524 iX=aEFs.Length()-1;
4e57c75e 525 aEF.SetIndices(nE, nF);
526 //
b4109929 527 bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
528 bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
529 if (!bV[0] || !bV[1]) {
4e57c75e 530 myDS->AddInterf(nE, nF);
531 break;
532 }
4e57c75e 533 aEF.SetCommonPart(aCPart);
534 // 2
535 myDS->AddInterf(nE, nF);
536 // 3
537 BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
538
539 }
540 break;
541 default:
542 break;
e30616a7 543 }//switch (aType) {
544 }//for (i=1; i<=aNbCPrts; ++i) {
545 }// for (k=0; k < aNbEdgeEdge; ++k) {
4e57c75e 546 //
547 //=========================================
548 // post treatment
549 //=========================================
d3578357 550 BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS, myContext);
551 UpdateVerticesOfCB();
d03c0898 552 PerformNewVertices(aMVCPB, aAllocator, aPSOuter.Next(1), Standard_False);
553 if (HasErrors())
554 {
555 return;
556 }
4e57c75e 557 //
558 // Update FaceInfoIn for all faces having EF common parts
47cd8af2 559 myDS->UpdateFaceInfoIn (aMIEFC);
560
4e57c75e 561 //-----------------------------------------------------scope t
562 aMIEFC.Clear();
563 aMVCPB.Clear();
564 aMPBLI.Clear();
e30616a7 565 ////aAllocator.Nullify();
4e57c75e 566}
567//=======================================================================
4e57c75e 568// function: CheckFacePaves
569// purpose:
570//=======================================================================
e30616a7 571Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
572 (const Standard_Integer nVx,
1155d05a 573 const TColStd_MapOfInteger& aMIFOn,
574 const TColStd_MapOfInteger& aMIFIn)
4e57c75e 575{
1103eb60 576 if (aMIFOn.Contains(nVx) || aMIFIn.Contains(nVx))
577 {
578 return true;
4e57c75e 579 }
1103eb60 580 return false;
4e57c75e 581}
582//=======================================================================
583// function: CheckFacePaves
584// purpose:
585//=======================================================================
e30616a7 586Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
587 (const TopoDS_Vertex& aVnew,
1155d05a 588 const TColStd_MapOfInteger& aMIF)
4e57c75e 589{
590 Standard_Boolean bRet;
591 Standard_Integer nV, iFlag;
1155d05a 592 TColStd_MapIteratorOfMapOfInteger aIt;
4e57c75e 593 //
594 bRet=Standard_True;
595 //
596 aIt.Initialize(aMIF);
597 for (; aIt.More(); aIt.Next()) {
598 nV=aIt.Value();
599 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
600 iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
601 if (!iFlag) {
602 return bRet;
603 }
604 }
605 //
606 return !bRet;
607}
b4109929 608//=======================================================================
609//function : ForceInterfVF
610//purpose :
611//=======================================================================
e30616a7 612Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
613 (const Standard_Integer nV,
614 const Standard_Integer nF)
b4109929 615{
616 Standard_Boolean bRet;
3510db62 617 Standard_Integer iFlag, nVx;
618 Standard_Real U, V, aTolVNew;
b4109929 619 //
620 bRet = Standard_False;
621 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
622 const TopoDS_Face& aF = *(TopoDS_Face*) &myDS->Shape(nF);
623 //
0d0481c7 624 iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew, myFuzzyValue);
3510db62 625 if (iFlag == 0 || iFlag == -2) {
626 bRet=!bRet;
b4109929 627 //
b4109929 628 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
a3476a9f 629 aVFs.SetIncrement(10);
3510db62 630 // 1
1155d05a 631 BOPDS_InterfVF& aVF=aVFs.Appended();
3510db62 632 //
b4109929 633 aVF.SetIndices(nV, nF);
634 aVF.SetUV(U, V);
3510db62 635 // 2
b4109929 636 myDS->AddInterf(nV, nF);
637 //
3510db62 638 // 3 update vertex V/F if necessary
639 nVx=UpdateVertex(nV, aTolVNew);
640 // 4
641 if (myDS->IsNewShape(nVx)) {
642 aVF.SetIndexNew(nVx);
643 }
b4109929 644 //
645 BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
1155d05a 646 TColStd_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
3510db62 647 aMVIn.Add(nVx);
33ba8565 648 //
649 // check for self-interference
650 Standard_Integer iRV = myDS->Rank(nV);
651 if (iRV >= 0 && iRV == myDS->Rank(nF)) {
652 // add warning status
653 TopoDS_Compound aWC;
654 BRep_Builder().MakeCompound(aWC);
655 BRep_Builder().Add(aWC, aV);
656 BRep_Builder().Add(aWC, aF);
657 AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
658 }
659
b4109929 660 }
b4109929 661 return bRet;
662}
01b5b3df 663//=======================================================================
664//function : ReduceIntersectionRange
665//purpose :
666//=======================================================================
667void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
668 const Standard_Integer theV2,
669 const Standard_Integer theE,
670 const Standard_Integer theF,
671 Standard_Real& theTS1,
672 Standard_Real& theTS2)
673{
674 if (!myDS->IsNewShape(theV1) &&
675 !myDS->IsNewShape(theV2)) {
676 return;
677 }
678 //
51db0179 679 if (!myDS->HasInterfShapeSubShapes(theE, theF)) {
680 return;
681 }
682 //
01b5b3df 683 BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
1155d05a 684 Standard_Integer aNbEEs = aEEs.Length();
01b5b3df 685 if (!aNbEEs) {
686 return;
687 }
688 //
689 Standard_Integer i, nV, nE1, nE2;
690 Standard_Real aTR1, aTR2;
691 //
692 // get face's edges to check that E/E contains the edge from the face
1155d05a 693 TColStd_MapOfInteger aMFE;
694 const TColStd_ListOfInteger& aLI = myDS->ShapeInfo(theF).SubShapes();
695 TColStd_ListIteratorOfListOfInteger aItLI(aLI);
01b5b3df 696 for (; aItLI.More(); aItLI.Next()) {
697 nE1 = aItLI.Value();
698 if (myDS->ShapeInfo(nE1).ShapeType() == TopAbs_EDGE) {
699 aMFE.Add(nE1);
700 }
701 }
702 //
703 for (i = 0; i < aNbEEs; ++i) {
704 BOPDS_InterfEE& aEE = aEEs(i);
705 if (!aEE.HasIndexNew()) {
706 continue;
707 }
708 //
709 // check the vertex
710 nV = aEE.IndexNew();
711 if (nV != theV1 && nV != theV2) {
712 continue;
713 }
714 //
715 // check that the intersection is between the edge
716 // and one of the face's edge
717 aEE.Indices(nE1, nE2);
718 if (((theE != nE1) && (theE != nE2)) ||
719 (!aMFE.Contains(nE1) && !aMFE.Contains(nE2))) {
720 continue;
721 }
722 //
723 // update the intersection range
724 const IntTools_CommonPrt& aCPart = aEE.CommonPart();
725 const IntTools_Range& aCRange =
726 (theE == nE1) ? aCPart.Range1() : aCPart.Ranges2().First();
727 aCRange.Range(aTR1, aTR2);
728 //
729 if (nV == theV1) {
730 if (theTS1 < aTR2) {
731 theTS1 = aTR2;
732 }
733 }
734 else {
735 if (theTS2 > aTR1) {
736 theTS2 = aTR1;
737 }
738 }
739 }
740}
d3578357 741
742//=======================================================================
743//function : ForceInterfEF
744//purpose :
745//=======================================================================
d03c0898 746void BOPAlgo_PaveFiller::ForceInterfEF(const Message_ProgressRange& theRange)
d3578357 747{
d03c0898 748 Message_ProgressScope aPS(theRange, NULL, 1);
d3578357 749 if (!myIsPrimary)
750 return;
751
752 // Now that we have vertices increased and unified, try to find additional
753 // edge/face common blocks among the pairs of edge/face.
754 // Here, we are interested in common blocks only, as all real intersections
755 // should have happened already. Thus, we need to check only those pairs
756 // of edge/face which have the same vertices.
757
758 // Collect all pave blocks
759 BOPDS_IndexedMapOfPaveBlock aMPB;
760 const Standard_Integer aNbS = myDS->NbSourceShapes();
761 for (Standard_Integer nE = 0; nE < aNbS; ++nE)
762 {
763 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE);
764 if (aSI.ShapeType() != TopAbs_EDGE)
765 // Not an edge
766 continue;
767
768 if (!aSI.HasReference())
769 // Edge has no pave blocks
770 continue;
771
772 if (aSI.HasFlag())
773 // Degenerated edge
774 continue;
775
d03c0898 776 if (UserBreak(aPS))
777 {
778 return;
779 }
d3578357 780 const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
781 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
782 for (; aItLPB.More(); aItLPB.Next())
783 {
784 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
785 const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
786 aMPB.Add(aPBR);
787 }
788 }
789
790 // Perform intersection of collected pave blocks with faces
d03c0898 791
792 ForceInterfEF(aMPB, aPS.Next(), Standard_True);
d3578357 793}
794
795//=======================================================================
796//function : ForceInterfEF
797//purpose :
798//=======================================================================
799void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
d03c0898 800 const Message_ProgressRange& theRange,
d3578357 801 const Standard_Boolean theAddInterf)
802{
d03c0898 803 // Split progress on preparation, intersection and post-treatment stages
804 Message_ProgressScope aPSOuter(theRange, NULL, 10);
d3578357 805 if (theMPB.IsEmpty())
806 return;
d3578357 807 // Fill the tree with bounding boxes of the pave blocks
9324aa2d 808 BOPTools_BoxTree aBBTree;
d3578357 809
810 Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
811 BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc);
812
813 Standard_Integer aNbPB = theMPB.Extent();
814 for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
815 {
816 Handle(BOPDS_PaveBlock) aPB = theMPB(iPB);
817 if (!aPB->HasShrunkData() || !myDS->IsValidShrunkData(aPB))
818 {
819 FillShrunkData(aPB);
820 if (!aPB->HasShrunkData())
821 continue;
822 }
d03c0898 823 if (UserBreak(aPSOuter))
824 {
825 return;
826 }
d3578357 827
828 Standard_Real f, l;
829 Bnd_Box aPBBox;
830 Standard_Boolean isSplit;
831 aPB->ShrunkData(f, l, aPBBox, isSplit);
832
9324aa2d 833 aBBTree.Add(aPBMap.Add(aPB), Bnd_Tools::Bnd2BVH(aPBBox));
d3578357 834 }
835
836 // Shake the tree
9324aa2d 837 aBBTree.Build();
d3578357 838
c08fd127 839 const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
840
d3578357 841 // Find pairs of Face/PaveBlock containing the same vertices
842 // and prepare those pairs for intersection.
843 BOPAlgo_VectorOfEdgeFace aVEdgeFace;
844
845 const Standard_Integer aNbS = myDS->NbSourceShapes();
846 for (Standard_Integer nF = 0; nF < aNbS; ++nF)
847 {
848 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
849 if (aSI.ShapeType() != TopAbs_FACE)
850 // Not a face
851 continue;
852
853 if (!aSI.HasReference())
854 // Face has no face info
855 continue;
856
d03c0898 857 if (UserBreak(aPSOuter))
858 {
859 return;
860 }
861
d3578357 862 const Bnd_Box& aBoxF = aSI.Box();
9324aa2d 863 BOPTools_BoxTreeSelector aSelector;
864 aSelector.SetBox(Bnd_Tools::Bnd2BVH(aBoxF));
865 aSelector.SetBVHSet (&aBBTree);
866 if (!aSelector.Select())
d3578357 867 continue;
868
869 const TopoDS_Face& aF = TopoDS::Face(aSI.Shape());
870 const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF);
871 // Vertices of the face
872 TColStd_MapOfInteger aMVF;
873 const TColStd_MapOfInteger* pMVF[] = { &aFI.VerticesOn(),
874 &aFI.VerticesIn(),
875 &aFI.VerticesSc() };
876 for (Standard_Integer iM = 0; iM < 3; ++iM)
877 {
878 TColStd_MapIteratorOfMapOfInteger itM(*pMVF[iM]);
879 for (; itM.More(); itM.Next())
880 aMVF.Add(itM.Value());
881 }
882
883 // Pave Blocks of the face
884 const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(),
885 &aFI.PaveBlocksIn(),
886 &aFI.PaveBlocksSc() };
887 for (Standard_Integer iM = 0; iM < 3; ++iM)
888 {
889 const Standard_Integer aNb = pMPBF[iM]->Extent();
890 for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB)
891 {
892 const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB);
893 aMVF.Add(aPB->Pave1().Index());
894 aMVF.Add(aPB->Pave2().Index());
895 }
896 }
897
898 // Projection tool
899 GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
62fbfa98 900 BRepAdaptor_Surface& aSurfAdaptor = myContext->SurfaceAdaptor (aF);
d3578357 901
902 // Iterate on pave blocks and combine pairs containing
903 // the same vertices
904 const TColStd_ListOfInteger& aLIPB = aSelector.Indices();
905 TColStd_ListOfInteger::Iterator itLIPB(aLIPB);
906 for (; itLIPB.More(); itLIPB.Next())
907 {
908 const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value());
909 if (pMPBF[0]->Contains(aPB) ||
910 pMPBF[1]->Contains(aPB) ||
911 pMPBF[2]->Contains(aPB))
912 continue;
913
914 // Check if the face contains both vertices of the pave block
915 Standard_Integer nV1, nV2;
916 aPB->Indices(nV1, nV2);
917 if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2))
918 // Face does not contain the vertices
919 continue;
920
921 // Get the edge
922 Standard_Integer nE;
923 if (!aPB->HasEdge(nE))
924 {
925 nE = aPB->OriginalEdge();
926 if (nE < 0)
927 continue;
928
929 // Make sure that the edge and face came from different arguments
930 if (myDS->Rank(nF) == myDS->Rank(nE))
931 continue;
932 }
933
934 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
935 BRepAdaptor_Curve aBAC(aE);
936
937 // Check directions coincidence at middle point on the edge
938 // and projection of that point on the face.
939 // If the angle between tangent vector to the curve and normal
62fbfa98 940 // of the face is not in the range of 65 - 115 degrees, do not use the additional
d3578357 941 // tolerance, as it may lead to undesired unification of edge with the face.
942 Standard_Boolean bUseAddTol = Standard_True;
943
944 Standard_Real aTS[2];
945 Bnd_Box aPBBox;
946 Standard_Boolean isSplit;
947 aPB->ShrunkData(aTS[0], aTS[1], aPBBox, isSplit);
948
949 // Middle point
950 gp_Pnt aPOnE;
951 // Tangent vector in the middle point
952 gp_Vec aVETgt;
953 aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt);
954 if (aVETgt.SquareMagnitude() < gp::Resolution())
955 continue;
956
957 aProjPS.Perform(aPOnE);
958 if (!aProjPS.NbPoints())
959 continue;
960
961 // Check the distance in the middle point, using the max vertices
962 // tolerance as the criteria.
963 const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
964 const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
c08fd127 965
966 // In the Self-Interference check mode we are interested in real
967 // intersections only, so use only the real tolerance of edges,
968 // no need to use the extended tolerance.
969 Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
970 2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
d3578357 971
972 if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
973 continue;
974
975 Standard_Real U, V;
976 aProjPS.LowerDistanceParameters(U, V);
977 if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V)))
978 continue;
979
62fbfa98 980 if (aSurfAdaptor.GetType() != GeomAbs_Plane ||
981 aBAC.GetType() != GeomAbs_Line)
d3578357 982 {
62fbfa98 983 gp_Pnt aPOnS = aProjPS.NearestPoint();
984 gp_Vec aVFNorm(aPOnS, aPOnE);
985 if (aVFNorm.SquareMagnitude() > gp::Resolution())
986 {
987 // Angle between vectors should be close to 90 degrees.
988 // We allow deviation of 25 degrees.
989 Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized());
990 if (Abs(aCos) > 0.4226)
991 bUseAddTol = Standard_False;
992 }
d3578357 993 }
994
995 // Compute an addition to Fuzzy value
996 Standard_Real aTolAdd = 0.0;
997 if (bUseAddTol)
998 {
999 // Compute the distance from the bounding points of the edge
1000 // to the face and use the maximal of these distances as a
1001 // fuzzy tolerance for the intersection.
1002 // Use the maximal tolerance of the pave block's vertices
1003 // as a max criteria for the computed distance.
1004
1005 for (Standard_Integer iP = 0; iP < 2; ++iP)
1006 {
1007 gp_Pnt aP = aBAC.Value(aTS[iP]);
1008 aProjPS.Perform(aP);
1009 if (aProjPS.NbPoints())
1010 {
1011 Standard_Real aDistEF = aProjPS.LowerDistance();
1012 if (aDistEF < aTolCheck && aDistEF > aTolAdd)
1013 aTolAdd = aDistEF;
1014 }
1015 }
1016 if (aTolAdd > 0.)
1017 {
1018 aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF));
1019 if (aTolAdd < 0.)
1020 aTolAdd = 0.;
1021 }
1022 }
1023
1024 Standard_Boolean bIntersect = aTolAdd > 0;
1025 if (!bIntersect)
1026 {
1027 const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF);
1028 bIntersect = !pMPB || !(pMPB->Contains(aPB));
1029 }
1030
1031 if (bIntersect)
1032 {
1033 // Prepare pair for intersection
1034 BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Appended();
1035 aEdgeFace.SetIndices(nE, nF);
1036 aEdgeFace.SetPaveBlock(aPB);
1037 aEdgeFace.SetEdge(aE);
1038 aEdgeFace.SetFace(aF);
c08fd127 1039 aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
d3578357 1040 aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
1041 aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
1042 aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
d3578357 1043 }
1044 }
1045 }
1046
1047 Standard_Integer aNbEFs = aVEdgeFace.Length();
1048 if (!aNbEFs)
d03c0898 1049 {
d3578357 1050 return;
d03c0898 1051 }
1052
1053 // close preparation step
1054 aPSOuter.Next(0.7);
d3578357 1055
1056 aPBMap.Clear();
1103eb60 1057 anAlloc->Reset(false);
d3578357 1058
d03c0898 1059 Message_ProgressScope aPS(aPSOuter.Next(9), "Checking for edges coinciding with faces", aNbEFs);
1060 for (Standard_Integer i = 0; i < aNbEFs; i++)
1061 {
1062 BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.ChangeValue(i);
1063 aEdgeFace.SetProgressRange(aPS.Next());
1064 }
d3578357 1065 // Perform intersection of the found pairs
fc867b96 1066 BOPTools_Parallel::Perform (myRunParallel, aVEdgeFace, myContext);
d03c0898 1067 if (UserBreak(aPSOuter))
1068 {
1069 return;
1070 }
d3578357 1071
1072 BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
1073 if (theAddInterf && aEFs.IsEmpty())
1074 aEFs.SetIncrement(10);
1075
1076 // Analyze the results of intersection looking for TopAbs_EDGE
1077 // intersection type only.
1078
1079 // Collect all pairs for common block creation
1080 BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc);
d3578357 1081 for (Standard_Integer i = 0; i < aNbEFs; ++i)
1082 {
d03c0898 1083 if (UserBreak(aPSOuter))
1084 {
1085 return;
1086 }
d3578357 1087 BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i);
1088 if (!anEdgeFace.IsDone() || anEdgeFace.HasErrors())
1089 {
1090 // Warn about failed intersection of sub-shapes
1091 AddIntersectionFailedWarning(anEdgeFace.Edge(), anEdgeFace.Face());
1092 continue;
1093 }
1094
1095 const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts();
1096 if (aCParts.Length() != 1)
1097 continue;
1098
1099 const IntTools_CommonPrt& aCP = aCParts(1);
1100 if (aCP.Type() != TopAbs_EDGE)
1101 continue;
1102
1103 Standard_Integer nE, nF;
1104 anEdgeFace.Indices(nE, nF);
1105 if (theAddInterf)
1106 {
1107 // Add interference
1108 BOPDS_InterfEF& aEF = aEFs.Appended();
1109 aEF.SetIndices(nE, nF);
1110 aEF.SetCommonPart(aCP);
1111 myDS->AddInterf(nE, nF);
1112 }
1113
1114 const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock();
1115 // Update face information with new IN pave block
1116 myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB);
1117 if (theAddInterf)
1118 // Fill map for common blocks creation
1119 BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc);
1120 }
1121
1122 if (aMPBLI.Extent())
1123 // Create new common blocks for coinciding pairs
1124 BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS);
1125}