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