0029987: Request for translation of French comments in the code
[occt.git] / src / ViewerTest / ViewerTest.cxx
1 // Created on: 1997-07-23
2 // Created by: Henri JEANNIN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Standard_Stream.hxx>
18
19 #include <ViewerTest.hxx>
20 #include <ViewerTest_CmdParser.hxx>
21
22 #include <Draw.hxx>
23 #include <TopLoc_Location.hxx>
24 #include <TopTools_HArray1OfShape.hxx>
25 #include <TColStd_HArray1OfTransient.hxx>
26 #include <TColStd_SequenceOfAsciiString.hxx>
27 #include <TColStd_HSequenceOfAsciiString.hxx>
28 #include <TColStd_MapOfTransient.hxx>
29 #include <OSD_Timer.hxx>
30 #include <Geom_Axis2Placement.hxx>
31 #include <Geom_Axis1Placement.hxx>
32 #include <gp_Trsf.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <BRepAdaptor_Curve.hxx>
35 #include <StdSelect_ShapeTypeFilter.hxx>
36 #include <AIS.hxx>
37 #include <AIS_ColoredShape.hxx>
38 #include <AIS_InteractiveObject.hxx>
39 #include <AIS_Trihedron.hxx>
40 #include <AIS_Axis.hxx>
41 #include <AIS_Relation.hxx>
42 #include <AIS_TypeFilter.hxx>
43 #include <AIS_SignatureFilter.hxx>
44 #include <AIS_ListOfInteractive.hxx>
45 #include <AIS_ListIteratorOfListOfInteractive.hxx>
46 #include <Aspect_InteriorStyle.hxx>
47 #include <Aspect_Window.hxx>
48 #include <Graphic3d_AspectFillArea3d.hxx>
49 #include <Graphic3d_AspectLine3d.hxx>
50 #include <Graphic3d_CStructure.hxx>
51 #include <Graphic3d_Texture2Dmanual.hxx>
52 #include <Graphic3d_GraphicDriver.hxx>
53 #include <Graphic3d_MediaTextureSet.hxx>
54 #include <Image_AlienPixMap.hxx>
55 #include <OSD_File.hxx>
56 #include <Prs3d_Drawer.hxx>
57 #include <Prs3d_ShadingAspect.hxx>
58 #include <Prs3d_IsoAspect.hxx>
59 #include <Prs3d_PointAspect.hxx>
60 #include <Select3D_SensitiveWire.hxx>
61 #include <Select3D_SensitivePrimitiveArray.hxx>
62 #include <SelectMgr_EntityOwner.hxx>
63 #include <StdSelect_BRepOwner.hxx>
64 #include <StdSelect_ViewerSelector3d.hxx>
65 #include <TopTools_MapOfShape.hxx>
66 #include <ViewerTest_AutoUpdater.hxx>
67
68 #include <stdio.h>
69
70 #include <Draw_Interpretor.hxx>
71 #include <TCollection_AsciiString.hxx>
72 #include <Draw_PluginMacro.hxx>
73
74 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
75
76 #include <Quantity_Color.hxx>
77 #include <Quantity_NameOfColor.hxx>
78
79 #include <Graphic3d_NameOfMaterial.hxx>
80
81 #define DEFAULT_COLOR              Quantity_NOC_GOLDENROD
82 #define DEFAULT_FREEBOUNDARY_COLOR Quantity_NOC_GREEN
83 #define DEFAULT_MATERIAL           Graphic3d_NOM_BRASS
84
85 namespace
86 {
87
88   const Standard_Integer THE_MAX_INTEGER_COLOR_COMPONENT = 255;
89
90   const Standard_ShortReal THE_MAX_REAL_COLOR_COMPONENT = 1.0f;
91
92   //! Parses string and get an integer color component (only values within range 0 .. 255 are allowed)
93   //! @param theColorComponentString the string representing the color component
94   //! @param theIntegerColorComponent an integer color component that is a result of parsing
95   //! @return true if parsing was successful, or false otherwise
96   static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
97                                             Standard_Integer&      theIntegerColorComponent)
98   {
99     Standard_Integer anIntegerColorComponent;
100     if (!Draw::ParseInteger (theColorComponentString, anIntegerColorComponent))
101     {
102       return false;
103     }
104     if ((anIntegerColorComponent < 0) || (anIntegerColorComponent > THE_MAX_INTEGER_COLOR_COMPONENT))
105     {
106       return false;
107     }
108     theIntegerColorComponent = anIntegerColorComponent;
109     return true;
110   }
111
112   //! Parses the string and gets a real color component from it (only values within range 0.0 .. 1.0 are allowed)
113   //! @param theColorComponentString the string representing the color component
114   //! @param theRealColorComponent a real color component that is a result of parsing
115   //! @return true if parsing was successful, or false otherwise
116   static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
117                                             Standard_ShortReal&    theRealColorComponent)
118   {
119     Standard_Real aRealColorComponent;
120     if (!Draw::ParseReal (theColorComponentString, aRealColorComponent))
121     {
122       return false;
123     }
124     const Standard_ShortReal aShortRealColorComponent = static_cast<Standard_ShortReal> (aRealColorComponent);
125     if ((aShortRealColorComponent < 0.0f) || (aShortRealColorComponent > THE_MAX_REAL_COLOR_COMPONENT))
126     {
127       return false;
128     }
129     theRealColorComponent = aShortRealColorComponent;
130     return true;
131   }
132
133   //! Parses the string and gets a real color component from it (integer values 2 .. 255 are scaled to the 0.0 .. 1.0
134   //! range, values 0 and 1 are leaved as they are)
135   //! @param theColorComponentString the string representing the color component
136   //! @param theColorComponent a color component that is a result of parsing
137   //! @return true if parsing was successful, or false otherwise
138   static bool parseColorComponent (const Standard_CString theColorComponentString,
139                                    Standard_ShortReal&    theColorComponent)
140   {
141     Standard_Integer anIntegerColorComponent;
142     if (parseNumericalColorComponent (theColorComponentString, anIntegerColorComponent))
143     {
144       if (anIntegerColorComponent == 1)
145       {
146         theColorComponent = THE_MAX_REAL_COLOR_COMPONENT;
147       }
148       else
149       {
150         theColorComponent = anIntegerColorComponent * 1.0f / THE_MAX_INTEGER_COLOR_COMPONENT;
151       }
152       return true;
153     }
154     return parseNumericalColorComponent (theColorComponentString, theColorComponent);
155   }
156
157   //! Parses the array of strings and gets an integer color (only values within range 0 .. 255 are allowed and at least
158   //! one of components must be greater than 1)
159   //! @tparam TheNumber the type of resulting color vector elements
160   //! @param theNumberOfColorComponents the number of color components
161   //! @param theColorComponentStrings the array of strings representing color components
162   //! @param theNumericalColor a 4-component vector that is a result of parsing
163   //! @return true if parsing was successful, or false otherwise
164   template <typename TheNumber>
165   static bool parseNumericalColor (Standard_Integer&            theNumberOfColorComponents,
166                                    const char* const* const     theColorComponentStrings,
167                                    NCollection_Vec4<TheNumber>& theNumericalColor)
168   {
169     for (Standard_Integer aColorComponentIndex = 0; aColorComponentIndex < theNumberOfColorComponents;
170          ++aColorComponentIndex)
171     {
172       const char* const aColorComponentString = theColorComponentStrings[aColorComponentIndex];
173       TheNumber         aNumericalColorComponent;
174       if (parseNumericalColorComponent (aColorComponentString, aNumericalColorComponent))
175       {
176         theNumericalColor[aColorComponentIndex] = aNumericalColorComponent;
177       }
178       else
179       {
180         if (aColorComponentIndex == 3)
181         {
182           theNumberOfColorComponents = 3;
183         }
184         else
185         {
186           return false;
187         }
188       }
189     }
190     return true;
191   }
192
193   //! Parses an array of strings and get an integer color (only values within range 0 .. 255 are allowed and at least
194   //! one of components must be greater than 1)
195   //! @param theNumberOfColorComponents the number of color components
196   //! @param theColorComponentStrings the array of strings representing color components
197   //! @param theColor a color that is a result of parsing
198   //! @return true if parsing was successful, or false otherwise
199   static bool parseIntegerColor (Standard_Integer&        theNumberOfColorComponents,
200                                  const char* const* const theColorComponentStrings,
201                                  Quantity_ColorRGBA&      theColor)
202   {
203     const Standard_Integer THE_COLOR_COMPONENT_NOT_PARSED = -1;
204     Graphic3d_Vec4i        anIntegerColor (THE_COLOR_COMPONENT_NOT_PARSED);
205     if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, anIntegerColor))
206     {
207       return false;
208     }
209
210     const bool hasColorComponentGreaterThanOne = (anIntegerColor.maxComp() > 1);
211     if (anIntegerColor.a() == THE_COLOR_COMPONENT_NOT_PARSED)
212     {
213       anIntegerColor.a() = THE_MAX_INTEGER_COLOR_COMPONENT;
214     }
215
216     Graphic3d_Vec4 aRealColor (anIntegerColor);
217     if (hasColorComponentGreaterThanOne)
218     {
219       aRealColor /= static_cast<Standard_ShortReal> (THE_MAX_INTEGER_COLOR_COMPONENT);
220     }
221     theColor = Quantity_ColorRGBA (aRealColor);
222     return true;
223   }
224
225   //! Parses an array of strings and get a real color (only values within range 0.0 .. 1.0 are allowed)
226   //! @param theNumberOfColorComponents the number of color components
227   //! @param theColorComponentStrings the array of strings representing color components
228   //! @param theColor a color that is a result of parsing
229   //! @return true if parsing was successful, or false otherwise
230   static bool parseRealColor (Standard_Integer&        theNumberOfColorComponents,
231                               const char* const* const theColorComponentStrings,
232                               Quantity_ColorRGBA&      theColor)
233   {
234     Graphic3d_Vec4 aRealColor (THE_MAX_REAL_COLOR_COMPONENT);
235     if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, aRealColor))
236     {
237       return false;
238     }
239     theColor = Quantity_ColorRGBA (aRealColor);
240     return true;
241   }
242
243 } // namespace
244
245 //=======================================================================
246 // function : GetColorFromName
247 // purpose  : get the Quantity_NameOfColor from a string
248 //=======================================================================
249
250 Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theName)
251 {
252   Quantity_NameOfColor aColor = DEFAULT_COLOR;
253   Quantity_Color::ColorFromName (theName, aColor);
254   return aColor;
255 }
256
257 //=======================================================================
258 // function : parseColor
259 // purpose  :
260 //=======================================================================
261 Standard_Integer ViewerTest::parseColor (const Standard_Integer   theArgNb,
262                                          const char* const* const theArgVec,
263                                          Quantity_ColorRGBA&      theColor,
264                                          const bool               theToParseAlpha)
265 {
266   if ((theArgNb >= 1) && Quantity_ColorRGBA::ColorFromHex (theArgVec[0], theColor, !theToParseAlpha))
267   {
268     return 1;
269   }
270   if (theArgNb >= 1 && Quantity_ColorRGBA::ColorFromName (theArgVec[0], theColor))
271   {
272     if (theArgNb >= 2 && theToParseAlpha)
273     {
274       const Standard_CString anAlphaStr = theArgVec[1];
275       Standard_ShortReal     anAlphaComponent;
276       if (parseColorComponent (anAlphaStr, anAlphaComponent))
277       {
278         theColor.SetAlpha (anAlphaComponent);
279         return 2;
280       }
281     }
282     return 1;
283   }
284   if (theArgNb >= 3)
285   {
286     const Standard_Integer aNumberOfColorComponentsToParse = Min (theArgNb, theToParseAlpha ? 4 : 3);
287     Standard_Integer       aNumberOfColorComponentsParsed  = aNumberOfColorComponentsToParse;
288     if (parseIntegerColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
289     {
290       return aNumberOfColorComponentsParsed;
291     }
292     if (parseRealColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
293     {
294       return aNumberOfColorComponentsParsed;
295     }
296     return 0;
297   }
298   return 0;
299 }
300
301 //=======================================================================
302 //function : ParseOnOff
303 //purpose  :
304 //=======================================================================
305 Standard_Boolean ViewerTest::ParseOnOff (Standard_CString  theArg,
306                                          Standard_Boolean& theIsOn)
307 {
308   TCollection_AsciiString aFlag(theArg);
309   aFlag.LowerCase();
310   if (aFlag == "on"
311    || aFlag == "1")
312   {
313     theIsOn = Standard_True;
314     return Standard_True;
315   }
316   else if (aFlag == "off"
317         || aFlag == "0")
318   {
319     theIsOn = Standard_False;
320     return Standard_True;
321   }
322   return Standard_False;
323 }
324
325 //=======================================================================
326 //function : GetSelectedShapes
327 //purpose  :
328 //=======================================================================
329 void ViewerTest::GetSelectedShapes (TopTools_ListOfShape& theSelectedShapes)
330 {
331   for (GetAISContext()->InitSelected(); GetAISContext()->MoreSelected(); GetAISContext()->NextSelected())
332   {
333     TopoDS_Shape aShape = GetAISContext()->SelectedShape();
334     if (!aShape.IsNull())
335     {
336       theSelectedShapes.Append (aShape);
337     }
338   }
339 }
340
341 //=======================================================================
342 //function : ParseLineType
343 //purpose  :
344 //=======================================================================
345 Standard_Boolean ViewerTest::ParseLineType (Standard_CString   theArg,
346                                             Aspect_TypeOfLine& theType)
347 {
348   TCollection_AsciiString aTypeStr (theArg);
349   aTypeStr.LowerCase();
350   if (aTypeStr == "empty")
351   {
352     theType = Aspect_TOL_EMPTY;
353   }
354   else if (aTypeStr == "solid")
355   {
356     theType = Aspect_TOL_SOLID;
357   }
358   else if (aTypeStr == "dot")
359   {
360     theType = Aspect_TOL_DOT;
361   }
362   else if (aTypeStr == "dash")
363   {
364     theType = Aspect_TOL_DASH;
365   }
366   else if (aTypeStr == "dotdash")
367   {
368     theType = Aspect_TOL_DOTDASH;
369   }
370   else if (aTypeStr.IsIntegerValue())
371   {
372     const int aTypeInt = aTypeStr.IntegerValue();
373     if (aTypeInt < -1 || aTypeInt >= Aspect_TOL_USERDEFINED)
374     {
375       return Standard_False;
376     }
377     theType = (Aspect_TypeOfLine )aTypeInt;
378   }
379   else
380   {
381     return Standard_False;
382   }
383   return Standard_True;
384 }
385
386 //=======================================================================
387 //function : ParseMarkerType
388 //purpose  :
389 //=======================================================================
390 Standard_Boolean ViewerTest::ParseMarkerType (Standard_CString theArg,
391                                               Aspect_TypeOfMarker& theType,
392                                               Handle(Image_PixMap)& theImage)
393 {
394   theImage.Nullify();
395   TCollection_AsciiString aTypeStr (theArg);
396   aTypeStr.LowerCase();
397   if (aTypeStr == "empty")
398   {
399     theType = Aspect_TOM_EMPTY;
400   }
401   else if (aTypeStr == "point"
402         || aTypeStr == "dot"
403         || aTypeStr == ".")
404   {
405     theType = Aspect_TOM_POINT;
406   }
407   else if (aTypeStr == "plus"
408         || aTypeStr == "+")
409   {
410     theType = Aspect_TOM_PLUS;
411   }
412   else if (aTypeStr == "star"
413         || aTypeStr == "*")
414   {
415     theType = Aspect_TOM_STAR;
416   }
417   else if (aTypeStr == "cross"
418         || aTypeStr == "x")
419   {
420     theType = Aspect_TOM_X;
421   }
422   else if (aTypeStr == "circle"
423         || aTypeStr == "o")
424   {
425     theType = Aspect_TOM_O;
426   }
427   else if (aTypeStr == "pointincircle")
428   {
429     theType = Aspect_TOM_O_POINT;
430   }
431   else if (aTypeStr == "plusincircle")
432   {
433     theType = Aspect_TOM_O_PLUS;
434   }
435   else if (aTypeStr == "starincircle")
436   {
437     theType = Aspect_TOM_O_STAR;
438   }
439   else if (aTypeStr == "crossincircle"
440         || aTypeStr == "xcircle")
441   {
442     theType = Aspect_TOM_O_X;
443   }
444   else if (aTypeStr == "ring1")
445   {
446     theType = Aspect_TOM_RING1;
447   }
448   else if (aTypeStr == "ring2")
449   {
450     theType = Aspect_TOM_RING2;
451   }
452   else if (aTypeStr == "ring"
453         || aTypeStr == "ring3")
454   {
455     theType = Aspect_TOM_RING3;
456   }
457   else if (aTypeStr == "ball")
458   {
459     theType = Aspect_TOM_BALL;
460   }
461   else if (aTypeStr.IsIntegerValue())
462   {
463     const int aTypeInt = aTypeStr.IntegerValue();
464     if (aTypeInt < -1 || aTypeInt >= Aspect_TOM_USERDEFINED)
465     {
466       return Standard_False;
467     }
468     theType = (Aspect_TypeOfMarker )aTypeInt;
469   }
470   else
471   {
472     theType = Aspect_TOM_USERDEFINED;
473     Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
474     if (!anImage->Load (theArg))
475     {
476       return Standard_False;
477     }
478     if (anImage->Format() == Image_Format_Gray)
479     {
480       anImage->SetFormat (Image_Format_Alpha);
481     }
482     else if (anImage->Format() == Image_Format_GrayF)
483     {
484       anImage->SetFormat (Image_Format_AlphaF);
485     }
486     theImage = anImage;
487   }
488   return Standard_True;
489 }
490
491 //=======================================================================
492 //function : ParseShadingModel
493 //purpose  :
494 //=======================================================================
495 Standard_Boolean ViewerTest::ParseShadingModel (Standard_CString              theArg,
496                                                 Graphic3d_TypeOfShadingModel& theModel)
497 {
498   TCollection_AsciiString aTypeStr (theArg);
499   aTypeStr.LowerCase();
500   if (aTypeStr == "unlit"
501    || aTypeStr == "color"
502    || aTypeStr == "none")
503   {
504     theModel = Graphic3d_TOSM_UNLIT;
505   }
506   else if (aTypeStr == "flat"
507         || aTypeStr == "facet")
508   {
509     theModel = Graphic3d_TOSM_FACET;
510   }
511   else if (aTypeStr == "gouraud"
512         || aTypeStr == "vertex"
513         || aTypeStr == "vert")
514   {
515     theModel = Graphic3d_TOSM_VERTEX;
516   }
517   else if (aTypeStr == "phong"
518         || aTypeStr == "fragment"
519         || aTypeStr == "frag"
520         || aTypeStr == "pixel")
521   {
522     theModel = Graphic3d_TOSM_FRAGMENT;
523   }
524   else if (aTypeStr == "default"
525         || aTypeStr == "def")
526   {
527     theModel = Graphic3d_TOSM_DEFAULT;
528   }
529   else if (aTypeStr.IsIntegerValue())
530   {
531     const int aTypeInt = aTypeStr.IntegerValue();
532     if (aTypeInt <= Graphic3d_TOSM_DEFAULT || aTypeInt >= Graphic3d_TypeOfShadingModel_NB)
533     {
534       return Standard_False;
535     }
536     theModel = (Graphic3d_TypeOfShadingModel)aTypeInt;
537   }
538   else
539   {
540     return Standard_False;
541   }
542   return Standard_True;
543 }
544
545 //=======================================================================
546 //function : parseZLayer
547 //purpose  :
548 //=======================================================================
549 Standard_Boolean ViewerTest::parseZLayer (Standard_CString theArg,
550                                           Standard_Boolean theToAllowInteger,
551                                           Graphic3d_ZLayerId& theLayer)
552 {
553   TCollection_AsciiString aName (theArg);
554   aName.LowerCase();
555   if (aName == "default"
556    || aName == "def")
557   {
558     theLayer = Graphic3d_ZLayerId_Default;
559   }
560   else if (aName == "top")
561   {
562     theLayer = Graphic3d_ZLayerId_Top;
563   }
564   else if (aName == "topmost")
565   {
566     theLayer = Graphic3d_ZLayerId_Topmost;
567   }
568   else if (aName == "overlay"
569         || aName == "toposd")
570   {
571     theLayer = Graphic3d_ZLayerId_TopOSD;
572   }
573   else if (aName == "underlay"
574         || aName == "botosd")
575   {
576     theLayer = Graphic3d_ZLayerId_BotOSD;
577   }
578   else if (aName == "undefined")
579   {
580     theLayer = Graphic3d_ZLayerId_UNKNOWN;
581   }
582   else if (!GetAISContext().IsNull())
583   {
584     const Handle(V3d_Viewer)& aViewer = ViewerTest::GetAISContext()->CurrentViewer();
585     TColStd_SequenceOfInteger aLayers;
586     aViewer->GetAllZLayers (aLayers);
587     for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
588     {
589       Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
590       if (TCollection_AsciiString::IsSameString (aSettings.Name(), aName, Standard_False))
591       {
592         theLayer = aLayeriter.Value();
593         return true;
594       }
595     }
596
597     if (!theToAllowInteger
598      || !aName.IsIntegerValue())
599     {
600       return false;
601     }
602     Graphic3d_ZLayerId aLayer = aName.IntegerValue();
603     if (aLayer == Graphic3d_ZLayerId_UNKNOWN
604      || std::find (aLayers.begin(), aLayers.end(), aLayer) != aLayers.end())
605     {
606       theLayer = aLayer;
607       return true;
608     }
609     return false;
610   }
611   return true;
612 }
613
614 //=======================================================================
615 //function : GetTypeNames
616 //purpose  :
617 //=======================================================================
618 static const char** GetTypeNames()
619 {
620   static const char* names[14] = {"Point","Axis","Trihedron","PlaneTrihedron", "Line","Circle","Plane",
621                           "Shape","ConnectedShape","MultiConn.Shape",
622                           "ConnectedInter.","MultiConn.",
623                           "Constraint","Dimension"};
624   static const char** ThePointer = names;
625   return ThePointer;
626 }
627
628 //=======================================================================
629 //function : GetTypeAndSignfromString
630 //purpose  :
631 //=======================================================================
632 void GetTypeAndSignfromString (const char* name,AIS_KindOfInteractive& TheType,Standard_Integer& TheSign)
633 {
634   const char ** thefullnames = GetTypeNames();
635   Standard_Integer index(-1);
636
637   for(Standard_Integer i=0;i<=13 && index==-1;i++)
638     if(!strcasecmp(name,thefullnames[i]))
639       index = i;
640
641   if(index ==-1){
642     TheType = AIS_KOI_None;
643     TheSign = -1;
644     return;
645   }
646
647   if(index<=6){
648     TheType = AIS_KOI_Datum;
649     TheSign = index+1;
650   }
651   else if (index <=9){
652     TheType = AIS_KOI_Shape;
653     TheSign = index-7;
654   }
655   else if(index<=11){
656     TheType = AIS_KOI_Object;
657     TheSign = index-10;
658   }
659   else{
660     TheType = AIS_KOI_Relation;
661     TheSign = index-12;
662   }
663
664 }
665
666
667
668 #include <string.h>
669 #include <Draw_Interpretor.hxx>
670 #include <Draw.hxx>
671 #include <Draw_Appli.hxx>
672 #include <DBRep.hxx>
673
674
675 #include <TCollection_AsciiString.hxx>
676 #include <V3d_Viewer.hxx>
677 #include <V3d_View.hxx>
678 #include <V3d.hxx>
679
680 #include <AIS_InteractiveContext.hxx>
681 #include <AIS_Shape.hxx>
682 #include <AIS_DisplayMode.hxx>
683 #include <TColStd_MapOfInteger.hxx>
684 #include <AIS_MapOfInteractive.hxx>
685 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
686 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
687 #include <ViewerTest_EventManager.hxx>
688
689 #include <TopoDS_Solid.hxx>
690 #include <BRepTools.hxx>
691 #include <BRep_Builder.hxx>
692 #include <TopAbs_ShapeEnum.hxx>
693
694 #include <TopoDS.hxx>
695 #include <BRep_Tool.hxx>
696
697
698 #include <Draw_Window.hxx>
699 #include <AIS_ListIteratorOfListOfInteractive.hxx>
700 #include <AIS_ListOfInteractive.hxx>
701 #include <AIS_DisplayMode.hxx>
702 #include <TopTools_ListOfShape.hxx>
703 #include <BRepOffsetAPI_MakeThickSolid.hxx>
704
705 //==============================================================================
706 //  VIEWER OBJECT MANAGEMENT GLOBAL VARIABLES
707 //==============================================================================
708 Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(){
709   static ViewerTest_DoubleMapOfInteractiveAndName TheMap;
710   return TheMap;
711 }
712
713 //=======================================================================
714 //function : Display
715 //purpose  :
716 //=======================================================================
717 Standard_Boolean ViewerTest::Display (const TCollection_AsciiString&       theName,
718                                       const Handle(AIS_InteractiveObject)& theObject,
719                                       const Standard_Boolean               theToUpdate,
720                                       const Standard_Boolean               theReplaceIfExists)
721 {
722   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
723   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
724   if (aCtx.IsNull())
725   {
726     std::cout << "Error: AIS context is not available.\n";
727     return Standard_False;
728   }
729
730   if (aMap.IsBound2 (theName))
731   {
732     if (!theReplaceIfExists)
733     {
734       std::cout << "Error: other interactive object has been already registered with name: " << theName << ".\n"
735                 << "Please use another name.\n";
736       return Standard_False;
737     }
738
739     if (Handle(AIS_InteractiveObject) anOldObj = aMap.Find2 (theName))
740     {
741       aCtx->Remove (anOldObj, theObject.IsNull() && theToUpdate);
742     }
743     aMap.UnBind2 (theName);
744   }
745
746   if (theObject.IsNull())
747   {
748     // object with specified name has been already unbound
749     return Standard_True;
750   }
751
752   // unbind AIS object if it was bound with another name
753   aMap.UnBind1 (theObject);
754
755   // can be registered without rebinding
756   aMap.Bind (theObject, theName);
757   aCtx->Display (theObject, theToUpdate);
758   return Standard_True;
759 }
760
761 //! Alias for ViewerTest::Display(), compatibility with old code.
762 Standard_EXPORT Standard_Boolean VDisplayAISObject (const TCollection_AsciiString&       theName,
763                                                     const Handle(AIS_InteractiveObject)& theObject,
764                                                     Standard_Boolean theReplaceIfExists = Standard_True)
765 {
766   return ViewerTest::Display (theName, theObject, Standard_True, theReplaceIfExists);
767 }
768
769 static NCollection_List<Handle(ViewerTest_EventManager)> theEventMgrs;
770
771 static Handle(V3d_View)&  a3DView()
772 {
773   static Handle(V3d_View) Viou;
774   return Viou;
775 }
776
777
778 Standard_EXPORT Handle(AIS_InteractiveContext)& TheAISContext(){
779   static Handle(AIS_InteractiveContext) aContext;
780   return aContext;
781 }
782
783 const Handle(V3d_View)& ViewerTest::CurrentView()
784 {
785   return a3DView();
786 }
787 void ViewerTest::CurrentView(const Handle(V3d_View)& V)
788 {
789   a3DView() = V;
790 }
791
792 const Handle(AIS_InteractiveContext)& ViewerTest::GetAISContext()
793 {
794   return TheAISContext();
795 }
796
797 void ViewerTest::SetAISContext (const Handle(AIS_InteractiveContext)& aCtx)
798 {
799   TheAISContext() = aCtx;
800   ViewerTest::ResetEventManager();
801 }
802
803 Handle(V3d_Viewer) ViewerTest::GetViewerFromContext()
804 {
805   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
806 }
807
808 Handle(V3d_Viewer) ViewerTest::GetCollectorFromContext()
809 {
810   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
811 }
812
813
814 void ViewerTest::SetEventManager(const Handle(ViewerTest_EventManager)& EM){
815   theEventMgrs.Prepend(EM);
816 }
817
818 void ViewerTest::UnsetEventManager()
819 {
820   theEventMgrs.RemoveFirst();
821 }
822
823
824 void ViewerTest::ResetEventManager()
825 {
826   theEventMgrs.Clear();
827   theEventMgrs.Prepend (new ViewerTest_EventManager (ViewerTest::CurrentView(), ViewerTest::GetAISContext()));
828 }
829
830 Handle(ViewerTest_EventManager) ViewerTest::CurrentEventManager()
831 {
832   return !theEventMgrs.IsEmpty()
833         ? theEventMgrs.First()
834         : Handle(ViewerTest_EventManager)();
835 }
836
837 //=======================================================================
838 //function : Get Context and active view
839 //purpose  :
840 //=======================================================================
841 static Standard_Boolean getCtxAndView (Handle(AIS_InteractiveContext)& theCtx,
842                                        Handle(V3d_View)&               theView)
843 {
844   theCtx  = ViewerTest::GetAISContext();
845   theView = ViewerTest::CurrentView();
846   if (theCtx.IsNull()
847    || theView.IsNull())
848   {
849     std::cout << "Error: cannot find an active view!\n";
850     return Standard_False;
851   }
852   return Standard_True;
853 }
854
855 //==============================================================================
856 //function : Clear
857 //purpose  : Remove all the object from the viewer
858 //==============================================================================
859 void ViewerTest::Clear()
860 {
861   if (a3DView().IsNull())
862   {
863     return;
864   }
865
866   NCollection_Sequence<Handle(AIS_InteractiveObject)> aListRemoved;
867   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS()); anObjIter.More(); anObjIter.Next())
868   {
869     const Handle(AIS_InteractiveObject) anObj = anObjIter.Key1();
870     if (anObj->GetContext() != TheAISContext())
871     {
872       continue;
873     }
874
875     std::cout << "Remove " << anObjIter.Key2() << std::endl;
876     TheAISContext()->Remove (anObj, Standard_False);
877     aListRemoved.Append (anObj);
878   }
879
880   TheAISContext()->RebuildSelectionStructs();
881   TheAISContext()->UpdateCurrentViewer();
882   if (aListRemoved.Size() == GetMapOfAIS().Extent())
883   {
884     GetMapOfAIS().Clear();
885   }
886   else
887   {
888     for (NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator anObjIter (aListRemoved); anObjIter.More(); anObjIter.Next())
889     {
890       GetMapOfAIS().UnBind1 (anObjIter.Value());
891     }
892   }
893 }
894
895 //==============================================================================
896 //function : CopyIsoAspect
897 //purpose  : Returns copy Prs3d_IsoAspect with new number of isolines.
898 //==============================================================================
899 static Handle(Prs3d_IsoAspect) CopyIsoAspect
900       (const Handle(Prs3d_IsoAspect) &theIsoAspect,
901        const Standard_Integer theNbIsos)
902 {
903   Quantity_Color    aColor = theIsoAspect->Aspect()->Color();
904   Aspect_TypeOfLine aType  = theIsoAspect->Aspect()->Type();
905   Standard_Real     aWidth = theIsoAspect->Aspect()->Width();
906
907   Handle(Prs3d_IsoAspect) aResult =
908     new Prs3d_IsoAspect(aColor, aType, aWidth, theNbIsos);
909
910   return aResult;
911 }
912
913 //==============================================================================
914 //function : visos
915 //purpose  : Returns or sets the number of U- and V- isos and isIsoOnPlane flag
916 //Draw arg : [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]
917 //==============================================================================
918 static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
919 {
920   if (TheAISContext().IsNull()) {
921     di << argv[0] << " Call 'vinit' before!\n";
922     return 1;
923   }
924
925   if (argc <= 1) {
926     di << "Current number of isos : " <<
927       TheAISContext()->IsoNumber(AIS_TOI_IsoU) << " " <<
928       TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n";
929     di << "IsoOnPlane mode is " <<
930       (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n";
931     di << "IsoOnTriangulation mode is " <<
932       (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n";
933     return 0;
934   }
935
936   Standard_Integer aLastInd = argc - 1;
937   Standard_Boolean isChanged = Standard_False;
938   Standard_Integer aNbUIsos = 0;
939   Standard_Integer aNbVIsos = 0;
940
941   if (aLastInd >= 3) {
942     Standard_Boolean isIsoOnPlane = Standard_False;
943
944     if (strcmp(argv[aLastInd], "1") == 0) {
945       isIsoOnPlane = Standard_True;
946       isChanged    = Standard_True;
947     } else if (strcmp(argv[aLastInd], "0") == 0) {
948       isIsoOnPlane = Standard_False;
949       isChanged    = Standard_True;
950     }
951
952     if (isChanged) {
953       aNbVIsos = Draw::Atoi(argv[aLastInd - 1]);
954       aNbUIsos = Draw::Atoi(argv[aLastInd - 2]);
955       aLastInd -= 3;
956
957       di << "New number of isos : " << aNbUIsos << " " << aNbVIsos << "\n";
958       di << "New IsoOnPlane mode is " << (isIsoOnPlane ? "ON" : "OFF") << "\n";
959
960       TheAISContext()->IsoOnPlane(isIsoOnPlane);
961
962       if (aLastInd == 0) {
963         // If there are no shapes provided set the default numbers.
964         TheAISContext()->SetIsoNumber(aNbUIsos, AIS_TOI_IsoU);
965         TheAISContext()->SetIsoNumber(aNbVIsos, AIS_TOI_IsoV);
966       }
967     }
968   }
969
970   Standard_Integer i;
971
972   for (i = 1; i <= aLastInd; i++)
973   {
974     TCollection_AsciiString name(argv[i]);
975     Handle(AIS_InteractiveObject) aShape;
976     GetMapOfAIS().Find2(name, aShape);
977     if (aShape.IsNull())
978     {
979       std::cout << "Syntax error: object '" << name << "' is not found\n";
980       return 1;
981     }
982
983     Handle(Prs3d_Drawer) CurDrawer = aShape->Attributes();
984     Handle(Prs3d_IsoAspect) aUIso = CurDrawer->UIsoAspect();
985     Handle(Prs3d_IsoAspect) aVIso = CurDrawer->VIsoAspect();
986     if (isChanged)
987     {
988       CurDrawer->SetUIsoAspect(CopyIsoAspect(aUIso, aNbUIsos));
989       CurDrawer->SetVIsoAspect(CopyIsoAspect(aVIso, aNbVIsos));
990       TheAISContext()->SetLocalAttributes (aShape, CurDrawer, Standard_False);
991       TheAISContext()->Redisplay (aShape, Standard_False);
992     }
993     else
994     {
995       di << "Number of isos for " << argv[i] << " : "
996           << aUIso->Number() << " " << aVIso->Number() << "\n";
997     }
998   }
999
1000   if (isChanged) {
1001     TheAISContext()->UpdateCurrentViewer();
1002   }
1003
1004   return 0;
1005 }
1006
1007 static Standard_Integer VDispSensi (Draw_Interpretor& ,
1008                                     Standard_Integer  theArgNb,
1009                                     Standard_CString* )
1010 {
1011   if (theArgNb > 1)
1012   {
1013     std::cout << "Error: wrong syntax!\n";
1014     return 1;
1015   }
1016
1017   Handle(AIS_InteractiveContext) aCtx;
1018   Handle(V3d_View)               aView;
1019   if (!getCtxAndView (aCtx, aView))
1020   {
1021     return 1;
1022   }
1023
1024   aCtx->DisplayActiveSensitive (aView);
1025   return 0;
1026
1027 }
1028
1029 static Standard_Integer VClearSensi (Draw_Interpretor& ,
1030                                      Standard_Integer  theArgNb,
1031                                      Standard_CString* )
1032 {
1033   if (theArgNb > 1)
1034   {
1035     std::cout << "Error: wrong syntax!\n";
1036     return 1;
1037   }
1038
1039   Handle(AIS_InteractiveContext) aCtx;
1040   Handle(V3d_View)               aView;
1041   if (!getCtxAndView (aCtx, aView))
1042   {
1043     return 1;
1044   }
1045   aCtx->ClearActiveSensitive (aView);
1046   return 0;
1047 }
1048
1049 //==============================================================================
1050 //function : VDir
1051 //purpose  : To list the displayed object with their attributes
1052 //==============================================================================
1053 static int VDir (Draw_Interpretor& theDI,
1054                  Standard_Integer theNbArgs,
1055                  const char** theArgVec)
1056 {
1057   TCollection_AsciiString aMatch;
1058   Standard_Boolean toFormat = Standard_False;
1059   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
1060   {
1061     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
1062     anArgCase.LowerCase();
1063     if (anArgCase == "-list"
1064      || anArgCase == "-format")
1065     {
1066       toFormat = Standard_True;
1067     }
1068     else if (aMatch.IsEmpty())
1069     {
1070       aMatch = theArgVec[anArgIter];
1071     }
1072     else
1073     {
1074       std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
1075       return 1;
1076     }
1077   }
1078
1079   TCollection_AsciiString aRes;
1080   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
1081   {
1082     if (!aMatch.IsEmpty())
1083     {
1084       const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aMatch + "' '" + anIter.Key2() + "'";
1085       if (theDI.Eval (aCheck.ToCString()) == 0
1086       && *theDI.Result() != '1')
1087       {
1088         continue;
1089       }
1090     }
1091
1092     if (toFormat)
1093     {
1094       aRes += TCollection_AsciiString("\t") + anIter.Key2() + "\n";
1095     }
1096     else
1097     {
1098       aRes += anIter.Key2() + " ";
1099     }
1100   }
1101   theDI.Reset();
1102   theDI << aRes;
1103   return 0;
1104 }
1105
1106 //! Auxiliary enumeration
1107 enum ViewerTest_StereoPair
1108 {
1109   ViewerTest_SP_Single,
1110   ViewerTest_SP_SideBySide,
1111   ViewerTest_SP_OverUnder
1112 };
1113
1114 //==============================================================================
1115 //function : VDump
1116 //purpose  : To dump the active view snapshot to image file
1117 //==============================================================================
1118 static Standard_Integer VDump (Draw_Interpretor& theDI,
1119                                Standard_Integer  theArgNb,
1120                                Standard_CString* theArgVec)
1121 {
1122   if (theArgNb < 2)
1123   {
1124     std::cout << "Error: wrong number of arguments! Image file name should be specified at least.\n";
1125     return 1;
1126   }
1127
1128   Standard_Integer      anArgIter   = 1;
1129   Standard_CString      aFilePath   = theArgVec[anArgIter++];
1130   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
1131   V3d_ImageDumpOptions  aParams;
1132   aParams.BufferType    = Graphic3d_BT_RGB;
1133   aParams.StereoOptions = V3d_SDO_MONO;
1134   for (; anArgIter < theArgNb; ++anArgIter)
1135   {
1136     TCollection_AsciiString anArg (theArgVec[anArgIter]);
1137     anArg.LowerCase();
1138     if (anArg == "-buffer")
1139     {
1140       if (++anArgIter >= theArgNb)
1141       {
1142         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
1143         return 1;
1144       }
1145
1146       TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
1147       aBufArg.LowerCase();
1148       if (aBufArg == "rgba")
1149       {
1150         aParams.BufferType = Graphic3d_BT_RGBA;
1151       }
1152       else if (aBufArg == "rgb")
1153       {
1154         aParams.BufferType = Graphic3d_BT_RGB;
1155       }
1156       else if (aBufArg == "depth")
1157       {
1158         aParams.BufferType = Graphic3d_BT_Depth;
1159       }
1160       else
1161       {
1162         std::cout << "Error: unknown buffer '" << aBufArg << "'\n";
1163         return 1;
1164       }
1165     }
1166     else if (anArg == "-stereo")
1167     {
1168       if (++anArgIter >= theArgNb)
1169       {
1170         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
1171         return 1;
1172       }
1173
1174       TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
1175       aStereoArg.LowerCase();
1176       if (aStereoArg == "l"
1177        || aStereoArg == "left")
1178       {
1179         aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1180       }
1181       else if (aStereoArg == "r"
1182             || aStereoArg == "right")
1183       {
1184         aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1185       }
1186       else if (aStereoArg == "mono")
1187       {
1188         aParams.StereoOptions = V3d_SDO_MONO;
1189       }
1190       else if (aStereoArg == "blended"
1191             || aStereoArg == "blend"
1192             || aStereoArg == "stereo")
1193       {
1194         aParams.StereoOptions = V3d_SDO_BLENDED;
1195       }
1196       else if (aStereoArg == "sbs"
1197             || aStereoArg == "sidebyside")
1198       {
1199         aStereoPair = ViewerTest_SP_SideBySide;
1200       }
1201       else if (aStereoArg == "ou"
1202             || aStereoArg == "overunder")
1203       {
1204         aStereoPair = ViewerTest_SP_OverUnder;
1205       }
1206       else
1207       {
1208         std::cout << "Error: unknown stereo format '" << aStereoArg << "'\n";
1209         return 1;
1210       }
1211     }
1212     else if (anArg == "-rgba"
1213           || anArg ==  "rgba")
1214     {
1215       aParams.BufferType = Graphic3d_BT_RGBA;
1216     }
1217     else if (anArg == "-rgb"
1218           || anArg ==  "rgb")
1219     {
1220       aParams.BufferType = Graphic3d_BT_RGB;
1221     }
1222     else if (anArg == "-depth"
1223           || anArg ==  "depth")
1224     {
1225       aParams.BufferType = Graphic3d_BT_Depth;
1226     }
1227     else if (anArg == "-width"
1228           || anArg ==  "width"
1229           || anArg ==  "sizex")
1230     {
1231       if (aParams.Width != 0)
1232       {
1233         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
1234         return 1;
1235       }
1236       else if (++anArgIter >= theArgNb)
1237       {
1238         std::cout << "Error: integer value is expected right after 'width'\n";
1239         return 1;
1240       }
1241       aParams.Width = Draw::Atoi (theArgVec[anArgIter]);
1242     }
1243     else if (anArg == "-height"
1244           || anArg ==  "height"
1245           || anArg ==  "-sizey")
1246     {
1247       if (aParams.Height != 0)
1248       {
1249         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
1250         return 1;
1251       }
1252       else if (++anArgIter >= theArgNb)
1253       {
1254         std::cout << "Error: integer value is expected right after 'height'\n";
1255         return 1;
1256       }
1257       aParams.Height = Draw::Atoi (theArgVec[anArgIter]);
1258     }
1259     else if (anArg == "-tile"
1260           || anArg == "-tilesize")
1261     {
1262       if (++anArgIter >= theArgNb)
1263       {
1264         std::cout << "Error: integer value is expected right after 'tileSize'\n";
1265         return 1;
1266       }
1267       aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
1268     }
1269     else
1270     {
1271       std::cout << "Error: unknown argument '" << theArgVec[anArgIter] << "'\n";
1272       return 1;
1273     }
1274   }
1275   if ((aParams.Width <= 0 && aParams.Height >  0)
1276    || (aParams.Width >  0 && aParams.Height <= 0))
1277   {
1278     std::cout << "Error: dimensions " << aParams.Width << "x" << aParams.Height << " are incorrect\n";
1279     return 1;
1280   }
1281
1282   Handle(V3d_View) aView = ViewerTest::CurrentView();
1283   if (aView.IsNull())
1284   {
1285     std::cout << "Error: cannot find an active view!\n";
1286     return 1;
1287   }
1288
1289   if (aParams.Width <= 0 || aParams.Height <= 0)
1290   {
1291     aView->Window()->Size (aParams.Width, aParams.Height);
1292   }
1293
1294   Image_AlienPixMap aPixMap;
1295   Image_Format aFormat = Image_Format_UNKNOWN;
1296   switch (aParams.BufferType)
1297   {
1298     case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
1299     case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
1300     case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
1301     case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
1302   }
1303
1304   switch (aStereoPair)
1305   {
1306     case ViewerTest_SP_Single:
1307     {
1308       if (!aView->ToPixMap (aPixMap, aParams))
1309       {
1310         theDI << "Fail: view dump failed!\n";
1311         return 0;
1312       }
1313       else if (aPixMap.SizeX() != Standard_Size(aParams.Width)
1314             || aPixMap.SizeY() != Standard_Size(aParams.Height))
1315       {
1316         theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
1317               << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
1318       }
1319       break;
1320     }
1321     case ViewerTest_SP_SideBySide:
1322     {
1323       if (!aPixMap.InitZero (aFormat, aParams.Width * 2, aParams.Height))
1324       {
1325         theDI << "Fail: not enough memory for image allocation!\n";
1326         return 0;
1327       }
1328
1329       Image_PixMap aPixMapL, aPixMapR;
1330       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1331                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1332       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aParams.Width,
1333                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1334
1335       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1336       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1337       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1338       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1339       if (!isOk)
1340       {
1341         theDI << "Fail: view dump failed!\n";
1342         return 0;
1343       }
1344       break;
1345     }
1346     case ViewerTest_SP_OverUnder:
1347     {
1348       if (!aPixMap.InitZero (aFormat, aParams.Width, aParams.Height * 2))
1349       {
1350         theDI << "Fail: not enough memory for image allocation!\n";
1351         return 0;
1352       }
1353
1354       Image_PixMap aPixMapL, aPixMapR;
1355       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1356                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1357       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
1358                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1359
1360       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1361       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1362       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1363       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1364       if (!isOk)
1365       {
1366         theDI << "Fail: view dump failed!\n";
1367         return 0;
1368       }
1369       break;
1370     }
1371   }
1372
1373   if (!aPixMap.Save (aFilePath))
1374   {
1375     theDI << "Fail: image can not be saved!\n";
1376   }
1377   return 0;
1378 }
1379
1380 enum TypeOfDispOperation
1381 {
1382   TypeOfDispOperation_SetDispMode,
1383   TypeOfDispOperation_UnsetDispMode
1384 };
1385
1386 //! Displays,Erase...
1387 static void VwrTst_DispErase (const Handle(AIS_InteractiveObject)& thePrs,
1388                                                 const Standard_Integer theMode,
1389                                                 const TypeOfDispOperation theType,
1390                                                 const Standard_Boolean theToUpdate)
1391 {
1392   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1393   switch (theType)
1394   {
1395     case TypeOfDispOperation_SetDispMode:
1396     {
1397       if (!thePrs.IsNull())
1398       {
1399         aCtx->SetDisplayMode (thePrs, theMode, theToUpdate);
1400       }
1401       else
1402       {
1403         aCtx->SetDisplayMode ((AIS_DisplayMode )theMode, theToUpdate);
1404       }
1405       break;
1406     }
1407     case TypeOfDispOperation_UnsetDispMode:
1408     {
1409       if (!thePrs.IsNull())
1410       {
1411         aCtx->UnsetDisplayMode (thePrs, theToUpdate);
1412       }
1413       else
1414       {
1415         aCtx->SetDisplayMode (AIS_WireFrame, theToUpdate);
1416       }
1417       break;
1418     }
1419   }
1420 }
1421
1422 //=======================================================================
1423 //function :
1424 //purpose  :
1425 //=======================================================================
1426 static int VDispMode (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1427 {
1428   if (argc < 1
1429    || argc > 3)
1430   {
1431     std::cout << "Syntax error: wrong number of arguments\n";
1432     return 1;
1433   }
1434
1435   TypeOfDispOperation aType = TCollection_AsciiString (argv[0]) == "vunsetdispmode"
1436                             ? TypeOfDispOperation_UnsetDispMode
1437                             : TypeOfDispOperation_SetDispMode;
1438   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1439   if (aType == TypeOfDispOperation_UnsetDispMode)
1440   {
1441     if (argc == 1)
1442     {
1443       if (aCtx->NbSelected() == 0)
1444       {
1445         VwrTst_DispErase (Handle(AIS_InteractiveObject)(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1446       }
1447       else
1448       {
1449         for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1450         {
1451           VwrTst_DispErase (aCtx->SelectedInteractive(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1452         }
1453       }
1454       aCtx->UpdateCurrentViewer();
1455     }
1456     else
1457     {
1458       TCollection_AsciiString aName = argv[1];
1459       Handle(AIS_InteractiveObject) aPrs;
1460       if (GetMapOfAIS().Find2 (aName, aPrs)
1461       && !aPrs.IsNull())
1462       {
1463         VwrTst_DispErase (aPrs, -1, TypeOfDispOperation_UnsetDispMode, Standard_True);
1464       }
1465     }
1466   }
1467   else if (argc == 2)
1468   {
1469     Standard_Integer aDispMode = Draw::Atoi (argv[1]);
1470     if (aCtx->NbSelected() == 0
1471      && aType == TypeOfDispOperation_SetDispMode)
1472     {
1473       VwrTst_DispErase (Handle(AIS_InteractiveObject)(), aDispMode, TypeOfDispOperation_SetDispMode, Standard_True);
1474     }
1475     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1476     {
1477       VwrTst_DispErase (aCtx->SelectedInteractive(), aDispMode, aType, Standard_False);
1478     }
1479     aCtx->UpdateCurrentViewer();
1480   }
1481   else
1482   {
1483     Handle(AIS_InteractiveObject) aPrs;
1484     TCollection_AsciiString aName (argv[1]);
1485     if (GetMapOfAIS().Find2 (aName, aPrs)
1486      && !aPrs.IsNull())
1487     {
1488       VwrTst_DispErase (aPrs, Draw::Atoi(argv[2]), aType, Standard_True);
1489     }
1490   }
1491   return 0;
1492 }
1493
1494
1495 //=======================================================================
1496 //function :
1497 //purpose  :
1498 //=======================================================================
1499 static int VSubInt(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1500 {
1501   if(argc==1) return 1;
1502   Standard_Integer On = Draw::Atoi(argv[1]);
1503   const Handle(AIS_InteractiveContext)& Ctx = ViewerTest::GetAISContext();
1504
1505   if(argc==2)
1506   {
1507     TCollection_AsciiString isOnOff = On == 1 ? "on" : "off";
1508     di << "Sub intensite is turned " << isOnOff << " for " << Ctx->NbSelected() << "objects\n";
1509     for (Ctx->InitSelected(); Ctx->MoreSelected(); Ctx->NextSelected())
1510     {
1511       if(On==1)
1512       {
1513         Ctx->SubIntensityOn (Ctx->SelectedInteractive(), Standard_False);
1514       }
1515       else
1516       {
1517         Ctx->SubIntensityOff (Ctx->SelectedInteractive(), Standard_False);
1518       }
1519     }
1520
1521     Ctx->UpdateCurrentViewer();
1522   }
1523   else {
1524     Handle(AIS_InteractiveObject) IO;
1525     TCollection_AsciiString name = argv[2];
1526     if (GetMapOfAIS().Find2 (name, IO)
1527     && !IO.IsNull())
1528     {
1529       if(On==1)
1530         Ctx->SubIntensityOn(IO, Standard_True);
1531       else
1532         Ctx->SubIntensityOff(IO, Standard_True);
1533     }
1534     else return 1;
1535   }
1536   return 0;
1537 }
1538
1539 //! Auxiliary class to iterate presentations from different collections.
1540 class ViewTest_PrsIter
1541 {
1542 public:
1543
1544   //! Create and initialize iterator object.
1545   ViewTest_PrsIter (const TCollection_AsciiString& theName)
1546   : mySource (IterSource_All)
1547   {
1548     NCollection_Sequence<TCollection_AsciiString> aNames;
1549     if (!theName.IsEmpty())
1550     aNames.Append (theName);
1551     Init (aNames);
1552   }
1553
1554   //! Create and initialize iterator object.
1555   ViewTest_PrsIter (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1556   : mySource (IterSource_All)
1557   {
1558     Init (theNames);
1559   }
1560
1561   //! Initialize the iterator.
1562   void Init (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1563   {
1564     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1565     mySeq = theNames;
1566     mySelIter.Nullify();
1567     myCurrent.Nullify();
1568     myCurrentTrs.Nullify();
1569     if (!mySeq.IsEmpty())
1570     {
1571       mySource = IterSource_List;
1572       mySeqIter = NCollection_Sequence<TCollection_AsciiString>::Iterator (mySeq);
1573     }
1574     else if (aCtx->NbSelected() > 0)
1575     {
1576       mySource  = IterSource_Selected;
1577       mySelIter = aCtx;
1578       mySelIter->InitSelected();
1579     }
1580     else
1581     {
1582       mySource = IterSource_All;
1583       myMapIter.Initialize (GetMapOfAIS());
1584     }
1585     initCurrent();
1586   }
1587
1588   const TCollection_AsciiString& CurrentName() const
1589   {
1590     return myCurrentName;
1591   }
1592
1593   const Handle(AIS_InteractiveObject)& Current() const
1594   {
1595     return myCurrent;
1596   }
1597
1598   const Handle(Standard_Transient)& CurrentTrs() const
1599   {
1600     return myCurrentTrs;
1601   }
1602
1603   //! @return true if iterator points to valid object within collection
1604   Standard_Boolean More() const
1605   {
1606     switch (mySource)
1607     {
1608       case IterSource_All:      return myMapIter.More();
1609       case IterSource_List:     return mySeqIter.More();
1610       case IterSource_Selected: return mySelIter->MoreSelected();
1611     }
1612     return Standard_False;
1613   }
1614
1615   //! Go to the next item.
1616   void Next()
1617   {
1618     myCurrentName.Clear();
1619     myCurrentTrs.Nullify();
1620     myCurrent.Nullify();
1621     switch (mySource)
1622     {
1623       case IterSource_All:
1624       {
1625         myMapIter.Next();
1626         break;
1627       }
1628       case IterSource_List:
1629       {
1630         mySeqIter.Next();
1631         break;
1632       }
1633       case IterSource_Selected:
1634       {
1635         mySelIter->NextSelected();
1636         break;
1637       }
1638     }
1639     initCurrent();
1640   }
1641
1642 private:
1643
1644   void initCurrent()
1645   {
1646     switch (mySource)
1647     {
1648       case IterSource_All:
1649       {
1650         if (myMapIter.More())
1651         {
1652           myCurrentName = myMapIter.Key2();
1653           myCurrentTrs  = myMapIter.Key1();
1654           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1655         }
1656         break;
1657       }
1658       case IterSource_List:
1659       {
1660         if (mySeqIter.More())
1661         {
1662           if (!GetMapOfAIS().IsBound2 (mySeqIter.Value()))
1663           {
1664             std::cout << "Error: object " << mySeqIter.Value() << " is not displayed!\n";
1665             return;
1666           }
1667           myCurrentName = mySeqIter.Value();
1668           myCurrentTrs  = GetMapOfAIS().Find2 (mySeqIter.Value());
1669           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1670         }
1671         break;
1672       }
1673       case IterSource_Selected:
1674       {
1675         if (mySelIter->MoreSelected())
1676         {
1677           myCurrentName = GetMapOfAIS().Find1 (mySelIter->SelectedInteractive());
1678           myCurrent     = mySelIter->SelectedInteractive();
1679         }
1680         break;
1681       }
1682     }
1683   }
1684
1685 private:
1686
1687   enum IterSource
1688   {
1689     IterSource_All,
1690     IterSource_List,
1691     IterSource_Selected
1692   };
1693
1694 private:
1695
1696   Handle(AIS_InteractiveContext) mySelIter;    //!< iterator for current (selected) objects (IterSource_Selected)
1697   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName myMapIter; //!< iterator for map of all objects (IterSource_All)
1698   NCollection_Sequence<TCollection_AsciiString>           mySeq;
1699   NCollection_Sequence<TCollection_AsciiString>::Iterator mySeqIter;
1700
1701   TCollection_AsciiString        myCurrentName;//!< current item name
1702   Handle(Standard_Transient)     myCurrentTrs; //!< current item (as transient object)
1703   Handle(AIS_InteractiveObject)  myCurrent;    //!< current item
1704
1705   IterSource                     mySource;     //!< iterated collection
1706
1707 };
1708
1709 //! Parse interior style name.
1710 static bool parseInteriorStyle (const TCollection_AsciiString& theArg,
1711                                 Aspect_InteriorStyle& theStyle)
1712 {
1713   TCollection_AsciiString anArg (theArg);
1714   anArg.LowerCase();
1715   if (anArg == "empty")
1716   {
1717     theStyle = Aspect_IS_EMPTY;
1718   }
1719   else if (anArg == "hollow")
1720   {
1721     theStyle = Aspect_IS_HOLLOW;
1722   }
1723   else if (anArg == "solid")
1724   {
1725     theStyle = Aspect_IS_SOLID;
1726   }
1727   else if (anArg == "hatch")
1728   {
1729     theStyle = Aspect_IS_HATCH;
1730   }
1731   else if (anArg == "hiddenline"
1732         || anArg == "hidden-line"
1733         || anArg == "hidden_line")
1734   {
1735     theStyle = Aspect_IS_HIDDENLINE;
1736   }
1737   else if (anArg == "point")
1738   {
1739     theStyle = Aspect_IS_POINT;
1740   }
1741   else if (theArg.IsIntegerValue())
1742   {
1743     const Standard_Integer anIntStyle = theArg.IntegerValue();
1744     if (anIntStyle < Aspect_IS_EMPTY || anIntStyle > Aspect_IS_POINT)
1745     {
1746       return false;
1747     }
1748     theStyle = (Aspect_InteriorStyle)anIntStyle;
1749   }
1750   else
1751   {
1752     return false;
1753   }
1754   return true;
1755 }
1756
1757 //! Auxiliary structure for VAspects
1758 struct ViewerTest_AspectsChangeSet
1759 {
1760   Standard_Integer             ToSetVisibility;
1761   Standard_Integer             Visibility;
1762
1763   Standard_Integer             ToSetColor;
1764   Quantity_Color               Color;
1765
1766   Standard_Integer             ToSetLineWidth;
1767   Standard_Real                LineWidth;
1768
1769   Standard_Integer             ToSetTypeOfLine;
1770   Aspect_TypeOfLine            TypeOfLine;
1771
1772   Standard_Integer             ToSetTypeOfMarker;
1773   Aspect_TypeOfMarker          TypeOfMarker;
1774   Handle(Image_PixMap)         MarkerImage;
1775
1776   Standard_Integer             ToSetMarkerSize;
1777   Standard_Real                MarkerSize;
1778
1779   Standard_Integer             ToSetTransparency;
1780   Standard_Real                Transparency;
1781
1782   Standard_Integer             ToSetAlphaMode;
1783   Graphic3d_AlphaMode          AlphaMode;
1784   Standard_ShortReal           AlphaCutoff;
1785
1786   Standard_Integer             ToSetMaterial;
1787   Graphic3d_NameOfMaterial     Material;
1788   TCollection_AsciiString      MatName;
1789
1790   NCollection_Sequence<TopoDS_Shape> SubShapes;
1791
1792   Standard_Integer             ToSetShowFreeBoundary;
1793   Standard_Integer             ToSetFreeBoundaryWidth;
1794   Standard_Real                FreeBoundaryWidth;
1795   Standard_Integer             ToSetFreeBoundaryColor;
1796   Quantity_Color               FreeBoundaryColor;
1797
1798   Standard_Integer             ToEnableIsoOnTriangulation;
1799
1800   Standard_Integer             ToSetFaceBoundaryDraw;
1801   Standard_Integer             ToSetFaceBoundaryUpperContinuity;
1802   GeomAbs_Shape                FaceBoundaryUpperContinuity;
1803
1804   Standard_Integer             ToSetFaceBoundaryColor;
1805   Quantity_Color               FaceBoundaryColor;
1806
1807   Standard_Integer             ToSetFaceBoundaryWidth;
1808   Standard_Real                FaceBoundaryWidth;
1809
1810   Standard_Integer             ToSetTypeOfFaceBoundaryLine;
1811   Aspect_TypeOfLine            TypeOfFaceBoundaryLine;
1812
1813   Standard_Integer             ToSetMaxParamValue;
1814   Standard_Real                MaxParamValue;
1815
1816   Standard_Integer             ToSetSensitivity;
1817   Standard_Integer             SelectionMode;
1818   Standard_Integer             Sensitivity;
1819
1820   Standard_Integer             ToSetHatch;
1821   Standard_Integer             StdHatchStyle;
1822   TCollection_AsciiString      PathToHatchPattern;
1823
1824   Standard_Integer             ToSetShadingModel;
1825   Graphic3d_TypeOfShadingModel ShadingModel;
1826   TCollection_AsciiString      ShadingModelName;
1827
1828   Standard_Integer             ToSetInterior;
1829   Aspect_InteriorStyle         InteriorStyle;
1830
1831   Standard_Integer             ToSetDrawSilhouette;
1832
1833   Standard_Integer             ToSetDrawEdges;
1834   Standard_Integer             ToSetQuadEdges;
1835
1836   Standard_Integer             ToSetEdgeColor;
1837   Quantity_ColorRGBA           EdgeColor;
1838
1839   Standard_Integer             ToSetEdgeWidth;
1840   Standard_Real                EdgeWidth;
1841
1842   Standard_Integer             ToSetTypeOfEdge;
1843   Aspect_TypeOfLine            TypeOfEdge;
1844
1845   //! Empty constructor
1846   ViewerTest_AspectsChangeSet()
1847   : ToSetVisibility   (0),
1848     Visibility        (1),
1849     ToSetColor        (0),
1850     Color             (DEFAULT_COLOR),
1851     ToSetLineWidth    (0),
1852     LineWidth         (1.0),
1853     ToSetTypeOfLine   (0),
1854     TypeOfLine        (Aspect_TOL_SOLID),
1855     ToSetTypeOfMarker (0),
1856     TypeOfMarker      (Aspect_TOM_PLUS),
1857     ToSetMarkerSize   (0),
1858     MarkerSize        (1.0),
1859     ToSetTransparency (0),
1860     Transparency      (0.0),
1861     ToSetAlphaMode    (0),
1862     AlphaMode         (Graphic3d_AlphaMode_BlendAuto),
1863     AlphaCutoff       (0.5f),
1864     ToSetMaterial     (0),
1865     Material          (Graphic3d_NOM_DEFAULT),
1866     ToSetShowFreeBoundary      (0),
1867     ToSetFreeBoundaryWidth     (0),
1868     FreeBoundaryWidth          (1.0),
1869     ToSetFreeBoundaryColor     (0),
1870     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
1871     ToEnableIsoOnTriangulation (0),
1872     //
1873     ToSetFaceBoundaryDraw      (0),
1874     ToSetFaceBoundaryUpperContinuity (0),
1875     FaceBoundaryUpperContinuity(GeomAbs_CN),
1876     ToSetFaceBoundaryColor     (0),
1877     FaceBoundaryColor          (Quantity_NOC_BLACK),
1878     ToSetFaceBoundaryWidth     (0),
1879     FaceBoundaryWidth          (1.0f),
1880     ToSetTypeOfFaceBoundaryLine(0),
1881     TypeOfFaceBoundaryLine     (Aspect_TOL_SOLID),
1882     //
1883     ToSetMaxParamValue         (0),
1884     MaxParamValue              (500000),
1885     ToSetSensitivity           (0),
1886     SelectionMode              (-1),
1887     Sensitivity                (-1),
1888     ToSetHatch                 (0),
1889     StdHatchStyle              (-1),
1890     ToSetShadingModel          (0),
1891     ShadingModel               (Graphic3d_TOSM_DEFAULT),
1892     ToSetInterior              (0),
1893     InteriorStyle              (Aspect_IS_SOLID),
1894     ToSetDrawSilhouette (0),
1895     ToSetDrawEdges    (0),
1896     ToSetQuadEdges    (0),
1897     ToSetEdgeColor    (0),
1898     ToSetEdgeWidth    (0),
1899     EdgeWidth         (1.0),
1900     ToSetTypeOfEdge   (0),
1901     TypeOfEdge        (Aspect_TOL_SOLID)
1902     {}
1903
1904   //! @return true if no changes have been requested
1905   Standard_Boolean IsEmpty() const
1906   {
1907     return ToSetVisibility        == 0
1908         && ToSetLineWidth         == 0
1909         && ToSetTransparency      == 0
1910         && ToSetAlphaMode         == 0
1911         && ToSetColor             == 0
1912         && ToSetMaterial          == 0
1913         && ToSetShowFreeBoundary  == 0
1914         && ToSetFreeBoundaryColor == 0
1915         && ToSetFreeBoundaryWidth == 0
1916         && ToEnableIsoOnTriangulation == 0
1917         && ToSetFaceBoundaryDraw == 0
1918         && ToSetFaceBoundaryUpperContinuity == 0
1919         && ToSetFaceBoundaryColor == 0
1920         && ToSetFaceBoundaryWidth == 0
1921         && ToSetTypeOfFaceBoundaryLine == 0
1922         && ToSetMaxParamValue     == 0
1923         && ToSetSensitivity       == 0
1924         && ToSetHatch             == 0
1925         && ToSetShadingModel      == 0
1926         && ToSetInterior          == 0
1927         && ToSetDrawSilhouette    == 0
1928         && ToSetDrawEdges         == 0
1929         && ToSetQuadEdges         == 0
1930         && ToSetEdgeColor         == 0
1931         && ToSetEdgeWidth         == 0
1932         && ToSetTypeOfEdge        == 0;
1933   }
1934
1935   //! @return true if properties are valid
1936   Standard_Boolean Validate() const
1937   {
1938     Standard_Boolean isOk = Standard_True;
1939     if (Visibility != 0 && Visibility != 1)
1940     {
1941       std::cout << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")\n";
1942       isOk = Standard_False;
1943     }
1944     if (LineWidth <= 0.0
1945      || LineWidth >  10.0)
1946     {
1947       std::cout << "Error: the width should be within [1; 10] range (specified " << LineWidth << ")\n";
1948       isOk = Standard_False;
1949     }
1950     if (Transparency < 0.0
1951      || Transparency > 1.0)
1952     {
1953       std::cout << "Error: the transparency should be within [0; 1] range (specified " << Transparency << ")\n";
1954       isOk = Standard_False;
1955     }
1956     if (ToSetAlphaMode == 1
1957      && (AlphaCutoff <= 0.0f || AlphaCutoff >= 1.0f))
1958     {
1959       std::cout << "Error: alpha cutoff value should be within (0; 1) range (specified " << AlphaCutoff << ")\n";
1960       isOk = Standard_False;
1961     }
1962     if (ToSetMaterial == 1
1963      && Material == Graphic3d_NOM_DEFAULT)
1964     {
1965       std::cout << "Error: unknown material " << MatName << ".\n";
1966       isOk = Standard_False;
1967     }
1968     if (FreeBoundaryWidth <= 0.0
1969      || FreeBoundaryWidth >  10.0)
1970     {
1971       std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
1972       isOk = Standard_False;
1973     }
1974     if (MaxParamValue < 0.0)
1975     {
1976       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
1977       isOk = Standard_False;
1978     }
1979     if (Sensitivity <= 0 && ToSetSensitivity)
1980     {
1981       std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
1982       isOk = Standard_False;
1983     }
1984     if (ToSetHatch == 1 && StdHatchStyle < 0 && PathToHatchPattern == "")
1985     {
1986       std::cout << "Error: hatch style must be specified\n";
1987       isOk = Standard_False;
1988     }
1989     if (ToSetShadingModel == 1
1990     && (ShadingModel < Graphic3d_TOSM_DEFAULT || ShadingModel > Graphic3d_TOSM_FRAGMENT))
1991     {
1992       std::cout << "Error: unknown shading model " << ShadingModelName << ".\n";
1993       isOk = Standard_False;
1994     }
1995     return isOk;
1996   }
1997
1998   //! Apply aspects to specified drawer.
1999   bool Apply (const Handle(Prs3d_Drawer)& theDrawer)
2000   {
2001     bool toRecompute = false;
2002     const Handle(Prs3d_Drawer)& aDefDrawer = ViewerTest::GetAISContext()->DefaultDrawer();
2003     if (ToSetShowFreeBoundary != 0)
2004     {
2005       theDrawer->SetFreeBoundaryDraw (ToSetShowFreeBoundary == 1);
2006       toRecompute = true;
2007     }
2008     if (ToSetFreeBoundaryWidth != 0)
2009     {
2010       if (ToSetFreeBoundaryWidth != -1
2011        || theDrawer->HasOwnFreeBoundaryAspect())
2012       {
2013         if (!theDrawer->HasOwnFreeBoundaryAspect())
2014         {
2015           Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2016           *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
2017           theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2018           toRecompute = true;
2019         }
2020         theDrawer->FreeBoundaryAspect()->SetWidth (FreeBoundaryWidth);
2021       }
2022     }
2023     if (ToSetFreeBoundaryColor != 0)
2024     {
2025       Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2026       *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
2027       aBoundaryAspect->SetColor (FreeBoundaryColor);
2028       theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2029       toRecompute = true;
2030     }
2031     if (ToSetTypeOfLine != 0)
2032     {
2033       if (ToSetTypeOfLine != -1
2034        || theDrawer->HasOwnLineAspect()
2035        || theDrawer->HasOwnWireAspect()
2036        || theDrawer->HasOwnFreeBoundaryAspect()
2037        || theDrawer->HasOwnUnFreeBoundaryAspect()
2038        || theDrawer->HasOwnSeenLineAspect())
2039       {
2040         toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
2041         theDrawer->LineAspect()->SetTypeOfLine           (TypeOfLine);
2042         theDrawer->WireAspect()->SetTypeOfLine           (TypeOfLine);
2043         theDrawer->FreeBoundaryAspect()->SetTypeOfLine   (TypeOfLine);
2044         theDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (TypeOfLine);
2045         theDrawer->SeenLineAspect()->SetTypeOfLine       (TypeOfLine);
2046       }
2047     }
2048     if (ToSetTypeOfMarker != 0)
2049     {
2050       if (ToSetTypeOfMarker != -1
2051        || theDrawer->HasOwnPointAspect())
2052       {
2053         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
2054         theDrawer->PointAspect()->SetTypeOfMarker (TypeOfMarker);
2055         theDrawer->PointAspect()->Aspect()->SetMarkerImage (MarkerImage.IsNull() ? Handle(Graphic3d_MarkerImage)() : new Graphic3d_MarkerImage (MarkerImage));
2056       }
2057     }
2058     if (ToSetMarkerSize != 0)
2059     {
2060       if (ToSetMarkerSize != -1
2061        || theDrawer->HasOwnPointAspect())
2062       {
2063         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
2064         theDrawer->PointAspect()->SetScale (MarkerSize);
2065         toRecompute = true;
2066       }
2067     }
2068     if (ToSetMaxParamValue != 0)
2069     {
2070       if (ToSetMaxParamValue != -1
2071        || theDrawer->HasOwnMaximalParameterValue())
2072       {
2073         theDrawer->SetMaximalParameterValue (MaxParamValue);
2074         toRecompute = true;
2075       }
2076     }
2077     if (ToSetFaceBoundaryDraw != 0)
2078     {
2079       if (ToSetFaceBoundaryDraw != -1
2080        || theDrawer->HasOwnFaceBoundaryDraw())
2081       {
2082         toRecompute = true;
2083         theDrawer->SetFaceBoundaryDraw (ToSetFaceBoundaryDraw == 1);
2084       }
2085     }
2086     if (ToSetFaceBoundaryUpperContinuity != 0)
2087     {
2088       if (ToSetFaceBoundaryUpperContinuity != -1
2089        || theDrawer->HasOwnFaceBoundaryUpperContinuity())
2090       {
2091         toRecompute = true;
2092         if (ToSetFaceBoundaryUpperContinuity == -1)
2093         {
2094           theDrawer->UnsetFaceBoundaryUpperContinuity();
2095         }
2096         else
2097         {
2098           theDrawer->SetFaceBoundaryUpperContinuity (FaceBoundaryUpperContinuity);
2099         }
2100       }
2101     }
2102     if (ToSetFaceBoundaryColor != 0)
2103     {
2104       if (ToSetFaceBoundaryColor != -1
2105        || theDrawer->HasOwnFaceBoundaryAspect())
2106       {
2107         if (ToSetFaceBoundaryColor == -1)
2108         {
2109           toRecompute = true;
2110           theDrawer->SetFaceBoundaryAspect (Handle(Prs3d_LineAspect)());
2111         }
2112         else
2113         {
2114           toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2115           theDrawer->FaceBoundaryAspect()->SetColor (FaceBoundaryColor);
2116         }
2117       }
2118     }
2119     if (ToSetFaceBoundaryWidth != 0)
2120     {
2121       if (ToSetFaceBoundaryWidth != -1
2122        || theDrawer->HasOwnFaceBoundaryAspect())
2123       {
2124         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2125         theDrawer->FaceBoundaryAspect()->SetWidth (FaceBoundaryWidth);
2126       }
2127     }
2128     if (ToSetTypeOfFaceBoundaryLine != 0)
2129     {
2130       if (ToSetTypeOfFaceBoundaryLine != -1
2131        || theDrawer->HasOwnFaceBoundaryAspect())
2132       {
2133         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2134         theDrawer->FaceBoundaryAspect()->SetTypeOfLine (TypeOfFaceBoundaryLine);
2135       }
2136     }
2137     if (ToSetShadingModel != 0)
2138     {
2139       if (ToSetShadingModel != -1
2140        || theDrawer->HasOwnShadingAspect())
2141       {
2142         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2143         theDrawer->ShadingAspect()->Aspect()->SetShadingModel (ShadingModel);
2144       }
2145     }
2146     if (ToSetAlphaMode != 0)
2147     {
2148       if (ToSetAlphaMode != -1
2149        || theDrawer->HasOwnShadingAspect())
2150       {
2151         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2152         theDrawer->ShadingAspect()->Aspect()->SetAlphaMode (AlphaMode, AlphaCutoff);
2153       }
2154     }
2155     if (ToSetHatch != 0)
2156     {
2157       if (ToSetHatch != -1
2158       ||  theDrawer->HasOwnShadingAspect())
2159       {
2160         theDrawer->SetupOwnShadingAspect (aDefDrawer);
2161         Handle(Graphic3d_AspectFillArea3d) anAsp = theDrawer->ShadingAspect()->Aspect();
2162         if (ToSetHatch == -1)
2163         {
2164           anAsp->SetInteriorStyle (Aspect_IS_SOLID);
2165         }
2166         else
2167         {
2168           anAsp->SetInteriorStyle (Aspect_IS_HATCH);
2169           if (!PathToHatchPattern.IsEmpty())
2170           {
2171             Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
2172             if (anImage->Load (TCollection_AsciiString (PathToHatchPattern.ToCString())))
2173             {
2174               anAsp->SetHatchStyle (new Graphic3d_HatchStyle (anImage));
2175             }
2176             else
2177             {
2178               std::cout << "Error: cannot load the following image: " << PathToHatchPattern << "\n";
2179             }
2180           }
2181           else if (StdHatchStyle != -1)
2182           {
2183             anAsp->SetHatchStyle (new Graphic3d_HatchStyle ((Aspect_HatchStyle)StdHatchStyle));
2184           }
2185         }
2186         toRecompute = true;
2187       }
2188     }
2189     if (ToSetInterior != 0)
2190     {
2191       if (ToSetInterior != -1
2192        || theDrawer->HasOwnShadingAspect())
2193       {
2194         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2195         theDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (InteriorStyle);
2196         if (InteriorStyle == Aspect_IS_HATCH
2197          && theDrawer->ShadingAspect()->Aspect()->HatchStyle().IsNull())
2198         {
2199           theDrawer->ShadingAspect()->Aspect()->SetHatchStyle (Aspect_HS_VERTICAL);
2200         }
2201       }
2202     }
2203     if (ToSetDrawSilhouette != 0)
2204     {
2205       if (ToSetDrawSilhouette != -1
2206        || theDrawer->HasOwnShadingAspect())
2207       {
2208         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2209         theDrawer->ShadingAspect()->Aspect()->SetDrawSilhouette (ToSetDrawSilhouette == 1);
2210       }
2211     }
2212     if (ToSetDrawEdges != 0)
2213     {
2214       if (ToSetDrawEdges != -1
2215        || theDrawer->HasOwnShadingAspect())
2216       {
2217         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2218         theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetDrawEdges == 1);
2219       }
2220     }
2221     if (ToSetQuadEdges != 0)
2222     {
2223       if (ToSetQuadEdges != -1
2224           || theDrawer->HasOwnShadingAspect())
2225       {
2226         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2227         theDrawer->ShadingAspect()->Aspect()->SetSkipFirstEdge (ToSetQuadEdges == 1);
2228       }
2229     }
2230     if (ToSetEdgeWidth != 0)
2231     {
2232       if (ToSetEdgeWidth != -1
2233        || theDrawer->HasOwnShadingAspect())
2234       {
2235         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2236         theDrawer->ShadingAspect()->Aspect()->SetEdgeWidth (EdgeWidth);
2237       }
2238     }
2239     if (ToSetTypeOfEdge != 0)
2240     {
2241       if (ToSetTypeOfEdge != -1
2242        || theDrawer->HasOwnShadingAspect())
2243       {
2244         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2245         theDrawer->ShadingAspect()->Aspect()->SetEdgeLineType (TypeOfEdge);
2246         if (ToSetInterior == 0)
2247         {
2248           theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetTypeOfEdge == 1
2249                                                            && TypeOfEdge != Aspect_TOL_EMPTY);
2250         }
2251       }
2252     }
2253     if (ToSetEdgeColor != 0)
2254     {
2255       if (ToSetEdgeColor != -1
2256        || theDrawer->HasOwnShadingAspect())
2257       {
2258         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2259         if (ToSetEdgeColor == -1)
2260         {
2261           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (theDrawer->ShadingAspect()->Aspect()->InteriorColor());
2262         }
2263         else
2264         {
2265           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (EdgeColor);
2266         }
2267       }
2268     }
2269     return toRecompute;
2270   }
2271 };
2272
2273 //==============================================================================
2274 //function : VAspects
2275 //purpose  :
2276 //==============================================================================
2277 static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
2278                                   Standard_Integer  theArgNb,
2279                                   const char**      theArgVec)
2280 {
2281   TCollection_AsciiString aCmdName (theArgVec[0]);
2282   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2283   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2284   if (aCtx.IsNull())
2285   {
2286     std::cerr << "Error: no active view!\n";
2287     return 1;
2288   }
2289
2290   Standard_Integer anArgIter = 1;
2291   Standard_Boolean isDefaults = Standard_False;
2292   NCollection_Sequence<TCollection_AsciiString> aNames;
2293   for (; anArgIter < theArgNb; ++anArgIter)
2294   {
2295     TCollection_AsciiString anArg = theArgVec[anArgIter];
2296     if (anUpdateTool.parseRedrawMode (anArg))
2297     {
2298       continue;
2299     }
2300     else if (!anArg.IsEmpty()
2301            && anArg.Value (1) != '-')
2302     {
2303       aNames.Append (anArg);
2304     }
2305     else
2306     {
2307       if (anArg == "-defaults")
2308       {
2309         isDefaults = Standard_True;
2310         ++anArgIter;
2311       }
2312       break;
2313     }
2314   }
2315
2316   if (!aNames.IsEmpty() && isDefaults)
2317   {
2318     std::cout << "Error: wrong syntax. If -defaults is used there should not be any objects' names!\n";
2319     return 1;
2320   }
2321
2322   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
2323   aChanges.Append (ViewerTest_AspectsChangeSet());
2324   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
2325
2326   // parse syntax of legacy commands
2327   bool toParseAliasArgs = false;
2328   if (aCmdName == "vsetwidth")
2329   {
2330     if (aNames.IsEmpty()
2331     || !aNames.Last().IsRealValue())
2332     {
2333       std::cout << "Error: not enough arguments!\n";
2334       return 1;
2335     }
2336     aChangeSet->ToSetLineWidth = 1;
2337     aChangeSet->LineWidth = aNames.Last().RealValue();
2338     aNames.Remove (aNames.Length());
2339   }
2340   else if (aCmdName == "vunsetwidth")
2341   {
2342     aChangeSet->ToSetLineWidth = -1;
2343   }
2344   else if (aCmdName == "vsetcolor")
2345   {
2346     if (aNames.IsEmpty())
2347     {
2348       std::cout << "Error: not enough arguments!\n";
2349       return 1;
2350     }
2351     aChangeSet->ToSetColor = 1;
2352
2353     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2354     Standard_Boolean     isOk   = Standard_False;
2355     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
2356     {
2357       aChangeSet->Color = aColor;
2358       aNames.Remove (aNames.Length());
2359       isOk = Standard_True;
2360     }
2361     else if (aNames.Length() >= 3)
2362     {
2363       const char* anArgVec[3] =
2364       {
2365         aNames.Value (aNames.Upper() - 2).ToCString(),
2366         aNames.Value (aNames.Upper() - 1).ToCString(),
2367         aNames.Value (aNames.Upper() - 0).ToCString(),
2368       };
2369
2370       Standard_Integer aNbParsed = ViewerTest::ParseColor (3, anArgVec, aChangeSet->Color);
2371       isOk = aNbParsed == 3;
2372       aNames.Remove (aNames.Length());
2373       aNames.Remove (aNames.Length());
2374       aNames.Remove (aNames.Length());
2375     }
2376     if (!isOk)
2377     {
2378       std::cout << "Error: not enough arguments!\n";
2379       return 1;
2380     }
2381   }
2382   else if (aCmdName == "vunsetcolor")
2383   {
2384     aChangeSet->ToSetColor = -1;
2385   }
2386   else if (aCmdName == "vsettransparency")
2387   {
2388     if (aNames.IsEmpty()
2389     || !aNames.Last().IsRealValue())
2390     {
2391       std::cout << "Error: not enough arguments!\n";
2392       return 1;
2393     }
2394     aChangeSet->ToSetTransparency = 1;
2395     aChangeSet->Transparency  = aNames.Last().RealValue();
2396     aNames.Remove (aNames.Length());
2397   }
2398   else if (aCmdName == "vunsettransparency")
2399   {
2400     aChangeSet->ToSetTransparency = -1;
2401   }
2402   else if (aCmdName == "vsetmaterial")
2403   {
2404     if (aNames.IsEmpty())
2405     {
2406       std::cout << "Error: not enough arguments!\n";
2407       return 1;
2408     }
2409     aChangeSet->ToSetMaterial = 1;
2410     aChangeSet->MatName  = aNames.Last();
2411     aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
2412     aNames.Remove (aNames.Length());
2413   }
2414   else if (aCmdName == "vunsetmaterial")
2415   {
2416     aChangeSet->ToSetMaterial = -1;
2417   }
2418   else if (aCmdName == "vsetinteriorstyle")
2419   {
2420     if (aNames.IsEmpty()
2421     || !aNames.Last().IsRealValue())
2422     {
2423       std::cout << "Error: not enough arguments!\n";
2424       return 1;
2425     }
2426     aChangeSet->ToSetInterior = 1;
2427     if (!parseInteriorStyle (aNames.Last(), aChangeSet->InteriorStyle))
2428     {
2429       std::cout << "Error: wrong syntax at " << aNames.Last() << "\n";
2430       return 1;
2431     }
2432     aNames.Remove (aNames.Length());
2433   }
2434   else if (aCmdName == "vsetedgetype")
2435   {
2436     aChangeSet->ToSetDrawEdges = 1;
2437     toParseAliasArgs = true;
2438   }
2439   else if (aCmdName == "vunsetedgetype")
2440   {
2441     aChangeSet->ToSetDrawEdges  = -1;
2442     aChangeSet->ToSetEdgeColor  = -1;
2443     aChangeSet->ToSetTypeOfEdge = -1;
2444     aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
2445   }
2446   else if (aCmdName == "vshowfaceboundary")
2447   {
2448     aChangeSet->ToSetFaceBoundaryDraw = 1;
2449     toParseAliasArgs = true;
2450     if (aNames.Size() >= 2
2451      && aNames.Value (2).IsIntegerValue())
2452     {
2453       if (aNames.Size() == 7)
2454       {
2455         if (ViewerTest::ParseLineType (aNames.Value (7).ToCString(), aChangeSet->TypeOfFaceBoundaryLine))
2456         {
2457           aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2458           aNames.Remove (7);
2459         }
2460       }
2461       if (aNames.Size() == 6
2462        && aNames.Value (6).IsRealValue())
2463       {
2464         aChangeSet->ToSetFaceBoundaryWidth = 1;
2465         aChangeSet->FaceBoundaryWidth = aNames.Value (6).RealValue();
2466         aNames.Remove (6);
2467       }
2468       if (aNames.Size() == 5
2469        && aNames.Value (3).IsIntegerValue()
2470        && aNames.Value (4).IsIntegerValue()
2471        && aNames.Value (5).IsIntegerValue())
2472       {
2473         aChangeSet->ToSetFaceBoundaryColor = 1;
2474         aChangeSet->FaceBoundaryColor = Quantity_Color (aNames.Value (3).IntegerValue() / 255.0,
2475                                                         aNames.Value (4).IntegerValue() / 255.0,
2476                                                         aNames.Value (5).IntegerValue() / 255.0,
2477                                                         Quantity_TOC_RGB);
2478         aNames.Remove (5);
2479         aNames.Remove (4);
2480         aNames.Remove (3);
2481       }
2482       if (aNames.Size() == 2)
2483       {
2484         toParseAliasArgs = false;
2485         aChangeSet->ToSetFaceBoundaryDraw = aNames.Value (2).IntegerValue() == 1 ? 1 : -1;
2486         aNames.Remove (2);
2487       }
2488     }
2489   }
2490   else if (anArgIter >= theArgNb)
2491   {
2492     std::cout << "Error: not enough arguments!\n";
2493     return 1;
2494   }
2495
2496   if (!aChangeSet->IsEmpty()
2497    && !toParseAliasArgs)
2498   {
2499     anArgIter = theArgNb;
2500   }
2501   for (; anArgIter < theArgNb; ++anArgIter)
2502   {
2503     TCollection_AsciiString anArg = theArgVec[anArgIter];
2504     anArg.LowerCase();
2505     if (anArg == "-setwidth"
2506      || anArg == "-width"
2507      || anArg == "-setlinewidth"
2508      || anArg == "-linewidth"
2509      || anArg == "-setedgewidth"
2510      || anArg == "-setedgeswidth"
2511      || anArg == "-edgewidth"
2512      || anArg == "-edgeswidth"
2513      || anArg == "-setfaceboundarywidth"
2514      || anArg == "-setboundarywidth"
2515      || anArg == "-faceboundarywidth"
2516      || anArg == "-boundarywidth")
2517     {
2518       if (++anArgIter >= theArgNb)
2519       {
2520         std::cout << "Error: wrong syntax at " << anArg << "\n";
2521         return 1;
2522       }
2523
2524       const Standard_Real aWidth = Draw::Atof (theArgVec[anArgIter]);
2525       if (anArg == "-setedgewidth"
2526        || anArg == "-setedgeswidth"
2527        || anArg == "-edgewidth"
2528        || anArg == "-edgeswidth"
2529        || aCmdName == "vsetedgetype")
2530       {
2531         aChangeSet->ToSetEdgeWidth = 1;
2532         aChangeSet->EdgeWidth = aWidth;
2533       }
2534       else if (anArg == "-setfaceboundarywidth"
2535             || anArg == "-setboundarywidth"
2536             || anArg == "-faceboundarywidth"
2537             || anArg == "-boundarywidth"
2538             || aCmdName == "vshowfaceboundary")
2539       {
2540         aChangeSet->ToSetFaceBoundaryWidth = 1;
2541         aChangeSet->FaceBoundaryWidth = aWidth;
2542       }
2543       else
2544       {
2545         aChangeSet->ToSetLineWidth = 1;
2546         aChangeSet->LineWidth = aWidth;
2547       }
2548     }
2549     else if (anArg == "-unsetwidth"
2550           || anArg == "-unsetlinewidth"
2551           || anArg == "-unsetedgewidth")
2552     {
2553       if (anArg == "-unsetedgewidth")
2554       {
2555         aChangeSet->ToSetEdgeWidth = -1;
2556         aChangeSet->EdgeWidth = 1.0;
2557       }
2558       else
2559       {
2560         aChangeSet->ToSetLineWidth = -1;
2561         aChangeSet->LineWidth = 1.0;
2562       }
2563     }
2564     else if (anArg == "-settransp"
2565           || anArg == "-settransparency"
2566           || anArg == "-transparency"
2567           || anArg == "-transp")
2568     {
2569       if (++anArgIter >= theArgNb)
2570       {
2571         std::cout << "Error: wrong syntax at " << anArg << "\n";
2572         return 1;
2573       }
2574       aChangeSet->ToSetTransparency = 1;
2575       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
2576       if (aChangeSet->Transparency >= 0.0
2577        && aChangeSet->Transparency <= Precision::Confusion())
2578       {
2579         aChangeSet->ToSetTransparency = -1;
2580         aChangeSet->Transparency = 0.0;
2581       }
2582     }
2583     else if (anArg == "-setalphamode"
2584           || anArg == "-alphamode")
2585     {
2586       if (++anArgIter >= theArgNb)
2587       {
2588         std::cout << "Error: wrong syntax at " << anArg << "\n";
2589         return 1;
2590       }
2591       aChangeSet->ToSetAlphaMode = 1;
2592       aChangeSet->AlphaCutoff = 0.5f;
2593       {
2594         TCollection_AsciiString aParam (theArgVec[anArgIter]);
2595         aParam.LowerCase();
2596         if (aParam == "opaque")
2597         {
2598           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Opaque;
2599         }
2600         else if (aParam == "mask")
2601         {
2602           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Mask;
2603         }
2604         else if (aParam == "blend")
2605         {
2606           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
2607         }
2608         else if (aParam == "blendauto"
2609               || aParam == "auto")
2610         {
2611           aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2612         }
2613         else
2614         {
2615           std::cout << "Error: wrong syntax at " << aParam << "\n";
2616           return 1;
2617         }
2618       }
2619
2620       if (anArgIter + 1 < theArgNb
2621        && theArgVec[anArgIter + 1][0] != '-')
2622       {
2623         TCollection_AsciiString aParam2 (theArgVec[anArgIter + 1]);
2624         if (aParam2.IsRealValue())
2625         {
2626           aChangeSet->AlphaCutoff = (float )aParam2.RealValue();
2627           ++anArgIter;
2628         }
2629       }
2630     }
2631     else if (anArg == "-setvis"
2632           || anArg == "-setvisibility"
2633           || anArg == "-visibility")
2634     {
2635       if (++anArgIter >= theArgNb)
2636       {
2637         std::cout << "Error: wrong syntax at " << anArg << "\n";
2638         return 1;
2639       }
2640
2641       aChangeSet->ToSetVisibility = 1;
2642       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
2643     }
2644     else if (anArg == "-setalpha"
2645           || anArg == "-alpha")
2646     {
2647       if (++anArgIter >= theArgNb)
2648       {
2649         std::cout << "Error: wrong syntax at " << anArg << "\n";
2650         return 1;
2651       }
2652       aChangeSet->ToSetTransparency = 1;
2653       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
2654       if (aChangeSet->Transparency < 0.0
2655        || aChangeSet->Transparency > 1.0)
2656       {
2657         std::cout << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")\n";
2658         return 1;
2659       }
2660       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
2661       if (aChangeSet->Transparency >= 0.0
2662        && aChangeSet->Transparency <= Precision::Confusion())
2663       {
2664         aChangeSet->ToSetTransparency = -1;
2665         aChangeSet->Transparency = 0.0;
2666       }
2667     }
2668     else if (anArg == "-unsettransp"
2669           || anArg == "-unsettransparency"
2670           || anArg == "-unsetalpha"
2671           || anArg == "-opaque")
2672     {
2673       aChangeSet->ToSetTransparency = -1;
2674       aChangeSet->Transparency = 0.0;
2675     }
2676     else if (anArg == "-setcolor"
2677           || anArg == "-color"
2678           || anArg == "-setfaceboundarycolor"
2679           || anArg == "-setboundarycolor"
2680           || anArg == "-faceboundarycolor"
2681           || anArg == "-boundarycolor")
2682     {
2683       Quantity_Color aColor;
2684       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2685                                                            theArgVec + anArgIter + 1,
2686                                                            aColor);
2687       if (aNbParsed == 0)
2688       {
2689         std::cout << "Syntax error at '" << anArg << "'\n";
2690         return 1;
2691       }
2692       anArgIter += aNbParsed;
2693       if (aCmdName == "vsetedgetype")
2694       {
2695         aChangeSet->ToSetEdgeColor = 1;
2696         aChangeSet->EdgeColor = Quantity_ColorRGBA (aColor);
2697       }
2698       else if (aCmdName == "vshowfaceboundary"
2699             || anArg == "-setfaceboundarycolor"
2700             || anArg == "-setboundarycolor"
2701             || anArg == "-faceboundarycolor"
2702             || anArg == "-boundarycolor")
2703       {
2704         aChangeSet->ToSetFaceBoundaryColor = 1;
2705         aChangeSet->FaceBoundaryColor = aColor;
2706       }
2707       else
2708       {
2709         aChangeSet->ToSetColor = 1;
2710         aChangeSet->Color = aColor;
2711       }
2712     }
2713     else if (anArg == "-setlinetype"
2714           || anArg == "-linetype"
2715           || anArg == "-setedgetype"
2716           || anArg == "-setedgestype"
2717           || anArg == "-edgetype"
2718           || anArg == "-edgestype"
2719           || anArg == "-setfaceboundarystyle"
2720           || anArg == "-faceboundarystyle"
2721           || anArg == "-boundarystyle"
2722           || anArg == "-setfaceboundarytype"
2723           || anArg == "-faceboundarytype"
2724           || anArg == "-setboundarytype"
2725           || anArg == "-boundarytype"
2726           || anArg == "-type")
2727     {
2728       if (++anArgIter >= theArgNb)
2729       {
2730         std::cout << "Error: wrong syntax at " << anArg << "\n";
2731         return 1;
2732       }
2733       Aspect_TypeOfLine aLineType = Aspect_TOL_EMPTY;
2734       if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType))
2735       {
2736         std::cout << "Error: wrong syntax at " << anArg << "\n";
2737         return 1;
2738       }
2739       if (anArg == "-setedgetype"
2740        || anArg == "-setedgestype"
2741        || anArg == "-edgetype"
2742        || anArg == "-edgestype"
2743        || aCmdName == "vsetedgetype")
2744       {
2745         aChangeSet->TypeOfEdge = aLineType;
2746         aChangeSet->ToSetTypeOfEdge = 1;
2747       }
2748       else if (anArg == "-setfaceboundarystyle"
2749             || anArg == "-faceboundarystyle"
2750             || anArg == "-boundarystyle"
2751             || anArg == "-setfaceboundarytype"
2752             || anArg == "-faceboundarytype"
2753             || anArg == "-setboundarytype"
2754             || anArg == "-boundarytype"
2755             || aCmdName == "vshowfaceboundary")
2756       {
2757         aChangeSet->TypeOfFaceBoundaryLine = aLineType;
2758         aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2759       }
2760       else
2761       {
2762         aChangeSet->TypeOfLine = aLineType;
2763         aChangeSet->ToSetTypeOfLine = 1;
2764       }
2765     }
2766     else if (anArg == "-unsetlinetype"
2767           || anArg == "-unsetedgetype"
2768           || anArg == "-unsetedgestype")
2769     {
2770       if (anArg == "-unsetedgetype"
2771        || anArg == "-unsetedgestype")
2772       {
2773         aChangeSet->ToSetTypeOfEdge = -1;
2774       }
2775       else
2776       {
2777         aChangeSet->ToSetTypeOfLine = -1;
2778       }
2779     }
2780     else if (anArg == "-setmarkertype"
2781           || anArg == "-markertype"
2782           || anArg == "-setpointtype"
2783           || anArg == "-pointtype")
2784     {
2785       if (++anArgIter >= theArgNb)
2786       {
2787         std::cout << "Error: wrong syntax at " << anArg << "\n";
2788         return 1;
2789       }
2790       if (!ViewerTest::ParseMarkerType (theArgVec[anArgIter], aChangeSet->TypeOfMarker, aChangeSet->MarkerImage))
2791       {
2792         std::cout << "Error: wrong syntax at " << anArg << "\n";
2793         return 1;
2794       }
2795
2796       aChangeSet->ToSetTypeOfMarker = 1;
2797     }
2798     else if (anArg == "-unsetmarkertype"
2799           || anArg == "-unsetpointtype")
2800     {
2801       aChangeSet->ToSetTypeOfMarker = -1;
2802     }
2803     else if (anArg == "-setmarkersize"
2804           || anArg == "-markersize"
2805           || anArg == "-setpointsize"
2806           || anArg == "-pointsize")
2807     {
2808       if (++anArgIter >= theArgNb)
2809       {
2810         std::cout << "Error: wrong syntax at " << anArg << "\n";
2811         return 1;
2812       }
2813       aChangeSet->ToSetMarkerSize = 1;
2814       aChangeSet->MarkerSize = Draw::Atof (theArgVec[anArgIter]);
2815     }
2816     else if (anArg == "-unsetmarkersize"
2817           || anArg == "-unsetpointsize")
2818     {
2819       aChangeSet->ToSetMarkerSize = -1;
2820       aChangeSet->MarkerSize = 1.0;
2821     }
2822     else if (anArg == "-unsetcolor")
2823     {
2824       aChangeSet->ToSetColor = -1;
2825       aChangeSet->Color = DEFAULT_COLOR;
2826     }
2827     else if (anArg == "-setmat"
2828           || anArg == "-mat"
2829           || anArg == "-setmaterial"
2830           || anArg == "-material")
2831     {
2832       if (++anArgIter >= theArgNb)
2833       {
2834         std::cout << "Error: wrong syntax at " << anArg << "\n";
2835         return 1;
2836       }
2837       aChangeSet->ToSetMaterial = 1;
2838       aChangeSet->MatName  = theArgVec[anArgIter];
2839       aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
2840     }
2841     else if (anArg == "-unsetmat"
2842           || anArg == "-unsetmaterial")
2843     {
2844       aChangeSet->ToSetMaterial = -1;
2845       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2846     }
2847     else if (anArg == "-subshape"
2848           || anArg == "-subshapes")
2849     {
2850       if (isDefaults)
2851       {
2852         std::cout << "Error: wrong syntax. -subshapes can not be used together with -defaults call!\n";
2853         return 1;
2854       }
2855
2856       if (aNames.IsEmpty())
2857       {
2858         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
2859         return 1;
2860       }
2861
2862       aChanges.Append (ViewerTest_AspectsChangeSet());
2863       aChangeSet = &aChanges.ChangeLast();
2864
2865       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
2866       {
2867         Standard_CString aSubShapeName = theArgVec[anArgIter];
2868         if (*aSubShapeName == '-')
2869         {
2870           --anArgIter;
2871           break;
2872         }
2873
2874         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
2875         if (aSubShape.IsNull())
2876         {
2877           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
2878           return 1;
2879         }
2880         aChangeSet->SubShapes.Append (aSubShape);
2881       }
2882
2883       if (aChangeSet->SubShapes.IsEmpty())
2884       {
2885         std::cerr << "Error: empty list is specified after -subshapes!\n";
2886         return 1;
2887       }
2888     }
2889     else if (anArg == "-setfreeboundary"
2890           || anArg == "-freeboundary"
2891           || anArg == "-setfb"
2892           || anArg == "-fb")
2893     {
2894       bool toEnable = true;
2895       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2896       {
2897         std::cout << "Error: wrong syntax at " << anArg << "\n";
2898         return 1;
2899       }
2900       ++anArgIter;
2901       aChangeSet->ToSetShowFreeBoundary = toEnable ? 1 : -1;
2902     }
2903     else if (anArg == "-setfreeboundarywidth"
2904           || anArg == "-freeboundarywidth"
2905           || anArg == "-setfbwidth"
2906           || anArg == "-fbwidth")
2907     {
2908       if (++anArgIter >= theArgNb)
2909       {
2910         std::cout << "Error: wrong syntax at " << anArg << "\n";
2911         return 1;
2912       }
2913       aChangeSet->ToSetFreeBoundaryWidth = 1;
2914       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2915     }
2916     else if (anArg == "-unsetfreeboundarywidth"
2917           || anArg == "-unsetfbwidth")
2918     {
2919       aChangeSet->ToSetFreeBoundaryWidth = -1;
2920       aChangeSet->FreeBoundaryWidth = 1.0;
2921     }
2922     else if (anArg == "-setfreeboundarycolor"
2923           || anArg == "-freeboundarycolor"
2924           || anArg == "-setfbcolor"
2925           || anArg == "-fbcolor")
2926     {
2927       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2928                                                            theArgVec + anArgIter + 1,
2929                                                            aChangeSet->FreeBoundaryColor);
2930       if (aNbParsed == 0)
2931       {
2932         std::cout << "Syntax error at '" << anArg << "'\n";
2933         return 1;
2934       }
2935       anArgIter += aNbParsed;
2936       aChangeSet->ToSetFreeBoundaryColor = 1;
2937     }
2938     else if (anArg == "-unsetfreeboundarycolor"
2939           || anArg == "-unsetfbcolor")
2940     {
2941       aChangeSet->ToSetFreeBoundaryColor = -1;
2942       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2943     }
2944     else if (anArg == "-setisoontriangulation"
2945           || anArg == "-isoontriangulation"
2946           || anArg == "-setisoontriang"
2947           || anArg == "-isoontriang")
2948     {
2949       bool toEnable = true;
2950       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2951       {
2952         std::cout << "Error: wrong syntax at " << anArg << "\n";
2953         return 1;
2954       }
2955       ++anArgIter;
2956       aChangeSet->ToEnableIsoOnTriangulation = toEnable ? 1 : -1;
2957     }
2958     else if (anArg == "-setfaceboundarydraw"
2959           || anArg == "-setdrawfaceboundary"
2960           || anArg == "-setdrawfaceboundaries"
2961           || anArg == "-setshowfaceboundary"
2962           || anArg == "-setshowfaceboundaries"
2963           || anArg == "-setdrawfaceedges"
2964           || anArg == "-faceboundarydraw"
2965           || anArg == "-drawfaceboundary"
2966           || anArg == "-drawfaceboundaries"
2967           || anArg == "-showfaceboundary"
2968           || anArg == "-showfaceboundaries"
2969           || anArg == "-drawfaceedges"
2970           || anArg == "-faceboundary"
2971           || anArg == "-faceboundaries"
2972           || anArg == "-faceedges")
2973     {
2974       bool toEnable = true;
2975       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2976       {
2977         std::cout << "Error: wrong syntax at " << anArg << "\n";
2978         return 1;
2979       }
2980       ++anArgIter;
2981       aChangeSet->ToSetFaceBoundaryDraw = toEnable ? 1 : -1;
2982     }
2983     else if (anArg == "-unsetfaceboundary"
2984           || anArg == "-unsetboundary")
2985     {
2986       aChangeSet->ToSetFaceBoundaryDraw  = -1;
2987       aChangeSet->ToSetFaceBoundaryColor = -1;
2988     }
2989     else if (anArg == "-setmostcontinuity"
2990           || anArg == "-mostcontinuity")
2991     {
2992       TCollection_AsciiString aClassArg (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "");
2993       aClassArg.LowerCase();
2994       GeomAbs_Shape aClass = GeomAbs_CN;
2995       if (aClassArg == "c0"
2996        || aClassArg == "0")
2997       {
2998         aClass = GeomAbs_C0;
2999       }
3000       else if (aClassArg == "c1"
3001             || aClassArg == "1")
3002       {
3003         aClass = GeomAbs_C1;
3004       }
3005       else if (aClassArg == "c2"
3006             || aClassArg == "2")
3007       {
3008         aClass = GeomAbs_C2;
3009       }
3010       else if (aClassArg == "c3"
3011             || aClassArg == "3")
3012       {
3013         aClass = GeomAbs_C3;
3014       }
3015       else if (aClassArg == "cn"
3016             || aClassArg == "n")
3017       {
3018         aClass = GeomAbs_CN;
3019       }
3020       else
3021       {
3022         std::cout << "Syntax error at '" << anArg << "'\n";
3023         return 1;
3024       }
3025
3026       ++anArgIter;
3027       aChangeSet->ToSetFaceBoundaryUpperContinuity = 1;
3028       aChangeSet->FaceBoundaryUpperContinuity = aClass;
3029     }
3030     else if (anArg == "-setmaxparamvalue"
3031           || anArg == "-maxparamvalue")
3032     {
3033       if (++anArgIter >= theArgNb)
3034       {
3035         std::cout << "Error: wrong syntax at " << anArg << "\n";
3036         return 1;
3037       }
3038       aChangeSet->ToSetMaxParamValue = 1;
3039       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
3040     }
3041     else if (anArg == "-setsensitivity"
3042           || anArg == "-sensitivity")
3043     {
3044       if (isDefaults)
3045       {
3046         std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
3047         return 1;
3048       }
3049
3050       if (aNames.IsEmpty())
3051       {
3052         std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
3053         return 1;
3054       }
3055
3056       if (anArgIter + 2 >= theArgNb)
3057       {
3058         std::cout << "Error: wrong syntax at " << anArg << "\n";
3059         return 1;
3060       }
3061       aChangeSet->ToSetSensitivity = 1;
3062       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
3063       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
3064     }
3065     else if (anArg == "-sethatch"
3066           || anArg == "-hatch")
3067     {
3068       if (isDefaults)
3069       {
3070         std::cout << "Error: wrong syntax. -setHatch can not be used together with -defaults call!\n";
3071         return 1;
3072       }
3073
3074       if (aNames.IsEmpty())
3075       {
3076         std::cout << "Error: object should be specified explicitly when -setHatch is used!\n";
3077         return 1;
3078       }
3079
3080       aChangeSet->ToSetHatch = 1;
3081       TCollection_AsciiString anArgHatch (theArgVec[++anArgIter]);
3082       if (anArgHatch.Length() <= 2)
3083       {
3084         const Standard_Integer anIntStyle = Draw::Atoi (anArgHatch.ToCString());
3085         if (anIntStyle < 0
3086          || anIntStyle >= Aspect_HS_NB)
3087         {
3088           std::cout << "Error: hatch style is out of range [0, " << (Aspect_HS_NB - 1) << "]!\n";
3089           return 1;
3090         }
3091         aChangeSet->StdHatchStyle = anIntStyle;
3092       }
3093       else
3094       {
3095         aChangeSet->PathToHatchPattern = anArgHatch;
3096       }
3097     }
3098     else if (anArg == "-setshadingmodel"
3099           || anArg == "-setshading"
3100           || anArg == "-shadingmodel"
3101           || anArg == "-shading")
3102     {
3103       if (++anArgIter >= theArgNb)
3104       {
3105         std::cout << "Error: wrong syntax at " << anArg << "\n";
3106         return 1;
3107       }
3108       aChangeSet->ToSetShadingModel = 1;
3109       aChangeSet->ShadingModelName  = theArgVec[anArgIter];
3110       if (!ViewerTest::ParseShadingModel (theArgVec[anArgIter], aChangeSet->ShadingModel))
3111       {
3112         std::cout << "Error: wrong syntax at " << anArg << "\n";
3113         return 1;
3114       }
3115     }
3116     else if (anArg == "-unsetshadingmodel")
3117     {
3118       aChangeSet->ToSetShadingModel = -1;
3119       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
3120     }
3121     else if (anArg == "-setinterior"
3122           || anArg == "-setinteriorstyle"
3123           || anArg == "-interior"
3124           || anArg == "-interiorstyle")
3125     {
3126       if (++anArgIter >= theArgNb)
3127       {
3128         std::cout << "Error: wrong syntax at " << anArg << "\n";
3129         return 1;
3130       }
3131       aChangeSet->ToSetInterior = 1;
3132       if (!parseInteriorStyle (theArgVec[anArgIter], aChangeSet->InteriorStyle))
3133       {
3134         std::cout << "Error: wrong syntax at " << anArg << "\n";
3135         return 1;
3136       }
3137     }
3138     else if (anArg == "-unsetinterior")
3139     {
3140       aChangeSet->ToSetInterior = -1;
3141       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
3142     }
3143     else if (anArg == "-setdrawoutline"
3144           || anArg == "-setdrawsilhouette"
3145           || anArg == "-setoutline"
3146           || anArg == "-setsilhouette"
3147           || anArg == "-outline"
3148           || anArg == "-outlined"
3149           || anArg == "-silhouette")
3150     {
3151       bool toDrawOutline = true;
3152       if (anArgIter + 1 < theArgNb
3153        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toDrawOutline))
3154       {
3155         ++anArgIter;
3156       }
3157       aChangeSet->ToSetDrawSilhouette = toDrawOutline ? 1 : -1;
3158     }
3159     else if (anArg == "-setdrawedges"
3160           || anArg == "-setdrawedge"
3161           || anArg == "-drawedges"
3162           || anArg == "-drawedge"
3163           || anArg == "-edges")
3164     {
3165       bool toDrawEdges = true;
3166       if (anArgIter + 1 < theArgNb
3167        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toDrawEdges))
3168       {
3169         ++anArgIter;
3170       }
3171       aChangeSet->ToSetDrawEdges = toDrawEdges ? 1 : -1;
3172     }
3173     else if (anArg == "-setquadedges"
3174           || anArg == "-setquads"
3175           || anArg == "-quads"
3176           || anArg == "-skipfirstedge")
3177     {
3178       bool isQuadMode = true;
3179       if (anArgIter + 1 < theArgNb
3180        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isQuadMode))
3181       {
3182         ++anArgIter;
3183       }
3184       aChangeSet->ToSetQuadEdges = isQuadMode ? 1 : -1;
3185     }
3186     else if (anArg == "-setedgecolor"
3187           || anArg == "-setedgescolor"
3188           || anArg == "-edgecolor"
3189           || anArg == "-edgescolor")
3190     {
3191       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3192                                                            theArgVec + anArgIter + 1,
3193                                                            aChangeSet->EdgeColor);
3194       if (aNbParsed == 0)
3195       {
3196         std::cout << "Syntax error at '" << anArg << "'\n";
3197         return 1;
3198       }
3199       anArgIter += aNbParsed;
3200       aChangeSet->ToSetEdgeColor = 1;
3201     }
3202     else if (anArg == "-unset")
3203     {
3204       aChangeSet->ToSetVisibility = 1;
3205       aChangeSet->Visibility = 1;
3206       aChangeSet->ToSetLineWidth = -1;
3207       aChangeSet->LineWidth = 1.0;
3208       aChangeSet->ToSetTypeOfLine = -1;
3209       aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
3210       aChangeSet->ToSetTypeOfMarker = -1;
3211       aChangeSet->TypeOfMarker = Aspect_TOM_PLUS;
3212       aChangeSet->ToSetMarkerSize = -1;
3213       aChangeSet->MarkerSize = 1.0;
3214       aChangeSet->ToSetTransparency = -1;
3215       aChangeSet->Transparency = 0.0;
3216       aChangeSet->ToSetAlphaMode = -1;
3217       aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
3218       aChangeSet->AlphaCutoff = 0.5f;
3219       aChangeSet->ToSetColor = -1;
3220       aChangeSet->Color = DEFAULT_COLOR;
3221       aChangeSet->ToSetMaterial = -1;
3222       aChangeSet->Material = Graphic3d_NOM_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
3258     {
3259       std::cout << "Error: wrong syntax at " << anArg << "\n";
3260       return 1;
3261     }
3262   }
3263
3264   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3265        aChangesIter.More(); aChangesIter.Next())
3266   {
3267     if (!aChangesIter.Value().Validate())
3268     {
3269       return 1;
3270     }
3271   }
3272
3273   // special case for -defaults parameter.
3274   // all changed values will be set to DefaultDrawer.
3275   if (isDefaults)
3276   {
3277     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
3278     aChangeSet->Apply (aDrawer);
3279     if (aChangeSet->ToSetLineWidth != 0)
3280     {
3281       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
3282       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
3283       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
3284       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
3285     }
3286     if (aChangeSet->ToSetColor != 0)
3287     {
3288       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
3289       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
3290       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
3291       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
3292       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
3293       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
3294     }
3295     if (aChangeSet->ToSetTransparency != 0)
3296     {
3297       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
3298     }
3299     if (aChangeSet->ToSetMaterial != 0)
3300     {
3301       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
3302     }
3303     if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3304     {
3305       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
3306     }
3307
3308     // redisplay all objects in context
3309     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3310     {
3311       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
3312       if (!aPrs.IsNull())
3313       {
3314         aCtx->Redisplay (aPrs, Standard_False);
3315       }
3316     }
3317     return 0;
3318   }
3319
3320   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3321   {
3322     const TCollection_AsciiString& aName = aPrsIter.CurrentName();
3323     Handle(AIS_InteractiveObject)  aPrs  = aPrsIter.Current();
3324     if (aPrs.IsNull())
3325     {
3326       return 1;
3327     }
3328
3329     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
3330     Handle(AIS_ColoredShape) aColoredPrs;
3331     Standard_Boolean toDisplay = Standard_False;
3332     Standard_Boolean toRedisplay = Standard_False;
3333     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
3334     {
3335       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
3336       if (aShapePrs.IsNull())
3337       {
3338         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
3339         return 1;
3340       }
3341       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
3342       if (aColoredPrs.IsNull())
3343       {
3344         aColoredPrs = new AIS_ColoredShape (aShapePrs);
3345         if (aShapePrs->HasDisplayMode())
3346         {
3347           aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode());
3348         }
3349         aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation());
3350         aCtx->Remove (aShapePrs, Standard_False);
3351         GetMapOfAIS().UnBind2 (aName);
3352         GetMapOfAIS().Bind (aColoredPrs, aName);
3353         toDisplay = Standard_True;
3354         aShapePrs = aColoredPrs;
3355         aPrs      = aColoredPrs;
3356       }
3357     }
3358
3359     if (!aPrs.IsNull())
3360     {
3361       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3362       aChangeSet = &aChangesIter.ChangeValue();
3363       if (aChangeSet->ToSetVisibility == 1)
3364       {
3365         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
3366         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
3367       }
3368       else if (aChangeSet->ToSetMaterial == 1)
3369       {
3370         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
3371       }
3372       else if (aChangeSet->ToSetMaterial == -1)
3373       {
3374         aCtx->UnsetMaterial (aPrs, Standard_False);
3375       }
3376       if (aChangeSet->ToSetColor == 1)
3377       {
3378         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
3379       }
3380       else if (aChangeSet->ToSetColor == -1)
3381       {
3382         aCtx->UnsetColor (aPrs, Standard_False);
3383       }
3384       if (aChangeSet->ToSetTransparency == 1)
3385       {
3386         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
3387       }
3388       else if (aChangeSet->ToSetTransparency == -1)
3389       {
3390         aCtx->UnsetTransparency (aPrs, Standard_False);
3391       }
3392       if (aChangeSet->ToSetLineWidth == 1)
3393       {
3394         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
3395       }
3396       else if (aChangeSet->ToSetLineWidth == -1)
3397       {
3398         aCtx->UnsetWidth (aPrs, Standard_False);
3399       }
3400       else if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3401       {
3402         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
3403         toRedisplay = Standard_True;
3404       }
3405       else if (aChangeSet->ToSetSensitivity != 0)
3406       {
3407         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3408       }
3409       if (!aDrawer.IsNull())
3410       {
3411         toRedisplay = aChangeSet->Apply (aDrawer) || toRedisplay;
3412       }
3413
3414       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
3415       {
3416         aChangeSet = &aChangesIter.ChangeValue();
3417         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
3418              aSubShapeIter.More(); aSubShapeIter.Next())
3419         {
3420           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
3421           if (!aChangeSet->IsEmpty())
3422           {
3423             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3424             aChangeSet->Apply (aCurColDrawer);
3425           }
3426           if (aChangeSet->ToSetVisibility == 1)
3427           {
3428             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3429             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
3430           }
3431           if (aChangeSet->ToSetColor == 1)
3432           {
3433             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
3434           }
3435           if (aChangeSet->ToSetTransparency == 1)
3436           {
3437             aColoredPrs->SetCustomTransparency (aSubShape, aChangeSet->Transparency);
3438           }
3439           if (aChangeSet->ToSetLineWidth == 1)
3440           {
3441             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
3442           }
3443           if (aChangeSet->ToSetColor     == -1
3444            || aChangeSet->ToSetLineWidth == -1)
3445           {
3446             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
3447           }
3448           if (aChangeSet->ToSetSensitivity != 0)
3449           {
3450             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3451           }
3452         }
3453       }
3454       if (toDisplay)
3455       {
3456         aCtx->Display (aPrs, Standard_False);
3457       }
3458       if (toRedisplay)
3459       {
3460         aCtx->Redisplay (aPrs, Standard_False);
3461       }
3462       else if (!aColoredPrs.IsNull())
3463       {
3464         aCtx->Redisplay (aColoredPrs, Standard_False);
3465       }
3466       else
3467       {
3468         aPrs->SynchronizeAspects();
3469       }
3470     }
3471   }
3472   return 0;
3473 }
3474
3475 //==============================================================================
3476 //function : VDonly2
3477 //author   : ege
3478 //purpose  : Display only a selected or named  object
3479 //           if there is no selected or named object s, nothing is done
3480 //==============================================================================
3481 static int VDonly2 (Draw_Interpretor& ,
3482                     Standard_Integer  theArgNb,
3483                     const char**      theArgVec)
3484 {
3485   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3486   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3487   if (aCtx.IsNull())
3488   {
3489     std::cerr << "Error: no active view!\n";
3490     return 1;
3491   }
3492
3493   Standard_Integer anArgIter = 1;
3494   for (; anArgIter < theArgNb; ++anArgIter)
3495   {
3496     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
3497     {
3498       break;
3499     }
3500   }
3501
3502   NCollection_Map<Handle(Standard_Transient)> aDispSet;
3503   if (anArgIter >= theArgNb)
3504   {
3505     // display only selected objects
3506     if (aCtx->NbSelected() < 1)
3507     {
3508       return 0;
3509     }
3510
3511     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3512     {
3513       aDispSet.Add (aCtx->SelectedInteractive());
3514     }
3515   }
3516   else
3517   {
3518     // display only specified objects
3519     for (; anArgIter < theArgNb; ++anArgIter)
3520     {
3521       TCollection_AsciiString aName = theArgVec[anArgIter];
3522       Handle(AIS_InteractiveObject) aShape;
3523       if (GetMapOfAIS().Find2 (aName, aShape)
3524       && !aShape.IsNull())
3525       {
3526         aCtx->Display (aShape, Standard_False);
3527         aDispSet.Add (aShape);
3528       }
3529     }
3530   }
3531
3532   // weed out other objects
3533   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
3534   {
3535     if (aDispSet.Contains (anIter.Key1()))
3536     {
3537       continue;
3538     }
3539
3540     if (Handle(AIS_InteractiveObject) aShape = anIter.Key1())
3541     {
3542       aCtx->Erase (aShape, Standard_False);
3543     }
3544   }
3545   return 0;
3546 }
3547
3548 //==============================================================================
3549 //function : VRemove
3550 //purpose  : Removes selected or named objects.
3551 //           If there is no selected or named objects,
3552 //           all objects in the viewer can be removed with argument -all.
3553 //           If -context is in arguments, the object is not deleted from the map of
3554 //           objects (deleted only from the current context).
3555 //==============================================================================
3556 int VRemove (Draw_Interpretor& theDI,
3557              Standard_Integer  theArgNb,
3558              const char**      theArgVec)
3559 {
3560   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3561   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3562   if (aCtx.IsNull())
3563   {
3564     std::cerr << "Error: no active view!\n";
3565     return 1;
3566   }
3567
3568   Standard_Boolean isContextOnly = Standard_False;
3569   Standard_Boolean toRemoveAll   = Standard_False;
3570   Standard_Boolean toPrintInfo   = Standard_True;
3571   Standard_Boolean toFailOnError = Standard_True;
3572
3573   Standard_Integer anArgIter = 1;
3574   for (; anArgIter < theArgNb; ++anArgIter)
3575   {
3576     TCollection_AsciiString anArg = theArgVec[anArgIter];
3577     anArg.LowerCase();
3578     if (anArg == "-context")
3579     {
3580       isContextOnly = Standard_True;
3581     }
3582     else if (anArg == "-all")
3583     {
3584       toRemoveAll = Standard_True;
3585     }
3586     else if (anArg == "-noinfo")
3587     {
3588       toPrintInfo = Standard_False;
3589     }
3590     else if (anArg == "-noerror"
3591           || anArg == "-nofail")
3592     {
3593       toFailOnError = Standard_False;
3594     }
3595     else if (anUpdateTool.parseRedrawMode (anArg))
3596     {
3597       continue;
3598     }
3599     else
3600     {
3601       break;
3602     }
3603   }
3604   if (toRemoveAll
3605    && anArgIter < theArgNb)
3606   {
3607     std::cerr << "Error: wrong syntax!\n";
3608     return 1;
3609   }
3610
3611   NCollection_List<TCollection_AsciiString> anIONameList;
3612   if (toRemoveAll)
3613   {
3614     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3615          anIter.More(); anIter.Next())
3616     {
3617       anIONameList.Append (anIter.Key2());
3618     }
3619   }
3620   else if (anArgIter < theArgNb) // removed objects names are in argument list
3621   {
3622     for (; anArgIter < theArgNb; ++anArgIter)
3623     {
3624       const TCollection_AsciiString aName (theArgVec[anArgIter]);
3625       if (aName.Search ("*") != -1)
3626       {
3627         for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aPrsIter (GetMapOfAIS()); aPrsIter.More(); aPrsIter.Next())
3628         {
3629           if (aPrsIter.Key1()->GetContext() != aCtx)
3630           {
3631             continue;
3632           }
3633           const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aName + "' '" + aPrsIter.Key2() + "'";
3634           if (theDI.Eval (aCheck.ToCString()) == 0
3635           && *theDI.Result() == '1')
3636           {
3637             anIONameList.Append (aPrsIter.Key2());
3638           }
3639         }
3640         theDI.Reset();
3641         continue;
3642       }
3643
3644       Handle(AIS_InteractiveObject) anIO;
3645       if (!GetMapOfAIS().Find2 (aName, anIO))
3646       {
3647         if (toFailOnError)
3648         {
3649           std::cout << "Syntax error: '" << aName << "' was not bound to some object.\n";
3650           return 1;
3651         }
3652       }
3653       else if (anIO->GetContext() != aCtx)
3654       {
3655         if (toFailOnError)
3656         {
3657           std::cout << "Syntax error: '" << aName << "' was not displayed in current context.\n"
3658                     << "Please activate view with this object displayed and try again.\n";
3659           return 1;
3660         }
3661       }
3662       else
3663       {
3664         anIONameList.Append (aName);
3665       }
3666     }
3667   }
3668   else if (aCtx->NbSelected() > 0)
3669   {
3670     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3671          anIter.More(); anIter.Next())
3672     {
3673       if (!aCtx->IsSelected (anIter.Key1()))
3674       {
3675         continue;
3676       }
3677
3678       anIONameList.Append (anIter.Key2());
3679       continue;
3680     }
3681   }
3682
3683   // Unbind all removed objects from the map of displayed IO.
3684   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
3685        anIter.More(); anIter.Next())
3686   {
3687     const Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (anIter.Value());
3688     aCtx->Remove (anIO, Standard_False);
3689     if (toPrintInfo)
3690     {
3691       theDI << anIter.Value() << " ";
3692     }
3693     if (!isContextOnly)
3694     {
3695       GetMapOfAIS().UnBind2 (anIter.Value());
3696     }
3697   }
3698   return 0;
3699 }
3700
3701 //==============================================================================
3702 //function : VErase
3703 //purpose  : Erase some selected or named objects
3704 //           if there is no selected or named objects, the whole viewer is erased
3705 //==============================================================================
3706 int VErase (Draw_Interpretor& theDI,
3707             Standard_Integer  theArgNb,
3708             const char**      theArgVec)
3709 {
3710   const Handle(AIS_InteractiveContext)& aCtx  = ViewerTest::GetAISContext();
3711   const Handle(V3d_View)&               aView = ViewerTest::CurrentView();
3712   ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
3713   if (aCtx.IsNull())
3714   {
3715     std::cerr << "Error: no active view!\n";
3716     return 1;
3717   }
3718
3719   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
3720
3721   Standard_Integer anArgIter = 1;
3722   Standard_Boolean toEraseInView = Standard_False;
3723   Standard_Boolean toFailOnError = Standard_True;
3724   TColStd_SequenceOfAsciiString aNamesOfEraseIO;
3725   for (; anArgIter < theArgNb; ++anArgIter)
3726   {
3727     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3728     anArgCase.LowerCase();
3729     if (anUpdateTool.parseRedrawMode (anArgCase))
3730     {
3731       continue;
3732     }
3733     else if (anArgCase == "-view"
3734           || anArgCase == "-inview")
3735     {
3736       toEraseInView = Standard_True;
3737     }
3738     else if (anArgCase == "-noerror"
3739           || anArgCase == "-nofail")
3740     {
3741       toFailOnError = Standard_False;
3742     }
3743     else
3744     {
3745       aNamesOfEraseIO.Append (theArgVec[anArgIter]);
3746     }
3747   }
3748
3749   if (!aNamesOfEraseIO.IsEmpty() && toEraseAll)
3750   {
3751     std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
3752     return 1;
3753   }
3754
3755   if (!aNamesOfEraseIO.IsEmpty())
3756   {
3757     // Erase named objects
3758     NCollection_IndexedDataMap<Handle(AIS_InteractiveObject), TCollection_AsciiString> aPrsList;
3759     for (TColStd_SequenceOfAsciiString::Iterator anIter (aNamesOfEraseIO); anIter.More(); anIter.Next())
3760     {
3761       const TCollection_AsciiString& aName = anIter.Value();
3762       if (aName.Search ("*") != -1)
3763       {
3764         for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aPrsIter (GetMapOfAIS()); aPrsIter.More(); aPrsIter.Next())
3765         {
3766           const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aName + "' '" + aPrsIter.Key2() + "'";
3767           if (theDI.Eval (aCheck.ToCString()) == 0
3768           && *theDI.Result() == '1')
3769           {
3770             aPrsList.Add (aPrsIter.Key1(), aPrsIter.Key2());
3771           }
3772         }
3773         theDI.Reset();
3774       }
3775       else
3776       {
3777         Handle(AIS_InteractiveObject) anIO;
3778         if (!GetMapOfAIS().Find2 (aName, anIO))
3779         {
3780           if (toFailOnError)
3781           {
3782             std::cout << "Syntax error: '" << aName << "' is not found\n";
3783             return 1;
3784           }
3785         }
3786         else
3787         {
3788           aPrsList.Add (anIO, aName);
3789         }
3790       }
3791     }
3792
3793     for (NCollection_IndexedDataMap<Handle(AIS_InteractiveObject), TCollection_AsciiString>::Iterator anIter (aPrsList); anIter.More(); anIter.Next())
3794     {
3795       theDI << anIter.Value() << " ";
3796       if (toEraseInView)
3797       {
3798         aCtx->SetViewAffinity (anIter.Key(), aView, Standard_False);
3799       }
3800       else
3801       {
3802         aCtx->Erase (anIter.Key(), Standard_False);
3803       }
3804     }
3805   }
3806   else if (!toEraseAll && aCtx->NbSelected() > 0)
3807   {
3808     // Erase selected objects
3809     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3810          anIter.More(); anIter.Next())
3811     {
3812       const Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3813       if (!anIO.IsNull()
3814        && aCtx->IsSelected (anIO))
3815       {
3816         theDI << anIter.Key2() << " ";
3817         if (toEraseInView)
3818         {
3819           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3820         }
3821       }
3822     }
3823
3824     if (!toEraseInView)
3825     {
3826       aCtx->EraseSelected (Standard_False);
3827     }
3828   }
3829   else
3830   {
3831     // Erase all objects
3832     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3833          anIter.More(); anIter.Next())
3834     {
3835       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3836       if (!anIO.IsNull())
3837       {
3838         if (toEraseInView)
3839         {
3840           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3841         }
3842         else
3843         {
3844           aCtx->Erase (anIO, Standard_False);
3845         }
3846       }
3847     }
3848   }
3849
3850   return 0;
3851 }
3852
3853 //==============================================================================
3854 //function : VDisplayAll
3855 //purpose  : Display all the objects of the Map
3856 //==============================================================================
3857 static int VDisplayAll (Draw_Interpretor& ,
3858                         Standard_Integer  theArgNb,
3859                         const char**      theArgVec)
3860
3861 {
3862   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3863   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3864   if (aCtx.IsNull())
3865   {
3866     std::cerr << "Error: no active view!\n";
3867     return 1;
3868   }
3869
3870   Standard_Integer anArgIter = 1;
3871   for (; anArgIter < theArgNb; ++anArgIter)
3872   {
3873     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3874     anArgCase.LowerCase();
3875     if (anUpdateTool.parseRedrawMode (anArgCase))
3876     {
3877       continue;
3878     }
3879     else
3880     {
3881       break;
3882     }
3883   }
3884   if (anArgIter < theArgNb)
3885   {
3886     std::cout << theArgVec[0] << "Error: wrong syntax\n";
3887     return 1;
3888   }
3889
3890   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3891        anIter.More(); anIter.Next())
3892   {
3893     aCtx->Erase (anIter.Key1(), Standard_False);
3894   }
3895
3896   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3897        anIter.More(); anIter.Next())
3898   {
3899     aCtx->Display (anIter.Key1(), Standard_False);
3900   }
3901   return 0;
3902 }
3903
3904 //! Auxiliary method to check if presentation exists
3905 inline Standard_Integer checkMode (const Handle(AIS_InteractiveContext)& theCtx,
3906                                    const Handle(AIS_InteractiveObject)&  theIO,
3907                                    const Standard_Integer                theMode)
3908 {
3909   if (theIO.IsNull() || theCtx.IsNull())
3910   {
3911     return -1;
3912   }
3913
3914   if (theMode != -1)
3915   {
3916     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
3917     {
3918       return theMode;
3919     }
3920   }
3921   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
3922   {
3923     return theIO->DisplayMode();
3924   }
3925   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
3926   {
3927     return theCtx->DisplayMode();
3928   }
3929
3930   return -1;
3931 }
3932
3933 enum ViewerTest_BndAction
3934 {
3935   BndAction_Hide,
3936   BndAction_Show,
3937   BndAction_Print
3938 };
3939
3940 //! Auxiliary method to print bounding box of presentation
3941 inline void bndPresentation (Draw_Interpretor&                         theDI,
3942                              const Handle(PrsMgr_PresentationManager)& theMgr,
3943                              const Handle(AIS_InteractiveObject)&      theObj,
3944                              const Standard_Integer                    theDispMode,
3945                              const TCollection_AsciiString&            theName,
3946                              const ViewerTest_BndAction                theAction,
3947                              const Handle(Prs3d_Drawer)&               theStyle)
3948 {
3949   switch (theAction)
3950   {
3951     case BndAction_Hide:
3952     {
3953       theMgr->Unhighlight (theObj);
3954       break;
3955     }
3956     case BndAction_Show:
3957     {
3958       theMgr->Color (theObj, theStyle, theDispMode);
3959       break;
3960     }
3961     case BndAction_Print:
3962     {
3963       Bnd_Box aBox;
3964       for (PrsMgr_Presentations::Iterator aPrsIter (theObj->Presentations()); aPrsIter.More(); aPrsIter.Next())
3965       {
3966         if (aPrsIter.Value()->Mode() != theDispMode)
3967           continue;
3968
3969         aBox = aPrsIter.Value()->MinMaxValues();
3970       }
3971       gp_Pnt aMin = aBox.CornerMin();
3972       gp_Pnt aMax = aBox.CornerMax();
3973       theDI << theName  << "\n"
3974             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
3975             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
3976       break;
3977     }
3978   }
3979 }
3980
3981 //==============================================================================
3982 //function : VBounding
3983 //purpose  :
3984 //==============================================================================
3985 int VBounding (Draw_Interpretor& theDI,
3986                Standard_Integer  theArgNb,
3987                const char**      theArgVec)
3988 {
3989   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
3990   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3991   if (aCtx.IsNull())
3992   {
3993     std::cout << "Error: no active view!\n";
3994     return 1;
3995   }
3996
3997   ViewerTest_BndAction anAction = BndAction_Show;
3998   Standard_Integer     aMode    = -1;
3999
4000   Handle(Prs3d_Drawer) aStyle;
4001
4002   Standard_Integer anArgIter = 1;
4003   for (; anArgIter < theArgNb; ++anArgIter)
4004   {
4005     TCollection_AsciiString anArg (theArgVec[anArgIter]);
4006     anArg.LowerCase();
4007     if (anArg == "-print")
4008     {
4009       anAction = BndAction_Print;
4010     }
4011     else if (anArg == "-show")
4012     {
4013       anAction = BndAction_Show;
4014     }
4015     else if (anArg == "-hide")
4016     {
4017       anAction = BndAction_Hide;
4018     }
4019     else if (anArg == "-mode")
4020     {
4021       if (++anArgIter >= theArgNb)
4022       {
4023         std::cout << "Error: wrong syntax at " << anArg << "\n";
4024         return 1;
4025       }
4026       aMode = Draw::Atoi (theArgVec[anArgIter]);
4027     }
4028     else if (!anUpdateTool.parseRedrawMode (anArg))
4029     {
4030       break;
4031     }
4032   }
4033
4034   if (anAction == BndAction_Show)
4035   {
4036     aStyle = new Prs3d_Drawer();
4037     aStyle->SetMethod (Aspect_TOHM_BOUNDBOX);
4038     aStyle->SetColor  (Quantity_NOC_GRAY99);
4039   }
4040
4041   Standard_Integer aHighlightedMode = -1;
4042   if (anArgIter < theArgNb)
4043   {
4044     // has a list of names
4045     for (; anArgIter < theArgNb; ++anArgIter)
4046     {
4047       TCollection_AsciiString aName = theArgVec[anArgIter];
4048       Handle(AIS_InteractiveObject) anIO;
4049       if (!GetMapOfAIS().Find2 (aName, anIO))
4050       {
4051         std::cout << "Error: presentation " << aName << " does not exist\n";
4052         return 1;
4053       }
4054
4055       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4056       if (aHighlightedMode == -1)
4057       {
4058         std::cout << "Error: object " << aName << " has no presentation with mode " << aMode << std::endl;
4059         return 1;
4060       }
4061       bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, aName, anAction, aStyle);
4062     }
4063   }
4064   else if (aCtx->NbSelected() > 0)
4065   {
4066     // remove all currently selected objects
4067     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
4068     {
4069       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
4070       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4071       if (aHighlightedMode != -1)
4072       {
4073         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode,
4074           GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction, aStyle);
4075       }
4076     }
4077   }
4078   else
4079   {
4080     // all objects
4081     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
4082          anIter.More(); anIter.Next())
4083     {
4084       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
4085       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4086       if (aHighlightedMode != -1)
4087       {
4088         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, anIter.Key2(), anAction, aStyle);
4089       }
4090     }
4091   }
4092   return 0;
4093 }
4094
4095 //==============================================================================
4096 //function : VTexture
4097 //purpose  :
4098 //==============================================================================
4099 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4100 {
4101   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
4102   if (aCtx.IsNull())
4103   {
4104     std::cout << "Error: no active view!\n";
4105     return 1;
4106   }
4107
4108   int  toModulate     = -1;
4109   bool toSetFilter    = false;
4110   bool toSetAniso     = false;
4111   bool toSetTrsfAngle = false;
4112   bool toSetTrsfTrans = false;
4113   bool toSetTrsfScale = false;
4114   Standard_ShortReal aTrsfRotAngle = 0.0f;
4115   Graphic3d_Vec2 aTrsfTrans (0.0f, 0.0f);
4116   Graphic3d_Vec2 aTrsfScale (1.0f, 1.0f);
4117   Graphic3d_TypeOfTextureFilter      aFilter       = Graphic3d_TOTF_NEAREST;
4118   Graphic3d_LevelOfTextureAnisotropy anAnisoFilter = Graphic3d_LOTA_OFF;
4119
4120   Handle(AIS_InteractiveObject) aTexturedIO;
4121   Handle(AIS_Shape) aTexturedShape;
4122   Handle(Graphic3d_TextureSet) aTextureSetOld;
4123   NCollection_Vector<Handle(Graphic3d_Texture2Dmanual)> aTextureVecNew;
4124   bool toSetGenRepeat = false;
4125   bool toSetGenScale  = false;
4126   bool toSetGenOrigin = false;
4127   bool toSetImage     = false;
4128   bool toComputeUV    = false;
4129
4130   const TCollection_AsciiString aCommandName (theArgVec[0]);
4131   bool toSetDefaults = aCommandName == "vtexdefault";
4132
4133   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4134   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
4135   {
4136     const TCollection_AsciiString aName     = theArgVec[anArgIter];
4137     TCollection_AsciiString       aNameCase = aName;
4138     aNameCase.LowerCase();
4139     if (anUpdateTool.parseRedrawMode (aName))
4140     {
4141       continue;
4142     }
4143     else if (aTexturedIO.IsNull())
4144     {
4145       const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
4146       if (aMapOfIO.IsBound2 (aName))
4147       {
4148         aTexturedIO = aMapOfIO.Find2 (aName);
4149         aTexturedShape = Handle(AIS_Shape)::DownCast (aTexturedIO);
4150       }
4151       if (aTexturedIO.IsNull())
4152       {
4153         std::cout << "Syntax error: shape " << aName << " does not exists in the viewer.\n";
4154         return 1;
4155       }
4156
4157       if (aTexturedIO->Attributes()->HasOwnShadingAspect())
4158       {
4159         aTextureSetOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureSet();
4160       }
4161     }
4162     else if (!aTexturedShape.IsNull()
4163           && (aNameCase == "-scale"
4164            || aNameCase == "-setscale"
4165            || aCommandName == "vtexscale"))
4166     {
4167       if (aCommandName != "vtexscale")
4168       {
4169         ++anArgIter;
4170       }
4171       if (anArgIter < theArgsNb)
4172       {
4173         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4174         TCollection_AsciiString aValUCase = aValU;
4175         aValUCase.LowerCase();
4176         toSetGenScale = true;
4177         if (aValUCase == "off")
4178         {
4179           aTexturedShape->SetTextureScaleUV (gp_Pnt2d (1.0, 1.0));
4180           continue;
4181         }
4182         else if (anArgIter + 1 < theArgsNb)
4183         {
4184           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4185           if (aValU.IsRealValue()
4186            && aValV.IsRealValue())
4187           {
4188             aTexturedShape->SetTextureScaleUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4189             ++anArgIter;
4190             continue;
4191           }
4192         }
4193       }
4194       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
4195       return 1;
4196     }
4197     else if (!aTexturedShape.IsNull()
4198           && (aNameCase == "-origin"
4199            || aNameCase == "-setorigin"
4200            || aCommandName == "vtexorigin"))
4201     {
4202       if (aCommandName != "vtexorigin")
4203       {
4204         ++anArgIter;
4205       }
4206       if (anArgIter < theArgsNb)
4207       {
4208         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4209         TCollection_AsciiString aValUCase = aValU;
4210         aValUCase.LowerCase();
4211         toSetGenOrigin = true;
4212         if (aValUCase == "off")
4213         {
4214           aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
4215           continue;
4216         }
4217         else if (anArgIter + 1 < theArgsNb)
4218         {
4219           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4220           if (aValU.IsRealValue()
4221            && aValV.IsRealValue())
4222           {
4223             aTexturedShape->SetTextureOriginUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4224             ++anArgIter;
4225             continue;
4226           }
4227         }
4228       }
4229       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
4230       return 1;
4231     }
4232     else if (!aTexturedShape.IsNull()
4233           && (aNameCase == "-repeat"
4234            || aNameCase == "-setrepeat"
4235            || aCommandName == "vtexrepeat"))
4236     {
4237       if (aCommandName != "vtexrepeat")
4238       {
4239         ++anArgIter;
4240       }
4241       if (anArgIter < theArgsNb)
4242       {
4243         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4244         TCollection_AsciiString aValUCase = aValU;
4245         aValUCase.LowerCase();
4246         toSetGenRepeat = true;
4247         if (aValUCase == "off")
4248         {
4249           aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
4250           continue;
4251         }
4252         else if (anArgIter + 1 < theArgsNb)
4253         {
4254           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4255           if (aValU.IsRealValue()
4256            && aValV.IsRealValue())
4257           {
4258             aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4259             ++anArgIter;
4260             continue;
4261           }
4262         }
4263       }
4264       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
4265       return 1;
4266     }
4267     else if (aNameCase == "-modulate")
4268     {
4269       bool toModulateBool = true;
4270       if (anArgIter + 1 < theArgsNb
4271        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toModulateBool))
4272       {
4273         ++anArgIter;
4274       }
4275       toModulate = toModulateBool ? 1 : 0;
4276     }
4277     else if ((aNameCase == "-setfilter"
4278            || aNameCase == "-filter")
4279            && anArgIter + 1 < theArgsNb)
4280     {
4281       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
4282       aValue.LowerCase();
4283       ++anArgIter;
4284       toSetFilter = true;
4285       if (aValue == "nearest")
4286       {
4287         aFilter = Graphic3d_TOTF_NEAREST;
4288       }
4289       else if (aValue == "bilinear")
4290       {
4291         aFilter = Graphic3d_TOTF_BILINEAR;
4292       }
4293       else if (aValue == "trilinear")
4294       {
4295         aFilter = Graphic3d_TOTF_TRILINEAR;
4296       }
4297       else
4298       {
4299         std::cout << "Syntax error: unexpected argument '" << aValue << "'\n";
4300         return 1;
4301       }
4302     }
4303     else if ((aNameCase == "-setaniso"
4304            || aNameCase == "-setanisofilter"
4305            || aNameCase == "-aniso"
4306            || aNameCase == "-anisofilter")
4307            && anArgIter + 1 < theArgsNb)
4308     {
4309       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
4310       aValue.LowerCase();
4311       ++anArgIter;
4312       toSetAniso = true;
4313       if (aValue == "off")
4314       {
4315         anAnisoFilter = Graphic3d_LOTA_OFF;
4316       }
4317       else if (aValue == "fast")
4318       {
4319         anAnisoFilter = Graphic3d_LOTA_FAST;
4320       }
4321       else if (aValue == "middle")
4322       {
4323         anAnisoFilter = Graphic3d_LOTA_MIDDLE;
4324       }
4325       else if (aValue == "quality"
4326             || aValue == "high")
4327       {
4328         anAnisoFilter =  Graphic3d_LOTA_QUALITY;
4329       }
4330       else
4331       {
4332         std::cout << "Syntax error: unexpected argument '" << aValue << "'\n";
4333         return 1;
4334       }
4335     }
4336     else if ((aNameCase == "-rotateangle"
4337            || aNameCase == "-rotangle"
4338            || aNameCase == "-rotate"
4339            || aNameCase == "-angle"
4340            || aNameCase == "-trsfangle")
4341            && anArgIter + 1 < theArgsNb)
4342     {
4343       aTrsfRotAngle  = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4344       toSetTrsfAngle = true;
4345       ++anArgIter;
4346     }
4347     else if ((aNameCase == "-trsftrans"
4348            || aNameCase == "-trsftranslate"
4349            || aNameCase == "-translate"
4350            || aNameCase == "-translation")
4351            && anArgIter + 2 < theArgsNb)
4352     {
4353       aTrsfTrans.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4354       aTrsfTrans.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
4355       toSetTrsfTrans = true;
4356       anArgIter += 2;
4357     }
4358     else if ((aNameCase == "-trsfscale")
4359            && anArgIter + 2 < theArgsNb)
4360     {
4361       aTrsfScale.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4362       aTrsfScale.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
4363       toSetTrsfScale = true;
4364       anArgIter += 2;
4365     }
4366     else if (aNameCase == "-default"
4367           || aNameCase == "-defaults")
4368     {
4369       toSetDefaults = true;
4370     }
4371     else if ((aNameCase == "-video")
4372            && anArgIter + 1 < theArgsNb)
4373     {
4374       const TCollection_AsciiString anInput (theArgVec[++anArgIter]);
4375       Handle(Graphic3d_MediaTextureSet) aMedia = Handle(Graphic3d_MediaTextureSet)::DownCast (aTextureSetOld);
4376       if (aMedia.IsNull())
4377       {
4378         aMedia = new Graphic3d_MediaTextureSet();
4379       }
4380       if (aMedia->Input() != anInput)
4381       {
4382         aMedia->OpenInput (anInput, false);
4383       }
4384       else
4385       {
4386         if (aMedia->SwapFrames()
4387         && !aCtx->CurrentViewer()->ZLayerSettings (aTexturedIO->ZLayer()).IsImmediate())
4388         {
4389           ViewerTest::CurrentView()->Invalidate();
4390         }
4391       }
4392       if (aTexturedIO->Attributes()->SetupOwnShadingAspect (aCtx->DefaultDrawer())
4393        && aTexturedShape.IsNull())
4394       {
4395         aTexturedIO->SetToUpdate();
4396       }
4397
4398       toComputeUV = aTextureSetOld.IsNull();
4399       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (true);
4400       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aMedia);
4401       aTextureSetOld.Nullify();
4402     }
4403     else if (aCommandName == "vtexture"
4404           && (aTextureVecNew.IsEmpty()
4405            || aNameCase.StartsWith ("-tex")))
4406     {
4407       Standard_Integer aTexIndex = 0;
4408       TCollection_AsciiString aTexName = aName;
4409       if (aNameCase.StartsWith ("-tex"))
4410       {
4411         if (anArgIter + 1 >= theArgsNb
4412          || aNameCase.Length() < 5)
4413         {
4414           std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
4415           return 1;
4416         }
4417
4418         TCollection_AsciiString aTexIndexStr = aNameCase.SubString (5, aNameCase.Length());
4419         if (!aTexIndexStr.IsIntegerValue())
4420         {
4421           std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
4422           return 1;
4423         }
4424
4425         aTexIndex = aTexIndexStr.IntegerValue();
4426         aTexName  = theArgVec[anArgIter + 1];
4427         ++anArgIter;
4428       }
4429       if (aTexIndex >= Graphic3d_TextureUnit_NB
4430        || aTexIndex >= aCtx->CurrentViewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxCombinedTextureUnits))
4431       {
4432         std::cout << "Error: too many textures specified\n";
4433         return 1;
4434       }
4435
4436       toSetImage = true;
4437       if (aTexName.IsIntegerValue())
4438       {
4439         const Standard_Integer aValue = aTexName.IntegerValue();
4440         if (aValue < 0 || aValue >= Graphic3d_Texture2D::NumberOfTextures())
4441         {
4442           std::cout << "Syntax error: texture with ID " << aValue << " is undefined!\n";
4443           return 1;
4444         }
4445         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue)));
4446       }
4447       else if (aTexName == "?")
4448       {
4449         const TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
4450
4451         theDi << "\n Files in current directory : \n\n";
4452         theDi.Eval ("glob -nocomplain *");
4453
4454         TCollection_AsciiString aCmnd ("glob -nocomplain ");
4455         aCmnd += aTextureFolder;
4456         aCmnd += "/* ";
4457
4458         theDi << "Files in " << aTextureFolder << " : \n\n";
4459         theDi.Eval (aCmnd.ToCString());
4460         return 0;
4461       }
4462       else if (aTexName != "off")
4463       {
4464         if (!OSD_File (aTexName).Exists())
4465         {
4466           std::cout << "Syntax error: non-existing image file has been specified '" << aTexName << "'.\n";
4467           return 1;
4468         }
4469         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (aTexName));
4470       }
4471       else
4472       {
4473         aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_Texture2Dmanual)());
4474       }
4475
4476       if (aTextureVecNew.Value (aTexIndex))
4477       {
4478         aTextureVecNew.ChangeValue(aTexIndex)->GetParams()->SetTextureUnit((Graphic3d_TextureUnit)aTexIndex);
4479       }
4480     }
4481     else
4482     {
4483       std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
4484       return 1;
4485     }
4486   }
4487
4488   if (toSetImage)
4489   {
4490     // check if new image set is equal to already set one
4491     Standard_Integer aNbChanged = 0;
4492     Handle(Graphic3d_TextureSet) aTextureSetNew;
4493     if (!aTextureVecNew.IsEmpty())
4494     {
4495       aNbChanged = aTextureVecNew.Size();
4496       aTextureSetNew = new Graphic3d_TextureSet (aTextureVecNew.Size());
4497       for (Standard_Integer aTexIter = 0; aTexIter < aTextureSetNew->Size(); ++aTexIter)
4498       {
4499         Handle(Graphic3d_Texture2Dmanual)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter);
4500         Handle(Graphic3d_TextureRoot) aTextureOld;
4501         if (!aTextureSetOld.IsNull()
4502           && aTexIter < aTextureSetOld->Size())
4503         {
4504           aTextureOld = aTextureSetOld->Value (aTexIter);
4505         }
4506
4507         if (!aTextureOld.IsNull()
4508          && !aTextureNew.IsNull())
4509         {
4510           *aTextureNew->GetParams() = *aTextureOld->GetParams();
4511           if (Handle(Graphic3d_Texture2Dmanual) anOldManualTex = Handle(Graphic3d_Texture2Dmanual)::DownCast (aTextureOld))
4512           {
4513             TCollection_AsciiString aFilePathOld, aFilePathNew;
4514             aTextureOld->Path().SystemName (aFilePathOld);
4515             aTextureNew->Path().SystemName (aFilePathNew);
4516             if (aTextureNew->Name() == anOldManualTex->Name()
4517              && aFilePathOld == aFilePathNew
4518              && (!aFilePathNew.IsEmpty() || aTextureNew->Name() != Graphic3d_NOT_2D_UNKNOWN))
4519             {
4520               --aNbChanged;
4521               aTextureNew = anOldManualTex;
4522             }
4523           }
4524         }
4525         aTextureSetNew->SetValue (aTexIter, aTextureNew);
4526       }
4527     }
4528     if (aNbChanged == 0
4529      && ((aTextureSetOld.IsNull() && aTextureSetNew.IsNull())
4530       || (aTextureSetOld->Size() == aTextureSetNew->Size())))
4531     {
4532       aTextureSetNew = aTextureSetOld;
4533     }
4534
4535     if (aTexturedIO->Attributes()->SetupOwnShadingAspect (aCtx->DefaultDrawer())
4536      && aTexturedShape.IsNull())
4537     {
4538       aTexturedIO->SetToUpdate();
4539     }
4540
4541     toComputeUV = !aTextureSetNew.IsNull() && aTextureSetOld.IsNull();
4542     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (!aTextureSetNew.IsNull());
4543     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aTextureSetNew);
4544     aTextureSetOld.Nullify();
4545   }
4546
4547   if (toSetDefaults)
4548   {
4549     if (toModulate != -1)
4550     {
4551       toModulate = 1;
4552     }
4553     if (!toSetFilter)
4554     {
4555       toSetFilter = true;
4556       aFilter     = Graphic3d_TOTF_BILINEAR;
4557     }
4558     if (!toSetAniso)
4559     {
4560       toSetAniso    = true;
4561       anAnisoFilter = Graphic3d_LOTA_OFF;
4562     }
4563     if (!toSetTrsfAngle)
4564     {
4565       toSetTrsfAngle = true;
4566       aTrsfRotAngle  = 0.0f;
4567     }
4568     if (!toSetTrsfTrans)
4569     {
4570       toSetTrsfTrans = true;
4571       aTrsfTrans = Graphic3d_Vec2 (0.0f, 0.0f);
4572     }
4573     if (!toSetTrsfScale)
4574     {
4575       toSetTrsfScale = true;
4576       aTrsfScale = Graphic3d_Vec2 (1.0f, 1.0f);
4577     }
4578   }
4579
4580   if (aCommandName == "vtexture"
4581    && theArgsNb == 2)
4582   {
4583     if (!aTextureSetOld.IsNull())
4584     {
4585       //toComputeUV = true; // we can keep UV vertex attributes
4586       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
4587       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (Handle(Graphic3d_TextureSet)());
4588       aTextureSetOld.Nullify();
4589     }
4590   }
4591
4592   if (aTexturedIO->Attributes()->HasOwnShadingAspect()
4593   && !aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap().IsNull())
4594   {
4595     if (toModulate != -1)
4596     {
4597       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetModulate (toModulate == 1);
4598     }
4599     if (toSetTrsfAngle)
4600     {
4601       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetRotation (aTrsfRotAngle); // takes degrees
4602     }
4603     if (toSetTrsfTrans)
4604     {
4605       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetTranslation (aTrsfTrans);
4606     }
4607     if (toSetTrsfScale)
4608     {
4609       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetScale (aTrsfScale);
4610     }
4611     if (toSetFilter)
4612     {
4613       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetFilter (aFilter);
4614     }
4615     if (toSetAniso)
4616     {
4617       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetAnisoFilter (anAnisoFilter);
4618     }
4619   }
4620
4621   // set default values if requested
4622   if (!toSetGenRepeat
4623    && (aCommandName == "vtexrepeat"
4624     || toSetDefaults))
4625   {
4626     if (!aTexturedShape.IsNull())
4627     {
4628       aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
4629     }
4630     toSetGenRepeat = true;
4631   }
4632   if (!toSetGenOrigin
4633    && (aCommandName == "vtexorigin"
4634     || toSetDefaults))
4635   {
4636     if (!aTexturedShape.IsNull())
4637     {
4638       aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
4639     }
4640     toSetGenOrigin = true;
4641   }
4642   if (!toSetGenScale
4643    && (aCommandName == "vtexscale"
4644     || toSetDefaults))
4645   {
4646     if (!aTexturedShape.IsNull())
4647     {
4648       aTexturedShape->SetTextureScaleUV  (gp_Pnt2d (1.0, 1.0));
4649     }
4650     toSetGenScale = true;
4651   }
4652
4653   if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toComputeUV)
4654   {
4655     if (!aTexturedShape.IsNull())
4656     {
4657       aTexturedShape->SetToUpdate (AIS_Shaded);
4658       if (toSetImage)
4659       {
4660         if ((aTexturedIO->HasDisplayMode() && aTexturedIO->DisplayMode() != AIS_Shaded)
4661          || aCtx->DisplayMode() != AIS_Shaded)
4662         {
4663           aCtx->SetDisplayMode (aTexturedIO, AIS_Shaded, false);
4664         }
4665       }
4666     }
4667   }
4668   aCtx->Display (aTexturedIO, false);
4669   aTexturedIO->SynchronizeAspects();
4670   return 0;
4671 }
4672
4673 //! Auxiliary method to parse transformation persistence flags
4674 inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFlagString,
4675                                            Graphic3d_TransModeFlags&      theFlags)
4676 {
4677   if (theFlagString == "zoom")
4678   {
4679     theFlags = Graphic3d_TMF_ZoomPers;
4680   }
4681   else if (theFlagString == "rotate")
4682   {
4683     theFlags = Graphic3d_TMF_RotatePers;
4684   }
4685   else if (theFlagString == "zoomrotate")
4686   {
4687     theFlags = Graphic3d_TMF_ZoomRotatePers;
4688   }
4689   else if (theFlagString == "trihedron"
4690         || theFlagString == "triedron")
4691   {
4692     theFlags = Graphic3d_TMF_TriedronPers;
4693   }
4694   else if (theFlagString == "none")
4695   {
4696     theFlags = Graphic3d_TMF_None;
4697   }
4698   else
4699   {
4700     return Standard_False;
4701   }
4702
4703   return Standard_True;
4704 }
4705
4706 //! Auxiliary method to parse transformation persistence flags
4707 inline Standard_Boolean parseTrsfPersCorner (const TCollection_AsciiString& theString,
4708                                              Aspect_TypeOfTriedronPosition& theCorner)
4709 {
4710   TCollection_AsciiString aString (theString);
4711   aString.LowerCase();
4712   if (aString == "center")
4713   {
4714     theCorner = Aspect_TOTP_CENTER;
4715   }
4716   else if (aString == "top"
4717         || aString == "upper")
4718   {
4719     theCorner = Aspect_TOTP_TOP;
4720   }
4721   else if (aString == "bottom"
4722         || aString == "lower")
4723   {
4724     theCorner = Aspect_TOTP_BOTTOM;
4725   }
4726   else if (aString == "left")
4727   {
4728     theCorner = Aspect_TOTP_LEFT;
4729   }
4730   else if (aString == "right")
4731   {
4732     theCorner = Aspect_TOTP_RIGHT;
4733   }
4734   else if (aString == "topleft"
4735         || aString == "leftupper"
4736         || aString == "upperleft")
4737   {
4738     theCorner = Aspect_TOTP_LEFT_UPPER;
4739   }
4740   else if (aString == "bottomleft"
4741         || aString == "leftlower"
4742         || aString == "lowerleft")
4743   {
4744     theCorner = Aspect_TOTP_LEFT_LOWER;
4745   }
4746   else if (aString == "topright"
4747         || aString == "rightupper"
4748         || aString == "upperright")
4749   {
4750     theCorner = Aspect_TOTP_RIGHT_UPPER;
4751   }
4752   else if (aString == "bottomright"
4753         || aString == "lowerright"
4754         || aString == "rightlower")
4755   {
4756     theCorner = Aspect_TOTP_RIGHT_LOWER;
4757   }
4758   else
4759   {
4760     return Standard_False;
4761   }
4762
4763   return Standard_True;
4764 }
4765
4766 //==============================================================================
4767 //function : VDisplay2
4768 //author   : ege
4769 //purpose  : Display an object from its name
4770 //==============================================================================
4771 static int VDisplay2 (Draw_Interpretor& theDI,
4772                       Standard_Integer  theArgNb,
4773                       const char**      theArgVec)
4774 {
4775   if (theArgNb < 2)
4776   {
4777     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
4778     return 1;
4779   }
4780   if (theArgNb == 2
4781    && TCollection_AsciiString (theArgVec[1]) == "*")
4782   {
4783     // alias
4784     return VDisplayAll (theDI, 1, theArgVec);
4785   }
4786
4787   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
4788   if (aCtx.IsNull())
4789   {
4790     ViewerTest::ViewerInit();
4791     aCtx = ViewerTest::GetAISContext();
4792   }
4793
4794   // Parse input arguments
4795   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4796   Standard_Integer   isMutable      = -1;
4797   Graphic3d_ZLayerId aZLayer        = Graphic3d_ZLayerId_UNKNOWN;
4798   Standard_Boolean   toReDisplay    = Standard_False;
4799   Standard_Integer   isSelectable   = -1;
4800   Standard_Integer   anObjDispMode  = -2;
4801   Standard_Integer   anObjHighMode  = -2;
4802   Standard_Boolean   toSetTrsfPers  = Standard_False;
4803   Handle(Graphic3d_TransformPers) aTrsfPers;
4804   TColStd_SequenceOfAsciiString aNamesOfDisplayIO;
4805   AIS_DisplayStatus aDispStatus = AIS_DS_None;
4806   Standard_Integer toDisplayInView = Standard_False;
4807   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4808   {
4809     const TCollection_AsciiString aName     = theArgVec[anArgIter];
4810     TCollection_AsciiString       aNameCase = aName;
4811     aNameCase.LowerCase();
4812     if (anUpdateTool.parseRedrawMode (aName))
4813     {
4814       continue;
4815     }
4816     else if (aNameCase == "-mutable")
4817     {
4818       isMutable = 1;
4819     }
4820     else if (aNameCase == "-neutral")
4821     {
4822       aDispStatus = AIS_DS_Displayed;
4823     }
4824     else if (aNameCase == "-immediate"
4825           || aNameCase == "-top")
4826     {
4827       aZLayer = Graphic3d_ZLayerId_Top;
4828     }
4829     else if (aNameCase == "-topmost")
4830     {
4831       aZLayer = Graphic3d_ZLayerId_Topmost;
4832     }
4833     else if (aNameCase == "-osd"
4834           || aNameCase == "-toposd"
4835           || aNameCase == "-overlay")
4836     {
4837       aZLayer = Graphic3d_ZLayerId_TopOSD;
4838     }
4839     else if (aNameCase == "-botosd"
4840           || aNameCase == "-underlay")
4841     {
4842       aZLayer = Graphic3d_ZLayerId_BotOSD;
4843     }
4844     else if (aNameCase == "-select"
4845           || aNameCase == "-selectable")
4846     {
4847       isSelectable = 1;
4848     }
4849     else if (aNameCase == "-noselect"
4850           || aNameCase == "-noselection")
4851     {
4852       isSelectable = 0;
4853     }
4854     else if (aNameCase == "-dispmode"
4855           || aNameCase == "-displaymode")
4856     {
4857       if (++anArgIter >= theArgNb)
4858       {
4859         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4860         return 1;
4861       }
4862
4863       anObjDispMode = Draw::Atoi (theArgVec [anArgIter]);
4864     }
4865     else if (aNameCase == "-himode"
4866           || aNameCase == "-highmode"
4867           || aNameCase == "-highlightmode")
4868     {
4869       if (++anArgIter >= theArgNb)
4870       {
4871         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4872         return 1;
4873       }
4874
4875       anObjHighMode = Draw::Atoi (theArgVec [anArgIter]);
4876     }
4877     else if (aNameCase == "-3d")
4878     {
4879       toSetTrsfPers  = Standard_True;
4880       aTrsfPers.Nullify();
4881     }
4882     else if (aNameCase == "-2d"
4883           || aNameCase == "-trihedron"
4884           || aNameCase == "-triedron")
4885     {
4886       toSetTrsfPers  = Standard_True;
4887       aTrsfPers = new Graphic3d_TransformPers (aNameCase == "-2d" ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
4888
4889       if (anArgIter + 1 < theArgNb)
4890       {
4891         Aspect_TypeOfTriedronPosition aCorner = Aspect_TOTP_CENTER;
4892         if (parseTrsfPersCorner (theArgVec[anArgIter + 1], aCorner))
4893         {
4894           ++anArgIter;
4895           aTrsfPers->SetCorner2d (aCorner);
4896
4897           if (anArgIter + 2 < theArgNb)
4898           {
4899             TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
4900             TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
4901             if (anX.IsIntegerValue()
4902              && anY.IsIntegerValue())
4903             {
4904               anArgIter += 2;
4905               aTrsfPers->SetOffset2d (Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue()));
4906             }
4907           }
4908         }
4909       }
4910     }
4911     else if (aNameCase == "-trsfpers"
4912           || aNameCase == "-pers")
4913     {
4914       if (++anArgIter >= theArgNb
4915        || !aTrsfPers.IsNull())
4916       {
4917         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4918         return 1;
4919       }
4920
4921       toSetTrsfPers  = Standard_True;
4922       Graphic3d_TransModeFlags aTrsfPersFlags = Graphic3d_TMF_None;
4923       TCollection_AsciiString aPersFlags (theArgVec [anArgIter]);
4924       aPersFlags.LowerCase();
4925       if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
4926       {
4927         std::cerr << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".\n";
4928         return 1;
4929       }
4930
4931       if (aTrsfPersFlags == Graphic3d_TMF_TriedronPers)
4932       {
4933         aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
4934       }
4935       else if (aTrsfPersFlags != Graphic3d_TMF_None)
4936       {
4937         aTrsfPers = new Graphic3d_TransformPers (aTrsfPersFlags, gp_Pnt());
4938       }
4939     }
4940     else if (aNameCase == "-trsfperspos"
4941           || aNameCase == "-perspos")
4942     {
4943       if (anArgIter + 2 >= theArgNb
4944        || aTrsfPers.IsNull())
4945       {
4946         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4947         return 1;
4948       }
4949
4950       TCollection_AsciiString aX (theArgVec[++anArgIter]);
4951       TCollection_AsciiString aY (theArgVec[++anArgIter]);
4952       TCollection_AsciiString aZ = "0";
4953       if (!aX.IsRealValue()
4954        || !aY.IsRealValue())
4955       {
4956         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4957         return 1;
4958       }
4959       if (anArgIter + 1 < theArgNb)
4960       {
4961         TCollection_AsciiString aTemp = theArgVec[anArgIter + 1];
4962         if (aTemp.IsRealValue())
4963         {
4964           aZ = aTemp;
4965           ++anArgIter;