e72db5fc6eabb2d3f58faa470e509007da2786e2
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_mkTondgE.cxx
1 // Created on: 1999-03-23
2 // Created by: Xuan PHAM PHU
3 // Copyright (c) 1999-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 <Precision.hxx>
24 #include <gp_Pnt.hxx>
25 #include <gp_Vec.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <TopoDS.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRepAdaptor_Surface.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopOpeBRepTool_EXPORT.hxx>
32 #include <TopOpeBRepTool_TOOL.hxx>
33 #include <TopOpeBRepTool_mkTondgE.ixx>
34 #include <TopOpeBRepTool_define.hxx>
35
36 #define M_FORWARD(sta)  (sta == TopAbs_FORWARD)
37 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
38 #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
39 #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
40
41 #define FORWARD  (1)
42 #define REVERSED (2)
43 #define INTERNAL (3)
44 #define EXTERNAL (4)
45 #define CLOSING  (5)
46
47 #define NOI      (0)
48 #define MKI1     (1)
49 #define MKI2     (2)
50 #define MKI12    (3)
51
52 static Standard_Real FUN_tola() 
53 {
54   Standard_Real tola = Precision::Angular();
55   return tola;
56 }
57
58 //=======================================================================
59 //function : TopOpeBRepTool_mkTondgE
60 //purpose  : 
61 //=======================================================================
62
63 TopOpeBRepTool_mkTondgE::TopOpeBRepTool_mkTondgE()
64 {
65 }
66
67 //=======================================================================
68 //function : Initialize
69 //purpose  : 
70 //=======================================================================
71
72 Standard_Boolean TopOpeBRepTool_mkTondgE::Initialize(const TopoDS_Edge& dgE, const TopoDS_Face& F,
73                                         const gp_Pnt2d& uvi, const TopoDS_Face& Fi)
74 {
75   isT2d = Standard_False; hasRest = Standard_False;
76   myclE.Nullify(); myEpari.Clear();
77
78   mydgE = dgE;
79   myF = F;
80
81   TopExp_Explorer exv(mydgE, TopAbs_VERTEX);const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current()); 
82   Standard_Real par = BRep_Tool::Parameter(v,mydgE);
83   gp_Pnt2d uv; Standard_Boolean ok = FUN_tool_paronEF(mydgE,par,myF,uv);
84   if (!ok) return Standard_False;  
85   gp_Vec tmp; ok = TopOpeBRepTool_TOOL::NggeomF(uv,myF,tmp); myngf = gp_Dir(tmp);
86   if (!ok) return Standard_False;
87   
88   myuvi = uvi;
89   myFi = Fi;
90   Standard_Boolean oki = TopOpeBRepTool_TOOL::NggeomF(myuvi,myFi,tmp); myngfi = gp_Dir(tmp);
91   if (!oki) return Standard_False;
92
93   Standard_Real dot = myngf.Dot(myngfi);
94   isT2d = (Abs(1-Abs(dot)) < FUN_tola());
95   return Standard_True;
96 }
97
98 //=======================================================================
99 //function : SetclE
100 //purpose  : 
101 //=======================================================================
102
103 Standard_Boolean TopOpeBRepTool_mkTondgE::SetclE(const TopoDS_Edge& clE)
104 {
105   myclE = clE;
106   return Standard_True;
107 }
108
109
110
111 //=======================================================================
112 //function : IsT2d
113 //purpose  : 
114 //=======================================================================
115
116 Standard_Boolean TopOpeBRepTool_mkTondgE::IsT2d() const
117 {
118   return isT2d;
119 }
120
121 //=======================================================================
122 //function : SetRest
123 //purpose  : 
124 //=======================================================================
125
126 Standard_Boolean TopOpeBRepTool_mkTondgE::SetRest(const Standard_Real pari, const TopoDS_Edge& Ei)
127 {
128   hasRest = Standard_True;
129   Standard_Boolean clEi = TopOpeBRepTool_TOOL::IsClosingE(Ei,myFi);
130   if (clEi) {hasRest = Standard_False; return Standard_False;}
131
132   myEpari.Bind(Ei,pari);
133   return Standard_True;
134 }
135
136 //=======================================================================
137 //function : GetAllRest
138 //purpose  : 
139 //=======================================================================
140
141 Standard_Integer TopOpeBRepTool_mkTondgE::GetAllRest(TopTools_ListOfShape& lEi)
142 {    
143   lEi.Clear();
144
145   BRepAdaptor_Surface bs(myFi);
146   Standard_Real tol3d = bs.Tolerance();
147   Standard_Real tolu = bs.UResolution(tol3d);
148   Standard_Real tolv = bs.VResolution(tol3d);
149   TopExp_Explorer ex(myFi, TopAbs_EDGE);
150   for (; ex.More(); ex.Next()){
151     const TopoDS_Edge& ei = TopoDS::Edge(ex.Current());
152     Standard_Boolean cli = TopOpeBRepTool_TOOL::IsClosingE(ei,myFi);
153     if (cli) continue;
154
155     Standard_Boolean isbi = myEpari.IsBound(ei);
156     if (isbi) {lEi.Append(ei); continue;}
157
158     Standard_Boolean isou,isov; gp_Dir2d d2d; gp_Pnt2d o2d;
159     Standard_Boolean uviso = TopOpeBRepTool_TOOL::UVISO(ei,myFi, isou,isov, d2d,o2d);
160     if (!uviso) continue;
161     
162     Standard_Boolean ok = Standard_False;
163     if (isou) ok = Abs(o2d.X()-myuvi.X()) < tolu;
164     if (isov) ok = Abs(o2d.Y()-myuvi.Y()) < tolv;
165     if (!ok) continue;
166
167     Standard_Real parei;
168     TopOpeBRepTool_TOOL::ParISO(myuvi,ei,myFi, parei);
169     myEpari.Bind(ei,parei);
170     lEi.Append(ei);
171   }
172   Standard_Integer nEi = lEi.Extent();
173   return nEi;
174 }
175
176 static Standard_Boolean FUN_getEc(const TopoDS_Face& f, const TopoDS_Vertex& v, TopoDS_Edge& cle)
177 {
178   TopExp_Explorer exe(f,TopAbs_EDGE); 
179   for (; exe.More(); exe.Next()){
180     const TopoDS_Edge& e  = TopoDS::Edge(exe.Current());
181     Standard_Boolean closed = TopOpeBRepTool_TOOL::IsClosingE(e,f);
182     if (!closed) continue;
183     TopExp_Explorer exv(e,TopAbs_VERTEX);
184     for (; exv.More(); exv.Next()){
185       if (exv.Current().IsSame(v)) {cle = e; return Standard_True;}
186     }
187   }
188   return Standard_False;
189 }
190
191 static Standard_Boolean FUN_MkTonE(const gp_Vec& faxis, const gp_Vec& dirINcle, const gp_Vec& xxi,
192                       const gp_Vec& /*ngf*/, Standard_Real& par1, Standard_Real& par2, Standard_Boolean& outin)
193 {
194    // tgi  / (tgi,xxi,faxis) is direct :
195   gp_Vec tgi = xxi.Crossed(faxis);
196     
197   // ******************** getting par1, par2
198   // at par1 : tr(dge, ei/fi) = forward
199   // at par2 : tr(dge, ei/fi) = forward
200   Standard_Real tola = FUN_tola();
201   Standard_Real dot1 = dirINcle.Dot(xxi);
202   Standard_Boolean isONi = (Abs(dot1) < tola);
203   
204   // par1 = ang  -> inout
205   // par2 = Cang -> outin
206   Standard_Real ang = 1.e7;
207   if (isONi) {
208     Standard_Real dot = dirINcle.Dot(tgi);
209     ang = (dot > 0) ? 0 : M_PI;
210 //    outin = (ang > 0); -xpu190499
211     outin = Standard_True;
212   }
213   else {
214     if (!isONi) ang = TopOpeBRepTool_TOOL::Matter(dirINcle,tgi.Reversed(),faxis);    
215     //Standard_Real dot = isONi ? 0 : (dirINcle^tgi).Dot(ngf);
216     Standard_Real dot = isONi ? 0 : (dirINcle^tgi).Dot(faxis);
217     if (dot1 < 0) outin = (dot > 0);
218     else          outin = (dot < 0);
219   }//!isONi
220
221   Standard_Real Cang = (ang > M_PI) ? ang-M_PI : ang+M_PI;
222   par1 = outin ? ang : Cang;
223   par2 = outin ? Cang : ang;
224   return Standard_True;
225 }//FUN_MkTonE
226
227 //=======================================================================
228 //function : MkTonE
229 //purpose  : 
230 //=======================================================================
231
232 Standard_Boolean TopOpeBRepTool_mkTondgE::MkTonE(Standard_Integer& mkT, Standard_Real& par1, Standard_Real& par2)
233 {
234   if (isT2d) return Standard_False;
235
236   mkT = NOI; par1=par2=1.e7;
237   // v : 
238   TopExp_Explorer exv(mydgE, TopAbs_VERTEX);
239   const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
240   // myclE :
241   if (myclE.IsNull()) {
242     Standard_Boolean find = FUN_getEc(myF,v,myclE);
243     if (!find) return Standard_False;
244   }
245
246   // dirINcle : tangent to cle at v oriented INSIDE 1d(cle) 
247   Standard_Integer ovcle; gp_Vec dirINcle; Standard_Boolean ok = TopOpeBRepTool_TOOL::TgINSIDE(v,myclE,dirINcle,ovcle);
248   if (!ok) return NOI;
249    
250   // faxis : describes f's axis for parametrization of <dgE>
251   gp_Vec faxis = myngf;
252   if (ovcle == FORWARD) faxis.Reverse();
253
254   // xxi : normal to fi oriented INSIDE 3d(fi) 
255   gp_Vec xxi; ok = TopOpeBRepTool_TOOL::NggeomF(myuvi,myFi,xxi);    
256   if (!ok) return Standard_False;
257   if (M_FORWARD(myFi.Orientation())) xxi.Reverse();
258
259   // mkT, par1, par2 : 
260   Standard_Boolean outin; ok = FUN_MkTonE(faxis,dirINcle,xxi,myngf, par1,par2,outin);  
261   if (ok) mkT = MKI12;
262   return ok;
263 }
264
265 //=======================================================================
266 //function : MkTonE
267 //purpose  : 
268 //=======================================================================
269
270 Standard_Boolean TopOpeBRepTool_mkTondgE::MkTonE(const TopoDS_Edge& ei, Standard_Integer& mkT, Standard_Real& par1, Standard_Real& par2)
271 // isT2d = true : 
272 //   prequesitory : f,fi are tangent on v
273 //                  dge interfers on v with ei
274 //   purpose : the compute of transition on dge / ei
275 //             at par1 : Tr(dge,e)= ou/in,
276 //             at par2 : Tr(dge,e)= in/ou
277 //
278 // isT2d = false : 
279 //   prequesitory : dge interfers on v with fi
280 //   purpose : the compute of transition on dge / fi
281 //             at par1 : Tr(dge,e)= ou/in,
282 //             at par2 : Tr(dge,e)= in/ou
283 //
284 {  
285   mkT = NOI; par1=par2=1.e7;
286   hasRest = myEpari.IsBound(ei);
287   if (!hasRest) return Standard_False;
288   const Standard_Real pari = myEpari.Find(ei);
289
290   Standard_Real pfi,pli; FUN_tool_bounds(ei,pfi,pli);
291   Standard_Real tolpi = TopOpeBRepTool_TOOL::TolP(ei,myFi);
292   Standard_Boolean onfi = (Abs(pari-pfi) < tolpi), onli = (Abs(pari-pli) < tolpi);
293   gp_Vec tgin1di;Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(pari,ei, tgin1di);
294   if (!ok) return Standard_False;
295   if (onli) tgin1di.Reverse();
296
297   // v :
298   TopExp_Explorer exv(mydgE, TopAbs_VERTEX);
299   const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
300   // myclE :
301   if (myclE.IsNull()) {
302     Standard_Boolean find = FUN_getEc(myF,v,myclE);
303     if (!find) return Standard_False;
304   }
305
306   // dirINcle : tangent to cle at v oriented INSIDE 1d(cle) 
307   Standard_Integer ovcle; gp_Vec dirINcle; ok = TopOpeBRepTool_TOOL::TgINSIDE(v,myclE,dirINcle,ovcle);
308   if (!ok) return NOI;
309
310   if (isT2d && !hasRest) return Standard_False; // no transition to compute
311    
312   // faxis : describes f's axis for parametrization of <dgE>
313   gp_Vec faxis = myngf;
314   if (ovcle == FORWARD) faxis.Reverse();
315   
316   gp_Dir xxi; //isT2d=true : normal to ei oriented INSIDE 2d(fi) 
317               //             normal to fi oriented INSIDE 3d(fi)
318   gp_Dir xxri;//isT2d=true : oriented inside 1d(ei)  
319               //             oriented inside 2d(fi)  
320
321
322   TopoDS_Vertex vclo; Standard_Boolean closedi = TopOpeBRepTool_TOOL::ClosedE(ei,vclo);//@190499
323   Standard_Boolean outin; 
324   if (isT2d) {      
325     // xxi : 
326     ok = TopOpeBRepTool_TOOL::XX(myuvi,myFi,pari,ei,xxi);
327     if (!ok) return Standard_False;
328     
329     // mkT,par1,par2
330     ok = FUN_MkTonE(faxis,dirINcle,xxi,myngf, par1,par2, outin);
331     if (!ok) return Standard_False;
332     
333     if (!onfi && !onli) {mkT = MKI12; return Standard_True;}// => the same for all edges of lei @190499
334     if (closedi)        {mkT = MKI12; return Standard_True;}// onfi || onli @190499
335     
336     // xxri : 
337     xxri = tgin1di;
338
339   }//isT2d
340   else {
341     // xxi : 
342     gp_Vec tmp; ok = TopOpeBRepTool_TOOL::NggeomF(myuvi,myFi,tmp); xxi = gp_Dir(tmp);   
343     if (!ok) return Standard_False;
344     if (M_FORWARD(myFi.Orientation())) xxi.Reverse();
345
346     // mkT,par1,par2
347     ok = FUN_MkTonE(faxis,dirINcle,xxi,myngf, par1,par2, outin);
348     if (!ok) return Standard_False;     
349
350     //// modified by jgv, 21.11.01 for BUC61053 ////
351     ok = TopOpeBRepTool_TOOL::XX(myuvi,myFi, pari,ei, xxri);
352     if (!ok) return Standard_False;
353     
354     mkT = MKI12;  // without restrictions.
355     gp_Vec tgi = xxi.Crossed(faxis);//tgi /(tgi,xxi,faxis) is direct :
356     Standard_Real dot = tgi.Dot(xxri);
357     if (Abs(dot) < FUN_tola())
358       {
359         if (!onfi && !onli || closedi)
360           { mkT = MKI12; return Standard_True; }
361         else
362           dot = tgi.Dot(tgin1di);
363       }
364     Standard_Boolean keepang = (dot > 0);  
365     if (keepang) mkT = outin ? MKI1 : MKI2;
366     else         mkT = outin ? MKI2 : MKI1;
367     return Standard_True;
368     ////////////////////////////////////////////////
369 /*
370     // xxri : 
371     Standard_Real ddot = tgin1di.Dot(faxis);
372     Standard_Boolean tgaxis = Abs(1-(Abs(ddot))) < FUN_tola(); //=true : edge is tangent to sphere's axis
373     if (tgaxis) {
374       ok = TopOpeBRepTool_TOOL::XX(myuvi,myFi, pari,ei, xxri);
375       if (!ok) return Standard_False;
376     }
377     else {
378       if ((!onfi) && (!onli)) {mkT = MKI12; return Standard_True;} // @190499
379       if (closedi)            {mkT = MKI12; return Standard_True;}// onfi || onli @190499
380       xxri = tgin1di;
381     }*/
382   }//!isT2d
383
384   mkT = MKI12;  // without restrictions.
385   gp_Vec tgi = xxi.Crossed(faxis);//tgi /(tgi,xxi,faxis) is direct :
386   Standard_Real dot = tgi.Dot(xxri);
387   Standard_Boolean keepang = (dot > 0);  
388   if (keepang) mkT = outin ? MKI1 : MKI2;
389   else         mkT = outin ? MKI2 : MKI1;
390
391   return Standard_True;
392
393 }