0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_TOOL.cxx
1 // File:        TopOpeBRepTool_TOOL.cxx
2 // Created:     Thu Nov 26 10:53:41 1998
3 // Author:      Xuan PHAM PHU
4 //              <xpu@poulopox.paris1.matra-dtv.fr>
5
6
7 #include <TopOpeBRepTool_TOOL.ixx>
8 #include <BRepAdaptor_Curve.hxx>
9 #include <BRepAdaptor_Surface.hxx>
10 #include <TopExp.hxx>
11 #include <TopExp_Explorer.hxx>
12 #include <TopoDS.hxx>
13 #include <TopoDS_Iterator.hxx>
14 #include <Precision.hxx>
15 #include <BRep_Tool.hxx>
16 #include <BRep_Builder.hxx>
17 #include <Geom2d_Line.hxx>
18 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
19 #include <gp_Pln.hxx>
20 #include <gp_Cylinder.hxx>
21 #include <gp_Lin.hxx>
22 #include <gp_Circ.hxx>
23 #include <gp_Elips.hxx>
24 #include <gp_Hypr.hxx>
25 #include <gp_Parab.hxx>
26 #include <TopOpeBRepTool_define.hxx>
27 #include <TopOpeBRepTool.hxx>
28 #include <TopOpeBRepTool_EXPORT.hxx>
29 #include <TopOpeBRepTool_2d.hxx>
30 #include <TopOpeBRepTool_ShapeTool.hxx>
31 #include <TopTools_DataMapOfIntegerShape.hxx>
32 #include <TColStd_Array1OfReal.hxx>
33 #include <TColStd_IndexedMapOfReal.hxx>
34 #include <TCollection_CompareOfReal.hxx>
35 #include <SortTools_QuickSortOfReal.hxx>
36 #include <BRepLProp_CLProps.hxx>
37 #include <GeomLProp_SLProps.hxx>
38 #include <gp_Torus.hxx>
39 #include <gp_Cone.hxx>
40 #include <gp_Sphere.hxx>
41 #include <Bnd_Box.hxx>
42 #include <BRepBndLib.hxx>
43 #include <ElCLib.hxx>
44
45 #define M_FORWARD(sta)  (sta == TopAbs_FORWARD)
46 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
47 #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
48 #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
49
50 #define FORWARD  (1)
51 #define REVERSED (2)
52 #define INTERNAL (3)
53 #define EXTERNAL (4)
54 #define CLOSING  (5)
55
56 // Unused :
57 #ifdef DEB
58 static Standard_Real FUN_nullcurv(const Standard_Real curv)
59 {
60   Standard_Real tol = Precision::Confusion()*1.e+2; // NYI
61   return (curv < tol);
62 }
63 #endif
64 static Standard_Boolean FUN_nullprodv(const Standard_Real prodv)
65 {
66 //  Standard_Real tola = Precision::Angular()*1.e+1; // NYI
67   Standard_Real tola = 1.e-6; // NYI NYI NYI : for case cto 012 I2
68   return (Abs(prodv) < tola);
69 }
70
71 //modified by NIZNHY-PKV Fri Aug  4 11:22:57 2000 from
72
73 //=======================================================================
74 //function : CheckEdgeLength
75 //purpose  : 
76 //=======================================================================
77 static Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
78 {
79   BRepAdaptor_Curve BC(E);
80
81   TopTools_IndexedMapOfShape aM;
82   TopExp::MapShapes(E, TopAbs_VERTEX, aM);
83   Standard_Integer i, anExtent, aN=10;
84   Standard_Real ln=0., d, t, f, l, dt; 
85   anExtent=aM.Extent();
86
87   if (anExtent!=1) 
88     return Standard_True;
89     
90   gp_Pnt p1, p2;
91   f = BC.FirstParameter();
92   l = BC.LastParameter();
93   dt=(l-f)/aN;
94   
95   BC.D0(f, p1);
96   for (i=1; i<=aN; i++) {
97     t=f+i*dt;
98     
99     if (i==aN) 
100       BC.D0(l, p2);
101       else 
102         BC.D0(t, p2);
103     
104     d=p1.Distance(p2);
105     ln+=d;
106     p1=p2;
107   }
108   
109   return (ln > Precision::Confusion()); 
110 }
111
112 //modified by NIZNHY-PKV Fri Aug  4 11:23:07 2000 to
113
114 //=======================================================================
115 //function : OriinSor
116 //purpose  : 
117 //=======================================================================
118
119 Standard_Integer TopOpeBRepTool_TOOL::OriinSor(const TopoDS_Shape& sub, const TopoDS_Shape& S, const Standard_Boolean checkclo)
120 {
121   if (checkclo) {
122     Standard_Boolean Sclosed = Standard_False;
123     if      (S.ShapeType() == TopAbs_EDGE) {
124       if (sub.ShapeType() != TopAbs_VERTEX) return 0;
125       
126       TopoDS_Vertex vclo; Sclosed = TopOpeBRepTool_TOOL::ClosedE(TopoDS::Edge(S),vclo);
127       if (Sclosed) 
128         if (sub.IsSame(vclo)) return CLOSING;
129     }
130     else if (S.ShapeType() == TopAbs_FACE) {
131       if (sub.ShapeType() != TopAbs_EDGE) return 0;
132       
133       Sclosed = ClosedS(TopoDS::Face(S));
134       if (Sclosed) 
135         if (IsClosingE(TopoDS::Edge(sub),TopoDS::Face(S))) return CLOSING;
136     } 
137   }
138
139   TopExp_Explorer ex(S,sub.ShapeType());
140   for(; ex.More(); ex.Next()) {
141     const TopoDS_Shape& ssub = ex.Current();
142     Standard_Boolean same = ssub.IsSame(sub);
143     if (!same) continue;
144     TopAbs_Orientation osub = ssub.Orientation();
145     if      (M_FORWARD(osub))  return FORWARD;
146     else if (M_REVERSED(osub)) return REVERSED;
147     else if (M_INTERNAL(osub)) return INTERNAL;
148     else if (M_EXTERNAL(osub)) return EXTERNAL;
149   }
150   return 0;
151 }
152
153 //=======================================================================
154 //function : OriinSorclosed
155 //purpose  : 
156 //=======================================================================
157
158 Standard_Integer TopOpeBRepTool_TOOL::OriinSorclosed(const TopoDS_Shape& sub, const TopoDS_Shape& S)
159 {
160   if (S.ShapeType() == TopAbs_EDGE)
161     {if (sub.ShapeType() != TopAbs_VERTEX) return 0;}
162   else if (S.ShapeType() == TopAbs_FACE) 
163     {if (sub.ShapeType() != TopAbs_EDGE) return 0;}
164   TopoDS_Iterator it(S);
165   for(; it.More(); it.Next()) {
166     const TopoDS_Shape& ssub = it.Value();
167     Standard_Boolean equal = ssub.IsEqual(sub);
168     if (!equal) continue;
169     TopAbs_Orientation osub = ssub.Orientation();
170     if      (M_FORWARD(osub))  return FORWARD;
171     else if (M_REVERSED(osub)) return REVERSED;
172   }
173   return 0;
174 }
175
176
177
178 //=======================================================================
179 //function : ClosedE
180 //purpose  : 
181 //=======================================================================
182
183 Standard_Boolean TopOpeBRepTool_TOOL::ClosedE(const TopoDS_Edge& E, TopoDS_Vertex& vclo)
184 {
185    // returns true if <E> has a closing vertex <vclosing>
186 //  return E.IsClosed();
187   Standard_Boolean isdgE = BRep_Tool::Degenerated(E);
188   if (isdgE) return Standard_False;
189
190   TopoDS_Shape vv; vclo.Nullify();
191   TopExp_Explorer ex(E,TopAbs_VERTEX);
192   for (; ex.More(); ex.Next()) {
193     const TopoDS_Shape& v = ex.Current();
194     if (M_INTERNAL(v.Orientation())) continue;
195     if (vv.IsNull()) vv = v;
196     else if (v.IsSame(vv))
197       {vclo = TopoDS::Vertex(vv); return Standard_True;}
198   }
199   return Standard_False; 
200 }
201
202 //=======================================================================
203 //function : ClosedS
204 //purpose  : 
205 //=======================================================================
206
207 Standard_Boolean TopOpeBRepTool_TOOL::ClosedS(const TopoDS_Face& F)
208 {
209   Handle(Geom_Surface) S =TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
210   if (S.IsNull()) return Standard_False;
211   Standard_Boolean uclosed = S->IsUClosed(); if (uclosed) uclosed = S->IsUPeriodic();
212   Standard_Boolean vclosed = S->IsVClosed(); if (vclosed) vclosed = S->IsVPeriodic(); 
213   return (uclosed || vclosed);
214 }
215
216 //=======================================================================
217 //function : IsClosingE
218 //purpose  : 
219 //=======================================================================
220
221 Standard_Boolean TopOpeBRepTool_TOOL::IsClosingE(const TopoDS_Edge& E, const TopoDS_Face& F)
222 {
223   Standard_Integer nbocc = 0;
224   TopExp_Explorer exp(F,TopAbs_EDGE);
225   for (;exp.More();exp.Next()) 
226     if (exp.Current().IsSame(E)) nbocc++;
227   if (nbocc != 2) return Standard_False;
228   return BRep_Tool::IsClosed(E,F);  
229 }
230
231 //=======================================================================
232 //function : IsClosingE
233 //purpose  : 
234 //=======================================================================
235
236 Standard_Boolean TopOpeBRepTool_TOOL::IsClosingE(const TopoDS_Edge& E, const TopoDS_Shape& W, const TopoDS_Face& F)
237 {
238   Standard_Integer nbocc = 0;
239   TopExp_Explorer exp(W,TopAbs_EDGE);
240   for (;exp.More();exp.Next()) 
241     if (exp.Current().IsSame(E)) nbocc++;
242   if (nbocc != 2) return Standard_False;
243   return BRep_Tool::IsClosed(E,F);  
244 }
245
246 //=======================================================================
247 //function : Vertices
248 //purpose  : 
249 //=======================================================================
250
251 void TopOpeBRepTool_TOOL::Vertices(const TopoDS_Edge& E, TopTools_Array1OfShape& Vces)
252 {
253   // Returns vertices (F,R) if E is FORWARD
254   //                  (R,V) if E is REVERSED
255   TopAbs_Orientation oriE = E.Orientation();
256   TopoDS_Vertex v1, v2; TopExp::Vertices(E,v1,v2);
257
258   if (M_INTERNAL(oriE) || M_EXTERNAL(oriE)) 
259     {Vces.ChangeValue(1)=v1;Vces.ChangeValue(2)=v2;}
260
261   Standard_Real par1 = BRep_Tool::Parameter(v1,E);
262   Standard_Real par2 = BRep_Tool::Parameter(v2,E);
263 #ifdef DEB
264 //  if (par1>par2) cout<<"TopOpeBRepTool_TOOL::Vertices ERROR"<<endl;
265 #endif
266   Standard_Integer ivparSMA = (par1<par2) ? FORWARD : REVERSED; 
267   Standard_Integer ivparSUP = (par1<par2) ? REVERSED : FORWARD;
268   if (M_REVERSED(oriE)) {
269     ivparSMA = (ivparSMA == FORWARD) ? REVERSED : FORWARD;
270     ivparSUP = (ivparSUP == REVERSED) ? FORWARD : REVERSED;
271   }
272   Vces.ChangeValue(ivparSMA) = v1;
273   Vces.ChangeValue(ivparSUP) = v2;
274 }
275
276 //=======================================================================
277 //function : Vertex
278 //purpose  : 
279 //=======================================================================
280
281 TopoDS_Vertex TopOpeBRepTool_TOOL::Vertex(const Standard_Integer Iv, const TopoDS_Edge& E)
282 {  
283   TopTools_Array1OfShape Vces(1,2); Vertices(E,Vces);
284   TopoDS_Vertex V = TopoDS::Vertex(Vces(Iv));
285   return V;  
286 }
287
288 //=======================================================================
289 //function : ParE
290 //purpose  : 
291 //=======================================================================
292
293 Standard_Real TopOpeBRepTool_TOOL::ParE(const Standard_Integer Iv, const TopoDS_Edge& E)
294 {
295   const TopoDS_Vertex& v = Vertex(Iv,E);
296   return (BRep_Tool::Parameter(v,E));
297 }
298
299 //=======================================================================
300 //function : OnBoundary
301 //purpose  : 
302 //=======================================================================
303
304 Standard_Integer TopOpeBRepTool_TOOL::OnBoundary(const Standard_Real par, const TopoDS_Edge& e)
305 {
306   BRepAdaptor_Curve bc(e);
307   Standard_Boolean closed = bc.IsClosed();
308   Standard_Real first = bc.FirstParameter();
309   Standard_Real last = bc.LastParameter();
310   Standard_Real tole = bc.Tolerance(); Standard_Real tolp = bc.Resolution(tole);
311   
312   Standard_Boolean onf = Abs(par-first)<tolp;
313   Standard_Boolean onl = Abs(par-last)<tolp;
314   Standard_Boolean onfl =  (onf || onf);
315   if (onfl && closed) return CLOSING;
316   if (onf) return FORWARD;
317   if (onl) return REVERSED;
318   if ((first < par)&&(par < last)) return INTERNAL;
319   return EXTERNAL;
320 }
321
322
323
324 static void FUN_tool_sortVonE(TopTools_ListOfShape& lov, const TopoDS_Edge E)
325 {
326   TopTools_DataMapOfIntegerShape mapiv;// mapiv.Find(iV) = V
327   TColStd_IndexedMapOfReal mappar;     // mappar.FindIndex(parV) = iV
328   
329   for (TopTools_ListIteratorOfListOfShape itlove(lov); itlove.More(); itlove.Next()){
330     const TopoDS_Vertex& v = TopoDS::Vertex(itlove.Value());
331     Standard_Real par = BRep_Tool::Parameter(v,E);
332     Standard_Integer iv = mappar.Add(par);
333     mapiv.Bind(iv,v);
334   }
335   Standard_Integer nv = mapiv.Extent();
336   TColStd_Array1OfReal tabpar(1,nv);
337 //  for (Standard_Integer i = 1; i <= nv; i++) {
338   Standard_Integer i ;
339   for ( i = 1; i <= nv; i++) {
340     Standard_Real p = mappar.FindKey(i);
341     tabpar.SetValue(i,p);
342   }
343   
344   TopTools_ListOfShape newlov;
345   TCollection_CompareOfReal compare; SortTools_QuickSortOfReal::Sort(tabpar, compare);
346   for (i = 1; i <= nv; i++) {
347     Standard_Real par = tabpar.Value(i);
348     Standard_Integer iv = mappar.FindIndex(par);
349     const TopoDS_Shape& v = mapiv.Find(iv);
350     newlov.Append(v);
351   }
352   lov.Clear(); lov.Append(newlov);
353 }
354
355 //=======================================================================
356 //function : SplitE
357 //purpose  : 
358 //=======================================================================
359
360 Standard_Boolean TopOpeBRepTool_TOOL::SplitE(const TopoDS_Edge& Eanc, TopTools_ListOfShape& Splits)
361 {
362   // prequesitory : <Eanc> is a valid edge.
363   TopAbs_Orientation oEanc = Eanc.Orientation();
364   TopoDS_Shape aLocalShape = Eanc.Oriented(TopAbs_FORWARD);
365   TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
366 //  TopoDS_Edge EFOR = TopoDS::Edge(Eanc.Oriented(TopAbs_FORWARD));
367   TopTools_ListOfShape lov;
368   TopExp_Explorer exv(EFOR,TopAbs_VERTEX);  
369   for (;exv.More(); exv.Next()) {
370     const TopoDS_Shape& v = exv.Current();
371     lov.Append(v);
372   }
373   Standard_Integer nv = lov.Extent();
374   if (nv <= 2) return Standard_False;
375
376   ::FUN_tool_sortVonE(lov,EFOR);
377
378   TopoDS_Vertex v0;
379   TopTools_ListIteratorOfListOfShape itlov(lov);
380   if (itlov.More()) {v0 = TopoDS::Vertex(itlov.Value()); itlov.Next();}
381   else return Standard_False;
382
383   for (; itlov.More(); itlov.Next()) {
384     TopoDS_Vertex v = TopoDS::Vertex(itlov.Value());
385     
386     // prequesitory: par0 < par
387     Standard_Real par0 = BRep_Tool::Parameter(v0, EFOR);
388     Standard_Real par  = BRep_Tool::Parameter(v, EFOR);
389
390     // here, ed has the same geometries than Ein, but with no subshapes.
391     TopoDS_Edge ed; FUN_ds_CopyEdge(EFOR,ed);
392     BRep_Builder BB;
393     v0.Orientation(TopAbs_FORWARD); BB.Add(ed,v0); FUN_ds_Parameter(ed,v0,par0); 
394     v.Orientation(TopAbs_REVERSED); BB.Add(ed,v);  FUN_ds_Parameter(ed,v,par); 
395     Splits.Append(ed.Oriented(oEanc));
396     v0 = v;
397   }  
398   return Standard_True;   
399 }
400
401
402
403
404 //=======================================================================
405 //function : UVF
406 //purpose  : 
407 //=======================================================================
408
409 gp_Pnt2d TopOpeBRepTool_TOOL::UVF(const Standard_Real par, const TopOpeBRepTool_C2DF& C2DF)
410 {
411   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
412   gp_Pnt2d UV; PC->D0(par,UV);
413   return UV;
414 }
415
416 //=======================================================================
417 //function : ParISO
418 //purpose  : 
419 //=======================================================================
420
421 Standard_Boolean TopOpeBRepTool_TOOL::ParISO(const gp_Pnt2d& uv, const TopoDS_Edge& E, const TopoDS_Face& F, 
422                                 Standard_Real& par)
423 {
424   par = 1.e7;
425   Standard_Boolean isou,isov; gp_Dir2d d2d; gp_Pnt2d o2d;
426   Standard_Boolean uviso = TopOpeBRepTool_TOOL::UVISO(E,F, isou,isov, d2d,o2d);
427   if (!uviso) return Standard_False;
428   if (isou) {par = (uv.Y()-o2d.Y()); if (d2d.Y()<0) par = -par;}
429   if (isov) {par = (uv.X()-o2d.X()); if (d2d.X()<0) par = -par;}
430   return Standard_True;
431 }
432
433
434
435 //=======================================================================
436 //function : ParE2d
437 //purpose  : 
438 //=======================================================================
439
440 Standard_Boolean TopOpeBRepTool_TOOL::ParE2d(const gp_Pnt2d& p2d, const TopoDS_Edge& E, const TopoDS_Face& F, 
441                                 Standard_Real& par, Standard_Real& dist)
442 {
443   // Avoid projections if possible :
444   BRepAdaptor_Curve2d BC2d(E,F);
445   GeomAbs_CurveType CT = BC2d.GetType();
446   const Handle(Geom2d_Curve)& C2d = BC2d.Curve();
447   if (CT == GeomAbs_Line) {
448     Standard_Boolean isoU,isoV; gp_Pnt2d Loc; gp_Dir2d dir2d;
449     TopOpeBRepTool_TOOL::UVISO(C2d,isoU,isoV,dir2d,Loc);
450     if (isoU) {par = p2d.Y()-Loc.Y();dist = Abs(p2d.X()-Loc.X());}
451     if (isoV) {par = p2d.X()-Loc.X();dist = Abs(p2d.Y()-Loc.Y());}
452     if (isoU || isoV) return Standard_True;
453   }  
454
455   Geom2dAPI_ProjectPointOnCurve proj(p2d,C2d);
456   dist = p2d.Distance(proj.NearestPoint()); 
457   par = proj.LowerDistanceParameter();
458   return Standard_True;
459 }
460
461
462
463 //=======================================================================
464 //function : TgINSIDE
465 //purpose  : 
466 //=======================================================================
467
468 Standard_Boolean TopOpeBRepTool_TOOL::TgINSIDE(const TopoDS_Vertex& v, const TopoDS_Edge& E,
469                                   gp_Vec& Tg, Standard_Integer& OvinE)
470 {
471   TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
472   TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
473 //  TopoDS_Edge EFOR = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
474   Standard_Integer ovE = TopOpeBRepTool_TOOL::OriinSor(v,EFOR,Standard_True);
475   if (ovE == 0) return Standard_False;
476   OvinE = ovE;
477   Standard_Integer iv = 0;
478   if      (ovE == CLOSING)                      iv = FORWARD;
479   else if ((ovE == FORWARD)||(ovE == REVERSED)) iv = ovE;    
480   Standard_Real parE;
481   if (iv == 0) parE = BRep_Tool::Parameter(v,E);
482   else         parE = TopOpeBRepTool_TOOL::ParE(iv,EFOR);
483   Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(parE,EFOR,Tg);
484   if (!ok) return Standard_False;
485   if (ovE == REVERSED) Tg.Reverse();
486   return Standard_True;
487 }
488
489 //=======================================================================
490 //function : TggeomE
491 //purpose  : 
492 //=======================================================================
493
494 Standard_Boolean TopOpeBRepTool_TOOL::TggeomE(const Standard_Real par, const BRepAdaptor_Curve& BC, 
495                                  gp_Vec& Tg)
496 {
497 #ifdef DEB
498   GeomAbs_CurveType ct =
499 #endif
500                          BC.GetType();
501 #ifdef DEB
502   Standard_Boolean apoles = (ct == GeomAbs_BezierCurve)||(ct == GeomAbs_BSplineCurve);
503 #endif
504   
505   Standard_Real f = BC.FirstParameter(), l = BC.LastParameter();
506   Standard_Real tolE = BC.Tolerance(); Standard_Real tolp = BC.Resolution(tolE);
507   
508   Standard_Boolean onf = Abs(f-par)<tolp; Standard_Boolean onl = Abs(l-par)<tolp; 
509   Standard_Boolean inbounds = (f<par)&&(par<l);
510
511   if ((!inbounds) && (!onf) && (!onl)) return Standard_False;
512   Standard_Real thepar = par;
513 //  if (apoles && (onf || onl)) thepar = onf ? (thepar+tolp) : (thepar-tolp);
514
515   gp_Pnt thepnt; BC.D1(thepar, thepnt, Tg);
516   Tg.Normalize(); 
517   return Standard_True;
518   
519 }
520
521 //=======================================================================
522 //function : TggeomE
523 //purpose  : 
524 //=======================================================================
525
526 Standard_Boolean TopOpeBRepTool_TOOL::TggeomE(const Standard_Real par, const TopoDS_Edge& E, gp_Vec& Tg)
527 {
528   Standard_Boolean isdgE = BRep_Tool::Degenerated(E); 
529   if (isdgE) return Standard_False;
530   
531   BRepAdaptor_Curve BC(E);
532   //modified by NIZNHY-PKV Fri Aug  4 09:49:31 2000 f
533   if (!CheckEdgeLength(E)) {
534     return Standard_False;
535   }
536   //modified by NIZNHY-PKV Fri Aug  4 09:49:36 2000 t
537   
538   return (TopOpeBRepTool_TOOL::TggeomE(par,BC,Tg));
539 }
540
541 //=======================================================================
542 //function : Tg2d
543 //purpose  : 
544 //=======================================================================
545
546 gp_Vec2d TopOpeBRepTool_TOOL::Tg2d(const Standard_Integer iv, const TopoDS_Edge& E,
547                                    const TopOpeBRepTool_C2DF& C2DF)
548 {
549   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
550   Standard_Real par = TopOpeBRepTool_TOOL::ParE(iv,E);
551   gp_Pnt2d UV; gp_Vec2d tg2d; PC->D1(par,UV,tg2d);
552   gp_Dir2d d2d(tg2d);
553   return d2d;
554
555
556 //=======================================================================
557 //function : Tg2dApp
558 //purpose  : 
559 //=======================================================================
560
561 gp_Vec2d TopOpeBRepTool_TOOL::Tg2dApp(const Standard_Integer iv, const TopoDS_Edge& E,
562                                       const TopOpeBRepTool_C2DF& C2DF, 
563                                       const Standard_Real factor)
564 {
565   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
566
567   Standard_Integer iOOv  = (iv == 1) ? 2 : 1;
568   Standard_Real par = TopOpeBRepTool_TOOL::ParE(iv,E);
569   Standard_Real OOpar = TopOpeBRepTool_TOOL::ParE(iOOv,E);
570   Standard_Real parE = (1-factor)*par + factor*OOpar;
571
572   gp_Pnt2d UV; gp_Vec2d tg2d; PC->D1(parE,UV,tg2d);
573   gp_Dir2d d2d(tg2d);
574
575 //modified by NIZHNY-MZV  Wed May 24 12:52:18 2000  
576 //  TopAbs_Orientation oE = E.Orientation();
577 //  if (M_REVERSED(oE)) d2d.Reverse();
578 //we remove this line because we want to know original tangent
579   return d2d;
580 }
581
582 //=======================================================================
583 //function : tryTg2dApp
584 //purpose  : 
585 //=======================================================================
586
587 gp_Vec2d TopOpeBRepTool_TOOL::tryTg2dApp(const Standard_Integer iv, const TopoDS_Edge& E,
588                                          const TopOpeBRepTool_C2DF& C2DF, 
589                                          const Standard_Real factor)
590 {
591   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
592   Standard_Boolean isquad = FUN_tool_quad(PC);
593   Standard_Boolean line   = FUN_tool_line(PC);
594   if (!isquad || line) return TopOpeBRepTool_TOOL::Tg2d(iv,E,C2DF);
595   return TopOpeBRepTool_TOOL::Tg2dApp(iv,E,C2DF,factor);
596 }
597
598 //=======================================================================
599 //function : OriEinF
600 //purpose  : 
601 //=======================================================================
602
603 Standard_Integer TopOpeBRepTool_TOOL::tryOriEinF(const Standard_Real par, const TopoDS_Edge& e, const TopoDS_Face& f)
604 {  
605   // ------------------------------------------------------------
606   // 1) <e> is a subshape of <f> 
607   // 2) else, compute oriEinF, using <e>'s 2d rep on <f>
608   //    PREQUESITORY : <e> must have a pcurve on <f>.
609   // ------------------------------------------------------------
610   Standard_Boolean checkclo = Standard_True; Standard_Integer oeinf = TopOpeBRepTool_TOOL::OriinSor(e,f,checkclo);
611   if (oeinf != 0) return oeinf;
612
613   Handle(Geom2d_Curve) pc; Standard_Real pf,pl,tol;
614   Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(e,f,pc);
615   if (!hasold) return 0;
616   pc = FC2D_EditableCurveOnSurface(e,f,pf,pl,tol);
617   
618   // n2d is such that (p2d,oop2d) is oriented INSIDE F
619   gp_Pnt2d uv; gp_Vec2d tg2d; pc->D1(par,uv,tg2d);
620   gp_Vec2d n2d(gp_Dir2d(-tg2d.Y(), tg2d.X()));
621
622   Standard_Real delta = TopOpeBRepTool_TOOL::minDUV(f); delta *= 1.e-1; 
623   gp_Pnt2d ouv = uv.Translated(delta*n2d);
624   Standard_Boolean outuvbounds = TopOpeBRepTool_TOOL::outUVbounds(ouv,f); 
625   oeinf = (outuvbounds) ? 2 : 1;
626   return oeinf;
627 }
628
629 //=======================================================================
630 //function : NgApp
631 //purpose  : 
632 //=======================================================================
633
634 Standard_Boolean TopOpeBRepTool_TOOL::NgApp(const Standard_Real par,const TopoDS_Edge& e, const TopoDS_Face& f,const Standard_Real tola,
635                                gp_Dir& ngApp)
636 {
637   // Give us an edge <e>, a face <f>, <e> has its geometry on <f>.
638   //
639   // P is the point of <par> on <e>
640   // purpose : the compute of <neinsidef>, at a point P' on <F>, near P
641   //           direction pp' is normal to <e>.
642   // return false if the compute fails, or <neinsidef> is closed to <newneinsidef>
643   //
644   // PREQUESITORY : <e> must have a pcurve on <f>.
645   // --------------
646
647   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(f);
648   if (S.IsNull()) return Standard_False;  
649
650   Standard_Boolean fplane = FUN_tool_plane(f);
651   if (fplane) return Standard_False;
652
653   // NYI : for bspline surfaces, use a evolutive parameter
654   //       on curve to find out "significant" tangents
655   Standard_Boolean fquad = FUN_tool_quad(f);
656   if (!fquad) return Standard_False;
657   // <pc> : 
658   Handle(Geom2d_Curve) pc; Standard_Real pf,pl,tol;
659   Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(e,f,pc);
660   if (!hasold) return Standard_False;
661   pc = FC2D_EditableCurveOnSurface(e,f,pf,pl,tol);
662   // <orieinf> : 
663   TopoDS_Shape aLocalShape = f.Oriented(TopAbs_FORWARD);  
664   Standard_Integer orieinf = TopOpeBRepTool_TOOL::tryOriEinF(par,e,TopoDS::Face(aLocalShape));
665 //  Standard_Integer orieinf = TopOpeBRepTool_TOOL::tryOriEinF(par,e,TopoDS::Face(f.Oriented(TopAbs_FORWARD)));
666   if (orieinf == 0) return Standard_False;
667   // <uv> : 
668   gp_Pnt2d uv; Standard_Boolean ok = FUN_tool_paronEF(e,par,f,uv);
669   if (!ok) return Standard_False;
670   // <ng> : 
671   gp_Dir ng = FUN_tool_ngS(uv,S);
672   if (!ok) return Standard_False;
673   
674   // <n2dinsideS> :
675   gp_Vec2d tg2d; pc->D1(par,uv,tg2d); 
676   gp_Dir2d n2dinsideS = FUN_tool_nC2dINSIDES( gp_Dir2d(tg2d) );
677   if (orieinf == 2)  n2dinsideS.Reverse();
678   //<duv> : '
679   Standard_Real eps = 0.45678; 
680   gp_Vec2d duv = gp_Vec2d(n2dinsideS).Multiplied(eps);
681
682   // cto009S4 : we need an iterative process to get other normal vector
683   Standard_Integer nmax = 5; Standard_Boolean same = Standard_False; Standard_Real delta = 0.45678;
684   for (Standard_Integer i=1; i<=nmax; i++) {
685
686     gp_Pnt2d newuv = uv.Translated(duv);
687     gp_Vec newng = FUN_tool_ngS(newuv,S);
688     same = ng.IsEqual(newng,tola);
689     Standard_Boolean okk = (newng.Magnitude() > tola);
690     if (!same && okk) {ngApp = gp_Dir(newng); break;}
691     delta *= 1.25; //  NYI
692     duv = gp_Vec2d(n2dinsideS).Multiplied(delta);  
693
694   }//i=1..nmax
695   return !same;
696 }
697
698 //=======================================================================
699 //function : tryNgApp
700 //purpose  : 
701 //=======================================================================
702
703 Standard_Boolean TopOpeBRepTool_TOOL::tryNgApp(const Standard_Real par,const TopoDS_Edge& e, const TopoDS_Face& f,const Standard_Real tola,
704                                   gp_Dir& Ng)
705 {
706   gp_Pnt2d uv; Standard_Boolean ok = FUN_tool_paronEF(e,par,f,uv);
707   if (!ok) return Standard_False;
708   gp_Dir ng( FUN_tool_nggeomF(uv,f) );  
709 #ifdef DEB
710   gp_Dir ngApp;
711 #endif
712   ok = TopOpeBRepTool_TOOL::NgApp(par,e,f,tola,Ng);
713   if (!ok) Ng = ng;
714   return Standard_True;
715 }
716
717 //=======================================================================
718 //function : IsQuad
719 //purpose  : 
720 //=======================================================================
721
722 Standard_Boolean TopOpeBRepTool_TOOL::IsQuad(const TopoDS_Edge& E)
723 {
724   BRepAdaptor_Curve bc(E);
725   return ( FUN_quadCT(bc.GetType()) );
726 }
727
728
729 //=======================================================================
730 //function : IsQuad
731 //purpose  : 
732 //=======================================================================
733
734 Standard_Boolean TopOpeBRepTool_TOOL::IsQuad(const TopoDS_Face& F)
735 {
736   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(F);
737   return ( FUN_tool_quad(S) );
738 }
739
740
741
742 //=======================================================================
743 //function : CurvE
744 //purpose  : 
745 //=======================================================================
746
747 Standard_Boolean TopOpeBRepTool_TOOL::CurvE(const TopoDS_Edge& E,const Standard_Real par,const gp_Dir& tg0,
748                                Standard_Real& curv)
749 {
750   curv = 0.;
751   BRepAdaptor_Curve BAC(E);
752   GeomAbs_CurveType CT = BAC.GetType();
753   Standard_Boolean line = (CT == GeomAbs_Line);
754   Standard_Real tola = Precision::Angular()*1.e3;//NYITOLXPU
755   if (line) {
756     gp_Dir dir = BAC.Line().Direction();
757     Standard_Real dot = dir.Dot(tg0);
758     if (Abs(1-dot) < tola) return Standard_False;
759     return Standard_True;
760   }
761
762   BRepLProp_CLProps clprops(BAC,par,2,Precision::Confusion());
763   Standard_Boolean tgdef = clprops.IsTangentDefined();
764   if (!tgdef) return Standard_False;
765   curv = Abs(clprops.Curvature());
766
767   Standard_Real tol = Precision::Confusion()*1.e+2;//NYITOLXPU
768   Standard_Boolean nullcurv = (curv < tol);
769   if (nullcurv) {curv = 0.; return Standard_True;}
770
771   gp_Dir N; clprops.Normal(N);
772   gp_Dir T; clprops.Tangent(T);
773   gp_Dir axis = N^T;
774   Standard_Real dot = Abs(axis.Dot(tg0));
775   nullcurv = dot < tola;
776   Standard_Boolean maxcurv  = Abs(1-dot) < tola;
777   if (nullcurv) {
778     curv = 0.;
779     return Standard_True;
780   }
781   if (maxcurv) {
782     return Standard_True;
783   }
784   return Standard_False; // nyi general case
785 }
786
787
788 // ================================================================================
789 //   In 3d space, give us a curve <C> and a surface <S>,
790 //   <C> is tangent to <S> at point P0 = <uv0> on <S> ,
791 //   <tgC> = C's tangent at P0,
792 //   <ngS> = <S>'s normal at P0.
793
794 //   These define a plane thePlane = (O = P0, XY = (<ngS>,<tgC>)), 
795 //   the projection of <S> in thePlane describes an apparent contour theContour.
796
797 //   In thePlane :
798 //   P0 -> p2d0 
799 //   <ngS> -> 2d axis x
800 //   <tgC> -> 2d axis y
801
802 //   <C> -> C2d (same curvature)
803 //   <S>'s contour -> theContour
804 //   - the half3dspace described by (<S>,<ngS>) -> the half2dspace described by (theContour,x)
805
806 //   if (<tgC>.<ngS> = 0.) : (X,Y) are normal vectors
807 //                           (x,y) are normal vectors
808 // ================================================================================
809 static Standard_Boolean FUN_analyticcS(const gp_Pnt2d& uv0, const Handle(Geom_Surface)& S, const gp_Dir& ngS,
810                           const gp_Dir& tg0, 
811                           Standard_Real& curv, Standard_Boolean& direct) // dummy if !analyticcontour
812 {
813   curv = 0.; direct = Standard_True; 
814   // purpose : Returns true if theContour is analytic, and
815   //           then computes its curvature <curv>.
816   Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(S);
817   if (S.IsNull()) return Standard_True;
818   GeomAdaptor_Surface GS(su);
819   GeomAbs_SurfaceType ST = GS.GetType();
820   Standard_Boolean plane = (ST == GeomAbs_Plane);
821   Standard_Boolean cyl   = (ST == GeomAbs_Cylinder);
822   Standard_Boolean cone  = (ST == GeomAbs_Cone);
823   Standard_Boolean sphe  = (ST == GeomAbs_Sphere);
824   Standard_Boolean torus  = (ST == GeomAbs_Torus);
825   
826   Standard_Boolean curvdone = Standard_False;
827   if (plane) {curv = 0.; curvdone = Standard_True;}
828   if (cyl || cone || torus){
829     gp_Dir axis;
830     if (cyl) {
831       const gp_Cylinder& cycy = GS.Cylinder();
832       axis = cycy.Axis().Direction();
833       direct = cycy.Direct();
834     }
835     if (cone) {
836       const gp_Cone& coco = GS.Cone();
837       axis = coco.Axis().Direction();
838       direct = coco.Direct();
839     }
840     if (torus) {
841       const gp_Torus& toto = GS.Torus();
842       axis = toto.Axis().Direction();
843       direct = toto.Direct();
844     }
845     Standard_Real prod = axis.Dot(tg0);
846     Standard_Boolean maxAcurv  = FUN_nullprodv(1-Abs(prod));
847     Standard_Boolean nullcurv = FUN_nullprodv(prod);
848
849     Standard_Real prod2 = ngS.Dot(tg0);
850     if (cyl || cone) nullcurv = nullcurv || FUN_nullprodv(1-Abs(prod2));
851
852     if (nullcurv) {curv = 0.; curvdone = Standard_True;}
853     if (maxAcurv)  {
854       GeomLProp_SLProps slprops(S,uv0.X(),uv0.Y(),2,Precision::Confusion());
855       Standard_Boolean curdef = slprops.IsCurvatureDefined();
856       if (curdef) {
857         Standard_Real minAcurv = Abs(slprops.MinCurvature());
858         Standard_Real maxAcurv = Abs(slprops.MaxCurvature()); 
859         Standard_Boolean isAmax = (maxAcurv > minAcurv);
860         curv = isAmax ? maxAcurv : minAcurv;
861       }
862       curvdone = Standard_True;
863     }
864   }
865   if (sphe) {
866     const gp_Sphere& spsp = GS.Sphere();    
867     curv = 1./spsp.Radius(); curvdone = Standard_True;
868     direct = spsp.Direct();
869   }
870
871   return curvdone;
872 }
873 //=======================================================================
874 //function : CurvF
875 //purpose  : 
876 //=======================================================================
877
878 Standard_Boolean TopOpeBRepTool_TOOL::CurvF(const TopoDS_Face& F,const gp_Pnt2d& uv,const gp_Dir& tg0,
879                                Standard_Real& curv,Standard_Boolean& direct)
880 {
881   curv = 0.;
882   gp_Dir ngS = FUN_tool_nggeomF(uv,F);
883   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(F);  
884   if (S.IsNull()) return Standard_False;
885   // purpose : Computes theContour's curvature,
886   //          returns false if the compute fails.
887   
888   Standard_Real tola = 1.e-6;//NYITOLXPU
889
890   Standard_Boolean analyticcontour = FUN_analyticcS(uv,S,ngS,tg0,curv,direct);
891   if (analyticcontour) return Standard_True;
892
893   GeomLProp_SLProps slprops(S,uv.X(),uv.Y(),2,Precision::Confusion());
894   Standard_Boolean curdef = slprops.IsCurvatureDefined();
895   if (curdef) {
896     gp_Dir npl = tg0;
897
898     gp_Dir MaxD, MinD; slprops.CurvatureDirections(MaxD, MinD);
899     Standard_Real mincurv = slprops.MinCurvature();
900     Standard_Real maxcurv = slprops.MaxCurvature();
901     
902     gp_Vec Dmax=ngS^MaxD, Dmin=ngS^MinD; //xpu180898 : cto015G2
903     Standard_Real dotmax = Dmax.Dot(npl);//MaxD.Dot(npl); -xpu180898
904     Standard_Boolean iscurmax = Abs(1-dotmax)<tola;
905     if (iscurmax) {direct = (maxcurv < 0.); curv = Abs(maxcurv);}
906     Standard_Real dotmin = Dmin.Dot(npl);//MinD.Dot(npl); -xpu180898
907     Standard_Boolean iscurmin = Abs(1-dotmin)<tola;
908     if (iscurmin) {direct = (mincurv < 0.); curv = Abs(mincurv);}
909     curdef = iscurmax || iscurmin;
910     // -------------
911     // NYI : !curdef
912     // -------------
913   }
914   return curdef; 
915 }
916
917
918
919 //=======================================================================
920 //function : UVISO
921 //purpose  : 
922 //=======================================================================
923
924 Standard_Boolean TopOpeBRepTool_TOOL::UVISO(const Handle(Geom2d_Curve)& PC,
925                                Standard_Boolean& isoU, Standard_Boolean& isoV, gp_Dir2d& d2d, gp_Pnt2d& o2d)
926 {
927   isoU = isoV = Standard_False;
928   if (PC.IsNull()) return Standard_False;
929   Handle(Geom2d_Curve) LLL = BASISCURVE2D(PC);
930   Handle(Standard_Type) T2 = LLL->DynamicType();
931   Standard_Boolean isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
932   if (!isline2d) return Standard_False;
933
934   Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(LLL);
935   d2d = L->Direction();
936   isoU = (Abs(d2d.X()) < Precision::Parametric(Precision::Confusion()));
937   isoV = (Abs(d2d.Y()) < Precision::Parametric(Precision::Confusion()));
938   Standard_Boolean isoUV = isoU || isoV;
939   if (!isoUV) return Standard_False;
940
941   o2d = L->Location();
942   return Standard_True;
943 }
944
945 Standard_Boolean TopOpeBRepTool_TOOL::UVISO(const TopoDS_Edge& E, const TopoDS_Face& F,
946                                Standard_Boolean & isoU, Standard_Boolean& isoV, gp_Dir2d& d2d, gp_Pnt2d& o2d)
947 {
948   //  Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,f,l,tol);
949   Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
950   Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,PC);
951 #ifdef DEB
952   Standard_Boolean hasnew =
953 #endif
954                FC2D_HasNewCurveOnSurface(E,F,PC);
955   PC = FC2D_EditableCurveOnSurface(E,F,f,l,tol);
956   if (!hasold) FC2D_AddNewCurveOnSurface(PC,E,F,f,l,tol);
957   
958   Standard_Boolean iso = UVISO(PC,isoU,isoV,d2d,o2d);  
959   return iso;
960 }
961
962 Standard_Boolean TopOpeBRepTool_TOOL::UVISO(const TopOpeBRepTool_C2DF& C2DF,
963                                Standard_Boolean & isoU, Standard_Boolean& isoV, gp_Dir2d& d2d, gp_Pnt2d& o2d)
964 {
965   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
966 //#ifdef DEB
967 //  const iso = UVISO(PC,isoU,isoV,d2d,o2d);
968 //#else
969   const Standard_Boolean iso = UVISO(PC,isoU,isoV,d2d,o2d);
970 //#endif
971   return iso;
972 }
973
974
975 //=======================================================================
976 //function : IsonCLO
977 //purpose  : 
978 //=======================================================================
979
980 Standard_Boolean TopOpeBRepTool_TOOL::IsonCLO(const Handle(Geom2d_Curve)& PC,
981                                  const Standard_Boolean onU, const Standard_Real xfirst, const Standard_Real xperiod, const Standard_Real xtol)
982 {
983   Standard_Boolean isou,isov; gp_Pnt2d o2d; gp_Dir2d d2d; 
984   Standard_Boolean isouv = UVISO(PC,isou,isov,d2d,o2d);  
985   if (!isouv) return Standard_False;
986   Standard_Boolean onX = (onU && isou) || ((!onU) && isov);
987   if (!onX) return Standard_False;
988   Standard_Real dxx=0;
989   if (onU) dxx = Abs(o2d.X()-xfirst);
990   else     dxx = Abs(o2d.Y()-xfirst);
991
992   Standard_Boolean onclo = (dxx < xtol);
993   onclo = onclo || (Abs(xperiod-dxx) < xtol);
994   return onclo;
995 }
996 Standard_Boolean TopOpeBRepTool_TOOL::IsonCLO(const TopOpeBRepTool_C2DF& C2DF,
997                                  const Standard_Boolean onU, const Standard_Real xfirst, const Standard_Real xperiod, const Standard_Real xtol)
998 {
999   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
1000   Standard_Boolean onclo = IsonCLO(PC,onU,xfirst,xperiod,xtol);
1001   return onclo;
1002 }
1003
1004 //=======================================================================
1005 //function : TrslUV
1006 //purpose  : 
1007 //=======================================================================
1008
1009 void TopOpeBRepTool_TOOL::TrslUV(const gp_Vec2d& t2d, TopOpeBRepTool_C2DF& C2DF)
1010 {
1011   Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = C2DF.PC(f,l,tol);
1012   PC->Translate(t2d);
1013   C2DF.SetPC(PC,f,l,tol);
1014 }
1015
1016 Standard_Boolean TopOpeBRepTool_TOOL::TrslUVModifE(const gp_Vec2d& t2d, const TopoDS_Face& F, TopoDS_Edge& E)
1017 {
1018   Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,f,l,tol);
1019 //  Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
1020
1021   if (PC.IsNull()) return Standard_False;
1022   PC->Translate(t2d);
1023 //  Handle(Geom2d_Curve) toclear; BB.UpdateEdge(E,toclear,F,tole);
1024   BRep_Builder BB; BB.UpdateEdge(E,PC,F,tol);    
1025   return Standard_True;
1026 }
1027
1028 //=======================================================================
1029 //function : Matter
1030 //purpose  : 
1031 //=======================================================================
1032
1033 Standard_Real TopOpeBRepTool_TOOL::Matter(const gp_Vec& d1, const gp_Vec& dR2, const gp_Vec& Ref)
1034 {
1035   gp_Vec d2 = dR2.Reversed();
1036
1037   Standard_Real tola = Precision::Angular();
1038   Standard_Real ang = d1.Angle(d2);
1039   Standard_Boolean equal = (ang < tola);
1040   if (equal) return 0.;
1041   Standard_Boolean oppo = ((M_PI-ang) < tola);
1042   if (oppo)  return M_PI;
1043
1044   ang = d1.AngleWithRef(d2,Ref);
1045   if (ang < 0) ang = 2.*M_PI+ang;    
1046   return ang;
1047 }
1048
1049 //=======================================================================
1050 //function : Matter
1051 //purpose  : 
1052 //=======================================================================
1053
1054 Standard_Real TopOpeBRepTool_TOOL::Matter(const gp_Vec2d& d1, const gp_Vec2d& dR2)
1055 {
1056   gp_Vec v1 = gp_Vec(d1.X(),d1.Y(),0.);
1057   gp_Vec vR2 = gp_Vec(dR2.X(),dR2.Y(),0.);
1058   gp_Vec Ref(0.,0.,1.);
1059
1060   Standard_Real ang = TopOpeBRepTool_TOOL::Matter(v1,vR2,Ref);
1061   return ang;
1062 }
1063
1064 //=======================================================================
1065 //function : Matter
1066 //purpose  : 
1067 //=======================================================================
1068
1069 Standard_Boolean TopOpeBRepTool_TOOL::Matter(const gp_Dir& xx1,const gp_Dir& nt1,
1070                                 const gp_Dir& xx2,const gp_Dir& nt2,
1071                                 const Standard_Real tola, Standard_Real& ang)
1072 // purpose : the compute of MatterAng(f1,f2)
1073 {
1074   // --------------------------------------------------
1075   // Give us a face f1 and one edge e of f1, pone=pnt(e,pare) 
1076   // We project the problem in a plane normal to e, at point pone 
1077   // ie we see the problem in space (x,y), with RONd (x,y,z), z tangent to e at pone.
1078   // RONd (x,y,z) = (xx1,nt1,x^y)
1079   // 
1080   // Make the analogy : 
1081   // f <-> Ef, e <-> Ve, 
1082   // In view (x,y), f1 is seen as an edge Ef, e is seen as a vertex Ve,
1083   // the matter delimited by f can be seen as the one delimited by Ef.
1084   // --------------------------------------------------
1085
1086   // Sign( (v1^nt1).z ) describes Ve's orientation in Ef1
1087   // (v1^nt1).z > 0. => Ve is oriented REVERSED in Ef1.
1088   // - ori(Ve,Ef1) == REVERSED : the matter delimited by <f1> 
1089   //                              is (y<=0) in (x,y) 2d space -
1090
1091   gp_Dir z1 = xx1^nt1;
1092   gp_Dir z2 = xx2^nt2;
1093   Standard_Real dot = z2.Dot(z1);
1094   Standard_Boolean oppo = (dot < 0.);
1095   if (!oppo) return Standard_False;
1096
1097   // -nti points towards 3dmatter(fi)
1098   // => zi = xxi^nti gives the opposite sense for the compute of the matter angle
1099   z1.Reverse();
1100   ang = xx1.AngleWithRef(xx2,z1);
1101   if (Abs(ang) < tola) {ang = 0.; return Standard_True;}
1102   if (ang < 0) ang = 2.*M_PI+ang; 
1103   
1104   return Standard_True;
1105 }
1106
1107 //=======================================================================
1108 //function : Getduv
1109 //purpose  : 
1110 //=======================================================================
1111
1112 Standard_Boolean TopOpeBRepTool_TOOL::Getduv(const TopoDS_Face& f,const gp_Pnt2d& uv,const gp_Vec& dir,
1113                                 const Standard_Real factor, gp_Dir2d& duv)
1114 {
1115   Standard_Boolean quad = TopOpeBRepTool_TOOL::IsQuad(f);
1116   if (!quad) return Standard_False;
1117   Bnd_Box bndf; BRepBndLib::AddClose(f,bndf);
1118   Standard_Real f1,f2,f3,l1,l2,l3; bndf.Get(f1,f2,f3,l1,l2,l3);
1119   gp_Vec d123(f1-l1, f2-l2, f3-l3);
1120 #ifdef DEB
1121   Standard_Real dmax =
1122 #endif
1123              d123.Dot(dir);
1124
1125   gp_Pnt p; FUN_tool_value(uv,f,p); p.Translate(dir.Multiplied(factor));
1126   Standard_Real d; gp_Pnt2d uvtr;
1127 #ifdef DEB
1128   Standard_Boolean ok =
1129 #endif
1130            FUN_tool_projPonF(p,f, uvtr,d);
1131   Standard_Real tolf = BRep_Tool::Tolerance(f); tolf *= 1.e2; //NYIXPUTOL
1132   if (d > tolf) return Standard_False;
1133
1134   gp_Vec2d DUV( uv, uvtr );
1135   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(f);
1136   if ((S->IsUPeriodic()) && (Abs(DUV.X()) > S->UPeriod()/2.))
1137     {
1138       Standard_Real U1 = uv.X(), U2 = uvtr.X(), period = S->UPeriod();
1139       ElCLib::AdjustPeriodic( 0., period, Precision::PConfusion(), U1, U2 );
1140       Standard_Real dx = U2-U1;
1141       if (dx > period/2.)
1142         dx -= period;
1143       DUV.SetX( dx );
1144     }
1145   if ((S->IsVPeriodic()) && (Abs(DUV.Y()) > S->VPeriod()/2.))
1146     {
1147       Standard_Real V1 = uv.Y(), V2 = uvtr.Y(), period = S->VPeriod();
1148       ElCLib::AdjustPeriodic( 0., period, Precision::PConfusion(), V1, V2 );
1149       Standard_Real dy = V2-V1;
1150       if (dy > period/2.)
1151         dy -= period;
1152       DUV.SetY( dy );
1153     }
1154   duv = gp_Dir2d( DUV );
1155
1156   return Standard_True;
1157 }
1158
1159
1160
1161 //=======================================================================
1162 //function : uvApp
1163 //purpose  : 
1164 //=======================================================================
1165
1166 Standard_Boolean TopOpeBRepTool_TOOL::uvApp(const TopoDS_Face& f,const TopoDS_Edge& e,const Standard_Real pare,const Standard_Real eps,
1167                                gp_Pnt2d& uvapp)
1168 {
1169   // uv : 
1170   Standard_Boolean ok = FUN_tool_paronEF(e,pare,f,uvapp);
1171   if (!ok) return Standard_False;
1172   gp_Vec2d dxx; ok = FUN_tool_getdxx(f,e,pare,dxx);
1173   if (!ok) return Standard_False;
1174   uvapp.Translate(dxx.Multiplied(eps));
1175   return Standard_True;
1176 }
1177
1178 //=======================================================================
1179 //function : XX
1180 //purpose  : 
1181 //=======================================================================
1182
1183 Standard_Boolean TopOpeBRepTool_TOOL::XX(const gp_Pnt2d& uv, const TopoDS_Face& f,
1184                             const Standard_Real par, const TopoDS_Edge& e, 
1185                             gp_Dir& XX)
1186 {
1187   // ng(uv):
1188   gp_Vec ng = FUN_tool_nggeomF(uv,f);
1189   gp_Vec geomxx = FUN_tool_getgeomxx(f,e,par,ng); 
1190
1191   Standard_Real tol = Precision::Confusion()*1.e2;//NYITOL
1192   Standard_Boolean nullng = (geomxx.Magnitude()<tol);
1193   if (nullng) return Standard_False;
1194  
1195   TopAbs_Orientation oef; Standard_Boolean ok = FUN_tool_orientEinFFORWARD(e,f,oef);
1196   if (!ok) return Standard_False;
1197   XX = gp_Dir(geomxx);
1198   if (M_REVERSED(oef)) XX.Reverse();
1199   return Standard_True;
1200 }
1201
1202 //=======================================================================
1203 //function : Nt
1204 //purpose  : 
1205 //=======================================================================
1206
1207 Standard_Boolean TopOpeBRepTool_TOOL::Nt(const gp_Pnt2d& uv, const TopoDS_Face& f,
1208                             gp_Dir& normt)
1209 {
1210   gp_Vec nggeom; Standard_Boolean ok = TopOpeBRepTool_TOOL::NggeomF(uv,f,nggeom);
1211   if (!ok) return Standard_False;
1212   normt = gp_Dir(nggeom);
1213   if (M_REVERSED(f.Orientation())) normt.Reverse();
1214   return Standard_True;
1215 }
1216
1217 //=======================================================================
1218 //function : NggeomF
1219 //purpose  : 
1220 //=======================================================================
1221
1222 static Standard_Boolean FUN_ngF(const gp_Pnt2d& uv, const TopoDS_Face& F, gp_Vec& ngF)
1223 {
1224   BRepAdaptor_Surface bs(F);
1225   Standard_Real tol3d = bs.Tolerance();
1226   Standard_Real tolu = bs.UResolution(tol3d);
1227   Standard_Real tolv = bs.VResolution(tol3d);
1228   
1229   // ###############################
1230   // nyi : all geometries are direct
1231   // ###############################
1232   gp_Pnt p; gp_Vec d1u,d1v; bs.D1(uv.X(),uv.Y(),p,d1u,d1v);  
1233
1234   Standard_Real delta = TopOpeBRepTool_TOOL::minDUV(F); delta *= 1.e-1; 
1235
1236   Standard_Real du = d1u.Magnitude();
1237   Standard_Real dv = d1v.Magnitude();
1238   Standard_Boolean kpart = (du < tolu) || (dv < tolv);
1239   if (kpart) { 
1240     GeomAbs_SurfaceType ST = bs.GetType();
1241     if (ST == GeomAbs_Cone) {
1242       Standard_Boolean nullx = (Abs(uv.X()) < tolu);
1243       Standard_Boolean apex = nullx && (Abs(uv.Y()) < tolv);
1244       if (apex) {
1245         const gp_Dir& axis = bs.Cone().Axis().Direction();
1246         gp_Vec ng(axis); ng.Reverse();
1247         ngF = ng; return Standard_True;
1248       }
1249       else if (du < tolu) {             
1250         Standard_Real x = uv.X(); 
1251         
1252         Standard_Real y = uv.Y(); 
1253         Standard_Real vf = bs.FirstVParameter();
1254         
1255         if (Abs(vf-y) < tolu) vf += delta;
1256         else                  vf -= delta;
1257
1258         //modified by NIZHNY-MZV  Fri Nov 26 12:38:55 1999
1259         y = vf;
1260         bs.D1(x,y,p,d1u,d1v);   
1261         gp_Vec ng = d1u^d1v;
1262
1263         ngF = ng; return Standard_True;
1264       }
1265     }
1266     if (ST == GeomAbs_Sphere) {
1267       Standard_Real pisur2 = M_PI*.5;
1268       Standard_Real u = uv.X(),v = uv.Y();
1269       Standard_Boolean vpisur2 = (Abs(v-pisur2) < tolv);
1270       Standard_Boolean vmoinspisur2 = (Abs(v+pisur2) < tolv);
1271       Standard_Boolean apex = vpisur2 || vmoinspisur2;
1272       if (apex) {
1273         gp_Pnt center = bs.Sphere().Location();
1274         gp_Pnt value  = bs.Value(u,v); 
1275         gp_Vec ng(center,value); 
1276         ngF = ng; return Standard_True;
1277       }
1278     }
1279 #ifdef DEB
1280     cout<<"FUN_tool_nggeomF NYI"<<endl;
1281 #endif
1282     return Standard_False;
1283   } //kpart
1284
1285   gp_Dir udir(d1u);
1286   gp_Dir vdir(d1v);
1287   ngF = gp_Vec(gp_Dir(udir^vdir));
1288   return Standard_True;
1289 }
1290
1291 Standard_Boolean TopOpeBRepTool_TOOL::NggeomF(const gp_Pnt2d& uv, const TopoDS_Face& f,
1292                                  gp_Vec& ng)
1293 {
1294   return FUN_ngF(uv,f,ng);
1295 }
1296
1297 //=======================================================================
1298 //function : Matter
1299 //purpose  : 
1300 //=======================================================================
1301
1302 Standard_Boolean TopOpeBRepTool_TOOL::Matter(const TopoDS_Face& f1,const TopoDS_Face& f2,
1303                                 const TopoDS_Edge& e,const Standard_Real par,
1304                                 const Standard_Real tola, Standard_Real& ang)
1305 {
1306   gp_Dir xx1,xx2;
1307   gp_Dir nt1,nt2;
1308   
1309   Standard_Real tolf1 = BRep_Tool::Tolerance(f1)*1.e2;//nyitolxpu
1310   gp_Pnt2d uv1; Standard_Boolean ok1 = FUN_tool_paronEF(e,par,f1,uv1,tolf1);
1311   if (!ok1) return Standard_False;
1312   ok1 = TopOpeBRepTool_TOOL::Nt(uv1,f1,nt1);
1313   if (!ok1) return Standard_False;
1314   ok1 = TopOpeBRepTool_TOOL::XX(uv1,f1,par,e,xx1);
1315   if (!ok1) return Standard_False;
1316   
1317   Standard_Real tolf2 = BRep_Tool::Tolerance(f2)*2.e2;//nyitolxpu
1318   gp_Pnt2d uv2; Standard_Boolean ok2 = FUN_tool_paronEF(e,par,f2,uv2,tolf2);
1319   if (!ok2) return Standard_False;
1320   ok2 = TopOpeBRepTool_TOOL::Nt(uv2,f2,nt2);
1321   if (!ok2) return Standard_False;
1322   ok2 = TopOpeBRepTool_TOOL::XX(uv2,f2,par,e,xx2);
1323   if (!ok2) return Standard_False;
1324   
1325   return (TopOpeBRepTool_TOOL::Matter(xx1,nt1,xx2,nt2,tola,ang));
1326 }
1327
1328
1329
1330
1331 //=======================================================================
1332 //function : MatterKPtg
1333 //purpose  : 
1334 //=======================================================================
1335
1336 Standard_Boolean TopOpeBRepTool_TOOL::MatterKPtg(const TopoDS_Face& f1,const TopoDS_Face& f2,const TopoDS_Edge& e,
1337                                     Standard_Real& ang)
1338 {
1339   Standard_Real f,l; FUN_tool_bounds(e,f,l);
1340   Standard_Real x = 0.45678; Standard_Real pare = (1-x)*f+x*l;
1341
1342   Standard_Real eps = 0.123; //NYIXPU190199
1343 #ifdef DEB
1344   Standard_Real tola = Precision::Angular()*1.e3;
1345 #endif
1346
1347   gp_Pnt2d uv1; FUN_tool_paronEF(e,pare,f1,uv1);
1348   gp_Dir nt1; Standard_Boolean ok1 = TopOpeBRepTool_TOOL::Nt(uv1,f1,nt1);
1349   if (!ok1) return Standard_False;
1350   gp_Pnt2d uvapp1; ok1 = TopOpeBRepTool_TOOL::uvApp(f1,e,pare,eps,uvapp1);
1351   if (!ok1) return Standard_False;
1352   gp_Pnt pf1; FUN_tool_value(uvapp1,f1,pf1); 
1353
1354   gp_Pnt2d uv2; Standard_Real d; Standard_Boolean ok2 = FUN_tool_projPonF(pf1,f2,uv2,d);
1355   gp_Pnt pf2; FUN_tool_value(uv2,f2,pf2); 
1356   if (!ok2) return Standard_False;
1357
1358   gp_Dir v12(gp_Vec(pf1,pf2));
1359   Standard_Real dot = v12.Dot(nt1);
1360   ang = (dot < 0.) ? 0. : 2.*M_PI;
1361
1362 //  gp_Dir nt1; ok1 = TopOpeBRepTool_TOOL::Nt(uv1,f1,nt1);
1363 //  if (!ok1) return Standard_False;
1364 //  gp_Dir xx1; ok1 = TopOpeBRepTool_TOOL::XX(uv1,f1,pare,e,xx1);
1365 //  if (!ok1) return Standard_False;    
1366 //  gp_Pnt2d uv2; Standard_Boolean ok2 = TopOpeBRepTool_TOOL::uvApp(f2,e,pare,eps,uv2);
1367 //  if (!ok2) return Standard_False;
1368 //  gp_Dir nt2; ok2 = TopOpeBRepTool_TOOL::Nt(uv2,f2,nt2);
1369 //  if (!ok2) return Standard_False;
1370 //  gp_Dir xx2; ok2 = TopOpeBRepTool_TOOL::XX(uv2,f2,pare,e,xx2);
1371 //  if (!ok2) return Standard_False;  
1372 //  Standard_Real angapp; Standard_Boolean ok = TopOpeBRepTool_TOOL::Matter(xx1,nt1, xx2,nt2,tola,angapp);
1373 //  if (!ok) return Standard_False;
1374 //  Standard_Boolean is0 = (Abs(angapp) < Abs(2.*M_PI-angapp));
1375 //  ang = is0 ? 0. : 2.*M_PI;
1376   return Standard_True;
1377 }
1378
1379 //=======================================================================
1380 //function : Getstp3dF
1381 //purpose  : 
1382 //=======================================================================
1383
1384 Standard_Boolean TopOpeBRepTool_TOOL::Getstp3dF(const gp_Pnt& p, const TopoDS_Face& f, gp_Pnt2d& uv, TopAbs_State& st)
1385 // classification solide de <P> / <F>
1386 {
1387   st = TopAbs_UNKNOWN;
1388   Standard_Real tol3d = BRep_Tool::Tolerance(f);
1389     // EXPENSIVE : calls an extrema
1390   Standard_Real d;  Standard_Boolean ok = FUN_tool_projPonF(p,f,uv,d);
1391   if (!ok) return Standard_False;
1392   if (d < tol3d) {st = TopAbs_ON; return Standard_True;}
1393
1394   gp_Pnt ppr; ok = FUN_tool_value(uv,f,ppr);
1395   if (!ok) return Standard_False;
1396
1397   gp_Dir ntf; ok = TopOpeBRepTool_TOOL::Nt(uv,f, ntf);
1398   if (!ok) return Standard_False;
1399
1400   gp_Dir dppr(gp_Vec(p,ppr));
1401   Standard_Real dot = dppr.Dot(ntf);
1402   Standard_Boolean isOUT = (dot < 0.);
1403   st = (isOUT ? TopAbs_OUT : TopAbs_IN);
1404   return Standard_True;
1405 }
1406
1407
1408
1409 //=======================================================================
1410 //function : MkShell
1411 //purpose  : 
1412 //=======================================================================
1413
1414 void TopOpeBRepTool_TOOL::MkShell(const TopTools_ListOfShape& lF, TopoDS_Shape& She)
1415 {
1416   BRep_Builder BB; BB.MakeShell(TopoDS::Shell(She));
1417   for (TopTools_ListIteratorOfListOfShape li(lF); li.More(); li.Next()) BB.Add(She,li.Value());
1418 }
1419
1420 //=======================================================================
1421 //function : Remove
1422 //purpose  : 
1423 //=======================================================================
1424
1425 Standard_Boolean TopOpeBRepTool_TOOL::Remove(TopTools_ListOfShape& loS, const TopoDS_Shape& toremove)
1426 {
1427   TopTools_ListIteratorOfListOfShape it(loS);
1428   Standard_Boolean found = Standard_False;
1429   while (it.More()) {
1430     if (it.Value().IsEqual(toremove)) {loS.Remove(it);found = Standard_True;}
1431     else                              it.Next();
1432   }
1433   return found;
1434 }
1435
1436 //=======================================================================
1437 //function : minDUV
1438 //purpose  : 
1439 //=======================================================================
1440
1441 Standard_Real TopOpeBRepTool_TOOL::minDUV(const TopoDS_Face& F)
1442 {
1443   BRepAdaptor_Surface BS(F);
1444   Standard_Real delta = BS.LastUParameter() - BS.FirstUParameter();
1445   Standard_Real tmp = BS.LastVParameter() - BS.FirstVParameter();
1446   delta = (tmp < delta) ? tmp : delta;  
1447   return delta;  
1448 }
1449
1450
1451 //=======================================================================
1452 //function : stuvF
1453 //purpose  : 
1454 //=======================================================================
1455 #define INFFIRST (-1)
1456 #define SUPLAST (-2)
1457 #define ONFIRST (1)
1458 #define ONLAST  (2)
1459 void TopOpeBRepTool_TOOL::stuvF(const gp_Pnt2d& uv,const TopoDS_Face& f,  Standard_Integer& onU,Standard_Integer& onV)
1460 {
1461   BRepAdaptor_Surface bs(f);
1462   onU = onV = 0;
1463   Standard_Real tolf = bs.Tolerance();
1464   Standard_Real tolu = bs.UResolution(tolf), tolv = bs.VResolution(tolf); 
1465   Standard_Real u=uv.X(),v = uv.Y();
1466   Standard_Real uf=bs.FirstUParameter(),ul=bs.LastUParameter(),vf=bs.FirstVParameter(),vl=bs.LastVParameter();
1467   Standard_Boolean onuf = (Abs(uf-u)<tolu), onul = (Abs(ul-u)<tolu);
1468   Standard_Boolean onvf = (Abs(vf-v)<tolv), onvl = (Abs(vl-v)<tolv);
1469   if (onuf) onU = ONFIRST; if (onul) onU = ONLAST;
1470   if (onvf) onV = ONFIRST; if (onvl) onV = ONLAST;
1471   if (u < (uf-tolu)) onU = INFFIRST; if (u > (ul+tolu)) onU = SUPLAST;
1472   if (v < (vf-tolv)) onV = INFFIRST; if (v > (vl+tolv)) onV = SUPLAST;
1473 }
1474
1475 //=======================================================================
1476 //function : outUVbounds
1477 //purpose  : 
1478 //=======================================================================
1479
1480 Standard_Boolean TopOpeBRepTool_TOOL::outUVbounds(const gp_Pnt2d& uv, const TopoDS_Face& F)
1481 {
1482   BRepAdaptor_Surface BS(F);
1483   Standard_Boolean outofboundU = (uv.X() > BS.LastUParameter())||(uv.X() < BS.FirstUParameter());
1484   Standard_Boolean outofboundV = (uv.Y() > BS.LastVParameter())||(uv.Y() < BS.FirstVParameter());  
1485   return outofboundU || outofboundV;
1486 }
1487
1488 //=======================================================================
1489 //function : TolUV
1490 //purpose  : 
1491 //=======================================================================
1492
1493 Standard_Real TopOpeBRepTool_TOOL::TolUV(const TopoDS_Face& F, const Standard_Real tol3d)
1494
1495   BRepAdaptor_Surface bs(F);
1496   Standard_Real tol2d = bs.UResolution(tol3d);
1497   tol2d = Max(tol2d,bs.VResolution(tol3d));
1498   return tol2d;
1499 }
1500
1501 //=======================================================================
1502 //function : TolP
1503 //purpose  : 
1504 //=======================================================================
1505
1506 Standard_Real TopOpeBRepTool_TOOL::TolP(const TopoDS_Edge& E, const TopoDS_Face& F) 
1507 {
1508   BRepAdaptor_Curve2d BC2d(E,F);
1509   return ( BC2d.Resolution(BRep_Tool::Tolerance(E)) );
1510 }
1511
1512 //=======================================================================
1513 //function : WireToFace
1514 //purpose  : 
1515 //=======================================================================
1516
1517 Standard_Boolean TopOpeBRepTool_TOOL::WireToFace(const TopoDS_Face& Fref, const TopTools_DataMapOfShapeListOfShape& mapWlow,
1518                                     TopTools_ListOfShape& lFs)
1519 {
1520   BRep_Builder BB;
1521   TopoDS_Shape aLocalShape = Fref.Oriented(TopAbs_FORWARD);
1522   TopoDS_Face F = TopoDS::Face(aLocalShape);
1523 //  TopoDS_Face F = TopoDS::Face(Fref.Oriented(TopAbs_FORWARD));
1524   Standard_Boolean toreverse = M_REVERSED(Fref.Orientation());
1525   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mapWlow);
1526   for (; itm.More(); itm.Next()) {
1527     TopoDS_Shape FF = F.EmptyCopied();
1528     const TopoDS_Wire& wi = TopoDS::Wire(itm.Key());  
1529     BB.Add(FF,wi);
1530     TopTools_ListIteratorOfListOfShape itw(itm.Value());
1531     for (; itw.More(); itw.Next()) {
1532       const TopoDS_Wire& wwi = TopoDS::Wire(itw.Value());
1533       BB.Add(FF,wwi);
1534     }
1535     if (toreverse) FF.Orientation(TopAbs_REVERSED);
1536     lFs.Append(FF);
1537   }
1538   return Standard_True;
1539 }
1540
1541 //=======================================================================
1542 //function : EdgeONFace
1543 //purpose  : 
1544 //=======================================================================
1545
1546 Standard_Boolean TopOpeBRepTool_TOOL::EdgeONFace(const Standard_Real par,const TopoDS_Edge& ed,
1547                                     const gp_Pnt2d& uv,const TopoDS_Face& fa,
1548                                     Standard_Boolean& isonfa)
1549 {
1550   isonfa = Standard_False;
1551   // prequesitory : pnt(par,ed) = pnt(uv,f)
1552   Standard_Boolean dge = BRep_Tool::Degenerated(ed);
1553   if (dge) {
1554     isonfa = Standard_True;
1555     return Standard_True;
1556   }
1557
1558   Standard_Real tola = Precision::Angular()*1.e2;//NYITOLXPU
1559   gp_Vec tge; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(par,ed,tge);  
1560   if (!ok) return Standard_False;
1561   gp_Vec ngf = FUN_tool_nggeomF(uv,fa);
1562   Standard_Real prod = tge.Dot(ngf);
1563   Standard_Boolean etgf = Abs(prod) < tola;
1564   if (!etgf) return Standard_True;
1565
1566   BRepAdaptor_Surface bs(fa);
1567   GeomAbs_SurfaceType st = bs.GetType();
1568   Standard_Boolean plane = (st == GeomAbs_Plane);
1569   Standard_Boolean cylinder = (st == GeomAbs_Cylinder);
1570   
1571   BRepAdaptor_Curve bc(ed);
1572   GeomAbs_CurveType ct = bc.GetType();
1573   Standard_Boolean line = (ct == GeomAbs_Line);
1574   Standard_Boolean circle = (ct == GeomAbs_Circle);
1575
1576   Standard_Real tole = bc.Tolerance(); Standard_Real tol1de = bc.Resolution(tole);
1577   Standard_Real tolf = bs.Tolerance();
1578   Standard_Real tol3d = Max(tole,tolf)*1.e2;//NYITOLXPU
1579
1580   // NYIxpu100299 : for other analytic geometries
1581   if (plane && line) {isonfa = Standard_True; return Standard_True;}
1582   if       (plane) {
1583     gp_Dir ne;
1584     Standard_Boolean det = Standard_True;
1585     if      (circle)  ne = bc.Circle().Axis().Direction();
1586     else if (ct == GeomAbs_Ellipse) ne = bc.Ellipse().Axis().Direction();
1587     else if (ct == GeomAbs_Hyperbola)    ne = bc.Hyperbola().Axis().Direction();
1588     else if (ct == GeomAbs_Parabola)ne = bc.Parabola().Axis().Direction();
1589     else                            det = Standard_False;
1590     if (det) {
1591       Standard_Real prod = ne.Dot(ngf);
1592       isonfa = ( Abs(1-Abs(prod)) < tola );
1593       return Standard_True;
1594     }
1595   }//plane
1596   else if (cylinder) {
1597     gp_Dir ne; Standard_Boolean det = Standard_True;
1598     if      (line)  ne = tge;
1599     else if (circle)ne = bc.Circle().Axis().Direction();
1600     else            det = Standard_False;
1601     gp_Dir axicy = bs.Cylinder().Axis().Direction();
1602
1603     if (det) {
1604       Standard_Real prod = ne.Dot(axicy);
1605       isonfa = ( Abs(1-Abs(prod)) < tola );
1606       if (isonfa && circle) {
1607         Standard_Real radci = bc.Circle().Radius();
1608         Standard_Real radcy = bs.Cylinder().Radius();
1609         isonfa = ( Abs(radci-radcy)<tol3d );
1610       }
1611       return Standard_True;
1612     }
1613   }//cylinder
1614
1615   // !!!!!!!!!!!!!!!! NOT STILL OK !!!!!!!!!!!!!!
1616   // projecting point of <ed> on <fa>
1617   Standard_Real x = 0.12345;
1618   Standard_Real f,l; FUN_tool_bounds(ed,f,l);
1619   Standard_Boolean onf = ( Abs(par-f)<tol1de );
1620   Standard_Real opar = onf ?  ((1-x)*f+x*l) : ((1-x)*f+x*par);
1621   gp_Pnt opc = bc.Value(opar);
1622   
1623   gp_Pnt2d ouv; ok = FUN_tool_parF(ed,opar,fa,ouv,tolf);
1624   if (!ok) return Standard_False;  
1625   gp_Pnt ops = bs.Value(ouv.X(),ouv.Y());
1626   
1627   Standard_Real dd = opc.Distance(ops);
1628   isonfa = (dd < tol3d);
1629   return Standard_True;
1630 }