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