0024002: Overall code and build procedure refactoring -- automatic
[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 {
236   Standard_Real aT, aT1, aT2;
237   
238   BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
239   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
240
241   BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
242
243   if (aF.Orientation()==TopAbs_REVERSED){
244     aDNF.Reverse();
245   }
246 }
247 //=======================================================================
248 //function : GetNormalToFaceOnEdge
249 //purpose  : 
250 //=======================================================================
251 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
252                                                   const TopoDS_Face& aF1,
253                                                   const Standard_Real aT, 
254                                                   gp_Dir& aDNF1)
255 {
256   Standard_Real U, V, aTolPC;
257   gp_Pnt2d aP2D;
258   gp_Pnt aP;
259   gp_Vec aD1U, aD1V;
260
261   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
262   
263   Handle(Geom2d_Curve)aC2D1;
264   BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC);
265
266   aC2D1->D0(aT, aP2D);
267   U=aP2D.X();
268   V=aP2D.Y();
269   
270   aS1->D1(U, V, aP, aD1U, aD1V);
271   gp_Dir aDD1U(aD1U); 
272   gp_Dir aDD1V(aD1V); 
273   
274   aDNF1=aDD1U^aDD1V; 
275 }
276 //=======================================================================
277 //function : SenseFlag
278 //purpose  :
279 //=======================================================================
280 Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
281                                                   const gp_Dir& aDNF2)
282 {
283   Standard_Boolean bIsDirsCoinside;
284   //
285   bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
286   if (!bIsDirsCoinside) {
287     return 0;
288   }
289   
290   Standard_Real aScPr;
291   
292   aScPr=aDNF1*aDNF2;
293   if (aScPr<0.) {
294     return -1;
295   }
296   else if (aScPr>0.) {
297     return 1;
298   }
299   return -1;
300 }
301 //=======================================================================
302 //function : GetNormalToSurface
303 //purpose  :
304 //=======================================================================
305 Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface
306   (const Handle(Geom_Surface)& aS,
307    const Standard_Real U,
308    const Standard_Real V,
309    gp_Dir& aDNS)
310 {
311   Standard_Boolean bFlag;
312   
313   gp_Pnt aP;
314   gp_Vec aD1U, aD1V;
315
316   aS->D1(U, V, aP, aD1U, aD1V);
317   
318   gp_Dir aDD1U(aD1U); 
319   gp_Dir aDD1V(aD1V); 
320   
321   bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
322   if (!bFlag) {
323     return bFlag;
324   }
325   
326   aDNS=aDD1U^aDD1V;
327   return bFlag;
328 }
329 //=======================================================================
330 //function : GetApproxNormalToFaceOnEdge
331 //purpose  : 
332 //=======================================================================
333 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
334   (const TopoDS_Edge& aE,
335    const TopoDS_Face& aF,
336    const Standard_Real aT,
337    gp_Pnt& aPNear,
338    gp_Dir& aDNF,
339    Standard_Real aDt2D)
340 {
341   Standard_Real aFirst, aLast;
342   Handle(Geom2d_Curve) aC2D= 
343     BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
344   
345   if (aC2D.IsNull()) {
346     return;
347   }
348   gp_Pnt2d aPx2DNear;
349   PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
350   Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
351   
352   BOPTools_AlgoTools3D::GetNormalToSurface 
353     (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
354   
355   if (aF.Orientation()==TopAbs_REVERSED){
356     aDNF.Reverse();
357   }
358 }
359 //=======================================================================
360 //function : GetApproxNormalToFaceOnEdge
361 //purpose  : 
362 //=======================================================================
363 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge 
364   (const TopoDS_Edge& aE,
365    const TopoDS_Face& aF,
366    const Standard_Real aT,
367    gp_Pnt& aPNear,
368    gp_Dir& aDNF,
369    Handle(IntTools_Context)& theContext)
370 {
371   Standard_Real aFirst, aLast;
372   Handle(Geom2d_Curve) aC2D= 
373     BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
374   
375   if (aC2D.IsNull()) {
376     return;
377   }
378   //gp_Pnt aPNear;
379   gp_Pnt2d aPx2DNear;
380   BOPTools_AlgoTools3D::PointNearEdge 
381     (aE, aF, aT, aPx2DNear, aPNear, theContext);
382   
383   Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
384   
385   BOPTools_AlgoTools3D::GetNormalToSurface 
386     (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
387   
388   if (aF.Orientation()==TopAbs_REVERSED){
389     aDNF.Reverse();
390   }
391 }
392 //=======================================================================
393 //function : PointNearEdge
394 //purpose  : 
395 //=======================================================================
396 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
397                                           const TopoDS_Face& aF,
398                                           const Standard_Real aT, 
399                                           const Standard_Real aDt2D, 
400                                           gp_Pnt2d& aPx2DNear,
401                                           gp_Pnt& aPxNear)
402 {
403   Standard_Real aFirst, aLast, aETol, aFTol, transVal;
404   GeomAbs_SurfaceType aTS;
405   Handle(Geom2d_Curve) aC2D;
406   Handle(Geom_Surface) aS;
407   //
408   aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
409   if (aC2D.IsNull()) {
410     aPx2DNear.SetCoord (99., 99);
411     return;
412   }
413   //
414   aS=BRep_Tool::Surface(aF);
415   //
416   gp_Pnt2d aPx2D;
417   gp_Vec2d aVx2D;
418   aC2D->D1 (aT, aPx2D, aVx2D);
419   gp_Dir2d aDx2D(aVx2D);
420   
421   gp_Dir2d aDP;
422   aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
423   
424   if (aE.Orientation()==TopAbs_REVERSED){
425     aDP.Reverse();
426   }
427
428   if (aF.Orientation()==TopAbs_REVERSED) {
429     aDP.Reverse();
430   }
431   //
432   aETol = BRep_Tool::Tolerance(aE);
433   aFTol = BRep_Tool::Tolerance(aF);
434   // NPAL19220
435   GeomAdaptor_Surface aGAS(aS);
436   aTS=aGAS.GetType();
437   if (aTS==GeomAbs_BSplineSurface) {
438     if (aETol > 1.e-5) {
439       aFTol=aETol;
440     }
441   }
442   if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
443     //
444     if(aTS!=GeomAbs_Sphere) {
445       gp_Vec2d transVec( aDP );
446       transVal = aDt2D + aETol + aFTol;
447       if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
448         Standard_Real aR, dT;
449         //
450         gp_Cylinder aCyl=aGAS.Cylinder();
451         aR=aCyl.Radius();
452         dT=1.-transVal/aR;
453         if (dT>=-1 && dT<=1) {
454           dT=acos(dT);
455           transVal=dT;
456         }
457       }
458       //
459       transVec.Multiply(transVal);
460       aPx2DNear = aPx2D.Translated( transVec );
461     }
462     else {
463       aPx2DNear.SetCoord 
464         (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
465     }
466   }
467   else {
468     aPx2DNear.SetCoord 
469       (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
470   }
471   //
472   aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
473 }
474 //=======================================================================
475 //function : PointNearEdge
476 //purpose  : 
477 //=======================================================================
478 void BOPTools_AlgoTools3D::PointNearEdge 
479   (const TopoDS_Edge& aE,
480    const TopoDS_Face& aF,
481    const Standard_Real aT, 
482    gp_Pnt2d& aPx2DNear,
483    gp_Pnt& aPxNear,
484    Handle(IntTools_Context)& theContext)
485 {
486   Standard_Real aTolE, aTolF, dTx, dT2D;
487   Handle(Geom_Surface) aS;
488   GeomAdaptor_Surface aGAS;
489   //
490   dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5;
491   //
492   aS = BRep_Tool::Surface(aF);
493   aGAS.Load(aS);
494   if (aGAS.GetType()==GeomAbs_Cylinder ||
495       aGAS.GetType()==GeomAbs_Sphere) {
496     dT2D=10.*dT2D;
497   } 
498   //
499   aTolE = BRep_Tool::Tolerance(aE);
500   aTolF = BRep_Tool::Tolerance(aF);
501   dTx = 2.*(aTolE + aTolF);
502   if (dTx > dT2D) {
503     dT2D=dTx;
504   }
505   //
506   BOPTools_AlgoTools3D::PointNearEdge 
507     (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
508   if (!theContext->IsPointInOnFace(aF, aPx2DNear)) {
509     Standard_Integer iErr;
510     Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh;
511     gp_Pnt aP;
512     gp_Pnt2d aP2d;
513     //
514     BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
515     // 
516     dU=aU2-aU1;
517     dV=aV2-aV1;
518     //
519     dTresh=1.e-4;
520     if (dT2D > dTresh) {
521       dTresh=dT2D;
522     }
523     //
524     if (dU < dTresh || dV < dTresh) {
525       iErr = BOPTools_AlgoTools3D::PointInFace
526         (aF, aP, aP2d, theContext);
527       if (!iErr) {
528         aPxNear = aP;
529         aPx2DNear = aP2d;
530       }
531     }
532   }
533 }
534 //=======================================================================
535 // function: PointNearEdge
536 // purpose: 
537 //=======================================================================
538 void  BOPTools_AlgoTools3D::PointNearEdge 
539   (const TopoDS_Edge& aE,
540    const TopoDS_Face& aF, 
541    gp_Pnt2d& aPInFace2D, 
542    gp_Pnt& aPInFace,
543    Handle(IntTools_Context)& theContext)
544 {
545   Standard_Real aT, aT1, aT2;
546   //
547   // 1. 
548   BRep_Tool::Range(aE, aT1, aT2);
549   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
550   //
551   // 2. a Point inside Face near aPOnEdge aPInFace;
552   TopoDS_Face aFF=aF;
553   TopoDS_Edge aERight;
554   aFF.Orientation(TopAbs_FORWARD);
555   BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
556   
557   BOPTools_AlgoTools3D::PointNearEdge 
558     (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
559 }
560 //=======================================================================
561 //function : MinStepIn2d
562 //purpose  : 
563 //=======================================================================
564 Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
565 {
566   Standard_Real dt=1.e-5;
567   return dt;
568
569 //=======================================================================
570 //function : IsEmptyShape
571 //purpose  : 
572 //=======================================================================
573 Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape
574   (const TopoDS_Shape& aS)
575 {
576   Standard_Boolean bHasGeometry=Standard_False;
577   //
578   BOPCol_IndexedMapOfShape myShapes;
579   //
580   Add(aS, myShapes, bHasGeometry);
581
582   return !bHasGeometry;
583 }
584 //=======================================================================
585 //function : Add
586 //purpose  : 
587 //=======================================================================
588 void Add(const TopoDS_Shape& aS,
589          BOPCol_IndexedMapOfShape& myShapes, 
590          Standard_Boolean& bHasGeometry)
591 {
592   Standard_Integer anIndex; 
593   //
594   if (bHasGeometry) {
595     return;
596   }
597   //
598   if (aS.IsNull()) {
599     return;
600   }
601   //
602   TopoDS_Shape aSx = aS;
603   //
604   anIndex=myShapes.FindIndex(aSx);
605   if (!anIndex) {
606     bHasGeometry=HasGeometry (aSx);
607     if (bHasGeometry) {
608       return;
609     }
610     //
611     TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
612     for(; anIt.More(); anIt.Next()) {
613       const TopoDS_Shape& aSy=anIt.Value();
614       Add(aSy, myShapes, bHasGeometry);
615       //
616       if (bHasGeometry) {
617         return;
618       }
619       //
620       myShapes.Add(aSx);
621     }
622   }
623 }
624 //=======================================================================
625 //function : HasGeometry
626 //purpose  : 
627 //=======================================================================
628 Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
629 {
630   Standard_Boolean bHasGeometry=Standard_True;
631   TopAbs_ShapeEnum aType= aS.ShapeType();
632
633   if (aType == TopAbs_VERTEX) {
634     return bHasGeometry;
635   }
636   //
637   else if (aType == TopAbs_EDGE) {
638     Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
639     BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
640
641     while (itrc.More()) {
642       const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
643       if (CR->IsCurve3D()) {
644         if (!CR->Curve3D().IsNull()) {
645           return bHasGeometry;
646         }
647       }
648       else if (CR->IsCurveOnSurface()) {
649         return bHasGeometry;
650       }
651       else if (CR->IsRegularity()) {
652         return bHasGeometry;
653       }
654       else if (!CR->Polygon3D().IsNull()) {
655         return bHasGeometry;
656       }
657       else if (CR->IsPolygonOnTriangulation()) {
658         return bHasGeometry;
659       }
660       else if (CR->IsPolygonOnSurface()) {
661         return bHasGeometry;
662       }
663       itrc.Next();
664     }
665   }
666   //
667   else if (aType == TopAbs_FACE) {
668     Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
669     if (!TF->Surface().IsNull())  {
670       return bHasGeometry;
671     }
672     Handle(Poly_Triangulation) Tr = TF->Triangulation();
673     if (!Tr.IsNull()) {
674       return bHasGeometry;
675     }
676   }
677   
678   return !bHasGeometry;
679 }
680 //=======================================================================
681 //function : OrientEdgeOnFace
682 //purpose  : 
683 //=======================================================================
684 void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
685                                              const TopoDS_Face& aF,
686                                              TopoDS_Edge& aERight)
687 {
688   if (BRep_Tool::IsClosed(aE, aF)) {
689     aERight=aE;
690     aERight.Orientation(aE.Orientation());
691
692     Standard_Integer iFoundCount = 0;
693     TopoDS_Edge anEdge = aE;
694     TopExp_Explorer anExp(aF, TopAbs_EDGE);
695
696     for (; anExp.More(); anExp.Next()) {
697       const TopoDS_Shape& aSS=anExp.Current();
698       
699       if (aSS.IsSame(aE)) {
700         anEdge = TopoDS::Edge(aSS);
701         iFoundCount++;
702       }
703     }
704     
705     if(iFoundCount == 1) {
706       aERight = anEdge;
707     }
708     return;
709   }
710   
711   TopExp_Explorer anExp(aF, TopAbs_EDGE);
712   for (; anExp.More(); anExp.Next()) {
713     const TopoDS_Shape& aSS=anExp.Current();
714     if (aSS.IsSame(aE)) {
715       aERight=aE;
716       aERight.Orientation(aSS.Orientation());
717       return;
718     }
719   }
720   aERight=aE;
721   aERight.Orientation(aE.Orientation());
722 }
723 //=======================================================================
724 //function : PointInFace
725 //purpose  :
726 //=======================================================================
727 Standard_Integer BOPTools_AlgoTools3D::PointInFace
728   (const TopoDS_Face& aF,
729    gp_Pnt& theP,
730    gp_Pnt2d& theP2D,
731    Handle(IntTools_Context)& theContext)
732 {
733   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
734   Standard_Integer iErr, aIx = 0, aNbDomains = 0;
735   Standard_Real aUMin, aUMax, aVMin, aVMax;
736   Standard_Real aVx = 0., aUx, aV1, aV2;
737   gp_Dir2d aD2D (0., 1.);
738   gp_Pnt2d aP2D;
739   gp_Pnt aPx;
740   Handle(Geom2d_Curve) aC2D;
741   Handle(Geom2d_Line) aL2D;
742   Handle(Geom_Surface) aS;
743   TopoDS_Face aFF;
744   //
745   Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF);
746   //
747   iErr=0;
748   //
749   aFF=aF;
750   aFF.Orientation (TopAbs_FORWARD);
751   //
752   aS=BRep_Tool::Surface(aFF);
753   BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
754   //
755   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
756   Standard_Integer i;
757   for(i = 1; i <= 2; ++i)
758   {
759     aP2D.SetCoord(aUx, 0.);
760     aL2D=new Geom2d_Line (aP2D, aD2D);
761     Geom2dAdaptor_Curve aHCur(aL2D);
762     //
763     aIx=aHatcher.AddHatching(aHCur) ;
764     //
765     aHatcher.Trim(aIx);
766     bIsDone=aHatcher.TrimDone(aIx);
767     if (!bIsDone) {
768       iErr=1;
769       return iErr;
770     }
771     //
772     if(aHatcher.NbPoints(aIx) > 1)
773     {
774       aHatcher.ComputeDomains(aIx);
775       bIsDone=aHatcher.IsDone(aIx);
776       if (!bIsDone) {
777         iErr=2;
778         return iErr;
779       }
780       break;
781     }
782     else
783     {
784       aUx = aUMax - (aUx - aUMin);
785     }
786   }
787   //
788   if(!aHatcher.IsDone(aIx))
789   {
790     iErr=2;
791     return iErr;
792   }
793
794   aNbDomains=aHatcher.NbDomains(aIx);
795   if (aNbDomains > 0) {
796     const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1);
797     bHasFirstPoint=aDomain.HasFirstPoint();
798     if (!bHasFirstPoint) {
799       iErr=3;
800       return iErr;
801     }
802     //
803     aV1=aDomain.FirstPoint().Parameter();
804     //
805     bHasSecondPoint=aDomain.HasSecondPoint();
806     if (!bHasSecondPoint) {
807       iErr=4;
808       return iErr;
809     }
810     //
811     aV2=aDomain.SecondPoint().Parameter();
812     //
813     aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
814     //
815   }
816   else {
817     iErr=2;
818     return iErr;
819   }
820   //
821   aS->D0(aUx, aVx, aPx);
822   //
823   theP2D.SetCoord(aUx, aVx);
824   theP=aPx;
825   //
826   return iErr;
827 }