27a053c7f9ba3ce657469514e25d0dedd2d0dc8c
[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       myProjector = new Select3D_Projector (aMVMatrix, aScaledProjMatrix);
479     }
480   }
481
482   myPrevAt[0] = anAt[0];
483   myPrevAt[1] = anAt[1];
484   myPrevAt[2] = anAt[2];
485   myPrevUp[0] = anUp[0];
486   myPrevUp[1] = anUp[1];
487   myPrevUp[2] = anUp[2];
488   myPrevProj[0] = aProj[0];
489   myPrevProj[1] = aProj[1];
490   myPrevProj[2] = aProj[2];
491   myPrevAxialScale[0] = anAxialScale[0];
492   myPrevAxialScale[1] = anAxialScale[1];
493   myPrevAxialScale[2] = anAxialScale[2];
494   myPrevFOV = aFOV;
495   myPrevScale = aScale;
496   myPrevOrthographic = isOrthographic;
497
498   if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
499   {
500     SetSensitivity (theView->Convert (myPixelTolerance));
501     myToUpdateTolerance = Standard_False;
502   }
503
504   if (toupdate)
505   {
506     UpdateConversion();
507   }
508
509   if (tosort)
510   {
511     UpdateSort();
512   }
513
514   return Standard_True;
515 }
516
517
518 //=======================================================================
519 // Function: DisplaySensitive.
520 // Purpose : Display active primitives.
521 //=======================================================================
522 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView)
523 {
524   if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW)
525   {
526     SetSensitivity (theView->Convert (myPixelTolerance));
527     myToUpdateTolerance = Standard_False;
528   }
529
530   if (toupdate)
531   {
532     UpdateProj (theView);
533   }
534
535   if (tosort)
536   {
537     UpdateSort(); // Updates the activated areas
538   }
539
540   // Preparation des structures
541   if (mystruct.IsNull())
542   {
543     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
544   }
545
546   if (mysensgroup.IsNull())
547   {
548     mysensgroup = mystruct->NewGroup();
549   }
550
551   Quantity_Color aColor (Quantity_NOC_INDIANRED3);
552   Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
553     new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
554
555   mysensgroup->SetPrimitivesAspect (aMarkerAspect);
556   mysensgroup->SetPrimitivesAspect (
557     new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
558
559   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation anIt (myselections);
560
561   for (; anIt.More(); anIt.Next())
562   {
563     if (anIt.Value()==0)
564     {
565       const Handle(SelectMgr_Selection)& aSel = anIt.Key();
566       ComputeSensitivePrs (aSel);
567     }
568   }
569
570   mysensgroup->Structure()->SetDisplayPriority (10);
571   mystruct->Display();
572
573   theView->Update();
574 }
575
576 //=======================================================================
577 // Function: ClearSensitive
578 // Purpose :
579 //=======================================================================
580 void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView)
581 {
582   if (mysensgroup.IsNull())
583   {
584     return;
585   }
586
587   mysensgroup->Clear();
588
589   if (theView.IsNull())
590   {
591     return;
592   }
593
594   theView->Update();
595 }
596
597 //=======================================================================
598 //function : DisplaySenstive
599 //purpose  :
600 //=======================================================================
601 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
602                                                    const Handle(V3d_View)& theView,
603                                                    const Standard_Boolean theToClearOthers)
604 {
605   if (mystruct.IsNull())
606   {
607     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
608   }
609
610   if (mysensgroup.IsNull())
611   {
612     mysensgroup = mystruct->NewGroup();
613     Quantity_Color aColor (Quantity_NOC_INDIANRED3);
614     Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
615       new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
616
617     mysensgroup-> SetPrimitivesAspect (aMarkerAspect);
618     mysensgroup->SetPrimitivesAspect (
619       new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
620   }
621
622   if (theToClearOthers)
623   {
624     mysensgroup->Clear();
625   }
626
627   ComputeSensitivePrs (theSel);
628
629   mystruct->SetDisplayPriority (10);
630   mystruct->Display();
631
632   theView->Update();
633 }
634
635 //=======================================================================
636 //function : DisplayAreas
637 //purpose  :
638 //=======================================================================
639 void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(SelectMgr_Selection)& theSel,
640                                                const Handle(V3d_View)& theView,
641                                                const Standard_Boolean theToClearOthers)
642 {
643   if (mystruct.IsNull())
644   {
645     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
646   }
647
648   if (mysensgroup.IsNull())
649   {
650     myareagroup = mystruct->NewGroup();
651     myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
652   }
653
654   if (theToClearOthers)
655   {
656     myareagroup->Clear();
657   }
658
659   ComputeAreasPrs (theSel);
660
661   mystruct->SetDisplayPriority (10);
662   mystruct->Display();
663
664   theView->Update();
665 }
666
667 //=======================================================================
668 //function : ComputeSensitivePrs
669 //purpose  :
670 //=======================================================================
671 void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel)
672 {
673   TColgp_SequenceOfPnt aSeqLines, aSeqFree;
674   TColStd_SequenceOfInteger aSeqBnds;
675
676   for (theSel->Init(); theSel->More(); theSel->Next())
677   {
678     Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(theSel->Sensitive());
679     const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation());
680
681     TopLoc_Location theloc;
682     if(hasloc)
683       theloc = Ent->Location();
684
685     //==============
686     // Box
687     //=============
688
689     if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
690     {
691       const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
692       Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
693       B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
694       Standard_Integer i;
695       gp_Pnt theboxpoint[8] =
696       {
697         gp_Pnt(xmin,ymin,zmin),
698         gp_Pnt(xmax,ymin,zmin),
699         gp_Pnt(xmax,ymax,zmin),
700         gp_Pnt(xmin,ymax,zmin),
701         gp_Pnt(xmin,ymin,zmax),
702         gp_Pnt(xmax,ymin,zmax),
703         gp_Pnt(xmax,ymax,zmax),
704         gp_Pnt(xmin,ymax,zmax)
705       };
706       if(hasloc)
707       {
708         for (i = 0; i <= 7; i++)
709           theboxpoint[i].Transform (theloc.Transformation());
710       }
711
712       aSeqBnds.Append(5);
713       for (i = 0; i < 4; i++)
714         aSeqLines.Append(theboxpoint[i]);
715       aSeqLines.Append(theboxpoint[0]);
716
717       aSeqBnds.Append(5);
718       for (i = 4; i < 8; i++)
719         aSeqLines.Append(theboxpoint[i]);
720       aSeqLines.Append(theboxpoint[4]);
721
722       for (i = 0; i < 4; i++)
723       {
724         aSeqBnds.Append(2);
725         aSeqLines.Append(theboxpoint[i]);
726         aSeqLines.Append(theboxpoint[i+4]);
727       }
728     }
729     //==============
730     // Face
731     //=============
732     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
733     {
734       Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
735       Handle(TColgp_HArray1OfPnt) TheHPts;
736       aFace->Points3D(TheHPts);
737       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
738
739       aSeqBnds.Append(ThePts.Length());
740       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
741       {
742         if (hasloc)
743           aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
744         else
745           aSeqLines.Append(ThePts(I));
746       }
747     }
748     //==============
749     // Curve
750     //=============
751     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
752     {
753       Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
754       Handle(TColgp_HArray1OfPnt) TheHPts;
755       aCurve->Points3D(TheHPts);
756       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
757
758       aSeqBnds.Append(ThePts.Length());
759       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
760       {
761         if (hasloc)
762           aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
763         else
764           aSeqLines.Append(ThePts(I));
765       }
766     }
767     //==============
768     // Wire
769     //=============
770     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
771     {
772       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
773       Select3D_SensitiveEntitySequence EntitySeq;
774       aWire->GetEdges (EntitySeq);
775
776       for (int i = 1; i <= EntitySeq.Length(); i++)
777       {
778         Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
779
780         //Segment
781         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
782         {
783           gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
784           gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
785           if (hasloc)
786           {
787             P1.Transform(theloc.Transformation());
788             P2.Transform(theloc.Transformation());
789           }
790           aSeqBnds.Append(2);
791           aSeqLines.Append(P1);
792           aSeqLines.Append(P2);
793         }
794
795         //circle
796         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
797         {
798           Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
799           Standard_Integer aFrom, aTo;
800           aCircle->ArrayBounds (aFrom, aTo);
801           aTo -= 2;
802           for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
803           {
804             gp_Pnt aPnts[3] =
805             {
806               gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
807               gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
808               gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
809             };
810
811             if (hasloc)
812             {
813               aPnts[0].Transform (theloc.Transformation());
814               aPnts[1].Transform (theloc.Transformation());
815               aPnts[2].Transform (theloc.Transformation());
816             }
817
818             aSeqBnds.Append (4);
819             aSeqLines.Append (aPnts[0]);
820             aSeqLines.Append (aPnts[1]);
821             aSeqLines.Append (aPnts[2]);
822             aSeqLines.Append (aPnts[0]);
823           }
824         }
825
826         //curve
827         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
828         {
829           Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
830           Handle(TColgp_HArray1OfPnt) TheHPts;
831           aCurve->Points3D (TheHPts);
832           const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
833
834           aSeqBnds.Append(ThePts.Length());
835           for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
836           {
837             if (hasloc)
838               aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
839             else
840               aSeqLines.Append(ThePts(I));
841           }
842         }
843       }
844     }
845     //==============
846     // Segment
847     //=============
848     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
849     {
850       gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
851       gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
852       if (hasloc)
853       {
854         P1.Transform (theloc.Transformation());
855         P2.Transform (theloc.Transformation());
856       }
857       aSeqBnds.Append(2);
858       aSeqLines.Append(P1);
859       aSeqLines.Append(P2);
860     }
861     //==============
862     // Circle
863     //=============
864     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
865     {
866       Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
867       Standard_Integer aFrom, aTo;
868       aCircle->ArrayBounds (aFrom, aTo);
869       aTo -= 2;
870       for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
871       {
872         gp_Pnt aPnts[3] =
873         {
874           gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
875           gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
876           gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
877         };
878
879         if (hasloc)
880         {
881           aPnts[0].Transform (theloc.Transformation());
882           aPnts[1].Transform (theloc.Transformation());
883           aPnts[2].Transform (theloc.Transformation());
884         }
885
886         aSeqBnds.Append (4);
887         aSeqLines.Append (aPnts[0]);
888         aSeqLines.Append (aPnts[1]);
889         aSeqLines.Append (aPnts[2]);
890         aSeqLines.Append (aPnts[0]);
891       }
892     }
893     //==============
894     // Point
895     //=============
896     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
897     {
898       gp_Pnt P = hasloc ?
899         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
900         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
901       Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
902       anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
903       mysensgroup->AddPrimitiveArray (anArrayOfPoints);
904     }
905     //============================================================
906     // Triangulation : On met un petit offset ves l'interieur...
907     //==========================================================
908     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
909     {
910       const Handle(Poly_Triangulation)& PT =
911         (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
912
913       const Poly_Array1OfTriangle& triangles = PT->Triangles();
914       const TColgp_Array1OfPnt& Nodes = PT->Nodes();
915       Standard_Integer n[3];
916
917       TopLoc_Location iloc, bidloc;
918       if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
919         bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
920
921       if (bidloc.IsIdentity())
922         iloc = theloc;
923       else
924         iloc = theloc * bidloc;
925
926       Standard_Integer i;
927       for (i = 1; i <= PT->NbTriangles(); i++)
928       {
929         triangles (i).Get (n[0], n[1], n[2]);
930         gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
931         gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
932         gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
933         gp_XYZ V1 (P1.XYZ());
934         gp_XYZ V2 (P2.XYZ());
935         gp_XYZ V3 (P3.XYZ());
936         gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
937         V1 -= CDG; V2 -= CDG; V3 -= CDG;
938         V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
939         V1 += CDG; V2 += CDG; V3 += CDG;
940
941         aSeqBnds.Append(4);
942         aSeqLines.Append(gp_Pnt(V1));
943         aSeqLines.Append(gp_Pnt(V2));
944         aSeqLines.Append(gp_Pnt(V3));
945         aSeqLines.Append(gp_Pnt(V1));
946       }
947
948       // recherche des bords libres...
949
950       Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
951       TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
952       Poly_Connect pc (PT);
953       Standard_Integer t[3];
954       Standard_Integer j;
955       Standard_Integer fr (1);
956       for (i = 1; i <= PT->NbTriangles(); i++)
957       {
958         pc.Triangles (i, t[0], t[1], t[2]);
959         triangles (i).Get (n[0], n[1], n[2]);
960         for (j = 0; j < 3; j++)
961         {
962           Standard_Integer k = (j + 1) % 3;
963           if (t[j] == 0)
964           {
965             FreeE (fr)    = n[j];
966             FreeE (fr + 1)= n[k];
967             fr += 2;
968           }
969         }
970       }
971       for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
972       {
973         gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
974         aSeqFree.Append(pe1);
975         aSeqFree.Append(pe2);
976       }
977     }
978     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
979     {
980       Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
981       gp_Pnt P1, P2, P3;
982       Str->Points3D (P1, P2, P3);
983       gp_Pnt CDG = Str->Center3D();
984
985       gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
986       gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
987       gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
988       V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
989       V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
990
991       aSeqBnds.Append(4);
992       aSeqLines.Append(gp_Pnt(V1));
993       aSeqLines.Append(gp_Pnt(V2));
994       aSeqLines.Append(gp_Pnt(V3));
995       aSeqLines.Append(gp_Pnt(V1));
996     }
997   }
998
999   Standard_Integer i;
1000
1001   if (aSeqLines.Length())
1002   {
1003     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
1004     for (i = 1; i <= aSeqLines.Length(); i++)
1005       aPrims->AddVertex(aSeqLines(i));
1006     for (i = 1; i <= aSeqBnds.Length(); i++)
1007       aPrims->AddBound(aSeqBnds(i));
1008     myareagroup->AddPrimitiveArray(aPrims);
1009   }
1010
1011   if (aSeqFree.Length())
1012   {
1013     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
1014     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
1015     for (i = 1; i <= aSeqFree.Length(); i++)
1016     {
1017       aPrims->AddBound(2);
1018       aPrims->AddVertex(aSeqLines(i++));
1019       aPrims->AddVertex(aSeqLines(i));
1020     }
1021     mysensgroup->AddPrimitiveArray(aPrims);
1022     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
1023   }
1024 }
1025
1026 //=======================================================================
1027 //function : ComputeAreaPrs
1028 //purpose  :
1029 //=======================================================================
1030 void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& theSel)
1031 {
1032   Standard_Real aXmin = 0.0;
1033   Standard_Real aYmin = 0.0;
1034   Standard_Real aXmax = 0.0;
1035   Standard_Real aYmax = 0.0;
1036
1037   gp_Pnt aPbid;
1038   SelectBasics_ListOfBox2d aBoxList;
1039
1040   TColgp_SequenceOfPnt aSeqLines;
1041   for (theSel->Init(); theSel->More(); theSel->Next())
1042   {
1043     theSel->Sensitive()->Areas (aBoxList);
1044     for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next())
1045     {
1046       aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax);
1047
1048       aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0);
1049       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1050       aSeqLines.Append (aPbid);
1051
1052       aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0);
1053       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1054       aSeqLines.Append (aPbid);
1055
1056       aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0);
1057       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1058       aSeqLines.Append (aPbid);
1059
1060       aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0);
1061       myProjector->Transform (aPbid, myProjector->InvertedTransformation());
1062       aSeqLines.Append (aPbid);
1063     }
1064   }
1065
1066   if (aSeqLines.Length())
1067   {
1068     Standard_Integer aN = 0;
1069     Standard_Integer aNP = 0;
1070     const Standard_Integer aNBL = aSeqLines.Length() / 4;
1071     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNBL, aNBL);
1072     for (aNP = 1, aN = 0; aN < aNBL; aN++)
1073     {
1074       aPrims->AddBound (5);
1075       const gp_Pnt &aP1 = aSeqLines (aNP++);
1076       aPrims->AddVertex (aP1);
1077       aPrims->AddVertex (aSeqLines (aNP++));
1078       aPrims->AddVertex (aSeqLines (aNP++));
1079       aPrims->AddVertex (aSeqLines (aNP++));
1080       aPrims->AddVertex (aP1);
1081     }
1082     myareagroup->AddPrimitiveArray (aPrims);
1083   }
1084 }
1085
1086 //=======================================================================
1087 //function : SetClipping
1088 //purpose  :
1089 //=======================================================================
1090 void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
1091 {
1092   myClipPlanes = thePlanes;
1093 }
1094
1095 //=======================================================================
1096 //function : ComputeClipRange
1097 //purpose  :
1098 //=======================================================================
1099 void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
1100                                                    const gp_Lin& thePickLine,
1101                                                    Standard_Real& theDepthMin,
1102                                                    Standard_Real& theDepthMax) const
1103 {
1104   theDepthMin = RealFirst();
1105   theDepthMax = RealLast();
1106   Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
1107
1108   Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
1109   for (; aPlaneIt.More(); aPlaneIt.Next())
1110   {
1111     const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
1112     if (!aClipPlane->IsOn())
1113       continue;
1114
1115     gp_Pln aGeomPlane = aClipPlane->ToPlane();
1116
1117     aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
1118
1119     const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
1120     const gp_Dir& aPickDir  = thePickLine.Direction();
1121     const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
1122     const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
1123
1124     Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
1125     Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
1126
1127     // check whether the pick line is parallel to clip plane
1128     if (Abs (aDotProduct) < Precision::Angular())
1129     {
1130       if (aDistance > 0.0)
1131       {
1132         // line lies above the plane, thus no selection is possible
1133         theDepthMin = 0.0;
1134         theDepthMax = 0.0;
1135         return;
1136       }
1137
1138       // line lies below the plane and is not clipped, skip
1139       continue;
1140     }
1141
1142     // compute distance to point of pick line intersection with the plane
1143     Standard_Real aIntDist = aDistance / aDotProduct;
1144
1145     // change depth limits for case of opposite and directed planes
1146     if (aDotProduct < 0.0)
1147     {
1148       theDepthMax = Min (aIntDist, theDepthMax);
1149     }
1150     else if (aIntDist > theDepthMin)
1151     {
1152       theDepthMin = Max (aIntDist, theDepthMin);
1153     }
1154   }
1155 }
1156
1157 //=======================================================================
1158 //function : PickingLine
1159 //purpose  :
1160 //=======================================================================
1161 gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
1162 {
1163   return myProjector->Shoot (theX, theY);
1164 }
1165
1166 //=======================================================================
1167 //function : DepthClipping
1168 //purpose  :
1169 //=======================================================================
1170 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1171                                                 const Standard_Real theY,
1172                                                 Standard_Real& theDepthMin,
1173                                                 Standard_Real& theDepthMax) const
1174 {
1175   return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
1176 }
1177
1178 //=======================================================================
1179 //function : DepthClipping
1180 //purpose  :
1181 //=======================================================================
1182 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1183                                                 const Standard_Real theY,
1184                                                 const Handle(SelectMgr_EntityOwner)& theOwner,
1185                                                 Standard_Real& theDepthMin,
1186                                                 Standard_Real& theDepthMax) const
1187 {
1188   return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
1189                            PickingLine (theX, theY),
1190                            theDepthMin, theDepthMax);
1191 }
1192
1193 //=======================================================================
1194 //function : HasDepthClipping
1195 //purpose  :
1196 //=======================================================================
1197 Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
1198 {
1199   if (!theOwner->HasSelectable())
1200   {
1201     return Standard_False;
1202   }
1203
1204   const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
1205   return (aSelectable->GetClipPlanes().Size() > 0);
1206 }