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