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