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