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