0029945: Export body of revolution to STEP breaks the shape
[occt.git] / src / AIS / AIS_InteractiveContext_1.cxx
... / ...
CommitLineData
1// Created on: 1997-01-29
2// Created by: Robert COUBLANC
3// Copyright (c) 1997-1999 Matra Datavision
4// Copyright (c) 1999-2014 OPEN CASCADE SAS
5//
6// This file is part of Open CASCADE Technology software library.
7//
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
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.
13//
14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
16
17
18#include <AIS_DataMapIteratorOfDataMapOfIOStatus.hxx>
19#include <AIS_GlobalStatus.hxx>
20#include <AIS_InteractiveContext.hxx>
21#include <AIS_InteractiveObject.hxx>
22#include <AIS_MapIteratorOfMapOfInteractive.hxx>
23#include <AIS_MapOfInteractive.hxx>
24#include <AIS_Selection.hxx>
25#include <AIS_Shape.hxx>
26#include <AIS_StatusOfDetection.hxx>
27#include <AIS_StatusOfPick.hxx>
28#include <Aspect_Grid.hxx>
29#include <Prs3d_BasicAspect.hxx>
30#include <Prs3d_LineAspect.hxx>
31#include <Prs3d_Presentation.hxx>
32#include <Quantity_Color.hxx>
33#include <SelectBasics_SensitiveEntity.hxx>
34#include <SelectMgr_EntityOwner.hxx>
35#include <SelectMgr_Filter.hxx>
36#include <SelectMgr_OrFilter.hxx>
37#include <SelectMgr_Selection.hxx>
38#include <SelectMgr_SelectionManager.hxx>
39#include <Standard_Transient.hxx>
40#include <StdSelect_BRepOwner.hxx>
41#include <StdSelect_ViewerSelector3d.hxx>
42#include <TCollection_AsciiString.hxx>
43#include <TCollection_ExtendedString.hxx>
44#include <TColStd_ListIteratorOfListOfInteger.hxx>
45#include <TopLoc_Location.hxx>
46#include <V3d_AmbientLight.hxx>
47#include <V3d_DirectionalLight.hxx>
48#include <V3d_Light.hxx>
49#include <V3d_PositionalLight.hxx>
50#include <V3d_SpotLight.hxx>
51#include <V3d_View.hxx>
52#include <V3d_Viewer.hxx>
53
54typedef NCollection_DataMap<Handle(AIS_InteractiveObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > AIS_MapOfObjSelectedOwners;
55
56namespace
57{
58 TopoDS_Shape AIS_InteractiveContext_myDummyShape;
59}
60
61//=======================================================================
62//function : highlightWithColor
63//purpose :
64//=======================================================================
65void AIS_InteractiveContext::highlightWithColor (const Handle(SelectMgr_EntityOwner)& theOwner,
66 const Handle(V3d_Viewer)& theViewer)
67{
68 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
69 if (anObj.IsNull())
70 {
71 return;
72 }
73
74 const Handle(Prs3d_Drawer)& aStyle = getHiStyle (anObj, theOwner);
75 const Standard_Integer aHiMode = getHilightMode (anObj, aStyle, -1);
76
77 myMainPM->BeginImmediateDraw();
78 theOwner->HilightWithColor (myMainPM, aStyle, aHiMode);
79 myMainPM->EndImmediateDraw (theViewer.IsNull() ? myMainVwr : theViewer);
80}
81
82//=======================================================================
83//function : highlightSelected
84//purpose :
85//=======================================================================
86void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwner)& theOwner)
87{
88 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
89 if (anObj.IsNull())
90 {
91 return;
92 }
93
94 if (!theOwner->IsAutoHilight())
95 {
96 SelectMgr_SequenceOfOwner aSeq;
97 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
98 {
99 if (aSelIter.Value()->IsSameSelectable (anObj))
100 {
101 aSeq.Append (aSelIter.Value());
102 }
103 }
104 anObj->HilightSelected (myMainPM, aSeq);
105 }
106 else
107 {
108 const Handle(Prs3d_Drawer)& aStyle = getSelStyle (anObj, theOwner);
109 const Standard_Integer aHiMode = getHilightMode (anObj, aStyle, -1);
110 theOwner->HilightWithColor (myMainPM, aStyle, aHiMode);
111 }
112}
113
114//=======================================================================
115//function : highlightGlobal
116//purpose :
117//=======================================================================
118void AIS_InteractiveContext::highlightGlobal (const Handle(AIS_InteractiveObject)& theObj,
119 const Handle(Prs3d_Drawer)& theStyle,
120 const Standard_Integer theDispMode) const
121{
122 if (theObj.IsNull())
123 {
124 return;
125 }
126
127 const Standard_Integer aHiMode = getHilightMode (theObj, theStyle, theDispMode);
128 const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
129
130 if (aGlobOwner.IsNull())
131 {
132 myMainPM->Color (theObj, theStyle, aHiMode);
133 return;
134 }
135
136 if (!aGlobOwner->IsAutoHilight())
137 {
138 SelectMgr_SequenceOfOwner aSeq;
139 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
140 {
141 if (aSelIter.Value()->IsSameSelectable (theObj))
142 {
143 aSeq.Append (aSelIter.Value());
144 }
145 }
146 theObj->HilightSelected (myMainPM, aSeq);
147 }
148 else
149 {
150 aGlobOwner->HilightWithColor (myMainPM, theStyle, aHiMode);
151 }
152}
153
154//=======================================================================
155//function : unhighlightSelected
156//purpose :
157//=======================================================================
158void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsToHilightSubIntensity)
159{
160 NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
161 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
162 {
163 const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
164 const Handle(AIS_InteractiveObject) anInteractive = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
165 Handle(AIS_GlobalStatus) aStatus;
166 if (!myObjects.Find (anInteractive, aStatus))
167 {
168 continue;
169 }
170
171 if (anOwner->IsAutoHilight())
172 {
173 anOwner->Unhilight (myMainPM);
174 if (theIsToHilightSubIntensity)
175 {
176 if (aStatus->IsSubIntensityOn())
177 {
178 const Standard_Integer aHiMode = getHilightMode (anInteractive, aStatus->HilightStyle(), aStatus->DisplayMode());
179 highlightWithSubintensity (anOwner, aHiMode);
180 }
181 }
182 }
183 else
184 {
185 anObjToClear.Add (anInteractive);
186 }
187 anOwner->SetSelected (Standard_False);
188 if (anOwner == anInteractive->GlobalSelOwner())
189 {
190 myObjects.ChangeFind (anInteractive)->SetHilightStatus (Standard_False);
191 }
192 }
193 for (NCollection_IndexedMap<Handle(AIS_InteractiveObject)>::Iterator anIter (anObjToClear); anIter.More(); anIter.Next())
194 {
195 const Handle(AIS_InteractiveObject)& anObj = anIter.Value();
196 myMainPM->Unhighlight (anObj);
197 anObj->ClearSelected();
198 }
199}
200
201//=======================================================================
202//function : unhighlightGlobal
203//purpose :
204//=======================================================================
205void AIS_InteractiveContext::unhighlightGlobal (const Handle(AIS_InteractiveObject)& theObj) const
206{
207 if (theObj.IsNull())
208 {
209 return;
210 }
211
212 const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
213 if (aGlobOwner.IsNull())
214 {
215 myMainPM->Unhighlight (theObj);
216 return;
217 }
218
219 if (aGlobOwner->IsAutoHilight())
220 {
221 aGlobOwner->Unhilight (myMainPM);
222 }
223 else
224 {
225 myMainPM->Unhighlight (theObj);
226 theObj->ClearSelected();
227 }
228}
229
230//=======================================================================
231//function : turnOnSubintensity
232//purpose :
233//=======================================================================
234void AIS_InteractiveContext::turnOnSubintensity (const Handle(AIS_InteractiveObject)& theObject,
235 const Standard_Integer theDispMode,
236 const Standard_Boolean theIsDisplayedOnly) const
237{
238 // the only differ with selection highlight is color, so sync transparency values
239 const Handle(Prs3d_Drawer)& aSubStyle = myStyles[Prs3d_TypeOfHighlight_SubIntensity];
240 aSubStyle->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
241
242 if (theObject.IsNull())
243 {
244 for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjsIter (myObjects); anObjsIter.More(); anObjsIter.Next())
245 {
246 const Handle(AIS_GlobalStatus)& aStatus = anObjsIter.Value();
247 if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
248 continue;
249
250 aStatus->SubIntensityOn();
251 myMainPM->Color (anObjsIter.Key(), aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
252 }
253 }
254 else
255 {
256 Handle(AIS_GlobalStatus) aStatus;
257 if (!myObjects.Find (theObject, aStatus))
258 return;
259
260 if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
261 return;
262
263 aStatus->SubIntensityOn();
264 myMainPM->Color (theObject, aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
265 }
266}
267
268//=======================================================================
269//function : highlightWithSubintensity
270//purpose :
271//=======================================================================
272void AIS_InteractiveContext::highlightWithSubintensity (const Handle(AIS_InteractiveObject)& theObject,
273 const Standard_Integer theMode) const
274{
275 // the only differ with selection highlight is color, so
276 // sync transparency values
277 myStyles[Prs3d_TypeOfHighlight_SubIntensity]->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
278
279 myMainPM->Color (theObject, myStyles[Prs3d_TypeOfHighlight_SubIntensity], theMode);
280}
281
282//=======================================================================
283//function : highlightWithSubintensity
284//purpose :
285//=======================================================================
286void AIS_InteractiveContext::highlightWithSubintensity (const Handle(SelectMgr_EntityOwner)& theOwner,
287 const Standard_Integer theMode) const
288{
289 // the only differ with selection highlight is color, so
290 // sync transparency values
291 myStyles[Prs3d_TypeOfHighlight_SubIntensity]->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
292
293 theOwner->HilightWithColor (myMainPM, myStyles[Prs3d_TypeOfHighlight_SubIntensity], theMode);
294}
295
296//=======================================================================
297//function : MoveTo
298//purpose :
299//=======================================================================
300AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer theXPix,
301 const Standard_Integer theYPix,
302 const Handle(V3d_View)& theView,
303 const Standard_Boolean theToRedrawOnUpdate)
304{
305 if (theView->Viewer() != myMainVwr)
306 {
307 throw Standard_ProgramError ("AIS_InteractiveContext::MoveTo() - invalid argument");
308 }
309
310 myCurDetected = 0;
311 myCurHighlighted = 0;
312 myDetectedSeq.Clear();
313
314 // preliminaires
315 myLastPicked = myLastinMain;
316 myWasLastMain = Standard_True;
317 AIS_StatusOfDetection aStatus = AIS_SOD_Nothing;
318 Standard_Boolean toUpdateViewer = Standard_False;
319
320 myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
321 myMainSel->Pick (theXPix, theYPix, theView);
322
323 // filling of myAISDetectedSeq sequence storing information about detected AIS objects
324 // (the objects must be AIS_Shapes)
325 const Standard_Integer aDetectedNb = myMainSel->NbPicked();
326 Standard_Integer aNewDetected = 0;
327 Standard_Boolean toIgnoreDetTop = Standard_False;
328 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
329 {
330 Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aDetIter);
331 if (anOwner.IsNull()
332 || !myFilters->IsOk (anOwner))
333 {
334 if (myPickingStrategy == SelectMgr_PickingStrategy_OnlyTopmost)
335 {
336 toIgnoreDetTop = Standard_True;
337 }
338 continue;
339 }
340
341 if (aNewDetected < 1
342 && !toIgnoreDetTop)
343 {
344 aNewDetected = aDetIter;
345 }
346
347 myDetectedSeq.Append (aDetIter);
348 }
349
350 if (aNewDetected >= 1)
351 {
352 myCurHighlighted = myDetectedSeq.Lower();
353
354 // Does nothing if previously detected object is equal to the current one.
355 // However in advanced selection modes the owners comparison
356 // is not effective because in that case only one owner manage the
357 // selection in current selection mode. It is necessary to check the current detected
358 // entity and hilight it only if the detected entity is not the same as
359 // previous detected (IsForcedHilight call)
360 Handle(SelectMgr_EntityOwner) aNewPickedOwner = myMainSel->Picked (aNewDetected);
361 if (aNewPickedOwner == myLastPicked && !aNewPickedOwner->IsForcedHilight())
362 {
363 return myLastPicked->IsSelected()
364 ? AIS_SOD_Selected
365 : AIS_SOD_OnlyOneDetected;
366 }
367
368 // Previously detected object is unhilighted if it is not selected or hilighted
369 // with selection color if it is selected. Such highlighting with selection color
370 // is needed only if myToHilightSelected flag is true. In this case previously detected
371 // object has been already highlighted with myHilightColor during previous MoveTo()
372 // method call. As result it is necessary to rehighligt it with mySelectionColor.
373 if (!myLastPicked.IsNull() && myLastPicked->HasSelectable())
374 {
375 clearDynamicHighlight();
376 toUpdateViewer = Standard_True;
377 }
378
379 // initialize myLastPicked field with currently detected object
380 myLastPicked = aNewPickedOwner;
381 myLastinMain = myLastPicked;
382
383 // highlight detected object if it is not selected or myToHilightSelected flag is true
384 if (myLastPicked->HasSelectable())
385 {
386 if (!myLastPicked->IsSelected() || myToHilightSelected)
387 {
388 highlightWithColor (myLastPicked, theView->Viewer());
389 toUpdateViewer = Standard_True;
390 }
391
392 aStatus = myLastPicked->IsSelected()
393 ? AIS_SOD_Selected
394 : AIS_SOD_OnlyOneDetected;
395 }
396 }
397 else
398 {
399 // previously detected object is unhilighted if it is not selected or hilighted
400 // with selection color if it is selected
401 aStatus = AIS_SOD_Nothing;
402 if (!myLastPicked.IsNull() && myLastPicked->HasSelectable())
403 {
404 clearDynamicHighlight();
405 toUpdateViewer = Standard_True;
406 }
407
408 myLastinMain.Nullify();
409 myLastPicked.Nullify();
410 }
411
412 if (toUpdateViewer
413 && theToRedrawOnUpdate)
414 {
415 theView->Viewer()->Update();
416 }
417
418 return aStatus;
419}
420
421//=======================================================================
422//function : AddSelect
423//purpose :
424//=======================================================================
425AIS_StatusOfPick AIS_InteractiveContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
426{
427 mySelection->AddSelect (theObject);
428
429 Standard_Integer aSelNum = NbSelected();
430 return (aSelNum == 0) ? AIS_SOP_NothingSelected
431 : (aSelNum == 1) ? AIS_SOP_OneSelected
432 : AIS_SOP_SeveralSelected;
433}
434
435//=======================================================================
436//function : Select
437//purpose :
438//=======================================================================
439AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer theXPMin,
440 const Standard_Integer theYPMin,
441 const Standard_Integer theXPMax,
442 const Standard_Integer theYPMax,
443 const Handle(V3d_View)& theView,
444 const Standard_Boolean toUpdateViewer)
445{
446 if (theView->Viewer() != myMainVwr)
447 {
448 throw Standard_ProgramError ("AIS_InteractiveContext::Select() - invalid argument");
449 }
450
451 // all objects detected by the selector are taken, previous current objects are emptied,
452 // new objects are put...
453 ClearSelected (Standard_False);
454 myWasLastMain = Standard_True;
455 myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
456 for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
457 {
458 const Handle(SelectMgr_EntityOwner)& aCurOwner = myMainSel->Picked (aPickIter);
459 if (aCurOwner.IsNull() || !aCurOwner->HasSelectable() || !myFilters->IsOk (aCurOwner))
460 continue;
461
462 mySelection->Select (aCurOwner);
463 aCurOwner->SetSelected (Standard_True);
464 }
465
466 if (myAutoHilight)
467 {
468 HilightSelected (toUpdateViewer);
469 }
470
471 Standard_Integer aSelNum = NbSelected();
472
473 return (aSelNum == 0) ? AIS_SOP_NothingSelected
474 : (aSelNum == 1) ? AIS_SOP_OneSelected
475 : AIS_SOP_SeveralSelected;
476
477}
478
479//=======================================================================
480//function : Select
481//purpose : Selection by polyline
482//=======================================================================
483AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
484 const Handle(V3d_View)& theView,
485 const Standard_Boolean toUpdateViewer)
486{
487 if (theView->Viewer() != myMainVwr)
488 {
489 throw Standard_ProgramError ("AIS_InteractiveContext::Select() - invalid argument");
490 }
491
492 // all objects detected by the selector are taken, previous current objects are emptied,
493 // new objects are put...
494 ClearSelected (Standard_False);
495 myWasLastMain = Standard_True;
496 myMainSel->Pick (thePolyline, theView);
497 for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
498 {
499 const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter);
500 if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
501 continue;
502
503 mySelection->Select (anOwner);
504 anOwner->SetSelected (Standard_True);
505 }
506
507 if (myAutoHilight)
508 {
509 HilightSelected (toUpdateViewer);
510 }
511
512 Standard_Integer aSelNum = NbSelected();
513
514 return (aSelNum == 0) ? AIS_SOP_NothingSelected
515 : (aSelNum == 1) ? AIS_SOP_OneSelected
516 : AIS_SOP_SeveralSelected;
517
518}
519
520//=======================================================================
521//function : Select
522//purpose :
523//=======================================================================
524AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdateViewer)
525{
526 if (myAutoHilight)
527 {
528 clearDynamicHighlight();
529 }
530 if (myWasLastMain && !myLastinMain.IsNull())
531 {
532 if (!myLastinMain->IsSelected()
533 || myLastinMain->IsForcedHilight()
534 || NbSelected() > 1)
535 {
536 SetSelected (myLastinMain, Standard_False);
537 if(toUpdateViewer)
538 {
539 UpdateCurrentViewer();
540 }
541 }
542 }
543 else
544 {
545 if (myAutoHilight)
546 {
547 unhighlightSelected (Standard_True);
548 }
549
550 mySelection->Clear();
551 if (toUpdateViewer && myWasLastMain)
552 {
553 UpdateCurrentViewer();
554 }
555 }
556
557 Standard_Integer aSelNum = NbSelected();
558
559 return (aSelNum == 0) ? AIS_SOP_NothingSelected
560 : (aSelNum == 1) ? AIS_SOP_OneSelected
561 : AIS_SOP_SeveralSelected;
562}
563
564//=======================================================================
565//function : ShiftSelect
566//purpose :
567//=======================================================================
568AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
569{
570 if (myAutoHilight)
571 {
572 clearDynamicHighlight();
573 }
574 if (myWasLastMain && !myLastinMain.IsNull())
575 {
576 AddOrRemoveSelected (myLastinMain, toUpdateViewer);
577 }
578
579 Standard_Integer aSelNum = NbSelected();
580
581 return (aSelNum == 0) ? AIS_SOP_NothingSelected
582 : (aSelNum == 1) ? AIS_SOP_OneSelected
583 : AIS_SOP_SeveralSelected;
584}
585
586//=======================================================================
587//function : ShiftSelect
588//purpose :
589//=======================================================================
590AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer theXPMin,
591 const Standard_Integer theYPMin,
592 const Standard_Integer theXPMax,
593 const Standard_Integer theYPMax,
594 const Handle(V3d_View)& theView,
595 const Standard_Boolean toUpdateViewer)
596{
597 if (theView->Viewer() != myMainVwr)
598 {
599 throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
600 }
601
602 if (myAutoHilight)
603 {
604 UnhilightSelected (Standard_False);
605 }
606 myWasLastMain = Standard_True;
607 myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
608 for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
609 {
610 const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter);
611 if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
612 continue;
613
614 AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
615 anOwner->SetSelected (aSelStatus == AIS_SS_Added);
616 }
617
618 if (myAutoHilight)
619 {
620 HilightSelected (toUpdateViewer);
621 }
622
623 Standard_Integer aSelNum = NbSelected();
624
625 return (aSelNum == 0) ? AIS_SOP_NothingSelected
626 : (aSelNum == 1) ? AIS_SOP_OneSelected
627 : AIS_SOP_SeveralSelected;
628
629}
630
631//=======================================================================
632//function : ShiftSelect
633//purpose :
634//=======================================================================
635AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
636 const Handle(V3d_View)& theView,
637 const Standard_Boolean toUpdateViewer)
638{
639 if (theView->Viewer() != myMainVwr)
640 {
641 throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
642 }
643
644 if (myAutoHilight)
645 {
646 UnhilightSelected (Standard_False);
647 }
648 myWasLastMain = Standard_True;
649 myMainSel->Pick (thePolyline, theView);
650 for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
651 {
652 const Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aPickIter);
653 if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
654 continue;
655
656 AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
657 anOwner->SetSelected (aSelStatus == AIS_SS_Added);
658 }
659
660 if (myAutoHilight)
661 {
662 HilightSelected (toUpdateViewer);
663 }
664
665 Standard_Integer aSelNum = NbSelected();
666
667 return (aSelNum == 0) ? AIS_SOP_NothingSelected
668 : (aSelNum == 1) ? AIS_SOP_OneSelected
669 : AIS_SOP_SeveralSelected;
670}
671
672//=======================================================================
673//function : HilightSelected
674//purpose :
675//=======================================================================
676void AIS_InteractiveContext::HilightSelected (const Standard_Boolean theToUpdateViewer)
677{
678 // In case of selection without using local context
679 clearDynamicHighlight();
680 AIS_MapOfObjSelectedOwners anObjOwnerMap;
681 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
682 {
683 const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
684 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
685 const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (anObj, anOwner);
686 Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind(anObj);
687 if (anOwner == anObj->GlobalSelOwner())
688 {
689 aState->SetHilightStatus (Standard_True);
690 aState->SetHilightStyle (anObjSelStyle);
691 }
692 anOwner->SetSelected (Standard_True);
693 if (!anOwner->IsAutoHilight())
694 {
695 NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq;
696 if (anObjOwnerMap.Find (anObj, aSeq))
697 {
698 aSeq->Append (anOwner);
699 }
700 else
701 {
702 aSeq = new SelectMgr_SequenceOfOwner();
703 aSeq->Append (anOwner);
704 anObjOwnerMap.Bind (anObj, aSeq);
705 }
706 }
707 else
708 {
709 const Standard_Integer aHiMode = getHilightMode (anObj, anObjSelStyle, aState->DisplayMode());
710 anOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
711 }
712 }
713
714 if (!anObjOwnerMap.IsEmpty())
715 {
716 for (AIS_MapOfObjSelectedOwners::Iterator anIter (anObjOwnerMap); anIter.More(); anIter.Next())
717 {
718 anIter.Key()->HilightSelected (myMainPM, *anIter.Value());
719 }
720 anObjOwnerMap.Clear();
721 }
722
723 if (theToUpdateViewer)
724 UpdateCurrentViewer();
725}
726
727//=======================================================================
728//function : UnhilightSelected
729//purpose :
730//=======================================================================
731void AIS_InteractiveContext::UnhilightSelected (const Standard_Boolean theToUpdateViewer)
732{
733 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
734 {
735 const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
736 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
737 if (anOwner == anObj->GlobalSelOwner())
738 {
739 myObjects.ChangeFind (anObj)->SetHilightStatus (Standard_False);
740 }
741
742 anOwner->SetSelected (Standard_False);
743 anOwner->Unhilight (myMainPM);
744 }
745
746 if (theToUpdateViewer)
747 UpdateCurrentViewer();
748}
749
750
751//=======================================================================
752//function : ClearSelected
753//purpose :
754//=======================================================================
755void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateViewer)
756{
757 if (NbSelected() == 0)
758 return;
759
760 if (myAutoHilight)
761 {
762 unhighlightSelected();
763 }
764
765 mySelection->Clear();
766 if (myAutoHilight)
767 {
768 clearDynamicHighlight();
769 }
770
771 if (theToUpdateViewer)
772 UpdateCurrentViewer();
773}
774
775//=======================================================================
776//function : SetSelected
777//purpose : Sets the whole object as selected and highlights it with selection color
778//=======================================================================
779void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& theObject,
780 const Standard_Boolean theToUpdateViewer)
781{
782 if (theObject.IsNull())
783 {
784 return;
785 }
786
787 if (!myObjects.IsBound (theObject))
788 {
789 Display (theObject, Standard_False);
790 }
791
792 Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
793 if (anOwner.IsNull())
794 {
795 return;
796 }
797
798 const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (theObject, anOwner);
799 if (NbSelected() == 1 && myObjects (theObject)->IsHilighted() && myAutoHilight)
800 {
801 Handle(Prs3d_Drawer) aCustomStyle;
802 if (HighlightStyle (theObject, aCustomStyle))
803 {
804 if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
805 {
806 HilightWithColor (theObject, anObjSelStyle, theToUpdateViewer);
807 }
808 }
809 return;
810 }
811
812 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
813 {
814 const Handle(SelectMgr_EntityOwner)& aSelOwner = aSelIter.Value();
815 if (!myFilters->IsOk (aSelOwner))
816 {
817 continue;
818 }
819
820 Handle(AIS_InteractiveObject) aSelectable = Handle(AIS_InteractiveObject)::DownCast (aSelOwner->Selectable());
821 if (myAutoHilight)
822 {
823 Unhilight (aSelectable, Standard_False);
824 }
825 aSelOwner->SetSelected (Standard_False);
826 if (aSelOwner == aSelectable->GlobalSelOwner())
827 {
828 myObjects.ChangeFind (aSelectable)->SetHilightStatus (Standard_False);
829 }
830 }
831
832 // added to avoid untimely viewer update...
833 mySelection->ClearAndSelect (anOwner);
834
835 if (myAutoHilight)
836 {
837 Handle(Prs3d_Drawer) aCustomStyle;
838 if (HighlightStyle (theObject, aCustomStyle))
839 {
840 if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
841 {
842 HilightWithColor (theObject, anObjSelStyle, Standard_False);
843 }
844 }
845 else
846 {
847 HilightWithColor (theObject, anObjSelStyle, Standard_False);
848 }
849 }
850 anOwner->SetSelected (Standard_True);
851
852 if (theToUpdateViewer)
853 UpdateCurrentViewer();
854}
855
856//=======================================================================
857//function : SetSelected
858//purpose : Sets the whole object as selected and highlights it with selection color
859//=======================================================================
860void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
861 const Standard_Boolean theToUpdateViewer)
862{
863 if (theOwner.IsNull() || !theOwner->HasSelectable() || !myFilters->IsOk (theOwner))
864 return;
865
866 const Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
867 const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (anObject, theOwner);
868 if (NbSelected() == 1 && theOwner->IsSelected() && !theOwner->IsForcedHilight())
869 {
870 Handle(Prs3d_Drawer) aCustomStyle;
871 if (myAutoHilight && HighlightStyle (theOwner, aCustomStyle))
872 {
873 if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
874 {
875 const Standard_Integer aHiMode = anObject->HasHilightMode() ? anObject->HilightMode() : 0;
876 theOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
877 }
878 }
879 return;
880 }
881
882 if (!myObjects.IsBound (anObject))
883 Display (anObject, Standard_False);
884
885 if (myAutoHilight)
886 {
887 unhighlightSelected();
888 }
889
890 mySelection->ClearAndSelect (theOwner);
891 if (myAutoHilight)
892 {
893 Handle(Prs3d_Drawer) aCustomStyle;
894 if (!HighlightStyle (theOwner, aCustomStyle) ||
895 (!aCustomStyle.IsNull() && aCustomStyle != anObjSelStyle))
896 {
897 theOwner->SetSelected (Standard_True);
898 highlightSelected (theOwner);
899 }
900 }
901
902 theOwner->SetSelected (Standard_True);
903 if (myAutoHilight && theOwner == anObject->GlobalSelOwner())
904 {
905 Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObject);
906 aState->SetHilightStatus (Standard_True);
907 aState->SetHilightStyle (anObjSelStyle);
908 }
909
910 if (theToUpdateViewer)
911 UpdateCurrentViewer();
912}
913
914//=======================================================================
915//function : AddOrRemoveSelected
916//purpose : Adds or removes current object from AIS selection and highlights/unhighlights it.
917// Since this method makes sence only for neutral point selection of a whole object,
918// if 0 selection of the object is empty this method simply does nothing.
919//=======================================================================
920void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(AIS_InteractiveObject)& theObject,
921 const Standard_Boolean theToUpdateViewer)
922{
923 if (theObject.IsNull()
924 || !myObjects.IsBound (theObject))
925 {
926 return;
927 }
928
929 const Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
930 if (!anOwner.IsNull()
931 && anOwner->HasSelectable())
932 {
933 AddOrRemoveSelected (anOwner, theToUpdateViewer);
934 }
935}
936
937//=======================================================================
938//function : AddOrRemoveSelected
939//purpose : Allows to highlight or unhighlight the owner given depending on
940// its selection status
941//=======================================================================
942void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
943 const Standard_Boolean theToUpdateViewer)
944{
945 if (theOwner.IsNull() || !theOwner->HasSelectable())
946 return;
947
948 if (!myFilters->IsOk(theOwner) && !theOwner->IsSelected())
949 return;
950
951 AIS_SelectStatus aSelStat = mySelection->Select (theOwner);
952 theOwner->SetSelected (aSelStat == AIS_SS_Added);
953
954 if (myAutoHilight)
955 {
956 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
957 const Standard_Boolean isGlobal = anObj->GlobalSelOwner() == theOwner;
958 Handle(AIS_GlobalStatus)& aStatus = myObjects.ChangeFind (anObj);
959 if (theOwner->IsSelected())
960 {
961 highlightSelected (theOwner);
962 if (isGlobal)
963 {
964 aStatus->SetHilightStatus (Standard_True);
965 aStatus->SetHilightStyle (getSelStyle (anObj, theOwner));
966 }
967 }
968 else
969 {
970 if (theOwner->IsAutoHilight())
971 {
972 theOwner->Unhilight (myMainPM);
973 }
974 else
975 {
976 anObj->ClearSelected();
977 }
978 aStatus->SetHilightStatus (Standard_False);
979 aStatus->SetHilightStyle (Handle(Prs3d_Drawer)());
980 }
981 }
982
983 if (theToUpdateViewer)
984 UpdateCurrentViewer();
985}
986
987
988//=======================================================================
989//function : IsSelected
990//purpose :
991//=======================================================================
992Standard_Boolean AIS_InteractiveContext::IsSelected (const Handle(AIS_InteractiveObject)& theObj) const
993{
994 if (theObj.IsNull())
995 {
996 return Standard_False;
997 }
998
999 const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
1000 if (aStatus == NULL)
1001 {
1002 return Standard_False;
1003 }
1004
1005 const Standard_Integer aGlobalSelMode = theObj->GlobalSelectionMode();
1006 const TColStd_ListOfInteger& anActivatedModes = (*aStatus)->SelectionModes();
1007 for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next())
1008 {
1009 if (aModeIter.Value() == aGlobalSelMode)
1010 {
1011 if (Handle(SelectMgr_EntityOwner) aGlobOwner = theObj->GlobalSelOwner())
1012 {
1013 return aGlobOwner->IsSelected();
1014 }
1015 return Standard_False;
1016 }
1017 }
1018 return Standard_False;
1019}
1020
1021//=======================================================================
1022//function : FirstSelectedObject
1023//purpose :
1024//=======================================================================
1025Handle(AIS_InteractiveObject) AIS_InteractiveContext::FirstSelectedObject() const
1026{
1027 return !mySelection->Objects().IsEmpty()
1028 ? Handle(AIS_InteractiveObject)::DownCast (mySelection->Objects().First()->Selectable())
1029 : Handle(AIS_InteractiveObject)();
1030}
1031
1032//=======================================================================
1033//function : HasSelectedShape
1034//purpose :
1035//=======================================================================
1036Standard_Boolean AIS_InteractiveContext::HasSelectedShape() const
1037{
1038 if (!mySelection->More())
1039 return Standard_False;
1040
1041 const Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
1042 return !anOwner.IsNull() && anOwner->HasShape();
1043}
1044
1045//=======================================================================
1046//function : SelectedShape
1047//purpose :
1048//=======================================================================
1049TopoDS_Shape AIS_InteractiveContext::SelectedShape() const
1050{
1051 if (!mySelection->More())
1052 return TopoDS_Shape();
1053
1054 const Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
1055 if (anOwner.IsNull() || !anOwner->HasSelectable())
1056 return TopoDS_Shape();
1057
1058 return anOwner->Shape().Located (anOwner->Location() * anOwner->Shape().Location());
1059}
1060
1061//=======================================================================
1062//function : EntityOwners
1063//purpose :
1064//=======================================================================
1065void AIS_InteractiveContext::EntityOwners(Handle(SelectMgr_IndexedMapOfOwner)& theOwners,
1066 const Handle(AIS_InteractiveObject)& theIObj,
1067 const Standard_Integer theMode) const
1068{
1069 if (theIObj.IsNull())
1070 {
1071 return;
1072 }
1073
1074 TColStd_ListOfInteger aModes;
1075 if (theMode == -1)
1076 {
1077 ActivatedModes (theIObj, aModes);
1078 }
1079 else
1080 {
1081 aModes.Append (theMode);
1082 }
1083
1084 if (theOwners.IsNull())
1085 {
1086 theOwners = new SelectMgr_IndexedMapOfOwner();
1087 }
1088
1089 for (TColStd_ListIteratorOfListOfInteger anItr (aModes); anItr.More(); anItr.Next())
1090 {
1091 const int aMode = anItr.Value();
1092 const Handle(SelectMgr_Selection)& aSel = theIObj->Selection (aMode);
1093 if (aSel.IsNull())
1094 {
1095 continue;
1096 }
1097
1098 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
1099 {
1100 if (Handle(SelectBasics_SensitiveEntity) aEntity = aSelEntIter.Value()->BaseSensitive())
1101 {
1102 if (Handle(SelectMgr_EntityOwner) aOwner = Handle(SelectMgr_EntityOwner)::DownCast(aEntity->OwnerId()))
1103 {
1104 theOwners->Add (aOwner);
1105 }
1106 }
1107 }
1108 }
1109}
1110
1111//=======================================================================
1112//function : HasDetectedShape
1113//purpose :
1114//=======================================================================
1115Standard_Boolean AIS_InteractiveContext::HasDetectedShape() const
1116{
1117 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (myLastPicked);
1118 return !anOwner.IsNull()
1119 && anOwner->HasShape();
1120}
1121
1122//=======================================================================
1123//function : DetectedShape
1124//purpose :
1125//=======================================================================
1126const TopoDS_Shape& AIS_InteractiveContext::DetectedShape() const
1127{
1128 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (myLastPicked);
1129 return anOwner->Shape();
1130}
1131
1132//=======================================================================
1133//function : HilightNextDetected
1134//purpose :
1135//=======================================================================
1136Standard_Integer AIS_InteractiveContext::HilightNextDetected (const Handle(V3d_View)& theView,
1137 const Standard_Boolean theToRedrawImmediate)
1138{
1139 myMainPM->ClearImmediateDraw();
1140 if (myDetectedSeq.IsEmpty())
1141 {
1142 return 0;
1143 }
1144
1145 if (++myCurHighlighted > myDetectedSeq.Upper())
1146 {
1147 myCurHighlighted = myDetectedSeq.Lower();
1148 }
1149 const Handle(SelectMgr_EntityOwner)& anOwner = myMainSel->Picked (myDetectedSeq (myCurHighlighted));
1150 if (anOwner.IsNull())
1151 {
1152 return 0;
1153 }
1154
1155 highlightWithColor (anOwner, theView->Viewer());
1156 myLastPicked = anOwner;
1157 myLastinMain = myLastPicked;
1158
1159 if (theToRedrawImmediate)
1160 {
1161 myMainPM->RedrawImmediate (theView->Viewer());
1162 myMainVwr->RedrawImmediate();
1163 }
1164
1165 return myCurHighlighted;
1166}
1167
1168//=======================================================================
1169//function : HilightPreviousDetected
1170//purpose :
1171//=======================================================================
1172Standard_Integer AIS_InteractiveContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1173 const Standard_Boolean theToRedrawImmediate)
1174{
1175 myMainPM->ClearImmediateDraw();
1176 if (myDetectedSeq.IsEmpty())
1177 {
1178 return 0;
1179 }
1180
1181 if (--myCurHighlighted < myDetectedSeq.Lower())
1182 {
1183 myCurHighlighted = myDetectedSeq.Upper();
1184 }
1185 const Handle(SelectMgr_EntityOwner)& anOwner = myMainSel->Picked (myDetectedSeq (myCurHighlighted));
1186 if (anOwner.IsNull())
1187 {
1188 return 0;
1189 }
1190
1191 highlightWithColor (anOwner, theView->Viewer());
1192 myLastPicked = anOwner;
1193 myLastinMain = myLastPicked;
1194
1195 if (theToRedrawImmediate)
1196 {
1197 myMainPM->RedrawImmediate (theView->Viewer());
1198 myMainVwr->RedrawImmediate();
1199 }
1200
1201 return myCurHighlighted;
1202}
1203
1204//=======================================================================
1205//function : DetectedCurrentOwner
1206//purpose :
1207//=======================================================================
1208Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::DetectedCurrentOwner() const
1209{
1210 return MoreDetected()
1211 ? myMainSel->Picked (myDetectedSeq (myCurDetected))
1212 : Handle(SelectMgr_EntityOwner)();
1213}
1214
1215//=======================================================================
1216//function : DetectedCurrentShape
1217//purpose :
1218//=======================================================================
1219const TopoDS_Shape& AIS_InteractiveContext::DetectedCurrentShape() const
1220{
1221 Standard_DISABLE_DEPRECATION_WARNINGS
1222 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1223 Standard_ENABLE_DEPRECATION_WARNINGS
1224 return !aCurrentShape.IsNull()
1225 ? aCurrentShape->Shape()
1226 : AIS_InteractiveContext_myDummyShape;
1227}
1228
1229//=======================================================================
1230//function : DetectedCurrentObject
1231//purpose :
1232//=======================================================================
1233Handle(AIS_InteractiveObject) AIS_InteractiveContext::DetectedCurrentObject() const
1234{
1235 return MoreDetected()
1236 ? Handle(AIS_InteractiveObject)::DownCast (myMainSel->Picked (myDetectedSeq (myCurDetected))->Selectable())
1237 : Handle(AIS_InteractiveObject)();
1238}