0030777: Visualization - Incorrect selection/highlighting of clipped objects
[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.
099f3513 45// Builder is an optional argument that represents corresponding settings for
46// re-constructing transformed frustum from scratch. Can be null if reconstruction
47// is not needed furthermore in the code.
3bf9a45f 48//=======================================================================
49SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTransform (const Standard_Integer theScaleFactor,
099f3513 50 const gp_GTrsf& theTrsf,
51 const Handle(SelectMgr_FrustumBuilder)& theBuilder) const
f751596e 52{
53 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
54
55 if (myActiveSelectionType == Unknown)
56 return aMgr;
57
58 aMgr.myActiveSelectionType = myActiveSelectionType;
3bf9a45f 59 aMgr.mySelectingVolumes[myActiveSelectionType / 2]
60 = mySelectingVolumes[myActiveSelectionType / 2]->ScaleAndTransform (theScaleFactor, theTrsf);
2157d6ac 61 aMgr.myToAllowOverlap = myToAllowOverlap;
099f3513 62 aMgr.mySelectingVolumes[myActiveSelectionType / 2]->SetBuilder (theBuilder);
8b1441e3 63 aMgr.myViewClipPlanes = myViewClipPlanes;
fe525c6f 64 aMgr.myObjectClipPlanes = myObjectClipPlanes;
f751596e 65
66 return aMgr;
67}
68
69//=======================================================================
70// function : GetActiveSelectionType
71// purpose :
72//=======================================================================
7ab15952 73Standard_Integer SelectMgr_SelectingVolumeManager::GetActiveSelectionType() const
f751596e 74{
75 return myActiveSelectionType;
76}
77
78//=======================================================================
79// function : SetActiveSelectionType
80// purpose :
81//=======================================================================
82void SelectMgr_SelectingVolumeManager::SetActiveSelectionType (const SelectionType& theType)
83{
84 myActiveSelectionType = theType;
85}
86
87//=======================================================================
88// function : SetCamera
89// purpose : Updates camera projection and orientation matrices in all
90// selecting volumes
91//=======================================================================
92void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera) theCamera)
93{
94 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
95 {
96 mySelectingVolumes[anIdx]->SetCamera (theCamera);
97 }
98}
99
100//=======================================================================
101// function : SetCamera
102// purpose : Updates camera projection and orientation matrices in all
103// selecting volumes
104//=======================================================================
105void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection,
825aa485 106 const Graphic3d_Mat4d& theWorldView,
107 const Standard_Boolean theIsOrthographic,
108 const Graphic3d_WorldViewProjState& theWVPState)
f751596e 109{
110 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
111 {
825aa485 112 mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState);
f751596e 113 }
114}
115
825aa485 116//=======================================================================
117// function : ProjectionMatrix
118// purpose : Returns current projection transformation common for all
119// selecting volumes
120//=======================================================================
121const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const
122{
123 return mySelectingVolumes[Frustum]->ProjectionMatrix();
124}
125
126//=======================================================================
127// function : WorldViewMatrix
128// purpose : Returns current world view transformation common for all
129// selecting volumes
130//=======================================================================
131const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const
132{
133 return mySelectingVolumes[Frustum]->WorldViewMatrix();
134}
135
136//=======================================================================
137// function : WorldViewProjState
138// purpose : Returns current camera world view projection transformation
139// state common for all selecting volumes
140//=======================================================================
141const Graphic3d_WorldViewProjState& SelectMgr_SelectingVolumeManager::WorldViewProjState() const
142{
143 return mySelectingVolumes[Frustum]->WorldViewProjState();
144}
145
91d96372 146//=======================================================================
147// function : WindowSize
148// purpose :
149//=======================================================================
099f3513 150void SelectMgr_SelectingVolumeManager::WindowSize (Standard_Integer& theWidth, Standard_Integer& theHeight) const
91d96372 151{
152 mySelectingVolumes[Frustum]->WindowSize (theWidth, theHeight);
153}
154
f751596e 155//=======================================================================
156// function : SetCamera
157// purpose : Updates viewport in all selecting volumes
158//=======================================================================
159void SelectMgr_SelectingVolumeManager::SetViewport (const Standard_Real theX,
160 const Standard_Real theY,
161 const Standard_Real theWidth,
162 const Standard_Real theHeight)
163{
164 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
165 {
166 mySelectingVolumes[anIdx]->SetViewport (theX, theY, theWidth, theHeight);
167 }
168}
169
170//=======================================================================
171// function : SetWindowSize
172// purpose : Updates window size in all selecting volumes
173//=======================================================================
174void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer theWidth,
175 const Standard_Integer theHeight)
176{
177 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
178 {
179 mySelectingVolumes[anIdx]->SetWindowSize (theWidth, theHeight);
180 }
181}
182
183//=======================================================================
184// function : SetPixelTolerance
185// purpose : Updates pixel tolerance in all selecting volumes
186//=======================================================================
3bf9a45f 187void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance)
f751596e 188{
189 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
190 {
191 mySelectingVolumes[anIdx]->SetPixelTolerance (theTolerance);
192 }
193}
194
195//=======================================================================
196// function : BuildSelectingVolume
197// purpose : Builds rectangular selecting frustum for point selection
198//=======================================================================
199void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& thePoint)
200{
201 if (myActiveSelectionType != Point)
202 return;
203
204 mySelectingVolumes[Frustum]->Build (thePoint);
205}
206
207//=======================================================================
208// function : BuildSelectingVolume
209// purpose : Builds rectangular selecting frustum for box selection
210//=======================================================================
211void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& theMinPt,
212 const gp_Pnt2d& theMaxPt)
213{
214 if (myActiveSelectionType != Box)
215 return;
216
217 mySelectingVolumes[Frustum]->Build (theMinPt, theMaxPt);
218}
219
220//=======================================================================
221// function : BuildSelectingVolume
222// purpose : Builds set of triangular selecting frustums for polyline
223// selection
224//=======================================================================
225void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints)
226{
227 if (myActiveSelectionType != Polyline)
228 return;
229
230 mySelectingVolumes[FrustumSet]->Build (thePoints);
231}
232
233//=======================================================================
234// function : Overlaps
235// purpose : SAT intersection test between defined volume and
236// given axis-aligned box
237//=======================================================================
3bf9a45f 238Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
239 const SelectMgr_Vec3& theBoxMax,
4a056d20 240 SelectBasics_PickResult& thePickResult) const
f751596e 241{
242 if (myActiveSelectionType == Unknown)
243 return Standard_False;
244
17017555 245 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, thePickResult);
f751596e 246}
247
248//=======================================================================
249// function : Overlaps
250// purpose : Intersection test between defined volume and given point
251//=======================================================================
2157d6ac 252Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
253 const SelectMgr_Vec3& theBoxMax,
4a056d20 254 Standard_Boolean* theInside) const
f751596e 255{
256 if (myActiveSelectionType == Unknown)
257 return Standard_False;
258
2157d6ac 259 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theInside);
f751596e 260}
261
262//=======================================================================
263// function : Overlaps
264// purpose : Intersection test between defined volume and given point
265//=======================================================================
3bf9a45f 266Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt,
4a056d20 267 SelectBasics_PickResult& thePickResult) const
f751596e 268{
269 if (myActiveSelectionType == Unknown)
270 return Standard_False;
271
3bf9a45f 272 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt,
17017555 273 thePickResult);
f751596e 274}
275
3bf9a45f 276//=======================================================================
277// function : Overlaps
278// purpose : Intersection test between defined volume and given point
279//=======================================================================
4a056d20 280Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt) const
3bf9a45f 281{
282 if (myActiveSelectionType == Unknown)
283 return Standard_False;
284
285 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt);
286}
287
f751596e 288//=======================================================================
289// function : Overlaps
290// purpose : SAT intersection test between defined volume and given
291// ordered set of points, representing line segments. The test
292// may be considered of interior part or boundary line defined
293// by segments depending on given sensitivity type
294//=======================================================================
3bf9a45f 295Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
7ab15952 296 Standard_Integer theSensType,
4a056d20 297 SelectBasics_PickResult& thePickResult) const
f751596e 298{
299 if (myActiveSelectionType == Unknown)
300 return Standard_False;
301
114b7bf1 302 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts->Array1(),
303 (Select3D_TypeOfSensitivity)theSensType,
17017555 304 thePickResult);
114b7bf1 305}
306
307//=======================================================================
308// function : Overlaps
309// purpose : SAT intersection test between defined volume and given
310// ordered set of points, representing line segments. The test
311// may be considered of interior part or boundary line defined
312// by segments depending on given sensitivity type
313//=======================================================================
314Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
315 Standard_Integer theSensType,
4a056d20 316 SelectBasics_PickResult& thePickResult) const
114b7bf1 317{
318 if (myActiveSelectionType == Unknown)
319 return Standard_False;
320
3bf9a45f 321 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts,
f751596e 322 (Select3D_TypeOfSensitivity)theSensType,
17017555 323 thePickResult);
f751596e 324}
325
326//=======================================================================
327// function : Overlaps
328// purpose : Checks if line segment overlaps selecting volume
329//=======================================================================
7ab15952 330Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
331 const gp_Pnt& thePt2,
4a056d20 332 SelectBasics_PickResult& thePickResult) const
f751596e 333{
334 if (myActiveSelectionType == Unknown)
335 return Standard_False;
336
17017555 337 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, thePickResult);
f751596e 338}
339
340//=======================================================================
341// function : Overlaps
342// purpose : SAT intersection test between defined volume and given
343// triangle. The test may be considered of interior part or
344// boundary line defined by triangle vertices depending on
345// given sensitivity type
346//=======================================================================
7ab15952 347Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
348 const gp_Pnt& thePt2,
349 const gp_Pnt& thePt3,
350 Standard_Integer theSensType,
4a056d20 351 SelectBasics_PickResult& thePickResult) const
f751596e 352{
353 if (myActiveSelectionType == Unknown)
354 return Standard_False;
355
356 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1,
357 thePt2,
358 thePt3,
359 (Select3D_TypeOfSensitivity)theSensType,
17017555 360 thePickResult);
f751596e 361}
362
363//=======================================================================
364// function : DistToGeometryCenter
365// purpose : Measures distance between 3d projection of user-picked
366// screen point and given point theCOG
367//=======================================================================
4a056d20 368Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_Pnt& theCOG) const
f751596e 369{
370 if (myActiveSelectionType == Unknown)
371 return Standard_False;
372
373 return mySelectingVolumes[myActiveSelectionType / 2]->DistToGeometryCenter (theCOG);
374}
375
376// =======================================================================
377// function : DetectedPoint
378// purpose : Calculates the point on a view ray that was detected during
379// the run of selection algo by given depth. Is valid for point
380// selection only
381// =======================================================================
3bf9a45f 382gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
f751596e 383{
384 if (myActiveSelectionType != Point)
949c9b7f 385 {
9775fa61 386 throw Standard_ProgramError("SelectMgr_SelectingVolumeManager::DetectedPoint() should be called only for Point selection type");
949c9b7f 387 }
f751596e 388
389 return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
390}
391
2157d6ac 392//=======================================================================
393// function : AllowOverlapDetection
394// purpose : If theIsToAllow is false, only fully included sensitives will
395// be detected, otherwise the algorithm will mark both included
396// and overlapped entities as matched
397//=======================================================================
398void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
399{
400 myToAllowOverlap = theIsToAllow;
401}
402
403//=======================================================================
404// function : IsOverlapAllowed
405// purpose :
406//=======================================================================
407Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
408{
409 return myActiveSelectionType != Box || myToAllowOverlap;
410}
3bf9a45f 411
412//=======================================================================
413// function : GetVertices
414// purpose :
415//=======================================================================
416const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const
417{
418 if (myActiveSelectionType == Polyline)
419 return NULL;
420
421 const SelectMgr_RectangularFrustum* aFr =
422 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
423 return aFr->GetVertices();
424}
425
426//=======================================================================
21a8e275 427// function : GetNearPickedPnt
3bf9a45f 428// purpose :
429//=======================================================================
21a8e275 430gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPickedPnt() const
3bf9a45f 431{
432 if (myActiveSelectionType == Polyline)
433 return gp_Pnt();
434
435 const SelectMgr_RectangularFrustum* aFr =
436 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
437 return aFr->GetNearPnt();
438}
439
440//=======================================================================
21a8e275 441// function : GetFarPickedPnt
3bf9a45f 442// purpose :
443//=======================================================================
21a8e275 444gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPickedPnt() const
3bf9a45f 445{
446 if (myActiveSelectionType == Polyline)
447 return gp_Pnt();
448
449 const SelectMgr_RectangularFrustum* aFr =
450 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
451 return aFr->GetFarPnt();
452}
e9312c0f 453
454//=======================================================================
455// function : SetViewClipping
456// purpose :
457//=======================================================================
fe525c6f 458void SelectMgr_SelectingVolumeManager::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& theViewPlanes,
459 const Handle(Graphic3d_SequenceOfHClipPlane)& theObjPlanes)
e9312c0f 460{
fe525c6f 461 myViewClipPlanes = theViewPlanes;
462 myObjectClipPlanes = theObjPlanes;
e9312c0f 463 if (myActiveSelectionType != Point)
464 return;
465
fe525c6f 466 mySelectingVolumes[Frustum]->SetViewClipping (theViewPlanes, theObjPlanes);
3202bf1e 467}