0029516: Visualization - eliminate redundant property Graphic3d_MaterialAspect::Refle...
[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 (FreeBoundaryWidth <= 0.0
1968      || FreeBoundaryWidth >  10.0)
1969     {
1970       std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
1971       isOk = Standard_False;
1972     }
1973     if (MaxParamValue < 0.0)
1974     {
1975       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
1976       isOk = Standard_False;
1977     }
1978     if (Sensitivity <= 0 && ToSetSensitivity)
1979     {
1980       std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
1981       isOk = Standard_False;
1982     }
1983     if (ToSetHatch == 1 && StdHatchStyle < 0 && PathToHatchPattern == "")
1984     {
1985       std::cout << "Error: hatch style must be specified\n";
1986       isOk = Standard_False;
1987     }
1988     if (ToSetShadingModel == 1
1989     && (ShadingModel < Graphic3d_TOSM_DEFAULT || ShadingModel > Graphic3d_TOSM_FRAGMENT))
1990     {
1991       std::cout << "Error: unknown shading model " << ShadingModelName << ".\n";
1992       isOk = Standard_False;
1993     }
1994     return isOk;
1995   }
1996
1997   //! Apply aspects to specified drawer.
1998   bool Apply (const Handle(Prs3d_Drawer)& theDrawer)
1999   {
2000     bool toRecompute = false;
2001     const Handle(Prs3d_Drawer)& aDefDrawer = ViewerTest::GetAISContext()->DefaultDrawer();
2002     if (ToSetShowFreeBoundary != 0)
2003     {
2004       theDrawer->SetFreeBoundaryDraw (ToSetShowFreeBoundary == 1);
2005       toRecompute = true;
2006     }
2007     if (ToSetFreeBoundaryWidth != 0)
2008     {
2009       if (ToSetFreeBoundaryWidth != -1
2010        || theDrawer->HasOwnFreeBoundaryAspect())
2011       {
2012         if (!theDrawer->HasOwnFreeBoundaryAspect())
2013         {
2014           Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2015           *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
2016           theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2017           toRecompute = true;
2018         }
2019         theDrawer->FreeBoundaryAspect()->SetWidth (FreeBoundaryWidth);
2020       }
2021     }
2022     if (ToSetFreeBoundaryColor != 0)
2023     {
2024       Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2025       *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
2026       aBoundaryAspect->SetColor (FreeBoundaryColor);
2027       theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2028       toRecompute = true;
2029     }
2030     if (ToSetTypeOfLine != 0)
2031     {
2032       if (ToSetTypeOfLine != -1
2033        || theDrawer->HasOwnLineAspect()
2034        || theDrawer->HasOwnWireAspect()
2035        || theDrawer->HasOwnFreeBoundaryAspect()
2036        || theDrawer->HasOwnUnFreeBoundaryAspect()
2037        || theDrawer->HasOwnSeenLineAspect())
2038       {
2039         toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
2040         theDrawer->LineAspect()->SetTypeOfLine           (TypeOfLine);
2041         theDrawer->WireAspect()->SetTypeOfLine           (TypeOfLine);
2042         theDrawer->FreeBoundaryAspect()->SetTypeOfLine   (TypeOfLine);
2043         theDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (TypeOfLine);
2044         theDrawer->SeenLineAspect()->SetTypeOfLine       (TypeOfLine);
2045       }
2046     }
2047     if (ToSetTypeOfMarker != 0)
2048     {
2049       if (ToSetTypeOfMarker != -1
2050        || theDrawer->HasOwnPointAspect())
2051       {
2052         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
2053         theDrawer->PointAspect()->SetTypeOfMarker (TypeOfMarker);
2054         theDrawer->PointAspect()->Aspect()->SetMarkerImage (MarkerImage.IsNull() ? Handle(Graphic3d_MarkerImage)() : new Graphic3d_MarkerImage (MarkerImage));
2055       }
2056     }
2057     if (ToSetMarkerSize != 0)
2058     {
2059       if (ToSetMarkerSize != -1
2060        || theDrawer->HasOwnPointAspect())
2061       {
2062         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
2063         theDrawer->PointAspect()->SetScale (MarkerSize);
2064         toRecompute = true;
2065       }
2066     }
2067     if (ToSetMaxParamValue != 0)
2068     {
2069       if (ToSetMaxParamValue != -1
2070        || theDrawer->HasOwnMaximalParameterValue())
2071       {
2072         theDrawer->SetMaximalParameterValue (MaxParamValue);
2073         toRecompute = true;
2074       }
2075     }
2076     if (ToSetFaceBoundaryDraw != 0)
2077     {
2078       if (ToSetFaceBoundaryDraw != -1
2079        || theDrawer->HasOwnFaceBoundaryDraw())
2080       {
2081         toRecompute = true;
2082         theDrawer->SetFaceBoundaryDraw (ToSetFaceBoundaryDraw == 1);
2083       }
2084     }
2085     if (ToSetFaceBoundaryUpperContinuity != 0)
2086     {
2087       if (ToSetFaceBoundaryUpperContinuity != -1
2088        || theDrawer->HasOwnFaceBoundaryUpperContinuity())
2089       {
2090         toRecompute = true;
2091         if (ToSetFaceBoundaryUpperContinuity == -1)
2092         {
2093           theDrawer->UnsetFaceBoundaryUpperContinuity();
2094         }
2095         else
2096         {
2097           theDrawer->SetFaceBoundaryUpperContinuity (FaceBoundaryUpperContinuity);
2098         }
2099       }
2100     }
2101     if (ToSetFaceBoundaryColor != 0)
2102     {
2103       if (ToSetFaceBoundaryColor != -1
2104        || theDrawer->HasOwnFaceBoundaryAspect())
2105       {
2106         if (ToSetFaceBoundaryColor == -1)
2107         {
2108           toRecompute = true;
2109           theDrawer->SetFaceBoundaryAspect (Handle(Prs3d_LineAspect)());
2110         }
2111         else
2112         {
2113           toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2114           theDrawer->FaceBoundaryAspect()->SetColor (FaceBoundaryColor);
2115         }
2116       }
2117     }
2118     if (ToSetFaceBoundaryWidth != 0)
2119     {
2120       if (ToSetFaceBoundaryWidth != -1
2121        || theDrawer->HasOwnFaceBoundaryAspect())
2122       {
2123         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2124         theDrawer->FaceBoundaryAspect()->SetWidth (FaceBoundaryWidth);
2125       }
2126     }
2127     if (ToSetTypeOfFaceBoundaryLine != 0)
2128     {
2129       if (ToSetTypeOfFaceBoundaryLine != -1
2130        || theDrawer->HasOwnFaceBoundaryAspect())
2131       {
2132         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2133         theDrawer->FaceBoundaryAspect()->SetTypeOfLine (TypeOfFaceBoundaryLine);
2134       }
2135     }
2136     if (ToSetShadingModel != 0)
2137     {
2138       if (ToSetShadingModel != -1
2139        || theDrawer->HasOwnShadingAspect())
2140       {
2141         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2142         theDrawer->ShadingAspect()->Aspect()->SetShadingModel (ShadingModel);
2143       }
2144     }
2145     if (ToSetBackFaceColor != 0)
2146     {
2147       if (ToSetBackFaceColor != -1
2148        || theDrawer->HasOwnShadingAspect())
2149       {
2150         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2151         theDrawer->ShadingAspect()->SetColor (BackFaceColor, Aspect_TOFM_BACK_SIDE);
2152       }
2153     }
2154     if (ToSetAlphaMode != 0)
2155     {
2156       if (ToSetAlphaMode != -1
2157        || theDrawer->HasOwnShadingAspect())
2158       {
2159         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2160         theDrawer->ShadingAspect()->Aspect()->SetAlphaMode (AlphaMode, AlphaCutoff);
2161       }
2162     }
2163     if (ToSetHatch != 0)
2164     {
2165       if (ToSetHatch != -1
2166       ||  theDrawer->HasOwnShadingAspect())
2167       {
2168         theDrawer->SetupOwnShadingAspect (aDefDrawer);
2169         Handle(Graphic3d_AspectFillArea3d) anAsp = theDrawer->ShadingAspect()->Aspect();
2170         if (ToSetHatch == -1)
2171         {
2172           anAsp->SetInteriorStyle (Aspect_IS_SOLID);
2173         }
2174         else
2175         {
2176           anAsp->SetInteriorStyle (Aspect_IS_HATCH);
2177           if (!PathToHatchPattern.IsEmpty())
2178           {
2179             Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
2180             if (anImage->Load (TCollection_AsciiString (PathToHatchPattern.ToCString())))
2181             {
2182               anAsp->SetHatchStyle (new Graphic3d_HatchStyle (anImage));
2183             }
2184             else
2185             {
2186               std::cout << "Error: cannot load the following image: " << PathToHatchPattern << "\n";
2187             }
2188           }
2189           else if (StdHatchStyle != -1)
2190           {
2191             anAsp->SetHatchStyle (new Graphic3d_HatchStyle ((Aspect_HatchStyle)StdHatchStyle));
2192           }
2193         }
2194         toRecompute = true;
2195       }
2196     }
2197     if (ToSetInterior != 0)
2198     {
2199       if (ToSetInterior != -1
2200        || theDrawer->HasOwnShadingAspect())
2201       {
2202         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2203         theDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (InteriorStyle);
2204         if (InteriorStyle == Aspect_IS_HATCH
2205          && theDrawer->ShadingAspect()->Aspect()->HatchStyle().IsNull())
2206         {
2207           theDrawer->ShadingAspect()->Aspect()->SetHatchStyle (Aspect_HS_VERTICAL);
2208         }
2209       }
2210     }
2211     if (ToSetDrawSilhouette != 0)
2212     {
2213       if (ToSetDrawSilhouette != -1
2214        || theDrawer->HasOwnShadingAspect())
2215       {
2216         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2217         theDrawer->ShadingAspect()->Aspect()->SetDrawSilhouette (ToSetDrawSilhouette == 1);
2218       }
2219     }
2220     if (ToSetDrawEdges != 0)
2221     {
2222       if (ToSetDrawEdges != -1
2223        || theDrawer->HasOwnShadingAspect())
2224       {
2225         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2226         theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetDrawEdges == 1);
2227       }
2228     }
2229     if (ToSetQuadEdges != 0)
2230     {
2231       if (ToSetQuadEdges != -1
2232           || theDrawer->HasOwnShadingAspect())
2233       {
2234         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2235         theDrawer->ShadingAspect()->Aspect()->SetSkipFirstEdge (ToSetQuadEdges == 1);
2236       }
2237     }
2238     if (ToSetEdgeWidth != 0)
2239     {
2240       if (ToSetEdgeWidth != -1
2241        || theDrawer->HasOwnShadingAspect())
2242       {
2243         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2244         theDrawer->ShadingAspect()->Aspect()->SetEdgeWidth (EdgeWidth);
2245       }
2246     }
2247     if (ToSetTypeOfEdge != 0)
2248     {
2249       if (ToSetTypeOfEdge != -1
2250        || theDrawer->HasOwnShadingAspect())
2251       {
2252         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2253         theDrawer->ShadingAspect()->Aspect()->SetEdgeLineType (TypeOfEdge);
2254         if (ToSetInterior == 0)
2255         {
2256           theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetTypeOfEdge == 1
2257                                                            && TypeOfEdge != Aspect_TOL_EMPTY);
2258         }
2259       }
2260     }
2261     if (ToSetEdgeColor != 0)
2262     {
2263       if (ToSetEdgeColor != -1
2264        || theDrawer->HasOwnShadingAspect())
2265       {
2266         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2267         if (ToSetEdgeColor == -1)
2268         {
2269           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (theDrawer->ShadingAspect()->Aspect()->InteriorColor());
2270         }
2271         else
2272         {
2273           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (EdgeColor);
2274         }
2275       }
2276     }
2277     return toRecompute;
2278   }
2279 };
2280
2281 //==============================================================================
2282 //function : VAspects
2283 //purpose  :
2284 //==============================================================================
2285 static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
2286                                   Standard_Integer  theArgNb,
2287                                   const char**      theArgVec)
2288 {
2289   TCollection_AsciiString aCmdName (theArgVec[0]);
2290   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2291   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2292   if (aCtx.IsNull())
2293   {
2294     std::cerr << "Error: no active view!\n";
2295     return 1;
2296   }
2297
2298   Standard_Integer anArgIter = 1;
2299   Standard_Boolean isDefaults = Standard_False;
2300   NCollection_Sequence<TCollection_AsciiString> aNames;
2301   for (; anArgIter < theArgNb; ++anArgIter)
2302   {
2303     TCollection_AsciiString anArg = theArgVec[anArgIter];
2304     if (anUpdateTool.parseRedrawMode (anArg))
2305     {
2306       continue;
2307     }
2308     else if (!anArg.IsEmpty()
2309            && anArg.Value (1) != '-')
2310     {
2311       aNames.Append (anArg);
2312     }
2313     else
2314     {
2315       if (anArg == "-defaults")
2316       {
2317         isDefaults = Standard_True;
2318         ++anArgIter;
2319       }
2320       break;
2321     }
2322   }
2323
2324   if (!aNames.IsEmpty() && isDefaults)
2325   {
2326     std::cout << "Error: wrong syntax. If -defaults is used there should not be any objects' names!\n";
2327     return 1;
2328   }
2329
2330   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
2331   aChanges.Append (ViewerTest_AspectsChangeSet());
2332   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
2333
2334   // parse syntax of legacy commands
2335   bool toParseAliasArgs = false;
2336   if (aCmdName == "vsetwidth")
2337   {
2338     if (aNames.IsEmpty()
2339     || !aNames.Last().IsRealValue())
2340     {
2341       std::cout << "Error: not enough arguments!\n";
2342       return 1;
2343     }
2344     aChangeSet->ToSetLineWidth = 1;
2345     aChangeSet->LineWidth = aNames.Last().RealValue();
2346     aNames.Remove (aNames.Length());
2347   }
2348   else if (aCmdName == "vunsetwidth")
2349   {
2350     aChangeSet->ToSetLineWidth = -1;
2351   }
2352   else if (aCmdName == "vsetcolor")
2353   {
2354     if (aNames.IsEmpty())
2355     {
2356       std::cout << "Error: not enough arguments!\n";
2357       return 1;
2358     }
2359     aChangeSet->ToSetColor = 1;
2360
2361     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2362     Standard_Boolean     isOk   = Standard_False;
2363     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
2364     {
2365       aChangeSet->Color = aColor;
2366       aNames.Remove (aNames.Length());
2367       isOk = Standard_True;
2368     }
2369     else if (aNames.Length() >= 3)
2370     {
2371       const char* anArgVec[3] =
2372       {
2373         aNames.Value (aNames.Upper() - 2).ToCString(),
2374         aNames.Value (aNames.Upper() - 1).ToCString(),
2375         aNames.Value (aNames.Upper() - 0).ToCString(),
2376       };
2377
2378       Standard_Integer aNbParsed = ViewerTest::ParseColor (3, anArgVec, aChangeSet->Color);
2379       isOk = aNbParsed == 3;
2380       aNames.Remove (aNames.Length());
2381       aNames.Remove (aNames.Length());
2382       aNames.Remove (aNames.Length());
2383     }
2384     if (!isOk)
2385     {
2386       std::cout << "Error: not enough arguments!\n";
2387       return 1;
2388     }
2389   }
2390   else if (aCmdName == "vunsetcolor")
2391   {
2392     aChangeSet->ToSetColor = -1;
2393   }
2394   else if (aCmdName == "vsettransparency")
2395   {
2396     if (aNames.IsEmpty()
2397     || !aNames.Last().IsRealValue())
2398     {
2399       std::cout << "Error: not enough arguments!\n";
2400       return 1;
2401     }
2402     aChangeSet->ToSetTransparency = 1;
2403     aChangeSet->Transparency  = aNames.Last().RealValue();
2404     aNames.Remove (aNames.Length());
2405   }
2406   else if (aCmdName == "vunsettransparency")
2407   {
2408     aChangeSet->ToSetTransparency = -1;
2409   }
2410   else if (aCmdName == "vsetmaterial")
2411   {
2412     if (aNames.IsEmpty())
2413     {
2414       std::cout << "Error: not enough arguments!\n";
2415       return 1;
2416     }
2417     aChangeSet->ToSetMaterial = 1;
2418     aChangeSet->MatName = aNames.Last();
2419     aNames.Remove (aNames.Length());
2420     if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString(), aChangeSet->Material))
2421     {
2422       std::cout << "Syntax error: unknown material '" << aChangeSet->MatName << "'.\n";
2423       return 1;
2424     }
2425   }
2426   else if (aCmdName == "vunsetmaterial")
2427   {
2428     aChangeSet->ToSetMaterial = -1;
2429   }
2430   else if (aCmdName == "vsetinteriorstyle")
2431   {
2432     if (aNames.IsEmpty()
2433     || !aNames.Last().IsRealValue())
2434     {
2435       std::cout << "Error: not enough arguments!\n";
2436       return 1;
2437     }
2438     aChangeSet->ToSetInterior = 1;
2439     if (!parseInteriorStyle (aNames.Last(), aChangeSet->InteriorStyle))
2440     {
2441       std::cout << "Error: wrong syntax at " << aNames.Last() << "\n";
2442       return 1;
2443     }
2444     aNames.Remove (aNames.Length());
2445   }
2446   else if (aCmdName == "vsetedgetype")
2447   {
2448     aChangeSet->ToSetDrawEdges = 1;
2449     toParseAliasArgs = true;
2450   }
2451   else if (aCmdName == "vunsetedgetype")
2452   {
2453     aChangeSet->ToSetDrawEdges  = -1;
2454     aChangeSet->ToSetEdgeColor  = -1;
2455     aChangeSet->ToSetTypeOfEdge = -1;
2456     aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
2457   }
2458   else if (aCmdName == "vshowfaceboundary")
2459   {
2460     aChangeSet->ToSetFaceBoundaryDraw = 1;
2461     toParseAliasArgs = true;
2462     if (aNames.Size() >= 2
2463      && aNames.Value (2).IsIntegerValue())
2464     {
2465       if (aNames.Size() == 7)
2466       {
2467         if (ViewerTest::ParseLineType (aNames.Value (7).ToCString(), aChangeSet->TypeOfFaceBoundaryLine))
2468         {
2469           aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2470           aNames.Remove (7);
2471         }
2472       }
2473       if (aNames.Size() == 6
2474        && aNames.Value (6).IsRealValue())
2475       {
2476         aChangeSet->ToSetFaceBoundaryWidth = 1;
2477         aChangeSet->FaceBoundaryWidth = aNames.Value (6).RealValue();
2478         aNames.Remove (6);
2479       }
2480       if (aNames.Size() == 5
2481        && aNames.Value (3).IsIntegerValue()
2482        && aNames.Value (4).IsIntegerValue()
2483        && aNames.Value (5).IsIntegerValue())
2484       {
2485         aChangeSet->ToSetFaceBoundaryColor = 1;
2486         aChangeSet->FaceBoundaryColor = Quantity_Color (aNames.Value (3).IntegerValue() / 255.0,
2487                                                         aNames.Value (4).IntegerValue() / 255.0,
2488                                                         aNames.Value (5).IntegerValue() / 255.0,
2489                                                         Quantity_TOC_RGB);
2490         aNames.Remove (5);
2491         aNames.Remove (4);
2492         aNames.Remove (3);
2493       }
2494       if (aNames.Size() == 2)
2495       {
2496         toParseAliasArgs = false;
2497         aChangeSet->ToSetFaceBoundaryDraw = aNames.Value (2).IntegerValue() == 1 ? 1 : -1;
2498         aNames.Remove (2);
2499       }
2500     }
2501   }
2502   else if (anArgIter >= theArgNb)
2503   {
2504     std::cout << "Error: not enough arguments!\n";
2505     return 1;
2506   }
2507
2508   if (!aChangeSet->IsEmpty()
2509    && !toParseAliasArgs)
2510   {
2511     anArgIter = theArgNb;
2512   }
2513   for (; anArgIter < theArgNb; ++anArgIter)
2514   {
2515     TCollection_AsciiString anArg = theArgVec[anArgIter];
2516     anArg.LowerCase();
2517     if (anArg == "-setwidth"
2518      || anArg == "-width"
2519      || anArg == "-setlinewidth"
2520      || anArg == "-linewidth"
2521      || anArg == "-setedgewidth"
2522      || anArg == "-setedgeswidth"
2523      || anArg == "-edgewidth"
2524      || anArg == "-edgeswidth"
2525      || anArg == "-setfaceboundarywidth"
2526      || anArg == "-setboundarywidth"
2527      || anArg == "-faceboundarywidth"
2528      || anArg == "-boundarywidth")
2529     {
2530       if (++anArgIter >= theArgNb)
2531       {
2532         std::cout << "Error: wrong syntax at " << anArg << "\n";
2533         return 1;
2534       }
2535
2536       const Standard_Real aWidth = Draw::Atof (theArgVec[anArgIter]);
2537       if (anArg == "-setedgewidth"
2538        || anArg == "-setedgeswidth"
2539        || anArg == "-edgewidth"
2540        || anArg == "-edgeswidth"
2541        || aCmdName == "vsetedgetype")
2542       {
2543         aChangeSet->ToSetEdgeWidth = 1;
2544         aChangeSet->EdgeWidth = aWidth;
2545       }
2546       else if (anArg == "-setfaceboundarywidth"
2547             || anArg == "-setboundarywidth"
2548             || anArg == "-faceboundarywidth"
2549             || anArg == "-boundarywidth"
2550             || aCmdName == "vshowfaceboundary")
2551       {
2552         aChangeSet->ToSetFaceBoundaryWidth = 1;
2553         aChangeSet->FaceBoundaryWidth = aWidth;
2554       }
2555       else
2556       {
2557         aChangeSet->ToSetLineWidth = 1;
2558         aChangeSet->LineWidth = aWidth;
2559       }
2560     }
2561     else if (anArg == "-unsetwidth"
2562           || anArg == "-unsetlinewidth"
2563           || anArg == "-unsetedgewidth")
2564     {
2565       if (anArg == "-unsetedgewidth")
2566       {
2567         aChangeSet->ToSetEdgeWidth = -1;
2568         aChangeSet->EdgeWidth = 1.0;
2569       }
2570       else
2571       {
2572         aChangeSet->ToSetLineWidth = -1;
2573         aChangeSet->LineWidth = 1.0;
2574       }
2575     }
2576     else if (anArg == "-settransp"
2577           || anArg == "-settransparency"
2578           || anArg == "-transparency"
2579           || anArg == "-transp")
2580     {
2581       if (++anArgIter >= theArgNb)
2582       {
2583         std::cout << "Error: wrong syntax at " << anArg << "\n";
2584         return 1;
2585       }
2586       aChangeSet->ToSetTransparency = 1;
2587       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
2588       if (aChangeSet->Transparency >= 0.0
2589        && aChangeSet->Transparency <= Precision::Confusion())
2590       {
2591         aChangeSet->ToSetTransparency = -1;
2592         aChangeSet->Transparency = 0.0;
2593       }
2594     }
2595     else if (anArg == "-setalphamode"
2596           || anArg == "-alphamode")
2597     {
2598       if (++anArgIter >= theArgNb)
2599       {
2600         std::cout << "Error: wrong syntax at " << anArg << "\n";
2601         return 1;
2602       }
2603       aChangeSet->ToSetAlphaMode = 1;
2604       aChangeSet->AlphaCutoff = 0.5f;
2605       {
2606         TCollection_AsciiString aParam (theArgVec[anArgIter]);
2607         aParam.LowerCase();
2608         if (aParam == "opaque")
2609         {
2610           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Opaque;
2611         }
2612         else if (aParam == "mask")
2613         {
2614           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Mask;
2615         }
2616         else if (aParam == "blend")
2617         {
2618           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
2619         }
2620         else if (aParam == "blendauto"
2621               || aParam == "auto")
2622         {
2623           aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2624         }
2625         else
2626         {
2627           std::cout << "Error: wrong syntax at " << aParam << "\n";
2628           return 1;
2629         }
2630       }
2631
2632       if (anArgIter + 1 < theArgNb
2633        && theArgVec[anArgIter + 1][0] != '-')
2634       {
2635         TCollection_AsciiString aParam2 (theArgVec[anArgIter + 1]);
2636         if (aParam2.IsRealValue())
2637         {
2638           aChangeSet->AlphaCutoff = (float )aParam2.RealValue();
2639           ++anArgIter;
2640         }
2641       }
2642     }
2643     else if (anArg == "-setvis"
2644           || anArg == "-setvisibility"
2645           || anArg == "-visibility")
2646     {
2647       if (++anArgIter >= theArgNb)
2648       {
2649         std::cout << "Error: wrong syntax at " << anArg << "\n";
2650         return 1;
2651       }
2652
2653       aChangeSet->ToSetVisibility = 1;
2654       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
2655     }
2656     else if (anArg == "-setalpha"
2657           || anArg == "-alpha")
2658     {
2659       if (++anArgIter >= theArgNb)
2660       {
2661         std::cout << "Error: wrong syntax at " << anArg << "\n";
2662         return 1;
2663       }
2664       aChangeSet->ToSetTransparency = 1;
2665       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
2666       if (aChangeSet->Transparency < 0.0
2667        || aChangeSet->Transparency > 1.0)
2668       {
2669         std::cout << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")\n";
2670         return 1;
2671       }
2672       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
2673       if (aChangeSet->Transparency >= 0.0
2674        && aChangeSet->Transparency <= Precision::Confusion())
2675       {
2676         aChangeSet->ToSetTransparency = -1;
2677         aChangeSet->Transparency = 0.0;
2678       }
2679     }
2680     else if (anArg == "-unsettransp"
2681           || anArg == "-unsettransparency"
2682           || anArg == "-unsetalpha"
2683           || anArg == "-opaque")
2684     {
2685       aChangeSet->ToSetTransparency = -1;
2686       aChangeSet->Transparency = 0.0;
2687     }
2688     else if (anArg == "-setcolor"
2689           || anArg == "-color"
2690           || anArg == "-setbackfacecolor"
2691           || anArg == "-backfacecolor"
2692           || anArg == "-setbackcolor"
2693           || anArg == "-backcolor"
2694           || anArg == "-setfaceboundarycolor"
2695           || anArg == "-setboundarycolor"
2696           || anArg == "-faceboundarycolor"
2697           || anArg == "-boundarycolor")
2698     {
2699       Quantity_Color aColor;
2700       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2701                                                            theArgVec + anArgIter + 1,
2702                                                            aColor);
2703       if (aNbParsed == 0)
2704       {
2705         std::cout << "Syntax error at '" << anArg << "'\n";
2706         return 1;
2707       }
2708       anArgIter += aNbParsed;
2709       if (aCmdName == "vsetedgetype")
2710       {
2711         aChangeSet->ToSetEdgeColor = 1;
2712         aChangeSet->EdgeColor = Quantity_ColorRGBA (aColor);
2713       }
2714       else if (aCmdName == "vshowfaceboundary"
2715             || anArg == "-setfaceboundarycolor"
2716             || anArg == "-setboundarycolor"
2717             || anArg == "-faceboundarycolor"
2718             || anArg == "-boundarycolor")
2719       {
2720         aChangeSet->ToSetFaceBoundaryColor = 1;
2721         aChangeSet->FaceBoundaryColor = aColor;
2722       }
2723       else if (anArg == "-setbackfacecolor"
2724             || anArg == "-backfacecolor"
2725             || anArg == "-setbackcolor"
2726             || anArg == "-backcolor")
2727       {
2728         aChangeSet->ToSetBackFaceColor = 1;
2729         aChangeSet->BackFaceColor = aColor;
2730       }
2731       else
2732       {
2733         aChangeSet->ToSetColor = 1;
2734         aChangeSet->Color = aColor;
2735       }
2736     }
2737     else if (anArg == "-setlinetype"
2738           || anArg == "-linetype"
2739           || anArg == "-setedgetype"
2740           || anArg == "-setedgestype"
2741           || anArg == "-edgetype"
2742           || anArg == "-edgestype"
2743           || anArg == "-setfaceboundarystyle"
2744           || anArg == "-faceboundarystyle"
2745           || anArg == "-boundarystyle"
2746           || anArg == "-setfaceboundarytype"
2747           || anArg == "-faceboundarytype"
2748           || anArg == "-setboundarytype"
2749           || anArg == "-boundarytype"
2750           || anArg == "-type")
2751     {
2752       if (++anArgIter >= theArgNb)
2753       {
2754         std::cout << "Error: wrong syntax at " << anArg << "\n";
2755         return 1;
2756       }
2757       Aspect_TypeOfLine aLineType = Aspect_TOL_EMPTY;
2758       if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType))
2759       {
2760         std::cout << "Error: wrong syntax at " << anArg << "\n";
2761         return 1;
2762       }
2763       if (anArg == "-setedgetype"
2764        || anArg == "-setedgestype"
2765        || anArg == "-edgetype"
2766        || anArg == "-edgestype"
2767        || aCmdName == "vsetedgetype")
2768       {
2769         aChangeSet->TypeOfEdge = aLineType;
2770         aChangeSet->ToSetTypeOfEdge = 1;
2771       }
2772       else if (anArg == "-setfaceboundarystyle"
2773             || anArg == "-faceboundarystyle"
2774             || anArg == "-boundarystyle"
2775             || anArg == "-setfaceboundarytype"
2776             || anArg == "-faceboundarytype"
2777             || anArg == "-setboundarytype"
2778             || anArg == "-boundarytype"
2779             || aCmdName == "vshowfaceboundary")
2780       {
2781         aChangeSet->TypeOfFaceBoundaryLine = aLineType;
2782         aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2783       }
2784       else
2785       {
2786         aChangeSet->TypeOfLine = aLineType;
2787         aChangeSet->ToSetTypeOfLine = 1;
2788       }
2789     }
2790     else if (anArg == "-unsetlinetype"
2791           || anArg == "-unsetedgetype"
2792           || anArg == "-unsetedgestype")
2793     {
2794       if (anArg == "-unsetedgetype"
2795        || anArg == "-unsetedgestype")
2796       {
2797         aChangeSet->ToSetTypeOfEdge = -1;
2798       }
2799       else
2800       {
2801         aChangeSet->ToSetTypeOfLine = -1;
2802       }
2803     }
2804     else if (anArg == "-setmarkertype"
2805           || anArg == "-markertype"
2806           || anArg == "-setpointtype"
2807           || anArg == "-pointtype")
2808     {
2809       if (++anArgIter >= theArgNb)
2810       {
2811         std::cout << "Error: wrong syntax at " << anArg << "\n";
2812         return 1;
2813       }
2814       if (!ViewerTest::ParseMarkerType (theArgVec[anArgIter], aChangeSet->TypeOfMarker, aChangeSet->MarkerImage))
2815       {
2816         std::cout << "Error: wrong syntax at " << anArg << "\n";
2817         return 1;
2818       }
2819
2820       aChangeSet->ToSetTypeOfMarker = 1;
2821     }
2822     else if (anArg == "-unsetmarkertype"
2823           || anArg == "-unsetpointtype")
2824     {
2825       aChangeSet->ToSetTypeOfMarker = -1;
2826     }
2827     else if (anArg == "-setmarkersize"
2828           || anArg == "-markersize"
2829           || anArg == "-setpointsize"
2830           || anArg == "-pointsize")
2831     {
2832       if (++anArgIter >= theArgNb)
2833       {
2834         std::cout << "Error: wrong syntax at " << anArg << "\n";
2835         return 1;
2836       }
2837       aChangeSet->ToSetMarkerSize = 1;
2838       aChangeSet->MarkerSize = Draw::Atof (theArgVec[anArgIter]);
2839     }
2840     else if (anArg == "-unsetmarkersize"
2841           || anArg == "-unsetpointsize")
2842     {
2843       aChangeSet->ToSetMarkerSize = -1;
2844       aChangeSet->MarkerSize = 1.0;
2845     }
2846     else if (anArg == "-unsetcolor")
2847     {
2848       aChangeSet->ToSetColor = -1;
2849       aChangeSet->Color = DEFAULT_COLOR;
2850     }
2851     else if (anArg == "-setmat"
2852           || anArg == "-mat"
2853           || anArg == "-setmaterial"
2854           || anArg == "-material")
2855     {
2856       if (++anArgIter >= theArgNb)
2857       {
2858         std::cout << "Error: wrong syntax at " << anArg << "\n";
2859         return 1;
2860       }
2861       aChangeSet->ToSetMaterial = 1;
2862       aChangeSet->MatName = theArgVec[anArgIter];
2863       if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString(), aChangeSet->Material))
2864       {
2865         std::cout << "Syntax error: unknown material '" << aChangeSet->MatName << "'.\n";
2866         return 1;
2867       }
2868     }
2869     else if (anArg == "-unsetmat"
2870           || anArg == "-unsetmaterial")
2871     {
2872       aChangeSet->ToSetMaterial = -1;
2873       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2874     }
2875     else if (anArg == "-subshape"
2876           || anArg == "-subshapes")
2877     {
2878       if (isDefaults)
2879       {
2880         std::cout << "Error: wrong syntax. -subshapes can not be used together with -defaults call!\n";
2881         return 1;
2882       }
2883
2884       if (aNames.IsEmpty())
2885       {
2886         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
2887         return 1;
2888       }
2889
2890       aChanges.Append (ViewerTest_AspectsChangeSet());
2891       aChangeSet = &aChanges.ChangeLast();
2892
2893       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
2894       {
2895         Standard_CString aSubShapeName = theArgVec[anArgIter];
2896         if (*aSubShapeName == '-')
2897         {
2898           --anArgIter;
2899           break;
2900         }
2901
2902         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
2903         if (aSubShape.IsNull())
2904         {
2905           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
2906           return 1;
2907         }
2908         aChangeSet->SubShapes.Append (aSubShape);
2909       }
2910
2911       if (aChangeSet->SubShapes.IsEmpty())
2912       {
2913         std::cerr << "Error: empty list is specified after -subshapes!\n";
2914         return 1;
2915       }
2916     }
2917     else if (anArg == "-setfreeboundary"
2918           || anArg == "-freeboundary"
2919           || anArg == "-setfb"
2920           || anArg == "-fb")
2921     {
2922       bool toEnable = true;
2923       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2924       {
2925         std::cout << "Error: wrong syntax at " << anArg << "\n";
2926         return 1;
2927       }
2928       ++anArgIter;
2929       aChangeSet->ToSetShowFreeBoundary = toEnable ? 1 : -1;
2930     }
2931     else if (anArg == "-setfreeboundarywidth"
2932           || anArg == "-freeboundarywidth"
2933           || anArg == "-setfbwidth"
2934           || anArg == "-fbwidth")
2935     {
2936       if (++anArgIter >= theArgNb)
2937       {
2938         std::cout << "Error: wrong syntax at " << anArg << "\n";
2939         return 1;
2940       }
2941       aChangeSet->ToSetFreeBoundaryWidth = 1;
2942       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2943     }
2944     else if (anArg == "-unsetfreeboundarywidth"
2945           || anArg == "-unsetfbwidth")
2946     {
2947       aChangeSet->ToSetFreeBoundaryWidth = -1;
2948       aChangeSet->FreeBoundaryWidth = 1.0;
2949     }
2950     else if (anArg == "-setfreeboundarycolor"
2951           || anArg == "-freeboundarycolor"
2952           || anArg == "-setfbcolor"
2953           || anArg == "-fbcolor")
2954     {
2955       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2956                                                            theArgVec + anArgIter + 1,
2957                                                            aChangeSet->FreeBoundaryColor);
2958       if (aNbParsed == 0)
2959       {
2960         std::cout << "Syntax error at '" << anArg << "'\n";
2961         return 1;
2962       }
2963       anArgIter += aNbParsed;
2964       aChangeSet->ToSetFreeBoundaryColor = 1;
2965     }
2966     else if (anArg == "-unsetfreeboundarycolor"
2967           || anArg == "-unsetfbcolor")
2968     {
2969       aChangeSet->ToSetFreeBoundaryColor = -1;
2970       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2971     }
2972     else if (anArg == "-setisoontriangulation"
2973           || anArg == "-isoontriangulation"
2974           || anArg == "-setisoontriang"
2975           || anArg == "-isoontriang")
2976     {
2977       bool toEnable = true;
2978       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2979       {
2980         std::cout << "Error: wrong syntax at " << anArg << "\n";
2981         return 1;
2982       }
2983       ++anArgIter;
2984       aChangeSet->ToEnableIsoOnTriangulation = toEnable ? 1 : -1;
2985     }
2986     else if (anArg == "-setfaceboundarydraw"
2987           || anArg == "-setdrawfaceboundary"
2988           || anArg == "-setdrawfaceboundaries"
2989           || anArg == "-setshowfaceboundary"
2990           || anArg == "-setshowfaceboundaries"
2991           || anArg == "-setdrawfaceedges"
2992           || anArg == "-faceboundarydraw"
2993           || anArg == "-drawfaceboundary"
2994           || anArg == "-drawfaceboundaries"
2995           || anArg == "-showfaceboundary"
2996           || anArg == "-showfaceboundaries"
2997           || anArg == "-drawfaceedges"
2998           || anArg == "-faceboundary"
2999           || anArg == "-faceboundaries"
3000           || anArg == "-faceedges")
3001     {
3002       bool toEnable = true;
3003       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
3004       {
3005         std::cout << "Error: wrong syntax at " << anArg << "\n";
3006         return 1;
3007       }
3008       ++anArgIter;
3009       aChangeSet->ToSetFaceBoundaryDraw = toEnable ? 1 : -1;
3010     }
3011     else if (anArg == "-unsetfaceboundary"
3012           || anArg == "-unsetboundary")
3013     {
3014       aChangeSet->ToSetFaceBoundaryDraw  = -1;
3015       aChangeSet->ToSetFaceBoundaryColor = -1;
3016     }
3017     else if (anArg == "-setmostcontinuity"
3018           || anArg == "-mostcontinuity")
3019     {
3020       TCollection_AsciiString aClassArg (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "");
3021       aClassArg.LowerCase();
3022       GeomAbs_Shape aClass = GeomAbs_CN;
3023       if (aClassArg == "c0"
3024        || aClassArg == "0")
3025       {
3026         aClass = GeomAbs_C0;
3027       }
3028       else if (aClassArg == "c1"
3029             || aClassArg == "1")
3030       {
3031         aClass = GeomAbs_C1;
3032       }
3033       else if (aClassArg == "c2"
3034             || aClassArg == "2")
3035       {
3036         aClass = GeomAbs_C2;
3037       }
3038       else if (aClassArg == "c3"
3039             || aClassArg == "3")
3040       {
3041         aClass = GeomAbs_C3;
3042       }
3043       else if (aClassArg == "cn"
3044             || aClassArg == "n")
3045       {
3046         aClass = GeomAbs_CN;
3047       }
3048       else
3049       {
3050         std::cout << "Syntax error at '" << anArg << "'\n";
3051         return 1;
3052       }
3053
3054       ++anArgIter;
3055       aChangeSet->ToSetFaceBoundaryUpperContinuity = 1;
3056       aChangeSet->FaceBoundaryUpperContinuity = aClass;
3057     }
3058     else if (anArg == "-setmaxparamvalue"
3059           || anArg == "-maxparamvalue")
3060     {
3061       if (++anArgIter >= theArgNb)
3062       {
3063         std::cout << "Error: wrong syntax at " << anArg << "\n";
3064         return 1;
3065       }
3066       aChangeSet->ToSetMaxParamValue = 1;
3067       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
3068     }
3069     else if (anArg == "-setsensitivity"
3070           || anArg == "-sensitivity")
3071     {
3072       if (isDefaults)
3073       {
3074         std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
3075         return 1;
3076       }
3077
3078       if (aNames.IsEmpty())
3079       {
3080         std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
3081         return 1;
3082       }
3083
3084       if (anArgIter + 2 >= theArgNb)
3085       {
3086         std::cout << "Error: wrong syntax at " << anArg << "\n";
3087         return 1;
3088       }
3089       aChangeSet->ToSetSensitivity = 1;
3090       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
3091       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
3092     }
3093     else if (anArg == "-sethatch"
3094           || anArg == "-hatch")
3095     {
3096       if (isDefaults)
3097       {
3098         std::cout << "Error: wrong syntax. -setHatch can not be used together with -defaults call!\n";
3099         return 1;
3100       }
3101
3102       if (aNames.IsEmpty())
3103       {
3104         std::cout << "Error: object should be specified explicitly when -setHatch is used!\n";
3105         return 1;
3106       }
3107
3108       aChangeSet->ToSetHatch = 1;
3109       TCollection_AsciiString anArgHatch (theArgVec[++anArgIter]);
3110       if (anArgHatch.Length() <= 2)
3111       {
3112         const Standard_Integer anIntStyle = Draw::Atoi (anArgHatch.ToCString());
3113         if (anIntStyle < 0
3114          || anIntStyle >= Aspect_HS_NB)
3115         {
3116           std::cout << "Error: hatch style is out of range [0, " << (Aspect_HS_NB - 1) << "]!\n";
3117           return 1;
3118         }
3119         aChangeSet->StdHatchStyle = anIntStyle;
3120       }
3121       else
3122       {
3123         aChangeSet->PathToHatchPattern = anArgHatch;
3124       }
3125     }
3126     else if (anArg == "-setshadingmodel"
3127           || anArg == "-setshading"
3128           || anArg == "-shadingmodel"
3129           || anArg == "-shading")
3130     {
3131       if (++anArgIter >= theArgNb)
3132       {
3133         std::cout << "Error: wrong syntax at " << anArg << "\n";
3134         return 1;
3135       }
3136       aChangeSet->ToSetShadingModel = 1;
3137       aChangeSet->ShadingModelName  = theArgVec[anArgIter];
3138       if (!ViewerTest::ParseShadingModel (theArgVec[anArgIter], aChangeSet->ShadingModel))
3139       {
3140         std::cout << "Error: wrong syntax at " << anArg << "\n";
3141         return 1;
3142       }
3143     }
3144     else if (anArg == "-unsetshadingmodel")
3145     {
3146       aChangeSet->ToSetShadingModel = -1;
3147       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
3148     }
3149     else if (anArg == "-setinterior"
3150           || anArg == "-setinteriorstyle"
3151           || anArg == "-interior"
3152           || anArg == "-interiorstyle")
3153     {
3154       if (++anArgIter >= theArgNb)
3155       {
3156         std::cout << "Error: wrong syntax at " << anArg << "\n";
3157         return 1;
3158       }
3159       aChangeSet->ToSetInterior = 1;
3160       if (!parseInteriorStyle (theArgVec[anArgIter], aChangeSet->InteriorStyle))
3161       {
3162         std::cout << "Error: wrong syntax at " << anArg << "\n";
3163         return 1;
3164       }
3165     }
3166     else if (anArg == "-unsetinterior")
3167     {
3168       aChangeSet->ToSetInterior = -1;
3169       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
3170     }
3171     else if (anArg == "-setdrawoutline"
3172           || anArg == "-setdrawsilhouette"
3173           || anArg == "-setoutline"
3174           || anArg == "-setsilhouette"
3175           || anArg == "-outline"
3176           || anArg == "-outlined"
3177           || anArg == "-silhouette")
3178     {
3179       bool toDrawOutline = true;
3180       if (anArgIter + 1 < theArgNb
3181        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toDrawOutline))
3182       {
3183         ++anArgIter;
3184       }
3185       aChangeSet->ToSetDrawSilhouette = toDrawOutline ? 1 : -1;
3186     }
3187     else if (anArg == "-setdrawedges"
3188           || anArg == "-setdrawedge"
3189           || anArg == "-drawedges"
3190           || anArg == "-drawedge"
3191           || anArg == "-edges")
3192     {
3193       bool toDrawEdges = true;
3194       if (anArgIter + 1 < theArgNb
3195        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toDrawEdges))
3196       {
3197         ++anArgIter;
3198       }
3199       aChangeSet->ToSetDrawEdges = toDrawEdges ? 1 : -1;
3200     }
3201     else if (anArg == "-setquadedges"
3202           || anArg == "-setquads"
3203           || anArg == "-quads"
3204           || anArg == "-skipfirstedge")
3205     {
3206       bool isQuadMode = true;
3207       if (anArgIter + 1 < theArgNb
3208        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isQuadMode))
3209       {
3210         ++anArgIter;
3211       }
3212       aChangeSet->ToSetQuadEdges = isQuadMode ? 1 : -1;
3213     }
3214     else if (anArg == "-setedgecolor"
3215           || anArg == "-setedgescolor"
3216           || anArg == "-edgecolor"
3217           || anArg == "-edgescolor")
3218     {
3219       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3220                                                            theArgVec + anArgIter + 1,
3221                                                            aChangeSet->EdgeColor);
3222       if (aNbParsed == 0)
3223       {
3224         std::cout << "Syntax error at '" << anArg << "'\n";
3225         return 1;
3226       }
3227       anArgIter += aNbParsed;
3228       aChangeSet->ToSetEdgeColor = 1;
3229     }
3230     else if (anArg == "-unset")
3231     {
3232       aChangeSet->ToSetVisibility = 1;
3233       aChangeSet->Visibility = 1;
3234       aChangeSet->ToSetLineWidth = -1;
3235       aChangeSet->LineWidth = 1.0;
3236       aChangeSet->ToSetTypeOfLine = -1;
3237       aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
3238       aChangeSet->ToSetTypeOfMarker = -1;
3239       aChangeSet->TypeOfMarker = Aspect_TOM_PLUS;
3240       aChangeSet->ToSetMarkerSize = -1;
3241       aChangeSet->MarkerSize = 1.0;
3242       aChangeSet->ToSetTransparency = -1;
3243       aChangeSet->Transparency = 0.0;
3244       aChangeSet->ToSetAlphaMode = -1;
3245       aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
3246       aChangeSet->AlphaCutoff = 0.5f;
3247       aChangeSet->ToSetColor = -1;
3248       aChangeSet->Color = DEFAULT_COLOR;
3249       //aChangeSet->ToSetBackFaceColor = -1; // should be reset by ToSetColor
3250       //aChangeSet->BackFaceColor = DEFAULT_COLOR;
3251       aChangeSet->ToSetMaterial = -1;
3252       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
3253       aChangeSet->ToSetShowFreeBoundary = -1;
3254       aChangeSet->ToSetFreeBoundaryColor = -1;
3255       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
3256       aChangeSet->ToSetFreeBoundaryWidth = -1;
3257       aChangeSet->FreeBoundaryWidth = 1.0;
3258       aChangeSet->ToEnableIsoOnTriangulation = -1;
3259       //
3260       aChangeSet->ToSetFaceBoundaryDraw = -1;
3261       aChangeSet->ToSetFaceBoundaryUpperContinuity = -1;
3262       aChangeSet->FaceBoundaryUpperContinuity = GeomAbs_CN;
3263       aChangeSet->ToSetFaceBoundaryColor = -1;
3264       aChangeSet->FaceBoundaryColor = Quantity_NOC_BLACK;
3265       aChangeSet->ToSetFaceBoundaryWidth = -1;
3266       aChangeSet->FaceBoundaryWidth = 1.0f;
3267       aChangeSet->ToSetTypeOfFaceBoundaryLine = -1;
3268       aChangeSet->TypeOfFaceBoundaryLine = Aspect_TOL_SOLID;
3269       //
3270       aChangeSet->ToSetHatch = -1;
3271       aChangeSet->StdHatchStyle = -1;
3272       aChangeSet->PathToHatchPattern.Clear();
3273       aChangeSet->ToSetShadingModel = -1;
3274       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
3275       aChangeSet->ToSetInterior = -1;
3276       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
3277       aChangeSet->ToSetDrawSilhouette = -1;
3278       aChangeSet->ToSetDrawEdges = -1;
3279       aChangeSet->ToSetQuadEdges = -1;
3280       aChangeSet->ToSetEdgeColor = -1;
3281       aChangeSet->EdgeColor = Quantity_ColorRGBA (DEFAULT_COLOR);
3282       aChangeSet->ToSetEdgeWidth = -1;
3283       aChangeSet->EdgeWidth = 1.0;
3284       aChangeSet->ToSetTypeOfEdge = -1;
3285       aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
3286     }
3287     else
3288     {
3289       std::cout << "Error: wrong syntax at " << anArg << "\n";
3290       return 1;
3291     }
3292   }
3293
3294   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3295        aChangesIter.More(); aChangesIter.Next())
3296   {
3297     if (!aChangesIter.Value().Validate())
3298     {
3299       return 1;
3300     }
3301   }
3302
3303   // special case for -defaults parameter.
3304   // all changed values will be set to DefaultDrawer.
3305   if (isDefaults)
3306   {
3307     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
3308     aChangeSet->Apply (aDrawer);
3309     if (aChangeSet->ToSetLineWidth != 0)
3310     {
3311       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
3312       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
3313       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
3314       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
3315     }
3316     if (aChangeSet->ToSetColor != 0)
3317     {
3318       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
3319       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
3320       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
3321       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
3322       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
3323       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
3324     }
3325     if (aChangeSet->ToSetTransparency != 0)
3326     {
3327       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
3328     }
3329     if (aChangeSet->ToSetMaterial != 0)
3330     {
3331       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
3332     }
3333     if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3334     {
3335       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
3336     }
3337
3338     // redisplay all objects in context
3339     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3340     {
3341       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
3342       if (!aPrs.IsNull())
3343       {
3344         aCtx->Redisplay (aPrs, Standard_False);
3345       }
3346     }
3347     return 0;
3348   }
3349
3350   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3351   {
3352     const TCollection_AsciiString& aName = aPrsIter.CurrentName();
3353     Handle(AIS_InteractiveObject)  aPrs  = aPrsIter.Current();
3354     if (aPrs.IsNull())
3355     {
3356       return 1;
3357     }
3358
3359     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
3360     Handle(AIS_ColoredShape) aColoredPrs;
3361     Standard_Boolean toDisplay = Standard_False;
3362     Standard_Boolean toRedisplay = Standard_False;
3363     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
3364     {
3365       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
3366       if (aShapePrs.IsNull())
3367       {
3368         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
3369         return 1;
3370       }
3371       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
3372       if (aColoredPrs.IsNull())
3373       {
3374         aColoredPrs = new AIS_ColoredShape (aShapePrs);
3375         if (aShapePrs->HasDisplayMode())
3376         {
3377           aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode());
3378         }
3379         aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation());
3380         aCtx->Remove (aShapePrs, Standard_False);
3381         GetMapOfAIS().UnBind2 (aName);
3382         GetMapOfAIS().Bind (aColoredPrs, aName);
3383         toDisplay = Standard_True;
3384         aShapePrs = aColoredPrs;
3385         aPrs      = aColoredPrs;
3386       }
3387     }
3388
3389     if (!aPrs.IsNull())
3390     {
3391       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3392       aChangeSet = &aChangesIter.ChangeValue();
3393       if (aChangeSet->ToSetVisibility == 1)
3394       {
3395         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
3396         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
3397       }
3398       else if (aChangeSet->ToSetMaterial == 1)
3399       {
3400         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
3401       }
3402       else if (aChangeSet->ToSetMaterial == -1)
3403       {
3404         aCtx->UnsetMaterial (aPrs, Standard_False);
3405       }
3406       if (aChangeSet->ToSetColor == 1)
3407       {
3408         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
3409       }
3410       else if (aChangeSet->ToSetColor == -1)
3411       {
3412         aCtx->UnsetColor (aPrs, Standard_False);
3413       }
3414       if (aChangeSet->ToSetTransparency == 1)
3415       {
3416         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
3417       }
3418       else if (aChangeSet->ToSetTransparency == -1)
3419       {
3420         aCtx->UnsetTransparency (aPrs, Standard_False);
3421       }
3422       if (aChangeSet->ToSetLineWidth == 1)
3423       {
3424         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
3425       }
3426       else if (aChangeSet->ToSetLineWidth == -1)
3427       {
3428         aCtx->UnsetWidth (aPrs, Standard_False);
3429       }
3430       else if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3431       {
3432         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
3433         toRedisplay = Standard_True;
3434       }
3435       else if (aChangeSet->ToSetSensitivity != 0)
3436       {
3437         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3438       }
3439       if (!aDrawer.IsNull())
3440       {
3441         toRedisplay = aChangeSet->Apply (aDrawer) || toRedisplay;
3442       }
3443
3444       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
3445       {
3446         aChangeSet = &aChangesIter.ChangeValue();
3447         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
3448              aSubShapeIter.More(); aSubShapeIter.Next())
3449         {
3450           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
3451           if (!aChangeSet->IsEmpty())
3452           {
3453             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3454             aChangeSet->Apply (aCurColDrawer);
3455           }
3456           if (aChangeSet->ToSetVisibility == 1)
3457           {
3458             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3459             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
3460           }
3461           if (aChangeSet->ToSetColor == 1)
3462           {
3463             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
3464           }
3465           if (aChangeSet->ToSetTransparency == 1)
3466           {
3467             aColoredPrs->SetCustomTransparency (aSubShape, aChangeSet->Transparency);
3468           }
3469           if (aChangeSet->ToSetLineWidth == 1)
3470           {
3471             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
3472           }
3473           if (aChangeSet->ToSetColor     == -1
3474            || aChangeSet->ToSetLineWidth == -1)
3475           {
3476             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
3477           }
3478           if (aChangeSet->ToSetSensitivity != 0)
3479           {
3480             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3481           }
3482         }
3483       }
3484       if (toDisplay)
3485       {
3486         aCtx->Display (aPrs, Standard_False);
3487       }
3488       if (toRedisplay)
3489       {
3490         aCtx->Redisplay (aPrs, Standard_False);
3491       }
3492       else if (!aColoredPrs.IsNull())
3493       {
3494         aCtx->Redisplay (aColoredPrs, Standard_False);
3495       }
3496       else
3497       {
3498         aPrs->SynchronizeAspects();
3499       }
3500     }
3501   }
3502   return 0;
3503 }
3504
3505 //==============================================================================
3506 //function : VDonly2
3507 //author   : ege
3508 //purpose  : Display only a selected or named  object
3509 //           if there is no selected or named object s, nothing is done
3510 //==============================================================================
3511 static int VDonly2 (Draw_Interpretor& ,
3512                     Standard_Integer  theArgNb,
3513                     const char**      theArgVec)
3514 {
3515   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3516   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3517   if (aCtx.IsNull())
3518   {
3519     std::cerr << "Error: no active view!\n";
3520     return 1;
3521   }
3522
3523   Standard_Integer anArgIter = 1;
3524   for (; anArgIter < theArgNb; ++anArgIter)
3525   {
3526     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
3527     {
3528       break;
3529     }
3530   }
3531
3532   NCollection_Map<Handle(Standard_Transient)> aDispSet;
3533   if (anArgIter >= theArgNb)
3534   {
3535     // display only selected objects
3536     if (aCtx->NbSelected() < 1)
3537     {
3538       return 0;
3539     }
3540
3541     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3542     {
3543       aDispSet.Add (aCtx->SelectedInteractive());
3544     }
3545   }
3546   else
3547   {
3548     // display only specified objects
3549     for (; anArgIter < theArgNb; ++anArgIter)
3550     {
3551       TCollection_AsciiString aName = theArgVec[anArgIter];
3552       Handle(AIS_InteractiveObject) aShape;
3553       if (GetMapOfAIS().Find2 (aName, aShape)
3554       && !aShape.IsNull())
3555       {
3556         aCtx->Display (aShape, Standard_False);
3557         aDispSet.Add (aShape);
3558       }
3559     }
3560   }
3561
3562   // weed out other objects
3563   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
3564   {
3565     if (aDispSet.Contains (anIter.Key1()))
3566     {
3567       continue;
3568     }
3569
3570     if (Handle(AIS_InteractiveObject) aShape = anIter.Key1())
3571     {
3572       aCtx->Erase (aShape, Standard_False);
3573     }
3574   }
3575   return 0;
3576 }
3577
3578 //==============================================================================
3579 //function : VRemove
3580 //purpose  : Removes selected or named objects.
3581 //           If there is no selected or named objects,
3582 //           all objects in the viewer can be removed with argument -all.
3583 //           If -context is in arguments, the object is not deleted from the map of
3584 //           objects (deleted only from the current context).
3585 //==============================================================================
3586 int VRemove (Draw_Interpretor& theDI,
3587              Standard_Integer  theArgNb,
3588              const char**      theArgVec)
3589 {
3590   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3591   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3592   if (aCtx.IsNull())
3593   {
3594     std::cerr << "Error: no active view!\n";
3595     return 1;
3596   }
3597
3598   Standard_Boolean isContextOnly = Standard_False;
3599   Standard_Boolean toRemoveAll   = Standard_False;
3600   Standard_Boolean toPrintInfo   = Standard_True;