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