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