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