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