0030991: Draw Harness - ViewerTest::ParseColor() defines out-of-range alpha component
[occt.git] / src / ViewerTest / ViewerTest.cxx
1 // Created on: 1997-07-23
2 // Created by: Henri JEANNIN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Standard_Stream.hxx>
18
19 #include <ViewerTest.hxx>
20 #include <ViewerTest_CmdParser.hxx>
21
22 #include <Draw.hxx>
23 #include <TopLoc_Location.hxx>
24 #include <TopTools_HArray1OfShape.hxx>
25 #include <TColStd_HArray1OfTransient.hxx>
26 #include <TColStd_SequenceOfAsciiString.hxx>
27 #include <TColStd_HSequenceOfAsciiString.hxx>
28 #include <TColStd_MapOfTransient.hxx>
29 #include <OSD_Timer.hxx>
30 #include <Geom_Axis2Placement.hxx>
31 #include <Geom_Axis1Placement.hxx>
32 #include <gp_Trsf.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <BRepAdaptor_Curve.hxx>
35 #include <StdSelect_ShapeTypeFilter.hxx>
36 #include <AIS.hxx>
37 #include <AIS_ColoredShape.hxx>
38 #include <AIS_InteractiveObject.hxx>
39 #include <AIS_Trihedron.hxx>
40 #include <AIS_Axis.hxx>
41 #include <AIS_Relation.hxx>
42 #include <AIS_TypeFilter.hxx>
43 #include <AIS_SignatureFilter.hxx>
44 #include <AIS_ListOfInteractive.hxx>
45 #include <AIS_ListIteratorOfListOfInteractive.hxx>
46 #include <Aspect_InteriorStyle.hxx>
47 #include <Aspect_Window.hxx>
48 #include <Graphic3d_AspectFillArea3d.hxx>
49 #include <Graphic3d_AspectLine3d.hxx>
50 #include <Graphic3d_CStructure.hxx>
51 #include <Graphic3d_Texture2Dmanual.hxx>
52 #include <Graphic3d_GraphicDriver.hxx>
53 #include <Graphic3d_MediaTextureSet.hxx>
54 #include <Image_AlienPixMap.hxx>
55 #include <OSD_File.hxx>
56 #include <Prs3d_Drawer.hxx>
57 #include <Prs3d_ShadingAspect.hxx>
58 #include <Prs3d_IsoAspect.hxx>
59 #include <Prs3d_PointAspect.hxx>
60 #include <Select3D_SensitiveWire.hxx>
61 #include <Select3D_SensitivePrimitiveArray.hxx>
62 #include <SelectMgr_EntityOwner.hxx>
63 #include <StdSelect_BRepOwner.hxx>
64 #include <StdSelect_ViewerSelector3d.hxx>
65 #include <TopTools_MapOfShape.hxx>
66 #include <ViewerTest_AutoUpdater.hxx>
67
68 #include <stdio.h>
69
70 #include <Draw_Interpretor.hxx>
71 #include <TCollection_AsciiString.hxx>
72 #include <Draw_PluginMacro.hxx>
73
74 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
75
76 #include <Quantity_Color.hxx>
77 #include <Quantity_NameOfColor.hxx>
78
79 #include <Graphic3d_NameOfMaterial.hxx>
80
81 #define DEFAULT_COLOR              Quantity_NOC_GOLDENROD
82 #define DEFAULT_FREEBOUNDARY_COLOR Quantity_NOC_GREEN
83 #define DEFAULT_MATERIAL           Graphic3d_NOM_BRASS
84
85 namespace
86 {
87
88   const Standard_Integer THE_MAX_INTEGER_COLOR_COMPONENT = 255;
89
90   const Standard_ShortReal THE_MAX_REAL_COLOR_COMPONENT = 1.0f;
91
92   //! Parses string and get an integer color component (only values within range 0 .. 255 are allowed)
93   //! @param theColorComponentString the string representing the color component
94   //! @param theIntegerColorComponent an integer color component that is a result of parsing
95   //! @return true if parsing was successful, or false otherwise
96   static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
97                                             Standard_Integer&      theIntegerColorComponent)
98   {
99     Standard_Integer anIntegerColorComponent;
100     if (!Draw::ParseInteger (theColorComponentString, anIntegerColorComponent))
101     {
102       return false;
103     }
104     if ((anIntegerColorComponent < 0) || (anIntegerColorComponent > THE_MAX_INTEGER_COLOR_COMPONENT))
105     {
106       return false;
107     }
108     theIntegerColorComponent = anIntegerColorComponent;
109     return true;
110   }
111
112   //! Parses the string and gets a real color component from it (only values within range 0.0 .. 1.0 are allowed)
113   //! @param theColorComponentString the string representing the color component
114   //! @param theRealColorComponent a real color component that is a result of parsing
115   //! @return true if parsing was successful, or false otherwise
116   static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
117                                             Standard_ShortReal&    theRealColorComponent)
118   {
119     Standard_Real aRealColorComponent;
120     if (!Draw::ParseReal (theColorComponentString, aRealColorComponent))
121     {
122       return false;
123     }
124     const Standard_ShortReal aShortRealColorComponent = static_cast<Standard_ShortReal> (aRealColorComponent);
125     if ((aShortRealColorComponent < 0.0f) || (aShortRealColorComponent > THE_MAX_REAL_COLOR_COMPONENT))
126     {
127       return false;
128     }
129     theRealColorComponent = aShortRealColorComponent;
130     return true;
131   }
132
133   //! Parses the string and gets a real color component from it (integer values 2 .. 255 are scaled to the 0.0 .. 1.0
134   //! range, values 0 and 1 are leaved as they are)
135   //! @param theColorComponentString the string representing the color component
136   //! @param theColorComponent a color component that is a result of parsing
137   //! @return true if parsing was successful, or false otherwise
138   static bool parseColorComponent (const Standard_CString theColorComponentString,
139                                    Standard_ShortReal&    theColorComponent)
140   {
141     Standard_Integer anIntegerColorComponent;
142     if (parseNumericalColorComponent (theColorComponentString, anIntegerColorComponent))
143     {
144       if (anIntegerColorComponent == 1)
145       {
146         theColorComponent = THE_MAX_REAL_COLOR_COMPONENT;
147       }
148       else
149       {
150         theColorComponent = anIntegerColorComponent * 1.0f / THE_MAX_INTEGER_COLOR_COMPONENT;
151       }
152       return true;
153     }
154     return parseNumericalColorComponent (theColorComponentString, theColorComponent);
155   }
156
157   //! Parses the array of strings and gets an integer color (only values within range 0 .. 255 are allowed and at least
158   //! one of components must be greater than 1)
159   //! @tparam TheNumber the type of resulting color vector elements
160   //! @param theNumberOfColorComponents the number of color components
161   //! @param theColorComponentStrings the array of strings representing color components
162   //! @param theNumericalColor a 4-component vector that is a result of parsing
163   //! @return true if parsing was successful, or false otherwise
164   template <typename TheNumber>
165   static bool parseNumericalColor (Standard_Integer&            theNumberOfColorComponents,
166                                    const char* const* const     theColorComponentStrings,
167                                    NCollection_Vec4<TheNumber>& theNumericalColor)
168   {
169     for (Standard_Integer aColorComponentIndex = 0; aColorComponentIndex < theNumberOfColorComponents;
170          ++aColorComponentIndex)
171     {
172       const char* const aColorComponentString = theColorComponentStrings[aColorComponentIndex];
173       TheNumber         aNumericalColorComponent;
174       if (parseNumericalColorComponent (aColorComponentString, aNumericalColorComponent))
175       {
176         theNumericalColor[aColorComponentIndex] = aNumericalColorComponent;
177       }
178       else
179       {
180         if (aColorComponentIndex == 3)
181         {
182           theNumberOfColorComponents = 3;
183         }
184         else
185         {
186           return false;
187         }
188       }
189     }
190     return true;
191   }
192
193   //! Parses an array of strings and get an integer color (only values within range 0 .. 255 are allowed and at least
194   //! one of components must be greater than 1)
195   //! @param theNumberOfColorComponents the number of color components
196   //! @param theColorComponentStrings the array of strings representing color components
197   //! @param theColor a color that is a result of parsing
198   //! @return true if parsing was successful, or false otherwise
199   static bool parseIntegerColor (Standard_Integer&        theNumberOfColorComponents,
200                                  const char* const* const theColorComponentStrings,
201                                  Quantity_ColorRGBA&      theColor)
202   {
203     const Standard_Integer THE_COLOR_COMPONENT_NOT_PARSED = -1;
204     Graphic3d_Vec4i        anIntegerColor (THE_COLOR_COMPONENT_NOT_PARSED);
205     if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, anIntegerColor)
206       || anIntegerColor.maxComp() <= 1)
207     {
208       return false;
209     }
210     if (anIntegerColor.a() == THE_COLOR_COMPONENT_NOT_PARSED)
211     {
212       anIntegerColor.a() = THE_MAX_INTEGER_COLOR_COMPONENT;
213     }
214
215     const Graphic3d_Vec4 aRealColor = Graphic3d_Vec4 (anIntegerColor) / static_cast<Standard_ShortReal> (THE_MAX_INTEGER_COLOR_COMPONENT);
216     theColor = Quantity_ColorRGBA (aRealColor);
217     return true;
218   }
219
220   //! Parses an array of strings and get a real color (only values within range 0.0 .. 1.0 are allowed)
221   //! @param theNumberOfColorComponents the number of color components
222   //! @param theColorComponentStrings the array of strings representing color components
223   //! @param theColor a color that is a result of parsing
224   //! @return true if parsing was successful, or false otherwise
225   static bool parseRealColor (Standard_Integer&        theNumberOfColorComponents,
226                               const char* const* const theColorComponentStrings,
227                               Quantity_ColorRGBA&      theColor)
228   {
229     Graphic3d_Vec4 aRealColor (THE_MAX_REAL_COLOR_COMPONENT);
230     if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, aRealColor))
231     {
232       return false;
233     }
234     theColor = Quantity_ColorRGBA (aRealColor);
235     return true;
236   }
237
238 } // namespace
239
240 //=======================================================================
241 // function : GetColorFromName
242 // purpose  : get the Quantity_NameOfColor from a string
243 //=======================================================================
244
245 Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theName)
246 {
247   Quantity_NameOfColor aColor = DEFAULT_COLOR;
248   Quantity_Color::ColorFromName (theName, aColor);
249   return aColor;
250 }
251
252 //=======================================================================
253 // function : parseColor
254 // purpose  :
255 //=======================================================================
256 Standard_Integer ViewerTest::parseColor (const Standard_Integer   theArgNb,
257                                          const char* const* const theArgVec,
258                                          Quantity_ColorRGBA&      theColor,
259                                          const bool               theToParseAlpha)
260 {
261   if ((theArgNb >= 1) && Quantity_ColorRGBA::ColorFromHex (theArgVec[0], theColor, !theToParseAlpha))
262   {
263     return 1;
264   }
265   if (theArgNb >= 1 && Quantity_ColorRGBA::ColorFromName (theArgVec[0], theColor))
266   {
267     if (theArgNb >= 2 && theToParseAlpha)
268     {
269       const Standard_CString anAlphaStr = theArgVec[1];
270       Standard_ShortReal     anAlphaComponent;
271       if (parseColorComponent (anAlphaStr, anAlphaComponent))
272       {
273         theColor.SetAlpha (anAlphaComponent);
274         return 2;
275       }
276     }
277     return 1;
278   }
279   if (theArgNb >= 3)
280   {
281     const Standard_Integer aNumberOfColorComponentsToParse = Min (theArgNb, theToParseAlpha ? 4 : 3);
282     Standard_Integer aNumberOfColorComponentsParsed = aNumberOfColorComponentsToParse;
283     if (parseIntegerColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
284     {
285       return aNumberOfColorComponentsParsed;
286     }
287     aNumberOfColorComponentsParsed = aNumberOfColorComponentsToParse;
288     if (parseRealColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
289     {
290       return aNumberOfColorComponentsParsed;
291     }
292     return 0;
293   }
294   return 0;
295 }
296
297 //=======================================================================
298 //function : ParseOnOff
299 //purpose  :
300 //=======================================================================
301 Standard_Boolean ViewerTest::ParseOnOff (Standard_CString  theArg,
302                                          Standard_Boolean& theIsOn)
303 {
304   TCollection_AsciiString aFlag(theArg);
305   aFlag.LowerCase();
306   if (aFlag == "on"
307    || aFlag == "1")
308   {
309     theIsOn = Standard_True;
310     return Standard_True;
311   }
312   else if (aFlag == "off"
313         || aFlag == "0")
314   {
315     theIsOn = Standard_False;
316     return Standard_True;
317   }
318   return Standard_False;
319 }
320
321 //=======================================================================
322 //function : GetSelectedShapes
323 //purpose  :
324 //=======================================================================
325 void ViewerTest::GetSelectedShapes (TopTools_ListOfShape& theSelectedShapes)
326 {
327   for (GetAISContext()->InitSelected(); GetAISContext()->MoreSelected(); GetAISContext()->NextSelected())
328   {
329     TopoDS_Shape aShape = GetAISContext()->SelectedShape();
330     if (!aShape.IsNull())
331     {
332       theSelectedShapes.Append (aShape);
333     }
334   }
335 }
336
337 //=======================================================================
338 //function : ParseLineType
339 //purpose  :
340 //=======================================================================
341 Standard_Boolean ViewerTest::ParseLineType (Standard_CString   theArg,
342                                             Aspect_TypeOfLine& theType)
343 {
344   TCollection_AsciiString aTypeStr (theArg);
345   aTypeStr.LowerCase();
346   if (aTypeStr == "empty")
347   {
348     theType = Aspect_TOL_EMPTY;
349   }
350   else if (aTypeStr == "solid")
351   {
352     theType = Aspect_TOL_SOLID;
353   }
354   else if (aTypeStr == "dot")
355   {
356     theType = Aspect_TOL_DOT;
357   }
358   else if (aTypeStr == "dash")
359   {
360     theType = Aspect_TOL_DASH;
361   }
362   else if (aTypeStr == "dotdash")
363   {
364     theType = Aspect_TOL_DOTDASH;
365   }
366   else if (aTypeStr.IsIntegerValue())
367   {
368     const int aTypeInt = aTypeStr.IntegerValue();
369     if (aTypeInt < -1 || aTypeInt >= Aspect_TOL_USERDEFINED)
370     {
371       return Standard_False;
372     }
373     theType = (Aspect_TypeOfLine )aTypeInt;
374   }
375   else
376   {
377     return Standard_False;
378   }
379   return Standard_True;
380 }
381
382 //=======================================================================
383 //function : ParseMarkerType
384 //purpose  :
385 //=======================================================================
386 Standard_Boolean ViewerTest::ParseMarkerType (Standard_CString theArg,
387                                               Aspect_TypeOfMarker& theType,
388                                               Handle(Image_PixMap)& theImage)
389 {
390   theImage.Nullify();
391   TCollection_AsciiString aTypeStr (theArg);
392   aTypeStr.LowerCase();
393   if (aTypeStr == "empty")
394   {
395     theType = Aspect_TOM_EMPTY;
396   }
397   else if (aTypeStr == "point"
398         || aTypeStr == "dot"
399         || aTypeStr == ".")
400   {
401     theType = Aspect_TOM_POINT;
402   }
403   else if (aTypeStr == "plus"
404         || aTypeStr == "+")
405   {
406     theType = Aspect_TOM_PLUS;
407   }
408   else if (aTypeStr == "star"
409         || aTypeStr == "*")
410   {
411     theType = Aspect_TOM_STAR;
412   }
413   else if (aTypeStr == "cross"
414         || aTypeStr == "x")
415   {
416     theType = Aspect_TOM_X;
417   }
418   else if (aTypeStr == "circle"
419         || aTypeStr == "o")
420   {
421     theType = Aspect_TOM_O;
422   }
423   else if (aTypeStr == "pointincircle")
424   {
425     theType = Aspect_TOM_O_POINT;
426   }
427   else if (aTypeStr == "plusincircle")
428   {
429     theType = Aspect_TOM_O_PLUS;
430   }
431   else if (aTypeStr == "starincircle")
432   {
433     theType = Aspect_TOM_O_STAR;
434   }
435   else if (aTypeStr == "crossincircle"
436         || aTypeStr == "xcircle")
437   {
438     theType = Aspect_TOM_O_X;
439   }
440   else if (aTypeStr == "ring1")
441   {
442     theType = Aspect_TOM_RING1;
443   }
444   else if (aTypeStr == "ring2")
445   {
446     theType = Aspect_TOM_RING2;
447   }
448   else if (aTypeStr == "ring"
449         || aTypeStr == "ring3")
450   {
451     theType = Aspect_TOM_RING3;
452   }
453   else if (aTypeStr == "ball")
454   {
455     theType = Aspect_TOM_BALL;
456   }
457   else if (aTypeStr.IsIntegerValue())
458   {
459     const int aTypeInt = aTypeStr.IntegerValue();
460     if (aTypeInt < -1 || aTypeInt >= Aspect_TOM_USERDEFINED)
461     {
462       return Standard_False;
463     }
464     theType = (Aspect_TypeOfMarker )aTypeInt;
465   }
466   else
467   {
468     theType = Aspect_TOM_USERDEFINED;
469     Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
470     if (!anImage->Load (theArg))
471     {
472       return Standard_False;
473     }
474     if (anImage->Format() == Image_Format_Gray)
475     {
476       anImage->SetFormat (Image_Format_Alpha);
477     }
478     else if (anImage->Format() == Image_Format_GrayF)
479     {
480       anImage->SetFormat (Image_Format_AlphaF);
481     }
482     theImage = anImage;
483   }
484   return Standard_True;
485 }
486
487 //=======================================================================
488 //function : ParseShadingModel
489 //purpose  :
490 //=======================================================================
491 Standard_Boolean ViewerTest::ParseShadingModel (Standard_CString              theArg,
492                                                 Graphic3d_TypeOfShadingModel& theModel)
493 {
494   TCollection_AsciiString aTypeStr (theArg);
495   aTypeStr.LowerCase();
496   if (aTypeStr == "unlit"
497    || aTypeStr == "color"
498    || aTypeStr == "none")
499   {
500     theModel = Graphic3d_TOSM_UNLIT;
501   }
502   else if (aTypeStr == "flat"
503         || aTypeStr == "facet")
504   {
505     theModel = Graphic3d_TOSM_FACET;
506   }
507   else if (aTypeStr == "gouraud"
508         || aTypeStr == "vertex"
509         || aTypeStr == "vert")
510   {
511     theModel = Graphic3d_TOSM_VERTEX;
512   }
513   else if (aTypeStr == "phong"
514         || aTypeStr == "fragment"
515         || aTypeStr == "frag"
516         || aTypeStr == "pixel")
517   {
518     theModel = Graphic3d_TOSM_FRAGMENT;
519   }
520   else if (aTypeStr == "default"
521         || aTypeStr == "def")
522   {
523     theModel = Graphic3d_TOSM_DEFAULT;
524   }
525   else if (aTypeStr.IsIntegerValue())
526   {
527     const int aTypeInt = aTypeStr.IntegerValue();
528     if (aTypeInt <= Graphic3d_TOSM_DEFAULT || aTypeInt >= Graphic3d_TypeOfShadingModel_NB)
529     {
530       return Standard_False;
531     }
532     theModel = (Graphic3d_TypeOfShadingModel)aTypeInt;
533   }
534   else
535   {
536     return Standard_False;
537   }
538   return Standard_True;
539 }
540
541 //=======================================================================
542 //function : parseZLayer
543 //purpose  :
544 //=======================================================================
545 Standard_Boolean ViewerTest::parseZLayer (Standard_CString theArg,
546                                           Standard_Boolean theToAllowInteger,
547                                           Graphic3d_ZLayerId& theLayer)
548 {
549   TCollection_AsciiString aName (theArg);
550   aName.LowerCase();
551   if (aName == "default"
552    || aName == "def")
553   {
554     theLayer = Graphic3d_ZLayerId_Default;
555   }
556   else if (aName == "top")
557   {
558     theLayer = Graphic3d_ZLayerId_Top;
559   }
560   else if (aName == "topmost")
561   {
562     theLayer = Graphic3d_ZLayerId_Topmost;
563   }
564   else if (aName == "overlay"
565         || aName == "toposd")
566   {
567     theLayer = Graphic3d_ZLayerId_TopOSD;
568   }
569   else if (aName == "underlay"
570         || aName == "botosd")
571   {
572     theLayer = Graphic3d_ZLayerId_BotOSD;
573   }
574   else if (aName == "undefined")
575   {
576     theLayer = Graphic3d_ZLayerId_UNKNOWN;
577   }
578   else if (!GetAISContext().IsNull())
579   {
580     const Handle(V3d_Viewer)& aViewer = ViewerTest::GetAISContext()->CurrentViewer();
581     TColStd_SequenceOfInteger aLayers;
582     aViewer->GetAllZLayers (aLayers);
583     for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
584     {
585       Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
586       if (TCollection_AsciiString::IsSameString (aSettings.Name(), aName, Standard_False))
587       {
588         theLayer = aLayeriter.Value();
589         return true;
590       }
591     }
592
593     if (!theToAllowInteger
594      || !aName.IsIntegerValue())
595     {
596       return false;
597     }
598     Graphic3d_ZLayerId aLayer = aName.IntegerValue();
599     if (aLayer == Graphic3d_ZLayerId_UNKNOWN
600      || std::find (aLayers.begin(), aLayers.end(), aLayer) != aLayers.end())
601     {
602       theLayer = aLayer;
603       return true;
604     }
605     return false;
606   }
607   return true;
608 }
609
610 //=======================================================================
611 //function : GetTypeNames
612 //purpose  :
613 //=======================================================================
614 static const char** GetTypeNames()
615 {
616   static const char* names[14] = {"Point","Axis","Trihedron","PlaneTrihedron", "Line","Circle","Plane",
617                           "Shape","ConnectedShape","MultiConn.Shape",
618                           "ConnectedInter.","MultiConn.",
619                           "Constraint","Dimension"};
620   static const char** ThePointer = names;
621   return ThePointer;
622 }
623
624 //=======================================================================
625 //function : GetTypeAndSignfromString
626 //purpose  :
627 //=======================================================================
628 void GetTypeAndSignfromString (const char* name,AIS_KindOfInteractive& TheType,Standard_Integer& TheSign)
629 {
630   const char ** thefullnames = GetTypeNames();
631   Standard_Integer index(-1);
632
633   for(Standard_Integer i=0;i<=13 && index==-1;i++)
634     if(!strcasecmp(name,thefullnames[i]))
635       index = i;
636
637   if(index ==-1){
638     TheType = AIS_KOI_None;
639     TheSign = -1;
640     return;
641   }
642
643   if(index<=6){
644     TheType = AIS_KOI_Datum;
645     TheSign = index+1;
646   }
647   else if (index <=9){
648     TheType = AIS_KOI_Shape;
649     TheSign = index-7;
650   }
651   else if(index<=11){
652     TheType = AIS_KOI_Object;
653     TheSign = index-10;
654   }
655   else{
656     TheType = AIS_KOI_Relation;
657     TheSign = index-12;
658   }
659
660 }
661
662
663
664 #include <string.h>
665 #include <Draw_Interpretor.hxx>
666 #include <Draw.hxx>
667 #include <Draw_Appli.hxx>
668 #include <DBRep.hxx>
669
670
671 #include <TCollection_AsciiString.hxx>
672 #include <V3d_Viewer.hxx>
673 #include <V3d_View.hxx>
674 #include <V3d.hxx>
675
676 #include <AIS_InteractiveContext.hxx>
677 #include <AIS_Shape.hxx>
678 #include <AIS_DisplayMode.hxx>
679 #include <TColStd_MapOfInteger.hxx>
680 #include <AIS_MapOfInteractive.hxx>
681 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
682 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
683 #include <ViewerTest_EventManager.hxx>
684
685 #include <TopoDS_Solid.hxx>
686 #include <BRepTools.hxx>
687 #include <BRep_Builder.hxx>
688 #include <TopAbs_ShapeEnum.hxx>
689
690 #include <TopoDS.hxx>
691 #include <BRep_Tool.hxx>
692
693
694 #include <Draw_Window.hxx>
695 #include <AIS_ListIteratorOfListOfInteractive.hxx>
696 #include <AIS_ListOfInteractive.hxx>
697 #include <AIS_DisplayMode.hxx>
698 #include <TopTools_ListOfShape.hxx>
699 #include <BRepOffsetAPI_MakeThickSolid.hxx>
700
701 //==============================================================================
702 //  VIEWER OBJECT MANAGEMENT GLOBAL VARIABLES
703 //==============================================================================
704 Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(){
705   static ViewerTest_DoubleMapOfInteractiveAndName TheMap;
706   return TheMap;
707 }
708
709 //=======================================================================
710 //function : Display
711 //purpose  :
712 //=======================================================================
713 Standard_Boolean ViewerTest::Display (const TCollection_AsciiString&       theName,
714                                       const Handle(AIS_InteractiveObject)& theObject,
715                                       const Standard_Boolean               theToUpdate,
716                                       const Standard_Boolean               theReplaceIfExists)
717 {
718   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
719   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
720   if (aCtx.IsNull())
721   {
722     std::cout << "Error: AIS context is not available.\n";
723     return Standard_False;
724   }
725
726   if (aMap.IsBound2 (theName))
727   {
728     if (!theReplaceIfExists)
729     {
730       std::cout << "Error: other interactive object has been already registered with name: " << theName << ".\n"
731                 << "Please use another name.\n";
732       return Standard_False;
733     }
734
735     if (Handle(AIS_InteractiveObject) anOldObj = aMap.Find2 (theName))
736     {
737       aCtx->Remove (anOldObj, theObject.IsNull() && theToUpdate);
738     }
739     aMap.UnBind2 (theName);
740   }
741
742   if (theObject.IsNull())
743   {
744     // object with specified name has been already unbound
745     return Standard_True;
746   }
747
748   // unbind AIS object if it was bound with another name
749   aMap.UnBind1 (theObject);
750
751   // can be registered without rebinding
752   aMap.Bind (theObject, theName);
753   aCtx->Display (theObject, theToUpdate);
754   return Standard_True;
755 }
756
757 //! Alias for ViewerTest::Display(), compatibility with old code.
758 Standard_EXPORT Standard_Boolean VDisplayAISObject (const TCollection_AsciiString&       theName,
759                                                     const Handle(AIS_InteractiveObject)& theObject,
760                                                     Standard_Boolean theReplaceIfExists = Standard_True)
761 {
762   return ViewerTest::Display (theName, theObject, Standard_True, theReplaceIfExists);
763 }
764
765 static NCollection_List<Handle(ViewerTest_EventManager)> theEventMgrs;
766
767 static Handle(V3d_View)&  a3DView()
768 {
769   static Handle(V3d_View) Viou;
770   return Viou;
771 }
772
773
774 Standard_EXPORT Handle(AIS_InteractiveContext)& TheAISContext(){
775   static Handle(AIS_InteractiveContext) aContext;
776   return aContext;
777 }
778
779 const Handle(V3d_View)& ViewerTest::CurrentView()
780 {
781   return a3DView();
782 }
783 void ViewerTest::CurrentView(const Handle(V3d_View)& V)
784 {
785   a3DView() = V;
786 }
787
788 const Handle(AIS_InteractiveContext)& ViewerTest::GetAISContext()
789 {
790   return TheAISContext();
791 }
792
793 void ViewerTest::SetAISContext (const Handle(AIS_InteractiveContext)& aCtx)
794 {
795   TheAISContext() = aCtx;
796   ViewerTest::ResetEventManager();
797 }
798
799 Handle(V3d_Viewer) ViewerTest::GetViewerFromContext()
800 {
801   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
802 }
803
804 Handle(V3d_Viewer) ViewerTest::GetCollectorFromContext()
805 {
806   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
807 }
808
809
810 void ViewerTest::SetEventManager(const Handle(ViewerTest_EventManager)& EM){
811   theEventMgrs.Prepend(EM);
812 }
813
814 void ViewerTest::UnsetEventManager()
815 {
816   theEventMgrs.RemoveFirst();
817 }
818
819
820 void ViewerTest::ResetEventManager()
821 {
822   theEventMgrs.Clear();
823   theEventMgrs.Prepend (new ViewerTest_EventManager (ViewerTest::CurrentView(), ViewerTest::GetAISContext()));
824 }
825
826 Handle(ViewerTest_EventManager) ViewerTest::CurrentEventManager()
827 {
828   return !theEventMgrs.IsEmpty()
829         ? theEventMgrs.First()
830         : Handle(ViewerTest_EventManager)();
831 }
832
833 //=======================================================================
834 //function : Get Context and active view
835 //purpose  :
836 //=======================================================================
837 static Standard_Boolean getCtxAndView (Handle(AIS_InteractiveContext)& theCtx,
838                                        Handle(V3d_View)&               theView)
839 {
840   theCtx  = ViewerTest::GetAISContext();
841   theView = ViewerTest::CurrentView();
842   if (theCtx.IsNull()
843    || theView.IsNull())
844   {
845     std::cout << "Error: cannot find an active view!\n";
846     return Standard_False;
847   }
848   return Standard_True;
849 }
850
851 //==============================================================================
852 //function : Clear
853 //purpose  : Remove all the object from the viewer
854 //==============================================================================
855 void ViewerTest::Clear()
856 {
857   if (a3DView().IsNull())
858   {
859     return;
860   }
861
862   NCollection_Sequence<Handle(AIS_InteractiveObject)> aListRemoved;
863   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS()); anObjIter.More(); anObjIter.Next())
864   {
865     const Handle(AIS_InteractiveObject) anObj = anObjIter.Key1();
866     if (anObj->GetContext() != TheAISContext())
867     {
868       continue;
869     }
870
871     std::cout << "Remove " << anObjIter.Key2() << std::endl;
872     TheAISContext()->Remove (anObj, Standard_False);
873     aListRemoved.Append (anObj);
874   }
875
876   TheAISContext()->RebuildSelectionStructs();
877   TheAISContext()->UpdateCurrentViewer();
878   if (aListRemoved.Size() == GetMapOfAIS().Extent())
879   {
880     GetMapOfAIS().Clear();
881   }
882   else
883   {
884     for (NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator anObjIter (aListRemoved); anObjIter.More(); anObjIter.Next())
885     {
886       GetMapOfAIS().UnBind1 (anObjIter.Value());
887     }
888   }
889 }
890
891 //==============================================================================
892 //function : CopyIsoAspect
893 //purpose  : Returns copy Prs3d_IsoAspect with new number of isolines.
894 //==============================================================================
895 static Handle(Prs3d_IsoAspect) CopyIsoAspect
896       (const Handle(Prs3d_IsoAspect) &theIsoAspect,
897        const Standard_Integer theNbIsos)
898 {
899   Quantity_Color    aColor = theIsoAspect->Aspect()->Color();
900   Aspect_TypeOfLine aType  = theIsoAspect->Aspect()->Type();
901   Standard_Real     aWidth = theIsoAspect->Aspect()->Width();
902
903   Handle(Prs3d_IsoAspect) aResult =
904     new Prs3d_IsoAspect(aColor, aType, aWidth, theNbIsos);
905
906   return aResult;
907 }
908
909 //==============================================================================
910 //function : visos
911 //purpose  : Returns or sets the number of U- and V- isos and isIsoOnPlane flag
912 //Draw arg : [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]
913 //==============================================================================
914 static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
915 {
916   if (TheAISContext().IsNull()) {
917     di << argv[0] << " Call 'vinit' before!\n";
918     return 1;
919   }
920
921   if (argc <= 1) {
922     di << "Current number of isos : " <<
923       TheAISContext()->IsoNumber(AIS_TOI_IsoU) << " " <<
924       TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n";
925     di << "IsoOnPlane mode is " <<
926       (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n";
927     di << "IsoOnTriangulation mode is " <<
928       (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n";
929     return 0;
930   }
931
932   Standard_Integer aLastInd = argc - 1;
933   Standard_Boolean isChanged = Standard_False;
934   Standard_Integer aNbUIsos = 0;
935   Standard_Integer aNbVIsos = 0;
936
937   if (aLastInd >= 3) {
938     Standard_Boolean isIsoOnPlane = Standard_False;
939
940     if (strcmp(argv[aLastInd], "1") == 0) {
941       isIsoOnPlane = Standard_True;
942       isChanged    = Standard_True;
943     } else if (strcmp(argv[aLastInd], "0") == 0) {
944       isIsoOnPlane = Standard_False;
945       isChanged    = Standard_True;
946     }
947
948     if (isChanged) {
949       aNbVIsos = Draw::Atoi(argv[aLastInd - 1]);
950       aNbUIsos = Draw::Atoi(argv[aLastInd - 2]);
951       aLastInd -= 3;
952
953       di << "New number of isos : " << aNbUIsos << " " << aNbVIsos << "\n";
954       di << "New IsoOnPlane mode is " << (isIsoOnPlane ? "ON" : "OFF") << "\n";
955
956       TheAISContext()->IsoOnPlane(isIsoOnPlane);
957
958       if (aLastInd == 0) {
959         // If there are no shapes provided set the default numbers.
960         TheAISContext()->SetIsoNumber(aNbUIsos, AIS_TOI_IsoU);
961         TheAISContext()->SetIsoNumber(aNbVIsos, AIS_TOI_IsoV);
962       }
963     }
964   }
965
966   Standard_Integer i;
967
968   for (i = 1; i <= aLastInd; i++)
969   {
970     TCollection_AsciiString name(argv[i]);
971     Handle(AIS_InteractiveObject) aShape;
972     GetMapOfAIS().Find2(name, aShape);
973     if (aShape.IsNull())
974     {
975       std::cout << "Syntax error: object '" << name << "' is not found\n";
976       return 1;
977     }
978
979     Handle(Prs3d_Drawer) CurDrawer = aShape->Attributes();
980     Handle(Prs3d_IsoAspect) aUIso = CurDrawer->UIsoAspect();
981     Handle(Prs3d_IsoAspect) aVIso = CurDrawer->VIsoAspect();
982     if (isChanged)
983     {
984       CurDrawer->SetUIsoAspect(CopyIsoAspect(aUIso, aNbUIsos));
985       CurDrawer->SetVIsoAspect(CopyIsoAspect(aVIso, aNbVIsos));
986       TheAISContext()->SetLocalAttributes (aShape, CurDrawer, Standard_False);
987       TheAISContext()->Redisplay (aShape, Standard_False);
988     }
989     else
990     {
991       di << "Number of isos for " << argv[i] << " : "
992           << aUIso->Number() << " " << aVIso->Number() << "\n";
993     }
994   }
995
996   if (isChanged) {
997     TheAISContext()->UpdateCurrentViewer();
998   }
999
1000   return 0;
1001 }
1002
1003 static Standard_Integer VDispSensi (Draw_Interpretor& ,
1004                                     Standard_Integer  theArgNb,
1005                                     Standard_CString* )
1006 {
1007   if (theArgNb > 1)
1008   {
1009     std::cout << "Error: wrong syntax!\n";
1010     return 1;
1011   }
1012
1013   Handle(AIS_InteractiveContext) aCtx;
1014   Handle(V3d_View)               aView;
1015   if (!getCtxAndView (aCtx, aView))
1016   {
1017     return 1;
1018   }
1019
1020   aCtx->DisplayActiveSensitive (aView);
1021   return 0;
1022
1023 }
1024
1025 static Standard_Integer VClearSensi (Draw_Interpretor& ,
1026                                      Standard_Integer  theArgNb,
1027                                      Standard_CString* )
1028 {
1029   if (theArgNb > 1)
1030   {
1031     std::cout << "Error: wrong syntax!\n";
1032     return 1;
1033   }
1034
1035   Handle(AIS_InteractiveContext) aCtx;
1036   Handle(V3d_View)               aView;
1037   if (!getCtxAndView (aCtx, aView))
1038   {
1039     return 1;
1040   }
1041   aCtx->ClearActiveSensitive (aView);
1042   return 0;
1043 }
1044
1045 //==============================================================================
1046 //function : VDir
1047 //purpose  : To list the displayed object with their attributes
1048 //==============================================================================
1049 static int VDir (Draw_Interpretor& theDI,
1050                  Standard_Integer theNbArgs,
1051                  const char** theArgVec)
1052 {
1053   TCollection_AsciiString aMatch;
1054   Standard_Boolean toFormat = Standard_False;
1055   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
1056   {
1057     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
1058     anArgCase.LowerCase();
1059     if (anArgCase == "-list"
1060      || anArgCase == "-format")
1061     {
1062       toFormat = Standard_True;
1063     }
1064     else if (aMatch.IsEmpty())
1065     {
1066       aMatch = theArgVec[anArgIter];
1067     }
1068     else
1069     {
1070       std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
1071       return 1;
1072     }
1073   }
1074
1075   TCollection_AsciiString aRes;
1076   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
1077   {
1078     if (!aMatch.IsEmpty())
1079     {
1080       const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aMatch + "' '" + anIter.Key2() + "'";
1081       if (theDI.Eval (aCheck.ToCString()) == 0
1082       && *theDI.Result() != '1')
1083       {
1084         continue;
1085       }
1086     }
1087
1088     if (toFormat)
1089     {
1090       aRes += TCollection_AsciiString("\t") + anIter.Key2() + "\n";
1091     }
1092     else
1093     {
1094       aRes += anIter.Key2() + " ";
1095     }
1096   }
1097   theDI.Reset();
1098   theDI << aRes;
1099   return 0;
1100 }
1101
1102 //! Auxiliary enumeration
1103 enum ViewerTest_StereoPair
1104 {
1105   ViewerTest_SP_Single,
1106   ViewerTest_SP_SideBySide,
1107   ViewerTest_SP_OverUnder
1108 };
1109
1110 //==============================================================================
1111 //function : VDump
1112 //purpose  : To dump the active view snapshot to image file
1113 //==============================================================================
1114 static Standard_Integer VDump (Draw_Interpretor& theDI,
1115                                Standard_Integer  theArgNb,
1116                                Standard_CString* theArgVec)
1117 {
1118   if (theArgNb < 2)
1119   {
1120     std::cout << "Error: wrong number of arguments! Image file name should be specified at least.\n";
1121     return 1;
1122   }
1123
1124   Standard_Integer      anArgIter   = 1;
1125   Standard_CString      aFilePath   = theArgVec[anArgIter++];
1126   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
1127   V3d_ImageDumpOptions  aParams;
1128   aParams.BufferType    = Graphic3d_BT_RGB;
1129   aParams.StereoOptions = V3d_SDO_MONO;
1130   for (; anArgIter < theArgNb; ++anArgIter)
1131   {
1132     TCollection_AsciiString anArg (theArgVec[anArgIter]);
1133     anArg.LowerCase();
1134     if (anArg == "-buffer")
1135     {
1136       if (++anArgIter >= theArgNb)
1137       {
1138         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
1139         return 1;
1140       }
1141
1142       TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
1143       aBufArg.LowerCase();
1144       if (aBufArg == "rgba")
1145       {
1146         aParams.BufferType = Graphic3d_BT_RGBA;
1147       }
1148       else if (aBufArg == "rgb")
1149       {
1150         aParams.BufferType = Graphic3d_BT_RGB;
1151       }
1152       else if (aBufArg == "depth")
1153       {
1154         aParams.BufferType = Graphic3d_BT_Depth;
1155       }
1156       else
1157       {
1158         std::cout << "Error: unknown buffer '" << aBufArg << "'\n";
1159         return 1;
1160       }
1161     }
1162     else if (anArg == "-stereo")
1163     {
1164       if (++anArgIter >= theArgNb)
1165       {
1166         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
1167         return 1;
1168       }
1169
1170       TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
1171       aStereoArg.LowerCase();
1172       if (aStereoArg == "l"
1173        || aStereoArg == "left")
1174       {
1175         aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1176       }
1177       else if (aStereoArg == "r"
1178             || aStereoArg == "right")
1179       {
1180         aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1181       }
1182       else if (aStereoArg == "mono")
1183       {
1184         aParams.StereoOptions = V3d_SDO_MONO;
1185       }
1186       else if (aStereoArg == "blended"
1187             || aStereoArg == "blend"
1188             || aStereoArg == "stereo")
1189       {
1190         aParams.StereoOptions = V3d_SDO_BLENDED;
1191       }
1192       else if (aStereoArg == "sbs"
1193             || aStereoArg == "sidebyside")
1194       {
1195         aStereoPair = ViewerTest_SP_SideBySide;
1196       }
1197       else if (aStereoArg == "ou"
1198             || aStereoArg == "overunder")
1199       {
1200         aStereoPair = ViewerTest_SP_OverUnder;
1201       }
1202       else
1203       {
1204         std::cout << "Error: unknown stereo format '" << aStereoArg << "'\n";
1205         return 1;
1206       }
1207     }
1208     else if (anArg == "-rgba"
1209           || anArg ==  "rgba")
1210     {
1211       aParams.BufferType = Graphic3d_BT_RGBA;
1212     }
1213     else if (anArg == "-rgb"
1214           || anArg ==  "rgb")
1215     {
1216       aParams.BufferType = Graphic3d_BT_RGB;
1217     }
1218     else if (anArg == "-depth"
1219           || anArg ==  "depth")
1220     {
1221       aParams.BufferType = Graphic3d_BT_Depth;
1222     }
1223     else if (anArg == "-width"
1224           || anArg ==  "width"
1225           || anArg ==  "sizex")
1226     {
1227       if (aParams.Width != 0)
1228       {
1229         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
1230         return 1;
1231       }
1232       else if (++anArgIter >= theArgNb)
1233       {
1234         std::cout << "Error: integer value is expected right after 'width'\n";
1235         return 1;
1236       }
1237       aParams.Width = Draw::Atoi (theArgVec[anArgIter]);
1238     }
1239     else if (anArg == "-height"
1240           || anArg ==  "height"
1241           || anArg ==  "-sizey")
1242     {
1243       if (aParams.Height != 0)
1244       {
1245         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
1246         return 1;
1247       }
1248       else if (++anArgIter >= theArgNb)
1249       {
1250         std::cout << "Error: integer value is expected right after 'height'\n";
1251         return 1;
1252       }
1253       aParams.Height = Draw::Atoi (theArgVec[anArgIter]);
1254     }
1255     else if (anArg == "-tile"
1256           || anArg == "-tilesize")
1257     {
1258       if (++anArgIter >= theArgNb)
1259       {
1260         std::cout << "Error: integer value is expected right after 'tileSize'\n";
1261         return 1;
1262       }
1263       aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
1264     }
1265     else
1266     {
1267       std::cout << "Error: unknown argument '" << theArgVec[anArgIter] << "'\n";
1268       return 1;
1269     }
1270   }
1271   if ((aParams.Width <= 0 && aParams.Height >  0)
1272    || (aParams.Width >  0 && aParams.Height <= 0))
1273   {
1274     std::cout << "Error: dimensions " << aParams.Width << "x" << aParams.Height << " are incorrect\n";
1275     return 1;
1276   }
1277
1278   Handle(V3d_View) aView = ViewerTest::CurrentView();
1279   if (aView.IsNull())
1280   {
1281     std::cout << "Error: cannot find an active view!\n";
1282     return 1;
1283   }
1284
1285   if (aParams.Width <= 0 || aParams.Height <= 0)
1286   {
1287     aView->Window()->Size (aParams.Width, aParams.Height);
1288   }
1289
1290   Image_AlienPixMap aPixMap;
1291   Image_Format aFormat = Image_Format_UNKNOWN;
1292   switch (aParams.BufferType)
1293   {
1294     case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
1295     case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
1296     case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
1297     case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
1298   }
1299
1300   switch (aStereoPair)
1301   {
1302     case ViewerTest_SP_Single:
1303     {
1304       if (!aView->ToPixMap (aPixMap, aParams))
1305       {
1306         theDI << "Fail: view dump failed!\n";
1307         return 0;
1308       }
1309       else if (aPixMap.SizeX() != Standard_Size(aParams.Width)
1310             || aPixMap.SizeY() != Standard_Size(aParams.Height))
1311       {
1312         theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
1313               << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
1314       }
1315       break;
1316     }
1317     case ViewerTest_SP_SideBySide:
1318     {
1319       if (!aPixMap.InitZero (aFormat, aParams.Width * 2, aParams.Height))
1320       {
1321         theDI << "Fail: not enough memory for image allocation!\n";
1322         return 0;
1323       }
1324
1325       Image_PixMap aPixMapL, aPixMapR;
1326       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1327                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1328       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aParams.Width,
1329                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1330
1331       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1332       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1333       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1334       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1335       if (!isOk)
1336       {
1337         theDI << "Fail: view dump failed!\n";
1338         return 0;
1339       }
1340       break;
1341     }
1342     case ViewerTest_SP_OverUnder:
1343     {
1344       if (!aPixMap.InitZero (aFormat, aParams.Width, aParams.Height * 2))
1345       {
1346         theDI << "Fail: not enough memory for image allocation!\n";
1347         return 0;
1348       }
1349
1350       Image_PixMap aPixMapL, aPixMapR;
1351       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1352                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1353       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
1354                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1355
1356       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1357       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1358       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1359       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1360       if (!isOk)
1361       {
1362         theDI << "Fail: view dump failed!\n";
1363         return 0;
1364       }
1365       break;
1366     }
1367   }
1368
1369   if (!aPixMap.Save (aFilePath))
1370   {
1371     theDI << "Fail: image can not be saved!\n";
1372   }
1373   return 0;
1374 }
1375
1376 enum TypeOfDispOperation
1377 {
1378   TypeOfDispOperation_SetDispMode,
1379   TypeOfDispOperation_UnsetDispMode
1380 };
1381
1382 //! Displays,Erase...
1383 static void VwrTst_DispErase (const Handle(AIS_InteractiveObject)& thePrs,
1384                                                 const Standard_Integer theMode,
1385                                                 const TypeOfDispOperation theType,
1386                                                 const Standard_Boolean theToUpdate)
1387 {
1388   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1389   switch (theType)
1390   {
1391     case TypeOfDispOperation_SetDispMode:
1392     {
1393       if (!thePrs.IsNull())
1394       {
1395         aCtx->SetDisplayMode (thePrs, theMode, theToUpdate);
1396       }
1397       else
1398       {
1399         aCtx->SetDisplayMode ((AIS_DisplayMode )theMode, theToUpdate);
1400       }
1401       break;
1402     }
1403     case TypeOfDispOperation_UnsetDispMode:
1404     {
1405       if (!thePrs.IsNull())
1406       {
1407         aCtx->UnsetDisplayMode (thePrs, theToUpdate);
1408       }
1409       else
1410       {
1411         aCtx->SetDisplayMode (AIS_WireFrame, theToUpdate);
1412       }
1413       break;
1414     }
1415   }
1416 }
1417
1418 //=======================================================================
1419 //function :
1420 //purpose  :
1421 //=======================================================================
1422 static int VDispMode (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1423 {
1424   if (argc < 1
1425    || argc > 3)
1426   {
1427     std::cout << "Syntax error: wrong number of arguments\n";
1428     return 1;
1429   }
1430
1431   TypeOfDispOperation aType = TCollection_AsciiString (argv[0]) == "vunsetdispmode"
1432                             ? TypeOfDispOperation_UnsetDispMode
1433                             : TypeOfDispOperation_SetDispMode;
1434   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1435   if (aType == TypeOfDispOperation_UnsetDispMode)
1436   {
1437     if (argc == 1)
1438     {
1439       if (aCtx->NbSelected() == 0)
1440       {
1441         VwrTst_DispErase (Handle(AIS_InteractiveObject)(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1442       }
1443       else
1444       {
1445         for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1446         {
1447           VwrTst_DispErase (aCtx->SelectedInteractive(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1448         }
1449       }
1450       aCtx->UpdateCurrentViewer();
1451     }
1452     else
1453     {
1454       TCollection_AsciiString aName = argv[1];
1455       Handle(AIS_InteractiveObject) aPrs;
1456       if (GetMapOfAIS().Find2 (aName, aPrs)
1457       && !aPrs.IsNull())
1458       {
1459         VwrTst_DispErase (aPrs, -1, TypeOfDispOperation_UnsetDispMode, Standard_True);
1460       }
1461     }
1462   }
1463   else if (argc == 2)
1464   {
1465     Standard_Integer aDispMode = Draw::Atoi (argv[1]);
1466     if (aCtx->NbSelected() == 0
1467      && aType == TypeOfDispOperation_SetDispMode)
1468     {
1469       VwrTst_DispErase (Handle(AIS_InteractiveObject)(), aDispMode, TypeOfDispOperation_SetDispMode, Standard_True);
1470     }
1471     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1472     {
1473       VwrTst_DispErase (aCtx->SelectedInteractive(), aDispMode, aType, Standard_False);
1474     }
1475     aCtx->UpdateCurrentViewer();
1476   }
1477   else
1478   {
1479     Handle(AIS_InteractiveObject) aPrs;
1480     TCollection_AsciiString aName (argv[1]);
1481     if (GetMapOfAIS().Find2 (aName, aPrs)
1482      && !aPrs.IsNull())
1483     {
1484       VwrTst_DispErase (aPrs, Draw::Atoi(argv[2]), aType, Standard_True);
1485     }
1486   }
1487   return 0;
1488 }
1489
1490
1491 //=======================================================================
1492 //function :
1493 //purpose  :
1494 //=======================================================================
1495 static int VSubInt(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1496 {
1497   if(argc==1) return 1;
1498   Standard_Integer On = Draw::Atoi(argv[1]);
1499   const Handle(AIS_InteractiveContext)& Ctx = ViewerTest::GetAISContext();
1500
1501   if(argc==2)
1502   {
1503     TCollection_AsciiString isOnOff = On == 1 ? "on" : "off";
1504     di << "Sub intensite is turned " << isOnOff << " for " << Ctx->NbSelected() << "objects\n";
1505     for (Ctx->InitSelected(); Ctx->MoreSelected(); Ctx->NextSelected())
1506     {
1507       if(On==1)
1508       {
1509         Ctx->SubIntensityOn (Ctx->SelectedInteractive(), Standard_False);
1510       }
1511       else
1512       {
1513         Ctx->SubIntensityOff (Ctx->SelectedInteractive(), Standard_False);
1514       }
1515     }
1516
1517     Ctx->UpdateCurrentViewer();
1518   }
1519   else {
1520     Handle(AIS_InteractiveObject) IO;
1521     TCollection_AsciiString name = argv[2];
1522     if (GetMapOfAIS().Find2 (name, IO)
1523     && !IO.IsNull())
1524     {
1525       if(On==1)
1526         Ctx->SubIntensityOn(IO, Standard_True);
1527       else
1528         Ctx->SubIntensityOff(IO, Standard_True);
1529     }
1530     else return 1;
1531   }
1532   return 0;
1533 }
1534
1535 //! Auxiliary class to iterate presentations from different collections.
1536 class ViewTest_PrsIter
1537 {
1538 public:
1539
1540   //! Create and initialize iterator object.
1541   ViewTest_PrsIter (const TCollection_AsciiString& theName)
1542   : mySource (IterSource_All)
1543   {
1544     NCollection_Sequence<TCollection_AsciiString> aNames;
1545     if (!theName.IsEmpty())
1546     aNames.Append (theName);
1547     Init (aNames);
1548   }
1549
1550   //! Create and initialize iterator object.
1551   ViewTest_PrsIter (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1552   : mySource (IterSource_All)
1553   {
1554     Init (theNames);
1555   }
1556
1557   //! Initialize the iterator.
1558   void Init (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1559   {
1560     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1561     mySeq = theNames;
1562     mySelIter.Nullify();
1563     myCurrent.Nullify();
1564     myCurrentTrs.Nullify();
1565     if (!mySeq.IsEmpty())
1566     {
1567       mySource = IterSource_List;
1568       mySeqIter = NCollection_Sequence<TCollection_AsciiString>::Iterator (mySeq);
1569     }
1570     else if (aCtx->NbSelected() > 0)
1571     {
1572       mySource  = IterSource_Selected;
1573       mySelIter = aCtx;
1574       mySelIter->InitSelected();
1575     }
1576     else
1577     {
1578       mySource = IterSource_All;
1579       myMapIter.Initialize (GetMapOfAIS());
1580     }
1581     initCurrent();
1582   }
1583
1584   const TCollection_AsciiString& CurrentName() const
1585   {
1586     return myCurrentName;
1587   }
1588
1589   const Handle(AIS_InteractiveObject)& Current() const
1590   {
1591     return myCurrent;
1592   }
1593
1594   const Handle(Standard_Transient)& CurrentTrs() const
1595   {
1596     return myCurrentTrs;
1597   }
1598
1599   //! @return true if iterator points to valid object within collection
1600   Standard_Boolean More() const
1601   {
1602     switch (mySource)
1603     {
1604       case IterSource_All:      return myMapIter.More();
1605       case IterSource_List:     return mySeqIter.More();
1606       case IterSource_Selected: return mySelIter->MoreSelected();
1607     }
1608     return Standard_False;
1609   }
1610
1611   //! Go to the next item.
1612   void Next()
1613   {
1614     myCurrentName.Clear();
1615     myCurrentTrs.Nullify();
1616     myCurrent.Nullify();
1617     switch (mySource)
1618     {
1619       case IterSource_All:
1620       {
1621         myMapIter.Next();
1622         break;
1623       }
1624       case IterSource_List:
1625       {
1626         mySeqIter.Next();
1627         break;
1628       }
1629       case IterSource_Selected:
1630       {
1631         mySelIter->NextSelected();
1632         break;
1633       }
1634     }
1635     initCurrent();
1636   }
1637
1638 private:
1639
1640   void initCurrent()
1641   {
1642     switch (mySource)
1643     {
1644       case IterSource_All:
1645       {
1646         if (myMapIter.More())
1647         {
1648           myCurrentName = myMapIter.Key2();
1649           myCurrentTrs  = myMapIter.Key1();
1650           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1651         }
1652         break;
1653       }
1654       case IterSource_List:
1655       {
1656         if (mySeqIter.More())
1657         {
1658           if (!GetMapOfAIS().IsBound2 (mySeqIter.Value()))
1659           {
1660             std::cout << "Error: object " << mySeqIter.Value() << " is not displayed!\n";
1661             return;
1662           }
1663           myCurrentName = mySeqIter.Value();
1664           myCurrentTrs  = GetMapOfAIS().Find2 (mySeqIter.Value());
1665           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1666         }
1667         break;
1668       }
1669       case IterSource_Selected:
1670       {
1671         if (mySelIter->MoreSelected())
1672         {
1673           myCurrentName = GetMapOfAIS().Find1 (mySelIter->SelectedInteractive());
1674           myCurrent     = mySelIter->SelectedInteractive();
1675         }
1676         break;
1677       }
1678     }
1679   }
1680
1681 private:
1682
1683   enum IterSource
1684   {
1685     IterSource_All,
1686     IterSource_List,
1687     IterSource_Selected
1688   };
1689
1690 private:
1691
1692   Handle(AIS_InteractiveContext) mySelIter;    //!< iterator for current (selected) objects (IterSource_Selected)
1693   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName myMapIter; //!< iterator for map of all objects (IterSource_All)
1694   NCollection_Sequence<TCollection_AsciiString>           mySeq;
1695   NCollection_Sequence<TCollection_AsciiString>::Iterator mySeqIter;
1696
1697   TCollection_AsciiString        myCurrentName;//!< current item name
1698   Handle(Standard_Transient)     myCurrentTrs; //!< current item (as transient object)
1699   Handle(AIS_InteractiveObject)  myCurrent;    //!< current item
1700
1701   IterSource                     mySource;     //!< iterated collection
1702
1703 };
1704
1705 //! Parse interior style name.
1706 static bool parseInteriorStyle (const TCollection_AsciiString& theArg,
1707                                 Aspect_InteriorStyle& theStyle)
1708 {
1709   TCollection_AsciiString anArg (theArg);
1710   anArg.LowerCase();
1711   if (anArg == "empty")
1712   {
1713     theStyle = Aspect_IS_EMPTY;
1714   }
1715   else if (anArg == "hollow")
1716   {
1717     theStyle = Aspect_IS_HOLLOW;
1718   }
1719   else if (anArg == "solid")
1720   {
1721     theStyle = Aspect_IS_SOLID;
1722   }
1723   else if (anArg == "hatch")
1724   {
1725     theStyle = Aspect_IS_HATCH;
1726   }
1727   else if (anArg == "hiddenline"
1728         || anArg == "hidden-line"
1729         || anArg == "hidden_line")
1730   {
1731     theStyle = Aspect_IS_HIDDENLINE;
1732   }
1733   else if (anArg == "point")
1734   {
1735     theStyle = Aspect_IS_POINT;
1736   }
1737   else if (theArg.IsIntegerValue())
1738   {
1739     const Standard_Integer anIntStyle = theArg.IntegerValue();
1740     if (anIntStyle < Aspect_IS_EMPTY || anIntStyle > Aspect_IS_POINT)
1741     {
1742       return false;
1743     }
1744     theStyle = (Aspect_InteriorStyle)anIntStyle;
1745   }
1746   else
1747   {
1748     return false;
1749   }
1750   return true;
1751 }
1752
1753 //! Auxiliary structure for VAspects
1754 struct ViewerTest_AspectsChangeSet
1755 {
1756   Standard_Integer             ToSetVisibility;
1757   Standard_Integer             Visibility;
1758
1759   Standard_Integer             ToSetColor;
1760   Quantity_Color               Color;
1761   Standard_Integer             ToSetBackFaceColor;
1762   Quantity_Color               BackFaceColor;
1763
1764   Standard_Integer             ToSetLineWidth;
1765   Standard_Real                LineWidth;
1766
1767   Standard_Integer             ToSetTypeOfLine;
1768   Aspect_TypeOfLine            TypeOfLine;
1769
1770   Standard_Integer             ToSetTypeOfMarker;
1771   Aspect_TypeOfMarker          TypeOfMarker;
1772   Handle(Image_PixMap)         MarkerImage;
1773
1774   Standard_Integer             ToSetMarkerSize;
1775   Standard_Real                MarkerSize;
1776
1777   Standard_Integer             ToSetTransparency;
1778   Standard_Real                Transparency;
1779
1780   Standard_Integer             ToSetAlphaMode;
1781   Graphic3d_AlphaMode          AlphaMode;
1782   Standard_ShortReal           AlphaCutoff;
1783
1784   Standard_Integer             ToSetMaterial;
1785   Graphic3d_NameOfMaterial     Material;
1786   TCollection_AsciiString      MatName;
1787
1788   NCollection_Sequence<TopoDS_Shape> SubShapes;
1789
1790   Standard_Integer             ToSetShowFreeBoundary;
1791   Standard_Integer             ToSetFreeBoundaryWidth;
1792   Standard_Real                FreeBoundaryWidth;
1793   Standard_Integer             ToSetFreeBoundaryColor;
1794   Quantity_Color               FreeBoundaryColor;
1795
1796   Standard_Integer             ToEnableIsoOnTriangulation;
1797
1798   Standard_Integer             ToSetFaceBoundaryDraw;
1799   Standard_Integer             ToSetFaceBoundaryUpperContinuity;
1800   GeomAbs_Shape                FaceBoundaryUpperContinuity;
1801
1802   Standard_Integer             ToSetFaceBoundaryColor;
1803   Quantity_Color               FaceBoundaryColor;
1804
1805   Standard_Integer             ToSetFaceBoundaryWidth;
1806   Standard_Real                FaceBoundaryWidth;
1807
1808   Standard_Integer             ToSetTypeOfFaceBoundaryLine;
1809   Aspect_TypeOfLine            TypeOfFaceBoundaryLine;
1810
1811   Standard_Integer             ToSetMaxParamValue;
1812   Standard_Real                MaxParamValue;
1813
1814   Standard_Integer             ToSetSensitivity;
1815   Standard_Integer             SelectionMode;
1816   Standard_Integer             Sensitivity;
1817
1818   Standard_Integer             ToSetHatch;
1819   Standard_Integer             StdHatchStyle;
1820   TCollection_AsciiString      PathToHatchPattern;
1821
1822   Standard_Integer             ToSetShadingModel;
1823   Graphic3d_TypeOfShadingModel ShadingModel;
1824   TCollection_AsciiString      ShadingModelName;
1825
1826   Standard_Integer             ToSetInterior;
1827   Aspect_InteriorStyle         InteriorStyle;
1828
1829   Standard_Integer             ToSetDrawSilhouette;
1830
1831   Standard_Integer             ToSetDrawEdges;
1832   Standard_Integer             ToSetQuadEdges;
1833
1834   Standard_Integer             ToSetEdgeColor;
1835   Quantity_ColorRGBA           EdgeColor;
1836
1837   Standard_Integer             ToSetEdgeWidth;
1838   Standard_Real                EdgeWidth;
1839
1840   Standard_Integer             ToSetTypeOfEdge;
1841   Aspect_TypeOfLine            TypeOfEdge;
1842
1843   //! Empty constructor
1844   ViewerTest_AspectsChangeSet()
1845   : ToSetVisibility   (0),
1846     Visibility        (1),
1847     ToSetColor        (0),
1848     Color             (DEFAULT_COLOR),
1849     ToSetBackFaceColor(0),
1850     BackFaceColor     (DEFAULT_COLOR),
1851     ToSetLineWidth    (0),
1852     LineWidth         (1.0),
1853     ToSetTypeOfLine   (0),
1854     TypeOfLine        (Aspect_TOL_SOLID),
1855     ToSetTypeOfMarker (0),
1856     TypeOfMarker      (Aspect_TOM_PLUS),
1857     ToSetMarkerSize   (0),
1858     MarkerSize        (1.0),
1859     ToSetTransparency (0),
1860     Transparency      (0.0),
1861     ToSetAlphaMode    (0),
1862     AlphaMode         (Graphic3d_AlphaMode_BlendAuto),
1863     AlphaCutoff       (0.5f),
1864     ToSetMaterial     (0),
1865     Material          (Graphic3d_NOM_DEFAULT),
1866     ToSetShowFreeBoundary      (0),
1867     ToSetFreeBoundaryWidth     (0),
1868     FreeBoundaryWidth          (1.0),
1869     ToSetFreeBoundaryColor     (0),
1870     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
1871     ToEnableIsoOnTriangulation (0),
1872     //
1873     ToSetFaceBoundaryDraw      (0),
1874     ToSetFaceBoundaryUpperContinuity (0),
1875     FaceBoundaryUpperContinuity(GeomAbs_CN),
1876     ToSetFaceBoundaryColor     (0),
1877     FaceBoundaryColor          (Quantity_NOC_BLACK),
1878     ToSetFaceBoundaryWidth     (0),
1879     FaceBoundaryWidth          (1.0f),
1880     ToSetTypeOfFaceBoundaryLine(0),
1881     TypeOfFaceBoundaryLine     (Aspect_TOL_SOLID),
1882     //
1883     ToSetMaxParamValue         (0),
1884     MaxParamValue              (500000),
1885     ToSetSensitivity           (0),
1886     SelectionMode              (-1),
1887     Sensitivity                (-1),
1888     ToSetHatch                 (0),
1889     StdHatchStyle              (-1),
1890     ToSetShadingModel          (0),
1891     ShadingModel               (Graphic3d_TOSM_DEFAULT),
1892     ToSetInterior              (0),
1893     InteriorStyle              (Aspect_IS_SOLID),
1894     ToSetDrawSilhouette (0),
1895     ToSetDrawEdges    (0),
1896     ToSetQuadEdges    (0),
1897     ToSetEdgeColor    (0),
1898     ToSetEdgeWidth    (0),
1899     EdgeWidth         (1.0),
1900     ToSetTypeOfEdge   (0),
1901     TypeOfEdge        (Aspect_TOL_SOLID)
1902     {}
1903
1904   //! @return true if no changes have been requested
1905   Standard_Boolean IsEmpty() const
1906   {
1907     return ToSetVisibility        == 0
1908         && ToSetLineWidth         == 0
1909         && ToSetTransparency      == 0
1910         && ToSetAlphaMode         == 0
1911         && ToSetColor             == 0
1912         && ToSetBackFaceColor     == 0
1913         && ToSetMaterial          == 0
1914         && ToSetShowFreeBoundary  == 0
1915         && ToSetFreeBoundaryColor == 0
1916         && ToSetFreeBoundaryWidth == 0
1917         && ToEnableIsoOnTriangulation == 0
1918         && ToSetFaceBoundaryDraw == 0
1919         && ToSetFaceBoundaryUpperContinuity == 0
1920         && ToSetFaceBoundaryColor == 0
1921         && ToSetFaceBoundaryWidth == 0
1922         && ToSetTypeOfFaceBoundaryLine == 0
1923         && ToSetMaxParamValue     == 0
1924         && ToSetSensitivity       == 0
1925         && ToSetHatch             == 0
1926         && ToSetShadingModel      == 0
1927         && ToSetInterior          == 0
1928         && ToSetDrawSilhouette    == 0
1929         && ToSetDrawEdges         == 0
1930         && ToSetQuadEdges         == 0
1931         && ToSetEdgeColor         == 0
1932         && ToSetEdgeWidth         == 0
1933         && ToSetTypeOfEdge        == 0;
1934   }
1935
1936   //! @return true if properties are valid
1937   Standard_Boolean Validate() const
1938   {
1939     Standard_Boolean isOk = Standard_True;
1940     if (Visibility != 0 && Visibility != 1)
1941     {
1942       std::cout << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")\n";
1943       isOk = Standard_False;
1944     }
1945     if (LineWidth <= 0.0
1946      || LineWidth >  10.0)
1947     {
1948       std::cout << "Error: the width should be within [1; 10] range (specified " << LineWidth << ")\n";
1949       isOk = Standard_False;
1950     }
1951     if (Transparency < 0.0
1952      || Transparency > 1.0)
1953     {
1954       std::cout << "Error: the transparency should be within [0; 1] range (specified " << Transparency << ")\n";
1955       isOk = Standard_False;
1956     }
1957     if (ToSetAlphaMode == 1
1958      && (AlphaCutoff <= 0.0f || AlphaCutoff >= 1.0f))
1959     {
1960       std::cout << "Error: alpha cutoff value should be within (0; 1) range (specified " << AlphaCutoff << ")\n";
1961       isOk = Standard_False;
1962     }
1963     if (FreeBoundaryWidth <= 0.0
1964      || FreeBoundaryWidth >  10.0)
1965     {
1966       std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
1967       isOk = Standard_False;
1968     }
1969     if (MaxParamValue < 0.0)
1970     {
1971       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
1972       isOk = Standard_False;
1973     }
1974     if (Sensitivity <= 0 && ToSetSensitivity)
1975     {
1976       std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
1977       isOk = Standard_False;
1978     }
1979     if (ToSetHatch == 1 && StdHatchStyle < 0 && PathToHatchPattern == "")
1980     {
1981       std::cout << "Error: hatch style must be specified\n";
1982       isOk = Standard_False;
1983     }
1984     if (ToSetShadingModel == 1
1985     && (ShadingModel < Graphic3d_TOSM_DEFAULT || ShadingModel > Graphic3d_TOSM_FRAGMENT))
1986     {
1987       std::cout << "Error: unknown shading model " << ShadingModelName << ".\n";
1988       isOk = Standard_False;
1989     }
1990     return isOk;
1991   }
1992
1993   //! Apply aspects to specified drawer.
1994   bool Apply (const Handle(Prs3d_Drawer)& theDrawer)
1995   {
1996     bool toRecompute = false;
1997     const Handle(Prs3d_Drawer)& aDefDrawer = ViewerTest::GetAISContext()->DefaultDrawer();
1998     if (ToSetShowFreeBoundary != 0)
1999     {
2000       theDrawer->SetFreeBoundaryDraw (ToSetShowFreeBoundary == 1);
2001       toRecompute = true;
2002     }
2003     if (ToSetFreeBoundaryWidth != 0)
2004     {
2005       if (ToSetFreeBoundaryWidth != -1
2006        || theDrawer->HasOwnFreeBoundaryAspect())
2007       {
2008         if (!theDrawer->HasOwnFreeBoundaryAspect())
2009         {
2010           Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2011           *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
2012           theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2013           toRecompute = true;
2014         }
2015         theDrawer->FreeBoundaryAspect()->SetWidth (FreeBoundaryWidth);
2016       }
2017     }
2018     if (ToSetFreeBoundaryColor != 0)
2019     {
2020       Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2021       *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
2022       aBoundaryAspect->SetColor (FreeBoundaryColor);
2023       theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2024       toRecompute = true;
2025     }
2026     if (ToSetTypeOfLine != 0)
2027     {
2028       if (ToSetTypeOfLine != -1
2029        || theDrawer->HasOwnLineAspect()
2030        || theDrawer->HasOwnWireAspect()
2031        || theDrawer->HasOwnFreeBoundaryAspect()
2032        || theDrawer->HasOwnUnFreeBoundaryAspect()
2033        || theDrawer->HasOwnSeenLineAspect())
2034       {
2035         toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
2036         theDrawer->LineAspect()->SetTypeOfLine           (TypeOfLine);
2037         theDrawer->WireAspect()->SetTypeOfLine           (TypeOfLine);
2038         theDrawer->FreeBoundaryAspect()->SetTypeOfLine   (TypeOfLine);
2039         theDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (TypeOfLine);
2040         theDrawer->SeenLineAspect()->SetTypeOfLine       (TypeOfLine);
2041       }
2042     }
2043     if (ToSetTypeOfMarker != 0)
2044     {
2045       if (ToSetTypeOfMarker != -1
2046        || theDrawer->HasOwnPointAspect())
2047       {
2048         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
2049         theDrawer->PointAspect()->SetTypeOfMarker (TypeOfMarker);
2050         theDrawer->PointAspect()->Aspect()->SetMarkerImage (MarkerImage.IsNull() ? Handle(Graphic3d_MarkerImage)() : new Graphic3d_MarkerImage (MarkerImage));
2051       }
2052     }
2053     if (ToSetMarkerSize != 0)
2054     {
2055       if (ToSetMarkerSize != -1
2056        || theDrawer->HasOwnPointAspect())
2057       {
2058         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
2059         theDrawer->PointAspect()->SetScale (MarkerSize);
2060         toRecompute = true;
2061       }
2062     }
2063     if (ToSetMaxParamValue != 0)
2064     {
2065       if (ToSetMaxParamValue != -1
2066        || theDrawer->HasOwnMaximalParameterValue())
2067       {
2068         theDrawer->SetMaximalParameterValue (MaxParamValue);
2069         toRecompute = true;
2070       }
2071     }
2072     if (ToSetFaceBoundaryDraw != 0)
2073     {
2074       if (ToSetFaceBoundaryDraw != -1
2075        || theDrawer->HasOwnFaceBoundaryDraw())
2076       {
2077         toRecompute = true;
2078         theDrawer->SetFaceBoundaryDraw (ToSetFaceBoundaryDraw == 1);
2079       }
2080     }
2081     if (ToSetFaceBoundaryUpperContinuity != 0)
2082     {
2083       if (ToSetFaceBoundaryUpperContinuity != -1
2084        || theDrawer->HasOwnFaceBoundaryUpperContinuity())
2085       {
2086         toRecompute = true;
2087         if (ToSetFaceBoundaryUpperContinuity == -1)
2088         {
2089           theDrawer->UnsetFaceBoundaryUpperContinuity();
2090         }
2091         else
2092         {
2093           theDrawer->SetFaceBoundaryUpperContinuity (FaceBoundaryUpperContinuity);
2094         }
2095       }
2096     }
2097     if (ToSetFaceBoundaryColor != 0)
2098     {
2099       if (ToSetFaceBoundaryColor != -1
2100        || theDrawer->HasOwnFaceBoundaryAspect())
2101       {
2102         if (ToSetFaceBoundaryColor == -1)
2103         {
2104           toRecompute = true;
2105           theDrawer->SetFaceBoundaryAspect (Handle(Prs3d_LineAspect)());
2106         }
2107         else
2108         {
2109           toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2110           theDrawer->FaceBoundaryAspect()->SetColor (FaceBoundaryColor);
2111         }
2112       }
2113     }
2114     if (ToSetFaceBoundaryWidth != 0)
2115     {
2116       if (ToSetFaceBoundaryWidth != -1
2117        || theDrawer->HasOwnFaceBoundaryAspect())
2118       {
2119         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2120         theDrawer->FaceBoundaryAspect()->SetWidth (FaceBoundaryWidth);
2121       }
2122     }
2123     if (ToSetTypeOfFaceBoundaryLine != 0)
2124     {
2125       if (ToSetTypeOfFaceBoundaryLine != -1
2126        || theDrawer->HasOwnFaceBoundaryAspect())
2127       {
2128         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2129         theDrawer->FaceBoundaryAspect()->SetTypeOfLine (TypeOfFaceBoundaryLine);
2130       }
2131     }
2132     if (ToSetShadingModel != 0)
2133     {
2134       if (ToSetShadingModel != -1
2135        || theDrawer->HasOwnShadingAspect())
2136       {
2137         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2138         theDrawer->ShadingAspect()->Aspect()->SetShadingModel (ShadingModel);
2139       }
2140     }
2141     if (ToSetBackFaceColor != 0)
2142     {
2143       if (ToSetBackFaceColor != -1
2144        || theDrawer->HasOwnShadingAspect())
2145       {
2146         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2147         theDrawer->ShadingAspect()->SetColor (BackFaceColor, Aspect_TOFM_BACK_SIDE);
2148       }
2149     }
2150     if (ToSetAlphaMode != 0)
2151     {
2152       if (ToSetAlphaMode != -1
2153        || theDrawer->HasOwnShadingAspect())
2154       {
2155         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2156         theDrawer->ShadingAspect()->Aspect()->SetAlphaMode (AlphaMode, AlphaCutoff);
2157       }
2158     }
2159     if (ToSetHatch != 0)
2160     {
2161       if (ToSetHatch != -1
2162       ||  theDrawer->HasOwnShadingAspect())
2163       {
2164         theDrawer->SetupOwnShadingAspect (aDefDrawer);
2165         Handle(Graphic3d_AspectFillArea3d) anAsp = theDrawer->ShadingAspect()->Aspect();
2166         if (ToSetHatch == -1)
2167         {
2168           anAsp->SetInteriorStyle (Aspect_IS_SOLID);
2169         }
2170         else
2171         {
2172           anAsp->SetInteriorStyle (Aspect_IS_HATCH);
2173           if (!PathToHatchPattern.IsEmpty())
2174           {
2175             Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
2176             if (anImage->Load (TCollection_AsciiString (PathToHatchPattern.ToCString())))
2177             {
2178               anAsp->SetHatchStyle (new Graphic3d_HatchStyle (anImage));
2179             }
2180             else
2181             {
2182               std::cout << "Error: cannot load the following image: " << PathToHatchPattern << "\n";
2183             }
2184           }
2185           else if (StdHatchStyle != -1)
2186           {
2187             anAsp->SetHatchStyle (new Graphic3d_HatchStyle ((Aspect_HatchStyle)StdHatchStyle));
2188           }
2189         }
2190         toRecompute = true;
2191       }
2192     }
2193     if (ToSetInterior != 0)
2194     {
2195       if (ToSetInterior != -1
2196        || theDrawer->HasOwnShadingAspect())
2197       {
2198         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2199         theDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (InteriorStyle);
2200         if (InteriorStyle == Aspect_IS_HATCH
2201          && theDrawer->ShadingAspect()->Aspect()->HatchStyle().IsNull())
2202         {
2203           theDrawer->ShadingAspect()->Aspect()->SetHatchStyle (Aspect_HS_VERTICAL);
2204         }
2205       }
2206     }
2207     if (ToSetDrawSilhouette != 0)
2208     {
2209       if (ToSetDrawSilhouette != -1
2210        || theDrawer->HasOwnShadingAspect())
2211       {
2212         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2213         theDrawer->ShadingAspect()->Aspect()->SetDrawSilhouette (ToSetDrawSilhouette == 1);
2214       }
2215     }
2216     if (ToSetDrawEdges != 0)
2217     {
2218       if (ToSetDrawEdges != -1
2219        || theDrawer->HasOwnShadingAspect())
2220       {
2221         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2222         theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetDrawEdges == 1);
2223       }
2224     }
2225     if (ToSetQuadEdges != 0)
2226     {
2227       if (ToSetQuadEdges != -1
2228           || theDrawer->HasOwnShadingAspect())
2229       {
2230         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2231         theDrawer->ShadingAspect()->Aspect()->SetSkipFirstEdge (ToSetQuadEdges == 1);
2232       }
2233     }
2234     if (ToSetEdgeWidth != 0)
2235     {
2236       if (ToSetEdgeWidth != -1
2237        || theDrawer->HasOwnShadingAspect())
2238       {
2239         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2240         theDrawer->ShadingAspect()->Aspect()->SetEdgeWidth (EdgeWidth);
2241       }
2242     }
2243     if (ToSetTypeOfEdge != 0)
2244     {
2245       if (ToSetTypeOfEdge != -1
2246        || theDrawer->HasOwnShadingAspect())
2247       {
2248         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2249         theDrawer->ShadingAspect()->Aspect()->SetEdgeLineType (TypeOfEdge);
2250         if (ToSetInterior == 0)
2251         {
2252           theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetTypeOfEdge == 1
2253                                                            && TypeOfEdge != Aspect_TOL_EMPTY);
2254         }
2255       }
2256     }
2257     if (ToSetEdgeColor != 0)
2258     {
2259       if (ToSetEdgeColor != -1
2260        || theDrawer->HasOwnShadingAspect())
2261       {
2262         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2263         if (ToSetEdgeColor == -1)
2264         {
2265           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (theDrawer->ShadingAspect()->Aspect()->InteriorColor());
2266         }
2267         else
2268         {
2269           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (EdgeColor);
2270         }
2271       }
2272     }
2273     return toRecompute;
2274   }
2275 };
2276
2277 //==============================================================================
2278 //function : VAspects
2279 //purpose  :
2280 //==============================================================================
2281 static Standard_Integer VAspects (Draw_Interpretor& theDI,
2282                                   Standard_Integer  theArgNb,
2283                                   const char**      theArgVec)
2284 {
2285   TCollection_AsciiString aCmdName (theArgVec[0]);
2286   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2287   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2288   if (aCtx.IsNull())
2289   {
2290     std::cerr << "Error: no active view!\n";
2291     return 1;
2292   }
2293
2294   Standard_Integer anArgIter = 1;
2295   Standard_Boolean isDefaults = Standard_False;
2296   NCollection_Sequence<TCollection_AsciiString> aNames;
2297   for (; anArgIter < theArgNb; ++anArgIter)
2298   {
2299     TCollection_AsciiString anArg = theArgVec[anArgIter];
2300     if (anUpdateTool.parseRedrawMode (anArg))
2301     {
2302       continue;
2303     }
2304     else if (!anArg.IsEmpty()
2305            && anArg.Value (1) != '-')
2306     {
2307       aNames.Append (anArg);
2308     }
2309     else
2310     {
2311       if (anArg == "-defaults")
2312       {
2313         isDefaults = Standard_True;
2314         ++anArgIter;
2315       }
2316       break;
2317     }
2318   }
2319
2320   if (!aNames.IsEmpty() && isDefaults)
2321   {
2322     std::cout << "Error: wrong syntax. If -defaults is used there should not be any objects' names!\n";
2323     return 1;
2324   }
2325
2326   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
2327   aChanges.Append (ViewerTest_AspectsChangeSet());
2328   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
2329
2330   // parse syntax of legacy commands
2331   bool toParseAliasArgs = false;
2332   Standard_Boolean toDump = 0;
2333   Standard_Boolean toCompactDump = 0;
2334   Standard_Integer aDumpDepth = -1;
2335   if (aCmdName == "vsetwidth")
2336   {
2337     if (aNames.IsEmpty()
2338     || !aNames.Last().IsRealValue())
2339     {
2340       std::cout << "Error: not enough arguments!\n";
2341       return 1;
2342     }
2343     aChangeSet->ToSetLineWidth = 1;
2344     aChangeSet->LineWidth = aNames.Last().RealValue();
2345     aNames.Remove (aNames.Length());
2346   }
2347   else if (aCmdName == "vunsetwidth")
2348   {
2349     aChangeSet->ToSetLineWidth = -1;
2350   }
2351   else if (aCmdName == "vsetcolor")
2352   {
2353     if (aNames.IsEmpty())
2354     {
2355       std::cout << "Error: not enough arguments!\n";
2356       return 1;
2357     }
2358     aChangeSet->ToSetColor = 1;
2359
2360     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2361     Standard_Boolean     isOk   = Standard_False;
2362     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
2363     {
2364       aChangeSet->Color = aColor;
2365       aNames.Remove (aNames.Length());
2366       isOk = Standard_True;
2367     }
2368     else if (Quantity_Color::ColorFromHex (aNames.Last().ToCString(), aChangeSet->Color))
2369     {
2370       aNames.Remove (aNames.Length());
2371       isOk = Standard_True;
2372     }
2373     else if (aNames.Length() >= 3)
2374     {
2375       const char* anArgVec[3] =
2376       {
2377         aNames.Value (aNames.Upper() - 2).ToCString(),
2378         aNames.Value (aNames.Upper() - 1).ToCString(),
2379         aNames.Value (aNames.Upper() - 0).ToCString(),
2380       };
2381
2382       Standard_Integer aNbParsed = ViewerTest::ParseColor (3, anArgVec, aChangeSet->Color);
2383       isOk = aNbParsed == 3;
2384       aNames.Remove (aNames.Length());
2385       aNames.Remove (aNames.Length());
2386       aNames.Remove (aNames.Length());
2387     }
2388     if (!isOk)
2389     {
2390       std::cout << "Error: not enough arguments!\n";
2391       return 1;
2392     }
2393   }
2394   else if (aCmdName == "vunsetcolor")
2395   {
2396     aChangeSet->ToSetColor = -1;
2397   }
2398   else if (aCmdName == "vsettransparency")
2399   {
2400     if (aNames.IsEmpty()
2401     || !aNames.Last().IsRealValue())
2402     {
2403       std::cout << "Error: not enough arguments!\n";
2404       return 1;
2405     }
2406     aChangeSet->ToSetTransparency = 1;
2407     aChangeSet->Transparency  = aNames.Last().RealValue();
2408     aNames.Remove (aNames.Length());
2409   }
2410   else if (aCmdName == "vunsettransparency")
2411   {
2412     aChangeSet->ToSetTransparency = -1;
2413   }
2414   else if (aCmdName == "vsetmaterial")
2415   {
2416     if (aNames.IsEmpty())
2417     {
2418       std::cout << "Error: not enough arguments!\n";
2419       return 1;
2420     }
2421     aChangeSet->ToSetMaterial = 1;
2422     aChangeSet->MatName = aNames.Last();
2423     aNames.Remove (aNames.Length());
2424     if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString(), aChangeSet->Material))
2425     {
2426       std::cout << "Syntax error: unknown material '" << aChangeSet->MatName << "'.\n";
2427       return 1;
2428     }
2429   }
2430   else if (aCmdName == "vunsetmaterial")
2431   {
2432     aChangeSet->ToSetMaterial = -1;
2433   }
2434   else if (aCmdName == "vsetinteriorstyle")
2435   {
2436     if (aNames.IsEmpty()
2437     || !aNames.Last().IsRealValue())
2438     {
2439       std::cout << "Error: not enough arguments!\n";
2440       return 1;
2441     }
2442     aChangeSet->ToSetInterior = 1;
2443     if (!parseInteriorStyle (aNames.Last(), aChangeSet->InteriorStyle))
2444     {
2445       std::cout << "Error: wrong syntax at " << aNames.Last() << "\n";
2446       return 1;
2447     }
2448     aNames.Remove (aNames.Length());
2449   }
2450   else if (aCmdName == "vsetedgetype")
2451   {
2452     aChangeSet->ToSetDrawEdges = 1;
2453     toParseAliasArgs = true;
2454   }
2455   else if (aCmdName == "vunsetedgetype")
2456   {
2457     aChangeSet->ToSetDrawEdges  = -1;
2458     aChangeSet->ToSetEdgeColor  = -1;
2459     aChangeSet->ToSetTypeOfEdge = -1;
2460     aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
2461   }
2462   else if (aCmdName == "vshowfaceboundary")
2463   {
2464     aChangeSet->ToSetFaceBoundaryDraw = 1;
2465     toParseAliasArgs = true;
2466     if (aNames.Size() >= 2
2467      && aNames.Value (2).IsIntegerValue())
2468     {
2469       if (aNames.Size() == 7)
2470       {
2471         if (ViewerTest::ParseLineType (aNames.Value (7).ToCString(), aChangeSet->TypeOfFaceBoundaryLine))
2472         {
2473           aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2474           aNames.Remove (7);
2475         }
2476       }
2477       if (aNames.Size() == 6
2478        && aNames.Value (6).IsRealValue())
2479       {
2480         aChangeSet->ToSetFaceBoundaryWidth = 1;
2481         aChangeSet->FaceBoundaryWidth = aNames.Value (6).RealValue();
2482         aNames.Remove (6);
2483       }
2484       if (aNames.Size() == 5
2485        && aNames.Value (3).IsIntegerValue()
2486        && aNames.Value (4).IsIntegerValue()
2487        && aNames.Value (5).IsIntegerValue())
2488       {
2489         aChangeSet->ToSetFaceBoundaryColor = 1;
2490         aChangeSet->FaceBoundaryColor = Quantity_Color (aNames.Value (3).IntegerValue() / 255.0,
2491                                                         aNames.Value (4).IntegerValue() / 255.0,
2492                                                         aNames.Value (5).IntegerValue() / 255.0,
2493                                                         Quantity_TOC_RGB);
2494         aNames.Remove (5);
2495         aNames.Remove (4);
2496         aNames.Remove (3);
2497       }
2498       if (aNames.Size() == 2)
2499       {
2500         toParseAliasArgs = false;
2501         aChangeSet->ToSetFaceBoundaryDraw = aNames.Value (2).IntegerValue() == 1 ? 1 : -1;
2502         aNames.Remove (2);
2503       }
2504     }
2505   }
2506   else if (anArgIter >= theArgNb)
2507   {
2508     std::cout << "Error: not enough arguments!\n";
2509     return 1;
2510   }
2511
2512   if (!aChangeSet->IsEmpty()
2513    && !toParseAliasArgs)
2514   {
2515     anArgIter = theArgNb;
2516   }
2517   for (; anArgIter < theArgNb; ++anArgIter)
2518   {
2519     TCollection_AsciiString anArg = theArgVec[anArgIter];
2520     anArg.LowerCase();
2521     if (anArg == "-setwidth"
2522      || anArg == "-width"
2523      || anArg == "-setlinewidth"
2524      || anArg == "-linewidth"
2525      || anArg == "-setedgewidth"
2526      || anArg == "-setedgeswidth"
2527      || anArg == "-edgewidth"
2528      || anArg == "-edgeswidth"
2529      || anArg == "-setfaceboundarywidth"
2530      || anArg == "-setboundarywidth"
2531      || anArg == "-faceboundarywidth"
2532      || anArg == "-boundarywidth")
2533     {
2534       if (++anArgIter >= theArgNb)
2535       {
2536         std::cout << "Error: wrong syntax at " << anArg << "\n";
2537         return 1;
2538       }
2539
2540       const Standard_Real aWidth = Draw::Atof (theArgVec[anArgIter]);
2541       if (anArg == "-setedgewidth"
2542        || anArg == "-setedgeswidth"
2543        || anArg == "-edgewidth"
2544        || anArg == "-edgeswidth"
2545        || aCmdName == "vsetedgetype")
2546       {
2547         aChangeSet->ToSetEdgeWidth = 1;
2548         aChangeSet->EdgeWidth = aWidth;
2549       }
2550       else if (anArg == "-setfaceboundarywidth"
2551             || anArg == "-setboundarywidth"
2552             || anArg == "-faceboundarywidth"
2553             || anArg == "-boundarywidth"
2554             || aCmdName == "vshowfaceboundary")
2555       {
2556         aChangeSet->ToSetFaceBoundaryWidth = 1;
2557         aChangeSet->FaceBoundaryWidth = aWidth;
2558       }
2559       else
2560       {
2561         aChangeSet->ToSetLineWidth = 1;
2562         aChangeSet->LineWidth = aWidth;
2563       }
2564     }
2565     else if (anArg == "-unsetwidth"
2566           || anArg == "-unsetlinewidth"
2567           || anArg == "-unsetedgewidth")
2568     {
2569       if (anArg == "-unsetedgewidth")
2570       {
2571         aChangeSet->ToSetEdgeWidth = -1;
2572         aChangeSet->EdgeWidth = 1.0;
2573       }
2574       else
2575       {
2576         aChangeSet->ToSetLineWidth = -1;
2577         aChangeSet->LineWidth = 1.0;
2578       }
2579     }
2580     else if (anArg == "-settransp"
2581           || anArg == "-settransparency"
2582           || anArg == "-transparency"
2583           || anArg == "-transp")
2584     {
2585       if (++anArgIter >= theArgNb)
2586       {
2587         std::cout << "Error: wrong syntax at " << anArg << "\n";
2588         return 1;
2589       }
2590       aChangeSet->ToSetTransparency = 1;
2591       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
2592       if (aChangeSet->Transparency >= 0.0
2593        && aChangeSet->Transparency <= Precision::Confusion())
2594       {
2595         aChangeSet->ToSetTransparency = -1;
2596         aChangeSet->Transparency = 0.0;
2597       }
2598     }
2599     else if (anArg == "-setalphamode"
2600           || anArg == "-alphamode")
2601     {
2602       if (++anArgIter >= theArgNb)
2603       {
2604         std::cout << "Error: wrong syntax at " << anArg << "\n";
2605         return 1;
2606       }
2607       aChangeSet->ToSetAlphaMode = 1;
2608       aChangeSet->AlphaCutoff = 0.5f;
2609       {
2610         TCollection_AsciiString aParam (theArgVec[anArgIter]);
2611         aParam.LowerCase();
2612         if (aParam == "opaque")
2613         {
2614           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Opaque;
2615         }
2616         else if (aParam == "mask")
2617         {
2618           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Mask;
2619         }
2620         else if (aParam == "blend")
2621         {
2622           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
2623         }
2624         else if (aParam == "blendauto"
2625               || aParam == "auto")
2626         {
2627           aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2628         }
2629         else
2630         {
2631           std::cout << "Error: wrong syntax at " << aParam << "\n";
2632           return 1;
2633         }
2634       }
2635
2636       if (anArgIter + 1 < theArgNb
2637        && theArgVec[anArgIter + 1][0] != '-')
2638       {
2639         TCollection_AsciiString aParam2 (theArgVec[anArgIter + 1]);
2640         if (aParam2.IsRealValue())
2641         {
2642           aChangeSet->AlphaCutoff = (float )aParam2.RealValue();
2643           ++anArgIter;
2644         }
2645       }
2646     }
2647     else if (anArg == "-setvis"
2648           || anArg == "-setvisibility"
2649           || anArg == "-visibility")
2650     {
2651       if (++anArgIter >= theArgNb)
2652       {
2653         std::cout << "Error: wrong syntax at " << anArg << "\n";
2654         return 1;
2655       }
2656
2657       aChangeSet->ToSetVisibility = 1;
2658       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
2659     }
2660     else if (anArg == "-setalpha"
2661           || anArg == "-alpha")
2662     {
2663       if (++anArgIter >= theArgNb)
2664       {
2665         std::cout << "Error: wrong syntax at " << anArg << "\n";
2666         return 1;
2667       }
2668       aChangeSet->ToSetTransparency = 1;
2669       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
2670       if (aChangeSet->Transparency < 0.0
2671        || aChangeSet->Transparency > 1.0)
2672       {
2673         std::cout << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")\n";
2674         return 1;
2675       }
2676       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
2677       if (aChangeSet->Transparency >= 0.0
2678        && aChangeSet->Transparency <= Precision::Confusion())
2679       {
2680         aChangeSet->ToSetTransparency = -1;
2681         aChangeSet->Transparency = 0.0;
2682       }
2683     }
2684     else if (anArg == "-unsettransp"
2685           || anArg == "-unsettransparency"
2686           || anArg == "-unsetalpha"
2687           || anArg == "-opaque")
2688     {
2689       aChangeSet->ToSetTransparency = -1;
2690       aChangeSet->Transparency = 0.0;
2691     }
2692     else if (anArg == "-setcolor"
2693           || anArg == "-color"
2694           || anArg == "-setbackfacecolor"
2695           || anArg == "-backfacecolor"
2696           || anArg == "-setbackcolor"
2697           || anArg == "-backcolor"
2698           || anArg == "-setfaceboundarycolor"
2699           || anArg == "-setboundarycolor"
2700           || anArg == "-faceboundarycolor"
2701           || anArg == "-boundarycolor")
2702     {
2703       Quantity_Color aColor;
2704       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2705                                                            theArgVec + anArgIter + 1,
2706                                                            aColor);
2707       if (aNbParsed == 0)
2708       {
2709         std::cout << "Syntax error at '" << anArg << "'\n";
2710         return 1;
2711       }
2712       anArgIter += aNbParsed;
2713       if (aCmdName == "vsetedgetype")
2714       {
2715         aChangeSet->ToSetEdgeColor = 1;
2716         aChangeSet->EdgeColor = Quantity_ColorRGBA (aColor);
2717       }
2718       else if (aCmdName == "vshowfaceboundary"
2719             || anArg == "-setfaceboundarycolor"
2720             || anArg == "-setboundarycolor"
2721             || anArg == "-faceboundarycolor"
2722             || anArg == "-boundarycolor")
2723       {
2724         aChangeSet->ToSetFaceBoundaryColor = 1;
2725         aChangeSet->FaceBoundaryColor = aColor;
2726       }
2727       else if (anArg == "-setbackfacecolor"
2728             || anArg == "-backfacecolor"
2729             || anArg == "-setbackcolor"
2730             || anArg == "-backcolor")
2731       {
2732         aChangeSet->ToSetBackFaceColor = 1;
2733         aChangeSet->BackFaceColor = aColor;
2734       }
2735       else
2736       {
2737         aChangeSet->ToSetColor = 1;
2738         aChangeSet->Color = aColor;
2739       }
2740     }
2741     else if (anArg == "-setlinetype"
2742           || anArg == "-linetype"
2743           || anArg == "-setedgetype"
2744           || anArg == "-setedgestype"
2745           || anArg == "-edgetype"
2746           || anArg == "-edgestype"
2747           || anArg == "-setfaceboundarystyle"
2748           || anArg == "-faceboundarystyle"
2749           || anArg == "-boundarystyle"
2750           || anArg == "-setfaceboundarytype"
2751           || anArg == "-faceboundarytype"
2752           || anArg == "-setboundarytype"
2753           || anArg == "-boundarytype"
2754           || anArg == "-type")
2755     {
2756       if (++anArgIter >= theArgNb)
2757       {
2758         std::cout << "Error: wrong syntax at " << anArg << "\n";
2759         return 1;
2760       }
2761       Aspect_TypeOfLine aLineType = Aspect_TOL_EMPTY;
2762       if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType))
2763       {
2764         std::cout << "Error: wrong syntax at " << anArg << "\n";
2765         return 1;
2766       }
2767       if (anArg == "-setedgetype"
2768        || anArg == "-setedgestype"
2769        || anArg == "-edgetype"
2770        || anArg == "-edgestype"
2771        || aCmdName == "vsetedgetype")
2772       {
2773         aChangeSet->TypeOfEdge = aLineType;
2774         aChangeSet->ToSetTypeOfEdge = 1;
2775       }
2776       else if (anArg == "-setfaceboundarystyle"
2777             || anArg == "-faceboundarystyle"
2778             || anArg == "-boundarystyle"
2779             || anArg == "-setfaceboundarytype"
2780             || anArg == "-faceboundarytype"
2781             || anArg == "-setboundarytype"
2782             || anArg == "-boundarytype"
2783             || aCmdName == "vshowfaceboundary")
2784       {
2785         aChangeSet->TypeOfFaceBoundaryLine = aLineType;
2786         aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2787       }
2788       else
2789       {
2790         aChangeSet->TypeOfLine = aLineType;
2791         aChangeSet->ToSetTypeOfLine = 1;
2792       }
2793     }
2794     else if (anArg == "-unsetlinetype"
2795           || anArg == "-unsetedgetype"
2796           || anArg == "-unsetedgestype")
2797     {
2798       if (anArg == "-unsetedgetype"
2799        || anArg == "-unsetedgestype")
2800       {
2801         aChangeSet->ToSetTypeOfEdge = -1;
2802       }
2803       else
2804       {
2805         aChangeSet->ToSetTypeOfLine = -1;
2806       }
2807     }
2808     else if (anArg == "-setmarkertype"
2809           || anArg == "-markertype"
2810           || anArg == "-setpointtype"
2811           || anArg == "-pointtype")
2812     {
2813       if (++anArgIter >= theArgNb)
2814       {
2815         std::cout << "Error: wrong syntax at " << anArg << "\n";
2816         return 1;
2817       }
2818       if (!ViewerTest::ParseMarkerType (theArgVec[anArgIter], aChangeSet->TypeOfMarker, aChangeSet->MarkerImage))
2819       {
2820         std::cout << "Error: wrong syntax at " << anArg << "\n";
2821         return 1;
2822       }
2823
2824       aChangeSet->ToSetTypeOfMarker = 1;
2825     }
2826     else if (anArg == "-unsetmarkertype"
2827           || anArg == "-unsetpointtype")
2828     {
2829       aChangeSet->ToSetTypeOfMarker = -1;
2830     }
2831     else if (anArg == "-setmarkersize"
2832           || anArg == "-markersize"
2833           || anArg == "-setpointsize"
2834           || anArg == "-pointsize")
2835     {
2836       if (++anArgIter >= theArgNb)
2837       {
2838         std::cout << "Error: wrong syntax at " << anArg << "\n";
2839         return 1;
2840       }
2841       aChangeSet->ToSetMarkerSize = 1;
2842       aChangeSet->MarkerSize = Draw::Atof (theArgVec[anArgIter]);
2843     }
2844     else if (anArg == "-unsetmarkersize"
2845           || anArg == "-unsetpointsize")
2846     {
2847       aChangeSet->ToSetMarkerSize = -1;
2848       aChangeSet->MarkerSize = 1.0;
2849     }
2850     else if (anArg == "-unsetcolor")
2851     {
2852       aChangeSet->ToSetColor = -1;
2853       aChangeSet->Color = DEFAULT_COLOR;
2854     }
2855     else if (anArg == "-setmat"
2856           || anArg == "-mat"
2857           || anArg == "-setmaterial"
2858           || anArg == "-material")
2859     {
2860       if (++anArgIter >= theArgNb)
2861       {
2862         std::cout << "Error: wrong syntax at " << anArg << "\n";
2863         return 1;
2864       }
2865       aChangeSet->ToSetMaterial = 1;
2866       aChangeSet->MatName = theArgVec[anArgIter];
2867       if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString(), aChangeSet->Material))
2868       {
2869         std::cout << "Syntax error: unknown material '" << aChangeSet->MatName << "'.\n";
2870         return 1;
2871       }
2872     }
2873     else if (anArg == "-unsetmat"
2874           || anArg == "-unsetmaterial")
2875     {
2876       aChangeSet->ToSetMaterial = -1;
2877       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2878     }
2879     else if (anArg == "-subshape"
2880           || anArg == "-subshapes")
2881     {
2882       if (isDefaults)
2883       {
2884         std::cout << "Error: wrong syntax. -subshapes can not be used together with -defaults call!\n";
2885         return 1;
2886       }
2887
2888       if (aNames.IsEmpty())
2889       {
2890         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
2891         return 1;
2892       }
2893
2894       aChanges.Append (ViewerTest_AspectsChangeSet());
2895       aChangeSet = &aChanges.ChangeLast();
2896
2897       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
2898       {
2899         Standard_CString aSubShapeName = theArgVec[anArgIter];
2900         if (*aSubShapeName == '-')
2901         {
2902           --anArgIter;
2903           break;
2904         }
2905
2906         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
2907         if (aSubShape.IsNull())
2908         {
2909           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
2910           return 1;
2911         }
2912         aChangeSet->SubShapes.Append (aSubShape);
2913       }
2914
2915       if (aChangeSet->SubShapes.IsEmpty())
2916       {
2917         std::cerr << "Error: empty list is specified after -subshapes!\n";
2918         return 1;
2919       }
2920     }
2921     else if (anArg == "-setfreeboundary"
2922           || anArg == "-freeboundary"
2923           || anArg == "-setfb"
2924           || anArg == "-fb")
2925     {
2926       bool toEnable = true;
2927       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2928       {
2929         std::cout << "Error: wrong syntax at " << anArg << "\n";
2930         return 1;
2931       }
2932       ++anArgIter;
2933       aChangeSet->ToSetShowFreeBoundary = toEnable ? 1 : -1;
2934     }
2935     else if (anArg == "-setfreeboundarywidth"
2936           || anArg == "-freeboundarywidth"
2937           || anArg == "-setfbwidth"
2938           || anArg == "-fbwidth")
2939     {
2940       if (++anArgIter >= theArgNb)
2941       {
2942         std::cout << "Error: wrong syntax at " << anArg << "\n";
2943         return 1;
2944       }
2945       aChangeSet->ToSetFreeBoundaryWidth = 1;
2946       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2947     }
2948     else if (anArg == "-unsetfreeboundarywidth"
2949           || anArg == "-unsetfbwidth")
2950     {
2951       aChangeSet->ToSetFreeBoundaryWidth = -1;
2952       aChangeSet->FreeBoundaryWidth = 1.0;
2953     }
2954     else if (anArg == "-setfreeboundarycolor"
2955           || anArg == "-freeboundarycolor"
2956           || anArg == "-setfbcolor"
2957           || anArg == "-fbcolor")
2958     {
2959       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2960                                                            theArgVec + anArgIter + 1,
2961                                                            aChangeSet->FreeBoundaryColor);
2962       if (aNbParsed == 0)
2963       {
2964         std::cout << "Syntax error at '" << anArg << "'\n";
2965         return 1;
2966       }
2967       anArgIter += aNbParsed;
2968       aChangeSet->ToSetFreeBoundaryColor = 1;
2969     }
2970     else if (anArg == "-unsetfreeboundarycolor"
2971           || anArg == "-unsetfbcolor")
2972     {
2973       aChangeSet->ToSetFreeBoundaryColor = -1;
2974       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2975     }
2976     else if (anArg == "-setisoontriangulation"
2977           || anArg == "-isoontriangulation"
2978           || anArg == "-setisoontriang"
2979           || anArg == "-isoontriang")
2980     {
2981       bool toEnable = true;
2982       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2983       {
2984         std::cout << "Error: wrong syntax at " << anArg << "\n";
2985         return 1;
2986       }
2987       ++anArgIter;
2988       aChangeSet->ToEnableIsoOnTriangulation = toEnable ? 1 : -1;
2989     }
2990     else if (anArg == "-setfaceboundarydraw"
2991           || anArg == "-setdrawfaceboundary"
2992           || anArg == "-setdrawfaceboundaries"
2993           || anArg == "-setshowfaceboundary"
2994           || anArg == "-setshowfaceboundaries"
2995           || anArg == "-setdrawfaceedges"
2996           || anArg == "-faceboundarydraw"
2997           || anArg == "-drawfaceboundary"
2998           || anArg == "-drawfaceboundaries"
2999           || anArg == "-showfaceboundary"
3000           || anArg == "-showfaceboundaries"
3001           || anArg == "-drawfaceedges"
3002           || anArg == "-faceboundary"
3003           || anArg == "-faceboundaries"
3004           || anArg == "-faceedges")
3005     {
3006       bool toEnable = true;
3007       if (!ViewerTest::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
3008       {
3009         std::cout << "Error: wrong syntax at " << anArg << "\n";
3010         return 1;
3011       }
3012       ++anArgIter;
3013       aChangeSet->ToSetFaceBoundaryDraw = toEnable ? 1 : -1;
3014     }
3015     else if (anArg == "-unsetfaceboundary"
3016           || anArg == "-unsetboundary")
3017     {
3018       aChangeSet->ToSetFaceBoundaryDraw  = -1;
3019       aChangeSet->ToSetFaceBoundaryColor = -1;
3020     }
3021     else if (anArg == "-setmostcontinuity"
3022           || anArg == "-mostcontinuity")
3023     {
3024       TCollection_AsciiString aClassArg (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "");
3025       aClassArg.LowerCase();
3026       GeomAbs_Shape aClass = GeomAbs_CN;
3027       if (aClassArg == "c0"
3028        || aClassArg == "0")
3029       {
3030         aClass = GeomAbs_C0;
3031       }
3032       else if (aClassArg == "c1"
3033             || aClassArg == "1")
3034       {
3035         aClass = GeomAbs_C1;
3036       }
3037       else if (aClassArg == "c2"
3038             || aClassArg == "2")
3039       {
3040         aClass = GeomAbs_C2;
3041       }
3042       else if (aClassArg == "c3"
3043             || aClassArg == "3")
3044       {
3045         aClass = GeomAbs_C3;
3046       }
3047       else if (aClassArg == "cn"
3048             || aClassArg == "n")
3049       {
3050         aClass = GeomAbs_CN;
3051       }
3052       else
3053       {
3054         std::cout << "Syntax error at '" << anArg << "'\n";
3055         return 1;
3056       }
3057
3058       ++anArgIter;
3059       aChangeSet->ToSetFaceBoundaryUpperContinuity = 1;
3060       aChangeSet->FaceBoundaryUpperContinuity = aClass;
3061     }
3062     else if (anArg == "-setmaxparamvalue"
3063           || anArg == "-maxparamvalue")
3064     {
3065       if (++anArgIter >= theArgNb)
3066       {
3067         std::cout << "Error: wrong syntax at " << anArg << "\n";
3068         return 1;
3069       }
3070       aChangeSet->ToSetMaxParamValue = 1;
3071       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
3072     }
3073     else if (anArg == "-setsensitivity"
3074           || anArg == "-sensitivity")
3075     {
3076       if (isDefaults)
3077       {
3078         std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
3079         return 1;
3080       }
3081
3082       if (aNames.IsEmpty())
3083       {
3084         std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
3085         return 1;
3086       }
3087
3088       if (anArgIter + 2 >= theArgNb)
3089       {
3090         std::cout << "Error: wrong syntax at " << anArg << "\n";
3091         return 1;
3092       }
3093       aChangeSet->ToSetSensitivity = 1;
3094       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
3095       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
3096     }
3097     else if (anArg == "-sethatch"
3098           || anArg == "-hatch")
3099     {
3100       if (isDefaults)
3101       {
3102         std::cout << "Error: wrong syntax. -setHatch can not be used together with -defaults call!\n";
3103         return 1;
3104       }
3105
3106       if (aNames.IsEmpty())
3107       {
3108         std::cout << "Error: object should be specified explicitly when -setHatch is used!\n";
3109         return 1;
3110       }
3111
3112       aChangeSet->ToSetHatch = 1;
3113       TCollection_AsciiString anArgHatch (theArgVec[++anArgIter]);
3114       if (anArgHatch.Length() <= 2)
3115       {
3116         const Standard_Integer anIntStyle = Draw::Atoi (anArgHatch.ToCString());
3117         if (anIntStyle < 0
3118          || anIntStyle >= Aspect_HS_NB)
3119         {
3120           std::cout << "Error: hatch style is out of range [0, " << (Aspect_HS_NB - 1) << "]!\n";
3121           return 1;
3122         }
3123         aChangeSet->StdHatchStyle = anIntStyle;
3124       }
3125       else
3126       {
3127         aChangeSet->PathToHatchPattern = anArgHatch;
3128       }
3129     }
3130     else if (anArg == "-setshadingmodel"
3131           || anArg == "-setshading"
3132           || anArg == "-shadingmodel"
3133           || anArg == "-shading")
3134     {
3135       if (++anArgIter >= theArgNb)
3136       {
3137         std::cout << "Error: wrong syntax at " << anArg << "\n";
3138         return 1;
3139       }
3140       aChangeSet->ToSetShadingModel = 1;
3141       aChangeSet->ShadingModelName  = theArgVec[anArgIter];
3142       if (!ViewerTest::ParseShadingModel (theArgVec[anArgIter], aChangeSet->ShadingModel))
3143       {
3144         std::cout << "Error: wrong syntax at " << anArg << "\n";
3145         return 1;
3146       }
3147     }
3148     else if (anArg == "-unsetshadingmodel")
3149     {
3150       aChangeSet->ToSetShadingModel = -1;
3151       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
3152     }
3153     else if (anArg == "-setinterior"
3154           || anArg == "-setinteriorstyle"
3155           || anArg == "-interior"
3156           || anArg == "-interiorstyle")
3157     {
3158       if (++anArgIter >= theArgNb)
3159       {
3160         std::cout << "Error: wrong syntax at " << anArg << "\n";
3161         return 1;
3162       }
3163       aChangeSet->ToSetInterior = 1;
3164       if (!parseInteriorStyle (theArgVec[anArgIter], aChangeSet->InteriorStyle))
3165       {
3166         std::cout << "Error: wrong syntax at " << anArg << "\n";
3167         return 1;
3168       }
3169     }
3170     else if (anArg == "-unsetinterior")
3171     {
3172       aChangeSet->ToSetInterior = -1;
3173       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
3174     }
3175     else if (anArg == "-setdrawoutline"
3176           || anArg == "-setdrawsilhouette"
3177           || anArg == "-setoutline"
3178           || anArg == "-setsilhouette"
3179           || anArg == "-outline"
3180           || anArg == "-outlined"
3181           || anArg == "-silhouette")
3182     {
3183       bool toDrawOutline = true;
3184       if (anArgIter + 1 < theArgNb
3185        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toDrawOutline))
3186       {
3187         ++anArgIter;
3188       }
3189       aChangeSet->ToSetDrawSilhouette = toDrawOutline ? 1 : -1;
3190     }
3191     else if (anArg == "-setdrawedges"
3192           || anArg == "-setdrawedge"
3193           || anArg == "-drawedges"
3194           || anArg == "-drawedge"
3195           || anArg == "-edges")
3196     {
3197       bool toDrawEdges = true;
3198       if (anArgIter + 1 < theArgNb
3199        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toDrawEdges))
3200       {
3201         ++anArgIter;
3202       }
3203       aChangeSet->ToSetDrawEdges = toDrawEdges ? 1 : -1;
3204     }
3205     else if (anArg == "-setquadedges"
3206           || anArg == "-setquads"
3207           || anArg == "-quads"
3208           || anArg == "-skipfirstedge")
3209     {
3210       bool isQuadMode = true;
3211       if (anArgIter + 1 < theArgNb
3212        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isQuadMode))
3213       {
3214         ++anArgIter;
3215       }
3216       aChangeSet->ToSetQuadEdges = isQuadMode ? 1 : -1;
3217     }
3218     else if (anArg == "-setedgecolor"
3219           || anArg == "-setedgescolor"
3220           || anArg == "-edgecolor"
3221           || anArg == "-edgescolor")
3222     {
3223       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3224                                                            theArgVec + anArgIter + 1,
3225                                                            aChangeSet->EdgeColor);
3226       if (aNbParsed == 0)
3227       {
3228         std::cout << "Syntax error at '" << anArg << "'\n";
3229         return 1;
3230       }
3231       anArgIter += aNbParsed;
3232       aChangeSet->ToSetEdgeColor = 1;
3233     }
3234     else if (anArg == "-unset")
3235     {
3236       aChangeSet->ToSetVisibility = 1;
3237       aChangeSet->Visibility = 1;
3238       aChangeSet->ToSetLineWidth = -1;
3239       aChangeSet->LineWidth = 1.0;
3240       aChangeSet->ToSetTypeOfLine = -1;
3241       aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
3242       aChangeSet->ToSetTypeOfMarker = -1;
3243       aChangeSet->TypeOfMarker = Aspect_TOM_PLUS;
3244       aChangeSet->ToSetMarkerSize = -1;
3245       aChangeSet->MarkerSize = 1.0;
3246       aChangeSet->ToSetTransparency = -1;
3247       aChangeSet->Transparency = 0.0;
3248       aChangeSet->ToSetAlphaMode = -1;
3249       aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
3250       aChangeSet->AlphaCutoff = 0.5f;
3251       aChangeSet->ToSetColor = -1;
3252       aChangeSet->Color = DEFAULT_COLOR;
3253       //aChangeSet->ToSetBackFaceColor = -1; // should be reset by ToSetColor
3254       //aChangeSet->BackFaceColor = DEFAULT_COLOR;
3255       aChangeSet->ToSetMaterial = -1;
3256       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
3257       aChangeSet->ToSetShowFreeBoundary = -1;
3258       aChangeSet->ToSetFreeBoundaryColor = -1;
3259       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
3260       aChangeSet->ToSetFreeBoundaryWidth = -1;
3261       aChangeSet->FreeBoundaryWidth = 1.0;
3262       aChangeSet->ToEnableIsoOnTriangulation = -1;
3263       //
3264       aChangeSet->ToSetFaceBoundaryDraw = -1;
3265       aChangeSet->ToSetFaceBoundaryUpperContinuity = -1;
3266       aChangeSet->FaceBoundaryUpperContinuity = GeomAbs_CN;
3267       aChangeSet->ToSetFaceBoundaryColor = -1;
3268       aChangeSet->FaceBoundaryColor = Quantity_NOC_BLACK;
3269       aChangeSet->ToSetFaceBoundaryWidth = -1;
3270       aChangeSet->FaceBoundaryWidth = 1.0f;
3271       aChangeSet->ToSetTypeOfFaceBoundaryLine = -1;
3272       aChangeSet->TypeOfFaceBoundaryLine = Aspect_TOL_SOLID;
3273       //
3274       aChangeSet->ToSetHatch = -1;
3275       aChangeSet->StdHatchStyle = -1;
3276       aChangeSet->PathToHatchPattern.Clear();
3277       aChangeSet->ToSetShadingModel = -1;
3278       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
3279       aChangeSet->ToSetInterior = -1;
3280       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
3281       aChangeSet->ToSetDrawSilhouette = -1;
3282       aChangeSet->ToSetDrawEdges = -1;
3283       aChangeSet->ToSetQuadEdges = -1;
3284       aChangeSet->ToSetEdgeColor = -1;
3285       aChangeSet->EdgeColor = Quantity_ColorRGBA (DEFAULT_COLOR);
3286       aChangeSet->ToSetEdgeWidth = -1;
3287       aChangeSet->EdgeWidth = 1.0;
3288       aChangeSet->ToSetTypeOfEdge = -1;
3289       aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
3290     }
3291     else if (anArg == "-dumpjson")
3292     {
3293       toDump = Standard_True;
3294     }
3295     else if (anArg == "-dumpcompact")
3296     {
3297       toCompactDump = Standard_False;
3298       if (++anArgIter >= theArgNb && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toCompactDump))
3299         ++anArgIter;
3300     }
3301     else if (anArg == "-dumpdepth")
3302     {
3303       if (++anArgIter >= theArgNb)
3304       {
3305         std::cout << "Error: wrong syntax at " << anArg << "\n";
3306         return 1;
3307       }
3308       aDumpDepth = Draw::Atoi (theArgVec[anArgIter]);
3309     }
3310     else
3311     {
3312       std::cout << "Error: wrong syntax at " << anArg << "\n";
3313       return 1;
3314     }
3315   }
3316
3317   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3318        aChangesIter.More(); aChangesIter.Next())
3319   {
3320     if (!aChangesIter.Value().Validate())
3321     {
3322       return 1;
3323     }
3324   }
3325
3326   // special case for -defaults parameter.
3327   // all changed values will be set to DefaultDrawer.
3328   if (isDefaults)
3329   {
3330     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
3331     aChangeSet->Apply (aDrawer);
3332     if (aChangeSet->ToSetLineWidth != 0)
3333     {
3334       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
3335       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
3336       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
3337       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
3338     }
3339     if (aChangeSet->ToSetColor != 0)
3340     {
3341       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
3342       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
3343       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
3344       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
3345       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
3346       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
3347     }
3348     if (aChangeSet->ToSetTransparency != 0)
3349     {
3350       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
3351     }
3352     if (aChangeSet->ToSetMaterial != 0)
3353     {
3354       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
3355     }
3356     if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3357     {
3358       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
3359     }
3360
3361     // redisplay all objects in context
3362     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3363     {
3364       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
3365       if (!aPrs.IsNull())
3366       {
3367         aCtx->Redisplay (aPrs, Standard_False);
3368       }
3369     }
3370     if (toDump)
3371     {
3372       Standard_SStream aStream;
3373       aDrawer->DumpJson (aStream, aDumpDepth);
3374
3375       if (toCompactDump)
3376         theDI << Standard_Dump::Text (aStream);
3377       else
3378         theDI << Standard_Dump::FormatJson (aStream);
3379     }
3380     return 0;
3381   }
3382
3383   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3384   {
3385     const TCollection_AsciiString& aName = aPrsIter.CurrentName();
3386     Handle(AIS_InteractiveObject)  aPrs  = aPrsIter.Current();
3387     if (aPrs.IsNull())
3388     {
3389       return 1;
3390     }
3391
3392     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
3393     Handle(AIS_ColoredShape) aColoredPrs;
3394     Standard_Boolean toDisplay = Standard_False;
3395     Standard_Boolean toRedisplay = Standard_False;
3396     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
3397     {
3398       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
3399       if (aShapePrs.IsNull())
3400       {
3401         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
3402         return 1;
3403       }
3404       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
3405       if (aColoredPrs.IsNull())
3406       {
3407         aColoredPrs = new AIS_ColoredShape (aShapePrs);
3408         if (aShapePrs->HasDisplayMode())
3409         {
3410           aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode());
3411         }
3412         aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation());
3413         aCtx->Remove (aShapePrs, Standard_False);
3414         GetMapOfAIS().UnBind2 (aName);
3415         GetMapOfAIS().Bind (aColoredPrs, aName);
3416         toDisplay = Standard_True;
3417         aShapePrs = aColoredPrs;
3418         aPrs      = aColoredPrs;
3419       }
3420     }
3421
3422     if (!aPrs.IsNull())
3423     {
3424       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3425       aChangeSet = &aChangesIter.ChangeValue();
3426       if (aChangeSet->ToSetVisibility == 1)
3427       {
3428         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
3429         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
3430       }
3431       else if (aChangeSet->ToSetMaterial == 1)
3432       {
3433         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
3434       }
3435       else if (aChangeSet->ToSetMaterial == -1)
3436       {
3437         aCtx->UnsetMaterial (aPrs, Standard_False);
3438       }
3439       if (aChangeSet->ToSetColor == 1)
3440       {
3441         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
3442       }
3443       else if (aChangeSet->ToSetColor == -1)
3444       {
3445         aCtx->UnsetColor (aPrs, Standard_False);
3446       }
3447       if (aChangeSet->ToSetTransparency == 1)
3448       {
3449         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
3450       }
3451       else if (aChangeSet->ToSetTransparency == -1)
3452       {
3453         aCtx->UnsetTransparency (aPrs, Standard_False);
3454       }
3455       if (aChangeSet->ToSetLineWidth == 1)
3456       {
3457         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
3458       }
3459       else if (aChangeSet->ToSetLineWidth == -1)
3460       {
3461         aCtx->UnsetWidth (aPrs, Standard_False);
3462       }
3463       else if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3464       {
3465         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
3466         toRedisplay = Standard_True;
3467       }
3468       else if (aChangeSet->ToSetSensitivity != 0)
3469       {
3470         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3471       }
3472       if (!aDrawer.IsNull())
3473       {
3474         toRedisplay = aChangeSet->Apply (aDrawer) || toRedisplay;
3475       }
3476
3477       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
3478       {
3479         aChangeSet = &aChangesIter.ChangeValue();
3480         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
3481              aSubShapeIter.More(); aSubShapeIter.Next())
3482         {
3483           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
3484           if (!aChangeSet->IsEmpty())
3485           {
3486             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3487             aChangeSet->Apply (aCurColDrawer);
3488           }
3489           if (aChangeSet->ToSetVisibility == 1)
3490           {
3491             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3492             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
3493           }
3494           if (aChangeSet->ToSetColor == 1)
3495           {
3496             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
3497           }
3498           if (aChangeSet->ToSetTransparency == 1)
3499           {
3500             aColoredPrs->SetCustomTransparency (aSubShape, aChangeSet->Transparency);
3501           }
3502           if (aChangeSet->ToSetLineWidth == 1)
3503           {
3504             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
3505           }
3506           if (aChangeSet->ToSetColor     == -1
3507            || aChangeSet->ToSetLineWidth == -1)
3508           {
3509             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
3510           }
3511           if (aChangeSet->ToSetSensitivity != 0)
3512           {
3513             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3514           }
3515         }
3516       }
3517       if (toDisplay)
3518       {
3519         aCtx->Display (aPrs, Standard_False);
3520       }
3521       if (toRedisplay)
3522       {
3523         aCtx->Redisplay (aPrs, Standard_False);
3524       }
3525       else if (!aColoredPrs.IsNull())
3526       {
3527         aCtx->Redisplay (aColoredPrs, Standard_False);
3528       }
3529       else
3530       {
3531         aPrs->SynchronizeAspects();
3532       }
3533
3534       if (toDump)
3535       {
3536         Standard_SStream aStream;
3537         aDrawer->DumpJson (aStream);
3538
3539         theDI << aName << ": \n";
3540         theDI << Standard_Dump::FormatJson (aStream);
3541         theDI << "\n";
3542       }
3543     }
3544   }
3545   return 0;
3546 }
3547
3548 //==============================================================================
3549 //function : VDonly2
3550 //author   : ege
3551 //purpose  : Display only a selected or named  object
3552 //           if there is no selected or named object s, nothing is done
3553 //==============================================================================
3554 static int VDonly2 (Draw_Interpretor& ,
3555                     Standard_Integer  theArgNb,
3556                     const char**      theArgVec)
3557 {
3558   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3559   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3560   if (aCtx.IsNull())
3561   {
3562     std::cerr << "Error: no active view!\n";
3563     return 1;
3564   }
3565
3566   Standard_Integer anArgIter = 1;
3567   for (; anArgIter < theArgNb; ++anArgIter)
3568   {
3569     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
3570     {
3571       break;
3572     }
3573   }
3574
3575   NCollection_Map<Handle(Standard_Transient)> aDispSet;
3576   if (anArgIter >= theArgNb)
3577   {
3578     // display only selected objects
3579     if (aCtx->NbSelected() < 1)
3580     {
3581       return 0;
3582     }
3583
3584     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3585     {
3586       aDispSet.Add (aCtx->SelectedInteractive());
3587     }
3588   }
3589   else
3590   {
3591     // display only specified objects
3592     for (; anArgIter < theArgNb; ++anArgIter)
3593     {
3594       TCollection_AsciiString aName = theArgVec[anArgIter];
3595       Handle(AIS_InteractiveObject) aShape;
3596       if (GetMapOfAIS().Find2 (aName, aShape)
3597       && !aShape.IsNull())
3598       {
3599         aCtx->Display (aShape, Standard_False);
3600         aDispSet.Add (aShape);
3601       }
3602     }
3603   }
3604
3605   // weed out other objects
3606   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
3607   {
3608     if (aDispSet.Contains (anIter.Key1()))
3609     {
3610       continue;
3611     }
3612
3613     if (Handle(AIS_InteractiveObject) aShape = anIter.Key1())
3614     {
3615       aCtx->Erase (aShape, Standard_False);
3616     }
3617   }
3618   return 0;
3619 }
3620
3621 //==============================================================================
3622 //function : VRemove
3623 //purpose  : Removes selected or named objects.
3624 //           If there is no selected or named objects,
3625 //           all objects in the viewer can be removed with argument -all.
3626 //           If -context is in arguments, the object is not deleted from the map of
3627 //           objects (deleted only from the current context).
3628 //==============================================================================
3629 int VRemove (Draw_Interpretor& theDI,
3630              Standard_Integer  theArgNb,
3631              const char**      theArgVec)
3632 {
3633   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3634   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3635   if (aCtx.IsNull())
3636   {
3637     std::cerr << "Error: no active view!\n";
3638     return 1;
3639   }
3640
3641   Standard_Boolean isContextOnly = Standard_False;
3642   Standard_Boolean toRemoveAll   = Standard_False;
3643   Standard_Boolean toPrintInfo   = Standard_True;
3644   Standard_Boolean toFailOnError = Standard_True;
3645
3646   Standard_Integer anArgIter = 1;
3647   for (; anArgIter < theArgNb; ++anArgIter)
3648   {
3649     TCollection_AsciiString anArg = theArgVec[anArgIter];
3650     anArg.LowerCase();
3651     if (anArg == "-context")
3652     {
3653       isContextOnly = Standard_True;
3654     }
3655     else if (anArg == "-all")
3656     {
3657       toRemoveAll = Standard_True;
3658     }
3659     else if (anArg == "-noinfo")
3660     {
3661       toPrintInfo = Standard_False;
3662     }
3663     else if (anArg == "-noerror"
3664           || anArg == "-nofail")
3665     {
3666       toFailOnError = Standard_False;
3667     }
3668     else if (anUpdateTool.parseRedrawMode (anArg))
3669     {
3670       continue;
3671     }
3672     else
3673     {
3674       break;
3675     }
3676   }
3677   if (toRemoveAll
3678    && anArgIter < theArgNb)
3679   {
3680     std::cerr << "Error: wrong syntax!\n";
3681     return 1;
3682   }
3683
3684   NCollection_List<TCollection_AsciiString> anIONameList;
3685   if (toRemoveAll)
3686   {
3687     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3688          anIter.More(); anIter.Next())
3689     {
3690       anIONameList.Append (anIter.Key2());
3691     }
3692   }
3693   else if (anArgIter < theArgNb) // removed objects names are in argument list
3694   {
3695     for (; anArgIter < theArgNb; ++anArgIter)
3696     {
3697       const TCollection_AsciiString aName (theArgVec[anArgIter]);
3698       if (aName.Search ("*") != -1)
3699       {
3700         for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aPrsIter (GetMapOfAIS()); aPrsIter.More(); aPrsIter.Next())
3701         {
3702           if (aPrsIter.Key1()->GetContext() != aCtx)
3703           {
3704             continue;
3705           }
3706           const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aName + "' '" + aPrsIter.Key2() + "'";
3707           if (theDI.Eval (aCheck.ToCString()) == 0
3708           && *theDI.Result() == '1')
3709           {
3710             anIONameList.Append (aPrsIter.Key2());
3711           }
3712         }
3713         theDI.Reset();
3714         continue;
3715       }
3716
3717       Handle(AIS_InteractiveObject) anIO;
3718       if (!GetMapOfAIS().Find2 (aName, anIO))
3719       {
3720         if (toFailOnError)
3721         {
3722           std::cout << "Syntax error: '" << aName << "' was not bound to some object.\n";
3723           return 1;
3724         }
3725       }
3726       else if (anIO->GetContext() != aCtx)
3727       {
3728         if (toFailOnError)
3729         {
3730           std::cout << "Syntax error: '" << aName << "' was not displayed in current context.\n"
3731                     << "Please activate view with this object displayed and try again.\n";
3732           return 1;
3733         }
3734       }
3735       else
3736       {
3737         anIONameList.Append (aName);
3738       }
3739     }
3740   }
3741   else if (aCtx->NbSelected() > 0)
3742   {
3743     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3744          anIter.More(); anIter.Next())
3745     {
3746       if (!aCtx->IsSelected (anIter.Key1()))
3747       {
3748         continue;
3749       }
3750
3751       anIONameList.Append (anIter.Key2());
3752       continue;
3753     }
3754   }
3755
3756   // Unbind all removed objects from the map of displayed IO.
3757   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
3758        anIter.More(); anIter.Next())
3759   {
3760     const Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (anIter.Value());
3761     aCtx->Remove (anIO, Standard_False);
3762     if (toPrintInfo)
3763     {
3764       theDI << anIter.Value() << " ";
3765     }
3766     if (!isContextOnly)
3767     {
3768       GetMapOfAIS().UnBind2 (anIter.Value());
3769     }
3770   }
3771   return 0;
3772 }
3773
3774 //==============================================================================
3775 //function : VErase
3776 //purpose  : Erase some selected or named objects
3777 //           if there is no selected or named objects, the whole viewer is erased
3778 //==============================================================================
3779 int VErase (Draw_Interpretor& theDI,
3780             Standard_Integer  theArgNb,
3781             const char**      theArgVec)
3782 {
3783   const Handle(AIS_InteractiveContext)& aCtx  = ViewerTest::GetAISContext();
3784   const Handle(V3d_View)&               aView = ViewerTest::CurrentView();
3785   ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
3786   if (aCtx.IsNull())
3787   {
3788     std::cerr << "Error: no active view!\n";
3789     return 1;
3790   }
3791
3792   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
3793
3794   Standard_Integer anArgIter = 1;
3795   Standard_Boolean toEraseInView = Standard_False;
3796   Standard_Boolean toFailOnError = Standard_True;
3797   TColStd_SequenceOfAsciiString aNamesOfEraseIO;
3798   for (; anArgIter < theArgNb; ++anArgIter)
3799   {
3800     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3801     anArgCase.LowerCase();
3802     if (anUpdateTool.parseRedrawMode (anArgCase))
3803     {
3804       continue;
3805     }
3806     else if (anArgCase == "-view"
3807           || anArgCase == "-inview")
3808     {
3809       toEraseInView = Standard_True;
3810     }
3811     else if (anArgCase == "-noerror"
3812           || anArgCase == "-nofail")
3813     {
3814       toFailOnError = Standard_False;
3815     }
3816     else
3817     {
3818       aNamesOfEraseIO.Append (theArgVec[anArgIter]);
3819     }
3820   }
3821
3822   if (!aNamesOfEraseIO.IsEmpty() && toEraseAll)
3823   {
3824     std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
3825     return 1;
3826   }
3827
3828   if (!aNamesOfEraseIO.IsEmpty())
3829   {
3830     // Erase named objects
3831     NCollection_IndexedDataMap<Handle(AIS_InteractiveObject), TCollection_AsciiString> aPrsList;
3832     for (TColStd_SequenceOfAsciiString::Iterator anIter (aNamesOfEraseIO); anIter.More(); anIter.Next())
3833     {
3834       const TCollection_AsciiString& aName = anIter.Value();
3835       if (aName.Search ("*") != -1)
3836       {
3837         for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aPrsIter (GetMapOfAIS()); aPrsIter.More(); aPrsIter.Next())
3838         {
3839           const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aName + "' '" + aPrsIter.Key2() + "'";
3840           if (theDI.Eval (aCheck.ToCString()) == 0
3841           && *theDI.Result() == '1')
3842           {
3843             aPrsList.Add (aPrsIter.Key1(), aPrsIter.Key2());
3844           }
3845         }
3846         theDI.Reset();
3847       }
3848       else
3849       {
3850         Handle(AIS_InteractiveObject) anIO;
3851         if (!GetMapOfAIS().Find2 (aName, anIO))
3852         {
3853           if (toFailOnError)
3854           {
3855             std::cout << "Syntax error: '" << aName << "' is not found\n";
3856             return 1;
3857           }
3858         }
3859         else
3860         {
3861           aPrsList.Add (anIO, aName);
3862         }
3863       }
3864     }
3865
3866     for (NCollection_IndexedDataMap<Handle(AIS_InteractiveObject), TCollection_AsciiString>::Iterator anIter (aPrsList); anIter.More(); anIter.Next())
3867     {
3868       theDI << anIter.Value() << " ";
3869       if (toEraseInView)
3870       {
3871         aCtx->SetViewAffinity (anIter.Key(), aView, Standard_False);
3872       }
3873       else
3874       {
3875         aCtx->Erase (anIter.Key(), Standard_False);
3876       }
3877     }
3878   }
3879   else if (!toEraseAll && aCtx->NbSelected() > 0)
3880   {
3881     // Erase selected objects
3882     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3883          anIter.More(); anIter.Next())
3884     {
3885       const Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3886       if (!anIO.IsNull()
3887        && aCtx->IsSelected (anIO))
3888       {
3889         theDI << anIter.Key2() << " ";
3890         if (toEraseInView)
3891         {
3892           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3893         }
3894       }
3895     }
3896
3897     if (!toEraseInView)
3898     {
3899       aCtx->EraseSelected (Standard_False);
3900     }
3901   }
3902   else
3903   {
3904     // Erase all objects
3905     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3906          anIter.More(); anIter.Next())
3907     {
3908       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3909       if (!anIO.IsNull())
3910       {
3911         if (toEraseInView)
3912         {
3913           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3914         }
3915         else
3916         {
3917           aCtx->Erase (anIO, Standard_False);
3918         }
3919       }
3920     }
3921   }
3922
3923   return 0;
3924 }
3925
3926 //==============================================================================
3927 //function : VDisplayAll
3928 //purpose  : Display all the objects of the Map
3929 //==============================================================================
3930 static int VDisplayAll (Draw_Interpretor& ,
3931                         Standard_Integer  theArgNb,
3932                         const char**      theArgVec)
3933
3934 {
3935   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3936   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3937   if (aCtx.IsNull())
3938   {
3939     std::cerr << "Error: no active view!\n";
3940     return 1;
3941   }
3942
3943   Standard_Integer anArgIter = 1;
3944   for (; anArgIter < theArgNb; ++anArgIter)
3945   {
3946     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3947     anArgCase.LowerCase();
3948     if (anUpdateTool.parseRedrawMode (anArgCase))
3949     {
3950       continue;
3951     }
3952     else
3953     {
3954       break;
3955     }
3956   }
3957   if (anArgIter < theArgNb)
3958   {
3959     std::cout << theArgVec[0] << "Error: wrong syntax\n";
3960     return 1;
3961   }
3962
3963   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3964        anIter.More(); anIter.Next())
3965   {
3966     aCtx->Erase (anIter.Key1(), Standard_False);
3967   }
3968
3969   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3970        anIter.More(); anIter.Next())
3971   {
3972     aCtx->Display (anIter.Key1(), Standard_False);
3973   }
3974   return 0;
3975 }
3976
3977 //! Auxiliary method to check if presentation exists
3978 inline Standard_Integer checkMode (const Handle(AIS_InteractiveContext)& theCtx,
3979                                    const Handle(AIS_InteractiveObject)&  theIO,
3980                                    const Standard_Integer                theMode)
3981 {
3982   if (theIO.IsNull() || theCtx.IsNull())
3983   {
3984     return -1;
3985   }
3986
3987   if (theMode != -1)
3988   {
3989     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
3990     {
3991       return theMode;
3992     }
3993   }
3994   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
3995   {
3996     return theIO->DisplayMode();
3997   }
3998   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
3999   {
4000     return theCtx->DisplayMode();
4001   }
4002
4003   return -1;
4004 }
4005
4006 enum ViewerTest_BndAction
4007 {
4008   BndAction_Hide,
4009   BndAction_Show,
4010   BndAction_Print
4011 };
4012
4013 //! Auxiliary method to print bounding box of presentation
4014 inline void bndPresentation (Draw_Interpretor&                         theDI,
4015                              const Handle(PrsMgr_PresentationManager)& theMgr,
4016                              const Handle(AIS_InteractiveObject)&      theObj,
4017                              const Standard_Integer                    theDispMode,
4018                              const TCollection_AsciiString&            theName,
4019                              const ViewerTest_BndAction                theAction,
4020                              const Handle(Prs3d_Drawer)&               theStyle)
4021 {
4022   switch (theAction)
4023   {
4024     case BndAction_Hide:
4025     {
4026       theMgr->Unhighlight (theObj);
4027       break;
4028     }
4029     case BndAction_Show:
4030     {
4031       theMgr->Color (theObj, theStyle, theDispMode);
4032       break;
4033     }
4034     case BndAction_Print:
4035     {
4036       Bnd_Box aBox;
4037       for (PrsMgr_Presentations::Iterator aPrsIter (theObj->Presentations()); aPrsIter.More(); aPrsIter.Next())
4038       {
4039         if (aPrsIter.Value()->Mode() != theDispMode)
4040           continue;
4041
4042         aBox = aPrsIter.Value()->MinMaxValues();
4043       }
4044       gp_Pnt aMin = aBox.CornerMin();
4045       gp_Pnt aMax = aBox.CornerMax();
4046       theDI << theName  << "\n"
4047             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
4048             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
4049       break;
4050     }
4051   }
4052 }
4053
4054 //==============================================================================
4055 //function : VBounding
4056 //purpose  :
4057 //==============================================================================
4058 int VBounding (Draw_Interpretor& theDI,
4059                Standard_Integer  theArgNb,
4060                const char**      theArgVec)
4061 {
4062   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
4063   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4064   if (aCtx.IsNull())
4065   {
4066     std::cout << "Error: no active view!\n";
4067     return 1;
4068   }
4069
4070   ViewerTest_BndAction anAction = BndAction_Show;
4071   Standard_Integer     aMode    = -1;
4072
4073   Handle(Prs3d_Drawer) aStyle;
4074
4075   Standard_Integer anArgIter = 1;
4076   for (; anArgIter < theArgNb; ++anArgIter)
4077   {
4078     TCollection_AsciiString anArg (theArgVec[anArgIter]);
4079     anArg.LowerCase();
4080     if (anArg == "-print")
4081     {
4082       anAction = BndAction_Print;
4083     }
4084     else if (anArg == "-show")
4085     {
4086       anAction = BndAction_Show;
4087     }
4088     else if (anArg == "-hide")
4089     {
4090       anAction = BndAction_Hide;
4091     }
4092     else if (anArg == "-mode")
4093     {
4094       if (++anArgIter >= theArgNb)
4095       {
4096         std::cout << "Error: wrong syntax at " << anArg << "\n";
4097         return 1;
4098       }
4099       aMode = Draw::Atoi (theArgVec[anArgIter]);
4100     }
4101     else if (!anUpdateTool.parseRedrawMode (anArg))
4102     {
4103       break;
4104     }
4105   }
4106
4107   if (anAction == BndAction_Show)
4108   {
4109     aStyle = new Prs3d_Drawer();
4110     aStyle->SetMethod (Aspect_TOHM_BOUNDBOX);
4111     aStyle->SetColor  (Quantity_NOC_GRAY99);
4112   }
4113
4114   Standard_Integer aHighlightedMode = -1;
4115   if (anArgIter < theArgNb)
4116   {
4117     // has a list of names
4118     for (; anArgIter < theArgNb; ++anArgIter)
4119     {
4120       TCollection_AsciiString aName = theArgVec[anArgIter];
4121       Handle(AIS_InteractiveObject) anIO;
4122       if (!GetMapOfAIS().Find2 (aName, anIO))
4123       {
4124         std::cout << "Error: presentation " << aName << " does not exist\n";
4125         return 1;
4126       }
4127
4128       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4129       if (aHighlightedMode == -1)
4130       {
4131         std::cout << "Error: object " << aName << " has no presentation with mode " << aMode << std::endl;
4132         return 1;
4133       }
4134       bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, aName, anAction, aStyle);
4135     }
4136   }
4137   else if (aCtx->NbSelected() > 0)
4138   {
4139     // remove all currently selected objects
4140     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
4141     {
4142       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
4143       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4144       if (aHighlightedMode != -1)
4145       {
4146         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode,
4147           GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction, aStyle);
4148       }
4149     }
4150   }
4151   else
4152   {
4153     // all objects
4154     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
4155          anIter.More(); anIter.Next())
4156     {
4157       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
4158       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4159       if (aHighlightedMode != -1)
4160       {
4161         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, anIter.Key2(), anAction, aStyle);
4162       }
4163     }
4164   }
4165   return 0;
4166 }
4167
4168 //==============================================================================
4169 //function : VTexture
4170 //purpose  :
4171 //==============================================================================
4172 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4173 {
4174   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
4175   if (aCtx.IsNull())
4176   {
4177     std::cout << "Error: no active view!\n";
4178     return 1;
4179   }
4180
4181   int  toModulate     = -1;
4182   bool toSetFilter    = false;
4183   bool toSetAniso     = false;
4184   bool toSetTrsfAngle = false;
4185   bool toSetTrsfTrans = false;
4186   bool toSetTrsfScale = false;
4187   Standard_ShortReal aTrsfRotAngle = 0.0f;
4188   Graphic3d_Vec2 aTrsfTrans (0.0f, 0.0f);
4189   Graphic3d_Vec2 aTrsfScale (1.0f, 1.0f);
4190   Graphic3d_TypeOfTextureFilter      aFilter       = Graphic3d_TOTF_NEAREST;
4191   Graphic3d_LevelOfTextureAnisotropy anAnisoFilter = Graphic3d_LOTA_OFF;
4192
4193   Handle(AIS_InteractiveObject) aTexturedIO;
4194   Handle(AIS_Shape) aTexturedShape;
4195   Handle(Graphic3d_TextureSet) aTextureSetOld;
4196   NCollection_Vector<Handle(Graphic3d_Texture2Dmanual)> aTextureVecNew;
4197   bool toSetGenRepeat = false;
4198   bool toSetGenScale  = false;
4199   bool toSetGenOrigin = false;
4200   bool toSetImage     = false;
4201   bool toComputeUV    = false;
4202
4203   const TCollection_AsciiString aCommandName (theArgVec[0]);
4204   bool toSetDefaults = aCommandName == "vtexdefault";
4205
4206   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4207   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
4208   {
4209     const TCollection_AsciiString aName     = theArgVec[anArgIter];
4210     TCollection_AsciiString       aNameCase = aName;
4211     aNameCase.LowerCase();
4212     if (anUpdateTool.parseRedrawMode (aName))
4213     {
4214       continue;
4215     }
4216     else if (aTexturedIO.IsNull())
4217     {
4218       const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
4219       if (aMapOfIO.IsBound2 (aName))
4220       {
4221         aTexturedIO = aMapOfIO.Find2 (aName);
4222         aTexturedShape = Handle(AIS_Shape)::DownCast (aTexturedIO);
4223       }
4224       if (aTexturedIO.IsNull())
4225       {
4226         std::cout << "Syntax error: shape " << aName << " does not exists in the viewer.\n";
4227         return 1;
4228       }
4229
4230       if (aTexturedIO->Attributes()->HasOwnShadingAspect())
4231       {
4232         aTextureSetOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureSet();
4233       }
4234     }
4235     else if (!aTexturedShape.IsNull()
4236           && (aNameCase == "-scale"
4237            || aNameCase == "-setscale"
4238            || aCommandName == "vtexscale"))
4239     {
4240       if (aCommandName != "vtexscale")
4241       {
4242         ++anArgIter;
4243       }
4244       if (anArgIter < theArgsNb)
4245       {
4246         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4247         TCollection_AsciiString aValUCase = aValU;
4248         aValUCase.LowerCase();
4249         toSetGenScale = true;
4250         if (aValUCase == "off")
4251         {
4252           aTexturedShape->SetTextureScaleUV (gp_Pnt2d (1.0, 1.0));
4253           continue;
4254         }
4255         else if (anArgIter + 1 < theArgsNb)
4256         {
4257           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4258           if (aValU.IsRealValue()
4259            && aValV.IsRealValue())
4260           {
4261             aTexturedShape->SetTextureScaleUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4262             ++anArgIter;
4263             continue;
4264           }
4265         }
4266       }
4267       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
4268       return 1;
4269     }
4270     else if (!aTexturedShape.IsNull()
4271           && (aNameCase == "-origin"
4272            || aNameCase == "-setorigin"
4273            || aCommandName == "vtexorigin"))
4274     {
4275       if (aCommandName != "vtexorigin")
4276       {
4277         ++anArgIter;
4278       }
4279       if (anArgIter < theArgsNb)
4280       {
4281         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4282         TCollection_AsciiString aValUCase = aValU;
4283         aValUCase.LowerCase();
4284         toSetGenOrigin = true;
4285         if (aValUCase == "off")
4286         {
4287           aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
4288           continue;
4289         }
4290         else if (anArgIter + 1 < theArgsNb)
4291         {
4292           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4293           if (aValU.IsRealValue()
4294            && aValV.IsRealValue())
4295           {
4296             aTexturedShape->SetTextureOriginUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4297             ++anArgIter;
4298             continue;
4299           }
4300         }
4301       }
4302       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
4303       return 1;
4304     }
4305     else if (!aTexturedShape.IsNull()
4306           && (aNameCase == "-repeat"
4307            || aNameCase == "-setrepeat"
4308            || aCommandName == "vtexrepeat"))
4309     {
4310       if (aCommandName != "vtexrepeat")
4311       {
4312         ++anArgIter;
4313       }
4314       if (anArgIter < theArgsNb)
4315       {
4316         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4317         TCollection_AsciiString aValUCase = aValU;
4318         aValUCase.LowerCase();
4319         toSetGenRepeat = true;
4320         if (aValUCase == "off")
4321         {
4322           aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
4323           continue;
4324         }
4325         else if (anArgIter + 1 < theArgsNb)
4326         {
4327           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4328           if (aValU.IsRealValue()
4329            && aValV.IsRealValue())
4330           {
4331             aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4332             ++anArgIter;
4333             continue;
4334           }
4335         }
4336       }
4337       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
4338       return 1;
4339     }
4340     else if (aNameCase == "-modulate")
4341     {
4342       bool toModulateBool = true;
4343       if (anArgIter + 1 < theArgsNb
4344        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toModulateBool))
4345       {
4346         ++anArgIter;
4347       }
4348       toModulate = toModulateBool ? 1 : 0;
4349     }
4350     else if ((aNameCase == "-setfilter"
4351            || aNameCase == "-filter")
4352            && anArgIter + 1 < theArgsNb)
4353     {
4354       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
4355       aValue.LowerCase();
4356       ++anArgIter;
4357       toSetFilter = true;
4358       if (aValue == "nearest")
4359       {
4360         aFilter = Graphic3d_TOTF_NEAREST;
4361       }
4362       else if (aValue == "bilinear")
4363       {
4364         aFilter = Graphic3d_TOTF_BILINEAR;
4365       }
4366       else if (aValue == "trilinear")
4367       {
4368         aFilter = Graphic3d_TOTF_TRILINEAR;
4369       }
4370       else
4371       {
4372         std::cout << "Syntax error: unexpected argument '" << aValue << "'\n";
4373         return 1;
4374       }
4375     }
4376     else if ((aNameCase == "-setaniso"
4377            || aNameCase == "-setanisofilter"
4378            || aNameCase == "-aniso"
4379            || aNameCase == "-anisofilter")
4380            && anArgIter + 1 < theArgsNb)
4381     {
4382       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
4383       aValue.LowerCase();
4384       ++anArgIter;
4385       toSetAniso = true;
4386       if (aValue == "off")
4387       {
4388         anAnisoFilter = Graphic3d_LOTA_OFF;
4389       }
4390       else if (aValue == "fast")
4391       {
4392         anAnisoFilter = Graphic3d_LOTA_FAST;
4393       }
4394       else if (aValue == "middle")
4395       {
4396         anAnisoFilter = Graphic3d_LOTA_MIDDLE;
4397       }
4398       else if (aValue == "quality"
4399             || aValue == "high")
4400       {
4401         anAnisoFilter =  Graphic3d_LOTA_QUALITY;
4402       }
4403       else
4404       {
4405         std::cout << "Syntax error: unexpected argument '" << aValue << "'\n";
4406         return 1;
4407       }
4408     }
4409     else if ((aNameCase == "-rotateangle"
4410            || aNameCase == "-rotangle"
4411            || aNameCase == "-rotate"
4412            || aNameCase == "-angle"
4413            || aNameCase == "-trsfangle")
4414            && anArgIter + 1 < theArgsNb)
4415     {
4416       aTrsfRotAngle  = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4417       toSetTrsfAngle = true;
4418       ++anArgIter;
4419     }
4420     else if ((aNameCase == "-trsftrans"
4421            || aNameCase == "-trsftranslate"
4422            || aNameCase == "-translate"
4423            || aNameCase == "-translation")
4424            && anArgIter + 2 < theArgsNb)
4425     {
4426       aTrsfTrans.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4427       aTrsfTrans.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
4428       toSetTrsfTrans = true;
4429       anArgIter += 2;
4430     }
4431     else if ((aNameCase == "-trsfscale")
4432            && anArgIter + 2 < theArgsNb)
4433     {
4434       aTrsfScale.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4435       aTrsfScale.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
4436       toSetTrsfScale = true;
4437       anArgIter += 2;
4438     }
4439     else if (aNameCase == "-default"
4440           || aNameCase == "-defaults")
4441     {
4442       toSetDefaults = true;
4443     }
4444     else if ((aNameCase == "-video")
4445            && anArgIter + 1 < theArgsNb)
4446     {
4447       const TCollection_AsciiString anInput (theArgVec[++anArgIter]);
4448       Handle(Graphic3d_MediaTextureSet) aMedia = Handle(Graphic3d_MediaTextureSet)::DownCast (aTextureSetOld);
4449       if (aMedia.IsNull())
4450       {
4451         aMedia = new Graphic3d_MediaTextureSet();
4452       }
4453       if (aMedia->Input() != anInput)
4454       {
4455         aMedia->OpenInput (anInput, false);
4456       }
4457       else
4458       {
4459         if (aMedia->SwapFrames()
4460         && !aCtx->CurrentViewer()->ZLayerSettings (aTexturedIO->ZLayer()).IsImmediate())
4461         {
4462           ViewerTest::CurrentView()->Invalidate();
4463         }
4464       }
4465       if (aTexturedIO->Attributes()->SetupOwnShadingAspect (aCtx->DefaultDrawer())
4466        && aTexturedShape.IsNull())
4467       {
4468         aTexturedIO->SetToUpdate();
4469       }
4470
4471       toComputeUV = aTextureSetOld.IsNull();
4472       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (true);
4473       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aMedia);
4474       aTextureSetOld.Nullify();
4475     }
4476     else if (aCommandName == "vtexture"
4477           && (aTextureVecNew.IsEmpty()
4478            || aNameCase.StartsWith ("-tex")))
4479     {
4480       Standard_Integer aTexIndex = 0;
4481       TCollection_AsciiString aTexName = aName;
4482       if (aNameCase.StartsWith ("-tex"))
4483       {
4484         if (anArgIter + 1 >= theArgsNb
4485          || aNameCase.Length() < 5)
4486         {
4487           std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
4488           return 1;
4489         }
4490
4491         TCollection_AsciiString aTexIndexStr = aNameCase.SubString (5, aNameCase.Length());
4492         if (!aTexIndexStr.IsIntegerValue())
4493         {
4494           std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
4495           return 1;
4496         }
4497
4498         aTexIndex = aTexIndexStr.IntegerValue();
4499         aTexName  = theArgVec[anArgIter + 1];
4500         ++anArgIter;
4501       }
4502       if (aTexIndex >= Graphic3d_TextureUnit_NB
4503        || aTexIndex >= aCtx->CurrentViewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxCombinedTextureUnits))
4504       {
4505         std::cout << "Error: too many textures specified\n";
4506         return 1;
4507       }
4508
4509       toSetImage = true;
4510       if (aTexName.IsIntegerValue())
4511       {
4512         const Standard_Integer aValue = aTexName.IntegerValue();
4513         if (aValue < 0 || aValue >= Graphic3d_Texture2D::NumberOfTextures())
4514         {
4515           std::cout << "Syntax error: texture with ID " << aValue << " is undefined!\n";
4516           return 1;
4517         }
4518         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue)));
4519       }
4520       else if (aTexName == "?")
4521       {
4522         const TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
4523
4524         theDi << "\n Files in current directory : \n\n";
4525         theDi.Eval ("glob -nocomplain *");
4526
4527         TCollection_AsciiString aCmnd ("glob -nocomplain ");
4528         aCmnd += aTextureFolder;
4529         aCmnd += "/* ";
4530
4531         theDi << "Files in " << aTextureFolder << " : \n\n";
4532         theDi.Eval (aCmnd.ToCString());
4533         return 0;
4534       }
4535       else if (aTexName != "off")
4536       {
4537         if (!OSD_File (aTexName).Exists())
4538         {
4539           std::cout << "Syntax error: non-existing image file has been specified '" << aTexName << "'.\n";
4540           return 1;
4541         }
4542         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (aTexName));
4543       }
4544       else
4545       {
4546         aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_Texture2Dmanual)());
4547       }
4548
4549       if (aTextureVecNew.Value (aTexIndex))
4550       {
4551         aTextureVecNew.ChangeValue(aTexIndex)->GetParams()->SetTextureUnit((Graphic3d_TextureUnit)aTexIndex);
4552       }
4553     }
4554     else
4555     {
4556       std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
4557       return 1;
4558     }
4559   }
4560
4561   if (toSetImage)
4562   {
4563     // check if new image set is equal to already set one
4564     Standard_Integer aNbChanged = 0;
4565     Handle(Graphic3d_TextureSet) aTextureSetNew;
4566     if (!aTextureVecNew.IsEmpty())
4567     {
4568       aNbChanged = aTextureVecNew.Size();
4569       aTextureSetNew = new Graphic3d_TextureSet (aTextureVecNew.Size());
4570       for (Standard_Integer aTexIter = 0; aTexIter < aTextureSetNew->Size(); ++aTexIter)
4571       {
4572         Handle(Graphic3d_Texture2Dmanual)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter);
4573         Handle(Graphic3d_TextureRoot) aTextureOld;
4574         if (!aTextureSetOld.IsNull()
4575           && aTexIter < aTextureSetOld->Size())
4576         {
4577           aTextureOld = aTextureSetOld->Value (aTexIter);
4578         }
4579
4580         if (!aTextureOld.IsNull()
4581          && !aTextureNew.IsNull())
4582         {
4583           *aTextureNew->GetParams() = *aTextureOld->GetParams();
4584           if (Handle(Graphic3d_Texture2Dmanual) anOldManualTex = Handle(Graphic3d_Texture2Dmanual)::DownCast (aTextureOld))
4585           {
4586             TCollection_AsciiString aFilePathOld, aFilePathNew;
4587             aTextureOld->Path().SystemName (aFilePathOld);
4588             aTextureNew->Path().SystemName (aFilePathNew);
4589             if (aTextureNew->Name() == anOldManualTex->Name()
4590              && aFilePathOld == aFilePathNew
4591              && (!aFilePathNew.IsEmpty() || aTextureNew->Name() != Graphic3d_NOT_2D_UNKNOWN))
4592             {
4593               --aNbChanged;
4594               aTextureNew = anOldManualTex;
4595             }
4596           }
4597         }
4598         aTextureSetNew->SetValue (aTexIter, aTextureNew);
4599       }
4600     }
4601     if (aNbChanged == 0
4602      && ((aTextureSetOld.IsNull() && aTextureSetNew.IsNull())
4603       || (aTextureSetOld->Size() == aTextureSetNew->Size())))
4604     {
4605       aTextureSetNew = aTextureSetOld;
4606     }
4607
4608     if (aTexturedIO->Attributes()->SetupOwnShadingAspect (aCtx->DefaultDrawer())
4609      && aTexturedShape.IsNull())
4610     {
4611       aTexturedIO->SetToUpdate();
4612     }
4613
4614     toComputeUV = !aTextureSetNew.IsNull() && aTextureSetOld.IsNull();
4615     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (!aTextureSetNew.IsNull());
4616     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aTextureSetNew);
4617     aTextureSetOld.Nullify();
4618   }
4619
4620   if (toSetDefaults)
4621   {
4622     if (toModulate != -1)
4623     {
4624       toModulate = 1;
4625     }
4626     if (!toSetFilter)
4627     {
4628       toSetFilter = true;
4629       aFilter     = Graphic3d_TOTF_BILINEAR;
4630     }
4631     if (!toSetAniso)
4632     {
4633       toSetAniso    = true;
4634       anAnisoFilter = Graphic3d_LOTA_OFF;
4635     }
4636     if (!toSetTrsfAngle)
4637     {
4638       toSetTrsfAngle = true;
4639       aTrsfRotAngle  = 0.0f;
4640     }
4641     if (!toSetTrsfTrans)
4642     {
4643       toSetTrsfTrans = true;
4644       aTrsfTrans = Graphic3d_Vec2 (0.0f, 0.0f);
4645     }
4646     if (!toSetTrsfScale)
4647     {
4648       toSetTrsfScale = true;
4649       aTrsfScale = Graphic3d_Vec2 (1.0f, 1.0f);
4650     }
4651   }
4652
4653   if (aCommandName == "vtexture"
4654    && theArgsNb == 2)
4655   {
4656     if (!aTextureSetOld.IsNull())
4657     {
4658       //toComputeUV = true; // we can keep UV vertex attributes
4659       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
4660       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (Handle(Graphic3d_TextureSet)());
4661       aTextureSetOld.Nullify();
4662     }
4663   }
4664
4665   if (aTexturedIO->Attributes()->HasOwnShadingAspect()
4666   && !aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap().IsNull())
4667   {
4668     if (toModulate != -1)
4669     {
4670       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetModulate (toModulate == 1);
4671     }
4672     if (toSetTrsfAngle)
4673     {
4674       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetRotation (aTrsfRotAngle); // takes degrees
4675     }
4676     if (toSetTrsfTrans)
4677     {
4678       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetTranslation (aTrsfTrans);
4679     }
4680     if (toSetTrsfScale)
4681     {
4682       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetScale (aTrsfScale);
4683     }
4684     if (toSetFilter)
4685     {
4686       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetFilter (aFilter);
4687     }
4688     if (toSetAniso)
4689     {
4690       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetAnisoFilter (anAnisoFilter);
4691     }
4692   }
4693
4694   // set default values if requested
4695   if (!toSetGenRepeat
4696    && (aCommandName == "vtexrepeat"
4697     || toSetDefaults))
4698   {
4699     if (!aTexturedShape.IsNull())
4700     {
4701       aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
4702     }
4703     toSetGenRepeat = true;
4704   }
4705   if (!toSetGenOrigin
4706    && (aCommandName == "vtexorigin"
4707     || toSetDefaults))
4708   {
4709     if (!aTexturedShape.IsNull())
4710     {
4711       aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
4712     }
4713     toSetGenOrigin = true;
4714   }
4715   if (!toSetGenScale
4716    && (aCommandName == "vtexscale"
4717     || toSetDefaults))
4718   {
4719     if (!aTexturedShape.IsNull())
4720     {
4721       aTexturedShape->SetTextureScaleUV  (gp_Pnt2d (1.0, 1.0));
4722     }
4723     toSetGenScale = true;
4724   }
4725
4726   if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toComputeUV)
4727   {
4728     if (!aTexturedShape.IsNull())
4729     {
4730       aTexturedShape->SetToUpdate (AIS_Shaded);
4731       if (toSetImage)
4732       {
4733         if ((aTexturedIO->HasDisplayMode() && aTexturedIO->DisplayMode() != AIS_Shaded)
4734          || aCtx->DisplayMode() != AIS_Shaded)
4735         {
4736           aCtx->SetDisplayMode (aTexturedIO, AIS_Shaded, false);
4737         }
4738       }
4739     }
4740   }
4741   aCtx->Display (aTexturedIO, false);
4742   aTexturedIO->SynchronizeAspects();
4743   return 0;
4744 }
4745
4746 //! Auxiliary method to parse transformation persistence flags
4747 inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFlagString,
4748                                            Graphic3d_TransModeFlags&      theFlags)
4749 {
4750   if (theFlagString == "zoom")
4751   {
4752     theFlags = Graphic3d_TMF_ZoomPers;
4753   }
4754   else if (theFlagString == "rotate")
4755   {
4756     theFlags = Graphic3d_TMF_RotatePers;
4757   }
4758   else if (theFlagString == "zoomrotate")
4759   {
4760     theFlags = Graphic3d_TMF_ZoomRotatePers;
4761   }
4762   else if (theFlagString == "trihedron"
4763         || theFlagString == "triedron")
4764   {
4765     theFlags = Graphic3d_TMF_TriedronPers;
4766   }
4767   else if (theFlagString == "none")
4768   {
4769     theFlags = Graphic3d_TMF_None;
4770   }
4771   else
4772   {
4773     return Standard_False;
4774   }
4775
4776   return Standard_True;
4777 }
4778
4779 //! Auxiliary method to parse transformation persistence flags
4780 inline Standard_Boolean parseTrsfPersCorner (const TCollection_AsciiString& theString,
4781                                              Aspect_TypeOfTriedronPosition& theCorner)
4782 {
4783   TCollection_AsciiString aString (theString);
4784   aString.LowerCase();
4785   if (aString == "center")
4786   {
4787     theCorner = Aspect_TOTP_CENTER;
4788   }
4789   else if (aString == "top"
4790         || aString == "upper")
4791   {
4792     theCorner = Aspect_TOTP_TOP;
4793   }
4794   else if (aString == "bottom"
4795         || aString == "lower")
4796   {
4797     theCorner = Aspect_TOTP_BOTTOM;
4798   }
4799   else if (aString == "left")
4800   {
4801     theCorner = Aspect_TOTP_LEFT;
4802   }
4803   else if (aString == "right")
4804   {
4805     theCorner = Aspect_TOTP_RIGHT;
4806   }
4807   else if (aString == "topleft"
4808         || aString == "leftupper"
4809         || aString == "upperleft")
4810   {
4811     theCorner = Aspect_TOTP_LEFT_UPPER;
4812   }
4813   else if (aString == "bottomleft"
4814         || aString == "leftlower"
4815         || aString == "lowerleft")
4816   {
4817     theCorner = Aspect_TOTP_LEFT_LOWER;
4818   }
4819   else if (aString == "topright"
4820         || aString == "rightupper"
4821         || aString == "upperright")
4822   {
4823     theCorner = Aspect_TOTP_RIGHT_UPPER;
4824   }
4825   else if (aString == "bottomright"
4826         || aString == "lowerright"
4827         || aString == "rightlower")
4828   {
4829     theCorner = Aspect_TOTP_RIGHT_LOWER;
4830   }
4831   else
4832   {
4833     return Standard_False;
4834   }
4835
4836   return Standard_True;
4837 }
4838
4839 //==============================================================================
4840 //function : VDisplay2
4841 //author   : ege
4842 //purpose  : Display an object from its name
4843 //==============================================================================
4844 static int VDisplay2 (Draw_Interpretor& theDI,
4845                       Standard_Integer  theArgNb,
4846                       const char**      theArgVec)
4847 {
4848   if (theArgNb < 2)
4849   {
4850     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
4851     return 1;
4852   }
4853   if (theArgNb == 2
4854    && TCollection_AsciiString (theArgVec[1]) == "*")
4855   {
4856     // alias
4857     return VDisplayAll (theDI, 1, theArgVec);
4858   }
4859
4860   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
4861   if (aCtx.IsNull())
4862   {
4863     ViewerTest::ViewerInit();
4864     aCtx = ViewerTest::GetAISContext();
4865   }
4866
4867   // Parse input arguments
4868   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4869   Standard_Integer   isMutable      = -1;
4870   Graphic3d_ZLayerId aZLayer        = Graphic3d_ZLayerId_UNKNOWN;
4871   Standard_Boolean   toReDisplay    = Standard_False;
4872   Standard_Integer   isSelectable   = -1;
4873   Standard_Integer   anObjDispMode  = -2;
4874   Standard_Integer   anObjHighMode  = -2;
4875   Standard_Boolean   toSetTrsfPers  = Standard_False;
4876   Handle(Graphic3d_TransformPers) aTrsfPers;
4877   TColStd_SequenceOfAsciiString aNamesOfDisplayIO;
4878   AIS_DisplayStatus aDispStatus = AIS_DS_None;
4879   Standard_Integer toDisplayInView = Standard_False;
4880   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4881   {
4882     const TCollection_AsciiString aName     = theArgVec[anArgIter];
4883     TCollection_AsciiString       aNameCase = aName;
4884     aNameCase.LowerCase();
4885     if (anUpdateTool.parseRedrawMode (aName))
4886     {
4887       continue;
4888     }
4889     else if (aNameCase == "-mutable")
4890     {
4891       isMutable = 1;
4892     }
4893     else if (aNameCase == "-neutral")
4894     {
4895       aDispStatus = AIS_DS_Displayed;
4896     }
4897     else if (aNameCase == "-immediate"
4898           || aNameCase == "-top")
4899     {
4900       aZLayer = Graphic3d_ZLayerId_Top;
4901     }
4902     else if (aNameCase == "-topmost")
4903     {
4904       aZLayer = Graphic3d_ZLayerId_Topmost;
4905     }
4906     else if (aNameCase == "-osd"
4907           || aNameCase == "-toposd"
4908           || aNameCase == "-overlay")
4909     {
4910       aZLayer = Graphic3d_ZLayerId_TopOSD;
4911     }
4912     else if (aNameCase == "-botosd"
4913           || aNameCase == "-underlay")
4914     {
4915       aZLayer = Graphic3d_ZLayerId_BotOSD;
4916     }
4917     else if (aNameCase == "-select"
4918           || aNameCase == "-selectable")
4919     {
4920       isSelectable = 1;
4921     }
4922     else if (aNameCase == "-noselect"
4923           || aNameCase == "-noselection")
4924     {
4925       isSelectable = 0;
4926     }
4927     else if (aNameCase == "-dispmode"
4928           || aNameCase == "-displaymode")
4929     {
4930       if (++anArgIter >= theArgNb)
4931       {
4932         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4933         return 1;
4934       }
4935
4936       anObjDispMode = Draw::Atoi (theArgVec [anArgIter]);
4937     }
4938     else if (aNameCase == "-himode"
4939           || aNameCase == "-highmode"
4940           || aNameCase == "-highlightmode")
4941     {
4942       if (++anArgIter >= theArgNb)
4943       {
4944         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4945         return 1;
4946       }
4947
4948       anObjHighMode = Draw::Atoi (theArgVec [anArgIter]);
4949     }
4950     else if (aNameCase == "-3d")
4951     {
4952       toSetTrsfPers  = Standard_True;
4953       aTrsfPers.Nullify();
4954     }
4955     else if (aNameCase == "-2d"
4956           || aNameCase == "-trihedron"
4957           || aNameCase == "-triedron")
4958     {
4959       toSetTrsfPers  = Standard_True;
4960       aTrsfPers = new Graphic3d_TransformPers (aNameCase == "-2d" ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
4961
4962       if (anArgIter + 1 < theArgNb)
4963       {
4964         Aspect_TypeOfTriedronPosition aCorner = Aspect_TOTP_CENTER;
4965         if (parseTrsfPersCorner (theArgVec[anArgIter + 1], aCorner))
4966         {
4967           ++anArgIter;
4968           aTrsfPers->SetCorner2d (aCorner);
4969
4970           if (anArgIter + 2 < theArgNb)
4971           {
4972             TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
4973             TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
4974             if (anX.IsIntegerValue()
4975              && anY.IsIntegerValue())
4976             {
4977               anArgIter += 2;
4978               aTrsfPers->SetOffset2d (Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue()));
4979             }
4980           }
4981         }
4982       }
4983     }
4984     else if (aNameCase == "-trsfpers"
4985           || aNameCase == "-pers")
4986     {
4987       if (++anArgIter >= theArgNb
4988        || !aTrsfPers.IsNull())
4989       {
4990         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4991         return 1;
4992       }
4993
4994       toSetTrsfPers  = Standard_True;
4995       Graphic3d_TransModeFlags aTrsfPersFlags = Graphic3d_TMF_None;
4996       TCollection_AsciiString aPersFlags (theArgVec [anArgIter]);
4997       aPersFlags.LowerCase();
4998       if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
4999       {
5000         std::cerr << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".\n";
5001         return 1;
5002       }
5003
5004       if (aTrsfPersFlags == Graphic3d_TMF_TriedronPers)
5005       {
5006         aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
5007       }
5008       else if (aTrsfPersFlags != Graphic3d_TMF_None)
5009       {
5010         aTrsfPers = new Graphic3d_TransformPers (aTrsfPersFlags, gp_Pnt());
5011       }
5012     }
5013     else if (aNameCase == "-trsfperspos"
5014           || aNameCase == "-perspos")
5015     {
5016       if (anArgIter + 2 >= theArgNb
5017        || aTrsfPers.IsNull())
5018       {
5019         std::cerr << "Error: wrong syntax at " << aName << ".\n";
5020         return 1;
5021       }
5022
5023       TCollection_AsciiString aX (theArgVec[++anArgIter]);
5024       TCollection_AsciiString aY (theArgVec[++anArgIter]);
5025       TCollection_AsciiString aZ = "0";
5026       if (!aX.IsRealValue()
5027        || !aY.IsRealValue())
5028       {
5029         std::cerr << "Error: wrong syntax at " << aName << ".\n";
5030         return 1;
5031       }
5032       if (anArgIter + 1 < theArgNb)
5033       {
5034         TCollection_AsciiString aTemp = theArgVec[anArgIter + 1];
5035         if (aTemp.IsRealValue())
5036         {
5037           aZ = aTemp;
5038           ++anArgIter;
5039         }
5040       }
5041
5042       const gp_Pnt aPnt (aX.RealValue(), aY.RealValue(), aZ.RealValue());
5043       if (aTrsfPers->IsZoomOrRotate())
5044       {
5045         aTrsfPers->SetAnchorPoint (aPnt);
5046       }
5047       else if (aTrsfPers->IsTrihedronOr2d())
5048       {
5049         aTrsfPers = Graphic3d_TransformPers::FromDeprecatedParams (aTrsfPers->Mode(), aPnt);
5050       }
5051     }
5052     else if (aNameCase == "-layer"
5053           || aNameCase == "-zlayer")
5054     {
5055       ++anArgIter;
5056       if (anArgIter >= theArgNb
5057       || !ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer)
5058       ||  aZLayer == Graphic3d_ZLayerId_UNKNOWN)
5059       {
5060         std::cerr << "Error: wrong syntax at " << aName << ".\n";
5061         return 1;
5062       }
5063     }
5064     else if (aNameCase == "-view"
5065           || aNameCase == "-inview")
5066     {
5067       toDisplayInView = Standard_True;
5068     }
5069     else if (aNameCase == "-redisplay")
5070     {
5071       toReDisplay = Standard_True;
5072     }
5073     else if (aNameCase == "-erased"
5074           || aNameCase == "-load")
5075     {
5076       aDispStatus = AIS_DS_Erased;
5077     }
5078     else
5079     {
5080       aNamesOfDisplayIO.Append (aName);
5081     }
5082   }
5083
5084   if (aNamesOfDisplayIO.IsEmpty())
5085   {
5086     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
5087     return 1;
5088   }
5089
5090   // Display interactive objects
5091   for (Standard_Integer anIter = 1; anIter <= aNamesOfDisplayIO.Length(); ++anIter)
5092   {
5093     const TCollection_AsciiString& aName = aNamesOfDisplayIO.Value (anIter);
5094     Handle(AIS_InteractiveObject) aShape;
5095     if (!GetMapOfAIS().Find2 (aName, aShape))
5096     {
5097       // create the AIS_Shape from a name
5098       TopoDS_Shape aDrawShape = DBRep::GetExisting (aName);
5099       if (!aDrawShape.IsNull())
5100       {
5101         aShape = new AIS_Shape (aDrawShape);
5102         if (isMutable != -1)
5103         {
5104           aShape->SetMutable (isMutable == 1);
5105         }
5106         if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
5107         {
5108           aShape->SetZLayer (aZLayer);
5109         }
5110         if (toSetTrsfPers)
5111         {
5112           aCtx->SetTransformPersistence (aShape, aTrsfPers);
5113         }
5114         if (anObjDispMode != -2)
5115         {
5116           if (anObjDispMode == -1)
5117           {
5118             aShape->UnsetDisplayMode();
5119           }
5120           if (!aShape->AcceptDisplayMode (anObjDispMode))
5121           {
5122             std::cout << "Syntax error: " << aShape->DynamicType()->Name() << " rejects " << anObjDispMode << " display mode\n";
5123             return 1;
5124           }
5125           else
5126           {
5127             aShape->SetDisplayMode (anObjDispMode);
5128           }
5129         }
5130         if (anObjHighMode != -2)
5131         {
5132           if (anObjHighMode != -1
5133           && !aShape->AcceptDisplayMode (anObjHighMode))
5134           {
5135             std::cout << "Syntax error: " << aShape->DynamicType()->Name() << " rejects " << anObjHighMode << " display mode\n";
5136             return 1;
5137           }
5138           aShape->SetHilightMode (anObjHighMode);
5139         }
5140
5141         GetMapOfAIS().Bind (aShape, aName);
5142         Standard_Integer aDispMode = aShape->HasDisplayMode()
5143                                    ? aShape->DisplayMode()
5144                                    : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
5145                                     ? aCtx->DisplayMode()
5146                                     : 0);
5147         Standard_Integer aSelMode = -1;
5148         if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
5149         {
5150           aSelMode = aShape->GlobalSelectionMode();
5151         }
5152
5153         aCtx->Display (aShape, aDispMode, aSelMode, Standard_False, aDispStatus);
5154         if (toDisplayInView)
5155         {
5156           for (V3d_ListOfViewIterator aViewIter (aCtx->CurrentViewer()->DefinedViewIterator()); aViewIter.More(); aViewIter.Next())
5157           {
5158             aCtx->SetViewAffinity (aShape, aViewIter.Value(), Standard_False);
5159           }
5160           aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
5161         }
5162       }
5163       else
5164       {
5165         std::cerr << "Error: object with name '" << aName << "' does not exist!\n";
5166       }
5167       continue;
5168     }
5169
5170     if (isMutable != -1)
5171     {
5172       aShape->SetMutable (isMutable == 1);
5173     }
5174     if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
5175     {
5176       aShape->SetZLayer (aZLayer);
5177     }
5178     if (toSetTrsfPers)
5179     {
5180       aCtx->SetTransformPersistence (aShape, aTrsfPers);
5181     }
5182     if (anObjDispMode != -2)
5183     {
5184       aShape->SetDisplayMode (anObjDispMode);
5185     }
5186     if (anObjHighMode != -2)
5187     {
5188       aShape->SetHilightMode (anObjHighMode);
5189     }
5190     Standard_Integer aDispMode = aShape->HasDisplayMode()
5191                                 ? aShape->DisplayMode()
5192                                 : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
5193                                 ? aCtx->DisplayMode()
5194                                 : 0);
5195     Standard_Integer aSelMode = -1;
5196     if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
5197     {
5198       aSelMode = aShape->GlobalSelectionMode();
5199     }
5200
5201     if (aShape->Type() == AIS_KOI_Datum)
5202     {
5203       aCtx->Display (aShape, Standard_False);
5204     }
5205     else
5206     {
5207       theDI << "Display " << aName << "\n";
5208
5209       // update the Shape in the AIS_Shape
5210       TopoDS_Shape      aNewShape = DBRep::GetExisting (aName);
5211       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aShape);
5212       if (!aShapePrs.IsNull())
5213       {
5214         if (!aShapePrs->Shape().IsEqual (aNewShape))
5215         {
5216           toReDisplay = Standard_True;
5217         }
5218         aShapePrs->Set (aNewShape);
5219       }
5220       if (toReDisplay)
5221       {
5222         aCtx->Redisplay (aShape, Standard_False);
5223       }
5224
5225       if (aSelMode == -1)
5226       {
5227         aCtx->Erase (aShape, Standard_False);
5228       }
5229       aCtx->Display (aShape, aDispMode, aSelMode, Standard_False, aDispStatus);
5230       if (toDisplayInView)
5231       {
5232         aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
5233       }
5234     }
5235   }
5236
5237   return 0;
5238 }
5239
5240 //=======================================================================
5241 //function : VNbDisplayed
5242 //purpose  : Returns number of displayed objects
5243 //=======================================================================
5244 static Standard_Integer VNbDisplayed (Draw_Interpretor& theDi,
5245                                       Standard_Integer theArgsNb,
5246                                       const char** theArgVec)
5247 {
5248   if(theArgsNb != 1)
5249   {
5250     theDi << "Usage : " << theArgVec[0] << "\n";
5251     return 1;
5252   }
5253
5254   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5255   if (aContextAIS.IsNull())
5256   {
5257     std::cout << theArgVec[0] << "AIS context is not available.\n";
5258     return 1;
5259   }
5260
5261   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5262   if(aContext.IsNull())
5263   {
5264     theDi << "use 'vinit' command before " << theArgVec[0] << "\n";
5265     return 1;
5266   }
5267
5268   AIS_ListOfInteractive aListOfIO;
5269   aContextAIS->DisplayedObjects (aListOfIO);
5270
5271   theDi << aListOfIO.Extent() << "\n";
5272   return 0;
5273 }
5274
5275 //===============================================================================================
5276 //function : VUpdate
5277 //purpose  :
5278 //===============================================================================================
5279 static int VUpdate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
5280 {
5281   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5282   if (aContextAIS.IsNull())
5283   {
5284     std::cout << theArgVec[0] << "AIS context is not available.\n";
5285     return 1;
5286   }
5287
5288   if (theArgsNb < 2)
5289   {
5290     std::cout << theArgVec[0] << ": insufficient arguments. Type help for more information.\n";
5291     return 1;
5292   }
5293
5294   AIS_ListOfInteractive aListOfIO;
5295   for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
5296   {
5297     TCollection_AsciiString aName = TCollection_AsciiString (theArgVec[anArgIt]);
5298
5299     Handle(AIS_InteractiveObject) anAISObj;
5300     GetMapOfAIS().Find2 (aName, anAISObj);
5301     if (anAISObj.IsNull())
5302     {
5303       std::cout << theArgVec[0] << ": no AIS interactive object named \"" << aName << "\".\n";
5304       return 1;
5305     }
5306
5307     aListOfIO.Append (anAISObj);
5308   }
5309
5310   AIS_ListIteratorOfListOfInteractive anIOIt (aListOfIO);
5311   for (; anIOIt.More(); anIOIt.Next())
5312   {
5313     aContextAIS->Update (anIOIt.Value(), Standard_False);
5314   }
5315
5316   aContextAIS->UpdateCurrentViewer();
5317
5318   return 0;
5319 }
5320
5321 //==============================================================================
5322 //function : VShading
5323 //purpose  : Sharpen or roughten the quality of the shading
5324 //Draw arg : vshading ShapeName 0.1->0.00001  1 deg-> 30 deg
5325 //==============================================================================
5326 static int VShading(Draw_Interpretor& ,Standard_Integer argc, const char** argv)
5327 {
5328   Standard_Real    myDevCoef;
5329   Handle(AIS_InteractiveObject) TheAisIO;
5330
5331   // Verifications
5332   const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetshading") == 0);
5333   if (argc < 3) {
5334     myDevCoef  = 0.0008;
5335   } else {
5336     myDevCoef  =Draw::Atof(argv[2]);
5337   }
5338
5339   TCollection_AsciiString name=argv[1];
5340   GetMapOfAIS().Find2(name, TheAisIO);
5341   if (TheAisIO.IsNull())
5342   {
5343     TopoDS_Shape aDrawShape = DBRep::GetExisting (name);
5344     if (!aDrawShape.IsNull())
5345     {
5346       TheAisIO = new AIS_Shape (aDrawShape);
5347     }
5348   }
5349
5350   if (HaveToSet)
5351     TheAISContext()->SetDeviationCoefficient(TheAisIO,myDevCoef,Standard_True);
5352   else
5353     TheAISContext()->SetDeviationCoefficient(TheAisIO,0.0008,Standard_True);
5354
5355   TheAISContext()->Redisplay (TheAisIO, Standard_True);
5356   return 0;
5357 }
5358
5359 //! Auxiliary method to print Interactive Object information
5360 static void objInfo (const NCollection_Map<Handle(AIS_InteractiveObject)>& theDetected,
5361                      const Handle(AIS_InteractiveObject)&                  theObj,
5362                      Draw_Interpretor&                                     theDI)
5363 {
5364   if (theObj.IsNull())
5365   {
5366     theDI << "NULL presentation\n";
5367     return;
5368   }
5369
5370   theDI << (TheAISContext()->IsDisplayed (theObj) ? "Displayed"  : "Hidden   ")
5371         << (TheAISContext()->IsSelected  (theObj) ? " Selected" : "         ")
5372         << (theDetected.Contains (theObj)         ? " Detected" : "         ")
5373         << " Type: ";
5374   if (theObj->Type() == AIS_KOI_Datum)
5375   {
5376     // AIS_Datum
5377     if      (theObj->Signature() == 3) { theDI << " AIS_Trihedron"; }
5378     else if (theObj->Signature() == 2) { theDI << " AIS_Axis"; }
5379     else if (theObj->Signature() == 6) { theDI << " AIS_Circle"; }
5380     else if (theObj->Signature() == 5) { theDI << " AIS_Line"; }
5381     else if (theObj->Signature() == 7) { theDI << " AIS_Plane"; }
5382     else if (theObj->Signature() == 1) { theDI << " AIS_Point"; }
5383     else if (theObj->Signature() == 4) { theDI << " AIS_PlaneTrihedron"; }
5384   }
5385   // AIS_Shape
5386   else if (theObj->Type()      == AIS_KOI_Shape
5387         && theObj->Signature() == 0)
5388   {
5389     theDI << " AIS_Shape";
5390   }
5391   else if (theObj->Type() == AIS_KOI_Relation)
5392   {
5393     // AIS_Dimention and AIS_Relation
5394     Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (theObj);
5395     switch (aRelation->KindOfDimension())
5396     {
5397       case AIS_KOD_PLANEANGLE:     theDI << " AIS_AngleDimension"; break;
5398       case AIS_KOD_LENGTH:         theDI << " AIS_Chamf2/3dDimension/AIS_LengthDimension"; break;
5399       case AIS_KOD_DIAMETER:       theDI << " AIS_DiameterDimension"; break;
5400       case AIS_KOD_ELLIPSERADIUS:  theDI << " AIS_EllipseRadiusDimension"; break;
5401       //case AIS_KOD_FILLETRADIUS:   theDI << " AIS_FilletRadiusDimension "; break;
5402       case AIS_KOD_OFFSET:         theDI << " AIS_OffsetDimension"; break;
5403       case AIS_KOD_RADIUS:         theDI << " AIS_RadiusDimension"; break;
5404       default:                     theDI << " UNKNOWN dimension"; break;
5405     }
5406   }
5407   else
5408   {
5409     theDI << " UserPrs";
5410   }
5411   theDI << " (" << theObj->DynamicType()->Name() << ")";
5412 }
5413
5414 //! Print information about locally selected sub-shapes
5415 template <typename T>
5416 static void printLocalSelectionInfo (const T& theContext, Draw_Interpretor& theDI)
5417 {
5418   const Standard_Boolean isGlobalCtx = (theContext->DynamicType() == STANDARD_TYPE(AIS_InteractiveContext));
5419   TCollection_AsciiString aPrevName;
5420   for (theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected())
5421   {
5422     const Handle(AIS_Shape) aShapeIO = Handle(AIS_Shape)::DownCast (theContext->SelectedInteractive());
5423     const Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner();
5424     if (aShapeIO.IsNull() || anOwner.IsNull())
5425       continue;
5426     if (isGlobalCtx)
5427     {
5428       if (anOwner == aShapeIO->GlobalSelOwner())
5429         continue;
5430     }
5431     const TopoDS_Shape      aSubShape = theContext->SelectedShape();
5432     if (aSubShape.IsNull()
5433       || aShapeIO.IsNull()
5434       || !GetMapOfAIS().IsBound1 (aShapeIO))
5435     {
5436       continue;
5437     }
5438
5439     const TCollection_AsciiString aParentName = GetMapOfAIS().Find1 (aShapeIO);
5440     TopTools_MapOfShape aFilter;
5441     Standard_Integer    aNumber = 0;
5442     const TopoDS_Shape  aShape  = aShapeIO->Shape();
5443     for (TopExp_Explorer anIter (aShape, aSubShape.ShapeType());
5444          anIter.More(); anIter.Next())
5445     {
5446       if (!aFilter.Add (anIter.Current()))
5447       {
5448         continue; // filter duplicates
5449       }
5450
5451       ++aNumber;
5452       if (!anIter.Current().IsSame (aSubShape))
5453       {
5454         continue;
5455       }
5456
5457       Standard_CString aShapeName = NULL;
5458       switch (aSubShape.ShapeType())
5459       {
5460         case TopAbs_COMPOUND:  aShapeName = " Compound"; break;
5461         case TopAbs_COMPSOLID: aShapeName = "CompSolid"; break;
5462         case TopAbs_SOLID:     aShapeName = "    Solid"; break;
5463         case TopAbs_SHELL:     aShapeName = "    Shell"; break;
5464         case TopAbs_FACE:      aShapeName = "     Face"; break;
5465         case TopAbs_WIRE:      aShapeName = "     Wire"; break;
5466         case TopAbs_EDGE:      aShapeName = "     Edge"; break;
5467         case TopAbs_VERTEX:    aShapeName = "   Vertex"; break;
5468         default:
5469         case TopAbs_SHAPE:     aShapeName = "    Shape"; break;
5470       }
5471
5472       if (aParentName != aPrevName)
5473       {
5474         theDI << "Locally selected sub-shapes within " << aParentName << ":\n";
5475         aPrevName = aParentName;
5476       }
5477       theDI << "  " << aShapeName << " #" << aNumber << "\n";
5478       break;
5479     }
5480   }
5481 }
5482
5483 //==============================================================================
5484 //function : VState
5485 //purpose  :
5486 //==============================================================================
5487 static Standard_Integer VState (Draw_Interpretor& theDI,
5488                                 Standard_Integer  theArgNb,
5489                                 Standard_CString* theArgVec)
5490 {
5491   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
5492   if (aCtx.IsNull())
5493   {
5494     std::cerr << "Error: No opened viewer!\n";
5495     return 1;
5496   }
5497
5498   Standard_Boolean toPrintEntities = Standard_False;
5499   Standard_Boolean toCheckSelected = Standard_False;
5500
5501   for (Standard_Integer anArgIdx = 1; anArgIdx < theArgNb; ++anArgIdx)
5502   {
5503     TCollection_AsciiString anOption (theArgVec[anArgIdx]);
5504     anOption.LowerCase();
5505     if (anOption == "-detectedentities"
5506       || anOption == "-entities")
5507     {
5508       toPrintEntities = Standard_True;
5509     }
5510     else if (anOption == "-hasselected")
5511     {
5512       toCheckSelected = Standard_True;
5513     }
5514   }
5515
5516   if (toCheckSelected)
5517   {
5518     aCtx->InitSelected();
5519     TCollection_AsciiString hasSelected (static_cast<Standard_Integer> (aCtx->HasSelectedShape()));
5520     theDI << "Check if context has selected shape: " << hasSelected << "\n";
5521
5522     return 0;
5523   }
5524
5525   if (toPrintEntities)
5526   {
5527     theDI << "Detected entities:\n";
5528     Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->MainSelector();
5529
5530     SelectMgr_SelectingVolumeManager aMgr = aSelector->GetManager();
5531     for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
5532     {
5533       const SelectMgr_SortCriterion&         aPickData = aSelector->PickedData (aPickIter);
5534       const Handle(Select3D_SensitiveEntity)& anEntity = aSelector->PickedEntity (aPickIter);
5535       const Handle(SelectMgr_EntityOwner)& anOwner = anEntity->OwnerId();
5536       Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
5537
5538       TCollection_AsciiString aName;
5539       GetMapOfAIS().Find1 (anObj, aName);
5540       aName.LeftJustify (20, ' ');
5541       char anInfoStr[512];
5542       Sprintf (anInfoStr,
5543                " Depth: %g Distance: %g Point: %g %g %g",
5544                aPickData.Depth,
5545                aPickData.MinDist,
5546                aPickData.Point.X(), aPickData.Point.Y(), aPickData.Point.Z());
5547       theDI << "  " << aName
5548             << anInfoStr
5549             << " (" << anEntity->DynamicType()->Name() << ")"
5550             << "\n";
5551
5552       Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
5553       if (!aBRepOwner.IsNull())
5554       {
5555         theDI << "                       Detected Shape: "
5556               << aBRepOwner->Shape().TShape()->DynamicType()->Name()
5557               << "\n";
5558       }
5559
5560       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast (anEntity);
5561       if (!aWire.IsNull())
5562       {
5563         Handle(Select3D_SensitiveEntity) aSen = aWire->GetLastDetected();
5564         theDI << "                       Detected Child: "
5565               << aSen->DynamicType()->Name()
5566               << "\n";
5567       }
5568
5569       Handle(Select3D_SensitivePrimitiveArray) aPrimArr = Handle(Select3D_SensitivePrimitiveArray)::DownCast (anEntity);
5570       if (!aPrimArr.IsNull())
5571       {
5572         theDI << "                       Detected Element: "
5573               << aPrimArr->LastDetectedElement()
5574               << "\n";
5575       }
5576     }
5577     return 0;
5578   }
5579
5580   NCollection_Map<Handle(AIS_InteractiveObject)> aDetected;
5581   for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected())
5582   {
5583     aDetected.Add (Handle(AIS_InteractiveObject)::DownCast (aCtx->DetectedCurrentOwner()->Selectable()));
5584   }
5585
5586   const Standard_Boolean toShowAll = (theArgNb >= 2 && *theArgVec[1] == '*');
5587   if (theArgNb >= 2
5588    && !toShowAll)
5589   {
5590     for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5591     {
5592       const TCollection_AsciiString anObjName = theArgVec[anArgIter];
5593       Handle(AIS_InteractiveObject) anObj;
5594       if (!GetMapOfAIS().Find2 (anObjName, anObj))
5595       {
5596         theDI << anObjName << " doesn't exist!\n";
5597         continue;
5598       }
5599
5600       TCollection_AsciiString aName = anObjName;
5601       aName.LeftJustify (20, ' ');
5602       theDI << "  " << aName << " ";
5603       objInfo (aDetected, anObj, theDI);
5604       theDI << "\n";
5605     }
5606     return 0;
5607   }
5608
5609   if (aCtx->NbSelected() > 0 && !toShowAll)
5610   {
5611     NCollection_DataMap<Handle(SelectMgr_EntityOwner), TopoDS_Shape> anOwnerShapeMap;
5612     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
5613     {
5614       const Handle(SelectMgr_EntityOwner) anOwner = aCtx->SelectedOwner();
5615       const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
5616       // handle whole object selection
5617       if (anOwner == anObj->GlobalSelOwner())
5618       {
5619         TCollection_AsciiString aName;
5620         GetMapOfAIS().Find1 (anObj, aName);
5621         aName.LeftJustify (20, ' ');
5622         theDI << aName << " ";
5623         objInfo (aDetected, anObj, theDI);
5624         theDI << "\n";
5625       }
5626     }
5627
5628     // process selected sub-shapes
5629     printLocalSelectionInfo (aCtx, theDI);
5630
5631     return 0;
5632   }
5633
5634   theDI << "Neutral-point state:\n";
5635   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5636        anObjIter.More(); anObjIter.Next())
5637   {
5638     if (anObjIter.Key1().IsNull())
5639     {
5640       continue;
5641     }
5642
5643     TCollection_AsciiString aName = anObjIter.Key2();
5644     aName.LeftJustify (20, ' ');
5645     theDI << "  " << aName << " ";
5646     objInfo (aDetected, anObjIter.Key1(), theDI);
5647     theDI << "\n";
5648   }
5649   printLocalSelectionInfo (aCtx, theDI);
5650   return 0;
5651 }
5652
5653 //=======================================================================
5654 //function : PickShape
5655 //purpose  : First Activate the rightmode + Put Filters to be able to
5656 //           pick objets that are of type <TheType>...
5657 //=======================================================================
5658
5659 TopoDS_Shape ViewerTest::PickShape (const TopAbs_ShapeEnum theShapeType,
5660                                     const Standard_Integer theMaxPick)
5661 {
5662   Handle(TopTools_HArray1OfShape) aResArray = new TopTools_HArray1OfShape (1, 1);
5663   PickShapes (theShapeType, aResArray, theMaxPick);
5664   return aResArray->First();
5665 }
5666
5667 //=======================================================================
5668 //function : PickShapes
5669 //purpose  :
5670 //=======================================================================
5671 Standard_Boolean ViewerTest::PickShapes (const TopAbs_ShapeEnum theShapeType,
5672                                          Handle(TopTools_HArray1OfShape)& theResArray,
5673                                          const Standard_Integer theMaxPick)
5674 {
5675   const Standard_Integer aNbToReach = theResArray->Length();
5676   if (aNbToReach > 1)
5677   {
5678     std::cout << " WARNING : Pick with Shift+ MB1 for Selection of more than 1 object\n";
5679   }
5680
5681   // step 1: prepare the data
5682   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
5683   aCtx->RemoveFilters();
5684   AIS_ListOfInteractive aDispObjects;
5685   aCtx->DisplayedObjects (aDispObjects);
5686   if (theShapeType == TopAbs_SHAPE)
5687   {
5688     aCtx->AddFilter (new AIS_TypeFilter (AIS_KOI_Shape));
5689   }
5690   else
5691   {
5692     aCtx->AddFilter (new StdSelect_ShapeTypeFilter (theShapeType));
5693   }
5694
5695   const Standard_Integer aSelMode = AIS_Shape::SelectionMode (theShapeType);
5696   for (AIS_ListOfInteractive::Iterator anObjIter (aDispObjects); anObjIter.More(); anObjIter.Next())
5697   {
5698     if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (anObjIter.Value()))
5699     {
5700       aCtx->SetSelectionModeActive (aShapePrs, aSelMode, true, AIS_SelectionModesConcurrency_Single);
5701     }
5702   }
5703
5704   // step 2 : wait for the selection...
5705   Standard_Integer aNbPickGood = 0, aNbPickFail = 0;
5706   Standard_Integer argccc = 5;
5707   const char *bufff[] = { "A", "B", "C", "D", "E" };
5708   const char **argvvv = (const char** )bufff;
5709   for (; aNbPickGood < aNbToReach && aNbPickFail <= theMaxPick; )
5710   {
5711     while (ViewerMainLoop (argccc, argvvv)) {}
5712     Standard_Integer aNbStored = aCtx->NbSelected();
5713     if (aNbStored != aNbPickGood)
5714     {
5715       aNbPickGood = aNbStored;
5716     }
5717     else
5718     {
5719       ++aNbPickFail;
5720     }
5721     std::cout << "NbPicked =  " << aNbPickGood << " |  Nb Pick Fail :" << aNbPickFail << "\n";
5722   }
5723
5724   // step3 get result.
5725   if (aNbPickFail >= aNbToReach)
5726   {
5727     return Standard_False;
5728   }
5729
5730   Standard_Integer anIndex = theResArray->Lower();
5731   for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected(), ++anIndex)
5732   {
5733     if (aCtx->HasSelectedShape())
5734     {
5735       theResArray->SetValue (anIndex, aCtx->SelectedShape());
5736     }
5737     else
5738     {
5739       Handle(AIS_InteractiveObject) IO = aCtx->SelectedInteractive();
5740       theResArray->SetValue (anIndex, Handle(AIS_Shape)::DownCast (IO)->Shape());
5741     }
5742   }
5743
5744   aCtx->RemoveFilters();
5745   if (theShapeType != TopAbs_SHAPE)
5746   {
5747     for (AIS_ListOfInteractive::Iterator anObjIter (aDispObjects); anObjIter.More(); anObjIter.Next())
5748     {
5749       if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (anObjIter.Value()))
5750       {
5751         aCtx->SetSelectionModeActive (aShapePrs, aSelMode, true, AIS_SelectionModesConcurrency_Single);
5752       }
5753     }
5754   }
5755   return Standard_True;
5756 }
5757
5758 //=======================================================================
5759 //function : VPickShape
5760 //purpose  :
5761 //=======================================================================
5762 static int VPickShape( Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5763 {
5764   TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
5765   if (argc != 1)
5766   {
5767     TCollection_AsciiString aShapeArg (argv[1]);
5768     aShapeArg.LowerCase();
5769     aShapeType = TopAbs_COMPOUND;
5770     if      (aShapeArg == "v"
5771           || aShapeArg == "vertex") aShapeType = TopAbs_VERTEX;
5772     else if (aShapeArg == "e"
5773           || aShapeArg == "edge")   aShapeType = TopAbs_EDGE;
5774     else if (aShapeArg == "w"
5775           || aShapeArg == "wire")   aShapeType = TopAbs_WIRE;
5776     else if (aShapeArg == "f"
5777           || aShapeArg == "face")   aShapeType = TopAbs_FACE;
5778     else if (aShapeArg == "shape")  aShapeType = TopAbs_SHAPE;
5779     else if (aShapeArg == "shell")  aShapeType = TopAbs_SHELL;
5780     else if (aShapeArg == "solid")  aShapeType = TopAbs_SOLID;
5781     else
5782     {
5783       std::cout << "Syntax error at '" << argv[1] << "'\n";
5784       return 1;
5785     }
5786   }
5787
5788   static Standard_Integer THE_NB_SHAPES_OF_TYPE[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
5789   static const TCollection_AsciiString THE_NAME_TYPE[8] = {"COMPS","SOL","SHE","F","W","E","V","SHAP"};
5790
5791   const Standard_Integer aNbToPick = argc > 2 ? argc - 2 : 1;
5792   if (aNbToPick == 1)
5793   {
5794     TopoDS_Shape aPickedShape = ViewerTest::PickShape (aShapeType);
5795     if (aPickedShape.IsNull())
5796     {
5797       return 1;
5798     }
5799
5800     TCollection_AsciiString aName;
5801     if (argc > 2)
5802     {
5803       aName = argv[2];
5804     }
5805     else
5806     {
5807       const int aShapeIndex = ++THE_NB_SHAPES_OF_TYPE[Standard_Integer(aShapeType)];
5808       aName = TCollection_AsciiString ("Picked_") + THE_NAME_TYPE[Standard_Integer(aShapeType)] + "_" + aShapeIndex;
5809     }
5810
5811     DBRep::Set (aName.ToCString(), aPickedShape);
5812     Handle(AIS_Shape) aShapePrs = new AIS_Shape (aPickedShape);
5813     ViewerTest::Display (aName, aShapePrs, false, true);
5814     di << "Name of picked shape: " << aName <<"\n";
5815   }
5816   else
5817   {
5818     TCollection_AsciiString aName (argv[2]);
5819     aName.LowerCase();
5820     const Standard_Boolean isAutoNaming = aName == ".";
5821     Handle(TopTools_HArray1OfShape) aPickedArray = new TopTools_HArray1OfShape (1, aNbToPick);
5822     if (ViewerTest::PickShapes (aShapeType, aPickedArray))
5823     {
5824       for (Standard_Integer aPickedIter = aPickedArray->Lower(); aPickedIter <= aPickedArray->Upper(); ++aPickedIter)
5825       {
5826         TopoDS_Shape aPickedShape = aPickedArray->Value (aPickedIter);
5827         aName.Clear();
5828         if (!aPickedShape.IsNull()
5829          && isAutoNaming)
5830         {
5831           const int aShapeIndex = ++THE_NB_SHAPES_OF_TYPE[Standard_Integer(aShapeType)];
5832           aName = TCollection_AsciiString ("Picked_") + THE_NAME_TYPE[Standard_Integer(aShapeType)] + "_" + aShapeIndex;
5833         }
5834         else
5835         {
5836           aName = argv[1 + aPickedIter];
5837         }
5838
5839         DBRep::Set (aName.ToCString(), aPickedShape);
5840         Handle(AIS_Shape) aShapePrs = new AIS_Shape (aPickedShape);
5841         di << "Display of picked shape #" << aPickedIter << " - name: " << aName <<"\n";
5842         ViewerTest::Display (aName, aShapePrs, false, true);
5843       }
5844     }
5845   }
5846   TheAISContext()->UpdateCurrentViewer();
5847   return 0;
5848 }
5849
5850 //=======================================================================
5851 //function : VSelFilter
5852 //purpose  :
5853 //=======================================================================
5854 static int VSelFilter(Draw_Interpretor& , Standard_Integer theArgc,
5855                       const char** theArgv)
5856 {
5857   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5858   if (aContext.IsNull())
5859   {
5860     std::cout << "Error: AIS context is not available.\n";
5861     return 1;
5862   }
5863
5864   for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
5865   {
5866     TCollection_AsciiString anArg (theArgv[anArgIter]);
5867     anArg.LowerCase();
5868     if (anArg == "-clear")
5869     {
5870       aContext->RemoveFilters();
5871     }
5872     else if (anArg == "-type"
5873           && anArgIter + 1 < theArgc)
5874     {
5875       TCollection_AsciiString aVal (theArgv[++anArgIter]);
5876       TopAbs_ShapeEnum aShapeType = TopAbs_COMPOUND;
5877       if (!TopAbs::ShapeTypeFromString (aVal.ToCString(), aShapeType))
5878       {
5879         std::cout << "Syntax error: wrong command attribute value '" << aVal << "'\n";
5880         return 1;
5881       }
5882
5883       Handle(SelectMgr_Filter) aFilter;
5884       if (aShapeType == TopAbs_SHAPE)
5885       {
5886         aFilter = new AIS_TypeFilter (AIS_KOI_Shape);
5887       }
5888       else
5889       {
5890         aFilter = new StdSelect_ShapeTypeFilter (aShapeType);
5891       }
5892       aContext->AddFilter (aFilter);
5893     }
5894     else
5895     {
5896       std::cout << "Syntax error: unknown argument '" << theArgv[anArgIter] << "'\n";
5897       return 1;
5898     }
5899   }
5900   return 0;
5901 }
5902
5903 //=======================================================================
5904 //function : VPickSelected
5905 //purpose  :
5906 //=======================================================================
5907 static int VPickSelected (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgs)
5908 {
5909   static Standard_Integer aCount = 0;
5910   TCollection_AsciiString aName = "PickedShape_";
5911
5912   if (theArgNb > 1)
5913   {
5914     aName = theArgs[1];
5915   }
5916   else
5917   {
5918     aName = aName + aCount++ + "_";
5919   }
5920
5921   Standard_Integer anIdx = 0;
5922   for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected(), ++anIdx)
5923   {
5924     TopoDS_Shape aShape;
5925     if (TheAISContext()->HasSelectedShape())
5926     {
5927       aShape = TheAISContext()->SelectedShape();
5928     }
5929     else
5930     {
5931       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
5932       aShape = Handle(AIS_Shape)::DownCast (IO)->Shape();
5933     }
5934
5935     TCollection_AsciiString aCurrentName = aName;
5936     if (anIdx > 0)
5937     {
5938       aCurrentName += anIdx;
5939     }
5940
5941     DBRep::Set ((aCurrentName).ToCString(), aShape);
5942
5943     Handle(AIS_Shape) aNewShape = new AIS_Shape (aShape);
5944     GetMapOfAIS().Bind (aNewShape, aCurrentName);
5945     TheAISContext()->Display (aNewShape, Standard_False);
5946   }
5947
5948   TheAISContext()->UpdateCurrentViewer();
5949
5950   return 0;
5951 }
5952
5953 //=======================================================================
5954 //function : list of known objects
5955 //purpose  :
5956 //=======================================================================
5957 static int VIOTypes( Draw_Interpretor& di, Standard_Integer , const char** )
5958 {
5959   //                             1234567890         12345678901234567         123456789
5960   TCollection_AsciiString Colum [3]={"Standard Types","Type Of Object","Signature"};
5961   TCollection_AsciiString BlankLine(64,'_');
5962   Standard_Integer i ;
5963
5964   di<<"/n"<<BlankLine.ToCString()<<"\n";
5965
5966   for( i =0;i<=2;i++)
5967     Colum[i].Center(20,' ');
5968   for(i=0;i<=2;i++)
5969     di<<"|"<<Colum[i].ToCString();
5970   di<<"|\n";
5971
5972   di<<BlankLine.ToCString()<<"\n";
5973
5974   //  TCollection_AsciiString thetypes[5]={"Datum","Shape","Object","Relation","None"};
5975   const char ** names = GetTypeNames();
5976
5977   TCollection_AsciiString curstring;
5978   TCollection_AsciiString curcolum[3];
5979
5980
5981   // les objets de type Datum..
5982   curcolum[1]+="Datum";
5983   for(i =0;i<=6;i++){
5984     curcolum[0].Clear();
5985     curcolum[0] += names[i];
5986
5987     curcolum[2].Clear();
5988     curcolum[2]+=TCollection_AsciiString(i+1);
5989
5990     for(Standard_Integer j =0;j<=2;j++){
5991       curcolum[j].Center(20,' ');
5992       di<<"|"<<curcolum[j].ToCString();
5993     }
5994     di<<"|\n";
5995   }
5996   di<<BlankLine.ToCString()<<"\n";
5997
5998   // les objets de type shape
5999   curcolum[1].Clear();
6000   curcolum[1]+="Shape";
6001   curcolum[1].Center(20,' ');
6002
6003   for(i=0;i<=2;i++){
6004     curcolum[0].Clear();
6005     curcolum[0] += names[7+i];
6006     curcolum[2].Clear();
6007     curcolum[2]+=TCollection_AsciiString(i);
6008
6009     for(Standard_Integer j =0;j<=2;j++){
6010       curcolum[j].Center(20,' ');
6011       di<<"|"<<curcolum[j].ToCString();
6012     }
6013     di<<"|\n";
6014   }
6015   di<<BlankLine.ToCString()<<"\n";
6016   // les IO de type objet...
6017   curcolum[1].Clear();
6018   curcolum[1]+="Object";
6019   curcolum[1].Center(20,' ');
6020   for(i=0;i<=1;i++){
6021     curcolum[0].Clear();
6022     curcolum[0] += names[10+i];
6023     curcolum[2].Clear();
6024     curcolum[2]+=TCollection_AsciiString(i);
6025
6026     for(Standard_Integer j =0;j<=2;j++){
6027       curcolum[j].Center(20,' ');
6028       di<<"|"<<curcolum[j].ToCString();
6029     }
6030     di<<"|\n";
6031   }
6032   di<<BlankLine.ToCString()<<"\n";
6033   // les contraintes et dimensions.
6034   // pour l'instant on separe juste contraintes et dimensions...
6035   // plus tard, on detaillera toutes les sortes...
6036   curcolum[1].Clear();
6037   curcolum[1]+="Relation";
6038   curcolum[1].Center(20,' ');
6039   for(i=0;i<=1;i++){
6040     curcolum[0].Clear();
6041     curcolum[0] += names[12+i];
6042     curcolum[2].Clear();
6043     curcolum[2]+=TCollection_AsciiString(i);
6044
6045     for(Standard_Integer j =0;j<=2;j++){
6046       curcolum[j].Center(20,' ');
6047       di<<"|"<<curcolum[j].ToCString();
6048     }
6049     di<<"|\n";
6050   }
6051   di<<BlankLine.ToCString()<<"\n";
6052
6053
6054   return 0;
6055 }
6056
6057
6058 static int VEraseType( Draw_Interpretor& , Standard_Integer argc, const char** argv)
6059 {
6060   if(argc!=2) return 1;
6061
6062   AIS_KindOfInteractive TheType;
6063   Standard_Integer TheSign(-1);
6064   GetTypeAndSignfromString(argv[1],TheType,TheSign);
6065
6066
6067   AIS_ListOfInteractive LIO;
6068
6069   // en attendant l'amelioration ais pour les dimensions...
6070   //
6071   Standard_Integer dimension_status(-1);
6072   if(TheType==AIS_KOI_Relation){
6073     dimension_status = TheSign ==1 ? 1 : 0;
6074     TheSign=-1;
6075   }
6076
6077   TheAISContext()->DisplayedObjects(TheType,TheSign,LIO);
6078   Handle(AIS_InteractiveObject) curio;
6079   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
6080     curio  = it.Value();
6081
6082     if(dimension_status == -1)
6083       TheAISContext()->Erase(curio,Standard_False);
6084     else {
6085       AIS_KindOfDimension KOD = Handle(AIS_Relation)::DownCast (curio)->KindOfDimension();
6086       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
6087           (dimension_status==1 && KOD != AIS_KOD_NONE))
6088         TheAISContext()->Erase(curio,Standard_False);
6089     }
6090   }
6091   TheAISContext()->UpdateCurrentViewer();
6092   return 0;
6093 }
6094 static int VDisplayType(Draw_Interpretor& , Standard_Integer argc, const char** argv)
6095 {
6096   if(argc!=2) return 1;
6097
6098   AIS_KindOfInteractive TheType;
6099   Standard_Integer TheSign(-1);
6100   GetTypeAndSignfromString(argv[1],TheType,TheSign);
6101
6102   // en attendant l'amelioration ais pour les dimensions...
6103   //
6104   Standard_Integer dimension_status(-1);
6105   if(TheType==AIS_KOI_Relation){
6106     dimension_status = TheSign ==1 ? 1 : 0;
6107     TheSign=-1;
6108   }
6109
6110   AIS_ListOfInteractive LIO;
6111   TheAISContext()->ObjectsInside(LIO,TheType,TheSign);
6112   Handle(AIS_InteractiveObject) curio;
6113   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
6114     curio  = it.Value();
6115     if(dimension_status == -1)
6116       TheAISContext()->Display(curio,Standard_False);
6117     else {
6118       AIS_KindOfDimension KOD = Handle(AIS_Relation)::DownCast (curio)->KindOfDimension();
6119       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
6120           (dimension_status==1 && KOD != AIS_KOD_NONE))
6121         TheAISContext()->Display(curio,Standard_False);
6122     }
6123
6124   }
6125
6126   TheAISContext()->UpdateCurrentViewer();
6127   return 0;
6128 }
6129
6130 static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a)
6131 {
6132   std::ifstream s(a[1]);
6133   BRep_Builder builder;
6134   TopoDS_Shape shape;
6135   BRepTools::Read(shape, s, builder);
6136   DBRep::Set(a[1], shape);
6137   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
6138   Handle(AIS_Shape) ais = new AIS_Shape(shape);
6139   Ctx->Display (ais, Standard_True);
6140   return 0;
6141 }
6142
6143 //===============================================================================================
6144 //function : VBsdf
6145 //purpose  :
6146 //===============================================================================================
6147 static int VBsdf (Draw_Interpretor& theDI,
6148                   Standard_Integer  theArgsNb,
6149                   const char**      theArgVec)
6150 {
6151   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
6152   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6153   if (aView.IsNull()
6154    || aViewer.IsNull())
6155   {
6156     std::cerr << "No active viewer!\n";
6157     return 1;
6158   }
6159
6160   ViewerTest_CmdParser aCmd;
6161
6162   aCmd.SetDescription ("Adjusts parameters of material BSDF:");
6163
6164   aCmd.AddOption ("print|echo|p", "Prints BSDF");
6165
6166   aCmd.AddOption ("noupdate|update", "Suppresses viewer redraw call");
6167
6168   aCmd.AddOption ("kc", "Weight of coat specular/glossy BRDF");
6169   aCmd.AddOption ("kd", "Weight of base diffuse BRDF");
6170   aCmd.AddOption ("ks", "Weight of base specular/glossy BRDF");
6171   aCmd.AddOption ("kt", "Weight of base specular/glossy BTDF");
6172   aCmd.AddOption ("le", "Radiance emitted by surface");
6173
6174   aCmd.AddOption ("coatFresnel|cf", "Fresnel reflectance of coat layer. Allowed formats: Constant R, Schlick R G B, Dielectric N, Conductor N K");
6175   aCmd.AddOption ("baseFresnel|bf", "Fresnel reflectance of base layer. Allowed formats: Constant R, Schlick R G B, Dielectric N, Conductor N K");
6176
6177   aCmd.AddOption ("coatRoughness|cr", "Roughness of coat glossy BRDF");
6178   aCmd.AddOption ("baseRoughness|br", "Roughness of base glossy BRDF");
6179
6180   aCmd.AddOption ("absorpCoeff|af", "Absorption coeff of base transmission BTDF");
6181   aCmd.AddOption ("absorpColor|ac", "Absorption color of base transmission BTDF");
6182
6183   aCmd.AddOption ("normalize|n", "Normalizes BSDF to ensure energy conservation");
6184
6185   aCmd.Parse (theArgsNb, theArgVec);
6186
6187   if (aCmd.HasOption ("help"))
6188   {
6189     theDI.PrintHelp (theArgVec[0]);
6190     return 0;
6191   }
6192
6193   // check viewer update mode
6194   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
6195   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6196   {
6197     if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
6198     {
6199       break;
6200     }
6201   }
6202
6203   // find object
6204   TCollection_AsciiString aName (aCmd.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0).c_str());
6205   Handle(AIS_InteractiveObject) anIObj;
6206   if (!GetMapOfAIS().Find2 (aName, anIObj))
6207   {
6208     std::cerr << "Use 'vdisplay' before\n";
6209     return 1;
6210   }
6211
6212   Graphic3d_MaterialAspect aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
6213   Graphic3d_BSDF aBSDF = aMaterial.BSDF();
6214
6215   if (aCmd.HasOption ("print"))
6216   {
6217     theDI << "\n"
6218       << "Kc:               " << aBSDF.Kc.r() << ", " << aBSDF.Kc.g() << ", " << aBSDF.Kc.b() << "\n"
6219       << "Kd:               " << aBSDF.Kd.r() << ", " << aBSDF.Kd.g() << ", " << aBSDF.Kd.b() << "\n"
6220       << "Ks:               " << aBSDF.Ks.r() << ", " << aBSDF.Ks.g() << ", " << aBSDF.Ks.b() << "\n"
6221       << "Kt:               " << aBSDF.Kt.r() << ", " << aBSDF.Kt.g() << ", " << aBSDF.Kt.b() << "\n"
6222       << "Le:               " << aBSDF.Le.r() << ", " << aBSDF.Le.g() << ", " << aBSDF.Le.b() << "\n";
6223
6224     for (int aLayerID = 0; aLayerID < 2; ++aLayerID)
6225     {
6226       const Graphic3d_Vec4 aFresnel = aLayerID < 1 ? aBSDF.FresnelCoat.Serialize()
6227                                                    : aBSDF.FresnelBase.Serialize();
6228
6229       theDI << (aLayerID < 1 ? "Coat Fresnel:     "
6230                              : "Base Fresnel:     ");
6231
6232       if (aFresnel.x() >= 0.f)
6233       {
6234         theDI << "Schlick " << "R = " << aFresnel.r() << ", "
6235                             << "G = " << aFresnel.g() << ", "
6236                             << "B = " << aFresnel.b() << "\n";
6237       }
6238       else if (aFresnel.x() >= -1.5f)
6239       {
6240         theDI << "Constant " << aFresnel.z() << "\n";
6241       }
6242       else if (aFresnel.x() >= -2.5f)
6243       {
6244         theDI << "Conductor " << "N = " << aFresnel.y() << ", "
6245                               << "K = " << aFresnel.z() << "\n";
6246       }
6247       else
6248       {
6249         theDI << "Dielectric " << "N = " << aFresnel.y() << "\n";
6250       }
6251     }
6252
6253     theDI << "Coat roughness:   " << aBSDF.Kc.w() << "\n"
6254           << "Base roughness:   " << aBSDF.Ks.w() << "\n"
6255           << "Absorption coeff: " << aBSDF.Absorption.w() << "\n"
6256           << "Absorption color: " << aBSDF.Absorption.r() << ", "
6257                                   << aBSDF.Absorption.g() << ", "
6258                                   << aBSDF.Absorption.b() << "\n";
6259
6260     return 0;
6261   }
6262
6263   if (aCmd.HasOption ("coatRoughness", 1, Standard_True))
6264   {
6265     aBSDF.Kc.w() = aCmd.ArgFloat ("coatRoughness");
6266   }
6267
6268   if (aCmd.HasOption ("baseRoughness", 1, Standard_True))
6269   {
6270     aBSDF.Ks.w () = aCmd.ArgFloat ("baseRoughness");
6271   }
6272
6273   if (aCmd.HasOption ("absorpCoeff", 1, Standard_True))
6274   {
6275     aBSDF.Absorption.w() = aCmd.ArgFloat ("absorpCoeff");
6276   }
6277
6278   if (aCmd.HasOption ("absorpColor", 3, Standard_True))
6279   {
6280     const Graphic3d_Vec3 aRGB = aCmd.ArgVec3f ("absorpColor");
6281
6282     aBSDF.Absorption.r() = aRGB.r();
6283     aBSDF.Absorption.g() = aRGB.g();
6284     aBSDF.Absorption.b() = aRGB.b();
6285   }
6286
6287   if (aCmd.HasOption ("kc", 3) || aCmd.HasOption ("kc", 1, Standard_True))
6288   {
6289     Graphic3d_Vec3 aKc;
6290
6291     if (aCmd.HasOption ("kc", 3))
6292     {
6293       aKc = aCmd.ArgVec3f ("kc");
6294     }
6295     else
6296     {
6297       aKc = Graphic3d_Vec3 (aCmd.ArgFloat ("kc"));
6298     }
6299
6300     aBSDF.Kc.r() = aKc.r();
6301     aBSDF.Kc.g() = aKc.g();
6302     aBSDF.Kc.b() = aKc.b();
6303   }
6304
6305   if (aCmd.HasOption ("kd", 3))
6306   {
6307     aBSDF.Kd = aCmd.ArgVec3f ("kd");
6308   }
6309   else if (aCmd.HasOption ("kd", 1, Standard_True))
6310   {
6311     aBSDF.Kd = Graphic3d_Vec3 (aCmd.ArgFloat ("kd"));
6312   }
6313
6314   if (aCmd.HasOption ("ks", 3) || aCmd.HasOption ("ks", 1, Standard_True))
6315   {
6316     Graphic3d_Vec3 aKs;
6317
6318     if (aCmd.HasOption ("ks", 3))
6319     {
6320       aKs = aCmd.ArgVec3f ("ks");
6321     }
6322     else
6323     {
6324       aKs = Graphic3d_Vec3 (aCmd.ArgFloat ("ks"));
6325     }
6326
6327     aBSDF.Ks.r() = aKs.r();
6328     aBSDF.Ks.g() = aKs.g();
6329     aBSDF.Ks.b() = aKs.b();
6330   }
6331
6332   if (aCmd.HasOption ("kt", 3))
6333   {
6334     aBSDF.Kt = aCmd.ArgVec3f ("kt");
6335   }
6336   else if (aCmd.HasOption ("kt", 1, Standard_True))
6337   {
6338     aBSDF.Kt = Graphic3d_Vec3 (aCmd.ArgFloat ("kt"));
6339   }
6340
6341   if (aCmd.HasOption ("le", 3))
6342   {
6343     aBSDF.Le = aCmd.ArgVec3f ("le");
6344   }
6345   else if (aCmd.HasOption ("le", 1, Standard_True))
6346   {
6347     aBSDF.Le = Graphic3d_Vec3 (aCmd.ArgFloat ("le"));
6348   }
6349
6350   const std::string aFresnelErrorMessage =
6351     "Error! Wrong Fresnel type. Allowed types are: Constant F, Schlick R G B, Dielectric N, Conductor N K\n";
6352
6353   for (int aLayerID = 0; aLayerID < 2; ++aLayerID)
6354   {
6355     const std::string aFresnel = aLayerID < 1 ? "baseFresnel"
6356                                               : "coatFresnel";
6357
6358     if (aCmd.HasOption (aFresnel, 4)) // Schlick: type R G B
6359     {
6360       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
6361       std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
6362
6363       if (aFresnelType == "schlick")
6364       {
6365         Graphic3d_Vec3 aRGB (static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str())),
6366                              static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 2).c_str())),
6367                              static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 3).c_str())));
6368
6369         aRGB.r() = std::min (std::max (aRGB.r(), 0.f), 1.f);
6370         aRGB.g() = std::min (std::max (aRGB.g(), 0.f), 1.f);
6371         aRGB.b() = std::min (std::max (aRGB.b(), 0.f), 1.f);
6372
6373         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateSchlick (aRGB);
6374       }
6375       else
6376       {
6377         theDI << aFresnelErrorMessage.c_str() << "\n";
6378       }
6379     }
6380     else if (aCmd.HasOption (aFresnel, 3)) // Conductor: type N K
6381     {
6382       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
6383       std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
6384
6385       if (aFresnelType == "conductor")
6386       {
6387         const float aN = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str()));
6388         const float aK = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 2).c_str()));
6389
6390         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateConductor (aN, aK);
6391       }
6392       else
6393       {
6394         theDI << aFresnelErrorMessage.c_str() << "\n";
6395       }
6396     }
6397     else if (aCmd.HasOption (aFresnel, 2)) // Dielectric or Constant: type N|C
6398     {
6399       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
6400       std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
6401
6402       if (aFresnelType == "constant")
6403       {
6404         const float aR = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str()));
6405
6406         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateConstant (aR);
6407       }
6408       else if (aFresnelType == "dielectric")
6409       {
6410         const float aN = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str()));
6411
6412         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateDielectric (aN);
6413       }
6414       else
6415       {
6416         theDI << aFresnelErrorMessage.c_str() << "\n";
6417       }
6418     }
6419   }
6420
6421   if (aCmd.HasOption ("normalize"))
6422   {
6423     aBSDF.Normalize();
6424   }
6425
6426   aMaterial.SetBSDF (aBSDF);
6427   anIObj->SetMaterial (aMaterial);
6428
6429   return 0;
6430 }
6431
6432 //==============================================================================
6433 //function : VLoadSelection
6434 //purpose  : Adds given objects to map of AIS and loads selection primitives for them
6435 //==============================================================================
6436 static Standard_Integer VLoadSelection (Draw_Interpretor& /*theDi*/,
6437                                         Standard_Integer theArgNb,
6438                                         const char** theArgVec)
6439 {
6440   if (theArgNb < 2)
6441   {
6442     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
6443     return 1;
6444   }
6445
6446   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
6447   if (aCtx.IsNull())
6448   {
6449     ViewerTest::ViewerInit();
6450     aCtx = ViewerTest::GetAISContext();
6451   }
6452
6453   // Parse input arguments
6454   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6455   {
6456     const TCollection_AsciiString aName = theArgVec[anArgIter];
6457     Handle(AIS_InteractiveObject) aShape;
6458     if (!GetMapOfAIS().Find2 (aName, aShape))
6459     {
6460       TopoDS_Shape aDrawShape = DBRep::GetExisting (aName);
6461       if (!aDrawShape.IsNull())
6462       {
6463         aShape = new AIS_Shape (aDrawShape);
6464         GetMapOfAIS().Bind (aShape, aName);
6465       }
6466     }
6467     if (aShape.IsNull())
6468     {
6469       std::cout << "Syntax error: presentation '" << aName << "' not found\n";
6470       return 1;
6471     }
6472
6473     aCtx->Load (aShape, -1);
6474     aCtx->Activate (aShape, aShape->GlobalSelectionMode(), Standard_True);
6475   }
6476   return 0;
6477 }
6478
6479 //==============================================================================
6480 //function : ViewerTest::Commands
6481 //purpose  : Add all the viewer command in the Draw_Interpretor
6482 //==============================================================================
6483
6484 void ViewerTest::Commands(Draw_Interpretor& theCommands)
6485 {
6486   ViewerTest::ViewerCommands(theCommands);
6487   ViewerTest::RelationCommands(theCommands);
6488   ViewerTest::ObjectCommands(theCommands);
6489   ViewerTest::FilletCommands(theCommands);
6490   ViewerTest::OpenGlCommands(theCommands);
6491
6492   const char *group = "AIS_Display";
6493
6494   // display
6495   theCommands.Add("visos",
6496       "visos [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]\n"
6497       "\tIf last 3 optional parameters are not set prints numbers of U-, V- isolines and IsoOnPlane.\n",
6498       __FILE__, visos, group);
6499
6500   theCommands.Add("vdisplay",
6501               "vdisplay [-noupdate|-update] [-local] [-mutable] [-neutral]"
6502       "\n\t\t:          [-trsfPers {zoom|rotate|zoomRotate|none}=none]"
6503       "\n\t\t:                            [-trsfPersPos X Y [Z]] [-3d]"
6504       "\n\t\t:          [-2d|-trihedron [{top|bottom|left|right|topLeft"
6505       "\n\t\t:                           |topRight|bottomLeft|bottomRight}"
6506       "\n\t\t:                                         [offsetX offsetY]]]"
6507       "\n\t\t:          [-dispMode mode] [-highMode mode]"
6508       "\n\t\t:          [-layer index] [-top|-topmost|-overlay|-underlay]"
6509       "\n\t\t:          [-redisplay] [-erased]"
6510       "\n\t\t:          name1 [name2] ... [name n]"
6511       "\n\t\t: Displays named objects."
6512       "\n\t\t: Option -local enables displaying of objects in local"
6513       "\n\t\t: selection context. Local selection context will be opened"
6514       "\n\t\t: if there is not any."
6515       "\n\t\t:  -noupdate    Suppresses viewer redraw call."
6516       "\n\t\t:  -mutable     Enables optimizations for mutable objects."
6517       "\n\t\t:  -neutral     Draws objects in main viewer."
6518       "\n\t\t:  -erased      Loads the object into context, but does not display it."
6519       "\n\t\t:  -layer       Sets z-layer for objects."
6520       "\n\t\t:               Alternatively -overlay|-underlay|-top|-topmost"
6521       "\n\t\t:               options can be used for the default z-layers."
6522       "\n\t\t:  -top         Draws object on top of main presentations"
6523       "\n\t\t:               but below topmost."
6524       "\n\t\t:  -topmost     Draws in overlay for 3D presentations."
6525       "\n\t\t:               with independent Depth."
6526       "\n\t\t:  -overlay     Draws objects in overlay for 2D presentations."
6527       "\n\t\t:               (On-Screen-Display)"
6528       "\n\t\t:  -underlay    Draws objects in underlay for 2D presentations."
6529       "\n\t\t:               (On-Screen-Display)"
6530       "\n\t\t:  -selectable|-noselect Controls selection of objects."
6531       "\n\t\t:  -trsfPers    Sets a transform persistence flags."
6532       "\n\t\t:  -trsfPersPos Sets an anchor point for transform persistence."
6533       "\n\t\t:  -2d          Displays object in screen coordinates."
6534       "\n\t\t:               (DY looks up)"
6535       "\n\t\t:  -dispmode    Sets display mode for objects."
6536       "\n\t\t:  -highmode    Sets hilight mode for objects."
6537       "\n\t\t:  -redisplay   Recomputes presentation of objects.",
6538       __FILE__, VDisplay2, group);
6539
6540   theCommands.Add ("vnbdisplayed",
6541       "vnbdisplayed"
6542       "\n\t\t: Returns number of displayed objects",
6543       __FILE__, VNbDisplayed, group);
6544
6545   theCommands.Add ("vupdate",
6546       "vupdate name1 [name2] ... [name n]"
6547       "\n\t\t: Updates named objects in interactive context",
6548       __FILE__, VUpdate, group);
6549
6550   theCommands.Add("verase",
6551       "verase [-noupdate|-update] [-local] [name1] ...  [name n] [-noerror]"
6552       "\n\t\t: Erases selected or named objects."
6553       "\n\t\t: If there are no selected or named objects the whole viewer is erased."
6554       "\n\t\t: Option -local enables erasing of selected or named objects without"
6555       "\n\t\t: closing local selection context."
6556       "\n\t\t: Option -noerror prevents exception on non-existing objects.",
6557       __FILE__, VErase, group);
6558
6559   theCommands.Add("vremove",
6560       "vremove [-noupdate|-update] [-context] [-all] [-noinfo] [name1] ...  [name n] [-noerror]"
6561       "or vremove [-context] -all to remove all objects"
6562       "\n\t\t: Removes selected or named objects."
6563       "\n\t\t  If -context is in arguments, the objects are not deleted"
6564       "\n\t\t  from the map of objects and names."
6565       "\n\t\t: Option -local enables removing of selected or named objects without"
6566       "\n\t\t: closing local selection context. Empty local selection context will be"
6567       "\n\t\t: closed."
6568       "\n\t\t: Option -noupdate suppresses viewer redraw call."
6569       "\n\t\t: Option -noinfo suppresses displaying the list of removed objects."
6570       "\n\t\t: Option -noerror prevents exception on non-existing objects.",
6571       __FILE__, VRemove, group);
6572
6573   theCommands.Add("vdonly",
6574                   "vdonly [-noupdate|-update] [name1] ...  [name n]"
6575       "\n\t\t: Displays only selected or named objects",
6576                   __FILE__,VDonly2,group);
6577
6578   theCommands.Add("vdisplayall",
6579       "vdisplayall"
6580       "\n\t\t: Displays all erased interactive objects (see vdir and vstate).",
6581       __FILE__, VDisplayAll, group);
6582
6583   theCommands.Add("veraseall",
6584       "veraseall"
6585       "\n\t\t: Erases all objects displayed in the viewer.",
6586       __FILE__, VErase, group);
6587
6588   theCommands.Add("verasetype",
6589       "verasetype <Type>"
6590       "\n\t\t: Erase all the displayed objects of one given kind (see vtypes)",
6591       __FILE__, VEraseType, group);
6592   theCommands.Add("vbounding",
6593               "vbounding [-noupdate|-update] [-mode] name1 [name2 [...]]"
6594       "\n\t\t:           [-print] [-hide]"
6595       "\n\t\t: Temporarily display bounding box of specified Interactive"
6596       "\n\t\t: Objects, or print it to console if -print is specified."
6597       "\n\t\t: Already displayed box might be hidden by -hide option.",
6598                   __FILE__,VBounding,group);
6599
6600   theCommands.Add("vdisplaytype",
6601                   "vdisplaytype        : vdisplaytype <Type> <Signature> \n\t display all the objects of one given kind (see vtypes) which are stored the AISContext ",
6602                   __FILE__,VDisplayType,group);
6603
6604   theCommands.Add("vsetdispmode",
6605                   "vsetdispmode [name] mode(1,2,..)"
6606       "\n\t\t: Sets display mode for all, selected or named objects.",
6607                   __FILE__,VDispMode,group);
6608
6609   theCommands.Add("vunsetdispmode",
6610                   "vunsetdispmode [name]"
6611       "\n\t\t: Unsets custom display mode for selected or named objects.",
6612                   __FILE__,VDispMode,group);
6613
6614   theCommands.Add("vdir",
6615               "vdir [mask] [-list]"
6616       "\n\t\t: Lists all objects displayed in 3D viewer"
6617       "\n\t\t:    mask - name filter like prefix*"
6618       "\n\t\t:   -list - format list with new-line per name; OFF by default",
6619                   __FILE__,VDir,group);
6620
6621 #ifdef HAVE_FREEIMAGE
6622   #define DUMP_FORMATS "{png|bmp|jpg|gif}"
6623 #else
6624   #define DUMP_FORMATS "{ppm}"
6625 #endif
6626   theCommands.Add("vdump",
6627               "vdump <filename>." DUMP_FORMATS " [-width Width -height Height]"
6628       "\n\t\t:       [-buffer rgb|rgba|depth=rgb]"
6629       "\n\t\t:       [-stereo mono|left|right|blend|sideBySide|overUnder=mono]"
6630       "\n\t\t:       [-tileSize Size=0]"
6631       "\n\t\t: Dumps content of the active view into image file",
6632                   __FILE__,VDump,group);
6633
6634   theCommands.Add("vsub",      "vsub 0/1 (off/on) [obj]        : Subintensity(on/off) of selected objects",
6635                   __FILE__,VSubInt,group);
6636
6637   theCommands.Add("vaspects",
6638               "vaspects [-noupdate|-update] [name1 [name2 [...]] | -defaults]"
6639       "\n\t\t:          [-setVisibility 0|1]"
6640       "\n\t\t:          [-setColor ColorName] [-setcolor R G B] [-unsetColor]"
6641       "\n\t\t:          [-setBackFaceColor Color]"
6642       "\n\t\t:          [-setMaterial MatName] [-unsetMaterial]"
6643       "\n\t\t:          [-setTransparency Transp] [-unsetTransparency]"
6644       "\n\t\t:          [-setWidth LineWidth] [-unsetWidth]"
6645       "\n\t\t:          [-setLineType {solid|dash|dot|dotDash}] [-unsetLineType]"
6646       "\n\t\t:          [-setMarkerType {.|+|x|O|xcircle|pointcircle|ring1|ring2|ring3|ball|ImagePath}]"
6647       "\n\t\t:          [-unsetMarkerType]"
6648       "\n\t\t:          [-setMarkerSize Scale] [-unsetMarkerSize]"
6649       "\n\t\t:          [-freeBoundary {off/on | 0/1}]"
6650       "\n\t\t:          [-setFreeBoundaryWidth Width] [-unsetFreeBoundaryWidth]"
6651       "\n\t\t:          [-setFreeBoundaryColor {ColorName | R G B}] [-unsetFreeBoundaryColor]"
6652       "\n\t\t:          [-subshapes subname1 [subname2 [...]]]"
6653       "\n\t\t:          [-isoontriangulation 0|1]"
6654       "\n\t\t:          [-setMaxParamValue {value}]"
6655       "\n\t\t:          [-setSensitivity {selection_mode} {value}]"
6656       "\n\t\t:          [-setShadingModel {unlit|flat|gouraud|phong}]"
6657       "\n\t\t:          [-unsetShadingModel]"
6658       "\n\t\t:          [-setInterior {solid|hatch|hidenline|point}]"
6659       "\n\t\t:          [-unsetInterior] [-setHatch HatchStyle]"
6660       "\n\t\t:          [-setFaceBoundaryDraw {0|1}] [-setMostContinuity {c0|c1|c2|c3|cn}"
6661       "\n\t\t:          [-setFaceBoundaryWidth LineWidth] [-setFaceBoundaryColor R G B] [-setFaceBoundaryType LineType]"
6662       "\n\t\t:          [-setDrawEdges {0|1}] [-setEdgeType LineType] [-setEdgeColor R G B] [-setQuadEdges {0|1}]"
6663       "\n\t\t:          [-setDrawSilhouette {0|1}]"
6664       "\n\t\t:          [-setAlphaMode {opaque|mask|blend|blendauto} [alphaCutOff=0.5]]"
6665       "\n\t\t:          [-dumpJson]"
6666       "\n\t\t:          [-dumpCompact {0|1}]"
6667       "\n\t\t:          [-dumpDepth depth]"
6668       "\n\t\t:          [-freeBoundary {off/on | 0/1}]"
6669       "\n\t\t: Manage presentation properties of all, selected or named objects."
6670       "\n\t\t: When -subshapes is specified than following properties will be"
6671       "\n\t\t: assigned to specified sub-shapes."
6672       "\n\t\t: When -defaults is specified than presentation properties will be"
6673       "\n\t\t: assigned to all objects that have not their own specified properties"
6674       "\n\t\t: and to all objects to be displayed in the future."
6675       "\n\t\t: If -defaults is used there should not be any objects' names and -subshapes specifier."
6676       "\n\t\t: See also vlistcolors and vlistmaterials to list named colors and materials"
6677       "\n\t\t: accepted by arguments -setMaterial and -setColor",
6678                   __FILE__,VAspects,group);
6679
6680   theCommands.Add("vsetcolor",
6681       "vsetcolor [-noupdate|-update] [name] ColorName"
6682       "\n\t\t: Sets color for all, selected or named objects."
6683       "\n\t\t: Alias for vaspects -setcolor [name] ColorName.",
6684                   __FILE__,VAspects,group);
6685
6686   theCommands.Add("vunsetcolor",
6687                   "vunsetcolor [-noupdate|-update] [name]"
6688       "\n\t\t: Resets color for all, selected or named objects."
6689       "\n\t\t: Alias for vaspects -unsetcolor [name].",
6690                   __FILE__,VAspects,group);
6691
6692   theCommands.Add("vsettransparency",
6693                   "vsettransparency [-noupdate|-update] [name] Coefficient"
6694       "\n\t\t: Sets transparency for all, selected or named objects."
6695       "\n\t\t: The Coefficient may be between 0.0 (opaque) and 1.0 (fully transparent)."
6696       "\n\t\t: Alias for vaspects -settransp [name] Coefficient.",
6697                   __FILE__,VAspects,group);
6698
6699   theCommands.Add("vunsettransparency",
6700                   "vunsettransparency [-noupdate|-update] [name]"
6701       "\n\t\t: Resets transparency for all, selected or named objects."
6702       "\n\t\t: Alias for vaspects -unsettransp [name].",
6703                   __FILE__,VAspects,group);
6704
6705   theCommands.Add("vsetmaterial",
6706                   "vsetmaterial [-noupdate|-update] [name] MaterialName"
6707       "\n\t\t: Alias for vaspects -setmaterial [name] MaterialName.",
6708                   __FILE__,VAspects,group);
6709
6710   theCommands.Add("vunsetmaterial",
6711                   "vunsetmaterial [-noupdate|-update] [name]"
6712       "\n\t\t: Alias for vaspects -unsetmaterial [name].",
6713                   __FILE__,VAspects,group);
6714
6715   theCommands.Add("vsetwidth",
6716                   "vsetwidth [-noupdate|-update] [name] width(0->10)"
6717       "\n\t\t: Alias for vaspects -setwidth [name] width.",
6718                   __FILE__,VAspects,group);
6719
6720   theCommands.Add("vunsetwidth",
6721                   "vunsetwidth [-noupdate|-update] [name]"
6722       "\n\t\t: Alias for vaspects -unsetwidth [name].",
6723                   __FILE__,VAspects,group);
6724
6725   theCommands.Add("vsetinteriorstyle",
6726     "vsetinteriorstyle [-noupdate|-update] [name] Style"
6727     "\n\t\t: Alias for vaspects -setInterior [name] Style.",
6728                   __FILE__,VAspects,group);
6729
6730   theCommands.Add ("vsetedgetype",
6731     "vsetedgetype [name] [-type {solid, dash, dot}] [-color R G B] [-width value]"
6732     "\n\t\t: Alias for vaspects [name] -setEdgeType Type.",
6733       __FILE__, VAspects, group);
6734
6735   theCommands.Add ("vunsetedgetype",
6736     "vunsetedgetype [name]"
6737     "\n\t\t: Alias for vaspects [name] -unsetEdgeType.",
6738       __FILE__, VAspects, group);
6739
6740   theCommands.Add ("vshowfaceboundary",
6741     "vshowfaceboundary [name]"
6742     "\n\t\t: Alias for vaspects [name] -setFaceBoundaryDraw on",
6743       __FILE__, VAspects, group);
6744
6745   theCommands.Add("vsensdis",
6746       "vsensdis : Display active entities (sensitive entities of one of the standard types corresponding to active selection modes)."
6747       "\n\t\t: Standard entity types are those defined in Select3D package:"
6748       "\n\t\t: - sensitive box"
6749       "\n\t\t: - sensitive face"
6750       "\n\t\t: - sensitive curve"
6751       "\n\t\t: - sensitive segment"
6752       "\n\t\t: - sensitive circle"
6753       "\n\t\t: - sensitive point"
6754       "\n\t\t: - sensitive triangulation"
6755       "\n\t\t: - sensitive triangle"
6756       "\n\t\t: Custom(application - defined) sensitive entity types are not processed by this command.",
6757       __FILE__,VDispSensi,group);
6758
6759   theCommands.Add("vsensera",
6760       "vsensera : erase active entities",
6761       __FILE__,VClearSensi,group);
6762
6763   theCommands.Add("vsetshading",
6764       "vsetshading  : vsetshading name Quality(default=0.0008) "
6765       "\n\t\t: Sets deflection coefficient that defines the quality of the shape representation in the shading mode.",
6766       __FILE__,VShading,group);
6767
6768   theCommands.Add("vunsetshading",
6769       "vunsetshading :vunsetshading name "
6770       "\n\t\t: Sets default deflection coefficient (0.0008) that defines the quality of the shape representation in the shading mode.",
6771       __FILE__,VShading,group);
6772
6773   theCommands.Add ("vtexture",
6774                    "vtexture [-noupdate|-update] name [ImageFile|IdOfTexture|off]"
6775                    "\n\t\t:          [-tex0 Image0] [-tex1 Image1] [...]"
6776                    "\n\t\t:          [-origin {u v|off}] [-scale {u v|off}] [-repeat {u v|off}]"
6777                    "\n\t\t:          [-trsfTrans du dv] [-trsfScale su sv] [-trsfAngle Angle]"
6778                    "\n\t\t:          [-modulate {on|off}]"
6779                    "\n\t\t:          [-setFilter {nearest|bilinear|trilinear}]"
6780                    "\n\t\t:          [-setAnisoFilter {off|low|middle|quality}]"
6781                    "\n\t\t:          [-default]"
6782                    "\n\t\t: The texture can be specified by filepath"
6783                    "\n\t\t: or as ID (0<=IdOfTexture<=20) specifying one of the predefined textures."
6784                    "\n\t\t: The options are:"
6785                    "\n\t\t:   -scale     Setup texture scaling for generating coordinates; (1, 1) by default"
6786                    "\n\t\t:   -origin    Setup texture origin  for generating coordinates; (0, 0) by default"
6787                    "\n\t\t:   -repeat    Setup texture repeat  for generating coordinates; (1, 1) by default"
6788                    "\n\t\t:   -modulate  Enable or disable texture color modulation"
6789                    "\n\t\t:   -trsfAngle Setup dynamic texture coordinates transformation - rotation angle"
6790                    "\n\t\t:   -trsfTrans Setup dynamic texture coordinates transformation - translation vector"
6791                    "\n\t\t:   -trsfScale Setup dynamic texture coordinates transformation - scale vector"
6792                    "\n\t\t:   -setFilter Setup texture filter"
6793                    "\n\t\t:   -setAnisoFilter Setup anisotropic filter for texture with mip-levels"
6794                    "\n\t\t:   -default   Sets texture mapping default parameters",
6795                     __FILE__, VTexture, group);
6796
6797   theCommands.Add("vtexscale",
6798                   "vtexscale name ScaleU ScaleV"
6799                   "\n\t\t: Alias for vtexture name -setScale ScaleU ScaleV.",
6800                   __FILE__,VTexture,group);
6801
6802   theCommands.Add("vtexorigin",
6803                   "vtexorigin name OriginU OriginV"
6804                   "\n\t\t: Alias for vtexture name -setOrigin OriginU OriginV.",
6805                   __FILE__,VTexture,group);
6806
6807   theCommands.Add("vtexrepeat",
6808                   "vtexrepeat name RepeatU RepeatV"
6809                   "\n\t\t: Alias for vtexture name -setRepeat RepeatU RepeatV.",
6810                   VTexture,group);
6811
6812   theCommands.Add("vtexdefault",
6813                   "vtexdefault name"
6814                   "\n\t\t: Alias for vtexture name -default.",
6815                   VTexture,group);
6816
6817   theCommands.Add("vstate",
6818       "vstate [-entities] [-hasSelected] [name1] ... [nameN]"
6819       "\n\t\t: Reports show/hidden state for selected or named objects"
6820       "\n\t\t:   -entities - print low-level information about detected entities"
6821       "\n\t\t:   -hasSelected - prints 1 if context has selected shape and 0 otherwise",
6822                   __FILE__,VState,group);
6823
6824   theCommands.Add("vpickshapes",
6825                   "vpickshape subtype(VERTEX,EDGE,WIRE,FACE,SHELL,SOLID) [name1 or .] [name2 or .] [name n or .]"
6826                   "\n\t\t: Hold Ctrl and pick object by clicking Left mouse button."
6827                   "\n\t\t: Hold also Shift for multiple selection.",
6828                   __FILE__, VPickShape, group);
6829
6830   theCommands.Add("vtypes",
6831                   "vtypes : list of known types and signatures in AIS - To be Used in vpickobject command for selection with filters",
6832                   VIOTypes,group);
6833
6834   theCommands.Add("vr",
6835       "vr filename"
6836       "\n\t\t: Reads shape from BREP-format file and displays it in the viewer. ",
6837                   __FILE__,vr, group);
6838
6839   theCommands.Add("vselfilter",
6840                   "vselfilter [-type {VERTEX|EDGE|WIRE|FACE|SHAPE|SHELL|SOLID}] [-clear]"
6841     "\nSets selection shape type filter in context or remove all filters."
6842     "\n    : Option -type set type of selection filter. Filters are applyed with Or combination."
6843     "\n    : Option -clear remove all filters in context",
6844                   __FILE__,VSelFilter,group);
6845
6846   theCommands.Add("vpickselected", "vpickselected [name]: extract selected shape.",
6847     __FILE__, VPickSelected, group);
6848
6849   theCommands.Add ("vloadselection",
6850     "vloadselection [-context] [name1] ... [nameN] : allows to load selection"
6851     "\n\t\t: primitives for the shapes with names given without displaying them.",
6852     __FILE__, VLoadSelection, group);
6853
6854   theCommands.Add("vbsdf", "vbsdf [name] [options]"
6855     "\nAdjusts parameters of material BSDF:"
6856     "\n    -help : Shows this message"
6857     "\n    -print : Print BSDF"
6858     "\n    -kd : Weight of the Lambertian BRDF"
6859     "\n    -kr : Weight of the reflection BRDF"
6860     "\n    -kt : Weight of the transmission BTDF"
6861     "\n    -ks : Weight of the glossy Blinn BRDF"
6862     "\n    -le : Self-emitted radiance"
6863     "\n    -fresnel : Fresnel coefficients; Allowed fresnel formats are: Constant x,"
6864     "\n               Schlick x y z, Dielectric x, Conductor x y"
6865     "\n    -roughness : Roughness of material (Blinn's exponent)"
6866     "\n    -absorpcoeff : Absorption coefficient (only for transparent material)"
6867     "\n    -absorpcolor : Absorption color (only for transparent material)"
6868     "\n    -normalize : Normalize BSDF coefficients",
6869     __FILE__, VBsdf, group);
6870
6871 }
6872
6873 //=====================================================================
6874 //========================= for testing Draft and Rib =================
6875 //=====================================================================
6876 #include <BRepOffsetAPI_MakeThickSolid.hxx>
6877 #include <DBRep.hxx>
6878 #include <TopoDS_Face.hxx>
6879 #include <gp_Pln.hxx>
6880 #include <AIS_KindOfSurface.hxx>
6881 #include <BRepOffsetAPI_DraftAngle.hxx>
6882 #include <Precision.hxx>
6883 #include <BRepAlgo.hxx>
6884 #include <OSD_Environment.hxx>
6885 #include <DrawTrSurf.hxx>
6886 //#include <DbgTools.hxx>
6887 //#include <FeatAlgo_MakeLinearForm.hxx>
6888
6889
6890
6891
6892 //=======================================================================
6893 //function : IsValid
6894 //purpose  :
6895 //=======================================================================
6896 static Standard_Boolean IsValid(const TopTools_ListOfShape& theArgs,
6897                                 const TopoDS_Shape& theResult,
6898                                 const Standard_Boolean closedSolid,
6899                                 const Standard_Boolean GeomCtrl)
6900 {
6901   OSD_Environment check ("DONT_SWITCH_IS_VALID") ;
6902   TCollection_AsciiString checkValid = check.Value();
6903   Standard_Boolean ToCheck = Standard_True;
6904   if (!checkValid.IsEmpty()) {
6905 #ifdef OCCT_DEBUG
6906     std::cout <<"DONT_SWITCH_IS_VALID positionnee a :"<<checkValid.ToCString()<<"\n";
6907 #endif
6908     if ( checkValid=="true" || checkValid=="TRUE" ) {
6909       ToCheck= Standard_False;
6910     }
6911   } else {
6912 #ifdef OCCT_DEBUG
6913     std::cout <<"DONT_SWITCH_IS_VALID non positionne\n";
6914 #endif
6915   }
6916   Standard_Boolean IsValid = Standard_True;
6917   if (ToCheck)
6918     IsValid = BRepAlgo::IsValid(theArgs,theResult,closedSolid,GeomCtrl) ;
6919   return IsValid;
6920
6921 }
6922
6923 //===============================================================================
6924 // TDraft : test draft, uses AIS Viewer
6925 // Solid Face Plane Angle  Reverse
6926 //===============================================================================
6927 static Standard_Integer TDraft(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
6928 {
6929   if (argc < 5) return 1;
6930 // argv[1] - TopoDS_Shape Solid
6931 // argv[2] - TopoDS_Shape Face
6932 // argv[3] - TopoDS_Shape Plane
6933 // argv[4] - Standard_Real Angle
6934 // argv[5] - Standard_Integer Reverse
6935
6936 //  Sprintf(prefix, argv[1]);
6937   Standard_Real anAngle = 0;
6938   Standard_Boolean Rev = Standard_False;
6939   Standard_Integer rev = 0;
6940   TopoDS_Shape Solid  = DBRep::Get (argv[1]);
6941   TopoDS_Shape face   = DBRep::Get (argv[2]);
6942   TopoDS_Face Face    = TopoDS::Face(face);
6943   TopoDS_Shape Plane  = DBRep::Get (argv[3]);
6944   if (Plane.IsNull ()) {
6945     di << "TEST : Plane is NULL\n";
6946     return 1;
6947   }
6948   anAngle = Draw::Atof(argv[4]);
6949   anAngle = 2*M_PI * anAngle / 360.0;
6950   gp_Pln aPln;
6951   Handle( Geom_Surface )aSurf;
6952   AIS_KindOfSurface aSurfType;
6953   Standard_Real Offset;
6954   gp_Dir aDir;
6955   if(argc > 4) { // == 5
6956     rev = Draw::Atoi(argv[5]);
6957     Rev = (rev)? Standard_True : Standard_False;
6958   }
6959
6960   TopoDS_Face face2 = TopoDS::Face(Plane);
6961   if(!AIS::GetPlaneFromFace(face2, aPln, aSurf, aSurfType, Offset))
6962     {
6963       di << "TEST : Can't find plane\n";
6964       return 1;
6965     }
6966
6967   aDir = aPln.Axis().Direction();
6968   if (!aPln.Direct())
6969     aDir.Reverse();
6970   if (Plane.Orientation() == TopAbs_REVERSED)
6971     aDir.Reverse();
6972   di << "TEST : gp::Resolution() = " << gp::Resolution() << "\n";
6973
6974   BRepOffsetAPI_DraftAngle Draft (Solid);
6975
6976   if(Abs(anAngle)< Precision::Angular()) {
6977     di << "TEST : NULL angle\n";
6978     return 1;}
6979
6980   if(Rev) anAngle = - anAngle;
6981   Draft.Add (Face, aDir, anAngle, aPln);
6982   Draft.Build ();
6983   if (!Draft.IsDone())  {
6984     di << "TEST : Draft Not DONE \n";
6985     return 1;
6986   }
6987   TopTools_ListOfShape Larg;
6988   Larg.Append(Solid);
6989   if (!IsValid(Larg,Draft.Shape(),Standard_True,Standard_False)) {
6990     di << "TEST : DesignAlgo returns Not valid\n";
6991     return 1;
6992   }
6993
6994   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
6995   Handle(AIS_Shape) ais = new AIS_Shape(Draft.Shape());
6996
6997   if ( !ais.IsNull() ) {
6998     ais->SetColor(DEFAULT_COLOR);
6999     ais->SetMaterial(DEFAULT_MATERIAL);
7000     // Display the AIS_Shape without redraw
7001     Ctx->Display(ais, Standard_False);
7002
7003     const char *Name = "draft1";
7004     Handle(AIS_InteractiveObject) an_object;
7005     if (GetMapOfAIS().Find2(Name, an_object))
7006     {
7007       if (!an_object.IsNull())
7008       {
7009         Ctx->Remove (an_object, Standard_True);
7010       }
7011       GetMapOfAIS().UnBind2 (Name);
7012     }
7013     GetMapOfAIS().Bind(ais, Name);
7014 //  DBRep::Set("draft", ais->Shape());
7015   }
7016   Ctx->Display(ais, Standard_True);
7017   return 0;
7018 }
7019
7020 //==============================================================================
7021 //function : splitParameter
7022 //purpose  : Split parameter string to parameter name and parameter value
7023 //==============================================================================
7024 Standard_Boolean ViewerTest::SplitParameter (const TCollection_AsciiString& theString,
7025                                              TCollection_AsciiString&       theName,
7026                                              TCollection_AsciiString&       theValue)
7027 {
7028   Standard_Integer aParamNameEnd = theString.FirstLocationInSet ("=", 1, theString.Length());
7029
7030   if (aParamNameEnd == 0)
7031   {
7032     return Standard_False;
7033   }
7034
7035   TCollection_AsciiString aString (theString);
7036   if (aParamNameEnd != 0)
7037   {
7038     theValue = aString.Split (aParamNameEnd);
7039     aString.Split (aString.Length() - 1);
7040     theName = aString;
7041   }
7042
7043   return Standard_True;
7044 }
7045
7046 //============================================================================
7047 //  MyCommands
7048 //============================================================================
7049 void ViewerTest::MyCommands( Draw_Interpretor& theCommands)
7050 {
7051
7052   DrawTrSurf::BasicCommands(theCommands);
7053   const char* group = "Check Features Operations commands";
7054
7055   theCommands.Add("Draft","Draft    Solid Face Plane Angle Reverse",
7056                   __FILE__,
7057                   &TDraft,group); //Draft_Modification
7058 }
7059
7060 //==============================================================================
7061 // ViewerTest::Factory
7062 //==============================================================================
7063 void ViewerTest::Factory(Draw_Interpretor& theDI)
7064 {
7065   // definition of Viewer Command
7066   ViewerTest::Commands(theDI);
7067
7068 #ifdef OCCT_DEBUG
7069       theDI << "Draw Plugin : OCC V2d & V3d commands are loaded\n";
7070 #endif
7071 }
7072
7073 // Declare entry point PLUGINFACTORY
7074 DPLUGIN(ViewerTest)