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