113dbfda6cdceec13c656603d66dfdc89c0faad9
[occt.git] / src / ViewerTest / ViewerTest.cxx
1 // Created on: 1997-07-23
2 // Created by: Henri JEANNIN
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 // Modified by  Eric Gouthiere [sep-oct 98] -> add commands for display...
18 // Modified by  Robert Coublanc [nov 16-17-18 1998]
19 //             -split ViewerTest.cxx into 3 files : ViewerTest.cxx,
20 //                                                  ViewerTest_ObjectCommands.cxx
21 //                                                  ViewerTest_RelationCommands.cxx
22 //             -add Functions and commands for interactive selection of shapes and objects
23 //              in AIS Viewers. (PickShape(s), PickObject(s),
24
25 #include <Standard_Stream.hxx>
26
27 #include <ViewerTest.hxx>
28 #include <ViewerTest_CmdParser.hxx>
29
30 #include <TopLoc_Location.hxx>
31 #include <TopTools_HArray1OfShape.hxx>
32 #include <TColStd_HArray1OfTransient.hxx>
33 #include <TColStd_SequenceOfAsciiString.hxx>
34 #include <TColStd_HSequenceOfAsciiString.hxx>
35 #include <TColStd_MapOfTransient.hxx>
36 #include <OSD_Timer.hxx>
37 #include <Geom_Axis2Placement.hxx>
38 #include <Geom_Axis1Placement.hxx>
39 #include <gp_Trsf.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <BRepAdaptor_Curve.hxx>
42 #include <StdSelect_ShapeTypeFilter.hxx>
43 #include <AIS.hxx>
44 #include <AIS_ColoredShape.hxx>
45 #include <AIS_InteractiveObject.hxx>
46 #include <AIS_Trihedron.hxx>
47 #include <AIS_Axis.hxx>
48 #include <AIS_Relation.hxx>
49 #include <AIS_TypeFilter.hxx>
50 #include <AIS_SignatureFilter.hxx>
51 #include <AIS_LocalContext.hxx>
52 #include <AIS_ListOfInteractive.hxx>
53 #include <AIS_ListIteratorOfListOfInteractive.hxx>
54 #include <Aspect_InteriorStyle.hxx>
55 #include <Aspect_Window.hxx>
56 #include <Graphic3d_AspectFillArea3d.hxx>
57 #include <Graphic3d_AspectLine3d.hxx>
58 #include <Graphic3d_CStructure.hxx>
59 #include <Graphic3d_TextureRoot.hxx>
60 #include <Image_AlienPixMap.hxx>
61 #include <Prs3d_Drawer.hxx>
62 #include <Prs3d_ShadingAspect.hxx>
63 #include <Prs3d_IsoAspect.hxx>
64 #include <Prs3d_PointAspect.hxx>
65 #include <Select3D_SensitiveWire.hxx>
66 #include <Select3D_SensitivePrimitiveArray.hxx>
67 #include <SelectMgr_EntityOwner.hxx>
68 #include <StdSelect_BRepOwner.hxx>
69 #include <StdSelect_ViewerSelector3d.hxx>
70 #include <TopTools_MapOfShape.hxx>
71 #include <ViewerTest_AutoUpdater.hxx>
72
73 #include <stdio.h>
74
75 #include <Draw_Interpretor.hxx>
76 #include <TCollection_AsciiString.hxx>
77 #include <Draw_PluginMacro.hxx>
78
79 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
80
81 #include <Quantity_Color.hxx>
82 #include <Quantity_NameOfColor.hxx>
83
84 #include <Graphic3d_NameOfMaterial.hxx>
85
86 #define DEFAULT_COLOR              Quantity_NOC_GOLDENROD
87 #define DEFAULT_FREEBOUNDARY_COLOR Quantity_NOC_GREEN
88 #define DEFAULT_MATERIAL           Graphic3d_NOM_BRASS
89
90 //=======================================================================
91 //function : GetColorFromName
92 //purpose  : get the Quantity_NameOfColor from a string
93 //=======================================================================
94
95 Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theName)
96 {
97   Quantity_NameOfColor aColor = DEFAULT_COLOR;
98   Quantity_Color::ColorFromName (theName, aColor);
99   return aColor;
100 }
101
102 //=======================================================================
103 //function : ParseColor
104 //purpose  :
105 //=======================================================================
106
107 Standard_Integer ViewerTest::ParseColor (Standard_Integer  theArgNb,
108                                          const char**      theArgVec,
109                                          Quantity_Color&   theColor)
110 {
111   Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
112   if (theArgNb >= 1
113    && Quantity_Color::ColorFromName (theArgVec[0], aColor))
114   {
115     theColor = aColor;
116     return 1;
117   }
118   else if (theArgNb >= 3)
119   {
120     const TCollection_AsciiString anRgbStr[3] =
121     {
122       theArgVec[0],
123       theArgVec[1],
124       theArgVec[2]
125     };
126     if (!anRgbStr[0].IsRealValue()
127      || !anRgbStr[1].IsRealValue()
128      || !anRgbStr[2].IsRealValue())
129     {
130       return 0;
131     }
132
133     Graphic3d_Vec4d anRgb;
134     anRgb.x() = anRgbStr[0].RealValue();
135     anRgb.y() = anRgbStr[1].RealValue();
136     anRgb.z() = anRgbStr[2].RealValue();
137     if (anRgb.x() < 0.0 || anRgb.x() > 1.0
138      || anRgb.y() < 0.0 || anRgb.y() > 1.0
139      || anRgb.z() < 0.0 || anRgb.z() > 1.0)
140     {
141       std::cout << "Error: RGB color values should be within range 0..1!\n";
142       return 0;
143     }
144
145     theColor.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
146     return 3;
147   }
148
149   return 0;
150 }
151
152 //=======================================================================
153 //function : ParseOnOff
154 //purpose  :
155 //=======================================================================
156 Standard_Boolean ViewerTest::ParseOnOff (Standard_CString  theArg,
157                                          Standard_Boolean& theIsOn)
158 {
159   TCollection_AsciiString aFlag(theArg);
160   aFlag.LowerCase();
161   if (aFlag == "on"
162    || aFlag == "1")
163   {
164     theIsOn = Standard_True;
165     return Standard_True;
166   }
167   else if (aFlag == "off"
168         || aFlag == "0")
169   {
170     theIsOn = Standard_False;
171     return Standard_True;
172   }
173   return Standard_False;
174 }
175
176 //=======================================================================
177 //function : GetTypeNames
178 //purpose  :
179 //=======================================================================
180 static const char** GetTypeNames()
181 {
182   static const char* names[14] = {"Point","Axis","Trihedron","PlaneTrihedron", "Line","Circle","Plane",
183                           "Shape","ConnectedShape","MultiConn.Shape",
184                           "ConnectedInter.","MultiConn.",
185                           "Constraint","Dimension"};
186   static const char** ThePointer = names;
187   return ThePointer;
188 }
189
190 //=======================================================================
191 //function : GetTypeAndSignfromString
192 //purpose  :
193 //=======================================================================
194 void GetTypeAndSignfromString (const char* name,AIS_KindOfInteractive& TheType,Standard_Integer& TheSign)
195 {
196   const char ** thefullnames = GetTypeNames();
197   Standard_Integer index(-1);
198
199   for(Standard_Integer i=0;i<=13 && index==-1;i++)
200     if(!strcasecmp(name,thefullnames[i]))
201       index = i;
202
203   if(index ==-1){
204     TheType = AIS_KOI_None;
205     TheSign = -1;
206     return;
207   }
208
209   if(index<=6){
210     TheType = AIS_KOI_Datum;
211     TheSign = index+1;
212   }
213   else if (index <=9){
214     TheType = AIS_KOI_Shape;
215     TheSign = index-7;
216   }
217   else if(index<=11){
218     TheType = AIS_KOI_Object;
219     TheSign = index-10;
220   }
221   else{
222     TheType = AIS_KOI_Relation;
223     TheSign = index-12;
224   }
225
226 }
227
228
229
230 #include <string.h>
231 #include <Draw_Interpretor.hxx>
232 #include <Draw.hxx>
233 #include <Draw_Appli.hxx>
234 #include <DBRep.hxx>
235
236
237 #include <TCollection_AsciiString.hxx>
238 #include <V3d_Viewer.hxx>
239 #include <V3d_View.hxx>
240 #include <V3d.hxx>
241
242 #include <AIS_InteractiveContext.hxx>
243 #include <AIS_Shape.hxx>
244 #include <AIS_TexturedShape.hxx>
245 #include <AIS_DisplayMode.hxx>
246 #include <TColStd_MapOfInteger.hxx>
247 #include <AIS_MapOfInteractive.hxx>
248 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
249 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
250 #include <ViewerTest_EventManager.hxx>
251
252 #include <TopoDS_Solid.hxx>
253 #include <BRepTools.hxx>
254 #include <BRep_Builder.hxx>
255 #include <TopAbs_ShapeEnum.hxx>
256
257 #include <TopoDS.hxx>
258 #include <BRep_Tool.hxx>
259
260
261 #include <Draw_Window.hxx>
262 #include <AIS_ListIteratorOfListOfInteractive.hxx>
263 #include <AIS_ListOfInteractive.hxx>
264 #include <AIS_DisplayMode.hxx>
265 #include <TopTools_ListOfShape.hxx>
266 #include <BRepOffsetAPI_MakeThickSolid.hxx>
267 #include <BRepOffset.hxx>
268
269 //==============================================================================
270 //  VIEWER OBJECT MANAGEMENT GLOBAL VARIABLES
271 //==============================================================================
272 Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(){
273   static ViewerTest_DoubleMapOfInteractiveAndName TheMap;
274   return TheMap;
275 }
276
277 //=======================================================================
278 //function : Display
279 //purpose  :
280 //=======================================================================
281 Standard_Boolean ViewerTest::Display (const TCollection_AsciiString&       theName,
282                                       const Handle(AIS_InteractiveObject)& theObject,
283                                       const Standard_Boolean               theToUpdate,
284                                       const Standard_Boolean               theReplaceIfExists)
285 {
286   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
287   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
288   if (aCtx.IsNull())
289   {
290     std::cout << "Error: AIS context is not available.\n";
291     return Standard_False;
292   }
293
294   if (aMap.IsBound2 (theName))
295   {
296     if (!theReplaceIfExists)
297     {
298       std::cout << "Error: other interactive object has been already registered with name: " << theName << ".\n"
299                 << "Please use another name.\n";
300       return Standard_False;
301     }
302
303     Handle(AIS_InteractiveObject) anOldObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theName));
304     if (!anOldObj.IsNull())
305     {
306       aCtx->Remove (anOldObj, Standard_True);
307     }
308     aMap.UnBind2 (theName);
309   }
310
311   if (theObject.IsNull())
312   {
313     // object with specified name has been already unbound
314     return Standard_True;
315   }
316
317   // unbind AIS object if it was bound with another name
318   aMap.UnBind1 (theObject);
319
320   // can be registered without rebinding
321   aMap.Bind (theObject, theName);
322   aCtx->Display (theObject, theToUpdate);
323   return Standard_True;
324 }
325
326 //! Alias for ViewerTest::Display(), compatibility with old code.
327 Standard_EXPORT Standard_Boolean VDisplayAISObject (const TCollection_AsciiString&       theName,
328                                                     const Handle(AIS_InteractiveObject)& theObject,
329                                                     Standard_Boolean theReplaceIfExists = Standard_True)
330 {
331   return ViewerTest::Display (theName, theObject, Standard_True, theReplaceIfExists);
332 }
333
334 static TColStd_MapOfInteger theactivatedmodes(8);
335 static TColStd_ListOfTransient theEventMgrs;
336
337 static void VwrTst_InitEventMgr(const Handle(V3d_View)& aView,
338                                 const Handle(AIS_InteractiveContext)& Ctx)
339 {
340   theEventMgrs.Clear();
341   theEventMgrs.Prepend(new ViewerTest_EventManager(aView, Ctx));
342 }
343
344 static Handle(V3d_View)&  a3DView()
345 {
346   static Handle(V3d_View) Viou;
347   return Viou;
348 }
349
350
351 Standard_EXPORT Handle(AIS_InteractiveContext)& TheAISContext(){
352   static Handle(AIS_InteractiveContext) aContext;
353   return aContext;
354 }
355
356 const Handle(V3d_View)& ViewerTest::CurrentView()
357 {
358   return a3DView();
359 }
360 void ViewerTest::CurrentView(const Handle(V3d_View)& V)
361 {
362   a3DView() = V;
363 }
364
365 const Handle(AIS_InteractiveContext)& ViewerTest::GetAISContext()
366 {
367   return TheAISContext();
368 }
369
370 void ViewerTest::SetAISContext (const Handle(AIS_InteractiveContext)& aCtx)
371 {
372   TheAISContext() = aCtx;
373   ViewerTest::ResetEventManager();
374 }
375
376 Handle(V3d_Viewer) ViewerTest::GetViewerFromContext()
377 {
378   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
379 }
380
381 Handle(V3d_Viewer) ViewerTest::GetCollectorFromContext()
382 {
383   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
384 }
385
386
387 void ViewerTest::SetEventManager(const Handle(ViewerTest_EventManager)& EM){
388   theEventMgrs.Prepend(EM);
389 }
390
391 void ViewerTest::UnsetEventManager()
392 {
393   theEventMgrs.RemoveFirst();
394 }
395
396
397 void ViewerTest::ResetEventManager()
398 {
399   const Handle(V3d_View) aView = ViewerTest::CurrentView();
400   VwrTst_InitEventMgr(aView, ViewerTest::GetAISContext());
401 }
402
403 Handle(ViewerTest_EventManager) ViewerTest::CurrentEventManager()
404 {
405   Handle(ViewerTest_EventManager) EM;
406   if(theEventMgrs.IsEmpty()) return EM;
407   Handle(Standard_Transient) Tr =  theEventMgrs.First();
408   EM = Handle(ViewerTest_EventManager)::DownCast (Tr);
409   return EM;
410 }
411
412 //=======================================================================
413 //function : Get Context and active view
414 //purpose  :
415 //=======================================================================
416 static Standard_Boolean getCtxAndView (Handle(AIS_InteractiveContext)& theCtx,
417                                        Handle(V3d_View)&               theView)
418 {
419   theCtx  = ViewerTest::GetAISContext();
420   theView = ViewerTest::CurrentView();
421   if (theCtx.IsNull()
422    || theView.IsNull())
423   {
424     std::cout << "Error: cannot find an active view!\n";
425     return Standard_False;
426   }
427   return Standard_True;
428 }
429
430 //==============================================================================
431 //function : GetShapeFromName
432 //purpose  : Compute an Shape from a draw variable or a file name
433 //==============================================================================
434
435 static TopoDS_Shape GetShapeFromName(const char* name)
436 {
437   TopoDS_Shape S = DBRep::Get(name);
438
439   if ( S.IsNull() ) {
440         BRep_Builder aBuilder;
441         BRepTools::Read( S, name, aBuilder);
442   }
443
444   return S;
445 }
446
447 //==============================================================================
448 //function : GetAISShapeFromName
449 //purpose  : Compute an AIS_Shape from a draw variable or a file name
450 //==============================================================================
451 Handle(AIS_Shape) GetAISShapeFromName(const char* name)
452 {
453   Handle(AIS_Shape) retsh;
454
455   if(GetMapOfAIS().IsBound2(name)){
456     const Handle(AIS_InteractiveObject) IO =
457       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
458     if (!IO.IsNull()) {
459       if(IO->Type()==AIS_KOI_Shape) {
460         if(IO->Signature()==0){
461           retsh = Handle(AIS_Shape)::DownCast (IO);
462         }
463         else
464           cout << "an Object which is not an AIS_Shape "
465             "already has this name!!!"<<endl;
466       }
467     }
468     return retsh;
469   }
470
471
472   TopoDS_Shape S = GetShapeFromName(name);
473   if ( !S.IsNull() ) {
474     retsh = new AIS_Shape(S);
475   }
476   return retsh;
477 }
478
479
480 //==============================================================================
481 //function : Clear
482 //purpose  : Remove all the object from the viewer
483 //==============================================================================
484 void ViewerTest::Clear()
485 {
486   if ( !a3DView().IsNull() ) {
487     if (TheAISContext()->HasOpenedContext())
488       TheAISContext()->CloseLocalContext();
489     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName it(GetMapOfAIS());
490     while ( it.More() ) {
491       cout << "Remove " << it.Key2() << endl;
492       const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (it.Key1());
493       TheAISContext()->Remove(anObj,Standard_False);
494       it.Next();
495     }
496     TheAISContext()->RebuildSelectionStructs();
497     TheAISContext()->UpdateCurrentViewer();
498     GetMapOfAIS().Clear();
499   }
500 }
501
502 //==============================================================================
503 //function : StandardModesActivation
504 //purpose  : Activate a selection mode, vertex, edge, wire ..., in a local
505 //           Context
506 //==============================================================================
507 void ViewerTest::StandardModeActivation(const Standard_Integer mode )
508 {
509   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
510   if(mode==0) {
511     if (TheAISContext()->HasOpenedContext())
512       aContext->CloseLocalContext();
513   } else {
514
515     if(!aContext->HasOpenedContext()) {
516       // To unhilight the preselected object
517       aContext->UnhilightSelected(Standard_False);
518       // Open a local Context in order to be able to select subshape from
519       // the selected shape if any or for all if there is no selection
520       if (!aContext->FirstSelectedObject().IsNull()){
521         aContext->OpenLocalContext(Standard_False);
522
523         for(aContext->InitSelected();aContext->MoreSelected();aContext->NextSelected()){
524           aContext->Load(       aContext->SelectedInteractive(),-1,Standard_True);
525         }
526       }
527       else
528         aContext->OpenLocalContext();
529     }
530
531     const char *cmode="???";
532
533     switch (mode) {
534     case 0: cmode = "Shape"; break;
535     case 1: cmode = "Vertex"; break;
536     case 2: cmode = "Edge"; break;
537     case 3: cmode = "Wire"; break;
538     case 4: cmode = "Face"; break;
539     case 5: cmode = "Shell"; break;
540     case 6: cmode = "Solid"; break;
541     case 7: cmode = "Compsolid"; break;
542     case 8: cmode = "Compound"; break;
543     }
544
545     if(theactivatedmodes.Contains(mode))
546       { // Desactivate
547         aContext->DeactivateStandardMode(AIS_Shape::SelectionType(mode));
548         theactivatedmodes.Remove(mode);
549         cout<<"Mode "<< cmode <<" OFF"<<endl;
550       }
551     else
552       { // Activate
553         aContext->ActivateStandardMode(AIS_Shape::SelectionType(mode));
554         theactivatedmodes.Add(mode);
555         cout<<"Mode "<< cmode << " ON" << endl;
556       }
557   }
558 }
559
560 //==============================================================================
561 //function : CopyIsoAspect
562 //purpose  : Returns copy Prs3d_IsoAspect with new number of isolines.
563 //==============================================================================
564 static Handle(Prs3d_IsoAspect) CopyIsoAspect
565       (const Handle(Prs3d_IsoAspect) &theIsoAspect,
566        const Standard_Integer theNbIsos)
567 {
568   Quantity_Color    aColor = theIsoAspect->Aspect()->Color();
569   Aspect_TypeOfLine aType  = theIsoAspect->Aspect()->Type();
570   Standard_Real     aWidth = theIsoAspect->Aspect()->Width();
571
572   Handle(Prs3d_IsoAspect) aResult =
573     new Prs3d_IsoAspect(aColor, aType, aWidth, theNbIsos);
574
575   return aResult;
576 }
577
578 //==============================================================================
579 //function : visos
580 //purpose  : Returns or sets the number of U- and V- isos and isIsoOnPlane flag
581 //Draw arg : [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]
582 //==============================================================================
583 static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
584 {
585   if (TheAISContext().IsNull()) {
586     di << argv[0] << " Call 'vinit' before!\n";
587     return 1;
588   }
589
590   if (argc <= 1) {
591     di << "Current number of isos : " <<
592       TheAISContext()->IsoNumber(AIS_TOI_IsoU) << " " <<
593       TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n";
594     di << "IsoOnPlane mode is " <<
595       (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n";
596     di << "IsoOnTriangulation mode is " <<
597       (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n";
598     return 0;
599   }
600
601   Standard_Integer aLastInd = argc - 1;
602   Standard_Boolean isChanged = Standard_False;
603   Standard_Integer aNbUIsos = 0;
604   Standard_Integer aNbVIsos = 0;
605
606   if (aLastInd >= 3) {
607     Standard_Boolean isIsoOnPlane = Standard_False;
608
609     if (strcmp(argv[aLastInd], "1") == 0) {
610       isIsoOnPlane = Standard_True;
611       isChanged    = Standard_True;
612     } else if (strcmp(argv[aLastInd], "0") == 0) {
613       isIsoOnPlane = Standard_False;
614       isChanged    = Standard_True;
615     }
616
617     if (isChanged) {
618       aNbVIsos = Draw::Atoi(argv[aLastInd - 1]);
619       aNbUIsos = Draw::Atoi(argv[aLastInd - 2]);
620       aLastInd -= 3;
621
622       di << "New number of isos : " << aNbUIsos << " " << aNbVIsos << "\n";
623       di << "New IsoOnPlane mode is " << (isIsoOnPlane ? "ON" : "OFF") << "\n";
624
625       TheAISContext()->IsoOnPlane(isIsoOnPlane);
626
627       if (aLastInd == 0) {
628         // If there are no shapes provided set the default numbers.
629         TheAISContext()->SetIsoNumber(aNbUIsos, AIS_TOI_IsoU);
630         TheAISContext()->SetIsoNumber(aNbVIsos, AIS_TOI_IsoV);
631       }
632     }
633   }
634
635   Standard_Integer i;
636
637   for (i = 1; i <= aLastInd; i++) {
638     TCollection_AsciiString name(argv[i]);
639     Standard_Boolean IsBound = GetMapOfAIS().IsBound2(name);
640
641     if (IsBound) {
642       const Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(name);
643       if (anObj->IsKind(STANDARD_TYPE(AIS_InteractiveObject))) {
644         const Handle(AIS_InteractiveObject) aShape =
645         Handle(AIS_InteractiveObject)::DownCast (anObj);
646         Handle(Prs3d_Drawer) CurDrawer = aShape->Attributes();
647         Handle(Prs3d_IsoAspect) aUIso = CurDrawer->UIsoAspect();
648         Handle(Prs3d_IsoAspect) aVIso = CurDrawer->VIsoAspect();
649
650         if (isChanged) {
651           CurDrawer->SetUIsoAspect(CopyIsoAspect(aUIso, aNbUIsos));
652           CurDrawer->SetVIsoAspect(CopyIsoAspect(aVIso, aNbVIsos));
653           TheAISContext()->SetLocalAttributes
654                   (aShape, CurDrawer, Standard_False);
655           TheAISContext()->Redisplay(aShape);
656         } else {
657           di << "Number of isos for " << argv[i] << " : "
658              << aUIso->Number() << " " << aVIso->Number() << "\n";
659         }
660       } else {
661         di << argv[i] << ": Not an AIS interactive object!\n";
662       }
663     } else {
664       di << argv[i] << ": Use 'vdisplay' before\n";
665     }
666   }
667
668   if (isChanged) {
669     TheAISContext()->UpdateCurrentViewer();
670   }
671
672   return 0;
673 }
674
675 static Standard_Integer VDispSensi (Draw_Interpretor& ,
676                                     Standard_Integer  theArgNb,
677                                     Standard_CString* )
678 {
679   if (theArgNb > 1)
680   {
681     std::cout << "Error: wrong syntax!\n";
682     return 1;
683   }
684
685   Handle(AIS_InteractiveContext) aCtx;
686   Handle(V3d_View)               aView;
687   if (!getCtxAndView (aCtx, aView))
688   {
689     return 1;
690   }
691
692   aCtx->DisplayActiveSensitive (aView);
693   return 0;
694
695 }
696
697 static Standard_Integer VClearSensi (Draw_Interpretor& ,
698                                      Standard_Integer  theArgNb,
699                                      Standard_CString* )
700 {
701   if (theArgNb > 1)
702   {
703     std::cout << "Error: wrong syntax!\n";
704     return 1;
705   }
706
707   Handle(AIS_InteractiveContext) aCtx;
708   Handle(V3d_View)               aView;
709   if (!getCtxAndView (aCtx, aView))
710   {
711     return 1;
712   }
713   aCtx->ClearActiveSensitive (aView);
714   return 0;
715 }
716
717 //==============================================================================
718 //function : VDir
719 //purpose  : To list the displayed object with their attributes
720 //==============================================================================
721 static int VDir (Draw_Interpretor& theDI,
722                  Standard_Integer ,
723                  const char** )
724 {
725   if (!a3DView().IsNull())
726   {
727     return 0;
728   }
729
730   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
731        anIter.More(); anIter.Next())
732   {
733     theDI << "\t" << anIter.Key2().ToCString() << "\n";
734   }
735   return 0;
736 }
737
738 //==============================================================================
739 //function : VSelPrecision
740 //purpose  : To set the selection tolerance value
741 //Draw arg : Selection tolerance value (real value determining the width and
742 //           height of selecting frustum bases). Without arguments the function
743 //           just prints current tolerance.
744 //==============================================================================
745 static int VSelPrecision(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
746 {
747   if( argc > 2 )
748   {
749     di << "Wrong parameters! Must be: " << argv[0] << " [-unset] [tolerance]\n";
750     return 1;
751   }
752
753   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
754   if( aContext.IsNull() )
755     return 1;
756
757   if( argc == 1 )
758   {
759     Standard_Real aPixelTolerance = aContext->PixelTolerance();
760     di << "Pixel tolerance : " << aPixelTolerance << "\n";
761   }
762   else if (argc == 2)
763   {
764     TCollection_AsciiString anArg = TCollection_AsciiString (argv[1]);
765     anArg.LowerCase();
766     if (anArg == "-unset")
767     {
768       aContext->SetPixelTolerance (-1);
769     }
770     else
771     {
772       aContext->SetPixelTolerance (anArg.IntegerValue());
773     }
774   }
775
776   return 0;
777 }
778
779 //! Auxiliary enumeration
780 enum ViewerTest_StereoPair
781 {
782   ViewerTest_SP_Single,
783   ViewerTest_SP_SideBySide,
784   ViewerTest_SP_OverUnder
785 };
786
787 //==============================================================================
788 //function : VDump
789 //purpose  : To dump the active view snapshot to image file
790 //==============================================================================
791 static Standard_Integer VDump (Draw_Interpretor& theDI,
792                                Standard_Integer  theArgNb,
793                                Standard_CString* theArgVec)
794 {
795   if (theArgNb < 2)
796   {
797     std::cout << "Error: wrong number of arguments! Image file name should be specified at least.\n";
798     return 1;
799   }
800
801   Standard_Integer      anArgIter   = 1;
802   Standard_CString      aFilePath   = theArgVec[anArgIter++];
803   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
804   V3d_ImageDumpOptions  aParams;
805   aParams.BufferType    = Graphic3d_BT_RGB;
806   aParams.StereoOptions = V3d_SDO_MONO;
807   for (; anArgIter < theArgNb; ++anArgIter)
808   {
809     TCollection_AsciiString anArg (theArgVec[anArgIter]);
810     anArg.LowerCase();
811     if (anArg == "-buffer")
812     {
813       if (++anArgIter >= theArgNb)
814       {
815         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
816         return 1;
817       }
818
819       TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
820       aBufArg.LowerCase();
821       if (aBufArg == "rgba")
822       {
823         aParams.BufferType = Graphic3d_BT_RGBA;
824       }
825       else if (aBufArg == "rgb")
826       {
827         aParams.BufferType = Graphic3d_BT_RGB;
828       }
829       else if (aBufArg == "depth")
830       {
831         aParams.BufferType = Graphic3d_BT_Depth;
832       }
833       else
834       {
835         std::cout << "Error: unknown buffer '" << aBufArg << "'\n";
836         return 1;
837       }
838     }
839     else if (anArg == "-stereo")
840     {
841       if (++anArgIter >= theArgNb)
842       {
843         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
844         return 1;
845       }
846
847       TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
848       aStereoArg.LowerCase();
849       if (aStereoArg == "l"
850        || aStereoArg == "left")
851       {
852         aParams.StereoOptions = V3d_SDO_LEFT_EYE;
853       }
854       else if (aStereoArg == "r"
855             || aStereoArg == "right")
856       {
857         aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
858       }
859       else if (aStereoArg == "mono")
860       {
861         aParams.StereoOptions = V3d_SDO_MONO;
862       }
863       else if (aStereoArg == "blended"
864             || aStereoArg == "blend"
865             || aStereoArg == "stereo")
866       {
867         aParams.StereoOptions = V3d_SDO_BLENDED;
868       }
869       else if (aStereoArg == "sbs"
870             || aStereoArg == "sidebyside")
871       {
872         aStereoPair = ViewerTest_SP_SideBySide;
873       }
874       else if (aStereoArg == "ou"
875             || aStereoArg == "overunder")
876       {
877         aStereoPair = ViewerTest_SP_OverUnder;
878       }
879       else
880       {
881         std::cout << "Error: unknown stereo format '" << aStereoArg << "'\n";
882         return 1;
883       }
884     }
885     else if (anArg == "-rgba"
886           || anArg ==  "rgba")
887     {
888       aParams.BufferType = Graphic3d_BT_RGBA;
889     }
890     else if (anArg == "-rgb"
891           || anArg ==  "rgb")
892     {
893       aParams.BufferType = Graphic3d_BT_RGB;
894     }
895     else if (anArg == "-depth"
896           || anArg ==  "depth")
897     {
898       aParams.BufferType = Graphic3d_BT_Depth;
899     }
900     else if (anArg == "-width"
901           || anArg ==  "width"
902           || anArg ==  "sizex")
903     {
904       if (aParams.Width != 0)
905       {
906         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
907         return 1;
908       }
909       else if (++anArgIter >= theArgNb)
910       {
911         std::cout << "Error: integer value is expected right after 'width'\n";
912         return 1;
913       }
914       aParams.Width = Draw::Atoi (theArgVec[anArgIter]);
915     }
916     else if (anArg == "-height"
917           || anArg ==  "height"
918           || anArg ==  "-sizey")
919     {
920       if (aParams.Height != 0)
921       {
922         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
923         return 1;
924       }
925       else if (++anArgIter >= theArgNb)
926       {
927         std::cout << "Error: integer value is expected right after 'height'\n";
928         return 1;
929       }
930       aParams.Height = Draw::Atoi (theArgVec[anArgIter]);
931     }
932     else if (anArg == "-tile"
933           || anArg == "-tilesize")
934     {
935       if (++anArgIter >= theArgNb)
936       {
937         std::cout << "Error: integer value is expected right after 'tileSize'\n";
938         return 1;
939       }
940       aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
941     }
942     else
943     {
944       std::cout << "Error: unknown argument '" << theArgVec[anArgIter] << "'\n";
945       return 1;
946     }
947   }
948   if ((aParams.Width <= 0 && aParams.Height >  0)
949    || (aParams.Width >  0 && aParams.Height <= 0))
950   {
951     std::cout << "Error: dimensions " << aParams.Width << "x" << aParams.Height << " are incorrect\n";
952     return 1;
953   }
954
955   Handle(V3d_View) aView = ViewerTest::CurrentView();
956   if (aView.IsNull())
957   {
958     std::cout << "Error: cannot find an active view!\n";
959     return 1;
960   }
961
962   if (aParams.Width <= 0 || aParams.Height <= 0)
963   {
964     aView->Window()->Size (aParams.Width, aParams.Height);
965   }
966
967   Image_AlienPixMap aPixMap;
968
969   bool isBigEndian = Image_PixMap::IsBigEndianHost();
970   Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
971   switch (aParams.BufferType)
972   {
973     case Graphic3d_BT_RGB:   aFormat = isBigEndian ? Image_PixMap::ImgRGB  : Image_PixMap::ImgBGR;  break;
974     case Graphic3d_BT_RGBA:  aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
975     case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
976   }
977
978   switch (aStereoPair)
979   {
980     case ViewerTest_SP_Single:
981     {
982       if (!aView->ToPixMap (aPixMap, aParams))
983       {
984         theDI << "Fail: view dump failed!\n";
985         return 0;
986       }
987       else if (aPixMap.SizeX() != Standard_Size(aParams.Width)
988             || aPixMap.SizeY() != Standard_Size(aParams.Height))
989       {
990         theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
991               << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
992       }
993       break;
994     }
995     case ViewerTest_SP_SideBySide:
996     {
997       if (!aPixMap.InitZero (aFormat, aParams.Width * 2, aParams.Height))
998       {
999         theDI << "Fail: not enough memory for image allocation!\n";
1000         return 0;
1001       }
1002
1003       Image_PixMap aPixMapL, aPixMapR;
1004       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1005                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1006       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aParams.Width,
1007                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1008
1009       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1010       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1011       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1012       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1013       if (!isOk)
1014       {
1015         theDI << "Fail: view dump failed!\n";
1016         return 0;
1017       }
1018       break;
1019     }
1020     case ViewerTest_SP_OverUnder:
1021     {
1022       if (!aPixMap.InitZero (aFormat, aParams.Width, aParams.Height * 2))
1023       {
1024         theDI << "Fail: not enough memory for image allocation!\n";
1025         return 0;
1026       }
1027
1028       Image_PixMap aPixMapL, aPixMapR;
1029       aPixMapL.InitWrapper (aFormat, aPixMap.ChangeData(),
1030                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1031       aPixMapR.InitWrapper (aFormat, aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
1032                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1033
1034       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1035       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1036       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1037       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1038       if (!isOk)
1039       {
1040         theDI << "Fail: view dump failed!\n";
1041         return 0;
1042       }
1043       break;
1044     }
1045   }
1046
1047   if (!aPixMap.Save (aFilePath))
1048   {
1049     theDI << "Fail: image can not be saved!\n";
1050   }
1051   return 0;
1052 }
1053
1054 enum TypeOfDispOperation
1055 {
1056   TypeOfDispOperation_SetDispMode,
1057   TypeOfDispOperation_UnsetDispMode
1058 };
1059
1060 //! Displays,Erase...
1061 static void VwrTst_DispErase (const Handle(AIS_InteractiveObject)& thePrs,
1062                                                 const Standard_Integer theMode,
1063                                                 const TypeOfDispOperation theType,
1064                                                 const Standard_Boolean theToUpdate)
1065 {
1066   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1067   switch (theType)
1068   {
1069     case TypeOfDispOperation_SetDispMode:
1070     {
1071       if (!thePrs.IsNull())
1072       {
1073         aCtx->SetDisplayMode (thePrs, theMode, theToUpdate);
1074       }
1075       else
1076       {
1077         aCtx->SetDisplayMode ((AIS_DisplayMode )theMode, theToUpdate);
1078       }
1079       break;
1080     }
1081     case TypeOfDispOperation_UnsetDispMode:
1082     {
1083       if (!thePrs.IsNull())
1084       {
1085         aCtx->UnsetDisplayMode (thePrs, theToUpdate);
1086       }
1087       else
1088       {
1089         aCtx->SetDisplayMode (AIS_WireFrame, theToUpdate);
1090       }
1091       break;
1092     }
1093   }
1094 }
1095
1096 //=======================================================================
1097 //function :
1098 //purpose  :
1099 //=======================================================================
1100 static int VDispMode (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1101 {
1102   if (argc < 1
1103    || argc > 3)
1104   {
1105     std::cout << "Syntax error: wrong number of arguments\n";
1106     return 1;
1107   }
1108
1109   TypeOfDispOperation aType = TCollection_AsciiString (argv[0]) == "vunsetdispmode"
1110                             ? TypeOfDispOperation_UnsetDispMode
1111                             : TypeOfDispOperation_SetDispMode;
1112   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1113   if (aType == TypeOfDispOperation_UnsetDispMode)
1114   {
1115     if (argc == 1)
1116     {
1117       if (aCtx->NbSelected() == 0)
1118       {
1119         VwrTst_DispErase (Handle(AIS_InteractiveObject)(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1120       }
1121       else
1122       {
1123         for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1124         {
1125           VwrTst_DispErase (aCtx->SelectedInteractive(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1126         }
1127       }
1128       aCtx->UpdateCurrentViewer();
1129     }
1130     else
1131     {
1132       TCollection_AsciiString aName = argv[1];
1133       if (GetMapOfAIS().IsBound2 (aName))
1134       {
1135         Handle(AIS_InteractiveObject) aPrs = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2 (aName));
1136         if (!aPrs.IsNull())
1137         {
1138           VwrTst_DispErase (aPrs, -1, TypeOfDispOperation_UnsetDispMode, Standard_True);
1139         }
1140       }
1141     }
1142   }
1143   else if (argc == 2)
1144   {
1145     Standard_Integer aDispMode = Draw::Atoi (argv[1]);
1146     if (aCtx->NbSelected() == 0
1147      && aType == TypeOfDispOperation_SetDispMode)
1148     {
1149       VwrTst_DispErase (Handle(AIS_InteractiveObject)(), aDispMode, TypeOfDispOperation_SetDispMode, Standard_True);
1150     }
1151     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1152     {
1153       VwrTst_DispErase (aCtx->SelectedInteractive(), aDispMode, aType, Standard_False);
1154     }
1155     aCtx->UpdateCurrentViewer();
1156   }
1157   else
1158   {
1159     Handle(AIS_InteractiveObject) aPrs;
1160     TCollection_AsciiString aName (argv[1]);
1161     if (GetMapOfAIS().IsBound2 (aName))
1162     {
1163       aPrs = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2 (aName));
1164     }
1165     if (!aPrs.IsNull())
1166     {
1167       VwrTst_DispErase (aPrs, Draw::Atoi(argv[2]), aType, Standard_True);
1168     }
1169   }
1170   return 0;
1171 }
1172
1173
1174 //=======================================================================
1175 //function :
1176 //purpose  :
1177 //=======================================================================
1178 static int VSubInt(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1179 {
1180   if(argc==1) return 1;
1181   Standard_Integer On = Draw::Atoi(argv[1]);
1182   const Handle(AIS_InteractiveContext)& Ctx = ViewerTest::GetAISContext();
1183
1184   if(argc==2)
1185   {
1186     TCollection_AsciiString isOnOff = On == 1 ? "on" : "off";
1187     di << "Sub intensite is turned " << isOnOff << " for " << Ctx->NbSelected() << "objects\n";
1188     for (Ctx->InitSelected(); Ctx->MoreSelected(); Ctx->NextSelected())
1189     {
1190       if(On==1)
1191       {
1192         Ctx->SubIntensityOn (Ctx->SelectedInteractive(), Standard_False);
1193       }
1194       else
1195       {
1196         Ctx->SubIntensityOff (Ctx->SelectedInteractive(), Standard_False);
1197       }
1198     }
1199
1200     Ctx->UpdateCurrentViewer();
1201   }
1202   else {
1203     Handle(AIS_InteractiveObject) IO;
1204     TCollection_AsciiString name = argv[2];
1205     if(GetMapOfAIS().IsBound2(name)){
1206       IO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
1207       if (!IO.IsNull()) {
1208         if(On==1)
1209           Ctx->SubIntensityOn(IO);
1210         else
1211           Ctx->SubIntensityOff(IO);
1212       }
1213     }
1214     else return 1;
1215   }
1216   return 0;
1217 }
1218
1219 //! Auxiliary class to iterate presentations from different collections.
1220 class ViewTest_PrsIter
1221 {
1222 public:
1223
1224   //! Create and initialize iterator object.
1225   ViewTest_PrsIter (const TCollection_AsciiString& theName)
1226   : mySource (IterSource_All)
1227   {
1228     NCollection_Sequence<TCollection_AsciiString> aNames;
1229     if (!theName.IsEmpty())
1230     aNames.Append (theName);
1231     Init (aNames);
1232   }
1233
1234   //! Create and initialize iterator object.
1235   ViewTest_PrsIter (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1236   : mySource (IterSource_All)
1237   {
1238     Init (theNames);
1239   }
1240
1241   //! Initialize the iterator.
1242   void Init (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1243   {
1244     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1245     mySeq = theNames;
1246     mySelIter.Nullify();
1247     myCurrent.Nullify();
1248     myCurrentTrs.Nullify();
1249     if (!mySeq.IsEmpty())
1250     {
1251       mySource = IterSource_List;
1252       mySeqIter = NCollection_Sequence<TCollection_AsciiString>::Iterator (mySeq);
1253     }
1254     else if (aCtx->NbSelected() > 0)
1255     {
1256       mySource  = IterSource_Selected;
1257       mySelIter = aCtx;
1258       mySelIter->InitSelected();
1259     }
1260     else
1261     {
1262       mySource = IterSource_All;
1263       myMapIter.Initialize (GetMapOfAIS());
1264     }
1265     initCurrent();
1266   }
1267
1268   const TCollection_AsciiString& CurrentName() const
1269   {
1270     return myCurrentName;
1271   }
1272
1273   const Handle(AIS_InteractiveObject)& Current() const
1274   {
1275     return myCurrent;
1276   }
1277
1278   const Handle(Standard_Transient)& CurrentTrs() const
1279   {
1280     return myCurrentTrs;
1281   }
1282
1283   //! @return true if iterator points to valid object within collection
1284   Standard_Boolean More() const
1285   {
1286     switch (mySource)
1287     {
1288       case IterSource_All:      return myMapIter.More();
1289       case IterSource_List:     return mySeqIter.More();
1290       case IterSource_Selected: return mySelIter->MoreSelected();
1291     }
1292     return Standard_False;
1293   }
1294
1295   //! Go to the next item.
1296   void Next()
1297   {
1298     myCurrentName.Clear();
1299     myCurrentTrs.Nullify();
1300     myCurrent.Nullify();
1301     switch (mySource)
1302     {
1303       case IterSource_All:
1304       {
1305         myMapIter.Next();
1306         break;
1307       }
1308       case IterSource_List:
1309       {
1310         mySeqIter.Next();
1311         break;
1312       }
1313       case IterSource_Selected:
1314       {
1315         mySelIter->NextSelected();
1316         break;
1317       }
1318     }
1319     initCurrent();
1320   }
1321
1322 private:
1323
1324   void initCurrent()
1325   {
1326     switch (mySource)
1327     {
1328       case IterSource_All:
1329       {
1330         if (myMapIter.More())
1331         {
1332           myCurrentName = myMapIter.Key2();
1333           myCurrentTrs  = myMapIter.Key1();
1334           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1335         }
1336         break;
1337       }
1338       case IterSource_List:
1339       {
1340         if (mySeqIter.More())
1341         {
1342           if (!GetMapOfAIS().IsBound2 (mySeqIter.Value()))
1343           {
1344             std::cout << "Error: object " << mySeqIter.Value() << " is not displayed!\n";
1345             return;
1346           }
1347           myCurrentName = mySeqIter.Value();
1348           myCurrentTrs  = GetMapOfAIS().Find2 (mySeqIter.Value());
1349           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1350         }
1351         break;
1352       }
1353       case IterSource_Selected:
1354       {
1355         if (mySelIter->MoreSelected())
1356         {
1357           myCurrentName = GetMapOfAIS().Find1 (mySelIter->SelectedInteractive());
1358           myCurrent     = mySelIter->SelectedInteractive();
1359         }
1360         break;
1361       }
1362     }
1363   }
1364
1365 private:
1366
1367   enum IterSource
1368   {
1369     IterSource_All,
1370     IterSource_List,
1371     IterSource_Selected
1372   };
1373
1374 private:
1375
1376   Handle(AIS_InteractiveContext) mySelIter;    //!< iterator for current (selected) objects (IterSource_Selected)
1377   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName myMapIter; //!< iterator for map of all objects (IterSource_All)
1378   NCollection_Sequence<TCollection_AsciiString>           mySeq;
1379   NCollection_Sequence<TCollection_AsciiString>::Iterator mySeqIter;
1380
1381   TCollection_AsciiString        myCurrentName;//!< current item name
1382   Handle(Standard_Transient)     myCurrentTrs; //!< current item (as transient object)
1383   Handle(AIS_InteractiveObject)  myCurrent;    //!< current item
1384
1385   IterSource                     mySource;     //!< iterated collection
1386
1387 };
1388
1389 //==============================================================================
1390 //function : VInteriorStyle
1391 //purpose  : sets interior style of the a selected or named or displayed shape
1392 //==============================================================================
1393 static int VSetInteriorStyle (Draw_Interpretor& theDI,
1394                               Standard_Integer  theArgNb,
1395                               const char**      theArgVec)
1396 {
1397   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1398   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
1399   if (aCtx.IsNull())
1400   {
1401     std::cerr << "Error: no active view!\n";
1402     return 1;
1403   }
1404
1405   Standard_Integer anArgIter = 1;
1406   for (; anArgIter < theArgNb; ++anArgIter)
1407   {
1408     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
1409     {
1410       break;
1411     }
1412   }
1413   TCollection_AsciiString aName;
1414   if (theArgNb - anArgIter == 2)
1415   {
1416     aName = theArgVec[anArgIter++];
1417   }
1418   else if (theArgNb - anArgIter != 1)
1419   {
1420     std::cout << "Error: wrong number of arguments! See usage:\n";
1421     theDI.PrintHelp (theArgVec[0]);
1422     return 1;
1423   }
1424   Standard_Integer        anInterStyle = Aspect_IS_SOLID;
1425   TCollection_AsciiString aStyleArg (theArgVec[anArgIter++]);
1426   aStyleArg.LowerCase();
1427   if (aStyleArg == "empty")
1428   {
1429     anInterStyle = 0;
1430   }
1431   else if (aStyleArg == "hollow")
1432   {
1433     anInterStyle = 1;
1434   }
1435   else if (aStyleArg == "hatch")
1436   {
1437     anInterStyle = 2;
1438   }
1439   else if (aStyleArg == "solid")
1440   {
1441     anInterStyle = 3;
1442   }
1443   else if (aStyleArg == "hiddenline")
1444   {
1445     anInterStyle = 4;
1446   }
1447   else
1448   {
1449     anInterStyle = aStyleArg.IntegerValue();
1450   }
1451   if (anInterStyle < Aspect_IS_EMPTY
1452    || anInterStyle > Aspect_IS_HIDDENLINE)
1453   {
1454     std::cout << "Error: style must be within a range [0 (Aspect_IS_EMPTY), "
1455               << Aspect_IS_HIDDENLINE << " (Aspect_IS_HIDDENLINE)]\n";
1456     return 1;
1457   }
1458
1459   if (!aName.IsEmpty()
1460    && !GetMapOfAIS().IsBound2 (aName))
1461   {
1462     std::cout << "Error: object " << aName << " is not displayed!\n";
1463     return 1;
1464   }
1465
1466   if (aCtx->HasOpenedContext())
1467   {
1468     aCtx->CloseLocalContext();
1469   }
1470   for (ViewTest_PrsIter anIter (aName); anIter.More(); anIter.Next())
1471   {
1472     const Handle(AIS_InteractiveObject)& anIO = anIter.Current();
1473     if (!anIO.IsNull())
1474     {
1475       const Handle(Prs3d_Drawer)& aDrawer        = anIO->Attributes();
1476       Handle(Prs3d_ShadingAspect) aShadingAspect = aDrawer->ShadingAspect();
1477       Handle(Graphic3d_AspectFillArea3d) aFillAspect = aShadingAspect->Aspect();
1478       aFillAspect->SetInteriorStyle ((Aspect_InteriorStyle )anInterStyle);
1479       aCtx->RecomputePrsOnly (anIO, Standard_False, Standard_True);
1480     }
1481   }
1482   return 0;
1483 }
1484
1485 //! Auxiliary structure for VAspects
1486 struct ViewerTest_AspectsChangeSet
1487 {
1488   Standard_Integer         ToSetVisibility;
1489   Standard_Integer         Visibility;
1490
1491   Standard_Integer         ToSetColor;
1492   Quantity_Color           Color;
1493
1494   Standard_Integer         ToSetLineWidth;
1495   Standard_Real            LineWidth;
1496
1497   Standard_Integer         ToSetTypeOfLine;
1498   Aspect_TypeOfLine        TypeOfLine;
1499
1500   Standard_Integer         ToSetTransparency;
1501   Standard_Real            Transparency;
1502
1503   Standard_Integer         ToSetMaterial;
1504   Graphic3d_NameOfMaterial Material;
1505   TCollection_AsciiString  MatName;
1506
1507   NCollection_Sequence<TopoDS_Shape> SubShapes;
1508
1509   Standard_Integer         ToSetShowFreeBoundary;
1510   Standard_Integer         ToSetFreeBoundaryWidth;
1511   Standard_Real            FreeBoundaryWidth;
1512   Standard_Integer         ToSetFreeBoundaryColor;
1513   Quantity_Color           FreeBoundaryColor;
1514
1515   Standard_Integer         ToEnableIsoOnTriangulation;
1516
1517   Standard_Integer         ToSetMaxParamValue;
1518   Standard_Real            MaxParamValue;
1519
1520   Standard_Integer         ToSetSensitivity;
1521   Standard_Integer         SelectionMode;
1522   Standard_Integer         Sensitivity;
1523
1524   //! Empty constructor
1525   ViewerTest_AspectsChangeSet()
1526   : ToSetVisibility   (0),
1527     Visibility        (1),
1528     ToSetColor        (0),
1529     Color             (DEFAULT_COLOR),
1530     ToSetLineWidth    (0),
1531     LineWidth         (1.0),
1532     ToSetTypeOfLine   (0),
1533     TypeOfLine        (Aspect_TOL_SOLID),
1534     ToSetTransparency (0),
1535     Transparency      (0.0),
1536     ToSetMaterial     (0),
1537     Material          (Graphic3d_NOM_DEFAULT),
1538     ToSetShowFreeBoundary      (0),
1539     ToSetFreeBoundaryWidth     (0),
1540     FreeBoundaryWidth          (1.0),
1541     ToSetFreeBoundaryColor     (0),
1542     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
1543     ToEnableIsoOnTriangulation (-1),
1544     ToSetMaxParamValue (0),
1545     MaxParamValue (500000),
1546     ToSetSensitivity (0),
1547     SelectionMode (-1),
1548     Sensitivity (-1) {}
1549
1550   //! @return true if no changes have been requested
1551   Standard_Boolean IsEmpty() const
1552   {
1553     return ToSetVisibility        == 0
1554         && ToSetLineWidth         == 0
1555         && ToSetTransparency      == 0
1556         && ToSetColor             == 0
1557         && ToSetMaterial          == 0
1558         && ToSetShowFreeBoundary  == 0
1559         && ToSetFreeBoundaryColor == 0
1560         && ToSetFreeBoundaryWidth == 0
1561         && ToSetMaxParamValue     == 0
1562         && ToSetSensitivity       == 0;
1563   }
1564
1565   //! @return true if properties are valid
1566   Standard_Boolean Validate (const Standard_Boolean theIsSubPart) const
1567   {
1568     Standard_Boolean isOk = Standard_True;
1569     if (Visibility != 0 && Visibility != 1)
1570     {
1571       std::cout << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")\n";
1572       isOk = Standard_False;
1573     }
1574     if (LineWidth <= 0.0
1575      || LineWidth >  10.0)
1576     {
1577       std::cout << "Error: the width should be within [1; 10] range (specified " << LineWidth << ")\n";
1578       isOk = Standard_False;
1579     }
1580     if (Transparency < 0.0
1581      || Transparency > 1.0)
1582     {
1583       std::cout << "Error: the transparency should be within [0; 1] range (specified " << Transparency << ")\n";
1584       isOk = Standard_False;
1585     }
1586     if (theIsSubPart
1587      && ToSetTransparency)
1588     {
1589       std::cout << "Error: the transparency can not be defined for sub-part of object!\n";
1590       isOk = Standard_False;
1591     }
1592     if (ToSetMaterial == 1
1593      && Material == Graphic3d_NOM_DEFAULT)
1594     {
1595       std::cout << "Error: unknown material " << MatName << ".\n";
1596       isOk = Standard_False;
1597     }
1598     if (FreeBoundaryWidth <= 0.0
1599      || FreeBoundaryWidth >  10.0)
1600     {
1601       std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
1602       isOk = Standard_False;
1603     }
1604     if (MaxParamValue < 0.0)
1605     {
1606       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
1607       isOk = Standard_False;
1608     }
1609     if (Sensitivity <= 0 && ToSetSensitivity)
1610     {
1611       std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
1612       isOk = Standard_False;
1613     }
1614     return isOk;
1615   }
1616
1617 };
1618
1619 //==============================================================================
1620 //function : VAspects
1621 //purpose  :
1622 //==============================================================================
1623 static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
1624                                   Standard_Integer  theArgNb,
1625                                   const char**      theArgVec)
1626 {
1627   TCollection_AsciiString aCmdName (theArgVec[0]);
1628   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1629   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
1630   if (aCtx.IsNull())
1631   {
1632     std::cerr << "Error: no active view!\n";
1633     return 1;
1634   }
1635
1636   Standard_Integer anArgIter = 1;
1637   Standard_Boolean isDefaults = Standard_False;
1638   NCollection_Sequence<TCollection_AsciiString> aNames;
1639   for (; anArgIter < theArgNb; ++anArgIter)
1640   {
1641     TCollection_AsciiString anArg = theArgVec[anArgIter];
1642     if (anUpdateTool.parseRedrawMode (anArg))
1643     {
1644       continue;
1645     }
1646     else if (!anArg.IsEmpty()
1647            && anArg.Value (1) != '-')
1648     {
1649       aNames.Append (anArg);
1650     }
1651     else
1652     {
1653       if (anArg == "-defaults")
1654       {
1655         isDefaults = Standard_True;
1656         ++anArgIter;
1657       }
1658       break;
1659     }
1660   }
1661
1662   if (!aNames.IsEmpty() && isDefaults)
1663   {
1664     std::cout << "Error: wrong syntax. If -defaults is used there should not be any objects' names!\n";
1665     return 1;
1666   }
1667
1668   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
1669   aChanges.Append (ViewerTest_AspectsChangeSet());
1670   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
1671
1672   // parse syntax of legacy commands
1673   if (aCmdName == "vsetwidth")
1674   {
1675     if (aNames.IsEmpty()
1676     || !aNames.Last().IsRealValue())
1677     {
1678       std::cout << "Error: not enough arguments!\n";
1679       return 1;
1680     }
1681     aChangeSet->ToSetLineWidth = 1;
1682     aChangeSet->LineWidth = aNames.Last().RealValue();
1683     aNames.Remove (aNames.Length());
1684   }
1685   else if (aCmdName == "vunsetwidth")
1686   {
1687     aChangeSet->ToSetLineWidth = -1;
1688   }
1689   else if (aCmdName == "vsetcolor")
1690   {
1691     if (aNames.IsEmpty())
1692     {
1693       std::cout << "Error: not enough arguments!\n";
1694       return 1;
1695     }
1696     aChangeSet->ToSetColor = 1;
1697
1698     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
1699     Standard_Boolean     isOk   = Standard_False;
1700     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
1701     {
1702       aChangeSet->Color = aColor;
1703       aNames.Remove (aNames.Length());
1704       isOk = Standard_True;
1705     }
1706     else if (aNames.Length() >= 3)
1707     {
1708       const TCollection_AsciiString anRgbStr[3] =
1709       {
1710         aNames.Value (aNames.Upper() - 2),
1711         aNames.Value (aNames.Upper() - 1),
1712         aNames.Value (aNames.Upper() - 0)
1713       };
1714       isOk = anRgbStr[0].IsRealValue()
1715           && anRgbStr[1].IsRealValue()
1716           && anRgbStr[2].IsRealValue();
1717       if (isOk)
1718       {
1719         Graphic3d_Vec4d anRgb;
1720         anRgb.x() = anRgbStr[0].RealValue();
1721         anRgb.y() = anRgbStr[1].RealValue();
1722         anRgb.z() = anRgbStr[2].RealValue();
1723         if (anRgb.x() < 0.0 || anRgb.x() > 1.0
1724          || anRgb.y() < 0.0 || anRgb.y() > 1.0
1725          || anRgb.z() < 0.0 || anRgb.z() > 1.0)
1726         {
1727           std::cout << "Error: RGB color values should be within range 0..1!\n";
1728           return 1;
1729         }
1730         aChangeSet->Color.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
1731         aNames.Remove (aNames.Length());
1732         aNames.Remove (aNames.Length());
1733         aNames.Remove (aNames.Length());
1734       }
1735     }
1736     if (!isOk)
1737     {
1738       std::cout << "Error: not enough arguments!\n";
1739       return 1;
1740     }
1741   }
1742   else if (aCmdName == "vunsetcolor")
1743   {
1744     aChangeSet->ToSetColor = -1;
1745   }
1746   else if (aCmdName == "vsettransparency")
1747   {
1748     if (aNames.IsEmpty()
1749     || !aNames.Last().IsRealValue())
1750     {
1751       std::cout << "Error: not enough arguments!\n";
1752       return 1;
1753     }
1754     aChangeSet->ToSetTransparency = 1;
1755     aChangeSet->Transparency  = aNames.Last().RealValue();
1756     aNames.Remove (aNames.Length());
1757   }
1758   else if (aCmdName == "vunsettransparency")
1759   {
1760     aChangeSet->ToSetTransparency = -1;
1761   }
1762   else if (aCmdName == "vsetmaterial")
1763   {
1764     if (aNames.IsEmpty())
1765     {
1766       std::cout << "Error: not enough arguments!\n";
1767       return 1;
1768     }
1769     aChangeSet->ToSetMaterial = 1;
1770     aChangeSet->MatName  = aNames.Last();
1771     aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
1772     aNames.Remove (aNames.Length());
1773   }
1774   else if (aCmdName == "vunsetmaterial")
1775   {
1776     aChangeSet->ToSetMaterial = -1;
1777   }
1778   else if (anArgIter >= theArgNb)
1779   {
1780     std::cout << "Error: not enough arguments!\n";
1781     return 1;
1782   }
1783
1784   if (!aChangeSet->IsEmpty())
1785   {
1786     anArgIter = theArgNb;
1787   }
1788   for (; anArgIter < theArgNb; ++anArgIter)
1789   {
1790     TCollection_AsciiString anArg = theArgVec[anArgIter];
1791     anArg.LowerCase();
1792     if (anArg == "-setwidth"
1793      || anArg == "-setlinewidth")
1794     {
1795       if (++anArgIter >= theArgNb)
1796       {
1797         std::cout << "Error: wrong syntax at " << anArg << "\n";
1798         return 1;
1799       }
1800       aChangeSet->ToSetLineWidth = 1;
1801       aChangeSet->LineWidth = Draw::Atof (theArgVec[anArgIter]);
1802     }
1803     else if (anArg == "-unsetwidth"
1804           || anArg == "-unsetlinewidth")
1805     {
1806       aChangeSet->ToSetLineWidth = -1;
1807       aChangeSet->LineWidth = 1.0;
1808     }
1809     else if (anArg == "-settransp"
1810           || anArg == "-settransparency")
1811     {
1812       if (++anArgIter >= theArgNb)
1813       {
1814         std::cout << "Error: wrong syntax at " << anArg << "\n";
1815         return 1;
1816       }
1817       aChangeSet->ToSetTransparency = 1;
1818       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
1819       if (aChangeSet->Transparency >= 0.0
1820        && aChangeSet->Transparency <= Precision::Confusion())
1821       {
1822         aChangeSet->ToSetTransparency = -1;
1823         aChangeSet->Transparency = 0.0;
1824       }
1825     }
1826     else if (anArg == "-setvis"
1827           || anArg == "-setvisibility")
1828     {
1829       if (++anArgIter >= theArgNb)
1830       {
1831         std::cout << "Error: wrong syntax at " << anArg << "\n";
1832         return 1;
1833       }
1834
1835       aChangeSet->ToSetVisibility = 1;
1836       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
1837     }
1838     else if (anArg == "-setalpha")
1839     {
1840       if (++anArgIter >= theArgNb)
1841       {
1842         std::cout << "Error: wrong syntax at " << anArg << "\n";
1843         return 1;
1844       }
1845       aChangeSet->ToSetTransparency = 1;
1846       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
1847       if (aChangeSet->Transparency < 0.0
1848        || aChangeSet->Transparency > 1.0)
1849       {
1850         std::cout << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")\n";
1851         return 1;
1852       }
1853       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
1854       if (aChangeSet->Transparency >= 0.0
1855        && aChangeSet->Transparency <= Precision::Confusion())
1856       {
1857         aChangeSet->ToSetTransparency = -1;
1858         aChangeSet->Transparency = 0.0;
1859       }
1860     }
1861     else if (anArg == "-unsettransp"
1862           || anArg == "-unsettransparency"
1863           || anArg == "-unsetalpha"
1864           || anArg == "-opaque")
1865     {
1866       aChangeSet->ToSetTransparency = -1;
1867       aChangeSet->Transparency = 0.0;
1868     }
1869     else if (anArg == "-setcolor")
1870     {
1871       Standard_Integer aNbComps  = 0;
1872       Standard_Integer aCompIter = anArgIter + 1;
1873       for (; aCompIter < theArgNb; ++aCompIter, ++aNbComps)
1874       {
1875         if (theArgVec[aCompIter][0] == '-')
1876         {
1877           break;
1878         }
1879       }
1880       switch (aNbComps)
1881       {
1882         case 1:
1883         {
1884           Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
1885           Standard_CString     aName  = theArgVec[anArgIter + 1];
1886           if (!Quantity_Color::ColorFromName (aName, aColor))
1887           {
1888             std::cout << "Error: unknown color name '" << aName << "'\n";
1889             return 1;
1890           }
1891           aChangeSet->Color = aColor;
1892           break;
1893         }
1894         case 3:
1895         {
1896           Graphic3d_Vec3d anRgb;
1897           anRgb.x() = Draw::Atof (theArgVec[anArgIter + 1]);
1898           anRgb.y() = Draw::Atof (theArgVec[anArgIter + 2]);
1899           anRgb.z() = Draw::Atof (theArgVec[anArgIter + 3]);
1900           if (anRgb.x() < 0.0 || anRgb.x() > 1.0
1901            || anRgb.y() < 0.0 || anRgb.y() > 1.0
1902            || anRgb.z() < 0.0 || anRgb.z() > 1.0)
1903           {
1904             std::cout << "Error: RGB color values should be within range 0..1!\n";
1905             return 1;
1906           }
1907           aChangeSet->Color.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
1908           break;
1909         }
1910         default:
1911         {
1912           std::cout << "Error: wrong syntax at " << anArg << "\n";
1913           return 1;
1914         }
1915       }
1916       aChangeSet->ToSetColor = 1;
1917       anArgIter += aNbComps;
1918     }
1919     else if (anArg == "-setlinetype")
1920     {
1921       if (++anArgIter >= theArgNb)
1922       {
1923         std::cout << "Error: wrong syntax at " << anArg << "\n";
1924         return 1;
1925       }
1926
1927       TCollection_AsciiString aValue (theArgVec[anArgIter]);
1928       aValue.LowerCase();
1929
1930       if (aValue.IsEqual ("solid"))
1931       {
1932         aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
1933       }
1934       else if (aValue.IsEqual ("dot"))
1935       {
1936         aChangeSet->TypeOfLine = Aspect_TOL_DOT;
1937       }
1938       else if (aValue.IsEqual ("dash"))
1939       {
1940         aChangeSet->TypeOfLine = Aspect_TOL_DASH;
1941       }
1942       else if (aValue.IsEqual ("dotdash"))
1943       {
1944         aChangeSet->TypeOfLine = Aspect_TOL_DOTDASH;
1945       }
1946       else
1947       {
1948         std::cout << "Error: wrong syntax at " << anArg << "\n";
1949         return 1;
1950       }
1951
1952       aChangeSet->ToSetTypeOfLine = 1;
1953     }
1954     else if (anArg == "-unsetlinetype")
1955     {
1956       aChangeSet->ToSetTypeOfLine = -1;
1957     }
1958     else if (anArg == "-unsetcolor")
1959     {
1960       aChangeSet->ToSetColor = -1;
1961       aChangeSet->Color = DEFAULT_COLOR;
1962     }
1963     else if (anArg == "-setmat"
1964           || anArg == "-setmaterial")
1965     {
1966       if (++anArgIter >= theArgNb)
1967       {
1968         std::cout << "Error: wrong syntax at " << anArg << "\n";
1969         return 1;
1970       }
1971       aChangeSet->ToSetMaterial = 1;
1972       aChangeSet->MatName  = theArgVec[anArgIter];
1973       aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
1974     }
1975     else if (anArg == "-unsetmat"
1976           || anArg == "-unsetmaterial")
1977     {
1978       aChangeSet->ToSetMaterial = -1;
1979       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
1980     }
1981     else if (anArg == "-subshape"
1982           || anArg == "-subshapes")
1983     {
1984       if (isDefaults)
1985       {
1986         std::cout << "Error: wrong syntax. -subshapes can not be used together with -defaults call!\n";
1987         return 1;
1988       }
1989
1990       if (aNames.IsEmpty())
1991       {
1992         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
1993         return 1;
1994       }
1995
1996       aChanges.Append (ViewerTest_AspectsChangeSet());
1997       aChangeSet = &aChanges.ChangeLast();
1998
1999       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
2000       {
2001         Standard_CString aSubShapeName = theArgVec[anArgIter];
2002         if (*aSubShapeName == '-')
2003         {
2004           --anArgIter;
2005           break;
2006         }
2007
2008         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
2009         if (aSubShape.IsNull())
2010         {
2011           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
2012           return 1;
2013         }
2014         aChangeSet->SubShapes.Append (aSubShape);
2015       }
2016
2017       if (aChangeSet->SubShapes.IsEmpty())
2018       {
2019         std::cerr << "Error: empty list is specified after -subshapes!\n";
2020         return 1;
2021       }
2022     }
2023     else if (anArg == "-freeboundary"
2024           || anArg == "-fb")
2025     {
2026       if (++anArgIter >= theArgNb)
2027       {
2028         std::cout << "Error: wrong syntax at " << anArg << "\n";
2029         return 1;
2030       }
2031       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2032       aValue.LowerCase();
2033       if (aValue == "on"
2034        || aValue == "1")
2035       {
2036         aChangeSet->ToSetShowFreeBoundary = 1;
2037       }
2038       else if (aValue == "off"
2039             || aValue == "0")
2040       {
2041         aChangeSet->ToSetShowFreeBoundary = -1;
2042       }
2043       else
2044       {
2045         std::cout << "Error: wrong syntax at " << anArg << "\n";
2046         return 1;
2047       }
2048     }
2049     else if (anArg == "-setfreeboundarywidth"
2050           || anArg == "-setfbwidth")
2051     {
2052       if (++anArgIter >= theArgNb)
2053       {
2054         std::cout << "Error: wrong syntax at " << anArg << "\n";
2055         return 1;
2056       }
2057       aChangeSet->ToSetFreeBoundaryWidth = 1;
2058       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2059     }
2060     else if (anArg == "-unsetfreeboundarywidth"
2061           || anArg == "-unsetfbwidth")
2062     {
2063       aChangeSet->ToSetFreeBoundaryWidth = -1;
2064       aChangeSet->FreeBoundaryWidth = 1.0;
2065     }
2066     else if (anArg == "-setfreeboundarycolor"
2067           || anArg == "-setfbcolor")
2068     {
2069       Standard_Integer aNbComps  = 0;
2070       Standard_Integer aCompIter = anArgIter + 1;
2071       for (; aCompIter < theArgNb; ++aCompIter, ++aNbComps)
2072       {
2073         if (theArgVec[aCompIter][0] == '-')
2074         {
2075           break;
2076         }
2077       }
2078       switch (aNbComps)
2079       {
2080         case 1:
2081         {
2082           Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2083           Standard_CString     aName  = theArgVec[anArgIter + 1];
2084           if (!Quantity_Color::ColorFromName (aName, aColor))
2085           {
2086             std::cout << "Error: unknown free boundary color name '" << aName << "'\n";
2087             return 1;
2088           }
2089           aChangeSet->FreeBoundaryColor = aColor;
2090           break;
2091         }
2092         case 3:
2093         {
2094           Graphic3d_Vec3d anRgb;
2095           anRgb.x() = Draw::Atof (theArgVec[anArgIter + 1]);
2096           anRgb.y() = Draw::Atof (theArgVec[anArgIter + 2]);
2097           anRgb.z() = Draw::Atof (theArgVec[anArgIter + 3]);
2098           if (anRgb.x() < 0.0 || anRgb.x() > 1.0
2099            || anRgb.y() < 0.0 || anRgb.y() > 1.0
2100            || anRgb.z() < 0.0 || anRgb.z() > 1.0)
2101           {
2102             std::cout << "Error: free boundary RGB color values should be within range 0..1!\n";
2103             return 1;
2104           }
2105           aChangeSet->FreeBoundaryColor.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
2106           break;
2107         }
2108         default:
2109         {
2110           std::cout << "Error: wrong syntax at " << anArg << "\n";
2111           return 1;
2112         }
2113       }
2114       aChangeSet->ToSetFreeBoundaryColor = 1;
2115       anArgIter += aNbComps;
2116     }
2117     else if (anArg == "-unsetfreeboundarycolor"
2118           || anArg == "-unsetfbcolor")
2119     {
2120       aChangeSet->ToSetFreeBoundaryColor = -1;
2121       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2122     }
2123     else if (anArg == "-unset")
2124     {
2125       aChangeSet->ToSetVisibility = 1;
2126       aChangeSet->Visibility = 1;
2127       aChangeSet->ToSetLineWidth = -1;
2128       aChangeSet->LineWidth = 1.0;
2129       aChangeSet->ToSetTypeOfLine = -1;
2130       aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
2131       aChangeSet->ToSetTransparency = -1;
2132       aChangeSet->Transparency = 0.0;
2133       aChangeSet->ToSetColor = -1;
2134       aChangeSet->Color = DEFAULT_COLOR;
2135       aChangeSet->ToSetMaterial = -1;
2136       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2137       aChangeSet->ToSetShowFreeBoundary = -1;
2138       aChangeSet->ToSetFreeBoundaryColor = -1;
2139       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2140       aChangeSet->ToSetFreeBoundaryWidth = -1;
2141       aChangeSet->FreeBoundaryWidth = 1.0;
2142     }
2143     else if (anArg == "-isoontriangulation"
2144           || anArg == "-isoontriang")
2145     {
2146       if (++anArgIter >= theArgNb)
2147       {
2148         std::cout << "Error: wrong syntax at " << anArg << "\n";
2149         return 1;
2150       }
2151       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2152       aValue.LowerCase();
2153       if (aValue == "on"
2154         || aValue == "1")
2155       {
2156         aChangeSet->ToEnableIsoOnTriangulation = 1;
2157       }
2158       else if (aValue == "off"
2159         || aValue == "0")
2160       {
2161         aChangeSet->ToEnableIsoOnTriangulation = 0;
2162       }
2163       else
2164       {
2165         std::cout << "Error: wrong syntax at " << anArg << "\n";
2166         return 1;
2167       }
2168     }
2169     else if (anArg == "-setmaxparamvalue")
2170     {
2171       if (++anArgIter >= theArgNb)
2172       {
2173         std::cout << "Error: wrong syntax at " << anArg << "\n";
2174         return 1;
2175       }
2176       aChangeSet->ToSetMaxParamValue = 1;
2177       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
2178     }
2179     else if (anArg == "-setsensitivity")
2180     {
2181       if (isDefaults)
2182       {
2183         std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
2184         return 1;
2185       }
2186
2187       if (aNames.IsEmpty())
2188       {
2189         std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
2190         return 1;
2191       }
2192
2193       if (anArgIter + 2 >= theArgNb)
2194       {
2195         std::cout << "Error: wrong syntax at " << anArg << "\n";
2196         return 1;
2197       }
2198       aChangeSet->ToSetSensitivity = 1;
2199       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
2200       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
2201     }
2202     else
2203     {
2204       std::cout << "Error: wrong syntax at " << anArg << "\n";
2205       return 1;
2206     }
2207   }
2208
2209   Standard_Boolean isFirst = Standard_True;
2210   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2211        aChangesIter.More(); aChangesIter.Next())
2212   {
2213     if (!aChangesIter.Value().Validate (!isFirst))
2214     {
2215       return 1;
2216     }
2217     isFirst = Standard_False;
2218   }
2219
2220   if (aCtx->HasOpenedContext())
2221   {
2222     aCtx->CloseLocalContext();
2223   }
2224
2225   // special case for -defaults parameter.
2226   // all changed values will be set to DefaultDrawer.
2227   if (isDefaults)
2228   {
2229     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
2230
2231     if (aChangeSet->ToSetLineWidth != 0)
2232     {
2233       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
2234       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
2235       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
2236       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
2237     }
2238     if (aChangeSet->ToSetColor != 0)
2239     {
2240       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
2241       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
2242       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
2243       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
2244       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
2245       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
2246     }
2247     if (aChangeSet->ToSetTypeOfLine != 0)
2248     {
2249       aDrawer->LineAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2250       aDrawer->WireAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2251       aDrawer->FreeBoundaryAspect()->SetTypeOfLine   (aChangeSet->TypeOfLine);
2252       aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine);
2253       aDrawer->SeenLineAspect()->SetTypeOfLine       (aChangeSet->TypeOfLine);
2254     }
2255     if (aChangeSet->ToSetTransparency != 0)
2256     {
2257       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
2258     }
2259     if (aChangeSet->ToSetMaterial != 0)
2260     {
2261       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
2262     }
2263     if (aChangeSet->ToSetShowFreeBoundary == 1)
2264     {
2265       aDrawer->SetFreeBoundaryDraw (Standard_True);
2266     }
2267     else if (aChangeSet->ToSetShowFreeBoundary == -1)
2268     {
2269       aDrawer->SetFreeBoundaryDraw (Standard_False);
2270     }
2271     if (aChangeSet->ToSetFreeBoundaryWidth != 0)
2272     {
2273       aDrawer->FreeBoundaryAspect()->SetWidth (aChangeSet->FreeBoundaryWidth);
2274     }
2275     if (aChangeSet->ToSetFreeBoundaryColor != 0)
2276     {
2277       aDrawer->FreeBoundaryAspect()->SetColor (aChangeSet->FreeBoundaryColor);
2278     }
2279     if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2280     {
2281       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
2282     }
2283     if (aChangeSet->ToSetMaxParamValue != 0)
2284     {
2285       aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2286     }
2287
2288     // redisplay all objects in context
2289     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2290     {
2291       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
2292       if (!aPrs.IsNull())
2293       {
2294         aCtx->Redisplay (aPrs, Standard_False);
2295       }
2296     }
2297     return 0;
2298   }
2299
2300   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2301   {
2302     const TCollection_AsciiString& aName   = aPrsIter.CurrentName();
2303     Handle(AIS_InteractiveObject)  aPrs    = aPrsIter.Current();
2304     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
2305     Handle(AIS_ColoredShape) aColoredPrs;
2306     Standard_Boolean toDisplay = Standard_False;
2307     Standard_Boolean toRedisplay = Standard_False;
2308     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
2309     {
2310       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
2311       if (aShapePrs.IsNull())
2312       {
2313         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
2314         return 1;
2315       }
2316       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
2317       if (aColoredPrs.IsNull())
2318       {
2319         aColoredPrs = new AIS_ColoredShape (aShapePrs);
2320         if (aShapePrs->HasDisplayMode())
2321         {
2322           aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode());
2323         }
2324         aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation());
2325         aCtx->Remove (aShapePrs, Standard_False);
2326         GetMapOfAIS().UnBind2 (aName);
2327         GetMapOfAIS().Bind (aColoredPrs, aName);
2328         toDisplay = Standard_True;
2329         aShapePrs = aColoredPrs;
2330         aPrs      = aColoredPrs;
2331       }
2332     }
2333
2334     if (!aPrs.IsNull())
2335     {
2336       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2337       aChangeSet = &aChangesIter.ChangeValue();
2338       if (aChangeSet->ToSetVisibility == 1)
2339       {
2340         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
2341         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
2342       }
2343       else if (aChangeSet->ToSetMaterial == 1)
2344       {
2345         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
2346       }
2347       else if (aChangeSet->ToSetMaterial == -1)
2348       {
2349         aCtx->UnsetMaterial (aPrs, Standard_False);
2350       }
2351       if (aChangeSet->ToSetColor == 1)
2352       {
2353         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
2354       }
2355       else if (aChangeSet->ToSetColor == -1)
2356       {
2357         aCtx->UnsetColor (aPrs, Standard_False);
2358       }
2359       if (aChangeSet->ToSetTransparency == 1)
2360       {
2361         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
2362       }
2363       else if (aChangeSet->ToSetTransparency == -1)
2364       {
2365         aCtx->UnsetTransparency (aPrs, Standard_False);
2366       }
2367       if (aChangeSet->ToSetLineWidth == 1)
2368       {
2369         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
2370       }
2371       else if (aChangeSet->ToSetLineWidth == -1)
2372       {
2373         aCtx->UnsetWidth (aPrs, Standard_False);
2374       }
2375       else if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2376       {
2377         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
2378         toRedisplay = Standard_True;
2379       }
2380       else if (aChangeSet->ToSetSensitivity != 0)
2381       {
2382         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2383       }
2384       if (!aDrawer.IsNull())
2385       {
2386         if (aChangeSet->ToSetShowFreeBoundary == 1)
2387         {
2388           aDrawer->SetFreeBoundaryDraw (Standard_True);
2389           toRedisplay = Standard_True;
2390         }
2391         else if (aChangeSet->ToSetShowFreeBoundary == -1)
2392         {
2393           aDrawer->SetFreeBoundaryDraw (Standard_False);
2394           toRedisplay = Standard_True;
2395         }
2396         if (aChangeSet->ToSetFreeBoundaryWidth != 0)
2397         {
2398           Handle(Prs3d_LineAspect) aBoundaryAspect =
2399               new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2400           *aBoundaryAspect->Aspect() = *aDrawer->FreeBoundaryAspect()->Aspect();
2401           aBoundaryAspect->SetWidth (aChangeSet->FreeBoundaryWidth);
2402           aDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2403           toRedisplay = Standard_True;
2404         }
2405         if (aChangeSet->ToSetFreeBoundaryColor != 0)
2406         {
2407           Handle(Prs3d_LineAspect) aBoundaryAspect =
2408               new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2409           *aBoundaryAspect->Aspect() = *aDrawer->FreeBoundaryAspect()->Aspect();
2410           aBoundaryAspect->SetColor (aChangeSet->FreeBoundaryColor);
2411           aDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2412           toRedisplay = Standard_True;
2413         }
2414         if (aChangeSet->ToSetTypeOfLine != 0)
2415         {
2416           aDrawer->LineAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2417           aDrawer->WireAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2418           aDrawer->FreeBoundaryAspect()->SetTypeOfLine   (aChangeSet->TypeOfLine);
2419           aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine);
2420           aDrawer->SeenLineAspect()->SetTypeOfLine       (aChangeSet->TypeOfLine);
2421           toRedisplay = Standard_True;
2422         }
2423         if (aChangeSet->ToSetMaxParamValue != 0)
2424         {
2425           aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2426         }
2427       }
2428
2429       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
2430       {
2431         aChangeSet = &aChangesIter.ChangeValue();
2432         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
2433              aSubShapeIter.More(); aSubShapeIter.Next())
2434         {
2435           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
2436           if (aChangeSet->ToSetVisibility == 1)
2437           {
2438             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2439             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
2440           }
2441           if (aChangeSet->ToSetColor == 1)
2442           {
2443             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
2444           }
2445           if (aChangeSet->ToSetLineWidth == 1)
2446           {
2447             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
2448           }
2449           if (aChangeSet->ToSetColor     == -1
2450            || aChangeSet->ToSetLineWidth == -1)
2451           {
2452             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
2453           }
2454           if (aChangeSet->ToSetMaxParamValue != 0)
2455           {
2456             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2457             aCurColDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2458           }
2459           if (aChangeSet->ToSetSensitivity != 0)
2460           {
2461             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2462           }
2463         }
2464       }
2465       if (toDisplay)
2466       {
2467         aCtx->Display (aPrs, Standard_False);
2468       }
2469       if (toRedisplay)
2470       {
2471         aCtx->Redisplay (aPrs, Standard_False);
2472       }
2473       else if (!aColoredPrs.IsNull())
2474       {
2475         aCtx->Redisplay (aColoredPrs, Standard_False);
2476       }
2477     }
2478   }
2479   return 0;
2480 }
2481
2482 //==============================================================================
2483 //function : VDonly2
2484 //author   : ege
2485 //purpose  : Display only a selected or named  object
2486 //           if there is no selected or named object s, nothing is done
2487 //==============================================================================
2488 static int VDonly2 (Draw_Interpretor& ,
2489                     Standard_Integer  theArgNb,
2490                     const char**      theArgVec)
2491 {
2492   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2493   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2494   if (aCtx.IsNull())
2495   {
2496     std::cerr << "Error: no active view!\n";
2497     return 1;
2498   }
2499
2500   if (aCtx->HasOpenedContext())
2501   {
2502     aCtx->CloseLocalContext();
2503   }
2504
2505   Standard_Integer anArgIter = 1;
2506   for (; anArgIter < theArgNb; ++anArgIter)
2507   {
2508     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
2509     {
2510       break;
2511     }
2512   }
2513
2514   NCollection_Map<Handle(Standard_Transient)> aDispSet;
2515   if (anArgIter >= theArgNb)
2516   {
2517     // display only selected objects
2518     if (aCtx->NbSelected() < 1)
2519     {
2520       return 0;
2521     }
2522
2523     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
2524     {
2525       aDispSet.Add (aCtx->SelectedInteractive());
2526     }
2527   }
2528   else
2529   {
2530     // display only specified objects
2531     for (; anArgIter < theArgNb; ++anArgIter)
2532     {
2533       TCollection_AsciiString aName = theArgVec[anArgIter];
2534       if (GetMapOfAIS().IsBound2 (aName))
2535       {
2536         const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
2537         if (!aShape.IsNull())
2538         {
2539           aCtx->Display (aShape, Standard_False);
2540           aDispSet.Add (aShape);
2541         }
2542       }
2543     }
2544   }
2545
2546   // weed out other objects
2547   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
2548   {
2549     if (aDispSet.Contains (anIter.Key1()))
2550     {
2551       continue;
2552     }
2553
2554     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2555     if (aShape.IsNull())
2556     {
2557       aCtx->Erase (aShape, Standard_False);
2558     }
2559   }
2560   return 0;
2561 }
2562
2563 //==============================================================================
2564 //function : VRemove
2565 //purpose  : Removes selected or named objects.
2566 //           If there is no selected or named objects,
2567 //           all objects in the viewer can be removed with argument -all.
2568 //           If -context is in arguments, the object is not deleted from the map of
2569 //           objects (deleted only from the current context).
2570 //==============================================================================
2571 int VRemove (Draw_Interpretor& theDI,
2572              Standard_Integer  theArgNb,
2573              const char**      theArgVec)
2574 {
2575   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2576   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2577   if (aCtx.IsNull())
2578   {
2579     std::cerr << "Error: no active view!\n";
2580     return 1;
2581   }
2582
2583   Standard_Boolean isContextOnly = Standard_False;
2584   Standard_Boolean toRemoveAll   = Standard_False;
2585   Standard_Boolean toPrintInfo   = Standard_True;
2586   Standard_Boolean toRemoveLocal = Standard_False;
2587
2588   Standard_Integer anArgIter = 1;
2589   for (; anArgIter < theArgNb; ++anArgIter)
2590   {
2591     TCollection_AsciiString anArg = theArgVec[anArgIter];
2592     anArg.LowerCase();
2593     if (anArg == "-context")
2594     {
2595       isContextOnly = Standard_True;
2596     }
2597     else if (anArg == "-all")
2598     {
2599       toRemoveAll = Standard_True;
2600     }
2601     else if (anArg == "-noinfo")
2602     {
2603       toPrintInfo = Standard_False;
2604     }
2605     else if (anArg == "-local")
2606     {
2607       toRemoveLocal = Standard_True;
2608     }
2609     else if (anUpdateTool.parseRedrawMode (anArg))
2610     {
2611       continue;
2612     }
2613     else
2614     {
2615       break;
2616     }
2617   }
2618   if (toRemoveAll
2619    && anArgIter < theArgNb)
2620   {
2621     std::cerr << "Error: wrong syntax!\n";
2622     return 1;
2623   }
2624
2625   if (toRemoveLocal && !aCtx->HasOpenedContext())
2626   {
2627     std::cerr << "Error: local selection context is not open.\n";
2628     return 1;
2629   }
2630   else if (!toRemoveLocal && aCtx->HasOpenedContext())
2631   {
2632     aCtx->CloseAllContexts (Standard_False);
2633   }
2634
2635   NCollection_List<TCollection_AsciiString> anIONameList;
2636   if (toRemoveAll)
2637   {
2638     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2639          anIter.More(); anIter.Next())
2640     {
2641       anIONameList.Append (anIter.Key2());
2642     }
2643   }
2644   else if (anArgIter < theArgNb) // removed objects names are in argument list
2645   {
2646     for (; anArgIter < theArgNb; ++anArgIter)
2647     {
2648       TCollection_AsciiString aName = theArgVec[anArgIter];
2649       if (!GetMapOfAIS().IsBound2 (aName))
2650       {
2651         theDI << aName.ToCString() << " was not bound to some object.\n";
2652         continue;
2653       }
2654
2655       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
2656       if (anIO->GetContext() != aCtx)
2657       {
2658         theDI << aName.ToCString() << " was not displayed in current context.\n";
2659         theDI << "Please activate view with this object displayed and try again.\n";
2660         continue;
2661       }
2662
2663       anIONameList.Append (aName);
2664       continue;
2665     }
2666   }
2667   else if (aCtx->NbSelected() > 0)
2668   {
2669     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2670          anIter.More(); anIter.Next())
2671     {
2672       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2673       if (!aCtx->IsSelected (anIO))
2674       {
2675         continue;
2676       }
2677
2678       anIONameList.Append (anIter.Key2());
2679       continue;
2680     }
2681   }
2682
2683   // Unbind all removed objects from the map of displayed IO.
2684   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
2685        anIter.More(); anIter.Next())
2686   {
2687     const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
2688     aCtx->Remove (anIO, Standard_False);
2689     if (toPrintInfo)
2690     {
2691       theDI << anIter.Value().ToCString() << " was removed\n";
2692     }
2693     if (!isContextOnly)
2694     {
2695       GetMapOfAIS().UnBind2 (anIter.Value());
2696     }
2697   }
2698
2699   // Close local context if it is empty
2700   TColStd_MapOfTransient aLocalIO;
2701   if (aCtx->HasOpenedContext()
2702    && !aCtx->LocalContext()->DisplayedObjects (aLocalIO))
2703   {
2704     aCtx->CloseAllContexts (Standard_False);
2705   }
2706
2707   return 0;
2708 }
2709
2710 //==============================================================================
2711 //function : VErase
2712 //purpose  : Erase some selected or named objects
2713 //           if there is no selected or named objects, the whole viewer is erased
2714 //==============================================================================
2715 int VErase (Draw_Interpretor& theDI,
2716             Standard_Integer  theArgNb,
2717             const char**      theArgVec)
2718 {
2719   const Handle(AIS_InteractiveContext)& aCtx  = ViewerTest::GetAISContext();
2720   const Handle(V3d_View)&               aView = ViewerTest::CurrentView();
2721   ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
2722   if (aCtx.IsNull())
2723   {
2724     std::cerr << "Error: no active view!\n";
2725     return 1;
2726   }
2727
2728   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
2729
2730   Standard_Integer anArgIter = 1;
2731   Standard_Boolean toEraseLocal  = Standard_False;
2732   Standard_Boolean toEraseInView = Standard_False;
2733   TColStd_SequenceOfAsciiString aNamesOfEraseIO;
2734   for (; anArgIter < theArgNb; ++anArgIter)
2735   {
2736     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2737     anArgCase.LowerCase();
2738     if (anUpdateTool.parseRedrawMode (anArgCase))
2739     {
2740       continue;
2741     }
2742     else if (anArgCase == "-local")
2743     {
2744       toEraseLocal = Standard_True;
2745     }
2746     else if (anArgCase == "-view"
2747           || anArgCase == "-inview")
2748     {
2749       toEraseInView = Standard_True;
2750     }
2751     else
2752     {
2753       aNamesOfEraseIO.Append (theArgVec[anArgIter]);
2754     }
2755   }
2756
2757   if (!aNamesOfEraseIO.IsEmpty() && toEraseAll)
2758   {
2759     std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
2760     return 1;
2761   }
2762
2763   if (toEraseLocal && !aCtx->HasOpenedContext())
2764   {
2765     std::cerr << "Error: local selection context is not open.\n";
2766     return 1;
2767   }
2768   else if (!toEraseLocal && aCtx->HasOpenedContext())
2769   {
2770     aCtx->CloseAllContexts (Standard_False);
2771   }
2772
2773   if (!aNamesOfEraseIO.IsEmpty())
2774   {
2775     // Erase named objects
2776     for (Standard_Integer anIter = 1; anIter <= aNamesOfEraseIO.Length(); ++anIter)
2777     {
2778       TCollection_AsciiString aName = aNamesOfEraseIO.Value (anIter);
2779       if (!GetMapOfAIS().IsBound2 (aName))
2780       {
2781         continue;
2782       }
2783
2784       const Handle(Standard_Transient)    anObj = GetMapOfAIS().Find2 (aName);
2785       const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (anObj);
2786       theDI << aName.ToCString() << " ";
2787       if (!anIO.IsNull())
2788       {
2789         if (toEraseInView)
2790         {
2791           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2792         }
2793         else
2794         {
2795           aCtx->Erase (anIO, Standard_False);
2796         }
2797       }
2798     }
2799   }
2800   else if (!toEraseAll && aCtx->NbSelected() > 0)
2801   {
2802     // Erase selected objects
2803     const Standard_Boolean aHasOpenedContext = aCtx->HasOpenedContext();
2804     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2805          anIter.More(); anIter.Next())
2806     {
2807       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2808       if (!anIO.IsNull()
2809        && aCtx->IsSelected (anIO))
2810       {
2811         theDI << anIter.Key2().ToCString() << " ";
2812         if (toEraseInView)
2813         {
2814           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2815         }
2816         else if (aHasOpenedContext)
2817         {
2818           aCtx->Erase (anIO, Standard_False);
2819         }
2820       }
2821     }
2822
2823     if (!toEraseInView)
2824     {
2825       aCtx->EraseSelected (Standard_False);
2826     }
2827   }
2828   else
2829   {
2830     // Erase all objects
2831     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2832          anIter.More(); anIter.Next())
2833     {
2834       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2835       if (!anIO.IsNull())
2836       {
2837         if (toEraseInView)
2838         {
2839           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2840         }
2841         else
2842         {
2843           aCtx->Erase (anIO, Standard_False);
2844         }
2845       }
2846     }
2847   }
2848
2849   return 0;
2850 }
2851
2852 //==============================================================================
2853 //function : VDisplayAll
2854 //author   : ege
2855 //purpose  : Display all the objects of the Map
2856 //==============================================================================
2857 static int VDisplayAll (Draw_Interpretor& ,
2858                         Standard_Integer  theArgNb,
2859                         const char**      theArgVec)
2860
2861 {
2862   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2863   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2864   if (aCtx.IsNull())
2865   {
2866     std::cerr << "Error: no active view!\n";
2867     return 1;
2868   }
2869
2870   Standard_Integer anArgIter = 1;
2871   Standard_Boolean toDisplayLocal = Standard_False;
2872   for (; anArgIter < theArgNb; ++anArgIter)
2873   {
2874     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2875     anArgCase.LowerCase();
2876     if (anArgCase == "-local")
2877     {
2878       toDisplayLocal = Standard_True;
2879     }
2880     else if (anUpdateTool.parseRedrawMode (anArgCase))
2881     {
2882       continue;
2883     }
2884     else
2885     {
2886       break;
2887     }
2888   }
2889   if (anArgIter < theArgNb)
2890   {
2891     std::cout << theArgVec[0] << "Error: wrong syntax\n";
2892     return 1;
2893   }
2894
2895   if (toDisplayLocal && !aCtx->HasOpenedContext())
2896   {
2897     std::cerr << "Error: local selection context is not open.\n";
2898     return 1;
2899   }
2900   else if (!toDisplayLocal && aCtx->HasOpenedContext())
2901   {
2902     aCtx->CloseLocalContext (Standard_False);
2903   }
2904
2905   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2906        anIter.More(); anIter.Next())
2907   {
2908     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2909     aCtx->Erase (aShape, Standard_False);
2910   }
2911
2912   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2913        anIter.More(); anIter.Next())
2914   {
2915     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2916     aCtx->Display (aShape, Standard_False);
2917   }
2918   return 0;
2919 }
2920
2921 //! Auxiliary method to find presentation
2922 inline Handle(PrsMgr_Presentation) findPresentation (const Handle(AIS_InteractiveContext)& theCtx,
2923                                                      const Handle(AIS_InteractiveObject)&  theIO,
2924                                                      const Standard_Integer                theMode)
2925 {
2926   if (theIO.IsNull())
2927   {
2928     return Handle(PrsMgr_Presentation)();
2929   }
2930
2931   if (theMode != -1)
2932   {
2933     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
2934     {
2935       return theCtx->MainPrsMgr()->Presentation (theIO, theMode);
2936     }
2937   }
2938   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
2939   {
2940     return theCtx->MainPrsMgr()->Presentation (theIO, theIO->DisplayMode());
2941   }
2942   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
2943   {
2944     return theCtx->MainPrsMgr()->Presentation (theIO, theCtx->DisplayMode());
2945   }
2946   return Handle(PrsMgr_Presentation)();
2947 }
2948
2949 enum ViewerTest_BndAction
2950 {
2951   BndAction_Hide,
2952   BndAction_Show,
2953   BndAction_Print
2954 };
2955
2956 //! Auxiliary method to print bounding box of presentation
2957 inline void bndPresentation (Draw_Interpretor&                  theDI,
2958                              const Handle(PrsMgr_Presentation)& thePrs,
2959                              const TCollection_AsciiString&     theName,
2960                              const ViewerTest_BndAction         theAction)
2961 {
2962   switch (theAction)
2963   {
2964     case BndAction_Hide:
2965     {
2966       thePrs->Presentation()->GraphicUnHighlight();
2967       break;
2968     }
2969     case BndAction_Show:
2970     {
2971       Handle(Graphic3d_Structure) aPrs (thePrs->Presentation());
2972       aPrs->CStructure()->HighlightColor = Quantity_NOC_GRAY99;
2973       aPrs->CStructure()->HighlightWithBndBox (aPrs, Standard_True);
2974       break;
2975     }
2976     case BndAction_Print:
2977     {
2978       Bnd_Box aBox = thePrs->Presentation()->MinMaxValues();
2979       gp_Pnt aMin = aBox.CornerMin();
2980       gp_Pnt aMax = aBox.CornerMax();
2981       theDI << theName  << "\n"
2982             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
2983             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
2984       break;
2985     }
2986   }
2987 }
2988
2989 //==============================================================================
2990 //function : VBounding
2991 //purpose  :
2992 //==============================================================================
2993 int VBounding (Draw_Interpretor& theDI,
2994                Standard_Integer  theArgNb,
2995                const char**      theArgVec)
2996 {
2997   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2998   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2999   if (aCtx.IsNull())
3000   {
3001     std::cout << "Error: no active view!\n";
3002     return 1;
3003   }
3004
3005   ViewerTest_BndAction anAction = BndAction_Show;
3006   Standard_Integer     aMode    = -1;
3007
3008   Standard_Integer anArgIter = 1;
3009   for (; anArgIter < theArgNb; ++anArgIter)
3010   {
3011     TCollection_AsciiString anArg (theArgVec[anArgIter]);
3012     anArg.LowerCase();
3013     if (anArg == "-print")
3014     {
3015       anAction = BndAction_Print;
3016     }
3017     else if (anArg == "-show")
3018     {
3019       anAction = BndAction_Show;
3020     }
3021     else if (anArg == "-hide")
3022     {
3023       anAction = BndAction_Hide;
3024     }
3025     else if (anArg == "-mode")
3026     {
3027       if (++anArgIter >= theArgNb)
3028       {
3029         std::cout << "Error: wrong syntax at " << anArg << "\n";
3030         return 1;
3031       }
3032       aMode = Draw::Atoi (theArgVec[anArgIter]);
3033     }
3034     else if (!anUpdateTool.parseRedrawMode (anArg))
3035     {
3036       break;
3037     }
3038   }
3039
3040   if (anArgIter < theArgNb)
3041   {
3042     // has a list of names
3043     for (; anArgIter < theArgNb; ++anArgIter)
3044     {
3045       TCollection_AsciiString aName = theArgVec[anArgIter];
3046       if (!GetMapOfAIS().IsBound2 (aName))
3047       {
3048         std::cout << "Error: presentation " << aName << " does not exist\n";
3049         return 1;
3050       }
3051
3052       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
3053       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3054       if (aPrs.IsNull())
3055       {
3056         std::cout << "Error: presentation " << aName << " does not exist\n";
3057         return 1;
3058       }
3059       bndPresentation (theDI, aPrs, aName, anAction);
3060     }
3061   }
3062   else if (aCtx->NbSelected() > 0)
3063   {
3064     // remove all currently selected objects
3065     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3066     {
3067       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
3068       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3069       if (!aPrs.IsNull())
3070       {
3071         bndPresentation (theDI, aPrs, GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction);
3072       }
3073     }
3074   }
3075   else
3076   {
3077     // all objects
3078     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3079          anIter.More(); anIter.Next())
3080     {
3081       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
3082       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3083       if (!aPrs.IsNull())
3084       {
3085         bndPresentation (theDI, aPrs, anIter.Key2(), anAction);
3086       }
3087     }
3088   }
3089   return 0;
3090 }
3091
3092 //==============================================================================
3093 //function : VTexture
3094 //purpose  :
3095 //==============================================================================
3096 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgv)
3097 {
3098   TCollection_AsciiString aCommandName (theArgv[0]);
3099
3100   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
3101   if (aCommandName == "vtexture")
3102   {
3103     if (theArgsNb < 2)
3104     {
3105       std::cout << theArgv[0] << ":  invalid arguments.\n";
3106       std::cout << "Type help for more information.\n";
3107       return 1;
3108     }
3109
3110     // look for options of vtexture command
3111     TCollection_AsciiString aParseKey;
3112     for (Standard_Integer anArgIt = 2; anArgIt < theArgsNb; ++anArgIt)
3113     {
3114       TCollection_AsciiString anArg (theArgv [anArgIt]);
3115
3116       anArg.UpperCase();
3117       if (anArg.Value (1) == '-' && !anArg.IsRealValue())
3118       {
3119         aParseKey = anArg;
3120         aParseKey.Remove (1);
3121         aParseKey.UpperCase();
3122         aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
3123         continue;
3124       }
3125
3126       if (aParseKey.IsEmpty())
3127       {
3128         continue;
3129       }
3130
3131       aMapOfArgs(aParseKey)->Append (anArg);
3132     }
3133   }
3134   else if (aCommandName == "vtexscale"
3135         || aCommandName == "vtexorigin"
3136         || aCommandName == "vtexrepeat")
3137   {
3138     // scan for parameters of vtexscale, vtexorigin, vtexrepeat commands
3139     // equal to -scale, -origin, -repeat options of vtexture command
3140     if (theArgsNb < 2 || theArgsNb > 4)
3141     {
3142       std::cout << theArgv[0] << ":  invalid arguments.\n";
3143       std::cout << "Type help for more information.\n";
3144       return 1;
3145     }
3146
3147     Handle(TColStd_HSequenceOfAsciiString) anArgs = new TColStd_HSequenceOfAsciiString;
3148     if (theArgsNb == 2)
3149     {
3150       anArgs->Append ("OFF");
3151     }
3152     else if (theArgsNb == 4)
3153     {
3154       anArgs->Append (TCollection_AsciiString (theArgv[2]));
3155       anArgs->Append (TCollection_AsciiString (theArgv[3]));
3156     }
3157
3158     TCollection_AsciiString anArgKey;
3159     if (aCommandName == "vtexscale")
3160     {
3161       anArgKey = "SCALE";
3162     }
3163     else if (aCommandName == "vtexorigin")
3164     {
3165       anArgKey = "ORIGIN";
3166     }
3167     else
3168     {
3169       anArgKey = "REPEAT";
3170     }
3171
3172     aMapOfArgs.Bind (anArgKey, anArgs);
3173   }
3174   else if (aCommandName == "vtexdefault")
3175   {
3176     // scan for parameters of vtexdefault command
3177     // equal to -default option of vtexture command
3178     aMapOfArgs.Bind ("DEFAULT", new TColStd_HSequenceOfAsciiString);
3179   }
3180
3181   // Check arguments for validity
3182   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
3183   for (; aMapIt.More(); aMapIt.Next())
3184   {
3185     const TCollection_AsciiString& aKey = aMapIt.Key();
3186     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
3187
3188     // -scale, -origin, -repeat: one argument "off", or two real values
3189     if ((aKey.IsEqual ("SCALE") || aKey.IsEqual ("ORIGIN") || aKey.IsEqual ("REPEAT"))
3190       && ((anArgs->Length() == 1 && anArgs->Value(1) == "OFF")
3191        || (anArgs->Length() == 2 && anArgs->Value(1).IsRealValue() && anArgs->Value(2).IsRealValue())))
3192     {
3193       continue;
3194     }
3195
3196     // -modulate: single argument "on" / "off"
3197     if (aKey.IsEqual ("MODULATE") && anArgs->Length() == 1 && (anArgs->Value(1) == "OFF" || anArgs->Value(1) == "ON"))
3198     {
3199       continue;
3200     }
3201
3202     // -default: no arguments
3203     if (aKey.IsEqual ("DEFAULT") && anArgs->IsEmpty())
3204     {
3205       continue;
3206     }
3207
3208     TCollection_AsciiString aLowerKey;
3209     aLowerKey  = "-";
3210     aLowerKey += aKey;
3211     aLowerKey.LowerCase();
3212     std::cout << theArgv[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
3213     std::cout << "Type help for more information.\n";
3214     return 1;
3215   }
3216
3217   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
3218   if (anAISContext.IsNull())
3219   {
3220     std::cout << aCommandName << ":  please use 'vinit' command to initialize view.\n";
3221     return 1;
3222   }
3223
3224   Standard_Integer aPreviousMode = 0;
3225
3226   TCollection_AsciiString aShapeName (theArgv[1]);
3227   Handle(AIS_InteractiveObject) anIO;
3228
3229   const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
3230   if (aMapOfIO.IsBound2 (aShapeName))
3231   {
3232     anIO = Handle(AIS_InteractiveObject)::DownCast (aMapOfIO.Find2 (aShapeName));
3233   }
3234
3235   if (anIO.IsNull())
3236   {
3237     std::cout << aCommandName << ": shape " << aShapeName << " does not exists.\n";
3238     return 1;
3239   }
3240
3241   Handle(AIS_TexturedShape) aTexturedIO;
3242   if (anIO->IsKind (STANDARD_TYPE (AIS_TexturedShape)))
3243   {
3244     aTexturedIO = Handle(AIS_TexturedShape)::DownCast (anIO);
3245     aPreviousMode = aTexturedIO->DisplayMode();
3246   }
3247   else
3248   {
3249     aTexturedIO = new AIS_TexturedShape (DBRep::Get (theArgv[1]));
3250
3251     if (anIO->HasTransformation())
3252     {
3253       const gp_Trsf& aLocalTrsf = anIO->LocalTransformation();
3254       aTexturedIO->SetLocalTransformation (aLocalTrsf);
3255     }
3256
3257     anAISContext->Remove (anIO, Standard_False);
3258     GetMapOfAIS().UnBind1 (anIO);
3259     GetMapOfAIS().UnBind2 (aShapeName);
3260     GetMapOfAIS().Bind (aTexturedIO, aShapeName);
3261   }
3262
3263   // -------------------------------------------
3264   //  Turn texturing on/off - only for vtexture
3265   // -------------------------------------------
3266
3267   if (aCommandName == "vtexture")
3268   {
3269     TCollection_AsciiString aTextureArg (theArgsNb > 2 ? theArgv[2] : "");
3270
3271     if (aTextureArg.IsEmpty())
3272     {
3273       std::cout << aCommandName << ":  Texture mapping disabled.\n";
3274       std::cout << "To enable it, use 'vtexture NameOfShape NameOfTexture'\n\n";
3275
3276       anAISContext->SetDisplayMode (aTexturedIO, AIS_Shaded, Standard_False);
3277       if (aPreviousMode == 3)
3278       {
3279         anAISContext->RecomputePrsOnly (aTexturedIO);
3280       }
3281
3282       anAISContext->Display (aTexturedIO, Standard_True);
3283       return 0;
3284     }
3285     else if (aTextureArg.Value(1) != '-') // "-option" on place of texture argument
3286     {
3287       if (aTextureArg == "?")
3288       {
3289         TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
3290
3291         theDi << "\n Files in current directory : \n\n";
3292         theDi.Eval ("glob -nocomplain *");
3293
3294         TCollection_AsciiString aCmnd ("glob -nocomplain ");
3295         aCmnd += aTextureFolder;
3296         aCmnd += "/* ";
3297
3298         theDi << "Files in " << aTextureFolder.ToCString() << " : \n\n";
3299         theDi.Eval (aCmnd.ToCString());
3300         return 0;
3301       }
3302       else
3303       {
3304         aTexturedIO->SetTextureFileName (aTextureArg);
3305       }
3306     }
3307   }
3308
3309   // ------------------------------------
3310   //  Process other options and commands
3311   // ------------------------------------
3312
3313   Handle(TColStd_HSequenceOfAsciiString) aValues;
3314   if (aMapOfArgs.Find ("DEFAULT", aValues))
3315   {
3316     aTexturedIO->SetTextureRepeat (Standard_False);
3317     aTexturedIO->SetTextureOrigin (Standard_False);
3318     aTexturedIO->SetTextureScale  (Standard_False);
3319     aTexturedIO->EnableTextureModulate();
3320   }
3321   else
3322   {
3323     if (aMapOfArgs.Find ("SCALE", aValues))
3324     {
3325       if (aValues->Value(1) != "OFF")
3326       {
3327         aTexturedIO->SetTextureScale (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3328       }
3329       else
3330       {
3331         aTexturedIO->SetTextureScale (Standard_False);
3332       }
3333     }
3334
3335     if (aMapOfArgs.Find ("ORIGIN", aValues))
3336     {
3337       if (aValues->Value(1) != "OFF")
3338       {
3339         aTexturedIO->SetTextureOrigin (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3340       }
3341       else
3342       {
3343         aTexturedIO->SetTextureOrigin (Standard_False);
3344       }
3345     }
3346
3347     if (aMapOfArgs.Find ("REPEAT", aValues))
3348     {
3349       if (aValues->Value(1) != "OFF")
3350       {
3351         aTexturedIO->SetTextureRepeat (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3352       }
3353       else
3354       {
3355         aTexturedIO->SetTextureRepeat (Standard_False);
3356       }
3357     }
3358
3359     if (aMapOfArgs.Find ("MODULATE", aValues))
3360     {
3361       if (aValues->Value(1) == "ON")
3362       {
3363         aTexturedIO->EnableTextureModulate();
3364       }
3365       else
3366       {
3367         aTexturedIO->DisableTextureModulate();
3368       }
3369     }
3370   }
3371
3372   if (aTexturedIO->DisplayMode() == 3 || aPreviousMode == 3)
3373   {
3374     anAISContext->RecomputePrsOnly (aTexturedIO);
3375   }
3376   else
3377   {
3378     anAISContext->SetDisplayMode (aTexturedIO, 3, Standard_False);
3379     anAISContext->Display (aTexturedIO, Standard_True);
3380     anAISContext->Update (aTexturedIO,Standard_True);
3381   }
3382
3383   return 0;
3384 }
3385
3386 //! Auxiliary method to parse transformation persistence flags
3387 inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFlagString,
3388                                            Graphic3d_TransModeFlags&      theFlags)
3389 {
3390   if (theFlagString == "zoom")
3391   {
3392     theFlags = Graphic3d_TMF_ZoomPers;
3393   }
3394   else if (theFlagString == "rotate")
3395   {
3396     theFlags = Graphic3d_TMF_RotatePers;
3397   }
3398   else if (theFlagString == "zoomrotate")
3399   {
3400     theFlags = Graphic3d_TMF_ZoomRotatePers;
3401   }
3402   else if (theFlagString == "trihedron"
3403         || theFlagString == "triedron")
3404   {
3405     theFlags = Graphic3d_TMF_TriedronPers;
3406   }
3407   else if (theFlagString == "none")
3408   {
3409     theFlags = Graphic3d_TMF_None;
3410   }
3411   else
3412   {
3413     return Standard_False;
3414   }
3415
3416   return Standard_True;
3417 }
3418
3419 //! Auxiliary method to parse transformation persistence flags
3420 inline Standard_Boolean parseTrsfPersCorner (const TCollection_AsciiString& theString,
3421                                              Aspect_TypeOfTriedronPosition& theCorner)
3422 {
3423   TCollection_AsciiString aString (theString);
3424   aString.LowerCase();
3425   if (aString == "center")
3426   {
3427     theCorner = Aspect_TOTP_CENTER;
3428   }
3429   else if (aString == "top"
3430         || aString == "upper")
3431   {
3432     theCorner = Aspect_TOTP_TOP;
3433   }
3434   else if (aString == "bottom"
3435         || aString == "lower")
3436   {
3437     theCorner = Aspect_TOTP_BOTTOM;
3438   }
3439   else if (aString == "left")
3440   {
3441     theCorner = Aspect_TOTP_LEFT;
3442   }
3443   else if (aString == "right")
3444   {
3445     theCorner = Aspect_TOTP_RIGHT;
3446   }
3447   else if (aString == "topleft"
3448         || aString == "leftupper"
3449         || aString == "upperleft")
3450   {
3451     theCorner = Aspect_TOTP_LEFT_UPPER;
3452   }
3453   else if (aString == "bottomleft"
3454         || aString == "leftlower"
3455         || aString == "lowerleft")
3456   {
3457     theCorner = Aspect_TOTP_LEFT_LOWER;
3458   }
3459   else if (aString == "topright"
3460         || aString == "rightupper"
3461         || aString == "upperright")
3462   {
3463     theCorner = Aspect_TOTP_RIGHT_UPPER;
3464   }
3465   else if (aString == "bottomright"
3466         || aString == "lowerright"
3467         || aString == "rightlower")
3468   {
3469     theCorner = Aspect_TOTP_RIGHT_LOWER;
3470   }
3471   else
3472   {
3473     return Standard_False;
3474   }
3475
3476   return Standard_True;
3477 }
3478
3479 //==============================================================================
3480 //function : VDisplay2
3481 //author   : ege
3482 //purpose  : Display an object from its name
3483 //==============================================================================
3484 static int VDisplay2 (Draw_Interpretor& theDI,
3485                       Standard_Integer  theArgNb,
3486                       const char**      theArgVec)
3487 {
3488   if (theArgNb < 2)
3489   {
3490     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
3491     return 1;
3492   }
3493
3494   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
3495   if (aCtx.IsNull())
3496   {
3497     ViewerTest::ViewerInit();
3498     aCtx = ViewerTest::GetAISContext();
3499   }
3500
3501   // Parse input arguments
3502   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3503   Standard_Integer   isMutable      = -1;
3504   Graphic3d_ZLayerId aZLayer        = Graphic3d_ZLayerId_UNKNOWN;
3505   Standard_Boolean   toDisplayLocal = Standard_False;
3506   Standard_Boolean   toReDisplay    = Standard_False;
3507   Standard_Integer   isSelectable   = -1;
3508   Standard_Integer   anObjDispMode  = -2;
3509   Standard_Integer   anObjHighMode  = -2;
3510   Standard_Boolean   toSetTrsfPers  = Standard_False;
3511   Handle(Graphic3d_TransformPers) aTrsfPers;
3512   TColStd_SequenceOfAsciiString aNamesOfDisplayIO;
3513   AIS_DisplayStatus aDispStatus = AIS_DS_None;
3514   Standard_Integer toDisplayInView = Standard_False;
3515   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3516   {
3517     const TCollection_AsciiString aName     = theArgVec[anArgIter];
3518     TCollection_AsciiString       aNameCase = aName;
3519     aNameCase.LowerCase();
3520     if (anUpdateTool.parseRedrawMode (aName))
3521     {
3522       continue;
3523     }
3524     else if (aNameCase == "-mutable")
3525     {
3526       isMutable = 1;
3527     }
3528     else if (aNameCase == "-neutral")
3529     {
3530       aDispStatus = AIS_DS_Displayed;
3531     }
3532     else if (aNameCase == "-immediate"
3533           || aNameCase == "-top")
3534     {
3535       aZLayer = Graphic3d_ZLayerId_Top;
3536     }
3537     else if (aNameCase == "-topmost")
3538     {
3539       aZLayer = Graphic3d_ZLayerId_Topmost;
3540     }
3541     else if (aNameCase == "-osd"
3542           || aNameCase == "-toposd"
3543           || aNameCase == "-overlay")
3544     {
3545       aZLayer = Graphic3d_ZLayerId_TopOSD;
3546     }
3547     else if (aNameCase == "-botosd"
3548           || aNameCase == "-underlay")
3549     {
3550       aZLayer = Graphic3d_ZLayerId_BotOSD;
3551     }
3552     else if (aNameCase == "-select"
3553           || aNameCase == "-selectable")
3554     {
3555       isSelectable = 1;
3556     }
3557     else if (aNameCase == "-noselect"
3558           || aNameCase == "-noselection")
3559     {
3560       isSelectable = 0;
3561     }
3562     else if (aNameCase == "-dispmode"
3563           || aNameCase == "-displaymode")
3564     {
3565       if (++anArgIter >= theArgNb)
3566       {
3567         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3568         return 1;
3569       }
3570
3571       anObjDispMode = Draw::Atoi (theArgVec [anArgIter]);
3572     }
3573     else if (aNameCase == "-highmode"
3574           || aNameCase == "-highlightmode")
3575     {
3576       if (++anArgIter >= theArgNb)
3577       {
3578         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3579         return 1;
3580       }
3581
3582       anObjHighMode = Draw::Atoi (theArgVec [anArgIter]);
3583     }
3584     else if (aNameCase == "-3d")
3585     {
3586       toSetTrsfPers  = Standard_True;
3587       aTrsfPers.Nullify();
3588     }
3589     else if (aNameCase == "-2d"
3590           || aNameCase == "-trihedron"
3591           || aNameCase == "-triedron")
3592     {
3593       toSetTrsfPers  = Standard_True;
3594       aTrsfPers = new Graphic3d_TransformPers (aNameCase == "-2d" ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
3595
3596       if (anArgIter + 1 < theArgNb)
3597       {
3598         Aspect_TypeOfTriedronPosition aCorner = Aspect_TOTP_CENTER;
3599         if (parseTrsfPersCorner (theArgVec[anArgIter + 1], aCorner))
3600         {
3601           ++anArgIter;
3602           aTrsfPers->SetCorner2d (aCorner);
3603
3604           if (anArgIter + 2 < theArgNb)
3605           {
3606             TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
3607             TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
3608             if (anX.IsIntegerValue()
3609              && anY.IsIntegerValue())
3610             {
3611               anArgIter += 2;
3612               aTrsfPers->SetOffset2d (Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue()));
3613             }
3614           }
3615         }
3616       }
3617     }
3618     else if (aNameCase == "-trsfpers"
3619           || aNameCase == "-pers")
3620     {
3621       if (++anArgIter >= theArgNb
3622        || !aTrsfPers.IsNull())
3623       {
3624         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3625         return 1;
3626       }
3627
3628       toSetTrsfPers  = Standard_True;
3629       Graphic3d_TransModeFlags aTrsfPersFlags = Graphic3d_TMF_None;
3630       TCollection_AsciiString aPersFlags (theArgVec [anArgIter]);
3631       aPersFlags.LowerCase();
3632       if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
3633       {
3634         std::cerr << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".\n";
3635         return 1;
3636       }
3637
3638       if (aTrsfPersFlags == Graphic3d_TMF_TriedronPers)
3639       {
3640         aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
3641       }
3642       else if (aTrsfPersFlags != Graphic3d_TMF_None)
3643       {
3644         aTrsfPers = new Graphic3d_TransformPers (aTrsfPersFlags, gp_Pnt());
3645       }
3646     }
3647     else if (aNameCase == "-trsfperspos"
3648           || aNameCase == "-perspos")
3649     {
3650       if (anArgIter + 2 >= theArgNb
3651        || aTrsfPers.IsNull())
3652       {
3653         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3654         return 1;
3655       }
3656
3657       TCollection_AsciiString aX (theArgVec[++anArgIter]);
3658       TCollection_AsciiString aY (theArgVec[++anArgIter]);
3659       TCollection_AsciiString aZ = "0";
3660       if (!aX.IsRealValue()
3661        || !aY.IsRealValue())
3662       {
3663         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3664         return 1;
3665       }
3666       if (anArgIter + 1 < theArgNb)
3667       {
3668         TCollection_AsciiString aTemp = theArgVec[anArgIter + 1];
3669         if (aTemp.IsRealValue())
3670         {
3671      &