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