0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / BOPTools / BOPTools_AlgoTools.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
19#include <BOPCol_IndexedMapOfShape.hxx>
20#include <BOPCol_MapOfShape.hxx>
21#include <BOPTools.hxx>
22#include <BOPTools_AlgoTools.hxx>
23#include <BOPTools_AlgoTools2D.hxx>
24#include <BOPTools_AlgoTools3D.hxx>
25#include <BOPTools_CoupleOfShape.hxx>
26#include <BOPTools_ListOfCoupleOfShape.hxx>
27#include <BRep_Builder.hxx>
28#include <BRep_Tool.hxx>
29#include <BRepAdaptor_Curve2d.hxx>
30#include <BRepAdaptor_Surface.hxx>
31#include <BRepClass3d_SolidClassifier.hxx>
32#include <BRepLib.hxx>
4e57c75e 33#include <Geom2d_Curve.hxx>
42cf5bc1 34#include <Geom2dInt_Geom2dCurveTool.hxx>
35#include <Geom_Curve.hxx>
df017cc9 36#include <Geom_Plane.hxx>
42cf5bc1 37#include <Geom_Surface.hxx>
4e57c75e 38#include <Geom_TrimmedCurve.hxx>
4e57c75e 39#include <GeomAPI_ProjectPointOnSurf.hxx>
42cf5bc1 40#include <gp_Cone.hxx>
41#include <gp_Cylinder.hxx>
42#include <gp_Lin.hxx>
43#include <gp_Pnt.hxx>
44#include <gp_Pnt2d.hxx>
45#include <gp_Sphere.hxx>
46#include <gp_Torus.hxx>
47#include <gp_XYZ.hxx>
48#include <IntTools_Context.hxx>
49#include <IntTools_Curve.hxx>
50#include <IntTools_Range.hxx>
51#include <IntTools_ShrunkRange.hxx>
52#include <IntTools_Tools.hxx>
53#include <Precision.hxx>
4e57c75e 54#include <TopAbs_Orientation.hxx>
42cf5bc1 55#include <TopExp.hxx>
56#include <TopExp_Explorer.hxx>
4e57c75e 57#include <TopoDS_Compound.hxx>
58#include <TopoDS_CompSolid.hxx>
42cf5bc1 59#include <TopoDS_Edge.hxx>
60#include <TopoDS_Face.hxx>
61#include <TopoDS_Shape.hxx>
4e57c75e 62#include <TopoDS_Shell.hxx>
42cf5bc1 63#include <TopoDS_Solid.hxx>
64#include <TopoDS_Vertex.hxx>
4e57c75e 65#include <TopoDS_Wire.hxx>
b0fbc579 66#include <NCollection_Array1.hxx>
67#include <algorithm>
42cf5bc1 68
69//
4e57c75e 70static
71 Standard_Real AngleWithRef(const gp_Dir& theD1,
72 const gp_Dir& theD2,
73 const gp_Dir& theDRef);
4e57c75e 74
75static
76 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
77 const BOPCol_ListOfShape& thLF,
78 BOPTools_ListOfCoupleOfShape& theLCFF,
1e143abb 79 Handle(IntTools_Context)& theContext);
4e57c75e 80static
81 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
82 const TopoDS_Face& aF);
83
bb58e462 84static
df017cc9 85 void GetFaceDir(const TopoDS_Edge& aE,
86 const TopoDS_Face& aF,
87 const gp_Pnt& aP,
88 const Standard_Real aT,
89 const gp_Dir& aDTgt,
90 gp_Dir& aDN,
91 gp_Dir& aDB,
1e143abb 92 Handle(IntTools_Context)& theContext,
f56518cd 93 GeomAPI_ProjectPointOnSurf& aProjPL,
94 const Standard_Real aDt);
bb58e462 95static
f56518cd 96 Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
df017cc9 97 const gp_Pnt& aP,
df017cc9 98 gp_Dir& aDB,
99 gp_Pnt& aPOut,
1e143abb 100 Handle(IntTools_Context)& theContext,
f56518cd 101 GeomAPI_ProjectPointOnSurf& aProjPL,
393598eb 102 const Standard_Real aDt,
103 const Standard_Real aTolE);
f56518cd 104static
105 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
106 const TopoDS_Face& theF1,
107 const BOPTools_ListOfCoupleOfShape& theLCS,
108 const gp_Pnt& aP);
4e57c75e 109
07ef8bdf 110
b0fbc579 111
112//=======================================================================
4e57c75e 113// function: MakeConnexityBlocks
114// purpose:
115//=======================================================================
505abfb8 116void BOPTools_AlgoTools::MakeConnexityBlocks
117 (const TopoDS_Shape& theS,
118 const TopAbs_ShapeEnum theType1,
119 const TopAbs_ShapeEnum theType2,
120 BOPCol_ListOfShape& theLCB)
4e57c75e 121{
122 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
123 BRep_Builder aBB;
124 TopoDS_Compound aC;
125 TopoDS_Iterator aIt;
126 TopExp_Explorer aExp;
127 BOPCol_MapOfShape aMP;
128 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
129 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
130 BOPCol_ListIteratorOfListOfShape aItLF;
131 //
132 // 1. aMEF
133 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
134 //
135 // 2. aMCB
136 aIt.Initialize(theS);
137 for (; aIt.More(); aIt.Next()) {
138 const TopoDS_Shape& aF1=aIt.Value();
139 if (aMP.Contains(aF1)) {
140 continue;
141 }
142 //
143 aMCB.Clear();
144 aMAdd.Clear();
145 aMAdd.Add(aF1);
146 //
302f96fb 147 for(;;) {
4e57c75e 148 aMAdd1.Clear();
149 //
150 aNbAdd = aMAdd.Extent();
151 for (i=1; i<=aNbAdd; ++i) {
152 const TopoDS_Shape& aF=aMAdd(i);
153 //
154 aExp.Init(aF, theType1);
155 for (; aExp.More(); aExp.Next()) {
156 const TopoDS_Shape& aE=aExp.Current();
157 //
158 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
159 aItLF.Initialize(aLF);
160 for (; aItLF.More(); aItLF.Next()) {
161 const TopoDS_Shape& aFx=aItLF.Value();
162 if (aFx.IsSame(aF)) {
163 continue;
164 }
165 if (aMCB.Contains(aFx)) {
166 continue;
167 }
168 aMAdd1.Add(aFx);
169 }
170 }//for (; aExp.More(); aExp.Next()){
171 aMCB.Add(aF);
172 }// for (i=1; i<=aNbAdd; ++i) {
173 //
174 aNbAdd1=aMAdd1.Extent();
175 if (!aNbAdd1) {
176 break;// ->make new CB from aMCB
177 }
178 //
179 aMAdd.Clear();
180 for (i=1; i<=aNbAdd1; ++i) {
181 const TopoDS_Shape& aFAdd = aMAdd1(i);
182 aMAdd.Add(aFAdd);
183 }
184 }//while(1) {
185 //
186 aNbF=aMCB.Extent();
187 if (aNbF) {
188 aBB.MakeCompound(aC);
189 //
190 for (i=1; i<=aNbF; ++i) {
191 const TopoDS_Shape& aF=aMCB(i);
192 aBB.Add(aC, aF);
193 aMP.Add(aF);
194 }
195 theLCB.Append(aC);
196 }
197 }// for (; aIt.More(); aIt.Next())
198}
199//=======================================================================
200// function: OrientFacesOnShell
201// purpose:
202//=======================================================================
744511c8 203void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
4e57c75e 204{
205 Standard_Boolean bIsProcessed1, bIsProcessed2;
206 Standard_Integer i, aNbE, aNbF, j;
207 TopAbs_Orientation anOrE1, anOrE2;
208 TopoDS_Face aF1x, aF2x;
209 TopoDS_Shape aShellNew;
210 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
211 BOPCol_IndexedMapOfShape aProcessedFaces;
212 BRep_Builder aBB;
213 //
214 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
215 //
505abfb8 216 BOPTools::MapShapesAndAncestors(aShell,
217 TopAbs_EDGE, TopAbs_FACE,
218 aEFMap);
4e57c75e 219 aNbE=aEFMap.Extent();
220 //
221 // One seam edge in aEFMap contains 2 equivalent faces.
222 for (i=1; i<=aNbE; ++i) {
223 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
224 aNbF=aLF.Extent();
225 if (aNbF>1) {
226 BOPCol_ListOfShape aLFTmp;
227 BOPCol_IndexedMapOfShape aFM;
228 //
229 BOPCol_ListIteratorOfListOfShape anIt(aLF);
230 for (; anIt.More(); anIt.Next()) {
231 const TopoDS_Shape& aF=anIt.Value();
232 if (!aFM.Contains(aF)) {
233 aFM.Add(aF);
234 aLFTmp.Append(aF);
235 }
236 }
237 aLF.Clear();
238 aLF=aLFTmp;
239 }
240 }
241 //
242 // Do
243 for (i=1; i<=aNbE; ++i) {
244 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
245 if (BRep_Tool::Degenerated(aE)) {
246 continue;
247 }
248 //
249 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
250 aNbF=aLF.Extent();
251 if (aNbF!=2) {
252 continue;
253 }
254 //
255 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
256 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
257 //
258 bIsProcessed1=aProcessedFaces.Contains(aF1);
259 bIsProcessed2=aProcessedFaces.Contains(aF2);
260 if (bIsProcessed1 && bIsProcessed2) {
261 continue;
262 }
263
264 if (!bIsProcessed1 && !bIsProcessed2) {
265 aProcessedFaces.Add(aF1);
266 aBB.Add(aShellNew, aF1);
267 bIsProcessed1=!bIsProcessed1;
268 }
269 //
270 aF1x=aF1;
271 if (bIsProcessed1) {
272 j=aProcessedFaces.FindIndex(aF1);
273 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
274 }
275 //
276 aF2x=aF2;
277 if (bIsProcessed2) {
278 j=aProcessedFaces.FindIndex(aF2);
279 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
280 }
281 //
282 anOrE1=Orientation(aE, aF1x);
283 anOrE2=Orientation(aE, aF2x);
284 //
285 if (bIsProcessed1 && !bIsProcessed2) {
286 if (anOrE1==anOrE2) {
287 if (!BRep_Tool::IsClosed(aE, aF1) &&
288 !BRep_Tool::IsClosed(aE, aF2)) {
289 aF2.Reverse();
290 }
291 }
292 aProcessedFaces.Add(aF2);
293 aBB.Add(aShellNew, aF2);
294 }
295 else if (!bIsProcessed1 && bIsProcessed2) {
296 if (anOrE1==anOrE2) {
297 if (!BRep_Tool::IsClosed(aE, aF1) &&
298 !BRep_Tool::IsClosed(aE, aF2)) {
299 aF1.Reverse();
300 }
301 }
302 aProcessedFaces.Add(aF1);
303 aBB.Add(aShellNew, aF1);
304 }
305 }
306 //
307 //
308 for (i=1; i<=aNbE; ++i) {
309 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
310 if (BRep_Tool::Degenerated(aE)) {
311 continue;
312 }
313 //
314 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
315 aNbF=aLF.Extent();
316 if (aNbF!=2) {
317 BOPCol_ListIteratorOfListOfShape anIt(aLF);
318 for(; anIt.More(); anIt.Next()) {
319 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
320 if (!aProcessedFaces.Contains(aF)) {
321 aProcessedFaces.Add(aF);
322 aBB.Add(aShellNew, aF);
323 }
324 }
325 }
326 }
327 aShell=aShellNew;
328}
329//=======================================================================
330//function : Orientation
331//purpose :
332//=======================================================================
744511c8 333TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
bb58e462 334 const TopoDS_Face& aF)
4e57c75e 335{
336 TopAbs_Orientation anOr=TopAbs_INTERNAL;
337
338 TopExp_Explorer anExp;
339 anExp.Init(aF, TopAbs_EDGE);
340 for (; anExp.More(); anExp.Next()) {
341 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
342 if (anEF1.IsSame(anE)) {
343 anOr=anEF1.Orientation();
344 break;
345 }
346 }
347 return anOr;
348}
4e57c75e 349//=======================================================================
350// function: MakeConnexityBlock.
351// purpose:
352//=======================================================================
505abfb8 353void BOPTools_AlgoTools::MakeConnexityBlock
354 (BOPCol_ListOfShape& theLFIn,
355 BOPCol_IndexedMapOfShape& theMEAvoid,
356 BOPCol_ListOfShape& theLCB,
357 const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 358{
359 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
360 TopExp_Explorer aExp;
361 BOPCol_ListIteratorOfListOfShape aIt;
362 //
363 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
364 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
365 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
366 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
367 //
368 // 1. aMEF
369 aNbF=theLFIn.Extent();
370 aIt.Initialize(theLFIn);
371 for (; aIt.More(); aIt.Next()) {
372 const TopoDS_Shape& aF=aIt.Value();
373 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
374 }
375 //
376 // 2. aMCB
377 const TopoDS_Shape& aF1=theLFIn.First();
378 aMAdd.Add(aF1);
379 //
302f96fb 380 for(;;) {
4e57c75e 381 aMAdd1.Clear();
382 aNbAdd = aMAdd.Extent();
383 for (i=1; i<=aNbAdd; ++i) {
384 const TopoDS_Shape& aF=aMAdd(i);
385 //
386 //aMAdd1.Clear();
387 aExp.Init(aF, TopAbs_EDGE);
388 for (; aExp.More(); aExp.Next()) {
389 const TopoDS_Shape& aE=aExp.Current();
390 if (theMEAvoid.Contains(aE)){
391 continue;
392 }
393 //
394 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
395 aIt.Initialize(aLF);
396 for (; aIt.More(); aIt.Next()) {
397 const TopoDS_Shape& aFx=aIt.Value();
398 if (aFx.IsSame(aF)) {
399 continue;
400 }
401 if (aMCB.Contains(aFx)) {
402 continue;
403 }
404 aMAdd1.Add(aFx);
405 }
406 }//for (; aExp.More(); aExp.Next()){
407 aMCB.Add(aF);
408 }// for (i=1; i<=aNbAdd; ++i) {
409 //
410 aNbAdd1=aMAdd1.Extent();
411 if (!aNbAdd1) {
412 break;
413 }
414 //
415 aMAdd.Clear();
416 for (i=1; i<=aNbAdd1; ++i) {
417 const TopoDS_Shape& aFAdd=aMAdd1(i);
418 aMAdd.Add(aFAdd);
419 }
420 //
421 }//while(1) {
422
423 //
424 aNbF=aMCB.Extent();
425 for (i=1; i<=aNbF; ++i) {
426 const TopoDS_Shape& aF=aMCB(i);
427 theLCB.Append(aF);
428 }
429}
430//=======================================================================
431// function: ComputeStateByOnePoint
432// purpose:
433//=======================================================================
505abfb8 434TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
435 (const TopoDS_Shape& theS,
436 const TopoDS_Solid& theRef,
437 const Standard_Real theTol,
1e143abb 438 Handle(IntTools_Context)& theContext)
4e57c75e 439{
440 TopAbs_State aState;
441 TopAbs_ShapeEnum aType;
442 //
443 aState=TopAbs_UNKNOWN;
444 aType=theS.ShapeType();
445 if (aType==TopAbs_VERTEX) {
446 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
447 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
448 }
449 else if (aType==TopAbs_EDGE) {
450 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
451 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
452 }
453 return aState;
454}
455
456//=======================================================================
457// function: ComputeState
458// purpose:
459//=======================================================================
505abfb8 460TopAbs_State BOPTools_AlgoTools::ComputeState
461 (const TopoDS_Face& theF,
462 const TopoDS_Solid& theRef,
463 const Standard_Real theTol,
464 BOPCol_IndexedMapOfShape& theBounds,
1e143abb 465 Handle(IntTools_Context)& theContext)
4e57c75e 466{
467 TopAbs_State aState;
468 TopExp_Explorer aExp;
469 TopoDS_Edge aE1;
470 gp_Pnt2d aP2D;
471 gp_Pnt aP3D;
472 //
473 aState=TopAbs_UNKNOWN;
474 //
475 aExp.Init(theF, TopAbs_EDGE);
476 for (; aExp.More(); aExp.Next()) {
477 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
478 if (BRep_Tool::Degenerated(aSE)) {
479 continue;
480 }
481 //
482 if (!theBounds.Contains(aSE)) {
483 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
505abfb8 484 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol,
485 theContext);
4e57c75e 486 return aState;
487 }
488 if (aE1.IsNull()) {
489 aE1=(*(TopoDS_Edge*)(&aSE));
490 }
491 }
492 // !!<- process edges that are all on theRef
493 if (!aE1.IsNull()) {
505abfb8 494 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
495 aP2D, aP3D, theContext);
496 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
497 theContext);
4e57c75e 498 }
499 //
500 return aState;
501}
502//=======================================================================
503// function: ComputeState
504// purpose:
505//=======================================================================
505abfb8 506TopAbs_State BOPTools_AlgoTools::ComputeState
507 (const TopoDS_Vertex& theV,
508 const TopoDS_Solid& theRef,
509 const Standard_Real theTol,
1e143abb 510 Handle(IntTools_Context)& theContext)
4e57c75e 511{
512 TopAbs_State aState;
513 gp_Pnt aP3D;
514 //
515 aP3D=BRep_Tool::Pnt(theV);
505abfb8 516 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
517 theContext);
4e57c75e 518 return aState;
519}
520//=======================================================================
521// function: ComputeState
522// purpose:
523//=======================================================================
505abfb8 524TopAbs_State BOPTools_AlgoTools::ComputeState
525 (const TopoDS_Edge& theE,
526 const TopoDS_Solid& theRef,
527 const Standard_Real theTol,
1e143abb 528 Handle(IntTools_Context)& theContext)
4e57c75e 529{
530 Standard_Real aT1, aT2, aT = 0.;
531 TopAbs_State aState;
532 Handle(Geom_Curve) aC3D;
533 gp_Pnt aP3D;
534 //
535 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
536 //
537 if(aC3D.IsNull()) {
538 //it means that we are in degenerated edge
539 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
540 if(aV.IsNull()){
541 return TopAbs_UNKNOWN;
542 }
543 aP3D=BRep_Tool::Pnt(aV);
544 }
545 else {//usual case
546 Standard_Boolean bF2Inf, bL2Inf;
547 Standard_Real dT=10.;
548 //
549 bF2Inf = Precision::IsNegativeInfinite(aT1);
550 bL2Inf = Precision::IsPositiveInfinite(aT2);
551 //
552 if (bF2Inf && !bL2Inf) {
553 aT=aT2-dT;
554 }
555 else if (!bF2Inf && bL2Inf) {
556 aT=aT1+dT;
557 }
558 else if (bF2Inf && bL2Inf) {
559 aT=0.;
560 }
561 else {
562 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
563 }
564 aC3D->D0(aT, aP3D);
565 }
566 //
505abfb8 567 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
568 theContext);
4e57c75e 569 //
570 return aState;
571}
572//=======================================================================
573// function: ComputeState
574// purpose:
575//=======================================================================
505abfb8 576TopAbs_State BOPTools_AlgoTools::ComputeState
577 (const gp_Pnt& theP,
578 const TopoDS_Solid& theRef,
579 const Standard_Real theTol,
1e143abb 580 Handle(IntTools_Context)& theContext)
4e57c75e 581{
582 TopAbs_State aState;
583 //
584 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
585 aSC.Perform(theP, theTol);
586 //
587 aState=aSC.State();
588 //
589 return aState;
590}
591//=======================================================================
592//function : IsInternalFace
593//purpose :
594//=======================================================================
dde68833 595Standard_Boolean BOPTools_AlgoTools::IsInternalFace
744511c8 596 (const TopoDS_Face& theFace,
597 const TopoDS_Solid& theSolid,
598 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
599 const Standard_Real theTol,
1e143abb 600 Handle(IntTools_Context)& theContext)
4e57c75e 601{
744511c8 602 Standard_Boolean bDegenerated;
603 Standard_Integer aNbF, iRet, iFound;
4e57c75e 604 TopAbs_Orientation aOr;
744511c8 605 TopoDS_Edge aE1;
4e57c75e 606 TopExp_Explorer aExp;
607 BOPCol_ListIteratorOfListOfShape aItF;
608 //
744511c8 609 // For all invoked functions: [::IsInternalFace(...)]
610 // the returned value iRet means:
611 // iRet=0; - state is not IN
612 // iRet=1; - state is IN
613 // iRet=2; - state can not be found by the method of angles
614 //
615 // For this function the returned value iRet means:
616 // iRet=0; - state is not IN
617 // iRet=1; - state is IN
4e57c75e 618 //
744511c8 619 iRet=0;
4e57c75e 620 // 1 Try to find an edge from theFace in theMEF
744511c8 621 iFound=0;
4e57c75e 622 aExp.Init(theFace, TopAbs_EDGE);
623 for(; aExp.More(); aExp.Next()) {
624 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
625 if (!theMEF.Contains(aE)) {
626 continue;
627 }
628 //
744511c8 629 ++iFound;
630 //
4e57c75e 631 aOr=aE.Orientation();
632 if (aOr==TopAbs_INTERNAL) {
633 continue;
634 }
635 bDegenerated=BRep_Tool::Degenerated(aE);
636 if (bDegenerated){
637 continue;
638 }
639 // aE
640 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
641 aNbF=aLF.Extent();
642 if (!aNbF) {
dde68833 643 return iRet != 0; // it can not be so
4e57c75e 644 }
744511c8 645 //
4e57c75e 646 else if (aNbF==1) {
647 // aE is internal edge on aLF.First()
648 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
744511c8 649 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
650 if (aE1.Orientation()!=TopAbs_INTERNAL) {
bb58e462 651 iRet=2;
652 break;
744511c8 653 }
654 //
505abfb8 655 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1,
656 theContext);
744511c8 657 break;
4e57c75e 658 }
744511c8 659 //
4e57c75e 660 else if (aNbF==2) {
661 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
662 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
663 //
664 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
665 // treat as it was for 1 face
505abfb8 666 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
667 theContext);
bb58e462 668 break;
4e57c75e 669 }
670 }
744511c8 671 //
4e57c75e 672 if (aNbF%2) {
dde68833 673 return Standard_False; // it can not be so
4e57c75e 674 }
675 else { // aNbF=2,4,6,8,...
505abfb8 676 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF,
677 theContext);
744511c8 678 break;
4e57c75e 679 }
680 }//for(; aExp.More(); aExp.Next()) {
681 //
744511c8 682 if (!iFound) {
683 // the face has no shared edges with the solid
684 iRet=2;
685 }
686 //
687 if (iRet!=2) {
dde68833 688 return iRet == 1;
744511c8 689 }
690 //
4e57c75e 691 //========================================
692 // 2. Classify face using classifier
693 //
694 TopAbs_State aState;
695 BOPCol_IndexedMapOfShape aBounds;
696 //
744511c8 697 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
698 //
505abfb8 699 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid,
700 theTol, aBounds, theContext);
dde68833 701 return aState == TopAbs_IN;
4e57c75e 702}
703//=======================================================================
704//function : IsInternalFace
705//purpose :
706//=======================================================================
505abfb8 707Standard_Integer BOPTools_AlgoTools::IsInternalFace
708 (const TopoDS_Face& theFace,
709 const TopoDS_Edge& theEdge,
710 BOPCol_ListOfShape& theLF,
1e143abb 711 Handle(IntTools_Context)& theContext)
4e57c75e 712{
744511c8 713 Standard_Integer aNbF, iRet;
4e57c75e 714 //
744511c8 715 iRet=0;
4e57c75e 716 //
717 aNbF=theLF.Extent();
718 if (aNbF==2) {
719 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
720 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
505abfb8 721 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
722 theContext);
744511c8 723 return iRet;
4e57c75e 724 }
725 //
726 else {
727 BOPTools_ListOfCoupleOfShape aLCFF;
728 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
729 //
730 FindFacePairs(theEdge, theLF, aLCFF, theContext);
731 //
732 aIt.Initialize(aLCFF);
733 for (; aIt.More(); aIt.Next()) {
734 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
735 //
736 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
737 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
505abfb8 738 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
739 theContext);
744511c8 740 if (iRet) {
741 return iRet;
4e57c75e 742 }
743 }
744 }
744511c8 745 return iRet;
4e57c75e 746}
747//=======================================================================
748//function : IsInternalFace
749//purpose :
750//=======================================================================
744511c8 751Standard_Integer BOPTools_AlgoTools::IsInternalFace
752 (const TopoDS_Face& theFace,
753 const TopoDS_Edge& theEdge,
754 const TopoDS_Face& theFace1,
755 const TopoDS_Face& theFace2,
1e143abb 756 Handle(IntTools_Context)& theContext)
4e57c75e 757{
758 Standard_Boolean bRet;
744511c8 759 Standard_Integer iRet;
4e57c75e 760 TopoDS_Edge aE1, aE2;
761 TopoDS_Face aFOff;
762 BOPTools_ListOfCoupleOfShape theLCSOff;
763 BOPTools_CoupleOfShape aCS1, aCS2;
764 //
765 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
766 if (aE1.Orientation()==TopAbs_INTERNAL) {
767 aE2=aE1;
768 aE1.Orientation(TopAbs_FORWARD);
769 aE2.Orientation(TopAbs_REVERSED);
770 }
771 else if (theFace1==theFace2) {
772 aE2=aE1;
773 aE1.Orientation(TopAbs_FORWARD);
774 aE2.Orientation(TopAbs_REVERSED);
775 }
776 else {
777 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
778 }
779 //
780 aCS1.SetShape1(theEdge);
781 aCS1.SetShape2(theFace);
782 theLCSOff.Append(aCS1);
783 //
784 aCS2.SetShape1(aE2);
785 aCS2.SetShape2(theFace2);
786 theLCSOff.Append(aCS2);
787 //
744511c8 788 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
4e57c75e 789 //
744511c8 790 iRet=0; // theFace is not internal
791 if (theFace.IsEqual(aFOff)) {
792 // theFace is internal
793 iRet=1;
794 if (!bRet) {
795 // theFace seems to be internal
796 iRet=2;
797 }
798 }
799 return iRet;
4e57c75e 800}
801//=======================================================================
802//function : GetFaceOff
803//purpose :
804//=======================================================================
744511c8 805Standard_Boolean BOPTools_AlgoTools::GetFaceOff
806 (const TopoDS_Edge& theE1,
807 const TopoDS_Face& theF1,
808 BOPTools_ListOfCoupleOfShape& theLCSOff,
809 TopoDS_Face& theFOff,
1e143abb 810 Handle(IntTools_Context)& theContext)
4e57c75e 811{
744511c8 812 Standard_Boolean bRet;
f56518cd 813 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
59f52058 814 Standard_Real aUmin, aUsup, aVmin, aVsup, aPA;
4e57c75e 815 gp_Pnt aPn1, aPn2, aPx;
df017cc9 816 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
4e57c75e 817 gp_Vec aVTgt;
df017cc9 818 TopAbs_Orientation aOr;
4e57c75e 819 Handle(Geom_Curve)aC3D;
bb58e462 820 Handle(Geom_Plane) aPL;
4e57c75e 821 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
bb58e462 822 GeomAPI_ProjectPointOnSurf aProjPL;
4e57c75e 823 //
59f52058 824 aPA=Precision::Angular();
4e57c75e 825 aAngleMin=100.;
826 aTwoPI=M_PI+M_PI;
827 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
4e57c75e 828 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
829 aC3D->D0(aT, aPx);
df017cc9 830 //
4e57c75e 831 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
df017cc9 832 gp_Dir aDTgt(aVTgt), aDTgt2;
833 aOr = theE1.Orientation();
834 //
bb58e462 835 aPL = new Geom_Plane(aPx, aDTgt);
836 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
837 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
838 //
f56518cd 839 aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx);
505abfb8 840 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext,
f56518cd 841 aProjPL, aDt3D);
df017cc9 842 //
4e57c75e 843 aDTF=aDN1^aDBF;
844 //
744511c8 845 bRet=Standard_True;
4e57c75e 846 aIt.Initialize(theLCSOff);
847 for (; aIt.More(); aIt.Next()) {
848 const BOPTools_CoupleOfShape& aCS=aIt.Value();
849 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
850 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
851 //
df017cc9 852 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
505abfb8 853 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext,
f56518cd 854 aProjPL, aDt3D);
4e57c75e 855 //Angle
856 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
857 //
858 if(aAngle<0.) {
859 aAngle=aTwoPI+aAngle;
860 }
df017cc9 861 //
59f52058 862 if (aAngle<aPA) {
df017cc9 863 if (aF2==theF1) {
864 aAngle=M_PI;
865 }
866 else if (aF2.IsSame(theF1)) {
867 aAngle=aTwoPI;
868 }
869 }
870 //
59f52058 871 if (fabs(aAngle-aAngleMin)<aPA) {
872 // the minimal angle can not be found
873 bRet=Standard_False;
874 }
875 //
4e57c75e 876 if (aAngle<aAngleMin){
877 aAngleMin=aAngle;
878 theFOff=aF2;
879 }
744511c8 880 else if (aAngle==aAngleMin) {
881 // the minimal angle can not be found
882 bRet=Standard_False;
883 }
4e57c75e 884 }
744511c8 885 return bRet;
4e57c75e 886}
887//=======================================================================
888//function : GetEdgeOff
889//purpose :
890//=======================================================================
bb58e462 891Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
892 const TopoDS_Face& theF2,
893 TopoDS_Edge& theE2)
4e57c75e 894{
895 Standard_Boolean bFound;
896 TopAbs_Orientation aOr1, aOr1C, aOr2;
897 TopExp_Explorer anExp;
898 //
899 bFound=Standard_False;
900 aOr1=theE1.Orientation();
901 aOr1C=TopAbs::Reverse(aOr1);
902 //
903 anExp.Init(theF2, TopAbs_EDGE);
904 for (; anExp.More(); anExp.Next()) {
905 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
906 if (aEF2.IsSame(theE1)) {
907 aOr2=aEF2.Orientation();
908 if (aOr2==aOr1C) {
909 theE2=aEF2;
910 bFound=!bFound;
911 return bFound;
912 }
913 }
914 }
915 return bFound;
916}
917
918//=======================================================================
919//function : AreFacesSameDomain
920//purpose :
921//=======================================================================
505abfb8 922Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
923 (const TopoDS_Face& theF1,
924 const TopoDS_Face& theF2,
1e143abb 925 Handle(IntTools_Context)& theContext)
4e57c75e 926{
927 Standard_Boolean bFlag;
e656bcbe 928 Standard_Integer iErr;
4e57c75e 929 Standard_Real aTolF1, aTolF2, aTol;
930 gp_Pnt2d aP2D;
931 gp_Pnt aP;
932 TopoDS_Face aF1, aF2;
933 TopoDS_Edge aE1;
934 TopExp_Explorer aExp;
935 //
936 bFlag=Standard_False;
937 //
938 aF1=theF1;
939 aF1.Orientation(TopAbs_FORWARD);
940 aF2=theF2;
941 aF2.Orientation(TopAbs_FORWARD);
942 //
943 aTolF1=BRep_Tool::Tolerance(aF1);
944 // 1
4e57c75e 945 aExp.Init(aF1, TopAbs_EDGE);
946 for (; aExp.More(); aExp.Next()) {
947 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
948 if (!BRep_Tool::Degenerated(aE1)) {
4e57c75e 949 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
950 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
951 }
952 }
4e57c75e 953 // 2
954 aTolF2=BRep_Tool::Tolerance(aF2);
3510db62 955 aTol = aTolF1 + aTolF2 + Precision::Confusion();
4e57c75e 956 //
505abfb8 957 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
958 theContext);
e656bcbe 959 if (!iErr) {
960 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
961 }
4e57c75e 962 //
963 return bFlag;
964}
965
966//=======================================================================
967//function : CheckSameGeom
968//purpose :
969//=======================================================================
505abfb8 970Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
971 (const TopoDS_Face& theF1,
972 const TopoDS_Face& theF2,
1e143abb 973 Handle(IntTools_Context)& theContext)
4e57c75e 974{
975 Standard_Boolean bRet;
976 Standard_Real aTolF1, aTolF2, aTol;
977 gp_Pnt2d aP2D;
978 gp_Pnt aP;
979 TopExp_Explorer aExp;
980 //
981 bRet=Standard_False;
982 aExp.Init(theF1, TopAbs_EDGE);
983 for (; aExp.More(); aExp.Next()) {
984 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
985 if (!BRep_Tool::Degenerated(aE)) {
986 aTolF1=BRep_Tool::Tolerance(theF1);
987 aTolF2=BRep_Tool::Tolerance(theF2);
988 aTol=aTolF1+aTolF2;
989 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
990 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
991 break;
992 }
993 }
994 return bRet;
995}
996//=======================================================================
997// function: Sense
998// purpose:
999//=======================================================================
bb58e462 1000Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
1001 const TopoDS_Face& theF2)
4e57c75e 1002{
1003 Standard_Integer iSense=0;
1004 gp_Dir aDNF1, aDNF2;
1005 TopoDS_Edge aE1, aE2;
1006 TopExp_Explorer aExp;
1007 //
1008 aExp.Init(theF1, TopAbs_EDGE);
1009 for (; aExp.More(); aExp.Next()) {
1010 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
1011 if (!BRep_Tool::Degenerated(aE1)) {
1012 if (!BRep_Tool::IsClosed(aE1, theF1)) {
1013 break;
1014 }
1015 }
1016 }
1017 //
1018 aExp.Init(theF2, TopAbs_EDGE);
1019 for (; aExp.More(); aExp.Next()) {
1020 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
1021 if (!BRep_Tool::Degenerated(aE2)) {
1022 if (!BRep_Tool::IsClosed(aE2, theF2)) {
1023 if (aE2.IsSame(aE1)) {
1024 iSense=1;
1025 break;
1026 }
1027 }
1028 }
1029 }
1030 //
1031 if (!iSense) {
1032 return iSense;
1033 }
1034 //
1035 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
1036 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
1037 //
1038 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1039 //
1040 return iSense;
1041}
1042//=======================================================================
1043// function: IsSplitToReverse
1044// purpose:
1045//=======================================================================
505abfb8 1046Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1047 (const TopoDS_Shape& theSp,
1048 const TopoDS_Shape& theSr,
1e143abb 1049 Handle(IntTools_Context)& theContext)
4e57c75e 1050{
1051 Standard_Boolean bRet;
1052 TopAbs_ShapeEnum aType;
1053 //
1054 bRet=Standard_False;
1055 //
1056 aType=theSp.ShapeType();
1057 switch (aType) {
1058 case TopAbs_EDGE: {
1059 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1060 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1061 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1062 }
1063 break;
1064 //
1065 case TopAbs_FACE: {
1066 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1067 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1068 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1069 }
1070 break;
1071 //
1072 default:
1073 break;
1074 }
1075 return bRet;
1076}
1077//=======================================================================
1078//function :IsSplitToReverse
1079//purpose :
1080//=======================================================================
505abfb8 1081Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1082 (const TopoDS_Face& theFSp,
1083 const TopoDS_Face& theFSr,
1e143abb 1084 Handle(IntTools_Context)& theContext)
4e57c75e 1085{
1086 Standard_Boolean bRet, bFound, bInFace;
1087 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1088 gp_Pnt aPFSp, aPFSr;
1089 gp_Dir aDNFSp;
1090 gp_Vec aD1U, aD1V;
1091 Handle(Geom_Surface) aSr, aSp;
1092 TopAbs_Orientation aOrSr, aOrSp;
1093 TopExp_Explorer anExp;
1094 TopoDS_Edge aESp;
1095 //
1096 bRet=Standard_False;
1097 //
1098 aSr=BRep_Tool::Surface(theFSr);
1099 aSp=BRep_Tool::Surface(theFSp);
1100 if (aSr==aSp) {
1101 aOrSr=theFSr.Orientation();
1102 aOrSp=theFSp.Orientation();
1103 bRet=(aOrSr!=aOrSp);
1104 return bRet;
1105 }
1106 //
1107 bFound=Standard_False;
1108 anExp.Init(theFSp, TopAbs_EDGE);
1109 for (; anExp.More(); anExp.Next()) {
1110 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1111 if (!BRep_Tool::Degenerated(aESp)) {
1112 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1113 bFound=!bFound;
1114 break;
1115 }
1116 }
1117 }
1118 if (!bFound) {
1119 Standard_Boolean bFlag;
1120 Standard_Integer iErr;
1121 gp_Pnt2d aP2DFSp;
1122 //
505abfb8 1123 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp,
1124 theContext);
4e57c75e 1125 if (iErr) {
1126 return bRet;
1127 }
1128 //
1129 aP2DFSp.Coord(aU, aV);
1130 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1131 if (!bFlag) {
1132 return bRet;
1133 }
5b98e25d 1134 //
1135 if (theFSp.Orientation()==TopAbs_REVERSED){
1136 aDNFSp.Reverse();
1137 }
4e57c75e 1138 }
1139 else {
1140 BRep_Tool::Range(aESp, aT1, aT2);
1141 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
505abfb8 1142 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT,
1143 aPFSp, aDNFSp,
1144 theContext);
4e57c75e 1145 }
1146 //
1147 // Parts of theContext->ComputeVS(..)
1148 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1149 aProjector.Perform(aPFSp);
1150 if (!aProjector.IsDone()) {
1151 return bRet;
1152 }
1153 //
1154 aProjector.LowerDistanceParameters(aU, aV);
1155 gp_Pnt2d aP2D(aU, aV);
905522ee 1156 bInFace=theContext->IsPointInOnFace (theFSr, aP2D);
4e57c75e 1157 if (!bInFace) {
1158 return bRet;
1159 }
1160 //
1161 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1162 gp_Dir aDD1U(aD1U);
1163 gp_Dir aDD1V(aD1V);
1164 gp_Dir aDNFSr=aDD1U^aDD1V;
1165 if (theFSr.Orientation()==TopAbs_REVERSED){
1166 aDNFSr.Reverse();
1167 }
1168 //
1169 aScPr=aDNFSp*aDNFSr;
1170 bRet=(aScPr<0.);
1171 //
1172 return bRet;
1173}
1174//=======================================================================
1175//function :IsSplitToReverse
1176//purpose :
1177//=======================================================================
505abfb8 1178Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1179 (const TopoDS_Edge& aEF1,
1180 const TopoDS_Edge& aEF2,
1e143abb 1181 Handle(IntTools_Context)& theContext)
4e57c75e 1182{
1183 Standard_Boolean bRet, bIsDegenerated;
1184 //
1185 bRet=Standard_False;
1186 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1187 BRep_Tool::Degenerated(aEF2));
1188 if (bIsDegenerated) {
1189 return bRet;
1190 }
1191 //
1192 Standard_Real a, b;
1193 TopAbs_Orientation aOrE, aOrSp;
1194 Handle(Geom_Curve)aC1, aC2;
1195 //
1196 aC2=BRep_Tool::Curve(aEF2, a, b);
1197 aC1=BRep_Tool::Curve(aEF1, a, b);
1198 //
1199 if (aC1==aC2) {
1200 aOrE=aEF2.Orientation();
1201 aOrSp=aEF1.Orientation();
1202 bRet=(aOrE!=aOrSp);
1203 return bRet;
1204 }
1205 //
1206 Standard_Real aT1, aT2, aScPr;
1207 gp_Vec aV1, aV2;
1208 gp_Pnt aP;
1209 //
1210 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1211 aC1->D0(aT1, aP);
1212 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1213 gp_Dir aDT1(aV1);
1214 //
1215 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1216 //
1217 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1218 gp_Dir aDT2(aV2);
1219 //
1220 aScPr=aDT1*aDT2;
1221 bRet=(aScPr<0.);
1222 //
1223 return bRet;
1224}
1225
1226//=======================================================================
1227//function : IsHole
1228//purpose :
1229//=======================================================================
bb58e462 1230Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1231 const TopoDS_Shape& aFace)
4e57c75e 1232{
1233 Standard_Boolean bIsHole;
1234 Standard_Integer i, aNbS;
1235 Standard_Real aT1, aT2, aS;
96a95605 1236 Standard_Real aU1, aU, dU;
4e57c75e 1237 Standard_Real aX1, aY1, aX0, aY0;
1238 TopAbs_Orientation aOr;
1239
1240 gp_Pnt2d aP2D0, aP2D1;
1241 Handle(Geom2d_Curve) aC2D;
1242 TopoDS_Face aF, aFF;
1243 TopoDS_Iterator aItW;
1244 //
1245 bIsHole=Standard_False;
1246 //
1247 aF=(*(TopoDS_Face *)(&aFace));
1248 aFF=aF;
1249 aFF.Orientation(TopAbs_FORWARD);
1250 //
1251 aS=0.;
1252 aItW.Initialize(aW);
1253 for (; aItW.More(); aItW.Next()) {
1254 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1255 aOr=aE.Orientation();
1256 if (!(aOr==TopAbs_FORWARD ||
1257 aOr==TopAbs_REVERSED)) {
1258 continue;
1259 }
1260 //
1261 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1262 if (aC2D.IsNull()) {
1263 break; //xx
1264 }
1265 //
1266 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1267 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1268 if (aNbS>2) {
1269 aNbS*=4;
1270 }
1271 //
1272 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1273 aU =aT1;
1274 aU1=aT1;
4e57c75e 1275 if (aOr==TopAbs_REVERSED) {
1276 aU =aT2;
1277 aU1=aT2;
4e57c75e 1278 dU=-dU;
1279 }
1280 //
94f71cad 1281 aBAC2D.D0(aU, aP2D0);
4e57c75e 1282 for(i=2; i<=aNbS; i++) {
1283 aU=aU1+(i-1)*dU;
94f71cad 1284 aBAC2D.D0(aU, aP2D1);
4e57c75e 1285 aP2D0.Coord(aX0, aY0);
1286 aP2D1.Coord(aX1, aY1);
1287 //
1288 aS=aS+(aY0+aY1)*(aX1-aX0);
1289 //
1290 aP2D0=aP2D1;
1291 }
1292 }//for (; aItW.More(); aItW.Next()) {
1293 bIsHole=(aS>0.);
1294 return bIsHole;
1295}
1296
1297//=======================================================================
1298// function: MakeContainer
1299// purpose:
1300//=======================================================================
bb58e462 1301void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1302 TopoDS_Shape& theC)
4e57c75e 1303{
1304 BRep_Builder aBB;
1305 //
1306 switch(theType) {
1307 case TopAbs_COMPOUND:{
1308 TopoDS_Compound aC;
1309 aBB.MakeCompound(aC);
1310 theC=aC;
1311 }
1312 break;
1313 //
1314 case TopAbs_COMPSOLID:{
1315 TopoDS_CompSolid aCS;
1316 aBB.MakeCompSolid(aCS);
1317 theC=aCS;
1318 }
1319 break;
1320 //
1321 case TopAbs_SOLID:{
1322 TopoDS_Solid aSolid;
1323 aBB.MakeSolid(aSolid);
1324 theC=aSolid;
1325 }
1326 break;
1327 //
1328 //
1329 case TopAbs_SHELL:{
1330 TopoDS_Shell aShell;
1331 aBB.MakeShell(aShell);
1332 theC=aShell;
1333 }
1334 break;
1335 //
1336 case TopAbs_WIRE: {
1337 TopoDS_Wire aWire;
1338 aBB.MakeWire(aWire);
1339 theC=aWire;
1340 }
1341 break;
1342 //
1343 default:
1344 break;
1345 }
1346}
1347//=======================================================================
1348// function: MakePCurve
1349// purpose:
1350//=======================================================================
bb58e462 1351void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1352 const TopoDS_Face& aF1,
1353 const TopoDS_Face& aF2,
1354 const IntTools_Curve& aIC,
1355 const Standard_Boolean bPC1,
1356 const Standard_Boolean bPC2)
4e57c75e 1357
1358{
1359 Standard_Integer i;
1360 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1361 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1362 TopoDS_Face aFFWD;
1363 BRep_Builder aBB;
1364 Standard_Boolean bPC;
1365 //
1366 aTolE=BRep_Tool::Tolerance(aE);
1367 //
1368 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
505abfb8 1369 Handle(Geom_TrimmedCurve)aC3DETrim=
1370 new Geom_TrimmedCurve(aC3DE, aT1, aT2);
4e57c75e 1371 //
1372 for (i=0; i<2; ++i) {
1373 bPC = !i ? bPC1 : bPC2;
1374 if (!bPC) {
1375 continue;
1376 }
1377 //
1378 if (!i) {
1379 aFFWD=aF1;
1380 aC2Dx1=aIC.FirstCurve2d();
1381 }
1382 else {
1383 aFFWD=aF2;
1384 aC2Dx1=aIC.SecondCurve2d();
1385 }
1386 //
1387 aFFWD.Orientation(TopAbs_FORWARD);
1388 //
1389 aC2D=aC2Dx1;
1390 if (aC2D.IsNull()) {
1391 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1392 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1393 aOutFirst, aOutLast,
1394 aOutTol);
1395 }
1396 //
1397 if (aC3DE->IsPeriodic()) {
505abfb8 1398 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D,
1399 aC2DA);
4e57c75e 1400 }
1401 else {
505abfb8 1402 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D,
1403 aC2DA);
4e57c75e 1404 }
1405 //
1406 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1407 //BRepLib::SameParameter(aE);
1408 }
1409 BRepLib::SameParameter(aE);
1410}
1411//=======================================================================
1412// function: MakeEdge
1413// purpose:
1414//=======================================================================
bb58e462 1415void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1416 const TopoDS_Vertex& theV1,
1417 const Standard_Real theT1,
1418 const TopoDS_Vertex& theV2,
1419 const Standard_Real theT2,
1420 const Standard_Real theTolR3D,
1421 TopoDS_Edge& theE)
4e57c75e 1422{
1423 Standard_Real aTolV;
1424 BRep_Builder aBB;
1425 //
505abfb8 1426 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2,
1427 theE);
4e57c75e 1428 //
1429 aBB.UpdateEdge(theE, theTolR3D);
1430 //
1431 aTolV=BRep_Tool::Tolerance(theV1);
1432 if (aTolV<theTolR3D) {
1433 aBB.UpdateVertex(theV1, theTolR3D);
1434 }
1435 //
1436 aTolV=BRep_Tool::Tolerance(theV2);
1437 if (aTolV<theTolR3D) {
1438 aBB.UpdateVertex(theV2, theTolR3D);
1439 }
1440}
1441//=======================================================================
1442// function: ComputeVV
1443// purpose:
1444//=======================================================================
bb58e462 1445Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1446 const gp_Pnt& aP2,
1447 const Standard_Real aTolP2)
4e57c75e 1448{
1449 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1450 gp_Pnt aP1;
1451 //
1452 aTolV1=BRep_Tool::Tolerance(aV1);
1453
3510db62 1454 aTolSum = aTolV1 + aTolP2 + Precision::Confusion();
4e57c75e 1455 aTolSum2=aTolSum*aTolSum;
1456 //
1457 aP1=BRep_Tool::Pnt(aV1);
1458 //
1459 aD2=aP1.SquareDistance(aP2);
1460 if (aD2>aTolSum2) {
1461 return 1;
1462 }
1463 return 0;
1464}
1465//=======================================================================
1466// function: ComputeVV
1467// purpose:
1468//=======================================================================
bb58e462 1469Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1470 const TopoDS_Vertex& aV2)
4e57c75e 1471{
1472 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1473 gp_Pnt aP1, aP2;
1474 //
1475 aTolV1=BRep_Tool::Tolerance(aV1);
1476 aTolV2=BRep_Tool::Tolerance(aV2);
3510db62 1477 aTolSum = aTolV1 + aTolV2 + Precision::Confusion();
4e57c75e 1478 aTolSum2=aTolSum*aTolSum;
1479 //
1480 aP1=BRep_Tool::Pnt(aV1);
1481 aP2=BRep_Tool::Pnt(aV2);
1482 //
1483 aD2=aP1.SquareDistance(aP2);
1484 if (aD2>aTolSum2) {
1485 return 1;
1486 }
1487 return 0;
1488}
1489//=======================================================================
1490// function: MakeVertex
1491// purpose :
1492//=======================================================================
3510db62 1493void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
bb58e462 1494 TopoDS_Vertex& aVnew)
4e57c75e 1495{
07ef8bdf 1496 Standard_Integer aNb = aLV.Extent();
1497 if (aNb == 1)
138ac530 1498 aVnew=*((TopoDS_Vertex*)(&aLV.First()));
07ef8bdf 1499 else if (aNb > 1)
1500 {
1501 Standard_Real aNTol;
1502 gp_Pnt aNC;
1503 BRepLib::BoundingVertex(aLV, aNC, aNTol);
4e57c75e 1504 BRep_Builder aBB;
07ef8bdf 1505 aBB.MakeVertex(aVnew, aNC, aNTol);
4e57c75e 1506 }
1507}
1508//=======================================================================
1509//function : GetEdgeOnFace
1510//purpose :
1511//=======================================================================
505abfb8 1512Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
1513(const TopoDS_Edge& theE1,
1514 const TopoDS_Face& theF2,
1515 TopoDS_Edge& theE2)
4e57c75e 1516{
1517 Standard_Boolean bFound;
1518 TopoDS_Iterator aItF, aItW;
1519 //
1520 bFound=Standard_False;
1521 //
1522 aItF.Initialize(theF2);
1523 for (; aItF.More(); aItF.Next()) {
1524 const TopoDS_Shape& aW=aItF.Value();
1525 aItW.Initialize(aW);
1526 for (; aItW.More(); aItW.Next()) {
1527 const TopoDS_Shape& aE=aItW.Value();
1528 if (aE.IsSame(theE1)) {
1529 theE2=(*(TopoDS_Edge*)(&aE));
1530 bFound=!bFound;
1531 return bFound;
1532 }
1533 }
1534 }
1535 return bFound;
1536}
1537//=======================================================================
1538//function : FindFacePairs
1539//purpose :
1540//=======================================================================
1541Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1542 const BOPCol_ListOfShape& thLF,
1543 BOPTools_ListOfCoupleOfShape& theLCFF,
1e143abb 1544 Handle(IntTools_Context)& theContext)
4e57c75e 1545{
1546 Standard_Boolean bFound;
1547 Standard_Integer i, aNbCEF;
1d47d8d0 1548 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
4e57c75e 1549 BOPCol_MapOfShape aMFP;
1550 TopoDS_Face aF1, aF2;
1551 TopoDS_Edge aEL, aE1;
1552 BOPCol_ListIteratorOfListOfShape aItLF;
1553 BOPTools_CoupleOfShape aCEF, aCFF;
1554 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1555 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1556 //
1557 bFound=Standard_True;
1558 //
1559 // Preface aLCEF
1560 aItLF.Initialize(thLF);
1561 for (; aItLF.More(); aItLF.Next()) {
1562 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1563 //
1564 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1565 if (!bFound) {
1566 return bFound; // it can not be so
1567 }
1568 //
1569 aCEF.SetShape1(aEL);
1570 aCEF.SetShape2(aFL);
1571 aLCEF.Append(aCEF);
1572 }
1573 //
1574 aNbCEF=aLCEF.Extent();
1575 while(aNbCEF) {
1576 //
1577 // aLCEFx
1578 aLCEFx.Clear();
1579 aIt.Initialize(aLCEF);
1580 for (i=0; aIt.More(); aIt.Next(), ++i) {
1581 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1582 const TopoDS_Shape& aEx=aCSx.Shape1();
1583 const TopoDS_Shape& aFx=aCSx.Shape2();
1584 //
1585 aOr=aEx.Orientation();
1586 //
1587 if (!i) {
1588 aOrC=TopAbs::Reverse(aOr);
1589 aE1=(*(TopoDS_Edge*)(&aEx));
1590 aF1=(*(TopoDS_Face*)(&aFx));
1591 aMFP.Add(aFx);
1592 continue;
1593 }
1594 //
1595 if (aOr==aOrC) {
1596 aLCEFx.Append(aCSx);
1597 aMFP.Add(aFx);
1598 }
1599 }
1600 //
1601 // F2
1602 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1603 //
1604 aCFF.SetShape1(aF1);
1605 aCFF.SetShape2(aF2);
1606 theLCFF.Append(aCFF);
1607 //
1608 aMFP.Add(aF1);
1609 aMFP.Add(aF2);
1610 //
1611 // refine aLCEF
1612 aLCEFx.Clear();
1613 aLCEFx=aLCEF;
1614 aLCEF.Clear();
1615 aIt.Initialize(aLCEFx);
1616 for (; aIt.More(); aIt.Next()) {
1617 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1618 const TopoDS_Shape& aFx=aCSx.Shape2();
1619 if (!aMFP.Contains(aFx)) {
1620 aLCEF.Append(aCSx);
1621 }
1622 }
1623 //
1624 aNbCEF=aLCEF.Extent();
1625 }//while(aNbCEF) {
1626 //
1627 return bFound;
1628}
1629//=======================================================================
1630//function : AngleWithRef
1631//purpose :
1632//=======================================================================
1633Standard_Real AngleWithRef(const gp_Dir& theD1,
1634 const gp_Dir& theD2,
1635 const gp_Dir& theDRef)
1636{
1637 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1638 gp_XYZ aXYZ;
1639 //
1640 aHalfPI=0.5*M_PI;
1641 //
1642 const gp_XYZ& aXYZ1=theD1.XYZ();
1643 const gp_XYZ& aXYZ2=theD2.XYZ();
1644 aXYZ=aXYZ1.Crossed(aXYZ2);
1645 aSinus=aXYZ.Modulus();
1646 aCosinus=theD1*theD2;
1647 //
1648 aBeta=0.;
1649 if (aSinus>=0.) {
1650 aBeta=aHalfPI*(1.-aCosinus);
1651 }
1652 else {
1653 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1654 }
1655 //
1656 aScPr=aXYZ.Dot(theDRef.XYZ());
1657 if (aScPr<0.) {
1658 aBeta=-aBeta;
1659 }
1660 return aBeta;
1661}
1662//=======================================================================
4e57c75e 1663// function: IsBlockInOnFace
1664// purpose:
1665//=======================================================================
505abfb8 1666Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
1667 (const IntTools_Range& aShrR,
1668 const TopoDS_Face& aF,
1669 const TopoDS_Edge& aE1,
1e143abb 1670 Handle(IntTools_Context)& aContext)
4e57c75e 1671{
1672 Standard_Boolean bFlag;
1673 Standard_Real f1, l1, ULD, VLD;
1674 gp_Pnt2d aP2D;
1675 gp_Pnt aP11, aP12;
1676 //
1677 aShrR.Range(f1, l1);
1678 Standard_Real dt=0.0075, k;//dt=0.001, k;
1679 k=dt*(l1-f1);
1680 f1=f1+k;
1681 l1=l1-k;
1682 //
1683 // Treatment P11
1684 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1685 //
1686 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1687 aProjector.Perform(aP11);
1688 //
1689 bFlag=aProjector.IsDone();
1690 if (!bFlag) {
1691 return bFlag;
1692 }
1693
1694 aProjector.LowerDistanceParameters(ULD, VLD);
1695 aP2D.SetCoord(ULD, VLD);
1696 //
1697 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1698 //
1699 if (!bFlag) {
1700 return bFlag;
1701 }
1702 //
1703 // Treatment P12
1704 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1705 //
1706 aProjector.Perform(aP12);
1707 //
1708 bFlag=aProjector.IsDone();
1709 if (!bFlag) {
1710 return bFlag;
1711 }
1712
1713 aProjector.LowerDistanceParameters(ULD, VLD);
1714 aP2D.SetCoord(ULD, VLD);
1715 //
1716 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1717 //
1718 if (!bFlag) {
1719 return bFlag;
1720 }
1721 //
1722 // Treatment intemediate
1723 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1724 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1725 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1726 //
1727 aProjector.Perform(aP12);
1728 //
1729 bFlag=aProjector.IsDone();
1730 if (!bFlag) {
1731 return bFlag;
1732 }
1733 //
1734 aTolE=BRep_Tool::Tolerance(aE1);
1735 aTolF=BRep_Tool::Tolerance(aF);
1736 aTol=aTolE+aTolF;
1737 aDist=aProjector.LowerDistance();
1738 if (aDist > aTol){
1739 return Standard_False;
1740 }
1741
1742 aProjector.LowerDistanceParameters(ULD, VLD);
1743 aP2D.SetCoord(ULD, VLD);
1744 //
1745 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1746 //
1747 if (!bFlag) {
1748 return bFlag;
1749 }
1750 return bFlag;
1751}
1752
1753//=======================================================================
4e57c75e 1754//function : IsMicroEdge
1755//purpose :
1756//=======================================================================
505abfb8 1757Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
1758 (const TopoDS_Edge& aE,
01b5b3df 1759 const Handle(IntTools_Context)& aCtx,
1760 const Standard_Boolean bCheckSplittable)
4e57c75e 1761{
1762 Standard_Boolean bRet;
4e57c75e 1763 Standard_Real aT1, aT2, aTmp;
1764 Handle(Geom_Curve) aC3D;
1765 TopoDS_Vertex aV1, aV2;
1766 //
1767 bRet=(BRep_Tool::Degenerated(aE) ||
1768 !BRep_Tool::IsGeometric(aE));
1769 if (bRet) {
1770 return bRet;
1771 }
1772 //
1773 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1774 TopExp::Vertices(aE, aV1, aV2);
1775 aT1=BRep_Tool::Parameter(aV1, aE);
1776 aT2=BRep_Tool::Parameter(aV2, aE);
1777 if (aT2<aT1) {
1778 aTmp=aT1;
1779 aT1=aT2;
1780 aT2=aTmp;
1781 }
1782 //
1e143abb 1783 IntTools_ShrunkRange aSR;
505abfb8 1784 aSR.SetContext(aCtx);
1785 aSR.SetData(aE, aT1, aT2, aV1, aV2);
4e57c75e 1786 aSR.Perform();
01b5b3df 1787 bRet = !aSR.IsDone();
1788 if (!bRet && bCheckSplittable) {
1789 bRet = !aSR.IsSplittable();
1790 }
4e57c75e 1791 //
1792 return bRet;
1793}
1794
4e57c75e 1795//=======================================================================
df017cc9 1796//function : GetFaceDir
1797//purpose : Get binormal direction for the face in the point aP
1798//=======================================================================
bb58e462 1799void GetFaceDir(const TopoDS_Edge& aE,
1800 const TopoDS_Face& aF,
1801 const gp_Pnt& aP,
1802 const Standard_Real aT,
1803 const gp_Dir& aDTgt,
1804 gp_Dir& aDN,
1805 gp_Dir& aDB,
1e143abb 1806 Handle(IntTools_Context)& theContext,
f56518cd 1807 GeomAPI_ProjectPointOnSurf& aProjPL,
1808 const Standard_Real aDt)
df017cc9 1809{
393598eb 1810 Standard_Real aTolE;
1811 gp_Pnt aPx;
1812 //
df017cc9 1813 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1814 if (aF.Orientation()==TopAbs_REVERSED){
1815 aDN.Reverse();
1816 }
393598eb 1817 //
1818 aTolE=BRep_Tool::Tolerance(aE);
df017cc9 1819 aDB = aDN^aDTgt;
1820 //
393598eb 1821 if (!FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt, aTolE)) {
505abfb8 1822 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx,
1823 aDN, theContext);
bb58e462 1824 aProjPL.Perform(aPx);
1825 aPx = aProjPL.NearestPoint();
1826 gp_Vec aVec(aP, aPx);
1827 aDB.SetXYZ(aVec.XYZ());
4e57c75e 1828 }
df017cc9 1829}
df017cc9 1830//=======================================================================
1831//function : FindPointInFace
1832//purpose : Find a point in the face in direction of <aDB>
1833//=======================================================================
f56518cd 1834Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
bb58e462 1835 const gp_Pnt& aP,
1836 gp_Dir& aDB,
1837 gp_Pnt& aPOut,
1e143abb 1838 Handle(IntTools_Context)& theContext,
f56518cd 1839 GeomAPI_ProjectPointOnSurf& aProjPL,
393598eb 1840 const Standard_Real aDt,
1841 const Standard_Real aTolE)
df017cc9 1842{
1843 Standard_Integer aNbItMax;
b9f6147d 1844 Standard_Real aDist, aDTol, aPM, anEps;
df017cc9 1845 Standard_Boolean bRet;
393598eb 1846 gp_Pnt aP1, aPS;
4e57c75e 1847 //
59495dbe 1848 aDTol = Precision::Angular();
1849 aPM = aP.XYZ().Modulus();
1850 if (aPM > 1000.) {
1851 aDTol = 5.e-16 * aPM;
1852 }
df017cc9 1853 bRet = Standard_False;
f56518cd 1854 aNbItMax = 15;
b9f6147d 1855 anEps = Precision::SquareConfusion();
4e57c75e 1856 //
df017cc9 1857 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
4e57c75e 1858 //
393598eb 1859 aPS=aP;
1860 aProj.Perform(aPS);
1861 if (!aProj.IsDone()) {
1862 return bRet;
1863 }
1864 aPS=aProj.NearestPoint();
1865 aProjPL.Perform(aPS);
1866 aPS=aProjPL.NearestPoint();
1867 //
1868 aPS.SetXYZ(aPS.XYZ()+2.*aTolE*aDB.XYZ());
b9f6147d 1869 aProj.Perform(aPS);
393598eb 1870 if (!aProj.IsDone()) {
1871 return bRet;
1872 }
1873 aPS=aProj.NearestPoint();
1874 aProjPL.Perform(aPS);
1875 aPS=aProjPL.NearestPoint();
1876 //
df017cc9 1877 do {
393598eb 1878 aP1.SetXYZ(aPS.XYZ()+aDt*aDB.XYZ());
df017cc9 1879 //
1880 aProj.Perform(aP1);
1881 if (!aProj.IsDone()) {
1882 return bRet;
1883 }
1884 aPOut = aProj.NearestPoint();
1885 aDist = aProj.LowerDistance();
1886 //
bb58e462 1887 aProjPL.Perform(aPOut);
1888 aPOut = aProjPL.NearestPoint();
1889 //
393598eb 1890 gp_Vec aV(aPS, aPOut);
b9f6147d 1891 if (aV.SquareMagnitude() < anEps) {
1892 return bRet;
1893 }
df017cc9 1894 aDB.SetXYZ(aV.XYZ());
59495dbe 1895 } while (aDist > aDTol && --aNbItMax);
4e57c75e 1896 //
59495dbe 1897 bRet = aDist < aDTol;
df017cc9 1898 return bRet;
4e57c75e 1899}
30ecd5f8 1900//=======================================================================
f56518cd 1901//function : MinStep3D
1902//purpose :
1903//=======================================================================
1904Standard_Real MinStep3D(const TopoDS_Edge& theE1,
1905 const TopoDS_Face& theF1,
1906 const BOPTools_ListOfCoupleOfShape& theLCS,
1907 const gp_Pnt& aP)
1908{
1909 Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin, aR;
1910 BOPTools_CoupleOfShape aCS1;
1911 BOPTools_ListOfCoupleOfShape aLCS;
1912 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1913 BRepAdaptor_Surface aBAS;
1914 //
1915 aLCS = theLCS;
1916 aCS1.SetShape1(theE1);
1917 aCS1.SetShape2(theF1);
1918 aLCS.Append(aCS1);
1919 //
1920 aTolE = BRep_Tool::Tolerance(theE1);
1921 aDtMax = -1.;
1922 aDtMin = 5.e-6;
1923 //
1924 aIt.Initialize(aLCS);
1925 for (; aIt.More(); aIt.Next()) {
1926 const BOPTools_CoupleOfShape& aCS = aIt.Value();
1927 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2()));
1928 //
1929 aTolF = BRep_Tool::Tolerance(aF);
1930 aDt = 2*(aTolE + aTolF);
1931 //
1932 aR = 0.;
1933 aBAS.Initialize(aF, Standard_False);
1934 GeomAbs_SurfaceType aSType = aBAS.GetType();
b9f6147d 1935 switch (aSType) {
1936 case GeomAbs_Cylinder: {
f56518cd 1937 aR = aBAS.Cylinder().Radius();
b9f6147d 1938 break;
f56518cd 1939 }
b9f6147d 1940 case GeomAbs_Cone: {
f56518cd 1941 gp_Lin aL(aBAS.Cone().Axis());
1942 aR = aL.Distance(aP);
b9f6147d 1943 break;
f56518cd 1944 }
b9f6147d 1945 case GeomAbs_Sphere: {
1946 aDtMin = Max(aDtMin, 5.e-4);
f56518cd 1947 aR = aBAS.Sphere().Radius();
b9f6147d 1948 break;
f56518cd 1949 }
b9f6147d 1950 case GeomAbs_Torus: {
f56518cd 1951 aR = aBAS.Torus().MajorRadius();
b9f6147d 1952 break;
f56518cd 1953 }
b9f6147d 1954 default:
1955 aDtMin = Max(aDtMin, 5.e-4);
1956 break;
f56518cd 1957 }
1958 //
1959 if (aR > 100.) {
b9f6147d 1960 Standard_Real d = 10*Precision::PConfusion();
1961 aDtMin = Max(aDtMin, sqrt(d*d + 2*d*aR));
f56518cd 1962 }
1963 //
1964 if (aDt > aDtMax) {
1965 aDtMax = aDt;
1966 }
1967 }
1968 //
1969 if (aDtMax < aDtMin) {
1970 aDtMax = aDtMin;
1971 }
1972 //
1973 return aDtMax;
1974}
1975//=======================================================================
30ecd5f8 1976//function : IsOpenShell
1977//purpose :
1978//=======================================================================
505abfb8 1979Standard_Boolean BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
30ecd5f8 1980{
1981 Standard_Boolean bRet;
1982 Standard_Integer i, aNbE, aNbF;
1983 TopAbs_Orientation aOrF;
1984 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
1985 BOPCol_ListIteratorOfListOfShape aItLS;
1986 //
1987 bRet=Standard_False;
1988 //
1989 BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF);
1990 //
1991 aNbE=aMEF.Extent();
1992 for (i=1; i<=aNbE; ++i) {
1993 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i));
1994 if (BRep_Tool::Degenerated(aE)) {
1995 continue;
1996 }
1997 //
1998 aNbF=0;
1999 const BOPCol_ListOfShape& aLF=aMEF(i);
2000 aItLS.Initialize(aLF);
2001 for (; aItLS.More(); aItLS.Next()) {
2002 const TopoDS_Shape& aF=aItLS.Value();
2003 aOrF=aF.Orientation();
2004 if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
505abfb8 2005 continue;
30ecd5f8 2006 }
2007 ++aNbF;
2008 }
2009 //
2010 if (aNbF==1) {
2011 bRet=!bRet; // True
2012 break;
2013 }
2014 }
2015 //
2016 return bRet;
2017}
2018//=======================================================================
2019//function : IsInvertedSolid
2020//purpose :
2021//=======================================================================
393598eb 2022Standard_Boolean BOPTools_AlgoTools::IsInvertedSolid
2023 (const TopoDS_Solid& aSolid)
30ecd5f8 2024{
2025 Standard_Real aTolS;
2026 TopAbs_State aState;
2027 BRepClass3d_SolidClassifier aSC(aSolid);
2028 //
2029 aTolS=1.e-7;
2030 aSC.PerformInfinitePoint(aTolS);
2031 aState=aSC.State();
2032 return (aState==TopAbs_IN);
2033}