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