0024023: Revamp the OCCT Handle -- downcast (automatic)
[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.hxx>
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_Group.hxx>
31 #include <Graphic3d_SequenceOfHClipPlane.hxx>
32 #include <Graphic3d_Structure.hxx>
33 #include <SelectMgr_SelectableObject.hxx>
34 #include <TColgp_HArray1OfPnt.hxx>
35 #include <TColgp_Array1OfPnt.hxx>
36 #include <TColgp_Array1OfPnt2d.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_SensitiveBox.hxx>
47 #include <SelectMgr_Selection.hxx>
48 #include <SelectMgr_EntityOwner.hxx>
49
50 #include <Aspect_Grid.hxx>
51 #include <Aspect_TypeOfMarker.hxx>
52 #include <Aspect_Window.hxx>
53 #include <Graphic3d_AspectMarker3d.hxx>
54 #include <Graphic3d_ArrayOfPoints.hxx>
55 #include <Poly_Connect.hxx>
56 #include <TColStd_HArray1OfInteger.hxx>
57
58 #include <Poly_Array1OfTriangle.hxx>
59 #include <Poly_Triangulation.hxx>
60 #include <OSD_Environment.hxx>
61 #include <V3d.hxx>
62 #include <V3d_View.hxx>
63 #include <V3d_Viewer.hxx>
64 #include <TColgp_SequenceOfPnt.hxx>
65
66 #include <OSD_Timer.hxx>
67
68
69 static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
70 {
71   Standard_Integer nFree = 0;
72   Poly_Connect pc(Trg);
73   Standard_Integer t[3];
74   Standard_Integer i, j;
75   for (i = 1; i <= Trg->NbTriangles(); i++)
76   {
77     pc.Triangles (i, t[0], t[1], t[2]);
78     for (j = 0; j < 3; j++)
79       if (t[j] == 0) nFree++;
80   }
81   return nFree;
82 }
83
84 //=======================================================================
85 // Function : Constructor
86 // Purpose  :
87 //=======================================================================
88 StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() {}
89
90 //=======================================================================
91 // Function: SetPixelTolerance
92 // Purpose :
93 //=======================================================================
94 void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Real theTolerance)
95 {
96   if (mytolerance != theTolerance)
97   {
98     if (theTolerance < 0.0)
99       myTolerances.ResetDefaults();
100     else
101       myTolerances.SetCustomTolerance (theTolerance);
102     mytolerance = myTolerances.Tolerance();
103     myToUpdateTolerance = Standard_True;
104   }
105 }
106
107 //=======================================================================
108 // Function: Pick
109 // Purpose :
110 //=======================================================================
111 void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
112                                        const Standard_Integer theYPix,
113                                        const Handle(V3d_View)& theView)
114 {
115   SetClipping (theView->GetClipPlanes());
116
117   if(myToUpdateTolerance)
118   {
119     mySelectingVolumeMgr.SetPixelTolerance (mytolerance);
120     myToUpdateTolerance = Standard_False;
121   }
122
123   mySelectingVolumeMgr.SetCamera (theView->Camera());
124   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Point);
125   Standard_Integer aWidth = 0, aHeight = 0;
126   theView->Window()->Size (aWidth, aHeight);
127   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
128   gp_Pnt2d aMousePos (static_cast<Standard_Real> (theXPix),
129                       static_cast<Standard_Real> (theYPix));
130   mySelectingVolumeMgr.BuildSelectingVolume (aMousePos);
131
132   TraverseSensitives();
133 }
134
135 //=======================================================================
136 // Function: Pick
137 // Purpose :
138 //=======================================================================
139 void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
140                                        const Standard_Integer theYPMin,
141                                        const Standard_Integer theXPMax,
142                                        const Standard_Integer theYPMax,
143                                        const Handle(V3d_View)& theView)
144 {
145   mySelectingVolumeMgr.SetCamera (theView->Camera());
146   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Box);
147   Standard_Integer aWidth = 0, aHeight = 0;
148   theView->Window()->Size (aWidth, aHeight);
149   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
150   gp_Pnt2d aMinMousePos (static_cast<Standard_Real> (theXPMin),
151                          static_cast<Standard_Real> (theYPMin));
152   gp_Pnt2d aMaxMousePos (static_cast<Standard_Real> (theXPMax),
153                          static_cast<Standard_Real> (theYPMax));
154   mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos,
155                                              aMaxMousePos);
156
157   TraverseSensitives();
158 }
159
160 //=======================================================================
161 // Function: Pick
162 // Purpose : Selection using a polyline
163 //=======================================================================
164 void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
165                                        const Handle(V3d_View)& theView)
166 {
167   mySelectingVolumeMgr.SetCamera (theView->Camera());
168   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Polyline);
169   Standard_Integer aWidth = 0, aHeight = 0;
170   theView->Window()->Size (aWidth, aHeight);
171   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
172   mySelectingVolumeMgr.BuildSelectingVolume (thePolyline);
173
174   TraverseSensitives();
175 }
176
177 //=======================================================================
178 // Function: DisplaySensitive.
179 // Purpose : Display active primitives.
180 //=======================================================================
181 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView)
182 {
183   // Preparation des structures
184   if (mystruct.IsNull())
185   {
186     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
187   }
188
189   if (mysensgroup.IsNull())
190   {
191     mysensgroup = mystruct->NewGroup();
192   }
193
194   Quantity_Color aColor (Quantity_NOC_INDIANRED3);
195   Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
196     new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
197
198   mysensgroup->SetPrimitivesAspect (aMarkerAspect);
199   mysensgroup->SetPrimitivesAspect (
200     new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
201
202   for (Standard_Integer anObjectIdx = 0; anObjectIdx <= mySelectableObjects->Size(); ++anObjectIdx)
203   {
204     const Handle (SelectMgr_SelectableObject)& anObject = mySelectableObjects->GetObjectById (anObjectIdx);
205     for (anObject->Init(); anObject->More(); anObject->Next())
206     {
207       if (anObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
208       {
209         ComputeSensitivePrs (anObject->CurrentSelection(), anObject->Transformation());
210       }
211     }
212   }
213
214   mysensgroup->Structure()->SetDisplayPriority (10);
215   mystruct->Display();
216
217   theView->Update();
218 }
219
220 //=======================================================================
221 // Function: ClearSensitive
222 // Purpose :
223 //=======================================================================
224 void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView)
225 {
226   if (mysensgroup.IsNull())
227   {
228     return;
229   }
230
231   mysensgroup->Clear();
232
233   if (theView.IsNull())
234   {
235     return;
236   }
237
238   theView->Update();
239 }
240
241 //=======================================================================
242 //function : DisplaySenstive
243 //purpose  :
244 //=======================================================================
245 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
246                                                    const gp_Trsf& theTrsf,
247                                                    const Handle(V3d_View)& theView,
248                                                    const Standard_Boolean theToClearOthers)
249 {
250   if (mystruct.IsNull())
251   {
252     mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer());
253   }
254
255   if (mysensgroup.IsNull())
256   {
257     mysensgroup = mystruct->NewGroup();
258     Quantity_Color aColor (Quantity_NOC_INDIANRED3);
259     Handle(Graphic3d_AspectMarker3d) aMarkerAspect =
260       new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
261
262     mysensgroup-> SetPrimitivesAspect (aMarkerAspect);
263     mysensgroup->SetPrimitivesAspect (
264       new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
265   }
266
267   if (theToClearOthers)
268   {
269     mysensgroup->Clear();
270   }
271
272   ComputeSensitivePrs (theSel, theTrsf);
273
274   mystruct->SetDisplayPriority (10);
275   mystruct->Display();
276
277   theView->Update();
278 }
279
280 //=======================================================================
281 //function : ComputeSensitivePrs
282 //purpose  :
283 //=======================================================================
284 void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel,
285                                                       const gp_Trsf& theLoc)
286 {
287   TColgp_SequenceOfPnt aSeqLines, aSeqFree;
288   TColStd_SequenceOfInteger aSeqBnds;
289
290   for (theSel->Init(); theSel->More(); theSel->Next())
291   {
292     Handle(Select3D_SensitiveEntity) Ent =
293       Handle(Select3D_SensitiveEntity)::DownCast(theSel->Sensitive()->BaseSensitive());
294     const Standard_Boolean hasloc = theLoc.Form() != gp_Identity;
295
296     //==============
297     // Box
298     //=============
299
300     if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
301     {
302       const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
303       Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
304       B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
305       Standard_Integer i;
306       gp_Pnt theboxpoint[8] =
307       {
308         gp_Pnt(xmin,ymin,zmin),
309         gp_Pnt(xmax,ymin,zmin),
310         gp_Pnt(xmax,ymax,zmin),
311         gp_Pnt(xmin,ymax,zmin),
312         gp_Pnt(xmin,ymin,zmax),
313         gp_Pnt(xmax,ymin,zmax),
314         gp_Pnt(xmax,ymax,zmax),
315         gp_Pnt(xmin,ymax,zmax)
316       };
317       if(hasloc)
318       {
319         for (i = 0; i <= 7; i++)
320           theboxpoint[i].Transform (theLoc);
321       }
322
323       aSeqBnds.Append(5);
324       for (i = 0; i < 4; i++)
325         aSeqLines.Append(theboxpoint[i]);
326       aSeqLines.Append(theboxpoint[0]);
327
328       aSeqBnds.Append(5);
329       for (i = 4; i < 8; i++)
330         aSeqLines.Append(theboxpoint[i]);
331       aSeqLines.Append(theboxpoint[4]);
332
333       for (i = 0; i < 4; i++)
334       {
335         aSeqBnds.Append(2);
336         aSeqLines.Append(theboxpoint[i]);
337         aSeqLines.Append(theboxpoint[i+4]);
338       }
339     }
340     //==============
341     // Face
342     //=============
343     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
344     {
345       Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
346       Handle(TColgp_HArray1OfPnt) TheHPts;
347       aFace->GetPoints(TheHPts);
348       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
349
350       aSeqBnds.Append(ThePts.Length());
351       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
352       {
353         if (hasloc)
354           aSeqLines.Append(ThePts(I).Transformed (theLoc));
355         else
356           aSeqLines.Append(ThePts(I));
357       }
358     }
359     //==============
360     // Curve
361     //=============
362     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
363     {
364       Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
365       Handle(TColgp_HArray1OfPnt) TheHPts;
366       aCurve->Points3D(TheHPts);
367       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
368
369       aSeqBnds.Append(ThePts.Length());
370       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
371       {
372         if (hasloc)
373           aSeqLines.Append(ThePts(I).Transformed (theLoc));
374         else
375           aSeqLines.Append(ThePts(I));
376       }
377     }
378     //==============
379     // Wire
380     //=============
381     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
382     {
383       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
384       const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& anEntities = aWire->GetEdges();
385
386       for (int i = 0; i < anEntities.Length(); i++)
387       {
388         Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(anEntities.Value(i));
389
390         //Segment
391         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
392         {
393           gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
394           gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
395           if (hasloc)
396           {
397             P1.Transform(theLoc);
398             P2.Transform(theLoc);
399           }
400           aSeqBnds.Append(2);
401           aSeqLines.Append(P1);
402           aSeqLines.Append(P2);
403         }
404
405         //circle
406         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
407         {
408           Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
409           Standard_Integer aFrom, aTo;
410           aCircle->ArrayBounds (aFrom, aTo);
411           aTo -= 2;
412           for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
413           {
414             gp_Pnt aPnts[3] =
415             {
416               gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
417               gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
418               gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
419             };
420
421             if (hasloc)
422             {
423               aPnts[0].Transform (theLoc);
424               aPnts[1].Transform (theLoc);
425               aPnts[2].Transform (theLoc);
426             }
427
428             aSeqBnds.Append (4);
429             aSeqLines.Append (aPnts[0]);
430             aSeqLines.Append (aPnts[1]);
431             aSeqLines.Append (aPnts[2]);
432             aSeqLines.Append (aPnts[0]);
433           }
434         }
435
436         //curve
437         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
438         {
439           Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
440           Handle(TColgp_HArray1OfPnt) TheHPts;
441           aCurve->Points3D (TheHPts);
442           const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
443
444           aSeqBnds.Append(ThePts.Length());
445           for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
446           {
447             if (hasloc)
448               aSeqLines.Append(ThePts(I).Transformed (theLoc));
449             else
450               aSeqLines.Append(ThePts(I));
451           }
452         }
453       }
454     }
455     //==============
456     // Segment
457     //=============
458     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
459     {
460       gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
461       gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
462       if (hasloc)
463       {
464         P1.Transform (theLoc);
465         P2.Transform (theLoc);
466       }
467       aSeqBnds.Append(2);
468       aSeqLines.Append(P1);
469       aSeqLines.Append(P2);
470     }
471     //==============
472     // Circle
473     //=============
474     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
475     {
476       Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
477       Standard_Integer aFrom, aTo;
478       aCircle->ArrayBounds (aFrom, aTo);
479       aTo -= 2;
480       for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
481       {
482         gp_Pnt aPnts[3] =
483         {
484           gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
485           gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
486           gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
487         };
488
489         if (hasloc)
490         {
491           aPnts[0].Transform (theLoc);
492           aPnts[1].Transform (theLoc);
493           aPnts[2].Transform (theLoc);
494         }
495
496         aSeqBnds.Append (4);
497         aSeqLines.Append (aPnts[0]);
498         aSeqLines.Append (aPnts[1]);
499         aSeqLines.Append (aPnts[2]);
500         aSeqLines.Append (aPnts[0]);
501       }
502     }
503     //==============
504     // Point
505     //=============
506     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
507     {
508       gp_Pnt P = hasloc ?
509         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
510         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theLoc);
511       Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
512       anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
513       mysensgroup->AddPrimitiveArray (anArrayOfPoints);
514     }
515     //============================================================
516     // Triangulation : On met un petit offset ves l'interieur...
517     //==========================================================
518     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
519     {
520       Handle(Poly_Triangulation) PT (Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->Triangulation());
521
522       const Poly_Array1OfTriangle& triangles = PT->Triangles();
523       const TColgp_Array1OfPnt& Nodes = PT->Nodes();
524       Standard_Integer n[3];
525
526       TopLoc_Location iloc, bidloc;
527       if (Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->HasInitLocation())
528         bidloc = Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->GetInitLocation();
529
530       if (bidloc.IsIdentity())
531         iloc = theLoc;
532       else
533         iloc = theLoc * bidloc;
534
535       Standard_Integer i;
536       for (i = 1; i <= PT->NbTriangles(); i++)
537       {
538         triangles (i).Get (n[0], n[1], n[2]);
539         gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
540         gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
541         gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
542         gp_XYZ V1 (P1.XYZ());
543         gp_XYZ V2 (P2.XYZ());
544         gp_XYZ V3 (P3.XYZ());
545         gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
546         V1 -= CDG; V2 -= CDG; V3 -= CDG;
547         V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
548         V1 += CDG; V2 += CDG; V3 += CDG;
549
550         aSeqBnds.Append(4);
551         aSeqLines.Append(gp_Pnt(V1));
552         aSeqLines.Append(gp_Pnt(V2));
553         aSeqLines.Append(gp_Pnt(V3));
554         aSeqLines.Append(gp_Pnt(V1));
555       }
556
557       // recherche des bords libres...
558
559       Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
560       TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
561       Poly_Connect pc (PT);
562       Standard_Integer t[3];
563       Standard_Integer j;
564       Standard_Integer fr (1);
565       for (i = 1; i <= PT->NbTriangles(); i++)
566       {
567         pc.Triangles (i, t[0], t[1], t[2]);
568         triangles (i).Get (n[0], n[1], n[2]);
569         for (j = 0; j < 3; j++)
570         {
571           Standard_Integer k = (j + 1) % 3;
572           if (t[j] == 0)
573           {
574             FreeE (fr)    = n[j];
575             FreeE (fr + 1)= n[k];
576             fr += 2;
577           }
578         }
579       }
580       for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
581       {
582         gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
583         aSeqFree.Append(pe1);
584         aSeqFree.Append(pe2);
585       }
586     }
587     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
588     {
589       Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
590       gp_Pnt P1, P2, P3;
591       Str->Points3D (P1, P2, P3);
592       gp_Pnt CDG = Str->Center3D();
593
594       gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
595       gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
596       gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
597       V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
598       V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
599
600       aSeqBnds.Append(4);
601       aSeqLines.Append(gp_Pnt(V1));
602       aSeqLines.Append(gp_Pnt(V2));
603       aSeqLines.Append(gp_Pnt(V3));
604       aSeqLines.Append(gp_Pnt(V1));
605     }
606   }
607
608   Standard_Integer i;
609
610   if (aSeqLines.Length())
611   {
612     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
613     for (i = 1; i <= aSeqLines.Length(); i++)
614       aPrims->AddVertex(aSeqLines(i));
615     for (i = 1; i <= aSeqBnds.Length(); i++)
616       aPrims->AddBound(aSeqBnds(i));
617     myareagroup->AddPrimitiveArray(aPrims);
618   }
619
620   if (aSeqFree.Length())
621   {
622     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
623     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
624     for (i = 1; i <= aSeqFree.Length(); i++)
625     {
626       aPrims->AddBound(2);
627       aPrims->AddVertex(aSeqLines(i++));
628       aPrims->AddVertex(aSeqLines(i));
629     }
630     mysensgroup->AddPrimitiveArray(aPrims);
631     mysensgroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
632   }
633 }
634
635 //=======================================================================
636 //function : SetClipping
637 //purpose  :
638 //=======================================================================
639 void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
640 {
641   myClipPlanes = thePlanes;
642 }
643
644 //=======================================================================
645 //function : HasDepthClipping
646 //purpose  :
647 //=======================================================================
648 Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
649 {
650   if (!theOwner->HasSelectable())
651   {
652     return Standard_False;
653   }
654
655   const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
656   return (aSelectable->GetClipPlanes().Size() > 0);
657 }
658
659 //=======================================================================
660 //function : ResetSelectionActivationStatus
661 //purpose  : Marks all sensitive entities, stored in viewer selector,
662 //           as inactive for selection
663 //=======================================================================
664 void StdSelect_ViewerSelector3d::ResetSelectionActivationStatus()
665 {
666   resetSelectionActivationStatus();
667 }
668
669 //=======================================================================
670 //function : AllowOverlapDetection
671 //purpose  : Sets the detection type: if theIsToAllow is false,
672 //           only fully included sensitives will be detected, otherwise
673 //           the algorithm will mark both included and overlapped entities
674 //           as matched
675 //=======================================================================
676 void StdSelect_ViewerSelector3d::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
677 {
678   mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
679 }