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