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