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