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