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