e7128bccaca5d725b9f92cf89592016ded08545b
[occt.git] / src / StdSelect / StdSelect_ViewerSelector3d.cxx
1 // Created on: 1995-03-15
2 // Created by: Robert COUBLANC
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 #include <StdSelect_ViewerSelector3d.ixx>
18 #include <StdSelect.hxx>
19 #include <SelectBasics_SensitiveEntity.hxx>
20 #include <Graphic3d_AspectLine3d.hxx>
21 #include <gp_Pnt.hxx>
22 #include <gp_Lin.hxx>
23 #include <gp_Pnt2d.hxx>
24 #include <gp_Dir.hxx>
25 #include <gp_Ax3.hxx>
26 #include <gp_GTrsf.hxx>
27 #include <gp_Pln.hxx>
28 #include <Select3D_SensitiveEntity.hxx>
29 #include <Graphic3d_ArrayOfPolylines.hxx>
30 #include <Graphic3d_SequenceOfHClipPlane.hxx>
31 #include <SelectMgr_SelectableObject.hxx>
32 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
33 #include <SelectBasics_ListOfBox2d.hxx>
34 #include <TColgp_HArray1OfPnt.hxx>
35 #include <TColgp_Array1OfPnt.hxx>
36 #include <TColgp_HArray1OfPnt2d.hxx>
37 #include <Select3D_SensitiveCurve.hxx>
38 #include <Select3D_SensitiveSegment.hxx>
39 #include <Select3D_SensitiveFace.hxx>
40 #include <Select3D_SensitiveCircle.hxx>
41 #include <Select3D_SensitivePoint.hxx>
42 #include <Select3D_SensitiveTriangulation.hxx>
43 #include <Select3D_SensitiveTriangle.hxx>
44 #include <Select3D_SensitiveWire.hxx>
45 #include <Select3D_SensitiveEntitySequence.hxx>
46 #include <Select3D_ListOfSensitiveTriangle.hxx>
47 #include <Select3D_SensitiveBox.hxx>
48 #include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
49
50 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
51 #include <Aspect_Grid.hxx>
52 #include <Aspect_TypeOfMarker.hxx>
53 #include <Graphic3d_AspectMarker3d.hxx>
54 #include <Graphic3d_ArrayOfPoints.hxx>
55 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
56 #include <Poly_Connect.hxx>
57 #include <TColStd_HArray1OfInteger.hxx>
58
59 #include <Poly_Array1OfTriangle.hxx>
60 #include <Poly_Triangulation.hxx>
61 #include <OSD_Environment.hxx>
62 #include <V3d.hxx>
63 #include <V3d_View.hxx>
64 #include <V3d_Viewer.hxx>
65 #include <TColgp_SequenceOfPnt.hxx>
66
67 static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
68 {
69   Standard_Integer nFree = 0;
70   Poly_Connect pc(Trg);
71   Standard_Integer t[3];
72   Standard_Integer i, j;
73   for (i = 1; i <= Trg->NbTriangles(); i++)
74   {
75     pc.Triangles (i, t[0], t[1], t[2]);
76     for (j = 0; j < 3; j++)
77       if (t[j] == 0) nFree++;
78   }
79   return nFree;
80 }
81
82 //=======================================================================
83 // Function : Constructor
84 // Purpose  :
85 //=======================================================================
86 StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d()
87 : myProjector (new Select3D_Projector()),
88   myPrevFOV (0.0),
89   myPrevScale (0.0),
90   myPrevOrthographic (Standard_True),
91   mySensMode (StdSelect_SM_WINDOW),
92   myPixelTolerance (2),
93   myToUpdateTolerance (Standard_True)
94 {
95   myPrevAt[0]         = 0.0;
96   myPrevAt[1]         = 0.0;
97   myPrevAt[2]         = 0.0;
98   myPrevUp[0]         = 0.0;
99   myPrevUp[1]         = 0.0;
100   myPrevUp[2]         = 0.0;
101   myPrevProj[0]       = 0.0;
102   myPrevProj[1]       = 0.0;
103   myPrevProj[2]       = 0.0;
104   myPrevAxialScale[0] = 0.0;
105   myPrevAxialScale[1] = 0.0;
106   myPrevAxialScale[2] = 0.0;
107 }
108
109 //=======================================================================
110 // Function : Constructor
111 // Purpose  :
112 //=======================================================================
113 StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d (const Handle(Select3D_Projector)& theProj)
114 : myProjector (theProj),
115   myPrevFOV (0.0),
116   myPrevScale (0.0),
117   myPrevOrthographic (Standard_True),
118   mySensMode (StdSelect_SM_WINDOW),
119   myPixelTolerance (2),
120   myToUpdateTolerance (Standard_True)
121 {
122   myPrevAt[0]         = 0.0;
123   myPrevAt[1]         = 0.0;
124   myPrevAt[2]         = 0.0;
125   myPrevUp[0]         = 0.0;
126   myPrevUp[1]         = 0.0;
127   myPrevUp[2]         = 0.0;
128   myPrevProj[0]       = 0.0;
129   myPrevProj[1]       = 0.0;
130   myPrevProj[2]       = 0.0;
131   myPrevAxialScale[0] = 0.0;
132   myPrevAxialScale[1] = 0.0;
133   myPrevAxialScale[2] = 0.0;
134 }
135
136 //=======================================================================
137 // Function: Convert
138 // Purpose :
139 //=======================================================================
140 void StdSelect_ViewerSelector3d::Convert (const Handle(SelectMgr_Selection)& theSel)
141 {
142   for (theSel->Init(); theSel->More(); theSel->Next())
143   {
144     if (theSel->Sensitive()->NeedsConversion())
145     {
146       Handle(Select3D_SensitiveEntity) aSE = *((Handle(Select3D_SensitiveEntity)*) &(theSel->Sensitive()));
147       aSE->Project (myProjector);
148       if (!tosort)
149       {
150         tosort = Standard_True;
151       }
152     }
153   }
154 }
155
156 //=======================================================================
157 // Function: Set
158 // Purpose :
159 //=======================================================================
160 void StdSelect_ViewerSelector3d::Set (const Handle(Select3D_Projector)& theProj)
161 {
162   myProjector = theProj;
163   toupdate = Standard_True;
164 }
165
166 //=======================================================================
167 // Function: SetSensitivityMode
168 // Purpose :
169 //=======================================================================
170 void StdSelect_ViewerSelector3d::SetSensitivityMode (const StdSelect_SensitivityMode theMode)
171 {
172   mySensMode = theMode;
173   toupdate = Standard_True;
174 }
175
176 //=======================================================================
177 // Function: SetPixelTolerance
178 // Purpose :
179 //=======================================================================
180 void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance)
181 {
182   if (myPixelTolerance != theTolerance)
183   {
184     myPixelTolerance = theTolerance;
185     myToUpdateTolerance = Standard_True;
186   }
187 }
188
189 //=======================================================================
190 // Function: Pick
191 // Purpose :
192 //=======================================================================
193 void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
194                                        const Standard_Integer theYPix,
195                                        const Handle(V3d_View)& theView)
196 {
197   SetClipping (theView->GetClipPlanes());
198   UpdateProj (theView);
199   Standard_Real aPnt3d[3];
200   theView->Convert (theXPix, theYPix,
201                     aPnt3d[0], aPnt3d[1], aPnt3d[2]);
202
203   gp_Pnt2d aPnt2d;
204   myProjector->Project (gp_Pnt (aPnt3d[0], aPnt3d[1], aPnt3d[2]), aPnt2d);
205
206   InitSelect (aPnt2d.X(), aPnt2d.Y());
207 }
208
209 //=======================================================================
210 // Function: Pick
211 // Purpose :
212 //=======================================================================
213 void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
214                                        const Standard_Integer theYPMin,
215                                        const Standard_Integer theXPMax,
216                                        const Standard_Integer theYPMax,
217                                        const Handle(V3d_View)& theView)
218 {
219   if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
220   {
221     SetSensitivity (theView->Convert (myPixelTolerance));
222     myToUpdateTolerance = Standard_False;
223   }
224
225   UpdateProj (theView);
226
227   Standard_Real aX1 = 0.0;
228   Standard_Real aY1 = 0.0;
229   Standard_Real aZ1 = 0.0;
230   Standard_Real aX2 = 0.0;
231   Standard_Real aY2 = 0.0;
232   Standard_Real aZ2 = 0.0;
233   gp_Pnt2d aP2d1;
234   gp_Pnt2d aP2d2;
235
236   theView->Convert (theXPMin, theYPMin, aX1, aY1, aZ1);
237   theView->Convert (theXPMax, theYPMax, aX2, aY2, aZ2);
238   myProjector->Project (gp_Pnt (aX1, aY1, aZ1), aP2d1);
239   myProjector->Project (gp_Pnt (aX2, aY2, aZ2), aP2d2);
240
241   InitSelect (Min (aP2d1.X(), aP2d2.X()),
242               Min (aP2d1.Y(), aP2d2.Y()),
243               Max (aP2d1.X(), aP2d2.X()),
244               Max (aP2d1.Y(), aP2d2.Y()));
245 }
246
247 //=======================================================================
248 // Function: Pick
249 // Purpose : Selection using a polyline
250 //=======================================================================
251 void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
252                                        const Handle(V3d_View)& theView)
253 {
254   if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
255   {
256     SetSensitivity (theView->Convert (myPixelTolerance));
257     myToUpdateTolerance = Standard_False;
258   }
259
260   UpdateProj (theView);
261
262   Standard_Integer aNbPix = thePolyline.Length();
263
264   // Convert pixel
265   Handle(TColgp_HArray1OfPnt2d) aP2d = new TColgp_HArray1OfPnt2d (1, aNbPix);
266
267   for (Standard_Integer aPntIt = 1; aPntIt <= aNbPix; ++aPntIt)
268   {
269     Standard_Integer aXP = (Standard_Integer)(thePolyline (aPntIt).X());
270     Standard_Integer aYP = (Standard_Integer)(thePolyline (aPntIt).Y());
271
272     Standard_Real aX = 0.0;
273     Standard_Real aY = 0.0;
274     Standard_Real aZ = 0.0;
275     gp_Pnt2d aPnt2d;
276
277     theView->Convert (aXP, aYP, aX, aY, aZ);
278     myProjector->Project (gp_Pnt (aX, aY, aZ), aPnt2d);
279
280     aP2d->SetValue (aPntIt, aPnt2d);
281   }
282
283   const TColgp_Array1OfPnt2d& aPolyConvert = aP2d->Array1();
284
285   InitSelect (aPolyConvert);
286 }
287
288 //=======================================================================
289 // Function: DisplayAreas
290 // Purpose : display the activated areas...
291 //=======================================================================
292 void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(V3d_View)& theView)
293 {
294   if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
295   {
296     SetSensitivity (theView->Convert (myPixelTolerance));
297     myToUpdateTolerance = Standard_False;
298   }
299
300   UpdateProj (theView);
301   UpdateSort(); // Updates the activated areas
302
303   if (mystruct.IsNull())
304   {
305     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
306   }
307
308   if (myareagroup.IsNull())
309   {
310     myareagroup  = mystruct->NewGroup();
311   }
312
313   SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive anIt (myentities);
314   Handle(Select3D_Projector) aProjector = StdSelect::GetProjector (theView);
315   aProjector->SetView (theView);
316
317   Standard_Real aXmin = 0.0;
318   Standard_Real aYmin = 0.0;
319   Standard_Real aXmax = 0.0;
320   Standard_Real aYmax = 0.0;
321   gp_Pnt aPbid;
322   SelectBasics_ListOfBox2d aBoxList;
323
324   TColgp_SequenceOfPnt aSeqLines;
325   for (; anIt.More(); anIt.Next())
326   {
327     anIt.Value()->Areas (aBoxList);
328
329     for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next())
330     {
331       aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax);
332
333       aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0);
334       aProjector->Transform (aPbid, aProjector->InvertedTransformation());
335       aSeqLines.Append (aPbid);
336
337       aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0);
338       aProjector->Transform (aPbid, aProjector->InvertedTransformation());
339       aSeqLines.Append (aPbid);
340
341       aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0);
342       aProjector->Transform (aPbid, aProjector->InvertedTransformation());
343       aSeqLines.Append (aPbid);
344
345       aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0);
346       aProjector->Transform (aPbid, aProjector->InvertedTransformation());
347       aSeqLines.Append (aPbid);
348     }
349   }
350
351   if (aSeqLines.Length())
352   {
353     Standard_Integer aN = 0;
354     Standard_Integer aNp = 0;
355     const Standard_Integer aNbl = aSeqLines.Length() / 4;
356
357     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNbl, aNbl);
358     for (aNp = 1, aN = 0; aN < aNbl; aN++)
359     {
360       aPrims->AddBound (5);
361       const gp_Pnt &aPnt1 = aSeqLines (aNp++);
362       aPrims->AddVertex (aPnt1);
363       aPrims->AddVertex (aSeqLines (aNp++));
364       aPrims->AddVertex (aSeqLines (aNp++));
365       aPrims->AddVertex (aSeqLines (aNp++));
366       aPrims->AddVertex (aPnt1);
367     }
368     myareagroup->AddPrimitiveArray (aPrims);
369   }
370
371   myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
372   myareagroup->Structure()->SetDisplayPriority (10);
373   myareagroup->Structure()->Display();
374
375   theView->Update();
376 }
377
378 //=======================================================================
379 // Function: ClearAreas
380 // Purpose :
381 //=======================================================================
382 void StdSelect_ViewerSelector3d::ClearAreas (const Handle(V3d_View)& theView)
383 {
384   if (myareagroup.IsNull())
385   {
386     return;
387   }
388
389   myareagroup->Clear();
390
391   if (!theView.IsNull())
392   {
393     theView->Update();
394   }
395 }
396
397 //=======================================================================
398 // Function: UpdateProj
399 // Purpose :
400 //=======================================================================
401 Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj (const Handle(V3d_View)& theView)
402 {
403   // Check common properties of camera
404   Standard_Real anUp[3];
405   Standard_Real aProj[3];
406   Standard_Real anAxialScale[3];
407   theView->Up (anUp[0], anUp[1], anUp[2]);
408   theView->Proj (aProj[0], aProj[1], aProj[2]);
409   theView->AxialScale (anAxialScale[0], anAxialScale[1], anAxialScale[2]);
410
411   Standard_Boolean isOrthographic = theView->Type() == V3d_ORTHOGRAPHIC;
412   Standard_Boolean toUpdateProjector = myPrevOrthographic  != isOrthographic
413                                     || myPrevUp[0]         != anUp[0]
414                                     || myPrevUp[1]         != anUp[1]
415                                     || myPrevUp[2]         != anUp[2]
416                                     || myPrevProj[0]       != aProj[0]
417                                     || myPrevProj[1]       != aProj[1]
418                                     || myPrevProj[2]       != aProj[2]
419                                     || myPrevAxialScale[0] != anAxialScale[0]
420                                     || myPrevAxialScale[1] != anAxialScale[1]
421                                     || myPrevAxialScale[2] != anAxialScale[2];
422
423   // Check properties of perspective camera
424   Standard_Real anAt[3];
425   Standard_Real aScale = theView->Scale();
426   Standard_Real aFOV   = theView->Camera()->FOVy();
427   theView->At (anAt[0], anAt[1], anAt[2]);
428   if (!isOrthographic && !toUpdateProjector)
429   {
430     toUpdateProjector = myPrevAt[0] != anAt[0]
431                      || myPrevAt[1] != anAt[1]
432                      || myPrevAt[2] != anAt[2]
433                      || myPrevScale != aScale
434                      || myPrevFOV   != aFOV;
435   }
436
437   myToUpdateTolerance = aScale != myPrevScale;
438
439   // Update projector if anything changed
440   if (toUpdateProjector)
441   {
442     toupdate = Standard_True;
443
444     myToUpdateTolerance = Standard_True;
445
446     if (isOrthographic)
447     {
448       // For orthographic view use only direction of projection and up vector
449       // Panning, and zooming has no effect on 2D selection sensitives.
450       Handle (Graphic3d_Camera) aCamera = new Graphic3d_Camera();
451
452       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
453       aCamera->SetCenter (gp::Origin());
454       aCamera->SetDirection (gp_Dir (-aProj[0], -aProj[1], -aProj[2]));
455       aCamera->SetUp (gp_Dir (anUp[0], anUp[1], anUp[2]));
456       aCamera->SetDistance (1.0);
457       aCamera->SetAxialScale (gp_XYZ (anAxialScale[0], anAxialScale[1], anAxialScale[2]));
458
459       myProjector = new Select3D_Projector (aCamera->OrientationMatrix(), Graphic3d_Mat4d());
460     }
461     else
462     {
463       // For perspective projection panning, zooming and location of view
464       // has effect. Thus, use current view and projection matrices from
465       // view camera. Exception is that the projection transformation
466       // is scaled from NDC to size of displaying frame of view space in order
467       // to maintain consistence with pixel tolerance conversion.
468       const Graphic3d_Mat4d& aMVMatrix   = theView->Camera()->OrientationMatrix();
469       const Graphic3d_Mat4d& aProjMatrix = theView->Camera()->ProjectionMatrix();
470       gp_XYZ aViewDimensions = theView->Camera()->ViewDimensions();
471
472       Graphic3d_Mat4d aScaledProj;
473       aScaledProj.ChangeValue (0, 0) = aViewDimensions.X();
474       aScaledProj.ChangeValue (1, 1) = aViewDimensions.Y();
475       aScaledProj.ChangeValue (2, 2) = aViewDimensions.Z();
476       Graphic3d_Mat4d aScaledProjMatrix = aScaledProj * aProjMatrix;
477
478       Standard_Real aZNear = theView->Camera()->ZNear();
479       Standard_Real aZFar  = theView->Camera()->ZFar();
480
481       myProjector = new Select3D_Projector (aMVMatrix, aScaledProjMatrix, aZNear, aZFar);
482     }
483   }
484
485   myPrevAt[0] = anAt[0];
486   myPrevAt[1] = anAt[1];
487   myPrevAt[2] = anAt[2];
488   myPrevUp[0] = anUp[0];
489   myPrevUp[1] = anUp[1];
490   myPrevUp[2] = anUp[2];
491   myPrevProj[0] = aProj[0];
492   myPrevProj[1] = aProj[1];
493   myPrevProj[2] = aProj[2];
494   myPrevAxialScale[0] = anAxialScale[0];
495   myPrevAxialScale[1] = anAxialScale[1];
496   myPrevAxialScale[2] = anAxialScale[2];
497   myPrevFOV = aFOV;
498   myPrevScale = aScale;
499   myPrevOrthographic = isOrthographic;
500
501   if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
502   {
503     SetSensitivity (theView->Convert (myPixelTolerance));
504     myToUpdateTolerance = Standard_False;
505   }
506
507   if (toupdate)
508   {
509     UpdateConversion();
510   }
511
512   if (tosort)
513   {
514     UpdateSort();
515   }
516
517   return Standard_True;
518 }
519
520
521 //=======================================================================
522 // Function: DisplaySensitive.
523 // Purpose : Display active primitives.
524 //=======================================================================
525 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView)
526 {
527   if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
528   {
529     SetSensitivity (theView->Convert (myPixelTolerance));
530     myToUpdateTolerance = Standard_False;
531   }
532
533   if (toupdate)
534   {
535     UpdateProj (theView);
536   }
537
538   if (tosort)
539   {
540     UpdateSort(); // Updates the activated areas
541   }
542
543   // Preparation des structures
544   if (mystruct.IsNull())
545   {
546     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
547   }
548
549   if (mysensgroup.IsNull())
550   {
551     mysensgroup = mystruct->NewGroup();
552   }
553
554   Quantity_Color aColor (Quantity_NOC_INDIANRED3);
555   Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
556     new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
557
558   mysensgroup->SetPrimitivesAspect (aMarkerAspect);
559   mysensgroup->SetPrimitivesAspect (
560     new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
561
562   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation anIt (myselections);
563
564   for (; anIt.More(); anIt.Next())
565   {
566     if (anIt.Value()==0)
567     {
568       const Handle(SelectMgr_Selection)& aSel = anIt.Key();
569       ComputeSensitivePrs (aSel);
570     }
571   }
572
573   mysensgroup->Structure()->SetDisplayPriority (10);
574   mystruct->Display();
575
576   theView->Update();
577 }
578
579 //=======================================================================
580 // Function: ClearSensitive
581 // Purpose :
582 //=======================================================================
583 void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView)
584 {
585   if (mysensgroup.IsNull())
586   {
587     return;
588   }
589
590   mysensgroup->Clear();
591
592   if (theView.IsNull())
593   {
594     return;
595   }
596
597   theView->Update();
598 }
599
600 //=======================================================================
601 //function : DisplaySenstive
602 //purpose  :
603 //=======================================================================
604 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
605                                                    const Handle(V3d_View)& theView,
606                                                    const Standard_Boolean theToClearOthers)
607 {
608   if (mystruct.IsNull())
609   {
610     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
611   }
612
613   if (mysensgroup.IsNull())
614   {
615     mysensgroup = mystruct->NewGroup();
616     Quantity_Color aColor (Quantity_NOC_INDIANRED3);
617     Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
618       new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
619
620     mysensgroup-> SetPrimitivesAspect (aMarkerAspect);
621     mysensgroup->SetPrimitivesAspect (
622       new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
623   }
624
625   if (theToClearOthers)
626   {
627     mysensgroup->Clear();
628   }
629
630   ComputeSensitivePrs (theSel);
631
632   mystruct->SetDisplayPriority (10);
633   mystruct->Display();
634
635   theView->Update();
636 }
637
638 //=======================================================================
639 //function : DisplayAreas
640 //purpose  :
641 //=======================================================================
642 void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(SelectMgr_Selection)& theSel,
643                                                const Handle(V3d_View)& theView,
644                                                const Standard_Boolean theToClearOthers)
645 {
646   if (mystruct.IsNull())
647   {
648     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
649   }
650
651   if (mysensgroup.IsNull())
652   {
653     myareagroup = mystruct->NewGroup();
654     myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
655   }
656
657   if (theToClearOthers)
658   {
659     myareagroup->Clear();
660   }
661
662   ComputeAreasPrs (theSel);
663
664   mystruct->SetDisplayPriority (10);
665   mystruct->Display();
666
667   theView->Update();
668 }
669
670 //=======================================================================
671 //function : ComputeSensitivePrs
672 //purpose  :
673 //=======================================================================
674 void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel)
675 {
676   TColgp_SequenceOfPnt aSeqLines, aSeqFree;
677   TColStd_SequenceOfInteger aSeqBnds;
678
679   for (theSel->Init(); theSel->More(); theSel->Next())
680   {
681     Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(theSel->Sensitive());
682     const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation());
683
684     TopLoc_Location theloc;
685     if(hasloc)
686       theloc = Ent->Location();
687
688     //==============
689     // Box
690     //=============
691
692     if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
693     {
694       const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
695       Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
696       B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
697       Standard_Integer i;
698       gp_Pnt theboxpoint[8] =
699       {
700         gp_Pnt(xmin,ymin,zmin),
701         gp_Pnt(xmax,ymin,zmin),
702         gp_Pnt(xmax,ymax,zmin),
703         gp_Pnt(xmin,ymax,zmin),
704         gp_Pnt(xmin,ymin,zmax),
705         gp_Pnt(xmax,ymin,zmax),
706         gp_Pnt(xmax,ymax,zmax),
707         gp_Pnt(xmin,ymax,zmax)
708       };
709       if(hasloc)
710       {
711         for (i = 0; i <= 7; i++)
712           theboxpoint[i].Transform (theloc.Transformation());
713       }
714
715       aSeqBnds.Append(5);
716       for (i = 0; i < 4; i++)
717         aSeqLines.Append(theboxpoint[i]);
718       aSeqLines.Append(theboxpoint[0]);
719
720       aSeqBnds.Append(5);
721       for (i = 4; i < 8; i++)
722         aSeqLines.Append(theboxpoint[i]);
723       aSeqLines.Append(theboxpoint[4]);
724
725       for (i = 0; i < 4; i++)
726       {
727         aSeqBnds.Append(2);
728         aSeqLines.Append(theboxpoint[i]);
729         aSeqLines.Append(theboxpoint[i+4]);
730       }
731     }
732     //==============
733     // Face
734     //=============
735     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
736     {
737       Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
738       Handle(TColgp_HArray1OfPnt) TheHPts;
739       aFace->Points3D(TheHPts);
740       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
741
742       aSeqBnds.Append(ThePts.Length());
743       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
744       {
745         if (hasloc)
746           aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
747         else
748           aSeqLines.Append(ThePts(I));
749       }
750     }
751     //==============
752     // Curve
753     //=============
754     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
755     {
756       Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
757       Handle(TColgp_HArray1OfPnt) TheHPts;
758       aCurve->Points3D(TheHPts);
759       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
760
761       aSeqBnds.Append(ThePts.Length());
762       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
763       {
764         if (hasloc)
765           aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
766         else
767           aSeqLines.Append(ThePts(I));
768       }
769     }
770     //==============
771     // Wire
772     //=============
773     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
774     {
775       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
776       Select3D_SensitiveEntitySequence EntitySeq;
777       aWire->GetEdges (EntitySeq);
778
779       for (int i = 1; i <= EntitySeq.Length(); i++)
780       {
781         Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
782
783         //Segment
784         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
785         {
786           gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
787           gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
788           if (hasloc)
789           {
790             P1.Transform(theloc.Transformation());
791             P2.Transform(theloc.Transformation());
792           }
793           aSeqBnds.Append(2);
794           aSeqLines.Append(P1);
795           aSeqLines.Append(P2);
796         }
797
798         //circle
799         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
800         {
801           Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
802           Standard_Integer aFrom, aTo;
803           aCircle->ArrayBounds (aFrom, aTo);
804           aTo -= 2;
805           for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
806           {
807             gp_Pnt aPnts[3] =
808             {
809               gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
810               gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
811               gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
812             };
813
814             if (hasloc)
815             {
816               aPnts[0].Transform (theloc.Transformation());
817               aPnts[1].Transform (theloc.Transformation());
818               aPnts[2].Transform (theloc.Transformation());
819             }
820
821             aSeqBnds.Append (4);
822             aSeqLines.Append (aPnts[0]);
823             aSeqLines.Append (aPnts[1]);
824             aSeqLines.Append (aPnts[2]);
825             aSeqLines.Append (aPnts[0]);
826           }
827         }
828
829         //curve
830         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
831         {
832           Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
833           Handle(TColgp_HArray1OfPnt) TheHPts;
834           aCurve->Points3D (TheHPts);
835           const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
836
837           aSeqBnds.Append(ThePts.Length());
838           for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
839           {
840             if (hasloc)
841               aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
842             else
843               aSeqLines.Append(ThePts(I));
844           }
845         }
846       }
847     }
848     //==============
849     // Segment
850     //=============
851     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
852     {
853       gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
854       gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
855       if (hasloc)
856       {
857         P1.Transform (theloc.Transformation());
858         P2.Transform (theloc.Transformation());
859       }
860       aSeqBnds.Append(2);
861       aSeqLines.Append(P1);
862       aSeqLines.Append(P2);
863     }
864     //==============
865     // Circle
866     //=============
867     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
868     {
869       Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
870       Standard_Integer aFrom, aTo;
871       aCircle->ArrayBounds (aFrom, aTo);
872       aTo -= 2;
873       for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
874       {
875         gp_Pnt aPnts[3] =
876         {
877           gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
878           gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
879           gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
880         };
881
882         if (hasloc)
883         {
884           aPnts[0].Transform (theloc.Transformation());
885           aPnts[1].Transform (theloc.Transformation());
886           aPnts[2].Transform (theloc.Transformation());
887         }
888
889         aSeqBnds.Append (4);
890         aSeqLines.Append (aPnts[0]);
891         aSeqLines.Append (aPnts[1]);
892         aSeqLines.Append (aPnts[2]);
893         aSeqLines.Append (aPnts[0]);
894       }
895     }
896     //==============
897     // Point
898     //=============
899     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
900     {
901       gp_Pnt P = hasloc ?
902         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
903         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
904       Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
905       anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
906       mysensgroup->AddPrimitiveArray (anArrayOfPoints);
907     }
908     //============================================================
909     // Triangulation : On met un petit offset ves l'interieur...
910     //==========================================================
911     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
912     {
913       const Handle(Poly_Triangulation)& PT =
914         (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
915
916       const Poly_Array1OfTriangle& triangles = PT->Triangles();
917       const TColgp_Array1OfPnt& Nodes = PT->Nodes();
918       Standard_Integer n[3];
919
920       TopLoc_Location iloc, bidloc;
921       if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
922         bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
923
924       if (bidloc.IsIdentity())
925         iloc = theloc;
926       else
927         iloc = theloc * bidloc;
928
929       Standard_Integer i;
930       for (i = 1; i <= PT->NbTriangles(); i++)
931       {
932         triangles (i).Get (n[0], n[1], n[2]);
933         gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
934         gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
935         gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
936         gp_XYZ V1 (P1.XYZ());
937         gp_XYZ V2 (P2.XYZ());
938         gp_XYZ V3 (P3.XYZ());
939         gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
940         V1 -= CDG; V2 -= CDG; V3 -= CDG;
941         V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
942         V1 += CDG; V2 += CDG; V3 += CDG;
943
944         aSeqBnds.Append(4);
945         aSeqLines.Append(gp_Pnt(V1));
946         aSeqLines.Append(gp_Pnt(V2));
947         aSeqLines.Append(gp_Pnt(V3));
948         aSeqLines.Append(gp_Pnt(V1));
949       }
950
951       // recherche des bords libres...
952
953       Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
954       TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
955       Poly_Connect pc (PT);
956       Standard_Integer t[3];
957       Standard_Integer j;
958       Standard_Integer fr (1);
959       for (i = 1; i <= PT->NbTriangles(); i++)
960       {
961         pc.Triangles (i, t[0], t[1], t[2]);
962         triangles (i).Get (n[0], n[1], n[2]);
963         for (j = 0; j < 3; j++)
964         {
965           Standard_Integer k = (j + 1) % 3;
966           if (t[j] == 0)
967           {
968             FreeE (fr)    = n[j];
969             FreeE (fr + 1)= n[k];
970             fr += 2;
971           }
972         }
973       }
974       for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
975       {
976         gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
977         aSeqFree.Append(pe1);
978         aSeqFree.Append(pe2);
979       }
980     }
981     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
982     {
983       Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
984       gp_Pnt P1, P2, P3;
985       Str->Points3D (P1, P2, P3);
986       gp_Pnt CDG = Str->Center3D();
987
988       gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
989       gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
990       gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
991       V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
992       V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
993
994       aSeqBnds.Append(4);
995       aSeqLines.Append(gp_Pnt(V1));
996       aSeqLines.Append(gp_Pnt(V2));
997       aSeqLines.Append(gp_Pnt(V3));
998       aSeqLines.Append(gp_Pnt(V1));
999     }
1000   }
1001
1002   Standard_Integer i;
1003
1004   if (aSeqLines.Length())
1005   {
1006     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
1007     for (i = 1; i <= aSeqLines.Length(); i++)
1008       aPrims->AddVertex(aSeqLines(i));
1009     for (i = 1; i <= aSeqBnds.Length(); i++)
1010       aPrims->AddBound(aSeqBnds(i));
1011     myareagroup->AddPrimitiveArray(aPrims);
1012   }
1013
1014   if (aSeqFree.Length())
1015   {
1016     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
1017     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
1018     for (i = 1; i <= aSeqFree.Length(); i++)
1019     {
1020       aPrims->AddBound(2);
1021       aPrims->AddVertex(aSeqLines(i++));
1022       aPrims->AddVertex(aSeqLines(i));
1023     }
1024     mysensgroup->AddPrimitiveArray(aPrims);
1025     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
1026   }
1027 }
1028
1029 //=======================================================================
1030 //function : ComputeAreaPrs
1031 //purpose  :
1032 //=======================================================================
1033 void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& theSel)
1034 {
1035   Standard_Real aXmin = 0.0;
1036   Standard_Real aYmin = 0.0;
1037   Standard_Real aXmax = 0.0;
1038   Standard_Real aYmax = 0.0;
1039
1040   gp_Pnt aPbid;
1041   SelectBasics_ListOfBox2d aBoxList;
1042
1043   TColgp_SequenceOfPnt aSeqLines;
1044   for (theSel->Init(); theSel->More(); theSel->Next())
1045   {
1046     theSel->Sensitive()->Areas (aBoxList);
1047     for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next())
1048     {
1049       aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax);
1050
1051       aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0);
1052       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1053       aSeqLines.Append (aPbid);
1054
1055       aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0);
1056       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1057       aSeqLines.Append (aPbid);
1058
1059       aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0);
1060       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1061       aSeqLines.Append (aPbid);
1062
1063       aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0);
1064       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1065       aSeqLines.Append (aPbid);
1066     }
1067   }
1068
1069   if (aSeqLines.Length())
1070   {
1071     Standard_Integer aN = 0;
1072     Standard_Integer aNP = 0;
1073     const Standard_Integer aNBL = aSeqLines.Length() / 4;
1074     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNBL, aNBL);
1075     for (aNP = 1, aN = 0; aN < aNBL; aN++)
1076     {
1077       aPrims->AddBound (5);
1078       const gp_Pnt &aP1 = aSeqLines (aNP++);
1079       aPrims->AddVertex (aP1);
1080       aPrims->AddVertex (aSeqLines (aNP++));
1081       aPrims->AddVertex (aSeqLines (aNP++));
1082       aPrims->AddVertex (aSeqLines (aNP++));
1083       aPrims->AddVertex (aP1);
1084     }
1085     myareagroup->AddPrimitiveArray (aPrims);
1086   }
1087 }
1088
1089 //=======================================================================
1090 //function : SetClipping
1091 //purpose  :
1092 //=======================================================================
1093 void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
1094 {
1095   myClipPlanes = thePlanes;
1096 }
1097
1098 //=======================================================================
1099 //function : ComputeClipRange
1100 //purpose  :
1101 //=======================================================================
1102 void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
1103                                                    const gp_Lin& thePickLine,
1104                                                    Standard_Real& theDepthMin,
1105                                                    Standard_Real& theDepthMax) const
1106 {
1107   theDepthMin = RealFirst();
1108   theDepthMax = RealLast();
1109   Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
1110
1111   Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
1112   for (; aPlaneIt.More(); aPlaneIt.Next())
1113   {
1114     const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
1115     if (!aClipPlane->IsOn())
1116       continue;
1117
1118     gp_Pln aGeomPlane = aClipPlane->ToPlane();
1119
1120     aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
1121
1122     const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
1123     const gp_Dir& aPickDir  = thePickLine.Direction();
1124     const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
1125     const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
1126
1127     Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
1128     Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
1129
1130     // check whether the pick line is parallel to clip plane
1131     if (Abs (aDotProduct) < Precision::Angular())
1132     {
1133       if (aDistance > 0.0)
1134       {
1135         // line lies above the plane, thus no selection is possible
1136         theDepthMin = 0.0;
1137         theDepthMax = 0.0;
1138         return;
1139       }
1140
1141       // line lies below the plane and is not clipped, skip
1142       continue;
1143     }
1144
1145     // compute distance to point of pick line intersection with the plane
1146     Standard_Real aIntDist = aDistance / aDotProduct;
1147
1148     // change depth limits for case of opposite and directed planes
1149     if (aDotProduct < 0.0)
1150     {
1151       theDepthMax = Min (aIntDist, theDepthMax);
1152     }
1153     else if (aIntDist > theDepthMin)
1154     {
1155       theDepthMin = Max (aIntDist, theDepthMin);
1156     }
1157   }
1158 }
1159
1160 //=======================================================================
1161 //function : PickingLine
1162 //purpose  :
1163 //=======================================================================
1164 gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
1165 {
1166   return myProjector->Shoot (theX, theY);
1167 }
1168
1169 //=======================================================================
1170 //function : DepthClipping
1171 //purpose  :
1172 //=======================================================================
1173 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1174                                                 const Standard_Real theY,
1175                                                 Standard_Real& theDepthMin,
1176                                                 Standard_Real& theDepthMax) const
1177 {
1178   return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
1179 }
1180
1181 //=======================================================================
1182 //function : DepthClipping
1183 //purpose  :
1184 //=======================================================================
1185 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1186                                                 const Standard_Real theY,
1187                                                 const Handle(SelectMgr_EntityOwner)& theOwner,
1188                                                 Standard_Real& theDepthMin,
1189                                                 Standard_Real& theDepthMax) const
1190 {
1191   return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
1192                            PickingLine (theX, theY),
1193                            theDepthMin, theDepthMax);
1194 }
1195
1196 //=======================================================================
1197 //function : HasDepthClipping
1198 //purpose  :
1199 //=======================================================================
1200 Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
1201 {
1202   if (!theOwner->HasSelectable())
1203   {
1204     return Standard_False;
1205   }
1206
1207   const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
1208   return (aSelectable->GetClipPlanes().Size() > 0);
1209 }