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