1 // Created on: 2014-05-22
2 // Created by: Varvara POSKONINA
3 // Copyright (c) 2005-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <SelectMgr_SelectingVolumeManager.hxx>
18 //=======================================================================
19 // function : SelectMgr_SelectingVolumeManager
20 // purpose : Creates instances of all available selecting volume types
21 //=======================================================================
22 SelectMgr_SelectingVolumeManager::SelectMgr_SelectingVolumeManager (Standard_Boolean theToAllocateFrustums)
24 myActiveSelectionType = Unknown;
25 myToAllowOverlap = Standard_False;
27 if (theToAllocateFrustums)
29 mySelectingVolumes[Frustum] = new SelectMgr_RectangularFrustum();
30 mySelectingVolumes[FrustumSet] = new SelectMgr_TriangularFrustumSet();
34 //=======================================================================
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.
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 // 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.
48 //=======================================================================
49 SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTransform (const Standard_Integer theScaleFactor,
50 const gp_GTrsf& theTrsf,
51 const Handle(SelectMgr_FrustumBuilder)& theBuilder) const
53 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
55 if (myActiveSelectionType == Unknown)
58 aMgr.myActiveSelectionType = myActiveSelectionType;
59 aMgr.mySelectingVolumes[myActiveSelectionType / 2]
60 = mySelectingVolumes[myActiveSelectionType / 2]->ScaleAndTransform (theScaleFactor, theTrsf);
61 aMgr.myToAllowOverlap = myToAllowOverlap;
62 aMgr.mySelectingVolumes[myActiveSelectionType / 2]->SetBuilder (theBuilder);
63 aMgr.myViewClipPlanes = myViewClipPlanes;
68 //=======================================================================
69 // function : GetActiveSelectionType
71 //=======================================================================
72 Standard_Integer SelectMgr_SelectingVolumeManager::GetActiveSelectionType() const
74 return myActiveSelectionType;
77 //=======================================================================
78 // function : SetActiveSelectionType
80 //=======================================================================
81 void SelectMgr_SelectingVolumeManager::SetActiveSelectionType (const SelectionType& theType)
83 myActiveSelectionType = theType;
86 //=======================================================================
87 // function : SetCamera
88 // purpose : Updates camera projection and orientation matrices in all
90 //=======================================================================
91 void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera) theCamera)
93 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
95 mySelectingVolumes[anIdx]->SetCamera (theCamera);
99 //=======================================================================
100 // function : SetCamera
101 // purpose : Updates camera projection and orientation matrices in all
103 //=======================================================================
104 void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection,
105 const Graphic3d_Mat4d& theWorldView,
106 const Standard_Boolean theIsOrthographic,
107 const Graphic3d_WorldViewProjState& theWVPState)
109 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
111 mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState);
115 //=======================================================================
116 // function : ProjectionMatrix
117 // purpose : Returns current projection transformation common for all
119 //=======================================================================
120 const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const
122 return mySelectingVolumes[Frustum]->ProjectionMatrix();
125 //=======================================================================
126 // function : WorldViewMatrix
127 // purpose : Returns current world view transformation common for all
129 //=======================================================================
130 const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const
132 return mySelectingVolumes[Frustum]->WorldViewMatrix();
135 //=======================================================================
136 // function : WorldViewProjState
137 // purpose : Returns current camera world view projection transformation
138 // state common for all selecting volumes
139 //=======================================================================
140 const Graphic3d_WorldViewProjState& SelectMgr_SelectingVolumeManager::WorldViewProjState() const
142 return mySelectingVolumes[Frustum]->WorldViewProjState();
145 //=======================================================================
146 // function : WindowSize
148 //=======================================================================
149 void SelectMgr_SelectingVolumeManager::WindowSize (Standard_Integer& theWidth, Standard_Integer& theHeight) const
151 mySelectingVolumes[Frustum]->WindowSize (theWidth, theHeight);
154 //=======================================================================
155 // function : SetCamera
156 // purpose : Updates viewport in all selecting volumes
157 //=======================================================================
158 void SelectMgr_SelectingVolumeManager::SetViewport (const Standard_Real theX,
159 const Standard_Real theY,
160 const Standard_Real theWidth,
161 const Standard_Real theHeight)
163 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
165 mySelectingVolumes[anIdx]->SetViewport (theX, theY, theWidth, theHeight);
169 //=======================================================================
170 // function : SetWindowSize
171 // purpose : Updates window size in all selecting volumes
172 //=======================================================================
173 void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer theWidth,
174 const Standard_Integer theHeight)
176 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
178 mySelectingVolumes[anIdx]->SetWindowSize (theWidth, theHeight);
182 //=======================================================================
183 // function : SetPixelTolerance
184 // purpose : Updates pixel tolerance in all selecting volumes
185 //=======================================================================
186 void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance)
188 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
190 mySelectingVolumes[anIdx]->SetPixelTolerance (theTolerance);
194 //=======================================================================
195 // function : BuildSelectingVolume
196 // purpose : Builds rectangular selecting frustum for point selection
197 //=======================================================================
198 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& thePoint)
200 if (myActiveSelectionType != Point)
203 mySelectingVolumes[Frustum]->Build (thePoint);
206 //=======================================================================
207 // function : BuildSelectingVolume
208 // purpose : Builds rectangular selecting frustum for box selection
209 //=======================================================================
210 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& theMinPt,
211 const gp_Pnt2d& theMaxPt)
213 if (myActiveSelectionType != Box)
216 mySelectingVolumes[Frustum]->Build (theMinPt, theMaxPt);
219 //=======================================================================
220 // function : BuildSelectingVolume
221 // purpose : Builds set of triangular selecting frustums for polyline
223 //=======================================================================
224 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints)
226 if (myActiveSelectionType != Polyline)
229 mySelectingVolumes[FrustumSet]->Build (thePoints);
232 //=======================================================================
233 // function : Overlaps
234 // purpose : SAT intersection test between defined volume and
235 // given axis-aligned box
236 //=======================================================================
237 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
238 const SelectMgr_Vec3& theBoxMax,
239 Standard_Real& theDepth)
241 if (myActiveSelectionType == Unknown)
242 return Standard_False;
244 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theDepth);
247 //=======================================================================
248 // function : Overlaps
249 // purpose : Intersection test between defined volume and given point
250 //=======================================================================
251 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
252 const SelectMgr_Vec3& theBoxMax,
253 Standard_Boolean* theInside)
255 if (myActiveSelectionType == Unknown)
256 return Standard_False;
258 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theInside);
261 //=======================================================================
262 // function : Overlaps
263 // purpose : Intersection test between defined volume and given point
264 //=======================================================================
265 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt,
266 Standard_Real& theDepth)
268 if (myActiveSelectionType == Unknown)
269 return Standard_False;
271 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt,
275 //=======================================================================
276 // function : Overlaps
277 // purpose : Intersection test between defined volume and given point
278 //=======================================================================
279 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt)
281 if (myActiveSelectionType == Unknown)
282 return Standard_False;
284 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt);
287 //=======================================================================
288 // function : Overlaps
289 // purpose : SAT intersection test between defined volume and given
290 // ordered set of points, representing line segments. The test
291 // may be considered of interior part or boundary line defined
292 // by segments depending on given sensitivity type
293 //=======================================================================
294 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
295 Standard_Integer theSensType,
296 Standard_Real& theDepth)
298 if (myActiveSelectionType == Unknown)
299 return Standard_False;
301 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts->Array1(),
302 (Select3D_TypeOfSensitivity)theSensType,
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 //=======================================================================
313 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
314 Standard_Integer theSensType,
315 Standard_Real& theDepth)
317 if (myActiveSelectionType == Unknown)
318 return Standard_False;
320 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts,
321 (Select3D_TypeOfSensitivity)theSensType,
325 //=======================================================================
326 // function : Overlaps
327 // purpose : Checks if line segment overlaps selecting volume
328 //=======================================================================
329 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
330 const gp_Pnt& thePt2,
331 Standard_Real& theDepth)
333 if (myActiveSelectionType == Unknown)
334 return Standard_False;
336 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, theDepth);
339 //=======================================================================
340 // function : Overlaps
341 // purpose : SAT intersection test between defined volume and given
342 // triangle. The test may be considered of interior part or
343 // boundary line defined by triangle vertices depending on
344 // given sensitivity type
345 //=======================================================================
346 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
347 const gp_Pnt& thePt2,
348 const gp_Pnt& thePt3,
349 Standard_Integer theSensType,
350 Standard_Real& theDepth)
352 if (myActiveSelectionType == Unknown)
353 return Standard_False;
355 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1,
358 (Select3D_TypeOfSensitivity)theSensType,
362 //=======================================================================
363 // function : DistToGeometryCenter
364 // purpose : Measures distance between 3d projection of user-picked
365 // screen point and given point theCOG
366 //=======================================================================
367 Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_Pnt& theCOG)
369 if (myActiveSelectionType == Unknown)
370 return Standard_False;
372 return mySelectingVolumes[myActiveSelectionType / 2]->DistToGeometryCenter (theCOG);
375 // =======================================================================
376 // function : DetectedPoint
377 // purpose : Calculates the point on a view ray that was detected during
378 // the run of selection algo by given depth. Is valid for point
380 // =======================================================================
381 gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
383 if (myActiveSelectionType != Point)
385 Standard_ProgramError::Raise ("SelectMgr_SelectingVolumeManager::DetectedPoint() should be called only for Point selection type");
388 return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
391 //=======================================================================
392 // function : IsClipped
393 // purpose : Checks if the point of sensitive in which selection was
394 // detected belongs to the region defined by clipping planes
395 //=======================================================================
396 Standard_Boolean SelectMgr_SelectingVolumeManager::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
397 const Standard_Real& theDepth)
399 if (myActiveSelectionType != Point)
400 return Standard_False;
402 return mySelectingVolumes[Frustum]->IsClipped (thePlanes, theDepth);
405 //=======================================================================
406 // function : AllowOverlapDetection
407 // purpose : If theIsToAllow is false, only fully included sensitives will
408 // be detected, otherwise the algorithm will mark both included
409 // and overlapped entities as matched
410 //=======================================================================
411 void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
413 myToAllowOverlap = theIsToAllow;
416 //=======================================================================
417 // function : IsOverlapAllowed
419 //=======================================================================
420 Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
422 return myActiveSelectionType != Box || myToAllowOverlap;
425 //=======================================================================
426 // function : GetVertices
428 //=======================================================================
429 const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const
431 if (myActiveSelectionType == Polyline)
434 const SelectMgr_RectangularFrustum* aFr =
435 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
436 return aFr->GetVertices();
439 //=======================================================================
440 // function : GetNearPickedPnt
442 //=======================================================================
443 gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPickedPnt() const
445 if (myActiveSelectionType == Polyline)
448 const SelectMgr_RectangularFrustum* aFr =
449 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
450 return aFr->GetNearPnt();
453 //=======================================================================
454 // function : GetFarPickedPnt
456 //=======================================================================
457 gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPickedPnt() const
459 if (myActiveSelectionType == Polyline)
462 const SelectMgr_RectangularFrustum* aFr =
463 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
464 return aFr->GetFarPnt();
467 //=======================================================================
468 // function : SetViewClipping
470 //=======================================================================
471 void SelectMgr_SelectingVolumeManager::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
473 myViewClipPlanes = thePlanes;
474 if (myActiveSelectionType != Point)
477 mySelectingVolumes[Frustum]->SetViewClipping (thePlanes);
480 //=======================================================================
481 // function : SetViewClippingEnabled
483 //=======================================================================
484 Standard_Boolean SelectMgr_SelectingVolumeManager::SetViewClippingEnabled (const Standard_Boolean theToEnable)
486 if (myActiveSelectionType != Point)
487 return Standard_False;
489 return mySelectingVolumes[Frustum]->SetViewClippingEnabled (theToEnable);