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