0024025: The method Modified2() in BRepAlgoAPI_BooleanOperation should be removed.
[occt.git] / src / QANewModTopOpe / QANewModTopOpe_Tools.cxx
CommitLineData
b311480e 1// Copyright (c) 1999-2012 OPEN CASCADE SAS
2//
3// The content of this file is subject to the Open CASCADE Technology Public
4// License Version 6.5 (the "License"). You may not use the content of this file
5// except in compliance with the License. Please obtain a copy of the License
6// at http://www.opencascade.org and read it completely before using this file.
7//
8// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10//
11// The Original Code and all software distributed under the License is
12// distributed on an "AS IS" basis, without warranty of any kind, and the
13// Initial Developer hereby disclaims all such warranties, including without
14// limitation, any warranties of merchantability, fitness for a particular
15// purpose or non-infringement. Please see the License for the specific terms
16// and conditions governing the rights and limitations under the License.
17
7fd59977 18#include <QANewModTopOpe_Tools.ixx>
19
7fd59977 20#include <BRepAlgoAPI_Cut.hxx>
21#include <BRepAlgoAPI_Common.hxx>
22
23#include <TopoDS.hxx>
24#include <TopoDS_Face.hxx>
25#include <TopoDS_Edge.hxx>
7fd59977 26
27#include <BRepTools.hxx>
28#include <BRep_Tool.hxx>
29#include <BRep_Builder.hxx>
30#include <Geom_Surface.hxx>
4e57c75e 31#include <BOPInt_Context.hxx>
7fd59977 32#include <TopExp_Explorer.hxx>
33#include <TopExp.hxx>
34#include <GeomAPI_ProjectPointOnSurf.hxx>
35#include <TopTools_IndexedMapOfShape.hxx>
36#include <TopTools_DataMapOfIntegerShape.hxx>
37
38#include <TCollection_CompareOfReal.hxx>
39#include <SortTools_QuickSortOfReal.hxx>
40
41#include <TColStd_Array1OfReal.hxx>
42#include <TColStd_IndexedMapOfReal.hxx>
43#include <TColStd_ListOfInteger.hxx>
44#include <TColStd_ListIteratorOfListOfInteger.hxx>
45
4e57c75e 46#include <BOPAlgo_PaveFiller.hxx>
47#include <BOPDS_DS.hxx>
48#include <BOPAlgo_Builder.hxx>
49#include <BOPAlgo_BOP.hxx>
50#include <IntTools_CommonPrt.hxx>
51#include <TopTools_ListIteratorOfListOfShape.hxx>
52#include <BOPDS_CommonBlock.hxx>
53#include <BOPTools_AlgoTools3D.hxx>
54
7fd59977 55static Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
4e57c75e 56 const TopoDS_Face& theFace2);
7fd59977 57
58static Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape,
4e57c75e 59 const TopoDS_Shape& theNewShape,
60 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap);
7fd59977 61
62static void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation& theBOP,
4e57c75e 63 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap);
7fd59977 64
65static void SortVertexOnEdge(const TopoDS_Edge& theEdge,
4e57c75e 66 const TopTools_ListOfShape& theListOfVertex,
67 TopTools_ListOfShape& theListOfVertexSorted);
68
69static TopAbs_State GetEdgeState(const BOPDS_PDS& pDS,
70 const Handle(BOPDS_PaveBlock)& aPB);
7fd59977 71
72// ========================================================================================
73// function: NbPoints
74// purpose:
75// ========================================================================================
4e57c75e 76Standard_Integer QANewModTopOpe_Tools::NbPoints(const BOPAlgo_PPaveFiller& theDSFiller)
7fd59977 77{
4e57c75e 78 Standard_Integer i, anbpoints, aNb;
79 //
80 const BOPDS_PDS& pDS = theDSFiller->PDS();
81 anbpoints = 0;
7fd59977 82
4e57c75e 83 //FF
84 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
85 aNb=aFFs.Extent();
86 for (i = 0; i < aNb; ++i) {
87 BOPDS_InterfFF& aFF=aFFs(i);
88 const BOPDS_VectorOfPoint& aVP=aFF.Points();
89 anbpoints += aVP.Extent();
90 }
7fd59977 91
4e57c75e 92 //EF
93 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
94 aNb = aEFs.Extent();
95 for (i = 0; i < aNb; ++i) {
96 BOPDS_InterfEF& aEF=aEFs(i);
97 IntTools_CommonPrt aCP = aEF.CommonPart();
98 if(aCP.Type() == TopAbs_VERTEX) {
7fd59977 99 anbpoints++;
4e57c75e 100 }
7fd59977 101 }
4e57c75e 102
103 //EE
104 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
7fd59977 105 aNb = aEEs.Extent();
4e57c75e 106 for (i = 0; i < aNb; ++i) {
107 BOPDS_InterfEE& aEE=aEEs(i);
108 IntTools_CommonPrt aCP = aEE.CommonPart();
109 if(aCP.Type() == TopAbs_VERTEX) {
7fd59977 110 anbpoints++;
4e57c75e 111 }
7fd59977 112 }
4e57c75e 113
7fd59977 114 return anbpoints;
115}
116
117// ========================================================================================
118// function: NewVertex
119// purpose:
120// ========================================================================================
4e57c75e 121TopoDS_Shape QANewModTopOpe_Tools::NewVertex(const BOPAlgo_PPaveFiller& theDSFiller,
122 const Standard_Integer theIndex)
7fd59977 123{
124 TopoDS_Shape aVertex;
4e57c75e 125 Standard_Integer i, j, anbpoints, aNb, aNbP;
126 //
127 const BOPDS_PDS& pDS = theDSFiller->PDS();
128 anbpoints = 0;
7fd59977 129
4e57c75e 130 //FF
131 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
132 aNb=aFFs.Extent();
133 for (i = 0; i < aNb; ++i) {
134 BOPDS_InterfFF& aFF=aFFs(i);
135 const BOPDS_VectorOfPoint& aVP=aFF.Points();
136 aNbP = aVP.Extent();
137 for(j = 0; j < aNbP; ++j) {
7fd59977 138 anbpoints++;
4e57c75e 139 //
140 if (theIndex == anbpoints) {
141 const BOPDS_Point& aNP = aVP(j);
142 return pDS->Shape(aNP.Index());
7fd59977 143 }
144 }
145 }
7fd59977 146
4e57c75e 147 //EF
148 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
149 aNb = aEFs.Extent();
150 for (i = 0; i < aNb; ++i) {
151 BOPDS_InterfEF& aEF=aEFs(i);
152 IntTools_CommonPrt aCP = aEF.CommonPart();
153 if(aCP.Type() == TopAbs_VERTEX) {
7fd59977 154 anbpoints++;
4e57c75e 155 //
156 if (theIndex == anbpoints) {
157 return pDS->Shape(aEF.IndexNew());
7fd59977 158 }
159 }
160 }
4e57c75e 161
162 //EE
163 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
7fd59977 164 aNb = aEEs.Extent();
4e57c75e 165 for (i = 0; i < aNb; ++i) {
166 BOPDS_InterfEE& aEE=aEEs(i);
167 IntTools_CommonPrt aCP = aEE.CommonPart();
168 if(aCP.Type() == TopAbs_VERTEX) {
7fd59977 169 anbpoints++;
4e57c75e 170 //
171 if (theIndex == anbpoints) {
172 return pDS->Shape(aEE.IndexNew());
7fd59977 173 }
174 }
175 }
4e57c75e 176
7fd59977 177 return aVertex;
178}
179
4e57c75e 180
7fd59977 181// ========================================================================================
4e57c75e 182// function: HasDomain
7fd59977 183// purpose:
184// ========================================================================================
4e57c75e 185Standard_Boolean QANewModTopOpe_Tools::HasSameDomain(const BOPAlgo_PBOP& theBuilder,
186 const TopoDS_Shape& theFace)
7fd59977 187{
4e57c75e 188 Standard_Integer bRet;
189 bRet = Standard_False;
7fd59977 190 //
4e57c75e 191 if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE))
192 return bRet;
7fd59977 193
4e57c75e 194 BOPCol_ListIteratorOfListOfShape aIt;
195 const BOPCol_DataMapOfShapeListOfShape& aImages = theBuilder->Images();
196 if (!aImages.IsBound(theFace)) {
197 return bRet;
198 }
199 const BOPCol_ListOfShape& aLF=aImages.Find(theFace);
200
201 if (aLF.Extent() == 0) {
202 return bRet;
203 }
204 const BOPCol_DataMapOfShapeShape& aShapesSD = theBuilder->ShapesSD();
7fd59977 205
4e57c75e 206 aIt.Initialize(aLF);
207 for (; aIt.More(); aIt.Next()) {
208 const TopoDS_Shape& aFsp = aIt.Value();
209 if (aShapesSD.IsBound(aFsp)) {
210 bRet = Standard_True;
211 break;
7fd59977 212 }
213 }
4e57c75e 214
215 return bRet;
7fd59977 216}
217
218// ========================================================================================
219// function: SameDomain
220// purpose:
221// ========================================================================================
4e57c75e 222void QANewModTopOpe_Tools::SameDomain(const BOPAlgo_PBOP& theBuilder,
223 const TopoDS_Shape& theFace,
224 TopTools_ListOfShape& theResultList)
7fd59977 225{
226 theResultList.Clear();
227
228 if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE))
229 return;
7fd59977 230
4e57c75e 231 BOPCol_ListIteratorOfListOfShape aIt;
232 const BOPCol_ListOfShape& aLF=theBuilder->Splits().Find(theFace);
233
234 if (aLF.Extent() == 0) {
235 return;
236 }
237 const BOPCol_DataMapOfShapeShape& aShapesSD = theBuilder->ShapesSD();
238 const BOPCol_DataMapOfShapeShape& aOrigins = theBuilder->Origins();
239
240 aIt.Initialize(aLF);
241 for (; aIt.More(); aIt.Next()) {
242 const TopoDS_Shape& aFSp = aIt.Value();
243 if (aShapesSD.IsBound(aFSp)) {
244 const TopoDS_Shape& aFSD = aShapesSD.Find(aFSp);
245 const TopoDS_Shape& aFOr = aOrigins.Find(aFSD);
246 if (theFace.IsEqual(aFOr)) {
247 BOPCol_DataMapIteratorOfDataMapOfShapeShape aItSD;
248 aItSD.Initialize(aShapesSD);
249 for (; aItSD.More(); aItSD.Next()) {
250 const TopoDS_Shape& aS = aItSD.Value();
251 if (aFSD.IsEqual(aS)) {
252 const TopoDS_Shape& aSK = aItSD.Key();
253 const TopoDS_Shape& aSKOr = aOrigins.Find(aSK);
254 if (!aSKOr.IsEqual(theFace)) {
255 theResultList.Append(aSKOr);
256 }
257 }
258 }
259 } else {
260 theResultList.Append(aFOr);
7fd59977 261 }
262 }
263 }
264}
265
266// ========================================================================================
267// function: IsSplit
268// purpose:
269// ========================================================================================
4e57c75e 270Standard_Boolean QANewModTopOpe_Tools::IsSplit(const BOPAlgo_PPaveFiller& theDSFiller,
271 const TopoDS_Shape& theEdge,
272 const TopAbs_State theState)
7fd59977 273{
274 if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE))
275 return Standard_False;
7fd59977 276
4e57c75e 277 Standard_Integer index, nSp;
278 //
279 const BOPDS_PDS& pDS = theDSFiller->PDS();
280 index = pDS->Index(theEdge);
281 if (index == -1) {
282 return Standard_False;
283 }
7fd59977 284
4e57c75e 285 const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(index);
286 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
287 aPBIt.Initialize(aLPB);
7fd59977 288 for (; aPBIt.More(); aPBIt.Next()) {
4e57c75e 289 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
290 nSp = aPB->Edge();
291
292 TopAbs_State aSplitState = GetEdgeState(pDS, aPB);
7fd59977 293
4e57c75e 294 if(aSplitState == theState) {
7fd59977 295 return Standard_True;
4e57c75e 296 }
7fd59977 297 }
298
7fd59977 299 return Standard_False;
300}
301
302// ========================================================================================
303// function: Splits
304// purpose:
305// ========================================================================================
4e57c75e 306void QANewModTopOpe_Tools::Splits(const BOPAlgo_PPaveFiller& theDSFiller,
307 const TopoDS_Shape& theEdge,
308 const TopAbs_State theState,
309 TopTools_ListOfShape& theResultList)
7fd59977 310{
311 theResultList.Clear();
312
313 if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE))
314 return;
7fd59977 315
4e57c75e 316 Standard_Integer index, nSp;
317 //
318 const BOPDS_PDS& pDS = theDSFiller->PDS();
319 index = pDS->Index(theEdge);
320 if (index == -1) {
321 return;
322 }
7fd59977 323
4e57c75e 324 const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(index);
325 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
326 aPBIt.Initialize(aLPB);
7fd59977 327 for (; aPBIt.More(); aPBIt.Next()) {
4e57c75e 328 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
329 nSp = aPB->Edge();
330
331 TopAbs_State aSplitState = GetEdgeState(pDS, aPB);
7fd59977 332
333 if(aSplitState == theState) {
4e57c75e 334 TopoDS_Shape aSplit = pDS->Shape(nSp);
7fd59977 335 theResultList.Append(aSplit);
7fd59977 336 }
337 }
7fd59977 338}
339
340// ========================================================================================
341// function: SplitE
342// purpose:
343// ========================================================================================
344Standard_Boolean QANewModTopOpe_Tools::SplitE(const TopoDS_Edge& theEdge,
4e57c75e 345 TopTools_ListOfShape& theSplits)
7fd59977 346{
347 // prequesitory : <Eanc> is a valid edge.
348 TopAbs_Orientation oEanc = theEdge.Orientation();
349 TopoDS_Shape aLocalShape = theEdge.Oriented(TopAbs_FORWARD);
350 TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
351 TopTools_ListOfShape aListOfVertex;
352 TopExp_Explorer exv(EFOR,TopAbs_VERTEX);
353
354 for (;exv.More(); exv.Next()) {
355 const TopoDS_Shape& v = exv.Current();
356 aListOfVertex.Append(v);
357 }
358 Standard_Integer nv = aListOfVertex.Extent();
359
360 if (nv <= 2) return Standard_False;
361 TopTools_ListOfShape aListOfVertexSorted;
362
363 SortVertexOnEdge(EFOR, aListOfVertex, aListOfVertexSorted);
364
365 TopoDS_Vertex v0;
366 TopTools_ListIteratorOfListOfShape anIt(aListOfVertexSorted);
367
368 if (anIt.More()) {
369 v0 = TopoDS::Vertex(anIt.Value());
370 anIt.Next();
371 }
372 else return Standard_False;
373
374 for (; anIt.More(); anIt.Next()) {
375 TopoDS_Vertex v = TopoDS::Vertex(anIt.Value());
376
377 // prequesitory: par0 < par
378 Standard_Real par0 = BRep_Tool::Parameter(v0, EFOR);
379 Standard_Real par = BRep_Tool::Parameter(v, EFOR);
380
381 // here, ed has the same geometries than Ein, but with no subshapes.
382 TopoDS_Edge ed = TopoDS::Edge(EFOR.EmptyCopied());
383 BRep_Builder BB;
384 v0.Orientation(TopAbs_FORWARD);
385 BB.Add(ed, v0);
386 v.Orientation(TopAbs_REVERSED);
387 BB.Add(ed, v);
388 BB.Range(ed, par0, par);
389
390 theSplits.Append(ed.Oriented(oEanc));
391 v0 = v;
392 }
393 return Standard_True;
394}
395
396
397// ========================================================================================
398// function: EdgeCurveAncestors
399// purpose:
400// ========================================================================================
4e57c75e 401 Standard_Boolean QANewModTopOpe_Tools::EdgeCurveAncestors(const BOPAlgo_PPaveFiller& theDSFiller,
402 const TopoDS_Shape& theEdge,
403 TopoDS_Shape& theFace1,
404 TopoDS_Shape& theFace2)
7fd59977 405{
406 theFace1.Nullify();
407 theFace2.Nullify();
4e57c75e 408 //
409 Standard_Integer i, j, aNb, aNbC, nE, nF1, nF2;
410 BOPDS_ListIteratorOfListOfPaveBlock aIt;
7fd59977 411
4e57c75e 412 const BOPDS_PDS& pDS = theDSFiller->PDS();
413 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
7fd59977 414
4e57c75e 415 aNb=aFFs.Extent();
416 for (i = 0; i < aNb; ++i) {
417 BOPDS_InterfFF& aFF=aFFs(i);
418
419 const BOPDS_VectorOfCurve& aVC = aFF.Curves();
420 aNbC = aVC.Extent();
421 for (j = 0; j < aNbC; ++j) {
422 const BOPDS_Curve& aNC = aVC(j);
423 const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks();
424 aIt.Initialize(aLPB);
425 for (; aIt.More(); aIt.Next()) {
426 const Handle(BOPDS_PaveBlock)& aPB = aIt.Value();
427 nE = aPB->Edge();
428 const TopoDS_Shape& aE = pDS->Shape(nE);
429 if (theEdge.IsSame(aE)) {
430 aFF.Indices(nF1, nF2);
431 theFace1 = pDS->Shape(nF1);
432 theFace2 = pDS->Shape(nF2);
433 return Standard_True;
434 }
7fd59977 435 }
436 }
437 }
4e57c75e 438
7fd59977 439 return Standard_False;
440}
441
442// ========================================================================================
443// function: EdgeSectionAncestors
444// purpose:
445// ========================================================================================
4e57c75e 446Standard_Boolean QANewModTopOpe_Tools::EdgeSectionAncestors(const BOPAlgo_PPaveFiller& theDSFiller,
447 const TopoDS_Shape& theEdge,
448 TopTools_ListOfShape& LF1,
449 TopTools_ListOfShape& LF2,
450 TopTools_ListOfShape& LE1,
451 TopTools_ListOfShape& LE2)
7fd59977 452{
453 if(theEdge.ShapeType() != TopAbs_EDGE)
454 return Standard_False;
4e57c75e 455
456 const BOPDS_PDS& pDS = theDSFiller->PDS();
457 Standard_Integer i = 0, nb = 0, nF, nE, nEOr;
458 BOPCol_MapOfInteger aMIF;
459 nb = pDS->NbSourceShapes();
460
461 nE = pDS->Index(theEdge);
462 const BOPDS_ListOfPaveBlock& aLPB1 = pDS->PaveBlocks(nE);
463 if (!aLPB1.Extent()) {
464 return Standard_False;
465 }
7fd59977 466
4e57c75e 467 const Handle(BOPDS_PaveBlock)& aPB1 = aLPB1.First();
5a77460e 468 const Handle(BOPDS_CommonBlock)& aCB=pDS->CommonBlock(aPB1);
4e57c75e 469 if (aCB.IsNull()) {
470 return Standard_False;
471 }
472
473 const BOPCol_ListOfInteger& aLIF = aCB->Faces();
474 BOPCol_ListIteratorOfListOfInteger aItLI;
475 aItLI.Initialize(aLIF);
476 for ( ; aItLI.More(); aItLI.Next()) {
477 nF = aItLI.Value();
478 if(pDS->Rank(nF) == 0)
479 LF1.Append(pDS->Shape(nF));
480 else
481 LF2.Append(pDS->Shape(nF));
7fd59977 482
4e57c75e 483 aMIF.Add(nF);
484 }
7fd59977 485
4e57c75e 486 const BOPDS_ListOfPaveBlock& aLPB = aCB->PaveBlocks();
487 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
488 aItPB.Initialize(aLPB);
489 for (; aItPB.More(); aItPB.Next()) {
490 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
491 nEOr = aPB->OriginalEdge();
7fd59977 492
4e57c75e 493 if(pDS->Rank(nEOr) == 0)
494 LE1.Append(pDS->Shape(nEOr));
495 else
496 LE2.Append(pDS->Shape(nEOr));
7fd59977 497
4e57c75e 498 //find edge ancestors
499 for(i = 0; i < nb; ++i) {
500 const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(i);
501 if(aSI.ShapeType() != TopAbs_FACE) {
502 continue;
7fd59977 503 }
4e57c75e 504 const BOPCol_ListOfInteger& aSubShapes = aSI.SubShapes();
505 aItLI.Initialize(aSubShapes);
506 for (; aItLI.More(); aItLI.Next()) {
507 if (nEOr == aItLI.Value()) {
508 if (aMIF.Add(i)) {
509 if(pDS->Rank(i) == 0) LF1.Append(pDS->Shape(i));
510 else LF2.Append(pDS->Shape(i));
511 }//if (aMIF.Add(i)) {
512 }//if (nEOr == aItLI.Value()) {
513 }//for (; aItLI.More(); aItLI.Next()) {
514 }//for(i = 0; i < nb; ++i) {
7fd59977 515 }
4e57c75e 516
7fd59977 517 Standard_Boolean r = (!LF1.IsEmpty() && !LF2.IsEmpty());
518 r = r && (!LE1.IsEmpty() || !LE2.IsEmpty());
519 return r;
520}
521
522// ========================================================================================
523// function: BoolOpe
524// purpose:
525// ========================================================================================
526Standard_Boolean QANewModTopOpe_Tools::BoolOpe(const TopoDS_Shape& theFace1,
4e57c75e 527 const TopoDS_Shape& theFace2,
528 Standard_Boolean& IsCommonFound,
529 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap)
7fd59977 530{
531 IsCommonFound = Standard_False;
532 theHistoryMap.Clear();
4e57c75e 533 gp_Dir aDNF1, aDNF2;
534 Standard_Integer iSenseFlag;
7fd59977 535
4e57c75e 536 BOPAlgo_PaveFiller aDSFiller;
537 BOPCol_ListOfShape aLS;
538 aLS.Append(theFace1);
539 aLS.Append(theFace2);
540 aDSFiller.SetArguments(aLS);
541
542 aDSFiller.Perform();
543 if (aDSFiller.ErrorStatus()) {
7fd59977 544 return Standard_False;
545 }
4e57c75e 546
547 const BOPDS_PDS& pDS = aDSFiller.PDS();
548
549 Standard_Integer aNb = 0, aNbSps;
7fd59977 550 Standard_Integer i = 0, j = 0;
551 TopTools_IndexedMapOfShape aMapV;
4e57c75e 552
7fd59977 553 {
554 BRepAlgoAPI_Common aCommon(theFace1, theFace2, aDSFiller);
555
556 if(!aCommon.IsDone()) {
557 return Standard_False;
558 }
4e57c75e 559
7fd59977 560 TopExp_Explorer anExp(aCommon.Shape(), TopAbs_FACE);
7fd59977 561 if(!anExp.More()) {
562 IsCommonFound = Standard_False;
563 return Standard_True;
564 }
4e57c75e 565
7fd59977 566 IsCommonFound = Standard_True;
567 TopExp::MapShapes(aCommon.Shape(), TopAbs_VERTEX, aMapV);
568 // fill edge history.begin
569 FillEdgeHistoryMap(aCommon, theHistoryMap);
570 // fill edge history.end
571
572 // fill face history.begin
4e57c75e 573 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
7fd59977 574 aNb = aFFs.Extent();
575 Standard_Boolean bReverseFlag = Standard_True;
576 Standard_Boolean fillhistory = Standard_True;
577
4e57c75e 578 for (i=0; i<aNb; ++i) {
579 BOPDS_InterfFF& aFF = aFFs(i);
580 Standard_Integer nF1, nF2;
581 aFF.Indices(nF1, nF2);
582
583 const TopoDS_Face& aF1 = *(TopoDS_Face*)(&pDS->Shape(nF1));
584 const TopoDS_Face& aF2 = *(TopoDS_Face*)(&pDS->Shape(nF2));
585
586 BOPCol_ListOfInteger aLSE;
587 pDS->SharedEdges(nF1, nF2, aLSE, aDSFiller.Allocator());
588 aNbSps = aLSE.Extent();
589
590 if (!aNbSps) {
591 fillhistory = Standard_False;
592 continue;
593 }
594
595 Standard_Integer nE = aLSE.First();
596 const TopoDS_Edge& aSpE = *(TopoDS_Edge*)(&pDS->Shape(nE));
597
598 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1);
599 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
600 iSenseFlag=BOPTools_AlgoTools3D::SenseFlag (aDNF1, aDNF2);
7fd59977 601
4e57c75e 602 if(iSenseFlag == 1) {
603 fillhistory = Standard_True;
604 bReverseFlag = Standard_False;
7fd59977 605 }
4e57c75e 606 else if(iSenseFlag == -1) {
607 fillhistory = Standard_True;
608 bReverseFlag = Standard_True;
7fd59977 609 }
610 else
4e57c75e 611 fillhistory = Standard_False;
7fd59977 612 }
613
614 if(fillhistory) {
615
616 for(; anExp.More(); anExp.Next()) {
4e57c75e 617 TopoDS_Shape aResShape = anExp.Current();
618
619 if(theFace1.Orientation() == aResShape.Orientation()) {
620 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
621
622 if(bReverseFlag)
623 aResShape.Reverse();
624 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
625 }
626 else if(theFace2.Orientation() == aResShape.Orientation()) {
627 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
628
629 if(bReverseFlag)
630 aResShape.Reverse();
631 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
632 }
633 else {
634 aResShape.Orientation(theFace1.Orientation());
635 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
636 aResShape.Orientation(theFace2.Orientation());
637
638 if(bReverseFlag)
639 aResShape.Reverse();
640 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
641 }
7fd59977 642 }
643 }
644 // fill face history.end
645 }
646 {
647 BRepAlgoAPI_Cut aCut1(theFace1, theFace2, aDSFiller);
648
649 if(!aCut1.IsDone())
650 return Standard_False;
651 TopExp::MapShapes(aCut1.Shape(), TopAbs_VERTEX, aMapV);
652 // fill edge history.begin
653 FillEdgeHistoryMap(aCut1, theHistoryMap);
654 // fill edge history.end
655
656 // fill face history.begin
657 TopExp_Explorer anExp(aCut1.Shape(), TopAbs_FACE);
658
659 for(; anExp.More(); anExp.Next()) {
660 TopoDS_Shape aResShape = anExp.Current();
661 aResShape.Orientation(theFace1.Orientation());
662 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
663 }
664 // fill face history.end
665 }
666
667 {
668 BRepAlgoAPI_Cut aCut2(theFace1, theFace2, aDSFiller, Standard_False);
669
670 if(!aCut2.IsDone())
671 return Standard_False;
672 TopExp::MapShapes(aCut2.Shape(), TopAbs_VERTEX, aMapV);
673 // fill edge history.begin
674 FillEdgeHistoryMap(aCut2, theHistoryMap);
675 // fill edge history.end
676
677 // fill face history.begin
678 TopExp_Explorer anExp(aCut2.Shape(), TopAbs_FACE);
679
680 for(; anExp.More(); anExp.Next()) {
681 TopoDS_Shape aResShape = anExp.Current();
682 aResShape.Orientation(theFace2.Orientation());
683 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
684 }
685 // fill face history.end
686 }
687
688 // fill vertex history.begin
4e57c75e 689 BOPDS_VectorOfInterfVV& aVVs = pDS->InterfVV();
7fd59977 690 aNb = aVVs.Extent();
691
4e57c75e 692 for (i = 0; i < aNb; ++i) {
693 BOPDS_InterfVV& aVVi = aVVs(i);
694 if (!aVVi.HasIndexNew()) {
7fd59977 695 continue;
4e57c75e 696 }
697 Standard_Integer aNewShapeIndex = aVVi.IndexNew();
7fd59977 698
4e57c75e 699 const TopoDS_Shape& aNewVertex = pDS->Shape(aNewShapeIndex);
700
701 if(!aMapV.Contains(aNewVertex)) {
7fd59977 702 continue;
4e57c75e 703 }
704
705 const TopoDS_Shape& aV1 = pDS->Shape(aVVi.Index1());
706 const TopoDS_Shape& aV2 = pDS->Shape(aVVi.Index2());
7fd59977 707 AddShapeToHistoryMap(aV1, aNewVertex, theHistoryMap);
708 AddShapeToHistoryMap(aV2, aNewVertex, theHistoryMap);
709 }
7fd59977 710
4e57c75e 711 BOPDS_VectorOfInterfVE& aVEs = pDS->InterfVE();
712 aNb = aVEs.Extent();
7fd59977 713
4e57c75e 714 for (i = 0; i < aNb; ++i) {
715 BOPDS_InterfVE& aVEi = aVEs(i);
716
717 Standard_Integer anIndex = aVEi.Index1();
718 const TopoDS_Shape& aNewVertex = pDS->Shape(anIndex);
7fd59977 719
720 if(!aMapV.Contains(aNewVertex))
721 continue;
7fd59977 722
4e57c75e 723 AddShapeToHistoryMap(aNewVertex, aNewVertex, theHistoryMap);
7fd59977 724 }
4e57c75e 725
726 BOPDS_VectorOfInterfVF& aVSs = pDS->InterfVF();
7fd59977 727 aNb = aVSs.Extent();
728
4e57c75e 729 for (i = 0; i < aNb; ++i) {
730 BOPDS_InterfVF& aVSi = aVSs(i);
7fd59977 731
4e57c75e 732 Standard_Integer anIndex = aVSi.Index1();
733 const TopoDS_Shape& aNewVertex = pDS->Shape(anIndex);
7fd59977 734
735 if(!aMapV.Contains(aNewVertex))
736 continue;
7fd59977 737
4e57c75e 738 AddShapeToHistoryMap(aNewVertex, aNewVertex, theHistoryMap);
7fd59977 739 }
740 // fill vertex history.end
741 return Standard_True;
742}
743
744// -----------------------------------------------------------------
745// static function: CheckSameDomainFaceInside
746// purpose: Check if distance between several points of theFace1 and
747// theFace2 is not more than sum of maximum of tolerances of
748// theFace1's edges and tolerance of theFace2
749// -----------------------------------------------------------------
750Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
4e57c75e 751 const TopoDS_Face& theFace2) {
7fd59977 752
753 Standard_Real umin = 0., umax = 0., vmin = 0., vmax = 0.;
754 BRepTools::UVBounds(theFace1, umin, umax, vmin, vmax);
4e57c75e 755 Handle(BOPInt_Context) aContext;
7fd59977 756 Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace1);
757 Standard_Real aTolerance = BRep_Tool::Tolerance(theFace1);
758
4e57c75e 759 aContext = new BOPInt_Context;
7fd59977 760 TopExp_Explorer anExpE(theFace1, TopAbs_EDGE);
761
762 for(; anExpE.More(); anExpE.Next()) {
763 const TopoDS_Edge& anEdge = TopoDS::Edge(anExpE.Current());
764 Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
765 aTolerance = (aTolerance < anEdgeTol) ? anEdgeTol : aTolerance;
766 }
767 aTolerance += BRep_Tool::Tolerance(theFace2);
768
769 Standard_Integer nbpoints = 5;
770 Standard_Real adeltau = (umax - umin) / (nbpoints + 1);
771 Standard_Real adeltav = (vmax - vmin) / (nbpoints + 1);
772 Standard_Real U = umin + adeltau;
4e57c75e 773 GeomAPI_ProjectPointOnSurf& aProjector = aContext->ProjPS(theFace2);
7fd59977 774
775 for(Standard_Integer i = 1; i <= nbpoints; i++, U+=adeltau) {
776 Standard_Real V = vmin + adeltav;
777
778 for(Standard_Integer j = 1; j <= nbpoints; j++, V+=adeltav) {
779 gp_Pnt2d aPoint(U,V);
780
4e57c75e 781 if(aContext->IsPointInFace(theFace1, aPoint)) {
782 gp_Pnt aP3d = aSurface->Value(U, V);
783 aProjector.Perform(aP3d);
7fd59977 784
4e57c75e 785 if(aProjector.IsDone()) {
7fd59977 786
4e57c75e 787 if(aProjector.LowerDistance() > aTolerance)
788 return Standard_False;
789 }
7fd59977 790 }
791 }
792 }
793
794 return Standard_True;
795}
796
797// --------------------------------------------------------------------------------------------
798// static function: AddShapeToHistoryMap
799// purpose:
800// --------------------------------------------------------------------------------------------
801Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape,
4e57c75e 802 const TopoDS_Shape& theNewShape,
803 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) {
7fd59977 804
805 if(!theHistoryMap.Contains(theOldShape)) {
806 TopTools_ListOfShape aList;
807 aList.Append(theNewShape);
808 theHistoryMap.Add(theOldShape, aList);
809 return Standard_True;
810 }
811
812 Standard_Boolean found = Standard_False;
813 TopTools_ListOfShape& aList = theHistoryMap.ChangeFromKey(theOldShape);
814 TopTools_ListIteratorOfListOfShape aVIt(aList);
815
816 for(; aVIt.More(); aVIt.Next()) {
817 if(theNewShape.IsSame(aVIt.Value())) {
818 found = Standard_True;
819 break;
820 }
821 }
822
823 if(!found) {
824 aList.Append(theNewShape);
825 }
826 return !found;
827}
828
829// --------------------------------------------------------------------------------------------
830// static function: FillEdgeHistoryMap
831// purpose:
832// --------------------------------------------------------------------------------------------
833void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation& theBOP,
4e57c75e 834 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) {
7fd59977 835
836 TopExp_Explorer anExp;
837 anExp.Init(theBOP.Shape1(), TopAbs_EDGE);
838
839 for(; anExp.More(); anExp.Next()) {
840 const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current());
841 TopTools_ListIteratorOfListOfShape anIt(aList);
842
843 for(; anIt.More(); anIt.Next()) {
844 AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap);
845 }
846 }
847
848 anExp.Init(theBOP.Shape2(), TopAbs_EDGE);
849
850 for(; anExp.More(); anExp.Next()) {
851 const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current());
852 TopTools_ListIteratorOfListOfShape anIt(aList);
853
854 for(; anIt.More(); anIt.Next()) {
855 AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap);
856 }
857 }
858}
859
860// --------------------------------------------------------------------------------------------
861// static function: SortVertexOnEdge
862// purpose:
863// --------------------------------------------------------------------------------------------
864void SortVertexOnEdge(const TopoDS_Edge& theEdge,
4e57c75e 865 const TopTools_ListOfShape& theListOfVertex,
866 TopTools_ListOfShape& theListOfVertexSorted) {
7fd59977 867
868 TopTools_DataMapOfIntegerShape mapiv;// mapiv.Find(iV) = V
869 TColStd_IndexedMapOfReal mappar; // mappar.FindIndex(parV) = iV
870 TopTools_ListIteratorOfListOfShape itlove(theListOfVertex);
871
872 for (; itlove.More(); itlove.Next()){
873 const TopoDS_Vertex& v = TopoDS::Vertex(itlove.Value());
874 Standard_Real par = BRep_Tool::Parameter(v, theEdge);
875 Standard_Integer iv = mappar.Add(par);
876 mapiv.Bind(iv,v);
877 }
878 Standard_Integer nv = mapiv.Extent();
879 TColStd_Array1OfReal tabpar(1,nv);
880 Standard_Integer i = 0;
881
882 for ( i = 1; i <= nv; i++) {
883 Standard_Real p = mappar.FindKey(i);
884 tabpar.SetValue(i,p);
885 }
886 theListOfVertexSorted.Clear();
887 TCollection_CompareOfReal compare;
888 SortTools_QuickSortOfReal::Sort(tabpar, compare);
889
890 for (i = 1; i <= nv; i++) {
891 Standard_Real par = tabpar.Value(i);
892 Standard_Integer iv = mappar.FindIndex(par);
893 const TopoDS_Shape& v = mapiv.Find(iv);
894 theListOfVertexSorted.Append(v);
895 }
896}
4e57c75e 897
898// --------------------------------------------------------------------------------------------
899// static function: GetEdgeState
900// purpose:
901// --------------------------------------------------------------------------------------------
902 static TopAbs_State GetEdgeState(const BOPDS_PDS& pDS,
903 const Handle(BOPDS_PaveBlock)& aPB)
904{
905 Standard_Integer j, aNbFI;
906 Standard_Boolean bIn;
907 TopAbs_State aState = TopAbs_ON;
908 //
909 const BOPDS_VectorOfFaceInfo& aVFI = pDS->FaceInfoPool();
910 aNbFI = aVFI.Extent();
911 //
912 for (j = 0; j < aNbFI; ++j) {
913 const BOPDS_FaceInfo& aFI = aVFI(j);
914 bIn = aFI.PaveBlocksIn().Contains(aPB);
915 if (bIn) {
916 aState = TopAbs_IN;
917 break;
918 }
919 }
920 return aState;
921}