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