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