0026195: Visualization - optimize selection algorithms
[occt.git] / src / SelectMgr / SelectMgr_SelectingVolumeManager.cxx
CommitLineData
f751596e 1// Created on: 2014-05-22
2// Created by: Varvara POSKONINA
3// Copyright (c) 2005-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <SelectMgr_SelectingVolumeManager.hxx>
17
18//=======================================================================
19// function : SelectMgr_SelectingVolumeManager
20// purpose : Creates instances of all available selecting volume types
21//=======================================================================
22SelectMgr_SelectingVolumeManager::SelectMgr_SelectingVolumeManager (Standard_Boolean theToAllocateFrustums)
23{
24 myActiveSelectionType = Unknown;
2157d6ac 25 myToAllowOverlap = Standard_False;
f751596e 26
27 if (theToAllocateFrustums)
28 {
29 mySelectingVolumes[Frustum] = new SelectMgr_RectangularFrustum();
30 mySelectingVolumes[FrustumSet] = new SelectMgr_TriangularFrustumSet();
31 }
32}
33
34//=======================================================================
3bf9a45f 35// function : ScaleAndTransform
36// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
37// Note that this method does not perform any checks on type of the frustum.
38//
39// Returns a copy of the frustum resized according to the scale factor given
40// and transforms it using the matrix given.
41// There are no default parameters, but in case if:
42// - transformation only is needed: @theScaleFactor must be initialized
43// as any negative value;
44// - scale only is needed: @theTrsf must be set to gp_Identity.
45//=======================================================================
46SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTransform (const Standard_Integer theScaleFactor,
47 const gp_Trsf& theTrsf)
f751596e 48{
49 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
50
51 if (myActiveSelectionType == Unknown)
52 return aMgr;
53
54 aMgr.myActiveSelectionType = myActiveSelectionType;
55
3bf9a45f 56 aMgr.mySelectingVolumes[myActiveSelectionType / 2]
57 = mySelectingVolumes[myActiveSelectionType / 2]->ScaleAndTransform (theScaleFactor, theTrsf);
2157d6ac 58 aMgr.myToAllowOverlap = myToAllowOverlap;
f751596e 59
60 return aMgr;
61}
62
63//=======================================================================
64// function : GetActiveSelectionType
65// purpose :
66//=======================================================================
7ab15952 67Standard_Integer SelectMgr_SelectingVolumeManager::GetActiveSelectionType() const
f751596e 68{
69 return myActiveSelectionType;
70}
71
72//=======================================================================
73// function : SetActiveSelectionType
74// purpose :
75//=======================================================================
76void SelectMgr_SelectingVolumeManager::SetActiveSelectionType (const SelectionType& theType)
77{
78 myActiveSelectionType = theType;
79}
80
81//=======================================================================
82// function : SetCamera
83// purpose : Updates camera projection and orientation matrices in all
84// selecting volumes
85//=======================================================================
86void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera) theCamera)
87{
88 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
89 {
90 mySelectingVolumes[anIdx]->SetCamera (theCamera);
91 }
92}
93
94//=======================================================================
95// function : SetCamera
96// purpose : Updates camera projection and orientation matrices in all
97// selecting volumes
98//=======================================================================
99void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection,
825aa485 100 const Graphic3d_Mat4d& theWorldView,
101 const Standard_Boolean theIsOrthographic,
102 const Graphic3d_WorldViewProjState& theWVPState)
f751596e 103{
104 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
105 {
825aa485 106 mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState);
f751596e 107 }
108}
109
825aa485 110//=======================================================================
111// function : ProjectionMatrix
112// purpose : Returns current projection transformation common for all
113// selecting volumes
114//=======================================================================
115const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const
116{
117 return mySelectingVolumes[Frustum]->ProjectionMatrix();
118}
119
120//=======================================================================
121// function : WorldViewMatrix
122// purpose : Returns current world view transformation common for all
123// selecting volumes
124//=======================================================================
125const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const
126{
127 return mySelectingVolumes[Frustum]->WorldViewMatrix();
128}
129
130//=======================================================================
131// function : WorldViewProjState
132// purpose : Returns current camera world view projection transformation
133// state common for all selecting volumes
134//=======================================================================
135const Graphic3d_WorldViewProjState& SelectMgr_SelectingVolumeManager::WorldViewProjState() const
136{
137 return mySelectingVolumes[Frustum]->WorldViewProjState();
138}
139
f751596e 140//=======================================================================
141// function : SetCamera
142// purpose : Updates viewport in all selecting volumes
143//=======================================================================
144void SelectMgr_SelectingVolumeManager::SetViewport (const Standard_Real theX,
145 const Standard_Real theY,
146 const Standard_Real theWidth,
147 const Standard_Real theHeight)
148{
149 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
150 {
151 mySelectingVolumes[anIdx]->SetViewport (theX, theY, theWidth, theHeight);
152 }
153}
154
155//=======================================================================
156// function : SetWindowSize
157// purpose : Updates window size in all selecting volumes
158//=======================================================================
159void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer theWidth,
160 const Standard_Integer theHeight)
161{
162 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
163 {
164 mySelectingVolumes[anIdx]->SetWindowSize (theWidth, theHeight);
165 }
166}
167
168//=======================================================================
169// function : SetPixelTolerance
170// purpose : Updates pixel tolerance in all selecting volumes
171//=======================================================================
3bf9a45f 172void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance)
f751596e 173{
174 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
175 {
176 mySelectingVolumes[anIdx]->SetPixelTolerance (theTolerance);
177 }
178}
179
180//=======================================================================
181// function : BuildSelectingVolume
182// purpose : Builds rectangular selecting frustum for point selection
183//=======================================================================
184void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& thePoint)
185{
186 if (myActiveSelectionType != Point)
187 return;
188
189 mySelectingVolumes[Frustum]->Build (thePoint);
190}
191
192//=======================================================================
193// function : BuildSelectingVolume
194// purpose : Builds rectangular selecting frustum for box selection
195//=======================================================================
196void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& theMinPt,
197 const gp_Pnt2d& theMaxPt)
198{
199 if (myActiveSelectionType != Box)
200 return;
201
202 mySelectingVolumes[Frustum]->Build (theMinPt, theMaxPt);
203}
204
205//=======================================================================
206// function : BuildSelectingVolume
207// purpose : Builds set of triangular selecting frustums for polyline
208// selection
209//=======================================================================
210void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints)
211{
212 if (myActiveSelectionType != Polyline)
213 return;
214
215 mySelectingVolumes[FrustumSet]->Build (thePoints);
216}
217
218//=======================================================================
219// function : Overlaps
220// purpose : SAT intersection test between defined volume and
221// given axis-aligned box
222//=======================================================================
3bf9a45f 223Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
224 const SelectMgr_Vec3& theBoxMax,
7ab15952 225 Standard_Real& theDepth)
f751596e 226{
227 if (myActiveSelectionType == Unknown)
228 return Standard_False;
229
3bf9a45f 230 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theDepth);
f751596e 231}
232
233//=======================================================================
234// function : Overlaps
235// purpose : Intersection test between defined volume and given point
236//=======================================================================
2157d6ac 237Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
238 const SelectMgr_Vec3& theBoxMax,
239 Standard_Boolean* theInside)
f751596e 240{
241 if (myActiveSelectionType == Unknown)
242 return Standard_False;
243
2157d6ac 244 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theInside);
f751596e 245}
246
247//=======================================================================
248// function : Overlaps
249// purpose : Intersection test between defined volume and given point
250//=======================================================================
3bf9a45f 251Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt,
7ab15952 252 Standard_Real& theDepth)
f751596e 253{
254 if (myActiveSelectionType == Unknown)
255 return Standard_False;
256
3bf9a45f 257 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt,
f751596e 258 theDepth);
259}
260
3bf9a45f 261//=======================================================================
262// function : Overlaps
263// purpose : Intersection test between defined volume and given point
264//=======================================================================
265Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt)
266{
267 if (myActiveSelectionType == Unknown)
268 return Standard_False;
269
270 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt);
271}
272
f751596e 273//=======================================================================
274// function : Overlaps
275// purpose : SAT intersection test between defined volume and given
276// ordered set of points, representing line segments. The test
277// may be considered of interior part or boundary line defined
278// by segments depending on given sensitivity type
279//=======================================================================
3bf9a45f 280Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
7ab15952 281 Standard_Integer theSensType,
282 Standard_Real& theDepth)
f751596e 283{
284 if (myActiveSelectionType == Unknown)
285 return Standard_False;
286
3bf9a45f 287 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts,
f751596e 288 (Select3D_TypeOfSensitivity)theSensType,
289 theDepth);
290}
291
292//=======================================================================
293// function : Overlaps
294// purpose : Checks if line segment overlaps selecting volume
295//=======================================================================
7ab15952 296Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
297 const gp_Pnt& thePt2,
298 Standard_Real& theDepth)
f751596e 299{
300 if (myActiveSelectionType == Unknown)
301 return Standard_False;
302
303 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, theDepth);
304}
305
306//=======================================================================
307// function : Overlaps
308// purpose : SAT intersection test between defined volume and given
309// triangle. The test may be considered of interior part or
310// boundary line defined by triangle vertices depending on
311// given sensitivity type
312//=======================================================================
7ab15952 313Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
314 const gp_Pnt& thePt2,
315 const gp_Pnt& thePt3,
316 Standard_Integer theSensType,
317 Standard_Real& theDepth)
f751596e 318{
319 if (myActiveSelectionType == Unknown)
320 return Standard_False;
321
322 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1,
323 thePt2,
324 thePt3,
325 (Select3D_TypeOfSensitivity)theSensType,
326 theDepth);
327}
328
329//=======================================================================
330// function : DistToGeometryCenter
331// purpose : Measures distance between 3d projection of user-picked
332// screen point and given point theCOG
333//=======================================================================
7ab15952 334Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_Pnt& theCOG)
f751596e 335{
336 if (myActiveSelectionType == Unknown)
337 return Standard_False;
338
339 return mySelectingVolumes[myActiveSelectionType / 2]->DistToGeometryCenter (theCOG);
340}
341
342// =======================================================================
343// function : DetectedPoint
344// purpose : Calculates the point on a view ray that was detected during
345// the run of selection algo by given depth. Is valid for point
346// selection only
347// =======================================================================
3bf9a45f 348gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
f751596e 349{
350 if (myActiveSelectionType != Point)
3bf9a45f 351 return gp_Pnt (RealLast(), RealLast(), RealLast());
f751596e 352
353 return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
354}
355
356//=======================================================================
357// function : IsClipped
358// purpose : Checks if the point of sensitive in which selection was
359// detected belongs to the region defined by clipping planes
360//=======================================================================
7ab15952 361Standard_Boolean SelectMgr_SelectingVolumeManager::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
362 const Standard_Real& theDepth)
f751596e 363{
364 if (myActiveSelectionType == Point)
365 return Standard_False;
366
367 return mySelectingVolumes[Frustum]->IsClipped (thePlanes, theDepth);
368}
2157d6ac 369
370//=======================================================================
371// function : AllowOverlapDetection
372// purpose : If theIsToAllow is false, only fully included sensitives will
373// be detected, otherwise the algorithm will mark both included
374// and overlapped entities as matched
375//=======================================================================
376void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
377{
378 myToAllowOverlap = theIsToAllow;
379}
380
381//=======================================================================
382// function : IsOverlapAllowed
383// purpose :
384//=======================================================================
385Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
386{
387 return myActiveSelectionType != Box || myToAllowOverlap;
388}
3bf9a45f 389
390//=======================================================================
391// function : GetVertices
392// purpose :
393//=======================================================================
394const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const
395{
396 if (myActiveSelectionType == Polyline)
397 return NULL;
398
399 const SelectMgr_RectangularFrustum* aFr =
400 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
401 return aFr->GetVertices();
402}
403
404//=======================================================================
405// function : GetNearPnt
406// purpose :
407//=======================================================================
408gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPnt() const
409{
410 if (myActiveSelectionType == Polyline)
411 return gp_Pnt();
412
413 const SelectMgr_RectangularFrustum* aFr =
414 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
415 return aFr->GetNearPnt();
416}
417
418//=======================================================================
419// function : GetFarPnt
420// purpose :
421//=======================================================================
422gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPnt() const
423{
424 if (myActiveSelectionType == Polyline)
425 return gp_Pnt();
426
427 const SelectMgr_RectangularFrustum* aFr =
428 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
429 return aFr->GetFarPnt();
430}