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