0032387: Visualization - use interface of ray-picking for selection/highlighting...
[occt.git] / src / SelectMgr / SelectMgr_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 <SelectMgr_ViewerSelector3d.hxx>
18
19 #include <Graphic3d_SequenceOfHClipPlane.hxx>
20 #include <Graphic3d_Structure.hxx>
21 #include <math_BullardGenerator.hxx>
22 #include <Quantity_ColorHasher.hxx>
23 #include <TColgp_Array1OfPnt2d.hxx>
24 #include <SelectMgr.hxx>
25 #include <SelectMgr_EntityOwner.hxx>
26 #include <SelectMgr_SelectableObject.hxx>
27 #include <SelectMgr_Selection.hxx>
28 #include <SelectMgr_SelectionImageFiller.hxx>
29 #include <V3d_View.hxx>
30 #include <V3d_Viewer.hxx>
31
32 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector3d, SelectMgr_ViewerSelector)
33
34 //=======================================================================
35 // Function : Constructor
36 // Purpose  :
37 //=======================================================================
38 SelectMgr_ViewerSelector3d::SelectMgr_ViewerSelector3d()
39 {
40   //
41 }
42
43 //=======================================================================
44 // Function: Pick
45 // Purpose :
46 //=======================================================================
47 void SelectMgr_ViewerSelector3d::Pick (const Standard_Integer theXPix,
48                                        const Standard_Integer theYPix,
49                                        const Handle(V3d_View)& theView)
50 {
51   updateZLayers (theView);
52
53   gp_Pnt2d aMousePos (static_cast<Standard_Real> (theXPix),
54                       static_cast<Standard_Real> (theYPix));
55   mySelectingVolumeMgr.InitPointSelectingVolume (aMousePos);
56
57   mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
58   mySelectingVolumeMgr.SetCamera (theView->Camera());
59   Standard_Integer aWidth = 0, aHeight = 0;
60   theView->Window()->Size (aWidth, aHeight);
61   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
62
63   mySelectingVolumeMgr.BuildSelectingVolume();
64   mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
65
66   TraverseSensitives();
67 }
68
69 //=======================================================================
70 // Function: Pick
71 // Purpose :
72 //=======================================================================
73 void SelectMgr_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
74                                        const Standard_Integer theYPMin,
75                                        const Standard_Integer theXPMax,
76                                        const Standard_Integer theYPMax,
77                                        const Handle(V3d_View)& theView)
78 {
79   updateZLayers (theView);
80
81   gp_Pnt2d aMinMousePos (static_cast<Standard_Real> (theXPMin),
82                          static_cast<Standard_Real> (theYPMin));
83   gp_Pnt2d aMaxMousePos (static_cast<Standard_Real> (theXPMax),
84                          static_cast<Standard_Real> (theYPMax));
85   mySelectingVolumeMgr.InitBoxSelectingVolume (aMinMousePos,
86                                                aMaxMousePos);
87
88   mySelectingVolumeMgr.SetCamera (theView->Camera());
89   Standard_Integer aWidth = 0, aHeight = 0;
90   theView->Window()->Size (aWidth, aHeight);
91   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
92
93   mySelectingVolumeMgr.BuildSelectingVolume();
94   mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
95   TraverseSensitives();
96 }
97
98 //=======================================================================
99 // Function: Pick
100 // Purpose : Selection using a polyline
101 //=======================================================================
102 void SelectMgr_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
103                                        const Handle(V3d_View)& theView)
104 {
105   updateZLayers (theView);
106
107   mySelectingVolumeMgr.InitPolylineSelectingVolume (thePolyline);
108   mySelectingVolumeMgr.SetCamera (theView->Camera());
109   Standard_Integer aWidth = 0, aHeight = 0;
110   theView->Window()->Size (aWidth, aHeight);
111   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
112   mySelectingVolumeMgr.BuildSelectingVolume();
113   mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
114
115   TraverseSensitives();
116 }
117
118 //=======================================================================
119 // Function: Pick
120 // Purpose :
121 //=======================================================================
122 void SelectMgr_ViewerSelector3d::Pick (const gp_Ax1& theAxis,
123                                        const Handle(V3d_View)& theView)
124 {
125   updateZLayers (theView);
126
127   mySelectingVolumeMgr.InitAxisSelectingVolume (theAxis);
128   mySelectingVolumeMgr.BuildSelectingVolume();
129   mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
130
131   TraverseSensitives();
132 }
133
134 //=======================================================================
135 // Function: DisplaySensitive.
136 // Purpose : Display active primitives.
137 //=======================================================================
138 void SelectMgr_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView)
139 {
140   for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
141   {
142     Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
143     const Handle (SelectMgr_SelectableObject)& anObj = aSelectableIt.Value();
144     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
145     {
146       if (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated)
147       {
148         SelectMgr::ComputeSensitivePrs (aStruct, aSelIter.Value(), anObj->Transformation(), anObj->TransformPersistence());
149       }
150     }
151
152     myStructs.Append (aStruct);
153   }
154
155   for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
156   {
157     Handle(Graphic3d_Structure)& aStruct = aStructIter.ChangeValue();
158     aStruct->SetDisplayPriority (10);
159     aStruct->Display();
160   }
161
162   theView->Update();
163 }
164
165 //=======================================================================
166 // Function: ClearSensitive
167 // Purpose :
168 //=======================================================================
169 void SelectMgr_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView)
170 {
171   for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
172   {
173     const Handle(Graphic3d_Structure)& aPrs = aStructIter.ChangeValue();
174     aPrs->Erase();
175     aPrs->Clear();
176     aPrs->Remove();
177   }
178   myStructs.Clear();
179
180   if (!theView.IsNull())
181   {
182     theView->Update();
183   }
184 }
185
186 //=======================================================================
187 //function : DisplaySenstive
188 //purpose  :
189 //=======================================================================
190 void SelectMgr_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
191                                                    const gp_Trsf& theTrsf,
192                                                    const Handle(V3d_View)& theView,
193                                                    const Standard_Boolean theToClearOthers)
194 {
195   if (theToClearOthers)
196   {
197     ClearSensitive (theView);
198   }
199
200   Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
201
202   SelectMgr::ComputeSensitivePrs (aStruct, theSel, theTrsf, Handle(Graphic3d_TransformPers)());
203
204   myStructs.Append (aStruct);
205   myStructs.Last()->SetDisplayPriority (10);
206   myStructs.Last()->Display();
207
208   theView->Update();
209 }
210
211 //=======================================================================
212 // Function: updateZLayers
213 // Purpose :
214 //=======================================================================
215 void SelectMgr_ViewerSelector3d::updateZLayers (const Handle(V3d_View)& theView)
216 {
217   myZLayerOrderMap.Clear();
218   TColStd_SequenceOfInteger aZLayers;
219   theView->Viewer()->GetAllZLayers (aZLayers);
220   Standard_Integer aPos = 0;
221   Standard_Boolean isPrevDepthWrite = true;
222   for (TColStd_SequenceOfInteger::Iterator aLayerIter (aZLayers); aLayerIter.More(); aLayerIter.Next())
223   {
224     Graphic3d_ZLayerSettings aSettings = theView->Viewer()->ZLayerSettings (aLayerIter.Value());
225     if (aSettings.ToClearDepth()
226      || isPrevDepthWrite != aSettings.ToEnableDepthWrite())
227     {
228       ++aPos;
229     }
230     isPrevDepthWrite = aSettings.ToEnableDepthWrite();
231     myZLayerOrderMap.Bind (aLayerIter.Value(), aPos);
232   }
233 }
234
235 //=======================================================================
236 //function : ToPixMap
237 //purpose  :
238 //=======================================================================
239 Standard_Boolean SelectMgr_ViewerSelector3d::ToPixMap (Image_PixMap&                        theImage,
240                                                        const Handle(V3d_View)&              theView,
241                                                        const StdSelect_TypeOfSelectionImage theType,
242                                                        const Standard_Integer               thePickedIndex)
243 {
244   if (theImage.IsEmpty())
245   {
246     throw Standard_ProgramError("SelectMgr_ViewerSelector3d::ToPixMap() has been called with empty image");
247   }
248
249   Handle(SelectMgr_SelectionImageFiller) aFiller = SelectMgr_SelectionImageFiller::CreateFiller (theImage, this, theType);
250   if (aFiller.IsNull())
251   {
252     return Standard_False;
253   }
254
255   const Standard_Integer aSizeX = static_cast<Standard_Integer> (theImage.SizeX());
256   const Standard_Integer aSizeY = static_cast<Standard_Integer> (theImage.SizeY());
257   for (Standard_Integer aRowIter = 0; aRowIter < aSizeY; ++aRowIter)
258   {
259     for (Standard_Integer aColIter = 0; aColIter < aSizeX; ++aColIter)
260     {
261       Pick (aColIter, aRowIter, theView);
262       aFiller->Fill (aColIter, aRowIter, thePickedIndex);
263     }
264   }
265   aFiller->Flush();
266   return Standard_True;
267 }
268
269 //=======================================================================
270 //function : DumpJson
271 //purpose  :
272 //=======================================================================
273 void SelectMgr_ViewerSelector3d::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
274 {
275   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
276
277   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myStructs.Length())
278   for (Graphic3d_SequenceOfStructure::Iterator aStructsIt (myStructs); aStructsIt.More(); aStructsIt.Next())
279   {
280     const Handle(Graphic3d_Structure)& aStructure = aStructsIt.Value();
281     OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, aStructure)
282   }
283 }