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