Warnings on vc14 were eliminated
[occt.git] / src / BOPTools / BOPTools_AlgoTools3D.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Bnd_Box.hxx>
17 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
18 #include <BOPCol_IndexedMapOfShape.hxx>
19 #include <BOPTools_AlgoTools2D.hxx>
20 #include <BOPTools_AlgoTools3D.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRep_CurveRepresentation.hxx>
23 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
24 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
25 #include <BRep_PointRepresentation.hxx>
26 #include <BRep_TEdge.hxx>
27 #include <BRep_TFace.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRep_TVertex.hxx>
30 #include <BRepAdaptor_Surface.hxx>
31 #include <BRepBndLib.hxx>
32 #include <BRepGProp.hxx>
33 #include <BRepTools.hxx>
34 #include <Geom2d_Curve.hxx>
35 #include <Geom2d_Line.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom2dAdaptor_Curve.hxx>
38 #include <Geom2dHatch_Hatcher.hxx>
39 #include <Geom_BezierSurface.hxx>
40 #include <Geom_BSplineSurface.hxx>
41 #include <Geom_Curve.hxx>
42 #include <Geom_RectangularTrimmedSurface.hxx>
43 #include <Geom_Surface.hxx>
44 #include <GeomAdaptor_Surface.hxx>
45 #include <gp_Cylinder.hxx>
46 #include <gp_Dir.hxx>
47 #include <gp_Dir2d.hxx>
48 #include <gp_Lin2d.hxx>
49 #include <gp_Pln.hxx>
50 #include <gp_Pnt.hxx>
51 #include <gp_Pnt2d.hxx>
52 #include <gp_Vec.hxx>
53 #include <gp_Vec2d.hxx>
54 #include <GProp_GProps.hxx>
55 #include <HatchGen_Domain.hxx>
56 #include <IntTools_Context.hxx>
57 #include <IntTools_Tools.hxx>
58 #include <Poly_Triangulation.hxx>
59 #include <TopExp.hxx>
60 #include <TopExp_Explorer.hxx>
61 #include <TopoDS.hxx>
62 #include <TopoDS_Edge.hxx>
63 #include <TopoDS_Face.hxx>
64 #include <TopoDS_Shape.hxx>
65 #include <TopoDS_Vertex.hxx>
66
67 static void Add(const TopoDS_Shape& aS,
68                 BOPCol_IndexedMapOfShape& myShapes, 
69                 Standard_Boolean& bHasGeometry);
70 static 
71   Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
72
73 //=======================================================================
74 //function : DoSplitSEAMOnFace
75 //purpose  : 
76 //=======================================================================
77 void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
78                                               const TopoDS_Face& aF)
79 {
80   Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
81   Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU, anU1;
82   Standard_Real aScPr, anV, dV, anV1;
83   Standard_Real aUmin, aUmax, aVmin, aVmax;
84   gp_Pnt2d aP2D;
85   gp_Vec2d aVec2D;
86   Handle(Geom2d_Curve) aTmpC1, aTmpC2;
87   Handle(Geom2d_Curve) C2D1;
88   Handle(Geom2d_Line) aLD1;
89   Handle(Geom_Surface) aS;
90   BRep_Builder BB;
91   TopoDS_Edge aSp;
92   //
93   bIsLeft = Standard_False;
94   aSp=aSplit;
95   aSp.Orientation(TopAbs_FORWARD);
96   aTol=BRep_Tool::Tolerance(aSp);
97   //
98   aS=BRep_Tool::Surface(aF);
99   //
100   aS->Bounds(aUmin, aUmax, aVmin, aVmax);
101   //
102   bIsUPeriodic=aS->IsUPeriodic();
103   bIsVPeriodic=aS->IsVPeriodic();
104   //
105   anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
106   anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
107   //
108   if (!bIsUPeriodic && !bIsVPeriodic) {
109     Standard_Boolean bIsUClosed, bIsVClosed;
110     Handle(Geom_BSplineSurface) aBS;
111     Handle(Geom_BezierSurface) aBZ;
112     Handle(Geom_RectangularTrimmedSurface) aRTS;
113     //
114     bIsUClosed=Standard_False;
115     bIsVClosed=Standard_False;
116     aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
117     aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
118     aRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
119     //
120     if (!aBS.IsNull()) {
121       bIsUClosed=aBS->IsUClosed();
122       bIsVClosed=aBS->IsVClosed();
123     }
124     else if (!aBZ.IsNull()) {
125       bIsUClosed=aBZ->IsUClosed();
126       bIsVClosed=aBZ->IsVClosed();
127     }
128     else if (!aRTS.IsNull()) {
129       Handle(Geom_Surface) aSB;
130       //
131       aSB=aRTS->BasisSurface();
132       bIsUPeriodic=aSB->IsUPeriodic();
133       bIsVPeriodic=aSB->IsVPeriodic();
134       //
135       if (!(bIsUPeriodic || bIsVPeriodic)) {
136         return;
137       }
138       anUPeriod = bIsUPeriodic ? aSB->UPeriod() : 0.;
139       anVPeriod = bIsVPeriodic ? aSB->VPeriod() : 0.;
140     }
141     //
142     if (aRTS.IsNull()) {
143       if (!bIsUClosed && !bIsVClosed) {
144         return;
145       }
146       //
147       if (bIsUClosed) {
148         anUPeriod=aUmax-aUmin;
149       }
150       if (bIsVClosed) {
151         anVPeriod=aVmax-aVmin;
152       }
153     }
154   }
155   //
156   //---------------------------------------------------
157   C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
158   //
159   aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
160   C2D1->D1(aT, aP2D, aVec2D);
161   gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
162   //
163   anU=aP2D.X();
164   anV=aP2D.Y();
165   //
166   anU1=anU;
167   anV1=anV;
168   //
169   GeomAdaptor_Surface aGAS(aS);
170   dU = aGAS.UResolution(aTol);
171   dV = aGAS.VResolution(aTol);
172   //
173   if (anUPeriod > 0.){
174     if (fabs (anU-aUmin) < dU) {
175       bIsLeft=Standard_True;
176       anU1=anU+anUPeriod;
177     }
178     else if (fabs (anU-aUmax) < dU) {
179       bIsLeft=Standard_False;
180       anU1=anU-anUPeriod;
181     }
182   }
183   //
184   if (anVPeriod > 0.) {
185     if (fabs (anV-aVmin) < dV) {
186       bIsLeft=Standard_True;
187       anV1=anV+anVPeriod;
188     }
189     else if (fabs (anV-aVmax) < dV) {
190       bIsLeft=Standard_False;
191       anV1=anV-anVPeriod;
192     }
193   }
194   //
195   if (anU1==anU && anV1==anV) {
196     return;
197   }
198   //
199   aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
200   //
201   aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
202   Handle(Geom2d_TrimmedCurve) aC1 = 
203     new Geom2d_TrimmedCurve(aTmpC1, a, b);
204   //
205   aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
206   Handle(Geom2d_TrimmedCurve) aC2 = 
207     new Geom2d_TrimmedCurve(aTmpC2, a, b);
208   gp_Vec2d aTrV(anU1-anU, anV1-anV);
209   aC2->Translate(aTrV);
210   //
211   if (!bIsLeft) {
212     if (aScPr<0.) {
213       BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
214     }
215     else {
216       BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
217     }
218   }
219   else {
220     if (aScPr<0.) {
221       BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
222     }
223     else {
224       BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
225     }
226   }
227 }
228 //=======================================================================
229 //function : GetNormalToFaceOnEdge
230 //purpose  : 
231 //=======================================================================
232 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
233                                                   const TopoDS_Face& aF,
234                                                   gp_Dir& aDNF,
235                                                   const Handle(IntTools_Context)& theContext)
236 {
237   Standard_Real aT, aT1, aT2;
238   
239   BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
240   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
241
242   BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF, theContext);
243
244   if (aF.Orientation()==TopAbs_REVERSED){
245     aDNF.Reverse();
246   }
247 }
248 //=======================================================================
249 //function : GetNormalToFaceOnEdge
250 //purpose  : 
251 //=======================================================================
252 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
253                                                   const TopoDS_Face& aF1,
254                                                   const Standard_Real aT, 
255                                                   gp_Dir& aDNF1,
256                                                   const Handle(IntTools_Context)& theContext)
257 {
258   Standard_Real U, V, aTolPC;
259   gp_Pnt2d aP2D;
260   gp_Pnt aP;
261   gp_Vec aD1U, aD1V;
262
263   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
264   
265   Handle(Geom2d_Curve)aC2D1;
266   BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC, theContext);
267
268   aC2D1->D0(aT, aP2D);
269   U=aP2D.X();
270   V=aP2D.Y();
271   
272   aS1->D1(U, V, aP, aD1U, aD1V);
273   gp_Dir aDD1U(aD1U); 
274   gp_Dir aDD1V(aD1V); 
275   
276   aDNF1=aDD1U^aDD1V; 
277 }
278 //=======================================================================
279 //function : SenseFlag
280 //purpose  :
281 //=======================================================================
282 Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
283                                                   const gp_Dir& aDNF2)
284 {
285   Standard_Boolean bIsDirsCoinside;
286   //
287   bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
288   if (!bIsDirsCoinside) {
289     return 0;
290   }
291   
292   Standard_Real aScPr;
293   
294   aScPr=aDNF1*aDNF2;
295   if (aScPr<0.) {
296     return -1;
297   }
298   else if (aScPr>0.) {
299     return 1;
300   }
301   return -1;
302 }
303 //=======================================================================
304 //function : GetNormalToSurface
305 //purpose  :
306 //=======================================================================
307 Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface
308   (const Handle(Geom_Surface)& aS,
309    const Standard_Real U,
310    const Standard_Real V,
311    gp_Dir& aDNS)
312 {
313   Standard_Boolean bFlag;
314   
315   gp_Pnt aP;
316   gp_Vec aD1U, aD1V;
317
318   aS->D1(U, V, aP, aD1U, aD1V);
319   
320   gp_Dir aDD1U(aD1U); 
321   gp_Dir aDD1V(aD1V); 
322   
323   bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
324   if (!bFlag) {
325     return bFlag;
326   }
327   
328   aDNS=aDD1U^aDD1V;
329   return bFlag;
330 }
331 //=======================================================================
332 //function : GetApproxNormalToFaceOnEdge
333 //purpose  : 
334 //=======================================================================
335 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
336   (const TopoDS_Edge& aE,
337    const TopoDS_Face& aF,
338    const Standard_Real aT,
339    gp_Pnt& aPNear,
340    gp_Dir& aDNF,
341    Standard_Real aDt2D)
342 {
343   Standard_Real aFirst, aLast;
344   Handle(Geom2d_Curve) aC2D= 
345     BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
346   
347   if (aC2D.IsNull()) {
348     return;
349   }
350   gp_Pnt2d aPx2DNear;
351   PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
352   Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
353   
354   BOPTools_AlgoTools3D::GetNormalToSurface 
355     (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
356   
357   if (aF.Orientation()==TopAbs_REVERSED){
358     aDNF.Reverse();
359   }
360 }
361 //=======================================================================
362 //function : GetApproxNormalToFaceOnEdge
363 //purpose  : 
364 //=======================================================================
365 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge 
366   (const TopoDS_Edge& aE,
367    const TopoDS_Face& aF,
368    const Standard_Real aT,
369    gp_Pnt& aPNear,
370    gp_Dir& aDNF,
371    Handle(IntTools_Context)& theContext)
372 {
373   Standard_Real aFirst, aLast;
374   Handle(Geom2d_Curve) aC2D= 
375     BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
376   
377   if (aC2D.IsNull()) {
378     return;
379   }
380   //gp_Pnt aPNear;
381   gp_Pnt2d aPx2DNear;
382   BOPTools_AlgoTools3D::PointNearEdge 
383     (aE, aF, aT, aPx2DNear, aPNear, theContext);
384   
385   Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
386   
387   BOPTools_AlgoTools3D::GetNormalToSurface 
388     (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
389   
390   if (aF.Orientation()==TopAbs_REVERSED){
391     aDNF.Reverse();
392   }
393 }
394 //=======================================================================
395 //function : PointNearEdge
396 //purpose  : 
397 //=======================================================================
398 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
399                                           const TopoDS_Face& aF,
400                                           const Standard_Real aT, 
401                                           const Standard_Real aDt2D, 
402                                           gp_Pnt2d& aPx2DNear,
403                                           gp_Pnt& aPxNear)
404 {
405   Standard_Real aFirst, aLast, aETol, aFTol, transVal;
406   GeomAbs_SurfaceType aTS;
407   Handle(Geom2d_Curve) aC2D;
408   Handle(Geom_Surface) aS;
409   //
410   aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
411   if (aC2D.IsNull()) {
412     aPx2DNear.SetCoord (99., 99);
413     return;
414   }
415   //
416   aS=BRep_Tool::Surface(aF);
417   //
418   gp_Pnt2d aPx2D;
419   gp_Vec2d aVx2D;
420   aC2D->D1 (aT, aPx2D, aVx2D);
421   gp_Dir2d aDx2D(aVx2D);
422   
423   gp_Dir2d aDP;
424   aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
425   
426   if (aE.Orientation()==TopAbs_REVERSED){
427     aDP.Reverse();
428   }
429
430   if (aF.Orientation()==TopAbs_REVERSED) {
431     aDP.Reverse();
432   }
433   //
434   aETol = BRep_Tool::Tolerance(aE);
435   aFTol = BRep_Tool::Tolerance(aF);
436   // NPAL19220
437   GeomAdaptor_Surface aGAS(aS);
438   aTS=aGAS.GetType();
439   if (aTS==GeomAbs_BSplineSurface) {
440     if (aETol > 1.e-5) {
441       aFTol=aETol;
442     }
443   }
444   if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
445     //
446     if(aTS!=GeomAbs_Sphere) {
447       gp_Vec2d transVec( aDP );
448       transVal = aDt2D + aETol + aFTol;
449       if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
450         Standard_Real aR, dT;
451         //
452         gp_Cylinder aCyl=aGAS.Cylinder();
453         aR=aCyl.Radius();
454         dT=1.-transVal/aR;
455         if (dT>=-1 && dT<=1) {
456           dT=acos(dT);
457           transVal=dT;
458         }
459       }
460       //
461       transVec.Multiply(transVal);
462       aPx2DNear = aPx2D.Translated( transVec );
463     }
464     else {
465       aPx2DNear.SetCoord 
466         (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
467     }
468   }
469   else {
470     aPx2DNear.SetCoord 
471       (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
472   }
473   //
474   aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
475 }
476 //=======================================================================
477 //function : PointNearEdge
478 //purpose  : 
479 //=======================================================================
480 void BOPTools_AlgoTools3D::PointNearEdge 
481   (const TopoDS_Edge& aE,
482    const TopoDS_Face& aF,
483    const Standard_Real aT, 
484    gp_Pnt2d& aPx2DNear,
485    gp_Pnt& aPxNear,
486    Handle(IntTools_Context)& theContext)
487 {
488   Standard_Real aTolE, aTolF, dTx, dT2D;
489   Handle(Geom_Surface) aS;
490   GeomAdaptor_Surface aGAS;
491   //
492   dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5;
493   //
494   aS = BRep_Tool::Surface(aF);
495   aGAS.Load(aS);
496   if (aGAS.GetType()==GeomAbs_Cylinder ||
497       aGAS.GetType()==GeomAbs_Sphere) {
498     dT2D=10.*dT2D;
499   } 
500   //
501   aTolE = BRep_Tool::Tolerance(aE);
502   aTolF = BRep_Tool::Tolerance(aF);
503   dTx = 2.*(aTolE + aTolF);
504   if (dTx > dT2D) {
505     dT2D=dTx;
506   }
507   //
508   BOPTools_AlgoTools3D::PointNearEdge 
509     (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
510   if (!theContext->IsPointInOnFace(aF, aPx2DNear)) {
511     Standard_Integer iErr;
512     Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh;
513     gp_Pnt aP;
514     gp_Pnt2d aP2d;
515     //
516     if (theContext.IsNull()) {
517       BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
518     }
519     else {
520       theContext->UVBounds(aF, aU1, aU2, aV1, aV2);
521     }
522     // 
523     dU=aU2-aU1;
524     dV=aV2-aV1;
525     //
526     dTresh=1.e-4;
527     if (dT2D > dTresh) {
528       dTresh=dT2D;
529     }
530     //
531     if (dU < dTresh || dV < dTresh) {
532       iErr = BOPTools_AlgoTools3D::PointInFace
533         (aF, aP, aP2d, theContext);
534       if (!iErr) {
535         aPxNear = aP;
536         aPx2DNear = aP2d;
537       }
538     }
539   }
540 }
541 //=======================================================================
542 // function: PointNearEdge
543 // purpose: 
544 //=======================================================================
545 void  BOPTools_AlgoTools3D::PointNearEdge 
546   (const TopoDS_Edge& aE,
547    const TopoDS_Face& aF, 
548    gp_Pnt2d& aPInFace2D, 
549    gp_Pnt& aPInFace,
550    Handle(IntTools_Context)& theContext)
551 {
552   Standard_Real aT, aT1, aT2;
553   //
554   // 1. 
555   BRep_Tool::Range(aE, aT1, aT2);
556   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
557   //
558   // 2. a Point inside Face near aPOnEdge aPInFace;
559   TopoDS_Face aFF=aF;
560   TopoDS_Edge aERight;
561   aFF.Orientation(TopAbs_FORWARD);
562   BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
563   
564   BOPTools_AlgoTools3D::PointNearEdge 
565     (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
566 }
567 //=======================================================================
568 //function : MinStepIn2d
569 //purpose  : 
570 //=======================================================================
571 Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
572 {
573   Standard_Real dt=1.e-5;
574   return dt;
575
576 //=======================================================================
577 //function : IsEmptyShape
578 //purpose  : 
579 //=======================================================================
580 Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape
581   (const TopoDS_Shape& aS)
582 {
583   Standard_Boolean bHasGeometry=Standard_False;
584   //
585   BOPCol_IndexedMapOfShape myShapes;
586   //
587   Add(aS, myShapes, bHasGeometry);
588
589   return !bHasGeometry;
590 }
591 //=======================================================================
592 //function : Add
593 //purpose  : 
594 //=======================================================================
595 void Add(const TopoDS_Shape& aS,
596          BOPCol_IndexedMapOfShape& myShapes, 
597          Standard_Boolean& bHasGeometry)
598 {
599   Standard_Integer anIndex; 
600   //
601   if (bHasGeometry) {
602     return;
603   }
604   //
605   if (aS.IsNull()) {
606     return;
607   }
608   //
609   TopoDS_Shape aSx = aS;
610   //
611   anIndex=myShapes.FindIndex(aSx);
612   if (!anIndex) {
613     bHasGeometry=HasGeometry (aSx);
614     if (bHasGeometry) {
615       return;
616     }
617     //
618     TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
619     for(; anIt.More(); anIt.Next()) {
620       const TopoDS_Shape& aSy=anIt.Value();
621       Add(aSy, myShapes, bHasGeometry);
622       //
623       if (bHasGeometry) {
624         return;
625       }
626       //
627       myShapes.Add(aSx);
628     }
629   }
630 }
631 //=======================================================================
632 //function : HasGeometry
633 //purpose  : 
634 //=======================================================================
635 Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
636 {
637   Standard_Boolean bHasGeometry=Standard_True;
638   TopAbs_ShapeEnum aType= aS.ShapeType();
639
640   if (aType == TopAbs_VERTEX) {
641     return bHasGeometry;
642   }
643   //
644   else if (aType == TopAbs_EDGE) {
645     Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
646     BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
647
648     while (itrc.More()) {
649       const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
650       if (CR->IsCurve3D()) {
651         if (!CR->Curve3D().IsNull()) {
652           return bHasGeometry;
653         }
654       }
655       else if (CR->IsCurveOnSurface()) {
656         return bHasGeometry;
657       }
658       else if (CR->IsRegularity()) {
659         return bHasGeometry;
660       }
661       else if (!CR->Polygon3D().IsNull()) {
662         return bHasGeometry;
663       }
664       else if (CR->IsPolygonOnTriangulation()) {
665         return bHasGeometry;
666       }
667       else if (CR->IsPolygonOnSurface()) {
668         return bHasGeometry;
669       }
670       itrc.Next();
671     }
672   }
673   //
674   else if (aType == TopAbs_FACE) {
675     Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
676     if (!TF->Surface().IsNull())  {
677       return bHasGeometry;
678     }
679     Handle(Poly_Triangulation) Tr = TF->Triangulation();
680     if (!Tr.IsNull()) {
681       return bHasGeometry;
682     }
683   }
684   
685   return !bHasGeometry;
686 }
687 //=======================================================================
688 //function : OrientEdgeOnFace
689 //purpose  : 
690 //=======================================================================
691 void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
692                                              const TopoDS_Face& aF,
693                                              TopoDS_Edge& aERight)
694 {
695   if (BRep_Tool::IsClosed(aE, aF)) {
696     aERight=aE;
697     aERight.Orientation(aE.Orientation());
698
699     Standard_Integer iFoundCount = 0;
700     TopoDS_Edge anEdge = aE;
701     TopExp_Explorer anExp(aF, TopAbs_EDGE);
702
703     for (; anExp.More(); anExp.Next()) {
704       const TopoDS_Shape& aSS=anExp.Current();
705       
706       if (aSS.IsSame(aE)) {
707         anEdge = TopoDS::Edge(aSS);
708         iFoundCount++;
709       }
710     }
711     
712     if(iFoundCount == 1) {
713       aERight = anEdge;
714     }
715     return;
716   }
717   
718   TopExp_Explorer anExp(aF, TopAbs_EDGE);
719   for (; anExp.More(); anExp.Next()) {
720     const TopoDS_Shape& aSS=anExp.Current();
721     if (aSS.IsSame(aE)) {
722       aERight=aE;
723       aERight.Orientation(aSS.Orientation());
724       return;
725     }
726   }
727   aERight=aE;
728   aERight.Orientation(aE.Orientation());
729 }
730 //=======================================================================
731 //function : PointInFace
732 //purpose  :
733 //=======================================================================
734 Standard_Integer BOPTools_AlgoTools3D::PointInFace
735   (const TopoDS_Face& aF,
736    gp_Pnt& theP,
737    gp_Pnt2d& theP2D,
738    Handle(IntTools_Context)& theContext)
739 {
740   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
741   Standard_Integer iErr, aIx = 0, aNbDomains = 0;
742   Standard_Real aUMin, aUMax, aVMin, aVMax;
743   Standard_Real aVx = 0., aUx, aV1, aV2;
744   gp_Dir2d aD2D (0., 1.);
745   gp_Pnt2d aP2D;
746   gp_Pnt aPx;
747   Handle(Geom2d_Curve) aC2D;
748   Handle(Geom2d_Line) aL2D;
749   Handle(Geom_Surface) aS;
750   TopoDS_Face aFF;
751   //
752   Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF);
753   //
754   iErr=0;
755   //
756   aFF=aF;
757   aFF.Orientation (TopAbs_FORWARD);
758   //
759   aS=BRep_Tool::Surface(aFF);
760   if (theContext.IsNull()) {
761     BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
762   }
763   else {
764     theContext->UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
765   }
766   //
767   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
768   Standard_Integer i;
769   for(i = 1; i <= 2; ++i)
770   {
771     aP2D.SetCoord(aUx, 0.);
772     aL2D=new Geom2d_Line (aP2D, aD2D);
773     Geom2dAdaptor_Curve aHCur(aL2D);
774     //
775     aIx=aHatcher.AddHatching(aHCur) ;
776     //
777     aHatcher.Trim(aIx);
778     bIsDone=aHatcher.TrimDone(aIx);
779     if (!bIsDone) {
780       iErr=1;
781       return iErr;
782     }
783     //
784     if(aHatcher.NbPoints(aIx) > 1)
785     {
786       aHatcher.ComputeDomains(aIx);
787       bIsDone=aHatcher.IsDone(aIx);
788       if (!bIsDone) {
789         iErr=2;
790         return iErr;
791       }
792       break;
793     }
794     else
795     {
796       aUx = aUMax - (aUx - aUMin);
797     }
798   }
799   //
800   if(!aHatcher.IsDone(aIx))
801   {
802     iErr=2;
803     return iErr;
804   }
805
806   aNbDomains=aHatcher.NbDomains(aIx);
807   if (aNbDomains > 0) {
808     const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1);
809     bHasFirstPoint=aDomain.HasFirstPoint();
810     if (!bHasFirstPoint) {
811       iErr=3;
812       return iErr;
813     }
814     //
815     aV1=aDomain.FirstPoint().Parameter();
816     //
817     bHasSecondPoint=aDomain.HasSecondPoint();
818     if (!bHasSecondPoint) {
819       iErr=4;
820       return iErr;
821     }
822     //
823     aV2=aDomain.SecondPoint().Parameter();
824     //
825     aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
826     //
827   }
828   else {
829     iErr=2;
830     return iErr;
831   }
832   //
833   aS->D0(aUx, aVx, aPx);
834   //
835   theP2D.SetCoord(aUx, aVx);
836   theP=aPx;
837   //
838   return iErr;
839 }