4292c1920d7a72edabaa90fbd0788adf431ef10e
[occt.git] / src / StdSelect / StdSelect_ViewerSelector3d.cxx
1 // Copyright:  Matra-Datavision 1995
2 // File:       StdSelect_ViewerSelector3d.cxx
3 // Created:    Wed Mar 15 10:30:14 1995
4 // Author:     Robert COUBLANC
5 //   <rob>
6
7 #include <StdSelect_ViewerSelector3d.ixx>
8 #include <StdSelect.hxx>
9 #include <SelectBasics_SensitiveEntity.hxx>
10 #include <Graphic3d_AspectLine3d.hxx>
11 #include <gp_Pnt.hxx>
12 #include <gp_Lin.hxx>
13 #include <gp_Pnt2d.hxx>
14 #include <gp_Dir.hxx>
15 #include <gp_Ax3.hxx>
16 #include <gp_GTrsf.hxx>
17 #include <V3d_PerspectiveView.hxx>
18 #include <Select3D_SensitiveEntity.hxx>
19 #include <Graphic3d_Array1OfVertex.hxx>
20 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
21 #include <SelectBasics_ListOfBox2d.hxx>
22 #include <Visual3d_TransientManager.hxx>
23 #include <TColgp_HArray1OfPnt.hxx>
24 #include <TColgp_Array1OfPnt.hxx>
25 #include <TColgp_HArray1OfPnt2d.hxx>
26 #include <Select3D_SensitiveCurve.hxx>
27 #include <Select3D_SensitiveSegment.hxx>
28 #include <Select3D_SensitiveFace.hxx>
29 #include <Select3D_SensitiveCircle.hxx>
30 #include <Select3D_SensitivePoint.hxx>
31 #include <Select3D_SensitiveTriangulation.hxx>
32 #include <Select3D_SensitiveTriangle.hxx>
33 #include <Select3D_SensitiveWire.hxx>
34 #include <Select3D_SensitiveEntitySequence.hxx>
35 #include <Select3D_ListOfSensitiveTriangle.hxx>
36 #include <Select3D_SensitiveBox.hxx>
37 #include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
38
39 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
40 #include <Aspect_TypeOfMarker.hxx>
41 #include <Graphic3d_AspectMarker3d.hxx>
42 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
43 #include <Poly_Connect.hxx>
44 #include <TColStd_HArray1OfInteger.hxx>
45
46 #include <Poly_Array1OfTriangle.hxx>
47 #include <Poly_Triangulation.hxx>
48 #include <OSD_Environment.hxx>
49 #include <V3d.hxx>
50 #include <V3d_View.hxx>
51
52 static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
53 {
54   Standard_Integer nFree = 0;
55   Poly_Connect pc(Trg);
56   Standard_Integer t[3];
57   Standard_Integer i, j;
58   for (i = 1; i <= Trg->NbTriangles(); i++)
59   {
60     pc.Triangles (i, t[0], t[1], t[2]);
61     for (j = 0; j < 3; j++)
62       if (t[j] == 0) nFree++;
63   }
64   return nFree;
65 }
66
67 static Standard_Boolean ReadIsDebugMode()
68 {
69   OSD_Environment StdSelectdb ("SELDEBUGMODE");
70   return !StdSelectdb.Value().IsEmpty();
71 }
72
73 static Standard_Boolean StdSelectDebugModeOn()
74 {
75   static const Standard_Boolean isDebugMode = ReadIsDebugMode();
76   return isDebugMode;
77 }
78
79 //==================================================
80 // Function:
81 // Purpose :
82 //==================================================
83
84 StdSelect_ViewerSelector3d
85 ::StdSelect_ViewerSelector3d():
86 mylastzoom(0.0),
87 mypixtol(2),
88 myupdatetol(Standard_True)
89 {
90   for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
91   for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
92 }
93
94
95 //==================================================
96 // Function:
97 // Purpose :
98 //==================================================
99
100 StdSelect_ViewerSelector3d
101 ::StdSelect_ViewerSelector3d(const Select3D_Projector& aProj):
102 myprj(aProj),
103 mylastzoom(0.0),
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 // Function: Convert
113 // Purpose :
114 //==================================================
115
116 void StdSelect_ViewerSelector3d::Convert(const Handle(SelectMgr_Selection)& aSel)
117 {
118   for(aSel->Init();aSel->More();aSel->Next())
119   {
120     if(aSel->Sensitive()->NeedsConversion())
121     {
122       Handle(Select3D_SensitiveEntity) SE = *((Handle(Select3D_SensitiveEntity)*) &(aSel->Sensitive()));
123       SE->Project(myprj);
124       if(!tosort) tosort=Standard_True;
125     }
126   }
127 }
128
129 //==================================================
130 // Function: Set
131 // Purpose :
132 //==================================================
133
134 void StdSelect_ViewerSelector3d
135 ::Set(const Standard_Integer PixelTolerance)
136 {
137   if(mypixtol!=PixelTolerance)
138   {
139     mypixtol   =  PixelTolerance;
140     myupdatetol = Standard_True;
141   }
142 }
143
144 //==================================================
145 // Function: Set
146 // Purpose :
147 //==================================================
148
149 void StdSelect_ViewerSelector3d
150 ::Set(const Select3D_Projector& aProj)
151 {
152   myprj = aProj;
153   toupdate=Standard_True;
154 }
155
156 //==================================================
157 // Function: SelectPix
158 // Purpose :
159 //==================================================
160
161 void StdSelect_ViewerSelector3d
162 ::Pick(const Standard_Integer XPix,
163        const Standard_Integer YPix,
164        const Handle(V3d_View)& aView)
165 {
166   UpdateProj(aView);
167   Standard_Real Xr3d,Yr3d,Zr3d;
168   gp_Pnt2d P2d;
169   aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d);
170   myprj.Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d);
171   InitSelect(P2d.X(),P2d.Y());
172 }
173
174
175 //==================================================
176 // Function: InitSelect
177 // Purpose :
178 //==================================================
179
180 void StdSelect_ViewerSelector3d
181 ::Pick(const Standard_Integer XPMin,
182        const Standard_Integer YPMin,
183        const Standard_Integer XPMax,
184        const Standard_Integer YPMax,
185        const Handle(V3d_View)& aView)
186 {
187   if (myupdatetol)
188   {
189     SetSensitivity (aView->Convert (mypixtol));
190     myupdatetol = Standard_False;
191   }
192   UpdateProj (aView);
193
194   Standard_Real x1,y1,z1,x2,y2,z2;
195   gp_Pnt2d P2d_1,P2d_2;
196   aView->Convert(XPMin,YPMin,x1,y1,z1);
197   aView->Convert(XPMax,YPMax,x2,y2,z2);
198   myprj.Project(gp_Pnt(x1,y1,z1),P2d_1);
199   myprj.Project(gp_Pnt(x2,y2,z2),P2d_2);
200
201   InitSelect (Min(P2d_1.X(),P2d_2.X()),
202               Min(P2d_1.Y(),P2d_2.Y()),
203               Max(P2d_1.X(),P2d_2.X()),
204               Max(P2d_1.Y(),P2d_2.Y()));
205 }
206
207 //==================================================
208 // Function: Pick
209 // Purpose : Selection using a polyline
210 //==================================================
211
212 void StdSelect_ViewerSelector3d
213 ::Pick(const TColgp_Array1OfPnt2d& aPolyline,
214        const Handle(V3d_View)& aView)
215 {
216   if (myupdatetol)
217   {
218     SetSensitivity (aView->Convert (mypixtol));
219     myupdatetol = Standard_False;
220   }
221
222   UpdateProj (aView);
223
224   Standard_Integer NbPix = aPolyline.Length();
225   Standard_Integer i;
226
227   // Convert pixel
228   Handle(TColgp_HArray1OfPnt2d) P2d =
229     new TColgp_HArray1OfPnt2d(1,NbPix);
230
231   for (i = 1; i <= NbPix; ++i)
232   {
233     Standard_Real x,y,z;
234     Standard_Integer XP = (Standard_Integer)(aPolyline(i).X());
235     Standard_Integer YP = (Standard_Integer)(aPolyline(i).Y());
236     gp_Pnt2d Pnt2d;
237
238     aView->Convert (XP, YP, x, y, z);
239     myprj.Project (gp_Pnt (x, y, z), Pnt2d);
240
241     P2d->SetValue (i, Pnt2d);
242   }
243
244   const TColgp_Array1OfPnt2d& aPolyConvert = P2d->Array1();
245
246   InitSelect(aPolyConvert);
247 }
248
249 //==================================================
250 // Function: DisplayAreas
251 // Purpose : display the activated areas...
252 //==================================================
253
254 void StdSelect_ViewerSelector3d::
255 DisplayAreas(const Handle(V3d_View)& aView)
256 {
257   if (myupdatetol)
258   {
259     SetSensitivity (aView->Convert (mypixtol));
260                 myupdatetol = Standard_False;
261   }
262   UpdateProj(aView);
263   UpdateSort(); // Updates the activated areas
264
265   if(mystruct.IsNull())
266   {
267     mystruct = new Graphic3d_Structure(aView->Viewer()->Viewer());
268   }
269   if(myareagroup.IsNull())
270   {
271     myareagroup  = new Graphic3d_Group(mystruct);
272   }
273
274   SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive It(myentities);
275   Select3D_Projector prj = StdSelect::GetProjector(aView);
276   prj.SetView(aView);
277
278
279   Graphic3d_Array1OfVertex Av1 (1,5);
280
281   Standard_Real xmin,ymin,xmax,ymax;
282   gp_Pnt Pbid;
283   SelectBasics_ListOfBox2d BoxList;
284
285   myareagroup->BeginPrimitives();
286   for (; It.More(); It.Next())
287   {
288     It.Value()->Areas(BoxList);
289     for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
290     {
291       itb.Value().Get (xmin, ymin, xmax, ymax);
292
293       Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
294       prj.Transform (Pbid, prj.InvertedTransformation());
295       Av1.SetValue (1, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
296
297       Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
298       prj.Transform (Pbid, prj.InvertedTransformation());
299       Av1.SetValue (2, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
300
301       Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
302       prj.Transform (Pbid, prj.InvertedTransformation());
303       Av1.SetValue (3, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
304
305       Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
306       prj.Transform (Pbid, prj.InvertedTransformation());
307       Av1.SetValue (4,Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
308
309       Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
310       prj.Transform (Pbid, prj.InvertedTransformation());
311       Av1.SetValue (5, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
312
313       myareagroup->Polyline (Av1);
314     }
315   }
316
317   myareagroup->EndPrimitives();
318   myareagroup->SetGroupPrimitivesAspect (new
319     Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
320   myareagroup->Structure()->SetDisplayPriority(10);
321   myareagroup->Structure()->Display();
322
323   if(aView->TransientManagerBeginDraw())
324   {
325     Visual3d_TransientManager::DrawStructure(mystruct);
326     Visual3d_TransientManager::EndDraw();
327   }
328   else
329   {
330     aView->Update();
331   }
332 }
333
334 //==================================================
335 // Function: ClearAreas
336 // Purpose :
337 //==================================================
338
339 void StdSelect_ViewerSelector3d::
340 ClearAreas(const Handle(V3d_View)& aView)
341 {
342   if(myareagroup.IsNull()) return;
343   myareagroup->Clear();
344   if(aView.IsNull()) return;
345   if(aView->TransientManagerBeginDraw())
346     Visual3d_TransientManager::EndDraw();
347   else
348     aView->Update();
349 }
350
351 //==================================================
352 // Function: updateproj
353 // Purpose : at any time verifies that
354 //           the view coefficients did not change :
355 // store current view coeffts
356 //        in static array cf [ 0->2 At coordinates XAT YAT ZAT
357 //                            3->5 Up coordinates XUP YUP ZUP
358 //                            6->8 ProjVect coordinates DX DY DZ
359 //                             9   focale
360 //                            10   1. if pers 0. else
361 //==================================================
362
363 Standard_Boolean  StdSelect_ViewerSelector3d::
364 UpdateProj(const Handle(V3d_View)& aView)
365 {
366   myprevcoeff[ 9] = 0.0;
367   myprevcoeff[10] = 0.0;
368   Standard_Boolean Pers = Standard_False;
369   if (aView->Type() == V3d_PERSPECTIVE)
370   {
371     Pers = Standard_True;
372     myprevcoeff[10] = 1.0;
373     myprevcoeff[ 9] = aView->Focale();
374   }
375   aView->At (myprevcoeff[0], myprevcoeff[1], myprevcoeff[2]);
376   aView->Up (myprevcoeff[3], myprevcoeff[4], myprevcoeff[5]);
377   aView->Proj (myprevcoeff[6], myprevcoeff[7], myprevcoeff[8]);
378   aView->AxialScale (myprevcoeff[11], myprevcoeff[12], myprevcoeff[13]);
379   aView->Center (myprevcenter[0], myprevcenter[1]);
380   Standard_Integer ii;
381
382   for (ii = 0; ii <= 13 && (myprevcoeff[ii] == mycoeff[ii]); ++ii) {}
383   if (ii <= 13 || (myprevcenter[0] != mycenter[0]) || (myprevcenter[1] != mycenter[1]))
384   {
385     if (StdSelectDebugModeOn())
386     {
387       cout<<"\t\t\t\t\t VS3d::UpdateProj====> coefficients changes on reprojette"<<endl;
388       cout<<"\t\t\t\t\t";
389       for (Standard_Integer i = 1; i <= 9; ++i)
390       {
391         cout<<mycoeff[i-1]<<"  ";
392         if (i%3==0)
393           cout<<"\n\t\t\t\t\t";
394       }
395       cout<<"focale :"<<mycoeff[9]<<" persp :"<<mycoeff[10]<<endl;
396       cout<<"center :"<<mycenter[0]<<"  "<<mycenter[1]<<endl;
397     }
398     toupdate = Standard_True;
399     myupdatetol = Standard_True;
400     for (Standard_Integer imod = ii; imod <= 13; ++imod)
401     {
402       mycoeff[imod] = myprevcoeff[imod];
403     }
404     for (Standard_Integer jmod = 0; jmod < 2; ++jmod)
405     {
406       mycenter[jmod] = myprevcenter[jmod];
407     }
408
409     gp_Dir Zpers (mycoeff[6], mycoeff[7], mycoeff[8]);
410     gp_Dir Ypers (mycoeff[3], mycoeff[4], mycoeff[5]);
411     gp_Dir Xpers = Ypers.Crossed (Zpers);
412     gp_XYZ loc (mycoeff[0], mycoeff[1], mycoeff[2]);
413     gp_Mat matrix;
414     matrix.SetCols (Xpers.XYZ(), Ypers.XYZ(), Zpers.XYZ());
415     gp_Mat matScale (mycoeff[11], 0, 0, 0, mycoeff[12], 0, 0, 0, mycoeff[13]);
416     matrix.Transpose();
417     loc.Multiply (matrix);
418     loc.Reverse ();
419     matrix.Multiply (matScale);
420     gp_GTrsf GT;
421     GT.SetTranslationPart (loc);
422     GT.SetVectorialPart (matrix);
423
424     myprj = Select3D_Projector (GT, Pers, mycoeff[9]);
425
426     // SAV 08/05/02 : fix for detection problem in a perspective view
427     if (aView->Type() == V3d_PERSPECTIVE)
428       myprj.SetView (aView);
429     // NKV 31/07/07 : fix for detection problem in case of custom matrix
430     else if (aView->ViewOrientation().IsCustomMatrix())
431       myprj.SetView (aView);
432   }
433
434   if (Abs (aView->Scale() - mylastzoom) > 1.e-3)
435   {
436     myupdatetol = Standard_True;
437     mylastzoom = aView->Scale();
438   }
439
440   if (myupdatetol)
441   {
442     SetSensitivity (aView->Convert (mypixtol));
443     myupdatetol = Standard_False;
444   }
445
446   if (toupdate) UpdateConversion();
447   if (tosort) UpdateSort();
448
449   return Standard_True;
450 }
451
452
453 //=============================
454 // Function: DisplaySensitive.
455 // Purpose : Display active primitives.
456 //=============================
457 void StdSelect_ViewerSelector3d::DisplaySensitive(const Handle(V3d_View)& aViou)
458 {
459   if (myupdatetol)
460   {
461     SetSensitivity (aViou->Convert (mypixtol));
462                 myupdatetol = Standard_False;
463   }
464   if(toupdate) UpdateProj(aViou);
465   if(tosort) UpdateSort(); // Updates the activated areas
466
467   // Preparation des structures
468   if(mystruct.IsNull())
469     mystruct = new Graphic3d_Structure(aViou->Viewer()->Viewer());
470
471   if(mysensgroup.IsNull())
472     mysensgroup = new Graphic3d_Group(mystruct);
473
474   Quantity_Color Col(Quantity_NOC_INDIANRED3);
475   Handle(Graphic3d_AspectMarker3d) AM =
476     new Graphic3d_AspectMarker3d(Aspect_TOM_O_PLUS,Col,2.);
477   mysensgroup-> SetPrimitivesAspect (AM);
478   mysensgroup->SetPrimitivesAspect (
479     new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
480
481   // Remplissage de la structure...
482
483   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
484   // Standard_Integer isel (0);
485
486   mysensgroup->BeginPrimitives();
487   for (; It.More(); It.Next())
488   {
489     if (It.Value()==0)
490     {
491       const Handle(SelectMgr_Selection)& Sel = It.Key();
492       ComputeSensitivePrs(Sel);
493     }
494   }
495   mysensgroup->EndPrimitives();
496
497   mysensgroup->Structure()->SetDisplayPriority(10);
498   mystruct->Display();
499   if (aViou->TransientManagerBeginDraw())
500   {
501     Visual3d_TransientManager::DrawStructure(mystruct);
502     Visual3d_TransientManager::EndDraw();
503   }
504   else if (!aViou.IsNull())
505   {
506     aViou->Update();
507   }
508 }
509
510 //=============================
511 // Function: ClearSensitive
512 // Purpose :
513 //=============================
514 void StdSelect_ViewerSelector3d::ClearSensitive(const Handle(V3d_View)& aViou)
515 {
516   if(mysensgroup.IsNull()) return;
517   mysensgroup->Clear();
518   if(aViou.IsNull()) return;
519
520   if(aViou->TransientManagerBeginDraw())
521     Visual3d_TransientManager::EndDraw();
522   else
523     aViou->Update();
524 }
525
526 //=======================================================================
527 //function : DisplaySenstive
528 //purpose  :
529 //=======================================================================
530 void StdSelect_ViewerSelector3d::
531 DisplaySensitive (const Handle(SelectMgr_Selection)& Sel,
532                   const Handle(V3d_View)& aViou,
533                   const Standard_Boolean ClearOthers)
534 {
535   if (mystruct.IsNull())
536     mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
537   if (mysensgroup.IsNull())
538   {
539     mysensgroup = new Graphic3d_Group (mystruct);
540     Quantity_Color Col (Quantity_NOC_INDIANRED3);
541     Handle(Graphic3d_AspectMarker3d) AM =
542       new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, Col, 2.0);
543     mysensgroup-> SetPrimitivesAspect (AM);
544     mysensgroup->SetPrimitivesAspect (
545       new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
546   }
547
548   if(ClearOthers) mysensgroup->Clear();
549
550   mysensgroup->BeginPrimitives();
551
552   ComputeSensitivePrs(Sel);
553
554   mysensgroup->EndPrimitives();
555   mystruct->SetDisplayPriority(10);
556   mystruct->Display();
557   if(aViou->TransientManagerBeginDraw())
558   {
559     Visual3d_TransientManager::DrawStructure(mystruct);
560     Visual3d_TransientManager::EndDraw();
561   }
562   else if(!aViou.IsNull())
563   {
564     aViou->Update();
565   }
566 }
567
568 //=======================================================================
569 //function : DisplayAreas
570 //purpose  :
571 //=======================================================================
572
573 void StdSelect_ViewerSelector3d::
574 DisplayAreas (const Handle(SelectMgr_Selection)& Sel,
575               const Handle(V3d_View)& aViou,
576               const Standard_Boolean ClearOthers)
577 {
578   if (mystruct.IsNull())
579     mystruct = new Graphic3d_Structure (aViou->Viewer()->Viewer());
580   if (mysensgroup.IsNull())
581   {
582     myareagroup = new Graphic3d_Group (mystruct);
583     myareagroup->SetGroupPrimitivesAspect (
584       new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
585   }
586
587   if(ClearOthers) myareagroup->Clear();
588
589   myareagroup->BeginPrimitives();
590   ComputeAreasPrs(Sel);
591   myareagroup->EndPrimitives();
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::
613 ComputeSensitivePrs(const Handle(SelectMgr_Selection)& Sel)
614 {
615   for(Sel->Init();Sel->More();Sel->Next())
616   {
617     Handle(Select3D_SensitiveEntity) Ent =
618       Handle(Select3D_SensitiveEntity)::DownCast(Sel->Sensitive());
619     Standard_Boolean hasloc = (Ent.IsNull()) ? Standard_False:
620       (Ent->HasLocation()? Standard_True:Standard_False);
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       gp_Pnt theboxpoint[8] =
636       {
637         gp_Pnt(xmin,ymin,zmin),
638         gp_Pnt(xmax,ymin,zmin),
639         gp_Pnt(xmax,ymax,zmin),
640         gp_Pnt(xmin,ymax,zmin),
641         gp_Pnt(xmin,ymin,zmax),
642         gp_Pnt(xmax,ymin,zmax),
643         gp_Pnt(xmax,ymax,zmax),
644         gp_Pnt(xmin,ymax,zmax)
645       };
646       if(hasloc)
647       {
648         for (Standard_Integer ii = 0; ii <= 7; ii++)
649           theboxpoint[ii].Transform (theloc.Transformation());
650       }
651       Graphic3d_Array1OfVertex Vtx (1, 5);
652
653       Standard_Integer ip;
654       for (ip = 0; ip < 4; ip++)
655       {
656         Vtx.SetValue (ip + 1, Graphic3d_Vertex (theboxpoint[ip].X(),
657                                                 theboxpoint[ip].Y(),
658                                                 theboxpoint[ip].Z()));
659       }
660       mysensgroup->Polyline (Vtx);
661       for (ip = 0; ip < 4; ip++)
662       {
663         Vtx.SetValue (ip + 1, Graphic3d_Vertex (theboxpoint[ip + 4].X(),
664                                                 theboxpoint[ip + 4].Y(),
665                                                 theboxpoint[ip + 4].Z()));
666       }
667       mysensgroup->Polyline (Vtx);
668
669       Graphic3d_Array1OfVertex Vtx2 (1, 2);
670       for (ip = 0; ip < 4; ip++)
671       {
672         Vtx2.SetValue (1, Graphic3d_Vertex (theboxpoint[ip].X(),
673                                             theboxpoint[ip].Y(),
674                                             theboxpoint[ip].Z()));
675
676         Vtx2.SetValue (2, Graphic3d_Vertex (theboxpoint[ip + 4].X(),
677                                             theboxpoint[ip + 4].Y(),
678                                             theboxpoint[ip + 4].Z()));
679         mysensgroup->Polyline (Vtx2);
680       }
681     }
682     //==============
683     // Face
684     //=============
685     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
686     {
687       Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
688       Handle(TColgp_HArray1OfPnt) TheHPts;
689       aFace->Points3D(TheHPts);
690       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
691
692       Graphic3d_Array1OfVertex Vtx (ThePts.Lower(), ThePts.Upper());
693
694       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
695       {
696         if (hasloc)
697         {
698           const gp_Pnt& curP = ThePts (I);
699           gp_Pnt ptrans = curP.Transformed (theloc.Transformation()).XYZ();
700           Vtx.SetValue (I, Graphic3d_Vertex (ptrans.X(), ptrans.Y(), ptrans.Z()));
701         }
702         else
703         {
704           Vtx.SetValue (I, Graphic3d_Vertex (ThePts (I).X(), ThePts (I).Y(), ThePts (I).Z()));
705         }
706       }
707       mysensgroup->Polyline (Vtx);
708     }
709     //==============
710     // Curve
711     //=============
712     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
713     {
714       Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
715       Handle(TColgp_HArray1OfPnt) TheHPts;
716       aCurve->Points3D(TheHPts);
717       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
718
719       Graphic3d_Array1OfVertex Vtx (ThePts.Lower(), ThePts.Upper());
720       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
721       {
722         if (hasloc)
723         {
724           gp_Pnt ptrans (ThePts (I).Transformed (theloc.Transformation()).XYZ());
725           Vtx.SetValue (I, Graphic3d_Vertex (ptrans.X(), ptrans.Y(), ptrans.Z()));
726         }
727         else
728         {
729           Vtx.SetValue (I, Graphic3d_Vertex (ThePts (I).X(), ThePts (I).Y(), ThePts (I).Z()));
730         }
731       }
732       mysensgroup->Polyline (Vtx);
733     }
734     //==============
735     // Wire
736     //=============
737     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
738     {
739         Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
740         Select3D_SensitiveEntitySequence EntitySeq;
741         aWire->GetEdges (EntitySeq);
742
743       for (int i = 1; i <= EntitySeq.Length(); i++)
744       {
745         Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i));
746
747         //Segment
748         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
749         {
750           Graphic3d_Array1OfVertex Vtx (1, 2);
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           Vtx.SetValue (1, Graphic3d_Vertex (P1.X(), P1.Y(), P1.Z()));
759           Vtx.SetValue (2, Graphic3d_Vertex (P2.X(), P2.Y(), P2.Z()));
760           mysensgroup->Polyline (Vtx);
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             Graphic3d_Array1OfVertex Vtx (1, 4);
773             gp_Pnt ThePts[3] =
774             {
775               gp_Pnt (C->GetPoint3d (II).XYZ()),
776               gp_Pnt (C->GetPoint3d (++II).XYZ()),
777               gp_Pnt (C->GetPoint3d (++II).XYZ())
778             };
779
780             if (hasloc)
781             {
782               for (Standard_Integer jj = 0; jj <= 2; jj++)
783                 ThePts[jj].Transform (theloc.Transformation());
784             }
785
786             Vtx.SetValue (1, Graphic3d_Vertex (ThePts[0].X(), ThePts[0].Y(), ThePts[0].Z()));
787             Vtx.SetValue (2, Graphic3d_Vertex (ThePts[1].X(), ThePts[1].Y(), ThePts[1].Z()));
788             Vtx.SetValue (3, Graphic3d_Vertex (ThePts[2].X(), ThePts[2].Y(), ThePts[2].Z()));
789             Vtx.SetValue (4, Graphic3d_Vertex (ThePts[0].X(), ThePts[0].Y(), ThePts[0].Z()));
790
791             mysensgroup->Polyline (Vtx);
792           }
793         }
794
795         //curve
796         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
797         {
798           Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
799           Handle(TColgp_HArray1OfPnt) TheHPts;
800           aCurve->Points3D (TheHPts);
801           const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
802           Graphic3d_Array1OfVertex Vtx (ThePts.Lower(), ThePts.Upper());
803           for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
804           {
805             if (hasloc)
806             {
807               gp_Pnt ptrans (ThePts (I).Transformed (theloc.Transformation()).XYZ());
808               Vtx.SetValue (I, Graphic3d_Vertex (ptrans.X(), ptrans.Y(), ptrans.Z()));
809             }
810             else
811             {
812               Vtx.SetValue (I, Graphic3d_Vertex (ThePts (I).X(), ThePts (I).Y(), ThePts (I).Z()));
813             }
814           }
815           mysensgroup->Polyline (Vtx);
816         }
817       }
818     }
819     //==============
820     // Segment
821     //=============
822     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
823     {
824       Graphic3d_Array1OfVertex Vtx (1,2);
825       gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
826       gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
827       if (hasloc)
828       {
829         P1.Transform (theloc.Transformation());
830         P2.Transform (theloc.Transformation());
831       }
832       Vtx.SetValue (1, Graphic3d_Vertex (P1.X(), P1.Y(), P1.Z()));
833       Vtx.SetValue (2, Graphic3d_Vertex (P2.X(), P2.Y(), P2.Z()));
834       mysensgroup->Polyline (Vtx);
835     }
836     //==============
837     // Circle
838     //=============
839     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
840     {
841       Handle(Select3D_SensitiveCircle) C = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
842       Standard_Integer Lo, Up;
843       C->ArrayBounds (Lo, Up);
844       Standard_Integer II = Lo;
845       while (II <= Up - 2)
846       {
847         Graphic3d_Array1OfVertex Vtx (1,4);
848         gp_Pnt ThePts[3] =
849         {
850           gp_Pnt (C->GetPoint3d (II).XYZ()),
851           gp_Pnt (C->GetPoint3d (++II).XYZ()),
852           gp_Pnt (C->GetPoint3d (++II).XYZ())
853         };
854
855         if (hasloc)
856         {
857           for (Standard_Integer jj = 0; jj <= 2; jj++)
858             ThePts[jj].Transform (theloc.Transformation());
859         }
860
861         Vtx.SetValue (1, Graphic3d_Vertex (ThePts[0].X(), ThePts[0].Y(), ThePts[0].Z()));
862         Vtx.SetValue (2, Graphic3d_Vertex (ThePts[1].X(), ThePts[1].Y(), ThePts[1].Z()));
863         Vtx.SetValue (3, Graphic3d_Vertex (ThePts[2].X(), ThePts[2].Y(), ThePts[2].Z()));
864         Vtx.SetValue (4, Graphic3d_Vertex (ThePts[0].X(), ThePts[0].Y(), ThePts[0].Z()));
865
866         mysensgroup->Polyline (Vtx);
867       }
868     }
869     //==============
870     // Point
871     //=============
872     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
873     {
874       gp_Pnt P = hasloc ?
875         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
876         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation());
877       Graphic3d_Vertex V (P.X(), P.Y(), P.Z());
878       mysensgroup->Marker (V);
879     }
880     //============================================================
881     // Triangulation : On met un petit offset ves l'interieur...
882     //==========================================================
883     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
884     {
885       const Handle(Poly_Triangulation)& PT =
886         (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->Triangulation();
887
888       const Poly_Array1OfTriangle& triangles = PT->Triangles();
889       const TColgp_Array1OfPnt& Nodes = PT->Nodes();
890       //      gp_Pnt P1, P2, P3;
891       Standard_Integer n[3];
892       Graphic3d_Array1OfVertex AV (1, 4);
893
894       TopLoc_Location iloc, bidloc;
895       if ((*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->HasInitLocation())
896         bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation();
897
898       if (bidloc.IsIdentity())
899         iloc = theloc;
900       else
901         iloc = theloc * bidloc;
902
903       Standard_Integer i;
904       for (i = 1; i <= PT->NbTriangles(); i++)
905       {
906         triangles (i).Get (n[0], n[1], n[2]);
907         gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
908         gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
909         gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
910         gp_XYZ V1 (P1.XYZ());
911         gp_XYZ V2 (P2.XYZ());
912         gp_XYZ V3 (P3.XYZ());
913         gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
914
915         V1 -= CDG; V2 -= CDG; V3 -= CDG;
916
917         V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
918         V1 += CDG; V2 += CDG; V3 += CDG;
919         AV.SetValue (1, Graphic3d_Vertex (V1.X(), V1.Y(), V1.Z()));
920         AV.SetValue (2, Graphic3d_Vertex (V2.X(), V2.Y(), V2.Z()));
921         AV.SetValue (3, Graphic3d_Vertex (V3.X(), V3.Y(), V3.Z()));
922         AV.SetValue (4, Graphic3d_Vertex (V1.X(), V1.Y(), V1.Z()));
923         mysensgroup->Polyline (AV);
924       }
925
926       // recherche des bords libres...
927
928       Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
929       TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
930       Poly_Connect pc (PT);
931       Standard_Integer t[3];
932       Standard_Integer j;
933       Standard_Integer fr (1);
934       for (i = 1; i <= PT->NbTriangles(); i++)
935       {
936         pc.Triangles (i, t[0], t[1], t[2]);
937         triangles (i).Get (n[0], n[1], n[2]);
938         for (j = 0; j < 3; j++)
939         {
940           Standard_Integer k = (j + 1) % 3;
941           if (t[j] == 0)
942           {
943             FreeE (fr)    = n[j];
944             FreeE (fr + 1)= n[k];
945             fr += 2;
946           }
947         }
948       }
949       Standard_Integer Node1, Node2;
950       mysensgroup->SetPrimitivesAspect (
951         new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
952       for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
953       {
954         Node1 = FreeE (ifri);
955         Node2 = FreeE (ifri + 1);
956         Graphic3d_Array1OfVertex FE (1, 2);
957         gp_Pnt pe1 (Nodes (Node1).Transformed (iloc)), pe2 (Nodes (Node2).Transformed (iloc));
958         FE.SetValue (1,Graphic3d_Vertex (pe1.X(), pe1.Y(), pe1.Z()));
959         FE.SetValue (2,Graphic3d_Vertex (pe2.X(), pe2.Y(), pe2.Z()));
960         mysensgroup->Polyline (FE);
961       }
962
963       mysensgroup->SetPrimitivesAspect (
964         new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
965     }
966     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
967     {
968       Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
969       gp_Pnt P1, P2, P3, CDG;
970       Graphic3d_Array1OfVertex AV (1, 4);
971       Str->Points3D (P1, P2, P3);
972       CDG = Str->Center3D();
973
974       gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
975       gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
976       gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
977
978       V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
979       V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
980       AV.SetValue (1, Graphic3d_Vertex (V1.X(), V1.Y(), V1.Z()));
981       AV.SetValue (2, Graphic3d_Vertex (V2.X(), V2.Y(), V2.Z()));
982       AV.SetValue (3, Graphic3d_Vertex (V3.X(), V3.Y(), V3.Z()));
983       AV.SetValue (4, Graphic3d_Vertex (V1.X(), V1.Y(), V1.Z()));
984       mysensgroup->Polyline (AV);
985     }
986   }
987 }
988
989 //=======================================================================
990 //function : ComputeAreaPrs
991 //purpose  :
992 //=======================================================================
993
994 void StdSelect_ViewerSelector3d::
995 ComputeAreasPrs (const Handle(SelectMgr_Selection)& Sel)
996 {
997   // Select3D_Projector myprj = StdSelect::GetProjector (aView);
998   Graphic3d_Array1OfVertex Av1 (1, 5);
999   Standard_Real xmin, ymin, xmax, ymax;
1000   gp_Pnt Pbid;
1001   SelectBasics_ListOfBox2d BoxList;
1002
1003   for (Sel->Init(); Sel->More(); Sel->Next())
1004   {
1005     Sel->Sensitive()->Areas (BoxList);
1006     for (SelectBasics_ListIteratorOfListOfBox2d itb (BoxList); itb.More(); itb.Next())
1007     {
1008       itb.Value().Get (xmin, ymin, xmax, ymax);
1009
1010       Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
1011       myprj.Transform (Pbid, myprj.InvertedTransformation());
1012       Av1.SetValue (1, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
1013
1014       Pbid.SetCoord (xmax + mytolerance, ymin - mytolerance, 0.0);
1015       myprj.Transform (Pbid, myprj.InvertedTransformation());
1016       Av1.SetValue (2, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
1017
1018       Pbid.SetCoord (xmax + mytolerance, ymax + mytolerance, 0.0);
1019       myprj.Transform (Pbid, myprj.InvertedTransformation());
1020       Av1.SetValue (3, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
1021
1022       Pbid.SetCoord (xmin - mytolerance, ymax + mytolerance, 0.0);
1023       myprj.Transform (Pbid, myprj.InvertedTransformation());
1024       Av1.SetValue (4, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
1025
1026       Pbid.SetCoord (xmin - mytolerance, ymin - mytolerance, 0.0);
1027       myprj.Transform (Pbid, myprj.InvertedTransformation());
1028       Av1.SetValue (5, Graphic3d_Vertex (Pbid.X(), Pbid.Y(), Pbid.Z()));
1029
1030       myareagroup->Polyline (Av1);
1031     }
1032   }
1033 }
1034
1035 //=======================================================================
1036 //function : ReactivateProjector
1037 //purpose  :
1038 //=======================================================================
1039 void StdSelect_ViewerSelector3d::ReactivateProjector()
1040 {
1041   Handle(SelectBasics_SensitiveEntity) BS;
1042   for (SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive it (myentities); it.More(); it.Next())
1043   {
1044     BS = it.Value();
1045     if (BS->Is3D())
1046     {
1047       (*((Handle(Select3D_SensitiveEntity)*) &BS))->SetLastPrj (myprj);
1048     }
1049   }
1050 }