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