]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMAlgo/GEOMAlgo_Tools3D.cxx
Salome HOME
Win32 compliation.
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Tools3D.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 //  File    : GEOMAlgo_Tools3D.cxx
23 //  Author  : Peter KURNEV
24
25 #include <GEOMAlgo_Tools3D.ixx>
26
27 #include <NMTTools_ListOfCoupleOfShape.hxx>
28 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
29 #include <NMTTools_CoupleOfShape.hxx>
30
31 #include <Basics_OCCTVersion.hxx>
32
33 #include <Precision.hxx>
34
35 #include <gp_Vec.hxx>
36 #include <gp_Pnt.hxx>
37 #include <gp_Dir.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <gp_Pln.hxx>
40 #include <gp_XYZ.hxx>
41 #include <gp_Dir2d.hxx>
42
43 #include <Geom_Curve.hxx>
44 #include <Geom_Surface.hxx>
45
46 #include <Geom2d_Curve.hxx>
47 #include <Geom2d_TrimmedCurve.hxx>
48 #include <Geom2d_Line.hxx>
49
50 #include <Geom2dHatch_Intersector.hxx>
51 #include <Geom2dHatch_Hatcher.hxx>
52
53 #include <HatchGen_Domain.hxx>
54
55 #include <GeomAPI_ProjectPointOnSurf.hxx>
56
57 #include <TopAbs_ShapeEnum.hxx>
58 #include <TopAbs_State.hxx>
59
60 #include <TopLoc_Location.hxx>
61
62 #include <TopoDS.hxx>
63 #include <TopoDS_Edge.hxx>
64 #include <TopoDS_CompSolid.hxx>
65 #include <TopoDS_Wire.hxx>
66 #include <TopoDS_Compound.hxx>
67 #include <TopoDS_Face.hxx>
68 #include <TopoDS_Vertex.hxx>
69 #include <TopoDS_Solid.hxx>
70 #include <TopoDS_Shell.hxx>
71 #include <TopoDS_Iterator.hxx>
72
73 #include <TopExp.hxx>
74 #include <TopExp_Explorer.hxx>
75
76 #include <BRep_Builder.hxx>
77 #include <BRep_Tool.hxx>
78
79 #include <TopTools_ListOfShape.hxx>
80 #include <TopTools_IndexedMapOfShape.hxx>
81 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
82 #include <TopTools_IndexedMapOfShape.hxx>
83 #include <TopTools_ListIteratorOfListOfShape.hxx>
84 #include <TopTools_MapOfShape.hxx>
85
86 #include <BRepClass3d_SolidClassifier.hxx>
87 #include <BRepTools.hxx>
88
89 #include <IntTools_Context.hxx>
90 #include <IntTools_Tools.hxx>
91
92 #include <BOPTools_Tools3D.hxx>
93 #include <BOPTools_Tools2D.hxx>
94 #include <BOPTools_Tools.hxx>
95
96 #include <TopTools_DataMapOfShapeListOfShape.hxx>
97 #include <TopTools_DataMapOfShapeListOfShape.hxx>
98 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
99 #include <TopTools_MapOfShape.hxx>
100 #include <TopTools_MapIteratorOfMapOfShape.hxx>
101
102 #include <GeomAdaptor_Surface.hxx>
103
104
105 static
106   Standard_Boolean FindFacePairs (const TopoDS_Edge& ,
107                                   const TopTools_ListOfShape& ,
108                                   NMTTools_ListOfCoupleOfShape& );
109
110
111 static
112   Standard_Real AngleWithRef(const gp_Dir& ,
113                              const gp_Dir& ,
114                              const gp_Dir& );
115
116 static
117   void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE,
118                                     const TopoDS_Face& aF,
119                                     Standard_Real aT,
120                                     gp_Pnt& aPF,
121                                     gp_Dir& aDNF,
122 #if OCC_VERSION_LARGE > 0x06050200
123                                     const Handle(IntTools_Context)& aCtx);
124 #else
125                                     IntTools_Context& aCtx);
126 #endif
127
128 //=======================================================================
129 //function : IsInternalFace
130 //purpose  :
131 //=======================================================================
132 Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
133                                                   const TopoDS_Solid& theSolid,
134                                                   const TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
135                                                   const Standard_Real theTol,
136 #if OCC_VERSION_LARGE > 0x06050200
137                                                   const Handle(IntTools_Context)& theContext)
138 #else
139                                                   IntTools_Context& theContext)
140 #endif
141 {
142   Standard_Boolean bRet;
143   Standard_Integer aNbF;
144   TopoDS_Edge aEL;
145   TopExp_Explorer aExp;
146   TopTools_ListIteratorOfListOfShape aItF;
147   //
148   bRet=Standard_False;
149   //
150   // 1 Try to find an edge from theFace in theMEF
151   aExp.Init(theFace, TopAbs_EDGE);
152   for(; aExp.More(); aExp.Next()) {
153     const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
154     if (!theMEF.Contains(aE)) {
155       continue;
156     }
157     //
158     const TopTools_ListOfShape& aLF=theMEF.FindFromKey(aE);
159     aNbF=aLF.Extent();
160     if (!aNbF) {
161       return bRet; // it can not be so
162     }
163     else if (aNbF==1) {
164       // aE is internal edge on aLF.First()
165       const TopoDS_Face& aF1=TopoDS::Face(aLF.First());
166       bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF1, theContext);
167       return bRet;
168     }
169     else if (aNbF==2) {
170       const TopoDS_Face& aF1=TopoDS::Face(aLF.First());
171       const TopoDS_Face& aF2=TopoDS::Face(aLF.Last());
172       //
173       if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
174         // treat as it was for 1 face
175         bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF2, theContext);
176         return bRet;
177       }
178     }
179     if (aNbF%2) {
180       return bRet; // it can not be so
181     }
182     else { // aNbF=2,4,6,8,...
183       bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aLF, theContext);
184       return bRet;
185     }
186   }//for(; aExp.More(); aExp.Next()) {
187   //
188   //========================================
189   // 2. Classify face using classifier
190   //
191   TopAbs_State aState;
192   TopTools_IndexedMapOfShape aBounds;
193   //
194   aState=GEOMAlgo_Tools3D::ComputeState(theFace, theSolid, theTol, aBounds, theContext);
195   bRet=(aState==TopAbs_IN);
196   //
197   return bRet;
198 }
199 //=======================================================================
200 //function : IsInternalFace
201 //purpose  :
202 //=======================================================================
203   Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
204                                                     const TopoDS_Edge& theEdge,
205                                                     const TopTools_ListOfShape& theLF,
206 #if OCC_VERSION_LARGE > 0x06050200
207                                                     const Handle(IntTools_Context)& theContext)
208 #else
209                                                     IntTools_Context& theContext)
210 #endif
211 {
212   Standard_Boolean bRet;
213   Standard_Boolean aNbF;
214   //
215   bRet=Standard_False;
216   //
217   aNbF=theLF.Extent();
218   if (aNbF==2) {
219     const TopoDS_Face& aF1=TopoDS::Face(theLF.First());
220     const TopoDS_Face& aF2=TopoDS::Face(theLF.Last());
221     bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
222     return bRet;
223   }
224   //
225   else {
226     NMTTools_ListOfCoupleOfShape aLCFF;
227     NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
228     //
229     FindFacePairs(theEdge, theLF, aLCFF);
230     //
231     aIt.Initialize(aLCFF);
232     for (; aIt.More(); aIt.Next()) {
233       const NMTTools_CoupleOfShape& aCSFF=aIt.Value();
234       //
235       const TopoDS_Face& aF1=TopoDS::Face(aCSFF.Shape1());
236       const TopoDS_Face& aF2=TopoDS::Face(aCSFF.Shape2());
237       bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
238       if (bRet) {
239         return bRet;
240       }
241     }
242   }
243   return bRet;
244 }
245 //=======================================================================
246 //function : IsInternalFace
247 //purpose  :
248 //=======================================================================
249   Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
250                                                     const TopoDS_Edge& theEdge,
251                                                     const TopoDS_Face& theFace1,
252                                                     const TopoDS_Face& theFace2,
253 #if OCC_VERSION_LARGE > 0x06050200
254                                                     const Handle(IntTools_Context)& theContext)
255 #else
256                                                     IntTools_Context& theContext)
257 #endif
258 {
259   Standard_Boolean bRet;
260   Standard_Real aT1, aT2, aT, aDt2D, aDt2Dx;
261   Standard_Real aA12, aA1x, aTwoPI;
262   gp_Pnt aPx, aPF, aPF1, aPF2;
263   gp_Pnt2d aP2D, aPF2D;
264   gp_Dir aDNF1, aDNF2;
265   TopoDS_Edge aE1, aE2;
266   Handle(Geom_Curve)aC3D;
267   //
268   aC3D =BRep_Tool::Curve(theEdge, aT1, aT2);
269   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
270   aC3D->D0(aT, aPx);
271   //
272   // 1. PF
273   aDt2D=BOPTools_Tools3D::MinStepIn2d();
274   aDt2Dx=10.*aDt2D;
275   BOPTools_Tools3D::PointNearEdge (theEdge, theFace, aT, aDt2Dx, aPF2D, aPF);
276   //
277   // 2. E1, E2
278   GEOMAlgo_Tools3D::GetEdgeOnFace(theEdge, theFace1, aE1);
279   if (aE1.Orientation()==TopAbs_INTERNAL) {
280     aE2=aE1;
281     aE1.Orientation(TopAbs_FORWARD);
282     aE2.Orientation(TopAbs_REVERSED);
283   }
284   else if (theFace1==theFace2) {
285     aE2=aE1;
286     aE1.Orientation(TopAbs_FORWARD);
287     aE2.Orientation(TopAbs_REVERSED);
288   }
289   else {
290     GEOMAlgo_Tools3D::GetEdgeOnFace(theEdge, theFace2, aE2);
291   }
292   //
293   // 3
294   bRet=Standard_False;
295   //
296   GetApproxNormalToFaceOnEdge (aE1, theFace1, aT, aPF1, aDNF1, theContext);
297   GetApproxNormalToFaceOnEdge (aE2, theFace2, aT, aPF2, aDNF2, theContext);
298   //
299   aTwoPI = 2.*M_PI;
300   gp_Vec aVBF (aPx, aPF );
301   gp_Vec aVBF1(aPx, aPF1);
302   gp_Vec aVBF2(aPx, aPF2);
303   //
304   gp_Dir aDTF1;
305   gp_Dir aDBF (aVBF);
306   gp_Dir aDBF1(aVBF1);
307   gp_Dir aDBF2(aVBF2);
308   //
309   aDTF1=aDNF1^aDBF1;
310   aA12=AngleWithRef(aDBF1, aDBF2, aDTF1);
311   if (aA12<0.) {
312     aA12=aA12+aTwoPI;
313   }
314
315   aA1x=AngleWithRef(aDBF1, aDBF , aDTF1);
316   if (aA1x<0.) {
317     aA1x=aA1x+aTwoPI;
318   }
319   //
320   if (aA1x<aA12) {
321     bRet=!bRet; //TopAbs_IN;
322   }
323   //
324   return bRet;
325 }
326 //=======================================================================
327 //function : GetFaceOff
328 //purpose  :
329 //=======================================================================
330   void GEOMAlgo_Tools3D::GetFaceOff(const TopoDS_Edge& theE1,
331                                    const TopoDS_Face& theF1,
332                                    const NMTTools_ListOfCoupleOfShape& theLCSOff,
333                                    TopoDS_Face& theFOff)
334 {
335   Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
336   gp_Pnt aPn1, aPn2;
337   gp_Vec aVTgt;
338   gp_Dir aDN1, aDN2;
339   NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
340   //
341   aAngleMin=100.;
342   aTwoPI = M_PI+M_PI;
343   BRep_Tool::Range(theE1, aT1, aT2);
344   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
345   // Ref
346   BOPTools_Tools2D::EdgeTangent(theE1, aT, aVTgt);
347   gp_Dir aDTtgt(aVTgt);
348   aDTtgt.Reverse();
349   // N1
350   BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(theE1, theF1, aT, aPn1, aDN1);
351   //
352   aIt.Initialize(theLCSOff);
353   for (; aIt.More(); aIt.Next()) {
354     const NMTTools_CoupleOfShape& aCS=aIt.Value();
355     const TopoDS_Edge& aE2=TopoDS::Edge(aCS.Shape1());
356     const TopoDS_Face& aF2=TopoDS::Face(aCS.Shape2());
357     //
358     if (aF2==theF1) {
359       aAngle=M_PI;
360     }
361     else if (aF2.IsSame(theF1)) {
362       aAngle=aTwoPI;
363     }
364     else {
365       BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aE2, aF2, aT, aPn2, aDN2);
366       aDN2.Reverse();
367       // Angle
368       aAngle=AngleWithRef(aDN1, aDN2, aDTtgt);
369       if(aAngle<0.) {
370         aAngle=aTwoPI+aAngle;
371       }
372     }
373     //
374     if (aAngle<aAngleMin){
375       aAngleMin=aAngle;
376       theFOff=aF2;
377     }
378   }
379 }
380 //=======================================================================
381 //function : GetEdgeOnFace
382 //purpose  :
383 //=======================================================================
384   Standard_Boolean GEOMAlgo_Tools3D::GetEdgeOnFace(const TopoDS_Edge& theE1,
385                                                   const TopoDS_Face& theF2,
386                                                   TopoDS_Edge& theE2)
387 {
388   Standard_Boolean bFound;
389   TopoDS_Iterator aItF, aItW;
390   //
391   bFound=Standard_False;
392   //
393   aItF.Initialize(theF2);
394   for (; aItF.More(); aItF.Next()) {
395     const TopoDS_Shape& aW=aItF.Value();
396     aItW.Initialize(aW);
397     for (; aItW.More(); aItW.Next()) {
398       const TopoDS_Shape& aE=aItW.Value();
399       if (aE.IsSame(theE1)) {
400         theE2=TopoDS::Edge(aE);
401         bFound=!bFound;
402         return bFound;
403       }
404     }
405   }
406   return bFound;
407 }
408 //=======================================================================
409 //function : GetEdgeOff
410 //purpose  :
411 //=======================================================================
412 Standard_Boolean GEOMAlgo_Tools3D::GetEdgeOff (const TopoDS_Edge& theE1,
413                                                const TopoDS_Face& theF2,
414                                                TopoDS_Edge& theE2)
415
416 {
417   Standard_Boolean bFound;
418   TopAbs_Orientation aOr1, aOr1C, aOr2;
419   TopExp_Explorer anExp;
420   //
421   bFound=Standard_False;
422   aOr1=theE1.Orientation();
423   aOr1C=TopAbs::Reverse(aOr1);
424   //
425   anExp.Init(theF2, TopAbs_EDGE);
426   for (; anExp.More(); anExp.Next()) {
427     const TopoDS_Edge& aEF2=TopoDS::Edge(anExp.Current());
428     if (aEF2.IsSame(theE1)) {
429       aOr2=aEF2.Orientation();
430       if (aOr2==aOr1C) {
431         theE2=aEF2;
432         bFound=!bFound;
433         return bFound;
434       }
435     }
436   }
437   return bFound;
438 }
439 //=======================================================================
440 // function:  ComputeState
441 // purpose:
442 //=======================================================================
443   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Face& theF,
444                                              const TopoDS_Solid& theRef,
445                                              const Standard_Real theTol,
446                                              const TopTools_IndexedMapOfShape& theBounds,
447 #if OCC_VERSION_LARGE > 0x06050200
448                                              const Handle(IntTools_Context)& theCtx)
449 #else
450                                              IntTools_Context& theCtx)
451 #endif
452 {
453   TopAbs_State aState;
454   TopExp_Explorer aExp;
455   TopoDS_Edge aE1;
456   gp_Pnt2d aP2D;
457   gp_Pnt aP3D;
458   //
459   aState=TopAbs_UNKNOWN;
460   //
461   aExp.Init(theF, TopAbs_EDGE);
462   for (; aExp.More(); aExp.Next()) {
463     const TopoDS_Edge& aSE=TopoDS::Edge(aExp.Current());
464     if (BRep_Tool::Degenerated(aSE)) {
465       continue;
466     }
467     //
468     if (!theBounds.Contains(aSE)) {
469       const TopoDS_Edge& aE=TopoDS::Edge(aSE);
470       aState= GEOMAlgo_Tools3D::ComputeState(aE, theRef, theTol, theCtx);
471       return aState;
472     }
473     if (aE1.IsNull()) {
474       aE1=TopoDS::Edge(aSE);
475     }
476   }
477   // !!<- process edges that are all on theRef
478   if (!aE1.IsNull()) {
479     BOPTools_Tools3D::PointNearEdge(aE1, theF, aP2D, aP3D);
480     aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx);
481   }
482   //
483   return aState;
484 }
485 //=======================================================================
486 // function:  ComputeStateByOnePoint
487 // purpose:
488 //=======================================================================
489   TopAbs_State GEOMAlgo_Tools3D::ComputeStateByOnePoint(const TopoDS_Shape& theS,
490                                                        const TopoDS_Solid& theRef,
491                                                        const Standard_Real theTol,
492 #if OCC_VERSION_LARGE > 0x06050200
493                                                        const Handle(IntTools_Context)& theCtx)
494 #else
495                                                        IntTools_Context& theCtx)
496 #endif
497 {
498   TopAbs_State aState;
499   TopAbs_ShapeEnum aType;
500   //
501   aState=TopAbs_UNKNOWN;
502   aType=theS.ShapeType();
503   if (aType==TopAbs_VERTEX) {
504     const TopoDS_Vertex& aV=TopoDS::Vertex(theS);
505     aState=GEOMAlgo_Tools3D::ComputeState(aV, theRef, theTol, theCtx);
506   }
507   else if (aType==TopAbs_EDGE) {
508     const TopoDS_Edge& aE=TopoDS::Edge(theS);
509     aState=GEOMAlgo_Tools3D::ComputeState(aE, theRef, theTol, theCtx);
510   }
511   return aState;
512 }
513 //=======================================================================
514 // function:  ComputeState
515 // purpose:
516 //=======================================================================
517   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Vertex& theV,
518                                              const TopoDS_Solid& theRef,
519                                              const Standard_Real theTol,
520 #if OCC_VERSION_LARGE > 0x06050200
521                                              const Handle(IntTools_Context)& theCtx)
522 #else
523                                              IntTools_Context& theCtx)
524 #endif
525 {
526   TopAbs_State aState;
527   gp_Pnt aP3D;
528   //
529   aP3D=BRep_Tool::Pnt(theV);
530   aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx);
531   return aState;
532 }
533 //=======================================================================
534 // function:  ComputeState
535 // purpose:
536 //=======================================================================
537   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Edge& theE,
538                                              const TopoDS_Solid& theRef,
539                                              const Standard_Real theTol,
540 #if OCC_VERSION_LARGE > 0x06050200
541                                              const Handle(IntTools_Context)& theCtx)
542 #else
543                                              IntTools_Context& theCtx)
544 #endif
545 {
546   Standard_Real aT1, aT2, aT = 0.;
547   TopAbs_State aState;
548   Handle(Geom_Curve) aC3D;
549   gp_Pnt aP3D;
550   //
551   aC3D = BRep_Tool::Curve(theE, aT1, aT2);
552   //
553   if(aC3D.IsNull()) {
554     //it means that we are in degenerated edge
555     const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
556     if(aV.IsNull()){
557       return TopAbs_UNKNOWN;
558     }
559     aP3D=BRep_Tool::Pnt(aV);
560   }
561   else {//usual case
562     Standard_Boolean bF2Inf, bL2Inf;
563     Standard_Real dT=10.;
564     //
565     bF2Inf = Precision::IsNegativeInfinite(aT1);
566     bL2Inf = Precision::IsPositiveInfinite(aT2);
567     //
568     if (bF2Inf && !bL2Inf) {
569       aT=aT2-dT;
570     }
571     else if (!bF2Inf && bL2Inf) {
572       aT=aT1+dT;
573     }
574     else if (bF2Inf && bL2Inf) {
575       aT=0.;
576     }
577     else {
578       aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
579     }
580     aC3D->D0(aT, aP3D);
581   }
582   //
583   aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx);
584   //
585   return aState;
586 }
587 //=======================================================================
588 // function:  ComputeState
589 // purpose:
590 //=======================================================================
591   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const gp_Pnt& theP,
592                                              const TopoDS_Solid& theRef,
593                                              const Standard_Real theTol,
594 #if OCC_VERSION_LARGE > 0x06050200
595                                              const Handle(IntTools_Context)& theCtx)
596 #else
597                                              IntTools_Context& theCtx)
598 #endif
599 {
600   TopAbs_State aState;
601   //
602 #if OCC_VERSION_LARGE > 0x06050200
603   BRepClass3d_SolidClassifier& aSC=theCtx->SolidClassifier(theRef);
604 #else
605   BRepClass3d_SolidClassifier& aSC=theCtx.SolidClassifier(theRef);
606 #endif
607   aSC.Perform(theP, theTol);
608   //
609   aState=aSC.State();
610   //
611   return aState;
612 }
613 //=======================================================================
614 // function: IsSplitToReverse
615 // purpose:
616 //=======================================================================
617 Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse (const TopoDS_Shape& theSp,
618                                                      const TopoDS_Shape& theSr,
619 #if OCC_VERSION_LARGE > 0x06050200
620                                                      const Handle(IntTools_Context)& theCtx)
621 #else
622                                                      IntTools_Context& theCtx)
623 #endif
624 {
625   Standard_Boolean bRet;
626   TopAbs_ShapeEnum aType;
627   //
628   bRet=Standard_False;
629   //
630   aType=theSp.ShapeType();
631   switch (aType) {
632     case TopAbs_EDGE: {
633       const TopoDS_Edge& aESp=TopoDS::Edge(theSp);
634       const TopoDS_Edge& aESr=TopoDS::Edge(theSr);
635       bRet=GEOMAlgo_Tools3D::IsSplitToReverse(aESp, aESr, theCtx);
636     }
637       break;
638       //
639     case TopAbs_FACE: {
640       const TopoDS_Face& aFSp=TopoDS::Face(theSp);
641       const TopoDS_Face& aFSr=TopoDS::Face(theSr);
642       bRet=GEOMAlgo_Tools3D::IsSplitToReverse(aFSp, aFSr, theCtx);
643     }
644       break;
645       //
646     default:
647       break;
648   }
649   return bRet;
650 }
651 //=======================================================================
652 //function :IsSplitToReverse
653 //purpose  :
654 //=======================================================================
655 Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse (const TopoDS_Face& theFSp,
656                                                      const TopoDS_Face& theFSr,
657 #if OCC_VERSION_LARGE > 0x06050200
658                                                      const Handle(IntTools_Context)& theContext)
659 #else
660                                                      IntTools_Context& theContext)
661 #endif
662 {
663   Standard_Boolean bRet, bFound, bInFace;
664   Standard_Real aT1, aT2, aT, aU, aV, aScPr;
665   gp_Pnt aPFSp, aPFSr;
666   gp_Dir aDNFSp;
667   gp_Vec aD1U, aD1V;
668   Handle(Geom_Surface) aSr, aSp;
669   TopAbs_Orientation aOrSr, aOrSp;
670   TopExp_Explorer anExp;
671   TopoDS_Edge aESp;
672   //
673   bRet=Standard_False;
674   //
675   aSr=BRep_Tool::Surface(theFSr);
676   aSp=BRep_Tool::Surface(theFSp);
677   if (aSr==aSp) {
678     aOrSr=theFSr.Orientation();
679     aOrSp=theFSp.Orientation();
680     bRet=(aOrSr!=aOrSp);
681     return bRet;
682   }
683   //
684   bFound=Standard_False;
685   anExp.Init(theFSp, TopAbs_EDGE);
686   for (; anExp.More(); anExp.Next()) {
687     aESp=TopoDS::Edge(anExp.Current());
688     if (!BRep_Tool::Degenerated(aESp)) {
689       if (!BRep_Tool::IsClosed(aESp, theFSp)) {
690         bFound=!bFound;
691         break;
692       }
693     }
694   }
695   //
696   //modified by NIZNHY-PKV Tue Nov 22 10:50:30 2011f
697   if (!bFound) {
698     Standard_Boolean bFlag;
699     Standard_Integer iErr;
700     gp_Pnt2d aP2DFSp;
701     //
702     iErr=GEOMAlgo_Tools3D::PntInFace(theFSp, aPFSp, aP2DFSp);
703     if (iErr) {
704       return bRet;
705     }
706     //
707     aP2DFSp.Coord(aU, aV);
708     bFlag=BOPTools_Tools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
709     if (!bFlag) {
710       return bRet;
711     }
712   }
713   else {
714     BRep_Tool::Range(aESp, aT1, aT2);
715     aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
716     BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp);
717   }
718   //
719   /*
720   if (!bFound) {
721     return bRet;
722   }
723   BRep_Tool::Range(aESp, aT1, aT2);
724   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
725   BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp);
726   */
727   //modified by NIZNHY-PKV Tue Nov 22 10:50:37 2011t
728   //
729   // Parts of theContext.ComputeVS(..)
730 #if OCC_VERSION_LARGE > 0x06050200
731   GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
732 #else
733   GeomAPI_ProjectPointOnSurf& aProjector=theContext.ProjPS(theFSr);
734 #endif
735   aProjector.Perform(aPFSp);
736   if (!aProjector.IsDone()) {
737     return bRet;
738   }
739   //
740   aProjector.LowerDistanceParameters(aU, aV);
741   gp_Pnt2d aP2D(aU, aV);
742 #if OCC_VERSION_LARGE > 0x06050200
743   bInFace=theContext->IsPointInFace (theFSr, aP2D);
744 #else
745   bInFace=theContext.IsPointInFace (theFSr, aP2D);
746 #endif
747   if (!bInFace) {
748     return bRet;
749   }
750   //
751   aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
752   gp_Dir aDD1U(aD1U);
753   gp_Dir aDD1V(aD1V);
754   gp_Dir aDNFSr=aDD1U^aDD1V;
755   if (theFSr.Orientation()==TopAbs_REVERSED){
756     aDNFSr.Reverse();
757   }
758   //
759   aScPr=aDNFSp*aDNFSr;
760   bRet=(aScPr<0.);
761   //
762   return bRet;
763 }
764 //=======================================================================
765 //function :IsSplitToReverse
766 //purpose  :
767 //=======================================================================
768 Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse (const TopoDS_Edge& theSplit,
769                                                      const TopoDS_Edge& theEdge,
770 #if OCC_VERSION_LARGE > 0x06050200
771                                                      const Handle(IntTools_Context)& theContext)
772 #else
773                                                      IntTools_Context& theContext)
774 #endif
775 {
776   Standard_Boolean bRet, aFlag, bIsDegenerated;
777   Standard_Real aTE, aTS, aScPr, aTa, aTb, aT1, aT2;
778   TopAbs_Orientation aOrSr, aOrSp;
779   Handle(Geom_Curve) aCEdge, aCSplit;
780   gp_Vec aVE, aVS;
781   gp_Pnt aP;
782   //
783   bRet=Standard_False;
784   //
785   bIsDegenerated=(BRep_Tool::Degenerated(theSplit) ||
786                   BRep_Tool::Degenerated(theEdge));
787   if (bIsDegenerated) {
788     return bRet;
789   }
790   //
791   aCEdge =BRep_Tool::Curve(theEdge , aT1, aT2);
792   aCSplit=BRep_Tool::Curve(theSplit, aTa, aTb);
793   //
794   if (aCEdge==aCSplit) {
795     aOrSr=theEdge.Orientation();
796     aOrSp=theSplit.Orientation();
797     bRet=(aOrSr!=aOrSp);
798     return bRet;
799   }
800   //
801   aTS=BOPTools_Tools2D::IntermediatePoint(aTa, aTb);
802   aCSplit->D0(aTS, aP);
803   aFlag=BOPTools_Tools2D::EdgeTangent(theSplit, aTS, aVS);
804   gp_Dir aDTS(aVS);
805   //
806 #if OCC_VERSION_LARGE > 0x06050200
807   aFlag=theContext->ProjectPointOnEdge(aP, theEdge, aTE);
808 #else
809   aFlag=theContext.ProjectPointOnEdge(aP, theEdge, aTE);
810 #endif
811   aFlag=BOPTools_Tools2D::EdgeTangent(theEdge, aTE, aVE);
812   gp_Dir aDTE(aVE);
813   //
814   aScPr=aDTS*aDTE;
815   bRet=(aScPr<0.);
816   //
817   return bRet;
818 }
819
820 //=======================================================================
821 // function: Sense
822 // purpose:
823 //=======================================================================
824   Standard_Integer GEOMAlgo_Tools3D::Sense (const TopoDS_Face& theF1,
825                                            const TopoDS_Face& theF2)
826 {
827   Standard_Integer iSense=0;
828   gp_Dir aDNF1, aDNF2;
829   TopoDS_Edge aE1, aE2;
830   TopExp_Explorer anExp;
831   //
832   anExp.Init(theF1, TopAbs_EDGE);
833   for (; anExp.More(); anExp.Next()) {
834     aE1=TopoDS::Edge(anExp.Current());
835     if (!BRep_Tool::Degenerated(aE1)) {
836       if (!BRep_Tool::IsClosed(aE1, theF1)) {
837         break;
838       }
839     }
840   }
841   //
842   anExp.Init(theF2, TopAbs_EDGE);
843   for (; anExp.More(); anExp.Next()) {
844     aE2=TopoDS::Edge(anExp.Current());
845     if (!BRep_Tool::Degenerated(aE2)) {
846       if (!BRep_Tool::IsClosed(aE2, theF2)) {
847         if (aE2.IsSame(aE1)) {
848           iSense=1;
849           break;
850         }
851       }
852     }
853   }
854   //
855   if (!iSense) {
856     return iSense;
857   }
858   //
859   BOPTools_Tools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
860   BOPTools_Tools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
861   //
862   iSense=BOPTools_Tools3D::SenseFlag(aDNF1, aDNF2);
863   //
864   return iSense;
865 }
866 //=======================================================================
867 // function: CopyFace
868 // purpose:
869 //=======================================================================
870   void GEOMAlgo_Tools3D::CopyFace (const TopoDS_Face& theF1,
871                                   TopoDS_Face& theF2)
872 {
873   Standard_Real aTol;
874   TopLoc_Location aLoc;
875   TopAbs_Orientation aOr;
876   TopoDS_Iterator aIt;
877   BRep_Builder aBB;
878   //
879   Handle(Geom_Surface) aSurface=BRep_Tool::Surface(theF1, aLoc);
880   aTol=BRep_Tool::Tolerance(theF1);
881   aOr=theF1.Orientation();
882   //
883   aBB.MakeFace (theF2, aSurface, aLoc, aTol);
884   theF2.Orientation(aOr);
885   //
886   aIt.Initialize(theF1);
887   for (; aIt.More(); aIt.Next()) {
888     const TopoDS_Shape& aW=aIt.Value();
889     aBB.Add(theF2, aW);
890   }
891 }
892 //=======================================================================
893 // function: MakeContainer
894 // purpose:
895 //=======================================================================
896   void GEOMAlgo_Tools3D::MakeContainer(const TopAbs_ShapeEnum theType,
897                                       TopoDS_Shape& theC)
898 {
899   BRep_Builder aBB;
900   //
901   switch(theType) {
902     case TopAbs_COMPOUND:{
903       TopoDS_Compound aC;
904       aBB.MakeCompound(aC);
905       theC=aC;
906     }
907       break;
908       //
909     case TopAbs_COMPSOLID:{
910       TopoDS_CompSolid aCS;
911       aBB.MakeCompSolid(aCS);
912       theC=aCS;
913     }
914       break;
915       //
916     case TopAbs_SOLID:{
917       TopoDS_Solid aSolid;
918       aBB.MakeSolid(aSolid);
919       theC=aSolid;
920     }
921       break;
922       //
923       //
924     case TopAbs_SHELL:{
925       TopoDS_Shell aShell;
926       aBB.MakeShell(aShell);
927       theC=aShell;
928     }
929       break;
930       //
931     case TopAbs_WIRE: {
932       TopoDS_Wire aWire;
933       aBB.MakeWire(aWire);
934       theC=aWire;
935     }
936       break;
937       //
938     default:
939       break;
940   }
941 }
942 //=======================================================================
943 // function: MakeConnexityBlock.
944 // purpose:
945 //=======================================================================
946   void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn,
947                                              const TopTools_IndexedMapOfShape& theMEAvoid,
948                                              TopTools_ListOfShape& theLCB)
949 {
950   Standard_Integer  aNbF, aNbAdd1;
951   TopExp_Explorer aExp;
952   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
953   TopTools_MapIteratorOfMapOfShape aItM, aItM1;
954   TopTools_MapOfShape aMCB, aMAdd, aMAdd1;
955   TopTools_ListIteratorOfListOfShape aIt;
956   //
957   // 1. aMEF
958   aNbF=theLFIn.Extent();
959   aIt.Initialize(theLFIn);
960   for (; aIt.More(); aIt.Next()) {
961     const TopoDS_Shape& aF=aIt.Value();
962     TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
963   }
964   //
965   // 2. aMCB
966   const TopoDS_Shape& aF1=theLFIn.First();
967   aMAdd.Add(aF1);
968   //
969   while(1) {
970     aMAdd1.Clear();
971     aItM.Initialize(aMAdd);
972     for (; aItM.More(); aItM.Next()) {
973       const TopoDS_Shape& aF=aItM.Key();
974       //
975       //aMAdd1.Clear();
976       aExp.Init(aF, TopAbs_EDGE);
977       for (; aExp.More(); aExp.Next()) {
978         const TopoDS_Shape& aE=aExp.Current();
979         if (theMEAvoid.Contains(aE)){
980           continue;
981         }
982         //
983         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
984         aIt.Initialize(aLF);
985         for (; aIt.More(); aIt.Next()) {
986           const TopoDS_Shape& aFx=aIt.Value();
987           if (aFx.IsSame(aF)) {
988             continue;
989           }
990           if (aMCB.Contains(aFx)) {
991             continue;
992           }
993           aMAdd1.Add(aFx);
994         }
995       }//for (; aExp.More(); aExp.Next()){
996       aMCB.Add(aF);
997     }// for (; aItM.More(); aItM.Next()) {
998     //
999     aNbAdd1=aMAdd1.Extent();
1000     if (!aNbAdd1) {
1001       break;
1002     }
1003     //
1004     aMAdd.Clear();
1005     aItM1.Initialize(aMAdd1);
1006     for (; aItM1.More(); aItM1.Next()) {
1007       const TopoDS_Shape& aFAdd=aItM1.Key();
1008       aMAdd.Add(aFAdd);
1009     }
1010     //
1011   }//while(1) {
1012
1013   //
1014   aNbF=aMCB.Extent();
1015   aItM.Initialize(aMCB);
1016   for (; aItM.More(); aItM.Next()) {
1017     const TopoDS_Shape& aF=aItM.Key();
1018     theLCB.Append(aF);
1019   }
1020 }
1021 //=======================================================================
1022 //function : FindFacePairs
1023 //purpose  :
1024 //=======================================================================
1025 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1026                                 const TopTools_ListOfShape& thLF,
1027                                 NMTTools_ListOfCoupleOfShape& theLCFF)
1028 {
1029   Standard_Boolean bFound;
1030   Standard_Integer i, aNbCEF;
1031   TopAbs_Orientation aOr, aOrC;
1032   TopTools_MapOfShape aMFP;
1033   TopoDS_Face aF1, aF2;
1034   TopoDS_Edge aEL, aE1;
1035   TopTools_ListIteratorOfListOfShape aItLF;
1036   NMTTools_CoupleOfShape aCEF, aCFF;
1037   NMTTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1038   NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
1039   //
1040   bFound=Standard_True;
1041   //
1042   // Preface aLCEF
1043   aItLF.Initialize(thLF);
1044   for (; aItLF.More(); aItLF.Next()) {
1045     const TopoDS_Face& aFL=TopoDS::Face(aItLF.Value());
1046     //
1047     bFound=GEOMAlgo_Tools3D::GetEdgeOnFace(theE, aFL, aEL);
1048     if (!bFound) {
1049       return bFound; // it can not be so
1050     }
1051     //
1052     aCEF.SetShape1(aEL);
1053     aCEF.SetShape2(aFL);
1054     aLCEF.Append(aCEF);
1055   }
1056   //
1057   aNbCEF=aLCEF.Extent();
1058   while(aNbCEF) {
1059     //
1060     // aLCEFx
1061     aLCEFx.Clear();
1062     aIt.Initialize(aLCEF);
1063     for (i=0; aIt.More(); aIt.Next(), ++i) {
1064       const NMTTools_CoupleOfShape& aCSx=aIt.Value();
1065       const TopoDS_Shape& aEx=aCSx.Shape1();
1066       const TopoDS_Shape& aFx=aCSx.Shape2();
1067       //
1068       aOr=aEx.Orientation();
1069       //
1070       if (!i) {
1071         aOrC=TopAbs::Reverse(aOr);
1072         aE1=TopoDS::Edge(aEx);
1073         aF1=TopoDS::Face(aFx);
1074         aMFP.Add(aFx);
1075         continue;
1076       }
1077       //
1078       if (aOr==aOrC) {
1079         aLCEFx.Append(aCSx);
1080         aMFP.Add(aFx);
1081       }
1082     }
1083     //
1084     // F2
1085     GEOMAlgo_Tools3D::GetFaceOff(aE1, aF1, aLCEFx, aF2);
1086     //
1087     aCFF.SetShape1(aF1);
1088     aCFF.SetShape2(aF2);
1089     theLCFF.Append(aCFF);
1090     //
1091     aMFP.Add(aF1);
1092     aMFP.Add(aF2);
1093     //
1094     // refine aLCEF
1095     aLCEFx.Clear();
1096     aLCEFx=aLCEF;
1097     aLCEF.Clear();
1098     aIt.Initialize(aLCEFx);
1099     for (; aIt.More(); aIt.Next()) {
1100       const NMTTools_CoupleOfShape& aCSx=aIt.Value();
1101       const TopoDS_Shape& aFx=aCSx.Shape2();
1102       if (!aMFP.Contains(aFx)) {
1103         aLCEF.Append(aCSx);
1104       }
1105     }
1106     //
1107     aNbCEF=aLCEF.Extent();
1108   }//while(aNbCEF) {
1109   //
1110   return bFound;
1111 }
1112 //
1113 //=======================================================================
1114 //function : AngleWithRef
1115 //purpose  :
1116 //=======================================================================
1117 Standard_Real AngleWithRef(const gp_Dir& theD1,
1118                            const gp_Dir& theD2,
1119                            const gp_Dir& theDRef)
1120 {
1121   Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1122   gp_XYZ aXYZ;
1123   //
1124   aHalfPI=0.5*M_PI;
1125   //
1126   const gp_XYZ& aXYZ1=theD1.XYZ();
1127   const gp_XYZ& aXYZ2=theD2.XYZ();
1128   aXYZ=aXYZ1.Crossed(aXYZ2);
1129   aSinus=aXYZ.Modulus();
1130   aCosinus=theD1*theD2;
1131   //
1132   aBeta=0.;
1133   if (aSinus>=0.) {
1134     aBeta=aHalfPI*(1.-aCosinus);
1135   }
1136   else {
1137     aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1138   }
1139   //
1140   aScPr=aXYZ.Dot(theDRef.XYZ());
1141   if (aScPr<0.) {
1142     aBeta=-aBeta;
1143   }
1144   return aBeta;
1145 }
1146 //=======================================================================
1147 //function : GetApproxNormalToFaceOnEdge
1148 //purpose  :
1149 //=======================================================================
1150 void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aEx,
1151                                   const TopoDS_Face& aFx,
1152                                   Standard_Real aT,
1153                                   gp_Pnt& aPF,
1154                                   gp_Dir& aDNF,
1155 #if OCC_VERSION_LARGE > 0x06050200
1156                                   const Handle(IntTools_Context)& aCtx)
1157 #else
1158                                   IntTools_Context& aCtx)
1159 #endif
1160 {
1161   Standard_Boolean bReverse;
1162   Standard_Real aT1, aT2, dT, aU, aV;
1163   gp_Dir aDTT, aDNFT, aDBT;
1164   gp_Pnt aPFT, aPFx;
1165   Handle(Geom_Curve) aC3D;
1166   Handle(Geom_Surface) aS;
1167   GeomAdaptor_Surface aGAS;
1168   GeomAbs_SurfaceType aTS;
1169   TopoDS_Face aF;
1170   TopoDS_Edge aE;
1171   //
1172   bReverse=Standard_False;
1173   aF=aFx;
1174   aE=aEx;
1175   if (aF.Orientation()==TopAbs_REVERSED){
1176     bReverse=!bReverse;
1177     aE.Reverse();
1178     //
1179     aF.Orientation(TopAbs_FORWARD);
1180   }
1181   //
1182   // Point at aT
1183   aC3D =BRep_Tool::Curve(aE, aT1, aT2);
1184   aC3D->D0(aT, aPFT);
1185   //
1186   // Normal at aT
1187   BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNFT);
1188
1189   // Tangent at aT
1190   BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDTT);
1191   //
1192   // Binormal at aT
1193   aDBT=aDNFT^aDTT;
1194   //
1195   dT=BOPTools_Tools3D::MinStepIn2d();//~1.e-5;
1196   dT=10.*dT;
1197   //----------------------------------------------
1198   {
1199     aS=BRep_Tool::Surface(aF);
1200     aGAS.Load(aS);
1201     aTS=aGAS.GetType();
1202     if (aTS==GeomAbs_BSplineSurface ||
1203         aTS==GeomAbs_BezierSurface ||
1204         aTS==GeomAbs_Plane){
1205       Standard_Real aTolEx, aTolFx, aTol, dUR, dVR, dR;
1206       //
1207       aTolEx=BRep_Tool::Tolerance(aEx);
1208       aTolFx=BRep_Tool::Tolerance(aFx);
1209       aTol=2.*aTolEx+aTolFx;
1210       dUR=aGAS.UResolution(aTol);
1211       dVR=aGAS.VResolution(aTol);
1212       dR=(dUR>dVR)? dUR : dVR;
1213       if (dR>dT) {
1214         dT=dR;
1215       }
1216     }
1217     else if (GeomAbs_Torus ||
1218              aTS==GeomAbs_Cylinder){
1219       Standard_Real aTolEx, aTolFx, aTol;
1220       //
1221       aTolEx=BRep_Tool::Tolerance(aEx);
1222       aTolFx=BRep_Tool::Tolerance(aFx);
1223       aTol=2.*aTolEx+aTolFx;
1224       if (aTol>dT) {
1225         dT=aTol;
1226       }
1227     }
1228   }
1229   //----------------------------------------------
1230   //
1231   aPFx.SetXYZ(aPFT.XYZ()+dT*aDBT.XYZ());
1232   //
1233   aPF=aPFx;
1234   aDNF=aDNFT;
1235   if (bReverse) {
1236     aDNF.Reverse();
1237   }
1238   //
1239 #if OCC_VERSION_LARGE > 0x06050200
1240   GeomAPI_ProjectPointOnSurf& aProjector=aCtx->ProjPS(aF);
1241 #else
1242   GeomAPI_ProjectPointOnSurf& aProjector=aCtx.ProjPS(aF);
1243 #endif
1244   //
1245   aProjector.Perform(aPFx);
1246   if(aProjector.IsDone()) {
1247     aProjector.LowerDistanceParameters (aU, aV);
1248     aS->D0(aU, aV, aPF);
1249     BOPTools_Tools3D::GetNormalToSurface (aS, aU, aV, aDNF);
1250     if (bReverse){
1251       aDNF.Reverse();
1252     }
1253   }
1254 }
1255
1256 //modified by NIZNHY-PKV Tue Nov 22 10:36:59 2011f
1257 //=======================================================================
1258 //function : PntInFace
1259 //purpose  : 
1260 //=======================================================================
1261 Standard_Integer GEOMAlgo_Tools3D::PntInFace(const TopoDS_Face& aF, 
1262                                              gp_Pnt& theP,
1263                                              gp_Pnt2d& theP2D)
1264 {
1265   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
1266   Standard_Integer iErr, aIx, aNbDomains, i;
1267   Standard_Real aUMin, aUMax, aVMin, aVMax;
1268   Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
1269   Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
1270   gp_Dir2d aD2D (0., 1.);
1271   gp_Pnt2d aP2D;
1272   gp_Pnt aPx;
1273   Handle(Geom2d_Curve) aC2D;
1274   Handle(Geom2d_TrimmedCurve) aCT2D;
1275   Handle(Geom2d_Line) aL2D;
1276   Handle(Geom_Surface) aS;
1277   TopAbs_Orientation aOrE;
1278   TopoDS_Face aFF;
1279   TopExp_Explorer aExp;
1280   //
1281   aTolHatch2D=1.e-8;
1282   aTolHatch3D=1.e-8;
1283   aTotArcIntr=1.e-10;
1284   aTolTangfIntr=1.e-10;
1285   //
1286   Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
1287   Geom2dHatch_Hatcher aHatcher(aIntr, 
1288                                aTolHatch2D, aTolHatch3D, 
1289                                Standard_True, Standard_False);
1290   //
1291   iErr=0;
1292   aEpsT=1.e-12;
1293   //
1294   aFF=aF;
1295   aFF.Orientation (TopAbs_FORWARD);
1296   // 
1297   aS=BRep_Tool::Surface(aFF);
1298   BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
1299   //
1300   // 1
1301   aExp.Init (aFF, TopAbs_EDGE);
1302   for (; aExp.More() ; aExp.Next()) {
1303     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
1304     aOrE=aE.Orientation();
1305     //
1306     aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
1307     if (aC2D.IsNull() ) {
1308       iErr=1;
1309       return iErr;
1310     }
1311     if (fabs(aU1-aU2) < aEpsT) {
1312       iErr=2;
1313       return iErr;
1314     }
1315     //
1316     aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
1317     aHatcher.AddElement(aCT2D, aOrE);
1318   }// for (; aExp.More() ; aExp.Next()) {
1319   //
1320   // 2
1321   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
1322   aP2D.SetCoord(aUx, 0.);
1323   aL2D=new Geom2d_Line (aP2D, aD2D);
1324   Geom2dAdaptor_Curve aHCur(aL2D);
1325   //
1326   aIx=aHatcher.AddHatching(aHCur) ;
1327   //
1328   // 3.
1329   aHatcher.Trim();
1330   bIsDone=aHatcher.TrimDone(aIx);
1331   if (!bIsDone) {
1332     iErr=3;
1333     return iErr;
1334   }
1335   //
1336   aHatcher.ComputeDomains(aIx);
1337   bIsDone=aHatcher.IsDone(aIx);
1338   if (!bIsDone) {
1339     iErr=4;
1340     return iErr;
1341   }
1342   //
1343   // 4.
1344   aNbDomains=aHatcher.NbDomains(aIx);
1345   for (i=1; i<=aNbDomains; ++i) {
1346     const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
1347     bHasFirstPoint=aDomain.HasFirstPoint();
1348     if (!bHasFirstPoint) {
1349       iErr=5;
1350       return iErr;
1351     }
1352     //
1353     aV1=aDomain.FirstPoint().Parameter();
1354     //
1355     bHasSecondPoint=aDomain.HasSecondPoint();
1356     if (!bHasSecondPoint) {
1357       iErr=6;
1358       return iErr;
1359     }
1360     //
1361     aV2=aDomain.SecondPoint().Parameter();
1362     //
1363     aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
1364     //
1365     break;
1366   }
1367   //
1368   aS->D0(aUx, aVx, aPx);
1369   //
1370   theP2D.SetCoord(aUx, aVx);
1371   theP=aPx;
1372   //
1373   return iErr;
1374 }
1375 //modified by NIZNHY-PKV Tue Nov 22 10:37:01 2011t