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