0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / CSLib / CSLib_Class2d.cxx
1 // Created on: 1995-03-08
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1995-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 //#define No_Standard_OutOfRange
18
19 #include <CSLib_Class2d.hxx>
20 #include <gp_Pnt2d.hxx>
21 #include <Standard_ConstructionError.hxx>
22
23 static inline 
24   Standard_Real Transform2d(const Standard_Real u,
25                             const Standard_Real umin,
26                             const Standard_Real umaxmumin);
27
28 //=======================================================================
29 //function : Init
30 //purpose  :
31 //=======================================================================
32 template <class TCol_Containers2d>
33 void CSLib_Class2d::Init(const TCol_Containers2d& TP2d,
34                  const Standard_Real aTolu,
35                  const Standard_Real aTolv,
36                  const Standard_Real umin,
37                  const Standard_Real vmin,
38                  const Standard_Real umax,
39                  const Standard_Real vmax)
40 {
41   Umin = umin;
42   Vmin = vmin;
43   Umax = umax;
44   Vmax = vmax;
45   //
46   if ((umax <= umin) || (vmax <= vmin) || (TP2d.Length() < 3))
47   {
48     MyPnts2dX.Nullify();
49     MyPnts2dY.Nullify();
50     N = 0;
51   }
52   //
53   else
54   {
55     Standard_Integer i, iLower;
56     Standard_Real du, dv, aPrc;
57     //
58     aPrc = 1.e-10;
59     N = TP2d.Length();
60     Tolu = aTolu;
61     Tolv = aTolv;
62     MyPnts2dX = new TColStd_Array1OfReal(0, N);
63     MyPnts2dY = new TColStd_Array1OfReal(0, N);
64     du = umax - umin;
65     dv = vmax - vmin;
66     //
67     iLower = TP2d.Lower();
68     for (i = 0; i<N; ++i)
69     {
70       const gp_Pnt2d& aP2D = TP2d(i + iLower);
71       MyPnts2dX->ChangeValue(i) = Transform2d(aP2D.X(), umin, du);
72       MyPnts2dY->ChangeValue(i) = Transform2d(aP2D.Y(), vmin, dv);
73     }
74     MyPnts2dX->ChangeLast() = MyPnts2dX->First();
75     MyPnts2dY->ChangeLast() = MyPnts2dY->First();
76     //
77     if (du>aPrc)
78     {
79       Tolu /= du;
80     }
81     if (dv>aPrc)
82     {
83       Tolv /= dv;
84     }
85   }
86 }
87
88 //=======================================================================
89 //function : CSLib_Class2d
90 //purpose  : 
91 //=======================================================================
92 CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& thePnts2d,
93                              const Standard_Real theTolU,
94                              const Standard_Real theTolV,
95                              const Standard_Real theUMin,
96                              const Standard_Real theVMin,
97                              const Standard_Real theUMax,
98                              const Standard_Real theVMax)
99 {
100   Init(thePnts2d, theTolU, theTolV, theUMin,
101        theVMin, theUMax, theVMax);
102 }
103
104 //=======================================================================
105 //function : CSLib_Class2d
106 //purpose  : 
107 //=======================================================================
108 CSLib_Class2d::CSLib_Class2d(const TColgp_SequenceOfPnt2d& thePnts2d,
109                              const Standard_Real theTolU,
110                              const Standard_Real theTolV,
111                              const Standard_Real theUMin,
112                              const Standard_Real theVMin,
113                              const Standard_Real theUMax,
114                              const Standard_Real theVMax)
115 {
116   Init(thePnts2d, theTolU, theTolV, theUMin,
117        theVMin, theUMax, theVMax);
118 }
119
120 //=======================================================================
121 //function : SiDans
122 //purpose  : 
123 //=======================================================================
124 Standard_Integer CSLib_Class2d::SiDans(const gp_Pnt2d& P) const
125
126   if(!N) {
127     return 0;
128   }
129   //
130   Standard_Real x,y, aTolu, aTolv;
131   //
132   x = P.X(); y = P.Y();
133   aTolu=Tolu*(Umax-Umin);
134   aTolv=Tolv*(Vmax-Vmin);
135   //
136   if(Umin<Umax && Vmin<Vmax)    {
137     if( ( x<(Umin-aTolu) ) || 
138        ( x>(Umax+aTolu) ) || 
139        ( y<(Vmin-aTolv) ) || 
140        ( y>(Vmax+aTolv) ) ) {
141       return -1;
142     }
143     x=Transform2d(x,Umin,Umax-Umin);
144     y=Transform2d(y,Vmin,Vmax-Vmin);
145   }
146
147
148   Standard_Integer res = InternalSiDansOuOn(x,y);
149   if(res==-1) {    
150     return 0;
151   }
152   if(Tolu || Tolv) {
153     if(res != InternalSiDans(x-Tolu,y-Tolv)) return 0;
154     if(res != InternalSiDans(x+Tolu,y-Tolv)) return 0;
155     if(res != InternalSiDans(x-Tolu,y+Tolv)) return 0;
156     if(res != InternalSiDans(x+Tolu,y+Tolv)) return 0; 
157   }
158   //
159   return((res)? 1: -1);
160 }
161 //=======================================================================
162 //function : SiDans_OnMode
163 //purpose  : 
164 //=======================================================================
165 Standard_Integer CSLib_Class2d::SiDans_OnMode(const gp_Pnt2d& P,
166                                               const Standard_Real Tol) const
167
168   if(!N){
169     return 0;
170   }
171   //
172   Standard_Real x,y, aTolu, aTolv;
173   //
174   x = P.X(); y = P.Y();
175   aTolu=Tol; 
176   aTolv=Tol; 
177
178   //-- ****** TO DO LATER, ESTIMATE AT EACH POINT Tol2d depending on Tol3d *****
179   if(Umin<Umax && Vmin<Vmax) { 
180     if(x<(Umin-aTolu) || (x>Umax+aTolu) || 
181        (y<Vmin-aTolv) || (y>Vmax+aTolv)) {
182       return -1;
183     }
184     x=Transform2d(x,Umin,Umax-Umin);
185     y=Transform2d(y,Vmin,Vmax-Vmin);
186   }
187   //
188   Standard_Integer res = InternalSiDansOuOn(x,y);
189   if(aTolu || aTolv) {
190     if(res != InternalSiDans(x-aTolu,y-aTolv)) return 0;
191     if(res != InternalSiDans(x+aTolu,y-aTolv)) return 0;
192     if(res != InternalSiDans(x-aTolu,y+aTolv)) return 0;
193     if(res != InternalSiDans(x+aTolu,y+aTolv)) return 0; 
194   }
195   return((res)? 1: -1);
196 }
197 //=======================================================================
198 //function : InternalSiDans
199 //purpose  : 
200 //=======================================================================
201 Standard_Integer CSLib_Class2d::InternalSiDans(const Standard_Real Px,
202                                                const Standard_Real Py) const
203
204   Standard_Integer nbc, i, ip1, SH, NH;
205   Standard_Real  x, y, nx, ny;
206   //
207   nbc = 0;
208   i   = 0;
209   ip1 = 1;
210   x   = (MyPnts2dX->Value(i)-Px);
211   y   = (MyPnts2dY->Value(i)-Py);
212   SH  = (y<0.)? -1 : 1;
213   //
214   for(i=0; i<N ; i++,ip1++) { 
215     nx = MyPnts2dX->Value(ip1) - Px;
216     ny = MyPnts2dY->Value(ip1) - Py;
217     
218     NH = (ny<0.)? -1 : 1;
219     if(NH!=SH) { 
220       if(x>0. && nx>0.) {
221         nbc++;
222       }
223       else { 
224         if(x>0.0 || nx>0.) { 
225           if((x-y*(nx-x)/(ny-y))>0.) {
226             nbc++;
227           }
228         }
229       }
230       SH = NH;
231     }
232     x = nx; y = ny;
233   }
234   return(nbc&1);
235 }
236 //modified by NIZNHY-PKV Fri Jan 15 09:03:48 2010f
237 //=======================================================================
238 //function : InternalSiDansOuOn
239 //purpose  : same code as above + test on ON (return(-1) in this case
240 //=======================================================================
241 Standard_Integer CSLib_Class2d::InternalSiDansOuOn(const Standard_Real Px,
242                                                    const Standard_Real Py) const 
243
244   Standard_Integer nbc, i, ip1, SH, NH, iRet;
245   Standard_Real x, y, nx, ny, aX;
246   Standard_Real aYmin;
247   //
248   nbc = 0;
249   i   = 0;
250   ip1 = 1;
251   x   = (MyPnts2dX->Value(i)-Px);
252   y   = (MyPnts2dY->Value(i)-Py);
253   aYmin=y;
254   SH  = (y<0.)? -1 : 1;
255   for(i=0; i<N ; i++, ip1++) { 
256    
257     nx = MyPnts2dX->Value(ip1) - Px;
258     ny = MyPnts2dY->Value(ip1) - Py;
259     //-- le 14 oct 97 
260     if(nx<Tolu && nx>-Tolu && ny<Tolv && ny>-Tolv) { 
261       iRet=-1;
262       return iRet;
263     }
264     //find Y coordinate of polyline for current X gka
265     //in order to detect possible status ON
266     Standard_Real aDx = (MyPnts2dX->Value(ip1) - MyPnts2dX->Value(ip1-1));
267     if( (MyPnts2dX->Value(ip1-1) - Px) * nx < 0.)
268     {
269      
270       Standard_Real aCurPY = MyPnts2dY->Value(ip1) - (MyPnts2dY->Value(ip1) - MyPnts2dY->Value(ip1-1))/aDx *nx;
271       Standard_Real aDeltaY = aCurPY - Py;
272       if(aDeltaY >= -Tolv && aDeltaY <= Tolv)
273       {
274          iRet=-1;
275          return iRet;
276       }
277     }
278     //
279       
280     NH = (ny<0.)? -1 : 1;
281     if(NH!=SH) { 
282       if(x>0. && nx>0.) {
283         nbc++;
284       }
285       else { 
286         if(x>0. || nx>0.) { 
287           aX=x-y*(nx-x)/(ny-y);
288           if(aX>0.){
289             nbc++;
290           }
291         }
292       }
293       SH = NH;
294     }
295     else {// y has same sign as ny  
296       if (ny<aYmin) {
297         aYmin=ny;
298       }
299     }
300     x = nx; y = ny; 
301   }// for(i=0; i<N ; i++,ip1++) { 
302  
303   iRet=nbc&1;
304   return iRet;
305 }
306 //modified by NIZNHY-PKV Fri Jan 15 09:03:55 2010t
307 //=======================================================================
308 //function : Transform2d
309 //purpose  : 
310 //=======================================================================
311 Standard_Real Transform2d(const Standard_Real u,
312                           const Standard_Real umin,
313                           const Standard_Real umaxmumin) 
314
315   if(umaxmumin>1e-10) { 
316     Standard_Real U = (u-umin)/umaxmumin;
317     return U;
318   }
319   else { 
320     return u;
321   }
322 }