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 | //======================================================================= |
22 | SelectMgr_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 | //======================================================================= |
49 | SelectMgr_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; |
f751596e |
64 | |
65 | return aMgr; |
66 | } |
67 | |
68 | //======================================================================= |
69 | // function : GetActiveSelectionType |
70 | // purpose : |
71 | //======================================================================= |
7ab15952 |
72 | Standard_Integer SelectMgr_SelectingVolumeManager::GetActiveSelectionType() const |
f751596e |
73 | { |
74 | return myActiveSelectionType; |
75 | } |
76 | |
77 | //======================================================================= |
78 | // function : SetActiveSelectionType |
79 | // purpose : |
80 | //======================================================================= |
81 | void SelectMgr_SelectingVolumeManager::SetActiveSelectionType (const SelectionType& theType) |
82 | { |
83 | myActiveSelectionType = theType; |
84 | } |
85 | |
86 | //======================================================================= |
87 | // function : SetCamera |
88 | // purpose : Updates camera projection and orientation matrices in all |
89 | // selecting volumes |
90 | //======================================================================= |
91 | void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera) theCamera) |
92 | { |
93 | for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) |
94 | { |
95 | mySelectingVolumes[anIdx]->SetCamera (theCamera); |
96 | } |
97 | } |
98 | |
99 | //======================================================================= |
100 | // function : SetCamera |
101 | // purpose : Updates camera projection and orientation matrices in all |
102 | // selecting volumes |
103 | //======================================================================= |
104 | void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection, |
825aa485 |
105 | const Graphic3d_Mat4d& theWorldView, |
106 | const Standard_Boolean theIsOrthographic, |
107 | const Graphic3d_WorldViewProjState& theWVPState) |
f751596e |
108 | { |
109 | for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) |
110 | { |
825aa485 |
111 | mySelectingVolumes[anIdx]->SetCamera (theProjection, theWorldView, theIsOrthographic, theWVPState); |
f751596e |
112 | } |
113 | } |
114 | |
825aa485 |
115 | //======================================================================= |
116 | // function : ProjectionMatrix |
117 | // purpose : Returns current projection transformation common for all |
118 | // selecting volumes |
119 | //======================================================================= |
120 | const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::ProjectionMatrix() const |
121 | { |
122 | return mySelectingVolumes[Frustum]->ProjectionMatrix(); |
123 | } |
124 | |
125 | //======================================================================= |
126 | // function : WorldViewMatrix |
127 | // purpose : Returns current world view transformation common for all |
128 | // selecting volumes |
129 | //======================================================================= |
130 | const Graphic3d_Mat4d& SelectMgr_SelectingVolumeManager::WorldViewMatrix() const |
131 | { |
132 | return mySelectingVolumes[Frustum]->WorldViewMatrix(); |
133 | } |
134 | |
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 |
141 | { |
142 | return mySelectingVolumes[Frustum]->WorldViewProjState(); |
143 | } |
144 | |
91d96372 |
145 | //======================================================================= |
146 | // function : WindowSize |
147 | // purpose : |
148 | //======================================================================= |
099f3513 |
149 | void SelectMgr_SelectingVolumeManager::WindowSize (Standard_Integer& theWidth, Standard_Integer& theHeight) const |
91d96372 |
150 | { |
151 | mySelectingVolumes[Frustum]->WindowSize (theWidth, theHeight); |
152 | } |
153 | |
f751596e |
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) |
162 | { |
163 | for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) |
164 | { |
165 | mySelectingVolumes[anIdx]->SetViewport (theX, theY, theWidth, theHeight); |
166 | } |
167 | } |
168 | |
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) |
175 | { |
176 | for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) |
177 | { |
178 | mySelectingVolumes[anIdx]->SetWindowSize (theWidth, theHeight); |
179 | } |
180 | } |
181 | |
182 | //======================================================================= |
183 | // function : SetPixelTolerance |
184 | // purpose : Updates pixel tolerance in all selecting volumes |
185 | //======================================================================= |
3bf9a45f |
186 | void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance) |
f751596e |
187 | { |
188 | for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) |
189 | { |
190 | mySelectingVolumes[anIdx]->SetPixelTolerance (theTolerance); |
191 | } |
192 | } |
193 | |
194 | //======================================================================= |
195 | // function : BuildSelectingVolume |
196 | // purpose : Builds rectangular selecting frustum for point selection |
197 | //======================================================================= |
198 | void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& thePoint) |
199 | { |
200 | if (myActiveSelectionType != Point) |
201 | return; |
202 | |
203 | mySelectingVolumes[Frustum]->Build (thePoint); |
204 | } |
205 | |
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) |
212 | { |
213 | if (myActiveSelectionType != Box) |
214 | return; |
215 | |
216 | mySelectingVolumes[Frustum]->Build (theMinPt, theMaxPt); |
217 | } |
218 | |
219 | //======================================================================= |
220 | // function : BuildSelectingVolume |
221 | // purpose : Builds set of triangular selecting frustums for polyline |
222 | // selection |
223 | //======================================================================= |
224 | void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints) |
225 | { |
226 | if (myActiveSelectionType != Polyline) |
227 | return; |
228 | |
229 | mySelectingVolumes[FrustumSet]->Build (thePoints); |
230 | } |
231 | |
232 | //======================================================================= |
233 | // function : Overlaps |
234 | // purpose : SAT intersection test between defined volume and |
235 | // given axis-aligned box |
236 | //======================================================================= |
3bf9a45f |
237 | Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin, |
238 | const SelectMgr_Vec3& theBoxMax, |
7ab15952 |
239 | Standard_Real& theDepth) |
f751596e |
240 | { |
241 | if (myActiveSelectionType == Unknown) |
242 | return Standard_False; |
243 | |
3bf9a45f |
244 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theDepth); |
f751596e |
245 | } |
246 | |
247 | //======================================================================= |
248 | // function : Overlaps |
249 | // purpose : Intersection test between defined volume and given point |
250 | //======================================================================= |
2157d6ac |
251 | Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin, |
252 | const SelectMgr_Vec3& theBoxMax, |
253 | Standard_Boolean* theInside) |
f751596e |
254 | { |
255 | if (myActiveSelectionType == Unknown) |
256 | return Standard_False; |
257 | |
2157d6ac |
258 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theInside); |
f751596e |
259 | } |
260 | |
261 | //======================================================================= |
262 | // function : Overlaps |
263 | // purpose : Intersection test between defined volume and given point |
264 | //======================================================================= |
3bf9a45f |
265 | Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt, |
7ab15952 |
266 | Standard_Real& theDepth) |
f751596e |
267 | { |
268 | if (myActiveSelectionType == Unknown) |
269 | return Standard_False; |
270 | |
3bf9a45f |
271 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt, |
f751596e |
272 | theDepth); |
273 | } |
274 | |
3bf9a45f |
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) |
280 | { |
281 | if (myActiveSelectionType == Unknown) |
282 | return Standard_False; |
283 | |
284 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt); |
285 | } |
286 | |
f751596e |
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 | //======================================================================= |
3bf9a45f |
294 | Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, |
7ab15952 |
295 | Standard_Integer theSensType, |
296 | Standard_Real& theDepth) |
f751596e |
297 | { |
298 | if (myActiveSelectionType == Unknown) |
299 | return Standard_False; |
300 | |
114b7bf1 |
301 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts->Array1(), |
302 | (Select3D_TypeOfSensitivity)theSensType, |
303 | theDepth); |
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 | //======================================================================= |
313 | Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts, |
314 | Standard_Integer theSensType, |
315 | Standard_Real& theDepth) |
316 | { |
317 | if (myActiveSelectionType == Unknown) |
318 | return Standard_False; |
319 | |
3bf9a45f |
320 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts, |
f751596e |
321 | (Select3D_TypeOfSensitivity)theSensType, |
322 | theDepth); |
323 | } |
324 | |
325 | //======================================================================= |
326 | // function : Overlaps |
327 | // purpose : Checks if line segment overlaps selecting volume |
328 | //======================================================================= |
7ab15952 |
329 | Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1, |
330 | const gp_Pnt& thePt2, |
331 | Standard_Real& theDepth) |
f751596e |
332 | { |
333 | if (myActiveSelectionType == Unknown) |
334 | return Standard_False; |
335 | |
336 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, theDepth); |
337 | } |
338 | |
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 | //======================================================================= |
7ab15952 |
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) |
f751596e |
351 | { |
352 | if (myActiveSelectionType == Unknown) |
353 | return Standard_False; |
354 | |
355 | return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, |
356 | thePt2, |
357 | thePt3, |
358 | (Select3D_TypeOfSensitivity)theSensType, |
359 | theDepth); |
360 | } |
361 | |
362 | //======================================================================= |
363 | // function : DistToGeometryCenter |
364 | // purpose : Measures distance between 3d projection of user-picked |
365 | // screen point and given point theCOG |
366 | //======================================================================= |
7ab15952 |
367 | Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_Pnt& theCOG) |
f751596e |
368 | { |
369 | if (myActiveSelectionType == Unknown) |
370 | return Standard_False; |
371 | |
372 | return mySelectingVolumes[myActiveSelectionType / 2]->DistToGeometryCenter (theCOG); |
373 | } |
374 | |
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 |
379 | // selection only |
380 | // ======================================================================= |
3bf9a45f |
381 | gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const |
f751596e |
382 | { |
383 | if (myActiveSelectionType != Point) |
949c9b7f |
384 | { |
9775fa61 |
385 | throw Standard_ProgramError("SelectMgr_SelectingVolumeManager::DetectedPoint() should be called only for Point selection type"); |
949c9b7f |
386 | } |
f751596e |
387 | |
388 | return mySelectingVolumes[Frustum]->DetectedPoint (theDepth); |
389 | } |
390 | |
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 | //======================================================================= |
7ab15952 |
396 | Standard_Boolean SelectMgr_SelectingVolumeManager::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes, |
397 | const Standard_Real& theDepth) |
f751596e |
398 | { |
e9312c0f |
399 | if (myActiveSelectionType != Point) |
f751596e |
400 | return Standard_False; |
401 | |
402 | return mySelectingVolumes[Frustum]->IsClipped (thePlanes, theDepth); |
403 | } |
2157d6ac |
404 | |
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) |
412 | { |
413 | myToAllowOverlap = theIsToAllow; |
414 | } |
415 | |
416 | //======================================================================= |
417 | // function : IsOverlapAllowed |
418 | // purpose : |
419 | //======================================================================= |
420 | Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const |
421 | { |
422 | return myActiveSelectionType != Box || myToAllowOverlap; |
423 | } |
3bf9a45f |
424 | |
425 | //======================================================================= |
426 | // function : GetVertices |
427 | // purpose : |
428 | //======================================================================= |
429 | const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const |
430 | { |
431 | if (myActiveSelectionType == Polyline) |
432 | return NULL; |
433 | |
434 | const SelectMgr_RectangularFrustum* aFr = |
435 | reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get()); |
436 | return aFr->GetVertices(); |
437 | } |
438 | |
439 | //======================================================================= |
21a8e275 |
440 | // function : GetNearPickedPnt |
3bf9a45f |
441 | // purpose : |
442 | //======================================================================= |
21a8e275 |
443 | gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPickedPnt() const |
3bf9a45f |
444 | { |
445 | if (myActiveSelectionType == Polyline) |
446 | return gp_Pnt(); |
447 | |
448 | const SelectMgr_RectangularFrustum* aFr = |
449 | reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get()); |
450 | return aFr->GetNearPnt(); |
451 | } |
452 | |
453 | //======================================================================= |
21a8e275 |
454 | // function : GetFarPickedPnt |
3bf9a45f |
455 | // purpose : |
456 | //======================================================================= |
21a8e275 |
457 | gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPickedPnt() const |
3bf9a45f |
458 | { |
459 | if (myActiveSelectionType == Polyline) |
460 | return gp_Pnt(); |
461 | |
462 | const SelectMgr_RectangularFrustum* aFr = |
463 | reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get()); |
464 | return aFr->GetFarPnt(); |
465 | } |
e9312c0f |
466 | |
467 | //======================================================================= |
468 | // function : SetViewClipping |
469 | // purpose : |
470 | //======================================================================= |
3202bf1e |
471 | void SelectMgr_SelectingVolumeManager::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) |
e9312c0f |
472 | { |
8b1441e3 |
473 | myViewClipPlanes = thePlanes; |
e9312c0f |
474 | if (myActiveSelectionType != Point) |
475 | return; |
476 | |
477 | mySelectingVolumes[Frustum]->SetViewClipping (thePlanes); |
478 | } |
3202bf1e |
479 | |
480 | //======================================================================= |
481 | // function : SetViewClippingEnabled |
482 | // purpose : |
483 | //======================================================================= |
484 | Standard_Boolean SelectMgr_SelectingVolumeManager::SetViewClippingEnabled (const Standard_Boolean theToEnable) |
485 | { |
486 | if (myActiveSelectionType != Point) |
487 | return Standard_False; |
488 | |
489 | return mySelectingVolumes[Frustum]->SetViewClippingEnabled (theToEnable); |
490 | } |