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