0024168: Eliminate CLang compiler warning -Wunused-variable
[occt.git] / src / NIS / NIS_View.cxx
CommitLineData
b311480e 1// Created on: 2007-07-06
2// Created by: Alexander GRIGORIEV
3// Copyright (c) 2007-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#include <NIS_View.hxx>
22#include <NIS_InteractiveContext.hxx>
23#include <NIS_InteractiveObject.hxx>
24#include <gp_Ax1.hxx>
25#include <Visual3d_View.hxx>
ffe2bea7
A
26#include <Bnd_B2f.hxx>
27#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
cfd5fa01 28
29#include <OpenGl_GlCore11.hxx>
7fd59977 30
31IMPLEMENT_STANDARD_HANDLE (NIS_View, V3d_OrthographicView)
32IMPLEMENT_STANDARD_RTTIEXT (NIS_View, V3d_OrthographicView)
33
34//=======================================================================
35//function : NIS_View()
36//purpose : Constructor
37//=======================================================================
38
39NIS_View::NIS_View (const Handle(V3d_Viewer)& theViewer,
40 const Handle(Aspect_Window)& theWindow)
cfd5fa01 41 : V3d_OrthographicView (theViewer),
ffe2bea7
A
42 myIsTopHilight(Standard_False),
43 myDoHilightSelected(Standard_True)
7fd59977 44{
ffe2bea7
A
45 if (!theWindow.IsNull())
46 V3d_View::SetWindow (theWindow, NULL, &MyCallback, this);
7fd59977 47}
48
49//=======================================================================
50//function : SetWindow
cfd5fa01 51//purpose :
7fd59977 52//=======================================================================
53
54void NIS_View::SetWindow(const Handle(Aspect_Window) &theWindow)
55{
ffe2bea7 56 V3d_View::SetWindow (theWindow, NULL, &MyCallback, this);
7fd59977 57}
58
59// //=======================================================================
60// //function : ~NIS_View
61// //purpose : Destructor
62// //=======================================================================
63
64// NIS_View::~NIS_View()
65// {}
66
67
68//=======================================================================
69//function : AddContext
cfd5fa01 70//purpose :
7fd59977 71//=======================================================================
72
73void NIS_View::AddContext (NIS_InteractiveContext * theCtx)
74{
75 // Check that the given context is not among already attached contexts
76 NCollection_List<NIS_InteractiveContext *>::Iterator anIter (myContexts);
77 for (; anIter.More(); anIter.Next())
78 if (anIter.Value() == theCtx)
79 break;
80 if (anIter.More() == Standard_False)
81 myContexts.Append (theCtx);
82}
83
84//=======================================================================
85//function : RemoveContext
cfd5fa01 86//purpose :
7fd59977 87//=======================================================================
88
89void NIS_View::RemoveContext (NIS_InteractiveContext * theCtx)
90{
91 NCollection_List<NIS_InteractiveContext *>::Iterator anIter (myContexts);
92 for (; anIter.More(); anIter.Next())
93 if (anIter.Value() == theCtx) {
94 myContexts.Remove (anIter);
95 break;
96 }
ffe2bea7
A
97
98 NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (theCtx->GetDrawers ());
99 for (; anIterD.More(); anIterD.Next()) {
100 const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
101 if (aDrawer.IsNull() == Standard_False) {
102 aDrawer->UpdateExListId(this);
103 }
104 }
7fd59977 105}
106
107//=======================================================================
108//function : FitAll3d
cfd5fa01 109//purpose :
7fd59977 110//=======================================================================
111
ffe2bea7
A
112Standard_Boolean NIS_View::FitAll3d (const Quantity_Coefficient theCoef)
113{
114 Standard_Boolean aResult(Standard_False);
115 /*
116 Standard_Integer aLimp[4] = { 1000000, -1000000, 1000000, -1000000 };
117 GetBndBox( aLimp[0], aLimp[1], aLimp[2], aLimp[3] );
118 if (aLimp[1] > -1000000 && aLimp[3] > -1000000 &&
119 aLimp[0] < aLimp[1] && aLimp[2] < aLimp[3])
120 {
121 // Scale the view
122 WindowFit (aLimp[0], aLimp[2], aLimp[1], aLimp[3]);
123 aResult = Standard_True;
124 }
125 */
126
127 Bnd_B3f aBox = GetBndBox();
128
129 // Check that the box is not empty
130 if (aBox.IsVoid() == Standard_False && MyView->IsDefined() == Standard_True) {
131 // Convert the 3D box to 2D representation in view coordinates
1d47d8d0 132 Standard_Real Umin = 0.,Umax = 0.,Vmin = 0.,Vmax = 0.,U,V,W;
ffe2bea7
A
133 gp_XYZ aCoord;
134
135 const gp_XYZ aCorner[2] = { aBox.CornerMin(), aBox.CornerMax() };
136
137 Standard_Boolean doFit = Standard_True;
138 while (doFit) {
139
140 for (Standard_Integer i = 0; i < 8; i++) {
141 if (i & 0x1) aCoord.SetX (aCorner[0].X());
142 else aCoord.SetX (aCorner[1].X());
143 if (i & 0x2) aCoord.SetY (aCorner[0].Y());
144 else aCoord.SetY (aCorner[1].Y());
145 if (i & 0x4) aCoord.SetZ (aCorner[0].Z());
146 else aCoord.SetZ (aCorner[1].Z());
147
148 MyView->Projects(aCoord.X(), aCoord.Y(), aCoord.Z(), U, V, W);
149 if (i) {
150 Umin = Min(Umin, U); Umax = Max(Umax, U);
151 Vmin = Min(Vmin, V); Vmax = Max(Vmax, V);
152 }
153 else {
154 Umin = Umax = U;
155 Vmin = Vmax = V;
156 }
157 }
158
159 if ( (Umax > Umin) && (Vmax > Vmin) ) {
160 Standard_Real OldUmin,OldUmax,OldVmin,OldVmax;
161 MyViewMapping.WindowLimit(OldUmin, OldVmin, OldUmax, OldVmax);
162 Standard_Real DxvOld = Abs(OldUmax - OldUmin);
163
164 // make a margin
165 Standard_Real Xrp, Yrp, DxvNew, DyvNew;
166
167 DxvNew = Abs(Umax - Umin); DyvNew = Abs(Vmax - Vmin);
168 DxvNew *= (1. + theCoef);
169 DyvNew *= (1. + theCoef);
170
171 Standard_Real aRatio = DxvNew / DxvOld;
172
173 Xrp = (Umin + Umax)/2. ; Yrp = (Vmin + Vmax)/2. ;
174 Umin = Xrp - DxvNew/2. ; Umax = Xrp + DxvNew/2. ;
175 Vmin = Yrp - DyvNew/2. ; Vmax = Yrp + DyvNew/2. ;
176
177 // fit view
178 FitAll(Umin, Vmin, Umax, Vmax);
179
180 // ratio 1e+6 often gives calculation error(s), reduce it
181 // if (aRatio < 1e+6) doFit = Standard_False;
182 if (aRatio < 100) doFit = Standard_False;
183 aResult = Standard_True;
184 }
185 else doFit = Standard_False;
186
187 }
188 }
189
190 return aResult;
191}
192
193//=======================================================================
194//function : GetBndBox
cfd5fa01 195//purpose :
ffe2bea7
A
196//=======================================================================
197
198Bnd_B3f NIS_View::GetBndBox() const
7fd59977 199{
200 // Calculate the 3D bounding box of visible objects
201 // in all interactive contexts
202 Bnd_B3f aBox;
203 NCollection_List<NIS_InteractiveContext *>::Iterator anIterC (myContexts);
204 for (; anIterC.More(); anIterC.Next()) {
205 NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD
206 (anIterC.Value()->myDrawers);
207 for (; anIterD.More(); anIterD.Next()) {
208 const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
209 Bnd_B3f aBoxD = aDrawer->GetBox (this);
210 aBox.Add (aBoxD);
211 }
212 }
213
7fd59977 214 // Take the bounding box of AIS objects displayed in the view
215 Standard_Real aVal[6];
216 View()->MinMaxValues(aVal[0], aVal[1], aVal[2], aVal[3], aVal[4], aVal[5]);
217 if (aVal[3] < 0.5 * RealLast()) {
218 aBox.Add (gp_XYZ (aVal[0], aVal[1], aVal[2]));
219 aBox.Add (gp_XYZ (aVal[3], aVal[4], aVal[5]));
220 }
221
ffe2bea7
A
222 return aBox;
223}
224
225//=======================================================================
226//function : GetBndBox
cfd5fa01 227//purpose :
ffe2bea7
A
228//=======================================================================
229
cfd5fa01 230void NIS_View::GetBndBox( Standard_Integer& theXMin, Standard_Integer& theXMax,
ffe2bea7
A
231 Standard_Integer& theYMin, Standard_Integer& theYMax ) const
232{
cfd5fa01 233 theXMin = theYMin = 0;
ffe2bea7
A
234 theXMax = theYMax = -1;
235
236 Bnd_B3f aBox = GetBndBox();
237
7fd59977 238 // Check that the box is not empty
239 if (aBox.IsVoid() == Standard_False) {
240 // Convert the 3D box to 2D representation in pixel coordinates
241 gp_XYZ aCoord;
242 Standard_Integer anXp, anYp;
243 const gp_XYZ aCorner[2] = { aBox.CornerMin(), aBox.CornerMax() };
244 Standard_Integer aLimp[4] = { 1000000, -1000000, 1000000, -1000000 };
245 for (Standard_Integer i = 0; i < 8; i++) {
246 if (i & 0x1) aCoord.SetX (aCorner[0].X());
247 else aCoord.SetX (aCorner[1].X());
248 if (i & 0x2) aCoord.SetY (aCorner[0].Y());
249 else aCoord.SetY (aCorner[1].Y());
250 if (i & 0x4) aCoord.SetZ (aCorner[0].Z());
251 else aCoord.SetZ (aCorner[1].Z());
252 Convert( aCoord.X(), aCoord.Y(), aCoord.Z(), anXp, anYp );
253 if (aLimp[0] > anXp) aLimp[0] = anXp;
254 if (aLimp[1] < anXp) aLimp[1] = anXp;
255 if (aLimp[2] > anYp) aLimp[2] = anYp;
256 if (aLimp[3] < anYp) aLimp[3] = anYp;
257 }
258 if (aLimp[0] < aLimp[1] && aLimp[2] < aLimp[3])
259 {
260 // Scale the view
cfd5fa01 261 // WindowFit (aLimp[0], aLimp[2], aLimp[1], aLimp[3]);
ffe2bea7
A
262 theXMin = aLimp[0];
263 theXMax = aLimp[1];
264 theYMin = aLimp[2];
265 theYMax = aLimp[3];
cfd5fa01 266 }
7fd59977 267 }
268}
269
270
271//=======================================================================
272//function : MyCallback
cfd5fa01 273//purpose :
7fd59977 274//=======================================================================
275
276int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
cfd5fa01 277 void* ptrData,
b299a91c 278 Aspect_GraphicCallbackStruct* callData /* call data */)
7fd59977 279{
b299a91c
A
280 // Avoid multiple rendering of the scene ( accordingly with update of
281 // callback mechanism, that invokes additional callbacks before
282 // underlay and overlay redrawing with OCC_PRE_REDRAW and OCC_PRE_OVERLAY
283 // bits added to the "reason" value of the callback data structure;
284 // see comments to OCC_REDRAW_ADDITIONAL_CALLBACKS definition )
285 if (callData->reason & OCC_REDRAW_ADDITIONAL_CALLBACKS)
286 return 0;
cfd5fa01 287
7fd59977 288 const Handle(NIS_View) thisView (static_cast<NIS_View *> (ptrData));
289 NCollection_List<NIS_InteractiveContext *>::Iterator anIter;
290#ifdef CLIP
291 // Find the bounding box of all displayed objects by summing the boxes stored
292 // in the relevant DrawList instances.
293 Bnd_B3f aBndBox;
294 for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
295 anIter.Value()->GetBox (aBndBox, pView);
296
297 if (aBndBox.IsVoid() == Standard_False) {
298 const gp_XYZ aBoxSize = 0.5 * (aBndBox.CornerMax() - aBndBox.CornerMin());
299 const gp_XYZ aBoxCenter = 0.5 * (aBndBox.CornerMax() + aBndBox.CornerMin());
300
301 // Find the ray passing through the clicked point in the view window.
302 Standard_Real anX, anY, aZ;
303 thisView->Convert(0, 0, anX, anY, aZ); // 3D point for the 3D coordinates
304 const gp_Pnt anEye (anX, anY, aZ);
305 thisView->Proj (anX, anY, aZ); // vector orthogonal to the view plane
306 const gp_Dir aProj (anX, anY, aZ);
307 const gp_Ax1 anAxis (anEye, aProj);
308
309 const Standard_Real aCenterDist = (anEye.XYZ() - aBoxCenter) * aProj.XYZ();
310 const Standard_Real aBoxExtent /*(fabs(aBoxSize.X() * anX) +
311 fabs(aBoxSize.Y() * anY) +
312 fabs(aBoxSize.Z() * aZ))*/(100.);
313
314#define FRONT_CLIPPING_PLANE (GL_CLIP_PLANE0 + 0)
315#define BACK_CLIPPING_PLANE (GL_CLIP_PLANE0 + 1)
316 Standard_Real arr[4] = {
317 0.0, /* Nx */
318 0.0, /* Ny */
319 1.0, /* Nz */
320 0.
321 };
322 arr[3] = aBoxExtent + 1.;
323 glClipPlane (BACK_CLIPPING_PLANE, arr);
324 glEnable (BACK_CLIPPING_PLANE);
325 arr[2] = -1.0;
326 arr[3] = aBoxExtent + 1.;
327 glClipPlane (FRONT_CLIPPING_PLANE, arr);
328 glEnable (FRONT_CLIPPING_PLANE);
329 }
330#endif //IS_DISABLED
331
7fd59977 332 GLboolean isDepthWriteMask, isDepthTest;
333 glGetBooleanv(GL_DEPTH_WRITEMASK,&isDepthWriteMask);
334 glGetBooleanv(GL_DEPTH_TEST,&isDepthTest);
335// printf ("GlDepthMask=%d; GlDepthTest=%d\n", depthwritemask, depthtest);
336 glDisableClientState(GL_COLOR_ARRAY);
337 glDisableClientState(GL_EDGE_FLAG_ARRAY);
338 glDisableClientState(GL_INDEX_ARRAY);
339 glDisableClientState(GL_NORMAL_ARRAY);
340 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
341 if (!isDepthTest) {
342 glEnable(GL_DEPTH_TEST);
343 glDepthFunc(GL_LESS);
344 glClearDepth(1.);
345 glClear(GL_DEPTH_BUFFER_BIT);
346 }
347
ffe2bea7
A
348 TColStd_MapIteratorOfPackedMapOfInteger anIterM(thisView->myExListId);
349 for (; anIterM.More(); anIterM.Next())
350 if (anIterM.Key() != 0) {
351#ifdef ARRAY_LISTS
352 glDeleteLists (anIterM.Key(), 5);
353#else
354 glDeleteLists (anIterM.Key(), 1);
355 }
356#endif
357 thisView->myExListId.Clear();
358
7fd59977 359 for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
360 anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Normal);
ffe2bea7
A
361
362 // #818151 - selected object is hidden by covered unselected one
363 // display hilighted objects always above the rest ones
364 if (thisView->myIsTopHilight == Standard_True) {
365 glDepthFunc(GL_ALWAYS);
366 }
367
7fd59977 368 for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
369 anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Hilighted);
370 for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
371 anIter.Value()->redraw (thisView, NIS_Drawer::Draw_DynHilighted);
ffe2bea7
A
372 for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
373 anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Transparent);
374
375 // draw top objects always above
376 if (thisView->myIsTopHilight == Standard_False) {
377 glDepthFunc(GL_ALWAYS);
378 }
379
380 for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
381 anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Top);
7fd59977 382
383 return 0;
384}
385
386//=======================================================================
387//function : DynamicHilight
cfd5fa01 388//purpose :
7fd59977 389//=======================================================================
390
391void NIS_View::DynamicHilight (const Standard_Integer theX,
392 const Standard_Integer theY)
393{
ffe2bea7 394 myDetected.Clear();
7fd59977 395 const Handle(NIS_InteractiveObject) aSelected = Pick (theX, theY);
396
cfd5fa01 397 // ASV: if at least one Context returns IsSelectable()==False,
7fd59977 398 // hilight is canceled, this method returns
399 if (aSelected.IsNull() == Standard_False) {
400 if (aSelected->IsSelectable() == Standard_False)
401 return;
402 }
403 if (aSelected != myDynHilighted) {
404 const Handle(NIS_View) aView (this);
405 if (myDynHilighted.IsNull() == Standard_False)
ffe2bea7
A
406 if (myDynHilighted->GetDrawer().IsNull() == Standard_False)
407 myDynHilighted->GetDrawer()->SetDynamicHilighted(Standard_False,
408 myDynHilighted, aView);
409
410 // 30.07.10 - NKV - synchronize behaviour with AIS interactive context (if need)
411 if (aSelected.IsNull() ||
cfd5fa01 412 (myDoHilightSelected == Standard_False &&
ffe2bea7
A
413 aSelected->GetDrawer()->GetContext()->IsSelected(aSelected)))
414 {
7fd59977 415 myDynHilighted.Nullify();
ffe2bea7 416 }
7fd59977 417 else {
418 aSelected->GetDrawer()->SetDynamicHilighted (Standard_True,
419 aSelected, aView);
420 myDynHilighted = aSelected;
421 }
422 Redraw();
423 }
424}
425
426//=======================================================================
427//function : DynamicUnhilight
cfd5fa01 428//purpose :
7fd59977 429//=======================================================================
430
431void NIS_View::DynamicUnhilight(const Handle_NIS_InteractiveObject& theObj)
432{
433 if (theObj == myDynHilighted && theObj.IsNull() == Standard_False) {
434 const Handle(NIS_View) aView (this);
ffe2bea7
A
435 if (myDynHilighted->GetDrawer().IsNull() == Standard_False)
436 myDynHilighted->GetDrawer()->SetDynamicHilighted (Standard_False,
437 myDynHilighted, aView);
7fd59977 438 myDynHilighted.Nullify();
439 Redraw();
440 }
441}
442
443//=======================================================================
444//function : Select
445//purpose : selection by single click
446//=======================================================================
447
448void NIS_View::Select (const Standard_Integer theX,
449 const Standard_Integer theY,
ffe2bea7
A
450 const Standard_Boolean isForceMultiple,
451 const Standard_Boolean theRedraw)
7fd59977 452{
ffe2bea7 453 myDetected.Clear();
7fd59977 454 const Handle(NIS_InteractiveObject) aSelected = Pick (theX, theY);
455 NCollection_List<NIS_InteractiveContext *>::Iterator anIter (myContexts);
456 for (; anIter.More(); anIter.Next())
457 anIter.Value()->ProcessSelection (aSelected, isForceMultiple);
458 if (aSelected == myDynHilighted && aSelected.IsNull() == Standard_False)
459 {
460 myDynHilighted.Nullify();
461 const Handle(NIS_Drawer)& aDrawer = aSelected->GetDrawer();
462 aDrawer->SetDynamicHilighted (Standard_False, aSelected, this);
463 }
ffe2bea7 464 if (theRedraw) Redraw();
7fd59977 465}
466
467//=======================================================================
468//function : Select
469//purpose : selection by rectange
470//=======================================================================
471
472void NIS_View::Select (const Standard_Integer theXmin,
473 const Standard_Integer theYmin,
474 const Standard_Integer theXmax,
475 const Standard_Integer theYmax,
476 const Standard_Boolean isForceMult,
ffe2bea7
A
477 const Standard_Boolean isFullyIncluded,
478 const Standard_Boolean theRedraw)
7fd59977 479{
ffe2bea7 480 myDetected.Clear();
7fd59977 481 Standard_Real anX, anY, aZ;
482 if (theXmin == theXmax || theYmin == theYmax)
483 return;
484
485 //Transformed box corresponding to the selected rectangle
486 Proj (anX, anY, aZ); // vector orthogonal to the view plane
487 const gp_Dir aProj (anX, anY, aZ);
488
489 Convert(theXmin, theYmin, anX, anY, aZ); // 3D point for the 3D coordinates
490 const gp_Pnt anEye (anX, anY, aZ);
491
492 Convert(theXmax, theYmin, anX, anY, aZ); // 3D point for the 3D coordinates
493 const gp_XYZ anXdir (gp_XYZ(anX, anY, aZ) - anEye.XYZ());
494 const gp_Ax3 anAx3 (anEye, aProj, anXdir);
495 gp_Trsf aTrf;
496 aTrf.SetTransformation (anAx3);
497 const gp_Trsf aTrfInv = aTrf.Inverted();
498
499 Convert(theXmax, theYmax, anX, anY, aZ); // 3D point for the 3D coordinates
500 gp_XYZ anUpperCorner (anX, anY, aZ);
501 aTrf.Transforms(anUpperCorner);
502
503 // Selecting box
504 Bnd_B3f aBoxSel;
505 aBoxSel.Add (gp_XYZ(0., 0., -10000.));
506 aBoxSel.Add (anUpperCorner);
507
508 TColStd_PackedMapOfInteger mapSelected;
509 NCollection_List<NIS_InteractiveContext *>::Iterator anIterC (myContexts);
510 for (; anIterC.More(); anIterC.Next()) {
511 NIS_InteractiveContext * pCtx = anIterC.Value();
512 mapSelected.Clear();
513 pCtx->selectObjects (mapSelected, aBoxSel, aTrfInv, aTrf, isFullyIncluded);
514 pCtx->ProcessSelection (mapSelected, isForceMult);
515 }
ffe2bea7 516 if (theRedraw) Redraw();
7fd59977 517}
518
ffe2bea7
A
519//=======================================================================
520//function : Select
521//purpose : Selection by polygon
522//=======================================================================
523
524void NIS_View::Select (const NCollection_List<gp_XY> &thePolygon,
525 const Standard_Boolean isForceMult,
526 const Standard_Boolean isFullyIncluded,
527 const Standard_Boolean theRedraw)
528{
529 myDetected.Clear();
530 if (thePolygon.IsEmpty())
531 return;
532
533 Standard_Real anX, anY, aZ;
534
535 //Transformed box corresponding to the selected rectangle
536 Proj (anX, anY, aZ); // vector orthogonal to the view plane
537 const gp_Dir aProj (anX, anY, aZ);
538
539 const gp_XY &aPf = thePolygon.First();
540 // 3D point for the 3D coordinates
541 Convert((Standard_Integer) aPf.X(), (Standard_Integer) aPf.Y(), anX, anY, aZ);
542 const gp_Pnt anEye (anX, anY, aZ);
543
544 // 3D point for the 3D coordinates
545 const gp_XY &aPl = thePolygon.Last();
546
547 Convert((Standard_Integer) aPl.X(), (Standard_Integer) aPl.Y(), anX, anY, aZ);
548
549 // Compute transformation.
550 const gp_XYZ anXdir (gp_XYZ(anX, anY, aZ) - anEye.XYZ());
476ed21f 551 if (anXdir.Modulus() <= gp::Resolution())
552 {
553 return;
554 }
555
ffe2bea7
A
556 const gp_Ax3 anAx3 (anEye, aProj, anXdir);
557 gp_Trsf aTrf;
558 aTrf.SetTransformation (anAx3);
ffe2bea7
A
559
560 // Prepare list of 2d points of selection polygon.
561 NCollection_List<gp_XY> aPoints;
562 NCollection_List<gp_XY>::Iterator anIter(thePolygon);
563 Bnd_B2f aPolyBox;
564
565 for (; anIter.More(); anIter.Next()) {
566 const gp_XY &aP = anIter.Value();
567
568 Convert((Standard_Integer) aP.X(), (Standard_Integer) aP.Y(), anX, anY, aZ);
569 gp_XYZ aP3d(anX, anY, aZ);
570
571 aTrf.Transforms(aP3d);
572
573 gp_XY aP2d(aP3d.X(), aP3d.Y());
574
575 aPoints.Append(aP2d);
576 aPolyBox.Add(aP2d);
577 }
578
579 TColStd_PackedMapOfInteger mapSelected;
580 NCollection_List<NIS_InteractiveContext *>::Iterator anIterC(myContexts);
581
582 for (; anIterC.More(); anIterC.Next()) {
583 NIS_InteractiveContext * pCtx = anIterC.Value();
584 mapSelected.Clear();
585 pCtx->selectObjects (mapSelected, aPoints, aPolyBox, aTrf, isFullyIncluded);
586 pCtx->ProcessSelection (mapSelected, isForceMult);
587 }
588
589 if (theRedraw) Redraw();
590}
7fd59977 591
592//=======================================================================
593//function : Pick
cfd5fa01 594//purpose :
7fd59977 595//=======================================================================
596
ffe2bea7
A
597Handle_NIS_InteractiveObject NIS_View::Pick (const Standard_Integer theX,
598 const Standard_Integer theY)
7fd59977 599{
600 // Find the ray passing through the clicked point in the view window.
601 Standard_Real anX, anY, aZ, anOver;
602 Convert(theX, theY, anX, anY, aZ); // 3D point for the 3D coordinates
603 const gp_Pnt anEye (anX, anY, aZ);
604 Proj (anX, anY, aZ); // vector orthogonal to the view plane
605 const gp_Dir aProj (-anX, -anY, -aZ);
606 const gp_Ax1 anAxis (anEye, aProj);
607
608 Convert (theX+1, theY+1, anX, anY, aZ);
609 anOver = ((gp_XYZ(anX, anY, aZ) - anEye.XYZ()) ^ aProj.XYZ()).Modulus() * 1.5;
610
611 return Pick(anAxis, anOver, Standard_True);
612}
613
614//=======================================================================
615//function : Pick
cfd5fa01 616//purpose :
7fd59977 617//=======================================================================
618
619Handle_NIS_InteractiveObject NIS_View::Pick
620 (const gp_Ax1& theAxis,
621 const Standard_Real theOver,
ffe2bea7 622 const Standard_Boolean isOnlySelectable)
7fd59977 623{
ffe2bea7 624 typedef NCollection_List<NIS_InteractiveContext::DetectedEnt> LstDetected;
7fd59977 625 Standard_Real aDistance (0.1 * RealLast());
626 Handle(NIS_InteractiveObject) aSelected, aTmpSel;
ffe2bea7 627 LstDetected aDetected;
7fd59977 628
629 NCollection_List<NIS_InteractiveContext *>::Iterator anIterC (myContexts);
630 for (; anIterC.More(); anIterC.Next()) {
631 const Standard_Real aDist =
ffe2bea7 632 anIterC.Value()->selectObject (aTmpSel, aDetected, theAxis, theOver,
7fd59977 633 isOnlySelectable);
634 if (aDist < aDistance) {
635 aDistance = aDist;
636 aSelected = aTmpSel;
637 }
638 }
ffe2bea7
A
639
640 // simple iterating is enough to create list of detected objects
641 // in the order of increasing distance
642 myDetected.Clear();
643 for (LstDetected::Iterator anIt(aDetected); anIt.More(); anIt.Next())
644 myDetected.Append(anIt.Value().PObj);
645
7fd59977 646 return aSelected;
647}
ffe2bea7 648