0024428: Implementation of LGPL license
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_makeTransition.cxx
1 // Created on: 1999-02-11
2 // Created by: Xuan PHAM PHU
3 // Copyright (c) 1999-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
9 // under the terms of the GNU Lesser General Public 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.hxx>
18 #include <TopOpeBRepTool_EXPORT.hxx>
19 #include <TopOpeBRepTool_makeTransition.ixx>
20 #include <TopOpeBRepTool_define.hxx>
21 #include <BRep_Tool.hxx>
22 #include <Precision.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25
26 #define BEFORE (1)
27 #define AFTER  (2)
28
29 #define isINifh1   (1)
30 #define isINifh2   (2)
31 #define isON2     (21)
32 #define isON2ifss (10)
33 #define isIN2ifss (11)
34 #define isOU2ifss (12)
35
36 #define INFFIRST (-1)
37 #define SUPLAST (-2)
38 #define ONFIRST (1)
39 #define ONLAST  (2)
40
41 #define FORWARD  (1)
42 #define REVERSED (2)
43 #define INTERNAL (3)
44 #define EXTERNAL (4)
45 #define CLOSING  (5)
46
47 #define M_ON(sta)       (sta == TopAbs_ON)
48 #define M_IN(sta)       (sta == TopAbs_IN)
49 #define M_FORWARD(sta)  (sta == TopAbs_FORWARD)
50 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
51 #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
52 #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
53 #define M_UNKNOWN(sta)  (sta == TopAbs_UNKNOWN)
54
55 static Standard_Real FUN_tolang()
56 {
57   return Precision::Angular()*1.e6;//=1.e-6 NYITOLXPU
58 }
59
60 //=======================================================================
61 //function : TopOpeBRepTool_makeTransition
62 //purpose  : 
63 //=======================================================================
64
65 TopOpeBRepTool_makeTransition::TopOpeBRepTool_makeTransition()
66 {
67 }
68
69 //=======================================================================
70 //function : Initialize
71 //purpose  : 
72 //=======================================================================
73
74 Standard_Boolean TopOpeBRepTool_makeTransition::Initialize
75 (const TopoDS_Edge& E,const Standard_Real pbef,const Standard_Real paft,const Standard_Real parE,
76  const TopoDS_Face& FS, const gp_Pnt2d& uv,
77  const Standard_Real factor)
78 {
79   Standard_Boolean isdge = BRep_Tool::Degenerated(E);
80   if (isdge) return Standard_False;
81
82   myE = E;
83   mypb = pbef; mypa = paft; mypE = parE;
84   myFS = FS; myuv = uv;
85   myfactor = factor;
86   hasES = Standard_False;
87
88   Standard_Boolean facko = (factor < 0.) || (factor > 1.);
89   if (facko) return Standard_False;
90
91   Standard_Boolean ok = TopOpeBRepTool_TOOL::EdgeONFace(mypE,myE,myuv,FS,isT2d);
92   return ok;
93 }
94
95 //=======================================================================
96 //function : Setfactor
97 //purpose  : 
98 //=======================================================================
99
100 void TopOpeBRepTool_makeTransition::Setfactor(const Standard_Real factor)
101 {
102   myfactor = factor;
103 }
104
105 //=======================================================================
106 //function : Getfactor
107 //purpose  : 
108 //=======================================================================
109
110 Standard_Real TopOpeBRepTool_makeTransition::Getfactor() const 
111 {
112   return myfactor;
113 }
114
115 //=======================================================================
116 //function : IsT2d
117 //purpose  : 
118 //=======================================================================
119
120 Standard_Boolean TopOpeBRepTool_makeTransition::IsT2d() const
121 {
122   return isT2d;
123 }
124
125
126
127 //=======================================================================
128 //function : SetRest
129 //purpose  : 
130 //=======================================================================
131
132 Standard_Boolean TopOpeBRepTool_makeTransition::SetRest(const TopoDS_Edge& ES, const Standard_Real parES)
133 {
134   Standard_Boolean isdge = BRep_Tool::Degenerated(ES);
135   if (isdge) return Standard_False;
136
137   hasES = Standard_True;
138   myES = ES;
139   mypES = parES;
140
141   // nyi check <ES> is edge of <myFS>
142   return Standard_True;
143 }
144
145 //=======================================================================
146 //function : HasRest
147 //purpose  : 
148 //=======================================================================
149
150 Standard_Boolean TopOpeBRepTool_makeTransition::HasRest() const
151 {
152   return hasES;
153 }
154
155 static Standard_Boolean FUN_nullcurv(const Standard_Real curv)
156 {
157   Standard_Real tol = Precision::Confusion()*1.e+2;//NYITOLXPU
158   return (curv < tol);
159 }
160
161 static Standard_Integer FUN_mkT2dquad(const Standard_Real curvC1, const Standard_Real curvC2)
162 {
163   // !!! only for quadratic geometries :
164   // prequesitory : C1 and C2 are ON given plane; they are tangent
165   // at point pt, where curvatures are respectively curvC1,curvC2
166   // stb = state of point on C1 before pt / C2
167   // = sta = state of point on C1 after pt / C2
168
169   Standard_Boolean nullc1  = FUN_nullcurv(curvC1);
170   Standard_Boolean nullc2 = FUN_nullcurv(curvC2);
171   if (nullc2 && nullc1) return isON2;
172   if (nullc2) return isINifh1;//is IN if (dot=tg1(pt after).xx2 > 0)
173   if (nullc1) return isINifh2;//is IN if (dot=tg2(pt after).xx2 < 0)  
174
175   Standard_Boolean samec = (Abs(curvC2-curvC1) < 1.e-2); //NYITOLXPU kpartkoletge
176   if (samec)           return isON2ifss;//is ON if curves are on same side/tg line
177   if (curvC1 > curvC2) return isIN2ifss;//is IN if curves are on same side/tg line
178   else                 return isOU2ifss;//is OU if curves are on same side/tg line
179 //  return 0;
180 }
181
182 static Standard_Boolean FUN_getnearpar(const TopoDS_Edge& e,const Standard_Real par,const Standard_Real f,const Standard_Real l,
183                           const Standard_Real factor,const Standard_Integer sta, Standard_Real& nearpar)
184 {
185   // hyp : f < par < l
186   BRepAdaptor_Curve bc(e);
187   Standard_Real tol1d = bc.Resolution( bc.Tolerance() ); 
188   Standard_Boolean onf = (Abs(par-f) < tol1d);
189   Standard_Boolean onl = (Abs(par-l) < tol1d);
190   if (onf && (sta == BEFORE)) return Standard_False; 
191   if (onl && (sta == AFTER))  return Standard_False; 
192   //nearpar = (sta == BEFORE) ? ((1-factor)*par - factor*f) : ((1-factor)*par - factor*l); 
193   nearpar = (sta == BEFORE) ? (par - factor*(l-f)) : (par + factor*(l-f)); 
194   return Standard_True;
195 }
196
197 static Standard_Boolean FUN_tg(const TopoDS_Edge& e,const Standard_Real par,const Standard_Real f,const Standard_Real l,const Standard_Real factor,
198                   gp_Dir& tg, Standard_Integer& st)
199 {
200   st = BEFORE;
201   for (Standard_Integer nite = 1; nite <= 2; nite++) {
202     if (nite == 2) st = AFTER;    
203     Standard_Real pn; Standard_Boolean mkp = FUN_getnearpar(e,par,f,l,factor,st,pn);
204     if (!mkp) continue;
205     gp_Vec tmp; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(pn,e,tmp);
206     if (!ok) continue;
207     tg = gp_Dir(tmp); 
208     return Standard_True;    
209   }
210   return Standard_False;  
211 }
212 static Standard_Boolean FUN_getsta(const Standard_Integer mkt,const gp_Dir& tga1,const gp_Dir& tga2,const gp_Dir& xx2,
213                       TopAbs_State& sta)
214 {
215   if      (mkt == isINifh1) {
216     // curv(e1) > 0.
217     //is IN if (dot=tg1(pt after).xx2 > 0)
218     Standard_Real dot = tga1.Dot(xx2);
219     sta =  (dot > 0) ? TopAbs_IN : TopAbs_OUT;
220     return Standard_True;
221   }
222   else if (mkt == isINifh2) {
223     // curv(e2) > 0.
224     //is IN if (dot=tg2(pt after).xx2 < 0) 
225     Standard_Real dot = tga2.Dot(xx2);
226     sta =  (dot < 0) ? TopAbs_IN : TopAbs_OUT;
227     return Standard_True;
228   }
229   else if (mkt == isON2ifss) {
230     // curv(e1), curv(e2) > 0.
231     //is ON if curves are on same side/tg line 
232     Standard_Boolean ssided = (tga1.Dot(tga2) > 0);
233     sta = ssided ? TopAbs_ON : TopAbs_IN;
234     return Standard_True;
235   }
236   else if (mkt == isIN2ifss) {
237     //stag = IN if curves are on same side/tg line  
238     Standard_Real dot = tga1.Dot(xx2);
239     sta = (dot < 0) ? TopAbs_OUT : TopAbs_IN;
240     return Standard_True;
241   }
242   else if (mkt == isOU2ifss) {
243     //stag = OU if curves are on same side/tg line 
244     Standard_Real dot = tga2.Dot(xx2);
245     sta = (dot < 0) ? TopAbs_IN : TopAbs_OUT;
246     return Standard_True;   
247   } 
248   else {//mkt == isON2
249     sta = TopAbs_ON; 
250     return Standard_True;
251   } 
252
253 static Standard_Boolean FUN_mkT2dquad(const TopoDS_Edge& e1,const Standard_Real par1,const Standard_Real f1,const Standard_Real l1,
254                          const TopoDS_Edge& e2,const Standard_Real par2,
255                          const Standard_Integer mkt,const gp_Dir& xx2,const Standard_Real factor,
256                          TopAbs_State& sta)
257 {
258   sta = TopAbs_UNKNOWN;
259
260   // !!! only for quadratic geometries :
261   // stb = state of point on e1 before pt / e2
262   // = sta = state of point on e1 after pt / e2
263
264   gp_Dir tga1,tga2;
265   Standard_Boolean mk1 = isINifh1 || isON2ifss || isIN2ifss;
266   if (mk1) {
267     Standard_Integer st1 = 0; gp_Dir tgnear1;
268     Standard_Boolean ok = FUN_tg(e1,par1,f1,l1,factor,tgnear1,st1);
269     if (!ok) return Standard_False;
270     tga1 = (st1 == AFTER) ? tgnear1 : tgnear1.Reversed();    
271   }
272   Standard_Boolean mk2 = isINifh2 || isON2ifss || isOU2ifss;
273   if (mk2) {
274     Standard_Real f2,l2; FUN_tool_bounds(e2,f2,l2);
275     Standard_Integer st2 = 0; gp_Dir tgnear2;
276     Standard_Boolean ok = FUN_tg(e2,par2,f2,l2,factor,tgnear2,st2);
277     if (!ok) return Standard_False;
278     tga2 = (st2 == AFTER) ? tgnear2 : tgnear2.Reversed();
279   }
280   return (FUN_getsta(mkt,tga1,tga2,xx2, sta));
281 }
282
283 //=======================================================================
284 //function : MkT2donE
285 //purpose  : 
286 //=======================================================================
287
288 Standard_Boolean TopOpeBRepTool_makeTransition::MkT2donE(TopAbs_State& Stb,TopAbs_State& Sta) const
289 {
290   if (!isT2d) return Standard_False;
291
292   // E is IN 2d(FS), meets no restriction at given point :
293   if (!hasES) {Stb = Sta = TopAbs_IN; return Standard_True;}
294   
295   // E is IN 2d(FS), meets restriction ES at given point :
296   Standard_Integer oriESFS = TopOpeBRepTool_TOOL::OriinSor(myES,myFS, Standard_True);
297   if (oriESFS == 0) return Standard_False;
298   
299   // ES is closing edge for FS, or ES is INTERNAL in FS : 
300   if      (oriESFS == INTERNAL) {Stb = Sta = TopAbs_IN; return Standard_True;}
301   else if (oriESFS == CLOSING)  {Stb = Sta = TopAbs_IN; return Standard_True;}  
302   
303   gp_Vec tmp; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(mypE,myE,tmp);
304   if (!ok) return Standard_False;
305   gp_Dir tgE(tmp);     
306   gp_Dir xxES; ok = TopOpeBRepTool_TOOL::XX(myuv,myFS, mypES,myES, xxES);
307   if (!ok) return Standard_False;
308   
309   Standard_Real tola = FUN_tolang();
310   Standard_Real dot = tgE.Dot(xxES);
311   
312   // E and ES are not tangent at interference point :
313   Standard_Boolean tgts = (Abs(dot) < tola);
314   if (!tgts) {
315     Standard_Boolean dotpos = (dot > 0.);
316     if (dotpos) {Stb = TopAbs_OUT; Sta = TopAbs_IN;}
317     else        {Stb = TopAbs_IN; Sta = TopAbs_OUT;}
318     return Standard_True;
319   }
320   
321   // E and ES are tangent, curves are quadratic :transition is INTERNAL/EXTERNAL,
322   // elsewhere                                  : transition is FOR/REV/INT/EXT
323   // we then use curvatures to compute transition T :
324   // xpu090299 PRO13455(E=e7, ES=e9, FS=f11)
325   gp_Dir ntFS; ok = TopOpeBRepTool_TOOL::Nt(myuv,myFS,ntFS);
326   if (!ok) return Standard_False;
327   Standard_Real curvE;  ok = TopOpeBRepTool_TOOL::CurvE(myE,mypE,ntFS,curvE);
328   if (!ok) return Standard_False;
329   Standard_Real curvES; ok = TopOpeBRepTool_TOOL::CurvE(myES,mypES,ntFS,curvES);
330   if (!ok) return Standard_False;  
331
332   Standard_Boolean quadE  = TopOpeBRepTool_TOOL::IsQuad(myE);
333   Standard_Boolean quadES = TopOpeBRepTool_TOOL::IsQuad(myES);
334   if (quadE && quadES) { // should return INT/EXT
335     TopAbs_State sta = TopAbs_UNKNOWN;
336     Standard_Integer mkt = FUN_mkT2dquad(curvE,curvES);
337     Standard_Boolean ok  = FUN_mkT2dquad(myE,mypb,mypa,mypE, myES,mypES, mkt,xxES,myfactor,sta);
338     if (ok) {
339       Stb = Sta = sta;
340       return Standard_True;
341     }
342   }
343
344   // !!!NYI: general case :
345   // ----------------------
346   // NYIKPART quadquad, only one state
347   return Standard_False;
348 }
349
350 static Standard_Boolean FUN_getnearuv(const TopoDS_Face& f,const gp_Pnt2d& uv,
351                          const Standard_Real factor,const Standard_Integer sta,const gp_Dir2d& duv, 
352                          gp_Pnt2d& nearuv)
353 {
354   BRepAdaptor_Surface bs(f);
355
356   gp_Vec2d xuv = gp_Vec2d(duv).Multiplied(factor);
357   if (sta == BEFORE) xuv.Reverse();
358   nearuv = uv.Translated(xuv) ;
359
360   Standard_Integer onu,onv; TopOpeBRepTool_TOOL::stuvF(uv,f, onu,onv);
361   Standard_Boolean uok = (onu == 0);
362   Standard_Boolean vok = (onv == 0);
363   if (uok && vok) return Standard_True;
364
365   Standard_Real nearu = nearuv.X(), nearv = nearuv.Y();
366
367   if ((onu == INFFIRST)||(onu == SUPLAST)) {
368     Standard_Boolean ucl = bs.IsUClosed();
369     if (!ucl) return Standard_False;
370     Standard_Real uper = bs.UPeriod();
371     if (onu == INFFIRST) nearu += uper;
372     else                 nearu -= uper;
373   }
374
375   if ((onv == INFFIRST)||(onv == SUPLAST)) {
376     Standard_Boolean vcl = bs.IsVClosed();
377     if (!vcl) return Standard_False;
378     Standard_Real vper = bs.VPeriod();
379     if (onv == INFFIRST) nearv += vper;
380     else                 nearv -= vper;
381   }
382   nearuv = gp_Pnt2d(nearu,nearv);
383   return Standard_True;
384 }//FUN_getnearuv
385 static Standard_Boolean FUN_tgef(const TopoDS_Face& f,
386                                  const gp_Pnt2d& uv,
387                                  const gp_Dir2d& duv,
388                                  const Standard_Real factor,
389 //                               const gp_Dir& tge,
390                                  const gp_Dir& ,
391                                  const gp_Dir& tg0,
392                                  gp_Dir& tgef, 
393                                  Standard_Integer& st)
394 {
395   st = BEFORE;
396   for (Standard_Integer nite = 1; nite <= 2; nite++) {
397     if (nite == 2) st = AFTER;    
398     gp_Pnt2d nearuv;
399 //    Standard_Real pn;
400     Standard_Boolean mkp = FUN_getnearuv(f,uv,factor,st,duv, nearuv);
401     if (!mkp) continue;
402     gp_Dir nt; Standard_Boolean ok = TopOpeBRepTool_TOOL::Nt(nearuv,f,nt);
403     if (!ok) return Standard_False;
404     // recall : ntf^tge = tg0, (tgef(uv) = tge) 
405     //          => near interference point, we assume nt^tgef(nearuv) = tg0 
406     tgef = tg0.Crossed(nt);
407     return Standard_True;    
408   }
409   return Standard_False;  
410 }//FUN_tgef
411 static Standard_Boolean FUN_mkT3dquad(const TopoDS_Edge& e,const Standard_Real pf,const Standard_Real pl,const Standard_Real par,
412                          const TopoDS_Face& f,const gp_Pnt2d& uv,
413                          const gp_Dir& tge,const gp_Dir& ntf,
414                          const Standard_Integer mkt,const Standard_Real factor, TopAbs_State& sta)
415      
416 {  
417   // stb = state of point on e before pt / ef
418   // = sta = state of point on e after pt / ef
419   sta = TopAbs_UNKNOWN;
420   gp_Dir xxef = ntf.Reversed();
421   gp_Dir tg0 = ntf.Crossed(tge);
422
423   gp_Dir tgae,tgaef;
424   Standard_Boolean mke = (mkt==isINifh1) || (mkt==isON2ifss) || (mkt==isIN2ifss);
425   if (mke) {
426     Standard_Integer st = 0; gp_Dir tgnear; Standard_Boolean ok = FUN_tg(e,par,pf,pl,factor,tgnear,st);
427     if (!ok) return Standard_False;
428     tgae = (st == AFTER) ? tgnear : tgnear.Reversed();
429   }
430   Standard_Boolean mkef = (mkt==isINifh2) || (mkt==isON2ifss) || (mkt==isOU2ifss);
431   if (mkef) { 
432     // choice : tgdir(ef,uv) = tgdir(e,pare)
433     Standard_Real fac3d = 0.01; //0.12345; not only planar faces
434     gp_Dir2d duv; Standard_Boolean ok = TopOpeBRepTool_TOOL::Getduv(f,uv,tge,fac3d, duv);
435     if (!ok) return Standard_False;
436     gp_Dir tgnear; Standard_Integer st = 0; ok = FUN_tgef(f,uv,duv,factor, tge,tg0, tgnear,st);
437     if (!ok) return Standard_False;
438     tgaef = (st == AFTER) ? tgnear : tgnear.Reversed();
439   }
440   return (FUN_getsta(mkt,tgae,tgaef,xxef, sta));
441 }
442
443 static TopAbs_State FUN_stawithES(const gp_Dir& tgE,const gp_Dir& xxES,const Standard_Integer st)
444 {
445   // prequesitory : FS and E are tangent at interference point
446   // ---------------------------------------------------------
447   // xxES : normal to ES oriented INSIDE 2d(FS)
448   // tgE  : tangent to E at Pt
449   // pt(st,E) (st=BEFORE,AFTER) has been found IN 3dFS()    
450   
451   TopAbs_State sta;
452   Standard_Real prod = tgE.Dot(xxES);
453   Standard_Real tola = FUN_tolang();
454   if (Abs(prod) < tola) return TopAbs_UNKNOWN;
455   Standard_Boolean positive = (prod > 0.);
456   if (positive) sta = (st == BEFORE) ? TopAbs_OUT : TopAbs_IN; //T.Set(TopAbs_FORWARD);
457   else          sta = (st == BEFORE) ? TopAbs_IN : TopAbs_OUT;//T.Set(TopAbs_REVERSED);
458 //  sta = (iP == BEFORE) ? T.Before() : T.After();
459   return sta;
460 }//FUN_stawithES
461 static TopAbs_State FUN_stawithES(const gp_Dir& tgE,const gp_Dir& xxES,const Standard_Integer st,const TopAbs_State stt)
462 {
463   TopAbs_State str = TopAbs_UNKNOWN;
464   if (M_UNKNOWN(stt)) return str;
465
466   TopAbs_State stES = FUN_stawithES(tgE,xxES,st);
467   // we keep statx as IN or ON if xwithline is IN
468   if (M_IN(stt) || M_ON(stt)) str = M_IN(stES) ? stt : TopAbs_OUT;
469   return str;
470 }
471
472 static Standard_Boolean FUN_staproj(const TopoDS_Edge& e,const Standard_Real pf,const Standard_Real pl,const Standard_Real pe,
473                        const Standard_Real factor, const Standard_Integer st, const TopoDS_Face& f, 
474                        TopAbs_State& sta)
475 {
476   Standard_Real par;Standard_Boolean ok = FUN_getnearpar(e,pe,pf,pl,factor,st, par);
477   if (!ok) return Standard_False;
478   gp_Pnt pt;  ok = FUN_tool_value(par,e, pt);
479   if (!ok) return Standard_False;
480   gp_Pnt2d uv; ok = TopOpeBRepTool_TOOL::Getstp3dF(pt,f,uv,sta);
481   return ok;
482 }
483
484 //=======================================================================
485 //function : MkT3dproj
486 //purpose  : can return in,out,on
487 //=======================================================================
488
489 Standard_Boolean TopOpeBRepTool_makeTransition::MkT3dproj(TopAbs_State& Stb,TopAbs_State& Sta) const
490 {
491   Stb = Sta = TopAbs_UNKNOWN;
492   Standard_Boolean okb = FUN_staproj(myE,mypb,mypa,mypE, myfactor,BEFORE,myFS, Stb);
493   if (!okb) return Standard_False;
494   Standard_Boolean oka = FUN_staproj(myE,mypb,mypa,mypE, myfactor,AFTER,myFS, Sta);
495   if (!oka) return Standard_False;
496   return Standard_True;
497 }
498
499 //=======================================================================
500 //function : MkT3donE
501 //purpose  : 
502 //   <myE> is tangent to <myFS> at point P = Pt(<myuv>,<myFS>) = Pt(<mypE>,<myE>)
503 //   <tgE> = E's tangent at P,
504 //   <ntF> = <F>'s topological normal at P.
505
506 //   These define a plane Pln = (O = P, XY = (<ntF>,<tgE>)), 
507 //   the projection of <F> in Pln describes an bounding edge eF in 2dspace(Pln)
508
509 //   In thePlane :
510 //   P -> myuv
511 //   <ntF> -> 2d axis x
512 //   <tgE> -> 2d axis y
513 // ================================================================================
514
515 Standard_Boolean TopOpeBRepTool_makeTransition::MkT3onE(TopAbs_State& Stb,TopAbs_State& Sta) const
516 {
517   if (isT2d) return Standard_False;
518   gp_Vec tmp; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(mypE,myE,tmp);
519   if (!ok) return Standard_False;
520   gp_Dir tgE(tmp); 
521   gp_Dir ntFS; ok = TopOpeBRepTool_TOOL::Nt(myuv,myFS,ntFS);
522   if (!ok) return Standard_False; 
523   
524   Standard_Real tola = FUN_tolang();
525   Standard_Real dot = tgE.Dot(ntFS);
526   
527   if (Abs(dot) > tola) {
528     Stb = (dot > 0) ? TopAbs_IN : TopAbs_OUT;
529     Sta = (dot > 0) ? TopAbs_OUT : TopAbs_IN;
530 //    TopAbs_Orientation oE = (dot > 0) ? TopAbs_REVERSED : TopAbs_FORWARD;
531 //    T.Set(oE);
532     return Standard_True;
533   }
534   
535   //E is tangent to FS at interference point
536   gp_Dir tg0 = ntFS.Crossed(tgE);
537   Standard_Real curE; ok = TopOpeBRepTool_TOOL::CurvE(myE,mypE,tg0, curE);
538   if (!ok) return Standard_False;
539   Standard_Real curFS; Standard_Boolean direct; ok = TopOpeBRepTool_TOOL::CurvF(myFS,myuv,tg0, curFS,direct);
540   if (!ok) return Standard_False;
541     
542   Standard_Boolean quadE   = TopOpeBRepTool_TOOL::IsQuad(myE);
543   Standard_Boolean quadFS  = TopOpeBRepTool_TOOL::IsQuad(myFS);
544   if (quadE && quadFS) { // should return INT/EXT
545     Standard_Integer mkt = FUN_mkT2dquad(curE,curFS);    
546     TopAbs_State sta = TopAbs_UNKNOWN;
547     ok = FUN_mkT3dquad(myE,mypb,mypa,mypE, myFS,myuv, tgE,ntFS, mkt,myfactor,sta); 
548     if (ok) {
549       if (hasES) {
550         gp_Dir xxES; Standard_Boolean ok = TopOpeBRepTool_TOOL::XX(myuv,myFS, mypES,myES, xxES);
551         if (!ok) return Standard_False;
552         Stb = FUN_stawithES(tgE,xxES,BEFORE,sta);
553         Sta = FUN_stawithES(tgE,xxES,AFTER,sta);
554       }
555       else {
556         Stb = Sta = sta; 
557       }
558       return Standard_True;
559     }
560   }
561   
562   // NYIGENERALCASE;
563   // NYIKPART quadquad, only one state
564   return Standard_False;
565 }
566
567 //=======================================================================
568 //function : MkTonE
569 //purpose  : 
570 //=======================================================================
571
572 Standard_Boolean TopOpeBRepTool_makeTransition::MkTonE(TopAbs_State& Stb,TopAbs_State& Sta) 
573 {
574   Stb = Sta = TopAbs_UNKNOWN;
575   if (isT2d) return (MkT2donE(Stb,Sta));
576
577   Standard_Boolean ok = MkT3onE(Stb,Sta);
578   if (!ok) ok = MkT3dproj(Stb, Sta);
579 //  if (!ok) return Standard_False;
580
581   gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(mypE,myE,tmp);
582   if (!ok) return Standard_False;
583   gp_Dir tgE(tmp); 
584   gp_Dir xxES; 
585   if (hasES && ok) {ok = TopOpeBRepTool_TOOL::XX(myuv,myFS, mypES,myES, xxES);
586                     if (!ok) return Standard_False;}
587   
588   Standard_Real delta = (1. - myfactor)/5.;  
589   Standard_Boolean kob=Standard_False, koa=Standard_False;
590   for (Standard_Integer nite = 1; nite <= 5; nite++) {
591     kob = (Stb == TopAbs_ON)||(Stb == TopAbs_UNKNOWN);
592     koa = (Sta == TopAbs_ON)||(Sta == TopAbs_UNKNOWN);
593     if (!koa && !kob) return Standard_True;
594     
595     Standard_Boolean okb=Standard_True, oka=Standard_True;
596     if (kob) {
597       okb = FUN_staproj(myE,mypb,mypa,mypE, myfactor,BEFORE,myFS, Stb);
598       if (okb && hasES) {TopAbs_State stb = Stb; Stb = FUN_stawithES(tgE,xxES,BEFORE,stb);}
599     }
600     if (koa) {
601       oka = FUN_staproj(myE,mypb,mypa,mypE, myfactor,AFTER,myFS, Sta);
602       if (oka && hasES) {TopAbs_State sta = Sta; Sta = FUN_stawithES(tgE,xxES,AFTER,sta);}
603     }
604     
605     myfactor += delta;
606   }//nite=1..5
607   return Standard_False;
608 }
609