0024070: OpenGL capped object-level clipping planes
[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-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <StdSelect_ViewerSelector3d.ixx>
23 #include <StdSelect.hxx>
24 #include <SelectBasics_SensitiveEntity.hxx>
25 #include <Graphic3d_AspectLine3d.hxx>
26 #include <gp_Pnt.hxx>
27 #include <gp_Lin.hxx>
28 #include <gp_Pnt2d.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Ax3.hxx>
31 #include <gp_GTrsf.hxx>
32 #include <gp_Pln.hxx>
33 #include <V3d_PerspectiveView.hxx>
34 #include <Select3D_SensitiveEntity.hxx>
35 #include <Graphic3d_ArrayOfPolylines.hxx>
36 #include <Graphic3d_SetOfHClipPlane.hxx>
37 #include <SelectMgr_SelectableObject.hxx>
38 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
39 #include <SelectBasics_ListOfBox2d.hxx>
40 #include <Visual3d_TransientManager.hxx>
41 #include <TColgp_HArray1OfPnt.hxx>
42 #include <TColgp_Array1OfPnt.hxx>
43 #include <TColgp_HArray1OfPnt2d.hxx>
44 #include <Select3D_SensitiveCurve.hxx>
45 #include <Select3D_SensitiveSegment.hxx>
46 #include <Select3D_SensitiveFace.hxx>
47 #include <Select3D_SensitiveCircle.hxx>
48 #include <Select3D_SensitivePoint.hxx>
49 #include <Select3D_SensitiveTriangulation.hxx>
50 #include <Select3D_SensitiveTriangle.hxx>
51 #include <Select3D_SensitiveWire.hxx>
52 #include <Select3D_SensitiveEntitySequence.hxx>
53 #include <Select3D_ListOfSensitiveTriangle.hxx>
54 #include <Select3D_SensitiveBox.hxx>
55 #include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
56
57 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
58 #include <Aspect_TypeOfMarker.hxx>
59 #include <Graphic3d_AspectMarker3d.hxx>
60 #include <Graphic3d_ArrayOfPoints.hxx>
61 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
62 #include <Poly_Connect.hxx>
63 #include <TColStd_HArray1OfInteger.hxx>
64
65 #include <Poly_Array1OfTriangle.hxx>
66 #include <Poly_Triangulation.hxx>
67 #include <OSD_Environment.hxx>
68 #include <V3d.hxx>
69 #include <V3d_View.hxx>
70 #include <TColgp_SequenceOfPnt.hxx>
71
72
73 static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
74 {
75   Standard_Integer nFree = 0;
76   Poly_Connect pc(Trg);
77   Standard_Integer t[3];
78   Standard_Integer i, j;
79   for (i = 1; i <= Trg->NbTriangles(); i++)
80   {
81     pc.Triangles (i, t[0], t[1], t[2]);
82     for (j = 0; j < 3; j++)
83       if (t[j] == 0) nFree++;
84   }
85   return nFree;
86 }
87
88 static Standard_Boolean ReadIsDebugMode()
89 {
90   OSD_Environment StdSelectdb ("SELDEBUGMODE");
91   return !StdSelectdb.Value().IsEmpty();
92 }
93
94 static Standard_Boolean StdSelectDebugModeOn()
95 {
96   static const Standard_Boolean isDebugMode = ReadIsDebugMode();
97   return isDebugMode;
98 }
99
100 //==================================================
101 // Function:
102 // Purpose :
103 //==================================================
104
105 StdSelect_ViewerSelector3d
106 ::StdSelect_ViewerSelector3d():
107 myprj(new Select3D_Projector()),
108 mylastzoom(0.0),
109 mysensmode(StdSelect_SM_WINDOW),
110 mypixtol(2),
111 myupdatetol(Standard_True)
112 {
113   for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
114   for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
115 }
116
117
118 //==================================================
119 // Function:
120 // Purpose :
121 //==================================================
122
123 StdSelect_ViewerSelector3d
124 ::StdSelect_ViewerSelector3d(const Handle(Select3D_Projector)& aProj):
125 myprj(aProj),
126 mylastzoom(0.0),
127 mysensmode(StdSelect_SM_WINDOW),
128 mypixtol(2),
129 myupdatetol(Standard_True)
130 {
131   for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
132   for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
133 }
134
135 //==================================================
136 // Function: Convert
137 // Purpose :
138 //==================================================
139
140 void StdSelect_ViewerSelector3d::Convert(const Handle(SelectMgr_Selection)& aSel)
141 {
142   for(aSel->Init();aSel->More();aSel->Next())
143   {
144     if(aSel->Sensitive()->NeedsConversion())
145     {
146       Handle(Select3D_SensitiveEntity) SE = *((Handle(Select3D_SensitiveEntity)*) &(aSel->Sensitive()));
147       SE->Project(myprj);
148       if(!tosort) tosort=Standard_True;
149     }
150   }
151 }
152
153 //==================================================
154 // Function: Set
155 // Purpose :
156 //==================================================
157
158 void StdSelect_ViewerSelector3d
159 ::Set(const Handle(Select3D_Projector)& aProj)
160 {
161   myprj = aProj;
162   toupdate=Standard_True;
163 }
164
165 //==================================================
166 // Function: SetSensitivityMode
167 // Purpose :
168 //==================================================
169
170 void StdSelect_ViewerSelector3d
171 ::SetSensitivityMode(const StdSelect_SensitivityMode aMode)
172 {
173   mysensmode = aMode;
174   toupdate = Standard_True;
175 }
176
177 //==================================================
178 // Function: SetPixelTolerance
179 // Purpose :
180 //==================================================
181
182 void StdSelect_ViewerSelector3d
183 ::SetPixelTolerance(const Standard_Integer aTolerance)
184 {
185   if(mypixtol!=aTolerance)
186   {
187     mypixtol    = aTolerance;
188     myupdatetol = Standard_True;
189   }
190 }
191
192 //==================================================
193 // Function: SelectPix
194 // Purpose :
195 //==================================================
196
197 void StdSelect_ViewerSelector3d
198 ::Pick(const Standard_Integer XPix,
199        const Standard_Integer YPix,
200        const Handle(V3d_View)& aView)
201 {
202   SetClipping (aView->GetClipPlanes());
203   UpdateProj(aView);
204   Standard_Real Xr3d,Yr3d,Zr3d;
205   gp_Pnt2d P2d;
206   aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d);
207   myprj->Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d);
208
209   InitSelect(P2d.X(),P2d.Y());
210 }
211
212
213 //==================================================
214 // Function: InitSelect
215 // Purpose :
216 //==================================================
217
218 void StdSelect_ViewerSelector3d
219 ::Pick(const Standard_Integer XPMin,
220        const Standard_Integer YPMin,
221        const Standard_Integer XPMax,
222        const Standard_Integer YPMax,
223        const Handle(V3d_View)& aView)
224 {
225   if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
226   {
227     SetSensitivity (aView->Convert (mypixtol));
228     myupdatetol = Standard_False;
229   }
230   UpdateProj (aView);
231
232   Standard_Real x1,y1,z1,x2,y2,z2;
233   gp_Pnt2d P2d_1,P2d_2;
234   aView->Convert(XPMin,YPMin,x1,y1,z1);
235   aView->Convert(XPMax,YPMax,x2,y2,z2);
236   myprj->Project(gp_Pnt(x1,y1,z1),P2d_1);
237   myprj->Project(gp_Pnt(x2,y2,z2),P2d_2);
238
239   InitSelect (Min(P2d_1.X(),P2d_2.X()),
240               Min(P2d_1.Y(),P2d_2.Y()),
241               Max(P2d_1.X(),P2d_2.X()),
242               Max(P2d_1.Y(),P2d_2.Y()));
243 }
244
245 //==================================================
246 // Function: Pick
247 // Purpose : Selection using a polyline
248 //==================================================
249
250 void StdSelect_ViewerSelector3d::Pick(const TColgp_Array1OfPnt2d& aPolyline, const Handle(V3d_View)& aView)
251 {
252   if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
253   {
254     SetSensitivity (aView->Convert (mypixtol));
255     myupdatetol = Standard_False;
256   }
257
258   UpdateProj (aView);
259
260   Standard_Integer NbPix = aPolyline.Length();
261   Standard_Integer i;
262
263   // Convert pixel
264   Handle(TColgp_HArray1OfPnt2d) P2d = new TColgp_HArray1OfPnt2d(1,NbPix);
265
266   for (i = 1; i <= NbPix; ++i)
267   {
268     Standard_Real x,y,z;
269     Standard_Integer XP = (Standard_Integer)(aPolyline(i).X());
270     Standard_Integer YP = (Standard_Integer)(aPolyline(i).Y());
271     gp_Pnt2d Pnt2d;
272
273     aView->Convert (XP, YP, x, y, z);
274     myprj->Project (gp_Pnt (x, y, z), Pnt2d);
275
276     P2d->SetValue (i, Pnt2d);
277   }
278
279   const TColgp_Array1OfPnt2d& aPolyConvert = P2d->Array1();
280
281   InitSelect(aPolyConvert);
282 }
283
284 //==================================================
285 // Function: DisplayAreas
286 // Purpose : display the activated areas...
287 //==================================================
288
289 void StdSelect_ViewerSelector3d::DisplayAreas(const Handle(V3d_View)& aView)
290 {
291   if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
292   {
293     SetSensitivity (aView->Convert (mypixtol));
294     myupdatetol = Standard_False;
295   }
296   UpdateProj(aView);
297   UpdateSort(); // Updates the activated areas
298
299   if(mystruct.IsNull())
300     mystruct = new Graphic3d_Structure(aView->Viewer()->Viewer());
301
302   if(myareagroup.IsNull())
303     myareagroup  = new Graphic3d_Group(mystruct);
304
305   SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive It(myentities);
306   Handle(Select3D_Projector) prj = StdSelect::GetProjector(aView);
307   prj->SetView(aView);
308
309   Standard_Real xmin,ymin,xmax,ymax;
310   gp_Pnt Pbid;
311   SelectBasics_ListOfBox2d BoxList;
312
313   TColgp_SequenceOfPnt aSeqLines;
314   for (; It.More(); It.Next())
315   {
316     It.Value()->Areas(BoxList);
317     for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
318     {
319       itb.Value().Get (xmin, ymin, xmax, ymax);
320
321       Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
322       prj->Transform (Pbid, prj->InvertedTransformation());
323           aSeqLines.Append(Pbid);
324
325       Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
326       prj->Transform (Pbid, prj->InvertedTransformation());
327           aSeqLines.Append(Pbid);
328
329       Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
330       prj->Transform (Pbid, prj->InvertedTransformation());
331           aSeqLines.Append(Pbid);
332
333       Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
334       prj->Transform (Pbid, prj->InvertedTransformation());
335           aSeqLines.Append(Pbid);
336     }
337   }
338
339   if (aSeqLines.Length())
340   {
341     Standard_Integer n, np;
342     const Standard_Integer nbl = aSeqLines.Length() / 4;
343     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
344     for (np = 1, n=0; n<nbl; n++) {
345       aPrims->AddBound(5);
346       const gp_Pnt &p1 = aSeqLines(np++);
347       aPrims->AddVertex(p1);
348       aPrims->AddVertex(aSeqLines(np++));
349       aPrims->AddVertex(aSeqLines(np++));
350       aPrims->AddVertex(aSeqLines(np++));
351       aPrims->AddVertex(p1);
352     }
353     myareagroup->AddPrimitiveArray(aPrims);
354   }
355
356   myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
357   myareagroup->Structure()->SetDisplayPriority(10);
358   myareagroup->Structure()->Display();
359
360   if(aView->TransientManagerBeginDraw())
361   {
362     Visual3d_TransientManager::DrawStructure(mystruct);
363     Visual3d_TransientManager::EndDraw();
364   }
365   else
366   {
367     aView->Update();
368   }
369 }
370
371 //==================================================
372 // Function: ClearAreas
373 // Purpose :
374 //==================================================
375
376 void StdSelect_ViewerSelector3d::ClearAreas(const Handle(V3d_View)& aView)
377 {
378   if(myareagroup.IsNull()) return;
379   myareagroup->Clear();
380   if(aView.IsNull()) return;
381   if(aView->TransientManagerBeginDraw())
382     Visual3d_TransientManager::EndDraw();
383   else
384     aView->Update();
385 }
386
387 //==================================================
388 // Function: updateproj
389 // Purpose : at any time verifies that
390 //           the view coefficients did not change :
391 // store current view coeffts
392 //        in static array cf [ 0->2 At coordinates XAT YAT ZAT
393 //                            3->5 Up coordinates XUP YUP ZUP
394 //                            6->8 ProjVect coordinates DX DY DZ
395 //                             9   focale
396 //                            10   1. if pers 0. else
397 //==================================================
398
399 Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj(const Handle(V3d_View)& aView)
400 {
401   myprevcoeff[ 9] = 0.0;
402   myprevcoeff[10] = 0.0;
403   Standard_Boolean Pers = Standard_False;
404   if (aView->Type() == V3d_PERSPECTIVE)
405   {
406     Pers = Standard_True;
407     myprevcoeff[10] = 1.0;
408     myprevcoeff[ 9] = aView->Focale();
409   }
410   aView->At (myprevcoeff[0], myprevcoeff[1], myprevcoeff[2]);
411   aView->Up (myprevcoeff[3], myprevcoeff[4], myprevcoeff[5]);
412   aView->Proj (myprevcoeff[6], myprevcoeff[7], myprevcoeff[8]);
413   aView->AxialScale (myprevcoeff[11], myprevcoeff[12], myprevcoeff[13]);
414   aView->Center (myprevcenter[0], myprevcenter[1]);
415   Standard_Integer ii;
416
417   for (ii = 0; ii <= 13 && (myprevcoeff[ii] == mycoeff[ii]); ++ii) {}
418   if (ii <= 13 || (myprevcenter[0] != mycenter[0]) || (myprevcenter[1] != mycenter[1]))
419   {
420     if (StdSelectDebugModeOn())
421     {
422       cout<<"\t\t\t\t\t VS3d::UpdateProj====> coefficients changes on reprojette"<<endl;
423       cout<<"\t\t\t\t\t";
424       for (Standard_Integer i = 1; i <= 9; ++i)
425       {
426         cout<<mycoeff[i-1]<<"  ";
427         if (i%3==0)
428           cout<<"\n\t\t\t\t\t";
429       }
430       cout<<"focale :"<<mycoeff[9]<<" persp :"<<mycoeff[10]<<endl;
431       cout<<"center :"<<mycenter[0]<<"  "<<mycenter[1]<<endl;
432     }
433     toupdate = Standard_True;
434     myupdatetol = Standard_True;
435     for (Standard_Integer imod = ii; imod <= 13; ++imod)
436     {
437       mycoeff[imod] = myprevcoeff[imod];
438     }
439     for (Standard_Integer jmod = 0; jmod < 2; ++jmod)
440     {
441       mycenter[jmod] = myprevcenter[jmod];
442     }
443
444     gp_Dir Zpers (mycoeff[6], mycoeff[7], mycoeff[8]);
445     gp_Dir Ypers (mycoeff[3], mycoeff[4], mycoeff[5]);
446     gp_Dir Xpers = Ypers.Crossed (Zpers);
447     gp_XYZ loc (mycoeff[0], mycoeff[1], mycoeff[2]);
448     gp_Mat matrix;
449     matrix.SetCols (Xpers.XYZ(), Ypers.XYZ(), Zpers.XYZ());
450     gp_Mat matScale (mycoeff[11], 0, 0, 0, mycoeff[12], 0, 0, 0, mycoeff[13]);
451     matrix.Transpose();
452     loc.Multiply (matrix);
453     loc.Reverse ();
454     matrix.Multiply (matScale);
455     gp_GTrsf GT;
456     GT.SetTranslationPart (loc);
457     GT.SetVectorialPart (matrix);
458
459     myprj = new Select3D_Projector (GT, Pers, mycoeff[9]);
460
461     // SAV 08/05/02 : fix for detection problem in a perspective view
462     if (aView->Type() == V3d_PERSPECTIVE)
463       myprj->SetView (aView);
464     // NKV 31/07/07 : fix for detection problem in case of custom matrix
465     else if (aView->ViewOrientation().IsCustomMatrix())
466       myprj->SetView (aView);
467   }
468
469   if (Abs (aView->Scale() - mylastzoom) > 1.e-3)
470   {
471     myupdatetol = Standard_True;
472     mylastzoom = aView->Scale();
473   }
474
475   if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
476   {
477     SetSensitivity (aView->Convert (mypixtol));
478     myupdatetol = Standard_False;
479   }
480
481   if (toupdate) UpdateConversion();
482   if (tosort) UpdateSort();
483
484   return Standard_True;
485 }
486
487
488 //=============================
489 // Function: DisplaySensitive.
490 // Purpose : Display active primitives.
491 //=============================
492 void StdSelect_ViewerSelector3d::DisplaySensitive(const Handle(V3d_View)& aViou)
493 {
494   if (myupdatetol && SensitivityMode() == StdSelect_SM_WINDOW)
495   {
496     SetSensitivity (aViou->Convert (mypixtol));
497                 myupdatetol = Standard_False;
498   }
499   if(toupdate) UpdateProj(aViou);
500   if(tosort) UpdateSort(); // Updates the activated areas
501
502   // Preparation des structures
503   if(mystruct.IsNull())
504     mystruct = new Graphic3d_Structure(aViou->Viewer()->Viewer());
505
506   if(mysensgroup.IsNull())
507     mysensgroup = new Graphic3d_Group(mystruct);
508
509   Quantity_Color Col(Quantity_NOC_INDIANRED3);
510   Handle(Graphic3d_AspectMarker3d) AM =
511     new Graphic3d_AspectMarker3d(Aspect_TOM_O_PLUS,Col,2.);
512   mysensgroup-> SetPrimitivesAspect (AM);
513   mysensgroup->SetPrimitivesAspect (
514     new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
515
516   // Remplissage de la structure...
517
518   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
519
520   for (; It.More(); It.Next())
521   {
522     if (It.Value()==0)
523     {
524       const Handle(SelectMgr_Selection)& Sel = It.Key();
525       ComputeSensitivePrs(Sel);
526     }
527   }
528
529   mysensgroup->Structure()->SetDisplayPriority(10);
530   mystruct->Display();
531   if (aViou->TransientManagerBeginDraw())
532   {
533     Visual3d_TransientManager::DrawStructure(mystruct);
534     Visual3d_TransientManager::EndDraw();
535   }
536   else if (!aViou.IsNull())
537   {
538     aViou->Update();
539   }
540 }
541
542 //=============================
543 // Function: ClearSensitive
544 // Purpose :
545 //=============================
546 void StdSelect_ViewerSelector3d::ClearSensitive(const Handle(V3d_View)& aViou)
547 {
548   if(mysensgroup.IsNull()) return;
549   mysensgroup->Clear();
550   if(aViou.IsNull()) return;
551
552   if(aViou->TransientManagerBeginDraw())
553     Visual3d_TransientManager::EndDraw();
554   else
555     aViou->Update();
556 }
557
558 //=======================================================================
559 //function : DisplaySenstive
560 //purpose  :
561 //=======================================================================
562 void StdSelect_ViewerSelector3d::
563 DisplaySensitive (const Handle(SelectMgr_Selection)& Sel,
564                   const Handle(V3d_View)& aViou,
565                   const Standard_Boolean ClearOthers)
566 {
567   if (mystruct.IsNull())
568     mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
569   if (mysensgroup.IsNull())
570   {
571     mysensgroup = new Graphic3d_Group (mystruct);
572     Quantity_Color Col (Quantity_NOC_INDIANRED3);
573     Handle(Graphic3d_AspectMarker3d) AM =
574       new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, Col, 2.0);
575     mysensgroup-> SetPrimitivesAspect (AM);
576     mysensgroup->SetPrimitivesAspect (
577       new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
578   }
579
580   if(ClearOthers) mysensgroup->Clear();
581
582   ComputeSensitivePrs(Sel);
583
584   mystruct->SetDisplayPriority(10);
585   mystruct->Display();
586   if(aViou->TransientManagerBeginDraw())
587   {
588     Visual3d_TransientManager::DrawStructure(mystruct);
589     Visual3d_TransientManager::EndDraw();
590   }
591   else if(!aViou.IsNull())
592   {
593     aViou->Update();
594   }
595 }
596
597 //=======================================================================
598 //function : DisplayAreas
599 //purpose  :
600 //=======================================================================
601
602 void StdSelect_ViewerSelector3d::
603 DisplayAreas (const Handle(SelectMgr_Selection)& Sel,
604               const Handle(V3d_View)& aViou,
605               const Standard_Boolean ClearOthers)
606 {
607   if (mystruct.IsNull())
608     mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
609
610   if (mysensgroup.IsNull())
611   {
612     myareagroup = new Graphic3d_Group (mystruct);
613     myareagroup->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
614   }
615
616   if(ClearOthers) myareagroup->Clear();
617
618   ComputeAreasPrs(Sel);
619
620   mystruct->SetDisplayPriority(10);
621   mystruct->Display();
622
623   if(aViou->TransientManagerBeginDraw())
624   {
625     Visual3d_TransientManager::DrawStructure(mystruct);
626     Visual3d_TransientManager::EndDraw();
627   }
628   else
629   {
630     aViou->Update();
631   }
632 }
633
634 //=======================================================================
635 //function : ComputeSensitivePrs
636 //purpose  :
637 //=======================================================================
638
639 void StdSelect_ViewerSelector3d::ComputeSensitivePrs(const Handle(SelectMgr_Selection)& Sel)
640 {
641   TColgp_SequenceOfPnt aSeqLines, aSeqFree;
642   TColStd_SequenceOfInteger aSeqBnds;
643
644   for(Sel->Init();Sel->More();Sel->Next())
645   {
646     Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(Sel->Sensitive());
647     const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation());
648
649     TopLoc_Location theloc;
650     if(hasloc)
651       theloc = Ent->Location();
652
653     //==============
654     // Box
655     //=============
656
657     if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
658     {
659       const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
660       Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
661       B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
662       Standard_Integer i;
663       gp_Pnt theboxpoint[8] =
664       {
665         gp_Pnt(xmin,ymin,zmin),
666         gp_Pnt(xmax,ymin,zmin),
667         gp_Pnt(xmax,ymax,zmin),
668         gp_Pnt(xmin,ymax,zmin),
669         gp_Pnt(xmin,ymin,zmax),
670         gp_Pnt(xmax,ymin,zmax),
671         gp_Pnt(xmax,ymax,zmax),
672         gp_Pnt(xmin,ymax,zmax)
673       };
674       if(hasloc)
675       {
676         for (i = 0; i <= 7; i++)
677           theboxpoint[i].Transform (theloc.Transformation());
678       }
679
680       aSeqBnds.Append(5);
681       for (i = 0; i < 4; i++)
682         aSeqLines.Append(theboxpoint[i]);
683       aSeqLines.Append(theboxpoint[0]);
684
685       aSeqBnds.Append(5);
686       for (i = 4; i < 8; i++)
687         aSeqLines.Append(theboxpoint[i]);
688       aSeqLines.Append(theboxpoint[4]);
689
690       for (i = 0; i < 4; i++)
691       {
692         aSeqBnds.Append(2);
693         aSeqLines.Append(theboxpoint[i]);
694         aSeqLines.Append(theboxpoint[i+4]);
695       }
696     }
697     //==============
698     // Face
699     //=============
700     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
701     {
702       Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
703       Handle(TColgp_HArray1OfPnt) TheHPts;
704       aFace->Points3D(TheHPts);
705       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
706
707       aSeqBnds.Append(ThePts.Length());
708       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
709       {
710         if (hasloc)
711           aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
712         else
713           aSeqLines.Append(ThePts(I));
714       }
715     }
716     //==============
717     // Curve
718     //=============
719     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
720     {
721       Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
722       Handle(TColgp_HArray1OfPnt) TheHPts;
723       aCurve->Points3D(TheHPts);
724       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
725
726       aSeqBnds.Append(ThePts.Length());
727       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
728       {
729         if (hasloc)
730           aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
731         else
732           aSeqLines.Append(ThePts(I));
733       }
734     }
735     //==============
736     // Wire
737     //=============
738     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
739     {
740       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
741       Select3D_SensitiveEntitySequence EntitySeq;
742       aWire->GetEdges (EntitySeq);
743
744       for (int i = 1; i <= EntitySeq.Length(); i++)
745       {
746         Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
747
748         //Segment
749         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
750         {
751           gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
752           gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
753           if (hasloc)
754           {
755             P1.Transform(theloc.Transformation());
756             P2.Transform(theloc.Transformation());
757           }
758           aSeqBnds.Append(2);
759           aSeqLines.Append(P1);
760           aSeqLines.Append(P2);
761         }
762
763         //circle
764         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
765         {
766           Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
767           Standard_Integer Lo, Up;
768           C->ArrayBounds (Lo, Up);
769           Standard_Integer II = Lo;
770           while (II <= Up - 2)
771           {
772             gp_Pnt ThePts[3] =
773             {
774               gp_Pnt (C->GetPoint3d (II).XYZ()),
775               gp_Pnt (C->GetPoint3d (++II).XYZ()),
776               gp_Pnt (C->GetPoint3d (++II).XYZ())
777             };
778
779             if (hasloc)
780             {
781               for (Standard_Integer jj = 0; jj <= 2; jj++)
782                 ThePts[jj].Transform (theloc.Transformation());
783             }
784
785             aSeqBnds.Append(4);
786             aSeqLines.Append(ThePts[0]);
787             aSeqLines.Append(ThePts[1]);
788             aSeqLines.Append(ThePts[2]);
789             aSeqLines.Append(ThePts[0]);
790           }
791         }
792
793         //curve
794         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
795         {
796           Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
797           Handle(TColgp_HArray1OfPnt) TheHPts;
798           aCurve->Points3D (TheHPts);
799           const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
800
801           aSeqBnds.Append(ThePts.Length());
802           for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
803           {
804             if (hasloc)
805               aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation()));
806             else
807               aSeqLines.Append(ThePts(I));
808           }
809         }
810       }
811     }
812     //==============
813     // Segment
814     //=============
815     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
816     {
817       gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
818       gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
819       if (hasloc)
820       {
821         P1.Transform (theloc.Transformation());
822         P2.Transform (theloc.Transformation());
823       }
824       aSeqBnds.Append(2);
825       aSeqLines.Append(P1);
826       aSeqLines.Append(P2);
827     }
828     //==============
829     // Circle
830     //=============
831     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
832     {
833       Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
834       Standard_Integer Lo, Up;
835       C->ArrayBounds (Lo, Up);
836       Standard_Integer II = Lo;
837       while (II <= Up - 2)
838       {
839         gp_Pnt ThePts[3] =
840         {
841           gp_Pnt (C->GetPoint3d (II).XYZ()),
842           gp_Pnt (C->GetPoint3d (++II).XYZ()),
843           gp_Pnt (C->GetPoint3d (++II).XYZ())
844         };
845
846         if (hasloc)
847         {
848           for (Standard_Integer jj = 0; jj <= 2; jj++)
849             ThePts[jj].Transform (theloc.Transformation());
850         }
851
852         aSeqBnds.Append(4);
853         aSeqLines.Append(ThePts[0]);
854         aSeqLines.Append(ThePts[1]);
855         aSeqLines.Append(ThePts[2]);
856         aSeqLines.Append(ThePts[0]);
857       }
858     }
859     //==============
860     // Point
861     //=============
862     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
863     {
864       gp_Pnt P = hasloc ?
865         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
866         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
867       Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
868       anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
869       mysensgroup->AddPrimitiveArray (anArrayOfPoints);
870     }
871     //============================================================
872     // Triangulation : On met un petit offset ves l'interieur...
873     //==========================================================
874     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
875     {
876       const Handle(Poly_Triangulation)& PT =
877         (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
878
879       const Poly_Array1OfTriangle& triangles = PT->Triangles();
880       const TColgp_Array1OfPnt& Nodes = PT->Nodes();
881       Standard_Integer n[3];
882
883       TopLoc_Location iloc, bidloc;
884       if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
885         bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
886
887       if (bidloc.IsIdentity())
888         iloc = theloc;
889       else
890         iloc = theloc * bidloc;
891
892       Standard_Integer i;
893       for (i = 1; i <= PT->NbTriangles(); i++)
894       {
895         triangles (i).Get (n[0], n[1], n[2]);
896         gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
897         gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
898         gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
899         gp_XYZ V1 (P1.XYZ());
900         gp_XYZ V2 (P2.XYZ());
901         gp_XYZ V3 (P3.XYZ());
902         gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
903         V1 -= CDG; V2 -= CDG; V3 -= CDG;
904         V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
905         V1 += CDG; V2 += CDG; V3 += CDG;
906
907         aSeqBnds.Append(4);
908         aSeqLines.Append(gp_Pnt(V1));
909         aSeqLines.Append(gp_Pnt(V2));
910         aSeqLines.Append(gp_Pnt(V3));
911         aSeqLines.Append(gp_Pnt(V1));
912       }
913
914       // recherche des bords libres...
915
916       Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
917       TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
918       Poly_Connect pc (PT);
919       Standard_Integer t[3];
920       Standard_Integer j;
921       Standard_Integer fr (1);
922       for (i = 1; i <= PT->NbTriangles(); i++)
923       {
924         pc.Triangles (i, t[0], t[1], t[2]);
925         triangles (i).Get (n[0], n[1], n[2]);
926         for (j = 0; j < 3; j++)
927         {
928           Standard_Integer k = (j + 1) % 3;
929           if (t[j] == 0)
930           {
931             FreeE (fr)    = n[j];
932             FreeE (fr + 1)= n[k];
933             fr += 2;
934           }
935         }
936       }
937       for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
938       {
939         gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
940         aSeqFree.Append(pe1);
941         aSeqFree.Append(pe2);
942       }
943     }
944     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
945     {
946       Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
947       gp_Pnt P1, P2, P3;
948       Str->Points3D (P1, P2, P3);
949       gp_Pnt CDG = Str->Center3D();
950
951       gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
952       gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
953       gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
954       V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
955       V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
956
957       aSeqBnds.Append(4);
958       aSeqLines.Append(gp_Pnt(V1));
959       aSeqLines.Append(gp_Pnt(V2));
960       aSeqLines.Append(gp_Pnt(V3));
961       aSeqLines.Append(gp_Pnt(V1));
962     }
963   }
964
965   Standard_Integer i;
966
967   if (aSeqLines.Length())
968   {
969     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
970     for (i = 1; i <= aSeqLines.Length(); i++)
971       aPrims->AddVertex(aSeqLines(i));
972     for (i = 1; i <= aSeqBnds.Length(); i++)
973       aPrims->AddBound(aSeqBnds(i));
974     myareagroup->AddPrimitiveArray(aPrims);
975   }
976
977   if (aSeqFree.Length())
978   {
979     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
980     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
981     for (i = 1; i <= aSeqFree.Length(); i++)
982         {
983       aPrims->AddBound(2);
984       aPrims->AddVertex(aSeqLines(i++));
985       aPrims->AddVertex(aSeqLines(i));
986         }
987     mysensgroup->AddPrimitiveArray(aPrims);
988     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
989   }
990 }
991
992 //=======================================================================
993 //function : ComputeAreaPrs
994 //purpose  :
995 //=======================================================================
996
997 void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& Sel)
998 {
999   Standard_Real xmin, ymin, xmax, ymax;
1000   gp_Pnt Pbid;
1001   SelectBasics_ListOfBox2d BoxList;
1002
1003   TColgp_SequenceOfPnt aSeqLines;
1004   for (Sel->Init(); Sel->More(); Sel->Next())
1005   {
1006     Sel->Sensitive()->Areas (BoxList);
1007     for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
1008     {
1009       itb.Value().Get (xmin, ymin, xmax, ymax);
1010
1011       Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
1012       myprj->Transform (Pbid, myprj->InvertedTransformation());
1013       aSeqLines.Append(Pbid);
1014
1015       Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
1016       myprj->Transform (Pbid, myprj->InvertedTransformation());
1017       aSeqLines.Append(Pbid);
1018
1019       Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
1020       myprj->Transform (Pbid, myprj->InvertedTransformation());
1021       aSeqLines.Append(Pbid);
1022
1023       Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
1024       myprj->Transform (Pbid, myprj->InvertedTransformation());
1025       aSeqLines.Append(Pbid);
1026     }
1027   }
1028
1029   if (aSeqLines.Length())
1030   {
1031     Standard_Integer n, np;
1032     const Standard_Integer nbl = aSeqLines.Length() / 4;
1033     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(5*nbl,nbl);
1034     for (np = 1, n=0; n<nbl; n++) {
1035       aPrims->AddBound(5);
1036       const gp_Pnt &p1 = aSeqLines(np++);
1037       aPrims->AddVertex(p1);
1038       aPrims->AddVertex(aSeqLines(np++));
1039       aPrims->AddVertex(aSeqLines(np++));
1040       aPrims->AddVertex(aSeqLines(np++));
1041       aPrims->AddVertex(p1);
1042     }
1043     myareagroup->AddPrimitiveArray(aPrims);
1044   }
1045 }
1046
1047 //=======================================================================
1048 //function : SetClipping
1049 //purpose  :
1050 //=======================================================================
1051 void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SetOfHClipPlane& thePlanes)
1052 {
1053   myClipPlanes = thePlanes;
1054 }
1055
1056 //=======================================================================
1057 //function : ComputeClipRange
1058 //purpose  :
1059 //=======================================================================
1060 void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SetOfHClipPlane& thePlanes,
1061                                                    const gp_Lin& thePickLine,
1062                                                    Standard_Real& theDepthMin,
1063                                                    Standard_Real& theDepthMax) const
1064 {
1065   theDepthMin = RealFirst();
1066   theDepthMax = RealLast();
1067   Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
1068
1069   Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
1070   for (; aPlaneIt.More(); aPlaneIt.Next())
1071   {
1072     const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
1073     if (!aClipPlane->IsOn())
1074       continue;
1075
1076     gp_Pln aGeomPlane = aClipPlane->ToPlane();
1077
1078     aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
1079
1080     const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
1081     const gp_Dir& aPickDir  = thePickLine.Direction();
1082     const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
1083     const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
1084
1085     Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
1086     Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
1087
1088     // check whether the pick line is parallel to clip plane
1089     if (Abs (aDotProduct) < Precision::Angular())
1090     {
1091       if (aDistance > 0.0)
1092       {
1093         // line lies above the plane, thus no selection is possible
1094         theDepthMin = 0.0;
1095         theDepthMax = 0.0;
1096         return;
1097       }
1098
1099       // line lies below the plane and is not clipped, skip
1100       continue;
1101     }
1102
1103     // compute distance to point of pick line intersection with the plane
1104     Standard_Real aIntDist = aDistance / aDotProduct;
1105
1106     // change depth limits for case of opposite and directed planes
1107     if (aDotProduct < 0.0)
1108     {
1109       theDepthMax = Min (aIntDist, theDepthMax);
1110     }
1111     else if (aIntDist > theDepthMin)
1112     {
1113       theDepthMin = Max (aIntDist, theDepthMin);
1114     }
1115   }
1116 }
1117
1118 //=======================================================================
1119 //function : PickingLine
1120 //purpose  :
1121 //=======================================================================
1122 gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
1123 {
1124   return myprj->Shoot (theX, theY);
1125 }
1126
1127 //=======================================================================
1128 //function : DepthClipping
1129 //purpose  :
1130 //=======================================================================
1131 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1132                                                 const Standard_Real theY,
1133                                                 Standard_Real& theDepthMin,
1134                                                 Standard_Real& theDepthMax) const
1135 {
1136   return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
1137 }
1138
1139 //=======================================================================
1140 //function : DepthClipping
1141 //purpose  :
1142 //=======================================================================
1143 void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
1144                                                 const Standard_Real theY,
1145                                                 const Handle(SelectMgr_EntityOwner)& theOwner,
1146                                                 Standard_Real& theDepthMin,
1147                                                 Standard_Real& theDepthMax) const
1148 {
1149   return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
1150                            PickingLine (theX, theY),
1151                            theDepthMin, theDepthMax);
1152 }
1153
1154 //=======================================================================
1155 //function : HasDepthClipping
1156 //purpose  :
1157 //=======================================================================
1158 Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
1159 {
1160   if (!theOwner->HasSelectable())
1161   {
1162     return Standard_False;
1163   }
1164
1165   const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
1166   return (aSelectable->GetClipPlanes().Size() > 0);
1167 }