Merging OCC22105, OCC22354, OCC22150 , OCC22199 , OCC22391 and OCC22108
[occt.git] / src / OpenGl / OpenGl_pick.cxx
CommitLineData
7fd59977 1/***********************************************************************
2
3FONCTION :
4----------
5File OpenGl_pick :
6
7
8REMARQUES:
9----------
10
11HISTORIQUE DES MODIFICATIONS :
12--------------------------------
13xx-xx-xx : xxx ; Creation.
1425-06-96 : FMN ; Suppression utilisation de glScissor.
1503-07-96 : FMN ; Suppression TelGetViewportAtLocation.
16
17************************************************************************/
18
19/*----------------------------------------------------------------------*/
20/*
21* Includes
22*/
23
24#include <OpenGl_tgl_all.hxx>
25
26#include <stdio.h>
27
28#include <GL/gl.h>
29
30#include <OpenGl_tsm.hxx>
31#include <OpenGl_tsm_ws.hxx>
32#include <OpenGl_telem_pick.hxx>
33#include <OpenGl_telem_view.hxx>
34#include <OpenGl_Memory.hxx>
35
36
37/*----------------------------------------------------------------------*/
38/*
39* Constantes
40*/
41
42#define ARRAY_GROW_SIZE 10
43
44
45/*----------------------------------------------------------------------*/
46/*
47* Variables statiques
48*/
49
50static GLuint *tgl_pick_buffer; /* buffer to be given to GL */
51static Tint tgl_pick_bufsize;
52
53
54/*----------------------------------------------------------------------*/
55
56static TStatus
57allocate( Tint *cur_size, Tint size_reqd, void **arr, Tint elem_size )
58{
59 size_reqd = ( ( size_reqd / ARRAY_GROW_SIZE ) + 1 ) * ARRAY_GROW_SIZE;
60
61 if( !( *cur_size ) ) {
62 *arr = malloc( size_reqd * elem_size );
63 memset( *arr, 0, size_reqd * elem_size );
64 }
65 else
66#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
67 *arr = realloc( *arr, size_reqd * elem_size );
68#else
69 *arr = (void*)cmn_resizemem<char>( (char*)*arr, size_reqd * elem_size );
70#endif
71
72 if( !(*arr) )
73 return TFailure;
74
75 *cur_size = size_reqd;
76 return TSuccess;
77}
78
79static TStatus
80Initialize( Tint wsid, Tint *view_stid )
81{
82 Tint depth;
83 CMN_KEY_DATA key;
84 Tint buf_siz_reqd = 0;
85
86 TsmGetWSAttri( wsid, WSViewStid, &key );
87 if( key.ldata == -1 )
88 return TFailure;
89
90 *view_stid = key.ldata;
91 TsmGetStructureDepth( *view_stid, &depth );
92
93 buf_siz_reqd = depth*6 + 2;
94
95 if( tgl_pick_bufsize < buf_siz_reqd )
96 {
97 if( allocate( &tgl_pick_bufsize, buf_siz_reqd, (void **)&tgl_pick_buffer,
98 sizeof( int ) ) == TFailure )
99 return TFailure;
100 }
101
102 return TSuccess;
103}
104/*----------------------------------------------------------------------*/
105
106static void
107fill_pick_report( tel_pick_report rep, TPickOrder order, Tint depth )
108{
109 Tint i, j;
110 TEL_PACKED_NAME pn;
111
112 rep->depth = tgl_pick_buffer[0]/6;
113
114 if( order == TTopFirst )
115 {
116 for( i = 0, j = 3; i < ( Tint )(tgl_pick_buffer[0]/6) && i < depth; i++ )
117 { /* skip hit numb. zmin, zmax -> j = 3 */
118 pn.s[0] = tgl_pick_buffer[j++];
119 pn.s[1] = tgl_pick_buffer[j++];
120 rep->pick_path[i].struct_id = pn.i;
121 pn.s[0] = tgl_pick_buffer[j++];
122 pn.s[1] = tgl_pick_buffer[j++];
123 rep->pick_path[i].pick_id = pn.i;
124 pn.s[0] = tgl_pick_buffer[j++];
125 pn.s[1] = tgl_pick_buffer[j++];
126 rep->pick_path[i].el_num = pn.i;
127 }
128 }
129 else
130 {
131 Tint is, js;
132
133 is = rep->depth < depth ? rep->depth : depth;
134 js = 3 + ( rep->depth - is )*6; /* skip hit numb. zmin, zmax -> j = 3 */
135 is--;
136
137 for( i = is, j = js; i >= 0; i-- )
138 {
139 pn.s[0] = tgl_pick_buffer[j++];
140 pn.s[1] = tgl_pick_buffer[j++];
141 rep->pick_path[i].struct_id = pn.i;
142 pn.s[0] = tgl_pick_buffer[j++];
143 pn.s[1] = tgl_pick_buffer[j++];
144 rep->pick_path[i].pick_id = pn.i;
145 pn.s[0] = tgl_pick_buffer[j++];
146 pn.s[1] = tgl_pick_buffer[j++];
147 rep->pick_path[i].el_num = pn.i;
148 }
149 }
150
151 return;
152}
153/*----------------------------------------------------------------------*/
154
155Tint TglVpBeingPicked = -1;
156
157TStatus
158TPick( Tint Wsid, Tint x, Tint y, Tfloat apw, Tfloat aph,
159 TPickOrder order, Tint depth, tel_pick_report rep )
160{
161 Tint vid;
162 TSM_ELEM_DATA data;
163 CMN_KEY key;
164 CMN_KEY_DATA key1;
165 TEL_VIEW_REP ovrep, vrep;
166
167 if( Initialize( Wsid, &(data.ldata) ) == TFailure )
168 return TFailure;
169
170 TglActiveWs = Wsid;
171 key.id = Wsid;
172
173 {
174 /* TStatus stat; */
175 Tfloat xsf, ysf, x1, x2, y1, y2, W, H, xm, xp, ym, yp, cx, cy;
176 Tint err;
177 TEL_VIEW_MAPPING map;
178
179 vid = Wsid;
180 TglVpBeingPicked = vid;
181 TelGetViewRepresentation( Wsid, vid, &vrep );
182 ovrep = vrep;
183
184 TsmGetWSAttri( Wsid, WSWidth, &key1 );
185 W = ( float )key1.ldata;
186 TsmGetWSAttri( Wsid, WSHeight, &key1 );
187 H = ( float )key1.ldata;
188
189 xm = vrep.extra.map.window.xmax, xp = vrep.extra.map.window.xmin;
190 ym = vrep.extra.map.window.ymax, yp = vrep.extra.map.window.ymin;
191 cx = xm + xp, cx /= 2;
192 cy = ym + yp, cy /= 2;
193 x1 = x - apw/2, x2 = x1 + apw, y1 = y - aph/2, y2 = y1 + aph;
194 xsf = xm - xp, xsf /= W;
195 ysf = ym - yp, ysf /= H;
196 x1 = xsf * x1 + xp;
197 y1 = ysf * y1 + yp;
198 x2 = xsf * x2 + xp;
199 y2 = ysf * y2 + yp;
200
201 map = vrep.extra.map;
202 map.window.xmin = x1, map.window.xmax = x2;
203 map.window.ymin = y1, map.window.ymax = y2;
204 TelEvalViewMappingMatrixPick( &map, &err, vrep.mapping_matrix, cx, cy );
205 if( err )
206 printf( "Error in Mapping pick\n" );
207
208 if( TelSetViewRepresentation( Wsid, vid, &vrep ) == TFailure )
209 printf( "Error in Set vrep for pick\n" );
210 }
211
212 glMatrixMode(GL_MODELVIEW);
213 tgl_pick_buffer[0] = 0;
214 glSelectBuffer( tgl_pick_bufsize , tgl_pick_buffer);
215 glRenderMode(GL_SELECT);
216 glLoadName(55);
217 TsmSendMessage( TelExecuteStructure, PickTraverse, data, 1, &key );
218 glRenderMode(GL_RENDER);
219 TglVpBeingPicked = -1;
220
221 /* print( ); */
222 fill_pick_report( rep, order, depth );
223 TelSetViewRepresentation( Wsid, vid, &ovrep );
224
225 return TSuccess;
226}
227/*----------------------------------------------------------------------*/