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>
17 #include <Standard_Dump.hxx>
19 //=======================================================================
20 // function : SelectMgr_SelectingVolumeManager
21 // purpose : Creates instances of all available selecting volume types
22 //=======================================================================
23 SelectMgr_SelectingVolumeManager::SelectMgr_SelectingVolumeManager (Standard_Boolean theToAllocateFrustums)
25 myActiveSelectionType = Unknown;
26 myToAllowOverlap = Standard_False;
28 if (theToAllocateFrustums)
30 mySelectingVolumes[Frustum] = new SelectMgr_RectangularFrustum();
31 mySelectingVolumes[FrustumSet] = new SelectMgr_TriangularFrustumSet();
35 //=======================================================================
36 // function : ScaleAndTransform
37 // purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
38 // Note that this method does not perform any checks on type of the frustum.
40 // Returns a copy of the frustum resized according to the scale factor given
41 // and transforms it using the matrix given.
42 // There are no default parameters, but in case if:
43 // - transformation only is needed: @theScaleFactor must be initialized
44 // as any negative value;
45 // - scale only is needed: @theTrsf must be set to gp_Identity.
46 // Builder is an optional argument that represents corresponding settings for
47 // re-constructing transformed frustum from scratch. Can be null if reconstruction
48 // is not needed furthermore in the code.
49 //=======================================================================
50 SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTransform (const Standard_Integer theScaleFactor,
51 const gp_GTrsf& theTrsf,
52 const Handle(SelectMgr_FrustumBuilder)& theBuilder) const
54 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
56 if (myActiveSelectionType == Unknown)
59 aMgr.myActiveSelectionType = myActiveSelectionType;
60 aMgr.mySelectingVolumes[myActiveSelectionType / 2]
61 = mySelectingVolumes[myActiveSelectionType / 2]->ScaleAndTransform (theScaleFactor, theTrsf);
62 aMgr.myToAllowOverlap = myToAllowOverlap;
63 aMgr.mySelectingVolumes[myActiveSelectionType / 2]->SetBuilder (theBuilder);
64 aMgr.myViewClipPlanes = myViewClipPlanes;
65 aMgr.myObjectClipPlanes = myObjectClipPlanes;
66 aMgr.myViewClipRange = myViewClipRange;
71 //=======================================================================
72 // function : GetActiveSelectionType
74 //=======================================================================
75 Standard_Integer SelectMgr_SelectingVolumeManager::GetActiveSelectionType() const
77 return myActiveSelectionType;
80 //=======================================================================
81 // function : SetActiveSelectionType
83 //=======================================================================
84 void SelectMgr_SelectingVolumeManager::SetActiveSelectionType (const SelectionType& theType)
86 myActiveSelectionType = theType;
89 //=======================================================================
90 // function : SetCamera
91 // purpose : Updates camera projection and orientation matrices in all
93 //=======================================================================
94 void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera) theCamera)
96 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
98 mySelectingVolumes[anIdx]->SetCamera (theCamera);
102 //=======================================================================
103 // function : SetCamera
104 // purpose : Updates camera projection and orientation matrices in all
106 //=======================================================================
107 void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection,
108 const Graphic3d_Mat4d& theWorldView,
109 const Standard_Boolean theIsOrthographic,
110 const Graphic3d_WorldViewProjState& theWVPState)
112 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
114 mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState);
118 //=======================================================================
119 // function : ProjectionMatrix
120 // purpose : Returns current projection transformation common for all
122 //=======================================================================
123 const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const
125 return mySelectingVolumes[Frustum]->ProjectionMatrix();
128 //=======================================================================
129 // function : WorldViewMatrix
130 // purpose : Returns current world view transformation common for all
132 //=======================================================================
133 const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const
135 return mySelectingVolumes[Frustum]->WorldViewMatrix();
138 //=======================================================================
139 // function : WorldViewProjState
140 // purpose : Returns current camera world view projection transformation
141 // state common for all selecting volumes
142 //=======================================================================
143 const Graphic3d_WorldViewProjState& SelectMgr_SelectingVolumeManager::WorldViewProjState() const
145 return mySelectingVolumes[Frustum]->WorldViewProjState();
148 //=======================================================================
149 // function : WindowSize
151 //=======================================================================
152 void SelectMgr_SelectingVolumeManager::WindowSize (Standard_Integer& theWidth, Standard_Integer& theHeight) const
154 mySelectingVolumes[Frustum]->WindowSize (theWidth, theHeight);
157 //=======================================================================
158 // function : SetCamera
159 // purpose : Updates viewport in all selecting volumes
160 //=======================================================================
161 void SelectMgr_SelectingVolumeManager::SetViewport (const Standard_Real theX,
162 const Standard_Real theY,
163 const Standard_Real theWidth,
164 const Standard_Real theHeight)
166 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
168 mySelectingVolumes[anIdx]->SetViewport (theX, theY, theWidth, theHeight);
172 //=======================================================================
173 // function : SetWindowSize
174 // purpose : Updates window size in all selecting volumes
175 //=======================================================================
176 void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer theWidth,
177 const Standard_Integer theHeight)
179 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
181 mySelectingVolumes[anIdx]->SetWindowSize (theWidth, theHeight);
185 //=======================================================================
186 // function : SetPixelTolerance
187 // purpose : Updates pixel tolerance in all selecting volumes
188 //=======================================================================
189 void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance)
191 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
193 mySelectingVolumes[anIdx]->SetPixelTolerance (theTolerance);
197 //=======================================================================
198 // function : BuildSelectingVolume
199 // purpose : Builds rectangular selecting frustum for point selection
200 //=======================================================================
201 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& thePoint)
203 if (myActiveSelectionType != Point)
206 mySelectingVolumes[Frustum]->Build (thePoint);
209 //=======================================================================
210 // function : BuildSelectingVolume
211 // purpose : Builds rectangular selecting frustum for box selection
212 //=======================================================================
213 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& theMinPt,
214 const gp_Pnt2d& theMaxPt)
216 if (myActiveSelectionType != Box)
219 mySelectingVolumes[Frustum]->Build (theMinPt, theMaxPt);
222 //=======================================================================
223 // function : BuildSelectingVolume
224 // purpose : Builds set of triangular selecting frustums for polyline
226 //=======================================================================
227 void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints)
229 if (myActiveSelectionType != Polyline)
232 mySelectingVolumes[FrustumSet]->Build (thePoints);
235 //=======================================================================
236 // function : Overlaps
237 // purpose : SAT intersection test between defined volume and
238 // given axis-aligned box
239 //=======================================================================
240 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
241 const SelectMgr_Vec3& theBoxMax,
242 SelectBasics_PickResult& thePickResult) const
244 if (myActiveSelectionType == Unknown)
245 return Standard_False;
247 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, myViewClipRange, thePickResult);
250 //=======================================================================
251 // function : Overlaps
252 // purpose : Intersection test between defined volume and given point
253 //=======================================================================
254 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
255 const SelectMgr_Vec3& theBoxMax,
256 Standard_Boolean* theInside) const
258 if (myActiveSelectionType == Unknown)
259 return Standard_False;
261 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theInside);
264 //=======================================================================
265 // function : Overlaps
266 // purpose : Intersection test between defined volume and given point
267 //=======================================================================
268 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt,
269 SelectBasics_PickResult& thePickResult) const
271 if (myActiveSelectionType == Unknown)
272 return Standard_False;
274 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt, myViewClipRange, thePickResult);
277 //=======================================================================
278 // function : Overlaps
279 // purpose : Intersection test between defined volume and given point
280 //=======================================================================
281 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt) const
283 if (myActiveSelectionType == Unknown)
284 return Standard_False;
286 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt);
289 //=======================================================================
290 // function : Overlaps
291 // purpose : SAT intersection test between defined volume and given
292 // ordered set of points, representing line segments. The test
293 // may be considered of interior part or boundary line defined
294 // by segments depending on given sensitivity type
295 //=======================================================================
296 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
297 Standard_Integer theSensType,
298 SelectBasics_PickResult& thePickResult) const
300 if (myActiveSelectionType == Unknown)
301 return Standard_False;
303 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts->Array1(), (Select3D_TypeOfSensitivity)theSensType,
304 myViewClipRange, thePickResult);
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 //=======================================================================
314 Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
315 Standard_Integer theSensType,
316 SelectBasics_PickResult& thePickResult) const
318 if (myActiveSelectionType == Unknown)
319 return Standard_False;
321 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts, (Select3D_TypeOfSensitivity)theSensType,
322 myViewClipRange, thePickResult);
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 SelectBasics_PickResult& thePickResult) const
333 if (myActiveSelectionType == Unknown)
334 return Standard_False;
336 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, myViewClipRange, thePickResult);
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 SelectBasics_PickResult& thePickResult) const
352 if (myActiveSelectionType == Unknown)
353 return Standard_False;
355 return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, thePt3, (Select3D_TypeOfSensitivity)theSensType,
356 myViewClipRange, thePickResult);
359 //=======================================================================
360 // function : DistToGeometryCenter
361 // purpose : Measures distance between 3d projection of user-picked
362 // screen point and given point theCOG
363 //=======================================================================
364 Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_Pnt& theCOG) const
366 if (myActiveSelectionType == Unknown)
367 return Standard_False;
369 return mySelectingVolumes[myActiveSelectionType / 2]->DistToGeometryCenter (theCOG);
372 // =======================================================================
373 // function : DetectedPoint
374 // purpose : Calculates the point on a view ray that was detected during
375 // the run of selection algo by given depth. Is valid for point
377 // =======================================================================
378 gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
380 if (myActiveSelectionType != Point)
382 throw Standard_ProgramError("SelectMgr_SelectingVolumeManager::DetectedPoint() should be called only for Point selection type");
385 return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
388 //=======================================================================
389 // function : AllowOverlapDetection
390 // purpose : If theIsToAllow is false, only fully included sensitives will
391 // be detected, otherwise the algorithm will mark both included
392 // and overlapped entities as matched
393 //=======================================================================
394 void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
396 myToAllowOverlap = theIsToAllow;
399 //=======================================================================
400 // function : IsOverlapAllowed
402 //=======================================================================
403 Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
405 return myActiveSelectionType != Box || myToAllowOverlap;
408 //=======================================================================
409 // function : GetVertices
411 //=======================================================================
412 const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const
414 if (myActiveSelectionType == Polyline)
417 const SelectMgr_RectangularFrustum* aFr =
418 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
419 return aFr->GetVertices();
422 //=======================================================================
423 // function : GetNearPickedPnt
425 //=======================================================================
426 gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPickedPnt() const
428 if (myActiveSelectionType == Polyline)
431 const SelectMgr_RectangularFrustum* aFr =
432 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
433 return aFr->GetNearPnt();
436 //=======================================================================
437 // function : GetFarPickedPnt
439 //=======================================================================
440 gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPickedPnt() const
442 if (myActiveSelectionType == Polyline)
445 const SelectMgr_RectangularFrustum* aFr =
446 reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
447 return aFr->GetFarPnt();
450 //=======================================================================
451 // function : SetViewClipping
453 //=======================================================================
454 void SelectMgr_SelectingVolumeManager::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& theViewPlanes,
455 const Handle(Graphic3d_SequenceOfHClipPlane)& theObjPlanes)
457 myViewClipPlanes = theViewPlanes;
458 myObjectClipPlanes = theObjPlanes;
459 if (myActiveSelectionType != Point)
462 const SelectMgr_RectangularFrustum* aFrustum = reinterpret_cast<const SelectMgr_RectangularFrustum*>(mySelectingVolumes[Frustum].get());
463 myViewClipRange.SetVoid();
464 if (!theViewPlanes.IsNull()
465 && !theViewPlanes->IsEmpty())
467 myViewClipRange.AddClippingPlanes (*theViewPlanes, gp_Ax1 (aFrustum->GetNearPnt(), aFrustum->GetViewRayDirection()));
469 if (!theObjPlanes.IsNull()
470 && !theObjPlanes->IsEmpty())
472 myViewClipRange.AddClippingPlanes (*theObjPlanes, gp_Ax1 (aFrustum->GetNearPnt(), aFrustum->GetViewRayDirection()));
476 //=======================================================================
477 // function : SetViewClipping
479 //=======================================================================
480 void SelectMgr_SelectingVolumeManager::SetViewClipping (const SelectMgr_SelectingVolumeManager& theOther)
482 myViewClipPlanes = theOther.myViewClipPlanes;
483 myObjectClipPlanes = theOther.myObjectClipPlanes;
484 myViewClipRange = theOther.myViewClipRange;
487 //=======================================================================
488 //function : DumpJson
490 //=======================================================================
491 void SelectMgr_SelectingVolumeManager::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
493 OCCT_DUMP_CLASS_BEGIN (theOStream, SelectMgr_SelectingVolumeManager)
495 for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
497 const Handle(SelectMgr_BaseFrustum)& aSelectingVolume = mySelectingVolumes[anIdx];
498 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, aSelectingVolume.get())
501 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myViewClipPlanes.get())
502 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myObjectClipPlanes.get())
504 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myViewClipRange)
505 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToAllowOverlap)