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