0024070: OpenGL capped object-level clipping planes
[occt.git] / src / MeshVS / MeshVS_SensitivePolyhedron.cxx
CommitLineData
b311480e 1// Created on: 2005-01-21
2// Created by: Alexander SOLOVYOV
3// Copyright (c) 2005-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <MeshVS_SensitivePolyhedron.ixx>
23
24#include <MeshVS_Tool.hxx>
25#include <CSLib_Class2d.hxx>
26#include <ElCLib.hxx>
27
28//================================================================
29// Function : Constructor MeshVS_SensitivePolyhedron
30// Purpose :
31//================================================================
32MeshVS_SensitivePolyhedron::
33MeshVS_SensitivePolyhedron( const Handle( SelectBasics_EntityOwner )& Owner,
34 const TColgp_Array1OfPnt& Nodes,
35 const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo )
4269bd1b 36: Select3D_SensitiveEntity( Owner ),
7fd59977 37 myTopo( Topo )
38{
39 Standard_Integer low = Nodes.Lower(), up = Nodes.Upper(), i;
40
41 myNodes = new TColgp_HArray1OfPnt ( low, up );
42 for( i=low; i<=up; i++ )
43 myNodes->SetValue( i, Nodes.Value( i ) );
44
45 myNodes2d = new TColgp_HArray1OfPnt2d( low, up );
46}
47
48//================================================================
49// Function : Project
50// Purpose :
51//================================================================
4952a30a 52void MeshVS_SensitivePolyhedron::Project( const Handle(Select3D_Projector)& aProjector )
7fd59977 53{
7fd59977 54 if( myNodes.IsNull() || myNodes2d.IsNull() )
55 return;
56
57 Standard_Integer low = myNodes->Lower(),
58 up = myNodes->Upper();
59
60 gp_Pnt pnt;
61 gp_Pnt2d proj;
62
63 Standard_Boolean hasLoc = HasLocation();
64
65 myCenter = gp_XY( 0, 0 );
66
67 for( Standard_Integer i=low; i<=up; i++ )
68 {
69 pnt = myNodes->Value( i );
70 if( !hasLoc )
4952a30a 71 aProjector->Project( pnt, proj );
7fd59977 72 else
4952a30a 73 aProjector->Project( pnt.Transformed( Location().Transformation() ), proj );
7fd59977 74
75 myNodes2d->SetValue( i, proj.XY() );
76 myCenter += proj.XY();
77 }
78
79 myCenter /= ( up-low+1 );
80}
81
82//================================================================
83// Function : GetConnected
84// Purpose :
85//================================================================
86Handle( Select3D_SensitiveEntity ) MeshVS_SensitivePolyhedron::GetConnected
87 ( const TopLoc_Location& aLocation )
88{
89 Handle( MeshVS_SensitivePolyhedron ) NewEnt = new
90 MeshVS_SensitivePolyhedron( myOwnerId, myNodes->Array1(), myTopo );
91
92 if( HasLocation() )
93 NewEnt->SetLocation( Location() );
94
95 NewEnt->UpdateLocation( aLocation );
96
97 return NewEnt;
98}
99
100//================================================================
101// Function : sort
102// Purpose :
103//================================================================
104void sort( Standard_Real& a, Standard_Real& b )
105{
106 if( a>b )
107 {
108 Standard_Real temp = a; a = b; b = temp;
109 }
110}
111
112//================================================================
113// Function : Matches
114// Purpose :
115//================================================================
4269bd1b 116Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const SelectBasics_PickArgs& thePickArgs,
117 Standard_Real& /*theMatchDMin*/,
118 Standard_Real& theMatchDepth )
7fd59977 119{
120 if( myNodes2d.IsNull() || myTopo.IsNull() )
121 return Standard_False;
122
123 Standard_Integer R1 = myTopo->Lower(),
124 R2 = myTopo->Upper(),
125 low = myNodes2d->Lower();
126
4269bd1b 127 Standard_Real rTol = thePickArgs.Tolerance() * SensitivityFactor();
7fd59977 128
129 Standard_Boolean inside = Standard_False;
130
131 // "odd-even" algorithm: with ray parallel axis of absciss and toward positive
132 for( Standard_Integer i=R1; i<=R2 && !inside; i++ )
133 {
134 Standard_Integer intersect = 0, cur, next, C1 = 1, C2 = myTopo->Value( i ).Length();
135 Standard_Real k, b, // y=kx+b -- equation of polygon's edge
136 x1, y1, x2, y2, xp; // auxiliary points
137
138 for( Standard_Integer j=C1; j<=C2; j++ )
139 {
140 cur = myTopo->Value( i ).Value( j );
141 next = myTopo->Value( i ).Value( j<C2 ? j+1 : C1 );
142
143 x1 = myNodes2d->Value( low+cur ).X(),
144 y1 = myNodes2d->Value( low+cur ).Y(),
145 x2 = myNodes2d->Value( low+next ).X(),
146 y2 = myNodes2d->Value( low+next ).Y();
147
148 if( Abs( x2-x1 )<Precision::Confusion() )
4269bd1b 149 {
7fd59977 150 //vertical edge!!!
151
152 sort( y1, y2 );
4269bd1b 153 if ( thePickArgs.Y() >= y1 - rTol && thePickArgs.Y() <= y2 + rTol && x1 > thePickArgs.X() - rTol )
7fd59977 154 intersect++;
155 }
156 else
4269bd1b 157 {
7fd59977 158 //inclined edge!!!
159
160 k = ( y2-y1 ) / ( x2-x1 );
161 b = y1 - k*x1;
162
163 if( Abs( k )>Precision::Confusion() )
164 {
4269bd1b 165 xp = ( thePickArgs.Y() - b ) / k; // absciss of point of intersection
7fd59977 166 sort( x1, x2 );
4269bd1b 167 if( xp >= x1 && xp <= x2 && xp > thePickArgs.X() - rTol )
7fd59977 168 intersect++;
169 }
170 }
171 }
172 inside = ( intersect%2 ) == 1;
173 }
174
175 if( inside )
4952a30a 176 {
4269bd1b 177 theMatchDepth = ComputeDepth (thePickArgs.PickLine());
178
179 return !thePickArgs.IsClipped(theMatchDepth);
4952a30a 180 }
4269bd1b 181
4952a30a 182 return Standard_False;
7fd59977 183}
184
185//================================================================
186// Function : Matches
187// Purpose :
188//================================================================
189Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real XMin,
190 const Standard_Real YMin,
191 const Standard_Real XMax,
192 const Standard_Real YMax,
193 const Standard_Real aTol )
194{
195 Standard_Real rTol = aTol*SensitivityFactor();
196
197 return myCenter.X()>=XMin-rTol && myCenter.X()<=XMax+rTol &&
198 myCenter.Y()>=YMin-rTol && myCenter.Y()<=YMax+rTol;
199}
200
201//================================================================
202// Function : Matches
203// Purpose :
204//================================================================
205Standard_Boolean MeshVS_SensitivePolyhedron::Matches
206 ( const TColgp_Array1OfPnt2d& Polyline,
207 const Bnd_Box2d& aBox,
208 const Standard_Real aTol )
209{
210 Standard_Real Umin, Vmin, Umax, Vmax;
211 aBox.Get( Umin, Vmin, Umax, Vmax );
212
213 CSLib_Class2d aClassifier2d( Polyline, aTol, aTol, Umin, Vmin, Umax, Vmax );
214
215 Standard_Integer res = aClassifier2d.SiDans( myCenter );
216 return( res==1 );
217}
218
219//================================================================
220// Function : FindIntersection
221// Purpose :
222//================================================================
223Standard_Real MeshVS_SensitivePolyhedron::FindIntersection
224 ( const TColStd_SequenceOfInteger& NodesIndices,
225 const gp_Lin& EyeLine) const
226{
227 Standard_Real val( Precision::Infinite() );
228 for( Standard_Integer i=1, n=NodesIndices.Length(); i<=n; i++ )
4269bd1b 229 val = Min( val, ElCLib::Parameter(
7fd59977 230 EyeLine, myNodes->Value( myNodes->Lower()+NodesIndices.Value( i ) ) ) );
231
232 return val;
233}
234
235//================================================================
236// Function : ComputeDepth
237// Purpose :
238//================================================================
239Standard_Real MeshVS_SensitivePolyhedron::ComputeDepth( const gp_Lin& EyeLine ) const
240{
241 Standard_Real val = Precision::Infinite();
242
243 if( !myTopo.IsNull() )
244 for( Standard_Integer i=myTopo->Lower(), up=myTopo->Upper(); i<=up; i++ )
245 val = Min( val, FindIntersection( myTopo->Value( i ), EyeLine ) );
246
247 return val;
248}
249
250//================================================================
251// Function : ComputeSize
252// Purpose :
253//================================================================
254/*Standard_Real MeshVS_SensitivePolyhedron::ComputeSize() const
255{
256 Bnd_Box2d aBox;
257 GetBox2d( aBox );
258
259 Standard_Real aXmin, aYmin, aXmax, aYmax;
260 aBox.Get( aXmin, aYmin, aXmax, aYmax );
261 return Abs( ( aXmax-aXmin ) * ( aYmax-aYmin ) );
262} */
263
264//================================================================
265// Function : Areas
266// Purpose :
267//================================================================
4269bd1b 268void MeshVS_SensitivePolyhedron::Areas( SelectBasics_ListOfBox2d& aResult )
7fd59977 269{
270 Bnd_Box2d aBox;
271 GetBox2d( aBox );
272 aResult.Append( aBox );
273}
274
275//================================================================
276// Function : GetBox2d
277// Purpose :
278//================================================================
279void MeshVS_SensitivePolyhedron::GetBox2d( Bnd_Box2d& aBox ) const
280{
281 aBox.SetVoid();
282
283 Standard_Real xmin = 0., ymin = 0., xmax = 0., ymax = 0., x, y;
284 Standard_Integer low = myNodes2d->Lower(),
285 up = myNodes2d->Upper();
286
287 if( !myNodes2d.IsNull() )
288 {
289 xmin = xmax = myNodes2d->Value( low ).X();
290 ymin = ymax = myNodes2d->Value( low ).Y();
291 for( Standard_Integer i=low+1; i<=up; i++ )
292 {
293 x = myNodes2d->Value( i ).X();
294 y = myNodes2d->Value( i ).Y();
295 if( x>xmax )
296 xmax = x;
297 else if( x<xmin )
298 xmin = x;
299 if( y>ymax )
300 ymax = y;
301 else if( y<ymin )
302 ymin = y;
303 }
304 }
305
306 aBox.Update( xmin, ymin, xmax, ymax );
307}