0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_3.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
19#include <Bnd_Box.hxx>
42cf5bc1 20#include <BOPAlgo_PaveFiller.hxx>
42cf5bc1 21#include <BOPAlgo_Tools.hxx>
33ba8565 22#include <BOPAlgo_Alerts.hxx>
a942f2da 23#include <BOPCol_NCVector.hxx>
c7b59798 24#include <BOPCol_Parallel.hxx>
4e57c75e 25#include <BOPDS_CommonBlock.hxx>
26#include <BOPDS_CoupleOfPaveBlocks.hxx>
42cf5bc1 27#include <BOPDS_DS.hxx>
4e57c75e 28#include <BOPDS_Interf.hxx>
42cf5bc1 29#include <BOPDS_Iterator.hxx>
30#include <BOPDS_MapOfPaveBlock.hxx>
4e57c75e 31#include <BOPDS_Pave.hxx>
42cf5bc1 32#include <BOPDS_PaveBlock.hxx>
33#include <BOPDS_VectorOfInterfEE.hxx>
34#include <BOPTools_AlgoTools.hxx>
01b5b3df 35#include <BndLib_Add3dCurve.hxx>
42cf5bc1 36#include <BRep_Tool.hxx>
33ba8565 37#include <BRep_Builder.hxx>
3510db62 38#include <BRepAdaptor_Curve.hxx>
42cf5bc1 39#include <gp_Pnt.hxx>
40#include <IntTools_CommonPrt.hxx>
41#include <IntTools_Context.hxx>
42#include <IntTools_EdgeEdge.hxx>
43#include <IntTools_Range.hxx>
44#include <IntTools_SequenceOfCommonPrts.hxx>
45#include <IntTools_SequenceOfRanges.hxx>
46#include <IntTools_ShrunkRange.hxx>
47#include <IntTools_Tools.hxx>
42cf5bc1 48#include <Precision.hxx>
8ae442a8 49#include <TopoDS.hxx>
42cf5bc1 50#include <TopoDS_Edge.hxx>
42cf5bc1 51#include <TopoDS_Vertex.hxx>
db8e4b9a 52
a2098360 53/////////////////////////////////////////////////////////////////////////
a942f2da 54//=======================================================================
55//class : BOPAlgo_EdgeEdge
56//purpose :
57//=======================================================================
36f4947b 58class BOPAlgo_EdgeEdge :
59 public IntTools_EdgeEdge,
60 public BOPAlgo_Algo {
61
a942f2da 62 public:
36f4947b 63
64 DEFINE_STANDARD_ALLOC
65 //
66 BOPAlgo_EdgeEdge():
67 IntTools_EdgeEdge(),
68 BOPAlgo_Algo() {
a942f2da 69 };
70 //
36f4947b 71 virtual ~BOPAlgo_EdgeEdge(){
a942f2da 72 };
73 //
74 void SetPaveBlock1(const Handle(BOPDS_PaveBlock)& aPB) {
75 myPB1=aPB;
76 }
77 //
78 Handle(BOPDS_PaveBlock)& PaveBlock1() {
79 return myPB1;
80 }
81 //
82 void SetPaveBlock2(const Handle(BOPDS_PaveBlock)& aPB) {
83 myPB2=aPB;
84 }
85 //
86 Handle(BOPDS_PaveBlock)& PaveBlock2() {
87 return myPB2;
88 }
36f4947b 89 //
0d0481c7 90 void SetFuzzyValue(const Standard_Real theFuzz) {
91 IntTools_EdgeEdge::SetFuzzyValue(theFuzz);
92 }
93 //
36f4947b 94 virtual void Perform() {
95 BOPAlgo_Algo::UserBreak();
96 IntTools_EdgeEdge::Perform();
97 }
a942f2da 98 //
99 protected:
100 Handle(BOPDS_PaveBlock) myPB1;
101 Handle(BOPDS_PaveBlock) myPB2;
102};
103//
505abfb8 104//=======================================================================
105typedef BOPCol_NCVector
106 <BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge;
a942f2da 107//
c7b59798 108typedef BOPCol_Functor
505abfb8 109 <BOPAlgo_EdgeEdge,
110 BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeFunctor;
111//
c7b59798 112typedef BOPCol_Cnt
505abfb8 113 <BOPAlgo_EdgeEdgeFunctor,
114 BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeCnt;
a942f2da 115//
a2098360 116/////////////////////////////////////////////////////////////////////////
117//=======================================================================
4e57c75e 118// function: PerformEE
119// purpose:
120//=======================================================================
db8e4b9a 121void BOPAlgo_PaveFiller::PerformEE()
4e57c75e 122{
505abfb8 123 FillShrunkData(TopAbs_EDGE, TopAbs_EDGE);
124 //
4e57c75e 125 myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE);
33ba8565 126 Standard_Integer iSize = myIterator->ExpectedLength();
4e57c75e 127 if (!iSize) {
128 return;
129 }
130 //
25dfc507 131 Standard_Boolean bExpressCompute, bIsPBSplittable1, bIsPBSplittable2;
01b5b3df 132 Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbEdgeEdge;
6dc83e21 133 Standard_Integer nV11, nV12, nV21, nV22;
a942f2da 134 Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22;
135 TopAbs_ShapeEnum aType;
136 BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2;
488e5b9d 137 Handle(NCollection_BaseAllocator) aAllocator;
a942f2da 138 BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
139 BOPDS_MapIteratorOfMapOfPaveBlock aItPB;
8ae442a8 140 // keep modified edges for further update
141 BOPCol_MapOfInteger aMEdges;
a942f2da 142 //
488e5b9d 143 aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
4e57c75e 144 //-----------------------------------------------------scope f
4e57c75e 145 BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator);
146 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
01b5b3df 147 BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
4e57c75e 148 //
4e57c75e 149 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
4e57c75e 150 aEEs.SetIncrement(iSize);
4e57c75e 151 //
152 for (; myIterator->More(); myIterator->Next()) {
25dfc507 153 myIterator->Value(nE1, nE2);
4e57c75e 154 //
155 const BOPDS_ShapeInfo& aSIE1=myDS->ShapeInfo(nE1);
156 if (aSIE1.HasFlag()){
157 continue;
158 }
159 const BOPDS_ShapeInfo& aSIE2=myDS->ShapeInfo(nE2);
160 if (aSIE2.HasFlag()){
161 continue;
162 }
163 //
752f9d72 164 BOPDS_ListOfPaveBlock& aLPB1 = myDS->ChangePaveBlocks(nE1);
165 if (aLPB1.IsEmpty()) {
166 continue;
167 }
168 //
169 BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE2);
170 if (aLPB2.IsEmpty()) {
171 continue;
172 }
173 //
4e57c75e 174 const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape()));
01b5b3df 175 const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape()));
4e57c75e 176 //
4e57c75e 177 aIt1.Initialize(aLPB1);
178 for (; aIt1.More(); aIt1.Next()) {
179 Bnd_Box aBB1;
180 //
181 Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue();
01b5b3df 182 //
183 if (!GetPBBox(aE1, aPB1, aDMPBBox, aT11, aT12, aTS11, aTS12, aBB1)) {
505abfb8 184 continue;
4e57c75e 185 }
4e57c75e 186 //
6dc83e21 187 aPB1->Indices(nV11, nV12);
188 //
4e57c75e 189 aIt2.Initialize(aLPB2);
190 for (; aIt2.More(); aIt2.Next()) {
191 Bnd_Box aBB2;
192 //
193 Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue();
01b5b3df 194 //
195 if (!GetPBBox(aE2, aPB2, aDMPBBox, aT21, aT22, aTS21, aTS22, aBB2)) {
505abfb8 196 continue;
4e57c75e 197 }
4e57c75e 198 //
199 if (aBB1.IsOut(aBB2)) {
200 continue;
201 }
202 //
6dc83e21 203 aPB2->Indices(nV21, nV22);
204 //
205 bExpressCompute=((nV11==nV21 && nV12==nV22) ||
206 (nV12==nV21 && nV11==nV22));
207 //
a942f2da 208 BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge.Append1();
6dc83e21 209 //
210 anEdgeEdge.UseQuickCoincidenceCheck(bExpressCompute);
211 //
a942f2da 212 anEdgeEdge.SetPaveBlock1(aPB1);
213 anEdgeEdge.SetPaveBlock2(aPB2);
214 //
ec0cdc0e 215 anEdgeEdge.SetEdge1(aE1, aT11, aT12);
216 anEdgeEdge.SetEdge2(aE2, aT21, aT22);
0d0481c7 217 anEdgeEdge.SetFuzzyValue(myFuzzyValue);
36f4947b 218 anEdgeEdge.SetProgressIndicator(myProgressIndicator);
a942f2da 219 }//for (; aIt2.More(); aIt2.Next()) {
220 }//for (; aIt1.More(); aIt1.Next()) {
221 }//for (; myIterator->More(); myIterator->Next()) {
222 //
01b5b3df 223 aNbEdgeEdge=aVEdgeEdge.Extent();
a942f2da 224 //======================================================
225 BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge);
226 //======================================================
227 //
01b5b3df 228 for (k = 0; k < aNbEdgeEdge; ++k) {
a942f2da 229 Bnd_Box aBB1, aBB2;
230 //
231 BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k);
232 if (!anEdgeEdge.IsDone()) {
233 continue;
234 }
235 //
51db0179 236 const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts();
237 aNbCPrts = aCPrts.Length();
238 if (!aNbCPrts) {
239 continue;
240 }
a942f2da 241 //--------------------------------------------
242 Handle(BOPDS_PaveBlock)& aPB1=anEdgeEdge.PaveBlock1();
243 nE1=aPB1->OriginalEdge();
244 aPB1->Range(aT11, aT12);
01b5b3df 245 if (!aPB1->HasShrunkData()) {
246 aTS11 = aT11;
247 aTS12 = aT12;
248 bIsPBSplittable1 = Standard_False;
249 }
250 else {
251 aPB1->ShrunkData(aTS11, aTS12, aBB1, bIsPBSplittable1);
252 }
a942f2da 253 //
254 Handle(BOPDS_PaveBlock)& aPB2=anEdgeEdge.PaveBlock2();
255 nE2=aPB2->OriginalEdge();
256 aPB2->Range(aT21, aT22);
01b5b3df 257 if (!aPB2->HasShrunkData()) {
258 aTS21 = aT21;
259 aTS22 = aT22;
260 bIsPBSplittable2 = Standard_False;
261 }
262 else {
263 aPB2->ShrunkData(aTS21, aTS22, aBB2, bIsPBSplittable2);
264 }
a942f2da 265 //
266 //--------------------------------------------
267 IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12),
268 aR21(aT21, aTS21), aR22(aTS22, aT22);
269 //
3065019c 270 Standard_Boolean bAnalytical = Standard_False;
51db0179 271 {
3510db62 272 const TopoDS_Edge& aOE1 = *(TopoDS_Edge*)&myDS->Shape(nE1);
273 const TopoDS_Edge& aOE2 = *(TopoDS_Edge*)&myDS->Shape(nE2);
274 //
275 BRepAdaptor_Curve aBAC1(aOE1), aBAC2(aOE2);
276 //
3065019c 277 GeomAbs_CurveType aType1 = aBAC1.GetType();
278 GeomAbs_CurveType aType2 = aBAC2.GetType();
279 //
280 bAnalytical = (((aType1 == GeomAbs_Line) &&
281 (aType2 == GeomAbs_Line ||
282 aType2 == GeomAbs_Circle)) ||
283 ((aType2 == GeomAbs_Line) &&
284 (aType1 == GeomAbs_Line ||
285 aType1 == GeomAbs_Circle)));
3510db62 286 }
287 //
a942f2da 288 for (i=1; i<=aNbCPrts; ++i) {
289 const IntTools_CommonPrt& aCPart=aCPrts(i);
290 //
291 const TopoDS_Edge& aE1=aCPart.Edge1();
292 const TopoDS_Edge& aE2=aCPart.Edge2();
293 //
294 aType=aCPart.Type();
295 switch (aType) {
296 case TopAbs_VERTEX: {
01b5b3df 297 if (!bIsPBSplittable1 || !bIsPBSplittable2) {
298 continue;
299 }
300 //
a942f2da 301 Standard_Boolean bIsOnPave[4], bFlag;
302 Standard_Integer nV[4], j;
303 Standard_Real aT1, aT2, aTol;
304 TopoDS_Vertex aVnew;
305 IntTools_Range aCR1, aCR2;
306 //
1e143abb 307 IntTools_Tools::VertexParameters(aCPart, aT1, aT2);
a942f2da 308 aTol = Precision::Confusion();
309 aCR1 = aCPart.Range1();
310 aCR2 = aCPart.Ranges2()(1);
311 //
312 //decide to keep the pave or not
1e143abb 313 bIsOnPave[0] = IntTools_Tools::IsOnPave1(aT1, aR11, aTol) ||
314 IntTools_Tools::IsOnPave1(aR11.First(), aCR1, aTol);
315 bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) ||
316 IntTools_Tools::IsOnPave1(aR12.Last(), aCR1, aTol);
317 bIsOnPave[2] = IntTools_Tools::IsOnPave1(aT2, aR21, aTol) ||
318 IntTools_Tools::IsOnPave1(aR21.First(), aCR2, aTol);
319 bIsOnPave[3] = IntTools_Tools::IsOnPave1(aT2, aR22, aTol) ||
320 IntTools_Tools::IsOnPave1(aR22.Last(), aCR2, aTol);
a942f2da 321 //
322 aPB1->Indices(nV[0], nV[1]);
323 aPB2->Indices(nV[2], nV[3]);
324 //
325 if((bIsOnPave[0] && bIsOnPave[2]) ||
326 (bIsOnPave[0] && bIsOnPave[3]) ||
327 (bIsOnPave[1] && bIsOnPave[2]) ||
328 (bIsOnPave[1] && bIsOnPave[3])) {
329 continue;
330 }
331 //
332 bFlag = Standard_False;
333 for (j = 0; j < 4; ++j) {
334 if (bIsOnPave[j]) {
335 //add interf VE(nV[j], nE)
336 Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1;
8ae442a8 337 ForceInterfVE(nV[j], aPB, aMEdges);
a942f2da 338 bFlag = Standard_True;
339 break;
340 }
341 }
342 if (bFlag) {
24542bc0 343 BOPDS_InterfEE& aEE = aEEs.Append1();
344 aEE.SetIndices(nE1, nE2);
345 aEE.SetCommonPart(aCPart);
a942f2da 346 continue;
347 }
348 //
349 BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
3510db62 350 Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
3065019c 351 if (bAnalytical) {
3510db62 352 // increase tolerance for Line/Line intersection, but do not update
353 // the vertex till its intersection with some other shape
3065019c 354 Standard_Real aTolMin = (BRepAdaptor_Curve(aE1).GetType() == GeomAbs_Line) ?
355 (aCR1.Last() - aCR1.First()) / 2. : (aCR2.Last() - aCR2.First()) / 2.;
8bb8064e 356 if (aTolMin > aTolVnew) {
357 aTolVnew = aTolMin;
3510db62 358 }
359 }
a942f2da 360 // <-LXBR
361 {
51740958 362 Standard_Integer nVS[2], iFound;
3510db62 363 Standard_Real aTolVx, aD2, aDT2;
a942f2da 364 BOPCol_MapOfInteger aMV;
365 gp_Pnt aPnew, aPx;
4e57c75e 366 //
a942f2da 367 iFound=0;
368 j=-1;
369 aMV.Add(nV[0]);
370 aMV.Add(nV[1]);
371 //
372 if (aMV.Contains(nV[2])) {
373 ++j;
374 nVS[j]=nV[2];
375 }
376 if (aMV.Contains(nV[3])) {
377 ++j;
378 nVS[j]=nV[3];
379 }
380 //
a942f2da 381 aPnew=BRep_Tool::Pnt(aVnew);
382 //
51740958 383 for (Standard_Integer k1=0; k1<=j; ++k1) {
384 const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1]));
a942f2da 385 aTolVx=BRep_Tool::Tolerance(aVx);
386 aPx=BRep_Tool::Pnt(aVx);
387 aD2=aPnew.SquareDistance(aPx);
388 //
389 aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx);
7eed5d29 390 //
a942f2da 391 if (aD2<aDT2) {
392 iFound=1;
4e57c75e 393 break;
394 }
a942f2da 395 }
396 //
397 if (iFound) {
398 continue;
399 }
400 }
402bfe81 401 //
a942f2da 402 // 1
402bfe81 403 BOPDS_InterfEE& aEE=aEEs.Append1();
404 iX=aEEs.Extent()-1;
a942f2da 405 aEE.SetIndices(nE1, nE2);
406 aEE.SetCommonPart(aCPart);
407 // 2
408 myDS->AddInterf(nE1, nE2);
409 //
410 BOPDS_CoupleOfPaveBlocks aCPB;
411 //
412 aCPB.SetPaveBlocks(aPB1, aPB2);
413 aCPB.SetIndexInterf(iX);
3510db62 414 aCPB.SetTolerance(aTolVnew);
a942f2da 415 aMVCPB.Add(aVnew, aCPB);
416 }//case TopAbs_VERTEX:
417 break;
418 //
419 case TopAbs_EDGE: {
420 if (aNbCPrts > 1) {
4e57c75e 421 break;
a942f2da 422 }
423 //
424 Standard_Boolean bHasSameBounds;
425 bHasSameBounds=aPB1->HasSameBounds(aPB2);
426 if (!bHasSameBounds) {
427 break;
428 }
429 // 1
402bfe81 430 BOPDS_InterfEE& aEE=aEEs.Append1();
431 iX=aEEs.Extent()-1;
a942f2da 432 aEE.SetIndices(nE1, nE2);
433 aEE.SetCommonPart(aCPart);
434 // 2
435 myDS->AddInterf(nE1, nE2);
436 //
edfa30de 437 BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock), TColStd_MapTransientHasher>(aPB1, aPB2, aMPBLPB, aAllocator);
a942f2da 438 }//case TopAbs_EDGE
439 break;
440 default:
441 break;
442 }//switch (aType) {
443 }//for (i=1; i<=aNbCPrts; i++) {
444 }//for (k=0; k < aNbFdgeEdge; ++k) {
4e57c75e 445 //
446 //=========================================
447 // post treatment
448 //=========================================
8ae442a8 449 BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS);
450 PerformNewVertices(aMVCPB, aAllocator);
451 //
452 if (aMEdges.Extent()) {
453 Standard_Integer aNbV = aMVCPB.Extent();
454 for (i = 1; i <= aNbV; ++i) {
455 Handle(BOPDS_PaveBlock) aPB1, aPB2;
456 const BOPDS_CoupleOfPaveBlocks& aCPB = aMVCPB.FindFromIndex(i);
457 aCPB.PaveBlocks(aPB1, aPB2);
a3476a9f 458 //
8ae442a8 459 aMEdges.Remove(aPB1->OriginalEdge());
460 aMEdges.Remove(aPB2->OriginalEdge());
b4109929 461 }
8ae442a8 462 //
463 SplitPaveBlocks(aMEdges, Standard_False);
b4109929 464 }
465 //
4e57c75e 466 //-----------------------------------------------------scope t
467 aMPBLPB.Clear();
468 aMVCPB.Clear();
4e57c75e 469}
470//=======================================================================
3510db62 471//function : PerformVerticesEE
4e57c75e 472//purpose :
473//=======================================================================
8ae442a8 474void BOPAlgo_PaveFiller::PerformNewVertices
db8e4b9a 475 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
8ae442a8 476 const Handle(NCollection_BaseAllocator)& theAllocator,
477 const Standard_Boolean bIsEEIntersection)
4e57c75e 478{
8ae442a8 479 Standard_Integer aNbV = theMVCPB.Extent();
4e57c75e 480 if (!aNbV) {
8ae442a8 481 return;
4e57c75e 482 }
483 //
8ae442a8 484 Standard_Real aTolAdd = myFuzzyValue / 2.;
4e57c75e 485 //
8ae442a8 486 // 1. Fuse the new vertices
4e57c75e 487 BOPCol_IndexedDataMapOfShapeListOfShape aImages;
3510db62 488 TreatNewVertices(theMVCPB, aImages);
4e57c75e 489 //
8ae442a8 490 // 2. Add new vertices to myDS and connect indices to CPB structure
491 BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
492 BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
493 //
494 Standard_Integer i, aNb = aImages.Extent();
495 for (i = 1; i <= aNb; ++i) {
496 const TopoDS_Vertex& aV = TopoDS::Vertex(aImages.FindKey(i));
497 const BOPCol_ListOfShape& aLVSD = aImages.FindFromIndex(i);
4e57c75e 498 //
8ae442a8 499 BOPDS_ShapeInfo aSI;
500 aSI.SetShapeType(TopAbs_VERTEX);
4e57c75e 501 aSI.SetShape(aV);
8ae442a8 502 Standard_Integer iV = myDS->Append(aSI);
4e57c75e 503 //
8ae442a8 504 BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(iV);
505 Bnd_Box& aBox = aSIDS.ChangeBox();
506 aBox.Add(BRep_Tool::Pnt(aV));
507 aBox.SetGap(BRep_Tool::Tolerance(aV) + aTolAdd);
4e57c75e 508 //
8ae442a8 509 BOPCol_ListIteratorOfListOfShape aItLS(aLVSD);
4e57c75e 510 for (; aItLS.More(); aItLS.Next()) {
511 const TopoDS_Shape& aVx = aItLS.Value();
8ae442a8 512 BOPDS_CoupleOfPaveBlocks &aCPB = theMVCPB.ChangeFromKey(aVx);
4e57c75e 513 aCPB.SetIndex(iV);
8ae442a8 514 // update interference
515 Standard_Integer iX = aCPB.IndexInterf();
516 BOPDS_Interf *aInt = bIsEEIntersection ? (BOPDS_Interf*)(&aEEs(iX)) : (BOPDS_Interf*) (&aEFs(iX));
517 aInt->SetIndexNew(iV);
4e57c75e 518 }
519 }
520 //
8ae442a8 521 // 3. Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
522 BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
523 for (i = 1; i <= aNbV; ++i) {
524 const BOPDS_CoupleOfPaveBlocks& aCPB = theMVCPB.FindFromIndex(i);
525 Standard_Integer iV = aCPB.Index();
4e57c75e 526 //
8ae442a8 527 Handle(BOPDS_PaveBlock) aPB[2];
528 aCPB.PaveBlocks(aPB[0], aPB[1]);
529 for (Standard_Integer j = 0; j < 2; ++j) {
530 BOPCol_ListOfInteger *pLI = aMPBLI.ChangeSeek(aPB[j]);
531 if (!pLI) {
532 pLI = &aMPBLI(aMPBLI.Add(aPB[j], BOPCol_ListOfInteger(theAllocator)));
4e57c75e 533 }
8ae442a8 534 pLI->Append(iV);
4e57c75e 535 //
8ae442a8 536 if (aPB[0] == aPB[1]) {
537 break;
538 }
4e57c75e 539 }
540 }
4e57c75e 541 //
8ae442a8 542 // 4. Compute Extra Paves and split Pave blocks by the Extra paves
543 IntersectVE(aMPBLI, Standard_False);
4e57c75e 544}
4e57c75e 545//=======================================================================
546//function : TreatNewVertices
547//purpose :
548//=======================================================================
db8e4b9a 549void BOPAlgo_PaveFiller::TreatNewVertices
8ae442a8 550 (const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
db8e4b9a 551 BOPCol_IndexedDataMapOfShapeListOfShape& myImages)
4e57c75e 552{
4e57c75e 553 //
8ae442a8 554 // Prepare for intersection
555 BOPCol_IndexedDataMapOfShapeReal aVerts;
556 Standard_Integer i, aNbV = theMVCPB.Extent();
557 for (i = 1; i <= aNbV; ++i) {
558 const TopoDS_Shape& aV = theMVCPB.FindKey(i);
559 Standard_Real aTol = theMVCPB.FindFromIndex(i).Tolerance();
560 aVerts.Add(aV, aTol);
4e57c75e 561 }
562 //
8ae442a8 563 // Perform intersection
564 BOPCol_ListOfListOfShape aChains;
565 BOPAlgo_Tools::IntersectVertices(aVerts, myRunParallel, myFuzzyValue, aChains);
a2098360 566 //
8ae442a8 567 // Treat the results - make new vertices for each chain
568 BOPCol_ListOfListOfShape::Iterator aItC(aChains);
569 for (; aItC.More(); aItC.Next()) {
570 const BOPCol_ListOfShape& aLVSD = aItC.Value();
4e57c75e 571 //
8ae442a8 572 TopoDS_Vertex aVNew;
573 BOPTools_AlgoTools::MakeVertex(aLVSD, aVNew);
574 myImages.Add(aVNew, aLVSD);
4e57c75e 575 }
576}
4e57c75e 577//=======================================================================
578//function : FillShrunkData
579//purpose :
580//=======================================================================
db8e4b9a 581void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
4e57c75e 582{
33ba8565 583 // Vertices
584 Standard_Integer nV1, nV2;
585 thePB->Indices(nV1, nV2);
4e57c75e 586 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
4e57c75e 587 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
33ba8565 588 // Original edge
589 Standard_Integer nE = thePB->OriginalEdge();
4e57c75e 590 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
33ba8565 591 // Range
592 Standard_Real aT1, aT2;
593 thePB->Range(aT1, aT2);
4e57c75e 594 //
33ba8565 595 IntTools_ShrunkRange aSR;
505abfb8 596 aSR.SetContext(myContext);
597 aSR.SetData(aE, aT1, aT2, aV1, aV2);
4e57c75e 598 aSR.Perform();
33ba8565 599 // Analyze the results of computations
600 AnalyzeShrunkData(thePB, aSR);
601}
602//=======================================================================
603// function: AnalyzeShrunkData
604// purpose:
605//=======================================================================
606void BOPAlgo_PaveFiller::AnalyzeShrunkData(const Handle(BOPDS_PaveBlock)& thePB,
607 const IntTools_ShrunkRange& theSR)
608{
609 // in case of error treat the warning status
610 Standard_Boolean bWholeEdge = Standard_False;
611 TopoDS_Shape aWarnShape;
612 //
613 if (!theSR.IsDone() || !theSR.IsSplittable()) {
614 Standard_Real aEFirst, aELast, aPBFirst, aPBLast;
615 BRep_Tool::Range(theSR.Edge(), aEFirst, aELast);
616 thePB->Range(aPBFirst, aPBLast);
617 bWholeEdge = !(aPBFirst > aEFirst || aPBLast < aELast);
618 if (bWholeEdge) {
619 aWarnShape = theSR.Edge();
620 }
621 else {
622 const TopoDS_Shape& aV1 = myDS->Shape(thePB->Pave1().Index());
623 const TopoDS_Shape& aV2 = myDS->Shape(thePB->Pave2().Index());
624 BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape));
625 BRep_Builder().Add(aWarnShape, theSR.Edge());
626 BRep_Builder().Add(aWarnShape, aV1);
627 BRep_Builder().Add(aWarnShape, aV2);
628 }
629 //
630 if (!theSR.IsDone()) {
631 if (bWholeEdge)
632 AddWarning (new BOPAlgo_AlertTooSmallEdge (aWarnShape));
633 else
634 AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape));
635 return;
636 }
637 //
638 if (bWholeEdge)
639 AddWarning (new BOPAlgo_AlertNotSplittableEdge (aWarnShape));
640 else
641 AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape));
4e57c75e 642 }
643 //
33ba8565 644 Standard_Real aTS1, aTS2;
645 theSR.ShrunkRange(aTS1, aTS2);
646 Bnd_Box aBox = theSR.BndBox();
647 aBox.SetGap(aBox.GetGap() + myFuzzyValue / 2.);
648 thePB->SetShrunkData(aTS1, aTS2, aBox, theSR.IsSplittable());
4e57c75e 649}
b4109929 650//=======================================================================
651//function : ForceInterfVE
652//purpose :
653//=======================================================================
654void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
655 Handle(BOPDS_PaveBlock)& aPB,
8ae442a8 656 BOPCol_MapOfInteger& theMEdges)
b4109929 657{
3510db62 658 Standard_Integer nE, nVx, nVSD, iFlag;
659 Standard_Real aT, aTolVNew;
b4109929 660 //
661 nE = aPB->OriginalEdge();
662 //
663 const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
664 if (aSIE.HasSubShape(nV)) {
665 return;
666 }
667 //
668 if (myDS->HasInterf(nV, nE)) {
669 return;
33ba8565 670 }
b4109929 671 //
672 if (myDS->HasInterfShapeSubShapes(nV, nE)) {
673 return;
674 }
675 //
3510db62 676 if (aPB->Pave1().Index() == nV ||
677 aPB->Pave2().Index() == nV) {
b4109929 678 return;
679 }
680 //
3510db62 681 nVx = nV;
682 if (myDS->HasShapeSD(nV, nVSD)) {
683 nVx = nVSD;
684 }
b4109929 685 //
3510db62 686 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nVx);
687 const TopoDS_Edge& aE = *(TopoDS_Edge*) &myDS->Shape(nE);
b4109929 688 //
0d0481c7 689 iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew, myFuzzyValue);
3510db62 690 if (iFlag == 0 || iFlag == -4) {
b4109929 691 BOPDS_Pave aPave;
692 //
b4109929 693 //
694 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
a3476a9f 695 aVEs.SetIncrement(10);
3510db62 696 // 1
402bfe81 697 BOPDS_InterfVE& aVE=aVEs.Append1();
b4109929 698 aVE.SetIndices(nV, nE);
699 aVE.SetParameter(aT);
3510db62 700 // 2
b4109929 701 myDS->AddInterf(nV, nE);
702 //
3510db62 703 // 3 update vertex V/E if necessary
704 nVx=UpdateVertex(nV, aTolVNew);
705 // 4
706 if (myDS->IsNewShape(nVx)) {
707 aVE.SetIndexNew(nVx);
708 }
709 // 5 append ext pave to pave block
710 aPave.SetIndex(nVx);
b4109929 711 aPave.SetParameter(aT);
712 aPB->AppendExtPave(aPave);
713 //
8ae442a8 714 theMEdges.Add(nE);
33ba8565 715 //
716 // check for self-interference
717 Standard_Integer iRV = myDS->Rank(nV);
718 if (iRV >= 0 && iRV == myDS->Rank(nE)) {
719 // add warning status
720 TopoDS_Compound aWC;
721 BRep_Builder().MakeCompound(aWC);
722 BRep_Builder().Add(aWC, aV);
723 BRep_Builder().Add(aWC, aE);
724 AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
725 }
b4109929 726 }
727}
01b5b3df 728
729//=======================================================================
730//function : GetPBBox
731//purpose :
732//=======================================================================
733Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
734 const Handle(BOPDS_PaveBlock)& thePB,
735 BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox,
736 Standard_Real& theFirst,
737 Standard_Real& theLast,
738 Standard_Real& theSFirst,
739 Standard_Real& theSLast,
740 Bnd_Box& theBox)
741{
742 thePB->Range(theFirst, theLast);
743 // check the validity of PB's range
744 Standard_Boolean bValid = theLast - theFirst > Precision::PConfusion();
745 if (!bValid) {
746 return bValid;
747 }
748 //
749 // check shrunk data
750 if (thePB->HasShrunkData()) {
751 Standard_Boolean bIsSplittable;
752 thePB->ShrunkData(theSFirst, theSLast, theBox, bIsSplittable);
753 return bValid;
754 }
755 //
756 theSFirst = theFirst;
757 theSLast = theLast;
758 // check the map
759 if (thePBBox.IsBound(thePB)) {
760 theBox = thePBBox.Find(thePB);
761 }
762 else {
763 // build bounding box
764 BRepAdaptor_Curve aBAC(theE);
765 Standard_Real aTol = BRep_Tool::Tolerance(theE) + Precision::Confusion();
766 BndLib_Add3dCurve::Add(aBAC, theSFirst, theSLast, aTol, theBox);
767 thePBBox.Bind(thePB, theBox);
768 }
769 return bValid;
770}