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