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