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