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;
64 aMgr.myObjectClipPlanes = myObjectClipPlanes;
65 aMgr.myViewClipRange = myViewClipRange;
70 //=======================================================================
71 // function : GetActiveSelectionType
73 //=======================================================================
74 Standard_Integer SelectMgr_SelectingVolumeManager::GetActiveSelectionType() const
76 return myActiveSelectionType;
79 //=======================================================================
80 // function : SetActiveSelectionType
82 //=======================================================================
83 void SelectMgr_SelectingVolumeManager::SetActiveSelectionType (const SelectionType& theType)
85 myActiveSelectionType = theType;
88 //=======================================================================
89 // function : SetCamera
90 // purpose : Updates camera projection and orientation matrices in all
92 //=======================================================================
93 void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera) theCamera)
95 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
97 mySelectingVolumes[anIdx]->SetCamera (theCamera);
101 //=======================================================================
102 // function : SetCamera
103 // purpose : Updates camera projection and orientation matrices in all
105 //=======================================================================
106 void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection,
107 const Graphic3d_Mat4d& theWorldView,
108 const Standard_Boolean theIsOrthographic,
109 const Graphic3d_WorldViewProjState& theWVPState)
111 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
113 mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState);
117 //=======================================================================
118 // function : ProjectionMatrix
119 // purpose : Returns current projection transformation common for all
121 //=======================================================================
122 const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const
124 return mySelectingVolumes[Frustum]->ProjectionMatrix();
127 //=======================================================================
128 // function : WorldViewMatrix
129 // purpose : Returns current world view transformation common for all
131 //=======================================================================
132 const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const
134 return mySelectingVolumes[Frustum]->WorldViewMatrix();
137 //=======================================================================
138 // function : WorldViewProjState
139 // purpose : Returns current camera world view projection transformation
140 // state common for all selecting volumes
141 //=======================================================================
142 const Graphic3d_WorldViewProjState& SelectMgr_SelectingVolumeManager::WorldViewProjState() const
144 return mySelectingVolumes[Frustum]->WorldViewProjState();
147 //=======================================================================
148 // function : WindowSize
150 //=======================================================================
151 void SelectMgr_SelectingVolumeManager::WindowSize (Standard_Integer& theWidth, Standard_Integer& theHeight) const
153 mySelectingVolumes[Frustum]->WindowSize (theWidth, theHeight);
156 //=======================================================================
157 // function : SetCamera
158 // purpose : Updates viewport in all selecting volumes
159 //=======================================================================
160 void SelectMgr_SelectingVolumeManager::SetViewport (const Standard_Real theX,
161 const Standard_Real theY,
162 const Standard_Real theWidth,
163 const Standard_Real theHeight)
165 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
167 mySelectingVolumes[anIdx]->SetViewport (theX, theY, theWidth, theHeight);
171 //=======================================================================
172 // function : SetWindowSize
173 // purpose : Updates window size in all selecting volumes
174 //=======================================================================
175 void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer theWidth,
176 const Standard_Integer theHeight)
178 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
180 mySelectingVolumes[anIdx]->SetWindowSize (theWidth, theHeight);
184 //=======================================================================
185 // function : SetPixelTolerance
186 // purpose : Updates pixel tolerance in all selecting volumes
187 //=======================================================================
188 void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance)
190 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
192 mySelectingVolumes[anIdx]->SetPixelTolerance (theTolerance);
196 //=======================================================================
197 // function : BuildSelectingVolume
198 // purpose : Builds rectangular selecting frustum for point selection
199 //=======================================================================
200 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& thePoint)
202 if (myActiveSelectionType != Point)
205 mySelectingVolumes[Frustum]->Build (thePoint);
208 //=======================================================================
209 // function : BuildSelectingVolume
210 // purpose : Builds rectangular selecting frustum for box selection
211 //=======================================================================
212 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& theMinPt,
213 const gp_Pnt2d& theMaxPt)
215 if (myActiveSelectionType != Box)
218 mySelectingVolumes[Frustum]->Build (theMinPt, theMaxPt);
221 //=======================================================================
222 // function : BuildSelectingVolume
223 // purpose : Builds set of triangular selecting frustums for polyline
225 //=======================================================================
226 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints)
228 if (myActiveSelectionType != Polyline)
231 mySelectingVolumes[FrustumSet]->Build (thePoints);
234 //=======================================================================
235 // function : Overlaps
236 // purpose : SAT intersection test between defined volume and
237 // given axis-aligned box
238 //=======================================================================
239 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
240 const SelectMgr_Vec3& theBoxMax,
241 SelectBasics_PickResult& thePickResult) const
243 if (myActiveSelectionType == Unknown)
244 return Standard_False;
246 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, myViewClipRange, thePickResult);
249 //=======================================================================
250 // function : Overlaps
251 // purpose : Intersection test between defined volume and given point
252 //=======================================================================
253 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
254 const SelectMgr_Vec3& theBoxMax,
255 Standard_Boolean* theInside) const
257 if (myActiveSelectionType == Unknown)
258 return Standard_False;
260 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theInside);
263 //=======================================================================
264 // function : Overlaps
265 // purpose : Intersection test between defined volume and given point
266 //=======================================================================
267 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt,
268 SelectBasics_PickResult& thePickResult) const
270 if (myActiveSelectionType == Unknown)
271 return Standard_False;
273 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt, myViewClipRange, thePickResult);
276 //=======================================================================
277 // function : Overlaps
278 // purpose : Intersection test between defined volume and given point
279 //=======================================================================
280 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt) const
282 if (myActiveSelectionType == Unknown)
283 return Standard_False;
285 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt);
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 //=======================================================================
295 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
296 Standard_Integer theSensType,
297 SelectBasics_PickResult& thePickResult) const
299 if (myActiveSelectionType == Unknown)
300 return Standard_False;
302 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts->Array1(), (Select3D_TypeOfSensitivity)theSensType,
303 myViewClipRange, thePickResult);
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 SelectBasics_PickResult& thePickResult) const
317 if (myActiveSelectionType == Unknown)
318 return Standard_False;
320 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts, (Select3D_TypeOfSensitivity)theSensType,
321 myViewClipRange, thePickResult);
324 //=======================================================================
325 // function : Overlaps
326 // purpose : Checks if line segment overlaps selecting volume
327 //=======================================================================
328 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
329 const gp_Pnt& thePt2,
330 SelectBasics_PickResult& thePickResult) const
332 if (myActiveSelectionType == Unknown)
333 return Standard_False;
335 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, myViewClipRange, thePickResult);
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 //=======================================================================
345 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1,
346 const gp_Pnt& thePt2,
347 const gp_Pnt& thePt3,
348 Standard_Integer theSensType,
349 SelectBasics_PickResult& thePickResult) const
351 if (myActiveSelectionType == Unknown)
352 return Standard_False;
354 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, thePt3, (Select3D_TypeOfSensitivity)theSensType,
355 myViewClipRange, thePickResult);
358 //=======================================================================
359 // function : DistToGeometryCenter
360 // purpose : Measures distance between 3d projection of user-picked
361 // screen point and given point theCOG
362 //=======================================================================
363 Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_Pnt& theCOG) const
365 if (myActiveSelectionType == Unknown)
366 return Standard_False;
368 return mySelectingVolumes[myActiveSelectionType / 2]->DistToGeometryCenter (theCOG);
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
376 // =======================================================================
377 gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
379 if (myActiveSelectionType != Point)
381 throw Standard_ProgramError("SelectMgr_SelectingVolumeManager::DetectedPoint() should be called only for Point selection type");
384 return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
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 //=======================================================================
393 void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
395 myToAllowOverlap = theIsToAllow;
398 //=======================================================================
399 // function : IsOverlapAllowed
401 //=======================================================================
402 Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
404 return myActiveSelectionType != Box || myToAllowOverlap;
407 //=======================================================================
408 // function : GetVertices
410 //=======================================================================
411 const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const
413 if (myActiveSelectionType == Polyline)
416 const SelectMgr_RectangularFrustum* aFr =
417 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
418 return aFr->GetVertices();
421 //=======================================================================
422 // function : GetNearPickedPnt
424 //=======================================================================
425 gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPickedPnt() const
427 if (myActiveSelectionType == Polyline)
430 const SelectMgr_RectangularFrustum* aFr =
431 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
432 return aFr->GetNearPnt();
435 //=======================================================================
436 // function : GetFarPickedPnt
438 //=======================================================================
439 gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPickedPnt() const
441 if (myActiveSelectionType == Polyline)
444 const SelectMgr_RectangularFrustum* aFr =
445 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
446 return aFr->GetFarPnt();
449 //=======================================================================
450 // function : SetViewClipping
452 //=======================================================================
453 void SelectMgr_SelectingVolumeManager::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& theViewPlanes,
454 const Handle(Graphic3d_SequenceOfHClipPlane)& theObjPlanes)
456 myViewClipPlanes = theViewPlanes;
457 myObjectClipPlanes = theObjPlanes;
458 if (myActiveSelectionType != Point)
461 const SelectMgr_RectangularFrustum* aFrustum = reinterpret_cast<const SelectMgr_RectangularFrustum*>(mySelectingVolumes[Frustum].get());
462 myViewClipRange.SetVoid();
463 if (!theViewPlanes.IsNull()
464 && !theViewPlanes->IsEmpty())
466 myViewClipRange.AddClippingPlanes (*theViewPlanes, gp_Ax1 (aFrustum->GetNearPnt(), aFrustum->GetViewRayDirection()));
468 if (!theObjPlanes.IsNull()
469 && !theObjPlanes->IsEmpty())
471 myViewClipRange.AddClippingPlanes (*theObjPlanes, gp_Ax1 (aFrustum->GetNearPnt(), aFrustum->GetViewRayDirection()));
475 //=======================================================================
476 // function : SetViewClipping
478 //=======================================================================
479 void SelectMgr_SelectingVolumeManager::SetViewClipping (const SelectMgr_SelectingVolumeManager& theOther)
481 myViewClipPlanes = theOther.myViewClipPlanes;
482 myObjectClipPlanes = theOther.myObjectClipPlanes;
483 myViewClipRange = theOther.myViewClipRange;