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