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