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