0026917: 3D Offset algorithm produces incorrect result
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_6.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
42cf5bc1 18#include <Bnd_Box.hxx>
19#include <BOPAlgo_PaveFiller.hxx>
20#include <BOPAlgo_SectionAttribute.hxx>
21#include <BOPAlgo_Tools.hxx>
4e57c75e 22#include <BOPCol_DataMapOfShapeInteger.hxx>
42cf5bc1 23#include <BOPCol_ListOfInteger.hxx>
24#include <BOPCol_ListOfShape.hxx>
25#include <BOPCol_MapOfInteger.hxx>
a2098360 26#include <BOPCol_NCVector.hxx>
c7b59798 27#include <BOPCol_Parallel.hxx>
42cf5bc1 28#include <BOPDS_CommonBlock.hxx>
29#include <BOPDS_CoupleOfPaveBlocks.hxx>
4e57c75e 30#include <BOPDS_Curve.hxx>
42cf5bc1 31#include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
32#include <BOPDS_DS.hxx>
4e57c75e 33#include <BOPDS_FaceInfo.hxx>
42cf5bc1 34#include <BOPDS_Interf.hxx>
35#include <BOPDS_Iterator.hxx>
36#include <BOPDS_ListOfPave.hxx>
37#include <BOPDS_ListOfPaveBlock.hxx>
4e57c75e 38#include <BOPDS_MapOfPaveBlock.hxx>
39#include <BOPDS_PaveBlock.hxx>
42cf5bc1 40#include <BOPDS_Point.hxx>
41#include <BOPDS_ShapeInfo.hxx>
4e57c75e 42#include <BOPDS_VectorOfCurve.hxx>
43#include <BOPDS_VectorOfPoint.hxx>
3510db62 44#include <BOPTools.hxx>
42cf5bc1 45#include <BOPTools_AlgoTools.hxx>
46#include <BOPTools_AlgoTools3D.hxx>
47#include <BRep_Builder.hxx>
48#include <BRep_Tool.hxx>
3510db62 49#include <BRep_TEdge.hxx>
42cf5bc1 50#include <BRepAdaptor_Curve.hxx>
51#include <BRepAdaptor_Surface.hxx>
52#include <BRepBndLib.hxx>
53#include <BRepBuilderAPI_MakeVertex.hxx>
54#include <BRepTools.hxx>
55#include <Geom2d_Curve.hxx>
56#include <Geom_Curve.hxx>
57#include <GeomAPI_ProjectPointOnCurve.hxx>
58#include <GeomAPI_ProjectPointOnSurf.hxx>
59#include <gp_Pnt.hxx>
60#include <IntSurf_ListOfPntOn2S.hxx>
61#include <IntSurf_PntOn2S.hxx>
3510db62 62#include <IntTools.hxx>
42cf5bc1 63#include <IntTools_Context.hxx>
64#include <IntTools_Curve.hxx>
65#include <IntTools_EdgeFace.hxx>
66#include <IntTools_FaceFace.hxx>
67#include <IntTools_PntOn2Faces.hxx>
68#include <IntTools_SequenceOfCurves.hxx>
69#include <IntTools_SequenceOfPntOn2Faces.hxx>
70#include <IntTools_ShrunkRange.hxx>
71#include <IntTools_Tools.hxx>
42cf5bc1 72#include <Precision.hxx>
73#include <TopExp.hxx>
74#include <TopExp_Explorer.hxx>
3510db62 75#include <TopoDS.hxx>
42cf5bc1 76#include <TopoDS_Compound.hxx>
77#include <TopoDS_Edge.hxx>
78#include <TopoDS_Face.hxx>
79#include <TopoDS_Vertex.hxx>
4e57c75e 80
42cf5bc1 81//
b4109929 82static void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
83 const BRepAdaptor_Surface& aBAS2,
4e57c75e 84 Standard_Real& aTolFF);
85
a2098360 86/////////////////////////////////////////////////////////////////////////
87//=======================================================================
88//class : BOPAlgo_FaceFace
89//purpose :
90//=======================================================================
36f4947b 91class BOPAlgo_FaceFace :
92 public IntTools_FaceFace,
93 public BOPAlgo_Algo {
94
a2098360 95 public:
36f4947b 96 DEFINE_STANDARD_ALLOC
97
98 BOPAlgo_FaceFace() :
99 IntTools_FaceFace(),
100 BOPAlgo_Algo(),
101 myIF1(-1), myIF2(-1), myTolFF(1.e-7) {
a2098360 102 }
103 //
36f4947b 104 virtual ~BOPAlgo_FaceFace() {
a2098360 105 }
106 //
107 void SetIndices(const Standard_Integer nF1,
108 const Standard_Integer nF2) {
109 myIF1=nF1;
110 myIF2=nF2;
111 }
112 //
113 void Indices(Standard_Integer& nF1,
114 Standard_Integer& nF2) const {
115 nF1=myIF1;
116 nF2=myIF2;
117 }
118 //
119 void SetFaces(const TopoDS_Face& aF1,
120 const TopoDS_Face& aF2) {
121 myF1=aF1;
122 myF2=aF2;
123 }
124 //
125 const TopoDS_Face& Face1()const {
126 return myF1;
127 }
128 //
129 const TopoDS_Face& Face2()const {
130 return myF2;
131 }
132 //
133 void SetTolFF(const Standard_Real aTolFF) {
134 myTolFF=aTolFF;
135 }
136 //
137 Standard_Real TolFF() const{
138 return myTolFF;
139 }
140 //
0d0481c7 141 void SetFuzzyValue(const Standard_Real theFuzz) {
142 IntTools_FaceFace::SetFuzzyValue(theFuzz);
143 }
144 //
36f4947b 145 virtual void Perform() {
146 BOPAlgo_Algo::UserBreak();
a2098360 147 IntTools_FaceFace::Perform(myF1, myF2);
148 }
149 //
150 protected:
151 Standard_Integer myIF1;
152 Standard_Integer myIF2;
153 Standard_Real myTolFF;
154 TopoDS_Face myF1;
155 TopoDS_Face myF2;
156};
157//
158//=======================================================================
159typedef BOPCol_NCVector
160 <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
161//
c7b59798 162typedef BOPCol_Functor
a2098360 163 <BOPAlgo_FaceFace,
164 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
165//
c7b59798 166typedef BOPCol_Cnt
a2098360 167 <BOPAlgo_FaceFaceFunctor,
168 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
169/////////////////////////////////////////////////////////////////////////
4e57c75e 170//=======================================================================
171//function : PerformFF
172//purpose :
173//=======================================================================
7ff8f019 174void BOPAlgo_PaveFiller::PerformFF()
4e57c75e 175{
176 Standard_Integer iSize;
177 Standard_Boolean bValid;
178 //
179 myErrorStatus=0;
180 //
181 myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
182 iSize=myIterator->ExpectedLength();
183 if (!iSize) {
184 return;
185 }
186 //
187 Standard_Boolean bJustAdd, bApp, bCompC2D1, bCompC2D2, bIsDone;
7ff8f019 188 Standard_Boolean bToSplit, bTangentFaces;
402bfe81 189 Standard_Integer nF1, nF2, aNbCurves, aNbPoints, i, aNbLP;
a2098360 190 Standard_Integer aNbFaceFace, k;
3510db62 191 Standard_Real aApproxTol, aTolR3D, aTolR2D, aTolFF, aTolReal;
b4109929 192 BRepAdaptor_Surface aBAS1, aBAS2;
af4e6dab 193 BOPCol_MapOfInteger aMI;
a2098360 194 BOPAlgo_VectorOfFaceFace aVFaceFace;
4e57c75e 195 //
196 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
4e57c75e 197 aFFs.SetIncrement(iSize);
4e57c75e 198 //
199 bApp=mySectionAttribute.Approximation();
200 bCompC2D1=mySectionAttribute.PCurveOnS1();
201 bCompC2D2=mySectionAttribute.PCurveOnS2();
202 aApproxTol=1.e-7;
203 bToSplit = Standard_False;
204 //
205 for (; myIterator->More(); myIterator->Next()) {
206 myIterator->Value(nF1, nF2, bJustAdd);
207 if(bJustAdd) {
208 continue;
209 }
210 //
211 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
212 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
213 //
3510db62 214 if (aMI.Add(nF1)) {
215 myDS->UpdateFaceInfoOn(nF1);
216 myDS->UpdateFaceInfoIn(nF1);
217 }
218 if (aMI.Add(nF2)) {
219 myDS->UpdateFaceInfoOn(nF2);
220 myDS->UpdateFaceInfoIn(nF2);
221 }
222 //
b4109929 223 aBAS1.Initialize(aF1, Standard_False);
224 aBAS2.Initialize(aF2, Standard_False);
b4109929 225 if (aBAS1.GetType() == GeomAbs_Plane &&
226 aBAS2.GetType() == GeomAbs_Plane) {
227 Standard_Boolean bToIntersect;
228 //
229 bToIntersect = CheckPlanes(nF1, nF2);
230 if (!bToIntersect) {
402bfe81 231 BOPDS_InterfFF& aFF=aFFs.Append1();
b4109929 232 aFF.SetIndices(nF1, nF2);
233 aFF.Init(0, 0);
234 continue;
235 }
236 }
237 //
a2098360 238 ToleranceFF(aBAS1, aBAS2, aTolFF);
239 //
240 BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
241 //
242 aFaceFace.SetIndices(nF1, nF2);
243 aFaceFace.SetFaces(aF1, aF2);
244 aFaceFace.SetTolFF(aTolFF);
4e57c75e 245 //
246 IntSurf_ListOfPntOn2S aListOfPnts;
247 GetEFPnts(nF1, nF2, aListOfPnts);
248 aNbLP = aListOfPnts.Extent();
249 if (aNbLP) {
250 aFaceFace.SetList(aListOfPnts);
251 }
a2098360 252 //
4e57c75e 253 aFaceFace.SetParameters(bApp, bCompC2D1, bCompC2D2, aApproxTol);
0d0481c7 254 aFaceFace.SetFuzzyValue(myFuzzyValue);
36f4947b 255 aFaceFace.SetProgressIndicator(myProgressIndicator);
a2098360 256 }//for (; myIterator->More(); myIterator->Next()) {
257 //
258 aNbFaceFace=aVFaceFace.Extent();
259 //======================================================
260 BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
261 //======================================================
262 //
263 for (k=0; k < aNbFaceFace; ++k) {
264 BOPAlgo_FaceFace& aFaceFace=aVFaceFace(k);
265 //
266 aFaceFace.Indices(nF1, nF2);
267 aTolFF=aFaceFace.TolFF();
4e57c75e 268 //
269 bIsDone=aFaceFace.IsDone();
270 if (bIsDone) {
271 aTolR3D=aFaceFace.TolReached3d();
272 aTolR2D=aFaceFace.TolReached2d();
3510db62 273 aTolReal = aFaceFace.TolReal();
7ff8f019 274 bTangentFaces=aFaceFace.TangentFaces();
4e57c75e 275 //
4e57c75e 276 if (aTolR3D < aTolFF){
277 aTolR3D=aTolFF;
278 }
3510db62 279 if (aTolReal < aTolFF) {
280 aTolReal = aTolFF;
281 }
4e57c75e 282 if (aTolR2D < 1.e-7){
283 aTolR2D=1.e-7;
284 }
285 //
286 aFaceFace.PrepareLines3D(bToSplit);
287 //
288 const IntTools_SequenceOfCurves& aCvsX=aFaceFace.Lines();
289 const IntTools_SequenceOfPntOn2Faces& aPntsX=aFaceFace.Points();
290 //
291 aNbCurves=aCvsX.Length();
292 aNbPoints=aPntsX.Length();
293 //
955b3e71 294 if (aNbCurves || aNbPoints) {
295 myDS->AddInterf(nF1, nF2);
296 }
4e57c75e 297 //
402bfe81 298 BOPDS_InterfFF& aFF=aFFs.Append1();
4e57c75e 299 aFF.SetIndices(nF1, nF2);
300 //
301 aFF.SetTolR3D(aTolR3D);
302 aFF.SetTolR2D(aTolR2D);
3510db62 303 aFF.SetTolReal(aTolReal);
7ff8f019 304 aFF.SetTangentFaces(bTangentFaces);
4e57c75e 305 //
306 // Curves, Points
307 aFF.Init(aNbCurves, aNbPoints);
308 //
309 // Curves
bcd19756 310
311 // Fix bounding box expanding coefficient.
312 Standard_Real aBoxExpandValue = aTolR3D;
313 if (aNbCurves > 0)
314 {
315 // Modify geometric expanding coefficient by topology value,
316 // since this bounging box used in sharing (vertex or edge).
317 Standard_Real aMaxVertexTol = Max (BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
318 BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
319 aBoxExpandValue += aMaxVertexTol;
320 }
321
4e57c75e 322 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
323 for (i=1; i<=aNbCurves; ++i) {
324 Bnd_Box aBox;
325 //
326 const IntTools_Curve& aIC=aCvsX(i);
327 const Handle(Geom_Curve)& aC3D= aIC.Curve();
bcd19756 328 bValid=IntTools_Tools::CheckCurve(aC3D, aBoxExpandValue, aBox);
4e57c75e 329 if (bValid) {
402bfe81 330 BOPDS_Curve& aNC=aVNC.Append1();
4e57c75e 331 aNC.SetCurve(aIC);
332 aNC.SetBox(aBox);
333 }
334 }
335 //
336 // Points
337 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
338 for (i=1; i<=aNbPoints; ++i) {
339 const IntTools_PntOn2Faces& aPi=aPntsX(i);
340 const gp_Pnt& aP=aPi.P1().Pnt();
341 //
402bfe81 342 BOPDS_Point& aNP=aVNP.Append1();
4e57c75e 343 aNP.SetPnt(aP);
344 }
345 //}// if (aNbCs || aNbPs)
346 }// if (bIsDone) {
347 else {// 904/L1
402bfe81 348 BOPDS_InterfFF& aFF=aFFs.Append1();
4e57c75e 349 aFF.SetIndices(nF1, nF2);
350 aNbCurves=0;
351 aNbPoints=0;
352 aFF.Init(aNbCurves, aNbPoints);
353 }
a2098360 354 }// for (k=0; k < aNbFaceFace; ++k) {
4e57c75e 355}
356//=======================================================================
357//function : MakeBlocks
358//purpose :
359//=======================================================================
78c66ef1 360void BOPAlgo_PaveFiller::MakeBlocks()
4e57c75e 361{
362 Standard_Integer aNbFF;
363 //
364 myErrorStatus=0;
365 //
366 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
367 aNbFF=aFFs.Extent();
368 if (!aNbFF) {
369 return;
370 }
371 //
372 Standard_Boolean bExist, bValid2D;
373 Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
374 Standard_Integer nV1, nV2;
0d0481c7 375 Standard_Real aTolR3D, aT1, aT2;
488e5b9d 376 Handle(NCollection_BaseAllocator) aAllocator;
4e57c75e 377 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
378 TopoDS_Edge aES;
379 Handle(BOPDS_PaveBlock) aPBOut;
380 //
381 //-----------------------------------------------------scope f
488e5b9d 382 aAllocator=
383 NCollection_BaseAllocator::CommonBaseAllocator();
4e57c75e 384 //
3285a59a 385 BOPCol_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
4e57c75e 386 BOPCol_MapOfInteger aMVOnIn(100, aAllocator), aMF(100, aAllocator),
387 aMVStick(100,aAllocator), aMVEF(100, aAllocator),
01b5b3df 388 aMI(100, aAllocator), aMVBounds(100, aAllocator);
decdfc94 389 BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
0d0481c7 390 BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon;
4e57c75e 391 BOPDS_ListOfPaveBlock aLPB(aAllocator);
392 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator);
393 BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
78c66ef1 394 BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
b4109929 395 BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
0d0481c7 396 BOPCol_DataMapOfIntegerInteger aDMNewSD(100, aAllocator);
397 BOPCol_DataMapOfIntegerListOfInteger aDMVLV;
3285a59a 398 BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
399 BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
01b5b3df 400 BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
4e57c75e 401 //
402 for (i=0; i<aNbFF; ++i) {
36f4947b 403 //
404 UserBreak();
405 //
4e57c75e 406 BOPDS_InterfFF& aFF=aFFs(i);
407 aFF.Indices(nF1, nF2);
408 //
409 BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
410 aNbP=aVP.Extent();
411 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
412 aNbC=aVC.Extent();
413 if (!aNbP && !aNbC) {
414 continue;
415 }
416 //
417 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
418 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
419 //
420 aTolR3D=aFF.TolR3D();
4e57c75e 421 //
422 // Update face info
423 if (aMF.Add(nF1)) {
424 myDS->UpdateFaceInfoOn(nF1);
3285a59a 425 myDS->UpdateFaceInfoIn(nF1);
4e57c75e 426 }
427 if (aMF.Add(nF2)) {
428 myDS->UpdateFaceInfoOn(nF2);
3285a59a 429 myDS->UpdateFaceInfoIn(nF2);
4e57c75e 430 }
3285a59a 431 //
4e57c75e 432 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
433 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
434 //
435 aMVOnIn.Clear();
436 aMPBOnIn.Clear();
0d0481c7 437 aMPBCommon.Clear();
3285a59a 438 aDMBV.Clear();
b4109929 439 aMVTol.Clear();
3f317e7d 440 aLSE.Clear();
4e57c75e 441 //
0d0481c7 442 myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
4e57c75e 443 myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
444
445 // 1. Treat Points
446 for (j=0; j<aNbP; ++j) {
447 TopoDS_Vertex aV;
448 BOPDS_CoupleOfPaveBlocks aCPB;
449 //
450 BOPDS_Point& aNP=aVP.ChangeValue(j);
451 const gp_Pnt& aP=aNP.Pnt();
452 //
453 bExist=IsExistingVertex(aP, aTolR3D, aMVOnIn);
454 if (!bExist) {
455 BOPTools_AlgoTools::MakeNewVertex(aP, aTolR3D, aV);
456 //
457 aCPB.SetIndexInterf(i);
458 aCPB.SetIndex(j);
459 aMSCPB.Add(aV, aCPB);
460 }
461 }
462 //
463 // 2. Treat Curves
464 aMVStick.Clear();
465 aMVEF.Clear();
78c66ef1 466 GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
4e57c75e 467 //
0d0481c7 468 for (j = 0; j < aNbC; ++j) {
469 BOPDS_Curve& aNC = aVC.ChangeValue(j);
4e57c75e 470 // DEBt
471 aNC.InitPaveBlock1();
472 //
0d0481c7 473 PutPavesOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV);
474 }
475
476 // if some E-F vertex was put on a curve due to large E-F intersection range,
477 // and it also was put on another curve correctly then remove this vertex from
478 // the first curve. Detect such case if the distance to curve exceeds aTolR3D.
479 FilterPavesOnCurves(aVC, aTolR3D);
480
481 for (j = 0; j<aNbC; ++j) {
482 BOPDS_Curve& aNC=aVC.ChangeValue(j);
483 const IntTools_Curve& aIC=aNC.Curve();
4e57c75e 484 //
0d0481c7 485 PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV);
7ff8f019 486 //904/F7
4e57c75e 487 if (aNbC == 1) {
0d0481c7 488 PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV);
4e57c75e 489 }
490 //
491 if (aIC.HasBounds()) {
3285a59a 492 aLBV.Clear();
493 //
494 PutBoundPaveOnCurve(aF1, aF2, aTolR3D, aNC, aLBV);
495 //
496 if (!aLBV.IsEmpty()) {
497 aDMBV.Bind(j, aLBV);
01b5b3df 498 BOPCol_ListIteratorOfListOfInteger aItI(aLBV);
499 for (; aItI.More(); aItI.Next()) {
500 aMVBounds.Add(aItI.Value());
501 }
3285a59a 502 }
4e57c75e 503 }
504 }//for (j=0; j<aNbC; ++j) {
0d0481c7 505
4e57c75e 506 // Put closing pave if needed
507 for (j=0; j<aNbC; ++j) {
508 BOPDS_Curve& aNC=aVC.ChangeValue(j);
509 PutClosingPaveOnCurve (aNC);
510 }
511 //
512 // 3. Make section edges
513 for (j=0; j<aNbC; ++j) {
514 BOPDS_Curve& aNC=aVC.ChangeValue(j);
515 const IntTools_Curve& aIC=aNC.Curve();
516 //
517 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
518 Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
519 //
520 aLPB.Clear();
521 aPB1->Update(aLPB, Standard_False);
522 //
523 aItLPB.Initialize(aLPB);
524 for (; aItLPB.More(); aItLPB.Next()) {
525 Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
526 aPB->Indices(nV1, nV2);
527 aPB->Range (aT1, aT2);
528 //
529 if (fabs(aT1 - aT2) < Precision::PConfusion()) {
530 continue;
531 }
532 //
465d1fba 533 bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC,
534 aF1, aF2, aTolR3D);
4e57c75e 535 if (!bValid2D) {
536 continue;
537 }
538 //
93e38faa 539 bExist=IsExistingPaveBlock(aPB, aNC, aLSE);
4e57c75e 540 if (bExist) {
541 continue;
542 }
543 //
01b5b3df 544 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
545 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
546 //
547 // Make Edge
548 BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
549 //
550 // check for micro edge
551 if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
552 // If the section edge is a micro edge, i.e. the whole edge is
553 // covered by the tolerance spheres of its vertices, it will be
554 // passed into post treatment process to fuse its vertices.
555 // The edge itself will not be kept.
556 if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
557 aMicroEdges.Add(aES);
558 // keep vertices for post treatment
559 aMVI.Bind(aV1, nV1);
560 aMVI.Bind(aV2, nV2);
561 }
562 continue;
563 }
564 //
05cf4d98 565 Standard_Real aTolNew;
0d0481c7 566 bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
4e57c75e 567 if (bExist) {
568 if (aMPBAdd.Add(aPBOut)) {
569 Standard_Boolean bInBothFaces = Standard_True;
5a77460e 570 if (!myDS->IsCommonBlock(aPBOut)) {
4e57c75e 571 Standard_Integer nE;
572 Standard_Real aTolE;
573 //
574 nE = aPBOut->Edge();
575 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
576 aTolE = BRep_Tool::Tolerance(aE);
05cf4d98 577 if (aTolNew < aFF.TolReal())
578 aTolNew = aFF.TolReal(); // use real tolerance of intersection
579 if (aTolNew > aTolE) {
580 UpdateEdgeTolerance(nE, aTolNew);
4e57c75e 581 }
582 bInBothFaces = Standard_False;
3510db62 583 }
584 else {
4e57c75e 585 bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
586 aFI1.PaveBlocksIn().Contains(aPBOut))&&
587 (aFI2.PaveBlocksOn().Contains(aPBOut) ||
588 aFI2.PaveBlocksIn().Contains(aPBOut));
589 }
590 if (!bInBothFaces) {
3285a59a 591 PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
4e57c75e 592 }
593 }
594 continue;
595 }
596 //
01b5b3df 597 // Make p-curves
4e57c75e 598 BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC,
599 mySectionAttribute.PCurveOnS1(),
600 mySectionAttribute.PCurveOnS2());
601 //
4e57c75e 602 // Append the Pave Block to the Curve j
603 aLPBC.Append(aPB);
604 //
605 // Keep info for post treatment
606 BOPDS_CoupleOfPaveBlocks aCPB;
607 aCPB.SetIndexInterf(i);
608 aCPB.SetIndex(j);
609 aCPB.SetPaveBlock1(aPB);
610 //
611 aMSCPB.Add(aES, aCPB);
612 aMVI.Bind(aV1, nV1);
613 aMVI.Bind(aV2, nV2);
b4109929 614 //
615 aMVTol.UnBind(nV1);
616 aMVTol.UnBind(nV2);
4e57c75e 617 }
618 //
619 aLPBC.RemoveFirst();
620 }//for (j=0; j<aNbC; ++j) {
0d0481c7 621 //
b4109929 622 //back to previous tolerance values for unused vertices
0d0481c7 623 //and forget about SD groups of such vertices
b4109929 624 aItMV.Initialize(aMVTol);
625 for (; aItMV.More(); aItMV.Next()) {
626 nV1 = aItMV.Key();
0d0481c7 627 Standard_Real aTol = aItMV.Value();
b4109929 628 //
629 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
465d1fba 630 const Handle(BRep_TVertex)& TV =
631 *((Handle(BRep_TVertex)*)&aV.TShape());
b4109929 632 TV->Tolerance(aTol);
0d0481c7 633 // reset bnd box
634 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
635 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
636 aBoxDS = Bnd_Box();
637 BRepBndLib::Add(aV, aBoxDS);
638 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
639 //
640 if (aDMVLV.IsBound(nV1))
641 aDMVLV.UnBind(nV1);
b4109929 642 }
643 //
3285a59a 644 ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
4e57c75e 645 }//for (i=0; i<aNbFF; ++i) {
646 //
647 // post treatment
0d0481c7 648 MakeSDVerticesFF(aDMVLV, aDMNewSD);
649 myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
4e57c75e 650 if (myErrorStatus) {
651 return;
652 }
3510db62 653 // reduce tolerances of section edges where it is appropriate
654 CorrectToleranceOfSE();
4e57c75e 655 //
656 // update face info
0d0481c7 657 UpdateFaceInfo(aDMExEdges, aDMNewSD);
78c66ef1 658 //Update all pave blocks
0d0481c7 659 UpdatePaveBlocks(aDMNewSD);
4e57c75e 660 //-----------------------------------------------------scope t
661 aMF.Clear();
662 aMVStick.Clear();
663 aMPBOnIn.Clear();
664 aMVOnIn.Clear();
665 aDMExEdges.Clear();
78c66ef1 666 aMI.Clear();
0d0481c7 667 aDMNewSD.Clear();
668}
669
670//=======================================================================
671//function : MakeSDVerticesFF
672//purpose :
673//=======================================================================
674void BOPAlgo_PaveFiller::MakeSDVerticesFF
675 (const BOPCol_DataMapOfIntegerListOfInteger& theDMVLV,
676 BOPCol_DataMapOfIntegerInteger& theDMNewSD)
677{
678 // Create a new SD vertex for each group of coinciding vertices
679 // and put new substitutions to theDMNewSD.
680 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV);
681 for (; aItG.More(); aItG.Next()) {
682 const BOPCol_ListOfInteger& aList = aItG.Value();
683 // make SD vertices w/o creation of interfs
684 Standard_Integer nSD = MakeSDVertices(aList, Standard_False);
685 // update theDMNewSD
686 BOPCol_ListIteratorOfListOfInteger aItL(aList);
687 for (; aItL.More(); aItL.Next()) {
688 Standard_Integer nV = aItL.Value();
689 theDMNewSD.Bind(nV, nSD);
690 }
691 }
4e57c75e 692}
693
694//=======================================================================
695//function : PostTreatFF
696//purpose :
697//=======================================================================
a942f2da 698Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
4e57c75e 699 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
700 BOPCol_DataMapOfShapeInteger& aMVI,
701 BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
0d0481c7 702 BOPCol_DataMapOfIntegerInteger& aDMNewSD,
01b5b3df 703 const BOPCol_IndexedMapOfShape& theMicroEdges,
7f22979e 704 const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 705{
706 Standard_Integer iRet, aNbS;
707 //
708 iRet=0;
709 aNbS=theMSCPB.Extent();
710 if (!aNbS) {
711 return iRet;
712 }
713 //
714 Standard_Boolean bHasPaveBlocks, bOld;
1d47d8d0 715 Standard_Integer iErr, nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
3510db62 716 Standard_Integer aNbLPBx;
4e57c75e 717 TopAbs_ShapeEnum aType;
718 TopoDS_Shape aV, aE;
719 BOPCol_ListIteratorOfListOfShape aItLS;
720 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
721 BOPDS_PDS aPDS;
722 Handle(BOPDS_PaveBlock) aPB1;
3510db62 723 BOPDS_Pave aPave[2];
4e57c75e 724 BOPDS_ShapeInfo aSI;
725 //
726 BOPCol_ListOfShape aLS(theAllocator);
727 BOPAlgo_PaveFiller aPF(theAllocator);
3510db62 728 aPF.SetIsPrimary(Standard_False);
729 aPF.SetNonDestructive(myNonDestructive);
4e57c75e 730 //
731 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
732 //
01b5b3df 733 Standard_Integer aNbME = theMicroEdges.Extent();
4e57c75e 734 // 0
01b5b3df 735 if (aNbS==1 && (aNbME == 0)) {
4e57c75e 736 const TopoDS_Shape& aS=theMSCPB.FindKey(1);
737 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
4e57c75e 738 //
739 aType=aS.ShapeType();
740 if (aType==TopAbs_VERTEX) {
741 aSI.SetShapeType(aType);
742 aSI.SetShape(aS);
743 iV=myDS->Append(aSI);
744 //
745 iX=aCPB.IndexInterf();
746 iP=aCPB.Index();
747 BOPDS_InterfFF& aFF=aFFs(iX);
748 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
749 BOPDS_Point& aNP=aVNP(iP);
750 aNP.SetIndex(iV);
751 }
752 else if (aType==TopAbs_EDGE) {
753 aPB1=aCPB.PaveBlock1();
754 //
755 if (aPB1->HasEdge()) {
756 BOPDS_ListOfPaveBlock aLPBx;
757 aLPBx.Append(aPB1);
758 aDMExEdges.Bind(aPB1, aLPBx);
759 } else {
760 aSI.SetShapeType(aType);
761 aSI.SetShape(aS);
762 iE=myDS->Append(aSI);
763 //
764 aPB1->SetEdge(iE);
765 }
766 }
767 return iRet;
768 }
769 //
770 // 1 prepare arguments
771 for (k=1; k<=aNbS; ++k) {
772 const TopoDS_Shape& aS=theMSCPB.FindKey(k);
773 aLS.Append(aS);
774 }
775 //
01b5b3df 776 // The section edges considered as a micro should be
777 // specially treated - their vertices should be united and
778 // the edge itself should be removed. Thus, we add only
779 // its vertices into operation.
780 //
781 BRep_Builder aBB;
782 for (k = 1; k <= aNbME; ++k) {
79cbd2cf 783 const TopoDS_Edge& aEM = TopoDS::Edge(theMicroEdges(k));
01b5b3df 784 //
785 TopoDS_Vertex aV1, aV2;
79cbd2cf 786 TopExp::Vertices(aEM, aV1, aV2);
01b5b3df 787 //
788 aLS.Append(aV1);
789 aLS.Append(aV2);
790 //
791 // make sure these vertices will be united
792 const gp_Pnt& aP1 = BRep_Tool::Pnt(aV1);
793 const gp_Pnt& aP2 = BRep_Tool::Pnt(aV2);
794 //
795 Standard_Real aDist = aP1.Distance(aP2);
796 Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1);
797 Standard_Real aTolV2 = BRep_Tool::Tolerance(aV2);
798 //
799 aDist -= (aTolV1 + aTolV2);
800 if (aDist > 0.) {
801 aDist /= 2.;
802 aBB.UpdateVertex(aV1, aTolV1 + aDist);
803 aBB.UpdateVertex(aV2, aTolV2 + aDist);
804 }
805 }
806 //
4e57c75e 807 // 2 Fuse shapes
36f4947b 808 aPF.SetProgressIndicator(myProgressIndicator);
a942f2da 809 aPF.SetRunParallel(myRunParallel);
4e57c75e 810 aPF.SetArguments(aLS);
811 aPF.Perform();
812 iErr=aPF.ErrorStatus();
813 if (iErr) {
4e57c75e 814 return iRet;
815 }
816 aPDS=aPF.PDS();
817 //
818 aItLS.Initialize(aLS);
819 for (; aItLS.More(); aItLS.Next()) {
820 const TopoDS_Shape& aSx=aItLS.Value();
821 nSx=aPDS->Index(aSx);
822 const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
823 //
824 aType=aSIx.ShapeType();
825 //
826 if (aType==TopAbs_VERTEX) {
01b5b3df 827 Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
828 //
4e57c75e 829 if (aPDS->HasShapeSD(nSx, nVSD)) {
830 aV=aPDS->Shape(nVSD);
831 }
832 else {
833 aV=aSx;
834 }
835 // index of new vertex in theDS -> iV
836 if (!aMVI.IsBound(aV)) {
837 aSI.SetShapeType(aType);
838 aSI.SetShape(aV);
839 iV=myDS->Append(aSI);
840 //
841 aMVI.Bind(aV, iV);
842 }
843 else {
844 iV=aMVI.Find(aV);
845 }
01b5b3df 846 //
847 if (!bIntersectionPoint) {
848 // save SD connection
849 nSx = aMVI.Find(aSx);
0d0481c7 850 aDMNewSD.Bind(nSx, iV);
01b5b3df 851 myDS->AddShapeSD(nSx, iV);
852 }
853 else {
4e57c75e 854 // update FF interference
0d0481c7 855 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
856 iX=aCPB.IndexInterf();
857 iP=aCPB.Index();
858 BOPDS_InterfFF& aFF=aFFs(iX);
859 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
860 BOPDS_Point& aNP=aVNP(iP);
861 aNP.SetIndex(iV);
01b5b3df 862 }
4e57c75e 863 }//if (aType==TopAbs_VERTEX) {
864 //
865 else if (aType==TopAbs_EDGE) {
866 bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
867 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
868 iX=aCPB.IndexInterf();
869 iC=aCPB.Index();
870 aPB1=aCPB.PaveBlock1();
871 //
872 bOld = aPB1->HasEdge();
873 if (bOld) {
874 BOPDS_ListOfPaveBlock aLPBx;
875 aDMExEdges.Bind(aPB1, aLPBx);
876 }
877 //
878 if (!bHasPaveBlocks) {
879 if (bOld) {
880 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
1b7ae951 881 }
882 else {
4e57c75e 883 aSI.SetShapeType(aType);
884 aSI.SetShape(aSx);
3510db62 885 iE = myDS->Append(aSI);
4e57c75e 886 //
887 aPB1->SetEdge(iE);
888 }
889 }
890 else {
891 BOPDS_InterfFF& aFF=aFFs(iX);
892 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
893 BOPDS_Curve& aNC=aVNC(iC);
894 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
895 //
3510db62 896 // check if edge occured to be micro edge;
897 // note we check not the edge aSx itself, but its image in aPDS
898 const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
899 aNbLPBx = aLPBx.Extent();
900 if (aPDS->HasPaveBlocks(nSx) &&
901 (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) {
902 BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
903 for (; it.More(); it.Next()) {
904 if (it.Value() == aPB1) {
905 aLPBC.Remove(it);
906 break;
907 }
908 }
909 continue;
910 }
4e57c75e 911 //
912 if (bOld && !aNbLPBx) {
913 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
914 continue;
915 }
916 //
917 if (!bOld) {
918 aItLPB.Initialize(aLPBC);
919 for (; aItLPB.More(); aItLPB.Next()) {
920 const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
921 if (aPBC==aPB1) {
922 aLPBC.Remove(aItLPB);
923 break;
924 }
925 }
926 }
927 //
928 if (!aNbLPBx) {
929 aE=aSx;
930 //
931 if (!aMVI.IsBound(aE)) {
932 aSI.SetShapeType(aType);
933 aSI.SetShape(aE);
934 iE=myDS->Append(aSI);
935 aMVI.Bind(aE, iE);
936 }
937 else {
938 iE=aMVI.Find(aE);
939 }
940 // append new PaveBlock to aLPBC
4e57c75e 941 aPB1->SetEdge(iE);
942 aLPBC.Append(aPB1);
943 } // if (!aNbLPBx) {
944 //
945 else {
946 aItLPB.Initialize(aLPBx);
4e57c75e 947 for (; aItLPB.More(); aItLPB.Next()) {
948 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
5a77460e 949 const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
4e57c75e 950 //
951 // update vertices of paves
952 aPave[0]=aPBx->Pave1();
953 aPave[1]=aPBx->Pave2();
954 for (j=0; j<2; ++j) {
3510db62 955 nV = aPave[j].Index();
956 aV = aPDS->Shape(nV);
957 //
958 if (!aMVI.IsBound(aV)) {
959 // index of new vertex in theDS -> iV
960 aSI.SetShapeType(TopAbs_VERTEX);
961 aSI.SetShape(aV);
962 iV = myDS->Append(aSI);
963 aMVI.Bind(aV, iV);
964 }
965 else {
966 iV = aMVI.Find(aV);
4e57c75e 967 }
78c66ef1 968 const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
465d1fba 969 if (aP1.Parameter() == aPave[j].Parameter() &&
970 aP1.Index() != iV) {
0d0481c7 971 aDMNewSD.Bind(aP1.Index(), iV);
6a43d224 972 myDS->AddShapeSD(aP1.Index(), iV);
78c66ef1 973 }
974 //
4e57c75e 975 aPave[j].SetIndex(iV);
976 }
977 //
978 // add edge
979 aE=aPDS->Shape(aPBRx->Edge());
980 //
981 if (!aMVI.IsBound(aE)) {
982 aSI.SetShapeType(aType);
983 aSI.SetShape(aE);
984 iE=myDS->Append(aSI);
985 aMVI.Bind(aE, iE);
3510db62 986 // update real edge tolerance according to distances in common block if any
987 if (aPDS->IsCommonBlock(aPBx)) {
988 const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBx);
989 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
990 if (aFF.TolReal() < aTol) {
991 aFF.SetTolReal(aTol);
992 }
993 }
4e57c75e 994 }
995 else {
996 iE=aMVI.Find(aE);
997 }
998 // append new PaveBlock to aLPBC
999 Handle(BOPDS_PaveBlock) aPBC=new BOPDS_PaveBlock();
1000 //
1001 aPBC->SetPave1(aPave[0]);
1002 aPBC->SetPave2(aPave[1]);
1003 aPBC->SetEdge(iE);
1004 if (bOld) {
1005 aPBC->SetOriginalEdge(aPB1->OriginalEdge());
1006 aDMExEdges.ChangeFind(aPB1).Append(aPBC);
1007 }
1008 else {
1009 aLPBC.Append(aPBC);
1010 }
1011 }
1012 }
1013 }
1014 }//else if (aType==TopAbs_EDGE)
1015 }//for (; aItLS.More(); aItLS.Next()) {
1016 return iRet;
1017}
1018
1019//=======================================================================
1020//function : UpdateFaceInfo
1021//purpose :
1022//=======================================================================
465d1fba 1023void BOPAlgo_PaveFiller::UpdateFaceInfo
1b7ae951 1024 (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
1025 const BOPCol_DataMapOfIntegerInteger& theDMV)
4e57c75e 1026{
1027 Standard_Integer i, j, nV1, nF1, nF2,
1b7ae951 1028 aNbFF, aNbC, aNbP;
4e57c75e 1029 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1b7ae951 1030 BOPCol_MapOfInteger aMF;
4e57c75e 1031 //
1032 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
1033 aNbFF=aFFs.Extent();
1034 //
1035 //1. Sections (curves, points);
1036 for (i=0; i<aNbFF; ++i) {
1037 BOPDS_InterfFF& aFF=aFFs(i);
1038 aFF.Indices(nF1, nF2);
1039 //
1040 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
1041 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
1042 //
1b7ae951 1043 // 1.1. Section edges
4e57c75e 1044 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
1045 aNbC=aVNC.Extent();
1046 for (j=0; j<aNbC; ++j) {
1047 BOPDS_Curve& aNC=aVNC(j);
1048 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
4e57c75e 1049 //
1b7ae951 1050 // Add section edges to face info
3285a59a 1051 aItLPB.Initialize(aLPBC);
1052 for (; aItLPB.More(); ) {
4e57c75e 1053 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
3285a59a 1054 //
1055 // Treat existing pave blocks
1056 if (theDME.IsBound(aPB)) {
1057 BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
1058 UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2);
1059 aLPBC.Remove(aItLPB);
1060 continue;
1061 }
1062 //
4e57c75e 1063 aFI1.ChangePaveBlocksSc().Add(aPB);
1064 aFI2.ChangePaveBlocksSc().Add(aPB);
3285a59a 1065 aItLPB.Next();
4e57c75e 1066 }
1067 }
1b7ae951 1068 //
1069 // 1.2. Section vertices
4e57c75e 1070 const BOPDS_VectorOfPoint& aVNP=aFF.Points();
1071 aNbP=aVNP.Extent();
1072 for (j=0; j<aNbP; ++j) {
1073 const BOPDS_Point& aNP=aVNP(j);
1074 nV1=aNP.Index();
85915310 1075 if (nV1<0) {
1076 continue;
1077 }
4e57c75e 1078 aFI1.ChangeVerticesSc().Add(nV1);
1079 aFI2.ChangeVerticesSc().Add(nV1);
1080 }
1b7ae951 1081 //
1082 aMF.Add(nF1);
1083 aMF.Add(nF2);
4e57c75e 1084 }
1085 //
1b7ae951 1086 Standard_Boolean bVerts, bEdges;
1087 //
1088 bVerts = theDMV.Extent() > 0;
1089 bEdges = theDME.Extent() > 0;
1090 //
1091 if (!bVerts && !bEdges) {
4e57c75e 1092 return;
1093 }
1094 //
1b7ae951 1095 // 2. Update Face Info information with new vertices and new
1096 // pave blocks created in PostTreatFF from existing ones
1097 Standard_Integer nV2, aNbPB;
1098 BOPCol_MapIteratorOfMapOfInteger aItMF;
1099 BOPCol_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
1100 //
1101 aItMF.Initialize(aMF);
1102 for (; aItMF.More(); aItMF.Next()) {
1103 nF1 = aItMF.Value();
4e57c75e 1104 //
1b7ae951 1105 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
4e57c75e 1106 //
1b7ae951 1107 // 2.1. Update information about vertices
1108 if (bVerts) {
1109 BOPCol_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
1110 BOPCol_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
1111 //
1112 aItMV.Initialize(theDMV);
1113 for (; aItMV.More(); aItMV.Next()) {
1114 nV1 = aItMV.Key();
1115 nV2 = aItMV.Value();
1116 //
1117 if (aMVOn.Remove(nV1)) {
1118 aMVOn.Add(nV2);
4e57c75e 1119 }
1b7ae951 1120 //
1121 if (aMVIn.Remove(nV1)) {
1122 aMVIn.Add(nV2);
1123 }
1124 } // for (; aItMV.More(); aItMV.Next()) {
1125 } // if (bVerts) {
1126 //
1127 // 2.2. Update information about pave blocks
1128 if (bEdges) {
1129 BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn();
1130 BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1131 //
1132 BOPDS_IndexedMapOfPaveBlock aMPBCopy;
1133 for (i = 0; i < 2; ++i) {
1134 BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn;
1135 aMPBCopy = aMPBOnIn;
1136 aMPBOnIn.Clear();
1137 //
1138 aNbPB = aMPBCopy.Extent();
1139 for (j = 1; j <= aNbPB; ++j) {
1140 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1141 if (theDME.IsBound(aPB)) {
1142 const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB);
3285a59a 1143 if (aLPB.IsEmpty()) {
1144 aMPBOnIn.Add(aPB);
1145 continue;
1146 }
1147 //
1b7ae951 1148 aItLPB.Initialize(aLPB);
1149 for (; aItLPB.More(); aItLPB.Next()) {
1150 const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1151 aMPBOnIn.Add(aPB1);
1152 }
1153 }
1154 else {
1155 aMPBOnIn.Add(aPB);
1156 }
1157 } // for (j = 1; j <= aNbPB; ++j) {
1158 } // for (i = 0; i < 2; ++i) {
1159 } // if (bEdges) {
1160 }
4e57c75e 1161}
4e57c75e 1162//=======================================================================
1163//function : IsExistingVertex
1164//purpose :
1165//=======================================================================
3510db62 1166Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1167 (const gp_Pnt& aP,
1168 const Standard_Real theTolR3D,
1169 const BOPCol_MapOfInteger& aMVOnIn)const
4e57c75e 1170{
1171 Standard_Boolean bRet;
1172 Standard_Integer nV, iFlag;
0d0481c7 1173 Standard_Real aTolCheck;
4e57c75e 1174 gp_Pnt aPV;
1175 Bnd_Box aBoxP;
1176 BOPCol_MapIteratorOfMapOfInteger aIt;
1177 //
0d0481c7 1178 aTolCheck = theTolR3D + myFuzzyValue;
4e57c75e 1179 bRet=Standard_True;
1180 //
1181 aBoxP.Add(aP);
1182 aBoxP.Enlarge(theTolR3D);
1183 //
1184 aIt.Initialize(aMVOnIn);
1185 for (; aIt.More(); aIt.Next()) {
4e57c75e 1186 nV=aIt.Value();
3510db62 1187 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1188 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1189 const Bnd_Box& aBoxV=aSIV.Box();
4e57c75e 1190 //
1191 if (!aBoxP.IsOut(aBoxV)) {
0d0481c7 1192 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck);
4e57c75e 1193 if (!iFlag) {
1194 return bRet;
1195 }
1196 }
1197 }
1198 return !bRet;
1199}
1200//=======================================================================
1201//function : IsExistingPaveBlock
1202//purpose :
1203//=======================================================================
3510db62 1204Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1205 (const Handle(BOPDS_PaveBlock)& thePB,
1206 const BOPDS_Curve& theNC,
3510db62 1207 const BOPCol_ListOfInteger& theLSE)
4e57c75e 1208{
1209 Standard_Boolean bRet=Standard_True;
1210 //
1211 if (theLSE.IsEmpty()) {
1212 return !bRet;
1213 }
1214 //
0d0481c7 1215 Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist;
93e38faa 1216 Standard_Integer nE, iFlag, nV1, nV2;
4e57c75e 1217 gp_Pnt aPm;
1218 Bnd_Box aBoxPm;
1219 BOPCol_ListIteratorOfListOfInteger aItLI;
1220 //
1221 thePB->Range(aT1, aT2);
93e38faa 1222 thePB->Indices(nV1, nV2);
1223 const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)),
1224 &aV2 = TopoDS::Vertex(myDS->Shape(nV2));
1225 const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1),
1226 aTolV2 = BRep_Tool::Tolerance(aV2);
1227
1228 aTol = Max(aTolV1, aTolV2);
1229
4e57c75e 1230 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1231 theNC.Curve().D0(aTm, aPm);
1232 aBoxPm.Add(aPm);
93e38faa 1233 aBoxPm.Enlarge(aTol);
4e57c75e 1234 //
1235 aItLI.Initialize(theLSE);
1236 for (; aItLI.More(); aItLI.Next()) {
1237 nE=aItLI.Value();
3510db62 1238 if (nE < 0)
1239 continue;
4e57c75e 1240 const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1241 const Bnd_Box& aBoxE=aSIE.Box();
1242 if (!aBoxE.IsOut(aBoxPm)) {
1243 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
0d0481c7 1244 aTolE = BRep_Tool::Tolerance(aE);
1245 aTolCheck = Max(aTolE, aTol) + myFuzzyValue;
1246 iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist);
4e57c75e 1247 if (!iFlag) {
1248 return bRet;
1249 }
1250 }
1251 }
1252 return !bRet;
1253}
1254
1255//=======================================================================
1256//function : IsExistingPaveBlock
1257//purpose :
1258//=======================================================================
0d0481c7 1259Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
4e57c75e 1260 (const Handle(BOPDS_PaveBlock)& thePB,
1261 const BOPDS_Curve& theNC,
1262 const Standard_Real theTolR3D,
decdfc94 1263 const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
0d0481c7 1264 const BOPDS_MapOfPaveBlock& theMPBCommon,
05cf4d98 1265 Handle(BOPDS_PaveBlock)& aPBOut,
1266 Standard_Real& theTolNew)
4e57c75e 1267{
1268 Standard_Boolean bRet;
0d0481c7 1269 Standard_Real aT1, aT2, aTm, aTx, aTolCheck;
decdfc94 1270 Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
4e57c75e 1271 gp_Pnt aP1, aPm, aP2;
93e38faa 1272 Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp;
4e57c75e 1273 //
78c66ef1 1274 bRet=Standard_False;
0d0481c7 1275 aTolCheck = theTolR3D + myFuzzyValue;
4e57c75e 1276 const IntTools_Curve& aIC=theNC.Curve();
1277 //
1278 thePB->Range(aT1, aT2);
1279 thePB->Indices(nV11, nV12);
93e38faa 1280 const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11)));
1281 const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12)));
0d0481c7 1282 const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue;
93e38faa 1283
4e57c75e 1284 //first point
1285 aIC.D0(aT1, aP1);
1286 aBoxP1.Add(aP1);
93e38faa 1287 aBoxP1.Enlarge(aTolV11);
4e57c75e 1288 //intermediate point
1289 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1290 aIC.D0(aTm, aPm);
1291 aBoxPm.Add(aPm);
4e57c75e 1292 //last point
1293 aIC.D0(aT2, aP2);
1294 aBoxP2.Add(aP2);
93e38faa 1295 aBoxP2.Enlarge(aTolV12);
4e57c75e 1296 //
05cf4d98 1297 theTolNew = 0.;
decdfc94 1298 aNbPB = theMPBOnIn.Extent();
1299 for (i = 1; i <= aNbPB; ++i) {
1300 const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i);
4e57c75e 1301 aPB->Indices(nV21, nV22);
93e38faa 1302 const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21)));
1303 const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22)));
0d0481c7 1304 const Standard_Real aTolV2 = Max(aTolV21, aTolV22) + myFuzzyValue;
4e57c75e 1305 nSp=aPB->Edge();
3510db62 1306 if (nSp < 0)
1307 continue;
4e57c75e 1308 const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
78c66ef1 1309 const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
4e57c75e 1310 const Bnd_Box& aBoxSp=aSISp.Box();
78c66ef1 1311 //
465d1fba 1312 iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 :
1313 (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
1314 iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 :
1315 (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
78c66ef1 1316 if (iFlag1 && iFlag2) {
f4dee9bb 1317 Standard_Real aDist = 0.;
93e38faa 1318
0d0481c7 1319 Standard_Real aRealTol = aTolCheck;
1320 if (myDS->IsCommonBlock(aPB))
1321 {
1322 aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
1323 if (theMPBCommon.Contains(aPB))
1324 // for an edge, which is a common block with a face,
1325 // increase the chance to coincide with section curve
1326 aRealTol *= 2.;
1327 }
1328
93e38faa 1329 aBoxTmp = aBoxPm;
1330 aBoxTmp.Enlarge(aRealTol);
1331
1332 if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm,
1333 aRealTol,
1334 aSp,
1335 aTx, theTolNew)) {
78c66ef1 1336 continue;
1337 }
1338 //
1339 if (iFlag1 == 1) {
93e38faa 1340 iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist);
f4dee9bb 1341 if (iFlag1 && theTolNew < aDist)
05cf4d98 1342 theTolNew = aDist;
78c66ef1 1343 }
1344 //
1345 if (iFlag2 == 1) {
93e38faa 1346 iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist);
f4dee9bb 1347 if (iFlag2 && theTolNew < aDist)
05cf4d98 1348 theTolNew = aDist;
78c66ef1 1349 }
1350 //
1351 if (iFlag1 && iFlag2) {
1352 aPBOut = aPB;
1353 bRet=Standard_True;
1354 break;
4e57c75e 1355 }
1356 }
1357 }
78c66ef1 1358 return bRet;
4e57c75e 1359}
4e57c75e 1360//=======================================================================
1361//function : PutBoundPaveOnCurve
1362//purpose :
1363//=======================================================================
0d0481c7 1364void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
1365 const TopoDS_Face& aF2,
1366 const Standard_Real aTolR3D,
1367 BOPDS_Curve& aNC,
1368 BOPCol_ListOfInteger& aLVB)
4e57c75e 1369{
1370 Standard_Boolean bVF;
1371 Standard_Integer nV, iFlag, nVn, j, aNbEP;
1372 Standard_Real aT[2], aTmin, aTmax, aTV, aTol, aTolVnew;
1373 gp_Pnt aP[2];
1374 TopoDS_Vertex aVn;
1375 BOPDS_ListIteratorOfListOfPave aItLP;
1376 BOPDS_Pave aPn, aPMM[2];
1377 //
1378 aTolVnew = Precision::Confusion();
1379 //
1380 const IntTools_Curve& aIC=aNC.Curve();
1381 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1382 //
1383 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1384 const BOPDS_ListOfPave& aLP=aPB->ExtPaves();
1385 //
1386 aNbEP=aLP.Extent();
1387 if (aNbEP) {
1388 aTmin=1.e10;
1389 aTmax=-aTmin;
1390 //
1391 aItLP.Initialize(aLP);
1392 for (; aItLP.More(); aItLP.Next()) {
1393 const BOPDS_Pave& aPv=aItLP.Value();
1394 aPv.Contents(nV, aTV);
1395 if (aTV<aTmin) {
1396 aPMM[0]=aPv;
1397 aTmin=aTV;
1398 }
1399 if (aTV>aTmax) {
1400 aPMM[1]=aPv;
1401 aTmax=aTV;
1402 }
1403 }
1404 }
1405 //
1406 for (j=0; j<2; ++j) {
1407 //if curve is closed, process only one bound
1408 if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
1409 continue;
1410 }
1411 //
1412 iFlag=1;
1413 //
1414 if (aNbEP) {
1415 Bnd_Box aBoxP;
1416 //
1417 aBoxP.Set(aP[j]);
1418 aTol = aTolR3D+Precision::Confusion();
1419 aBoxP.Enlarge(aTol);
1420 const BOPDS_Pave& aPV=aPMM[j];
1421 nV=aPV.Index();
1422 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1423 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1424 const Bnd_Box& aBoxV=aSIV.Box();
1425 if (!aBoxP.IsOut(aBoxV)){
1426 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1427 }
1428 }
1429 if (iFlag) {
1430 // 900/L5
1431 bVF=myContext->IsValidPointForFaces (aP[j], aF1, aF2, aTolR3D);
1432 if (!bVF) {
1433 continue;
1434 }
1435 //
1436 BOPDS_ShapeInfo aSIVn;
1437 //
1438 BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
1439 aSIVn.SetShapeType(TopAbs_VERTEX);
1440 aSIVn.SetShape(aVn);
1441 //
1442 nVn=myDS->Append(aSIVn);
1443 //
1444 aPn.SetIndex(nVn);
1445 aPn.SetParameter(aT[j]);
1446 aPB->AppendExtPave(aPn);
1447 //
1448 aVn=(*(TopoDS_Vertex *)(&myDS->Shape(nVn)));
1449 BOPTools_AlgoTools::UpdateVertex (aIC, aT[j], aVn);
1450 //
1451 aTolVnew = BRep_Tool::Tolerance(aVn);
1452 //
1453 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVn);
1454 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1455 BRepBndLib::Add(aVn, aBoxDS);
3510db62 1456 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
3285a59a 1457 //
1458 aLVB.Append(nVn);
4e57c75e 1459 }
1460 }
1461}
1462
1463//=======================================================================
78c66ef1 1464//function : PutPavesOnCurve
4e57c75e 1465//purpose :
1466//=======================================================================
0d0481c7 1467void BOPAlgo_PaveFiller::PutPavesOnCurve
465d1fba 1468 (const BOPCol_MapOfInteger& aMVOnIn,
1469 const Standard_Real aTolR3D,
1470 BOPDS_Curve& aNC,
1471 const Standard_Integer nF1,
1472 const Standard_Integer nF2,
1473 const BOPCol_MapOfInteger& aMI,
1474 const BOPCol_MapOfInteger& aMVEF,
0d0481c7 1475 BOPCol_DataMapOfIntegerReal& aMVTol,
1476 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
4e57c75e 1477{
78c66ef1 1478 Standard_Boolean bInBothFaces;
4e57c75e 1479 Standard_Integer nV;
4e57c75e 1480 BOPCol_MapIteratorOfMapOfInteger aIt;
1481 //
4e57c75e 1482 const Bnd_Box& aBoxC=aNC.Box();
1483 //
78c66ef1 1484 //Put EF vertices first
1485 aIt.Initialize(aMVEF);
1486 for (; aIt.More(); aIt.Next()) {
1487 nV=aIt.Value();
0d0481c7 1488 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2);
78c66ef1 1489 }
1490 //Put all other vertices
4e57c75e 1491 aIt.Initialize(aMVOnIn);
1492 for (; aIt.More(); aIt.Next()) {
1493 nV=aIt.Value();
78c66ef1 1494 if (aMVEF.Contains(nV)) {
1495 continue;
4e57c75e 1496 }
1497 //
78c66ef1 1498 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1499 const Bnd_Box& aBoxV=aSIV.Box();
4e57c75e 1500 //
78c66ef1 1501 if (aBoxC.IsOut(aBoxV)){
1502 continue;
1503 }
1504 if (!myDS->IsNewShape(nV)) {
1505 const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
1506 const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
b4109929 1507 //
78c66ef1 1508 bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
1509 aFI1.VerticesIn().Contains(nV))&&
1510 (aFI2.VerticesOn().Contains(nV) ||
1511 aFI2.VerticesIn().Contains(nV));
1512 if (!bInBothFaces) {
1513 continue;
b4109929 1514 }
4e57c75e 1515 }
78c66ef1 1516 //
0d0481c7 1517 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1);
1518 }
1519}
1520
1521//=======================================================================
1522//function : FilterPavesOnCurves
1523//purpose :
1524//=======================================================================
1525namespace {
1526 struct PaveBlockDist {
1527 Handle(BOPDS_PaveBlock) PB;
1528 Standard_Real Dist; // square distance from vertex to the paveblock
1529 Standard_Real SinAngle; // sinus of angle between projection vector
1530 // and tangent at projection point
1531 };
1532}
1533void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC,
1534 const Standard_Real theTolR3D)
1535{
1536 Standard_Real aSqTol = theTolR3D * theTolR3D;
1537
1538 // For each vertex found in ExtPaves of pave blocks of section curves
1539 // collect list of pave blocks with distance to the curve
1540 NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs;
1541 Standard_Integer i;
1542 const Standard_Real anEps = gp::Resolution();
1543 for (i = 0; i < theVNC.Extent(); ++i)
1544 {
1545 const BOPDS_Curve& aNC = theVNC(i);
1546 const IntTools_Curve& aIC = aNC.Curve();
1547 GeomAdaptor_Curve aGAC(aIC.Curve());
1548 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
1549 const BOPDS_ListOfPave& aPaves = aPB->ExtPaves();
1550 BOPDS_ListOfPave::Iterator itPaves(aPaves);
1551 for (; itPaves.More(); itPaves.Next())
1552 {
1553 const BOPDS_Pave& aPave = itPaves.Value();
1554 Standard_Integer nV = aPave.Index();
1555 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
1556 // compute distance from vertex to the point on curve with vertex parameter
1557 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1558 Standard_Real aPar = aPave.Parameter();
1559 gp_Pnt aPonC;
1560 gp_Vec aD1;
1561 aGAC.D1(aPar, aPonC, aD1);
1562 gp_Vec aProjVec(aPV, aPonC);
1563 Standard_Real aSqDist = aProjVec.SquareMagnitude();
1564 Standard_Real aSqD1Mod = aD1.SquareMagnitude();
1565 Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1);
1566 if (aSqDist > anEps && aSqD1Mod > anEps)
1567 aSin = sqrt(aSin / aSqDist / aSqD1Mod);
1568 NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV);
1569 if (!pList)
1570 pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>()));
1571 PaveBlockDist aPBD = { aPB, aSqDist, aSin };
1572 pList->Append(aPBD);
1573 }
1574 }
1575
1576 // Process each vertex
1577 const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious
1578 for (i = 1; i <= aIDMVertPBs.Extent(); i++)
1579 {
1580 Standard_Integer nV = aIDMVertPBs.FindKey(i);
1581 const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i);
1582 // Find a pave with minimal distance
1583 Standard_Real aMinDist = RealLast();
1584 Handle(BOPDS_PaveBlock) aPBMinDist;
1585 NCollection_List<PaveBlockDist>::Iterator itL(aList);
1586 for (; itL.More(); itL.Next())
1587 {
1588 const PaveBlockDist& aPBD = itL.Value();
1589 if (aPBD.Dist < aMinDist)
1590 {
1591 aMinDist = aPBD.Dist;
1592 aPBMinDist = aPBD.PB;
1593 }
1594 }
1595 // Remove a vertex from a pave block if the distance is greater than the tolerance
1596 // and there are other pave blocks for which the distance is less than the current.
1597 // Do not remove a vertex if it is projected on the curve with quite large angle
1598 // (see test bugs modalg_6 bug27761).
1599 Standard_Real aCheckDist = 100. * Max(aSqTol, aMinDist);
1600 for (itL.Init(aList); itL.More(); itL.Next())
1601 {
1602 const PaveBlockDist& aPBD = itL.Value();
1603 if (aPBD.Dist > aCheckDist && aPBD.SinAngle < aSinAngleMin)
1604 {
1605 aPBD.PB->RemoveExtPave(nV);
1606 }
1607 }
4e57c75e 1608 }
1609}
1610
1611//=======================================================================
1612//function : ExtendedTolerance
1613//purpose :
1614//=======================================================================
465d1fba 1615Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
1616 (const Standard_Integer nV,
1617 const BOPCol_MapOfInteger& aMI,
1618 Standard_Real& aTolVExt,
1619 const Standard_Integer aType)
4e57c75e 1620{
1621 Standard_Boolean bFound = Standard_False;
1622 if (!(myDS->IsNewShape(nV))) {
1623 return bFound;
1624 }
78c66ef1 1625 //
1626 Standard_Integer i, k, aNbLines, aNbInt;
4e57c75e 1627 Standard_Real aT11, aT12, aD1, aD2, aD;
1628 TopoDS_Vertex aV;
1629 gp_Pnt aPV, aP11, aP12;
78c66ef1 1630 //
1631 k = 0;
1632 aNbInt = 2;
1633 if (aType == 1) {
1634 aNbInt = 1;
1635 } else if (aType == 2) {
1636 k = 1;
1637 }
1638 //
4e57c75e 1639 aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1640 aPV=BRep_Tool::Pnt(aV);
1641 //
1642 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1643 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
78c66ef1 1644 //
1645 for (; k<aNbInt; ++k) {
4e57c75e 1646 aNbLines = !k ? aEEs.Extent() : aEFs.Extent();
1647 for (i = 0; i < aNbLines; ++i) {
1648 BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
78c66ef1 1649 (BOPDS_Interf*) (&aEFs(i));
4e57c75e 1650 if (aInt->IndexNew() == nV) {
465d1fba 1651 if (aMI.Contains(aInt->Index1()) &&
1652 aMI.Contains(aInt->Index2())) {
4e57c75e 1653 const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
78c66ef1 1654 aEFs(i).CommonPart();
4e57c75e 1655 //
1656 const TopoDS_Edge& aE1=aComPrt.Edge1();
1657 aComPrt.Range1(aT11, aT12);
1658 BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
1659 BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
1660 aD1=aPV.Distance(aP11);
1661 aD2=aPV.Distance(aP12);
1662 aD=(aD1>aD2)? aD1 : aD2;
1663 if (aD>aTolVExt) {
1664 aTolVExt=aD;
1665 }
1666 return !bFound;
1667 }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
1668 }//if (aInt->IndexNew() == nV) {
1669 }//for (i = 0; i < aNbLines; ++i) {
1670 }//for (k=0; k<2; ++k) {
4e57c75e 1671 return bFound;
1672}
1673
1674//=======================================================================
1675//function : GetEFPnts
1676//purpose :
1677//=======================================================================
3510db62 1678void BOPAlgo_PaveFiller::GetEFPnts
1679 (const Standard_Integer nF1,
1680 const Standard_Integer nF2,
1681 IntSurf_ListOfPntOn2S& aListOfPnts)
4e57c75e 1682{
1683 Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
1684 Standard_Real U1, U2, V1, V2, f, l;
78c66ef1 1685 BOPCol_MapOfInteger aMI;
4e57c75e 1686 //
1687 //collect indexes of all shapes from nF1 and nF2.
78c66ef1 1688 GetFullShapeMap(nF1, aMI);
1689 GetFullShapeMap(nF2, aMI);
4e57c75e 1690 //
1691 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1692 aNbEFs = aEFs.Extent();
1693 //
1694 for(i = 0; i < aNbEFs; ++i) {
1695 const BOPDS_InterfEF& aEF = aEFs(i);
78c66ef1 1696 if (aEF.HasIndexNew()) {
1697 aEF.Indices(nE, nFOpposite);
1698 if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
1699 const IntTools_CommonPrt& aCP = aEF.CommonPart();
4e57c75e 1700 Standard_Real aPar = aCP.VertexParameter1();
1701 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
465d1fba 1702 const TopoDS_Face& aFOpposite =
1703 (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
4e57c75e 1704 //
1705 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
1706 //
1707 nF = (nFOpposite == nF1) ? nF2 : nF1;
1708 const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
465d1fba 1709 Handle(Geom2d_Curve) aPCurve =
1710 BRep_Tool::CurveOnSurface(aE, aF, f, l);
4e57c75e 1711 //
465d1fba 1712 GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
4e57c75e 1713 //
1714 gp_Pnt aPoint;
1715 aCurve->D0(aPar, aPoint);
1716 IntSurf_PntOn2S aPnt;
1717 if(!aPCurve.IsNull()) {
1718 gp_Pnt2d aP2d = aPCurve->Value(aPar);
1719 aProj.Perform(aPoint);
1720 if(aProj.IsDone()) {
1721 aProj.LowerDistanceParameters(U1,V1);
1722 if (nF == nF1) {
1723 aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
1724 } else {
1725 aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
1726 }
1727 aListOfPnts.Append(aPnt);
1728 }
1729 }
1730 else {
1731 GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
1732 aProj1.Perform(aPoint);
1733 aProj.Perform(aPoint);
1734 if(aProj1.IsDone() && aProj.IsDone()){
1735 aProj1.LowerDistanceParameters(U1,V1);
1736 aProj.LowerDistanceParameters(U2,V2);
1737 if (nF == nF1) {
1738 aPnt.SetValue(U1,V1,U2,V2);
1739 } else {
1740 aPnt.SetValue(U2,V2,U1,V1);
1741 }
1742 aListOfPnts.Append(aPnt);
1743 }
1744 }
1745 }
1746 }
1747 }
1748}
1749
1750//=======================================================================
0d0481c7 1751//function : PutEFPavesOnCurve
4e57c75e 1752//purpose :
1753//=======================================================================
465d1fba 1754 void BOPAlgo_PaveFiller::PutEFPavesOnCurve
1755 (BOPDS_Curve& aNC,
1756 const BOPCol_MapOfInteger& aMI,
1757 const BOPCol_MapOfInteger& aMVEF,
0d0481c7 1758 BOPCol_DataMapOfIntegerReal& aMVTol,
1759 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
4e57c75e 1760{
1761 if (!aMVEF.Extent()) {
1762 return;
1763 }
1764 //
1765 const IntTools_Curve& aIC=aNC.Curve();
1766 GeomAbs_CurveType aTypeC;
1767 aTypeC=aIC.Type();
1768 if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
1769 return;
1770 }
1771 //
1772 Standard_Integer nV;
1773 BOPCol_MapOfInteger aMV;
1774 //
1775 aMV.Assign(aMVEF);
1776 RemoveUsedVertices(aNC, aMV);
1777 if (!aMV.Extent()) {
1778 return;
1779 }
1780 //
1781 Standard_Real aDist;
1782 BOPDS_Pave aPave;
1783 //
1784 const Handle(Geom_Curve)& aC3D=aIC.Curve();
4e57c75e 1785 GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
78c66ef1 1786 //
4e57c75e 1787 BOPCol_MapIteratorOfMapOfInteger aItMI;
1788 aItMI.Initialize(aMV);
1789 for (; aItMI.More(); aItMI.Next()) {
1790 nV = aItMI.Value();
1791 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1792 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1793 aProjPT.Perform(aPV);
1794 Standard_Integer aNbPoints = aProjPT.NbPoints();
1795 if (aNbPoints) {
1796 aDist = aProjPT.LowerDistance();
0d0481c7 1797 PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV);
4e57c75e 1798 }
1799 }
1800}
1801
1802//=======================================================================
1803//function : ProcessUnUsedVertices
1804//purpose :
1805//=======================================================================
465d1fba 1806 void BOPAlgo_PaveFiller::PutStickPavesOnCurve
1807 (const TopoDS_Face& aF1,
1808 const TopoDS_Face& aF2,
1809 const BOPCol_MapOfInteger& aMI,
1810 BOPDS_Curve& aNC,
1811 const BOPCol_MapOfInteger& aMVStick,
0d0481c7 1812 BOPCol_DataMapOfIntegerReal& aMVTol,
1813 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
4e57c75e 1814{
1815 BOPCol_MapOfInteger aMV;
1816 aMV.Assign(aMVStick);
1817 RemoveUsedVertices(aNC, aMV);
1818 //
1819 if (!aMV.Extent()) {
1820 return;
1821 }
1822 //
4e57c75e 1823 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1824 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
ec0cdc0e 1825 //
1826 const IntTools_Curve& aIC=aNC.Curve();
ec0cdc0e 1827 //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1828 Handle(Geom2d_Curve) aC2D[2];
1829 //
1830 aC2D[0]=aIC.FirstCurve2d();
1831 aC2D[1]=aIC.SecondCurve2d();
1832 if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
1833 Standard_Integer nV, m, n;
1834 Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
1835 gp_Pnt aPC[2], aPV;
1836 gp_Dir aDN[2];
1837 gp_Pnt2d aP2D;
1838 BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1;
1839 //
1840 aDT2=2e-7; // the rich criteria
1841 aDScPr=5.e-9; // the creasing criteria
1842 aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
4e57c75e 1843 //
ec0cdc0e 1844 aItMI.Initialize(aMV);
1845 for (; aItMI.More(); aItMI.Next()) {
1846 nV = aItMI.Value();
1847 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
1848 aPV=BRep_Tool::Pnt(aV);
4e57c75e 1849 //
ec0cdc0e 1850 for (m=0; m<2; ++m) {
1851 aD2=aPC[m].SquareDistance(aPV);
1852 if (aD2>aDT2) {// no rich
1853 continue;
1854 }
78c66ef1 1855 //
ec0cdc0e 1856 for (n=0; n<2; ++n) {
1857 Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
1858 aC2D[n]->D0(aTC[m], aP2D);
1859 aP2D.Coord(u, v);
1860 BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
1861 }
1862 //
1863 aScPr=aDN[0]*aDN[1];
1864 if (aScPr<0.) {
1865 aScPr=-aScPr;
1866 }
1867 aScPr=1.-aScPr;
78c66ef1 1868 //
ec0cdc0e 1869 if (aScPr>aDScPr) {
1870 continue;
1871 }
1872 //
1873 // The intersection curve aIC is vanishing curve (the crease)
1874 aD=sqrt(aD2);
1875 //
0d0481c7 1876 PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV);
4e57c75e 1877 }
ec0cdc0e 1878 }//for (jVU=1; jVU=aNbVU; ++jVU) {
1879 }
1880 //}//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1881 //}//if(aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) {
4e57c75e 1882}
1883
1884//=======================================================================
1885//function : GetStickVertices
1886//purpose :
1887//=======================================================================
3510db62 1888void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
1889 const Standard_Integer nF2,
1890 BOPCol_MapOfInteger& aMVStick,
1891 BOPCol_MapOfInteger& aMVEF,
1892 BOPCol_MapOfInteger& aMI)
4e57c75e 1893{
78c66ef1 1894 Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
4e57c75e 1895 //
1896 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
1897 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
1898 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1899 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
1900 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1901 //
465d1fba 1902 Standard_Integer aNbLines[5] = {
1903 aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
1904 aVFs.Extent(), aEFs.Extent()
1905 };
78c66ef1 1906 //collect indices of all shapes from nF1 and nF2.
1907 aMI.Clear();
1908 GetFullShapeMap(nF1, aMI);
1909 GetFullShapeMap(nF2, aMI);
1910 //
1911 //collect VV, VE, EE, VF interferences
1912 for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
1913 for (i = 0; i < aNbLines[aTypeInt]; ++i) {
1914 BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) :
1915 ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
465d1fba 1916 ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) :
1917 (BOPDS_Interf*)(&aVFs(i))));
78c66ef1 1918 if (aInt->HasIndexNew()) {
1919 aInt->Indices(nS1, nS2);
1920 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1921 nVNew = aInt->IndexNew();
1922 aMVStick.Add(nVNew);
1923 }
4e57c75e 1924 }
1925 }
1926 }
4e57c75e 1927 //collect EF interferences
78c66ef1 1928 for (i = 0; i < aNbLines[4]; ++i) {
1929 const BOPDS_InterfEF& aInt = aEFs(i);
1930 if (aInt.HasIndexNew()) {
1931 aInt.Indices(nS1, nS2);
1932 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1933 nVNew = aInt.IndexNew();
4e57c75e 1934 aMVStick.Add(nVNew);
1935 aMVEF.Add(nVNew);
1936 }
1937 }
1938 }
1939}
1940
1941//=======================================================================
78c66ef1 1942// function: GetFullShapeMap
4e57c75e 1943// purpose:
1944//=======================================================================
78c66ef1 1945void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
1946 BOPCol_MapOfInteger& aMI)
4e57c75e 1947{
78c66ef1 1948 BOPCol_ListIteratorOfListOfInteger aIt;
1949 Standard_Integer nS;
1950 //
1951 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
1952 const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
1953 //
4e57c75e 1954 aMI.Add(nF);
78c66ef1 1955 aIt.Initialize(aLI);
1956 for (; aIt.More(); aIt.Next()) {
1957 nS = aIt.Value();
1958 aMI.Add(nS);
4e57c75e 1959 }
1960}
1961
1962//=======================================================================
1963// function: RemoveUsedVertices
1964// purpose:
1965//=======================================================================
1966void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
1967 BOPCol_MapOfInteger& aMV)
1968{
1969 if (!aMV.Extent()) {
1970 return;
1971 }
1972 Standard_Integer nV;
1973 BOPDS_Pave aPave;
1974 BOPDS_ListIteratorOfListOfPave aItLP;
1975 //
1976 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1977 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
1978 aItLP.Initialize(aLP);
1979 for (;aItLP.More();aItLP.Next()) {
1980 aPave = aItLP.Value();
1981 nV = aPave.Index();
1982 aMV.Remove(nV);
1983 }
1984}
1985
1986//=======================================================================
1987//function : PutPaveOnCurve
1988//purpose :
1989//=======================================================================
0d0481c7 1990void BOPAlgo_PaveFiller::PutPaveOnCurve
465d1fba 1991 (const Standard_Integer nV,
1992 const Standard_Real aTolR3D,
0d0481c7 1993 const BOPDS_Curve& aNC,
465d1fba 1994 const BOPCol_MapOfInteger& aMI,
1995 BOPCol_DataMapOfIntegerReal& aMVTol,
0d0481c7 1996 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV,
465d1fba 1997 const Standard_Integer iCheckExtend)
4e57c75e 1998{
1999 Standard_Boolean bIsVertexOnLine;
0d0481c7 2000 Standard_Real aT;
4e57c75e 2001 //
787c4320 2002 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
0d0481c7 2003 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
4e57c75e 2004 const IntTools_Curve& aIC = aNC.Curve();
2005 //
0d0481c7 2006 Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV));
2007
2008 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
78c66ef1 2009 if (!bIsVertexOnLine && iCheckExtend) {
787c4320 2010 ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
0d0481c7 2011 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
78c66ef1 2012 }
2013 //
4e57c75e 2014 if (bIsVertexOnLine) {
787c4320 2015 // check if aPB contains the parameter aT
2016 Standard_Boolean bExist;
0d0481c7 2017 Standard_Integer nVUsed;
2018 Standard_Real aPTol, aDTol;
4e57c75e 2019 //
787c4320 2020 aDTol = 1.e-12;
4e57c75e 2021 //
787c4320 2022 GeomAdaptor_Curve aGAC(aIC.Curve());
2023 aPTol = aGAC.Resolution(aTolR3D);
b4109929 2024 //
0d0481c7 2025 bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
787c4320 2026 if (bExist) {
2027 // use existing pave
0d0481c7 2028 BOPCol_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed);
2029 if (!pList) {
2030 pList = aDMVLV.Bound(nVUsed, BOPCol_ListOfInteger());
2031 pList->Append(nVUsed);
2032 if (!aMVTol.IsBound(nVUsed)) {
2033 const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed)));
2034 aTolV = BRep_Tool::Tolerance(aVUsed);
2035 aMVTol.Bind(nVUsed, aTolV);
2036 }
2037 }
2038 pList->Append(nV);
2039 if (!aMVTol.IsBound(nV)) {
2040 aTolV = BRep_Tool::Tolerance(aV);
2041 aMVTol.Bind(nV, aTolV);
2042 }
787c4320 2043 }
2044 else {
2045 // add new pave
2046 BOPDS_Pave aPave;
2047 aPave.SetIndex(nV);
2048 aPave.SetParameter(aT);
2049 aPB->AppendExtPave(aPave);
2050 //
0d0481c7 2051 gp_Pnt aP1 = aGAC.Value(aT);
2052 aTolV = BRep_Tool::Tolerance(aV);
2053 gp_Pnt aP2 = BRep_Tool::Pnt(aV);
2054 Standard_Real aDist = aP1.Distance(aP2);
2055 if (aDist > aTolV) {
2056 BRep_Builder().UpdateVertex(aV, aDist + aDTol);
2057 //
2058 if (!aMVTol.IsBound(nV)) {
2059 aMVTol.Bind(nV, aTolV);
2060 }
2061 //
2062 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
2063 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
2064 BRepBndLib::Add(aV, aBoxDS);
2065 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
b4109929 2066 }
2067 }
4e57c75e 2068 }
2069}
2070
2071//=======================================================================
0d0481c7 2072//function : ProcessExistingPaveBlocks
4e57c75e 2073//purpose :
2074//=======================================================================
3510db62 2075void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
4e57c75e 2076 (const Standard_Integer theInt,
decdfc94 2077 const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
3285a59a 2078 const BOPCol_DataMapOfIntegerListOfInteger& aDMBV,
4e57c75e 2079 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2080 BOPCol_DataMapOfShapeInteger& aMVI,
4e57c75e 2081 BOPDS_MapOfPaveBlock& aMPB)
2082{
3285a59a 2083 if (aDMBV.IsEmpty()) {
2084 return;
2085 }
2086 //
3510db62 2087 Standard_Real aT, dummy;
3285a59a 2088 Standard_Integer i, nV, nE, iC, aNbPB, iFlag;
2089 BOPCol_ListIteratorOfListOfInteger aItLI;
2090 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
4e57c75e 2091 //
3285a59a 2092 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
4e57c75e 2093 BOPDS_InterfFF& aFF = aFFs(theInt);
3285a59a 2094 BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
2095 //
2096 aNbPB = aMPBOnIn.Extent();
2097 //
2098 aItBV.Initialize(aDMBV);
2099 for (; aItBV.More(); aItBV.Next()) {
2100 iC = aItBV.Key();
2101 const BOPCol_ListOfInteger& aLBV = aItBV.Value();
4e57c75e 2102 //
3285a59a 2103 BOPDS_Curve& aNC = aVC.ChangeValue(iC);
2104 BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
2105 //
2106 aItLI.Initialize(aLBV);
2107 for (; aItLI.More(); aItLI.Next()) {
2108 nV = aItLI.Value();
2109 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
2110 const Bnd_Box& aBoxV=aSIV.Box();
2111 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
2112 if (!aMVI.IsBound(aV)) {
4e57c75e 2113 continue;
2114 }
4e57c75e 2115 //
3285a59a 2116 for (i = 1; i <= aNbPB; ++i) {
2117 const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i);
2118 if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
2119 continue;
2120 }
2121 //
2122 if (aMPB.Contains(aPB)) {
2123 continue;
2124 }
3510db62 2125 if (myDS->ShapeInfo(aPB->OriginalEdge()).HasFlag()) { // skip degenerated edges
2126 continue;
2127 }
3285a59a 2128 //
2129 nE = aPB->Edge();
2130 const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
2131 const Bnd_Box& aBoxE = aSIE.Box();
2132 //
2133 if (aBoxV.IsOut(aBoxE)) {
2134 continue;
2135 }
2136 //
4e57c75e 2137 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
2138 //
0d0481c7 2139 iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue);
4e57c75e 2140 if (!iFlag) {
2141 aMPB.Add(aPB);
3285a59a 2142 PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
4e57c75e 2143 }
2144 }
2145 }
2146 }
2147}
4e57c75e 2148//=======================================================================
2149//function : UpdateExistingPaveBlocks
2150//purpose :
2151//=======================================================================
3510db62 2152void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
2153 (const Handle(BOPDS_PaveBlock)& aPBf,
2154 BOPDS_ListOfPaveBlock& aLPB,
2155 const Standard_Integer nF1,
2156 const Standard_Integer nF2)
4e57c75e 2157{
01b5b3df 2158 if (!aLPB.Extent()) {
2159 return;
2160 }
2161 //
4e57c75e 2162 Standard_Integer nE;
2163 Standard_Boolean bCB;
2164 Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
2165 Handle(BOPDS_CommonBlock) aCB;
2166 BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
4e57c75e 2167 //
4e57c75e 2168 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
2169 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
2170 //
2171 BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn();
2172 BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn();
2173 BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
2174 BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
2175 //
01b5b3df 2176 // 1. Remove old pave blocks
5a77460e 2177 const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
4e57c75e 2178 bCB = !aCB1.IsNull();
2179 BOPDS_ListOfPaveBlock aLPB1;
2180 //
2181 if (bCB) {
2182 aLPB1.Assign(aCB1->PaveBlocks());
2183 } else {
2184 aLPB1.Append(aPBf);
2185 }
2186 aIt1.Initialize(aLPB1);
2187 for (; aIt1.More(); aIt1.Next()) {
2188 aPB1 = aIt1.Value();
2189 nE = aPB1->OriginalEdge();
2190 //
2191 BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
2192 aIt2.Initialize(aLPB2);
2193 for (; aIt2.More(); aIt2.Next()) {
2194 aPB2 = aIt2.Value();
2195 if (aPB1 == aPB2) {
2196 aLPB2.Remove(aIt2);
2197 break;
2198 }
2199 }
2200 }
2201 //
01b5b3df 2202 // 2. Update pave blocks
4e57c75e 2203 if (bCB) {
1b7ae951 2204 //create new common blocks
3285a59a 2205 BOPDS_ListOfPaveBlock aLPBNew;
4e57c75e 2206 const BOPCol_ListOfInteger& aFaces = aCB1->Faces();
2207 aIt.Initialize(aLPB);
2208 for (; aIt.More(); aIt.Next()) {
51740958 2209 const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
4e57c75e 2210 //
2211 aCB = new BOPDS_CommonBlock;
2212 aIt1.Initialize(aLPB1);
2213 for (; aIt1.More(); aIt1.Next()) {
2214 aPB2 = aIt1.Value();
2215 nE = aPB2->OriginalEdge();
2216 //
2217 aPB2n = new BOPDS_PaveBlock;
51740958 2218 aPB2n->SetPave1(aPBValue->Pave1());
2219 aPB2n->SetPave2(aPBValue->Pave2());
2220 aPB2n->SetEdge(aPBValue->Edge());
4e57c75e 2221 aPB2n->SetOriginalEdge(nE);
2222 aCB->AddPaveBlock(aPB2n);
5a77460e 2223 myDS->SetCommonBlock(aPB2n, aCB);
4e57c75e 2224 myDS->ChangePaveBlocks(nE).Append(aPB2n);
2225 }
3510db62 2226 aCB->SetFaces(aFaces);
4e57c75e 2227 myDS->SortPaveBlocks(aCB);
2228 //
3285a59a 2229 const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
2230 aLPBNew.Append(aPBNew);
4e57c75e 2231 }
3285a59a 2232 //
2233 aLPB = aLPBNew;
4e57c75e 2234 }
1b7ae951 2235 else {
2236 nE = aPBf->OriginalEdge();
2237 BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
2238 aIt.Initialize(aLPB);
2239 for (; aIt.More(); aIt.Next()) {
2240 aPB = aIt.Value();
2241 aLPBE.Append(aPB);
4e57c75e 2242 }
2243 }
2244 //
4e57c75e 2245 Standard_Boolean bIn1, bIn2;
2246 //
2247 bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf);
2248 bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf);
2249 //
1b7ae951 2250 if (bIn1 && bIn2) {
2251 return;
2252 }
2253 //
01b5b3df 2254 // 3. Check new pave blocks for coincidence
1b7ae951 2255 // with the opposite face.
2256 // In case of coincidence create common blocks
2257 Standard_Integer nF;
1b7ae951 2258 //
2259 nF = bIn1 ? nF2 : nF1;
2260 const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
2261 BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
1b7ae951 2262 //
2263 aIt.Initialize(aLPB);
2264 for (; aIt.More(); aIt.Next()) {
51740958 2265 Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
2266 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
1b7ae951 2267 //
2268 IntTools_EdgeFace anEF;
2269 anEF.SetEdge(aE);
2270 anEF.SetFace(aF);
0d0481c7 2271 anEF.SetFuzzyValue(myFuzzyValue);
51740958 2272 anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
1b7ae951 2273 anEF.SetContext(myContext);
2274 anEF.Perform();
4e57c75e 2275 //
1b7ae951 2276 const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
2277 if (aCPrts.Length() == 1) {
2278 Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
2279 if (bCoinc) {
2280 if (bCB) {
51740958 2281 aCB = myDS->CommonBlock(aPBChangeValue);
1b7ae951 2282 } else {
2283 aCB = new BOPDS_CommonBlock;
51740958 2284 aCB->AddPaveBlock(aPBChangeValue);
2285 myDS->SetCommonBlock(aPBChangeValue, aCB);
1b7ae951 2286 }
2287 aCB->AddFace(nF);
2288 //
51740958 2289 aMPBIn.Add(aPBChangeValue);
1b7ae951 2290 }
4e57c75e 2291 }
2292 }
2293}
4e57c75e 2294//=======================================================================
2295// function: PutClosingPaveOnCurve
2296// purpose:
2297//=======================================================================
3510db62 2298void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
4e57c75e 2299{
2300 Standard_Boolean bIsClosed, bHasBounds, bAdded;
2301 Standard_Integer nVC, j;
2302 Standard_Real aT[2], aTC, dT, aTx;
2303 gp_Pnt aP[2] ;
2304 BOPDS_Pave aPVx;
2305 BOPDS_ListIteratorOfListOfPave aItLP;
2306 //
2307 const IntTools_Curve& aIC=aNC.Curve();
2308 const Handle(Geom_Curve)& aC3D=aIC.Curve();
2309 if(aC3D.IsNull()) {
2310 return;
2311 }
2312 //
2313 bIsClosed=IntTools_Tools::IsClosed(aC3D);
2314 if (!bIsClosed) {
2315 return;
2316 }
2317 //
2318 bHasBounds=aIC.HasBounds ();
2319 if (!bHasBounds){
2320 return;
2321 }
2322 //
2323 bAdded=Standard_False;
2324 dT=Precision::PConfusion();
2325 aIC.Bounds (aT[0], aT[1], aP[0], aP[1]);
2326 //
2327 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2328 BOPDS_ListOfPave& aLP=aPB->ChangeExtPaves();
2329 //
2330 aItLP.Initialize(aLP);
2331 for (; aItLP.More() && !bAdded; aItLP.Next()) {
2332 const BOPDS_Pave& aPC=aItLP.Value();
2333 nVC=aPC.Index();
2334 aTC=aPC.Parameter();
2335 //
2336 for (j=0; j<2; ++j) {
2337 if (fabs(aTC-aT[j]) < dT) {
2338 aTx=(!j) ? aT[1] : aT[0];
2339 aPVx.SetIndex(nVC);
2340 aPVx.SetParameter(aTx);
2341 aLP.Append(aPVx);
2342 //
2343 bAdded=Standard_True;
2344 break;
2345 }
2346 }
2347 }
2348}
4e57c75e 2349//=======================================================================
2350//function : PreparePostTreatFF
2351//purpose :
2352//=======================================================================
3510db62 2353void BOPAlgo_PaveFiller::PreparePostTreatFF
4e57c75e 2354 (const Standard_Integer aInt,
3285a59a 2355 const Standard_Integer aCur,
4e57c75e 2356 const Handle(BOPDS_PaveBlock)& aPB,
2357 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2358 BOPCol_DataMapOfShapeInteger& aMVI,
3285a59a 2359 BOPDS_ListOfPaveBlock& aLPBC)
4e57c75e 2360{
3285a59a 2361 Standard_Integer nV1, nV2;
4e57c75e 2362 //
4e57c75e 2363 aLPBC.Append(aPB);
2364 //
2365 aPB->Indices(nV1, nV2);
2366 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
2367 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
2368 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
2369 // Keep info for post treatment
2370 BOPDS_CoupleOfPaveBlocks aCPB;
2371 aCPB.SetIndexInterf(aInt);
3285a59a 2372 aCPB.SetIndex(aCur);
4e57c75e 2373 aCPB.SetPaveBlock1(aPB);
2374 //
2375 aMSCPB.Add(aE, aCPB);
2376 aMVI.Bind(aV1, nV1);
2377 aMVI.Bind(aV2, nV2);
2378}
2379
2380//=======================================================================
b4109929 2381//function : CheckPlanes
2382//purpose :
2383//=======================================================================
465d1fba 2384Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
2385 (const Standard_Integer nF1,
2386 const Standard_Integer nF2)const
b4109929 2387{
2388 Standard_Boolean bToIntersect;
af4e6dab 2389 Standard_Integer i, nV2, iCnt;
b4109929 2390 BOPCol_MapIteratorOfMapOfInteger aIt;
2391 //
af4e6dab 2392 bToIntersect=Standard_False;
b4109929 2393 //
af4e6dab 2394 const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2395 const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
b4109929 2396 //
af4e6dab 2397 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2398 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
b4109929 2399 //
af4e6dab 2400 iCnt=0;
2401 for (i=0; (i<2 && !bToIntersect); ++i) {
2402 const BOPCol_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn()
2403 : aFI2.VerticesOn();
2404 //
2405 aIt.Initialize(aMV2);
b4109929 2406 for (; aIt.More(); aIt.Next()) {
af4e6dab 2407 nV2=aIt.Value();
2408 if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
78c66ef1 2409 ++iCnt;
2410 if (iCnt>1) {
2411 bToIntersect=!bToIntersect;
2412 break;
2413 }
b4109929 2414 }
2415 }
2416 }
b4109929 2417 //
2418 return bToIntersect;
2419}
b4109929 2420//=======================================================================
78c66ef1 2421//function : UpdatePaveBlocks
2422//purpose :
2423//=======================================================================
465d1fba 2424void BOPAlgo_PaveFiller::UpdatePaveBlocks
0d0481c7 2425(const BOPCol_DataMapOfIntegerInteger& aDMNewSD)
78c66ef1 2426{
0d0481c7 2427 if (aDMNewSD.IsEmpty()) {
78c66ef1 2428 return;
2429 }
2430 //
2431 Standard_Integer nSp, aNbPBP, nV[2], i, j;
2432 Standard_Real aT[2];
2433 Standard_Boolean bCB, bRebuild;
2434 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2435 BOPDS_MapOfPaveBlock aMPB;
3510db62 2436 BOPCol_MapOfInteger aMicroEdges;
78c66ef1 2437 //
3510db62 2438 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
78c66ef1 2439 aNbPBP = aPBP.Extent();
3510db62 2440 for (i = 0; i < aNbPBP; ++i) {
2441 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
78c66ef1 2442 //
2443 aItPB.Initialize(aLPB);
2444 for (; aItPB.More(); aItPB.Next()) {
3510db62 2445 Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
2446 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
78c66ef1 2447 bCB = !aCB.IsNull();
2448 if (bCB) {
3510db62 2449 aPB = aCB->PaveBlock1();
78c66ef1 2450 }
2451 //
2452 if (aMPB.Add(aPB)) {
2453 bRebuild = Standard_False;
2454 aPB->Indices(nV[0], nV[1]);
2455 aPB->Range(aT[0], aT[1]);
3510db62 2456 // remember the fact if the edge had different vertices before substitution
2457 Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
78c66ef1 2458 //
2459 for (j = 0; j < 2; ++j) {
0d0481c7 2460 if (aDMNewSD.IsBound(nV[j])) {
78c66ef1 2461 BOPDS_Pave aPave;
2462 //
0d0481c7 2463 nV[j] = aDMNewSD.Find(nV[j]);
78c66ef1 2464 aPave.SetIndex(nV[j]);
2465 aPave.SetParameter(aT[j]);
2466 //
2467 bRebuild = Standard_True;
2468 if (!j) {
2469 aPB->SetPave1(aPave);
3510db62 2470 }
2471 else {
78c66ef1 2472 aPB->SetPave2(aPave);
2473 }
2474 }
2475 }
2476 //
2477 if (bRebuild) {
3510db62 2478 Standard_Boolean isDegEdge = myDS->ShapeInfo(aPB->Edge()).HasFlag();
2479 if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
2480 // now edge has the same vertex on both ends;
2481 // check if it is not a regular closed curve.
2482 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
2483 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[0]));
2484 Standard_Real aLength = IntTools::Length(aE);
2485 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2486 if (aLength <= aTolV * 2.) {
2487 // micro edge, so mark it for removal
2488 aMicroEdges.Add(aPB->Edge());
2489 continue;
2490 }
2491 }
787c4320 2492 nSp = SplitEdge(aPB->OriginalEdge(), nV[0], aT[0], nV[1], aT[1]);
78c66ef1 2493 if (bCB) {
2494 aCB->SetEdge(nSp);
2495 }
2496 else {
2497 aPB->SetEdge(nSp);
2498 }
2499 }// if (bRebuild) {
2500 }// if (aMPB.Add(aPB)) {
2501 }// for (; aItPB.More(); aItPB.Next()) {
2502 }// for (i=0; i<aNbPBP; ++i) {
2503 aMPB.Clear();
3510db62 2504
2505 if (aMicroEdges.Extent())
2506 RemovePaveBlocks(aMicroEdges);
78c66ef1 2507}
2508//=======================================================================
3510db62 2509//function : RemovePaveBlocks
2510//purpose :
2511//=======================================================================
2512void BOPAlgo_PaveFiller::RemovePaveBlocks(const BOPCol_MapOfInteger theEdges)
2513{
2514 // Remove all pave blocks referring to input edges:
2515 //
2516 // 1. from the Pave Blocks Pool
2517 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2518 Standard_Integer aNbPBP = aPBP.Extent(), i;
2519 for (i = 0; i < aNbPBP; ++i) {
2520 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2521 //
2522 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2523 while (aItPB.More()) {
2524 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2525 if (theEdges.Contains(aPB->Edge()))
2526 aLPB.Remove(aItPB);
2527 else
2528 aItPB.Next();
2529 }
2530 }
2531
2532 // 2. from Face Info and section curves
2533 BOPCol_MapOfInteger aMPassed;
2534 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2535 Standard_Integer aNbFF = aFFs.Extent(), j;
2536 for (i = 0; i < aNbFF; ++i) {
2537 BOPDS_InterfFF& aFF = aFFs(i);
2538 Standard_Integer nF1, nF2;
2539 aFF.Indices(nF1, nF2);
2540 //
2541 // rebuild pave block maps of face info
2542 for (j = 0; j < 2; j++) {
2543 Standard_Integer nF = (j == 0 ? nF1 : nF2);
2544 if (!aMPassed.Add(nF))
2545 continue;
2546 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
2547 BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
2548 &aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() };
2549 for (Standard_Integer k = 0; k < 3; k++) {
2550 Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
2551 for (m = 1; m <= aNbPB; ++m) {
2552 const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
2553 if (theEdges.Contains(aPB->Edge()))
2554 break;
2555 }
2556 if (m <= aNbPB) {
2557 BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
2558 aIMPB[k]->Clear();
2559 for (m = 1; m <= aNbPB; ++m) {
2560 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
2561 if (!theEdges.Contains(aPB->Edge()))
2562 aIMPB[k]->Add(aPB);
2563 }
2564 }
2565 }
2566 }
2567 // remove from Section pave blocks
2568 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2569 Standard_Integer aNbC = aVNC.Extent();
2570 for (j = 0; j < aNbC; ++j) {
2571 BOPDS_Curve& aNC = aVNC(j);
2572 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2573 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2574 while (aItPB.More()) {
2575 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2576 if (theEdges.Contains(aPB->Edge()))
2577 aLPB.Remove(aItPB);
2578 else
2579 aItPB.Next();
2580 }
2581 }
2582 }
2583}
2584
2585//=======================================================================
4e57c75e 2586//function : ToleranceFF
2587//purpose : Computes the TolFF according to the tolerance value and
2588// types of the faces.
2589//=======================================================================
b4109929 2590 void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
2591 const BRepAdaptor_Surface& aBAS2,
4e57c75e 2592 Standard_Real& aTolFF)
2593{
2594 Standard_Real aTol1, aTol2;
2595 Standard_Boolean isAna1, isAna2;
2596 //
b4109929 2597 aTol1 = aBAS1.Tolerance();
2598 aTol2 = aBAS2.Tolerance();
4e57c75e 2599 aTolFF = Max(aTol1, aTol2);
2600 //
b4109929 2601 isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
2602 aBAS1.GetType() == GeomAbs_Cylinder ||
2603 aBAS1.GetType() == GeomAbs_Cone ||
2604 aBAS1.GetType() == GeomAbs_Sphere ||
2605 aBAS1.GetType() == GeomAbs_Torus);
4e57c75e 2606 //
b4109929 2607 isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
2608 aBAS2.GetType() == GeomAbs_Cylinder ||
2609 aBAS2.GetType() == GeomAbs_Cone ||
2610 aBAS2.GetType() == GeomAbs_Sphere ||
2611 aBAS2.GetType() == GeomAbs_Torus);
4e57c75e 2612 //
b4109929 2613 if (!isAna1 || !isAna2) {
2614 aTolFF = Max(aTolFF, 5.e-6);
2615 }
4e57c75e 2616}
3510db62 2617//=======================================================================
2618//function : UpdateBlocksWithSharedVertices
2619//purpose :
2620//=======================================================================
2621void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
2622{
2623 if (!myNonDestructive) {
2624 return;
2625 }
2626 //
2627 myErrorStatus=0;
2628 //
2629 Standard_Integer aNbFF;
2630 //
2631 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
2632 aNbFF=aFFs.Extent();
2633 if (!aNbFF) {
2634 return;
2635 }
2636 //
2637 Standard_Boolean bOnCurve, bHasShapeSD;
2638 Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD;
2639 Standard_Real aTolR3D, aTolV;
2640 BOPCol_MapOfInteger aMF;
2641 //
2642 for (i=0; i<aNbFF; ++i) {
2643 BOPDS_InterfFF& aFF=aFFs(i);
2644 //
2645 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
2646 aNbC=aVC.Extent();
2647 if (!aNbC) {
2648 continue;
2649 }
2650 //
2651 aFF.Indices(nF1, nF2);
2652 aTolR3D=aFF.TolR3D();
2653 //
2654 if (aMF.Add(nF1)) {
2655 myDS->UpdateFaceInfoOn(nF1);
2656 }
2657 if (aMF.Add(nF2)) {
2658 myDS->UpdateFaceInfoOn(nF2);
2659 }
2660 //
2661 // Collect old vertices that are shared for nF1, nF2 ->aMI;
2662 BOPCol_MapOfInteger aMI;
2663 BOPCol_MapIteratorOfMapOfInteger aItMI;
2664 //
2665 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2666 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2667 //
2668 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2669 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2670 const BOPCol_MapOfInteger& aMVOn2=aFI2.VerticesOn();
2671 const BOPCol_MapOfInteger& aMVIn2=aFI2.VerticesIn();
2672 //
2673 for (j=0; j<2; ++j) {
2674 const BOPCol_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1;
2675 aItMI.Initialize(aMV1);
2676 for (; aItMI.More(); aItMI.Next()) {
2677 nV=aItMI.Value();
2678 if (myDS->IsNewShape(nV)) {
2679 continue;
2680 }
2681 if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
2682 aMI.Add(nV);
2683 }
2684 }
2685 }
2686 //
2687 // Try to put vertices aMI on curves
2688 for (j=0; j<aNbC; ++j) {
2689 BOPDS_Curve& aNC=aVC.ChangeValue(j);
2690 //const IntTools_Curve& aIC=aNC.Curve();
2691 //
2692 aItMI.Initialize(aMI);
2693 for (; aItMI.More(); aItMI.Next()) {
2694 nV=aItMI.Value();
2695 //
2696 bHasShapeSD=myDS->HasShapeSD(nV, nVSD);
2697 if (bHasShapeSD) {
2698 continue;
2699 }
2700 //
2701 bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D);
2702 if (!bOnCurve) {
2703 continue;
2704 }
2705 //
2706 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2707 aTolV=BRep_Tool::Tolerance(aV);
2708 //
2709 UpdateVertex(nV, aTolV);
2710 }
2711 }//for (j=0; j<aNbC; ++j) {
2712 }//for (i=0; i<aNbFF; ++i) {
2713 //
2714 UpdateCommonBlocksWithSDVertices();
2715}
2716//=======================================================================
2717//function : EstimatePaveOnCurve
2718//purpose :
2719//=======================================================================
2720Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve
2721 (const Standard_Integer nV,
2722 const BOPDS_Curve& aNC,
2723 const Standard_Real aTolR3D)
2724{
2725 Standard_Boolean bIsVertexOnLine;
2726 Standard_Real aT;
2727 //
2728 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2729 const IntTools_Curve& aIC=aNC.Curve();
2730 //
2731 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
2732 return bIsVertexOnLine;
2733}
2734
2735//=======================================================================
2736//function : CorrectToleranceOfSE
2737//purpose :
2738//=======================================================================
2739void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
2740{
2741 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2742 NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
5be33fb6 2743 BOPCol_MapOfInteger aMVIToReduce;
3510db62 2744 //
5be33fb6 2745 // 1. iterate on all sections F-F
3510db62 2746 Standard_Integer aNb = aFFs.Extent(), i;
2747 for (i = 0; i < aNb; ++i) {
01b5b3df 2748 BOPDS_InterfFF& aFF = aFFs(i);
3510db62 2749 Standard_Real aTolR3D = aFF.TolR3D();
2750 Standard_Real aTolReal = aFF.TolReal();
5be33fb6 2751 Standard_Boolean bToReduce = aTolReal < aTolR3D;
0d0481c7 2752 // tolerance of intersection has been increased, so process this intersection
01b5b3df 2753 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
0d0481c7 2754 Standard_Integer aNbC = aVNC.Extent(), k;
2755 for (k = 0; k < aNbC; ++k) {
01b5b3df 2756 BOPDS_Curve& aNC = aVNC(k);
2757 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
0d0481c7 2758 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
01b5b3df 2759 for (; aItLPB.More(); ) {
0d0481c7 2760 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2761 Standard_Integer nE;
5be33fb6 2762 if (!aPB->HasEdge(nE)) {
01b5b3df 2763 aLPB.Remove(aItLPB);
0d0481c7 2764 continue;
2765 }
5be33fb6 2766 //
2767 Standard_Boolean bIsReduced = Standard_False;
2768 if (bToReduce && (aPB->OriginalEdge() < 0)) {
3510db62 2769 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2770 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2771 if (aTolReal < aTolE) {
2772 // reduce edge tolerance
2773 reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolReal);
5be33fb6 2774 bIsReduced = Standard_True;
3510db62 2775 }
5be33fb6 2776 }
2777 //
0d0481c7 2778 // fill in the map vertex index - pave blocks
2779 for (Standard_Integer j=0; j < 2; j++) {
5be33fb6 2780 Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
0d0481c7 2781 BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
2782 if (!pPBList) {
2783 pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
2784 }
5be33fb6 2785 pPBList->Append(aPB);
2786 if (bIsReduced) {
2787 aMVIToReduce.Add(nV);
2788 }
2789 }
01b5b3df 2790 aItLPB.Next();
5be33fb6 2791 }
2792 }
2793 }
2794 //
2795 if (aMVIToReduce.IsEmpty()) {
2796 return;
2797 }
2798 //
2799 // 2. try to reduce tolerances of connected vertices
2800 // 2.1 find all other edges containing these connected vertices to avoid
2801 // reducing the tolerance to the value less than the tolerances of edges,
2802 // i.e. minimal tolerance for the vertex is the max tolerance of the
2803 // edges containing this vertex
2804 BOPCol_DataMapOfIntegerReal aMVITol;
2805 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2806 aNb = aPBP.Extent();
2807 for (i = 0; i < aNb; ++i) {
2808 const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2809 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2810 for (; aItLPB.More(); aItLPB.Next()) {
2811 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2812 Standard_Integer nE;
2813 if (!aPB->HasEdge(nE)) {
2814 continue;
2815 }
2816 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2817 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2818 //
2819 Standard_Integer nV[2];
2820 aPB->Indices(nV[0], nV[1]);
2821 //
2822 for (Standard_Integer j = 0; j < 2; j++) {
2823 if (aMVIToReduce.Contains(nV[j])) {
2824 Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
2825 if (!aMaxTol) {
2826 aMVITol.Bind(nV[j], aTolE);
2827 }
2828 else if (aTolE > *aMaxTol) {
2829 *aMaxTol = aTolE;
3510db62 2830 }
2831 }
2832 }
2833 }
2834 }
5be33fb6 2835 //
2836 // 2.2 reduce tolerances if possible
3510db62 2837 aNb = aMVIPBs.Extent();
2838 for (i = 1; i <= aNb; ++i) {
2839 Standard_Integer nV = aMVIPBs.FindKey(i);
5be33fb6 2840 if (!aMVIToReduce.Contains(nV)) {
2841 continue;
2842 }
2843 //
3510db62 2844 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
5be33fb6 2845 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2846 Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
2847 // it makes no sense to compute the real tolerance if it is
2848 // impossible to reduce the tolerance at least 0.1% of the current value
2849 if (aTolV - aMaxTol < 0.001 * aTolV) {
2850 continue;
2851 }
3510db62 2852 //
2853 // compute the maximal distance from the vertex to the adjacent edges
5be33fb6 2854 gp_Pnt aP = BRep_Tool::Pnt(aV);
2855 //
3510db62 2856 const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
2857 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2858 for (; aItLPB.More(); aItLPB.Next()) {
2859 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2860 Standard_Integer nE = aPB->Edge();
2861 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2862 const BOPDS_Pave& aPave = (aPB->Pave1().Index() == nV ? aPB->Pave1() : aPB->Pave2());
2863 BRepAdaptor_Curve aC(aE);
2864 gp_Pnt aPonE = aC.Value(aPave.Parameter());
2865 Standard_Real aDist = aP.Distance(aPonE);
2866 aDist += BRep_Tool::Tolerance(aE);
2867 if (aDist > aMaxTol) {
2868 aMaxTol = aDist;
2869 }
2870 }
5be33fb6 2871 //
3510db62 2872 if (aMaxTol < aTolV) {
2873 reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol);
2874 }
2875 }
2876}