Salome HOME
af1855f56c91ecb0350c656e496b90c3f81e379c
[modules/shaper.git] / src / XGUI / XGUI_SelectionActivate.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "XGUI_SelectionActivate.h"
22
23 #include "ModelAPI_Object.h"
24
25 #include "ModuleBase_IModule.h"
26 #include "ModuleBase_IViewer.h"
27 #include "ModuleBase_ModelWidget.h"
28 #include "ModuleBase_Preferences.h"
29
30 #include "XGUI_ActiveControlMgr.h"
31 #include "XGUI_ActiveControlSelector.h"
32 #include "XGUI_Displayer.h"
33 #include "XGUI_FacesPanel.h"
34 #include "XGUI_FacesPanelSelector.h"
35 #include "XGUI_SelectionMgr.h"
36 #include "XGUI_Tools.h"
37 #include "XGUI_Workshop.h"
38
39 #include <SUIT_ResourceMgr.h>
40
41 #include <AIS_InteractiveContext.hxx>
42 #include <AIS_Shape.hxx>
43 #include <AIS_Trihedron.hxx>
44
45 #include <SelectMgr_SelectionManager.hxx>
46
47 //#define DEBUG_ACTIVATE_OBJECTS
48 //#define DEBUG_DEACTIVATE
49 //#define DEBUG_ACTIVATE_AIS
50 //#define DEBUG_DEACTIVATE_AIS
51
52 #define CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
53
54 //**************************************************************
55 XGUI_SelectionActivate::XGUI_SelectionActivate(ModuleBase_IWorkshop* theWorkshop)
56  : ModuleBase_ISelectionActivate(theWorkshop), myIsTrihedronActive(true)
57 {
58 }
59
60 //**************************************************************
61 XGUI_SelectionActivate::SelectionPlace XGUI_SelectionActivate::activeSelectionPlace() const
62 {
63   XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
64   XGUI_ActiveControlSelector* anActiveSelector = aWorkshop->activeControlMgr()->activeSelector();
65   if (!anActiveSelector)
66     return Workshop;
67
68   if (anActiveSelector->getType() == XGUI_FacesPanelSelector::Type())
69     return FacesPanel;
70   else
71     return PropertyPanel;
72 }
73
74 //**************************************************************
75 void XGUI_SelectionActivate::updateSelectionModes()
76 {
77   QIntList aModes;
78   switch (activeSelectionPlace()) {
79   case Workshop:
80     myWorkshop->module()->activeSelectionModes(aModes);
81     break;
82     case PropertyPanel: {
83       ModuleBase_ModelWidget* anActiveWidget = myWorkshop->module()->activeWidget();
84       if (anActiveWidget)
85         getSelectionModes(anActiveWidget, aModes);
86       else
87         myWorkshop->module()->activeSelectionModes(aModes); //using module modes
88     }
89     break;
90     case FacesPanel: {
91       XGUI_Tools::workshop(myWorkshop)->facesPanel()->selectionModes(aModes);
92       myWorkshop->module()->customSubShapesSelectionModes(aModes); // avoid wire selection
93     }
94     break;
95     default: break;
96   }
97   activateObjects(aModes, getDisplayer()->displayedObjects(), true);
98 }
99
100 //**************************************************************
101 void XGUI_SelectionActivate::updateSelectionFilters()
102 {
103   SelectMgr_ListOfFilter aSelectionFilters;
104   switch (activeSelectionPlace()) {
105   case Workshop:
106     XGUI_Tools::workshop(myWorkshop)->selectionFilters(aSelectionFilters);
107     break;
108     case PropertyPanel: {
109       ModuleBase_ModelWidget* anActiveWidget = myWorkshop->module()->activeWidget();
110       getSelectionFilters(anActiveWidget, aSelectionFilters);
111     }
112     break;
113     case FacesPanel: {
114       //XGUI_Tools::workshop(myWorkshop)->selectionFilters(aSelectionFilters);
115       XGUI_Tools::workshop(myWorkshop)->facesPanel()->selectionFilters(aSelectionFilters);
116     }
117     break;
118     default: break;
119   }
120   activateSelectionFilters(aSelectionFilters);
121 }
122
123 //**************************************************************
124 void XGUI_SelectionActivate::activateSelectionFilters
125   (const SelectMgr_ListOfFilter& theSelectionFilters)
126 {
127   XGUI_Displayer* aDisplayer = getDisplayer();
128   aDisplayer->deactivateSelectionFilters(false);
129
130   SelectMgr_ListIteratorOfListOfFilter aIt(theSelectionFilters);
131   for (; aIt.More(); aIt.Next()) {
132     Handle(SelectMgr_Filter) aFilter = aIt.Value();
133     if (aFilter.IsNull())
134       continue;
135     aDisplayer->addSelectionFilter(aFilter);
136   }
137 }
138
139 //**************************************************************
140 void XGUI_SelectionActivate::getSelectionModes(ModuleBase_ModelWidget* theWidget,
141                                                QIntList& theModes)
142 {
143   if (!theWidget)
144     return;
145
146   bool isAdditional = false;
147   theWidget->selectionModes(theModes, isAdditional);
148   if (isAdditional) {
149     myWorkshop->module()->customSubShapesSelectionModes(theModes);
150     //theModes.append(XGUI_Tools::workshop(myWorkshop)->viewerSelectionModes());
151     //myWorkshop->module()->activeSelectionModes(theModes);
152   }
153 }
154
155 //**************************************************************
156 void XGUI_SelectionActivate::getSelectionFilters(ModuleBase_ModelWidget* theWidget,
157                                                  SelectMgr_ListOfFilter& theSelectionFilters)
158 {
159   XGUI_Tools::workshop(myWorkshop)->selectionFilters(theSelectionFilters);
160
161   if (theWidget)
162     theWidget->selectionFilters(theSelectionFilters);
163 }
164
165 //**************************************************************
166 QIntList XGUI_SelectionActivate::activeSelectionModes() const
167 {
168   QIntList aModes;
169   foreach (int aMode, myActiveSelectionModes) {
170     // aMode < 9 is a Shape Enum values
171     aModes << ((aMode < 9)? AIS_Shape::SelectionType(aMode) : aMode);
172   }
173   return aModes;
174 }
175
176 //**************************************************************
177 bool XGUI_SelectionActivate::isActive(ObjectPtr theObject) const
178 {
179   Handle(AIS_InteractiveContext) aContext = AISContext();
180   if (aContext.IsNull() || !getDisplayer()->isVisible(theObject))
181     return false;
182
183   AISObjectPtr anObj = getDisplayedAISObject(theObject);
184   Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
185
186   TColStd_ListOfInteger aModes;
187   aContext->ActivatedModes(anAIS, aModes);
188
189   return aModes.Extent() > 0;
190 }
191
192 //**************************************************************
193 void XGUI_SelectionActivate::activateObjects(const QIntList& theModes,
194   const QObjectPtrList& theObjList, const bool theUpdateViewer)
195 {
196   setSelectionModes(theModes);
197
198   Handle(AIS_InteractiveContext) aContext = AISContext();
199   // Open local context if there is no one
200   if (aContext.IsNull())
201     return;
202
203   //aContext->UseDisplayedObjects();
204   //myUseExternalObjects = true;
205
206   Handle(AIS_InteractiveObject) anAISIO;
207   AIS_ListOfInteractive aPrsList;
208   AIS_ListOfInteractive aPrsListToBeDeactivated;
209   //if (aObjList.isEmpty())
210   //  return;
211   //else {
212   foreach(ObjectPtr anObject, theObjList) {
213     AISObjectPtr anAISObject = getDisplayedAISObject(anObject);
214     if (!anAISObject.get())
215       continue;
216
217     Handle(AIS_InteractiveObject) aPrs = anAISObject->impl<Handle(AIS_InteractiveObject)>();
218     if (myWorkshop->module()->canActivateSelection(anObject))
219       aPrsList.Append(aPrs);
220     else
221       aPrsListToBeDeactivated.Append(aPrs);
222   }
223   //}
224
225   // Add trihedron because it has to partisipate in selection
226   Handle(AIS_InteractiveObject) aTrihedron;
227   if (isTrihedronActive()) {
228     aTrihedron = getTrihedron();
229     if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron))
230       aPrsList.Append(aTrihedron);
231   }
232   if (aPrsList.Extent() == 0 && aPrsListToBeDeactivated.Extent() == 0)
233     return;
234
235   AIS_ListIteratorOfListOfInteractive aLIt;
236   bool isActivationChanged = false;
237   for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()) {
238     anAISIO = aLIt.Value();
239     if (activate(anAISIO, false))
240       isActivationChanged = true;
241   }
242
243   for(aLIt.Initialize(aPrsListToBeDeactivated); aLIt.More(); aLIt.Next()) {
244     anAISIO = aLIt.Value();
245     deactivateAIS(anAISIO);
246     isActivationChanged = true;
247   }
248 }
249
250 #ifdef DEBUG_ACTIVATE_OBJECTS
251 //**************************************************************
252 QString getModeInfo(const int theMode)
253 {
254   QString anInfo = "Undefined";
255   switch(theMode) {
256     case 0: anInfo = "SHAPE(0)"; break;
257     case 1: anInfo = "VERTEX(1)"; break;
258     case 2: anInfo = "EDGE(2)"; break;
259     case 3: anInfo = "WIRE(3)"; break;
260     case 4: anInfo = "FACE(4)"; break;
261     case 5: anInfo = "SHELL(5)"; break;
262     case 6: anInfo = "SOLID(6)"; break;
263     case 7: anInfo = "COMPSOLID(7)"; break;
264     case 8: anInfo = "COMPOUND(8)"; break;
265     case 100: anInfo = "Sel_Mode_First(100)"; break; //SketcherPrs_Tools
266     case 101: anInfo = "Sel_Constraint(101)"; break;
267     case 102: anInfo = "Sel_Dimension_All(102)"; break;
268     case 103: anInfo = "Sel_Dimension_Line(103)"; break;
269     case 104: anInfo = "Sel_Dimension_Text(104)"; break;
270     default: break;
271   }
272   return anInfo;
273 }
274
275 //**************************************************************
276 QString getModesInfo(const QIntList& theModes)
277 {
278   QStringList aModesInfo;
279   for (int i = 0, aSize = theModes.size(); i < aSize; i++)
280     aModesInfo.append(getModeInfo(theModes[i]));
281   return QString("[%1] = %2").arg(aModesInfo.size()).arg(aModesInfo.join(", "));
282 }
283 #endif
284
285 //**************************************************************
286 void XGUI_SelectionActivate::setSelectionModes(const QIntList& theModes)
287 {
288   // Convert shape types to selection types
289   QIntList aModes;
290   foreach(int aType, theModes) {
291     aModes.append(getSelectionMode(aType));
292   }
293
294 #ifdef DEBUG_ACTIVATE_OBJECTS
295   QStringList anInfo;
296   QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end();
297   for (; anIt != aLast; ++anIt) {
298     anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
299   }
300   QString anInfoStr = anInfo.join(", ");
301
302   qDebug(QString("activateObjects: new modes%1, active modes%2, objects[%3] = %4").
303     arg(getModesInfo(aModes)).
304     arg(getModesInfo(myActiveSelectionModes)).
305     arg(theObjList.size()).
306     arg(anInfoStr).
307     toStdString().c_str());
308 #endif
309   // In order to avoid doblications of selection modes
310   QIntList aNewModes;
311   foreach (int aMode, aModes) {
312     if (!aNewModes.contains(aMode))
313       aNewModes.append(aMode);
314   }
315   myActiveSelectionModes = aNewModes;
316 }
317
318 //**************************************************************
319 void XGUI_SelectionActivate::activateOnDisplay(const Handle(AIS_InteractiveObject)& theIO,
320                                                const bool theUpdateViewer)
321 {
322   if (myActiveSelectionModes.size() == 0)
323     activateAIS(theIO, 0, theUpdateViewer);
324   else {
325     foreach(int aMode, myActiveSelectionModes) {
326       activateAIS(theIO, aMode, theUpdateViewer);
327     }
328   }
329 }
330
331 //**************************************************************
332 void XGUI_SelectionActivate::activateAIS(const Handle(AIS_InteractiveObject)& theIO,
333                                          const int theMode, const bool theUpdateViewer) const
334 {
335   Handle(AIS_InteractiveContext) aContext = AISContext();
336   if (!theIO.IsNull() && theIO == getTrihedron()) {
337     if (theMode != AIS_Shape::SelectionType(TopAbs_EDGE) &&
338         theMode != AIS_Shape::SelectionType(TopAbs_VERTEX))
339       return;
340   }
341   if (!aContext.IsNull()) {
342     if (myWorkshop->module()) {
343       int aMode = (theMode > 8)? theMode : AIS_Shape::SelectionType(theMode);
344       aContext->Activate(theIO, theMode, false);
345     } else
346       aContext->Activate(theIO, theMode, false);
347
348     // the fix from VPA for more suitable selection of sketcher lines
349     if (theIO->Width() > 1) {
350       double aPrecision = theIO->Width() + 2;
351       if (theMode == getSelectionMode(TopAbs_VERTEX))
352         aPrecision = ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer",
353         "point-selection-sensitivity", 12);
354       else if ((theMode == getSelectionMode(TopAbs_EDGE)) ||
355                (theMode == getSelectionMode(TopAbs_WIRE)))
356         aPrecision = theIO->Width() + ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer",
357            "edge-selection-sensitivity", 2);
358       aContext->SetSelectionSensitivity(theIO, theMode, aPrecision);
359     }
360
361 #ifdef DEBUG_ACTIVATE_AIS
362     ObjectPtr anObject = getObject(theIO);
363     anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
364     qDebug(QString("activateAIS: theMode = %1, object = %2").arg(theMode)
365       .arg(anInfo).toStdString().c_str());
366 #endif
367     if (theUpdateViewer)
368       getDisplayer()->updateViewer();
369   }
370 }
371
372 //**************************************************************
373 void XGUI_SelectionActivate::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO,
374                                            const int theMode) const
375 {
376   Handle(AIS_InteractiveContext) aContext = AISContext();
377   if (!aContext.IsNull()) {
378     if (theMode == -1)
379       aContext->Deactivate(theIO);
380     else
381       aContext->Deactivate(theIO, theMode);
382
383 #ifdef DEBUG_DEACTIVATE_AIS
384     ObjectPtr anObject = getObject(theIO);
385     anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
386     qDebug(QString("deactivateAIS: theMode = %1, object = %2").arg(theMode)
387       .arg(anInfo).toStdString().c_str());
388 #endif
389   }
390 }
391
392 //**************************************************************
393 bool XGUI_SelectionActivate::activate(const Handle(AIS_InteractiveObject)& theIO,
394                                       const bool theUpdateViewer) const
395 {
396   Handle(AIS_InteractiveContext) aContext = AISContext();
397   if (aContext.IsNull() || theIO.IsNull())
398     return false;
399
400   bool isActivationChanged = false;
401   // deactivate object in all modes, which are not in the list of activation
402   // It seems that after the IO deactivation the selected state of the IO's owners
403   // is modified in OCC(version: 6.8.0) and the selection of the object later is lost.
404   // By this reason, the number of the IO deactivate is decreased and the object is deactivated
405   // only if there is a difference in the current modes and the parameters modes.
406   // If the selection problem happens again, it is possible to write a test scenario and create
407   // a bug. The bug steps are the following:
408   // Create two IO, activate them in 5 modes, select the first IO, deactivate 3 modes for both,
409   // with clicked SHIFT select the second object.
410   // The result is the selection of the first IO is lost.
411   TColStd_ListOfInteger aTColModes;
412   aContext->ActivatedModes(theIO, aTColModes);
413   TColStd_ListIteratorOfListOfInteger itr( aTColModes );
414   QIntList aModesActivatedForIO;
415   bool isDeactivated = false;
416   bool aHasValidMode = false;
417   for (; itr.More(); itr.Next() ) {
418     Standard_Integer aMode = itr.Value();
419     aHasValidMode = aHasValidMode || aMode != -1;
420     int aShapeMode = (aMode > 8)? aMode : AIS_Shape::SelectionType(aMode);
421     if (!myActiveSelectionModes.contains(aMode)) {
422       deactivateAIS(theIO, aMode);
423       isDeactivated = true;
424     }
425     else {
426       aModesActivatedForIO.append(aMode);
427     }
428   }
429   if (isDeactivated) {
430     // the selection from the previous activation modes should be cleared manually (#26172)
431     //theIO->ClearSelected();
432 #ifndef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
433     XGUI_Tools::workshop(myWorkshop)->selector()->deselectPresentation(theIO);
434 #endif
435     // For performance issues
436     //if (theUpdateViewer)
437     //  getDisplayer()->updateViewer();
438     isActivationChanged = true;
439   }
440
441   // loading the interactive object allowing the decomposition
442   if (aTColModes.IsEmpty() || !aHasValidMode) {
443     aContext->Load(theIO, -1, true);
444     Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
445     if (!aTrihedron.IsNull()) {
446       // Workaround for Trihedron. It should be loaded using the next Load method to
447       // add this object to myGlobal map of selection manager
448       // it is important to activate trihedron in two selection modes: edges and vertices
449       aContext->SelectionManager()->Load(theIO);
450     }
451   }
452
453   // trihedron AIS check should be after the AIS loading.
454   // If it is not loaded, it is steel selectable in the viewer.
455   Handle(AIS_Trihedron) aTrihedron;
456   if (!isTrihedronActive())
457     aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
458   if (aTrihedron.IsNull()) {
459       // In order to clear active modes list
460     if (myActiveSelectionModes.size() == 0) {
461       activateAIS(theIO, 0, theUpdateViewer);
462     } else {
463       foreach(int aMode, myActiveSelectionModes) {
464         if (!aModesActivatedForIO.contains(aMode)) {
465           activateAIS(theIO, aMode, theUpdateViewer);
466           isActivationChanged = true;
467         }
468       }
469     }
470   }
471   return isActivationChanged;
472 }
473
474 //**************************************************************
475 void XGUI_SelectionActivate::deactivate(const ObjectPtr& theObject, const bool theUpdateViewer)
476 {
477 #ifdef DEBUG_DEACTIVATE
478   QString anInfoStr = ModuleBase_Tools::objectInfo(theObject);
479   qDebug(QString("deactivate: myActiveSelectionModes[%1]: %2, objects = ").
480     arg(myActiveSelectionModes.size()).arg(qIntListInfo(myActiveSelectionModes)).
481     arg(anInfoStr).
482     toStdString().c_str());
483 #endif
484   Handle(AIS_InteractiveContext) aContext = AISContext();
485   if (!aContext.IsNull() && getDisplayer()->isVisible(theObject)) {
486     AISObjectPtr anObj = getDisplayedAISObject(theObject);
487     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
488
489     deactivateAIS(anAIS);
490     // the selection from the previous activation modes should be cleared manually (#26172)
491 #ifndef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
492     XGUI_Tools::workshop(myWorkshop)->selector()->deselectPresentation(anAIS);
493 #endif
494     if (theUpdateViewer)
495       getDisplayer()->updateViewer();
496   }
497 }
498
499 /// #1136 hidden axis are selected in sketch
500 #ifdef BEFORE_TRIHEDRON_PATCH
501 //**************************************************************
502 void deactivateObject(Handle(AIS_InteractiveContext) theContext,
503                       Handle(AIS_InteractiveObject) theObject)
504 {
505   if (!theObject.IsNull())
506     theContext->Deactivate(theObject);
507 }
508 #endif
509
510 //**************************************************************
511 void XGUI_SelectionActivate::activateTrihedron(bool theIsActive)
512 {
513   myIsTrihedronActive = theIsActive;
514   if (!myIsTrihedronActive)
515     deactivateTrihedron(true);
516 }
517
518 //**************************************************************
519 void XGUI_SelectionActivate::deactivateTrihedron(const bool theUpdateViewer) const
520 {
521   Handle(AIS_InteractiveObject) aTrihedron = getTrihedron();
522   Handle(AIS_InteractiveContext) aContext = AISContext();
523   if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron)) {
524     Handle(AIS_Trihedron) aTrie = Handle(AIS_Trihedron)::DownCast(aTrihedron);
525     if (!aTrie.IsNull())
526       aContext->Deactivate(aTrie);
527
528     /// #1136 hidden axis are selected in sketch
529 #ifdef BEFORE_TRIHEDRON_PATCH
530     deactivateObject(aContext, aTrie->XAxis());
531     deactivateObject(aContext, aTrie->YAxis());
532     deactivateObject(aContext, aTrie->Axis());
533     deactivateObject(aContext, aTrie->Position());
534
535     deactivateObject(aContext, aTrie->XYPlane());
536     deactivateObject(aContext, aTrie->XZPlane());
537     deactivateObject(aContext, aTrie->YZPlane());
538 #endif
539     if (theUpdateViewer)
540       getDisplayer()->updateViewer();
541   }
542 }
543
544 //**************************************************************
545 void XGUI_SelectionActivate::deactivateTrihedronInSelectionModes()
546 {
547   Handle(AIS_InteractiveContext) aContext = AISContext();
548   Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(getTrihedron());
549   /// deactivate trihedron in selection modes
550   TColStd_ListOfInteger aTColModes;
551   aContext->ActivatedModes(aTrihedron, aTColModes);
552   TColStd_ListIteratorOfListOfInteger itr( aTColModes );
553   for (; itr.More(); itr.Next() ) {
554     Standard_Integer aMode = itr.Value();
555     aContext->Deactivate(aTrihedron, aMode);
556   }
557 }
558
559 //**************************************************************
560 Handle(AIS_InteractiveContext) XGUI_SelectionActivate::AISContext() const
561 {
562   return myWorkshop->viewer()->AISContext();
563 }
564
565 //**************************************************************
566 XGUI_Displayer* XGUI_SelectionActivate::getDisplayer() const
567 {
568   return XGUI_Tools::workshop(myWorkshop)->displayer();
569 }
570
571 //**************************************************************
572 Handle(AIS_InteractiveObject) XGUI_SelectionActivate::getTrihedron() const
573 {
574   return myWorkshop->viewer()->trihedron();
575 }
576
577 //**************************************************************
578 AISObjectPtr XGUI_SelectionActivate::getDisplayedAISObject(ObjectPtr theObject) const
579 {
580   return getDisplayer()->getAISObject(theObject);
581 }
582
583 //**************************************************************
584 int XGUI_SelectionActivate::getSelectionMode(int theShapeType)
585 {
586   return (theShapeType > TopAbs_SHAPE) ? theShapeType :
587                                          AIS_Shape::SelectionMode((TopAbs_ShapeEnum)theShapeType);
588 }