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