b311480e |
1 | // Created on: 1995-02-15 |
2 | // Created by: Roberc Coublanc |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
aa75c0cf |
17 | #include <SelectMgr_ViewerSelector.hxx> |
7fd59977 |
18 | |
f751596e |
19 | #include <BVH_Tree.hxx> |
91d96372 |
20 | #include <gp_GTrsf.hxx> |
7fd59977 |
21 | #include <gp_Pnt.hxx> |
f751596e |
22 | #include <OSD_Environment.hxx> |
7fd59977 |
23 | #include <Precision.hxx> |
0ef04197 |
24 | #include <Select3D_SensitiveEntity.hxx> |
f751596e |
25 | #include <SelectBasics_PickResult.hxx> |
26 | #include <SelectMgr_EntityOwner.hxx> |
7fd59977 |
27 | #include <SelectMgr_SortCriterion.hxx> |
f751596e |
28 | #include <SelectMgr_SensitiveEntitySet.hxx> |
f751596e |
29 | #include <TColStd_Array1OfInteger.hxx> |
30 | #include <TCollection_AsciiString.hxx> |
31 | #include <TColStd_HArray1OfInteger.hxx> |
32 | #include <TColStd_ListOfInteger.hxx> |
33 | |
e35db416 |
34 | #include <algorithm> |
35 | |
f5b72419 |
36 | IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient) |
92efcf78 |
37 | |
e35db416 |
38 | namespace { |
39 | // Comparison operator for sorting selection results |
40 | class CompareResults |
41 | { |
42 | public: |
43 | |
44 | CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion) |
45 | : myMapOfCriterion (aMapOfCriterion) |
46 | { |
47 | } |
48 | |
49 | Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const |
50 | { |
51 | return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight); |
52 | } |
53 | |
54 | private: |
55 | void operator = (const CompareResults&); |
56 | |
57 | private: |
58 | const SelectMgr_IndexedDataMapOfOwnerCriterion& myMapOfCriterion; |
59 | }; |
f751596e |
60 | |
fe76088c |
61 | static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT; |
62 | } |
63 | |
64 | //======================================================================= |
65 | // function : updatePoint3d |
66 | // purpose : |
67 | //======================================================================= |
68 | void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion, |
17017555 |
69 | const SelectBasics_PickResult& thePickResult, |
0ef04197 |
70 | const Handle(Select3D_SensitiveEntity)& theEntity, |
fe76088c |
71 | const gp_GTrsf& theInversedTrsf, |
72 | const SelectMgr_SelectingVolumeManager& theMgr) const |
73 | { |
74 | if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point) |
4269bd1b |
75 | { |
fe76088c |
76 | return; |
77 | } |
949c9b7f |
78 | |
17017555 |
79 | if (thePickResult.HasPickedPoint()) |
80 | { |
81 | theCriterion.Point = thePickResult.PickedPoint(); |
82 | } |
b44bf0f8 |
83 | else if (!thePickResult.IsValid()) |
84 | { |
85 | theCriterion.Point = thePickResult.PickedPoint(); |
86 | return; |
87 | } |
17017555 |
88 | else |
89 | { |
90 | theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth); |
91 | } |
92 | |
fe76088c |
93 | gp_GTrsf anInvTrsf = theInversedTrsf; |
94 | if (theCriterion.Entity->HasInitLocation()) |
95 | { |
96 | anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf; |
97 | } |
98 | if (anInvTrsf.Form() != gp_Identity) |
99 | { |
100 | anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord()); |
f751596e |
101 | } |
aa75c0cf |
102 | |
fe76088c |
103 | if (mySelectingVolumeMgr.Camera().IsNull()) |
104 | { |
105 | theCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0; |
106 | } |
107 | else if (mySelectingVolumeMgr.Camera()->IsOrthographic()) |
108 | { |
109 | theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor(); |
110 | } |
111 | else |
112 | { |
b44bf0f8 |
113 | const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ())); |
fe76088c |
114 | theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor(); |
115 | } |
f751596e |
116 | } |
117 | |
7fd59977 |
118 | //================================================== |
119 | // Function: Initialize |
120 | // Purpose : |
121 | //================================================== |
122 | SelectMgr_ViewerSelector::SelectMgr_ViewerSelector(): |
7fd59977 |
123 | preferclosest(Standard_True), |
f751596e |
124 | myToUpdateTolerance (Standard_True), |
fe76088c |
125 | myCameraScale (1.0), |
f751596e |
126 | myCurRank (0), |
127 | myIsLeftChildQueuedFirst (Standard_False), |
128 | myEntityIdx (0) |
7fd59977 |
129 | { |
f5b72419 |
130 | myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True); |
7fd59977 |
131 | } |
132 | |
7fd59977 |
133 | //================================================== |
134 | // Function: Activate |
135 | // Purpose : |
136 | //================================================== |
f751596e |
137 | void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection) |
7fd59977 |
138 | { |
b5cce1ab |
139 | for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next()) |
7fd59977 |
140 | { |
b5cce1ab |
141 | aSelEntIter.Value()->SetActiveForSelection(); |
4269bd1b |
142 | } |
7fd59977 |
143 | |
82d23ad5 |
144 | if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated) |
145 | { |
146 | theSelection->SetSelectionState (SelectMgr_SOS_Activated); |
7fd59977 |
147 | |
82d23ad5 |
148 | myTolerances.Add (theSelection->Sensitivity()); |
149 | myToUpdateTolerance = Standard_True; |
150 | } |
7fd59977 |
151 | } |
152 | |
7fd59977 |
153 | //================================================== |
f751596e |
154 | // Function: Deactivate |
7fd59977 |
155 | // Purpose : |
156 | //================================================== |
f751596e |
157 | void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection) |
4269bd1b |
158 | { |
b5cce1ab |
159 | for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next()) |
f751596e |
160 | { |
b5cce1ab |
161 | aSelEntIter.Value()->ResetSelectionActiveStatus(); |
7fd59977 |
162 | } |
7fd59977 |
163 | |
82d23ad5 |
164 | if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated) |
165 | { |
166 | theSelection->SetSelectionState (SelectMgr_SOS_Deactivated); |
7fd59977 |
167 | |
82d23ad5 |
168 | myTolerances.Decrement (theSelection->Sensitivity()); |
169 | myToUpdateTolerance = Standard_True; |
170 | } |
7fd59977 |
171 | } |
172 | |
7fd59977 |
173 | //================================================== |
174 | // Function: Clear |
175 | // Purpose : |
176 | //================================================== |
177 | void SelectMgr_ViewerSelector::Clear() |
178 | { |
7fd59977 |
179 | mystored.Clear(); |
7fd59977 |
180 | } |
181 | |
28ee613b |
182 | //======================================================================= |
183 | // function: isToScaleFrustum |
184 | // purpose : Checks if the entity given requires to scale current selecting frustum |
185 | //======================================================================= |
0ef04197 |
186 | Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity) |
28ee613b |
187 | { |
188 | return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point |
29a4908e |
189 | && sensitivity (theEntity) < myTolerances.Tolerance(); |
28ee613b |
190 | } |
191 | |
29a4908e |
192 | //======================================================================= |
193 | // function: sensitivity |
194 | // purpose : In case if custom tolerance is set, this method will return sum of entity |
195 | // sensitivity and custom tolerance. |
196 | //======================================================================= |
0ef04197 |
197 | Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(Select3D_SensitiveEntity)& theEntity) const |
29a4908e |
198 | { |
199 | return myTolerances.IsCustomTolSet() ? |
200 | theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor(); |
201 | } |
202 | |
f751596e |
203 | //======================================================================= |
204 | // function: checkOverlap |
205 | // purpose : Internal function that checks if a particular sensitive |
206 | // entity theEntity overlaps current selecting volume precisely |
207 | //======================================================================= |
0ef04197 |
208 | void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEntity)& theEntity, |
aa75c0cf |
209 | const gp_GTrsf& theInversedTrsf, |
f751596e |
210 | SelectMgr_SelectingVolumeManager& theMgr) |
7fd59977 |
211 | { |
0ef04197 |
212 | const Handle(SelectMgr_EntityOwner)& anOwner = theEntity->OwnerId(); |
3202bf1e |
213 | Handle(SelectMgr_SelectableObject) aSelectable; |
214 | Standard_Boolean toRestoresViewClipEnabled = Standard_False; |
215 | if (!anOwner.IsNull()) |
216 | { |
217 | aSelectable = anOwner->Selectable(); |
b1c235df |
218 | } |
219 | if (!aSelectable.IsNull()) |
220 | { |
8b1441e3 |
221 | if (!aSelectable->ClipPlanes().IsNull() |
222 | && aSelectable->ClipPlanes()->ToOverrideGlobal()) |
3202bf1e |
223 | { |
224 | theMgr.SetViewClippingEnabled (Standard_False); |
225 | toRestoresViewClipEnabled = Standard_True; |
226 | } |
8b1441e3 |
227 | else if (!aSelectable->TransformPersistence().IsNull()) |
228 | { |
229 | if (aSelectable->TransformPersistence()->IsZoomOrRotate() |
230 | && !theMgr.ViewClipping().IsNull()) |
231 | { |
232 | // Zoom/rotate persistence object lives in two worlds at the same time. |
233 | // Global clipping planes can not be trivially applied without being converted |
234 | // into local space of transformation persistence object. |
235 | // As more simple alternative - just clip entire object by its anchor point defined in the world space. |
236 | const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping(); |
237 | |
238 | const gp_Pnt anAnchor = aSelectable->TransformPersistence()->AnchorPoint(); |
239 | for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next()) |
240 | { |
241 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); |
242 | if (!aPlane->IsOn()) |
243 | { |
244 | continue; |
245 | } |
246 | |
25c35042 |
247 | const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0); |
248 | if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out) |
8b1441e3 |
249 | { |
250 | return; |
251 | } |
252 | } |
253 | } |
254 | |
255 | theMgr.SetViewClippingEnabled (Standard_False); |
256 | toRestoresViewClipEnabled = Standard_True; |
257 | } |
3202bf1e |
258 | } |
7fd59977 |
259 | |
f751596e |
260 | SelectBasics_PickResult aPickResult; |
3202bf1e |
261 | const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult); |
262 | if (toRestoresViewClipEnabled) |
f751596e |
263 | { |
3202bf1e |
264 | theMgr.SetViewClippingEnabled (Standard_True); |
265 | } |
7fd59977 |
266 | |
3202bf1e |
267 | if (!isMatched |
268 | || anOwner.IsNull()) |
269 | { |
270 | return; |
271 | } |
272 | |
273 | if (HasDepthClipping (anOwner) |
b1c235df |
274 | && !aSelectable.IsNull() |
3202bf1e |
275 | && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point) |
276 | { |
277 | Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(), |
278 | aPickResult.Depth()); |
279 | if (isClipped) |
280 | return; |
281 | } |
282 | |
283 | SelectMgr_SortCriterion aCriterion; |
b1c235df |
284 | myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition); |
3202bf1e |
285 | aCriterion.Entity = theEntity; |
286 | aCriterion.Priority = anOwner->Priority(); |
287 | aCriterion.Depth = aPickResult.Depth(); |
288 | aCriterion.MinDist = aPickResult.DistToGeomCenter(); |
3202bf1e |
289 | aCriterion.ToPreferClosest = preferclosest; |
290 | |
be7fc29e |
291 | if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner)) |
3202bf1e |
292 | { |
be7fc29e |
293 | ++aPrevCriterion->NbOwnerMatches; |
294 | aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches; |
3202bf1e |
295 | if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box) |
296 | { |
be7fc29e |
297 | if (aCriterion > *aPrevCriterion) |
f751596e |
298 | { |
17017555 |
299 | updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr); |
be7fc29e |
300 | *aPrevCriterion = aCriterion; |
7fd59977 |
301 | } |
302 | } |
7fd59977 |
303 | } |
3202bf1e |
304 | else |
305 | { |
be7fc29e |
306 | aCriterion.NbOwnerMatches = 1; |
17017555 |
307 | updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr); |
3202bf1e |
308 | mystored.Add (anOwner, aCriterion); |
309 | } |
7fd59977 |
310 | } |
311 | |
3bf9a45f |
312 | //======================================================================= |
313 | // function: computeFrustum |
314 | // purpose : Internal function that checks if a current selecting frustum |
315 | // needs to be scaled and transformed for the entity and performs |
316 | // necessary calculations |
317 | //======================================================================= |
0ef04197 |
318 | void SelectMgr_ViewerSelector::computeFrustum (const Handle(Select3D_SensitiveEntity)& theEnt, |
099f3513 |
319 | const SelectMgr_SelectingVolumeManager& theMgr, |
91d96372 |
320 | const gp_GTrsf& theInvTrsf, |
3bf9a45f |
321 | SelectMgr_FrustumCache& theCachedMgrs, |
322 | SelectMgr_SelectingVolumeManager& theResMgr) |
323 | { |
7479f643 |
324 | Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1; |
91d96372 |
325 | const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf; |
7479f643 |
326 | const Standard_Boolean toScale = aScale != 1; |
327 | const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity; |
328 | if (toScale && toTransform) |
3bf9a45f |
329 | { |
099f3513 |
330 | theResMgr = theMgr.ScaleAndTransform (aScale, aTrsfMtr, NULL); |
3bf9a45f |
331 | } |
332 | else if (toScale) |
333 | { |
334 | if (!theCachedMgrs.IsBound (aScale)) |
335 | { |
099f3513 |
336 | theCachedMgrs.Bind (aScale, theMgr.ScaleAndTransform (aScale, gp_Trsf(), NULL)); |
3bf9a45f |
337 | } |
3bf9a45f |
338 | theResMgr = theCachedMgrs.Find (aScale); |
339 | } |
7479f643 |
340 | else if (toTransform) |
341 | { |
099f3513 |
342 | theResMgr = theMgr.ScaleAndTransform (1, aTrsfMtr, NULL); |
7479f643 |
343 | } |
3bf9a45f |
344 | } |
345 | |
f751596e |
346 | //======================================================================= |
347 | // function: traverseObject |
348 | // purpose : Internal function that checks if there is possible overlap |
349 | // between some entity of selectable object theObject and |
350 | // current selecting volume |
351 | //======================================================================= |
099f3513 |
352 | void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject, |
353 | const SelectMgr_SelectingVolumeManager& theMgr, |
354 | const Handle(Graphic3d_Camera)& theCamera, |
355 | const Graphic3d_Mat4d& theProjectionMat, |
356 | const Graphic3d_Mat4d& theWorldViewMat, |
357 | const Standard_Integer theViewportWidth, |
358 | const Standard_Integer theViewportHeight) |
7fd59977 |
359 | { |
f5b72419 |
360 | Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject); |
f751596e |
361 | if (anEntitySet->Size() == 0) |
f5b72419 |
362 | { |
f751596e |
363 | return; |
f5b72419 |
364 | } |
7fd59977 |
365 | |
f5b72419 |
366 | const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH(); |
91d96372 |
367 | gp_GTrsf aInversedTrsf; |
778cd667 |
368 | if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull()) |
825aa485 |
369 | { |
778cd667 |
370 | if (theObject->TransformPersistence().IsNull()) |
825aa485 |
371 | { |
372 | aInversedTrsf = theObject->InversedTransformation(); |
373 | } |
374 | else |
375 | { |
91d96372 |
376 | gp_GTrsf aTPers; |
778cd667 |
377 | Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight); |
099f3513 |
378 | |
91d96372 |
379 | aTPers.SetValue (1, 1, aMat.GetValue (0, 0)); |
380 | aTPers.SetValue (1, 2, aMat.GetValue (0, 1)); |
381 | aTPers.SetValue (1, 3, aMat.GetValue (0, 2)); |
382 | aTPers.SetValue (2, 1, aMat.GetValue (1, 0)); |
383 | aTPers.SetValue (2, 2, aMat.GetValue (1, 1)); |
384 | aTPers.SetValue (2, 3, aMat.GetValue (1, 2)); |
385 | aTPers.SetValue (3, 1, aMat.GetValue (2, 0)); |
386 | aTPers.SetValue (3, 2, aMat.GetValue (2, 1)); |
387 | aTPers.SetValue (3, 3, aMat.GetValue (2, 2)); |
388 | aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3))); |
389 | |
390 | aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted(); |
825aa485 |
391 | } |
392 | } |
393 | |
394 | SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity |
099f3513 |
395 | ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL) |
396 | : theMgr; |
7fd59977 |
397 | |
3bf9a45f |
398 | SelectMgr_FrustumCache aScaledTrnsfFrustums; |
28ee613b |
399 | |
f751596e |
400 | Standard_Integer aNode = 0; // a root node |
401 | if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0), |
402 | aSensitivesTree->MaxPoint (0))) |
403 | { |
404 | return; |
7fd59977 |
405 | } |
be7fc29e |
406 | |
407 | const Standard_Integer aFirstStored = mystored.Extent() + 1; |
408 | |
f5b72419 |
409 | Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; |
f751596e |
410 | Standard_Integer aHead = -1; |
411 | for (;;) |
412 | { |
413 | if (!aSensitivesTree->IsOuter (aNode)) |
414 | { |
f2474958 |
415 | const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode); |
416 | const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode); |
f751596e |
417 | const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx), |
418 | aSensitivesTree->MaxPoint (aLeftChildIdx)); |
419 | const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx), |
420 | aSensitivesTree->MaxPoint (aRightChildIdx)); |
421 | if (isLeftChildIn |
422 | && isRightChildIn) |
423 | { |
424 | aNode = aLeftChildIdx; |
425 | ++aHead; |
426 | aStack[aHead] = aRightChildIdx; |
427 | } |
428 | else if (isLeftChildIn |
429 | || isRightChildIn) |
430 | { |
431 | aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; |
432 | } |
433 | else |
434 | { |
435 | if (aHead < 0) |
436 | { |
437 | break; |
438 | } |
7fd59977 |
439 | |
f751596e |
440 | aNode = aStack[aHead]; |
441 | --aHead; |
442 | } |
443 | } |
444 | else |
445 | { |
446 | Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode); |
447 | Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode); |
448 | for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) |
449 | { |
be7fc29e |
450 | const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx); |
f751596e |
451 | if (aSensitive->IsActiveForSelection()) |
452 | { |
0ef04197 |
453 | const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive(); |
28ee613b |
454 | SelectMgr_SelectingVolumeManager aTmpMgr = aMgr; |
099f3513 |
455 | computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr); |
aa75c0cf |
456 | checkOverlap (anEnt, aInversedTrsf, aTmpMgr); |
f751596e |
457 | } |
458 | } |
459 | if (aHead < 0) |
460 | { |
461 | break; |
462 | } |
7fd59977 |
463 | |
f751596e |
464 | aNode = aStack[aHead]; |
465 | --aHead; |
466 | } |
7fd59977 |
467 | } |
be7fc29e |
468 | |
469 | // in case of Box/Polyline selection - keep only Owners having all Entities detected |
470 | if (mySelectingVolumeMgr.IsOverlapAllowed() |
471 | || (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box |
472 | && theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline)) |
473 | { |
474 | return; |
475 | } |
476 | |
477 | for (Standard_Integer aStoredIter = mystored.Extent(); aStoredIter >= aFirstStored; --aStoredIter) |
478 | { |
479 | const SelectMgr_SortCriterion& aCriterion = mystored.FindFromIndex (aStoredIter); |
0ef04197 |
480 | const Handle(SelectMgr_EntityOwner)& anOwner = aCriterion.Entity->OwnerId(); |
be7fc29e |
481 | Standard_Integer aNbOwnerEntities = 0; |
482 | for (SelectMgr_IndexedMapOfHSensitive::Iterator aSensIter (anEntitySet->Sensitives()); aSensIter.More(); aSensIter.Next()) |
483 | { |
484 | if (aSensIter.Value()->BaseSensitive()->OwnerId() == anOwner) |
485 | { |
486 | if (++aNbOwnerEntities > aCriterion.NbOwnerMatches) |
487 | { |
488 | // Remove from index map. |
489 | // Considering NCollection_IndexedDataMap implementation, the values for lower indexes will not be modified. |
490 | // Hence, just keep iterating in backward direction. |
491 | mystored.RemoveFromIndex (aStoredIter); |
492 | break; |
493 | } |
494 | } |
495 | } |
496 | } |
7fd59977 |
497 | } |
498 | |
f751596e |
499 | //======================================================================= |
500 | // function: TraverseSensitives |
501 | // purpose : Traverses BVH containing all added selectable objects and |
502 | // finds candidates for further search of overlap |
503 | //======================================================================= |
504 | void SelectMgr_ViewerSelector::TraverseSensitives() |
7fd59977 |
505 | { |
506 | mystored.Clear(); |
507 | |
099f3513 |
508 | Standard_Integer aWidth; |
509 | Standard_Integer aHeight; |
510 | mySelectingVolumeMgr.WindowSize (aWidth, aHeight); |
511 | mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(), |
512 | mySelectingVolumeMgr.ProjectionMatrix(), |
513 | mySelectingVolumeMgr.WorldViewMatrix(), |
514 | mySelectingVolumeMgr.WorldViewProjState(), |
515 | aWidth, aHeight); |
fe76088c |
516 | const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera(); |
517 | if (!aCamera.IsNull()) |
518 | { |
519 | myCameraEye = aCamera->Eye().XYZ(); |
520 | myCameraDir = aCamera->Direction().XYZ(); |
521 | myCameraScale = aCamera->IsOrthographic() |
522 | ? aCamera->Scale() |
523 | : 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0); |
524 | const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight); |
525 | myCameraScale *= aPixelSize; |
526 | } |
099f3513 |
527 | |
528 | for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt) |
f751596e |
529 | { |
099f3513 |
530 | SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset = |
531 | static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt); |
532 | |
533 | if (mySelectableObjects.IsEmpty (aBVHSubset)) |
4269bd1b |
534 | { |
099f3513 |
535 | continue; |
536 | } |
537 | |
538 | gp_GTrsf aTFrustum; |
539 | |
540 | SelectMgr_SelectingVolumeManager aMgr (Standard_False); |
541 | |
542 | // for 2D space selection transform selecting volumes to perform overap testing |
543 | // directly in camera's eye space omitting the camera position, which is not |
544 | // needed there at all |
545 | if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent) |
546 | { |
547 | const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix(); |
548 | aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0)); |
549 | aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1)); |
550 | aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2)); |
551 | aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0)); |
552 | aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1)); |
553 | aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2)); |
554 | aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0)); |
555 | aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1)); |
556 | aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2)); |
557 | aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3))); |
558 | |
559 | // define corresponding frustum builder parameters |
560 | Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder(); |
561 | aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix()); |
896faa72 |
562 | aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT); |
099f3513 |
563 | aBuilder->SetWindowSize (aWidth, aHeight); |
564 | aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder); |
825aa485 |
565 | } |
566 | else |
567 | { |
099f3513 |
568 | aMgr = mySelectingVolumeMgr; |
825aa485 |
569 | } |
570 | |
099f3513 |
571 | const Graphic3d_Mat4d& aProjectionMat = mySelectingVolumeMgr.ProjectionMatrix(); |
572 | const Graphic3d_Mat4d& aWorldViewMat = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent |
573 | ? mySelectingVolumeMgr.WorldViewMatrix() |
896faa72 |
574 | : SelectMgr_ViewerSelector_THE_IDENTITY_MAT; |
099f3513 |
575 | |
f5b72419 |
576 | const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset); |
099f3513 |
577 | |
825aa485 |
578 | Standard_Integer aNode = 0; |
099f3513 |
579 | if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0))) |
825aa485 |
580 | { |
581 | continue; |
582 | } |
583 | |
f5b72419 |
584 | Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; |
825aa485 |
585 | Standard_Integer aHead = -1; |
586 | for (;;) |
587 | { |
588 | if (!aBVHTree->IsOuter (aNode)) |
589 | { |
f2474958 |
590 | const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode); |
591 | const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode); |
825aa485 |
592 | const Standard_Boolean isLeftChildIn = |
099f3513 |
593 | aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx)); |
825aa485 |
594 | const Standard_Boolean isRightChildIn = |
099f3513 |
595 | aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx)); |
825aa485 |
596 | if (isLeftChildIn |
597 | && isRightChildIn) |
598 | { |
599 | aNode = aLeftChildIdx; |
600 | ++aHead; |
601 | aStack[aHead] = aRightChildIdx; |
602 | } |
603 | else if (isLeftChildIn |
604 | || isRightChildIn) |
605 | { |
606 | aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; |
607 | } |
608 | else |
609 | { |
610 | if (aHead < 0) |
611 | { |
612 | break; |
613 | } |
614 | |
615 | aNode = aStack[aHead]; |
616 | --aHead; |
617 | } |
f751596e |
618 | } |
619 | else |
620 | { |
825aa485 |
621 | Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode); |
622 | Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode); |
623 | for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) |
624 | { |
099f3513 |
625 | const Handle(SelectMgr_SelectableObject)& aSelectableObject = |
626 | mySelectableObjects.GetObjectById (aBVHSubset, anIdx); |
825aa485 |
627 | |
099f3513 |
628 | traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight); |
825aa485 |
629 | } |
f751596e |
630 | if (aHead < 0) |
4269bd1b |
631 | { |
f751596e |
632 | break; |
4269bd1b |
633 | } |
7fd59977 |
634 | |
f751596e |
635 | aNode = aStack[aHead]; |
636 | --aHead; |
7fd59977 |
637 | } |
638 | } |
7fd59977 |
639 | } |
4269bd1b |
640 | |
f751596e |
641 | SortResult(); |
7fd59977 |
642 | } |
4269bd1b |
643 | |
8a590580 |
644 | //================================================== |
645 | // Function: ClearPicked |
646 | // Purpose : |
647 | //================================================== |
648 | void SelectMgr_ViewerSelector::ClearPicked() |
649 | { |
650 | mystored.Clear(); |
651 | } |
652 | |
7fd59977 |
653 | //================================================== |
654 | // Function: Picked |
655 | // Purpose : |
656 | //================================================== |
0ef04197 |
657 | Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked() const |
7fd59977 |
658 | { |
0ef04197 |
659 | const Standard_Integer aRankInMap = myIndexes->Value (myCurRank); |
660 | const Handle(SelectMgr_EntityOwner)& anOwner = mystored.FindKey (aRankInMap); |
661 | return anOwner; |
7fd59977 |
662 | } |
663 | |
7fd59977 |
664 | //======================================================================= |
aa75c0cf |
665 | //function : Picked |
4269bd1b |
666 | //purpose : |
7fd59977 |
667 | //======================================================================= |
aa75c0cf |
668 | Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const |
7fd59977 |
669 | { |
aa75c0cf |
670 | if (theRank < 1 || theRank > NbPicked()) |
671 | { |
0ef04197 |
672 | return Handle(SelectMgr_EntityOwner)(); |
7fd59977 |
673 | } |
674 | |
aa75c0cf |
675 | const Standard_Integer anOwnerIdx = myIndexes->Value (theRank); |
0ef04197 |
676 | const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx); |
677 | return aStoredOwner; |
7fd59977 |
678 | } |
679 | |
7fd59977 |
680 | //======================================================================= |
aa75c0cf |
681 | //function : PickedData |
4269bd1b |
682 | //purpose : |
7fd59977 |
683 | //======================================================================= |
aa75c0cf |
684 | const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const |
7fd59977 |
685 | { |
aa75c0cf |
686 | Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index"); |
687 | const Standard_Integer anOwnerIdx = myIndexes->Value (theRank); |
688 | return mystored.FindFromIndex (anOwnerIdx); |
7fd59977 |
689 | } |
690 | |
7fd59977 |
691 | //=================================================== |
692 | // |
693 | // INTERNAL METHODS .... |
694 | // |
695 | //================================================== |
696 | |
f5b72419 |
697 | //================================================== |
698 | // Function: SetEntitySetBuilder |
699 | // Purpose : |
700 | //================================================== |
701 | void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) |
702 | { |
703 | myEntitySetBuilder = theBuilder; |
704 | for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next()) |
705 | { |
706 | aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder); |
707 | } |
708 | } |
709 | |
7fd59977 |
710 | //================================================== |
711 | // Function: Contains |
4269bd1b |
712 | // Purpose : |
7fd59977 |
713 | //================================================== |
f751596e |
714 | Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const |
7fd59977 |
715 | { |
099f3513 |
716 | return mySelectableObjects.Contains (theObject); |
7fd59977 |
717 | } |
718 | |
7fd59977 |
719 | //================================================== |
720 | // Function: ActiveModes |
721 | // Purpose : return all the modes with a given state for an object |
722 | //================================================== |
f751596e |
723 | Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
724 | TColStd_ListOfInteger& theModeList, |
725 | const SelectMgr_StateOfSelection theWantedState) const |
7fd59977 |
726 | { |
825aa485 |
727 | Standard_Boolean hasActivatedStates = Contains (theSelectableObject); |
b5cce1ab |
728 | for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next()) |
f751596e |
729 | { |
82d23ad5 |
730 | if (theWantedState == SelectMgr_SOS_Any) |
731 | { |
732 | theModeList.Append (aSelIter.Value()->Mode()); |
733 | } |
734 | else if (theWantedState == aSelIter.Value()->GetSelectionState()) |
735 | { |
736 | theModeList.Append (aSelIter.Value()->Mode()); |
737 | } |
7fd59977 |
738 | } |
7fd59977 |
739 | |
f751596e |
740 | return hasActivatedStates; |
741 | } |
7fd59977 |
742 | |
f751596e |
743 | //================================================== |
744 | // Function: IsActive |
745 | // Purpose : |
746 | //================================================== |
747 | Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
748 | const Standard_Integer theMode) const |
7fd59977 |
749 | { |
825aa485 |
750 | if (!Contains (theSelectableObject)) |
f751596e |
751 | return Standard_False; |
752 | |
b5cce1ab |
753 | const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode); |
754 | return !aSel.IsNull() |
755 | && aSel->GetSelectionState() == SelectMgr_SOS_Activated; |
7fd59977 |
756 | } |
757 | |
f751596e |
758 | //================================================== |
759 | // Function: IsInside |
760 | // Purpose : |
761 | //================================================== |
762 | Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
763 | const Standard_Integer theMode) const |
7fd59977 |
764 | { |
825aa485 |
765 | if (!Contains (theSelectableObject)) |
f751596e |
766 | return Standard_False; |
7fd59977 |
767 | |
b5cce1ab |
768 | const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode); |
769 | return !aSel.IsNull() |
770 | && aSel->GetSelectionState() != SelectMgr_SOS_Unknown; |
7fd59977 |
771 | } |
772 | |
773 | |
774 | //======================================================================= |
775 | //function : Status |
4269bd1b |
776 | //purpose : |
7fd59977 |
777 | //======================================================================= |
778 | |
f751596e |
779 | SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const |
7fd59977 |
780 | { |
f751596e |
781 | return theSelection->GetSelectionState(); |
7fd59977 |
782 | } |
783 | |
7fd59977 |
784 | //================================================== |
785 | // Function: Status |
786 | // Purpose : gives Information about selectors |
787 | //================================================== |
788 | |
f751596e |
789 | TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const |
7fd59977 |
790 | { |
f751596e |
791 | TCollection_AsciiString aStatus ("Status Object :\n\t"); |
b5cce1ab |
792 | for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next()) |
f751596e |
793 | { |
b5cce1ab |
794 | if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown) |
7fd59977 |
795 | { |
b5cce1ab |
796 | aStatus = aStatus + "Mode " + TCollection_AsciiString (aSelIter.Value()->Mode()) + " present - " |
797 | + (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" : " Inactive \n\t"); |
7fd59977 |
798 | } |
799 | } |
800 | |
825aa485 |
801 | if (!Contains (theSelectableObject)) |
7fd59977 |
802 | { |
f751596e |
803 | aStatus = aStatus + "Not Present in the selector\n\n"; |
7fd59977 |
804 | } |
f751596e |
805 | |
806 | return aStatus; |
7fd59977 |
807 | } |
808 | |
809 | //======================================================================= |
810 | //function : SortResult |
4269bd1b |
811 | //purpose : there is a certain number of entities ranged by criteria |
81bba717 |
812 | // (depth, size, priority, mouse distance from borders or |
813 | // CDG of the detected primitive. Parsing : |
814 | // maximum priorities . |
815 | // then a reasonable compromise between depth and distance... |
816 | // finally the ranges are stored in myindexes depending on the parsing. |
4269bd1b |
817 | // so, it is possible to only read |
7fd59977 |
818 | //======================================================================= |
819 | void SelectMgr_ViewerSelector::SortResult() |
820 | { |
821 | if(mystored.IsEmpty()) return; |
822 | |
823 | const Standard_Integer anExtent = mystored.Extent(); |
824 | if(myIndexes.IsNull() || anExtent != myIndexes->Length()) |
825 | myIndexes = new TColStd_HArray1OfInteger (1, anExtent); |
826 | |
f5b72419 |
827 | TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1(); |
828 | for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter) |
829 | { |
830 | anIndexArray.SetValue (anIndexIter, anIndexIter); |
831 | } |
832 | std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored)); |
f751596e |
833 | } |
834 | |
835 | //======================================================================= |
836 | //function : HasDepthClipping |
837 | //purpose : Stub |
838 | //======================================================================= |
839 | Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const |
840 | { |
841 | return Standard_False; |
842 | } |
843 | |
844 | //======================================================================= |
845 | // function : AddSelectableObject |
846 | // purpose : Adds new object to the map of selectable objects |
847 | //======================================================================= |
848 | void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
849 | { |
850 | if (!myMapOfObjectSensitives.IsBound (theObject)) |
851 | { |
099f3513 |
852 | mySelectableObjects.Append (theObject); |
f5b72419 |
853 | Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder); |
f751596e |
854 | myMapOfObjectSensitives.Bind (theObject, anEntitySet); |
7fd59977 |
855 | } |
f751596e |
856 | } |
7fd59977 |
857 | |
f751596e |
858 | //======================================================================= |
859 | // function : AddSelectionToObject |
860 | // purpose : Adds new selection to the object and builds its BVH tree |
861 | //======================================================================= |
862 | void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject, |
863 | const Handle(SelectMgr_Selection)& theSelection) |
864 | { |
f5b72419 |
865 | if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject)) |
f751596e |
866 | { |
f5b72419 |
867 | (*anEntitySet)->Append (theSelection); |
868 | (*anEntitySet)->BVH(); |
f751596e |
869 | } |
870 | else |
871 | { |
872 | AddSelectableObject (theObject); |
873 | AddSelectionToObject (theObject, theSelection); |
874 | } |
7fd59977 |
875 | } |
876 | |
1d92133e |
877 | //======================================================================= |
878 | // function : MoveSelectableObject |
879 | // purpose : |
880 | //======================================================================= |
881 | void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
882 | { |
099f3513 |
883 | mySelectableObjects.ChangeSubset (theObject); |
1d92133e |
884 | } |
885 | |
f751596e |
886 | //======================================================================= |
887 | // function : RemoveSelectableObject |
888 | // purpose : Removes selectable object from map of selectable ones |
889 | //======================================================================= |
890 | void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
891 | { |
f5b72419 |
892 | Handle(SelectMgr_SelectableObject) anObj = theObject; |
893 | if (myMapOfObjectSensitives.UnBind (theObject)) |
f751596e |
894 | { |
099f3513 |
895 | mySelectableObjects.Remove (theObject); |
f751596e |
896 | } |
897 | } |
7fd59977 |
898 | |
899 | //======================================================================= |
f751596e |
900 | // function : RemoveSelectionOfObject |
901 | // purpose : Removes selection of the object and marks its BVH tree |
902 | // for rebuild |
7fd59977 |
903 | //======================================================================= |
f751596e |
904 | void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject, |
905 | const Handle(SelectMgr_Selection)& theSelection) |
7fd59977 |
906 | { |
f5b72419 |
907 | if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject)) |
f751596e |
908 | { |
f5b72419 |
909 | (*anEntitySet)->Remove (theSelection); |
f751596e |
910 | } |
7fd59977 |
911 | } |
912 | |
913 | //======================================================================= |
f751596e |
914 | // function : RebuildObjectsTree |
915 | // purpose : Marks BVH of selectable objects for rebuild |
7fd59977 |
916 | //======================================================================= |
f751596e |
917 | void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce) |
7fd59977 |
918 | { |
825aa485 |
919 | mySelectableObjects.MarkDirty(); |
f751596e |
920 | |
921 | if (theIsForce) |
922 | { |
099f3513 |
923 | Standard_Integer aViewportWidth, aViewportHeight; |
91d96372 |
924 | mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight); |
825aa485 |
925 | |
099f3513 |
926 | Standard_Integer aWidth; |
927 | Standard_Integer aHeight; |
928 | mySelectingVolumeMgr.WindowSize (aWidth, aHeight); |
929 | mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(), |
930 | mySelectingVolumeMgr.ProjectionMatrix(), |
931 | mySelectingVolumeMgr.WorldViewMatrix(), |
932 | mySelectingVolumeMgr.WorldViewProjState(), |
933 | aWidth, aHeight); |
f751596e |
934 | } |
7fd59977 |
935 | } |
4269bd1b |
936 | |
937 | //======================================================================= |
f751596e |
938 | // function : RebuildSensitivesTree |
939 | // purpose : Marks BVH of sensitive entities of particular selectable |
940 | // object for rebuild |
4269bd1b |
941 | //======================================================================= |
f751596e |
942 | void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject, |
943 | const Standard_Boolean theIsForce) |
4269bd1b |
944 | { |
825aa485 |
945 | if (!Contains (theObject)) |
f751596e |
946 | return; |
947 | |
f5b72419 |
948 | Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject); |
f751596e |
949 | anEntitySet->MarkDirty(); |
950 | |
951 | if (theIsForce) |
952 | { |
953 | anEntitySet->BVH(); |
954 | } |
4269bd1b |
955 | } |
956 | |
957 | //======================================================================= |
f751596e |
958 | // function : resetSelectionActivationStatus |
959 | // purpose : Marks all added sensitive entities of all objects as |
960 | // non-selectable |
4269bd1b |
961 | //======================================================================= |
29a4908e |
962 | void SelectMgr_ViewerSelector::ResetSelectionActivationStatus() |
4269bd1b |
963 | { |
f5b72419 |
964 | for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next()) |
f751596e |
965 | { |
f5b72419 |
966 | Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue(); |
967 | const Standard_Integer anEntitiesNb = anEntitySet->Size(); |
f751596e |
968 | for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) |
969 | { |
970 | anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus(); |
971 | } |
972 | } |
4269bd1b |
973 | } |
974 | |
975 | //======================================================================= |
f751596e |
976 | // function : DetectedEntity |
977 | // purpose : Returns sensitive entity that was detected during the |
978 | // previous run of selection algorithm |
4269bd1b |
979 | //======================================================================= |
0ef04197 |
980 | const Handle(Select3D_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const |
4269bd1b |
981 | { |
aa75c0cf |
982 | const Standard_Integer aRankInMap = myIndexes->Value(myCurRank); |
983 | return mystored.FindFromIndex (aRankInMap).Entity; |
4269bd1b |
984 | } |
985 | |
986 | //======================================================================= |
f751596e |
987 | // function : ActiveOwners |
988 | // purpose : Returns the list of active entity owners |
4269bd1b |
989 | //======================================================================= |
0ef04197 |
990 | void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const |
4269bd1b |
991 | { |
f751596e |
992 | for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next()) |
993 | { |
f5b72419 |
994 | const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value(); |
995 | const Standard_Integer anEntitiesNb = anEntitySet->Size(); |
f751596e |
996 | for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) |
997 | { |
f5b72419 |
998 | const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx); |
999 | if (aSensitive->IsActiveForSelection()) |
f751596e |
1000 | { |
f5b72419 |
1001 | theOwners.Append (aSensitive->BaseSensitive()->OwnerId()); |
f751596e |
1002 | } |
1003 | } |
1004 | } |
4269bd1b |
1005 | } |
29a4908e |
1006 | |
1007 | //======================================================================= |
1008 | //function : AllowOverlapDetection |
1009 | //purpose : Sets the detection type: if theIsToAllow is false, |
1010 | // only fully included sensitives will be detected, otherwise |
1011 | // the algorithm will mark both included and overlapped entities |
1012 | // as matched |
1013 | //======================================================================= |
1014 | void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow) |
1015 | { |
1016 | mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow); |
1017 | } |