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