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